10b57cec5SDimitry Andric //===- ExprCXX.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 /// \file
100b57cec5SDimitry Andric /// Defines the clang::Expr interface and subclasses for C++ expressions.
110b57cec5SDimitry Andric //
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric 
140b57cec5SDimitry Andric #ifndef LLVM_CLANG_AST_EXPRCXX_H
150b57cec5SDimitry Andric #define LLVM_CLANG_AST_EXPRCXX_H
160b57cec5SDimitry Andric 
175ffd83dbSDimitry Andric #include "clang/AST/ASTConcept.h"
185ffd83dbSDimitry Andric #include "clang/AST/ComputeDependence.h"
190b57cec5SDimitry Andric #include "clang/AST/Decl.h"
200b57cec5SDimitry Andric #include "clang/AST/DeclBase.h"
210b57cec5SDimitry Andric #include "clang/AST/DeclCXX.h"
22a7dea167SDimitry Andric #include "clang/AST/DeclTemplate.h"
230b57cec5SDimitry Andric #include "clang/AST/DeclarationName.h"
245ffd83dbSDimitry Andric #include "clang/AST/DependenceFlags.h"
250b57cec5SDimitry Andric #include "clang/AST/Expr.h"
260b57cec5SDimitry Andric #include "clang/AST/NestedNameSpecifier.h"
270b57cec5SDimitry Andric #include "clang/AST/OperationKinds.h"
280b57cec5SDimitry Andric #include "clang/AST/Stmt.h"
295ffd83dbSDimitry Andric #include "clang/AST/StmtCXX.h"
300b57cec5SDimitry Andric #include "clang/AST/TemplateBase.h"
310b57cec5SDimitry Andric #include "clang/AST/Type.h"
320b57cec5SDimitry Andric #include "clang/AST/UnresolvedSet.h"
330b57cec5SDimitry Andric #include "clang/Basic/ExceptionSpecificationType.h"
340b57cec5SDimitry Andric #include "clang/Basic/ExpressionTraits.h"
350b57cec5SDimitry Andric #include "clang/Basic/LLVM.h"
360b57cec5SDimitry Andric #include "clang/Basic/Lambda.h"
370b57cec5SDimitry Andric #include "clang/Basic/LangOptions.h"
380b57cec5SDimitry Andric #include "clang/Basic/OperatorKinds.h"
390b57cec5SDimitry Andric #include "clang/Basic/SourceLocation.h"
400b57cec5SDimitry Andric #include "clang/Basic/Specifiers.h"
410b57cec5SDimitry Andric #include "clang/Basic/TypeTraits.h"
420b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h"
430b57cec5SDimitry Andric #include "llvm/ADT/PointerUnion.h"
440b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
450b57cec5SDimitry Andric #include "llvm/ADT/iterator_range.h"
460b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
470b57cec5SDimitry Andric #include "llvm/Support/Compiler.h"
480b57cec5SDimitry Andric #include "llvm/Support/TrailingObjects.h"
490b57cec5SDimitry Andric #include <cassert>
500b57cec5SDimitry Andric #include <cstddef>
510b57cec5SDimitry Andric #include <cstdint>
520b57cec5SDimitry Andric #include <memory>
53bdd1243dSDimitry Andric #include <optional>
540b57cec5SDimitry Andric 
550b57cec5SDimitry Andric namespace clang {
560b57cec5SDimitry Andric 
570b57cec5SDimitry Andric class ASTContext;
580b57cec5SDimitry Andric class DeclAccessPair;
590b57cec5SDimitry Andric class IdentifierInfo;
600b57cec5SDimitry Andric class LambdaCapture;
610b57cec5SDimitry Andric class NonTypeTemplateParmDecl;
620b57cec5SDimitry Andric class TemplateParameterList;
630b57cec5SDimitry Andric 
640b57cec5SDimitry Andric //===--------------------------------------------------------------------===//
650b57cec5SDimitry Andric // C++ Expressions.
660b57cec5SDimitry Andric //===--------------------------------------------------------------------===//
670b57cec5SDimitry Andric 
680b57cec5SDimitry Andric /// A call to an overloaded operator written using operator
690b57cec5SDimitry Andric /// syntax.
700b57cec5SDimitry Andric ///
710b57cec5SDimitry Andric /// Represents a call to an overloaded operator written using operator
720b57cec5SDimitry Andric /// syntax, e.g., "x + y" or "*p". While semantically equivalent to a
730b57cec5SDimitry Andric /// normal call, this AST node provides better information about the
740b57cec5SDimitry Andric /// syntactic representation of the call.
750b57cec5SDimitry Andric ///
760b57cec5SDimitry Andric /// In a C++ template, this expression node kind will be used whenever
770b57cec5SDimitry Andric /// any of the arguments are type-dependent. In this case, the
780b57cec5SDimitry Andric /// function itself will be a (possibly empty) set of functions and
790b57cec5SDimitry Andric /// function templates that were found by name lookup at template
800b57cec5SDimitry Andric /// definition time.
810b57cec5SDimitry Andric class CXXOperatorCallExpr final : public CallExpr {
820b57cec5SDimitry Andric   friend class ASTStmtReader;
830b57cec5SDimitry Andric   friend class ASTStmtWriter;
840b57cec5SDimitry Andric 
850b57cec5SDimitry Andric   SourceRange Range;
860b57cec5SDimitry Andric 
870b57cec5SDimitry Andric   // CXXOperatorCallExpr has some trailing objects belonging
880b57cec5SDimitry Andric   // to CallExpr. See CallExpr for the details.
890b57cec5SDimitry Andric 
900b57cec5SDimitry Andric   SourceRange getSourceRangeImpl() const LLVM_READONLY;
910b57cec5SDimitry Andric 
920b57cec5SDimitry Andric   CXXOperatorCallExpr(OverloadedOperatorKind OpKind, Expr *Fn,
930b57cec5SDimitry Andric                       ArrayRef<Expr *> Args, QualType Ty, ExprValueKind VK,
945ffd83dbSDimitry Andric                       SourceLocation OperatorLoc, FPOptionsOverride FPFeatures,
950b57cec5SDimitry Andric                       ADLCallKind UsesADL);
960b57cec5SDimitry Andric 
97e8d8bef9SDimitry Andric   CXXOperatorCallExpr(unsigned NumArgs, bool HasFPFeatures, EmptyShell Empty);
980b57cec5SDimitry Andric 
990b57cec5SDimitry Andric public:
1000b57cec5SDimitry Andric   static CXXOperatorCallExpr *
1010b57cec5SDimitry Andric   Create(const ASTContext &Ctx, OverloadedOperatorKind OpKind, Expr *Fn,
1020b57cec5SDimitry Andric          ArrayRef<Expr *> Args, QualType Ty, ExprValueKind VK,
1035ffd83dbSDimitry Andric          SourceLocation OperatorLoc, FPOptionsOverride FPFeatures,
1040b57cec5SDimitry Andric          ADLCallKind UsesADL = NotADL);
1050b57cec5SDimitry Andric 
1060b57cec5SDimitry Andric   static CXXOperatorCallExpr *CreateEmpty(const ASTContext &Ctx,
107e8d8bef9SDimitry Andric                                           unsigned NumArgs, bool HasFPFeatures,
108e8d8bef9SDimitry Andric                                           EmptyShell Empty);
1090b57cec5SDimitry Andric 
1100b57cec5SDimitry Andric   /// Returns the kind of overloaded operator that this expression refers to.
getOperator()1110b57cec5SDimitry Andric   OverloadedOperatorKind getOperator() const {
1120b57cec5SDimitry Andric     return static_cast<OverloadedOperatorKind>(
1130b57cec5SDimitry Andric         CXXOperatorCallExprBits.OperatorKind);
1140b57cec5SDimitry Andric   }
1150b57cec5SDimitry Andric 
isAssignmentOp(OverloadedOperatorKind Opc)1160b57cec5SDimitry Andric   static bool isAssignmentOp(OverloadedOperatorKind Opc) {
1170b57cec5SDimitry Andric     return Opc == OO_Equal || Opc == OO_StarEqual || Opc == OO_SlashEqual ||
1180b57cec5SDimitry Andric            Opc == OO_PercentEqual || Opc == OO_PlusEqual ||
1190b57cec5SDimitry Andric            Opc == OO_MinusEqual || Opc == OO_LessLessEqual ||
1200b57cec5SDimitry Andric            Opc == OO_GreaterGreaterEqual || Opc == OO_AmpEqual ||
1210b57cec5SDimitry Andric            Opc == OO_CaretEqual || Opc == OO_PipeEqual;
1220b57cec5SDimitry Andric   }
isAssignmentOp()1230b57cec5SDimitry Andric   bool isAssignmentOp() const { return isAssignmentOp(getOperator()); }
1240b57cec5SDimitry Andric 
isComparisonOp(OverloadedOperatorKind Opc)1255ffd83dbSDimitry Andric   static bool isComparisonOp(OverloadedOperatorKind Opc) {
1265ffd83dbSDimitry Andric     switch (Opc) {
1275ffd83dbSDimitry Andric     case OO_EqualEqual:
1285ffd83dbSDimitry Andric     case OO_ExclaimEqual:
1295ffd83dbSDimitry Andric     case OO_Greater:
1305ffd83dbSDimitry Andric     case OO_GreaterEqual:
1315ffd83dbSDimitry Andric     case OO_Less:
1325ffd83dbSDimitry Andric     case OO_LessEqual:
1335ffd83dbSDimitry Andric     case OO_Spaceship:
1345ffd83dbSDimitry Andric       return true;
1355ffd83dbSDimitry Andric     default:
1365ffd83dbSDimitry Andric       return false;
1375ffd83dbSDimitry Andric     }
1385ffd83dbSDimitry Andric   }
isComparisonOp()1395ffd83dbSDimitry Andric   bool isComparisonOp() const { return isComparisonOp(getOperator()); }
1405ffd83dbSDimitry Andric 
1410b57cec5SDimitry Andric   /// Is this written as an infix binary operator?
1420b57cec5SDimitry Andric   bool isInfixBinaryOp() const;
1430b57cec5SDimitry Andric 
1440b57cec5SDimitry Andric   /// Returns the location of the operator symbol in the expression.
1450b57cec5SDimitry Andric   ///
1460b57cec5SDimitry Andric   /// When \c getOperator()==OO_Call, this is the location of the right
1470b57cec5SDimitry Andric   /// parentheses; when \c getOperator()==OO_Subscript, this is the location
1480b57cec5SDimitry Andric   /// of the right bracket.
getOperatorLoc()1490b57cec5SDimitry Andric   SourceLocation getOperatorLoc() const { return getRParenLoc(); }
1500b57cec5SDimitry Andric 
getExprLoc()1510b57cec5SDimitry Andric   SourceLocation getExprLoc() const LLVM_READONLY {
1520b57cec5SDimitry Andric     OverloadedOperatorKind Operator = getOperator();
1530b57cec5SDimitry Andric     return (Operator < OO_Plus || Operator >= OO_Arrow ||
1540b57cec5SDimitry Andric             Operator == OO_PlusPlus || Operator == OO_MinusMinus)
1550b57cec5SDimitry Andric                ? getBeginLoc()
1560b57cec5SDimitry Andric                : getOperatorLoc();
1570b57cec5SDimitry Andric   }
1580b57cec5SDimitry Andric 
getBeginLoc()1590b57cec5SDimitry Andric   SourceLocation getBeginLoc() const { return Range.getBegin(); }
getEndLoc()1600b57cec5SDimitry Andric   SourceLocation getEndLoc() const { return Range.getEnd(); }
getSourceRange()1610b57cec5SDimitry Andric   SourceRange getSourceRange() const { return Range; }
1620b57cec5SDimitry Andric 
classof(const Stmt * T)1630b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
1640b57cec5SDimitry Andric     return T->getStmtClass() == CXXOperatorCallExprClass;
1650b57cec5SDimitry Andric   }
1660b57cec5SDimitry Andric };
1670b57cec5SDimitry Andric 
1680b57cec5SDimitry Andric /// Represents a call to a member function that
1690b57cec5SDimitry Andric /// may be written either with member call syntax (e.g., "obj.func()"
1700b57cec5SDimitry Andric /// or "objptr->func()") or with normal function-call syntax
1710b57cec5SDimitry Andric /// ("func()") within a member function that ends up calling a member
1720b57cec5SDimitry Andric /// function. The callee in either case is a MemberExpr that contains
1730b57cec5SDimitry Andric /// both the object argument and the member function, while the
1740b57cec5SDimitry Andric /// arguments are the arguments within the parentheses (not including
1750b57cec5SDimitry Andric /// the object argument).
1760b57cec5SDimitry Andric class CXXMemberCallExpr final : public CallExpr {
1770b57cec5SDimitry Andric   // CXXMemberCallExpr has some trailing objects belonging
1780b57cec5SDimitry Andric   // to CallExpr. See CallExpr for the details.
1790b57cec5SDimitry Andric 
1800b57cec5SDimitry Andric   CXXMemberCallExpr(Expr *Fn, ArrayRef<Expr *> Args, QualType Ty,
181e8d8bef9SDimitry Andric                     ExprValueKind VK, SourceLocation RP,
182e8d8bef9SDimitry Andric                     FPOptionsOverride FPOptions, unsigned MinNumArgs);
1830b57cec5SDimitry Andric 
184e8d8bef9SDimitry Andric   CXXMemberCallExpr(unsigned NumArgs, bool HasFPFeatures, EmptyShell Empty);
1850b57cec5SDimitry Andric 
1860b57cec5SDimitry Andric public:
1870b57cec5SDimitry Andric   static CXXMemberCallExpr *Create(const ASTContext &Ctx, Expr *Fn,
1880b57cec5SDimitry Andric                                    ArrayRef<Expr *> Args, QualType Ty,
1890b57cec5SDimitry Andric                                    ExprValueKind VK, SourceLocation RP,
190e8d8bef9SDimitry Andric                                    FPOptionsOverride FPFeatures,
1910b57cec5SDimitry Andric                                    unsigned MinNumArgs = 0);
1920b57cec5SDimitry Andric 
1930b57cec5SDimitry Andric   static CXXMemberCallExpr *CreateEmpty(const ASTContext &Ctx, unsigned NumArgs,
194e8d8bef9SDimitry Andric                                         bool HasFPFeatures, EmptyShell Empty);
1950b57cec5SDimitry Andric 
1960b57cec5SDimitry Andric   /// Retrieve the implicit object argument for the member call.
1970b57cec5SDimitry Andric   ///
1980b57cec5SDimitry Andric   /// For example, in "x.f(5)", this returns the sub-expression "x".
1990b57cec5SDimitry Andric   Expr *getImplicitObjectArgument() const;
2000b57cec5SDimitry Andric 
2010b57cec5SDimitry Andric   /// Retrieve the type of the object argument.
2020b57cec5SDimitry Andric   ///
2030b57cec5SDimitry Andric   /// Note that this always returns a non-pointer type.
2040b57cec5SDimitry Andric   QualType getObjectType() const;
2050b57cec5SDimitry Andric 
2060b57cec5SDimitry Andric   /// Retrieve the declaration of the called method.
2070b57cec5SDimitry Andric   CXXMethodDecl *getMethodDecl() const;
2080b57cec5SDimitry Andric 
2090b57cec5SDimitry Andric   /// Retrieve the CXXRecordDecl for the underlying type of
2100b57cec5SDimitry Andric   /// the implicit object argument.
2110b57cec5SDimitry Andric   ///
2120b57cec5SDimitry Andric   /// Note that this is may not be the same declaration as that of the class
2130b57cec5SDimitry Andric   /// context of the CXXMethodDecl which this function is calling.
2140b57cec5SDimitry Andric   /// FIXME: Returns 0 for member pointer call exprs.
2150b57cec5SDimitry Andric   CXXRecordDecl *getRecordDecl() const;
2160b57cec5SDimitry Andric 
getExprLoc()2170b57cec5SDimitry Andric   SourceLocation getExprLoc() const LLVM_READONLY {
2180b57cec5SDimitry Andric     SourceLocation CLoc = getCallee()->getExprLoc();
2190b57cec5SDimitry Andric     if (CLoc.isValid())
2200b57cec5SDimitry Andric       return CLoc;
2210b57cec5SDimitry Andric 
2220b57cec5SDimitry Andric     return getBeginLoc();
2230b57cec5SDimitry Andric   }
2240b57cec5SDimitry Andric 
classof(const Stmt * T)2250b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
2260b57cec5SDimitry Andric     return T->getStmtClass() == CXXMemberCallExprClass;
2270b57cec5SDimitry Andric   }
2280b57cec5SDimitry Andric };
2290b57cec5SDimitry Andric 
2300b57cec5SDimitry Andric /// Represents a call to a CUDA kernel function.
2310b57cec5SDimitry Andric class CUDAKernelCallExpr final : public CallExpr {
2320b57cec5SDimitry Andric   friend class ASTStmtReader;
2330b57cec5SDimitry Andric 
2340b57cec5SDimitry Andric   enum { CONFIG, END_PREARG };
2350b57cec5SDimitry Andric 
2360b57cec5SDimitry Andric   // CUDAKernelCallExpr has some trailing objects belonging
2370b57cec5SDimitry Andric   // to CallExpr. See CallExpr for the details.
2380b57cec5SDimitry Andric 
2390b57cec5SDimitry Andric   CUDAKernelCallExpr(Expr *Fn, CallExpr *Config, ArrayRef<Expr *> Args,
2400b57cec5SDimitry Andric                      QualType Ty, ExprValueKind VK, SourceLocation RP,
241e8d8bef9SDimitry Andric                      FPOptionsOverride FPFeatures, unsigned MinNumArgs);
2420b57cec5SDimitry Andric 
243e8d8bef9SDimitry Andric   CUDAKernelCallExpr(unsigned NumArgs, bool HasFPFeatures, EmptyShell Empty);
2440b57cec5SDimitry Andric 
2450b57cec5SDimitry Andric public:
2460b57cec5SDimitry Andric   static CUDAKernelCallExpr *Create(const ASTContext &Ctx, Expr *Fn,
2470b57cec5SDimitry Andric                                     CallExpr *Config, ArrayRef<Expr *> Args,
2480b57cec5SDimitry Andric                                     QualType Ty, ExprValueKind VK,
249e8d8bef9SDimitry Andric                                     SourceLocation RP,
250e8d8bef9SDimitry Andric                                     FPOptionsOverride FPFeatures,
251e8d8bef9SDimitry Andric                                     unsigned MinNumArgs = 0);
2520b57cec5SDimitry Andric 
2530b57cec5SDimitry Andric   static CUDAKernelCallExpr *CreateEmpty(const ASTContext &Ctx,
254e8d8bef9SDimitry Andric                                          unsigned NumArgs, bool HasFPFeatures,
255e8d8bef9SDimitry Andric                                          EmptyShell Empty);
2560b57cec5SDimitry Andric 
getConfig()2570b57cec5SDimitry Andric   const CallExpr *getConfig() const {
2580b57cec5SDimitry Andric     return cast_or_null<CallExpr>(getPreArg(CONFIG));
2590b57cec5SDimitry Andric   }
getConfig()2600b57cec5SDimitry Andric   CallExpr *getConfig() { return cast_or_null<CallExpr>(getPreArg(CONFIG)); }
2610b57cec5SDimitry Andric 
classof(const Stmt * T)2620b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
2630b57cec5SDimitry Andric     return T->getStmtClass() == CUDAKernelCallExprClass;
2640b57cec5SDimitry Andric   }
2650b57cec5SDimitry Andric };
2660b57cec5SDimitry Andric 
267a7dea167SDimitry Andric /// A rewritten comparison expression that was originally written using
268a7dea167SDimitry Andric /// operator syntax.
269a7dea167SDimitry Andric ///
270a7dea167SDimitry Andric /// In C++20, the following rewrites are performed:
271a7dea167SDimitry Andric /// - <tt>a == b</tt> -> <tt>b == a</tt>
272a7dea167SDimitry Andric /// - <tt>a != b</tt> -> <tt>!(a == b)</tt>
273a7dea167SDimitry Andric /// - <tt>a != b</tt> -> <tt>!(b == a)</tt>
274a7dea167SDimitry Andric /// - For \c \@ in \c <, \c <=, \c >, \c >=, \c <=>:
275a7dea167SDimitry Andric ///   - <tt>a @ b</tt> -> <tt>(a <=> b) @ 0</tt>
276a7dea167SDimitry Andric ///   - <tt>a @ b</tt> -> <tt>0 @ (b <=> a)</tt>
277a7dea167SDimitry Andric ///
278a7dea167SDimitry Andric /// This expression provides access to both the original syntax and the
279a7dea167SDimitry Andric /// rewritten expression.
280a7dea167SDimitry Andric ///
281a7dea167SDimitry Andric /// Note that the rewritten calls to \c ==, \c <=>, and \c \@ are typically
282a7dea167SDimitry Andric /// \c CXXOperatorCallExprs, but could theoretically be \c BinaryOperators.
283a7dea167SDimitry Andric class CXXRewrittenBinaryOperator : public Expr {
284a7dea167SDimitry Andric   friend class ASTStmtReader;
285a7dea167SDimitry Andric 
286a7dea167SDimitry Andric   /// The rewritten semantic form.
287a7dea167SDimitry Andric   Stmt *SemanticForm;
288a7dea167SDimitry Andric 
289a7dea167SDimitry Andric public:
CXXRewrittenBinaryOperator(Expr * SemanticForm,bool IsReversed)290a7dea167SDimitry Andric   CXXRewrittenBinaryOperator(Expr *SemanticForm, bool IsReversed)
291a7dea167SDimitry Andric       : Expr(CXXRewrittenBinaryOperatorClass, SemanticForm->getType(),
2925ffd83dbSDimitry Andric              SemanticForm->getValueKind(), SemanticForm->getObjectKind()),
293a7dea167SDimitry Andric         SemanticForm(SemanticForm) {
294a7dea167SDimitry Andric     CXXRewrittenBinaryOperatorBits.IsReversed = IsReversed;
2955ffd83dbSDimitry Andric     setDependence(computeDependence(this));
296a7dea167SDimitry Andric   }
CXXRewrittenBinaryOperator(EmptyShell Empty)297a7dea167SDimitry Andric   CXXRewrittenBinaryOperator(EmptyShell Empty)
298a7dea167SDimitry Andric       : Expr(CXXRewrittenBinaryOperatorClass, Empty), SemanticForm() {}
299a7dea167SDimitry Andric 
300a7dea167SDimitry Andric   /// Get an equivalent semantic form for this expression.
getSemanticForm()301a7dea167SDimitry Andric   Expr *getSemanticForm() { return cast<Expr>(SemanticForm); }
getSemanticForm()302a7dea167SDimitry Andric   const Expr *getSemanticForm() const { return cast<Expr>(SemanticForm); }
303a7dea167SDimitry Andric 
304a7dea167SDimitry Andric   struct DecomposedForm {
305a7dea167SDimitry Andric     /// The original opcode, prior to rewriting.
306a7dea167SDimitry Andric     BinaryOperatorKind Opcode;
307a7dea167SDimitry Andric     /// The original left-hand side.
308a7dea167SDimitry Andric     const Expr *LHS;
309a7dea167SDimitry Andric     /// The original right-hand side.
310a7dea167SDimitry Andric     const Expr *RHS;
311a7dea167SDimitry Andric     /// The inner \c == or \c <=> operator expression.
312a7dea167SDimitry Andric     const Expr *InnerBinOp;
313a7dea167SDimitry Andric   };
314a7dea167SDimitry Andric 
315a7dea167SDimitry Andric   /// Decompose this operator into its syntactic form.
316a7dea167SDimitry Andric   DecomposedForm getDecomposedForm() const LLVM_READONLY;
317a7dea167SDimitry Andric 
318a7dea167SDimitry Andric   /// Determine whether this expression was rewritten in reverse form.
isReversed()319a7dea167SDimitry Andric   bool isReversed() const { return CXXRewrittenBinaryOperatorBits.IsReversed; }
320a7dea167SDimitry Andric 
getOperator()321a7dea167SDimitry Andric   BinaryOperatorKind getOperator() const { return getDecomposedForm().Opcode; }
getOpcode()322e8d8bef9SDimitry Andric   BinaryOperatorKind getOpcode() const { return getOperator(); }
getOpcodeStr(BinaryOperatorKind Op)323e8d8bef9SDimitry Andric   static StringRef getOpcodeStr(BinaryOperatorKind Op) {
324e8d8bef9SDimitry Andric     return BinaryOperator::getOpcodeStr(Op);
325e8d8bef9SDimitry Andric   }
getOpcodeStr()326e8d8bef9SDimitry Andric   StringRef getOpcodeStr() const {
327e8d8bef9SDimitry Andric     return BinaryOperator::getOpcodeStr(getOpcode());
328e8d8bef9SDimitry Andric   }
isComparisonOp()329e8d8bef9SDimitry Andric   bool isComparisonOp() const { return true; }
isAssignmentOp()330e8d8bef9SDimitry Andric   bool isAssignmentOp() const { return false; }
331e8d8bef9SDimitry Andric 
getLHS()332a7dea167SDimitry Andric   const Expr *getLHS() const { return getDecomposedForm().LHS; }
getRHS()333a7dea167SDimitry Andric   const Expr *getRHS() const { return getDecomposedForm().RHS; }
334a7dea167SDimitry Andric 
getOperatorLoc()335a7dea167SDimitry Andric   SourceLocation getOperatorLoc() const LLVM_READONLY {
336a7dea167SDimitry Andric     return getDecomposedForm().InnerBinOp->getExprLoc();
337a7dea167SDimitry Andric   }
getExprLoc()338a7dea167SDimitry Andric   SourceLocation getExprLoc() const LLVM_READONLY { return getOperatorLoc(); }
339a7dea167SDimitry Andric 
340a7dea167SDimitry Andric   /// Compute the begin and end locations from the decomposed form.
341a7dea167SDimitry Andric   /// The locations of the semantic form are not reliable if this is
342a7dea167SDimitry Andric   /// a reversed expression.
343a7dea167SDimitry Andric   //@{
getBeginLoc()344a7dea167SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY {
345a7dea167SDimitry Andric     return getDecomposedForm().LHS->getBeginLoc();
346a7dea167SDimitry Andric   }
getEndLoc()347a7dea167SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY {
348a7dea167SDimitry Andric     return getDecomposedForm().RHS->getEndLoc();
349a7dea167SDimitry Andric   }
getSourceRange()350a7dea167SDimitry Andric   SourceRange getSourceRange() const LLVM_READONLY {
351a7dea167SDimitry Andric     DecomposedForm DF = getDecomposedForm();
352a7dea167SDimitry Andric     return SourceRange(DF.LHS->getBeginLoc(), DF.RHS->getEndLoc());
353a7dea167SDimitry Andric   }
354a7dea167SDimitry Andric   //@}
355a7dea167SDimitry Andric 
children()356a7dea167SDimitry Andric   child_range children() {
357a7dea167SDimitry Andric     return child_range(&SemanticForm, &SemanticForm + 1);
358a7dea167SDimitry Andric   }
359a7dea167SDimitry Andric 
classof(const Stmt * T)360a7dea167SDimitry Andric   static bool classof(const Stmt *T) {
361a7dea167SDimitry Andric     return T->getStmtClass() == CXXRewrittenBinaryOperatorClass;
362a7dea167SDimitry Andric   }
363a7dea167SDimitry Andric };
364a7dea167SDimitry Andric 
3650b57cec5SDimitry Andric /// Abstract class common to all of the C++ "named"/"keyword" casts.
3660b57cec5SDimitry Andric ///
3670b57cec5SDimitry Andric /// This abstract class is inherited by all of the classes
3680b57cec5SDimitry Andric /// representing "named" casts: CXXStaticCastExpr for \c static_cast,
3690b57cec5SDimitry Andric /// CXXDynamicCastExpr for \c dynamic_cast, CXXReinterpretCastExpr for
3705ffd83dbSDimitry Andric /// reinterpret_cast, CXXConstCastExpr for \c const_cast and
3715ffd83dbSDimitry Andric /// CXXAddrspaceCastExpr for addrspace_cast (in OpenCL).
3720b57cec5SDimitry Andric class CXXNamedCastExpr : public ExplicitCastExpr {
3730b57cec5SDimitry Andric private:
3740b57cec5SDimitry Andric   // the location of the casting op
3750b57cec5SDimitry Andric   SourceLocation Loc;
3760b57cec5SDimitry Andric 
3770b57cec5SDimitry Andric   // the location of the right parenthesis
3780b57cec5SDimitry Andric   SourceLocation RParenLoc;
3790b57cec5SDimitry Andric 
3800b57cec5SDimitry Andric   // range for '<' '>'
3810b57cec5SDimitry Andric   SourceRange AngleBrackets;
3820b57cec5SDimitry Andric 
3830b57cec5SDimitry Andric protected:
3840b57cec5SDimitry Andric   friend class ASTStmtReader;
3850b57cec5SDimitry Andric 
CXXNamedCastExpr(StmtClass SC,QualType ty,ExprValueKind VK,CastKind kind,Expr * op,unsigned PathSize,bool HasFPFeatures,TypeSourceInfo * writtenTy,SourceLocation l,SourceLocation RParenLoc,SourceRange AngleBrackets)386e8d8bef9SDimitry Andric   CXXNamedCastExpr(StmtClass SC, QualType ty, ExprValueKind VK, CastKind kind,
387e8d8bef9SDimitry Andric                    Expr *op, unsigned PathSize, bool HasFPFeatures,
3880b57cec5SDimitry Andric                    TypeSourceInfo *writtenTy, SourceLocation l,
389e8d8bef9SDimitry Andric                    SourceLocation RParenLoc, SourceRange AngleBrackets)
390e8d8bef9SDimitry Andric       : ExplicitCastExpr(SC, ty, VK, kind, op, PathSize, HasFPFeatures,
391e8d8bef9SDimitry Andric                          writtenTy),
392e8d8bef9SDimitry Andric         Loc(l), RParenLoc(RParenLoc), AngleBrackets(AngleBrackets) {}
3930b57cec5SDimitry Andric 
CXXNamedCastExpr(StmtClass SC,EmptyShell Shell,unsigned PathSize,bool HasFPFeatures)394e8d8bef9SDimitry Andric   explicit CXXNamedCastExpr(StmtClass SC, EmptyShell Shell, unsigned PathSize,
395e8d8bef9SDimitry Andric                             bool HasFPFeatures)
396e8d8bef9SDimitry Andric       : ExplicitCastExpr(SC, Shell, PathSize, HasFPFeatures) {}
3970b57cec5SDimitry Andric 
3980b57cec5SDimitry Andric public:
3990b57cec5SDimitry Andric   const char *getCastName() const;
4000b57cec5SDimitry Andric 
4010b57cec5SDimitry Andric   /// Retrieve the location of the cast operator keyword, e.g.,
4020b57cec5SDimitry Andric   /// \c static_cast.
getOperatorLoc()4030b57cec5SDimitry Andric   SourceLocation getOperatorLoc() const { return Loc; }
4040b57cec5SDimitry Andric 
4050b57cec5SDimitry Andric   /// Retrieve the location of the closing parenthesis.
getRParenLoc()4060b57cec5SDimitry Andric   SourceLocation getRParenLoc() const { return RParenLoc; }
4070b57cec5SDimitry Andric 
getBeginLoc()4080b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; }
getEndLoc()4090b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
getAngleBrackets()4100b57cec5SDimitry Andric   SourceRange getAngleBrackets() const LLVM_READONLY { return AngleBrackets; }
4110b57cec5SDimitry Andric 
classof(const Stmt * T)4120b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
4130b57cec5SDimitry Andric     switch (T->getStmtClass()) {
4140b57cec5SDimitry Andric     case CXXStaticCastExprClass:
4150b57cec5SDimitry Andric     case CXXDynamicCastExprClass:
4160b57cec5SDimitry Andric     case CXXReinterpretCastExprClass:
4170b57cec5SDimitry Andric     case CXXConstCastExprClass:
4185ffd83dbSDimitry Andric     case CXXAddrspaceCastExprClass:
4190b57cec5SDimitry Andric       return true;
4200b57cec5SDimitry Andric     default:
4210b57cec5SDimitry Andric       return false;
4220b57cec5SDimitry Andric     }
4230b57cec5SDimitry Andric   }
4240b57cec5SDimitry Andric };
4250b57cec5SDimitry Andric 
4260b57cec5SDimitry Andric /// A C++ \c static_cast expression (C++ [expr.static.cast]).
4270b57cec5SDimitry Andric ///
4280b57cec5SDimitry Andric /// This expression node represents a C++ static cast, e.g.,
4290b57cec5SDimitry Andric /// \c static_cast<int>(1.0).
4300b57cec5SDimitry Andric class CXXStaticCastExpr final
4310b57cec5SDimitry Andric     : public CXXNamedCastExpr,
432e8d8bef9SDimitry Andric       private llvm::TrailingObjects<CXXStaticCastExpr, CXXBaseSpecifier *,
433e8d8bef9SDimitry Andric                                     FPOptionsOverride> {
CXXStaticCastExpr(QualType ty,ExprValueKind vk,CastKind kind,Expr * op,unsigned pathSize,TypeSourceInfo * writtenTy,FPOptionsOverride FPO,SourceLocation l,SourceLocation RParenLoc,SourceRange AngleBrackets)4340b57cec5SDimitry Andric   CXXStaticCastExpr(QualType ty, ExprValueKind vk, CastKind kind, Expr *op,
4350b57cec5SDimitry Andric                     unsigned pathSize, TypeSourceInfo *writtenTy,
436e8d8bef9SDimitry Andric                     FPOptionsOverride FPO, SourceLocation l,
437e8d8bef9SDimitry Andric                     SourceLocation RParenLoc, SourceRange AngleBrackets)
4380b57cec5SDimitry Andric       : CXXNamedCastExpr(CXXStaticCastExprClass, ty, vk, kind, op, pathSize,
439e8d8bef9SDimitry Andric                          FPO.requiresTrailingStorage(), writtenTy, l, RParenLoc,
440e8d8bef9SDimitry Andric                          AngleBrackets) {
441e8d8bef9SDimitry Andric     if (hasStoredFPFeatures())
442e8d8bef9SDimitry Andric       *getTrailingFPFeatures() = FPO;
443e8d8bef9SDimitry Andric   }
4440b57cec5SDimitry Andric 
CXXStaticCastExpr(EmptyShell Empty,unsigned PathSize,bool HasFPFeatures)445e8d8bef9SDimitry Andric   explicit CXXStaticCastExpr(EmptyShell Empty, unsigned PathSize,
446e8d8bef9SDimitry Andric                              bool HasFPFeatures)
447e8d8bef9SDimitry Andric       : CXXNamedCastExpr(CXXStaticCastExprClass, Empty, PathSize,
448e8d8bef9SDimitry Andric                          HasFPFeatures) {}
449e8d8bef9SDimitry Andric 
numTrailingObjects(OverloadToken<CXXBaseSpecifier * >)450e8d8bef9SDimitry Andric   unsigned numTrailingObjects(OverloadToken<CXXBaseSpecifier *>) const {
451e8d8bef9SDimitry Andric     return path_size();
452e8d8bef9SDimitry Andric   }
4530b57cec5SDimitry Andric 
4540b57cec5SDimitry Andric public:
4550b57cec5SDimitry Andric   friend class CastExpr;
4560b57cec5SDimitry Andric   friend TrailingObjects;
4570b57cec5SDimitry Andric 
458e8d8bef9SDimitry Andric   static CXXStaticCastExpr *
459e8d8bef9SDimitry Andric   Create(const ASTContext &Context, QualType T, ExprValueKind VK, CastKind K,
460e8d8bef9SDimitry Andric          Expr *Op, const CXXCastPath *Path, TypeSourceInfo *Written,
461e8d8bef9SDimitry Andric          FPOptionsOverride FPO, SourceLocation L, SourceLocation RParenLoc,
4620b57cec5SDimitry Andric          SourceRange AngleBrackets);
4630b57cec5SDimitry Andric   static CXXStaticCastExpr *CreateEmpty(const ASTContext &Context,
464e8d8bef9SDimitry Andric                                         unsigned PathSize, bool hasFPFeatures);
4650b57cec5SDimitry Andric 
classof(const Stmt * T)4660b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
4670b57cec5SDimitry Andric     return T->getStmtClass() == CXXStaticCastExprClass;
4680b57cec5SDimitry Andric   }
4690b57cec5SDimitry Andric };
4700b57cec5SDimitry Andric 
4710b57cec5SDimitry Andric /// A C++ @c dynamic_cast expression (C++ [expr.dynamic.cast]).
4720b57cec5SDimitry Andric ///
4730b57cec5SDimitry Andric /// This expression node represents a dynamic cast, e.g.,
4740b57cec5SDimitry Andric /// \c dynamic_cast<Derived*>(BasePtr). Such a cast may perform a run-time
4750b57cec5SDimitry Andric /// check to determine how to perform the type conversion.
4760b57cec5SDimitry Andric class CXXDynamicCastExpr final
4770b57cec5SDimitry Andric     : public CXXNamedCastExpr,
4780b57cec5SDimitry Andric       private llvm::TrailingObjects<CXXDynamicCastExpr, CXXBaseSpecifier *> {
CXXDynamicCastExpr(QualType ty,ExprValueKind VK,CastKind kind,Expr * op,unsigned pathSize,TypeSourceInfo * writtenTy,SourceLocation l,SourceLocation RParenLoc,SourceRange AngleBrackets)479e8d8bef9SDimitry Andric   CXXDynamicCastExpr(QualType ty, ExprValueKind VK, CastKind kind, Expr *op,
480e8d8bef9SDimitry Andric                      unsigned pathSize, TypeSourceInfo *writtenTy,
4810b57cec5SDimitry Andric                      SourceLocation l, SourceLocation RParenLoc,
4820b57cec5SDimitry Andric                      SourceRange AngleBrackets)
4830b57cec5SDimitry Andric       : CXXNamedCastExpr(CXXDynamicCastExprClass, ty, VK, kind, op, pathSize,
484e8d8bef9SDimitry Andric                          /*HasFPFeatures*/ false, writtenTy, l, RParenLoc,
485e8d8bef9SDimitry Andric                          AngleBrackets) {}
4860b57cec5SDimitry Andric 
CXXDynamicCastExpr(EmptyShell Empty,unsigned pathSize)4870b57cec5SDimitry Andric   explicit CXXDynamicCastExpr(EmptyShell Empty, unsigned pathSize)
488e8d8bef9SDimitry Andric       : CXXNamedCastExpr(CXXDynamicCastExprClass, Empty, pathSize,
489e8d8bef9SDimitry Andric                          /*HasFPFeatures*/ false) {}
4900b57cec5SDimitry Andric 
4910b57cec5SDimitry Andric public:
4920b57cec5SDimitry Andric   friend class CastExpr;
4930b57cec5SDimitry Andric   friend TrailingObjects;
4940b57cec5SDimitry Andric 
4950b57cec5SDimitry Andric   static CXXDynamicCastExpr *Create(const ASTContext &Context, QualType T,
4960b57cec5SDimitry Andric                                     ExprValueKind VK, CastKind Kind, Expr *Op,
4970b57cec5SDimitry Andric                                     const CXXCastPath *Path,
4980b57cec5SDimitry Andric                                     TypeSourceInfo *Written, SourceLocation L,
4990b57cec5SDimitry Andric                                     SourceLocation RParenLoc,
5000b57cec5SDimitry Andric                                     SourceRange AngleBrackets);
5010b57cec5SDimitry Andric 
5020b57cec5SDimitry Andric   static CXXDynamicCastExpr *CreateEmpty(const ASTContext &Context,
5030b57cec5SDimitry Andric                                          unsigned pathSize);
5040b57cec5SDimitry Andric 
5050b57cec5SDimitry Andric   bool isAlwaysNull() const;
5060b57cec5SDimitry Andric 
classof(const Stmt * T)5070b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
5080b57cec5SDimitry Andric     return T->getStmtClass() == CXXDynamicCastExprClass;
5090b57cec5SDimitry Andric   }
5100b57cec5SDimitry Andric };
5110b57cec5SDimitry Andric 
5120b57cec5SDimitry Andric /// A C++ @c reinterpret_cast expression (C++ [expr.reinterpret.cast]).
5130b57cec5SDimitry Andric ///
5140b57cec5SDimitry Andric /// This expression node represents a reinterpret cast, e.g.,
5150b57cec5SDimitry Andric /// @c reinterpret_cast<int>(VoidPtr).
5160b57cec5SDimitry Andric ///
5170b57cec5SDimitry Andric /// A reinterpret_cast provides a differently-typed view of a value but
5180b57cec5SDimitry Andric /// (in Clang, as in most C++ implementations) performs no actual work at
5190b57cec5SDimitry Andric /// run time.
5200b57cec5SDimitry Andric class CXXReinterpretCastExpr final
5210b57cec5SDimitry Andric     : public CXXNamedCastExpr,
5220b57cec5SDimitry Andric       private llvm::TrailingObjects<CXXReinterpretCastExpr,
5230b57cec5SDimitry Andric                                     CXXBaseSpecifier *> {
CXXReinterpretCastExpr(QualType ty,ExprValueKind vk,CastKind kind,Expr * op,unsigned pathSize,TypeSourceInfo * writtenTy,SourceLocation l,SourceLocation RParenLoc,SourceRange AngleBrackets)524e8d8bef9SDimitry Andric   CXXReinterpretCastExpr(QualType ty, ExprValueKind vk, CastKind kind, Expr *op,
525e8d8bef9SDimitry Andric                          unsigned pathSize, TypeSourceInfo *writtenTy,
526e8d8bef9SDimitry Andric                          SourceLocation l, SourceLocation RParenLoc,
5270b57cec5SDimitry Andric                          SourceRange AngleBrackets)
5280b57cec5SDimitry Andric       : CXXNamedCastExpr(CXXReinterpretCastExprClass, ty, vk, kind, op,
529e8d8bef9SDimitry Andric                          pathSize, /*HasFPFeatures*/ false, writtenTy, l,
530e8d8bef9SDimitry Andric                          RParenLoc, AngleBrackets) {}
5310b57cec5SDimitry Andric 
CXXReinterpretCastExpr(EmptyShell Empty,unsigned pathSize)5320b57cec5SDimitry Andric   CXXReinterpretCastExpr(EmptyShell Empty, unsigned pathSize)
533e8d8bef9SDimitry Andric       : CXXNamedCastExpr(CXXReinterpretCastExprClass, Empty, pathSize,
534e8d8bef9SDimitry Andric                          /*HasFPFeatures*/ false) {}
5350b57cec5SDimitry Andric 
5360b57cec5SDimitry Andric public:
5370b57cec5SDimitry Andric   friend class CastExpr;
5380b57cec5SDimitry Andric   friend TrailingObjects;
5390b57cec5SDimitry Andric 
5400b57cec5SDimitry Andric   static CXXReinterpretCastExpr *Create(const ASTContext &Context, QualType T,
5410b57cec5SDimitry Andric                                         ExprValueKind VK, CastKind Kind,
5420b57cec5SDimitry Andric                                         Expr *Op, const CXXCastPath *Path,
5430b57cec5SDimitry Andric                                  TypeSourceInfo *WrittenTy, SourceLocation L,
5440b57cec5SDimitry Andric                                         SourceLocation RParenLoc,
5450b57cec5SDimitry Andric                                         SourceRange AngleBrackets);
5460b57cec5SDimitry Andric   static CXXReinterpretCastExpr *CreateEmpty(const ASTContext &Context,
5470b57cec5SDimitry Andric                                              unsigned pathSize);
5480b57cec5SDimitry Andric 
classof(const Stmt * T)5490b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
5500b57cec5SDimitry Andric     return T->getStmtClass() == CXXReinterpretCastExprClass;
5510b57cec5SDimitry Andric   }
5520b57cec5SDimitry Andric };
5530b57cec5SDimitry Andric 
5540b57cec5SDimitry Andric /// A C++ \c const_cast expression (C++ [expr.const.cast]).
5550b57cec5SDimitry Andric ///
5560b57cec5SDimitry Andric /// This expression node represents a const cast, e.g.,
5570b57cec5SDimitry Andric /// \c const_cast<char*>(PtrToConstChar).
5580b57cec5SDimitry Andric ///
5590b57cec5SDimitry Andric /// A const_cast can remove type qualifiers but does not change the underlying
5600b57cec5SDimitry Andric /// value.
5610b57cec5SDimitry Andric class CXXConstCastExpr final
5620b57cec5SDimitry Andric     : public CXXNamedCastExpr,
5630b57cec5SDimitry Andric       private llvm::TrailingObjects<CXXConstCastExpr, CXXBaseSpecifier *> {
CXXConstCastExpr(QualType ty,ExprValueKind VK,Expr * op,TypeSourceInfo * writtenTy,SourceLocation l,SourceLocation RParenLoc,SourceRange AngleBrackets)5640b57cec5SDimitry Andric   CXXConstCastExpr(QualType ty, ExprValueKind VK, Expr *op,
5650b57cec5SDimitry Andric                    TypeSourceInfo *writtenTy, SourceLocation l,
5660b57cec5SDimitry Andric                    SourceLocation RParenLoc, SourceRange AngleBrackets)
567e8d8bef9SDimitry Andric       : CXXNamedCastExpr(CXXConstCastExprClass, ty, VK, CK_NoOp, op, 0,
568e8d8bef9SDimitry Andric                          /*HasFPFeatures*/ false, writtenTy, l, RParenLoc,
569e8d8bef9SDimitry Andric                          AngleBrackets) {}
5700b57cec5SDimitry Andric 
CXXConstCastExpr(EmptyShell Empty)5710b57cec5SDimitry Andric   explicit CXXConstCastExpr(EmptyShell Empty)
572e8d8bef9SDimitry Andric       : CXXNamedCastExpr(CXXConstCastExprClass, Empty, 0,
573e8d8bef9SDimitry Andric                          /*HasFPFeatures*/ false) {}
5740b57cec5SDimitry Andric 
5750b57cec5SDimitry Andric public:
5760b57cec5SDimitry Andric   friend class CastExpr;
5770b57cec5SDimitry Andric   friend TrailingObjects;
5780b57cec5SDimitry Andric 
5790b57cec5SDimitry Andric   static CXXConstCastExpr *Create(const ASTContext &Context, QualType T,
5800b57cec5SDimitry Andric                                   ExprValueKind VK, Expr *Op,
5810b57cec5SDimitry Andric                                   TypeSourceInfo *WrittenTy, SourceLocation L,
5820b57cec5SDimitry Andric                                   SourceLocation RParenLoc,
5830b57cec5SDimitry Andric                                   SourceRange AngleBrackets);
5840b57cec5SDimitry Andric   static CXXConstCastExpr *CreateEmpty(const ASTContext &Context);
5850b57cec5SDimitry Andric 
classof(const Stmt * T)5860b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
5870b57cec5SDimitry Andric     return T->getStmtClass() == CXXConstCastExprClass;
5880b57cec5SDimitry Andric   }
5890b57cec5SDimitry Andric };
5900b57cec5SDimitry Andric 
5915ffd83dbSDimitry Andric /// A C++ addrspace_cast expression (currently only enabled for OpenCL).
5925ffd83dbSDimitry Andric ///
5935ffd83dbSDimitry Andric /// This expression node represents a cast between pointers to objects in
5945ffd83dbSDimitry Andric /// different address spaces e.g.,
5955ffd83dbSDimitry Andric /// \c addrspace_cast<global int*>(PtrToGenericInt).
5965ffd83dbSDimitry Andric ///
5975ffd83dbSDimitry Andric /// A addrspace_cast can cast address space type qualifiers but does not change
5985ffd83dbSDimitry Andric /// the underlying value.
5995ffd83dbSDimitry Andric class CXXAddrspaceCastExpr final
6005ffd83dbSDimitry Andric     : public CXXNamedCastExpr,
6015ffd83dbSDimitry Andric       private llvm::TrailingObjects<CXXAddrspaceCastExpr, CXXBaseSpecifier *> {
CXXAddrspaceCastExpr(QualType ty,ExprValueKind VK,CastKind Kind,Expr * op,TypeSourceInfo * writtenTy,SourceLocation l,SourceLocation RParenLoc,SourceRange AngleBrackets)6025ffd83dbSDimitry Andric   CXXAddrspaceCastExpr(QualType ty, ExprValueKind VK, CastKind Kind, Expr *op,
6035ffd83dbSDimitry Andric                        TypeSourceInfo *writtenTy, SourceLocation l,
6045ffd83dbSDimitry Andric                        SourceLocation RParenLoc, SourceRange AngleBrackets)
6055ffd83dbSDimitry Andric       : CXXNamedCastExpr(CXXAddrspaceCastExprClass, ty, VK, Kind, op, 0,
606e8d8bef9SDimitry Andric                          /*HasFPFeatures*/ false, writtenTy, l, RParenLoc,
607e8d8bef9SDimitry Andric                          AngleBrackets) {}
6085ffd83dbSDimitry Andric 
CXXAddrspaceCastExpr(EmptyShell Empty)6095ffd83dbSDimitry Andric   explicit CXXAddrspaceCastExpr(EmptyShell Empty)
610e8d8bef9SDimitry Andric       : CXXNamedCastExpr(CXXAddrspaceCastExprClass, Empty, 0,
611e8d8bef9SDimitry Andric                          /*HasFPFeatures*/ false) {}
6125ffd83dbSDimitry Andric 
6135ffd83dbSDimitry Andric public:
6145ffd83dbSDimitry Andric   friend class CastExpr;
6155ffd83dbSDimitry Andric   friend TrailingObjects;
6165ffd83dbSDimitry Andric 
6175ffd83dbSDimitry Andric   static CXXAddrspaceCastExpr *
6185ffd83dbSDimitry Andric   Create(const ASTContext &Context, QualType T, ExprValueKind VK, CastKind Kind,
6195ffd83dbSDimitry Andric          Expr *Op, TypeSourceInfo *WrittenTy, SourceLocation L,
6205ffd83dbSDimitry Andric          SourceLocation RParenLoc, SourceRange AngleBrackets);
6215ffd83dbSDimitry Andric   static CXXAddrspaceCastExpr *CreateEmpty(const ASTContext &Context);
6225ffd83dbSDimitry Andric 
classof(const Stmt * T)6235ffd83dbSDimitry Andric   static bool classof(const Stmt *T) {
6245ffd83dbSDimitry Andric     return T->getStmtClass() == CXXAddrspaceCastExprClass;
6255ffd83dbSDimitry Andric   }
6265ffd83dbSDimitry Andric };
6275ffd83dbSDimitry Andric 
6280b57cec5SDimitry Andric /// A call to a literal operator (C++11 [over.literal])
6290b57cec5SDimitry Andric /// written as a user-defined literal (C++11 [lit.ext]).
6300b57cec5SDimitry Andric ///
6310b57cec5SDimitry Andric /// Represents a user-defined literal, e.g. "foo"_bar or 1.23_xyz. While this
6320b57cec5SDimitry Andric /// is semantically equivalent to a normal call, this AST node provides better
6330b57cec5SDimitry Andric /// information about the syntactic representation of the literal.
6340b57cec5SDimitry Andric ///
6350b57cec5SDimitry Andric /// Since literal operators are never found by ADL and can only be declared at
6360b57cec5SDimitry Andric /// namespace scope, a user-defined literal is never dependent.
6370b57cec5SDimitry Andric class UserDefinedLiteral final : public CallExpr {
6380b57cec5SDimitry Andric   friend class ASTStmtReader;
6390b57cec5SDimitry Andric   friend class ASTStmtWriter;
6400b57cec5SDimitry Andric 
6410b57cec5SDimitry Andric   /// The location of a ud-suffix within the literal.
6420b57cec5SDimitry Andric   SourceLocation UDSuffixLoc;
6430b57cec5SDimitry Andric 
6440b57cec5SDimitry Andric   // UserDefinedLiteral has some trailing objects belonging
6450b57cec5SDimitry Andric   // to CallExpr. See CallExpr for the details.
6460b57cec5SDimitry Andric 
6470b57cec5SDimitry Andric   UserDefinedLiteral(Expr *Fn, ArrayRef<Expr *> Args, QualType Ty,
6480b57cec5SDimitry Andric                      ExprValueKind VK, SourceLocation LitEndLoc,
649e8d8bef9SDimitry Andric                      SourceLocation SuffixLoc, FPOptionsOverride FPFeatures);
6500b57cec5SDimitry Andric 
651e8d8bef9SDimitry Andric   UserDefinedLiteral(unsigned NumArgs, bool HasFPFeatures, EmptyShell Empty);
6520b57cec5SDimitry Andric 
6530b57cec5SDimitry Andric public:
6540b57cec5SDimitry Andric   static UserDefinedLiteral *Create(const ASTContext &Ctx, Expr *Fn,
6550b57cec5SDimitry Andric                                     ArrayRef<Expr *> Args, QualType Ty,
6560b57cec5SDimitry Andric                                     ExprValueKind VK, SourceLocation LitEndLoc,
657e8d8bef9SDimitry Andric                                     SourceLocation SuffixLoc,
658e8d8bef9SDimitry Andric                                     FPOptionsOverride FPFeatures);
6590b57cec5SDimitry Andric 
6600b57cec5SDimitry Andric   static UserDefinedLiteral *CreateEmpty(const ASTContext &Ctx,
661e8d8bef9SDimitry Andric                                          unsigned NumArgs, bool HasFPOptions,
662e8d8bef9SDimitry Andric                                          EmptyShell Empty);
6630b57cec5SDimitry Andric 
6640b57cec5SDimitry Andric   /// The kind of literal operator which is invoked.
6650b57cec5SDimitry Andric   enum LiteralOperatorKind {
6660b57cec5SDimitry Andric     /// Raw form: operator "" X (const char *)
6670b57cec5SDimitry Andric     LOK_Raw,
6680b57cec5SDimitry Andric 
6690b57cec5SDimitry Andric     /// Raw form: operator "" X<cs...> ()
6700b57cec5SDimitry Andric     LOK_Template,
6710b57cec5SDimitry Andric 
6720b57cec5SDimitry Andric     /// operator "" X (unsigned long long)
6730b57cec5SDimitry Andric     LOK_Integer,
6740b57cec5SDimitry Andric 
6750b57cec5SDimitry Andric     /// operator "" X (long double)
6760b57cec5SDimitry Andric     LOK_Floating,
6770b57cec5SDimitry Andric 
6780b57cec5SDimitry Andric     /// operator "" X (const CharT *, size_t)
6790b57cec5SDimitry Andric     LOK_String,
6800b57cec5SDimitry Andric 
6810b57cec5SDimitry Andric     /// operator "" X (CharT)
6820b57cec5SDimitry Andric     LOK_Character
6830b57cec5SDimitry Andric   };
6840b57cec5SDimitry Andric 
6850b57cec5SDimitry Andric   /// Returns the kind of literal operator invocation
6860b57cec5SDimitry Andric   /// which this expression represents.
6870b57cec5SDimitry Andric   LiteralOperatorKind getLiteralOperatorKind() const;
6880b57cec5SDimitry Andric 
6890b57cec5SDimitry Andric   /// If this is not a raw user-defined literal, get the
6900b57cec5SDimitry Andric   /// underlying cooked literal (representing the literal with the suffix
6910b57cec5SDimitry Andric   /// removed).
6920b57cec5SDimitry Andric   Expr *getCookedLiteral();
getCookedLiteral()6930b57cec5SDimitry Andric   const Expr *getCookedLiteral() const {
6940b57cec5SDimitry Andric     return const_cast<UserDefinedLiteral*>(this)->getCookedLiteral();
6950b57cec5SDimitry Andric   }
6960b57cec5SDimitry Andric 
getBeginLoc()6970b57cec5SDimitry Andric   SourceLocation getBeginLoc() const {
6980b57cec5SDimitry Andric     if (getLiteralOperatorKind() == LOK_Template)
6990b57cec5SDimitry Andric       return getRParenLoc();
7000b57cec5SDimitry Andric     return getArg(0)->getBeginLoc();
7010b57cec5SDimitry Andric   }
7020b57cec5SDimitry Andric 
getEndLoc()7030b57cec5SDimitry Andric   SourceLocation getEndLoc() const { return getRParenLoc(); }
7040b57cec5SDimitry Andric 
7050b57cec5SDimitry Andric   /// Returns the location of a ud-suffix in the expression.
7060b57cec5SDimitry Andric   ///
7070b57cec5SDimitry Andric   /// For a string literal, there may be multiple identical suffixes. This
7080b57cec5SDimitry Andric   /// returns the first.
getUDSuffixLoc()7090b57cec5SDimitry Andric   SourceLocation getUDSuffixLoc() const { return UDSuffixLoc; }
7100b57cec5SDimitry Andric 
7110b57cec5SDimitry Andric   /// Returns the ud-suffix specified for this literal.
7120b57cec5SDimitry Andric   const IdentifierInfo *getUDSuffix() const;
7130b57cec5SDimitry Andric 
classof(const Stmt * S)7140b57cec5SDimitry Andric   static bool classof(const Stmt *S) {
7150b57cec5SDimitry Andric     return S->getStmtClass() == UserDefinedLiteralClass;
7160b57cec5SDimitry Andric   }
7170b57cec5SDimitry Andric };
7180b57cec5SDimitry Andric 
7190b57cec5SDimitry Andric /// A boolean literal, per ([C++ lex.bool] Boolean literals).
7200b57cec5SDimitry Andric class CXXBoolLiteralExpr : public Expr {
7210b57cec5SDimitry Andric public:
CXXBoolLiteralExpr(bool Val,QualType Ty,SourceLocation Loc)7220b57cec5SDimitry Andric   CXXBoolLiteralExpr(bool Val, QualType Ty, SourceLocation Loc)
723fe6060f1SDimitry Andric       : Expr(CXXBoolLiteralExprClass, Ty, VK_PRValue, OK_Ordinary) {
7240b57cec5SDimitry Andric     CXXBoolLiteralExprBits.Value = Val;
7250b57cec5SDimitry Andric     CXXBoolLiteralExprBits.Loc = Loc;
7265ffd83dbSDimitry Andric     setDependence(ExprDependence::None);
7270b57cec5SDimitry Andric   }
7280b57cec5SDimitry Andric 
CXXBoolLiteralExpr(EmptyShell Empty)7290b57cec5SDimitry Andric   explicit CXXBoolLiteralExpr(EmptyShell Empty)
7300b57cec5SDimitry Andric       : Expr(CXXBoolLiteralExprClass, Empty) {}
7310b57cec5SDimitry Andric 
Create(const ASTContext & C,bool Val,QualType Ty,SourceLocation Loc)732bdd1243dSDimitry Andric   static CXXBoolLiteralExpr *Create(const ASTContext &C, bool Val, QualType Ty,
733bdd1243dSDimitry Andric                                     SourceLocation Loc) {
734bdd1243dSDimitry Andric     return new (C) CXXBoolLiteralExpr(Val, Ty, Loc);
735bdd1243dSDimitry Andric   }
736bdd1243dSDimitry Andric 
getValue()7370b57cec5SDimitry Andric   bool getValue() const { return CXXBoolLiteralExprBits.Value; }
setValue(bool V)7380b57cec5SDimitry Andric   void setValue(bool V) { CXXBoolLiteralExprBits.Value = V; }
7390b57cec5SDimitry Andric 
getBeginLoc()7400b57cec5SDimitry Andric   SourceLocation getBeginLoc() const { return getLocation(); }
getEndLoc()7410b57cec5SDimitry Andric   SourceLocation getEndLoc() const { return getLocation(); }
7420b57cec5SDimitry Andric 
getLocation()7430b57cec5SDimitry Andric   SourceLocation getLocation() const { return CXXBoolLiteralExprBits.Loc; }
setLocation(SourceLocation L)7440b57cec5SDimitry Andric   void setLocation(SourceLocation L) { CXXBoolLiteralExprBits.Loc = L; }
7450b57cec5SDimitry Andric 
classof(const Stmt * T)7460b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
7470b57cec5SDimitry Andric     return T->getStmtClass() == CXXBoolLiteralExprClass;
7480b57cec5SDimitry Andric   }
7490b57cec5SDimitry Andric 
7500b57cec5SDimitry Andric   // Iterators
children()7510b57cec5SDimitry Andric   child_range children() {
7520b57cec5SDimitry Andric     return child_range(child_iterator(), child_iterator());
7530b57cec5SDimitry Andric   }
7540b57cec5SDimitry Andric 
children()7550b57cec5SDimitry Andric   const_child_range children() const {
7560b57cec5SDimitry Andric     return const_child_range(const_child_iterator(), const_child_iterator());
7570b57cec5SDimitry Andric   }
7580b57cec5SDimitry Andric };
7590b57cec5SDimitry Andric 
7600b57cec5SDimitry Andric /// The null pointer literal (C++11 [lex.nullptr])
7610b57cec5SDimitry Andric ///
7620b57cec5SDimitry Andric /// Introduced in C++11, the only literal of type \c nullptr_t is \c nullptr.
7635f757f3fSDimitry Andric /// This also implements the null pointer literal in C23 (C23 6.4.1) which is
764bdd1243dSDimitry Andric /// intended to have the same semantics as the feature in C++.
7650b57cec5SDimitry Andric class CXXNullPtrLiteralExpr : public Expr {
7660b57cec5SDimitry Andric public:
CXXNullPtrLiteralExpr(QualType Ty,SourceLocation Loc)7670b57cec5SDimitry Andric   CXXNullPtrLiteralExpr(QualType Ty, SourceLocation Loc)
768fe6060f1SDimitry Andric       : Expr(CXXNullPtrLiteralExprClass, Ty, VK_PRValue, OK_Ordinary) {
7690b57cec5SDimitry Andric     CXXNullPtrLiteralExprBits.Loc = Loc;
7705ffd83dbSDimitry Andric     setDependence(ExprDependence::None);
7710b57cec5SDimitry Andric   }
7720b57cec5SDimitry Andric 
CXXNullPtrLiteralExpr(EmptyShell Empty)7730b57cec5SDimitry Andric   explicit CXXNullPtrLiteralExpr(EmptyShell Empty)
7740b57cec5SDimitry Andric       : Expr(CXXNullPtrLiteralExprClass, Empty) {}
7750b57cec5SDimitry Andric 
getBeginLoc()7760b57cec5SDimitry Andric   SourceLocation getBeginLoc() const { return getLocation(); }
getEndLoc()7770b57cec5SDimitry Andric   SourceLocation getEndLoc() const { return getLocation(); }
7780b57cec5SDimitry Andric 
getLocation()7790b57cec5SDimitry Andric   SourceLocation getLocation() const { return CXXNullPtrLiteralExprBits.Loc; }
setLocation(SourceLocation L)7800b57cec5SDimitry Andric   void setLocation(SourceLocation L) { CXXNullPtrLiteralExprBits.Loc = L; }
7810b57cec5SDimitry Andric 
classof(const Stmt * T)7820b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
7830b57cec5SDimitry Andric     return T->getStmtClass() == CXXNullPtrLiteralExprClass;
7840b57cec5SDimitry Andric   }
7850b57cec5SDimitry Andric 
children()7860b57cec5SDimitry Andric   child_range children() {
7870b57cec5SDimitry Andric     return child_range(child_iterator(), child_iterator());
7880b57cec5SDimitry Andric   }
7890b57cec5SDimitry Andric 
children()7900b57cec5SDimitry Andric   const_child_range children() const {
7910b57cec5SDimitry Andric     return const_child_range(const_child_iterator(), const_child_iterator());
7920b57cec5SDimitry Andric   }
7930b57cec5SDimitry Andric };
7940b57cec5SDimitry Andric 
7950b57cec5SDimitry Andric /// Implicit construction of a std::initializer_list<T> object from an
7960b57cec5SDimitry Andric /// array temporary within list-initialization (C++11 [dcl.init.list]p5).
7970b57cec5SDimitry Andric class CXXStdInitializerListExpr : public Expr {
7980b57cec5SDimitry Andric   Stmt *SubExpr = nullptr;
7990b57cec5SDimitry Andric 
CXXStdInitializerListExpr(EmptyShell Empty)8000b57cec5SDimitry Andric   CXXStdInitializerListExpr(EmptyShell Empty)
8010b57cec5SDimitry Andric       : Expr(CXXStdInitializerListExprClass, Empty) {}
8020b57cec5SDimitry Andric 
8030b57cec5SDimitry Andric public:
8040b57cec5SDimitry Andric   friend class ASTReader;
8050b57cec5SDimitry Andric   friend class ASTStmtReader;
8060b57cec5SDimitry Andric 
CXXStdInitializerListExpr(QualType Ty,Expr * SubExpr)8070b57cec5SDimitry Andric   CXXStdInitializerListExpr(QualType Ty, Expr *SubExpr)
808fe6060f1SDimitry Andric       : Expr(CXXStdInitializerListExprClass, Ty, VK_PRValue, OK_Ordinary),
8095ffd83dbSDimitry Andric         SubExpr(SubExpr) {
8105ffd83dbSDimitry Andric     setDependence(computeDependence(this));
8115ffd83dbSDimitry Andric   }
8120b57cec5SDimitry Andric 
getSubExpr()8130b57cec5SDimitry Andric   Expr *getSubExpr() { return static_cast<Expr*>(SubExpr); }
getSubExpr()8140b57cec5SDimitry Andric   const Expr *getSubExpr() const { return static_cast<const Expr*>(SubExpr); }
8150b57cec5SDimitry Andric 
getBeginLoc()8160b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY {
8170b57cec5SDimitry Andric     return SubExpr->getBeginLoc();
8180b57cec5SDimitry Andric   }
8190b57cec5SDimitry Andric 
getEndLoc()8200b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY {
8210b57cec5SDimitry Andric     return SubExpr->getEndLoc();
8220b57cec5SDimitry Andric   }
8230b57cec5SDimitry Andric 
8240b57cec5SDimitry Andric   /// Retrieve the source range of the expression.
getSourceRange()8250b57cec5SDimitry Andric   SourceRange getSourceRange() const LLVM_READONLY {
8260b57cec5SDimitry Andric     return SubExpr->getSourceRange();
8270b57cec5SDimitry Andric   }
8280b57cec5SDimitry Andric 
classof(const Stmt * S)8290b57cec5SDimitry Andric   static bool classof(const Stmt *S) {
8300b57cec5SDimitry Andric     return S->getStmtClass() == CXXStdInitializerListExprClass;
8310b57cec5SDimitry Andric   }
8320b57cec5SDimitry Andric 
children()8330b57cec5SDimitry Andric   child_range children() { return child_range(&SubExpr, &SubExpr + 1); }
8340b57cec5SDimitry Andric 
children()8350b57cec5SDimitry Andric   const_child_range children() const {
8360b57cec5SDimitry Andric     return const_child_range(&SubExpr, &SubExpr + 1);
8370b57cec5SDimitry Andric   }
8380b57cec5SDimitry Andric };
8390b57cec5SDimitry Andric 
8400b57cec5SDimitry Andric /// A C++ \c typeid expression (C++ [expr.typeid]), which gets
8410b57cec5SDimitry Andric /// the \c type_info that corresponds to the supplied type, or the (possibly
8420b57cec5SDimitry Andric /// dynamic) type of the supplied expression.
8430b57cec5SDimitry Andric ///
8440b57cec5SDimitry Andric /// This represents code like \c typeid(int) or \c typeid(*objPtr)
8450b57cec5SDimitry Andric class CXXTypeidExpr : public Expr {
8465ffd83dbSDimitry Andric   friend class ASTStmtReader;
8475ffd83dbSDimitry Andric 
8480b57cec5SDimitry Andric private:
8490b57cec5SDimitry Andric   llvm::PointerUnion<Stmt *, TypeSourceInfo *> Operand;
8500b57cec5SDimitry Andric   SourceRange Range;
8510b57cec5SDimitry Andric 
8520b57cec5SDimitry Andric public:
CXXTypeidExpr(QualType Ty,TypeSourceInfo * Operand,SourceRange R)8530b57cec5SDimitry Andric   CXXTypeidExpr(QualType Ty, TypeSourceInfo *Operand, SourceRange R)
8545ffd83dbSDimitry Andric       : Expr(CXXTypeidExprClass, Ty, VK_LValue, OK_Ordinary), Operand(Operand),
8555ffd83dbSDimitry Andric         Range(R) {
8565ffd83dbSDimitry Andric     setDependence(computeDependence(this));
8575ffd83dbSDimitry Andric   }
8580b57cec5SDimitry Andric 
CXXTypeidExpr(QualType Ty,Expr * Operand,SourceRange R)8590b57cec5SDimitry Andric   CXXTypeidExpr(QualType Ty, Expr *Operand, SourceRange R)
8605ffd83dbSDimitry Andric       : Expr(CXXTypeidExprClass, Ty, VK_LValue, OK_Ordinary), Operand(Operand),
8615ffd83dbSDimitry Andric         Range(R) {
8625ffd83dbSDimitry Andric     setDependence(computeDependence(this));
8635ffd83dbSDimitry Andric   }
8640b57cec5SDimitry Andric 
CXXTypeidExpr(EmptyShell Empty,bool isExpr)8650b57cec5SDimitry Andric   CXXTypeidExpr(EmptyShell Empty, bool isExpr)
8660b57cec5SDimitry Andric       : Expr(CXXTypeidExprClass, Empty) {
8670b57cec5SDimitry Andric     if (isExpr)
8680b57cec5SDimitry Andric       Operand = (Expr*)nullptr;
8690b57cec5SDimitry Andric     else
8700b57cec5SDimitry Andric       Operand = (TypeSourceInfo*)nullptr;
8710b57cec5SDimitry Andric   }
8720b57cec5SDimitry Andric 
8730b57cec5SDimitry Andric   /// Determine whether this typeid has a type operand which is potentially
8740b57cec5SDimitry Andric   /// evaluated, per C++11 [expr.typeid]p3.
8750b57cec5SDimitry Andric   bool isPotentiallyEvaluated() const;
8760b57cec5SDimitry Andric 
877e8d8bef9SDimitry Andric   /// Best-effort check if the expression operand refers to a most derived
878e8d8bef9SDimitry Andric   /// object. This is not a strong guarantee.
879e8d8bef9SDimitry Andric   bool isMostDerived(ASTContext &Context) const;
880e8d8bef9SDimitry Andric 
isTypeOperand()8810b57cec5SDimitry Andric   bool isTypeOperand() const { return Operand.is<TypeSourceInfo *>(); }
8820b57cec5SDimitry Andric 
8830b57cec5SDimitry Andric   /// Retrieves the type operand of this typeid() expression after
8840b57cec5SDimitry Andric   /// various required adjustments (removing reference types, cv-qualifiers).
8850b57cec5SDimitry Andric   QualType getTypeOperand(ASTContext &Context) const;
8860b57cec5SDimitry Andric 
8870b57cec5SDimitry Andric   /// Retrieve source information for the type operand.
getTypeOperandSourceInfo()8880b57cec5SDimitry Andric   TypeSourceInfo *getTypeOperandSourceInfo() const {
8890b57cec5SDimitry Andric     assert(isTypeOperand() && "Cannot call getTypeOperand for typeid(expr)");
8900b57cec5SDimitry Andric     return Operand.get<TypeSourceInfo *>();
8910b57cec5SDimitry Andric   }
getExprOperand()8920b57cec5SDimitry Andric   Expr *getExprOperand() const {
8930b57cec5SDimitry Andric     assert(!isTypeOperand() && "Cannot call getExprOperand for typeid(type)");
8940b57cec5SDimitry Andric     return static_cast<Expr*>(Operand.get<Stmt *>());
8950b57cec5SDimitry Andric   }
8960b57cec5SDimitry Andric 
getBeginLoc()8970b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); }
getEndLoc()8980b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); }
getSourceRange()8990b57cec5SDimitry Andric   SourceRange getSourceRange() const LLVM_READONLY { return Range; }
setSourceRange(SourceRange R)9000b57cec5SDimitry Andric   void setSourceRange(SourceRange R) { Range = R; }
9010b57cec5SDimitry Andric 
classof(const Stmt * T)9020b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
9030b57cec5SDimitry Andric     return T->getStmtClass() == CXXTypeidExprClass;
9040b57cec5SDimitry Andric   }
9050b57cec5SDimitry Andric 
9060b57cec5SDimitry Andric   // Iterators
children()9070b57cec5SDimitry Andric   child_range children() {
9080b57cec5SDimitry Andric     if (isTypeOperand())
9090b57cec5SDimitry Andric       return child_range(child_iterator(), child_iterator());
9100b57cec5SDimitry Andric     auto **begin = reinterpret_cast<Stmt **>(&Operand);
9110b57cec5SDimitry Andric     return child_range(begin, begin + 1);
9120b57cec5SDimitry Andric   }
9130b57cec5SDimitry Andric 
children()9140b57cec5SDimitry Andric   const_child_range children() const {
9150b57cec5SDimitry Andric     if (isTypeOperand())
9160b57cec5SDimitry Andric       return const_child_range(const_child_iterator(), const_child_iterator());
9170b57cec5SDimitry Andric 
9180b57cec5SDimitry Andric     auto **begin =
9190b57cec5SDimitry Andric         reinterpret_cast<Stmt **>(&const_cast<CXXTypeidExpr *>(this)->Operand);
9200b57cec5SDimitry Andric     return const_child_range(begin, begin + 1);
9210b57cec5SDimitry Andric   }
9220b57cec5SDimitry Andric };
9230b57cec5SDimitry Andric 
9240b57cec5SDimitry Andric /// A member reference to an MSPropertyDecl.
9250b57cec5SDimitry Andric ///
9260b57cec5SDimitry Andric /// This expression always has pseudo-object type, and therefore it is
9270b57cec5SDimitry Andric /// typically not encountered in a fully-typechecked expression except
9280b57cec5SDimitry Andric /// within the syntactic form of a PseudoObjectExpr.
9290b57cec5SDimitry Andric class MSPropertyRefExpr : public Expr {
9300b57cec5SDimitry Andric   Expr *BaseExpr;
9310b57cec5SDimitry Andric   MSPropertyDecl *TheDecl;
9320b57cec5SDimitry Andric   SourceLocation MemberLoc;
9330b57cec5SDimitry Andric   bool IsArrow;
9340b57cec5SDimitry Andric   NestedNameSpecifierLoc QualifierLoc;
9350b57cec5SDimitry Andric 
9360b57cec5SDimitry Andric public:
9370b57cec5SDimitry Andric   friend class ASTStmtReader;
9380b57cec5SDimitry Andric 
MSPropertyRefExpr(Expr * baseExpr,MSPropertyDecl * decl,bool isArrow,QualType ty,ExprValueKind VK,NestedNameSpecifierLoc qualifierLoc,SourceLocation nameLoc)9390b57cec5SDimitry Andric   MSPropertyRefExpr(Expr *baseExpr, MSPropertyDecl *decl, bool isArrow,
9400b57cec5SDimitry Andric                     QualType ty, ExprValueKind VK,
9415ffd83dbSDimitry Andric                     NestedNameSpecifierLoc qualifierLoc, SourceLocation nameLoc)
9425ffd83dbSDimitry Andric       : Expr(MSPropertyRefExprClass, ty, VK, OK_Ordinary), BaseExpr(baseExpr),
9435ffd83dbSDimitry Andric         TheDecl(decl), MemberLoc(nameLoc), IsArrow(isArrow),
9445ffd83dbSDimitry Andric         QualifierLoc(qualifierLoc) {
9455ffd83dbSDimitry Andric     setDependence(computeDependence(this));
9465ffd83dbSDimitry Andric   }
9470b57cec5SDimitry Andric 
MSPropertyRefExpr(EmptyShell Empty)9480b57cec5SDimitry Andric   MSPropertyRefExpr(EmptyShell Empty) : Expr(MSPropertyRefExprClass, Empty) {}
9490b57cec5SDimitry Andric 
getSourceRange()9500b57cec5SDimitry Andric   SourceRange getSourceRange() const LLVM_READONLY {
9510b57cec5SDimitry Andric     return SourceRange(getBeginLoc(), getEndLoc());
9520b57cec5SDimitry Andric   }
9530b57cec5SDimitry Andric 
isImplicitAccess()9540b57cec5SDimitry Andric   bool isImplicitAccess() const {
9550b57cec5SDimitry Andric     return getBaseExpr() && getBaseExpr()->isImplicitCXXThis();
9560b57cec5SDimitry Andric   }
9570b57cec5SDimitry Andric 
getBeginLoc()9580b57cec5SDimitry Andric   SourceLocation getBeginLoc() const {
9590b57cec5SDimitry Andric     if (!isImplicitAccess())
9600b57cec5SDimitry Andric       return BaseExpr->getBeginLoc();
9610b57cec5SDimitry Andric     else if (QualifierLoc)
9620b57cec5SDimitry Andric       return QualifierLoc.getBeginLoc();
9630b57cec5SDimitry Andric     else
9640b57cec5SDimitry Andric         return MemberLoc;
9650b57cec5SDimitry Andric   }
9660b57cec5SDimitry Andric 
getEndLoc()9670b57cec5SDimitry Andric   SourceLocation getEndLoc() const { return getMemberLoc(); }
9680b57cec5SDimitry Andric 
children()9690b57cec5SDimitry Andric   child_range children() {
9700b57cec5SDimitry Andric     return child_range((Stmt**)&BaseExpr, (Stmt**)&BaseExpr + 1);
9710b57cec5SDimitry Andric   }
9720b57cec5SDimitry Andric 
children()9730b57cec5SDimitry Andric   const_child_range children() const {
9740b57cec5SDimitry Andric     auto Children = const_cast<MSPropertyRefExpr *>(this)->children();
9750b57cec5SDimitry Andric     return const_child_range(Children.begin(), Children.end());
9760b57cec5SDimitry Andric   }
9770b57cec5SDimitry Andric 
classof(const Stmt * T)9780b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
9790b57cec5SDimitry Andric     return T->getStmtClass() == MSPropertyRefExprClass;
9800b57cec5SDimitry Andric   }
9810b57cec5SDimitry Andric 
getBaseExpr()9820b57cec5SDimitry Andric   Expr *getBaseExpr() const { return BaseExpr; }
getPropertyDecl()9830b57cec5SDimitry Andric   MSPropertyDecl *getPropertyDecl() const { return TheDecl; }
isArrow()9840b57cec5SDimitry Andric   bool isArrow() const { return IsArrow; }
getMemberLoc()9850b57cec5SDimitry Andric   SourceLocation getMemberLoc() const { return MemberLoc; }
getQualifierLoc()9860b57cec5SDimitry Andric   NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
9870b57cec5SDimitry Andric };
9880b57cec5SDimitry Andric 
9890b57cec5SDimitry Andric /// MS property subscript expression.
9900b57cec5SDimitry Andric /// MSVC supports 'property' attribute and allows to apply it to the
9910b57cec5SDimitry Andric /// declaration of an empty array in a class or structure definition.
9920b57cec5SDimitry Andric /// For example:
9930b57cec5SDimitry Andric /// \code
9940b57cec5SDimitry Andric /// __declspec(property(get=GetX, put=PutX)) int x[];
9950b57cec5SDimitry Andric /// \endcode
9960b57cec5SDimitry Andric /// The above statement indicates that x[] can be used with one or more array
9970b57cec5SDimitry Andric /// indices. In this case, i=p->x[a][b] will be turned into i=p->GetX(a, b), and
9980b57cec5SDimitry Andric /// p->x[a][b] = i will be turned into p->PutX(a, b, i).
9990b57cec5SDimitry Andric /// This is a syntactic pseudo-object expression.
10000b57cec5SDimitry Andric class MSPropertySubscriptExpr : public Expr {
10010b57cec5SDimitry Andric   friend class ASTStmtReader;
10020b57cec5SDimitry Andric 
10030b57cec5SDimitry Andric   enum { BASE_EXPR, IDX_EXPR, NUM_SUBEXPRS = 2 };
10040b57cec5SDimitry Andric 
10050b57cec5SDimitry Andric   Stmt *SubExprs[NUM_SUBEXPRS];
10060b57cec5SDimitry Andric   SourceLocation RBracketLoc;
10070b57cec5SDimitry Andric 
setBase(Expr * Base)10080b57cec5SDimitry Andric   void setBase(Expr *Base) { SubExprs[BASE_EXPR] = Base; }
setIdx(Expr * Idx)10090b57cec5SDimitry Andric   void setIdx(Expr *Idx) { SubExprs[IDX_EXPR] = Idx; }
10100b57cec5SDimitry Andric 
10110b57cec5SDimitry Andric public:
MSPropertySubscriptExpr(Expr * Base,Expr * Idx,QualType Ty,ExprValueKind VK,ExprObjectKind OK,SourceLocation RBracketLoc)10120b57cec5SDimitry Andric   MSPropertySubscriptExpr(Expr *Base, Expr *Idx, QualType Ty, ExprValueKind VK,
10130b57cec5SDimitry Andric                           ExprObjectKind OK, SourceLocation RBracketLoc)
10145ffd83dbSDimitry Andric       : Expr(MSPropertySubscriptExprClass, Ty, VK, OK),
10150b57cec5SDimitry Andric         RBracketLoc(RBracketLoc) {
10160b57cec5SDimitry Andric     SubExprs[BASE_EXPR] = Base;
10170b57cec5SDimitry Andric     SubExprs[IDX_EXPR] = Idx;
10185ffd83dbSDimitry Andric     setDependence(computeDependence(this));
10190b57cec5SDimitry Andric   }
10200b57cec5SDimitry Andric 
10210b57cec5SDimitry Andric   /// Create an empty array subscript expression.
MSPropertySubscriptExpr(EmptyShell Shell)10220b57cec5SDimitry Andric   explicit MSPropertySubscriptExpr(EmptyShell Shell)
10230b57cec5SDimitry Andric       : Expr(MSPropertySubscriptExprClass, Shell) {}
10240b57cec5SDimitry Andric 
getBase()10250b57cec5SDimitry Andric   Expr *getBase() { return cast<Expr>(SubExprs[BASE_EXPR]); }
getBase()10260b57cec5SDimitry Andric   const Expr *getBase() const { return cast<Expr>(SubExprs[BASE_EXPR]); }
10270b57cec5SDimitry Andric 
getIdx()10280b57cec5SDimitry Andric   Expr *getIdx() { return cast<Expr>(SubExprs[IDX_EXPR]); }
getIdx()10290b57cec5SDimitry Andric   const Expr *getIdx() const { return cast<Expr>(SubExprs[IDX_EXPR]); }
10300b57cec5SDimitry Andric 
getBeginLoc()10310b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY {
10320b57cec5SDimitry Andric     return getBase()->getBeginLoc();
10330b57cec5SDimitry Andric   }
10340b57cec5SDimitry Andric 
getEndLoc()10350b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY { return RBracketLoc; }
10360b57cec5SDimitry Andric 
getRBracketLoc()10370b57cec5SDimitry Andric   SourceLocation getRBracketLoc() const { return RBracketLoc; }
setRBracketLoc(SourceLocation L)10380b57cec5SDimitry Andric   void setRBracketLoc(SourceLocation L) { RBracketLoc = L; }
10390b57cec5SDimitry Andric 
getExprLoc()10400b57cec5SDimitry Andric   SourceLocation getExprLoc() const LLVM_READONLY {
10410b57cec5SDimitry Andric     return getBase()->getExprLoc();
10420b57cec5SDimitry Andric   }
10430b57cec5SDimitry Andric 
classof(const Stmt * T)10440b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
10450b57cec5SDimitry Andric     return T->getStmtClass() == MSPropertySubscriptExprClass;
10460b57cec5SDimitry Andric   }
10470b57cec5SDimitry Andric 
10480b57cec5SDimitry Andric   // Iterators
children()10490b57cec5SDimitry Andric   child_range children() {
10500b57cec5SDimitry Andric     return child_range(&SubExprs[0], &SubExprs[0] + NUM_SUBEXPRS);
10510b57cec5SDimitry Andric   }
10520b57cec5SDimitry Andric 
children()10530b57cec5SDimitry Andric   const_child_range children() const {
10540b57cec5SDimitry Andric     return const_child_range(&SubExprs[0], &SubExprs[0] + NUM_SUBEXPRS);
10550b57cec5SDimitry Andric   }
10560b57cec5SDimitry Andric };
10570b57cec5SDimitry Andric 
10580b57cec5SDimitry Andric /// A Microsoft C++ @c __uuidof expression, which gets
10590b57cec5SDimitry Andric /// the _GUID that corresponds to the supplied type or expression.
10600b57cec5SDimitry Andric ///
10610b57cec5SDimitry Andric /// This represents code like @c __uuidof(COMTYPE) or @c __uuidof(*comPtr)
10620b57cec5SDimitry Andric class CXXUuidofExpr : public Expr {
10635ffd83dbSDimitry Andric   friend class ASTStmtReader;
10645ffd83dbSDimitry Andric 
10650b57cec5SDimitry Andric private:
10660b57cec5SDimitry Andric   llvm::PointerUnion<Stmt *, TypeSourceInfo *> Operand;
10675ffd83dbSDimitry Andric   MSGuidDecl *Guid;
10680b57cec5SDimitry Andric   SourceRange Range;
10690b57cec5SDimitry Andric 
10700b57cec5SDimitry Andric public:
CXXUuidofExpr(QualType Ty,TypeSourceInfo * Operand,MSGuidDecl * Guid,SourceRange R)10715ffd83dbSDimitry Andric   CXXUuidofExpr(QualType Ty, TypeSourceInfo *Operand, MSGuidDecl *Guid,
10720b57cec5SDimitry Andric                 SourceRange R)
10735ffd83dbSDimitry Andric       : Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary), Operand(Operand),
10745ffd83dbSDimitry Andric         Guid(Guid), Range(R) {
10755ffd83dbSDimitry Andric     setDependence(computeDependence(this));
10765ffd83dbSDimitry Andric   }
10770b57cec5SDimitry Andric 
CXXUuidofExpr(QualType Ty,Expr * Operand,MSGuidDecl * Guid,SourceRange R)10785ffd83dbSDimitry Andric   CXXUuidofExpr(QualType Ty, Expr *Operand, MSGuidDecl *Guid, SourceRange R)
10795ffd83dbSDimitry Andric       : Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary), Operand(Operand),
10805ffd83dbSDimitry Andric         Guid(Guid), Range(R) {
10815ffd83dbSDimitry Andric     setDependence(computeDependence(this));
10825ffd83dbSDimitry Andric   }
10830b57cec5SDimitry Andric 
CXXUuidofExpr(EmptyShell Empty,bool isExpr)10840b57cec5SDimitry Andric   CXXUuidofExpr(EmptyShell Empty, bool isExpr)
10850b57cec5SDimitry Andric     : Expr(CXXUuidofExprClass, Empty) {
10860b57cec5SDimitry Andric     if (isExpr)
10870b57cec5SDimitry Andric       Operand = (Expr*)nullptr;
10880b57cec5SDimitry Andric     else
10890b57cec5SDimitry Andric       Operand = (TypeSourceInfo*)nullptr;
10900b57cec5SDimitry Andric   }
10910b57cec5SDimitry Andric 
isTypeOperand()10920b57cec5SDimitry Andric   bool isTypeOperand() const { return Operand.is<TypeSourceInfo *>(); }
10930b57cec5SDimitry Andric 
10940b57cec5SDimitry Andric   /// Retrieves the type operand of this __uuidof() expression after
10950b57cec5SDimitry Andric   /// various required adjustments (removing reference types, cv-qualifiers).
10960b57cec5SDimitry Andric   QualType getTypeOperand(ASTContext &Context) const;
10970b57cec5SDimitry Andric 
10980b57cec5SDimitry Andric   /// Retrieve source information for the type operand.
getTypeOperandSourceInfo()10990b57cec5SDimitry Andric   TypeSourceInfo *getTypeOperandSourceInfo() const {
11000b57cec5SDimitry Andric     assert(isTypeOperand() && "Cannot call getTypeOperand for __uuidof(expr)");
11010b57cec5SDimitry Andric     return Operand.get<TypeSourceInfo *>();
11020b57cec5SDimitry Andric   }
getExprOperand()11030b57cec5SDimitry Andric   Expr *getExprOperand() const {
11040b57cec5SDimitry Andric     assert(!isTypeOperand() && "Cannot call getExprOperand for __uuidof(type)");
11050b57cec5SDimitry Andric     return static_cast<Expr*>(Operand.get<Stmt *>());
11060b57cec5SDimitry Andric   }
11070b57cec5SDimitry Andric 
getGuidDecl()11085ffd83dbSDimitry Andric   MSGuidDecl *getGuidDecl() const { return Guid; }
11090b57cec5SDimitry Andric 
getBeginLoc()11100b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); }
getEndLoc()11110b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); }
getSourceRange()11120b57cec5SDimitry Andric   SourceRange getSourceRange() const LLVM_READONLY { return Range; }
setSourceRange(SourceRange R)11130b57cec5SDimitry Andric   void setSourceRange(SourceRange R) { Range = R; }
11140b57cec5SDimitry Andric 
classof(const Stmt * T)11150b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
11160b57cec5SDimitry Andric     return T->getStmtClass() == CXXUuidofExprClass;
11170b57cec5SDimitry Andric   }
11180b57cec5SDimitry Andric 
11190b57cec5SDimitry Andric   // Iterators
children()11200b57cec5SDimitry Andric   child_range children() {
11210b57cec5SDimitry Andric     if (isTypeOperand())
11220b57cec5SDimitry Andric       return child_range(child_iterator(), child_iterator());
11230b57cec5SDimitry Andric     auto **begin = reinterpret_cast<Stmt **>(&Operand);
11240b57cec5SDimitry Andric     return child_range(begin, begin + 1);
11250b57cec5SDimitry Andric   }
11260b57cec5SDimitry Andric 
children()11270b57cec5SDimitry Andric   const_child_range children() const {
11280b57cec5SDimitry Andric     if (isTypeOperand())
11290b57cec5SDimitry Andric       return const_child_range(const_child_iterator(), const_child_iterator());
11300b57cec5SDimitry Andric     auto **begin =
11310b57cec5SDimitry Andric         reinterpret_cast<Stmt **>(&const_cast<CXXUuidofExpr *>(this)->Operand);
11320b57cec5SDimitry Andric     return const_child_range(begin, begin + 1);
11330b57cec5SDimitry Andric   }
11340b57cec5SDimitry Andric };
11350b57cec5SDimitry Andric 
11360b57cec5SDimitry Andric /// Represents the \c this expression in C++.
11370b57cec5SDimitry Andric ///
11380b57cec5SDimitry Andric /// This is a pointer to the object on which the current member function is
11390b57cec5SDimitry Andric /// executing (C++ [expr.prim]p3). Example:
11400b57cec5SDimitry Andric ///
11410b57cec5SDimitry Andric /// \code
11420b57cec5SDimitry Andric /// class Foo {
11430b57cec5SDimitry Andric /// public:
11440b57cec5SDimitry Andric ///   void bar();
11450b57cec5SDimitry Andric ///   void test() { this->bar(); }
11460b57cec5SDimitry Andric /// };
11470b57cec5SDimitry Andric /// \endcode
11480b57cec5SDimitry Andric class CXXThisExpr : public Expr {
CXXThisExpr(SourceLocation L,QualType Ty,bool IsImplicit,ExprValueKind VK)11495f757f3fSDimitry Andric   CXXThisExpr(SourceLocation L, QualType Ty, bool IsImplicit, ExprValueKind VK)
11505f757f3fSDimitry Andric       : Expr(CXXThisExprClass, Ty, VK, OK_Ordinary) {
11510b57cec5SDimitry Andric     CXXThisExprBits.IsImplicit = IsImplicit;
11520b57cec5SDimitry Andric     CXXThisExprBits.Loc = L;
11535ffd83dbSDimitry Andric     setDependence(computeDependence(this));
11540b57cec5SDimitry Andric   }
11550b57cec5SDimitry Andric 
CXXThisExpr(EmptyShell Empty)11560b57cec5SDimitry Andric   CXXThisExpr(EmptyShell Empty) : Expr(CXXThisExprClass, Empty) {}
11570b57cec5SDimitry Andric 
11585f757f3fSDimitry Andric public:
11595f757f3fSDimitry Andric   static CXXThisExpr *Create(const ASTContext &Ctx, SourceLocation L,
11605f757f3fSDimitry Andric                              QualType Ty, bool IsImplicit);
11615f757f3fSDimitry Andric 
11625f757f3fSDimitry Andric   static CXXThisExpr *CreateEmpty(const ASTContext &Ctx);
11635f757f3fSDimitry Andric 
getLocation()11640b57cec5SDimitry Andric   SourceLocation getLocation() const { return CXXThisExprBits.Loc; }
setLocation(SourceLocation L)11650b57cec5SDimitry Andric   void setLocation(SourceLocation L) { CXXThisExprBits.Loc = L; }
11660b57cec5SDimitry Andric 
getBeginLoc()11670b57cec5SDimitry Andric   SourceLocation getBeginLoc() const { return getLocation(); }
getEndLoc()11680b57cec5SDimitry Andric   SourceLocation getEndLoc() const { return getLocation(); }
11690b57cec5SDimitry Andric 
isImplicit()11700b57cec5SDimitry Andric   bool isImplicit() const { return CXXThisExprBits.IsImplicit; }
setImplicit(bool I)11710b57cec5SDimitry Andric   void setImplicit(bool I) { CXXThisExprBits.IsImplicit = I; }
11720b57cec5SDimitry Andric 
classof(const Stmt * T)11730b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
11740b57cec5SDimitry Andric     return T->getStmtClass() == CXXThisExprClass;
11750b57cec5SDimitry Andric   }
11760b57cec5SDimitry Andric 
11770b57cec5SDimitry Andric   // Iterators
children()11780b57cec5SDimitry Andric   child_range children() {
11790b57cec5SDimitry Andric     return child_range(child_iterator(), child_iterator());
11800b57cec5SDimitry Andric   }
11810b57cec5SDimitry Andric 
children()11820b57cec5SDimitry Andric   const_child_range children() const {
11830b57cec5SDimitry Andric     return const_child_range(const_child_iterator(), const_child_iterator());
11840b57cec5SDimitry Andric   }
11850b57cec5SDimitry Andric };
11860b57cec5SDimitry Andric 
11870b57cec5SDimitry Andric /// A C++ throw-expression (C++ [except.throw]).
11880b57cec5SDimitry Andric ///
11890b57cec5SDimitry Andric /// This handles 'throw' (for re-throwing the current exception) and
11900b57cec5SDimitry Andric /// 'throw' assignment-expression.  When assignment-expression isn't
11910b57cec5SDimitry Andric /// present, Op will be null.
11920b57cec5SDimitry Andric class CXXThrowExpr : public Expr {
11930b57cec5SDimitry Andric   friend class ASTStmtReader;
11940b57cec5SDimitry Andric 
11950b57cec5SDimitry Andric   /// The optional expression in the throw statement.
11960b57cec5SDimitry Andric   Stmt *Operand;
11970b57cec5SDimitry Andric 
11980b57cec5SDimitry Andric public:
11990b57cec5SDimitry Andric   // \p Ty is the void type which is used as the result type of the
12000b57cec5SDimitry Andric   // expression. The \p Loc is the location of the throw keyword.
12010b57cec5SDimitry Andric   // \p Operand is the expression in the throw statement, and can be
12020b57cec5SDimitry Andric   // null if not present.
CXXThrowExpr(Expr * Operand,QualType Ty,SourceLocation Loc,bool IsThrownVariableInScope)12030b57cec5SDimitry Andric   CXXThrowExpr(Expr *Operand, QualType Ty, SourceLocation Loc,
12040b57cec5SDimitry Andric                bool IsThrownVariableInScope)
1205fe6060f1SDimitry Andric       : Expr(CXXThrowExprClass, Ty, VK_PRValue, OK_Ordinary), Operand(Operand) {
12060b57cec5SDimitry Andric     CXXThrowExprBits.ThrowLoc = Loc;
12070b57cec5SDimitry Andric     CXXThrowExprBits.IsThrownVariableInScope = IsThrownVariableInScope;
12085ffd83dbSDimitry Andric     setDependence(computeDependence(this));
12090b57cec5SDimitry Andric   }
CXXThrowExpr(EmptyShell Empty)12100b57cec5SDimitry Andric   CXXThrowExpr(EmptyShell Empty) : Expr(CXXThrowExprClass, Empty) {}
12110b57cec5SDimitry Andric 
getSubExpr()12120b57cec5SDimitry Andric   const Expr *getSubExpr() const { return cast_or_null<Expr>(Operand); }
getSubExpr()12130b57cec5SDimitry Andric   Expr *getSubExpr() { return cast_or_null<Expr>(Operand); }
12140b57cec5SDimitry Andric 
getThrowLoc()12150b57cec5SDimitry Andric   SourceLocation getThrowLoc() const { return CXXThrowExprBits.ThrowLoc; }
12160b57cec5SDimitry Andric 
12170b57cec5SDimitry Andric   /// Determines whether the variable thrown by this expression (if any!)
12180b57cec5SDimitry Andric   /// is within the innermost try block.
12190b57cec5SDimitry Andric   ///
12200b57cec5SDimitry Andric   /// This information is required to determine whether the NRVO can apply to
12210b57cec5SDimitry Andric   /// this variable.
isThrownVariableInScope()12220b57cec5SDimitry Andric   bool isThrownVariableInScope() const {
12230b57cec5SDimitry Andric     return CXXThrowExprBits.IsThrownVariableInScope;
12240b57cec5SDimitry Andric   }
12250b57cec5SDimitry Andric 
getBeginLoc()12260b57cec5SDimitry Andric   SourceLocation getBeginLoc() const { return getThrowLoc(); }
getEndLoc()12270b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY {
12280b57cec5SDimitry Andric     if (!getSubExpr())
12290b57cec5SDimitry Andric       return getThrowLoc();
12300b57cec5SDimitry Andric     return getSubExpr()->getEndLoc();
12310b57cec5SDimitry Andric   }
12320b57cec5SDimitry Andric 
classof(const Stmt * T)12330b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
12340b57cec5SDimitry Andric     return T->getStmtClass() == CXXThrowExprClass;
12350b57cec5SDimitry Andric   }
12360b57cec5SDimitry Andric 
12370b57cec5SDimitry Andric   // Iterators
children()12380b57cec5SDimitry Andric   child_range children() {
12390b57cec5SDimitry Andric     return child_range(&Operand, Operand ? &Operand + 1 : &Operand);
12400b57cec5SDimitry Andric   }
12410b57cec5SDimitry Andric 
children()12420b57cec5SDimitry Andric   const_child_range children() const {
12430b57cec5SDimitry Andric     return const_child_range(&Operand, Operand ? &Operand + 1 : &Operand);
12440b57cec5SDimitry Andric   }
12450b57cec5SDimitry Andric };
12460b57cec5SDimitry Andric 
12470b57cec5SDimitry Andric /// A default argument (C++ [dcl.fct.default]).
12480b57cec5SDimitry Andric ///
12490b57cec5SDimitry Andric /// This wraps up a function call argument that was created from the
12500b57cec5SDimitry Andric /// corresponding parameter's default argument, when the call did not
12510b57cec5SDimitry Andric /// explicitly supply arguments for all of the parameters.
1252bdd1243dSDimitry Andric class CXXDefaultArgExpr final
1253bdd1243dSDimitry Andric     : public Expr,
1254bdd1243dSDimitry Andric       private llvm::TrailingObjects<CXXDefaultArgExpr, Expr *> {
12550b57cec5SDimitry Andric   friend class ASTStmtReader;
1256bdd1243dSDimitry Andric   friend class ASTReader;
1257bdd1243dSDimitry Andric   friend TrailingObjects;
12580b57cec5SDimitry Andric 
12590b57cec5SDimitry Andric   /// The parameter whose default is being used.
12600b57cec5SDimitry Andric   ParmVarDecl *Param;
12610b57cec5SDimitry Andric 
12620b57cec5SDimitry Andric   /// The context where the default argument expression was used.
12630b57cec5SDimitry Andric   DeclContext *UsedContext;
12640b57cec5SDimitry Andric 
CXXDefaultArgExpr(StmtClass SC,SourceLocation Loc,ParmVarDecl * Param,Expr * RewrittenExpr,DeclContext * UsedContext)12650b57cec5SDimitry Andric   CXXDefaultArgExpr(StmtClass SC, SourceLocation Loc, ParmVarDecl *Param,
1266bdd1243dSDimitry Andric                     Expr *RewrittenExpr, DeclContext *UsedContext)
12670b57cec5SDimitry Andric       : Expr(SC,
12680b57cec5SDimitry Andric              Param->hasUnparsedDefaultArg()
12690b57cec5SDimitry Andric                  ? Param->getType().getNonReferenceType()
12700b57cec5SDimitry Andric                  : Param->getDefaultArg()->getType(),
12710b57cec5SDimitry Andric              Param->getDefaultArg()->getValueKind(),
12725ffd83dbSDimitry Andric              Param->getDefaultArg()->getObjectKind()),
12730b57cec5SDimitry Andric         Param(Param), UsedContext(UsedContext) {
12740b57cec5SDimitry Andric     CXXDefaultArgExprBits.Loc = Loc;
1275bdd1243dSDimitry Andric     CXXDefaultArgExprBits.HasRewrittenInit = RewrittenExpr != nullptr;
1276bdd1243dSDimitry Andric     if (RewrittenExpr)
1277bdd1243dSDimitry Andric       *getTrailingObjects<Expr *>() = RewrittenExpr;
1278fe6060f1SDimitry Andric     setDependence(computeDependence(this));
12790b57cec5SDimitry Andric   }
12800b57cec5SDimitry Andric 
CXXDefaultArgExpr(EmptyShell Empty,bool HasRewrittenInit)1281bdd1243dSDimitry Andric   CXXDefaultArgExpr(EmptyShell Empty, bool HasRewrittenInit)
1282bdd1243dSDimitry Andric       : Expr(CXXDefaultArgExprClass, Empty) {
1283bdd1243dSDimitry Andric     CXXDefaultArgExprBits.HasRewrittenInit = HasRewrittenInit;
1284bdd1243dSDimitry Andric   }
1285bdd1243dSDimitry Andric 
12860b57cec5SDimitry Andric public:
1287bdd1243dSDimitry Andric   static CXXDefaultArgExpr *CreateEmpty(const ASTContext &C,
1288bdd1243dSDimitry Andric                                         bool HasRewrittenInit);
12890b57cec5SDimitry Andric 
12900b57cec5SDimitry Andric   // \p Param is the parameter whose default argument is used by this
12910b57cec5SDimitry Andric   // expression.
12920b57cec5SDimitry Andric   static CXXDefaultArgExpr *Create(const ASTContext &C, SourceLocation Loc,
1293bdd1243dSDimitry Andric                                    ParmVarDecl *Param, Expr *RewrittenExpr,
1294bdd1243dSDimitry Andric                                    DeclContext *UsedContext);
12950b57cec5SDimitry Andric   // Retrieve the parameter that the argument was created from.
getParam()12960b57cec5SDimitry Andric   const ParmVarDecl *getParam() const { return Param; }
getParam()12970b57cec5SDimitry Andric   ParmVarDecl *getParam() { return Param; }
12980b57cec5SDimitry Andric 
hasRewrittenInit()1299bdd1243dSDimitry Andric   bool hasRewrittenInit() const {
1300bdd1243dSDimitry Andric     return CXXDefaultArgExprBits.HasRewrittenInit;
1301bdd1243dSDimitry Andric   }
1302bdd1243dSDimitry Andric 
1303bdd1243dSDimitry Andric   // Retrieve the argument to the function call.
1304bdd1243dSDimitry Andric   Expr *getExpr();
getExpr()1305bdd1243dSDimitry Andric   const Expr *getExpr() const {
1306bdd1243dSDimitry Andric     return const_cast<CXXDefaultArgExpr *>(this)->getExpr();
1307bdd1243dSDimitry Andric   }
1308bdd1243dSDimitry Andric 
getRewrittenExpr()1309bdd1243dSDimitry Andric   Expr *getRewrittenExpr() {
1310bdd1243dSDimitry Andric     return hasRewrittenInit() ? *getTrailingObjects<Expr *>() : nullptr;
1311bdd1243dSDimitry Andric   }
1312bdd1243dSDimitry Andric 
getRewrittenExpr()1313bdd1243dSDimitry Andric   const Expr *getRewrittenExpr() const {
1314bdd1243dSDimitry Andric     return const_cast<CXXDefaultArgExpr *>(this)->getRewrittenExpr();
1315bdd1243dSDimitry Andric   }
1316bdd1243dSDimitry Andric 
1317bdd1243dSDimitry Andric   // Retrieve the rewritten init expression (for an init expression containing
1318bdd1243dSDimitry Andric   // immediate calls) with the top level FullExpr and ConstantExpr stripped off.
1319bdd1243dSDimitry Andric   Expr *getAdjustedRewrittenExpr();
getAdjustedRewrittenExpr()1320bdd1243dSDimitry Andric   const Expr *getAdjustedRewrittenExpr() const {
1321bdd1243dSDimitry Andric     return const_cast<CXXDefaultArgExpr *>(this)->getAdjustedRewrittenExpr();
1322bdd1243dSDimitry Andric   }
13230b57cec5SDimitry Andric 
getUsedContext()13240b57cec5SDimitry Andric   const DeclContext *getUsedContext() const { return UsedContext; }
getUsedContext()13250b57cec5SDimitry Andric   DeclContext *getUsedContext() { return UsedContext; }
13260b57cec5SDimitry Andric 
13270b57cec5SDimitry Andric   /// Retrieve the location where this default argument was actually used.
getUsedLocation()13280b57cec5SDimitry Andric   SourceLocation getUsedLocation() const { return CXXDefaultArgExprBits.Loc; }
13290b57cec5SDimitry Andric 
13300b57cec5SDimitry Andric   /// Default argument expressions have no representation in the
13310b57cec5SDimitry Andric   /// source, so they have an empty source range.
getBeginLoc()13320b57cec5SDimitry Andric   SourceLocation getBeginLoc() const { return SourceLocation(); }
getEndLoc()13330b57cec5SDimitry Andric   SourceLocation getEndLoc() const { return SourceLocation(); }
13340b57cec5SDimitry Andric 
getExprLoc()13350b57cec5SDimitry Andric   SourceLocation getExprLoc() const { return getUsedLocation(); }
13360b57cec5SDimitry Andric 
classof(const Stmt * T)13370b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
13380b57cec5SDimitry Andric     return T->getStmtClass() == CXXDefaultArgExprClass;
13390b57cec5SDimitry Andric   }
13400b57cec5SDimitry Andric 
13410b57cec5SDimitry Andric   // Iterators
children()13420b57cec5SDimitry Andric   child_range children() {
13430b57cec5SDimitry Andric     return child_range(child_iterator(), child_iterator());
13440b57cec5SDimitry Andric   }
13450b57cec5SDimitry Andric 
children()13460b57cec5SDimitry Andric   const_child_range children() const {
13470b57cec5SDimitry Andric     return const_child_range(const_child_iterator(), const_child_iterator());
13480b57cec5SDimitry Andric   }
13490b57cec5SDimitry Andric };
13500b57cec5SDimitry Andric 
13510b57cec5SDimitry Andric /// A use of a default initializer in a constructor or in aggregate
13520b57cec5SDimitry Andric /// initialization.
13530b57cec5SDimitry Andric ///
13540b57cec5SDimitry Andric /// This wraps a use of a C++ default initializer (technically,
13550b57cec5SDimitry Andric /// a brace-or-equal-initializer for a non-static data member) when it
13560b57cec5SDimitry Andric /// is implicitly used in a mem-initializer-list in a constructor
13570b57cec5SDimitry Andric /// (C++11 [class.base.init]p8) or in aggregate initialization
13580b57cec5SDimitry Andric /// (C++1y [dcl.init.aggr]p7).
1359bdd1243dSDimitry Andric class CXXDefaultInitExpr final
1360bdd1243dSDimitry Andric     : public Expr,
1361bdd1243dSDimitry Andric       private llvm::TrailingObjects<CXXDefaultInitExpr, Expr *> {
13620b57cec5SDimitry Andric 
1363bdd1243dSDimitry Andric   friend class ASTStmtReader;
1364bdd1243dSDimitry Andric   friend class ASTReader;
1365bdd1243dSDimitry Andric   friend TrailingObjects;
13660b57cec5SDimitry Andric   /// The field whose default is being used.
13670b57cec5SDimitry Andric   FieldDecl *Field;
13680b57cec5SDimitry Andric 
13690b57cec5SDimitry Andric   /// The context where the default initializer expression was used.
13700b57cec5SDimitry Andric   DeclContext *UsedContext;
13710b57cec5SDimitry Andric 
13720b57cec5SDimitry Andric   CXXDefaultInitExpr(const ASTContext &Ctx, SourceLocation Loc,
1373bdd1243dSDimitry Andric                      FieldDecl *Field, QualType Ty, DeclContext *UsedContext,
1374bdd1243dSDimitry Andric                      Expr *RewrittenInitExpr);
13750b57cec5SDimitry Andric 
CXXDefaultInitExpr(EmptyShell Empty,bool HasRewrittenInit)1376bdd1243dSDimitry Andric   CXXDefaultInitExpr(EmptyShell Empty, bool HasRewrittenInit)
1377bdd1243dSDimitry Andric       : Expr(CXXDefaultInitExprClass, Empty) {
1378bdd1243dSDimitry Andric     CXXDefaultInitExprBits.HasRewrittenInit = HasRewrittenInit;
1379bdd1243dSDimitry Andric   }
13800b57cec5SDimitry Andric 
13810b57cec5SDimitry Andric public:
1382bdd1243dSDimitry Andric   static CXXDefaultInitExpr *CreateEmpty(const ASTContext &C,
1383bdd1243dSDimitry Andric                                          bool HasRewrittenInit);
13840b57cec5SDimitry Andric   /// \p Field is the non-static data member whose default initializer is used
13850b57cec5SDimitry Andric   /// by this expression.
13860b57cec5SDimitry Andric   static CXXDefaultInitExpr *Create(const ASTContext &Ctx, SourceLocation Loc,
1387bdd1243dSDimitry Andric                                     FieldDecl *Field, DeclContext *UsedContext,
1388bdd1243dSDimitry Andric                                     Expr *RewrittenInitExpr);
1389bdd1243dSDimitry Andric 
hasRewrittenInit()1390bdd1243dSDimitry Andric   bool hasRewrittenInit() const {
1391bdd1243dSDimitry Andric     return CXXDefaultInitExprBits.HasRewrittenInit;
13920b57cec5SDimitry Andric   }
13930b57cec5SDimitry Andric 
13940b57cec5SDimitry Andric   /// Get the field whose initializer will be used.
getField()13950b57cec5SDimitry Andric   FieldDecl *getField() { return Field; }
getField()13960b57cec5SDimitry Andric   const FieldDecl *getField() const { return Field; }
13970b57cec5SDimitry Andric 
13980b57cec5SDimitry Andric   /// Get the initialization expression that will be used.
1399bdd1243dSDimitry Andric   Expr *getExpr();
getExpr()14000b57cec5SDimitry Andric   const Expr *getExpr() const {
1401bdd1243dSDimitry Andric     return const_cast<CXXDefaultInitExpr *>(this)->getExpr();
14020b57cec5SDimitry Andric   }
1403bdd1243dSDimitry Andric 
1404bdd1243dSDimitry Andric   /// Retrieve the initializing expression with evaluated immediate calls, if
1405bdd1243dSDimitry Andric   /// any.
getRewrittenExpr()1406bdd1243dSDimitry Andric   const Expr *getRewrittenExpr() const {
1407bdd1243dSDimitry Andric     assert(hasRewrittenInit() && "expected a rewritten init expression");
1408bdd1243dSDimitry Andric     return *getTrailingObjects<Expr *>();
1409bdd1243dSDimitry Andric   }
1410bdd1243dSDimitry Andric 
1411bdd1243dSDimitry Andric   /// Retrieve the initializing expression with evaluated immediate calls, if
1412bdd1243dSDimitry Andric   /// any.
getRewrittenExpr()1413bdd1243dSDimitry Andric   Expr *getRewrittenExpr() {
1414bdd1243dSDimitry Andric     assert(hasRewrittenInit() && "expected a rewritten init expression");
1415bdd1243dSDimitry Andric     return *getTrailingObjects<Expr *>();
14160b57cec5SDimitry Andric   }
14170b57cec5SDimitry Andric 
getUsedContext()14180b57cec5SDimitry Andric   const DeclContext *getUsedContext() const { return UsedContext; }
getUsedContext()14190b57cec5SDimitry Andric   DeclContext *getUsedContext() { return UsedContext; }
14200b57cec5SDimitry Andric 
14210b57cec5SDimitry Andric   /// Retrieve the location where this default initializer expression was
14220b57cec5SDimitry Andric   /// actually used.
getUsedLocation()14230b57cec5SDimitry Andric   SourceLocation getUsedLocation() const { return getBeginLoc(); }
14240b57cec5SDimitry Andric 
getBeginLoc()14250b57cec5SDimitry Andric   SourceLocation getBeginLoc() const { return CXXDefaultInitExprBits.Loc; }
getEndLoc()14260b57cec5SDimitry Andric   SourceLocation getEndLoc() const { return CXXDefaultInitExprBits.Loc; }
14270b57cec5SDimitry Andric 
classof(const Stmt * T)14280b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
14290b57cec5SDimitry Andric     return T->getStmtClass() == CXXDefaultInitExprClass;
14300b57cec5SDimitry Andric   }
14310b57cec5SDimitry Andric 
14320b57cec5SDimitry Andric   // Iterators
children()14330b57cec5SDimitry Andric   child_range children() {
14340b57cec5SDimitry Andric     return child_range(child_iterator(), child_iterator());
14350b57cec5SDimitry Andric   }
14360b57cec5SDimitry Andric 
children()14370b57cec5SDimitry Andric   const_child_range children() const {
14380b57cec5SDimitry Andric     return const_child_range(const_child_iterator(), const_child_iterator());
14390b57cec5SDimitry Andric   }
14400b57cec5SDimitry Andric };
14410b57cec5SDimitry Andric 
14420b57cec5SDimitry Andric /// Represents a C++ temporary.
14430b57cec5SDimitry Andric class CXXTemporary {
14440b57cec5SDimitry Andric   /// The destructor that needs to be called.
14450b57cec5SDimitry Andric   const CXXDestructorDecl *Destructor;
14460b57cec5SDimitry Andric 
CXXTemporary(const CXXDestructorDecl * destructor)14470b57cec5SDimitry Andric   explicit CXXTemporary(const CXXDestructorDecl *destructor)
14480b57cec5SDimitry Andric       : Destructor(destructor) {}
14490b57cec5SDimitry Andric 
14500b57cec5SDimitry Andric public:
14510b57cec5SDimitry Andric   static CXXTemporary *Create(const ASTContext &C,
14520b57cec5SDimitry Andric                               const CXXDestructorDecl *Destructor);
14530b57cec5SDimitry Andric 
getDestructor()14540b57cec5SDimitry Andric   const CXXDestructorDecl *getDestructor() const { return Destructor; }
14550b57cec5SDimitry Andric 
setDestructor(const CXXDestructorDecl * Dtor)14560b57cec5SDimitry Andric   void setDestructor(const CXXDestructorDecl *Dtor) {
14570b57cec5SDimitry Andric     Destructor = Dtor;
14580b57cec5SDimitry Andric   }
14590b57cec5SDimitry Andric };
14600b57cec5SDimitry Andric 
14610b57cec5SDimitry Andric /// Represents binding an expression to a temporary.
14620b57cec5SDimitry Andric ///
14630b57cec5SDimitry Andric /// This ensures the destructor is called for the temporary. It should only be
14640b57cec5SDimitry Andric /// needed for non-POD, non-trivially destructable class types. For example:
14650b57cec5SDimitry Andric ///
14660b57cec5SDimitry Andric /// \code
14670b57cec5SDimitry Andric ///   struct S {
14680b57cec5SDimitry Andric ///     S() { }  // User defined constructor makes S non-POD.
14690b57cec5SDimitry Andric ///     ~S() { } // User defined destructor makes it non-trivial.
14700b57cec5SDimitry Andric ///   };
14710b57cec5SDimitry Andric ///   void test() {
14720b57cec5SDimitry Andric ///     const S &s_ref = S(); // Requires a CXXBindTemporaryExpr.
14730b57cec5SDimitry Andric ///   }
14740b57cec5SDimitry Andric /// \endcode
14750b57cec5SDimitry Andric class CXXBindTemporaryExpr : public Expr {
14760b57cec5SDimitry Andric   CXXTemporary *Temp = nullptr;
14770b57cec5SDimitry Andric   Stmt *SubExpr = nullptr;
14780b57cec5SDimitry Andric 
CXXBindTemporaryExpr(CXXTemporary * temp,Expr * SubExpr)14790b57cec5SDimitry Andric   CXXBindTemporaryExpr(CXXTemporary *temp, Expr *SubExpr)
1480fe6060f1SDimitry Andric       : Expr(CXXBindTemporaryExprClass, SubExpr->getType(), VK_PRValue,
14815ffd83dbSDimitry Andric              OK_Ordinary),
14825ffd83dbSDimitry Andric         Temp(temp), SubExpr(SubExpr) {
14835ffd83dbSDimitry Andric     setDependence(computeDependence(this));
14845ffd83dbSDimitry Andric   }
14850b57cec5SDimitry Andric 
14860b57cec5SDimitry Andric public:
CXXBindTemporaryExpr(EmptyShell Empty)14870b57cec5SDimitry Andric   CXXBindTemporaryExpr(EmptyShell Empty)
14880b57cec5SDimitry Andric       : Expr(CXXBindTemporaryExprClass, Empty) {}
14890b57cec5SDimitry Andric 
14900b57cec5SDimitry Andric   static CXXBindTemporaryExpr *Create(const ASTContext &C, CXXTemporary *Temp,
14910b57cec5SDimitry Andric                                       Expr* SubExpr);
14920b57cec5SDimitry Andric 
getTemporary()14930b57cec5SDimitry Andric   CXXTemporary *getTemporary() { return Temp; }
getTemporary()14940b57cec5SDimitry Andric   const CXXTemporary *getTemporary() const { return Temp; }
setTemporary(CXXTemporary * T)14950b57cec5SDimitry Andric   void setTemporary(CXXTemporary *T) { Temp = T; }
14960b57cec5SDimitry Andric 
getSubExpr()14970b57cec5SDimitry Andric   const Expr *getSubExpr() const { return cast<Expr>(SubExpr); }
getSubExpr()14980b57cec5SDimitry Andric   Expr *getSubExpr() { return cast<Expr>(SubExpr); }
setSubExpr(Expr * E)14990b57cec5SDimitry Andric   void setSubExpr(Expr *E) { SubExpr = E; }
15000b57cec5SDimitry Andric 
getBeginLoc()15010b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY {
15020b57cec5SDimitry Andric     return SubExpr->getBeginLoc();
15030b57cec5SDimitry Andric   }
15040b57cec5SDimitry Andric 
getEndLoc()15050b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY {
15060b57cec5SDimitry Andric     return SubExpr->getEndLoc();
15070b57cec5SDimitry Andric   }
15080b57cec5SDimitry Andric 
15090b57cec5SDimitry Andric   // Implement isa/cast/dyncast/etc.
classof(const Stmt * T)15100b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
15110b57cec5SDimitry Andric     return T->getStmtClass() == CXXBindTemporaryExprClass;
15120b57cec5SDimitry Andric   }
15130b57cec5SDimitry Andric 
15140b57cec5SDimitry Andric   // Iterators
children()15150b57cec5SDimitry Andric   child_range children() { return child_range(&SubExpr, &SubExpr + 1); }
15160b57cec5SDimitry Andric 
children()15170b57cec5SDimitry Andric   const_child_range children() const {
15180b57cec5SDimitry Andric     return const_child_range(&SubExpr, &SubExpr + 1);
15190b57cec5SDimitry Andric   }
15200b57cec5SDimitry Andric };
15210b57cec5SDimitry Andric 
15225f757f3fSDimitry Andric enum class CXXConstructionKind {
15235f757f3fSDimitry Andric   Complete,
15245f757f3fSDimitry Andric   NonVirtualBase,
15255f757f3fSDimitry Andric   VirtualBase,
15265f757f3fSDimitry Andric   Delegating
15275f757f3fSDimitry Andric };
15285f757f3fSDimitry Andric 
15290b57cec5SDimitry Andric /// Represents a call to a C++ constructor.
15300b57cec5SDimitry Andric class CXXConstructExpr : public Expr {
15310b57cec5SDimitry Andric   friend class ASTStmtReader;
15320b57cec5SDimitry Andric 
15330b57cec5SDimitry Andric   /// A pointer to the constructor which will be ultimately called.
15340b57cec5SDimitry Andric   CXXConstructorDecl *Constructor;
15350b57cec5SDimitry Andric 
15360b57cec5SDimitry Andric   SourceRange ParenOrBraceRange;
15370b57cec5SDimitry Andric 
15380b57cec5SDimitry Andric   /// The number of arguments.
15390b57cec5SDimitry Andric   unsigned NumArgs;
15400b57cec5SDimitry Andric 
15410b57cec5SDimitry Andric   // We would like to stash the arguments of the constructor call after
15420b57cec5SDimitry Andric   // CXXConstructExpr. However CXXConstructExpr is used as a base class of
15430b57cec5SDimitry Andric   // CXXTemporaryObjectExpr which makes the use of llvm::TrailingObjects
15440b57cec5SDimitry Andric   // impossible.
15450b57cec5SDimitry Andric   //
15460b57cec5SDimitry Andric   // Instead we manually stash the trailing object after the full object
15470b57cec5SDimitry Andric   // containing CXXConstructExpr (that is either CXXConstructExpr or
15480b57cec5SDimitry Andric   // CXXTemporaryObjectExpr).
15490b57cec5SDimitry Andric   //
15500b57cec5SDimitry Andric   // The trailing objects are:
15510b57cec5SDimitry Andric   //
15520b57cec5SDimitry Andric   // * An array of getNumArgs() "Stmt *" for the arguments of the
15530b57cec5SDimitry Andric   //   constructor call.
15540b57cec5SDimitry Andric 
15550b57cec5SDimitry Andric   /// Return a pointer to the start of the trailing arguments.
15560b57cec5SDimitry Andric   /// Defined just after CXXTemporaryObjectExpr.
15570b57cec5SDimitry Andric   inline Stmt **getTrailingArgs();
getTrailingArgs()15580b57cec5SDimitry Andric   const Stmt *const *getTrailingArgs() const {
15590b57cec5SDimitry Andric     return const_cast<CXXConstructExpr *>(this)->getTrailingArgs();
15600b57cec5SDimitry Andric   }
15610b57cec5SDimitry Andric 
15620b57cec5SDimitry Andric protected:
15630b57cec5SDimitry Andric   /// Build a C++ construction expression.
15640b57cec5SDimitry Andric   CXXConstructExpr(StmtClass SC, QualType Ty, SourceLocation Loc,
15650b57cec5SDimitry Andric                    CXXConstructorDecl *Ctor, bool Elidable,
15660b57cec5SDimitry Andric                    ArrayRef<Expr *> Args, bool HadMultipleCandidates,
15670b57cec5SDimitry Andric                    bool ListInitialization, bool StdInitListInitialization,
15685f757f3fSDimitry Andric                    bool ZeroInitialization, CXXConstructionKind ConstructKind,
15690b57cec5SDimitry Andric                    SourceRange ParenOrBraceRange);
15700b57cec5SDimitry Andric 
15710b57cec5SDimitry Andric   /// Build an empty C++ construction expression.
15720b57cec5SDimitry Andric   CXXConstructExpr(StmtClass SC, EmptyShell Empty, unsigned NumArgs);
15730b57cec5SDimitry Andric 
15740b57cec5SDimitry Andric   /// Return the size in bytes of the trailing objects. Used by
15750b57cec5SDimitry Andric   /// CXXTemporaryObjectExpr to allocate the right amount of storage.
sizeOfTrailingObjects(unsigned NumArgs)15760b57cec5SDimitry Andric   static unsigned sizeOfTrailingObjects(unsigned NumArgs) {
15770b57cec5SDimitry Andric     return NumArgs * sizeof(Stmt *);
15780b57cec5SDimitry Andric   }
15790b57cec5SDimitry Andric 
15800b57cec5SDimitry Andric public:
15810b57cec5SDimitry Andric   /// Create a C++ construction expression.
15820b57cec5SDimitry Andric   static CXXConstructExpr *
15830b57cec5SDimitry Andric   Create(const ASTContext &Ctx, QualType Ty, SourceLocation Loc,
15840b57cec5SDimitry Andric          CXXConstructorDecl *Ctor, bool Elidable, ArrayRef<Expr *> Args,
15850b57cec5SDimitry Andric          bool HadMultipleCandidates, bool ListInitialization,
15860b57cec5SDimitry Andric          bool StdInitListInitialization, bool ZeroInitialization,
15875f757f3fSDimitry Andric          CXXConstructionKind ConstructKind, SourceRange ParenOrBraceRange);
15880b57cec5SDimitry Andric 
15890b57cec5SDimitry Andric   /// Create an empty C++ construction expression.
15900b57cec5SDimitry Andric   static CXXConstructExpr *CreateEmpty(const ASTContext &Ctx, unsigned NumArgs);
15910b57cec5SDimitry Andric 
15920b57cec5SDimitry Andric   /// Get the constructor that this expression will (ultimately) call.
getConstructor()15930b57cec5SDimitry Andric   CXXConstructorDecl *getConstructor() const { return Constructor; }
15940b57cec5SDimitry Andric 
getLocation()15950b57cec5SDimitry Andric   SourceLocation getLocation() const { return CXXConstructExprBits.Loc; }
setLocation(SourceLocation Loc)15960b57cec5SDimitry Andric   void setLocation(SourceLocation Loc) { CXXConstructExprBits.Loc = Loc; }
15970b57cec5SDimitry Andric 
15980b57cec5SDimitry Andric   /// Whether this construction is elidable.
isElidable()15990b57cec5SDimitry Andric   bool isElidable() const { return CXXConstructExprBits.Elidable; }
setElidable(bool E)16000b57cec5SDimitry Andric   void setElidable(bool E) { CXXConstructExprBits.Elidable = E; }
16010b57cec5SDimitry Andric 
16020b57cec5SDimitry Andric   /// Whether the referred constructor was resolved from
16030b57cec5SDimitry Andric   /// an overloaded set having size greater than 1.
hadMultipleCandidates()16040b57cec5SDimitry Andric   bool hadMultipleCandidates() const {
16050b57cec5SDimitry Andric     return CXXConstructExprBits.HadMultipleCandidates;
16060b57cec5SDimitry Andric   }
setHadMultipleCandidates(bool V)16070b57cec5SDimitry Andric   void setHadMultipleCandidates(bool V) {
16080b57cec5SDimitry Andric     CXXConstructExprBits.HadMultipleCandidates = V;
16090b57cec5SDimitry Andric   }
16100b57cec5SDimitry Andric 
16110b57cec5SDimitry Andric   /// Whether this constructor call was written as list-initialization.
isListInitialization()16120b57cec5SDimitry Andric   bool isListInitialization() const {
16130b57cec5SDimitry Andric     return CXXConstructExprBits.ListInitialization;
16140b57cec5SDimitry Andric   }
setListInitialization(bool V)16150b57cec5SDimitry Andric   void setListInitialization(bool V) {
16160b57cec5SDimitry Andric     CXXConstructExprBits.ListInitialization = V;
16170b57cec5SDimitry Andric   }
16180b57cec5SDimitry Andric 
16190b57cec5SDimitry Andric   /// Whether this constructor call was written as list-initialization,
16200b57cec5SDimitry Andric   /// but was interpreted as forming a std::initializer_list<T> from the list
16210b57cec5SDimitry Andric   /// and passing that as a single constructor argument.
16220b57cec5SDimitry Andric   /// See C++11 [over.match.list]p1 bullet 1.
isStdInitListInitialization()16230b57cec5SDimitry Andric   bool isStdInitListInitialization() const {
16240b57cec5SDimitry Andric     return CXXConstructExprBits.StdInitListInitialization;
16250b57cec5SDimitry Andric   }
setStdInitListInitialization(bool V)16260b57cec5SDimitry Andric   void setStdInitListInitialization(bool V) {
16270b57cec5SDimitry Andric     CXXConstructExprBits.StdInitListInitialization = V;
16280b57cec5SDimitry Andric   }
16290b57cec5SDimitry Andric 
16300b57cec5SDimitry Andric   /// Whether this construction first requires
16310b57cec5SDimitry Andric   /// zero-initialization before the initializer is called.
requiresZeroInitialization()16320b57cec5SDimitry Andric   bool requiresZeroInitialization() const {
16330b57cec5SDimitry Andric     return CXXConstructExprBits.ZeroInitialization;
16340b57cec5SDimitry Andric   }
setRequiresZeroInitialization(bool ZeroInit)16350b57cec5SDimitry Andric   void setRequiresZeroInitialization(bool ZeroInit) {
16360b57cec5SDimitry Andric     CXXConstructExprBits.ZeroInitialization = ZeroInit;
16370b57cec5SDimitry Andric   }
16380b57cec5SDimitry Andric 
16390b57cec5SDimitry Andric   /// Determine whether this constructor is actually constructing
16400b57cec5SDimitry Andric   /// a base class (rather than a complete object).
getConstructionKind()16415f757f3fSDimitry Andric   CXXConstructionKind getConstructionKind() const {
16425f757f3fSDimitry Andric     return static_cast<CXXConstructionKind>(
16435f757f3fSDimitry Andric         CXXConstructExprBits.ConstructionKind);
16440b57cec5SDimitry Andric   }
setConstructionKind(CXXConstructionKind CK)16455f757f3fSDimitry Andric   void setConstructionKind(CXXConstructionKind CK) {
16465f757f3fSDimitry Andric     CXXConstructExprBits.ConstructionKind = llvm::to_underlying(CK);
16470b57cec5SDimitry Andric   }
16480b57cec5SDimitry Andric 
16490b57cec5SDimitry Andric   using arg_iterator = ExprIterator;
16500b57cec5SDimitry Andric   using const_arg_iterator = ConstExprIterator;
16510b57cec5SDimitry Andric   using arg_range = llvm::iterator_range<arg_iterator>;
16520b57cec5SDimitry Andric   using const_arg_range = llvm::iterator_range<const_arg_iterator>;
16530b57cec5SDimitry Andric 
arguments()16540b57cec5SDimitry Andric   arg_range arguments() { return arg_range(arg_begin(), arg_end()); }
arguments()16550b57cec5SDimitry Andric   const_arg_range arguments() const {
16560b57cec5SDimitry Andric     return const_arg_range(arg_begin(), arg_end());
16570b57cec5SDimitry Andric   }
16580b57cec5SDimitry Andric 
arg_begin()16590b57cec5SDimitry Andric   arg_iterator arg_begin() { return getTrailingArgs(); }
arg_end()16600b57cec5SDimitry Andric   arg_iterator arg_end() { return arg_begin() + getNumArgs(); }
arg_begin()16610b57cec5SDimitry Andric   const_arg_iterator arg_begin() const { return getTrailingArgs(); }
arg_end()16620b57cec5SDimitry Andric   const_arg_iterator arg_end() const { return arg_begin() + getNumArgs(); }
16630b57cec5SDimitry Andric 
getArgs()16640b57cec5SDimitry Andric   Expr **getArgs() { return reinterpret_cast<Expr **>(getTrailingArgs()); }
getArgs()16650b57cec5SDimitry Andric   const Expr *const *getArgs() const {
16660b57cec5SDimitry Andric     return reinterpret_cast<const Expr *const *>(getTrailingArgs());
16670b57cec5SDimitry Andric   }
16680b57cec5SDimitry Andric 
16690b57cec5SDimitry Andric   /// Return the number of arguments to the constructor call.
getNumArgs()16700b57cec5SDimitry Andric   unsigned getNumArgs() const { return NumArgs; }
16710b57cec5SDimitry Andric 
16720b57cec5SDimitry Andric   /// Return the specified argument.
getArg(unsigned Arg)16730b57cec5SDimitry Andric   Expr *getArg(unsigned Arg) {
16740b57cec5SDimitry Andric     assert(Arg < getNumArgs() && "Arg access out of range!");
16750b57cec5SDimitry Andric     return getArgs()[Arg];
16760b57cec5SDimitry Andric   }
getArg(unsigned Arg)16770b57cec5SDimitry Andric   const Expr *getArg(unsigned Arg) const {
16780b57cec5SDimitry Andric     assert(Arg < getNumArgs() && "Arg access out of range!");
16790b57cec5SDimitry Andric     return getArgs()[Arg];
16800b57cec5SDimitry Andric   }
16810b57cec5SDimitry Andric 
16820b57cec5SDimitry Andric   /// Set the specified argument.
setArg(unsigned Arg,Expr * ArgExpr)16830b57cec5SDimitry Andric   void setArg(unsigned Arg, Expr *ArgExpr) {
16840b57cec5SDimitry Andric     assert(Arg < getNumArgs() && "Arg access out of range!");
16850b57cec5SDimitry Andric     getArgs()[Arg] = ArgExpr;
16860b57cec5SDimitry Andric   }
16870b57cec5SDimitry Andric 
isImmediateEscalating()168806c3fb27SDimitry Andric   bool isImmediateEscalating() const {
168906c3fb27SDimitry Andric     return CXXConstructExprBits.IsImmediateEscalating;
169006c3fb27SDimitry Andric   }
169106c3fb27SDimitry Andric 
setIsImmediateEscalating(bool Set)169206c3fb27SDimitry Andric   void setIsImmediateEscalating(bool Set) {
169306c3fb27SDimitry Andric     CXXConstructExprBits.IsImmediateEscalating = Set;
169406c3fb27SDimitry Andric   }
169506c3fb27SDimitry Andric 
16960b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY;
16970b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY;
getParenOrBraceRange()16980b57cec5SDimitry Andric   SourceRange getParenOrBraceRange() const { return ParenOrBraceRange; }
setParenOrBraceRange(SourceRange Range)16990b57cec5SDimitry Andric   void setParenOrBraceRange(SourceRange Range) { ParenOrBraceRange = Range; }
17000b57cec5SDimitry Andric 
classof(const Stmt * T)17010b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
17020b57cec5SDimitry Andric     return T->getStmtClass() == CXXConstructExprClass ||
17030b57cec5SDimitry Andric            T->getStmtClass() == CXXTemporaryObjectExprClass;
17040b57cec5SDimitry Andric   }
17050b57cec5SDimitry Andric 
17060b57cec5SDimitry Andric   // Iterators
children()17070b57cec5SDimitry Andric   child_range children() {
17080b57cec5SDimitry Andric     return child_range(getTrailingArgs(), getTrailingArgs() + getNumArgs());
17090b57cec5SDimitry Andric   }
17100b57cec5SDimitry Andric 
children()17110b57cec5SDimitry Andric   const_child_range children() const {
17120b57cec5SDimitry Andric     auto Children = const_cast<CXXConstructExpr *>(this)->children();
17130b57cec5SDimitry Andric     return const_child_range(Children.begin(), Children.end());
17140b57cec5SDimitry Andric   }
17150b57cec5SDimitry Andric };
17160b57cec5SDimitry Andric 
17170b57cec5SDimitry Andric /// Represents a call to an inherited base class constructor from an
17180b57cec5SDimitry Andric /// inheriting constructor. This call implicitly forwards the arguments from
17190b57cec5SDimitry Andric /// the enclosing context (an inheriting constructor) to the specified inherited
17200b57cec5SDimitry Andric /// base class constructor.
17210b57cec5SDimitry Andric class CXXInheritedCtorInitExpr : public Expr {
17220b57cec5SDimitry Andric private:
17230b57cec5SDimitry Andric   CXXConstructorDecl *Constructor = nullptr;
17240b57cec5SDimitry Andric 
17250b57cec5SDimitry Andric   /// The location of the using declaration.
17260b57cec5SDimitry Andric   SourceLocation Loc;
17270b57cec5SDimitry Andric 
17280b57cec5SDimitry Andric   /// Whether this is the construction of a virtual base.
17295f757f3fSDimitry Andric   LLVM_PREFERRED_TYPE(bool)
17300b57cec5SDimitry Andric   unsigned ConstructsVirtualBase : 1;
17310b57cec5SDimitry Andric 
17320b57cec5SDimitry Andric   /// Whether the constructor is inherited from a virtual base class of the
17330b57cec5SDimitry Andric   /// class that we construct.
17345f757f3fSDimitry Andric   LLVM_PREFERRED_TYPE(bool)
17350b57cec5SDimitry Andric   unsigned InheritedFromVirtualBase : 1;
17360b57cec5SDimitry Andric 
17370b57cec5SDimitry Andric public:
17380b57cec5SDimitry Andric   friend class ASTStmtReader;
17390b57cec5SDimitry Andric 
17400b57cec5SDimitry Andric   /// Construct a C++ inheriting construction expression.
CXXInheritedCtorInitExpr(SourceLocation Loc,QualType T,CXXConstructorDecl * Ctor,bool ConstructsVirtualBase,bool InheritedFromVirtualBase)17410b57cec5SDimitry Andric   CXXInheritedCtorInitExpr(SourceLocation Loc, QualType T,
17420b57cec5SDimitry Andric                            CXXConstructorDecl *Ctor, bool ConstructsVirtualBase,
17430b57cec5SDimitry Andric                            bool InheritedFromVirtualBase)
1744fe6060f1SDimitry Andric       : Expr(CXXInheritedCtorInitExprClass, T, VK_PRValue, OK_Ordinary),
17450b57cec5SDimitry Andric         Constructor(Ctor), Loc(Loc),
17460b57cec5SDimitry Andric         ConstructsVirtualBase(ConstructsVirtualBase),
17470b57cec5SDimitry Andric         InheritedFromVirtualBase(InheritedFromVirtualBase) {
17480b57cec5SDimitry Andric     assert(!T->isDependentType());
17495ffd83dbSDimitry Andric     setDependence(ExprDependence::None);
17500b57cec5SDimitry Andric   }
17510b57cec5SDimitry Andric 
17520b57cec5SDimitry Andric   /// Construct an empty C++ inheriting construction expression.
CXXInheritedCtorInitExpr(EmptyShell Empty)17530b57cec5SDimitry Andric   explicit CXXInheritedCtorInitExpr(EmptyShell Empty)
17540b57cec5SDimitry Andric       : Expr(CXXInheritedCtorInitExprClass, Empty),
17550b57cec5SDimitry Andric         ConstructsVirtualBase(false), InheritedFromVirtualBase(false) {}
17560b57cec5SDimitry Andric 
17570b57cec5SDimitry Andric   /// Get the constructor that this expression will call.
getConstructor()17580b57cec5SDimitry Andric   CXXConstructorDecl *getConstructor() const { return Constructor; }
17590b57cec5SDimitry Andric 
17600b57cec5SDimitry Andric   /// Determine whether this constructor is actually constructing
17610b57cec5SDimitry Andric   /// a base class (rather than a complete object).
constructsVBase()17620b57cec5SDimitry Andric   bool constructsVBase() const { return ConstructsVirtualBase; }
getConstructionKind()17635f757f3fSDimitry Andric   CXXConstructionKind getConstructionKind() const {
17645f757f3fSDimitry Andric     return ConstructsVirtualBase ? CXXConstructionKind::VirtualBase
17655f757f3fSDimitry Andric                                  : CXXConstructionKind::NonVirtualBase;
17660b57cec5SDimitry Andric   }
17670b57cec5SDimitry Andric 
17680b57cec5SDimitry Andric   /// Determine whether the inherited constructor is inherited from a
17690b57cec5SDimitry Andric   /// virtual base of the object we construct. If so, we are not responsible
17700b57cec5SDimitry Andric   /// for calling the inherited constructor (the complete object constructor
17710b57cec5SDimitry Andric   /// does that), and so we don't need to pass any arguments.
inheritedFromVBase()17720b57cec5SDimitry Andric   bool inheritedFromVBase() const { return InheritedFromVirtualBase; }
17730b57cec5SDimitry Andric 
getLocation()17740b57cec5SDimitry Andric   SourceLocation getLocation() const LLVM_READONLY { return Loc; }
getBeginLoc()17750b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; }
getEndLoc()17760b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY { return Loc; }
17770b57cec5SDimitry Andric 
classof(const Stmt * T)17780b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
17790b57cec5SDimitry Andric     return T->getStmtClass() == CXXInheritedCtorInitExprClass;
17800b57cec5SDimitry Andric   }
17810b57cec5SDimitry Andric 
children()17820b57cec5SDimitry Andric   child_range children() {
17830b57cec5SDimitry Andric     return child_range(child_iterator(), child_iterator());
17840b57cec5SDimitry Andric   }
17850b57cec5SDimitry Andric 
children()17860b57cec5SDimitry Andric   const_child_range children() const {
17870b57cec5SDimitry Andric     return const_child_range(const_child_iterator(), const_child_iterator());
17880b57cec5SDimitry Andric   }
17890b57cec5SDimitry Andric };
17900b57cec5SDimitry Andric 
17910b57cec5SDimitry Andric /// Represents an explicit C++ type conversion that uses "functional"
17920b57cec5SDimitry Andric /// notation (C++ [expr.type.conv]).
17930b57cec5SDimitry Andric ///
17940b57cec5SDimitry Andric /// Example:
17950b57cec5SDimitry Andric /// \code
17960b57cec5SDimitry Andric ///   x = int(0.5);
17970b57cec5SDimitry Andric /// \endcode
17980b57cec5SDimitry Andric class CXXFunctionalCastExpr final
17990b57cec5SDimitry Andric     : public ExplicitCastExpr,
1800e8d8bef9SDimitry Andric       private llvm::TrailingObjects<CXXFunctionalCastExpr, CXXBaseSpecifier *,
1801e8d8bef9SDimitry Andric                                     FPOptionsOverride> {
18020b57cec5SDimitry Andric   SourceLocation LParenLoc;
18030b57cec5SDimitry Andric   SourceLocation RParenLoc;
18040b57cec5SDimitry Andric 
CXXFunctionalCastExpr(QualType ty,ExprValueKind VK,TypeSourceInfo * writtenTy,CastKind kind,Expr * castExpr,unsigned pathSize,FPOptionsOverride FPO,SourceLocation lParenLoc,SourceLocation rParenLoc)18050b57cec5SDimitry Andric   CXXFunctionalCastExpr(QualType ty, ExprValueKind VK,
1806e8d8bef9SDimitry Andric                         TypeSourceInfo *writtenTy, CastKind kind,
1807e8d8bef9SDimitry Andric                         Expr *castExpr, unsigned pathSize,
1808e8d8bef9SDimitry Andric                         FPOptionsOverride FPO, SourceLocation lParenLoc,
1809e8d8bef9SDimitry Andric                         SourceLocation rParenLoc)
1810e8d8bef9SDimitry Andric       : ExplicitCastExpr(CXXFunctionalCastExprClass, ty, VK, kind, castExpr,
1811e8d8bef9SDimitry Andric                          pathSize, FPO.requiresTrailingStorage(), writtenTy),
1812e8d8bef9SDimitry Andric         LParenLoc(lParenLoc), RParenLoc(rParenLoc) {
1813e8d8bef9SDimitry Andric     if (hasStoredFPFeatures())
1814e8d8bef9SDimitry Andric       *getTrailingFPFeatures() = FPO;
1815e8d8bef9SDimitry Andric   }
18160b57cec5SDimitry Andric 
CXXFunctionalCastExpr(EmptyShell Shell,unsigned PathSize,bool HasFPFeatures)1817e8d8bef9SDimitry Andric   explicit CXXFunctionalCastExpr(EmptyShell Shell, unsigned PathSize,
1818e8d8bef9SDimitry Andric                                  bool HasFPFeatures)
1819e8d8bef9SDimitry Andric       : ExplicitCastExpr(CXXFunctionalCastExprClass, Shell, PathSize,
1820e8d8bef9SDimitry Andric                          HasFPFeatures) {}
1821e8d8bef9SDimitry Andric 
numTrailingObjects(OverloadToken<CXXBaseSpecifier * >)1822e8d8bef9SDimitry Andric   unsigned numTrailingObjects(OverloadToken<CXXBaseSpecifier *>) const {
1823e8d8bef9SDimitry Andric     return path_size();
1824e8d8bef9SDimitry Andric   }
18250b57cec5SDimitry Andric 
18260b57cec5SDimitry Andric public:
18270b57cec5SDimitry Andric   friend class CastExpr;
18280b57cec5SDimitry Andric   friend TrailingObjects;
18290b57cec5SDimitry Andric 
1830e8d8bef9SDimitry Andric   static CXXFunctionalCastExpr *
1831e8d8bef9SDimitry Andric   Create(const ASTContext &Context, QualType T, ExprValueKind VK,
1832e8d8bef9SDimitry Andric          TypeSourceInfo *Written, CastKind Kind, Expr *Op,
1833e8d8bef9SDimitry Andric          const CXXCastPath *Path, FPOptionsOverride FPO, SourceLocation LPLoc,
18340b57cec5SDimitry Andric          SourceLocation RPLoc);
1835e8d8bef9SDimitry Andric   static CXXFunctionalCastExpr *
1836e8d8bef9SDimitry Andric   CreateEmpty(const ASTContext &Context, unsigned PathSize, bool HasFPFeatures);
18370b57cec5SDimitry Andric 
getLParenLoc()18380b57cec5SDimitry Andric   SourceLocation getLParenLoc() const { return LParenLoc; }
setLParenLoc(SourceLocation L)18390b57cec5SDimitry Andric   void setLParenLoc(SourceLocation L) { LParenLoc = L; }
getRParenLoc()18400b57cec5SDimitry Andric   SourceLocation getRParenLoc() const { return RParenLoc; }
setRParenLoc(SourceLocation L)18410b57cec5SDimitry Andric   void setRParenLoc(SourceLocation L) { RParenLoc = L; }
18420b57cec5SDimitry Andric 
18430b57cec5SDimitry Andric   /// Determine whether this expression models list-initialization.
isListInitialization()18440b57cec5SDimitry Andric   bool isListInitialization() const { return LParenLoc.isInvalid(); }
18450b57cec5SDimitry Andric 
18460b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY;
18470b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY;
18480b57cec5SDimitry Andric 
classof(const Stmt * T)18490b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
18500b57cec5SDimitry Andric     return T->getStmtClass() == CXXFunctionalCastExprClass;
18510b57cec5SDimitry Andric   }
18520b57cec5SDimitry Andric };
18530b57cec5SDimitry Andric 
18540b57cec5SDimitry Andric /// Represents a C++ functional cast expression that builds a
18550b57cec5SDimitry Andric /// temporary object.
18560b57cec5SDimitry Andric ///
18570b57cec5SDimitry Andric /// This expression type represents a C++ "functional" cast
18580b57cec5SDimitry Andric /// (C++[expr.type.conv]) with N != 1 arguments that invokes a
18590b57cec5SDimitry Andric /// constructor to build a temporary object. With N == 1 arguments the
18600b57cec5SDimitry Andric /// functional cast expression will be represented by CXXFunctionalCastExpr.
18610b57cec5SDimitry Andric /// Example:
18620b57cec5SDimitry Andric /// \code
18630b57cec5SDimitry Andric /// struct X { X(int, float); }
18640b57cec5SDimitry Andric ///
18650b57cec5SDimitry Andric /// X create_X() {
18660b57cec5SDimitry Andric ///   return X(1, 3.14f); // creates a CXXTemporaryObjectExpr
18670b57cec5SDimitry Andric /// };
18680b57cec5SDimitry Andric /// \endcode
18690b57cec5SDimitry Andric class CXXTemporaryObjectExpr final : public CXXConstructExpr {
18700b57cec5SDimitry Andric   friend class ASTStmtReader;
18710b57cec5SDimitry Andric 
18720b57cec5SDimitry Andric   // CXXTemporaryObjectExpr has some trailing objects belonging
18730b57cec5SDimitry Andric   // to CXXConstructExpr. See the comment inside CXXConstructExpr
18740b57cec5SDimitry Andric   // for more details.
18750b57cec5SDimitry Andric 
18760b57cec5SDimitry Andric   TypeSourceInfo *TSI;
18770b57cec5SDimitry Andric 
18780b57cec5SDimitry Andric   CXXTemporaryObjectExpr(CXXConstructorDecl *Cons, QualType Ty,
18790b57cec5SDimitry Andric                          TypeSourceInfo *TSI, ArrayRef<Expr *> Args,
18800b57cec5SDimitry Andric                          SourceRange ParenOrBraceRange,
18810b57cec5SDimitry Andric                          bool HadMultipleCandidates, bool ListInitialization,
18820b57cec5SDimitry Andric                          bool StdInitListInitialization,
18830b57cec5SDimitry Andric                          bool ZeroInitialization);
18840b57cec5SDimitry Andric 
18850b57cec5SDimitry Andric   CXXTemporaryObjectExpr(EmptyShell Empty, unsigned NumArgs);
18860b57cec5SDimitry Andric 
18870b57cec5SDimitry Andric public:
18880b57cec5SDimitry Andric   static CXXTemporaryObjectExpr *
18890b57cec5SDimitry Andric   Create(const ASTContext &Ctx, CXXConstructorDecl *Cons, QualType Ty,
18900b57cec5SDimitry Andric          TypeSourceInfo *TSI, ArrayRef<Expr *> Args,
18910b57cec5SDimitry Andric          SourceRange ParenOrBraceRange, bool HadMultipleCandidates,
18920b57cec5SDimitry Andric          bool ListInitialization, bool StdInitListInitialization,
18930b57cec5SDimitry Andric          bool ZeroInitialization);
18940b57cec5SDimitry Andric 
18950b57cec5SDimitry Andric   static CXXTemporaryObjectExpr *CreateEmpty(const ASTContext &Ctx,
18960b57cec5SDimitry Andric                                              unsigned NumArgs);
18970b57cec5SDimitry Andric 
getTypeSourceInfo()18980b57cec5SDimitry Andric   TypeSourceInfo *getTypeSourceInfo() const { return TSI; }
18990b57cec5SDimitry Andric 
19000b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY;
19010b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY;
19020b57cec5SDimitry Andric 
classof(const Stmt * T)19030b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
19040b57cec5SDimitry Andric     return T->getStmtClass() == CXXTemporaryObjectExprClass;
19050b57cec5SDimitry Andric   }
19060b57cec5SDimitry Andric };
19070b57cec5SDimitry Andric 
getTrailingArgs()19080b57cec5SDimitry Andric Stmt **CXXConstructExpr::getTrailingArgs() {
19090b57cec5SDimitry Andric   if (auto *E = dyn_cast<CXXTemporaryObjectExpr>(this))
19100b57cec5SDimitry Andric     return reinterpret_cast<Stmt **>(E + 1);
19110b57cec5SDimitry Andric   assert((getStmtClass() == CXXConstructExprClass) &&
19120b57cec5SDimitry Andric          "Unexpected class deriving from CXXConstructExpr!");
19130b57cec5SDimitry Andric   return reinterpret_cast<Stmt **>(this + 1);
19140b57cec5SDimitry Andric }
19150b57cec5SDimitry Andric 
19160b57cec5SDimitry Andric /// A C++ lambda expression, which produces a function object
19170b57cec5SDimitry Andric /// (of unspecified type) that can be invoked later.
19180b57cec5SDimitry Andric ///
19190b57cec5SDimitry Andric /// Example:
19200b57cec5SDimitry Andric /// \code
19210b57cec5SDimitry Andric /// void low_pass_filter(std::vector<double> &values, double cutoff) {
19220b57cec5SDimitry Andric ///   values.erase(std::remove_if(values.begin(), values.end(),
19230b57cec5SDimitry Andric ///                               [=](double value) { return value > cutoff; });
19240b57cec5SDimitry Andric /// }
19250b57cec5SDimitry Andric /// \endcode
19260b57cec5SDimitry Andric ///
19270b57cec5SDimitry Andric /// C++11 lambda expressions can capture local variables, either by copying
19280b57cec5SDimitry Andric /// the values of those local variables at the time the function
19290b57cec5SDimitry Andric /// object is constructed (not when it is called!) or by holding a
19300b57cec5SDimitry Andric /// reference to the local variable. These captures can occur either
19310b57cec5SDimitry Andric /// implicitly or can be written explicitly between the square
19320b57cec5SDimitry Andric /// brackets ([...]) that start the lambda expression.
19330b57cec5SDimitry Andric ///
19340b57cec5SDimitry Andric /// C++1y introduces a new form of "capture" called an init-capture that
19350b57cec5SDimitry Andric /// includes an initializing expression (rather than capturing a variable),
19360b57cec5SDimitry Andric /// and which can never occur implicitly.
19370b57cec5SDimitry Andric class LambdaExpr final : public Expr,
19380b57cec5SDimitry Andric                          private llvm::TrailingObjects<LambdaExpr, Stmt *> {
19395ffd83dbSDimitry Andric   // LambdaExpr has some data stored in LambdaExprBits.
19405ffd83dbSDimitry Andric 
19410b57cec5SDimitry Andric   /// The source range that covers the lambda introducer ([...]).
19420b57cec5SDimitry Andric   SourceRange IntroducerRange;
19430b57cec5SDimitry Andric 
19440b57cec5SDimitry Andric   /// The source location of this lambda's capture-default ('=' or '&').
19450b57cec5SDimitry Andric   SourceLocation CaptureDefaultLoc;
19460b57cec5SDimitry Andric 
19470b57cec5SDimitry Andric   /// The location of the closing brace ('}') that completes
19480b57cec5SDimitry Andric   /// the lambda.
19490b57cec5SDimitry Andric   ///
19500b57cec5SDimitry Andric   /// The location of the brace is also available by looking up the
19510b57cec5SDimitry Andric   /// function call operator in the lambda class. However, it is
19520b57cec5SDimitry Andric   /// stored here to improve the performance of getSourceRange(), and
19530b57cec5SDimitry Andric   /// to avoid having to deserialize the function call operator from a
19540b57cec5SDimitry Andric   /// module file just to determine the source range.
19550b57cec5SDimitry Andric   SourceLocation ClosingBrace;
19560b57cec5SDimitry Andric 
19570b57cec5SDimitry Andric   /// Construct a lambda expression.
19580b57cec5SDimitry Andric   LambdaExpr(QualType T, SourceRange IntroducerRange,
19590b57cec5SDimitry Andric              LambdaCaptureDefault CaptureDefault,
19605ffd83dbSDimitry Andric              SourceLocation CaptureDefaultLoc, bool ExplicitParams,
19615ffd83dbSDimitry Andric              bool ExplicitResultType, ArrayRef<Expr *> CaptureInits,
19625ffd83dbSDimitry Andric              SourceLocation ClosingBrace, bool ContainsUnexpandedParameterPack);
19630b57cec5SDimitry Andric 
19640b57cec5SDimitry Andric   /// Construct an empty lambda expression.
19655ffd83dbSDimitry Andric   LambdaExpr(EmptyShell Empty, unsigned NumCaptures);
19660b57cec5SDimitry Andric 
getStoredStmts()19670b57cec5SDimitry Andric   Stmt **getStoredStmts() { return getTrailingObjects<Stmt *>(); }
getStoredStmts()19680b57cec5SDimitry Andric   Stmt *const *getStoredStmts() const { return getTrailingObjects<Stmt *>(); }
19690b57cec5SDimitry Andric 
19705ffd83dbSDimitry Andric   void initBodyIfNeeded() const;
19715ffd83dbSDimitry Andric 
19720b57cec5SDimitry Andric public:
19730b57cec5SDimitry Andric   friend class ASTStmtReader;
19740b57cec5SDimitry Andric   friend class ASTStmtWriter;
19750b57cec5SDimitry Andric   friend TrailingObjects;
19760b57cec5SDimitry Andric 
19770b57cec5SDimitry Andric   /// Construct a new lambda expression.
19780b57cec5SDimitry Andric   static LambdaExpr *
19790b57cec5SDimitry Andric   Create(const ASTContext &C, CXXRecordDecl *Class, SourceRange IntroducerRange,
19800b57cec5SDimitry Andric          LambdaCaptureDefault CaptureDefault, SourceLocation CaptureDefaultLoc,
19815ffd83dbSDimitry Andric          bool ExplicitParams, bool ExplicitResultType,
19825ffd83dbSDimitry Andric          ArrayRef<Expr *> CaptureInits, SourceLocation ClosingBrace,
19835ffd83dbSDimitry Andric          bool ContainsUnexpandedParameterPack);
19840b57cec5SDimitry Andric 
19850b57cec5SDimitry Andric   /// Construct a new lambda expression that will be deserialized from
19860b57cec5SDimitry Andric   /// an external source.
19870b57cec5SDimitry Andric   static LambdaExpr *CreateDeserialized(const ASTContext &C,
19880b57cec5SDimitry Andric                                         unsigned NumCaptures);
19890b57cec5SDimitry Andric 
19900b57cec5SDimitry Andric   /// Determine the default capture kind for this lambda.
getCaptureDefault()19910b57cec5SDimitry Andric   LambdaCaptureDefault getCaptureDefault() const {
19925ffd83dbSDimitry Andric     return static_cast<LambdaCaptureDefault>(LambdaExprBits.CaptureDefault);
19930b57cec5SDimitry Andric   }
19940b57cec5SDimitry Andric 
19950b57cec5SDimitry Andric   /// Retrieve the location of this lambda's capture-default, if any.
getCaptureDefaultLoc()19965ffd83dbSDimitry Andric   SourceLocation getCaptureDefaultLoc() const { return CaptureDefaultLoc; }
19970b57cec5SDimitry Andric 
19980b57cec5SDimitry Andric   /// Determine whether one of this lambda's captures is an init-capture.
19990b57cec5SDimitry Andric   bool isInitCapture(const LambdaCapture *Capture) const;
20000b57cec5SDimitry Andric 
20010b57cec5SDimitry Andric   /// An iterator that walks over the captures of the lambda,
20020b57cec5SDimitry Andric   /// both implicit and explicit.
20030b57cec5SDimitry Andric   using capture_iterator = const LambdaCapture *;
20040b57cec5SDimitry Andric 
20050b57cec5SDimitry Andric   /// An iterator over a range of lambda captures.
20060b57cec5SDimitry Andric   using capture_range = llvm::iterator_range<capture_iterator>;
20070b57cec5SDimitry Andric 
20080b57cec5SDimitry Andric   /// Retrieve this lambda's captures.
20090b57cec5SDimitry Andric   capture_range captures() const;
20100b57cec5SDimitry Andric 
20110b57cec5SDimitry Andric   /// Retrieve an iterator pointing to the first lambda capture.
20120b57cec5SDimitry Andric   capture_iterator capture_begin() const;
20130b57cec5SDimitry Andric 
20140b57cec5SDimitry Andric   /// Retrieve an iterator pointing past the end of the
20150b57cec5SDimitry Andric   /// sequence of lambda captures.
20160b57cec5SDimitry Andric   capture_iterator capture_end() const;
20170b57cec5SDimitry Andric 
20180b57cec5SDimitry Andric   /// Determine the number of captures in this lambda.
capture_size()20195ffd83dbSDimitry Andric   unsigned capture_size() const { return LambdaExprBits.NumCaptures; }
20200b57cec5SDimitry Andric 
20210b57cec5SDimitry Andric   /// Retrieve this lambda's explicit captures.
20220b57cec5SDimitry Andric   capture_range explicit_captures() const;
20230b57cec5SDimitry Andric 
20240b57cec5SDimitry Andric   /// Retrieve an iterator pointing to the first explicit
20250b57cec5SDimitry Andric   /// lambda capture.
20260b57cec5SDimitry Andric   capture_iterator explicit_capture_begin() const;
20270b57cec5SDimitry Andric 
20280b57cec5SDimitry Andric   /// Retrieve an iterator pointing past the end of the sequence of
20290b57cec5SDimitry Andric   /// explicit lambda captures.
20300b57cec5SDimitry Andric   capture_iterator explicit_capture_end() const;
20310b57cec5SDimitry Andric 
20320b57cec5SDimitry Andric   /// Retrieve this lambda's implicit captures.
20330b57cec5SDimitry Andric   capture_range implicit_captures() const;
20340b57cec5SDimitry Andric 
20350b57cec5SDimitry Andric   /// Retrieve an iterator pointing to the first implicit
20360b57cec5SDimitry Andric   /// lambda capture.
20370b57cec5SDimitry Andric   capture_iterator implicit_capture_begin() const;
20380b57cec5SDimitry Andric 
20390b57cec5SDimitry Andric   /// Retrieve an iterator pointing past the end of the sequence of
20400b57cec5SDimitry Andric   /// implicit lambda captures.
20410b57cec5SDimitry Andric   capture_iterator implicit_capture_end() const;
20420b57cec5SDimitry Andric 
20430b57cec5SDimitry Andric   /// Iterator that walks over the capture initialization
20440b57cec5SDimitry Andric   /// arguments.
20450b57cec5SDimitry Andric   using capture_init_iterator = Expr **;
20460b57cec5SDimitry Andric 
20470b57cec5SDimitry Andric   /// Const iterator that walks over the capture initialization
20480b57cec5SDimitry Andric   /// arguments.
20495ffd83dbSDimitry Andric   /// FIXME: This interface is prone to being used incorrectly.
20500b57cec5SDimitry Andric   using const_capture_init_iterator = Expr *const *;
20510b57cec5SDimitry Andric 
20520b57cec5SDimitry Andric   /// Retrieve the initialization expressions for this lambda's captures.
capture_inits()20530b57cec5SDimitry Andric   llvm::iterator_range<capture_init_iterator> capture_inits() {
20540b57cec5SDimitry Andric     return llvm::make_range(capture_init_begin(), capture_init_end());
20550b57cec5SDimitry Andric   }
20560b57cec5SDimitry Andric 
20570b57cec5SDimitry Andric   /// Retrieve the initialization expressions for this lambda's captures.
capture_inits()20580b57cec5SDimitry Andric   llvm::iterator_range<const_capture_init_iterator> capture_inits() const {
20590b57cec5SDimitry Andric     return llvm::make_range(capture_init_begin(), capture_init_end());
20600b57cec5SDimitry Andric   }
20610b57cec5SDimitry Andric 
20620b57cec5SDimitry Andric   /// Retrieve the first initialization argument for this
20630b57cec5SDimitry Andric   /// lambda expression (which initializes the first capture field).
capture_init_begin()20640b57cec5SDimitry Andric   capture_init_iterator capture_init_begin() {
20650b57cec5SDimitry Andric     return reinterpret_cast<Expr **>(getStoredStmts());
20660b57cec5SDimitry Andric   }
20670b57cec5SDimitry Andric 
20680b57cec5SDimitry Andric   /// Retrieve the first initialization argument for this
20690b57cec5SDimitry Andric   /// lambda expression (which initializes the first capture field).
capture_init_begin()20700b57cec5SDimitry Andric   const_capture_init_iterator capture_init_begin() const {
20710b57cec5SDimitry Andric     return reinterpret_cast<Expr *const *>(getStoredStmts());
20720b57cec5SDimitry Andric   }
20730b57cec5SDimitry Andric 
20740b57cec5SDimitry Andric   /// Retrieve the iterator pointing one past the last
20750b57cec5SDimitry Andric   /// initialization argument for this lambda expression.
capture_init_end()20760b57cec5SDimitry Andric   capture_init_iterator capture_init_end() {
20775ffd83dbSDimitry Andric     return capture_init_begin() + capture_size();
20780b57cec5SDimitry Andric   }
20790b57cec5SDimitry Andric 
20800b57cec5SDimitry Andric   /// Retrieve the iterator pointing one past the last
20810b57cec5SDimitry Andric   /// initialization argument for this lambda expression.
capture_init_end()20820b57cec5SDimitry Andric   const_capture_init_iterator capture_init_end() const {
20835ffd83dbSDimitry Andric     return capture_init_begin() + capture_size();
20840b57cec5SDimitry Andric   }
20850b57cec5SDimitry Andric 
20860b57cec5SDimitry Andric   /// Retrieve the source range covering the lambda introducer,
20870b57cec5SDimitry Andric   /// which contains the explicit capture list surrounded by square
20880b57cec5SDimitry Andric   /// brackets ([...]).
getIntroducerRange()20890b57cec5SDimitry Andric   SourceRange getIntroducerRange() const { return IntroducerRange; }
20900b57cec5SDimitry Andric 
20910b57cec5SDimitry Andric   /// Retrieve the class that corresponds to the lambda.
20920b57cec5SDimitry Andric   ///
20930b57cec5SDimitry Andric   /// This is the "closure type" (C++1y [expr.prim.lambda]), and stores the
20940b57cec5SDimitry Andric   /// captures in its fields and provides the various operations permitted
20950b57cec5SDimitry Andric   /// on a lambda (copying, calling).
20960b57cec5SDimitry Andric   CXXRecordDecl *getLambdaClass() const;
20970b57cec5SDimitry Andric 
20980b57cec5SDimitry Andric   /// Retrieve the function call operator associated with this
20990b57cec5SDimitry Andric   /// lambda expression.
21000b57cec5SDimitry Andric   CXXMethodDecl *getCallOperator() const;
21010b57cec5SDimitry Andric 
2102a7dea167SDimitry Andric   /// Retrieve the function template call operator associated with this
2103a7dea167SDimitry Andric   /// lambda expression.
2104a7dea167SDimitry Andric   FunctionTemplateDecl *getDependentCallOperator() const;
2105a7dea167SDimitry Andric 
21060b57cec5SDimitry Andric   /// If this is a generic lambda expression, retrieve the template
21070b57cec5SDimitry Andric   /// parameter list associated with it, or else return null.
21080b57cec5SDimitry Andric   TemplateParameterList *getTemplateParameterList() const;
21090b57cec5SDimitry Andric 
21100b57cec5SDimitry Andric   /// Get the template parameters were explicitly specified (as opposed to being
21110b57cec5SDimitry Andric   /// invented by use of an auto parameter).
21120b57cec5SDimitry Andric   ArrayRef<NamedDecl *> getExplicitTemplateParameters() const;
21130b57cec5SDimitry Andric 
2114e8d8bef9SDimitry Andric   /// Get the trailing requires clause, if any.
2115e8d8bef9SDimitry Andric   Expr *getTrailingRequiresClause() const;
2116e8d8bef9SDimitry Andric 
21170b57cec5SDimitry Andric   /// Whether this is a generic lambda.
isGenericLambda()21180b57cec5SDimitry Andric   bool isGenericLambda() const { return getTemplateParameterList(); }
21190b57cec5SDimitry Andric 
21205ffd83dbSDimitry Andric   /// Retrieve the body of the lambda. This will be most of the time
21215ffd83dbSDimitry Andric   /// a \p CompoundStmt, but can also be \p CoroutineBodyStmt wrapping
21225ffd83dbSDimitry Andric   /// a \p CompoundStmt. Note that unlike functions, lambda-expressions
21235ffd83dbSDimitry Andric   /// cannot have a function-try-block.
21245ffd83dbSDimitry Andric   Stmt *getBody() const;
21255ffd83dbSDimitry Andric 
21265ffd83dbSDimitry Andric   /// Retrieve the \p CompoundStmt representing the body of the lambda.
21275ffd83dbSDimitry Andric   /// This is a convenience function for callers who do not need
21285ffd83dbSDimitry Andric   /// to handle node(s) which may wrap a \p CompoundStmt.
21295ffd83dbSDimitry Andric   const CompoundStmt *getCompoundStmtBody() const;
getCompoundStmtBody()21305ffd83dbSDimitry Andric   CompoundStmt *getCompoundStmtBody() {
21315ffd83dbSDimitry Andric     const auto *ConstThis = this;
21325ffd83dbSDimitry Andric     return const_cast<CompoundStmt *>(ConstThis->getCompoundStmtBody());
21335ffd83dbSDimitry Andric   }
21340b57cec5SDimitry Andric 
21350b57cec5SDimitry Andric   /// Determine whether the lambda is mutable, meaning that any
21360b57cec5SDimitry Andric   /// captures values can be modified.
21370b57cec5SDimitry Andric   bool isMutable() const;
21380b57cec5SDimitry Andric 
21390b57cec5SDimitry Andric   /// Determine whether this lambda has an explicit parameter
21400b57cec5SDimitry Andric   /// list vs. an implicit (empty) parameter list.
hasExplicitParameters()21415ffd83dbSDimitry Andric   bool hasExplicitParameters() const { return LambdaExprBits.ExplicitParams; }
21420b57cec5SDimitry Andric 
21430b57cec5SDimitry Andric   /// Whether this lambda had its result type explicitly specified.
hasExplicitResultType()21445ffd83dbSDimitry Andric   bool hasExplicitResultType() const {
21455ffd83dbSDimitry Andric     return LambdaExprBits.ExplicitResultType;
21465ffd83dbSDimitry Andric   }
21470b57cec5SDimitry Andric 
classof(const Stmt * T)21480b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
21490b57cec5SDimitry Andric     return T->getStmtClass() == LambdaExprClass;
21500b57cec5SDimitry Andric   }
21510b57cec5SDimitry Andric 
getBeginLoc()21520b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY {
21530b57cec5SDimitry Andric     return IntroducerRange.getBegin();
21540b57cec5SDimitry Andric   }
21550b57cec5SDimitry Andric 
getEndLoc()21560b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY { return ClosingBrace; }
21570b57cec5SDimitry Andric 
21585ffd83dbSDimitry Andric   /// Includes the captures and the body of the lambda.
21595ffd83dbSDimitry Andric   child_range children();
21605ffd83dbSDimitry Andric   const_child_range children() const;
21610b57cec5SDimitry Andric };
21620b57cec5SDimitry Andric 
21630b57cec5SDimitry Andric /// An expression "T()" which creates a value-initialized rvalue of type
21640b57cec5SDimitry Andric /// T, which is a non-class type.  See (C++98 [5.2.3p2]).
21650b57cec5SDimitry Andric class CXXScalarValueInitExpr : public Expr {
21660b57cec5SDimitry Andric   friend class ASTStmtReader;
21670b57cec5SDimitry Andric 
21680b57cec5SDimitry Andric   TypeSourceInfo *TypeInfo;
21690b57cec5SDimitry Andric 
21700b57cec5SDimitry Andric public:
21710b57cec5SDimitry Andric   /// Create an explicitly-written scalar-value initialization
21720b57cec5SDimitry Andric   /// expression.
CXXScalarValueInitExpr(QualType Type,TypeSourceInfo * TypeInfo,SourceLocation RParenLoc)21730b57cec5SDimitry Andric   CXXScalarValueInitExpr(QualType Type, TypeSourceInfo *TypeInfo,
21740b57cec5SDimitry Andric                          SourceLocation RParenLoc)
2175fe6060f1SDimitry Andric       : Expr(CXXScalarValueInitExprClass, Type, VK_PRValue, OK_Ordinary),
21760b57cec5SDimitry Andric         TypeInfo(TypeInfo) {
21770b57cec5SDimitry Andric     CXXScalarValueInitExprBits.RParenLoc = RParenLoc;
21785ffd83dbSDimitry Andric     setDependence(computeDependence(this));
21790b57cec5SDimitry Andric   }
21800b57cec5SDimitry Andric 
CXXScalarValueInitExpr(EmptyShell Shell)21810b57cec5SDimitry Andric   explicit CXXScalarValueInitExpr(EmptyShell Shell)
21820b57cec5SDimitry Andric       : Expr(CXXScalarValueInitExprClass, Shell) {}
21830b57cec5SDimitry Andric 
getTypeSourceInfo()21840b57cec5SDimitry Andric   TypeSourceInfo *getTypeSourceInfo() const {
21850b57cec5SDimitry Andric     return TypeInfo;
21860b57cec5SDimitry Andric   }
21870b57cec5SDimitry Andric 
getRParenLoc()21880b57cec5SDimitry Andric   SourceLocation getRParenLoc() const {
21890b57cec5SDimitry Andric     return CXXScalarValueInitExprBits.RParenLoc;
21900b57cec5SDimitry Andric   }
21910b57cec5SDimitry Andric 
21920b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY;
getEndLoc()21930b57cec5SDimitry Andric   SourceLocation getEndLoc() const { return getRParenLoc(); }
21940b57cec5SDimitry Andric 
classof(const Stmt * T)21950b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
21960b57cec5SDimitry Andric     return T->getStmtClass() == CXXScalarValueInitExprClass;
21970b57cec5SDimitry Andric   }
21980b57cec5SDimitry Andric 
21990b57cec5SDimitry Andric   // Iterators
children()22000b57cec5SDimitry Andric   child_range children() {
22010b57cec5SDimitry Andric     return child_range(child_iterator(), child_iterator());
22020b57cec5SDimitry Andric   }
22030b57cec5SDimitry Andric 
children()22040b57cec5SDimitry Andric   const_child_range children() const {
22050b57cec5SDimitry Andric     return const_child_range(const_child_iterator(), const_child_iterator());
22060b57cec5SDimitry Andric   }
22070b57cec5SDimitry Andric };
22080b57cec5SDimitry Andric 
22095f757f3fSDimitry Andric enum class CXXNewInitializationStyle {
22105f757f3fSDimitry Andric   /// New-expression has no initializer as written.
22115f757f3fSDimitry Andric   None,
22125f757f3fSDimitry Andric 
22135f757f3fSDimitry Andric   /// New-expression has a C++98 paren-delimited initializer.
22147a6dacacSDimitry Andric   Parens,
22155f757f3fSDimitry Andric 
22165f757f3fSDimitry Andric   /// New-expression has a C++11 list-initializer.
22177a6dacacSDimitry Andric   Braces
22185f757f3fSDimitry Andric };
22195f757f3fSDimitry Andric 
22200b57cec5SDimitry Andric /// Represents a new-expression for memory allocation and constructor
22210b57cec5SDimitry Andric /// calls, e.g: "new CXXNewExpr(foo)".
22220b57cec5SDimitry Andric class CXXNewExpr final
22230b57cec5SDimitry Andric     : public Expr,
22240b57cec5SDimitry Andric       private llvm::TrailingObjects<CXXNewExpr, Stmt *, SourceRange> {
22250b57cec5SDimitry Andric   friend class ASTStmtReader;
22260b57cec5SDimitry Andric   friend class ASTStmtWriter;
22270b57cec5SDimitry Andric   friend TrailingObjects;
22280b57cec5SDimitry Andric 
22290b57cec5SDimitry Andric   /// Points to the allocation function used.
22300b57cec5SDimitry Andric   FunctionDecl *OperatorNew;
22310b57cec5SDimitry Andric 
22320b57cec5SDimitry Andric   /// Points to the deallocation function used in case of error. May be null.
22330b57cec5SDimitry Andric   FunctionDecl *OperatorDelete;
22340b57cec5SDimitry Andric 
22350b57cec5SDimitry Andric   /// The allocated type-source information, as written in the source.
22360b57cec5SDimitry Andric   TypeSourceInfo *AllocatedTypeInfo;
22370b57cec5SDimitry Andric 
22380b57cec5SDimitry Andric   /// Range of the entire new expression.
22390b57cec5SDimitry Andric   SourceRange Range;
22400b57cec5SDimitry Andric 
22410b57cec5SDimitry Andric   /// Source-range of a paren-delimited initializer.
22420b57cec5SDimitry Andric   SourceRange DirectInitRange;
22430b57cec5SDimitry Andric 
22440b57cec5SDimitry Andric   // CXXNewExpr is followed by several optional trailing objects.
22450b57cec5SDimitry Andric   // They are in order:
22460b57cec5SDimitry Andric   //
22470b57cec5SDimitry Andric   // * An optional "Stmt *" for the array size expression.
22480b57cec5SDimitry Andric   //    Present if and ony if isArray().
22490b57cec5SDimitry Andric   //
22500b57cec5SDimitry Andric   // * An optional "Stmt *" for the init expression.
22510b57cec5SDimitry Andric   //    Present if and only if hasInitializer().
22520b57cec5SDimitry Andric   //
22530b57cec5SDimitry Andric   // * An array of getNumPlacementArgs() "Stmt *" for the placement new
22540b57cec5SDimitry Andric   //   arguments, if any.
22550b57cec5SDimitry Andric   //
22560b57cec5SDimitry Andric   // * An optional SourceRange for the range covering the parenthesized type-id
22570b57cec5SDimitry Andric   //    if the allocated type was expressed as a parenthesized type-id.
22580b57cec5SDimitry Andric   //    Present if and only if isParenTypeId().
arraySizeOffset()22590b57cec5SDimitry Andric   unsigned arraySizeOffset() const { return 0; }
initExprOffset()22600b57cec5SDimitry Andric   unsigned initExprOffset() const { return arraySizeOffset() + isArray(); }
placementNewArgsOffset()22610b57cec5SDimitry Andric   unsigned placementNewArgsOffset() const {
22620b57cec5SDimitry Andric     return initExprOffset() + hasInitializer();
22630b57cec5SDimitry Andric   }
22640b57cec5SDimitry Andric 
numTrailingObjects(OverloadToken<Stmt * >)22650b57cec5SDimitry Andric   unsigned numTrailingObjects(OverloadToken<Stmt *>) const {
22660b57cec5SDimitry Andric     return isArray() + hasInitializer() + getNumPlacementArgs();
22670b57cec5SDimitry Andric   }
22680b57cec5SDimitry Andric 
numTrailingObjects(OverloadToken<SourceRange>)22690b57cec5SDimitry Andric   unsigned numTrailingObjects(OverloadToken<SourceRange>) const {
22700b57cec5SDimitry Andric     return isParenTypeId();
22710b57cec5SDimitry Andric   }
22720b57cec5SDimitry Andric 
22730b57cec5SDimitry Andric   /// Build a c++ new expression.
22740b57cec5SDimitry Andric   CXXNewExpr(bool IsGlobalNew, FunctionDecl *OperatorNew,
22750b57cec5SDimitry Andric              FunctionDecl *OperatorDelete, bool ShouldPassAlignment,
22760b57cec5SDimitry Andric              bool UsualArrayDeleteWantsSize, ArrayRef<Expr *> PlacementArgs,
2277bdd1243dSDimitry Andric              SourceRange TypeIdParens, std::optional<Expr *> ArraySize,
22785f757f3fSDimitry Andric              CXXNewInitializationStyle InitializationStyle, Expr *Initializer,
22790b57cec5SDimitry Andric              QualType Ty, TypeSourceInfo *AllocatedTypeInfo, SourceRange Range,
22800b57cec5SDimitry Andric              SourceRange DirectInitRange);
22810b57cec5SDimitry Andric 
22820b57cec5SDimitry Andric   /// Build an empty c++ new expression.
22830b57cec5SDimitry Andric   CXXNewExpr(EmptyShell Empty, bool IsArray, unsigned NumPlacementArgs,
22840b57cec5SDimitry Andric              bool IsParenTypeId);
22850b57cec5SDimitry Andric 
22860b57cec5SDimitry Andric public:
22870b57cec5SDimitry Andric   /// Create a c++ new expression.
22880b57cec5SDimitry Andric   static CXXNewExpr *
22890b57cec5SDimitry Andric   Create(const ASTContext &Ctx, bool IsGlobalNew, FunctionDecl *OperatorNew,
22900b57cec5SDimitry Andric          FunctionDecl *OperatorDelete, bool ShouldPassAlignment,
22910b57cec5SDimitry Andric          bool UsualArrayDeleteWantsSize, ArrayRef<Expr *> PlacementArgs,
2292bdd1243dSDimitry Andric          SourceRange TypeIdParens, std::optional<Expr *> ArraySize,
22935f757f3fSDimitry Andric          CXXNewInitializationStyle InitializationStyle, Expr *Initializer,
22940b57cec5SDimitry Andric          QualType Ty, TypeSourceInfo *AllocatedTypeInfo, SourceRange Range,
22950b57cec5SDimitry Andric          SourceRange DirectInitRange);
22960b57cec5SDimitry Andric 
22970b57cec5SDimitry Andric   /// Create an empty c++ new expression.
22980b57cec5SDimitry Andric   static CXXNewExpr *CreateEmpty(const ASTContext &Ctx, bool IsArray,
22990b57cec5SDimitry Andric                                  bool HasInit, unsigned NumPlacementArgs,
23000b57cec5SDimitry Andric                                  bool IsParenTypeId);
23010b57cec5SDimitry Andric 
getAllocatedType()23020b57cec5SDimitry Andric   QualType getAllocatedType() const {
2303a7dea167SDimitry Andric     return getType()->castAs<PointerType>()->getPointeeType();
23040b57cec5SDimitry Andric   }
23050b57cec5SDimitry Andric 
getAllocatedTypeSourceInfo()23060b57cec5SDimitry Andric   TypeSourceInfo *getAllocatedTypeSourceInfo() const {
23070b57cec5SDimitry Andric     return AllocatedTypeInfo;
23080b57cec5SDimitry Andric   }
23090b57cec5SDimitry Andric 
23100b57cec5SDimitry Andric   /// True if the allocation result needs to be null-checked.
23110b57cec5SDimitry Andric   ///
23120b57cec5SDimitry Andric   /// C++11 [expr.new]p13:
23130b57cec5SDimitry Andric   ///   If the allocation function returns null, initialization shall
23140b57cec5SDimitry Andric   ///   not be done, the deallocation function shall not be called,
23150b57cec5SDimitry Andric   ///   and the value of the new-expression shall be null.
23160b57cec5SDimitry Andric   ///
23170b57cec5SDimitry Andric   /// C++ DR1748:
23180b57cec5SDimitry Andric   ///   If the allocation function is a reserved placement allocation
23190b57cec5SDimitry Andric   ///   function that returns null, the behavior is undefined.
23200b57cec5SDimitry Andric   ///
23210b57cec5SDimitry Andric   /// An allocation function is not allowed to return null unless it
23220b57cec5SDimitry Andric   /// has a non-throwing exception-specification.  The '03 rule is
23230b57cec5SDimitry Andric   /// identical except that the definition of a non-throwing
23240b57cec5SDimitry Andric   /// exception specification is just "is it throw()?".
23250b57cec5SDimitry Andric   bool shouldNullCheckAllocation() const;
23260b57cec5SDimitry Andric 
getOperatorNew()23270b57cec5SDimitry Andric   FunctionDecl *getOperatorNew() const { return OperatorNew; }
setOperatorNew(FunctionDecl * D)23280b57cec5SDimitry Andric   void setOperatorNew(FunctionDecl *D) { OperatorNew = D; }
getOperatorDelete()23290b57cec5SDimitry Andric   FunctionDecl *getOperatorDelete() const { return OperatorDelete; }
setOperatorDelete(FunctionDecl * D)23300b57cec5SDimitry Andric   void setOperatorDelete(FunctionDecl *D) { OperatorDelete = D; }
23310b57cec5SDimitry Andric 
isArray()23320b57cec5SDimitry Andric   bool isArray() const { return CXXNewExprBits.IsArray; }
23330b57cec5SDimitry Andric 
2334bdd1243dSDimitry Andric   /// This might return std::nullopt even if isArray() returns true,
233581ad6265SDimitry Andric   /// since there might not be an array size expression.
233606c3fb27SDimitry Andric   /// If the result is not std::nullopt, it will never wrap a nullptr.
getArraySize()2337bdd1243dSDimitry Andric   std::optional<Expr *> getArraySize() {
23380b57cec5SDimitry Andric     if (!isArray())
2339bdd1243dSDimitry Andric       return std::nullopt;
234081ad6265SDimitry Andric 
234181ad6265SDimitry Andric     if (auto *Result =
234281ad6265SDimitry Andric             cast_or_null<Expr>(getTrailingObjects<Stmt *>()[arraySizeOffset()]))
234381ad6265SDimitry Andric       return Result;
234481ad6265SDimitry Andric 
2345bdd1243dSDimitry Andric     return std::nullopt;
23460b57cec5SDimitry Andric   }
234781ad6265SDimitry Andric 
2348bdd1243dSDimitry Andric   /// This might return std::nullopt even if isArray() returns true,
234981ad6265SDimitry Andric   /// since there might not be an array size expression.
235006c3fb27SDimitry Andric   /// If the result is not std::nullopt, it will never wrap a nullptr.
getArraySize()2351bdd1243dSDimitry Andric   std::optional<const Expr *> getArraySize() const {
23520b57cec5SDimitry Andric     if (!isArray())
2353bdd1243dSDimitry Andric       return std::nullopt;
235481ad6265SDimitry Andric 
235581ad6265SDimitry Andric     if (auto *Result =
235681ad6265SDimitry Andric             cast_or_null<Expr>(getTrailingObjects<Stmt *>()[arraySizeOffset()]))
235781ad6265SDimitry Andric       return Result;
235881ad6265SDimitry Andric 
2359bdd1243dSDimitry Andric     return std::nullopt;
23600b57cec5SDimitry Andric   }
23610b57cec5SDimitry Andric 
getNumPlacementArgs()23620b57cec5SDimitry Andric   unsigned getNumPlacementArgs() const {
23630b57cec5SDimitry Andric     return CXXNewExprBits.NumPlacementArgs;
23640b57cec5SDimitry Andric   }
23650b57cec5SDimitry Andric 
getPlacementArgs()23660b57cec5SDimitry Andric   Expr **getPlacementArgs() {
23670b57cec5SDimitry Andric     return reinterpret_cast<Expr **>(getTrailingObjects<Stmt *>() +
23680b57cec5SDimitry Andric                                      placementNewArgsOffset());
23690b57cec5SDimitry Andric   }
23700b57cec5SDimitry Andric 
getPlacementArg(unsigned I)23710b57cec5SDimitry Andric   Expr *getPlacementArg(unsigned I) {
23720b57cec5SDimitry Andric     assert((I < getNumPlacementArgs()) && "Index out of range!");
23730b57cec5SDimitry Andric     return getPlacementArgs()[I];
23740b57cec5SDimitry Andric   }
getPlacementArg(unsigned I)23750b57cec5SDimitry Andric   const Expr *getPlacementArg(unsigned I) const {
23760b57cec5SDimitry Andric     return const_cast<CXXNewExpr *>(this)->getPlacementArg(I);
23770b57cec5SDimitry Andric   }
23780b57cec5SDimitry Andric 
isParenTypeId()23790b57cec5SDimitry Andric   bool isParenTypeId() const { return CXXNewExprBits.IsParenTypeId; }
getTypeIdParens()23800b57cec5SDimitry Andric   SourceRange getTypeIdParens() const {
23810b57cec5SDimitry Andric     return isParenTypeId() ? getTrailingObjects<SourceRange>()[0]
23820b57cec5SDimitry Andric                            : SourceRange();
23830b57cec5SDimitry Andric   }
23840b57cec5SDimitry Andric 
isGlobalNew()23850b57cec5SDimitry Andric   bool isGlobalNew() const { return CXXNewExprBits.IsGlobalNew; }
23860b57cec5SDimitry Andric 
23870b57cec5SDimitry Andric   /// Whether this new-expression has any initializer at all.
hasInitializer()23887a6dacacSDimitry Andric   bool hasInitializer() const { return CXXNewExprBits.HasInitializer; }
23890b57cec5SDimitry Andric 
23900b57cec5SDimitry Andric   /// The kind of initializer this new-expression has.
getInitializationStyle()23915f757f3fSDimitry Andric   CXXNewInitializationStyle getInitializationStyle() const {
23925f757f3fSDimitry Andric     return static_cast<CXXNewInitializationStyle>(
23935f757f3fSDimitry Andric         CXXNewExprBits.StoredInitializationStyle);
23940b57cec5SDimitry Andric   }
23950b57cec5SDimitry Andric 
23960b57cec5SDimitry Andric   /// The initializer of this new-expression.
getInitializer()23970b57cec5SDimitry Andric   Expr *getInitializer() {
23980b57cec5SDimitry Andric     return hasInitializer()
23990b57cec5SDimitry Andric                ? cast<Expr>(getTrailingObjects<Stmt *>()[initExprOffset()])
24000b57cec5SDimitry Andric                : nullptr;
24010b57cec5SDimitry Andric   }
getInitializer()24020b57cec5SDimitry Andric   const Expr *getInitializer() const {
24030b57cec5SDimitry Andric     return hasInitializer()
24040b57cec5SDimitry Andric                ? cast<Expr>(getTrailingObjects<Stmt *>()[initExprOffset()])
24050b57cec5SDimitry Andric                : nullptr;
24060b57cec5SDimitry Andric   }
24070b57cec5SDimitry Andric 
24080b57cec5SDimitry Andric   /// Returns the CXXConstructExpr from this new-expression, or null.
getConstructExpr()24090b57cec5SDimitry Andric   const CXXConstructExpr *getConstructExpr() const {
24100b57cec5SDimitry Andric     return dyn_cast_or_null<CXXConstructExpr>(getInitializer());
24110b57cec5SDimitry Andric   }
24120b57cec5SDimitry Andric 
24130b57cec5SDimitry Andric   /// Indicates whether the required alignment should be implicitly passed to
24140b57cec5SDimitry Andric   /// the allocation function.
passAlignment()24150b57cec5SDimitry Andric   bool passAlignment() const { return CXXNewExprBits.ShouldPassAlignment; }
24160b57cec5SDimitry Andric 
24170b57cec5SDimitry Andric   /// Answers whether the usual array deallocation function for the
24180b57cec5SDimitry Andric   /// allocated type expects the size of the allocation as a
24190b57cec5SDimitry Andric   /// parameter.
doesUsualArrayDeleteWantSize()24200b57cec5SDimitry Andric   bool doesUsualArrayDeleteWantSize() const {
24210b57cec5SDimitry Andric     return CXXNewExprBits.UsualArrayDeleteWantsSize;
24220b57cec5SDimitry Andric   }
24230b57cec5SDimitry Andric 
24240b57cec5SDimitry Andric   using arg_iterator = ExprIterator;
24250b57cec5SDimitry Andric   using const_arg_iterator = ConstExprIterator;
24260b57cec5SDimitry Andric 
placement_arguments()24270b57cec5SDimitry Andric   llvm::iterator_range<arg_iterator> placement_arguments() {
24280b57cec5SDimitry Andric     return llvm::make_range(placement_arg_begin(), placement_arg_end());
24290b57cec5SDimitry Andric   }
24300b57cec5SDimitry Andric 
placement_arguments()24310b57cec5SDimitry Andric   llvm::iterator_range<const_arg_iterator> placement_arguments() const {
24320b57cec5SDimitry Andric     return llvm::make_range(placement_arg_begin(), placement_arg_end());
24330b57cec5SDimitry Andric   }
24340b57cec5SDimitry Andric 
placement_arg_begin()24350b57cec5SDimitry Andric   arg_iterator placement_arg_begin() {
24360b57cec5SDimitry Andric     return getTrailingObjects<Stmt *>() + placementNewArgsOffset();
24370b57cec5SDimitry Andric   }
placement_arg_end()24380b57cec5SDimitry Andric   arg_iterator placement_arg_end() {
24390b57cec5SDimitry Andric     return placement_arg_begin() + getNumPlacementArgs();
24400b57cec5SDimitry Andric   }
placement_arg_begin()24410b57cec5SDimitry Andric   const_arg_iterator placement_arg_begin() const {
24420b57cec5SDimitry Andric     return getTrailingObjects<Stmt *>() + placementNewArgsOffset();
24430b57cec5SDimitry Andric   }
placement_arg_end()24440b57cec5SDimitry Andric   const_arg_iterator placement_arg_end() const {
24450b57cec5SDimitry Andric     return placement_arg_begin() + getNumPlacementArgs();
24460b57cec5SDimitry Andric   }
24470b57cec5SDimitry Andric 
24480b57cec5SDimitry Andric   using raw_arg_iterator = Stmt **;
24490b57cec5SDimitry Andric 
raw_arg_begin()24500b57cec5SDimitry Andric   raw_arg_iterator raw_arg_begin() { return getTrailingObjects<Stmt *>(); }
raw_arg_end()24510b57cec5SDimitry Andric   raw_arg_iterator raw_arg_end() {
24520b57cec5SDimitry Andric     return raw_arg_begin() + numTrailingObjects(OverloadToken<Stmt *>());
24530b57cec5SDimitry Andric   }
raw_arg_begin()24540b57cec5SDimitry Andric   const_arg_iterator raw_arg_begin() const {
24550b57cec5SDimitry Andric     return getTrailingObjects<Stmt *>();
24560b57cec5SDimitry Andric   }
raw_arg_end()24570b57cec5SDimitry Andric   const_arg_iterator raw_arg_end() const {
24580b57cec5SDimitry Andric     return raw_arg_begin() + numTrailingObjects(OverloadToken<Stmt *>());
24590b57cec5SDimitry Andric   }
24600b57cec5SDimitry Andric 
getBeginLoc()24610b57cec5SDimitry Andric   SourceLocation getBeginLoc() const { return Range.getBegin(); }
getEndLoc()24620b57cec5SDimitry Andric   SourceLocation getEndLoc() const { return Range.getEnd(); }
24630b57cec5SDimitry Andric 
getDirectInitRange()24640b57cec5SDimitry Andric   SourceRange getDirectInitRange() const { return DirectInitRange; }
getSourceRange()24650b57cec5SDimitry Andric   SourceRange getSourceRange() const { return Range; }
24660b57cec5SDimitry Andric 
classof(const Stmt * T)24670b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
24680b57cec5SDimitry Andric     return T->getStmtClass() == CXXNewExprClass;
24690b57cec5SDimitry Andric   }
24700b57cec5SDimitry Andric 
24710b57cec5SDimitry Andric   // Iterators
children()24720b57cec5SDimitry Andric   child_range children() { return child_range(raw_arg_begin(), raw_arg_end()); }
24730b57cec5SDimitry Andric 
children()24740b57cec5SDimitry Andric   const_child_range children() const {
24750b57cec5SDimitry Andric     return const_child_range(const_cast<CXXNewExpr *>(this)->children());
24760b57cec5SDimitry Andric   }
24770b57cec5SDimitry Andric };
24780b57cec5SDimitry Andric 
24790b57cec5SDimitry Andric /// Represents a \c delete expression for memory deallocation and
24800b57cec5SDimitry Andric /// destructor calls, e.g. "delete[] pArray".
24810b57cec5SDimitry Andric class CXXDeleteExpr : public Expr {
24820b57cec5SDimitry Andric   friend class ASTStmtReader;
24830b57cec5SDimitry Andric 
24840b57cec5SDimitry Andric   /// Points to the operator delete overload that is used. Could be a member.
24850b57cec5SDimitry Andric   FunctionDecl *OperatorDelete = nullptr;
24860b57cec5SDimitry Andric 
24870b57cec5SDimitry Andric   /// The pointer expression to be deleted.
24880b57cec5SDimitry Andric   Stmt *Argument = nullptr;
24890b57cec5SDimitry Andric 
24900b57cec5SDimitry Andric public:
CXXDeleteExpr(QualType Ty,bool GlobalDelete,bool ArrayForm,bool ArrayFormAsWritten,bool UsualArrayDeleteWantsSize,FunctionDecl * OperatorDelete,Expr * Arg,SourceLocation Loc)24910b57cec5SDimitry Andric   CXXDeleteExpr(QualType Ty, bool GlobalDelete, bool ArrayForm,
24920b57cec5SDimitry Andric                 bool ArrayFormAsWritten, bool UsualArrayDeleteWantsSize,
24930b57cec5SDimitry Andric                 FunctionDecl *OperatorDelete, Expr *Arg, SourceLocation Loc)
2494fe6060f1SDimitry Andric       : Expr(CXXDeleteExprClass, Ty, VK_PRValue, OK_Ordinary),
24950b57cec5SDimitry Andric         OperatorDelete(OperatorDelete), Argument(Arg) {
24960b57cec5SDimitry Andric     CXXDeleteExprBits.GlobalDelete = GlobalDelete;
24970b57cec5SDimitry Andric     CXXDeleteExprBits.ArrayForm = ArrayForm;
24980b57cec5SDimitry Andric     CXXDeleteExprBits.ArrayFormAsWritten = ArrayFormAsWritten;
24990b57cec5SDimitry Andric     CXXDeleteExprBits.UsualArrayDeleteWantsSize = UsualArrayDeleteWantsSize;
25000b57cec5SDimitry Andric     CXXDeleteExprBits.Loc = Loc;
25015ffd83dbSDimitry Andric     setDependence(computeDependence(this));
25020b57cec5SDimitry Andric   }
25030b57cec5SDimitry Andric 
CXXDeleteExpr(EmptyShell Shell)25040b57cec5SDimitry Andric   explicit CXXDeleteExpr(EmptyShell Shell) : Expr(CXXDeleteExprClass, Shell) {}
25050b57cec5SDimitry Andric 
isGlobalDelete()25060b57cec5SDimitry Andric   bool isGlobalDelete() const { return CXXDeleteExprBits.GlobalDelete; }
isArrayForm()25070b57cec5SDimitry Andric   bool isArrayForm() const { return CXXDeleteExprBits.ArrayForm; }
isArrayFormAsWritten()25080b57cec5SDimitry Andric   bool isArrayFormAsWritten() const {
25090b57cec5SDimitry Andric     return CXXDeleteExprBits.ArrayFormAsWritten;
25100b57cec5SDimitry Andric   }
25110b57cec5SDimitry Andric 
25120b57cec5SDimitry Andric   /// Answers whether the usual array deallocation function for the
25130b57cec5SDimitry Andric   /// allocated type expects the size of the allocation as a
25140b57cec5SDimitry Andric   /// parameter.  This can be true even if the actual deallocation
25150b57cec5SDimitry Andric   /// function that we're using doesn't want a size.
doesUsualArrayDeleteWantSize()25160b57cec5SDimitry Andric   bool doesUsualArrayDeleteWantSize() const {
25170b57cec5SDimitry Andric     return CXXDeleteExprBits.UsualArrayDeleteWantsSize;
25180b57cec5SDimitry Andric   }
25190b57cec5SDimitry Andric 
getOperatorDelete()25200b57cec5SDimitry Andric   FunctionDecl *getOperatorDelete() const { return OperatorDelete; }
25210b57cec5SDimitry Andric 
getArgument()25220b57cec5SDimitry Andric   Expr *getArgument() { return cast<Expr>(Argument); }
getArgument()25230b57cec5SDimitry Andric   const Expr *getArgument() const { return cast<Expr>(Argument); }
25240b57cec5SDimitry Andric 
25250b57cec5SDimitry Andric   /// Retrieve the type being destroyed.
25260b57cec5SDimitry Andric   ///
25270b57cec5SDimitry Andric   /// If the type being destroyed is a dependent type which may or may not
25280b57cec5SDimitry Andric   /// be a pointer, return an invalid type.
25290b57cec5SDimitry Andric   QualType getDestroyedType() const;
25300b57cec5SDimitry Andric 
getBeginLoc()25310b57cec5SDimitry Andric   SourceLocation getBeginLoc() const { return CXXDeleteExprBits.Loc; }
getEndLoc()25320b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY {
25330b57cec5SDimitry Andric     return Argument->getEndLoc();
25340b57cec5SDimitry Andric   }
25350b57cec5SDimitry Andric 
classof(const Stmt * T)25360b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
25370b57cec5SDimitry Andric     return T->getStmtClass() == CXXDeleteExprClass;
25380b57cec5SDimitry Andric   }
25390b57cec5SDimitry Andric 
25400b57cec5SDimitry Andric   // Iterators
children()25410b57cec5SDimitry Andric   child_range children() { return child_range(&Argument, &Argument + 1); }
25420b57cec5SDimitry Andric 
children()25430b57cec5SDimitry Andric   const_child_range children() const {
25440b57cec5SDimitry Andric     return const_child_range(&Argument, &Argument + 1);
25450b57cec5SDimitry Andric   }
25460b57cec5SDimitry Andric };
25470b57cec5SDimitry Andric 
25480b57cec5SDimitry Andric /// Stores the type being destroyed by a pseudo-destructor expression.
25490b57cec5SDimitry Andric class PseudoDestructorTypeStorage {
25500b57cec5SDimitry Andric   /// Either the type source information or the name of the type, if
25510b57cec5SDimitry Andric   /// it couldn't be resolved due to type-dependence.
25520b57cec5SDimitry Andric   llvm::PointerUnion<TypeSourceInfo *, IdentifierInfo *> Type;
25530b57cec5SDimitry Andric 
25540b57cec5SDimitry Andric   /// The starting source location of the pseudo-destructor type.
25550b57cec5SDimitry Andric   SourceLocation Location;
25560b57cec5SDimitry Andric 
25570b57cec5SDimitry Andric public:
25580b57cec5SDimitry Andric   PseudoDestructorTypeStorage() = default;
25590b57cec5SDimitry Andric 
PseudoDestructorTypeStorage(IdentifierInfo * II,SourceLocation Loc)25600b57cec5SDimitry Andric   PseudoDestructorTypeStorage(IdentifierInfo *II, SourceLocation Loc)
25610b57cec5SDimitry Andric       : Type(II), Location(Loc) {}
25620b57cec5SDimitry Andric 
25630b57cec5SDimitry Andric   PseudoDestructorTypeStorage(TypeSourceInfo *Info);
25640b57cec5SDimitry Andric 
getTypeSourceInfo()25650b57cec5SDimitry Andric   TypeSourceInfo *getTypeSourceInfo() const {
25660b57cec5SDimitry Andric     return Type.dyn_cast<TypeSourceInfo *>();
25670b57cec5SDimitry Andric   }
25680b57cec5SDimitry Andric 
getIdentifier()25690b57cec5SDimitry Andric   IdentifierInfo *getIdentifier() const {
25700b57cec5SDimitry Andric     return Type.dyn_cast<IdentifierInfo *>();
25710b57cec5SDimitry Andric   }
25720b57cec5SDimitry Andric 
getLocation()25730b57cec5SDimitry Andric   SourceLocation getLocation() const { return Location; }
25740b57cec5SDimitry Andric };
25750b57cec5SDimitry Andric 
25760b57cec5SDimitry Andric /// Represents a C++ pseudo-destructor (C++ [expr.pseudo]).
25770b57cec5SDimitry Andric ///
25780b57cec5SDimitry Andric /// A pseudo-destructor is an expression that looks like a member access to a
25790b57cec5SDimitry Andric /// destructor of a scalar type, except that scalar types don't have
25800b57cec5SDimitry Andric /// destructors. For example:
25810b57cec5SDimitry Andric ///
25820b57cec5SDimitry Andric /// \code
25830b57cec5SDimitry Andric /// typedef int T;
25840b57cec5SDimitry Andric /// void f(int *p) {
25850b57cec5SDimitry Andric ///   p->T::~T();
25860b57cec5SDimitry Andric /// }
25870b57cec5SDimitry Andric /// \endcode
25880b57cec5SDimitry Andric ///
25890b57cec5SDimitry Andric /// Pseudo-destructors typically occur when instantiating templates such as:
25900b57cec5SDimitry Andric ///
25910b57cec5SDimitry Andric /// \code
25920b57cec5SDimitry Andric /// template<typename T>
25930b57cec5SDimitry Andric /// void destroy(T* ptr) {
25940b57cec5SDimitry Andric ///   ptr->T::~T();
25950b57cec5SDimitry Andric /// }
25960b57cec5SDimitry Andric /// \endcode
25970b57cec5SDimitry Andric ///
25980b57cec5SDimitry Andric /// for scalar types. A pseudo-destructor expression has no run-time semantics
25990b57cec5SDimitry Andric /// beyond evaluating the base expression.
26000b57cec5SDimitry Andric class CXXPseudoDestructorExpr : public Expr {
26010b57cec5SDimitry Andric   friend class ASTStmtReader;
26020b57cec5SDimitry Andric 
26030b57cec5SDimitry Andric   /// The base expression (that is being destroyed).
26040b57cec5SDimitry Andric   Stmt *Base = nullptr;
26050b57cec5SDimitry Andric 
26060b57cec5SDimitry Andric   /// Whether the operator was an arrow ('->'); otherwise, it was a
26070b57cec5SDimitry Andric   /// period ('.').
26085f757f3fSDimitry Andric   LLVM_PREFERRED_TYPE(bool)
26090b57cec5SDimitry Andric   bool IsArrow : 1;
26100b57cec5SDimitry Andric 
26110b57cec5SDimitry Andric   /// The location of the '.' or '->' operator.
26120b57cec5SDimitry Andric   SourceLocation OperatorLoc;
26130b57cec5SDimitry Andric 
26140b57cec5SDimitry Andric   /// The nested-name-specifier that follows the operator, if present.
26150b57cec5SDimitry Andric   NestedNameSpecifierLoc QualifierLoc;
26160b57cec5SDimitry Andric 
26170b57cec5SDimitry Andric   /// The type that precedes the '::' in a qualified pseudo-destructor
26180b57cec5SDimitry Andric   /// expression.
26190b57cec5SDimitry Andric   TypeSourceInfo *ScopeType = nullptr;
26200b57cec5SDimitry Andric 
26210b57cec5SDimitry Andric   /// The location of the '::' in a qualified pseudo-destructor
26220b57cec5SDimitry Andric   /// expression.
26230b57cec5SDimitry Andric   SourceLocation ColonColonLoc;
26240b57cec5SDimitry Andric 
26250b57cec5SDimitry Andric   /// The location of the '~'.
26260b57cec5SDimitry Andric   SourceLocation TildeLoc;
26270b57cec5SDimitry Andric 
26280b57cec5SDimitry Andric   /// The type being destroyed, or its name if we were unable to
26290b57cec5SDimitry Andric   /// resolve the name.
26300b57cec5SDimitry Andric   PseudoDestructorTypeStorage DestroyedType;
26310b57cec5SDimitry Andric 
26320b57cec5SDimitry Andric public:
26330b57cec5SDimitry Andric   CXXPseudoDestructorExpr(const ASTContext &Context,
26340b57cec5SDimitry Andric                           Expr *Base, bool isArrow, SourceLocation OperatorLoc,
26350b57cec5SDimitry Andric                           NestedNameSpecifierLoc QualifierLoc,
26360b57cec5SDimitry Andric                           TypeSourceInfo *ScopeType,
26370b57cec5SDimitry Andric                           SourceLocation ColonColonLoc,
26380b57cec5SDimitry Andric                           SourceLocation TildeLoc,
26390b57cec5SDimitry Andric                           PseudoDestructorTypeStorage DestroyedType);
26400b57cec5SDimitry Andric 
CXXPseudoDestructorExpr(EmptyShell Shell)26410b57cec5SDimitry Andric   explicit CXXPseudoDestructorExpr(EmptyShell Shell)
26420b57cec5SDimitry Andric       : Expr(CXXPseudoDestructorExprClass, Shell), IsArrow(false) {}
26430b57cec5SDimitry Andric 
getBase()26440b57cec5SDimitry Andric   Expr *getBase() const { return cast<Expr>(Base); }
26450b57cec5SDimitry Andric 
26460b57cec5SDimitry Andric   /// Determines whether this member expression actually had
26470b57cec5SDimitry Andric   /// a C++ nested-name-specifier prior to the name of the member, e.g.,
26480b57cec5SDimitry Andric   /// x->Base::foo.
hasQualifier()26490b57cec5SDimitry Andric   bool hasQualifier() const { return QualifierLoc.hasQualifier(); }
26500b57cec5SDimitry Andric 
26510b57cec5SDimitry Andric   /// Retrieves the nested-name-specifier that qualifies the type name,
26520b57cec5SDimitry Andric   /// with source-location information.
getQualifierLoc()26530b57cec5SDimitry Andric   NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
26540b57cec5SDimitry Andric 
26550b57cec5SDimitry Andric   /// If the member name was qualified, retrieves the
26560b57cec5SDimitry Andric   /// nested-name-specifier that precedes the member name. Otherwise, returns
26570b57cec5SDimitry Andric   /// null.
getQualifier()26580b57cec5SDimitry Andric   NestedNameSpecifier *getQualifier() const {
26590b57cec5SDimitry Andric     return QualifierLoc.getNestedNameSpecifier();
26600b57cec5SDimitry Andric   }
26610b57cec5SDimitry Andric 
26620b57cec5SDimitry Andric   /// Determine whether this pseudo-destructor expression was written
26630b57cec5SDimitry Andric   /// using an '->' (otherwise, it used a '.').
isArrow()26640b57cec5SDimitry Andric   bool isArrow() const { return IsArrow; }
26650b57cec5SDimitry Andric 
26660b57cec5SDimitry Andric   /// Retrieve the location of the '.' or '->' operator.
getOperatorLoc()26670b57cec5SDimitry Andric   SourceLocation getOperatorLoc() const { return OperatorLoc; }
26680b57cec5SDimitry Andric 
26690b57cec5SDimitry Andric   /// Retrieve the scope type in a qualified pseudo-destructor
26700b57cec5SDimitry Andric   /// expression.
26710b57cec5SDimitry Andric   ///
26720b57cec5SDimitry Andric   /// Pseudo-destructor expressions can have extra qualification within them
26730b57cec5SDimitry Andric   /// that is not part of the nested-name-specifier, e.g., \c p->T::~T().
26740b57cec5SDimitry Andric   /// Here, if the object type of the expression is (or may be) a scalar type,
26750b57cec5SDimitry Andric   /// \p T may also be a scalar type and, therefore, cannot be part of a
26760b57cec5SDimitry Andric   /// nested-name-specifier. It is stored as the "scope type" of the pseudo-
26770b57cec5SDimitry Andric   /// destructor expression.
getScopeTypeInfo()26780b57cec5SDimitry Andric   TypeSourceInfo *getScopeTypeInfo() const { return ScopeType; }
26790b57cec5SDimitry Andric 
26800b57cec5SDimitry Andric   /// Retrieve the location of the '::' in a qualified pseudo-destructor
26810b57cec5SDimitry Andric   /// expression.
getColonColonLoc()26820b57cec5SDimitry Andric   SourceLocation getColonColonLoc() const { return ColonColonLoc; }
26830b57cec5SDimitry Andric 
26840b57cec5SDimitry Andric   /// Retrieve the location of the '~'.
getTildeLoc()26850b57cec5SDimitry Andric   SourceLocation getTildeLoc() const { return TildeLoc; }
26860b57cec5SDimitry Andric 
26870b57cec5SDimitry Andric   /// Retrieve the source location information for the type
26880b57cec5SDimitry Andric   /// being destroyed.
26890b57cec5SDimitry Andric   ///
26900b57cec5SDimitry Andric   /// This type-source information is available for non-dependent
26910b57cec5SDimitry Andric   /// pseudo-destructor expressions and some dependent pseudo-destructor
26920b57cec5SDimitry Andric   /// expressions. Returns null if we only have the identifier for a
26930b57cec5SDimitry Andric   /// dependent pseudo-destructor expression.
getDestroyedTypeInfo()26940b57cec5SDimitry Andric   TypeSourceInfo *getDestroyedTypeInfo() const {
26950b57cec5SDimitry Andric     return DestroyedType.getTypeSourceInfo();
26960b57cec5SDimitry Andric   }
26970b57cec5SDimitry Andric 
26980b57cec5SDimitry Andric   /// In a dependent pseudo-destructor expression for which we do not
26990b57cec5SDimitry Andric   /// have full type information on the destroyed type, provides the name
27000b57cec5SDimitry Andric   /// of the destroyed type.
getDestroyedTypeIdentifier()27010b57cec5SDimitry Andric   IdentifierInfo *getDestroyedTypeIdentifier() const {
27020b57cec5SDimitry Andric     return DestroyedType.getIdentifier();
27030b57cec5SDimitry Andric   }
27040b57cec5SDimitry Andric 
27050b57cec5SDimitry Andric   /// Retrieve the type being destroyed.
27060b57cec5SDimitry Andric   QualType getDestroyedType() const;
27070b57cec5SDimitry Andric 
27080b57cec5SDimitry Andric   /// Retrieve the starting location of the type being destroyed.
getDestroyedTypeLoc()27090b57cec5SDimitry Andric   SourceLocation getDestroyedTypeLoc() const {
27100b57cec5SDimitry Andric     return DestroyedType.getLocation();
27110b57cec5SDimitry Andric   }
27120b57cec5SDimitry Andric 
27130b57cec5SDimitry Andric   /// Set the name of destroyed type for a dependent pseudo-destructor
27140b57cec5SDimitry Andric   /// expression.
setDestroyedType(IdentifierInfo * II,SourceLocation Loc)27150b57cec5SDimitry Andric   void setDestroyedType(IdentifierInfo *II, SourceLocation Loc) {
27160b57cec5SDimitry Andric     DestroyedType = PseudoDestructorTypeStorage(II, Loc);
27170b57cec5SDimitry Andric   }
27180b57cec5SDimitry Andric 
27190b57cec5SDimitry Andric   /// Set the destroyed type.
setDestroyedType(TypeSourceInfo * Info)27200b57cec5SDimitry Andric   void setDestroyedType(TypeSourceInfo *Info) {
27210b57cec5SDimitry Andric     DestroyedType = PseudoDestructorTypeStorage(Info);
27220b57cec5SDimitry Andric   }
27230b57cec5SDimitry Andric 
getBeginLoc()27240b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY {
27250b57cec5SDimitry Andric     return Base->getBeginLoc();
27260b57cec5SDimitry Andric   }
27270b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY;
27280b57cec5SDimitry Andric 
classof(const Stmt * T)27290b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
27300b57cec5SDimitry Andric     return T->getStmtClass() == CXXPseudoDestructorExprClass;
27310b57cec5SDimitry Andric   }
27320b57cec5SDimitry Andric 
27330b57cec5SDimitry Andric   // Iterators
children()27340b57cec5SDimitry Andric   child_range children() { return child_range(&Base, &Base + 1); }
27350b57cec5SDimitry Andric 
children()27360b57cec5SDimitry Andric   const_child_range children() const {
27370b57cec5SDimitry Andric     return const_child_range(&Base, &Base + 1);
27380b57cec5SDimitry Andric   }
27390b57cec5SDimitry Andric };
27400b57cec5SDimitry Andric 
27410b57cec5SDimitry Andric /// A type trait used in the implementation of various C++11 and
27420b57cec5SDimitry Andric /// Library TR1 trait templates.
27430b57cec5SDimitry Andric ///
27440b57cec5SDimitry Andric /// \code
27450b57cec5SDimitry Andric ///   __is_pod(int) == true
27460b57cec5SDimitry Andric ///   __is_enum(std::string) == false
27470b57cec5SDimitry Andric ///   __is_trivially_constructible(vector<int>, int*, int*)
27480b57cec5SDimitry Andric /// \endcode
27490b57cec5SDimitry Andric class TypeTraitExpr final
27500b57cec5SDimitry Andric     : public Expr,
27510b57cec5SDimitry Andric       private llvm::TrailingObjects<TypeTraitExpr, TypeSourceInfo *> {
27520b57cec5SDimitry Andric   /// The location of the type trait keyword.
27530b57cec5SDimitry Andric   SourceLocation Loc;
27540b57cec5SDimitry Andric 
27550b57cec5SDimitry Andric   ///  The location of the closing parenthesis.
27560b57cec5SDimitry Andric   SourceLocation RParenLoc;
27570b57cec5SDimitry Andric 
27580b57cec5SDimitry Andric   // Note: The TypeSourceInfos for the arguments are allocated after the
27590b57cec5SDimitry Andric   // TypeTraitExpr.
27600b57cec5SDimitry Andric 
27610b57cec5SDimitry Andric   TypeTraitExpr(QualType T, SourceLocation Loc, TypeTrait Kind,
27620b57cec5SDimitry Andric                 ArrayRef<TypeSourceInfo *> Args,
27630b57cec5SDimitry Andric                 SourceLocation RParenLoc,
27640b57cec5SDimitry Andric                 bool Value);
27650b57cec5SDimitry Andric 
TypeTraitExpr(EmptyShell Empty)27660b57cec5SDimitry Andric   TypeTraitExpr(EmptyShell Empty) : Expr(TypeTraitExprClass, Empty) {}
27670b57cec5SDimitry Andric 
numTrailingObjects(OverloadToken<TypeSourceInfo * >)27680b57cec5SDimitry Andric   size_t numTrailingObjects(OverloadToken<TypeSourceInfo *>) const {
27690b57cec5SDimitry Andric     return getNumArgs();
27700b57cec5SDimitry Andric   }
27710b57cec5SDimitry Andric 
27720b57cec5SDimitry Andric public:
27730b57cec5SDimitry Andric   friend class ASTStmtReader;
27740b57cec5SDimitry Andric   friend class ASTStmtWriter;
27750b57cec5SDimitry Andric   friend TrailingObjects;
27760b57cec5SDimitry Andric 
27770b57cec5SDimitry Andric   /// Create a new type trait expression.
27780b57cec5SDimitry Andric   static TypeTraitExpr *Create(const ASTContext &C, QualType T,
27790b57cec5SDimitry Andric                                SourceLocation Loc, TypeTrait Kind,
27800b57cec5SDimitry Andric                                ArrayRef<TypeSourceInfo *> Args,
27810b57cec5SDimitry Andric                                SourceLocation RParenLoc,
27820b57cec5SDimitry Andric                                bool Value);
27830b57cec5SDimitry Andric 
27840b57cec5SDimitry Andric   static TypeTraitExpr *CreateDeserialized(const ASTContext &C,
27850b57cec5SDimitry Andric                                            unsigned NumArgs);
27860b57cec5SDimitry Andric 
27870b57cec5SDimitry Andric   /// Determine which type trait this expression uses.
getTrait()27880b57cec5SDimitry Andric   TypeTrait getTrait() const {
27890b57cec5SDimitry Andric     return static_cast<TypeTrait>(TypeTraitExprBits.Kind);
27900b57cec5SDimitry Andric   }
27910b57cec5SDimitry Andric 
getValue()27920b57cec5SDimitry Andric   bool getValue() const {
27930b57cec5SDimitry Andric     assert(!isValueDependent());
27940b57cec5SDimitry Andric     return TypeTraitExprBits.Value;
27950b57cec5SDimitry Andric   }
27960b57cec5SDimitry Andric 
27970b57cec5SDimitry Andric   /// Determine the number of arguments to this type trait.
getNumArgs()27980b57cec5SDimitry Andric   unsigned getNumArgs() const { return TypeTraitExprBits.NumArgs; }
27990b57cec5SDimitry Andric 
28000b57cec5SDimitry Andric   /// Retrieve the Ith argument.
getArg(unsigned I)28010b57cec5SDimitry Andric   TypeSourceInfo *getArg(unsigned I) const {
28020b57cec5SDimitry Andric     assert(I < getNumArgs() && "Argument out-of-range");
28030b57cec5SDimitry Andric     return getArgs()[I];
28040b57cec5SDimitry Andric   }
28050b57cec5SDimitry Andric 
28060b57cec5SDimitry Andric   /// Retrieve the argument types.
getArgs()28070b57cec5SDimitry Andric   ArrayRef<TypeSourceInfo *> getArgs() const {
2808bdd1243dSDimitry Andric     return llvm::ArrayRef(getTrailingObjects<TypeSourceInfo *>(), getNumArgs());
28090b57cec5SDimitry Andric   }
28100b57cec5SDimitry Andric 
getBeginLoc()28110b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; }
getEndLoc()28120b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
28130b57cec5SDimitry Andric 
classof(const Stmt * T)28140b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
28150b57cec5SDimitry Andric     return T->getStmtClass() == TypeTraitExprClass;
28160b57cec5SDimitry Andric   }
28170b57cec5SDimitry Andric 
28180b57cec5SDimitry Andric   // Iterators
children()28190b57cec5SDimitry Andric   child_range children() {
28200b57cec5SDimitry Andric     return child_range(child_iterator(), child_iterator());
28210b57cec5SDimitry Andric   }
28220b57cec5SDimitry Andric 
children()28230b57cec5SDimitry Andric   const_child_range children() const {
28240b57cec5SDimitry Andric     return const_child_range(const_child_iterator(), const_child_iterator());
28250b57cec5SDimitry Andric   }
28260b57cec5SDimitry Andric };
28270b57cec5SDimitry Andric 
28280b57cec5SDimitry Andric /// An Embarcadero array type trait, as used in the implementation of
28290b57cec5SDimitry Andric /// __array_rank and __array_extent.
28300b57cec5SDimitry Andric ///
28310b57cec5SDimitry Andric /// Example:
28320b57cec5SDimitry Andric /// \code
28330b57cec5SDimitry Andric ///   __array_rank(int[10][20]) == 2
28340b57cec5SDimitry Andric ///   __array_extent(int, 1)    == 20
28350b57cec5SDimitry Andric /// \endcode
28360b57cec5SDimitry Andric class ArrayTypeTraitExpr : public Expr {
28370b57cec5SDimitry Andric   /// The trait. An ArrayTypeTrait enum in MSVC compat unsigned.
28385f757f3fSDimitry Andric   LLVM_PREFERRED_TYPE(ArrayTypeTrait)
28390b57cec5SDimitry Andric   unsigned ATT : 2;
28400b57cec5SDimitry Andric 
28410b57cec5SDimitry Andric   /// The value of the type trait. Unspecified if dependent.
28420b57cec5SDimitry Andric   uint64_t Value = 0;
28430b57cec5SDimitry Andric 
28440b57cec5SDimitry Andric   /// The array dimension being queried, or -1 if not used.
28450b57cec5SDimitry Andric   Expr *Dimension;
28460b57cec5SDimitry Andric 
28470b57cec5SDimitry Andric   /// The location of the type trait keyword.
28480b57cec5SDimitry Andric   SourceLocation Loc;
28490b57cec5SDimitry Andric 
28500b57cec5SDimitry Andric   /// The location of the closing paren.
28510b57cec5SDimitry Andric   SourceLocation RParen;
28520b57cec5SDimitry Andric 
28530b57cec5SDimitry Andric   /// The type being queried.
28540b57cec5SDimitry Andric   TypeSourceInfo *QueriedType = nullptr;
28550b57cec5SDimitry Andric 
28560b57cec5SDimitry Andric public:
28570b57cec5SDimitry Andric   friend class ASTStmtReader;
28580b57cec5SDimitry Andric 
ArrayTypeTraitExpr(SourceLocation loc,ArrayTypeTrait att,TypeSourceInfo * queried,uint64_t value,Expr * dimension,SourceLocation rparen,QualType ty)28590b57cec5SDimitry Andric   ArrayTypeTraitExpr(SourceLocation loc, ArrayTypeTrait att,
28605ffd83dbSDimitry Andric                      TypeSourceInfo *queried, uint64_t value, Expr *dimension,
28615ffd83dbSDimitry Andric                      SourceLocation rparen, QualType ty)
2862fe6060f1SDimitry Andric       : Expr(ArrayTypeTraitExprClass, ty, VK_PRValue, OK_Ordinary), ATT(att),
28635ffd83dbSDimitry Andric         Value(value), Dimension(dimension), Loc(loc), RParen(rparen),
28645ffd83dbSDimitry Andric         QueriedType(queried) {
28655ffd83dbSDimitry Andric     assert(att <= ATT_Last && "invalid enum value!");
28665ffd83dbSDimitry Andric     assert(static_cast<unsigned>(att) == ATT && "ATT overflow!");
28675ffd83dbSDimitry Andric     setDependence(computeDependence(this));
28685ffd83dbSDimitry Andric   }
28690b57cec5SDimitry Andric 
ArrayTypeTraitExpr(EmptyShell Empty)28700b57cec5SDimitry Andric   explicit ArrayTypeTraitExpr(EmptyShell Empty)
28710b57cec5SDimitry Andric       : Expr(ArrayTypeTraitExprClass, Empty), ATT(0) {}
28720b57cec5SDimitry Andric 
getBeginLoc()28730b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; }
getEndLoc()28740b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY { return RParen; }
28750b57cec5SDimitry Andric 
getTrait()28760b57cec5SDimitry Andric   ArrayTypeTrait getTrait() const { return static_cast<ArrayTypeTrait>(ATT); }
28770b57cec5SDimitry Andric 
getQueriedType()28780b57cec5SDimitry Andric   QualType getQueriedType() const { return QueriedType->getType(); }
28790b57cec5SDimitry Andric 
getQueriedTypeSourceInfo()28800b57cec5SDimitry Andric   TypeSourceInfo *getQueriedTypeSourceInfo() const { return QueriedType; }
28810b57cec5SDimitry Andric 
getValue()28820b57cec5SDimitry Andric   uint64_t getValue() const { assert(!isTypeDependent()); return Value; }
28830b57cec5SDimitry Andric 
getDimensionExpression()28840b57cec5SDimitry Andric   Expr *getDimensionExpression() const { return Dimension; }
28850b57cec5SDimitry Andric 
classof(const Stmt * T)28860b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
28870b57cec5SDimitry Andric     return T->getStmtClass() == ArrayTypeTraitExprClass;
28880b57cec5SDimitry Andric   }
28890b57cec5SDimitry Andric 
28900b57cec5SDimitry Andric   // Iterators
children()28910b57cec5SDimitry Andric   child_range children() {
28920b57cec5SDimitry Andric     return child_range(child_iterator(), child_iterator());
28930b57cec5SDimitry Andric   }
28940b57cec5SDimitry Andric 
children()28950b57cec5SDimitry Andric   const_child_range children() const {
28960b57cec5SDimitry Andric     return const_child_range(const_child_iterator(), const_child_iterator());
28970b57cec5SDimitry Andric   }
28980b57cec5SDimitry Andric };
28990b57cec5SDimitry Andric 
29000b57cec5SDimitry Andric /// An expression trait intrinsic.
29010b57cec5SDimitry Andric ///
29020b57cec5SDimitry Andric /// Example:
29030b57cec5SDimitry Andric /// \code
29040b57cec5SDimitry Andric ///   __is_lvalue_expr(std::cout) == true
29050b57cec5SDimitry Andric ///   __is_lvalue_expr(1) == false
29060b57cec5SDimitry Andric /// \endcode
29070b57cec5SDimitry Andric class ExpressionTraitExpr : public Expr {
29080b57cec5SDimitry Andric   /// The trait. A ExpressionTrait enum in MSVC compatible unsigned.
29095f757f3fSDimitry Andric   LLVM_PREFERRED_TYPE(ExpressionTrait)
29100b57cec5SDimitry Andric   unsigned ET : 31;
29110b57cec5SDimitry Andric 
29120b57cec5SDimitry Andric   /// The value of the type trait. Unspecified if dependent.
29135f757f3fSDimitry Andric   LLVM_PREFERRED_TYPE(bool)
29140b57cec5SDimitry Andric   unsigned Value : 1;
29150b57cec5SDimitry Andric 
29160b57cec5SDimitry Andric   /// The location of the type trait keyword.
29170b57cec5SDimitry Andric   SourceLocation Loc;
29180b57cec5SDimitry Andric 
29190b57cec5SDimitry Andric   /// The location of the closing paren.
29200b57cec5SDimitry Andric   SourceLocation RParen;
29210b57cec5SDimitry Andric 
29220b57cec5SDimitry Andric   /// The expression being queried.
29230b57cec5SDimitry Andric   Expr* QueriedExpression = nullptr;
29240b57cec5SDimitry Andric 
29250b57cec5SDimitry Andric public:
29260b57cec5SDimitry Andric   friend class ASTStmtReader;
29270b57cec5SDimitry Andric 
ExpressionTraitExpr(SourceLocation loc,ExpressionTrait et,Expr * queried,bool value,SourceLocation rparen,QualType resultType)29285ffd83dbSDimitry Andric   ExpressionTraitExpr(SourceLocation loc, ExpressionTrait et, Expr *queried,
29295ffd83dbSDimitry Andric                       bool value, SourceLocation rparen, QualType resultType)
2930fe6060f1SDimitry Andric       : Expr(ExpressionTraitExprClass, resultType, VK_PRValue, OK_Ordinary),
29310b57cec5SDimitry Andric         ET(et), Value(value), Loc(loc), RParen(rparen),
29325ffd83dbSDimitry Andric         QueriedExpression(queried) {
29335ffd83dbSDimitry Andric     assert(et <= ET_Last && "invalid enum value!");
29345ffd83dbSDimitry Andric     assert(static_cast<unsigned>(et) == ET && "ET overflow!");
29355ffd83dbSDimitry Andric     setDependence(computeDependence(this));
29365ffd83dbSDimitry Andric   }
29370b57cec5SDimitry Andric 
ExpressionTraitExpr(EmptyShell Empty)29380b57cec5SDimitry Andric   explicit ExpressionTraitExpr(EmptyShell Empty)
29390b57cec5SDimitry Andric       : Expr(ExpressionTraitExprClass, Empty), ET(0), Value(false) {}
29400b57cec5SDimitry Andric 
getBeginLoc()29410b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; }
getEndLoc()29420b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY { return RParen; }
29430b57cec5SDimitry Andric 
getTrait()29440b57cec5SDimitry Andric   ExpressionTrait getTrait() const { return static_cast<ExpressionTrait>(ET); }
29450b57cec5SDimitry Andric 
getQueriedExpression()29460b57cec5SDimitry Andric   Expr *getQueriedExpression() const { return QueriedExpression; }
29470b57cec5SDimitry Andric 
getValue()29480b57cec5SDimitry Andric   bool getValue() const { return Value; }
29490b57cec5SDimitry Andric 
classof(const Stmt * T)29500b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
29510b57cec5SDimitry Andric     return T->getStmtClass() == ExpressionTraitExprClass;
29520b57cec5SDimitry Andric   }
29530b57cec5SDimitry Andric 
29540b57cec5SDimitry Andric   // Iterators
children()29550b57cec5SDimitry Andric   child_range children() {
29560b57cec5SDimitry Andric     return child_range(child_iterator(), child_iterator());
29570b57cec5SDimitry Andric   }
29580b57cec5SDimitry Andric 
children()29590b57cec5SDimitry Andric   const_child_range children() const {
29600b57cec5SDimitry Andric     return const_child_range(const_child_iterator(), const_child_iterator());
29610b57cec5SDimitry Andric   }
29620b57cec5SDimitry Andric };
29630b57cec5SDimitry Andric 
29640b57cec5SDimitry Andric /// A reference to an overloaded function set, either an
29650b57cec5SDimitry Andric /// \c UnresolvedLookupExpr or an \c UnresolvedMemberExpr.
29660b57cec5SDimitry Andric class OverloadExpr : public Expr {
29670b57cec5SDimitry Andric   friend class ASTStmtReader;
29680b57cec5SDimitry Andric   friend class ASTStmtWriter;
29690b57cec5SDimitry Andric 
29700b57cec5SDimitry Andric   /// The common name of these declarations.
29710b57cec5SDimitry Andric   DeclarationNameInfo NameInfo;
29720b57cec5SDimitry Andric 
29730b57cec5SDimitry Andric   /// The nested-name-specifier that qualifies the name, if any.
29740b57cec5SDimitry Andric   NestedNameSpecifierLoc QualifierLoc;
29750b57cec5SDimitry Andric 
29760b57cec5SDimitry Andric protected:
29770b57cec5SDimitry Andric   OverloadExpr(StmtClass SC, const ASTContext &Context,
29780b57cec5SDimitry Andric                NestedNameSpecifierLoc QualifierLoc,
29790b57cec5SDimitry Andric                SourceLocation TemplateKWLoc,
29800b57cec5SDimitry Andric                const DeclarationNameInfo &NameInfo,
29810b57cec5SDimitry Andric                const TemplateArgumentListInfo *TemplateArgs,
29820b57cec5SDimitry Andric                UnresolvedSetIterator Begin, UnresolvedSetIterator End,
29830b57cec5SDimitry Andric                bool KnownDependent, bool KnownInstantiationDependent,
29840b57cec5SDimitry Andric                bool KnownContainsUnexpandedParameterPack);
29850b57cec5SDimitry Andric 
29860b57cec5SDimitry Andric   OverloadExpr(StmtClass SC, EmptyShell Empty, unsigned NumResults,
29870b57cec5SDimitry Andric                bool HasTemplateKWAndArgsInfo);
29880b57cec5SDimitry Andric 
29890b57cec5SDimitry Andric   /// Return the results. Defined after UnresolvedMemberExpr.
29900b57cec5SDimitry Andric   inline DeclAccessPair *getTrailingResults();
getTrailingResults()29910b57cec5SDimitry Andric   const DeclAccessPair *getTrailingResults() const {
29920b57cec5SDimitry Andric     return const_cast<OverloadExpr *>(this)->getTrailingResults();
29930b57cec5SDimitry Andric   }
29940b57cec5SDimitry Andric 
29950b57cec5SDimitry Andric   /// Return the optional template keyword and arguments info.
29960b57cec5SDimitry Andric   /// Defined after UnresolvedMemberExpr.
29970b57cec5SDimitry Andric   inline ASTTemplateKWAndArgsInfo *getTrailingASTTemplateKWAndArgsInfo();
getTrailingASTTemplateKWAndArgsInfo()29980b57cec5SDimitry Andric   const ASTTemplateKWAndArgsInfo *getTrailingASTTemplateKWAndArgsInfo() const {
29990b57cec5SDimitry Andric     return const_cast<OverloadExpr *>(this)
30000b57cec5SDimitry Andric         ->getTrailingASTTemplateKWAndArgsInfo();
30010b57cec5SDimitry Andric   }
30020b57cec5SDimitry Andric 
30030b57cec5SDimitry Andric   /// Return the optional template arguments. Defined after
30040b57cec5SDimitry Andric   /// UnresolvedMemberExpr.
30050b57cec5SDimitry Andric   inline TemplateArgumentLoc *getTrailingTemplateArgumentLoc();
getTrailingTemplateArgumentLoc()30060b57cec5SDimitry Andric   const TemplateArgumentLoc *getTrailingTemplateArgumentLoc() const {
30070b57cec5SDimitry Andric     return const_cast<OverloadExpr *>(this)->getTrailingTemplateArgumentLoc();
30080b57cec5SDimitry Andric   }
30090b57cec5SDimitry Andric 
hasTemplateKWAndArgsInfo()30100b57cec5SDimitry Andric   bool hasTemplateKWAndArgsInfo() const {
30110b57cec5SDimitry Andric     return OverloadExprBits.HasTemplateKWAndArgsInfo;
30120b57cec5SDimitry Andric   }
30130b57cec5SDimitry Andric 
30140b57cec5SDimitry Andric public:
30150b57cec5SDimitry Andric   struct FindResult {
30160b57cec5SDimitry Andric     OverloadExpr *Expression;
30170b57cec5SDimitry Andric     bool IsAddressOfOperand;
30180b57cec5SDimitry Andric     bool HasFormOfMemberPointer;
30190b57cec5SDimitry Andric   };
30200b57cec5SDimitry Andric 
30210b57cec5SDimitry Andric   /// Finds the overloaded expression in the given expression \p E of
30220b57cec5SDimitry Andric   /// OverloadTy.
30230b57cec5SDimitry Andric   ///
30240b57cec5SDimitry Andric   /// \return the expression (which must be there) and true if it has
30250b57cec5SDimitry Andric   /// the particular form of a member pointer expression
find(Expr * E)30260b57cec5SDimitry Andric   static FindResult find(Expr *E) {
30270b57cec5SDimitry Andric     assert(E->getType()->isSpecificBuiltinType(BuiltinType::Overload));
30280b57cec5SDimitry Andric 
30290b57cec5SDimitry Andric     FindResult Result;
30300b57cec5SDimitry Andric 
30310b57cec5SDimitry Andric     E = E->IgnoreParens();
30320b57cec5SDimitry Andric     if (isa<UnaryOperator>(E)) {
30330b57cec5SDimitry Andric       assert(cast<UnaryOperator>(E)->getOpcode() == UO_AddrOf);
30340b57cec5SDimitry Andric       E = cast<UnaryOperator>(E)->getSubExpr();
30350b57cec5SDimitry Andric       auto *Ovl = cast<OverloadExpr>(E->IgnoreParens());
30360b57cec5SDimitry Andric 
30370b57cec5SDimitry Andric       Result.HasFormOfMemberPointer = (E == Ovl && Ovl->getQualifier());
30380b57cec5SDimitry Andric       Result.IsAddressOfOperand = true;
30390b57cec5SDimitry Andric       Result.Expression = Ovl;
30400b57cec5SDimitry Andric     } else {
30410b57cec5SDimitry Andric       Result.HasFormOfMemberPointer = false;
30420b57cec5SDimitry Andric       Result.IsAddressOfOperand = false;
30430b57cec5SDimitry Andric       Result.Expression = cast<OverloadExpr>(E);
30440b57cec5SDimitry Andric     }
30450b57cec5SDimitry Andric 
30460b57cec5SDimitry Andric     return Result;
30470b57cec5SDimitry Andric   }
30480b57cec5SDimitry Andric 
30490b57cec5SDimitry Andric   /// Gets the naming class of this lookup, if any.
30500b57cec5SDimitry Andric   /// Defined after UnresolvedMemberExpr.
30510b57cec5SDimitry Andric   inline CXXRecordDecl *getNamingClass();
getNamingClass()30520b57cec5SDimitry Andric   const CXXRecordDecl *getNamingClass() const {
30530b57cec5SDimitry Andric     return const_cast<OverloadExpr *>(this)->getNamingClass();
30540b57cec5SDimitry Andric   }
30550b57cec5SDimitry Andric 
30560b57cec5SDimitry Andric   using decls_iterator = UnresolvedSetImpl::iterator;
30570b57cec5SDimitry Andric 
decls_begin()30580b57cec5SDimitry Andric   decls_iterator decls_begin() const {
30590b57cec5SDimitry Andric     return UnresolvedSetIterator(getTrailingResults());
30600b57cec5SDimitry Andric   }
decls_end()30610b57cec5SDimitry Andric   decls_iterator decls_end() const {
30620b57cec5SDimitry Andric     return UnresolvedSetIterator(getTrailingResults() + getNumDecls());
30630b57cec5SDimitry Andric   }
decls()30640b57cec5SDimitry Andric   llvm::iterator_range<decls_iterator> decls() const {
30650b57cec5SDimitry Andric     return llvm::make_range(decls_begin(), decls_end());
30660b57cec5SDimitry Andric   }
30670b57cec5SDimitry Andric 
30680b57cec5SDimitry Andric   /// Gets the number of declarations in the unresolved set.
getNumDecls()30690b57cec5SDimitry Andric   unsigned getNumDecls() const { return OverloadExprBits.NumResults; }
30700b57cec5SDimitry Andric 
30710b57cec5SDimitry Andric   /// Gets the full name info.
getNameInfo()30720b57cec5SDimitry Andric   const DeclarationNameInfo &getNameInfo() const { return NameInfo; }
30730b57cec5SDimitry Andric 
30740b57cec5SDimitry Andric   /// Gets the name looked up.
getName()30750b57cec5SDimitry Andric   DeclarationName getName() const { return NameInfo.getName(); }
30760b57cec5SDimitry Andric 
30770b57cec5SDimitry Andric   /// Gets the location of the name.
getNameLoc()30780b57cec5SDimitry Andric   SourceLocation getNameLoc() const { return NameInfo.getLoc(); }
30790b57cec5SDimitry Andric 
30800b57cec5SDimitry Andric   /// Fetches the nested-name qualifier, if one was given.
getQualifier()30810b57cec5SDimitry Andric   NestedNameSpecifier *getQualifier() const {
30820b57cec5SDimitry Andric     return QualifierLoc.getNestedNameSpecifier();
30830b57cec5SDimitry Andric   }
30840b57cec5SDimitry Andric 
30850b57cec5SDimitry Andric   /// Fetches the nested-name qualifier with source-location
30860b57cec5SDimitry Andric   /// information, if one was given.
getQualifierLoc()30870b57cec5SDimitry Andric   NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
30880b57cec5SDimitry Andric 
30890b57cec5SDimitry Andric   /// Retrieve the location of the template keyword preceding
30900b57cec5SDimitry Andric   /// this name, if any.
getTemplateKeywordLoc()30910b57cec5SDimitry Andric   SourceLocation getTemplateKeywordLoc() const {
30920b57cec5SDimitry Andric     if (!hasTemplateKWAndArgsInfo())
30930b57cec5SDimitry Andric       return SourceLocation();
30940b57cec5SDimitry Andric     return getTrailingASTTemplateKWAndArgsInfo()->TemplateKWLoc;
30950b57cec5SDimitry Andric   }
30960b57cec5SDimitry Andric 
30970b57cec5SDimitry Andric   /// Retrieve the location of the left angle bracket starting the
30980b57cec5SDimitry Andric   /// explicit template argument list following the name, if any.
getLAngleLoc()30990b57cec5SDimitry Andric   SourceLocation getLAngleLoc() const {
31000b57cec5SDimitry Andric     if (!hasTemplateKWAndArgsInfo())
31010b57cec5SDimitry Andric       return SourceLocation();
31020b57cec5SDimitry Andric     return getTrailingASTTemplateKWAndArgsInfo()->LAngleLoc;
31030b57cec5SDimitry Andric   }
31040b57cec5SDimitry Andric 
31050b57cec5SDimitry Andric   /// Retrieve the location of the right angle bracket ending the
31060b57cec5SDimitry Andric   /// explicit template argument list following the name, if any.
getRAngleLoc()31070b57cec5SDimitry Andric   SourceLocation getRAngleLoc() const {
31080b57cec5SDimitry Andric     if (!hasTemplateKWAndArgsInfo())
31090b57cec5SDimitry Andric       return SourceLocation();
31100b57cec5SDimitry Andric     return getTrailingASTTemplateKWAndArgsInfo()->RAngleLoc;
31110b57cec5SDimitry Andric   }
31120b57cec5SDimitry Andric 
31130b57cec5SDimitry Andric   /// Determines whether the name was preceded by the template keyword.
hasTemplateKeyword()31140b57cec5SDimitry Andric   bool hasTemplateKeyword() const { return getTemplateKeywordLoc().isValid(); }
31150b57cec5SDimitry Andric 
31160b57cec5SDimitry Andric   /// Determines whether this expression had explicit template arguments.
hasExplicitTemplateArgs()31170b57cec5SDimitry Andric   bool hasExplicitTemplateArgs() const { return getLAngleLoc().isValid(); }
31180b57cec5SDimitry Andric 
getTemplateArgs()31190b57cec5SDimitry Andric   TemplateArgumentLoc const *getTemplateArgs() const {
31200b57cec5SDimitry Andric     if (!hasExplicitTemplateArgs())
31210b57cec5SDimitry Andric       return nullptr;
31220b57cec5SDimitry Andric     return const_cast<OverloadExpr *>(this)->getTrailingTemplateArgumentLoc();
31230b57cec5SDimitry Andric   }
31240b57cec5SDimitry Andric 
getNumTemplateArgs()31250b57cec5SDimitry Andric   unsigned getNumTemplateArgs() const {
31260b57cec5SDimitry Andric     if (!hasExplicitTemplateArgs())
31270b57cec5SDimitry Andric       return 0;
31280b57cec5SDimitry Andric 
31290b57cec5SDimitry Andric     return getTrailingASTTemplateKWAndArgsInfo()->NumTemplateArgs;
31300b57cec5SDimitry Andric   }
31310b57cec5SDimitry Andric 
template_arguments()31320b57cec5SDimitry Andric   ArrayRef<TemplateArgumentLoc> template_arguments() const {
31330b57cec5SDimitry Andric     return {getTemplateArgs(), getNumTemplateArgs()};
31340b57cec5SDimitry Andric   }
31350b57cec5SDimitry Andric 
31360b57cec5SDimitry Andric   /// Copies the template arguments into the given structure.
copyTemplateArgumentsInto(TemplateArgumentListInfo & List)31370b57cec5SDimitry Andric   void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
31380b57cec5SDimitry Andric     if (hasExplicitTemplateArgs())
31390b57cec5SDimitry Andric       getTrailingASTTemplateKWAndArgsInfo()->copyInto(getTemplateArgs(), List);
31400b57cec5SDimitry Andric   }
31410b57cec5SDimitry Andric 
classof(const Stmt * T)31420b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
31430b57cec5SDimitry Andric     return T->getStmtClass() == UnresolvedLookupExprClass ||
31440b57cec5SDimitry Andric            T->getStmtClass() == UnresolvedMemberExprClass;
31450b57cec5SDimitry Andric   }
31460b57cec5SDimitry Andric };
31470b57cec5SDimitry Andric 
31480b57cec5SDimitry Andric /// A reference to a name which we were able to look up during
31490b57cec5SDimitry Andric /// parsing but could not resolve to a specific declaration.
31500b57cec5SDimitry Andric ///
31510b57cec5SDimitry Andric /// This arises in several ways:
31520b57cec5SDimitry Andric ///   * we might be waiting for argument-dependent lookup;
31530b57cec5SDimitry Andric ///   * the name might resolve to an overloaded function;
31540b57cec5SDimitry Andric /// and eventually:
31550b57cec5SDimitry Andric ///   * the lookup might have included a function template.
31560b57cec5SDimitry Andric ///
31570b57cec5SDimitry Andric /// These never include UnresolvedUsingValueDecls, which are always class
31580b57cec5SDimitry Andric /// members and therefore appear only in UnresolvedMemberLookupExprs.
31590b57cec5SDimitry Andric class UnresolvedLookupExpr final
31600b57cec5SDimitry Andric     : public OverloadExpr,
31610b57cec5SDimitry Andric       private llvm::TrailingObjects<UnresolvedLookupExpr, DeclAccessPair,
31620b57cec5SDimitry Andric                                     ASTTemplateKWAndArgsInfo,
31630b57cec5SDimitry Andric                                     TemplateArgumentLoc> {
31640b57cec5SDimitry Andric   friend class ASTStmtReader;
31650b57cec5SDimitry Andric   friend class OverloadExpr;
31660b57cec5SDimitry Andric   friend TrailingObjects;
31670b57cec5SDimitry Andric 
31680b57cec5SDimitry Andric   /// The naming class (C++ [class.access.base]p5) of the lookup, if
31690b57cec5SDimitry Andric   /// any.  This can generally be recalculated from the context chain,
31700b57cec5SDimitry Andric   /// but that can be fairly expensive for unqualified lookups.
31710b57cec5SDimitry Andric   CXXRecordDecl *NamingClass;
31720b57cec5SDimitry Andric 
31730b57cec5SDimitry Andric   // UnresolvedLookupExpr is followed by several trailing objects.
31740b57cec5SDimitry Andric   // They are in order:
31750b57cec5SDimitry Andric   //
31760b57cec5SDimitry Andric   // * An array of getNumResults() DeclAccessPair for the results. These are
31770b57cec5SDimitry Andric   //   undesugared, which is to say, they may include UsingShadowDecls.
31780b57cec5SDimitry Andric   //   Access is relative to the naming class.
31790b57cec5SDimitry Andric   //
31800b57cec5SDimitry Andric   // * An optional ASTTemplateKWAndArgsInfo for the explicitly specified
31810b57cec5SDimitry Andric   //   template keyword and arguments. Present if and only if
31820b57cec5SDimitry Andric   //   hasTemplateKWAndArgsInfo().
31830b57cec5SDimitry Andric   //
31840b57cec5SDimitry Andric   // * An array of getNumTemplateArgs() TemplateArgumentLoc containing
31850b57cec5SDimitry Andric   //   location information for the explicitly specified template arguments.
31860b57cec5SDimitry Andric 
31870b57cec5SDimitry Andric   UnresolvedLookupExpr(const ASTContext &Context, CXXRecordDecl *NamingClass,
31880b57cec5SDimitry Andric                        NestedNameSpecifierLoc QualifierLoc,
31890b57cec5SDimitry Andric                        SourceLocation TemplateKWLoc,
31900b57cec5SDimitry Andric                        const DeclarationNameInfo &NameInfo, bool RequiresADL,
31910b57cec5SDimitry Andric                        bool Overloaded,
31920b57cec5SDimitry Andric                        const TemplateArgumentListInfo *TemplateArgs,
31935f757f3fSDimitry Andric                        UnresolvedSetIterator Begin, UnresolvedSetIterator End,
31945f757f3fSDimitry Andric                        bool KnownDependent);
31950b57cec5SDimitry Andric 
31960b57cec5SDimitry Andric   UnresolvedLookupExpr(EmptyShell Empty, unsigned NumResults,
31970b57cec5SDimitry Andric                        bool HasTemplateKWAndArgsInfo);
31980b57cec5SDimitry Andric 
numTrailingObjects(OverloadToken<DeclAccessPair>)31990b57cec5SDimitry Andric   unsigned numTrailingObjects(OverloadToken<DeclAccessPair>) const {
32000b57cec5SDimitry Andric     return getNumDecls();
32010b57cec5SDimitry Andric   }
32020b57cec5SDimitry Andric 
numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>)32030b57cec5SDimitry Andric   unsigned numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
32040b57cec5SDimitry Andric     return hasTemplateKWAndArgsInfo();
32050b57cec5SDimitry Andric   }
32060b57cec5SDimitry Andric 
32070b57cec5SDimitry Andric public:
32080b57cec5SDimitry Andric   static UnresolvedLookupExpr *
32090b57cec5SDimitry Andric   Create(const ASTContext &Context, CXXRecordDecl *NamingClass,
32100b57cec5SDimitry Andric          NestedNameSpecifierLoc QualifierLoc,
32110b57cec5SDimitry Andric          const DeclarationNameInfo &NameInfo, bool RequiresADL, bool Overloaded,
32120b57cec5SDimitry Andric          UnresolvedSetIterator Begin, UnresolvedSetIterator End);
32130b57cec5SDimitry Andric 
32145f757f3fSDimitry Andric   // After canonicalization, there may be dependent template arguments in
32155f757f3fSDimitry Andric   // CanonicalConverted But none of Args is dependent. When any of
32165f757f3fSDimitry Andric   // CanonicalConverted dependent, KnownDependent is true.
32170b57cec5SDimitry Andric   static UnresolvedLookupExpr *
32180b57cec5SDimitry Andric   Create(const ASTContext &Context, CXXRecordDecl *NamingClass,
32190b57cec5SDimitry Andric          NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc,
32200b57cec5SDimitry Andric          const DeclarationNameInfo &NameInfo, bool RequiresADL,
32210b57cec5SDimitry Andric          const TemplateArgumentListInfo *Args, UnresolvedSetIterator Begin,
32225f757f3fSDimitry Andric          UnresolvedSetIterator End, bool KnownDependent);
32230b57cec5SDimitry Andric 
32240b57cec5SDimitry Andric   static UnresolvedLookupExpr *CreateEmpty(const ASTContext &Context,
32250b57cec5SDimitry Andric                                            unsigned NumResults,
32260b57cec5SDimitry Andric                                            bool HasTemplateKWAndArgsInfo,
32270b57cec5SDimitry Andric                                            unsigned NumTemplateArgs);
32280b57cec5SDimitry Andric 
32290b57cec5SDimitry Andric   /// True if this declaration should be extended by
32300b57cec5SDimitry Andric   /// argument-dependent lookup.
requiresADL()32310b57cec5SDimitry Andric   bool requiresADL() const { return UnresolvedLookupExprBits.RequiresADL; }
32320b57cec5SDimitry Andric 
32330b57cec5SDimitry Andric   /// True if this lookup is overloaded.
isOverloaded()32340b57cec5SDimitry Andric   bool isOverloaded() const { return UnresolvedLookupExprBits.Overloaded; }
32350b57cec5SDimitry Andric 
32360b57cec5SDimitry Andric   /// Gets the 'naming class' (in the sense of C++0x
32370b57cec5SDimitry Andric   /// [class.access.base]p5) of the lookup.  This is the scope
32380b57cec5SDimitry Andric   /// that was looked in to find these results.
getNamingClass()32390b57cec5SDimitry Andric   CXXRecordDecl *getNamingClass() { return NamingClass; }
getNamingClass()32400b57cec5SDimitry Andric   const CXXRecordDecl *getNamingClass() const { return NamingClass; }
32410b57cec5SDimitry Andric 
getBeginLoc()32420b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY {
32430b57cec5SDimitry Andric     if (NestedNameSpecifierLoc l = getQualifierLoc())
32440b57cec5SDimitry Andric       return l.getBeginLoc();
32450b57cec5SDimitry Andric     return getNameInfo().getBeginLoc();
32460b57cec5SDimitry Andric   }
32470b57cec5SDimitry Andric 
getEndLoc()32480b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY {
32490b57cec5SDimitry Andric     if (hasExplicitTemplateArgs())
32500b57cec5SDimitry Andric       return getRAngleLoc();
32510b57cec5SDimitry Andric     return getNameInfo().getEndLoc();
32520b57cec5SDimitry Andric   }
32530b57cec5SDimitry Andric 
children()32540b57cec5SDimitry Andric   child_range children() {
32550b57cec5SDimitry Andric     return child_range(child_iterator(), child_iterator());
32560b57cec5SDimitry Andric   }
32570b57cec5SDimitry Andric 
children()32580b57cec5SDimitry Andric   const_child_range children() const {
32590b57cec5SDimitry Andric     return const_child_range(const_child_iterator(), const_child_iterator());
32600b57cec5SDimitry Andric   }
32610b57cec5SDimitry Andric 
classof(const Stmt * T)32620b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
32630b57cec5SDimitry Andric     return T->getStmtClass() == UnresolvedLookupExprClass;
32640b57cec5SDimitry Andric   }
32650b57cec5SDimitry Andric };
32660b57cec5SDimitry Andric 
32670b57cec5SDimitry Andric /// A qualified reference to a name whose declaration cannot
32680b57cec5SDimitry Andric /// yet be resolved.
32690b57cec5SDimitry Andric ///
32700b57cec5SDimitry Andric /// DependentScopeDeclRefExpr is similar to DeclRefExpr in that
32710b57cec5SDimitry Andric /// it expresses a reference to a declaration such as
32720b57cec5SDimitry Andric /// X<T>::value. The difference, however, is that an
32730b57cec5SDimitry Andric /// DependentScopeDeclRefExpr node is used only within C++ templates when
32740b57cec5SDimitry Andric /// the qualification (e.g., X<T>::) refers to a dependent type. In
32750b57cec5SDimitry Andric /// this case, X<T>::value cannot resolve to a declaration because the
32760b57cec5SDimitry Andric /// declaration will differ from one instantiation of X<T> to the
32770b57cec5SDimitry Andric /// next. Therefore, DependentScopeDeclRefExpr keeps track of the
32780b57cec5SDimitry Andric /// qualifier (X<T>::) and the name of the entity being referenced
32790b57cec5SDimitry Andric /// ("value"). Such expressions will instantiate to a DeclRefExpr once the
32800b57cec5SDimitry Andric /// declaration can be found.
32810b57cec5SDimitry Andric class DependentScopeDeclRefExpr final
32820b57cec5SDimitry Andric     : public Expr,
32830b57cec5SDimitry Andric       private llvm::TrailingObjects<DependentScopeDeclRefExpr,
32840b57cec5SDimitry Andric                                     ASTTemplateKWAndArgsInfo,
32850b57cec5SDimitry Andric                                     TemplateArgumentLoc> {
32860b57cec5SDimitry Andric   friend class ASTStmtReader;
32870b57cec5SDimitry Andric   friend class ASTStmtWriter;
32880b57cec5SDimitry Andric   friend TrailingObjects;
32890b57cec5SDimitry Andric 
32900b57cec5SDimitry Andric   /// The nested-name-specifier that qualifies this unresolved
32910b57cec5SDimitry Andric   /// declaration name.
32920b57cec5SDimitry Andric   NestedNameSpecifierLoc QualifierLoc;
32930b57cec5SDimitry Andric 
32940b57cec5SDimitry Andric   /// The name of the entity we will be referencing.
32950b57cec5SDimitry Andric   DeclarationNameInfo NameInfo;
32960b57cec5SDimitry Andric 
32970b57cec5SDimitry Andric   DependentScopeDeclRefExpr(QualType Ty, NestedNameSpecifierLoc QualifierLoc,
32980b57cec5SDimitry Andric                             SourceLocation TemplateKWLoc,
32990b57cec5SDimitry Andric                             const DeclarationNameInfo &NameInfo,
33000b57cec5SDimitry Andric                             const TemplateArgumentListInfo *Args);
33010b57cec5SDimitry Andric 
numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>)33020b57cec5SDimitry Andric   size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
33030b57cec5SDimitry Andric     return hasTemplateKWAndArgsInfo();
33040b57cec5SDimitry Andric   }
33050b57cec5SDimitry Andric 
hasTemplateKWAndArgsInfo()33060b57cec5SDimitry Andric   bool hasTemplateKWAndArgsInfo() const {
33070b57cec5SDimitry Andric     return DependentScopeDeclRefExprBits.HasTemplateKWAndArgsInfo;
33080b57cec5SDimitry Andric   }
33090b57cec5SDimitry Andric 
33100b57cec5SDimitry Andric public:
33110b57cec5SDimitry Andric   static DependentScopeDeclRefExpr *
33120b57cec5SDimitry Andric   Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc,
33130b57cec5SDimitry Andric          SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo,
33140b57cec5SDimitry Andric          const TemplateArgumentListInfo *TemplateArgs);
33150b57cec5SDimitry Andric 
33160b57cec5SDimitry Andric   static DependentScopeDeclRefExpr *CreateEmpty(const ASTContext &Context,
33170b57cec5SDimitry Andric                                                 bool HasTemplateKWAndArgsInfo,
33180b57cec5SDimitry Andric                                                 unsigned NumTemplateArgs);
33190b57cec5SDimitry Andric 
33200b57cec5SDimitry Andric   /// Retrieve the name that this expression refers to.
getNameInfo()33210b57cec5SDimitry Andric   const DeclarationNameInfo &getNameInfo() const { return NameInfo; }
33220b57cec5SDimitry Andric 
33230b57cec5SDimitry Andric   /// Retrieve the name that this expression refers to.
getDeclName()33240b57cec5SDimitry Andric   DeclarationName getDeclName() const { return NameInfo.getName(); }
33250b57cec5SDimitry Andric 
33260b57cec5SDimitry Andric   /// Retrieve the location of the name within the expression.
33270b57cec5SDimitry Andric   ///
33280b57cec5SDimitry Andric   /// For example, in "X<T>::value" this is the location of "value".
getLocation()33290b57cec5SDimitry Andric   SourceLocation getLocation() const { return NameInfo.getLoc(); }
33300b57cec5SDimitry Andric 
33310b57cec5SDimitry Andric   /// Retrieve the nested-name-specifier that qualifies the
33320b57cec5SDimitry Andric   /// name, with source location information.
getQualifierLoc()33330b57cec5SDimitry Andric   NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
33340b57cec5SDimitry Andric 
33350b57cec5SDimitry Andric   /// Retrieve the nested-name-specifier that qualifies this
33360b57cec5SDimitry Andric   /// declaration.
getQualifier()33370b57cec5SDimitry Andric   NestedNameSpecifier *getQualifier() const {
33380b57cec5SDimitry Andric     return QualifierLoc.getNestedNameSpecifier();
33390b57cec5SDimitry Andric   }
33400b57cec5SDimitry Andric 
33410b57cec5SDimitry Andric   /// Retrieve the location of the template keyword preceding
33420b57cec5SDimitry Andric   /// this name, if any.
getTemplateKeywordLoc()33430b57cec5SDimitry Andric   SourceLocation getTemplateKeywordLoc() const {
33440b57cec5SDimitry Andric     if (!hasTemplateKWAndArgsInfo())
33450b57cec5SDimitry Andric       return SourceLocation();
33460b57cec5SDimitry Andric     return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->TemplateKWLoc;
33470b57cec5SDimitry Andric   }
33480b57cec5SDimitry Andric 
33490b57cec5SDimitry Andric   /// Retrieve the location of the left angle bracket starting the
33500b57cec5SDimitry Andric   /// explicit template argument list following the name, if any.
getLAngleLoc()33510b57cec5SDimitry Andric   SourceLocation getLAngleLoc() const {
33520b57cec5SDimitry Andric     if (!hasTemplateKWAndArgsInfo())
33530b57cec5SDimitry Andric       return SourceLocation();
33540b57cec5SDimitry Andric     return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->LAngleLoc;
33550b57cec5SDimitry Andric   }
33560b57cec5SDimitry Andric 
33570b57cec5SDimitry Andric   /// Retrieve the location of the right angle bracket ending the
33580b57cec5SDimitry Andric   /// explicit template argument list following the name, if any.
getRAngleLoc()33590b57cec5SDimitry Andric   SourceLocation getRAngleLoc() const {
33600b57cec5SDimitry Andric     if (!hasTemplateKWAndArgsInfo())
33610b57cec5SDimitry Andric       return SourceLocation();
33620b57cec5SDimitry Andric     return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->RAngleLoc;
33630b57cec5SDimitry Andric   }
33640b57cec5SDimitry Andric 
33650b57cec5SDimitry Andric   /// Determines whether the name was preceded by the template keyword.
hasTemplateKeyword()33660b57cec5SDimitry Andric   bool hasTemplateKeyword() const { return getTemplateKeywordLoc().isValid(); }
33670b57cec5SDimitry Andric 
33680b57cec5SDimitry Andric   /// Determines whether this lookup had explicit template arguments.
hasExplicitTemplateArgs()33690b57cec5SDimitry Andric   bool hasExplicitTemplateArgs() const { return getLAngleLoc().isValid(); }
33700b57cec5SDimitry Andric 
33710b57cec5SDimitry Andric   /// Copies the template arguments (if present) into the given
33720b57cec5SDimitry Andric   /// structure.
copyTemplateArgumentsInto(TemplateArgumentListInfo & List)33730b57cec5SDimitry Andric   void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
33740b57cec5SDimitry Andric     if (hasExplicitTemplateArgs())
33750b57cec5SDimitry Andric       getTrailingObjects<ASTTemplateKWAndArgsInfo>()->copyInto(
33760b57cec5SDimitry Andric           getTrailingObjects<TemplateArgumentLoc>(), List);
33770b57cec5SDimitry Andric   }
33780b57cec5SDimitry Andric 
getTemplateArgs()33790b57cec5SDimitry Andric   TemplateArgumentLoc const *getTemplateArgs() const {
33800b57cec5SDimitry Andric     if (!hasExplicitTemplateArgs())
33810b57cec5SDimitry Andric       return nullptr;
33820b57cec5SDimitry Andric 
33830b57cec5SDimitry Andric     return getTrailingObjects<TemplateArgumentLoc>();
33840b57cec5SDimitry Andric   }
33850b57cec5SDimitry Andric 
getNumTemplateArgs()33860b57cec5SDimitry Andric   unsigned getNumTemplateArgs() const {
33870b57cec5SDimitry Andric     if (!hasExplicitTemplateArgs())
33880b57cec5SDimitry Andric       return 0;
33890b57cec5SDimitry Andric 
33900b57cec5SDimitry Andric     return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->NumTemplateArgs;
33910b57cec5SDimitry Andric   }
33920b57cec5SDimitry Andric 
template_arguments()33930b57cec5SDimitry Andric   ArrayRef<TemplateArgumentLoc> template_arguments() const {
33940b57cec5SDimitry Andric     return {getTemplateArgs(), getNumTemplateArgs()};
33950b57cec5SDimitry Andric   }
33960b57cec5SDimitry Andric 
33970b57cec5SDimitry Andric   /// Note: getBeginLoc() is the start of the whole DependentScopeDeclRefExpr,
33980b57cec5SDimitry Andric   /// and differs from getLocation().getStart().
getBeginLoc()33990b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY {
34000b57cec5SDimitry Andric     return QualifierLoc.getBeginLoc();
34010b57cec5SDimitry Andric   }
34020b57cec5SDimitry Andric 
getEndLoc()34030b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY {
34040b57cec5SDimitry Andric     if (hasExplicitTemplateArgs())
34050b57cec5SDimitry Andric       return getRAngleLoc();
34060b57cec5SDimitry Andric     return getLocation();
34070b57cec5SDimitry Andric   }
34080b57cec5SDimitry Andric 
classof(const Stmt * T)34090b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
34100b57cec5SDimitry Andric     return T->getStmtClass() == DependentScopeDeclRefExprClass;
34110b57cec5SDimitry Andric   }
34120b57cec5SDimitry Andric 
children()34130b57cec5SDimitry Andric   child_range children() {
34140b57cec5SDimitry Andric     return child_range(child_iterator(), child_iterator());
34150b57cec5SDimitry Andric   }
34160b57cec5SDimitry Andric 
children()34170b57cec5SDimitry Andric   const_child_range children() const {
34180b57cec5SDimitry Andric     return const_child_range(const_child_iterator(), const_child_iterator());
34190b57cec5SDimitry Andric   }
34200b57cec5SDimitry Andric };
34210b57cec5SDimitry Andric 
34220b57cec5SDimitry Andric /// Represents an expression -- generally a full-expression -- that
34230b57cec5SDimitry Andric /// introduces cleanups to be run at the end of the sub-expression's
34240b57cec5SDimitry Andric /// evaluation.  The most common source of expression-introduced
34250b57cec5SDimitry Andric /// cleanups is temporary objects in C++, but several other kinds of
34260b57cec5SDimitry Andric /// expressions can create cleanups, including basically every
34270b57cec5SDimitry Andric /// call in ARC that returns an Objective-C pointer.
34280b57cec5SDimitry Andric ///
34290b57cec5SDimitry Andric /// This expression also tracks whether the sub-expression contains a
34300b57cec5SDimitry Andric /// potentially-evaluated block literal.  The lifetime of a block
34310b57cec5SDimitry Andric /// literal is the extent of the enclosing scope.
34320b57cec5SDimitry Andric class ExprWithCleanups final
34330b57cec5SDimitry Andric     : public FullExpr,
34345ffd83dbSDimitry Andric       private llvm::TrailingObjects<
34355ffd83dbSDimitry Andric           ExprWithCleanups,
34365ffd83dbSDimitry Andric           llvm::PointerUnion<BlockDecl *, CompoundLiteralExpr *>> {
34370b57cec5SDimitry Andric public:
34380b57cec5SDimitry Andric   /// The type of objects that are kept in the cleanup.
34395ffd83dbSDimitry Andric   /// It's useful to remember the set of blocks and block-scoped compound
34405ffd83dbSDimitry Andric   /// literals; we could also remember the set of temporaries, but there's
34415ffd83dbSDimitry Andric   /// currently no need.
34425ffd83dbSDimitry Andric   using CleanupObject = llvm::PointerUnion<BlockDecl *, CompoundLiteralExpr *>;
34430b57cec5SDimitry Andric 
34440b57cec5SDimitry Andric private:
34450b57cec5SDimitry Andric   friend class ASTStmtReader;
34460b57cec5SDimitry Andric   friend TrailingObjects;
34470b57cec5SDimitry Andric 
34480b57cec5SDimitry Andric   ExprWithCleanups(EmptyShell, unsigned NumObjects);
34490b57cec5SDimitry Andric   ExprWithCleanups(Expr *SubExpr, bool CleanupsHaveSideEffects,
34500b57cec5SDimitry Andric                    ArrayRef<CleanupObject> Objects);
34510b57cec5SDimitry Andric 
34520b57cec5SDimitry Andric public:
34530b57cec5SDimitry Andric   static ExprWithCleanups *Create(const ASTContext &C, EmptyShell empty,
34540b57cec5SDimitry Andric                                   unsigned numObjects);
34550b57cec5SDimitry Andric 
34560b57cec5SDimitry Andric   static ExprWithCleanups *Create(const ASTContext &C, Expr *subexpr,
34570b57cec5SDimitry Andric                                   bool CleanupsHaveSideEffects,
34580b57cec5SDimitry Andric                                   ArrayRef<CleanupObject> objects);
34590b57cec5SDimitry Andric 
getObjects()34600b57cec5SDimitry Andric   ArrayRef<CleanupObject> getObjects() const {
3461bdd1243dSDimitry Andric     return llvm::ArrayRef(getTrailingObjects<CleanupObject>(), getNumObjects());
34620b57cec5SDimitry Andric   }
34630b57cec5SDimitry Andric 
getNumObjects()34640b57cec5SDimitry Andric   unsigned getNumObjects() const { return ExprWithCleanupsBits.NumObjects; }
34650b57cec5SDimitry Andric 
getObject(unsigned i)34660b57cec5SDimitry Andric   CleanupObject getObject(unsigned i) const {
34670b57cec5SDimitry Andric     assert(i < getNumObjects() && "Index out of range");
34680b57cec5SDimitry Andric     return getObjects()[i];
34690b57cec5SDimitry Andric   }
34700b57cec5SDimitry Andric 
cleanupsHaveSideEffects()34710b57cec5SDimitry Andric   bool cleanupsHaveSideEffects() const {
34720b57cec5SDimitry Andric     return ExprWithCleanupsBits.CleanupsHaveSideEffects;
34730b57cec5SDimitry Andric   }
34740b57cec5SDimitry Andric 
getBeginLoc()34750b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY {
34760b57cec5SDimitry Andric     return SubExpr->getBeginLoc();
34770b57cec5SDimitry Andric   }
34780b57cec5SDimitry Andric 
getEndLoc()34790b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY {
34800b57cec5SDimitry Andric     return SubExpr->getEndLoc();
34810b57cec5SDimitry Andric   }
34820b57cec5SDimitry Andric 
34830b57cec5SDimitry Andric   // Implement isa/cast/dyncast/etc.
classof(const Stmt * T)34840b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
34850b57cec5SDimitry Andric     return T->getStmtClass() == ExprWithCleanupsClass;
34860b57cec5SDimitry Andric   }
34870b57cec5SDimitry Andric 
34880b57cec5SDimitry Andric   // Iterators
children()34890b57cec5SDimitry Andric   child_range children() { return child_range(&SubExpr, &SubExpr + 1); }
34900b57cec5SDimitry Andric 
children()34910b57cec5SDimitry Andric   const_child_range children() const {
34920b57cec5SDimitry Andric     return const_child_range(&SubExpr, &SubExpr + 1);
34930b57cec5SDimitry Andric   }
34940b57cec5SDimitry Andric };
34950b57cec5SDimitry Andric 
34960b57cec5SDimitry Andric /// Describes an explicit type conversion that uses functional
34970b57cec5SDimitry Andric /// notion but could not be resolved because one or more arguments are
34980b57cec5SDimitry Andric /// type-dependent.
34990b57cec5SDimitry Andric ///
35000b57cec5SDimitry Andric /// The explicit type conversions expressed by
35010b57cec5SDimitry Andric /// CXXUnresolvedConstructExpr have the form <tt>T(a1, a2, ..., aN)</tt>,
35020b57cec5SDimitry Andric /// where \c T is some type and \c a1, \c a2, ..., \c aN are values, and
35030b57cec5SDimitry Andric /// either \c T is a dependent type or one or more of the <tt>a</tt>'s is
35040b57cec5SDimitry Andric /// type-dependent. For example, this would occur in a template such
35050b57cec5SDimitry Andric /// as:
35060b57cec5SDimitry Andric ///
35070b57cec5SDimitry Andric /// \code
35080b57cec5SDimitry Andric ///   template<typename T, typename A1>
35090b57cec5SDimitry Andric ///   inline T make_a(const A1& a1) {
35100b57cec5SDimitry Andric ///     return T(a1);
35110b57cec5SDimitry Andric ///   }
35120b57cec5SDimitry Andric /// \endcode
35130b57cec5SDimitry Andric ///
35140b57cec5SDimitry Andric /// When the returned expression is instantiated, it may resolve to a
35150b57cec5SDimitry Andric /// constructor call, conversion function call, or some kind of type
35160b57cec5SDimitry Andric /// conversion.
35170b57cec5SDimitry Andric class CXXUnresolvedConstructExpr final
35180b57cec5SDimitry Andric     : public Expr,
35190b57cec5SDimitry Andric       private llvm::TrailingObjects<CXXUnresolvedConstructExpr, Expr *> {
35200b57cec5SDimitry Andric   friend class ASTStmtReader;
35210b57cec5SDimitry Andric   friend TrailingObjects;
35220b57cec5SDimitry Andric 
352306c3fb27SDimitry Andric   /// The type being constructed, and whether the construct expression models
352406c3fb27SDimitry Andric   /// list initialization or not.
352506c3fb27SDimitry Andric   llvm::PointerIntPair<TypeSourceInfo *, 1> TypeAndInitForm;
35260b57cec5SDimitry Andric 
35270b57cec5SDimitry Andric   /// The location of the left parentheses ('(').
35280b57cec5SDimitry Andric   SourceLocation LParenLoc;
35290b57cec5SDimitry Andric 
35300b57cec5SDimitry Andric   /// The location of the right parentheses (')').
35310b57cec5SDimitry Andric   SourceLocation RParenLoc;
35320b57cec5SDimitry Andric 
3533e8d8bef9SDimitry Andric   CXXUnresolvedConstructExpr(QualType T, TypeSourceInfo *TSI,
3534e8d8bef9SDimitry Andric                              SourceLocation LParenLoc, ArrayRef<Expr *> Args,
353506c3fb27SDimitry Andric                              SourceLocation RParenLoc, bool IsListInit);
35360b57cec5SDimitry Andric 
CXXUnresolvedConstructExpr(EmptyShell Empty,unsigned NumArgs)35370b57cec5SDimitry Andric   CXXUnresolvedConstructExpr(EmptyShell Empty, unsigned NumArgs)
353806c3fb27SDimitry Andric       : Expr(CXXUnresolvedConstructExprClass, Empty) {
35390b57cec5SDimitry Andric     CXXUnresolvedConstructExprBits.NumArgs = NumArgs;
35400b57cec5SDimitry Andric   }
35410b57cec5SDimitry Andric 
35420b57cec5SDimitry Andric public:
354306c3fb27SDimitry Andric   static CXXUnresolvedConstructExpr *
354406c3fb27SDimitry Andric   Create(const ASTContext &Context, QualType T, TypeSourceInfo *TSI,
354506c3fb27SDimitry Andric          SourceLocation LParenLoc, ArrayRef<Expr *> Args,
354606c3fb27SDimitry Andric          SourceLocation RParenLoc, bool IsListInit);
35470b57cec5SDimitry Andric 
35480b57cec5SDimitry Andric   static CXXUnresolvedConstructExpr *CreateEmpty(const ASTContext &Context,
35490b57cec5SDimitry Andric                                                  unsigned NumArgs);
35500b57cec5SDimitry Andric 
35510b57cec5SDimitry Andric   /// Retrieve the type that is being constructed, as specified
35520b57cec5SDimitry Andric   /// in the source code.
getTypeAsWritten()355306c3fb27SDimitry Andric   QualType getTypeAsWritten() const { return getTypeSourceInfo()->getType(); }
35540b57cec5SDimitry Andric 
35550b57cec5SDimitry Andric   /// Retrieve the type source information for the type being
35560b57cec5SDimitry Andric   /// constructed.
getTypeSourceInfo()355706c3fb27SDimitry Andric   TypeSourceInfo *getTypeSourceInfo() const {
355806c3fb27SDimitry Andric     return TypeAndInitForm.getPointer();
355906c3fb27SDimitry Andric   }
35600b57cec5SDimitry Andric 
35610b57cec5SDimitry Andric   /// Retrieve the location of the left parentheses ('(') that
35620b57cec5SDimitry Andric   /// precedes the argument list.
getLParenLoc()35630b57cec5SDimitry Andric   SourceLocation getLParenLoc() const { return LParenLoc; }
setLParenLoc(SourceLocation L)35640b57cec5SDimitry Andric   void setLParenLoc(SourceLocation L) { LParenLoc = L; }
35650b57cec5SDimitry Andric 
35660b57cec5SDimitry Andric   /// Retrieve the location of the right parentheses (')') that
35670b57cec5SDimitry Andric   /// follows the argument list.
getRParenLoc()35680b57cec5SDimitry Andric   SourceLocation getRParenLoc() const { return RParenLoc; }
setRParenLoc(SourceLocation L)35690b57cec5SDimitry Andric   void setRParenLoc(SourceLocation L) { RParenLoc = L; }
35700b57cec5SDimitry Andric 
35710b57cec5SDimitry Andric   /// Determine whether this expression models list-initialization.
35720b57cec5SDimitry Andric   /// If so, there will be exactly one subexpression, which will be
35730b57cec5SDimitry Andric   /// an InitListExpr.
isListInitialization()357406c3fb27SDimitry Andric   bool isListInitialization() const { return TypeAndInitForm.getInt(); }
35750b57cec5SDimitry Andric 
35760b57cec5SDimitry Andric   /// Retrieve the number of arguments.
getNumArgs()3577e8d8bef9SDimitry Andric   unsigned getNumArgs() const { return CXXUnresolvedConstructExprBits.NumArgs; }
35780b57cec5SDimitry Andric 
35790b57cec5SDimitry Andric   using arg_iterator = Expr **;
35800b57cec5SDimitry Andric   using arg_range = llvm::iterator_range<arg_iterator>;
35810b57cec5SDimitry Andric 
arg_begin()35820b57cec5SDimitry Andric   arg_iterator arg_begin() { return getTrailingObjects<Expr *>(); }
arg_end()3583e8d8bef9SDimitry Andric   arg_iterator arg_end() { return arg_begin() + getNumArgs(); }
arguments()35840b57cec5SDimitry Andric   arg_range arguments() { return arg_range(arg_begin(), arg_end()); }
35850b57cec5SDimitry Andric 
35860b57cec5SDimitry Andric   using const_arg_iterator = const Expr* const *;
35870b57cec5SDimitry Andric   using const_arg_range = llvm::iterator_range<const_arg_iterator>;
35880b57cec5SDimitry Andric 
arg_begin()35890b57cec5SDimitry Andric   const_arg_iterator arg_begin() const { return getTrailingObjects<Expr *>(); }
arg_end()3590e8d8bef9SDimitry Andric   const_arg_iterator arg_end() const { return arg_begin() + getNumArgs(); }
arguments()35910b57cec5SDimitry Andric   const_arg_range arguments() const {
35920b57cec5SDimitry Andric     return const_arg_range(arg_begin(), arg_end());
35930b57cec5SDimitry Andric   }
35940b57cec5SDimitry Andric 
getArg(unsigned I)35950b57cec5SDimitry Andric   Expr *getArg(unsigned I) {
3596e8d8bef9SDimitry Andric     assert(I < getNumArgs() && "Argument index out-of-range");
35970b57cec5SDimitry Andric     return arg_begin()[I];
35980b57cec5SDimitry Andric   }
35990b57cec5SDimitry Andric 
getArg(unsigned I)36000b57cec5SDimitry Andric   const Expr *getArg(unsigned I) const {
3601e8d8bef9SDimitry Andric     assert(I < getNumArgs() && "Argument index out-of-range");
36020b57cec5SDimitry Andric     return arg_begin()[I];
36030b57cec5SDimitry Andric   }
36040b57cec5SDimitry Andric 
setArg(unsigned I,Expr * E)36050b57cec5SDimitry Andric   void setArg(unsigned I, Expr *E) {
3606e8d8bef9SDimitry Andric     assert(I < getNumArgs() && "Argument index out-of-range");
36070b57cec5SDimitry Andric     arg_begin()[I] = E;
36080b57cec5SDimitry Andric   }
36090b57cec5SDimitry Andric 
36100b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY;
getEndLoc()36110b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY {
3612e8d8bef9SDimitry Andric     if (!RParenLoc.isValid() && getNumArgs() > 0)
3613e8d8bef9SDimitry Andric       return getArg(getNumArgs() - 1)->getEndLoc();
36140b57cec5SDimitry Andric     return RParenLoc;
36150b57cec5SDimitry Andric   }
36160b57cec5SDimitry Andric 
classof(const Stmt * T)36170b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
36180b57cec5SDimitry Andric     return T->getStmtClass() == CXXUnresolvedConstructExprClass;
36190b57cec5SDimitry Andric   }
36200b57cec5SDimitry Andric 
36210b57cec5SDimitry Andric   // Iterators
children()36220b57cec5SDimitry Andric   child_range children() {
36230b57cec5SDimitry Andric     auto **begin = reinterpret_cast<Stmt **>(arg_begin());
3624e8d8bef9SDimitry Andric     return child_range(begin, begin + getNumArgs());
36250b57cec5SDimitry Andric   }
36260b57cec5SDimitry Andric 
children()36270b57cec5SDimitry Andric   const_child_range children() const {
36280b57cec5SDimitry Andric     auto **begin = reinterpret_cast<Stmt **>(
36290b57cec5SDimitry Andric         const_cast<CXXUnresolvedConstructExpr *>(this)->arg_begin());
3630e8d8bef9SDimitry Andric     return const_child_range(begin, begin + getNumArgs());
36310b57cec5SDimitry Andric   }
36320b57cec5SDimitry Andric };
36330b57cec5SDimitry Andric 
36340b57cec5SDimitry Andric /// Represents a C++ member access expression where the actual
36350b57cec5SDimitry Andric /// member referenced could not be resolved because the base
36360b57cec5SDimitry Andric /// expression or the member name was dependent.
36370b57cec5SDimitry Andric ///
36380b57cec5SDimitry Andric /// Like UnresolvedMemberExprs, these can be either implicit or
36390b57cec5SDimitry Andric /// explicit accesses.  It is only possible to get one of these with
36400b57cec5SDimitry Andric /// an implicit access if a qualifier is provided.
36410b57cec5SDimitry Andric class CXXDependentScopeMemberExpr final
36420b57cec5SDimitry Andric     : public Expr,
36430b57cec5SDimitry Andric       private llvm::TrailingObjects<CXXDependentScopeMemberExpr,
36440b57cec5SDimitry Andric                                     ASTTemplateKWAndArgsInfo,
36450b57cec5SDimitry Andric                                     TemplateArgumentLoc, NamedDecl *> {
36460b57cec5SDimitry Andric   friend class ASTStmtReader;
36470b57cec5SDimitry Andric   friend class ASTStmtWriter;
36480b57cec5SDimitry Andric   friend TrailingObjects;
36490b57cec5SDimitry Andric 
36500b57cec5SDimitry Andric   /// The expression for the base pointer or class reference,
36510b57cec5SDimitry Andric   /// e.g., the \c x in x.f.  Can be null in implicit accesses.
36520b57cec5SDimitry Andric   Stmt *Base;
36530b57cec5SDimitry Andric 
36540b57cec5SDimitry Andric   /// The type of the base expression.  Never null, even for
36550b57cec5SDimitry Andric   /// implicit accesses.
36560b57cec5SDimitry Andric   QualType BaseType;
36570b57cec5SDimitry Andric 
36580b57cec5SDimitry Andric   /// The nested-name-specifier that precedes the member name, if any.
36590b57cec5SDimitry Andric   /// FIXME: This could be in principle store as a trailing object.
36600b57cec5SDimitry Andric   /// However the performance impact of doing so should be investigated first.
36610b57cec5SDimitry Andric   NestedNameSpecifierLoc QualifierLoc;
36620b57cec5SDimitry Andric 
36630b57cec5SDimitry Andric   /// The member to which this member expression refers, which
36640b57cec5SDimitry Andric   /// can be name, overloaded operator, or destructor.
36650b57cec5SDimitry Andric   ///
36660b57cec5SDimitry Andric   /// FIXME: could also be a template-id
36670b57cec5SDimitry Andric   DeclarationNameInfo MemberNameInfo;
36680b57cec5SDimitry Andric 
36690b57cec5SDimitry Andric   // CXXDependentScopeMemberExpr is followed by several trailing objects,
36700b57cec5SDimitry Andric   // some of which optional. They are in order:
36710b57cec5SDimitry Andric   //
36720b57cec5SDimitry Andric   // * An optional ASTTemplateKWAndArgsInfo for the explicitly specified
36730b57cec5SDimitry Andric   //   template keyword and arguments. Present if and only if
36740b57cec5SDimitry Andric   //   hasTemplateKWAndArgsInfo().
36750b57cec5SDimitry Andric   //
36760b57cec5SDimitry Andric   // * An array of getNumTemplateArgs() TemplateArgumentLoc containing location
36770b57cec5SDimitry Andric   //   information for the explicitly specified template arguments.
36780b57cec5SDimitry Andric   //
36790b57cec5SDimitry Andric   // * An optional NamedDecl *. In a qualified member access expression such
36800b57cec5SDimitry Andric   //   as t->Base::f, this member stores the resolves of name lookup in the
36810b57cec5SDimitry Andric   //   context of the member access expression, to be used at instantiation
36820b57cec5SDimitry Andric   //   time. Present if and only if hasFirstQualifierFoundInScope().
36830b57cec5SDimitry Andric 
hasTemplateKWAndArgsInfo()36840b57cec5SDimitry Andric   bool hasTemplateKWAndArgsInfo() const {
36850b57cec5SDimitry Andric     return CXXDependentScopeMemberExprBits.HasTemplateKWAndArgsInfo;
36860b57cec5SDimitry Andric   }
36870b57cec5SDimitry Andric 
hasFirstQualifierFoundInScope()36880b57cec5SDimitry Andric   bool hasFirstQualifierFoundInScope() const {
36890b57cec5SDimitry Andric     return CXXDependentScopeMemberExprBits.HasFirstQualifierFoundInScope;
36900b57cec5SDimitry Andric   }
36910b57cec5SDimitry Andric 
numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>)36920b57cec5SDimitry Andric   unsigned numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
36930b57cec5SDimitry Andric     return hasTemplateKWAndArgsInfo();
36940b57cec5SDimitry Andric   }
36950b57cec5SDimitry Andric 
numTrailingObjects(OverloadToken<TemplateArgumentLoc>)36960b57cec5SDimitry Andric   unsigned numTrailingObjects(OverloadToken<TemplateArgumentLoc>) const {
36970b57cec5SDimitry Andric     return getNumTemplateArgs();
36980b57cec5SDimitry Andric   }
36990b57cec5SDimitry Andric 
numTrailingObjects(OverloadToken<NamedDecl * >)37000b57cec5SDimitry Andric   unsigned numTrailingObjects(OverloadToken<NamedDecl *>) const {
37010b57cec5SDimitry Andric     return hasFirstQualifierFoundInScope();
37020b57cec5SDimitry Andric   }
37030b57cec5SDimitry Andric 
37040b57cec5SDimitry Andric   CXXDependentScopeMemberExpr(const ASTContext &Ctx, Expr *Base,
37050b57cec5SDimitry Andric                               QualType BaseType, bool IsArrow,
37060b57cec5SDimitry Andric                               SourceLocation OperatorLoc,
37070b57cec5SDimitry Andric                               NestedNameSpecifierLoc QualifierLoc,
37080b57cec5SDimitry Andric                               SourceLocation TemplateKWLoc,
37090b57cec5SDimitry Andric                               NamedDecl *FirstQualifierFoundInScope,
37100b57cec5SDimitry Andric                               DeclarationNameInfo MemberNameInfo,
37110b57cec5SDimitry Andric                               const TemplateArgumentListInfo *TemplateArgs);
37120b57cec5SDimitry Andric 
37130b57cec5SDimitry Andric   CXXDependentScopeMemberExpr(EmptyShell Empty, bool HasTemplateKWAndArgsInfo,
37140b57cec5SDimitry Andric                               bool HasFirstQualifierFoundInScope);
37150b57cec5SDimitry Andric 
37160b57cec5SDimitry Andric public:
37170b57cec5SDimitry Andric   static CXXDependentScopeMemberExpr *
37180b57cec5SDimitry Andric   Create(const ASTContext &Ctx, Expr *Base, QualType BaseType, bool IsArrow,
37190b57cec5SDimitry Andric          SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc,
37200b57cec5SDimitry Andric          SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierFoundInScope,
37210b57cec5SDimitry Andric          DeclarationNameInfo MemberNameInfo,
37220b57cec5SDimitry Andric          const TemplateArgumentListInfo *TemplateArgs);
37230b57cec5SDimitry Andric 
37240b57cec5SDimitry Andric   static CXXDependentScopeMemberExpr *
37250b57cec5SDimitry Andric   CreateEmpty(const ASTContext &Ctx, bool HasTemplateKWAndArgsInfo,
37260b57cec5SDimitry Andric               unsigned NumTemplateArgs, bool HasFirstQualifierFoundInScope);
37270b57cec5SDimitry Andric 
37280b57cec5SDimitry Andric   /// True if this is an implicit access, i.e. one in which the
37290b57cec5SDimitry Andric   /// member being accessed was not written in the source.  The source
37300b57cec5SDimitry Andric   /// location of the operator is invalid in this case.
isImplicitAccess()37310b57cec5SDimitry Andric   bool isImplicitAccess() const {
37320b57cec5SDimitry Andric     if (!Base)
37330b57cec5SDimitry Andric       return true;
37340b57cec5SDimitry Andric     return cast<Expr>(Base)->isImplicitCXXThis();
37350b57cec5SDimitry Andric   }
37360b57cec5SDimitry Andric 
37370b57cec5SDimitry Andric   /// Retrieve the base object of this member expressions,
37380b57cec5SDimitry Andric   /// e.g., the \c x in \c x.m.
getBase()37390b57cec5SDimitry Andric   Expr *getBase() const {
37400b57cec5SDimitry Andric     assert(!isImplicitAccess());
37410b57cec5SDimitry Andric     return cast<Expr>(Base);
37420b57cec5SDimitry Andric   }
37430b57cec5SDimitry Andric 
getBaseType()37440b57cec5SDimitry Andric   QualType getBaseType() const { return BaseType; }
37450b57cec5SDimitry Andric 
37460b57cec5SDimitry Andric   /// Determine whether this member expression used the '->'
37470b57cec5SDimitry Andric   /// operator; otherwise, it used the '.' operator.
isArrow()37480b57cec5SDimitry Andric   bool isArrow() const { return CXXDependentScopeMemberExprBits.IsArrow; }
37490b57cec5SDimitry Andric 
37500b57cec5SDimitry Andric   /// Retrieve the location of the '->' or '.' operator.
getOperatorLoc()37510b57cec5SDimitry Andric   SourceLocation getOperatorLoc() const {
37520b57cec5SDimitry Andric     return CXXDependentScopeMemberExprBits.OperatorLoc;
37530b57cec5SDimitry Andric   }
37540b57cec5SDimitry Andric 
37550b57cec5SDimitry Andric   /// Retrieve the nested-name-specifier that qualifies the member name.
getQualifier()37560b57cec5SDimitry Andric   NestedNameSpecifier *getQualifier() const {
37570b57cec5SDimitry Andric     return QualifierLoc.getNestedNameSpecifier();
37580b57cec5SDimitry Andric   }
37590b57cec5SDimitry Andric 
37600b57cec5SDimitry Andric   /// Retrieve the nested-name-specifier that qualifies the member
37610b57cec5SDimitry Andric   /// name, with source location information.
getQualifierLoc()37620b57cec5SDimitry Andric   NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
37630b57cec5SDimitry Andric 
37640b57cec5SDimitry Andric   /// Retrieve the first part of the nested-name-specifier that was
37650b57cec5SDimitry Andric   /// found in the scope of the member access expression when the member access
37660b57cec5SDimitry Andric   /// was initially parsed.
37670b57cec5SDimitry Andric   ///
37680b57cec5SDimitry Andric   /// This function only returns a useful result when member access expression
37690b57cec5SDimitry Andric   /// uses a qualified member name, e.g., "x.Base::f". Here, the declaration
37700b57cec5SDimitry Andric   /// returned by this function describes what was found by unqualified name
37710b57cec5SDimitry Andric   /// lookup for the identifier "Base" within the scope of the member access
37720b57cec5SDimitry Andric   /// expression itself. At template instantiation time, this information is
37730b57cec5SDimitry Andric   /// combined with the results of name lookup into the type of the object
37740b57cec5SDimitry Andric   /// expression itself (the class type of x).
getFirstQualifierFoundInScope()37750b57cec5SDimitry Andric   NamedDecl *getFirstQualifierFoundInScope() const {
37760b57cec5SDimitry Andric     if (!hasFirstQualifierFoundInScope())
37770b57cec5SDimitry Andric       return nullptr;
37780b57cec5SDimitry Andric     return *getTrailingObjects<NamedDecl *>();
37790b57cec5SDimitry Andric   }
37800b57cec5SDimitry Andric 
37810b57cec5SDimitry Andric   /// Retrieve the name of the member that this expression refers to.
getMemberNameInfo()37820b57cec5SDimitry Andric   const DeclarationNameInfo &getMemberNameInfo() const {
37830b57cec5SDimitry Andric     return MemberNameInfo;
37840b57cec5SDimitry Andric   }
37850b57cec5SDimitry Andric 
37860b57cec5SDimitry Andric   /// Retrieve the name of the member that this expression refers to.
getMember()37870b57cec5SDimitry Andric   DeclarationName getMember() const { return MemberNameInfo.getName(); }
37880b57cec5SDimitry Andric 
37890b57cec5SDimitry Andric   // Retrieve the location of the name of the member that this
37900b57cec5SDimitry Andric   // expression refers to.
getMemberLoc()37910b57cec5SDimitry Andric   SourceLocation getMemberLoc() const { return MemberNameInfo.getLoc(); }
37920b57cec5SDimitry Andric 
37930b57cec5SDimitry Andric   /// Retrieve the location of the template keyword preceding the
37940b57cec5SDimitry Andric   /// member name, if any.
getTemplateKeywordLoc()37950b57cec5SDimitry Andric   SourceLocation getTemplateKeywordLoc() const {
37960b57cec5SDimitry Andric     if (!hasTemplateKWAndArgsInfo())
37970b57cec5SDimitry Andric       return SourceLocation();
37980b57cec5SDimitry Andric     return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->TemplateKWLoc;
37990b57cec5SDimitry Andric   }
38000b57cec5SDimitry Andric 
38010b57cec5SDimitry Andric   /// Retrieve the location of the left angle bracket starting the
38020b57cec5SDimitry Andric   /// explicit template argument list following the member name, if any.
getLAngleLoc()38030b57cec5SDimitry Andric   SourceLocation getLAngleLoc() const {
38040b57cec5SDimitry Andric     if (!hasTemplateKWAndArgsInfo())
38050b57cec5SDimitry Andric       return SourceLocation();
38060b57cec5SDimitry Andric     return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->LAngleLoc;
38070b57cec5SDimitry Andric   }
38080b57cec5SDimitry Andric 
38090b57cec5SDimitry Andric   /// Retrieve the location of the right angle bracket ending the
38100b57cec5SDimitry Andric   /// explicit template argument list following the member name, if any.
getRAngleLoc()38110b57cec5SDimitry Andric   SourceLocation getRAngleLoc() const {
38120b57cec5SDimitry Andric     if (!hasTemplateKWAndArgsInfo())
38130b57cec5SDimitry Andric       return SourceLocation();
38140b57cec5SDimitry Andric     return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->RAngleLoc;
38150b57cec5SDimitry Andric   }
38160b57cec5SDimitry Andric 
38170b57cec5SDimitry Andric   /// Determines whether the member name was preceded by the template keyword.
hasTemplateKeyword()38180b57cec5SDimitry Andric   bool hasTemplateKeyword() const { return getTemplateKeywordLoc().isValid(); }
38190b57cec5SDimitry Andric 
38200b57cec5SDimitry Andric   /// Determines whether this member expression actually had a C++
38210b57cec5SDimitry Andric   /// template argument list explicitly specified, e.g., x.f<int>.
hasExplicitTemplateArgs()38220b57cec5SDimitry Andric   bool hasExplicitTemplateArgs() const { return getLAngleLoc().isValid(); }
38230b57cec5SDimitry Andric 
38240b57cec5SDimitry Andric   /// Copies the template arguments (if present) into the given
38250b57cec5SDimitry Andric   /// structure.
copyTemplateArgumentsInto(TemplateArgumentListInfo & List)38260b57cec5SDimitry Andric   void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
38270b57cec5SDimitry Andric     if (hasExplicitTemplateArgs())
38280b57cec5SDimitry Andric       getTrailingObjects<ASTTemplateKWAndArgsInfo>()->copyInto(
38290b57cec5SDimitry Andric           getTrailingObjects<TemplateArgumentLoc>(), List);
38300b57cec5SDimitry Andric   }
38310b57cec5SDimitry Andric 
38320b57cec5SDimitry Andric   /// Retrieve the template arguments provided as part of this
38330b57cec5SDimitry Andric   /// template-id.
getTemplateArgs()38340b57cec5SDimitry Andric   const TemplateArgumentLoc *getTemplateArgs() const {
38350b57cec5SDimitry Andric     if (!hasExplicitTemplateArgs())
38360b57cec5SDimitry Andric       return nullptr;
38370b57cec5SDimitry Andric 
38380b57cec5SDimitry Andric     return getTrailingObjects<TemplateArgumentLoc>();
38390b57cec5SDimitry Andric   }
38400b57cec5SDimitry Andric 
38410b57cec5SDimitry Andric   /// Retrieve the number of template arguments provided as part of this
38420b57cec5SDimitry Andric   /// template-id.
getNumTemplateArgs()38430b57cec5SDimitry Andric   unsigned getNumTemplateArgs() const {
38440b57cec5SDimitry Andric     if (!hasExplicitTemplateArgs())
38450b57cec5SDimitry Andric       return 0;
38460b57cec5SDimitry Andric 
38470b57cec5SDimitry Andric     return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->NumTemplateArgs;
38480b57cec5SDimitry Andric   }
38490b57cec5SDimitry Andric 
template_arguments()38500b57cec5SDimitry Andric   ArrayRef<TemplateArgumentLoc> template_arguments() const {
38510b57cec5SDimitry Andric     return {getTemplateArgs(), getNumTemplateArgs()};
38520b57cec5SDimitry Andric   }
38530b57cec5SDimitry Andric 
getBeginLoc()38540b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY {
38550b57cec5SDimitry Andric     if (!isImplicitAccess())
38560b57cec5SDimitry Andric       return Base->getBeginLoc();
38570b57cec5SDimitry Andric     if (getQualifier())
38580b57cec5SDimitry Andric       return getQualifierLoc().getBeginLoc();
38590b57cec5SDimitry Andric     return MemberNameInfo.getBeginLoc();
38600b57cec5SDimitry Andric   }
38610b57cec5SDimitry Andric 
getEndLoc()38620b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY {
38630b57cec5SDimitry Andric     if (hasExplicitTemplateArgs())
38640b57cec5SDimitry Andric       return getRAngleLoc();
38650b57cec5SDimitry Andric     return MemberNameInfo.getEndLoc();
38660b57cec5SDimitry Andric   }
38670b57cec5SDimitry Andric 
classof(const Stmt * T)38680b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
38690b57cec5SDimitry Andric     return T->getStmtClass() == CXXDependentScopeMemberExprClass;
38700b57cec5SDimitry Andric   }
38710b57cec5SDimitry Andric 
38720b57cec5SDimitry Andric   // Iterators
children()38730b57cec5SDimitry Andric   child_range children() {
38740b57cec5SDimitry Andric     if (isImplicitAccess())
38750b57cec5SDimitry Andric       return child_range(child_iterator(), child_iterator());
38760b57cec5SDimitry Andric     return child_range(&Base, &Base + 1);
38770b57cec5SDimitry Andric   }
38780b57cec5SDimitry Andric 
children()38790b57cec5SDimitry Andric   const_child_range children() const {
38800b57cec5SDimitry Andric     if (isImplicitAccess())
38810b57cec5SDimitry Andric       return const_child_range(const_child_iterator(), const_child_iterator());
38820b57cec5SDimitry Andric     return const_child_range(&Base, &Base + 1);
38830b57cec5SDimitry Andric   }
38840b57cec5SDimitry Andric };
38850b57cec5SDimitry Andric 
38860b57cec5SDimitry Andric /// Represents a C++ member access expression for which lookup
38870b57cec5SDimitry Andric /// produced a set of overloaded functions.
38880b57cec5SDimitry Andric ///
38890b57cec5SDimitry Andric /// The member access may be explicit or implicit:
38900b57cec5SDimitry Andric /// \code
38910b57cec5SDimitry Andric ///    struct A {
38920b57cec5SDimitry Andric ///      int a, b;
38930b57cec5SDimitry Andric ///      int explicitAccess() { return this->a + this->A::b; }
38940b57cec5SDimitry Andric ///      int implicitAccess() { return a + A::b; }
38950b57cec5SDimitry Andric ///    };
38960b57cec5SDimitry Andric /// \endcode
38970b57cec5SDimitry Andric ///
38980b57cec5SDimitry Andric /// In the final AST, an explicit access always becomes a MemberExpr.
38990b57cec5SDimitry Andric /// An implicit access may become either a MemberExpr or a
39000b57cec5SDimitry Andric /// DeclRefExpr, depending on whether the member is static.
39010b57cec5SDimitry Andric class UnresolvedMemberExpr final
39020b57cec5SDimitry Andric     : public OverloadExpr,
39030b57cec5SDimitry Andric       private llvm::TrailingObjects<UnresolvedMemberExpr, DeclAccessPair,
39040b57cec5SDimitry Andric                                     ASTTemplateKWAndArgsInfo,
39050b57cec5SDimitry Andric                                     TemplateArgumentLoc> {
39060b57cec5SDimitry Andric   friend class ASTStmtReader;
39070b57cec5SDimitry Andric   friend class OverloadExpr;
39080b57cec5SDimitry Andric   friend TrailingObjects;
39090b57cec5SDimitry Andric 
39100b57cec5SDimitry Andric   /// The expression for the base pointer or class reference,
39110b57cec5SDimitry Andric   /// e.g., the \c x in x.f.
39120b57cec5SDimitry Andric   ///
39130b57cec5SDimitry Andric   /// This can be null if this is an 'unbased' member expression.
39140b57cec5SDimitry Andric   Stmt *Base;
39150b57cec5SDimitry Andric 
39160b57cec5SDimitry Andric   /// The type of the base expression; never null.
39170b57cec5SDimitry Andric   QualType BaseType;
39180b57cec5SDimitry Andric 
39190b57cec5SDimitry Andric   /// The location of the '->' or '.' operator.
39200b57cec5SDimitry Andric   SourceLocation OperatorLoc;
39210b57cec5SDimitry Andric 
39220b57cec5SDimitry Andric   // UnresolvedMemberExpr is followed by several trailing objects.
39230b57cec5SDimitry Andric   // They are in order:
39240b57cec5SDimitry Andric   //
39250b57cec5SDimitry Andric   // * An array of getNumResults() DeclAccessPair for the results. These are
39260b57cec5SDimitry Andric   //   undesugared, which is to say, they may include UsingShadowDecls.
39270b57cec5SDimitry Andric   //   Access is relative to the naming class.
39280b57cec5SDimitry Andric   //
39290b57cec5SDimitry Andric   // * An optional ASTTemplateKWAndArgsInfo for the explicitly specified
39300b57cec5SDimitry Andric   //   template keyword and arguments. Present if and only if
39310b57cec5SDimitry Andric   //   hasTemplateKWAndArgsInfo().
39320b57cec5SDimitry Andric   //
39330b57cec5SDimitry Andric   // * An array of getNumTemplateArgs() TemplateArgumentLoc containing
39340b57cec5SDimitry Andric   //   location information for the explicitly specified template arguments.
39350b57cec5SDimitry Andric 
39360b57cec5SDimitry Andric   UnresolvedMemberExpr(const ASTContext &Context, bool HasUnresolvedUsing,
39370b57cec5SDimitry Andric                        Expr *Base, QualType BaseType, bool IsArrow,
39380b57cec5SDimitry Andric                        SourceLocation OperatorLoc,
39390b57cec5SDimitry Andric                        NestedNameSpecifierLoc QualifierLoc,
39400b57cec5SDimitry Andric                        SourceLocation TemplateKWLoc,
39410b57cec5SDimitry Andric                        const DeclarationNameInfo &MemberNameInfo,
39420b57cec5SDimitry Andric                        const TemplateArgumentListInfo *TemplateArgs,
39430b57cec5SDimitry Andric                        UnresolvedSetIterator Begin, UnresolvedSetIterator End);
39440b57cec5SDimitry Andric 
39450b57cec5SDimitry Andric   UnresolvedMemberExpr(EmptyShell Empty, unsigned NumResults,
39460b57cec5SDimitry Andric                        bool HasTemplateKWAndArgsInfo);
39470b57cec5SDimitry Andric 
numTrailingObjects(OverloadToken<DeclAccessPair>)39480b57cec5SDimitry Andric   unsigned numTrailingObjects(OverloadToken<DeclAccessPair>) const {
39490b57cec5SDimitry Andric     return getNumDecls();
39500b57cec5SDimitry Andric   }
39510b57cec5SDimitry Andric 
numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>)39520b57cec5SDimitry Andric   unsigned numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
39530b57cec5SDimitry Andric     return hasTemplateKWAndArgsInfo();
39540b57cec5SDimitry Andric   }
39550b57cec5SDimitry Andric 
39560b57cec5SDimitry Andric public:
39570b57cec5SDimitry Andric   static UnresolvedMemberExpr *
39580b57cec5SDimitry Andric   Create(const ASTContext &Context, bool HasUnresolvedUsing, Expr *Base,
39590b57cec5SDimitry Andric          QualType BaseType, bool IsArrow, SourceLocation OperatorLoc,
39600b57cec5SDimitry Andric          NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc,
39610b57cec5SDimitry Andric          const DeclarationNameInfo &MemberNameInfo,
39620b57cec5SDimitry Andric          const TemplateArgumentListInfo *TemplateArgs,
39630b57cec5SDimitry Andric          UnresolvedSetIterator Begin, UnresolvedSetIterator End);
39640b57cec5SDimitry Andric 
39650b57cec5SDimitry Andric   static UnresolvedMemberExpr *CreateEmpty(const ASTContext &Context,
39660b57cec5SDimitry Andric                                            unsigned NumResults,
39670b57cec5SDimitry Andric                                            bool HasTemplateKWAndArgsInfo,
39680b57cec5SDimitry Andric                                            unsigned NumTemplateArgs);
39690b57cec5SDimitry Andric 
39700b57cec5SDimitry Andric   /// True if this is an implicit access, i.e., one in which the
39710b57cec5SDimitry Andric   /// member being accessed was not written in the source.
39720b57cec5SDimitry Andric   ///
39730b57cec5SDimitry Andric   /// The source location of the operator is invalid in this case.
39740b57cec5SDimitry Andric   bool isImplicitAccess() const;
39750b57cec5SDimitry Andric 
39760b57cec5SDimitry Andric   /// Retrieve the base object of this member expressions,
39770b57cec5SDimitry Andric   /// e.g., the \c x in \c x.m.
getBase()39780b57cec5SDimitry Andric   Expr *getBase() {
39790b57cec5SDimitry Andric     assert(!isImplicitAccess());
39800b57cec5SDimitry Andric     return cast<Expr>(Base);
39810b57cec5SDimitry Andric   }
getBase()39820b57cec5SDimitry Andric   const Expr *getBase() const {
39830b57cec5SDimitry Andric     assert(!isImplicitAccess());
39840b57cec5SDimitry Andric     return cast<Expr>(Base);
39850b57cec5SDimitry Andric   }
39860b57cec5SDimitry Andric 
getBaseType()39870b57cec5SDimitry Andric   QualType getBaseType() const { return BaseType; }
39880b57cec5SDimitry Andric 
39890b57cec5SDimitry Andric   /// Determine whether the lookup results contain an unresolved using
39900b57cec5SDimitry Andric   /// declaration.
hasUnresolvedUsing()39910b57cec5SDimitry Andric   bool hasUnresolvedUsing() const {
39920b57cec5SDimitry Andric     return UnresolvedMemberExprBits.HasUnresolvedUsing;
39930b57cec5SDimitry Andric   }
39940b57cec5SDimitry Andric 
39950b57cec5SDimitry Andric   /// Determine whether this member expression used the '->'
39960b57cec5SDimitry Andric   /// operator; otherwise, it used the '.' operator.
isArrow()39970b57cec5SDimitry Andric   bool isArrow() const { return UnresolvedMemberExprBits.IsArrow; }
39980b57cec5SDimitry Andric 
39990b57cec5SDimitry Andric   /// Retrieve the location of the '->' or '.' operator.
getOperatorLoc()40000b57cec5SDimitry Andric   SourceLocation getOperatorLoc() const { return OperatorLoc; }
40010b57cec5SDimitry Andric 
40020b57cec5SDimitry Andric   /// Retrieve the naming class of this lookup.
40030b57cec5SDimitry Andric   CXXRecordDecl *getNamingClass();
getNamingClass()40040b57cec5SDimitry Andric   const CXXRecordDecl *getNamingClass() const {
40050b57cec5SDimitry Andric     return const_cast<UnresolvedMemberExpr *>(this)->getNamingClass();
40060b57cec5SDimitry Andric   }
40070b57cec5SDimitry Andric 
40080b57cec5SDimitry Andric   /// Retrieve the full name info for the member that this expression
40090b57cec5SDimitry Andric   /// refers to.
getMemberNameInfo()40100b57cec5SDimitry Andric   const DeclarationNameInfo &getMemberNameInfo() const { return getNameInfo(); }
40110b57cec5SDimitry Andric 
40120b57cec5SDimitry Andric   /// Retrieve the name of the member that this expression refers to.
getMemberName()40130b57cec5SDimitry Andric   DeclarationName getMemberName() const { return getName(); }
40140b57cec5SDimitry Andric 
40150b57cec5SDimitry Andric   /// Retrieve the location of the name of the member that this
40160b57cec5SDimitry Andric   /// expression refers to.
getMemberLoc()40170b57cec5SDimitry Andric   SourceLocation getMemberLoc() const { return getNameLoc(); }
40180b57cec5SDimitry Andric 
40190b57cec5SDimitry Andric   /// Return the preferred location (the member name) for the arrow when
40200b57cec5SDimitry Andric   /// diagnosing a problem with this expression.
getExprLoc()40210b57cec5SDimitry Andric   SourceLocation getExprLoc() const LLVM_READONLY { return getMemberLoc(); }
40220b57cec5SDimitry Andric 
getBeginLoc()40230b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY {
40240b57cec5SDimitry Andric     if (!isImplicitAccess())
40250b57cec5SDimitry Andric       return Base->getBeginLoc();
40260b57cec5SDimitry Andric     if (NestedNameSpecifierLoc l = getQualifierLoc())
40270b57cec5SDimitry Andric       return l.getBeginLoc();
40280b57cec5SDimitry Andric     return getMemberNameInfo().getBeginLoc();
40290b57cec5SDimitry Andric   }
40300b57cec5SDimitry Andric 
getEndLoc()40310b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY {
40320b57cec5SDimitry Andric     if (hasExplicitTemplateArgs())
40330b57cec5SDimitry Andric       return getRAngleLoc();
40340b57cec5SDimitry Andric     return getMemberNameInfo().getEndLoc();
40350b57cec5SDimitry Andric   }
40360b57cec5SDimitry Andric 
classof(const Stmt * T)40370b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
40380b57cec5SDimitry Andric     return T->getStmtClass() == UnresolvedMemberExprClass;
40390b57cec5SDimitry Andric   }
40400b57cec5SDimitry Andric 
40410b57cec5SDimitry Andric   // Iterators
children()40420b57cec5SDimitry Andric   child_range children() {
40430b57cec5SDimitry Andric     if (isImplicitAccess())
40440b57cec5SDimitry Andric       return child_range(child_iterator(), child_iterator());
40450b57cec5SDimitry Andric     return child_range(&Base, &Base + 1);
40460b57cec5SDimitry Andric   }
40470b57cec5SDimitry Andric 
children()40480b57cec5SDimitry Andric   const_child_range children() const {
40490b57cec5SDimitry Andric     if (isImplicitAccess())
40500b57cec5SDimitry Andric       return const_child_range(const_child_iterator(), const_child_iterator());
40510b57cec5SDimitry Andric     return const_child_range(&Base, &Base + 1);
40520b57cec5SDimitry Andric   }
40530b57cec5SDimitry Andric };
40540b57cec5SDimitry Andric 
getTrailingResults()40550b57cec5SDimitry Andric DeclAccessPair *OverloadExpr::getTrailingResults() {
40560b57cec5SDimitry Andric   if (auto *ULE = dyn_cast<UnresolvedLookupExpr>(this))
40570b57cec5SDimitry Andric     return ULE->getTrailingObjects<DeclAccessPair>();
40580b57cec5SDimitry Andric   return cast<UnresolvedMemberExpr>(this)->getTrailingObjects<DeclAccessPair>();
40590b57cec5SDimitry Andric }
40600b57cec5SDimitry Andric 
getTrailingASTTemplateKWAndArgsInfo()40610b57cec5SDimitry Andric ASTTemplateKWAndArgsInfo *OverloadExpr::getTrailingASTTemplateKWAndArgsInfo() {
40620b57cec5SDimitry Andric   if (!hasTemplateKWAndArgsInfo())
40630b57cec5SDimitry Andric     return nullptr;
40640b57cec5SDimitry Andric 
40650b57cec5SDimitry Andric   if (auto *ULE = dyn_cast<UnresolvedLookupExpr>(this))
40660b57cec5SDimitry Andric     return ULE->getTrailingObjects<ASTTemplateKWAndArgsInfo>();
40670b57cec5SDimitry Andric   return cast<UnresolvedMemberExpr>(this)
40680b57cec5SDimitry Andric       ->getTrailingObjects<ASTTemplateKWAndArgsInfo>();
40690b57cec5SDimitry Andric }
40700b57cec5SDimitry Andric 
getTrailingTemplateArgumentLoc()40710b57cec5SDimitry Andric TemplateArgumentLoc *OverloadExpr::getTrailingTemplateArgumentLoc() {
40720b57cec5SDimitry Andric   if (auto *ULE = dyn_cast<UnresolvedLookupExpr>(this))
40730b57cec5SDimitry Andric     return ULE->getTrailingObjects<TemplateArgumentLoc>();
40740b57cec5SDimitry Andric   return cast<UnresolvedMemberExpr>(this)
40750b57cec5SDimitry Andric       ->getTrailingObjects<TemplateArgumentLoc>();
40760b57cec5SDimitry Andric }
40770b57cec5SDimitry Andric 
getNamingClass()40780b57cec5SDimitry Andric CXXRecordDecl *OverloadExpr::getNamingClass() {
40790b57cec5SDimitry Andric   if (auto *ULE = dyn_cast<UnresolvedLookupExpr>(this))
40800b57cec5SDimitry Andric     return ULE->getNamingClass();
40810b57cec5SDimitry Andric   return cast<UnresolvedMemberExpr>(this)->getNamingClass();
40820b57cec5SDimitry Andric }
40830b57cec5SDimitry Andric 
40840b57cec5SDimitry Andric /// Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]).
40850b57cec5SDimitry Andric ///
40860b57cec5SDimitry Andric /// The noexcept expression tests whether a given expression might throw. Its
40870b57cec5SDimitry Andric /// result is a boolean constant.
40880b57cec5SDimitry Andric class CXXNoexceptExpr : public Expr {
40890b57cec5SDimitry Andric   friend class ASTStmtReader;
40900b57cec5SDimitry Andric 
40910b57cec5SDimitry Andric   Stmt *Operand;
40920b57cec5SDimitry Andric   SourceRange Range;
40930b57cec5SDimitry Andric 
40940b57cec5SDimitry Andric public:
CXXNoexceptExpr(QualType Ty,Expr * Operand,CanThrowResult Val,SourceLocation Keyword,SourceLocation RParen)40950b57cec5SDimitry Andric   CXXNoexceptExpr(QualType Ty, Expr *Operand, CanThrowResult Val,
40960b57cec5SDimitry Andric                   SourceLocation Keyword, SourceLocation RParen)
4097fe6060f1SDimitry Andric       : Expr(CXXNoexceptExprClass, Ty, VK_PRValue, OK_Ordinary),
40980b57cec5SDimitry Andric         Operand(Operand), Range(Keyword, RParen) {
40990b57cec5SDimitry Andric     CXXNoexceptExprBits.Value = Val == CT_Cannot;
41005ffd83dbSDimitry Andric     setDependence(computeDependence(this, Val));
41010b57cec5SDimitry Andric   }
41020b57cec5SDimitry Andric 
CXXNoexceptExpr(EmptyShell Empty)41030b57cec5SDimitry Andric   CXXNoexceptExpr(EmptyShell Empty) : Expr(CXXNoexceptExprClass, Empty) {}
41040b57cec5SDimitry Andric 
getOperand()41050b57cec5SDimitry Andric   Expr *getOperand() const { return static_cast<Expr *>(Operand); }
41060b57cec5SDimitry Andric 
getBeginLoc()41070b57cec5SDimitry Andric   SourceLocation getBeginLoc() const { return Range.getBegin(); }
getEndLoc()41080b57cec5SDimitry Andric   SourceLocation getEndLoc() const { return Range.getEnd(); }
getSourceRange()41090b57cec5SDimitry Andric   SourceRange getSourceRange() const { return Range; }
41100b57cec5SDimitry Andric 
getValue()41110b57cec5SDimitry Andric   bool getValue() const { return CXXNoexceptExprBits.Value; }
41120b57cec5SDimitry Andric 
classof(const Stmt * T)41130b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
41140b57cec5SDimitry Andric     return T->getStmtClass() == CXXNoexceptExprClass;
41150b57cec5SDimitry Andric   }
41160b57cec5SDimitry Andric 
41170b57cec5SDimitry Andric   // Iterators
children()41180b57cec5SDimitry Andric   child_range children() { return child_range(&Operand, &Operand + 1); }
41190b57cec5SDimitry Andric 
children()41200b57cec5SDimitry Andric   const_child_range children() const {
41210b57cec5SDimitry Andric     return const_child_range(&Operand, &Operand + 1);
41220b57cec5SDimitry Andric   }
41230b57cec5SDimitry Andric };
41240b57cec5SDimitry Andric 
41250b57cec5SDimitry Andric /// Represents a C++11 pack expansion that produces a sequence of
41260b57cec5SDimitry Andric /// expressions.
41270b57cec5SDimitry Andric ///
41280b57cec5SDimitry Andric /// A pack expansion expression contains a pattern (which itself is an
41290b57cec5SDimitry Andric /// expression) followed by an ellipsis. For example:
41300b57cec5SDimitry Andric ///
41310b57cec5SDimitry Andric /// \code
41320b57cec5SDimitry Andric /// template<typename F, typename ...Types>
41330b57cec5SDimitry Andric /// void forward(F f, Types &&...args) {
41340b57cec5SDimitry Andric ///   f(static_cast<Types&&>(args)...);
41350b57cec5SDimitry Andric /// }
41360b57cec5SDimitry Andric /// \endcode
41370b57cec5SDimitry Andric ///
41380b57cec5SDimitry Andric /// Here, the argument to the function object \c f is a pack expansion whose
41390b57cec5SDimitry Andric /// pattern is \c static_cast<Types&&>(args). When the \c forward function
41400b57cec5SDimitry Andric /// template is instantiated, the pack expansion will instantiate to zero or
41410b57cec5SDimitry Andric /// or more function arguments to the function object \c f.
41420b57cec5SDimitry Andric class PackExpansionExpr : public Expr {
41430b57cec5SDimitry Andric   friend class ASTStmtReader;
41440b57cec5SDimitry Andric   friend class ASTStmtWriter;
41450b57cec5SDimitry Andric 
41460b57cec5SDimitry Andric   SourceLocation EllipsisLoc;
41470b57cec5SDimitry Andric 
41480b57cec5SDimitry Andric   /// The number of expansions that will be produced by this pack
41490b57cec5SDimitry Andric   /// expansion expression, if known.
41500b57cec5SDimitry Andric   ///
41510b57cec5SDimitry Andric   /// When zero, the number of expansions is not known. Otherwise, this value
41520b57cec5SDimitry Andric   /// is the number of expansions + 1.
41530b57cec5SDimitry Andric   unsigned NumExpansions;
41540b57cec5SDimitry Andric 
41550b57cec5SDimitry Andric   Stmt *Pattern;
41560b57cec5SDimitry Andric 
41570b57cec5SDimitry Andric public:
PackExpansionExpr(QualType T,Expr * Pattern,SourceLocation EllipsisLoc,std::optional<unsigned> NumExpansions)41580b57cec5SDimitry Andric   PackExpansionExpr(QualType T, Expr *Pattern, SourceLocation EllipsisLoc,
4159bdd1243dSDimitry Andric                     std::optional<unsigned> NumExpansions)
41600b57cec5SDimitry Andric       : Expr(PackExpansionExprClass, T, Pattern->getValueKind(),
41615ffd83dbSDimitry Andric              Pattern->getObjectKind()),
41620b57cec5SDimitry Andric         EllipsisLoc(EllipsisLoc),
41630b57cec5SDimitry Andric         NumExpansions(NumExpansions ? *NumExpansions + 1 : 0),
41645ffd83dbSDimitry Andric         Pattern(Pattern) {
41655ffd83dbSDimitry Andric     setDependence(computeDependence(this));
41665ffd83dbSDimitry Andric   }
41670b57cec5SDimitry Andric 
PackExpansionExpr(EmptyShell Empty)41680b57cec5SDimitry Andric   PackExpansionExpr(EmptyShell Empty) : Expr(PackExpansionExprClass, Empty) {}
41690b57cec5SDimitry Andric 
41700b57cec5SDimitry Andric   /// Retrieve the pattern of the pack expansion.
getPattern()41710b57cec5SDimitry Andric   Expr *getPattern() { return reinterpret_cast<Expr *>(Pattern); }
41720b57cec5SDimitry Andric 
41730b57cec5SDimitry Andric   /// Retrieve the pattern of the pack expansion.
getPattern()41740b57cec5SDimitry Andric   const Expr *getPattern() const { return reinterpret_cast<Expr *>(Pattern); }
41750b57cec5SDimitry Andric 
41760b57cec5SDimitry Andric   /// Retrieve the location of the ellipsis that describes this pack
41770b57cec5SDimitry Andric   /// expansion.
getEllipsisLoc()41780b57cec5SDimitry Andric   SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
41790b57cec5SDimitry Andric 
41800b57cec5SDimitry Andric   /// Determine the number of expansions that will be produced when
41810b57cec5SDimitry Andric   /// this pack expansion is instantiated, if already known.
getNumExpansions()4182bdd1243dSDimitry Andric   std::optional<unsigned> getNumExpansions() const {
41830b57cec5SDimitry Andric     if (NumExpansions)
41840b57cec5SDimitry Andric       return NumExpansions - 1;
41850b57cec5SDimitry Andric 
4186bdd1243dSDimitry Andric     return std::nullopt;
41870b57cec5SDimitry Andric   }
41880b57cec5SDimitry Andric 
getBeginLoc()41890b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY {
41900b57cec5SDimitry Andric     return Pattern->getBeginLoc();
41910b57cec5SDimitry Andric   }
41920b57cec5SDimitry Andric 
getEndLoc()41930b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY { return EllipsisLoc; }
41940b57cec5SDimitry Andric 
classof(const Stmt * T)41950b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
41960b57cec5SDimitry Andric     return T->getStmtClass() == PackExpansionExprClass;
41970b57cec5SDimitry Andric   }
41980b57cec5SDimitry Andric 
41990b57cec5SDimitry Andric   // Iterators
children()42000b57cec5SDimitry Andric   child_range children() {
42010b57cec5SDimitry Andric     return child_range(&Pattern, &Pattern + 1);
42020b57cec5SDimitry Andric   }
42030b57cec5SDimitry Andric 
children()42040b57cec5SDimitry Andric   const_child_range children() const {
42050b57cec5SDimitry Andric     return const_child_range(&Pattern, &Pattern + 1);
42060b57cec5SDimitry Andric   }
42070b57cec5SDimitry Andric };
42080b57cec5SDimitry Andric 
42090b57cec5SDimitry Andric /// Represents an expression that computes the length of a parameter
42100b57cec5SDimitry Andric /// pack.
42110b57cec5SDimitry Andric ///
42120b57cec5SDimitry Andric /// \code
42130b57cec5SDimitry Andric /// template<typename ...Types>
42140b57cec5SDimitry Andric /// struct count {
42150b57cec5SDimitry Andric ///   static const unsigned value = sizeof...(Types);
42160b57cec5SDimitry Andric /// };
42170b57cec5SDimitry Andric /// \endcode
42180b57cec5SDimitry Andric class SizeOfPackExpr final
42190b57cec5SDimitry Andric     : public Expr,
42200b57cec5SDimitry Andric       private llvm::TrailingObjects<SizeOfPackExpr, TemplateArgument> {
42210b57cec5SDimitry Andric   friend class ASTStmtReader;
42220b57cec5SDimitry Andric   friend class ASTStmtWriter;
42230b57cec5SDimitry Andric   friend TrailingObjects;
42240b57cec5SDimitry Andric 
42250b57cec5SDimitry Andric   /// The location of the \c sizeof keyword.
42260b57cec5SDimitry Andric   SourceLocation OperatorLoc;
42270b57cec5SDimitry Andric 
42280b57cec5SDimitry Andric   /// The location of the name of the parameter pack.
42290b57cec5SDimitry Andric   SourceLocation PackLoc;
42300b57cec5SDimitry Andric 
42310b57cec5SDimitry Andric   /// The location of the closing parenthesis.
42320b57cec5SDimitry Andric   SourceLocation RParenLoc;
42330b57cec5SDimitry Andric 
42340b57cec5SDimitry Andric   /// The length of the parameter pack, if known.
42350b57cec5SDimitry Andric   ///
42360b57cec5SDimitry Andric   /// When this expression is not value-dependent, this is the length of
42370b57cec5SDimitry Andric   /// the pack. When the expression was parsed rather than instantiated
42380b57cec5SDimitry Andric   /// (and thus is value-dependent), this is zero.
42390b57cec5SDimitry Andric   ///
42400b57cec5SDimitry Andric   /// After partial substitution into a sizeof...(X) expression (for instance,
42410b57cec5SDimitry Andric   /// within an alias template or during function template argument deduction),
42420b57cec5SDimitry Andric   /// we store a trailing array of partially-substituted TemplateArguments,
42430b57cec5SDimitry Andric   /// and this is the length of that array.
42440b57cec5SDimitry Andric   unsigned Length;
42450b57cec5SDimitry Andric 
42460b57cec5SDimitry Andric   /// The parameter pack.
42470b57cec5SDimitry Andric   NamedDecl *Pack = nullptr;
42480b57cec5SDimitry Andric 
42490b57cec5SDimitry Andric   /// Create an expression that computes the length of
42500b57cec5SDimitry Andric   /// the given parameter pack.
SizeOfPackExpr(QualType SizeType,SourceLocation OperatorLoc,NamedDecl * Pack,SourceLocation PackLoc,SourceLocation RParenLoc,std::optional<unsigned> Length,ArrayRef<TemplateArgument> PartialArgs)42510b57cec5SDimitry Andric   SizeOfPackExpr(QualType SizeType, SourceLocation OperatorLoc, NamedDecl *Pack,
42520b57cec5SDimitry Andric                  SourceLocation PackLoc, SourceLocation RParenLoc,
4253bdd1243dSDimitry Andric                  std::optional<unsigned> Length,
42545ffd83dbSDimitry Andric                  ArrayRef<TemplateArgument> PartialArgs)
4255fe6060f1SDimitry Andric       : Expr(SizeOfPackExprClass, SizeType, VK_PRValue, OK_Ordinary),
42560b57cec5SDimitry Andric         OperatorLoc(OperatorLoc), PackLoc(PackLoc), RParenLoc(RParenLoc),
42570b57cec5SDimitry Andric         Length(Length ? *Length : PartialArgs.size()), Pack(Pack) {
42580b57cec5SDimitry Andric     assert((!Length || PartialArgs.empty()) &&
42590b57cec5SDimitry Andric            "have partial args for non-dependent sizeof... expression");
42600b57cec5SDimitry Andric     auto *Args = getTrailingObjects<TemplateArgument>();
42610b57cec5SDimitry Andric     std::uninitialized_copy(PartialArgs.begin(), PartialArgs.end(), Args);
42625ffd83dbSDimitry Andric     setDependence(Length ? ExprDependence::None
42635ffd83dbSDimitry Andric                          : ExprDependence::ValueInstantiation);
42640b57cec5SDimitry Andric   }
42650b57cec5SDimitry Andric 
42660b57cec5SDimitry Andric   /// Create an empty expression.
SizeOfPackExpr(EmptyShell Empty,unsigned NumPartialArgs)42670b57cec5SDimitry Andric   SizeOfPackExpr(EmptyShell Empty, unsigned NumPartialArgs)
42680b57cec5SDimitry Andric       : Expr(SizeOfPackExprClass, Empty), Length(NumPartialArgs) {}
42690b57cec5SDimitry Andric 
42700b57cec5SDimitry Andric public:
4271bdd1243dSDimitry Andric   static SizeOfPackExpr *
4272bdd1243dSDimitry Andric   Create(ASTContext &Context, SourceLocation OperatorLoc, NamedDecl *Pack,
4273bdd1243dSDimitry Andric          SourceLocation PackLoc, SourceLocation RParenLoc,
4274bdd1243dSDimitry Andric          std::optional<unsigned> Length = std::nullopt,
4275bdd1243dSDimitry Andric          ArrayRef<TemplateArgument> PartialArgs = std::nullopt);
42760b57cec5SDimitry Andric   static SizeOfPackExpr *CreateDeserialized(ASTContext &Context,
42770b57cec5SDimitry Andric                                             unsigned NumPartialArgs);
42780b57cec5SDimitry Andric 
42790b57cec5SDimitry Andric   /// Determine the location of the 'sizeof' keyword.
getOperatorLoc()42800b57cec5SDimitry Andric   SourceLocation getOperatorLoc() const { return OperatorLoc; }
42810b57cec5SDimitry Andric 
42820b57cec5SDimitry Andric   /// Determine the location of the parameter pack.
getPackLoc()42830b57cec5SDimitry Andric   SourceLocation getPackLoc() const { return PackLoc; }
42840b57cec5SDimitry Andric 
42850b57cec5SDimitry Andric   /// Determine the location of the right parenthesis.
getRParenLoc()42860b57cec5SDimitry Andric   SourceLocation getRParenLoc() const { return RParenLoc; }
42870b57cec5SDimitry Andric 
42880b57cec5SDimitry Andric   /// Retrieve the parameter pack.
getPack()42890b57cec5SDimitry Andric   NamedDecl *getPack() const { return Pack; }
42900b57cec5SDimitry Andric 
42910b57cec5SDimitry Andric   /// Retrieve the length of the parameter pack.
42920b57cec5SDimitry Andric   ///
42930b57cec5SDimitry Andric   /// This routine may only be invoked when the expression is not
42940b57cec5SDimitry Andric   /// value-dependent.
getPackLength()42950b57cec5SDimitry Andric   unsigned getPackLength() const {
42960b57cec5SDimitry Andric     assert(!isValueDependent() &&
42970b57cec5SDimitry Andric            "Cannot get the length of a value-dependent pack size expression");
42980b57cec5SDimitry Andric     return Length;
42990b57cec5SDimitry Andric   }
43000b57cec5SDimitry Andric 
43010b57cec5SDimitry Andric   /// Determine whether this represents a partially-substituted sizeof...
43020b57cec5SDimitry Andric   /// expression, such as is produced for:
43030b57cec5SDimitry Andric   ///
43040b57cec5SDimitry Andric   ///   template<typename ...Ts> using X = int[sizeof...(Ts)];
43050b57cec5SDimitry Andric   ///   template<typename ...Us> void f(X<Us..., 1, 2, 3, Us...>);
isPartiallySubstituted()43060b57cec5SDimitry Andric   bool isPartiallySubstituted() const {
43070b57cec5SDimitry Andric     return isValueDependent() && Length;
43080b57cec5SDimitry Andric   }
43090b57cec5SDimitry Andric 
43100b57cec5SDimitry Andric   /// Get
getPartialArguments()43110b57cec5SDimitry Andric   ArrayRef<TemplateArgument> getPartialArguments() const {
43120b57cec5SDimitry Andric     assert(isPartiallySubstituted());
43130b57cec5SDimitry Andric     const auto *Args = getTrailingObjects<TemplateArgument>();
4314bdd1243dSDimitry Andric     return llvm::ArrayRef(Args, Args + Length);
43150b57cec5SDimitry Andric   }
43160b57cec5SDimitry Andric 
getBeginLoc()43170b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY { return OperatorLoc; }
getEndLoc()43180b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
43190b57cec5SDimitry Andric 
classof(const Stmt * T)43200b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
43210b57cec5SDimitry Andric     return T->getStmtClass() == SizeOfPackExprClass;
43220b57cec5SDimitry Andric   }
43230b57cec5SDimitry Andric 
43240b57cec5SDimitry Andric   // Iterators
children()43250b57cec5SDimitry Andric   child_range children() {
43260b57cec5SDimitry Andric     return child_range(child_iterator(), child_iterator());
43270b57cec5SDimitry Andric   }
43280b57cec5SDimitry Andric 
children()43290b57cec5SDimitry Andric   const_child_range children() const {
43300b57cec5SDimitry Andric     return const_child_range(const_child_iterator(), const_child_iterator());
43310b57cec5SDimitry Andric   }
43320b57cec5SDimitry Andric };
43330b57cec5SDimitry Andric 
43340b57cec5SDimitry Andric /// Represents a reference to a non-type template parameter
43350b57cec5SDimitry Andric /// that has been substituted with a template argument.
43360b57cec5SDimitry Andric class SubstNonTypeTemplateParmExpr : public Expr {
43370b57cec5SDimitry Andric   friend class ASTReader;
43380b57cec5SDimitry Andric   friend class ASTStmtReader;
43390b57cec5SDimitry Andric 
43400b57cec5SDimitry Andric   /// The replacement expression.
43410b57cec5SDimitry Andric   Stmt *Replacement;
43420b57cec5SDimitry Andric 
4343bdd1243dSDimitry Andric   /// The associated declaration and a flag indicating if it was a reference
4344bdd1243dSDimitry Andric   /// parameter. For class NTTPs, we can't determine that based on the value
4345bdd1243dSDimitry Andric   /// category alone.
4346bdd1243dSDimitry Andric   llvm::PointerIntPair<Decl *, 1, bool> AssociatedDeclAndRef;
4347bdd1243dSDimitry Andric 
4348bdd1243dSDimitry Andric   unsigned Index : 15;
4349bdd1243dSDimitry Andric   unsigned PackIndex : 16;
4350bdd1243dSDimitry Andric 
SubstNonTypeTemplateParmExpr(EmptyShell Empty)43510b57cec5SDimitry Andric   explicit SubstNonTypeTemplateParmExpr(EmptyShell Empty)
43520b57cec5SDimitry Andric       : Expr(SubstNonTypeTemplateParmExprClass, Empty) {}
43530b57cec5SDimitry Andric 
43540b57cec5SDimitry Andric public:
SubstNonTypeTemplateParmExpr(QualType Ty,ExprValueKind ValueKind,SourceLocation Loc,Expr * Replacement,Decl * AssociatedDecl,unsigned Index,std::optional<unsigned> PackIndex,bool RefParam)43550b57cec5SDimitry Andric   SubstNonTypeTemplateParmExpr(QualType Ty, ExprValueKind ValueKind,
4356bdd1243dSDimitry Andric                                SourceLocation Loc, Expr *Replacement,
4357bdd1243dSDimitry Andric                                Decl *AssociatedDecl, unsigned Index,
4358bdd1243dSDimitry Andric                                std::optional<unsigned> PackIndex, bool RefParam)
43595ffd83dbSDimitry Andric       : Expr(SubstNonTypeTemplateParmExprClass, Ty, ValueKind, OK_Ordinary),
4360bdd1243dSDimitry Andric         Replacement(Replacement),
4361bdd1243dSDimitry Andric         AssociatedDeclAndRef(AssociatedDecl, RefParam), Index(Index),
4362bdd1243dSDimitry Andric         PackIndex(PackIndex ? *PackIndex + 1 : 0) {
4363bdd1243dSDimitry Andric     assert(AssociatedDecl != nullptr);
43640b57cec5SDimitry Andric     SubstNonTypeTemplateParmExprBits.NameLoc = Loc;
43655ffd83dbSDimitry Andric     setDependence(computeDependence(this));
43660b57cec5SDimitry Andric   }
43670b57cec5SDimitry Andric 
getNameLoc()43680b57cec5SDimitry Andric   SourceLocation getNameLoc() const {
43690b57cec5SDimitry Andric     return SubstNonTypeTemplateParmExprBits.NameLoc;
43700b57cec5SDimitry Andric   }
getBeginLoc()43710b57cec5SDimitry Andric   SourceLocation getBeginLoc() const { return getNameLoc(); }
getEndLoc()43720b57cec5SDimitry Andric   SourceLocation getEndLoc() const { return getNameLoc(); }
43730b57cec5SDimitry Andric 
getReplacement()43740b57cec5SDimitry Andric   Expr *getReplacement() const { return cast<Expr>(Replacement); }
43750b57cec5SDimitry Andric 
4376bdd1243dSDimitry Andric   /// A template-like entity which owns the whole pattern being substituted.
4377bdd1243dSDimitry Andric   /// This will own a set of template parameters.
getAssociatedDecl()4378bdd1243dSDimitry Andric   Decl *getAssociatedDecl() const { return AssociatedDeclAndRef.getPointer(); }
4379bdd1243dSDimitry Andric 
4380bdd1243dSDimitry Andric   /// Returns the index of the replaced parameter in the associated declaration.
4381bdd1243dSDimitry Andric   /// This should match the result of `getParameter()->getIndex()`.
getIndex()4382bdd1243dSDimitry Andric   unsigned getIndex() const { return Index; }
4383bdd1243dSDimitry Andric 
getPackIndex()4384bdd1243dSDimitry Andric   std::optional<unsigned> getPackIndex() const {
4385bdd1243dSDimitry Andric     if (PackIndex == 0)
4386bdd1243dSDimitry Andric       return std::nullopt;
4387bdd1243dSDimitry Andric     return PackIndex - 1;
4388e8d8bef9SDimitry Andric   }
4389e8d8bef9SDimitry Andric 
4390bdd1243dSDimitry Andric   NonTypeTemplateParmDecl *getParameter() const;
4391bdd1243dSDimitry Andric 
isReferenceParameter()4392bdd1243dSDimitry Andric   bool isReferenceParameter() const { return AssociatedDeclAndRef.getInt(); }
4393e8d8bef9SDimitry Andric 
4394e8d8bef9SDimitry Andric   /// Determine the substituted type of the template parameter.
4395e8d8bef9SDimitry Andric   QualType getParameterType(const ASTContext &Ctx) const;
43960b57cec5SDimitry Andric 
classof(const Stmt * s)43970b57cec5SDimitry Andric   static bool classof(const Stmt *s) {
43980b57cec5SDimitry Andric     return s->getStmtClass() == SubstNonTypeTemplateParmExprClass;
43990b57cec5SDimitry Andric   }
44000b57cec5SDimitry Andric 
44010b57cec5SDimitry Andric   // Iterators
children()44020b57cec5SDimitry Andric   child_range children() { return child_range(&Replacement, &Replacement + 1); }
44030b57cec5SDimitry Andric 
children()44040b57cec5SDimitry Andric   const_child_range children() const {
44050b57cec5SDimitry Andric     return const_child_range(&Replacement, &Replacement + 1);
44060b57cec5SDimitry Andric   }
44070b57cec5SDimitry Andric };
44080b57cec5SDimitry Andric 
44090b57cec5SDimitry Andric /// Represents a reference to a non-type template parameter pack that
44100b57cec5SDimitry Andric /// has been substituted with a non-template argument pack.
44110b57cec5SDimitry Andric ///
44120b57cec5SDimitry Andric /// When a pack expansion in the source code contains multiple parameter packs
44130b57cec5SDimitry Andric /// and those parameter packs correspond to different levels of template
44140b57cec5SDimitry Andric /// parameter lists, this node is used to represent a non-type template
44150b57cec5SDimitry Andric /// parameter pack from an outer level, which has already had its argument pack
44160b57cec5SDimitry Andric /// substituted but that still lives within a pack expansion that itself
44170b57cec5SDimitry Andric /// could not be instantiated. When actually performing a substitution into
44180b57cec5SDimitry Andric /// that pack expansion (e.g., when all template parameters have corresponding
44190b57cec5SDimitry Andric /// arguments), this type will be replaced with the appropriate underlying
44200b57cec5SDimitry Andric /// expression at the current pack substitution index.
44210b57cec5SDimitry Andric class SubstNonTypeTemplateParmPackExpr : public Expr {
44220b57cec5SDimitry Andric   friend class ASTReader;
44230b57cec5SDimitry Andric   friend class ASTStmtReader;
44240b57cec5SDimitry Andric 
44250b57cec5SDimitry Andric   /// The non-type template parameter pack itself.
4426bdd1243dSDimitry Andric   Decl *AssociatedDecl;
44270b57cec5SDimitry Andric 
44280b57cec5SDimitry Andric   /// A pointer to the set of template arguments that this
44290b57cec5SDimitry Andric   /// parameter pack is instantiated with.
44300b57cec5SDimitry Andric   const TemplateArgument *Arguments;
44310b57cec5SDimitry Andric 
44320b57cec5SDimitry Andric   /// The number of template arguments in \c Arguments.
4433bdd1243dSDimitry Andric   unsigned NumArguments : 16;
4434bdd1243dSDimitry Andric 
4435bdd1243dSDimitry Andric   unsigned Index : 16;
44360b57cec5SDimitry Andric 
44370b57cec5SDimitry Andric   /// The location of the non-type template parameter pack reference.
44380b57cec5SDimitry Andric   SourceLocation NameLoc;
44390b57cec5SDimitry Andric 
SubstNonTypeTemplateParmPackExpr(EmptyShell Empty)44400b57cec5SDimitry Andric   explicit SubstNonTypeTemplateParmPackExpr(EmptyShell Empty)
44410b57cec5SDimitry Andric       : Expr(SubstNonTypeTemplateParmPackExprClass, Empty) {}
44420b57cec5SDimitry Andric 
44430b57cec5SDimitry Andric public:
4444bdd1243dSDimitry Andric   SubstNonTypeTemplateParmPackExpr(QualType T, ExprValueKind ValueKind,
44450b57cec5SDimitry Andric                                    SourceLocation NameLoc,
4446bdd1243dSDimitry Andric                                    const TemplateArgument &ArgPack,
4447bdd1243dSDimitry Andric                                    Decl *AssociatedDecl, unsigned Index);
4448bdd1243dSDimitry Andric 
4449bdd1243dSDimitry Andric   /// A template-like entity which owns the whole pattern being substituted.
4450bdd1243dSDimitry Andric   /// This will own a set of template parameters.
getAssociatedDecl()4451bdd1243dSDimitry Andric   Decl *getAssociatedDecl() const { return AssociatedDecl; }
4452bdd1243dSDimitry Andric 
4453bdd1243dSDimitry Andric   /// Returns the index of the replaced parameter in the associated declaration.
4454bdd1243dSDimitry Andric   /// This should match the result of `getParameterPack()->getIndex()`.
getIndex()4455bdd1243dSDimitry Andric   unsigned getIndex() const { return Index; }
44560b57cec5SDimitry Andric 
44570b57cec5SDimitry Andric   /// Retrieve the non-type template parameter pack being substituted.
4458bdd1243dSDimitry Andric   NonTypeTemplateParmDecl *getParameterPack() const;
44590b57cec5SDimitry Andric 
44600b57cec5SDimitry Andric   /// Retrieve the location of the parameter pack name.
getParameterPackLocation()44610b57cec5SDimitry Andric   SourceLocation getParameterPackLocation() const { return NameLoc; }
44620b57cec5SDimitry Andric 
44630b57cec5SDimitry Andric   /// Retrieve the template argument pack containing the substituted
44640b57cec5SDimitry Andric   /// template arguments.
44650b57cec5SDimitry Andric   TemplateArgument getArgumentPack() const;
44660b57cec5SDimitry Andric 
getBeginLoc()44670b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY { return NameLoc; }
getEndLoc()44680b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY { return NameLoc; }
44690b57cec5SDimitry Andric 
classof(const Stmt * T)44700b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
44710b57cec5SDimitry Andric     return T->getStmtClass() == SubstNonTypeTemplateParmPackExprClass;
44720b57cec5SDimitry Andric   }
44730b57cec5SDimitry Andric 
44740b57cec5SDimitry Andric   // Iterators
children()44750b57cec5SDimitry Andric   child_range children() {
44760b57cec5SDimitry Andric     return child_range(child_iterator(), child_iterator());
44770b57cec5SDimitry Andric   }
44780b57cec5SDimitry Andric 
children()44790b57cec5SDimitry Andric   const_child_range children() const {
44800b57cec5SDimitry Andric     return const_child_range(const_child_iterator(), const_child_iterator());
44810b57cec5SDimitry Andric   }
44820b57cec5SDimitry Andric };
44830b57cec5SDimitry Andric 
44840b57cec5SDimitry Andric /// Represents a reference to a function parameter pack or init-capture pack
44850b57cec5SDimitry Andric /// that has been substituted but not yet expanded.
44860b57cec5SDimitry Andric ///
44870b57cec5SDimitry Andric /// When a pack expansion contains multiple parameter packs at different levels,
44880b57cec5SDimitry Andric /// this node is used to represent a function parameter pack at an outer level
44890b57cec5SDimitry Andric /// which we have already substituted to refer to expanded parameters, but where
44900b57cec5SDimitry Andric /// the containing pack expansion cannot yet be expanded.
44910b57cec5SDimitry Andric ///
44920b57cec5SDimitry Andric /// \code
44930b57cec5SDimitry Andric /// template<typename...Ts> struct S {
44940b57cec5SDimitry Andric ///   template<typename...Us> auto f(Ts ...ts) -> decltype(g(Us(ts)...));
44950b57cec5SDimitry Andric /// };
44960b57cec5SDimitry Andric /// template struct S<int, int>;
44970b57cec5SDimitry Andric /// \endcode
44980b57cec5SDimitry Andric class FunctionParmPackExpr final
44990b57cec5SDimitry Andric     : public Expr,
45000b57cec5SDimitry Andric       private llvm::TrailingObjects<FunctionParmPackExpr, VarDecl *> {
45010b57cec5SDimitry Andric   friend class ASTReader;
45020b57cec5SDimitry Andric   friend class ASTStmtReader;
45030b57cec5SDimitry Andric   friend TrailingObjects;
45040b57cec5SDimitry Andric 
45050b57cec5SDimitry Andric   /// The function parameter pack which was referenced.
45060b57cec5SDimitry Andric   VarDecl *ParamPack;
45070b57cec5SDimitry Andric 
45080b57cec5SDimitry Andric   /// The location of the function parameter pack reference.
45090b57cec5SDimitry Andric   SourceLocation NameLoc;
45100b57cec5SDimitry Andric 
45110b57cec5SDimitry Andric   /// The number of expansions of this pack.
45120b57cec5SDimitry Andric   unsigned NumParameters;
45130b57cec5SDimitry Andric 
45140b57cec5SDimitry Andric   FunctionParmPackExpr(QualType T, VarDecl *ParamPack,
45150b57cec5SDimitry Andric                        SourceLocation NameLoc, unsigned NumParams,
45160b57cec5SDimitry Andric                        VarDecl *const *Params);
45170b57cec5SDimitry Andric 
45180b57cec5SDimitry Andric public:
45190b57cec5SDimitry Andric   static FunctionParmPackExpr *Create(const ASTContext &Context, QualType T,
45200b57cec5SDimitry Andric                                       VarDecl *ParamPack,
45210b57cec5SDimitry Andric                                       SourceLocation NameLoc,
45220b57cec5SDimitry Andric                                       ArrayRef<VarDecl *> Params);
45230b57cec5SDimitry Andric   static FunctionParmPackExpr *CreateEmpty(const ASTContext &Context,
45240b57cec5SDimitry Andric                                            unsigned NumParams);
45250b57cec5SDimitry Andric 
45260b57cec5SDimitry Andric   /// Get the parameter pack which this expression refers to.
getParameterPack()45270b57cec5SDimitry Andric   VarDecl *getParameterPack() const { return ParamPack; }
45280b57cec5SDimitry Andric 
45290b57cec5SDimitry Andric   /// Get the location of the parameter pack.
getParameterPackLocation()45300b57cec5SDimitry Andric   SourceLocation getParameterPackLocation() const { return NameLoc; }
45310b57cec5SDimitry Andric 
45320b57cec5SDimitry Andric   /// Iterators over the parameters which the parameter pack expanded
45330b57cec5SDimitry Andric   /// into.
45340b57cec5SDimitry Andric   using iterator = VarDecl * const *;
begin()45350b57cec5SDimitry Andric   iterator begin() const { return getTrailingObjects<VarDecl *>(); }
end()45360b57cec5SDimitry Andric   iterator end() const { return begin() + NumParameters; }
45370b57cec5SDimitry Andric 
45380b57cec5SDimitry Andric   /// Get the number of parameters in this parameter pack.
getNumExpansions()45390b57cec5SDimitry Andric   unsigned getNumExpansions() const { return NumParameters; }
45400b57cec5SDimitry Andric 
45410b57cec5SDimitry Andric   /// Get an expansion of the parameter pack by index.
getExpansion(unsigned I)45420b57cec5SDimitry Andric   VarDecl *getExpansion(unsigned I) const { return begin()[I]; }
45430b57cec5SDimitry Andric 
getBeginLoc()45440b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY { return NameLoc; }
getEndLoc()45450b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY { return NameLoc; }
45460b57cec5SDimitry Andric 
classof(const Stmt * T)45470b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
45480b57cec5SDimitry Andric     return T->getStmtClass() == FunctionParmPackExprClass;
45490b57cec5SDimitry Andric   }
45500b57cec5SDimitry Andric 
children()45510b57cec5SDimitry Andric   child_range children() {
45520b57cec5SDimitry Andric     return child_range(child_iterator(), child_iterator());
45530b57cec5SDimitry Andric   }
45540b57cec5SDimitry Andric 
children()45550b57cec5SDimitry Andric   const_child_range children() const {
45560b57cec5SDimitry Andric     return const_child_range(const_child_iterator(), const_child_iterator());
45570b57cec5SDimitry Andric   }
45580b57cec5SDimitry Andric };
45590b57cec5SDimitry Andric 
45600b57cec5SDimitry Andric /// Represents a prvalue temporary that is written into memory so that
45610b57cec5SDimitry Andric /// a reference can bind to it.
45620b57cec5SDimitry Andric ///
45630b57cec5SDimitry Andric /// Prvalue expressions are materialized when they need to have an address
45640b57cec5SDimitry Andric /// in memory for a reference to bind to. This happens when binding a
45650b57cec5SDimitry Andric /// reference to the result of a conversion, e.g.,
45660b57cec5SDimitry Andric ///
45670b57cec5SDimitry Andric /// \code
45680b57cec5SDimitry Andric /// const int &r = 1.0;
45690b57cec5SDimitry Andric /// \endcode
45700b57cec5SDimitry Andric ///
45710b57cec5SDimitry Andric /// Here, 1.0 is implicitly converted to an \c int. That resulting \c int is
45720b57cec5SDimitry Andric /// then materialized via a \c MaterializeTemporaryExpr, and the reference
45730b57cec5SDimitry Andric /// binds to the temporary. \c MaterializeTemporaryExprs are always glvalues
45740b57cec5SDimitry Andric /// (either an lvalue or an xvalue, depending on the kind of reference binding
45750b57cec5SDimitry Andric /// to it), maintaining the invariant that references always bind to glvalues.
45760b57cec5SDimitry Andric ///
45770b57cec5SDimitry Andric /// Reference binding and copy-elision can both extend the lifetime of a
45780b57cec5SDimitry Andric /// temporary. When either happens, the expression will also track the
45790b57cec5SDimitry Andric /// declaration which is responsible for the lifetime extension.
45800b57cec5SDimitry Andric class MaterializeTemporaryExpr : public Expr {
45810b57cec5SDimitry Andric private:
45820b57cec5SDimitry Andric   friend class ASTStmtReader;
45830b57cec5SDimitry Andric   friend class ASTStmtWriter;
45840b57cec5SDimitry Andric 
4585480093f4SDimitry Andric   llvm::PointerUnion<Stmt *, LifetimeExtendedTemporaryDecl *> State;
45860b57cec5SDimitry Andric 
45870b57cec5SDimitry Andric public:
45880b57cec5SDimitry Andric   MaterializeTemporaryExpr(QualType T, Expr *Temporary,
4589480093f4SDimitry Andric                            bool BoundToLvalueReference,
4590480093f4SDimitry Andric                            LifetimeExtendedTemporaryDecl *MTD = nullptr);
45910b57cec5SDimitry Andric 
MaterializeTemporaryExpr(EmptyShell Empty)45920b57cec5SDimitry Andric   MaterializeTemporaryExpr(EmptyShell Empty)
45930b57cec5SDimitry Andric       : Expr(MaterializeTemporaryExprClass, Empty) {}
45940b57cec5SDimitry Andric 
45950b57cec5SDimitry Andric   /// Retrieve the temporary-generating subexpression whose value will
45960b57cec5SDimitry Andric   /// be materialized into a glvalue.
getSubExpr()4597480093f4SDimitry Andric   Expr *getSubExpr() const {
4598480093f4SDimitry Andric     return cast<Expr>(
4599480093f4SDimitry Andric         State.is<Stmt *>()
4600480093f4SDimitry Andric             ? State.get<Stmt *>()
4601480093f4SDimitry Andric             : State.get<LifetimeExtendedTemporaryDecl *>()->getTemporaryExpr());
4602480093f4SDimitry Andric   }
46030b57cec5SDimitry Andric 
46040b57cec5SDimitry Andric   /// Retrieve the storage duration for the materialized temporary.
getStorageDuration()46050b57cec5SDimitry Andric   StorageDuration getStorageDuration() const {
4606480093f4SDimitry Andric     return State.is<Stmt *>() ? SD_FullExpression
4607480093f4SDimitry Andric                               : State.get<LifetimeExtendedTemporaryDecl *>()
4608480093f4SDimitry Andric                                     ->getStorageDuration();
4609480093f4SDimitry Andric   }
4610480093f4SDimitry Andric 
4611480093f4SDimitry Andric   /// Get the storage for the constant value of a materialized temporary
4612480093f4SDimitry Andric   /// of static storage duration.
getOrCreateValue(bool MayCreate)4613480093f4SDimitry Andric   APValue *getOrCreateValue(bool MayCreate) const {
4614480093f4SDimitry Andric     assert(State.is<LifetimeExtendedTemporaryDecl *>() &&
4615480093f4SDimitry Andric            "the temporary has not been lifetime extended");
4616480093f4SDimitry Andric     return State.get<LifetimeExtendedTemporaryDecl *>()->getOrCreateValue(
4617480093f4SDimitry Andric         MayCreate);
4618480093f4SDimitry Andric   }
4619480093f4SDimitry Andric 
getLifetimeExtendedTemporaryDecl()4620480093f4SDimitry Andric   LifetimeExtendedTemporaryDecl *getLifetimeExtendedTemporaryDecl() {
4621480093f4SDimitry Andric     return State.dyn_cast<LifetimeExtendedTemporaryDecl *>();
4622480093f4SDimitry Andric   }
4623480093f4SDimitry Andric   const LifetimeExtendedTemporaryDecl *
getLifetimeExtendedTemporaryDecl()4624480093f4SDimitry Andric   getLifetimeExtendedTemporaryDecl() const {
4625480093f4SDimitry Andric     return State.dyn_cast<LifetimeExtendedTemporaryDecl *>();
46260b57cec5SDimitry Andric   }
46270b57cec5SDimitry Andric 
46280b57cec5SDimitry Andric   /// Get the declaration which triggered the lifetime-extension of this
46290b57cec5SDimitry Andric   /// temporary, if any.
getExtendingDecl()4630480093f4SDimitry Andric   ValueDecl *getExtendingDecl() {
46310b57cec5SDimitry Andric     return State.is<Stmt *>() ? nullptr
4632480093f4SDimitry Andric                               : State.get<LifetimeExtendedTemporaryDecl *>()
4633480093f4SDimitry Andric                                     ->getExtendingDecl();
4634480093f4SDimitry Andric   }
getExtendingDecl()4635480093f4SDimitry Andric   const ValueDecl *getExtendingDecl() const {
4636480093f4SDimitry Andric     return const_cast<MaterializeTemporaryExpr *>(this)->getExtendingDecl();
46370b57cec5SDimitry Andric   }
46380b57cec5SDimitry Andric 
4639480093f4SDimitry Andric   void setExtendingDecl(ValueDecl *ExtendedBy, unsigned ManglingNumber);
46400b57cec5SDimitry Andric 
getManglingNumber()46410b57cec5SDimitry Andric   unsigned getManglingNumber() const {
4642480093f4SDimitry Andric     return State.is<Stmt *>() ? 0
4643480093f4SDimitry Andric                               : State.get<LifetimeExtendedTemporaryDecl *>()
4644480093f4SDimitry Andric                                     ->getManglingNumber();
46450b57cec5SDimitry Andric   }
46460b57cec5SDimitry Andric 
46470b57cec5SDimitry Andric   /// Determine whether this materialized temporary is bound to an
46480b57cec5SDimitry Andric   /// lvalue reference; otherwise, it's bound to an rvalue reference.
isBoundToLvalueReference()4649fe6060f1SDimitry Andric   bool isBoundToLvalueReference() const { return isLValue(); }
46500b57cec5SDimitry Andric 
4651e8d8bef9SDimitry Andric   /// Determine whether this temporary object is usable in constant
4652e8d8bef9SDimitry Andric   /// expressions, as specified in C++20 [expr.const]p4.
4653e8d8bef9SDimitry Andric   bool isUsableInConstantExpressions(const ASTContext &Context) const;
4654e8d8bef9SDimitry Andric 
getBeginLoc()46550b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY {
4656480093f4SDimitry Andric     return getSubExpr()->getBeginLoc();
46570b57cec5SDimitry Andric   }
46580b57cec5SDimitry Andric 
getEndLoc()46590b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY {
4660480093f4SDimitry Andric     return getSubExpr()->getEndLoc();
46610b57cec5SDimitry Andric   }
46620b57cec5SDimitry Andric 
classof(const Stmt * T)46630b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
46640b57cec5SDimitry Andric     return T->getStmtClass() == MaterializeTemporaryExprClass;
46650b57cec5SDimitry Andric   }
46660b57cec5SDimitry Andric 
46670b57cec5SDimitry Andric   // Iterators
children()46680b57cec5SDimitry Andric   child_range children() {
4669480093f4SDimitry Andric     return State.is<Stmt *>()
4670480093f4SDimitry Andric                ? child_range(State.getAddrOfPtr1(), State.getAddrOfPtr1() + 1)
4671480093f4SDimitry Andric                : State.get<LifetimeExtendedTemporaryDecl *>()->childrenExpr();
46720b57cec5SDimitry Andric   }
46730b57cec5SDimitry Andric 
children()46740b57cec5SDimitry Andric   const_child_range children() const {
4675480093f4SDimitry Andric     return State.is<Stmt *>()
4676480093f4SDimitry Andric                ? const_child_range(State.getAddrOfPtr1(),
4677480093f4SDimitry Andric                                    State.getAddrOfPtr1() + 1)
4678480093f4SDimitry Andric                : const_cast<const LifetimeExtendedTemporaryDecl *>(
4679480093f4SDimitry Andric                      State.get<LifetimeExtendedTemporaryDecl *>())
4680480093f4SDimitry Andric                      ->childrenExpr();
46810b57cec5SDimitry Andric   }
46820b57cec5SDimitry Andric };
46830b57cec5SDimitry Andric 
46840b57cec5SDimitry Andric /// Represents a folding of a pack over an operator.
46850b57cec5SDimitry Andric ///
46860b57cec5SDimitry Andric /// This expression is always dependent and represents a pack expansion of the
46870b57cec5SDimitry Andric /// forms:
46880b57cec5SDimitry Andric ///
46890b57cec5SDimitry Andric ///    ( expr op ... )
46900b57cec5SDimitry Andric ///    ( ... op expr )
46910b57cec5SDimitry Andric ///    ( expr op ... op expr )
46920b57cec5SDimitry Andric class CXXFoldExpr : public Expr {
46930b57cec5SDimitry Andric   friend class ASTStmtReader;
46940b57cec5SDimitry Andric   friend class ASTStmtWriter;
46950b57cec5SDimitry Andric 
4696e8d8bef9SDimitry Andric   enum SubExpr { Callee, LHS, RHS, Count };
4697e8d8bef9SDimitry Andric 
46980b57cec5SDimitry Andric   SourceLocation LParenLoc;
46990b57cec5SDimitry Andric   SourceLocation EllipsisLoc;
47000b57cec5SDimitry Andric   SourceLocation RParenLoc;
47010b57cec5SDimitry Andric   // When 0, the number of expansions is not known. Otherwise, this is one more
47020b57cec5SDimitry Andric   // than the number of expansions.
47030b57cec5SDimitry Andric   unsigned NumExpansions;
4704e8d8bef9SDimitry Andric   Stmt *SubExprs[SubExpr::Count];
47050b57cec5SDimitry Andric   BinaryOperatorKind Opcode;
47060b57cec5SDimitry Andric 
47070b57cec5SDimitry Andric public:
CXXFoldExpr(QualType T,UnresolvedLookupExpr * Callee,SourceLocation LParenLoc,Expr * LHS,BinaryOperatorKind Opcode,SourceLocation EllipsisLoc,Expr * RHS,SourceLocation RParenLoc,std::optional<unsigned> NumExpansions)4708e8d8bef9SDimitry Andric   CXXFoldExpr(QualType T, UnresolvedLookupExpr *Callee,
4709e8d8bef9SDimitry Andric               SourceLocation LParenLoc, Expr *LHS, BinaryOperatorKind Opcode,
4710e8d8bef9SDimitry Andric               SourceLocation EllipsisLoc, Expr *RHS, SourceLocation RParenLoc,
4711bdd1243dSDimitry Andric               std::optional<unsigned> NumExpansions)
4712fe6060f1SDimitry Andric       : Expr(CXXFoldExprClass, T, VK_PRValue, OK_Ordinary),
4713fe6060f1SDimitry Andric         LParenLoc(LParenLoc), EllipsisLoc(EllipsisLoc), RParenLoc(RParenLoc),
47140b57cec5SDimitry Andric         NumExpansions(NumExpansions ? *NumExpansions + 1 : 0), Opcode(Opcode) {
4715e8d8bef9SDimitry Andric     SubExprs[SubExpr::Callee] = Callee;
4716e8d8bef9SDimitry Andric     SubExprs[SubExpr::LHS] = LHS;
4717e8d8bef9SDimitry Andric     SubExprs[SubExpr::RHS] = RHS;
47185ffd83dbSDimitry Andric     setDependence(computeDependence(this));
47190b57cec5SDimitry Andric   }
47200b57cec5SDimitry Andric 
CXXFoldExpr(EmptyShell Empty)47210b57cec5SDimitry Andric   CXXFoldExpr(EmptyShell Empty) : Expr(CXXFoldExprClass, Empty) {}
47220b57cec5SDimitry Andric 
getCallee()4723e8d8bef9SDimitry Andric   UnresolvedLookupExpr *getCallee() const {
4724e8d8bef9SDimitry Andric     return static_cast<UnresolvedLookupExpr *>(SubExprs[SubExpr::Callee]);
4725e8d8bef9SDimitry Andric   }
getLHS()4726e8d8bef9SDimitry Andric   Expr *getLHS() const { return static_cast<Expr*>(SubExprs[SubExpr::LHS]); }
getRHS()4727e8d8bef9SDimitry Andric   Expr *getRHS() const { return static_cast<Expr*>(SubExprs[SubExpr::RHS]); }
47280b57cec5SDimitry Andric 
47290b57cec5SDimitry Andric   /// Does this produce a right-associated sequence of operators?
isRightFold()47300b57cec5SDimitry Andric   bool isRightFold() const {
47310b57cec5SDimitry Andric     return getLHS() && getLHS()->containsUnexpandedParameterPack();
47320b57cec5SDimitry Andric   }
47330b57cec5SDimitry Andric 
47340b57cec5SDimitry Andric   /// Does this produce a left-associated sequence of operators?
isLeftFold()47350b57cec5SDimitry Andric   bool isLeftFold() const { return !isRightFold(); }
47360b57cec5SDimitry Andric 
47370b57cec5SDimitry Andric   /// Get the pattern, that is, the operand that contains an unexpanded pack.
getPattern()47380b57cec5SDimitry Andric   Expr *getPattern() const { return isLeftFold() ? getRHS() : getLHS(); }
47390b57cec5SDimitry Andric 
47400b57cec5SDimitry Andric   /// Get the operand that doesn't contain a pack, for a binary fold.
getInit()47410b57cec5SDimitry Andric   Expr *getInit() const { return isLeftFold() ? getLHS() : getRHS(); }
47420b57cec5SDimitry Andric 
getLParenLoc()4743e8d8bef9SDimitry Andric   SourceLocation getLParenLoc() const { return LParenLoc; }
getRParenLoc()4744e8d8bef9SDimitry Andric   SourceLocation getRParenLoc() const { return RParenLoc; }
getEllipsisLoc()47450b57cec5SDimitry Andric   SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
getOperator()47460b57cec5SDimitry Andric   BinaryOperatorKind getOperator() const { return Opcode; }
47470b57cec5SDimitry Andric 
getNumExpansions()4748bdd1243dSDimitry Andric   std::optional<unsigned> getNumExpansions() const {
47490b57cec5SDimitry Andric     if (NumExpansions)
47500b57cec5SDimitry Andric       return NumExpansions - 1;
4751bdd1243dSDimitry Andric     return std::nullopt;
47520b57cec5SDimitry Andric   }
47530b57cec5SDimitry Andric 
getBeginLoc()4754e8d8bef9SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY {
4755e8d8bef9SDimitry Andric     if (LParenLoc.isValid())
4756e8d8bef9SDimitry Andric       return LParenLoc;
4757e8d8bef9SDimitry Andric     if (isLeftFold())
4758e8d8bef9SDimitry Andric       return getEllipsisLoc();
4759e8d8bef9SDimitry Andric     return getLHS()->getBeginLoc();
4760e8d8bef9SDimitry Andric   }
47610b57cec5SDimitry Andric 
getEndLoc()4762e8d8bef9SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY {
4763e8d8bef9SDimitry Andric     if (RParenLoc.isValid())
4764e8d8bef9SDimitry Andric       return RParenLoc;
4765e8d8bef9SDimitry Andric     if (isRightFold())
4766e8d8bef9SDimitry Andric       return getEllipsisLoc();
4767e8d8bef9SDimitry Andric     return getRHS()->getEndLoc();
4768e8d8bef9SDimitry Andric   }
47690b57cec5SDimitry Andric 
classof(const Stmt * T)47700b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
47710b57cec5SDimitry Andric     return T->getStmtClass() == CXXFoldExprClass;
47720b57cec5SDimitry Andric   }
47730b57cec5SDimitry Andric 
47740b57cec5SDimitry Andric   // Iterators
children()4775e8d8bef9SDimitry Andric   child_range children() {
4776e8d8bef9SDimitry Andric     return child_range(SubExprs, SubExprs + SubExpr::Count);
4777e8d8bef9SDimitry Andric   }
47780b57cec5SDimitry Andric 
children()47790b57cec5SDimitry Andric   const_child_range children() const {
4780e8d8bef9SDimitry Andric     return const_child_range(SubExprs, SubExprs + SubExpr::Count);
47810b57cec5SDimitry Andric   }
47820b57cec5SDimitry Andric };
47830b57cec5SDimitry Andric 
4784bdd1243dSDimitry Andric /// Represents a list-initialization with parenthesis.
4785bdd1243dSDimitry Andric ///
4786bdd1243dSDimitry Andric /// As per P0960R3, this is a C++20 feature that allows aggregate to
4787bdd1243dSDimitry Andric /// be initialized with a parenthesized list of values:
4788bdd1243dSDimitry Andric /// ```
4789bdd1243dSDimitry Andric /// struct A {
4790bdd1243dSDimitry Andric ///   int a;
4791bdd1243dSDimitry Andric ///   double b;
4792bdd1243dSDimitry Andric /// };
4793bdd1243dSDimitry Andric ///
4794bdd1243dSDimitry Andric /// void foo() {
4795bdd1243dSDimitry Andric ///   A a1(0);        // Well-formed in C++20
4796bdd1243dSDimitry Andric ///   A a2(1.5, 1.0); // Well-formed in C++20
4797bdd1243dSDimitry Andric /// }
4798bdd1243dSDimitry Andric /// ```
4799bdd1243dSDimitry Andric /// It has some sort of similiarity to braced
4800bdd1243dSDimitry Andric /// list-initialization, with some differences such as
4801bdd1243dSDimitry Andric /// it allows narrowing conversion whilst braced
4802bdd1243dSDimitry Andric /// list-initialization doesn't.
4803bdd1243dSDimitry Andric /// ```
4804bdd1243dSDimitry Andric /// struct A {
4805bdd1243dSDimitry Andric ///   char a;
4806bdd1243dSDimitry Andric /// };
4807bdd1243dSDimitry Andric /// void foo() {
4808bdd1243dSDimitry Andric ///   A a(1.5); // Well-formed in C++20
4809bdd1243dSDimitry Andric ///   A b{1.5}; // Ill-formed !
4810bdd1243dSDimitry Andric /// }
4811bdd1243dSDimitry Andric /// ```
4812bdd1243dSDimitry Andric class CXXParenListInitExpr final
4813bdd1243dSDimitry Andric     : public Expr,
4814bdd1243dSDimitry Andric       private llvm::TrailingObjects<CXXParenListInitExpr, Expr *> {
4815bdd1243dSDimitry Andric   friend class TrailingObjects;
4816bdd1243dSDimitry Andric   friend class ASTStmtReader;
4817bdd1243dSDimitry Andric   friend class ASTStmtWriter;
4818bdd1243dSDimitry Andric 
4819bdd1243dSDimitry Andric   unsigned NumExprs;
4820bdd1243dSDimitry Andric   unsigned NumUserSpecifiedExprs;
4821bdd1243dSDimitry Andric   SourceLocation InitLoc, LParenLoc, RParenLoc;
4822bdd1243dSDimitry Andric   llvm::PointerUnion<Expr *, FieldDecl *> ArrayFillerOrUnionFieldInit;
4823bdd1243dSDimitry Andric 
CXXParenListInitExpr(ArrayRef<Expr * > Args,QualType T,unsigned NumUserSpecifiedExprs,SourceLocation InitLoc,SourceLocation LParenLoc,SourceLocation RParenLoc)4824bdd1243dSDimitry Andric   CXXParenListInitExpr(ArrayRef<Expr *> Args, QualType T,
4825bdd1243dSDimitry Andric                        unsigned NumUserSpecifiedExprs, SourceLocation InitLoc,
4826bdd1243dSDimitry Andric                        SourceLocation LParenLoc, SourceLocation RParenLoc)
4827bdd1243dSDimitry Andric       : Expr(CXXParenListInitExprClass, T, getValueKindForType(T), OK_Ordinary),
4828bdd1243dSDimitry Andric         NumExprs(Args.size()), NumUserSpecifiedExprs(NumUserSpecifiedExprs),
4829bdd1243dSDimitry Andric         InitLoc(InitLoc), LParenLoc(LParenLoc), RParenLoc(RParenLoc) {
4830bdd1243dSDimitry Andric     std::copy(Args.begin(), Args.end(), getTrailingObjects<Expr *>());
4831bdd1243dSDimitry Andric     assert(NumExprs >= NumUserSpecifiedExprs &&
4832bdd1243dSDimitry Andric            "number of user specified inits is greater than the number of "
4833bdd1243dSDimitry Andric            "passed inits");
4834bdd1243dSDimitry Andric     setDependence(computeDependence(this));
4835bdd1243dSDimitry Andric   }
4836bdd1243dSDimitry Andric 
numTrailingObjects(OverloadToken<Expr * >)4837bdd1243dSDimitry Andric   size_t numTrailingObjects(OverloadToken<Expr *>) const { return NumExprs; }
4838bdd1243dSDimitry Andric 
4839bdd1243dSDimitry Andric public:
4840bdd1243dSDimitry Andric   static CXXParenListInitExpr *
4841bdd1243dSDimitry Andric   Create(ASTContext &C, ArrayRef<Expr *> Args, QualType T,
4842bdd1243dSDimitry Andric          unsigned NumUserSpecifiedExprs, SourceLocation InitLoc,
4843bdd1243dSDimitry Andric          SourceLocation LParenLoc, SourceLocation RParenLoc);
4844bdd1243dSDimitry Andric 
4845bdd1243dSDimitry Andric   static CXXParenListInitExpr *CreateEmpty(ASTContext &C, unsigned numExprs,
4846bdd1243dSDimitry Andric                                            EmptyShell Empty);
4847bdd1243dSDimitry Andric 
CXXParenListInitExpr(EmptyShell Empty,unsigned NumExprs)4848bdd1243dSDimitry Andric   explicit CXXParenListInitExpr(EmptyShell Empty, unsigned NumExprs)
4849bdd1243dSDimitry Andric       : Expr(CXXParenListInitExprClass, Empty), NumExprs(NumExprs),
4850bdd1243dSDimitry Andric         NumUserSpecifiedExprs(0) {}
4851bdd1243dSDimitry Andric 
updateDependence()4852bdd1243dSDimitry Andric   void updateDependence() { setDependence(computeDependence(this)); }
4853bdd1243dSDimitry Andric 
getInitExprs()4854bdd1243dSDimitry Andric   ArrayRef<Expr *> getInitExprs() {
4855bdd1243dSDimitry Andric     return ArrayRef(getTrailingObjects<Expr *>(), NumExprs);
4856bdd1243dSDimitry Andric   }
4857bdd1243dSDimitry Andric 
getInitExprs()4858bdd1243dSDimitry Andric   const ArrayRef<Expr *> getInitExprs() const {
4859bdd1243dSDimitry Andric     return ArrayRef(getTrailingObjects<Expr *>(), NumExprs);
4860bdd1243dSDimitry Andric   }
4861bdd1243dSDimitry Andric 
getUserSpecifiedInitExprs()4862bdd1243dSDimitry Andric   ArrayRef<Expr *> getUserSpecifiedInitExprs() {
4863bdd1243dSDimitry Andric     return ArrayRef(getTrailingObjects<Expr *>(), NumUserSpecifiedExprs);
4864bdd1243dSDimitry Andric   }
4865bdd1243dSDimitry Andric 
getUserSpecifiedInitExprs()4866bdd1243dSDimitry Andric   const ArrayRef<Expr *> getUserSpecifiedInitExprs() const {
4867bdd1243dSDimitry Andric     return ArrayRef(getTrailingObjects<Expr *>(), NumUserSpecifiedExprs);
4868bdd1243dSDimitry Andric   }
4869bdd1243dSDimitry Andric 
getBeginLoc()4870bdd1243dSDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY { return LParenLoc; }
4871bdd1243dSDimitry Andric 
getEndLoc()4872bdd1243dSDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
4873bdd1243dSDimitry Andric 
getInitLoc()4874bdd1243dSDimitry Andric   SourceLocation getInitLoc() const LLVM_READONLY { return InitLoc; }
4875bdd1243dSDimitry Andric 
getSourceRange()4876bdd1243dSDimitry Andric   SourceRange getSourceRange() const LLVM_READONLY {
4877bdd1243dSDimitry Andric     return SourceRange(getBeginLoc(), getEndLoc());
4878bdd1243dSDimitry Andric   }
4879bdd1243dSDimitry Andric 
setArrayFiller(Expr * E)4880bdd1243dSDimitry Andric   void setArrayFiller(Expr *E) { ArrayFillerOrUnionFieldInit = E; }
4881bdd1243dSDimitry Andric 
getArrayFiller()4882bdd1243dSDimitry Andric   Expr *getArrayFiller() {
4883bdd1243dSDimitry Andric     return ArrayFillerOrUnionFieldInit.dyn_cast<Expr *>();
4884bdd1243dSDimitry Andric   }
4885bdd1243dSDimitry Andric 
getArrayFiller()4886bdd1243dSDimitry Andric   const Expr *getArrayFiller() const {
4887bdd1243dSDimitry Andric     return ArrayFillerOrUnionFieldInit.dyn_cast<Expr *>();
4888bdd1243dSDimitry Andric   }
4889bdd1243dSDimitry Andric 
setInitializedFieldInUnion(FieldDecl * FD)4890bdd1243dSDimitry Andric   void setInitializedFieldInUnion(FieldDecl *FD) {
4891bdd1243dSDimitry Andric     ArrayFillerOrUnionFieldInit = FD;
4892bdd1243dSDimitry Andric   }
4893bdd1243dSDimitry Andric 
getInitializedFieldInUnion()4894bdd1243dSDimitry Andric   FieldDecl *getInitializedFieldInUnion() {
4895bdd1243dSDimitry Andric     return ArrayFillerOrUnionFieldInit.dyn_cast<FieldDecl *>();
4896bdd1243dSDimitry Andric   }
4897bdd1243dSDimitry Andric 
getInitializedFieldInUnion()4898bdd1243dSDimitry Andric   const FieldDecl *getInitializedFieldInUnion() const {
4899bdd1243dSDimitry Andric     return ArrayFillerOrUnionFieldInit.dyn_cast<FieldDecl *>();
4900bdd1243dSDimitry Andric   }
4901bdd1243dSDimitry Andric 
children()4902bdd1243dSDimitry Andric   child_range children() {
4903bdd1243dSDimitry Andric     Stmt **Begin = reinterpret_cast<Stmt **>(getTrailingObjects<Expr *>());
4904bdd1243dSDimitry Andric     return child_range(Begin, Begin + NumExprs);
4905bdd1243dSDimitry Andric   }
4906bdd1243dSDimitry Andric 
children()4907bdd1243dSDimitry Andric   const_child_range children() const {
4908bdd1243dSDimitry Andric     Stmt *const *Begin =
4909bdd1243dSDimitry Andric         reinterpret_cast<Stmt *const *>(getTrailingObjects<Expr *>());
4910bdd1243dSDimitry Andric     return const_child_range(Begin, Begin + NumExprs);
4911bdd1243dSDimitry Andric   }
4912bdd1243dSDimitry Andric 
classof(const Stmt * T)4913bdd1243dSDimitry Andric   static bool classof(const Stmt *T) {
4914bdd1243dSDimitry Andric     return T->getStmtClass() == CXXParenListInitExprClass;
4915bdd1243dSDimitry Andric   }
4916bdd1243dSDimitry Andric };
4917bdd1243dSDimitry Andric 
49180b57cec5SDimitry Andric /// Represents an expression that might suspend coroutine execution;
49190b57cec5SDimitry Andric /// either a co_await or co_yield expression.
49200b57cec5SDimitry Andric ///
49210b57cec5SDimitry Andric /// Evaluation of this expression first evaluates its 'ready' expression. If
49220b57cec5SDimitry Andric /// that returns 'false':
49230b57cec5SDimitry Andric ///  -- execution of the coroutine is suspended
49240b57cec5SDimitry Andric ///  -- the 'suspend' expression is evaluated
49250b57cec5SDimitry Andric ///     -- if the 'suspend' expression returns 'false', the coroutine is
49260b57cec5SDimitry Andric ///        resumed
49270b57cec5SDimitry Andric ///     -- otherwise, control passes back to the resumer.
49280b57cec5SDimitry Andric /// If the coroutine is not suspended, or when it is resumed, the 'resume'
49290b57cec5SDimitry Andric /// expression is evaluated, and its result is the result of the overall
49300b57cec5SDimitry Andric /// expression.
49310b57cec5SDimitry Andric class CoroutineSuspendExpr : public Expr {
49320b57cec5SDimitry Andric   friend class ASTStmtReader;
49330b57cec5SDimitry Andric 
49340b57cec5SDimitry Andric   SourceLocation KeywordLoc;
49350b57cec5SDimitry Andric 
493681ad6265SDimitry Andric   enum SubExpr { Operand, Common, Ready, Suspend, Resume, Count };
49370b57cec5SDimitry Andric 
49380b57cec5SDimitry Andric   Stmt *SubExprs[SubExpr::Count];
49390b57cec5SDimitry Andric   OpaqueValueExpr *OpaqueValue = nullptr;
49400b57cec5SDimitry Andric 
49410b57cec5SDimitry Andric public:
CoroutineSuspendExpr(StmtClass SC,SourceLocation KeywordLoc,Expr * Operand,Expr * Common,Expr * Ready,Expr * Suspend,Expr * Resume,OpaqueValueExpr * OpaqueValue)494281ad6265SDimitry Andric   CoroutineSuspendExpr(StmtClass SC, SourceLocation KeywordLoc, Expr *Operand,
494381ad6265SDimitry Andric                        Expr *Common, Expr *Ready, Expr *Suspend, Expr *Resume,
49440b57cec5SDimitry Andric                        OpaqueValueExpr *OpaqueValue)
49450b57cec5SDimitry Andric       : Expr(SC, Resume->getType(), Resume->getValueKind(),
49465ffd83dbSDimitry Andric              Resume->getObjectKind()),
49470b57cec5SDimitry Andric         KeywordLoc(KeywordLoc), OpaqueValue(OpaqueValue) {
494881ad6265SDimitry Andric     SubExprs[SubExpr::Operand] = Operand;
49490b57cec5SDimitry Andric     SubExprs[SubExpr::Common] = Common;
49500b57cec5SDimitry Andric     SubExprs[SubExpr::Ready] = Ready;
49510b57cec5SDimitry Andric     SubExprs[SubExpr::Suspend] = Suspend;
49520b57cec5SDimitry Andric     SubExprs[SubExpr::Resume] = Resume;
49535ffd83dbSDimitry Andric     setDependence(computeDependence(this));
49540b57cec5SDimitry Andric   }
49550b57cec5SDimitry Andric 
CoroutineSuspendExpr(StmtClass SC,SourceLocation KeywordLoc,QualType Ty,Expr * Operand,Expr * Common)49560b57cec5SDimitry Andric   CoroutineSuspendExpr(StmtClass SC, SourceLocation KeywordLoc, QualType Ty,
495781ad6265SDimitry Andric                        Expr *Operand, Expr *Common)
4958fe6060f1SDimitry Andric       : Expr(SC, Ty, VK_PRValue, OK_Ordinary), KeywordLoc(KeywordLoc) {
49590b57cec5SDimitry Andric     assert(Common->isTypeDependent() && Ty->isDependentType() &&
49600b57cec5SDimitry Andric            "wrong constructor for non-dependent co_await/co_yield expression");
496181ad6265SDimitry Andric     SubExprs[SubExpr::Operand] = Operand;
49620b57cec5SDimitry Andric     SubExprs[SubExpr::Common] = Common;
49630b57cec5SDimitry Andric     SubExprs[SubExpr::Ready] = nullptr;
49640b57cec5SDimitry Andric     SubExprs[SubExpr::Suspend] = nullptr;
49650b57cec5SDimitry Andric     SubExprs[SubExpr::Resume] = nullptr;
49665ffd83dbSDimitry Andric     setDependence(computeDependence(this));
49670b57cec5SDimitry Andric   }
49680b57cec5SDimitry Andric 
CoroutineSuspendExpr(StmtClass SC,EmptyShell Empty)49690b57cec5SDimitry Andric   CoroutineSuspendExpr(StmtClass SC, EmptyShell Empty) : Expr(SC, Empty) {
497081ad6265SDimitry Andric     SubExprs[SubExpr::Operand] = nullptr;
49710b57cec5SDimitry Andric     SubExprs[SubExpr::Common] = nullptr;
49720b57cec5SDimitry Andric     SubExprs[SubExpr::Ready] = nullptr;
49730b57cec5SDimitry Andric     SubExprs[SubExpr::Suspend] = nullptr;
49740b57cec5SDimitry Andric     SubExprs[SubExpr::Resume] = nullptr;
49750b57cec5SDimitry Andric   }
49760b57cec5SDimitry Andric 
getCommonExpr()49770b57cec5SDimitry Andric   Expr *getCommonExpr() const {
49780b57cec5SDimitry Andric     return static_cast<Expr*>(SubExprs[SubExpr::Common]);
49790b57cec5SDimitry Andric   }
49800b57cec5SDimitry Andric 
49810b57cec5SDimitry Andric   /// getOpaqueValue - Return the opaque value placeholder.
getOpaqueValue()49820b57cec5SDimitry Andric   OpaqueValueExpr *getOpaqueValue() const { return OpaqueValue; }
49830b57cec5SDimitry Andric 
getReadyExpr()49840b57cec5SDimitry Andric   Expr *getReadyExpr() const {
49850b57cec5SDimitry Andric     return static_cast<Expr*>(SubExprs[SubExpr::Ready]);
49860b57cec5SDimitry Andric   }
49870b57cec5SDimitry Andric 
getSuspendExpr()49880b57cec5SDimitry Andric   Expr *getSuspendExpr() const {
49890b57cec5SDimitry Andric     return static_cast<Expr*>(SubExprs[SubExpr::Suspend]);
49900b57cec5SDimitry Andric   }
49910b57cec5SDimitry Andric 
getResumeExpr()49920b57cec5SDimitry Andric   Expr *getResumeExpr() const {
49930b57cec5SDimitry Andric     return static_cast<Expr*>(SubExprs[SubExpr::Resume]);
49940b57cec5SDimitry Andric   }
49950b57cec5SDimitry Andric 
499681ad6265SDimitry Andric   // The syntactic operand written in the code
getOperand()499781ad6265SDimitry Andric   Expr *getOperand() const {
499881ad6265SDimitry Andric     return static_cast<Expr *>(SubExprs[SubExpr::Operand]);
499981ad6265SDimitry Andric   }
500081ad6265SDimitry Andric 
getKeywordLoc()500181ad6265SDimitry Andric   SourceLocation getKeywordLoc() const { return KeywordLoc; }
500281ad6265SDimitry Andric 
getBeginLoc()50030b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY { return KeywordLoc; }
50040b57cec5SDimitry Andric 
getEndLoc()50050b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY {
500681ad6265SDimitry Andric     return getOperand()->getEndLoc();
50070b57cec5SDimitry Andric   }
50080b57cec5SDimitry Andric 
children()50090b57cec5SDimitry Andric   child_range children() {
50100b57cec5SDimitry Andric     return child_range(SubExprs, SubExprs + SubExpr::Count);
50110b57cec5SDimitry Andric   }
50120b57cec5SDimitry Andric 
children()50130b57cec5SDimitry Andric   const_child_range children() const {
50140b57cec5SDimitry Andric     return const_child_range(SubExprs, SubExprs + SubExpr::Count);
50150b57cec5SDimitry Andric   }
50160b57cec5SDimitry Andric 
classof(const Stmt * T)50170b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
50180b57cec5SDimitry Andric     return T->getStmtClass() == CoawaitExprClass ||
50190b57cec5SDimitry Andric            T->getStmtClass() == CoyieldExprClass;
50200b57cec5SDimitry Andric   }
50210b57cec5SDimitry Andric };
50220b57cec5SDimitry Andric 
50230b57cec5SDimitry Andric /// Represents a 'co_await' expression.
50240b57cec5SDimitry Andric class CoawaitExpr : public CoroutineSuspendExpr {
50250b57cec5SDimitry Andric   friend class ASTStmtReader;
50260b57cec5SDimitry Andric 
50270b57cec5SDimitry Andric public:
502881ad6265SDimitry Andric   CoawaitExpr(SourceLocation CoawaitLoc, Expr *Operand, Expr *Common,
502981ad6265SDimitry Andric               Expr *Ready, Expr *Suspend, Expr *Resume,
503081ad6265SDimitry Andric               OpaqueValueExpr *OpaqueValue, bool IsImplicit = false)
CoroutineSuspendExpr(CoawaitExprClass,CoawaitLoc,Operand,Common,Ready,Suspend,Resume,OpaqueValue)503181ad6265SDimitry Andric       : CoroutineSuspendExpr(CoawaitExprClass, CoawaitLoc, Operand, Common,
503281ad6265SDimitry Andric                              Ready, Suspend, Resume, OpaqueValue) {
50330b57cec5SDimitry Andric     CoawaitBits.IsImplicit = IsImplicit;
50340b57cec5SDimitry Andric   }
50350b57cec5SDimitry Andric 
50360b57cec5SDimitry Andric   CoawaitExpr(SourceLocation CoawaitLoc, QualType Ty, Expr *Operand,
503781ad6265SDimitry Andric               Expr *Common, bool IsImplicit = false)
CoroutineSuspendExpr(CoawaitExprClass,CoawaitLoc,Ty,Operand,Common)503881ad6265SDimitry Andric       : CoroutineSuspendExpr(CoawaitExprClass, CoawaitLoc, Ty, Operand,
503981ad6265SDimitry Andric                              Common) {
50400b57cec5SDimitry Andric     CoawaitBits.IsImplicit = IsImplicit;
50410b57cec5SDimitry Andric   }
50420b57cec5SDimitry Andric 
CoawaitExpr(EmptyShell Empty)50430b57cec5SDimitry Andric   CoawaitExpr(EmptyShell Empty)
50440b57cec5SDimitry Andric       : CoroutineSuspendExpr(CoawaitExprClass, Empty) {}
50450b57cec5SDimitry Andric 
isImplicit()50460b57cec5SDimitry Andric   bool isImplicit() const { return CoawaitBits.IsImplicit; }
50470b57cec5SDimitry Andric   void setIsImplicit(bool value = true) { CoawaitBits.IsImplicit = value; }
50480b57cec5SDimitry Andric 
classof(const Stmt * T)50490b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
50500b57cec5SDimitry Andric     return T->getStmtClass() == CoawaitExprClass;
50510b57cec5SDimitry Andric   }
50520b57cec5SDimitry Andric };
50530b57cec5SDimitry Andric 
50540b57cec5SDimitry Andric /// Represents a 'co_await' expression while the type of the promise
50550b57cec5SDimitry Andric /// is dependent.
50560b57cec5SDimitry Andric class DependentCoawaitExpr : public Expr {
50570b57cec5SDimitry Andric   friend class ASTStmtReader;
50580b57cec5SDimitry Andric 
50590b57cec5SDimitry Andric   SourceLocation KeywordLoc;
50600b57cec5SDimitry Andric   Stmt *SubExprs[2];
50610b57cec5SDimitry Andric 
50620b57cec5SDimitry Andric public:
DependentCoawaitExpr(SourceLocation KeywordLoc,QualType Ty,Expr * Op,UnresolvedLookupExpr * OpCoawait)50630b57cec5SDimitry Andric   DependentCoawaitExpr(SourceLocation KeywordLoc, QualType Ty, Expr *Op,
50640b57cec5SDimitry Andric                        UnresolvedLookupExpr *OpCoawait)
5065fe6060f1SDimitry Andric       : Expr(DependentCoawaitExprClass, Ty, VK_PRValue, OK_Ordinary),
50660b57cec5SDimitry Andric         KeywordLoc(KeywordLoc) {
50670b57cec5SDimitry Andric     // NOTE: A co_await expression is dependent on the coroutines promise
50680b57cec5SDimitry Andric     // type and may be dependent even when the `Op` expression is not.
50690b57cec5SDimitry Andric     assert(Ty->isDependentType() &&
50700b57cec5SDimitry Andric            "wrong constructor for non-dependent co_await/co_yield expression");
50710b57cec5SDimitry Andric     SubExprs[0] = Op;
50720b57cec5SDimitry Andric     SubExprs[1] = OpCoawait;
50735ffd83dbSDimitry Andric     setDependence(computeDependence(this));
50740b57cec5SDimitry Andric   }
50750b57cec5SDimitry Andric 
DependentCoawaitExpr(EmptyShell Empty)50760b57cec5SDimitry Andric   DependentCoawaitExpr(EmptyShell Empty)
50770b57cec5SDimitry Andric       : Expr(DependentCoawaitExprClass, Empty) {}
50780b57cec5SDimitry Andric 
getOperand()50790b57cec5SDimitry Andric   Expr *getOperand() const { return cast<Expr>(SubExprs[0]); }
50800b57cec5SDimitry Andric 
getOperatorCoawaitLookup()50810b57cec5SDimitry Andric   UnresolvedLookupExpr *getOperatorCoawaitLookup() const {
50820b57cec5SDimitry Andric     return cast<UnresolvedLookupExpr>(SubExprs[1]);
50830b57cec5SDimitry Andric   }
50840b57cec5SDimitry Andric 
getKeywordLoc()50850b57cec5SDimitry Andric   SourceLocation getKeywordLoc() const { return KeywordLoc; }
50860b57cec5SDimitry Andric 
getBeginLoc()50870b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY { return KeywordLoc; }
50880b57cec5SDimitry Andric 
getEndLoc()50890b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY {
50900b57cec5SDimitry Andric     return getOperand()->getEndLoc();
50910b57cec5SDimitry Andric   }
50920b57cec5SDimitry Andric 
children()50930b57cec5SDimitry Andric   child_range children() { return child_range(SubExprs, SubExprs + 2); }
50940b57cec5SDimitry Andric 
children()50950b57cec5SDimitry Andric   const_child_range children() const {
50960b57cec5SDimitry Andric     return const_child_range(SubExprs, SubExprs + 2);
50970b57cec5SDimitry Andric   }
50980b57cec5SDimitry Andric 
classof(const Stmt * T)50990b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
51000b57cec5SDimitry Andric     return T->getStmtClass() == DependentCoawaitExprClass;
51010b57cec5SDimitry Andric   }
51020b57cec5SDimitry Andric };
51030b57cec5SDimitry Andric 
51040b57cec5SDimitry Andric /// Represents a 'co_yield' expression.
51050b57cec5SDimitry Andric class CoyieldExpr : public CoroutineSuspendExpr {
51060b57cec5SDimitry Andric   friend class ASTStmtReader;
51070b57cec5SDimitry Andric 
51080b57cec5SDimitry Andric public:
CoyieldExpr(SourceLocation CoyieldLoc,Expr * Operand,Expr * Common,Expr * Ready,Expr * Suspend,Expr * Resume,OpaqueValueExpr * OpaqueValue)510981ad6265SDimitry Andric   CoyieldExpr(SourceLocation CoyieldLoc, Expr *Operand, Expr *Common,
511081ad6265SDimitry Andric               Expr *Ready, Expr *Suspend, Expr *Resume,
511181ad6265SDimitry Andric               OpaqueValueExpr *OpaqueValue)
511281ad6265SDimitry Andric       : CoroutineSuspendExpr(CoyieldExprClass, CoyieldLoc, Operand, Common,
511381ad6265SDimitry Andric                              Ready, Suspend, Resume, OpaqueValue) {}
CoyieldExpr(SourceLocation CoyieldLoc,QualType Ty,Expr * Operand,Expr * Common)511481ad6265SDimitry Andric   CoyieldExpr(SourceLocation CoyieldLoc, QualType Ty, Expr *Operand,
511581ad6265SDimitry Andric               Expr *Common)
511681ad6265SDimitry Andric       : CoroutineSuspendExpr(CoyieldExprClass, CoyieldLoc, Ty, Operand,
511781ad6265SDimitry Andric                              Common) {}
CoyieldExpr(EmptyShell Empty)51180b57cec5SDimitry Andric   CoyieldExpr(EmptyShell Empty)
51190b57cec5SDimitry Andric       : CoroutineSuspendExpr(CoyieldExprClass, Empty) {}
51200b57cec5SDimitry Andric 
classof(const Stmt * T)51210b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
51220b57cec5SDimitry Andric     return T->getStmtClass() == CoyieldExprClass;
51230b57cec5SDimitry Andric   }
51240b57cec5SDimitry Andric };
51250b57cec5SDimitry Andric 
51260b57cec5SDimitry Andric /// Represents a C++2a __builtin_bit_cast(T, v) expression. Used to implement
51270b57cec5SDimitry Andric /// std::bit_cast. These can sometimes be evaluated as part of a constant
51280b57cec5SDimitry Andric /// expression, but otherwise CodeGen to a simple memcpy in general.
51290b57cec5SDimitry Andric class BuiltinBitCastExpr final
51300b57cec5SDimitry Andric     : public ExplicitCastExpr,
51310b57cec5SDimitry Andric       private llvm::TrailingObjects<BuiltinBitCastExpr, CXXBaseSpecifier *> {
51320b57cec5SDimitry Andric   friend class ASTStmtReader;
51330b57cec5SDimitry Andric   friend class CastExpr;
5134e8d8bef9SDimitry Andric   friend TrailingObjects;
51350b57cec5SDimitry Andric 
51360b57cec5SDimitry Andric   SourceLocation KWLoc;
51370b57cec5SDimitry Andric   SourceLocation RParenLoc;
51380b57cec5SDimitry Andric 
51390b57cec5SDimitry Andric public:
BuiltinBitCastExpr(QualType T,ExprValueKind VK,CastKind CK,Expr * SrcExpr,TypeSourceInfo * DstType,SourceLocation KWLoc,SourceLocation RParenLoc)51400b57cec5SDimitry Andric   BuiltinBitCastExpr(QualType T, ExprValueKind VK, CastKind CK, Expr *SrcExpr,
51410b57cec5SDimitry Andric                      TypeSourceInfo *DstType, SourceLocation KWLoc,
51420b57cec5SDimitry Andric                      SourceLocation RParenLoc)
5143e8d8bef9SDimitry Andric       : ExplicitCastExpr(BuiltinBitCastExprClass, T, VK, CK, SrcExpr, 0, false,
51440b57cec5SDimitry Andric                          DstType),
51450b57cec5SDimitry Andric         KWLoc(KWLoc), RParenLoc(RParenLoc) {}
BuiltinBitCastExpr(EmptyShell Empty)51465ffd83dbSDimitry Andric   BuiltinBitCastExpr(EmptyShell Empty)
5147e8d8bef9SDimitry Andric       : ExplicitCastExpr(BuiltinBitCastExprClass, Empty, 0, false) {}
51480b57cec5SDimitry Andric 
getBeginLoc()51490b57cec5SDimitry Andric   SourceLocation getBeginLoc() const LLVM_READONLY { return KWLoc; }
getEndLoc()51500b57cec5SDimitry Andric   SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
51510b57cec5SDimitry Andric 
classof(const Stmt * T)51520b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
51530b57cec5SDimitry Andric     return T->getStmtClass() == BuiltinBitCastExprClass;
51540b57cec5SDimitry Andric   }
51550b57cec5SDimitry Andric };
51560b57cec5SDimitry Andric 
51570b57cec5SDimitry Andric } // namespace clang
51580b57cec5SDimitry Andric 
51590b57cec5SDimitry Andric #endif // LLVM_CLANG_AST_EXPRCXX_H
5160