mirror of
https://github.com/verilator/verilator.git
synced 2025-01-01 04:07:34 +00:00
Internals: Defer class extends
resolution until link
This commit is contained in:
parent
b71d49e55a
commit
15d1751b23
@ -84,6 +84,12 @@ class LinkNodeMatcherClass final : public VNodeMatcher {
|
|||||||
public:
|
public:
|
||||||
bool nodeMatch(const AstNode* nodep) const override { return VN_IS(nodep, Class); }
|
bool nodeMatch(const AstNode* nodep) const override { return VN_IS(nodep, Class); }
|
||||||
};
|
};
|
||||||
|
class LinkNodeMatcherClassOrPackage final : public VNodeMatcher {
|
||||||
|
public:
|
||||||
|
bool nodeMatch(const AstNode* nodep) const override {
|
||||||
|
return VN_IS(nodep, Class) || VN_IS(nodep, Package);
|
||||||
|
}
|
||||||
|
};
|
||||||
class LinkNodeMatcherFTask final : public VNodeMatcher {
|
class LinkNodeMatcherFTask final : public VNodeMatcher {
|
||||||
public:
|
public:
|
||||||
bool nodeMatch(const AstNode* nodep) const override { return VN_IS(nodep, NodeFTask); }
|
bool nodeMatch(const AstNode* nodep) const override { return VN_IS(nodep, NodeFTask); }
|
||||||
@ -2300,6 +2306,23 @@ class LinkDotResolveVisitor final : public VNVisitor {
|
|||||||
UASSERT_OBJ(ifaceTopVarp, nodep, "Can't find interface var ref: " << findName);
|
UASSERT_OBJ(ifaceTopVarp, nodep, "Can't find interface var ref: " << findName);
|
||||||
return ifaceTopVarp;
|
return ifaceTopVarp;
|
||||||
}
|
}
|
||||||
|
VSymEnt* findClassOrPackage(VSymEnt* lookSymp, AstClassOrPackageRef* nodep, bool classOnly,
|
||||||
|
const string& forWhat) {
|
||||||
|
if (nodep->classOrPackagep()) return m_statep->getNodeSym(nodep->classOrPackagep());
|
||||||
|
VSymEnt* const foundp = lookSymp->findIdFallback(nodep->name());
|
||||||
|
if (foundp) {
|
||||||
|
nodep->classOrPackageNodep(foundp->nodep());
|
||||||
|
return foundp;
|
||||||
|
} else {
|
||||||
|
const string suggest = m_statep->suggestSymFallback(lookSymp, nodep->name(),
|
||||||
|
LinkNodeMatcherClassOrPackage{});
|
||||||
|
nodep->v3error((classOnly ? "Class" : "Package/Class")
|
||||||
|
<< " for '" << forWhat // extends/implements
|
||||||
|
<< "' not found: " << nodep->prettyNameQ() << '\n'
|
||||||
|
<< (suggest.empty() ? "" : nodep->warnMore() + suggest));
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
void markAndCheckPinDup(AstPin* nodep, AstNode* refp, const char* whatp) {
|
void markAndCheckPinDup(AstPin* nodep, AstNode* refp, const char* whatp) {
|
||||||
const auto pair = m_usedPins.emplace(refp, nodep);
|
const auto pair = m_usedPins.emplace(refp, nodep);
|
||||||
if (!pair.second) {
|
if (!pair.second) {
|
||||||
@ -3812,6 +3835,9 @@ class LinkDotResolveVisitor final : public VNVisitor {
|
|||||||
if (AstClassOrPackageRef* lookNodep = VN_CAST(dotp->lhsp(), ClassOrPackageRef)) {
|
if (AstClassOrPackageRef* lookNodep = VN_CAST(dotp->lhsp(), ClassOrPackageRef)) {
|
||||||
iterate(lookNodep);
|
iterate(lookNodep);
|
||||||
cprp = dotp->rhsp();
|
cprp = dotp->rhsp();
|
||||||
|
VSymEnt* const foundp
|
||||||
|
= findClassOrPackage(lookSymp, lookNodep, false, nodep->verilogKwd());
|
||||||
|
if (!foundp) return;
|
||||||
UASSERT_OBJ(lookNodep->classOrPackagep(), nodep, "Bad package link");
|
UASSERT_OBJ(lookNodep->classOrPackagep(), nodep, "Bad package link");
|
||||||
lookSymp = m_statep->getNodeSym(lookNodep->classOrPackagep());
|
lookSymp = m_statep->getNodeSym(lookNodep->classOrPackagep());
|
||||||
} else {
|
} else {
|
||||||
@ -3825,7 +3851,8 @@ class LinkDotResolveVisitor final : public VNVisitor {
|
|||||||
nodep->v3error("Attempting to extend using non-class"); // LCOV_EXCL_LINE
|
nodep->v3error("Attempting to extend using non-class"); // LCOV_EXCL_LINE
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
VSymEnt* const foundp = lookSymp->findIdFallback(cpackagerefp->name());
|
VSymEnt* const foundp
|
||||||
|
= findClassOrPackage(lookSymp, cpackagerefp, true, nodep->verilogKwd());
|
||||||
if (foundp) {
|
if (foundp) {
|
||||||
if (AstClass* const classp = VN_CAST(foundp->nodep(), Class)) {
|
if (AstClass* const classp = VN_CAST(foundp->nodep(), Class)) {
|
||||||
AstPin* paramsp = cpackagerefp->paramsp();
|
AstPin* paramsp = cpackagerefp->paramsp();
|
||||||
@ -3850,12 +3877,6 @@ class LinkDotResolveVisitor final : public VNVisitor {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const string suggest = m_statep->suggestSymFallback(
|
|
||||||
m_curSymp, cpackagerefp->name(), LinkNodeMatcherClass{});
|
|
||||||
cpackagerefp->v3error(
|
|
||||||
"Class for '" << nodep->verilogKwd() // extends/implements
|
|
||||||
<< "' not found: " << cpackagerefp->prettyNameQ() << '\n'
|
|
||||||
<< (suggest.empty() ? "" : cpackagerefp->warnMore() + suggest));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!nodep->childDTypep()) nodep->v3error("Attempting to extend using non-class");
|
if (!nodep->childDTypep()) nodep->v3error("Attempting to extend using non-class");
|
||||||
|
@ -7227,12 +7227,12 @@ class_typeExtImpOne<nodeExprp>: // part of IEEE: class_type, where we either ge
|
|||||||
idAny
|
idAny
|
||||||
/*mid*/ { /* no nextId as not refing it above this*/ }
|
/*mid*/ { /* no nextId as not refing it above this*/ }
|
||||||
/*cont*/ parameter_value_assignmentClassE
|
/*cont*/ parameter_value_assignmentClassE
|
||||||
{ $$ = new AstClassOrPackageRef{$<fl>1, *$1, $<scp>1, $3};
|
{ $$ = new AstClassOrPackageRef{$<fl>1, *$1, nullptr, $3};
|
||||||
$<scp>$ = $<scp>1; }
|
$<scp>$ = $<scp>1; }
|
||||||
| idCC
|
| idCC
|
||||||
/*mid*/ { /* no nextId as not refing it above this*/ }
|
/*mid*/ { /* no nextId as not refing it above this*/ }
|
||||||
/*cont*/ parameter_value_assignmentClassE
|
/*cont*/ parameter_value_assignmentClassE
|
||||||
{ $$ = new AstClassOrPackageRef{$<fl>1, *$1, $<scp>1, $3};
|
{ $$ = new AstClassOrPackageRef{$<fl>1, *$1, nullptr, $3};
|
||||||
$<scp>$ = $<scp>1; }
|
$<scp>$ = $<scp>1; }
|
||||||
//
|
//
|
||||||
// // package_sopeIdFollows expanded
|
// // package_sopeIdFollows expanded
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
%Error: t/t_class_extends_nf_bad.v:10:19: Class for 'extends' not found: 'IsNotFound'
|
%Error: t/t_class_extends_nf_bad.v:15:19: Class for 'extends' not found: 'IsNotFound'
|
||||||
: ... Suggested alternative: 'IsFound'
|
: ... Suggested alternative: 'IsFound'
|
||||||
10 | class Cls extends IsNotFound;
|
15 | class Cls extends IsNotFound;
|
||||||
| ^~~~~~~~~~
|
| ^~~~~~~~~~
|
||||||
|
%Error: t/t_class_extends_nf_bad.v:18:25: Class for 'extends' not found: 'NotFound2'
|
||||||
|
: ... Suggested alternative: 'otFound2'
|
||||||
|
18 | class Cls2 extends Pkg::NotFound2;
|
||||||
|
| ^~~~~~~~~
|
||||||
%Error: Exiting due to
|
%Error: Exiting due to
|
||||||
|
@ -4,10 +4,18 @@
|
|||||||
// any use, without warranty, 2020 by Wilson Snyder.
|
// any use, without warranty, 2020 by Wilson Snyder.
|
||||||
// SPDX-License-Identifier: CC0-1.0
|
// SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
package Pkg;
|
||||||
|
class otFound2;
|
||||||
|
endclass
|
||||||
|
endpackage
|
||||||
|
|
||||||
class IsFound;
|
class IsFound;
|
||||||
endclass
|
endclass
|
||||||
|
|
||||||
class Cls extends IsNotFound;
|
class Cls extends IsNotFound; // BAD: not found
|
||||||
|
endclass
|
||||||
|
|
||||||
|
class Cls2 extends Pkg::NotFound2; // BAD: not found
|
||||||
endclass
|
endclass
|
||||||
|
|
||||||
module t (/*AUTOARG*/);
|
module t (/*AUTOARG*/);
|
||||||
|
Loading…
Reference in New Issue
Block a user