diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index d2add78cd8dc..8ed16ad59cd3 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -1694,6 +1694,9 @@ public: /// unsigned getNumArgs() const { return NumArgs; } + /// \brief Retrieve the call arguments. + Expr **getArgs() { return reinterpret_cast(SubExprs + ARGS_START); } + /// getArg - Return the specified argument. Expr *getArg(unsigned Arg) { assert(Arg < NumArgs && "Arg access out of range!"); @@ -2737,6 +2740,9 @@ public: /// pointers. unsigned getNumSubExprs() const { return NumExprs; } + /// \brief Retrieve the array of expressions. + Expr **getSubExprs() { return reinterpret_cast(SubExprs); } + /// getExpr - Return the Expr at the specified index. Expr *getExpr(unsigned Index) { assert((Index < NumExprs) && "Arg access out of range!"); @@ -2971,6 +2977,9 @@ public: unsigned getNumInits() const { return InitExprs.size(); } + /// \brief Retrieve the set of initializers. + Expr **getInits() { return reinterpret_cast(InitExprs.data()); } + const Expr *getInit(unsigned Init) const { assert(Init < getNumInits() && "Initializer access out of range!"); return cast_or_null(InitExprs[Init]); diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h index bd7d3f09c386..5311d9c3a83e 100644 --- a/clang/include/clang/AST/ExprCXX.h +++ b/clang/include/clang/AST/ExprCXX.h @@ -21,11 +21,11 @@ namespace clang { - class CXXConstructorDecl; - class CXXDestructorDecl; - class CXXMethodDecl; - class CXXTemporary; - class TemplateArgumentListInfo; +class CXXConstructorDecl; +class CXXDestructorDecl; +class CXXMethodDecl; +class CXXTemporary; +class TemplateArgumentListInfo; //===--------------------------------------------------------------------===// // C++ Expressions. @@ -1052,6 +1052,10 @@ public: } unsigned getNumPlacementArgs() const { return NumPlacementArgs; } + Expr **getPlacementArgs() { + return reinterpret_cast(SubExprs + Array); + } + Expr *getPlacementArg(unsigned i) { assert(i < NumPlacementArgs && "Index out of range"); return cast(SubExprs[Array + i]); @@ -1070,6 +1074,11 @@ public: void setHasInitializer(bool V) { Initializer = V; } unsigned getNumConstructorArgs() const { return NumConstructorArgs; } + + Expr **getConstructorArgs() { + return reinterpret_cast(SubExprs + Array + NumPlacementArgs); + } + Expr *getConstructorArg(unsigned i) { assert(i < NumConstructorArgs && "Index out of range"); return cast(SubExprs[Array + NumPlacementArgs + i]); diff --git a/clang/include/clang/AST/ExprObjC.h b/clang/include/clang/AST/ExprObjC.h index 0eba6ba9f2e8..c89d4e34c118 100644 --- a/clang/include/clang/AST/ExprObjC.h +++ b/clang/include/clang/AST/ExprObjC.h @@ -746,11 +746,11 @@ public: /// \brief Retrieve the arguments to this message, not including the /// receiver. - Stmt **getArgs() { - return reinterpret_cast(this + 1) + 1; + Expr **getArgs() { + return reinterpret_cast(this + 1) + 1; } - const Stmt * const *getArgs() const { - return reinterpret_cast(this + 1) + 1; + const Expr * const *getArgs() const { + return reinterpret_cast(this + 1) + 1; } /// getArg - Return the specified argument. @@ -792,10 +792,16 @@ public: typedef ExprIterator arg_iterator; typedef ConstExprIterator const_arg_iterator; - arg_iterator arg_begin() { return getArgs(); } - arg_iterator arg_end() { return getArgs() + NumArgs; } - const_arg_iterator arg_begin() const { return getArgs(); } - const_arg_iterator arg_end() const { return getArgs() + NumArgs; } + arg_iterator arg_begin() { return reinterpret_cast(getArgs()); } + arg_iterator arg_end() { + return reinterpret_cast(getArgs() + NumArgs); + } + const_arg_iterator arg_begin() const { + return reinterpret_cast(getArgs()); + } + const_arg_iterator arg_end() const { + return reinterpret_cast(getArgs() + NumArgs); + } friend class ASTStmtReader; friend class ASTStmtWriter; diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index d8bb0af01838..3a71883419f3 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -2300,7 +2300,7 @@ ObjCMessageExpr::ObjCMessageExpr(QualType T, SelectorLoc(SelLoc), LBracLoc(LBracLoc), RBracLoc(RBracLoc) { setReceiverPointer(Receiver); - Stmt **MyArgs = getArgs(); + Expr **MyArgs = getArgs(); for (unsigned I = 0; I != NumArgs; ++I) { if (Args[I]->isTypeDependent()) ExprBits.TypeDependent = true; @@ -2331,7 +2331,7 @@ ObjCMessageExpr::ObjCMessageExpr(QualType T, SelectorLoc(SelLoc), LBracLoc(LBracLoc), RBracLoc(RBracLoc) { setReceiverPointer(Receiver); - Stmt **MyArgs = getArgs(); + Expr **MyArgs = getArgs(); for (unsigned I = 0; I != NumArgs; ++I) { if (Args[I]->isTypeDependent()) ExprBits.TypeDependent = true; @@ -2928,10 +2928,10 @@ Stmt::child_iterator ObjCProtocolExpr::child_end() { Stmt::child_iterator ObjCMessageExpr::child_begin() { if (getReceiverKind() == Instance) return reinterpret_cast(this + 1); - return getArgs(); + return reinterpret_cast(getArgs()); } Stmt::child_iterator ObjCMessageExpr::child_end() { - return getArgs() + getNumArgs(); + return reinterpret_cast(getArgs() + getNumArgs()); } // Blocks diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 992b84990468..03f5fc0c9a03 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -270,6 +270,33 @@ public: /// \returns the transformed expression. ExprResult TransformExpr(Expr *E); + /// \brief Transform the given list of expressions. + /// + /// This routine transforms a list of expressions by invoking + /// \c TransformExpr() for each subexpression. However, it also provides + /// support for variadic templates by expanding any pack expansions (if the + /// derived class permits such expansion) along the way. When pack expansions + /// are present, the number of outputs may not equal the number of inputs. + /// + /// \param Inputs The set of expressions to be transformed. + /// + /// \param NumInputs The number of expressions in \c Inputs. + /// + /// \param IsCall If \c true, then this transform is being performed on + /// function-call arguments, and any arguments that should be dropped, will + /// be. + /// + /// \param Outputs The transformed input expressions will be added to this + /// vector. + /// + /// \param ArgChanged If non-NULL, will be set \c true if any argument changed + /// due to transformation. + /// + /// \returns true if an error occurred, false otherwise. + bool TransformExprs(Expr **Inputs, unsigned NumInputs, bool IsCall, + llvm::SmallVectorImpl &Outputs, + bool *ArgChanged = 0); + /// \brief Transform the given declaration, which is referenced from a type /// or expression. /// @@ -2158,6 +2185,34 @@ ExprResult TreeTransform::TransformExpr(Expr *E) { return SemaRef.Owned(E); } +template +bool TreeTransform::TransformExprs(Expr **Inputs, + unsigned NumInputs, + bool IsCall, + llvm::SmallVectorImpl &Outputs, + bool *ArgChanged) { + for (unsigned I = 0; I != NumInputs; ++I) { + // If requested, drop call arguments that need to be dropped. + if (IsCall && getDerived().DropCallArgument(Inputs[I])) { + if (ArgChanged) + *ArgChanged = true; + + break; + } + + ExprResult Result = getDerived().TransformExpr(Inputs[I]); + if (Result.isInvalid()) + return true; + + if (Result.get() != Inputs[I] && ArgChanged) + *ArgChanged = true; + + Outputs.push_back(Result.get()); + } + + return false; +} + template NestedNameSpecifier * TreeTransform::TransformNestedNameSpecifier(NestedNameSpecifier *NNS, @@ -4878,15 +4933,10 @@ TreeTransform::TransformCallExpr(CallExpr *E) { // Transform arguments. bool ArgChanged = false; ASTOwningVector Args(SemaRef); - for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) { - ExprResult Arg = getDerived().TransformExpr(E->getArg(I)); - if (Arg.isInvalid()) - return ExprError(); - - ArgChanged = ArgChanged || Arg.get() != E->getArg(I); - Args.push_back(Arg.get()); - } - + if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args, + &ArgChanged)) + return ExprError(); + if (!getDerived().AlwaysRebuild() && Callee.get() == E->getCallee() && !ArgChanged) @@ -5114,15 +5164,10 @@ TreeTransform::TransformInitListExpr(InitListExpr *E) { bool InitChanged = false; ASTOwningVector Inits(SemaRef); - for (unsigned I = 0, N = E->getNumInits(); I != N; ++I) { - ExprResult Init = getDerived().TransformExpr(E->getInit(I)); - if (Init.isInvalid()) - return ExprError(); - - InitChanged = InitChanged || Init.get() != E->getInit(I); - Inits.push_back(Init.get()); - } - + if (getDerived().TransformExprs(E->getInits(), E->getNumInits(), false, + Inits, &InitChanged)) + return ExprError(); + if (!getDerived().AlwaysRebuild() && !InitChanged) return SemaRef.Owned(E); @@ -5242,15 +5287,10 @@ ExprResult TreeTransform::TransformParenListExpr(ParenListExpr *E) { bool ArgumentChanged = false; ASTOwningVector Inits(SemaRef); - for (unsigned I = 0, N = E->getNumExprs(); I != N; ++I) { - ExprResult Init = getDerived().TransformExpr(E->getExpr(I)); - if (Init.isInvalid()) - return ExprError(); - - ArgumentChanged = ArgumentChanged || Init.get() != E->getExpr(I); - Inits.push_back(Init.get()); - } - + if (TransformExprs(E->getExprs(), E->getNumExprs(), true, Inits, + &ArgumentChanged)) + return ExprError(); + return getDerived().RebuildParenListExpr(E->getLParenLoc(), move_arg(Inits), E->getRParenLoc()); @@ -5344,16 +5384,9 @@ TreeTransform::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) { // Transform the call arguments. ASTOwningVector Args(SemaRef); - for (unsigned I = 1, N = E->getNumArgs(); I != N; ++I) { - if (getDerived().DropCallArgument(E->getArg(I))) - break; - - ExprResult Arg = getDerived().TransformExpr(E->getArg(I)); - if (Arg.isInvalid()) - return ExprError(); - - Args.push_back(Arg.release()); - } + if (getDerived().TransformExprs(E->getArgs() + 1, E->getNumArgs() - 1, true, + Args)) + return ExprError(); return getDerived().RebuildCallExpr(Object.get(), FakeLParenLoc, move_arg(Args), @@ -5662,35 +5695,16 @@ TreeTransform::TransformCXXNewExpr(CXXNewExpr *E) { // Transform the placement arguments (if any). bool ArgumentChanged = false; ASTOwningVector PlacementArgs(SemaRef); - for (unsigned I = 0, N = E->getNumPlacementArgs(); I != N; ++I) { - if (getDerived().DropCallArgument(E->getPlacementArg(I))) { - ArgumentChanged = true; - break; - } - - ExprResult Arg = getDerived().TransformExpr(E->getPlacementArg(I)); - if (Arg.isInvalid()) - return ExprError(); - - ArgumentChanged = ArgumentChanged || Arg.get() != E->getPlacementArg(I); - PlacementArgs.push_back(Arg.take()); - } + if (getDerived().TransformExprs(E->getPlacementArgs(), + E->getNumPlacementArgs(), true, + PlacementArgs, &ArgumentChanged)) + return ExprError(); // transform the constructor arguments (if any). ASTOwningVector ConstructorArgs(SemaRef); - for (unsigned I = 0, N = E->getNumConstructorArgs(); I != N; ++I) { - if (getDerived().DropCallArgument(E->getConstructorArg(I))) { - ArgumentChanged = true; - break; - } - - ExprResult Arg = getDerived().TransformExpr(E->getConstructorArg(I)); - if (Arg.isInvalid()) - return ExprError(); - - ArgumentChanged = ArgumentChanged || Arg.get() != E->getConstructorArg(I); - ConstructorArgs.push_back(Arg.take()); - } + if (TransformExprs(E->getConstructorArgs(), E->getNumConstructorArgs(), true, + ConstructorArgs, &ArgumentChanged)) + return ExprError(); // Transform constructor, new operator, and delete operator. CXXConstructorDecl *Constructor = 0; @@ -6092,22 +6106,10 @@ TreeTransform::TransformCXXConstructExpr(CXXConstructExpr *E) { bool ArgumentChanged = false; ASTOwningVector Args(SemaRef); - for (CXXConstructExpr::arg_iterator Arg = E->arg_begin(), - ArgEnd = E->arg_end(); - Arg != ArgEnd; ++Arg) { - if (getDerived().DropCallArgument(*Arg)) { - ArgumentChanged = true; - break; - } - - ExprResult TransArg = getDerived().TransformExpr(*Arg); - if (TransArg.isInvalid()) - return ExprError(); - - ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg; - Args.push_back(TransArg.get()); - } - + if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args, + &ArgumentChanged)) + return ExprError(); + if (!getDerived().AlwaysRebuild() && T == E->getType() && Constructor == E->getConstructor() && @@ -6165,21 +6167,9 @@ TreeTransform::TransformCXXTemporaryObjectExpr( bool ArgumentChanged = false; ASTOwningVector Args(SemaRef); Args.reserve(E->getNumArgs()); - for (CXXTemporaryObjectExpr::arg_iterator Arg = E->arg_begin(), - ArgEnd = E->arg_end(); - Arg != ArgEnd; ++Arg) { - if (getDerived().DropCallArgument(*Arg)) { - ArgumentChanged = true; - break; - } - - ExprResult TransArg = getDerived().TransformExpr(*Arg); - if (TransArg.isInvalid()) - return ExprError(); - - ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg; - Args.push_back((Expr *)TransArg.release()); - } + if (TransformExprs(E->getArgs(), E->getNumArgs(), true, Args, + &ArgumentChanged)) + return ExprError(); if (!getDerived().AlwaysRebuild() && T == E->getTypeSourceInfo() && @@ -6206,17 +6196,11 @@ TreeTransform::TransformCXXUnresolvedConstructExpr( bool ArgumentChanged = false; ASTOwningVector Args(SemaRef); - for (CXXUnresolvedConstructExpr::arg_iterator Arg = E->arg_begin(), - ArgEnd = E->arg_end(); - Arg != ArgEnd; ++Arg) { - ExprResult TransArg = getDerived().TransformExpr(*Arg); - if (TransArg.isInvalid()) - return ExprError(); - - ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg; - Args.push_back(TransArg.get()); - } - + Args.reserve(E->arg_size()); + if (getDerived().TransformExprs(E->arg_begin(), E->arg_size(), true, Args, + &ArgumentChanged)) + return ExprError(); + if (!getDerived().AlwaysRebuild() && T == E->getTypeSourceInfo() && !ArgumentChanged) @@ -6473,15 +6457,11 @@ TreeTransform::TransformObjCMessageExpr(ObjCMessageExpr *E) { // Transform arguments. bool ArgChanged = false; ASTOwningVector Args(SemaRef); - for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) { - ExprResult Arg = getDerived().TransformExpr(E->getArg(I)); - if (Arg.isInvalid()) - return ExprError(); - - ArgChanged = ArgChanged || Arg.get() != E->getArg(I); - Args.push_back(Arg.get()); - } - + Args.reserve(E->getNumArgs()); + if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), false, Args, + &ArgChanged)) + return ExprError(); + if (E->getReceiverKind() == ObjCMessageExpr::Class) { // Class message: transform the receiver type. TypeSourceInfo *ReceiverTypeInfo @@ -6613,14 +6593,10 @@ ExprResult TreeTransform::TransformShuffleVectorExpr(ShuffleVectorExpr *E) { bool ArgumentChanged = false; ASTOwningVector SubExprs(SemaRef); - for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I) { - ExprResult SubExpr = getDerived().TransformExpr(E->getExpr(I)); - if (SubExpr.isInvalid()) - return ExprError(); - - ArgumentChanged = ArgumentChanged || SubExpr.get() != E->getExpr(I); - SubExprs.push_back(SubExpr.get()); - } + SubExprs.reserve(E->getNumSubExprs()); + if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false, + SubExprs, &ArgumentChanged)) + return ExprError(); if (!getDerived().AlwaysRebuild() && !ArgumentChanged)