From c7e0f2e196251d622dfe62be57c0e0a4249db43b Mon Sep 17 00:00:00 2001 From: Johan Bjork Date: Wed, 11 Nov 2015 20:40:24 -0500 Subject: [PATCH] Fix function calls on arrayed interface, bug994. Signed-off-by: Wilson Snyder --- Changes | 2 ++ src/V3AstNodes.h | 18 +++++++++--------- src/V3LinkDot.cpp | 18 ++++++++++++++---- src/V3LinkResolve.cpp | 2 +- src/V3Param.cpp | 17 +++++++++++++---- test_regress/t/t_interface_mp_func.v | 12 +++++++++--- 6 files changed, 48 insertions(+), 21 deletions(-) diff --git a/Changes b/Changes index c61e56fa5..4f4758f1d 100644 --- a/Changes +++ b/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] diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index 39105e715..c0030e737 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -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 { diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index 3c88f993f..461a6cbd1 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -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: "<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()) { diff --git a/src/V3Param.cpp b/src/V3Param.cpp index 522832840..b7a900831 100644 --- a/src/V3Param.cpp +++ b/src/V3Param.cpp @@ -108,7 +108,7 @@ private: typedef deque 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*) { diff --git a/test_regress/t/t_interface_mp_func.v b/test_regress/t/t_interface_mp_func.v index 35fc69536..504d769b3 100644 --- a/test_regress/t/t_interface_mp_func.v +++ b/test_regress/t/t_interface_mp_func.v @@ -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