Support local and protected on typedef (#5460).

This commit is contained in:
Wilson Snyder
2024-10-06 18:08:40 -04:00
parent bc8a332ee8
commit 28ecd8e908
12 changed files with 104 additions and 22 deletions
+9 -1
View File
@@ -1714,12 +1714,16 @@ class AstTypedef final : public AstNode {
string m_name;
string m_tag; // Holds the string of the verilator tag -- used in XML output.
bool m_attrPublic = false;
bool m_isHideLocal : 1; // Verilog local
bool m_isHideProtected : 1; // Verilog protected
public:
AstTypedef(FileLine* fl, const string& name, AstNode* attrsp, VFlagChildDType,
AstNodeDType* dtp)
: ASTGEN_SUPER_Typedef(fl)
, m_name{name} {
, m_name{name}
, m_isHideLocal{false}
, m_isHideProtected{false} {
childDTypep(dtp); // Only for parser
addAttrsp(attrsp);
dtypep(nullptr); // V3Width will resolve
@@ -1738,6 +1742,10 @@ public:
void name(const string& flag) override { m_name = flag; }
bool attrPublic() const { return m_attrPublic; }
void attrPublic(bool flag) { m_attrPublic = flag; }
bool isHideLocal() const { return m_isHideLocal; }
void isHideLocal(bool flag) { m_isHideLocal = flag; }
bool isHideProtected() const { return m_isHideProtected; }
void isHideProtected(bool flag) { m_isHideProtected = flag; }
void tag(const string& text) override { m_tag = text; }
string tag() const override { return m_tag; }
};
+3 -2
View File
@@ -2031,9 +2031,10 @@ void AstRefDType::dump(std::ostream& str) const {
if (!s_recursing) { // Prevent infinite dump if circular typedefs
s_recursing = true;
str << " -> ";
if (const auto subp = typedefp()) {
if (const auto subp = subDTypep()) {
if (typedefp()) str << "typedef=" << static_cast<void*>(typedefp())<< " -> ";
subp->dump(str);
} else if (const auto subp = subDTypep()) {
} else if (const auto subp = typedefp()) {
subp->dump(str);
}
s_recursing = false;
+10 -2
View File
@@ -74,11 +74,19 @@ struct VMemberQualifiers final {
if (m_static) nodep->isStatic(true);
if (m_virtual) nodep->isVirtual(true);
if (m_const || m_rand || m_randc) {
nodep->v3error("Syntax error: 'const'/'rand'/'randc' not allowed before "
"function/task declaration");
nodep->v3error("Syntax error: 'const'/'rand'/'randc' not allowed "
"before function/task declaration");
}
}
}
void applyToNodes(AstTypedef* nodep) const {
if (m_local) nodep->isHideLocal(true);
if (m_protected) nodep->isHideProtected(true);
if (m_static || m_virtual || m_rand || m_randc) {
nodep->v3error("Syntax error: 'static'/'virtual'/'rand'/'randc' not allowed "
"before typedef declaration");
}
}
void applyToNodes(AstVar* nodesp) const {
for (AstVar* nodep = nodesp; nodep; nodep = VN_AS(nodep->nextp(), Var)) {
if (m_rand) nodep->rand(VRandAttr::RAND);
+1 -3
View File
@@ -1853,13 +1853,11 @@ class WidthVisitor final : public VNVisitor {
if (AstNodeDType* typeofDtp = VN_CAST(nodep->typeofp(), NodeDType)) {
// It's directly a type, e.g. "type(int)"
typeofDtp = iterateEditMoveDTypep(nodep, typeofDtp); // Changes typeofp
nodep->typedefp(nullptr);
nodep->refDTypep(typeofDtp);
} else {
// Type comes from expression's type, e.g. "type(variable)"
userIterateAndNext(nodep->typeofp(), WidthVP{SELF, BOTH}.p());
AstNode* const typeofp = nodep->typeofp();
nodep->typedefp(nullptr);
nodep->refDTypep(typeofp->dtypep());
VL_DO_DANGLING(typeofp->unlinkFrBack()->deleteTree(), typeofp);
}
@@ -1873,7 +1871,6 @@ class WidthVisitor final : public VNVisitor {
// this node's childDTypep
userIterate(nodep->subDTypep(), nullptr);
nodep->refDTypep(iterateEditMoveDTypep(nodep, nodep->subDTypep()));
nodep->typedefp(nullptr); // Note until line above subDTypep() may have followed this
// Widths are resolved, but special iterate to check for recursion
userIterate(nodep->subDTypep(), nullptr);
}
@@ -1883,6 +1880,7 @@ class WidthVisitor final : public VNVisitor {
nodep->dtypeFrom(nodep->subDTypep());
nodep->widthFromSub(nodep->subDTypep());
UINFO(4, "dtWidthed " << nodep << endl);
// No nodep->typedefp(nullptr) for now; V3WidthCommit needs to check accesses
nodep->doingWidth(false);
}
void visit(AstTypedef* nodep) override {
+15 -6
View File
@@ -85,12 +85,15 @@ private:
"Only rand_mode() and constraint_mode() can have no def");
return;
}
if (const auto varp = VN_CAST(defp, Var)) {
local = varp->isHideLocal();
prot = varp->isHideProtected();
} else if (const auto ftaskp = VN_CAST(defp, NodeFTask)) {
local = ftaskp->isHideLocal();
prot = ftaskp->isHideProtected();
if (const auto anodep = VN_CAST(defp, Var)) {
local = anodep->isHideLocal();
prot = anodep->isHideProtected();
} else if (const auto anodep = VN_CAST(defp, NodeFTask)) {
local = anodep->isHideLocal();
prot = anodep->isHideProtected();
} else if (const auto anodep = VN_CAST(defp, Typedef)) {
local = anodep->isHideLocal();
prot = anodep->isHideProtected();
} else {
nodep->v3fatalSrc("ref to unhandled definition type " << defp->prettyTypeName());
}
@@ -178,6 +181,12 @@ private:
nodep->unlinkFrBack(); // Make non-child
v3Global.rootp()->typeTablep()->addTypesp(nodep);
}
void visit(AstRefDType* nodep) override {
visitIterateNodeDType(nodep);
if (!nodep->typedefp()) return; // Already checked and cleared
classEncapCheck(nodep, nodep->typedefp(), VN_CAST(nodep->classOrPackagep(), Class));
nodep->typedefp(nullptr); // No longer needed
}
void visitIterateNodeDType(AstNodeDType* nodep) {
// Rather than use dtypeChg which may make new nodes, we edit in place,
// as we don't need to preserve any widthMin's, and every dtype with the same width
+8 -6
View File
@@ -186,14 +186,14 @@ public:
}
AstNode* createTypedef(FileLine* fl, const string& name, AstNode* attrsp, AstNodeDType* basep,
AstNodeRange* rangep) {
AstNode* const nodep = new AstTypedef{fl, name, attrsp, VFlagChildDType{},
AstTypedef* const nodep = new AstTypedef{fl, name, attrsp, VFlagChildDType{},
GRAMMARP->createArray(basep, rangep, false)};
SYMP->reinsert(nodep);
PARSEP->tagNodep(nodep);
return nodep;
}
AstNode* createTypedefFwd(FileLine* fl, const string& name) {
AstNode* const nodep = new AstTypedefFwd{fl, name};
AstTypedefFwd* const nodep = new AstTypedefFwd{fl, name};
SYMP->reinsert(nodep);
PARSEP->tagNodep(nodep);
return nodep;
@@ -2479,11 +2479,13 @@ data_declaration<nodep>: // ==IEEE: data_declaration
;
class_property<nodep>: // ==IEEE: class_property, which is {property_qualifier} data_declaration
memberQualListE data_declarationVarClass { $$ = $2; $1.applyToNodes($2); }
memberQualListE data_declarationVarClass
{ $$ = $2; $1.applyToNodes($2); }
| memberQualListE type_declaration
{ $$ = $2; if (VN_IS($2, Typedef)) $1.applyToNodes(VN_AS($2, Typedef)); }
// // UNSUP: Import needs to apply local/protected from memberQualList, and error on others
| memberQualListE type_declaration { $$ = $2; }
// // UNSUP: Import needs to apply local/protected from memberQualList, and error on others
| memberQualListE package_import_declaration { $$ = $2; }
| memberQualListE package_import_declaration
{ $$ = $2; }
// // IEEE: virtual_interface_declaration
// // "yVIRTUAL yID yID" looks just like a data_declaration
// // Therefore the virtual_interface_declaration term isn't used