Index: include/clang/AST/Expr.h =================================================================== --- include/clang/AST/Expr.h +++ include/clang/AST/Expr.h @@ -908,6 +908,10 @@ return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + /// The source expression of an opaque value expression is the /// expression which originally generated the value. This is /// provided as a convenience for analyses that don't wish to @@ -1168,6 +1172,10 @@ return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + friend TrailingObjects; friend class ASTStmtReader; friend class ASTStmtWriter; @@ -1223,6 +1231,9 @@ // Iterators child_range children() { return child_range(&FnName, &FnName + 1); } + const_child_range children() const { + return const_child_range(&FnName, &FnName + 1); + } friend class ASTStmtReader; }; @@ -1316,6 +1327,9 @@ child_range children() { return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } }; class CharacterLiteral : public Expr { @@ -1366,6 +1380,9 @@ child_range children() { return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } }; class FloatingLiteral : public Expr, private APFloatStorage { @@ -1430,6 +1447,9 @@ child_range children() { return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } }; /// ImaginaryLiteral - We support imaginary integer and floating point literals, @@ -1462,6 +1482,9 @@ // Iterators child_range children() { return child_range(&Val, &Val+1); } + const_child_range children() const { + return const_child_range(&Val, &Val + 1); + } }; /// StringLiteral - This represents a string literal expression, e.g. "foo" @@ -1629,6 +1652,9 @@ child_range children() { return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } }; /// ParenExpr - This represents a parethesized expression, e.g. "(1)". This @@ -1670,6 +1696,9 @@ // Iterators child_range children() { return child_range(&Val, &Val+1); } + const_child_range children() const { + return const_child_range(&Val, &Val + 1); + } }; /// UnaryOperator - This represents the unary-expression's (except sizeof and @@ -1779,6 +1808,9 @@ // Iterators child_range children() { return child_range(&Val, &Val+1); } + const_child_range children() const { + return const_child_range(&Val, &Val + 1); + } }; /// Helper class for OffsetOfExpr. @@ -1982,6 +2014,11 @@ Stmt **begin = reinterpret_cast(getTrailingObjects()); return child_range(begin, begin + NumExprs); } + const_child_range children() const { + Stmt *const *begin = + reinterpret_cast(getTrailingObjects()); + return const_child_range(begin, begin + NumExprs); + } friend TrailingObjects; }; @@ -2070,6 +2107,7 @@ // Iterators child_range children(); + const_child_range children() const; }; //===----------------------------------------------------------------------===// @@ -2154,6 +2192,9 @@ child_range children() { return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR); } + const_child_range children() const { + return const_child_range(&SubExprs[0], &SubExprs[0] + END_EXPR); + } }; /// CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]). @@ -2314,6 +2355,11 @@ return child_range(&SubExprs[0], &SubExprs[0]+NumArgs+getNumPreArgs()+PREARGS_START); } + + const_child_range children() const { + return const_child_range(&SubExprs[0], &SubExprs[0] + NumArgs + + getNumPreArgs() + PREARGS_START); + } }; /// Extra data stored in some MemberExpr objects. @@ -2568,6 +2614,9 @@ // Iterators child_range children() { return child_range(&Base, &Base+1); } + const_child_range children() const { + return const_child_range(&Base, &Base + 1); + } friend TrailingObjects; friend class ASTReader; @@ -2640,6 +2689,9 @@ // Iterators child_range children() { return child_range(&Init, &Init+1); } + const_child_range children() const { + return const_child_range(&Init, &Init + 1); + } }; /// CastExpr - Base class for type casts, including both implicit @@ -2726,6 +2778,7 @@ // Iterators child_range children() { return child_range(&Op, &Op+1); } + const_child_range children() const { return const_child_range(&Op, &Op + 1); } }; /// ImplicitCastExpr - Allows us to explicitly represent implicit type @@ -3069,6 +3122,9 @@ child_range children() { return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR); } + const_child_range children() const { + return const_child_range(&SubExprs[0], &SubExprs[0] + END_EXPR); + } // Set the FP contractability status of this operator. Only meaningful for // operations on floating point types. @@ -3249,6 +3305,9 @@ child_range children() { return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR); } + const_child_range children() const { + return const_child_range(&SubExprs[0], &SubExprs[0] + END_EXPR); + } }; /// BinaryConditionalOperator - The GNU extension to the conditional @@ -3334,6 +3393,9 @@ child_range children() { return child_range(SubExprs, SubExprs + NUM_SUBEXPRS); } + const_child_range children() const { + return const_child_range(SubExprs, SubExprs + NUM_SUBEXPRS); + } }; inline Expr *AbstractConditionalOperator::getCond() const { @@ -3388,6 +3450,9 @@ child_range children() { return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } }; /// StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}). @@ -3430,6 +3495,9 @@ // Iterators child_range children() { return child_range(&SubStmt, &SubStmt+1); } + const_child_range children() const { + return const_child_range(&SubStmt, &SubStmt + 1); + } }; /// ShuffleVectorExpr - clang-specific builtin-in function @@ -3498,6 +3566,9 @@ child_range children() { return child_range(&SubExprs[0], &SubExprs[0]+NumExprs); } + const_child_range children() const { + return const_child_range(&SubExprs[0], &SubExprs[0] + NumExprs); + } }; /// ConvertVectorExpr - Clang builtin function __builtin_convertvector @@ -3552,6 +3623,9 @@ // Iterators child_range children() { return child_range(&SrcExpr, &SrcExpr+1); } + const_child_range children() const { + return const_child_range(&SrcExpr, &SrcExpr + 1); + } }; /// ChooseExpr - GNU builtin-in function __builtin_choose_expr. @@ -3632,6 +3706,9 @@ child_range children() { return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR); } + const_child_range children() const { + return const_child_range(&SubExprs[0], &SubExprs[0] + END_EXPR); + } }; /// GNUNullExpr - Implements the GNU __null extension, which is a name @@ -3668,6 +3745,9 @@ child_range children() { return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } }; /// Represents a call to the builtin function \c __builtin_va_arg. @@ -3715,6 +3795,9 @@ // Iterators child_range children() { return child_range(&Val, &Val+1); } + const_child_range children() const { + return const_child_range(&Val, &Val + 1); + } }; /// @brief Describes an C or C++ initializer list. @@ -3939,10 +4022,16 @@ // Iterators child_range children() { + const_child_range CCR = const_cast(this)->children(); + return child_range(cast_away_const(CCR.begin()), + cast_away_const(CCR.end())); + } + + const_child_range children() const { // FIXME: This does not include the array filler expression. if (InitExprs.empty()) - return child_range(child_iterator(), child_iterator()); - return child_range(&InitExprs[0], &InitExprs[0] + InitExprs.size()); + return const_child_range(const_child_iterator(), const_child_iterator()); + return const_child_range(&InitExprs[0], &InitExprs[0] + InitExprs.size()); } typedef InitExprsTy::iterator iterator; @@ -4257,6 +4346,10 @@ Stmt **begin = getTrailingObjects(); return child_range(begin, begin + NumSubExprs); } + const_child_range children() const { + Stmt * const *begin = getTrailingObjects(); + return const_child_range(begin, begin + NumSubExprs); + } friend TrailingObjects; }; @@ -4290,6 +4383,9 @@ child_range children() { return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } }; // In cases like: @@ -4335,6 +4431,10 @@ child_range children() { return child_range(&BaseAndUpdaterExprs[0], &BaseAndUpdaterExprs[0] + 2); } + const_child_range children() const { + return const_child_range(&BaseAndUpdaterExprs[0], + &BaseAndUpdaterExprs[0] + 2); + } }; /// \brief Represents a loop initializing the elements of an array. @@ -4396,6 +4496,9 @@ child_range children() { return child_range(SubExprs, SubExprs + 2); } + const_child_range children() const { + return const_child_range(SubExprs, SubExprs + 2); + } friend class ASTReader; friend class ASTStmtReader; @@ -4424,6 +4527,9 @@ child_range children() { return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } friend class ASTReader; friend class ASTStmtReader; @@ -4458,6 +4564,9 @@ child_range children() { return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } }; class ParenListExpr : public Expr { @@ -4504,6 +4613,9 @@ child_range children() { return child_range(&Exprs[0], &Exprs[0]+NumExprs); } + const_child_range children() const { + return const_child_range(&Exprs[0], &Exprs[0] + NumExprs); + } friend class ASTStmtReader; friend class ASTStmtWriter; @@ -4624,7 +4736,9 @@ child_range children() { return child_range(SubExprs, SubExprs+END_EXPR+NumAssocs); } - + const_child_range children() const { + return const_child_range(SubExprs, SubExprs + END_EXPR + NumAssocs); + } friend class ASTStmtReader; }; @@ -4693,6 +4807,9 @@ // Iterators child_range children() { return child_range(&Base, &Base+1); } + const_child_range children() const { + return const_child_range(&Base, &Base + 1); + } }; /// BlockExpr - Adaptor class for mixing a BlockDecl with expressions. @@ -4734,6 +4851,9 @@ child_range children() { return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } }; /// AsTypeExpr - Clang builtin function __builtin_astype [OpenCL 6.2.4.2] @@ -4779,6 +4899,9 @@ // Iterators child_range children() { return child_range(&SrcExpr, &SrcExpr+1); } + const_child_range children() const { + return const_child_range(&SrcExpr, &SrcExpr + 1); + } }; /// PseudoObjectExpr - An expression which accesses a pseudo-object @@ -4917,9 +5040,16 @@ } child_range children() { - Stmt **cs = reinterpret_cast(getSubExprsBuffer()); - return child_range(cs, cs + getNumSubExprs()); + const_child_range CCR = + const_cast(this)->children(); + return child_range(cast_away_const(CCR.begin()), + cast_away_const(CCR.end())); } + const_child_range children() const { + Stmt *const *cs = const_cast( + reinterpret_cast(getSubExprsBuffer())); + return const_child_range(cs, cs + getNumSubExprs()); + } static bool classof(const Stmt *T) { return T->getStmtClass() == PseudoObjectExprClass; @@ -5024,6 +5154,9 @@ child_range children() { return child_range(SubExprs, SubExprs+NumSubExprs); } + const_child_range children() const { + return const_child_range(SubExprs, SubExprs + NumSubExprs); + } }; /// TypoExpr - Internal placeholder for expressions where typo correction @@ -5042,6 +5175,10 @@ child_range children() { return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + SourceLocation getLocStart() const LLVM_READONLY { return SourceLocation(); } SourceLocation getLocEnd() const LLVM_READONLY { return SourceLocation(); } Index: include/clang/AST/StmtIterator.h =================================================================== --- include/clang/AST/StmtIterator.h +++ include/clang/AST/StmtIterator.h @@ -128,6 +128,13 @@ StmtIterator(const VariableArrayType *t) : StmtIteratorImpl(t) {} + +private: + StmtIterator(const StmtIteratorBase &RHS) + : StmtIteratorImpl(RHS) {} + + inline friend StmtIterator + cast_away_const(const struct ConstStmtIterator &RHS); }; struct ConstStmtIterator : public StmtIteratorImpl(RHS) {} + + ConstStmtIterator(Stmt * const *S) + : StmtIteratorImpl( + const_cast(S)) {} }; +inline StmtIterator cast_away_const(const ConstStmtIterator &RHS) { + return RHS; +} } // end namespace clang #endif Index: lib/AST/Expr.cpp =================================================================== --- lib/AST/Expr.cpp +++ lib/AST/Expr.cpp @@ -2730,7 +2730,11 @@ } case InitListExprClass: { const InitListExpr *ILE = cast(this); - if (ILE->getType()->isArrayType()) { + QualType UnderlyingType = ILE->getType(); + if (UnderlyingType->isAtomicType()) + UnderlyingType = UnderlyingType->castAs()->getValueType(); + + if (UnderlyingType->isArrayType()) { unsigned numInits = ILE->getNumInits(); for (unsigned i = 0; i < numInits; i++) { if (!ILE->getInit(i)->isConstantInitializer(Ctx, false, Culprit)) @@ -2739,9 +2743,9 @@ return true; } - if (ILE->getType()->isRecordType()) { + if (UnderlyingType->isRecordType()) { unsigned ElementNo = 0; - RecordDecl *RD = ILE->getType()->getAs()->getDecl(); + RecordDecl *RD = UnderlyingType->getAs()->getDecl(); for (const auto *Field : RD->fields()) { // If this is a union, skip all the fields that aren't being initialized. if (RD->isUnion() && ILE->getInitializedFieldInUnion() != Field) @@ -3887,16 +3891,22 @@ // UnaryExprOrTypeTraitExpr Stmt::child_range UnaryExprOrTypeTraitExpr::children() { + const_child_range CCR = + const_cast(this)->children(); + return child_range(cast_away_const(CCR.begin()), cast_away_const(CCR.end())); +} + +Stmt::const_child_range UnaryExprOrTypeTraitExpr::children() const { // If this is of a type and the type is a VLA type (and not a typedef), the // size expression of the VLA needs to be treated as an executable expression. // Why isn't this weirdness documented better in StmtIterator? if (isArgumentType()) { - if (const VariableArrayType* T = dyn_cast( - getArgumentType().getTypePtr())) - return child_range(child_iterator(T), child_iterator()); - return child_range(child_iterator(), child_iterator()); + if (const VariableArrayType *T = + dyn_cast(getArgumentType().getTypePtr())) + return const_child_range(const_child_iterator(T), const_child_iterator()); + return const_child_range(const_child_iterator(), const_child_iterator()); } - return child_range(&Argument.Ex, &Argument.Ex + 1); + return const_child_range(&Argument.Ex, &Argument.Ex + 1); } AtomicExpr::AtomicExpr(SourceLocation BLoc, ArrayRef args,