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 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]
|
**** Fix display %u, %v, %p, %z, bug989. [Johan Bjork]
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1604,21 +1604,21 @@ public:
|
||||||
AstNode* selp() const { return op1p(); } // op1 = Select expression
|
AstNode* selp() const { return op1p(); } // op1 = Select expression
|
||||||
};
|
};
|
||||||
|
|
||||||
class AstUnlinkedVarXRef : public AstNode {
|
class AstUnlinkedRef : public AstNode {
|
||||||
// As-of-yet unlinkable VarXRef
|
// As-of-yet unlinkable Ref
|
||||||
private:
|
private:
|
||||||
string m_name; // Var name
|
string m_name; // Var name
|
||||||
public:
|
public:
|
||||||
AstUnlinkedVarXRef(FileLine* fl,
|
AstUnlinkedRef(FileLine* fl,
|
||||||
AstVarXRef* vxrp, string name, AstNode* crp)
|
AstNode* refp, string name, AstNode* crp)
|
||||||
: AstNode(fl)
|
: AstNode(fl)
|
||||||
, m_name(name) {
|
, m_name(name) {
|
||||||
addNOp1p(vxrp); addNOp2p(crp); }
|
addNOp1p(refp); addNOp2p(crp); }
|
||||||
ASTNODE_NODE_FUNCS(UnlinkedVarXRef, UNLINKEDVARXREF)
|
ASTNODE_NODE_FUNCS(UnlinkedRef, UNLINKEDREF)
|
||||||
// ACCESSORS
|
// ACCESSORS
|
||||||
virtual string name() const { return m_name; } // * = Var name
|
virtual string name() const { return m_name; } // * = Var name
|
||||||
AstVarXRef* varxrefp() const { return op1p()->castVarXRef(); } // op1 = VarXRef
|
AstNode* refp() const { return op1p(); } // op1 = VarXRef or AstNodeFTaskRef
|
||||||
AstNode* cellrefp() const { return op2p(); } // op1 = CellArrayRef or CellRef
|
AstNode* cellrefp() const { return op2p(); } // op2 = CellArrayRef or CellRef
|
||||||
};
|
};
|
||||||
|
|
||||||
class AstBind : public AstNode {
|
class AstBind : public AstNode {
|
||||||
|
|
|
||||||
|
|
@ -1662,11 +1662,13 @@ private:
|
||||||
else if (allowVar) {
|
else if (allowVar) {
|
||||||
AstNode* newp;
|
AstNode* newp;
|
||||||
if (m_ds.m_dotText != "") {
|
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);
|
refp->varp(varp);
|
||||||
m_ds.m_dotText = "";
|
m_ds.m_dotText = "";
|
||||||
if (m_ds.m_unresolved && m_ds.m_unlinkedScope) {
|
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_unlinkedScope = NULL;
|
||||||
m_ds.m_unresolved = false;
|
m_ds.m_unresolved = false;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1857,7 +1859,15 @@ private:
|
||||||
m_ds.m_dotPos = DP_SCOPE;
|
m_ds.m_dotPos = DP_SCOPE;
|
||||||
m_ds.m_dotp = NULL;
|
m_ds.m_dotp = NULL;
|
||||||
} else if (m_ds.m_dotp && m_ds.m_dotPos == DP_FINAL) {
|
} 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) {
|
} 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 )
|
// Found a Var, everything following is method call. {scope}.{var}.HERE {method} ( ARGS )
|
||||||
AstNode* varEtcp = m_ds.m_dotp->lhsp()->unlinkFrBack();
|
AstNode* varEtcp = m_ds.m_dotp->lhsp()->unlinkFrBack();
|
||||||
|
|
@ -2054,7 +2064,7 @@ private:
|
||||||
UINFO(5," AstCellArrayRef: "<<nodep<<" "<<m_ds.ascii()<<endl);
|
UINFO(5," AstCellArrayRef: "<<nodep<<" "<<m_ds.ascii()<<endl);
|
||||||
// Expression already iterated
|
// Expression already iterated
|
||||||
}
|
}
|
||||||
virtual void visit(AstUnlinkedVarXRef* nodep, AstNUser*) {
|
virtual void visit(AstUnlinkedRef* nodep, AstNUser*) {
|
||||||
UINFO(5," AstCellArrayRef: "<<nodep<<" "<<m_ds.ascii()<<endl);
|
UINFO(5," AstCellArrayRef: "<<nodep<<" "<<m_ds.ascii()<<endl);
|
||||||
// No need to iterate, if we have a UnlinkedVarXRef, we're already done
|
// 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
|
if (AstNodeVarRef* varrefp = basefromp->castNodeVarRef()) { // Maybe varxref - so need to clone
|
||||||
nodep->attrp(new AstAttrOf(nodep->fileline(), AstAttrType::VAR_BASE,
|
nodep->attrp(new AstAttrOf(nodep->fileline(), AstAttrType::VAR_BASE,
|
||||||
varrefp->cloneTree(false)));
|
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,
|
nodep->attrp(new AstAttrOf(nodep->fileline(), AstAttrType::VAR_BASE,
|
||||||
uvxrp->cloneTree(false)));
|
uvxrp->cloneTree(false)));
|
||||||
} else if (AstMemberSel* fromp = basefromp->castMemberSel()) {
|
} else if (AstMemberSel* fromp = basefromp->castMemberSel()) {
|
||||||
|
|
|
||||||
|
|
@ -108,7 +108,7 @@ private:
|
||||||
typedef deque<AstCell*> CellList;
|
typedef deque<AstCell*> CellList;
|
||||||
CellList m_cellps; // Cells left to process (in this module)
|
CellList m_cellps; // Cells left to process (in this module)
|
||||||
|
|
||||||
string m_unlinkedTxt; // Text for AstUnlinkedVarXRef
|
string m_unlinkedTxt; // Text for AstUnlinkedRef
|
||||||
|
|
||||||
// METHODS
|
// METHODS
|
||||||
static int debug() {
|
static int debug() {
|
||||||
|
|
@ -254,11 +254,20 @@ private:
|
||||||
virtual void visit(AstVarXRef* nodep, AstNUser*) {
|
virtual void visit(AstVarXRef* nodep, AstNUser*) {
|
||||||
nodep->varp(NULL); // Needs relink, as may remove pointed-to var
|
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();
|
m_unlinkedTxt.clear();
|
||||||
nodep->cellrefp()->iterate(*this);
|
nodep->cellrefp()->iterate(*this);
|
||||||
nodep->varxrefp()->dotted(m_unlinkedTxt);
|
AstVarXRef* varxrefp = nodep->op1p()->castVarXRef();
|
||||||
nodep->replaceWith(nodep->varxrefp()->unlinkFrBack());
|
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);
|
pushDeletep(nodep); VL_DANGLING(nodep);
|
||||||
}
|
}
|
||||||
virtual void visit(AstCellArrayRef* nodep, AstNUser*) {
|
virtual void visit(AstCellArrayRef* nodep, AstNUser*) {
|
||||||
|
|
|
||||||
|
|
@ -18,10 +18,16 @@ interface pads_if();
|
||||||
endinterface
|
endinterface
|
||||||
|
|
||||||
module t();
|
module t();
|
||||||
pads_if padsif();
|
pads_if padsif[1:0]();
|
||||||
|
pads_if padsif_arr[1:0]();
|
||||||
initial begin
|
initial begin
|
||||||
padsif.fOut(3);
|
padsif[0].fOut(3);
|
||||||
if (padsif.fIn(3) != 33) $stop;
|
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");
|
$write("*-* All Finished *-*\n");
|
||||||
$finish;
|
$finish;
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue