diff options
Diffstat (limited to 'include/clang/AST/Expr.h')
-rw-r--r-- | include/clang/AST/Expr.h | 1158 |
1 files changed, 742 insertions, 416 deletions
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index 48130becf3b5..a17205c2b6b9 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -25,6 +25,7 @@ #include "llvm/ADT/APFloat.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" +#include <cctype> #include <vector> namespace clang { @@ -39,8 +40,10 @@ namespace clang { class CXXBaseSpecifier; class CXXOperatorCallExpr; class CXXMemberCallExpr; + class ObjCPropertyRefExpr; class TemplateArgumentLoc; class TemplateArgumentListInfo; + class OpaqueValueExpr; /// \brief A simple array of base specifiers. typedef llvm::SmallVector<CXXBaseSpecifier*, 4> CXXCastPath; @@ -52,24 +55,14 @@ typedef llvm::SmallVector<CXXBaseSpecifier*, 4> CXXCastPath; class Expr : public Stmt { QualType TR; - virtual void ANCHOR(); // key function. protected: - /// TypeDependent - Whether this expression is type-dependent - /// (C++ [temp.dep.expr]). - bool TypeDependent : 1; - - /// ValueDependent - Whether this expression is value-dependent - /// (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), ValueKind(0) { + Expr(StmtClass SC, QualType T, ExprValueKind VK, ExprObjectKind OK, + bool TD, bool VD, bool ContainsUnexpandedParameterPack) : Stmt(SC) { + ExprBits.TypeDependent = TD; + ExprBits.ValueDependent = VD; + ExprBits.ValueKind = VK; + ExprBits.ObjectKind = OK; + ExprBits.ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack; setType(T); } @@ -77,15 +70,6 @@ protected: explicit Expr(StmtClass SC, EmptyShell) : Stmt(SC) { } public: - /// \brief Increases the reference count for this expression. - /// - /// Invoke the Retain() operation when this expression - /// is being shared by another owner. - Expr *Retain() { - Stmt::Retain(); - return this; - } - QualType getType() const { return TR; } void setType(QualType t) { // In C++, the type of an expression is always adjusted so that it @@ -108,10 +92,10 @@ public: /// @code /// template<int Size, char (&Chars)[Size]> struct meta_string; /// @endcode - bool isValueDependent() const { return ValueDependent; } + bool isValueDependent() const { return ExprBits.ValueDependent; } /// \brief Set whether this expression is value-dependent or not. - void setValueDependent(bool VD) { ValueDependent = VD; } + void setValueDependent(bool VD) { ExprBits.ValueDependent = VD; } /// isTypeDependent - Determines whether this expression is /// type-dependent (C++ [temp.dep.expr]), which means that its type @@ -124,19 +108,38 @@ public: /// x + y; /// } /// @endcode - bool isTypeDependent() const { return TypeDependent; } + bool isTypeDependent() const { return ExprBits.TypeDependent; } /// \brief Set whether this expression is type-dependent or not. - void setTypeDependent(bool TD) { TypeDependent = TD; } + void setTypeDependent(bool TD) { ExprBits.TypeDependent = TD; } + + /// \brief Whether this expression contains an unexpanded parameter + /// pack (for C++0x variadic templates). + /// + /// Given the following function template: + /// + /// \code + /// template<typename F, typename ...Types> + /// void forward(const F &f, Types &&...args) { + /// f(static_cast<Types&&>(args)...); + /// } + /// \endcode + /// + /// The expressions \c args and \c static_cast<Types&&>(args) both + /// contain parameter packs. + bool containsUnexpandedParameterPack() const { + return ExprBits.ContainsUnexpandedParameterPack; + } - /// SourceLocation tokens are not useful in isolation - they are low level - /// value objects created/interpreted by SourceManager. We assume AST - /// clients will have a pointer to the respective SourceManager. - virtual SourceRange getSourceRange() const = 0; + /// \brief Set the bit that describes whether this expression + /// contains an unexpanded parameter pack. + void setContainsUnexpandedParameterPack(bool PP = true) { + ExprBits.ContainsUnexpandedParameterPack = PP; + } /// getExprLoc - Return the preferred location for the arrow when diagnosing /// a problem with a generic expression. - virtual SourceLocation getExprLoc() const { return getLocStart(); } + SourceLocation getExprLoc() const; /// isUnusedResultAWarning - Return true if this immediate expression should /// be warned about if the result is unused. If so, fill in Loc and Ranges @@ -145,19 +148,25 @@ public: bool isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1, SourceRange &R2, ASTContext &Ctx) const; - /// isLvalue - C99 6.3.2.1: an lvalue is an expression with an object type or - /// incomplete type other than void. Nonarray expressions that can be lvalues: - /// - name, where name must be a variable - /// - e[i] - /// - (e), where e must be an lvalue - /// - e.name, where e must be an lvalue - /// - e->name - /// - *e, the type of e cannot be a function type - /// - string-constant - /// - reference type [C++ [expr]] - /// - b ? x : y, where x and y are lvalues of suitable types [C++] + /// isLValue - True if this expression is an "l-value" according to + /// the rules of the current language. C and C++ give somewhat + /// different rules for this concept, but in general, the result of + /// an l-value expression identifies a specific object whereas the + /// result of an r-value expression is a value detached from any + /// specific storage. /// - enum isLvalueResult { + /// C++0x divides the concept of "r-value" into pure r-values + /// ("pr-values") and so-called expiring values ("x-values"), which + /// identify specific objects that can be safely cannibalized for + /// their resources. This is an unfortunate abuse of terminology on + /// the part of the C++ committee. In Clang, when we say "r-value", + /// we generally mean a pr-value. + bool isLValue() const { return getValueKind() == VK_LValue; } + bool isRValue() const { return getValueKind() == VK_RValue; } + bool isXValue() const { return getValueKind() == VK_XValue; } + bool isGLValue() const { return getValueKind() != VK_RValue; } + + enum LValueClassification { LV_Valid, LV_NotObjectType, LV_IncompleteVoidType, @@ -167,7 +176,8 @@ public: LV_SubObjCPropertySetting, LV_ClassTemporary }; - isLvalueResult isLvalue(ASTContext &Ctx) const; + /// Reasons why an expression might not be an l-value. + LValueClassification ClassifyLValue(ASTContext &Ctx) const; /// isModifiableLvalue - C99 6.3.2.1: an lvalue that does not have array type, /// does not have an incomplete type, does not have a const-qualified type, @@ -252,8 +262,14 @@ public: bool isPRValue() const { return Kind >= CL_Function; } bool isRValue() const { return Kind >= CL_XValue; } bool isModifiable() const { return getModifiable() == CM_Modifiable; } + + /// \brief Create a simple, modifiably lvalue + static Classification makeSimpleLValue() { + return Classification(CL_LValue, CM_Modifiable); + } + }; - /// \brief classify - Classify this expression according to the C++0x + /// \brief Classify - Classify this expression according to the C++0x /// expression taxonomy. /// /// C++0x defines ([basic.lval]) a new taxonomy of expressions to replace the @@ -269,7 +285,7 @@ public: return ClassifyImpl(Ctx, 0); } - /// \brief classifyModifiable - Classify this expression according to the + /// \brief ClassifyModifiable - Classify this expression according to the /// C++0x expression taxonomy, and see if it is valid on the left side /// of an assignment. /// @@ -281,6 +297,40 @@ public: return ClassifyImpl(Ctx, &Loc); } + /// getValueKindForType - Given a formal return or parameter type, + /// give its value kind. + static ExprValueKind getValueKindForType(QualType T) { + if (const ReferenceType *RT = T->getAs<ReferenceType>()) + return (isa<LValueReferenceType>(RT) + ? VK_LValue + : (RT->getPointeeType()->isFunctionType() + ? VK_LValue : VK_XValue)); + return VK_RValue; + } + + /// getValueKind - The value kind that this expression produces. + ExprValueKind getValueKind() const { + return static_cast<ExprValueKind>(ExprBits.ValueKind); + } + + /// getObjectKind - The object kind that this expression produces. + /// Object kinds are meaningful only for expressions that yield an + /// l-value or x-value. + ExprObjectKind getObjectKind() const { + return static_cast<ExprObjectKind>(ExprBits.ObjectKind); + } + + bool isOrdinaryOrBitFieldObject() const { + ExprObjectKind OK = getObjectKind(); + return (OK == OK_Ordinary || OK == OK_BitField); + } + + /// setValueKind - Set the value kind produced by this expression. + void setValueKind(ExprValueKind Cat) { ExprBits.ValueKind = Cat; } + + /// setObjectKind - Set the object kind produced by this expression. + void setObjectKind(ExprObjectKind Cat) { ExprBits.ObjectKind = Cat; } + private: Classification ClassifyImpl(ASTContext &Ctx, SourceLocation *Loc) const; @@ -294,6 +344,10 @@ public: return const_cast<Expr*>(this)->getBitField(); } + /// \brief If this expression is an l-value for an Objective C + /// property, find the underlying property reference expression. + const ObjCPropertyRefExpr *getObjCProperty() const; + /// \brief Returns whether this expression refers to a vector element. bool refersToVectorElement() const; @@ -355,33 +409,49 @@ public: /// any crazy technique (that has nothing to do with language standards) that /// we want to. If this function returns true, it returns the folded constant /// in Result. - bool Evaluate(EvalResult &Result, ASTContext &Ctx) const; + bool Evaluate(EvalResult &Result, const ASTContext &Ctx) const; /// EvaluateAsBooleanCondition - Return true if this is a constant /// which we we can fold and convert to a boolean condition using /// any crazy technique that we want to. - bool EvaluateAsBooleanCondition(bool &Result, ASTContext &Ctx) const; + bool EvaluateAsBooleanCondition(bool &Result, const ASTContext &Ctx) const; /// isEvaluatable - Call Evaluate to see if this expression can be constant /// folded, but discard the result. - bool isEvaluatable(ASTContext &Ctx) const; + bool isEvaluatable(const ASTContext &Ctx) const; /// HasSideEffects - This routine returns true for all those expressions - /// which must be evaluated each time and must not be optimization away + /// which must be evaluated each time and must not be optimized away /// or evaluated at compile time. Example is a function call, volatile /// variable read. - bool HasSideEffects(ASTContext &Ctx) const; + bool HasSideEffects(const ASTContext &Ctx) const; /// EvaluateAsInt - Call Evaluate and return the folded integer. This /// must be called on an expression that constant folds to an integer. - llvm::APSInt EvaluateAsInt(ASTContext &Ctx) const; + llvm::APSInt EvaluateAsInt(const ASTContext &Ctx) const; /// EvaluateAsLValue - Evaluate an expression to see if it's a lvalue /// with link time known address. - bool EvaluateAsLValue(EvalResult &Result, ASTContext &Ctx) const; + bool EvaluateAsLValue(EvalResult &Result, const ASTContext &Ctx) const; /// EvaluateAsLValue - Evaluate an expression to see if it's a lvalue. - bool EvaluateAsAnyLValue(EvalResult &Result, ASTContext &Ctx) const; + bool EvaluateAsAnyLValue(EvalResult &Result, const ASTContext &Ctx) const; + + /// \brief Enumeration used to describe the kind of Null pointer constant + /// returned from \c isNullPointerConstant(). + enum NullPointerConstantKind { + /// \brief Expression is not a Null pointer constant. + NPCK_NotNull = 0, + + /// \brief Expression is a Null pointer constant built from a zero integer. + NPCK_ZeroInteger, + + /// \brief Expression is a C++0X nullptr. + NPCK_CXX0X_nullptr, + + /// \brief Expression is a GNU-style __null constant. + NPCK_GNUNull + }; /// \brief Enumeration used to describe how \c isNullPointerConstant() /// should cope with value-dependent expressions. @@ -398,16 +468,30 @@ public: NPC_ValueDependentIsNotNull }; - /// isNullPointerConstant - C99 6.3.2.3p3 - Return true if this is either an - /// integer constant expression with the value zero, or if this is one that is - /// cast to void*. - bool isNullPointerConstant(ASTContext &Ctx, - NullPointerConstantValueDependence NPC) const; + /// isNullPointerConstant - C99 6.3.2.3p3 - Test if this reduces down to + /// a Null pointer constant. The return value can further distinguish the + /// kind of NULL pointer constant that was detected. + NullPointerConstantKind isNullPointerConstant( + ASTContext &Ctx, + NullPointerConstantValueDependence NPC) const; /// isOBJCGCCandidate - Return true if this expression may be used in a read/ /// write barrier. bool isOBJCGCCandidate(ASTContext &Ctx) const; + /// \brief Returns true if this expression is a bound member function. + bool isBoundMemberFunction(ASTContext &Ctx) const; + + /// \brief Result type of CanThrow(). + enum CanThrowResult { + CT_Cannot, + CT_Dependent, + CT_Can + }; + /// \brief Test if this expression, if evaluated, might throw, according to + /// the rules of C++ [expr.unary.noexcept]. + CanThrowResult CanThrow(ASTContext &C) const; + /// IgnoreParens - Ignore parentheses. If this Expr is a ParenExpr, return /// its subexpression. If that subexpression is also a ParenExpr, /// then this method recursively returns its subexpression, and so forth. @@ -422,6 +506,18 @@ public: /// ParenExpr or ImplicitCastExprs, returning their operand. Expr *IgnoreParenImpCasts(); + const Expr *IgnoreParenImpCasts() const { + return const_cast<Expr*>(this)->IgnoreParenImpCasts(); + } + + /// Ignore parentheses and lvalue casts. Strip off any ParenExpr and + /// CastExprs that represent lvalue casts, returning their operand. + Expr *IgnoreParenLValueCasts(); + + const Expr *IgnoreParenLValueCasts() const { + return const_cast<Expr*>(this)->IgnoreParenLValueCasts(); + } + /// IgnoreParenNoopCasts - Ignore parentheses and casts that do not change the /// value (including ptr->int casts of the same size). Strip off any /// ParenExpr or CastExprs, returning their operand. @@ -436,14 +532,9 @@ public: /// the expression is a default argument. bool isDefaultArgument() const; - /// \brief Determine whether this expression directly creates a - /// temporary object (of class type). - bool isTemporaryObject() const { return getTemporaryObject() != 0; } - - /// \brief If this expression directly creates a temporary object of - /// class type, return the expression that actually constructs that - /// temporary object. - const Expr *getTemporaryObject() const; + /// \brief Determine whether the result of this expression is a + /// temporary object of the given class type. + bool isTemporaryObject(ASTContext &Ctx, const CXXRecordDecl *TempTy) const; const Expr *IgnoreParens() const { return const_cast<Expr*>(this)->IgnoreParens(); @@ -470,6 +561,63 @@ public: // Primary Expressions. //===----------------------------------------------------------------------===// +/// OpaqueValueExpr - An expression referring to an opaque object of a +/// fixed type and value class. These don't correspond to concrete +/// syntax; instead they're used to express operations (usually copy +/// operations) on values whose source is generally obvious from +/// context. +class OpaqueValueExpr : public Expr { + friend class ASTStmtReader; + Expr *SourceExpr; + SourceLocation Loc; + +public: + OpaqueValueExpr(SourceLocation Loc, QualType T, ExprValueKind VK, + ExprObjectKind OK = OK_Ordinary) + : Expr(OpaqueValueExprClass, T, VK, OK, + T->isDependentType(), T->isDependentType(), false), + SourceExpr(0), Loc(Loc) { + } + + /// Given an expression which invokes a copy constructor --- i.e. a + /// CXXConstructExpr, possibly wrapped in an ExprWithCleanups --- + /// find the OpaqueValueExpr that's the source of the construction. + static const OpaqueValueExpr *findInCopyConstruct(const Expr *expr); + + explicit OpaqueValueExpr(EmptyShell Empty) + : Expr(OpaqueValueExprClass, Empty) { } + + /// \brief Retrieve the location of this expression. + SourceLocation getLocation() const { return Loc; } + + SourceRange getSourceRange() const { + if (SourceExpr) return SourceExpr->getSourceRange(); + return Loc; + } + SourceLocation getExprLoc() const { + if (SourceExpr) return SourceExpr->getExprLoc(); + return Loc; + } + + child_range children() { return child_range(); } + + /// 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 + /// precisely model the execution behavior of the program. + /// + /// The source expression is typically set when building the + /// expression which binds the opaque value expression in the first + /// place. + Expr *getSourceExpr() const { return SourceExpr; } + void setSourceExpr(Expr *e) { SourceExpr = e; } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OpaqueValueExprClass; + } + static bool classof(const OpaqueValueExpr *) { return true; } +}; + /// \brief Represents the qualifier that may precede a C++ name, e.g., the /// "std::" in "std::sort". struct NameQualifier { @@ -505,6 +653,8 @@ struct ExplicitTemplateArgumentList { } void initializeFrom(const TemplateArgumentListInfo &List); + void initializeFrom(const TemplateArgumentListInfo &List, + bool &Dependent, bool &ContainsUnexpandedParameterPack); void copyInto(TemplateArgumentListInfo &List) const; static std::size_t sizeFor(unsigned NumTemplateArgs); static std::size_t sizeFor(const TemplateArgumentListInfo &List); @@ -551,12 +701,12 @@ class DeclRefExpr : public Expr { DeclRefExpr(NestedNameSpecifier *Qualifier, SourceRange QualifierRange, ValueDecl *D, SourceLocation NameLoc, const TemplateArgumentListInfo *TemplateArgs, - QualType T); + QualType T, ExprValueKind VK); DeclRefExpr(NestedNameSpecifier *Qualifier, SourceRange QualifierRange, ValueDecl *D, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *TemplateArgs, - QualType T); + QualType T, ExprValueKind VK); /// \brief Construct an empty declaration reference expression. explicit DeclRefExpr(EmptyShell Empty) @@ -567,8 +717,9 @@ class DeclRefExpr : public Expr { void computeDependence(); public: - DeclRefExpr(ValueDecl *d, QualType t, SourceLocation l) : - Expr(DeclRefExprClass, t, false, false), DecoratedD(d, 0), Loc(l) { + DeclRefExpr(ValueDecl *d, QualType t, ExprValueKind VK, SourceLocation l) : + Expr(DeclRefExprClass, t, VK, OK_Ordinary, false, false, false), + DecoratedD(d, 0), Loc(l) { computeDependence(); } @@ -577,7 +728,7 @@ public: SourceRange QualifierRange, ValueDecl *D, SourceLocation NameLoc, - QualType T, + QualType T, ExprValueKind VK, const TemplateArgumentListInfo *TemplateArgs = 0); static DeclRefExpr *Create(ASTContext &Context, @@ -585,12 +736,14 @@ public: SourceRange QualifierRange, ValueDecl *D, const DeclarationNameInfo &NameInfo, - QualType T, + QualType T, ExprValueKind VK, const TemplateArgumentListInfo *TemplateArgs = 0); /// \brief Construct an empty declaration reference expression. static DeclRefExpr *CreateEmpty(ASTContext &Context, - bool HasQualifier, unsigned NumTemplateArgs); + bool HasQualifier, + bool HasExplicitTemplateArgs, + unsigned NumTemplateArgs); ValueDecl *getDecl() { return DecoratedD.getPointer(); } const ValueDecl *getDecl() const { return DecoratedD.getPointer(); } @@ -602,7 +755,7 @@ public: SourceLocation getLocation() const { return Loc; } void setLocation(SourceLocation L) { Loc = L; } - virtual SourceRange getSourceRange() const; + SourceRange getSourceRange() const; /// \brief Determine whether this declaration reference was preceded by a /// C++ nested-name-specifier, e.g., \c N::foo. @@ -706,8 +859,7 @@ public: static bool classof(const DeclRefExpr *) { return true; } // Iterators - virtual child_iterator child_begin(); - virtual child_iterator child_end(); + child_range children() { return child_range(); } friend class ASTStmtReader; friend class ASTStmtWriter; @@ -730,8 +882,10 @@ private: IdentType Type; public: PredefinedExpr(SourceLocation l, QualType type, IdentType IT) - : Expr(PredefinedExprClass, type, type->isDependentType(), - type->isDependentType()), Loc(l), Type(IT) {} + : Expr(PredefinedExprClass, type, VK_LValue, OK_Ordinary, + type->isDependentType(), type->isDependentType(), + /*ContainsUnexpandedParameterPack=*/false), + Loc(l), Type(IT) {} /// \brief Construct an empty predefined expression. explicit PredefinedExpr(EmptyShell Empty) @@ -745,7 +899,7 @@ public: static std::string ComputeName(IdentType IT, const Decl *CurrentDecl); - virtual SourceRange getSourceRange() const { return SourceRange(Loc); } + SourceRange getSourceRange() const { return SourceRange(Loc); } static bool classof(const Stmt *T) { return T->getStmtClass() == PredefinedExprClass; @@ -753,8 +907,7 @@ public: static bool classof(const PredefinedExpr *) { return true; } // Iterators - virtual child_iterator child_begin(); - virtual child_iterator child_end(); + child_range children() { return child_range(); } }; /// \brief Used by IntegerLiteral/FloatingLiteral to store the numeric without @@ -817,7 +970,9 @@ public: // or UnsignedLongLongTy IntegerLiteral(ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l) - : Expr(IntegerLiteralClass, type, false, false), Loc(l) { + : Expr(IntegerLiteralClass, type, VK_RValue, OK_Ordinary, false, false, + false), + Loc(l) { assert(type->isIntegerType() && "Illegal type in IntegerLiteral"); setValue(C, V); } @@ -829,7 +984,7 @@ public: static IntegerLiteral *Create(ASTContext &C, EmptyShell Empty); llvm::APInt getValue() const { return Num.getValue(); } - virtual SourceRange getSourceRange() const { return SourceRange(Loc); } + SourceRange getSourceRange() const { return SourceRange(Loc); } /// \brief Retrieve the location of the literal. SourceLocation getLocation() const { return Loc; } @@ -843,8 +998,7 @@ public: static bool classof(const IntegerLiteral *) { return true; } // Iterators - virtual child_iterator child_begin(); - virtual child_iterator child_end(); + child_range children() { return child_range(); } }; class CharacterLiteral : public Expr { @@ -854,8 +1008,9 @@ class CharacterLiteral : public Expr { public: // type should be IntTy CharacterLiteral(unsigned value, bool iswide, QualType type, SourceLocation l) - : Expr(CharacterLiteralClass, type, false, false), Value(value), Loc(l), - IsWide(iswide) { + : Expr(CharacterLiteralClass, type, VK_RValue, OK_Ordinary, false, false, + false), + Value(value), Loc(l), IsWide(iswide) { } /// \brief Construct an empty character literal. @@ -864,7 +1019,7 @@ public: SourceLocation getLocation() const { return Loc; } bool isWide() const { return IsWide; } - virtual SourceRange getSourceRange() const { return SourceRange(Loc); } + SourceRange getSourceRange() const { return SourceRange(Loc); } unsigned getValue() const { return Value; } @@ -878,8 +1033,7 @@ public: static bool classof(const CharacterLiteral *) { return true; } // Iterators - virtual child_iterator child_begin(); - virtual child_iterator child_end(); + child_range children() { return child_range(); } }; class FloatingLiteral : public Expr { @@ -889,7 +1043,8 @@ class FloatingLiteral : public Expr { FloatingLiteral(ASTContext &C, const llvm::APFloat &V, bool isexact, QualType Type, SourceLocation L) - : Expr(FloatingLiteralClass, Type, false, false), + : Expr(FloatingLiteralClass, Type, VK_RValue, OK_Ordinary, false, false, + false), IsExact(isexact), Loc(L) { setValue(C, V); } @@ -919,7 +1074,7 @@ public: SourceLocation getLocation() const { return Loc; } void setLocation(SourceLocation L) { Loc = L; } - virtual SourceRange getSourceRange() const { return SourceRange(Loc); } + SourceRange getSourceRange() const { return SourceRange(Loc); } static bool classof(const Stmt *T) { return T->getStmtClass() == FloatingLiteralClass; @@ -927,8 +1082,7 @@ public: static bool classof(const FloatingLiteral *) { return true; } // Iterators - virtual child_iterator child_begin(); - virtual child_iterator child_end(); + child_range children() { return child_range(); } }; /// ImaginaryLiteral - We support imaginary integer and floating point literals, @@ -940,7 +1094,9 @@ class ImaginaryLiteral : public Expr { Stmt *Val; public: ImaginaryLiteral(Expr *val, QualType Ty) - : Expr(ImaginaryLiteralClass, Ty, false, false), Val(val) {} + : Expr(ImaginaryLiteralClass, Ty, VK_RValue, OK_Ordinary, false, false, + false), + Val(val) {} /// \brief Build an empty imaginary literal. explicit ImaginaryLiteral(EmptyShell Empty) @@ -950,15 +1106,14 @@ public: Expr *getSubExpr() { return cast<Expr>(Val); } void setSubExpr(Expr *E) { Val = E; } - virtual SourceRange getSourceRange() const { return Val->getSourceRange(); } + SourceRange getSourceRange() const { return Val->getSourceRange(); } static bool classof(const Stmt *T) { return T->getStmtClass() == ImaginaryLiteralClass; } static bool classof(const ImaginaryLiteral *) { return true; } // Iterators - virtual child_iterator child_begin(); - virtual child_iterator child_end(); + child_range children() { return child_range(&Val, &Val+1); } }; /// StringLiteral - This represents a string literal expression, e.g. "foo" @@ -984,7 +1139,8 @@ class StringLiteral : public Expr { unsigned NumConcatenated; SourceLocation TokLocs[1]; - StringLiteral(QualType Ty) : Expr(StringLiteralClass, Ty, false, false) {} + StringLiteral(QualType Ty) : + Expr(StringLiteralClass, Ty, VK_LValue, OK_Ordinary, false, false, false) {} public: /// This is the "fully general" constructor that allows representation of @@ -1034,12 +1190,23 @@ public: assert(TokNum < NumConcatenated && "Invalid tok number"); TokLocs[TokNum] = L; } + + /// getLocationOfByte - Return a source location that points to the specified + /// byte of this string literal. + /// + /// Strings are amazingly complex. They can be formed from multiple tokens + /// and can have escape sequences in them in addition to the usual trigraph + /// and escaped newline business. This routine handles this complexity. + /// + SourceLocation getLocationOfByte(unsigned ByteNo, const SourceManager &SM, + const LangOptions &Features, + const TargetInfo &Target) const; typedef const SourceLocation *tokloc_iterator; tokloc_iterator tokloc_begin() const { return TokLocs; } tokloc_iterator tokloc_end() const { return TokLocs+NumConcatenated; } - virtual SourceRange getSourceRange() const { + SourceRange getSourceRange() const { return SourceRange(TokLocs[0], TokLocs[NumConcatenated-1]); } static bool classof(const Stmt *T) { @@ -1048,8 +1215,7 @@ public: static bool classof(const StringLiteral *) { return true; } // Iterators - virtual child_iterator child_begin(); - virtual child_iterator child_end(); + child_range children() { return child_range(); } }; /// ParenExpr - This represents a parethesized expression, e.g. "(1)". This @@ -1060,7 +1226,9 @@ class ParenExpr : public Expr { public: ParenExpr(SourceLocation l, SourceLocation r, Expr *val) : Expr(ParenExprClass, val->getType(), - val->isTypeDependent(), val->isValueDependent()), + val->getValueKind(), val->getObjectKind(), + val->isTypeDependent(), val->isValueDependent(), + val->containsUnexpandedParameterPack()), L(l), R(r), Val(val) {} /// \brief Construct an empty parenthesized expression. @@ -1071,7 +1239,7 @@ public: Expr *getSubExpr() { return cast<Expr>(Val); } void setSubExpr(Expr *E) { Val = E; } - virtual SourceRange getSourceRange() const { return SourceRange(L, R); } + SourceRange getSourceRange() const { return SourceRange(L, R); } /// \brief Get the location of the left parentheses '('. SourceLocation getLParen() const { return L; } @@ -1087,8 +1255,7 @@ public: static bool classof(const ParenExpr *) { return true; } // Iterators - virtual child_iterator child_begin(); - virtual child_iterator child_end(); + child_range children() { return child_range(&Val, &Val+1); } }; @@ -1112,10 +1279,12 @@ private: Stmt *Val; public: - UnaryOperator(Expr *input, Opcode opc, QualType type, SourceLocation l) - : Expr(UnaryOperatorClass, type, + UnaryOperator(Expr *input, Opcode opc, QualType type, + ExprValueKind VK, ExprObjectKind OK, SourceLocation l) + : Expr(UnaryOperatorClass, type, VK, OK, input->isTypeDependent() || type->isDependentType(), - input->isValueDependent()), + input->isValueDependent(), + input->containsUnexpandedParameterPack()), Opc(opc), Loc(l), Val(input) {} /// \brief Build an empty unary operator. @@ -1137,7 +1306,7 @@ public: return Op == UO_PostInc || Op == UO_PostDec; } - /// isPostfix - Return true if this is a prefix operation, like --x. + /// isPrefix - Return true if this is a prefix operation, like --x. static bool isPrefix(Opcode Op) { return Op == UO_PreInc || Op == UO_PreDec; } @@ -1167,13 +1336,13 @@ public: /// the given unary opcode. static OverloadedOperatorKind getOverloadedOperator(Opcode Opc); - virtual SourceRange getSourceRange() const { + SourceRange getSourceRange() const { if (isPostfix()) return SourceRange(Val->getLocStart(), Loc); else return SourceRange(Loc, Val->getLocEnd()); } - virtual SourceLocation getExprLoc() const { return Loc; } + SourceLocation getExprLoc() const { return Loc; } static bool classof(const Stmt *T) { return T->getStmtClass() == UnaryOperatorClass; @@ -1181,8 +1350,7 @@ public: static bool classof(const UnaryOperator *) { return true; } // Iterators - virtual child_iterator child_begin(); - virtual child_iterator child_end(); + child_range children() { return child_range(&Val, &Val+1); } }; /// OffsetOfExpr - [C99 7.17] - This represents an expression of the form @@ -1369,7 +1537,7 @@ public: return NumExprs; } - virtual SourceRange getSourceRange() const { + SourceRange getSourceRange() const { return SourceRange(OperatorLoc, RParenLoc); } @@ -1380,8 +1548,12 @@ public: static bool classof(const OffsetOfExpr *) { return true; } // Iterators - virtual child_iterator child_begin(); - virtual child_iterator child_end(); + child_range children() { + Stmt **begin = + reinterpret_cast<Stmt**>(reinterpret_cast<OffsetOfNode*>(this + 1) + + NumComps); + return child_range(begin, begin + NumExprs); + } }; /// SizeOfAlignOfExpr - [C99 6.5.3.4] - This is for sizeof/alignof, both of @@ -1399,10 +1571,11 @@ public: SizeOfAlignOfExpr(bool issizeof, TypeSourceInfo *TInfo, QualType resultType, SourceLocation op, SourceLocation rp) : - Expr(SizeOfAlignOfExprClass, resultType, + Expr(SizeOfAlignOfExprClass, resultType, VK_RValue, OK_Ordinary, false, // Never type-dependent (C++ [temp.dep.expr]p3). // Value-dependent if the argument is type-dependent. - TInfo->getType()->isDependentType()), + TInfo->getType()->isDependentType(), + TInfo->getType()->containsUnexpandedParameterPack()), isSizeof(issizeof), isType(true), OpLoc(op), RParenLoc(rp) { Argument.Ty = TInfo; } @@ -1410,10 +1583,11 @@ public: SizeOfAlignOfExpr(bool issizeof, Expr *E, QualType resultType, SourceLocation op, SourceLocation rp) : - Expr(SizeOfAlignOfExprClass, resultType, + Expr(SizeOfAlignOfExprClass, resultType, VK_RValue, OK_Ordinary, false, // Never type-dependent (C++ [temp.dep.expr]p3). // Value-dependent if the argument is type-dependent. - E->isTypeDependent()), + E->isTypeDependent(), + E->containsUnexpandedParameterPack()), isSizeof(issizeof), isType(false), OpLoc(op), RParenLoc(rp) { Argument.Ex = E; } @@ -1459,7 +1633,7 @@ public: SourceLocation getRParenLoc() const { return RParenLoc; } void setRParenLoc(SourceLocation L) { RParenLoc = L; } - virtual SourceRange getSourceRange() const { + SourceRange getSourceRange() const { return SourceRange(OpLoc, RParenLoc); } @@ -1469,8 +1643,7 @@ public: static bool classof(const SizeOfAlignOfExpr *) { return true; } // Iterators - virtual child_iterator child_begin(); - virtual child_iterator child_end(); + child_range children(); }; //===----------------------------------------------------------------------===// @@ -1484,10 +1657,13 @@ class ArraySubscriptExpr : public Expr { SourceLocation RBracketLoc; public: ArraySubscriptExpr(Expr *lhs, Expr *rhs, QualType t, + ExprValueKind VK, ExprObjectKind OK, SourceLocation rbracketloc) - : Expr(ArraySubscriptExprClass, t, + : Expr(ArraySubscriptExprClass, t, VK, OK, lhs->isTypeDependent() || rhs->isTypeDependent(), - lhs->isValueDependent() || rhs->isValueDependent()), + lhs->isValueDependent() || rhs->isValueDependent(), + (lhs->containsUnexpandedParameterPack() || + rhs->containsUnexpandedParameterPack())), RBracketLoc(rbracketloc) { SubExprs[LHS] = lhs; SubExprs[RHS] = rhs; @@ -1530,14 +1706,14 @@ public: return cast<Expr>(getRHS()->getType()->isIntegerType() ? getRHS():getLHS()); } - virtual SourceRange getSourceRange() const { + SourceRange getSourceRange() const { return SourceRange(getLHS()->getLocStart(), RBracketLoc); } SourceLocation getRBracketLoc() const { return RBracketLoc; } void setRBracketLoc(SourceLocation L) { RBracketLoc = L; } - virtual SourceLocation getExprLoc() const { return getBase()->getExprLoc(); } + SourceLocation getExprLoc() const { return getBase()->getExprLoc(); } static bool classof(const Stmt *T) { return T->getStmtClass() == ArraySubscriptExprClass; @@ -1545,8 +1721,9 @@ public: static bool classof(const ArraySubscriptExpr *) { return true; } // Iterators - virtual child_iterator child_begin(); - virtual child_iterator child_end(); + child_range children() { + return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR); + } }; @@ -1557,19 +1734,36 @@ public: /// a subclass for overloaded operator calls that use operator syntax, e.g., /// "str1 + str2" to resolve to a function call. class CallExpr : public Expr { - enum { FN=0, ARGS_START=1 }; + enum { FN=0, PREARGS_START=1 }; Stmt **SubExprs; unsigned NumArgs; SourceLocation RParenLoc; protected: - // This version of the constructor is for derived classes. - CallExpr(ASTContext& C, StmtClass SC, Expr *fn, Expr **args, unsigned numargs, - QualType t, SourceLocation rparenloc); + // These versions of the constructor are for derived classes. + CallExpr(ASTContext& C, StmtClass SC, Expr *fn, unsigned NumPreArgs, + Expr **args, unsigned numargs, QualType t, ExprValueKind VK, + SourceLocation rparenloc); + CallExpr(ASTContext &C, StmtClass SC, unsigned NumPreArgs, EmptyShell Empty); + + Stmt *getPreArg(unsigned i) { + assert(i < getNumPreArgs() && "Prearg access out of range!"); + return SubExprs[PREARGS_START+i]; + } + const Stmt *getPreArg(unsigned i) const { + assert(i < getNumPreArgs() && "Prearg access out of range!"); + return SubExprs[PREARGS_START+i]; + } + void setPreArg(unsigned i, Stmt *PreArg) { + assert(i < getNumPreArgs() && "Prearg access out of range!"); + SubExprs[PREARGS_START+i] = PreArg; + } + + unsigned getNumPreArgs() const { return CallExprBits.NumPreArgs; } public: CallExpr(ASTContext& C, Expr *fn, Expr **args, unsigned numargs, QualType t, - SourceLocation rparenloc); + ExprValueKind VK, SourceLocation rparenloc); /// \brief Build an empty call expression. CallExpr(ASTContext &C, StmtClass SC, EmptyShell Empty); @@ -1593,20 +1787,25 @@ public: /// unsigned getNumArgs() const { return NumArgs; } + /// \brief Retrieve the call arguments. + Expr **getArgs() { + return reinterpret_cast<Expr **>(SubExprs+getNumPreArgs()+PREARGS_START); + } + /// getArg - Return the specified argument. Expr *getArg(unsigned Arg) { assert(Arg < NumArgs && "Arg access out of range!"); - return cast<Expr>(SubExprs[Arg+ARGS_START]); + return cast<Expr>(SubExprs[Arg+getNumPreArgs()+PREARGS_START]); } const Expr *getArg(unsigned Arg) const { assert(Arg < NumArgs && "Arg access out of range!"); - return cast<Expr>(SubExprs[Arg+ARGS_START]); + return cast<Expr>(SubExprs[Arg+getNumPreArgs()+PREARGS_START]); } /// setArg - Set the specified argument. void setArg(unsigned Arg, Expr *ArgExpr) { assert(Arg < NumArgs && "Arg access out of range!"); - SubExprs[Arg+ARGS_START] = ArgExpr; + SubExprs[Arg+getNumPreArgs()+PREARGS_START] = ArgExpr; } /// setNumArgs - This changes the number of arguments present in this call. @@ -1617,10 +1816,16 @@ public: typedef ExprIterator arg_iterator; typedef ConstExprIterator const_arg_iterator; - arg_iterator arg_begin() { return SubExprs+ARGS_START; } - arg_iterator arg_end() { return SubExprs+ARGS_START+getNumArgs(); } - const_arg_iterator arg_begin() const { return SubExprs+ARGS_START; } - const_arg_iterator arg_end() const { return SubExprs+ARGS_START+getNumArgs();} + arg_iterator arg_begin() { return SubExprs+PREARGS_START+getNumPreArgs(); } + arg_iterator arg_end() { + return SubExprs+PREARGS_START+getNumPreArgs()+getNumArgs(); + } + const_arg_iterator arg_begin() const { + return SubExprs+PREARGS_START+getNumPreArgs(); + } + const_arg_iterator arg_end() const { + return SubExprs+PREARGS_START+getNumPreArgs()+getNumArgs(); + } /// getNumCommas - Return the number of commas that must have been present in /// this function call. @@ -1628,7 +1833,7 @@ public: /// isBuiltinCall - If this is a call to a builtin, return the builtin ID. If /// not, return 0. - unsigned isBuiltinCall(ASTContext &Context) const; + unsigned isBuiltinCall(const ASTContext &Context) const; /// getCallReturnType - Get the return type of the call expr. This is not /// always the type of the expr itself, if the return type is a reference @@ -1638,7 +1843,7 @@ public: SourceLocation getRParenLoc() const { return RParenLoc; } void setRParenLoc(SourceLocation L) { RParenLoc = L; } - virtual SourceRange getSourceRange() const { + SourceRange getSourceRange() const { return SourceRange(getCallee()->getLocStart(), RParenLoc); } @@ -1649,8 +1854,10 @@ public: static bool classof(const CallExpr *) { return true; } // Iterators - virtual child_iterator child_begin(); - virtual child_iterator child_end(); + child_range children() { + return child_range(&SubExprs[0], + &SubExprs[0]+NumArgs+getNumPreArgs()+PREARGS_START); + } }; /// MemberExpr - [C99 6.5.2.3] Structure and Union Members. X->F and X.F. @@ -1705,9 +1912,11 @@ class MemberExpr : public Expr { public: MemberExpr(Expr *base, bool isarrow, ValueDecl *memberdecl, - const DeclarationNameInfo &NameInfo, QualType ty) - : Expr(MemberExprClass, ty, - base->isTypeDependent(), base->isValueDependent()), + const DeclarationNameInfo &NameInfo, QualType ty, + ExprValueKind VK, ExprObjectKind OK) + : Expr(MemberExprClass, ty, VK, OK, + base->isTypeDependent(), base->isValueDependent(), + base->containsUnexpandedParameterPack()), Base(base), MemberDecl(memberdecl), MemberLoc(NameInfo.getLoc()), MemberDNLoc(NameInfo.getInfo()), IsArrow(isarrow), HasQualifierOrFoundDecl(false), HasExplicitTemplateArgumentList(false) { @@ -1719,9 +1928,11 @@ public: // (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()), + SourceLocation l, QualType ty, + ExprValueKind VK, ExprObjectKind OK) + : Expr(MemberExprClass, ty, VK, OK, + base->isTypeDependent(), base->isValueDependent(), + base->containsUnexpandedParameterPack()), Base(base), MemberDecl(memberdecl), MemberLoc(l), MemberDNLoc(), IsArrow(isarrow), HasQualifierOrFoundDecl(false), HasExplicitTemplateArgumentList(false) {} @@ -1731,7 +1942,7 @@ public: ValueDecl *memberdecl, DeclAccessPair founddecl, DeclarationNameInfo MemberNameInfo, const TemplateArgumentListInfo *targs, - QualType ty); + QualType ty, ExprValueKind VK, ExprObjectKind OK); void setBase(Expr *E) { Base = E; } Expr *getBase() const { return cast<Expr>(Base); } @@ -1866,7 +2077,7 @@ public: SourceLocation getMemberLoc() const { return MemberLoc; } void setMemberLoc(SourceLocation L) { MemberLoc = L; } - virtual SourceRange getSourceRange() const { + SourceRange getSourceRange() const { // If we have an implicit base (like a C++ implicit this), // make sure not to return its location SourceLocation EndLoc = (HasExplicitTemplateArgumentList) @@ -1878,7 +2089,7 @@ public: return SourceRange(BaseLoc, EndLoc); } - virtual SourceLocation getExprLoc() const { return MemberLoc; } + SourceLocation getExprLoc() const { return MemberLoc; } static bool classof(const Stmt *T) { return T->getStmtClass() == MemberExprClass; @@ -1886,8 +2097,10 @@ public: static bool classof(const MemberExpr *) { return true; } // Iterators - virtual child_iterator child_begin(); - virtual child_iterator child_end(); + child_range children() { return child_range(&Base, &Base+1); } + + friend class ASTReader; + friend class ASTStmtWriter; }; /// CompoundLiteralExpr - [C99 6.5.2.5] @@ -1904,11 +2117,12 @@ class CompoundLiteralExpr : public Expr { Stmt *Init; bool FileScope; public: - // FIXME: Can compound literals be value-dependent? CompoundLiteralExpr(SourceLocation lparenloc, TypeSourceInfo *tinfo, - QualType T, Expr *init, bool fileScope) - : Expr(CompoundLiteralExprClass, T, - tinfo->getType()->isDependentType(), false), + QualType T, ExprValueKind VK, Expr *init, bool fileScope) + : Expr(CompoundLiteralExprClass, T, VK, OK_Ordinary, + tinfo->getType()->isDependentType(), + init->isValueDependent(), + init->containsUnexpandedParameterPack()), LParenLoc(lparenloc), TInfo(tinfo), Init(init), FileScope(fileScope) {} /// \brief Construct an empty compound literal. @@ -1928,7 +2142,7 @@ public: TypeSourceInfo *getTypeSourceInfo() const { return TInfo; } void setTypeSourceInfo(TypeSourceInfo* tinfo) { TInfo = tinfo; } - virtual SourceRange getSourceRange() const { + SourceRange getSourceRange() const { // FIXME: Init should never be null. if (!Init) return SourceRange(); @@ -1943,8 +2157,7 @@ public: static bool classof(const CompoundLiteralExpr *) { return true; } // Iterators - virtual child_iterator child_begin(); - virtual child_iterator child_end(); + child_range children() { return child_range(&Init, &Init+1); } }; /// CastExpr - Base class for type casts, including both implicit @@ -1956,11 +2169,9 @@ public: typedef clang::CastKind CastKind; private: - unsigned Kind : 5; - unsigned BasePathSize : BitsRemaining - 5; Stmt *Op; - void CheckBasePath() const { + void CheckCastConsistency() const { #ifndef NDEBUG switch (getCastKind()) { case CK_DerivedToBase: @@ -1972,16 +2183,13 @@ private: break; // These should not have an inheritance path. - case CK_Unknown: case CK_BitCast: - case CK_LValueBitCast: - case CK_NoOp: case CK_Dynamic: case CK_ToUnion: case CK_ArrayToPointerDecay: case CK_FunctionToPointerDecay: case CK_NullToMemberPointer: - case CK_UserDefinedConversion: + case CK_NullToPointer: case CK_ConstructorConversion: case CK_IntegralToPointer: case CK_PointerToIntegral: @@ -1991,10 +2199,32 @@ private: case CK_IntegralToFloating: case CK_FloatingToIntegral: case CK_FloatingCast: - case CK_MemberPointerToBoolean: case CK_AnyPointerToObjCPointerCast: case CK_AnyPointerToBlockPointerCast: case CK_ObjCObjectLValueCast: + case CK_FloatingRealToComplex: + case CK_FloatingComplexToReal: + case CK_FloatingComplexCast: + case CK_FloatingComplexToIntegralComplex: + case CK_IntegralRealToComplex: + case CK_IntegralComplexToReal: + case CK_IntegralComplexCast: + case CK_IntegralComplexToFloatingComplex: + assert(!getType()->isBooleanType() && "unheralded conversion to bool"); + // fallthrough to check for null base path + + case CK_Dependent: + case CK_LValueToRValue: + case CK_GetObjCProperty: + case CK_NoOp: + case CK_PointerToBoolean: + case CK_IntegralToBoolean: + case CK_FloatingToBoolean: + case CK_MemberPointerToBoolean: + case CK_FloatingComplexToBoolean: + case CK_IntegralComplexToBoolean: + case CK_LValueBitCast: // -> bool& + case CK_UserDefinedConversion: // operator bool() assert(path_empty() && "Cast kind should not have a base path!"); break; } @@ -2007,26 +2237,33 @@ private: CXXBaseSpecifier **path_buffer(); protected: - CastExpr(StmtClass SC, QualType ty, const CastKind kind, Expr *op, - unsigned BasePathSize) : - Expr(SC, ty, + CastExpr(StmtClass SC, QualType ty, ExprValueKind VK, + const CastKind kind, Expr *op, unsigned BasePathSize) : + Expr(SC, ty, VK, OK_Ordinary, // Cast expressions are type-dependent if the type is // dependent (C++ [temp.dep.expr]p3). ty->isDependentType(), // Cast expressions are value-dependent if the type is // dependent or if the subexpression is value-dependent. - ty->isDependentType() || (op && op->isValueDependent())), - Kind(kind), BasePathSize(BasePathSize), Op(op) { - CheckBasePath(); + ty->isDependentType() || (op && op->isValueDependent()), + (ty->containsUnexpandedParameterPack() || + op->containsUnexpandedParameterPack())), + Op(op) { + assert(kind != CK_Invalid && "creating cast with invalid cast kind"); + CastExprBits.Kind = kind; + CastExprBits.BasePathSize = BasePathSize; + CheckCastConsistency(); } /// \brief Construct an empty cast. CastExpr(StmtClass SC, EmptyShell Empty, unsigned BasePathSize) - : Expr(SC, Empty), BasePathSize(BasePathSize) { } + : Expr(SC, Empty) { + CastExprBits.BasePathSize = BasePathSize; + } public: - CastKind getCastKind() const { return static_cast<CastKind>(Kind); } - void setCastKind(CastKind K) { Kind = K; } + CastKind getCastKind() const { return (CastKind) CastExprBits.Kind; } + void setCastKind(CastKind K) { CastExprBits.Kind = K; } const char *getCastKindName() const; Expr *getSubExpr() { return cast<Expr>(Op); } @@ -2043,8 +2280,8 @@ public: typedef CXXBaseSpecifier **path_iterator; typedef const CXXBaseSpecifier * const *path_const_iterator; - bool path_empty() const { return BasePathSize == 0; } - unsigned path_size() const { return BasePathSize; } + bool path_empty() const { return CastExprBits.BasePathSize == 0; } + unsigned path_size() const { return CastExprBits.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(); } @@ -2059,8 +2296,7 @@ public: static bool classof(const CastExpr *) { return true; } // Iterators - virtual child_iterator child_begin(); - virtual child_iterator child_end(); + child_range children() { return child_range(&Op, &Op+1); } }; /// ImplicitCastExpr - Allows us to explicitly represent implicit type @@ -2087,8 +2323,7 @@ class ImplicitCastExpr : public CastExpr { private: ImplicitCastExpr(QualType ty, CastKind kind, Expr *op, unsigned BasePathLength, ExprValueKind VK) - : CastExpr(ImplicitCastExprClass, ty, kind, op, BasePathLength) { - ValueKind = VK; + : CastExpr(ImplicitCastExprClass, ty, VK, kind, op, BasePathLength) { } /// \brief Construct an empty implicit cast. @@ -2099,8 +2334,7 @@ public: enum OnStack_t { OnStack }; ImplicitCastExpr(OnStack_t _, QualType ty, CastKind kind, Expr *op, ExprValueKind VK) - : CastExpr(ImplicitCastExprClass, ty, kind, op, 0) { - ValueKind = VK; + : CastExpr(ImplicitCastExprClass, ty, VK, kind, op, 0) { } static ImplicitCastExpr *Create(ASTContext &Context, QualType T, @@ -2110,18 +2344,10 @@ public: static ImplicitCastExpr *CreateEmpty(ASTContext &Context, unsigned PathSize); - virtual SourceRange getSourceRange() const { + SourceRange getSourceRange() const { return getSubExpr()->getSourceRange(); } - /// getValueKind - The value kind that this cast produces. - ExprValueKind getValueKind() const { - return static_cast<ExprValueKind>(ValueKind); - } - - /// setValueKind - Set the value kind this cast produces. - void setValueKind(ExprValueKind Cat) { ValueKind = Cat; } - static bool classof(const Stmt *T) { return T->getStmtClass() == ImplicitCastExprClass; } @@ -2150,9 +2376,10 @@ class ExplicitCastExpr : public CastExpr { TypeSourceInfo *TInfo; protected: - ExplicitCastExpr(StmtClass SC, QualType exprTy, CastKind kind, - Expr *op, unsigned PathSize, TypeSourceInfo *writtenTy) - : CastExpr(SC, exprTy, kind, op, PathSize), TInfo(writtenTy) {} + ExplicitCastExpr(StmtClass SC, QualType exprTy, ExprValueKind VK, + CastKind kind, Expr *op, unsigned PathSize, + TypeSourceInfo *writtenTy) + : CastExpr(SC, exprTy, VK, kind, op, PathSize), TInfo(writtenTy) {} /// \brief Construct an empty explicit cast. ExplicitCastExpr(StmtClass SC, EmptyShell Shell, unsigned PathSize) @@ -2182,10 +2409,10 @@ class CStyleCastExpr : public ExplicitCastExpr { SourceLocation LPLoc; // the location of the left paren SourceLocation RPLoc; // the location of the right paren - CStyleCastExpr(QualType exprTy, CastKind kind, Expr *op, + CStyleCastExpr(QualType exprTy, ExprValueKind vk, CastKind kind, Expr *op, unsigned PathSize, TypeSourceInfo *writtenTy, SourceLocation l, SourceLocation r) - : ExplicitCastExpr(CStyleCastExprClass, exprTy, kind, op, PathSize, + : ExplicitCastExpr(CStyleCastExprClass, exprTy, vk, kind, op, PathSize, writtenTy), LPLoc(l), RPLoc(r) {} /// \brief Construct an empty C-style explicit cast. @@ -2193,7 +2420,8 @@ class CStyleCastExpr : public ExplicitCastExpr { : ExplicitCastExpr(CStyleCastExprClass, Shell, PathSize) { } public: - static CStyleCastExpr *Create(ASTContext &Context, QualType T, CastKind K, + static CStyleCastExpr *Create(ASTContext &Context, QualType T, + ExprValueKind VK, CastKind K, Expr *Op, const CXXCastPath *BasePath, TypeSourceInfo *WrittenTy, SourceLocation L, SourceLocation R); @@ -2206,7 +2434,7 @@ public: SourceLocation getRParenLoc() const { return RPLoc; } void setRParenLoc(SourceLocation L) { RPLoc = L; } - virtual SourceRange getSourceRange() const { + SourceRange getSourceRange() const { return SourceRange(LPLoc, getSubExpr()->getSourceRange().getEnd()); } static bool classof(const Stmt *T) { @@ -2246,10 +2474,13 @@ private: public: BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy, + ExprValueKind VK, ExprObjectKind OK, SourceLocation opLoc) - : Expr(BinaryOperatorClass, ResTy, + : Expr(BinaryOperatorClass, ResTy, VK, OK, lhs->isTypeDependent() || rhs->isTypeDependent(), - lhs->isValueDependent() || rhs->isValueDependent()), + lhs->isValueDependent() || rhs->isValueDependent(), + (lhs->containsUnexpandedParameterPack() || + rhs->containsUnexpandedParameterPack())), Opc(opc), OpLoc(opLoc) { SubExprs[LHS] = lhs; SubExprs[RHS] = rhs; @@ -2272,7 +2503,7 @@ public: Expr *getRHS() const { return cast<Expr>(SubExprs[RHS]); } void setRHS(Expr *E) { SubExprs[RHS] = E; } - virtual SourceRange getSourceRange() const { + SourceRange getSourceRange() const { return SourceRange(getLHS()->getLocStart(), getRHS()->getLocEnd()); } @@ -2291,6 +2522,7 @@ public: static OverloadedOperatorKind getOverloadedOperator(Opcode Opc); /// predicates to categorize the respective opcodes. + bool isPtrMemOp() const { return Opc == BO_PtrMemD || Opc == BO_PtrMemI; } 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()); } @@ -2312,13 +2544,24 @@ public: static bool isLogicalOp(Opcode Opc) { return Opc == BO_LAnd || Opc==BO_LOr; } bool isLogicalOp() const { return isLogicalOp(getOpcode()); } - bool isAssignmentOp() const { return Opc >= BO_Assign && Opc <= BO_OrAssign; } - bool isCompoundAssignmentOp() const { + static bool isAssignmentOp(Opcode Opc) { + return Opc >= BO_Assign && Opc <= BO_OrAssign; + } + bool isAssignmentOp() const { return isAssignmentOp(getOpcode()); } + + static bool isCompoundAssignmentOp(Opcode Opc) { return Opc > BO_Assign && Opc <= BO_OrAssign; } - bool isShiftAssignOp() const { + bool isCompoundAssignmentOp() const { + return isCompoundAssignmentOp(getOpcode()); + } + + static bool isShiftAssignOp(Opcode Opc) { return Opc == BO_ShlAssign || Opc == BO_ShrAssign; } + bool isShiftAssignOp() const { + return isShiftAssignOp(getOpcode()); + } static bool classof(const Stmt *S) { return S->getStmtClass() >= firstBinaryOperatorConstant && @@ -2327,15 +2570,19 @@ public: static bool classof(const BinaryOperator *) { return true; } // Iterators - virtual child_iterator child_begin(); - virtual child_iterator child_end(); + child_range children() { + return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR); + } protected: BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy, + ExprValueKind VK, ExprObjectKind OK, SourceLocation opLoc, bool dead) - : Expr(CompoundAssignOperatorClass, ResTy, + : Expr(CompoundAssignOperatorClass, ResTy, VK, OK, lhs->isTypeDependent() || rhs->isTypeDependent(), - lhs->isValueDependent() || rhs->isValueDependent()), + lhs->isValueDependent() || rhs->isValueDependent(), + (lhs->containsUnexpandedParameterPack() || + rhs->containsUnexpandedParameterPack())), Opc(opc), OpLoc(opLoc) { SubExprs[LHS] = lhs; SubExprs[RHS] = rhs; @@ -2355,11 +2602,11 @@ class CompoundAssignOperator : public BinaryOperator { QualType ComputationLHSType; QualType ComputationResultType; public: - CompoundAssignOperator(Expr *lhs, Expr *rhs, Opcode opc, - QualType ResType, QualType CompLHSType, - QualType CompResultType, + CompoundAssignOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResType, + ExprValueKind VK, ExprObjectKind OK, + QualType CompLHSType, QualType CompResultType, SourceLocation OpLoc) - : BinaryOperator(lhs, rhs, opc, ResType, OpLoc, true), + : BinaryOperator(lhs, rhs, opc, ResType, VK, OK, OpLoc, true), ComputationLHSType(CompLHSType), ComputationResultType(CompResultType) { assert(isCompoundAssignmentOp() && @@ -2385,75 +2632,97 @@ public: } }; -/// ConditionalOperator - The ?: operator. Note that LHS may be null when the -/// GNU "missing LHS" extension is in use. -/// -class ConditionalOperator : public Expr { +/// AbstractConditionalOperator - An abstract base class for +/// ConditionalOperator and BinaryConditionalOperator. +class AbstractConditionalOperator : public Expr { + SourceLocation QuestionLoc, ColonLoc; + friend class ASTStmtReader; + +protected: + AbstractConditionalOperator(StmtClass SC, QualType T, + ExprValueKind VK, ExprObjectKind OK, + bool TD, bool VD, + bool ContainsUnexpandedParameterPack, + SourceLocation qloc, + SourceLocation cloc) + : Expr(SC, T, VK, OK, TD, VD, ContainsUnexpandedParameterPack), + QuestionLoc(qloc), ColonLoc(cloc) {} + + AbstractConditionalOperator(StmtClass SC, EmptyShell Empty) + : Expr(SC, Empty) { } + +public: + // getCond - Return the expression representing the condition for + // the ?: operator. + Expr *getCond() const; + + // getTrueExpr - Return the subexpression representing the value of + // the expression if the condition evaluates to true. + Expr *getTrueExpr() const; + + // 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; + + SourceLocation getQuestionLoc() const { return QuestionLoc; } + SourceLocation getColonLoc() const { return ColonLoc; } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == ConditionalOperatorClass || + T->getStmtClass() == BinaryConditionalOperatorClass; + } + static bool classof(const AbstractConditionalOperator *) { return true; } +}; + +/// ConditionalOperator - The ?: ternary operator. The GNU "missing +/// middle" extension is a BinaryConditionalOperator. +class ConditionalOperator : public AbstractConditionalOperator { enum { COND, LHS, RHS, END_EXPR }; Stmt* SubExprs[END_EXPR]; // Left/Middle/Right hand sides. - Stmt* Save; - SourceLocation QuestionLoc, ColonLoc; + + friend class ASTStmtReader; public: ConditionalOperator(Expr *cond, SourceLocation QLoc, Expr *lhs, - SourceLocation CLoc, Expr *rhs, Expr *save, QualType t) - : Expr(ConditionalOperatorClass, t, + SourceLocation CLoc, Expr *rhs, + QualType t, ExprValueKind VK, ExprObjectKind OK) + : AbstractConditionalOperator(ConditionalOperatorClass, t, VK, OK, // FIXME: the type of the conditional operator doesn't // depend on the type of the conditional, but the standard // seems to imply that it could. File a bug! - ((lhs && lhs->isTypeDependent()) || (rhs && rhs->isTypeDependent())), - (cond->isValueDependent() || - (lhs && lhs->isValueDependent()) || - (rhs && rhs->isValueDependent()))), - QuestionLoc(QLoc), - ColonLoc(CLoc) { + (lhs->isTypeDependent() || rhs->isTypeDependent()), + (cond->isValueDependent() || lhs->isValueDependent() || + rhs->isValueDependent()), + (cond->containsUnexpandedParameterPack() || + lhs->containsUnexpandedParameterPack() || + rhs->containsUnexpandedParameterPack()), + QLoc, CLoc) { SubExprs[COND] = cond; SubExprs[LHS] = lhs; SubExprs[RHS] = rhs; - Save = save; } /// \brief Build an empty conditional operator. explicit ConditionalOperator(EmptyShell Empty) - : Expr(ConditionalOperatorClass, Empty) { } + : AbstractConditionalOperator(ConditionalOperatorClass, Empty) { } // getCond - Return the expression representing the condition for - // the ?: operator. + // the ?: operator. Expr *getCond() const { return cast<Expr>(SubExprs[COND]); } - void setCond(Expr *E) { SubExprs[COND] = E; } - // getTrueExpr - Return the subexpression representing the value of the ?: - // expression if the condition evaluates to true. - Expr *getTrueExpr() const { - return cast<Expr>(!Save ? SubExprs[LHS] : SubExprs[COND]); - } + // getTrueExpr - Return the subexpression representing the value of + // the expression if the condition evaluates to true. + Expr *getTrueExpr() const { return cast<Expr>(SubExprs[LHS]); } - // getFalseExpr - Return the subexpression representing the value of the ?: - // expression if the condition evaluates to false. This is the same as getRHS. + // 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]); } - // 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 *getLHS() const { return cast<Expr>(SubExprs[LHS]); } 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; } - SourceLocation getColonLoc() const { return ColonLoc; } - void setColonLoc(SourceLocation L) { ColonLoc = L; } - - virtual SourceRange getSourceRange() const { + SourceRange getSourceRange() const { return SourceRange(getCond()->getLocStart(), getRHS()->getLocEnd()); } static bool classof(const Stmt *T) { @@ -2462,18 +2731,118 @@ public: static bool classof(const ConditionalOperator *) { return true; } // Iterators - virtual child_iterator child_begin(); - virtual child_iterator child_end(); + child_range children() { + return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR); + } +}; + +/// BinaryConditionalOperator - The GNU extension to the conditional +/// operator which allows the middle operand to be omitted. +/// +/// This is a different expression kind on the assumption that almost +/// every client ends up needing to know that these are different. +class BinaryConditionalOperator : public AbstractConditionalOperator { + enum { COMMON, COND, LHS, RHS, NUM_SUBEXPRS }; + + /// - the common condition/left-hand-side expression, which will be + /// evaluated as the opaque value + /// - the condition, expressed in terms of the opaque value + /// - the left-hand-side, expressed in terms of the opaque value + /// - the right-hand-side + Stmt *SubExprs[NUM_SUBEXPRS]; + OpaqueValueExpr *OpaqueValue; + + friend class ASTStmtReader; +public: + BinaryConditionalOperator(Expr *common, OpaqueValueExpr *opaqueValue, + Expr *cond, Expr *lhs, Expr *rhs, + SourceLocation qloc, SourceLocation cloc, + QualType t, ExprValueKind VK, ExprObjectKind OK) + : AbstractConditionalOperator(BinaryConditionalOperatorClass, t, VK, OK, + (common->isTypeDependent() || rhs->isTypeDependent()), + (common->isValueDependent() || rhs->isValueDependent()), + (common->containsUnexpandedParameterPack() || + rhs->containsUnexpandedParameterPack()), + qloc, cloc), + OpaqueValue(opaqueValue) { + SubExprs[COMMON] = common; + SubExprs[COND] = cond; + SubExprs[LHS] = lhs; + SubExprs[RHS] = rhs; + + OpaqueValue->setSourceExpr(common); + } + + /// \brief Build an empty conditional operator. + explicit BinaryConditionalOperator(EmptyShell Empty) + : AbstractConditionalOperator(BinaryConditionalOperatorClass, Empty) { } + + /// \brief getCommon - Return the common expression, written to the + /// left of the condition. The opaque value will be bound to the + /// result of this expression. + Expr *getCommon() const { return cast<Expr>(SubExprs[COMMON]); } + + /// \brief getOpaqueValue - Return the opaque value placeholder. + OpaqueValueExpr *getOpaqueValue() const { return OpaqueValue; } + + /// \brief getCond - Return the condition expression; this is defined + /// in terms of the opaque value. + Expr *getCond() const { return cast<Expr>(SubExprs[COND]); } + + /// \brief getTrueExpr - Return the subexpression which will be + /// evaluated if the condition evaluates to true; this is defined + /// in terms of the opaque value. + Expr *getTrueExpr() const { + return cast<Expr>(SubExprs[LHS]); + } + + /// \brief getFalseExpr - Return the subexpression which will be + /// evaluated if the condnition evaluates to false; this is + /// defined in terms of the opaque value. + Expr *getFalseExpr() const { + return cast<Expr>(SubExprs[RHS]); + } + + SourceRange getSourceRange() const { + return SourceRange(getCommon()->getLocStart(), getFalseExpr()->getLocEnd()); + } + static bool classof(const Stmt *T) { + return T->getStmtClass() == BinaryConditionalOperatorClass; + } + static bool classof(const BinaryConditionalOperator *) { return true; } + + // Iterators + child_range children() { + return child_range(SubExprs, SubExprs + NUM_SUBEXPRS); + } }; +inline Expr *AbstractConditionalOperator::getCond() const { + if (const ConditionalOperator *co = dyn_cast<ConditionalOperator>(this)) + return co->getCond(); + return cast<BinaryConditionalOperator>(this)->getCond(); +} + +inline Expr *AbstractConditionalOperator::getTrueExpr() const { + if (const ConditionalOperator *co = dyn_cast<ConditionalOperator>(this)) + return co->getTrueExpr(); + return cast<BinaryConditionalOperator>(this)->getTrueExpr(); +} + +inline Expr *AbstractConditionalOperator::getFalseExpr() const { + if (const ConditionalOperator *co = dyn_cast<ConditionalOperator>(this)) + return co->getFalseExpr(); + return cast<BinaryConditionalOperator>(this)->getFalseExpr(); +} + /// AddrLabelExpr - The GNU address of label extension, representing &&label. class AddrLabelExpr : public Expr { SourceLocation AmpAmpLoc, LabelLoc; - LabelStmt *Label; + LabelDecl *Label; public: - AddrLabelExpr(SourceLocation AALoc, SourceLocation LLoc, LabelStmt *L, + AddrLabelExpr(SourceLocation AALoc, SourceLocation LLoc, LabelDecl *L, QualType t) - : Expr(AddrLabelExprClass, t, false, false), + : Expr(AddrLabelExprClass, t, VK_RValue, OK_Ordinary, false, false, false), AmpAmpLoc(AALoc), LabelLoc(LLoc), Label(L) {} /// \brief Build an empty address of a label expression. @@ -2485,12 +2854,12 @@ public: SourceLocation getLabelLoc() const { return LabelLoc; } void setLabelLoc(SourceLocation L) { LabelLoc = L; } - virtual SourceRange getSourceRange() const { + SourceRange getSourceRange() const { return SourceRange(AmpAmpLoc, LabelLoc); } - LabelStmt *getLabel() const { return Label; } - void setLabel(LabelStmt *S) { Label = S; } + LabelDecl *getLabel() const { return Label; } + void setLabel(LabelDecl *L) { Label = L; } static bool classof(const Stmt *T) { return T->getStmtClass() == AddrLabelExprClass; @@ -2498,13 +2867,15 @@ public: static bool classof(const AddrLabelExpr *) { return true; } // Iterators - virtual child_iterator child_begin(); - virtual child_iterator child_end(); + child_range children() { return child_range(); } }; /// StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}). /// The StmtExpr contains a single CompoundStmt node, which it evaluates and /// takes the value of the last subexpression. +/// +/// A StmtExpr is always an r-value; values "returned" out of a +/// StmtExpr will be copied. class StmtExpr : public Expr { Stmt *SubStmt; SourceLocation LParenLoc, RParenLoc; @@ -2512,7 +2883,8 @@ public: // FIXME: Does type-dependence need to be computed differently? StmtExpr(CompoundStmt *substmt, QualType T, SourceLocation lp, SourceLocation rp) : - Expr(StmtExprClass, T, T->isDependentType(), false), + Expr(StmtExprClass, T, VK_RValue, OK_Ordinary, + T->isDependentType(), false, false), SubStmt(substmt), LParenLoc(lp), RParenLoc(rp) { } /// \brief Build an empty statement expression. @@ -2522,7 +2894,7 @@ public: const CompoundStmt *getSubStmt() const { return cast<CompoundStmt>(SubStmt); } void setSubStmt(CompoundStmt *S) { SubStmt = S; } - virtual SourceRange getSourceRange() const { + SourceRange getSourceRange() const { return SourceRange(LParenLoc, RParenLoc); } @@ -2537,55 +2909,9 @@ public: static bool classof(const StmtExpr *) { return true; } // Iterators - virtual child_iterator child_begin(); - virtual child_iterator child_end(); + child_range children() { return child_range(&SubStmt, &SubStmt+1); } }; -/// TypesCompatibleExpr - GNU builtin-in function __builtin_types_compatible_p. -/// This AST node represents a function that returns 1 if two *types* (not -/// expressions) are compatible. The result of this built-in function can be -/// used in integer constant expressions. -class TypesCompatibleExpr : public Expr { - TypeSourceInfo *TInfo1; - TypeSourceInfo *TInfo2; - SourceLocation BuiltinLoc, RParenLoc; -public: - TypesCompatibleExpr(QualType ReturnType, SourceLocation BLoc, - TypeSourceInfo *tinfo1, TypeSourceInfo *tinfo2, - SourceLocation RP) : - Expr(TypesCompatibleExprClass, ReturnType, false, false), - TInfo1(tinfo1), TInfo2(tinfo2), BuiltinLoc(BLoc), RParenLoc(RP) {} - - /// \brief Build an empty __builtin_type_compatible_p expression. - explicit TypesCompatibleExpr(EmptyShell Empty) - : Expr(TypesCompatibleExprClass, Empty) { } - - 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; } - - SourceLocation getRParenLoc() const { return RParenLoc; } - void setRParenLoc(SourceLocation L) { RParenLoc = L; } - - virtual SourceRange getSourceRange() const { - return SourceRange(BuiltinLoc, RParenLoc); - } - static bool classof(const Stmt *T) { - return T->getStmtClass() == TypesCompatibleExprClass; - } - static bool classof(const TypesCompatibleExpr *) { return true; } - - // Iterators - virtual child_iterator child_begin(); - virtual child_iterator child_end(); -}; /// ShuffleVectorExpr - clang-specific builtin-in function /// __builtin_shufflevector. @@ -2604,18 +2930,9 @@ class ShuffleVectorExpr : public Expr { unsigned NumExprs; public: - // FIXME: Can a shufflevector be value-dependent? Does type-dependence need - // to be computed differently? ShuffleVectorExpr(ASTContext &C, Expr **args, unsigned nexpr, QualType Type, SourceLocation BLoc, - SourceLocation RP) : - Expr(ShuffleVectorExprClass, Type, Type->isDependentType(), false), - BuiltinLoc(BLoc), RParenLoc(RP), NumExprs(nexpr) { - - SubExprs = new (C) Stmt*[nexpr]; - for (unsigned i = 0; i < nexpr; i++) - SubExprs[i] = args[i]; - } + SourceLocation RP); /// \brief Build an empty vector-shuffle expression. explicit ShuffleVectorExpr(EmptyShell Empty) @@ -2627,7 +2944,7 @@ public: SourceLocation getRParenLoc() const { return RParenLoc; } void setRParenLoc(SourceLocation L) { RParenLoc = L; } - virtual SourceRange getSourceRange() const { + SourceRange getSourceRange() const { return SourceRange(BuiltinLoc, RParenLoc); } static bool classof(const Stmt *T) { @@ -2640,6 +2957,9 @@ public: /// pointers. unsigned getNumSubExprs() const { return NumExprs; } + /// \brief Retrieve the array of expressions. + Expr **getSubExprs() { return reinterpret_cast<Expr **>(SubExprs); } + /// getExpr - Return the Expr at the specified index. Expr *getExpr(unsigned Index) { assert((Index < NumExprs) && "Arg access out of range!"); @@ -2658,8 +2978,9 @@ public: } // Iterators - virtual child_iterator child_begin(); - virtual child_iterator child_end(); + child_range children() { + return child_range(&SubExprs[0], &SubExprs[0]+NumExprs); + } }; /// ChooseExpr - GNU builtin-in function __builtin_choose_expr. @@ -2676,9 +2997,13 @@ class ChooseExpr : public Expr { Stmt* SubExprs[END_EXPR]; // Left/Middle/Right hand sides. SourceLocation BuiltinLoc, RParenLoc; public: - ChooseExpr(SourceLocation BLoc, Expr *cond, Expr *lhs, Expr *rhs, QualType t, + ChooseExpr(SourceLocation BLoc, Expr *cond, Expr *lhs, Expr *rhs, + QualType t, ExprValueKind VK, ExprObjectKind OK, SourceLocation RP, bool TypeDependent, bool ValueDependent) - : Expr(ChooseExprClass, t, TypeDependent, ValueDependent), + : Expr(ChooseExprClass, t, VK, OK, TypeDependent, ValueDependent, + (cond->containsUnexpandedParameterPack() || + lhs->containsUnexpandedParameterPack() || + rhs->containsUnexpandedParameterPack())), BuiltinLoc(BLoc), RParenLoc(RP) { SubExprs[COND] = cond; SubExprs[LHS] = lhs; @@ -2690,11 +3015,11 @@ public: /// isConditionTrue - Return whether the condition is true (i.e. not /// equal to zero). - bool isConditionTrue(ASTContext &C) const; + bool isConditionTrue(const ASTContext &C) const; /// getChosenSubExpr - Return the subexpression chosen according to the /// condition. - Expr *getChosenSubExpr(ASTContext &C) const { + Expr *getChosenSubExpr(const ASTContext &C) const { return isConditionTrue(C) ? getLHS() : getRHS(); } @@ -2711,7 +3036,7 @@ public: SourceLocation getRParenLoc() const { return RParenLoc; } void setRParenLoc(SourceLocation L) { RParenLoc = L; } - virtual SourceRange getSourceRange() const { + SourceRange getSourceRange() const { return SourceRange(BuiltinLoc, RParenLoc); } static bool classof(const Stmt *T) { @@ -2720,8 +3045,9 @@ public: static bool classof(const ChooseExpr *) { return true; } // Iterators - virtual child_iterator child_begin(); - virtual child_iterator child_end(); + child_range children() { + return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR); + } }; /// GNUNullExpr - Implements the GNU __null extension, which is a name @@ -2736,7 +3062,8 @@ class GNUNullExpr : public Expr { public: GNUNullExpr(QualType Ty, SourceLocation Loc) - : Expr(GNUNullExprClass, Ty, false, false), TokenLoc(Loc) { } + : Expr(GNUNullExprClass, Ty, VK_RValue, OK_Ordinary, false, false, false), + TokenLoc(Loc) { } /// \brief Build an empty GNU __null expression. explicit GNUNullExpr(EmptyShell Empty) : Expr(GNUNullExprClass, Empty) { } @@ -2745,7 +3072,7 @@ public: SourceLocation getTokenLocation() const { return TokenLoc; } void setTokenLocation(SourceLocation L) { TokenLoc = L; } - virtual SourceRange getSourceRange() const { + SourceRange getSourceRange() const { return SourceRange(TokenLoc); } static bool classof(const Stmt *T) { @@ -2754,8 +3081,7 @@ public: static bool classof(const GNUNullExpr *) { return true; } // Iterators - virtual child_iterator child_begin(); - virtual child_iterator child_end(); + child_range children() { return child_range(); } }; /// VAArgExpr, used for the builtin function __builtin_va_arg. @@ -2766,7 +3092,10 @@ class VAArgExpr : public Expr { public: VAArgExpr(SourceLocation BLoc, Expr* e, TypeSourceInfo *TInfo, SourceLocation RPLoc, QualType t) - : Expr(VAArgExprClass, t, t->isDependentType(), false), + : Expr(VAArgExprClass, t, VK_RValue, OK_Ordinary, + t->isDependentType(), false, + (TInfo->getType()->containsUnexpandedParameterPack() || + e->containsUnexpandedParameterPack())), Val(e), TInfo(TInfo), BuiltinLoc(BLoc), RParenLoc(RPLoc) { } @@ -2787,7 +3116,7 @@ public: SourceLocation getRParenLoc() const { return RParenLoc; } void setRParenLoc(SourceLocation L) { RParenLoc = L; } - virtual SourceRange getSourceRange() const { + SourceRange getSourceRange() const { return SourceRange(BuiltinLoc, RParenLoc); } static bool classof(const Stmt *T) { @@ -2796,8 +3125,7 @@ public: static bool classof(const VAArgExpr *) { return true; } // Iterators - virtual child_iterator child_begin(); - virtual child_iterator child_end(); + child_range children() { return child_range(&Val, &Val+1); } }; /// @brief Describes an C or C++ initializer list. @@ -2866,12 +3194,15 @@ public: unsigned getNumInits() const { return InitExprs.size(); } - const Expr* getInit(unsigned Init) const { + /// \brief Retrieve the set of initializers. + Expr **getInits() { return reinterpret_cast<Expr **>(InitExprs.data()); } + + const Expr *getInit(unsigned Init) const { assert(Init < getNumInits() && "Initializer access out of range!"); return cast_or_null<Expr>(InitExprs[Init]); } - Expr* getInit(unsigned Init) { + Expr *getInit(unsigned Init) { assert(Init < getNumInits() && "Initializer access out of range!"); return cast_or_null<Expr>(InitExprs[Init]); } @@ -2933,17 +3264,18 @@ public: HadArrayRangeDesignator = ARD; } - virtual SourceRange getSourceRange() const { - return SourceRange(LBraceLoc, RBraceLoc); - } + SourceRange getSourceRange() const; + static bool classof(const Stmt *T) { return T->getStmtClass() == InitListExprClass; } static bool classof(const InitListExpr *) { return true; } // Iterators - virtual child_iterator child_begin(); - virtual child_iterator child_end(); + child_range children() { + if (InitExprs.empty()) return child_range(); + return child_range(&InitExprs[0], &InitExprs[0] + InitExprs.size()); + } typedef InitExprsTy::iterator iterator; typedef InitExprsTy::const_iterator const_iterator; @@ -3182,6 +3514,15 @@ public: return Designators + NumDesignators; } + typedef std::reverse_iterator<designators_iterator> + reverse_designators_iterator; + reverse_designators_iterator designators_rbegin() { + return reverse_designators_iterator(designators_end()); + } + reverse_designators_iterator designators_rend() { + return reverse_designators_iterator(designators_begin()); + } + Designator *getDesignator(unsigned Idx) { return &designators_begin()[Idx]; } void setDesignators(ASTContext &C, const Designator *Desigs, @@ -3235,7 +3576,7 @@ public: void ExpandDesignator(ASTContext &C, unsigned Idx, const Designator *First, const Designator *Last); - virtual SourceRange getSourceRange() const; + SourceRange getSourceRange() const; static bool classof(const Stmt *T) { return T->getStmtClass() == DesignatedInitExprClass; @@ -3243,8 +3584,10 @@ public: static bool classof(const DesignatedInitExpr *) { return true; } // Iterators - virtual child_iterator child_begin(); - virtual child_iterator child_end(); + child_range children() { + Stmt **begin = reinterpret_cast<Stmt**>(this + 1); + return child_range(begin, begin + NumSubExprs); + } }; /// \brief Represents an implicitly-generated value initialization of @@ -3258,7 +3601,8 @@ public: class ImplicitValueInitExpr : public Expr { public: explicit ImplicitValueInitExpr(QualType ty) - : Expr(ImplicitValueInitExprClass, ty, false, false) { } + : Expr(ImplicitValueInitExprClass, ty, VK_RValue, OK_Ordinary, + false, false, false) { } /// \brief Construct an empty implicit value initialization. explicit ImplicitValueInitExpr(EmptyShell Empty) @@ -3269,13 +3613,12 @@ public: } static bool classof(const ImplicitValueInitExpr *) { return true; } - virtual SourceRange getSourceRange() const { + SourceRange getSourceRange() const { return SourceRange(); } // Iterators - virtual child_iterator child_begin(); - virtual child_iterator child_end(); + child_range children() { return child_range(); } }; @@ -3308,7 +3651,7 @@ public: SourceLocation getLParenLoc() const { return LParenLoc; } SourceLocation getRParenLoc() const { return RParenLoc; } - virtual SourceRange getSourceRange() const { + SourceRange getSourceRange() const { return SourceRange(LParenLoc, RParenLoc); } static bool classof(const Stmt *T) { @@ -3317,8 +3660,9 @@ public: static bool classof(const ParenListExpr *) { return true; } // Iterators - virtual child_iterator child_begin(); - virtual child_iterator child_end(); + child_range children() { + return child_range(&Exprs[0], &Exprs[0]+NumExprs); + } friend class ASTStmtReader; friend class ASTStmtWriter; @@ -3342,10 +3686,12 @@ class ExtVectorElementExpr : public Expr { IdentifierInfo *Accessor; SourceLocation AccessorLoc; public: - ExtVectorElementExpr(QualType ty, Expr *base, IdentifierInfo &accessor, - SourceLocation loc) - : Expr(ExtVectorElementExprClass, ty, base->isTypeDependent(), - base->isValueDependent()), + ExtVectorElementExpr(QualType ty, ExprValueKind VK, Expr *base, + IdentifierInfo &accessor, SourceLocation loc) + : Expr(ExtVectorElementExprClass, ty, VK, + (VK == VK_RValue ? OK_Ordinary : OK_VectorComponent), + base->isTypeDependent(), base->isValueDependent(), + base->containsUnexpandedParameterPack()), Base(base), Accessor(&accessor), AccessorLoc(loc) {} /// \brief Build an empty vector element expression. @@ -3373,7 +3719,7 @@ public: /// aggregate Constant of ConstantInt(s). void getEncodedElementAccess(llvm::SmallVectorImpl<unsigned> &Elts) const; - virtual SourceRange getSourceRange() const { + SourceRange getSourceRange() const { return SourceRange(getBase()->getLocStart(), AccessorLoc); } @@ -3387,8 +3733,7 @@ public: static bool classof(const ExtVectorElementExpr *) { return true; } // Iterators - virtual child_iterator child_begin(); - virtual child_iterator child_end(); + child_range children() { return child_range(&Base, &Base+1); } }; @@ -3397,11 +3742,11 @@ public: class BlockExpr : public Expr { protected: BlockDecl *TheBlock; - bool HasBlockDeclRefExprs; public: - BlockExpr(BlockDecl *BD, QualType ty, bool hasBlockDeclRefExprs) - : Expr(BlockExprClass, ty, ty->isDependentType(), false), - TheBlock(BD), HasBlockDeclRefExprs(hasBlockDeclRefExprs) {} + BlockExpr(BlockDecl *BD, QualType ty) + : Expr(BlockExprClass, ty, VK_RValue, OK_Ordinary, + ty->isDependentType(), false, false), + TheBlock(BD) {} /// \brief Build an empty block expression. explicit BlockExpr(EmptyShell Empty) : Expr(BlockExprClass, Empty) { } @@ -3415,58 +3760,46 @@ public: const Stmt *getBody() const; Stmt *getBody(); - virtual SourceRange getSourceRange() const { + SourceRange getSourceRange() const { return SourceRange(getCaretLocation(), getBody()->getLocEnd()); } /// getFunctionType - Return the underlying function type for this block. const FunctionType *getFunctionType() const; - /// hasBlockDeclRefExprs - Return true iff the block has BlockDeclRefExpr - /// inside of the block that reference values outside the block. - bool hasBlockDeclRefExprs() const { return HasBlockDeclRefExprs; } - void setHasBlockDeclRefExprs(bool BDRE) { HasBlockDeclRefExprs = BDRE; } - static bool classof(const Stmt *T) { return T->getStmtClass() == BlockExprClass; } static bool classof(const BlockExpr *) { return true; } // Iterators - virtual child_iterator child_begin(); - virtual child_iterator child_end(); + child_range children() { return child_range(); } }; -/// BlockDeclRefExpr - A reference to a declared variable, function, -/// enum, etc. +/// BlockDeclRefExpr - A reference to a local variable declared in an +/// enclosing scope. class BlockDeclRefExpr : public Expr { - ValueDecl *D; + VarDecl *D; SourceLocation Loc; bool IsByRef : 1; bool ConstQualAdded : 1; - Stmt *CopyConstructorVal; public: - // FIXME: Fix type/value dependence! - BlockDeclRefExpr(ValueDecl *d, QualType t, SourceLocation l, bool ByRef, - bool constAdded = false, - Stmt *copyConstructorVal = 0) - : Expr(BlockDeclRefExprClass, t, (!t.isNull() && t->isDependentType()),false), - D(d), Loc(l), IsByRef(ByRef), - ConstQualAdded(constAdded), CopyConstructorVal(copyConstructorVal) {} + BlockDeclRefExpr(VarDecl *d, QualType t, ExprValueKind VK, + SourceLocation l, bool ByRef, bool constAdded = false); // \brief Build an empty reference to a declared variable in a // block. explicit BlockDeclRefExpr(EmptyShell Empty) : Expr(BlockDeclRefExprClass, Empty) { } - ValueDecl *getDecl() { return D; } - const ValueDecl *getDecl() const { return D; } - void setDecl(ValueDecl *VD) { D = VD; } + VarDecl *getDecl() { return D; } + const VarDecl *getDecl() const { return D; } + void setDecl(VarDecl *VD) { D = VD; } SourceLocation getLocation() const { return Loc; } void setLocation(SourceLocation L) { Loc = L; } - virtual SourceRange getSourceRange() const { return SourceRange(Loc); } + SourceRange getSourceRange() const { return SourceRange(Loc); } bool isByRef() const { return IsByRef; } void setByRef(bool BR) { IsByRef = BR; } @@ -3474,20 +3807,13 @@ public: bool isConstQualAdded() const { return ConstQualAdded; } void setConstQualAdded(bool C) { ConstQualAdded = C; } - const Expr *getCopyConstructorExpr() const - { return cast_or_null<Expr>(CopyConstructorVal); } - Expr *getCopyConstructorExpr() - { return cast_or_null<Expr>(CopyConstructorVal); } - void setCopyConstructorExpr(Expr *E) { CopyConstructorVal = E; } - static bool classof(const Stmt *T) { return T->getStmtClass() == BlockDeclRefExprClass; } static bool classof(const BlockDeclRefExpr *) { return true; } // Iterators - virtual child_iterator child_begin(); - virtual child_iterator child_end(); + child_range children() { return child_range(); } }; } // end namespace clang |