]> Git Repo - verilator.git/blob - src/V3AstNodes.cpp
Internals: Move VLVF flags to common function. No functional change.
[verilator.git] / src / V3AstNodes.cpp
1 // -*- mode: C++; c-file-style: "cc-mode" -*-
2 //*************************************************************************
3 // DESCRIPTION: Verilator: Ast node structures
4 //
5 // Code available from: http://www.veripool.org/verilator
6 //
7 //*************************************************************************
8 //
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
12 // Version 2.0.
13 //
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.
18 //
19 //*************************************************************************
20 \f
21 #include "config_build.h"
22 #include "verilatedos.h"
23 #include <cstdio>
24 #include <cstdarg>
25 #include <fstream>
26 #include <iomanip>
27 #include <vector>
28 #include <algorithm>
29 #include VL_INCLUDE_UNORDERED_SET
30
31 #include "V3Ast.h"
32 #include "V3File.h"
33 #include "V3Global.h"
34
35 //======================================================================
36 // Special methods
37
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());
43     return NULL;
44 }
45
46 AstIface* AstIfaceRefDType::ifaceViaCellp() const {
47     return ((m_cellp && m_cellp->modp()) ? m_cellp->modp()->castIface() : m_ifacep);
48 }
49
50 const char* AstNodeVarRef::broken() const {
51     BROKEN_RTN(m_varScopep && !m_varScopep->brokeExists());
52     BROKEN_RTN(m_varp && !m_varp->brokeExists());
53     return NULL;
54 }
55
56 void AstNodeVarRef::cloneRelink() {
57     if (m_varp && m_varp->clonep()) { m_varp = m_varp->clonep(); }
58 }
59
60 int AstNodeSel::bitConst() const {
61     AstConst* constp=bitp()->castConst(); return (constp?constp->toSInt():0);
62 }
63
64 void AstNodeClassDType::repairMemberCache() {
65     clearCache();
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));
69     }
70 }
71
72 const char* AstNodeClassDType::broken() const {
73     vl_unordered_set<AstMemberDType*> exists;
74     for (AstMemberDType* itemp = membersp(); itemp; itemp=itemp->nextp()->castMemberDType()) {
75         exists.insert(itemp);
76     }
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";
81         }
82     }
83     return NULL;
84 }
85
86 int AstBasicDType::widthAlignBytes() const {
87     if (width()<=8) return 1;
88     else if (width()<=16) return 2;
89     else if (isQuad()) return 8;
90     else return 4;
91 }
92
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);
98 }
99
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);
105 }
106
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;
113     else return 8;
114 }
115
116 AstNodeBiop* AstEq::newTyped(FileLine* fl, AstNode* lhsp, AstNode* rhsp) {
117     if (lhsp->isDouble() && rhsp->isDouble()) {
118         return new AstEqD(fl, lhsp, rhsp);
119     } else {
120         return new AstEq(fl, lhsp, rhsp);
121     }
122 }
123
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);
129     } else {
130         return new AstGte(fl, lhsp, rhsp);
131     }
132 }
133
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);
139     } else {
140         return new AstLte(fl, lhsp, rhsp);
141     }
142 }
143
144 AstNodeBiop* AstEqWild::newTyped(FileLine* fl, AstNode* lhsp, AstNode* rhsp) {
145     if (lhsp->isDouble() && rhsp->isDouble()) {
146         return new AstEqD(fl, lhsp, rhsp);
147     } else {
148         return new AstEqWild(fl, lhsp, rhsp);
149     }
150 }
151
152 bool AstVar::isSigPublic() const {
153     return (m_sigPublic || (v3Global.opt.allPublic() && !isTemp() && !isGenVar()));
154 }
155
156 bool AstVar::isScQuad() const {
157     return (isSc() && isQuad() && !isScBv() && !isScBigUint());
158 }
159
160 bool AstVar::isScBv() const {
161     return ((isSc() && width() >= v3Global.opt.pinsBv()) || m_attrScBv);
162 }
163
164 bool AstVar::isScUint() const {
165     return ((isSc() && v3Global.opt.pinsScUint() && width() >= 2 && width() <= 64) && !isScBv());
166 }
167
168 bool AstVar::isScBigUint() const {
169     return ((isSc() && v3Global.opt.pinsScBigUint() && width() >= 65 && width() <= 512) && !isScBv());
170 }
171
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)
181         m_input = true;
182     if (type==AstVarType::OUTPUT || type==AstVarType::INOUT) {
183         m_output = true;
184         m_declOutput = true;
185     }
186     if (type==AstVarType::INOUT || type==AstVarType::TRIWIRE
187         || type==AstVarType::TRI0 || type==AstVarType::TRI1)
188         m_tristate = true;
189     if (type==AstVarType::TRI0)
190         m_isPulldown = true;
191     if (type==AstVarType::TRI1)
192         m_isPullup = true;
193 }
194
195 string AstVar::verilogKwd() const {
196     if (isInout()) {
197         return "inout";
198     } else if (isInput()) {
199         return "input";
200     } else if (isOutput()) {
201         return "output";
202     } else if (isTristate()) {
203         return "tri";
204     } else if (varType()==AstVarType::WIRE) {
205         return "wire";
206     } else if (varType()==AstVarType::WREAL) {
207         return "wreal";
208     } else {
209         return dtypep()->name();
210     }
211 }
212
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");
216     string arg;
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) {
225         arg += "double";
226     } else if (bdtypep && bdtypep->keyword()==AstBasicDTypeKwd::FLOAT) {
227         arg += "float";
228     } else if (strtype) {
229         if (isInOnly()) arg += "const ";
230         arg += "std::string";
231     } else if (widthMin() <= 8) {
232         arg += "CData";
233     } else if (widthMin() <= 16) {
234         arg += "SData";
235     } else if (widthMin() <= VL_WORDSIZE) {
236         arg += "IData";
237     } else if (isQuad()) {
238         arg += "QData";
239     } else if (isWide()) {
240         arg += "WData";  // []'s added later
241     }
242     if (isWide() && !strtype) {
243         arg += " (& "+name();
244         arg += ")["+cvtToStr(widthWords())+"]";
245     } else {
246         if (forFunc && (isOutput() || (strtype && isInput()))) arg += "&";
247         if (named) arg += " "+name();
248     }
249     return arg;
250 }
251
252 string AstVar::vlEnumType() const {
253     string arg;
254     AstBasicDType* bdtypep = basicp();
255     bool strtype = bdtypep && bdtypep->keyword()==AstBasicDTypeKwd::STRING;
256     if (bdtypep && bdtypep->keyword()==AstBasicDTypeKwd::CHARPTR) {
257         return "VLVT_PTR";
258     } else if (bdtypep && bdtypep->keyword()==AstBasicDTypeKwd::SCOPEPTR) {
259         return "VLVT_PTR";
260     } else if (strtype) {
261         arg += "VLVT_STRING";
262     } else if (widthMin() <= 8) {
263         arg += "VLVT_UINT8";
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()) {
271         arg += "VLVT_WDATA";
272     }
273     // else return "VLVT_UNKNOWN"
274     return arg;
275 }
276
277 string AstVar::vlEnumDir() const {
278     string out;
279     if (isInout()) {
280         out = "VLVD_INOUT";
281     } else if (isInOnly()) {
282         out = "VLVD_IN";
283     } else if (isOutOnly()) {
284         out = "VLVD_OUT";
285     } else {
286         out = "VLVD_NODIR";
287     }
288     //
289     if (isSigUserRWPublic()) out += "|VLVF_PUB_RW";
290     else if (isSigUserRdPublic()) out += "|VLVF_PUB_RD";
291     return out;
292 }
293
294 string AstVar::cPubArgType(bool named, bool forReturn) const {
295     if (forReturn) named=false;
296     string arg;
297     if (isWide() && isInOnly()) arg += "const ";
298     if (widthMin() == 1) {
299         arg += "bool";
300     } else if (widthMin() <= VL_WORDSIZE) {
301         arg += "uint32_t";
302     } else if (isWide()) {
303         arg += "uint32_t";  // []'s added later
304     } else {
305         arg += "vluint64_t";
306     }
307     if (isWide()) {
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())+"]";
311     } else {
312         if (isOutput() && !forReturn) arg += "&";
313         if (named) arg += " "+name();
314     }
315     return arg;
316 }
317
318 string AstVar::dpiArgType(bool named, bool forReturn) const {
319     if (forReturn) named=false;
320     string arg;
321     if (!basicp()) arg = "UNKNOWN";
322     else if (basicp()->keyword().isDpiBitVal()) {
323         if (widthMin() == 1) {
324             arg = "unsigned char";
325             if (!forReturn && isOutput()) arg += "*";
326         } else {
327             if (forReturn) {
328                 arg = "svBitVecVal";
329             } else if (isInOnly()) {
330                 arg = "const svBitVecVal*";
331             } else {
332                 arg = "svBitVecVal*";
333             }
334         }
335     } else if (basicp()->keyword().isDpiLogicVal()) {
336         if (widthMin() == 1) {
337             arg = "unsigned char";
338             if (!forReturn && isOutput()) arg += "*";
339         } else {
340             if (forReturn) {
341                 arg = "svLogicVecVal";
342             } else if (isInOnly()) {
343                 arg = "const svLogicVecVal*";
344             } else {
345                 arg = "svLogicVecVal*";
346             }
347         }
348     } else {
349         arg = basicp()->keyword().dpiType();
350         if (basicp()->keyword().isDpiUnsignable() && !basicp()->isSigned()) {
351             arg = "unsigned "+arg;
352         }
353         if (!forReturn && isOutput()) arg += "*";
354     }
355     if (named) arg += " "+name();
356     return arg;
357 }
358
359 string AstVar::scType() const {
360     if (isScBigUint()) {
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) {
367         return "bool";
368     } else if (widthMin() <= VL_WORDSIZE) {
369         if (widthMin() <= 8 && v3Global.opt.pinsUint8()) {
370             return "uint8_t";
371         } else if (widthMin() <= 16 && v3Global.opt.pinsUint8()) {
372             return "uint16_t";
373         } else {
374             return "uint32_t";
375         }
376     } else {
377         return "vluint64_t";
378     }
379 }
380
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;
387         else return NULL;
388     }
389     else if (nodep->castVarRef()) {
390         if (nodep->castVarRef()->varp()->isSc()) return nodep->castVarRef()->varp();
391         else return NULL;
392     }
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;
398     }
399     return NULL;
400 }
401
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.
416     int dim = 0;
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) {
422                 return dtypep;
423             }
424             dtypep = adtypep->subDTypep();
425             continue;
426         }
427         else if (AstBasicDType* adtypep = dtypep->castBasicDType()) {
428             // AstBasicDType - nothing below, return null
429             if (adtypep->isRanged()) {
430                 if ((dim++) == dimension) {
431                     return adtypep;
432                 }
433             }
434             return NULL;
435         }
436         else if (AstNodeClassDType* adtypep = dtypep->castNodeClassDType()) {
437             if (adtypep->packed()) {
438                 if ((dim++) == dimension) {
439                     return adtypep;
440                 }
441             }
442             return NULL;
443         }
444         // Node no ->next in loop; use continue where necessary
445         break;
446     }
447     return NULL;
448 }
449
450 uint32_t AstNodeDType::arrayUnpackedElements() {
451     uint32_t entries=1;
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();
458         }
459         else {
460             // AstBasicDType - nothing below, 1
461             break;
462         }
463     }
464     return entries;
465 }
466
467 pair<uint32_t,uint32_t> AstNodeDType::dimensions(bool includeBasic) {
468     // How many array dimensions (packed,unpacked) does this Var have?
469     uint32_t packed = 0;
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++;
476             else unpacked++;
477             dtypep = adtypep->subDTypep();
478             continue;
479         }
480         else if (AstBasicDType* adtypep = dtypep->castBasicDType()) {
481             if (includeBasic && adtypep->isRanged()) packed++;
482         }
483         break;
484     }
485     return make_pair(packed, unpacked);
486 }
487
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));
493     }
494     return 1;
495 }
496
497 AstNode* AstArraySel::baseFromp(AstNode* nodep) {       ///< What is the base variable (or const) this dereferences?
498     // Else AstArraySel etc; search for the base
499     while (nodep) {
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();
507             } else {
508                 nodep=nodep->castNodePreSel()->lhsp();
509             }
510             continue;
511         }
512         else break;
513     }
514     return nodep;
515 }
516
517 const char* AstScope::broken() const {
518     BROKEN_RTN(m_aboveScopep && !m_aboveScopep->brokeExists());
519     BROKEN_RTN(m_aboveCellp && !m_aboveCellp->brokeExists());
520     BROKEN_RTN(!m_modp);
521     BROKEN_RTN(m_modp && !m_modp->brokeExists());
522     return NULL;
523 }
524
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();
529 }
530
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, "__");
536     }
537     return out;
538 }
539
540 string AstScopeName::scopePrettyNameFormatter(AstText* scopeTextp) const {
541     string out;
542     for (AstText* textp=scopeTextp; textp; textp=textp->nextp()->castText()) {
543         out += textp->text();
544     }
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);
550 }
551
552 string AstScopeName::scopeNameFormatter(AstText* scopeTextp) const {
553     string out;
554     for (AstText* textp=scopeTextp; textp; textp=textp->nextp()->castText()) {
555         out += textp->text();
556     }
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, "__");
563     }
564     while ((pos=out.find("__DOT__")) != string::npos) {
565         out.replace(pos, 7, "__");
566     }
567     return out;
568 }
569
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;
574     }
575     return false;
576 }
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;
581     }
582     return false;
583 }
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;
588     }
589     return false;
590 }
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;
595     }
596     return false;
597 }
598
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) {
603         m_basicps[i] = NULL;
604     }
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];
608             mapr.clear();
609         }
610     }
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);
616         }
617     }
618 }
619
620 void AstTypeTable::repairCache() {
621     // After we mass-change widthMin in V3WidthCommit, we need to correct the table.
622     clearCache();
623     for (AstNode* nodep = typesp(); nodep; nodep=nodep->nextp()) {
624         if (AstBasicDType* bdtypep = nodep->castBasicDType()) {
625             (void)findInsertSameDType(bdtypep);
626         }
627     }
628 }
629
630 AstBasicDType* AstTypeTable::findBasicDType(FileLine* fl, AstBasicDTypeKwd kwd) {
631     if (m_basicps[kwd]) return m_basicps[kwd];
632     //
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);
640     //
641     m_basicps[kwd] = newp;
642     return newp;
643 }
644
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;
655     //
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);
663     //
664     mapr.insert(make_pair(widths,newp));
665     return newp;
666 }
667
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);
674     return newp;
675 }
676
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
686     return nodep;
687 }
688
689 //======================================================================
690 // Special walking tree inserters
691
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);
696 }
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);
701 }
702
703 void AstNodeStmt::addBeforeStmt(AstNode* newp, AstNode*) {
704     // Insert newp before current node
705     this->addHereThisAsNext(newp);
706 }
707 void AstNodeStmt::addNextStmt(AstNode* newp, AstNode*) {
708     // Insert newp after current node
709     this->addNextHere(newp);
710 }
711
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
721         addPrecondsp(newp);
722     } else if (belowp == bodysp()) {
723         // Was first statement in body, so new front
724         belowp->addHereThisAsNext(newp);
725     } else {
726         belowp->v3fatalSrc("Doesn't look like this was really under the while");
727     }
728 }
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
738         if (bodysp()) {
739             bodysp()->addHereThisAsNext(newp);
740         } else {
741             addBodysp(newp);
742         }
743     } else if (belowp == bodysp()) {
744         // Next statement in body
745         belowp->addNextHere(newp);
746     } else {
747         belowp->v3fatalSrc("Doesn't look like this was really under the while");
748     }
749 }
750
751 //======================================================================
752 // Per-type Debugging
753
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();
765     if (hasDType()) {
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()) {
769             dtp->dumpSmall(str);
770         }
771     } else { // V3Broken will throw an error
772         if (dtypep()) str<<" %Error-dtype-exp=null,got="<<(void*)dtypep();
773     }
774     if (name()!="") {
775         if (castConst()) str<<"  "<<name();  // Already quoted
776         else str<<"  "<<V3Number::quoteNameControls(name());
777     }
778 }
779
780 void AstAlways::dump(ostream& str) {
781     this->AstNode::dump(str);
782     if (keyword() != VAlwaysKwd::ALWAYS) str<<" ["<<keyword().ascii()<<"]";
783 }
784
785 void AstAttrOf::dump(ostream& str) {
786     this->AstNode::dump(str);
787     str<<" ["<<attrType().ascii()<<"]";
788 }
789 void AstBasicDType::dump(ostream& str) {
790     this->AstNodeDType::dump(str);
791     str<<" kwd="<<keyword().ascii();
792     if (isRanged() && !rangep()) str<<" range=["<<left()<<":"<<right()<<"]";
793 }
794 void AstCCast::dump(ostream& str) {
795     this->AstNode::dump(str);
796     str<<" sz"<<size();
797 }
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(); }
803 }
804 void AstCellInline::dump(ostream& str) {
805     this->AstNode::dump(str);
806     str<<" -> "<<origModName();
807 }
808 void AstDisplay::dump(ostream& str) {
809     this->AstNode::dump(str);
810     //str<<" "<<displayType().ascii();
811 }
812 void AstEnumItemRef::dump(ostream& str) {
813     this->AstNode::dump(str);
814     str<<" -> ";
815     if (itemp()) { itemp()->dump(str); }
816     else { str<<"UNLINKED"; }
817 }
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"; }
826 }
827 void AstIfaceRefDType::dumpSmall(ostream& str) {
828     this->AstNodeDType::dumpSmall(str);
829     str<<"iface";
830 }
831 void AstJumpGo::dump(ostream& str) {
832     this->AstNode::dump(str);
833     str<<" -> ";
834     if (labelp()) { labelp()->dump(str); }
835     else { str<<"%Error:UNLINKED"; }
836 }
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"; }
843 }
844 void AstModportVarRef::dump(ostream& str) {
845     this->AstNode::dump(str);
846     str<<" "<<varType();
847     if (varp()) { str<<" -> "; varp()->dump(str); }
848     else { str<<" -> UNLINKED"; }
849 }
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]";
855 }
856 void AstTypedef::dump(ostream& str) {
857     this->AstNode::dump(str);
858     if (attrPublic()) str<<" [PUBLIC]";
859 }
860 void AstRange::dump(ostream& str) {
861     this->AstNode::dump(str);
862     if (littleEndian()) str<<" [LITTLE]";
863 }
864 void AstRefDType::dump(ostream& str) {
865     this->AstNodeDType::dump(str);
866     if (defp()) { str<<" -> "; defp()->dump(str); }
867     else { str<<" -> UNLINKED"; }
868 }
869 void AstNodeClassDType::dump(ostream& str) {
870     this->AstNode::dump(str);
871     if (packed()) str<<" [PACKED]";
872     if (isFourstate()) str<<" [4STATE]";
873 }
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);
879         dtp->dumpSmall(str);
880     }
881 }
882 void AstNodeDType::dumpSmall(ostream& str) {
883     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();
891     }
892     if (!widthSized()) str<<"/"<<widthMin();
893     str<<")";
894 }
895 void AstNodeArrayDType::dumpSmall(ostream& str) {
896     this->AstNodeDType::dumpSmall(str);
897     if (castPackArrayDType()) str<<"p"; else str<<"u";
898     str<<declRange();
899 }
900 void AstNodeArrayDType::dump(ostream& str) {
901     this->AstNodeDType::dump(str);
902     str<<" "<<declRange();
903 }
904 void AstNodeModule::dump(ostream& str) {
905     this->AstNode::dump(str);
906     str<<"  L"<<level();
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]";
912 }
913 void AstPackageExport::dump(ostream& str) {
914     this->AstNode::dump(str);
915     str<<" -> "<<packagep();
916 }
917 void AstPackageImport::dump(ostream& str) {
918     this->AstNode::dump(str);
919     str<<" -> "<<packagep();
920 }
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();
926     }
927 }
928 void AstSliceSel::dump(ostream& str) {
929     this->AstNode::dump(str);
930     if (declRange().ranged()) {
931         str<<" decl"<<declRange();
932     }
933 }
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();
940             str<<"  -> ";
941             subnodep->dump(str);
942         }
943     }
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
950                 stringstream nsstr;
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";
955                 str<<"  ->  ";
956                 dtypep->dump(str);
957             }
958         }
959     }
960     {
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  ->  ";
966             dtypep->dump(str);
967         }
968     }
969     // Note get newline from caller too.
970 }
971
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"; }
977 }
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"; }
988 }
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"; }
997 }
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]"));
1002     else {
1003         if (isInout()) str<<" [IO]";
1004         else if (isInput()) str<<" [I]";
1005         else if (isOutput()) str<<" [O]";
1006     }
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();
1020 }
1021 void AstSenTree::dump(ostream& str) {
1022     this->AstNode::dump(str);
1023     if (isMulti()) str<<" [MULTI]";
1024 }
1025 void AstSenItem::dump(ostream& str) {
1026     this->AstNode::dump(str);
1027     str<<" ["<<edgeType().ascii()<<"]";
1028 }
1029 void AstParseRef::dump(ostream& str) {
1030     this->AstNode::dump(str);
1031     str<<" ["<<expect().ascii()<<"]";
1032 }
1033 void AstPackageRef::dump(ostream& str) {
1034     this->AstNode::dump(str);
1035     if (packagep()) { str<<" pkg="<<(void*)packagep(); }
1036     str<<" -> ";
1037     if (packagep()) { packagep()->dump(str); }
1038     else { str<<"UNLINKED"; }
1039 }
1040 void AstDot::dump(ostream& str) {
1041     this->AstNode::dump(str);
1042 }
1043 void AstActive::dump(ostream& str) {
1044     this->AstNode::dump(str);
1045     str<<" => ";
1046     if (sensesp()) { sensesp()->dump(str); }
1047     else { str<<"UNLINKED"; }
1048 }
1049 void AstNodeFTaskRef::dump(ostream& str) {
1050     this->AstNode::dump(str);
1051     if (packagep()) { str<<" pkg="<<(void*)packagep(); }
1052     str<<" -> ";
1053     if (dotted()!="") { str<<dotted()<<". - "; }
1054     if (taskp()) { taskp()->dump(str); }
1055     else { str<<"UNLINKED"; }
1056 }
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()<<"]";
1064 }
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]";
1070 }
1071 void AstCoverDecl::dump(ostream& str) {
1072     this->AstNode::dump(str);
1073     if (this->dataDeclNullp()) {
1074         str<<" -> ";
1075         this->dataDeclNullp()->dump(str);
1076     } else {
1077         if (binNum()) { str<<" bin"<<dec<<binNum(); }
1078     }
1079 }
1080 void AstCoverInc::dump(ostream& str) {
1081     this->AstNode::dump(str);
1082     str<<" -> ";
1083     if (declp()) { declp()->dump(str); }
1084     else { str<<"%Error:UNLINKED"; }
1085 }
1086 void AstTraceInc::dump(ostream& str) {
1087     this->AstNode::dump(str);
1088     str<<" -> ";
1089     if (declp()) { declp()->dump(str); }
1090     else { str<<"%Error:UNLINKED"; }
1091 }
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);
1098         out += "...";
1099     }
1100     str<<" \""<<out<<"\"";
1101 }
1102
1103 void AstCFile::dump(ostream& str) {
1104     this->AstNode::dump(str);
1105     if (source()) str<<" [SRC]";
1106     if (slow()) str<<" [SLOW]";
1107 }
1108 void AstCCall::dump(ostream& str) {
1109     this->AstNode::dump(str);
1110     if (funcp()) {
1111         str<<" "<<funcp()->name()<<" => ";
1112         funcp()->dump(str);
1113     }
1114 }
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]";
1122 }
This page took 0.090524 seconds and 4 git commands to generate.