Fix false recursive definition error (#6769) (#7118)

This commit is contained in:
Alex Zhou 2026-03-16 04:31:35 -07:00 committed by GitHub
parent 1e50fefb89
commit 651f223387
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 99 additions and 0 deletions

View File

@ -1913,6 +1913,55 @@ public:
void visit(AstNode* nodep) override { iterateChildren(nodep); }
};
//######################################################################
// Relink RefDType nodes to point to parameterized classes' type parameters
class ParamClassRefDTypeRelinkVisitor final : public VNVisitor {
AstClass* m_classp = nullptr;
std::unordered_map<const AstParamTypeDType*, AstClass*> m_paramTypeClassMap;
public:
explicit ParamClassRefDTypeRelinkVisitor(AstNetlist* netlistp) { iterate(netlistp); }
void visit(AstClass* nodep) override {
VL_RESTORER(m_classp);
m_classp = nodep;
for (AstNode* stmtp = nodep->stmtsp(); stmtp; stmtp = stmtp->nextp()) {
if (AstParamTypeDType* const ptp = VN_CAST(stmtp, ParamTypeDType)) {
m_paramTypeClassMap[ptp] = nodep;
}
}
iterateChildren(nodep);
}
void visit(AstRefDType* nodep) override {
iterateChildren(nodep);
AstParamTypeDType* const paramtypep = VN_CAST(nodep->refDTypep(), ParamTypeDType);
if (!paramtypep) return;
const auto it = m_paramTypeClassMap.find(paramtypep);
if (it == m_paramTypeClassMap.end()) return;
AstClass* const origClassp = it->second;
if (!origClassp->hasGParam()) return; // only relink refs to original param classes
if (origClassp->user3p()) return; // will not get removed, no need to relink
AstClass* const parametrizedClassp = VN_CAST(origClassp->user4p(), Class);
if (!parametrizedClassp) return;
const string paramName = paramtypep->name();
AstParamTypeDType* newParamTypep = nullptr;
for (AstNode* stmtp = parametrizedClassp->stmtsp(); stmtp; stmtp = stmtp->nextp()) {
if (AstParamTypeDType* const ptp = VN_CAST(stmtp, ParamTypeDType)) {
if (ptp->name() == paramName) {
newParamTypep = ptp;
break;
}
}
}
if (newParamTypep) {
nodep->refDTypep(newParamTypep);
nodep->classOrPackagep(parametrizedClassp);
}
}
void visit(AstNode* nodep) override { iterateChildren(nodep); }
};
//######################################################################
// Process parameter top state
@ -2784,6 +2833,8 @@ public:
}
});
ParamClassRefDTypeRelinkVisitor paramClassDTypeRelinkVisitor{netlistp};
relinkDots();
resortNetlistModules(netlistp);

View File

@ -0,0 +1,18 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# 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-FileCopyrightText: 2024 Wilson Snyder
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
import vltest_bootstrap
test.scenarios('simulator')
test.compile()
test.execute()
test.passes()

View File

@ -0,0 +1,30 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain.
// SPDX-FileCopyrightText: 2023 Antmicro Ltd
// SPDX-License-Identifier: CC0-1.0
module t;
class uvm_built_in_comp #(
type T = int
);
endclass
class uvm_in_order_comparator #(
type T = int,
type comp_type = uvm_built_in_comp#(T)
);
endclass
class uvm_in_order_built_in_comparator #(
type T = int
) extends uvm_in_order_comparator #(T);
endclass
initial begin
uvm_in_order_built_in_comparator #(int) sb;
$write("*-* All Finished *-*\n");
$finish;
end
endmodule