diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 0e43c2daa..716412623 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -102,7 +102,7 @@ ostream& operator<<(ostream& str, const Determ& rhs) { //###################################################################### // Width state, as a visitor of each AstNode -class WidthVP : public AstNUser { +class WidthVP { // Parameters to pass down hierarchy with visit functions. AstNodeDType* m_dtypep; // Parent's data type to resolve to Stage m_stage; // If true, report errors @@ -115,6 +115,7 @@ public: : m_dtypep(NULL), m_stage(stage) { if (determ != SELF && stage != PRELIM) v3fatalSrc("Context-determined width request only allowed as prelim step"); } + WidthVP* p() { return this; } bool selfDtm() const { return m_dtypep==NULL; } AstNodeDType* dtypep() const { // Detect where overrideDType is probably the intended call @@ -173,6 +174,8 @@ public: #define accept in_WidthVisitor_use_AstNode_iterate_instead_of_AstNode_accept +//###################################################################### + class WidthVisitor : public AstNVisitor { private: // TYPES @@ -180,6 +183,7 @@ private: typedef map PatVecMap; // STATE + WidthVP* m_vup; // Current node state bool m_paramsOnly; // Computing parameter value; limit operation AstRange* m_cellRangep; // Range for arrayed instantiations, NULL for normal instantiations AstFunc* m_funcp; // Current function @@ -211,119 +215,119 @@ private: // _Ox=anything // Widths: 1 bit out, lhs 1 bit; Real: converts via compare with 0 - virtual void visit(AstLogNot* nodep, AstNUser* vup) { visit_log_not(nodep,vup); } + virtual void visit(AstLogNot* nodep, AstNUser*) { visit_log_not(nodep); } // Widths: 1 bit out, lhs 1 bit, rhs 1 bit; Real: converts via compare with 0 - virtual void visit(AstLogAnd* nodep, AstNUser* vup) { visit_log_and_or(nodep,vup); } - virtual void visit(AstLogOr* nodep, AstNUser* vup) { visit_log_and_or(nodep,vup); } - virtual void visit(AstLogIf* nodep, AstNUser* vup) { visit_log_and_or(nodep,vup); } // Conversion from real not in IEEE, but a fallout - virtual void visit(AstLogIff* nodep, AstNUser* vup) { visit_log_and_or(nodep,vup); } // Conversion from real not in IEEE, but a fallout + virtual void visit(AstLogAnd* nodep, AstNUser*) { visit_log_and_or(nodep); } + virtual void visit(AstLogOr* nodep, AstNUser*) { visit_log_and_or(nodep); } + virtual void visit(AstLogIf* nodep, AstNUser*) { visit_log_and_or(nodep); } // Conversion from real not in IEEE, but a fallout + virtual void visit(AstLogIff* nodep, AstNUser*) { visit_log_and_or(nodep); } // Conversion from real not in IEEE, but a fallout // Widths: 1 bit out, Any width lhs - virtual void visit(AstRedAnd* nodep, AstNUser* vup) { visit_red_and_or(nodep,vup); } - virtual void visit(AstRedOr* nodep, AstNUser* vup) { visit_red_and_or(nodep,vup); } - virtual void visit(AstRedXnor* nodep, AstNUser* vup){ visit_red_and_or(nodep,vup); } - virtual void visit(AstRedXor* nodep,AstNUser* vup) { visit_red_and_or(nodep,vup); } - virtual void visit(AstOneHot* nodep,AstNUser* vup) { visit_red_and_or(nodep,vup); } - virtual void visit(AstOneHot0* nodep,AstNUser* vup) { visit_red_and_or(nodep,vup); } - virtual void visit(AstIsUnknown* nodep,AstNUser* vup) { visit_red_unknown(nodep,vup); } // Allow real + virtual void visit(AstRedAnd* nodep, AstNUser*) { visit_red_and_or(nodep); } + virtual void visit(AstRedOr* nodep, AstNUser*) { visit_red_and_or(nodep); } + virtual void visit(AstRedXnor* nodep, AstNUser*){ visit_red_and_or(nodep); } + virtual void visit(AstRedXor* nodep, AstNUser*) { visit_red_and_or(nodep); } + virtual void visit(AstOneHot* nodep, AstNUser*) { visit_red_and_or(nodep); } + virtual void visit(AstOneHot0* nodep, AstNUser*) { visit_red_and_or(nodep); } + virtual void visit(AstIsUnknown* nodep, AstNUser*) { visit_red_unknown(nodep); } // Allow real // These have different node types, as they operate differently // Must add to case statement below, // Widths: 1 bit out, lhs width == rhs width. real if lhs|rhs real - virtual void visit(AstEq* nodep, AstNUser* vup) { visit_cmp_eq_gt(nodep,vup,true); } - virtual void visit(AstNeq* nodep, AstNUser* vup) { visit_cmp_eq_gt(nodep,vup,true); } - virtual void visit(AstGt* nodep, AstNUser* vup) { visit_cmp_eq_gt(nodep,vup,true); } - virtual void visit(AstGte* nodep, AstNUser* vup) { visit_cmp_eq_gt(nodep,vup,true); } - virtual void visit(AstLt* nodep, AstNUser* vup) { visit_cmp_eq_gt(nodep,vup,true); } - virtual void visit(AstLte* nodep, AstNUser* vup) { visit_cmp_eq_gt(nodep,vup,true); } - virtual void visit(AstGtS* nodep, AstNUser* vup) { visit_cmp_eq_gt(nodep,vup,true); } - virtual void visit(AstGteS* nodep, AstNUser* vup) { visit_cmp_eq_gt(nodep,vup,true); } - virtual void visit(AstLtS* nodep, AstNUser* vup) { visit_cmp_eq_gt(nodep,vup,true); } - virtual void visit(AstLteS* nodep, AstNUser* vup) { visit_cmp_eq_gt(nodep,vup,true); } - virtual void visit(AstEqCase* nodep, AstNUser* vup) { visit_cmp_eq_gt(nodep,vup,true); } - virtual void visit(AstNeqCase* nodep, AstNUser* vup) { visit_cmp_eq_gt(nodep,vup,true); } + virtual void visit(AstEq* nodep, AstNUser*) { visit_cmp_eq_gt(nodep, true); } + virtual void visit(AstNeq* nodep, AstNUser*) { visit_cmp_eq_gt(nodep, true); } + virtual void visit(AstGt* nodep, AstNUser*) { visit_cmp_eq_gt(nodep, true); } + virtual void visit(AstGte* nodep, AstNUser*) { visit_cmp_eq_gt(nodep, true); } + virtual void visit(AstLt* nodep, AstNUser*) { visit_cmp_eq_gt(nodep, true); } + virtual void visit(AstLte* nodep, AstNUser*) { visit_cmp_eq_gt(nodep, true); } + virtual void visit(AstGtS* nodep, AstNUser*) { visit_cmp_eq_gt(nodep, true); } + virtual void visit(AstGteS* nodep, AstNUser*) { visit_cmp_eq_gt(nodep, true); } + virtual void visit(AstLtS* nodep, AstNUser*) { visit_cmp_eq_gt(nodep, true); } + virtual void visit(AstLteS* nodep, AstNUser*) { visit_cmp_eq_gt(nodep, true); } + virtual void visit(AstEqCase* nodep, AstNUser*) { visit_cmp_eq_gt(nodep, true); } + virtual void visit(AstNeqCase* nodep, AstNUser*) { visit_cmp_eq_gt(nodep, true); } // ... These comparisons don't allow reals - virtual void visit(AstEqWild* nodep, AstNUser* vup) { visit_cmp_eq_gt(nodep,vup,false); } - virtual void visit(AstNeqWild* nodep, AstNUser* vup) { visit_cmp_eq_gt(nodep,vup,false); } + virtual void visit(AstEqWild* nodep, AstNUser*) { visit_cmp_eq_gt(nodep, false); } + virtual void visit(AstNeqWild* nodep, AstNUser*) { visit_cmp_eq_gt(nodep, false); } // ... Real compares - virtual void visit(AstEqD* nodep, AstNUser* vup) { visit_cmp_real(nodep,vup); } - virtual void visit(AstNeqD* nodep, AstNUser* vup) { visit_cmp_real(nodep,vup); } - virtual void visit(AstLtD* nodep, AstNUser* vup) { visit_cmp_real(nodep,vup); } - virtual void visit(AstLteD* nodep, AstNUser* vup) { visit_cmp_real(nodep,vup); } - virtual void visit(AstGtD* nodep, AstNUser* vup) { visit_cmp_real(nodep,vup); } - virtual void visit(AstGteD* nodep, AstNUser* vup) { visit_cmp_real(nodep,vup); } + virtual void visit(AstEqD* nodep, AstNUser*) { visit_cmp_real(nodep); } + virtual void visit(AstNeqD* nodep, AstNUser*) { visit_cmp_real(nodep); } + virtual void visit(AstLtD* nodep, AstNUser*) { visit_cmp_real(nodep); } + virtual void visit(AstLteD* nodep, AstNUser*) { visit_cmp_real(nodep); } + virtual void visit(AstGtD* nodep, AstNUser*) { visit_cmp_real(nodep); } + virtual void visit(AstGteD* nodep, AstNUser*) { visit_cmp_real(nodep); } // ... String compares - virtual void visit(AstEqN* nodep, AstNUser* vup) { visit_cmp_string(nodep,vup); } - virtual void visit(AstNeqN* nodep, AstNUser* vup) { visit_cmp_string(nodep,vup); } - virtual void visit(AstLtN* nodep, AstNUser* vup) { visit_cmp_string(nodep,vup); } - virtual void visit(AstLteN* nodep, AstNUser* vup) { visit_cmp_string(nodep,vup); } - virtual void visit(AstGtN* nodep, AstNUser* vup) { visit_cmp_string(nodep,vup); } - virtual void visit(AstGteN* nodep, AstNUser* vup) { visit_cmp_string(nodep,vup); } + virtual void visit(AstEqN* nodep, AstNUser*) { visit_cmp_string(nodep); } + virtual void visit(AstNeqN* nodep, AstNUser*) { visit_cmp_string(nodep); } + virtual void visit(AstLtN* nodep, AstNUser*) { visit_cmp_string(nodep); } + virtual void visit(AstLteN* nodep, AstNUser*) { visit_cmp_string(nodep); } + virtual void visit(AstGtN* nodep, AstNUser*) { visit_cmp_string(nodep); } + virtual void visit(AstGteN* nodep, AstNUser*) { visit_cmp_string(nodep); } // Widths: out width = lhs width = rhs width // Signed: Output signed iff LHS & RHS signed. // Real: Not allowed - virtual void visit(AstAnd* nodep, AstNUser* vup) { visit_boolmath_and_or(nodep,vup); } - virtual void visit(AstOr* nodep, AstNUser* vup) { visit_boolmath_and_or(nodep,vup); } - virtual void visit(AstXnor* nodep, AstNUser* vup) { visit_boolmath_and_or(nodep,vup); } - virtual void visit(AstXor* nodep, AstNUser* vup) { visit_boolmath_and_or(nodep,vup); } - virtual void visit(AstBufIf1* nodep, AstNUser* vup) { visit_boolmath_and_or(nodep,vup); } // Signed behavior changing in 3.814 + virtual void visit(AstAnd* nodep, AstNUser*) { visit_boolmath_and_or(nodep); } + virtual void visit(AstOr* nodep, AstNUser*) { visit_boolmath_and_or(nodep); } + virtual void visit(AstXnor* nodep, AstNUser*) { visit_boolmath_and_or(nodep); } + virtual void visit(AstXor* nodep, AstNUser*) { visit_boolmath_and_or(nodep); } + virtual void visit(AstBufIf1* nodep, AstNUser*) { visit_boolmath_and_or(nodep); } // Signed behavior changing in 3.814 // Width: Max(Lhs,Rhs) sort of. // Real: If either side real // Signed: If both sides real - virtual void visit(AstAdd* nodep, AstNUser* vup) { visit_add_sub_replace(nodep,vup,true); } - virtual void visit(AstSub* nodep, AstNUser* vup) { visit_add_sub_replace(nodep,vup,true); } - virtual void visit(AstDiv* nodep, AstNUser* vup) { visit_add_sub_replace(nodep,vup,true); } - virtual void visit(AstMul* nodep, AstNUser* vup) { visit_add_sub_replace(nodep,vup,true); } + virtual void visit(AstAdd* nodep, AstNUser*) { visit_add_sub_replace(nodep, true); } + virtual void visit(AstSub* nodep, AstNUser*) { visit_add_sub_replace(nodep, true); } + virtual void visit(AstDiv* nodep, AstNUser*) { visit_add_sub_replace(nodep, true); } + virtual void visit(AstMul* nodep, AstNUser*) { visit_add_sub_replace(nodep, true); } // These can't promote to real - virtual void visit(AstModDiv* nodep, AstNUser* vup) { visit_add_sub_replace(nodep,vup,false); } - virtual void visit(AstModDivS* nodep, AstNUser* vup) { visit_add_sub_replace(nodep,vup,false); } - virtual void visit(AstMulS* nodep, AstNUser* vup) { visit_add_sub_replace(nodep,vup,false); } - virtual void visit(AstDivS* nodep, AstNUser* vup) { visit_add_sub_replace(nodep,vup,false); } + virtual void visit(AstModDiv* nodep, AstNUser*) { visit_add_sub_replace(nodep, false); } + virtual void visit(AstModDivS* nodep, AstNUser*) { visit_add_sub_replace(nodep, false); } + virtual void visit(AstMulS* nodep, AstNUser*) { visit_add_sub_replace(nodep, false); } + virtual void visit(AstDivS* nodep, AstNUser*) { visit_add_sub_replace(nodep, false); } // Widths: out width = lhs width, but upper matters // Signed: Output signed iff LHS signed; unary operator // Unary promote to real - virtual void visit(AstNegate* nodep, AstNUser* vup) { visit_negate_not(nodep,vup,true); } + virtual void visit(AstNegate* nodep, AstNUser*) { visit_negate_not(nodep, true); } // Unary never real - virtual void visit(AstNot* nodep, AstNUser* vup) { visit_negate_not(nodep,vup,false); } + virtual void visit(AstNot* nodep, AstNUser*) { visit_negate_not(nodep, false); } // Real: inputs and output real - virtual void visit(AstAddD* nodep, AstNUser* vup) { visit_real_add_sub(nodep,vup); } - virtual void visit(AstSubD* nodep, AstNUser* vup) { visit_real_add_sub(nodep,vup); } - virtual void visit(AstDivD* nodep, AstNUser* vup) { visit_real_add_sub(nodep,vup); } - virtual void visit(AstMulD* nodep, AstNUser* vup) { visit_real_add_sub(nodep,vup); } - virtual void visit(AstPowD* nodep, AstNUser* vup) { visit_real_add_sub(nodep,vup); } + virtual void visit(AstAddD* nodep, AstNUser*) { visit_real_add_sub(nodep); } + virtual void visit(AstSubD* nodep, AstNUser*) { visit_real_add_sub(nodep); } + virtual void visit(AstDivD* nodep, AstNUser*) { visit_real_add_sub(nodep); } + virtual void visit(AstMulD* nodep, AstNUser*) { visit_real_add_sub(nodep); } + virtual void visit(AstPowD* nodep, AstNUser*) { visit_real_add_sub(nodep); } // Real: Output real - virtual void visit(AstNegateD* nodep, AstNUser* vup) { visit_real_neg_ceil(nodep,vup); } - virtual void visit(AstCeilD* nodep, AstNUser* vup) { visit_real_neg_ceil(nodep,vup); } - virtual void visit(AstExpD* nodep, AstNUser* vup) { visit_real_neg_ceil(nodep,vup); } - virtual void visit(AstFloorD* nodep, AstNUser* vup) { visit_real_neg_ceil(nodep,vup); } - virtual void visit(AstLogD* nodep, AstNUser* vup) { visit_real_neg_ceil(nodep,vup); } - virtual void visit(AstLog10D* nodep, AstNUser* vup) { visit_real_neg_ceil(nodep,vup); } - virtual void visit(AstSqrtD* nodep, AstNUser* vup) { visit_real_neg_ceil(nodep,vup); } + virtual void visit(AstNegateD* nodep, AstNUser*) { visit_real_neg_ceil(nodep); } + virtual void visit(AstCeilD* nodep, AstNUser*) { visit_real_neg_ceil(nodep); } + virtual void visit(AstExpD* nodep, AstNUser*) { visit_real_neg_ceil(nodep); } + virtual void visit(AstFloorD* nodep, AstNUser*) { visit_real_neg_ceil(nodep); } + virtual void visit(AstLogD* nodep, AstNUser*) { visit_real_neg_ceil(nodep); } + virtual void visit(AstLog10D* nodep, AstNUser*) { visit_real_neg_ceil(nodep); } + virtual void visit(AstSqrtD* nodep, AstNUser*) { visit_real_neg_ceil(nodep); } // Widths: out signed/unsigned width = lhs width, input un|signed - virtual void visit(AstSigned* nodep, AstNUser* vup) { visit_signed_unsigned(nodep,vup,AstNumeric::SIGNED); } - virtual void visit(AstUnsigned* nodep, AstNUser* vup) { visit_signed_unsigned(nodep,vup,AstNumeric::UNSIGNED); } + virtual void visit(AstSigned* nodep, AstNUser*) { visit_signed_unsigned(nodep, AstNumeric::SIGNED); } + virtual void visit(AstUnsigned* nodep, AstNUser*) { visit_signed_unsigned(nodep, AstNumeric::UNSIGNED); } // Widths: Output width from lhs, rhs<33 bits // Signed: If lhs signed - virtual void visit(AstShiftL* nodep, AstNUser* vup) { visit_shift(nodep,vup); } - virtual void visit(AstShiftR* nodep, AstNUser* vup) { visit_shift(nodep,vup); } + virtual void visit(AstShiftL* nodep, AstNUser*) { visit_shift(nodep); } + virtual void visit(AstShiftR* nodep, AstNUser*) { visit_shift(nodep); } // ShiftRS converts to ShiftR, but not vice-versa - virtual void visit(AstShiftRS* nodep, AstNUser* vup) { visit_shift(nodep,vup); } + virtual void visit(AstShiftRS* nodep, AstNUser*) { visit_shift(nodep); } //======== // Widths: Output real, input integer signed - virtual void visit(AstBitsToRealD* nodep, AstNUser* vup) { visit_Or_Lu64(nodep,vup); } - virtual void visit(AstIToRD* nodep, AstNUser* vup) { visit_Or_Ls32(nodep,vup); } + virtual void visit(AstBitsToRealD* nodep, AstNUser*) { visit_Or_Lu64(nodep); } + virtual void visit(AstIToRD* nodep, AstNUser*) { visit_Or_Ls32(nodep); } // Widths: Output integer signed, input real - virtual void visit(AstRToIS* nodep, AstNUser* vup) { visit_Os32_Lr(nodep,vup); } - virtual void visit(AstRToIRoundS* nodep, AstNUser* vup) { visit_Os32_Lr(nodep,vup); } + virtual void visit(AstRToIS* nodep, AstNUser*) { visit_Os32_Lr(nodep); } + virtual void visit(AstRToIRoundS* nodep, AstNUser*) { visit_Os32_Lr(nodep); } // Widths: Output integer unsigned, input real - virtual void visit(AstRealToBits* nodep, AstNUser* vup) { visit_Ou64_Lr(nodep,vup); } + virtual void visit(AstRealToBits* nodep, AstNUser*) { visit_Ou64_Lr(nodep); } // Widths: Constant, terminal virtual void visit(AstTime* nodep, AstNUser*) { nodep->dtypeSetUInt64(); } @@ -332,24 +336,24 @@ private: virtual void visit(AstScopeName* nodep, AstNUser*) { nodep->dtypeSetUInt64(); } // A pointer, but not that it matters // Special cases. So many.... - virtual void visit(AstNodeCond* nodep, AstNUser* vup) { + virtual void visit(AstNodeCond* nodep, AstNUser*) { // op=cond?expr1:expr2 // Signed: Output signed iff RHS & THS signed (presumed, not in IEEE) // See IEEE-2012 11.4.11 and Table 11-21. // LHS is self-determined // Width: max(RHS,THS) // Real: Output real if either expression is real, non-real argument gets converted - if (vup->c()->prelim()) { // First stage evaluation + if (m_vup->prelim()) { // First stage evaluation // Just once, do the conditional, expect one bit out. iterateCheckBool(nodep,"Conditional Test",nodep->condp(),BOTH); // Determine sub expression widths only relying on what's in the subops // CONTEXT determined, but need data type for pattern assignments - nodep->expr1p()->iterateAndNext(*this,WidthVP(vup->c()->dtypeNullp(),PRELIM).p()); - nodep->expr2p()->iterateAndNext(*this,WidthVP(vup->c()->dtypeNullp(),PRELIM).p()); + userIterateAndNext(nodep->expr1p(), WidthVP(m_vup->dtypeNullp(),PRELIM).p()); + userIterateAndNext(nodep->expr2p(), WidthVP(m_vup->dtypeNullp(),PRELIM).p()); // Calculate width of this expression. - // First call (prelim()) vup->c()->width() is probably zero, so we'll return + // First call (prelim()) m_vup->width() is probably zero, so we'll return // the size of this subexpression only. - // Second call (final()) vup->c()->width() is probably the expression size, so + // Second call (final()) m_vup->width() is probably the expression size, so // the expression includes the size of the output too. if (nodep->expr1p()->isDouble() || nodep->expr2p()->isDouble()) { nodep->dtypeSetDouble(); @@ -360,8 +364,8 @@ private: nodep->dtypeSetLogicSized(width,mwidth,AstNumeric::fromBool(issigned)); } } - if (vup->c()->final()) { - AstNodeDType* expDTypep = vup->c()->dtypeOverridep(nodep->dtypep()); + if (m_vup->final()) { + AstNodeDType* expDTypep = m_vup->dtypeOverridep(nodep->dtypep()); AstNodeDType* subDTypep = expDTypep; nodep->dtypeFrom(expDTypep); // Error report and change sizes for suboperands of this node. @@ -369,14 +373,14 @@ private: iterateCheck(nodep,"Conditional False",nodep->expr2p(),CONTEXT,FINAL,subDTypep,EXTEND_EXP); } } - virtual void visit(AstConcat* nodep, AstNUser* vup) { + virtual void visit(AstConcat* nodep, AstNUser*) { // Real: Not allowed (assumed) // Signed: unsigned output, input either (assumed) // IEEE-2012 Table 11-21, and 11.8.1: // LHS, RHS is self-determined // signed: Unsigned (11.8.1) // width: LHS + RHS - if (vup->c()->prelim()) { + if (m_vup->prelim()) { iterateCheckSizedSelf(nodep,"LHS",nodep->lhsp(),SELF,BOTH); iterateCheckSizedSelf(nodep,"RHS",nodep->rhsp(),SELF,BOTH); nodep->dtypeSetLogicSized(nodep->lhsp()->width() + nodep->rhsp()->width(), @@ -407,33 +411,33 @@ private: return; } } - if (vup->c()->final()) { + if (m_vup->final()) { if (!nodep->dtypep()->widthSized()) { // See also error in V3Number nodep->v3warn(WIDTHCONCAT,"Unsized numbers/parameters not allowed in concatenations."); } } } - virtual void visit(AstConcatN* nodep, AstNUser* vup) { + virtual void visit(AstConcatN* nodep, AstNUser*) { // String concatenate. // Already did AstConcat simplifications - if (vup->c()->prelim()) { + if (m_vup->prelim()) { iterateCheckString(nodep,"LHS",nodep->lhsp(),BOTH); iterateCheckString(nodep,"RHS",nodep->rhsp(),BOTH); nodep->dtypeSetString(); } - if (vup->c()->final()) { + if (m_vup->final()) { if (!nodep->dtypep()->widthSized()) { // See also error in V3Number nodep->v3warn(WIDTHCONCAT,"Unsized numbers/parameters not allowed in concatenations."); } } } - virtual void visit(AstReplicate* nodep, AstNUser* vup) { + virtual void visit(AstReplicate* nodep, AstNUser*) { // IEEE-2012 Table 11-21: // LHS, RHS is self-determined // width: value(LHS) * width(RHS) - if (vup->c()->prelim()) { + if (m_vup->prelim()) { iterateCheckSizedSelf(nodep,"LHS",nodep->lhsp(),SELF,BOTH); iterateCheckSizedSelf(nodep,"RHS",nodep->rhsp(),SELF,BOTH); V3Const::constifyParamsEdit(nodep->rhsp()); // rhsp may change @@ -455,16 +459,16 @@ private: AstNumeric::UNSIGNED); } } - if (vup->c()->final()) { + if (m_vup->final()) { if (!nodep->dtypep()->widthSized()) { // See also error in V3Number nodep->v3warn(WIDTHCONCAT,"Unsized numbers/parameters not allowed in replications."); } } } - virtual void visit(AstReplicateN* nodep, AstNUser* vup) { + virtual void visit(AstReplicateN* nodep, AstNUser*) { // Replicate with string - if (vup->c()->prelim()) { + if (m_vup->prelim()) { iterateCheckString(nodep,"LHS",nodep->lhsp(),BOTH); iterateCheckSizedSelf(nodep,"RHS",nodep->rhsp(),SELF,BOTH); V3Const::constifyParamsEdit(nodep->rhsp()); // rhsp may change @@ -476,15 +480,15 @@ private: } nodep->dtypeSetString(); } - if (vup->c()->final()) { + if (m_vup->final()) { if (!nodep->dtypep()->widthSized()) { // See also error in V3Number nodep->v3warn(WIDTHCONCAT,"Unsized numbers/parameters not allowed in replications."); } } } - virtual void visit(AstNodeStream* nodep, AstNUser* vup) { - if (vup->c()->prelim()) { + virtual void visit(AstNodeStream* nodep, AstNUser*) { + if (m_vup->prelim()) { iterateCheckSizedSelf(nodep,"LHS",nodep->lhsp(),SELF,BOTH); iterateCheckSizedSelf(nodep,"RHS",nodep->rhsp(),SELF,BOTH); V3Const::constifyParamsEdit(nodep->rhsp()); // rhsp may change @@ -503,14 +507,14 @@ private: (nodep->lhsp()->widthMin()), AstNumeric::UNSIGNED); } - if (vup->c()->final()) { + if (m_vup->final()) { if (!nodep->dtypep()->widthSized()) { // See also error in V3Number nodep->v3warn(WIDTHCONCAT,"Unsized numbers/parameters not allowed in streams."); } } } - virtual void visit(AstRange* nodep, AstNUser* vup) { + virtual void visit(AstRange* nodep, AstNUser*) { // Real: Not allowed // Signed: unsigned output, input either // Convert all range values to constants @@ -530,7 +534,7 @@ private: // and when tracing the vector. nodep->msbp()->swapWith(nodep->lsbp()); } - if (vup->c()->prelim()) { + if (m_vup->prelim()) { // Don't need to iterate because V3Const already constified int width = nodep->elementsConst(); if (width > (1<<28)) nodep->v3error("Width of bit range is huge; vector of over 1billion bits: 0x"<didWidth()) return; - if (vup->c()->prelim()) { + if (m_vup->prelim()) { if (debug()>=9) nodep->dumpTree(cout,"-selWidth: "); - nodep->fromp()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p()); - nodep->lsbp()->iterateAndNext(*this,WidthVP(SELF,PRELIM).p()); + userIterateAndNext(nodep->fromp(), WidthVP(CONTEXT,PRELIM).p()); + userIterateAndNext(nodep->lsbp(), WidthVP(SELF,PRELIM).p()); checkCvtUS(nodep->fromp()); iterateCheckSizedSelf(nodep,"Select Width",nodep->widthp(),SELF,BOTH); iterateCheckSizedSelf(nodep,"Select LHS",nodep->lhsp(),SELF,BOTH); @@ -577,7 +581,7 @@ private: <<" bits from only "<fromp()->width()<<" bit number"); // Extend it. AstNodeDType* subDTypep = nodep->findLogicDType(width,width,nodep->fromp()->dtypep()->numeric()); - widthCheckSized(nodep,"errorless...",nodep->fromp(),subDTypep,EXTEND_EXP,false/*noerror*/); + widthCheckSized(nodep,"errorless...",nodep->fromp(),subDTypep,EXTEND_EXP, false/*noerror*/); } // Check bit indexes. // What is the MSB? We want the true MSB, not one starting at 0, @@ -593,8 +597,8 @@ private: } int selwidth = V3Number::log2b(frommsb+1-1)+1; // Width to address a bit AstNodeDType* selwidthDTypep = nodep->findLogicDType(selwidth,selwidth,nodep->lsbp()->dtypep()->numeric()); - nodep->fromp()->iterateAndNext(*this,WidthVP(SELF,FINAL).p()); - nodep->lsbp()->iterateAndNext(*this,WidthVP(SELF,FINAL).p()); + userIterateAndNext(nodep->fromp(), WidthVP(SELF,FINAL).p()); + userIterateAndNext(nodep->lsbp(), WidthVP(SELF,FINAL).p()); if (widthBad(nodep->lsbp(),selwidthDTypep) && nodep->lsbp()->width()!=32) { if (!nodep->fileline()->warnIsOff(V3ErrorCode::WIDTH)) { @@ -634,18 +638,18 @@ private: // lsbp() must be self-determined, however for performance we want the select to be // truncated to fit within the maximum select range, e.g. turn Xs outside of the select // into something fast which pulls from within the array. - widthCheckSized(nodep,"Extract Range",nodep->lsbp(),selwidthDTypep,EXTEND_EXP,false/*NOWARN*/); + widthCheckSized(nodep,"Extract Range",nodep->lsbp(),selwidthDTypep,EXTEND_EXP, false/*NOWARN*/); } } } - virtual void visit(AstArraySel* nodep, AstNUser* vup) { + virtual void visit(AstArraySel* nodep, AstNUser*) { // Signed/Real: Output signed iff LHS signed/real; binary operator // Note by contrast, bit extract selects are unsigned // LSB is self-determined (IEEE 2012 11.5.1) - if (vup->c()->prelim()) { + if (m_vup->prelim()) { iterateCheckSizedSelf(nodep,"Bit select",nodep->bitp(),SELF,BOTH); - nodep->fromp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); + userIterateAndNext(nodep->fromp(), WidthVP(SELF,BOTH).p()); // int frommsb; int fromlsb; @@ -689,57 +693,57 @@ private: <<" outside "<bitp(),selwidthDTypep,EXTEND_EXP,false/*NOWARN*/); + widthCheckSized(nodep,"Extract Range",nodep->bitp(),selwidthDTypep,EXTEND_EXP, false/*NOWARN*/); } } } - virtual void visit(AstSelBit* nodep, AstNUser* vup) { + virtual void visit(AstSelBit* nodep, AstNUser*) { // Just a quick check as after V3Param these nodes instead are AstSel's - nodep->fromp()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p()); //FINAL in AstSel - nodep->rhsp()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p()); //FINAL in AstSel - nodep->thsp()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p()); //FINAL in AstSel - nodep->attrp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); - AstNode* selp = V3Width::widthSelNoIterEdit(nodep); if (selp!=nodep) { nodep=NULL; selp->iterate(*this,vup); return; } + userIterateAndNext(nodep->fromp(), WidthVP(CONTEXT,PRELIM).p()); //FINAL in AstSel + userIterateAndNext(nodep->rhsp(), WidthVP(CONTEXT,PRELIM).p()); //FINAL in AstSel + userIterateAndNext(nodep->thsp(), WidthVP(CONTEXT,PRELIM).p()); //FINAL in AstSel + userIterateAndNext(nodep->attrp(), WidthVP(SELF,BOTH).p()); + AstNode* selp = V3Width::widthSelNoIterEdit(nodep); if (selp!=nodep) { nodep=NULL; userIterate(selp, m_vup); return; } nodep->v3fatalSrc("AstSelBit should disappear after widthSel"); } - virtual void visit(AstSelExtract* nodep, AstNUser* vup) { + virtual void visit(AstSelExtract* nodep, AstNUser*) { // Just a quick check as after V3Param these nodes instead are AstSel's - nodep->fromp()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p()); //FINAL in AstSel - nodep->rhsp()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p()); //FINAL in AstSel - nodep->thsp()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p()); //FINAL in AstSel - nodep->attrp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); - AstNode* selp = V3Width::widthSelNoIterEdit(nodep); if (selp!=nodep) { nodep=NULL; selp->iterate(*this,vup); return; } + userIterateAndNext(nodep->fromp(), WidthVP(CONTEXT,PRELIM).p()); //FINAL in AstSel + userIterateAndNext(nodep->rhsp(), WidthVP(CONTEXT,PRELIM).p()); //FINAL in AstSel + userIterateAndNext(nodep->thsp(), WidthVP(CONTEXT,PRELIM).p()); //FINAL in AstSel + userIterateAndNext(nodep->attrp(), WidthVP(SELF,BOTH).p()); + AstNode* selp = V3Width::widthSelNoIterEdit(nodep); if (selp!=nodep) { nodep=NULL; userIterate(selp, m_vup); return; } nodep->v3fatalSrc("AstSelExtract should disappear after widthSel"); } - virtual void visit(AstSelPlus* nodep, AstNUser* vup) { - nodep->fromp()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p()); //FINAL in AstSel - nodep->rhsp()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p()); //FINAL in AstSel - nodep->thsp()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p()); //FINAL in AstSel - nodep->attrp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); - AstNode* selp = V3Width::widthSelNoIterEdit(nodep); if (selp!=nodep) { nodep=NULL; selp->iterate(*this,vup); return; } + virtual void visit(AstSelPlus* nodep, AstNUser*) { + userIterateAndNext(nodep->fromp(), WidthVP(CONTEXT,PRELIM).p()); //FINAL in AstSel + userIterateAndNext(nodep->rhsp(), WidthVP(CONTEXT,PRELIM).p()); //FINAL in AstSel + userIterateAndNext(nodep->thsp(), WidthVP(CONTEXT,PRELIM).p()); //FINAL in AstSel + userIterateAndNext(nodep->attrp(), WidthVP(SELF,BOTH).p()); + AstNode* selp = V3Width::widthSelNoIterEdit(nodep); if (selp!=nodep) { nodep=NULL; userIterate(selp, m_vup); return; } nodep->v3fatalSrc("AstSelPlus should disappear after widthSel"); } - virtual void visit(AstSelMinus* nodep, AstNUser* vup) { - nodep->fromp()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p()); //FINAL in AstSel - nodep->rhsp()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p()); //FINAL in AstSel - nodep->thsp()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p()); //FINAL in AstSel - nodep->attrp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); - AstNode* selp = V3Width::widthSelNoIterEdit(nodep); if (selp!=nodep) { nodep=NULL; selp->iterate(*this,vup); return; } + virtual void visit(AstSelMinus* nodep, AstNUser*) { + userIterateAndNext(nodep->fromp(), WidthVP(CONTEXT,PRELIM).p()); //FINAL in AstSel + userIterateAndNext(nodep->rhsp(), WidthVP(CONTEXT,PRELIM).p()); //FINAL in AstSel + userIterateAndNext(nodep->thsp(), WidthVP(CONTEXT,PRELIM).p()); //FINAL in AstSel + userIterateAndNext(nodep->attrp(), WidthVP(SELF,BOTH).p()); + AstNode* selp = V3Width::widthSelNoIterEdit(nodep); if (selp!=nodep) { nodep=NULL; userIterate(selp, m_vup); return; } nodep->v3fatalSrc("AstSelMinus should disappear after widthSel"); } - virtual void visit(AstExtend* nodep, AstNUser* vup) { + virtual void visit(AstExtend* nodep, AstNUser*) { // Only created by this process, so we know width from here down is correct. } - virtual void visit(AstExtendS* nodep, AstNUser* vup) { + virtual void visit(AstExtendS* nodep, AstNUser*) { // Only created by this process, so we know width from here down is correct. } - virtual void visit(AstConst* nodep, AstNUser* vup) { + virtual void visit(AstConst* nodep, AstNUser*) { // The node got setup with the signed/real state of the node. // However a later operation may have changed the node->signed w/o changing // the number's sign. So we don't: nodep->dtypeChgSigned(nodep->num().isSigned()); - if (vup && vup->c()->prelim()) { + if (m_vup && m_vup->prelim()) { if (nodep->num().isString()) { nodep->dtypeSetString(); } else if (nodep->num().sized()) { @@ -751,37 +755,37 @@ private: // We don't size the constant until we commit the widths, as need parameters // to remain unsized, and numbers to remain unsized to avoid backp() warnings } - virtual void visit(AstRand* nodep, AstNUser* vup) { - if (vup->c()->prelim()) { + virtual void visit(AstRand* nodep, AstNUser*) { + if (m_vup->prelim()) { nodep->dtypeSetSigned32(); // Says the spec } } - virtual void visit(AstUCFunc* nodep, AstNUser* vup) { + virtual void visit(AstUCFunc* nodep, AstNUser*) { // Give it the size the user wants. - if (vup && vup->c()->prelim()) { + if (m_vup && m_vup->prelim()) { nodep->dtypeSetLogicSized(32,1,AstNumeric::UNSIGNED); // We don't care // All arguments seek their natural sizes - nodep->iterateChildren(*this,WidthVP(SELF,BOTH).p()); + userIterateChildren(nodep, WidthVP(SELF,BOTH).p()); } - if (vup->c()->final()) { - AstNodeDType* expDTypep = vup->c()->dtypeOverridep(nodep->dtypep()); + if (m_vup->final()) { + AstNodeDType* expDTypep = m_vup->dtypeOverridep(nodep->dtypep()); nodep->dtypeFrom(expDTypep); // Assume user knows the rules; go with the flow if (nodep->width()>64) nodep->v3error("Unsupported: $c can't generate wider than 64 bits"); } } - virtual void visit(AstCLog2* nodep, AstNUser* vup) { - if (vup->c()->prelim()) { + virtual void visit(AstCLog2* nodep, AstNUser*) { + if (m_vup->prelim()) { iterateCheckSizedSelf(nodep,"LHS",nodep->lhsp(),SELF,BOTH); nodep->dtypeSetSigned32(); } } - virtual void visit(AstPow* nodep, AstNUser* vup) { + virtual void visit(AstPow* nodep, AstNUser*) { // Pow is special, output sign only depends on LHS sign, but function result depends on both signs // RHS is self-determined (IEEE) // Real if either side is real (as with AstAdd) - if (vup->c()->prelim()) { - nodep->lhsp()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p()); - nodep->rhsp()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p()); + if (m_vup->prelim()) { + userIterateAndNext(nodep->lhsp(), WidthVP(CONTEXT,PRELIM).p()); + userIterateAndNext(nodep->rhsp(), WidthVP(CONTEXT,PRELIM).p()); if (nodep->lhsp()->isDouble() || nodep->rhsp()->isDouble()) { spliceCvtD(nodep->lhsp()); spliceCvtD(nodep->rhsp()); @@ -794,8 +798,8 @@ private: nodep->dtypeFrom(nodep->lhsp()); } - if (vup->c()->final()) { - AstNodeDType* expDTypep = vup->c()->dtypeOverridep(nodep->dtypep()); + if (m_vup->final()) { + AstNodeDType* expDTypep = m_vup->dtypeOverridep(nodep->dtypep()); nodep->dtypeFrom(expDTypep); // rhs already finalized in iterate_shift_prelim iterateCheck(nodep,"LHS",nodep->lhsp(),SELF,FINAL,nodep->dtypep(),EXTEND_EXP); @@ -819,38 +823,38 @@ private: } } } - virtual void visit(AstPowSU* nodep, AstNUser* vup) { + virtual void visit(AstPowSU* nodep, AstNUser*) { // POWSU/SS/US only created here, dtype already determined, so nothing to do in this function - nodep->lhsp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); - nodep->rhsp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); + userIterateAndNext(nodep->lhsp(), WidthVP(SELF,BOTH).p()); + userIterateAndNext(nodep->rhsp(), WidthVP(SELF,BOTH).p()); } - virtual void visit(AstPowSS* nodep, AstNUser* vup) { + virtual void visit(AstPowSS* nodep, AstNUser*) { // POWSU/SS/US only created here, dtype already determined, so nothing to do in this function - nodep->lhsp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); - nodep->rhsp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); + userIterateAndNext(nodep->lhsp(), WidthVP(SELF,BOTH).p()); + userIterateAndNext(nodep->rhsp(), WidthVP(SELF,BOTH).p()); } - virtual void visit(AstPowUS* nodep, AstNUser* vup) { + virtual void visit(AstPowUS* nodep, AstNUser*) { // POWSU/SS/US only created here, dtype already determined, so nothing to do in this function - nodep->lhsp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); - nodep->rhsp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); + userIterateAndNext(nodep->lhsp(), WidthVP(SELF,BOTH).p()); + userIterateAndNext(nodep->rhsp(), WidthVP(SELF,BOTH).p()); } - virtual void visit(AstCountOnes* nodep, AstNUser* vup) { - if (vup->c()->prelim()) { + virtual void visit(AstCountOnes* nodep, AstNUser*) { + if (m_vup->prelim()) { iterateCheckSizedSelf(nodep,"LHS",nodep->lhsp(),SELF,BOTH); // If it's a 32 bit number, we need a 6 bit number as we need to return '32'. int selwidth = V3Number::log2b(nodep->lhsp()->width())+1; nodep->dtypeSetLogicSized(selwidth,selwidth,AstNumeric::UNSIGNED); // Spec doesn't indicate if an integer } } - virtual void visit(AstCvtPackString* nodep, AstNUser* vup) { + virtual void visit(AstCvtPackString* nodep, AstNUser*) { // Opaque returns, so arbitrary - nodep->lhsp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); + userIterateAndNext(nodep->lhsp(), WidthVP(SELF,BOTH).p()); // Type set in constructor } virtual void visit(AstAttrOf* nodep, AstNUser*) { AstAttrOf* oldAttr = m_attrp; m_attrp = nodep; - nodep->fromp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); + userIterateAndNext(nodep->fromp(), WidthVP(SELF,BOTH).p()); // Don't iterate children, don't want to lose VarRef. switch (nodep->attrType()) { case AstAttrType::VAR_BASE: @@ -903,7 +907,7 @@ private: } m_attrp = oldAttr; } - virtual void visit(AstText* nodep, AstNUser* vup) { + virtual void visit(AstText* nodep, AstNUser*) { // Only used in CStmts which don't care.... } @@ -914,7 +918,7 @@ private: // Iterate into subDTypep() to resolve that type and update pointer. nodep->refDTypep(iterateEditDTypep(nodep, nodep->subDTypep())); // Cleanup array size - nodep->rangep()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); + userIterateAndNext(nodep->rangep(), WidthVP(SELF,BOTH).p()); nodep->dtypep(nodep); // The array itself, not subDtype if (nodep->castUnpackArrayDType()) { // Historically array elements have width of the ref type not the full array @@ -929,7 +933,7 @@ private: if (nodep->didWidthAndSet()) return; // This node is a dtype & not both PRELIMed+FINALed if (nodep->generic()) return; // Already perfect if (nodep->rangep()) { - nodep->rangep()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); + userIterateAndNext(nodep->rangep(), WidthVP(SELF,BOTH).p()); // Because this DType has a unique child range, we know it's not pointed at by // other nodes unless they are referencing this type. Furthermore the width() // calculation would return identical values. Therefore we can directly replace the width @@ -957,14 +961,14 @@ private: if (nodep->childDTypep()) nodep->refDTypep(moveChildDTypeEdit(nodep)); // Iterate into subDTypep() to resolve that type and update pointer. nodep->refDTypep(iterateEditDTypep(nodep, nodep->subDTypep())); - nodep->iterateChildren(*this); + userIterateChildren(nodep, NULL); nodep->dtypep(nodep); // Should already be set, but be clear it's not the subDType nodep->widthFromSub(nodep->subDTypep()); UINFO(4,"dtWidthed "<didWidthAndSet()) return; // This node is a dtype & not both PRELIMed+FINALed - nodep->iterateChildren(*this); + userIterateChildren(nodep, NULL); if (nodep->subDTypep()) nodep->refDTypep(iterateEditDTypep(nodep, nodep->subDTypep())); nodep->dtypeFrom(nodep->dtypeSkipRefp()); nodep->widthFromSub(nodep->subDTypep()); @@ -973,17 +977,17 @@ private: virtual void visit(AstTypedef* nodep, AstNUser*) { if (nodep->didWidthAndSet()) return; // This node is a dtype & not both PRELIMed+FINALed if (nodep->childDTypep()) nodep->dtypep(moveChildDTypeEdit(nodep)); - nodep->iterateChildren(*this); + userIterateChildren(nodep, NULL); nodep->dtypep(iterateEditDTypep(nodep, nodep->subDTypep())); } virtual void visit(AstParamTypeDType* nodep, AstNUser*) { if (nodep->didWidthAndSet()) return; // This node is a dtype & not both PRELIMed+FINALed if (nodep->childDTypep()) nodep->dtypep(moveChildDTypeEdit(nodep)); - nodep->iterateChildren(*this); + userIterateChildren(nodep, NULL); nodep->dtypep(iterateEditDTypep(nodep, nodep->subDTypep())); nodep->widthFromSub(nodep->subDTypep()); } - virtual void visit(AstCastParse* nodep, AstNUser* vup) { + virtual void visit(AstCastParse* nodep, AstNUser*) { // nodep->dtp could be data type, or a primary_constant // Don't iterate lhsp, will deal with that once convert the type V3Const::constifyParamsEdit(nodep->dtp()); // itemp may change @@ -992,17 +996,17 @@ private: AstNode* newp = new AstCastSize(nodep->fileline(), nodep->lhsp()->unlinkFrBack(), constp); nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep); - newp->iterate(*this,vup); + userIterate(newp, m_vup); } else { nodep->v3error("Unsupported: Cast to "<dtp()->prettyTypeName()); nodep->replaceWith(nodep->lhsp()->unlinkFrBack()); } } - virtual void visit(AstCast* nodep, AstNUser* vup) { + virtual void visit(AstCast* nodep, AstNUser*) { if (nodep->childDTypep()) nodep->dtypep(moveChildDTypeEdit(nodep)); nodep->dtypep(iterateEditDTypep(nodep, nodep->dtypep())); //if (debug()) nodep->dumpTree(cout," CastPre: "); - nodep->lhsp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); + userIterateAndNext(nodep->lhsp(), WidthVP(SELF,BOTH).p()); // When more general casts are supported, the cast elimination will be done later. // For now, replace it ASAP, so widthing can propagate easily // The cast may change signing, but we don't know the sign yet. Make it so. @@ -1014,7 +1018,7 @@ private: // Note widthCheckSized might modify nodep->lhsp() AstNodeDType* subDTypep = nodep->findLogicDType(nodep->width(),nodep->width(), nodep->lhsp()->dtypep()->numeric()); - widthCheckSized(nodep,"Cast",nodep->lhsp(),subDTypep,EXTEND_EXP,false); + widthCheckSized(nodep,"Cast",nodep->lhsp(),subDTypep,EXTEND_EXP, false); } AstNode* newp = nodep->lhsp()->unlinkFrBack(); if (basicp->isDouble() && !newp->isDouble()) { @@ -1037,15 +1041,15 @@ private: pushDeletep(nodep); VL_DANGLING(nodep); //if (debug()) newp->dumpTree(cout," CastOut: "); } - virtual void visit(AstCastSize* nodep, AstNUser* vup) { + virtual void visit(AstCastSize* nodep, AstNUser*) { // IEEE: Signedness of result is same as self-determined signedness // However, the result is same as BITSEL, so we do not sign extend the LHS if (!nodep->rhsp()->castConst()) nodep->v3fatalSrc("Unsupported: Non-const cast of size"); //if (debug()) nodep->dumpTree(cout," CastSizePre: "); - if (vup->c()->prelim()) { + if (m_vup->prelim()) { int width = nodep->rhsp()->castConst()->toSInt(); if (width < 1) { nodep->v3error("Size-changing cast to zero or negative size"); width=1; } - nodep->lhsp()->iterateAndNext(*this,WidthVP(SELF,PRELIM).p()); + userIterateAndNext(nodep->lhsp(), WidthVP(SELF,PRELIM).p()); AstBasicDType* underDtp = nodep->lhsp()->dtypep()->castBasicDType(); if (!underDtp) { underDtp = nodep->lhsp()->dtypep()->basicp(); @@ -1065,7 +1069,7 @@ private: : nodep->findBitDType(calcWidth, calcWidth, underDtp->numeric())); nodep->dtypep(calcDtp); // We ignore warnings as that is sort of the point of a cast - iterateCheck(nodep,"Cast expr",nodep->lhsp(),CONTEXT,FINAL,calcDtp,EXTEND_EXP,false); + iterateCheck(nodep,"Cast expr",nodep->lhsp(),CONTEXT,FINAL,calcDtp,EXTEND_EXP, false); } if (debug()) nodep->dumpTree(cout," CastSizeClc: "); // Next step, make the proper output width @@ -1075,10 +1079,10 @@ private: : nodep->findBitDType(width, width, underDtp->numeric())); nodep->dtypep(outDtp); // We ignore warnings as that is sort of the point of a cast - widthCheckSized(nodep,"Cast expr",nodep->lhsp(),outDtp,EXTEND_EXP,false); + widthCheckSized(nodep,"Cast expr",nodep->lhsp(),outDtp,EXTEND_EXP, false); } } - if (vup->c()->final()) { + if (m_vup->final()) { // CastSize not needed once sizes determined AstNode* underp = nodep->lhsp()->unlinkFrBack(); nodep->replaceWith(underp); @@ -1086,7 +1090,7 @@ private: } //if (debug()) nodep->dumpTree(cout," CastSizeOut: "); } - virtual void visit(AstVar* nodep, AstNUser* vup) { + virtual void visit(AstVar* nodep, AstNUser*) { //if (debug()) nodep->dumpTree(cout," InitPre: "); // Must have deterministic constant width // We can't skip this step when width()!=0, as creating a AstVar @@ -1120,7 +1124,7 @@ private: bool implicitParam = nodep->isParam() && bdtypep && bdtypep->implicit(); if (implicitParam) { if (nodep->valuep()) { - nodep->valuep()->iterateAndNext(*this,WidthVP(nodep->dtypep(),PRELIM).p()); + userIterateAndNext(nodep->valuep(), WidthVP(nodep->dtypep(),PRELIM).p()); UINFO(9,"implicitParamPRELIMIV "<valuep()<valuep() && !didchk) { //if (debug()) nodep->dumpTree(cout," final: "); // AstPattern requires assignments to pass datatype on PRELIM - nodep->valuep()->iterateAndNext(*this,WidthVP(nodep->dtypep(),PRELIM).p()); + userIterateAndNext(nodep->valuep(), WidthVP(nodep->dtypep(),PRELIM).p()); iterateCheckAssign(nodep,"Initial value",nodep->valuep(),FINAL,nodep->dtypep()); } UINFO(4,"varWidthed "<didWidth(true); nodep->doingWidth(false); } - virtual void visit(AstNodeVarRef* nodep, AstNUser* vup) { + virtual void visit(AstNodeVarRef* nodep, AstNUser*) { if (nodep->didWidth()) return; if (!nodep->varp()) nodep->v3fatalSrc("Unlinked varref"); if (!nodep->varp()->didWidth()) { // Var hasn't been widthed, so make it so. - nodep->varp()->iterate(*this); + userIterate(nodep->varp(), NULL); } //if (debug()>=9) { nodep->dumpTree(cout," VRin "); nodep->varp()->dumpTree(cout," forvar "); } // Note genvar's are also entered as integers @@ -1201,7 +1205,7 @@ private: nodep->didWidth(true); } - virtual void visit(AstEnumDType* nodep, AstNUser* vup) { + virtual void visit(AstEnumDType* nodep, AstNUser*) { if (nodep->didWidthAndSet()) return; // This node is a dtype & not both PRELIMed+FINALed UINFO(5," ENUMDTYPE "<childDTypep()) nodep->refDTypep(moveChildDTypeEdit(nodep)); @@ -1209,7 +1213,7 @@ private: nodep->dtypep(nodep); nodep->widthFromSub(nodep->subDTypep()); // Assign widths - nodep->itemsp()->iterateAndNext(*this,WidthVP(nodep->dtypep(),BOTH).p()); + userIterateAndNext(nodep->itemsp(), WidthVP(nodep->dtypep(),BOTH).p()); // Assign missing values V3Number num (nodep->fileline(), nodep->width(), 0); V3Number one (nodep->fileline(), nodep->width(), 1); @@ -1247,20 +1251,20 @@ private: num.opAdd(one, itemp->valuep()->castConst()->num()); } } - virtual void visit(AstEnumItem* nodep, AstNUser* vup) { + virtual void visit(AstEnumItem* nodep, AstNUser*) { UINFO(5," ENUMITEM "<c()->dtypep(); + AstNodeDType* vdtypep = m_vup->dtypep(); if (!vdtypep) nodep->v3fatalSrc("ENUMITEM not under ENUM"); nodep->dtypep(vdtypep); if (nodep->valuep()) { // else the value will be assigned sequentially // Default type is int, but common to assign narrower values, so minwidth from value - nodep->valuep()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p()); + userIterateAndNext(nodep->valuep(), WidthVP(CONTEXT,PRELIM).p()); int mwidth = nodep->valuep()->widthMin(); // Value determines minwidth nodep->dtypeChgWidth(nodep->width(), mwidth); iterateCheck(nodep,"Enum value",nodep->valuep(),CONTEXT,FINAL,nodep->dtypep(),EXTEND_EXP); } } - virtual void visit(AstEnumItemRef* nodep, AstNUser* vup) { + virtual void visit(AstEnumItemRef* nodep, AstNUser*) { if (!nodep->itemp()->didWidth()) { // We need to do the whole enum en-mass AstNode* enump = nodep->itemp(); @@ -1269,28 +1273,28 @@ private: if (enump->castEnumDType()) break; } if (!enump) nodep->v3fatalSrc("EnumItemRef can't deref back to an Enum"); - enump->iterate(*this,vup); VL_DANGLING(enump); // parent's connection to enump may be relinked + userIterate(enump, m_vup); VL_DANGLING(enump); // parent's connection to enump may be relinked } nodep->dtypeFrom(nodep->itemp()); } - virtual void visit(AstInitArray* nodep, AstNUser* vup) { + virtual void visit(AstInitArray* nodep, AstNUser*) { // InitArray has type of the array; children are array values - if (vup->c()->prelim()) { // First stage evaluation - AstNodeDType* vdtypep = vup->c()->dtypep(); + if (m_vup->prelim()) { // First stage evaluation + AstNodeDType* vdtypep = m_vup->dtypep(); if (!vdtypep) nodep->v3fatalSrc("InitArray type not assigned by AstPattern/Var visitor"); nodep->dtypep(vdtypep); if (AstNodeArrayDType* arrayp = vdtypep->castNodeArrayDType()) { - nodep->iterateChildren(*this,WidthVP(arrayp->subDTypep(),BOTH).p()); + userIterateChildren(nodep, WidthVP(arrayp->subDTypep(),BOTH).p()); } else { nodep->v3fatalSrc("InitArray on non-array"); } } } - virtual void visit(AstInside* nodep, AstNUser* vup) { - nodep->exprp()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p()); + virtual void visit(AstInside* nodep, AstNUser*) { + userIterateAndNext(nodep->exprp(), WidthVP(CONTEXT,PRELIM).p()); for (AstNode* nextip, *itemp = nodep->itemsp(); itemp; itemp=nextip) { nextip = itemp->nextp(); // Prelim may cause the node to get replaced - itemp->iterate(*this,WidthVP(CONTEXT,PRELIM).p()); VL_DANGLING(itemp); + userIterate(itemp, WidthVP(CONTEXT,PRELIM).p()); VL_DANGLING(itemp); } // Take width as maximum across all items int width = nodep->exprp()->width(); @@ -1333,29 +1337,29 @@ private: if (debug()>=9) newp->dumpTree(cout,"-inside-out: "); nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep); } - virtual void visit(AstInsideRange* nodep, AstNUser* vup) { + virtual void visit(AstInsideRange* nodep, AstNUser*) { // Just do each side; AstInside will rip these nodes out later - nodep->lhsp()->iterateAndNext(*this,vup); - nodep->rhsp()->iterateAndNext(*this,vup); + userIterateAndNext(nodep->lhsp(), m_vup); + userIterateAndNext(nodep->rhsp(), m_vup); nodep->dtypeFrom(nodep->lhsp()); } - virtual void visit(AstIfaceRefDType* nodep, AstNUser* vup) { + virtual void visit(AstIfaceRefDType* nodep, AstNUser*) { if (nodep->didWidthAndSet()) return; // This node is a dtype & not both PRELIMed+FINALed UINFO(5," IFACEREF "<iterateChildren(*this, vup); + userIterateChildren(nodep, m_vup); nodep->dtypep(nodep); nodep->widthForce(1, 1); // Not really relevant UINFO(4,"dtWidthed "<didWidthAndSet()) return; // This node is a dtype & not both PRELIMed+FINALed UINFO(5," NODECLASS "<=9) nodep->dumpTree("-class-in--"); if (!nodep->packed()) { nodep->v3warn(UNPACKED, "Unsupported: Unpacked struct/union"); } - nodep->iterateChildren(*this); // First size all members + userIterateChildren(nodep, NULL); // First size all members nodep->repairMemberCache(); // Determine bit assignments and width nodep->dtypep(nodep); @@ -1377,7 +1381,7 @@ private: nodep->widthForce(width,width); // Signing stays as-is, as parsed from declaration //if (debug()>=9) nodep->dumpTree("-class-out-"); } - virtual void visit(AstMemberDType* nodep, AstNUser* vup) { + virtual void visit(AstMemberDType* nodep, AstNUser*) { if (nodep->didWidthAndSet()) return; // This node is a dtype & not both PRELIMed+FINALed if (nodep->childDTypep()) nodep->refDTypep(moveChildDTypeEdit(nodep)); // Iterate into subDTypep() to resolve that type and update pointer. @@ -1385,10 +1389,10 @@ private: nodep->dtypep(nodep); // The member itself, not subDtype nodep->widthFromSub(nodep->subDTypep()); } - virtual void visit(AstMemberSel* nodep, AstNUser* vup) { + virtual void visit(AstMemberSel* nodep, AstNUser*) { UINFO(5," MEMBERSEL "<=9) nodep->dumpTree("-mbs-in: "); - nodep->iterateChildren(*this,WidthVP(SELF,BOTH).p()); + userIterateChildren(nodep, WidthVP(SELF,BOTH).p()); if (debug()>=9) nodep->dumpTree("-mbs-ic: "); // Find the fromp dtype - should be a class AstNodeDType* fromDtp = nodep->fromp()->dtypep()->skipRefToEnump(); @@ -1407,7 +1411,7 @@ private: AstNode* newp = new AstMethodSel(nodep->fileline(), nodep->fromp()->unlinkFrBack(), nodep->name(), NULL); nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep); - newp->iterate(*this,vup); + userIterate(newp, m_vup); return; } else { @@ -1437,13 +1441,13 @@ private: } } - virtual void visit(AstMethodSel* nodep, AstNUser* vup) { + virtual void visit(AstMethodSel* nodep, AstNUser*) { UINFO(5," METHODSEL "<=9) nodep->dumpTree("-mts-in: "); // Should check types the method requires, but at present we don't do much - nodep->fromp()->iterate(*this,WidthVP(SELF,BOTH).p()); + userIterate(nodep->fromp(), WidthVP(SELF,BOTH).p()); for (AstArg* argp = nodep->pinsp()->castArg(); argp; argp = argp->nextp()->castArg()) { - if (argp->exprp()) argp->exprp()->iterate(*this,WidthVP(SELF,BOTH).p()); + if (argp->exprp()) userIterate(argp->exprp(), WidthVP(SELF,BOTH).p()); } // Find the fromp dtype - should be a class if (!nodep->fromp() || !nodep->fromp()->dtypep()) nodep->v3fatalSrc("Unsized expression"); @@ -1531,12 +1535,12 @@ private: } } - virtual void visit(AstPattern* nodep, AstNUser* vup) { + virtual void visit(AstPattern* nodep, AstNUser*) { if (nodep->didWidthAndSet()) return; UINFO(9,"PATTERN "<childDTypep()) nodep->dtypep(moveChildDTypeEdit(nodep)); // data_type '{ pattern } - if (!nodep->dtypep() && vup->c()->dtypeNullp()) { // Get it from parent assignment/pin/etc - nodep->dtypep(vup->c()->dtypep()); + if (!nodep->dtypep() && m_vup->dtypeNullp()) { // Get it from parent assignment/pin/etc + nodep->dtypep(m_vup->dtypep()); } AstNodeDType* vdtypep = nodep->dtypep(); if (!vdtypep) nodep->v3error("Unsupported/Illegal: Assignment pattern member not underneath a supported construct: "<backp()->prettyTypeName()); @@ -1638,7 +1642,7 @@ private: // Determine initial values vdtypep = memp; patp->dtypep(memp); - patp->iterate(*this,WidthVP(memp,BOTH).p()); // See visit(AstPatMember* + userIterate(patp, WidthVP(memp,BOTH).p()); // See visit(AstPatMember* // Convert to concat for now AstNode* valuep = patp->lhssp()->unlinkFrBack(); @@ -1693,7 +1697,7 @@ private: // Don't want the RHS an array patp->dtypep(vdtypep); // Determine values - might be another InitArray - patp->iterate(*this,WidthVP(patp->dtypep(),BOTH).p()); // See visit(AstPatMember* + userIterate(patp, WidthVP(patp->dtypep(),BOTH).p()); // See visit(AstPatMember* // Convert to InitArray or constify immediately AstNode* valuep = patp->lhssp()->unlinkFrBack(); if (valuep->castConst()) { @@ -1761,7 +1765,7 @@ private: // Don't want the RHS an array patp->dtypep(vdtypep); // Determine values - might be another InitArray - patp->iterate(*this,WidthVP(patp->dtypep(),BOTH).p()); + userIterate(patp, WidthVP(patp->dtypep(),BOTH).p()); // Convert to InitArray or constify immediately AstNode* valuep = patp->lhssp()->unlinkFrBack(); if (valuep->castConst()) { @@ -1794,14 +1798,14 @@ private: } } } - virtual void visit(AstPatMember* nodep, AstNUser* vup) { - AstNodeDType* vdtypep = vup->c()->dtypeNullp(); + virtual void visit(AstPatMember* nodep, AstNUser*) { + AstNodeDType* vdtypep = m_vup->dtypeNullp(); if (!vdtypep) nodep->v3fatalSrc("Pattern member type not assigned by AstPattern visitor"); nodep->dtypep(vdtypep); UINFO(9," PATMEMBER "<lhssp()->nextp()) nodep->v3fatalSrc("PatMember value should be singular w/replicates removed"); // Need to propagate assignment type downwards, even on prelim - nodep->iterateChildren(*this,WidthVP(nodep->dtypep(),PRELIM).p()); + userIterateChildren(nodep, WidthVP(nodep->dtypep(),PRELIM).p()); iterateCheck(nodep,"Pattern value",nodep->lhssp(),ASSIGN,FINAL,vdtypep,EXTEND_LHS); } int visitPatMemberRep(AstPatMember* nodep) { @@ -1818,10 +1822,10 @@ private: return times; } - virtual void visit(AstPslClocked* nodep, AstNUser* vup) { - if (vup->c()->prelim()) { // First stage evaluation + virtual void visit(AstPslClocked* nodep, AstNUser*) { + if (m_vup->prelim()) { // First stage evaluation iterateCheckBool(nodep,"Property",nodep->propp(),BOTH); - nodep->sensesp()->iterateAndNext(*this); + userIterateAndNext(nodep->sensesp(), NULL); if (nodep->disablep()) { iterateCheckBool(nodep,"Disable",nodep->disablep(),BOTH); // it's like an if() condition. } @@ -1832,18 +1836,18 @@ private: //-------------------- // Top levels - virtual void visit(AstNodeCase* nodep, AstNUser* vup) { + virtual void visit(AstNodeCase* nodep, AstNUser*) { // IEEE-2012 12.5: // Width: MAX(expr, all items) // Signed: Only if expr, and all items signed - assertAtStatement(nodep,vup); - nodep->exprp()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p()); + assertAtStatement(nodep); + userIterateAndNext(nodep->exprp(), WidthVP(CONTEXT,PRELIM).p()); for (AstCaseItem* nextip, *itemp = nodep->itemsp(); itemp; itemp=nextip) { nextip = itemp->nextp()->castCaseItem(); // Prelim may cause the node to get replaced - if (!nodep->castGenCase()) itemp->bodysp()->iterateAndNext(*this); + if (!nodep->castGenCase()) userIterateAndNext(itemp->bodysp(), NULL); for (AstNode* nextcp, *condp = itemp->condsp(); condp; condp=nextcp) { nextcp = condp->nextp(); // Prelim may cause the node to get replaced - condp->iterate(*this,WidthVP(CONTEXT,PRELIM).p()); VL_DANGLING(condp); + userIterate(condp, WidthVP(CONTEXT,PRELIM).p()); VL_DANGLING(condp); } } @@ -1872,55 +1876,55 @@ private: } } } - virtual void visit(AstNodeFor* nodep, AstNUser* vup) { - assertAtStatement(nodep,vup); - nodep->initsp()->iterateAndNext(*this); + virtual void visit(AstNodeFor* nodep, AstNUser*) { + assertAtStatement(nodep); + userIterateAndNext(nodep->initsp(), NULL); iterateCheckBool(nodep,"For Test Condition",nodep->condp(),BOTH); // it's like an if() condition. - if (!nodep->castGenFor()) nodep->bodysp()->iterateAndNext(*this); - nodep->incsp()->iterateAndNext(*this); + if (!nodep->castGenFor()) userIterateAndNext(nodep->bodysp(), NULL); + userIterateAndNext(nodep->incsp(), NULL); } - virtual void visit(AstRepeat* nodep, AstNUser* vup) { - assertAtStatement(nodep,vup); - nodep->countp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); - nodep->bodysp()->iterateAndNext(*this); + virtual void visit(AstRepeat* nodep, AstNUser*) { + assertAtStatement(nodep); + userIterateAndNext(nodep->countp(), WidthVP(SELF,BOTH).p()); + userIterateAndNext(nodep->bodysp(), NULL); } - virtual void visit(AstWhile* nodep, AstNUser* vup) { - assertAtStatement(nodep,vup); - nodep->precondsp()->iterateAndNext(*this); + virtual void visit(AstWhile* nodep, AstNUser*) { + assertAtStatement(nodep); + userIterateAndNext(nodep->precondsp(), NULL); iterateCheckBool(nodep,"For Test Condition",nodep->condp(),BOTH); // it's like an if() condition. - nodep->bodysp()->iterateAndNext(*this); - nodep->incsp()->iterateAndNext(*this); + userIterateAndNext(nodep->bodysp(), NULL); + userIterateAndNext(nodep->incsp(), NULL); } - virtual void visit(AstNodeIf* nodep, AstNUser* vup) { - assertAtStatement(nodep,vup); + virtual void visit(AstNodeIf* nodep, AstNUser*) { + assertAtStatement(nodep); //if (debug()) nodep->dumpTree(cout," IfPre: "); if (!nodep->castGenIf()) { // for m_paramsOnly - nodep->ifsp()->iterateAndNext(*this); - nodep->elsesp()->iterateAndNext(*this); + userIterateAndNext(nodep->ifsp(), NULL); + userIterateAndNext(nodep->elsesp(), NULL); } iterateCheckBool(nodep,"If",nodep->condp(),BOTH); // it's like an if() condition. //if (debug()) nodep->dumpTree(cout," IfOut: "); } - virtual void visit(AstNodeAssign* nodep, AstNUser* vup) { + virtual void visit(AstNodeAssign* nodep, AstNUser*) { // IEEE-2012 10.7, 11.8.2, 11.8.3, 11.5: (Careful of 11.8.1 which is // only one step; final dtype depends on assign LHS.) // Determine RHS type width and signing // Propagate type down to *non-self-determined* operators // Real propagates only across one operator if one side is real - handled in each visitor. // Then LHS sign-extends only if *RHS* is signed - assertAtStatement(nodep,vup); + assertAtStatement(nodep); //if (debug()) nodep->dumpTree(cout," AssignPre: "); { //if (debug()) nodep->dumpTree(cout,"- assin: "); - nodep->lhsp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); + userIterateAndNext(nodep->lhsp(), WidthVP(SELF,BOTH).p()); if (!nodep->lhsp()->dtypep()) nodep->v3fatalSrc("How can LHS be untyped?"); if (!nodep->lhsp()->dtypep()->widthSized()) nodep->v3fatalSrc("How can LHS be unsized?"); nodep->dtypeFrom(nodep->lhsp()); // // AstPattern needs to know the proposed data type of the lhs, so pass on the prelim - nodep->rhsp()->iterateAndNext(*this,WidthVP(nodep->dtypep(),PRELIM).p()); + userIterateAndNext(nodep->rhsp(), WidthVP(nodep->dtypep(),PRELIM).p()); // //if (debug()) nodep->dumpTree(cout,"- assign: "); AstNodeDType* lhsDTypep = nodep->lhsp()->dtypep(); // Note we use rhsp for context determined @@ -1929,11 +1933,11 @@ private: } } - virtual void visit(AstSFormatF* nodep, AstNUser* vup) { + virtual void visit(AstSFormatF* nodep, AstNUser*) { // Excludes NodeDisplay, see below - if (vup && !vup->c()->prelim()) return; // Can be called as statement or function + if (m_vup && !m_vup->prelim()) return; // Can be called as statement or function // Just let all arguments seek their natural sizes - nodep->iterateChildren(*this,WidthVP(SELF,BOTH).p()); + userIterateChildren(nodep, WidthVP(SELF,BOTH).p()); // UINFO(9," Display in "<text()<text(newFormat); UINFO(9," Display out "<text()<filep()) { iterateCheckFileDesc(nodep,nodep->filep(),BOTH); } // Just let all arguments seek their natural sizes - nodep->iterateChildren(*this,WidthVP(SELF,BOTH).p()); + userIterateChildren(nodep, WidthVP(SELF,BOTH).p()); } - virtual void visit(AstFOpen* nodep, AstNUser* vup) { + virtual void visit(AstFOpen* nodep, AstNUser*) { // Although a system function in IEEE, here a statement which sets the file pointer (MCD) - assertAtStatement(nodep,vup); + assertAtStatement(nodep); iterateCheckFileDesc(nodep,nodep->filep(),BOTH); - nodep->filenamep()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); - nodep->modep()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); + userIterateAndNext(nodep->filenamep(), WidthVP(SELF,BOTH).p()); + userIterateAndNext(nodep->modep(), WidthVP(SELF,BOTH).p()); } - virtual void visit(AstFClose* nodep, AstNUser* vup) { - assertAtStatement(nodep,vup); + virtual void visit(AstFClose* nodep, AstNUser*) { + assertAtStatement(nodep); iterateCheckFileDesc(nodep,nodep->filep(),BOTH); } - virtual void visit(AstFEof* nodep, AstNUser* vup) { - if (vup->c()->prelim()) { + virtual void visit(AstFEof* nodep, AstNUser*) { + if (m_vup->prelim()) { iterateCheckFileDesc(nodep,nodep->filep(),BOTH); nodep->dtypeSetLogicSized(32,1,AstNumeric::SIGNED); // Spec says integer return } } - virtual void visit(AstFFlush* nodep, AstNUser* vup) { - assertAtStatement(nodep,vup); + virtual void visit(AstFFlush* nodep, AstNUser*) { + assertAtStatement(nodep); if (nodep->filep()) { iterateCheckFileDesc(nodep,nodep->filep(),BOTH); } } - virtual void visit(AstFGetC* nodep, AstNUser* vup) { - if (vup->c()->prelim()) { + virtual void visit(AstFGetC* nodep, AstNUser*) { + if (m_vup->prelim()) { iterateCheckFileDesc(nodep,nodep->filep(),BOTH); nodep->dtypeSetLogicSized(32,8,AstNumeric::SIGNED); // Spec says integer return } } - virtual void visit(AstFGetS* nodep, AstNUser* vup) { - if (vup->c()->prelim()) { + virtual void visit(AstFGetS* nodep, AstNUser*) { + if (m_vup->prelim()) { nodep->dtypeSetSigned32(); // Spec says integer return iterateCheckFileDesc(nodep,nodep->filep(),BOTH); - nodep->strgp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); + userIterateAndNext(nodep->strgp(), WidthVP(SELF,BOTH).p()); } } - virtual void visit(AstFScanF* nodep, AstNUser* vup) { - if (vup->c()->prelim()) { + virtual void visit(AstFScanF* nodep, AstNUser*) { + if (m_vup->prelim()) { nodep->dtypeSetSigned32(); // Spec says integer return iterateCheckFileDesc(nodep,nodep->filep(),BOTH); - nodep->exprsp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); + userIterateAndNext(nodep->exprsp(), WidthVP(SELF,BOTH).p()); } } - virtual void visit(AstSScanF* nodep, AstNUser* vup) { - if (vup->c()->prelim()) { + virtual void visit(AstSScanF* nodep, AstNUser*) { + if (m_vup->prelim()) { nodep->dtypeSetSigned32(); // Spec says integer return - nodep->fromp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); - nodep->exprsp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); + userIterateAndNext(nodep->fromp(), WidthVP(SELF,BOTH).p()); + userIterateAndNext(nodep->exprsp(), WidthVP(SELF,BOTH).p()); } } - virtual void visit(AstSysIgnore* nodep, AstNUser* vup) { - nodep->exprsp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); + virtual void visit(AstSysIgnore* nodep, AstNUser*) { + userIterateAndNext(nodep->exprsp(), WidthVP(SELF,BOTH).p()); } - virtual void visit(AstSystemF* nodep, AstNUser* vup) { - if (vup->c()->prelim()) { - nodep->lhsp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); + virtual void visit(AstSystemF* nodep, AstNUser*) { + if (m_vup->prelim()) { + userIterateAndNext(nodep->lhsp(), WidthVP(SELF,BOTH).p()); nodep->dtypeSetSigned32(); // Spec says integer return } } - virtual void visit(AstSystemT* nodep, AstNUser* vup) { - assertAtStatement(nodep,vup); - nodep->lhsp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); + virtual void visit(AstSystemT* nodep, AstNUser*) { + assertAtStatement(nodep); + userIterateAndNext(nodep->lhsp(), WidthVP(SELF,BOTH).p()); } - virtual void visit(AstReadMem* nodep, AstNUser* vup) { - assertAtStatement(nodep,vup); - nodep->filenamep()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); - nodep->memp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); + virtual void visit(AstReadMem* nodep, AstNUser*) { + assertAtStatement(nodep); + userIterateAndNext(nodep->filenamep(), WidthVP(SELF,BOTH).p()); + userIterateAndNext(nodep->memp(), WidthVP(SELF,BOTH).p()); if (!nodep->memp()->dtypep()->skipRefp()->castUnpackArrayDType()) { nodep->memp()->v3error("Unsupported: $readmem into other than unpacked array"); } - nodep->lsbp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); - nodep->msbp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); + userIterateAndNext(nodep->lsbp(), WidthVP(SELF,BOTH).p()); + userIterateAndNext(nodep->msbp(), WidthVP(SELF,BOTH).p()); } - virtual void visit(AstValuePlusArgs* nodep, AstNUser* vup) { - if (vup->c()->prelim()) { - nodep->exprsp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); + virtual void visit(AstValuePlusArgs* nodep, AstNUser*) { + if (m_vup->prelim()) { + userIterateAndNext(nodep->exprsp(), WidthVP(SELF,BOTH).p()); nodep->dtypeSetSigned32(); // Spec says integer return } } - virtual void visit(AstUCStmt* nodep, AstNUser* vup) { + virtual void visit(AstUCStmt* nodep, AstNUser*) { // Just let all arguments seek their natural sizes - assertAtStatement(nodep,vup); - nodep->iterateChildren(*this,WidthVP(SELF,BOTH).p()); + assertAtStatement(nodep); + userIterateChildren(nodep, WidthVP(SELF,BOTH).p()); } - virtual void visit(AstPslCover* nodep, AstNUser* vup) { - assertAtStatement(nodep,vup); + virtual void visit(AstPslCover* nodep, AstNUser*) { + assertAtStatement(nodep); iterateCheckBool(nodep,"Property",nodep->propp(),BOTH); // it's like an if() condition. - nodep->stmtsp()->iterateAndNext(*this); + userIterateAndNext(nodep->stmtsp(), NULL); } - virtual void visit(AstVAssert* nodep, AstNUser* vup) { - assertAtStatement(nodep,vup); + virtual void visit(AstVAssert* nodep, AstNUser*) { + assertAtStatement(nodep); iterateCheckBool(nodep,"Property",nodep->propp(),BOTH); // it's like an if() condition. - nodep->passsp()->iterateAndNext(*this); - nodep->failsp()->iterateAndNext(*this); + userIterateAndNext(nodep->passsp(), NULL); + userIterateAndNext(nodep->failsp(), NULL); } virtual void visit(AstPin* nodep, AstNUser*) { //if (debug()) nodep->dumpTree(cout,"- PinPre: "); // TOP LEVEL NODE if (nodep->modVarp() && nodep->modVarp()->isGParam()) { // Widthing handled as special init() case - nodep->iterateChildren(*this,WidthVP(SELF,BOTH).p()); + userIterateChildren(nodep, WidthVP(SELF,BOTH).p()); } else if (!m_paramsOnly) { if (!nodep->modVarp()->didWidth()) { // Var hasn't been widthed, so make it so. - nodep->modVarp()->iterate(*this); + userIterate(nodep->modVarp(), NULL); } if (!nodep->exprp()) { // No-connect return; } // Very much like like an assignment, but which side is LH/RHS // depends on pin being a in/output/inout. - nodep->exprp()->iterateAndNext(*this,WidthVP(nodep->modVarp()->dtypep(),PRELIM).p()); + userIterateAndNext(nodep->exprp(), WidthVP(nodep->modVarp()->dtypep(),PRELIM).p()); AstNodeDType* pinDTypep = nodep->modVarp()->dtypep(); AstNodeDType* conDTypep = nodep->exprp()->dtypep(); AstNodeDType* subDTypep = pinDTypep; int pinwidth = pinDTypep->width(); int conwidth = conDTypep->width(); if (conDTypep == pinDTypep) { // If match, we're golden - nodep->exprp()->iterateAndNext(*this,WidthVP(subDTypep,FINAL).p()); + userIterateAndNext(nodep->exprp(), WidthVP(subDTypep,FINAL).p()); } else if (m_cellRangep) { int numInsts = m_cellRangep->elementsConst(); @@ -2142,7 +2146,7 @@ private: <<" generates "<exprp()->iterateAndNext(*this,WidthVP(subDTypep,FINAL).p()); + userIterateAndNext(nodep->exprp(), WidthVP(subDTypep,FINAL).p()); } else { if (nodep->modVarp()->isTristate()) { if (pinwidth != conwidth) { @@ -2179,17 +2183,17 @@ private: } if (nodep->rangep()) { m_cellRangep = nodep->rangep(); - nodep->rangep()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); + userIterateAndNext(nodep->rangep(), WidthVP(SELF,BOTH).p()); } - nodep->pinsp()->iterateAndNext(*this); + userIterateAndNext(nodep->pinsp(), NULL); } - nodep->paramsp()->iterateAndNext(*this); + userIterateAndNext(nodep->paramsp(), NULL); m_cellRangep = NULL; } - virtual void visit(AstGatePin* nodep, AstNUser* vup) { - if (vup->c()->prelim()) { - nodep->rangep()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); - nodep->exprp()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p()); + virtual void visit(AstGatePin* nodep, AstNUser*) { + if (m_vup->prelim()) { + userIterateAndNext(nodep->rangep(), WidthVP(SELF,BOTH).p()); + userIterateAndNext(nodep->exprp(), WidthVP(CONTEXT,PRELIM).p()); nodep->dtypeFrom(nodep->rangep()); // Very much like like an pin AstNodeDType* conDTypep = nodep->exprp()->dtypep(); @@ -2198,7 +2202,7 @@ private: int conwidth = conDTypep->width(); if (conwidth == 1 && pinwidth > 1) { // Multiple connections AstNodeDType* subDTypep = nodep->findLogicDType(1,1, conDTypep->numeric()); - nodep->exprp()->iterateAndNext(*this,WidthVP(subDTypep,FINAL).p()); + userIterateAndNext(nodep->exprp(), WidthVP(subDTypep,FINAL).p()); AstNode* newp = new AstReplicate(nodep->fileline(), nodep->exprp()->unlinkFrBack(), numInsts); @@ -2206,13 +2210,13 @@ private: } else { // Eliminating so pass down all of vup - nodep->exprp()->iterateAndNext(*this,vup); + userIterateAndNext(nodep->exprp(), m_vup); nodep->replaceWith(nodep->exprp()->unlinkFrBack()); } pushDeletep(nodep); VL_DANGLING(nodep); } } - virtual void visit(AstNodeFTask* nodep, AstNUser* vup) { + virtual void visit(AstNodeFTask* nodep, AstNUser*) { // Grab width from the output variable (if it's a function) if (nodep->didWidth()) return; UINFO(5," FTASK "<doingWidth(true); // Would use user1 etc, but V3Width called from too many places to spend a user - nodep->iterateChildren(*this); + userIterateChildren(nodep, NULL); if (nodep->fvarp()) { m_funcp = nodep->castFunc(); if (!m_funcp) nodep->v3fatalSrc("FTask with function variable, but isn't a function"); @@ -2234,9 +2238,9 @@ private: nodep->doingWidth(false); m_funcp = NULL; } - virtual void visit(AstReturn* nodep, AstNUser* vup) { + virtual void visit(AstReturn* nodep, AstNUser*) { // IEEE: Assignment-like context - assertAtStatement(nodep,vup); + assertAtStatement(nodep); if (!m_funcp) { if (nodep->lhsp()) { // Return w/o value ok other places nodep->v3error("Return with return value isn't underneath a function"); @@ -2246,24 +2250,24 @@ private: // Function hasn't been widthed, so make it so. nodep->dtypeFrom(m_funcp->fvarp()); // AstPattern requires assignments to pass datatype on PRELIM - nodep->lhsp()->iterateAndNext(*this,WidthVP(nodep->dtypep(),PRELIM).p()); + userIterateAndNext(nodep->lhsp(), WidthVP(nodep->dtypep(),PRELIM).p()); iterateCheckAssign(nodep,"Return value",nodep->lhsp(),FINAL,nodep->dtypep()); } } } - virtual void visit(AstFuncRef* nodep, AstNUser* vup) { - visit(nodep->castNodeFTaskRef(), vup); + virtual void visit(AstFuncRef* nodep, AstNUser*) { + visit(nodep->castNodeFTaskRef(), NULL); nodep->dtypeFrom(nodep->taskp()); //if (debug()) nodep->dumpTree(cout," FuncOut: "); } - virtual void visit(AstNodeFTaskRef* nodep, AstNUser* vup) { + virtual void visit(AstNodeFTaskRef* nodep, AstNUser*) { // For arguments, is assignment-like context; see IEEE rules in AstNodeAssign // Function hasn't been widthed, so make it so. UINFO(5, " FTASKREF "<taskp()) nodep->v3fatalSrc("Unlinked"); if (nodep->didWidth()) return; - nodep->taskp()->iterate(*this); + userIterate(nodep->taskp(), NULL); // // And do the arguments to the task/function too for (int accept_mode=0; accept_mode<3; accept_mode++) { // Avoid duplicate code; just do inner stuff several times @@ -2311,7 +2315,7 @@ private: pinp = newp; } // AstPattern requires assignments to pass datatype on PRELIM - pinp->iterate(*this,WidthVP(portp->dtypep(),PRELIM).p()); VL_DANGLING(pinp); + userIterate(pinp, WidthVP(portp->dtypep(),PRELIM).p()); VL_DANGLING(pinp); } else if (accept_mode==1) { // Change data types based on above accept completion if (portp->isDouble()) { @@ -2319,7 +2323,7 @@ private: } } else if (accept_mode==2) { // Do PRELIM again, because above accept may have exited early due to node replacement - pinp->iterate(*this,WidthVP(portp->dtypep(),PRELIM).p()); + userIterate(pinp, WidthVP(portp->dtypep(),PRELIM).p()); if ((portp->isOutput() || portp->isInout()) && pinp->width() != portp->width()) { pinp->v3error("Unsupported: Function output argument '"<prettyName()<<"'" @@ -2330,7 +2334,7 @@ private: // (get an ASSIGN with EXTEND on the lhs instead of rhs) } if (!portp->basicp() || portp->basicp()->isOpaque()) { - pinp->iterate(*this,WidthVP(portp->dtypep(),FINAL).p()); + userIterate(pinp, WidthVP(portp->dtypep(),FINAL).p()); } else { iterateCheckAssign(nodep,"Function Argument",pinp,FINAL,portp->dtypep()); } @@ -2340,76 +2344,76 @@ private: } nodep->didWidth(true); } - virtual void visit(AstInitial* nodep, AstNUser* vup) { - assertAtStatement(nodep,vup); + virtual void visit(AstInitial* nodep, AstNUser*) { + assertAtStatement(nodep); m_initialp = nodep; - nodep->iterateChildren(*this); + userIterateChildren(nodep, NULL); m_initialp = NULL; } virtual void visit(AstNetlist* nodep, AstNUser*) { // Iterate modules backwards, in bottom-up order. That's faster - nodep->iterateChildrenBackwards(*this); + userIterateChildrenBackwards(nodep, NULL); } //-------------------- // Default virtual void visit(AstNodeMath* nodep, AstNUser*) { nodep->v3fatalSrc("Visit function missing? Widthed function missing for math node: "<iterateChildren(*this); + userIterateChildren(nodep, NULL); } - virtual void visit(AstNode* nodep, AstNUser* vup) { + virtual void visit(AstNode* nodep, AstNUser*) { // Default: Just iterate - if (vup) nodep->v3fatalSrc("Visit function missing? Widthed expectation for this node: "<iterateChildren(*this); + if (m_vup) nodep->v3fatalSrc("Visit function missing? Widthed expectation for this node: "<c()->prelim()) { // First stage evaluation + if (m_vup->prelim()) { // First stage evaluation nodep->dtypeSetDouble(); AstNodeDType* subDTypep = nodep->findLogicDType(64,64, AstNumeric::UNSIGNED); // Self-determined operand - nodep->lhsp()->iterateAndNext(*this,WidthVP(SELF,PRELIM).p()); + userIterateAndNext(nodep->lhsp(), WidthVP(SELF,PRELIM).p()); iterateCheck(nodep,"LHS",nodep->lhsp(),SELF,FINAL,subDTypep,EXTEND_EXP); } } - void visit_Or_Ls32(AstNodeUniop* nodep, AstNUser* vup) { + void visit_Or_Ls32(AstNodeUniop* nodep) { // CALLER: AstIToRD // Real: Output real // LHS presumed self-determined, then coerced to real - if (vup->c()->prelim()) { // First stage evaluation + if (m_vup->prelim()) { // First stage evaluation nodep->dtypeSetDouble(); AstNodeDType* subDTypep = nodep->findLogicDType(32,32, AstNumeric::SIGNED); // Self-determined operand - nodep->lhsp()->iterateAndNext(*this,WidthVP(SELF,PRELIM).p()); + userIterateAndNext(nodep->lhsp(), WidthVP(SELF,PRELIM).p()); iterateCheck(nodep,"LHS",nodep->lhsp(),SELF,FINAL,subDTypep,EXTEND_EXP); } } - void visit_Os32_Lr(AstNodeUniop* nodep, AstNUser* vup) { + void visit_Os32_Lr(AstNodeUniop* nodep) { // CALLER: RToI // Real: LHS real // LHS presumed self-determined, then coerced to real - if (vup->c()->prelim()) { // First stage evaluation + if (m_vup->prelim()) { // First stage evaluation iterateCheckReal(nodep,"LHS",nodep->lhsp(),BOTH); nodep->dtypeSetSigned32(); } } - void visit_Ou64_Lr(AstNodeUniop* nodep, AstNUser* vup) { + void visit_Ou64_Lr(AstNodeUniop* nodep) { // CALLER: RealToBits // Real: LHS real // LHS presumed self-determined, then coerced to real - if (vup->c()->prelim()) { // First stage evaluation + if (m_vup->prelim()) { // First stage evaluation iterateCheckReal(nodep,"LHS",nodep->lhsp(),BOTH); nodep->dtypeSetUInt64(); } } - void visit_log_not(AstNode* nodep, AstNUser* vup) { + void visit_log_not(AstNode* nodep) { // CALLER: LogNot // Width-check: lhs 1 bit // Real: Allowed; implicitly compares with zero @@ -2421,49 +2425,49 @@ private: // Width: 1 bit out // Sign: unsigned out (11.8.1) if (nodep->op2p()) nodep->v3fatalSrc("For unary ops only!"); - if (vup->c()->prelim()) { + if (m_vup->prelim()) { iterateCheckBool(nodep,"LHS",nodep->op1p(),BOTH); nodep->dtypeSetLogicBool(); } } - void visit_log_and_or(AstNodeBiop* nodep, AstNUser* vup) { + void visit_log_and_or(AstNodeBiop* nodep) { // CALLER: LogAnd, LogOr, LogIf, LogIff // Widths: 1 bit out, lhs 1 bit, rhs 1 bit // IEEE-2012 Table 11-21: // LHS is self-determined // RHS is self-determined - if (vup->c()->prelim()) { + if (m_vup->prelim()) { iterateCheckBool(nodep,"LHS",nodep->lhsp(),BOTH); iterateCheckBool(nodep,"RHS",nodep->rhsp(),BOTH); nodep->dtypeSetLogicBool(); } } - void visit_red_and_or(AstNodeUniop* nodep, AstNUser* vup) { + void visit_red_and_or(AstNodeUniop* nodep) { // CALLER: RedAnd, RedOr, ... // Signed: Output unsigned, Lhs/Rhs/etc non-real (presumed, not in IEEE) // IEEE-2012: Table 11-21 and 11.8.1: // LHS is self-determined // Width: 1 bit out // Sign: unsigned out (11.8.1) - if (vup->c()->prelim()) { + if (m_vup->prelim()) { iterateCheckSizedSelf(nodep,"LHS",nodep->lhsp(),SELF,BOTH); nodep->dtypeSetLogicBool(); } } - void visit_red_unknown(AstNodeUniop* nodep, AstNUser* vup) { + void visit_red_unknown(AstNodeUniop* nodep) { // CALLER: IsUnknown // Signed: Output unsigned, Lhs/Rhs/etc non-real (presumed, not in IEEE) // IEEE-2012: Table 11-21 and 11.8.1: // LHS is self-determined // Width: 1 bit out // Sign: unsigned out (11.8.1) - if (vup->c()->prelim()) { - nodep->lhsp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); + if (m_vup->prelim()) { + userIterateAndNext(nodep->lhsp(), WidthVP(SELF,BOTH).p()); nodep->dtypeSetLogicBool(); } } - void visit_cmp_eq_gt(AstNodeBiop* nodep, AstNUser* vup, bool realok) { + void visit_cmp_eq_gt(AstNodeBiop* nodep, bool realok) { // CALLER: AstEq, AstGt, ..., AstLtS // Real allowed if and only if real_lhs set // See IEEE-2012 11.4.4, and 11.8.1: @@ -2475,9 +2479,9 @@ private: // TODO: chandle/class handle/iface handle only allowed to self-compare or against null // TODO: chandle/class handle/iface handle no relational compares if (!nodep->rhsp()) nodep->v3fatalSrc("For binary ops only!"); - if (vup->c()->prelim()) { - nodep->lhsp()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p()); - nodep->rhsp()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p()); + if (m_vup->prelim()) { + userIterateAndNext(nodep->lhsp(), WidthVP(CONTEXT,PRELIM).p()); + userIterateAndNext(nodep->rhsp(), WidthVP(CONTEXT,PRELIM).p()); if (nodep->lhsp()->isDouble() || nodep->rhsp()->isDouble()) { if (!realok) nodep->v3error("Real not allowed as operand to in ?== operator"); if (AstNodeBiop* newp=replaceWithDVersion(nodep)) { VL_DANGLING(nodep); @@ -2506,27 +2510,27 @@ private: nodep->dtypeSetLogicBool(); } } - void visit_cmp_real(AstNodeBiop* nodep, AstNUser* vup) { + void visit_cmp_real(AstNodeBiop* nodep) { // CALLER: EqD, LtD // Widths: 1 bit out, lhs width == rhs width // Signed compare (not output) if both sides signed // Real if and only if real_allow set // IEEE, 11.4.4: relational compares (<,>,<=,>=,==,===,!=,!==) use "zero padding" on unsigned if (!nodep->rhsp()) nodep->v3fatalSrc("For binary ops only!"); - if (vup->c()->prelim()) { + if (m_vup->prelim()) { // See similar handling in visit_cmp_eq_gt where created iterateCheckReal(nodep,"LHS",nodep->lhsp(),BOTH); iterateCheckReal(nodep,"RHS",nodep->rhsp(),BOTH); nodep->dtypeSetLogicBool(); } } - void visit_cmp_string(AstNodeBiop* nodep, AstNUser* vup) { + void visit_cmp_string(AstNodeBiop* nodep) { // CALLER: EqN, LtN // Widths: 1 bit out, lhs width == rhs width // String compare (not output) // Real if and only if real_allow set if (!nodep->rhsp()) nodep->v3fatalSrc("For binary ops only!"); - if (vup->c()->prelim()) { + if (m_vup->prelim()) { // See similar handling in visit_cmp_eq_gt where created iterateCheckString(nodep,"LHS",nodep->lhsp(),BOTH); iterateCheckString(nodep,"RHS",nodep->rhsp(),BOTH); @@ -2534,15 +2538,15 @@ private: } } - void visit_negate_not(AstNodeUniop* nodep, AstNUser* vup, bool real_ok) { + void visit_negate_not(AstNodeUniop* nodep, bool real_ok) { // CALLER: (real_ok=false) Not // CALLER: (real_ok=true) Negate // Signed: From lhs // IEEE-2012 Table 11-21: // Widths: out width = lhs width if (nodep->op2p()) nodep->v3fatalSrc("For unary ops only!"); - if (vup->c()->prelim()) { - nodep->lhsp()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p()); + if (m_vup->prelim()) { + userIterateAndNext(nodep->lhsp(), WidthVP(CONTEXT,PRELIM).p()); if (!real_ok) checkCvtUS(nodep->lhsp()); } if (real_ok && nodep->lhsp()->isDouble()) { @@ -2557,18 +2561,18 @@ private: // Note there aren't yet uniops that need version changes // So no need to call replaceWithUOrSVersion(nodep, nodep->isSigned()) } - if (vup->c()->prelim()) { + if (m_vup->prelim()) { nodep->dtypeFrom(nodep->lhsp()); } - if (vup->c()->final()) { - AstNodeDType* expDTypep = vup->c()->dtypeOverridep(nodep->dtypep()); + if (m_vup->final()) { + AstNodeDType* expDTypep = m_vup->dtypeOverridep(nodep->dtypep()); nodep->dtypep(expDTypep); // Propagate expression type to negation AstNodeDType* subDTypep = expDTypep; iterateCheck(nodep,"LHS",nodep->lhsp(),CONTEXT,FINAL,subDTypep,EXTEND_EXP); } } - void visit_signed_unsigned(AstNodeUniop* nodep, AstNUser* vup, AstNumeric rs_out) { + void visit_signed_unsigned(AstNodeUniop* nodep, AstNumeric rs_out) { // CALLER: Signed, Unsigned // Width: lhs is self determined width // See IEEE-2012 6.24.1: @@ -2576,8 +2580,8 @@ private: // Sign: Output sign is as specified by operation // TODO: Type: Two-state if input is two-state, else four-state if (nodep->op2p()) nodep->v3fatalSrc("For unary ops only!"); - if (vup->c()->prelim()) { - nodep->lhsp()->iterateAndNext(*this,WidthVP(SELF,PRELIM).p()); + if (m_vup->prelim()) { + userIterateAndNext(nodep->lhsp(), WidthVP(SELF,PRELIM).p()); checkCvtUS(nodep->lhsp()); int width = nodep->lhsp()->width(); AstNodeDType* expDTypep = nodep->findLogicDType(width,width,rs_out); @@ -2588,32 +2592,32 @@ private: } } - void visit_shift(AstNodeBiop* nodep, AstNUser* vup) { + void visit_shift(AstNodeBiop* nodep) { // CALLER: ShiftL, ShiftR, ShiftRS // Widths: Output width from lhs, rhs<33 bits // Signed: Output signed iff LHS signed; unary operator // See IEEE 2012 11.4.10: // RHS is self-determined. RHS is always treated as unsigned, has no effect on result. - iterate_shift_prelim(nodep,vup); + iterate_shift_prelim(nodep); nodep->dtypeChgSigned(nodep->lhsp()->isSigned()); - AstNodeBiop* newp = iterate_shift_final(nodep,vup); VL_DANGLING(nodep); + AstNodeBiop* newp = iterate_shift_final(nodep); VL_DANGLING(nodep); if (newp) {} // Ununused } - void iterate_shift_prelim(AstNodeBiop* nodep, AstNUser* vup) { + void iterate_shift_prelim(AstNodeBiop* nodep) { // Shifts // See IEEE-2012 11.4.10 and Table 11-21. // RHS is self-determined. RHS is always treated as unsigned, has no effect on result. - if (vup->c()->prelim()) { - nodep->lhsp()->iterateAndNext(*this,WidthVP(SELF,PRELIM).p()); + if (m_vup->prelim()) { + userIterateAndNext(nodep->lhsp(), WidthVP(SELF,PRELIM).p()); checkCvtUS(nodep->lhsp()); iterateCheckSizedSelf(nodep,"RHS",nodep->rhsp(),SELF,BOTH); nodep->dtypeFrom(nodep->lhsp()); } } - AstNodeBiop* iterate_shift_final(AstNodeBiop* nodep, AstNUser* vup) { + AstNodeBiop* iterate_shift_final(AstNodeBiop* nodep) { // Nodep maybe edited - if (vup->c()->final()) { - AstNodeDType* expDTypep = vup->c()->dtypeOverridep(nodep->dtypep()); + if (m_vup->final()) { + AstNodeDType* expDTypep = m_vup->dtypeOverridep(nodep->dtypep()); AstNodeDType* subDTypep = expDTypep; nodep->dtypeFrom(expDTypep); // ShiftRS converts to ShiftR, but not vice-versa @@ -2640,7 +2644,7 @@ private: return nodep; // May edit } - void visit_boolmath_and_or(AstNodeBiop* nodep, AstNUser* vup) { + void visit_boolmath_and_or(AstNodeBiop* nodep) { // CALLER: And, Or, Xor, ... // Lint widths: out width = lhs width = rhs width // Signed: if lhs & rhs signed @@ -2650,10 +2654,10 @@ private: // If errors are off, we need to follow the spec; thus we really need to do the max() // because the rhs could be larger, and we need to have proper editing to get the widths // to be the same for our operations. - if (vup->c()->prelim()) { // First stage evaluation + if (m_vup->prelim()) { // First stage evaluation // Determine expression widths only relying on what's in the subops - nodep->lhsp()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p()); - nodep->rhsp()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p()); + userIterateAndNext(nodep->lhsp(), WidthVP(CONTEXT,PRELIM).p()); + userIterateAndNext(nodep->rhsp(), WidthVP(CONTEXT,PRELIM).p()); checkCvtUS(nodep->lhsp()); checkCvtUS(nodep->rhsp()); int width = max(nodep->lhsp()->width(), nodep->rhsp()->width()); @@ -2661,8 +2665,8 @@ private: bool expSigned = (nodep->lhsp()->isSigned() && nodep->rhsp()->isSigned()); nodep->dtypeChgWidthSigned(width,mwidth,AstNumeric::fromBool(expSigned)); } - if (vup->c()->final()) { - AstNodeDType* expDTypep = vup->c()->dtypeOverridep(nodep->dtypep()); + if (m_vup->final()) { + AstNodeDType* expDTypep = m_vup->dtypeOverridep(nodep->dtypep()); AstNodeDType* subDTypep = expDTypep; nodep->dtypeFrom(expDTypep); // Error report and change sizes for suboperands of this node. @@ -2671,7 +2675,7 @@ private: } } - void visit_add_sub_replace(AstNodeBiop* nodep, AstNUser* vup, bool real_ok) { + void visit_add_sub_replace(AstNodeBiop* nodep, bool real_ok) { // CALLER: (real_ok=false) AddS, SubS, ... // CALLER: (real_ok=true) Add, Sub, ... // Widths: out width = lhs width = rhs width @@ -2683,11 +2687,11 @@ private: // because the rhs could be larger, and we need to have proper editing to get the widths // to be the same for our operations. // - //if (debug()>=9) { UINFO(0,"-rus "<c()<dumpTree(cout,"-rusin-"); } - if (vup->c()->prelim()) { // First stage evaluation + //if (debug()>=9) { UINFO(0,"-rus "<dumpTree(cout,"-rusin-"); } + if (m_vup->prelim()) { // First stage evaluation // Determine expression widths only relying on what's in the subops - nodep->lhsp()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p()); - nodep->rhsp()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p()); + userIterateAndNext(nodep->lhsp(), WidthVP(CONTEXT,PRELIM).p()); + userIterateAndNext(nodep->rhsp(), WidthVP(CONTEXT,PRELIM).p()); if (!real_ok) { checkCvtUS(nodep->lhsp()); checkCvtUS(nodep->rhsp()); @@ -2709,9 +2713,9 @@ private: nodep->dtypeChgWidthSigned(width,mwidth,AstNumeric::fromBool(expSigned)); } } - if (vup->c()->final()) { + if (m_vup->final()) { // Parent's data type was computed using the max(upper, nodep->dtype) - AstNodeDType* expDTypep = vup->c()->dtypeOverridep(nodep->dtypep()); + AstNodeDType* expDTypep = m_vup->dtypeOverridep(nodep->dtypep()); AstNodeDType* subDTypep = expDTypep; nodep->dtypeFrom(expDTypep); if (AstNodeBiop* newp=replaceWithUOrSVersion(nodep, expDTypep->isSigned())) { VL_DANGLING(nodep); @@ -2733,18 +2737,18 @@ private: } //if (debug()>=9) nodep->dumpTree(cout,"-rusou-"); } - void visit_real_add_sub(AstNodeBiop* nodep, AstNUser* vup) { + void visit_real_add_sub(AstNodeBiop* nodep) { // CALLER: AddD, MulD, ... - if (vup->c()->prelim()) { // First stage evaluation + if (m_vup->prelim()) { // First stage evaluation // Note similar steps in visit_add_sub_replace promotion to double iterateCheckReal(nodep,"LHS",nodep->lhsp(),BOTH); iterateCheckReal(nodep,"RHS",nodep->rhsp(),BOTH); nodep->dtypeSetDouble(); } } - void visit_real_neg_ceil(AstNodeUniop* nodep, AstNUser* vup) { + void visit_real_neg_ceil(AstNodeUniop* nodep) { // CALLER: Negate, Ceil, Log, ... - if (vup->c()->prelim()) { // First stage evaluation + if (m_vup->prelim()) { // First stage evaluation // See alsl visit_negate_not conversion iterateCheckReal(nodep,"LHS",nodep->lhsp(),BOTH); nodep->dtypeSetDouble(); @@ -2878,7 +2882,7 @@ private: void iterateCheckFileDesc (AstNode* nodep, AstNode* underp, Stage stage) { if (stage != BOTH) nodep->v3fatalSrc("Bad call"); // underp may change as a result of replacement - underp = underp->iterateSubtreeReturnEdits(*this,WidthVP(SELF,PRELIM).p()); + underp = userIterateSubtreeReturnEdits(underp, WidthVP(SELF,PRELIM).p()); AstNodeDType* expDTypep = underp->findUInt32DType(); underp = iterateCheck(nodep,"file_descriptor",underp,SELF,FINAL,expDTypep,EXTEND_EXP); if (underp) {} // cppcheck @@ -2891,7 +2895,7 @@ private: // otherwise self-determined was correct // underp may change as a result of replacement if (stage & PRELIM) { - underp = underp->iterateSubtreeReturnEdits(*this,WidthVP(SELF,PRELIM).p()); + underp = userIterateSubtreeReturnEdits(underp, WidthVP(SELF,PRELIM).p()); } if (stage & FINAL) { AstNodeDType* expDTypep = nodep->findDoubleDType(); @@ -2901,7 +2905,7 @@ private: } void iterateCheckString (AstNode* nodep, const char* side, AstNode* underp, Stage stage) { if (stage & PRELIM) { - underp = underp->iterateSubtreeReturnEdits(*this,WidthVP(SELF,PRELIM).p()); + underp = userIterateSubtreeReturnEdits(underp, WidthVP(SELF,PRELIM).p()); } if (stage & FINAL) { AstNodeDType* expDTypep = nodep->findStringDType(); @@ -2916,7 +2920,7 @@ private: if (determ != SELF) nodep->v3fatalSrc("Bad call"); if (stage != FINAL && stage != BOTH) nodep->v3fatalSrc("Bad call"); // underp may change as a result of replacement - if (stage & PRELIM) underp = underp->iterateSubtreeReturnEdits(*this,WidthVP(SELF,PRELIM).p()); + if (stage & PRELIM) underp = userIterateSubtreeReturnEdits(underp, WidthVP(SELF,PRELIM).p()); underp = checkCvtUS(underp); AstNodeDType* expDTypep = underp->dtypep(); underp = iterateCheck(nodep,side,underp,SELF,FINAL,expDTypep,EXTEND_EXP); @@ -2941,7 +2945,7 @@ private: // stage is always BOTH so not passed as argument // underp may change as a result of replacement if (!underp) underp->v3fatalSrc("Node has no type"); - underp = underp->iterateSubtreeReturnEdits(*this,WidthVP(SELF,BOTH).p()); + underp = userIterateSubtreeReturnEdits(underp, WidthVP(SELF,BOTH).p()); if (!underp || !underp->dtypep()) underp->v3fatalSrc("Node has no type"); // Perhaps forgot to do a prelim visit on it? // // For DOUBLE under a logical op, add implied test against zero, never a warning @@ -2985,18 +2989,18 @@ private: if (stage != FINAL) nodep->v3fatalSrc("Bad state to iterateCheck"); if (!underp || !underp->dtypep()) underp->v3fatalSrc("Node has no type"); // Perhaps forgot to do a prelim visit on it? if (expDTypep == underp->dtypep()) { // Perfect - underp = underp->iterateSubtreeReturnEdits(*this,WidthVP(SELF,FINAL).p()); + underp = userIterateSubtreeReturnEdits(underp, WidthVP(SELF,FINAL).p()); } else if (expDTypep->isDouble() && underp->isDouble()) { // Also good - underp = underp->iterateSubtreeReturnEdits(*this,WidthVP(SELF,FINAL).p()); + underp = userIterateSubtreeReturnEdits(underp, WidthVP(SELF,FINAL).p()); } else if (expDTypep->isDouble() && !underp->isDouble()) { underp = spliceCvtD(underp); - underp = underp->iterateSubtreeReturnEdits(*this,WidthVP(SELF,FINAL).p()); + underp = userIterateSubtreeReturnEdits(underp, WidthVP(SELF,FINAL).p()); } else if (!expDTypep->isDouble() && underp->isDouble()) { underp = spliceCvtS(underp, true); // Round RHS - underp = underp->iterateSubtreeReturnEdits(*this,WidthVP(SELF,FINAL).p()); + underp = userIterateSubtreeReturnEdits(underp, WidthVP(SELF,FINAL).p()); } else if (expDTypep->isString() && !underp->dtypep()->isString()) { underp = spliceCvtString(underp); - underp = underp->iterateSubtreeReturnEdits(*this,WidthVP(SELF,FINAL).p()); + underp = userIterateSubtreeReturnEdits(underp, WidthVP(SELF,FINAL).p()); } else { AstBasicDType* expBasicp = expDTypep->basicp(); AstBasicDType* underBasicp = underp->dtypep()->basicp(); @@ -3006,7 +3010,7 @@ private: // is e.g. an ADD, the ADD will auto-adjust to the proper data type // or if another operation e.g. ATOI will not. if (determ == SELF) { - underp = underp->iterateSubtreeReturnEdits(*this,WidthVP(SELF,FINAL).p()); + underp = userIterateSubtreeReturnEdits(underp, WidthVP(SELF,FINAL).p()); } else if (determ == ASSIGN) { // IEEE: Signedness is solely determined by the RHS (underp), not by the LHS (expDTypep) if (underp->isSigned() != subDTypep->isSigned() @@ -3016,9 +3020,9 @@ private: AstNumeric::fromBool(underp->isSigned())); UINFO(9,"Assignment of opposite-signed RHS to LHS: "<iterateSubtreeReturnEdits(*this,WidthVP(subDTypep,FINAL).p()); + underp = userIterateSubtreeReturnEdits(underp, WidthVP(subDTypep,FINAL).p()); } else { - underp = underp->iterateSubtreeReturnEdits(*this,WidthVP(subDTypep,FINAL).p()); + underp = userIterateSubtreeReturnEdits(underp, WidthVP(subDTypep,FINAL).p()); } // Note the check uses the expected size, not the child's subDTypep as we want the // child node's width to end up correct for the assignment (etc) @@ -3311,7 +3315,7 @@ private: // or have a call outside of normal visitor land. // or have a m_return type (but need to return if width called multiple times) if (!nodep) parentp->v3fatalSrc("Null dtype when widthing dtype"); - nodep->iterate(*this); + userIterate(nodep, NULL); return nodep; } @@ -3414,7 +3418,7 @@ private: for (unsigned i=1; iaddValuep(dimensionValue(nodep, attrType, i)); } - varp->iterate(*this); // May have already done $unit so must do this var + userIterate(varp, NULL); // May have already done $unit so must do this var m_tableMap.insert(make_pair(make_pair(nodep,attrType), varp)); return varp; } @@ -3489,7 +3493,7 @@ private: AstNode* valp = values[i]; if (valp) initp->addIndexValuep(i, valp); } - varp->iterate(*this); // May have already done $unit so must do this var + userIterate(varp, NULL); // May have already done $unit so must do this var m_tableMap.insert(make_pair(make_pair(nodep,attrType), varp)); return varp; } @@ -3519,9 +3523,9 @@ private: //---------------------------------------------------------------------- // METHODS - special type detection - void assertAtStatement(AstNode* nodep, AstNUser* vup) { - if (VL_UNLIKELY(vup && !vup->c()->selfDtm())) { - UINFO(1,"-: "<c()<selfDtm())) { + UINFO(1,"-: "<v3fatalSrc("No dtype expected at statement "<prettyTypeName()); } } @@ -3535,6 +3539,58 @@ private: } } + //---------------------------------------------------------------------- + // METHODS - special iterators + // These functions save/restore the AstNUser information so it can pass to child nodes. + + AstNode* userIterateSubtreeReturnEdits(AstNode* nodep, WidthVP* vup) { + if (!nodep) return NULL; + WidthVP* saveVup = m_vup; + AstNode* ret; + { + m_vup = vup; + ret = nodep->iterateSubtreeReturnEdits(*this); + } + m_vup = saveVup; + return ret; + } + void userIterate(AstNode* nodep, WidthVP* vup) { + if (!nodep) return; + WidthVP* saveVup = m_vup; + { + m_vup = vup; + nodep->iterate(*this); + } + m_vup = saveVup; + } + void userIterateAndNext(AstNode* nodep, WidthVP* vup) { + if (!nodep) return; + WidthVP* saveVup = m_vup; + { + m_vup = vup; + nodep->iterateAndNext(*this); + } + m_vup = saveVup; + } + void userIterateChildren(AstNode* nodep, WidthVP* vup) { + if (!nodep) return; + WidthVP* saveVup = m_vup; + { + m_vup = vup; + nodep->iterateChildren(*this); + } + m_vup = saveVup; + } + void userIterateChildrenBackwards(AstNode* nodep, WidthVP* vup) { + if (!nodep) return; + WidthVP* saveVup = m_vup; + { + m_vup = vup; + nodep->iterateChildrenBackwards(*this); + } + m_vup = saveVup; + } + public: // CONSTUCTORS WidthVisitor(bool paramsOnly, // [in] TRUE if we are considering parameters only. @@ -3547,9 +3603,10 @@ public: m_attrp = NULL; m_doGenerate = doGenerate; m_dtTables = 0; + m_vup = NULL; } AstNode* mainAcceptEdit(AstNode* nodep) { - return nodep->iterateSubtreeReturnEdits(*this, WidthVP(SELF,BOTH).p()); + return userIterateSubtreeReturnEdits(nodep, WidthVP(SELF,BOTH).p()); } virtual ~WidthVisitor() {} };