mirror of
https://github.com/verilator/verilator.git
synced 2026-10-06 01:54:01 +02:00
Support local and protected on typedef (#5460).
This commit is contained in:
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user