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()5030