diff --git a/src/V3Ast.h b/src/V3Ast.h
index c491f04f7..b80bf7409 100644
--- a/src/V3Ast.h
+++ b/src/V3Ast.h
@@ -1708,6 +1708,7 @@ public:
virtual AstNodeDType* virtRefDTypep() const { return NULL; } // Iff has a non-null refDTypep(), as generic node function
virtual void virtRefDTypep(AstNodeDType* nodep) { } // Iff has refDTypep(), set as generic node function
virtual bool similarDType(AstNodeDType* samep) const = 0; // Assignable equivalence. Call skipRefp() on this and samep before calling
+ virtual AstNodeDType* subDTypep() const { return NULL; } // Iff has a non-null subDTypep(), as generic node function
//
// Changing the width may confuse the data type resolution, so must clear TypeTable cache after use.
void widthForce(int width, int sized) { m_width=width; m_widthMin=sized; }
@@ -1811,7 +1812,7 @@ public:
AstNodeDType* getChildDTypep() const { return childDTypep(); }
AstNodeDType* childDTypep() const { return op1p()->castNodeDType(); } // op1 = Range of variable
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
- AstNodeDType* subDTypep() const { return m_refDTypep ? m_refDTypep : childDTypep(); }
+ virtual AstNodeDType* subDTypep() const { return m_refDTypep ? m_refDTypep : childDTypep(); }
void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; }
virtual AstNodeDType* virtRefDTypep() const { return m_refDTypep; }
virtual void virtRefDTypep(AstNodeDType* nodep) { refDTypep(nodep); }
diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h
index a5e322fbe..03b5a5497 100644
--- a/src/V3AstNodes.h
+++ b/src/V3AstNodes.h
@@ -179,7 +179,7 @@ public:
AstNodeDType* getChildDTypep() const { return childDTypep(); }
AstNodeDType* childDTypep() const { return op1p()->castNodeDType(); } // op1 = Type assigning to
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
- AstNodeDType* subDTypep() const { return dtypep() ? dtypep() : childDTypep(); }
+ virtual AstNodeDType* subDTypep() const { return dtypep() ? dtypep() : childDTypep(); }
virtual AstBasicDType* basicp() const { return subDTypep()->basicp(); } // (Slow) recurse down to find basic data type
virtual AstNodeDType* skipRefp() const { return subDTypep()->skipRefp(); }
virtual AstNodeDType* skipRefToConstp() const { return subDTypep()->skipRefToConstp(); }
@@ -217,7 +217,7 @@ public:
AstNodeDType* getChildDTypep() const { return childDTypep(); }
AstNodeDType* childDTypep() const { return op1p()->castNodeDType(); } // op1 = Type assigning to
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
- AstNodeDType* subDTypep() const { return dtypep() ? dtypep() : childDTypep(); }
+ virtual AstNodeDType* subDTypep() const { return dtypep() ? dtypep() : childDTypep(); }
void addAttrsp(AstNode* nodep) { addNOp4p(nodep); }
AstNode* attrsp() const { return op4p(); } // op4 = Attributes during early parse
// METHODS
@@ -267,7 +267,7 @@ public:
AstNodeDType* getChildDTypep() const { return childDTypep(); }
AstNodeDType* childDTypep() const { return op1p()->castNodeDType(); } // op1 = Range of variable
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
- AstNodeDType* subDTypep() const { return dtypep() ? dtypep() : childDTypep(); }
+ virtual AstNodeDType* subDTypep() const { return dtypep() ? dtypep() : childDTypep(); }
void* containerp() const { return m_containerp; }
// METHODS
AstNodeDType* dtypeSkipRefp() const { return dtypep()->skipRefp(); } // op1 = Range of variable
@@ -478,7 +478,7 @@ public:
AstNodeDType* getChildDTypep() const { return childDTypep(); }
AstNodeDType* childDTypep() const { return op1p()->castNodeDType(); } // op1 = Range of variable
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
- AstNodeDType* subDTypep() const { return m_refDTypep ? m_refDTypep : childDTypep(); } // op1 = Range of variable
+ virtual AstNodeDType* subDTypep() const { return m_refDTypep ? m_refDTypep : childDTypep(); } // op1 = Range of variable
void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; }
virtual AstNodeDType* virtRefDTypep() const { return m_refDTypep; }
virtual void virtRefDTypep(AstNodeDType* nodep) { refDTypep(nodep); }
@@ -588,7 +588,7 @@ public:
void refDTypep(AstNodeDType* nodep) { m_refDTypep=nodep; }
virtual AstNodeDType* virtRefDTypep() const { return refDTypep(); }
virtual void virtRefDTypep(AstNodeDType* nodep) { refDTypep(nodep); }
- AstNodeDType* subDTypep() const { return m_refDTypep; }
+ virtual AstNodeDType* subDTypep() const { return m_refDTypep; }
AstPackage* packagep() const { return m_packagep; }
void packagep(AstPackage* nodep) { m_packagep=nodep; }
};
@@ -642,7 +642,7 @@ public:
AstNodeDType* getChildDTypep() const { return childDTypep(); }
AstNodeDType* childDTypep() const { return op1p()->castNodeDType(); } // op1 = Range of variable
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
- AstNodeDType* subDTypep() const { return m_refDTypep ? m_refDTypep : childDTypep(); }
+ virtual AstNodeDType* subDTypep() const { return m_refDTypep ? m_refDTypep : childDTypep(); }
void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; }
virtual AstNodeDType* virtRefDTypep() const { return m_refDTypep; }
virtual void virtRefDTypep(AstNodeDType* nodep) { refDTypep(nodep); }
@@ -738,7 +738,7 @@ public:
AstNodeDType* getChildDTypep() const { return childDTypep(); }
AstNodeDType* childDTypep() const { return op1p()->castNodeDType(); } // op1 = Data type
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
- AstNodeDType* subDTypep() const { return m_refDTypep ? m_refDTypep : childDTypep(); } // op1 = Range of variable
+ virtual AstNodeDType* subDTypep() const { return m_refDTypep ? m_refDTypep : childDTypep(); } // op1 = Range of variable
void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; }
virtual AstNodeDType* virtRefDTypep() const { return m_refDTypep; }
virtual void virtRefDTypep(AstNodeDType* nodep) { refDTypep(nodep); }
@@ -1103,7 +1103,7 @@ public:
void addAttrsp(AstNode* nodep) { addNOp4p(nodep); }
AstNode* attrsp() const { return op4p(); } // op4 = Attributes during early parse
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
- AstNodeDType* subDTypep() const { return dtypep() ? dtypep() : childDTypep(); }
+ virtual AstNodeDType* subDTypep() const { return dtypep() ? dtypep() : childDTypep(); }
void attrClockEn(bool flag) { m_attrClockEn = flag; }
void attrClocker(AstVarAttrClocker flag) { m_attrClocker = flag; }
void attrFileDescr(bool flag) { m_fileDescr = flag; }
@@ -4911,7 +4911,7 @@ public:
AstNodeDType* getChildDTypep() const { return childDTypep(); }
AstNodeDType* childDTypep() const { return op1p()->castNodeDType(); } // op1 = Type assigning to
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
- AstNodeDType* subDTypep() const { return dtypep() ? dtypep() : childDTypep(); }
+ virtual AstNodeDType* subDTypep() const { return dtypep() ? dtypep() : childDTypep(); }
AstNode* itemsp() const { return op2p(); } // op2 = AstPatReplicate, AstPatMember, etc
};
class AstPatMember : public AstNodeMath {
diff --git a/src/V3EmitXml.cpp b/src/V3EmitXml.cpp
index 5e840c5b3..6da40f7c3 100644
--- a/src/V3EmitXml.cpp
+++ b/src/V3EmitXml.cpp
@@ -80,9 +80,9 @@ class EmitXmlFileVisitor : public AstNVisitor {
if (nodep->name()!="") { puts(" name="); putsQuoted(nodep->prettyName()); }
if (nodep->tag()!="") { puts(" tag="); putsQuoted(nodep->tag()); }
if (AstNodeDType* dtp = nodep->castNodeDType()) {
- if (dtp->skipRefp() && dtp->skipRefp()!=dtp) { puts(" sub_dtype_id="); outputId(dtp->skipRefp()); }
+ if (dtp->subDTypep()) { puts(" sub_dtype_id="); outputId(dtp->subDTypep()->skipRefp()); }
} else {
- if (nodep->dtypep()) { puts(" dtype_id="); outputId(nodep->dtypep()); }
+ if (nodep->dtypep()) { puts(" dtype_id="); outputId(nodep->dtypep()->skipRefp()); }
}
}
void outputChildrenEnd(AstNode* nodep, string tag) {
@@ -127,7 +127,7 @@ class EmitXmlFileVisitor : public AstNVisitor {
}
virtual void visit(AstAssignW* nodep) {
outputTag(nodep, "contassign"); // IEEE: vpiContAssign
- outputChildrenEnd(nodep, "contAssign");
+ outputChildrenEnd(nodep, "contassign");
}
// Data types
diff --git a/test_regress/t/t_xml_first.out b/test_regress/t/t_xml_first.out
new file mode 100644
index 000000000..a6bbcae9c
--- /dev/null
+++ b/test_regress/t/t_xml_first.out
@@ -0,0 +1,70 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test_regress/t/t_xml_first.pl b/test_regress/t/t_xml_first.pl
index 366518305..a544448e5 100755
--- a/test_regress/t/t_xml_first.pl
+++ b/test_regress/t/t_xml_first.pl
@@ -16,7 +16,6 @@ compile (
verilator_make_gcc => 0,
);
-file_grep ($out_filename, qr//);
-ok(1);
+ok(files_identical("$out_filename", "t/$Self->{name}.out"));
1;
diff --git a/test_regress/t/t_xml_tag.out b/test_regress/t/t_xml_tag.out
index 594134a53..57d962264 100644
--- a/test_regress/t/t_xml_tag.out
+++ b/test_regress/t/t_xml_tag.out
@@ -17,18 +17,25 @@
+
-
-
-
-
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test_regress/t/t_xml_tag.v b/test_regress/t/t_xml_tag.v
index db8ae3bd9..d644ad559 100644
--- a/test_regress/t/t_xml_tag.v
+++ b/test_regress/t/t_xml_tag.v
@@ -20,6 +20,6 @@ module m
// This is a comment
- my_struct this_struct;
+ my_struct this_struct [2];
endmodule