summaryrefslogtreecommitdiffstats
path: root/include/clang/AST/ExprCXX.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/AST/ExprCXX.h')
-rw-r--r--include/clang/AST/ExprCXX.h4179
1 files changed, 0 insertions, 4179 deletions
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
deleted file mode 100644
index 0608aba..0000000
--- a/include/clang/AST/ExprCXX.h
+++ /dev/null
@@ -1,4179 +0,0 @@
-//===--- ExprCXX.h - Classes for representing expressions -------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief Defines the clang::Expr interface and subclasses for C++ expressions.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_EXPRCXX_H
-#define LLVM_CLANG_AST_EXPRCXX_H
-
-#include "clang/AST/Decl.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/LambdaCapture.h"
-#include "clang/AST/TemplateBase.h"
-#include "clang/AST/UnresolvedSet.h"
-#include "clang/Basic/ExpressionTraits.h"
-#include "clang/Basic/TypeTraits.h"
-#include "llvm/Support/Compiler.h"
-
-namespace clang {
-
-class CXXConstructorDecl;
-class CXXDestructorDecl;
-class CXXMethodDecl;
-class CXXTemporary;
-class MSPropertyDecl;
-class TemplateArgumentListInfo;
-class UuidAttr;
-
-//===--------------------------------------------------------------------===//
-// C++ Expressions.
-//===--------------------------------------------------------------------===//
-
-/// \brief A call to an overloaded operator written using operator
-/// syntax.
-///
-/// Represents a call to an overloaded operator written using operator
-/// syntax, e.g., "x + y" or "*p". While semantically equivalent to a
-/// normal call, this AST node provides better information about the
-/// syntactic representation of the call.
-///
-/// In a C++ template, this expression node kind will be used whenever
-/// any of the arguments are type-dependent. In this case, the
-/// function itself will be a (possibly empty) set of functions and
-/// function templates that were found by name lookup at template
-/// definition time.
-class CXXOperatorCallExpr : public CallExpr {
- /// \brief The overloaded operator.
- OverloadedOperatorKind Operator;
- SourceRange Range;
-
- // Record the FP_CONTRACT state that applies to this operator call. Only
- // meaningful for floating point types. For other types this value can be
- // set to false.
- unsigned FPContractable : 1;
-
- SourceRange getSourceRangeImpl() const LLVM_READONLY;
-public:
- CXXOperatorCallExpr(ASTContext& C, OverloadedOperatorKind Op, Expr *fn,
- ArrayRef<Expr*> args, QualType t, ExprValueKind VK,
- SourceLocation operatorloc, bool fpContractable)
- : CallExpr(C, CXXOperatorCallExprClass, fn, 0, args, t, VK,
- operatorloc),
- Operator(Op), FPContractable(fpContractable) {
- Range = getSourceRangeImpl();
- }
- explicit CXXOperatorCallExpr(ASTContext& C, EmptyShell Empty) :
- CallExpr(C, CXXOperatorCallExprClass, Empty) { }
-
-
- /// \brief Returns the kind of overloaded operator that this
- /// expression refers to.
- OverloadedOperatorKind getOperator() const { return Operator; }
-
- /// \brief Returns the location of the operator symbol in the expression.
- ///
- /// When \c getOperator()==OO_Call, this is the location of the right
- /// parentheses; when \c getOperator()==OO_Subscript, this is the location
- /// of the right bracket.
- SourceLocation getOperatorLoc() const { return getRParenLoc(); }
-
- SourceLocation getExprLoc() const LLVM_READONLY {
- return (Operator < OO_Plus || Operator >= OO_Arrow ||
- Operator == OO_PlusPlus || Operator == OO_MinusMinus)
- ? getLocStart()
- : getOperatorLoc();
- }
-
- SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
- SourceRange getSourceRange() const { return Range; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXOperatorCallExprClass;
- }
-
- // Set the FP contractability status of this operator. Only meaningful for
- // operations on floating point types.
- void setFPContractable(bool FPC) { FPContractable = FPC; }
-
- // Get the FP contractability status of this operator. Only meaningful for
- // operations on floating point types.
- bool isFPContractable() const { return FPContractable; }
-
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-};
-
-/// Represents a call to a member function that
-/// may be written either with member call syntax (e.g., "obj.func()"
-/// or "objptr->func()") or with normal function-call syntax
-/// ("func()") within a member function that ends up calling a member
-/// function. The callee in either case is a MemberExpr that contains
-/// both the object argument and the member function, while the
-/// arguments are the arguments within the parentheses (not including
-/// the object argument).
-class CXXMemberCallExpr : public CallExpr {
-public:
- CXXMemberCallExpr(ASTContext &C, Expr *fn, ArrayRef<Expr*> args,
- QualType t, ExprValueKind VK, SourceLocation RP)
- : CallExpr(C, CXXMemberCallExprClass, fn, 0, args, t, VK, RP) {}
-
- CXXMemberCallExpr(ASTContext &C, EmptyShell Empty)
- : CallExpr(C, CXXMemberCallExprClass, Empty) { }
-
- /// \brief Retrieves the implicit object argument for the member call.
- ///
- /// For example, in "x.f(5)", this returns the sub-expression "x".
- Expr *getImplicitObjectArgument() const;
-
- /// \brief Retrieves the declaration of the called method.
- CXXMethodDecl *getMethodDecl() const;
-
- /// \brief Retrieves the CXXRecordDecl for the underlying type of
- /// the implicit object argument.
- ///
- /// Note that this is may not be the same declaration as that of the class
- /// context of the CXXMethodDecl which this function is calling.
- /// FIXME: Returns 0 for member pointer call exprs.
- CXXRecordDecl *getRecordDecl() const;
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXMemberCallExprClass;
- }
-};
-
-/// \brief Represents a call to a CUDA kernel function.
-class CUDAKernelCallExpr : public CallExpr {
-private:
- enum { CONFIG, END_PREARG };
-
-public:
- CUDAKernelCallExpr(ASTContext &C, Expr *fn, CallExpr *Config,
- ArrayRef<Expr*> args, QualType t, ExprValueKind VK,
- SourceLocation RP)
- : CallExpr(C, CUDAKernelCallExprClass, fn, END_PREARG, args, t, VK, RP) {
- setConfig(Config);
- }
-
- CUDAKernelCallExpr(ASTContext &C, EmptyShell Empty)
- : CallExpr(C, CUDAKernelCallExprClass, END_PREARG, Empty) { }
-
- const CallExpr *getConfig() const {
- return cast_or_null<CallExpr>(getPreArg(CONFIG));
- }
- CallExpr *getConfig() { return cast_or_null<CallExpr>(getPreArg(CONFIG)); }
- void setConfig(CallExpr *E) { setPreArg(CONFIG, E); }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CUDAKernelCallExprClass;
- }
-};
-
-/// \brief Abstract class common to all of the C++ "named"/"keyword" casts.
-///
-/// This abstract class is inherited by all of the classes
-/// representing "named" casts: CXXStaticCastExpr for \c static_cast,
-/// CXXDynamicCastExpr for \c dynamic_cast, CXXReinterpretCastExpr for
-/// reinterpret_cast, and CXXConstCastExpr for \c const_cast.
-class CXXNamedCastExpr : public ExplicitCastExpr {
-private:
- SourceLocation Loc; // the location of the casting op
- SourceLocation RParenLoc; // the location of the right parenthesis
- SourceRange AngleBrackets; // range for '<' '>'
-
-protected:
- CXXNamedCastExpr(StmtClass SC, QualType ty, ExprValueKind VK,
- CastKind kind, Expr *op, unsigned PathSize,
- TypeSourceInfo *writtenTy, SourceLocation l,
- SourceLocation RParenLoc,
- SourceRange AngleBrackets)
- : ExplicitCastExpr(SC, ty, VK, kind, op, PathSize, writtenTy), Loc(l),
- RParenLoc(RParenLoc), AngleBrackets(AngleBrackets) {}
-
- explicit CXXNamedCastExpr(StmtClass SC, EmptyShell Shell, unsigned PathSize)
- : ExplicitCastExpr(SC, Shell, PathSize) { }
-
- friend class ASTStmtReader;
-
-public:
- const char *getCastName() const;
-
- /// \brief Retrieve the location of the cast operator keyword, e.g.,
- /// \c static_cast.
- SourceLocation getOperatorLoc() const { return Loc; }
-
- /// \brief Retrieve the location of the closing parenthesis.
- SourceLocation getRParenLoc() const { return RParenLoc; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
- SourceRange getAngleBrackets() const LLVM_READONLY { return AngleBrackets; }
-
- static bool classof(const Stmt *T) {
- switch (T->getStmtClass()) {
- case CXXStaticCastExprClass:
- case CXXDynamicCastExprClass:
- case CXXReinterpretCastExprClass:
- case CXXConstCastExprClass:
- return true;
- default:
- return false;
- }
- }
-};
-
-/// \brief A C++ \c static_cast expression (C++ [expr.static.cast]).
-///
-/// This expression node represents a C++ static cast, e.g.,
-/// \c static_cast<int>(1.0).
-class CXXStaticCastExpr final
- : public CXXNamedCastExpr,
- private llvm::TrailingObjects<CXXStaticCastExpr, CXXBaseSpecifier *> {
- CXXStaticCastExpr(QualType ty, ExprValueKind vk, CastKind kind, Expr *op,
- unsigned pathSize, TypeSourceInfo *writtenTy,
- SourceLocation l, SourceLocation RParenLoc,
- SourceRange AngleBrackets)
- : CXXNamedCastExpr(CXXStaticCastExprClass, ty, vk, kind, op, pathSize,
- writtenTy, l, RParenLoc, AngleBrackets) {}
-
- explicit CXXStaticCastExpr(EmptyShell Empty, unsigned PathSize)
- : CXXNamedCastExpr(CXXStaticCastExprClass, Empty, PathSize) { }
-
-public:
- static CXXStaticCastExpr *Create(const ASTContext &Context, QualType T,
- ExprValueKind VK, CastKind K, Expr *Op,
- const CXXCastPath *Path,
- TypeSourceInfo *Written, SourceLocation L,
- SourceLocation RParenLoc,
- SourceRange AngleBrackets);
- static CXXStaticCastExpr *CreateEmpty(const ASTContext &Context,
- unsigned PathSize);
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXStaticCastExprClass;
- }
-
- friend TrailingObjects;
- friend class CastExpr;
-};
-
-/// \brief A C++ @c dynamic_cast expression (C++ [expr.dynamic.cast]).
-///
-/// This expression node represents a dynamic cast, e.g.,
-/// \c dynamic_cast<Derived*>(BasePtr). Such a cast may perform a run-time
-/// check to determine how to perform the type conversion.
-class CXXDynamicCastExpr final
- : public CXXNamedCastExpr,
- private llvm::TrailingObjects<CXXDynamicCastExpr, CXXBaseSpecifier *> {
- CXXDynamicCastExpr(QualType ty, ExprValueKind VK, CastKind kind,
- Expr *op, unsigned pathSize, TypeSourceInfo *writtenTy,
- SourceLocation l, SourceLocation RParenLoc,
- SourceRange AngleBrackets)
- : CXXNamedCastExpr(CXXDynamicCastExprClass, ty, VK, kind, op, pathSize,
- writtenTy, l, RParenLoc, AngleBrackets) {}
-
- explicit CXXDynamicCastExpr(EmptyShell Empty, unsigned pathSize)
- : CXXNamedCastExpr(CXXDynamicCastExprClass, Empty, pathSize) { }
-
-public:
- static CXXDynamicCastExpr *Create(const ASTContext &Context, QualType T,
- ExprValueKind VK, CastKind Kind, Expr *Op,
- const CXXCastPath *Path,
- TypeSourceInfo *Written, SourceLocation L,
- SourceLocation RParenLoc,
- SourceRange AngleBrackets);
-
- static CXXDynamicCastExpr *CreateEmpty(const ASTContext &Context,
- unsigned pathSize);
-
- bool isAlwaysNull() const;
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXDynamicCastExprClass;
- }
-
- friend TrailingObjects;
- friend class CastExpr;
-};
-
-/// \brief A C++ @c reinterpret_cast expression (C++ [expr.reinterpret.cast]).
-///
-/// This expression node represents a reinterpret cast, e.g.,
-/// @c reinterpret_cast<int>(VoidPtr).
-///
-/// A reinterpret_cast provides a differently-typed view of a value but
-/// (in Clang, as in most C++ implementations) performs no actual work at
-/// run time.
-class CXXReinterpretCastExpr final
- : public CXXNamedCastExpr,
- private llvm::TrailingObjects<CXXReinterpretCastExpr,
- CXXBaseSpecifier *> {
- CXXReinterpretCastExpr(QualType ty, ExprValueKind vk, CastKind kind,
- Expr *op, unsigned pathSize,
- TypeSourceInfo *writtenTy, SourceLocation l,
- SourceLocation RParenLoc,
- SourceRange AngleBrackets)
- : CXXNamedCastExpr(CXXReinterpretCastExprClass, ty, vk, kind, op,
- pathSize, writtenTy, l, RParenLoc, AngleBrackets) {}
-
- CXXReinterpretCastExpr(EmptyShell Empty, unsigned pathSize)
- : CXXNamedCastExpr(CXXReinterpretCastExprClass, Empty, pathSize) { }
-
-public:
- static CXXReinterpretCastExpr *Create(const ASTContext &Context, QualType T,
- ExprValueKind VK, CastKind Kind,
- Expr *Op, const CXXCastPath *Path,
- TypeSourceInfo *WrittenTy, SourceLocation L,
- SourceLocation RParenLoc,
- SourceRange AngleBrackets);
- static CXXReinterpretCastExpr *CreateEmpty(const ASTContext &Context,
- unsigned pathSize);
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXReinterpretCastExprClass;
- }
-
- friend TrailingObjects;
- friend class CastExpr;
-};
-
-/// \brief A C++ \c const_cast expression (C++ [expr.const.cast]).
-///
-/// This expression node represents a const cast, e.g.,
-/// \c const_cast<char*>(PtrToConstChar).
-///
-/// A const_cast can remove type qualifiers but does not change the underlying
-/// value.
-class CXXConstCastExpr final
- : public CXXNamedCastExpr,
- private llvm::TrailingObjects<CXXConstCastExpr, CXXBaseSpecifier *> {
- CXXConstCastExpr(QualType ty, ExprValueKind VK, Expr *op,
- TypeSourceInfo *writtenTy, SourceLocation l,
- SourceLocation RParenLoc, SourceRange AngleBrackets)
- : CXXNamedCastExpr(CXXConstCastExprClass, ty, VK, CK_NoOp, op,
- 0, writtenTy, l, RParenLoc, AngleBrackets) {}
-
- explicit CXXConstCastExpr(EmptyShell Empty)
- : CXXNamedCastExpr(CXXConstCastExprClass, Empty, 0) { }
-
-public:
- static CXXConstCastExpr *Create(const ASTContext &Context, QualType T,
- ExprValueKind VK, Expr *Op,
- TypeSourceInfo *WrittenTy, SourceLocation L,
- SourceLocation RParenLoc,
- SourceRange AngleBrackets);
- static CXXConstCastExpr *CreateEmpty(const ASTContext &Context);
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXConstCastExprClass;
- }
-
- friend TrailingObjects;
- friend class CastExpr;
-};
-
-/// \brief A call to a literal operator (C++11 [over.literal])
-/// written as a user-defined literal (C++11 [lit.ext]).
-///
-/// Represents a user-defined literal, e.g. "foo"_bar or 1.23_xyz. While this
-/// is semantically equivalent to a normal call, this AST node provides better
-/// information about the syntactic representation of the literal.
-///
-/// Since literal operators are never found by ADL and can only be declared at
-/// namespace scope, a user-defined literal is never dependent.
-class UserDefinedLiteral : public CallExpr {
- /// \brief The location of a ud-suffix within the literal.
- SourceLocation UDSuffixLoc;
-
-public:
- UserDefinedLiteral(const ASTContext &C, Expr *Fn, ArrayRef<Expr*> Args,
- QualType T, ExprValueKind VK, SourceLocation LitEndLoc,
- SourceLocation SuffixLoc)
- : CallExpr(C, UserDefinedLiteralClass, Fn, 0, Args, T, VK, LitEndLoc),
- UDSuffixLoc(SuffixLoc) {}
- explicit UserDefinedLiteral(const ASTContext &C, EmptyShell Empty)
- : CallExpr(C, UserDefinedLiteralClass, Empty) {}
-
- /// The kind of literal operator which is invoked.
- enum LiteralOperatorKind {
- LOK_Raw, ///< Raw form: operator "" X (const char *)
- LOK_Template, ///< Raw form: operator "" X<cs...> ()
- LOK_Integer, ///< operator "" X (unsigned long long)
- LOK_Floating, ///< operator "" X (long double)
- LOK_String, ///< operator "" X (const CharT *, size_t)
- LOK_Character ///< operator "" X (CharT)
- };
-
- /// \brief Returns the kind of literal operator invocation
- /// which this expression represents.
- LiteralOperatorKind getLiteralOperatorKind() const;
-
- /// \brief If this is not a raw user-defined literal, get the
- /// underlying cooked literal (representing the literal with the suffix
- /// removed).
- Expr *getCookedLiteral();
- const Expr *getCookedLiteral() const {
- return const_cast<UserDefinedLiteral*>(this)->getCookedLiteral();
- }
-
- SourceLocation getLocStart() const {
- if (getLiteralOperatorKind() == LOK_Template)
- return getRParenLoc();
- return getArg(0)->getLocStart();
- }
- SourceLocation getLocEnd() const { return getRParenLoc(); }
-
-
- /// \brief Returns the location of a ud-suffix in the expression.
- ///
- /// For a string literal, there may be multiple identical suffixes. This
- /// returns the first.
- SourceLocation getUDSuffixLoc() const { return UDSuffixLoc; }
-
- /// \brief Returns the ud-suffix specified for this literal.
- const IdentifierInfo *getUDSuffix() const;
-
- static bool classof(const Stmt *S) {
- return S->getStmtClass() == UserDefinedLiteralClass;
- }
-
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-};
-
-/// \brief A boolean literal, per ([C++ lex.bool] Boolean literals).
-///
-class CXXBoolLiteralExpr : public Expr {
- bool Value;
- SourceLocation Loc;
-public:
- CXXBoolLiteralExpr(bool val, QualType Ty, SourceLocation l) :
- Expr(CXXBoolLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, false,
- false, false),
- Value(val), Loc(l) {}
-
- explicit CXXBoolLiteralExpr(EmptyShell Empty)
- : Expr(CXXBoolLiteralExprClass, Empty) { }
-
- bool getValue() const { return Value; }
- void setValue(bool V) { Value = V; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
-
- SourceLocation getLocation() const { return Loc; }
- void setLocation(SourceLocation L) { Loc = L; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXBoolLiteralExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// \brief The null pointer literal (C++11 [lex.nullptr])
-///
-/// Introduced in C++11, the only literal of type \c nullptr_t is \c nullptr.
-class CXXNullPtrLiteralExpr : public Expr {
- SourceLocation Loc;
-public:
- CXXNullPtrLiteralExpr(QualType Ty, SourceLocation l) :
- Expr(CXXNullPtrLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, false,
- false, false),
- Loc(l) {}
-
- explicit CXXNullPtrLiteralExpr(EmptyShell Empty)
- : Expr(CXXNullPtrLiteralExprClass, Empty) { }
-
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
-
- SourceLocation getLocation() const { return Loc; }
- void setLocation(SourceLocation L) { Loc = L; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXNullPtrLiteralExprClass;
- }
-
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// \brief Implicit construction of a std::initializer_list<T> object from an
-/// array temporary within list-initialization (C++11 [dcl.init.list]p5).
-class CXXStdInitializerListExpr : public Expr {
- Stmt *SubExpr;
-
- CXXStdInitializerListExpr(EmptyShell Empty)
- : Expr(CXXStdInitializerListExprClass, Empty), SubExpr(nullptr) {}
-
-public:
- CXXStdInitializerListExpr(QualType Ty, Expr *SubExpr)
- : Expr(CXXStdInitializerListExprClass, Ty, VK_RValue, OK_Ordinary,
- Ty->isDependentType(), SubExpr->isValueDependent(),
- SubExpr->isInstantiationDependent(),
- SubExpr->containsUnexpandedParameterPack()),
- SubExpr(SubExpr) {}
-
- Expr *getSubExpr() { return static_cast<Expr*>(SubExpr); }
- const Expr *getSubExpr() const { return static_cast<const Expr*>(SubExpr); }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return SubExpr->getLocStart();
- }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return SubExpr->getLocEnd();
- }
- SourceRange getSourceRange() const LLVM_READONLY {
- return SubExpr->getSourceRange();
- }
-
- static bool classof(const Stmt *S) {
- return S->getStmtClass() == CXXStdInitializerListExprClass;
- }
-
- child_range children() { return child_range(&SubExpr, &SubExpr + 1); }
-
- friend class ASTReader;
- friend class ASTStmtReader;
-};
-
-/// A C++ \c typeid expression (C++ [expr.typeid]), which gets
-/// the \c type_info that corresponds to the supplied type, or the (possibly
-/// dynamic) type of the supplied expression.
-///
-/// This represents code like \c typeid(int) or \c typeid(*objPtr)
-class CXXTypeidExpr : public Expr {
-private:
- llvm::PointerUnion<Stmt *, TypeSourceInfo *> Operand;
- SourceRange Range;
-
-public:
- CXXTypeidExpr(QualType Ty, TypeSourceInfo *Operand, SourceRange R)
- : Expr(CXXTypeidExprClass, Ty, VK_LValue, OK_Ordinary,
- // typeid is never type-dependent (C++ [temp.dep.expr]p4)
- false,
- // typeid is value-dependent if the type or expression are dependent
- Operand->getType()->isDependentType(),
- Operand->getType()->isInstantiationDependentType(),
- Operand->getType()->containsUnexpandedParameterPack()),
- Operand(Operand), Range(R) { }
-
- CXXTypeidExpr(QualType Ty, Expr *Operand, SourceRange R)
- : Expr(CXXTypeidExprClass, Ty, VK_LValue, OK_Ordinary,
- // typeid is never type-dependent (C++ [temp.dep.expr]p4)
- false,
- // typeid is value-dependent if the type or expression are dependent
- Operand->isTypeDependent() || Operand->isValueDependent(),
- Operand->isInstantiationDependent(),
- Operand->containsUnexpandedParameterPack()),
- Operand(Operand), Range(R) { }
-
- CXXTypeidExpr(EmptyShell Empty, bool isExpr)
- : Expr(CXXTypeidExprClass, Empty) {
- if (isExpr)
- Operand = (Expr*)nullptr;
- else
- Operand = (TypeSourceInfo*)nullptr;
- }
-
- /// Determine whether this typeid has a type operand which is potentially
- /// evaluated, per C++11 [expr.typeid]p3.
- bool isPotentiallyEvaluated() const;
-
- bool isTypeOperand() const { return Operand.is<TypeSourceInfo *>(); }
-
- /// \brief Retrieves the type operand of this typeid() expression after
- /// various required adjustments (removing reference types, cv-qualifiers).
- QualType getTypeOperand(ASTContext &Context) const;
-
- /// \brief Retrieve source information for the type operand.
- TypeSourceInfo *getTypeOperandSourceInfo() const {
- assert(isTypeOperand() && "Cannot call getTypeOperand for typeid(expr)");
- return Operand.get<TypeSourceInfo *>();
- }
-
- void setTypeOperandSourceInfo(TypeSourceInfo *TSI) {
- assert(isTypeOperand() && "Cannot call getTypeOperand for typeid(expr)");
- Operand = TSI;
- }
-
- Expr *getExprOperand() const {
- assert(!isTypeOperand() && "Cannot call getExprOperand for typeid(type)");
- return static_cast<Expr*>(Operand.get<Stmt *>());
- }
-
- void setExprOperand(Expr *E) {
- assert(!isTypeOperand() && "Cannot call getExprOperand for typeid(type)");
- Operand = E;
- }
-
- SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
- SourceRange getSourceRange() const LLVM_READONLY { return Range; }
- void setSourceRange(SourceRange R) { Range = R; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXTypeidExprClass;
- }
-
- // Iterators
- child_range children() {
- if (isTypeOperand())
- return child_range(child_iterator(), child_iterator());
- Stmt **begin = reinterpret_cast<Stmt**>(&Operand);
- return child_range(begin, begin + 1);
- }
-};
-
-/// \brief A member reference to an MSPropertyDecl.
-///
-/// This expression always has pseudo-object type, and therefore it is
-/// typically not encountered in a fully-typechecked expression except
-/// within the syntactic form of a PseudoObjectExpr.
-class MSPropertyRefExpr : public Expr {
- Expr *BaseExpr;
- MSPropertyDecl *TheDecl;
- SourceLocation MemberLoc;
- bool IsArrow;
- NestedNameSpecifierLoc QualifierLoc;
-
-public:
- MSPropertyRefExpr(Expr *baseExpr, MSPropertyDecl *decl, bool isArrow,
- QualType ty, ExprValueKind VK,
- NestedNameSpecifierLoc qualifierLoc,
- SourceLocation nameLoc)
- : Expr(MSPropertyRefExprClass, ty, VK, OK_Ordinary,
- /*type-dependent*/ false, baseExpr->isValueDependent(),
- baseExpr->isInstantiationDependent(),
- baseExpr->containsUnexpandedParameterPack()),
- BaseExpr(baseExpr), TheDecl(decl),
- MemberLoc(nameLoc), IsArrow(isArrow),
- QualifierLoc(qualifierLoc) {}
-
- MSPropertyRefExpr(EmptyShell Empty) : Expr(MSPropertyRefExprClass, Empty) {}
-
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(getLocStart(), getLocEnd());
- }
- bool isImplicitAccess() const {
- return getBaseExpr() && getBaseExpr()->isImplicitCXXThis();
- }
- SourceLocation getLocStart() const {
- if (!isImplicitAccess())
- return BaseExpr->getLocStart();
- else if (QualifierLoc)
- return QualifierLoc.getBeginLoc();
- else
- return MemberLoc;
- }
- SourceLocation getLocEnd() const { return getMemberLoc(); }
-
- child_range children() {
- return child_range((Stmt**)&BaseExpr, (Stmt**)&BaseExpr + 1);
- }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == MSPropertyRefExprClass;
- }
-
- Expr *getBaseExpr() const { return BaseExpr; }
- MSPropertyDecl *getPropertyDecl() const { return TheDecl; }
- bool isArrow() const { return IsArrow; }
- SourceLocation getMemberLoc() const { return MemberLoc; }
- NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
-
- friend class ASTStmtReader;
-};
-
-/// MS property subscript expression.
-/// MSVC supports 'property' attribute and allows to apply it to the
-/// declaration of an empty array in a class or structure definition.
-/// For example:
-/// \code
-/// __declspec(property(get=GetX, put=PutX)) int x[];
-/// \endcode
-/// The above statement indicates that x[] can be used with one or more array
-/// indices. In this case, i=p->x[a][b] will be turned into i=p->GetX(a, b), and
-/// p->x[a][b] = i will be turned into p->PutX(a, b, i).
-/// This is a syntactic pseudo-object expression.
-class MSPropertySubscriptExpr : public Expr {
- friend class ASTStmtReader;
- enum { BASE_EXPR, IDX_EXPR, NUM_SUBEXPRS = 2 };
- Stmt *SubExprs[NUM_SUBEXPRS];
- SourceLocation RBracketLoc;
-
- void setBase(Expr *Base) { SubExprs[BASE_EXPR] = Base; }
- void setIdx(Expr *Idx) { SubExprs[IDX_EXPR] = Idx; }
-
-public:
- MSPropertySubscriptExpr(Expr *Base, Expr *Idx, QualType Ty, ExprValueKind VK,
- ExprObjectKind OK, SourceLocation RBracketLoc)
- : Expr(MSPropertySubscriptExprClass, Ty, VK, OK, Idx->isTypeDependent(),
- Idx->isValueDependent(), Idx->isInstantiationDependent(),
- Idx->containsUnexpandedParameterPack()),
- RBracketLoc(RBracketLoc) {
- SubExprs[BASE_EXPR] = Base;
- SubExprs[IDX_EXPR] = Idx;
- }
-
- /// \brief Create an empty array subscript expression.
- explicit MSPropertySubscriptExpr(EmptyShell Shell)
- : Expr(MSPropertySubscriptExprClass, Shell) {}
-
- Expr *getBase() { return cast<Expr>(SubExprs[BASE_EXPR]); }
- const Expr *getBase() const { return cast<Expr>(SubExprs[BASE_EXPR]); }
-
- Expr *getIdx() { return cast<Expr>(SubExprs[IDX_EXPR]); }
- const Expr *getIdx() const { return cast<Expr>(SubExprs[IDX_EXPR]); }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return getBase()->getLocStart();
- }
- SourceLocation getLocEnd() const LLVM_READONLY { return RBracketLoc; }
-
- SourceLocation getRBracketLoc() const { return RBracketLoc; }
- void setRBracketLoc(SourceLocation L) { RBracketLoc = L; }
-
- SourceLocation getExprLoc() const LLVM_READONLY {
- return getBase()->getExprLoc();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == MSPropertySubscriptExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(&SubExprs[0], &SubExprs[0] + NUM_SUBEXPRS);
- }
-};
-
-/// A Microsoft C++ @c __uuidof expression, which gets
-/// the _GUID that corresponds to the supplied type or expression.
-///
-/// This represents code like @c __uuidof(COMTYPE) or @c __uuidof(*comPtr)
-class CXXUuidofExpr : public Expr {
-private:
- llvm::PointerUnion<Stmt *, TypeSourceInfo *> Operand;
- SourceRange Range;
-
-public:
- CXXUuidofExpr(QualType Ty, TypeSourceInfo *Operand, SourceRange R)
- : Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary,
- false, Operand->getType()->isDependentType(),
- Operand->getType()->isInstantiationDependentType(),
- Operand->getType()->containsUnexpandedParameterPack()),
- Operand(Operand), Range(R) { }
-
- CXXUuidofExpr(QualType Ty, Expr *Operand, SourceRange R)
- : Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary,
- false, Operand->isTypeDependent(),
- Operand->isInstantiationDependent(),
- Operand->containsUnexpandedParameterPack()),
- Operand(Operand), Range(R) { }
-
- CXXUuidofExpr(EmptyShell Empty, bool isExpr)
- : Expr(CXXUuidofExprClass, Empty) {
- if (isExpr)
- Operand = (Expr*)nullptr;
- else
- Operand = (TypeSourceInfo*)nullptr;
- }
-
- bool isTypeOperand() const { return Operand.is<TypeSourceInfo *>(); }
-
- /// \brief Retrieves the type operand of this __uuidof() expression after
- /// various required adjustments (removing reference types, cv-qualifiers).
- QualType getTypeOperand(ASTContext &Context) const;
-
- /// \brief Retrieve source information for the type operand.
- TypeSourceInfo *getTypeOperandSourceInfo() const {
- assert(isTypeOperand() && "Cannot call getTypeOperand for __uuidof(expr)");
- return Operand.get<TypeSourceInfo *>();
- }
-
- void setTypeOperandSourceInfo(TypeSourceInfo *TSI) {
- assert(isTypeOperand() && "Cannot call getTypeOperand for __uuidof(expr)");
- Operand = TSI;
- }
-
- Expr *getExprOperand() const {
- assert(!isTypeOperand() && "Cannot call getExprOperand for __uuidof(type)");
- return static_cast<Expr*>(Operand.get<Stmt *>());
- }
-
- void setExprOperand(Expr *E) {
- assert(!isTypeOperand() && "Cannot call getExprOperand for __uuidof(type)");
- Operand = E;
- }
-
- StringRef getUuidAsStringRef(ASTContext &Context) const;
-
- SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
- SourceRange getSourceRange() const LLVM_READONLY { return Range; }
- void setSourceRange(SourceRange R) { Range = R; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXUuidofExprClass;
- }
-
- /// Grabs __declspec(uuid()) off a type, or returns 0 if we cannot resolve to
- /// a single GUID.
- static const UuidAttr *GetUuidAttrOfType(QualType QT,
- bool *HasMultipleGUIDsPtr = nullptr);
-
- // Iterators
- child_range children() {
- if (isTypeOperand())
- return child_range(child_iterator(), child_iterator());
- Stmt **begin = reinterpret_cast<Stmt**>(&Operand);
- return child_range(begin, begin + 1);
- }
-};
-
-/// \brief Represents the \c this expression in C++.
-///
-/// This is a pointer to the object on which the current member function is
-/// executing (C++ [expr.prim]p3). Example:
-///
-/// \code
-/// class Foo {
-/// public:
-/// void bar();
-/// void test() { this->bar(); }
-/// };
-/// \endcode
-class CXXThisExpr : public Expr {
- SourceLocation Loc;
- bool Implicit : 1;
-
-public:
- CXXThisExpr(SourceLocation L, QualType Type, bool isImplicit)
- : Expr(CXXThisExprClass, Type, VK_RValue, OK_Ordinary,
- // 'this' is type-dependent if the class type of the enclosing
- // member function is dependent (C++ [temp.dep.expr]p2)
- Type->isDependentType(), Type->isDependentType(),
- Type->isInstantiationDependentType(),
- /*ContainsUnexpandedParameterPack=*/false),
- Loc(L), Implicit(isImplicit) { }
-
- CXXThisExpr(EmptyShell Empty) : Expr(CXXThisExprClass, Empty) {}
-
- SourceLocation getLocation() const { return Loc; }
- void setLocation(SourceLocation L) { Loc = L; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
-
- bool isImplicit() const { return Implicit; }
- void setImplicit(bool I) { Implicit = I; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXThisExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// \brief A C++ throw-expression (C++ [except.throw]).
-///
-/// This handles 'throw' (for re-throwing the current exception) and
-/// 'throw' assignment-expression. When assignment-expression isn't
-/// present, Op will be null.
-class CXXThrowExpr : public Expr {
- Stmt *Op;
- SourceLocation ThrowLoc;
- /// \brief Whether the thrown variable (if any) is in scope.
- unsigned IsThrownVariableInScope : 1;
-
- friend class ASTStmtReader;
-
-public:
- // \p Ty is the void type which is used as the result type of the
- // expression. The \p l is the location of the throw keyword. \p expr
- // can by null, if the optional expression to throw isn't present.
- CXXThrowExpr(Expr *expr, QualType Ty, SourceLocation l,
- bool IsThrownVariableInScope) :
- Expr(CXXThrowExprClass, Ty, VK_RValue, OK_Ordinary, false, false,
- expr && expr->isInstantiationDependent(),
- expr && expr->containsUnexpandedParameterPack()),
- Op(expr), ThrowLoc(l), IsThrownVariableInScope(IsThrownVariableInScope) {}
- CXXThrowExpr(EmptyShell Empty) : Expr(CXXThrowExprClass, Empty) {}
-
- const Expr *getSubExpr() const { return cast_or_null<Expr>(Op); }
- Expr *getSubExpr() { return cast_or_null<Expr>(Op); }
-
- SourceLocation getThrowLoc() const { return ThrowLoc; }
-
- /// \brief Determines whether the variable thrown by this expression (if any!)
- /// is within the innermost try block.
- ///
- /// This information is required to determine whether the NRVO can apply to
- /// this variable.
- bool isThrownVariableInScope() const { return IsThrownVariableInScope; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return ThrowLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY {
- if (!getSubExpr())
- return ThrowLoc;
- return getSubExpr()->getLocEnd();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXThrowExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(&Op, Op ? &Op+1 : &Op);
- }
-};
-
-/// \brief A default argument (C++ [dcl.fct.default]).
-///
-/// This wraps up a function call argument that was created from the
-/// corresponding parameter's default argument, when the call did not
-/// explicitly supply arguments for all of the parameters.
-class CXXDefaultArgExpr final
- : public Expr,
- private llvm::TrailingObjects<CXXDefaultArgExpr, Expr *> {
- /// \brief The parameter whose default is being used.
- ///
- /// When the bit is set, the subexpression is stored after the
- /// CXXDefaultArgExpr itself. When the bit is clear, the parameter's
- /// actual default expression is the subexpression.
- llvm::PointerIntPair<ParmVarDecl *, 1, bool> Param;
-
- /// \brief The location where the default argument expression was used.
- SourceLocation Loc;
-
- CXXDefaultArgExpr(StmtClass SC, SourceLocation Loc, ParmVarDecl *param)
- : Expr(SC,
- param->hasUnparsedDefaultArg()
- ? param->getType().getNonReferenceType()
- : param->getDefaultArg()->getType(),
- param->getDefaultArg()->getValueKind(),
- param->getDefaultArg()->getObjectKind(), false, false, false, false),
- Param(param, false), Loc(Loc) { }
-
- CXXDefaultArgExpr(StmtClass SC, SourceLocation Loc, ParmVarDecl *param,
- Expr *SubExpr)
- : Expr(SC, SubExpr->getType(),
- SubExpr->getValueKind(), SubExpr->getObjectKind(),
- false, false, false, false),
- Param(param, true), Loc(Loc) {
- *getTrailingObjects<Expr *>() = SubExpr;
- }
-
-public:
- CXXDefaultArgExpr(EmptyShell Empty) : Expr(CXXDefaultArgExprClass, Empty) {}
-
- // \p Param is the parameter whose default argument is used by this
- // expression.
- static CXXDefaultArgExpr *Create(const ASTContext &C, SourceLocation Loc,
- ParmVarDecl *Param) {
- return new (C) CXXDefaultArgExpr(CXXDefaultArgExprClass, Loc, Param);
- }
-
- // \p Param is the parameter whose default argument is used by this
- // expression, and \p SubExpr is the expression that will actually be used.
- static CXXDefaultArgExpr *Create(const ASTContext &C, SourceLocation Loc,
- ParmVarDecl *Param, Expr *SubExpr);
-
- // Retrieve the parameter that the argument was created from.
- const ParmVarDecl *getParam() const { return Param.getPointer(); }
- ParmVarDecl *getParam() { return Param.getPointer(); }
-
- // Retrieve the actual argument to the function call.
- const Expr *getExpr() const {
- if (Param.getInt())
- return *getTrailingObjects<Expr *>();
- return getParam()->getDefaultArg();
- }
- Expr *getExpr() {
- if (Param.getInt())
- return *getTrailingObjects<Expr *>();
- return getParam()->getDefaultArg();
- }
-
- /// \brief Retrieve the location where this default argument was actually
- /// used.
- SourceLocation getUsedLocation() const { return Loc; }
-
- /// Default argument expressions have no representation in the
- /// source, so they have an empty source range.
- SourceLocation getLocStart() const LLVM_READONLY { return SourceLocation(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return SourceLocation(); }
-
- SourceLocation getExprLoc() const LLVM_READONLY { return Loc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXDefaultArgExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-
- friend TrailingObjects;
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-};
-
-/// \brief A use of a default initializer in a constructor or in aggregate
-/// initialization.
-///
-/// This wraps a use of a C++ default initializer (technically,
-/// a brace-or-equal-initializer for a non-static data member) when it
-/// is implicitly used in a mem-initializer-list in a constructor
-/// (C++11 [class.base.init]p8) or in aggregate initialization
-/// (C++1y [dcl.init.aggr]p7).
-class CXXDefaultInitExpr : public Expr {
- /// \brief The field whose default is being used.
- FieldDecl *Field;
-
- /// \brief The location where the default initializer expression was used.
- SourceLocation Loc;
-
- CXXDefaultInitExpr(const ASTContext &C, SourceLocation Loc, FieldDecl *Field,
- QualType T);
-
- CXXDefaultInitExpr(EmptyShell Empty) : Expr(CXXDefaultInitExprClass, Empty) {}
-
-public:
- /// \p Field is the non-static data member whose default initializer is used
- /// by this expression.
- static CXXDefaultInitExpr *Create(const ASTContext &C, SourceLocation Loc,
- FieldDecl *Field) {
- return new (C) CXXDefaultInitExpr(C, Loc, Field, Field->getType());
- }
-
- /// \brief Get the field whose initializer will be used.
- FieldDecl *getField() { return Field; }
- const FieldDecl *getField() const { return Field; }
-
- /// \brief Get the initialization expression that will be used.
- const Expr *getExpr() const {
- assert(Field->getInClassInitializer() && "initializer hasn't been parsed");
- return Field->getInClassInitializer();
- }
- Expr *getExpr() {
- assert(Field->getInClassInitializer() && "initializer hasn't been parsed");
- return Field->getInClassInitializer();
- }
-
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXDefaultInitExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-
- friend class ASTReader;
- friend class ASTStmtReader;
-};
-
-/// \brief Represents a C++ temporary.
-class CXXTemporary {
- /// \brief The destructor that needs to be called.
- const CXXDestructorDecl *Destructor;
-
- explicit CXXTemporary(const CXXDestructorDecl *destructor)
- : Destructor(destructor) { }
-
-public:
- static CXXTemporary *Create(const ASTContext &C,
- const CXXDestructorDecl *Destructor);
-
- const CXXDestructorDecl *getDestructor() const { return Destructor; }
- void setDestructor(const CXXDestructorDecl *Dtor) {
- Destructor = Dtor;
- }
-};
-
-/// \brief Represents binding an expression to a temporary.
-///
-/// This ensures the destructor is called for the temporary. It should only be
-/// needed for non-POD, non-trivially destructable class types. For example:
-///
-/// \code
-/// struct S {
-/// S() { } // User defined constructor makes S non-POD.
-/// ~S() { } // User defined destructor makes it non-trivial.
-/// };
-/// void test() {
-/// const S &s_ref = S(); // Requires a CXXBindTemporaryExpr.
-/// }
-/// \endcode
-class CXXBindTemporaryExpr : public Expr {
- CXXTemporary *Temp;
-
- Stmt *SubExpr;
-
- CXXBindTemporaryExpr(CXXTemporary *temp, Expr* SubExpr)
- : Expr(CXXBindTemporaryExprClass, SubExpr->getType(),
- VK_RValue, OK_Ordinary, SubExpr->isTypeDependent(),
- SubExpr->isValueDependent(),
- SubExpr->isInstantiationDependent(),
- SubExpr->containsUnexpandedParameterPack()),
- Temp(temp), SubExpr(SubExpr) { }
-
-public:
- CXXBindTemporaryExpr(EmptyShell Empty)
- : Expr(CXXBindTemporaryExprClass, Empty), Temp(nullptr), SubExpr(nullptr) {}
-
- static CXXBindTemporaryExpr *Create(const ASTContext &C, CXXTemporary *Temp,
- Expr* SubExpr);
-
- CXXTemporary *getTemporary() { return Temp; }
- const CXXTemporary *getTemporary() const { return Temp; }
- void setTemporary(CXXTemporary *T) { Temp = T; }
-
- const Expr *getSubExpr() const { return cast<Expr>(SubExpr); }
- Expr *getSubExpr() { return cast<Expr>(SubExpr); }
- void setSubExpr(Expr *E) { SubExpr = E; }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return SubExpr->getLocStart();
- }
- SourceLocation getLocEnd() const LLVM_READONLY { return SubExpr->getLocEnd();}
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXBindTemporaryExprClass;
- }
-
- // Iterators
- child_range children() { return child_range(&SubExpr, &SubExpr + 1); }
-};
-
-/// \brief Represents a call to a C++ constructor.
-class CXXConstructExpr : public Expr {
-public:
- enum ConstructionKind {
- CK_Complete,
- CK_NonVirtualBase,
- CK_VirtualBase,
- CK_Delegating
- };
-
-private:
- CXXConstructorDecl *Constructor;
-
- SourceLocation Loc;
- SourceRange ParenOrBraceRange;
- unsigned NumArgs : 16;
- bool Elidable : 1;
- bool HadMultipleCandidates : 1;
- bool ListInitialization : 1;
- bool StdInitListInitialization : 1;
- bool ZeroInitialization : 1;
- unsigned ConstructKind : 2;
- Stmt **Args;
-
-protected:
- CXXConstructExpr(const ASTContext &C, StmtClass SC, QualType T,
- SourceLocation Loc,
- CXXConstructorDecl *d, bool elidable,
- ArrayRef<Expr *> Args,
- bool HadMultipleCandidates,
- bool ListInitialization,
- bool StdInitListInitialization,
- bool ZeroInitialization,
- ConstructionKind ConstructKind,
- SourceRange ParenOrBraceRange);
-
- /// \brief Construct an empty C++ construction expression.
- CXXConstructExpr(StmtClass SC, EmptyShell Empty)
- : Expr(SC, Empty), Constructor(nullptr), NumArgs(0), Elidable(false),
- HadMultipleCandidates(false), ListInitialization(false),
- ZeroInitialization(false), ConstructKind(0), Args(nullptr)
- { }
-
-public:
- /// \brief Construct an empty C++ construction expression.
- explicit CXXConstructExpr(EmptyShell Empty)
- : Expr(CXXConstructExprClass, Empty), Constructor(nullptr),
- NumArgs(0), Elidable(false), HadMultipleCandidates(false),
- ListInitialization(false), ZeroInitialization(false),
- ConstructKind(0), Args(nullptr)
- { }
-
- static CXXConstructExpr *Create(const ASTContext &C, QualType T,
- SourceLocation Loc,
- CXXConstructorDecl *D, bool Elidable,
- ArrayRef<Expr *> Args,
- bool HadMultipleCandidates,
- bool ListInitialization,
- bool StdInitListInitialization,
- bool ZeroInitialization,
- ConstructionKind ConstructKind,
- SourceRange ParenOrBraceRange);
-
- CXXConstructorDecl *getConstructor() const { return Constructor; }
- void setConstructor(CXXConstructorDecl *C) { Constructor = C; }
-
- SourceLocation getLocation() const { return Loc; }
- void setLocation(SourceLocation Loc) { this->Loc = Loc; }
-
- /// \brief Whether this construction is elidable.
- bool isElidable() const { return Elidable; }
- void setElidable(bool E) { Elidable = E; }
-
- /// \brief Whether the referred constructor was resolved from
- /// an overloaded set having size greater than 1.
- bool hadMultipleCandidates() const { return HadMultipleCandidates; }
- void setHadMultipleCandidates(bool V) { HadMultipleCandidates = V; }
-
- /// \brief Whether this constructor call was written as list-initialization.
- bool isListInitialization() const { return ListInitialization; }
- void setListInitialization(bool V) { ListInitialization = V; }
-
- /// \brief Whether this constructor call was written as list-initialization,
- /// but was interpreted as forming a std::initializer_list<T> from the list
- /// and passing that as a single constructor argument.
- /// See C++11 [over.match.list]p1 bullet 1.
- bool isStdInitListInitialization() const { return StdInitListInitialization; }
- void setStdInitListInitialization(bool V) { StdInitListInitialization = V; }
-
- /// \brief Whether this construction first requires
- /// zero-initialization before the initializer is called.
- bool requiresZeroInitialization() const { return ZeroInitialization; }
- void setRequiresZeroInitialization(bool ZeroInit) {
- ZeroInitialization = ZeroInit;
- }
-
- /// \brief Determine whether this constructor is actually constructing
- /// a base class (rather than a complete object).
- ConstructionKind getConstructionKind() const {
- return (ConstructionKind)ConstructKind;
- }
- void setConstructionKind(ConstructionKind CK) {
- ConstructKind = CK;
- }
-
- typedef ExprIterator arg_iterator;
- typedef ConstExprIterator const_arg_iterator;
- typedef llvm::iterator_range<arg_iterator> arg_range;
- typedef llvm::iterator_range<const_arg_iterator> arg_const_range;
-
- arg_range arguments() { return arg_range(arg_begin(), arg_end()); }
- arg_const_range arguments() const {
- return arg_const_range(arg_begin(), arg_end());
- }
-
- arg_iterator arg_begin() { return Args; }
- arg_iterator arg_end() { return Args + NumArgs; }
- const_arg_iterator arg_begin() const { return Args; }
- const_arg_iterator arg_end() const { return Args + NumArgs; }
-
- Expr **getArgs() { return reinterpret_cast<Expr **>(Args); }
- const Expr *const *getArgs() const {
- return const_cast<CXXConstructExpr *>(this)->getArgs();
- }
- unsigned getNumArgs() const { return NumArgs; }
-
- /// \brief Return the specified argument.
- Expr *getArg(unsigned Arg) {
- assert(Arg < NumArgs && "Arg access out of range!");
- return cast<Expr>(Args[Arg]);
- }
- const Expr *getArg(unsigned Arg) const {
- assert(Arg < NumArgs && "Arg access out of range!");
- return cast<Expr>(Args[Arg]);
- }
-
- /// \brief Set the specified argument.
- void setArg(unsigned Arg, Expr *ArgExpr) {
- assert(Arg < NumArgs && "Arg access out of range!");
- Args[Arg] = ArgExpr;
- }
-
- SourceLocation getLocStart() const LLVM_READONLY;
- SourceLocation getLocEnd() const LLVM_READONLY;
- SourceRange getParenOrBraceRange() const { return ParenOrBraceRange; }
- void setParenOrBraceRange(SourceRange Range) { ParenOrBraceRange = Range; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXConstructExprClass ||
- T->getStmtClass() == CXXTemporaryObjectExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(&Args[0], &Args[0]+NumArgs);
- }
-
- friend class ASTStmtReader;
-};
-
-/// \brief Represents an explicit C++ type conversion that uses "functional"
-/// notation (C++ [expr.type.conv]).
-///
-/// Example:
-/// \code
-/// x = int(0.5);
-/// \endcode
-class CXXFunctionalCastExpr final
- : public ExplicitCastExpr,
- private llvm::TrailingObjects<CXXFunctionalCastExpr, CXXBaseSpecifier *> {
- SourceLocation LParenLoc;
- SourceLocation RParenLoc;
-
- CXXFunctionalCastExpr(QualType ty, ExprValueKind VK,
- TypeSourceInfo *writtenTy,
- CastKind kind, Expr *castExpr, unsigned pathSize,
- SourceLocation lParenLoc, SourceLocation rParenLoc)
- : ExplicitCastExpr(CXXFunctionalCastExprClass, ty, VK, kind,
- castExpr, pathSize, writtenTy),
- LParenLoc(lParenLoc), RParenLoc(rParenLoc) {}
-
- explicit CXXFunctionalCastExpr(EmptyShell Shell, unsigned PathSize)
- : ExplicitCastExpr(CXXFunctionalCastExprClass, Shell, PathSize) { }
-
-public:
- static CXXFunctionalCastExpr *Create(const ASTContext &Context, QualType T,
- ExprValueKind VK,
- TypeSourceInfo *Written,
- CastKind Kind, Expr *Op,
- const CXXCastPath *Path,
- SourceLocation LPLoc,
- SourceLocation RPLoc);
- static CXXFunctionalCastExpr *CreateEmpty(const ASTContext &Context,
- unsigned PathSize);
-
- SourceLocation getLParenLoc() const { return LParenLoc; }
- void setLParenLoc(SourceLocation L) { LParenLoc = L; }
- SourceLocation getRParenLoc() const { return RParenLoc; }
- void setRParenLoc(SourceLocation L) { RParenLoc = L; }
-
- SourceLocation getLocStart() const LLVM_READONLY;
- SourceLocation getLocEnd() const LLVM_READONLY;
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXFunctionalCastExprClass;
- }
-
- friend TrailingObjects;
- friend class CastExpr;
-};
-
-/// @brief Represents a C++ functional cast expression that builds a
-/// temporary object.
-///
-/// This expression type represents a C++ "functional" cast
-/// (C++[expr.type.conv]) with N != 1 arguments that invokes a
-/// constructor to build a temporary object. With N == 1 arguments the
-/// functional cast expression will be represented by CXXFunctionalCastExpr.
-/// Example:
-/// \code
-/// struct X { X(int, float); }
-///
-/// X create_X() {
-/// return X(1, 3.14f); // creates a CXXTemporaryObjectExpr
-/// };
-/// \endcode
-class CXXTemporaryObjectExpr : public CXXConstructExpr {
- TypeSourceInfo *Type;
-
-public:
- CXXTemporaryObjectExpr(const ASTContext &C, CXXConstructorDecl *Cons,
- TypeSourceInfo *Type,
- ArrayRef<Expr *> Args,
- SourceRange ParenOrBraceRange,
- bool HadMultipleCandidates,
- bool ListInitialization,
- bool StdInitListInitialization,
- bool ZeroInitialization);
- explicit CXXTemporaryObjectExpr(EmptyShell Empty)
- : CXXConstructExpr(CXXTemporaryObjectExprClass, Empty), Type() { }
-
- TypeSourceInfo *getTypeSourceInfo() const { return Type; }
-
- SourceLocation getLocStart() const LLVM_READONLY;
- SourceLocation getLocEnd() const LLVM_READONLY;
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXTemporaryObjectExprClass;
- }
-
- friend class ASTStmtReader;
-};
-
-/// \brief A C++ lambda expression, which produces a function object
-/// (of unspecified type) that can be invoked later.
-///
-/// Example:
-/// \code
-/// void low_pass_filter(std::vector<double> &values, double cutoff) {
-/// values.erase(std::remove_if(values.begin(), values.end(),
-/// [=](double value) { return value > cutoff; });
-/// }
-/// \endcode
-///
-/// C++11 lambda expressions can capture local variables, either by copying
-/// the values of those local variables at the time the function
-/// object is constructed (not when it is called!) or by holding a
-/// reference to the local variable. These captures can occur either
-/// implicitly or can be written explicitly between the square
-/// brackets ([...]) that start the lambda expression.
-///
-/// C++1y introduces a new form of "capture" called an init-capture that
-/// includes an initializing expression (rather than capturing a variable),
-/// and which can never occur implicitly.
-class LambdaExpr final
- : public Expr,
- private llvm::TrailingObjects<LambdaExpr, Stmt *, unsigned, VarDecl *> {
- /// \brief The source range that covers the lambda introducer ([...]).
- SourceRange IntroducerRange;
-
- /// \brief The source location of this lambda's capture-default ('=' or '&').
- SourceLocation CaptureDefaultLoc;
-
- /// \brief The number of captures.
- unsigned NumCaptures : 16;
-
- /// \brief The default capture kind, which is a value of type
- /// LambdaCaptureDefault.
- unsigned CaptureDefault : 2;
-
- /// \brief Whether this lambda had an explicit parameter list vs. an
- /// implicit (and empty) parameter list.
- unsigned ExplicitParams : 1;
-
- /// \brief Whether this lambda had the result type explicitly specified.
- unsigned ExplicitResultType : 1;
-
- /// \brief Whether there are any array index variables stored at the end of
- /// this lambda expression.
- unsigned HasArrayIndexVars : 1;
-
- /// \brief The location of the closing brace ('}') that completes
- /// the lambda.
- ///
- /// The location of the brace is also available by looking up the
- /// function call operator in the lambda class. However, it is
- /// stored here to improve the performance of getSourceRange(), and
- /// to avoid having to deserialize the function call operator from a
- /// module file just to determine the source range.
- SourceLocation ClosingBrace;
-
- size_t numTrailingObjects(OverloadToken<Stmt *>) const {
- return NumCaptures + 1;
- }
-
- size_t numTrailingObjects(OverloadToken<unsigned>) const {
- return HasArrayIndexVars ? NumCaptures + 1 : 0;
- }
-
- /// \brief Construct a lambda expression.
- LambdaExpr(QualType T, SourceRange IntroducerRange,
- LambdaCaptureDefault CaptureDefault,
- SourceLocation CaptureDefaultLoc, ArrayRef<LambdaCapture> Captures,
- bool ExplicitParams, bool ExplicitResultType,
- ArrayRef<Expr *> CaptureInits, ArrayRef<VarDecl *> ArrayIndexVars,
- ArrayRef<unsigned> ArrayIndexStarts, SourceLocation ClosingBrace,
- bool ContainsUnexpandedParameterPack);
-
- /// \brief Construct an empty lambda expression.
- LambdaExpr(EmptyShell Empty, unsigned NumCaptures, bool HasArrayIndexVars)
- : Expr(LambdaExprClass, Empty),
- NumCaptures(NumCaptures), CaptureDefault(LCD_None), ExplicitParams(false),
- ExplicitResultType(false), HasArrayIndexVars(true) {
- getStoredStmts()[NumCaptures] = nullptr;
- }
-
- Stmt **getStoredStmts() { return getTrailingObjects<Stmt *>(); }
-
- Stmt *const *getStoredStmts() const { return getTrailingObjects<Stmt *>(); }
-
- /// \brief Retrieve the mapping from captures to the first array index
- /// variable.
- unsigned *getArrayIndexStarts() { return getTrailingObjects<unsigned>(); }
-
- const unsigned *getArrayIndexStarts() const {
- return getTrailingObjects<unsigned>();
- }
-
- /// \brief Retrieve the complete set of array-index variables.
- VarDecl **getArrayIndexVars() { return getTrailingObjects<VarDecl *>(); }
-
- VarDecl *const *getArrayIndexVars() const {
- return getTrailingObjects<VarDecl *>();
- }
-
-public:
- /// \brief Construct a new lambda expression.
- static LambdaExpr *
- Create(const ASTContext &C, CXXRecordDecl *Class, SourceRange IntroducerRange,
- LambdaCaptureDefault CaptureDefault, SourceLocation CaptureDefaultLoc,
- ArrayRef<LambdaCapture> Captures, bool ExplicitParams,
- bool ExplicitResultType, ArrayRef<Expr *> CaptureInits,
- ArrayRef<VarDecl *> ArrayIndexVars,
- ArrayRef<unsigned> ArrayIndexStarts, SourceLocation ClosingBrace,
- bool ContainsUnexpandedParameterPack);
-
- /// \brief Construct a new lambda expression that will be deserialized from
- /// an external source.
- static LambdaExpr *CreateDeserialized(const ASTContext &C,
- unsigned NumCaptures,
- unsigned NumArrayIndexVars);
-
- /// \brief Determine the default capture kind for this lambda.
- LambdaCaptureDefault getCaptureDefault() const {
- return static_cast<LambdaCaptureDefault>(CaptureDefault);
- }
-
- /// \brief Retrieve the location of this lambda's capture-default, if any.
- SourceLocation getCaptureDefaultLoc() const {
- return CaptureDefaultLoc;
- }
-
- /// \brief Determine whether one of this lambda's captures is an init-capture.
- bool isInitCapture(const LambdaCapture *Capture) const;
-
- /// \brief An iterator that walks over the captures of the lambda,
- /// both implicit and explicit.
- typedef const LambdaCapture *capture_iterator;
-
- /// \brief An iterator over a range of lambda captures.
- typedef llvm::iterator_range<capture_iterator> capture_range;
-
- /// \brief Retrieve this lambda's captures.
- capture_range captures() const;
-
- /// \brief Retrieve an iterator pointing to the first lambda capture.
- capture_iterator capture_begin() const;
-
- /// \brief Retrieve an iterator pointing past the end of the
- /// sequence of lambda captures.
- capture_iterator capture_end() const;
-
- /// \brief Determine the number of captures in this lambda.
- unsigned capture_size() const { return NumCaptures; }
-
- /// \brief Retrieve this lambda's explicit captures.
- capture_range explicit_captures() const;
-
- /// \brief Retrieve an iterator pointing to the first explicit
- /// lambda capture.
- capture_iterator explicit_capture_begin() const;
-
- /// \brief Retrieve an iterator pointing past the end of the sequence of
- /// explicit lambda captures.
- capture_iterator explicit_capture_end() const;
-
- /// \brief Retrieve this lambda's implicit captures.
- capture_range implicit_captures() const;
-
- /// \brief Retrieve an iterator pointing to the first implicit
- /// lambda capture.
- capture_iterator implicit_capture_begin() const;
-
- /// \brief Retrieve an iterator pointing past the end of the sequence of
- /// implicit lambda captures.
- capture_iterator implicit_capture_end() const;
-
- /// \brief Iterator that walks over the capture initialization
- /// arguments.
- typedef Expr **capture_init_iterator;
-
- /// \brief Const iterator that walks over the capture initialization
- /// arguments.
- typedef Expr *const *const_capture_init_iterator;
-
- /// \brief Retrieve the initialization expressions for this lambda's captures.
- llvm::iterator_range<capture_init_iterator> capture_inits() {
- return llvm::make_range(capture_init_begin(), capture_init_end());
- }
-
- /// \brief Retrieve the initialization expressions for this lambda's captures.
- llvm::iterator_range<const_capture_init_iterator> capture_inits() const {
- return llvm::make_range(capture_init_begin(), capture_init_end());
- }
-
- /// \brief Retrieve the first initialization argument for this
- /// lambda expression (which initializes the first capture field).
- capture_init_iterator capture_init_begin() {
- return reinterpret_cast<Expr **>(getStoredStmts());
- }
-
- /// \brief Retrieve the first initialization argument for this
- /// lambda expression (which initializes the first capture field).
- const_capture_init_iterator capture_init_begin() const {
- return reinterpret_cast<Expr *const *>(getStoredStmts());
- }
-
- /// \brief Retrieve the iterator pointing one past the last
- /// initialization argument for this lambda expression.
- capture_init_iterator capture_init_end() {
- return capture_init_begin() + NumCaptures;
- }
-
- /// \brief Retrieve the iterator pointing one past the last
- /// initialization argument for this lambda expression.
- const_capture_init_iterator capture_init_end() const {
- return capture_init_begin() + NumCaptures;
- }
-
- /// \brief Retrieve the set of index variables used in the capture
- /// initializer of an array captured by copy.
- ///
- /// \param Iter The iterator that points at the capture initializer for
- /// which we are extracting the corresponding index variables.
- ArrayRef<VarDecl *>
- getCaptureInitIndexVars(const_capture_init_iterator Iter) const;
-
- /// \brief Retrieve the source range covering the lambda introducer,
- /// which contains the explicit capture list surrounded by square
- /// brackets ([...]).
- SourceRange getIntroducerRange() const { return IntroducerRange; }
-
- /// \brief Retrieve the class that corresponds to the lambda.
- ///
- /// This is the "closure type" (C++1y [expr.prim.lambda]), and stores the
- /// captures in its fields and provides the various operations permitted
- /// on a lambda (copying, calling).
- CXXRecordDecl *getLambdaClass() const;
-
- /// \brief Retrieve the function call operator associated with this
- /// lambda expression.
- CXXMethodDecl *getCallOperator() const;
-
- /// \brief If this is a generic lambda expression, retrieve the template
- /// parameter list associated with it, or else return null.
- TemplateParameterList *getTemplateParameterList() const;
-
- /// \brief Whether this is a generic lambda.
- bool isGenericLambda() const { return getTemplateParameterList(); }
-
- /// \brief Retrieve the body of the lambda.
- CompoundStmt *getBody() const;
-
- /// \brief Determine whether the lambda is mutable, meaning that any
- /// captures values can be modified.
- bool isMutable() const;
-
- /// \brief Determine whether this lambda has an explicit parameter
- /// list vs. an implicit (empty) parameter list.
- bool hasExplicitParameters() const { return ExplicitParams; }
-
- /// \brief Whether this lambda had its result type explicitly specified.
- bool hasExplicitResultType() const { return ExplicitResultType; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == LambdaExprClass;
- }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return IntroducerRange.getBegin();
- }
- SourceLocation getLocEnd() const LLVM_READONLY { return ClosingBrace; }
-
- child_range children() {
- // Includes initialization exprs plus body stmt
- return child_range(getStoredStmts(), getStoredStmts() + NumCaptures + 1);
- }
-
- friend TrailingObjects;
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-};
-
-/// An expression "T()" which creates a value-initialized rvalue of type
-/// T, which is a non-class type. See (C++98 [5.2.3p2]).
-class CXXScalarValueInitExpr : public Expr {
- SourceLocation RParenLoc;
- TypeSourceInfo *TypeInfo;
-
- friend class ASTStmtReader;
-
-public:
- /// \brief Create an explicitly-written scalar-value initialization
- /// expression.
- CXXScalarValueInitExpr(QualType Type, TypeSourceInfo *TypeInfo,
- SourceLocation rParenLoc)
- : Expr(CXXScalarValueInitExprClass, Type, VK_RValue, OK_Ordinary,
- false, false, Type->isInstantiationDependentType(),
- Type->containsUnexpandedParameterPack()),
- RParenLoc(rParenLoc), TypeInfo(TypeInfo) {}
-
- explicit CXXScalarValueInitExpr(EmptyShell Shell)
- : Expr(CXXScalarValueInitExprClass, Shell) { }
-
- TypeSourceInfo *getTypeSourceInfo() const {
- return TypeInfo;
- }
-
- SourceLocation getRParenLoc() const { return RParenLoc; }
-
- SourceLocation getLocStart() const LLVM_READONLY;
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXScalarValueInitExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// \brief Represents a new-expression for memory allocation and constructor
-/// calls, e.g: "new CXXNewExpr(foo)".
-class CXXNewExpr : public Expr {
- /// Contains an optional array size expression, an optional initialization
- /// expression, and any number of optional placement arguments, in that order.
- Stmt **SubExprs;
- /// \brief Points to the allocation function used.
- FunctionDecl *OperatorNew;
- /// \brief Points to the deallocation function used in case of error. May be
- /// null.
- FunctionDecl *OperatorDelete;
-
- /// \brief The allocated type-source information, as written in the source.
- TypeSourceInfo *AllocatedTypeInfo;
-
- /// \brief If the allocated type was expressed as a parenthesized type-id,
- /// the source range covering the parenthesized type-id.
- SourceRange TypeIdParens;
-
- /// \brief Range of the entire new expression.
- SourceRange Range;
-
- /// \brief Source-range of a paren-delimited initializer.
- SourceRange DirectInitRange;
-
- /// Was the usage ::new, i.e. is the global new to be used?
- bool GlobalNew : 1;
- /// Do we allocate an array? If so, the first SubExpr is the size expression.
- bool Array : 1;
- /// If this is an array allocation, does the usual deallocation
- /// function for the allocated type want to know the allocated size?
- bool UsualArrayDeleteWantsSize : 1;
- /// The number of placement new arguments.
- unsigned NumPlacementArgs : 13;
- /// What kind of initializer do we have? Could be none, parens, or braces.
- /// In storage, we distinguish between "none, and no initializer expr", and
- /// "none, but an implicit initializer expr".
- unsigned StoredInitializationStyle : 2;
-
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-public:
- enum InitializationStyle {
- NoInit, ///< New-expression has no initializer as written.
- CallInit, ///< New-expression has a C++98 paren-delimited initializer.
- ListInit ///< New-expression has a C++11 list-initializer.
- };
-
- CXXNewExpr(const ASTContext &C, bool globalNew, FunctionDecl *operatorNew,
- FunctionDecl *operatorDelete, bool usualArrayDeleteWantsSize,
- ArrayRef<Expr*> placementArgs,
- SourceRange typeIdParens, Expr *arraySize,
- InitializationStyle initializationStyle, Expr *initializer,
- QualType ty, TypeSourceInfo *AllocatedTypeInfo,
- SourceRange Range, SourceRange directInitRange);
- explicit CXXNewExpr(EmptyShell Shell)
- : Expr(CXXNewExprClass, Shell), SubExprs(nullptr) { }
-
- void AllocateArgsArray(const ASTContext &C, bool isArray,
- unsigned numPlaceArgs, bool hasInitializer);
-
- QualType getAllocatedType() const {
- assert(getType()->isPointerType());
- return getType()->getAs<PointerType>()->getPointeeType();
- }
-
- TypeSourceInfo *getAllocatedTypeSourceInfo() const {
- return AllocatedTypeInfo;
- }
-
- /// \brief True if the allocation result needs to be null-checked.
- ///
- /// C++11 [expr.new]p13:
- /// If the allocation function returns null, initialization shall
- /// not be done, the deallocation function shall not be called,
- /// and the value of the new-expression shall be null.
- ///
- /// C++ DR1748:
- /// If the allocation function is a reserved placement allocation
- /// function that returns null, the behavior is undefined.
- ///
- /// An allocation function is not allowed to return null unless it
- /// has a non-throwing exception-specification. The '03 rule is
- /// identical except that the definition of a non-throwing
- /// exception specification is just "is it throw()?".
- bool shouldNullCheckAllocation(const ASTContext &Ctx) const;
-
- FunctionDecl *getOperatorNew() const { return OperatorNew; }
- void setOperatorNew(FunctionDecl *D) { OperatorNew = D; }
- FunctionDecl *getOperatorDelete() const { return OperatorDelete; }
- void setOperatorDelete(FunctionDecl *D) { OperatorDelete = D; }
-
- bool isArray() const { return Array; }
- Expr *getArraySize() {
- return Array ? cast<Expr>(SubExprs[0]) : nullptr;
- }
- const Expr *getArraySize() const {
- return Array ? cast<Expr>(SubExprs[0]) : nullptr;
- }
-
- unsigned getNumPlacementArgs() const { return NumPlacementArgs; }
- Expr **getPlacementArgs() {
- return reinterpret_cast<Expr **>(SubExprs + Array + hasInitializer());
- }
-
- Expr *getPlacementArg(unsigned i) {
- assert(i < NumPlacementArgs && "Index out of range");
- return getPlacementArgs()[i];
- }
- const Expr *getPlacementArg(unsigned i) const {
- assert(i < NumPlacementArgs && "Index out of range");
- return const_cast<CXXNewExpr*>(this)->getPlacementArg(i);
- }
-
- bool isParenTypeId() const { return TypeIdParens.isValid(); }
- SourceRange getTypeIdParens() const { return TypeIdParens; }
-
- bool isGlobalNew() const { return GlobalNew; }
-
- /// \brief Whether this new-expression has any initializer at all.
- bool hasInitializer() const { return StoredInitializationStyle > 0; }
-
- /// \brief The kind of initializer this new-expression has.
- InitializationStyle getInitializationStyle() const {
- if (StoredInitializationStyle == 0)
- return NoInit;
- return static_cast<InitializationStyle>(StoredInitializationStyle-1);
- }
-
- /// \brief The initializer of this new-expression.
- Expr *getInitializer() {
- return hasInitializer() ? cast<Expr>(SubExprs[Array]) : nullptr;
- }
- const Expr *getInitializer() const {
- return hasInitializer() ? cast<Expr>(SubExprs[Array]) : nullptr;
- }
-
- /// \brief Returns the CXXConstructExpr from this new-expression, or null.
- const CXXConstructExpr* getConstructExpr() const {
- return dyn_cast_or_null<CXXConstructExpr>(getInitializer());
- }
-
- /// Answers whether the usual array deallocation function for the
- /// allocated type expects the size of the allocation as a
- /// parameter.
- bool doesUsualArrayDeleteWantSize() const {
- return UsualArrayDeleteWantsSize;
- }
-
- typedef ExprIterator arg_iterator;
- typedef ConstExprIterator const_arg_iterator;
-
- llvm::iterator_range<arg_iterator> placement_arguments() {
- return llvm::make_range(placement_arg_begin(), placement_arg_end());
- }
-
- llvm::iterator_range<const_arg_iterator> placement_arguments() const {
- return llvm::make_range(placement_arg_begin(), placement_arg_end());
- }
-
- arg_iterator placement_arg_begin() {
- return SubExprs + Array + hasInitializer();
- }
- arg_iterator placement_arg_end() {
- return SubExprs + Array + hasInitializer() + getNumPlacementArgs();
- }
- const_arg_iterator placement_arg_begin() const {
- return SubExprs + Array + hasInitializer();
- }
- const_arg_iterator placement_arg_end() const {
- return SubExprs + Array + hasInitializer() + getNumPlacementArgs();
- }
-
- typedef Stmt **raw_arg_iterator;
- raw_arg_iterator raw_arg_begin() { return SubExprs; }
- raw_arg_iterator raw_arg_end() {
- return SubExprs + Array + hasInitializer() + getNumPlacementArgs();
- }
- const_arg_iterator raw_arg_begin() const { return SubExprs; }
- const_arg_iterator raw_arg_end() const {
- return SubExprs + Array + hasInitializer() + getNumPlacementArgs();
- }
-
- SourceLocation getStartLoc() const { return Range.getBegin(); }
- SourceLocation getEndLoc() const { return Range.getEnd(); }
-
- SourceRange getDirectInitRange() const { return DirectInitRange; }
-
- SourceRange getSourceRange() const LLVM_READONLY {
- return Range;
- }
- SourceLocation getLocStart() const LLVM_READONLY { return getStartLoc(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXNewExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(raw_arg_begin(), raw_arg_end());
- }
-};
-
-/// \brief Represents a \c delete expression for memory deallocation and
-/// destructor calls, e.g. "delete[] pArray".
-class CXXDeleteExpr : public Expr {
- /// Points to the operator delete overload that is used. Could be a member.
- FunctionDecl *OperatorDelete;
- /// The pointer expression to be deleted.
- Stmt *Argument;
- /// Location of the expression.
- SourceLocation Loc;
- /// Is this a forced global delete, i.e. "::delete"?
- bool GlobalDelete : 1;
- /// Is this the array form of delete, i.e. "delete[]"?
- bool ArrayForm : 1;
- /// ArrayFormAsWritten can be different from ArrayForm if 'delete' is applied
- /// to pointer-to-array type (ArrayFormAsWritten will be false while ArrayForm
- /// will be true).
- bool ArrayFormAsWritten : 1;
- /// Does the usual deallocation function for the element type require
- /// a size_t argument?
- bool UsualArrayDeleteWantsSize : 1;
-public:
- CXXDeleteExpr(QualType ty, bool globalDelete, bool arrayForm,
- bool arrayFormAsWritten, bool usualArrayDeleteWantsSize,
- FunctionDecl *operatorDelete, Expr *arg, SourceLocation loc)
- : Expr(CXXDeleteExprClass, ty, VK_RValue, OK_Ordinary, false, false,
- arg->isInstantiationDependent(),
- arg->containsUnexpandedParameterPack()),
- OperatorDelete(operatorDelete), Argument(arg), Loc(loc),
- GlobalDelete(globalDelete),
- ArrayForm(arrayForm), ArrayFormAsWritten(arrayFormAsWritten),
- UsualArrayDeleteWantsSize(usualArrayDeleteWantsSize) { }
- explicit CXXDeleteExpr(EmptyShell Shell)
- : Expr(CXXDeleteExprClass, Shell), OperatorDelete(nullptr),
- Argument(nullptr) {}
-
- bool isGlobalDelete() const { return GlobalDelete; }
- bool isArrayForm() const { return ArrayForm; }
- bool isArrayFormAsWritten() const { return ArrayFormAsWritten; }
-
- /// Answers whether the usual array deallocation function for the
- /// allocated type expects the size of the allocation as a
- /// parameter. This can be true even if the actual deallocation
- /// function that we're using doesn't want a size.
- bool doesUsualArrayDeleteWantSize() const {
- return UsualArrayDeleteWantsSize;
- }
-
- FunctionDecl *getOperatorDelete() const { return OperatorDelete; }
-
- Expr *getArgument() { return cast<Expr>(Argument); }
- const Expr *getArgument() const { return cast<Expr>(Argument); }
-
- /// \brief Retrieve the type being destroyed.
- ///
- /// If the type being destroyed is a dependent type which may or may not
- /// be a pointer, return an invalid type.
- QualType getDestroyedType() const;
-
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY {return Argument->getLocEnd();}
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXDeleteExprClass;
- }
-
- // Iterators
- child_range children() { return child_range(&Argument, &Argument+1); }
-
- friend class ASTStmtReader;
-};
-
-/// \brief Stores the type being destroyed by a pseudo-destructor expression.
-class PseudoDestructorTypeStorage {
- /// \brief Either the type source information or the name of the type, if
- /// it couldn't be resolved due to type-dependence.
- llvm::PointerUnion<TypeSourceInfo *, IdentifierInfo *> Type;
-
- /// \brief The starting source location of the pseudo-destructor type.
- SourceLocation Location;
-
-public:
- PseudoDestructorTypeStorage() { }
-
- PseudoDestructorTypeStorage(IdentifierInfo *II, SourceLocation Loc)
- : Type(II), Location(Loc) { }
-
- PseudoDestructorTypeStorage(TypeSourceInfo *Info);
-
- TypeSourceInfo *getTypeSourceInfo() const {
- return Type.dyn_cast<TypeSourceInfo *>();
- }
-
- IdentifierInfo *getIdentifier() const {
- return Type.dyn_cast<IdentifierInfo *>();
- }
-
- SourceLocation getLocation() const { return Location; }
-};
-
-/// \brief Represents a C++ pseudo-destructor (C++ [expr.pseudo]).
-///
-/// A pseudo-destructor is an expression that looks like a member access to a
-/// destructor of a scalar type, except that scalar types don't have
-/// destructors. For example:
-///
-/// \code
-/// typedef int T;
-/// void f(int *p) {
-/// p->T::~T();
-/// }
-/// \endcode
-///
-/// Pseudo-destructors typically occur when instantiating templates such as:
-///
-/// \code
-/// template<typename T>
-/// void destroy(T* ptr) {
-/// ptr->T::~T();
-/// }
-/// \endcode
-///
-/// for scalar types. A pseudo-destructor expression has no run-time semantics
-/// beyond evaluating the base expression.
-class CXXPseudoDestructorExpr : public Expr {
- /// \brief The base expression (that is being destroyed).
- Stmt *Base;
-
- /// \brief Whether the operator was an arrow ('->'); otherwise, it was a
- /// period ('.').
- bool IsArrow : 1;
-
- /// \brief The location of the '.' or '->' operator.
- SourceLocation OperatorLoc;
-
- /// \brief The nested-name-specifier that follows the operator, if present.
- NestedNameSpecifierLoc QualifierLoc;
-
- /// \brief The type that precedes the '::' in a qualified pseudo-destructor
- /// expression.
- TypeSourceInfo *ScopeType;
-
- /// \brief The location of the '::' in a qualified pseudo-destructor
- /// expression.
- SourceLocation ColonColonLoc;
-
- /// \brief The location of the '~'.
- SourceLocation TildeLoc;
-
- /// \brief The type being destroyed, or its name if we were unable to
- /// resolve the name.
- PseudoDestructorTypeStorage DestroyedType;
-
- friend class ASTStmtReader;
-
-public:
- CXXPseudoDestructorExpr(const ASTContext &Context,
- Expr *Base, bool isArrow, SourceLocation OperatorLoc,
- NestedNameSpecifierLoc QualifierLoc,
- TypeSourceInfo *ScopeType,
- SourceLocation ColonColonLoc,
- SourceLocation TildeLoc,
- PseudoDestructorTypeStorage DestroyedType);
-
- explicit CXXPseudoDestructorExpr(EmptyShell Shell)
- : Expr(CXXPseudoDestructorExprClass, Shell),
- Base(nullptr), IsArrow(false), QualifierLoc(), ScopeType(nullptr) { }
-
- Expr *getBase() const { return cast<Expr>(Base); }
-
- /// \brief Determines whether this member expression actually had
- /// a C++ nested-name-specifier prior to the name of the member, e.g.,
- /// x->Base::foo.
- bool hasQualifier() const { return QualifierLoc.hasQualifier(); }
-
- /// \brief Retrieves the nested-name-specifier that qualifies the type name,
- /// with source-location information.
- NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
-
- /// \brief If the member name was qualified, retrieves the
- /// nested-name-specifier that precedes the member name. Otherwise, returns
- /// null.
- NestedNameSpecifier *getQualifier() const {
- return QualifierLoc.getNestedNameSpecifier();
- }
-
- /// \brief Determine whether this pseudo-destructor expression was written
- /// using an '->' (otherwise, it used a '.').
- bool isArrow() const { return IsArrow; }
-
- /// \brief Retrieve the location of the '.' or '->' operator.
- SourceLocation getOperatorLoc() const { return OperatorLoc; }
-
- /// \brief Retrieve the scope type in a qualified pseudo-destructor
- /// expression.
- ///
- /// Pseudo-destructor expressions can have extra qualification within them
- /// that is not part of the nested-name-specifier, e.g., \c p->T::~T().
- /// Here, if the object type of the expression is (or may be) a scalar type,
- /// \p T may also be a scalar type and, therefore, cannot be part of a
- /// nested-name-specifier. It is stored as the "scope type" of the pseudo-
- /// destructor expression.
- TypeSourceInfo *getScopeTypeInfo() const { return ScopeType; }
-
- /// \brief Retrieve the location of the '::' in a qualified pseudo-destructor
- /// expression.
- SourceLocation getColonColonLoc() const { return ColonColonLoc; }
-
- /// \brief Retrieve the location of the '~'.
- SourceLocation getTildeLoc() const { return TildeLoc; }
-
- /// \brief Retrieve the source location information for the type
- /// being destroyed.
- ///
- /// This type-source information is available for non-dependent
- /// pseudo-destructor expressions and some dependent pseudo-destructor
- /// expressions. Returns null if we only have the identifier for a
- /// dependent pseudo-destructor expression.
- TypeSourceInfo *getDestroyedTypeInfo() const {
- return DestroyedType.getTypeSourceInfo();
- }
-
- /// \brief In a dependent pseudo-destructor expression for which we do not
- /// have full type information on the destroyed type, provides the name
- /// of the destroyed type.
- IdentifierInfo *getDestroyedTypeIdentifier() const {
- return DestroyedType.getIdentifier();
- }
-
- /// \brief Retrieve the type being destroyed.
- QualType getDestroyedType() const;
-
- /// \brief Retrieve the starting location of the type being destroyed.
- SourceLocation getDestroyedTypeLoc() const {
- return DestroyedType.getLocation();
- }
-
- /// \brief Set the name of destroyed type for a dependent pseudo-destructor
- /// expression.
- void setDestroyedType(IdentifierInfo *II, SourceLocation Loc) {
- DestroyedType = PseudoDestructorTypeStorage(II, Loc);
- }
-
- /// \brief Set the destroyed type.
- void setDestroyedType(TypeSourceInfo *Info) {
- DestroyedType = PseudoDestructorTypeStorage(Info);
- }
-
- SourceLocation getLocStart() const LLVM_READONLY {return Base->getLocStart();}
- SourceLocation getLocEnd() const LLVM_READONLY;
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXPseudoDestructorExprClass;
- }
-
- // Iterators
- child_range children() { return child_range(&Base, &Base + 1); }
-};
-
-/// \brief A type trait used in the implementation of various C++11 and
-/// Library TR1 trait templates.
-///
-/// \code
-/// __is_pod(int) == true
-/// __is_enum(std::string) == false
-/// __is_trivially_constructible(vector<int>, int*, int*)
-/// \endcode
-class TypeTraitExpr final
- : public Expr,
- private llvm::TrailingObjects<TypeTraitExpr, TypeSourceInfo *> {
- /// \brief The location of the type trait keyword.
- SourceLocation Loc;
-
- /// \brief The location of the closing parenthesis.
- SourceLocation RParenLoc;
-
- // Note: The TypeSourceInfos for the arguments are allocated after the
- // TypeTraitExpr.
-
- TypeTraitExpr(QualType T, SourceLocation Loc, TypeTrait Kind,
- ArrayRef<TypeSourceInfo *> Args,
- SourceLocation RParenLoc,
- bool Value);
-
- TypeTraitExpr(EmptyShell Empty) : Expr(TypeTraitExprClass, Empty) { }
-
- size_t numTrailingObjects(OverloadToken<TypeSourceInfo *>) const {
- return getNumArgs();
- }
-
-public:
- /// \brief Create a new type trait expression.
- static TypeTraitExpr *Create(const ASTContext &C, QualType T,
- SourceLocation Loc, TypeTrait Kind,
- ArrayRef<TypeSourceInfo *> Args,
- SourceLocation RParenLoc,
- bool Value);
-
- static TypeTraitExpr *CreateDeserialized(const ASTContext &C,
- unsigned NumArgs);
-
- /// \brief Determine which type trait this expression uses.
- TypeTrait getTrait() const {
- return static_cast<TypeTrait>(TypeTraitExprBits.Kind);
- }
-
- bool getValue() const {
- assert(!isValueDependent());
- return TypeTraitExprBits.Value;
- }
-
- /// \brief Determine the number of arguments to this type trait.
- unsigned getNumArgs() const { return TypeTraitExprBits.NumArgs; }
-
- /// \brief Retrieve the Ith argument.
- TypeSourceInfo *getArg(unsigned I) const {
- assert(I < getNumArgs() && "Argument out-of-range");
- return getArgs()[I];
- }
-
- /// \brief Retrieve the argument types.
- ArrayRef<TypeSourceInfo *> getArgs() const {
- return llvm::makeArrayRef(getTrailingObjects<TypeSourceInfo *>(),
- getNumArgs());
- }
-
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == TypeTraitExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-
- friend TrailingObjects;
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-};
-
-/// \brief An Embarcadero array type trait, as used in the implementation of
-/// __array_rank and __array_extent.
-///
-/// Example:
-/// \code
-/// __array_rank(int[10][20]) == 2
-/// __array_extent(int, 1) == 20
-/// \endcode
-class ArrayTypeTraitExpr : public Expr {
- virtual void anchor();
-
- /// \brief The trait. An ArrayTypeTrait enum in MSVC compat unsigned.
- unsigned ATT : 2;
-
- /// \brief The value of the type trait. Unspecified if dependent.
- uint64_t Value;
-
- /// \brief The array dimension being queried, or -1 if not used.
- Expr *Dimension;
-
- /// \brief The location of the type trait keyword.
- SourceLocation Loc;
-
- /// \brief The location of the closing paren.
- SourceLocation RParen;
-
- /// \brief The type being queried.
- TypeSourceInfo *QueriedType;
-
-public:
- ArrayTypeTraitExpr(SourceLocation loc, ArrayTypeTrait att,
- TypeSourceInfo *queried, uint64_t value,
- Expr *dimension, SourceLocation rparen, QualType ty)
- : Expr(ArrayTypeTraitExprClass, ty, VK_RValue, OK_Ordinary,
- false, queried->getType()->isDependentType(),
- (queried->getType()->isInstantiationDependentType() ||
- (dimension && dimension->isInstantiationDependent())),
- queried->getType()->containsUnexpandedParameterPack()),
- ATT(att), Value(value), Dimension(dimension),
- Loc(loc), RParen(rparen), QueriedType(queried) { }
-
-
- explicit ArrayTypeTraitExpr(EmptyShell Empty)
- : Expr(ArrayTypeTraitExprClass, Empty), ATT(0), Value(false),
- QueriedType() { }
-
- virtual ~ArrayTypeTraitExpr() { }
-
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParen; }
-
- ArrayTypeTrait getTrait() const { return static_cast<ArrayTypeTrait>(ATT); }
-
- QualType getQueriedType() const { return QueriedType->getType(); }
-
- TypeSourceInfo *getQueriedTypeSourceInfo() const { return QueriedType; }
-
- uint64_t getValue() const { assert(!isTypeDependent()); return Value; }
-
- Expr *getDimensionExpression() const { return Dimension; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ArrayTypeTraitExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-
- friend class ASTStmtReader;
-};
-
-/// \brief An expression trait intrinsic.
-///
-/// Example:
-/// \code
-/// __is_lvalue_expr(std::cout) == true
-/// __is_lvalue_expr(1) == false
-/// \endcode
-class ExpressionTraitExpr : public Expr {
- /// \brief The trait. A ExpressionTrait enum in MSVC compatible unsigned.
- unsigned ET : 31;
- /// \brief The value of the type trait. Unspecified if dependent.
- bool Value : 1;
-
- /// \brief The location of the type trait keyword.
- SourceLocation Loc;
-
- /// \brief The location of the closing paren.
- SourceLocation RParen;
-
- /// \brief The expression being queried.
- Expr* QueriedExpression;
-public:
- ExpressionTraitExpr(SourceLocation loc, ExpressionTrait et,
- Expr *queried, bool value,
- SourceLocation rparen, QualType resultType)
- : Expr(ExpressionTraitExprClass, resultType, VK_RValue, OK_Ordinary,
- false, // Not type-dependent
- // Value-dependent if the argument is type-dependent.
- queried->isTypeDependent(),
- queried->isInstantiationDependent(),
- queried->containsUnexpandedParameterPack()),
- ET(et), Value(value), Loc(loc), RParen(rparen),
- QueriedExpression(queried) { }
-
- explicit ExpressionTraitExpr(EmptyShell Empty)
- : Expr(ExpressionTraitExprClass, Empty), ET(0), Value(false),
- QueriedExpression() { }
-
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParen; }
-
- ExpressionTrait getTrait() const { return static_cast<ExpressionTrait>(ET); }
-
- Expr *getQueriedExpression() const { return QueriedExpression; }
-
- bool getValue() const { return Value; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ExpressionTraitExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-
- friend class ASTStmtReader;
-};
-
-
-/// \brief A reference to an overloaded function set, either an
-/// \c UnresolvedLookupExpr or an \c UnresolvedMemberExpr.
-class OverloadExpr : public Expr {
- /// \brief The common name of these declarations.
- DeclarationNameInfo NameInfo;
-
- /// \brief The nested-name-specifier that qualifies the name, if any.
- NestedNameSpecifierLoc QualifierLoc;
-
- /// The results. These are undesugared, which is to say, they may
- /// include UsingShadowDecls. Access is relative to the naming
- /// class.
- // FIXME: Allocate this data after the OverloadExpr subclass.
- DeclAccessPair *Results;
- unsigned NumResults;
-
-protected:
- /// \brief Whether the name includes info for explicit template
- /// keyword and arguments.
- bool HasTemplateKWAndArgsInfo;
-
- /// \brief Return the optional template keyword and arguments info.
- ASTTemplateKWAndArgsInfo *
- getTrailingASTTemplateKWAndArgsInfo(); // defined far below.
-
- /// \brief Return the optional template keyword and arguments info.
- const ASTTemplateKWAndArgsInfo *getTrailingASTTemplateKWAndArgsInfo() const {
- return const_cast<OverloadExpr *>(this)
- ->getTrailingASTTemplateKWAndArgsInfo();
- }
-
- /// Return the optional template arguments.
- TemplateArgumentLoc *getTrailingTemplateArgumentLoc(); // defined far below
-
- OverloadExpr(StmtClass K, const ASTContext &C,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc,
- const DeclarationNameInfo &NameInfo,
- const TemplateArgumentListInfo *TemplateArgs,
- UnresolvedSetIterator Begin, UnresolvedSetIterator End,
- bool KnownDependent,
- bool KnownInstantiationDependent,
- bool KnownContainsUnexpandedParameterPack);
-
- OverloadExpr(StmtClass K, EmptyShell Empty)
- : Expr(K, Empty), QualifierLoc(), Results(nullptr), NumResults(0),
- HasTemplateKWAndArgsInfo(false) { }
-
- void initializeResults(const ASTContext &C,
- UnresolvedSetIterator Begin,
- UnresolvedSetIterator End);
-
-public:
- struct FindResult {
- OverloadExpr *Expression;
- bool IsAddressOfOperand;
- bool HasFormOfMemberPointer;
- };
-
- /// \brief Finds the overloaded expression in the given expression \p E of
- /// OverloadTy.
- ///
- /// \return the expression (which must be there) and true if it has
- /// the particular form of a member pointer expression
- static FindResult find(Expr *E) {
- assert(E->getType()->isSpecificBuiltinType(BuiltinType::Overload));
-
- FindResult Result;
-
- E = E->IgnoreParens();
- if (isa<UnaryOperator>(E)) {
- assert(cast<UnaryOperator>(E)->getOpcode() == UO_AddrOf);
- E = cast<UnaryOperator>(E)->getSubExpr();
- OverloadExpr *Ovl = cast<OverloadExpr>(E->IgnoreParens());
-
- Result.HasFormOfMemberPointer = (E == Ovl && Ovl->getQualifier());
- Result.IsAddressOfOperand = true;
- Result.Expression = Ovl;
- } else {
- Result.HasFormOfMemberPointer = false;
- Result.IsAddressOfOperand = false;
- Result.Expression = cast<OverloadExpr>(E);
- }
-
- return Result;
- }
-
- /// \brief Gets the naming class of this lookup, if any.
- CXXRecordDecl *getNamingClass() const;
-
- typedef UnresolvedSetImpl::iterator decls_iterator;
- decls_iterator decls_begin() const { return UnresolvedSetIterator(Results); }
- decls_iterator decls_end() const {
- return UnresolvedSetIterator(Results + NumResults);
- }
- llvm::iterator_range<decls_iterator> decls() const {
- return llvm::make_range(decls_begin(), decls_end());
- }
-
- /// \brief Gets the number of declarations in the unresolved set.
- unsigned getNumDecls() const { return NumResults; }
-
- /// \brief Gets the full name info.
- const DeclarationNameInfo &getNameInfo() const { return NameInfo; }
-
- /// \brief Gets the name looked up.
- DeclarationName getName() const { return NameInfo.getName(); }
-
- /// \brief Gets the location of the name.
- SourceLocation getNameLoc() const { return NameInfo.getLoc(); }
-
- /// \brief Fetches the nested-name qualifier, if one was given.
- NestedNameSpecifier *getQualifier() const {
- return QualifierLoc.getNestedNameSpecifier();
- }
-
- /// \brief Fetches the nested-name qualifier with source-location
- /// information, if one was given.
- NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
-
- /// \brief Retrieve the location of the template keyword preceding
- /// this name, if any.
- SourceLocation getTemplateKeywordLoc() const {
- if (!HasTemplateKWAndArgsInfo) return SourceLocation();
- return getTrailingASTTemplateKWAndArgsInfo()->TemplateKWLoc;
- }
-
- /// \brief Retrieve the location of the left angle bracket starting the
- /// explicit template argument list following the name, if any.
- SourceLocation getLAngleLoc() const {
- if (!HasTemplateKWAndArgsInfo) return SourceLocation();
- return getTrailingASTTemplateKWAndArgsInfo()->LAngleLoc;
- }
-
- /// \brief Retrieve the location of the right angle bracket ending the
- /// explicit template argument list following the name, if any.
- SourceLocation getRAngleLoc() const {
- if (!HasTemplateKWAndArgsInfo) return SourceLocation();
- return getTrailingASTTemplateKWAndArgsInfo()->RAngleLoc;
- }
-
- /// \brief Determines whether the name was preceded by the template keyword.
- bool hasTemplateKeyword() const { return getTemplateKeywordLoc().isValid(); }
-
- /// \brief Determines whether this expression had explicit template arguments.
- bool hasExplicitTemplateArgs() const { return getLAngleLoc().isValid(); }
-
- TemplateArgumentLoc const *getTemplateArgs() const {
- if (!hasExplicitTemplateArgs())
- return nullptr;
- return const_cast<OverloadExpr *>(this)->getTrailingTemplateArgumentLoc();
- }
-
- unsigned getNumTemplateArgs() const {
- if (!hasExplicitTemplateArgs())
- return 0;
-
- return getTrailingASTTemplateKWAndArgsInfo()->NumTemplateArgs;
- }
-
- /// \brief Copies the template arguments into the given structure.
- void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
- if (hasExplicitTemplateArgs())
- getTrailingASTTemplateKWAndArgsInfo()->copyInto(getTemplateArgs(), List);
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == UnresolvedLookupExprClass ||
- T->getStmtClass() == UnresolvedMemberExprClass;
- }
-
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-};
-
-/// \brief A reference to a name which we were able to look up during
-/// parsing but could not resolve to a specific declaration.
-///
-/// This arises in several ways:
-/// * we might be waiting for argument-dependent lookup;
-/// * the name might resolve to an overloaded function;
-/// and eventually:
-/// * the lookup might have included a function template.
-///
-/// These never include UnresolvedUsingValueDecls, which are always class
-/// members and therefore appear only in UnresolvedMemberLookupExprs.
-class UnresolvedLookupExpr final
- : public OverloadExpr,
- private llvm::TrailingObjects<
- UnresolvedLookupExpr, ASTTemplateKWAndArgsInfo, TemplateArgumentLoc> {
- /// True if these lookup results should be extended by
- /// argument-dependent lookup if this is the operand of a function
- /// call.
- bool RequiresADL;
-
- /// True if these lookup results are overloaded. This is pretty
- /// trivially rederivable if we urgently need to kill this field.
- bool Overloaded;
-
- /// The naming class (C++ [class.access.base]p5) of the lookup, if
- /// any. This can generally be recalculated from the context chain,
- /// but that can be fairly expensive for unqualified lookups. If we
- /// want to improve memory use here, this could go in a union
- /// against the qualified-lookup bits.
- CXXRecordDecl *NamingClass;
-
- size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
- return HasTemplateKWAndArgsInfo ? 1 : 0;
- }
-
- UnresolvedLookupExpr(const ASTContext &C,
- CXXRecordDecl *NamingClass,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc,
- const DeclarationNameInfo &NameInfo,
- bool RequiresADL, bool Overloaded,
- const TemplateArgumentListInfo *TemplateArgs,
- UnresolvedSetIterator Begin, UnresolvedSetIterator End)
- : OverloadExpr(UnresolvedLookupExprClass, C, QualifierLoc, TemplateKWLoc,
- NameInfo, TemplateArgs, Begin, End, false, false, false),
- RequiresADL(RequiresADL),
- Overloaded(Overloaded), NamingClass(NamingClass)
- {}
-
- UnresolvedLookupExpr(EmptyShell Empty)
- : OverloadExpr(UnresolvedLookupExprClass, Empty),
- RequiresADL(false), Overloaded(false), NamingClass(nullptr)
- {}
-
- friend TrailingObjects;
- friend class OverloadExpr;
- friend class ASTStmtReader;
-
-public:
- static UnresolvedLookupExpr *Create(const ASTContext &C,
- CXXRecordDecl *NamingClass,
- NestedNameSpecifierLoc QualifierLoc,
- const DeclarationNameInfo &NameInfo,
- bool ADL, bool Overloaded,
- UnresolvedSetIterator Begin,
- UnresolvedSetIterator End) {
- return new(C) UnresolvedLookupExpr(C, NamingClass, QualifierLoc,
- SourceLocation(), NameInfo,
- ADL, Overloaded, nullptr, Begin, End);
- }
-
- static UnresolvedLookupExpr *Create(const ASTContext &C,
- CXXRecordDecl *NamingClass,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc,
- const DeclarationNameInfo &NameInfo,
- bool ADL,
- const TemplateArgumentListInfo *Args,
- UnresolvedSetIterator Begin,
- UnresolvedSetIterator End);
-
- static UnresolvedLookupExpr *CreateEmpty(const ASTContext &C,
- bool HasTemplateKWAndArgsInfo,
- unsigned NumTemplateArgs);
-
- /// True if this declaration should be extended by
- /// argument-dependent lookup.
- bool requiresADL() const { return RequiresADL; }
-
- /// True if this lookup is overloaded.
- bool isOverloaded() const { return Overloaded; }
-
- /// Gets the 'naming class' (in the sense of C++0x
- /// [class.access.base]p5) of the lookup. This is the scope
- /// that was looked in to find these results.
- CXXRecordDecl *getNamingClass() const { return NamingClass; }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- if (NestedNameSpecifierLoc l = getQualifierLoc())
- return l.getBeginLoc();
- return getNameInfo().getLocStart();
- }
- SourceLocation getLocEnd() const LLVM_READONLY {
- if (hasExplicitTemplateArgs())
- return getRAngleLoc();
- return getNameInfo().getLocEnd();
- }
-
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == UnresolvedLookupExprClass;
- }
-};
-
-/// \brief A qualified reference to a name whose declaration cannot
-/// yet be resolved.
-///
-/// DependentScopeDeclRefExpr is similar to DeclRefExpr in that
-/// it expresses a reference to a declaration such as
-/// X<T>::value. The difference, however, is that an
-/// DependentScopeDeclRefExpr node is used only within C++ templates when
-/// the qualification (e.g., X<T>::) refers to a dependent type. In
-/// this case, X<T>::value cannot resolve to a declaration because the
-/// declaration will differ from one instantiation of X<T> to the
-/// next. Therefore, DependentScopeDeclRefExpr keeps track of the
-/// qualifier (X<T>::) and the name of the entity being referenced
-/// ("value"). Such expressions will instantiate to a DeclRefExpr once the
-/// declaration can be found.
-class DependentScopeDeclRefExpr final
- : public Expr,
- private llvm::TrailingObjects<DependentScopeDeclRefExpr,
- ASTTemplateKWAndArgsInfo,
- TemplateArgumentLoc> {
- /// \brief The nested-name-specifier that qualifies this unresolved
- /// declaration name.
- NestedNameSpecifierLoc QualifierLoc;
-
- /// \brief The name of the entity we will be referencing.
- DeclarationNameInfo NameInfo;
-
- /// \brief Whether the name includes info for explicit template
- /// keyword and arguments.
- bool HasTemplateKWAndArgsInfo;
-
- size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
- return HasTemplateKWAndArgsInfo ? 1 : 0;
- }
-
- DependentScopeDeclRefExpr(QualType T,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc,
- const DeclarationNameInfo &NameInfo,
- const TemplateArgumentListInfo *Args);
-
-public:
- static DependentScopeDeclRefExpr *Create(const ASTContext &C,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc,
- const DeclarationNameInfo &NameInfo,
- const TemplateArgumentListInfo *TemplateArgs);
-
- static DependentScopeDeclRefExpr *CreateEmpty(const ASTContext &C,
- bool HasTemplateKWAndArgsInfo,
- unsigned NumTemplateArgs);
-
- /// \brief Retrieve the name that this expression refers to.
- const DeclarationNameInfo &getNameInfo() const { return NameInfo; }
-
- /// \brief Retrieve the name that this expression refers to.
- DeclarationName getDeclName() const { return NameInfo.getName(); }
-
- /// \brief Retrieve the location of the name within the expression.
- ///
- /// For example, in "X<T>::value" this is the location of "value".
- SourceLocation getLocation() const { return NameInfo.getLoc(); }
-
- /// \brief Retrieve the nested-name-specifier that qualifies the
- /// name, with source location information.
- NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
-
- /// \brief Retrieve the nested-name-specifier that qualifies this
- /// declaration.
- NestedNameSpecifier *getQualifier() const {
- return QualifierLoc.getNestedNameSpecifier();
- }
-
- /// \brief Retrieve the location of the template keyword preceding
- /// this name, if any.
- SourceLocation getTemplateKeywordLoc() const {
- if (!HasTemplateKWAndArgsInfo) return SourceLocation();
- return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->TemplateKWLoc;
- }
-
- /// \brief Retrieve the location of the left angle bracket starting the
- /// explicit template argument list following the name, if any.
- SourceLocation getLAngleLoc() const {
- if (!HasTemplateKWAndArgsInfo) return SourceLocation();
- return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->LAngleLoc;
- }
-
- /// \brief Retrieve the location of the right angle bracket ending the
- /// explicit template argument list following the name, if any.
- SourceLocation getRAngleLoc() const {
- if (!HasTemplateKWAndArgsInfo) return SourceLocation();
- return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->RAngleLoc;
- }
-
- /// Determines whether the name was preceded by the template keyword.
- bool hasTemplateKeyword() const { return getTemplateKeywordLoc().isValid(); }
-
- /// Determines whether this lookup had explicit template arguments.
- bool hasExplicitTemplateArgs() const { return getLAngleLoc().isValid(); }
-
- /// \brief Copies the template arguments (if present) into the given
- /// structure.
- void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
- if (hasExplicitTemplateArgs())
- getTrailingObjects<ASTTemplateKWAndArgsInfo>()->copyInto(
- getTrailingObjects<TemplateArgumentLoc>(), List);
- }
-
- TemplateArgumentLoc const *getTemplateArgs() const {
- if (!hasExplicitTemplateArgs())
- return nullptr;
-
- return getTrailingObjects<TemplateArgumentLoc>();
- }
-
- unsigned getNumTemplateArgs() const {
- if (!hasExplicitTemplateArgs())
- return 0;
-
- return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->NumTemplateArgs;
- }
-
- /// Note: getLocStart() is the start of the whole DependentScopeDeclRefExpr,
- /// and differs from getLocation().getStart().
- SourceLocation getLocStart() const LLVM_READONLY {
- return QualifierLoc.getBeginLoc();
- }
- SourceLocation getLocEnd() const LLVM_READONLY {
- if (hasExplicitTemplateArgs())
- return getRAngleLoc();
- return getLocation();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == DependentScopeDeclRefExprClass;
- }
-
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-
- friend TrailingObjects;
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-};
-
-/// Represents an expression -- generally a full-expression -- that
-/// introduces cleanups to be run at the end of the sub-expression's
-/// evaluation. The most common source of expression-introduced
-/// cleanups is temporary objects in C++, but several other kinds of
-/// expressions can create cleanups, including basically every
-/// call in ARC that returns an Objective-C pointer.
-///
-/// This expression also tracks whether the sub-expression contains a
-/// potentially-evaluated block literal. The lifetime of a block
-/// literal is the extent of the enclosing scope.
-class ExprWithCleanups final
- : public Expr,
- private llvm::TrailingObjects<ExprWithCleanups, BlockDecl *> {
-public:
- /// The type of objects that are kept in the cleanup.
- /// It's useful to remember the set of blocks; we could also
- /// remember the set of temporaries, but there's currently
- /// no need.
- typedef BlockDecl *CleanupObject;
-
-private:
- Stmt *SubExpr;
-
- ExprWithCleanups(EmptyShell, unsigned NumObjects);
- ExprWithCleanups(Expr *SubExpr, ArrayRef<CleanupObject> Objects);
-
- friend TrailingObjects;
- friend class ASTStmtReader;
-
-public:
- static ExprWithCleanups *Create(const ASTContext &C, EmptyShell empty,
- unsigned numObjects);
-
- static ExprWithCleanups *Create(const ASTContext &C, Expr *subexpr,
- ArrayRef<CleanupObject> objects);
-
- ArrayRef<CleanupObject> getObjects() const {
- return llvm::makeArrayRef(getTrailingObjects<CleanupObject>(),
- getNumObjects());
- }
-
- unsigned getNumObjects() const { return ExprWithCleanupsBits.NumObjects; }
-
- CleanupObject getObject(unsigned i) const {
- assert(i < getNumObjects() && "Index out of range");
- return getObjects()[i];
- }
-
- Expr *getSubExpr() { return cast<Expr>(SubExpr); }
- const Expr *getSubExpr() const { return cast<Expr>(SubExpr); }
-
- /// As with any mutator of the AST, be very careful
- /// when modifying an existing AST to preserve its invariants.
- void setSubExpr(Expr *E) { SubExpr = E; }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return SubExpr->getLocStart();
- }
- SourceLocation getLocEnd() const LLVM_READONLY { return SubExpr->getLocEnd();}
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ExprWithCleanupsClass;
- }
-
- // Iterators
- child_range children() { return child_range(&SubExpr, &SubExpr + 1); }
-};
-
-/// \brief Describes an explicit type conversion that uses functional
-/// notion but could not be resolved because one or more arguments are
-/// type-dependent.
-///
-/// The explicit type conversions expressed by
-/// CXXUnresolvedConstructExpr have the form <tt>T(a1, a2, ..., aN)</tt>,
-/// where \c T is some type and \c a1, \c a2, ..., \c aN are values, and
-/// either \c T is a dependent type or one or more of the <tt>a</tt>'s is
-/// type-dependent. For example, this would occur in a template such
-/// as:
-///
-/// \code
-/// template<typename T, typename A1>
-/// inline T make_a(const A1& a1) {
-/// return T(a1);
-/// }
-/// \endcode
-///
-/// When the returned expression is instantiated, it may resolve to a
-/// constructor call, conversion function call, or some kind of type
-/// conversion.
-class CXXUnresolvedConstructExpr final
- : public Expr,
- private llvm::TrailingObjects<CXXUnresolvedConstructExpr, Expr *> {
- /// \brief The type being constructed.
- TypeSourceInfo *Type;
-
- /// \brief The location of the left parentheses ('(').
- SourceLocation LParenLoc;
-
- /// \brief The location of the right parentheses (')').
- SourceLocation RParenLoc;
-
- /// \brief The number of arguments used to construct the type.
- unsigned NumArgs;
-
- CXXUnresolvedConstructExpr(TypeSourceInfo *Type,
- SourceLocation LParenLoc,
- ArrayRef<Expr*> Args,
- SourceLocation RParenLoc);
-
- CXXUnresolvedConstructExpr(EmptyShell Empty, unsigned NumArgs)
- : Expr(CXXUnresolvedConstructExprClass, Empty), Type(), NumArgs(NumArgs) { }
-
- friend TrailingObjects;
- friend class ASTStmtReader;
-
-public:
- static CXXUnresolvedConstructExpr *Create(const ASTContext &C,
- TypeSourceInfo *Type,
- SourceLocation LParenLoc,
- ArrayRef<Expr*> Args,
- SourceLocation RParenLoc);
-
- static CXXUnresolvedConstructExpr *CreateEmpty(const ASTContext &C,
- unsigned NumArgs);
-
- /// \brief Retrieve the type that is being constructed, as specified
- /// in the source code.
- QualType getTypeAsWritten() const { return Type->getType(); }
-
- /// \brief Retrieve the type source information for the type being
- /// constructed.
- TypeSourceInfo *getTypeSourceInfo() const { return Type; }
-
- /// \brief Retrieve the location of the left parentheses ('(') that
- /// precedes the argument list.
- SourceLocation getLParenLoc() const { return LParenLoc; }
- void setLParenLoc(SourceLocation L) { LParenLoc = L; }
-
- /// \brief Retrieve the location of the right parentheses (')') that
- /// follows the argument list.
- SourceLocation getRParenLoc() const { return RParenLoc; }
- void setRParenLoc(SourceLocation L) { RParenLoc = L; }
-
- /// \brief Retrieve the number of arguments.
- unsigned arg_size() const { return NumArgs; }
-
- typedef Expr** arg_iterator;
- arg_iterator arg_begin() { return getTrailingObjects<Expr *>(); }
- arg_iterator arg_end() { return arg_begin() + NumArgs; }
-
- typedef const Expr* const * const_arg_iterator;
- const_arg_iterator arg_begin() const { return getTrailingObjects<Expr *>(); }
- const_arg_iterator arg_end() const {
- return arg_begin() + NumArgs;
- }
-
- Expr *getArg(unsigned I) {
- assert(I < NumArgs && "Argument index out-of-range");
- return *(arg_begin() + I);
- }
-
- const Expr *getArg(unsigned I) const {
- assert(I < NumArgs && "Argument index out-of-range");
- return *(arg_begin() + I);
- }
-
- void setArg(unsigned I, Expr *E) {
- assert(I < NumArgs && "Argument index out-of-range");
- *(arg_begin() + I) = E;
- }
-
- SourceLocation getLocStart() const LLVM_READONLY;
- SourceLocation getLocEnd() const LLVM_READONLY {
- if (!RParenLoc.isValid() && NumArgs > 0)
- return getArg(NumArgs - 1)->getLocEnd();
- return RParenLoc;
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXUnresolvedConstructExprClass;
- }
-
- // Iterators
- child_range children() {
- Stmt **begin = reinterpret_cast<Stmt **>(arg_begin());
- return child_range(begin, begin + NumArgs);
- }
-};
-
-/// \brief Represents a C++ member access expression where the actual
-/// member referenced could not be resolved because the base
-/// expression or the member name was dependent.
-///
-/// Like UnresolvedMemberExprs, these can be either implicit or
-/// explicit accesses. It is only possible to get one of these with
-/// an implicit access if a qualifier is provided.
-class CXXDependentScopeMemberExpr final
- : public Expr,
- private llvm::TrailingObjects<CXXDependentScopeMemberExpr,
- ASTTemplateKWAndArgsInfo,
- TemplateArgumentLoc> {
- /// \brief The expression for the base pointer or class reference,
- /// e.g., the \c x in x.f. Can be null in implicit accesses.
- Stmt *Base;
-
- /// \brief The type of the base expression. Never null, even for
- /// implicit accesses.
- QualType BaseType;
-
- /// \brief Whether this member expression used the '->' operator or
- /// the '.' operator.
- bool IsArrow : 1;
-
- /// \brief Whether this member expression has info for explicit template
- /// keyword and arguments.
- bool HasTemplateKWAndArgsInfo : 1;
-
- /// \brief The location of the '->' or '.' operator.
- SourceLocation OperatorLoc;
-
- /// \brief The nested-name-specifier that precedes the member name, if any.
- NestedNameSpecifierLoc QualifierLoc;
-
- /// \brief In a qualified member access expression such as t->Base::f, this
- /// member stores the resolves of name lookup in the context of the member
- /// access expression, to be used at instantiation time.
- ///
- /// FIXME: This member, along with the QualifierLoc, could
- /// be stuck into a structure that is optionally allocated at the end of
- /// the CXXDependentScopeMemberExpr, to save space in the common case.
- NamedDecl *FirstQualifierFoundInScope;
-
- /// \brief The member to which this member expression refers, which
- /// can be name, overloaded operator, or destructor.
- ///
- /// FIXME: could also be a template-id
- DeclarationNameInfo MemberNameInfo;
-
- size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
- return HasTemplateKWAndArgsInfo ? 1 : 0;
- }
-
- CXXDependentScopeMemberExpr(const ASTContext &C, Expr *Base,
- QualType BaseType, bool IsArrow,
- SourceLocation OperatorLoc,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc,
- NamedDecl *FirstQualifierFoundInScope,
- DeclarationNameInfo MemberNameInfo,
- const TemplateArgumentListInfo *TemplateArgs);
-
-public:
- CXXDependentScopeMemberExpr(const ASTContext &C, Expr *Base,
- QualType BaseType, bool IsArrow,
- SourceLocation OperatorLoc,
- NestedNameSpecifierLoc QualifierLoc,
- NamedDecl *FirstQualifierFoundInScope,
- DeclarationNameInfo MemberNameInfo);
-
- static CXXDependentScopeMemberExpr *
- Create(const ASTContext &C, Expr *Base, QualType BaseType, bool IsArrow,
- SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierFoundInScope,
- DeclarationNameInfo MemberNameInfo,
- const TemplateArgumentListInfo *TemplateArgs);
-
- static CXXDependentScopeMemberExpr *
- CreateEmpty(const ASTContext &C, bool HasTemplateKWAndArgsInfo,
- unsigned NumTemplateArgs);
-
- /// \brief True if this is an implicit access, i.e. one in which the
- /// member being accessed was not written in the source. The source
- /// location of the operator is invalid in this case.
- bool isImplicitAccess() const;
-
- /// \brief Retrieve the base object of this member expressions,
- /// e.g., the \c x in \c x.m.
- Expr *getBase() const {
- assert(!isImplicitAccess());
- return cast<Expr>(Base);
- }
-
- QualType getBaseType() const { return BaseType; }
-
- /// \brief Determine whether this member expression used the '->'
- /// operator; otherwise, it used the '.' operator.
- bool isArrow() const { return IsArrow; }
-
- /// \brief Retrieve the location of the '->' or '.' operator.
- SourceLocation getOperatorLoc() const { return OperatorLoc; }
-
- /// \brief Retrieve the nested-name-specifier that qualifies the member
- /// name.
- NestedNameSpecifier *getQualifier() const {
- return QualifierLoc.getNestedNameSpecifier();
- }
-
- /// \brief Retrieve the nested-name-specifier that qualifies the member
- /// name, with source location information.
- NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
-
-
- /// \brief Retrieve the first part of the nested-name-specifier that was
- /// found in the scope of the member access expression when the member access
- /// was initially parsed.
- ///
- /// This function only returns a useful result when member access expression
- /// uses a qualified member name, e.g., "x.Base::f". Here, the declaration
- /// returned by this function describes what was found by unqualified name
- /// lookup for the identifier "Base" within the scope of the member access
- /// expression itself. At template instantiation time, this information is
- /// combined with the results of name lookup into the type of the object
- /// expression itself (the class type of x).
- NamedDecl *getFirstQualifierFoundInScope() const {
- return FirstQualifierFoundInScope;
- }
-
- /// \brief Retrieve the name of the member that this expression
- /// refers to.
- const DeclarationNameInfo &getMemberNameInfo() const {
- return MemberNameInfo;
- }
-
- /// \brief Retrieve the name of the member that this expression
- /// refers to.
- DeclarationName getMember() const { return MemberNameInfo.getName(); }
-
- // \brief Retrieve the location of the name of the member that this
- // expression refers to.
- SourceLocation getMemberLoc() const { return MemberNameInfo.getLoc(); }
-
- /// \brief Retrieve the location of the template keyword preceding the
- /// member name, if any.
- SourceLocation getTemplateKeywordLoc() const {
- if (!HasTemplateKWAndArgsInfo) return SourceLocation();
- return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->TemplateKWLoc;
- }
-
- /// \brief Retrieve the location of the left angle bracket starting the
- /// explicit template argument list following the member name, if any.
- SourceLocation getLAngleLoc() const {
- if (!HasTemplateKWAndArgsInfo) return SourceLocation();
- return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->LAngleLoc;
- }
-
- /// \brief Retrieve the location of the right angle bracket ending the
- /// explicit template argument list following the member name, if any.
- SourceLocation getRAngleLoc() const {
- if (!HasTemplateKWAndArgsInfo) return SourceLocation();
- return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->RAngleLoc;
- }
-
- /// Determines whether the member name was preceded by the template keyword.
- bool hasTemplateKeyword() const { return getTemplateKeywordLoc().isValid(); }
-
- /// \brief Determines whether this member expression actually had a C++
- /// template argument list explicitly specified, e.g., x.f<int>.
- bool hasExplicitTemplateArgs() const { return getLAngleLoc().isValid(); }
-
- /// \brief Copies the template arguments (if present) into the given
- /// structure.
- void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
- if (hasExplicitTemplateArgs())
- getTrailingObjects<ASTTemplateKWAndArgsInfo>()->copyInto(
- getTrailingObjects<TemplateArgumentLoc>(), List);
- }
-
- /// \brief Retrieve the template arguments provided as part of this
- /// template-id.
- const TemplateArgumentLoc *getTemplateArgs() const {
- if (!hasExplicitTemplateArgs())
- return nullptr;
-
- return getTrailingObjects<TemplateArgumentLoc>();
- }
-
- /// \brief Retrieve the number of template arguments provided as part of this
- /// template-id.
- unsigned getNumTemplateArgs() const {
- if (!hasExplicitTemplateArgs())
- return 0;
-
- return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->NumTemplateArgs;
- }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- if (!isImplicitAccess())
- return Base->getLocStart();
- if (getQualifier())
- return getQualifierLoc().getBeginLoc();
- return MemberNameInfo.getBeginLoc();
- }
-
- SourceLocation getLocEnd() const LLVM_READONLY {
- if (hasExplicitTemplateArgs())
- return getRAngleLoc();
- return MemberNameInfo.getEndLoc();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXDependentScopeMemberExprClass;
- }
-
- // Iterators
- child_range children() {
- if (isImplicitAccess())
- return child_range(child_iterator(), child_iterator());
- return child_range(&Base, &Base + 1);
- }
-
- friend TrailingObjects;
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-};
-
-/// \brief Represents a C++ member access expression for which lookup
-/// produced a set of overloaded functions.
-///
-/// The member access may be explicit or implicit:
-/// \code
-/// struct A {
-/// int a, b;
-/// int explicitAccess() { return this->a + this->A::b; }
-/// int implicitAccess() { return a + A::b; }
-/// };
-/// \endcode
-///
-/// In the final AST, an explicit access always becomes a MemberExpr.
-/// An implicit access may become either a MemberExpr or a
-/// DeclRefExpr, depending on whether the member is static.
-class UnresolvedMemberExpr final
- : public OverloadExpr,
- private llvm::TrailingObjects<
- UnresolvedMemberExpr, ASTTemplateKWAndArgsInfo, TemplateArgumentLoc> {
- /// \brief Whether this member expression used the '->' operator or
- /// the '.' operator.
- bool IsArrow : 1;
-
- /// \brief Whether the lookup results contain an unresolved using
- /// declaration.
- bool HasUnresolvedUsing : 1;
-
- /// \brief The expression for the base pointer or class reference,
- /// e.g., the \c x in x.f.
- ///
- /// This can be null if this is an 'unbased' member expression.
- Stmt *Base;
-
- /// \brief The type of the base expression; never null.
- QualType BaseType;
-
- /// \brief The location of the '->' or '.' operator.
- SourceLocation OperatorLoc;
-
- size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
- return HasTemplateKWAndArgsInfo ? 1 : 0;
- }
-
- UnresolvedMemberExpr(const ASTContext &C, bool HasUnresolvedUsing,
- Expr *Base, QualType BaseType, bool IsArrow,
- SourceLocation OperatorLoc,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc,
- const DeclarationNameInfo &MemberNameInfo,
- const TemplateArgumentListInfo *TemplateArgs,
- UnresolvedSetIterator Begin, UnresolvedSetIterator End);
-
- UnresolvedMemberExpr(EmptyShell Empty)
- : OverloadExpr(UnresolvedMemberExprClass, Empty), IsArrow(false),
- HasUnresolvedUsing(false), Base(nullptr) { }
-
- friend TrailingObjects;
- friend class OverloadExpr;
- friend class ASTStmtReader;
-
-public:
- static UnresolvedMemberExpr *
- Create(const ASTContext &C, bool HasUnresolvedUsing,
- Expr *Base, QualType BaseType, bool IsArrow,
- SourceLocation OperatorLoc,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc,
- const DeclarationNameInfo &MemberNameInfo,
- const TemplateArgumentListInfo *TemplateArgs,
- UnresolvedSetIterator Begin, UnresolvedSetIterator End);
-
- static UnresolvedMemberExpr *
- CreateEmpty(const ASTContext &C, bool HasTemplateKWAndArgsInfo,
- unsigned NumTemplateArgs);
-
- /// \brief True if this is an implicit access, i.e., one in which the
- /// member being accessed was not written in the source.
- ///
- /// The source location of the operator is invalid in this case.
- bool isImplicitAccess() const;
-
- /// \brief Retrieve the base object of this member expressions,
- /// e.g., the \c x in \c x.m.
- Expr *getBase() {
- assert(!isImplicitAccess());
- return cast<Expr>(Base);
- }
- const Expr *getBase() const {
- assert(!isImplicitAccess());
- return cast<Expr>(Base);
- }
-
- QualType getBaseType() const { return BaseType; }
-
- /// \brief Determine whether the lookup results contain an unresolved using
- /// declaration.
- bool hasUnresolvedUsing() const { return HasUnresolvedUsing; }
-
- /// \brief Determine whether this member expression used the '->'
- /// operator; otherwise, it used the '.' operator.
- bool isArrow() const { return IsArrow; }
-
- /// \brief Retrieve the location of the '->' or '.' operator.
- SourceLocation getOperatorLoc() const { return OperatorLoc; }
-
- /// \brief Retrieve the naming class of this lookup.
- CXXRecordDecl *getNamingClass() const;
-
- /// \brief Retrieve the full name info for the member that this expression
- /// refers to.
- const DeclarationNameInfo &getMemberNameInfo() const { return getNameInfo(); }
-
- /// \brief Retrieve the name of the member that this expression
- /// refers to.
- DeclarationName getMemberName() const { return getName(); }
-
- // \brief Retrieve the location of the name of the member that this
- // expression refers to.
- SourceLocation getMemberLoc() const { return getNameLoc(); }
-
- // \brief Return the preferred location (the member name) for the arrow when
- // diagnosing a problem with this expression.
- SourceLocation getExprLoc() const LLVM_READONLY { return getMemberLoc(); }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- if (!isImplicitAccess())
- return Base->getLocStart();
- if (NestedNameSpecifierLoc l = getQualifierLoc())
- return l.getBeginLoc();
- return getMemberNameInfo().getLocStart();
- }
- SourceLocation getLocEnd() const LLVM_READONLY {
- if (hasExplicitTemplateArgs())
- return getRAngleLoc();
- return getMemberNameInfo().getLocEnd();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == UnresolvedMemberExprClass;
- }
-
- // Iterators
- child_range children() {
- if (isImplicitAccess())
- return child_range(child_iterator(), child_iterator());
- return child_range(&Base, &Base + 1);
- }
-};
-
-inline ASTTemplateKWAndArgsInfo *
-OverloadExpr::getTrailingASTTemplateKWAndArgsInfo() {
- if (!HasTemplateKWAndArgsInfo)
- return nullptr;
-
- if (isa<UnresolvedLookupExpr>(this))
- return cast<UnresolvedLookupExpr>(this)
- ->getTrailingObjects<ASTTemplateKWAndArgsInfo>();
- else
- return cast<UnresolvedMemberExpr>(this)
- ->getTrailingObjects<ASTTemplateKWAndArgsInfo>();
-}
-
-inline TemplateArgumentLoc *OverloadExpr::getTrailingTemplateArgumentLoc() {
- if (isa<UnresolvedLookupExpr>(this))
- return cast<UnresolvedLookupExpr>(this)
- ->getTrailingObjects<TemplateArgumentLoc>();
- else
- return cast<UnresolvedMemberExpr>(this)
- ->getTrailingObjects<TemplateArgumentLoc>();
-}
-
-/// \brief Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]).
-///
-/// The noexcept expression tests whether a given expression might throw. Its
-/// result is a boolean constant.
-class CXXNoexceptExpr : public Expr {
- bool Value : 1;
- Stmt *Operand;
- SourceRange Range;
-
- friend class ASTStmtReader;
-
-public:
- CXXNoexceptExpr(QualType Ty, Expr *Operand, CanThrowResult Val,
- SourceLocation Keyword, SourceLocation RParen)
- : Expr(CXXNoexceptExprClass, Ty, VK_RValue, OK_Ordinary,
- /*TypeDependent*/false,
- /*ValueDependent*/Val == CT_Dependent,
- Val == CT_Dependent || Operand->isInstantiationDependent(),
- Operand->containsUnexpandedParameterPack()),
- Value(Val == CT_Cannot), Operand(Operand), Range(Keyword, RParen)
- { }
-
- CXXNoexceptExpr(EmptyShell Empty)
- : Expr(CXXNoexceptExprClass, Empty)
- { }
-
- Expr *getOperand() const { return static_cast<Expr*>(Operand); }
-
- SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
- SourceRange getSourceRange() const LLVM_READONLY { return Range; }
-
- bool getValue() const { return Value; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXNoexceptExprClass;
- }
-
- // Iterators
- child_range children() { return child_range(&Operand, &Operand + 1); }
-};
-
-/// \brief Represents a C++11 pack expansion that produces a sequence of
-/// expressions.
-///
-/// A pack expansion expression contains a pattern (which itself is an
-/// expression) followed by an ellipsis. For example:
-///
-/// \code
-/// template<typename F, typename ...Types>
-/// void forward(F f, Types &&...args) {
-/// f(static_cast<Types&&>(args)...);
-/// }
-/// \endcode
-///
-/// Here, the argument to the function object \c f is a pack expansion whose
-/// pattern is \c static_cast<Types&&>(args). When the \c forward function
-/// template is instantiated, the pack expansion will instantiate to zero or
-/// or more function arguments to the function object \c f.
-class PackExpansionExpr : public Expr {
- SourceLocation EllipsisLoc;
-
- /// \brief The number of expansions that will be produced by this pack
- /// expansion expression, if known.
- ///
- /// When zero, the number of expansions is not known. Otherwise, this value
- /// is the number of expansions + 1.
- unsigned NumExpansions;
-
- Stmt *Pattern;
-
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-
-public:
- PackExpansionExpr(QualType T, Expr *Pattern, SourceLocation EllipsisLoc,
- Optional<unsigned> NumExpansions)
- : Expr(PackExpansionExprClass, T, Pattern->getValueKind(),
- Pattern->getObjectKind(), /*TypeDependent=*/true,
- /*ValueDependent=*/true, /*InstantiationDependent=*/true,
- /*ContainsUnexpandedParameterPack=*/false),
- EllipsisLoc(EllipsisLoc),
- NumExpansions(NumExpansions? *NumExpansions + 1 : 0),
- Pattern(Pattern) { }
-
- PackExpansionExpr(EmptyShell Empty) : Expr(PackExpansionExprClass, Empty) { }
-
- /// \brief Retrieve the pattern of the pack expansion.
- Expr *getPattern() { return reinterpret_cast<Expr *>(Pattern); }
-
- /// \brief Retrieve the pattern of the pack expansion.
- const Expr *getPattern() const { return reinterpret_cast<Expr *>(Pattern); }
-
- /// \brief Retrieve the location of the ellipsis that describes this pack
- /// expansion.
- SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
-
- /// \brief Determine the number of expansions that will be produced when
- /// this pack expansion is instantiated, if already known.
- Optional<unsigned> getNumExpansions() const {
- if (NumExpansions)
- return NumExpansions - 1;
-
- return None;
- }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return Pattern->getLocStart();
- }
- SourceLocation getLocEnd() const LLVM_READONLY { return EllipsisLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == PackExpansionExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(&Pattern, &Pattern + 1);
- }
-};
-
-
-/// \brief Represents an expression that computes the length of a parameter
-/// pack.
-///
-/// \code
-/// template<typename ...Types>
-/// struct count {
-/// static const unsigned value = sizeof...(Types);
-/// };
-/// \endcode
-class SizeOfPackExpr final
- : public Expr,
- private llvm::TrailingObjects<SizeOfPackExpr, TemplateArgument> {
- /// \brief The location of the \c sizeof keyword.
- SourceLocation OperatorLoc;
-
- /// \brief The location of the name of the parameter pack.
- SourceLocation PackLoc;
-
- /// \brief The location of the closing parenthesis.
- SourceLocation RParenLoc;
-
- /// \brief The length of the parameter pack, if known.
- ///
- /// When this expression is not value-dependent, this is the length of
- /// the pack. When the expression was parsed rather than instantiated
- /// (and thus is value-dependent), this is zero.
- ///
- /// After partial substitution into a sizeof...(X) expression (for instance,
- /// within an alias template or during function template argument deduction),
- /// we store a trailing array of partially-substituted TemplateArguments,
- /// and this is the length of that array.
- unsigned Length;
-
- /// \brief The parameter pack.
- NamedDecl *Pack;
-
- friend TrailingObjects;
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-
- /// \brief Create an expression that computes the length of
- /// the given parameter pack.
- SizeOfPackExpr(QualType SizeType, SourceLocation OperatorLoc, NamedDecl *Pack,
- SourceLocation PackLoc, SourceLocation RParenLoc,
- Optional<unsigned> Length, ArrayRef<TemplateArgument> PartialArgs)
- : Expr(SizeOfPackExprClass, SizeType, VK_RValue, OK_Ordinary,
- /*TypeDependent=*/false, /*ValueDependent=*/!Length,
- /*InstantiationDependent=*/!Length,
- /*ContainsUnexpandedParameterPack=*/false),
- OperatorLoc(OperatorLoc), PackLoc(PackLoc), RParenLoc(RParenLoc),
- Length(Length ? *Length : PartialArgs.size()), Pack(Pack) {
- assert((!Length || PartialArgs.empty()) &&
- "have partial args for non-dependent sizeof... expression");
- TemplateArgument *Args = getTrailingObjects<TemplateArgument>();
- std::uninitialized_copy(PartialArgs.begin(), PartialArgs.end(), Args);
- }
-
- /// \brief Create an empty expression.
- SizeOfPackExpr(EmptyShell Empty, unsigned NumPartialArgs)
- : Expr(SizeOfPackExprClass, Empty), Length(NumPartialArgs), Pack() {}
-
-public:
- static SizeOfPackExpr *Create(ASTContext &Context, SourceLocation OperatorLoc,
- NamedDecl *Pack, SourceLocation PackLoc,
- SourceLocation RParenLoc,
- Optional<unsigned> Length = None,
- ArrayRef<TemplateArgument> PartialArgs = None);
- static SizeOfPackExpr *CreateDeserialized(ASTContext &Context,
- unsigned NumPartialArgs);
-
- /// \brief Determine the location of the 'sizeof' keyword.
- SourceLocation getOperatorLoc() const { return OperatorLoc; }
-
- /// \brief Determine the location of the parameter pack.
- SourceLocation getPackLoc() const { return PackLoc; }
-
- /// \brief Determine the location of the right parenthesis.
- SourceLocation getRParenLoc() const { return RParenLoc; }
-
- /// \brief Retrieve the parameter pack.
- NamedDecl *getPack() const { return Pack; }
-
- /// \brief Retrieve the length of the parameter pack.
- ///
- /// This routine may only be invoked when the expression is not
- /// value-dependent.
- unsigned getPackLength() const {
- assert(!isValueDependent() &&
- "Cannot get the length of a value-dependent pack size expression");
- return Length;
- }
-
- /// \brief Determine whether this represents a partially-substituted sizeof...
- /// expression, such as is produced for:
- ///
- /// template<typename ...Ts> using X = int[sizeof...(Ts)];
- /// template<typename ...Us> void f(X<Us..., 1, 2, 3, Us...>);
- bool isPartiallySubstituted() const {
- return isValueDependent() && Length;
- }
-
- /// \brief Get
- ArrayRef<TemplateArgument> getPartialArguments() const {
- assert(isPartiallySubstituted());
- const TemplateArgument *Args = getTrailingObjects<TemplateArgument>();
- return llvm::makeArrayRef(Args, Args + Length);
- }
-
- SourceLocation getLocStart() const LLVM_READONLY { return OperatorLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == SizeOfPackExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// \brief Represents a reference to a non-type template parameter
-/// that has been substituted with a template argument.
-class SubstNonTypeTemplateParmExpr : public Expr {
- /// \brief The replaced parameter.
- NonTypeTemplateParmDecl *Param;
-
- /// \brief The replacement expression.
- Stmt *Replacement;
-
- /// \brief The location of the non-type template parameter reference.
- SourceLocation NameLoc;
-
- friend class ASTReader;
- friend class ASTStmtReader;
- explicit SubstNonTypeTemplateParmExpr(EmptyShell Empty)
- : Expr(SubstNonTypeTemplateParmExprClass, Empty) { }
-
-public:
- SubstNonTypeTemplateParmExpr(QualType type,
- ExprValueKind valueKind,
- SourceLocation loc,
- NonTypeTemplateParmDecl *param,
- Expr *replacement)
- : Expr(SubstNonTypeTemplateParmExprClass, type, valueKind, OK_Ordinary,
- replacement->isTypeDependent(), replacement->isValueDependent(),
- replacement->isInstantiationDependent(),
- replacement->containsUnexpandedParameterPack()),
- Param(param), Replacement(replacement), NameLoc(loc) {}
-
- SourceLocation getNameLoc() const { return NameLoc; }
- SourceLocation getLocStart() const LLVM_READONLY { return NameLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return NameLoc; }
-
- Expr *getReplacement() const { return cast<Expr>(Replacement); }
-
- NonTypeTemplateParmDecl *getParameter() const { return Param; }
-
- static bool classof(const Stmt *s) {
- return s->getStmtClass() == SubstNonTypeTemplateParmExprClass;
- }
-
- // Iterators
- child_range children() { return child_range(&Replacement, &Replacement+1); }
-};
-
-/// \brief Represents a reference to a non-type template parameter pack that
-/// has been substituted with a non-template argument pack.
-///
-/// When a pack expansion in the source code contains multiple parameter packs
-/// and those parameter packs correspond to different levels of template
-/// parameter lists, this node is used to represent a non-type template
-/// parameter pack from an outer level, which has already had its argument pack
-/// substituted but that still lives within a pack expansion that itself
-/// could not be instantiated. When actually performing a substitution into
-/// that pack expansion (e.g., when all template parameters have corresponding
-/// arguments), this type will be replaced with the appropriate underlying
-/// expression at the current pack substitution index.
-class SubstNonTypeTemplateParmPackExpr : public Expr {
- /// \brief The non-type template parameter pack itself.
- NonTypeTemplateParmDecl *Param;
-
- /// \brief A pointer to the set of template arguments that this
- /// parameter pack is instantiated with.
- const TemplateArgument *Arguments;
-
- /// \brief The number of template arguments in \c Arguments.
- unsigned NumArguments;
-
- /// \brief The location of the non-type template parameter pack reference.
- SourceLocation NameLoc;
-
- friend class ASTReader;
- friend class ASTStmtReader;
- explicit SubstNonTypeTemplateParmPackExpr(EmptyShell Empty)
- : Expr(SubstNonTypeTemplateParmPackExprClass, Empty) { }
-
-public:
- SubstNonTypeTemplateParmPackExpr(QualType T,
- NonTypeTemplateParmDecl *Param,
- SourceLocation NameLoc,
- const TemplateArgument &ArgPack);
-
- /// \brief Retrieve the non-type template parameter pack being substituted.
- NonTypeTemplateParmDecl *getParameterPack() const { return Param; }
-
- /// \brief Retrieve the location of the parameter pack name.
- SourceLocation getParameterPackLocation() const { return NameLoc; }
-
- /// \brief Retrieve the template argument pack containing the substituted
- /// template arguments.
- TemplateArgument getArgumentPack() const;
-
- SourceLocation getLocStart() const LLVM_READONLY { return NameLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return NameLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == SubstNonTypeTemplateParmPackExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// \brief Represents a reference to a function parameter pack that has been
-/// substituted but not yet expanded.
-///
-/// When a pack expansion contains multiple parameter packs at different levels,
-/// this node is used to represent a function parameter pack at an outer level
-/// which we have already substituted to refer to expanded parameters, but where
-/// the containing pack expansion cannot yet be expanded.
-///
-/// \code
-/// template<typename...Ts> struct S {
-/// template<typename...Us> auto f(Ts ...ts) -> decltype(g(Us(ts)...));
-/// };
-/// template struct S<int, int>;
-/// \endcode
-class FunctionParmPackExpr final
- : public Expr,
- private llvm::TrailingObjects<FunctionParmPackExpr, ParmVarDecl *> {
- /// \brief The function parameter pack which was referenced.
- ParmVarDecl *ParamPack;
-
- /// \brief The location of the function parameter pack reference.
- SourceLocation NameLoc;
-
- /// \brief The number of expansions of this pack.
- unsigned NumParameters;
-
- FunctionParmPackExpr(QualType T, ParmVarDecl *ParamPack,
- SourceLocation NameLoc, unsigned NumParams,
- ParmVarDecl *const *Params);
-
- friend TrailingObjects;
- friend class ASTReader;
- friend class ASTStmtReader;
-
-public:
- static FunctionParmPackExpr *Create(const ASTContext &Context, QualType T,
- ParmVarDecl *ParamPack,
- SourceLocation NameLoc,
- ArrayRef<ParmVarDecl *> Params);
- static FunctionParmPackExpr *CreateEmpty(const ASTContext &Context,
- unsigned NumParams);
-
- /// \brief Get the parameter pack which this expression refers to.
- ParmVarDecl *getParameterPack() const { return ParamPack; }
-
- /// \brief Get the location of the parameter pack.
- SourceLocation getParameterPackLocation() const { return NameLoc; }
-
- /// \brief Iterators over the parameters which the parameter pack expanded
- /// into.
- typedef ParmVarDecl * const *iterator;
- iterator begin() const { return getTrailingObjects<ParmVarDecl *>(); }
- iterator end() const { return begin() + NumParameters; }
-
- /// \brief Get the number of parameters in this parameter pack.
- unsigned getNumExpansions() const { return NumParameters; }
-
- /// \brief Get an expansion of the parameter pack by index.
- ParmVarDecl *getExpansion(unsigned I) const { return begin()[I]; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return NameLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return NameLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == FunctionParmPackExprClass;
- }
-
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// \brief Represents a prvalue temporary that is written into memory so that
-/// a reference can bind to it.
-///
-/// Prvalue expressions are materialized when they need to have an address
-/// in memory for a reference to bind to. This happens when binding a
-/// reference to the result of a conversion, e.g.,
-///
-/// \code
-/// const int &r = 1.0;
-/// \endcode
-///
-/// Here, 1.0 is implicitly converted to an \c int. That resulting \c int is
-/// then materialized via a \c MaterializeTemporaryExpr, and the reference
-/// binds to the temporary. \c MaterializeTemporaryExprs are always glvalues
-/// (either an lvalue or an xvalue, depending on the kind of reference binding
-/// to it), maintaining the invariant that references always bind to glvalues.
-///
-/// Reference binding and copy-elision can both extend the lifetime of a
-/// temporary. When either happens, the expression will also track the
-/// declaration which is responsible for the lifetime extension.
-class MaterializeTemporaryExpr : public Expr {
-private:
- struct ExtraState {
- /// \brief The temporary-generating expression whose value will be
- /// materialized.
- Stmt *Temporary;
-
- /// \brief The declaration which lifetime-extended this reference, if any.
- /// Either a VarDecl, or (for a ctor-initializer) a FieldDecl.
- const ValueDecl *ExtendingDecl;
-
- unsigned ManglingNumber;
- };
- llvm::PointerUnion<Stmt *, ExtraState *> State;
-
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-
- void initializeExtraState(const ValueDecl *ExtendedBy,
- unsigned ManglingNumber);
-
-public:
- MaterializeTemporaryExpr(QualType T, Expr *Temporary,
- bool BoundToLvalueReference)
- : Expr(MaterializeTemporaryExprClass, T,
- BoundToLvalueReference? VK_LValue : VK_XValue, OK_Ordinary,
- Temporary->isTypeDependent(), Temporary->isValueDependent(),
- Temporary->isInstantiationDependent(),
- Temporary->containsUnexpandedParameterPack()),
- State(Temporary) {}
-
- MaterializeTemporaryExpr(EmptyShell Empty)
- : Expr(MaterializeTemporaryExprClass, Empty) { }
-
- Stmt *getTemporary() const {
- return State.is<Stmt *>() ? State.get<Stmt *>()
- : State.get<ExtraState *>()->Temporary;
- }
-
- /// \brief Retrieve the temporary-generating subexpression whose value will
- /// be materialized into a glvalue.
- Expr *GetTemporaryExpr() const { return static_cast<Expr *>(getTemporary()); }
-
- /// \brief Retrieve the storage duration for the materialized temporary.
- StorageDuration getStorageDuration() const {
- const ValueDecl *ExtendingDecl = getExtendingDecl();
- if (!ExtendingDecl)
- return SD_FullExpression;
- // FIXME: This is not necessarily correct for a temporary materialized
- // within a default initializer.
- if (isa<FieldDecl>(ExtendingDecl))
- return SD_Automatic;
- return cast<VarDecl>(ExtendingDecl)->getStorageDuration();
- }
-
- /// \brief Get the declaration which triggered the lifetime-extension of this
- /// temporary, if any.
- const ValueDecl *getExtendingDecl() const {
- return State.is<Stmt *>() ? nullptr
- : State.get<ExtraState *>()->ExtendingDecl;
- }
-
- void setExtendingDecl(const ValueDecl *ExtendedBy, unsigned ManglingNumber);
-
- unsigned getManglingNumber() const {
- return State.is<Stmt *>() ? 0 : State.get<ExtraState *>()->ManglingNumber;
- }
-
- /// \brief Determine whether this materialized temporary is bound to an
- /// lvalue reference; otherwise, it's bound to an rvalue reference.
- bool isBoundToLvalueReference() const {
- return getValueKind() == VK_LValue;
- }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return getTemporary()->getLocStart();
- }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return getTemporary()->getLocEnd();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == MaterializeTemporaryExprClass;
- }
-
- // Iterators
- child_range children() {
- if (State.is<Stmt *>())
- return child_range(State.getAddrOfPtr1(), State.getAddrOfPtr1() + 1);
-
- auto ES = State.get<ExtraState *>();
- return child_range(&ES->Temporary, &ES->Temporary + 1);
- }
-};
-
-/// \brief Represents a folding of a pack over an operator.
-///
-/// This expression is always dependent and represents a pack expansion of the
-/// forms:
-///
-/// ( expr op ... )
-/// ( ... op expr )
-/// ( expr op ... op expr )
-class CXXFoldExpr : public Expr {
- SourceLocation LParenLoc;
- SourceLocation EllipsisLoc;
- SourceLocation RParenLoc;
- Stmt *SubExprs[2];
- BinaryOperatorKind Opcode;
-
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-public:
- CXXFoldExpr(QualType T, SourceLocation LParenLoc, Expr *LHS,
- BinaryOperatorKind Opcode, SourceLocation EllipsisLoc, Expr *RHS,
- SourceLocation RParenLoc)
- : Expr(CXXFoldExprClass, T, VK_RValue, OK_Ordinary,
- /*Dependent*/ true, true, true,
- /*ContainsUnexpandedParameterPack*/ false),
- LParenLoc(LParenLoc), EllipsisLoc(EllipsisLoc), RParenLoc(RParenLoc),
- Opcode(Opcode) {
- SubExprs[0] = LHS;
- SubExprs[1] = RHS;
- }
- CXXFoldExpr(EmptyShell Empty) : Expr(CXXFoldExprClass, Empty) {}
-
- Expr *getLHS() const { return static_cast<Expr*>(SubExprs[0]); }
- Expr *getRHS() const { return static_cast<Expr*>(SubExprs[1]); }
-
- /// Does this produce a right-associated sequence of operators?
- bool isRightFold() const {
- return getLHS() && getLHS()->containsUnexpandedParameterPack();
- }
- /// Does this produce a left-associated sequence of operators?
- bool isLeftFold() const { return !isRightFold(); }
- /// Get the pattern, that is, the operand that contains an unexpanded pack.
- Expr *getPattern() const { return isLeftFold() ? getRHS() : getLHS(); }
- /// Get the operand that doesn't contain a pack, for a binary fold.
- Expr *getInit() const { return isLeftFold() ? getLHS() : getRHS(); }
-
- SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
- BinaryOperatorKind getOperator() const { return Opcode; }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return LParenLoc;
- }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return RParenLoc;
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXFoldExprClass;
- }
-
- // Iterators
- child_range children() { return child_range(SubExprs, SubExprs + 2); }
-};
-
-/// \brief Represents an expression that might suspend coroutine execution;
-/// either a co_await or co_yield expression.
-///
-/// Evaluation of this expression first evaluates its 'ready' expression. If
-/// that returns 'false':
-/// -- execution of the coroutine is suspended
-/// -- the 'suspend' expression is evaluated
-/// -- if the 'suspend' expression returns 'false', the coroutine is
-/// resumed
-/// -- otherwise, control passes back to the resumer.
-/// If the coroutine is not suspended, or when it is resumed, the 'resume'
-/// expression is evaluated, and its result is the result of the overall
-/// expression.
-class CoroutineSuspendExpr : public Expr {
- SourceLocation KeywordLoc;
-
- enum SubExpr { Common, Ready, Suspend, Resume, Count };
- Stmt *SubExprs[SubExpr::Count];
-
- friend class ASTStmtReader;
-public:
- CoroutineSuspendExpr(StmtClass SC, SourceLocation KeywordLoc, Expr *Common,
- Expr *Ready, Expr *Suspend, Expr *Resume)
- : Expr(SC, Resume->getType(), Resume->getValueKind(),
- Resume->getObjectKind(), Resume->isTypeDependent(),
- Resume->isValueDependent(), Common->isInstantiationDependent(),
- Common->containsUnexpandedParameterPack()),
- KeywordLoc(KeywordLoc) {
- SubExprs[SubExpr::Common] = Common;
- SubExprs[SubExpr::Ready] = Ready;
- SubExprs[SubExpr::Suspend] = Suspend;
- SubExprs[SubExpr::Resume] = Resume;
- }
- CoroutineSuspendExpr(StmtClass SC, SourceLocation KeywordLoc, QualType Ty,
- Expr *Common)
- : Expr(SC, Ty, VK_RValue, OK_Ordinary, true, true, true,
- Common->containsUnexpandedParameterPack()),
- KeywordLoc(KeywordLoc) {
- assert(Common->isTypeDependent() && Ty->isDependentType() &&
- "wrong constructor for non-dependent co_await/co_yield expression");
- SubExprs[SubExpr::Common] = Common;
- SubExprs[SubExpr::Ready] = nullptr;
- SubExprs[SubExpr::Suspend] = nullptr;
- SubExprs[SubExpr::Resume] = nullptr;
- }
- CoroutineSuspendExpr(StmtClass SC, EmptyShell Empty) : Expr(SC, Empty) {
- SubExprs[SubExpr::Common] = nullptr;
- SubExprs[SubExpr::Ready] = nullptr;
- SubExprs[SubExpr::Suspend] = nullptr;
- SubExprs[SubExpr::Resume] = nullptr;
- }
-
- SourceLocation getKeywordLoc() const { return KeywordLoc; }
- Expr *getCommonExpr() const {
- return static_cast<Expr*>(SubExprs[SubExpr::Common]);
- }
-
- Expr *getReadyExpr() const {
- return static_cast<Expr*>(SubExprs[SubExpr::Ready]);
- }
- Expr *getSuspendExpr() const {
- return static_cast<Expr*>(SubExprs[SubExpr::Suspend]);
- }
- Expr *getResumeExpr() const {
- return static_cast<Expr*>(SubExprs[SubExpr::Resume]);
- }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return KeywordLoc;
- }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return getCommonExpr()->getLocEnd();
- }
-
- child_range children() {
- return child_range(SubExprs, SubExprs + SubExpr::Count);
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CoawaitExprClass ||
- T->getStmtClass() == CoyieldExprClass;
- }
-};
-
-/// \brief Represents a 'co_await' expression.
-class CoawaitExpr : public CoroutineSuspendExpr {
- friend class ASTStmtReader;
-public:
- CoawaitExpr(SourceLocation CoawaitLoc, Expr *Operand, Expr *Ready,
- Expr *Suspend, Expr *Resume)
- : CoroutineSuspendExpr(CoawaitExprClass, CoawaitLoc, Operand, Ready,
- Suspend, Resume) {}
- CoawaitExpr(SourceLocation CoawaitLoc, QualType Ty, Expr *Operand)
- : CoroutineSuspendExpr(CoawaitExprClass, CoawaitLoc, Ty, Operand) {}
- CoawaitExpr(EmptyShell Empty)
- : CoroutineSuspendExpr(CoawaitExprClass, Empty) {}
-
- Expr *getOperand() const {
- // FIXME: Dig out the actual operand or store it.
- return getCommonExpr();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CoawaitExprClass;
- }
-};
-
-/// \brief Represents a 'co_yield' expression.
-class CoyieldExpr : public CoroutineSuspendExpr {
- friend class ASTStmtReader;
-public:
- CoyieldExpr(SourceLocation CoyieldLoc, Expr *Operand, Expr *Ready,
- Expr *Suspend, Expr *Resume)
- : CoroutineSuspendExpr(CoyieldExprClass, CoyieldLoc, Operand, Ready,
- Suspend, Resume) {}
- CoyieldExpr(SourceLocation CoyieldLoc, QualType Ty, Expr *Operand)
- : CoroutineSuspendExpr(CoyieldExprClass, CoyieldLoc, Ty, Operand) {}
- CoyieldExpr(EmptyShell Empty)
- : CoroutineSuspendExpr(CoyieldExprClass, Empty) {}
-
- Expr *getOperand() const {
- // FIXME: Dig out the actual operand or store it.
- return getCommonExpr();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CoyieldExprClass;
- }
-};
-
-} // end namespace clang
-
-#endif
OpenPOWER on IntegriCloud