void AstNodeClassDType::repairMemberCache() {
    clearCache();
    for (AstMemberDType* itemp = membersp(); itemp; itemp=itemp->nextp()->castMemberDType()) {
	if (m_members.find(itemp->name())!=m_members.end()) { itemp->v3error("Duplicate declaration of member name: "<<itemp->prettyName()); }
	else m_members.insert(make_pair(itemp->name(), itemp));
    }
}
Example #2
0
    virtual void visit(AstNodeClassDType* nodep, AstNUser*) {
	if (m_traVscp) {
	    if (nodep->packed() && !v3Global.opt.traceStructs()) {
		// Everything downstream is packed, so deal with as one trace unit
		// This may not be the nicest for user presentation, but is a much faster way to trace
		addTraceDecl(VNumRange());
	    } else {
		if (!nodep->packed()) {
		    addIgnore("Unsupported: Unpacked struct/union");
		} else {
		    for (AstMemberDType* itemp = nodep->membersp(); itemp; itemp=itemp->nextp()->castMemberDType()) {
			AstNodeDType* subtypep = itemp->subDTypep()->skipRefp();
			string oldShowname = m_traShowname;
			AstNode* oldValuep = m_traValuep;
			{
			    m_traShowname += string(" ")+itemp->prettyName();
			    if (nodep->castStructDType()) {
				m_traValuep = new AstSel(nodep->fileline(), m_traValuep->cloneTree(true),
							 itemp->lsb(), subtypep->width());
				subtypep->accept(*this);
				m_traValuep->deleteTree(); m_traValuep = NULL;
			    } else { // Else union, replicate fields
				subtypep->accept(*this);
			    }
			}
			m_traShowname = oldShowname;
			m_traValuep = oldValuep;
		    }
		}
	    }
	}
    }
const char* AstNodeClassDType::broken() const {
    set<AstMemberDType*> exists;
    for (AstMemberDType* itemp = membersp(); itemp; itemp=itemp->nextp()->castMemberDType()) {
	exists.insert(itemp);
    }
    for (MemberNameMap::const_iterator it=m_members.begin(); it!=m_members.end(); ++it) {
	if (VL_UNLIKELY(exists.find(it->second) == exists.end())) {
	    this->v3error("Internal: Structure member broken: "<<it->first);
	    return "member broken";
	}
    }
    return NULL;
}