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