1 // -*- mode: C++; c-file-style: "cc-mode" -*-
2 //*************************************************************************
3 // DESCRIPTION: Verilator: Ast node structures
5 // Code available from: http://www.veripool.org/verilator
7 //*************************************************************************
9 // Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
10 // redistribute it and/or modify it under the terms of either the GNU
11 // Lesser General Public License Version 3 or the Perl Artistic License
14 // Verilator is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 // GNU General Public License for more details.
19 //*************************************************************************
21 #include "config_build.h"
22 #include "verilatedos.h"
29 #include VL_INCLUDE_UNORDERED_SET
35 //======================================================================
38 // We need these here, because the classes they point to aren't defined when we declare the class
39 const char* AstIfaceRefDType::broken() const {
40 BROKEN_RTN(m_ifacep && !m_ifacep->brokeExists());
41 BROKEN_RTN(m_cellp && !m_cellp->brokeExists());
42 BROKEN_RTN(m_modportp && !m_modportp->brokeExists());
46 AstIface* AstIfaceRefDType::ifaceViaCellp() const {
47 return ((m_cellp && m_cellp->modp()) ? m_cellp->modp()->castIface() : m_ifacep);
50 const char* AstNodeVarRef::broken() const {
51 BROKEN_RTN(m_varScopep && !m_varScopep->brokeExists());
52 BROKEN_RTN(m_varp && !m_varp->brokeExists());
56 void AstNodeVarRef::cloneRelink() {
57 if (m_varp && m_varp->clonep()) { m_varp = m_varp->clonep(); }
60 int AstNodeSel::bitConst() const {
61 AstConst* constp=bitp()->castConst(); return (constp?constp->toSInt():0);
64 void AstNodeClassDType::repairMemberCache() {
66 for (AstMemberDType* itemp = membersp(); itemp; itemp=itemp->nextp()->castMemberDType()) {
67 if (m_members.find(itemp->name())!=m_members.end()) { itemp->v3error("Duplicate declaration of member name: "<<itemp->prettyName()); }
68 else m_members.insert(make_pair(itemp->name(), itemp));
72 const char* AstNodeClassDType::broken() const {
73 vl_unordered_set<AstMemberDType*> exists;
74 for (AstMemberDType* itemp = membersp(); itemp; itemp=itemp->nextp()->castMemberDType()) {
77 for (MemberNameMap::const_iterator it=m_members.begin(); it!=m_members.end(); ++it) {
78 if (VL_UNLIKELY(exists.find(it->second) == exists.end())) {
79 this->v3error("Internal: Structure member broken: "<<it->first);
80 return "member broken";
86 int AstBasicDType::widthAlignBytes() const {
87 if (width()<=8) return 1;
88 else if (width()<=16) return 2;
89 else if (isQuad()) return 8;
93 int AstBasicDType::widthTotalBytes() const {
94 if (width()<=8) return 1;
95 else if (width()<=16) return 2;
96 else if (isQuad()) return 8;
97 else return widthWords()*(VL_WORDSIZE/8);
100 int AstNodeClassDType::widthTotalBytes() const {
101 if (width()<=8) return 1;
102 else if (width()<=16) return 2;
103 else if (isQuad()) return 8;
104 else return widthWords()*(VL_WORDSIZE/8);
107 int AstNodeClassDType::widthAlignBytes() const {
108 // Could do max across members but that would be slow,
109 // instead intuit based on total structure size
110 if (width()<=8) return 1;
111 else if (width()<=16) return 2;
112 else if (width()<=32) return 4;
116 AstNodeBiop* AstEq::newTyped(FileLine* fl, AstNode* lhsp, AstNode* rhsp) {
117 if (lhsp->isDouble() && rhsp->isDouble()) {
118 return new AstEqD(fl, lhsp, rhsp);
120 return new AstEq(fl, lhsp, rhsp);
124 AstNodeBiop* AstGte::newTyped(FileLine* fl, AstNode* lhsp, AstNode* rhsp) {
125 if (lhsp->isDouble() && rhsp->isDouble()) {
126 return new AstGteD(fl, lhsp, rhsp);
127 } else if (lhsp->isSigned() && rhsp->isSigned()) {
128 return new AstGteS(fl, lhsp, rhsp);
130 return new AstGte(fl, lhsp, rhsp);
134 AstNodeBiop* AstLte::newTyped(FileLine* fl, AstNode* lhsp, AstNode* rhsp) {
135 if (lhsp->isDouble() && rhsp->isDouble()) {
136 return new AstLteD(fl, lhsp, rhsp);
137 } else if (lhsp->isSigned() && rhsp->isSigned()) {
138 return new AstLteS(fl, lhsp, rhsp);
140 return new AstLte(fl, lhsp, rhsp);
144 AstNodeBiop* AstEqWild::newTyped(FileLine* fl, AstNode* lhsp, AstNode* rhsp) {
145 if (lhsp->isDouble() && rhsp->isDouble()) {
146 return new AstEqD(fl, lhsp, rhsp);
148 return new AstEqWild(fl, lhsp, rhsp);
152 bool AstVar::isSigPublic() const {
153 return (m_sigPublic || (v3Global.opt.allPublic() && !isTemp() && !isGenVar()));
156 bool AstVar::isScQuad() const {
157 return (isSc() && isQuad() && !isScBv() && !isScBigUint());
160 bool AstVar::isScBv() const {
161 return ((isSc() && width() >= v3Global.opt.pinsBv()) || m_attrScBv);
164 bool AstVar::isScUint() const {
165 return ((isSc() && v3Global.opt.pinsScUint() && width() >= 2 && width() <= 64) && !isScBv());
168 bool AstVar::isScBigUint() const {
169 return ((isSc() && v3Global.opt.pinsScBigUint() && width() >= 65 && width() <= 512) && !isScBv());
172 void AstVar::combineType(AstVarType type) {
173 // These flags get combined with the existing settings of the flags.
174 // We don't test varType for certain types, instead set flags since
175 // when we combine wires cross-hierarchy we need a union of all characteristics.
176 if (type == AstVarType::SUPPLY0) type = AstVarType::WIRE;
177 if (type == AstVarType::SUPPLY1) type = AstVarType::WIRE;
178 m_varType=type; // For debugging prints only
179 // These flags get combined with the existing settings of the flags.
180 if (type==AstVarType::INPUT || type==AstVarType::INOUT)
182 if (type==AstVarType::OUTPUT || type==AstVarType::INOUT) {
186 if (type==AstVarType::INOUT || type==AstVarType::TRIWIRE
187 || type==AstVarType::TRI0 || type==AstVarType::TRI1)
189 if (type==AstVarType::TRI0)
191 if (type==AstVarType::TRI1)
195 string AstVar::verilogKwd() const {
198 } else if (isInput()) {
200 } else if (isOutput()) {
202 } else if (isTristate()) {
204 } else if (varType()==AstVarType::WIRE) {
206 } else if (varType()==AstVarType::WREAL) {
209 return dtypep()->name();
213 string AstVar::vlArgType(bool named, bool forReturn, bool forFunc) const {
214 if (forReturn) named=false;
215 if (forReturn) v3fatalSrc("verilator internal data is never passed as return, but as first argument");
217 if (isWide() && isInOnly()) arg += "const ";
218 AstBasicDType* bdtypep = basicp();
219 bool strtype = bdtypep && bdtypep->keyword()==AstBasicDTypeKwd::STRING;
220 if (bdtypep && bdtypep->keyword()==AstBasicDTypeKwd::CHARPTR) {
221 arg += "const char*";
222 } else if (bdtypep && bdtypep->keyword()==AstBasicDTypeKwd::SCOPEPTR) {
223 arg += "const VerilatedScope*";
224 } else if (bdtypep && bdtypep->keyword()==AstBasicDTypeKwd::DOUBLE) {
226 } else if (bdtypep && bdtypep->keyword()==AstBasicDTypeKwd::FLOAT) {
228 } else if (strtype) {
229 if (isInOnly()) arg += "const ";
230 arg += "std::string";
231 } else if (widthMin() <= 8) {
233 } else if (widthMin() <= 16) {
235 } else if (widthMin() <= VL_WORDSIZE) {
237 } else if (isQuad()) {
239 } else if (isWide()) {
240 arg += "WData"; // []'s added later
242 if (isWide() && !strtype) {
243 arg += " (& "+name();
244 arg += ")["+cvtToStr(widthWords())+"]";
246 if (forFunc && (isOutput() || (strtype && isInput()))) arg += "&";
247 if (named) arg += " "+name();
252 string AstVar::vlEnumType() const {
254 AstBasicDType* bdtypep = basicp();
255 bool strtype = bdtypep && bdtypep->keyword()==AstBasicDTypeKwd::STRING;
256 if (bdtypep && bdtypep->keyword()==AstBasicDTypeKwd::CHARPTR) {
258 } else if (bdtypep && bdtypep->keyword()==AstBasicDTypeKwd::SCOPEPTR) {
260 } else if (strtype) {
261 arg += "VLVT_STRING";
262 } else if (widthMin() <= 8) {
264 } else if (widthMin() <= 16) {
265 arg += "VLVT_UINT16";
266 } else if (widthMin() <= VL_WORDSIZE) {
267 arg += "VLVT_UINT32";
268 } else if (isQuad()) {
269 arg += "VLVT_UINT64";
270 } else if (isWide()) {
273 // else return "VLVT_UNKNOWN"
277 string AstVar::vlEnumDir() const {
281 } else if (isInOnly()) {
283 } else if (isOutOnly()) {
289 if (isSigUserRWPublic()) out += "|VLVF_PUB_RW";
290 else if (isSigUserRdPublic()) out += "|VLVF_PUB_RD";
294 string AstVar::cPubArgType(bool named, bool forReturn) const {
295 if (forReturn) named=false;
297 if (isWide() && isInOnly()) arg += "const ";
298 if (widthMin() == 1) {
300 } else if (widthMin() <= VL_WORDSIZE) {
302 } else if (isWide()) {
303 arg += "uint32_t"; // []'s added later
308 if (forReturn) v3error("Unsupported: Public functions with >64 bit outputs; make an output of a public task instead");
309 arg += " (& "+name();
310 arg += ")["+cvtToStr(widthWords())+"]";
312 if (isOutput() && !forReturn) arg += "&";
313 if (named) arg += " "+name();
318 string AstVar::dpiArgType(bool named, bool forReturn) const {
319 if (forReturn) named=false;
321 if (!basicp()) arg = "UNKNOWN";
322 else if (basicp()->keyword().isDpiBitVal()) {
323 if (widthMin() == 1) {
324 arg = "unsigned char";
325 if (!forReturn && isOutput()) arg += "*";
329 } else if (isInOnly()) {
330 arg = "const svBitVecVal*";
332 arg = "svBitVecVal*";
335 } else if (basicp()->keyword().isDpiLogicVal()) {
336 if (widthMin() == 1) {
337 arg = "unsigned char";
338 if (!forReturn && isOutput()) arg += "*";
341 arg = "svLogicVecVal";
342 } else if (isInOnly()) {
343 arg = "const svLogicVecVal*";
345 arg = "svLogicVecVal*";
349 arg = basicp()->keyword().dpiType();
350 if (basicp()->keyword().isDpiUnsignable() && !basicp()->isSigned()) {
351 arg = "unsigned "+arg;
353 if (!forReturn && isOutput()) arg += "*";
355 if (named) arg += " "+name();
359 string AstVar::scType() const {
361 return (string("sc_biguint<")+cvtToStr(widthMin())+"> "); // Keep the space so don't get >>
362 } else if (isScUint()) {
363 return (string("sc_uint<")+cvtToStr(widthMin())+"> "); // Keep the space so don't get >>
364 } else if (isScBv()) {
365 return (string("sc_bv<")+cvtToStr(widthMin())+"> "); // Keep the space so don't get >>
366 } else if (widthMin() == 1) {
368 } else if (widthMin() <= VL_WORDSIZE) {
369 if (widthMin() <= 8 && v3Global.opt.pinsUint8()) {
371 } else if (widthMin() <= 16 && v3Global.opt.pinsUint8()) {
381 AstVar* AstVar::scVarRecurse(AstNode* nodep) {
382 // See if this is a SC assignment; if so return that type
383 // Historically sc variables are identified by a variable
384 // attribute. TODO it would better be a data type attribute.
385 if (AstVar* anodep = nodep->castVar()) {
386 if (anodep->isSc()) return anodep;
389 else if (nodep->castVarRef()) {
390 if (nodep->castVarRef()->varp()->isSc()) return nodep->castVarRef()->varp();
393 else if (nodep->castArraySel()) {
394 if (nodep->op1p()) if (AstVar* p = scVarRecurse(nodep->op1p())) return p;
395 if (nodep->op2p()) if (AstVar* p = scVarRecurse(nodep->op2p())) return p;
396 if (nodep->op3p()) if (AstVar* p = scVarRecurse(nodep->op3p())) return p;
397 if (nodep->op4p()) if (AstVar* p = scVarRecurse(nodep->op4p())) return p;
402 AstNodeDType* AstNodeDType::dtypeDimensionp(int dimension) {
403 // dimension passed from AstArraySel::dimension
404 // Dimension 0 means the VAR itself, 1 is the closest SEL to the AstVar,
405 // which is the lowest in the dtype list.
406 // ref order: a[1][2][3][4]
407 // Created as: reg [4] a [1][2][3];
408 // *or* reg a [1][2][3][4];
409 // // The bit select is optional; used only if "leftover" []'s
410 // SEL: SEL4(SEL3(SEL2(SEL1(VARREF0 a))))
411 // DECL: VAR a (ARRAYSEL0 (ARRAYSEL1 (ARRAYSEL2 (DT RANGE3))))
412 // *or* VAR a (ARRAYSEL0 (ARRAYSEL1 (ARRAYSEL2 (ARRAYSEL3 (DT))))
413 // SEL1 needs to select from entire variable which is a pointer to ARRAYSEL0
414 // TODO this function should be removed in favor of recursing the dtype(),
415 // as that allows for more complicated data types.
417 UDEBUGONLY(UASSERT(dynamic_cast<AstNode*>(this),"this should not be NULL"););
418 for (AstNodeDType* dtypep=this; dtypep; ) {
419 dtypep = dtypep->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node
420 if (AstNodeArrayDType* adtypep = dtypep->castNodeArrayDType()) {
421 if ((dim++)==dimension) {
424 dtypep = adtypep->subDTypep();
427 else if (AstBasicDType* adtypep = dtypep->castBasicDType()) {
428 // AstBasicDType - nothing below, return null
429 if (adtypep->isRanged()) {
430 if ((dim++) == dimension) {
436 else if (AstNodeClassDType* adtypep = dtypep->castNodeClassDType()) {
437 if (adtypep->packed()) {
438 if ((dim++) == dimension) {
444 // Node no ->next in loop; use continue where necessary
450 uint32_t AstNodeDType::arrayUnpackedElements() {
452 UDEBUGONLY(UASSERT(dynamic_cast<AstNode*>(this),"this should not be NULL"););
453 for (AstNodeDType* dtypep=this; dtypep; ) {
454 dtypep = dtypep->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node
455 if (AstUnpackArrayDType* adtypep = dtypep->castUnpackArrayDType()) {
456 entries *= adtypep->elementsConst();
457 dtypep = adtypep->subDTypep();
460 // AstBasicDType - nothing below, 1
467 pair<uint32_t,uint32_t> AstNodeDType::dimensions(bool includeBasic) {
468 // How many array dimensions (packed,unpacked) does this Var have?
470 uint32_t unpacked = 0;
471 UDEBUGONLY(UASSERT(dynamic_cast<AstNode*>(this),"this should not be NULL"););
472 for (AstNodeDType* dtypep=this; dtypep; ) {
473 dtypep = dtypep->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node
474 if (AstNodeArrayDType* adtypep = dtypep->castNodeArrayDType()) {
475 if (adtypep->castPackArrayDType()) packed++;
477 dtypep = adtypep->subDTypep();
480 else if (AstBasicDType* adtypep = dtypep->castBasicDType()) {
481 if (includeBasic && adtypep->isRanged()) packed++;
485 return make_pair(packed, unpacked);
488 int AstNodeDType::widthPow2() const {
489 // I.e. width 30 returns 32, width 32 returns 32.
490 uint32_t width = this->width();
491 for (int p2=30; p2>=0; p2--) {
492 if (width > (1UL<<p2)) return (1UL<<(p2+1));
497 AstNode* AstArraySel::baseFromp(AstNode* nodep) { ///< What is the base variable (or const) this dereferences?
498 // Else AstArraySel etc; search for the base
500 if (nodep->castArraySel()) { nodep=nodep->castArraySel()->fromp(); continue; }
501 else if (nodep->castSel()) { nodep=nodep->castSel()->fromp(); continue; }
502 // AstNodeSelPre stashes the associated variable under an ATTROF of AstAttrType::VAR_BASE/MEMBER_BASE so it isn't constified
503 else if (nodep->castAttrOf()) { nodep=nodep->castAttrOf()->fromp(); continue; }
504 else if (nodep->castNodePreSel()) {
505 if (nodep->castNodePreSel()->attrp()) {
506 nodep=nodep->castNodePreSel()->attrp();
508 nodep=nodep->castNodePreSel()->lhsp();
517 const char* AstScope::broken() const {
518 BROKEN_RTN(m_aboveScopep && !m_aboveScopep->brokeExists());
519 BROKEN_RTN(m_aboveCellp && !m_aboveCellp->brokeExists());
521 BROKEN_RTN(m_modp && !m_modp->brokeExists());
525 void AstScope::cloneRelink() {
526 if (m_aboveScopep && m_aboveScopep->clonep()) m_aboveScopep->clonep();
527 if (m_aboveCellp && m_aboveCellp->clonep()) m_aboveCellp->clonep();
528 if (m_modp && ((AstNode*)m_modp)->clonep()) ((AstNode*)m_modp)->clonep();
531 string AstScope::nameDotless() const {
532 string out = shortName();
533 string::size_type pos;
534 while ((pos=out.find(".")) != string::npos) {
535 out.replace(pos, 1, "__");
540 string AstScopeName::scopePrettyNameFormatter(AstText* scopeTextp) const {
542 for (AstText* textp=scopeTextp; textp; textp=textp->nextp()->castText()) {
543 out += textp->text();
545 // TOP will be replaced by top->name()
546 if (out.substr(0,10) == "__DOT__TOP") out.replace(0,10,"");
547 if (out.substr(0,7) == "__DOT__") out.replace(0,7,"");
548 if (out.substr(0,1) == ".") out.replace(0,1,"");
549 return AstNode::prettyName(out);
552 string AstScopeName::scopeNameFormatter(AstText* scopeTextp) const {
554 for (AstText* textp=scopeTextp; textp; textp=textp->nextp()->castText()) {
555 out += textp->text();
557 if (out.substr(0,10) == "__DOT__TOP") out.replace(0,10,"");
558 if (out.substr(0,7) == "__DOT__") out.replace(0,7,"");
559 if (out.substr(0,1) == ".") out.replace(0,1,"");
560 string::size_type pos;
561 while ((pos=out.find(".")) != string::npos) {
562 out.replace(pos, 1, "__");
564 while ((pos=out.find("__DOT__")) != string::npos) {
565 out.replace(pos, 7, "__");
570 bool AstSenTree::hasClocked() const {
571 if (!sensesp()) this->v3fatalSrc("SENTREE without any SENITEMs under it");
572 for (AstNodeSenItem* senp = sensesp(); senp; senp=senp->nextp()->castNodeSenItem()) {
573 if (senp->isClocked()) return true;
577 bool AstSenTree::hasSettle() const {
578 if (!sensesp()) this->v3fatalSrc("SENTREE without any SENITEMs under it");
579 for (AstNodeSenItem* senp = sensesp(); senp; senp=senp->nextp()->castNodeSenItem()) {
580 if (senp->isSettle()) return true;
584 bool AstSenTree::hasInitial() const {
585 if (!sensesp()) this->v3fatalSrc("SENTREE without any SENITEMs under it");
586 for (AstNodeSenItem* senp = sensesp(); senp; senp=senp->nextp()->castNodeSenItem()) {
587 if (senp->isInitial()) return true;
591 bool AstSenTree::hasCombo() const {
592 if (!sensesp()) this->v3fatalSrc("SENTREE without any SENITEMs under it");
593 for (AstNodeSenItem* senp = sensesp(); senp; senp=senp->nextp()->castNodeSenItem()) {
594 if (senp->isCombo()) return true;
599 void AstTypeTable::clearCache() {
600 // When we mass-change widthMin in V3WidthCommit, we need to correct the table.
601 // Just clear out the maps; the search functions will be used to rebuild the map
602 for (int i=0; i<(int)(AstBasicDTypeKwd::_ENUM_MAX); ++i) {
605 for (int isbit=0; isbit<_IDX0_MAX; ++isbit) {
606 for (int numer=0; numer<AstNumeric::_ENUM_MAX; ++numer) {
607 LogicMap& mapr = m_logicMap[isbit][numer];
611 m_detailedMap.clear();
612 // Clear generic()'s so dead detection will work
613 for (AstNode* nodep = typesp(); nodep; nodep=nodep->nextp()) {
614 if (AstBasicDType* bdtypep = nodep->castBasicDType()) {
615 bdtypep->generic(false);
620 void AstTypeTable::repairCache() {
621 // After we mass-change widthMin in V3WidthCommit, we need to correct the table.
623 for (AstNode* nodep = typesp(); nodep; nodep=nodep->nextp()) {
624 if (AstBasicDType* bdtypep = nodep->castBasicDType()) {
625 (void)findInsertSameDType(bdtypep);
630 AstBasicDType* AstTypeTable::findBasicDType(FileLine* fl, AstBasicDTypeKwd kwd) {
631 if (m_basicps[kwd]) return m_basicps[kwd];
633 AstBasicDType* new1p = new AstBasicDType(fl, kwd);
634 // Because the detailed map doesn't update this map,
635 // check the detailed map for this same node
636 // Also adds this new node to the detailed map
637 AstBasicDType* newp = findInsertSameDType(new1p);
638 if (newp != new1p) new1p->deleteTree();
639 else addTypesp(newp);
641 m_basicps[kwd] = newp;
645 AstBasicDType* AstTypeTable::findLogicBitDType(FileLine* fl, AstBasicDTypeKwd kwd,
646 int width, int widthMin, AstNumeric numeric) {
647 int idx = IDX0_LOGIC;
648 if (kwd == AstBasicDTypeKwd::LOGIC) idx = IDX0_LOGIC;
649 else if (kwd == AstBasicDTypeKwd::BIT) idx = IDX0_BIT;
650 else fl->v3fatalSrc("Bad kwd for findLogicBitDType");
651 pair<int,int> widths = make_pair(width,widthMin);
652 LogicMap& mapr = m_logicMap[idx][(int)numeric];
653 LogicMap::const_iterator it = mapr.find(widths);
654 if (it != mapr.end()) return it->second;
656 AstBasicDType* new1p = new AstBasicDType(fl, kwd, numeric, width, widthMin);
657 // Because the detailed map doesn't update this map,
658 // check the detailed map for this same node, and if found update this map
659 // Also adds this new node to the detailed map
660 AstBasicDType* newp = findInsertSameDType(new1p);
661 if (newp != new1p) new1p->deleteTree();
662 else addTypesp(newp);
664 mapr.insert(make_pair(widths,newp));
668 AstBasicDType* AstTypeTable::findLogicBitDType(FileLine* fl, AstBasicDTypeKwd kwd,
669 VNumRange range, int widthMin, AstNumeric numeric) {
670 AstBasicDType* new1p = new AstBasicDType(fl, kwd, numeric, range, widthMin);
671 AstBasicDType* newp = findInsertSameDType(new1p);
672 if (newp != new1p) new1p->deleteTree();
673 else addTypesp(newp);
677 AstBasicDType* AstTypeTable::findInsertSameDType(AstBasicDType* nodep) {
678 VBasicTypeKey key (nodep->width(), nodep->widthMin(), nodep->numeric(),
679 nodep->keyword(), nodep->nrange());
680 DetailedMap& mapr = m_detailedMap;
681 DetailedMap::const_iterator it = mapr.find(key);
682 if (it != mapr.end()) return it->second;
683 mapr.insert(make_pair(key,nodep));
684 nodep->generic(true);
685 // No addTypesp; the upper function that called new() is responsible for adding
689 //======================================================================
690 // Special walking tree inserters
692 void AstNode::addBeforeStmt(AstNode* newp, AstNode*) {
693 if (!backp()) newp->v3fatalSrc("Can't find current statement to addBeforeStmt");
694 // Look up; virtual call will find where to put it
695 this->backp()->addBeforeStmt(newp, this);
697 void AstNode::addNextStmt(AstNode* newp, AstNode*) {
698 if (!backp()) newp->v3fatalSrc("Can't find current statement to addBeforeStmt");
699 // Look up; virtual call will find where to put it
700 this->backp()->addNextStmt(newp, this);
703 void AstNodeStmt::addBeforeStmt(AstNode* newp, AstNode*) {
704 // Insert newp before current node
705 this->addHereThisAsNext(newp);
707 void AstNodeStmt::addNextStmt(AstNode* newp, AstNode*) {
708 // Insert newp after current node
709 this->addNextHere(newp);
712 void AstWhile::addBeforeStmt(AstNode* newp, AstNode* belowp) {
713 // Special, as statements need to be put in different places
714 // Belowp is how we came to recurse up to this point
715 // Preconditions insert first just before themselves (the normal rule for other statement types)
716 if (belowp == precondsp()) {
717 // Must have been first statement in precondsp list, so newp is new first statement
718 belowp->addHereThisAsNext(newp);
719 } else if (belowp == condp()) {
720 // Goes before condition, IE in preconditions
722 } else if (belowp == bodysp()) {
723 // Was first statement in body, so new front
724 belowp->addHereThisAsNext(newp);
726 belowp->v3fatalSrc("Doesn't look like this was really under the while");
729 void AstWhile::addNextStmt(AstNode* newp, AstNode* belowp) {
730 // Special, as statements need to be put in different places
731 // Belowp is how we came to recurse up to this point
732 // Preconditions insert first just before themselves (the normal rule for other statement types)
733 if (belowp == precondsp()) {
734 // Next in precond list
735 belowp->addNextHere(newp);
736 } else if (belowp == condp()) {
737 // Becomes first statement in body, body may have been empty
739 bodysp()->addHereThisAsNext(newp);
743 } else if (belowp == bodysp()) {
744 // Next statement in body
745 belowp->addNextHere(newp);
747 belowp->v3fatalSrc("Doesn't look like this was really under the while");
751 //======================================================================
752 // Per-type Debugging
754 void AstNode::dump(ostream& str) {
755 str<<typeName()<<" "<<(void*)this
756 //<<" "<<(void*)this->m_backp
757 <<" <e"<<dec<<editCount()
758 <<((editCount()>=editCountLast())?"#>":">")
759 <<" {"<<fileline()->filenameLetters()<<dec<<fileline()->lineno()<<"}";
760 if (user1p()) str<<" u1="<<(void*)user1p();
761 if (user2p()) str<<" u2="<<(void*)user2p();
762 if (user3p()) str<<" u3="<<(void*)user3p();
763 if (user4p()) str<<" u4="<<(void*)user4p();
764 if (user5p()) str<<" u5="<<(void*)user5p();
766 if (dtypep()==this) str<<" @dt="<<"this@";
767 else str<<" @dt="<<(void*)dtypep()<<"@"; // Final @ so less likely to by accident think it's nodep
768 if (AstNodeDType* dtp = dtypep()) {
771 } else { // V3Broken will throw an error
772 if (dtypep()) str<<" %Error-dtype-exp=null,got="<<(void*)dtypep();
775 if (castConst()) str<<" "<<name(); // Already quoted
776 else str<<" "<<V3Number::quoteNameControls(name());
780 void AstAlways::dump(ostream& str) {
781 this->AstNode::dump(str);
782 if (keyword() != VAlwaysKwd::ALWAYS) str<<" ["<<keyword().ascii()<<"]";
785 void AstAttrOf::dump(ostream& str) {
786 this->AstNode::dump(str);
787 str<<" ["<<attrType().ascii()<<"]";
789 void AstBasicDType::dump(ostream& str) {
790 this->AstNodeDType::dump(str);
791 str<<" kwd="<<keyword().ascii();
792 if (isRanged() && !rangep()) str<<" range=["<<left()<<":"<<right()<<"]";
794 void AstCCast::dump(ostream& str) {
795 this->AstNode::dump(str);
798 void AstCell::dump(ostream& str) {
799 this->AstNode::dump(str);
800 if (recursive()) str<<" [RECURSIVE]";
801 if (modp()) { str<<" -> "; modp()->dump(str); }
802 else { str<<" ->UNLINKED:"<<modName(); }
804 void AstCellInline::dump(ostream& str) {
805 this->AstNode::dump(str);
806 str<<" -> "<<origModName();
808 void AstDisplay::dump(ostream& str) {
809 this->AstNode::dump(str);
810 //str<<" "<<displayType().ascii();
812 void AstEnumItemRef::dump(ostream& str) {
813 this->AstNode::dump(str);
815 if (itemp()) { itemp()->dump(str); }
816 else { str<<"UNLINKED"; }
818 void AstIfaceRefDType::dump(ostream& str) {
819 this->AstNode::dump(str);
820 if (cellName()!="") { str<<" cell="<<cellName(); }
821 if (ifaceName()!="") { str<<" if="<<ifaceName(); }
822 if (modportName()!="") { str<<" mp="<<modportName(); }
823 if (cellp()) { str<<" -> "; cellp()->dump(str); }
824 else if (ifacep()) { str<<" -> "; ifacep()->dump(str); }
825 else { str<<" -> UNLINKED"; }
827 void AstIfaceRefDType::dumpSmall(ostream& str) {
828 this->AstNodeDType::dumpSmall(str);
831 void AstJumpGo::dump(ostream& str) {
832 this->AstNode::dump(str);
834 if (labelp()) { labelp()->dump(str); }
835 else { str<<"%Error:UNLINKED"; }
837 void AstModportFTaskRef::dump(ostream& str) {
838 this->AstNode::dump(str);
839 if (isExport()) str<<" EXPORT";
840 if (isImport()) str<<" IMPORT";
841 if (ftaskp()) { str<<" -> "; ftaskp()->dump(str); }
842 else { str<<" -> UNLINKED"; }
844 void AstModportVarRef::dump(ostream& str) {
845 this->AstNode::dump(str);
847 if (varp()) { str<<" -> "; varp()->dump(str); }
848 else { str<<" -> UNLINKED"; }
850 void AstPin::dump(ostream& str) {
851 this->AstNode::dump(str);
852 if (modVarp()) { str<<" -> "; modVarp()->dump(str); }
853 else { str<<" ->UNLINKED"; }
854 if (svImplicit()) str<<" [.SV]";
856 void AstTypedef::dump(ostream& str) {
857 this->AstNode::dump(str);
858 if (attrPublic()) str<<" [PUBLIC]";
860 void AstRange::dump(ostream& str) {
861 this->AstNode::dump(str);
862 if (littleEndian()) str<<" [LITTLE]";
864 void AstRefDType::dump(ostream& str) {
865 this->AstNodeDType::dump(str);
866 if (defp()) { str<<" -> "; defp()->dump(str); }
867 else { str<<" -> UNLINKED"; }
869 void AstNodeClassDType::dump(ostream& str) {
870 this->AstNode::dump(str);
871 if (packed()) str<<" [PACKED]";
872 if (isFourstate()) str<<" [4STATE]";
874 void AstNodeDType::dump(ostream& str) {
875 this->AstNode::dump(str);
876 if (generic()) str<<" [GENERIC]";
877 if (AstNodeDType* dtp = virtRefDTypep()) {
878 str<<" refdt="<<(void*)(dtp);
882 void AstNodeDType::dumpSmall(ostream& str) {
884 <<(generic()?"G/":"")
885 <<((isSigned()&&!isDouble())?"s":"")
886 <<(isNosign()?"n":"")
887 <<(isDouble()?"d":"")
888 <<(isString()?"str":"");
889 if (!isDouble() && !isString()) {
890 str<<"w"<<(widthSized()?"":"u")<<width();
892 if (!widthSized()) str<<"/"<<widthMin();
895 void AstNodeArrayDType::dumpSmall(ostream& str) {
896 this->AstNodeDType::dumpSmall(str);
897 if (castPackArrayDType()) str<<"p"; else str<<"u";
900 void AstNodeArrayDType::dump(ostream& str) {
901 this->AstNodeDType::dump(str);
902 str<<" "<<declRange();
904 void AstNodeModule::dump(ostream& str) {
905 this->AstNode::dump(str);
907 if (modPublic()) str<<" [P]";
908 if (inLibrary()) str<<" [LIB]";
909 if (dead()) str<<" [DEAD]";
910 if (recursiveClone()) str<<" [RECURSIVE-CLONE]";
911 else if (recursive()) str<<" [RECURSIVE]";
913 void AstPackageExport::dump(ostream& str) {
914 this->AstNode::dump(str);
915 str<<" -> "<<packagep();
917 void AstPackageImport::dump(ostream& str) {
918 this->AstNode::dump(str);
919 str<<" -> "<<packagep();
921 void AstSel::dump(ostream& str) {
922 this->AstNode::dump(str);
923 if (declRange().ranged()) {
924 str<<" decl"<<declRange()<<"]";
925 if (declElWidth()!=1) str<<"/"<<declElWidth();
928 void AstSliceSel::dump(ostream& str) {
929 this->AstNode::dump(str);
930 if (declRange().ranged()) {
931 str<<" decl"<<declRange();
934 void AstTypeTable::dump(ostream& str) {
935 this->AstNode::dump(str);
936 for (int i=0; i<(int)(AstBasicDTypeKwd::_ENUM_MAX); ++i) {
937 if (AstBasicDType* subnodep=m_basicps[i]) {
938 str<<endl; // Newline from caller, so newline first
939 str<<"\t\t"<<setw(8)<<AstBasicDTypeKwd(i).ascii();
944 for (int isbit=0; isbit<2; ++isbit) {
945 for (int issigned=0; issigned<AstNumeric::_ENUM_MAX; ++issigned) {
946 LogicMap& mapr = m_logicMap[isbit][issigned];
947 for (LogicMap::const_iterator it = mapr.begin(); it != mapr.end(); ++it) {
948 AstBasicDType* dtypep = it->second;
949 str<<endl; // Newline from caller, so newline first
951 nsstr<<(isbit?"bw":"lw")
952 <<it->first.first<<"/"<<it->first.second;
953 str<<"\t\t"<<setw(8)<<nsstr.str();
954 if (issigned) str<<" s"; else str<<" u";
961 DetailedMap& mapr = m_detailedMap;
962 for (DetailedMap::const_iterator it = mapr.begin(); it != mapr.end(); ++it) {
963 AstBasicDType* dtypep = it->second;
964 str<<endl; // Newline from caller, so newline first
965 str<<"\t\tdetailed -> ";
969 // Note get newline from caller too.
972 void AstVarScope::dump(ostream& str) {
973 this->AstNode::dump(str);
974 if (isCircular()) str<<" [CIRC]";
975 if (varp()) { str<<" -> "; varp()->dump(str); }
976 else { str<<" ->UNLINKED"; }
978 void AstVarXRef::dump(ostream& str) {
979 this->AstNode::dump(str);
980 if (packagep()) { str<<" pkg="<<(void*)packagep(); }
981 if (lvalue()) str<<" [LV] => ";
982 else str<<" [RV] <- ";
983 str<<dotted()<<". - ";
984 if (inlinedDots()!="") str<<" inline.="<<inlinedDots()<<" - ";
985 if (varScopep()) { varScopep()->dump(str); }
986 else if (varp()) { varp()->dump(str); }
987 else { str<<"UNLINKED"; }
989 void AstVarRef::dump(ostream& str) {
990 this->AstNode::dump(str);
991 if (packagep()) { str<<" pkg="<<(void*)packagep(); }
992 if (lvalue()) str<<" [LV] => ";
993 else str<<" [RV] <- ";
994 if (varScopep()) { varScopep()->dump(str); }
995 else if (varp()) { varp()->dump(str); }
996 else { str<<"UNLINKED"; }
998 void AstVar::dump(ostream& str) {
999 this->AstNode::dump(str);
1000 if (isSc()) str<<" [SC]";
1001 if (isPrimaryIO()) str<<(isInout()?" [PIO]":(isInput()?" [PI]":" [PO]"));
1003 if (isInout()) str<<" [IO]";
1004 else if (isInput()) str<<" [I]";
1005 else if (isOutput()) str<<" [O]";
1007 if (isConst()) str<<" [CONST]";
1008 if (isPullup()) str<<" [PULLUP]";
1009 if (isPulldown()) str<<" [PULLDOWN]";
1010 if (isUsedClock()) str<<" [CLK]";
1011 if (isSigPublic()) str<<" [P]";
1012 if (isUsedLoopIdx()) str<<" [LOOP]";
1013 if (attrClockEn()) str<<" [aCLKEN]";
1014 if (attrIsolateAssign()) str<<" [aISO]";
1015 if (attrFileDescr()) str<<" [aFD]";
1016 if (isFuncReturn()) str<<" [FUNCRTN]";
1017 else if (isFuncLocal()) str<<" [FUNC]";
1018 if (!attrClocker().unknown()) str<<" ["<<attrClocker().ascii()<<"] ";
1019 str<<" "<<varType();
1021 void AstSenTree::dump(ostream& str) {
1022 this->AstNode::dump(str);
1023 if (isMulti()) str<<" [MULTI]";
1025 void AstSenItem::dump(ostream& str) {
1026 this->AstNode::dump(str);
1027 str<<" ["<<edgeType().ascii()<<"]";
1029 void AstParseRef::dump(ostream& str) {
1030 this->AstNode::dump(str);
1031 str<<" ["<<expect().ascii()<<"]";
1033 void AstPackageRef::dump(ostream& str) {
1034 this->AstNode::dump(str);
1035 if (packagep()) { str<<" pkg="<<(void*)packagep(); }
1037 if (packagep()) { packagep()->dump(str); }
1038 else { str<<"UNLINKED"; }
1040 void AstDot::dump(ostream& str) {
1041 this->AstNode::dump(str);
1043 void AstActive::dump(ostream& str) {
1044 this->AstNode::dump(str);
1046 if (sensesp()) { sensesp()->dump(str); }
1047 else { str<<"UNLINKED"; }
1049 void AstNodeFTaskRef::dump(ostream& str) {
1050 this->AstNode::dump(str);
1051 if (packagep()) { str<<" pkg="<<(void*)packagep(); }
1053 if (dotted()!="") { str<<dotted()<<". - "; }
1054 if (taskp()) { taskp()->dump(str); }
1055 else { str<<"UNLINKED"; }
1057 void AstNodeFTask::dump(ostream& str) {
1058 this->AstNode::dump(str);
1059 if (taskPublic()) str<<" [PUBLIC]";
1060 if (prototype()) str<<" [PROTOTYPE]";
1061 if (dpiImport()) str<<" [DPII]";
1062 if (dpiExport()) str<<" [DPIX]";
1063 if ((dpiImport() || dpiExport()) && cname()!=name()) str<<" [c="<<cname()<<"]";
1065 void AstBegin::dump(ostream& str) {
1066 this->AstNode::dump(str);
1067 if (unnamed()) str<<" [UNNAMED]";
1068 if (generate()) str<<" [GEN]";
1069 if (genforp()) str<<" [GENFOR]";
1071 void AstCoverDecl::dump(ostream& str) {
1072 this->AstNode::dump(str);
1073 if (this->dataDeclNullp()) {
1075 this->dataDeclNullp()->dump(str);
1077 if (binNum()) { str<<" bin"<<dec<<binNum(); }
1080 void AstCoverInc::dump(ostream& str) {
1081 this->AstNode::dump(str);
1083 if (declp()) { declp()->dump(str); }
1084 else { str<<"%Error:UNLINKED"; }
1086 void AstTraceInc::dump(ostream& str) {
1087 this->AstNode::dump(str);
1089 if (declp()) { declp()->dump(str); }
1090 else { str<<"%Error:UNLINKED"; }
1092 void AstNodeText::dump(ostream& str) {
1093 this->AstNode::dump(str);
1094 string out = text();
1095 string::size_type pos;
1096 if ((pos = out.find("\n")) != string::npos) {
1097 out.erase(pos,out.length()-pos);
1100 str<<" \""<<out<<"\"";
1103 void AstCFile::dump(ostream& str) {
1104 this->AstNode::dump(str);
1105 if (source()) str<<" [SRC]";
1106 if (slow()) str<<" [SLOW]";
1108 void AstCCall::dump(ostream& str) {
1109 this->AstNode::dump(str);
1111 str<<" "<<funcp()->name()<<" => ";
1115 void AstCFunc::dump(ostream& str) {
1116 this->AstNode::dump(str);
1117 if (slow()) str<<" [SLOW]";
1118 if (pure()) str<<" [PURE]";
1119 if (dpiImport()) str<<" [DPII]";
1120 if (dpiExport()) str<<" [DPIX]";
1121 if (dpiExportWrapper()) str<<" [DPIXWR]";