Index: clang/include/clang/AST/Expr.h =================================================================== --- clang/include/clang/AST/Expr.h +++ clang/include/clang/AST/Expr.h @@ -2274,13 +2274,55 @@ } }; +/// Abstract interface for CallExpr, ObjCMessageExpr and CXXConstructExpr. +class AbstractCallExpr : public Expr { +public: + AbstractCallExpr(StmtClass SC, QualType T, ExprValueKind VK, + ExprObjectKind OK, bool TD, bool VD, bool ID, + bool ContainsUnexpandedParameterPack) + : Expr(SC, T, VK, OK, TD, VD, ID, ContainsUnexpandedParameterPack) {} + + explicit AbstractCallExpr(StmtClass SC, EmptyShell ES) : Expr(SC, ES) {} + + typedef ExprIterator arg_iterator; + typedef ConstExprIterator const_arg_iterator; + typedef llvm::iterator_range arg_range; + typedef llvm::iterator_range arg_const_range; + + virtual arg_iterator arg_begin() = 0; + virtual arg_iterator arg_end() = 0; + virtual const_arg_iterator arg_begin() const = 0; + virtual const_arg_iterator arg_end() const = 0; + + virtual arg_range arguments() { + return arg_range(arg_begin(), arg_end()); + } + + virtual arg_const_range arguments() const { + return arg_const_range(arg_begin(), arg_end()); + } + + virtual unsigned getNumArgs() const; + virtual Expr **getArgs() = 0; + virtual const Expr * const *getArgs() const = 0; + virtual Expr *getArg(unsigned Arg) = 0; + virtual const Expr *getArg(unsigned Arg) const = 0; + + virtual void setArg(unsigned Arg, Expr *ArgExpr) = 0; + + virtual SourceLocation getLocStart() const LLVM_READONLY = 0; + virtual SourceLocation getLocEnd() const LLVM_READONLY = 0; + + virtual ~AbstractCallExpr(){} +}; + /// CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]). /// CallExpr itself represents a normal function call, e.g., "f(x, 2)", /// while its subclasses may represent alternative syntax that (semantically) /// results in a function call. For example, CXXOperatorCallExpr is /// a subclass for overloaded operator calls that use operator syntax, e.g., /// "str1 + str2" to resolve to a function call. -class CallExpr : public Expr { +class CallExpr : public AbstractCallExpr { enum { FN=0, PREARGS_START=1 }; Stmt **SubExprs; unsigned NumArgs; @@ -2337,29 +2379,29 @@ /// getNumArgs - Return the number of actual arguments to this call. /// - unsigned getNumArgs() const { return NumArgs; } + unsigned getNumArgs() const override { return NumArgs; } /// Retrieve the call arguments. - Expr **getArgs() { + Expr **getArgs() override { return reinterpret_cast(SubExprs+getNumPreArgs()+PREARGS_START); } - const Expr *const *getArgs() const { + const Expr *const *getArgs() const override { return reinterpret_cast(SubExprs + getNumPreArgs() + PREARGS_START); } /// getArg - Return the specified argument. - Expr *getArg(unsigned Arg) { + Expr *getArg(unsigned Arg) override { assert(Arg < NumArgs && "Arg access out of range!"); return cast_or_null(SubExprs[Arg + getNumPreArgs() + PREARGS_START]); } - const Expr *getArg(unsigned Arg) const { + const Expr *getArg(unsigned Arg) const override { assert(Arg < NumArgs && "Arg access out of range!"); return cast_or_null(SubExprs[Arg + getNumPreArgs() + PREARGS_START]); } /// setArg - Set the specified argument. - void setArg(unsigned Arg, Expr *ArgExpr) { + void setArg(unsigned Arg, Expr *ArgExpr) override { assert(Arg < NumArgs && "Arg access out of range!"); SubExprs[Arg+getNumPreArgs()+PREARGS_START] = ArgExpr; } @@ -2369,24 +2411,19 @@ /// to null. void setNumArgs(const ASTContext& C, unsigned NumArgs); - typedef ExprIterator arg_iterator; - typedef ConstExprIterator const_arg_iterator; - typedef llvm::iterator_range arg_range; - typedef llvm::iterator_range arg_const_range; - - arg_range arguments() { return arg_range(arg_begin(), arg_end()); } - arg_const_range arguments() const { - return arg_const_range(arg_begin(), arg_end()); + arg_iterator arg_begin() override { + return SubExprs+PREARGS_START+getNumPreArgs(); } - arg_iterator arg_begin() { return SubExprs+PREARGS_START+getNumPreArgs(); } - arg_iterator arg_end() { + arg_iterator arg_end() override { return SubExprs+PREARGS_START+getNumPreArgs()+getNumArgs(); } - const_arg_iterator arg_begin() const { + + const_arg_iterator arg_begin() const override { return SubExprs+PREARGS_START+getNumPreArgs(); } - const_arg_iterator arg_end() const { + + const_arg_iterator arg_end() const override { return SubExprs+PREARGS_START+getNumPreArgs()+getNumArgs(); } @@ -2419,8 +2456,8 @@ SourceLocation getRParenLoc() const { return RParenLoc; } void setRParenLoc(SourceLocation L) { RParenLoc = L; } - SourceLocation getLocStart() const LLVM_READONLY; - SourceLocation getLocEnd() const LLVM_READONLY; + SourceLocation getLocStart() const override LLVM_READONLY; + SourceLocation getLocEnd() const override LLVM_READONLY; /// Return true if this is a call to __assume() or __builtin_assume() with /// a non-value-dependent constant parameter evaluating as false. Index: clang/include/clang/AST/ExprCXX.h =================================================================== --- clang/include/clang/AST/ExprCXX.h +++ clang/include/clang/AST/ExprCXX.h @@ -1236,7 +1236,7 @@ }; /// Represents a call to a C++ constructor. -class CXXConstructExpr : public Expr { +class CXXConstructExpr : public AbstractCallExpr { public: enum ConstructionKind { CK_Complete, @@ -1275,7 +1275,7 @@ /// Construct an empty C++ construction expression. CXXConstructExpr(StmtClass SC, EmptyShell Empty) - : Expr(SC, Empty), NumArgs(0), Elidable(false), + : AbstractCallExpr(SC, Empty), NumArgs(0), Elidable(false), HadMultipleCandidates(false), ListInitialization(false), ZeroInitialization(false), ConstructKind(0) {} @@ -1340,45 +1340,35 @@ ConstructKind = CK; } - using arg_iterator = ExprIterator; - using const_arg_iterator = ConstExprIterator; - using arg_range = llvm::iterator_range; - using arg_const_range = llvm::iterator_range; - - arg_range arguments() { return arg_range(arg_begin(), arg_end()); } - arg_const_range arguments() const { - return arg_const_range(arg_begin(), arg_end()); - } + arg_iterator arg_begin() override { return Args; } + arg_iterator arg_end() override { return Args + NumArgs; } + const_arg_iterator arg_begin() const override { return Args; } + const_arg_iterator arg_end() const override { return Args + NumArgs; } - arg_iterator arg_begin() { return Args; } - arg_iterator arg_end() { return Args + NumArgs; } - const_arg_iterator arg_begin() const { return Args; } - const_arg_iterator arg_end() const { return Args + NumArgs; } - - Expr **getArgs() { return reinterpret_cast(Args); } - const Expr *const *getArgs() const { + Expr **getArgs() override { return reinterpret_cast(Args); } + const Expr *const *getArgs() const override { return const_cast(this)->getArgs(); } - unsigned getNumArgs() const { return NumArgs; } + unsigned getNumArgs() const override { return NumArgs; } /// Return the specified argument. - Expr *getArg(unsigned Arg) { + Expr *getArg(unsigned Arg) override { assert(Arg < NumArgs && "Arg access out of range!"); return cast(Args[Arg]); } - const Expr *getArg(unsigned Arg) const { + const Expr *getArg(unsigned Arg) const override { assert(Arg < NumArgs && "Arg access out of range!"); return cast(Args[Arg]); } /// Set the specified argument. - void setArg(unsigned Arg, Expr *ArgExpr) { + void setArg(unsigned Arg, Expr *ArgExpr) override { assert(Arg < NumArgs && "Arg access out of range!"); Args[Arg] = ArgExpr; } - SourceLocation getLocStart() const LLVM_READONLY; - SourceLocation getLocEnd() const LLVM_READONLY; + SourceLocation getLocStart() const override LLVM_READONLY; + SourceLocation getLocEnd() const override LLVM_READONLY; SourceRange getParenOrBraceRange() const { return ParenOrBraceRange; } void setParenOrBraceRange(SourceRange Range) { ParenOrBraceRange = Range; } Index: clang/include/clang/AST/ExprObjC.h =================================================================== --- clang/include/clang/AST/ExprObjC.h +++ clang/include/clang/AST/ExprObjC.h @@ -901,7 +901,7 @@ /// receiver pointer), and NumArgs Expr *. But due to the /// implementation of children(), these must be together contiguously. class ObjCMessageExpr final - : public Expr, + : public AbstractCallExpr, private llvm::TrailingObjects { /// Stores either the selector that this message is sending /// to (when \c HasMethod is zero) or an \c ObjCMethodDecl pointer @@ -948,7 +948,7 @@ SourceLocation LBracLoc, RBracLoc; ObjCMessageExpr(EmptyShell Empty, unsigned NumArgs) - : Expr(ObjCMessageExprClass, Empty), Kind(0), HasMethod(false), + : AbstractCallExpr(ObjCMessageExprClass, Empty), Kind(0), HasMethod(false), IsDelegateInitCall(false), IsImplicit(false), SelLocsKind(0) { setNumArgs(NumArgs); } @@ -1325,30 +1325,30 @@ /// Return the number of actual arguments in this message, /// not counting the receiver. - unsigned getNumArgs() const { return NumArgs; } + unsigned getNumArgs() const override { return NumArgs; } /// Retrieve the arguments to this message, not including the /// receiver. - Expr **getArgs() { + Expr **getArgs() override { return reinterpret_cast(getTrailingObjects() + 1); } - const Expr * const *getArgs() const { + const Expr * const *getArgs() const override { return reinterpret_cast(getTrailingObjects() + 1); } /// getArg - Return the specified argument. - Expr *getArg(unsigned Arg) { + Expr *getArg(unsigned Arg) override { assert(Arg < NumArgs && "Arg access out of range!"); return getArgs()[Arg]; } - const Expr *getArg(unsigned Arg) const { + const Expr *getArg(unsigned Arg) const override { assert(Arg < NumArgs && "Arg access out of range!"); return getArgs()[Arg]; } /// setArg - Set the specified argument. - void setArg(unsigned Arg, Expr *ArgExpr) { + void setArg(unsigned Arg, Expr *ArgExpr) override { assert(Arg < NumArgs && "Arg access out of range!"); getArgs()[Arg] = ArgExpr; } @@ -1395,34 +1395,29 @@ RBracLoc = R.getEnd(); } - SourceLocation getLocStart() const LLVM_READONLY { return LBracLoc; } - SourceLocation getLocEnd() const LLVM_READONLY { return RBracLoc; } + SourceLocation getLocStart() const override LLVM_READONLY { + return LBracLoc; + } + SourceLocation getLocEnd() const override LLVM_READONLY { + return RBracLoc; + } // Iterators child_range children(); - using arg_iterator = ExprIterator; - using const_arg_iterator = ConstExprIterator; - - llvm::iterator_range arguments() { - return llvm::make_range(arg_begin(), arg_end()); - } - - llvm::iterator_range arguments() const { - return llvm::make_range(arg_begin(), arg_end()); + arg_iterator arg_begin() override { + return reinterpret_cast(getArgs()); } - arg_iterator arg_begin() { return reinterpret_cast(getArgs()); } - - arg_iterator arg_end() { + arg_iterator arg_end() override { return reinterpret_cast(getArgs() + NumArgs); } - const_arg_iterator arg_begin() const { + const_arg_iterator arg_begin() const override { return reinterpret_cast(getArgs()); } - const_arg_iterator arg_end() const { + const_arg_iterator arg_end() const override { return reinterpret_cast(getArgs() + NumArgs); } Index: clang/lib/AST/Expr.cpp =================================================================== --- clang/lib/AST/Expr.cpp +++ clang/lib/AST/Expr.cpp @@ -1191,7 +1191,7 @@ CallExpr::CallExpr(const ASTContext &C, StmtClass SC, Expr *fn, ArrayRef preargs, ArrayRef args, QualType t, ExprValueKind VK, SourceLocation rparenloc) - : Expr(SC, t, VK, OK_Ordinary, fn->isTypeDependent(), + : AbstractCallExpr(SC, t, VK, OK_Ordinary, fn->isTypeDependent(), fn->isValueDependent(), fn->isInstantiationDependent(), fn->containsUnexpandedParameterPack()), NumArgs(args.size()) { @@ -1227,7 +1227,7 @@ CallExpr::CallExpr(const ASTContext &C, StmtClass SC, unsigned NumPreArgs, EmptyShell Empty) - : Expr(SC, Empty), SubExprs(nullptr), NumArgs(0) { + : AbstractCallExpr(SC, Empty), SubExprs(nullptr), NumArgs(0) { // FIXME: Why do we allocate this? SubExprs = new (C) Stmt*[PREARGS_START+NumPreArgs](); CallExprBits.NumPreArgs = NumPreArgs; Index: clang/lib/AST/ExprCXX.cpp =================================================================== --- clang/lib/AST/ExprCXX.cpp +++ clang/lib/AST/ExprCXX.cpp @@ -806,21 +806,15 @@ ParenOrBraceRange); } -CXXConstructExpr::CXXConstructExpr(const ASTContext &C, StmtClass SC, - QualType T, SourceLocation Loc, - CXXConstructorDecl *Ctor, - bool Elidable, - ArrayRef Args, - bool HadMultipleCandidates, - bool ListInitialization, - bool StdInitListInitialization, - bool ZeroInitialization, - ConstructionKind ConstructKind, - SourceRange ParenOrBraceRange) - : Expr(SC, T, VK_RValue, OK_Ordinary, - T->isDependentType(), T->isDependentType(), - T->isInstantiationDependentType(), - T->containsUnexpandedParameterPack()), +CXXConstructExpr::CXXConstructExpr( + const ASTContext &C, StmtClass SC, QualType T, SourceLocation Loc, + CXXConstructorDecl *Ctor, bool Elidable, ArrayRef Args, + bool HadMultipleCandidates, bool ListInitialization, + bool StdInitListInitialization, bool ZeroInitialization, + ConstructionKind ConstructKind, SourceRange ParenOrBraceRange) + : AbstractCallExpr(SC, T, VK_RValue, OK_Ordinary, T->isDependentType(), + T->isDependentType(), T->isInstantiationDependentType(), + T->containsUnexpandedParameterPack()), Constructor(Ctor), Loc(Loc), ParenOrBraceRange(ParenOrBraceRange), NumArgs(Args.size()), Elidable(Elidable), HadMultipleCandidates(HadMultipleCandidates), Index: clang/lib/AST/ExprObjC.cpp =================================================================== --- clang/lib/AST/ExprObjC.cpp +++ clang/lib/AST/ExprObjC.cpp @@ -128,10 +128,10 @@ SelectorLocationsKind SelLocsK, ObjCMethodDecl *Method, ArrayRef Args, SourceLocation RBracLoc, bool isImplicit) - : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary, - /*TypeDependent=*/false, /*ValueDependent=*/false, - /*InstantiationDependent=*/false, - /*ContainsUnexpandedParameterPack=*/false), + : AbstractCallExpr(ObjCMessageExprClass, T, VK, OK_Ordinary, + /*TypeDependent=*/false, /*ValueDependent=*/false, + /*InstantiationDependent=*/false, + /*ContainsUnexpandedParameterPack=*/false), SelectorOrMethod( reinterpret_cast(Method ? Method : Sel.getAsOpaquePtr())), Kind(IsInstanceSuper ? SuperInstance : SuperClass), @@ -149,9 +149,10 @@ SelectorLocationsKind SelLocsK, ObjCMethodDecl *Method, ArrayRef Args, SourceLocation RBracLoc, bool isImplicit) - : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary, T->isDependentType(), - T->isDependentType(), T->isInstantiationDependentType(), - T->containsUnexpandedParameterPack()), + : AbstractCallExpr(ObjCMessageExprClass, T, VK, OK_Ordinary, + T->isDependentType(), T->isDependentType(), + T->isInstantiationDependentType(), + T->containsUnexpandedParameterPack()), SelectorOrMethod( reinterpret_cast(Method ? Method : Sel.getAsOpaquePtr())), Kind(Class), HasMethod(Method != nullptr), IsDelegateInitCall(false), @@ -166,10 +167,10 @@ SelectorLocationsKind SelLocsK, ObjCMethodDecl *Method, ArrayRef Args, SourceLocation RBracLoc, bool isImplicit) - : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary, - Receiver->isTypeDependent(), Receiver->isTypeDependent(), - Receiver->isInstantiationDependent(), - Receiver->containsUnexpandedParameterPack()), + : AbstractCallExpr(ObjCMessageExprClass, T, VK, OK_Ordinary, + Receiver->isTypeDependent(), Receiver->isTypeDependent(), + Receiver->isInstantiationDependent(), + Receiver->containsUnexpandedParameterPack()), SelectorOrMethod( reinterpret_cast(Method ? Method : Sel.getAsOpaquePtr())), Kind(Instance), HasMethod(Method != nullptr), IsDelegateInitCall(false),