diff options
Diffstat (limited to 'include/clang/AST/Expr.h')
-rw-r--r-- | include/clang/AST/Expr.h | 748 |
1 files changed, 397 insertions, 351 deletions
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index ade2b09..48130be 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -18,6 +18,7 @@ #include "clang/AST/Stmt.h" #include "clang/AST/Type.h" #include "clang/AST/DeclAccessPair.h" +#include "clang/AST/OperationKinds.h" #include "clang/AST/ASTVector.h" #include "clang/AST/UsuallyTinyPtrVector.h" #include "llvm/ADT/APSInt.h" @@ -42,7 +43,7 @@ namespace clang { class TemplateArgumentListInfo; /// \brief A simple array of base specifiers. -typedef UsuallyTinyPtrVector<const CXXBaseSpecifier> CXXBaseSpecifierArray; +typedef llvm::SmallVector<CXXBaseSpecifier*, 4> CXXCastPath; /// Expr - This represents one expression. Note that Expr's are subclasses of /// Stmt. This allows an expression to be transparently used any place a Stmt @@ -61,8 +62,14 @@ protected: /// (C++ [temp.dep.constexpr]). bool ValueDependent : 1; + /// ValueKind - The value classification of this expression. + /// Only actually used by certain subclasses. + unsigned ValueKind : 2; + + enum { BitsRemaining = 28 }; + Expr(StmtClass SC, QualType T, bool TD, bool VD) - : Stmt(SC), TypeDependent(TD), ValueDependent(VD) { + : Stmt(SC), TypeDependent(TD), ValueDependent(VD), ValueKind(0) { setType(T); } @@ -258,7 +265,6 @@ public: /// function returning an rvalue reference. /// lvalues and xvalues are collectively referred to as glvalues, while /// prvalues and xvalues together form rvalues. - /// If a Classification Classify(ASTContext &Ctx) const { return ClassifyImpl(Ctx, 0); } @@ -310,7 +316,7 @@ public: } /// isConstantInitializer - Returns true if this expression is a constant /// initializer, which can be emitted at compile-time. - bool isConstantInitializer(ASTContext &Ctx) const; + bool isConstantInitializer(ASTContext &Ctx, bool ForRef) const; /// EvalResult is a struct with detailed info about an evaluated expression. struct EvalResult { @@ -521,10 +527,14 @@ class DeclRefExpr : public Expr { // (2) the declaration's name was followed by an explicit template // argument list. llvm::PointerIntPair<ValueDecl *, 2> DecoratedD; - + // Loc - The location of the declaration name itself. SourceLocation Loc; + /// DNLoc - Provides source/type location info for the + /// declaration name embedded in DecoratedD. + DeclarationNameLoc DNLoc; + /// \brief Retrieve the qualifier that preceded the declaration name, if any. NameQualifier *getNameQualifier() { if ((DecoratedD.getInt() & HasQualifierFlag) == 0) @@ -537,31 +547,17 @@ class DeclRefExpr : public Expr { const NameQualifier *getNameQualifier() const { return const_cast<DeclRefExpr *>(this)->getNameQualifier(); } - - /// \brief Retrieve the explicit template argument list that followed the - /// member template name, if any. - ExplicitTemplateArgumentList *getExplicitTemplateArgumentList() { - if ((DecoratedD.getInt() & HasExplicitTemplateArgumentListFlag) == 0) - return 0; - - if ((DecoratedD.getInt() & HasQualifierFlag) == 0) - return reinterpret_cast<ExplicitTemplateArgumentList *>(this + 1); - - return reinterpret_cast<ExplicitTemplateArgumentList *>( - getNameQualifier() + 1); - } - - /// \brief Retrieve the explicit template argument list that followed the - /// member template name, if any. - const ExplicitTemplateArgumentList *getExplicitTemplateArgumentList() const { - return const_cast<DeclRefExpr *>(this)->getExplicitTemplateArgumentList(); - } - + DeclRefExpr(NestedNameSpecifier *Qualifier, SourceRange QualifierRange, ValueDecl *D, SourceLocation NameLoc, const TemplateArgumentListInfo *TemplateArgs, QualType T); + DeclRefExpr(NestedNameSpecifier *Qualifier, SourceRange QualifierRange, + ValueDecl *D, const DeclarationNameInfo &NameInfo, + const TemplateArgumentListInfo *TemplateArgs, + QualType T); + /// \brief Construct an empty declaration reference expression. explicit DeclRefExpr(EmptyShell Empty) : Expr(DeclRefExprClass, Empty) { } @@ -584,6 +580,14 @@ public: QualType T, const TemplateArgumentListInfo *TemplateArgs = 0); + static DeclRefExpr *Create(ASTContext &Context, + NestedNameSpecifier *Qualifier, + SourceRange QualifierRange, + ValueDecl *D, + const DeclarationNameInfo &NameInfo, + QualType T, + const TemplateArgumentListInfo *TemplateArgs = 0); + /// \brief Construct an empty declaration reference expression. static DeclRefExpr *CreateEmpty(ASTContext &Context, bool HasQualifier, unsigned NumTemplateArgs); @@ -592,6 +596,10 @@ public: const ValueDecl *getDecl() const { return DecoratedD.getPointer(); } void setDecl(ValueDecl *NewD) { DecoratedD.setPointer(NewD); } + DeclarationNameInfo getNameInfo() const { + return DeclarationNameInfo(getDecl()->getDeclName(), Loc, DNLoc); + } + SourceLocation getLocation() const { return Loc; } void setLocation(SourceLocation L) { Loc = L; } virtual SourceRange getSourceRange() const; @@ -619,53 +627,77 @@ public: return getNameQualifier()->NNS; } - /// \brief Determines whether this member expression actually had a C++ - /// template argument list explicitly specified, e.g., x.f<int>. - bool hasExplicitTemplateArgumentList() const { - return DecoratedD.getInt() & HasExplicitTemplateArgumentListFlag; + bool hasExplicitTemplateArgs() const { + return (DecoratedD.getInt() & HasExplicitTemplateArgumentListFlag); + } + + /// \brief Retrieve the explicit template argument list that followed the + /// member template name. + ExplicitTemplateArgumentList &getExplicitTemplateArgs() { + assert(hasExplicitTemplateArgs()); + + if ((DecoratedD.getInt() & HasQualifierFlag) == 0) + return *reinterpret_cast<ExplicitTemplateArgumentList *>(this + 1); + + return *reinterpret_cast<ExplicitTemplateArgumentList *>( + getNameQualifier() + 1); + } + + /// \brief Retrieve the explicit template argument list that followed the + /// member template name. + const ExplicitTemplateArgumentList &getExplicitTemplateArgs() const { + return const_cast<DeclRefExpr *>(this)->getExplicitTemplateArgs(); } + /// \brief Retrieves the optional explicit template arguments. + /// This points to the same data as getExplicitTemplateArgs(), but + /// returns null if there are no explicit template arguments. + const ExplicitTemplateArgumentList *getExplicitTemplateArgsOpt() const { + if (!hasExplicitTemplateArgs()) return 0; + return &getExplicitTemplateArgs(); + } + /// \brief Copies the template arguments (if present) into the given /// structure. void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const { - if (hasExplicitTemplateArgumentList()) - getExplicitTemplateArgumentList()->copyInto(List); + if (hasExplicitTemplateArgs()) + getExplicitTemplateArgs().copyInto(List); } /// \brief Retrieve the location of the left angle bracket following the /// member name ('<'), if any. SourceLocation getLAngleLoc() const { - if (!hasExplicitTemplateArgumentList()) + if (!hasExplicitTemplateArgs()) return SourceLocation(); - return getExplicitTemplateArgumentList()->LAngleLoc; + return getExplicitTemplateArgs().LAngleLoc; } /// \brief Retrieve the template arguments provided as part of this /// template-id. const TemplateArgumentLoc *getTemplateArgs() const { - if (!hasExplicitTemplateArgumentList()) + if (!hasExplicitTemplateArgs()) return 0; - return getExplicitTemplateArgumentList()->getTemplateArgs(); + return getExplicitTemplateArgs().getTemplateArgs(); } /// \brief Retrieve the number of template arguments provided as part of this /// template-id. unsigned getNumTemplateArgs() const { - if (!hasExplicitTemplateArgumentList()) + if (!hasExplicitTemplateArgs()) return 0; - return getExplicitTemplateArgumentList()->NumTemplateArgs; + return getExplicitTemplateArgs().NumTemplateArgs; } /// \brief Retrieve the location of the right angle bracket following the /// template arguments ('>'). SourceLocation getRAngleLoc() const { - if (!hasExplicitTemplateArgumentList()) + if (!hasExplicitTemplateArgs()) return SourceLocation(); - return getExplicitTemplateArgumentList()->RAngleLoc; + return getExplicitTemplateArgs().RAngleLoc; } static bool classof(const Stmt *T) { @@ -677,8 +709,8 @@ public: virtual child_iterator child_begin(); virtual child_iterator child_end(); - friend class PCHStmtReader; - friend class PCHStmtWriter; + friend class ASTStmtReader; + friend class ASTStmtWriter; }; /// PredefinedExpr - [C99 6.4.2.2] - A predefined identifier such as __func__. @@ -725,28 +757,84 @@ public: virtual child_iterator child_end(); }; +/// \brief Used by IntegerLiteral/FloatingLiteral to store the numeric without +/// leaking memory. +/// +/// For large floats/integers, APFloat/APInt will allocate memory from the heap +/// to represent these numbers. Unfortunately, when we use a BumpPtrAllocator +/// to allocate IntegerLiteral/FloatingLiteral nodes the memory associated with +/// the APFloat/APInt values will never get freed. APNumericStorage uses +/// ASTContext's allocator for memory allocation. +class APNumericStorage { + unsigned BitWidth; + union { + uint64_t VAL; ///< Used to store the <= 64 bits integer value. + uint64_t *pVal; ///< Used to store the >64 bits integer value. + }; + + bool hasAllocation() const { return llvm::APInt::getNumWords(BitWidth) > 1; } + + APNumericStorage(const APNumericStorage&); // do not implement + APNumericStorage& operator=(const APNumericStorage&); // do not implement + +protected: + APNumericStorage() : BitWidth(0), VAL(0) { } + + llvm::APInt getIntValue() const { + unsigned NumWords = llvm::APInt::getNumWords(BitWidth); + if (NumWords > 1) + return llvm::APInt(BitWidth, NumWords, pVal); + else + return llvm::APInt(BitWidth, VAL); + } + void setIntValue(ASTContext &C, const llvm::APInt &Val); +}; + +class APIntStorage : public APNumericStorage { +public: + llvm::APInt getValue() const { return getIntValue(); } + void setValue(ASTContext &C, const llvm::APInt &Val) { setIntValue(C, Val); } +}; + +class APFloatStorage : public APNumericStorage { +public: + llvm::APFloat getValue() const { return llvm::APFloat(getIntValue()); } + void setValue(ASTContext &C, const llvm::APFloat &Val) { + setIntValue(C, Val.bitcastToAPInt()); + } +}; + class IntegerLiteral : public Expr { - llvm::APInt Value; + APIntStorage Num; SourceLocation Loc; + + /// \brief Construct an empty integer literal. + explicit IntegerLiteral(EmptyShell Empty) + : Expr(IntegerLiteralClass, Empty) { } + public: // type should be IntTy, LongTy, LongLongTy, UnsignedIntTy, UnsignedLongTy, // or UnsignedLongLongTy - IntegerLiteral(const llvm::APInt &V, QualType type, SourceLocation l) - : Expr(IntegerLiteralClass, type, false, false), Value(V), Loc(l) { + IntegerLiteral(ASTContext &C, const llvm::APInt &V, + QualType type, SourceLocation l) + : Expr(IntegerLiteralClass, type, false, false), Loc(l) { assert(type->isIntegerType() && "Illegal type in IntegerLiteral"); + setValue(C, V); } - /// \brief Construct an empty integer literal. - explicit IntegerLiteral(EmptyShell Empty) - : Expr(IntegerLiteralClass, Empty) { } + // type should be IntTy, LongTy, LongLongTy, UnsignedIntTy, UnsignedLongTy, + // or UnsignedLongLongTy + static IntegerLiteral *Create(ASTContext &C, const llvm::APInt &V, + QualType type, SourceLocation l); + static IntegerLiteral *Create(ASTContext &C, EmptyShell Empty); - const llvm::APInt &getValue() const { return Value; } + llvm::APInt getValue() const { return Num.getValue(); } virtual SourceRange getSourceRange() const { return SourceRange(Loc); } /// \brief Retrieve the location of the literal. SourceLocation getLocation() const { return Loc; } - void setValue(const llvm::APInt &Val) { Value = Val; } + void setValue(ASTContext &C, const llvm::APInt &Val) { Num.setValue(C, Val); } void setLocation(SourceLocation Location) { Loc = Location; } static bool classof(const Stmt *T) { @@ -795,21 +883,30 @@ public: }; class FloatingLiteral : public Expr { - llvm::APFloat Value; + APFloatStorage Num; bool IsExact : 1; SourceLocation Loc; -public: - FloatingLiteral(const llvm::APFloat &V, bool isexact, + + FloatingLiteral(ASTContext &C, const llvm::APFloat &V, bool isexact, QualType Type, SourceLocation L) - : Expr(FloatingLiteralClass, Type, false, false), Value(V), - IsExact(isexact), Loc(L) {} + : Expr(FloatingLiteralClass, Type, false, false), + IsExact(isexact), Loc(L) { + setValue(C, V); + } /// \brief Construct an empty floating-point literal. explicit FloatingLiteral(EmptyShell Empty) - : Expr(FloatingLiteralClass, Empty), Value(0.0) { } + : Expr(FloatingLiteralClass, Empty), IsExact(false) { } - const llvm::APFloat &getValue() const { return Value; } - void setValue(const llvm::APFloat &Val) { Value = Val; } +public: + static FloatingLiteral *Create(ASTContext &C, const llvm::APFloat &V, + bool isexact, QualType Type, SourceLocation L); + static FloatingLiteral *Create(ASTContext &C, EmptyShell Empty); + + llvm::APFloat getValue() const { return Num.getValue(); } + void setValue(ASTContext &C, const llvm::APFloat &Val) { + Num.setValue(C, Val); + } bool isExact() const { return IsExact; } void setExact(bool E) { IsExact = E; } @@ -889,9 +986,6 @@ class StringLiteral : public Expr { StringLiteral(QualType Ty) : Expr(StringLiteralClass, Ty, false, false) {} -protected: - virtual void DoDestroy(ASTContext &C); - public: /// This is the "fully general" constructor that allows representation of /// strings formed from multiple concatenated tokens. @@ -912,8 +1006,7 @@ public: llvm::StringRef getString() const { return llvm::StringRef(StrData, ByteLength); } - // FIXME: These are deprecated, replace with StringRef. - const char *getStrData() const { return StrData; } + unsigned getByteLength() const { return ByteLength; } /// \brief Sets the string data to the given string data. @@ -1009,40 +1102,27 @@ public: /// applied to a non-complex value, the former returns its operand and the /// later returns zero in the type of the operand. /// -/// __builtin_offsetof(type, a.b[10]) is represented as a unary operator whose -/// subexpression is a compound literal with the various MemberExpr and -/// ArraySubscriptExpr's applied to it. (This is only used in C) -/// class UnaryOperator : public Expr { public: - // Note that additions to this should also update the StmtVisitor class. - enum Opcode { - PostInc, PostDec, // [C99 6.5.2.4] Postfix increment and decrement operators - PreInc, PreDec, // [C99 6.5.3.1] Prefix increment and decrement operators. - AddrOf, Deref, // [C99 6.5.3.2] Address and indirection operators. - Plus, Minus, // [C99 6.5.3.3] Unary arithmetic operators. - Not, LNot, // [C99 6.5.3.3] Unary arithmetic operators. - Real, Imag, // "__real expr"/"__imag expr" Extension. - Extension, // __extension__ marker. - OffsetOf // __builtin_offsetof - }; + typedef UnaryOperatorKind Opcode; + private: - Stmt *Val; - Opcode Opc; + unsigned Opc : 5; SourceLocation Loc; + Stmt *Val; public: UnaryOperator(Expr *input, Opcode opc, QualType type, SourceLocation l) : Expr(UnaryOperatorClass, type, - input->isTypeDependent() && opc != OffsetOf, + input->isTypeDependent() || type->isDependentType(), input->isValueDependent()), - Val(input), Opc(opc), Loc(l) {} + Opc(opc), Loc(l), Val(input) {} /// \brief Build an empty unary operator. explicit UnaryOperator(EmptyShell Empty) - : Expr(UnaryOperatorClass, Empty), Opc(AddrOf) { } + : Expr(UnaryOperatorClass, Empty), Opc(UO_AddrOf) { } - Opcode getOpcode() const { return Opc; } + Opcode getOpcode() const { return static_cast<Opcode>(Opc); } void setOpcode(Opcode O) { Opc = O; } Expr *getSubExpr() const { return cast<Expr>(Val); } @@ -1054,21 +1134,26 @@ public: /// isPostfix - Return true if this is a postfix operation, like x++. static bool isPostfix(Opcode Op) { - return Op == PostInc || Op == PostDec; + return Op == UO_PostInc || Op == UO_PostDec; } /// isPostfix - Return true if this is a prefix operation, like --x. static bool isPrefix(Opcode Op) { - return Op == PreInc || Op == PreDec; + return Op == UO_PreInc || Op == UO_PreDec; } - bool isPrefix() const { return isPrefix(Opc); } - bool isPostfix() const { return isPostfix(Opc); } - bool isIncrementOp() const {return Opc==PreInc || Opc==PostInc; } - bool isIncrementDecrementOp() const { return Opc>=PostInc && Opc<=PreDec; } - bool isOffsetOfOp() const { return Opc == OffsetOf; } - static bool isArithmeticOp(Opcode Op) { return Op >= Plus && Op <= LNot; } - bool isArithmeticOp() const { return isArithmeticOp(Opc); } + bool isPrefix() const { return isPrefix(getOpcode()); } + bool isPostfix() const { return isPostfix(getOpcode()); } + bool isIncrementOp() const { + return Opc == UO_PreInc || Opc == UO_PostInc; + } + bool isIncrementDecrementOp() const { + return Opc <= UO_PreDec; + } + static bool isArithmeticOp(Opcode Op) { + return Op >= UO_Plus && Op <= UO_LNot; + } + bool isArithmeticOp() const { return isArithmeticOp(getOpcode()); } /// getOpcodeStr - Turn an Opcode enum value into the punctuation char it /// corresponds to, e.g. "sizeof" or "[pre]++" @@ -1310,9 +1395,6 @@ class SizeOfAlignOfExpr : public Expr { } Argument; SourceLocation OpLoc, RParenLoc; -protected: - virtual void DoDestroy(ASTContext& C); - public: SizeOfAlignOfExpr(bool issizeof, TypeSourceInfo *TInfo, QualType resultType, SourceLocation op, @@ -1485,8 +1567,6 @@ protected: CallExpr(ASTContext& C, StmtClass SC, Expr *fn, Expr **args, unsigned numargs, QualType t, SourceLocation rparenloc); - virtual void DoDestroy(ASTContext& C); - public: CallExpr(ASTContext& C, Expr *fn, Expr **args, unsigned numargs, QualType t, SourceLocation rparenloc); @@ -1494,8 +1574,6 @@ public: /// \brief Build an empty call expression. CallExpr(ASTContext &C, StmtClass SC, EmptyShell Empty); - ~CallExpr() {} - const Expr *getCallee() const { return cast<Expr>(SubExprs[FN]); } Expr *getCallee() { return cast<Expr>(SubExprs[FN]); } void setCallee(Expr *F) { SubExprs[FN] = F; } @@ -1594,6 +1672,10 @@ class MemberExpr : public Expr { /// MemberLoc - This is the location of the member name. SourceLocation MemberLoc; + /// MemberDNLoc - Provides source/type location info for the + /// declaration name embedded in MemberDecl. + DeclarationNameLoc MemberDNLoc; + /// IsArrow - True if this is "X->F", false if this is "X.F". bool IsArrow : 1; @@ -1621,37 +1703,33 @@ class MemberExpr : public Expr { return const_cast<MemberExpr *>(this)->getMemberQualifier(); } - /// \brief Retrieve the explicit template argument list that followed the - /// member template name, if any. - ExplicitTemplateArgumentList *getExplicitTemplateArgumentList() { - if (!HasExplicitTemplateArgumentList) - return 0; - - if (!HasQualifierOrFoundDecl) - return reinterpret_cast<ExplicitTemplateArgumentList *>(this + 1); - - return reinterpret_cast<ExplicitTemplateArgumentList *>( - getMemberQualifier() + 1); - } - - /// \brief Retrieve the explicit template argument list that followed the - /// member template name, if any. - const ExplicitTemplateArgumentList *getExplicitTemplateArgumentList() const { - return const_cast<MemberExpr *>(this)->getExplicitTemplateArgumentList(); +public: + MemberExpr(Expr *base, bool isarrow, ValueDecl *memberdecl, + const DeclarationNameInfo &NameInfo, QualType ty) + : Expr(MemberExprClass, ty, + base->isTypeDependent(), base->isValueDependent()), + Base(base), MemberDecl(memberdecl), MemberLoc(NameInfo.getLoc()), + MemberDNLoc(NameInfo.getInfo()), IsArrow(isarrow), + HasQualifierOrFoundDecl(false), HasExplicitTemplateArgumentList(false) { + assert(memberdecl->getDeclName() == NameInfo.getName()); } -public: + // NOTE: this constructor should be used only when it is known that + // the member name can not provide additional syntactic info + // (i.e., source locations for C++ operator names or type source info + // for constructors, destructors and conversion oeprators). MemberExpr(Expr *base, bool isarrow, ValueDecl *memberdecl, SourceLocation l, QualType ty) : Expr(MemberExprClass, ty, base->isTypeDependent(), base->isValueDependent()), - Base(base), MemberDecl(memberdecl), MemberLoc(l), IsArrow(isarrow), + Base(base), MemberDecl(memberdecl), MemberLoc(l), MemberDNLoc(), + IsArrow(isarrow), HasQualifierOrFoundDecl(false), HasExplicitTemplateArgumentList(false) {} static MemberExpr *Create(ASTContext &C, Expr *base, bool isarrow, NestedNameSpecifier *qual, SourceRange qualrange, ValueDecl *memberdecl, DeclAccessPair founddecl, - SourceLocation l, + DeclarationNameInfo MemberNameInfo, const TemplateArgumentListInfo *targs, QualType ty); @@ -1700,15 +1778,42 @@ public: /// \brief Determines whether this member expression actually had a C++ /// template argument list explicitly specified, e.g., x.f<int>. - bool hasExplicitTemplateArgumentList() const { + bool hasExplicitTemplateArgs() const { return HasExplicitTemplateArgumentList; } /// \brief Copies the template arguments (if present) into the given /// structure. void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const { - if (hasExplicitTemplateArgumentList()) - getExplicitTemplateArgumentList()->copyInto(List); + if (hasExplicitTemplateArgs()) + getExplicitTemplateArgs().copyInto(List); + } + + /// \brief Retrieve the explicit template argument list that + /// follow the member template name. This must only be called on an + /// expression with explicit template arguments. + ExplicitTemplateArgumentList &getExplicitTemplateArgs() { + assert(HasExplicitTemplateArgumentList); + if (!HasQualifierOrFoundDecl) + return *reinterpret_cast<ExplicitTemplateArgumentList *>(this + 1); + + return *reinterpret_cast<ExplicitTemplateArgumentList *>( + getMemberQualifier() + 1); + } + + /// \brief Retrieve the explicit template argument list that + /// followed the member template name. This must only be called on + /// an expression with explicit template arguments. + const ExplicitTemplateArgumentList &getExplicitTemplateArgs() const { + return const_cast<MemberExpr *>(this)->getExplicitTemplateArgs(); + } + + /// \brief Retrieves the optional explicit template arguments. + /// This points to the same data as getExplicitTemplateArgs(), but + /// returns null if there are no explicit template arguments. + const ExplicitTemplateArgumentList *getOptionalExplicitTemplateArgs() const { + if (!hasExplicitTemplateArgs()) return 0; + return &getExplicitTemplateArgs(); } /// \brief Retrieve the location of the left angle bracket following the @@ -1717,7 +1822,7 @@ public: if (!HasExplicitTemplateArgumentList) return SourceLocation(); - return getExplicitTemplateArgumentList()->LAngleLoc; + return getExplicitTemplateArgs().LAngleLoc; } /// \brief Retrieve the template arguments provided as part of this @@ -1726,7 +1831,7 @@ public: if (!HasExplicitTemplateArgumentList) return 0; - return getExplicitTemplateArgumentList()->getTemplateArgs(); + return getExplicitTemplateArgs().getTemplateArgs(); } /// \brief Retrieve the number of template arguments provided as part of this @@ -1735,7 +1840,7 @@ public: if (!HasExplicitTemplateArgumentList) return 0; - return getExplicitTemplateArgumentList()->NumTemplateArgs; + return getExplicitTemplateArgs().NumTemplateArgs; } /// \brief Retrieve the location of the right angle bracket following the @@ -1744,7 +1849,13 @@ public: if (!HasExplicitTemplateArgumentList) return SourceLocation(); - return getExplicitTemplateArgumentList()->RAngleLoc; + return getExplicitTemplateArgs().RAngleLoc; + } + + /// \brief Retrieve the member declaration name info. + DeclarationNameInfo getMemberNameInfo() const { + return DeclarationNameInfo(MemberDecl->getDeclName(), + MemberLoc, MemberDNLoc); } bool isArrow() const { return IsArrow; } @@ -1758,9 +1869,8 @@ public: virtual SourceRange getSourceRange() const { // If we have an implicit base (like a C++ implicit this), // make sure not to return its location - SourceLocation EndLoc = MemberLoc; - if (HasExplicitTemplateArgumentList) - EndLoc = getRAngleLoc(); + SourceLocation EndLoc = (HasExplicitTemplateArgumentList) + ? getRAngleLoc() : getMemberNameInfo().getEndLoc(); SourceLocation BaseLoc = getBase()->getLocStart(); if (BaseLoc.isInvalid()) @@ -1843,110 +1953,13 @@ public: /// classes). class CastExpr : public Expr { public: - /// CastKind - the kind of cast this represents. - enum CastKind { - /// CK_Unknown - Unknown cast kind. - /// FIXME: The goal is to get rid of this and make all casts have a - /// kind so that the AST client doesn't have to try to figure out what's - /// going on. - CK_Unknown, - - /// CK_BitCast - Used for reinterpret_cast. - CK_BitCast, - - /// CK_LValueBitCast - Used for reinterpret_cast of expressions to - /// a reference type. - CK_LValueBitCast, - - /// CK_NoOp - Used for const_cast. - CK_NoOp, - - /// CK_BaseToDerived - Base to derived class casts. - CK_BaseToDerived, - - /// CK_DerivedToBase - Derived to base class casts. - CK_DerivedToBase, - - /// CK_UncheckedDerivedToBase - Derived to base class casts that - /// assume that the derived pointer is not null. - CK_UncheckedDerivedToBase, - - /// CK_Dynamic - Dynamic cast. - CK_Dynamic, - - /// CK_ToUnion - Cast to union (GCC extension). - CK_ToUnion, - - /// CK_ArrayToPointerDecay - Array to pointer decay. - CK_ArrayToPointerDecay, - - // CK_FunctionToPointerDecay - Function to pointer decay. - CK_FunctionToPointerDecay, - - /// CK_NullToMemberPointer - Null pointer to member pointer. - CK_NullToMemberPointer, - - /// CK_BaseToDerivedMemberPointer - Member pointer in base class to - /// member pointer in derived class. - CK_BaseToDerivedMemberPointer, - - /// CK_DerivedToBaseMemberPointer - Member pointer in derived class to - /// member pointer in base class. - CK_DerivedToBaseMemberPointer, - - /// CK_UserDefinedConversion - Conversion using a user defined type - /// conversion function. - CK_UserDefinedConversion, - - /// CK_ConstructorConversion - Conversion by constructor - CK_ConstructorConversion, - - /// CK_IntegralToPointer - Integral to pointer - CK_IntegralToPointer, - - /// CK_PointerToIntegral - Pointer to integral - CK_PointerToIntegral, - - /// CK_ToVoid - Cast to void. - CK_ToVoid, - - /// CK_VectorSplat - Casting from an integer/floating type to an extended - /// vector type with the same element type as the src type. Splats the - /// src expression into the destination expression. - CK_VectorSplat, - - /// CK_IntegralCast - Casting between integral types of different size. - CK_IntegralCast, - - /// CK_IntegralToFloating - Integral to floating point. - CK_IntegralToFloating, - - /// CK_FloatingToIntegral - Floating point to integral. - CK_FloatingToIntegral, - - /// CK_FloatingCast - Casting between floating types of different size. - CK_FloatingCast, - - /// CK_MemberPointerToBoolean - Member pointer to boolean - CK_MemberPointerToBoolean, - - /// CK_AnyPointerToObjCPointerCast - Casting any pointer to objective-c - /// pointer - CK_AnyPointerToObjCPointerCast, - /// CK_AnyPointerToBlockPointerCast - Casting any pointer to block - /// pointer - CK_AnyPointerToBlockPointerCast - - }; + typedef clang::CastKind CastKind; private: - CastKind Kind; + unsigned Kind : 5; + unsigned BasePathSize : BitsRemaining - 5; Stmt *Op; - /// BasePath - For derived-to-base and base-to-derived casts, the base array - /// contains the inheritance path. - CXXBaseSpecifierArray BasePath; - void CheckBasePath() const { #ifndef NDEBUG switch (getCastKind()) { @@ -1955,7 +1968,7 @@ private: case CK_DerivedToBaseMemberPointer: case CK_BaseToDerived: case CK_BaseToDerivedMemberPointer: - assert(!BasePath.empty() && "Cast kind should have a base path!"); + assert(!path_empty() && "Cast kind should have a base path!"); break; // These should not have an inheritance path. @@ -1981,15 +1994,21 @@ private: case CK_MemberPointerToBoolean: case CK_AnyPointerToObjCPointerCast: case CK_AnyPointerToBlockPointerCast: - assert(BasePath.empty() && "Cast kind should not have a base path!"); + case CK_ObjCObjectLValueCast: + assert(path_empty() && "Cast kind should not have a base path!"); break; } #endif } + const CXXBaseSpecifier * const *path_buffer() const { + return const_cast<CastExpr*>(this)->path_buffer(); + } + CXXBaseSpecifier **path_buffer(); + protected: CastExpr(StmtClass SC, QualType ty, const CastKind kind, Expr *op, - CXXBaseSpecifierArray BasePath) : + unsigned BasePathSize) : Expr(SC, ty, // Cast expressions are type-dependent if the type is // dependent (C++ [temp.dep.expr]p3). @@ -1997,18 +2016,16 @@ protected: // Cast expressions are value-dependent if the type is // dependent or if the subexpression is value-dependent. ty->isDependentType() || (op && op->isValueDependent())), - Kind(kind), Op(op), BasePath(BasePath) { - CheckBasePath(); - } + Kind(kind), BasePathSize(BasePathSize), Op(op) { + CheckBasePath(); + } /// \brief Construct an empty cast. - CastExpr(StmtClass SC, EmptyShell Empty) - : Expr(SC, Empty) { } - - virtual void DoDestroy(ASTContext &C); + CastExpr(StmtClass SC, EmptyShell Empty, unsigned BasePathSize) + : Expr(SC, Empty), BasePathSize(BasePathSize) { } public: - CastKind getCastKind() const { return Kind; } + CastKind getCastKind() const { return static_cast<CastKind>(Kind); } void setCastKind(CastKind K) { Kind = K; } const char *getCastKindName() const; @@ -2024,8 +2041,16 @@ public: return const_cast<CastExpr *>(this)->getSubExprAsWritten(); } - const CXXBaseSpecifierArray& getBasePath() const { return BasePath; } - CXXBaseSpecifierArray& getBasePath() { return BasePath; } + typedef CXXBaseSpecifier **path_iterator; + typedef const CXXBaseSpecifier * const *path_const_iterator; + bool path_empty() const { return BasePathSize == 0; } + unsigned path_size() const { return BasePathSize; } + path_iterator path_begin() { return path_buffer(); } + path_iterator path_end() { return path_buffer() + path_size(); } + path_const_iterator path_begin() const { return path_buffer(); } + path_const_iterator path_end() const { return path_buffer() + path_size(); } + + void setCastPath(const CXXCastPath &Path); static bool classof(const Stmt *T) { return T->getStmtClass() >= firstCastExprConstant && @@ -2045,38 +2070,57 @@ public: /// /// In C, implicit casts always produce rvalues. However, in C++, an /// implicit cast whose result is being bound to a reference will be -/// an lvalue. For example: +/// an lvalue or xvalue. For example: /// /// @code /// class Base { }; /// class Derived : public Base { }; +/// Derived &&ref(); /// void f(Derived d) { -/// Base& b = d; // initializer is an ImplicitCastExpr to an lvalue of type Base +/// Base& b = d; // initializer is an ImplicitCastExpr +/// // to an lvalue of type Base +/// Base&& r = ref(); // initializer is an ImplicitCastExpr +/// // to an xvalue of type Base /// } /// @endcode class ImplicitCastExpr : public CastExpr { - /// LvalueCast - Whether this cast produces an lvalue. - bool LvalueCast; +private: + ImplicitCastExpr(QualType ty, CastKind kind, Expr *op, + unsigned BasePathLength, ExprValueKind VK) + : CastExpr(ImplicitCastExprClass, ty, kind, op, BasePathLength) { + ValueKind = VK; + } + + /// \brief Construct an empty implicit cast. + explicit ImplicitCastExpr(EmptyShell Shell, unsigned PathSize) + : CastExpr(ImplicitCastExprClass, Shell, PathSize) { } public: - ImplicitCastExpr(QualType ty, CastKind kind, Expr *op, - CXXBaseSpecifierArray BasePath, bool Lvalue) - : CastExpr(ImplicitCastExprClass, ty, kind, op, BasePath), - LvalueCast(Lvalue) { } + enum OnStack_t { OnStack }; + ImplicitCastExpr(OnStack_t _, QualType ty, CastKind kind, Expr *op, + ExprValueKind VK) + : CastExpr(ImplicitCastExprClass, ty, kind, op, 0) { + ValueKind = VK; + } - /// \brief Construct an empty implicit cast. - explicit ImplicitCastExpr(EmptyShell Shell) - : CastExpr(ImplicitCastExprClass, Shell) { } + static ImplicitCastExpr *Create(ASTContext &Context, QualType T, + CastKind Kind, Expr *Operand, + const CXXCastPath *BasePath, + ExprValueKind Cat); + + static ImplicitCastExpr *CreateEmpty(ASTContext &Context, unsigned PathSize); virtual SourceRange getSourceRange() const { return getSubExpr()->getSourceRange(); } - /// isLvalueCast - Whether this cast produces an lvalue. - bool isLvalueCast() const { return LvalueCast; } + /// getValueKind - The value kind that this cast produces. + ExprValueKind getValueKind() const { + return static_cast<ExprValueKind>(ValueKind); + } - /// setLvalueCast - Set whether this cast produces an lvalue. - void setLvalueCast(bool Lvalue) { LvalueCast = Lvalue; } + /// setValueKind - Set the value kind this cast produces. + void setValueKind(ExprValueKind Cat) { ValueKind = Cat; } static bool classof(const Stmt *T) { return T->getStmtClass() == ImplicitCastExprClass; @@ -2098,8 +2142,8 @@ public: /// actual type of the expression as determined by semantic /// analysis. These types may differ slightly. For example, in C++ one /// can cast to a reference type, which indicates that the resulting -/// expression will be an lvalue. The reference type, however, will -/// not be used as the type of the expression. +/// expression will be an lvalue or xvalue. The reference type, however, +/// will not be used as the type of the expression. class ExplicitCastExpr : public CastExpr { /// TInfo - Source type info for the (written) type /// this expression is casting to. @@ -2107,13 +2151,12 @@ class ExplicitCastExpr : public CastExpr { protected: ExplicitCastExpr(StmtClass SC, QualType exprTy, CastKind kind, - Expr *op, CXXBaseSpecifierArray BasePath, - TypeSourceInfo *writtenTy) - : CastExpr(SC, exprTy, kind, op, BasePath), TInfo(writtenTy) {} + Expr *op, unsigned PathSize, TypeSourceInfo *writtenTy) + : CastExpr(SC, exprTy, kind, op, PathSize), TInfo(writtenTy) {} /// \brief Construct an empty explicit cast. - ExplicitCastExpr(StmtClass SC, EmptyShell Shell) - : CastExpr(SC, Shell) { } + ExplicitCastExpr(StmtClass SC, EmptyShell Shell, unsigned PathSize) + : CastExpr(SC, Shell, PathSize) { } public: /// getTypeInfoAsWritten - Returns the type source info for the type @@ -2138,16 +2181,24 @@ public: class CStyleCastExpr : public ExplicitCastExpr { SourceLocation LPLoc; // the location of the left paren SourceLocation RPLoc; // the location of the right paren -public: + CStyleCastExpr(QualType exprTy, CastKind kind, Expr *op, - CXXBaseSpecifierArray BasePath, TypeSourceInfo *writtenTy, + unsigned PathSize, TypeSourceInfo *writtenTy, SourceLocation l, SourceLocation r) - : ExplicitCastExpr(CStyleCastExprClass, exprTy, kind, op, BasePath, + : ExplicitCastExpr(CStyleCastExprClass, exprTy, kind, op, PathSize, writtenTy), LPLoc(l), RPLoc(r) {} /// \brief Construct an empty C-style explicit cast. - explicit CStyleCastExpr(EmptyShell Shell) - : ExplicitCastExpr(CStyleCastExprClass, Shell) { } + explicit CStyleCastExpr(EmptyShell Shell, unsigned PathSize) + : ExplicitCastExpr(CStyleCastExprClass, Shell, PathSize) { } + +public: + static CStyleCastExpr *Create(ASTContext &Context, QualType T, CastKind K, + Expr *Op, const CXXCastPath *BasePath, + TypeSourceInfo *WrittenTy, SourceLocation L, + SourceLocation R); + + static CStyleCastExpr *CreateEmpty(ASTContext &Context, unsigned PathSize); SourceLocation getLParenLoc() const { return LPLoc; } void setLParenLoc(SourceLocation L) { LPLoc = L; } @@ -2184,33 +2235,14 @@ public: /// be used to express the computation. class BinaryOperator : public Expr { public: - enum Opcode { - // Operators listed in order of precedence. - // Note that additions to this should also update the StmtVisitor class. - PtrMemD, PtrMemI, // [C++ 5.5] Pointer-to-member operators. - Mul, Div, Rem, // [C99 6.5.5] Multiplicative operators. - Add, Sub, // [C99 6.5.6] Additive operators. - Shl, Shr, // [C99 6.5.7] Bitwise shift operators. - LT, GT, LE, GE, // [C99 6.5.8] Relational operators. - EQ, NE, // [C99 6.5.9] Equality operators. - And, // [C99 6.5.10] Bitwise AND operator. - Xor, // [C99 6.5.11] Bitwise XOR operator. - Or, // [C99 6.5.12] Bitwise OR operator. - LAnd, // [C99 6.5.13] Logical AND operator. - LOr, // [C99 6.5.14] Logical OR operator. - Assign, MulAssign,// [C99 6.5.16] Assignment operators. - DivAssign, RemAssign, - AddAssign, SubAssign, - ShlAssign, ShrAssign, - AndAssign, XorAssign, - OrAssign, - Comma // [C99 6.5.17] Comma operator. - }; + typedef BinaryOperatorKind Opcode; + private: + unsigned Opc : 6; + SourceLocation OpLoc; + enum { LHS, RHS, END_EXPR }; Stmt* SubExprs[END_EXPR]; - Opcode Opc; - SourceLocation OpLoc; public: BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy, @@ -2227,12 +2259,12 @@ public: /// \brief Construct an empty binary operator. explicit BinaryOperator(EmptyShell Empty) - : Expr(BinaryOperatorClass, Empty), Opc(Comma) { } + : Expr(BinaryOperatorClass, Empty), Opc(BO_Comma) { } SourceLocation getOperatorLoc() const { return OpLoc; } void setOperatorLoc(SourceLocation L) { OpLoc = L; } - Opcode getOpcode() const { return Opc; } + Opcode getOpcode() const { return static_cast<Opcode>(Opc); } void setOpcode(Opcode O) { Opc = O; } Expr *getLHS() const { return cast<Expr>(SubExprs[LHS]); } @@ -2248,6 +2280,8 @@ public: /// corresponds to, e.g. "<<=". static const char *getOpcodeStr(Opcode Op); + const char *getOpcodeStr() const { return getOpcodeStr(getOpcode()); } + /// \brief Retrieve the binary opcode that corresponds to the given /// overloaded operator. static Opcode getOverloadedOpcode(OverloadedOperatorKind OO); @@ -2257,30 +2291,34 @@ public: static OverloadedOperatorKind getOverloadedOperator(Opcode Opc); /// predicates to categorize the respective opcodes. - bool isMultiplicativeOp() const { return Opc >= Mul && Opc <= Rem; } - static bool isAdditiveOp(Opcode Opc) { return Opc == Add || Opc == Sub; } - bool isAdditiveOp() const { return isAdditiveOp(Opc); } - static bool isShiftOp(Opcode Opc) { return Opc == Shl || Opc == Shr; } - bool isShiftOp() const { return isShiftOp(Opc); } + bool isMultiplicativeOp() const { return Opc >= BO_Mul && Opc <= BO_Rem; } + static bool isAdditiveOp(Opcode Opc) { return Opc == BO_Add || Opc==BO_Sub; } + bool isAdditiveOp() const { return isAdditiveOp(getOpcode()); } + static bool isShiftOp(Opcode Opc) { return Opc == BO_Shl || Opc == BO_Shr; } + bool isShiftOp() const { return isShiftOp(getOpcode()); } - static bool isBitwiseOp(Opcode Opc) { return Opc >= And && Opc <= Or; } - bool isBitwiseOp() const { return isBitwiseOp(Opc); } + static bool isBitwiseOp(Opcode Opc) { return Opc >= BO_And && Opc <= BO_Or; } + bool isBitwiseOp() const { return isBitwiseOp(getOpcode()); } - static bool isRelationalOp(Opcode Opc) { return Opc >= LT && Opc <= GE; } - bool isRelationalOp() const { return isRelationalOp(Opc); } + static bool isRelationalOp(Opcode Opc) { return Opc >= BO_LT && Opc<=BO_GE; } + bool isRelationalOp() const { return isRelationalOp(getOpcode()); } - static bool isEqualityOp(Opcode Opc) { return Opc == EQ || Opc == NE; } - bool isEqualityOp() const { return isEqualityOp(Opc); } + static bool isEqualityOp(Opcode Opc) { return Opc == BO_EQ || Opc == BO_NE; } + bool isEqualityOp() const { return isEqualityOp(getOpcode()); } - static bool isComparisonOp(Opcode Opc) { return Opc >= LT && Opc <= NE; } - bool isComparisonOp() const { return isComparisonOp(Opc); } + static bool isComparisonOp(Opcode Opc) { return Opc >= BO_LT && Opc<=BO_NE; } + bool isComparisonOp() const { return isComparisonOp(getOpcode()); } - static bool isLogicalOp(Opcode Opc) { return Opc == LAnd || Opc == LOr; } - bool isLogicalOp() const { return isLogicalOp(Opc); } + static bool isLogicalOp(Opcode Opc) { return Opc == BO_LAnd || Opc==BO_LOr; } + bool isLogicalOp() const { return isLogicalOp(getOpcode()); } - bool isAssignmentOp() const { return Opc >= Assign && Opc <= OrAssign; } - bool isCompoundAssignmentOp() const { return Opc > Assign && Opc <= OrAssign;} - bool isShiftAssignOp() const { return Opc == ShlAssign || Opc == ShrAssign; } + bool isAssignmentOp() const { return Opc >= BO_Assign && Opc <= BO_OrAssign; } + bool isCompoundAssignmentOp() const { + return Opc > BO_Assign && Opc <= BO_OrAssign; + } + bool isShiftAssignOp() const { + return Opc == BO_ShlAssign || Opc == BO_ShrAssign; + } static bool classof(const Stmt *S) { return S->getStmtClass() >= firstBinaryOperatorConstant && @@ -2304,7 +2342,7 @@ protected: } BinaryOperator(StmtClass SC, EmptyShell Empty) - : Expr(SC, Empty), Opc(MulAssign) { } + : Expr(SC, Empty), Opc(BO_MulAssign) { } }; /// CompoundAssignOperator - For compound assignments (e.g. +=), we keep @@ -2353,10 +2391,11 @@ public: class ConditionalOperator : public Expr { enum { COND, LHS, RHS, END_EXPR }; Stmt* SubExprs[END_EXPR]; // Left/Middle/Right hand sides. + Stmt* Save; SourceLocation QuestionLoc, ColonLoc; public: ConditionalOperator(Expr *cond, SourceLocation QLoc, Expr *lhs, - SourceLocation CLoc, Expr *rhs, QualType t) + SourceLocation CLoc, Expr *rhs, Expr *save, QualType t) : Expr(ConditionalOperatorClass, t, // FIXME: the type of the conditional operator doesn't // depend on the type of the conditional, but the standard @@ -2370,6 +2409,7 @@ public: SubExprs[COND] = cond; SubExprs[LHS] = lhs; SubExprs[RHS] = rhs; + Save = save; } /// \brief Build an empty conditional operator. @@ -2382,25 +2422,31 @@ public: void setCond(Expr *E) { SubExprs[COND] = E; } // getTrueExpr - Return the subexpression representing the value of the ?: - // expression if the condition evaluates to true. In most cases this value - // will be the same as getLHS() except a GCC extension allows the left - // subexpression to be omitted, and instead of the condition be returned. - // e.g: x ?: y is shorthand for x ? x : y, except that the expression "x" - // is only evaluated once. + // expression if the condition evaluates to true. Expr *getTrueExpr() const { - return cast<Expr>(SubExprs[LHS] ? SubExprs[LHS] : SubExprs[COND]); + return cast<Expr>(!Save ? SubExprs[LHS] : SubExprs[COND]); } - // getTrueExpr - Return the subexpression representing the value of the ?: + // getFalseExpr - Return the subexpression representing the value of the ?: // expression if the condition evaluates to false. This is the same as getRHS. Expr *getFalseExpr() const { return cast<Expr>(SubExprs[RHS]); } - - Expr *getLHS() const { return cast_or_null<Expr>(SubExprs[LHS]); } + + // getSaveExpr - In most cases this value will be null. Except a GCC extension + // allows the left subexpression to be omitted, and instead of that condition + // be returned. e.g: x ?: y is shorthand for x ? x : y, except that the + // expression "x" is only evaluated once. Under this senario, this function + // returns the original, non-converted condition expression for the ?:operator + Expr *getSaveExpr() const { return Save? cast<Expr>(Save) : (Expr*)0; } + + Expr *getLHS() const { return Save ? 0 : cast<Expr>(SubExprs[LHS]); } void setLHS(Expr *E) { SubExprs[LHS] = E; } Expr *getRHS() const { return cast<Expr>(SubExprs[RHS]); } void setRHS(Expr *E) { SubExprs[RHS] = E; } + Expr *getSAVE() const { return Save? cast<Expr>(Save) : (Expr*)0; } + void setSAVE(Expr *E) { Save = E; } + SourceLocation getQuestionLoc() const { return QuestionLoc; } void setQuestionLoc(SourceLocation L) { QuestionLoc = L; } @@ -2500,23 +2546,27 @@ public: /// expressions) are compatible. The result of this built-in function can be /// used in integer constant expressions. class TypesCompatibleExpr : public Expr { - QualType Type1; - QualType Type2; + TypeSourceInfo *TInfo1; + TypeSourceInfo *TInfo2; SourceLocation BuiltinLoc, RParenLoc; public: TypesCompatibleExpr(QualType ReturnType, SourceLocation BLoc, - QualType t1, QualType t2, SourceLocation RP) : + TypeSourceInfo *tinfo1, TypeSourceInfo *tinfo2, + SourceLocation RP) : Expr(TypesCompatibleExprClass, ReturnType, false, false), - Type1(t1), Type2(t2), BuiltinLoc(BLoc), RParenLoc(RP) {} + TInfo1(tinfo1), TInfo2(tinfo2), BuiltinLoc(BLoc), RParenLoc(RP) {} /// \brief Build an empty __builtin_type_compatible_p expression. explicit TypesCompatibleExpr(EmptyShell Empty) : Expr(TypesCompatibleExprClass, Empty) { } - QualType getArgType1() const { return Type1; } - void setArgType1(QualType T) { Type1 = T; } - QualType getArgType2() const { return Type2; } - void setArgType2(QualType T) { Type2 = T; } + TypeSourceInfo *getArgTInfo1() const { return TInfo1; } + void setArgTInfo1(TypeSourceInfo *TInfo) { TInfo1 = TInfo; } + TypeSourceInfo *getArgTInfo2() const { return TInfo2; } + void setArgTInfo2(TypeSourceInfo *TInfo) { TInfo2 = TInfo; } + + QualType getArgType1() const { return TInfo1->getType(); } + QualType getArgType2() const { return TInfo2->getType(); } SourceLocation getBuiltinLoc() const { return BuiltinLoc; } void setBuiltinLoc(SourceLocation L) { BuiltinLoc = L; } @@ -2553,9 +2603,6 @@ class ShuffleVectorExpr : public Expr { Stmt **SubExprs; unsigned NumExprs; -protected: - virtual void DoDestroy(ASTContext &C); - public: // FIXME: Can a shufflevector be value-dependent? Does type-dependence need // to be computed differently? @@ -2588,8 +2635,6 @@ public: } static bool classof(const ShuffleVectorExpr *) { return true; } - ~ShuffleVectorExpr() {} - /// getNumSubExprs - Return the size of the SubExprs array. This includes the /// constant expression, the actual arguments passed in, and the function /// pointers. @@ -2716,11 +2761,13 @@ public: /// VAArgExpr, used for the builtin function __builtin_va_arg. class VAArgExpr : public Expr { Stmt *Val; + TypeSourceInfo *TInfo; SourceLocation BuiltinLoc, RParenLoc; public: - VAArgExpr(SourceLocation BLoc, Expr* e, QualType t, SourceLocation RPLoc) + VAArgExpr(SourceLocation BLoc, Expr* e, TypeSourceInfo *TInfo, + SourceLocation RPLoc, QualType t) : Expr(VAArgExprClass, t, t->isDependentType(), false), - Val(e), + Val(e), TInfo(TInfo), BuiltinLoc(BLoc), RParenLoc(RPLoc) { } @@ -2731,6 +2778,9 @@ public: Expr *getSubExpr() { return cast<Expr>(Val); } void setSubExpr(Expr *E) { Val = E; } + TypeSourceInfo *getWrittenTypeInfo() const { return TInfo; } + void setWrittenTypeInfo(TypeSourceInfo *TI) { TInfo = TI; } + SourceLocation getBuiltinLoc() const { return BuiltinLoc; } void setBuiltinLoc(SourceLocation L) { BuiltinLoc = L; } @@ -2896,12 +2946,18 @@ public: virtual child_iterator child_end(); typedef InitExprsTy::iterator iterator; + typedef InitExprsTy::const_iterator const_iterator; typedef InitExprsTy::reverse_iterator reverse_iterator; + typedef InitExprsTy::const_reverse_iterator const_reverse_iterator; iterator begin() { return InitExprs.begin(); } + const_iterator begin() const { return InitExprs.begin(); } iterator end() { return InitExprs.end(); } + const_iterator end() const { return InitExprs.end(); } reverse_iterator rbegin() { return InitExprs.rbegin(); } + const_reverse_iterator rbegin() const { return InitExprs.rbegin(); } reverse_iterator rend() { return InitExprs.rend(); } + const_reverse_iterator rend() const { return InitExprs.rend(); } }; /// @brief Represents a C99 designated initializer expression. @@ -2961,11 +3017,6 @@ private: : Expr(DesignatedInitExprClass, EmptyShell()), NumDesignators(0), Designators(0), NumSubExprs(NumSubExprs) { } -protected: - virtual void DoDestroy(ASTContext &C); - - void DestroyDesignators(ASTContext &C); - public: /// A field designator, e.g., ".x". struct FieldDesignator { @@ -3233,15 +3284,10 @@ class ParenListExpr : public Expr { unsigned NumExprs; SourceLocation LParenLoc, RParenLoc; -protected: - virtual void DoDestroy(ASTContext& C); - public: ParenListExpr(ASTContext& C, SourceLocation lparenloc, Expr **exprs, unsigned numexprs, SourceLocation rparenloc); - ~ParenListExpr() {} - /// \brief Build an empty paren list. explicit ParenListExpr(EmptyShell Empty) : Expr(ParenListExprClass, Empty) { } @@ -3274,8 +3320,8 @@ public: virtual child_iterator child_begin(); virtual child_iterator child_end(); - friend class PCHStmtReader; - friend class PCHStmtWriter; + friend class ASTStmtReader; + friend class ASTStmtWriter; }; |