aboutsummaryrefslogtreecommitdiff
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.h392
1 files changed, 114 insertions, 278 deletions
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index 6356ee7aee63..3a43d6dac140 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -20,7 +20,7 @@
#include "clang/AST/TemplateBase.h"
#include "clang/AST/UnresolvedSet.h"
#include "clang/Basic/ExpressionTraits.h"
-#include "clang/Basic/Lambda.h"
+#include "clang/AST/LambdaCapture.h"
#include "clang/Basic/TypeTraits.h"
#include "llvm/Support/Compiler.h"
@@ -486,7 +486,7 @@ class CXXStdInitializerListExpr : public Expr {
Stmt *SubExpr;
CXXStdInitializerListExpr(EmptyShell Empty)
- : Expr(CXXStdInitializerListExprClass, Empty), SubExpr(0) {}
+ : Expr(CXXStdInitializerListExprClass, Empty), SubExpr(nullptr) {}
public:
CXXStdInitializerListExpr(QualType Ty, Expr *SubExpr)
@@ -553,9 +553,9 @@ public:
CXXTypeidExpr(EmptyShell Empty, bool isExpr)
: Expr(CXXTypeidExprClass, Empty) {
if (isExpr)
- Operand = (Expr*)0;
+ Operand = (Expr*)nullptr;
else
- Operand = (TypeSourceInfo*)0;
+ Operand = (TypeSourceInfo*)nullptr;
}
/// Determine whether this typeid has a type operand which is potentially
@@ -692,9 +692,9 @@ public:
CXXUuidofExpr(EmptyShell Empty, bool isExpr)
: Expr(CXXUuidofExprClass, Empty) {
if (isExpr)
- Operand = (Expr*)0;
+ Operand = (Expr*)nullptr;
else
- Operand = (TypeSourceInfo*)0;
+ Operand = (TypeSourceInfo*)nullptr;
}
bool isTypeOperand() const { return Operand.is<TypeSourceInfo *>(); }
@@ -737,8 +737,8 @@ public:
/// Grabs __declspec(uuid()) off a type, or returns 0 if we cannot resolve to
/// a single GUID.
- static UuidAttr *GetUuidAttrOfType(QualType QT,
- bool *HasMultipleGUIDsPtr = 0);
+ static const UuidAttr *GetUuidAttrOfType(QualType QT,
+ bool *HasMultipleGUIDsPtr = nullptr);
// Iterators
child_range children() {
@@ -832,7 +832,7 @@ public:
SourceLocation getLocStart() const LLVM_READONLY { return ThrowLoc; }
SourceLocation getLocEnd() const LLVM_READONLY {
- if (getSubExpr() == 0)
+ if (!getSubExpr())
return ThrowLoc;
return getSubExpr()->getLocEnd();
}
@@ -1031,7 +1031,7 @@ class CXXBindTemporaryExpr : public Expr {
public:
CXXBindTemporaryExpr(EmptyShell Empty)
- : Expr(CXXBindTemporaryExprClass, Empty), Temp(0), SubExpr(0) {}
+ : Expr(CXXBindTemporaryExprClass, Empty), Temp(nullptr), SubExpr(nullptr) {}
static CXXBindTemporaryExpr *Create(const ASTContext &C, CXXTemporary *Temp,
Expr* SubExpr);
@@ -1077,6 +1077,7 @@ private:
bool Elidable : 1;
bool HadMultipleCandidates : 1;
bool ListInitialization : 1;
+ bool StdInitListInitialization : 1;
bool ZeroInitialization : 1;
unsigned ConstructKind : 2;
Stmt **Args;
@@ -1088,24 +1089,25 @@ protected:
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(0), NumArgs(0), Elidable(false),
+ : Expr(SC, Empty), Constructor(nullptr), NumArgs(0), Elidable(false),
HadMultipleCandidates(false), ListInitialization(false),
- ZeroInitialization(false), ConstructKind(0), Args(0)
+ ZeroInitialization(false), ConstructKind(0), Args(nullptr)
{ }
public:
/// \brief Construct an empty C++ construction expression.
explicit CXXConstructExpr(EmptyShell Empty)
- : Expr(CXXConstructExprClass, Empty), Constructor(0),
+ : Expr(CXXConstructExprClass, Empty), Constructor(nullptr),
NumArgs(0), Elidable(false), HadMultipleCandidates(false),
ListInitialization(false), ZeroInitialization(false),
- ConstructKind(0), Args(0)
+ ConstructKind(0), Args(nullptr)
{ }
static CXXConstructExpr *Create(const ASTContext &C, QualType T,
@@ -1114,6 +1116,7 @@ public:
ArrayRef<Expr *> Args,
bool HadMultipleCandidates,
bool ListInitialization,
+ bool StdInitListInitialization,
bool ZeroInitialization,
ConstructionKind ConstructKind,
SourceRange ParenOrBraceRange);
@@ -1137,6 +1140,13 @@ public:
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; }
@@ -1161,7 +1171,10 @@ public:
const_arg_iterator arg_begin() const { return Args; }
const_arg_iterator arg_end() const { return Args + NumArgs; }
- Expr **getArgs() const { return reinterpret_cast<Expr **>(Args); }
+ 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.
@@ -1269,6 +1282,7 @@ public:
SourceRange ParenOrBraceRange,
bool HadMultipleCandidates,
bool ListInitialization,
+ bool StdInitListInitialization,
bool ZeroInitialization);
explicit CXXTemporaryObjectExpr(EmptyShell Empty)
: CXXConstructExpr(CXXTemporaryObjectExprClass, Empty), Type() { }
@@ -1307,18 +1321,6 @@ public:
/// includes an initializing expression (rather than capturing a variable),
/// and which can never occur implicitly.
class LambdaExpr : public Expr {
- enum {
- /// \brief Flag used by the Capture class to indicate that the given
- /// capture was implicit.
- Capture_Implicit = 0x01,
-
- /// \brief Flag used by the Capture class to indicate that the
- /// given capture was by-copy.
- ///
- /// This includes the case of a non-reference init-capture.
- Capture_ByCopy = 0x02
- };
-
/// \brief The source range that covers the lambda introducer ([...]).
SourceRange IntroducerRange;
@@ -1357,93 +1359,8 @@ class LambdaExpr : public Expr {
// expression, along with the index variables used to initialize by-copy
// array captures.
-public:
- /// \brief Describes the capture of a variable or of \c this, or of a
- /// C++1y init-capture.
- class Capture {
- llvm::PointerIntPair<Decl *, 2> DeclAndBits;
- SourceLocation Loc;
- SourceLocation EllipsisLoc;
-
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-
- public:
- /// \brief Create a new capture of a variable or of \c this.
- ///
- /// \param Loc The source location associated with this capture.
- ///
- /// \param Kind The kind of capture (this, byref, bycopy), which must
- /// not be init-capture.
- ///
- /// \param Implicit Whether the capture was implicit or explicit.
- ///
- /// \param Var The local variable being captured, or null if capturing
- /// \c this.
- ///
- /// \param EllipsisLoc The location of the ellipsis (...) for a
- /// capture that is a pack expansion, or an invalid source
- /// location to indicate that this is not a pack expansion.
- Capture(SourceLocation Loc, bool Implicit,
- LambdaCaptureKind Kind, VarDecl *Var = 0,
- SourceLocation EllipsisLoc = SourceLocation());
-
- /// \brief Determine the kind of capture.
- LambdaCaptureKind getCaptureKind() const;
-
- /// \brief Determine whether this capture handles the C++ \c this
- /// pointer.
- bool capturesThis() const { return DeclAndBits.getPointer() == 0; }
-
- /// \brief Determine whether this capture handles a variable.
- bool capturesVariable() const {
- return dyn_cast_or_null<VarDecl>(DeclAndBits.getPointer());
- }
-
- /// \brief Determine whether this is an init-capture.
- bool isInitCapture() const {
- return capturesVariable() && getCapturedVar()->isInitCapture();
- }
-
- /// \brief Retrieve the declaration of the local variable being
- /// captured.
- ///
- /// This operation is only valid if this capture is a variable capture
- /// (other than a capture of \c this).
- VarDecl *getCapturedVar() const {
- assert(capturesVariable() && "No variable available for 'this' capture");
- return cast<VarDecl>(DeclAndBits.getPointer());
- }
-
- /// \brief Determine whether this was an implicit capture (not
- /// written between the square brackets introducing the lambda).
- bool isImplicit() const { return DeclAndBits.getInt() & Capture_Implicit; }
-
- /// \brief Determine whether this was an explicit capture (written
- /// between the square brackets introducing the lambda).
- bool isExplicit() const { return !isImplicit(); }
-
- /// \brief Retrieve the source location of the capture.
- ///
- /// For an explicit capture, this returns the location of the
- /// explicit capture in the source. For an implicit capture, this
- /// returns the location at which the variable or \c this was first
- /// used.
- SourceLocation getLocation() const { return Loc; }
-
- /// \brief Determine whether this capture is a pack expansion,
- /// which captures a function parameter pack.
- bool isPackExpansion() const { return EllipsisLoc.isValid(); }
-
- /// \brief Retrieve the location of the ellipsis for a capture
- /// that is a pack expansion.
- SourceLocation getEllipsisLoc() const {
- assert(isPackExpansion() && "No ellipsis location for a non-expansion");
- return EllipsisLoc;
- }
- };
+ typedef LambdaCapture Capture;
-private:
/// \brief Construct a lambda expression.
LambdaExpr(QualType T, SourceRange IntroducerRange,
LambdaCaptureDefault CaptureDefault,
@@ -1462,7 +1379,7 @@ private:
: Expr(LambdaExprClass, Empty),
NumCaptures(NumCaptures), CaptureDefault(LCD_None), ExplicitParams(false),
ExplicitResultType(false), HasArrayIndexVars(true) {
- getStoredStmts()[NumCaptures] = 0;
+ getStoredStmts()[NumCaptures] = nullptr;
}
Stmt **getStoredStmts() const {
@@ -1520,6 +1437,12 @@ public:
/// both implicit and explicit.
typedef const Capture *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;
@@ -1529,6 +1452,9 @@ public:
/// \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.
@@ -1538,6 +1464,9 @@ public:
/// 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;
@@ -1550,6 +1479,12 @@ public:
/// arguments.
typedef Expr **capture_init_iterator;
+ /// \brief Retrieve the initialization expressions for this lambda's captures.
+ llvm::iterator_range<capture_init_iterator> capture_inits() const {
+ return llvm::iterator_range<capture_init_iterator>(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() const {
@@ -1717,7 +1652,7 @@ public:
QualType ty, TypeSourceInfo *AllocatedTypeInfo,
SourceRange Range, SourceRange directInitRange);
explicit CXXNewExpr(EmptyShell Shell)
- : Expr(CXXNewExprClass, Shell), SubExprs(0) { }
+ : Expr(CXXNewExprClass, Shell), SubExprs(nullptr) { }
void AllocateArgsArray(const ASTContext &C, bool isArray,
unsigned numPlaceArgs, bool hasInitializer);
@@ -1751,10 +1686,10 @@ public:
bool isArray() const { return Array; }
Expr *getArraySize() {
- return Array ? cast<Expr>(SubExprs[0]) : 0;
+ return Array ? cast<Expr>(SubExprs[0]) : nullptr;
}
const Expr *getArraySize() const {
- return Array ? cast<Expr>(SubExprs[0]) : 0;
+ return Array ? cast<Expr>(SubExprs[0]) : nullptr;
}
unsigned getNumPlacementArgs() const { return NumPlacementArgs; }
@@ -1788,10 +1723,10 @@ public:
/// \brief The initializer of this new-expression.
Expr *getInitializer() {
- return hasInitializer() ? cast<Expr>(SubExprs[Array]) : 0;
+ return hasInitializer() ? cast<Expr>(SubExprs[Array]) : nullptr;
}
const Expr *getInitializer() const {
- return hasInitializer() ? cast<Expr>(SubExprs[Array]) : 0;
+ return hasInitializer() ? cast<Expr>(SubExprs[Array]) : nullptr;
}
/// \brief Returns the CXXConstructExpr from this new-expression, or null.
@@ -1885,7 +1820,8 @@ public:
ArrayForm(arrayForm), ArrayFormAsWritten(arrayFormAsWritten),
UsualArrayDeleteWantsSize(usualArrayDeleteWantsSize) { }
explicit CXXDeleteExpr(EmptyShell Shell)
- : Expr(CXXDeleteExprClass, Shell), OperatorDelete(0), Argument(0) { }
+ : Expr(CXXDeleteExprClass, Shell), OperatorDelete(nullptr),
+ Argument(nullptr) {}
bool isGlobalDelete() const { return GlobalDelete; }
bool isArrayForm() const { return ArrayForm; }
@@ -2017,7 +1953,7 @@ public:
explicit CXXPseudoDestructorExpr(EmptyShell Shell)
: Expr(CXXPseudoDestructorExprClass, Shell),
- Base(0), IsArrow(false), QualifierLoc(), ScopeType(0) { }
+ Base(nullptr), IsArrow(false), QualifierLoc(), ScopeType(nullptr) { }
Expr *getBase() const { return cast<Expr>(Base); }
@@ -2110,138 +2046,12 @@ public:
child_range children() { return child_range(&Base, &Base + 1); }
};
-/// \brief Represents a GCC or MS unary type trait, as used in the
-/// implementation of TR1/C++11 type trait templates.
-///
-/// Example:
-/// \code
-/// __is_pod(int) == true
-/// __is_enum(std::string) == false
-/// \endcode
-class UnaryTypeTraitExpr : public Expr {
- /// \brief The trait. A UnaryTypeTrait enum in MSVC compatible unsigned.
- unsigned UTT : 31;
- /// 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 type being queried.
- TypeSourceInfo *QueriedType;
-
-public:
- UnaryTypeTraitExpr(SourceLocation loc, UnaryTypeTrait utt,
- TypeSourceInfo *queried, bool value,
- SourceLocation rparen, QualType ty)
- : Expr(UnaryTypeTraitExprClass, ty, VK_RValue, OK_Ordinary,
- false, queried->getType()->isDependentType(),
- queried->getType()->isInstantiationDependentType(),
- queried->getType()->containsUnexpandedParameterPack()),
- UTT(utt), Value(value), Loc(loc), RParen(rparen), QueriedType(queried) { }
-
- explicit UnaryTypeTraitExpr(EmptyShell Empty)
- : Expr(UnaryTypeTraitExprClass, Empty), UTT(0), Value(false),
- QueriedType() { }
-
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParen; }
-
- UnaryTypeTrait getTrait() const { return static_cast<UnaryTypeTrait>(UTT); }
-
- QualType getQueriedType() const { return QueriedType->getType(); }
-
- TypeSourceInfo *getQueriedTypeSourceInfo() const { return QueriedType; }
-
- bool getValue() const { return Value; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == UnaryTypeTraitExprClass;
- }
-
- // Iterators
- child_range children() { return child_range(); }
-
- friend class ASTStmtReader;
-};
-
-/// \brief Represents a GCC or MS binary type trait, as used in the
-/// implementation of TR1/C++11 type trait templates.
-///
-/// Example:
-/// \code
-/// __is_base_of(Base, Derived) == true
-/// \endcode
-class BinaryTypeTraitExpr : public Expr {
- /// \brief The trait. A BinaryTypeTrait enum in MSVC compatible unsigned.
- unsigned BTT : 8;
-
- /// 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 lhs type being queried.
- TypeSourceInfo *LhsType;
-
- /// \brief The rhs type being queried.
- TypeSourceInfo *RhsType;
-
-public:
- BinaryTypeTraitExpr(SourceLocation loc, BinaryTypeTrait btt,
- TypeSourceInfo *lhsType, TypeSourceInfo *rhsType,
- bool value, SourceLocation rparen, QualType ty)
- : Expr(BinaryTypeTraitExprClass, ty, VK_RValue, OK_Ordinary, false,
- lhsType->getType()->isDependentType() ||
- rhsType->getType()->isDependentType(),
- (lhsType->getType()->isInstantiationDependentType() ||
- rhsType->getType()->isInstantiationDependentType()),
- (lhsType->getType()->containsUnexpandedParameterPack() ||
- rhsType->getType()->containsUnexpandedParameterPack())),
- BTT(btt), Value(value), Loc(loc), RParen(rparen),
- LhsType(lhsType), RhsType(rhsType) { }
-
-
- explicit BinaryTypeTraitExpr(EmptyShell Empty)
- : Expr(BinaryTypeTraitExprClass, Empty), BTT(0), Value(false),
- LhsType(), RhsType() { }
-
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParen; }
-
- BinaryTypeTrait getTrait() const {
- return static_cast<BinaryTypeTrait>(BTT);
- }
-
- QualType getLhsType() const { return LhsType->getType(); }
- QualType getRhsType() const { return RhsType->getType(); }
-
- TypeSourceInfo *getLhsTypeSourceInfo() const { return LhsType; }
- TypeSourceInfo *getRhsTypeSourceInfo() const { return RhsType; }
-
- bool getValue() const { assert(!isTypeDependent()); return Value; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == BinaryTypeTraitExprClass;
- }
-
- // Iterators
- child_range children() { return child_range(); }
-
- friend class ASTStmtReader;
-};
-
/// \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 : public Expr {
@@ -2334,7 +2144,7 @@ public:
friend class ASTStmtWriter;
};
-
+
/// \brief An Embarcadero array type trait, as used in the implementation of
/// __array_rank and __array_extent.
///
@@ -2504,7 +2314,7 @@ protected:
bool KnownContainsUnexpandedParameterPack);
OverloadExpr(StmtClass K, EmptyShell Empty)
- : Expr(K, Empty), QualifierLoc(), Results(0), NumResults(0),
+ : Expr(K, Empty), QualifierLoc(), Results(nullptr), NumResults(0),
HasTemplateKWAndArgsInfo(false) { }
void initializeResults(const ASTContext &C,
@@ -2554,6 +2364,9 @@ public:
decls_iterator decls_end() const {
return UnresolvedSetIterator(Results + NumResults);
}
+ llvm::iterator_range<decls_iterator> decls() const {
+ return llvm::iterator_range<decls_iterator>(decls_begin(), decls_end());
+ }
/// \brief Gets the number of declarations in the unresolved set.
unsigned getNumDecls() const { return NumResults; }
@@ -2634,7 +2447,7 @@ public:
/// This points to the same data as getExplicitTemplateArgs(), but
/// returns null if there are no explicit template arguments.
const ASTTemplateArgumentListInfo *getOptionalExplicitTemplateArgs() const {
- if (!hasExplicitTemplateArgs()) return 0;
+ if (!hasExplicitTemplateArgs()) return nullptr;
return &getExplicitTemplateArgs();
}
@@ -2691,7 +2504,7 @@ class UnresolvedLookupExpr : public OverloadExpr {
UnresolvedLookupExpr(EmptyShell Empty)
: OverloadExpr(UnresolvedLookupExprClass, Empty),
- RequiresADL(false), Overloaded(false), NamingClass(0)
+ RequiresADL(false), Overloaded(false), NamingClass(nullptr)
{}
friend class ASTStmtReader;
@@ -2706,7 +2519,7 @@ public:
UnresolvedSetIterator End) {
return new(C) UnresolvedLookupExpr(C, NamingClass, QualifierLoc,
SourceLocation(), NameInfo,
- ADL, Overloaded, 0, Begin, End);
+ ADL, Overloaded, nullptr, Begin, End);
}
static UnresolvedLookupExpr *Create(const ASTContext &C,
@@ -2781,7 +2594,7 @@ class DependentScopeDeclRefExpr : public Expr {
/// \brief Return the optional template keyword and arguments info.
ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() {
- if (!HasTemplateKWAndArgsInfo) return 0;
+ if (!HasTemplateKWAndArgsInfo) return nullptr;
return reinterpret_cast<ASTTemplateKWAndArgsInfo*>(this + 1);
}
/// \brief Return the optional template keyword and arguments info.
@@ -2875,7 +2688,7 @@ public:
/// This points to the same data as getExplicitTemplateArgs(), but
/// returns null if there are no explicit template arguments.
const ASTTemplateArgumentListInfo *getOptionalExplicitTemplateArgs() const {
- if (!hasExplicitTemplateArgs()) return 0;
+ if (!hasExplicitTemplateArgs()) return nullptr;
return &getExplicitTemplateArgs();
}
@@ -3151,7 +2964,7 @@ class CXXDependentScopeMemberExpr : public Expr {
/// \brief Return the optional template keyword and arguments info.
ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() {
- if (!HasTemplateKWAndArgsInfo) return 0;
+ if (!HasTemplateKWAndArgsInfo) return nullptr;
return reinterpret_cast<ASTTemplateKWAndArgsInfo*>(this + 1);
}
/// \brief Return the optional template keyword and arguments info.
@@ -3296,7 +3109,7 @@ public:
/// This points to the same data as getExplicitTemplateArgs(), but
/// returns null if there are no explicit template arguments.
const ASTTemplateArgumentListInfo *getOptionalExplicitTemplateArgs() const {
- if (!hasExplicitTemplateArgs()) return 0;
+ if (!hasExplicitTemplateArgs()) return nullptr;
return &getExplicitTemplateArgs();
}
@@ -3398,7 +3211,7 @@ class UnresolvedMemberExpr : public OverloadExpr {
UnresolvedMemberExpr(EmptyShell Empty)
: OverloadExpr(UnresolvedMemberExprClass, Empty), IsArrow(false),
- HasUnresolvedUsing(false), Base(0) { }
+ HasUnresolvedUsing(false), Base(nullptr) { }
friend class ASTStmtReader;
@@ -3612,7 +3425,7 @@ public:
};
inline ASTTemplateKWAndArgsInfo *OverloadExpr::getTemplateKWAndArgsInfo() {
- if (!HasTemplateKWAndArgsInfo) return 0;
+ if (!HasTemplateKWAndArgsInfo) return nullptr;
if (isa<UnresolvedLookupExpr>(this))
return reinterpret_cast<ASTTemplateKWAndArgsInfo*>
(cast<UnresolvedLookupExpr>(this) + 1);
@@ -3904,39 +3717,51 @@ public:
/// temporary. When either happens, the expression will also track the
/// declaration which is responsible for the lifetime extension.
class MaterializeTemporaryExpr : public Expr {
-public:
- /// \brief The temporary-generating expression whose value will be
- /// materialized.
- Stmt *Temporary;
+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;
+ /// \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,
- const ValueDecl *ExtendedBy)
+ bool BoundToLvalueReference)
: Expr(MaterializeTemporaryExprClass, T,
BoundToLvalueReference? VK_LValue : VK_XValue, OK_Ordinary,
Temporary->isTypeDependent(), Temporary->isValueDependent(),
Temporary->isInstantiationDependent(),
Temporary->containsUnexpandedParameterPack()),
- Temporary(Temporary), ExtendingDecl(ExtendedBy) {
- }
+ 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 *>(Temporary); }
+ 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
@@ -3948,10 +3773,15 @@ public:
/// \brief Get the declaration which triggered the lifetime-extension of this
/// temporary, if any.
- const ValueDecl *getExtendingDecl() const { return ExtendingDecl; }
+ const ValueDecl *getExtendingDecl() const {
+ return State.is<Stmt *>() ? nullptr
+ : State.get<ExtraState *>()->ExtendingDecl;
+ }
+
+ void setExtendingDecl(const ValueDecl *ExtendedBy, unsigned ManglingNumber);
- void setExtendingDecl(const ValueDecl *ExtendedBy) {
- ExtendingDecl = ExtendedBy;
+ unsigned getManglingNumber() const {
+ return State.is<Stmt *>() ? 0 : State.get<ExtraState *>()->ManglingNumber;
}
/// \brief Determine whether this materialized temporary is bound to an
@@ -3961,10 +3791,10 @@ public:
}
SourceLocation getLocStart() const LLVM_READONLY {
- return Temporary->getLocStart();
+ return getTemporary()->getLocStart();
}
SourceLocation getLocEnd() const LLVM_READONLY {
- return Temporary->getLocEnd();
+ return getTemporary()->getLocEnd();
}
static bool classof(const Stmt *T) {
@@ -3972,7 +3802,13 @@ public:
}
// Iterators
- child_range children() { return child_range(&Temporary, &Temporary + 1); }
+ 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);
+ }
};
} // end namespace clang