Support empty queue assignment to delete queue
This commit is contained in:
parent
27d53691bd
commit
43aa3229fb
|
|
@ -1264,12 +1264,15 @@ AstNodeDType* AstNode::findBitRangeDType(const VNumRange& range, int widthMin,
|
|||
AstBasicDType* AstNode::findInsertSameDType(AstBasicDType* nodep) {
|
||||
return v3Global.rootp()->typeTablep()->findInsertSameDType(nodep);
|
||||
}
|
||||
AstNodeDType* AstNode::findVoidDType() const {
|
||||
return v3Global.rootp()->typeTablep()->findVoidDType(fileline());
|
||||
AstNodeDType* AstNode::findEmptyQueueDType() const {
|
||||
return v3Global.rootp()->typeTablep()->findEmptyQueueDType(fileline());
|
||||
}
|
||||
AstNodeDType* AstNode::findQueueIndexDType() const {
|
||||
return v3Global.rootp()->typeTablep()->findQueueIndexDType(fileline());
|
||||
}
|
||||
AstNodeDType* AstNode::findVoidDType() const {
|
||||
return v3Global.rootp()->typeTablep()->findVoidDType(fileline());
|
||||
}
|
||||
|
||||
//######################################################################
|
||||
// AstNVisitor
|
||||
|
|
|
|||
|
|
@ -1698,6 +1698,7 @@ public:
|
|||
void dtypeSetSigned32() { dtypep(findSigned32DType()); }
|
||||
void dtypeSetUInt32() { dtypep(findUInt32DType()); } // Twostate
|
||||
void dtypeSetUInt64() { dtypep(findUInt64DType()); } // Twostate
|
||||
void dtypeSetEmptyQueue() { dtypep(findEmptyQueueDType()); }
|
||||
void dtypeSetVoid() { dtypep(findVoidDType()); }
|
||||
|
||||
// Data type locators
|
||||
|
|
@ -1708,6 +1709,7 @@ public:
|
|||
AstNodeDType* findUInt32DType() { return findBasicDType(AstBasicDTypeKwd::UINT32); }
|
||||
AstNodeDType* findUInt64DType() { return findBasicDType(AstBasicDTypeKwd::UINT64); }
|
||||
AstNodeDType* findCHandleDType() { return findBasicDType(AstBasicDTypeKwd::CHANDLE); }
|
||||
AstNodeDType* findEmptyQueueDType() const;
|
||||
AstNodeDType* findVoidDType() const;
|
||||
AstNodeDType* findQueueIndexDType() const;
|
||||
AstNodeDType* findBitDType(int width, int widthMin, VSigning numeric) const;
|
||||
|
|
|
|||
|
|
@ -932,9 +932,18 @@ void AstTypeTable::repairCache() {
|
|||
}
|
||||
}
|
||||
|
||||
AstEmptyQueueDType* AstTypeTable::findEmptyQueueDType(FileLine* fl) {
|
||||
if (VL_UNLIKELY(!m_emptyQueuep)) {
|
||||
AstEmptyQueueDType* newp = new AstEmptyQueueDType{fl};
|
||||
addTypesp(newp);
|
||||
m_emptyQueuep = newp;
|
||||
}
|
||||
return m_emptyQueuep;
|
||||
}
|
||||
|
||||
AstVoidDType* AstTypeTable::findVoidDType(FileLine* fl) {
|
||||
if (VL_UNLIKELY(!m_voidp)) {
|
||||
AstVoidDType* newp = new AstVoidDType(fl);
|
||||
AstVoidDType* newp = new AstVoidDType{fl};
|
||||
addTypesp(newp);
|
||||
m_voidp = newp;
|
||||
}
|
||||
|
|
@ -1642,6 +1651,10 @@ void AstUnsizedArrayDType::dumpSmall(std::ostream& str) const {
|
|||
this->AstNodeDType::dumpSmall(str);
|
||||
str << "[]";
|
||||
}
|
||||
void AstEmptyQueueDType::dumpSmall(std::ostream& str) const {
|
||||
this->AstNodeDType::dumpSmall(str);
|
||||
str << "emptyq";
|
||||
}
|
||||
void AstVoidDType::dumpSmall(std::ostream& str) const {
|
||||
this->AstNodeDType::dumpSmall(str);
|
||||
str << "void";
|
||||
|
|
|
|||
|
|
@ -183,6 +183,17 @@ public:
|
|||
static AstConst* parseParamLiteral(FileLine* fl, const string& literal);
|
||||
};
|
||||
|
||||
class AstEmptyQueue final : public AstNodeMath {
|
||||
public:
|
||||
AstEmptyQueue(FileLine* fl)
|
||||
: ASTGEN_SUPER_EmptyQueue(fl) {}
|
||||
ASTNODE_NODE_FUNCS(EmptyQueue)
|
||||
virtual string emitC() { V3ERROR_NA_RETURN(""); }
|
||||
virtual string emitVerilog() { return "{}"; }
|
||||
virtual bool same(const AstNode* samep) const override { return true; }
|
||||
virtual bool cleanOut() const { return true; }
|
||||
};
|
||||
|
||||
class AstRange final : public AstNodeRange {
|
||||
// Range specification, for use under variables and cells
|
||||
public:
|
||||
|
|
@ -1354,6 +1365,33 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
class AstEmptyQueueDType final : public AstNodeDType {
|
||||
// For EmptyQueue
|
||||
public:
|
||||
explicit AstEmptyQueueDType(FileLine* fl)
|
||||
: ASTGEN_SUPER_EmptyQueueDType(fl) {
|
||||
dtypep(this);
|
||||
}
|
||||
ASTNODE_NODE_FUNCS(EmptyQueueDType)
|
||||
virtual void dumpSmall(std::ostream& str) const override;
|
||||
virtual bool hasDType() const override { return true; }
|
||||
virtual bool maybePointedTo() const override { return true; }
|
||||
virtual AstNodeDType* subDTypep() const override { return nullptr; }
|
||||
virtual AstNodeDType* virtRefDTypep() const override { return nullptr; }
|
||||
virtual void virtRefDTypep(AstNodeDType* nodep) override {}
|
||||
virtual bool similarDType(AstNodeDType* samep) const override { return this == samep; }
|
||||
virtual AstBasicDType* basicp() const override { return nullptr; }
|
||||
// cppcheck-suppress csyleCast
|
||||
virtual AstNodeDType* skipRefp() const override { return (AstNodeDType*)this; }
|
||||
// cppcheck-suppress csyleCast
|
||||
virtual AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; }
|
||||
// cppcheck-suppress csyleCast
|
||||
virtual AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; }
|
||||
virtual int widthAlignBytes() const override { return 1; }
|
||||
virtual int widthTotalBytes() const override { return 1; }
|
||||
virtual bool isCompound() const override { return false; }
|
||||
};
|
||||
|
||||
class AstVoidDType final : public AstNodeDType {
|
||||
// For e.g. a function returning void
|
||||
public:
|
||||
|
|
@ -9088,8 +9126,9 @@ public:
|
|||
class AstTypeTable final : public AstNode {
|
||||
// Container for hash of standard data types
|
||||
// Children: NODEDTYPEs
|
||||
AstVoidDType* m_voidp = nullptr;
|
||||
AstEmptyQueueDType* m_emptyQueuep = nullptr;
|
||||
AstQueueDType* m_queueIndexp = nullptr;
|
||||
AstVoidDType* m_voidp = nullptr;
|
||||
AstBasicDType* m_basicps[AstBasicDTypeKwd::_ENUM_MAX];
|
||||
//
|
||||
using DetailedMap = std::map<VBasicTypeKey, AstBasicDType*>;
|
||||
|
|
@ -9100,14 +9139,15 @@ public:
|
|||
ASTNODE_NODE_FUNCS(TypeTable)
|
||||
AstNodeDType* typesp() const { return VN_CAST(op1p(), NodeDType); } // op1 = List of dtypes
|
||||
void addTypesp(AstNodeDType* nodep) { addOp1p(nodep); }
|
||||
AstVoidDType* findVoidDType(FileLine* fl);
|
||||
AstQueueDType* findQueueIndexDType(FileLine* fl);
|
||||
AstBasicDType* findBasicDType(FileLine* fl, AstBasicDTypeKwd kwd);
|
||||
AstBasicDType* findLogicBitDType(FileLine* fl, AstBasicDTypeKwd kwd, int width, int widthMin,
|
||||
VSigning numeric);
|
||||
AstBasicDType* findLogicBitDType(FileLine* fl, AstBasicDTypeKwd kwd, const VNumRange& range,
|
||||
int widthMin, VSigning numeric);
|
||||
AstBasicDType* findInsertSameDType(AstBasicDType* nodep);
|
||||
AstEmptyQueueDType* findEmptyQueueDType(FileLine* fl);
|
||||
AstQueueDType* findQueueIndexDType(FileLine* fl);
|
||||
AstVoidDType* findVoidDType(FileLine* fl);
|
||||
void clearCache();
|
||||
void repairCache();
|
||||
virtual void dump(std::ostream& str = std::cout) const override;
|
||||
|
|
|
|||
|
|
@ -1078,6 +1078,12 @@ private:
|
|||
// We don't size the constant until we commit the widths, as need parameters
|
||||
// to remain unsized, and numbers to remain unsized to avoid backp() warnings
|
||||
}
|
||||
virtual void visit(AstEmptyQueue* nodep) override {
|
||||
nodep->dtypeSetEmptyQueue();
|
||||
if (!VN_IS(nodep->backp(), Assign))
|
||||
nodep->v3warn(E_UNSUPPORTED,
|
||||
"Unsupported/Illegal: empty queue ('{}') in this context");
|
||||
}
|
||||
virtual void visit(AstFell* nodep) override {
|
||||
if (m_vup->prelim()) {
|
||||
iterateCheckSizedSelf(nodep, "LHS", nodep->exprp(), SELF, BOTH);
|
||||
|
|
@ -1173,6 +1179,7 @@ private:
|
|||
return;
|
||||
}
|
||||
}
|
||||
nodep->backp()->dumpTree(cout, "-FIXME-tr ");
|
||||
nodep->v3warn(E_UNSUPPORTED, "Unsupported/illegal unbounded ('$') in this context.");
|
||||
}
|
||||
virtual void visit(AstIsUnbounded* nodep) override {
|
||||
|
|
@ -3761,6 +3768,23 @@ private:
|
|||
nodep->v3warn(E_UNSUPPORTED, "Unsupported: assignment of event data type");
|
||||
}
|
||||
}
|
||||
if (VN_IS(nodep->rhsp(), EmptyQueue)) {
|
||||
UINFO(9, "= {} -> .delete(): " << nodep);
|
||||
if (!VN_IS(nodep->lhsp()->dtypep()->skipRefp(), QueueDType)) {
|
||||
nodep->v3warn(E_UNSUPPORTED,
|
||||
"Unsupported/Illegal: empty queue ('{}') in this assign context");
|
||||
VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep);
|
||||
return;
|
||||
}
|
||||
AstMethodCall* const newp = new AstMethodCall{
|
||||
nodep->fileline(), nodep->lhsp()->unlinkFrBack(), "delete", nullptr};
|
||||
newp->makeStatement();
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
// Need to now convert it
|
||||
visit(newp);
|
||||
return;
|
||||
}
|
||||
if (AstNewDynamic* dynp = VN_CAST(nodep->rhsp(), NewDynamic)) {
|
||||
UINFO(9, "= new[] -> .resize(): " << nodep);
|
||||
AstCMethodHard* newp;
|
||||
|
|
@ -3777,6 +3801,7 @@ private:
|
|||
newp->makeStatement();
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
// return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4268,8 +4268,7 @@ expr<nodep>: // IEEE: part of expression/constant_expression/primary
|
|||
// // IEEE: "... hierarchical_identifier select" see below
|
||||
//
|
||||
// // IEEE: empty_queue (IEEE 1800-2017 empty_unpacked_array_concatenation)
|
||||
| '{' '}' { $$ = new AstConst($1, AstConst::BitFalse());
|
||||
BBUNSUP($<fl>1, "Unsupported: empty queues (\"{ }\")"); }
|
||||
| '{' '}' { $$ = new AstEmptyQueue($1); }
|
||||
//
|
||||
// // IEEE: concatenation/constant_concatenation
|
||||
// // Part of exprOkLvalue below
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
%Error-UNSUPPORTED: t/t_queue_empty_bad.v:11:11: Unsupported/Illegal: empty queue ('{}') in this context
|
||||
: ... In instance t
|
||||
11 | i = {} + 1;
|
||||
| ^
|
||||
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
|
||||
%Error-UNSUPPORTED: t/t_queue_empty_bad.v:13:9: Unsupported/Illegal: empty queue ('{}') in this assign context
|
||||
: ... In instance t
|
||||
13 | i = {};
|
||||
| ^
|
||||
%Error: Exiting due to
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
#!/usr/bin/env perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you
|
||||
# can redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
scenarios(vlt => 1);
|
||||
|
||||
lint(
|
||||
fails => 1,
|
||||
expect_filename => $Self->{golden_filename},
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||
// any use, without warranty, 2019 by Wilson Snyder.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
module t (/*AUTOARG*/);
|
||||
initial begin
|
||||
int i;
|
||||
|
||||
i = {} + 1;
|
||||
|
||||
i = {};
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -26,6 +26,9 @@ module t (/*AUTOARG*/);
|
|||
q = '{"q"};
|
||||
v = $sformatf("%p", q); `checks(v, "'{\"q\"} ");
|
||||
|
||||
q = {};
|
||||
i = q.size(); `checkh(i, 0);
|
||||
|
||||
q = '{"q", "b", "c", "d", "e", "f"};
|
||||
if (q[0] !== "q") $stop;
|
||||
v = $sformatf("%p", q); `checks(v, "'{\"q\", \"b\", \"c\", \"d\", \"e\", \"f\"} ");
|
||||
|
|
|
|||
Loading…
Reference in New Issue