Fix function calls on arrayed interface, bug994.

Signed-off-by: Wilson Snyder <wsnyder@wsnyder.org>
This commit is contained in:
Johan Bjork 2015-11-11 20:40:24 -05:00 committed by Wilson Snyder
parent acabaab6ac
commit c7e0f2e196
6 changed files with 48 additions and 21 deletions

View File

@ -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]

View File

@ -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 {

View File

@ -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
}

View File

@ -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()) {

View File

@ -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*) {

View File

@ -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