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