forked from github/verilator
Fix function calls on arrayed interface, bug994.
Signed-off-by: Wilson Snyder <wsnyder@wsnyder.org>
This commit is contained in:
parent
acabaab6ac
commit
c7e0f2e196
2
Changes
2
Changes
@ -9,6 +9,8 @@ indicates the contributor was also the author of the fix; Thanks!
|
||||
|
||||
**** Fix size-changing cast on packed struct, bug993. [Johan Bjork]
|
||||
|
||||
**** Fix function calls on arrayed interface, bug994. [Johan Bjork]
|
||||
|
||||
**** Fix display %u, %v, %p, %z, bug989. [Johan Bjork]
|
||||
|
||||
|
||||
|
@ -1604,21 +1604,21 @@ public:
|
||||
AstNode* selp() const { return op1p(); } // op1 = Select expression
|
||||
};
|
||||
|
||||
class AstUnlinkedVarXRef : public AstNode {
|
||||
// As-of-yet unlinkable VarXRef
|
||||
class AstUnlinkedRef : public AstNode {
|
||||
// As-of-yet unlinkable Ref
|
||||
private:
|
||||
string m_name; // Var name
|
||||
public:
|
||||
AstUnlinkedVarXRef(FileLine* fl,
|
||||
AstVarXRef* vxrp, string name, AstNode* crp)
|
||||
AstUnlinkedRef(FileLine* fl,
|
||||
AstNode* refp, string name, AstNode* crp)
|
||||
: AstNode(fl)
|
||||
, m_name(name) {
|
||||
addNOp1p(vxrp); addNOp2p(crp); }
|
||||
ASTNODE_NODE_FUNCS(UnlinkedVarXRef, UNLINKEDVARXREF)
|
||||
addNOp1p(refp); addNOp2p(crp); }
|
||||
ASTNODE_NODE_FUNCS(UnlinkedRef, UNLINKEDREF)
|
||||
// ACCESSORS
|
||||
virtual string name() const { return m_name; } // * = Var name
|
||||
AstVarXRef* varxrefp() const { return op1p()->castVarXRef(); } // op1 = VarXRef
|
||||
AstNode* cellrefp() const { return op2p(); } // op1 = CellArrayRef or CellRef
|
||||
virtual string name() const { return m_name; } // * = Var name
|
||||
AstNode* refp() const { return op1p(); } // op1 = VarXRef or AstNodeFTaskRef
|
||||
AstNode* cellrefp() const { return op2p(); } // op2 = CellArrayRef or CellRef
|
||||
};
|
||||
|
||||
class AstBind : public AstNode {
|
||||
|
@ -1662,11 +1662,13 @@ private:
|
||||
else if (allowVar) {
|
||||
AstNode* newp;
|
||||
if (m_ds.m_dotText != "") {
|
||||
AstVarXRef* refp = new AstVarXRef(nodep->fileline(), nodep->name(), m_ds.m_dotText, false); // lvalue'ness computed later
|
||||
AstVarXRef* refp = new AstVarXRef(nodep->fileline(), nodep->name(),
|
||||
m_ds.m_dotText, false); // lvalue'ness computed later
|
||||
refp->varp(varp);
|
||||
m_ds.m_dotText = "";
|
||||
if (m_ds.m_unresolved && m_ds.m_unlinkedScope) {
|
||||
newp = new AstUnlinkedVarXRef(nodep->fileline(), refp->castVarXRef(), refp->name(), m_ds.m_unlinkedScope->unlinkFrBack());
|
||||
newp = new AstUnlinkedRef(nodep->fileline(), refp->castVarXRef(),
|
||||
refp->name(), m_ds.m_unlinkedScope->unlinkFrBack());
|
||||
m_ds.m_unlinkedScope = NULL;
|
||||
m_ds.m_unresolved = false;
|
||||
} else {
|
||||
@ -1857,7 +1859,15 @@ private:
|
||||
m_ds.m_dotPos = DP_SCOPE;
|
||||
m_ds.m_dotp = NULL;
|
||||
} else if (m_ds.m_dotp && m_ds.m_dotPos == DP_FINAL) {
|
||||
nodep->dotted(m_ds.m_dotText); // Maybe ""
|
||||
if (m_ds.m_unresolved && m_ds.m_unlinkedScope) {
|
||||
AstNode* newp = new AstUnlinkedRef(nodep->fileline(), nodep->cloneTree(false), nodep->name(), m_ds.m_unlinkedScope->unlinkFrBack());
|
||||
m_ds.m_unlinkedScope = NULL;
|
||||
m_ds.m_unresolved = false;
|
||||
nodep->replaceWith(newp);
|
||||
return;
|
||||
} else {
|
||||
nodep->dotted(m_ds.m_dotText); // Maybe ""
|
||||
}
|
||||
} else if (m_ds.m_dotp && m_ds.m_dotPos == DP_MEMBER) {
|
||||
// Found a Var, everything following is method call. {scope}.{var}.HERE {method} ( ARGS )
|
||||
AstNode* varEtcp = m_ds.m_dotp->lhsp()->unlinkFrBack();
|
||||
@ -2054,7 +2064,7 @@ private:
|
||||
UINFO(5," AstCellArrayRef: "<<nodep<<" "<<m_ds.ascii()<<endl);
|
||||
// Expression already iterated
|
||||
}
|
||||
virtual void visit(AstUnlinkedVarXRef* nodep, AstNUser*) {
|
||||
virtual void visit(AstUnlinkedRef* nodep, AstNUser*) {
|
||||
UINFO(5," AstCellArrayRef: "<<nodep<<" "<<m_ds.ascii()<<endl);
|
||||
// No need to iterate, if we have a UnlinkedVarXRef, we're already done
|
||||
}
|
||||
|
@ -205,7 +205,7 @@ private:
|
||||
if (AstNodeVarRef* varrefp = basefromp->castNodeVarRef()) { // Maybe varxref - so need to clone
|
||||
nodep->attrp(new AstAttrOf(nodep->fileline(), AstAttrType::VAR_BASE,
|
||||
varrefp->cloneTree(false)));
|
||||
} else if (AstUnlinkedVarXRef* uvxrp = basefromp->castUnlinkedVarXRef()) { // Maybe varxref - so need to clone
|
||||
} else if (AstUnlinkedRef* uvxrp = basefromp->castUnlinkedRef()) { // Maybe unlinked - so need to clone
|
||||
nodep->attrp(new AstAttrOf(nodep->fileline(), AstAttrType::VAR_BASE,
|
||||
uvxrp->cloneTree(false)));
|
||||
} else if (AstMemberSel* fromp = basefromp->castMemberSel()) {
|
||||
|
@ -108,7 +108,7 @@ private:
|
||||
typedef deque<AstCell*> CellList;
|
||||
CellList m_cellps; // Cells left to process (in this module)
|
||||
|
||||
string m_unlinkedTxt; // Text for AstUnlinkedVarXRef
|
||||
string m_unlinkedTxt; // Text for AstUnlinkedRef
|
||||
|
||||
// METHODS
|
||||
static int debug() {
|
||||
@ -254,11 +254,20 @@ private:
|
||||
virtual void visit(AstVarXRef* nodep, AstNUser*) {
|
||||
nodep->varp(NULL); // Needs relink, as may remove pointed-to var
|
||||
}
|
||||
virtual void visit(AstUnlinkedVarXRef* nodep, AstNUser*) {
|
||||
|
||||
virtual void visit(AstUnlinkedRef* nodep, AstNUser*) {
|
||||
m_unlinkedTxt.clear();
|
||||
nodep->cellrefp()->iterate(*this);
|
||||
nodep->varxrefp()->dotted(m_unlinkedTxt);
|
||||
nodep->replaceWith(nodep->varxrefp()->unlinkFrBack());
|
||||
AstVarXRef* varxrefp = nodep->op1p()->castVarXRef();
|
||||
AstNodeFTaskRef* taskref = nodep->op1p()->castNodeFTaskRef();
|
||||
if (varxrefp) {
|
||||
varxrefp->dotted(m_unlinkedTxt);
|
||||
} else if (taskref) {
|
||||
taskref->dotted(m_unlinkedTxt);
|
||||
} else {
|
||||
nodep->v3fatalSrc("Unexpected AstUnlinkedRef node");
|
||||
}
|
||||
nodep->replaceWith(nodep->op1p()->unlinkFrBack());
|
||||
pushDeletep(nodep); VL_DANGLING(nodep);
|
||||
}
|
||||
virtual void visit(AstCellArrayRef* nodep, AstNUser*) {
|
||||
|
@ -18,10 +18,16 @@ interface pads_if();
|
||||
endinterface
|
||||
|
||||
module t();
|
||||
pads_if padsif();
|
||||
pads_if padsif[1:0]();
|
||||
pads_if padsif_arr[1:0]();
|
||||
initial begin
|
||||
padsif.fOut(3);
|
||||
if (padsif.fIn(3) != 33) $stop;
|
||||
padsif[0].fOut(3);
|
||||
if (padsif[0].fIn(3) != 33) $stop;
|
||||
|
||||
padsif_arr[0].fOut(3);
|
||||
if (padsif_arr[0].fIn(3) != 33) $stop;
|
||||
padsif_arr[1].fOut(3);
|
||||
if (padsif_arr[1].fIn(3) != 33) $stop;
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user