Support const object new() assignments.

This commit is contained in:
Wilson Snyder 2020-09-07 17:26:53 -04:00
parent 1899a875a4
commit 30f3774134
3 changed files with 16 additions and 5 deletions

View File

@ -5,6 +5,8 @@ The contributors that suggested a given feature are shown in []. Thanks!
* Verilator 4.101 devel * Verilator 4.101 devel
**** Support const object new() assignments.
* Verilator 4.100 2020-09-07 * Verilator 4.100 2020-09-07

View File

@ -128,6 +128,11 @@ public:
return m_dtypep; return m_dtypep;
} }
AstNodeDType* dtypeNullp() const { return m_dtypep; } AstNodeDType* dtypeNullp() const { return m_dtypep; }
AstNodeDType* dtypeNullSkipRefp() const {
AstNodeDType* dtp = dtypeNullp();
if (dtp) dtp = dtp->skipRefp();
return dtp;
}
AstNodeDType* dtypeOverridep(AstNodeDType* defaultp) const { AstNodeDType* dtypeOverridep(AstNodeDType* defaultp) const {
if (m_stage == PRELIM) v3fatalSrc("Parent dtype should be a final-stage action"); if (m_stage == PRELIM) v3fatalSrc("Parent dtype should be a final-stage action");
return m_dtypep ? m_dtypep : defaultp; return m_dtypep ? m_dtypep : defaultp;
@ -478,7 +483,7 @@ private:
// signed: Unsigned (11.8.1) // signed: Unsigned (11.8.1)
// width: LHS + RHS // width: LHS + RHS
if (m_vup->prelim()) { if (m_vup->prelim()) {
AstNodeDType* vdtypep = m_vup->dtypeNullp(); AstNodeDType* vdtypep = m_vup->dtypeNullSkipRefp();
if (vdtypep if (vdtypep
&& (VN_IS(vdtypep, AssocArrayDType) // && (VN_IS(vdtypep, AssocArrayDType) //
|| VN_IS(vdtypep, DynArrayDType) // || VN_IS(vdtypep, DynArrayDType) //
@ -602,7 +607,7 @@ private:
// LHS, RHS is self-determined // LHS, RHS is self-determined
// width: value(LHS) * width(RHS) // width: value(LHS) * width(RHS)
if (m_vup->prelim()) { if (m_vup->prelim()) {
AstNodeDType* vdtypep = m_vup->dtypeNullp(); AstNodeDType* vdtypep = m_vup->dtypeNullSkipRefp();
if (vdtypep if (vdtypep
&& (VN_IS(vdtypep, AssocArrayDType) || VN_IS(vdtypep, DynArrayDType) && (VN_IS(vdtypep, AssocArrayDType) || VN_IS(vdtypep, DynArrayDType)
|| VN_IS(vdtypep, QueueDType) || VN_IS(vdtypep, UnpackArrayDType))) { || VN_IS(vdtypep, QueueDType) || VN_IS(vdtypep, UnpackArrayDType))) {
@ -2725,7 +2730,7 @@ private:
virtual void visit(AstNew* nodep) override { virtual void visit(AstNew* nodep) override {
if (nodep->didWidthAndSet()) return; if (nodep->didWidthAndSet()) return;
AstClassRefDType* refp = VN_CAST(m_vup->dtypeNullp(), ClassRefDType); AstClassRefDType* refp = VN_CAST(m_vup->dtypeNullSkipRefp(), ClassRefDType);
if (!refp) { // e.g. int a = new; if (!refp) { // e.g. int a = new;
nodep->v3error("new() not expected in this context"); nodep->v3error("new() not expected in this context");
return; return;
@ -2751,7 +2756,7 @@ private:
} }
virtual void visit(AstNewCopy* nodep) override { virtual void visit(AstNewCopy* nodep) override {
if (nodep->didWidthAndSet()) return; if (nodep->didWidthAndSet()) return;
AstClassRefDType* refp = VN_CAST(m_vup->dtypeNullp(), ClassRefDType); AstClassRefDType* refp = VN_CAST(m_vup->dtypeNullSkipRefp(), ClassRefDType);
if (!refp) { // e.g. int a = new; if (!refp) { // e.g. int a = new;
nodep->v3error("new() not expected in this context"); nodep->v3error("new() not expected in this context");
return; return;
@ -2766,7 +2771,7 @@ private:
} }
virtual void visit(AstNewDynamic* nodep) override { virtual void visit(AstNewDynamic* nodep) override {
if (nodep->didWidthAndSet()) return; if (nodep->didWidthAndSet()) return;
AstDynArrayDType* adtypep = VN_CAST(m_vup->dtypeNullp(), DynArrayDType); AstDynArrayDType* adtypep = VN_CAST(m_vup->dtypeNullSkipRefp(), DynArrayDType);
if (!adtypep) { // e.g. int a = new; if (!adtypep) { // e.g. int a = new;
nodep->v3error( nodep->v3error(
"dynamic new() not expected in this context (data type must be dynamic array)"); "dynamic new() not expected in this context (data type must be dynamic array)");

View File

@ -13,6 +13,8 @@ class Cls;
protected int m_prot = B; protected int m_prot = B;
endclass endclass
const Cls mod_c = new;
initial begin initial begin
Cls c; Cls c;
if (c.A != 10) $stop; if (c.A != 10) $stop;
@ -21,6 +23,8 @@ endclass
c.m_loc = 10; c.m_loc = 10;
if (c.m_loc != 10) $stop; if (c.m_loc != 10) $stop;
if (c.m_prot != 20) $stop; if (c.m_prot != 20) $stop;
//
if (mod_c.A != 10) $stop;
$write("*-* All Finished *-*\n"); $write("*-* All Finished *-*\n");
$finish; $finish;
end end