10b57cec5SDimitry Andric //===--- Expr.h - Classes for representing expressions ----------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric //  This file defines the Expr interface and subclasses.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #ifndef LLVM_CLANG_AST_EXPR_H
140b57cec5SDimitry Andric #define LLVM_CLANG_AST_EXPR_H
150b57cec5SDimitry Andric 
167a6dacacSDimitry Andric #include "clang/AST/APNumericStorage.h"
170b57cec5SDimitry Andric #include "clang/AST/APValue.h"
180b57cec5SDimitry Andric #include "clang/AST/ASTVector.h"
195ffd83dbSDimitry Andric #include "clang/AST/ComputeDependence.h"
200b57cec5SDimitry Andric #include "clang/AST/Decl.h"
210b57cec5SDimitry Andric #include "clang/AST/DeclAccessPair.h"
225ffd83dbSDimitry Andric #include "clang/AST/DependenceFlags.h"
230b57cec5SDimitry Andric #include "clang/AST/OperationKinds.h"
240b57cec5SDimitry Andric #include "clang/AST/Stmt.h"
250b57cec5SDimitry Andric #include "clang/AST/TemplateBase.h"
260b57cec5SDimitry Andric #include "clang/AST/Type.h"
270b57cec5SDimitry Andric #include "clang/Basic/CharInfo.h"
280b57cec5SDimitry Andric #include "clang/Basic/LangOptions.h"
290b57cec5SDimitry Andric #include "clang/Basic/SyncScope.h"
300b57cec5SDimitry Andric #include "clang/Basic/TypeTraits.h"
310b57cec5SDimitry Andric #include "llvm/ADT/APFloat.h"
320b57cec5SDimitry Andric #include "llvm/ADT/APSInt.h"
330b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
340b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
355ffd83dbSDimitry Andric #include "llvm/ADT/iterator.h"
365ffd83dbSDimitry Andric #include "llvm/ADT/iterator_range.h"
370b57cec5SDimitry Andric #include "llvm/Support/AtomicOrdering.h"
380b57cec5SDimitry Andric #include "llvm/Support/Compiler.h"
390b57cec5SDimitry Andric #include "llvm/Support/TrailingObjects.h"
40bdd1243dSDimitry Andric #include <optional>
410b57cec5SDimitry Andric 
420b57cec5SDimitry Andric namespace clang {
430b57cec5SDimitry Andric   class APValue;
440b57cec5SDimitry Andric   class ASTContext;
450b57cec5SDimitry Andric   class BlockDecl;
460b57cec5SDimitry Andric   class CXXBaseSpecifier;
470b57cec5SDimitry Andric   class CXXMemberCallExpr;
480b57cec5SDimitry Andric   class CXXOperatorCallExpr;
490b57cec5SDimitry Andric   class CastExpr;
500b57cec5SDimitry Andric   class Decl;
510b57cec5SDimitry Andric   class IdentifierInfo;
520b57cec5SDimitry Andric   class MaterializeTemporaryExpr;
530b57cec5SDimitry Andric   class NamedDecl;
540b57cec5SDimitry Andric   class ObjCPropertyRefExpr;
550b57cec5SDimitry Andric   class OpaqueValueExpr;
560b57cec5SDimitry Andric   class ParmVarDecl;
570b57cec5SDimitry Andric   class StringLiteral;
580b57cec5SDimitry Andric   class TargetInfo;
590b57cec5SDimitry Andric   class ValueDecl;
600b57cec5SDimitry Andric 
610b57cec5SDimitry Andric /// A simple array of base specifiers.
620b57cec5SDimitry Andric typedef SmallVector<CXXBaseSpecifier*, 4> CXXCastPath;
630b57cec5SDimitry Andric 
640b57cec5SDimitry Andric /// An adjustment to be made to the temporary created when emitting a
650b57cec5SDimitry Andric /// reference binding, which accesses a particular subobject of that temporary.
660b57cec5SDimitry Andric struct SubobjectAdjustment {
670b57cec5SDimitry Andric   enum {
680b57cec5SDimitry Andric     DerivedToBaseAdjustment,
690b57cec5SDimitry Andric     FieldAdjustment,
700b57cec5SDimitry Andric     MemberPointerAdjustment
710b57cec5SDimitry Andric   } Kind;
720b57cec5SDimitry Andric 
730b57cec5SDimitry Andric   struct DTB {
740b57cec5SDimitry Andric     const CastExpr *BasePath;
750b57cec5SDimitry Andric     const CXXRecordDecl *DerivedClass;
760b57cec5SDimitry Andric   };
770b57cec5SDimitry Andric 
780b57cec5SDimitry Andric   struct P {
790b57cec5SDimitry Andric     const MemberPointerType *MPT;
800b57cec5SDimitry Andric     Expr *RHS;
810b57cec5SDimitry Andric   };
820b57cec5SDimitry Andric 
830b57cec5SDimitry Andric   union {
840b57cec5SDimitry Andric     struct DTB DerivedToBase;
850b57cec5SDimitry Andric     FieldDecl *Field;
860b57cec5SDimitry Andric     struct P Ptr;
870b57cec5SDimitry Andric   };
880b57cec5SDimitry Andric 
SubobjectAdjustmentSubobjectAdjustment890b57cec5SDimitry Andric   SubobjectAdjustment(const CastExpr *BasePath,
900b57cec5SDimitry Andric                       const CXXRecordDecl *DerivedClass)
910b57cec5SDimitry Andric     : Kind(DerivedToBaseAdjustment) {
920b57cec5SDimitry Andric     DerivedToBase.BasePath = BasePath;
930b57cec5SDimitry Andric     DerivedToBase.DerivedClass = DerivedClass;
940b57cec5SDimitry Andric   }
950b57cec5SDimitry Andric 
SubobjectAdjustmentSubobjectAdjustment960b57cec5SDimitry Andric   SubobjectAdjustment(FieldDecl *Field)
970b57cec5SDimitry Andric     : Kind(FieldAdjustment) {
980b57cec5SDimitry Andric     this->Field = Field;
990b57cec5SDimitry Andric   }
1000b57cec5SDimitry Andric 
SubobjectAdjustmentSubobjectAdjustment1010b57cec5SDimitry Andric   SubobjectAdjustment(const MemberPointerType *MPT, Expr *RHS)
1020b57cec5SDimitry Andric     : Kind(MemberPointerAdjustment) {
1030b57cec5SDimitry Andric     this->Ptr.MPT = MPT;
1040b57cec5SDimitry Andric     this->Ptr.RHS = RHS;
1050b57cec5SDimitry Andric   }
1060b57cec5SDimitry Andric };
1070b57cec5SDimitry Andric 
1080b57cec5SDimitry Andric /// This represents one expression.  Note that Expr's are subclasses of Stmt.
1090b57cec5SDimitry Andric /// This allows an expression to be transparently used any place a Stmt is
1100b57cec5SDimitry Andric /// required.
1110b57cec5SDimitry Andric class Expr : public ValueStmt {
1120b57cec5SDimitry Andric   QualType TR;
1130b57cec5SDimitry Andric 
1140b57cec5SDimitry Andric public:
1150b57cec5SDimitry Andric   Expr() = delete;
1160b57cec5SDimitry Andric   Expr(const Expr&) = delete;
1170b57cec5SDimitry Andric   Expr(Expr &&) = delete;
1180b57cec5SDimitry Andric   Expr &operator=(const Expr&) = delete;
1190b57cec5SDimitry Andric   Expr &operator=(Expr&&) = delete;
1200b57cec5SDimitry Andric 
1210b57cec5SDimitry Andric protected:
Expr(StmtClass SC,QualType T,ExprValueKind VK,ExprObjectKind OK)1225ffd83dbSDimitry Andric   Expr(StmtClass SC, QualType T, ExprValueKind VK, ExprObjectKind OK)
1235ffd83dbSDimitry Andric       : ValueStmt(SC) {
1245ffd83dbSDimitry Andric     ExprBits.Dependent = 0;
1250b57cec5SDimitry Andric     ExprBits.ValueKind = VK;
1260b57cec5SDimitry Andric     ExprBits.ObjectKind = OK;
1270b57cec5SDimitry Andric     assert(ExprBits.ObjectKind == OK && "truncated kind");
1280b57cec5SDimitry Andric     setType(T);
1290b57cec5SDimitry Andric   }
1300b57cec5SDimitry Andric 
1310b57cec5SDimitry Andric   /// Construct an empty expression.
Expr(StmtClass SC,EmptyShell)1320b57cec5SDimitry Andric   explicit Expr(StmtClass SC, EmptyShell) : ValueStmt(SC) { }
1330b57cec5SDimitry Andric 
1345ffd83dbSDimitry Andric   /// Each concrete expr subclass is expected to compute its dependence and call
1355ffd83dbSDimitry Andric   /// this in the constructor.
setDependence(ExprDependence Deps)1365ffd83dbSDimitry Andric   void setDependence(ExprDependence Deps) {
1375ffd83dbSDimitry Andric     ExprBits.Dependent = static_cast<unsigned>(Deps);
1385ffd83dbSDimitry Andric   }
13906c3fb27SDimitry Andric   friend class ASTImporter;   // Sets dependence directly.
14006c3fb27SDimitry Andric   friend class ASTStmtReader; // Sets dependence directly.
1415ffd83dbSDimitry Andric 
1420b57cec5SDimitry Andric public:
getType()1430b57cec5SDimitry Andric   QualType getType() const { return TR; }
setType(QualType t)1440b57cec5SDimitry Andric   void setType(QualType t) {
1450b57cec5SDimitry Andric     // In C++, the type of an expression is always adjusted so that it
1460b57cec5SDimitry Andric     // will not have reference type (C++ [expr]p6). Use
1470b57cec5SDimitry Andric     // QualType::getNonReferenceType() to retrieve the non-reference
1480b57cec5SDimitry Andric     // type. Additionally, inspect Expr::isLvalue to determine whether
1490b57cec5SDimitry Andric     // an expression that is adjusted in this manner should be
1500b57cec5SDimitry Andric     // considered an lvalue.
1510b57cec5SDimitry Andric     assert((t.isNull() || !t->isReferenceType()) &&
1520b57cec5SDimitry Andric            "Expressions can't have reference type");
1530b57cec5SDimitry Andric 
1540b57cec5SDimitry Andric     TR = t;
1550b57cec5SDimitry Andric   }
1560b57cec5SDimitry Andric 
getDependence()1575ffd83dbSDimitry Andric   ExprDependence getDependence() const {
1585ffd83dbSDimitry Andric     return static_cast<ExprDependence>(ExprBits.Dependent);
1595ffd83dbSDimitry Andric   }
1605ffd83dbSDimitry Andric 
1615ffd83dbSDimitry Andric   /// Determines whether the value of this expression depends on
1625ffd83dbSDimitry Andric   ///   - a template parameter (C++ [temp.dep.constexpr])
1635ffd83dbSDimitry Andric   ///   - or an error, whose resolution is unknown
1645ffd83dbSDimitry Andric   ///
1655ffd83dbSDimitry Andric   /// For example, the array bound of "Chars" in the following example is
1660b57cec5SDimitry Andric   /// value-dependent.
1670b57cec5SDimitry Andric   /// @code
1680b57cec5SDimitry Andric   /// template<int Size, char (&Chars)[Size]> struct meta_string;
1690b57cec5SDimitry Andric   /// @endcode
isValueDependent()1705ffd83dbSDimitry Andric   bool isValueDependent() const {
1715ffd83dbSDimitry Andric     return static_cast<bool>(getDependence() & ExprDependence::Value);
1720b57cec5SDimitry Andric   }
1730b57cec5SDimitry Andric 
1745ffd83dbSDimitry Andric   /// Determines whether the type of this expression depends on
17506c3fb27SDimitry Andric   ///   - a template parameter (C++ [temp.dep.expr], which means that its type
1765ffd83dbSDimitry Andric   ///     could change from one template instantiation to the next)
1775ffd83dbSDimitry Andric   ///   - or an error
1785ffd83dbSDimitry Andric   ///
1795ffd83dbSDimitry Andric   /// For example, the expressions "x" and "x + y" are type-dependent in
1800b57cec5SDimitry Andric   /// the following code, but "y" is not type-dependent:
1810b57cec5SDimitry Andric   /// @code
1820b57cec5SDimitry Andric   /// template<typename T>
1830b57cec5SDimitry Andric   /// void add(T x, int y) {
1840b57cec5SDimitry Andric   ///   x + y;
1850b57cec5SDimitry Andric   /// }
1860b57cec5SDimitry Andric   /// @endcode
isTypeDependent()1875ffd83dbSDimitry Andric   bool isTypeDependent() const {
1885ffd83dbSDimitry Andric     return static_cast<bool>(getDependence() & ExprDependence::Type);
1890b57cec5SDimitry Andric   }
1900b57cec5SDimitry Andric 
1910b57cec5SDimitry Andric   /// Whether this expression is instantiation-dependent, meaning that
1925ffd83dbSDimitry Andric   /// it depends in some way on
1935ffd83dbSDimitry Andric   ///    - a template parameter (even if neither its type nor (constant) value
1945ffd83dbSDimitry Andric   ///      can change due to the template instantiation)
1955ffd83dbSDimitry Andric   ///    - or an error
1960b57cec5SDimitry Andric   ///
1970b57cec5SDimitry Andric   /// In the following example, the expression \c sizeof(sizeof(T() + T())) is
1980b57cec5SDimitry Andric   /// instantiation-dependent (since it involves a template parameter \c T), but
1990b57cec5SDimitry Andric   /// is neither type- nor value-dependent, since the type of the inner
2000b57cec5SDimitry Andric   /// \c sizeof is known (\c std::size_t) and therefore the size of the outer
2010b57cec5SDimitry Andric   /// \c sizeof is known.
2020b57cec5SDimitry Andric   ///
2030b57cec5SDimitry Andric   /// \code
2040b57cec5SDimitry Andric   /// template<typename T>
2050b57cec5SDimitry Andric   /// void f(T x, T y) {
2060b57cec5SDimitry Andric   ///   sizeof(sizeof(T() + T());
2070b57cec5SDimitry Andric   /// }
2080b57cec5SDimitry Andric   /// \endcode
2090b57cec5SDimitry Andric   ///
2105ffd83dbSDimitry Andric   /// \code
2115ffd83dbSDimitry Andric   /// void func(int) {
2125ffd83dbSDimitry Andric   ///   func(); // the expression is instantiation-dependent, because it depends
2135ffd83dbSDimitry Andric   ///           // on an error.
2145ffd83dbSDimitry Andric   /// }
2155ffd83dbSDimitry Andric   /// \endcode
isInstantiationDependent()2160b57cec5SDimitry Andric   bool isInstantiationDependent() const {
2175ffd83dbSDimitry Andric     return static_cast<bool>(getDependence() & ExprDependence::Instantiation);
2180b57cec5SDimitry Andric   }
2190b57cec5SDimitry Andric 
2200b57cec5SDimitry Andric   /// Whether this expression contains an unexpanded parameter
2210b57cec5SDimitry Andric   /// pack (for C++11 variadic templates).
2220b57cec5SDimitry Andric   ///
2230b57cec5SDimitry Andric   /// Given the following function template:
2240b57cec5SDimitry Andric   ///
2250b57cec5SDimitry Andric   /// \code
2260b57cec5SDimitry Andric   /// template<typename F, typename ...Types>
2270b57cec5SDimitry Andric   /// void forward(const F &f, Types &&...args) {
2280b57cec5SDimitry Andric   ///   f(static_cast<Types&&>(args)...);
2290b57cec5SDimitry Andric   /// }
2300b57cec5SDimitry Andric   /// \endcode
2310b57cec5SDimitry Andric   ///
2320b57cec5SDimitry Andric   /// The expressions \c args and \c static_cast<Types&&>(args) both
2330b57cec5SDimitry Andric   /// contain parameter packs.
containsUnexpandedParameterPack()2340b57cec5SDimitry Andric   bool containsUnexpandedParameterPack() const {
2355ffd83dbSDimitry Andric     return static_cast<bool>(getDependence() & ExprDependence::UnexpandedPack);
2360b57cec5SDimitry Andric   }
2370b57cec5SDimitry Andric 
2385ffd83dbSDimitry Andric   /// Whether this expression contains subexpressions which had errors, e.g. a
2395ffd83dbSDimitry Andric   /// TypoExpr.
containsErrors()2405ffd83dbSDimitry Andric   bool containsErrors() const {
2415ffd83dbSDimitry Andric     return static_cast<bool>(getDependence() & ExprDependence::Error);
2420b57cec5SDimitry Andric   }
2430b57cec5SDimitry Andric 
2440b57cec5SDimitry Andric   /// getExprLoc - Return the preferred location for the arrow when diagnosing
2450b57cec5SDimitry Andric   /// a problem with a generic expression.
2460b57cec5SDimitry Andric   SourceLocation getExprLoc() const LLVM_READONLY;
2470b57cec5SDimitry Andric 
2485ffd83dbSDimitry Andric   /// Determine whether an lvalue-to-rvalue conversion should implicitly be
2495ffd83dbSDimitry Andric   /// applied to this expression if it appears as a discarded-value expression
2505ffd83dbSDimitry Andric   /// in C++11 onwards. This applies to certain forms of volatile glvalues.
2515ffd83dbSDimitry Andric   bool isReadIfDiscardedInCPlusPlus11() const;
2525ffd83dbSDimitry Andric 
2530b57cec5SDimitry Andric   /// isUnusedResultAWarning - Return true if this immediate expression should
2540b57cec5SDimitry Andric   /// be warned about if the result is unused.  If so, fill in expr, location,
2550b57cec5SDimitry Andric   /// and ranges with expr to warn on and source locations/ranges appropriate
2560b57cec5SDimitry Andric   /// for a warning.
2570b57cec5SDimitry Andric   bool isUnusedResultAWarning(const Expr *&WarnExpr, SourceLocation &Loc,
2580b57cec5SDimitry Andric                               SourceRange &R1, SourceRange &R2,
2590b57cec5SDimitry Andric                               ASTContext &Ctx) const;
2600b57cec5SDimitry Andric 
2610b57cec5SDimitry Andric   /// isLValue - True if this expression is an "l-value" according to
2620b57cec5SDimitry Andric   /// the rules of the current language.  C and C++ give somewhat
2630b57cec5SDimitry Andric   /// different rules for this concept, but in general, the result of
2640b57cec5SDimitry Andric   /// an l-value expression identifies a specific object whereas the
2650b57cec5SDimitry Andric   /// result of an r-value expression is a value detached from any
2660b57cec5SDimitry Andric   /// specific storage.
2670b57cec5SDimitry Andric   ///
2680b57cec5SDimitry Andric   /// C++11 divides the concept of "r-value" into pure r-values
2690b57cec5SDimitry Andric   /// ("pr-values") and so-called expiring values ("x-values"), which
2700b57cec5SDimitry Andric   /// identify specific objects that can be safely cannibalized for
271fe6060f1SDimitry Andric   /// their resources.
isLValue()2720b57cec5SDimitry Andric   bool isLValue() const { return getValueKind() == VK_LValue; }
isPRValue()273fe6060f1SDimitry Andric   bool isPRValue() const { return getValueKind() == VK_PRValue; }
isXValue()2740b57cec5SDimitry Andric   bool isXValue() const { return getValueKind() == VK_XValue; }
isGLValue()275fe6060f1SDimitry Andric   bool isGLValue() const { return getValueKind() != VK_PRValue; }
2760b57cec5SDimitry Andric 
2770b57cec5SDimitry Andric   enum LValueClassification {
2780b57cec5SDimitry Andric     LV_Valid,
2790b57cec5SDimitry Andric     LV_NotObjectType,
2800b57cec5SDimitry Andric     LV_IncompleteVoidType,
2810b57cec5SDimitry Andric     LV_DuplicateVectorComponents,
2820b57cec5SDimitry Andric     LV_InvalidExpression,
2830b57cec5SDimitry Andric     LV_InvalidMessageExpression,
2840b57cec5SDimitry Andric     LV_MemberFunction,
2850b57cec5SDimitry Andric     LV_SubObjCPropertySetting,
2860b57cec5SDimitry Andric     LV_ClassTemporary,
2870b57cec5SDimitry Andric     LV_ArrayTemporary
2880b57cec5SDimitry Andric   };
2890b57cec5SDimitry Andric   /// Reasons why an expression might not be an l-value.
2900b57cec5SDimitry Andric   LValueClassification ClassifyLValue(ASTContext &Ctx) const;
2910b57cec5SDimitry Andric 
2920b57cec5SDimitry Andric   enum isModifiableLvalueResult {
2930b57cec5SDimitry Andric     MLV_Valid,
2940b57cec5SDimitry Andric     MLV_NotObjectType,
2950b57cec5SDimitry Andric     MLV_IncompleteVoidType,
2960b57cec5SDimitry Andric     MLV_DuplicateVectorComponents,
2970b57cec5SDimitry Andric     MLV_InvalidExpression,
2980b57cec5SDimitry Andric     MLV_LValueCast,           // Specialized form of MLV_InvalidExpression.
2990b57cec5SDimitry Andric     MLV_IncompleteType,
3000b57cec5SDimitry Andric     MLV_ConstQualified,
3010b57cec5SDimitry Andric     MLV_ConstQualifiedField,
3020b57cec5SDimitry Andric     MLV_ConstAddrSpace,
3030b57cec5SDimitry Andric     MLV_ArrayType,
3040b57cec5SDimitry Andric     MLV_NoSetterProperty,
3050b57cec5SDimitry Andric     MLV_MemberFunction,
3060b57cec5SDimitry Andric     MLV_SubObjCPropertySetting,
3070b57cec5SDimitry Andric     MLV_InvalidMessageExpression,
3080b57cec5SDimitry Andric     MLV_ClassTemporary,
3090b57cec5SDimitry Andric     MLV_ArrayTemporary
3100b57cec5SDimitry Andric   };
3110b57cec5SDimitry Andric   /// isModifiableLvalue - C99 6.3.2.1: an lvalue that does not have array type,
3120b57cec5SDimitry Andric   /// does not have an incomplete type, does not have a const-qualified type,
3130b57cec5SDimitry Andric   /// and if it is a structure or union, does not have any member (including,
3140b57cec5SDimitry Andric   /// recursively, any member or element of all contained aggregates or unions)
3150b57cec5SDimitry Andric   /// with a const-qualified type.
3160b57cec5SDimitry Andric   ///
3170b57cec5SDimitry Andric   /// \param Loc [in,out] - A source location which *may* be filled
3180b57cec5SDimitry Andric   /// in with the location of the expression making this a
3190b57cec5SDimitry Andric   /// non-modifiable lvalue, if specified.
3200b57cec5SDimitry Andric   isModifiableLvalueResult
3210b57cec5SDimitry Andric   isModifiableLvalue(ASTContext &Ctx, SourceLocation *Loc = nullptr) const;
3220b57cec5SDimitry Andric 
3230b57cec5SDimitry Andric   /// The return type of classify(). Represents the C++11 expression
3240b57cec5SDimitry Andric   ///        taxonomy.
3250b57cec5SDimitry Andric   class Classification {
3260b57cec5SDimitry Andric   public:
3270b57cec5SDimitry Andric     /// The various classification results. Most of these mean prvalue.
3280b57cec5SDimitry Andric     enum Kinds {
3290b57cec5SDimitry Andric       CL_LValue,
3300b57cec5SDimitry Andric       CL_XValue,
3310b57cec5SDimitry Andric       CL_Function, // Functions cannot be lvalues in C.
3320b57cec5SDimitry Andric       CL_Void, // Void cannot be an lvalue in C.
3330b57cec5SDimitry Andric       CL_AddressableVoid, // Void expression whose address can be taken in C.
3340b57cec5SDimitry Andric       CL_DuplicateVectorComponents, // A vector shuffle with dupes.
3350b57cec5SDimitry Andric       CL_MemberFunction, // An expression referring to a member function
3360b57cec5SDimitry Andric       CL_SubObjCPropertySetting,
3370b57cec5SDimitry Andric       CL_ClassTemporary, // A temporary of class type, or subobject thereof.
3380b57cec5SDimitry Andric       CL_ArrayTemporary, // A temporary of array type.
3390b57cec5SDimitry Andric       CL_ObjCMessageRValue, // ObjC message is an rvalue
3400b57cec5SDimitry Andric       CL_PRValue // A prvalue for any other reason, of any other type
3410b57cec5SDimitry Andric     };
3420b57cec5SDimitry Andric     /// The results of modification testing.
3430b57cec5SDimitry Andric     enum ModifiableType {
3440b57cec5SDimitry Andric       CM_Untested, // testModifiable was false.
3450b57cec5SDimitry Andric       CM_Modifiable,
3460b57cec5SDimitry Andric       CM_RValue, // Not modifiable because it's an rvalue
3470b57cec5SDimitry Andric       CM_Function, // Not modifiable because it's a function; C++ only
3480b57cec5SDimitry Andric       CM_LValueCast, // Same as CM_RValue, but indicates GCC cast-as-lvalue ext
3490b57cec5SDimitry Andric       CM_NoSetterProperty,// Implicit assignment to ObjC property without setter
3500b57cec5SDimitry Andric       CM_ConstQualified,
3510b57cec5SDimitry Andric       CM_ConstQualifiedField,
3520b57cec5SDimitry Andric       CM_ConstAddrSpace,
3530b57cec5SDimitry Andric       CM_ArrayType,
3540b57cec5SDimitry Andric       CM_IncompleteType
3550b57cec5SDimitry Andric     };
3560b57cec5SDimitry Andric 
3570b57cec5SDimitry Andric   private:
3580b57cec5SDimitry Andric     friend class Expr;
3590b57cec5SDimitry Andric 
3600b57cec5SDimitry Andric     unsigned short Kind;
3610b57cec5SDimitry Andric     unsigned short Modifiable;
3620b57cec5SDimitry Andric 
Classification(Kinds k,ModifiableType m)3630b57cec5SDimitry Andric     explicit Classification(Kinds k, ModifiableType m)
3640b57cec5SDimitry Andric       : Kind(k), Modifiable(m)
3650b57cec5SDimitry Andric     {}
3660b57cec5SDimitry Andric 
3670b57cec5SDimitry Andric   public:
Classification()3680b57cec5SDimitry Andric     Classification() {}
3690b57cec5SDimitry Andric 
getKind()3700b57cec5SDimitry Andric     Kinds getKind() const { return static_cast<Kinds>(Kind); }
getModifiable()3710b57cec5SDimitry Andric     ModifiableType getModifiable() const {
3720b57cec5SDimitry Andric       assert(Modifiable != CM_Untested && "Did not test for modifiability.");
3730b57cec5SDimitry Andric       return static_cast<ModifiableType>(Modifiable);
3740b57cec5SDimitry Andric     }
isLValue()3750b57cec5SDimitry Andric     bool isLValue() const { return Kind == CL_LValue; }
isXValue()3760b57cec5SDimitry Andric     bool isXValue() const { return Kind == CL_XValue; }
isGLValue()3770b57cec5SDimitry Andric     bool isGLValue() const { return Kind <= CL_XValue; }
isPRValue()3780b57cec5SDimitry Andric     bool isPRValue() const { return Kind >= CL_Function; }
isRValue()3790b57cec5SDimitry Andric     bool isRValue() const { return Kind >= CL_XValue; }
isModifiable()3800b57cec5SDimitry Andric     bool isModifiable() const { return getModifiable() == CM_Modifiable; }
3810b57cec5SDimitry Andric 
3820b57cec5SDimitry Andric     /// Create a simple, modifiably lvalue
makeSimpleLValue()3830b57cec5SDimitry Andric     static Classification makeSimpleLValue() {
3840b57cec5SDimitry Andric       return Classification(CL_LValue, CM_Modifiable);
3850b57cec5SDimitry Andric     }
3860b57cec5SDimitry Andric 
3870b57cec5SDimitry Andric   };
3880b57cec5SDimitry Andric   /// Classify - Classify this expression according to the C++11
3890b57cec5SDimitry Andric   ///        expression taxonomy.
3900b57cec5SDimitry Andric   ///
3910b57cec5SDimitry Andric   /// C++11 defines ([basic.lval]) a new taxonomy of expressions to replace the
3920b57cec5SDimitry Andric   /// old lvalue vs rvalue. This function determines the type of expression this
3930b57cec5SDimitry Andric   /// is. There are three expression types:
3940b57cec5SDimitry Andric   /// - lvalues are classical lvalues as in C++03.
3950b57cec5SDimitry Andric   /// - prvalues are equivalent to rvalues in C++03.
3960b57cec5SDimitry Andric   /// - xvalues are expressions yielding unnamed rvalue references, e.g. a
3970b57cec5SDimitry Andric   ///   function returning an rvalue reference.
3980b57cec5SDimitry Andric   /// lvalues and xvalues are collectively referred to as glvalues, while
3990b57cec5SDimitry Andric   /// prvalues and xvalues together form rvalues.
Classify(ASTContext & Ctx)4000b57cec5SDimitry Andric   Classification Classify(ASTContext &Ctx) const {
4010b57cec5SDimitry Andric     return ClassifyImpl(Ctx, nullptr);
4020b57cec5SDimitry Andric   }
4030b57cec5SDimitry Andric 
4040b57cec5SDimitry Andric   /// ClassifyModifiable - Classify this expression according to the
4050b57cec5SDimitry Andric   ///        C++11 expression taxonomy, and see if it is valid on the left side
4060b57cec5SDimitry Andric   ///        of an assignment.
4070b57cec5SDimitry Andric   ///
4080b57cec5SDimitry Andric   /// This function extends classify in that it also tests whether the
4090b57cec5SDimitry Andric   /// expression is modifiable (C99 6.3.2.1p1).
4100b57cec5SDimitry Andric   /// \param Loc A source location that might be filled with a relevant location
4110b57cec5SDimitry Andric   ///            if the expression is not modifiable.
ClassifyModifiable(ASTContext & Ctx,SourceLocation & Loc)4120b57cec5SDimitry Andric   Classification ClassifyModifiable(ASTContext &Ctx, SourceLocation &Loc) const{
4130b57cec5SDimitry Andric     return ClassifyImpl(Ctx, &Loc);
4140b57cec5SDimitry Andric   }
4150b57cec5SDimitry Andric 
416e8d8bef9SDimitry Andric   /// Returns the set of floating point options that apply to this expression.
417e8d8bef9SDimitry Andric   /// Only meaningful for operations on floating point values.
418e8d8bef9SDimitry Andric   FPOptions getFPFeaturesInEffect(const LangOptions &LO) const;
419e8d8bef9SDimitry Andric 
4200b57cec5SDimitry Andric   /// getValueKindForType - Given a formal return or parameter type,
4210b57cec5SDimitry Andric   /// give its value kind.
getValueKindForType(QualType T)4220b57cec5SDimitry Andric   static ExprValueKind getValueKindForType(QualType T) {
4230b57cec5SDimitry Andric     if (const ReferenceType *RT = T->getAs<ReferenceType>())
4240b57cec5SDimitry Andric       return (isa<LValueReferenceType>(RT)
4250b57cec5SDimitry Andric                 ? VK_LValue
4260b57cec5SDimitry Andric                 : (RT->getPointeeType()->isFunctionType()
4270b57cec5SDimitry Andric                      ? VK_LValue : VK_XValue));
428fe6060f1SDimitry Andric     return VK_PRValue;
4290b57cec5SDimitry Andric   }
4300b57cec5SDimitry Andric 
4310b57cec5SDimitry Andric   /// getValueKind - The value kind that this expression produces.
getValueKind()4320b57cec5SDimitry Andric   ExprValueKind getValueKind() const {
4330b57cec5SDimitry Andric     return static_cast<ExprValueKind>(ExprBits.ValueKind);
4340b57cec5SDimitry Andric   }
4350b57cec5SDimitry Andric 
4360b57cec5SDimitry Andric   /// getObjectKind - The object kind that this expression produces.
4370b57cec5SDimitry Andric   /// Object kinds are meaningful only for expressions that yield an
4380b57cec5SDimitry Andric   /// l-value or x-value.
getObjectKind()4390b57cec5SDimitry Andric   ExprObjectKind getObjectKind() const {
4400b57cec5SDimitry Andric     return static_cast<ExprObjectKind>(ExprBits.ObjectKind);
4410b57cec5SDimitry Andric   }
4420b57cec5SDimitry Andric 
isOrdinaryOrBitFieldObject()4430b57cec5SDimitry Andric   bool isOrdinaryOrBitFieldObject() const {
4440b57cec5SDimitry Andric     ExprObjectKind OK = getObjectKind();
4450b57cec5SDimitry Andric     return (OK == OK_Ordinary || OK == OK_BitField);
4460b57cec5SDimitry Andric   }
4470b57cec5SDimitry Andric 
4480b57cec5SDimitry Andric   /// setValueKind - Set the value kind produced by this expression.
setValueKind(ExprValueKind Cat)4490b57cec5SDimitry Andric   void setValueKind(ExprValueKind Cat) { ExprBits.ValueKind = Cat; }
4500b57cec5SDimitry Andric 
4510b57cec5SDimitry Andric   /// setObjectKind - Set the object kind produced by this expression.
setObjectKind(ExprObjectKind Cat)4520b57cec5SDimitry Andric   void setObjectKind(ExprObjectKind Cat) { ExprBits.ObjectKind = Cat; }
4530b57cec5SDimitry Andric 
4540b57cec5SDimitry Andric private:
4550b57cec5SDimitry Andric   Classification ClassifyImpl(ASTContext &Ctx, SourceLocation *Loc) const;
4560b57cec5SDimitry Andric 
4570b57cec5SDimitry Andric public:
4580b57cec5SDimitry Andric 
4590b57cec5SDimitry Andric   /// Returns true if this expression is a gl-value that
4600b57cec5SDimitry Andric   /// potentially refers to a bit-field.
4610b57cec5SDimitry Andric   ///
4620b57cec5SDimitry Andric   /// In C++, whether a gl-value refers to a bitfield is essentially
4630b57cec5SDimitry Andric   /// an aspect of the value-kind type system.
refersToBitField()4640b57cec5SDimitry Andric   bool refersToBitField() const { return getObjectKind() == OK_BitField; }
4650b57cec5SDimitry Andric 
4660b57cec5SDimitry Andric   /// If this expression refers to a bit-field, retrieve the
4670b57cec5SDimitry Andric   /// declaration of that bit-field.
4680b57cec5SDimitry Andric   ///
4690b57cec5SDimitry Andric   /// Note that this returns a non-null pointer in subtly different
4700b57cec5SDimitry Andric   /// places than refersToBitField returns true.  In particular, this can
4710b57cec5SDimitry Andric   /// return a non-null pointer even for r-values loaded from
4720b57cec5SDimitry Andric   /// bit-fields, but it will return null for a conditional bit-field.
4730b57cec5SDimitry Andric   FieldDecl *getSourceBitField();
4740b57cec5SDimitry Andric 
getSourceBitField()4750b57cec5SDimitry Andric   const FieldDecl *getSourceBitField() const {
4760b57cec5SDimitry Andric     return const_cast<Expr*>(this)->getSourceBitField();
4770b57cec5SDimitry Andric   }
4780b57cec5SDimitry Andric 
4790b57cec5SDimitry Andric   Decl *getReferencedDeclOfCallee();
getReferencedDeclOfCallee()4800b57cec5SDimitry Andric   const Decl *getReferencedDeclOfCallee() const {
4810b57cec5SDimitry Andric     return const_cast<Expr*>(this)->getReferencedDeclOfCallee();
4820b57cec5SDimitry Andric   }
4830b57cec5SDimitry Andric 
4840b57cec5SDimitry Andric   /// If this expression is an l-value for an Objective C
4850b57cec5SDimitry Andric   /// property, find the underlying property reference expression.
4860b57cec5SDimitry Andric   const ObjCPropertyRefExpr *getObjCProperty() const;
4870b57cec5SDimitry Andric 
4880b57cec5SDimitry Andric   /// Check if this expression is the ObjC 'self' implicit parameter.
4890b57cec5SDimitry Andric   bool isObjCSelfExpr() const;
4900b57cec5SDimitry Andric 
4910b57cec5SDimitry Andric   /// Returns whether this expression refers to a vector element.
4920b57cec5SDimitry Andric   bool refersToVectorElement() const;
4930b57cec5SDimitry Andric 
4945ffd83dbSDimitry Andric   /// Returns whether this expression refers to a matrix element.
refersToMatrixElement()4955ffd83dbSDimitry Andric   bool refersToMatrixElement() const {
4965ffd83dbSDimitry Andric     return getObjectKind() == OK_MatrixComponent;
4975ffd83dbSDimitry Andric   }
4985ffd83dbSDimitry Andric 
4990b57cec5SDimitry Andric   /// Returns whether this expression refers to a global register
5000b57cec5SDimitry Andric   /// variable.
5010b57cec5SDimitry Andric   bool refersToGlobalRegisterVar() const;
5020b57cec5SDimitry Andric 
5030b57cec5SDimitry Andric   /// Returns whether this expression has a placeholder type.
hasPlaceholderType()5040b57cec5SDimitry Andric   bool hasPlaceholderType() const {
5050b57cec5SDimitry Andric     return getType()->isPlaceholderType();
5060b57cec5SDimitry Andric   }
5070b57cec5SDimitry Andric 
5080b57cec5SDimitry Andric   /// Returns whether this expression has a specific placeholder type.
hasPlaceholderType(BuiltinType::Kind K)5090b57cec5SDimitry Andric   bool hasPlaceholderType(BuiltinType::Kind K) const {
5100b57cec5SDimitry Andric     assert(BuiltinType::isPlaceholderTypeKind(K));
5110b57cec5SDimitry Andric     if (const BuiltinType *BT = dyn_cast<BuiltinType>(getType()))
5120b57cec5SDimitry Andric       return BT->getKind() == K;
5130b57cec5SDimitry Andric     return false;
5140b57cec5SDimitry Andric   }
5150b57cec5SDimitry Andric 
5160b57cec5SDimitry Andric   /// isKnownToHaveBooleanValue - Return true if this is an integer expression
5170b57cec5SDimitry Andric   /// that is known to return 0 or 1.  This happens for _Bool/bool expressions
5180b57cec5SDimitry Andric   /// but also int expressions which are produced by things like comparisons in
5190b57cec5SDimitry Andric   /// C.
520480093f4SDimitry Andric   ///
521480093f4SDimitry Andric   /// \param Semantic If true, only return true for expressions that are known
522480093f4SDimitry Andric   /// to be semantically boolean, which might not be true even for expressions
523480093f4SDimitry Andric   /// that are known to evaluate to 0/1. For instance, reading an unsigned
524480093f4SDimitry Andric   /// bit-field with width '1' will evaluate to 0/1, but doesn't necessarily
525480093f4SDimitry Andric   /// semantically correspond to a bool.
526480093f4SDimitry Andric   bool isKnownToHaveBooleanValue(bool Semantic = true) const;
5270b57cec5SDimitry Andric 
528bdd1243dSDimitry Andric   /// Check whether this array fits the idiom of a flexible array member,
529bdd1243dSDimitry Andric   /// depending on the value of -fstrict-flex-array.
530bdd1243dSDimitry Andric   /// When IgnoreTemplateOrMacroSubstitution is set, it doesn't consider sizes
531bdd1243dSDimitry Andric   /// resulting from the substitution of a macro or a template as special sizes.
532bdd1243dSDimitry Andric   bool isFlexibleArrayMemberLike(
533bdd1243dSDimitry Andric       ASTContext &Context,
534bdd1243dSDimitry Andric       LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel,
535bdd1243dSDimitry Andric       bool IgnoreTemplateOrMacroSubstitution = false) const;
536bdd1243dSDimitry Andric 
537e8d8bef9SDimitry Andric   /// isIntegerConstantExpr - Return the value if this expression is a valid
538bdd1243dSDimitry Andric   /// integer constant expression.  If not a valid i-c-e, return std::nullopt
539bdd1243dSDimitry Andric   /// and fill in Loc (if specified) with the location of the invalid
540bdd1243dSDimitry Andric   /// expression.
5410b57cec5SDimitry Andric   ///
5420b57cec5SDimitry Andric   /// Note: This does not perform the implicit conversions required by C++11
5430b57cec5SDimitry Andric   /// [expr.const]p5.
544bdd1243dSDimitry Andric   std::optional<llvm::APSInt>
5455f757f3fSDimitry Andric   getIntegerConstantExpr(const ASTContext &Ctx,
5465f757f3fSDimitry Andric                          SourceLocation *Loc = nullptr) const;
5470b57cec5SDimitry Andric   bool isIntegerConstantExpr(const ASTContext &Ctx,
5480b57cec5SDimitry Andric                              SourceLocation *Loc = nullptr) const;
5490b57cec5SDimitry Andric 
5500b57cec5SDimitry Andric   /// isCXX98IntegralConstantExpr - Return true if this expression is an
5510b57cec5SDimitry Andric   /// integral constant expression in C++98. Can only be used in C++.
5520b57cec5SDimitry Andric   bool isCXX98IntegralConstantExpr(const ASTContext &Ctx) const;
5530b57cec5SDimitry Andric 
5540b57cec5SDimitry Andric   /// isCXX11ConstantExpr - Return true if this expression is a constant
5550b57cec5SDimitry Andric   /// expression in C++11. Can only be used in C++.
5560b57cec5SDimitry Andric   ///
5570b57cec5SDimitry Andric   /// Note: This does not perform the implicit conversions required by C++11
5580b57cec5SDimitry Andric   /// [expr.const]p5.
5590b57cec5SDimitry Andric   bool isCXX11ConstantExpr(const ASTContext &Ctx, APValue *Result = nullptr,
5600b57cec5SDimitry Andric                            SourceLocation *Loc = nullptr) const;
5610b57cec5SDimitry Andric 
5620b57cec5SDimitry Andric   /// isPotentialConstantExpr - Return true if this function's definition
5630b57cec5SDimitry Andric   /// might be usable in a constant expression in C++11, if it were marked
5640b57cec5SDimitry Andric   /// constexpr. Return false if the function can never produce a constant
5650b57cec5SDimitry Andric   /// expression, along with diagnostics describing why not.
5660b57cec5SDimitry Andric   static bool isPotentialConstantExpr(const FunctionDecl *FD,
5670b57cec5SDimitry Andric                                       SmallVectorImpl<
5680b57cec5SDimitry Andric                                         PartialDiagnosticAt> &Diags);
5690b57cec5SDimitry Andric 
5705f757f3fSDimitry Andric   /// isPotentialConstantExprUnevaluated - Return true if this expression might
5710b57cec5SDimitry Andric   /// be usable in a constant expression in C++11 in an unevaluated context, if
5720b57cec5SDimitry Andric   /// it were in function FD marked constexpr. Return false if the function can
5730b57cec5SDimitry Andric   /// never produce a constant expression, along with diagnostics describing
5740b57cec5SDimitry Andric   /// why not.
5750b57cec5SDimitry Andric   static bool isPotentialConstantExprUnevaluated(Expr *E,
5760b57cec5SDimitry Andric                                                  const FunctionDecl *FD,
5770b57cec5SDimitry Andric                                                  SmallVectorImpl<
5780b57cec5SDimitry Andric                                                    PartialDiagnosticAt> &Diags);
5790b57cec5SDimitry Andric 
5800b57cec5SDimitry Andric   /// isConstantInitializer - Returns true if this expression can be emitted to
5810b57cec5SDimitry Andric   /// IR as a constant, and thus can be used as a constant initializer in C.
5820b57cec5SDimitry Andric   /// If this expression is not constant and Culprit is non-null,
5830b57cec5SDimitry Andric   /// it is used to store the address of first non constant expr.
5840b57cec5SDimitry Andric   bool isConstantInitializer(ASTContext &Ctx, bool ForRef,
5850b57cec5SDimitry Andric                              const Expr **Culprit = nullptr) const;
5860b57cec5SDimitry Andric 
5870eae32dcSDimitry Andric   /// If this expression is an unambiguous reference to a single declaration,
5880eae32dcSDimitry Andric   /// in the style of __builtin_function_start, return that declaration.  Note
5890eae32dcSDimitry Andric   /// that this may return a non-static member function or field in C++ if this
5900eae32dcSDimitry Andric   /// expression is a member pointer constant.
5910eae32dcSDimitry Andric   const ValueDecl *getAsBuiltinConstantDeclRef(const ASTContext &Context) const;
5920eae32dcSDimitry Andric 
5930b57cec5SDimitry Andric   /// EvalStatus is a struct with detailed info about an evaluation in progress.
5940b57cec5SDimitry Andric   struct EvalStatus {
5950b57cec5SDimitry Andric     /// Whether the evaluated expression has side effects.
5960b57cec5SDimitry Andric     /// For example, (f() && 0) can be folded, but it still has side effects.
59706c3fb27SDimitry Andric     bool HasSideEffects = false;
5980b57cec5SDimitry Andric 
5990b57cec5SDimitry Andric     /// Whether the evaluation hit undefined behavior.
6000b57cec5SDimitry Andric     /// For example, 1.0 / 0.0 can be folded to Inf, but has undefined behavior.
6010b57cec5SDimitry Andric     /// Likewise, INT_MAX + 1 can be folded to INT_MIN, but has UB.
60206c3fb27SDimitry Andric     bool HasUndefinedBehavior = false;
6030b57cec5SDimitry Andric 
6040b57cec5SDimitry Andric     /// Diag - If this is non-null, it will be filled in with a stack of notes
6050b57cec5SDimitry Andric     /// indicating why evaluation failed (or why it failed to produce a constant
6060b57cec5SDimitry Andric     /// expression).
6070b57cec5SDimitry Andric     /// If the expression is unfoldable, the notes will indicate why it's not
6080b57cec5SDimitry Andric     /// foldable. If the expression is foldable, but not a constant expression,
6090b57cec5SDimitry Andric     /// the notes will describes why it isn't a constant expression. If the
6100b57cec5SDimitry Andric     /// expression *is* a constant expression, no notes will be produced.
6115f757f3fSDimitry Andric     ///
6125f757f3fSDimitry Andric     /// FIXME: this causes significant performance concerns and should be
6135f757f3fSDimitry Andric     /// refactored at some point. Not all evaluations of the constant
6145f757f3fSDimitry Andric     /// expression interpreter will display the given diagnostics, this means
6155f757f3fSDimitry Andric     /// those kinds of uses are paying the expense of generating a diagnostic
6165f757f3fSDimitry Andric     /// (which may include expensive operations like converting APValue objects
6175f757f3fSDimitry Andric     /// to a string representation).
61806c3fb27SDimitry Andric     SmallVectorImpl<PartialDiagnosticAt> *Diag = nullptr;
6190b57cec5SDimitry Andric 
62006c3fb27SDimitry Andric     EvalStatus() = default;
6210b57cec5SDimitry Andric 
6220b57cec5SDimitry Andric     // hasSideEffects - Return true if the evaluated expression has
6230b57cec5SDimitry Andric     // side effects.
hasSideEffectsEvalStatus6240b57cec5SDimitry Andric     bool hasSideEffects() const {
6250b57cec5SDimitry Andric       return HasSideEffects;
6260b57cec5SDimitry Andric     }
6270b57cec5SDimitry Andric   };
6280b57cec5SDimitry Andric 
6290b57cec5SDimitry Andric   /// EvalResult is a struct with detailed info about an evaluated expression.
6300b57cec5SDimitry Andric   struct EvalResult : EvalStatus {
6310b57cec5SDimitry Andric     /// Val - This is the value the expression can be folded to.
6320b57cec5SDimitry Andric     APValue Val;
6330b57cec5SDimitry Andric 
6340b57cec5SDimitry Andric     // isGlobalLValue - Return true if the evaluated lvalue expression
6350b57cec5SDimitry Andric     // is global.
6360b57cec5SDimitry Andric     bool isGlobalLValue() const;
6370b57cec5SDimitry Andric   };
6380b57cec5SDimitry Andric 
6390b57cec5SDimitry Andric   /// EvaluateAsRValue - Return true if this is a constant which we can fold to
6400b57cec5SDimitry Andric   /// an rvalue using any crazy technique (that has nothing to do with language
6410b57cec5SDimitry Andric   /// standards) that we want to, even if the expression has side-effects. If
6420b57cec5SDimitry Andric   /// this function returns true, it returns the folded constant in Result. If
6430b57cec5SDimitry Andric   /// the expression is a glvalue, an lvalue-to-rvalue conversion will be
6440b57cec5SDimitry Andric   /// applied.
6450b57cec5SDimitry Andric   bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx,
6460b57cec5SDimitry Andric                         bool InConstantContext = false) const;
6470b57cec5SDimitry Andric 
6480b57cec5SDimitry Andric   /// EvaluateAsBooleanCondition - Return true if this is a constant
6490b57cec5SDimitry Andric   /// which we can fold and convert to a boolean condition using
6500b57cec5SDimitry Andric   /// any crazy technique that we want to, even if the expression has
6510b57cec5SDimitry Andric   /// side-effects.
6520b57cec5SDimitry Andric   bool EvaluateAsBooleanCondition(bool &Result, const ASTContext &Ctx,
6530b57cec5SDimitry Andric                                   bool InConstantContext = false) const;
6540b57cec5SDimitry Andric 
6550b57cec5SDimitry Andric   enum SideEffectsKind {
6560b57cec5SDimitry Andric     SE_NoSideEffects,          ///< Strictly evaluate the expression.
6570b57cec5SDimitry Andric     SE_AllowUndefinedBehavior, ///< Allow UB that we can give a value, but not
6580b57cec5SDimitry Andric                                ///< arbitrary unmodeled side effects.
6590b57cec5SDimitry Andric     SE_AllowSideEffects        ///< Allow any unmodeled side effect.
6600b57cec5SDimitry Andric   };
6610b57cec5SDimitry Andric 
6620b57cec5SDimitry Andric   /// EvaluateAsInt - Return true if this is a constant which we can fold and
6630b57cec5SDimitry Andric   /// convert to an integer, using any crazy technique that we want to.
6640b57cec5SDimitry Andric   bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx,
6650b57cec5SDimitry Andric                      SideEffectsKind AllowSideEffects = SE_NoSideEffects,
6660b57cec5SDimitry Andric                      bool InConstantContext = false) const;
6670b57cec5SDimitry Andric 
6680b57cec5SDimitry Andric   /// EvaluateAsFloat - Return true if this is a constant which we can fold and
6690b57cec5SDimitry Andric   /// convert to a floating point value, using any crazy technique that we
6700b57cec5SDimitry Andric   /// want to.
6710b57cec5SDimitry Andric   bool EvaluateAsFloat(llvm::APFloat &Result, const ASTContext &Ctx,
6720b57cec5SDimitry Andric                        SideEffectsKind AllowSideEffects = SE_NoSideEffects,
6730b57cec5SDimitry Andric                        bool InConstantContext = false) const;
6740b57cec5SDimitry Andric 
67506c3fb27SDimitry Andric   /// EvaluateAsFixedPoint - Return true if this is a constant which we can fold
67606c3fb27SDimitry Andric   /// and convert to a fixed point value.
6770b57cec5SDimitry Andric   bool EvaluateAsFixedPoint(EvalResult &Result, const ASTContext &Ctx,
6780b57cec5SDimitry Andric                             SideEffectsKind AllowSideEffects = SE_NoSideEffects,
6790b57cec5SDimitry Andric                             bool InConstantContext = false) const;
6800b57cec5SDimitry Andric 
6810b57cec5SDimitry Andric   /// isEvaluatable - Call EvaluateAsRValue to see if this expression can be
6820b57cec5SDimitry Andric   /// constant folded without side-effects, but discard the result.
6830b57cec5SDimitry Andric   bool isEvaluatable(const ASTContext &Ctx,
6840b57cec5SDimitry Andric                      SideEffectsKind AllowSideEffects = SE_NoSideEffects) const;
6850b57cec5SDimitry Andric 
6860b57cec5SDimitry Andric   /// HasSideEffects - This routine returns true for all those expressions
6870b57cec5SDimitry Andric   /// which have any effect other than producing a value. Example is a function
6880b57cec5SDimitry Andric   /// call, volatile variable read, or throwing an exception. If
6890b57cec5SDimitry Andric   /// IncludePossibleEffects is false, this call treats certain expressions with
6900b57cec5SDimitry Andric   /// potential side effects (such as function call-like expressions,
6910b57cec5SDimitry Andric   /// instantiation-dependent expressions, or invocations from a macro) as not
6920b57cec5SDimitry Andric   /// having side effects.
6930b57cec5SDimitry Andric   bool HasSideEffects(const ASTContext &Ctx,
6940b57cec5SDimitry Andric                       bool IncludePossibleEffects = true) const;
6950b57cec5SDimitry Andric 
6960b57cec5SDimitry Andric   /// Determine whether this expression involves a call to any function
6970b57cec5SDimitry Andric   /// that is not trivial.
6980b57cec5SDimitry Andric   bool hasNonTrivialCall(const ASTContext &Ctx) const;
6990b57cec5SDimitry Andric 
7000b57cec5SDimitry Andric   /// EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded
7010b57cec5SDimitry Andric   /// integer. This must be called on an expression that constant folds to an
7020b57cec5SDimitry Andric   /// integer.
7030b57cec5SDimitry Andric   llvm::APSInt EvaluateKnownConstInt(
7040b57cec5SDimitry Andric       const ASTContext &Ctx,
7050b57cec5SDimitry Andric       SmallVectorImpl<PartialDiagnosticAt> *Diag = nullptr) const;
7060b57cec5SDimitry Andric 
7070b57cec5SDimitry Andric   llvm::APSInt EvaluateKnownConstIntCheckOverflow(
7080b57cec5SDimitry Andric       const ASTContext &Ctx,
7090b57cec5SDimitry Andric       SmallVectorImpl<PartialDiagnosticAt> *Diag = nullptr) const;
7100b57cec5SDimitry Andric 
7110b57cec5SDimitry Andric   void EvaluateForOverflow(const ASTContext &Ctx) const;
7120b57cec5SDimitry Andric 
7130b57cec5SDimitry Andric   /// EvaluateAsLValue - Evaluate an expression to see if we can fold it to an
7140b57cec5SDimitry Andric   /// lvalue with link time known address, with no side-effects.
7150b57cec5SDimitry Andric   bool EvaluateAsLValue(EvalResult &Result, const ASTContext &Ctx,
7160b57cec5SDimitry Andric                         bool InConstantContext = false) const;
7170b57cec5SDimitry Andric 
7180b57cec5SDimitry Andric   /// EvaluateAsInitializer - Evaluate an expression as if it were the
7190b57cec5SDimitry Andric   /// initializer of the given declaration. Returns true if the initializer
7200b57cec5SDimitry Andric   /// can be folded to a constant, and produces any relevant notes. In C++11,
7210b57cec5SDimitry Andric   /// notes will be produced if the expression is not a constant expression.
7220b57cec5SDimitry Andric   bool EvaluateAsInitializer(APValue &Result, const ASTContext &Ctx,
7230b57cec5SDimitry Andric                              const VarDecl *VD,
72406c3fb27SDimitry Andric                              SmallVectorImpl<PartialDiagnosticAt> &Notes,
72506c3fb27SDimitry Andric                              bool IsConstantInitializer) const;
7260b57cec5SDimitry Andric 
7270b57cec5SDimitry Andric   /// EvaluateWithSubstitution - Evaluate an expression as if from the context
7280b57cec5SDimitry Andric   /// of a call to the given function with the given arguments, inside an
7290b57cec5SDimitry Andric   /// unevaluated context. Returns true if the expression could be folded to a
7300b57cec5SDimitry Andric   /// constant.
7310b57cec5SDimitry Andric   bool EvaluateWithSubstitution(APValue &Value, ASTContext &Ctx,
7320b57cec5SDimitry Andric                                 const FunctionDecl *Callee,
7330b57cec5SDimitry Andric                                 ArrayRef<const Expr*> Args,
7340b57cec5SDimitry Andric                                 const Expr *This = nullptr) const;
7350b57cec5SDimitry Andric 
736e8d8bef9SDimitry Andric   enum class ConstantExprKind {
737e8d8bef9SDimitry Andric     /// An integer constant expression (an array bound, enumerator, case value,
738e8d8bef9SDimitry Andric     /// bit-field width, or similar) or similar.
739e8d8bef9SDimitry Andric     Normal,
740e8d8bef9SDimitry Andric     /// A non-class template argument. Such a value is only used for mangling,
741e8d8bef9SDimitry Andric     /// not for code generation, so can refer to dllimported functions.
742e8d8bef9SDimitry Andric     NonClassTemplateArgument,
743e8d8bef9SDimitry Andric     /// A class template argument. Such a value is used for code generation.
744e8d8bef9SDimitry Andric     ClassTemplateArgument,
745e8d8bef9SDimitry Andric     /// An immediate invocation. The destruction of the end result of this
746e8d8bef9SDimitry Andric     /// evaluation is not part of the evaluation, but all other temporaries
747e8d8bef9SDimitry Andric     /// are destroyed.
748e8d8bef9SDimitry Andric     ImmediateInvocation,
749e8d8bef9SDimitry Andric   };
7500b57cec5SDimitry Andric 
751e8d8bef9SDimitry Andric   /// Evaluate an expression that is required to be a constant expression. Does
752e8d8bef9SDimitry Andric   /// not check the syntactic constraints for C and C++98 constant expressions.
753e8d8bef9SDimitry Andric   bool EvaluateAsConstantExpr(
754e8d8bef9SDimitry Andric       EvalResult &Result, const ASTContext &Ctx,
755e8d8bef9SDimitry Andric       ConstantExprKind Kind = ConstantExprKind::Normal) const;
7560b57cec5SDimitry Andric 
7570b57cec5SDimitry Andric   /// If the current Expr is a pointer, this will try to statically
7580b57cec5SDimitry Andric   /// determine the number of bytes available where the pointer is pointing.
7590b57cec5SDimitry Andric   /// Returns true if all of the above holds and we were able to figure out the
7600b57cec5SDimitry Andric   /// size, false otherwise.
7610b57cec5SDimitry Andric   ///
7620b57cec5SDimitry Andric   /// \param Type - How to evaluate the size of the Expr, as defined by the
7630b57cec5SDimitry Andric   /// "type" parameter of __builtin_object_size
7640b57cec5SDimitry Andric   bool tryEvaluateObjectSize(uint64_t &Result, ASTContext &Ctx,
7650b57cec5SDimitry Andric                              unsigned Type) const;
7660b57cec5SDimitry Andric 
767349cc55cSDimitry Andric   /// If the current Expr is a pointer, this will try to statically
768349cc55cSDimitry Andric   /// determine the strlen of the string pointed to.
769349cc55cSDimitry Andric   /// Returns true if all of the above holds and we were able to figure out the
770349cc55cSDimitry Andric   /// strlen, false otherwise.
771349cc55cSDimitry Andric   bool tryEvaluateStrLen(uint64_t &Result, ASTContext &Ctx) const;
772349cc55cSDimitry Andric 
77306c3fb27SDimitry Andric   bool EvaluateCharRangeAsString(std::string &Result,
77406c3fb27SDimitry Andric                                  const Expr *SizeExpression,
77506c3fb27SDimitry Andric                                  const Expr *PtrExpression, ASTContext &Ctx,
77606c3fb27SDimitry Andric                                  EvalResult &Status) const;
77706c3fb27SDimitry Andric 
7780b57cec5SDimitry Andric   /// Enumeration used to describe the kind of Null pointer constant
7790b57cec5SDimitry Andric   /// returned from \c isNullPointerConstant().
7800b57cec5SDimitry Andric   enum NullPointerConstantKind {
7810b57cec5SDimitry Andric     /// Expression is not a Null pointer constant.
7820b57cec5SDimitry Andric     NPCK_NotNull = 0,
7830b57cec5SDimitry Andric 
7840b57cec5SDimitry Andric     /// Expression is a Null pointer constant built from a zero integer
7850b57cec5SDimitry Andric     /// expression that is not a simple, possibly parenthesized, zero literal.
7860b57cec5SDimitry Andric     /// C++ Core Issue 903 will classify these expressions as "not pointers"
7870b57cec5SDimitry Andric     /// once it is adopted.
7880b57cec5SDimitry Andric     /// http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#903
7890b57cec5SDimitry Andric     NPCK_ZeroExpression,
7900b57cec5SDimitry Andric 
7910b57cec5SDimitry Andric     /// Expression is a Null pointer constant built from a literal zero.
7920b57cec5SDimitry Andric     NPCK_ZeroLiteral,
7930b57cec5SDimitry Andric 
7940b57cec5SDimitry Andric     /// Expression is a C++11 nullptr.
7950b57cec5SDimitry Andric     NPCK_CXX11_nullptr,
7960b57cec5SDimitry Andric 
7970b57cec5SDimitry Andric     /// Expression is a GNU-style __null constant.
7980b57cec5SDimitry Andric     NPCK_GNUNull
7990b57cec5SDimitry Andric   };
8000b57cec5SDimitry Andric 
8010b57cec5SDimitry Andric   /// Enumeration used to describe how \c isNullPointerConstant()
8020b57cec5SDimitry Andric   /// should cope with value-dependent expressions.
8030b57cec5SDimitry Andric   enum NullPointerConstantValueDependence {
8040b57cec5SDimitry Andric     /// Specifies that the expression should never be value-dependent.
8050b57cec5SDimitry Andric     NPC_NeverValueDependent = 0,
8060b57cec5SDimitry Andric 
8070b57cec5SDimitry Andric     /// Specifies that a value-dependent expression of integral or
8080b57cec5SDimitry Andric     /// dependent type should be considered a null pointer constant.
8090b57cec5SDimitry Andric     NPC_ValueDependentIsNull,
8100b57cec5SDimitry Andric 
8110b57cec5SDimitry Andric     /// Specifies that a value-dependent expression should be considered
8120b57cec5SDimitry Andric     /// to never be a null pointer constant.
8130b57cec5SDimitry Andric     NPC_ValueDependentIsNotNull
8140b57cec5SDimitry Andric   };
8150b57cec5SDimitry Andric 
8160b57cec5SDimitry Andric   /// isNullPointerConstant - C99 6.3.2.3p3 - Test if this reduces down to
8170b57cec5SDimitry Andric   /// a Null pointer constant. The return value can further distinguish the
8180b57cec5SDimitry Andric   /// kind of NULL pointer constant that was detected.
8190b57cec5SDimitry Andric   NullPointerConstantKind isNullPointerConstant(
8200b57cec5SDimitry Andric       ASTContext &Ctx,
8210b57cec5SDimitry Andric       NullPointerConstantValueDependence NPC) const;
8220b57cec5SDimitry Andric 
8230b57cec5SDimitry Andric   /// isOBJCGCCandidate - Return true if this expression may be used in a read/
8240b57cec5SDimitry Andric   /// write barrier.
8250b57cec5SDimitry Andric   bool isOBJCGCCandidate(ASTContext &Ctx) const;
8260b57cec5SDimitry Andric 
8270b57cec5SDimitry Andric   /// Returns true if this expression is a bound member function.
8280b57cec5SDimitry Andric   bool isBoundMemberFunction(ASTContext &Ctx) const;
8290b57cec5SDimitry Andric 
8300b57cec5SDimitry Andric   /// Given an expression of bound-member type, find the type
8310b57cec5SDimitry Andric   /// of the member.  Returns null if this is an *overloaded* bound
8320b57cec5SDimitry Andric   /// member expression.
8330b57cec5SDimitry Andric   static QualType findBoundMemberType(const Expr *expr);
8340b57cec5SDimitry Andric 
83506c3fb27SDimitry Andric   /// Skip past any invisible AST nodes which might surround this
836480093f4SDimitry Andric   /// statement, such as ExprWithCleanups or ImplicitCastExpr nodes,
837480093f4SDimitry Andric   /// but also injected CXXMemberExpr and CXXConstructExpr which represent
838480093f4SDimitry Andric   /// implicit conversions.
839480093f4SDimitry Andric   Expr *IgnoreUnlessSpelledInSource();
IgnoreUnlessSpelledInSource()840480093f4SDimitry Andric   const Expr *IgnoreUnlessSpelledInSource() const {
841480093f4SDimitry Andric     return const_cast<Expr *>(this)->IgnoreUnlessSpelledInSource();
842480093f4SDimitry Andric   }
843480093f4SDimitry Andric 
8440b57cec5SDimitry Andric   /// Skip past any implicit casts which might surround this expression until
8450b57cec5SDimitry Andric   /// reaching a fixed point. Skips:
8460b57cec5SDimitry Andric   /// * ImplicitCastExpr
8470b57cec5SDimitry Andric   /// * FullExpr
8480b57cec5SDimitry Andric   Expr *IgnoreImpCasts() LLVM_READONLY;
IgnoreImpCasts()8490b57cec5SDimitry Andric   const Expr *IgnoreImpCasts() const {
8500b57cec5SDimitry Andric     return const_cast<Expr *>(this)->IgnoreImpCasts();
8510b57cec5SDimitry Andric   }
8520b57cec5SDimitry Andric 
8530b57cec5SDimitry Andric   /// Skip past any casts which might surround this expression until reaching
8540b57cec5SDimitry Andric   /// a fixed point. Skips:
8550b57cec5SDimitry Andric   /// * CastExpr
8560b57cec5SDimitry Andric   /// * FullExpr
8570b57cec5SDimitry Andric   /// * MaterializeTemporaryExpr
8580b57cec5SDimitry Andric   /// * SubstNonTypeTemplateParmExpr
8590b57cec5SDimitry Andric   Expr *IgnoreCasts() LLVM_READONLY;
IgnoreCasts()8600b57cec5SDimitry Andric   const Expr *IgnoreCasts() const {
8610b57cec5SDimitry Andric     return const_cast<Expr *>(this)->IgnoreCasts();
8620b57cec5SDimitry Andric   }
8630b57cec5SDimitry Andric 
8640b57cec5SDimitry Andric   /// Skip past any implicit AST nodes which might surround this expression
8650b57cec5SDimitry Andric   /// until reaching a fixed point. Skips:
8660b57cec5SDimitry Andric   /// * What IgnoreImpCasts() skips
8670b57cec5SDimitry Andric   /// * MaterializeTemporaryExpr
8680b57cec5SDimitry Andric   /// * CXXBindTemporaryExpr
8690b57cec5SDimitry Andric   Expr *IgnoreImplicit() LLVM_READONLY;
IgnoreImplicit()8700b57cec5SDimitry Andric   const Expr *IgnoreImplicit() const {
8710b57cec5SDimitry Andric     return const_cast<Expr *>(this)->IgnoreImplicit();
8720b57cec5SDimitry Andric   }
8730b57cec5SDimitry Andric 
874480093f4SDimitry Andric   /// Skip past any implicit AST nodes which might surround this expression
875480093f4SDimitry Andric   /// until reaching a fixed point. Same as IgnoreImplicit, except that it
876480093f4SDimitry Andric   /// also skips over implicit calls to constructors and conversion functions.
877480093f4SDimitry Andric   ///
878480093f4SDimitry Andric   /// FIXME: Should IgnoreImplicit do this?
879480093f4SDimitry Andric   Expr *IgnoreImplicitAsWritten() LLVM_READONLY;
IgnoreImplicitAsWritten()880480093f4SDimitry Andric   const Expr *IgnoreImplicitAsWritten() const {
881480093f4SDimitry Andric     return const_cast<Expr *>(this)->IgnoreImplicitAsWritten();
882480093f4SDimitry Andric   }
883480093f4SDimitry Andric 
8840b57cec5SDimitry Andric   /// Skip past any parentheses which might surround this expression until
8850b57cec5SDimitry Andric   /// reaching a fixed point. Skips:
8860b57cec5SDimitry Andric   /// * ParenExpr
8870b57cec5SDimitry Andric   /// * UnaryOperator if `UO_Extension`
8880b57cec5SDimitry Andric   /// * GenericSelectionExpr if `!isResultDependent()`
8890b57cec5SDimitry Andric   /// * ChooseExpr if `!isConditionDependent()`
8900b57cec5SDimitry Andric   /// * ConstantExpr
8910b57cec5SDimitry Andric   Expr *IgnoreParens() LLVM_READONLY;
IgnoreParens()8920b57cec5SDimitry Andric   const Expr *IgnoreParens() const {
8930b57cec5SDimitry Andric     return const_cast<Expr *>(this)->IgnoreParens();
8940b57cec5SDimitry Andric   }
8950b57cec5SDimitry Andric 
8960b57cec5SDimitry Andric   /// Skip past any parentheses and implicit casts which might surround this
8970b57cec5SDimitry Andric   /// expression until reaching a fixed point.
8980b57cec5SDimitry Andric   /// FIXME: IgnoreParenImpCasts really ought to be equivalent to
8990b57cec5SDimitry Andric   /// IgnoreParens() + IgnoreImpCasts() until reaching a fixed point. However
9000b57cec5SDimitry Andric   /// this is currently not the case. Instead IgnoreParenImpCasts() skips:
9010b57cec5SDimitry Andric   /// * What IgnoreParens() skips
9020b57cec5SDimitry Andric   /// * What IgnoreImpCasts() skips
9030b57cec5SDimitry Andric   /// * MaterializeTemporaryExpr
9040b57cec5SDimitry Andric   /// * SubstNonTypeTemplateParmExpr
9050b57cec5SDimitry Andric   Expr *IgnoreParenImpCasts() LLVM_READONLY;
IgnoreParenImpCasts()9060b57cec5SDimitry Andric   const Expr *IgnoreParenImpCasts() const {
9070b57cec5SDimitry Andric     return const_cast<Expr *>(this)->IgnoreParenImpCasts();
9080b57cec5SDimitry Andric   }
9090b57cec5SDimitry Andric 
9100b57cec5SDimitry Andric   /// Skip past any parentheses and casts which might surround this expression
9110b57cec5SDimitry Andric   /// until reaching a fixed point. Skips:
9120b57cec5SDimitry Andric   /// * What IgnoreParens() skips
9130b57cec5SDimitry Andric   /// * What IgnoreCasts() skips
9140b57cec5SDimitry Andric   Expr *IgnoreParenCasts() LLVM_READONLY;
IgnoreParenCasts()9150b57cec5SDimitry Andric   const Expr *IgnoreParenCasts() const {
9160b57cec5SDimitry Andric     return const_cast<Expr *>(this)->IgnoreParenCasts();
9170b57cec5SDimitry Andric   }
9180b57cec5SDimitry Andric 
9190b57cec5SDimitry Andric   /// Skip conversion operators. If this Expr is a call to a conversion
9200b57cec5SDimitry Andric   /// operator, return the argument.
921e8d8bef9SDimitry Andric   Expr *IgnoreConversionOperatorSingleStep() LLVM_READONLY;
IgnoreConversionOperatorSingleStep()922e8d8bef9SDimitry Andric   const Expr *IgnoreConversionOperatorSingleStep() const {
923e8d8bef9SDimitry Andric     return const_cast<Expr *>(this)->IgnoreConversionOperatorSingleStep();
9240b57cec5SDimitry Andric   }
9250b57cec5SDimitry Andric 
9260b57cec5SDimitry Andric   /// Skip past any parentheses and lvalue casts which might surround this
9270b57cec5SDimitry Andric   /// expression until reaching a fixed point. Skips:
9280b57cec5SDimitry Andric   /// * What IgnoreParens() skips
9290b57cec5SDimitry Andric   /// * What IgnoreCasts() skips, except that only lvalue-to-rvalue
9300b57cec5SDimitry Andric   ///   casts are skipped
9310b57cec5SDimitry Andric   /// FIXME: This is intended purely as a temporary workaround for code
9320b57cec5SDimitry Andric   /// that hasn't yet been rewritten to do the right thing about those
9330b57cec5SDimitry Andric   /// casts, and may disappear along with the last internal use.
9340b57cec5SDimitry Andric   Expr *IgnoreParenLValueCasts() LLVM_READONLY;
IgnoreParenLValueCasts()9350b57cec5SDimitry Andric   const Expr *IgnoreParenLValueCasts() const {
9360b57cec5SDimitry Andric     return const_cast<Expr *>(this)->IgnoreParenLValueCasts();
9370b57cec5SDimitry Andric   }
9380b57cec5SDimitry Andric 
93906c3fb27SDimitry Andric   /// Skip past any parentheses and casts which do not change the value
9400b57cec5SDimitry Andric   /// (including ptr->int casts of the same size) until reaching a fixed point.
9410b57cec5SDimitry Andric   /// Skips:
9420b57cec5SDimitry Andric   /// * What IgnoreParens() skips
9430b57cec5SDimitry Andric   /// * CastExpr which do not change the value
9440b57cec5SDimitry Andric   /// * SubstNonTypeTemplateParmExpr
9450b57cec5SDimitry Andric   Expr *IgnoreParenNoopCasts(const ASTContext &Ctx) LLVM_READONLY;
IgnoreParenNoopCasts(const ASTContext & Ctx)9460b57cec5SDimitry Andric   const Expr *IgnoreParenNoopCasts(const ASTContext &Ctx) const {
9470b57cec5SDimitry Andric     return const_cast<Expr *>(this)->IgnoreParenNoopCasts(Ctx);
9480b57cec5SDimitry Andric   }
9490b57cec5SDimitry Andric 
9500b57cec5SDimitry Andric   /// Skip past any parentheses and derived-to-base casts until reaching a
9510b57cec5SDimitry Andric   /// fixed point. Skips:
9520b57cec5SDimitry Andric   /// * What IgnoreParens() skips
9530b57cec5SDimitry Andric   /// * CastExpr which represent a derived-to-base cast (CK_DerivedToBase,
9540b57cec5SDimitry Andric   ///   CK_UncheckedDerivedToBase and CK_NoOp)
955e8d8bef9SDimitry Andric   Expr *IgnoreParenBaseCasts() LLVM_READONLY;
IgnoreParenBaseCasts()956e8d8bef9SDimitry Andric   const Expr *IgnoreParenBaseCasts() const {
957e8d8bef9SDimitry Andric     return const_cast<Expr *>(this)->IgnoreParenBaseCasts();
9580b57cec5SDimitry Andric   }
9590b57cec5SDimitry Andric 
9600b57cec5SDimitry Andric   /// Determine whether this expression is a default function argument.
9610b57cec5SDimitry Andric   ///
9620b57cec5SDimitry Andric   /// Default arguments are implicitly generated in the abstract syntax tree
9630b57cec5SDimitry Andric   /// by semantic analysis for function calls, object constructions, etc. in
9640b57cec5SDimitry Andric   /// C++. Default arguments are represented by \c CXXDefaultArgExpr nodes;
9650b57cec5SDimitry Andric   /// this routine also looks through any implicit casts to determine whether
9660b57cec5SDimitry Andric   /// the expression is a default argument.
9670b57cec5SDimitry Andric   bool isDefaultArgument() const;
9680b57cec5SDimitry Andric 
9690b57cec5SDimitry Andric   /// Determine whether the result of this expression is a
9700b57cec5SDimitry Andric   /// temporary object of the given class type.
9710b57cec5SDimitry Andric   bool isTemporaryObject(ASTContext &Ctx, const CXXRecordDecl *TempTy) const;
9720b57cec5SDimitry Andric 
9730b57cec5SDimitry Andric   /// Whether this expression is an implicit reference to 'this' in C++.
9740b57cec5SDimitry Andric   bool isImplicitCXXThis() const;
9750b57cec5SDimitry Andric 
9760b57cec5SDimitry Andric   static bool hasAnyTypeDependentArguments(ArrayRef<Expr *> Exprs);
9770b57cec5SDimitry Andric 
9780b57cec5SDimitry Andric   /// For an expression of class type or pointer to class type,
9790b57cec5SDimitry Andric   /// return the most derived class decl the expression is known to refer to.
9800b57cec5SDimitry Andric   ///
9810b57cec5SDimitry Andric   /// If this expression is a cast, this method looks through it to find the
9820b57cec5SDimitry Andric   /// most derived decl that can be inferred from the expression.
9830b57cec5SDimitry Andric   /// This is valid because derived-to-base conversions have undefined
9840b57cec5SDimitry Andric   /// behavior if the object isn't dynamically of the derived type.
9850b57cec5SDimitry Andric   const CXXRecordDecl *getBestDynamicClassType() const;
9860b57cec5SDimitry Andric 
9870b57cec5SDimitry Andric   /// Get the inner expression that determines the best dynamic class.
9880b57cec5SDimitry Andric   /// If this is a prvalue, we guarantee that it is of the most-derived type
9890b57cec5SDimitry Andric   /// for the object itself.
9900b57cec5SDimitry Andric   const Expr *getBestDynamicClassTypeExpr() const;
9910b57cec5SDimitry Andric 
9920b57cec5SDimitry Andric   /// Walk outwards from an expression we want to bind a reference to and
9930b57cec5SDimitry Andric   /// find the expression whose lifetime needs to be extended. Record
9940b57cec5SDimitry Andric   /// the LHSs of comma expressions and adjustments needed along the path.
9950b57cec5SDimitry Andric   const Expr *skipRValueSubobjectAdjustments(
9960b57cec5SDimitry Andric       SmallVectorImpl<const Expr *> &CommaLHS,
9970b57cec5SDimitry Andric       SmallVectorImpl<SubobjectAdjustment> &Adjustments) const;
skipRValueSubobjectAdjustments()9980b57cec5SDimitry Andric   const Expr *skipRValueSubobjectAdjustments() const {
9990b57cec5SDimitry Andric     SmallVector<const Expr *, 8> CommaLHSs;
10000b57cec5SDimitry Andric     SmallVector<SubobjectAdjustment, 8> Adjustments;
10010b57cec5SDimitry Andric     return skipRValueSubobjectAdjustments(CommaLHSs, Adjustments);
10020b57cec5SDimitry Andric   }
10030b57cec5SDimitry Andric 
1004a7dea167SDimitry Andric   /// Checks that the two Expr's will refer to the same value as a comparison
1005a7dea167SDimitry Andric   /// operand.  The caller must ensure that the values referenced by the Expr's
1006a7dea167SDimitry Andric   /// are not modified between E1 and E2 or the result my be invalid.
1007a7dea167SDimitry Andric   static bool isSameComparisonOperand(const Expr* E1, const Expr* E2);
1008a7dea167SDimitry Andric 
classof(const Stmt * T)10090b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
10100b57cec5SDimitry Andric     return T->getStmtClass() >= firstExprConstant &&
10110b57cec5SDimitry Andric            T->getStmtClass() <= lastExprConstant;
10120b57cec5SDimitry Andric   }
10130b57cec5SDimitry Andric };
1014e8d8bef9SDimitry Andric // PointerLikeTypeTraits is specialized so it can be used with a forward-decl of
1015e8d8bef9SDimitry Andric // Expr. Verify that we got it right.
1016e8d8bef9SDimitry Andric static_assert(llvm::PointerLikeTypeTraits<Expr *>::NumLowBitsAvailable <=
1017e8d8bef9SDimitry Andric                   llvm::detail::ConstantLog2<alignof(Expr)>::value,
1018e8d8bef9SDimitry Andric               "PointerLikeTypeTraits<Expr*> assumes too much alignment.");
1019e8d8bef9SDimitry Andric 
1020e8d8bef9SDimitry Andric using ConstantExprKind = Expr::ConstantExprKind;
10210b57cec5SDimitry Andric 
10220b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
10230b57cec5SDimitry Andric // Wrapper Expressions.
10240b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
10250b57cec5SDimitry Andric 
10260b57cec5SDimitry Andric /// FullExpr - Represents a "full-expression" node.
10270b57cec5SDimitry Andric class FullExpr : public Expr {
10280b57cec5SDimitry Andric protected:
10290b57cec5SDimitry Andric  Stmt *SubExpr;
10300b57cec5SDimitry Andric 
FullExpr(StmtClass SC,Expr * subexpr)10310b57cec5SDimitry Andric  FullExpr(StmtClass SC, Expr *subexpr)
10325ffd83dbSDimitry Andric      : Expr(SC, subexpr->getType(), subexpr->getValueKind(),
10335ffd83dbSDimitry Andric             subexpr->getObjectKind()),
10345ffd83dbSDimitry Andric        SubExpr(subexpr) {
10355ffd83dbSDimitry Andric    setDependence(computeDependence(this));
10365ffd83dbSDimitry Andric  }
FullExpr(StmtClass SC,EmptyShell Empty)10370b57cec5SDimitry Andric   FullExpr(StmtClass SC, EmptyShell Empty)
10380b57cec5SDimitry Andric     : Expr(SC, Empty) {}
10390b57cec5SDimitry Andric public:
getSubExpr()10400b57cec5SDimitry Andric   const Expr *getSubExpr() const { return cast<Expr>(SubExpr); }
getSubExpr()10410b57cec5SDimitry Andric   Expr *getSubExpr() { return cast<Expr>(SubExpr); }
10420b57cec5SDimitry Andric 
10430b57cec5SDimitry Andric   /// As with any mutator of the AST, be very careful when modifying an
10440b57cec5SDimitry Andric   /// existing AST to preserve its invariants.
setSubExpr(Expr * E)10450b57cec5SDimitry Andric   void setSubExpr(Expr *E) { SubExpr = E; }
10460b57cec5SDimitry Andric 
classof(const Stmt * T)10470b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
10480b57cec5SDimitry Andric     return T->getStmtClass() >= firstFullExprConstant &&
10490b57cec5SDimitry Andric            T->getStmtClass() <= lastFullExprConstant;
10500b57cec5SDimitry Andric   }
10510b57cec5SDimitry Andric };
10520b57cec5SDimitry Andric 
10535f757f3fSDimitry Andric /// Describes the kind of result that can be tail-allocated.
10545f757f3fSDimitry Andric enum class ConstantResultStorageKind { None, Int64, APValue };
10555f757f3fSDimitry Andric 
10560b57cec5SDimitry Andric /// ConstantExpr - An expression that occurs in a constant context and
10570b57cec5SDimitry Andric /// optionally the result of evaluating the expression.
10580b57cec5SDimitry Andric class ConstantExpr final
10590b57cec5SDimitry Andric     : public FullExpr,
10600b57cec5SDimitry Andric       private llvm::TrailingObjects<ConstantExpr, APValue, uint64_t> {
10610b57cec5SDimitry Andric   static_assert(std::is_same<uint64_t, llvm::APInt::WordType>::value,
10625ffd83dbSDimitry Andric                 "ConstantExpr assumes that llvm::APInt::WordType is uint64_t "
10635ffd83dbSDimitry Andric                 "for tail-allocated storage");
10645ffd83dbSDimitry Andric   friend TrailingObjects;
10655ffd83dbSDimitry Andric   friend class ASTStmtReader;
10665ffd83dbSDimitry Andric   friend class ASTStmtWriter;
10670b57cec5SDimitry Andric 
numTrailingObjects(OverloadToken<APValue>)10680b57cec5SDimitry Andric   size_t numTrailingObjects(OverloadToken<APValue>) const {
10695f757f3fSDimitry Andric     return getResultStorageKind() == ConstantResultStorageKind::APValue;
10700b57cec5SDimitry Andric   }
numTrailingObjects(OverloadToken<uint64_t>)10710b57cec5SDimitry Andric   size_t numTrailingObjects(OverloadToken<uint64_t>) const {
10725f757f3fSDimitry Andric     return getResultStorageKind() == ConstantResultStorageKind::Int64;
10730b57cec5SDimitry Andric   }
10740b57cec5SDimitry Andric 
Int64Result()10750b57cec5SDimitry Andric   uint64_t &Int64Result() {
10765f757f3fSDimitry Andric     assert(getResultStorageKind() == ConstantResultStorageKind::Int64 &&
10770b57cec5SDimitry Andric            "invalid accessor");
10780b57cec5SDimitry Andric     return *getTrailingObjects<uint64_t>();
10790b57cec5SDimitry Andric   }
Int64Result()10800b57cec5SDimitry Andric   const uint64_t &Int64Result() const {
10810b57cec5SDimitry Andric     return const_cast<ConstantExpr *>(this)->Int64Result();
10820b57cec5SDimitry Andric   }
APValueResult()10830b57cec5SDimitry Andric   APValue &APValueResult() {
10845f757f3fSDimitry Andric     assert(getResultStorageKind() == ConstantResultStorageKind::APValue &&
10850b57cec5SDimitry Andric            "invalid accessor");
10860b57cec5SDimitry Andric     return *getTrailingObjects<APValue>();
10870b57cec5SDimitry Andric   }
APValueResult()10885ffd83dbSDimitry Andric   APValue &APValueResult() const {
10890b57cec5SDimitry Andric     return const_cast<ConstantExpr *>(this)->APValueResult();
10900b57cec5SDimitry Andric   }
10910b57cec5SDimitry Andric 
10925f757f3fSDimitry Andric   ConstantExpr(Expr *SubExpr, ConstantResultStorageKind StorageKind,
10935ffd83dbSDimitry Andric                bool IsImmediateInvocation);
10945f757f3fSDimitry Andric   ConstantExpr(EmptyShell Empty, ConstantResultStorageKind StorageKind);
10950b57cec5SDimitry Andric 
10960b57cec5SDimitry Andric public:
10970b57cec5SDimitry Andric   static ConstantExpr *Create(const ASTContext &Context, Expr *E,
10980b57cec5SDimitry Andric                               const APValue &Result);
10995f757f3fSDimitry Andric   static ConstantExpr *
11005f757f3fSDimitry Andric   Create(const ASTContext &Context, Expr *E,
11015f757f3fSDimitry Andric          ConstantResultStorageKind Storage = ConstantResultStorageKind::None,
11025ffd83dbSDimitry Andric          bool IsImmediateInvocation = false);
11030b57cec5SDimitry Andric   static ConstantExpr *CreateEmpty(const ASTContext &Context,
11045f757f3fSDimitry Andric                                    ConstantResultStorageKind StorageKind);
11050b57cec5SDimitry Andric 
11065f757f3fSDimitry Andric   static ConstantResultStorageKind getStorageKind(const APValue &Value);
11075f757f3fSDimitry Andric   static ConstantResultStorageKind getStorageKind(const Type *T,
11080b57cec5SDimitry Andric                                                   const ASTContext &Context);
11090b57cec5SDimitry Andric 
getBeginLoc()11100b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY {
11110b57cec5SDimitry Andric     return SubExpr->getBeginLoc();
11120b57cec5SDimitry Andric   }
getEndLoc()11130b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY {
11140b57cec5SDimitry Andric     return SubExpr->getEndLoc();
11150b57cec5SDimitry Andric   }
11160b57cec5SDimitry Andric 
classof(const Stmt * T)11170b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
11180b57cec5SDimitry Andric     return T->getStmtClass() == ConstantExprClass;
11190b57cec5SDimitry Andric   }
11200b57cec5SDimitry Andric 
SetResult(APValue Value,const ASTContext & Context)11210b57cec5SDimitry Andric   void SetResult(APValue Value, const ASTContext &Context) {
11220b57cec5SDimitry Andric     MoveIntoResult(Value, Context);
11230b57cec5SDimitry Andric   }
11240b57cec5SDimitry Andric   void MoveIntoResult(APValue &Value, const ASTContext &Context);
11250b57cec5SDimitry Andric 
getResultAPValueKind()11260b57cec5SDimitry Andric   APValue::ValueKind getResultAPValueKind() const {
11270b57cec5SDimitry Andric     return static_cast<APValue::ValueKind>(ConstantExprBits.APValueKind);
11280b57cec5SDimitry Andric   }
getResultStorageKind()11295f757f3fSDimitry Andric   ConstantResultStorageKind getResultStorageKind() const {
11305f757f3fSDimitry Andric     return static_cast<ConstantResultStorageKind>(ConstantExprBits.ResultKind);
11310b57cec5SDimitry Andric   }
isImmediateInvocation()11325ffd83dbSDimitry Andric   bool isImmediateInvocation() const {
11335ffd83dbSDimitry Andric     return ConstantExprBits.IsImmediateInvocation;
11345ffd83dbSDimitry Andric   }
hasAPValueResult()11355ffd83dbSDimitry Andric   bool hasAPValueResult() const {
11365ffd83dbSDimitry Andric     return ConstantExprBits.APValueKind != APValue::None;
11375ffd83dbSDimitry Andric   }
11380b57cec5SDimitry Andric   APValue getAPValueResult() const;
11390b57cec5SDimitry Andric   llvm::APSInt getResultAsAPSInt() const;
11400b57cec5SDimitry Andric   // Iterators
children()11410b57cec5SDimitry Andric   child_range children() { return child_range(&SubExpr, &SubExpr+1); }
children()11420b57cec5SDimitry Andric   const_child_range children() const {
11430b57cec5SDimitry Andric     return const_child_range(&SubExpr, &SubExpr + 1);
11440b57cec5SDimitry Andric   }
11450b57cec5SDimitry Andric };
11460b57cec5SDimitry Andric 
11470b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
11480b57cec5SDimitry Andric // Primary Expressions.
11490b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
11500b57cec5SDimitry Andric 
11510b57cec5SDimitry Andric /// OpaqueValueExpr - An expression referring to an opaque object of a
11520b57cec5SDimitry Andric /// fixed type and value class.  These don't correspond to concrete
11530b57cec5SDimitry Andric /// syntax; instead they're used to express operations (usually copy
11540b57cec5SDimitry Andric /// operations) on values whose source is generally obvious from
11550b57cec5SDimitry Andric /// context.
11560b57cec5SDimitry Andric class OpaqueValueExpr : public Expr {
11570b57cec5SDimitry Andric   friend class ASTStmtReader;
11580b57cec5SDimitry Andric   Expr *SourceExpr;
11590b57cec5SDimitry Andric 
11600b57cec5SDimitry Andric public:
11610b57cec5SDimitry Andric   OpaqueValueExpr(SourceLocation Loc, QualType T, ExprValueKind VK,
11625ffd83dbSDimitry Andric                   ExprObjectKind OK = OK_Ordinary, Expr *SourceExpr = nullptr)
Expr(OpaqueValueExprClass,T,VK,OK)11635ffd83dbSDimitry Andric       : Expr(OpaqueValueExprClass, T, VK, OK), SourceExpr(SourceExpr) {
11640b57cec5SDimitry Andric     setIsUnique(false);
11650b57cec5SDimitry Andric     OpaqueValueExprBits.Loc = Loc;
11665ffd83dbSDimitry Andric     setDependence(computeDependence(this));
11670b57cec5SDimitry Andric   }
11680b57cec5SDimitry Andric 
11690b57cec5SDimitry Andric   /// Given an expression which invokes a copy constructor --- i.e.  a
11700b57cec5SDimitry Andric   /// CXXConstructExpr, possibly wrapped in an ExprWithCleanups ---
11710b57cec5SDimitry Andric   /// find the OpaqueValueExpr that's the source of the construction.
11720b57cec5SDimitry Andric   static const OpaqueValueExpr *findInCopyConstruct(const Expr *expr);
11730b57cec5SDimitry Andric 
OpaqueValueExpr(EmptyShell Empty)11740b57cec5SDimitry Andric   explicit OpaqueValueExpr(EmptyShell Empty)
11750b57cec5SDimitry Andric     : Expr(OpaqueValueExprClass, Empty) {}
11760b57cec5SDimitry Andric 
11770b57cec5SDimitry Andric   /// Retrieve the location of this expression.
getLocation()11780b57cec5SDimitry Andric   SourceLocation getLocation() const { return OpaqueValueExprBits.Loc; }
11790b57cec5SDimitry Andric 
getBeginLoc()11800b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY {
11810b57cec5SDimitry Andric     return SourceExpr ? SourceExpr->getBeginLoc() : getLocation();
11820b57cec5SDimitry Andric   }
getEndLoc()11830b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY {
11840b57cec5SDimitry Andric     return SourceExpr ? SourceExpr->getEndLoc() : getLocation();
11850b57cec5SDimitry Andric   }
getExprLoc()11860b57cec5SDimitry Andric   SourceLocation getExprLoc() const LLVM_READONLY {
11870b57cec5SDimitry Andric     return SourceExpr ? SourceExpr->getExprLoc() : getLocation();
11880b57cec5SDimitry Andric   }
11890b57cec5SDimitry Andric 
children()11900b57cec5SDimitry Andric   child_range children() {
11910b57cec5SDimitry Andric     return child_range(child_iterator(), child_iterator());
11920b57cec5SDimitry Andric   }
11930b57cec5SDimitry Andric 
children()11940b57cec5SDimitry Andric   const_child_range children() const {
11950b57cec5SDimitry Andric     return const_child_range(const_child_iterator(), const_child_iterator());
11960b57cec5SDimitry Andric   }
11970b57cec5SDimitry Andric 
11980b57cec5SDimitry Andric   /// The source expression of an opaque value expression is the
11990b57cec5SDimitry Andric   /// expression which originally generated the value.  This is
12000b57cec5SDimitry Andric   /// provided as a convenience for analyses that don't wish to
12010b57cec5SDimitry Andric   /// precisely model the execution behavior of the program.
12020b57cec5SDimitry Andric   ///
12030b57cec5SDimitry Andric   /// The source expression is typically set when building the
12040b57cec5SDimitry Andric   /// expression which binds the opaque value expression in the first
12050b57cec5SDimitry Andric   /// place.
getSourceExpr()12060b57cec5SDimitry Andric   Expr *getSourceExpr() const { return SourceExpr; }
12070b57cec5SDimitry Andric 
setIsUnique(bool V)12080b57cec5SDimitry Andric   void setIsUnique(bool V) {
12090b57cec5SDimitry Andric     assert((!V || SourceExpr) &&
12100b57cec5SDimitry Andric            "unique OVEs are expected to have source expressions");
12110b57cec5SDimitry Andric     OpaqueValueExprBits.IsUnique = V;
12120b57cec5SDimitry Andric   }
12130b57cec5SDimitry Andric 
isUnique()12140b57cec5SDimitry Andric   bool isUnique() const { return OpaqueValueExprBits.IsUnique; }
12150b57cec5SDimitry Andric 
classof(const Stmt * T)12160b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
12170b57cec5SDimitry Andric     return T->getStmtClass() == OpaqueValueExprClass;
12180b57cec5SDimitry Andric   }
12190b57cec5SDimitry Andric };
12200b57cec5SDimitry Andric 
12210b57cec5SDimitry Andric /// A reference to a declared variable, function, enum, etc.
12220b57cec5SDimitry Andric /// [C99 6.5.1p2]
12230b57cec5SDimitry Andric ///
12240b57cec5SDimitry Andric /// This encodes all the information about how a declaration is referenced
12250b57cec5SDimitry Andric /// within an expression.
12260b57cec5SDimitry Andric ///
12270b57cec5SDimitry Andric /// There are several optional constructs attached to DeclRefExprs only when
12280b57cec5SDimitry Andric /// they apply in order to conserve memory. These are laid out past the end of
12290b57cec5SDimitry Andric /// the object, and flags in the DeclRefExprBitfield track whether they exist:
12300b57cec5SDimitry Andric ///
12310b57cec5SDimitry Andric ///   DeclRefExprBits.HasQualifier:
12320b57cec5SDimitry Andric ///       Specifies when this declaration reference expression has a C++
12330b57cec5SDimitry Andric ///       nested-name-specifier.
12340b57cec5SDimitry Andric ///   DeclRefExprBits.HasFoundDecl:
12350b57cec5SDimitry Andric ///       Specifies when this declaration reference expression has a record of
12360b57cec5SDimitry Andric ///       a NamedDecl (different from the referenced ValueDecl) which was found
12370b57cec5SDimitry Andric ///       during name lookup and/or overload resolution.
12380b57cec5SDimitry Andric ///   DeclRefExprBits.HasTemplateKWAndArgsInfo:
12390b57cec5SDimitry Andric ///       Specifies when this declaration reference expression has an explicit
12400b57cec5SDimitry Andric ///       C++ template keyword and/or template argument list.
12410b57cec5SDimitry Andric ///   DeclRefExprBits.RefersToEnclosingVariableOrCapture
12420b57cec5SDimitry Andric ///       Specifies when this declaration reference expression (validly)
12430b57cec5SDimitry Andric ///       refers to an enclosed local or a captured variable.
12440b57cec5SDimitry Andric class DeclRefExpr final
12450b57cec5SDimitry Andric     : public Expr,
12460b57cec5SDimitry Andric       private llvm::TrailingObjects<DeclRefExpr, NestedNameSpecifierLoc,
12470b57cec5SDimitry Andric                                     NamedDecl *, ASTTemplateKWAndArgsInfo,
12480b57cec5SDimitry Andric                                     TemplateArgumentLoc> {
12490b57cec5SDimitry Andric   friend class ASTStmtReader;
12500b57cec5SDimitry Andric   friend class ASTStmtWriter;
12510b57cec5SDimitry Andric   friend TrailingObjects;
12520b57cec5SDimitry Andric 
12530b57cec5SDimitry Andric   /// The declaration that we are referencing.
12540b57cec5SDimitry Andric   ValueDecl *D;
12550b57cec5SDimitry Andric 
12560b57cec5SDimitry Andric   /// Provides source/type location info for the declaration name
12570b57cec5SDimitry Andric   /// embedded in D.
12580b57cec5SDimitry Andric   DeclarationNameLoc DNLoc;
12590b57cec5SDimitry Andric 
numTrailingObjects(OverloadToken<NestedNameSpecifierLoc>)12600b57cec5SDimitry Andric   size_t numTrailingObjects(OverloadToken<NestedNameSpecifierLoc>) const {
12610b57cec5SDimitry Andric     return hasQualifier();
12620b57cec5SDimitry Andric   }
12630b57cec5SDimitry Andric 
numTrailingObjects(OverloadToken<NamedDecl * >)12640b57cec5SDimitry Andric   size_t numTrailingObjects(OverloadToken<NamedDecl *>) const {
12650b57cec5SDimitry Andric     return hasFoundDecl();
12660b57cec5SDimitry Andric   }
12670b57cec5SDimitry Andric 
numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>)12680b57cec5SDimitry Andric   size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
12690b57cec5SDimitry Andric     return hasTemplateKWAndArgsInfo();
12700b57cec5SDimitry Andric   }
12710b57cec5SDimitry Andric 
12720b57cec5SDimitry Andric   /// Test whether there is a distinct FoundDecl attached to the end of
12730b57cec5SDimitry Andric   /// this DRE.
hasFoundDecl()12740b57cec5SDimitry Andric   bool hasFoundDecl() const { return DeclRefExprBits.HasFoundDecl; }
12750b57cec5SDimitry Andric 
12760b57cec5SDimitry Andric   DeclRefExpr(const ASTContext &Ctx, NestedNameSpecifierLoc QualifierLoc,
12770b57cec5SDimitry Andric               SourceLocation TemplateKWLoc, ValueDecl *D,
12780b57cec5SDimitry Andric               bool RefersToEnlosingVariableOrCapture,
12790b57cec5SDimitry Andric               const DeclarationNameInfo &NameInfo, NamedDecl *FoundD,
12800b57cec5SDimitry Andric               const TemplateArgumentListInfo *TemplateArgs, QualType T,
12810b57cec5SDimitry Andric               ExprValueKind VK, NonOdrUseReason NOUR);
12820b57cec5SDimitry Andric 
12830b57cec5SDimitry Andric   /// Construct an empty declaration reference expression.
DeclRefExpr(EmptyShell Empty)12840b57cec5SDimitry Andric   explicit DeclRefExpr(EmptyShell Empty) : Expr(DeclRefExprClass, Empty) {}
12850b57cec5SDimitry Andric 
12860b57cec5SDimitry Andric public:
12870b57cec5SDimitry Andric   DeclRefExpr(const ASTContext &Ctx, ValueDecl *D,
12880b57cec5SDimitry Andric               bool RefersToEnclosingVariableOrCapture, QualType T,
12890b57cec5SDimitry Andric               ExprValueKind VK, SourceLocation L,
12900b57cec5SDimitry Andric               const DeclarationNameLoc &LocInfo = DeclarationNameLoc(),
12910b57cec5SDimitry Andric               NonOdrUseReason NOUR = NOUR_None);
12920b57cec5SDimitry Andric 
12930b57cec5SDimitry Andric   static DeclRefExpr *
12940b57cec5SDimitry Andric   Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc,
12950b57cec5SDimitry Andric          SourceLocation TemplateKWLoc, ValueDecl *D,
12960b57cec5SDimitry Andric          bool RefersToEnclosingVariableOrCapture, SourceLocation NameLoc,
12970b57cec5SDimitry Andric          QualType T, ExprValueKind VK, NamedDecl *FoundD = nullptr,
12980b57cec5SDimitry Andric          const TemplateArgumentListInfo *TemplateArgs = nullptr,
12990b57cec5SDimitry Andric          NonOdrUseReason NOUR = NOUR_None);
13000b57cec5SDimitry Andric 
13010b57cec5SDimitry Andric   static DeclRefExpr *
13020b57cec5SDimitry Andric   Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc,
13030b57cec5SDimitry Andric          SourceLocation TemplateKWLoc, ValueDecl *D,
13040b57cec5SDimitry Andric          bool RefersToEnclosingVariableOrCapture,
13050b57cec5SDimitry Andric          const DeclarationNameInfo &NameInfo, QualType T, ExprValueKind VK,
13060b57cec5SDimitry Andric          NamedDecl *FoundD = nullptr,
13070b57cec5SDimitry Andric          const TemplateArgumentListInfo *TemplateArgs = nullptr,
13080b57cec5SDimitry Andric          NonOdrUseReason NOUR = NOUR_None);
13090b57cec5SDimitry Andric 
13100b57cec5SDimitry Andric   /// Construct an empty declaration reference expression.
13110b57cec5SDimitry Andric   static DeclRefExpr *CreateEmpty(const ASTContext &Context, bool HasQualifier,
13120b57cec5SDimitry Andric                                   bool HasFoundDecl,
13130b57cec5SDimitry Andric                                   bool HasTemplateKWAndArgsInfo,
13140b57cec5SDimitry Andric                                   unsigned NumTemplateArgs);
13150b57cec5SDimitry Andric 
getDecl()13160b57cec5SDimitry Andric   ValueDecl *getDecl() { return D; }
getDecl()13170b57cec5SDimitry Andric   const ValueDecl *getDecl() const { return D; }
1318e8d8bef9SDimitry Andric   void setDecl(ValueDecl *NewD);
13190b57cec5SDimitry Andric 
getNameInfo()13200b57cec5SDimitry Andric   DeclarationNameInfo getNameInfo() const {
13210b57cec5SDimitry Andric     return DeclarationNameInfo(getDecl()->getDeclName(), getLocation(), DNLoc);
13220b57cec5SDimitry Andric   }
13230b57cec5SDimitry Andric 
getLocation()13240b57cec5SDimitry Andric   SourceLocation getLocation() const { return DeclRefExprBits.Loc; }
setLocation(SourceLocation L)13250b57cec5SDimitry Andric   void setLocation(SourceLocation L) { DeclRefExprBits.Loc = L; }
13260b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY;
13270b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY;
13280b57cec5SDimitry Andric 
13290b57cec5SDimitry Andric   /// Determine whether this declaration reference was preceded by a
13300b57cec5SDimitry Andric   /// C++ nested-name-specifier, e.g., \c N::foo.
hasQualifier()13310b57cec5SDimitry Andric   bool hasQualifier() const { return DeclRefExprBits.HasQualifier; }
13320b57cec5SDimitry Andric 
13330b57cec5SDimitry Andric   /// If the name was qualified, retrieves the nested-name-specifier
13340b57cec5SDimitry Andric   /// that precedes the name, with source-location information.
getQualifierLoc()13350b57cec5SDimitry Andric   NestedNameSpecifierLoc getQualifierLoc() const {
13360b57cec5SDimitry Andric     if (!hasQualifier())
13370b57cec5SDimitry Andric       return NestedNameSpecifierLoc();
13380b57cec5SDimitry Andric     return *getTrailingObjects<NestedNameSpecifierLoc>();
13390b57cec5SDimitry Andric   }
13400b57cec5SDimitry Andric 
13410b57cec5SDimitry Andric   /// If the name was qualified, retrieves the nested-name-specifier
13420b57cec5SDimitry Andric   /// that precedes the name. Otherwise, returns NULL.
getQualifier()13430b57cec5SDimitry Andric   NestedNameSpecifier *getQualifier() const {
13440b57cec5SDimitry Andric     return getQualifierLoc().getNestedNameSpecifier();
13450b57cec5SDimitry Andric   }
13460b57cec5SDimitry Andric 
13470b57cec5SDimitry Andric   /// Get the NamedDecl through which this reference occurred.
13480b57cec5SDimitry Andric   ///
13490b57cec5SDimitry Andric   /// This Decl may be different from the ValueDecl actually referred to in the
13500b57cec5SDimitry Andric   /// presence of using declarations, etc. It always returns non-NULL, and may
13510b57cec5SDimitry Andric   /// simple return the ValueDecl when appropriate.
13520b57cec5SDimitry Andric 
getFoundDecl()13530b57cec5SDimitry Andric   NamedDecl *getFoundDecl() {
13540b57cec5SDimitry Andric     return hasFoundDecl() ? *getTrailingObjects<NamedDecl *>() : D;
13550b57cec5SDimitry Andric   }
13560b57cec5SDimitry Andric 
13570b57cec5SDimitry Andric   /// Get the NamedDecl through which this reference occurred.
13580b57cec5SDimitry Andric   /// See non-const variant.
getFoundDecl()13590b57cec5SDimitry Andric   const NamedDecl *getFoundDecl() const {
13600b57cec5SDimitry Andric     return hasFoundDecl() ? *getTrailingObjects<NamedDecl *>() : D;
13610b57cec5SDimitry Andric   }
13620b57cec5SDimitry Andric 
hasTemplateKWAndArgsInfo()13630b57cec5SDimitry Andric   bool hasTemplateKWAndArgsInfo() const {
13640b57cec5SDimitry Andric     return DeclRefExprBits.HasTemplateKWAndArgsInfo;
13650b57cec5SDimitry Andric   }
13660b57cec5SDimitry Andric 
13670b57cec5SDimitry Andric   /// Retrieve the location of the template keyword preceding
13680b57cec5SDimitry Andric   /// this name, if any.
getTemplateKeywordLoc()13690b57cec5SDimitry Andric   SourceLocation getTemplateKeywordLoc() const {
13700b57cec5SDimitry Andric     if (!hasTemplateKWAndArgsInfo())
13710b57cec5SDimitry Andric       return SourceLocation();
13720b57cec5SDimitry Andric     return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->TemplateKWLoc;
13730b57cec5SDimitry Andric   }
13740b57cec5SDimitry Andric 
13750b57cec5SDimitry Andric   /// Retrieve the location of the left angle bracket starting the
13760b57cec5SDimitry Andric   /// explicit template argument list following the name, if any.
getLAngleLoc()13770b57cec5SDimitry Andric   SourceLocation getLAngleLoc() const {
13780b57cec5SDimitry Andric     if (!hasTemplateKWAndArgsInfo())
13790b57cec5SDimitry Andric       return SourceLocation();
13800b57cec5SDimitry Andric     return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->LAngleLoc;
13810b57cec5SDimitry Andric   }
13820b57cec5SDimitry Andric 
13830b57cec5SDimitry Andric   /// Retrieve the location of the right angle bracket ending the
13840b57cec5SDimitry Andric   /// explicit template argument list following the name, if any.
getRAngleLoc()13850b57cec5SDimitry Andric   SourceLocation getRAngleLoc() const {
13860b57cec5SDimitry Andric     if (!hasTemplateKWAndArgsInfo())
13870b57cec5SDimitry Andric       return SourceLocation();
13880b57cec5SDimitry Andric     return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->RAngleLoc;
13890b57cec5SDimitry Andric   }
13900b57cec5SDimitry Andric 
13910b57cec5SDimitry Andric   /// Determines whether the name in this declaration reference
13920b57cec5SDimitry Andric   /// was preceded by the template keyword.
hasTemplateKeyword()13930b57cec5SDimitry Andric   bool hasTemplateKeyword() const { return getTemplateKeywordLoc().isValid(); }
13940b57cec5SDimitry Andric 
13950b57cec5SDimitry Andric   /// Determines whether this declaration reference was followed by an
13960b57cec5SDimitry Andric   /// explicit template argument list.
hasExplicitTemplateArgs()13970b57cec5SDimitry Andric   bool hasExplicitTemplateArgs() const { return getLAngleLoc().isValid(); }
13980b57cec5SDimitry Andric 
13990b57cec5SDimitry Andric   /// Copies the template arguments (if present) into the given
14000b57cec5SDimitry Andric   /// structure.
copyTemplateArgumentsInto(TemplateArgumentListInfo & List)14010b57cec5SDimitry Andric   void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
14020b57cec5SDimitry Andric     if (hasExplicitTemplateArgs())
14030b57cec5SDimitry Andric       getTrailingObjects<ASTTemplateKWAndArgsInfo>()->copyInto(
14040b57cec5SDimitry Andric           getTrailingObjects<TemplateArgumentLoc>(), List);
14050b57cec5SDimitry Andric   }
14060b57cec5SDimitry Andric 
14070b57cec5SDimitry Andric   /// Retrieve the template arguments provided as part of this
14080b57cec5SDimitry Andric   /// template-id.
getTemplateArgs()14090b57cec5SDimitry Andric   const TemplateArgumentLoc *getTemplateArgs() const {
14100b57cec5SDimitry Andric     if (!hasExplicitTemplateArgs())
14110b57cec5SDimitry Andric       return nullptr;
14120b57cec5SDimitry Andric     return getTrailingObjects<TemplateArgumentLoc>();
14130b57cec5SDimitry Andric   }
14140b57cec5SDimitry Andric 
14150b57cec5SDimitry Andric   /// Retrieve the number of template arguments provided as part of this
14160b57cec5SDimitry Andric   /// template-id.
getNumTemplateArgs()14170b57cec5SDimitry Andric   unsigned getNumTemplateArgs() const {
14180b57cec5SDimitry Andric     if (!hasExplicitTemplateArgs())
14190b57cec5SDimitry Andric       return 0;
14200b57cec5SDimitry Andric     return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->NumTemplateArgs;
14210b57cec5SDimitry Andric   }
14220b57cec5SDimitry Andric 
template_arguments()14230b57cec5SDimitry Andric   ArrayRef<TemplateArgumentLoc> template_arguments() const {
14240b57cec5SDimitry Andric     return {getTemplateArgs(), getNumTemplateArgs()};
14250b57cec5SDimitry Andric   }
14260b57cec5SDimitry Andric 
14270b57cec5SDimitry Andric   /// Returns true if this expression refers to a function that
14280b57cec5SDimitry Andric   /// was resolved from an overloaded set having size greater than 1.
hadMultipleCandidates()14290b57cec5SDimitry Andric   bool hadMultipleCandidates() const {
14300b57cec5SDimitry Andric     return DeclRefExprBits.HadMultipleCandidates;
14310b57cec5SDimitry Andric   }
14320b57cec5SDimitry Andric   /// Sets the flag telling whether this expression refers to
14330b57cec5SDimitry Andric   /// a function that was resolved from an overloaded set having size
14340b57cec5SDimitry Andric   /// greater than 1.
14350b57cec5SDimitry Andric   void setHadMultipleCandidates(bool V = true) {
14360b57cec5SDimitry Andric     DeclRefExprBits.HadMultipleCandidates = V;
14370b57cec5SDimitry Andric   }
14380b57cec5SDimitry Andric 
14390b57cec5SDimitry Andric   /// Is this expression a non-odr-use reference, and if so, why?
isNonOdrUse()14400b57cec5SDimitry Andric   NonOdrUseReason isNonOdrUse() const {
14410b57cec5SDimitry Andric     return static_cast<NonOdrUseReason>(DeclRefExprBits.NonOdrUseReason);
14420b57cec5SDimitry Andric   }
14430b57cec5SDimitry Andric 
14440b57cec5SDimitry Andric   /// Does this DeclRefExpr refer to an enclosing local or a captured
14450b57cec5SDimitry Andric   /// variable?
refersToEnclosingVariableOrCapture()14460b57cec5SDimitry Andric   bool refersToEnclosingVariableOrCapture() const {
14470b57cec5SDimitry Andric     return DeclRefExprBits.RefersToEnclosingVariableOrCapture;
14480b57cec5SDimitry Andric   }
14490b57cec5SDimitry Andric 
isImmediateEscalating()145006c3fb27SDimitry Andric   bool isImmediateEscalating() const {
145106c3fb27SDimitry Andric     return DeclRefExprBits.IsImmediateEscalating;
145206c3fb27SDimitry Andric   }
145306c3fb27SDimitry Andric 
setIsImmediateEscalating(bool Set)145406c3fb27SDimitry Andric   void setIsImmediateEscalating(bool Set) {
145506c3fb27SDimitry Andric     DeclRefExprBits.IsImmediateEscalating = Set;
145606c3fb27SDimitry Andric   }
145706c3fb27SDimitry Andric 
isCapturedByCopyInLambdaWithExplicitObjectParameter()14585f757f3fSDimitry Andric   bool isCapturedByCopyInLambdaWithExplicitObjectParameter() const {
14595f757f3fSDimitry Andric     return DeclRefExprBits.CapturedByCopyInLambdaWithExplicitObjectParameter;
14605f757f3fSDimitry Andric   }
14615f757f3fSDimitry Andric 
setCapturedByCopyInLambdaWithExplicitObjectParameter(bool Set,const ASTContext & Context)14625f757f3fSDimitry Andric   void setCapturedByCopyInLambdaWithExplicitObjectParameter(
14635f757f3fSDimitry Andric       bool Set, const ASTContext &Context) {
14645f757f3fSDimitry Andric     DeclRefExprBits.CapturedByCopyInLambdaWithExplicitObjectParameter = Set;
14655f757f3fSDimitry Andric     setDependence(computeDependence(this, Context));
14665f757f3fSDimitry Andric   }
14675f757f3fSDimitry Andric 
classof(const Stmt * T)14680b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
14690b57cec5SDimitry Andric     return T->getStmtClass() == DeclRefExprClass;
14700b57cec5SDimitry Andric   }
14710b57cec5SDimitry Andric 
14720b57cec5SDimitry Andric   // Iterators
children()14730b57cec5SDimitry Andric   child_range children() {
14740b57cec5SDimitry Andric     return child_range(child_iterator(), child_iterator());
14750b57cec5SDimitry Andric   }
14760b57cec5SDimitry Andric 
children()14770b57cec5SDimitry Andric   const_child_range children() const {
14780b57cec5SDimitry Andric     return const_child_range(const_child_iterator(), const_child_iterator());
14790b57cec5SDimitry Andric   }
14800b57cec5SDimitry Andric };
14810b57cec5SDimitry Andric 
14820b57cec5SDimitry Andric class IntegerLiteral : public Expr, public APIntStorage {
14830b57cec5SDimitry Andric   SourceLocation Loc;
14840b57cec5SDimitry Andric 
14850b57cec5SDimitry Andric   /// Construct an empty integer literal.
IntegerLiteral(EmptyShell Empty)14860b57cec5SDimitry Andric   explicit IntegerLiteral(EmptyShell Empty)
14870b57cec5SDimitry Andric     : Expr(IntegerLiteralClass, Empty) { }
14880b57cec5SDimitry Andric 
14890b57cec5SDimitry Andric public:
14900b57cec5SDimitry Andric   // type should be IntTy, LongTy, LongLongTy, UnsignedIntTy, UnsignedLongTy,
14910b57cec5SDimitry Andric   // or UnsignedLongLongTy
14920b57cec5SDimitry Andric   IntegerLiteral(const ASTContext &C, const llvm::APInt &V, QualType type,
14930b57cec5SDimitry Andric                  SourceLocation l);
14940b57cec5SDimitry Andric 
14950b57cec5SDimitry Andric   /// Returns a new integer literal with value 'V' and type 'type'.
14960b57cec5SDimitry Andric   /// \param type - either IntTy, LongTy, LongLongTy, UnsignedIntTy,
14970b57cec5SDimitry Andric   /// UnsignedLongTy, or UnsignedLongLongTy which should match the size of V
14980b57cec5SDimitry Andric   /// \param V - the value that the returned integer literal contains.
14990b57cec5SDimitry Andric   static IntegerLiteral *Create(const ASTContext &C, const llvm::APInt &V,
15000b57cec5SDimitry Andric                                 QualType type, SourceLocation l);
15010b57cec5SDimitry Andric   /// Returns a new empty integer literal.
15020b57cec5SDimitry Andric   static IntegerLiteral *Create(const ASTContext &C, EmptyShell Empty);
15030b57cec5SDimitry Andric 
getBeginLoc()15040b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; }
getEndLoc()15050b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY { return Loc; }
15060b57cec5SDimitry Andric 
15070b57cec5SDimitry Andric   /// Retrieve the location of the literal.
getLocation()15080b57cec5SDimitry Andric   SourceLocation getLocation() const { return Loc; }
15090b57cec5SDimitry Andric 
setLocation(SourceLocation Location)15100b57cec5SDimitry Andric   void setLocation(SourceLocation Location) { Loc = Location; }
15110b57cec5SDimitry Andric 
classof(const Stmt * T)15120b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
15130b57cec5SDimitry Andric     return T->getStmtClass() == IntegerLiteralClass;
15140b57cec5SDimitry Andric   }
15150b57cec5SDimitry Andric 
15160b57cec5SDimitry Andric   // Iterators
children()15170b57cec5SDimitry Andric   child_range children() {
15180b57cec5SDimitry Andric     return child_range(child_iterator(), child_iterator());
15190b57cec5SDimitry Andric   }
children()15200b57cec5SDimitry Andric   const_child_range children() const {
15210b57cec5SDimitry Andric     return const_child_range(const_child_iterator(), const_child_iterator());
15220b57cec5SDimitry Andric   }
15230b57cec5SDimitry Andric };
15240b57cec5SDimitry Andric 
15250b57cec5SDimitry Andric class FixedPointLiteral : public Expr, public APIntStorage {
15260b57cec5SDimitry Andric   SourceLocation Loc;
15270b57cec5SDimitry Andric   unsigned Scale;
15280b57cec5SDimitry Andric 
15295ffd83dbSDimitry Andric   /// \brief Construct an empty fixed-point literal.
FixedPointLiteral(EmptyShell Empty)15300b57cec5SDimitry Andric   explicit FixedPointLiteral(EmptyShell Empty)
15310b57cec5SDimitry Andric       : Expr(FixedPointLiteralClass, Empty) {}
15320b57cec5SDimitry Andric 
15330b57cec5SDimitry Andric  public:
15340b57cec5SDimitry Andric   FixedPointLiteral(const ASTContext &C, const llvm::APInt &V, QualType type,
15350b57cec5SDimitry Andric                     SourceLocation l, unsigned Scale);
15360b57cec5SDimitry Andric 
15370b57cec5SDimitry Andric   // Store the int as is without any bit shifting.
15380b57cec5SDimitry Andric   static FixedPointLiteral *CreateFromRawInt(const ASTContext &C,
15390b57cec5SDimitry Andric                                              const llvm::APInt &V,
15400b57cec5SDimitry Andric                                              QualType type, SourceLocation l,
15410b57cec5SDimitry Andric                                              unsigned Scale);
15420b57cec5SDimitry Andric 
15435ffd83dbSDimitry Andric   /// Returns an empty fixed-point literal.
15445ffd83dbSDimitry Andric   static FixedPointLiteral *Create(const ASTContext &C, EmptyShell Empty);
15455ffd83dbSDimitry Andric 
getBeginLoc()15460b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; }
getEndLoc()15470b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY { return Loc; }
15480b57cec5SDimitry Andric 
15490b57cec5SDimitry Andric   /// \brief Retrieve the location of the literal.
getLocation()15500b57cec5SDimitry Andric   SourceLocation getLocation() const { return Loc; }
15510b57cec5SDimitry Andric 
setLocation(SourceLocation Location)15520b57cec5SDimitry Andric   void setLocation(SourceLocation Location) { Loc = Location; }
15530b57cec5SDimitry Andric 
getScale()15545ffd83dbSDimitry Andric   unsigned getScale() const { return Scale; }
setScale(unsigned S)15555ffd83dbSDimitry Andric   void setScale(unsigned S) { Scale = S; }
15565ffd83dbSDimitry Andric 
classof(const Stmt * T)15570b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
15580b57cec5SDimitry Andric     return T->getStmtClass() == FixedPointLiteralClass;
15590b57cec5SDimitry Andric   }
15600b57cec5SDimitry Andric 
15610b57cec5SDimitry Andric   std::string getValueAsString(unsigned Radix) const;
15620b57cec5SDimitry Andric 
15630b57cec5SDimitry Andric   // Iterators
children()15640b57cec5SDimitry Andric   child_range children() {
15650b57cec5SDimitry Andric     return child_range(child_iterator(), child_iterator());
15660b57cec5SDimitry Andric   }
children()15670b57cec5SDimitry Andric   const_child_range children() const {
15680b57cec5SDimitry Andric     return const_child_range(const_child_iterator(), const_child_iterator());
15690b57cec5SDimitry Andric   }
15700b57cec5SDimitry Andric };
15710b57cec5SDimitry Andric 
15725f757f3fSDimitry Andric enum class CharacterLiteralKind { Ascii, Wide, UTF8, UTF16, UTF32 };
15730b57cec5SDimitry Andric 
15745f757f3fSDimitry Andric class CharacterLiteral : public Expr {
15750b57cec5SDimitry Andric   unsigned Value;
15760b57cec5SDimitry Andric   SourceLocation Loc;
15770b57cec5SDimitry Andric public:
15780b57cec5SDimitry Andric   // type should be IntTy
CharacterLiteral(unsigned value,CharacterLiteralKind kind,QualType type,SourceLocation l)15795f757f3fSDimitry Andric   CharacterLiteral(unsigned value, CharacterLiteralKind kind, QualType type,
15800b57cec5SDimitry Andric                    SourceLocation l)
1581fe6060f1SDimitry Andric       : Expr(CharacterLiteralClass, type, VK_PRValue, OK_Ordinary),
1582fe6060f1SDimitry Andric         Value(value), Loc(l) {
15835f757f3fSDimitry Andric     CharacterLiteralBits.Kind = llvm::to_underlying(kind);
15845ffd83dbSDimitry Andric     setDependence(ExprDependence::None);
15850b57cec5SDimitry Andric   }
15860b57cec5SDimitry Andric 
15870b57cec5SDimitry Andric   /// Construct an empty character literal.
CharacterLiteral(EmptyShell Empty)15880b57cec5SDimitry Andric   CharacterLiteral(EmptyShell Empty) : Expr(CharacterLiteralClass, Empty) { }
15890b57cec5SDimitry Andric 
getLocation()15900b57cec5SDimitry Andric   SourceLocation getLocation() const { return Loc; }
getKind()15915f757f3fSDimitry Andric   CharacterLiteralKind getKind() const {
15925f757f3fSDimitry Andric     return static_cast<CharacterLiteralKind>(CharacterLiteralBits.Kind);
15930b57cec5SDimitry Andric   }
15940b57cec5SDimitry Andric 
getBeginLoc()15950b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; }
getEndLoc()15960b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY { return Loc; }
15970b57cec5SDimitry Andric 
getValue()15980b57cec5SDimitry Andric   unsigned getValue() const { return Value; }
15990b57cec5SDimitry Andric 
setLocation(SourceLocation Location)16000b57cec5SDimitry Andric   void setLocation(SourceLocation Location) { Loc = Location; }
setKind(CharacterLiteralKind kind)16015f757f3fSDimitry Andric   void setKind(CharacterLiteralKind kind) {
16025f757f3fSDimitry Andric     CharacterLiteralBits.Kind = llvm::to_underlying(kind);
16035f757f3fSDimitry Andric   }
setValue(unsigned Val)16040b57cec5SDimitry Andric   void setValue(unsigned Val) { Value = Val; }
16050b57cec5SDimitry Andric 
classof(const Stmt * T)16060b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
16070b57cec5SDimitry Andric     return T->getStmtClass() == CharacterLiteralClass;
16080b57cec5SDimitry Andric   }
16090b57cec5SDimitry Andric 
16105f757f3fSDimitry Andric   static void print(unsigned val, CharacterLiteralKind Kind, raw_ostream &OS);
1611fe6060f1SDimitry Andric 
16120b57cec5SDimitry Andric   // Iterators
children()16130b57cec5SDimitry Andric   child_range children() {
16140b57cec5SDimitry Andric     return child_range(child_iterator(), child_iterator());
16150b57cec5SDimitry Andric   }
children()16160b57cec5SDimitry Andric   const_child_range children() const {
16170b57cec5SDimitry Andric     return const_child_range(const_child_iterator(), const_child_iterator());
16180b57cec5SDimitry Andric   }
16190b57cec5SDimitry Andric };
16200b57cec5SDimitry Andric 
16210b57cec5SDimitry Andric class FloatingLiteral : public Expr, private APFloatStorage {
16220b57cec5SDimitry Andric   SourceLocation Loc;
16230b57cec5SDimitry Andric 
16240b57cec5SDimitry Andric   FloatingLiteral(const ASTContext &C, const llvm::APFloat &V, bool isexact,
16250b57cec5SDimitry Andric                   QualType Type, SourceLocation L);
16260b57cec5SDimitry Andric 
16270b57cec5SDimitry Andric   /// Construct an empty floating-point literal.
16280b57cec5SDimitry Andric   explicit FloatingLiteral(const ASTContext &C, EmptyShell Empty);
16290b57cec5SDimitry Andric 
16300b57cec5SDimitry Andric public:
16310b57cec5SDimitry Andric   static FloatingLiteral *Create(const ASTContext &C, const llvm::APFloat &V,
16320b57cec5SDimitry Andric                                  bool isexact, QualType Type, SourceLocation L);
16330b57cec5SDimitry Andric   static FloatingLiteral *Create(const ASTContext &C, EmptyShell Empty);
16340b57cec5SDimitry Andric 
getValue()16350b57cec5SDimitry Andric   llvm::APFloat getValue() const {
16360b57cec5SDimitry Andric     return APFloatStorage::getValue(getSemantics());
16370b57cec5SDimitry Andric   }
setValue(const ASTContext & C,const llvm::APFloat & Val)16380b57cec5SDimitry Andric   void setValue(const ASTContext &C, const llvm::APFloat &Val) {
16390b57cec5SDimitry Andric     assert(&getSemantics() == &Val.getSemantics() && "Inconsistent semantics");
16400b57cec5SDimitry Andric     APFloatStorage::setValue(C, Val);
16410b57cec5SDimitry Andric   }
16420b57cec5SDimitry Andric 
16430b57cec5SDimitry Andric   /// Get a raw enumeration value representing the floating-point semantics of
16440b57cec5SDimitry Andric   /// this literal (32-bit IEEE, x87, ...), suitable for serialisation.
getRawSemantics()16450b57cec5SDimitry Andric   llvm::APFloatBase::Semantics getRawSemantics() const {
16460b57cec5SDimitry Andric     return static_cast<llvm::APFloatBase::Semantics>(
16470b57cec5SDimitry Andric         FloatingLiteralBits.Semantics);
16480b57cec5SDimitry Andric   }
16490b57cec5SDimitry Andric 
16500b57cec5SDimitry Andric   /// Set the raw enumeration value representing the floating-point semantics of
16510b57cec5SDimitry Andric   /// this literal (32-bit IEEE, x87, ...), suitable for serialisation.
setRawSemantics(llvm::APFloatBase::Semantics Sem)16520b57cec5SDimitry Andric   void setRawSemantics(llvm::APFloatBase::Semantics Sem) {
16530b57cec5SDimitry Andric     FloatingLiteralBits.Semantics = Sem;
16540b57cec5SDimitry Andric   }
16550b57cec5SDimitry Andric 
16560b57cec5SDimitry Andric   /// Return the APFloat semantics this literal uses.
getSemantics()16570b57cec5SDimitry Andric   const llvm::fltSemantics &getSemantics() const {
16580b57cec5SDimitry Andric     return llvm::APFloatBase::EnumToSemantics(
16590b57cec5SDimitry Andric         static_cast<llvm::APFloatBase::Semantics>(
16600b57cec5SDimitry Andric             FloatingLiteralBits.Semantics));
16610b57cec5SDimitry Andric   }
16620b57cec5SDimitry Andric 
16630b57cec5SDimitry Andric   /// Set the APFloat semantics this literal uses.
setSemantics(const llvm::fltSemantics & Sem)16640b57cec5SDimitry Andric   void setSemantics(const llvm::fltSemantics &Sem) {
16650b57cec5SDimitry Andric     FloatingLiteralBits.Semantics = llvm::APFloatBase::SemanticsToEnum(Sem);
16660b57cec5SDimitry Andric   }
16670b57cec5SDimitry Andric 
isExact()16680b57cec5SDimitry Andric   bool isExact() const { return FloatingLiteralBits.IsExact; }
setExact(bool E)16690b57cec5SDimitry Andric   void setExact(bool E) { FloatingLiteralBits.IsExact = E; }
16700b57cec5SDimitry Andric 
16710b57cec5SDimitry Andric   /// getValueAsApproximateDouble - This returns the value as an inaccurate
16720b57cec5SDimitry Andric   /// double.  Note that this may cause loss of precision, but is useful for
16730b57cec5SDimitry Andric   /// debugging dumps, etc.
16740b57cec5SDimitry Andric   double getValueAsApproximateDouble() const;
16750b57cec5SDimitry Andric 
getLocation()16760b57cec5SDimitry Andric   SourceLocation getLocation() const { return Loc; }
setLocation(SourceLocation L)16770b57cec5SDimitry Andric   void setLocation(SourceLocation L) { Loc = L; }
16780b57cec5SDimitry Andric 
getBeginLoc()16790b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; }
getEndLoc()16800b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY { return Loc; }
16810b57cec5SDimitry Andric 
classof(const Stmt * T)16820b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
16830b57cec5SDimitry Andric     return T->getStmtClass() == FloatingLiteralClass;
16840b57cec5SDimitry Andric   }
16850b57cec5SDimitry Andric 
16860b57cec5SDimitry Andric   // Iterators
children()16870b57cec5SDimitry Andric   child_range children() {
16880b57cec5SDimitry Andric     return child_range(child_iterator(), child_iterator());
16890b57cec5SDimitry Andric   }
children()16900b57cec5SDimitry Andric   const_child_range children() const {
16910b57cec5SDimitry Andric     return const_child_range(const_child_iterator(), const_child_iterator());
16920b57cec5SDimitry Andric   }
16930b57cec5SDimitry Andric };
16940b57cec5SDimitry Andric 
16950b57cec5SDimitry Andric /// ImaginaryLiteral - We support imaginary integer and floating point literals,
16960b57cec5SDimitry Andric /// like "1.0i".  We represent these as a wrapper around FloatingLiteral and
16970b57cec5SDimitry Andric /// IntegerLiteral classes.  Instances of this class always have a Complex type
16980b57cec5SDimitry Andric /// whose element type matches the subexpression.
16990b57cec5SDimitry Andric ///
17000b57cec5SDimitry Andric class ImaginaryLiteral : public Expr {
17010b57cec5SDimitry Andric   Stmt *Val;
17020b57cec5SDimitry Andric public:
ImaginaryLiteral(Expr * val,QualType Ty)17030b57cec5SDimitry Andric   ImaginaryLiteral(Expr *val, QualType Ty)
1704fe6060f1SDimitry Andric       : Expr(ImaginaryLiteralClass, Ty, VK_PRValue, OK_Ordinary), Val(val) {
17055ffd83dbSDimitry Andric     setDependence(ExprDependence::None);
17065ffd83dbSDimitry Andric   }
17070b57cec5SDimitry Andric 
17080b57cec5SDimitry Andric   /// Build an empty imaginary literal.
ImaginaryLiteral(EmptyShell Empty)17090b57cec5SDimitry Andric   explicit ImaginaryLiteral(EmptyShell Empty)
17100b57cec5SDimitry Andric     : Expr(ImaginaryLiteralClass, Empty) { }
17110b57cec5SDimitry Andric 
getSubExpr()17120b57cec5SDimitry Andric   const Expr *getSubExpr() const { return cast<Expr>(Val); }
getSubExpr()17130b57cec5SDimitry Andric   Expr *getSubExpr() { return cast<Expr>(Val); }
setSubExpr(Expr * E)17140b57cec5SDimitry Andric   void setSubExpr(Expr *E) { Val = E; }
17150b57cec5SDimitry Andric 
getBeginLoc()17160b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY {
17170b57cec5SDimitry Andric     return Val->getBeginLoc();
17180b57cec5SDimitry Andric   }
getEndLoc()17190b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY { return Val->getEndLoc(); }
17200b57cec5SDimitry Andric 
classof(const Stmt * T)17210b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
17220b57cec5SDimitry Andric     return T->getStmtClass() == ImaginaryLiteralClass;
17230b57cec5SDimitry Andric   }
17240b57cec5SDimitry Andric 
17250b57cec5SDimitry Andric   // Iterators
children()17260b57cec5SDimitry Andric   child_range children() { return child_range(&Val, &Val+1); }
children()17270b57cec5SDimitry Andric   const_child_range children() const {
17280b57cec5SDimitry Andric     return const_child_range(&Val, &Val + 1);
17290b57cec5SDimitry Andric   }
17300b57cec5SDimitry Andric };
17310b57cec5SDimitry Andric 
17325f757f3fSDimitry Andric enum class StringLiteralKind {
17335f757f3fSDimitry Andric   Ordinary,
17345f757f3fSDimitry Andric   Wide,
17355f757f3fSDimitry Andric   UTF8,
17365f757f3fSDimitry Andric   UTF16,
17375f757f3fSDimitry Andric   UTF32,
17385f757f3fSDimitry Andric   Unevaluated
17395f757f3fSDimitry Andric };
17405f757f3fSDimitry Andric 
17410b57cec5SDimitry Andric /// StringLiteral - This represents a string literal expression, e.g. "foo"
17420b57cec5SDimitry Andric /// or L"bar" (wide strings). The actual string data can be obtained with
17430b57cec5SDimitry Andric /// getBytes() and is NOT null-terminated. The length of the string data is
17440b57cec5SDimitry Andric /// determined by calling getByteLength().
17450b57cec5SDimitry Andric ///
17460b57cec5SDimitry Andric /// The C type for a string is always a ConstantArrayType. In C++, the char
17470b57cec5SDimitry Andric /// type is const qualified, in C it is not.
17480b57cec5SDimitry Andric ///
17490b57cec5SDimitry Andric /// Note that strings in C can be formed by concatenation of multiple string
17500b57cec5SDimitry Andric /// literal pptokens in translation phase #6. This keeps track of the locations
17510b57cec5SDimitry Andric /// of each of these pieces.
17520b57cec5SDimitry Andric ///
17530b57cec5SDimitry Andric /// Strings in C can also be truncated and extended by assigning into arrays,
17540b57cec5SDimitry Andric /// e.g. with constructs like:
17550b57cec5SDimitry Andric ///   char X[2] = "foobar";
17560b57cec5SDimitry Andric /// In this case, getByteLength() will return 6, but the string literal will
17570b57cec5SDimitry Andric /// have type "char[2]".
17580b57cec5SDimitry Andric class StringLiteral final
17590b57cec5SDimitry Andric     : public Expr,
17600b57cec5SDimitry Andric       private llvm::TrailingObjects<StringLiteral, unsigned, SourceLocation,
17610b57cec5SDimitry Andric                                     char> {
17620b57cec5SDimitry Andric   friend class ASTStmtReader;
17630b57cec5SDimitry Andric   friend TrailingObjects;
17640b57cec5SDimitry Andric 
17650b57cec5SDimitry Andric   /// StringLiteral is followed by several trailing objects. They are in order:
17660b57cec5SDimitry Andric   ///
17670b57cec5SDimitry Andric   /// * A single unsigned storing the length in characters of this string. The
17680b57cec5SDimitry Andric   ///   length in bytes is this length times the width of a single character.
17690b57cec5SDimitry Andric   ///   Always present and stored as a trailing objects because storing it in
17700b57cec5SDimitry Andric   ///   StringLiteral would increase the size of StringLiteral by sizeof(void *)
17710b57cec5SDimitry Andric   ///   due to alignment requirements. If you add some data to StringLiteral,
17720b57cec5SDimitry Andric   ///   consider moving it inside StringLiteral.
17730b57cec5SDimitry Andric   ///
17740b57cec5SDimitry Andric   /// * An array of getNumConcatenated() SourceLocation, one for each of the
17750b57cec5SDimitry Andric   ///   token this string is made of.
17760b57cec5SDimitry Andric   ///
17770b57cec5SDimitry Andric   /// * An array of getByteLength() char used to store the string data.
17780b57cec5SDimitry Andric 
numTrailingObjects(OverloadToken<unsigned>)17790b57cec5SDimitry Andric   unsigned numTrailingObjects(OverloadToken<unsigned>) const { return 1; }
numTrailingObjects(OverloadToken<SourceLocation>)17800b57cec5SDimitry Andric   unsigned numTrailingObjects(OverloadToken<SourceLocation>) const {
17810b57cec5SDimitry Andric     return getNumConcatenated();
17820b57cec5SDimitry Andric   }
17830b57cec5SDimitry Andric 
numTrailingObjects(OverloadToken<char>)17840b57cec5SDimitry Andric   unsigned numTrailingObjects(OverloadToken<char>) const {
17850b57cec5SDimitry Andric     return getByteLength();
17860b57cec5SDimitry Andric   }
17870b57cec5SDimitry Andric 
getStrDataAsChar()17880b57cec5SDimitry Andric   char *getStrDataAsChar() { return getTrailingObjects<char>(); }
getStrDataAsChar()17890b57cec5SDimitry Andric   const char *getStrDataAsChar() const { return getTrailingObjects<char>(); }
17900b57cec5SDimitry Andric 
getStrDataAsUInt16()17910b57cec5SDimitry Andric   const uint16_t *getStrDataAsUInt16() const {
17920b57cec5SDimitry Andric     return reinterpret_cast<const uint16_t *>(getTrailingObjects<char>());
17930b57cec5SDimitry Andric   }
17940b57cec5SDimitry Andric 
getStrDataAsUInt32()17950b57cec5SDimitry Andric   const uint32_t *getStrDataAsUInt32() const {
17960b57cec5SDimitry Andric     return reinterpret_cast<const uint32_t *>(getTrailingObjects<char>());
17970b57cec5SDimitry Andric   }
17980b57cec5SDimitry Andric 
17990b57cec5SDimitry Andric   /// Build a string literal.
18005f757f3fSDimitry Andric   StringLiteral(const ASTContext &Ctx, StringRef Str, StringLiteralKind Kind,
18010b57cec5SDimitry Andric                 bool Pascal, QualType Ty, const SourceLocation *Loc,
18020b57cec5SDimitry Andric                 unsigned NumConcatenated);
18030b57cec5SDimitry Andric 
18040b57cec5SDimitry Andric   /// Build an empty string literal.
18050b57cec5SDimitry Andric   StringLiteral(EmptyShell Empty, unsigned NumConcatenated, unsigned Length,
18060b57cec5SDimitry Andric                 unsigned CharByteWidth);
18070b57cec5SDimitry Andric 
18080b57cec5SDimitry Andric   /// Map a target and string kind to the appropriate character width.
18095f757f3fSDimitry Andric   static unsigned mapCharByteWidth(TargetInfo const &Target,
18105f757f3fSDimitry Andric                                    StringLiteralKind SK);
18110b57cec5SDimitry Andric 
18120b57cec5SDimitry Andric   /// Set one of the string literal token.
setStrTokenLoc(unsigned TokNum,SourceLocation L)18130b57cec5SDimitry Andric   void setStrTokenLoc(unsigned TokNum, SourceLocation L) {
18140b57cec5SDimitry Andric     assert(TokNum < getNumConcatenated() && "Invalid tok number");
18150b57cec5SDimitry Andric     getTrailingObjects<SourceLocation>()[TokNum] = L;
18160b57cec5SDimitry Andric   }
18170b57cec5SDimitry Andric 
18180b57cec5SDimitry Andric public:
18190b57cec5SDimitry Andric   /// This is the "fully general" constructor that allows representation of
18200b57cec5SDimitry Andric   /// strings formed from multiple concatenated tokens.
18210b57cec5SDimitry Andric   static StringLiteral *Create(const ASTContext &Ctx, StringRef Str,
18225f757f3fSDimitry Andric                                StringLiteralKind Kind, bool Pascal, QualType Ty,
18230b57cec5SDimitry Andric                                const SourceLocation *Loc,
18240b57cec5SDimitry Andric                                unsigned NumConcatenated);
18250b57cec5SDimitry Andric 
18260b57cec5SDimitry Andric   /// Simple constructor for string literals made from one token.
Create(const ASTContext & Ctx,StringRef Str,StringLiteralKind Kind,bool Pascal,QualType Ty,SourceLocation Loc)18270b57cec5SDimitry Andric   static StringLiteral *Create(const ASTContext &Ctx, StringRef Str,
18285f757f3fSDimitry Andric                                StringLiteralKind Kind, bool Pascal, QualType Ty,
18290b57cec5SDimitry Andric                                SourceLocation Loc) {
18300b57cec5SDimitry Andric     return Create(Ctx, Str, Kind, Pascal, Ty, &Loc, 1);
18310b57cec5SDimitry Andric   }
18320b57cec5SDimitry Andric 
18330b57cec5SDimitry Andric   /// Construct an empty string literal.
18340b57cec5SDimitry Andric   static StringLiteral *CreateEmpty(const ASTContext &Ctx,
18350b57cec5SDimitry Andric                                     unsigned NumConcatenated, unsigned Length,
18360b57cec5SDimitry Andric                                     unsigned CharByteWidth);
18370b57cec5SDimitry Andric 
getString()18380b57cec5SDimitry Andric   StringRef getString() const {
183906c3fb27SDimitry Andric     assert((isUnevaluated() || getCharByteWidth() == 1) &&
18400b57cec5SDimitry Andric            "This function is used in places that assume strings use char");
18410b57cec5SDimitry Andric     return StringRef(getStrDataAsChar(), getByteLength());
18420b57cec5SDimitry Andric   }
18430b57cec5SDimitry Andric 
18440b57cec5SDimitry Andric   /// Allow access to clients that need the byte representation, such as
18450b57cec5SDimitry Andric   /// ASTWriterStmt::VisitStringLiteral().
getBytes()18460b57cec5SDimitry Andric   StringRef getBytes() const {
18470b57cec5SDimitry Andric     // FIXME: StringRef may not be the right type to use as a result for this.
18480b57cec5SDimitry Andric     return StringRef(getStrDataAsChar(), getByteLength());
18490b57cec5SDimitry Andric   }
18500b57cec5SDimitry Andric 
18510b57cec5SDimitry Andric   void outputString(raw_ostream &OS) const;
18520b57cec5SDimitry Andric 
getCodeUnit(size_t i)18530b57cec5SDimitry Andric   uint32_t getCodeUnit(size_t i) const {
18540b57cec5SDimitry Andric     assert(i < getLength() && "out of bounds access");
18550b57cec5SDimitry Andric     switch (getCharByteWidth()) {
18560b57cec5SDimitry Andric     case 1:
18570b57cec5SDimitry Andric       return static_cast<unsigned char>(getStrDataAsChar()[i]);
18580b57cec5SDimitry Andric     case 2:
18590b57cec5SDimitry Andric       return getStrDataAsUInt16()[i];
18600b57cec5SDimitry Andric     case 4:
18610b57cec5SDimitry Andric       return getStrDataAsUInt32()[i];
18620b57cec5SDimitry Andric     }
18630b57cec5SDimitry Andric     llvm_unreachable("Unsupported character width!");
18640b57cec5SDimitry Andric   }
18650b57cec5SDimitry Andric 
getByteLength()18660b57cec5SDimitry Andric   unsigned getByteLength() const { return getCharByteWidth() * getLength(); }
getLength()18670b57cec5SDimitry Andric   unsigned getLength() const { return *getTrailingObjects<unsigned>(); }
getCharByteWidth()18680b57cec5SDimitry Andric   unsigned getCharByteWidth() const { return StringLiteralBits.CharByteWidth; }
18690b57cec5SDimitry Andric 
getKind()18705f757f3fSDimitry Andric   StringLiteralKind getKind() const {
18715f757f3fSDimitry Andric     return static_cast<StringLiteralKind>(StringLiteralBits.Kind);
18720b57cec5SDimitry Andric   }
18730b57cec5SDimitry Andric 
isOrdinary()18745f757f3fSDimitry Andric   bool isOrdinary() const { return getKind() == StringLiteralKind::Ordinary; }
isWide()18755f757f3fSDimitry Andric   bool isWide() const { return getKind() == StringLiteralKind::Wide; }
isUTF8()18765f757f3fSDimitry Andric   bool isUTF8() const { return getKind() == StringLiteralKind::UTF8; }
isUTF16()18775f757f3fSDimitry Andric   bool isUTF16() const { return getKind() == StringLiteralKind::UTF16; }
isUTF32()18785f757f3fSDimitry Andric   bool isUTF32() const { return getKind() == StringLiteralKind::UTF32; }
isUnevaluated()18795f757f3fSDimitry Andric   bool isUnevaluated() const { return getKind() == StringLiteralKind::Unevaluated; }
isPascal()18800b57cec5SDimitry Andric   bool isPascal() const { return StringLiteralBits.IsPascal; }
18810b57cec5SDimitry Andric 
containsNonAscii()18820b57cec5SDimitry Andric   bool containsNonAscii() const {
18830b57cec5SDimitry Andric     for (auto c : getString())
18840b57cec5SDimitry Andric       if (!isASCII(c))
18850b57cec5SDimitry Andric         return true;
18860b57cec5SDimitry Andric     return false;
18870b57cec5SDimitry Andric   }
18880b57cec5SDimitry Andric 
containsNonAsciiOrNull()18890b57cec5SDimitry Andric   bool containsNonAsciiOrNull() const {
18900b57cec5SDimitry Andric     for (auto c : getString())
18910b57cec5SDimitry Andric       if (!isASCII(c) || !c)
18920b57cec5SDimitry Andric         return true;
18930b57cec5SDimitry Andric     return false;
18940b57cec5SDimitry Andric   }
18950b57cec5SDimitry Andric 
18960b57cec5SDimitry Andric   /// getNumConcatenated - Get the number of string literal tokens that were
18970b57cec5SDimitry Andric   /// concatenated in translation phase #6 to form this string literal.
getNumConcatenated()18980b57cec5SDimitry Andric   unsigned getNumConcatenated() const {
18990b57cec5SDimitry Andric     return StringLiteralBits.NumConcatenated;
19000b57cec5SDimitry Andric   }
19010b57cec5SDimitry Andric 
19020b57cec5SDimitry Andric   /// Get one of the string literal token.
getStrTokenLoc(unsigned TokNum)19030b57cec5SDimitry Andric   SourceLocation getStrTokenLoc(unsigned TokNum) const {
19040b57cec5SDimitry Andric     assert(TokNum < getNumConcatenated() && "Invalid tok number");
19050b57cec5SDimitry Andric     return getTrailingObjects<SourceLocation>()[TokNum];
19060b57cec5SDimitry Andric   }
19070b57cec5SDimitry Andric 
19080b57cec5SDimitry Andric   /// getLocationOfByte - Return a source location that points to the specified
19090b57cec5SDimitry Andric   /// byte of this string literal.
19100b57cec5SDimitry Andric   ///
19110b57cec5SDimitry Andric   /// Strings are amazingly complex.  They can be formed from multiple tokens
19120b57cec5SDimitry Andric   /// and can have escape sequences in them in addition to the usual trigraph
19130b57cec5SDimitry Andric   /// and escaped newline business.  This routine handles this complexity.
19140b57cec5SDimitry Andric   ///
19150b57cec5SDimitry Andric   SourceLocation
19160b57cec5SDimitry Andric   getLocationOfByte(unsigned ByteNo, const SourceManager &SM,
19170b57cec5SDimitry Andric                     const LangOptions &Features, const TargetInfo &Target,
19180b57cec5SDimitry Andric                     unsigned *StartToken = nullptr,
19190b57cec5SDimitry Andric                     unsigned *StartTokenByteOffset = nullptr) const;
19200b57cec5SDimitry Andric 
19210b57cec5SDimitry Andric   typedef const SourceLocation *tokloc_iterator;
19220b57cec5SDimitry Andric 
tokloc_begin()19230b57cec5SDimitry Andric   tokloc_iterator tokloc_begin() const {
19240b57cec5SDimitry Andric     return getTrailingObjects<SourceLocation>();
19250b57cec5SDimitry Andric   }
19260b57cec5SDimitry Andric 
tokloc_end()19270b57cec5SDimitry Andric   tokloc_iterator tokloc_end() const {
19280b57cec5SDimitry Andric     return getTrailingObjects<SourceLocation>() + getNumConcatenated();
19290b57cec5SDimitry Andric   }
19300b57cec5SDimitry Andric 
getBeginLoc()19310b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY { return *tokloc_begin(); }
getEndLoc()19320b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY { return *(tokloc_end() - 1); }
19330b57cec5SDimitry Andric 
classof(const Stmt * T)19340b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
19350b57cec5SDimitry Andric     return T->getStmtClass() == StringLiteralClass;
19360b57cec5SDimitry Andric   }
19370b57cec5SDimitry Andric 
19380b57cec5SDimitry Andric   // Iterators
children()19390b57cec5SDimitry Andric   child_range children() {
19400b57cec5SDimitry Andric     return child_range(child_iterator(), child_iterator());
19410b57cec5SDimitry Andric   }
children()19420b57cec5SDimitry Andric   const_child_range children() const {
19430b57cec5SDimitry Andric     return const_child_range(const_child_iterator(), const_child_iterator());
19440b57cec5SDimitry Andric   }
19450b57cec5SDimitry Andric };
19460b57cec5SDimitry Andric 
19475f757f3fSDimitry Andric enum class PredefinedIdentKind {
19480b57cec5SDimitry Andric   Func,
19490b57cec5SDimitry Andric   Function,
19500b57cec5SDimitry Andric   LFunction, // Same as Function, but as wide string.
19510b57cec5SDimitry Andric   FuncDName,
19520b57cec5SDimitry Andric   FuncSig,
1953bdd1243dSDimitry Andric   LFuncSig, // Same as FuncSig, but as wide string
19540b57cec5SDimitry Andric   PrettyFunction,
19550b57cec5SDimitry Andric   /// The same as PrettyFunction, except that the
19560b57cec5SDimitry Andric   /// 'virtual' keyword is omitted for virtual member functions.
1957e8d8bef9SDimitry Andric   PrettyFunctionNoVirtual
19580b57cec5SDimitry Andric };
19590b57cec5SDimitry Andric 
19605f757f3fSDimitry Andric /// [C99 6.4.2.2] - A predefined identifier such as __func__.
19615f757f3fSDimitry Andric class PredefinedExpr final
19625f757f3fSDimitry Andric     : public Expr,
19635f757f3fSDimitry Andric       private llvm::TrailingObjects<PredefinedExpr, Stmt *> {
19645f757f3fSDimitry Andric   friend class ASTStmtReader;
19655f757f3fSDimitry Andric   friend TrailingObjects;
19665f757f3fSDimitry Andric 
19675f757f3fSDimitry Andric   // PredefinedExpr is optionally followed by a single trailing
19685f757f3fSDimitry Andric   // "Stmt *" for the predefined identifier. It is present if and only if
19695f757f3fSDimitry Andric   // hasFunctionName() is true and is always a "StringLiteral *".
19705f757f3fSDimitry Andric 
19715f757f3fSDimitry Andric   PredefinedExpr(SourceLocation L, QualType FNTy, PredefinedIdentKind IK,
197206c3fb27SDimitry Andric                  bool IsTransparent, StringLiteral *SL);
19730b57cec5SDimitry Andric 
19740b57cec5SDimitry Andric   explicit PredefinedExpr(EmptyShell Empty, bool HasFunctionName);
19750b57cec5SDimitry Andric 
19760b57cec5SDimitry Andric   /// True if this PredefinedExpr has storage for a function name.
hasFunctionName()19770b57cec5SDimitry Andric   bool hasFunctionName() const { return PredefinedExprBits.HasFunctionName; }
19780b57cec5SDimitry Andric 
setFunctionName(StringLiteral * SL)19790b57cec5SDimitry Andric   void setFunctionName(StringLiteral *SL) {
19800b57cec5SDimitry Andric     assert(hasFunctionName() &&
19810b57cec5SDimitry Andric            "This PredefinedExpr has no storage for a function name!");
19820b57cec5SDimitry Andric     *getTrailingObjects<Stmt *>() = SL;
19830b57cec5SDimitry Andric   }
19840b57cec5SDimitry Andric 
19850b57cec5SDimitry Andric public:
19860b57cec5SDimitry Andric   /// Create a PredefinedExpr.
198706c3fb27SDimitry Andric   ///
198806c3fb27SDimitry Andric   /// If IsTransparent, the PredefinedExpr is transparently handled as a
198906c3fb27SDimitry Andric   /// StringLiteral.
19900b57cec5SDimitry Andric   static PredefinedExpr *Create(const ASTContext &Ctx, SourceLocation L,
19915f757f3fSDimitry Andric                                 QualType FNTy, PredefinedIdentKind IK,
19925f757f3fSDimitry Andric                                 bool IsTransparent, StringLiteral *SL);
19930b57cec5SDimitry Andric 
19940b57cec5SDimitry Andric   /// Create an empty PredefinedExpr.
19950b57cec5SDimitry Andric   static PredefinedExpr *CreateEmpty(const ASTContext &Ctx,
19960b57cec5SDimitry Andric                                      bool HasFunctionName);
19970b57cec5SDimitry Andric 
getIdentKind()19985f757f3fSDimitry Andric   PredefinedIdentKind getIdentKind() const {
19995f757f3fSDimitry Andric     return static_cast<PredefinedIdentKind>(PredefinedExprBits.Kind);
20000b57cec5SDimitry Andric   }
20010b57cec5SDimitry Andric 
isTransparent()200206c3fb27SDimitry Andric   bool isTransparent() const { return PredefinedExprBits.IsTransparent; }
200306c3fb27SDimitry Andric 
getLocation()20040b57cec5SDimitry Andric   SourceLocation getLocation() const { return PredefinedExprBits.Loc; }
setLocation(SourceLocation L)20050b57cec5SDimitry Andric   void setLocation(SourceLocation L) { PredefinedExprBits.Loc = L; }
20060b57cec5SDimitry Andric 
getFunctionName()20070b57cec5SDimitry Andric   StringLiteral *getFunctionName() {
20080b57cec5SDimitry Andric     return hasFunctionName()
20090b57cec5SDimitry Andric                ? static_cast<StringLiteral *>(*getTrailingObjects<Stmt *>())
20100b57cec5SDimitry Andric                : nullptr;
20110b57cec5SDimitry Andric   }
20120b57cec5SDimitry Andric 
getFunctionName()20130b57cec5SDimitry Andric   const StringLiteral *getFunctionName() const {
20140b57cec5SDimitry Andric     return hasFunctionName()
20150b57cec5SDimitry Andric                ? static_cast<StringLiteral *>(*getTrailingObjects<Stmt *>())
20160b57cec5SDimitry Andric                : nullptr;
20170b57cec5SDimitry Andric   }
20180b57cec5SDimitry Andric 
20195f757f3fSDimitry Andric   static StringRef getIdentKindName(PredefinedIdentKind IK);
getIdentKindName()2020e8d8bef9SDimitry Andric   StringRef getIdentKindName() const {
2021e8d8bef9SDimitry Andric     return getIdentKindName(getIdentKind());
2022e8d8bef9SDimitry Andric   }
2023e8d8bef9SDimitry Andric 
20245f757f3fSDimitry Andric   static std::string ComputeName(PredefinedIdentKind IK,
20255f757f3fSDimitry Andric                                  const Decl *CurrentDecl);
20260b57cec5SDimitry Andric 
getBeginLoc()20270b57cec5SDimitry Andric   SourceLocation getBeginLoc() const { return getLocation(); }
getEndLoc()20280b57cec5SDimitry Andric   SourceLocation getEndLoc() const { return getLocation(); }
20290b57cec5SDimitry Andric 
classof(const Stmt * T)20300b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
20310b57cec5SDimitry Andric     return T->getStmtClass() == PredefinedExprClass;
20320b57cec5SDimitry Andric   }
20330b57cec5SDimitry Andric 
20340b57cec5SDimitry Andric   // Iterators
children()20350b57cec5SDimitry Andric   child_range children() {
20360b57cec5SDimitry Andric     return child_range(getTrailingObjects<Stmt *>(),
20370b57cec5SDimitry Andric                        getTrailingObjects<Stmt *>() + hasFunctionName());
20380b57cec5SDimitry Andric   }
20390b57cec5SDimitry Andric 
children()20400b57cec5SDimitry Andric   const_child_range children() const {
20410b57cec5SDimitry Andric     return const_child_range(getTrailingObjects<Stmt *>(),
20420b57cec5SDimitry Andric                              getTrailingObjects<Stmt *>() + hasFunctionName());
20430b57cec5SDimitry Andric   }
20440b57cec5SDimitry Andric };
20450b57cec5SDimitry Andric 
2046fe6060f1SDimitry Andric // This represents a use of the __builtin_sycl_unique_stable_name, which takes a
2047fe6060f1SDimitry Andric // type-id, and at CodeGen time emits a unique string representation of the
2048fe6060f1SDimitry Andric // type in a way that permits us to properly encode information about the SYCL
2049fe6060f1SDimitry Andric // kernels.
2050fe6060f1SDimitry Andric class SYCLUniqueStableNameExpr final : public Expr {
2051fe6060f1SDimitry Andric   friend class ASTStmtReader;
2052fe6060f1SDimitry Andric   SourceLocation OpLoc, LParen, RParen;
2053fe6060f1SDimitry Andric   TypeSourceInfo *TypeInfo;
2054fe6060f1SDimitry Andric 
2055fe6060f1SDimitry Andric   SYCLUniqueStableNameExpr(EmptyShell Empty, QualType ResultTy);
2056fe6060f1SDimitry Andric   SYCLUniqueStableNameExpr(SourceLocation OpLoc, SourceLocation LParen,
2057fe6060f1SDimitry Andric                            SourceLocation RParen, QualType ResultTy,
2058fe6060f1SDimitry Andric                            TypeSourceInfo *TSI);
2059fe6060f1SDimitry Andric 
setTypeSourceInfo(TypeSourceInfo * Ty)2060fe6060f1SDimitry Andric   void setTypeSourceInfo(TypeSourceInfo *Ty) { TypeInfo = Ty; }
2061fe6060f1SDimitry Andric 
setLocation(SourceLocation L)2062fe6060f1SDimitry Andric   void setLocation(SourceLocation L) { OpLoc = L; }
setLParenLocation(SourceLocation L)2063fe6060f1SDimitry Andric   void setLParenLocation(SourceLocation L) { LParen = L; }
setRParenLocation(SourceLocation L)2064fe6060f1SDimitry Andric   void setRParenLocation(SourceLocation L) { RParen = L; }
2065fe6060f1SDimitry Andric 
2066fe6060f1SDimitry Andric public:
getTypeSourceInfo()2067fe6060f1SDimitry Andric   TypeSourceInfo *getTypeSourceInfo() { return TypeInfo; }
2068fe6060f1SDimitry Andric 
getTypeSourceInfo()2069fe6060f1SDimitry Andric   const TypeSourceInfo *getTypeSourceInfo() const { return TypeInfo; }
2070fe6060f1SDimitry Andric 
2071fe6060f1SDimitry Andric   static SYCLUniqueStableNameExpr *
2072fe6060f1SDimitry Andric   Create(const ASTContext &Ctx, SourceLocation OpLoc, SourceLocation LParen,
2073fe6060f1SDimitry Andric          SourceLocation RParen, TypeSourceInfo *TSI);
2074fe6060f1SDimitry Andric 
2075fe6060f1SDimitry Andric   static SYCLUniqueStableNameExpr *CreateEmpty(const ASTContext &Ctx);
2076fe6060f1SDimitry Andric 
getBeginLoc()2077fe6060f1SDimitry Andric   SourceLocation getBeginLoc() const { return getLocation(); }
getEndLoc()2078fe6060f1SDimitry Andric   SourceLocation getEndLoc() const { return RParen; }
getLocation()2079fe6060f1SDimitry Andric   SourceLocation getLocation() const { return OpLoc; }
getLParenLocation()2080fe6060f1SDimitry Andric   SourceLocation getLParenLocation() const { return LParen; }
getRParenLocation()2081fe6060f1SDimitry Andric   SourceLocation getRParenLocation() const { return RParen; }
2082fe6060f1SDimitry Andric 
classof(const Stmt * T)2083fe6060f1SDimitry Andric   static bool classof(const Stmt *T) {
2084fe6060f1SDimitry Andric     return T->getStmtClass() == SYCLUniqueStableNameExprClass;
2085fe6060f1SDimitry Andric   }
2086fe6060f1SDimitry Andric 
2087fe6060f1SDimitry Andric   // Iterators
children()2088fe6060f1SDimitry Andric   child_range children() {
2089fe6060f1SDimitry Andric     return child_range(child_iterator(), child_iterator());
2090fe6060f1SDimitry Andric   }
2091fe6060f1SDimitry Andric 
children()2092fe6060f1SDimitry Andric   const_child_range children() const {
2093fe6060f1SDimitry Andric     return const_child_range(const_child_iterator(), const_child_iterator());
2094fe6060f1SDimitry Andric   }
2095fe6060f1SDimitry Andric 
2096fe6060f1SDimitry Andric   // Convenience function to generate the name of the currently stored type.
2097fe6060f1SDimitry Andric   std::string ComputeName(ASTContext &Context) const;
2098fe6060f1SDimitry Andric 
2099fe6060f1SDimitry Andric   // Get the generated name of the type.  Note that this only works after all
2100fe6060f1SDimitry Andric   // kernels have been instantiated.
2101fe6060f1SDimitry Andric   static std::string ComputeName(ASTContext &Context, QualType Ty);
2102fe6060f1SDimitry Andric };
2103fe6060f1SDimitry Andric 
21040b57cec5SDimitry Andric /// ParenExpr - This represents a parethesized expression, e.g. "(1)".  This
21050b57cec5SDimitry Andric /// AST node is only formed if full location information is requested.
21060b57cec5SDimitry Andric class ParenExpr : public Expr {
21070b57cec5SDimitry Andric   SourceLocation L, R;
21080b57cec5SDimitry Andric   Stmt *Val;
21090b57cec5SDimitry Andric public:
ParenExpr(SourceLocation l,SourceLocation r,Expr * val)21100b57cec5SDimitry Andric   ParenExpr(SourceLocation l, SourceLocation r, Expr *val)
21115ffd83dbSDimitry Andric       : Expr(ParenExprClass, val->getType(), val->getValueKind(),
21125ffd83dbSDimitry Andric              val->getObjectKind()),
21135ffd83dbSDimitry Andric         L(l), R(r), Val(val) {
21145ffd83dbSDimitry Andric     setDependence(computeDependence(this));
21155ffd83dbSDimitry Andric   }
21160b57cec5SDimitry Andric 
21170b57cec5SDimitry Andric   /// Construct an empty parenthesized expression.
ParenExpr(EmptyShell Empty)21180b57cec5SDimitry Andric   explicit ParenExpr(EmptyShell Empty)
21190b57cec5SDimitry Andric     : Expr(ParenExprClass, Empty) { }
21200b57cec5SDimitry Andric 
getSubExpr()21210b57cec5SDimitry Andric   const Expr *getSubExpr() const { return cast<Expr>(Val); }
getSubExpr()21220b57cec5SDimitry Andric   Expr *getSubExpr() { return cast<Expr>(Val); }
setSubExpr(Expr * E)21230b57cec5SDimitry Andric   void setSubExpr(Expr *E) { Val = E; }
21240b57cec5SDimitry Andric 
getBeginLoc()21250b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY { return L; }
getEndLoc()21260b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY { return R; }
21270b57cec5SDimitry Andric 
21280b57cec5SDimitry Andric   /// Get the location of the left parentheses '('.
getLParen()21290b57cec5SDimitry Andric   SourceLocation getLParen() const { return L; }
setLParen(SourceLocation Loc)21300b57cec5SDimitry Andric   void setLParen(SourceLocation Loc) { L = Loc; }
21310b57cec5SDimitry Andric 
21320b57cec5SDimitry Andric   /// Get the location of the right parentheses ')'.
getRParen()21330b57cec5SDimitry Andric   SourceLocation getRParen() const { return R; }
setRParen(SourceLocation Loc)21340b57cec5SDimitry Andric   void setRParen(SourceLocation Loc) { R = Loc; }
21350b57cec5SDimitry Andric 
classof(const Stmt * T)21360b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
21370b57cec5SDimitry Andric     return T->getStmtClass() == ParenExprClass;
21380b57cec5SDimitry Andric   }
21390b57cec5SDimitry Andric 
21400b57cec5SDimitry Andric   // Iterators
children()21410b57cec5SDimitry Andric   child_range children() { return child_range(&Val, &Val+1); }
children()21420b57cec5SDimitry Andric   const_child_range children() const {
21430b57cec5SDimitry Andric     return const_child_range(&Val, &Val + 1);
21440b57cec5SDimitry Andric   }
21450b57cec5SDimitry Andric };
21460b57cec5SDimitry Andric 
21470b57cec5SDimitry Andric /// UnaryOperator - This represents the unary-expression's (except sizeof and
21480b57cec5SDimitry Andric /// alignof), the postinc/postdec operators from postfix-expression, and various
21490b57cec5SDimitry Andric /// extensions.
21500b57cec5SDimitry Andric ///
21510b57cec5SDimitry Andric /// Notes on various nodes:
21520b57cec5SDimitry Andric ///
21530b57cec5SDimitry Andric /// Real/Imag - These return the real/imag part of a complex operand.  If
21540b57cec5SDimitry Andric ///   applied to a non-complex value, the former returns its operand and the
21550b57cec5SDimitry Andric ///   later returns zero in the type of the operand.
21560b57cec5SDimitry Andric ///
21575ffd83dbSDimitry Andric class UnaryOperator final
21585ffd83dbSDimitry Andric     : public Expr,
21595ffd83dbSDimitry Andric       private llvm::TrailingObjects<UnaryOperator, FPOptionsOverride> {
21600b57cec5SDimitry Andric   Stmt *Val;
21610b57cec5SDimitry Andric 
numTrailingObjects(OverloadToken<FPOptionsOverride>)21625ffd83dbSDimitry Andric   size_t numTrailingObjects(OverloadToken<FPOptionsOverride>) const {
21635ffd83dbSDimitry Andric     return UnaryOperatorBits.HasFPFeatures ? 1 : 0;
21645ffd83dbSDimitry Andric   }
21655ffd83dbSDimitry Andric 
getTrailingFPFeatures()21665ffd83dbSDimitry Andric   FPOptionsOverride &getTrailingFPFeatures() {
21675ffd83dbSDimitry Andric     assert(UnaryOperatorBits.HasFPFeatures);
21685ffd83dbSDimitry Andric     return *getTrailingObjects<FPOptionsOverride>();
21695ffd83dbSDimitry Andric   }
21705ffd83dbSDimitry Andric 
getTrailingFPFeatures()21715ffd83dbSDimitry Andric   const FPOptionsOverride &getTrailingFPFeatures() const {
21725ffd83dbSDimitry Andric     assert(UnaryOperatorBits.HasFPFeatures);
21735ffd83dbSDimitry Andric     return *getTrailingObjects<FPOptionsOverride>();
21745ffd83dbSDimitry Andric   }
21755ffd83dbSDimitry Andric 
21760b57cec5SDimitry Andric public:
21770b57cec5SDimitry Andric   typedef UnaryOperatorKind Opcode;
21780b57cec5SDimitry Andric 
21795ffd83dbSDimitry Andric protected:
21805ffd83dbSDimitry Andric   UnaryOperator(const ASTContext &Ctx, Expr *input, Opcode opc, QualType type,
21815ffd83dbSDimitry Andric                 ExprValueKind VK, ExprObjectKind OK, SourceLocation l,
21825ffd83dbSDimitry Andric                 bool CanOverflow, FPOptionsOverride FPFeatures);
21830b57cec5SDimitry Andric 
21840b57cec5SDimitry Andric   /// Build an empty unary operator.
UnaryOperator(bool HasFPFeatures,EmptyShell Empty)21855ffd83dbSDimitry Andric   explicit UnaryOperator(bool HasFPFeatures, EmptyShell Empty)
21865ffd83dbSDimitry Andric       : Expr(UnaryOperatorClass, Empty) {
21870b57cec5SDimitry Andric     UnaryOperatorBits.Opc = UO_AddrOf;
21885ffd83dbSDimitry Andric     UnaryOperatorBits.HasFPFeatures = HasFPFeatures;
21890b57cec5SDimitry Andric   }
21900b57cec5SDimitry Andric 
21915ffd83dbSDimitry Andric public:
21925ffd83dbSDimitry Andric   static UnaryOperator *CreateEmpty(const ASTContext &C, bool hasFPFeatures);
21935ffd83dbSDimitry Andric 
21945ffd83dbSDimitry Andric   static UnaryOperator *Create(const ASTContext &C, Expr *input, Opcode opc,
21955ffd83dbSDimitry Andric                                QualType type, ExprValueKind VK,
21965ffd83dbSDimitry Andric                                ExprObjectKind OK, SourceLocation l,
21975ffd83dbSDimitry Andric                                bool CanOverflow, FPOptionsOverride FPFeatures);
21985ffd83dbSDimitry Andric 
getOpcode()21990b57cec5SDimitry Andric   Opcode getOpcode() const {
22000b57cec5SDimitry Andric     return static_cast<Opcode>(UnaryOperatorBits.Opc);
22010b57cec5SDimitry Andric   }
setOpcode(Opcode Opc)22020b57cec5SDimitry Andric   void setOpcode(Opcode Opc) { UnaryOperatorBits.Opc = Opc; }
22030b57cec5SDimitry Andric 
getSubExpr()22040b57cec5SDimitry Andric   Expr *getSubExpr() const { return cast<Expr>(Val); }
setSubExpr(Expr * E)22050b57cec5SDimitry Andric   void setSubExpr(Expr *E) { Val = E; }
22060b57cec5SDimitry Andric 
22070b57cec5SDimitry Andric   /// getOperatorLoc - Return the location of the operator.
getOperatorLoc()22080b57cec5SDimitry Andric   SourceLocation getOperatorLoc() const { return UnaryOperatorBits.Loc; }
setOperatorLoc(SourceLocation L)22090b57cec5SDimitry Andric   void setOperatorLoc(SourceLocation L) { UnaryOperatorBits.Loc = L; }
22100b57cec5SDimitry Andric 
22110b57cec5SDimitry Andric   /// Returns true if the unary operator can cause an overflow. For instance,
22120b57cec5SDimitry Andric   ///   signed int i = INT_MAX; i++;
22130b57cec5SDimitry Andric   ///   signed char c = CHAR_MAX; c++;
22140b57cec5SDimitry Andric   /// Due to integer promotions, c++ is promoted to an int before the postfix
22150b57cec5SDimitry Andric   /// increment, and the result is an int that cannot overflow. However, i++
22160b57cec5SDimitry Andric   /// can overflow.
canOverflow()22170b57cec5SDimitry Andric   bool canOverflow() const { return UnaryOperatorBits.CanOverflow; }
setCanOverflow(bool C)22180b57cec5SDimitry Andric   void setCanOverflow(bool C) { UnaryOperatorBits.CanOverflow = C; }
22190b57cec5SDimitry Andric 
222006c3fb27SDimitry Andric   /// Get the FP contractability status of this operator. Only meaningful for
222106c3fb27SDimitry Andric   /// operations on floating point types.
isFPContractableWithinStatement(const LangOptions & LO)22225ffd83dbSDimitry Andric   bool isFPContractableWithinStatement(const LangOptions &LO) const {
22235ffd83dbSDimitry Andric     return getFPFeaturesInEffect(LO).allowFPContractWithinStatement();
22245ffd83dbSDimitry Andric   }
22255ffd83dbSDimitry Andric 
222606c3fb27SDimitry Andric   /// Get the FENV_ACCESS status of this operator. Only meaningful for
222706c3fb27SDimitry Andric   /// operations on floating point types.
isFEnvAccessOn(const LangOptions & LO)22285ffd83dbSDimitry Andric   bool isFEnvAccessOn(const LangOptions &LO) const {
22295ffd83dbSDimitry Andric     return getFPFeaturesInEffect(LO).getAllowFEnvAccess();
22305ffd83dbSDimitry Andric   }
22315ffd83dbSDimitry Andric 
22320b57cec5SDimitry Andric   /// isPostfix - Return true if this is a postfix operation, like x++.
isPostfix(Opcode Op)22330b57cec5SDimitry Andric   static bool isPostfix(Opcode Op) {
22340b57cec5SDimitry Andric     return Op == UO_PostInc || Op == UO_PostDec;
22350b57cec5SDimitry Andric   }
22360b57cec5SDimitry Andric 
22370b57cec5SDimitry Andric   /// isPrefix - Return true if this is a prefix operation, like --x.
isPrefix(Opcode Op)22380b57cec5SDimitry Andric   static bool isPrefix(Opcode Op) {
22390b57cec5SDimitry Andric     return Op == UO_PreInc || Op == UO_PreDec;
22400b57cec5SDimitry Andric   }
22410b57cec5SDimitry Andric 
isPrefix()22420b57cec5SDimitry Andric   bool isPrefix() const { return isPrefix(getOpcode()); }
isPostfix()22430b57cec5SDimitry Andric   bool isPostfix() const { return isPostfix(getOpcode()); }
22440b57cec5SDimitry Andric 
isIncrementOp(Opcode Op)22450b57cec5SDimitry Andric   static bool isIncrementOp(Opcode Op) {
22460b57cec5SDimitry Andric     return Op == UO_PreInc || Op == UO_PostInc;
22470b57cec5SDimitry Andric   }
isIncrementOp()22480b57cec5SDimitry Andric   bool isIncrementOp() const {
22490b57cec5SDimitry Andric     return isIncrementOp(getOpcode());
22500b57cec5SDimitry Andric   }
22510b57cec5SDimitry Andric 
isDecrementOp(Opcode Op)22520b57cec5SDimitry Andric   static bool isDecrementOp(Opcode Op) {
22530b57cec5SDimitry Andric     return Op == UO_PreDec || Op == UO_PostDec;
22540b57cec5SDimitry Andric   }
isDecrementOp()22550b57cec5SDimitry Andric   bool isDecrementOp() const {
22560b57cec5SDimitry Andric     return isDecrementOp(getOpcode());
22570b57cec5SDimitry Andric   }
22580b57cec5SDimitry Andric 
isIncrementDecrementOp(Opcode Op)22590b57cec5SDimitry Andric   static bool isIncrementDecrementOp(Opcode Op) { return Op <= UO_PreDec; }
isIncrementDecrementOp()22600b57cec5SDimitry Andric   bool isIncrementDecrementOp() const {
22610b57cec5SDimitry Andric     return isIncrementDecrementOp(getOpcode());
22620b57cec5SDimitry Andric   }
22630b57cec5SDimitry Andric 
isArithmeticOp(Opcode Op)22640b57cec5SDimitry Andric   static bool isArithmeticOp(Opcode Op) {
22650b57cec5SDimitry Andric     return Op >= UO_Plus && Op <= UO_LNot;
22660b57cec5SDimitry Andric   }
isArithmeticOp()22670b57cec5SDimitry Andric   bool isArithmeticOp() const { return isArithmeticOp(getOpcode()); }
22680b57cec5SDimitry Andric 
22690b57cec5SDimitry Andric   /// getOpcodeStr - Turn an Opcode enum value into the punctuation char it
22700b57cec5SDimitry Andric   /// corresponds to, e.g. "sizeof" or "[pre]++"
22710b57cec5SDimitry Andric   static StringRef getOpcodeStr(Opcode Op);
22720b57cec5SDimitry Andric 
22730b57cec5SDimitry Andric   /// Retrieve the unary opcode that corresponds to the given
22740b57cec5SDimitry Andric   /// overloaded operator.
22750b57cec5SDimitry Andric   static Opcode getOverloadedOpcode(OverloadedOperatorKind OO, bool Postfix);
22760b57cec5SDimitry Andric 
22770b57cec5SDimitry Andric   /// Retrieve the overloaded operator kind that corresponds to
22780b57cec5SDimitry Andric   /// the given unary opcode.
22790b57cec5SDimitry Andric   static OverloadedOperatorKind getOverloadedOperator(Opcode Opc);
22800b57cec5SDimitry Andric 
getBeginLoc()22810b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY {
22820b57cec5SDimitry Andric     return isPostfix() ? Val->getBeginLoc() : getOperatorLoc();
22830b57cec5SDimitry Andric   }
getEndLoc()22840b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY {
22850b57cec5SDimitry Andric     return isPostfix() ? getOperatorLoc() : Val->getEndLoc();
22860b57cec5SDimitry Andric   }
getExprLoc()22870b57cec5SDimitry Andric   SourceLocation getExprLoc() const { return getOperatorLoc(); }
22880b57cec5SDimitry Andric 
classof(const Stmt * T)22890b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
22900b57cec5SDimitry Andric     return T->getStmtClass() == UnaryOperatorClass;
22910b57cec5SDimitry Andric   }
22920b57cec5SDimitry Andric 
22930b57cec5SDimitry Andric   // Iterators
children()22940b57cec5SDimitry Andric   child_range children() { return child_range(&Val, &Val+1); }
children()22950b57cec5SDimitry Andric   const_child_range children() const {
22960b57cec5SDimitry Andric     return const_child_range(&Val, &Val + 1);
22970b57cec5SDimitry Andric   }
22985ffd83dbSDimitry Andric 
22995ffd83dbSDimitry Andric   /// Is FPFeatures in Trailing Storage?
hasStoredFPFeatures()23005ffd83dbSDimitry Andric   bool hasStoredFPFeatures() const { return UnaryOperatorBits.HasFPFeatures; }
23015ffd83dbSDimitry Andric 
2302e8d8bef9SDimitry Andric   /// Get FPFeatures from trailing storage.
getStoredFPFeatures()23035ffd83dbSDimitry Andric   FPOptionsOverride getStoredFPFeatures() const {
23045ffd83dbSDimitry Andric     return getTrailingFPFeatures();
23055ffd83dbSDimitry Andric   }
23065ffd83dbSDimitry Andric 
2307e8d8bef9SDimitry Andric protected:
23085f757f3fSDimitry Andric   /// Set FPFeatures in trailing storage, used by Serialization & ASTImporter.
setStoredFPFeatures(FPOptionsOverride F)23095ffd83dbSDimitry Andric   void setStoredFPFeatures(FPOptionsOverride F) { getTrailingFPFeatures() = F; }
23105ffd83dbSDimitry Andric 
23115ffd83dbSDimitry Andric public:
231206c3fb27SDimitry Andric   /// Get the FP features status of this operator. Only meaningful for
231306c3fb27SDimitry Andric   /// operations on floating point types.
getFPFeaturesInEffect(const LangOptions & LO)23145ffd83dbSDimitry Andric   FPOptions getFPFeaturesInEffect(const LangOptions &LO) const {
23155ffd83dbSDimitry Andric     if (UnaryOperatorBits.HasFPFeatures)
23165ffd83dbSDimitry Andric       return getStoredFPFeatures().applyOverrides(LO);
23175ffd83dbSDimitry Andric     return FPOptions::defaultWithoutTrailingStorage(LO);
23185ffd83dbSDimitry Andric   }
getFPOptionsOverride()23195ffd83dbSDimitry Andric   FPOptionsOverride getFPOptionsOverride() const {
23205ffd83dbSDimitry Andric     if (UnaryOperatorBits.HasFPFeatures)
23215ffd83dbSDimitry Andric       return getStoredFPFeatures();
23225ffd83dbSDimitry Andric     return FPOptionsOverride();
23235ffd83dbSDimitry Andric   }
23245ffd83dbSDimitry Andric 
23255ffd83dbSDimitry Andric   friend TrailingObjects;
23265f757f3fSDimitry Andric   friend class ASTNodeImporter;
23275ffd83dbSDimitry Andric   friend class ASTReader;
23285ffd83dbSDimitry Andric   friend class ASTStmtReader;
23295ffd83dbSDimitry Andric   friend class ASTStmtWriter;
23300b57cec5SDimitry Andric };
23310b57cec5SDimitry Andric 
23320b57cec5SDimitry Andric /// Helper class for OffsetOfExpr.
23330b57cec5SDimitry Andric 
23340b57cec5SDimitry Andric // __builtin_offsetof(type, identifier(.identifier|[expr])*)
23350b57cec5SDimitry Andric class OffsetOfNode {
23360b57cec5SDimitry Andric public:
23370b57cec5SDimitry Andric   /// The kind of offsetof node we have.
23380b57cec5SDimitry Andric   enum Kind {
23390b57cec5SDimitry Andric     /// An index into an array.
23400b57cec5SDimitry Andric     Array = 0x00,
23410b57cec5SDimitry Andric     /// A field.
23420b57cec5SDimitry Andric     Field = 0x01,
23430b57cec5SDimitry Andric     /// A field in a dependent type, known only by its name.
23440b57cec5SDimitry Andric     Identifier = 0x02,
23450b57cec5SDimitry Andric     /// An implicit indirection through a C++ base class, when the
23460b57cec5SDimitry Andric     /// field found is in a base class.
23470b57cec5SDimitry Andric     Base = 0x03
23480b57cec5SDimitry Andric   };
23490b57cec5SDimitry Andric 
23500b57cec5SDimitry Andric private:
23510b57cec5SDimitry Andric   enum { MaskBits = 2, Mask = 0x03 };
23520b57cec5SDimitry Andric 
23530b57cec5SDimitry Andric   /// The source range that covers this part of the designator.
23540b57cec5SDimitry Andric   SourceRange Range;
23550b57cec5SDimitry Andric 
23560b57cec5SDimitry Andric   /// The data describing the designator, which comes in three
23570b57cec5SDimitry Andric   /// different forms, depending on the lower two bits.
23580b57cec5SDimitry Andric   ///   - An unsigned index into the array of Expr*'s stored after this node
23590b57cec5SDimitry Andric   ///     in memory, for [constant-expression] designators.
23600b57cec5SDimitry Andric   ///   - A FieldDecl*, for references to a known field.
23610b57cec5SDimitry Andric   ///   - An IdentifierInfo*, for references to a field with a given name
23620b57cec5SDimitry Andric   ///     when the class type is dependent.
23630b57cec5SDimitry Andric   ///   - A CXXBaseSpecifier*, for references that look at a field in a
23640b57cec5SDimitry Andric   ///     base class.
23650b57cec5SDimitry Andric   uintptr_t Data;
23660b57cec5SDimitry Andric 
23670b57cec5SDimitry Andric public:
23680b57cec5SDimitry Andric   /// Create an offsetof node that refers to an array element.
OffsetOfNode(SourceLocation LBracketLoc,unsigned Index,SourceLocation RBracketLoc)23690b57cec5SDimitry Andric   OffsetOfNode(SourceLocation LBracketLoc, unsigned Index,
23700b57cec5SDimitry Andric                SourceLocation RBracketLoc)
23710b57cec5SDimitry Andric       : Range(LBracketLoc, RBracketLoc), Data((Index << 2) | Array) {}
23720b57cec5SDimitry Andric 
23730b57cec5SDimitry Andric   /// Create an offsetof node that refers to a field.
OffsetOfNode(SourceLocation DotLoc,FieldDecl * Field,SourceLocation NameLoc)23740b57cec5SDimitry Andric   OffsetOfNode(SourceLocation DotLoc, FieldDecl *Field, SourceLocation NameLoc)
23750b57cec5SDimitry Andric       : Range(DotLoc.isValid() ? DotLoc : NameLoc, NameLoc),
23760b57cec5SDimitry Andric         Data(reinterpret_cast<uintptr_t>(Field) | OffsetOfNode::Field) {}
23770b57cec5SDimitry Andric 
23780b57cec5SDimitry Andric   /// Create an offsetof node that refers to an identifier.
OffsetOfNode(SourceLocation DotLoc,IdentifierInfo * Name,SourceLocation NameLoc)23790b57cec5SDimitry Andric   OffsetOfNode(SourceLocation DotLoc, IdentifierInfo *Name,
23800b57cec5SDimitry Andric                SourceLocation NameLoc)
23810b57cec5SDimitry Andric       : Range(DotLoc.isValid() ? DotLoc : NameLoc, NameLoc),
23820b57cec5SDimitry Andric         Data(reinterpret_cast<uintptr_t>(Name) | Identifier) {}
23830b57cec5SDimitry Andric 
23840b57cec5SDimitry Andric   /// Create an offsetof node that refers into a C++ base class.
OffsetOfNode(const CXXBaseSpecifier * Base)23850b57cec5SDimitry Andric   explicit OffsetOfNode(const CXXBaseSpecifier *Base)
238604eeddc0SDimitry Andric       : Data(reinterpret_cast<uintptr_t>(Base) | OffsetOfNode::Base) {}
23870b57cec5SDimitry Andric 
23880b57cec5SDimitry Andric   /// Determine what kind of offsetof node this is.
getKind()23890b57cec5SDimitry Andric   Kind getKind() const { return static_cast<Kind>(Data & Mask); }
23900b57cec5SDimitry Andric 
23910b57cec5SDimitry Andric   /// For an array element node, returns the index into the array
23920b57cec5SDimitry Andric   /// of expressions.
getArrayExprIndex()23930b57cec5SDimitry Andric   unsigned getArrayExprIndex() const {
23940b57cec5SDimitry Andric     assert(getKind() == Array);
23950b57cec5SDimitry Andric     return Data >> 2;
23960b57cec5SDimitry Andric   }
23970b57cec5SDimitry Andric 
23980b57cec5SDimitry Andric   /// For a field offsetof node, returns the field.
getField()23990b57cec5SDimitry Andric   FieldDecl *getField() const {
24000b57cec5SDimitry Andric     assert(getKind() == Field);
24010b57cec5SDimitry Andric     return reinterpret_cast<FieldDecl *>(Data & ~(uintptr_t)Mask);
24020b57cec5SDimitry Andric   }
24030b57cec5SDimitry Andric 
24040b57cec5SDimitry Andric   /// For a field or identifier offsetof node, returns the name of
24050b57cec5SDimitry Andric   /// the field.
24060b57cec5SDimitry Andric   IdentifierInfo *getFieldName() const;
24070b57cec5SDimitry Andric 
24080b57cec5SDimitry Andric   /// For a base class node, returns the base specifier.
getBase()24090b57cec5SDimitry Andric   CXXBaseSpecifier *getBase() const {
24100b57cec5SDimitry Andric     assert(getKind() == Base);
24110b57cec5SDimitry Andric     return reinterpret_cast<CXXBaseSpecifier *>(Data & ~(uintptr_t)Mask);
24120b57cec5SDimitry Andric   }
24130b57cec5SDimitry Andric 
24140b57cec5SDimitry Andric   /// Retrieve the source range that covers this offsetof node.
24150b57cec5SDimitry Andric   ///
24160b57cec5SDimitry Andric   /// For an array element node, the source range contains the locations of
24170b57cec5SDimitry Andric   /// the square brackets. For a field or identifier node, the source range
24180b57cec5SDimitry Andric   /// contains the location of the period (if there is one) and the
24190b57cec5SDimitry Andric   /// identifier.
getSourceRange()24200b57cec5SDimitry Andric   SourceRange getSourceRange() const LLVM_READONLY { return Range; }
getBeginLoc()24210b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); }
getEndLoc()24220b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); }
24230b57cec5SDimitry Andric };
24240b57cec5SDimitry Andric 
24250b57cec5SDimitry Andric /// OffsetOfExpr - [C99 7.17] - This represents an expression of the form
24260b57cec5SDimitry Andric /// offsetof(record-type, member-designator). For example, given:
24270b57cec5SDimitry Andric /// @code
24280b57cec5SDimitry Andric /// struct S {
24290b57cec5SDimitry Andric ///   float f;
24300b57cec5SDimitry Andric ///   double d;
24310b57cec5SDimitry Andric /// };
24320b57cec5SDimitry Andric /// struct T {
24330b57cec5SDimitry Andric ///   int i;
24340b57cec5SDimitry Andric ///   struct S s[10];
24350b57cec5SDimitry Andric /// };
24360b57cec5SDimitry Andric /// @endcode
24370b57cec5SDimitry Andric /// we can represent and evaluate the expression @c offsetof(struct T, s[2].d).
24380b57cec5SDimitry Andric 
24390b57cec5SDimitry Andric class OffsetOfExpr final
24400b57cec5SDimitry Andric     : public Expr,
24410b57cec5SDimitry Andric       private llvm::TrailingObjects<OffsetOfExpr, OffsetOfNode, Expr *> {
24420b57cec5SDimitry Andric   SourceLocation OperatorLoc, RParenLoc;
24430b57cec5SDimitry Andric   // Base type;
24440b57cec5SDimitry Andric   TypeSourceInfo *TSInfo;
24450b57cec5SDimitry Andric   // Number of sub-components (i.e. instances of OffsetOfNode).
24460b57cec5SDimitry Andric   unsigned NumComps;
24470b57cec5SDimitry Andric   // Number of sub-expressions (i.e. array subscript expressions).
24480b57cec5SDimitry Andric   unsigned NumExprs;
24490b57cec5SDimitry Andric 
numTrailingObjects(OverloadToken<OffsetOfNode>)24500b57cec5SDimitry Andric   size_t numTrailingObjects(OverloadToken<OffsetOfNode>) const {
24510b57cec5SDimitry Andric     return NumComps;
24520b57cec5SDimitry Andric   }
24530b57cec5SDimitry Andric 
24540b57cec5SDimitry Andric   OffsetOfExpr(const ASTContext &C, QualType type,
24550b57cec5SDimitry Andric                SourceLocation OperatorLoc, TypeSourceInfo *tsi,
24560b57cec5SDimitry Andric                ArrayRef<OffsetOfNode> comps, ArrayRef<Expr*> exprs,
24570b57cec5SDimitry Andric                SourceLocation RParenLoc);
24580b57cec5SDimitry Andric 
OffsetOfExpr(unsigned numComps,unsigned numExprs)24590b57cec5SDimitry Andric   explicit OffsetOfExpr(unsigned numComps, unsigned numExprs)
24600b57cec5SDimitry Andric     : Expr(OffsetOfExprClass, EmptyShell()),
24610b57cec5SDimitry Andric       TSInfo(nullptr), NumComps(numComps), NumExprs(numExprs) {}
24620b57cec5SDimitry Andric 
24630b57cec5SDimitry Andric public:
24640b57cec5SDimitry Andric 
24650b57cec5SDimitry Andric   static OffsetOfExpr *Create(const ASTContext &C, QualType type,
24660b57cec5SDimitry Andric                               SourceLocation OperatorLoc, TypeSourceInfo *tsi,
24670b57cec5SDimitry Andric                               ArrayRef<OffsetOfNode> comps,
24680b57cec5SDimitry Andric                               ArrayRef<Expr*> exprs, SourceLocation RParenLoc);
24690b57cec5SDimitry Andric 
24700b57cec5SDimitry Andric   static OffsetOfExpr *CreateEmpty(const ASTContext &C,
24710b57cec5SDimitry Andric                                    unsigned NumComps, unsigned NumExprs);
24720b57cec5SDimitry Andric 
24730b57cec5SDimitry Andric   /// getOperatorLoc - Return the location of the operator.
getOperatorLoc()24740b57cec5SDimitry Andric   SourceLocation getOperatorLoc() const { return OperatorLoc; }
setOperatorLoc(SourceLocation L)24750b57cec5SDimitry Andric   void setOperatorLoc(SourceLocation L) { OperatorLoc = L; }
24760b57cec5SDimitry Andric 
24770b57cec5SDimitry Andric   /// Return the location of the right parentheses.
getRParenLoc()24780b57cec5SDimitry Andric   SourceLocation getRParenLoc() const { return RParenLoc; }
setRParenLoc(SourceLocation R)24790b57cec5SDimitry Andric   void setRParenLoc(SourceLocation R) { RParenLoc = R; }
24800b57cec5SDimitry Andric 
getTypeSourceInfo()24810b57cec5SDimitry Andric   TypeSourceInfo *getTypeSourceInfo() const {
24820b57cec5SDimitry Andric     return TSInfo;
24830b57cec5SDimitry Andric   }
setTypeSourceInfo(TypeSourceInfo * tsi)24840b57cec5SDimitry Andric   void setTypeSourceInfo(TypeSourceInfo *tsi) {
24850b57cec5SDimitry Andric     TSInfo = tsi;
24860b57cec5SDimitry Andric   }
24870b57cec5SDimitry Andric 
getComponent(unsigned Idx)24880b57cec5SDimitry Andric   const OffsetOfNode &getComponent(unsigned Idx) const {
24890b57cec5SDimitry Andric     assert(Idx < NumComps && "Subscript out of range");
24900b57cec5SDimitry Andric     return getTrailingObjects<OffsetOfNode>()[Idx];
24910b57cec5SDimitry Andric   }
24920b57cec5SDimitry Andric 
setComponent(unsigned Idx,OffsetOfNode ON)24930b57cec5SDimitry Andric   void setComponent(unsigned Idx, OffsetOfNode ON) {
24940b57cec5SDimitry Andric     assert(Idx < NumComps && "Subscript out of range");
24950b57cec5SDimitry Andric     getTrailingObjects<OffsetOfNode>()[Idx] = ON;
24960b57cec5SDimitry Andric   }
24970b57cec5SDimitry Andric 
getNumComponents()24980b57cec5SDimitry Andric   unsigned getNumComponents() const {
24990b57cec5SDimitry Andric     return NumComps;
25000b57cec5SDimitry Andric   }
25010b57cec5SDimitry Andric 
getIndexExpr(unsigned Idx)25020b57cec5SDimitry Andric   Expr* getIndexExpr(unsigned Idx) {
25030b57cec5SDimitry Andric     assert(Idx < NumExprs && "Subscript out of range");
25040b57cec5SDimitry Andric     return getTrailingObjects<Expr *>()[Idx];
25050b57cec5SDimitry Andric   }
25060b57cec5SDimitry Andric 
getIndexExpr(unsigned Idx)25070b57cec5SDimitry Andric   const Expr *getIndexExpr(unsigned Idx) const {
25080b57cec5SDimitry Andric     assert(Idx < NumExprs && "Subscript out of range");
25090b57cec5SDimitry Andric     return getTrailingObjects<Expr *>()[Idx];
25100b57cec5SDimitry Andric   }
25110b57cec5SDimitry Andric 
setIndexExpr(unsigned Idx,Expr * E)25120b57cec5SDimitry Andric   void setIndexExpr(unsigned Idx, Expr* E) {
25130b57cec5SDimitry Andric     assert(Idx < NumComps && "Subscript out of range");
25140b57cec5SDimitry Andric     getTrailingObjects<Expr *>()[Idx] = E;
25150b57cec5SDimitry Andric   }
25160b57cec5SDimitry Andric 
getNumExpressions()25170b57cec5SDimitry Andric   unsigned getNumExpressions() const {
25180b57cec5SDimitry Andric     return NumExprs;
25190b57cec5SDimitry Andric   }
25200b57cec5SDimitry Andric 
getBeginLoc()25210b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY { return OperatorLoc; }
getEndLoc()25220b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
25230b57cec5SDimitry Andric 
classof(const Stmt * T)25240b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
25250b57cec5SDimitry Andric     return T->getStmtClass() == OffsetOfExprClass;
25260b57cec5SDimitry Andric   }
25270b57cec5SDimitry Andric 
25280b57cec5SDimitry Andric   // Iterators
children()25290b57cec5SDimitry Andric   child_range children() {
25300b57cec5SDimitry Andric     Stmt **begin = reinterpret_cast<Stmt **>(getTrailingObjects<Expr *>());
25310b57cec5SDimitry Andric     return child_range(begin, begin + NumExprs);
25320b57cec5SDimitry Andric   }
children()25330b57cec5SDimitry Andric   const_child_range children() const {
25340b57cec5SDimitry Andric     Stmt *const *begin =
25350b57cec5SDimitry Andric         reinterpret_cast<Stmt *const *>(getTrailingObjects<Expr *>());
25360b57cec5SDimitry Andric     return const_child_range(begin, begin + NumExprs);
25370b57cec5SDimitry Andric   }
25380b57cec5SDimitry Andric   friend TrailingObjects;
25390b57cec5SDimitry Andric };
25400b57cec5SDimitry Andric 
25410b57cec5SDimitry Andric /// UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated)
25420b57cec5SDimitry Andric /// expression operand.  Used for sizeof/alignof (C99 6.5.3.4) and
25430b57cec5SDimitry Andric /// vec_step (OpenCL 1.1 6.11.12).
25440b57cec5SDimitry Andric class UnaryExprOrTypeTraitExpr : public Expr {
25450b57cec5SDimitry Andric   union {
25460b57cec5SDimitry Andric     TypeSourceInfo *Ty;
25470b57cec5SDimitry Andric     Stmt *Ex;
25480b57cec5SDimitry Andric   } Argument;
25490b57cec5SDimitry Andric   SourceLocation OpLoc, RParenLoc;
25500b57cec5SDimitry Andric 
25510b57cec5SDimitry Andric public:
UnaryExprOrTypeTraitExpr(UnaryExprOrTypeTrait ExprKind,TypeSourceInfo * TInfo,QualType resultType,SourceLocation op,SourceLocation rp)25520b57cec5SDimitry Andric   UnaryExprOrTypeTraitExpr(UnaryExprOrTypeTrait ExprKind, TypeSourceInfo *TInfo,
25530b57cec5SDimitry Andric                            QualType resultType, SourceLocation op,
25545ffd83dbSDimitry Andric                            SourceLocation rp)
2555fe6060f1SDimitry Andric       : Expr(UnaryExprOrTypeTraitExprClass, resultType, VK_PRValue,
2556fe6060f1SDimitry Andric              OK_Ordinary),
25570b57cec5SDimitry Andric         OpLoc(op), RParenLoc(rp) {
25585ffd83dbSDimitry Andric     assert(ExprKind <= UETT_Last && "invalid enum value!");
25590b57cec5SDimitry Andric     UnaryExprOrTypeTraitExprBits.Kind = ExprKind;
25605ffd83dbSDimitry Andric     assert(static_cast<unsigned>(ExprKind) ==
25615ffd83dbSDimitry Andric                UnaryExprOrTypeTraitExprBits.Kind &&
25625ffd83dbSDimitry Andric            "UnaryExprOrTypeTraitExprBits.Kind overflow!");
25630b57cec5SDimitry Andric     UnaryExprOrTypeTraitExprBits.IsType = true;
25640b57cec5SDimitry Andric     Argument.Ty = TInfo;
25655ffd83dbSDimitry Andric     setDependence(computeDependence(this));
25660b57cec5SDimitry Andric   }
25670b57cec5SDimitry Andric 
25680b57cec5SDimitry Andric   UnaryExprOrTypeTraitExpr(UnaryExprOrTypeTrait ExprKind, Expr *E,
25690b57cec5SDimitry Andric                            QualType resultType, SourceLocation op,
25700b57cec5SDimitry Andric                            SourceLocation rp);
25710b57cec5SDimitry Andric 
25720b57cec5SDimitry Andric   /// Construct an empty sizeof/alignof expression.
UnaryExprOrTypeTraitExpr(EmptyShell Empty)25730b57cec5SDimitry Andric   explicit UnaryExprOrTypeTraitExpr(EmptyShell Empty)
25740b57cec5SDimitry Andric     : Expr(UnaryExprOrTypeTraitExprClass, Empty) { }
25750b57cec5SDimitry Andric 
getKind()25760b57cec5SDimitry Andric   UnaryExprOrTypeTrait getKind() const {
25770b57cec5SDimitry Andric     return static_cast<UnaryExprOrTypeTrait>(UnaryExprOrTypeTraitExprBits.Kind);
25780b57cec5SDimitry Andric   }
setKind(UnaryExprOrTypeTrait K)25795ffd83dbSDimitry Andric   void setKind(UnaryExprOrTypeTrait K) {
25805ffd83dbSDimitry Andric     assert(K <= UETT_Last && "invalid enum value!");
25815ffd83dbSDimitry Andric     UnaryExprOrTypeTraitExprBits.Kind = K;
25825ffd83dbSDimitry Andric     assert(static_cast<unsigned>(K) == UnaryExprOrTypeTraitExprBits.Kind &&
25835ffd83dbSDimitry Andric            "UnaryExprOrTypeTraitExprBits.Kind overflow!");
25845ffd83dbSDimitry Andric   }
25850b57cec5SDimitry Andric 
isArgumentType()25860b57cec5SDimitry Andric   bool isArgumentType() const { return UnaryExprOrTypeTraitExprBits.IsType; }
getArgumentType()25870b57cec5SDimitry Andric   QualType getArgumentType() const {
25880b57cec5SDimitry Andric     return getArgumentTypeInfo()->getType();
25890b57cec5SDimitry Andric   }
getArgumentTypeInfo()25900b57cec5SDimitry Andric   TypeSourceInfo *getArgumentTypeInfo() const {
25910b57cec5SDimitry Andric     assert(isArgumentType() && "calling getArgumentType() when arg is expr");
25920b57cec5SDimitry Andric     return Argument.Ty;
25930b57cec5SDimitry Andric   }
getArgumentExpr()25940b57cec5SDimitry Andric   Expr *getArgumentExpr() {
25950b57cec5SDimitry Andric     assert(!isArgumentType() && "calling getArgumentExpr() when arg is type");
25960b57cec5SDimitry Andric     return static_cast<Expr*>(Argument.Ex);
25970b57cec5SDimitry Andric   }
getArgumentExpr()25980b57cec5SDimitry Andric   const Expr *getArgumentExpr() const {
25990b57cec5SDimitry Andric     return const_cast<UnaryExprOrTypeTraitExpr*>(this)->getArgumentExpr();
26000b57cec5SDimitry Andric   }
26010b57cec5SDimitry Andric 
setArgument(Expr * E)26020b57cec5SDimitry Andric   void setArgument(Expr *E) {
26030b57cec5SDimitry Andric     Argument.Ex = E;
26040b57cec5SDimitry Andric     UnaryExprOrTypeTraitExprBits.IsType = false;
26050b57cec5SDimitry Andric   }
setArgument(TypeSourceInfo * TInfo)26060b57cec5SDimitry Andric   void setArgument(TypeSourceInfo *TInfo) {
26070b57cec5SDimitry Andric     Argument.Ty = TInfo;
26080b57cec5SDimitry Andric     UnaryExprOrTypeTraitExprBits.IsType = true;
26090b57cec5SDimitry Andric   }
26100b57cec5SDimitry Andric 
26110b57cec5SDimitry Andric   /// Gets the argument type, or the type of the argument expression, whichever
26120b57cec5SDimitry Andric   /// is appropriate.
getTypeOfArgument()26130b57cec5SDimitry Andric   QualType getTypeOfArgument() const {
26140b57cec5SDimitry Andric     return isArgumentType() ? getArgumentType() : getArgumentExpr()->getType();
26150b57cec5SDimitry Andric   }
26160b57cec5SDimitry Andric 
getOperatorLoc()26170b57cec5SDimitry Andric   SourceLocation getOperatorLoc() const { return OpLoc; }
setOperatorLoc(SourceLocation L)26180b57cec5SDimitry Andric   void setOperatorLoc(SourceLocation L) { OpLoc = L; }
26190b57cec5SDimitry Andric 
getRParenLoc()26200b57cec5SDimitry Andric   SourceLocation getRParenLoc() const { return RParenLoc; }
setRParenLoc(SourceLocation L)26210b57cec5SDimitry Andric   void setRParenLoc(SourceLocation L) { RParenLoc = L; }
26220b57cec5SDimitry Andric 
getBeginLoc()26230b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY { return OpLoc; }
getEndLoc()26240b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
26250b57cec5SDimitry Andric 
classof(const Stmt * T)26260b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
26270b57cec5SDimitry Andric     return T->getStmtClass() == UnaryExprOrTypeTraitExprClass;
26280b57cec5SDimitry Andric   }
26290b57cec5SDimitry Andric 
26300b57cec5SDimitry Andric   // Iterators
26310b57cec5SDimitry Andric   child_range children();
26320b57cec5SDimitry Andric   const_child_range children() const;
26330b57cec5SDimitry Andric };
26340b57cec5SDimitry Andric 
26350b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
26360b57cec5SDimitry Andric // Postfix Operators.
26370b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
26380b57cec5SDimitry Andric 
26390b57cec5SDimitry Andric /// ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
26400b57cec5SDimitry Andric class ArraySubscriptExpr : public Expr {
26410b57cec5SDimitry Andric   enum { LHS, RHS, END_EXPR };
26420b57cec5SDimitry Andric   Stmt *SubExprs[END_EXPR];
26430b57cec5SDimitry Andric 
lhsIsBase()26440b57cec5SDimitry Andric   bool lhsIsBase() const { return getRHS()->getType()->isIntegerType(); }
26450b57cec5SDimitry Andric 
26460b57cec5SDimitry Andric public:
ArraySubscriptExpr(Expr * lhs,Expr * rhs,QualType t,ExprValueKind VK,ExprObjectKind OK,SourceLocation rbracketloc)26475ffd83dbSDimitry Andric   ArraySubscriptExpr(Expr *lhs, Expr *rhs, QualType t, ExprValueKind VK,
26485ffd83dbSDimitry Andric                      ExprObjectKind OK, SourceLocation rbracketloc)
26495ffd83dbSDimitry Andric       : Expr(ArraySubscriptExprClass, t, VK, OK) {
26500b57cec5SDimitry Andric     SubExprs[LHS] = lhs;
26510b57cec5SDimitry Andric     SubExprs[RHS] = rhs;
26525ffd83dbSDimitry Andric     ArrayOrMatrixSubscriptExprBits.RBracketLoc = rbracketloc;
26535ffd83dbSDimitry Andric     setDependence(computeDependence(this));
26540b57cec5SDimitry Andric   }
26550b57cec5SDimitry Andric 
26560b57cec5SDimitry Andric   /// Create an empty array subscript expression.
ArraySubscriptExpr(EmptyShell Shell)26570b57cec5SDimitry Andric   explicit ArraySubscriptExpr(EmptyShell Shell)
26580b57cec5SDimitry Andric     : Expr(ArraySubscriptExprClass, Shell) { }
26590b57cec5SDimitry Andric 
26600b57cec5SDimitry Andric   /// An array access can be written A[4] or 4[A] (both are equivalent).
26610b57cec5SDimitry Andric   /// - getBase() and getIdx() always present the normalized view: A[4].
26620b57cec5SDimitry Andric   ///    In this case getBase() returns "A" and getIdx() returns "4".
26630b57cec5SDimitry Andric   /// - getLHS() and getRHS() present the syntactic view. e.g. for
26640b57cec5SDimitry Andric   ///    4[A] getLHS() returns "4".
26650b57cec5SDimitry Andric   /// Note: Because vector element access is also written A[4] we must
26660b57cec5SDimitry Andric   /// predicate the format conversion in getBase and getIdx only on the
26670b57cec5SDimitry Andric   /// the type of the RHS, as it is possible for the LHS to be a vector of
26680b57cec5SDimitry Andric   /// integer type
getLHS()26690b57cec5SDimitry Andric   Expr *getLHS() { return cast<Expr>(SubExprs[LHS]); }
getLHS()26700b57cec5SDimitry Andric   const Expr *getLHS() const { return cast<Expr>(SubExprs[LHS]); }
setLHS(Expr * E)26710b57cec5SDimitry Andric   void setLHS(Expr *E) { SubExprs[LHS] = E; }
26720b57cec5SDimitry Andric 
getRHS()26730b57cec5SDimitry Andric   Expr *getRHS() { return cast<Expr>(SubExprs[RHS]); }
getRHS()26740b57cec5SDimitry Andric   const Expr *getRHS() const { return cast<Expr>(SubExprs[RHS]); }
setRHS(Expr * E)26750b57cec5SDimitry Andric   void setRHS(Expr *E) { SubExprs[RHS] = E; }
26760b57cec5SDimitry Andric 
getBase()26770b57cec5SDimitry Andric   Expr *getBase() { return lhsIsBase() ? getLHS() : getRHS(); }
getBase()26780b57cec5SDimitry Andric   const Expr *getBase() const { return lhsIsBase() ? getLHS() : getRHS(); }
26790b57cec5SDimitry Andric 
getIdx()26800b57cec5SDimitry Andric   Expr *getIdx() { return lhsIsBase() ? getRHS() : getLHS(); }
getIdx()26810b57cec5SDimitry Andric   const Expr *getIdx() const { return lhsIsBase() ? getRHS() : getLHS(); }
26820b57cec5SDimitry Andric 
getBeginLoc()26830b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY {
26840b57cec5SDimitry Andric     return getLHS()->getBeginLoc();
26850b57cec5SDimitry Andric   }
getEndLoc()26860b57cec5SDimitry Andric   SourceLocation getEndLoc() const { return getRBracketLoc(); }
26870b57cec5SDimitry Andric 
getRBracketLoc()26880b57cec5SDimitry Andric   SourceLocation getRBracketLoc() const {
26895ffd83dbSDimitry Andric     return ArrayOrMatrixSubscriptExprBits.RBracketLoc;
26900b57cec5SDimitry Andric   }
setRBracketLoc(SourceLocation L)26910b57cec5SDimitry Andric   void setRBracketLoc(SourceLocation L) {
26925ffd83dbSDimitry Andric     ArrayOrMatrixSubscriptExprBits.RBracketLoc = L;
26930b57cec5SDimitry Andric   }
26940b57cec5SDimitry Andric 
getExprLoc()26950b57cec5SDimitry Andric   SourceLocation getExprLoc() const LLVM_READONLY {
26960b57cec5SDimitry Andric     return getBase()->getExprLoc();
26970b57cec5SDimitry Andric   }
26980b57cec5SDimitry Andric 
classof(const Stmt * T)26990b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
27000b57cec5SDimitry Andric     return T->getStmtClass() == ArraySubscriptExprClass;
27010b57cec5SDimitry Andric   }
27020b57cec5SDimitry Andric 
27030b57cec5SDimitry Andric   // Iterators
children()27040b57cec5SDimitry Andric   child_range children() {
27050b57cec5SDimitry Andric     return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
27060b57cec5SDimitry Andric   }
children()27070b57cec5SDimitry Andric   const_child_range children() const {
27080b57cec5SDimitry Andric     return const_child_range(&SubExprs[0], &SubExprs[0] + END_EXPR);
27090b57cec5SDimitry Andric   }
27100b57cec5SDimitry Andric };
27110b57cec5SDimitry Andric 
27125ffd83dbSDimitry Andric /// MatrixSubscriptExpr - Matrix subscript expression for the MatrixType
27135ffd83dbSDimitry Andric /// extension.
27145ffd83dbSDimitry Andric /// MatrixSubscriptExpr can be either incomplete (only Base and RowIdx are set
27155ffd83dbSDimitry Andric /// so far, the type is IncompleteMatrixIdx) or complete (Base, RowIdx and
27165ffd83dbSDimitry Andric /// ColumnIdx refer to valid expressions). Incomplete matrix expressions only
27175ffd83dbSDimitry Andric /// exist during the initial construction of the AST.
27185ffd83dbSDimitry Andric class MatrixSubscriptExpr : public Expr {
27195ffd83dbSDimitry Andric   enum { BASE, ROW_IDX, COLUMN_IDX, END_EXPR };
27205ffd83dbSDimitry Andric   Stmt *SubExprs[END_EXPR];
27215ffd83dbSDimitry Andric 
27225ffd83dbSDimitry Andric public:
MatrixSubscriptExpr(Expr * Base,Expr * RowIdx,Expr * ColumnIdx,QualType T,SourceLocation RBracketLoc)27235ffd83dbSDimitry Andric   MatrixSubscriptExpr(Expr *Base, Expr *RowIdx, Expr *ColumnIdx, QualType T,
27245ffd83dbSDimitry Andric                       SourceLocation RBracketLoc)
27255ffd83dbSDimitry Andric       : Expr(MatrixSubscriptExprClass, T, Base->getValueKind(),
27265ffd83dbSDimitry Andric              OK_MatrixComponent) {
27275ffd83dbSDimitry Andric     SubExprs[BASE] = Base;
27285ffd83dbSDimitry Andric     SubExprs[ROW_IDX] = RowIdx;
27295ffd83dbSDimitry Andric     SubExprs[COLUMN_IDX] = ColumnIdx;
27305ffd83dbSDimitry Andric     ArrayOrMatrixSubscriptExprBits.RBracketLoc = RBracketLoc;
27315ffd83dbSDimitry Andric     setDependence(computeDependence(this));
27325ffd83dbSDimitry Andric   }
27335ffd83dbSDimitry Andric 
27345ffd83dbSDimitry Andric   /// Create an empty matrix subscript expression.
MatrixSubscriptExpr(EmptyShell Shell)27355ffd83dbSDimitry Andric   explicit MatrixSubscriptExpr(EmptyShell Shell)
27365ffd83dbSDimitry Andric       : Expr(MatrixSubscriptExprClass, Shell) {}
27375ffd83dbSDimitry Andric 
isIncomplete()27385ffd83dbSDimitry Andric   bool isIncomplete() const {
27395ffd83dbSDimitry Andric     bool IsIncomplete = hasPlaceholderType(BuiltinType::IncompleteMatrixIdx);
27405ffd83dbSDimitry Andric     assert((SubExprs[COLUMN_IDX] || IsIncomplete) &&
27415ffd83dbSDimitry Andric            "expressions without column index must be marked as incomplete");
27425ffd83dbSDimitry Andric     return IsIncomplete;
27435ffd83dbSDimitry Andric   }
getBase()27445ffd83dbSDimitry Andric   Expr *getBase() { return cast<Expr>(SubExprs[BASE]); }
getBase()27455ffd83dbSDimitry Andric   const Expr *getBase() const { return cast<Expr>(SubExprs[BASE]); }
setBase(Expr * E)27465ffd83dbSDimitry Andric   void setBase(Expr *E) { SubExprs[BASE] = E; }
27475ffd83dbSDimitry Andric 
getRowIdx()27485ffd83dbSDimitry Andric   Expr *getRowIdx() { return cast<Expr>(SubExprs[ROW_IDX]); }
getRowIdx()27495ffd83dbSDimitry Andric   const Expr *getRowIdx() const { return cast<Expr>(SubExprs[ROW_IDX]); }
setRowIdx(Expr * E)27505ffd83dbSDimitry Andric   void setRowIdx(Expr *E) { SubExprs[ROW_IDX] = E; }
27515ffd83dbSDimitry Andric 
getColumnIdx()27525ffd83dbSDimitry Andric   Expr *getColumnIdx() { return cast_or_null<Expr>(SubExprs[COLUMN_IDX]); }
getColumnIdx()27535ffd83dbSDimitry Andric   const Expr *getColumnIdx() const {
27545ffd83dbSDimitry Andric     assert(!isIncomplete() &&
27555ffd83dbSDimitry Andric            "cannot get the column index of an incomplete expression");
27565ffd83dbSDimitry Andric     return cast<Expr>(SubExprs[COLUMN_IDX]);
27575ffd83dbSDimitry Andric   }
setColumnIdx(Expr * E)27585ffd83dbSDimitry Andric   void setColumnIdx(Expr *E) { SubExprs[COLUMN_IDX] = E; }
27595ffd83dbSDimitry Andric 
getBeginLoc()27605ffd83dbSDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY {
27615ffd83dbSDimitry Andric     return getBase()->getBeginLoc();
27625ffd83dbSDimitry Andric   }
27635ffd83dbSDimitry Andric 
getEndLoc()27645ffd83dbSDimitry Andric   SourceLocation getEndLoc() const { return getRBracketLoc(); }
27655ffd83dbSDimitry Andric 
getExprLoc()27665ffd83dbSDimitry Andric   SourceLocation getExprLoc() const LLVM_READONLY {
27675ffd83dbSDimitry Andric     return getBase()->getExprLoc();
27685ffd83dbSDimitry Andric   }
27695ffd83dbSDimitry Andric 
getRBracketLoc()27705ffd83dbSDimitry Andric   SourceLocation getRBracketLoc() const {
27715ffd83dbSDimitry Andric     return ArrayOrMatrixSubscriptExprBits.RBracketLoc;
27725ffd83dbSDimitry Andric   }
setRBracketLoc(SourceLocation L)27735ffd83dbSDimitry Andric   void setRBracketLoc(SourceLocation L) {
27745ffd83dbSDimitry Andric     ArrayOrMatrixSubscriptExprBits.RBracketLoc = L;
27755ffd83dbSDimitry Andric   }
27765ffd83dbSDimitry Andric 
classof(const Stmt * T)27775ffd83dbSDimitry Andric   static bool classof(const Stmt *T) {
27785ffd83dbSDimitry Andric     return T->getStmtClass() == MatrixSubscriptExprClass;
27795ffd83dbSDimitry Andric   }
27805ffd83dbSDimitry Andric 
27815ffd83dbSDimitry Andric   // Iterators
children()27825ffd83dbSDimitry Andric   child_range children() {
27835ffd83dbSDimitry Andric     return child_range(&SubExprs[0], &SubExprs[0] + END_EXPR);
27845ffd83dbSDimitry Andric   }
children()27855ffd83dbSDimitry Andric   const_child_range children() const {
27865ffd83dbSDimitry Andric     return const_child_range(&SubExprs[0], &SubExprs[0] + END_EXPR);
27875ffd83dbSDimitry Andric   }
27885ffd83dbSDimitry Andric };
27895ffd83dbSDimitry Andric 
27900b57cec5SDimitry Andric /// CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
27910b57cec5SDimitry Andric /// CallExpr itself represents a normal function call, e.g., "f(x, 2)",
27920b57cec5SDimitry Andric /// while its subclasses may represent alternative syntax that (semantically)
27930b57cec5SDimitry Andric /// results in a function call. For example, CXXOperatorCallExpr is
27940b57cec5SDimitry Andric /// a subclass for overloaded operator calls that use operator syntax, e.g.,
27950b57cec5SDimitry Andric /// "str1 + str2" to resolve to a function call.
27960b57cec5SDimitry Andric class CallExpr : public Expr {
27970b57cec5SDimitry Andric   enum { FN = 0, PREARGS_START = 1 };
27980b57cec5SDimitry Andric 
27990b57cec5SDimitry Andric   /// The number of arguments in the call expression.
28000b57cec5SDimitry Andric   unsigned NumArgs;
28010b57cec5SDimitry Andric 
280206c3fb27SDimitry Andric   /// The location of the right parentheses. This has a different meaning for
28030b57cec5SDimitry Andric   /// the derived classes of CallExpr.
28040b57cec5SDimitry Andric   SourceLocation RParenLoc;
28050b57cec5SDimitry Andric 
28060b57cec5SDimitry Andric   // CallExpr store some data in trailing objects. However since CallExpr
28070b57cec5SDimitry Andric   // is used a base of other expression classes we cannot use
28080b57cec5SDimitry Andric   // llvm::TrailingObjects. Instead we manually perform the pointer arithmetic
28090b57cec5SDimitry Andric   // and casts.
28100b57cec5SDimitry Andric   //
28110b57cec5SDimitry Andric   // The trailing objects are in order:
28120b57cec5SDimitry Andric   //
28130b57cec5SDimitry Andric   // * A single "Stmt *" for the callee expression.
28140b57cec5SDimitry Andric   //
28150b57cec5SDimitry Andric   // * An array of getNumPreArgs() "Stmt *" for the pre-argument expressions.
28160b57cec5SDimitry Andric   //
28170b57cec5SDimitry Andric   // * An array of getNumArgs() "Stmt *" for the argument expressions.
28180b57cec5SDimitry Andric   //
2819e8d8bef9SDimitry Andric   // * An optional of type FPOptionsOverride.
2820e8d8bef9SDimitry Andric   //
28210b57cec5SDimitry Andric   // Note that we store the offset in bytes from the this pointer to the start
28220b57cec5SDimitry Andric   // of the trailing objects. It would be perfectly possible to compute it
28230b57cec5SDimitry Andric   // based on the dynamic kind of the CallExpr. However 1.) we have plenty of
28240b57cec5SDimitry Andric   // space in the bit-fields of Stmt. 2.) It was benchmarked to be faster to
28250b57cec5SDimitry Andric   // compute this once and then load the offset from the bit-fields of Stmt,
28260b57cec5SDimitry Andric   // instead of re-computing the offset each time the trailing objects are
28270b57cec5SDimitry Andric   // accessed.
28280b57cec5SDimitry Andric 
28290b57cec5SDimitry Andric   /// Return a pointer to the start of the trailing array of "Stmt *".
getTrailingStmts()28300b57cec5SDimitry Andric   Stmt **getTrailingStmts() {
28310b57cec5SDimitry Andric     return reinterpret_cast<Stmt **>(reinterpret_cast<char *>(this) +
28320b57cec5SDimitry Andric                                      CallExprBits.OffsetToTrailingObjects);
28330b57cec5SDimitry Andric   }
getTrailingStmts()28340b57cec5SDimitry Andric   Stmt *const *getTrailingStmts() const {
28350b57cec5SDimitry Andric     return const_cast<CallExpr *>(this)->getTrailingStmts();
28360b57cec5SDimitry Andric   }
28370b57cec5SDimitry Andric 
28380b57cec5SDimitry Andric   /// Map a statement class to the appropriate offset in bytes from the
28390b57cec5SDimitry Andric   /// this pointer to the trailing objects.
28400b57cec5SDimitry Andric   static unsigned offsetToTrailingObjects(StmtClass SC);
28410b57cec5SDimitry Andric 
getSizeOfTrailingStmts()2842e8d8bef9SDimitry Andric   unsigned getSizeOfTrailingStmts() const {
2843e8d8bef9SDimitry Andric     return (1 + getNumPreArgs() + getNumArgs()) * sizeof(Stmt *);
2844e8d8bef9SDimitry Andric   }
2845e8d8bef9SDimitry Andric 
getOffsetOfTrailingFPFeatures()2846e8d8bef9SDimitry Andric   size_t getOffsetOfTrailingFPFeatures() const {
2847e8d8bef9SDimitry Andric     assert(hasStoredFPFeatures());
2848e8d8bef9SDimitry Andric     return CallExprBits.OffsetToTrailingObjects + getSizeOfTrailingStmts();
2849e8d8bef9SDimitry Andric   }
2850e8d8bef9SDimitry Andric 
28510b57cec5SDimitry Andric public:
28520b57cec5SDimitry Andric   enum class ADLCallKind : bool { NotADL, UsesADL };
28530b57cec5SDimitry Andric   static constexpr ADLCallKind NotADL = ADLCallKind::NotADL;
28540b57cec5SDimitry Andric   static constexpr ADLCallKind UsesADL = ADLCallKind::UsesADL;
28550b57cec5SDimitry Andric 
28560b57cec5SDimitry Andric protected:
28570b57cec5SDimitry Andric   /// Build a call expression, assuming that appropriate storage has been
28580b57cec5SDimitry Andric   /// allocated for the trailing objects.
28590b57cec5SDimitry Andric   CallExpr(StmtClass SC, Expr *Fn, ArrayRef<Expr *> PreArgs,
28600b57cec5SDimitry Andric            ArrayRef<Expr *> Args, QualType Ty, ExprValueKind VK,
2861e8d8bef9SDimitry Andric            SourceLocation RParenLoc, FPOptionsOverride FPFeatures,
2862e8d8bef9SDimitry Andric            unsigned MinNumArgs, ADLCallKind UsesADL);
28630b57cec5SDimitry Andric 
28640b57cec5SDimitry Andric   /// Build an empty call expression, for deserialization.
28650b57cec5SDimitry Andric   CallExpr(StmtClass SC, unsigned NumPreArgs, unsigned NumArgs,
2866e8d8bef9SDimitry Andric            bool hasFPFeatures, EmptyShell Empty);
28670b57cec5SDimitry Andric 
28680b57cec5SDimitry Andric   /// Return the size in bytes needed for the trailing objects.
28690b57cec5SDimitry Andric   /// Used by the derived classes to allocate the right amount of storage.
sizeOfTrailingObjects(unsigned NumPreArgs,unsigned NumArgs,bool HasFPFeatures)2870e8d8bef9SDimitry Andric   static unsigned sizeOfTrailingObjects(unsigned NumPreArgs, unsigned NumArgs,
2871e8d8bef9SDimitry Andric                                         bool HasFPFeatures) {
2872e8d8bef9SDimitry Andric     return (1 + NumPreArgs + NumArgs) * sizeof(Stmt *) +
2873e8d8bef9SDimitry Andric            HasFPFeatures * sizeof(FPOptionsOverride);
28740b57cec5SDimitry Andric   }
28750b57cec5SDimitry Andric 
getPreArg(unsigned I)28760b57cec5SDimitry Andric   Stmt *getPreArg(unsigned I) {
28770b57cec5SDimitry Andric     assert(I < getNumPreArgs() && "Prearg access out of range!");
28780b57cec5SDimitry Andric     return getTrailingStmts()[PREARGS_START + I];
28790b57cec5SDimitry Andric   }
getPreArg(unsigned I)28800b57cec5SDimitry Andric   const Stmt *getPreArg(unsigned I) const {
28810b57cec5SDimitry Andric     assert(I < getNumPreArgs() && "Prearg access out of range!");
28820b57cec5SDimitry Andric     return getTrailingStmts()[PREARGS_START + I];
28830b57cec5SDimitry Andric   }
setPreArg(unsigned I,Stmt * PreArg)28840b57cec5SDimitry Andric   void setPreArg(unsigned I, Stmt *PreArg) {
28850b57cec5SDimitry Andric     assert(I < getNumPreArgs() && "Prearg access out of range!");
28860b57cec5SDimitry Andric     getTrailingStmts()[PREARGS_START + I] = PreArg;
28870b57cec5SDimitry Andric   }
28880b57cec5SDimitry Andric 
getNumPreArgs()28890b57cec5SDimitry Andric   unsigned getNumPreArgs() const { return CallExprBits.NumPreArgs; }
28900b57cec5SDimitry Andric 
2891e8d8bef9SDimitry Andric   /// Return a pointer to the trailing FPOptions
getTrailingFPFeatures()2892e8d8bef9SDimitry Andric   FPOptionsOverride *getTrailingFPFeatures() {
2893e8d8bef9SDimitry Andric     assert(hasStoredFPFeatures());
2894e8d8bef9SDimitry Andric     return reinterpret_cast<FPOptionsOverride *>(
2895e8d8bef9SDimitry Andric         reinterpret_cast<char *>(this) + CallExprBits.OffsetToTrailingObjects +
2896e8d8bef9SDimitry Andric         getSizeOfTrailingStmts());
2897e8d8bef9SDimitry Andric   }
getTrailingFPFeatures()2898e8d8bef9SDimitry Andric   const FPOptionsOverride *getTrailingFPFeatures() const {
2899e8d8bef9SDimitry Andric     assert(hasStoredFPFeatures());
2900e8d8bef9SDimitry Andric     return reinterpret_cast<const FPOptionsOverride *>(
2901e8d8bef9SDimitry Andric         reinterpret_cast<const char *>(this) +
2902e8d8bef9SDimitry Andric         CallExprBits.OffsetToTrailingObjects + getSizeOfTrailingStmts());
2903e8d8bef9SDimitry Andric   }
2904e8d8bef9SDimitry Andric 
29050b57cec5SDimitry Andric public:
2906e8d8bef9SDimitry Andric   /// Create a call expression.
2907e8d8bef9SDimitry Andric   /// \param Fn     The callee expression,
2908e8d8bef9SDimitry Andric   /// \param Args   The argument array,
2909e8d8bef9SDimitry Andric   /// \param Ty     The type of the call expression (which is *not* the return
2910e8d8bef9SDimitry Andric   ///               type in general),
2911e8d8bef9SDimitry Andric   /// \param VK     The value kind of the call expression (lvalue, rvalue, ...),
2912e8d8bef9SDimitry Andric   /// \param RParenLoc  The location of the right parenthesis in the call
2913e8d8bef9SDimitry Andric   ///                   expression.
2914e8d8bef9SDimitry Andric   /// \param FPFeatures Floating-point features associated with the call,
2915e8d8bef9SDimitry Andric   /// \param MinNumArgs Specifies the minimum number of arguments. The actual
2916e8d8bef9SDimitry Andric   ///                   number of arguments will be the greater of Args.size()
2917e8d8bef9SDimitry Andric   ///                   and MinNumArgs. This is used in a few places to allocate
2918e8d8bef9SDimitry Andric   ///                   enough storage for the default arguments.
2919e8d8bef9SDimitry Andric   /// \param UsesADL    Specifies whether the callee was found through
2920e8d8bef9SDimitry Andric   ///                   argument-dependent lookup.
29210b57cec5SDimitry Andric   ///
29220b57cec5SDimitry Andric   /// Note that you can use CreateTemporary if you need a temporary call
29230b57cec5SDimitry Andric   /// expression on the stack.
29240b57cec5SDimitry Andric   static CallExpr *Create(const ASTContext &Ctx, Expr *Fn,
29250b57cec5SDimitry Andric                           ArrayRef<Expr *> Args, QualType Ty, ExprValueKind VK,
2926e8d8bef9SDimitry Andric                           SourceLocation RParenLoc,
2927e8d8bef9SDimitry Andric                           FPOptionsOverride FPFeatures, unsigned MinNumArgs = 0,
29280b57cec5SDimitry Andric                           ADLCallKind UsesADL = NotADL);
29290b57cec5SDimitry Andric 
29300b57cec5SDimitry Andric   /// Create a temporary call expression with no arguments in the memory
29310b57cec5SDimitry Andric   /// pointed to by Mem. Mem must points to at least sizeof(CallExpr)
29320b57cec5SDimitry Andric   /// + sizeof(Stmt *) bytes of storage, aligned to alignof(CallExpr):
29330b57cec5SDimitry Andric   ///
29340b57cec5SDimitry Andric   /// \code{.cpp}
2935a7dea167SDimitry Andric   ///   alignas(CallExpr) char Buffer[sizeof(CallExpr) + sizeof(Stmt *)];
2936a7dea167SDimitry Andric   ///   CallExpr *TheCall = CallExpr::CreateTemporary(Buffer, etc);
29370b57cec5SDimitry Andric   /// \endcode
29380b57cec5SDimitry Andric   static CallExpr *CreateTemporary(void *Mem, Expr *Fn, QualType Ty,
29390b57cec5SDimitry Andric                                    ExprValueKind VK, SourceLocation RParenLoc,
29400b57cec5SDimitry Andric                                    ADLCallKind UsesADL = NotADL);
29410b57cec5SDimitry Andric 
29420b57cec5SDimitry Andric   /// Create an empty call expression, for deserialization.
29430b57cec5SDimitry Andric   static CallExpr *CreateEmpty(const ASTContext &Ctx, unsigned NumArgs,
2944e8d8bef9SDimitry Andric                                bool HasFPFeatures, EmptyShell Empty);
29450b57cec5SDimitry Andric 
getCallee()29460b57cec5SDimitry Andric   Expr *getCallee() { return cast<Expr>(getTrailingStmts()[FN]); }
getCallee()29470b57cec5SDimitry Andric   const Expr *getCallee() const { return cast<Expr>(getTrailingStmts()[FN]); }
setCallee(Expr * F)29480b57cec5SDimitry Andric   void setCallee(Expr *F) { getTrailingStmts()[FN] = F; }
29490b57cec5SDimitry Andric 
getADLCallKind()29500b57cec5SDimitry Andric   ADLCallKind getADLCallKind() const {
29510b57cec5SDimitry Andric     return static_cast<ADLCallKind>(CallExprBits.UsesADL);
29520b57cec5SDimitry Andric   }
29530b57cec5SDimitry Andric   void setADLCallKind(ADLCallKind V = UsesADL) {
29540b57cec5SDimitry Andric     CallExprBits.UsesADL = static_cast<bool>(V);
29550b57cec5SDimitry Andric   }
usesADL()29560b57cec5SDimitry Andric   bool usesADL() const { return getADLCallKind() == UsesADL; }
29570b57cec5SDimitry Andric 
hasStoredFPFeatures()2958e8d8bef9SDimitry Andric   bool hasStoredFPFeatures() const { return CallExprBits.HasFPFeatures; }
2959e8d8bef9SDimitry Andric 
getCalleeDecl()29600b57cec5SDimitry Andric   Decl *getCalleeDecl() { return getCallee()->getReferencedDeclOfCallee(); }
getCalleeDecl()29610b57cec5SDimitry Andric   const Decl *getCalleeDecl() const {
29620b57cec5SDimitry Andric     return getCallee()->getReferencedDeclOfCallee();
29630b57cec5SDimitry Andric   }
29640b57cec5SDimitry Andric 
29650b57cec5SDimitry Andric   /// If the callee is a FunctionDecl, return it. Otherwise return null.
getDirectCallee()29660b57cec5SDimitry Andric   FunctionDecl *getDirectCallee() {
29670b57cec5SDimitry Andric     return dyn_cast_or_null<FunctionDecl>(getCalleeDecl());
29680b57cec5SDimitry Andric   }
getDirectCallee()29690b57cec5SDimitry Andric   const FunctionDecl *getDirectCallee() const {
29700b57cec5SDimitry Andric     return dyn_cast_or_null<FunctionDecl>(getCalleeDecl());
29710b57cec5SDimitry Andric   }
29720b57cec5SDimitry Andric 
29730b57cec5SDimitry Andric   /// getNumArgs - Return the number of actual arguments to this call.
getNumArgs()29740b57cec5SDimitry Andric   unsigned getNumArgs() const { return NumArgs; }
29750b57cec5SDimitry Andric 
29760b57cec5SDimitry Andric   /// Retrieve the call arguments.
getArgs()29770b57cec5SDimitry Andric   Expr **getArgs() {
29780b57cec5SDimitry Andric     return reinterpret_cast<Expr **>(getTrailingStmts() + PREARGS_START +
29790b57cec5SDimitry Andric                                      getNumPreArgs());
29800b57cec5SDimitry Andric   }
getArgs()29810b57cec5SDimitry Andric   const Expr *const *getArgs() const {
29820b57cec5SDimitry Andric     return reinterpret_cast<const Expr *const *>(
29830b57cec5SDimitry Andric         getTrailingStmts() + PREARGS_START + getNumPreArgs());
29840b57cec5SDimitry Andric   }
29850b57cec5SDimitry Andric 
29860b57cec5SDimitry Andric   /// getArg - Return the specified argument.
getArg(unsigned Arg)29870b57cec5SDimitry Andric   Expr *getArg(unsigned Arg) {
29880b57cec5SDimitry Andric     assert(Arg < getNumArgs() && "Arg access out of range!");
29890b57cec5SDimitry Andric     return getArgs()[Arg];
29900b57cec5SDimitry Andric   }
getArg(unsigned Arg)29910b57cec5SDimitry Andric   const Expr *getArg(unsigned Arg) const {
29920b57cec5SDimitry Andric     assert(Arg < getNumArgs() && "Arg access out of range!");
29930b57cec5SDimitry Andric     return getArgs()[Arg];
29940b57cec5SDimitry Andric   }
29950b57cec5SDimitry Andric 
29960b57cec5SDimitry Andric   /// setArg - Set the specified argument.
2997fe6060f1SDimitry Andric   /// ! the dependence bits might be stale after calling this setter, it is
2998fe6060f1SDimitry Andric   /// *caller*'s responsibility to recompute them by calling
2999fe6060f1SDimitry Andric   /// computeDependence().
setArg(unsigned Arg,Expr * ArgExpr)30000b57cec5SDimitry Andric   void setArg(unsigned Arg, Expr *ArgExpr) {
30010b57cec5SDimitry Andric     assert(Arg < getNumArgs() && "Arg access out of range!");
30020b57cec5SDimitry Andric     getArgs()[Arg] = ArgExpr;
30030b57cec5SDimitry Andric   }
30040b57cec5SDimitry Andric 
3005fe6060f1SDimitry Andric   /// Compute and set dependence bits.
computeDependence()3006fe6060f1SDimitry Andric   void computeDependence() {
3007fe6060f1SDimitry Andric     setDependence(clang::computeDependence(
3008bdd1243dSDimitry Andric         this, llvm::ArrayRef(
3009fe6060f1SDimitry Andric                   reinterpret_cast<Expr **>(getTrailingStmts() + PREARGS_START),
3010fe6060f1SDimitry Andric                   getNumPreArgs())));
3011fe6060f1SDimitry Andric   }
3012fe6060f1SDimitry Andric 
30130b57cec5SDimitry Andric   /// Reduce the number of arguments in this call expression. This is used for
30140b57cec5SDimitry Andric   /// example during error recovery to drop extra arguments. There is no way
30150b57cec5SDimitry Andric   /// to perform the opposite because: 1.) We don't track how much storage
30160b57cec5SDimitry Andric   /// we have for the argument array 2.) This would potentially require growing
30170b57cec5SDimitry Andric   /// the argument array, something we cannot support since the arguments are
30180b57cec5SDimitry Andric   /// stored in a trailing array.
shrinkNumArgs(unsigned NewNumArgs)30190b57cec5SDimitry Andric   void shrinkNumArgs(unsigned NewNumArgs) {
30200b57cec5SDimitry Andric     assert((NewNumArgs <= getNumArgs()) &&
30210b57cec5SDimitry Andric            "shrinkNumArgs cannot increase the number of arguments!");
30220b57cec5SDimitry Andric     NumArgs = NewNumArgs;
30230b57cec5SDimitry Andric   }
30240b57cec5SDimitry Andric 
30250b57cec5SDimitry Andric   /// Bluntly set a new number of arguments without doing any checks whatsoever.
30260b57cec5SDimitry Andric   /// Only used during construction of a CallExpr in a few places in Sema.
30270b57cec5SDimitry Andric   /// FIXME: Find a way to remove it.
setNumArgsUnsafe(unsigned NewNumArgs)30280b57cec5SDimitry Andric   void setNumArgsUnsafe(unsigned NewNumArgs) { NumArgs = NewNumArgs; }
30290b57cec5SDimitry Andric 
30300b57cec5SDimitry Andric   typedef ExprIterator arg_iterator;
30310b57cec5SDimitry Andric   typedef ConstExprIterator const_arg_iterator;
30320b57cec5SDimitry Andric   typedef llvm::iterator_range<arg_iterator> arg_range;
30330b57cec5SDimitry Andric   typedef llvm::iterator_range<const_arg_iterator> const_arg_range;
30340b57cec5SDimitry Andric 
arguments()30350b57cec5SDimitry Andric   arg_range arguments() { return arg_range(arg_begin(), arg_end()); }
arguments()30360b57cec5SDimitry Andric   const_arg_range arguments() const {
30370b57cec5SDimitry Andric     return const_arg_range(arg_begin(), arg_end());
30380b57cec5SDimitry Andric   }
30390b57cec5SDimitry Andric 
arg_begin()30400b57cec5SDimitry Andric   arg_iterator arg_begin() {
30410b57cec5SDimitry Andric     return getTrailingStmts() + PREARGS_START + getNumPreArgs();
30420b57cec5SDimitry Andric   }
arg_end()30430b57cec5SDimitry Andric   arg_iterator arg_end() { return arg_begin() + getNumArgs(); }
30440b57cec5SDimitry Andric 
arg_begin()30450b57cec5SDimitry Andric   const_arg_iterator arg_begin() const {
30460b57cec5SDimitry Andric     return getTrailingStmts() + PREARGS_START + getNumPreArgs();
30470b57cec5SDimitry Andric   }
arg_end()30480b57cec5SDimitry Andric   const_arg_iterator arg_end() const { return arg_begin() + getNumArgs(); }
30490b57cec5SDimitry Andric 
30500b57cec5SDimitry Andric   /// This method provides fast access to all the subexpressions of
30510b57cec5SDimitry Andric   /// a CallExpr without going through the slower virtual child_iterator
30520b57cec5SDimitry Andric   /// interface.  This provides efficient reverse iteration of the
30530b57cec5SDimitry Andric   /// subexpressions.  This is currently used for CFG construction.
getRawSubExprs()30540b57cec5SDimitry Andric   ArrayRef<Stmt *> getRawSubExprs() {
3055bdd1243dSDimitry Andric     return llvm::ArrayRef(getTrailingStmts(),
30560b57cec5SDimitry Andric                           PREARGS_START + getNumPreArgs() + getNumArgs());
30570b57cec5SDimitry Andric   }
30580b57cec5SDimitry Andric 
3059e8d8bef9SDimitry Andric   /// Get FPOptionsOverride from trailing storage.
getStoredFPFeatures()3060e8d8bef9SDimitry Andric   FPOptionsOverride getStoredFPFeatures() const {
3061e8d8bef9SDimitry Andric     assert(hasStoredFPFeatures());
3062e8d8bef9SDimitry Andric     return *getTrailingFPFeatures();
3063e8d8bef9SDimitry Andric   }
3064e8d8bef9SDimitry Andric   /// Set FPOptionsOverride in trailing storage. Used only by Serialization.
setStoredFPFeatures(FPOptionsOverride F)3065e8d8bef9SDimitry Andric   void setStoredFPFeatures(FPOptionsOverride F) {
3066e8d8bef9SDimitry Andric     assert(hasStoredFPFeatures());
3067e8d8bef9SDimitry Andric     *getTrailingFPFeatures() = F;
3068e8d8bef9SDimitry Andric   }
3069e8d8bef9SDimitry Andric 
307006c3fb27SDimitry Andric   /// Get the FP features status of this operator. Only meaningful for
307106c3fb27SDimitry Andric   /// operations on floating point types.
getFPFeaturesInEffect(const LangOptions & LO)3072e8d8bef9SDimitry Andric   FPOptions getFPFeaturesInEffect(const LangOptions &LO) const {
3073e8d8bef9SDimitry Andric     if (hasStoredFPFeatures())
3074e8d8bef9SDimitry Andric       return getStoredFPFeatures().applyOverrides(LO);
3075e8d8bef9SDimitry Andric     return FPOptions::defaultWithoutTrailingStorage(LO);
3076e8d8bef9SDimitry Andric   }
3077e8d8bef9SDimitry Andric 
getFPFeatures()3078e8d8bef9SDimitry Andric   FPOptionsOverride getFPFeatures() const {
3079e8d8bef9SDimitry Andric     if (hasStoredFPFeatures())
3080e8d8bef9SDimitry Andric       return getStoredFPFeatures();
3081e8d8bef9SDimitry Andric     return FPOptionsOverride();
3082e8d8bef9SDimitry Andric   }
3083e8d8bef9SDimitry Andric 
30840b57cec5SDimitry Andric   /// getBuiltinCallee - If this is a call to a builtin, return the builtin ID
30850b57cec5SDimitry Andric   /// of the callee. If not, return 0.
30860b57cec5SDimitry Andric   unsigned getBuiltinCallee() const;
30870b57cec5SDimitry Andric 
30880b57cec5SDimitry Andric   /// Returns \c true if this is a call to a builtin which does not
30890b57cec5SDimitry Andric   /// evaluate side-effects within its arguments.
30900b57cec5SDimitry Andric   bool isUnevaluatedBuiltinCall(const ASTContext &Ctx) const;
30910b57cec5SDimitry Andric 
30920b57cec5SDimitry Andric   /// getCallReturnType - Get the return type of the call expr. This is not
30930b57cec5SDimitry Andric   /// always the type of the expr itself, if the return type is a reference
30940b57cec5SDimitry Andric   /// type.
30950b57cec5SDimitry Andric   QualType getCallReturnType(const ASTContext &Ctx) const;
30960b57cec5SDimitry Andric 
30970b57cec5SDimitry Andric   /// Returns the WarnUnusedResultAttr that is either declared on the called
30980b57cec5SDimitry Andric   /// function, or its return type declaration.
30990b57cec5SDimitry Andric   const Attr *getUnusedResultAttr(const ASTContext &Ctx) const;
31000b57cec5SDimitry Andric 
31010b57cec5SDimitry Andric   /// Returns true if this call expression should warn on unused results.
hasUnusedResultAttr(const ASTContext & Ctx)31020b57cec5SDimitry Andric   bool hasUnusedResultAttr(const ASTContext &Ctx) const {
31030b57cec5SDimitry Andric     return getUnusedResultAttr(Ctx) != nullptr;
31040b57cec5SDimitry Andric   }
31050b57cec5SDimitry Andric 
getRParenLoc()31060b57cec5SDimitry Andric   SourceLocation getRParenLoc() const { return RParenLoc; }
setRParenLoc(SourceLocation L)31070b57cec5SDimitry Andric   void setRParenLoc(SourceLocation L) { RParenLoc = L; }
31080b57cec5SDimitry Andric 
31090b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY;
31100b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY;
31110b57cec5SDimitry Andric 
31120b57cec5SDimitry Andric   /// Return true if this is a call to __assume() or __builtin_assume() with
31130b57cec5SDimitry Andric   /// a non-value-dependent constant parameter evaluating as false.
31140b57cec5SDimitry Andric   bool isBuiltinAssumeFalse(const ASTContext &Ctx) const;
31150b57cec5SDimitry Andric 
31165ffd83dbSDimitry Andric   /// Used by Sema to implement MSVC-compatible delayed name lookup.
31175ffd83dbSDimitry Andric   /// (Usually Exprs themselves should set dependence).
markDependentForPostponedNameLookup()31185ffd83dbSDimitry Andric   void markDependentForPostponedNameLookup() {
31195ffd83dbSDimitry Andric     setDependence(getDependence() | ExprDependence::TypeValueInstantiation);
31205ffd83dbSDimitry Andric   }
31215ffd83dbSDimitry Andric 
312281ad6265SDimitry Andric   bool isCallToStdMove() const;
31230b57cec5SDimitry Andric 
classof(const Stmt * T)31240b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
31250b57cec5SDimitry Andric     return T->getStmtClass() >= firstCallExprConstant &&
31260b57cec5SDimitry Andric            T->getStmtClass() <= lastCallExprConstant;
31270b57cec5SDimitry Andric   }
31280b57cec5SDimitry Andric 
31290b57cec5SDimitry Andric   // Iterators
children()31300b57cec5SDimitry Andric   child_range children() {
31310b57cec5SDimitry Andric     return child_range(getTrailingStmts(), getTrailingStmts() + PREARGS_START +
31320b57cec5SDimitry Andric                                                getNumPreArgs() + getNumArgs());
31330b57cec5SDimitry Andric   }
31340b57cec5SDimitry Andric 
children()31350b57cec5SDimitry Andric   const_child_range children() const {
31360b57cec5SDimitry Andric     return const_child_range(getTrailingStmts(),
31370b57cec5SDimitry Andric                              getTrailingStmts() + PREARGS_START +
31380b57cec5SDimitry Andric                                  getNumPreArgs() + getNumArgs());
31390b57cec5SDimitry Andric   }
31400b57cec5SDimitry Andric };
31410b57cec5SDimitry Andric 
31420b57cec5SDimitry Andric /// Extra data stored in some MemberExpr objects.
31430b57cec5SDimitry Andric struct MemberExprNameQualifier {
31440b57cec5SDimitry Andric   /// The nested-name-specifier that qualifies the name, including
31450b57cec5SDimitry Andric   /// source-location information.
31460b57cec5SDimitry Andric   NestedNameSpecifierLoc QualifierLoc;
31470b57cec5SDimitry Andric 
31480b57cec5SDimitry Andric   /// The DeclAccessPair through which the MemberDecl was found due to
31490b57cec5SDimitry Andric   /// name qualifiers.
31500b57cec5SDimitry Andric   DeclAccessPair FoundDecl;
31510b57cec5SDimitry Andric };
31520b57cec5SDimitry Andric 
31530b57cec5SDimitry Andric /// MemberExpr - [C99 6.5.2.3] Structure and Union Members.  X->F and X.F.
31540b57cec5SDimitry Andric ///
31550b57cec5SDimitry Andric class MemberExpr final
31560b57cec5SDimitry Andric     : public Expr,
31570b57cec5SDimitry Andric       private llvm::TrailingObjects<MemberExpr, MemberExprNameQualifier,
31580b57cec5SDimitry Andric                                     ASTTemplateKWAndArgsInfo,
31590b57cec5SDimitry Andric                                     TemplateArgumentLoc> {
31600b57cec5SDimitry Andric   friend class ASTReader;
31610b57cec5SDimitry Andric   friend class ASTStmtReader;
31620b57cec5SDimitry Andric   friend class ASTStmtWriter;
31630b57cec5SDimitry Andric   friend TrailingObjects;
31640b57cec5SDimitry Andric 
31650b57cec5SDimitry Andric   /// Base - the expression for the base pointer or structure references.  In
31660b57cec5SDimitry Andric   /// X.F, this is "X".
31670b57cec5SDimitry Andric   Stmt *Base;
31680b57cec5SDimitry Andric 
31690b57cec5SDimitry Andric   /// MemberDecl - This is the decl being referenced by the field/member name.
31700b57cec5SDimitry Andric   /// In X.F, this is the decl referenced by F.
31710b57cec5SDimitry Andric   ValueDecl *MemberDecl;
31720b57cec5SDimitry Andric 
31730b57cec5SDimitry Andric   /// MemberDNLoc - Provides source/type location info for the
31740b57cec5SDimitry Andric   /// declaration name embedded in MemberDecl.
31750b57cec5SDimitry Andric   DeclarationNameLoc MemberDNLoc;
31760b57cec5SDimitry Andric 
31770b57cec5SDimitry Andric   /// MemberLoc - This is the location of the member name.
31780b57cec5SDimitry Andric   SourceLocation MemberLoc;
31790b57cec5SDimitry Andric 
numTrailingObjects(OverloadToken<MemberExprNameQualifier>)31800b57cec5SDimitry Andric   size_t numTrailingObjects(OverloadToken<MemberExprNameQualifier>) const {
31810b57cec5SDimitry Andric     return hasQualifierOrFoundDecl();
31820b57cec5SDimitry Andric   }
31830b57cec5SDimitry Andric 
numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>)31840b57cec5SDimitry Andric   size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
31850b57cec5SDimitry Andric     return hasTemplateKWAndArgsInfo();
31860b57cec5SDimitry Andric   }
31870b57cec5SDimitry Andric 
hasQualifierOrFoundDecl()31880b57cec5SDimitry Andric   bool hasQualifierOrFoundDecl() const {
31890b57cec5SDimitry Andric     return MemberExprBits.HasQualifierOrFoundDecl;
31900b57cec5SDimitry Andric   }
31910b57cec5SDimitry Andric 
hasTemplateKWAndArgsInfo()31920b57cec5SDimitry Andric   bool hasTemplateKWAndArgsInfo() const {
31930b57cec5SDimitry Andric     return MemberExprBits.HasTemplateKWAndArgsInfo;
31940b57cec5SDimitry Andric   }
31950b57cec5SDimitry Andric 
31960b57cec5SDimitry Andric   MemberExpr(Expr *Base, bool IsArrow, SourceLocation OperatorLoc,
31970b57cec5SDimitry Andric              ValueDecl *MemberDecl, const DeclarationNameInfo &NameInfo,
31980b57cec5SDimitry Andric              QualType T, ExprValueKind VK, ExprObjectKind OK,
31990b57cec5SDimitry Andric              NonOdrUseReason NOUR);
MemberExpr(EmptyShell Empty)32000b57cec5SDimitry Andric   MemberExpr(EmptyShell Empty)
32010b57cec5SDimitry Andric       : Expr(MemberExprClass, Empty), Base(), MemberDecl() {}
32020b57cec5SDimitry Andric 
32030b57cec5SDimitry Andric public:
32040b57cec5SDimitry Andric   static MemberExpr *Create(const ASTContext &C, Expr *Base, bool IsArrow,
32050b57cec5SDimitry Andric                             SourceLocation OperatorLoc,
32060b57cec5SDimitry Andric                             NestedNameSpecifierLoc QualifierLoc,
32070b57cec5SDimitry Andric                             SourceLocation TemplateKWLoc, ValueDecl *MemberDecl,
32080b57cec5SDimitry Andric                             DeclAccessPair FoundDecl,
32090b57cec5SDimitry Andric                             DeclarationNameInfo MemberNameInfo,
32100b57cec5SDimitry Andric                             const TemplateArgumentListInfo *TemplateArgs,
32110b57cec5SDimitry Andric                             QualType T, ExprValueKind VK, ExprObjectKind OK,
32120b57cec5SDimitry Andric                             NonOdrUseReason NOUR);
32130b57cec5SDimitry Andric 
32140b57cec5SDimitry Andric   /// Create an implicit MemberExpr, with no location, qualifier, template
32150b57cec5SDimitry Andric   /// arguments, and so on. Suitable only for non-static member access.
CreateImplicit(const ASTContext & C,Expr * Base,bool IsArrow,ValueDecl * MemberDecl,QualType T,ExprValueKind VK,ExprObjectKind OK)32160b57cec5SDimitry Andric   static MemberExpr *CreateImplicit(const ASTContext &C, Expr *Base,
32170b57cec5SDimitry Andric                                     bool IsArrow, ValueDecl *MemberDecl,
32180b57cec5SDimitry Andric                                     QualType T, ExprValueKind VK,
32190b57cec5SDimitry Andric                                     ExprObjectKind OK) {
32200b57cec5SDimitry Andric     return Create(C, Base, IsArrow, SourceLocation(), NestedNameSpecifierLoc(),
32210b57cec5SDimitry Andric                   SourceLocation(), MemberDecl,
32220b57cec5SDimitry Andric                   DeclAccessPair::make(MemberDecl, MemberDecl->getAccess()),
32230b57cec5SDimitry Andric                   DeclarationNameInfo(), nullptr, T, VK, OK, NOUR_None);
32240b57cec5SDimitry Andric   }
32250b57cec5SDimitry Andric 
32260b57cec5SDimitry Andric   static MemberExpr *CreateEmpty(const ASTContext &Context, bool HasQualifier,
32270b57cec5SDimitry Andric                                  bool HasFoundDecl,
32280b57cec5SDimitry Andric                                  bool HasTemplateKWAndArgsInfo,
32290b57cec5SDimitry Andric                                  unsigned NumTemplateArgs);
32300b57cec5SDimitry Andric 
setBase(Expr * E)32310b57cec5SDimitry Andric   void setBase(Expr *E) { Base = E; }
getBase()32320b57cec5SDimitry Andric   Expr *getBase() const { return cast<Expr>(Base); }
32330b57cec5SDimitry Andric 
32340b57cec5SDimitry Andric   /// Retrieve the member declaration to which this expression refers.
32350b57cec5SDimitry Andric   ///
32360b57cec5SDimitry Andric   /// The returned declaration will be a FieldDecl or (in C++) a VarDecl (for
32370b57cec5SDimitry Andric   /// static data members), a CXXMethodDecl, or an EnumConstantDecl.
getMemberDecl()32380b57cec5SDimitry Andric   ValueDecl *getMemberDecl() const { return MemberDecl; }
3239e8d8bef9SDimitry Andric   void setMemberDecl(ValueDecl *D);
32400b57cec5SDimitry Andric 
32410b57cec5SDimitry Andric   /// Retrieves the declaration found by lookup.
getFoundDecl()32420b57cec5SDimitry Andric   DeclAccessPair getFoundDecl() const {
32430b57cec5SDimitry Andric     if (!hasQualifierOrFoundDecl())
32440b57cec5SDimitry Andric       return DeclAccessPair::make(getMemberDecl(),
32450b57cec5SDimitry Andric                                   getMemberDecl()->getAccess());
32460b57cec5SDimitry Andric     return getTrailingObjects<MemberExprNameQualifier>()->FoundDecl;
32470b57cec5SDimitry Andric   }
32480b57cec5SDimitry Andric 
32490b57cec5SDimitry Andric   /// Determines whether this member expression actually had
32500b57cec5SDimitry Andric   /// a C++ nested-name-specifier prior to the name of the member, e.g.,
32510b57cec5SDimitry Andric   /// x->Base::foo.
hasQualifier()32520b57cec5SDimitry Andric   bool hasQualifier() const { return getQualifier() != nullptr; }
32530b57cec5SDimitry Andric 
32540b57cec5SDimitry Andric   /// If the member name was qualified, retrieves the
32550b57cec5SDimitry Andric   /// nested-name-specifier that precedes the member name, with source-location
32560b57cec5SDimitry Andric   /// information.
getQualifierLoc()32570b57cec5SDimitry Andric   NestedNameSpecifierLoc getQualifierLoc() const {
32580b57cec5SDimitry Andric     if (!hasQualifierOrFoundDecl())
32590b57cec5SDimitry Andric       return NestedNameSpecifierLoc();
32600b57cec5SDimitry Andric     return getTrailingObjects<MemberExprNameQualifier>()->QualifierLoc;
32610b57cec5SDimitry Andric   }
32620b57cec5SDimitry Andric 
32630b57cec5SDimitry Andric   /// If the member name was qualified, retrieves the
32640b57cec5SDimitry Andric   /// nested-name-specifier that precedes the member name. Otherwise, returns
32650b57cec5SDimitry Andric   /// NULL.
getQualifier()32660b57cec5SDimitry Andric   NestedNameSpecifier *getQualifier() const {
32670b57cec5SDimitry Andric     return getQualifierLoc().getNestedNameSpecifier();
32680b57cec5SDimitry Andric   }
32690b57cec5SDimitry Andric 
32700b57cec5SDimitry Andric   /// Retrieve the location of the template keyword preceding
32710b57cec5SDimitry Andric   /// the member name, if any.
getTemplateKeywordLoc()32720b57cec5SDimitry Andric   SourceLocation getTemplateKeywordLoc() const {
32730b57cec5SDimitry Andric     if (!hasTemplateKWAndArgsInfo())
32740b57cec5SDimitry Andric       return SourceLocation();
32750b57cec5SDimitry Andric     return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->TemplateKWLoc;
32760b57cec5SDimitry Andric   }
32770b57cec5SDimitry Andric 
32780b57cec5SDimitry Andric   /// Retrieve the location of the left angle bracket starting the
32790b57cec5SDimitry Andric   /// explicit template argument list following the member name, if any.
getLAngleLoc()32800b57cec5SDimitry Andric   SourceLocation getLAngleLoc() const {
32810b57cec5SDimitry Andric     if (!hasTemplateKWAndArgsInfo())
32820b57cec5SDimitry Andric       return SourceLocation();
32830b57cec5SDimitry Andric     return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->LAngleLoc;
32840b57cec5SDimitry Andric   }
32850b57cec5SDimitry Andric 
32860b57cec5SDimitry Andric   /// Retrieve the location of the right angle bracket ending the
32870b57cec5SDimitry Andric   /// explicit template argument list following the member name, if any.
getRAngleLoc()32880b57cec5SDimitry Andric   SourceLocation getRAngleLoc() const {
32890b57cec5SDimitry Andric     if (!hasTemplateKWAndArgsInfo())
32900b57cec5SDimitry Andric       return SourceLocation();
32910b57cec5SDimitry Andric     return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->RAngleLoc;
32920b57cec5SDimitry Andric   }
32930b57cec5SDimitry Andric 
32940b57cec5SDimitry Andric   /// Determines whether the member name was preceded by the template keyword.
hasTemplateKeyword()32950b57cec5SDimitry Andric   bool hasTemplateKeyword() const { return getTemplateKeywordLoc().isValid(); }
32960b57cec5SDimitry Andric 
32970b57cec5SDimitry Andric   /// Determines whether the member name was followed by an
32980b57cec5SDimitry Andric   /// explicit template argument list.
hasExplicitTemplateArgs()32990b57cec5SDimitry Andric   bool hasExplicitTemplateArgs() const { return getLAngleLoc().isValid(); }
33000b57cec5SDimitry Andric 
33010b57cec5SDimitry Andric   /// Copies the template arguments (if present) into the given
33020b57cec5SDimitry Andric   /// structure.
copyTemplateArgumentsInto(TemplateArgumentListInfo & List)33030b57cec5SDimitry Andric   void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
33040b57cec5SDimitry Andric     if (hasExplicitTemplateArgs())
33050b57cec5SDimitry Andric       getTrailingObjects<ASTTemplateKWAndArgsInfo>()->copyInto(
33060b57cec5SDimitry Andric           getTrailingObjects<TemplateArgumentLoc>(), List);
33070b57cec5SDimitry Andric   }
33080b57cec5SDimitry Andric 
33090b57cec5SDimitry Andric   /// Retrieve the template arguments provided as part of this
33100b57cec5SDimitry Andric   /// template-id.
getTemplateArgs()33110b57cec5SDimitry Andric   const TemplateArgumentLoc *getTemplateArgs() const {
33120b57cec5SDimitry Andric     if (!hasExplicitTemplateArgs())
33130b57cec5SDimitry Andric       return nullptr;
33140b57cec5SDimitry Andric 
33150b57cec5SDimitry Andric     return getTrailingObjects<TemplateArgumentLoc>();
33160b57cec5SDimitry Andric   }
33170b57cec5SDimitry Andric 
33180b57cec5SDimitry Andric   /// Retrieve the number of template arguments provided as part of this
33190b57cec5SDimitry Andric   /// template-id.
getNumTemplateArgs()33200b57cec5SDimitry Andric   unsigned getNumTemplateArgs() const {
33210b57cec5SDimitry Andric     if (!hasExplicitTemplateArgs())
33220b57cec5SDimitry Andric       return 0;
33230b57cec5SDimitry Andric 
33240b57cec5SDimitry Andric     return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->NumTemplateArgs;
33250b57cec5SDimitry Andric   }
33260b57cec5SDimitry Andric 
template_arguments()33270b57cec5SDimitry Andric   ArrayRef<TemplateArgumentLoc> template_arguments() const {
33280b57cec5SDimitry Andric     return {getTemplateArgs(), getNumTemplateArgs()};
33290b57cec5SDimitry Andric   }
33300b57cec5SDimitry Andric 
33310b57cec5SDimitry Andric   /// Retrieve the member declaration name info.
getMemberNameInfo()33320b57cec5SDimitry Andric   DeclarationNameInfo getMemberNameInfo() const {
33330b57cec5SDimitry Andric     return DeclarationNameInfo(MemberDecl->getDeclName(),
33340b57cec5SDimitry Andric                                MemberLoc, MemberDNLoc);
33350b57cec5SDimitry Andric   }
33360b57cec5SDimitry Andric 
getOperatorLoc()33370b57cec5SDimitry Andric   SourceLocation getOperatorLoc() const { return MemberExprBits.OperatorLoc; }
33380b57cec5SDimitry Andric 
isArrow()33390b57cec5SDimitry Andric   bool isArrow() const { return MemberExprBits.IsArrow; }
setArrow(bool A)33400b57cec5SDimitry Andric   void setArrow(bool A) { MemberExprBits.IsArrow = A; }
33410b57cec5SDimitry Andric 
33420b57cec5SDimitry Andric   /// getMemberLoc - Return the location of the "member", in X->F, it is the
33430b57cec5SDimitry Andric   /// location of 'F'.
getMemberLoc()33440b57cec5SDimitry Andric   SourceLocation getMemberLoc() const { return MemberLoc; }
setMemberLoc(SourceLocation L)33450b57cec5SDimitry Andric   void setMemberLoc(SourceLocation L) { MemberLoc = L; }
33460b57cec5SDimitry Andric 
33470b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY;
33480b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY;
33490b57cec5SDimitry Andric 
getExprLoc()33500b57cec5SDimitry Andric   SourceLocation getExprLoc() const LLVM_READONLY { return MemberLoc; }
33510b57cec5SDimitry Andric 
33520b57cec5SDimitry Andric   /// Determine whether the base of this explicit is implicit.
isImplicitAccess()33530b57cec5SDimitry Andric   bool isImplicitAccess() const {
33540b57cec5SDimitry Andric     return getBase() && getBase()->isImplicitCXXThis();
33550b57cec5SDimitry Andric   }
33560b57cec5SDimitry Andric 
33570b57cec5SDimitry Andric   /// Returns true if this member expression refers to a method that
33580b57cec5SDimitry Andric   /// was resolved from an overloaded set having size greater than 1.
hadMultipleCandidates()33590b57cec5SDimitry Andric   bool hadMultipleCandidates() const {
33600b57cec5SDimitry Andric     return MemberExprBits.HadMultipleCandidates;
33610b57cec5SDimitry Andric   }
33620b57cec5SDimitry Andric   /// Sets the flag telling whether this expression refers to
33630b57cec5SDimitry Andric   /// a method that was resolved from an overloaded set having size
33640b57cec5SDimitry Andric   /// greater than 1.
33650b57cec5SDimitry Andric   void setHadMultipleCandidates(bool V = true) {
33660b57cec5SDimitry Andric     MemberExprBits.HadMultipleCandidates = V;
33670b57cec5SDimitry Andric   }
33680b57cec5SDimitry Andric 
33690b57cec5SDimitry Andric   /// Returns true if virtual dispatch is performed.
33700b57cec5SDimitry Andric   /// If the member access is fully qualified, (i.e. X::f()), virtual
33710b57cec5SDimitry Andric   /// dispatching is not performed. In -fapple-kext mode qualified
33720b57cec5SDimitry Andric   /// calls to virtual method will still go through the vtable.
performsVirtualDispatch(const LangOptions & LO)33730b57cec5SDimitry Andric   bool performsVirtualDispatch(const LangOptions &LO) const {
33740b57cec5SDimitry Andric     return LO.AppleKext || !hasQualifier();
33750b57cec5SDimitry Andric   }
33760b57cec5SDimitry Andric 
33770b57cec5SDimitry Andric   /// Is this expression a non-odr-use reference, and if so, why?
33780b57cec5SDimitry Andric   /// This is only meaningful if the named member is a static member.
isNonOdrUse()33790b57cec5SDimitry Andric   NonOdrUseReason isNonOdrUse() const {
33800b57cec5SDimitry Andric     return static_cast<NonOdrUseReason>(MemberExprBits.NonOdrUseReason);
33810b57cec5SDimitry Andric   }
33820b57cec5SDimitry Andric 
classof(const Stmt * T)33830b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
33840b57cec5SDimitry Andric     return T->getStmtClass() == MemberExprClass;
33850b57cec5SDimitry Andric   }
33860b57cec5SDimitry Andric 
33870b57cec5SDimitry Andric   // Iterators
children()33880b57cec5SDimitry Andric   child_range children() { return child_range(&Base, &Base+1); }
children()33890b57cec5SDimitry Andric   const_child_range children() const {
33900b57cec5SDimitry Andric     return const_child_range(&Base, &Base + 1);
33910b57cec5SDimitry Andric   }
33920b57cec5SDimitry Andric };
33930b57cec5SDimitry Andric 
33940b57cec5SDimitry Andric /// CompoundLiteralExpr - [C99 6.5.2.5]
33950b57cec5SDimitry Andric ///
33960b57cec5SDimitry Andric class CompoundLiteralExpr : public Expr {
33970b57cec5SDimitry Andric   /// LParenLoc - If non-null, this is the location of the left paren in a
33980b57cec5SDimitry Andric   /// compound literal like "(int){4}".  This can be null if this is a
33990b57cec5SDimitry Andric   /// synthesized compound expression.
34000b57cec5SDimitry Andric   SourceLocation LParenLoc;
34010b57cec5SDimitry Andric 
34020b57cec5SDimitry Andric   /// The type as written.  This can be an incomplete array type, in
34030b57cec5SDimitry Andric   /// which case the actual expression type will be different.
34040b57cec5SDimitry Andric   /// The int part of the pair stores whether this expr is file scope.
34050b57cec5SDimitry Andric   llvm::PointerIntPair<TypeSourceInfo *, 1, bool> TInfoAndScope;
34060b57cec5SDimitry Andric   Stmt *Init;
34070b57cec5SDimitry Andric public:
CompoundLiteralExpr(SourceLocation lparenloc,TypeSourceInfo * tinfo,QualType T,ExprValueKind VK,Expr * init,bool fileScope)34080b57cec5SDimitry Andric   CompoundLiteralExpr(SourceLocation lparenloc, TypeSourceInfo *tinfo,
34090b57cec5SDimitry Andric                       QualType T, ExprValueKind VK, Expr *init, bool fileScope)
34105ffd83dbSDimitry Andric       : Expr(CompoundLiteralExprClass, T, VK, OK_Ordinary),
34115ffd83dbSDimitry Andric         LParenLoc(lparenloc), TInfoAndScope(tinfo, fileScope), Init(init) {
34125ffd83dbSDimitry Andric     setDependence(computeDependence(this));
34135ffd83dbSDimitry Andric   }
34140b57cec5SDimitry Andric 
34150b57cec5SDimitry Andric   /// Construct an empty compound literal.
CompoundLiteralExpr(EmptyShell Empty)34160b57cec5SDimitry Andric   explicit CompoundLiteralExpr(EmptyShell Empty)
34170b57cec5SDimitry Andric     : Expr(CompoundLiteralExprClass, Empty) { }
34180b57cec5SDimitry Andric 
getInitializer()34190b57cec5SDimitry Andric   const Expr *getInitializer() const { return cast<Expr>(Init); }
getInitializer()34200b57cec5SDimitry Andric   Expr *getInitializer() { return cast<Expr>(Init); }
setInitializer(Expr * E)34210b57cec5SDimitry Andric   void setInitializer(Expr *E) { Init = E; }
34220b57cec5SDimitry Andric 
isFileScope()34230b57cec5SDimitry Andric   bool isFileScope() const { return TInfoAndScope.getInt(); }
setFileScope(bool FS)34240b57cec5SDimitry Andric   void setFileScope(bool FS) { TInfoAndScope.setInt(FS); }
34250b57cec5SDimitry Andric 
getLParenLoc()34260b57cec5SDimitry Andric   SourceLocation getLParenLoc() const { return LParenLoc; }
setLParenLoc(SourceLocation L)34270b57cec5SDimitry Andric   void setLParenLoc(SourceLocation L) { LParenLoc = L; }
34280b57cec5SDimitry Andric 
getTypeSourceInfo()34290b57cec5SDimitry Andric   TypeSourceInfo *getTypeSourceInfo() const {
34300b57cec5SDimitry Andric     return TInfoAndScope.getPointer();
34310b57cec5SDimitry Andric   }
setTypeSourceInfo(TypeSourceInfo * tinfo)34320b57cec5SDimitry Andric   void setTypeSourceInfo(TypeSourceInfo *tinfo) {
34330b57cec5SDimitry Andric     TInfoAndScope.setPointer(tinfo);
34340b57cec5SDimitry Andric   }
34350b57cec5SDimitry Andric 
getBeginLoc()34360b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY {
34370b57cec5SDimitry Andric     // FIXME: Init should never be null.
34380b57cec5SDimitry Andric     if (!Init)
34390b57cec5SDimitry Andric       return SourceLocation();
34400b57cec5SDimitry Andric     if (LParenLoc.isInvalid())
34410b57cec5SDimitry Andric       return Init->getBeginLoc();
34420b57cec5SDimitry Andric     return LParenLoc;
34430b57cec5SDimitry Andric   }
getEndLoc()34440b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY {
34450b57cec5SDimitry Andric     // FIXME: Init should never be null.
34460b57cec5SDimitry Andric     if (!Init)
34470b57cec5SDimitry Andric       return SourceLocation();
34480b57cec5SDimitry Andric     return Init->getEndLoc();
34490b57cec5SDimitry Andric   }
34500b57cec5SDimitry Andric 
classof(const Stmt * T)34510b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
34520b57cec5SDimitry Andric     return T->getStmtClass() == CompoundLiteralExprClass;
34530b57cec5SDimitry Andric   }
34540b57cec5SDimitry Andric 
34550b57cec5SDimitry Andric   // Iterators
children()34560b57cec5SDimitry Andric   child_range children() { return child_range(&Init, &Init+1); }
children()34570b57cec5SDimitry Andric   const_child_range children() const {
34580b57cec5SDimitry Andric     return const_child_range(&Init, &Init + 1);
34590b57cec5SDimitry Andric   }
34600b57cec5SDimitry Andric };
34610b57cec5SDimitry Andric 
34620b57cec5SDimitry Andric /// CastExpr - Base class for type casts, including both implicit
34630b57cec5SDimitry Andric /// casts (ImplicitCastExpr) and explicit casts that have some
34640b57cec5SDimitry Andric /// representation in the source code (ExplicitCastExpr's derived
34650b57cec5SDimitry Andric /// classes).
34660b57cec5SDimitry Andric class CastExpr : public Expr {
34670b57cec5SDimitry Andric   Stmt *Op;
34680b57cec5SDimitry Andric 
34690b57cec5SDimitry Andric   bool CastConsistency() const;
34700b57cec5SDimitry Andric 
path_buffer()34710b57cec5SDimitry Andric   const CXXBaseSpecifier * const *path_buffer() const {
34720b57cec5SDimitry Andric     return const_cast<CastExpr*>(this)->path_buffer();
34730b57cec5SDimitry Andric   }
34740b57cec5SDimitry Andric   CXXBaseSpecifier **path_buffer();
34750b57cec5SDimitry Andric 
3476e8d8bef9SDimitry Andric   friend class ASTStmtReader;
3477e8d8bef9SDimitry Andric 
34780b57cec5SDimitry Andric protected:
CastExpr(StmtClass SC,QualType ty,ExprValueKind VK,const CastKind kind,Expr * op,unsigned BasePathSize,bool HasFPFeatures)34790b57cec5SDimitry Andric   CastExpr(StmtClass SC, QualType ty, ExprValueKind VK, const CastKind kind,
3480e8d8bef9SDimitry Andric            Expr *op, unsigned BasePathSize, bool HasFPFeatures)
34815ffd83dbSDimitry Andric       : Expr(SC, ty, VK, OK_Ordinary), Op(op) {
34820b57cec5SDimitry Andric     CastExprBits.Kind = kind;
34830b57cec5SDimitry Andric     CastExprBits.PartOfExplicitCast = false;
34840b57cec5SDimitry Andric     CastExprBits.BasePathSize = BasePathSize;
34850b57cec5SDimitry Andric     assert((CastExprBits.BasePathSize == BasePathSize) &&
34860b57cec5SDimitry Andric            "BasePathSize overflow!");
34870b57cec5SDimitry Andric     assert(CastConsistency());
3488e8d8bef9SDimitry Andric     CastExprBits.HasFPFeatures = HasFPFeatures;
34890b57cec5SDimitry Andric   }
34900b57cec5SDimitry Andric 
34910b57cec5SDimitry Andric   /// Construct an empty cast.
CastExpr(StmtClass SC,EmptyShell Empty,unsigned BasePathSize,bool HasFPFeatures)3492e8d8bef9SDimitry Andric   CastExpr(StmtClass SC, EmptyShell Empty, unsigned BasePathSize,
3493e8d8bef9SDimitry Andric            bool HasFPFeatures)
34940b57cec5SDimitry Andric       : Expr(SC, Empty) {
34950b57cec5SDimitry Andric     CastExprBits.PartOfExplicitCast = false;
34960b57cec5SDimitry Andric     CastExprBits.BasePathSize = BasePathSize;
3497e8d8bef9SDimitry Andric     CastExprBits.HasFPFeatures = HasFPFeatures;
34980b57cec5SDimitry Andric     assert((CastExprBits.BasePathSize == BasePathSize) &&
34990b57cec5SDimitry Andric            "BasePathSize overflow!");
35000b57cec5SDimitry Andric   }
35010b57cec5SDimitry Andric 
3502e8d8bef9SDimitry Andric   /// Return a pointer to the trailing FPOptions.
3503e8d8bef9SDimitry Andric   /// \pre hasStoredFPFeatures() == true
3504e8d8bef9SDimitry Andric   FPOptionsOverride *getTrailingFPFeatures();
getTrailingFPFeatures()3505e8d8bef9SDimitry Andric   const FPOptionsOverride *getTrailingFPFeatures() const {
3506e8d8bef9SDimitry Andric     return const_cast<CastExpr *>(this)->getTrailingFPFeatures();
3507e8d8bef9SDimitry Andric   }
3508e8d8bef9SDimitry Andric 
35090b57cec5SDimitry Andric public:
getCastKind()35100b57cec5SDimitry Andric   CastKind getCastKind() const { return (CastKind) CastExprBits.Kind; }
setCastKind(CastKind K)35110b57cec5SDimitry Andric   void setCastKind(CastKind K) { CastExprBits.Kind = K; }
35120b57cec5SDimitry Andric 
35130b57cec5SDimitry Andric   static const char *getCastKindName(CastKind CK);
getCastKindName()35140b57cec5SDimitry Andric   const char *getCastKindName() const { return getCastKindName(getCastKind()); }
35150b57cec5SDimitry Andric 
getSubExpr()35160b57cec5SDimitry Andric   Expr *getSubExpr() { return cast<Expr>(Op); }
getSubExpr()35170b57cec5SDimitry Andric   const Expr *getSubExpr() const { return cast<Expr>(Op); }
setSubExpr(Expr * E)35180b57cec5SDimitry Andric   void setSubExpr(Expr *E) { Op = E; }
35190b57cec5SDimitry Andric 
35200b57cec5SDimitry Andric   /// Retrieve the cast subexpression as it was written in the source
35210b57cec5SDimitry Andric   /// code, looking through any implicit casts or other intermediate nodes
35220b57cec5SDimitry Andric   /// introduced by semantic analysis.
35230b57cec5SDimitry Andric   Expr *getSubExprAsWritten();
getSubExprAsWritten()35240b57cec5SDimitry Andric   const Expr *getSubExprAsWritten() const {
35250b57cec5SDimitry Andric     return const_cast<CastExpr *>(this)->getSubExprAsWritten();
35260b57cec5SDimitry Andric   }
35270b57cec5SDimitry Andric 
35280b57cec5SDimitry Andric   /// If this cast applies a user-defined conversion, retrieve the conversion
35290b57cec5SDimitry Andric   /// function that it invokes.
35300b57cec5SDimitry Andric   NamedDecl *getConversionFunction() const;
35310b57cec5SDimitry Andric 
35320b57cec5SDimitry Andric   typedef CXXBaseSpecifier **path_iterator;
35330b57cec5SDimitry Andric   typedef const CXXBaseSpecifier *const *path_const_iterator;
path_empty()35340b57cec5SDimitry Andric   bool path_empty() const { return path_size() == 0; }
path_size()35350b57cec5SDimitry Andric   unsigned path_size() const { return CastExprBits.BasePathSize; }
path_begin()35360b57cec5SDimitry Andric   path_iterator path_begin() { return path_buffer(); }
path_end()35370b57cec5SDimitry Andric   path_iterator path_end() { return path_buffer() + path_size(); }
path_begin()35380b57cec5SDimitry Andric   path_const_iterator path_begin() const { return path_buffer(); }
path_end()35390b57cec5SDimitry Andric   path_const_iterator path_end() const { return path_buffer() + path_size(); }
35400b57cec5SDimitry Andric 
path()35410b57cec5SDimitry Andric   llvm::iterator_range<path_iterator> path() {
35420b57cec5SDimitry Andric     return llvm::make_range(path_begin(), path_end());
35430b57cec5SDimitry Andric   }
path()35440b57cec5SDimitry Andric   llvm::iterator_range<path_const_iterator> path() const {
35450b57cec5SDimitry Andric     return llvm::make_range(path_begin(), path_end());
35460b57cec5SDimitry Andric   }
35470b57cec5SDimitry Andric 
getTargetUnionField()35480b57cec5SDimitry Andric   const FieldDecl *getTargetUnionField() const {
35490b57cec5SDimitry Andric     assert(getCastKind() == CK_ToUnion);
35500b57cec5SDimitry Andric     return getTargetFieldForToUnionCast(getType(), getSubExpr()->getType());
35510b57cec5SDimitry Andric   }
35520b57cec5SDimitry Andric 
hasStoredFPFeatures()3553e8d8bef9SDimitry Andric   bool hasStoredFPFeatures() const { return CastExprBits.HasFPFeatures; }
3554e8d8bef9SDimitry Andric 
3555e8d8bef9SDimitry Andric   /// Get FPOptionsOverride from trailing storage.
getStoredFPFeatures()3556e8d8bef9SDimitry Andric   FPOptionsOverride getStoredFPFeatures() const {
3557e8d8bef9SDimitry Andric     assert(hasStoredFPFeatures());
3558e8d8bef9SDimitry Andric     return *getTrailingFPFeatures();
3559e8d8bef9SDimitry Andric   }
3560e8d8bef9SDimitry Andric 
356106c3fb27SDimitry Andric   /// Get the FP features status of this operation. Only meaningful for
356206c3fb27SDimitry Andric   /// operations on floating point types.
getFPFeaturesInEffect(const LangOptions & LO)3563e8d8bef9SDimitry Andric   FPOptions getFPFeaturesInEffect(const LangOptions &LO) const {
3564e8d8bef9SDimitry Andric     if (hasStoredFPFeatures())
3565e8d8bef9SDimitry Andric       return getStoredFPFeatures().applyOverrides(LO);
3566e8d8bef9SDimitry Andric     return FPOptions::defaultWithoutTrailingStorage(LO);
3567e8d8bef9SDimitry Andric   }
3568e8d8bef9SDimitry Andric 
getFPFeatures()3569e8d8bef9SDimitry Andric   FPOptionsOverride getFPFeatures() const {
3570e8d8bef9SDimitry Andric     if (hasStoredFPFeatures())
3571e8d8bef9SDimitry Andric       return getStoredFPFeatures();
3572e8d8bef9SDimitry Andric     return FPOptionsOverride();
3573e8d8bef9SDimitry Andric   }
3574e8d8bef9SDimitry Andric 
35755f757f3fSDimitry Andric   /// Return
35765f757f3fSDimitry Andric   //  True : if this conversion changes the volatile-ness of a gl-value.
35775f757f3fSDimitry Andric   //         Qualification conversions on gl-values currently use CK_NoOp, but
35785f757f3fSDimitry Andric   //         it's important to recognize volatile-changing conversions in
35795f757f3fSDimitry Andric   //         clients code generation that normally eagerly peephole loads. Note
35805f757f3fSDimitry Andric   //         that the query is answering for this specific node; Sema may
35815f757f3fSDimitry Andric   //         produce multiple cast nodes for any particular conversion sequence.
35825f757f3fSDimitry Andric   //  False : Otherwise.
changesVolatileQualification()35835f757f3fSDimitry Andric   bool changesVolatileQualification() const {
35845f757f3fSDimitry Andric     return (isGLValue() && (getType().isVolatileQualified() !=
35855f757f3fSDimitry Andric                             getSubExpr()->getType().isVolatileQualified()));
35865f757f3fSDimitry Andric   }
35875f757f3fSDimitry Andric 
35880b57cec5SDimitry Andric   static const FieldDecl *getTargetFieldForToUnionCast(QualType unionType,
35890b57cec5SDimitry Andric                                                        QualType opType);
35900b57cec5SDimitry Andric   static const FieldDecl *getTargetFieldForToUnionCast(const RecordDecl *RD,
35910b57cec5SDimitry Andric                                                        QualType opType);
35920b57cec5SDimitry Andric 
classof(const Stmt * T)35930b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
35940b57cec5SDimitry Andric     return T->getStmtClass() >= firstCastExprConstant &&
35950b57cec5SDimitry Andric            T->getStmtClass() <= lastCastExprConstant;
35960b57cec5SDimitry Andric   }
35970b57cec5SDimitry Andric 
35980b57cec5SDimitry Andric   // Iterators
children()35990b57cec5SDimitry Andric   child_range children() { return child_range(&Op, &Op+1); }
children()36000b57cec5SDimitry Andric   const_child_range children() const { return const_child_range(&Op, &Op + 1); }
36010b57cec5SDimitry Andric };
36020b57cec5SDimitry Andric 
36030b57cec5SDimitry Andric /// ImplicitCastExpr - Allows us to explicitly represent implicit type
36040b57cec5SDimitry Andric /// conversions, which have no direct representation in the original
36050b57cec5SDimitry Andric /// source code. For example: converting T[]->T*, void f()->void
36060b57cec5SDimitry Andric /// (*f)(), float->double, short->int, etc.
36070b57cec5SDimitry Andric ///
36080b57cec5SDimitry Andric /// In C, implicit casts always produce rvalues. However, in C++, an
36090b57cec5SDimitry Andric /// implicit cast whose result is being bound to a reference will be
36100b57cec5SDimitry Andric /// an lvalue or xvalue. For example:
36110b57cec5SDimitry Andric ///
36120b57cec5SDimitry Andric /// @code
36130b57cec5SDimitry Andric /// class Base { };
36140b57cec5SDimitry Andric /// class Derived : public Base { };
36150b57cec5SDimitry Andric /// Derived &&ref();
36160b57cec5SDimitry Andric /// void f(Derived d) {
36170b57cec5SDimitry Andric ///   Base& b = d; // initializer is an ImplicitCastExpr
36180b57cec5SDimitry Andric ///                // to an lvalue of type Base
36190b57cec5SDimitry Andric ///   Base&& r = ref(); // initializer is an ImplicitCastExpr
36200b57cec5SDimitry Andric ///                     // to an xvalue of type Base
36210b57cec5SDimitry Andric /// }
36220b57cec5SDimitry Andric /// @endcode
36230b57cec5SDimitry Andric class ImplicitCastExpr final
36240b57cec5SDimitry Andric     : public CastExpr,
3625e8d8bef9SDimitry Andric       private llvm::TrailingObjects<ImplicitCastExpr, CXXBaseSpecifier *,
3626e8d8bef9SDimitry Andric                                     FPOptionsOverride> {
36270b57cec5SDimitry Andric 
ImplicitCastExpr(QualType ty,CastKind kind,Expr * op,unsigned BasePathLength,FPOptionsOverride FPO,ExprValueKind VK)36280b57cec5SDimitry Andric   ImplicitCastExpr(QualType ty, CastKind kind, Expr *op,
3629e8d8bef9SDimitry Andric                    unsigned BasePathLength, FPOptionsOverride FPO,
3630e8d8bef9SDimitry Andric                    ExprValueKind VK)
3631e8d8bef9SDimitry Andric       : CastExpr(ImplicitCastExprClass, ty, VK, kind, op, BasePathLength,
3632e8d8bef9SDimitry Andric                  FPO.requiresTrailingStorage()) {
36333b7f365eSDimitry Andric     setDependence(computeDependence(this));
3634e8d8bef9SDimitry Andric     if (hasStoredFPFeatures())
3635e8d8bef9SDimitry Andric       *getTrailingFPFeatures() = FPO;
3636e8d8bef9SDimitry Andric   }
36370b57cec5SDimitry Andric 
36380b57cec5SDimitry Andric   /// Construct an empty implicit cast.
ImplicitCastExpr(EmptyShell Shell,unsigned PathSize,bool HasFPFeatures)3639e8d8bef9SDimitry Andric   explicit ImplicitCastExpr(EmptyShell Shell, unsigned PathSize,
3640e8d8bef9SDimitry Andric                             bool HasFPFeatures)
3641e8d8bef9SDimitry Andric       : CastExpr(ImplicitCastExprClass, Shell, PathSize, HasFPFeatures) {}
3642e8d8bef9SDimitry Andric 
numTrailingObjects(OverloadToken<CXXBaseSpecifier * >)3643e8d8bef9SDimitry Andric   unsigned numTrailingObjects(OverloadToken<CXXBaseSpecifier *>) const {
3644e8d8bef9SDimitry Andric     return path_size();
3645e8d8bef9SDimitry Andric   }
36460b57cec5SDimitry Andric 
36470b57cec5SDimitry Andric public:
36480b57cec5SDimitry Andric   enum OnStack_t { OnStack };
ImplicitCastExpr(OnStack_t _,QualType ty,CastKind kind,Expr * op,ExprValueKind VK,FPOptionsOverride FPO)36490b57cec5SDimitry Andric   ImplicitCastExpr(OnStack_t _, QualType ty, CastKind kind, Expr *op,
3650e8d8bef9SDimitry Andric                    ExprValueKind VK, FPOptionsOverride FPO)
3651e8d8bef9SDimitry Andric       : CastExpr(ImplicitCastExprClass, ty, VK, kind, op, 0,
3652e8d8bef9SDimitry Andric                  FPO.requiresTrailingStorage()) {
3653e8d8bef9SDimitry Andric     if (hasStoredFPFeatures())
3654e8d8bef9SDimitry Andric       *getTrailingFPFeatures() = FPO;
36550b57cec5SDimitry Andric   }
36560b57cec5SDimitry Andric 
isPartOfExplicitCast()36570b57cec5SDimitry Andric   bool isPartOfExplicitCast() const { return CastExprBits.PartOfExplicitCast; }
setIsPartOfExplicitCast(bool PartOfExplicitCast)36580b57cec5SDimitry Andric   void setIsPartOfExplicitCast(bool PartOfExplicitCast) {
36590b57cec5SDimitry Andric     CastExprBits.PartOfExplicitCast = PartOfExplicitCast;
36600b57cec5SDimitry Andric   }
36610b57cec5SDimitry Andric 
36620b57cec5SDimitry Andric   static ImplicitCastExpr *Create(const ASTContext &Context, QualType T,
36630b57cec5SDimitry Andric                                   CastKind Kind, Expr *Operand,
36640b57cec5SDimitry Andric                                   const CXXCastPath *BasePath,
3665e8d8bef9SDimitry Andric                                   ExprValueKind Cat, FPOptionsOverride FPO);
36660b57cec5SDimitry Andric 
36670b57cec5SDimitry Andric   static ImplicitCastExpr *CreateEmpty(const ASTContext &Context,
3668e8d8bef9SDimitry Andric                                        unsigned PathSize, bool HasFPFeatures);
36690b57cec5SDimitry Andric 
getBeginLoc()36700b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY {
36710b57cec5SDimitry Andric     return getSubExpr()->getBeginLoc();
36720b57cec5SDimitry Andric   }
getEndLoc()36730b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY {
36740b57cec5SDimitry Andric     return getSubExpr()->getEndLoc();
36750b57cec5SDimitry Andric   }
36760b57cec5SDimitry Andric 
classof(const Stmt * T)36770b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
36780b57cec5SDimitry Andric     return T->getStmtClass() == ImplicitCastExprClass;
36790b57cec5SDimitry Andric   }
36800b57cec5SDimitry Andric 
36810b57cec5SDimitry Andric   friend TrailingObjects;
36820b57cec5SDimitry Andric   friend class CastExpr;
36830b57cec5SDimitry Andric };
36840b57cec5SDimitry Andric 
36850b57cec5SDimitry Andric /// ExplicitCastExpr - An explicit cast written in the source
36860b57cec5SDimitry Andric /// code.
36870b57cec5SDimitry Andric ///
36880b57cec5SDimitry Andric /// This class is effectively an abstract class, because it provides
36890b57cec5SDimitry Andric /// the basic representation of an explicitly-written cast without
36900b57cec5SDimitry Andric /// specifying which kind of cast (C cast, functional cast, static
36910b57cec5SDimitry Andric /// cast, etc.) was written; specific derived classes represent the
36920b57cec5SDimitry Andric /// particular style of cast and its location information.
36930b57cec5SDimitry Andric ///
36940b57cec5SDimitry Andric /// Unlike implicit casts, explicit cast nodes have two different
36950b57cec5SDimitry Andric /// types: the type that was written into the source code, and the
36960b57cec5SDimitry Andric /// actual type of the expression as determined by semantic
36970b57cec5SDimitry Andric /// analysis. These types may differ slightly. For example, in C++ one
36980b57cec5SDimitry Andric /// can cast to a reference type, which indicates that the resulting
36990b57cec5SDimitry Andric /// expression will be an lvalue or xvalue. The reference type, however,
37000b57cec5SDimitry Andric /// will not be used as the type of the expression.
37010b57cec5SDimitry Andric class ExplicitCastExpr : public CastExpr {
37020b57cec5SDimitry Andric   /// TInfo - Source type info for the (written) type
37030b57cec5SDimitry Andric   /// this expression is casting to.
37040b57cec5SDimitry Andric   TypeSourceInfo *TInfo;
37050b57cec5SDimitry Andric 
37060b57cec5SDimitry Andric protected:
ExplicitCastExpr(StmtClass SC,QualType exprTy,ExprValueKind VK,CastKind kind,Expr * op,unsigned PathSize,bool HasFPFeatures,TypeSourceInfo * writtenTy)37070b57cec5SDimitry Andric   ExplicitCastExpr(StmtClass SC, QualType exprTy, ExprValueKind VK,
37080b57cec5SDimitry Andric                    CastKind kind, Expr *op, unsigned PathSize,
3709e8d8bef9SDimitry Andric                    bool HasFPFeatures, TypeSourceInfo *writtenTy)
3710e8d8bef9SDimitry Andric       : CastExpr(SC, exprTy, VK, kind, op, PathSize, HasFPFeatures),
37113b7f365eSDimitry Andric         TInfo(writtenTy) {
37123b7f365eSDimitry Andric     setDependence(computeDependence(this));
37133b7f365eSDimitry Andric   }
37140b57cec5SDimitry Andric 
37150b57cec5SDimitry Andric   /// Construct an empty explicit cast.
ExplicitCastExpr(StmtClass SC,EmptyShell Shell,unsigned PathSize,bool HasFPFeatures)3716e8d8bef9SDimitry Andric   ExplicitCastExpr(StmtClass SC, EmptyShell Shell, unsigned PathSize,
3717e8d8bef9SDimitry Andric                    bool HasFPFeatures)
3718e8d8bef9SDimitry Andric       : CastExpr(SC, Shell, PathSize, HasFPFeatures) {}
37190b57cec5SDimitry Andric 
37200b57cec5SDimitry Andric public:
37210b57cec5SDimitry Andric   /// getTypeInfoAsWritten - Returns the type source info for the type
37220b57cec5SDimitry Andric   /// that this expression is casting to.
getTypeInfoAsWritten()37230b57cec5SDimitry Andric   TypeSourceInfo *getTypeInfoAsWritten() const { return TInfo; }
setTypeInfoAsWritten(TypeSourceInfo * writtenTy)37240b57cec5SDimitry Andric   void setTypeInfoAsWritten(TypeSourceInfo *writtenTy) { TInfo = writtenTy; }
37250b57cec5SDimitry Andric 
37260b57cec5SDimitry Andric   /// getTypeAsWritten - Returns the type that this expression is
37270b57cec5SDimitry Andric   /// casting to, as written in the source code.
getTypeAsWritten()37280b57cec5SDimitry Andric   QualType getTypeAsWritten() const { return TInfo->getType(); }
37290b57cec5SDimitry Andric 
classof(const Stmt * T)37300b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
37310b57cec5SDimitry Andric      return T->getStmtClass() >= firstExplicitCastExprConstant &&
37320b57cec5SDimitry Andric             T->getStmtClass() <= lastExplicitCastExprConstant;
37330b57cec5SDimitry Andric   }
37340b57cec5SDimitry Andric };
37350b57cec5SDimitry Andric 
37360b57cec5SDimitry Andric /// CStyleCastExpr - An explicit cast in C (C99 6.5.4) or a C-style
37370b57cec5SDimitry Andric /// cast in C++ (C++ [expr.cast]), which uses the syntax
37380b57cec5SDimitry Andric /// (Type)expr. For example: @c (int)f.
37390b57cec5SDimitry Andric class CStyleCastExpr final
37400b57cec5SDimitry Andric     : public ExplicitCastExpr,
3741e8d8bef9SDimitry Andric       private llvm::TrailingObjects<CStyleCastExpr, CXXBaseSpecifier *,
3742e8d8bef9SDimitry Andric                                     FPOptionsOverride> {
37430b57cec5SDimitry Andric   SourceLocation LPLoc; // the location of the left paren
37440b57cec5SDimitry Andric   SourceLocation RPLoc; // the location of the right paren
37450b57cec5SDimitry Andric 
CStyleCastExpr(QualType exprTy,ExprValueKind vk,CastKind kind,Expr * op,unsigned PathSize,FPOptionsOverride FPO,TypeSourceInfo * writtenTy,SourceLocation l,SourceLocation r)37460b57cec5SDimitry Andric   CStyleCastExpr(QualType exprTy, ExprValueKind vk, CastKind kind, Expr *op,
3747e8d8bef9SDimitry Andric                  unsigned PathSize, FPOptionsOverride FPO,
3748e8d8bef9SDimitry Andric                  TypeSourceInfo *writtenTy, SourceLocation l, SourceLocation r)
37490b57cec5SDimitry Andric       : ExplicitCastExpr(CStyleCastExprClass, exprTy, vk, kind, op, PathSize,
3750e8d8bef9SDimitry Andric                          FPO.requiresTrailingStorage(), writtenTy),
3751e8d8bef9SDimitry Andric         LPLoc(l), RPLoc(r) {
3752e8d8bef9SDimitry Andric     if (hasStoredFPFeatures())
3753e8d8bef9SDimitry Andric       *getTrailingFPFeatures() = FPO;
3754e8d8bef9SDimitry Andric   }
37550b57cec5SDimitry Andric 
37560b57cec5SDimitry Andric   /// Construct an empty C-style explicit cast.
CStyleCastExpr(EmptyShell Shell,unsigned PathSize,bool HasFPFeatures)3757e8d8bef9SDimitry Andric   explicit CStyleCastExpr(EmptyShell Shell, unsigned PathSize,
3758e8d8bef9SDimitry Andric                           bool HasFPFeatures)
3759e8d8bef9SDimitry Andric       : ExplicitCastExpr(CStyleCastExprClass, Shell, PathSize, HasFPFeatures) {}
3760e8d8bef9SDimitry Andric 
numTrailingObjects(OverloadToken<CXXBaseSpecifier * >)3761e8d8bef9SDimitry Andric   unsigned numTrailingObjects(OverloadToken<CXXBaseSpecifier *>) const {
3762e8d8bef9SDimitry Andric     return path_size();
3763e8d8bef9SDimitry Andric   }
37640b57cec5SDimitry Andric 
37650b57cec5SDimitry Andric public:
3766e8d8bef9SDimitry Andric   static CStyleCastExpr *
3767e8d8bef9SDimitry Andric   Create(const ASTContext &Context, QualType T, ExprValueKind VK, CastKind K,
3768e8d8bef9SDimitry Andric          Expr *Op, const CXXCastPath *BasePath, FPOptionsOverride FPO,
3769e8d8bef9SDimitry Andric          TypeSourceInfo *WrittenTy, SourceLocation L, SourceLocation R);
37700b57cec5SDimitry Andric 
37710b57cec5SDimitry Andric   static CStyleCastExpr *CreateEmpty(const ASTContext &Context,
3772e8d8bef9SDimitry Andric                                      unsigned PathSize, bool HasFPFeatures);
37730b57cec5SDimitry Andric 
getLParenLoc()37740b57cec5SDimitry Andric   SourceLocation getLParenLoc() const { return LPLoc; }
setLParenLoc(SourceLocation L)37750b57cec5SDimitry Andric   void setLParenLoc(SourceLocation L) { LPLoc = L; }
37760b57cec5SDimitry Andric 
getRParenLoc()37770b57cec5SDimitry Andric   SourceLocation getRParenLoc() const { return RPLoc; }
setRParenLoc(SourceLocation L)37780b57cec5SDimitry Andric   void setRParenLoc(SourceLocation L) { RPLoc = L; }
37790b57cec5SDimitry Andric 
getBeginLoc()37800b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY { return LPLoc; }
getEndLoc()37810b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY {
37820b57cec5SDimitry Andric     return getSubExpr()->getEndLoc();
37830b57cec5SDimitry Andric   }
37840b57cec5SDimitry Andric 
classof(const Stmt * T)37850b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
37860b57cec5SDimitry Andric     return T->getStmtClass() == CStyleCastExprClass;
37870b57cec5SDimitry Andric   }
37880b57cec5SDimitry Andric 
37890b57cec5SDimitry Andric   friend TrailingObjects;
37900b57cec5SDimitry Andric   friend class CastExpr;
37910b57cec5SDimitry Andric };
37920b57cec5SDimitry Andric 
37930b57cec5SDimitry Andric /// A builtin binary operation expression such as "x + y" or "x <= y".
37940b57cec5SDimitry Andric ///
37950b57cec5SDimitry Andric /// This expression node kind describes a builtin binary operation,
37960b57cec5SDimitry Andric /// such as "x + y" for integer values "x" and "y". The operands will
37970b57cec5SDimitry Andric /// already have been converted to appropriate types (e.g., by
37980b57cec5SDimitry Andric /// performing promotions or conversions).
37990b57cec5SDimitry Andric ///
38000b57cec5SDimitry Andric /// In C++, where operators may be overloaded, a different kind of
38010b57cec5SDimitry Andric /// expression node (CXXOperatorCallExpr) is used to express the
38020b57cec5SDimitry Andric /// invocation of an overloaded operator with operator syntax. Within
38030b57cec5SDimitry Andric /// a C++ template, whether BinaryOperator or CXXOperatorCallExpr is
38040b57cec5SDimitry Andric /// used to store an expression "x + y" depends on the subexpressions
38050b57cec5SDimitry Andric /// for x and y. If neither x or y is type-dependent, and the "+"
38060b57cec5SDimitry Andric /// operator resolves to a built-in operation, BinaryOperator will be
38070b57cec5SDimitry Andric /// used to express the computation (x and y may still be
38080b57cec5SDimitry Andric /// value-dependent). If either x or y is type-dependent, or if the
38090b57cec5SDimitry Andric /// "+" resolves to an overloaded operator, CXXOperatorCallExpr will
38100b57cec5SDimitry Andric /// be used to express the computation.
38110b57cec5SDimitry Andric class BinaryOperator : public Expr {
38120b57cec5SDimitry Andric   enum { LHS, RHS, END_EXPR };
38130b57cec5SDimitry Andric   Stmt *SubExprs[END_EXPR];
38140b57cec5SDimitry Andric 
38150b57cec5SDimitry Andric public:
38160b57cec5SDimitry Andric   typedef BinaryOperatorKind Opcode;
38170b57cec5SDimitry Andric 
38185ffd83dbSDimitry Andric protected:
38195ffd83dbSDimitry Andric   size_t offsetOfTrailingStorage() const;
38205ffd83dbSDimitry Andric 
38215ffd83dbSDimitry Andric   /// Return a pointer to the trailing FPOptions
getTrailingFPFeatures()38225ffd83dbSDimitry Andric   FPOptionsOverride *getTrailingFPFeatures() {
38235ffd83dbSDimitry Andric     assert(BinaryOperatorBits.HasFPFeatures);
38245ffd83dbSDimitry Andric     return reinterpret_cast<FPOptionsOverride *>(
38255ffd83dbSDimitry Andric         reinterpret_cast<char *>(this) + offsetOfTrailingStorage());
38260b57cec5SDimitry Andric   }
getTrailingFPFeatures()38275ffd83dbSDimitry Andric   const FPOptionsOverride *getTrailingFPFeatures() const {
38285ffd83dbSDimitry Andric     assert(BinaryOperatorBits.HasFPFeatures);
38295ffd83dbSDimitry Andric     return reinterpret_cast<const FPOptionsOverride *>(
38305ffd83dbSDimitry Andric         reinterpret_cast<const char *>(this) + offsetOfTrailingStorage());
38315ffd83dbSDimitry Andric   }
38325ffd83dbSDimitry Andric 
38335ffd83dbSDimitry Andric   /// Build a binary operator, assuming that appropriate storage has been
38345ffd83dbSDimitry Andric   /// allocated for the trailing objects when needed.
38355ffd83dbSDimitry Andric   BinaryOperator(const ASTContext &Ctx, Expr *lhs, Expr *rhs, Opcode opc,
38365ffd83dbSDimitry Andric                  QualType ResTy, ExprValueKind VK, ExprObjectKind OK,
38375ffd83dbSDimitry Andric                  SourceLocation opLoc, FPOptionsOverride FPFeatures);
38380b57cec5SDimitry Andric 
38390b57cec5SDimitry Andric   /// Construct an empty binary operator.
BinaryOperator(EmptyShell Empty)38400b57cec5SDimitry Andric   explicit BinaryOperator(EmptyShell Empty) : Expr(BinaryOperatorClass, Empty) {
38410b57cec5SDimitry Andric     BinaryOperatorBits.Opc = BO_Comma;
38420b57cec5SDimitry Andric   }
38430b57cec5SDimitry Andric 
38445ffd83dbSDimitry Andric public:
38455ffd83dbSDimitry Andric   static BinaryOperator *CreateEmpty(const ASTContext &C, bool hasFPFeatures);
38465ffd83dbSDimitry Andric 
38475ffd83dbSDimitry Andric   static BinaryOperator *Create(const ASTContext &C, Expr *lhs, Expr *rhs,
38485ffd83dbSDimitry Andric                                 Opcode opc, QualType ResTy, ExprValueKind VK,
38495ffd83dbSDimitry Andric                                 ExprObjectKind OK, SourceLocation opLoc,
38505ffd83dbSDimitry Andric                                 FPOptionsOverride FPFeatures);
getExprLoc()38510b57cec5SDimitry Andric   SourceLocation getExprLoc() const { return getOperatorLoc(); }
getOperatorLoc()38520b57cec5SDimitry Andric   SourceLocation getOperatorLoc() const { return BinaryOperatorBits.OpLoc; }
setOperatorLoc(SourceLocation L)38530b57cec5SDimitry Andric   void setOperatorLoc(SourceLocation L) { BinaryOperatorBits.OpLoc = L; }
38540b57cec5SDimitry Andric 
getOpcode()38550b57cec5SDimitry Andric   Opcode getOpcode() const {
38560b57cec5SDimitry Andric     return static_cast<Opcode>(BinaryOperatorBits.Opc);
38570b57cec5SDimitry Andric   }
setOpcode(Opcode Opc)38580b57cec5SDimitry Andric   void setOpcode(Opcode Opc) { BinaryOperatorBits.Opc = Opc; }
38590b57cec5SDimitry Andric 
getLHS()38600b57cec5SDimitry Andric   Expr *getLHS() const { return cast<Expr>(SubExprs[LHS]); }
setLHS(Expr * E)38610b57cec5SDimitry Andric   void setLHS(Expr *E) { SubExprs[LHS] = E; }
getRHS()38620b57cec5SDimitry Andric   Expr *getRHS() const { return cast<Expr>(SubExprs[RHS]); }
setRHS(Expr * E)38630b57cec5SDimitry Andric   void setRHS(Expr *E) { SubExprs[RHS] = E; }
38640b57cec5SDimitry Andric 
getBeginLoc()38650b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY {
38660b57cec5SDimitry Andric     return getLHS()->getBeginLoc();
38670b57cec5SDimitry Andric   }
getEndLoc()38680b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY {
38690b57cec5SDimitry Andric     return getRHS()->getEndLoc();
38700b57cec5SDimitry Andric   }
38710b57cec5SDimitry Andric 
38720b57cec5SDimitry Andric   /// getOpcodeStr - Turn an Opcode enum value into the punctuation char it
38730b57cec5SDimitry Andric   /// corresponds to, e.g. "<<=".
38740b57cec5SDimitry Andric   static StringRef getOpcodeStr(Opcode Op);
38750b57cec5SDimitry Andric 
getOpcodeStr()38760b57cec5SDimitry Andric   StringRef getOpcodeStr() const { return getOpcodeStr(getOpcode()); }
38770b57cec5SDimitry Andric 
38780b57cec5SDimitry Andric   /// Retrieve the binary opcode that corresponds to the given
38790b57cec5SDimitry Andric   /// overloaded operator.
38800b57cec5SDimitry Andric   static Opcode getOverloadedOpcode(OverloadedOperatorKind OO);
38810b57cec5SDimitry Andric 
38820b57cec5SDimitry Andric   /// Retrieve the overloaded operator kind that corresponds to
38830b57cec5SDimitry Andric   /// the given binary opcode.
38840b57cec5SDimitry Andric   static OverloadedOperatorKind getOverloadedOperator(Opcode Opc);
38850b57cec5SDimitry Andric 
38860b57cec5SDimitry Andric   /// predicates to categorize the respective opcodes.
isPtrMemOp(Opcode Opc)38870b57cec5SDimitry Andric   static bool isPtrMemOp(Opcode Opc) {
38880b57cec5SDimitry Andric     return Opc == BO_PtrMemD || Opc == BO_PtrMemI;
38890b57cec5SDimitry Andric   }
isPtrMemOp()38900b57cec5SDimitry Andric   bool isPtrMemOp() const { return isPtrMemOp(getOpcode()); }
38910b57cec5SDimitry Andric 
isMultiplicativeOp(Opcode Opc)38920b57cec5SDimitry Andric   static bool isMultiplicativeOp(Opcode Opc) {
38930b57cec5SDimitry Andric     return Opc >= BO_Mul && Opc <= BO_Rem;
38940b57cec5SDimitry Andric   }
isMultiplicativeOp()38950b57cec5SDimitry Andric   bool isMultiplicativeOp() const { return isMultiplicativeOp(getOpcode()); }
isAdditiveOp(Opcode Opc)38960b57cec5SDimitry Andric   static bool isAdditiveOp(Opcode Opc) { return Opc == BO_Add || Opc==BO_Sub; }
isAdditiveOp()38970b57cec5SDimitry Andric   bool isAdditiveOp() const { return isAdditiveOp(getOpcode()); }
isShiftOp(Opcode Opc)38980b57cec5SDimitry Andric   static bool isShiftOp(Opcode Opc) { return Opc == BO_Shl || Opc == BO_Shr; }
isShiftOp()38990b57cec5SDimitry Andric   bool isShiftOp() const { return isShiftOp(getOpcode()); }
39000b57cec5SDimitry Andric 
isBitwiseOp(Opcode Opc)39010b57cec5SDimitry Andric   static bool isBitwiseOp(Opcode Opc) { return Opc >= BO_And && Opc <= BO_Or; }
isBitwiseOp()39020b57cec5SDimitry Andric   bool isBitwiseOp() const { return isBitwiseOp(getOpcode()); }
39030b57cec5SDimitry Andric 
isRelationalOp(Opcode Opc)39040b57cec5SDimitry Andric   static bool isRelationalOp(Opcode Opc) { return Opc >= BO_LT && Opc<=BO_GE; }
isRelationalOp()39050b57cec5SDimitry Andric   bool isRelationalOp() const { return isRelationalOp(getOpcode()); }
39060b57cec5SDimitry Andric 
isEqualityOp(Opcode Opc)39070b57cec5SDimitry Andric   static bool isEqualityOp(Opcode Opc) { return Opc == BO_EQ || Opc == BO_NE; }
isEqualityOp()39080b57cec5SDimitry Andric   bool isEqualityOp() const { return isEqualityOp(getOpcode()); }
39090b57cec5SDimitry Andric 
isComparisonOp(Opcode Opc)39100b57cec5SDimitry Andric   static bool isComparisonOp(Opcode Opc) { return Opc >= BO_Cmp && Opc<=BO_NE; }
isComparisonOp()39110b57cec5SDimitry Andric   bool isComparisonOp() const { return isComparisonOp(getOpcode()); }
39120b57cec5SDimitry Andric 
isCommaOp(Opcode Opc)39130b57cec5SDimitry Andric   static bool isCommaOp(Opcode Opc) { return Opc == BO_Comma; }
isCommaOp()39140b57cec5SDimitry Andric   bool isCommaOp() const { return isCommaOp(getOpcode()); }
39150b57cec5SDimitry Andric 
negateComparisonOp(Opcode Opc)39160b57cec5SDimitry Andric   static Opcode negateComparisonOp(Opcode Opc) {
39170b57cec5SDimitry Andric     switch (Opc) {
39180b57cec5SDimitry Andric     default:
39190b57cec5SDimitry Andric       llvm_unreachable("Not a comparison operator.");
39200b57cec5SDimitry Andric     case BO_LT: return BO_GE;
39210b57cec5SDimitry Andric     case BO_GT: return BO_LE;
39220b57cec5SDimitry Andric     case BO_LE: return BO_GT;
39230b57cec5SDimitry Andric     case BO_GE: return BO_LT;
39240b57cec5SDimitry Andric     case BO_EQ: return BO_NE;
39250b57cec5SDimitry Andric     case BO_NE: return BO_EQ;
39260b57cec5SDimitry Andric     }
39270b57cec5SDimitry Andric   }
39280b57cec5SDimitry Andric 
reverseComparisonOp(Opcode Opc)39290b57cec5SDimitry Andric   static Opcode reverseComparisonOp(Opcode Opc) {
39300b57cec5SDimitry Andric     switch (Opc) {
39310b57cec5SDimitry Andric     default:
39320b57cec5SDimitry Andric       llvm_unreachable("Not a comparison operator.");
39330b57cec5SDimitry Andric     case BO_LT: return BO_GT;
39340b57cec5SDimitry Andric     case BO_GT: return BO_LT;
39350b57cec5SDimitry Andric     case BO_LE: return BO_GE;
39360b57cec5SDimitry Andric     case BO_GE: return BO_LE;
39370b57cec5SDimitry Andric     case BO_EQ:
39380b57cec5SDimitry Andric     case BO_NE:
39390b57cec5SDimitry Andric       return Opc;
39400b57cec5SDimitry Andric     }
39410b57cec5SDimitry Andric   }
39420b57cec5SDimitry Andric 
isLogicalOp(Opcode Opc)39430b57cec5SDimitry Andric   static bool isLogicalOp(Opcode Opc) { return Opc == BO_LAnd || Opc==BO_LOr; }
isLogicalOp()39440b57cec5SDimitry Andric   bool isLogicalOp() const { return isLogicalOp(getOpcode()); }
39450b57cec5SDimitry Andric 
isAssignmentOp(Opcode Opc)39460b57cec5SDimitry Andric   static bool isAssignmentOp(Opcode Opc) {
39470b57cec5SDimitry Andric     return Opc >= BO_Assign && Opc <= BO_OrAssign;
39480b57cec5SDimitry Andric   }
isAssignmentOp()39490b57cec5SDimitry Andric   bool isAssignmentOp() const { return isAssignmentOp(getOpcode()); }
39500b57cec5SDimitry Andric 
isCompoundAssignmentOp(Opcode Opc)39510b57cec5SDimitry Andric   static bool isCompoundAssignmentOp(Opcode Opc) {
39520b57cec5SDimitry Andric     return Opc > BO_Assign && Opc <= BO_OrAssign;
39530b57cec5SDimitry Andric   }
isCompoundAssignmentOp()39540b57cec5SDimitry Andric   bool isCompoundAssignmentOp() const {
39550b57cec5SDimitry Andric     return isCompoundAssignmentOp(getOpcode());
39560b57cec5SDimitry Andric   }
getOpForCompoundAssignment(Opcode Opc)39570b57cec5SDimitry Andric   static Opcode getOpForCompoundAssignment(Opcode Opc) {
39580b57cec5SDimitry Andric     assert(isCompoundAssignmentOp(Opc));
39590b57cec5SDimitry Andric     if (Opc >= BO_AndAssign)
39600b57cec5SDimitry Andric       return Opcode(unsigned(Opc) - BO_AndAssign + BO_And);
39610b57cec5SDimitry Andric     else
39620b57cec5SDimitry Andric       return Opcode(unsigned(Opc) - BO_MulAssign + BO_Mul);
39630b57cec5SDimitry Andric   }
39640b57cec5SDimitry Andric 
isShiftAssignOp(Opcode Opc)39650b57cec5SDimitry Andric   static bool isShiftAssignOp(Opcode Opc) {
39660b57cec5SDimitry Andric     return Opc == BO_ShlAssign || Opc == BO_ShrAssign;
39670b57cec5SDimitry Andric   }
isShiftAssignOp()39680b57cec5SDimitry Andric   bool isShiftAssignOp() const {
39690b57cec5SDimitry Andric     return isShiftAssignOp(getOpcode());
39700b57cec5SDimitry Andric   }
39710b57cec5SDimitry Andric 
397206c3fb27SDimitry Andric   /// Return true if a binary operator using the specified opcode and operands
397306c3fb27SDimitry Andric   /// would match the 'p = (i8*)nullptr + n' idiom for casting a pointer-sized
397406c3fb27SDimitry Andric   /// integer to a pointer.
39750b57cec5SDimitry Andric   static bool isNullPointerArithmeticExtension(ASTContext &Ctx, Opcode Opc,
397606c3fb27SDimitry Andric                                                const Expr *LHS,
397706c3fb27SDimitry Andric                                                const Expr *RHS);
39780b57cec5SDimitry Andric 
classof(const Stmt * S)39790b57cec5SDimitry Andric   static bool classof(const Stmt *S) {
39800b57cec5SDimitry Andric     return S->getStmtClass() >= firstBinaryOperatorConstant &&
39810b57cec5SDimitry Andric            S->getStmtClass() <= lastBinaryOperatorConstant;
39820b57cec5SDimitry Andric   }
39830b57cec5SDimitry Andric 
39840b57cec5SDimitry Andric   // Iterators
children()39850b57cec5SDimitry Andric   child_range children() {
39860b57cec5SDimitry Andric     return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
39870b57cec5SDimitry Andric   }
children()39880b57cec5SDimitry Andric   const_child_range children() const {
39890b57cec5SDimitry Andric     return const_child_range(&SubExprs[0], &SubExprs[0] + END_EXPR);
39900b57cec5SDimitry Andric   }
39910b57cec5SDimitry Andric 
39925ffd83dbSDimitry Andric   /// Set and fetch the bit that shows whether FPFeatures needs to be
39935ffd83dbSDimitry Andric   /// allocated in Trailing Storage
setHasStoredFPFeatures(bool B)39945ffd83dbSDimitry Andric   void setHasStoredFPFeatures(bool B) { BinaryOperatorBits.HasFPFeatures = B; }
hasStoredFPFeatures()39955ffd83dbSDimitry Andric   bool hasStoredFPFeatures() const { return BinaryOperatorBits.HasFPFeatures; }
39965ffd83dbSDimitry Andric 
39975ffd83dbSDimitry Andric   /// Get FPFeatures from trailing storage
getStoredFPFeatures()39985ffd83dbSDimitry Andric   FPOptionsOverride getStoredFPFeatures() const {
39995ffd83dbSDimitry Andric     assert(hasStoredFPFeatures());
40005ffd83dbSDimitry Andric     return *getTrailingFPFeatures();
40015ffd83dbSDimitry Andric   }
40025ffd83dbSDimitry Andric   /// Set FPFeatures in trailing storage, used only by Serialization
setStoredFPFeatures(FPOptionsOverride F)40035ffd83dbSDimitry Andric   void setStoredFPFeatures(FPOptionsOverride F) {
40045ffd83dbSDimitry Andric     assert(BinaryOperatorBits.HasFPFeatures);
40055ffd83dbSDimitry Andric     *getTrailingFPFeatures() = F;
40060b57cec5SDimitry Andric   }
40070b57cec5SDimitry Andric 
400806c3fb27SDimitry Andric   /// Get the FP features status of this operator. Only meaningful for
400906c3fb27SDimitry Andric   /// operations on floating point types.
getFPFeaturesInEffect(const LangOptions & LO)40105ffd83dbSDimitry Andric   FPOptions getFPFeaturesInEffect(const LangOptions &LO) const {
40115ffd83dbSDimitry Andric     if (BinaryOperatorBits.HasFPFeatures)
40125ffd83dbSDimitry Andric       return getStoredFPFeatures().applyOverrides(LO);
40135ffd83dbSDimitry Andric     return FPOptions::defaultWithoutTrailingStorage(LO);
40145ffd83dbSDimitry Andric   }
40155ffd83dbSDimitry Andric 
40165ffd83dbSDimitry Andric   // This is used in ASTImporter
getFPFeatures()4017bdd1243dSDimitry Andric   FPOptionsOverride getFPFeatures() const {
40185ffd83dbSDimitry Andric     if (BinaryOperatorBits.HasFPFeatures)
40195ffd83dbSDimitry Andric       return getStoredFPFeatures();
40205ffd83dbSDimitry Andric     return FPOptionsOverride();
40210b57cec5SDimitry Andric   }
40220b57cec5SDimitry Andric 
402306c3fb27SDimitry Andric   /// Get the FP contractability status of this operator. Only meaningful for
402406c3fb27SDimitry Andric   /// operations on floating point types.
isFPContractableWithinStatement(const LangOptions & LO)40255ffd83dbSDimitry Andric   bool isFPContractableWithinStatement(const LangOptions &LO) const {
40265ffd83dbSDimitry Andric     return getFPFeaturesInEffect(LO).allowFPContractWithinStatement();
40270b57cec5SDimitry Andric   }
40280b57cec5SDimitry Andric 
402906c3fb27SDimitry Andric   /// Get the FENV_ACCESS status of this operator. Only meaningful for
403006c3fb27SDimitry Andric   /// operations on floating point types.
isFEnvAccessOn(const LangOptions & LO)40315ffd83dbSDimitry Andric   bool isFEnvAccessOn(const LangOptions &LO) const {
40325ffd83dbSDimitry Andric     return getFPFeaturesInEffect(LO).getAllowFEnvAccess();
40330b57cec5SDimitry Andric   }
40340b57cec5SDimitry Andric 
40355ffd83dbSDimitry Andric protected:
40365ffd83dbSDimitry Andric   BinaryOperator(const ASTContext &Ctx, Expr *lhs, Expr *rhs, Opcode opc,
40375ffd83dbSDimitry Andric                  QualType ResTy, ExprValueKind VK, ExprObjectKind OK,
40385ffd83dbSDimitry Andric                  SourceLocation opLoc, FPOptionsOverride FPFeatures,
40395ffd83dbSDimitry Andric                  bool dead2);
40405ffd83dbSDimitry Andric 
40415ffd83dbSDimitry Andric   /// Construct an empty BinaryOperator, SC is CompoundAssignOperator.
BinaryOperator(StmtClass SC,EmptyShell Empty)40420b57cec5SDimitry Andric   BinaryOperator(StmtClass SC, EmptyShell Empty) : Expr(SC, Empty) {
40430b57cec5SDimitry Andric     BinaryOperatorBits.Opc = BO_MulAssign;
40440b57cec5SDimitry Andric   }
40455ffd83dbSDimitry Andric 
40465ffd83dbSDimitry Andric   /// Return the size in bytes needed for the trailing objects.
40475ffd83dbSDimitry Andric   /// Used to allocate the right amount of storage.
sizeOfTrailingObjects(bool HasFPFeatures)40485ffd83dbSDimitry Andric   static unsigned sizeOfTrailingObjects(bool HasFPFeatures) {
40495ffd83dbSDimitry Andric     return HasFPFeatures * sizeof(FPOptionsOverride);
40505ffd83dbSDimitry Andric   }
40510b57cec5SDimitry Andric };
40520b57cec5SDimitry Andric 
40530b57cec5SDimitry Andric /// CompoundAssignOperator - For compound assignments (e.g. +=), we keep
40540b57cec5SDimitry Andric /// track of the type the operation is performed in.  Due to the semantics of
40550b57cec5SDimitry Andric /// these operators, the operands are promoted, the arithmetic performed, an
40560b57cec5SDimitry Andric /// implicit conversion back to the result type done, then the assignment takes
40570b57cec5SDimitry Andric /// place.  This captures the intermediate type which the computation is done
40580b57cec5SDimitry Andric /// in.
40590b57cec5SDimitry Andric class CompoundAssignOperator : public BinaryOperator {
40600b57cec5SDimitry Andric   QualType ComputationLHSType;
40610b57cec5SDimitry Andric   QualType ComputationResultType;
40625ffd83dbSDimitry Andric 
40635ffd83dbSDimitry Andric   /// Construct an empty CompoundAssignOperator.
CompoundAssignOperator(const ASTContext & C,EmptyShell Empty,bool hasFPFeatures)40645ffd83dbSDimitry Andric   explicit CompoundAssignOperator(const ASTContext &C, EmptyShell Empty,
40655ffd83dbSDimitry Andric                                   bool hasFPFeatures)
40665ffd83dbSDimitry Andric       : BinaryOperator(CompoundAssignOperatorClass, Empty) {}
40675ffd83dbSDimitry Andric 
40685ffd83dbSDimitry Andric protected:
CompoundAssignOperator(const ASTContext & C,Expr * lhs,Expr * rhs,Opcode opc,QualType ResType,ExprValueKind VK,ExprObjectKind OK,SourceLocation OpLoc,FPOptionsOverride FPFeatures,QualType CompLHSType,QualType CompResultType)40695ffd83dbSDimitry Andric   CompoundAssignOperator(const ASTContext &C, Expr *lhs, Expr *rhs, Opcode opc,
40705ffd83dbSDimitry Andric                          QualType ResType, ExprValueKind VK, ExprObjectKind OK,
40715ffd83dbSDimitry Andric                          SourceLocation OpLoc, FPOptionsOverride FPFeatures,
40725ffd83dbSDimitry Andric                          QualType CompLHSType, QualType CompResultType)
40735ffd83dbSDimitry Andric       : BinaryOperator(C, lhs, rhs, opc, ResType, VK, OK, OpLoc, FPFeatures,
40740b57cec5SDimitry Andric                        true),
40755ffd83dbSDimitry Andric         ComputationLHSType(CompLHSType), ComputationResultType(CompResultType) {
40760b57cec5SDimitry Andric     assert(isCompoundAssignmentOp() &&
40770b57cec5SDimitry Andric            "Only should be used for compound assignments");
40780b57cec5SDimitry Andric   }
40790b57cec5SDimitry Andric 
40805ffd83dbSDimitry Andric public:
40815ffd83dbSDimitry Andric   static CompoundAssignOperator *CreateEmpty(const ASTContext &C,
40825ffd83dbSDimitry Andric                                              bool hasFPFeatures);
40835ffd83dbSDimitry Andric 
40845ffd83dbSDimitry Andric   static CompoundAssignOperator *
40855ffd83dbSDimitry Andric   Create(const ASTContext &C, Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy,
40865ffd83dbSDimitry Andric          ExprValueKind VK, ExprObjectKind OK, SourceLocation opLoc,
40875ffd83dbSDimitry Andric          FPOptionsOverride FPFeatures, QualType CompLHSType = QualType(),
40885ffd83dbSDimitry Andric          QualType CompResultType = QualType());
40890b57cec5SDimitry Andric 
40900b57cec5SDimitry Andric   // The two computation types are the type the LHS is converted
40910b57cec5SDimitry Andric   // to for the computation and the type of the result; the two are
40920b57cec5SDimitry Andric   // distinct in a few cases (specifically, int+=ptr and ptr-=ptr).
getComputationLHSType()40930b57cec5SDimitry Andric   QualType getComputationLHSType() const { return ComputationLHSType; }
setComputationLHSType(QualType T)40940b57cec5SDimitry Andric   void setComputationLHSType(QualType T) { ComputationLHSType = T; }
40950b57cec5SDimitry Andric 
getComputationResultType()40960b57cec5SDimitry Andric   QualType getComputationResultType() const { return ComputationResultType; }
setComputationResultType(QualType T)40970b57cec5SDimitry Andric   void setComputationResultType(QualType T) { ComputationResultType = T; }
40980b57cec5SDimitry Andric 
classof(const Stmt * S)40990b57cec5SDimitry Andric   static bool classof(const Stmt *S) {
41000b57cec5SDimitry Andric     return S->getStmtClass() == CompoundAssignOperatorClass;
41010b57cec5SDimitry Andric   }
41020b57cec5SDimitry Andric };
41030b57cec5SDimitry Andric 
offsetOfTrailingStorage()41045ffd83dbSDimitry Andric inline size_t BinaryOperator::offsetOfTrailingStorage() const {
41055ffd83dbSDimitry Andric   assert(BinaryOperatorBits.HasFPFeatures);
41065ffd83dbSDimitry Andric   return isa<CompoundAssignOperator>(this) ? sizeof(CompoundAssignOperator)
41075ffd83dbSDimitry Andric                                            : sizeof(BinaryOperator);
41085ffd83dbSDimitry Andric }
41095ffd83dbSDimitry Andric 
41100b57cec5SDimitry Andric /// AbstractConditionalOperator - An abstract base class for
41110b57cec5SDimitry Andric /// ConditionalOperator and BinaryConditionalOperator.
41120b57cec5SDimitry Andric class AbstractConditionalOperator : public Expr {
41130b57cec5SDimitry Andric   SourceLocation QuestionLoc, ColonLoc;
41140b57cec5SDimitry Andric   friend class ASTStmtReader;
41150b57cec5SDimitry Andric 
41160b57cec5SDimitry Andric protected:
AbstractConditionalOperator(StmtClass SC,QualType T,ExprValueKind VK,ExprObjectKind OK,SourceLocation qloc,SourceLocation cloc)41175ffd83dbSDimitry Andric   AbstractConditionalOperator(StmtClass SC, QualType T, ExprValueKind VK,
41185ffd83dbSDimitry Andric                               ExprObjectKind OK, SourceLocation qloc,
41190b57cec5SDimitry Andric                               SourceLocation cloc)
41205ffd83dbSDimitry Andric       : Expr(SC, T, VK, OK), QuestionLoc(qloc), ColonLoc(cloc) {}
41210b57cec5SDimitry Andric 
AbstractConditionalOperator(StmtClass SC,EmptyShell Empty)41220b57cec5SDimitry Andric   AbstractConditionalOperator(StmtClass SC, EmptyShell Empty)
41230b57cec5SDimitry Andric     : Expr(SC, Empty) { }
41240b57cec5SDimitry Andric 
41250b57cec5SDimitry Andric public:
412606c3fb27SDimitry Andric   /// getCond - Return the expression representing the condition for
412706c3fb27SDimitry Andric   ///   the ?: operator.
41280b57cec5SDimitry Andric   Expr *getCond() const;
41290b57cec5SDimitry Andric 
413006c3fb27SDimitry Andric   /// getTrueExpr - Return the subexpression representing the value of
413106c3fb27SDimitry Andric   ///   the expression if the condition evaluates to true.
41320b57cec5SDimitry Andric   Expr *getTrueExpr() const;
41330b57cec5SDimitry Andric 
413406c3fb27SDimitry Andric   /// getFalseExpr - Return the subexpression representing the value of
413506c3fb27SDimitry Andric   ///   the expression if the condition evaluates to false.  This is
413606c3fb27SDimitry Andric   ///   the same as getRHS.
41370b57cec5SDimitry Andric   Expr *getFalseExpr() const;
41380b57cec5SDimitry Andric 
getQuestionLoc()41390b57cec5SDimitry Andric   SourceLocation getQuestionLoc() const { return QuestionLoc; }
getColonLoc()41400b57cec5SDimitry Andric   SourceLocation getColonLoc() const { return ColonLoc; }
41410b57cec5SDimitry Andric 
classof(const Stmt * T)41420b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
41430b57cec5SDimitry Andric     return T->getStmtClass() == ConditionalOperatorClass ||
41440b57cec5SDimitry Andric            T->getStmtClass() == BinaryConditionalOperatorClass;
41450b57cec5SDimitry Andric   }
41460b57cec5SDimitry Andric };
41470b57cec5SDimitry Andric 
41480b57cec5SDimitry Andric /// ConditionalOperator - The ?: ternary operator.  The GNU "missing
41490b57cec5SDimitry Andric /// middle" extension is a BinaryConditionalOperator.
41500b57cec5SDimitry Andric class ConditionalOperator : public AbstractConditionalOperator {
41510b57cec5SDimitry Andric   enum { COND, LHS, RHS, END_EXPR };
41520b57cec5SDimitry Andric   Stmt* SubExprs[END_EXPR]; // Left/Middle/Right hand sides.
41530b57cec5SDimitry Andric 
41540b57cec5SDimitry Andric   friend class ASTStmtReader;
41550b57cec5SDimitry Andric public:
ConditionalOperator(Expr * cond,SourceLocation QLoc,Expr * lhs,SourceLocation CLoc,Expr * rhs,QualType t,ExprValueKind VK,ExprObjectKind OK)41560b57cec5SDimitry Andric   ConditionalOperator(Expr *cond, SourceLocation QLoc, Expr *lhs,
4157480093f4SDimitry Andric                       SourceLocation CLoc, Expr *rhs, QualType t,
4158480093f4SDimitry Andric                       ExprValueKind VK, ExprObjectKind OK)
41595ffd83dbSDimitry Andric       : AbstractConditionalOperator(ConditionalOperatorClass, t, VK, OK, QLoc,
41605ffd83dbSDimitry Andric                                     CLoc) {
41610b57cec5SDimitry Andric     SubExprs[COND] = cond;
41620b57cec5SDimitry Andric     SubExprs[LHS] = lhs;
41630b57cec5SDimitry Andric     SubExprs[RHS] = rhs;
41645ffd83dbSDimitry Andric     setDependence(computeDependence(this));
41650b57cec5SDimitry Andric   }
41660b57cec5SDimitry Andric 
41670b57cec5SDimitry Andric   /// Build an empty conditional operator.
ConditionalOperator(EmptyShell Empty)41680b57cec5SDimitry Andric   explicit ConditionalOperator(EmptyShell Empty)
41690b57cec5SDimitry Andric     : AbstractConditionalOperator(ConditionalOperatorClass, Empty) { }
41700b57cec5SDimitry Andric 
417106c3fb27SDimitry Andric   /// getCond - Return the expression representing the condition for
417206c3fb27SDimitry Andric   ///   the ?: operator.
getCond()41730b57cec5SDimitry Andric   Expr *getCond() const { return cast<Expr>(SubExprs[COND]); }
41740b57cec5SDimitry Andric 
417506c3fb27SDimitry Andric   /// getTrueExpr - Return the subexpression representing the value of
417606c3fb27SDimitry Andric   ///   the expression if the condition evaluates to true.
getTrueExpr()41770b57cec5SDimitry Andric   Expr *getTrueExpr() const { return cast<Expr>(SubExprs[LHS]); }
41780b57cec5SDimitry Andric 
417906c3fb27SDimitry Andric   /// getFalseExpr - Return the subexpression representing the value of
418006c3fb27SDimitry Andric   ///   the expression if the condition evaluates to false.  This is
418106c3fb27SDimitry Andric   ///   the same as getRHS.
getFalseExpr()41820b57cec5SDimitry Andric   Expr *getFalseExpr() const { return cast<Expr>(SubExprs[RHS]); }
41830b57cec5SDimitry Andric 
getLHS()41840b57cec5SDimitry Andric   Expr *getLHS() const { return cast<Expr>(SubExprs[LHS]); }
getRHS()41850b57cec5SDimitry Andric   Expr *getRHS() const { return cast<Expr>(SubExprs[RHS]); }
41860b57cec5SDimitry Andric 
getBeginLoc()41870b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY {
41880b57cec5SDimitry Andric     return getCond()->getBeginLoc();
41890b57cec5SDimitry Andric   }
getEndLoc()41900b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY {
41910b57cec5SDimitry Andric     return getRHS()->getEndLoc();
41920b57cec5SDimitry Andric   }
41930b57cec5SDimitry Andric 
classof(const Stmt * T)41940b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
41950b57cec5SDimitry Andric     return T->getStmtClass() == ConditionalOperatorClass;
41960b57cec5SDimitry Andric   }
41970b57cec5SDimitry Andric 
41980b57cec5SDimitry Andric   // Iterators
children()41990b57cec5SDimitry Andric   child_range children() {
42000b57cec5SDimitry Andric     return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
42010b57cec5SDimitry Andric   }
children()42020b57cec5SDimitry Andric   const_child_range children() const {
42030b57cec5SDimitry Andric     return const_child_range(&SubExprs[0], &SubExprs[0] + END_EXPR);
42040b57cec5SDimitry Andric   }
42050b57cec5SDimitry Andric };
42060b57cec5SDimitry Andric 
42070b57cec5SDimitry Andric /// BinaryConditionalOperator - The GNU extension to the conditional
42080b57cec5SDimitry Andric /// operator which allows the middle operand to be omitted.
42090b57cec5SDimitry Andric ///
42100b57cec5SDimitry Andric /// This is a different expression kind on the assumption that almost
42110b57cec5SDimitry Andric /// every client ends up needing to know that these are different.
42120b57cec5SDimitry Andric class BinaryConditionalOperator : public AbstractConditionalOperator {
42130b57cec5SDimitry Andric   enum { COMMON, COND, LHS, RHS, NUM_SUBEXPRS };
42140b57cec5SDimitry Andric 
42150b57cec5SDimitry Andric   /// - the common condition/left-hand-side expression, which will be
42160b57cec5SDimitry Andric   ///   evaluated as the opaque value
42170b57cec5SDimitry Andric   /// - the condition, expressed in terms of the opaque value
42180b57cec5SDimitry Andric   /// - the left-hand-side, expressed in terms of the opaque value
42190b57cec5SDimitry Andric   /// - the right-hand-side
42200b57cec5SDimitry Andric   Stmt *SubExprs[NUM_SUBEXPRS];
42210b57cec5SDimitry Andric   OpaqueValueExpr *OpaqueValue;
42220b57cec5SDimitry Andric 
42230b57cec5SDimitry Andric   friend class ASTStmtReader;
42240b57cec5SDimitry Andric public:
BinaryConditionalOperator(Expr * common,OpaqueValueExpr * opaqueValue,Expr * cond,Expr * lhs,Expr * rhs,SourceLocation qloc,SourceLocation cloc,QualType t,ExprValueKind VK,ExprObjectKind OK)42250b57cec5SDimitry Andric   BinaryConditionalOperator(Expr *common, OpaqueValueExpr *opaqueValue,
42260b57cec5SDimitry Andric                             Expr *cond, Expr *lhs, Expr *rhs,
42270b57cec5SDimitry Andric                             SourceLocation qloc, SourceLocation cloc,
42280b57cec5SDimitry Andric                             QualType t, ExprValueKind VK, ExprObjectKind OK)
42290b57cec5SDimitry Andric       : AbstractConditionalOperator(BinaryConditionalOperatorClass, t, VK, OK,
42300b57cec5SDimitry Andric                                     qloc, cloc),
42310b57cec5SDimitry Andric         OpaqueValue(opaqueValue) {
42320b57cec5SDimitry Andric     SubExprs[COMMON] = common;
42330b57cec5SDimitry Andric     SubExprs[COND] = cond;
42340b57cec5SDimitry Andric     SubExprs[LHS] = lhs;
42350b57cec5SDimitry Andric     SubExprs[RHS] = rhs;
42360b57cec5SDimitry Andric     assert(OpaqueValue->getSourceExpr() == common && "Wrong opaque value");
42375ffd83dbSDimitry Andric     setDependence(computeDependence(this));
42380b57cec5SDimitry Andric   }
42390b57cec5SDimitry Andric 
42400b57cec5SDimitry Andric   /// Build an empty conditional operator.
BinaryConditionalOperator(EmptyShell Empty)42410b57cec5SDimitry Andric   explicit BinaryConditionalOperator(EmptyShell Empty)
42420b57cec5SDimitry Andric     : AbstractConditionalOperator(BinaryConditionalOperatorClass, Empty) { }
42430b57cec5SDimitry Andric 
42440b57cec5SDimitry Andric   /// getCommon - Return the common expression, written to the
42450b57cec5SDimitry Andric   ///   left of the condition.  The opaque value will be bound to the
42460b57cec5SDimitry Andric   ///   result of this expression.
getCommon()42470b57cec5SDimitry Andric   Expr *getCommon() const { return cast<Expr>(SubExprs[COMMON]); }
42480b57cec5SDimitry Andric 
42490b57cec5SDimitry Andric   /// getOpaqueValue - Return the opaque value placeholder.
getOpaqueValue()42500b57cec5SDimitry Andric   OpaqueValueExpr *getOpaqueValue() const { return OpaqueValue; }
42510b57cec5SDimitry Andric 
42520b57cec5SDimitry Andric   /// getCond - Return the condition expression; this is defined
42530b57cec5SDimitry Andric   ///   in terms of the opaque value.
getCond()42540b57cec5SDimitry Andric   Expr *getCond() const { return cast<Expr>(SubExprs[COND]); }
42550b57cec5SDimitry Andric 
42560b57cec5SDimitry Andric   /// getTrueExpr - Return the subexpression which will be
42570b57cec5SDimitry Andric   ///   evaluated if the condition evaluates to true;  this is defined
42580b57cec5SDimitry Andric   ///   in terms of the opaque value.
getTrueExpr()42590b57cec5SDimitry Andric   Expr *getTrueExpr() const {
42600b57cec5SDimitry Andric     return cast<Expr>(SubExprs[LHS]);
42610b57cec5SDimitry Andric   }
42620b57cec5SDimitry Andric 
42630b57cec5SDimitry Andric   /// getFalseExpr - Return the subexpression which will be
42640b57cec5SDimitry Andric   ///   evaluated if the condnition evaluates to false; this is
42650b57cec5SDimitry Andric   ///   defined in terms of the opaque value.
getFalseExpr()42660b57cec5SDimitry Andric   Expr *getFalseExpr() const {
42670b57cec5SDimitry Andric     return cast<Expr>(SubExprs[RHS]);
42680b57cec5SDimitry Andric   }
42690b57cec5SDimitry Andric 
getBeginLoc()42700b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY {
42710b57cec5SDimitry Andric     return getCommon()->getBeginLoc();
42720b57cec5SDimitry Andric   }
getEndLoc()42730b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY {
42740b57cec5SDimitry Andric     return getFalseExpr()->getEndLoc();
42750b57cec5SDimitry Andric   }
42760b57cec5SDimitry Andric 
classof(const Stmt * T)42770b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
42780b57cec5SDimitry Andric     return T->getStmtClass() == BinaryConditionalOperatorClass;
42790b57cec5SDimitry Andric   }
42800b57cec5SDimitry Andric 
42810b57cec5SDimitry Andric   // Iterators
children()42820b57cec5SDimitry Andric   child_range children() {
42830b57cec5SDimitry Andric     return child_range(SubExprs, SubExprs + NUM_SUBEXPRS);
42840b57cec5SDimitry Andric   }
children()42850b57cec5SDimitry Andric   const_child_range children() const {
42860b57cec5SDimitry Andric     return const_child_range(SubExprs, SubExprs + NUM_SUBEXPRS);
42870b57cec5SDimitry Andric   }
42880b57cec5SDimitry Andric };
42890b57cec5SDimitry Andric 
getCond()42900b57cec5SDimitry Andric inline Expr *AbstractConditionalOperator::getCond() const {
42910b57cec5SDimitry Andric   if (const ConditionalOperator *co = dyn_cast<ConditionalOperator>(this))
42920b57cec5SDimitry Andric     return co->getCond();
42930b57cec5SDimitry Andric   return cast<BinaryConditionalOperator>(this)->getCond();
42940b57cec5SDimitry Andric }
42950b57cec5SDimitry Andric 
getTrueExpr()42960b57cec5SDimitry Andric inline Expr *AbstractConditionalOperator::getTrueExpr() const {
42970b57cec5SDimitry Andric   if (const ConditionalOperator *co = dyn_cast<ConditionalOperator>(this))
42980b57cec5SDimitry Andric     return co->getTrueExpr();
42990b57cec5SDimitry Andric   return cast<BinaryConditionalOperator>(this)->getTrueExpr();
43000b57cec5SDimitry Andric }
43010b57cec5SDimitry Andric 
getFalseExpr()43020b57cec5SDimitry Andric inline Expr *AbstractConditionalOperator::getFalseExpr() const {
43030b57cec5SDimitry Andric   if (const ConditionalOperator *co = dyn_cast<ConditionalOperator>(this))
43040b57cec5SDimitry Andric     return co->getFalseExpr();
43050b57cec5SDimitry Andric   return cast<BinaryConditionalOperator>(this)->getFalseExpr();
43060b57cec5SDimitry Andric }
43070b57cec5SDimitry Andric 
43080b57cec5SDimitry Andric /// AddrLabelExpr - The GNU address of label extension, representing &&label.
43090b57cec5SDimitry Andric class AddrLabelExpr : public Expr {
43100b57cec5SDimitry Andric   SourceLocation AmpAmpLoc, LabelLoc;
43110b57cec5SDimitry Andric   LabelDecl *Label;
43120b57cec5SDimitry Andric public:
AddrLabelExpr(SourceLocation AALoc,SourceLocation LLoc,LabelDecl * L,QualType t)43130b57cec5SDimitry Andric   AddrLabelExpr(SourceLocation AALoc, SourceLocation LLoc, LabelDecl *L,
43140b57cec5SDimitry Andric                 QualType t)
4315fe6060f1SDimitry Andric       : Expr(AddrLabelExprClass, t, VK_PRValue, OK_Ordinary), AmpAmpLoc(AALoc),
43165ffd83dbSDimitry Andric         LabelLoc(LLoc), Label(L) {
43175ffd83dbSDimitry Andric     setDependence(ExprDependence::None);
43185ffd83dbSDimitry Andric   }
43190b57cec5SDimitry Andric 
43200b57cec5SDimitry Andric   /// Build an empty address of a label expression.
AddrLabelExpr(EmptyShell Empty)43210b57cec5SDimitry Andric   explicit AddrLabelExpr(EmptyShell Empty)
43220b57cec5SDimitry Andric     : Expr(AddrLabelExprClass, Empty) { }
43230b57cec5SDimitry Andric 
getAmpAmpLoc()43240b57cec5SDimitry Andric   SourceLocation getAmpAmpLoc() const { return AmpAmpLoc; }
setAmpAmpLoc(SourceLocation L)43250b57cec5SDimitry Andric   void setAmpAmpLoc(SourceLocation L) { AmpAmpLoc = L; }
getLabelLoc()43260b57cec5SDimitry Andric   SourceLocation getLabelLoc() const { return LabelLoc; }
setLabelLoc(SourceLocation L)43270b57cec5SDimitry Andric   void setLabelLoc(SourceLocation L) { LabelLoc = L; }
43280b57cec5SDimitry Andric 
getBeginLoc()43290b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY { return AmpAmpLoc; }
getEndLoc()43300b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY { return LabelLoc; }
43310b57cec5SDimitry Andric 
getLabel()43320b57cec5SDimitry Andric   LabelDecl *getLabel() const { return Label; }
setLabel(LabelDecl * L)43330b57cec5SDimitry Andric   void setLabel(LabelDecl *L) { Label = L; }
43340b57cec5SDimitry Andric 
classof(const Stmt * T)43350b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
43360b57cec5SDimitry Andric     return T->getStmtClass() == AddrLabelExprClass;
43370b57cec5SDimitry Andric   }
43380b57cec5SDimitry Andric 
43390b57cec5SDimitry Andric   // Iterators
children()43400b57cec5SDimitry Andric   child_range children() {
43410b57cec5SDimitry Andric     return child_range(child_iterator(), child_iterator());
43420b57cec5SDimitry Andric   }
children()43430b57cec5SDimitry Andric   const_child_range children() const {
43440b57cec5SDimitry Andric     return const_child_range(const_child_iterator(), const_child_iterator());
43450b57cec5SDimitry Andric   }
43460b57cec5SDimitry Andric };
43470b57cec5SDimitry Andric 
43480b57cec5SDimitry Andric /// StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
43490b57cec5SDimitry Andric /// The StmtExpr contains a single CompoundStmt node, which it evaluates and
43500b57cec5SDimitry Andric /// takes the value of the last subexpression.
43510b57cec5SDimitry Andric ///
43520b57cec5SDimitry Andric /// A StmtExpr is always an r-value; values "returned" out of a
43530b57cec5SDimitry Andric /// StmtExpr will be copied.
43540b57cec5SDimitry Andric class StmtExpr : public Expr {
43550b57cec5SDimitry Andric   Stmt *SubStmt;
43560b57cec5SDimitry Andric   SourceLocation LParenLoc, RParenLoc;
43570b57cec5SDimitry Andric public:
StmtExpr(CompoundStmt * SubStmt,QualType T,SourceLocation LParenLoc,SourceLocation RParenLoc,unsigned TemplateDepth)4358cd675bb6SDimitry Andric   StmtExpr(CompoundStmt *SubStmt, QualType T, SourceLocation LParenLoc,
4359cd675bb6SDimitry Andric            SourceLocation RParenLoc, unsigned TemplateDepth)
4360fe6060f1SDimitry Andric       : Expr(StmtExprClass, T, VK_PRValue, OK_Ordinary), SubStmt(SubStmt),
43615ffd83dbSDimitry Andric         LParenLoc(LParenLoc), RParenLoc(RParenLoc) {
43625ffd83dbSDimitry Andric     setDependence(computeDependence(this, TemplateDepth));
4363cd675bb6SDimitry Andric     // FIXME: A templated statement expression should have an associated
4364cd675bb6SDimitry Andric     // DeclContext so that nested declarations always have a dependent context.
4365cd675bb6SDimitry Andric     StmtExprBits.TemplateDepth = TemplateDepth;
4366cd675bb6SDimitry Andric   }
43670b57cec5SDimitry Andric 
43680b57cec5SDimitry Andric   /// Build an empty statement expression.
StmtExpr(EmptyShell Empty)43690b57cec5SDimitry Andric   explicit StmtExpr(EmptyShell Empty) : Expr(StmtExprClass, Empty) { }
43700b57cec5SDimitry Andric 
getSubStmt()43710b57cec5SDimitry Andric   CompoundStmt *getSubStmt() { return cast<CompoundStmt>(SubStmt); }
getSubStmt()43720b57cec5SDimitry Andric   const CompoundStmt *getSubStmt() const { return cast<CompoundStmt>(SubStmt); }
setSubStmt(CompoundStmt * S)43730b57cec5SDimitry Andric   void setSubStmt(CompoundStmt *S) { SubStmt = S; }
43740b57cec5SDimitry Andric 
getBeginLoc()43750b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY { return LParenLoc; }
getEndLoc()43760b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
43770b57cec5SDimitry Andric 
getLParenLoc()43780b57cec5SDimitry Andric   SourceLocation getLParenLoc() const { return LParenLoc; }
setLParenLoc(SourceLocation L)43790b57cec5SDimitry Andric   void setLParenLoc(SourceLocation L) { LParenLoc = L; }
getRParenLoc()43800b57cec5SDimitry Andric   SourceLocation getRParenLoc() const { return RParenLoc; }
setRParenLoc(SourceLocation L)43810b57cec5SDimitry Andric   void setRParenLoc(SourceLocation L) { RParenLoc = L; }
43820b57cec5SDimitry Andric 
getTemplateDepth()4383cd675bb6SDimitry Andric   unsigned getTemplateDepth() const { return StmtExprBits.TemplateDepth; }
4384cd675bb6SDimitry Andric 
classof(const Stmt * T)43850b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
43860b57cec5SDimitry Andric     return T->getStmtClass() == StmtExprClass;
43870b57cec5SDimitry Andric   }
43880b57cec5SDimitry Andric 
43890b57cec5SDimitry Andric   // Iterators
children()43900b57cec5SDimitry Andric   child_range children() { return child_range(&SubStmt, &SubStmt+1); }
children()43910b57cec5SDimitry Andric   const_child_range children() const {
43920b57cec5SDimitry Andric     return const_child_range(&SubStmt, &SubStmt + 1);
43930b57cec5SDimitry Andric   }
43940b57cec5SDimitry Andric };
43950b57cec5SDimitry Andric 
43960b57cec5SDimitry Andric /// ShuffleVectorExpr - clang-specific builtin-in function
43970b57cec5SDimitry Andric /// __builtin_shufflevector.
43980b57cec5SDimitry Andric /// This AST node represents a operator that does a constant
43990b57cec5SDimitry Andric /// shuffle, similar to LLVM's shufflevector instruction. It takes
44000b57cec5SDimitry Andric /// two vectors and a variable number of constant indices,
44010b57cec5SDimitry Andric /// and returns the appropriately shuffled vector.
44020b57cec5SDimitry Andric class ShuffleVectorExpr : public Expr {
44030b57cec5SDimitry Andric   SourceLocation BuiltinLoc, RParenLoc;
44040b57cec5SDimitry Andric 
44050b57cec5SDimitry Andric   // SubExprs - the list of values passed to the __builtin_shufflevector
44060b57cec5SDimitry Andric   // function. The first two are vectors, and the rest are constant
44070b57cec5SDimitry Andric   // indices.  The number of values in this list is always
44080b57cec5SDimitry Andric   // 2+the number of indices in the vector type.
44090b57cec5SDimitry Andric   Stmt **SubExprs;
44100b57cec5SDimitry Andric   unsigned NumExprs;
44110b57cec5SDimitry Andric 
44120b57cec5SDimitry Andric public:
44130b57cec5SDimitry Andric   ShuffleVectorExpr(const ASTContext &C, ArrayRef<Expr*> args, QualType Type,
44140b57cec5SDimitry Andric                     SourceLocation BLoc, SourceLocation RP);
44150b57cec5SDimitry Andric 
44160b57cec5SDimitry Andric   /// Build an empty vector-shuffle expression.
ShuffleVectorExpr(EmptyShell Empty)44170b57cec5SDimitry Andric   explicit ShuffleVectorExpr(EmptyShell Empty)
44180b57cec5SDimitry Andric     : Expr(ShuffleVectorExprClass, Empty), SubExprs(nullptr) { }
44190b57cec5SDimitry Andric 
getBuiltinLoc()44200b57cec5SDimitry Andric   SourceLocation getBuiltinLoc() const { return BuiltinLoc; }
setBuiltinLoc(SourceLocation L)44210b57cec5SDimitry Andric   void setBuiltinLoc(SourceLocation L) { BuiltinLoc = L; }
44220b57cec5SDimitry Andric 
getRParenLoc()44230b57cec5SDimitry Andric   SourceLocation getRParenLoc() const { return RParenLoc; }
setRParenLoc(SourceLocation L)44240b57cec5SDimitry Andric   void setRParenLoc(SourceLocation L) { RParenLoc = L; }
44250b57cec5SDimitry Andric 
getBeginLoc()44260b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY { return BuiltinLoc; }
getEndLoc()44270b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
44280b57cec5SDimitry Andric 
classof(const Stmt * T)44290b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
44300b57cec5SDimitry Andric     return T->getStmtClass() == ShuffleVectorExprClass;
44310b57cec5SDimitry Andric   }
44320b57cec5SDimitry Andric 
44330b57cec5SDimitry Andric   /// getNumSubExprs - Return the size of the SubExprs array.  This includes the
44340b57cec5SDimitry Andric   /// constant expression, the actual arguments passed in, and the function
44350b57cec5SDimitry Andric   /// pointers.
getNumSubExprs()44360b57cec5SDimitry Andric   unsigned getNumSubExprs() const { return NumExprs; }
44370b57cec5SDimitry Andric 
44380b57cec5SDimitry Andric   /// Retrieve the array of expressions.
getSubExprs()44390b57cec5SDimitry Andric   Expr **getSubExprs() { return reinterpret_cast<Expr **>(SubExprs); }
44400b57cec5SDimitry Andric 
44410b57cec5SDimitry Andric   /// getExpr - Return the Expr at the specified index.
getExpr(unsigned Index)44420b57cec5SDimitry Andric   Expr *getExpr(unsigned Index) {
44430b57cec5SDimitry Andric     assert((Index < NumExprs) && "Arg access out of range!");
44440b57cec5SDimitry Andric     return cast<Expr>(SubExprs[Index]);
44450b57cec5SDimitry Andric   }
getExpr(unsigned Index)44460b57cec5SDimitry Andric   const Expr *getExpr(unsigned Index) const {
44470b57cec5SDimitry Andric     assert((Index < NumExprs) && "Arg access out of range!");
44480b57cec5SDimitry Andric     return cast<Expr>(SubExprs[Index]);
44490b57cec5SDimitry Andric   }
44500b57cec5SDimitry Andric 
44510b57cec5SDimitry Andric   void setExprs(const ASTContext &C, ArrayRef<Expr *> Exprs);
44520b57cec5SDimitry Andric 
getShuffleMaskIdx(const ASTContext & Ctx,unsigned N)44530b57cec5SDimitry Andric   llvm::APSInt getShuffleMaskIdx(const ASTContext &Ctx, unsigned N) const {
44540b57cec5SDimitry Andric     assert((N < NumExprs - 2) && "Shuffle idx out of range!");
44550b57cec5SDimitry Andric     return getExpr(N+2)->EvaluateKnownConstInt(Ctx);
44560b57cec5SDimitry Andric   }
44570b57cec5SDimitry Andric 
44580b57cec5SDimitry Andric   // Iterators
children()44590b57cec5SDimitry Andric   child_range children() {
44600b57cec5SDimitry Andric     return child_range(&SubExprs[0], &SubExprs[0]+NumExprs);
44610b57cec5SDimitry Andric   }
children()44620b57cec5SDimitry Andric   const_child_range children() const {
44630b57cec5SDimitry Andric     return const_child_range(&SubExprs[0], &SubExprs[0] + NumExprs);
44640b57cec5SDimitry Andric   }
44650b57cec5SDimitry Andric };
44660b57cec5SDimitry Andric 
44670b57cec5SDimitry Andric /// ConvertVectorExpr - Clang builtin function __builtin_convertvector
44680b57cec5SDimitry Andric /// This AST node provides support for converting a vector type to another
44690b57cec5SDimitry Andric /// vector type of the same arity.
44700b57cec5SDimitry Andric class ConvertVectorExpr : public Expr {
44710b57cec5SDimitry Andric private:
44720b57cec5SDimitry Andric   Stmt *SrcExpr;
44730b57cec5SDimitry Andric   TypeSourceInfo *TInfo;
44740b57cec5SDimitry Andric   SourceLocation BuiltinLoc, RParenLoc;
44750b57cec5SDimitry Andric 
44760b57cec5SDimitry Andric   friend class ASTReader;
44770b57cec5SDimitry Andric   friend class ASTStmtReader;
ConvertVectorExpr(EmptyShell Empty)44780b57cec5SDimitry Andric   explicit ConvertVectorExpr(EmptyShell Empty) : Expr(ConvertVectorExprClass, Empty) {}
44790b57cec5SDimitry Andric 
44800b57cec5SDimitry Andric public:
ConvertVectorExpr(Expr * SrcExpr,TypeSourceInfo * TI,QualType DstType,ExprValueKind VK,ExprObjectKind OK,SourceLocation BuiltinLoc,SourceLocation RParenLoc)44810b57cec5SDimitry Andric   ConvertVectorExpr(Expr *SrcExpr, TypeSourceInfo *TI, QualType DstType,
44820b57cec5SDimitry Andric                     ExprValueKind VK, ExprObjectKind OK,
44830b57cec5SDimitry Andric                     SourceLocation BuiltinLoc, SourceLocation RParenLoc)
44845ffd83dbSDimitry Andric       : Expr(ConvertVectorExprClass, DstType, VK, OK), SrcExpr(SrcExpr),
44855ffd83dbSDimitry Andric         TInfo(TI), BuiltinLoc(BuiltinLoc), RParenLoc(RParenLoc) {
44865ffd83dbSDimitry Andric     setDependence(computeDependence(this));
44875ffd83dbSDimitry Andric   }
44880b57cec5SDimitry Andric 
44890b57cec5SDimitry Andric   /// getSrcExpr - Return the Expr to be converted.
getSrcExpr()44900b57cec5SDimitry Andric   Expr *getSrcExpr() const { return cast<Expr>(SrcExpr); }
44910b57cec5SDimitry Andric 
44920b57cec5SDimitry Andric   /// getTypeSourceInfo - Return the destination type.
getTypeSourceInfo()44930b57cec5SDimitry Andric   TypeSourceInfo *getTypeSourceInfo() const {
44940b57cec5SDimitry Andric     return TInfo;
44950b57cec5SDimitry Andric   }
setTypeSourceInfo(TypeSourceInfo * ti)44960b57cec5SDimitry Andric   void setTypeSourceInfo(TypeSourceInfo *ti) {
44970b57cec5SDimitry Andric     TInfo = ti;
44980b57cec5SDimitry Andric   }
44990b57cec5SDimitry Andric 
45000b57cec5SDimitry Andric   /// getBuiltinLoc - Return the location of the __builtin_convertvector token.
getBuiltinLoc()45010b57cec5SDimitry Andric   SourceLocation getBuiltinLoc() const { return BuiltinLoc; }
45020b57cec5SDimitry Andric 
45030b57cec5SDimitry Andric   /// getRParenLoc - Return the location of final right parenthesis.
getRParenLoc()45040b57cec5SDimitry Andric   SourceLocation getRParenLoc() const { return RParenLoc; }
45050b57cec5SDimitry Andric 
getBeginLoc()45060b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY { return BuiltinLoc; }
getEndLoc()45070b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
45080b57cec5SDimitry Andric 
classof(const Stmt * T)45090b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
45100b57cec5SDimitry Andric     return T->getStmtClass() == ConvertVectorExprClass;
45110b57cec5SDimitry Andric   }
45120b57cec5SDimitry Andric 
45130b57cec5SDimitry Andric   // Iterators
children()45140b57cec5SDimitry Andric   child_range children() { return child_range(&SrcExpr, &SrcExpr+1); }
children()45150b57cec5SDimitry Andric   const_child_range children() const {
45160b57cec5SDimitry Andric     return const_child_range(&SrcExpr, &SrcExpr + 1);
45170b57cec5SDimitry Andric   }
45180b57cec5SDimitry Andric };
45190b57cec5SDimitry Andric 
45200b57cec5SDimitry Andric /// ChooseExpr - GNU builtin-in function __builtin_choose_expr.
45210b57cec5SDimitry Andric /// This AST node is similar to the conditional operator (?:) in C, with
45220b57cec5SDimitry Andric /// the following exceptions:
45230b57cec5SDimitry Andric /// - the test expression must be a integer constant expression.
45240b57cec5SDimitry Andric /// - the expression returned acts like the chosen subexpression in every
45250b57cec5SDimitry Andric ///   visible way: the type is the same as that of the chosen subexpression,
45260b57cec5SDimitry Andric ///   and all predicates (whether it's an l-value, whether it's an integer
45270b57cec5SDimitry Andric ///   constant expression, etc.) return the same result as for the chosen
45280b57cec5SDimitry Andric ///   sub-expression.
45290b57cec5SDimitry Andric class ChooseExpr : public Expr {
45300b57cec5SDimitry Andric   enum { COND, LHS, RHS, END_EXPR };
45310b57cec5SDimitry Andric   Stmt* SubExprs[END_EXPR]; // Left/Middle/Right hand sides.
45320b57cec5SDimitry Andric   SourceLocation BuiltinLoc, RParenLoc;
45330b57cec5SDimitry Andric   bool CondIsTrue;
45340b57cec5SDimitry Andric public:
ChooseExpr(SourceLocation BLoc,Expr * cond,Expr * lhs,Expr * rhs,QualType t,ExprValueKind VK,ExprObjectKind OK,SourceLocation RP,bool condIsTrue)45355ffd83dbSDimitry Andric   ChooseExpr(SourceLocation BLoc, Expr *cond, Expr *lhs, Expr *rhs, QualType t,
45365ffd83dbSDimitry Andric              ExprValueKind VK, ExprObjectKind OK, SourceLocation RP,
45375ffd83dbSDimitry Andric              bool condIsTrue)
45385ffd83dbSDimitry Andric       : Expr(ChooseExprClass, t, VK, OK), BuiltinLoc(BLoc), RParenLoc(RP),
45395ffd83dbSDimitry Andric         CondIsTrue(condIsTrue) {
45400b57cec5SDimitry Andric     SubExprs[COND] = cond;
45410b57cec5SDimitry Andric     SubExprs[LHS] = lhs;
45420b57cec5SDimitry Andric     SubExprs[RHS] = rhs;
45435ffd83dbSDimitry Andric 
45445ffd83dbSDimitry Andric     setDependence(computeDependence(this));
45450b57cec5SDimitry Andric   }
45460b57cec5SDimitry Andric 
45470b57cec5SDimitry Andric   /// Build an empty __builtin_choose_expr.
ChooseExpr(EmptyShell Empty)45480b57cec5SDimitry Andric   explicit ChooseExpr(EmptyShell Empty) : Expr(ChooseExprClass, Empty) { }
45490b57cec5SDimitry Andric 
45500b57cec5SDimitry Andric   /// isConditionTrue - Return whether the condition is true (i.e. not
45510b57cec5SDimitry Andric   /// equal to zero).
isConditionTrue()45520b57cec5SDimitry Andric   bool isConditionTrue() const {
45530b57cec5SDimitry Andric     assert(!isConditionDependent() &&
45540b57cec5SDimitry Andric            "Dependent condition isn't true or false");
45550b57cec5SDimitry Andric     return CondIsTrue;
45560b57cec5SDimitry Andric   }
setIsConditionTrue(bool isTrue)45570b57cec5SDimitry Andric   void setIsConditionTrue(bool isTrue) { CondIsTrue = isTrue; }
45580b57cec5SDimitry Andric 
isConditionDependent()45590b57cec5SDimitry Andric   bool isConditionDependent() const {
45600b57cec5SDimitry Andric     return getCond()->isTypeDependent() || getCond()->isValueDependent();
45610b57cec5SDimitry Andric   }
45620b57cec5SDimitry Andric 
45630b57cec5SDimitry Andric   /// getChosenSubExpr - Return the subexpression chosen according to the
45640b57cec5SDimitry Andric   /// condition.
getChosenSubExpr()45650b57cec5SDimitry Andric   Expr *getChosenSubExpr() const {
45660b57cec5SDimitry Andric     return isConditionTrue() ? getLHS() : getRHS();
45670b57cec5SDimitry Andric   }
45680b57cec5SDimitry Andric 
getCond()45690b57cec5SDimitry Andric   Expr *getCond() const { return cast<Expr>(SubExprs[COND]); }
setCond(Expr * E)45700b57cec5SDimitry Andric   void setCond(Expr *E) { SubExprs[COND] = E; }
getLHS()45710b57cec5SDimitry Andric   Expr *getLHS() const { return cast<Expr>(SubExprs[LHS]); }
setLHS(Expr * E)45720b57cec5SDimitry Andric   void setLHS(Expr *E) { SubExprs[LHS] = E; }
getRHS()45730b57cec5SDimitry Andric   Expr *getRHS() const { return cast<Expr>(SubExprs[RHS]); }
setRHS(Expr * E)45740b57cec5SDimitry Andric   void setRHS(Expr *E) { SubExprs[RHS] = E; }
45750b57cec5SDimitry Andric 
getBuiltinLoc()45760b57cec5SDimitry Andric   SourceLocation getBuiltinLoc() const { return BuiltinLoc; }
setBuiltinLoc(SourceLocation L)45770b57cec5SDimitry Andric   void setBuiltinLoc(SourceLocation L) { BuiltinLoc = L; }
45780b57cec5SDimitry Andric 
getRParenLoc()45790b57cec5SDimitry Andric   SourceLocation getRParenLoc() const { return RParenLoc; }
setRParenLoc(SourceLocation L)45800b57cec5SDimitry Andric   void setRParenLoc(SourceLocation L) { RParenLoc = L; }
45810b57cec5SDimitry Andric 
getBeginLoc()45820b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY { return BuiltinLoc; }
getEndLoc()45830b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
45840b57cec5SDimitry Andric 
classof(const Stmt * T)45850b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
45860b57cec5SDimitry Andric     return T->getStmtClass() == ChooseExprClass;
45870b57cec5SDimitry Andric   }
45880b57cec5SDimitry Andric 
45890b57cec5SDimitry Andric   // Iterators
children()45900b57cec5SDimitry Andric   child_range children() {
45910b57cec5SDimitry Andric     return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
45920b57cec5SDimitry Andric   }
children()45930b57cec5SDimitry Andric   const_child_range children() const {
45940b57cec5SDimitry Andric     return const_child_range(&SubExprs[0], &SubExprs[0] + END_EXPR);
45950b57cec5SDimitry Andric   }
45960b57cec5SDimitry Andric };
45970b57cec5SDimitry Andric 
45980b57cec5SDimitry Andric /// GNUNullExpr - Implements the GNU __null extension, which is a name
45990b57cec5SDimitry Andric /// for a null pointer constant that has integral type (e.g., int or
46000b57cec5SDimitry Andric /// long) and is the same size and alignment as a pointer. The __null
46010b57cec5SDimitry Andric /// extension is typically only used by system headers, which define
46020b57cec5SDimitry Andric /// NULL as __null in C++ rather than using 0 (which is an integer
46030b57cec5SDimitry Andric /// that may not match the size of a pointer).
46040b57cec5SDimitry Andric class GNUNullExpr : public Expr {
46050b57cec5SDimitry Andric   /// TokenLoc - The location of the __null keyword.
46060b57cec5SDimitry Andric   SourceLocation TokenLoc;
46070b57cec5SDimitry Andric 
46080b57cec5SDimitry Andric public:
GNUNullExpr(QualType Ty,SourceLocation Loc)46090b57cec5SDimitry Andric   GNUNullExpr(QualType Ty, SourceLocation Loc)
4610fe6060f1SDimitry Andric       : Expr(GNUNullExprClass, Ty, VK_PRValue, OK_Ordinary), TokenLoc(Loc) {
46115ffd83dbSDimitry Andric     setDependence(ExprDependence::None);
46125ffd83dbSDimitry Andric   }
46130b57cec5SDimitry Andric 
46140b57cec5SDimitry Andric   /// Build an empty GNU __null expression.
GNUNullExpr(EmptyShell Empty)46150b57cec5SDimitry Andric   explicit GNUNullExpr(EmptyShell Empty) : Expr(GNUNullExprClass, Empty) { }
46160b57cec5SDimitry Andric 
46170b57cec5SDimitry Andric   /// getTokenLocation - The location of the __null token.
getTokenLocation()46180b57cec5SDimitry Andric   SourceLocation getTokenLocation() const { return TokenLoc; }
setTokenLocation(SourceLocation L)46190b57cec5SDimitry Andric   void setTokenLocation(SourceLocation L) { TokenLoc = L; }
46200b57cec5SDimitry Andric 
getBeginLoc()46210b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY { return TokenLoc; }
getEndLoc()46220b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY { return TokenLoc; }
46230b57cec5SDimitry Andric 
classof(const Stmt * T)46240b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
46250b57cec5SDimitry Andric     return T->getStmtClass() == GNUNullExprClass;
46260b57cec5SDimitry Andric   }
46270b57cec5SDimitry Andric 
46280b57cec5SDimitry Andric   // Iterators
children()46290b57cec5SDimitry Andric   child_range children() {
46300b57cec5SDimitry Andric     return child_range(child_iterator(), child_iterator());
46310b57cec5SDimitry Andric   }
children()46320b57cec5SDimitry Andric   const_child_range children() const {
46330b57cec5SDimitry Andric     return const_child_range(const_child_iterator(), const_child_iterator());
46340b57cec5SDimitry Andric   }
46350b57cec5SDimitry Andric };
46360b57cec5SDimitry Andric 
46370b57cec5SDimitry Andric /// Represents a call to the builtin function \c __builtin_va_arg.
46380b57cec5SDimitry Andric class VAArgExpr : public Expr {
46390b57cec5SDimitry Andric   Stmt *Val;
46400b57cec5SDimitry Andric   llvm::PointerIntPair<TypeSourceInfo *, 1, bool> TInfo;
46410b57cec5SDimitry Andric   SourceLocation BuiltinLoc, RParenLoc;
46420b57cec5SDimitry Andric public:
VAArgExpr(SourceLocation BLoc,Expr * e,TypeSourceInfo * TInfo,SourceLocation RPLoc,QualType t,bool IsMS)46430b57cec5SDimitry Andric   VAArgExpr(SourceLocation BLoc, Expr *e, TypeSourceInfo *TInfo,
46440b57cec5SDimitry Andric             SourceLocation RPLoc, QualType t, bool IsMS)
4645fe6060f1SDimitry Andric       : Expr(VAArgExprClass, t, VK_PRValue, OK_Ordinary), Val(e),
46465ffd83dbSDimitry Andric         TInfo(TInfo, IsMS), BuiltinLoc(BLoc), RParenLoc(RPLoc) {
46475ffd83dbSDimitry Andric     setDependence(computeDependence(this));
46485ffd83dbSDimitry Andric   }
46490b57cec5SDimitry Andric 
46500b57cec5SDimitry Andric   /// Create an empty __builtin_va_arg expression.
VAArgExpr(EmptyShell Empty)46510b57cec5SDimitry Andric   explicit VAArgExpr(EmptyShell Empty)
46520b57cec5SDimitry Andric       : Expr(VAArgExprClass, Empty), Val(nullptr), TInfo(nullptr, false) {}
46530b57cec5SDimitry Andric 
getSubExpr()46540b57cec5SDimitry Andric   const Expr *getSubExpr() const { return cast<Expr>(Val); }
getSubExpr()46550b57cec5SDimitry Andric   Expr *getSubExpr() { return cast<Expr>(Val); }
setSubExpr(Expr * E)46560b57cec5SDimitry Andric   void setSubExpr(Expr *E) { Val = E; }
46570b57cec5SDimitry Andric 
46580b57cec5SDimitry Andric   /// Returns whether this is really a Win64 ABI va_arg expression.
isMicrosoftABI()46590b57cec5SDimitry Andric   bool isMicrosoftABI() const { return TInfo.getInt(); }
setIsMicrosoftABI(bool IsMS)46600b57cec5SDimitry Andric   void setIsMicrosoftABI(bool IsMS) { TInfo.setInt(IsMS); }
46610b57cec5SDimitry Andric 
getWrittenTypeInfo()46620b57cec5SDimitry Andric   TypeSourceInfo *getWrittenTypeInfo() const { return TInfo.getPointer(); }
setWrittenTypeInfo(TypeSourceInfo * TI)46630b57cec5SDimitry Andric   void setWrittenTypeInfo(TypeSourceInfo *TI) { TInfo.setPointer(TI); }
46640b57cec5SDimitry Andric 
getBuiltinLoc()46650b57cec5SDimitry Andric   SourceLocation getBuiltinLoc() const { return BuiltinLoc; }
setBuiltinLoc(SourceLocation L)46660b57cec5SDimitry Andric   void setBuiltinLoc(SourceLocation L) { BuiltinLoc = L; }
46670b57cec5SDimitry Andric 
getRParenLoc()46680b57cec5SDimitry Andric   SourceLocation getRParenLoc() const { return RParenLoc; }
setRParenLoc(SourceLocation L)46690b57cec5SDimitry Andric   void setRParenLoc(SourceLocation L) { RParenLoc = L; }
46700b57cec5SDimitry Andric 
getBeginLoc()46710b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY { return BuiltinLoc; }
getEndLoc()46720b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
46730b57cec5SDimitry Andric 
classof(const Stmt * T)46740b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
46750b57cec5SDimitry Andric     return T->getStmtClass() == VAArgExprClass;
46760b57cec5SDimitry Andric   }
46770b57cec5SDimitry Andric 
46780b57cec5SDimitry Andric   // Iterators
children()46790b57cec5SDimitry Andric   child_range children() { return child_range(&Val, &Val+1); }
children()46800b57cec5SDimitry Andric   const_child_range children() const {
46810b57cec5SDimitry Andric     return const_child_range(&Val, &Val + 1);
46820b57cec5SDimitry Andric   }
46830b57cec5SDimitry Andric };
46840b57cec5SDimitry Andric 
46855f757f3fSDimitry Andric enum class SourceLocIdentKind {
468606c3fb27SDimitry Andric   Function,
468706c3fb27SDimitry Andric   FuncSig,
468806c3fb27SDimitry Andric   File,
468906c3fb27SDimitry Andric   FileName,
469006c3fb27SDimitry Andric   Line,
469106c3fb27SDimitry Andric   Column,
469206c3fb27SDimitry Andric   SourceLocStruct
469306c3fb27SDimitry Andric };
46940b57cec5SDimitry Andric 
46955f757f3fSDimitry Andric /// Represents a function call to one of __builtin_LINE(), __builtin_COLUMN(),
46965f757f3fSDimitry Andric /// __builtin_FUNCTION(), __builtin_FUNCSIG(), __builtin_FILE(),
46975f757f3fSDimitry Andric /// __builtin_FILE_NAME() or __builtin_source_location().
46985f757f3fSDimitry Andric class SourceLocExpr final : public Expr {
46995f757f3fSDimitry Andric   SourceLocation BuiltinLoc, RParenLoc;
47005f757f3fSDimitry Andric   DeclContext *ParentContext;
47015f757f3fSDimitry Andric 
47025f757f3fSDimitry Andric public:
47035f757f3fSDimitry Andric   SourceLocExpr(const ASTContext &Ctx, SourceLocIdentKind Type,
47045f757f3fSDimitry Andric                 QualType ResultTy, SourceLocation BLoc,
47055f757f3fSDimitry Andric                 SourceLocation RParenLoc, DeclContext *Context);
47060b57cec5SDimitry Andric 
47070b57cec5SDimitry Andric   /// Build an empty call expression.
SourceLocExpr(EmptyShell Empty)47080b57cec5SDimitry Andric   explicit SourceLocExpr(EmptyShell Empty) : Expr(SourceLocExprClass, Empty) {}
47090b57cec5SDimitry Andric 
47100b57cec5SDimitry Andric   /// Return the result of evaluating this SourceLocExpr in the specified
47110b57cec5SDimitry Andric   /// (and possibly null) default argument or initialization context.
47120b57cec5SDimitry Andric   APValue EvaluateInContext(const ASTContext &Ctx,
47130b57cec5SDimitry Andric                             const Expr *DefaultExpr) const;
47140b57cec5SDimitry Andric 
47150b57cec5SDimitry Andric   /// Return a string representing the name of the specific builtin function.
47160b57cec5SDimitry Andric   StringRef getBuiltinStr() const;
47170b57cec5SDimitry Andric 
getIdentKind()47185f757f3fSDimitry Andric   SourceLocIdentKind getIdentKind() const {
47195f757f3fSDimitry Andric     return static_cast<SourceLocIdentKind>(SourceLocExprBits.Kind);
47200b57cec5SDimitry Andric   }
47210b57cec5SDimitry Andric 
isIntType()472281ad6265SDimitry Andric   bool isIntType() const {
47230b57cec5SDimitry Andric     switch (getIdentKind()) {
47245f757f3fSDimitry Andric     case SourceLocIdentKind::File:
47255f757f3fSDimitry Andric     case SourceLocIdentKind::FileName:
47265f757f3fSDimitry Andric     case SourceLocIdentKind::Function:
47275f757f3fSDimitry Andric     case SourceLocIdentKind::FuncSig:
47285f757f3fSDimitry Andric     case SourceLocIdentKind::SourceLocStruct:
472981ad6265SDimitry Andric       return false;
47305f757f3fSDimitry Andric     case SourceLocIdentKind::Line:
47315f757f3fSDimitry Andric     case SourceLocIdentKind::Column:
473281ad6265SDimitry Andric       return true;
47330b57cec5SDimitry Andric     }
47340b57cec5SDimitry Andric     llvm_unreachable("unknown source location expression kind");
47350b57cec5SDimitry Andric   }
47360b57cec5SDimitry Andric 
47370b57cec5SDimitry Andric   /// If the SourceLocExpr has been resolved return the subexpression
47380b57cec5SDimitry Andric   /// representing the resolved value. Otherwise return null.
getParentContext()47390b57cec5SDimitry Andric   const DeclContext *getParentContext() const { return ParentContext; }
getParentContext()47400b57cec5SDimitry Andric   DeclContext *getParentContext() { return ParentContext; }
47410b57cec5SDimitry Andric 
getLocation()47420b57cec5SDimitry Andric   SourceLocation getLocation() const { return BuiltinLoc; }
getBeginLoc()47430b57cec5SDimitry Andric   SourceLocation getBeginLoc() const { return BuiltinLoc; }
getEndLoc()47440b57cec5SDimitry Andric   SourceLocation getEndLoc() const { return RParenLoc; }
47450b57cec5SDimitry Andric 
children()47460b57cec5SDimitry Andric   child_range children() {
47470b57cec5SDimitry Andric     return child_range(child_iterator(), child_iterator());
47480b57cec5SDimitry Andric   }
47490b57cec5SDimitry Andric 
children()47500b57cec5SDimitry Andric   const_child_range children() const {
47510b57cec5SDimitry Andric     return const_child_range(child_iterator(), child_iterator());
47520b57cec5SDimitry Andric   }
47530b57cec5SDimitry Andric 
classof(const Stmt * T)47540b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
47550b57cec5SDimitry Andric     return T->getStmtClass() == SourceLocExprClass;
47560b57cec5SDimitry Andric   }
47570b57cec5SDimitry Andric 
MayBeDependent(SourceLocIdentKind Kind)47587a6dacacSDimitry Andric   static bool MayBeDependent(SourceLocIdentKind Kind) {
47597a6dacacSDimitry Andric     switch (Kind) {
47607a6dacacSDimitry Andric     case SourceLocIdentKind::Function:
47617a6dacacSDimitry Andric     case SourceLocIdentKind::FuncSig:
47627a6dacacSDimitry Andric     case SourceLocIdentKind::SourceLocStruct:
47637a6dacacSDimitry Andric       return true;
47647a6dacacSDimitry Andric     default:
47657a6dacacSDimitry Andric       return false;
47667a6dacacSDimitry Andric     }
47677a6dacacSDimitry Andric   }
47687a6dacacSDimitry Andric 
47690b57cec5SDimitry Andric private:
47700b57cec5SDimitry Andric   friend class ASTStmtReader;
47710b57cec5SDimitry Andric };
47720b57cec5SDimitry Andric 
47730b57cec5SDimitry Andric /// Describes an C or C++ initializer list.
47740b57cec5SDimitry Andric ///
47750b57cec5SDimitry Andric /// InitListExpr describes an initializer list, which can be used to
47760b57cec5SDimitry Andric /// initialize objects of different types, including
47770b57cec5SDimitry Andric /// struct/class/union types, arrays, and vectors. For example:
47780b57cec5SDimitry Andric ///
47790b57cec5SDimitry Andric /// @code
47800b57cec5SDimitry Andric /// struct foo x = { 1, { 2, 3 } };
47810b57cec5SDimitry Andric /// @endcode
47820b57cec5SDimitry Andric ///
47830b57cec5SDimitry Andric /// Prior to semantic analysis, an initializer list will represent the
47840b57cec5SDimitry Andric /// initializer list as written by the user, but will have the
47850b57cec5SDimitry Andric /// placeholder type "void". This initializer list is called the
47860b57cec5SDimitry Andric /// syntactic form of the initializer, and may contain C99 designated
47870b57cec5SDimitry Andric /// initializers (represented as DesignatedInitExprs), initializations
47880b57cec5SDimitry Andric /// of subobject members without explicit braces, and so on. Clients
47890b57cec5SDimitry Andric /// interested in the original syntax of the initializer list should
47900b57cec5SDimitry Andric /// use the syntactic form of the initializer list.
47910b57cec5SDimitry Andric ///
47920b57cec5SDimitry Andric /// After semantic analysis, the initializer list will represent the
47930b57cec5SDimitry Andric /// semantic form of the initializer, where the initializations of all
47940b57cec5SDimitry Andric /// subobjects are made explicit with nested InitListExpr nodes and
47950b57cec5SDimitry Andric /// C99 designators have been eliminated by placing the designated
47960b57cec5SDimitry Andric /// initializations into the subobject they initialize. Additionally,
47970b57cec5SDimitry Andric /// any "holes" in the initialization, where no initializer has been
47980b57cec5SDimitry Andric /// specified for a particular subobject, will be replaced with
47990b57cec5SDimitry Andric /// implicitly-generated ImplicitValueInitExpr expressions that
48000b57cec5SDimitry Andric /// value-initialize the subobjects. Note, however, that the
48010b57cec5SDimitry Andric /// initializer lists may still have fewer initializers than there are
48020b57cec5SDimitry Andric /// elements to initialize within the object.
48030b57cec5SDimitry Andric ///
48040b57cec5SDimitry Andric /// After semantic analysis has completed, given an initializer list,
48050b57cec5SDimitry Andric /// method isSemanticForm() returns true if and only if this is the
48060b57cec5SDimitry Andric /// semantic form of the initializer list (note: the same AST node
48070b57cec5SDimitry Andric /// may at the same time be the syntactic form).
48080b57cec5SDimitry Andric /// Given the semantic form of the initializer list, one can retrieve
48090b57cec5SDimitry Andric /// the syntactic form of that initializer list (when different)
48100b57cec5SDimitry Andric /// using method getSyntacticForm(); the method returns null if applied
48110b57cec5SDimitry Andric /// to a initializer list which is already in syntactic form.
48120b57cec5SDimitry Andric /// Similarly, given the syntactic form (i.e., an initializer list such
48130b57cec5SDimitry Andric /// that isSemanticForm() returns false), one can retrieve the semantic
48140b57cec5SDimitry Andric /// form using method getSemanticForm().
48150b57cec5SDimitry Andric /// Since many initializer lists have the same syntactic and semantic forms,
48160b57cec5SDimitry Andric /// getSyntacticForm() may return NULL, indicating that the current
48170b57cec5SDimitry Andric /// semantic initializer list also serves as its syntactic form.
48180b57cec5SDimitry Andric class InitListExpr : public Expr {
48190b57cec5SDimitry Andric   // FIXME: Eliminate this vector in favor of ASTContext allocation
48200b57cec5SDimitry Andric   typedef ASTVector<Stmt *> InitExprsTy;
48210b57cec5SDimitry Andric   InitExprsTy InitExprs;
48220b57cec5SDimitry Andric   SourceLocation LBraceLoc, RBraceLoc;
48230b57cec5SDimitry Andric 
48240b57cec5SDimitry Andric   /// The alternative form of the initializer list (if it exists).
48250b57cec5SDimitry Andric   /// The int part of the pair stores whether this initializer list is
48260b57cec5SDimitry Andric   /// in semantic form. If not null, the pointer points to:
48270b57cec5SDimitry Andric   ///   - the syntactic form, if this is in semantic form;
48280b57cec5SDimitry Andric   ///   - the semantic form, if this is in syntactic form.
48290b57cec5SDimitry Andric   llvm::PointerIntPair<InitListExpr *, 1, bool> AltForm;
48300b57cec5SDimitry Andric 
48310b57cec5SDimitry Andric   /// Either:
48320b57cec5SDimitry Andric   ///  If this initializer list initializes an array with more elements than
48330b57cec5SDimitry Andric   ///  there are initializers in the list, specifies an expression to be used
48340b57cec5SDimitry Andric   ///  for value initialization of the rest of the elements.
48350b57cec5SDimitry Andric   /// Or
48360b57cec5SDimitry Andric   ///  If this initializer list initializes a union, specifies which
48370b57cec5SDimitry Andric   ///  field within the union will be initialized.
48380b57cec5SDimitry Andric   llvm::PointerUnion<Expr *, FieldDecl *> ArrayFillerOrUnionFieldInit;
48390b57cec5SDimitry Andric 
48400b57cec5SDimitry Andric public:
48410b57cec5SDimitry Andric   InitListExpr(const ASTContext &C, SourceLocation lbraceloc,
48420b57cec5SDimitry Andric                ArrayRef<Expr*> initExprs, SourceLocation rbraceloc);
48430b57cec5SDimitry Andric 
48440b57cec5SDimitry Andric   /// Build an empty initializer list.
InitListExpr(EmptyShell Empty)48450b57cec5SDimitry Andric   explicit InitListExpr(EmptyShell Empty)
48460b57cec5SDimitry Andric     : Expr(InitListExprClass, Empty), AltForm(nullptr, true) { }
48470b57cec5SDimitry Andric 
getNumInits()48480b57cec5SDimitry Andric   unsigned getNumInits() const { return InitExprs.size(); }
48490b57cec5SDimitry Andric 
48500b57cec5SDimitry Andric   /// Retrieve the set of initializers.
getInits()48510b57cec5SDimitry Andric   Expr **getInits() { return reinterpret_cast<Expr **>(InitExprs.data()); }
48520b57cec5SDimitry Andric 
48530b57cec5SDimitry Andric   /// Retrieve the set of initializers.
getInits()48540b57cec5SDimitry Andric   Expr * const *getInits() const {
48550b57cec5SDimitry Andric     return reinterpret_cast<Expr * const *>(InitExprs.data());
48560b57cec5SDimitry Andric   }
48570b57cec5SDimitry Andric 
inits()4858bdd1243dSDimitry Andric   ArrayRef<Expr *> inits() { return llvm::ArrayRef(getInits(), getNumInits()); }
48590b57cec5SDimitry Andric 
inits()48600b57cec5SDimitry Andric   ArrayRef<Expr *> inits() const {
4861bdd1243dSDimitry Andric     return llvm::ArrayRef(getInits(), getNumInits());
48620b57cec5SDimitry Andric   }
48630b57cec5SDimitry Andric 
getInit(unsigned Init)48640b57cec5SDimitry Andric   const Expr *getInit(unsigned Init) const {
48650b57cec5SDimitry Andric     assert(Init < getNumInits() && "Initializer access out of range!");
48660b57cec5SDimitry Andric     return cast_or_null<Expr>(InitExprs[Init]);
48670b57cec5SDimitry Andric   }
48680b57cec5SDimitry Andric 
getInit(unsigned Init)48690b57cec5SDimitry Andric   Expr *getInit(unsigned Init) {
48700b57cec5SDimitry Andric     assert(Init < getNumInits() && "Initializer access out of range!");
48710b57cec5SDimitry Andric     return cast_or_null<Expr>(InitExprs[Init]);
48720b57cec5SDimitry Andric   }
48730b57cec5SDimitry Andric 
setInit(unsigned Init,Expr * expr)48740b57cec5SDimitry Andric   void setInit(unsigned Init, Expr *expr) {
48750b57cec5SDimitry Andric     assert(Init < getNumInits() && "Initializer access out of range!");
48760b57cec5SDimitry Andric     InitExprs[Init] = expr;
48770b57cec5SDimitry Andric 
48785ffd83dbSDimitry Andric     if (expr)
48795ffd83dbSDimitry Andric       setDependence(getDependence() | expr->getDependence());
48800b57cec5SDimitry Andric   }
48810b57cec5SDimitry Andric 
4882e8d8bef9SDimitry Andric   /// Mark the semantic form of the InitListExpr as error when the semantic
4883e8d8bef9SDimitry Andric   /// analysis fails.
markError()4884e8d8bef9SDimitry Andric   void markError() {
4885e8d8bef9SDimitry Andric     assert(isSemanticForm());
4886e8d8bef9SDimitry Andric     setDependence(getDependence() | ExprDependence::ErrorDependent);
4887e8d8bef9SDimitry Andric   }
4888e8d8bef9SDimitry Andric 
48890b57cec5SDimitry Andric   /// Reserve space for some number of initializers.
48900b57cec5SDimitry Andric   void reserveInits(const ASTContext &C, unsigned NumInits);
48910b57cec5SDimitry Andric 
48920b57cec5SDimitry Andric   /// Specify the number of initializers
48930b57cec5SDimitry Andric   ///
48940b57cec5SDimitry Andric   /// If there are more than @p NumInits initializers, the remaining
48950b57cec5SDimitry Andric   /// initializers will be destroyed. If there are fewer than @p
48960b57cec5SDimitry Andric   /// NumInits initializers, NULL expressions will be added for the
48970b57cec5SDimitry Andric   /// unknown initializers.
48980b57cec5SDimitry Andric   void resizeInits(const ASTContext &Context, unsigned NumInits);
48990b57cec5SDimitry Andric 
49000b57cec5SDimitry Andric   /// Updates the initializer at index @p Init with the new
49010b57cec5SDimitry Andric   /// expression @p expr, and returns the old expression at that
49020b57cec5SDimitry Andric   /// location.
49030b57cec5SDimitry Andric   ///
49040b57cec5SDimitry Andric   /// When @p Init is out of range for this initializer list, the
49050b57cec5SDimitry Andric   /// initializer list will be extended with NULL expressions to
49060b57cec5SDimitry Andric   /// accommodate the new entry.
49070b57cec5SDimitry Andric   Expr *updateInit(const ASTContext &C, unsigned Init, Expr *expr);
49080b57cec5SDimitry Andric 
49090b57cec5SDimitry Andric   /// If this initializer list initializes an array with more elements
49100b57cec5SDimitry Andric   /// than there are initializers in the list, specifies an expression to be
49110b57cec5SDimitry Andric   /// used for value initialization of the rest of the elements.
getArrayFiller()49120b57cec5SDimitry Andric   Expr *getArrayFiller() {
49130b57cec5SDimitry Andric     return ArrayFillerOrUnionFieldInit.dyn_cast<Expr *>();
49140b57cec5SDimitry Andric   }
getArrayFiller()49150b57cec5SDimitry Andric   const Expr *getArrayFiller() const {
49160b57cec5SDimitry Andric     return const_cast<InitListExpr *>(this)->getArrayFiller();
49170b57cec5SDimitry Andric   }
49180b57cec5SDimitry Andric   void setArrayFiller(Expr *filler);
49190b57cec5SDimitry Andric 
49200b57cec5SDimitry Andric   /// Return true if this is an array initializer and its array "filler"
49210b57cec5SDimitry Andric   /// has been set.
hasArrayFiller()49220b57cec5SDimitry Andric   bool hasArrayFiller() const { return getArrayFiller(); }
49230b57cec5SDimitry Andric 
492406c3fb27SDimitry Andric   /// Determine whether this initializer list contains a designated initializer.
hasDesignatedInit()492506c3fb27SDimitry Andric   bool hasDesignatedInit() const {
492606c3fb27SDimitry Andric     return std::any_of(begin(), end(), [](const Stmt *S) {
492706c3fb27SDimitry Andric       return isa<DesignatedInitExpr>(S);
492806c3fb27SDimitry Andric     });
492906c3fb27SDimitry Andric   }
493006c3fb27SDimitry Andric 
49310b57cec5SDimitry Andric   /// If this initializes a union, specifies which field in the
49320b57cec5SDimitry Andric   /// union to initialize.
49330b57cec5SDimitry Andric   ///
49340b57cec5SDimitry Andric   /// Typically, this field is the first named field within the
49350b57cec5SDimitry Andric   /// union. However, a designated initializer can specify the
49360b57cec5SDimitry Andric   /// initialization of a different field within the union.
getInitializedFieldInUnion()49370b57cec5SDimitry Andric   FieldDecl *getInitializedFieldInUnion() {
49380b57cec5SDimitry Andric     return ArrayFillerOrUnionFieldInit.dyn_cast<FieldDecl *>();
49390b57cec5SDimitry Andric   }
getInitializedFieldInUnion()49400b57cec5SDimitry Andric   const FieldDecl *getInitializedFieldInUnion() const {
49410b57cec5SDimitry Andric     return const_cast<InitListExpr *>(this)->getInitializedFieldInUnion();
49420b57cec5SDimitry Andric   }
setInitializedFieldInUnion(FieldDecl * FD)49430b57cec5SDimitry Andric   void setInitializedFieldInUnion(FieldDecl *FD) {
49440b57cec5SDimitry Andric     assert((FD == nullptr
49450b57cec5SDimitry Andric             || getInitializedFieldInUnion() == nullptr
49460b57cec5SDimitry Andric             || getInitializedFieldInUnion() == FD)
49470b57cec5SDimitry Andric            && "Only one field of a union may be initialized at a time!");
49480b57cec5SDimitry Andric     ArrayFillerOrUnionFieldInit = FD;
49490b57cec5SDimitry Andric   }
49500b57cec5SDimitry Andric 
49510b57cec5SDimitry Andric   // Explicit InitListExpr's originate from source code (and have valid source
49520b57cec5SDimitry Andric   // locations). Implicit InitListExpr's are created by the semantic analyzer.
4953a7dea167SDimitry Andric   // FIXME: This is wrong; InitListExprs created by semantic analysis have
4954a7dea167SDimitry Andric   // valid source locations too!
isExplicit()49550b57cec5SDimitry Andric   bool isExplicit() const {
49560b57cec5SDimitry Andric     return LBraceLoc.isValid() && RBraceLoc.isValid();
49570b57cec5SDimitry Andric   }
49580b57cec5SDimitry Andric 
495906c3fb27SDimitry Andric   /// Is this an initializer for an array of characters, initialized by a string
496006c3fb27SDimitry Andric   /// literal or an @encode?
49610b57cec5SDimitry Andric   bool isStringLiteralInit() const;
49620b57cec5SDimitry Andric 
49630b57cec5SDimitry Andric   /// Is this a transparent initializer list (that is, an InitListExpr that is
49640b57cec5SDimitry Andric   /// purely syntactic, and whose semantics are that of the sole contained
49650b57cec5SDimitry Andric   /// initializer)?
49660b57cec5SDimitry Andric   bool isTransparent() const;
49670b57cec5SDimitry Andric 
49680b57cec5SDimitry Andric   /// Is this the zero initializer {0} in a language which considers it
49690b57cec5SDimitry Andric   /// idiomatic?
49700b57cec5SDimitry Andric   bool isIdiomaticZeroInitializer(const LangOptions &LangOpts) const;
49710b57cec5SDimitry Andric 
getLBraceLoc()49720b57cec5SDimitry Andric   SourceLocation getLBraceLoc() const { return LBraceLoc; }
setLBraceLoc(SourceLocation Loc)49730b57cec5SDimitry Andric   void setLBraceLoc(SourceLocation Loc) { LBraceLoc = Loc; }
getRBraceLoc()49740b57cec5SDimitry Andric   SourceLocation getRBraceLoc() const { return RBraceLoc; }
setRBraceLoc(SourceLocation Loc)49750b57cec5SDimitry Andric   void setRBraceLoc(SourceLocation Loc) { RBraceLoc = Loc; }
49760b57cec5SDimitry Andric 
isSemanticForm()49770b57cec5SDimitry Andric   bool isSemanticForm() const { return AltForm.getInt(); }
getSemanticForm()49780b57cec5SDimitry Andric   InitListExpr *getSemanticForm() const {
49790b57cec5SDimitry Andric     return isSemanticForm() ? nullptr : AltForm.getPointer();
49800b57cec5SDimitry Andric   }
isSyntacticForm()49810b57cec5SDimitry Andric   bool isSyntacticForm() const {
49820b57cec5SDimitry Andric     return !AltForm.getInt() || !AltForm.getPointer();
49830b57cec5SDimitry Andric   }
getSyntacticForm()49840b57cec5SDimitry Andric   InitListExpr *getSyntacticForm() const {
49850b57cec5SDimitry Andric     return isSemanticForm() ? AltForm.getPointer() : nullptr;
49860b57cec5SDimitry Andric   }
49870b57cec5SDimitry Andric 
setSyntacticForm(InitListExpr * Init)49880b57cec5SDimitry Andric   void setSyntacticForm(InitListExpr *Init) {
49890b57cec5SDimitry Andric     AltForm.setPointer(Init);
49900b57cec5SDimitry Andric     AltForm.setInt(true);
49910b57cec5SDimitry Andric     Init->AltForm.setPointer(this);
49920b57cec5SDimitry Andric     Init->AltForm.setInt(false);
49930b57cec5SDimitry Andric   }
49940b57cec5SDimitry Andric 
hadArrayRangeDesignator()49950b57cec5SDimitry Andric   bool hadArrayRangeDesignator() const {
49960b57cec5SDimitry Andric     return InitListExprBits.HadArrayRangeDesignator != 0;
49970b57cec5SDimitry Andric   }
49980b57cec5SDimitry Andric   void sawArrayRangeDesignator(bool ARD = true) {
49990b57cec5SDimitry Andric     InitListExprBits.HadArrayRangeDesignator = ARD;
50000b57cec5SDimitry Andric   }
50010b57cec5SDimitry Andric 
50020b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY;
50030b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY;
50040b57cec5SDimitry Andric 
classof(const Stmt * T)50050b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
50060b57cec5SDimitry Andric     return T->getStmtClass() == InitListExprClass;
50070b57cec5SDimitry Andric   }
50080b57cec5SDimitry Andric 
50090b57cec5SDimitry Andric   // Iterators
children()50100b57cec5SDimitry Andric   child_range children() {
50110b57cec5SDimitry Andric     const_child_range CCR = const_cast<const InitListExpr *>(this)->children();
50120b57cec5SDimitry Andric     return child_range(cast_away_const(CCR.begin()),
50130b57cec5SDimitry Andric                        cast_away_const(CCR.end()));
50140b57cec5SDimitry Andric   }
50150b57cec5SDimitry Andric 
children()50160b57cec5SDimitry Andric   const_child_range children() const {
50170b57cec5SDimitry Andric     // FIXME: This does not include the array filler expression.
50180b57cec5SDimitry Andric     if (InitExprs.empty())
50190b57cec5SDimitry Andric       return const_child_range(const_child_iterator(), const_child_iterator());
50200b57cec5SDimitry Andric     return const_child_range(&InitExprs[0], &InitExprs[0] + InitExprs.size());
50210b57cec5SDimitry Andric   }
50220b57cec5SDimitry Andric 
50230b57cec5SDimitry Andric   typedef InitExprsTy::iterator iterator;
50240b57cec5SDimitry Andric   typedef InitExprsTy::const_iterator const_iterator;
50250b57cec5SDimitry Andric   typedef InitExprsTy::reverse_iterator reverse_iterator;
50260b57cec5SDimitry Andric   typedef InitExprsTy::const_reverse_iterator const_reverse_iterator;
50270b57cec5SDimitry Andric 
begin()50280b57cec5SDimitry Andric   iterator begin() { return InitExprs.begin(); }
begin()50290b57cec5SDimitry Andric   const_iterator begin() const { return InitExprs.begin(); }
end()50300b57cec5SDimitry Andric   iterator end() { return InitExprs.end(); }
end()50310b57cec5SDimitry Andric   const_iterator end() const { return InitExprs.end(); }
rbegin()50320b57cec5SDimitry Andric   reverse_iterator rbegin() { return InitExprs.rbegin(); }
rbegin()50330b57cec5SDimitry Andric   const_reverse_iterator rbegin() const { return InitExprs.rbegin(); }
rend()50340b57cec5SDimitry Andric   reverse_iterator rend() { return InitExprs.rend(); }
rend()50350b57cec5SDimitry Andric   const_reverse_iterator rend() const { return InitExprs.rend(); }
50360b57cec5SDimitry Andric 
50370b57cec5SDimitry Andric   friend class ASTStmtReader;
50380b57cec5SDimitry Andric   friend class ASTStmtWriter;
50390b57cec5SDimitry Andric };
50400b57cec5SDimitry Andric 
50410b57cec5SDimitry Andric /// Represents a C99 designated initializer expression.
50420b57cec5SDimitry Andric ///
50430b57cec5SDimitry Andric /// A designated initializer expression (C99 6.7.8) contains one or
50440b57cec5SDimitry Andric /// more designators (which can be field designators, array
50450b57cec5SDimitry Andric /// designators, or GNU array-range designators) followed by an
50460b57cec5SDimitry Andric /// expression that initializes the field or element(s) that the
50470b57cec5SDimitry Andric /// designators refer to. For example, given:
50480b57cec5SDimitry Andric ///
50490b57cec5SDimitry Andric /// @code
50500b57cec5SDimitry Andric /// struct point {
50510b57cec5SDimitry Andric ///   double x;
50520b57cec5SDimitry Andric ///   double y;
50530b57cec5SDimitry Andric /// };
50540b57cec5SDimitry Andric /// struct point ptarray[10] = { [2].y = 1.0, [2].x = 2.0, [0].x = 1.0 };
50550b57cec5SDimitry Andric /// @endcode
50560b57cec5SDimitry Andric ///
50570b57cec5SDimitry Andric /// The InitListExpr contains three DesignatedInitExprs, the first of
50580b57cec5SDimitry Andric /// which covers @c [2].y=1.0. This DesignatedInitExpr will have two
50590b57cec5SDimitry Andric /// designators, one array designator for @c [2] followed by one field
50600b57cec5SDimitry Andric /// designator for @c .y. The initialization expression will be 1.0.
50610b57cec5SDimitry Andric class DesignatedInitExpr final
50620b57cec5SDimitry Andric     : public Expr,
50630b57cec5SDimitry Andric       private llvm::TrailingObjects<DesignatedInitExpr, Stmt *> {
50640b57cec5SDimitry Andric public:
50650b57cec5SDimitry Andric   /// Forward declaration of the Designator class.
50660b57cec5SDimitry Andric   class Designator;
50670b57cec5SDimitry Andric 
50680b57cec5SDimitry Andric private:
50690b57cec5SDimitry Andric   /// The location of the '=' or ':' prior to the actual initializer
50700b57cec5SDimitry Andric   /// expression.
50710b57cec5SDimitry Andric   SourceLocation EqualOrColonLoc;
50720b57cec5SDimitry Andric 
50730b57cec5SDimitry Andric   /// Whether this designated initializer used the GNU deprecated
50740b57cec5SDimitry Andric   /// syntax rather than the C99 '=' syntax.
50755f757f3fSDimitry Andric   LLVM_PREFERRED_TYPE(bool)
50760b57cec5SDimitry Andric   unsigned GNUSyntax : 1;
50770b57cec5SDimitry Andric 
50780b57cec5SDimitry Andric   /// The number of designators in this initializer expression.
50790b57cec5SDimitry Andric   unsigned NumDesignators : 15;
50800b57cec5SDimitry Andric 
50810b57cec5SDimitry Andric   /// The number of subexpressions of this initializer expression,
50820b57cec5SDimitry Andric   /// which contains both the initializer and any additional
50830b57cec5SDimitry Andric   /// expressions used by array and array-range designators.
50840b57cec5SDimitry Andric   unsigned NumSubExprs : 16;
50850b57cec5SDimitry Andric 
50860b57cec5SDimitry Andric   /// The designators in this designated initialization
50870b57cec5SDimitry Andric   /// expression.
50880b57cec5SDimitry Andric   Designator *Designators;
50890b57cec5SDimitry Andric 
50900b57cec5SDimitry Andric   DesignatedInitExpr(const ASTContext &C, QualType Ty,
50910b57cec5SDimitry Andric                      llvm::ArrayRef<Designator> Designators,
50920b57cec5SDimitry Andric                      SourceLocation EqualOrColonLoc, bool GNUSyntax,
50930b57cec5SDimitry Andric                      ArrayRef<Expr *> IndexExprs, Expr *Init);
50940b57cec5SDimitry Andric 
DesignatedInitExpr(unsigned NumSubExprs)50950b57cec5SDimitry Andric   explicit DesignatedInitExpr(unsigned NumSubExprs)
50960b57cec5SDimitry Andric     : Expr(DesignatedInitExprClass, EmptyShell()),
50970b57cec5SDimitry Andric       NumDesignators(0), NumSubExprs(NumSubExprs), Designators(nullptr) { }
50980b57cec5SDimitry Andric 
50990b57cec5SDimitry Andric public:
510006c3fb27SDimitry Andric   /// Represents a single C99 designator.
510106c3fb27SDimitry Andric   ///
510206c3fb27SDimitry Andric   /// @todo This class is infuriatingly similar to clang::Designator,
510306c3fb27SDimitry Andric   /// but minor differences (storing indices vs. storing pointers)
510406c3fb27SDimitry Andric   /// keep us from reusing it. Try harder, later, to rectify these
510506c3fb27SDimitry Andric   /// differences.
510606c3fb27SDimitry Andric   class Designator {
51070b57cec5SDimitry Andric     /// A field designator, e.g., ".x".
510806c3fb27SDimitry Andric     struct FieldDesignatorInfo {
51090b57cec5SDimitry Andric       /// Refers to the field that is being initialized. The low bit
51100b57cec5SDimitry Andric       /// of this field determines whether this is actually a pointer
51110b57cec5SDimitry Andric       /// to an IdentifierInfo (if 1) or a FieldDecl (if 0). When
51120b57cec5SDimitry Andric       /// initially constructed, a field designator will store an
51130b57cec5SDimitry Andric       /// IdentifierInfo*. After semantic analysis has resolved that
51140b57cec5SDimitry Andric       /// name, the field designator will instead store a FieldDecl*.
51150b57cec5SDimitry Andric       uintptr_t NameOrField;
51160b57cec5SDimitry Andric 
51170b57cec5SDimitry Andric       /// The location of the '.' in the designated initializer.
5118e8d8bef9SDimitry Andric       SourceLocation DotLoc;
51190b57cec5SDimitry Andric 
51200b57cec5SDimitry Andric       /// The location of the field name in the designated initializer.
5121e8d8bef9SDimitry Andric       SourceLocation FieldLoc;
512206c3fb27SDimitry Andric 
FieldDesignatorInfoFieldDesignatorInfo512306c3fb27SDimitry Andric       FieldDesignatorInfo(const IdentifierInfo *II, SourceLocation DotLoc,
512406c3fb27SDimitry Andric                           SourceLocation FieldLoc)
512506c3fb27SDimitry Andric           : NameOrField(reinterpret_cast<uintptr_t>(II) | 0x1), DotLoc(DotLoc),
512606c3fb27SDimitry Andric             FieldLoc(FieldLoc) {}
51270b57cec5SDimitry Andric     };
51280b57cec5SDimitry Andric 
512906c3fb27SDimitry Andric     /// An array or GNU array-range designator, e.g., "[9]" or "[10...15]".
513006c3fb27SDimitry Andric     struct ArrayOrRangeDesignatorInfo {
51310b57cec5SDimitry Andric       /// Location of the first index expression within the designated
51320b57cec5SDimitry Andric       /// initializer expression's list of subexpressions.
51330b57cec5SDimitry Andric       unsigned Index;
513406c3fb27SDimitry Andric 
51350b57cec5SDimitry Andric       /// The location of the '[' starting the array range designator.
5136e8d8bef9SDimitry Andric       SourceLocation LBracketLoc;
513706c3fb27SDimitry Andric 
51380b57cec5SDimitry Andric       /// The location of the ellipsis separating the start and end
51390b57cec5SDimitry Andric       /// indices. Only valid for GNU array-range designators.
5140e8d8bef9SDimitry Andric       SourceLocation EllipsisLoc;
514106c3fb27SDimitry Andric 
51420b57cec5SDimitry Andric       /// The location of the ']' terminating the array range designator.
5143e8d8bef9SDimitry Andric       SourceLocation RBracketLoc;
514406c3fb27SDimitry Andric 
ArrayOrRangeDesignatorInfoArrayOrRangeDesignatorInfo514506c3fb27SDimitry Andric       ArrayOrRangeDesignatorInfo(unsigned Index, SourceLocation LBracketLoc,
514606c3fb27SDimitry Andric                                  SourceLocation RBracketLoc)
514706c3fb27SDimitry Andric           : Index(Index), LBracketLoc(LBracketLoc), RBracketLoc(RBracketLoc) {}
514806c3fb27SDimitry Andric 
ArrayOrRangeDesignatorInfoArrayOrRangeDesignatorInfo514906c3fb27SDimitry Andric       ArrayOrRangeDesignatorInfo(unsigned Index,
515006c3fb27SDimitry Andric                                  SourceLocation LBracketLoc,
515106c3fb27SDimitry Andric                                  SourceLocation EllipsisLoc,
515206c3fb27SDimitry Andric                                  SourceLocation RBracketLoc)
515306c3fb27SDimitry Andric           : Index(Index), LBracketLoc(LBracketLoc), EllipsisLoc(EllipsisLoc),
515406c3fb27SDimitry Andric             RBracketLoc(RBracketLoc) {}
51550b57cec5SDimitry Andric     };
51560b57cec5SDimitry Andric 
51570b57cec5SDimitry Andric     /// The kind of designator this describes.
515806c3fb27SDimitry Andric     enum DesignatorKind {
51590b57cec5SDimitry Andric       FieldDesignator,
51600b57cec5SDimitry Andric       ArrayDesignator,
51610b57cec5SDimitry Andric       ArrayRangeDesignator
516206c3fb27SDimitry Andric     };
516306c3fb27SDimitry Andric 
516406c3fb27SDimitry Andric     DesignatorKind Kind;
51650b57cec5SDimitry Andric 
51660b57cec5SDimitry Andric     union {
51670b57cec5SDimitry Andric       /// A field designator, e.g., ".x".
516806c3fb27SDimitry Andric       struct FieldDesignatorInfo FieldInfo;
516906c3fb27SDimitry Andric 
51700b57cec5SDimitry Andric       /// An array or GNU array-range designator, e.g., "[9]" or "[10..15]".
517106c3fb27SDimitry Andric       struct ArrayOrRangeDesignatorInfo ArrayOrRangeInfo;
51720b57cec5SDimitry Andric     };
517306c3fb27SDimitry Andric 
Designator(DesignatorKind Kind)517406c3fb27SDimitry Andric     Designator(DesignatorKind Kind) : Kind(Kind) {}
51750b57cec5SDimitry Andric 
51760b57cec5SDimitry Andric   public:
Designator()51770b57cec5SDimitry Andric     Designator() {}
51780b57cec5SDimitry Andric 
isFieldDesignator()51790b57cec5SDimitry Andric     bool isFieldDesignator() const { return Kind == FieldDesignator; }
isArrayDesignator()51800b57cec5SDimitry Andric     bool isArrayDesignator() const { return Kind == ArrayDesignator; }
isArrayRangeDesignator()51810b57cec5SDimitry Andric     bool isArrayRangeDesignator() const { return Kind == ArrayRangeDesignator; }
51820b57cec5SDimitry Andric 
518306c3fb27SDimitry Andric     //===------------------------------------------------------------------===//
518406c3fb27SDimitry Andric     // FieldDesignatorInfo
51850b57cec5SDimitry Andric 
518606c3fb27SDimitry Andric     /// Creates a field designator.
CreateFieldDesignator(const IdentifierInfo * FieldName,SourceLocation DotLoc,SourceLocation FieldLoc)518706c3fb27SDimitry Andric     static Designator CreateFieldDesignator(const IdentifierInfo *FieldName,
518806c3fb27SDimitry Andric                                             SourceLocation DotLoc,
518906c3fb27SDimitry Andric                                             SourceLocation FieldLoc) {
519006c3fb27SDimitry Andric       Designator D(FieldDesignator);
519106c3fb27SDimitry Andric       new (&D.FieldInfo) FieldDesignatorInfo(FieldName, DotLoc, FieldLoc);
519206c3fb27SDimitry Andric       return D;
51930b57cec5SDimitry Andric     }
51940b57cec5SDimitry Andric 
519506c3fb27SDimitry Andric     const IdentifierInfo *getFieldName() const;
519606c3fb27SDimitry Andric 
getFieldDecl()519706c3fb27SDimitry Andric     FieldDecl *getFieldDecl() const {
519806c3fb27SDimitry Andric       assert(isFieldDesignator() && "Only valid on a field designator");
519906c3fb27SDimitry Andric       if (FieldInfo.NameOrField & 0x01)
520006c3fb27SDimitry Andric         return nullptr;
520106c3fb27SDimitry Andric       return reinterpret_cast<FieldDecl *>(FieldInfo.NameOrField);
520206c3fb27SDimitry Andric     }
520306c3fb27SDimitry Andric 
setFieldDecl(FieldDecl * FD)520406c3fb27SDimitry Andric     void setFieldDecl(FieldDecl *FD) {
520506c3fb27SDimitry Andric       assert(isFieldDesignator() && "Only valid on a field designator");
520606c3fb27SDimitry Andric       FieldInfo.NameOrField = reinterpret_cast<uintptr_t>(FD);
52070b57cec5SDimitry Andric     }
52080b57cec5SDimitry Andric 
getDotLoc()52090b57cec5SDimitry Andric     SourceLocation getDotLoc() const {
521006c3fb27SDimitry Andric       assert(isFieldDesignator() && "Only valid on a field designator");
521106c3fb27SDimitry Andric       return FieldInfo.DotLoc;
52120b57cec5SDimitry Andric     }
52130b57cec5SDimitry Andric 
getFieldLoc()52140b57cec5SDimitry Andric     SourceLocation getFieldLoc() const {
521506c3fb27SDimitry Andric       assert(isFieldDesignator() && "Only valid on a field designator");
521606c3fb27SDimitry Andric       return FieldInfo.FieldLoc;
521706c3fb27SDimitry Andric     }
521806c3fb27SDimitry Andric 
521906c3fb27SDimitry Andric     //===------------------------------------------------------------------===//
522006c3fb27SDimitry Andric     // ArrayOrRangeDesignator
522106c3fb27SDimitry Andric 
522206c3fb27SDimitry Andric     /// Creates an array designator.
CreateArrayDesignator(unsigned Index,SourceLocation LBracketLoc,SourceLocation RBracketLoc)522306c3fb27SDimitry Andric     static Designator CreateArrayDesignator(unsigned Index,
522406c3fb27SDimitry Andric                                             SourceLocation LBracketLoc,
522506c3fb27SDimitry Andric                                             SourceLocation RBracketLoc) {
522606c3fb27SDimitry Andric       Designator D(ArrayDesignator);
522706c3fb27SDimitry Andric       new (&D.ArrayOrRangeInfo) ArrayOrRangeDesignatorInfo(Index, LBracketLoc,
522806c3fb27SDimitry Andric                                                            RBracketLoc);
522906c3fb27SDimitry Andric       return D;
523006c3fb27SDimitry Andric     }
523106c3fb27SDimitry Andric 
523206c3fb27SDimitry Andric     /// Creates a GNU array-range designator.
CreateArrayRangeDesignator(unsigned Index,SourceLocation LBracketLoc,SourceLocation EllipsisLoc,SourceLocation RBracketLoc)523306c3fb27SDimitry Andric     static Designator CreateArrayRangeDesignator(unsigned Index,
523406c3fb27SDimitry Andric                                                  SourceLocation LBracketLoc,
523506c3fb27SDimitry Andric                                                  SourceLocation EllipsisLoc,
523606c3fb27SDimitry Andric                                                  SourceLocation RBracketLoc) {
523706c3fb27SDimitry Andric       Designator D(ArrayRangeDesignator);
523806c3fb27SDimitry Andric       new (&D.ArrayOrRangeInfo) ArrayOrRangeDesignatorInfo(Index, LBracketLoc,
523906c3fb27SDimitry Andric                                                            EllipsisLoc,
524006c3fb27SDimitry Andric                                                            RBracketLoc);
524106c3fb27SDimitry Andric       return D;
524206c3fb27SDimitry Andric     }
524306c3fb27SDimitry Andric 
getArrayIndex()524406c3fb27SDimitry Andric     unsigned getArrayIndex() const {
524506c3fb27SDimitry Andric       assert((isArrayDesignator() || isArrayRangeDesignator()) &&
524606c3fb27SDimitry Andric              "Only valid on an array or array-range designator");
524706c3fb27SDimitry Andric       return ArrayOrRangeInfo.Index;
52480b57cec5SDimitry Andric     }
52490b57cec5SDimitry Andric 
getLBracketLoc()52500b57cec5SDimitry Andric     SourceLocation getLBracketLoc() const {
525106c3fb27SDimitry Andric       assert((isArrayDesignator() || isArrayRangeDesignator()) &&
52520b57cec5SDimitry Andric              "Only valid on an array or array-range designator");
525306c3fb27SDimitry Andric       return ArrayOrRangeInfo.LBracketLoc;
52540b57cec5SDimitry Andric     }
52550b57cec5SDimitry Andric 
getEllipsisLoc()52560b57cec5SDimitry Andric     SourceLocation getEllipsisLoc() const {
525706c3fb27SDimitry Andric       assert(isArrayRangeDesignator() &&
52580b57cec5SDimitry Andric              "Only valid on an array-range designator");
525906c3fb27SDimitry Andric       return ArrayOrRangeInfo.EllipsisLoc;
52600b57cec5SDimitry Andric     }
52610b57cec5SDimitry Andric 
getRBracketLoc()526206c3fb27SDimitry Andric     SourceLocation getRBracketLoc() const {
526306c3fb27SDimitry Andric       assert((isArrayDesignator() || isArrayRangeDesignator()) &&
52640b57cec5SDimitry Andric              "Only valid on an array or array-range designator");
526506c3fb27SDimitry Andric       return ArrayOrRangeInfo.RBracketLoc;
52660b57cec5SDimitry Andric     }
52670b57cec5SDimitry Andric 
getBeginLoc()52680b57cec5SDimitry Andric     SourceLocation getBeginLoc() const LLVM_READONLY {
526906c3fb27SDimitry Andric       if (isFieldDesignator())
52700b57cec5SDimitry Andric         return getDotLoc().isInvalid() ? getFieldLoc() : getDotLoc();
52710b57cec5SDimitry Andric       return getLBracketLoc();
52720b57cec5SDimitry Andric     }
527306c3fb27SDimitry Andric 
getEndLoc()52740b57cec5SDimitry Andric     SourceLocation getEndLoc() const LLVM_READONLY {
527506c3fb27SDimitry Andric       return isFieldDesignator() ? getFieldLoc() : getRBracketLoc();
52760b57cec5SDimitry Andric     }
527706c3fb27SDimitry Andric 
getSourceRange()52780b57cec5SDimitry Andric     SourceRange getSourceRange() const LLVM_READONLY {
52790b57cec5SDimitry Andric       return SourceRange(getBeginLoc(), getEndLoc());
52800b57cec5SDimitry Andric     }
52810b57cec5SDimitry Andric   };
52820b57cec5SDimitry Andric 
52830b57cec5SDimitry Andric   static DesignatedInitExpr *Create(const ASTContext &C,
52840b57cec5SDimitry Andric                                     llvm::ArrayRef<Designator> Designators,
52850b57cec5SDimitry Andric                                     ArrayRef<Expr*> IndexExprs,
52860b57cec5SDimitry Andric                                     SourceLocation EqualOrColonLoc,
52870b57cec5SDimitry Andric                                     bool GNUSyntax, Expr *Init);
52880b57cec5SDimitry Andric 
52890b57cec5SDimitry Andric   static DesignatedInitExpr *CreateEmpty(const ASTContext &C,
52900b57cec5SDimitry Andric                                          unsigned NumIndexExprs);
52910b57cec5SDimitry Andric 
52920b57cec5SDimitry Andric   /// Returns the number of designators in this initializer.
size()52930b57cec5SDimitry Andric   unsigned size() const { return NumDesignators; }
52940b57cec5SDimitry Andric 
52950b57cec5SDimitry Andric   // Iterator access to the designators.
designators()52960b57cec5SDimitry Andric   llvm::MutableArrayRef<Designator> designators() {
52970b57cec5SDimitry Andric     return {Designators, NumDesignators};
52980b57cec5SDimitry Andric   }
52990b57cec5SDimitry Andric 
designators()53000b57cec5SDimitry Andric   llvm::ArrayRef<Designator> designators() const {
53010b57cec5SDimitry Andric     return {Designators, NumDesignators};
53020b57cec5SDimitry Andric   }
53030b57cec5SDimitry Andric 
getDesignator(unsigned Idx)53040b57cec5SDimitry Andric   Designator *getDesignator(unsigned Idx) { return &designators()[Idx]; }
getDesignator(unsigned Idx)53050b57cec5SDimitry Andric   const Designator *getDesignator(unsigned Idx) const {
53060b57cec5SDimitry Andric     return &designators()[Idx];
53070b57cec5SDimitry Andric   }
53080b57cec5SDimitry Andric 
53090b57cec5SDimitry Andric   void setDesignators(const ASTContext &C, const Designator *Desigs,
53100b57cec5SDimitry Andric                       unsigned NumDesigs);
53110b57cec5SDimitry Andric 
53120b57cec5SDimitry Andric   Expr *getArrayIndex(const Designator &D) const;
53130b57cec5SDimitry Andric   Expr *getArrayRangeStart(const Designator &D) const;
53140b57cec5SDimitry Andric   Expr *getArrayRangeEnd(const Designator &D) const;
53150b57cec5SDimitry Andric 
53160b57cec5SDimitry Andric   /// Retrieve the location of the '=' that precedes the
53170b57cec5SDimitry Andric   /// initializer value itself, if present.
getEqualOrColonLoc()53180b57cec5SDimitry Andric   SourceLocation getEqualOrColonLoc() const { return EqualOrColonLoc; }
setEqualOrColonLoc(SourceLocation L)53190b57cec5SDimitry Andric   void setEqualOrColonLoc(SourceLocation L) { EqualOrColonLoc = L; }
53200b57cec5SDimitry Andric 
5321a7dea167SDimitry Andric   /// Whether this designated initializer should result in direct-initialization
5322a7dea167SDimitry Andric   /// of the designated subobject (eg, '{.foo{1, 2, 3}}').
isDirectInit()5323a7dea167SDimitry Andric   bool isDirectInit() const { return EqualOrColonLoc.isInvalid(); }
5324a7dea167SDimitry Andric 
53250b57cec5SDimitry Andric   /// Determines whether this designated initializer used the
53260b57cec5SDimitry Andric   /// deprecated GNU syntax for designated initializers.
usesGNUSyntax()53270b57cec5SDimitry Andric   bool usesGNUSyntax() const { return GNUSyntax; }
setGNUSyntax(bool GNU)53280b57cec5SDimitry Andric   void setGNUSyntax(bool GNU) { GNUSyntax = GNU; }
53290b57cec5SDimitry Andric 
53300b57cec5SDimitry Andric   /// Retrieve the initializer value.
getInit()53310b57cec5SDimitry Andric   Expr *getInit() const {
53320b57cec5SDimitry Andric     return cast<Expr>(*const_cast<DesignatedInitExpr*>(this)->child_begin());
53330b57cec5SDimitry Andric   }
53340b57cec5SDimitry Andric 
setInit(Expr * init)53350b57cec5SDimitry Andric   void setInit(Expr *init) {
53360b57cec5SDimitry Andric     *child_begin() = init;
53370b57cec5SDimitry Andric   }
53380b57cec5SDimitry Andric 
53390b57cec5SDimitry Andric   /// Retrieve the total number of subexpressions in this
53400b57cec5SDimitry Andric   /// designated initializer expression, including the actual
53410b57cec5SDimitry Andric   /// initialized value and any expressions that occur within array
53420b57cec5SDimitry Andric   /// and array-range designators.
getNumSubExprs()53430b57cec5SDimitry Andric   unsigned getNumSubExprs() const { return NumSubExprs; }
53440b57cec5SDimitry Andric 
getSubExpr(unsigned Idx)53450b57cec5SDimitry Andric   Expr *getSubExpr(unsigned Idx) const {
53460b57cec5SDimitry Andric     assert(Idx < NumSubExprs && "Subscript out of range");
53470b57cec5SDimitry Andric     return cast<Expr>(getTrailingObjects<Stmt *>()[Idx]);
53480b57cec5SDimitry Andric   }
53490b57cec5SDimitry Andric 
setSubExpr(unsigned Idx,Expr * E)53500b57cec5SDimitry Andric   void setSubExpr(unsigned Idx, Expr *E) {
53510b57cec5SDimitry Andric     assert(Idx < NumSubExprs && "Subscript out of range");
53520b57cec5SDimitry Andric     getTrailingObjects<Stmt *>()[Idx] = E;
53530b57cec5SDimitry Andric   }
53540b57cec5SDimitry Andric 
53550b57cec5SDimitry Andric   /// Replaces the designator at index @p Idx with the series
53560b57cec5SDimitry Andric   /// of designators in [First, Last).
53570b57cec5SDimitry Andric   void ExpandDesignator(const ASTContext &C, unsigned Idx,
53580b57cec5SDimitry Andric                         const Designator *First, const Designator *Last);
53590b57cec5SDimitry Andric 
53600b57cec5SDimitry Andric   SourceRange getDesignatorsSourceRange() const;
53610b57cec5SDimitry Andric 
53620b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY;
53630b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY;
53640b57cec5SDimitry Andric 
classof(const Stmt * T)53650b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
53660b57cec5SDimitry Andric     return T->getStmtClass() == DesignatedInitExprClass;
53670b57cec5SDimitry Andric   }
53680b57cec5SDimitry Andric 
53690b57cec5SDimitry Andric   // Iterators
children()53700b57cec5SDimitry Andric   child_range children() {
53710b57cec5SDimitry Andric     Stmt **begin = getTrailingObjects<Stmt *>();
53720b57cec5SDimitry Andric     return child_range(begin, begin + NumSubExprs);
53730b57cec5SDimitry Andric   }
children()53740b57cec5SDimitry Andric   const_child_range children() const {
53750b57cec5SDimitry Andric     Stmt * const *begin = getTrailingObjects<Stmt *>();
53760b57cec5SDimitry Andric     return const_child_range(begin, begin + NumSubExprs);
53770b57cec5SDimitry Andric   }
53780b57cec5SDimitry Andric 
53790b57cec5SDimitry Andric   friend TrailingObjects;
53800b57cec5SDimitry Andric };
53810b57cec5SDimitry Andric 
53820b57cec5SDimitry Andric /// Represents a place-holder for an object not to be initialized by
53830b57cec5SDimitry Andric /// anything.
53840b57cec5SDimitry Andric ///
53850b57cec5SDimitry Andric /// This only makes sense when it appears as part of an updater of a
53860b57cec5SDimitry Andric /// DesignatedInitUpdateExpr (see below). The base expression of a DIUE
53870b57cec5SDimitry Andric /// initializes a big object, and the NoInitExpr's mark the spots within the
53880b57cec5SDimitry Andric /// big object not to be overwritten by the updater.
53890b57cec5SDimitry Andric ///
53900b57cec5SDimitry Andric /// \see DesignatedInitUpdateExpr
53910b57cec5SDimitry Andric class NoInitExpr : public Expr {
53920b57cec5SDimitry Andric public:
NoInitExpr(QualType ty)53930b57cec5SDimitry Andric   explicit NoInitExpr(QualType ty)
5394fe6060f1SDimitry Andric       : Expr(NoInitExprClass, ty, VK_PRValue, OK_Ordinary) {
53955ffd83dbSDimitry Andric     setDependence(computeDependence(this));
53965ffd83dbSDimitry Andric   }
53970b57cec5SDimitry Andric 
NoInitExpr(EmptyShell Empty)53980b57cec5SDimitry Andric   explicit NoInitExpr(EmptyShell Empty)
53990b57cec5SDimitry Andric     : Expr(NoInitExprClass, Empty) { }
54000b57cec5SDimitry Andric 
classof(const Stmt * T)54010b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
54020b57cec5SDimitry Andric     return T->getStmtClass() == NoInitExprClass;
54030b57cec5SDimitry Andric   }
54040b57cec5SDimitry Andric 
getBeginLoc()54050b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY { return SourceLocation(); }
getEndLoc()54060b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY { return SourceLocation(); }
54070b57cec5SDimitry Andric 
54080b57cec5SDimitry Andric   // Iterators
children()54090b57cec5SDimitry Andric   child_range children() {
54100b57cec5SDimitry Andric     return child_range(child_iterator(), child_iterator());
54110b57cec5SDimitry Andric   }
children()54120b57cec5SDimitry Andric   const_child_range children() const {
54130b57cec5SDimitry Andric     return const_child_range(const_child_iterator(), const_child_iterator());
54140b57cec5SDimitry Andric   }
54150b57cec5SDimitry Andric };
54160b57cec5SDimitry Andric 
54170b57cec5SDimitry Andric // In cases like:
54180b57cec5SDimitry Andric //   struct Q { int a, b, c; };
54190b57cec5SDimitry Andric //   Q *getQ();
54200b57cec5SDimitry Andric //   void foo() {
54210b57cec5SDimitry Andric //     struct A { Q q; } a = { *getQ(), .q.b = 3 };
54220b57cec5SDimitry Andric //   }
54230b57cec5SDimitry Andric //
54240b57cec5SDimitry Andric // We will have an InitListExpr for a, with type A, and then a
54250b57cec5SDimitry Andric // DesignatedInitUpdateExpr for "a.q" with type Q. The "base" for this DIUE
54260b57cec5SDimitry Andric // is the call expression *getQ(); the "updater" for the DIUE is ".q.b = 3"
54270b57cec5SDimitry Andric //
54280b57cec5SDimitry Andric class DesignatedInitUpdateExpr : public Expr {
54290b57cec5SDimitry Andric   // BaseAndUpdaterExprs[0] is the base expression;
54300b57cec5SDimitry Andric   // BaseAndUpdaterExprs[1] is an InitListExpr overwriting part of the base.
54310b57cec5SDimitry Andric   Stmt *BaseAndUpdaterExprs[2];
54320b57cec5SDimitry Andric 
54330b57cec5SDimitry Andric public:
54340b57cec5SDimitry Andric   DesignatedInitUpdateExpr(const ASTContext &C, SourceLocation lBraceLoc,
54350b57cec5SDimitry Andric                            Expr *baseExprs, SourceLocation rBraceLoc);
54360b57cec5SDimitry Andric 
DesignatedInitUpdateExpr(EmptyShell Empty)54370b57cec5SDimitry Andric   explicit DesignatedInitUpdateExpr(EmptyShell Empty)
54380b57cec5SDimitry Andric     : Expr(DesignatedInitUpdateExprClass, Empty) { }
54390b57cec5SDimitry Andric 
54400b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY;
54410b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY;
54420b57cec5SDimitry Andric 
classof(const Stmt * T)54430b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
54440b57cec5SDimitry Andric     return T->getStmtClass() == DesignatedInitUpdateExprClass;
54450b57cec5SDimitry Andric   }
54460b57cec5SDimitry Andric 
getBase()54470b57cec5SDimitry Andric   Expr *getBase() const { return cast<Expr>(BaseAndUpdaterExprs[0]); }
setBase(Expr * Base)54480b57cec5SDimitry Andric   void setBase(Expr *Base) { BaseAndUpdaterExprs[0] = Base; }
54490b57cec5SDimitry Andric 
getUpdater()54500b57cec5SDimitry Andric   InitListExpr *getUpdater() const {
54510b57cec5SDimitry Andric     return cast<InitListExpr>(BaseAndUpdaterExprs[1]);
54520b57cec5SDimitry Andric   }
setUpdater(Expr * Updater)54530b57cec5SDimitry Andric   void setUpdater(Expr *Updater) { BaseAndUpdaterExprs[1] = Updater; }
54540b57cec5SDimitry Andric 
54550b57cec5SDimitry Andric   // Iterators
54560b57cec5SDimitry Andric   // children = the base and the updater
children()54570b57cec5SDimitry Andric   child_range children() {
54580b57cec5SDimitry Andric     return child_range(&BaseAndUpdaterExprs[0], &BaseAndUpdaterExprs[0] + 2);
54590b57cec5SDimitry Andric   }
children()54600b57cec5SDimitry Andric   const_child_range children() const {
54610b57cec5SDimitry Andric     return const_child_range(&BaseAndUpdaterExprs[0],
54620b57cec5SDimitry Andric                              &BaseAndUpdaterExprs[0] + 2);
54630b57cec5SDimitry Andric   }
54640b57cec5SDimitry Andric };
54650b57cec5SDimitry Andric 
54660b57cec5SDimitry Andric /// Represents a loop initializing the elements of an array.
54670b57cec5SDimitry Andric ///
54680b57cec5SDimitry Andric /// The need to initialize the elements of an array occurs in a number of
54690b57cec5SDimitry Andric /// contexts:
54700b57cec5SDimitry Andric ///
54710b57cec5SDimitry Andric ///  * in the implicit copy/move constructor for a class with an array member
54720b57cec5SDimitry Andric ///  * when a lambda-expression captures an array by value
54730b57cec5SDimitry Andric ///  * when a decomposition declaration decomposes an array
54740b57cec5SDimitry Andric ///
54750b57cec5SDimitry Andric /// There are two subexpressions: a common expression (the source array)
54760b57cec5SDimitry Andric /// that is evaluated once up-front, and a per-element initializer that
54770b57cec5SDimitry Andric /// runs once for each array element.
54780b57cec5SDimitry Andric ///
54790b57cec5SDimitry Andric /// Within the per-element initializer, the common expression may be referenced
54800b57cec5SDimitry Andric /// via an OpaqueValueExpr, and the current index may be obtained via an
54810b57cec5SDimitry Andric /// ArrayInitIndexExpr.
54820b57cec5SDimitry Andric class ArrayInitLoopExpr : public Expr {
54830b57cec5SDimitry Andric   Stmt *SubExprs[2];
54840b57cec5SDimitry Andric 
ArrayInitLoopExpr(EmptyShell Empty)54850b57cec5SDimitry Andric   explicit ArrayInitLoopExpr(EmptyShell Empty)
54860b57cec5SDimitry Andric       : Expr(ArrayInitLoopExprClass, Empty), SubExprs{} {}
54870b57cec5SDimitry Andric 
54880b57cec5SDimitry Andric public:
ArrayInitLoopExpr(QualType T,Expr * CommonInit,Expr * ElementInit)54890b57cec5SDimitry Andric   explicit ArrayInitLoopExpr(QualType T, Expr *CommonInit, Expr *ElementInit)
5490fe6060f1SDimitry Andric       : Expr(ArrayInitLoopExprClass, T, VK_PRValue, OK_Ordinary),
54915ffd83dbSDimitry Andric         SubExprs{CommonInit, ElementInit} {
54925ffd83dbSDimitry Andric     setDependence(computeDependence(this));
54935ffd83dbSDimitry Andric   }
54940b57cec5SDimitry Andric 
54950b57cec5SDimitry Andric   /// Get the common subexpression shared by all initializations (the source
54960b57cec5SDimitry Andric   /// array).
getCommonExpr()54970b57cec5SDimitry Andric   OpaqueValueExpr *getCommonExpr() const {
54980b57cec5SDimitry Andric     return cast<OpaqueValueExpr>(SubExprs[0]);
54990b57cec5SDimitry Andric   }
55000b57cec5SDimitry Andric 
55010b57cec5SDimitry Andric   /// Get the initializer to use for each array element.
getSubExpr()55020b57cec5SDimitry Andric   Expr *getSubExpr() const { return cast<Expr>(SubExprs[1]); }
55030b57cec5SDimitry Andric 
getArraySize()55040b57cec5SDimitry Andric   llvm::APInt getArraySize() const {
55050b57cec5SDimitry Andric     return cast<ConstantArrayType>(getType()->castAsArrayTypeUnsafe())
55060b57cec5SDimitry Andric         ->getSize();
55070b57cec5SDimitry Andric   }
55080b57cec5SDimitry Andric 
classof(const Stmt * S)55090b57cec5SDimitry Andric   static bool classof(const Stmt *S) {
55100b57cec5SDimitry Andric     return S->getStmtClass() == ArrayInitLoopExprClass;
55110b57cec5SDimitry Andric   }
55120b57cec5SDimitry Andric 
getBeginLoc()55130b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY {
55140b57cec5SDimitry Andric     return getCommonExpr()->getBeginLoc();
55150b57cec5SDimitry Andric   }
getEndLoc()55160b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY {
55170b57cec5SDimitry Andric     return getCommonExpr()->getEndLoc();
55180b57cec5SDimitry Andric   }
55190b57cec5SDimitry Andric 
children()55200b57cec5SDimitry Andric   child_range children() {
55210b57cec5SDimitry Andric     return child_range(SubExprs, SubExprs + 2);
55220b57cec5SDimitry Andric   }
children()55230b57cec5SDimitry Andric   const_child_range children() const {
55240b57cec5SDimitry Andric     return const_child_range(SubExprs, SubExprs + 2);
55250b57cec5SDimitry Andric   }
55260b57cec5SDimitry Andric 
55270b57cec5SDimitry Andric   friend class ASTReader;
55280b57cec5SDimitry Andric   friend class ASTStmtReader;
55290b57cec5SDimitry Andric   friend class ASTStmtWriter;
55300b57cec5SDimitry Andric };
55310b57cec5SDimitry Andric 
55320b57cec5SDimitry Andric /// Represents the index of the current element of an array being
55330b57cec5SDimitry Andric /// initialized by an ArrayInitLoopExpr. This can only appear within the
55340b57cec5SDimitry Andric /// subexpression of an ArrayInitLoopExpr.
55350b57cec5SDimitry Andric class ArrayInitIndexExpr : public Expr {
ArrayInitIndexExpr(EmptyShell Empty)55360b57cec5SDimitry Andric   explicit ArrayInitIndexExpr(EmptyShell Empty)
55370b57cec5SDimitry Andric       : Expr(ArrayInitIndexExprClass, Empty) {}
55380b57cec5SDimitry Andric 
55390b57cec5SDimitry Andric public:
ArrayInitIndexExpr(QualType T)55400b57cec5SDimitry Andric   explicit ArrayInitIndexExpr(QualType T)
5541fe6060f1SDimitry Andric       : Expr(ArrayInitIndexExprClass, T, VK_PRValue, OK_Ordinary) {
55425ffd83dbSDimitry Andric     setDependence(ExprDependence::None);
55435ffd83dbSDimitry Andric   }
55440b57cec5SDimitry Andric 
classof(const Stmt * S)55450b57cec5SDimitry Andric   static bool classof(const Stmt *S) {
55460b57cec5SDimitry Andric     return S->getStmtClass() == ArrayInitIndexExprClass;
55470b57cec5SDimitry Andric   }
55480b57cec5SDimitry Andric 
getBeginLoc()55490b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY { return SourceLocation(); }
getEndLoc()55500b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY { return SourceLocation(); }
55510b57cec5SDimitry Andric 
children()55520b57cec5SDimitry Andric   child_range children() {
55530b57cec5SDimitry Andric     return child_range(child_iterator(), child_iterator());
55540b57cec5SDimitry Andric   }
children()55550b57cec5SDimitry Andric   const_child_range children() const {
55560b57cec5SDimitry Andric     return const_child_range(const_child_iterator(), const_child_iterator());
55570b57cec5SDimitry Andric   }
55580b57cec5SDimitry Andric 
55590b57cec5SDimitry Andric   friend class ASTReader;
55600b57cec5SDimitry Andric   friend class ASTStmtReader;
55610b57cec5SDimitry Andric };
55620b57cec5SDimitry Andric 
55630b57cec5SDimitry Andric /// Represents an implicitly-generated value initialization of
55640b57cec5SDimitry Andric /// an object of a given type.
55650b57cec5SDimitry Andric ///
55660b57cec5SDimitry Andric /// Implicit value initializations occur within semantic initializer
55670b57cec5SDimitry Andric /// list expressions (InitListExpr) as placeholders for subobject
55680b57cec5SDimitry Andric /// initializations not explicitly specified by the user.
55690b57cec5SDimitry Andric ///
55700b57cec5SDimitry Andric /// \see InitListExpr
55710b57cec5SDimitry Andric class ImplicitValueInitExpr : public Expr {
55720b57cec5SDimitry Andric public:
ImplicitValueInitExpr(QualType ty)55730b57cec5SDimitry Andric   explicit ImplicitValueInitExpr(QualType ty)
5574fe6060f1SDimitry Andric       : Expr(ImplicitValueInitExprClass, ty, VK_PRValue, OK_Ordinary) {
55755ffd83dbSDimitry Andric     setDependence(computeDependence(this));
55765ffd83dbSDimitry Andric   }
55770b57cec5SDimitry Andric 
55780b57cec5SDimitry Andric   /// Construct an empty implicit value initialization.
ImplicitValueInitExpr(EmptyShell Empty)55790b57cec5SDimitry Andric   explicit ImplicitValueInitExpr(EmptyShell Empty)
55800b57cec5SDimitry Andric     : Expr(ImplicitValueInitExprClass, Empty) { }
55810b57cec5SDimitry Andric 
classof(const Stmt * T)55820b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
55830b57cec5SDimitry Andric     return T->getStmtClass() == ImplicitValueInitExprClass;
55840b57cec5SDimitry Andric   }
55850b57cec5SDimitry Andric 
getBeginLoc()55860b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY { return SourceLocation(); }
getEndLoc()55870b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY { return SourceLocation(); }
55880b57cec5SDimitry Andric 
55890b57cec5SDimitry Andric   // Iterators
children()55900b57cec5SDimitry Andric   child_range children() {
55910b57cec5SDimitry Andric     return child_range(child_iterator(), child_iterator());
55920b57cec5SDimitry Andric   }
children()55930b57cec5SDimitry Andric   const_child_range children() const {
55940b57cec5SDimitry Andric     return const_child_range(const_child_iterator(), const_child_iterator());
55950b57cec5SDimitry Andric   }
55960b57cec5SDimitry Andric };
55970b57cec5SDimitry Andric 
55980b57cec5SDimitry Andric class ParenListExpr final
55990b57cec5SDimitry Andric     : public Expr,
56000b57cec5SDimitry Andric       private llvm::TrailingObjects<ParenListExpr, Stmt *> {
56010b57cec5SDimitry Andric   friend class ASTStmtReader;
56020b57cec5SDimitry Andric   friend TrailingObjects;
56030b57cec5SDimitry Andric 
56040b57cec5SDimitry Andric   /// The location of the left and right parentheses.
56050b57cec5SDimitry Andric   SourceLocation LParenLoc, RParenLoc;
56060b57cec5SDimitry Andric 
56070b57cec5SDimitry Andric   /// Build a paren list.
56080b57cec5SDimitry Andric   ParenListExpr(SourceLocation LParenLoc, ArrayRef<Expr *> Exprs,
56090b57cec5SDimitry Andric                 SourceLocation RParenLoc);
56100b57cec5SDimitry Andric 
56110b57cec5SDimitry Andric   /// Build an empty paren list.
56120b57cec5SDimitry Andric   ParenListExpr(EmptyShell Empty, unsigned NumExprs);
56130b57cec5SDimitry Andric 
56140b57cec5SDimitry Andric public:
56150b57cec5SDimitry Andric   /// Create a paren list.
56160b57cec5SDimitry Andric   static ParenListExpr *Create(const ASTContext &Ctx, SourceLocation LParenLoc,
56170b57cec5SDimitry Andric                                ArrayRef<Expr *> Exprs,
56180b57cec5SDimitry Andric                                SourceLocation RParenLoc);
56190b57cec5SDimitry Andric 
56200b57cec5SDimitry Andric   /// Create an empty paren list.
56210b57cec5SDimitry Andric   static ParenListExpr *CreateEmpty(const ASTContext &Ctx, unsigned NumExprs);
56220b57cec5SDimitry Andric 
56230b57cec5SDimitry Andric   /// Return the number of expressions in this paren list.
getNumExprs()56240b57cec5SDimitry Andric   unsigned getNumExprs() const { return ParenListExprBits.NumExprs; }
56250b57cec5SDimitry Andric 
getExpr(unsigned Init)56260b57cec5SDimitry Andric   Expr *getExpr(unsigned Init) {
56270b57cec5SDimitry Andric     assert(Init < getNumExprs() && "Initializer access out of range!");
56280b57cec5SDimitry Andric     return getExprs()[Init];
56290b57cec5SDimitry Andric   }
56300b57cec5SDimitry Andric 
getExpr(unsigned Init)56310b57cec5SDimitry Andric   const Expr *getExpr(unsigned Init) const {
56320b57cec5SDimitry Andric     return const_cast<ParenListExpr *>(this)->getExpr(Init);
56330b57cec5SDimitry Andric   }
56340b57cec5SDimitry Andric 
getExprs()56350b57cec5SDimitry Andric   Expr **getExprs() {
56360b57cec5SDimitry Andric     return reinterpret_cast<Expr **>(getTrailingObjects<Stmt *>());
56370b57cec5SDimitry Andric   }
56380b57cec5SDimitry Andric 
exprs()5639bdd1243dSDimitry Andric   ArrayRef<Expr *> exprs() { return llvm::ArrayRef(getExprs(), getNumExprs()); }
56400b57cec5SDimitry Andric 
getLParenLoc()56410b57cec5SDimitry Andric   SourceLocation getLParenLoc() const { return LParenLoc; }
getRParenLoc()56420b57cec5SDimitry Andric   SourceLocation getRParenLoc() const { return RParenLoc; }
getBeginLoc()56430b57cec5SDimitry Andric   SourceLocation getBeginLoc() const { return getLParenLoc(); }
getEndLoc()56440b57cec5SDimitry Andric   SourceLocation getEndLoc() const { return getRParenLoc(); }
56450b57cec5SDimitry Andric 
classof(const Stmt * T)56460b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
56470b57cec5SDimitry Andric     return T->getStmtClass() == ParenListExprClass;
56480b57cec5SDimitry Andric   }
56490b57cec5SDimitry Andric 
56500b57cec5SDimitry Andric   // Iterators
children()56510b57cec5SDimitry Andric   child_range children() {
56520b57cec5SDimitry Andric     return child_range(getTrailingObjects<Stmt *>(),
56530b57cec5SDimitry Andric                        getTrailingObjects<Stmt *>() + getNumExprs());
56540b57cec5SDimitry Andric   }
children()56550b57cec5SDimitry Andric   const_child_range children() const {
56560b57cec5SDimitry Andric     return const_child_range(getTrailingObjects<Stmt *>(),
56570b57cec5SDimitry Andric                              getTrailingObjects<Stmt *>() + getNumExprs());
56580b57cec5SDimitry Andric   }
56590b57cec5SDimitry Andric };
56600b57cec5SDimitry Andric 
56610b57cec5SDimitry Andric /// Represents a C11 generic selection.
56620b57cec5SDimitry Andric ///
56630b57cec5SDimitry Andric /// A generic selection (C11 6.5.1.1) contains an unevaluated controlling
56640b57cec5SDimitry Andric /// expression, followed by one or more generic associations.  Each generic
56650b57cec5SDimitry Andric /// association specifies a type name and an expression, or "default" and an
56660b57cec5SDimitry Andric /// expression (in which case it is known as a default generic association).
56670b57cec5SDimitry Andric /// The type and value of the generic selection are identical to those of its
56680b57cec5SDimitry Andric /// result expression, which is defined as the expression in the generic
56690b57cec5SDimitry Andric /// association with a type name that is compatible with the type of the
56700b57cec5SDimitry Andric /// controlling expression, or the expression in the default generic association
56710b57cec5SDimitry Andric /// if no types are compatible.  For example:
56720b57cec5SDimitry Andric ///
56730b57cec5SDimitry Andric /// @code
56740b57cec5SDimitry Andric /// _Generic(X, double: 1, float: 2, default: 3)
56750b57cec5SDimitry Andric /// @endcode
56760b57cec5SDimitry Andric ///
56770b57cec5SDimitry Andric /// The above expression evaluates to 1 if 1.0 is substituted for X, 2 if 1.0f
56780b57cec5SDimitry Andric /// or 3 if "hello".
56790b57cec5SDimitry Andric ///
56800b57cec5SDimitry Andric /// As an extension, generic selections are allowed in C++, where the following
56810b57cec5SDimitry Andric /// additional semantics apply:
56820b57cec5SDimitry Andric ///
56830b57cec5SDimitry Andric /// Any generic selection whose controlling expression is type-dependent or
56840b57cec5SDimitry Andric /// which names a dependent type in its association list is result-dependent,
56850b57cec5SDimitry Andric /// which means that the choice of result expression is dependent.
56860b57cec5SDimitry Andric /// Result-dependent generic associations are both type- and value-dependent.
568706c3fb27SDimitry Andric ///
568806c3fb27SDimitry Andric /// We also allow an extended form in both C and C++ where the controlling
568906c3fb27SDimitry Andric /// predicate for the selection expression is a type rather than an expression.
569006c3fb27SDimitry Andric /// This type argument form does not perform any conversions for the
569106c3fb27SDimitry Andric /// controlling type, which makes it suitable for use with qualified type
569206c3fb27SDimitry Andric /// associations, which is not possible with the expression form.
56930b57cec5SDimitry Andric class GenericSelectionExpr final
56940b57cec5SDimitry Andric     : public Expr,
56950b57cec5SDimitry Andric       private llvm::TrailingObjects<GenericSelectionExpr, Stmt *,
56960b57cec5SDimitry Andric                                     TypeSourceInfo *> {
56970b57cec5SDimitry Andric   friend class ASTStmtReader;
56980b57cec5SDimitry Andric   friend class ASTStmtWriter;
56990b57cec5SDimitry Andric   friend TrailingObjects;
57000b57cec5SDimitry Andric 
57010b57cec5SDimitry Andric   /// The number of association expressions and the index of the result
57020b57cec5SDimitry Andric   /// expression in the case where the generic selection expression is not
57030b57cec5SDimitry Andric   /// result-dependent. The result index is equal to ResultDependentIndex
57040b57cec5SDimitry Andric   /// if and only if the generic selection expression is result-dependent.
570506c3fb27SDimitry Andric   unsigned NumAssocs : 15;
570606c3fb27SDimitry Andric   unsigned ResultIndex : 15; // NB: ResultDependentIndex is tied to this width.
57075f757f3fSDimitry Andric   LLVM_PREFERRED_TYPE(bool)
570806c3fb27SDimitry Andric   unsigned IsExprPredicate : 1;
57090b57cec5SDimitry Andric   enum : unsigned {
571006c3fb27SDimitry Andric     ResultDependentIndex = 0x7FFF
57110b57cec5SDimitry Andric   };
57120b57cec5SDimitry Andric 
getIndexOfControllingExpression()571306c3fb27SDimitry Andric   unsigned getIndexOfControllingExpression() const {
571406c3fb27SDimitry Andric     // If controlled by an expression, the first offset into the Stmt *
571506c3fb27SDimitry Andric     // trailing array is the controlling expression, the associated expressions
571606c3fb27SDimitry Andric     // follow this.
571706c3fb27SDimitry Andric     assert(isExprPredicate() && "Asking for the controlling expression of a "
571806c3fb27SDimitry Andric                                 "selection expr predicated by a type");
571906c3fb27SDimitry Andric     return 0;
572006c3fb27SDimitry Andric   }
572106c3fb27SDimitry Andric 
getIndexOfControllingType()572206c3fb27SDimitry Andric   unsigned getIndexOfControllingType() const {
572306c3fb27SDimitry Andric     // If controlled by a type, the first offset into the TypeSourceInfo *
572406c3fb27SDimitry Andric     // trailing array is the controlling type, the associated types follow this.
572506c3fb27SDimitry Andric     assert(isTypePredicate() && "Asking for the controlling type of a "
572606c3fb27SDimitry Andric                                  "selection expr predicated by an expression");
572706c3fb27SDimitry Andric     return 0;
572806c3fb27SDimitry Andric   }
572906c3fb27SDimitry Andric 
getIndexOfStartOfAssociatedExprs()573006c3fb27SDimitry Andric   unsigned getIndexOfStartOfAssociatedExprs() const {
573106c3fb27SDimitry Andric     // If the predicate is a type, then the associated expressions are the only
573206c3fb27SDimitry Andric     // Stmt * in the trailing array, otherwise we need to offset past the
573306c3fb27SDimitry Andric     // predicate expression.
573406c3fb27SDimitry Andric     return (int)isExprPredicate();
573506c3fb27SDimitry Andric   }
573606c3fb27SDimitry Andric 
getIndexOfStartOfAssociatedTypes()573706c3fb27SDimitry Andric   unsigned getIndexOfStartOfAssociatedTypes() const {
573806c3fb27SDimitry Andric     // If the predicate is a type, then the associated types follow it in the
573906c3fb27SDimitry Andric     // trailing array. Otherwise, the associated types are the only
574006c3fb27SDimitry Andric     // TypeSourceInfo * in the trailing array.
574106c3fb27SDimitry Andric     return (int)isTypePredicate();
574206c3fb27SDimitry Andric   }
574306c3fb27SDimitry Andric 
574406c3fb27SDimitry Andric 
57450b57cec5SDimitry Andric   /// The location of the "default" and of the right parenthesis.
57460b57cec5SDimitry Andric   SourceLocation DefaultLoc, RParenLoc;
57470b57cec5SDimitry Andric 
57480b57cec5SDimitry Andric   // GenericSelectionExpr is followed by several trailing objects.
57490b57cec5SDimitry Andric   // They are (in order):
57500b57cec5SDimitry Andric   //
575106c3fb27SDimitry Andric   // * A single Stmt * for the controlling expression or a TypeSourceInfo * for
575206c3fb27SDimitry Andric   //   the controlling type, depending on the result of isTypePredicate() or
575306c3fb27SDimitry Andric   //   isExprPredicate().
57540b57cec5SDimitry Andric   // * An array of getNumAssocs() Stmt * for the association expressions.
57550b57cec5SDimitry Andric   // * An array of getNumAssocs() TypeSourceInfo *, one for each of the
57560b57cec5SDimitry Andric   //   association expressions.
numTrailingObjects(OverloadToken<Stmt * >)57570b57cec5SDimitry Andric   unsigned numTrailingObjects(OverloadToken<Stmt *>) const {
57580b57cec5SDimitry Andric     // Add one to account for the controlling expression; the remainder
57590b57cec5SDimitry Andric     // are the associated expressions.
576006c3fb27SDimitry Andric     return getNumAssocs() + (int)isExprPredicate();
57610b57cec5SDimitry Andric   }
57620b57cec5SDimitry Andric 
numTrailingObjects(OverloadToken<TypeSourceInfo * >)57630b57cec5SDimitry Andric   unsigned numTrailingObjects(OverloadToken<TypeSourceInfo *>) const {
576406c3fb27SDimitry Andric     // Add one to account for the controlling type predicate, the remainder
576506c3fb27SDimitry Andric     // are the associated types.
576606c3fb27SDimitry Andric     return getNumAssocs() + (int)isTypePredicate();
57670b57cec5SDimitry Andric   }
57680b57cec5SDimitry Andric 
57690b57cec5SDimitry Andric   template <bool Const> class AssociationIteratorTy;
57700b57cec5SDimitry Andric   /// Bundle together an association expression and its TypeSourceInfo.
57710b57cec5SDimitry Andric   /// The Const template parameter is for the const and non-const versions
57720b57cec5SDimitry Andric   /// of AssociationTy.
57730b57cec5SDimitry Andric   template <bool Const> class AssociationTy {
57740b57cec5SDimitry Andric     friend class GenericSelectionExpr;
57750b57cec5SDimitry Andric     template <bool OtherConst> friend class AssociationIteratorTy;
57765ffd83dbSDimitry Andric     using ExprPtrTy = std::conditional_t<Const, const Expr *, Expr *>;
57775ffd83dbSDimitry Andric     using TSIPtrTy =
57785ffd83dbSDimitry Andric         std::conditional_t<Const, const TypeSourceInfo *, TypeSourceInfo *>;
57790b57cec5SDimitry Andric     ExprPtrTy E;
57800b57cec5SDimitry Andric     TSIPtrTy TSI;
57810b57cec5SDimitry Andric     bool Selected;
AssociationTy(ExprPtrTy E,TSIPtrTy TSI,bool Selected)57820b57cec5SDimitry Andric     AssociationTy(ExprPtrTy E, TSIPtrTy TSI, bool Selected)
57830b57cec5SDimitry Andric         : E(E), TSI(TSI), Selected(Selected) {}
57840b57cec5SDimitry Andric 
57850b57cec5SDimitry Andric   public:
getAssociationExpr()57860b57cec5SDimitry Andric     ExprPtrTy getAssociationExpr() const { return E; }
getTypeSourceInfo()57870b57cec5SDimitry Andric     TSIPtrTy getTypeSourceInfo() const { return TSI; }
getType()57880b57cec5SDimitry Andric     QualType getType() const { return TSI ? TSI->getType() : QualType(); }
isSelected()57890b57cec5SDimitry Andric     bool isSelected() const { return Selected; }
57900b57cec5SDimitry Andric     AssociationTy *operator->() { return this; }
57910b57cec5SDimitry Andric     const AssociationTy *operator->() const { return this; }
57920b57cec5SDimitry Andric   }; // class AssociationTy
57930b57cec5SDimitry Andric 
57940b57cec5SDimitry Andric   /// Iterator over const and non-const Association objects. The Association
57950b57cec5SDimitry Andric   /// objects are created on the fly when the iterator is dereferenced.
57960b57cec5SDimitry Andric   /// This abstract over how exactly the association expressions and the
57970b57cec5SDimitry Andric   /// corresponding TypeSourceInfo * are stored.
57980b57cec5SDimitry Andric   template <bool Const>
57990b57cec5SDimitry Andric   class AssociationIteratorTy
58000b57cec5SDimitry Andric       : public llvm::iterator_facade_base<
58010b57cec5SDimitry Andric             AssociationIteratorTy<Const>, std::input_iterator_tag,
58020b57cec5SDimitry Andric             AssociationTy<Const>, std::ptrdiff_t, AssociationTy<Const>,
58030b57cec5SDimitry Andric             AssociationTy<Const>> {
58040b57cec5SDimitry Andric     friend class GenericSelectionExpr;
58050b57cec5SDimitry Andric     // FIXME: This iterator could conceptually be a random access iterator, and
58060b57cec5SDimitry Andric     // it would be nice if we could strengthen the iterator category someday.
58070b57cec5SDimitry Andric     // However this iterator does not satisfy two requirements of forward
58080b57cec5SDimitry Andric     // iterators:
58090b57cec5SDimitry Andric     // a) reference = T& or reference = const T&
58100b57cec5SDimitry Andric     // b) If It1 and It2 are both dereferenceable, then It1 == It2 if and only
58110b57cec5SDimitry Andric     //    if *It1 and *It2 are bound to the same objects.
58120b57cec5SDimitry Andric     // An alternative design approach was discussed during review;
58130b57cec5SDimitry Andric     // store an Association object inside the iterator, and return a reference
58140b57cec5SDimitry Andric     // to it when dereferenced. This idea was discarded beacuse of nasty
58150b57cec5SDimitry Andric     // lifetime issues:
58160b57cec5SDimitry Andric     //    AssociationIterator It = ...;
58170b57cec5SDimitry Andric     //    const Association &Assoc = *It++; // Oops, Assoc is dangling.
58180b57cec5SDimitry Andric     using BaseTy = typename AssociationIteratorTy::iterator_facade_base;
58190b57cec5SDimitry Andric     using StmtPtrPtrTy =
58205ffd83dbSDimitry Andric         std::conditional_t<Const, const Stmt *const *, Stmt **>;
58215ffd83dbSDimitry Andric     using TSIPtrPtrTy = std::conditional_t<Const, const TypeSourceInfo *const *,
58225ffd83dbSDimitry Andric                                            TypeSourceInfo **>;
58230b57cec5SDimitry Andric     StmtPtrPtrTy E; // = nullptr; FIXME: Once support for gcc 4.8 is dropped.
58240b57cec5SDimitry Andric     TSIPtrPtrTy TSI; // Kept in sync with E.
58250b57cec5SDimitry Andric     unsigned Offset = 0, SelectedOffset = 0;
AssociationIteratorTy(StmtPtrPtrTy E,TSIPtrPtrTy TSI,unsigned Offset,unsigned SelectedOffset)58260b57cec5SDimitry Andric     AssociationIteratorTy(StmtPtrPtrTy E, TSIPtrPtrTy TSI, unsigned Offset,
58270b57cec5SDimitry Andric                           unsigned SelectedOffset)
58280b57cec5SDimitry Andric         : E(E), TSI(TSI), Offset(Offset), SelectedOffset(SelectedOffset) {}
58290b57cec5SDimitry Andric 
58300b57cec5SDimitry Andric   public:
AssociationIteratorTy()58310b57cec5SDimitry Andric     AssociationIteratorTy() : E(nullptr), TSI(nullptr) {}
58320b57cec5SDimitry Andric     typename BaseTy::reference operator*() const {
58330b57cec5SDimitry Andric       return AssociationTy<Const>(cast<Expr>(*E), *TSI,
58340b57cec5SDimitry Andric                                   Offset == SelectedOffset);
58350b57cec5SDimitry Andric     }
58360b57cec5SDimitry Andric     typename BaseTy::pointer operator->() const { return **this; }
58370b57cec5SDimitry Andric     using BaseTy::operator++;
58380b57cec5SDimitry Andric     AssociationIteratorTy &operator++() {
58390b57cec5SDimitry Andric       ++E;
58400b57cec5SDimitry Andric       ++TSI;
58410b57cec5SDimitry Andric       ++Offset;
58420b57cec5SDimitry Andric       return *this;
58430b57cec5SDimitry Andric     }
58440b57cec5SDimitry Andric     bool operator==(AssociationIteratorTy Other) const { return E == Other.E; }
58450b57cec5SDimitry Andric   }; // class AssociationIterator
58460b57cec5SDimitry Andric 
584706c3fb27SDimitry Andric   /// Build a non-result-dependent generic selection expression accepting an
584806c3fb27SDimitry Andric   /// expression predicate.
58490b57cec5SDimitry Andric   GenericSelectionExpr(const ASTContext &Context, SourceLocation GenericLoc,
58500b57cec5SDimitry Andric                        Expr *ControllingExpr,
58510b57cec5SDimitry Andric                        ArrayRef<TypeSourceInfo *> AssocTypes,
58520b57cec5SDimitry Andric                        ArrayRef<Expr *> AssocExprs, SourceLocation DefaultLoc,
58530b57cec5SDimitry Andric                        SourceLocation RParenLoc,
58540b57cec5SDimitry Andric                        bool ContainsUnexpandedParameterPack,
58550b57cec5SDimitry Andric                        unsigned ResultIndex);
58560b57cec5SDimitry Andric 
585706c3fb27SDimitry Andric   /// Build a result-dependent generic selection expression accepting an
585806c3fb27SDimitry Andric   /// expression predicate.
58590b57cec5SDimitry Andric   GenericSelectionExpr(const ASTContext &Context, SourceLocation GenericLoc,
58600b57cec5SDimitry Andric                        Expr *ControllingExpr,
58610b57cec5SDimitry Andric                        ArrayRef<TypeSourceInfo *> AssocTypes,
58620b57cec5SDimitry Andric                        ArrayRef<Expr *> AssocExprs, SourceLocation DefaultLoc,
58630b57cec5SDimitry Andric                        SourceLocation RParenLoc,
58640b57cec5SDimitry Andric                        bool ContainsUnexpandedParameterPack);
58650b57cec5SDimitry Andric 
586606c3fb27SDimitry Andric   /// Build a non-result-dependent generic selection expression accepting a
586706c3fb27SDimitry Andric   /// type predicate.
586806c3fb27SDimitry Andric   GenericSelectionExpr(const ASTContext &Context, SourceLocation GenericLoc,
586906c3fb27SDimitry Andric                        TypeSourceInfo *ControllingType,
587006c3fb27SDimitry Andric                        ArrayRef<TypeSourceInfo *> AssocTypes,
587106c3fb27SDimitry Andric                        ArrayRef<Expr *> AssocExprs, SourceLocation DefaultLoc,
587206c3fb27SDimitry Andric                        SourceLocation RParenLoc,
587306c3fb27SDimitry Andric                        bool ContainsUnexpandedParameterPack,
587406c3fb27SDimitry Andric                        unsigned ResultIndex);
587506c3fb27SDimitry Andric 
587606c3fb27SDimitry Andric   /// Build a result-dependent generic selection expression accepting a type
587706c3fb27SDimitry Andric   /// predicate.
587806c3fb27SDimitry Andric   GenericSelectionExpr(const ASTContext &Context, SourceLocation GenericLoc,
587906c3fb27SDimitry Andric                        TypeSourceInfo *ControllingType,
588006c3fb27SDimitry Andric                        ArrayRef<TypeSourceInfo *> AssocTypes,
588106c3fb27SDimitry Andric                        ArrayRef<Expr *> AssocExprs, SourceLocation DefaultLoc,
588206c3fb27SDimitry Andric                        SourceLocation RParenLoc,
588306c3fb27SDimitry Andric                        bool ContainsUnexpandedParameterPack);
588406c3fb27SDimitry Andric 
58850b57cec5SDimitry Andric   /// Build an empty generic selection expression for deserialization.
58860b57cec5SDimitry Andric   explicit GenericSelectionExpr(EmptyShell Empty, unsigned NumAssocs);
58870b57cec5SDimitry Andric 
58880b57cec5SDimitry Andric public:
588906c3fb27SDimitry Andric   /// Create a non-result-dependent generic selection expression accepting an
589006c3fb27SDimitry Andric   /// expression predicate.
58910b57cec5SDimitry Andric   static GenericSelectionExpr *
58920b57cec5SDimitry Andric   Create(const ASTContext &Context, SourceLocation GenericLoc,
58930b57cec5SDimitry Andric          Expr *ControllingExpr, ArrayRef<TypeSourceInfo *> AssocTypes,
58940b57cec5SDimitry Andric          ArrayRef<Expr *> AssocExprs, SourceLocation DefaultLoc,
58950b57cec5SDimitry Andric          SourceLocation RParenLoc, bool ContainsUnexpandedParameterPack,
58960b57cec5SDimitry Andric          unsigned ResultIndex);
58970b57cec5SDimitry Andric 
589806c3fb27SDimitry Andric   /// Create a result-dependent generic selection expression accepting an
589906c3fb27SDimitry Andric   /// expression predicate.
59000b57cec5SDimitry Andric   static GenericSelectionExpr *
59010b57cec5SDimitry Andric   Create(const ASTContext &Context, SourceLocation GenericLoc,
59020b57cec5SDimitry Andric          Expr *ControllingExpr, ArrayRef<TypeSourceInfo *> AssocTypes,
59030b57cec5SDimitry Andric          ArrayRef<Expr *> AssocExprs, SourceLocation DefaultLoc,
59040b57cec5SDimitry Andric          SourceLocation RParenLoc, bool ContainsUnexpandedParameterPack);
59050b57cec5SDimitry Andric 
590606c3fb27SDimitry Andric   /// Create a non-result-dependent generic selection expression accepting a
590706c3fb27SDimitry Andric   /// type predicate.
590806c3fb27SDimitry Andric   static GenericSelectionExpr *
590906c3fb27SDimitry Andric   Create(const ASTContext &Context, SourceLocation GenericLoc,
591006c3fb27SDimitry Andric          TypeSourceInfo *ControllingType, ArrayRef<TypeSourceInfo *> AssocTypes,
591106c3fb27SDimitry Andric          ArrayRef<Expr *> AssocExprs, SourceLocation DefaultLoc,
591206c3fb27SDimitry Andric          SourceLocation RParenLoc, bool ContainsUnexpandedParameterPack,
591306c3fb27SDimitry Andric          unsigned ResultIndex);
591406c3fb27SDimitry Andric 
591506c3fb27SDimitry Andric   /// Create a result-dependent generic selection expression accepting a type
591606c3fb27SDimitry Andric   /// predicate
591706c3fb27SDimitry Andric   static GenericSelectionExpr *
591806c3fb27SDimitry Andric   Create(const ASTContext &Context, SourceLocation GenericLoc,
591906c3fb27SDimitry Andric          TypeSourceInfo *ControllingType, ArrayRef<TypeSourceInfo *> AssocTypes,
592006c3fb27SDimitry Andric          ArrayRef<Expr *> AssocExprs, SourceLocation DefaultLoc,
592106c3fb27SDimitry Andric          SourceLocation RParenLoc, bool ContainsUnexpandedParameterPack);
592206c3fb27SDimitry Andric 
59230b57cec5SDimitry Andric   /// Create an empty generic selection expression for deserialization.
59240b57cec5SDimitry Andric   static GenericSelectionExpr *CreateEmpty(const ASTContext &Context,
59250b57cec5SDimitry Andric                                            unsigned NumAssocs);
59260b57cec5SDimitry Andric 
59270b57cec5SDimitry Andric   using Association = AssociationTy<false>;
59280b57cec5SDimitry Andric   using ConstAssociation = AssociationTy<true>;
59290b57cec5SDimitry Andric   using AssociationIterator = AssociationIteratorTy<false>;
59300b57cec5SDimitry Andric   using ConstAssociationIterator = AssociationIteratorTy<true>;
59310b57cec5SDimitry Andric   using association_range = llvm::iterator_range<AssociationIterator>;
59320b57cec5SDimitry Andric   using const_association_range =
59330b57cec5SDimitry Andric       llvm::iterator_range<ConstAssociationIterator>;
59340b57cec5SDimitry Andric 
59350b57cec5SDimitry Andric   /// The number of association expressions.
getNumAssocs()59360b57cec5SDimitry Andric   unsigned getNumAssocs() const { return NumAssocs; }
59370b57cec5SDimitry Andric 
59380b57cec5SDimitry Andric   /// The zero-based index of the result expression's generic association in
59390b57cec5SDimitry Andric   /// the generic selection's association list.  Defined only if the
59400b57cec5SDimitry Andric   /// generic selection is not result-dependent.
getResultIndex()59410b57cec5SDimitry Andric   unsigned getResultIndex() const {
59420b57cec5SDimitry Andric     assert(!isResultDependent() &&
59430b57cec5SDimitry Andric            "Generic selection is result-dependent but getResultIndex called!");
59440b57cec5SDimitry Andric     return ResultIndex;
59450b57cec5SDimitry Andric   }
59460b57cec5SDimitry Andric 
59470b57cec5SDimitry Andric   /// Whether this generic selection is result-dependent.
isResultDependent()59480b57cec5SDimitry Andric   bool isResultDependent() const { return ResultIndex == ResultDependentIndex; }
59490b57cec5SDimitry Andric 
595006c3fb27SDimitry Andric   /// Whether this generic selection uses an expression as its controlling
595106c3fb27SDimitry Andric   /// argument.
isExprPredicate()595206c3fb27SDimitry Andric   bool isExprPredicate() const { return IsExprPredicate; }
595306c3fb27SDimitry Andric   /// Whether this generic selection uses a type as its controlling argument.
isTypePredicate()595406c3fb27SDimitry Andric   bool isTypePredicate() const { return !IsExprPredicate; }
595506c3fb27SDimitry Andric 
59560b57cec5SDimitry Andric   /// Return the controlling expression of this generic selection expression.
595706c3fb27SDimitry Andric   /// Only valid to call if the selection expression used an expression as its
595806c3fb27SDimitry Andric   /// controlling argument.
getControllingExpr()59590b57cec5SDimitry Andric   Expr *getControllingExpr() {
596006c3fb27SDimitry Andric     return cast<Expr>(
596106c3fb27SDimitry Andric         getTrailingObjects<Stmt *>()[getIndexOfControllingExpression()]);
59620b57cec5SDimitry Andric   }
getControllingExpr()59630b57cec5SDimitry Andric   const Expr *getControllingExpr() const {
596406c3fb27SDimitry Andric     return cast<Expr>(
596506c3fb27SDimitry Andric         getTrailingObjects<Stmt *>()[getIndexOfControllingExpression()]);
596606c3fb27SDimitry Andric   }
596706c3fb27SDimitry Andric 
596806c3fb27SDimitry Andric   /// Return the controlling type of this generic selection expression. Only
596906c3fb27SDimitry Andric   /// valid to call if the selection expression used a type as its controlling
597006c3fb27SDimitry Andric   /// argument.
getControllingType()597106c3fb27SDimitry Andric   TypeSourceInfo *getControllingType() {
597206c3fb27SDimitry Andric     return getTrailingObjects<TypeSourceInfo *>()[getIndexOfControllingType()];
597306c3fb27SDimitry Andric   }
getControllingType()597406c3fb27SDimitry Andric   const TypeSourceInfo* getControllingType() const {
597506c3fb27SDimitry Andric     return getTrailingObjects<TypeSourceInfo *>()[getIndexOfControllingType()];
59760b57cec5SDimitry Andric   }
59770b57cec5SDimitry Andric 
59780b57cec5SDimitry Andric   /// Return the result expression of this controlling expression. Defined if
59790b57cec5SDimitry Andric   /// and only if the generic selection expression is not result-dependent.
getResultExpr()59800b57cec5SDimitry Andric   Expr *getResultExpr() {
59810b57cec5SDimitry Andric     return cast<Expr>(
598206c3fb27SDimitry Andric         getTrailingObjects<Stmt *>()[getIndexOfStartOfAssociatedExprs() +
598306c3fb27SDimitry Andric                                      getResultIndex()]);
59840b57cec5SDimitry Andric   }
getResultExpr()59850b57cec5SDimitry Andric   const Expr *getResultExpr() const {
59860b57cec5SDimitry Andric     return cast<Expr>(
598706c3fb27SDimitry Andric         getTrailingObjects<Stmt *>()[getIndexOfStartOfAssociatedExprs() +
598806c3fb27SDimitry Andric                                      getResultIndex()]);
59890b57cec5SDimitry Andric   }
59900b57cec5SDimitry Andric 
getAssocExprs()59910b57cec5SDimitry Andric   ArrayRef<Expr *> getAssocExprs() const {
59920b57cec5SDimitry Andric     return {reinterpret_cast<Expr *const *>(getTrailingObjects<Stmt *>() +
599306c3fb27SDimitry Andric                                             getIndexOfStartOfAssociatedExprs()),
59940b57cec5SDimitry Andric             NumAssocs};
59950b57cec5SDimitry Andric   }
getAssocTypeSourceInfos()59960b57cec5SDimitry Andric   ArrayRef<TypeSourceInfo *> getAssocTypeSourceInfos() const {
599706c3fb27SDimitry Andric     return {getTrailingObjects<TypeSourceInfo *>() +
599806c3fb27SDimitry Andric                 getIndexOfStartOfAssociatedTypes(),
599906c3fb27SDimitry Andric             NumAssocs};
60000b57cec5SDimitry Andric   }
60010b57cec5SDimitry Andric 
60020b57cec5SDimitry Andric   /// Return the Ith association expression with its TypeSourceInfo,
60030b57cec5SDimitry Andric   /// bundled together in GenericSelectionExpr::(Const)Association.
getAssociation(unsigned I)60040b57cec5SDimitry Andric   Association getAssociation(unsigned I) {
60050b57cec5SDimitry Andric     assert(I < getNumAssocs() &&
60060b57cec5SDimitry Andric            "Out-of-range index in GenericSelectionExpr::getAssociation!");
60070b57cec5SDimitry Andric     return Association(
600806c3fb27SDimitry Andric         cast<Expr>(
600906c3fb27SDimitry Andric             getTrailingObjects<Stmt *>()[getIndexOfStartOfAssociatedExprs() +
601006c3fb27SDimitry Andric                                          I]),
601106c3fb27SDimitry Andric         getTrailingObjects<
601206c3fb27SDimitry Andric             TypeSourceInfo *>()[getIndexOfStartOfAssociatedTypes() + I],
60130b57cec5SDimitry Andric         !isResultDependent() && (getResultIndex() == I));
60140b57cec5SDimitry Andric   }
getAssociation(unsigned I)60150b57cec5SDimitry Andric   ConstAssociation getAssociation(unsigned I) const {
60160b57cec5SDimitry Andric     assert(I < getNumAssocs() &&
60170b57cec5SDimitry Andric            "Out-of-range index in GenericSelectionExpr::getAssociation!");
60180b57cec5SDimitry Andric     return ConstAssociation(
601906c3fb27SDimitry Andric         cast<Expr>(
602006c3fb27SDimitry Andric             getTrailingObjects<Stmt *>()[getIndexOfStartOfAssociatedExprs() +
602106c3fb27SDimitry Andric                                          I]),
602206c3fb27SDimitry Andric         getTrailingObjects<
602306c3fb27SDimitry Andric             TypeSourceInfo *>()[getIndexOfStartOfAssociatedTypes() + I],
60240b57cec5SDimitry Andric         !isResultDependent() && (getResultIndex() == I));
60250b57cec5SDimitry Andric   }
60260b57cec5SDimitry Andric 
associations()60270b57cec5SDimitry Andric   association_range associations() {
60280b57cec5SDimitry Andric     AssociationIterator Begin(getTrailingObjects<Stmt *>() +
602906c3fb27SDimitry Andric                                   getIndexOfStartOfAssociatedExprs(),
603006c3fb27SDimitry Andric                               getTrailingObjects<TypeSourceInfo *>() +
603106c3fb27SDimitry Andric                                   getIndexOfStartOfAssociatedTypes(),
60320b57cec5SDimitry Andric                               /*Offset=*/0, ResultIndex);
60330b57cec5SDimitry Andric     AssociationIterator End(Begin.E + NumAssocs, Begin.TSI + NumAssocs,
60340b57cec5SDimitry Andric                             /*Offset=*/NumAssocs, ResultIndex);
60350b57cec5SDimitry Andric     return llvm::make_range(Begin, End);
60360b57cec5SDimitry Andric   }
60370b57cec5SDimitry Andric 
associations()60380b57cec5SDimitry Andric   const_association_range associations() const {
60390b57cec5SDimitry Andric     ConstAssociationIterator Begin(getTrailingObjects<Stmt *>() +
604006c3fb27SDimitry Andric                                        getIndexOfStartOfAssociatedExprs(),
604106c3fb27SDimitry Andric                                    getTrailingObjects<TypeSourceInfo *>() +
604206c3fb27SDimitry Andric                                        getIndexOfStartOfAssociatedTypes(),
60430b57cec5SDimitry Andric                                    /*Offset=*/0, ResultIndex);
60440b57cec5SDimitry Andric     ConstAssociationIterator End(Begin.E + NumAssocs, Begin.TSI + NumAssocs,
60450b57cec5SDimitry Andric                                  /*Offset=*/NumAssocs, ResultIndex);
60460b57cec5SDimitry Andric     return llvm::make_range(Begin, End);
60470b57cec5SDimitry Andric   }
60480b57cec5SDimitry Andric 
getGenericLoc()60490b57cec5SDimitry Andric   SourceLocation getGenericLoc() const {
60500b57cec5SDimitry Andric     return GenericSelectionExprBits.GenericLoc;
60510b57cec5SDimitry Andric   }
getDefaultLoc()60520b57cec5SDimitry Andric   SourceLocation getDefaultLoc() const { return DefaultLoc; }
getRParenLoc()60530b57cec5SDimitry Andric   SourceLocation getRParenLoc() const { return RParenLoc; }
getBeginLoc()60540b57cec5SDimitry Andric   SourceLocation getBeginLoc() const { return getGenericLoc(); }
getEndLoc()60550b57cec5SDimitry Andric   SourceLocation getEndLoc() const { return getRParenLoc(); }
60560b57cec5SDimitry Andric 
classof(const Stmt * T)60570b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
60580b57cec5SDimitry Andric     return T->getStmtClass() == GenericSelectionExprClass;
60590b57cec5SDimitry Andric   }
60600b57cec5SDimitry Andric 
children()60610b57cec5SDimitry Andric   child_range children() {
60620b57cec5SDimitry Andric     return child_range(getTrailingObjects<Stmt *>(),
60630b57cec5SDimitry Andric                        getTrailingObjects<Stmt *>() +
60640b57cec5SDimitry Andric                            numTrailingObjects(OverloadToken<Stmt *>()));
60650b57cec5SDimitry Andric   }
children()60660b57cec5SDimitry Andric   const_child_range children() const {
60670b57cec5SDimitry Andric     return const_child_range(getTrailingObjects<Stmt *>(),
60680b57cec5SDimitry Andric                              getTrailingObjects<Stmt *>() +
60690b57cec5SDimitry Andric                                  numTrailingObjects(OverloadToken<Stmt *>()));
60700b57cec5SDimitry Andric   }
60710b57cec5SDimitry Andric };
60720b57cec5SDimitry Andric 
60730b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
60740b57cec5SDimitry Andric // Clang Extensions
60750b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
60760b57cec5SDimitry Andric 
60770b57cec5SDimitry Andric /// ExtVectorElementExpr - This represents access to specific elements of a
60780b57cec5SDimitry Andric /// vector, and may occur on the left hand side or right hand side.  For example
60790b57cec5SDimitry Andric /// the following is legal:  "V.xy = V.zw" if V is a 4 element extended vector.
60800b57cec5SDimitry Andric ///
60810b57cec5SDimitry Andric /// Note that the base may have either vector or pointer to vector type, just
60820b57cec5SDimitry Andric /// like a struct field reference.
60830b57cec5SDimitry Andric ///
60840b57cec5SDimitry Andric class ExtVectorElementExpr : public Expr {
60850b57cec5SDimitry Andric   Stmt *Base;
60860b57cec5SDimitry Andric   IdentifierInfo *Accessor;
60870b57cec5SDimitry Andric   SourceLocation AccessorLoc;
60880b57cec5SDimitry Andric public:
ExtVectorElementExpr(QualType ty,ExprValueKind VK,Expr * base,IdentifierInfo & accessor,SourceLocation loc)60890b57cec5SDimitry Andric   ExtVectorElementExpr(QualType ty, ExprValueKind VK, Expr *base,
60900b57cec5SDimitry Andric                        IdentifierInfo &accessor, SourceLocation loc)
60910b57cec5SDimitry Andric       : Expr(ExtVectorElementExprClass, ty, VK,
6092fe6060f1SDimitry Andric              (VK == VK_PRValue ? OK_Ordinary : OK_VectorComponent)),
60935ffd83dbSDimitry Andric         Base(base), Accessor(&accessor), AccessorLoc(loc) {
60945ffd83dbSDimitry Andric     setDependence(computeDependence(this));
60955ffd83dbSDimitry Andric   }
60960b57cec5SDimitry Andric 
60970b57cec5SDimitry Andric   /// Build an empty vector element expression.
ExtVectorElementExpr(EmptyShell Empty)60980b57cec5SDimitry Andric   explicit ExtVectorElementExpr(EmptyShell Empty)
60990b57cec5SDimitry Andric     : Expr(ExtVectorElementExprClass, Empty) { }
61000b57cec5SDimitry Andric 
getBase()61010b57cec5SDimitry Andric   const Expr *getBase() const { return cast<Expr>(Base); }
getBase()61020b57cec5SDimitry Andric   Expr *getBase() { return cast<Expr>(Base); }
setBase(Expr * E)61030b57cec5SDimitry Andric   void setBase(Expr *E) { Base = E; }
61040b57cec5SDimitry Andric 
getAccessor()61050b57cec5SDimitry Andric   IdentifierInfo &getAccessor() const { return *Accessor; }
setAccessor(IdentifierInfo * II)61060b57cec5SDimitry Andric   void setAccessor(IdentifierInfo *II) { Accessor = II; }
61070b57cec5SDimitry Andric 
getAccessorLoc()61080b57cec5SDimitry Andric   SourceLocation getAccessorLoc() const { return AccessorLoc; }
setAccessorLoc(SourceLocation L)61090b57cec5SDimitry Andric   void setAccessorLoc(SourceLocation L) { AccessorLoc = L; }
61100b57cec5SDimitry Andric 
61110b57cec5SDimitry Andric   /// getNumElements - Get the number of components being selected.
61120b57cec5SDimitry Andric   unsigned getNumElements() const;
61130b57cec5SDimitry Andric 
61140b57cec5SDimitry Andric   /// containsDuplicateElements - Return true if any element access is
61150b57cec5SDimitry Andric   /// repeated.
61160b57cec5SDimitry Andric   bool containsDuplicateElements() const;
61170b57cec5SDimitry Andric 
61180b57cec5SDimitry Andric   /// getEncodedElementAccess - Encode the elements accessed into an llvm
61190b57cec5SDimitry Andric   /// aggregate Constant of ConstantInt(s).
61200b57cec5SDimitry Andric   void getEncodedElementAccess(SmallVectorImpl<uint32_t> &Elts) const;
61210b57cec5SDimitry Andric 
getBeginLoc()61220b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY {
61230b57cec5SDimitry Andric     return getBase()->getBeginLoc();
61240b57cec5SDimitry Andric   }
getEndLoc()61250b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY { return AccessorLoc; }
61260b57cec5SDimitry Andric 
61270b57cec5SDimitry Andric   /// isArrow - Return true if the base expression is a pointer to vector,
61280b57cec5SDimitry Andric   /// return false if the base expression is a vector.
61290b57cec5SDimitry Andric   bool isArrow() const;
61300b57cec5SDimitry Andric 
classof(const Stmt * T)61310b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
61320b57cec5SDimitry Andric     return T->getStmtClass() == ExtVectorElementExprClass;
61330b57cec5SDimitry Andric   }
61340b57cec5SDimitry Andric 
61350b57cec5SDimitry Andric   // Iterators
children()61360b57cec5SDimitry Andric   child_range children() { return child_range(&Base, &Base+1); }
children()61370b57cec5SDimitry Andric   const_child_range children() const {
61380b57cec5SDimitry Andric     return const_child_range(&Base, &Base + 1);
61390b57cec5SDimitry Andric   }
61400b57cec5SDimitry Andric };
61410b57cec5SDimitry Andric 
61420b57cec5SDimitry Andric /// BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
61430b57cec5SDimitry Andric /// ^{ statement-body }   or   ^(int arg1, float arg2){ statement-body }
61440b57cec5SDimitry Andric class BlockExpr : public Expr {
61450b57cec5SDimitry Andric protected:
61460b57cec5SDimitry Andric   BlockDecl *TheBlock;
61470b57cec5SDimitry Andric public:
BlockExpr(BlockDecl * BD,QualType ty)61480b57cec5SDimitry Andric   BlockExpr(BlockDecl *BD, QualType ty)
6149fe6060f1SDimitry Andric       : Expr(BlockExprClass, ty, VK_PRValue, OK_Ordinary), TheBlock(BD) {
61505ffd83dbSDimitry Andric     setDependence(computeDependence(this));
61515ffd83dbSDimitry Andric   }
61520b57cec5SDimitry Andric 
61530b57cec5SDimitry Andric   /// Build an empty block expression.
BlockExpr(EmptyShell Empty)61540b57cec5SDimitry Andric   explicit BlockExpr(EmptyShell Empty) : Expr(BlockExprClass, Empty) { }
61550b57cec5SDimitry Andric 
getBlockDecl()61560b57cec5SDimitry Andric   const BlockDecl *getBlockDecl() const { return TheBlock; }
getBlockDecl()61570b57cec5SDimitry Andric   BlockDecl *getBlockDecl() { return TheBlock; }
setBlockDecl(BlockDecl * BD)61580b57cec5SDimitry Andric   void setBlockDecl(BlockDecl *BD) { TheBlock = BD; }
61590b57cec5SDimitry Andric 
61600b57cec5SDimitry Andric   // Convenience functions for probing the underlying BlockDecl.
61610b57cec5SDimitry Andric   SourceLocation getCaretLocation() const;
61620b57cec5SDimitry Andric   const Stmt *getBody() const;
61630b57cec5SDimitry Andric   Stmt *getBody();
61640b57cec5SDimitry Andric 
getBeginLoc()61650b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY {
61660b57cec5SDimitry Andric     return getCaretLocation();
61670b57cec5SDimitry Andric   }
getEndLoc()61680b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY {
61690b57cec5SDimitry Andric     return getBody()->getEndLoc();
61700b57cec5SDimitry Andric   }
61710b57cec5SDimitry Andric 
61720b57cec5SDimitry Andric   /// getFunctionType - Return the underlying function type for this block.
61730b57cec5SDimitry Andric   const FunctionProtoType *getFunctionType() const;
61740b57cec5SDimitry Andric 
classof(const Stmt * T)61750b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
61760b57cec5SDimitry Andric     return T->getStmtClass() == BlockExprClass;
61770b57cec5SDimitry Andric   }
61780b57cec5SDimitry Andric 
61790b57cec5SDimitry Andric   // Iterators
children()61800b57cec5SDimitry Andric   child_range children() {
61810b57cec5SDimitry Andric     return child_range(child_iterator(), child_iterator());
61820b57cec5SDimitry Andric   }
children()61830b57cec5SDimitry Andric   const_child_range children() const {
61840b57cec5SDimitry Andric     return const_child_range(const_child_iterator(), const_child_iterator());
61850b57cec5SDimitry Andric   }
61860b57cec5SDimitry Andric };
61870b57cec5SDimitry Andric 
6188480093f4SDimitry Andric /// Copy initialization expr of a __block variable and a boolean flag that
6189480093f4SDimitry Andric /// indicates whether the expression can throw.
6190480093f4SDimitry Andric struct BlockVarCopyInit {
6191480093f4SDimitry Andric   BlockVarCopyInit() = default;
BlockVarCopyInitBlockVarCopyInit6192480093f4SDimitry Andric   BlockVarCopyInit(Expr *CopyExpr, bool CanThrow)
6193480093f4SDimitry Andric       : ExprAndFlag(CopyExpr, CanThrow) {}
setExprAndFlagBlockVarCopyInit6194480093f4SDimitry Andric   void setExprAndFlag(Expr *CopyExpr, bool CanThrow) {
6195480093f4SDimitry Andric     ExprAndFlag.setPointerAndInt(CopyExpr, CanThrow);
6196480093f4SDimitry Andric   }
getCopyExprBlockVarCopyInit6197480093f4SDimitry Andric   Expr *getCopyExpr() const { return ExprAndFlag.getPointer(); }
canThrowBlockVarCopyInit6198480093f4SDimitry Andric   bool canThrow() const { return ExprAndFlag.getInt(); }
6199480093f4SDimitry Andric   llvm::PointerIntPair<Expr *, 1, bool> ExprAndFlag;
6200480093f4SDimitry Andric };
6201480093f4SDimitry Andric 
62020b57cec5SDimitry Andric /// AsTypeExpr - Clang builtin function __builtin_astype [OpenCL 6.2.4.2]
62030b57cec5SDimitry Andric /// This AST node provides support for reinterpreting a type to another
62040b57cec5SDimitry Andric /// type of the same size.
62050b57cec5SDimitry Andric class AsTypeExpr : public Expr {
62060b57cec5SDimitry Andric private:
62070b57cec5SDimitry Andric   Stmt *SrcExpr;
62080b57cec5SDimitry Andric   SourceLocation BuiltinLoc, RParenLoc;
62090b57cec5SDimitry Andric 
62100b57cec5SDimitry Andric   friend class ASTReader;
62110b57cec5SDimitry Andric   friend class ASTStmtReader;
AsTypeExpr(EmptyShell Empty)62120b57cec5SDimitry Andric   explicit AsTypeExpr(EmptyShell Empty) : Expr(AsTypeExprClass, Empty) {}
62130b57cec5SDimitry Andric 
62140b57cec5SDimitry Andric public:
AsTypeExpr(Expr * SrcExpr,QualType DstType,ExprValueKind VK,ExprObjectKind OK,SourceLocation BuiltinLoc,SourceLocation RParenLoc)62155ffd83dbSDimitry Andric   AsTypeExpr(Expr *SrcExpr, QualType DstType, ExprValueKind VK,
62165ffd83dbSDimitry Andric              ExprObjectKind OK, SourceLocation BuiltinLoc,
62175ffd83dbSDimitry Andric              SourceLocation RParenLoc)
62185ffd83dbSDimitry Andric       : Expr(AsTypeExprClass, DstType, VK, OK), SrcExpr(SrcExpr),
62195ffd83dbSDimitry Andric         BuiltinLoc(BuiltinLoc), RParenLoc(RParenLoc) {
62205ffd83dbSDimitry Andric     setDependence(computeDependence(this));
62215ffd83dbSDimitry Andric   }
62220b57cec5SDimitry Andric 
62230b57cec5SDimitry Andric   /// getSrcExpr - Return the Expr to be converted.
getSrcExpr()62240b57cec5SDimitry Andric   Expr *getSrcExpr() const { return cast<Expr>(SrcExpr); }
62250b57cec5SDimitry Andric 
62260b57cec5SDimitry Andric   /// getBuiltinLoc - Return the location of the __builtin_astype token.
getBuiltinLoc()62270b57cec5SDimitry Andric   SourceLocation getBuiltinLoc() const { return BuiltinLoc; }
62280b57cec5SDimitry Andric 
62290b57cec5SDimitry Andric   /// getRParenLoc - Return the location of final right parenthesis.
getRParenLoc()62300b57cec5SDimitry Andric   SourceLocation getRParenLoc() const { return RParenLoc; }
62310b57cec5SDimitry Andric 
getBeginLoc()62320b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY { return BuiltinLoc; }
getEndLoc()62330b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
62340b57cec5SDimitry Andric 
classof(const Stmt * T)62350b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
62360b57cec5SDimitry Andric     return T->getStmtClass() == AsTypeExprClass;
62370b57cec5SDimitry Andric   }
62380b57cec5SDimitry Andric 
62390b57cec5SDimitry Andric   // Iterators
children()62400b57cec5SDimitry Andric   child_range children() { return child_range(&SrcExpr, &SrcExpr+1); }
children()62410b57cec5SDimitry Andric   const_child_range children() const {
62420b57cec5SDimitry Andric     return const_child_range(&SrcExpr, &SrcExpr + 1);
62430b57cec5SDimitry Andric   }
62440b57cec5SDimitry Andric };
62450b57cec5SDimitry Andric 
62460b57cec5SDimitry Andric /// PseudoObjectExpr - An expression which accesses a pseudo-object
62470b57cec5SDimitry Andric /// l-value.  A pseudo-object is an abstract object, accesses to which
62480b57cec5SDimitry Andric /// are translated to calls.  The pseudo-object expression has a
62490b57cec5SDimitry Andric /// syntactic form, which shows how the expression was actually
62500b57cec5SDimitry Andric /// written in the source code, and a semantic form, which is a series
62510b57cec5SDimitry Andric /// of expressions to be executed in order which detail how the
62520b57cec5SDimitry Andric /// operation is actually evaluated.  Optionally, one of the semantic
62530b57cec5SDimitry Andric /// forms may also provide a result value for the expression.
62540b57cec5SDimitry Andric ///
62550b57cec5SDimitry Andric /// If any of the semantic-form expressions is an OpaqueValueExpr,
62560b57cec5SDimitry Andric /// that OVE is required to have a source expression, and it is bound
62570b57cec5SDimitry Andric /// to the result of that source expression.  Such OVEs may appear
62580b57cec5SDimitry Andric /// only in subsequent semantic-form expressions and as
62590b57cec5SDimitry Andric /// sub-expressions of the syntactic form.
62600b57cec5SDimitry Andric ///
62610b57cec5SDimitry Andric /// PseudoObjectExpr should be used only when an operation can be
62620b57cec5SDimitry Andric /// usefully described in terms of fairly simple rewrite rules on
62630b57cec5SDimitry Andric /// objects and functions that are meant to be used by end-developers.
62640b57cec5SDimitry Andric /// For example, under the Itanium ABI, dynamic casts are implemented
62650b57cec5SDimitry Andric /// as a call to a runtime function called __dynamic_cast; using this
62660b57cec5SDimitry Andric /// class to describe that would be inappropriate because that call is
62670b57cec5SDimitry Andric /// not really part of the user-visible semantics, and instead the
62680b57cec5SDimitry Andric /// cast is properly reflected in the AST and IR-generation has been
62690b57cec5SDimitry Andric /// taught to generate the call as necessary.  In contrast, an
62700b57cec5SDimitry Andric /// Objective-C property access is semantically defined to be
62710b57cec5SDimitry Andric /// equivalent to a particular message send, and this is very much
62720b57cec5SDimitry Andric /// part of the user model.  The name of this class encourages this
62730b57cec5SDimitry Andric /// modelling design.
62740b57cec5SDimitry Andric class PseudoObjectExpr final
62750b57cec5SDimitry Andric     : public Expr,
62760b57cec5SDimitry Andric       private llvm::TrailingObjects<PseudoObjectExpr, Expr *> {
62770b57cec5SDimitry Andric   // PseudoObjectExprBits.NumSubExprs - The number of sub-expressions.
62780b57cec5SDimitry Andric   // Always at least two, because the first sub-expression is the
62790b57cec5SDimitry Andric   // syntactic form.
62800b57cec5SDimitry Andric 
62810b57cec5SDimitry Andric   // PseudoObjectExprBits.ResultIndex - The index of the
62820b57cec5SDimitry Andric   // sub-expression holding the result.  0 means the result is void,
62830b57cec5SDimitry Andric   // which is unambiguous because it's the index of the syntactic
62840b57cec5SDimitry Andric   // form.  Note that this is therefore 1 higher than the value passed
62850b57cec5SDimitry Andric   // in to Create, which is an index within the semantic forms.
62860b57cec5SDimitry Andric   // Note also that ASTStmtWriter assumes this encoding.
62870b57cec5SDimitry Andric 
getSubExprsBuffer()62880b57cec5SDimitry Andric   Expr **getSubExprsBuffer() { return getTrailingObjects<Expr *>(); }
getSubExprsBuffer()62890b57cec5SDimitry Andric   const Expr * const *getSubExprsBuffer() const {
62900b57cec5SDimitry Andric     return getTrailingObjects<Expr *>();
62910b57cec5SDimitry Andric   }
62920b57cec5SDimitry Andric 
62930b57cec5SDimitry Andric   PseudoObjectExpr(QualType type, ExprValueKind VK,
62940b57cec5SDimitry Andric                    Expr *syntactic, ArrayRef<Expr*> semantic,
62950b57cec5SDimitry Andric                    unsigned resultIndex);
62960b57cec5SDimitry Andric 
62970b57cec5SDimitry Andric   PseudoObjectExpr(EmptyShell shell, unsigned numSemanticExprs);
62980b57cec5SDimitry Andric 
getNumSubExprs()62990b57cec5SDimitry Andric   unsigned getNumSubExprs() const {
63000b57cec5SDimitry Andric     return PseudoObjectExprBits.NumSubExprs;
63010b57cec5SDimitry Andric   }
63020b57cec5SDimitry Andric 
63030b57cec5SDimitry Andric public:
63040b57cec5SDimitry Andric   /// NoResult - A value for the result index indicating that there is
63050b57cec5SDimitry Andric   /// no semantic result.
63060b57cec5SDimitry Andric   enum : unsigned { NoResult = ~0U };
63070b57cec5SDimitry Andric 
63080b57cec5SDimitry Andric   static PseudoObjectExpr *Create(const ASTContext &Context, Expr *syntactic,
63090b57cec5SDimitry Andric                                   ArrayRef<Expr*> semantic,
63100b57cec5SDimitry Andric                                   unsigned resultIndex);
63110b57cec5SDimitry Andric 
63120b57cec5SDimitry Andric   static PseudoObjectExpr *Create(const ASTContext &Context, EmptyShell shell,
63130b57cec5SDimitry Andric                                   unsigned numSemanticExprs);
63140b57cec5SDimitry Andric 
63150b57cec5SDimitry Andric   /// Return the syntactic form of this expression, i.e. the
63160b57cec5SDimitry Andric   /// expression it actually looks like.  Likely to be expressed in
63170b57cec5SDimitry Andric   /// terms of OpaqueValueExprs bound in the semantic form.
getSyntacticForm()63180b57cec5SDimitry Andric   Expr *getSyntacticForm() { return getSubExprsBuffer()[0]; }
getSyntacticForm()63190b57cec5SDimitry Andric   const Expr *getSyntacticForm() const { return getSubExprsBuffer()[0]; }
63200b57cec5SDimitry Andric 
63210b57cec5SDimitry Andric   /// Return the index of the result-bearing expression into the semantics
63220b57cec5SDimitry Andric   /// expressions, or PseudoObjectExpr::NoResult if there is none.
getResultExprIndex()63230b57cec5SDimitry Andric   unsigned getResultExprIndex() const {
63240b57cec5SDimitry Andric     if (PseudoObjectExprBits.ResultIndex == 0) return NoResult;
63250b57cec5SDimitry Andric     return PseudoObjectExprBits.ResultIndex - 1;
63260b57cec5SDimitry Andric   }
63270b57cec5SDimitry Andric 
63280b57cec5SDimitry Andric   /// Return the result-bearing expression, or null if there is none.
getResultExpr()63290b57cec5SDimitry Andric   Expr *getResultExpr() {
63300b57cec5SDimitry Andric     if (PseudoObjectExprBits.ResultIndex == 0)
63310b57cec5SDimitry Andric       return nullptr;
63320b57cec5SDimitry Andric     return getSubExprsBuffer()[PseudoObjectExprBits.ResultIndex];
63330b57cec5SDimitry Andric   }
getResultExpr()63340b57cec5SDimitry Andric   const Expr *getResultExpr() const {
63350b57cec5SDimitry Andric     return const_cast<PseudoObjectExpr*>(this)->getResultExpr();
63360b57cec5SDimitry Andric   }
63370b57cec5SDimitry Andric 
getNumSemanticExprs()63380b57cec5SDimitry Andric   unsigned getNumSemanticExprs() const { return getNumSubExprs() - 1; }
63390b57cec5SDimitry Andric 
63400b57cec5SDimitry Andric   typedef Expr * const *semantics_iterator;
63410b57cec5SDimitry Andric   typedef const Expr * const *const_semantics_iterator;
semantics_begin()63420b57cec5SDimitry Andric   semantics_iterator semantics_begin() {
63430b57cec5SDimitry Andric     return getSubExprsBuffer() + 1;
63440b57cec5SDimitry Andric   }
semantics_begin()63450b57cec5SDimitry Andric   const_semantics_iterator semantics_begin() const {
63460b57cec5SDimitry Andric     return getSubExprsBuffer() + 1;
63470b57cec5SDimitry Andric   }
semantics_end()63480b57cec5SDimitry Andric   semantics_iterator semantics_end() {
63490b57cec5SDimitry Andric     return getSubExprsBuffer() + getNumSubExprs();
63500b57cec5SDimitry Andric   }
semantics_end()63510b57cec5SDimitry Andric   const_semantics_iterator semantics_end() const {
63520b57cec5SDimitry Andric     return getSubExprsBuffer() + getNumSubExprs();
63530b57cec5SDimitry Andric   }
63540b57cec5SDimitry Andric 
semantics()635506c3fb27SDimitry Andric   ArrayRef<Expr*> semantics() {
635606c3fb27SDimitry Andric     return ArrayRef(semantics_begin(), semantics_end());
63570b57cec5SDimitry Andric   }
semantics()635806c3fb27SDimitry Andric   ArrayRef<const Expr*> semantics() const {
635906c3fb27SDimitry Andric     return ArrayRef(semantics_begin(), semantics_end());
63600b57cec5SDimitry Andric   }
63610b57cec5SDimitry Andric 
getSemanticExpr(unsigned index)63620b57cec5SDimitry Andric   Expr *getSemanticExpr(unsigned index) {
63630b57cec5SDimitry Andric     assert(index + 1 < getNumSubExprs());
63640b57cec5SDimitry Andric     return getSubExprsBuffer()[index + 1];
63650b57cec5SDimitry Andric   }
getSemanticExpr(unsigned index)63660b57cec5SDimitry Andric   const Expr *getSemanticExpr(unsigned index) const {
63670b57cec5SDimitry Andric     return const_cast<PseudoObjectExpr*>(this)->getSemanticExpr(index);
63680b57cec5SDimitry Andric   }
63690b57cec5SDimitry Andric 
getExprLoc()63700b57cec5SDimitry Andric   SourceLocation getExprLoc() const LLVM_READONLY {
63710b57cec5SDimitry Andric     return getSyntacticForm()->getExprLoc();
63720b57cec5SDimitry Andric   }
63730b57cec5SDimitry Andric 
getBeginLoc()63740b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY {
63750b57cec5SDimitry Andric     return getSyntacticForm()->getBeginLoc();
63760b57cec5SDimitry Andric   }
getEndLoc()63770b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY {
63780b57cec5SDimitry Andric     return getSyntacticForm()->getEndLoc();
63790b57cec5SDimitry Andric   }
63800b57cec5SDimitry Andric 
children()63810b57cec5SDimitry Andric   child_range children() {
63820b57cec5SDimitry Andric     const_child_range CCR =
63830b57cec5SDimitry Andric         const_cast<const PseudoObjectExpr *>(this)->children();
63840b57cec5SDimitry Andric     return child_range(cast_away_const(CCR.begin()),
63850b57cec5SDimitry Andric                        cast_away_const(CCR.end()));
63860b57cec5SDimitry Andric   }
children()63870b57cec5SDimitry Andric   const_child_range children() const {
63880b57cec5SDimitry Andric     Stmt *const *cs = const_cast<Stmt *const *>(
63890b57cec5SDimitry Andric         reinterpret_cast<const Stmt *const *>(getSubExprsBuffer()));
63900b57cec5SDimitry Andric     return const_child_range(cs, cs + getNumSubExprs());
63910b57cec5SDimitry Andric   }
63920b57cec5SDimitry Andric 
classof(const Stmt * T)63930b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
63940b57cec5SDimitry Andric     return T->getStmtClass() == PseudoObjectExprClass;
63950b57cec5SDimitry Andric   }
63960b57cec5SDimitry Andric 
63970b57cec5SDimitry Andric   friend TrailingObjects;
63980b57cec5SDimitry Andric   friend class ASTStmtReader;
63990b57cec5SDimitry Andric };
64000b57cec5SDimitry Andric 
64010b57cec5SDimitry Andric /// AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*,
64020b57cec5SDimitry Andric /// __atomic_load, __atomic_store, and __atomic_compare_exchange_*, for the
64030b57cec5SDimitry Andric /// similarly-named C++11 instructions, and __c11 variants for <stdatomic.h>,
64040b57cec5SDimitry Andric /// and corresponding __opencl_atomic_* for OpenCL 2.0.
64050b57cec5SDimitry Andric /// All of these instructions take one primary pointer, at least one memory
64060b57cec5SDimitry Andric /// order. The instructions for which getScopeModel returns non-null value
64070b57cec5SDimitry Andric /// take one synch scope.
64080b57cec5SDimitry Andric class AtomicExpr : public Expr {
64090b57cec5SDimitry Andric public:
64100b57cec5SDimitry Andric   enum AtomicOp {
64110b57cec5SDimitry Andric #define BUILTIN(ID, TYPE, ATTRS)
64120b57cec5SDimitry Andric #define ATOMIC_BUILTIN(ID, TYPE, ATTRS) AO ## ID,
64130b57cec5SDimitry Andric #include "clang/Basic/Builtins.def"
64140b57cec5SDimitry Andric     // Avoid trailing comma
64150b57cec5SDimitry Andric     BI_First = 0
64160b57cec5SDimitry Andric   };
64170b57cec5SDimitry Andric 
64180b57cec5SDimitry Andric private:
64190b57cec5SDimitry Andric   /// Location of sub-expressions.
64200b57cec5SDimitry Andric   /// The location of Scope sub-expression is NumSubExprs - 1, which is
64210b57cec5SDimitry Andric   /// not fixed, therefore is not defined in enum.
64220b57cec5SDimitry Andric   enum { PTR, ORDER, VAL1, ORDER_FAIL, VAL2, WEAK, END_EXPR };
64230b57cec5SDimitry Andric   Stmt *SubExprs[END_EXPR + 1];
64240b57cec5SDimitry Andric   unsigned NumSubExprs;
64250b57cec5SDimitry Andric   SourceLocation BuiltinLoc, RParenLoc;
64260b57cec5SDimitry Andric   AtomicOp Op;
64270b57cec5SDimitry Andric 
64280b57cec5SDimitry Andric   friend class ASTStmtReader;
64290b57cec5SDimitry Andric public:
64300b57cec5SDimitry Andric   AtomicExpr(SourceLocation BLoc, ArrayRef<Expr*> args, QualType t,
64310b57cec5SDimitry Andric              AtomicOp op, SourceLocation RP);
64320b57cec5SDimitry Andric 
64330b57cec5SDimitry Andric   /// Determine the number of arguments the specified atomic builtin
64340b57cec5SDimitry Andric   /// should have.
64350b57cec5SDimitry Andric   static unsigned getNumSubExprs(AtomicOp Op);
64360b57cec5SDimitry Andric 
64370b57cec5SDimitry Andric   /// Build an empty AtomicExpr.
AtomicExpr(EmptyShell Empty)64380b57cec5SDimitry Andric   explicit AtomicExpr(EmptyShell Empty) : Expr(AtomicExprClass, Empty) { }
64390b57cec5SDimitry Andric 
getPtr()64400b57cec5SDimitry Andric   Expr *getPtr() const {
64410b57cec5SDimitry Andric     return cast<Expr>(SubExprs[PTR]);
64420b57cec5SDimitry Andric   }
getOrder()64430b57cec5SDimitry Andric   Expr *getOrder() const {
64440b57cec5SDimitry Andric     return cast<Expr>(SubExprs[ORDER]);
64450b57cec5SDimitry Andric   }
getScope()64460b57cec5SDimitry Andric   Expr *getScope() const {
64470b57cec5SDimitry Andric     assert(getScopeModel() && "No scope");
64480b57cec5SDimitry Andric     return cast<Expr>(SubExprs[NumSubExprs - 1]);
64490b57cec5SDimitry Andric   }
getVal1()64500b57cec5SDimitry Andric   Expr *getVal1() const {
64510b57cec5SDimitry Andric     if (Op == AO__c11_atomic_init || Op == AO__opencl_atomic_init)
64520b57cec5SDimitry Andric       return cast<Expr>(SubExprs[ORDER]);
64530b57cec5SDimitry Andric     assert(NumSubExprs > VAL1);
64540b57cec5SDimitry Andric     return cast<Expr>(SubExprs[VAL1]);
64550b57cec5SDimitry Andric   }
getOrderFail()64560b57cec5SDimitry Andric   Expr *getOrderFail() const {
64570b57cec5SDimitry Andric     assert(NumSubExprs > ORDER_FAIL);
64580b57cec5SDimitry Andric     return cast<Expr>(SubExprs[ORDER_FAIL]);
64590b57cec5SDimitry Andric   }
getVal2()64600b57cec5SDimitry Andric   Expr *getVal2() const {
64615f757f3fSDimitry Andric     if (Op == AO__atomic_exchange || Op == AO__scoped_atomic_exchange)
64620b57cec5SDimitry Andric       return cast<Expr>(SubExprs[ORDER_FAIL]);
64630b57cec5SDimitry Andric     assert(NumSubExprs > VAL2);
64640b57cec5SDimitry Andric     return cast<Expr>(SubExprs[VAL2]);
64650b57cec5SDimitry Andric   }
getWeak()64660b57cec5SDimitry Andric   Expr *getWeak() const {
64670b57cec5SDimitry Andric     assert(NumSubExprs > WEAK);
64680b57cec5SDimitry Andric     return cast<Expr>(SubExprs[WEAK]);
64690b57cec5SDimitry Andric   }
64700b57cec5SDimitry Andric   QualType getValueType() const;
64710b57cec5SDimitry Andric 
getOp()64720b57cec5SDimitry Andric   AtomicOp getOp() const { return Op; }
getOpAsString()64735f757f3fSDimitry Andric   StringRef getOpAsString() const {
64745f757f3fSDimitry Andric     switch (Op) {
64755f757f3fSDimitry Andric #define BUILTIN(ID, TYPE, ATTRS)
64765f757f3fSDimitry Andric #define ATOMIC_BUILTIN(ID, TYPE, ATTRS)                                        \
64775f757f3fSDimitry Andric   case AO##ID:                                                                 \
64785f757f3fSDimitry Andric     return #ID;
64795f757f3fSDimitry Andric #include "clang/Basic/Builtins.def"
64805f757f3fSDimitry Andric     }
64815f757f3fSDimitry Andric     llvm_unreachable("not an atomic operator?");
64825f757f3fSDimitry Andric   }
getNumSubExprs()64830b57cec5SDimitry Andric   unsigned getNumSubExprs() const { return NumSubExprs; }
64840b57cec5SDimitry Andric 
getSubExprs()64850b57cec5SDimitry Andric   Expr **getSubExprs() { return reinterpret_cast<Expr **>(SubExprs); }
getSubExprs()64860b57cec5SDimitry Andric   const Expr * const *getSubExprs() const {
64870b57cec5SDimitry Andric     return reinterpret_cast<Expr * const *>(SubExprs);
64880b57cec5SDimitry Andric   }
64890b57cec5SDimitry Andric 
isVolatile()64900b57cec5SDimitry Andric   bool isVolatile() const {
64910b57cec5SDimitry Andric     return getPtr()->getType()->getPointeeType().isVolatileQualified();
64920b57cec5SDimitry Andric   }
64930b57cec5SDimitry Andric 
isCmpXChg()64940b57cec5SDimitry Andric   bool isCmpXChg() const {
64950b57cec5SDimitry Andric     return getOp() == AO__c11_atomic_compare_exchange_strong ||
64960b57cec5SDimitry Andric            getOp() == AO__c11_atomic_compare_exchange_weak ||
64974824e7fdSDimitry Andric            getOp() == AO__hip_atomic_compare_exchange_strong ||
64980b57cec5SDimitry Andric            getOp() == AO__opencl_atomic_compare_exchange_strong ||
64990b57cec5SDimitry Andric            getOp() == AO__opencl_atomic_compare_exchange_weak ||
65004824e7fdSDimitry Andric            getOp() == AO__hip_atomic_compare_exchange_weak ||
65010b57cec5SDimitry Andric            getOp() == AO__atomic_compare_exchange ||
65025f757f3fSDimitry Andric            getOp() == AO__atomic_compare_exchange_n ||
65035f757f3fSDimitry Andric            getOp() == AO__scoped_atomic_compare_exchange ||
65045f757f3fSDimitry Andric            getOp() == AO__scoped_atomic_compare_exchange_n;
65050b57cec5SDimitry Andric   }
65060b57cec5SDimitry Andric 
isOpenCL()65070b57cec5SDimitry Andric   bool isOpenCL() const {
65080b57cec5SDimitry Andric     return getOp() >= AO__opencl_atomic_init &&
65090b57cec5SDimitry Andric            getOp() <= AO__opencl_atomic_fetch_max;
65100b57cec5SDimitry Andric   }
65110b57cec5SDimitry Andric 
getBuiltinLoc()65120b57cec5SDimitry Andric   SourceLocation getBuiltinLoc() const { return BuiltinLoc; }
getRParenLoc()65130b57cec5SDimitry Andric   SourceLocation getRParenLoc() const { return RParenLoc; }
65140b57cec5SDimitry Andric 
getBeginLoc()65150b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY { return BuiltinLoc; }
getEndLoc()65160b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
65170b57cec5SDimitry Andric 
classof(const Stmt * T)65180b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
65190b57cec5SDimitry Andric     return T->getStmtClass() == AtomicExprClass;
65200b57cec5SDimitry Andric   }
65210b57cec5SDimitry Andric 
65220b57cec5SDimitry Andric   // Iterators
children()65230b57cec5SDimitry Andric   child_range children() {
65240b57cec5SDimitry Andric     return child_range(SubExprs, SubExprs+NumSubExprs);
65250b57cec5SDimitry Andric   }
children()65260b57cec5SDimitry Andric   const_child_range children() const {
65270b57cec5SDimitry Andric     return const_child_range(SubExprs, SubExprs + NumSubExprs);
65280b57cec5SDimitry Andric   }
65290b57cec5SDimitry Andric 
65300b57cec5SDimitry Andric   /// Get atomic scope model for the atomic op code.
65310b57cec5SDimitry Andric   /// \return empty atomic scope model if the atomic op code does not have
65320b57cec5SDimitry Andric   ///   scope operand.
getScopeModel(AtomicOp Op)65330b57cec5SDimitry Andric   static std::unique_ptr<AtomicScopeModel> getScopeModel(AtomicOp Op) {
65345f757f3fSDimitry Andric     if (Op >= AO__opencl_atomic_load && Op <= AO__opencl_atomic_fetch_max)
65355f757f3fSDimitry Andric       return AtomicScopeModel::create(AtomicScopeModelKind::OpenCL);
65365f757f3fSDimitry Andric     else if (Op >= AO__hip_atomic_load && Op <= AO__hip_atomic_fetch_max)
65375f757f3fSDimitry Andric       return AtomicScopeModel::create(AtomicScopeModelKind::HIP);
65385f757f3fSDimitry Andric     else if (Op >= AO__scoped_atomic_load && Op <= AO__scoped_atomic_fetch_max)
65395f757f3fSDimitry Andric       return AtomicScopeModel::create(AtomicScopeModelKind::Generic);
65405f757f3fSDimitry Andric     return AtomicScopeModel::create(AtomicScopeModelKind::None);
65410b57cec5SDimitry Andric   }
65420b57cec5SDimitry Andric 
65430b57cec5SDimitry Andric   /// Get atomic scope model.
65440b57cec5SDimitry Andric   /// \return empty atomic scope model if this atomic expression does not have
65450b57cec5SDimitry Andric   ///   scope operand.
getScopeModel()65460b57cec5SDimitry Andric   std::unique_ptr<AtomicScopeModel> getScopeModel() const {
65470b57cec5SDimitry Andric     return getScopeModel(getOp());
65480b57cec5SDimitry Andric   }
65490b57cec5SDimitry Andric };
65500b57cec5SDimitry Andric 
65510b57cec5SDimitry Andric /// TypoExpr - Internal placeholder for expressions where typo correction
65520b57cec5SDimitry Andric /// still needs to be performed and/or an error diagnostic emitted.
65530b57cec5SDimitry Andric class TypoExpr : public Expr {
65545ffd83dbSDimitry Andric   // The location for the typo name.
65555ffd83dbSDimitry Andric   SourceLocation TypoLoc;
65565ffd83dbSDimitry Andric 
65570b57cec5SDimitry Andric public:
TypoExpr(QualType T,SourceLocation TypoLoc)65585ffd83dbSDimitry Andric   TypoExpr(QualType T, SourceLocation TypoLoc)
65595ffd83dbSDimitry Andric       : Expr(TypoExprClass, T, VK_LValue, OK_Ordinary), TypoLoc(TypoLoc) {
65600b57cec5SDimitry Andric     assert(T->isDependentType() && "TypoExpr given a non-dependent type");
65615ffd83dbSDimitry Andric     setDependence(ExprDependence::TypeValueInstantiation |
65625ffd83dbSDimitry Andric                   ExprDependence::Error);
65630b57cec5SDimitry Andric   }
65640b57cec5SDimitry Andric 
children()65650b57cec5SDimitry Andric   child_range children() {
65660b57cec5SDimitry Andric     return child_range(child_iterator(), child_iterator());
65670b57cec5SDimitry Andric   }
children()65680b57cec5SDimitry Andric   const_child_range children() const {
65690b57cec5SDimitry Andric     return const_child_range(const_child_iterator(), const_child_iterator());
65700b57cec5SDimitry Andric   }
65710b57cec5SDimitry Andric 
getBeginLoc()65725ffd83dbSDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY { return TypoLoc; }
getEndLoc()65735ffd83dbSDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY { return TypoLoc; }
65740b57cec5SDimitry Andric 
classof(const Stmt * T)65750b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
65760b57cec5SDimitry Andric     return T->getStmtClass() == TypoExprClass;
65770b57cec5SDimitry Andric   }
65780b57cec5SDimitry Andric 
65790b57cec5SDimitry Andric };
65805ffd83dbSDimitry Andric 
65815ffd83dbSDimitry Andric /// Frontend produces RecoveryExprs on semantic errors that prevent creating
65825ffd83dbSDimitry Andric /// other well-formed expressions. E.g. when type-checking of a binary operator
65835ffd83dbSDimitry Andric /// fails, we cannot produce a BinaryOperator expression. Instead, we can choose
65845ffd83dbSDimitry Andric /// to produce a recovery expression storing left and right operands.
65855ffd83dbSDimitry Andric ///
65865ffd83dbSDimitry Andric /// RecoveryExpr does not have any semantic meaning in C++, it is only useful to
65875ffd83dbSDimitry Andric /// preserve expressions in AST that would otherwise be dropped. It captures
65885ffd83dbSDimitry Andric /// subexpressions of some expression that we could not construct and source
65895ffd83dbSDimitry Andric /// range covered by the expression.
65905ffd83dbSDimitry Andric ///
65915ffd83dbSDimitry Andric /// By default, RecoveryExpr uses dependence-bits to take advantage of existing
65925ffd83dbSDimitry Andric /// machinery to deal with dependent code in C++, e.g. RecoveryExpr is preserved
65935ffd83dbSDimitry Andric /// in `decltype(<broken-expr>)` as part of the `DependentDecltypeType`. In
65945ffd83dbSDimitry Andric /// addition to that, clang does not report most errors on dependent
65955ffd83dbSDimitry Andric /// expressions, so we get rid of bogus errors for free. However, note that
65965ffd83dbSDimitry Andric /// unlike other dependent expressions, RecoveryExpr can be produced in
65975ffd83dbSDimitry Andric /// non-template contexts.
65985ffd83dbSDimitry Andric ///
65995ffd83dbSDimitry Andric /// We will preserve the type in RecoveryExpr when the type is known, e.g.
66005ffd83dbSDimitry Andric /// preserving the return type for a broken non-overloaded function call, a
66015ffd83dbSDimitry Andric /// overloaded call where all candidates have the same return type. In this
66025ffd83dbSDimitry Andric /// case, the expression is not type-dependent (unless the known type is itself
66035ffd83dbSDimitry Andric /// dependent)
66045ffd83dbSDimitry Andric ///
66055ffd83dbSDimitry Andric /// One can also reliably suppress all bogus errors on expressions containing
66065ffd83dbSDimitry Andric /// recovery expressions by examining results of Expr::containsErrors().
66075ffd83dbSDimitry Andric class RecoveryExpr final : public Expr,
66085ffd83dbSDimitry Andric                            private llvm::TrailingObjects<RecoveryExpr, Expr *> {
66095ffd83dbSDimitry Andric public:
66105ffd83dbSDimitry Andric   static RecoveryExpr *Create(ASTContext &Ctx, QualType T,
66115ffd83dbSDimitry Andric                               SourceLocation BeginLoc, SourceLocation EndLoc,
66125ffd83dbSDimitry Andric                               ArrayRef<Expr *> SubExprs);
66135ffd83dbSDimitry Andric   static RecoveryExpr *CreateEmpty(ASTContext &Ctx, unsigned NumSubExprs);
66145ffd83dbSDimitry Andric 
subExpressions()66155ffd83dbSDimitry Andric   ArrayRef<Expr *> subExpressions() {
66165ffd83dbSDimitry Andric     auto *B = getTrailingObjects<Expr *>();
6617bdd1243dSDimitry Andric     return llvm::ArrayRef(B, B + NumExprs);
66185ffd83dbSDimitry Andric   }
66195ffd83dbSDimitry Andric 
subExpressions()66205ffd83dbSDimitry Andric   ArrayRef<const Expr *> subExpressions() const {
66215ffd83dbSDimitry Andric     return const_cast<RecoveryExpr *>(this)->subExpressions();
66225ffd83dbSDimitry Andric   }
66235ffd83dbSDimitry Andric 
children()66245ffd83dbSDimitry Andric   child_range children() {
66255ffd83dbSDimitry Andric     Stmt **B = reinterpret_cast<Stmt **>(getTrailingObjects<Expr *>());
66265ffd83dbSDimitry Andric     return child_range(B, B + NumExprs);
66275ffd83dbSDimitry Andric   }
66285ffd83dbSDimitry Andric 
getBeginLoc()66295ffd83dbSDimitry Andric   SourceLocation getBeginLoc() const { return BeginLoc; }
getEndLoc()66305ffd83dbSDimitry Andric   SourceLocation getEndLoc() const { return EndLoc; }
66315ffd83dbSDimitry Andric 
classof(const Stmt * T)66325ffd83dbSDimitry Andric   static bool classof(const Stmt *T) {
66335ffd83dbSDimitry Andric     return T->getStmtClass() == RecoveryExprClass;
66345ffd83dbSDimitry Andric   }
66355ffd83dbSDimitry Andric 
66365ffd83dbSDimitry Andric private:
66375ffd83dbSDimitry Andric   RecoveryExpr(ASTContext &Ctx, QualType T, SourceLocation BeginLoc,
66385ffd83dbSDimitry Andric                SourceLocation EndLoc, ArrayRef<Expr *> SubExprs);
RecoveryExpr(EmptyShell Empty,unsigned NumSubExprs)66395ffd83dbSDimitry Andric   RecoveryExpr(EmptyShell Empty, unsigned NumSubExprs)
66405ffd83dbSDimitry Andric       : Expr(RecoveryExprClass, Empty), NumExprs(NumSubExprs) {}
66415ffd83dbSDimitry Andric 
numTrailingObjects(OverloadToken<Stmt * >)66425ffd83dbSDimitry Andric   size_t numTrailingObjects(OverloadToken<Stmt *>) const { return NumExprs; }
66435ffd83dbSDimitry Andric 
66445ffd83dbSDimitry Andric   SourceLocation BeginLoc, EndLoc;
66455ffd83dbSDimitry Andric   unsigned NumExprs;
66465ffd83dbSDimitry Andric   friend TrailingObjects;
66475ffd83dbSDimitry Andric   friend class ASTStmtReader;
66485ffd83dbSDimitry Andric   friend class ASTStmtWriter;
66495ffd83dbSDimitry Andric };
66505ffd83dbSDimitry Andric 
66510b57cec5SDimitry Andric } // end namespace clang
66520b57cec5SDimitry Andric 
66530b57cec5SDimitry Andric #endif // LLVM_CLANG_AST_EXPR_H
6654