xref: /openbsd-src/gnu/llvm/clang/lib/AST/ExprCXX.cpp (revision 12c855180aad702bbcca06e0398d774beeafb155)
1e5dd7070Spatrick //===- ExprCXX.cpp - (C++) Expression AST Node Implementation -------------===//
2e5dd7070Spatrick //
3e5dd7070Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e5dd7070Spatrick // See https://llvm.org/LICENSE.txt for license information.
5e5dd7070Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e5dd7070Spatrick //
7e5dd7070Spatrick //===----------------------------------------------------------------------===//
8e5dd7070Spatrick //
9e5dd7070Spatrick // This file implements the subclesses of Expr class declared in ExprCXX.h
10e5dd7070Spatrick //
11e5dd7070Spatrick //===----------------------------------------------------------------------===//
12e5dd7070Spatrick 
13e5dd7070Spatrick #include "clang/AST/ExprCXX.h"
14e5dd7070Spatrick #include "clang/AST/ASTContext.h"
15e5dd7070Spatrick #include "clang/AST/Attr.h"
16ec727ea7Spatrick #include "clang/AST/ComputeDependence.h"
17e5dd7070Spatrick #include "clang/AST/Decl.h"
18e5dd7070Spatrick #include "clang/AST/DeclAccessPair.h"
19e5dd7070Spatrick #include "clang/AST/DeclBase.h"
20e5dd7070Spatrick #include "clang/AST/DeclCXX.h"
21e5dd7070Spatrick #include "clang/AST/DeclTemplate.h"
22e5dd7070Spatrick #include "clang/AST/DeclarationName.h"
23ec727ea7Spatrick #include "clang/AST/DependenceFlags.h"
24e5dd7070Spatrick #include "clang/AST/Expr.h"
25e5dd7070Spatrick #include "clang/AST/LambdaCapture.h"
26e5dd7070Spatrick #include "clang/AST/NestedNameSpecifier.h"
27e5dd7070Spatrick #include "clang/AST/TemplateBase.h"
28e5dd7070Spatrick #include "clang/AST/Type.h"
29e5dd7070Spatrick #include "clang/AST/TypeLoc.h"
30e5dd7070Spatrick #include "clang/Basic/LLVM.h"
31e5dd7070Spatrick #include "clang/Basic/OperatorKinds.h"
32e5dd7070Spatrick #include "clang/Basic/SourceLocation.h"
33e5dd7070Spatrick #include "clang/Basic/Specifiers.h"
34e5dd7070Spatrick #include "llvm/ADT/ArrayRef.h"
35e5dd7070Spatrick #include "llvm/Support/Casting.h"
36e5dd7070Spatrick #include "llvm/Support/ErrorHandling.h"
37e5dd7070Spatrick #include <cassert>
38e5dd7070Spatrick #include <cstddef>
39e5dd7070Spatrick #include <cstring>
40e5dd7070Spatrick #include <memory>
41*12c85518Srobert #include <optional>
42e5dd7070Spatrick 
43e5dd7070Spatrick using namespace clang;
44e5dd7070Spatrick 
45e5dd7070Spatrick //===----------------------------------------------------------------------===//
46e5dd7070Spatrick //  Child Iterators for iterating over subexpressions/substatements
47e5dd7070Spatrick //===----------------------------------------------------------------------===//
48e5dd7070Spatrick 
isInfixBinaryOp() const49e5dd7070Spatrick bool CXXOperatorCallExpr::isInfixBinaryOp() const {
50e5dd7070Spatrick   // An infix binary operator is any operator with two arguments other than
51e5dd7070Spatrick   // operator() and operator[]. Note that none of these operators can have
52e5dd7070Spatrick   // default arguments, so it suffices to check the number of argument
53e5dd7070Spatrick   // expressions.
54e5dd7070Spatrick   if (getNumArgs() != 2)
55e5dd7070Spatrick     return false;
56e5dd7070Spatrick 
57e5dd7070Spatrick   switch (getOperator()) {
58e5dd7070Spatrick   case OO_Call: case OO_Subscript:
59e5dd7070Spatrick     return false;
60e5dd7070Spatrick   default:
61e5dd7070Spatrick     return true;
62e5dd7070Spatrick   }
63e5dd7070Spatrick }
64e5dd7070Spatrick 
65e5dd7070Spatrick CXXRewrittenBinaryOperator::DecomposedForm
getDecomposedForm() const66e5dd7070Spatrick CXXRewrittenBinaryOperator::getDecomposedForm() const {
67e5dd7070Spatrick   DecomposedForm Result = {};
68e5dd7070Spatrick   const Expr *E = getSemanticForm()->IgnoreImplicit();
69e5dd7070Spatrick 
70e5dd7070Spatrick   // Remove an outer '!' if it exists (only happens for a '!=' rewrite).
71e5dd7070Spatrick   bool SkippedNot = false;
72e5dd7070Spatrick   if (auto *NotEq = dyn_cast<UnaryOperator>(E)) {
73e5dd7070Spatrick     assert(NotEq->getOpcode() == UO_LNot);
74e5dd7070Spatrick     E = NotEq->getSubExpr()->IgnoreImplicit();
75e5dd7070Spatrick     SkippedNot = true;
76e5dd7070Spatrick   }
77e5dd7070Spatrick 
78e5dd7070Spatrick   // Decompose the outer binary operator.
79e5dd7070Spatrick   if (auto *BO = dyn_cast<BinaryOperator>(E)) {
80e5dd7070Spatrick     assert(!SkippedNot || BO->getOpcode() == BO_EQ);
81e5dd7070Spatrick     Result.Opcode = SkippedNot ? BO_NE : BO->getOpcode();
82e5dd7070Spatrick     Result.LHS = BO->getLHS();
83e5dd7070Spatrick     Result.RHS = BO->getRHS();
84e5dd7070Spatrick     Result.InnerBinOp = BO;
85e5dd7070Spatrick   } else if (auto *BO = dyn_cast<CXXOperatorCallExpr>(E)) {
86e5dd7070Spatrick     assert(!SkippedNot || BO->getOperator() == OO_EqualEqual);
87e5dd7070Spatrick     assert(BO->isInfixBinaryOp());
88e5dd7070Spatrick     switch (BO->getOperator()) {
89e5dd7070Spatrick     case OO_Less: Result.Opcode = BO_LT; break;
90e5dd7070Spatrick     case OO_LessEqual: Result.Opcode = BO_LE; break;
91e5dd7070Spatrick     case OO_Greater: Result.Opcode = BO_GT; break;
92e5dd7070Spatrick     case OO_GreaterEqual: Result.Opcode = BO_GE; break;
93e5dd7070Spatrick     case OO_Spaceship: Result.Opcode = BO_Cmp; break;
94e5dd7070Spatrick     case OO_EqualEqual: Result.Opcode = SkippedNot ? BO_NE : BO_EQ; break;
95e5dd7070Spatrick     default: llvm_unreachable("unexpected binop in rewritten operator expr");
96e5dd7070Spatrick     }
97e5dd7070Spatrick     Result.LHS = BO->getArg(0);
98e5dd7070Spatrick     Result.RHS = BO->getArg(1);
99e5dd7070Spatrick     Result.InnerBinOp = BO;
100e5dd7070Spatrick   } else {
101e5dd7070Spatrick     llvm_unreachable("unexpected rewritten operator form");
102e5dd7070Spatrick   }
103e5dd7070Spatrick 
104e5dd7070Spatrick   // Put the operands in the right order for == and !=, and canonicalize the
105e5dd7070Spatrick   // <=> subexpression onto the LHS for all other forms.
106e5dd7070Spatrick   if (isReversed())
107e5dd7070Spatrick     std::swap(Result.LHS, Result.RHS);
108e5dd7070Spatrick 
109e5dd7070Spatrick   // If this isn't a spaceship rewrite, we're done.
110e5dd7070Spatrick   if (Result.Opcode == BO_EQ || Result.Opcode == BO_NE)
111e5dd7070Spatrick     return Result;
112e5dd7070Spatrick 
113e5dd7070Spatrick   // Otherwise, we expect a <=> to now be on the LHS.
114e5dd7070Spatrick   E = Result.LHS->IgnoreImplicitAsWritten();
115e5dd7070Spatrick   if (auto *BO = dyn_cast<BinaryOperator>(E)) {
116e5dd7070Spatrick     assert(BO->getOpcode() == BO_Cmp);
117e5dd7070Spatrick     Result.LHS = BO->getLHS();
118e5dd7070Spatrick     Result.RHS = BO->getRHS();
119e5dd7070Spatrick     Result.InnerBinOp = BO;
120e5dd7070Spatrick   } else if (auto *BO = dyn_cast<CXXOperatorCallExpr>(E)) {
121e5dd7070Spatrick     assert(BO->getOperator() == OO_Spaceship);
122e5dd7070Spatrick     Result.LHS = BO->getArg(0);
123e5dd7070Spatrick     Result.RHS = BO->getArg(1);
124e5dd7070Spatrick     Result.InnerBinOp = BO;
125e5dd7070Spatrick   } else {
126e5dd7070Spatrick     llvm_unreachable("unexpected rewritten operator form");
127e5dd7070Spatrick   }
128e5dd7070Spatrick 
129e5dd7070Spatrick   // Put the comparison operands in the right order.
130e5dd7070Spatrick   if (isReversed())
131e5dd7070Spatrick     std::swap(Result.LHS, Result.RHS);
132e5dd7070Spatrick   return Result;
133e5dd7070Spatrick }
134e5dd7070Spatrick 
isPotentiallyEvaluated() const135e5dd7070Spatrick bool CXXTypeidExpr::isPotentiallyEvaluated() const {
136e5dd7070Spatrick   if (isTypeOperand())
137e5dd7070Spatrick     return false;
138e5dd7070Spatrick 
139e5dd7070Spatrick   // C++11 [expr.typeid]p3:
140e5dd7070Spatrick   //   When typeid is applied to an expression other than a glvalue of
141e5dd7070Spatrick   //   polymorphic class type, [...] the expression is an unevaluated operand.
142e5dd7070Spatrick   const Expr *E = getExprOperand();
143e5dd7070Spatrick   if (const CXXRecordDecl *RD = E->getType()->getAsCXXRecordDecl())
144e5dd7070Spatrick     if (RD->isPolymorphic() && E->isGLValue())
145e5dd7070Spatrick       return true;
146e5dd7070Spatrick 
147e5dd7070Spatrick   return false;
148e5dd7070Spatrick }
149e5dd7070Spatrick 
isMostDerived(ASTContext & Context) const150a9ac8606Spatrick bool CXXTypeidExpr::isMostDerived(ASTContext &Context) const {
151a9ac8606Spatrick   assert(!isTypeOperand() && "Cannot call isMostDerived for typeid(type)");
152a9ac8606Spatrick   const Expr *E = getExprOperand()->IgnoreParenNoopCasts(Context);
153a9ac8606Spatrick   if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
154a9ac8606Spatrick     QualType Ty = DRE->getDecl()->getType();
155a9ac8606Spatrick     if (!Ty->isPointerType() && !Ty->isReferenceType())
156a9ac8606Spatrick       return true;
157a9ac8606Spatrick   }
158a9ac8606Spatrick 
159a9ac8606Spatrick   return false;
160a9ac8606Spatrick }
161a9ac8606Spatrick 
getTypeOperand(ASTContext & Context) const162e5dd7070Spatrick QualType CXXTypeidExpr::getTypeOperand(ASTContext &Context) const {
163e5dd7070Spatrick   assert(isTypeOperand() && "Cannot call getTypeOperand for typeid(expr)");
164e5dd7070Spatrick   Qualifiers Quals;
165e5dd7070Spatrick   return Context.getUnqualifiedArrayType(
166e5dd7070Spatrick       Operand.get<TypeSourceInfo *>()->getType().getNonReferenceType(), Quals);
167e5dd7070Spatrick }
168e5dd7070Spatrick 
getTypeOperand(ASTContext & Context) const169e5dd7070Spatrick QualType CXXUuidofExpr::getTypeOperand(ASTContext &Context) const {
170e5dd7070Spatrick   assert(isTypeOperand() && "Cannot call getTypeOperand for __uuidof(expr)");
171e5dd7070Spatrick   Qualifiers Quals;
172e5dd7070Spatrick   return Context.getUnqualifiedArrayType(
173e5dd7070Spatrick       Operand.get<TypeSourceInfo *>()->getType().getNonReferenceType(), Quals);
174e5dd7070Spatrick }
175e5dd7070Spatrick 
176e5dd7070Spatrick // CXXScalarValueInitExpr
getBeginLoc() const177e5dd7070Spatrick SourceLocation CXXScalarValueInitExpr::getBeginLoc() const {
178e5dd7070Spatrick   return TypeInfo ? TypeInfo->getTypeLoc().getBeginLoc() : getRParenLoc();
179e5dd7070Spatrick }
180e5dd7070Spatrick 
181e5dd7070Spatrick // CXXNewExpr
CXXNewExpr(bool IsGlobalNew,FunctionDecl * OperatorNew,FunctionDecl * OperatorDelete,bool ShouldPassAlignment,bool UsualArrayDeleteWantsSize,ArrayRef<Expr * > PlacementArgs,SourceRange TypeIdParens,std::optional<Expr * > ArraySize,InitializationStyle InitializationStyle,Expr * Initializer,QualType Ty,TypeSourceInfo * AllocatedTypeInfo,SourceRange Range,SourceRange DirectInitRange)182e5dd7070Spatrick CXXNewExpr::CXXNewExpr(bool IsGlobalNew, FunctionDecl *OperatorNew,
183e5dd7070Spatrick                        FunctionDecl *OperatorDelete, bool ShouldPassAlignment,
184e5dd7070Spatrick                        bool UsualArrayDeleteWantsSize,
185e5dd7070Spatrick                        ArrayRef<Expr *> PlacementArgs, SourceRange TypeIdParens,
186*12c85518Srobert                        std::optional<Expr *> ArraySize,
187e5dd7070Spatrick                        InitializationStyle InitializationStyle,
188e5dd7070Spatrick                        Expr *Initializer, QualType Ty,
189e5dd7070Spatrick                        TypeSourceInfo *AllocatedTypeInfo, SourceRange Range,
190e5dd7070Spatrick                        SourceRange DirectInitRange)
191a9ac8606Spatrick     : Expr(CXXNewExprClass, Ty, VK_PRValue, OK_Ordinary),
192e5dd7070Spatrick       OperatorNew(OperatorNew), OperatorDelete(OperatorDelete),
193e5dd7070Spatrick       AllocatedTypeInfo(AllocatedTypeInfo), Range(Range),
194e5dd7070Spatrick       DirectInitRange(DirectInitRange) {
195e5dd7070Spatrick 
196e5dd7070Spatrick   assert((Initializer != nullptr || InitializationStyle == NoInit) &&
197e5dd7070Spatrick          "Only NoInit can have no initializer!");
198e5dd7070Spatrick 
199e5dd7070Spatrick   CXXNewExprBits.IsGlobalNew = IsGlobalNew;
200*12c85518Srobert   CXXNewExprBits.IsArray = ArraySize.has_value();
201e5dd7070Spatrick   CXXNewExprBits.ShouldPassAlignment = ShouldPassAlignment;
202e5dd7070Spatrick   CXXNewExprBits.UsualArrayDeleteWantsSize = UsualArrayDeleteWantsSize;
203e5dd7070Spatrick   CXXNewExprBits.StoredInitializationStyle =
204e5dd7070Spatrick       Initializer ? InitializationStyle + 1 : 0;
205e5dd7070Spatrick   bool IsParenTypeId = TypeIdParens.isValid();
206e5dd7070Spatrick   CXXNewExprBits.IsParenTypeId = IsParenTypeId;
207e5dd7070Spatrick   CXXNewExprBits.NumPlacementArgs = PlacementArgs.size();
208e5dd7070Spatrick 
209ec727ea7Spatrick   if (ArraySize)
210e5dd7070Spatrick     getTrailingObjects<Stmt *>()[arraySizeOffset()] = *ArraySize;
211ec727ea7Spatrick   if (Initializer)
212e5dd7070Spatrick     getTrailingObjects<Stmt *>()[initExprOffset()] = Initializer;
213ec727ea7Spatrick   for (unsigned I = 0; I != PlacementArgs.size(); ++I)
214e5dd7070Spatrick     getTrailingObjects<Stmt *>()[placementNewArgsOffset() + I] =
215e5dd7070Spatrick         PlacementArgs[I];
216e5dd7070Spatrick   if (IsParenTypeId)
217e5dd7070Spatrick     getTrailingObjects<SourceRange>()[0] = TypeIdParens;
218e5dd7070Spatrick 
219e5dd7070Spatrick   switch (getInitializationStyle()) {
220e5dd7070Spatrick   case CallInit:
221e5dd7070Spatrick     this->Range.setEnd(DirectInitRange.getEnd());
222e5dd7070Spatrick     break;
223e5dd7070Spatrick   case ListInit:
224e5dd7070Spatrick     this->Range.setEnd(getInitializer()->getSourceRange().getEnd());
225e5dd7070Spatrick     break;
226e5dd7070Spatrick   default:
227e5dd7070Spatrick     if (IsParenTypeId)
228e5dd7070Spatrick       this->Range.setEnd(TypeIdParens.getEnd());
229e5dd7070Spatrick     break;
230e5dd7070Spatrick   }
231ec727ea7Spatrick 
232ec727ea7Spatrick   setDependence(computeDependence(this));
233e5dd7070Spatrick }
234e5dd7070Spatrick 
CXXNewExpr(EmptyShell Empty,bool IsArray,unsigned NumPlacementArgs,bool IsParenTypeId)235e5dd7070Spatrick CXXNewExpr::CXXNewExpr(EmptyShell Empty, bool IsArray,
236e5dd7070Spatrick                        unsigned NumPlacementArgs, bool IsParenTypeId)
237e5dd7070Spatrick     : Expr(CXXNewExprClass, Empty) {
238e5dd7070Spatrick   CXXNewExprBits.IsArray = IsArray;
239e5dd7070Spatrick   CXXNewExprBits.NumPlacementArgs = NumPlacementArgs;
240e5dd7070Spatrick   CXXNewExprBits.IsParenTypeId = IsParenTypeId;
241e5dd7070Spatrick }
242e5dd7070Spatrick 
243e5dd7070Spatrick CXXNewExpr *
Create(const ASTContext & Ctx,bool IsGlobalNew,FunctionDecl * OperatorNew,FunctionDecl * OperatorDelete,bool ShouldPassAlignment,bool UsualArrayDeleteWantsSize,ArrayRef<Expr * > PlacementArgs,SourceRange TypeIdParens,std::optional<Expr * > ArraySize,InitializationStyle InitializationStyle,Expr * Initializer,QualType Ty,TypeSourceInfo * AllocatedTypeInfo,SourceRange Range,SourceRange DirectInitRange)244e5dd7070Spatrick CXXNewExpr::Create(const ASTContext &Ctx, bool IsGlobalNew,
245e5dd7070Spatrick                    FunctionDecl *OperatorNew, FunctionDecl *OperatorDelete,
246e5dd7070Spatrick                    bool ShouldPassAlignment, bool UsualArrayDeleteWantsSize,
247e5dd7070Spatrick                    ArrayRef<Expr *> PlacementArgs, SourceRange TypeIdParens,
248*12c85518Srobert                    std::optional<Expr *> ArraySize,
249e5dd7070Spatrick                    InitializationStyle InitializationStyle, Expr *Initializer,
250e5dd7070Spatrick                    QualType Ty, TypeSourceInfo *AllocatedTypeInfo,
251e5dd7070Spatrick                    SourceRange Range, SourceRange DirectInitRange) {
252*12c85518Srobert   bool IsArray = ArraySize.has_value();
253e5dd7070Spatrick   bool HasInit = Initializer != nullptr;
254e5dd7070Spatrick   unsigned NumPlacementArgs = PlacementArgs.size();
255e5dd7070Spatrick   bool IsParenTypeId = TypeIdParens.isValid();
256e5dd7070Spatrick   void *Mem =
257e5dd7070Spatrick       Ctx.Allocate(totalSizeToAlloc<Stmt *, SourceRange>(
258e5dd7070Spatrick                        IsArray + HasInit + NumPlacementArgs, IsParenTypeId),
259e5dd7070Spatrick                    alignof(CXXNewExpr));
260e5dd7070Spatrick   return new (Mem)
261e5dd7070Spatrick       CXXNewExpr(IsGlobalNew, OperatorNew, OperatorDelete, ShouldPassAlignment,
262e5dd7070Spatrick                  UsualArrayDeleteWantsSize, PlacementArgs, TypeIdParens,
263e5dd7070Spatrick                  ArraySize, InitializationStyle, Initializer, Ty,
264e5dd7070Spatrick                  AllocatedTypeInfo, Range, DirectInitRange);
265e5dd7070Spatrick }
266e5dd7070Spatrick 
CreateEmpty(const ASTContext & Ctx,bool IsArray,bool HasInit,unsigned NumPlacementArgs,bool IsParenTypeId)267e5dd7070Spatrick CXXNewExpr *CXXNewExpr::CreateEmpty(const ASTContext &Ctx, bool IsArray,
268e5dd7070Spatrick                                     bool HasInit, unsigned NumPlacementArgs,
269e5dd7070Spatrick                                     bool IsParenTypeId) {
270e5dd7070Spatrick   void *Mem =
271e5dd7070Spatrick       Ctx.Allocate(totalSizeToAlloc<Stmt *, SourceRange>(
272e5dd7070Spatrick                        IsArray + HasInit + NumPlacementArgs, IsParenTypeId),
273e5dd7070Spatrick                    alignof(CXXNewExpr));
274e5dd7070Spatrick   return new (Mem)
275e5dd7070Spatrick       CXXNewExpr(EmptyShell(), IsArray, NumPlacementArgs, IsParenTypeId);
276e5dd7070Spatrick }
277e5dd7070Spatrick 
shouldNullCheckAllocation() const278e5dd7070Spatrick bool CXXNewExpr::shouldNullCheckAllocation() const {
279a9ac8606Spatrick   return !getOperatorNew()->hasAttr<ReturnsNonNullAttr>() &&
280a9ac8606Spatrick          getOperatorNew()
281e5dd7070Spatrick              ->getType()
282e5dd7070Spatrick              ->castAs<FunctionProtoType>()
283e5dd7070Spatrick              ->isNothrow() &&
284e5dd7070Spatrick          !getOperatorNew()->isReservedGlobalPlacementOperator();
285e5dd7070Spatrick }
286e5dd7070Spatrick 
287e5dd7070Spatrick // CXXDeleteExpr
getDestroyedType() const288e5dd7070Spatrick QualType CXXDeleteExpr::getDestroyedType() const {
289e5dd7070Spatrick   const Expr *Arg = getArgument();
290e5dd7070Spatrick 
291e5dd7070Spatrick   // For a destroying operator delete, we may have implicitly converted the
292e5dd7070Spatrick   // pointer type to the type of the parameter of the 'operator delete'
293e5dd7070Spatrick   // function.
294e5dd7070Spatrick   while (const auto *ICE = dyn_cast<ImplicitCastExpr>(Arg)) {
295e5dd7070Spatrick     if (ICE->getCastKind() == CK_DerivedToBase ||
296e5dd7070Spatrick         ICE->getCastKind() == CK_UncheckedDerivedToBase ||
297e5dd7070Spatrick         ICE->getCastKind() == CK_NoOp) {
298e5dd7070Spatrick       assert((ICE->getCastKind() == CK_NoOp ||
299e5dd7070Spatrick               getOperatorDelete()->isDestroyingOperatorDelete()) &&
300e5dd7070Spatrick              "only a destroying operator delete can have a converted arg");
301e5dd7070Spatrick       Arg = ICE->getSubExpr();
302e5dd7070Spatrick     } else
303e5dd7070Spatrick       break;
304e5dd7070Spatrick   }
305e5dd7070Spatrick 
306e5dd7070Spatrick   // The type-to-delete may not be a pointer if it's a dependent type.
307e5dd7070Spatrick   const QualType ArgType = Arg->getType();
308e5dd7070Spatrick 
309e5dd7070Spatrick   if (ArgType->isDependentType() && !ArgType->isPointerType())
310e5dd7070Spatrick     return QualType();
311e5dd7070Spatrick 
312e5dd7070Spatrick   return ArgType->castAs<PointerType>()->getPointeeType();
313e5dd7070Spatrick }
314e5dd7070Spatrick 
315e5dd7070Spatrick // CXXPseudoDestructorExpr
PseudoDestructorTypeStorage(TypeSourceInfo * Info)316e5dd7070Spatrick PseudoDestructorTypeStorage::PseudoDestructorTypeStorage(TypeSourceInfo *Info)
317e5dd7070Spatrick     : Type(Info) {
318*12c85518Srobert   Location = Info->getTypeLoc().getBeginLoc();
319e5dd7070Spatrick }
320e5dd7070Spatrick 
CXXPseudoDestructorExpr(const ASTContext & Context,Expr * Base,bool isArrow,SourceLocation OperatorLoc,NestedNameSpecifierLoc QualifierLoc,TypeSourceInfo * ScopeType,SourceLocation ColonColonLoc,SourceLocation TildeLoc,PseudoDestructorTypeStorage DestroyedType)321ec727ea7Spatrick CXXPseudoDestructorExpr::CXXPseudoDestructorExpr(
322ec727ea7Spatrick     const ASTContext &Context, Expr *Base, bool isArrow,
323ec727ea7Spatrick     SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc,
324ec727ea7Spatrick     TypeSourceInfo *ScopeType, SourceLocation ColonColonLoc,
325ec727ea7Spatrick     SourceLocation TildeLoc, PseudoDestructorTypeStorage DestroyedType)
326a9ac8606Spatrick     : Expr(CXXPseudoDestructorExprClass, Context.BoundMemberTy, VK_PRValue,
327ec727ea7Spatrick            OK_Ordinary),
328e5dd7070Spatrick       Base(static_cast<Stmt *>(Base)), IsArrow(isArrow),
329e5dd7070Spatrick       OperatorLoc(OperatorLoc), QualifierLoc(QualifierLoc),
330e5dd7070Spatrick       ScopeType(ScopeType), ColonColonLoc(ColonColonLoc), TildeLoc(TildeLoc),
331ec727ea7Spatrick       DestroyedType(DestroyedType) {
332ec727ea7Spatrick   setDependence(computeDependence(this));
333ec727ea7Spatrick }
334e5dd7070Spatrick 
getDestroyedType() const335e5dd7070Spatrick QualType CXXPseudoDestructorExpr::getDestroyedType() const {
336e5dd7070Spatrick   if (TypeSourceInfo *TInfo = DestroyedType.getTypeSourceInfo())
337e5dd7070Spatrick     return TInfo->getType();
338e5dd7070Spatrick 
339e5dd7070Spatrick   return QualType();
340e5dd7070Spatrick }
341e5dd7070Spatrick 
getEndLoc() const342e5dd7070Spatrick SourceLocation CXXPseudoDestructorExpr::getEndLoc() const {
343e5dd7070Spatrick   SourceLocation End = DestroyedType.getLocation();
344e5dd7070Spatrick   if (TypeSourceInfo *TInfo = DestroyedType.getTypeSourceInfo())
345*12c85518Srobert     End = TInfo->getTypeLoc().getSourceRange().getEnd();
346e5dd7070Spatrick   return End;
347e5dd7070Spatrick }
348e5dd7070Spatrick 
349e5dd7070Spatrick // UnresolvedLookupExpr
UnresolvedLookupExpr(const ASTContext & Context,CXXRecordDecl * NamingClass,NestedNameSpecifierLoc QualifierLoc,SourceLocation TemplateKWLoc,const DeclarationNameInfo & NameInfo,bool RequiresADL,bool Overloaded,const TemplateArgumentListInfo * TemplateArgs,UnresolvedSetIterator Begin,UnresolvedSetIterator End)350e5dd7070Spatrick UnresolvedLookupExpr::UnresolvedLookupExpr(
351e5dd7070Spatrick     const ASTContext &Context, CXXRecordDecl *NamingClass,
352e5dd7070Spatrick     NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc,
353e5dd7070Spatrick     const DeclarationNameInfo &NameInfo, bool RequiresADL, bool Overloaded,
354e5dd7070Spatrick     const TemplateArgumentListInfo *TemplateArgs, UnresolvedSetIterator Begin,
355e5dd7070Spatrick     UnresolvedSetIterator End)
356e5dd7070Spatrick     : OverloadExpr(UnresolvedLookupExprClass, Context, QualifierLoc,
357e5dd7070Spatrick                    TemplateKWLoc, NameInfo, TemplateArgs, Begin, End, false,
358e5dd7070Spatrick                    false, false),
359e5dd7070Spatrick       NamingClass(NamingClass) {
360e5dd7070Spatrick   UnresolvedLookupExprBits.RequiresADL = RequiresADL;
361e5dd7070Spatrick   UnresolvedLookupExprBits.Overloaded = Overloaded;
362e5dd7070Spatrick }
363e5dd7070Spatrick 
UnresolvedLookupExpr(EmptyShell Empty,unsigned NumResults,bool HasTemplateKWAndArgsInfo)364e5dd7070Spatrick UnresolvedLookupExpr::UnresolvedLookupExpr(EmptyShell Empty,
365e5dd7070Spatrick                                            unsigned NumResults,
366e5dd7070Spatrick                                            bool HasTemplateKWAndArgsInfo)
367e5dd7070Spatrick     : OverloadExpr(UnresolvedLookupExprClass, Empty, NumResults,
368e5dd7070Spatrick                    HasTemplateKWAndArgsInfo) {}
369e5dd7070Spatrick 
Create(const ASTContext & Context,CXXRecordDecl * NamingClass,NestedNameSpecifierLoc QualifierLoc,const DeclarationNameInfo & NameInfo,bool RequiresADL,bool Overloaded,UnresolvedSetIterator Begin,UnresolvedSetIterator End)370e5dd7070Spatrick UnresolvedLookupExpr *UnresolvedLookupExpr::Create(
371e5dd7070Spatrick     const ASTContext &Context, CXXRecordDecl *NamingClass,
372e5dd7070Spatrick     NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo,
373e5dd7070Spatrick     bool RequiresADL, bool Overloaded, UnresolvedSetIterator Begin,
374e5dd7070Spatrick     UnresolvedSetIterator End) {
375e5dd7070Spatrick   unsigned NumResults = End - Begin;
376e5dd7070Spatrick   unsigned Size = totalSizeToAlloc<DeclAccessPair, ASTTemplateKWAndArgsInfo,
377e5dd7070Spatrick                                    TemplateArgumentLoc>(NumResults, 0, 0);
378e5dd7070Spatrick   void *Mem = Context.Allocate(Size, alignof(UnresolvedLookupExpr));
379e5dd7070Spatrick   return new (Mem) UnresolvedLookupExpr(Context, NamingClass, QualifierLoc,
380e5dd7070Spatrick                                         SourceLocation(), NameInfo, RequiresADL,
381e5dd7070Spatrick                                         Overloaded, nullptr, Begin, End);
382e5dd7070Spatrick }
383e5dd7070Spatrick 
Create(const ASTContext & Context,CXXRecordDecl * NamingClass,NestedNameSpecifierLoc QualifierLoc,SourceLocation TemplateKWLoc,const DeclarationNameInfo & NameInfo,bool RequiresADL,const TemplateArgumentListInfo * Args,UnresolvedSetIterator Begin,UnresolvedSetIterator End)384e5dd7070Spatrick UnresolvedLookupExpr *UnresolvedLookupExpr::Create(
385e5dd7070Spatrick     const ASTContext &Context, CXXRecordDecl *NamingClass,
386e5dd7070Spatrick     NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc,
387e5dd7070Spatrick     const DeclarationNameInfo &NameInfo, bool RequiresADL,
388e5dd7070Spatrick     const TemplateArgumentListInfo *Args, UnresolvedSetIterator Begin,
389e5dd7070Spatrick     UnresolvedSetIterator End) {
390e5dd7070Spatrick   assert(Args || TemplateKWLoc.isValid());
391e5dd7070Spatrick   unsigned NumResults = End - Begin;
392e5dd7070Spatrick   unsigned NumTemplateArgs = Args ? Args->size() : 0;
393e5dd7070Spatrick   unsigned Size =
394e5dd7070Spatrick       totalSizeToAlloc<DeclAccessPair, ASTTemplateKWAndArgsInfo,
395e5dd7070Spatrick                        TemplateArgumentLoc>(NumResults, 1, NumTemplateArgs);
396e5dd7070Spatrick   void *Mem = Context.Allocate(Size, alignof(UnresolvedLookupExpr));
397e5dd7070Spatrick   return new (Mem) UnresolvedLookupExpr(Context, NamingClass, QualifierLoc,
398e5dd7070Spatrick                                         TemplateKWLoc, NameInfo, RequiresADL,
399e5dd7070Spatrick                                         /*Overloaded*/ true, Args, Begin, End);
400e5dd7070Spatrick }
401e5dd7070Spatrick 
CreateEmpty(const ASTContext & Context,unsigned NumResults,bool HasTemplateKWAndArgsInfo,unsigned NumTemplateArgs)402e5dd7070Spatrick UnresolvedLookupExpr *UnresolvedLookupExpr::CreateEmpty(
403e5dd7070Spatrick     const ASTContext &Context, unsigned NumResults,
404e5dd7070Spatrick     bool HasTemplateKWAndArgsInfo, unsigned NumTemplateArgs) {
405e5dd7070Spatrick   assert(NumTemplateArgs == 0 || HasTemplateKWAndArgsInfo);
406e5dd7070Spatrick   unsigned Size = totalSizeToAlloc<DeclAccessPair, ASTTemplateKWAndArgsInfo,
407e5dd7070Spatrick                                    TemplateArgumentLoc>(
408e5dd7070Spatrick       NumResults, HasTemplateKWAndArgsInfo, NumTemplateArgs);
409e5dd7070Spatrick   void *Mem = Context.Allocate(Size, alignof(UnresolvedLookupExpr));
410e5dd7070Spatrick   return new (Mem)
411e5dd7070Spatrick       UnresolvedLookupExpr(EmptyShell(), NumResults, HasTemplateKWAndArgsInfo);
412e5dd7070Spatrick }
413e5dd7070Spatrick 
OverloadExpr(StmtClass SC,const ASTContext & Context,NestedNameSpecifierLoc QualifierLoc,SourceLocation TemplateKWLoc,const DeclarationNameInfo & NameInfo,const TemplateArgumentListInfo * TemplateArgs,UnresolvedSetIterator Begin,UnresolvedSetIterator End,bool KnownDependent,bool KnownInstantiationDependent,bool KnownContainsUnexpandedParameterPack)414e5dd7070Spatrick OverloadExpr::OverloadExpr(StmtClass SC, const ASTContext &Context,
415e5dd7070Spatrick                            NestedNameSpecifierLoc QualifierLoc,
416e5dd7070Spatrick                            SourceLocation TemplateKWLoc,
417e5dd7070Spatrick                            const DeclarationNameInfo &NameInfo,
418e5dd7070Spatrick                            const TemplateArgumentListInfo *TemplateArgs,
419e5dd7070Spatrick                            UnresolvedSetIterator Begin,
420e5dd7070Spatrick                            UnresolvedSetIterator End, bool KnownDependent,
421e5dd7070Spatrick                            bool KnownInstantiationDependent,
422e5dd7070Spatrick                            bool KnownContainsUnexpandedParameterPack)
423ec727ea7Spatrick     : Expr(SC, Context.OverloadTy, VK_LValue, OK_Ordinary), NameInfo(NameInfo),
424ec727ea7Spatrick       QualifierLoc(QualifierLoc) {
425e5dd7070Spatrick   unsigned NumResults = End - Begin;
426e5dd7070Spatrick   OverloadExprBits.NumResults = NumResults;
427e5dd7070Spatrick   OverloadExprBits.HasTemplateKWAndArgsInfo =
428e5dd7070Spatrick       (TemplateArgs != nullptr ) || TemplateKWLoc.isValid();
429e5dd7070Spatrick 
430e5dd7070Spatrick   if (NumResults) {
431e5dd7070Spatrick     // Copy the results to the trailing array past UnresolvedLookupExpr
432e5dd7070Spatrick     // or UnresolvedMemberExpr.
433e5dd7070Spatrick     DeclAccessPair *Results = getTrailingResults();
434e5dd7070Spatrick     memcpy(Results, Begin.I, NumResults * sizeof(DeclAccessPair));
435e5dd7070Spatrick   }
436e5dd7070Spatrick 
437e5dd7070Spatrick   if (TemplateArgs) {
438ec727ea7Spatrick     auto Deps = TemplateArgumentDependence::None;
439e5dd7070Spatrick     getTrailingASTTemplateKWAndArgsInfo()->initializeFrom(
440ec727ea7Spatrick         TemplateKWLoc, *TemplateArgs, getTrailingTemplateArgumentLoc(), Deps);
441e5dd7070Spatrick   } else if (TemplateKWLoc.isValid()) {
442e5dd7070Spatrick     getTrailingASTTemplateKWAndArgsInfo()->initializeFrom(TemplateKWLoc);
443e5dd7070Spatrick   }
444e5dd7070Spatrick 
445ec727ea7Spatrick   setDependence(computeDependence(this, KnownDependent,
446ec727ea7Spatrick                                   KnownInstantiationDependent,
447ec727ea7Spatrick                                   KnownContainsUnexpandedParameterPack));
448e5dd7070Spatrick   if (isTypeDependent())
449e5dd7070Spatrick     setType(Context.DependentTy);
450e5dd7070Spatrick }
451e5dd7070Spatrick 
OverloadExpr(StmtClass SC,EmptyShell Empty,unsigned NumResults,bool HasTemplateKWAndArgsInfo)452e5dd7070Spatrick OverloadExpr::OverloadExpr(StmtClass SC, EmptyShell Empty, unsigned NumResults,
453e5dd7070Spatrick                            bool HasTemplateKWAndArgsInfo)
454e5dd7070Spatrick     : Expr(SC, Empty) {
455e5dd7070Spatrick   OverloadExprBits.NumResults = NumResults;
456e5dd7070Spatrick   OverloadExprBits.HasTemplateKWAndArgsInfo = HasTemplateKWAndArgsInfo;
457e5dd7070Spatrick }
458e5dd7070Spatrick 
459e5dd7070Spatrick // DependentScopeDeclRefExpr
DependentScopeDeclRefExpr(QualType Ty,NestedNameSpecifierLoc QualifierLoc,SourceLocation TemplateKWLoc,const DeclarationNameInfo & NameInfo,const TemplateArgumentListInfo * Args)460e5dd7070Spatrick DependentScopeDeclRefExpr::DependentScopeDeclRefExpr(
461e5dd7070Spatrick     QualType Ty, NestedNameSpecifierLoc QualifierLoc,
462e5dd7070Spatrick     SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo,
463e5dd7070Spatrick     const TemplateArgumentListInfo *Args)
464ec727ea7Spatrick     : Expr(DependentScopeDeclRefExprClass, Ty, VK_LValue, OK_Ordinary),
465e5dd7070Spatrick       QualifierLoc(QualifierLoc), NameInfo(NameInfo) {
466e5dd7070Spatrick   DependentScopeDeclRefExprBits.HasTemplateKWAndArgsInfo =
467e5dd7070Spatrick       (Args != nullptr) || TemplateKWLoc.isValid();
468e5dd7070Spatrick   if (Args) {
469ec727ea7Spatrick     auto Deps = TemplateArgumentDependence::None;
470e5dd7070Spatrick     getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
471ec727ea7Spatrick         TemplateKWLoc, *Args, getTrailingObjects<TemplateArgumentLoc>(), Deps);
472e5dd7070Spatrick   } else if (TemplateKWLoc.isValid()) {
473e5dd7070Spatrick     getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
474e5dd7070Spatrick         TemplateKWLoc);
475e5dd7070Spatrick   }
476ec727ea7Spatrick   setDependence(computeDependence(this));
477e5dd7070Spatrick }
478e5dd7070Spatrick 
Create(const ASTContext & Context,NestedNameSpecifierLoc QualifierLoc,SourceLocation TemplateKWLoc,const DeclarationNameInfo & NameInfo,const TemplateArgumentListInfo * Args)479e5dd7070Spatrick DependentScopeDeclRefExpr *DependentScopeDeclRefExpr::Create(
480e5dd7070Spatrick     const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc,
481e5dd7070Spatrick     SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo,
482e5dd7070Spatrick     const TemplateArgumentListInfo *Args) {
483e5dd7070Spatrick   assert(QualifierLoc && "should be created for dependent qualifiers");
484e5dd7070Spatrick   bool HasTemplateKWAndArgsInfo = Args || TemplateKWLoc.isValid();
485e5dd7070Spatrick   std::size_t Size =
486e5dd7070Spatrick       totalSizeToAlloc<ASTTemplateKWAndArgsInfo, TemplateArgumentLoc>(
487e5dd7070Spatrick           HasTemplateKWAndArgsInfo, Args ? Args->size() : 0);
488e5dd7070Spatrick   void *Mem = Context.Allocate(Size);
489e5dd7070Spatrick   return new (Mem) DependentScopeDeclRefExpr(Context.DependentTy, QualifierLoc,
490e5dd7070Spatrick                                              TemplateKWLoc, NameInfo, Args);
491e5dd7070Spatrick }
492e5dd7070Spatrick 
493e5dd7070Spatrick DependentScopeDeclRefExpr *
CreateEmpty(const ASTContext & Context,bool HasTemplateKWAndArgsInfo,unsigned NumTemplateArgs)494e5dd7070Spatrick DependentScopeDeclRefExpr::CreateEmpty(const ASTContext &Context,
495e5dd7070Spatrick                                        bool HasTemplateKWAndArgsInfo,
496e5dd7070Spatrick                                        unsigned NumTemplateArgs) {
497e5dd7070Spatrick   assert(NumTemplateArgs == 0 || HasTemplateKWAndArgsInfo);
498e5dd7070Spatrick   std::size_t Size =
499e5dd7070Spatrick       totalSizeToAlloc<ASTTemplateKWAndArgsInfo, TemplateArgumentLoc>(
500e5dd7070Spatrick           HasTemplateKWAndArgsInfo, NumTemplateArgs);
501e5dd7070Spatrick   void *Mem = Context.Allocate(Size);
502e5dd7070Spatrick   auto *E = new (Mem) DependentScopeDeclRefExpr(
503e5dd7070Spatrick       QualType(), NestedNameSpecifierLoc(), SourceLocation(),
504e5dd7070Spatrick       DeclarationNameInfo(), nullptr);
505e5dd7070Spatrick   E->DependentScopeDeclRefExprBits.HasTemplateKWAndArgsInfo =
506e5dd7070Spatrick       HasTemplateKWAndArgsInfo;
507e5dd7070Spatrick   return E;
508e5dd7070Spatrick }
509e5dd7070Spatrick 
getBeginLoc() const510e5dd7070Spatrick SourceLocation CXXConstructExpr::getBeginLoc() const {
511e5dd7070Spatrick   if (isa<CXXTemporaryObjectExpr>(this))
512e5dd7070Spatrick     return cast<CXXTemporaryObjectExpr>(this)->getBeginLoc();
513e5dd7070Spatrick   return getLocation();
514e5dd7070Spatrick }
515e5dd7070Spatrick 
getEndLoc() const516e5dd7070Spatrick SourceLocation CXXConstructExpr::getEndLoc() const {
517e5dd7070Spatrick   if (isa<CXXTemporaryObjectExpr>(this))
518e5dd7070Spatrick     return cast<CXXTemporaryObjectExpr>(this)->getEndLoc();
519e5dd7070Spatrick 
520e5dd7070Spatrick   if (ParenOrBraceRange.isValid())
521e5dd7070Spatrick     return ParenOrBraceRange.getEnd();
522e5dd7070Spatrick 
523e5dd7070Spatrick   SourceLocation End = getLocation();
524e5dd7070Spatrick   for (unsigned I = getNumArgs(); I > 0; --I) {
525e5dd7070Spatrick     const Expr *Arg = getArg(I-1);
526e5dd7070Spatrick     if (!Arg->isDefaultArgument()) {
527e5dd7070Spatrick       SourceLocation NewEnd = Arg->getEndLoc();
528e5dd7070Spatrick       if (NewEnd.isValid()) {
529e5dd7070Spatrick         End = NewEnd;
530e5dd7070Spatrick         break;
531e5dd7070Spatrick       }
532e5dd7070Spatrick     }
533e5dd7070Spatrick   }
534e5dd7070Spatrick 
535e5dd7070Spatrick   return End;
536e5dd7070Spatrick }
537e5dd7070Spatrick 
CXXOperatorCallExpr(OverloadedOperatorKind OpKind,Expr * Fn,ArrayRef<Expr * > Args,QualType Ty,ExprValueKind VK,SourceLocation OperatorLoc,FPOptionsOverride FPFeatures,ADLCallKind UsesADL)538e5dd7070Spatrick CXXOperatorCallExpr::CXXOperatorCallExpr(OverloadedOperatorKind OpKind,
539e5dd7070Spatrick                                          Expr *Fn, ArrayRef<Expr *> Args,
540e5dd7070Spatrick                                          QualType Ty, ExprValueKind VK,
541e5dd7070Spatrick                                          SourceLocation OperatorLoc,
542ec727ea7Spatrick                                          FPOptionsOverride FPFeatures,
543e5dd7070Spatrick                                          ADLCallKind UsesADL)
544e5dd7070Spatrick     : CallExpr(CXXOperatorCallExprClass, Fn, /*PreArgs=*/{}, Args, Ty, VK,
545a9ac8606Spatrick                OperatorLoc, FPFeatures, /*MinNumArgs=*/0, UsesADL) {
546e5dd7070Spatrick   CXXOperatorCallExprBits.OperatorKind = OpKind;
547e5dd7070Spatrick   assert(
548e5dd7070Spatrick       (CXXOperatorCallExprBits.OperatorKind == static_cast<unsigned>(OpKind)) &&
549e5dd7070Spatrick       "OperatorKind overflow!");
550e5dd7070Spatrick   Range = getSourceRangeImpl();
551e5dd7070Spatrick }
552e5dd7070Spatrick 
CXXOperatorCallExpr(unsigned NumArgs,bool HasFPFeatures,EmptyShell Empty)553a9ac8606Spatrick CXXOperatorCallExpr::CXXOperatorCallExpr(unsigned NumArgs, bool HasFPFeatures,
554a9ac8606Spatrick                                          EmptyShell Empty)
555a9ac8606Spatrick     : CallExpr(CXXOperatorCallExprClass, /*NumPreArgs=*/0, NumArgs,
556a9ac8606Spatrick                HasFPFeatures, Empty) {}
557e5dd7070Spatrick 
558ec727ea7Spatrick CXXOperatorCallExpr *
Create(const ASTContext & Ctx,OverloadedOperatorKind OpKind,Expr * Fn,ArrayRef<Expr * > Args,QualType Ty,ExprValueKind VK,SourceLocation OperatorLoc,FPOptionsOverride FPFeatures,ADLCallKind UsesADL)559ec727ea7Spatrick CXXOperatorCallExpr::Create(const ASTContext &Ctx,
560ec727ea7Spatrick                             OverloadedOperatorKind OpKind, Expr *Fn,
561ec727ea7Spatrick                             ArrayRef<Expr *> Args, QualType Ty,
562ec727ea7Spatrick                             ExprValueKind VK, SourceLocation OperatorLoc,
563ec727ea7Spatrick                             FPOptionsOverride FPFeatures, ADLCallKind UsesADL) {
564e5dd7070Spatrick   // Allocate storage for the trailing objects of CallExpr.
565e5dd7070Spatrick   unsigned NumArgs = Args.size();
566a9ac8606Spatrick   unsigned SizeOfTrailingObjects = CallExpr::sizeOfTrailingObjects(
567a9ac8606Spatrick       /*NumPreArgs=*/0, NumArgs, FPFeatures.requiresTrailingStorage());
568e5dd7070Spatrick   void *Mem = Ctx.Allocate(sizeof(CXXOperatorCallExpr) + SizeOfTrailingObjects,
569e5dd7070Spatrick                            alignof(CXXOperatorCallExpr));
570e5dd7070Spatrick   return new (Mem) CXXOperatorCallExpr(OpKind, Fn, Args, Ty, VK, OperatorLoc,
571e5dd7070Spatrick                                        FPFeatures, UsesADL);
572e5dd7070Spatrick }
573e5dd7070Spatrick 
CreateEmpty(const ASTContext & Ctx,unsigned NumArgs,bool HasFPFeatures,EmptyShell Empty)574e5dd7070Spatrick CXXOperatorCallExpr *CXXOperatorCallExpr::CreateEmpty(const ASTContext &Ctx,
575e5dd7070Spatrick                                                       unsigned NumArgs,
576a9ac8606Spatrick                                                       bool HasFPFeatures,
577e5dd7070Spatrick                                                       EmptyShell Empty) {
578e5dd7070Spatrick   // Allocate storage for the trailing objects of CallExpr.
579e5dd7070Spatrick   unsigned SizeOfTrailingObjects =
580a9ac8606Spatrick       CallExpr::sizeOfTrailingObjects(/*NumPreArgs=*/0, NumArgs, HasFPFeatures);
581e5dd7070Spatrick   void *Mem = Ctx.Allocate(sizeof(CXXOperatorCallExpr) + SizeOfTrailingObjects,
582e5dd7070Spatrick                            alignof(CXXOperatorCallExpr));
583a9ac8606Spatrick   return new (Mem) CXXOperatorCallExpr(NumArgs, HasFPFeatures, Empty);
584e5dd7070Spatrick }
585e5dd7070Spatrick 
getSourceRangeImpl() const586e5dd7070Spatrick SourceRange CXXOperatorCallExpr::getSourceRangeImpl() const {
587e5dd7070Spatrick   OverloadedOperatorKind Kind = getOperator();
588e5dd7070Spatrick   if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) {
589e5dd7070Spatrick     if (getNumArgs() == 1)
590e5dd7070Spatrick       // Prefix operator
591e5dd7070Spatrick       return SourceRange(getOperatorLoc(), getArg(0)->getEndLoc());
592e5dd7070Spatrick     else
593e5dd7070Spatrick       // Postfix operator
594e5dd7070Spatrick       return SourceRange(getArg(0)->getBeginLoc(), getOperatorLoc());
595e5dd7070Spatrick   } else if (Kind == OO_Arrow) {
596ec727ea7Spatrick     return SourceRange(getArg(0)->getBeginLoc(), getOperatorLoc());
597e5dd7070Spatrick   } else if (Kind == OO_Call) {
598e5dd7070Spatrick     return SourceRange(getArg(0)->getBeginLoc(), getRParenLoc());
599e5dd7070Spatrick   } else if (Kind == OO_Subscript) {
600e5dd7070Spatrick     return SourceRange(getArg(0)->getBeginLoc(), getRParenLoc());
601e5dd7070Spatrick   } else if (getNumArgs() == 1) {
602e5dd7070Spatrick     return SourceRange(getOperatorLoc(), getArg(0)->getEndLoc());
603e5dd7070Spatrick   } else if (getNumArgs() == 2) {
604e5dd7070Spatrick     return SourceRange(getArg(0)->getBeginLoc(), getArg(1)->getEndLoc());
605e5dd7070Spatrick   } else {
606e5dd7070Spatrick     return getOperatorLoc();
607e5dd7070Spatrick   }
608e5dd7070Spatrick }
609e5dd7070Spatrick 
CXXMemberCallExpr(Expr * Fn,ArrayRef<Expr * > Args,QualType Ty,ExprValueKind VK,SourceLocation RP,FPOptionsOverride FPOptions,unsigned MinNumArgs)610e5dd7070Spatrick CXXMemberCallExpr::CXXMemberCallExpr(Expr *Fn, ArrayRef<Expr *> Args,
611e5dd7070Spatrick                                      QualType Ty, ExprValueKind VK,
612a9ac8606Spatrick                                      SourceLocation RP,
613a9ac8606Spatrick                                      FPOptionsOverride FPOptions,
614a9ac8606Spatrick                                      unsigned MinNumArgs)
615e5dd7070Spatrick     : CallExpr(CXXMemberCallExprClass, Fn, /*PreArgs=*/{}, Args, Ty, VK, RP,
616a9ac8606Spatrick                FPOptions, MinNumArgs, NotADL) {}
617e5dd7070Spatrick 
CXXMemberCallExpr(unsigned NumArgs,bool HasFPFeatures,EmptyShell Empty)618a9ac8606Spatrick CXXMemberCallExpr::CXXMemberCallExpr(unsigned NumArgs, bool HasFPFeatures,
619a9ac8606Spatrick                                      EmptyShell Empty)
620a9ac8606Spatrick     : CallExpr(CXXMemberCallExprClass, /*NumPreArgs=*/0, NumArgs, HasFPFeatures,
621a9ac8606Spatrick                Empty) {}
622e5dd7070Spatrick 
Create(const ASTContext & Ctx,Expr * Fn,ArrayRef<Expr * > Args,QualType Ty,ExprValueKind VK,SourceLocation RP,FPOptionsOverride FPFeatures,unsigned MinNumArgs)623e5dd7070Spatrick CXXMemberCallExpr *CXXMemberCallExpr::Create(const ASTContext &Ctx, Expr *Fn,
624e5dd7070Spatrick                                              ArrayRef<Expr *> Args, QualType Ty,
625e5dd7070Spatrick                                              ExprValueKind VK,
626e5dd7070Spatrick                                              SourceLocation RP,
627a9ac8606Spatrick                                              FPOptionsOverride FPFeatures,
628e5dd7070Spatrick                                              unsigned MinNumArgs) {
629e5dd7070Spatrick   // Allocate storage for the trailing objects of CallExpr.
630e5dd7070Spatrick   unsigned NumArgs = std::max<unsigned>(Args.size(), MinNumArgs);
631a9ac8606Spatrick   unsigned SizeOfTrailingObjects = CallExpr::sizeOfTrailingObjects(
632a9ac8606Spatrick       /*NumPreArgs=*/0, NumArgs, FPFeatures.requiresTrailingStorage());
633e5dd7070Spatrick   void *Mem = Ctx.Allocate(sizeof(CXXMemberCallExpr) + SizeOfTrailingObjects,
634e5dd7070Spatrick                            alignof(CXXMemberCallExpr));
635a9ac8606Spatrick   return new (Mem)
636a9ac8606Spatrick       CXXMemberCallExpr(Fn, Args, Ty, VK, RP, FPFeatures, MinNumArgs);
637e5dd7070Spatrick }
638e5dd7070Spatrick 
CreateEmpty(const ASTContext & Ctx,unsigned NumArgs,bool HasFPFeatures,EmptyShell Empty)639e5dd7070Spatrick CXXMemberCallExpr *CXXMemberCallExpr::CreateEmpty(const ASTContext &Ctx,
640e5dd7070Spatrick                                                   unsigned NumArgs,
641a9ac8606Spatrick                                                   bool HasFPFeatures,
642e5dd7070Spatrick                                                   EmptyShell Empty) {
643e5dd7070Spatrick   // Allocate storage for the trailing objects of CallExpr.
644e5dd7070Spatrick   unsigned SizeOfTrailingObjects =
645a9ac8606Spatrick       CallExpr::sizeOfTrailingObjects(/*NumPreArgs=*/0, NumArgs, HasFPFeatures);
646e5dd7070Spatrick   void *Mem = Ctx.Allocate(sizeof(CXXMemberCallExpr) + SizeOfTrailingObjects,
647e5dd7070Spatrick                            alignof(CXXMemberCallExpr));
648a9ac8606Spatrick   return new (Mem) CXXMemberCallExpr(NumArgs, HasFPFeatures, Empty);
649e5dd7070Spatrick }
650e5dd7070Spatrick 
getImplicitObjectArgument() const651e5dd7070Spatrick Expr *CXXMemberCallExpr::getImplicitObjectArgument() const {
652e5dd7070Spatrick   const Expr *Callee = getCallee()->IgnoreParens();
653e5dd7070Spatrick   if (const auto *MemExpr = dyn_cast<MemberExpr>(Callee))
654e5dd7070Spatrick     return MemExpr->getBase();
655e5dd7070Spatrick   if (const auto *BO = dyn_cast<BinaryOperator>(Callee))
656e5dd7070Spatrick     if (BO->getOpcode() == BO_PtrMemD || BO->getOpcode() == BO_PtrMemI)
657e5dd7070Spatrick       return BO->getLHS();
658e5dd7070Spatrick 
659e5dd7070Spatrick   // FIXME: Will eventually need to cope with member pointers.
660e5dd7070Spatrick   return nullptr;
661e5dd7070Spatrick }
662e5dd7070Spatrick 
getObjectType() const663e5dd7070Spatrick QualType CXXMemberCallExpr::getObjectType() const {
664e5dd7070Spatrick   QualType Ty = getImplicitObjectArgument()->getType();
665e5dd7070Spatrick   if (Ty->isPointerType())
666e5dd7070Spatrick     Ty = Ty->getPointeeType();
667e5dd7070Spatrick   return Ty;
668e5dd7070Spatrick }
669e5dd7070Spatrick 
getMethodDecl() const670e5dd7070Spatrick CXXMethodDecl *CXXMemberCallExpr::getMethodDecl() const {
671e5dd7070Spatrick   if (const auto *MemExpr = dyn_cast<MemberExpr>(getCallee()->IgnoreParens()))
672e5dd7070Spatrick     return cast<CXXMethodDecl>(MemExpr->getMemberDecl());
673e5dd7070Spatrick 
674e5dd7070Spatrick   // FIXME: Will eventually need to cope with member pointers.
675a9ac8606Spatrick   // NOTE: Update makeTailCallIfSwiftAsync on fixing this.
676e5dd7070Spatrick   return nullptr;
677e5dd7070Spatrick }
678e5dd7070Spatrick 
getRecordDecl() const679e5dd7070Spatrick CXXRecordDecl *CXXMemberCallExpr::getRecordDecl() const {
680e5dd7070Spatrick   Expr* ThisArg = getImplicitObjectArgument();
681e5dd7070Spatrick   if (!ThisArg)
682e5dd7070Spatrick     return nullptr;
683e5dd7070Spatrick 
684e5dd7070Spatrick   if (ThisArg->getType()->isAnyPointerType())
685e5dd7070Spatrick     return ThisArg->getType()->getPointeeType()->getAsCXXRecordDecl();
686e5dd7070Spatrick 
687e5dd7070Spatrick   return ThisArg->getType()->getAsCXXRecordDecl();
688e5dd7070Spatrick }
689e5dd7070Spatrick 
690e5dd7070Spatrick //===----------------------------------------------------------------------===//
691e5dd7070Spatrick //  Named casts
692e5dd7070Spatrick //===----------------------------------------------------------------------===//
693e5dd7070Spatrick 
694e5dd7070Spatrick /// getCastName - Get the name of the C++ cast being used, e.g.,
695e5dd7070Spatrick /// "static_cast", "dynamic_cast", "reinterpret_cast", or
696e5dd7070Spatrick /// "const_cast". The returned pointer must not be freed.
getCastName() const697e5dd7070Spatrick const char *CXXNamedCastExpr::getCastName() const {
698e5dd7070Spatrick   switch (getStmtClass()) {
699e5dd7070Spatrick   case CXXStaticCastExprClass:      return "static_cast";
700e5dd7070Spatrick   case CXXDynamicCastExprClass:     return "dynamic_cast";
701e5dd7070Spatrick   case CXXReinterpretCastExprClass: return "reinterpret_cast";
702e5dd7070Spatrick   case CXXConstCastExprClass:       return "const_cast";
703ec727ea7Spatrick   case CXXAddrspaceCastExprClass:   return "addrspace_cast";
704e5dd7070Spatrick   default:                          return "<invalid cast>";
705e5dd7070Spatrick   }
706e5dd7070Spatrick }
707e5dd7070Spatrick 
708a9ac8606Spatrick CXXStaticCastExpr *
Create(const ASTContext & C,QualType T,ExprValueKind VK,CastKind K,Expr * Op,const CXXCastPath * BasePath,TypeSourceInfo * WrittenTy,FPOptionsOverride FPO,SourceLocation L,SourceLocation RParenLoc,SourceRange AngleBrackets)709a9ac8606Spatrick CXXStaticCastExpr::Create(const ASTContext &C, QualType T, ExprValueKind VK,
710a9ac8606Spatrick                           CastKind K, Expr *Op, const CXXCastPath *BasePath,
711a9ac8606Spatrick                           TypeSourceInfo *WrittenTy, FPOptionsOverride FPO,
712a9ac8606Spatrick                           SourceLocation L, SourceLocation RParenLoc,
713e5dd7070Spatrick                           SourceRange AngleBrackets) {
714e5dd7070Spatrick   unsigned PathSize = (BasePath ? BasePath->size() : 0);
715a9ac8606Spatrick   void *Buffer =
716a9ac8606Spatrick       C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *, FPOptionsOverride>(
717a9ac8606Spatrick           PathSize, FPO.requiresTrailingStorage()));
718a9ac8606Spatrick   auto *E = new (Buffer) CXXStaticCastExpr(T, VK, K, Op, PathSize, WrittenTy,
719a9ac8606Spatrick                                            FPO, L, RParenLoc, AngleBrackets);
720e5dd7070Spatrick   if (PathSize)
721e5dd7070Spatrick     std::uninitialized_copy_n(BasePath->data(), BasePath->size(),
722e5dd7070Spatrick                               E->getTrailingObjects<CXXBaseSpecifier *>());
723e5dd7070Spatrick   return E;
724e5dd7070Spatrick }
725e5dd7070Spatrick 
CreateEmpty(const ASTContext & C,unsigned PathSize,bool HasFPFeatures)726e5dd7070Spatrick CXXStaticCastExpr *CXXStaticCastExpr::CreateEmpty(const ASTContext &C,
727a9ac8606Spatrick                                                   unsigned PathSize,
728a9ac8606Spatrick                                                   bool HasFPFeatures) {
729a9ac8606Spatrick   void *Buffer =
730a9ac8606Spatrick       C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *, FPOptionsOverride>(
731a9ac8606Spatrick           PathSize, HasFPFeatures));
732a9ac8606Spatrick   return new (Buffer) CXXStaticCastExpr(EmptyShell(), PathSize, HasFPFeatures);
733e5dd7070Spatrick }
734e5dd7070Spatrick 
Create(const ASTContext & C,QualType T,ExprValueKind VK,CastKind K,Expr * Op,const CXXCastPath * BasePath,TypeSourceInfo * WrittenTy,SourceLocation L,SourceLocation RParenLoc,SourceRange AngleBrackets)735e5dd7070Spatrick CXXDynamicCastExpr *CXXDynamicCastExpr::Create(const ASTContext &C, QualType T,
736e5dd7070Spatrick                                                ExprValueKind VK,
737e5dd7070Spatrick                                                CastKind K, Expr *Op,
738e5dd7070Spatrick                                                const CXXCastPath *BasePath,
739e5dd7070Spatrick                                                TypeSourceInfo *WrittenTy,
740e5dd7070Spatrick                                                SourceLocation L,
741e5dd7070Spatrick                                                SourceLocation RParenLoc,
742e5dd7070Spatrick                                                SourceRange AngleBrackets) {
743e5dd7070Spatrick   unsigned PathSize = (BasePath ? BasePath->size() : 0);
744e5dd7070Spatrick   void *Buffer = C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *>(PathSize));
745e5dd7070Spatrick   auto *E =
746e5dd7070Spatrick       new (Buffer) CXXDynamicCastExpr(T, VK, K, Op, PathSize, WrittenTy, L,
747e5dd7070Spatrick                                       RParenLoc, AngleBrackets);
748e5dd7070Spatrick   if (PathSize)
749e5dd7070Spatrick     std::uninitialized_copy_n(BasePath->data(), BasePath->size(),
750e5dd7070Spatrick                               E->getTrailingObjects<CXXBaseSpecifier *>());
751e5dd7070Spatrick   return E;
752e5dd7070Spatrick }
753e5dd7070Spatrick 
CreateEmpty(const ASTContext & C,unsigned PathSize)754e5dd7070Spatrick CXXDynamicCastExpr *CXXDynamicCastExpr::CreateEmpty(const ASTContext &C,
755e5dd7070Spatrick                                                     unsigned PathSize) {
756e5dd7070Spatrick   void *Buffer = C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *>(PathSize));
757e5dd7070Spatrick   return new (Buffer) CXXDynamicCastExpr(EmptyShell(), PathSize);
758e5dd7070Spatrick }
759e5dd7070Spatrick 
760e5dd7070Spatrick /// isAlwaysNull - Return whether the result of the dynamic_cast is proven
761e5dd7070Spatrick /// to always be null. For example:
762e5dd7070Spatrick ///
763e5dd7070Spatrick /// struct A { };
764e5dd7070Spatrick /// struct B final : A { };
765e5dd7070Spatrick /// struct C { };
766e5dd7070Spatrick ///
767e5dd7070Spatrick /// C *f(B* b) { return dynamic_cast<C*>(b); }
isAlwaysNull() const768e5dd7070Spatrick bool CXXDynamicCastExpr::isAlwaysNull() const
769e5dd7070Spatrick {
770e5dd7070Spatrick   QualType SrcType = getSubExpr()->getType();
771e5dd7070Spatrick   QualType DestType = getType();
772e5dd7070Spatrick 
773e5dd7070Spatrick   if (const auto *SrcPTy = SrcType->getAs<PointerType>()) {
774e5dd7070Spatrick     SrcType = SrcPTy->getPointeeType();
775e5dd7070Spatrick     DestType = DestType->castAs<PointerType>()->getPointeeType();
776e5dd7070Spatrick   }
777e5dd7070Spatrick 
778e5dd7070Spatrick   if (DestType->isVoidType())
779e5dd7070Spatrick     return false;
780e5dd7070Spatrick 
781e5dd7070Spatrick   const auto *SrcRD =
782e5dd7070Spatrick       cast<CXXRecordDecl>(SrcType->castAs<RecordType>()->getDecl());
783e5dd7070Spatrick 
784e5dd7070Spatrick   if (!SrcRD->hasAttr<FinalAttr>())
785e5dd7070Spatrick     return false;
786e5dd7070Spatrick 
787e5dd7070Spatrick   const auto *DestRD =
788e5dd7070Spatrick       cast<CXXRecordDecl>(DestType->castAs<RecordType>()->getDecl());
789e5dd7070Spatrick 
790e5dd7070Spatrick   return !DestRD->isDerivedFrom(SrcRD);
791e5dd7070Spatrick }
792e5dd7070Spatrick 
793e5dd7070Spatrick CXXReinterpretCastExpr *
Create(const ASTContext & C,QualType T,ExprValueKind VK,CastKind K,Expr * Op,const CXXCastPath * BasePath,TypeSourceInfo * WrittenTy,SourceLocation L,SourceLocation RParenLoc,SourceRange AngleBrackets)794e5dd7070Spatrick CXXReinterpretCastExpr::Create(const ASTContext &C, QualType T,
795e5dd7070Spatrick                                ExprValueKind VK, CastKind K, Expr *Op,
796e5dd7070Spatrick                                const CXXCastPath *BasePath,
797e5dd7070Spatrick                                TypeSourceInfo *WrittenTy, SourceLocation L,
798e5dd7070Spatrick                                SourceLocation RParenLoc,
799e5dd7070Spatrick                                SourceRange AngleBrackets) {
800e5dd7070Spatrick   unsigned PathSize = (BasePath ? BasePath->size() : 0);
801e5dd7070Spatrick   void *Buffer = C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *>(PathSize));
802e5dd7070Spatrick   auto *E =
803e5dd7070Spatrick       new (Buffer) CXXReinterpretCastExpr(T, VK, K, Op, PathSize, WrittenTy, L,
804e5dd7070Spatrick                                           RParenLoc, AngleBrackets);
805e5dd7070Spatrick   if (PathSize)
806e5dd7070Spatrick     std::uninitialized_copy_n(BasePath->data(), BasePath->size(),
807e5dd7070Spatrick                               E->getTrailingObjects<CXXBaseSpecifier *>());
808e5dd7070Spatrick   return E;
809e5dd7070Spatrick }
810e5dd7070Spatrick 
811e5dd7070Spatrick CXXReinterpretCastExpr *
CreateEmpty(const ASTContext & C,unsigned PathSize)812e5dd7070Spatrick CXXReinterpretCastExpr::CreateEmpty(const ASTContext &C, unsigned PathSize) {
813e5dd7070Spatrick   void *Buffer = C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *>(PathSize));
814e5dd7070Spatrick   return new (Buffer) CXXReinterpretCastExpr(EmptyShell(), PathSize);
815e5dd7070Spatrick }
816e5dd7070Spatrick 
Create(const ASTContext & C,QualType T,ExprValueKind VK,Expr * Op,TypeSourceInfo * WrittenTy,SourceLocation L,SourceLocation RParenLoc,SourceRange AngleBrackets)817e5dd7070Spatrick CXXConstCastExpr *CXXConstCastExpr::Create(const ASTContext &C, QualType T,
818e5dd7070Spatrick                                            ExprValueKind VK, Expr *Op,
819e5dd7070Spatrick                                            TypeSourceInfo *WrittenTy,
820e5dd7070Spatrick                                            SourceLocation L,
821e5dd7070Spatrick                                            SourceLocation RParenLoc,
822e5dd7070Spatrick                                            SourceRange AngleBrackets) {
823e5dd7070Spatrick   return new (C) CXXConstCastExpr(T, VK, Op, WrittenTy, L, RParenLoc, AngleBrackets);
824e5dd7070Spatrick }
825e5dd7070Spatrick 
CreateEmpty(const ASTContext & C)826e5dd7070Spatrick CXXConstCastExpr *CXXConstCastExpr::CreateEmpty(const ASTContext &C) {
827e5dd7070Spatrick   return new (C) CXXConstCastExpr(EmptyShell());
828e5dd7070Spatrick }
829e5dd7070Spatrick 
830ec727ea7Spatrick CXXAddrspaceCastExpr *
Create(const ASTContext & C,QualType T,ExprValueKind VK,CastKind K,Expr * Op,TypeSourceInfo * WrittenTy,SourceLocation L,SourceLocation RParenLoc,SourceRange AngleBrackets)831ec727ea7Spatrick CXXAddrspaceCastExpr::Create(const ASTContext &C, QualType T, ExprValueKind VK,
832ec727ea7Spatrick                              CastKind K, Expr *Op, TypeSourceInfo *WrittenTy,
833ec727ea7Spatrick                              SourceLocation L, SourceLocation RParenLoc,
834ec727ea7Spatrick                              SourceRange AngleBrackets) {
835ec727ea7Spatrick   return new (C) CXXAddrspaceCastExpr(T, VK, K, Op, WrittenTy, L, RParenLoc,
836ec727ea7Spatrick                                       AngleBrackets);
837ec727ea7Spatrick }
838ec727ea7Spatrick 
CreateEmpty(const ASTContext & C)839ec727ea7Spatrick CXXAddrspaceCastExpr *CXXAddrspaceCastExpr::CreateEmpty(const ASTContext &C) {
840ec727ea7Spatrick   return new (C) CXXAddrspaceCastExpr(EmptyShell());
841ec727ea7Spatrick }
842ec727ea7Spatrick 
Create(const ASTContext & C,QualType T,ExprValueKind VK,TypeSourceInfo * Written,CastKind K,Expr * Op,const CXXCastPath * BasePath,FPOptionsOverride FPO,SourceLocation L,SourceLocation R)843a9ac8606Spatrick CXXFunctionalCastExpr *CXXFunctionalCastExpr::Create(
844a9ac8606Spatrick     const ASTContext &C, QualType T, ExprValueKind VK, TypeSourceInfo *Written,
845a9ac8606Spatrick     CastKind K, Expr *Op, const CXXCastPath *BasePath, FPOptionsOverride FPO,
846e5dd7070Spatrick     SourceLocation L, SourceLocation R) {
847e5dd7070Spatrick   unsigned PathSize = (BasePath ? BasePath->size() : 0);
848a9ac8606Spatrick   void *Buffer =
849a9ac8606Spatrick       C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *, FPOptionsOverride>(
850a9ac8606Spatrick           PathSize, FPO.requiresTrailingStorage()));
851a9ac8606Spatrick   auto *E = new (Buffer)
852a9ac8606Spatrick       CXXFunctionalCastExpr(T, VK, Written, K, Op, PathSize, FPO, L, R);
853e5dd7070Spatrick   if (PathSize)
854e5dd7070Spatrick     std::uninitialized_copy_n(BasePath->data(), BasePath->size(),
855e5dd7070Spatrick                               E->getTrailingObjects<CXXBaseSpecifier *>());
856e5dd7070Spatrick   return E;
857e5dd7070Spatrick }
858e5dd7070Spatrick 
CreateEmpty(const ASTContext & C,unsigned PathSize,bool HasFPFeatures)859a9ac8606Spatrick CXXFunctionalCastExpr *CXXFunctionalCastExpr::CreateEmpty(const ASTContext &C,
860a9ac8606Spatrick                                                           unsigned PathSize,
861a9ac8606Spatrick                                                           bool HasFPFeatures) {
862a9ac8606Spatrick   void *Buffer =
863a9ac8606Spatrick       C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *, FPOptionsOverride>(
864a9ac8606Spatrick           PathSize, HasFPFeatures));
865a9ac8606Spatrick   return new (Buffer)
866a9ac8606Spatrick       CXXFunctionalCastExpr(EmptyShell(), PathSize, HasFPFeatures);
867e5dd7070Spatrick }
868e5dd7070Spatrick 
getBeginLoc() const869e5dd7070Spatrick SourceLocation CXXFunctionalCastExpr::getBeginLoc() const {
870e5dd7070Spatrick   return getTypeInfoAsWritten()->getTypeLoc().getBeginLoc();
871e5dd7070Spatrick }
872e5dd7070Spatrick 
getEndLoc() const873e5dd7070Spatrick SourceLocation CXXFunctionalCastExpr::getEndLoc() const {
874e5dd7070Spatrick   return RParenLoc.isValid() ? RParenLoc : getSubExpr()->getEndLoc();
875e5dd7070Spatrick }
876e5dd7070Spatrick 
UserDefinedLiteral(Expr * Fn,ArrayRef<Expr * > Args,QualType Ty,ExprValueKind VK,SourceLocation LitEndLoc,SourceLocation SuffixLoc,FPOptionsOverride FPFeatures)877e5dd7070Spatrick UserDefinedLiteral::UserDefinedLiteral(Expr *Fn, ArrayRef<Expr *> Args,
878e5dd7070Spatrick                                        QualType Ty, ExprValueKind VK,
879e5dd7070Spatrick                                        SourceLocation LitEndLoc,
880a9ac8606Spatrick                                        SourceLocation SuffixLoc,
881a9ac8606Spatrick                                        FPOptionsOverride FPFeatures)
882e5dd7070Spatrick     : CallExpr(UserDefinedLiteralClass, Fn, /*PreArgs=*/{}, Args, Ty, VK,
883a9ac8606Spatrick                LitEndLoc, FPFeatures, /*MinNumArgs=*/0, NotADL),
884e5dd7070Spatrick       UDSuffixLoc(SuffixLoc) {}
885e5dd7070Spatrick 
UserDefinedLiteral(unsigned NumArgs,bool HasFPFeatures,EmptyShell Empty)886a9ac8606Spatrick UserDefinedLiteral::UserDefinedLiteral(unsigned NumArgs, bool HasFPFeatures,
887a9ac8606Spatrick                                        EmptyShell Empty)
888a9ac8606Spatrick     : CallExpr(UserDefinedLiteralClass, /*NumPreArgs=*/0, NumArgs,
889a9ac8606Spatrick                HasFPFeatures, Empty) {}
890e5dd7070Spatrick 
Create(const ASTContext & Ctx,Expr * Fn,ArrayRef<Expr * > Args,QualType Ty,ExprValueKind VK,SourceLocation LitEndLoc,SourceLocation SuffixLoc,FPOptionsOverride FPFeatures)891e5dd7070Spatrick UserDefinedLiteral *UserDefinedLiteral::Create(const ASTContext &Ctx, Expr *Fn,
892e5dd7070Spatrick                                                ArrayRef<Expr *> Args,
893e5dd7070Spatrick                                                QualType Ty, ExprValueKind VK,
894e5dd7070Spatrick                                                SourceLocation LitEndLoc,
895a9ac8606Spatrick                                                SourceLocation SuffixLoc,
896a9ac8606Spatrick                                                FPOptionsOverride FPFeatures) {
897e5dd7070Spatrick   // Allocate storage for the trailing objects of CallExpr.
898e5dd7070Spatrick   unsigned NumArgs = Args.size();
899a9ac8606Spatrick   unsigned SizeOfTrailingObjects = CallExpr::sizeOfTrailingObjects(
900a9ac8606Spatrick       /*NumPreArgs=*/0, NumArgs, FPFeatures.requiresTrailingStorage());
901e5dd7070Spatrick   void *Mem = Ctx.Allocate(sizeof(UserDefinedLiteral) + SizeOfTrailingObjects,
902e5dd7070Spatrick                            alignof(UserDefinedLiteral));
903a9ac8606Spatrick   return new (Mem)
904a9ac8606Spatrick       UserDefinedLiteral(Fn, Args, Ty, VK, LitEndLoc, SuffixLoc, FPFeatures);
905e5dd7070Spatrick }
906e5dd7070Spatrick 
CreateEmpty(const ASTContext & Ctx,unsigned NumArgs,bool HasFPOptions,EmptyShell Empty)907e5dd7070Spatrick UserDefinedLiteral *UserDefinedLiteral::CreateEmpty(const ASTContext &Ctx,
908e5dd7070Spatrick                                                     unsigned NumArgs,
909a9ac8606Spatrick                                                     bool HasFPOptions,
910e5dd7070Spatrick                                                     EmptyShell Empty) {
911e5dd7070Spatrick   // Allocate storage for the trailing objects of CallExpr.
912e5dd7070Spatrick   unsigned SizeOfTrailingObjects =
913a9ac8606Spatrick       CallExpr::sizeOfTrailingObjects(/*NumPreArgs=*/0, NumArgs, HasFPOptions);
914e5dd7070Spatrick   void *Mem = Ctx.Allocate(sizeof(UserDefinedLiteral) + SizeOfTrailingObjects,
915e5dd7070Spatrick                            alignof(UserDefinedLiteral));
916a9ac8606Spatrick   return new (Mem) UserDefinedLiteral(NumArgs, HasFPOptions, Empty);
917e5dd7070Spatrick }
918e5dd7070Spatrick 
919e5dd7070Spatrick UserDefinedLiteral::LiteralOperatorKind
getLiteralOperatorKind() const920e5dd7070Spatrick UserDefinedLiteral::getLiteralOperatorKind() const {
921e5dd7070Spatrick   if (getNumArgs() == 0)
922e5dd7070Spatrick     return LOK_Template;
923e5dd7070Spatrick   if (getNumArgs() == 2)
924e5dd7070Spatrick     return LOK_String;
925e5dd7070Spatrick 
926e5dd7070Spatrick   assert(getNumArgs() == 1 && "unexpected #args in literal operator call");
927e5dd7070Spatrick   QualType ParamTy =
928e5dd7070Spatrick     cast<FunctionDecl>(getCalleeDecl())->getParamDecl(0)->getType();
929e5dd7070Spatrick   if (ParamTy->isPointerType())
930e5dd7070Spatrick     return LOK_Raw;
931e5dd7070Spatrick   if (ParamTy->isAnyCharacterType())
932e5dd7070Spatrick     return LOK_Character;
933e5dd7070Spatrick   if (ParamTy->isIntegerType())
934e5dd7070Spatrick     return LOK_Integer;
935e5dd7070Spatrick   if (ParamTy->isFloatingType())
936e5dd7070Spatrick     return LOK_Floating;
937e5dd7070Spatrick 
938e5dd7070Spatrick   llvm_unreachable("unknown kind of literal operator");
939e5dd7070Spatrick }
940e5dd7070Spatrick 
getCookedLiteral()941e5dd7070Spatrick Expr *UserDefinedLiteral::getCookedLiteral() {
942e5dd7070Spatrick #ifndef NDEBUG
943e5dd7070Spatrick   LiteralOperatorKind LOK = getLiteralOperatorKind();
944e5dd7070Spatrick   assert(LOK != LOK_Template && LOK != LOK_Raw && "not a cooked literal");
945e5dd7070Spatrick #endif
946e5dd7070Spatrick   return getArg(0);
947e5dd7070Spatrick }
948e5dd7070Spatrick 
getUDSuffix() const949e5dd7070Spatrick const IdentifierInfo *UserDefinedLiteral::getUDSuffix() const {
950e5dd7070Spatrick   return cast<FunctionDecl>(getCalleeDecl())->getLiteralIdentifier();
951e5dd7070Spatrick }
952e5dd7070Spatrick 
CreateEmpty(const ASTContext & C,bool HasRewrittenInit)953*12c85518Srobert CXXDefaultArgExpr *CXXDefaultArgExpr::CreateEmpty(const ASTContext &C,
954*12c85518Srobert                                                   bool HasRewrittenInit) {
955*12c85518Srobert   size_t Size = totalSizeToAlloc<Expr *>(HasRewrittenInit);
956*12c85518Srobert   auto *Mem = C.Allocate(Size, alignof(CXXDefaultArgExpr));
957*12c85518Srobert   return new (Mem) CXXDefaultArgExpr(EmptyShell(), HasRewrittenInit);
958*12c85518Srobert }
959*12c85518Srobert 
Create(const ASTContext & C,SourceLocation Loc,ParmVarDecl * Param,Expr * RewrittenExpr,DeclContext * UsedContext)960*12c85518Srobert CXXDefaultArgExpr *CXXDefaultArgExpr::Create(const ASTContext &C,
961*12c85518Srobert                                              SourceLocation Loc,
962*12c85518Srobert                                              ParmVarDecl *Param,
963*12c85518Srobert                                              Expr *RewrittenExpr,
964*12c85518Srobert                                              DeclContext *UsedContext) {
965*12c85518Srobert   size_t Size = totalSizeToAlloc<Expr *>(RewrittenExpr != nullptr);
966*12c85518Srobert   auto *Mem = C.Allocate(Size, alignof(CXXDefaultArgExpr));
967*12c85518Srobert   return new (Mem) CXXDefaultArgExpr(CXXDefaultArgExprClass, Loc, Param,
968*12c85518Srobert                                      RewrittenExpr, UsedContext);
969*12c85518Srobert }
970*12c85518Srobert 
getExpr()971*12c85518Srobert Expr *CXXDefaultArgExpr::getExpr() {
972*12c85518Srobert   return CXXDefaultArgExprBits.HasRewrittenInit ? getAdjustedRewrittenExpr()
973*12c85518Srobert                                                 : getParam()->getDefaultArg();
974*12c85518Srobert }
975*12c85518Srobert 
getAdjustedRewrittenExpr()976*12c85518Srobert Expr *CXXDefaultArgExpr::getAdjustedRewrittenExpr() {
977*12c85518Srobert   assert(hasRewrittenInit() &&
978*12c85518Srobert          "expected this CXXDefaultArgExpr to have a rewritten init.");
979*12c85518Srobert   Expr *Init = getRewrittenExpr();
980*12c85518Srobert   if (auto *E = dyn_cast_if_present<FullExpr>(Init))
981*12c85518Srobert     if (!isa<ConstantExpr>(E))
982*12c85518Srobert       return E->getSubExpr();
983*12c85518Srobert   return Init;
984*12c85518Srobert }
985*12c85518Srobert 
CXXDefaultInitExpr(const ASTContext & Ctx,SourceLocation Loc,FieldDecl * Field,QualType Ty,DeclContext * UsedContext,Expr * RewrittenInitExpr)986ec727ea7Spatrick CXXDefaultInitExpr::CXXDefaultInitExpr(const ASTContext &Ctx,
987ec727ea7Spatrick                                        SourceLocation Loc, FieldDecl *Field,
988*12c85518Srobert                                        QualType Ty, DeclContext *UsedContext,
989*12c85518Srobert                                        Expr *RewrittenInitExpr)
990e5dd7070Spatrick     : Expr(CXXDefaultInitExprClass, Ty.getNonLValueExprType(Ctx),
991a9ac8606Spatrick            Ty->isLValueReferenceType()   ? VK_LValue
992a9ac8606Spatrick            : Ty->isRValueReferenceType() ? VK_XValue
993a9ac8606Spatrick                                          : VK_PRValue,
994ec727ea7Spatrick            /*FIXME*/ OK_Ordinary),
995e5dd7070Spatrick       Field(Field), UsedContext(UsedContext) {
996e5dd7070Spatrick   CXXDefaultInitExprBits.Loc = Loc;
997*12c85518Srobert   CXXDefaultInitExprBits.HasRewrittenInit = RewrittenInitExpr != nullptr;
998*12c85518Srobert 
999*12c85518Srobert   if (CXXDefaultInitExprBits.HasRewrittenInit)
1000*12c85518Srobert     *getTrailingObjects<Expr *>() = RewrittenInitExpr;
1001*12c85518Srobert 
1002e5dd7070Spatrick   assert(Field->hasInClassInitializer());
1003ec727ea7Spatrick 
1004a9ac8606Spatrick   setDependence(computeDependence(this));
1005e5dd7070Spatrick }
1006e5dd7070Spatrick 
CreateEmpty(const ASTContext & C,bool HasRewrittenInit)1007*12c85518Srobert CXXDefaultInitExpr *CXXDefaultInitExpr::CreateEmpty(const ASTContext &C,
1008*12c85518Srobert                                                     bool HasRewrittenInit) {
1009*12c85518Srobert   size_t Size = totalSizeToAlloc<Expr *>(HasRewrittenInit);
1010*12c85518Srobert   auto *Mem = C.Allocate(Size, alignof(CXXDefaultInitExpr));
1011*12c85518Srobert   return new (Mem) CXXDefaultInitExpr(EmptyShell(), HasRewrittenInit);
1012*12c85518Srobert }
1013*12c85518Srobert 
Create(const ASTContext & Ctx,SourceLocation Loc,FieldDecl * Field,DeclContext * UsedContext,Expr * RewrittenInitExpr)1014*12c85518Srobert CXXDefaultInitExpr *CXXDefaultInitExpr::Create(const ASTContext &Ctx,
1015*12c85518Srobert                                                SourceLocation Loc,
1016*12c85518Srobert                                                FieldDecl *Field,
1017*12c85518Srobert                                                DeclContext *UsedContext,
1018*12c85518Srobert                                                Expr *RewrittenInitExpr) {
1019*12c85518Srobert 
1020*12c85518Srobert   size_t Size = totalSizeToAlloc<Expr *>(RewrittenInitExpr != nullptr);
1021*12c85518Srobert   auto *Mem = Ctx.Allocate(Size, alignof(CXXDefaultInitExpr));
1022*12c85518Srobert   return new (Mem) CXXDefaultInitExpr(Ctx, Loc, Field, Field->getType(),
1023*12c85518Srobert                                       UsedContext, RewrittenInitExpr);
1024*12c85518Srobert }
1025*12c85518Srobert 
getExpr()1026*12c85518Srobert Expr *CXXDefaultInitExpr::getExpr() {
1027*12c85518Srobert   assert(Field->getInClassInitializer() && "initializer hasn't been parsed");
1028*12c85518Srobert   if (hasRewrittenInit())
1029*12c85518Srobert     return getRewrittenExpr();
1030*12c85518Srobert 
1031*12c85518Srobert   return Field->getInClassInitializer();
1032*12c85518Srobert }
1033*12c85518Srobert 
Create(const ASTContext & C,const CXXDestructorDecl * Destructor)1034e5dd7070Spatrick CXXTemporary *CXXTemporary::Create(const ASTContext &C,
1035e5dd7070Spatrick                                    const CXXDestructorDecl *Destructor) {
1036e5dd7070Spatrick   return new (C) CXXTemporary(Destructor);
1037e5dd7070Spatrick }
1038e5dd7070Spatrick 
Create(const ASTContext & C,CXXTemporary * Temp,Expr * SubExpr)1039e5dd7070Spatrick CXXBindTemporaryExpr *CXXBindTemporaryExpr::Create(const ASTContext &C,
1040e5dd7070Spatrick                                                    CXXTemporary *Temp,
1041e5dd7070Spatrick                                                    Expr* SubExpr) {
1042e5dd7070Spatrick   assert((SubExpr->getType()->isRecordType() ||
1043e5dd7070Spatrick           SubExpr->getType()->isArrayType()) &&
1044e5dd7070Spatrick          "Expression bound to a temporary must have record or array type!");
1045e5dd7070Spatrick 
1046e5dd7070Spatrick   return new (C) CXXBindTemporaryExpr(Temp, SubExpr);
1047e5dd7070Spatrick }
1048e5dd7070Spatrick 
CXXTemporaryObjectExpr(CXXConstructorDecl * Cons,QualType Ty,TypeSourceInfo * TSI,ArrayRef<Expr * > Args,SourceRange ParenOrBraceRange,bool HadMultipleCandidates,bool ListInitialization,bool StdInitListInitialization,bool ZeroInitialization)1049e5dd7070Spatrick CXXTemporaryObjectExpr::CXXTemporaryObjectExpr(
1050e5dd7070Spatrick     CXXConstructorDecl *Cons, QualType Ty, TypeSourceInfo *TSI,
1051e5dd7070Spatrick     ArrayRef<Expr *> Args, SourceRange ParenOrBraceRange,
1052e5dd7070Spatrick     bool HadMultipleCandidates, bool ListInitialization,
1053e5dd7070Spatrick     bool StdInitListInitialization, bool ZeroInitialization)
1054e5dd7070Spatrick     : CXXConstructExpr(
1055e5dd7070Spatrick           CXXTemporaryObjectExprClass, Ty, TSI->getTypeLoc().getBeginLoc(),
1056e5dd7070Spatrick           Cons, /* Elidable=*/false, Args, HadMultipleCandidates,
1057e5dd7070Spatrick           ListInitialization, StdInitListInitialization, ZeroInitialization,
1058e5dd7070Spatrick           CXXConstructExpr::CK_Complete, ParenOrBraceRange),
1059*12c85518Srobert       TSI(TSI) {
1060*12c85518Srobert   setDependence(computeDependence(this));
1061*12c85518Srobert }
1062e5dd7070Spatrick 
CXXTemporaryObjectExpr(EmptyShell Empty,unsigned NumArgs)1063e5dd7070Spatrick CXXTemporaryObjectExpr::CXXTemporaryObjectExpr(EmptyShell Empty,
1064e5dd7070Spatrick                                                unsigned NumArgs)
1065e5dd7070Spatrick     : CXXConstructExpr(CXXTemporaryObjectExprClass, Empty, NumArgs) {}
1066e5dd7070Spatrick 
Create(const ASTContext & Ctx,CXXConstructorDecl * Cons,QualType Ty,TypeSourceInfo * TSI,ArrayRef<Expr * > Args,SourceRange ParenOrBraceRange,bool HadMultipleCandidates,bool ListInitialization,bool StdInitListInitialization,bool ZeroInitialization)1067e5dd7070Spatrick CXXTemporaryObjectExpr *CXXTemporaryObjectExpr::Create(
1068e5dd7070Spatrick     const ASTContext &Ctx, CXXConstructorDecl *Cons, QualType Ty,
1069e5dd7070Spatrick     TypeSourceInfo *TSI, ArrayRef<Expr *> Args, SourceRange ParenOrBraceRange,
1070e5dd7070Spatrick     bool HadMultipleCandidates, bool ListInitialization,
1071e5dd7070Spatrick     bool StdInitListInitialization, bool ZeroInitialization) {
1072e5dd7070Spatrick   unsigned SizeOfTrailingObjects = sizeOfTrailingObjects(Args.size());
1073e5dd7070Spatrick   void *Mem =
1074e5dd7070Spatrick       Ctx.Allocate(sizeof(CXXTemporaryObjectExpr) + SizeOfTrailingObjects,
1075e5dd7070Spatrick                    alignof(CXXTemporaryObjectExpr));
1076e5dd7070Spatrick   return new (Mem) CXXTemporaryObjectExpr(
1077e5dd7070Spatrick       Cons, Ty, TSI, Args, ParenOrBraceRange, HadMultipleCandidates,
1078e5dd7070Spatrick       ListInitialization, StdInitListInitialization, ZeroInitialization);
1079e5dd7070Spatrick }
1080e5dd7070Spatrick 
1081e5dd7070Spatrick CXXTemporaryObjectExpr *
CreateEmpty(const ASTContext & Ctx,unsigned NumArgs)1082e5dd7070Spatrick CXXTemporaryObjectExpr::CreateEmpty(const ASTContext &Ctx, unsigned NumArgs) {
1083e5dd7070Spatrick   unsigned SizeOfTrailingObjects = sizeOfTrailingObjects(NumArgs);
1084e5dd7070Spatrick   void *Mem =
1085e5dd7070Spatrick       Ctx.Allocate(sizeof(CXXTemporaryObjectExpr) + SizeOfTrailingObjects,
1086e5dd7070Spatrick                    alignof(CXXTemporaryObjectExpr));
1087e5dd7070Spatrick   return new (Mem) CXXTemporaryObjectExpr(EmptyShell(), NumArgs);
1088e5dd7070Spatrick }
1089e5dd7070Spatrick 
getBeginLoc() const1090e5dd7070Spatrick SourceLocation CXXTemporaryObjectExpr::getBeginLoc() const {
1091e5dd7070Spatrick   return getTypeSourceInfo()->getTypeLoc().getBeginLoc();
1092e5dd7070Spatrick }
1093e5dd7070Spatrick 
getEndLoc() const1094e5dd7070Spatrick SourceLocation CXXTemporaryObjectExpr::getEndLoc() const {
1095e5dd7070Spatrick   SourceLocation Loc = getParenOrBraceRange().getEnd();
1096e5dd7070Spatrick   if (Loc.isInvalid() && getNumArgs())
1097e5dd7070Spatrick     Loc = getArg(getNumArgs() - 1)->getEndLoc();
1098e5dd7070Spatrick   return Loc;
1099e5dd7070Spatrick }
1100e5dd7070Spatrick 
Create(const ASTContext & Ctx,QualType Ty,SourceLocation Loc,CXXConstructorDecl * Ctor,bool Elidable,ArrayRef<Expr * > Args,bool HadMultipleCandidates,bool ListInitialization,bool StdInitListInitialization,bool ZeroInitialization,ConstructionKind ConstructKind,SourceRange ParenOrBraceRange)1101e5dd7070Spatrick CXXConstructExpr *CXXConstructExpr::Create(
1102e5dd7070Spatrick     const ASTContext &Ctx, QualType Ty, SourceLocation Loc,
1103e5dd7070Spatrick     CXXConstructorDecl *Ctor, bool Elidable, ArrayRef<Expr *> Args,
1104e5dd7070Spatrick     bool HadMultipleCandidates, bool ListInitialization,
1105e5dd7070Spatrick     bool StdInitListInitialization, bool ZeroInitialization,
1106e5dd7070Spatrick     ConstructionKind ConstructKind, SourceRange ParenOrBraceRange) {
1107e5dd7070Spatrick   unsigned SizeOfTrailingObjects = sizeOfTrailingObjects(Args.size());
1108e5dd7070Spatrick   void *Mem = Ctx.Allocate(sizeof(CXXConstructExpr) + SizeOfTrailingObjects,
1109e5dd7070Spatrick                            alignof(CXXConstructExpr));
1110e5dd7070Spatrick   return new (Mem) CXXConstructExpr(
1111e5dd7070Spatrick       CXXConstructExprClass, Ty, Loc, Ctor, Elidable, Args,
1112e5dd7070Spatrick       HadMultipleCandidates, ListInitialization, StdInitListInitialization,
1113e5dd7070Spatrick       ZeroInitialization, ConstructKind, ParenOrBraceRange);
1114e5dd7070Spatrick }
1115e5dd7070Spatrick 
CreateEmpty(const ASTContext & Ctx,unsigned NumArgs)1116e5dd7070Spatrick CXXConstructExpr *CXXConstructExpr::CreateEmpty(const ASTContext &Ctx,
1117e5dd7070Spatrick                                                 unsigned NumArgs) {
1118e5dd7070Spatrick   unsigned SizeOfTrailingObjects = sizeOfTrailingObjects(NumArgs);
1119e5dd7070Spatrick   void *Mem = Ctx.Allocate(sizeof(CXXConstructExpr) + SizeOfTrailingObjects,
1120e5dd7070Spatrick                            alignof(CXXConstructExpr));
1121e5dd7070Spatrick   return new (Mem)
1122e5dd7070Spatrick       CXXConstructExpr(CXXConstructExprClass, EmptyShell(), NumArgs);
1123e5dd7070Spatrick }
1124e5dd7070Spatrick 
CXXConstructExpr(StmtClass SC,QualType Ty,SourceLocation Loc,CXXConstructorDecl * Ctor,bool Elidable,ArrayRef<Expr * > Args,bool HadMultipleCandidates,bool ListInitialization,bool StdInitListInitialization,bool ZeroInitialization,ConstructionKind ConstructKind,SourceRange ParenOrBraceRange)1125e5dd7070Spatrick CXXConstructExpr::CXXConstructExpr(
1126e5dd7070Spatrick     StmtClass SC, QualType Ty, SourceLocation Loc, CXXConstructorDecl *Ctor,
1127e5dd7070Spatrick     bool Elidable, ArrayRef<Expr *> Args, bool HadMultipleCandidates,
1128e5dd7070Spatrick     bool ListInitialization, bool StdInitListInitialization,
1129e5dd7070Spatrick     bool ZeroInitialization, ConstructionKind ConstructKind,
1130e5dd7070Spatrick     SourceRange ParenOrBraceRange)
1131a9ac8606Spatrick     : Expr(SC, Ty, VK_PRValue, OK_Ordinary), Constructor(Ctor),
1132ec727ea7Spatrick       ParenOrBraceRange(ParenOrBraceRange), NumArgs(Args.size()) {
1133e5dd7070Spatrick   CXXConstructExprBits.Elidable = Elidable;
1134e5dd7070Spatrick   CXXConstructExprBits.HadMultipleCandidates = HadMultipleCandidates;
1135e5dd7070Spatrick   CXXConstructExprBits.ListInitialization = ListInitialization;
1136e5dd7070Spatrick   CXXConstructExprBits.StdInitListInitialization = StdInitListInitialization;
1137e5dd7070Spatrick   CXXConstructExprBits.ZeroInitialization = ZeroInitialization;
1138e5dd7070Spatrick   CXXConstructExprBits.ConstructionKind = ConstructKind;
1139e5dd7070Spatrick   CXXConstructExprBits.Loc = Loc;
1140e5dd7070Spatrick 
1141e5dd7070Spatrick   Stmt **TrailingArgs = getTrailingArgs();
1142e5dd7070Spatrick   for (unsigned I = 0, N = Args.size(); I != N; ++I) {
1143e5dd7070Spatrick     assert(Args[I] && "NULL argument in CXXConstructExpr!");
1144e5dd7070Spatrick     TrailingArgs[I] = Args[I];
1145e5dd7070Spatrick   }
1146ec727ea7Spatrick 
1147*12c85518Srobert   // CXXTemporaryObjectExpr does this itself after setting its TypeSourceInfo.
1148*12c85518Srobert   if (SC == CXXConstructExprClass)
1149ec727ea7Spatrick     setDependence(computeDependence(this));
1150e5dd7070Spatrick }
1151e5dd7070Spatrick 
CXXConstructExpr(StmtClass SC,EmptyShell Empty,unsigned NumArgs)1152e5dd7070Spatrick CXXConstructExpr::CXXConstructExpr(StmtClass SC, EmptyShell Empty,
1153e5dd7070Spatrick                                    unsigned NumArgs)
1154e5dd7070Spatrick     : Expr(SC, Empty), NumArgs(NumArgs) {}
1155e5dd7070Spatrick 
LambdaCapture(SourceLocation Loc,bool Implicit,LambdaCaptureKind Kind,ValueDecl * Var,SourceLocation EllipsisLoc)1156e5dd7070Spatrick LambdaCapture::LambdaCapture(SourceLocation Loc, bool Implicit,
1157*12c85518Srobert                              LambdaCaptureKind Kind, ValueDecl *Var,
1158e5dd7070Spatrick                              SourceLocation EllipsisLoc)
1159e5dd7070Spatrick     : DeclAndBits(Var, 0), Loc(Loc), EllipsisLoc(EllipsisLoc) {
1160e5dd7070Spatrick   unsigned Bits = 0;
1161e5dd7070Spatrick   if (Implicit)
1162e5dd7070Spatrick     Bits |= Capture_Implicit;
1163e5dd7070Spatrick 
1164e5dd7070Spatrick   switch (Kind) {
1165e5dd7070Spatrick   case LCK_StarThis:
1166e5dd7070Spatrick     Bits |= Capture_ByCopy;
1167*12c85518Srobert     [[fallthrough]];
1168e5dd7070Spatrick   case LCK_This:
1169e5dd7070Spatrick     assert(!Var && "'this' capture cannot have a variable!");
1170e5dd7070Spatrick     Bits |= Capture_This;
1171e5dd7070Spatrick     break;
1172e5dd7070Spatrick 
1173e5dd7070Spatrick   case LCK_ByCopy:
1174e5dd7070Spatrick     Bits |= Capture_ByCopy;
1175*12c85518Srobert     [[fallthrough]];
1176e5dd7070Spatrick   case LCK_ByRef:
1177e5dd7070Spatrick     assert(Var && "capture must have a variable!");
1178e5dd7070Spatrick     break;
1179e5dd7070Spatrick   case LCK_VLAType:
1180e5dd7070Spatrick     assert(!Var && "VLA type capture cannot have a variable!");
1181e5dd7070Spatrick     break;
1182e5dd7070Spatrick   }
1183e5dd7070Spatrick   DeclAndBits.setInt(Bits);
1184e5dd7070Spatrick }
1185e5dd7070Spatrick 
getCaptureKind() const1186e5dd7070Spatrick LambdaCaptureKind LambdaCapture::getCaptureKind() const {
1187e5dd7070Spatrick   if (capturesVLAType())
1188e5dd7070Spatrick     return LCK_VLAType;
1189e5dd7070Spatrick   bool CapByCopy = DeclAndBits.getInt() & Capture_ByCopy;
1190e5dd7070Spatrick   if (capturesThis())
1191e5dd7070Spatrick     return CapByCopy ? LCK_StarThis : LCK_This;
1192e5dd7070Spatrick   return CapByCopy ? LCK_ByCopy : LCK_ByRef;
1193e5dd7070Spatrick }
1194e5dd7070Spatrick 
LambdaExpr(QualType T,SourceRange IntroducerRange,LambdaCaptureDefault CaptureDefault,SourceLocation CaptureDefaultLoc,bool ExplicitParams,bool ExplicitResultType,ArrayRef<Expr * > CaptureInits,SourceLocation ClosingBrace,bool ContainsUnexpandedParameterPack)1195e5dd7070Spatrick LambdaExpr::LambdaExpr(QualType T, SourceRange IntroducerRange,
1196e5dd7070Spatrick                        LambdaCaptureDefault CaptureDefault,
1197ec727ea7Spatrick                        SourceLocation CaptureDefaultLoc, bool ExplicitParams,
1198e5dd7070Spatrick                        bool ExplicitResultType, ArrayRef<Expr *> CaptureInits,
1199e5dd7070Spatrick                        SourceLocation ClosingBrace,
1200e5dd7070Spatrick                        bool ContainsUnexpandedParameterPack)
1201a9ac8606Spatrick     : Expr(LambdaExprClass, T, VK_PRValue, OK_Ordinary),
1202e5dd7070Spatrick       IntroducerRange(IntroducerRange), CaptureDefaultLoc(CaptureDefaultLoc),
1203e5dd7070Spatrick       ClosingBrace(ClosingBrace) {
1204ec727ea7Spatrick   LambdaExprBits.NumCaptures = CaptureInits.size();
1205ec727ea7Spatrick   LambdaExprBits.CaptureDefault = CaptureDefault;
1206ec727ea7Spatrick   LambdaExprBits.ExplicitParams = ExplicitParams;
1207ec727ea7Spatrick   LambdaExprBits.ExplicitResultType = ExplicitResultType;
1208ec727ea7Spatrick 
1209e5dd7070Spatrick   CXXRecordDecl *Class = getLambdaClass();
1210ec727ea7Spatrick   (void)Class;
1211ec727ea7Spatrick   assert(capture_size() == Class->capture_size() && "Wrong number of captures");
1212ec727ea7Spatrick   assert(getCaptureDefault() == Class->getLambdaCaptureDefault());
1213e5dd7070Spatrick 
1214e5dd7070Spatrick   // Copy initialization expressions for the non-static data members.
1215e5dd7070Spatrick   Stmt **Stored = getStoredStmts();
1216e5dd7070Spatrick   for (unsigned I = 0, N = CaptureInits.size(); I != N; ++I)
1217e5dd7070Spatrick     *Stored++ = CaptureInits[I];
1218e5dd7070Spatrick 
1219e5dd7070Spatrick   // Copy the body of the lambda.
1220e5dd7070Spatrick   *Stored++ = getCallOperator()->getBody();
1221ec727ea7Spatrick 
1222ec727ea7Spatrick   setDependence(computeDependence(this, ContainsUnexpandedParameterPack));
1223e5dd7070Spatrick }
1224e5dd7070Spatrick 
LambdaExpr(EmptyShell Empty,unsigned NumCaptures)1225ec727ea7Spatrick LambdaExpr::LambdaExpr(EmptyShell Empty, unsigned NumCaptures)
1226ec727ea7Spatrick     : Expr(LambdaExprClass, Empty) {
1227ec727ea7Spatrick   LambdaExprBits.NumCaptures = NumCaptures;
1228ec727ea7Spatrick 
1229ec727ea7Spatrick   // Initially don't initialize the body of the LambdaExpr. The body will
1230ec727ea7Spatrick   // be lazily deserialized when needed.
1231ec727ea7Spatrick   getStoredStmts()[NumCaptures] = nullptr; // Not one past the end.
1232ec727ea7Spatrick }
1233ec727ea7Spatrick 
Create(const ASTContext & Context,CXXRecordDecl * Class,SourceRange IntroducerRange,LambdaCaptureDefault CaptureDefault,SourceLocation CaptureDefaultLoc,bool ExplicitParams,bool ExplicitResultType,ArrayRef<Expr * > CaptureInits,SourceLocation ClosingBrace,bool ContainsUnexpandedParameterPack)1234ec727ea7Spatrick LambdaExpr *LambdaExpr::Create(const ASTContext &Context, CXXRecordDecl *Class,
1235ec727ea7Spatrick                                SourceRange IntroducerRange,
1236ec727ea7Spatrick                                LambdaCaptureDefault CaptureDefault,
1237ec727ea7Spatrick                                SourceLocation CaptureDefaultLoc,
1238ec727ea7Spatrick                                bool ExplicitParams, bool ExplicitResultType,
1239ec727ea7Spatrick                                ArrayRef<Expr *> CaptureInits,
1240ec727ea7Spatrick                                SourceLocation ClosingBrace,
1241ec727ea7Spatrick                                bool ContainsUnexpandedParameterPack) {
1242e5dd7070Spatrick   // Determine the type of the expression (i.e., the type of the
1243e5dd7070Spatrick   // function object we're creating).
1244e5dd7070Spatrick   QualType T = Context.getTypeDeclType(Class);
1245e5dd7070Spatrick 
1246ec727ea7Spatrick   unsigned Size = totalSizeToAlloc<Stmt *>(CaptureInits.size() + 1);
1247e5dd7070Spatrick   void *Mem = Context.Allocate(Size);
1248e5dd7070Spatrick   return new (Mem)
1249e5dd7070Spatrick       LambdaExpr(T, IntroducerRange, CaptureDefault, CaptureDefaultLoc,
1250ec727ea7Spatrick                  ExplicitParams, ExplicitResultType, CaptureInits, ClosingBrace,
1251ec727ea7Spatrick                  ContainsUnexpandedParameterPack);
1252e5dd7070Spatrick }
1253e5dd7070Spatrick 
CreateDeserialized(const ASTContext & C,unsigned NumCaptures)1254e5dd7070Spatrick LambdaExpr *LambdaExpr::CreateDeserialized(const ASTContext &C,
1255e5dd7070Spatrick                                            unsigned NumCaptures) {
1256e5dd7070Spatrick   unsigned Size = totalSizeToAlloc<Stmt *>(NumCaptures + 1);
1257e5dd7070Spatrick   void *Mem = C.Allocate(Size);
1258e5dd7070Spatrick   return new (Mem) LambdaExpr(EmptyShell(), NumCaptures);
1259e5dd7070Spatrick }
1260e5dd7070Spatrick 
initBodyIfNeeded() const1261ec727ea7Spatrick void LambdaExpr::initBodyIfNeeded() const {
1262ec727ea7Spatrick   if (!getStoredStmts()[capture_size()]) {
1263ec727ea7Spatrick     auto *This = const_cast<LambdaExpr *>(this);
1264ec727ea7Spatrick     This->getStoredStmts()[capture_size()] = getCallOperator()->getBody();
1265ec727ea7Spatrick   }
1266ec727ea7Spatrick }
1267ec727ea7Spatrick 
getBody() const1268ec727ea7Spatrick Stmt *LambdaExpr::getBody() const {
1269ec727ea7Spatrick   initBodyIfNeeded();
1270ec727ea7Spatrick   return getStoredStmts()[capture_size()];
1271ec727ea7Spatrick }
1272ec727ea7Spatrick 
getCompoundStmtBody() const1273ec727ea7Spatrick const CompoundStmt *LambdaExpr::getCompoundStmtBody() const {
1274ec727ea7Spatrick   Stmt *Body = getBody();
1275ec727ea7Spatrick   if (const auto *CoroBody = dyn_cast<CoroutineBodyStmt>(Body))
1276ec727ea7Spatrick     return cast<CompoundStmt>(CoroBody->getBody());
1277ec727ea7Spatrick   return cast<CompoundStmt>(Body);
1278ec727ea7Spatrick }
1279ec727ea7Spatrick 
isInitCapture(const LambdaCapture * C) const1280e5dd7070Spatrick bool LambdaExpr::isInitCapture(const LambdaCapture *C) const {
1281*12c85518Srobert   return C->capturesVariable() && C->getCapturedVar()->isInitCapture() &&
1282*12c85518Srobert          getCallOperator() == C->getCapturedVar()->getDeclContext();
1283e5dd7070Spatrick }
1284e5dd7070Spatrick 
capture_begin() const1285e5dd7070Spatrick LambdaExpr::capture_iterator LambdaExpr::capture_begin() const {
1286*12c85518Srobert   return getLambdaClass()->captures_begin();
1287e5dd7070Spatrick }
1288e5dd7070Spatrick 
capture_end() const1289e5dd7070Spatrick LambdaExpr::capture_iterator LambdaExpr::capture_end() const {
1290*12c85518Srobert   return getLambdaClass()->captures_end();
1291e5dd7070Spatrick }
1292e5dd7070Spatrick 
captures() const1293e5dd7070Spatrick LambdaExpr::capture_range LambdaExpr::captures() const {
1294e5dd7070Spatrick   return capture_range(capture_begin(), capture_end());
1295e5dd7070Spatrick }
1296e5dd7070Spatrick 
explicit_capture_begin() const1297e5dd7070Spatrick LambdaExpr::capture_iterator LambdaExpr::explicit_capture_begin() const {
1298e5dd7070Spatrick   return capture_begin();
1299e5dd7070Spatrick }
1300e5dd7070Spatrick 
explicit_capture_end() const1301e5dd7070Spatrick LambdaExpr::capture_iterator LambdaExpr::explicit_capture_end() const {
1302*12c85518Srobert   return capture_begin() +
1303*12c85518Srobert          getLambdaClass()->getLambdaData().NumExplicitCaptures;
1304e5dd7070Spatrick }
1305e5dd7070Spatrick 
explicit_captures() const1306e5dd7070Spatrick LambdaExpr::capture_range LambdaExpr::explicit_captures() const {
1307e5dd7070Spatrick   return capture_range(explicit_capture_begin(), explicit_capture_end());
1308e5dd7070Spatrick }
1309e5dd7070Spatrick 
implicit_capture_begin() const1310e5dd7070Spatrick LambdaExpr::capture_iterator LambdaExpr::implicit_capture_begin() const {
1311e5dd7070Spatrick   return explicit_capture_end();
1312e5dd7070Spatrick }
1313e5dd7070Spatrick 
implicit_capture_end() const1314e5dd7070Spatrick LambdaExpr::capture_iterator LambdaExpr::implicit_capture_end() const {
1315e5dd7070Spatrick   return capture_end();
1316e5dd7070Spatrick }
1317e5dd7070Spatrick 
implicit_captures() const1318e5dd7070Spatrick LambdaExpr::capture_range LambdaExpr::implicit_captures() const {
1319e5dd7070Spatrick   return capture_range(implicit_capture_begin(), implicit_capture_end());
1320e5dd7070Spatrick }
1321e5dd7070Spatrick 
getLambdaClass() const1322e5dd7070Spatrick CXXRecordDecl *LambdaExpr::getLambdaClass() const {
1323e5dd7070Spatrick   return getType()->getAsCXXRecordDecl();
1324e5dd7070Spatrick }
1325e5dd7070Spatrick 
getCallOperator() const1326e5dd7070Spatrick CXXMethodDecl *LambdaExpr::getCallOperator() const {
1327e5dd7070Spatrick   CXXRecordDecl *Record = getLambdaClass();
1328e5dd7070Spatrick   return Record->getLambdaCallOperator();
1329e5dd7070Spatrick }
1330e5dd7070Spatrick 
getDependentCallOperator() const1331e5dd7070Spatrick FunctionTemplateDecl *LambdaExpr::getDependentCallOperator() const {
1332e5dd7070Spatrick   CXXRecordDecl *Record = getLambdaClass();
1333e5dd7070Spatrick   return Record->getDependentLambdaCallOperator();
1334e5dd7070Spatrick }
1335e5dd7070Spatrick 
getTemplateParameterList() const1336e5dd7070Spatrick TemplateParameterList *LambdaExpr::getTemplateParameterList() const {
1337e5dd7070Spatrick   CXXRecordDecl *Record = getLambdaClass();
1338e5dd7070Spatrick   return Record->getGenericLambdaTemplateParameterList();
1339e5dd7070Spatrick }
1340e5dd7070Spatrick 
getExplicitTemplateParameters() const1341e5dd7070Spatrick ArrayRef<NamedDecl *> LambdaExpr::getExplicitTemplateParameters() const {
1342e5dd7070Spatrick   const CXXRecordDecl *Record = getLambdaClass();
1343e5dd7070Spatrick   return Record->getLambdaExplicitTemplateParameters();
1344e5dd7070Spatrick }
1345e5dd7070Spatrick 
getTrailingRequiresClause() const1346a9ac8606Spatrick Expr *LambdaExpr::getTrailingRequiresClause() const {
1347a9ac8606Spatrick   return getCallOperator()->getTrailingRequiresClause();
1348a9ac8606Spatrick }
1349a9ac8606Spatrick 
isMutable() const1350ec727ea7Spatrick bool LambdaExpr::isMutable() const { return !getCallOperator()->isConst(); }
1351e5dd7070Spatrick 
children()1352ec727ea7Spatrick LambdaExpr::child_range LambdaExpr::children() {
1353ec727ea7Spatrick   initBodyIfNeeded();
1354ec727ea7Spatrick   return child_range(getStoredStmts(), getStoredStmts() + capture_size() + 1);
1355e5dd7070Spatrick }
1356e5dd7070Spatrick 
children() const1357ec727ea7Spatrick LambdaExpr::const_child_range LambdaExpr::children() const {
1358ec727ea7Spatrick   initBodyIfNeeded();
1359ec727ea7Spatrick   return const_child_range(getStoredStmts(),
1360ec727ea7Spatrick                            getStoredStmts() + capture_size() + 1);
1361e5dd7070Spatrick }
1362e5dd7070Spatrick 
ExprWithCleanups(Expr * subexpr,bool CleanupsHaveSideEffects,ArrayRef<CleanupObject> objects)1363e5dd7070Spatrick ExprWithCleanups::ExprWithCleanups(Expr *subexpr,
1364e5dd7070Spatrick                                    bool CleanupsHaveSideEffects,
1365e5dd7070Spatrick                                    ArrayRef<CleanupObject> objects)
1366e5dd7070Spatrick     : FullExpr(ExprWithCleanupsClass, subexpr) {
1367e5dd7070Spatrick   ExprWithCleanupsBits.CleanupsHaveSideEffects = CleanupsHaveSideEffects;
1368e5dd7070Spatrick   ExprWithCleanupsBits.NumObjects = objects.size();
1369e5dd7070Spatrick   for (unsigned i = 0, e = objects.size(); i != e; ++i)
1370e5dd7070Spatrick     getTrailingObjects<CleanupObject>()[i] = objects[i];
1371e5dd7070Spatrick }
1372e5dd7070Spatrick 
Create(const ASTContext & C,Expr * subexpr,bool CleanupsHaveSideEffects,ArrayRef<CleanupObject> objects)1373e5dd7070Spatrick ExprWithCleanups *ExprWithCleanups::Create(const ASTContext &C, Expr *subexpr,
1374e5dd7070Spatrick                                            bool CleanupsHaveSideEffects,
1375e5dd7070Spatrick                                            ArrayRef<CleanupObject> objects) {
1376e5dd7070Spatrick   void *buffer = C.Allocate(totalSizeToAlloc<CleanupObject>(objects.size()),
1377e5dd7070Spatrick                             alignof(ExprWithCleanups));
1378e5dd7070Spatrick   return new (buffer)
1379e5dd7070Spatrick       ExprWithCleanups(subexpr, CleanupsHaveSideEffects, objects);
1380e5dd7070Spatrick }
1381e5dd7070Spatrick 
ExprWithCleanups(EmptyShell empty,unsigned numObjects)1382e5dd7070Spatrick ExprWithCleanups::ExprWithCleanups(EmptyShell empty, unsigned numObjects)
1383e5dd7070Spatrick     : FullExpr(ExprWithCleanupsClass, empty) {
1384e5dd7070Spatrick   ExprWithCleanupsBits.NumObjects = numObjects;
1385e5dd7070Spatrick }
1386e5dd7070Spatrick 
Create(const ASTContext & C,EmptyShell empty,unsigned numObjects)1387e5dd7070Spatrick ExprWithCleanups *ExprWithCleanups::Create(const ASTContext &C,
1388e5dd7070Spatrick                                            EmptyShell empty,
1389e5dd7070Spatrick                                            unsigned numObjects) {
1390e5dd7070Spatrick   void *buffer = C.Allocate(totalSizeToAlloc<CleanupObject>(numObjects),
1391e5dd7070Spatrick                             alignof(ExprWithCleanups));
1392e5dd7070Spatrick   return new (buffer) ExprWithCleanups(empty, numObjects);
1393e5dd7070Spatrick }
1394e5dd7070Spatrick 
CXXUnresolvedConstructExpr(QualType T,TypeSourceInfo * TSI,SourceLocation LParenLoc,ArrayRef<Expr * > Args,SourceLocation RParenLoc)1395a9ac8606Spatrick CXXUnresolvedConstructExpr::CXXUnresolvedConstructExpr(QualType T,
1396a9ac8606Spatrick                                                        TypeSourceInfo *TSI,
1397e5dd7070Spatrick                                                        SourceLocation LParenLoc,
1398e5dd7070Spatrick                                                        ArrayRef<Expr *> Args,
1399e5dd7070Spatrick                                                        SourceLocation RParenLoc)
1400a9ac8606Spatrick     : Expr(CXXUnresolvedConstructExprClass, T,
1401a9ac8606Spatrick            (TSI->getType()->isLValueReferenceType()   ? VK_LValue
1402e5dd7070Spatrick             : TSI->getType()->isRValueReferenceType() ? VK_XValue
1403a9ac8606Spatrick                                                       : VK_PRValue),
1404ec727ea7Spatrick            OK_Ordinary),
1405e5dd7070Spatrick       TSI(TSI), LParenLoc(LParenLoc), RParenLoc(RParenLoc) {
1406e5dd7070Spatrick   CXXUnresolvedConstructExprBits.NumArgs = Args.size();
1407e5dd7070Spatrick   auto **StoredArgs = getTrailingObjects<Expr *>();
1408ec727ea7Spatrick   for (unsigned I = 0; I != Args.size(); ++I)
1409e5dd7070Spatrick     StoredArgs[I] = Args[I];
1410ec727ea7Spatrick   setDependence(computeDependence(this));
1411e5dd7070Spatrick }
1412e5dd7070Spatrick 
Create(const ASTContext & Context,QualType T,TypeSourceInfo * TSI,SourceLocation LParenLoc,ArrayRef<Expr * > Args,SourceLocation RParenLoc)1413e5dd7070Spatrick CXXUnresolvedConstructExpr *CXXUnresolvedConstructExpr::Create(
1414a9ac8606Spatrick     const ASTContext &Context, QualType T, TypeSourceInfo *TSI, SourceLocation LParenLoc,
1415e5dd7070Spatrick     ArrayRef<Expr *> Args, SourceLocation RParenLoc) {
1416e5dd7070Spatrick   void *Mem = Context.Allocate(totalSizeToAlloc<Expr *>(Args.size()));
1417a9ac8606Spatrick   return new (Mem)
1418a9ac8606Spatrick       CXXUnresolvedConstructExpr(T, TSI, LParenLoc, Args, RParenLoc);
1419e5dd7070Spatrick }
1420e5dd7070Spatrick 
1421e5dd7070Spatrick CXXUnresolvedConstructExpr *
CreateEmpty(const ASTContext & Context,unsigned NumArgs)1422e5dd7070Spatrick CXXUnresolvedConstructExpr::CreateEmpty(const ASTContext &Context,
1423e5dd7070Spatrick                                         unsigned NumArgs) {
1424e5dd7070Spatrick   void *Mem = Context.Allocate(totalSizeToAlloc<Expr *>(NumArgs));
1425e5dd7070Spatrick   return new (Mem) CXXUnresolvedConstructExpr(EmptyShell(), NumArgs);
1426e5dd7070Spatrick }
1427e5dd7070Spatrick 
getBeginLoc() const1428e5dd7070Spatrick SourceLocation CXXUnresolvedConstructExpr::getBeginLoc() const {
1429e5dd7070Spatrick   return TSI->getTypeLoc().getBeginLoc();
1430e5dd7070Spatrick }
1431e5dd7070Spatrick 
CXXDependentScopeMemberExpr(const ASTContext & Ctx,Expr * Base,QualType BaseType,bool IsArrow,SourceLocation OperatorLoc,NestedNameSpecifierLoc QualifierLoc,SourceLocation TemplateKWLoc,NamedDecl * FirstQualifierFoundInScope,DeclarationNameInfo MemberNameInfo,const TemplateArgumentListInfo * TemplateArgs)1432e5dd7070Spatrick CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(
1433e5dd7070Spatrick     const ASTContext &Ctx, Expr *Base, QualType BaseType, bool IsArrow,
1434e5dd7070Spatrick     SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc,
1435e5dd7070Spatrick     SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierFoundInScope,
1436e5dd7070Spatrick     DeclarationNameInfo MemberNameInfo,
1437e5dd7070Spatrick     const TemplateArgumentListInfo *TemplateArgs)
1438e5dd7070Spatrick     : Expr(CXXDependentScopeMemberExprClass, Ctx.DependentTy, VK_LValue,
1439ec727ea7Spatrick            OK_Ordinary),
1440e5dd7070Spatrick       Base(Base), BaseType(BaseType), QualifierLoc(QualifierLoc),
1441e5dd7070Spatrick       MemberNameInfo(MemberNameInfo) {
1442e5dd7070Spatrick   CXXDependentScopeMemberExprBits.IsArrow = IsArrow;
1443e5dd7070Spatrick   CXXDependentScopeMemberExprBits.HasTemplateKWAndArgsInfo =
1444e5dd7070Spatrick       (TemplateArgs != nullptr) || TemplateKWLoc.isValid();
1445e5dd7070Spatrick   CXXDependentScopeMemberExprBits.HasFirstQualifierFoundInScope =
1446e5dd7070Spatrick       FirstQualifierFoundInScope != nullptr;
1447e5dd7070Spatrick   CXXDependentScopeMemberExprBits.OperatorLoc = OperatorLoc;
1448e5dd7070Spatrick 
1449e5dd7070Spatrick   if (TemplateArgs) {
1450ec727ea7Spatrick     auto Deps = TemplateArgumentDependence::None;
1451e5dd7070Spatrick     getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
1452e5dd7070Spatrick         TemplateKWLoc, *TemplateArgs, getTrailingObjects<TemplateArgumentLoc>(),
1453ec727ea7Spatrick         Deps);
1454e5dd7070Spatrick   } else if (TemplateKWLoc.isValid()) {
1455e5dd7070Spatrick     getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
1456e5dd7070Spatrick         TemplateKWLoc);
1457e5dd7070Spatrick   }
1458e5dd7070Spatrick 
1459e5dd7070Spatrick   if (hasFirstQualifierFoundInScope())
1460e5dd7070Spatrick     *getTrailingObjects<NamedDecl *>() = FirstQualifierFoundInScope;
1461ec727ea7Spatrick   setDependence(computeDependence(this));
1462e5dd7070Spatrick }
1463e5dd7070Spatrick 
CXXDependentScopeMemberExpr(EmptyShell Empty,bool HasTemplateKWAndArgsInfo,bool HasFirstQualifierFoundInScope)1464e5dd7070Spatrick CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(
1465e5dd7070Spatrick     EmptyShell Empty, bool HasTemplateKWAndArgsInfo,
1466e5dd7070Spatrick     bool HasFirstQualifierFoundInScope)
1467e5dd7070Spatrick     : Expr(CXXDependentScopeMemberExprClass, Empty) {
1468e5dd7070Spatrick   CXXDependentScopeMemberExprBits.HasTemplateKWAndArgsInfo =
1469e5dd7070Spatrick       HasTemplateKWAndArgsInfo;
1470e5dd7070Spatrick   CXXDependentScopeMemberExprBits.HasFirstQualifierFoundInScope =
1471e5dd7070Spatrick       HasFirstQualifierFoundInScope;
1472e5dd7070Spatrick }
1473e5dd7070Spatrick 
Create(const ASTContext & Ctx,Expr * Base,QualType BaseType,bool IsArrow,SourceLocation OperatorLoc,NestedNameSpecifierLoc QualifierLoc,SourceLocation TemplateKWLoc,NamedDecl * FirstQualifierFoundInScope,DeclarationNameInfo MemberNameInfo,const TemplateArgumentListInfo * TemplateArgs)1474e5dd7070Spatrick CXXDependentScopeMemberExpr *CXXDependentScopeMemberExpr::Create(
1475e5dd7070Spatrick     const ASTContext &Ctx, Expr *Base, QualType BaseType, bool IsArrow,
1476e5dd7070Spatrick     SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc,
1477e5dd7070Spatrick     SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierFoundInScope,
1478e5dd7070Spatrick     DeclarationNameInfo MemberNameInfo,
1479e5dd7070Spatrick     const TemplateArgumentListInfo *TemplateArgs) {
1480e5dd7070Spatrick   bool HasTemplateKWAndArgsInfo =
1481e5dd7070Spatrick       (TemplateArgs != nullptr) || TemplateKWLoc.isValid();
1482e5dd7070Spatrick   unsigned NumTemplateArgs = TemplateArgs ? TemplateArgs->size() : 0;
1483e5dd7070Spatrick   bool HasFirstQualifierFoundInScope = FirstQualifierFoundInScope != nullptr;
1484e5dd7070Spatrick 
1485e5dd7070Spatrick   unsigned Size = totalSizeToAlloc<ASTTemplateKWAndArgsInfo,
1486e5dd7070Spatrick                                    TemplateArgumentLoc, NamedDecl *>(
1487e5dd7070Spatrick       HasTemplateKWAndArgsInfo, NumTemplateArgs, HasFirstQualifierFoundInScope);
1488e5dd7070Spatrick 
1489e5dd7070Spatrick   void *Mem = Ctx.Allocate(Size, alignof(CXXDependentScopeMemberExpr));
1490e5dd7070Spatrick   return new (Mem) CXXDependentScopeMemberExpr(
1491e5dd7070Spatrick       Ctx, Base, BaseType, IsArrow, OperatorLoc, QualifierLoc, TemplateKWLoc,
1492e5dd7070Spatrick       FirstQualifierFoundInScope, MemberNameInfo, TemplateArgs);
1493e5dd7070Spatrick }
1494e5dd7070Spatrick 
CreateEmpty(const ASTContext & Ctx,bool HasTemplateKWAndArgsInfo,unsigned NumTemplateArgs,bool HasFirstQualifierFoundInScope)1495e5dd7070Spatrick CXXDependentScopeMemberExpr *CXXDependentScopeMemberExpr::CreateEmpty(
1496e5dd7070Spatrick     const ASTContext &Ctx, bool HasTemplateKWAndArgsInfo,
1497e5dd7070Spatrick     unsigned NumTemplateArgs, bool HasFirstQualifierFoundInScope) {
1498e5dd7070Spatrick   assert(NumTemplateArgs == 0 || HasTemplateKWAndArgsInfo);
1499e5dd7070Spatrick 
1500e5dd7070Spatrick   unsigned Size = totalSizeToAlloc<ASTTemplateKWAndArgsInfo,
1501e5dd7070Spatrick                                    TemplateArgumentLoc, NamedDecl *>(
1502e5dd7070Spatrick       HasTemplateKWAndArgsInfo, NumTemplateArgs, HasFirstQualifierFoundInScope);
1503e5dd7070Spatrick 
1504e5dd7070Spatrick   void *Mem = Ctx.Allocate(Size, alignof(CXXDependentScopeMemberExpr));
1505e5dd7070Spatrick   return new (Mem) CXXDependentScopeMemberExpr(
1506e5dd7070Spatrick       EmptyShell(), HasTemplateKWAndArgsInfo, HasFirstQualifierFoundInScope);
1507e5dd7070Spatrick }
1508e5dd7070Spatrick 
hasOnlyNonStaticMemberFunctions(UnresolvedSetIterator begin,UnresolvedSetIterator end)1509e5dd7070Spatrick static bool hasOnlyNonStaticMemberFunctions(UnresolvedSetIterator begin,
1510e5dd7070Spatrick                                             UnresolvedSetIterator end) {
1511e5dd7070Spatrick   do {
1512e5dd7070Spatrick     NamedDecl *decl = *begin;
1513e5dd7070Spatrick     if (isa<UnresolvedUsingValueDecl>(decl))
1514e5dd7070Spatrick       return false;
1515e5dd7070Spatrick 
1516e5dd7070Spatrick     // Unresolved member expressions should only contain methods and
1517e5dd7070Spatrick     // method templates.
1518e5dd7070Spatrick     if (cast<CXXMethodDecl>(decl->getUnderlyingDecl()->getAsFunction())
1519e5dd7070Spatrick             ->isStatic())
1520e5dd7070Spatrick       return false;
1521e5dd7070Spatrick   } while (++begin != end);
1522e5dd7070Spatrick 
1523e5dd7070Spatrick   return true;
1524e5dd7070Spatrick }
1525e5dd7070Spatrick 
UnresolvedMemberExpr(const ASTContext & Context,bool HasUnresolvedUsing,Expr * Base,QualType BaseType,bool IsArrow,SourceLocation OperatorLoc,NestedNameSpecifierLoc QualifierLoc,SourceLocation TemplateKWLoc,const DeclarationNameInfo & MemberNameInfo,const TemplateArgumentListInfo * TemplateArgs,UnresolvedSetIterator Begin,UnresolvedSetIterator End)1526e5dd7070Spatrick UnresolvedMemberExpr::UnresolvedMemberExpr(
1527e5dd7070Spatrick     const ASTContext &Context, bool HasUnresolvedUsing, Expr *Base,
1528e5dd7070Spatrick     QualType BaseType, bool IsArrow, SourceLocation OperatorLoc,
1529e5dd7070Spatrick     NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc,
1530e5dd7070Spatrick     const DeclarationNameInfo &MemberNameInfo,
1531e5dd7070Spatrick     const TemplateArgumentListInfo *TemplateArgs, UnresolvedSetIterator Begin,
1532e5dd7070Spatrick     UnresolvedSetIterator End)
1533e5dd7070Spatrick     : OverloadExpr(
1534e5dd7070Spatrick           UnresolvedMemberExprClass, Context, QualifierLoc, TemplateKWLoc,
1535e5dd7070Spatrick           MemberNameInfo, TemplateArgs, Begin, End,
1536e5dd7070Spatrick           // Dependent
1537e5dd7070Spatrick           ((Base && Base->isTypeDependent()) || BaseType->isDependentType()),
1538e5dd7070Spatrick           ((Base && Base->isInstantiationDependent()) ||
1539e5dd7070Spatrick            BaseType->isInstantiationDependentType()),
1540e5dd7070Spatrick           // Contains unexpanded parameter pack
1541e5dd7070Spatrick           ((Base && Base->containsUnexpandedParameterPack()) ||
1542e5dd7070Spatrick            BaseType->containsUnexpandedParameterPack())),
1543e5dd7070Spatrick       Base(Base), BaseType(BaseType), OperatorLoc(OperatorLoc) {
1544e5dd7070Spatrick   UnresolvedMemberExprBits.IsArrow = IsArrow;
1545e5dd7070Spatrick   UnresolvedMemberExprBits.HasUnresolvedUsing = HasUnresolvedUsing;
1546e5dd7070Spatrick 
1547e5dd7070Spatrick   // Check whether all of the members are non-static member functions,
1548e5dd7070Spatrick   // and if so, mark give this bound-member type instead of overload type.
1549e5dd7070Spatrick   if (hasOnlyNonStaticMemberFunctions(Begin, End))
1550e5dd7070Spatrick     setType(Context.BoundMemberTy);
1551e5dd7070Spatrick }
1552e5dd7070Spatrick 
UnresolvedMemberExpr(EmptyShell Empty,unsigned NumResults,bool HasTemplateKWAndArgsInfo)1553e5dd7070Spatrick UnresolvedMemberExpr::UnresolvedMemberExpr(EmptyShell Empty,
1554e5dd7070Spatrick                                            unsigned NumResults,
1555e5dd7070Spatrick                                            bool HasTemplateKWAndArgsInfo)
1556e5dd7070Spatrick     : OverloadExpr(UnresolvedMemberExprClass, Empty, NumResults,
1557e5dd7070Spatrick                    HasTemplateKWAndArgsInfo) {}
1558e5dd7070Spatrick 
isImplicitAccess() const1559e5dd7070Spatrick bool UnresolvedMemberExpr::isImplicitAccess() const {
1560e5dd7070Spatrick   if (!Base)
1561e5dd7070Spatrick     return true;
1562e5dd7070Spatrick 
1563e5dd7070Spatrick   return cast<Expr>(Base)->isImplicitCXXThis();
1564e5dd7070Spatrick }
1565e5dd7070Spatrick 
Create(const ASTContext & Context,bool HasUnresolvedUsing,Expr * Base,QualType BaseType,bool IsArrow,SourceLocation OperatorLoc,NestedNameSpecifierLoc QualifierLoc,SourceLocation TemplateKWLoc,const DeclarationNameInfo & MemberNameInfo,const TemplateArgumentListInfo * TemplateArgs,UnresolvedSetIterator Begin,UnresolvedSetIterator End)1566e5dd7070Spatrick UnresolvedMemberExpr *UnresolvedMemberExpr::Create(
1567e5dd7070Spatrick     const ASTContext &Context, bool HasUnresolvedUsing, Expr *Base,
1568e5dd7070Spatrick     QualType BaseType, bool IsArrow, SourceLocation OperatorLoc,
1569e5dd7070Spatrick     NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc,
1570e5dd7070Spatrick     const DeclarationNameInfo &MemberNameInfo,
1571e5dd7070Spatrick     const TemplateArgumentListInfo *TemplateArgs, UnresolvedSetIterator Begin,
1572e5dd7070Spatrick     UnresolvedSetIterator End) {
1573e5dd7070Spatrick   unsigned NumResults = End - Begin;
1574e5dd7070Spatrick   bool HasTemplateKWAndArgsInfo = TemplateArgs || TemplateKWLoc.isValid();
1575e5dd7070Spatrick   unsigned NumTemplateArgs = TemplateArgs ? TemplateArgs->size() : 0;
1576e5dd7070Spatrick   unsigned Size = totalSizeToAlloc<DeclAccessPair, ASTTemplateKWAndArgsInfo,
1577e5dd7070Spatrick                                    TemplateArgumentLoc>(
1578e5dd7070Spatrick       NumResults, HasTemplateKWAndArgsInfo, NumTemplateArgs);
1579e5dd7070Spatrick   void *Mem = Context.Allocate(Size, alignof(UnresolvedMemberExpr));
1580e5dd7070Spatrick   return new (Mem) UnresolvedMemberExpr(
1581e5dd7070Spatrick       Context, HasUnresolvedUsing, Base, BaseType, IsArrow, OperatorLoc,
1582e5dd7070Spatrick       QualifierLoc, TemplateKWLoc, MemberNameInfo, TemplateArgs, Begin, End);
1583e5dd7070Spatrick }
1584e5dd7070Spatrick 
CreateEmpty(const ASTContext & Context,unsigned NumResults,bool HasTemplateKWAndArgsInfo,unsigned NumTemplateArgs)1585e5dd7070Spatrick UnresolvedMemberExpr *UnresolvedMemberExpr::CreateEmpty(
1586e5dd7070Spatrick     const ASTContext &Context, unsigned NumResults,
1587e5dd7070Spatrick     bool HasTemplateKWAndArgsInfo, unsigned NumTemplateArgs) {
1588e5dd7070Spatrick   assert(NumTemplateArgs == 0 || HasTemplateKWAndArgsInfo);
1589e5dd7070Spatrick   unsigned Size = totalSizeToAlloc<DeclAccessPair, ASTTemplateKWAndArgsInfo,
1590e5dd7070Spatrick                                    TemplateArgumentLoc>(
1591e5dd7070Spatrick       NumResults, HasTemplateKWAndArgsInfo, NumTemplateArgs);
1592e5dd7070Spatrick   void *Mem = Context.Allocate(Size, alignof(UnresolvedMemberExpr));
1593e5dd7070Spatrick   return new (Mem)
1594e5dd7070Spatrick       UnresolvedMemberExpr(EmptyShell(), NumResults, HasTemplateKWAndArgsInfo);
1595e5dd7070Spatrick }
1596e5dd7070Spatrick 
getNamingClass()1597e5dd7070Spatrick CXXRecordDecl *UnresolvedMemberExpr::getNamingClass() {
1598e5dd7070Spatrick   // Unlike for UnresolvedLookupExpr, it is very easy to re-derive this.
1599e5dd7070Spatrick 
1600e5dd7070Spatrick   // If there was a nested name specifier, it names the naming class.
1601e5dd7070Spatrick   // It can't be dependent: after all, we were actually able to do the
1602e5dd7070Spatrick   // lookup.
1603e5dd7070Spatrick   CXXRecordDecl *Record = nullptr;
1604e5dd7070Spatrick   auto *NNS = getQualifier();
1605e5dd7070Spatrick   if (NNS && NNS->getKind() != NestedNameSpecifier::Super) {
1606e5dd7070Spatrick     const Type *T = getQualifier()->getAsType();
1607e5dd7070Spatrick     assert(T && "qualifier in member expression does not name type");
1608e5dd7070Spatrick     Record = T->getAsCXXRecordDecl();
1609e5dd7070Spatrick     assert(Record && "qualifier in member expression does not name record");
1610e5dd7070Spatrick   }
1611e5dd7070Spatrick   // Otherwise the naming class must have been the base class.
1612e5dd7070Spatrick   else {
1613e5dd7070Spatrick     QualType BaseType = getBaseType().getNonReferenceType();
1614e5dd7070Spatrick     if (isArrow())
1615e5dd7070Spatrick       BaseType = BaseType->castAs<PointerType>()->getPointeeType();
1616e5dd7070Spatrick 
1617e5dd7070Spatrick     Record = BaseType->getAsCXXRecordDecl();
1618e5dd7070Spatrick     assert(Record && "base of member expression does not name record");
1619e5dd7070Spatrick   }
1620e5dd7070Spatrick 
1621e5dd7070Spatrick   return Record;
1622e5dd7070Spatrick }
1623e5dd7070Spatrick 
Create(ASTContext & Context,SourceLocation OperatorLoc,NamedDecl * Pack,SourceLocation PackLoc,SourceLocation RParenLoc,std::optional<unsigned> Length,ArrayRef<TemplateArgument> PartialArgs)1624*12c85518Srobert SizeOfPackExpr *SizeOfPackExpr::Create(ASTContext &Context,
1625*12c85518Srobert                                        SourceLocation OperatorLoc,
1626e5dd7070Spatrick                                        NamedDecl *Pack, SourceLocation PackLoc,
1627e5dd7070Spatrick                                        SourceLocation RParenLoc,
1628*12c85518Srobert                                        std::optional<unsigned> Length,
1629e5dd7070Spatrick                                        ArrayRef<TemplateArgument> PartialArgs) {
1630e5dd7070Spatrick   void *Storage =
1631e5dd7070Spatrick       Context.Allocate(totalSizeToAlloc<TemplateArgument>(PartialArgs.size()));
1632e5dd7070Spatrick   return new (Storage) SizeOfPackExpr(Context.getSizeType(), OperatorLoc, Pack,
1633e5dd7070Spatrick                                       PackLoc, RParenLoc, Length, PartialArgs);
1634e5dd7070Spatrick }
1635e5dd7070Spatrick 
CreateDeserialized(ASTContext & Context,unsigned NumPartialArgs)1636e5dd7070Spatrick SizeOfPackExpr *SizeOfPackExpr::CreateDeserialized(ASTContext &Context,
1637e5dd7070Spatrick                                                    unsigned NumPartialArgs) {
1638e5dd7070Spatrick   void *Storage =
1639e5dd7070Spatrick       Context.Allocate(totalSizeToAlloc<TemplateArgument>(NumPartialArgs));
1640e5dd7070Spatrick   return new (Storage) SizeOfPackExpr(EmptyShell(), NumPartialArgs);
1641e5dd7070Spatrick }
1642e5dd7070Spatrick 
getParameter() const1643*12c85518Srobert NonTypeTemplateParmDecl *SubstNonTypeTemplateParmExpr::getParameter() const {
1644*12c85518Srobert   return cast<NonTypeTemplateParmDecl>(
1645*12c85518Srobert       getReplacedTemplateParameterList(getAssociatedDecl())->asArray()[Index]);
1646*12c85518Srobert }
1647*12c85518Srobert 
getParameterType(const ASTContext & Context) const1648a9ac8606Spatrick QualType SubstNonTypeTemplateParmExpr::getParameterType(
1649a9ac8606Spatrick     const ASTContext &Context) const {
1650a9ac8606Spatrick   // Note that, for a class type NTTP, we will have an lvalue of type 'const
1651a9ac8606Spatrick   // T', so we can't just compute this from the type and value category.
1652a9ac8606Spatrick   if (isReferenceParameter())
1653a9ac8606Spatrick     return Context.getLValueReferenceType(getType());
1654a9ac8606Spatrick   return getType().getUnqualifiedType();
1655a9ac8606Spatrick }
1656a9ac8606Spatrick 
SubstNonTypeTemplateParmPackExpr(QualType T,ExprValueKind ValueKind,SourceLocation NameLoc,const TemplateArgument & ArgPack,Decl * AssociatedDecl,unsigned Index)1657ec727ea7Spatrick SubstNonTypeTemplateParmPackExpr::SubstNonTypeTemplateParmPackExpr(
1658*12c85518Srobert     QualType T, ExprValueKind ValueKind, SourceLocation NameLoc,
1659*12c85518Srobert     const TemplateArgument &ArgPack, Decl *AssociatedDecl, unsigned Index)
1660ec727ea7Spatrick     : Expr(SubstNonTypeTemplateParmPackExprClass, T, ValueKind, OK_Ordinary),
1661*12c85518Srobert       AssociatedDecl(AssociatedDecl), Arguments(ArgPack.pack_begin()),
1662*12c85518Srobert       NumArguments(ArgPack.pack_size()), Index(Index), NameLoc(NameLoc) {
1663*12c85518Srobert   assert(AssociatedDecl != nullptr);
1664ec727ea7Spatrick   setDependence(ExprDependence::TypeValueInstantiation |
1665ec727ea7Spatrick                 ExprDependence::UnexpandedPack);
1666ec727ea7Spatrick }
1667e5dd7070Spatrick 
1668*12c85518Srobert NonTypeTemplateParmDecl *
getParameterPack() const1669*12c85518Srobert SubstNonTypeTemplateParmPackExpr::getParameterPack() const {
1670*12c85518Srobert   return cast<NonTypeTemplateParmDecl>(
1671*12c85518Srobert       getReplacedTemplateParameterList(getAssociatedDecl())->asArray()[Index]);
1672*12c85518Srobert }
1673*12c85518Srobert 
getArgumentPack() const1674e5dd7070Spatrick TemplateArgument SubstNonTypeTemplateParmPackExpr::getArgumentPack() const {
1675*12c85518Srobert   return TemplateArgument(llvm::ArrayRef(Arguments, NumArguments));
1676e5dd7070Spatrick }
1677e5dd7070Spatrick 
FunctionParmPackExpr(QualType T,VarDecl * ParamPack,SourceLocation NameLoc,unsigned NumParams,VarDecl * const * Params)1678e5dd7070Spatrick FunctionParmPackExpr::FunctionParmPackExpr(QualType T, VarDecl *ParamPack,
1679e5dd7070Spatrick                                            SourceLocation NameLoc,
1680e5dd7070Spatrick                                            unsigned NumParams,
1681e5dd7070Spatrick                                            VarDecl *const *Params)
1682ec727ea7Spatrick     : Expr(FunctionParmPackExprClass, T, VK_LValue, OK_Ordinary),
1683e5dd7070Spatrick       ParamPack(ParamPack), NameLoc(NameLoc), NumParameters(NumParams) {
1684e5dd7070Spatrick   if (Params)
1685e5dd7070Spatrick     std::uninitialized_copy(Params, Params + NumParams,
1686e5dd7070Spatrick                             getTrailingObjects<VarDecl *>());
1687ec727ea7Spatrick   setDependence(ExprDependence::TypeValueInstantiation |
1688ec727ea7Spatrick                 ExprDependence::UnexpandedPack);
1689e5dd7070Spatrick }
1690e5dd7070Spatrick 
1691e5dd7070Spatrick FunctionParmPackExpr *
Create(const ASTContext & Context,QualType T,VarDecl * ParamPack,SourceLocation NameLoc,ArrayRef<VarDecl * > Params)1692e5dd7070Spatrick FunctionParmPackExpr::Create(const ASTContext &Context, QualType T,
1693e5dd7070Spatrick                              VarDecl *ParamPack, SourceLocation NameLoc,
1694e5dd7070Spatrick                              ArrayRef<VarDecl *> Params) {
1695e5dd7070Spatrick   return new (Context.Allocate(totalSizeToAlloc<VarDecl *>(Params.size())))
1696e5dd7070Spatrick       FunctionParmPackExpr(T, ParamPack, NameLoc, Params.size(), Params.data());
1697e5dd7070Spatrick }
1698e5dd7070Spatrick 
1699e5dd7070Spatrick FunctionParmPackExpr *
CreateEmpty(const ASTContext & Context,unsigned NumParams)1700e5dd7070Spatrick FunctionParmPackExpr::CreateEmpty(const ASTContext &Context,
1701e5dd7070Spatrick                                   unsigned NumParams) {
1702e5dd7070Spatrick   return new (Context.Allocate(totalSizeToAlloc<VarDecl *>(NumParams)))
1703e5dd7070Spatrick       FunctionParmPackExpr(QualType(), nullptr, SourceLocation(), 0, nullptr);
1704e5dd7070Spatrick }
1705e5dd7070Spatrick 
MaterializeTemporaryExpr(QualType T,Expr * Temporary,bool BoundToLvalueReference,LifetimeExtendedTemporaryDecl * MTD)1706e5dd7070Spatrick MaterializeTemporaryExpr::MaterializeTemporaryExpr(
1707e5dd7070Spatrick     QualType T, Expr *Temporary, bool BoundToLvalueReference,
1708e5dd7070Spatrick     LifetimeExtendedTemporaryDecl *MTD)
1709e5dd7070Spatrick     : Expr(MaterializeTemporaryExprClass, T,
1710ec727ea7Spatrick            BoundToLvalueReference ? VK_LValue : VK_XValue, OK_Ordinary) {
1711e5dd7070Spatrick   if (MTD) {
1712e5dd7070Spatrick     State = MTD;
1713e5dd7070Spatrick     MTD->ExprWithTemporary = Temporary;
1714e5dd7070Spatrick     return;
1715e5dd7070Spatrick   }
1716e5dd7070Spatrick   State = Temporary;
1717ec727ea7Spatrick   setDependence(computeDependence(this));
1718e5dd7070Spatrick }
1719e5dd7070Spatrick 
setExtendingDecl(ValueDecl * ExtendedBy,unsigned ManglingNumber)1720e5dd7070Spatrick void MaterializeTemporaryExpr::setExtendingDecl(ValueDecl *ExtendedBy,
1721e5dd7070Spatrick                                                 unsigned ManglingNumber) {
1722e5dd7070Spatrick   // We only need extra state if we have to remember more than just the Stmt.
1723e5dd7070Spatrick   if (!ExtendedBy)
1724e5dd7070Spatrick     return;
1725e5dd7070Spatrick 
1726e5dd7070Spatrick   // We may need to allocate extra storage for the mangling number and the
1727e5dd7070Spatrick   // extended-by ValueDecl.
1728e5dd7070Spatrick   if (!State.is<LifetimeExtendedTemporaryDecl *>())
1729e5dd7070Spatrick     State = LifetimeExtendedTemporaryDecl::Create(
1730e5dd7070Spatrick         cast<Expr>(State.get<Stmt *>()), ExtendedBy, ManglingNumber);
1731e5dd7070Spatrick 
1732e5dd7070Spatrick   auto ES = State.get<LifetimeExtendedTemporaryDecl *>();
1733e5dd7070Spatrick   ES->ExtendingDecl = ExtendedBy;
1734e5dd7070Spatrick   ES->ManglingNumber = ManglingNumber;
1735e5dd7070Spatrick }
1736e5dd7070Spatrick 
isUsableInConstantExpressions(const ASTContext & Context) const1737a9ac8606Spatrick bool MaterializeTemporaryExpr::isUsableInConstantExpressions(
1738a9ac8606Spatrick     const ASTContext &Context) const {
1739a9ac8606Spatrick   // C++20 [expr.const]p4:
1740a9ac8606Spatrick   //   An object or reference is usable in constant expressions if it is [...]
1741a9ac8606Spatrick   //   a temporary object of non-volatile const-qualified literal type
1742a9ac8606Spatrick   //   whose lifetime is extended to that of a variable that is usable
1743a9ac8606Spatrick   //   in constant expressions
1744a9ac8606Spatrick   auto *VD = dyn_cast_or_null<VarDecl>(getExtendingDecl());
1745a9ac8606Spatrick   return VD && getType().isConstant(Context) &&
1746a9ac8606Spatrick          !getType().isVolatileQualified() &&
1747a9ac8606Spatrick          getType()->isLiteralType(Context) &&
1748a9ac8606Spatrick          VD->isUsableInConstantExpressions(Context);
1749a9ac8606Spatrick }
1750a9ac8606Spatrick 
TypeTraitExpr(QualType T,SourceLocation Loc,TypeTrait Kind,ArrayRef<TypeSourceInfo * > Args,SourceLocation RParenLoc,bool Value)1751e5dd7070Spatrick TypeTraitExpr::TypeTraitExpr(QualType T, SourceLocation Loc, TypeTrait Kind,
1752e5dd7070Spatrick                              ArrayRef<TypeSourceInfo *> Args,
1753ec727ea7Spatrick                              SourceLocation RParenLoc, bool Value)
1754a9ac8606Spatrick     : Expr(TypeTraitExprClass, T, VK_PRValue, OK_Ordinary), Loc(Loc),
1755ec727ea7Spatrick       RParenLoc(RParenLoc) {
1756ec727ea7Spatrick   assert(Kind <= TT_Last && "invalid enum value!");
1757e5dd7070Spatrick   TypeTraitExprBits.Kind = Kind;
1758ec727ea7Spatrick   assert(static_cast<unsigned>(Kind) == TypeTraitExprBits.Kind &&
1759ec727ea7Spatrick          "TypeTraitExprBits.Kind overflow!");
1760e5dd7070Spatrick   TypeTraitExprBits.Value = Value;
1761e5dd7070Spatrick   TypeTraitExprBits.NumArgs = Args.size();
1762ec727ea7Spatrick   assert(Args.size() == TypeTraitExprBits.NumArgs &&
1763ec727ea7Spatrick          "TypeTraitExprBits.NumArgs overflow!");
1764e5dd7070Spatrick 
1765e5dd7070Spatrick   auto **ToArgs = getTrailingObjects<TypeSourceInfo *>();
1766ec727ea7Spatrick   for (unsigned I = 0, N = Args.size(); I != N; ++I)
1767e5dd7070Spatrick     ToArgs[I] = Args[I];
1768ec727ea7Spatrick 
1769ec727ea7Spatrick   setDependence(computeDependence(this));
1770e5dd7070Spatrick }
1771e5dd7070Spatrick 
Create(const ASTContext & C,QualType T,SourceLocation Loc,TypeTrait Kind,ArrayRef<TypeSourceInfo * > Args,SourceLocation RParenLoc,bool Value)1772e5dd7070Spatrick TypeTraitExpr *TypeTraitExpr::Create(const ASTContext &C, QualType T,
1773e5dd7070Spatrick                                      SourceLocation Loc,
1774e5dd7070Spatrick                                      TypeTrait Kind,
1775e5dd7070Spatrick                                      ArrayRef<TypeSourceInfo *> Args,
1776e5dd7070Spatrick                                      SourceLocation RParenLoc,
1777e5dd7070Spatrick                                      bool Value) {
1778e5dd7070Spatrick   void *Mem = C.Allocate(totalSizeToAlloc<TypeSourceInfo *>(Args.size()));
1779e5dd7070Spatrick   return new (Mem) TypeTraitExpr(T, Loc, Kind, Args, RParenLoc, Value);
1780e5dd7070Spatrick }
1781e5dd7070Spatrick 
CreateDeserialized(const ASTContext & C,unsigned NumArgs)1782e5dd7070Spatrick TypeTraitExpr *TypeTraitExpr::CreateDeserialized(const ASTContext &C,
1783e5dd7070Spatrick                                                  unsigned NumArgs) {
1784e5dd7070Spatrick   void *Mem = C.Allocate(totalSizeToAlloc<TypeSourceInfo *>(NumArgs));
1785e5dd7070Spatrick   return new (Mem) TypeTraitExpr(EmptyShell());
1786e5dd7070Spatrick }
1787e5dd7070Spatrick 
CUDAKernelCallExpr(Expr * Fn,CallExpr * Config,ArrayRef<Expr * > Args,QualType Ty,ExprValueKind VK,SourceLocation RP,FPOptionsOverride FPFeatures,unsigned MinNumArgs)1788e5dd7070Spatrick CUDAKernelCallExpr::CUDAKernelCallExpr(Expr *Fn, CallExpr *Config,
1789e5dd7070Spatrick                                        ArrayRef<Expr *> Args, QualType Ty,
1790e5dd7070Spatrick                                        ExprValueKind VK, SourceLocation RP,
1791a9ac8606Spatrick                                        FPOptionsOverride FPFeatures,
1792e5dd7070Spatrick                                        unsigned MinNumArgs)
1793e5dd7070Spatrick     : CallExpr(CUDAKernelCallExprClass, Fn, /*PreArgs=*/Config, Args, Ty, VK,
1794a9ac8606Spatrick                RP, FPFeatures, MinNumArgs, NotADL) {}
1795e5dd7070Spatrick 
CUDAKernelCallExpr(unsigned NumArgs,bool HasFPFeatures,EmptyShell Empty)1796a9ac8606Spatrick CUDAKernelCallExpr::CUDAKernelCallExpr(unsigned NumArgs, bool HasFPFeatures,
1797a9ac8606Spatrick                                        EmptyShell Empty)
1798e5dd7070Spatrick     : CallExpr(CUDAKernelCallExprClass, /*NumPreArgs=*/END_PREARG, NumArgs,
1799a9ac8606Spatrick                HasFPFeatures, Empty) {}
1800e5dd7070Spatrick 
1801e5dd7070Spatrick CUDAKernelCallExpr *
Create(const ASTContext & Ctx,Expr * Fn,CallExpr * Config,ArrayRef<Expr * > Args,QualType Ty,ExprValueKind VK,SourceLocation RP,FPOptionsOverride FPFeatures,unsigned MinNumArgs)1802e5dd7070Spatrick CUDAKernelCallExpr::Create(const ASTContext &Ctx, Expr *Fn, CallExpr *Config,
1803e5dd7070Spatrick                            ArrayRef<Expr *> Args, QualType Ty, ExprValueKind VK,
1804a9ac8606Spatrick                            SourceLocation RP, FPOptionsOverride FPFeatures,
1805a9ac8606Spatrick                            unsigned MinNumArgs) {
1806e5dd7070Spatrick   // Allocate storage for the trailing objects of CallExpr.
1807e5dd7070Spatrick   unsigned NumArgs = std::max<unsigned>(Args.size(), MinNumArgs);
1808a9ac8606Spatrick   unsigned SizeOfTrailingObjects = CallExpr::sizeOfTrailingObjects(
1809a9ac8606Spatrick       /*NumPreArgs=*/END_PREARG, NumArgs, FPFeatures.requiresTrailingStorage());
1810e5dd7070Spatrick   void *Mem = Ctx.Allocate(sizeof(CUDAKernelCallExpr) + SizeOfTrailingObjects,
1811e5dd7070Spatrick                            alignof(CUDAKernelCallExpr));
1812a9ac8606Spatrick   return new (Mem)
1813a9ac8606Spatrick       CUDAKernelCallExpr(Fn, Config, Args, Ty, VK, RP, FPFeatures, MinNumArgs);
1814e5dd7070Spatrick }
1815e5dd7070Spatrick 
CreateEmpty(const ASTContext & Ctx,unsigned NumArgs,bool HasFPFeatures,EmptyShell Empty)1816e5dd7070Spatrick CUDAKernelCallExpr *CUDAKernelCallExpr::CreateEmpty(const ASTContext &Ctx,
1817e5dd7070Spatrick                                                     unsigned NumArgs,
1818a9ac8606Spatrick                                                     bool HasFPFeatures,
1819e5dd7070Spatrick                                                     EmptyShell Empty) {
1820e5dd7070Spatrick   // Allocate storage for the trailing objects of CallExpr.
1821a9ac8606Spatrick   unsigned SizeOfTrailingObjects = CallExpr::sizeOfTrailingObjects(
1822a9ac8606Spatrick       /*NumPreArgs=*/END_PREARG, NumArgs, HasFPFeatures);
1823e5dd7070Spatrick   void *Mem = Ctx.Allocate(sizeof(CUDAKernelCallExpr) + SizeOfTrailingObjects,
1824e5dd7070Spatrick                            alignof(CUDAKernelCallExpr));
1825a9ac8606Spatrick   return new (Mem) CUDAKernelCallExpr(NumArgs, HasFPFeatures, Empty);
1826e5dd7070Spatrick }
1827*12c85518Srobert 
1828*12c85518Srobert CXXParenListInitExpr *
Create(ASTContext & C,ArrayRef<Expr * > Args,QualType T,unsigned NumUserSpecifiedExprs,SourceLocation InitLoc,SourceLocation LParenLoc,SourceLocation RParenLoc)1829*12c85518Srobert CXXParenListInitExpr::Create(ASTContext &C, ArrayRef<Expr *> Args, QualType T,
1830*12c85518Srobert                              unsigned NumUserSpecifiedExprs,
1831*12c85518Srobert                              SourceLocation InitLoc, SourceLocation LParenLoc,
1832*12c85518Srobert                              SourceLocation RParenLoc) {
1833*12c85518Srobert   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(Args.size()));
1834*12c85518Srobert   return new (Mem) CXXParenListInitExpr(Args, T, NumUserSpecifiedExprs, InitLoc,
1835*12c85518Srobert                                         LParenLoc, RParenLoc);
1836*12c85518Srobert }
1837*12c85518Srobert 
CreateEmpty(ASTContext & C,unsigned NumExprs,EmptyShell Empty)1838*12c85518Srobert CXXParenListInitExpr *CXXParenListInitExpr::CreateEmpty(ASTContext &C,
1839*12c85518Srobert                                                         unsigned NumExprs,
1840*12c85518Srobert                                                         EmptyShell Empty) {
1841*12c85518Srobert   void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(NumExprs),
1842*12c85518Srobert                          alignof(CXXParenListInitExpr));
1843*12c85518Srobert   return new (Mem) CXXParenListInitExpr(Empty, NumExprs);
1844*12c85518Srobert }
1845