Fix class field linking when a super classes is a param (#3949)

This commit is contained in:
Ryszard Rozak 2023-02-10 13:44:14 +01:00 committed by GitHub
parent 93d50c4499
commit d34aa10faf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 35 additions and 8 deletions

View File

@ -2003,6 +2003,9 @@ private:
// *::user4() -> See LinkDotState // *::user4() -> See LinkDotState
// Cleared on Cell // Cleared on Cell
// AstVar::user5() // bool. True if pin used in this cell // AstVar::user5() // bool. True if pin used in this cell
// AstClass::user5() // bool. True if class has a parameter
// as a (possibly indirect) base class.
// Used only in LDS_PRIMARY pass
const VNUser3InUse m_inuser3; const VNUser3InUse m_inuser3;
const VNUser5InUse m_inuser5; const VNUser5InUse m_inuser5;
@ -3230,6 +3233,7 @@ private:
iterateChildren(nodep); iterateChildren(nodep);
} }
void visit(AstClass* nodep) override { void visit(AstClass* nodep) override {
nodep->user3SetOnce();
UINFO(5, " " << nodep << endl); UINFO(5, " " << nodep << endl);
checkNoDot(nodep); checkNoDot(nodep);
VL_RESTORER(m_curSymp); VL_RESTORER(m_curSymp);
@ -3261,6 +3265,16 @@ private:
AstClassRefDType* classRefDtypep = nullptr; AstClassRefDType* classRefDtypep = nullptr;
AstClass* classp = VN_CAST(foundp->nodep(), Class); AstClass* classp = VN_CAST(foundp->nodep(), Class);
if (classp) { if (classp) {
if (classp != nodep) {
// Case with recursive inheritance is handled later in this
// function
iterate(classp);
}
if (classp->user5()) {
// Has a parameter as its base class
nodep->user5(true);
return;
}
AstPin* paramsp = cpackagerefp->paramsp(); AstPin* paramsp = cpackagerefp->paramsp();
if (paramsp) paramsp = paramsp->cloneTree(true); if (paramsp) paramsp = paramsp->cloneTree(true);
classRefDtypep classRefDtypep
@ -3271,6 +3285,7 @@ private:
// Extending has to be handled after V3Param.cpp, but the type // Extending has to be handled after V3Param.cpp, but the type
// reference has to be visited // reference has to be visited
iterate(paramp); iterate(paramp);
nodep->user5(true);
return; return;
} else { } else {
AstNodeDType* const paramTypep = paramp->getChildDTypep(); AstNodeDType* const paramTypep = paramp->getChildDTypep();

View File

@ -7,7 +7,7 @@
module t (/*AUTOARG*/ module t (/*AUTOARG*/
); );
class foo; class Foo;
int x = 1; int x = 1;
function int get_x; function int get_x;
return x; return x;
@ -17,10 +17,10 @@ module t (/*AUTOARG*/
endfunction endfunction
endclass endclass
class bar #(type T=foo) extends T; class Bar #(type T=Foo) extends T;
endclass endclass
class baz; class Baz;
int x = 2; int x = 2;
function int get_x; function int get_x;
return x; return x;
@ -30,14 +30,26 @@ module t (/*AUTOARG*/
endfunction endfunction
endclass endclass
bar bar_foo_i; class ExtendBar extends Bar;
bar #(baz) bar_baz_i; function int get_x;
return super.get_x();
endfunction
function int get_6;
return 2 * get_3();
endfunction
endclass
Bar bar_foo_i;
Bar #(Baz) bar_baz_i;
ExtendBar extend_bar_i;
initial begin initial begin
bar_foo_i = new; bar_foo_i = new;
bar_baz_i = new; bar_baz_i = new;
extend_bar_i = new;
if (bar_foo_i.get_x() == 1 && bar_foo_i.get_3() == 3 && if (bar_foo_i.get_x() == 1 && bar_foo_i.get_3() == 3 &&
bar_baz_i.get_x() == 2 && bar_baz_i.get_4() == 4) begin bar_baz_i.get_x() == 2 && bar_baz_i.get_4() == 4 &&
extend_bar_i.get_x() == 1 && extend_bar_i.get_6() == 6) begin
$write("*-* All Finished *-*\n"); $write("*-* All Finished *-*\n");
$finish; $finish;
end end