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) {
|
AstBasicDType* AstNode::findInsertSameDType(AstBasicDType* nodep) {
|
||||||
return v3Global.rootp()->typeTablep()->findInsertSameDType(nodep);
|
return v3Global.rootp()->typeTablep()->findInsertSameDType(nodep);
|
||||||
}
|
}
|
||||||
AstNodeDType* AstNode::findVoidDType() const {
|
AstNodeDType* AstNode::findEmptyQueueDType() const {
|
||||||
return v3Global.rootp()->typeTablep()->findVoidDType(fileline());
|
return v3Global.rootp()->typeTablep()->findEmptyQueueDType(fileline());
|
||||||
}
|
}
|
||||||
AstNodeDType* AstNode::findQueueIndexDType() const {
|
AstNodeDType* AstNode::findQueueIndexDType() const {
|
||||||
return v3Global.rootp()->typeTablep()->findQueueIndexDType(fileline());
|
return v3Global.rootp()->typeTablep()->findQueueIndexDType(fileline());
|
||||||
}
|
}
|
||||||
|
AstNodeDType* AstNode::findVoidDType() const {
|
||||||
|
return v3Global.rootp()->typeTablep()->findVoidDType(fileline());
|
||||||
|
}
|
||||||
|
|
||||||
//######################################################################
|
//######################################################################
|
||||||
// AstNVisitor
|
// AstNVisitor
|
||||||
|
|
|
||||||
|
|
@ -1698,6 +1698,7 @@ public:
|
||||||
void dtypeSetSigned32() { dtypep(findSigned32DType()); }
|
void dtypeSetSigned32() { dtypep(findSigned32DType()); }
|
||||||
void dtypeSetUInt32() { dtypep(findUInt32DType()); } // Twostate
|
void dtypeSetUInt32() { dtypep(findUInt32DType()); } // Twostate
|
||||||
void dtypeSetUInt64() { dtypep(findUInt64DType()); } // Twostate
|
void dtypeSetUInt64() { dtypep(findUInt64DType()); } // Twostate
|
||||||
|
void dtypeSetEmptyQueue() { dtypep(findEmptyQueueDType()); }
|
||||||
void dtypeSetVoid() { dtypep(findVoidDType()); }
|
void dtypeSetVoid() { dtypep(findVoidDType()); }
|
||||||
|
|
||||||
// Data type locators
|
// Data type locators
|
||||||
|
|
@ -1708,6 +1709,7 @@ public:
|
||||||
AstNodeDType* findUInt32DType() { return findBasicDType(AstBasicDTypeKwd::UINT32); }
|
AstNodeDType* findUInt32DType() { return findBasicDType(AstBasicDTypeKwd::UINT32); }
|
||||||
AstNodeDType* findUInt64DType() { return findBasicDType(AstBasicDTypeKwd::UINT64); }
|
AstNodeDType* findUInt64DType() { return findBasicDType(AstBasicDTypeKwd::UINT64); }
|
||||||
AstNodeDType* findCHandleDType() { return findBasicDType(AstBasicDTypeKwd::CHANDLE); }
|
AstNodeDType* findCHandleDType() { return findBasicDType(AstBasicDTypeKwd::CHANDLE); }
|
||||||
|
AstNodeDType* findEmptyQueueDType() const;
|
||||||
AstNodeDType* findVoidDType() const;
|
AstNodeDType* findVoidDType() const;
|
||||||
AstNodeDType* findQueueIndexDType() const;
|
AstNodeDType* findQueueIndexDType() const;
|
||||||
AstNodeDType* findBitDType(int width, int widthMin, VSigning numeric) 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) {
|
AstVoidDType* AstTypeTable::findVoidDType(FileLine* fl) {
|
||||||
if (VL_UNLIKELY(!m_voidp)) {
|
if (VL_UNLIKELY(!m_voidp)) {
|
||||||
AstVoidDType* newp = new AstVoidDType(fl);
|
AstVoidDType* newp = new AstVoidDType{fl};
|
||||||
addTypesp(newp);
|
addTypesp(newp);
|
||||||
m_voidp = newp;
|
m_voidp = newp;
|
||||||
}
|
}
|
||||||
|
|
@ -1642,6 +1651,10 @@ void AstUnsizedArrayDType::dumpSmall(std::ostream& str) const {
|
||||||
this->AstNodeDType::dumpSmall(str);
|
this->AstNodeDType::dumpSmall(str);
|
||||||
str << "[]";
|
str << "[]";
|
||||||
}
|
}
|
||||||
|
void AstEmptyQueueDType::dumpSmall(std::ostream& str) const {
|
||||||
|
this->AstNodeDType::dumpSmall(str);
|
||||||
|
str << "emptyq";
|
||||||
|
}
|
||||||
void AstVoidDType::dumpSmall(std::ostream& str) const {
|
void AstVoidDType::dumpSmall(std::ostream& str) const {
|
||||||
this->AstNodeDType::dumpSmall(str);
|
this->AstNodeDType::dumpSmall(str);
|
||||||
str << "void";
|
str << "void";
|
||||||
|
|
|
||||||
|
|
@ -183,6 +183,17 @@ public:
|
||||||
static AstConst* parseParamLiteral(FileLine* fl, const string& literal);
|
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 {
|
class AstRange final : public AstNodeRange {
|
||||||
// Range specification, for use under variables and cells
|
// Range specification, for use under variables and cells
|
||||||
public:
|
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 {
|
class AstVoidDType final : public AstNodeDType {
|
||||||
// For e.g. a function returning void
|
// For e.g. a function returning void
|
||||||
public:
|
public:
|
||||||
|
|
@ -9088,8 +9126,9 @@ public:
|
||||||
class AstTypeTable final : public AstNode {
|
class AstTypeTable final : public AstNode {
|
||||||
// Container for hash of standard data types
|
// Container for hash of standard data types
|
||||||
// Children: NODEDTYPEs
|
// Children: NODEDTYPEs
|
||||||
AstVoidDType* m_voidp = nullptr;
|
AstEmptyQueueDType* m_emptyQueuep = nullptr;
|
||||||
AstQueueDType* m_queueIndexp = nullptr;
|
AstQueueDType* m_queueIndexp = nullptr;
|
||||||
|
AstVoidDType* m_voidp = nullptr;
|
||||||
AstBasicDType* m_basicps[AstBasicDTypeKwd::_ENUM_MAX];
|
AstBasicDType* m_basicps[AstBasicDTypeKwd::_ENUM_MAX];
|
||||||
//
|
//
|
||||||
using DetailedMap = std::map<VBasicTypeKey, AstBasicDType*>;
|
using DetailedMap = std::map<VBasicTypeKey, AstBasicDType*>;
|
||||||
|
|
@ -9100,14 +9139,15 @@ public:
|
||||||
ASTNODE_NODE_FUNCS(TypeTable)
|
ASTNODE_NODE_FUNCS(TypeTable)
|
||||||
AstNodeDType* typesp() const { return VN_CAST(op1p(), NodeDType); } // op1 = List of dtypes
|
AstNodeDType* typesp() const { return VN_CAST(op1p(), NodeDType); } // op1 = List of dtypes
|
||||||
void addTypesp(AstNodeDType* nodep) { addOp1p(nodep); }
|
void addTypesp(AstNodeDType* nodep) { addOp1p(nodep); }
|
||||||
AstVoidDType* findVoidDType(FileLine* fl);
|
|
||||||
AstQueueDType* findQueueIndexDType(FileLine* fl);
|
|
||||||
AstBasicDType* findBasicDType(FileLine* fl, AstBasicDTypeKwd kwd);
|
AstBasicDType* findBasicDType(FileLine* fl, AstBasicDTypeKwd kwd);
|
||||||
AstBasicDType* findLogicBitDType(FileLine* fl, AstBasicDTypeKwd kwd, int width, int widthMin,
|
AstBasicDType* findLogicBitDType(FileLine* fl, AstBasicDTypeKwd kwd, int width, int widthMin,
|
||||||
VSigning numeric);
|
VSigning numeric);
|
||||||
AstBasicDType* findLogicBitDType(FileLine* fl, AstBasicDTypeKwd kwd, const VNumRange& range,
|
AstBasicDType* findLogicBitDType(FileLine* fl, AstBasicDTypeKwd kwd, const VNumRange& range,
|
||||||
int widthMin, VSigning numeric);
|
int widthMin, VSigning numeric);
|
||||||
AstBasicDType* findInsertSameDType(AstBasicDType* nodep);
|
AstBasicDType* findInsertSameDType(AstBasicDType* nodep);
|
||||||
|
AstEmptyQueueDType* findEmptyQueueDType(FileLine* fl);
|
||||||
|
AstQueueDType* findQueueIndexDType(FileLine* fl);
|
||||||
|
AstVoidDType* findVoidDType(FileLine* fl);
|
||||||
void clearCache();
|
void clearCache();
|
||||||
void repairCache();
|
void repairCache();
|
||||||
virtual void dump(std::ostream& str = std::cout) const override;
|
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
|
// 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
|
// 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 {
|
virtual void visit(AstFell* nodep) override {
|
||||||
if (m_vup->prelim()) {
|
if (m_vup->prelim()) {
|
||||||
iterateCheckSizedSelf(nodep, "LHS", nodep->exprp(), SELF, BOTH);
|
iterateCheckSizedSelf(nodep, "LHS", nodep->exprp(), SELF, BOTH);
|
||||||
|
|
@ -1173,6 +1179,7 @@ private:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
nodep->backp()->dumpTree(cout, "-FIXME-tr ");
|
||||||
nodep->v3warn(E_UNSUPPORTED, "Unsupported/illegal unbounded ('$') in this context.");
|
nodep->v3warn(E_UNSUPPORTED, "Unsupported/illegal unbounded ('$') in this context.");
|
||||||
}
|
}
|
||||||
virtual void visit(AstIsUnbounded* nodep) override {
|
virtual void visit(AstIsUnbounded* nodep) override {
|
||||||
|
|
@ -3761,6 +3768,23 @@ private:
|
||||||
nodep->v3warn(E_UNSUPPORTED, "Unsupported: assignment of event data type");
|
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)) {
|
if (AstNewDynamic* dynp = VN_CAST(nodep->rhsp(), NewDynamic)) {
|
||||||
UINFO(9, "= new[] -> .resize(): " << nodep);
|
UINFO(9, "= new[] -> .resize(): " << nodep);
|
||||||
AstCMethodHard* newp;
|
AstCMethodHard* newp;
|
||||||
|
|
@ -3777,6 +3801,7 @@ private:
|
||||||
newp->makeStatement();
|
newp->makeStatement();
|
||||||
nodep->replaceWith(newp);
|
nodep->replaceWith(newp);
|
||||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
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: "... hierarchical_identifier select" see below
|
||||||
//
|
//
|
||||||
// // IEEE: empty_queue (IEEE 1800-2017 empty_unpacked_array_concatenation)
|
// // IEEE: empty_queue (IEEE 1800-2017 empty_unpacked_array_concatenation)
|
||||||
| '{' '}' { $$ = new AstConst($1, AstConst::BitFalse());
|
| '{' '}' { $$ = new AstEmptyQueue($1); }
|
||||||
BBUNSUP($<fl>1, "Unsupported: empty queues (\"{ }\")"); }
|
|
||||||
//
|
//
|
||||||
// // IEEE: concatenation/constant_concatenation
|
// // IEEE: concatenation/constant_concatenation
|
||||||
// // Part of exprOkLvalue below
|
// // 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"};
|
q = '{"q"};
|
||||||
v = $sformatf("%p", q); `checks(v, "'{\"q\"} ");
|
v = $sformatf("%p", q); `checks(v, "'{\"q\"} ");
|
||||||
|
|
||||||
|
q = {};
|
||||||
|
i = q.size(); `checkh(i, 0);
|
||||||
|
|
||||||
q = '{"q", "b", "c", "d", "e", "f"};
|
q = '{"q", "b", "c", "d", "e", "f"};
|
||||||
if (q[0] !== "q") $stop;
|
if (q[0] !== "q") $stop;
|
||||||
v = $sformatf("%p", q); `checks(v, "'{\"q\", \"b\", \"c\", \"d\", \"e\", \"f\"} ");
|
v = $sformatf("%p", q); `checks(v, "'{\"q\", \"b\", \"c\", \"d\", \"e\", \"f\"} ");
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue