Fix dotted references in parameterized classes (#4206)

This commit is contained in:
Ryszard Rozak 2023-05-16 13:40:02 +02:00 committed by GitHub
parent 2ce7a348df
commit 279216048b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 56 additions and 41 deletions

View File

@ -2772,49 +2772,57 @@ private:
}
}
}
// Don't throw error ifthe reference is inside a class that extends a param, because
// some members can't be linked in such a case. m_insideClassExtParam may be true only
// in the first stage of linking.
if (!ok && !m_insideClassExtParam) {
// Cells/interfaces can't be implicit
const bool isCell = foundp ? VN_IS(foundp->nodep(), Cell) : false;
const bool checkImplicit = (!m_ds.m_dotp && m_ds.m_dotText == "" && !isCell);
const bool err = !(checkImplicit && m_statep->implicitOk(m_modp, nodep->name()));
if (err) {
if (foundp) {
nodep->v3error("Found definition of '"
<< m_ds.m_dotText << (m_ds.m_dotText == "" ? "" : ".")
<< nodep->prettyName() << "'"
<< " as a " << foundp->nodep()->typeName()
<< " but expected a " << expectWhat);
} else if (m_ds.m_dotText == "") {
UINFO(7, " ErrParseRef curSymp=se" << cvtToHex(m_curSymp)
<< " ds=" << m_ds.ascii() << endl);
const string suggest = m_statep->suggestSymFallback(
m_ds.m_dotSymp, nodep->name(), VNodeMatcher{});
nodep->v3error("Can't find definition of "
<< expectWhat << ": " << nodep->prettyNameQ() << '\n'
<< (suggest.empty() ? "" : nodep->warnMore() + suggest));
} else {
nodep->v3error("Can't find definition of "
<< (!baddot.empty() ? AstNode::prettyNameQ(baddot)
: nodep->prettyNameQ())
<< " in dotted " << expectWhat << ": '"
<< m_ds.m_dotText + "." + nodep->prettyName() << "'");
if (okSymp) {
okSymp->cellErrorScopes(nodep, AstNode::prettyName(m_ds.m_dotText));
if (!ok) {
if (m_insideClassExtParam) {
// Don't throw error if the reference is inside a class that extends a param,
// because some members can't be linked in such a case. m_insideClassExtParam
// may be true only in the first stage of linking.
// Mark that the Dot statement can't be resolved.
m_ds.m_unresolvedClass = true;
} else {
// Cells/interfaces can't be implicit
const bool isCell = foundp ? VN_IS(foundp->nodep(), Cell) : false;
const bool checkImplicit = (!m_ds.m_dotp && m_ds.m_dotText == "" && !isCell);
const bool err
= !(checkImplicit && m_statep->implicitOk(m_modp, nodep->name()));
if (err) {
if (foundp) {
nodep->v3error("Found definition of '"
<< m_ds.m_dotText << (m_ds.m_dotText == "" ? "" : ".")
<< nodep->prettyName() << "'"
<< " as a " << foundp->nodep()->typeName()
<< " but expected a " << expectWhat);
} else if (m_ds.m_dotText == "") {
UINFO(7, " ErrParseRef curSymp=se"
<< cvtToHex(m_curSymp) << " ds=" << m_ds.ascii() << endl);
const string suggest = m_statep->suggestSymFallback(
m_ds.m_dotSymp, nodep->name(), VNodeMatcher{});
nodep->v3error(
"Can't find definition of "
<< expectWhat << ": " << nodep->prettyNameQ() << '\n'
<< (suggest.empty() ? "" : nodep->warnMore() + suggest));
} else {
nodep->v3error("Can't find definition of "
<< (!baddot.empty() ? AstNode::prettyNameQ(baddot)
: nodep->prettyNameQ())
<< " in dotted " << expectWhat << ": '"
<< m_ds.m_dotText + "." + nodep->prettyName() << "'");
if (okSymp) {
okSymp->cellErrorScopes(nodep,
AstNode::prettyName(m_ds.m_dotText));
}
}
m_ds.m_dotErr = true;
}
if (checkImplicit) {
// Create if implicit, and also if error (so only complain once)
// Else if a scope is allowed, making a signal won't help error cascade
AstVarRef* const newp
= new AstVarRef{nodep->fileline(), nodep->name(), VAccess::READ};
nodep->replaceWith(newp);
VL_DO_DANGLING(pushDeletep(nodep), nodep);
createImplicitVar(m_curSymp, newp, m_modp, m_modSymp, err);
}
m_ds.m_dotErr = true;
}
if (checkImplicit) {
// Create if implicit, and also if error (so only complain once)
// Else if a scope is allowed, making a signal won't help error cascade
AstVarRef* const newp
= new AstVarRef{nodep->fileline(), nodep->name(), VAccess::READ};
nodep->replaceWith(newp);
VL_DO_DANGLING(pushDeletep(nodep), nodep);
createImplicitVar(m_curSymp, newp, m_modp, m_modSymp, err);
}
}
}

View File

@ -34,8 +34,10 @@ class Getter2;
endclass
class Foo #(type T=Getter1);
T foo_field;
int x;
function new(int y);
foo_field = new;
x = y;
endfunction
endclass
@ -50,6 +52,10 @@ class Bar #(type S=Getter2) extends Foo#(S);
function int get_field_int;
return field.get_int();
endfunction
function int get_foo_field_int;
return foo_field.get_int();
endfunction
endclass
// See also t_class_param_mod.v
@ -81,6 +87,7 @@ module t (/*AUTOARG*/);
if (b.x != 1) $stop;
if (b.get_field_int() != 2) $stop;
if (b.get_foo_field_int() != 2) $stop;
$write("*-* All Finished *-*\n");
$finish;