Fix enum item references in class extends with parameters.
This commit is contained in:
parent
8130fed777
commit
ae480c5f76
1
Changes
1
Changes
|
|
@ -84,6 +84,7 @@ Verilator 5.043 devel
|
|||
* Fix DFG assertion on out-of-bounds selects. [Geza Lore]
|
||||
* Fix crash when super.new() called without a base class (#6772). [Matthew Ballance]
|
||||
* Fix class-in-class extends with parameters (#6773).
|
||||
* Fix enum item references in class extends with parameters.
|
||||
|
||||
|
||||
Verilator 5.042 2025-11-02
|
||||
|
|
|
|||
|
|
@ -1285,11 +1285,13 @@ public:
|
|||
bool cleanOut() const override { return true; }
|
||||
};
|
||||
class AstEnumItemRef final : public AstNodeExpr {
|
||||
// @astgen ptr := m_itemp : AstEnumItem // [AfterLink] Pointer to item
|
||||
// @astgen ptr := m_itemp : Optional[AstEnumItem] // [AfterLink] Pointer to item
|
||||
// @astgen ptr := m_classOrPackagep : Optional[AstNodeModule] // Class/package defined in
|
||||
string m_name; // Name of enum (for param relink)
|
||||
public:
|
||||
AstEnumItemRef(FileLine* fl, AstEnumItem* itemp, AstNodeModule* classOrPackagep)
|
||||
: ASTGEN_SUPER_EnumItemRef(fl)
|
||||
, m_name{itemp->name()}
|
||||
, m_itemp{itemp}
|
||||
, m_classOrPackagep{classOrPackagep} {
|
||||
dtypeFrom(m_itemp);
|
||||
|
|
@ -1297,13 +1299,14 @@ public:
|
|||
ASTGEN_MEMBERS_AstEnumItemRef;
|
||||
void dump(std::ostream& str) const override;
|
||||
void dumpJson(std::ostream& str) const override;
|
||||
string name() const override VL_MT_STABLE { return itemp() ? itemp()->name() : "<null>"; }
|
||||
string name() const override VL_MT_STABLE { return itemp() ? itemp()->name() : m_name; }
|
||||
int instrCount() const override { return 0; }
|
||||
bool sameNode(const AstNode* samep) const override {
|
||||
const AstEnumItemRef* const sp = VN_DBG_AS(samep, EnumItemRef);
|
||||
return itemp() == sp->itemp();
|
||||
}
|
||||
AstEnumItem* itemp() const VL_MT_STABLE { return m_itemp; }
|
||||
void itemp(AstEnumItem* nodep) { m_itemp = nodep; }
|
||||
string emitVerilog() override { V3ERROR_NA_RETURN(""); }
|
||||
string emitC() override { V3ERROR_NA_RETURN(""); }
|
||||
bool cleanOut() const override { return true; }
|
||||
|
|
@ -1691,8 +1694,6 @@ class AstLambdaArgRef final : public AstNodeExpr {
|
|||
// Lambda argument usage
|
||||
// These are not AstVarRefs because we need to be able to delete/clone lambdas during
|
||||
// optimizations and AstVar's are painful to remove.
|
||||
|
||||
private:
|
||||
string m_name; // Name of variable
|
||||
bool m_index; // Index, not value
|
||||
|
||||
|
|
|
|||
|
|
@ -4370,8 +4370,25 @@ class LinkDotResolveVisitor final : public VNVisitor {
|
|||
}
|
||||
}
|
||||
void visit(AstEnumItemRef* nodep) override {
|
||||
// EnumItemRef may be under a dot. Should already be resolved.
|
||||
// Resolve its reference
|
||||
// EnumItemRefs are created by the first pass, but V3Param may regenerate due to
|
||||
// a parameterized class/module, so we shouldn't get can't find errors.
|
||||
// No checkNoDot; created and iterated from a parseRef
|
||||
LINKDOT_VISIT_START();
|
||||
if (!nodep->itemp()) {
|
||||
UINFO(9, indent() << "linkEnumRef se" << cvtToHex(m_curSymp) << " n=" << nodep);
|
||||
UASSERT_OBJ(m_curSymp, nodep, "nullptr lookup symbol table");
|
||||
VSymEnt* const foundp = m_curSymp->findIdFallback(nodep->name());
|
||||
if (AstEnumItem* const itemp = foundp ? VN_CAST(foundp->nodep(), EnumItem) : nullptr) {
|
||||
nodep->itemp(itemp);
|
||||
nodep->classOrPackagep(foundp->classOrPackagep());
|
||||
UINFO(9, indent() << " resolved " << nodep);
|
||||
}
|
||||
if (VL_UNCOVERABLE(!nodep->itemp())) {
|
||||
nodep->v3error("Can't find definition of enum item, again: " // LCOV_EXCL_LINE
|
||||
<< nodep->prettyNameQ());
|
||||
}
|
||||
}
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
void visit(AstMethodCall* nodep) override {
|
||||
|
|
|
|||
|
|
@ -2032,8 +2032,12 @@ public:
|
|||
}
|
||||
// Set all links pointing to a user3 (deleting) node as null
|
||||
netlistp->foreach([](AstNode* const nodep) {
|
||||
nodep->foreachLink([](AstNode** const linkpp, const char*) {
|
||||
if (*linkpp && (*linkpp)->user3()) *linkpp = nullptr;
|
||||
nodep->foreachLink([&](AstNode** const linkpp, const char*) {
|
||||
if (*linkpp && (*linkpp)->user3()) {
|
||||
UINFO(9, "clear link " << nodep);
|
||||
*linkpp = nullptr;
|
||||
UINFO(9, "cleared link " << nodep);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2817,6 +2817,7 @@ class WidthVisitor final : public VNVisitor {
|
|||
}
|
||||
}
|
||||
void visit(AstEnumItemRef* nodep) override {
|
||||
UASSERT_OBJ(nodep->itemp(), nodep, "Unlinked");
|
||||
if (!nodep->itemp()->didWidth()) {
|
||||
// We need to do the whole enum en masse
|
||||
AstNode* enump = nodep->itemp();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
#!/usr/bin/env python3
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2025 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
|
||||
|
||||
import vltest_bootstrap
|
||||
|
||||
test.scenarios('simulator')
|
||||
|
||||
test.compile()
|
||||
|
||||
test.execute()
|
||||
|
||||
test.passes()
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||
// any use, without warranty, 2025 by Wilson Snyder.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
// verilog_format: off
|
||||
`define stop $stop
|
||||
`define checkd(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d (%s !== %s)\n", `__FILE__,`__LINE__, (gotv), (expv), `"gotv`", `"expv`"); `stop; end while(0);
|
||||
// verilog_format: on
|
||||
|
||||
package uvm_pkg;
|
||||
class uvm_reg_sequence #(
|
||||
type BASE = int
|
||||
);
|
||||
typedef enum {
|
||||
LOCAL = 2,
|
||||
UPSTREAM = 3
|
||||
} seq_parent_e;
|
||||
endclass
|
||||
endpackage
|
||||
|
||||
module t;
|
||||
import uvm_pkg::*;
|
||||
class test_seq extends uvm_reg_sequence;
|
||||
endclass
|
||||
initial begin
|
||||
test_seq c;
|
||||
c = new;
|
||||
`checkd(c.LOCAL, 2);
|
||||
`checkd(c.UPSTREAM, 3);
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
Loading…
Reference in New Issue