aboutsummaryrefslogtreecommitdiff
path: root/clang/include/clang/AST/ExprCXX.h
diff options
context:
space:
mode:
Diffstat (limited to 'clang/include/clang/AST/ExprCXX.h')
-rw-r--r--clang/include/clang/AST/ExprCXX.h532
1 files changed, 211 insertions, 321 deletions
diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h
index 2c29409e0ca5..6f0b68479b9d 100644
--- a/clang/include/clang/AST/ExprCXX.h
+++ b/clang/include/clang/AST/ExprCXX.h
@@ -15,15 +15,18 @@
#define LLVM_CLANG_AST_EXPRCXX_H
#include "clang/AST/ASTConcept.h"
+#include "clang/AST/ComputeDependence.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/DeclarationName.h"
+#include "clang/AST/DependenceFlags.h"
#include "clang/AST/Expr.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/OperationKinds.h"
#include "clang/AST/Stmt.h"
+#include "clang/AST/StmtCXX.h"
#include "clang/AST/TemplateBase.h"
#include "clang/AST/Type.h"
#include "clang/AST/UnresolvedSet.h"
@@ -81,6 +84,7 @@ class CXXOperatorCallExpr final : public CallExpr {
friend class ASTStmtWriter;
SourceRange Range;
+ FPOptionsOverride Overrides;
// CXXOperatorCallExpr has some trailing objects belonging
// to CallExpr. See CallExpr for the details.
@@ -89,7 +93,7 @@ class CXXOperatorCallExpr final : public CallExpr {
CXXOperatorCallExpr(OverloadedOperatorKind OpKind, Expr *Fn,
ArrayRef<Expr *> Args, QualType Ty, ExprValueKind VK,
- SourceLocation OperatorLoc, FPOptions FPFeatures,
+ SourceLocation OperatorLoc, FPOptionsOverride FPFeatures,
ADLCallKind UsesADL);
CXXOperatorCallExpr(unsigned NumArgs, EmptyShell Empty);
@@ -98,7 +102,7 @@ public:
static CXXOperatorCallExpr *
Create(const ASTContext &Ctx, OverloadedOperatorKind OpKind, Expr *Fn,
ArrayRef<Expr *> Args, QualType Ty, ExprValueKind VK,
- SourceLocation OperatorLoc, FPOptions FPFeatures,
+ SourceLocation OperatorLoc, FPOptionsOverride FPFeatures,
ADLCallKind UsesADL = NotADL);
static CXXOperatorCallExpr *CreateEmpty(const ASTContext &Ctx,
@@ -119,6 +123,22 @@ public:
}
bool isAssignmentOp() const { return isAssignmentOp(getOperator()); }
+ static bool isComparisonOp(OverloadedOperatorKind Opc) {
+ switch (Opc) {
+ case OO_EqualEqual:
+ case OO_ExclaimEqual:
+ case OO_Greater:
+ case OO_GreaterEqual:
+ case OO_Less:
+ case OO_LessEqual:
+ case OO_Spaceship:
+ return true;
+ default:
+ return false;
+ }
+ }
+ bool isComparisonOp() const { return isComparisonOp(getOperator()); }
+
/// Is this written as an infix binary operator?
bool isInfixBinaryOp() const;
@@ -145,20 +165,10 @@ public:
return T->getStmtClass() == CXXOperatorCallExprClass;
}
- // Set the FP contractability status of this operator. Only meaningful for
+ // Set the FPFeatures status of this operator. Only meaningful for
// operations on floating point types.
- void setFPFeatures(FPOptions F) {
- CXXOperatorCallExprBits.FPFeatures = F.getInt();
- }
- FPOptions getFPFeatures() const {
- return FPOptions(CXXOperatorCallExprBits.FPFeatures);
- }
-
- // Get the FP contractability status of this operator. Only meaningful for
- // operations on floating point types.
- bool isFPContractableWithinStatement() const {
- return getFPFeatures().allowFPContractWithinStatement();
- }
+ void setFPFeatures(FPOptionsOverride F) { Overrides = F; }
+ FPOptionsOverride getFPFeatures() const { return Overrides; }
};
/// Represents a call to a member function that
@@ -280,12 +290,10 @@ class CXXRewrittenBinaryOperator : public Expr {
public:
CXXRewrittenBinaryOperator(Expr *SemanticForm, bool IsReversed)
: Expr(CXXRewrittenBinaryOperatorClass, SemanticForm->getType(),
- SemanticForm->getValueKind(), SemanticForm->getObjectKind(),
- SemanticForm->isTypeDependent(), SemanticForm->isValueDependent(),
- SemanticForm->isInstantiationDependent(),
- SemanticForm->containsUnexpandedParameterPack()),
+ SemanticForm->getValueKind(), SemanticForm->getObjectKind()),
SemanticForm(SemanticForm) {
CXXRewrittenBinaryOperatorBits.IsReversed = IsReversed;
+ setDependence(computeDependence(this));
}
CXXRewrittenBinaryOperator(EmptyShell Empty)
: Expr(CXXRewrittenBinaryOperatorClass, Empty), SemanticForm() {}
@@ -350,7 +358,8 @@ public:
/// 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.
+/// reinterpret_cast, CXXConstCastExpr for \c const_cast and
+/// CXXAddrspaceCastExpr for addrspace_cast (in OpenCL).
class CXXNamedCastExpr : public ExplicitCastExpr {
private:
// the location of the casting op
@@ -396,6 +405,7 @@ public:
case CXXDynamicCastExprClass:
case CXXReinterpretCastExprClass:
case CXXConstCastExprClass:
+ case CXXAddrspaceCastExprClass:
return true;
default:
return false;
@@ -553,6 +563,41 @@ public:
}
};
+/// A C++ addrspace_cast expression (currently only enabled for OpenCL).
+///
+/// This expression node represents a cast between pointers to objects in
+/// different address spaces e.g.,
+/// \c addrspace_cast<global int*>(PtrToGenericInt).
+///
+/// A addrspace_cast can cast address space type qualifiers but does not change
+/// the underlying value.
+class CXXAddrspaceCastExpr final
+ : public CXXNamedCastExpr,
+ private llvm::TrailingObjects<CXXAddrspaceCastExpr, CXXBaseSpecifier *> {
+ CXXAddrspaceCastExpr(QualType ty, ExprValueKind VK, CastKind Kind, Expr *op,
+ TypeSourceInfo *writtenTy, SourceLocation l,
+ SourceLocation RParenLoc, SourceRange AngleBrackets)
+ : CXXNamedCastExpr(CXXAddrspaceCastExprClass, ty, VK, Kind, op, 0,
+ writtenTy, l, RParenLoc, AngleBrackets) {}
+
+ explicit CXXAddrspaceCastExpr(EmptyShell Empty)
+ : CXXNamedCastExpr(CXXAddrspaceCastExprClass, Empty, 0) {}
+
+public:
+ friend class CastExpr;
+ friend TrailingObjects;
+
+ static CXXAddrspaceCastExpr *
+ Create(const ASTContext &Context, QualType T, ExprValueKind VK, CastKind Kind,
+ Expr *Op, TypeSourceInfo *WrittenTy, SourceLocation L,
+ SourceLocation RParenLoc, SourceRange AngleBrackets);
+ static CXXAddrspaceCastExpr *CreateEmpty(const ASTContext &Context);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == CXXAddrspaceCastExprClass;
+ }
+};
+
/// A call to a literal operator (C++11 [over.literal])
/// written as a user-defined literal (C++11 [lit.ext]).
///
@@ -646,10 +691,10 @@ public:
class CXXBoolLiteralExpr : public Expr {
public:
CXXBoolLiteralExpr(bool Val, QualType Ty, SourceLocation Loc)
- : Expr(CXXBoolLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, false,
- false, false) {
+ : Expr(CXXBoolLiteralExprClass, Ty, VK_RValue, OK_Ordinary) {
CXXBoolLiteralExprBits.Value = Val;
CXXBoolLiteralExprBits.Loc = Loc;
+ setDependence(ExprDependence::None);
}
explicit CXXBoolLiteralExpr(EmptyShell Empty)
@@ -684,9 +729,9 @@ public:
class CXXNullPtrLiteralExpr : public Expr {
public:
CXXNullPtrLiteralExpr(QualType Ty, SourceLocation Loc)
- : Expr(CXXNullPtrLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false,
- false, false, false) {
+ : Expr(CXXNullPtrLiteralExprClass, Ty, VK_RValue, OK_Ordinary) {
CXXNullPtrLiteralExprBits.Loc = Loc;
+ setDependence(ExprDependence::None);
}
explicit CXXNullPtrLiteralExpr(EmptyShell Empty)
@@ -724,11 +769,10 @@ public:
friend class ASTStmtReader;
CXXStdInitializerListExpr(QualType Ty, Expr *SubExpr)
- : Expr(CXXStdInitializerListExprClass, Ty, VK_RValue, OK_Ordinary,
- Ty->isDependentType(), SubExpr->isValueDependent(),
- SubExpr->isInstantiationDependent(),
- SubExpr->containsUnexpandedParameterPack()),
- SubExpr(SubExpr) {}
+ : Expr(CXXStdInitializerListExprClass, Ty, VK_RValue, OK_Ordinary),
+ SubExpr(SubExpr) {
+ setDependence(computeDependence(this));
+ }
Expr *getSubExpr() { return static_cast<Expr*>(SubExpr); }
const Expr *getSubExpr() const { return static_cast<const Expr*>(SubExpr); }
@@ -763,32 +807,24 @@ public:
///
/// This represents code like \c typeid(int) or \c typeid(*objPtr)
class CXXTypeidExpr : public Expr {
+ friend class ASTStmtReader;
+
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) {}
+ : Expr(CXXTypeidExprClass, Ty, VK_LValue, OK_Ordinary), Operand(Operand),
+ Range(R) {
+ setDependence(computeDependence(this));
+ }
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) {}
+ : Expr(CXXTypeidExprClass, Ty, VK_LValue, OK_Ordinary), Operand(Operand),
+ Range(R) {
+ setDependence(computeDependence(this));
+ }
CXXTypeidExpr(EmptyShell Empty, bool isExpr)
: Expr(CXXTypeidExprClass, Empty) {
@@ -813,22 +849,11 @@ public:
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 getBeginLoc() const LLVM_READONLY { return Range.getBegin(); }
SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); }
SourceRange getSourceRange() const LLVM_READONLY { return Range; }
@@ -873,15 +898,12 @@ 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) {}
+ NestedNameSpecifierLoc qualifierLoc, SourceLocation nameLoc)
+ : Expr(MSPropertyRefExprClass, ty, VK, OK_Ordinary), BaseExpr(baseExpr),
+ TheDecl(decl), MemberLoc(nameLoc), IsArrow(isArrow),
+ QualifierLoc(qualifierLoc) {
+ setDependence(computeDependence(this));
+ }
MSPropertyRefExpr(EmptyShell Empty) : Expr(MSPropertyRefExprClass, Empty) {}
@@ -949,12 +971,11 @@ class MSPropertySubscriptExpr : public Expr {
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()),
+ : Expr(MSPropertySubscriptExprClass, Ty, VK, OK),
RBracketLoc(RBracketLoc) {
SubExprs[BASE_EXPR] = Base;
SubExprs[IDX_EXPR] = Idx;
+ setDependence(computeDependence(this));
}
/// Create an empty array subscript expression.
@@ -999,25 +1020,26 @@ public:
///
/// This represents code like @c __uuidof(COMTYPE) or @c __uuidof(*comPtr)
class CXXUuidofExpr : public Expr {
+ friend class ASTStmtReader;
+
private:
llvm::PointerUnion<Stmt *, TypeSourceInfo *> Operand;
- StringRef UuidStr;
+ MSGuidDecl *Guid;
SourceRange Range;
public:
- CXXUuidofExpr(QualType Ty, TypeSourceInfo *Operand, StringRef UuidStr,
+ CXXUuidofExpr(QualType Ty, TypeSourceInfo *Operand, MSGuidDecl *Guid,
SourceRange R)
- : Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary, false,
- Operand->getType()->isDependentType(),
- Operand->getType()->isInstantiationDependentType(),
- Operand->getType()->containsUnexpandedParameterPack()),
- Operand(Operand), UuidStr(UuidStr), Range(R) {}
-
- CXXUuidofExpr(QualType Ty, Expr *Operand, StringRef UuidStr, SourceRange R)
- : Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary, false,
- Operand->isTypeDependent(), Operand->isInstantiationDependent(),
- Operand->containsUnexpandedParameterPack()),
- Operand(Operand), UuidStr(UuidStr), Range(R) {}
+ : Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary), Operand(Operand),
+ Guid(Guid), Range(R) {
+ setDependence(computeDependence(this));
+ }
+
+ CXXUuidofExpr(QualType Ty, Expr *Operand, MSGuidDecl *Guid, SourceRange R)
+ : Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary), Operand(Operand),
+ Guid(Guid), Range(R) {
+ setDependence(computeDependence(this));
+ }
CXXUuidofExpr(EmptyShell Empty, bool isExpr)
: Expr(CXXUuidofExprClass, Empty) {
@@ -1038,24 +1060,12 @@ public:
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;
- }
-
- void setUuidStr(StringRef US) { UuidStr = US; }
- StringRef getUuidStr() const { return UuidStr; }
+ MSGuidDecl *getGuidDecl() const { return Guid; }
SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); }
SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); }
@@ -1098,14 +1108,10 @@ public:
class CXXThisExpr : public Expr {
public:
CXXThisExpr(SourceLocation L, QualType Ty, bool IsImplicit)
- : Expr(CXXThisExprClass, Ty, VK_RValue, OK_Ordinary,
- // 'this' is type-dependent if the class type of the enclosing
- // member function is dependent (C++ [temp.dep.expr]p2)
- Ty->isDependentType(), Ty->isDependentType(),
- Ty->isInstantiationDependentType(),
- /*ContainsUnexpandedParameterPack=*/false) {
+ : Expr(CXXThisExprClass, Ty, VK_RValue, OK_Ordinary) {
CXXThisExprBits.IsImplicit = IsImplicit;
CXXThisExprBits.Loc = L;
+ setDependence(computeDependence(this));
}
CXXThisExpr(EmptyShell Empty) : Expr(CXXThisExprClass, Empty) {}
@@ -1151,12 +1157,10 @@ public:
// null if not present.
CXXThrowExpr(Expr *Operand, QualType Ty, SourceLocation Loc,
bool IsThrownVariableInScope)
- : Expr(CXXThrowExprClass, Ty, VK_RValue, OK_Ordinary, false, false,
- Operand && Operand->isInstantiationDependent(),
- Operand && Operand->containsUnexpandedParameterPack()),
- Operand(Operand) {
+ : Expr(CXXThrowExprClass, Ty, VK_RValue, OK_Ordinary), Operand(Operand) {
CXXThrowExprBits.ThrowLoc = Loc;
CXXThrowExprBits.IsThrownVariableInScope = IsThrownVariableInScope;
+ setDependence(computeDependence(this));
}
CXXThrowExpr(EmptyShell Empty) : Expr(CXXThrowExprClass, Empty) {}
@@ -1210,16 +1214,16 @@ class CXXDefaultArgExpr final : public Expr {
DeclContext *UsedContext;
CXXDefaultArgExpr(StmtClass SC, SourceLocation Loc, ParmVarDecl *Param,
- DeclContext *UsedContext)
+ DeclContext *UsedContext)
: Expr(SC,
Param->hasUnparsedDefaultArg()
? Param->getType().getNonReferenceType()
: Param->getDefaultArg()->getType(),
Param->getDefaultArg()->getValueKind(),
- Param->getDefaultArg()->getObjectKind(), false, false, false,
- false),
+ Param->getDefaultArg()->getObjectKind()),
Param(Param), UsedContext(UsedContext) {
CXXDefaultArgExprBits.Loc = Loc;
+ setDependence(ExprDependence::None);
}
public:
@@ -1375,13 +1379,12 @@ class CXXBindTemporaryExpr : public Expr {
CXXTemporary *Temp = nullptr;
Stmt *SubExpr = nullptr;
- 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) {}
+ CXXBindTemporaryExpr(CXXTemporary *temp, Expr *SubExpr)
+ : Expr(CXXBindTemporaryExprClass, SubExpr->getType(), VK_RValue,
+ OK_Ordinary),
+ Temp(temp), SubExpr(SubExpr) {
+ setDependence(computeDependence(this));
+ }
public:
CXXBindTemporaryExpr(EmptyShell Empty)
@@ -1632,12 +1635,12 @@ public:
CXXInheritedCtorInitExpr(SourceLocation Loc, QualType T,
CXXConstructorDecl *Ctor, bool ConstructsVirtualBase,
bool InheritedFromVirtualBase)
- : Expr(CXXInheritedCtorInitExprClass, T, VK_RValue, OK_Ordinary, false,
- false, false, false),
+ : Expr(CXXInheritedCtorInitExprClass, T, VK_RValue, OK_Ordinary),
Constructor(Ctor), Loc(Loc),
ConstructsVirtualBase(ConstructsVirtualBase),
InheritedFromVirtualBase(InheritedFromVirtualBase) {
assert(!T->isDependentType());
+ setDependence(ExprDependence::None);
}
/// Construct an empty C++ inheriting construction expression.
@@ -1818,26 +1821,14 @@ Stmt **CXXConstructExpr::getTrailingArgs() {
/// and which can never occur implicitly.
class LambdaExpr final : public Expr,
private llvm::TrailingObjects<LambdaExpr, Stmt *> {
+ // LambdaExpr has some data stored in LambdaExprBits.
+
/// The source range that covers the lambda introducer ([...]).
SourceRange IntroducerRange;
/// The source location of this lambda's capture-default ('=' or '&').
SourceLocation CaptureDefaultLoc;
- /// The number of captures.
- unsigned NumCaptures : 16;
-
- /// The default capture kind, which is a value of type
- /// LambdaCaptureDefault.
- unsigned CaptureDefault : 2;
-
- /// Whether this lambda had an explicit parameter list vs. an
- /// implicit (and empty) parameter list.
- unsigned ExplicitParams : 1;
-
- /// Whether this lambda had the result type explicitly specified.
- unsigned ExplicitResultType : 1;
-
/// The location of the closing brace ('}') that completes
/// the lambda.
///
@@ -1851,23 +1842,18 @@ class LambdaExpr final : public Expr,
/// Construct a lambda expression.
LambdaExpr(QualType T, SourceRange IntroducerRange,
LambdaCaptureDefault CaptureDefault,
- SourceLocation CaptureDefaultLoc, ArrayRef<LambdaCapture> Captures,
- bool ExplicitParams, bool ExplicitResultType,
- ArrayRef<Expr *> CaptureInits, SourceLocation ClosingBrace,
- bool ContainsUnexpandedParameterPack);
+ SourceLocation CaptureDefaultLoc, bool ExplicitParams,
+ bool ExplicitResultType, ArrayRef<Expr *> CaptureInits,
+ SourceLocation ClosingBrace, bool ContainsUnexpandedParameterPack);
/// Construct an empty lambda expression.
- LambdaExpr(EmptyShell Empty, unsigned NumCaptures)
- : Expr(LambdaExprClass, Empty), NumCaptures(NumCaptures),
- CaptureDefault(LCD_None), ExplicitParams(false),
- ExplicitResultType(false) {
- getStoredStmts()[NumCaptures] = nullptr;
- }
+ LambdaExpr(EmptyShell Empty, unsigned NumCaptures);
Stmt **getStoredStmts() { return getTrailingObjects<Stmt *>(); }
-
Stmt *const *getStoredStmts() const { return getTrailingObjects<Stmt *>(); }
+ void initBodyIfNeeded() const;
+
public:
friend class ASTStmtReader;
friend class ASTStmtWriter;
@@ -1877,9 +1863,9 @@ public:
static LambdaExpr *
Create(const ASTContext &C, CXXRecordDecl *Class, SourceRange IntroducerRange,
LambdaCaptureDefault CaptureDefault, SourceLocation CaptureDefaultLoc,
- ArrayRef<LambdaCapture> Captures, bool ExplicitParams,
- bool ExplicitResultType, ArrayRef<Expr *> CaptureInits,
- SourceLocation ClosingBrace, bool ContainsUnexpandedParameterPack);
+ bool ExplicitParams, bool ExplicitResultType,
+ ArrayRef<Expr *> CaptureInits, SourceLocation ClosingBrace,
+ bool ContainsUnexpandedParameterPack);
/// Construct a new lambda expression that will be deserialized from
/// an external source.
@@ -1888,13 +1874,11 @@ public:
/// Determine the default capture kind for this lambda.
LambdaCaptureDefault getCaptureDefault() const {
- return static_cast<LambdaCaptureDefault>(CaptureDefault);
+ return static_cast<LambdaCaptureDefault>(LambdaExprBits.CaptureDefault);
}
/// Retrieve the location of this lambda's capture-default, if any.
- SourceLocation getCaptureDefaultLoc() const {
- return CaptureDefaultLoc;
- }
+ SourceLocation getCaptureDefaultLoc() const { return CaptureDefaultLoc; }
/// Determine whether one of this lambda's captures is an init-capture.
bool isInitCapture(const LambdaCapture *Capture) const;
@@ -1917,7 +1901,7 @@ public:
capture_iterator capture_end() const;
/// Determine the number of captures in this lambda.
- unsigned capture_size() const { return NumCaptures; }
+ unsigned capture_size() const { return LambdaExprBits.NumCaptures; }
/// Retrieve this lambda's explicit captures.
capture_range explicit_captures() const;
@@ -1947,6 +1931,7 @@ public:
/// Const iterator that walks over the capture initialization
/// arguments.
+ /// FIXME: This interface is prone to being used incorrectly.
using const_capture_init_iterator = Expr *const *;
/// Retrieve the initialization expressions for this lambda's captures.
@@ -1974,13 +1959,13 @@ public:
/// 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;
+ return capture_init_begin() + capture_size();
}
/// 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;
+ return capture_init_begin() + capture_size();
}
/// Retrieve the source range covering the lambda introducer,
@@ -2014,8 +1999,20 @@ public:
/// Whether this is a generic lambda.
bool isGenericLambda() const { return getTemplateParameterList(); }
- /// Retrieve the body of the lambda.
- CompoundStmt *getBody() const;
+ /// Retrieve the body of the lambda. This will be most of the time
+ /// a \p CompoundStmt, but can also be \p CoroutineBodyStmt wrapping
+ /// a \p CompoundStmt. Note that unlike functions, lambda-expressions
+ /// cannot have a function-try-block.
+ Stmt *getBody() const;
+
+ /// Retrieve the \p CompoundStmt representing the body of the lambda.
+ /// This is a convenience function for callers who do not need
+ /// to handle node(s) which may wrap a \p CompoundStmt.
+ const CompoundStmt *getCompoundStmtBody() const;
+ CompoundStmt *getCompoundStmtBody() {
+ const auto *ConstThis = this;
+ return const_cast<CompoundStmt *>(ConstThis->getCompoundStmtBody());
+ }
/// Determine whether the lambda is mutable, meaning that any
/// captures values can be modified.
@@ -2023,10 +2020,12 @@ public:
/// Determine whether this lambda has an explicit parameter
/// list vs. an implicit (empty) parameter list.
- bool hasExplicitParameters() const { return ExplicitParams; }
+ bool hasExplicitParameters() const { return LambdaExprBits.ExplicitParams; }
/// Whether this lambda had its result type explicitly specified.
- bool hasExplicitResultType() const { return ExplicitResultType; }
+ bool hasExplicitResultType() const {
+ return LambdaExprBits.ExplicitResultType;
+ }
static bool classof(const Stmt *T) {
return T->getStmtClass() == LambdaExprClass;
@@ -2038,15 +2037,9 @@ public:
SourceLocation getEndLoc() const LLVM_READONLY { return ClosingBrace; }
- child_range children() {
- // Includes initialization exprs plus body stmt
- return child_range(getStoredStmts(), getStoredStmts() + NumCaptures + 1);
- }
-
- const_child_range children() const {
- return const_child_range(getStoredStmts(),
- getStoredStmts() + NumCaptures + 1);
- }
+ /// Includes the captures and the body of the lambda.
+ child_range children();
+ const_child_range children() const;
};
/// An expression "T()" which creates a value-initialized rvalue of type
@@ -2061,11 +2054,10 @@ public:
/// expression.
CXXScalarValueInitExpr(QualType Type, TypeSourceInfo *TypeInfo,
SourceLocation RParenLoc)
- : Expr(CXXScalarValueInitExprClass, Type, VK_RValue, OK_Ordinary, false,
- false, Type->isInstantiationDependentType(),
- Type->containsUnexpandedParameterPack()),
+ : Expr(CXXScalarValueInitExprClass, Type, VK_RValue, OK_Ordinary),
TypeInfo(TypeInfo) {
CXXScalarValueInitExprBits.RParenLoc = RParenLoc;
+ setDependence(computeDependence(this));
}
explicit CXXScalarValueInitExpr(EmptyShell Shell)
@@ -2370,15 +2362,14 @@ 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,
- Arg->isValueDependent(), Arg->isInstantiationDependent(),
- Arg->containsUnexpandedParameterPack()),
+ : Expr(CXXDeleteExprClass, Ty, VK_RValue, OK_Ordinary),
OperatorDelete(OperatorDelete), Argument(Arg) {
CXXDeleteExprBits.GlobalDelete = GlobalDelete;
CXXDeleteExprBits.ArrayForm = ArrayForm;
CXXDeleteExprBits.ArrayFormAsWritten = ArrayFormAsWritten;
CXXDeleteExprBits.UsualArrayDeleteWantsSize = UsualArrayDeleteWantsSize;
CXXDeleteExprBits.Loc = Loc;
+ setDependence(computeDependence(this));
}
explicit CXXDeleteExpr(EmptyShell Shell) : Expr(CXXDeleteExprClass, Shell) {}
@@ -2736,15 +2727,15 @@ public:
friend class ASTStmtReader;
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) {}
+ TypeSourceInfo *queried, uint64_t value, Expr *dimension,
+ SourceLocation rparen, QualType ty)
+ : Expr(ArrayTypeTraitExprClass, ty, VK_RValue, OK_Ordinary), ATT(att),
+ Value(value), Dimension(dimension), Loc(loc), RParen(rparen),
+ QueriedType(queried) {
+ assert(att <= ATT_Last && "invalid enum value!");
+ assert(static_cast<unsigned>(att) == ATT && "ATT overflow!");
+ setDependence(computeDependence(this));
+ }
explicit ArrayTypeTraitExpr(EmptyShell Empty)
: Expr(ArrayTypeTraitExprClass, Empty), ATT(0) {}
@@ -2802,17 +2793,15 @@ class ExpressionTraitExpr : public Expr {
public:
friend class ASTStmtReader;
- 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()),
+ ExpressionTraitExpr(SourceLocation loc, ExpressionTrait et, Expr *queried,
+ bool value, SourceLocation rparen, QualType resultType)
+ : Expr(ExpressionTraitExprClass, resultType, VK_RValue, OK_Ordinary),
ET(et), Value(value), Loc(loc), RParen(rparen),
- QueriedExpression(queried) {}
+ QueriedExpression(queried) {
+ assert(et <= ET_Last && "invalid enum value!");
+ assert(static_cast<unsigned>(et) == ET && "ET overflow!");
+ setDependence(computeDependence(this));
+ }
explicit ExpressionTraitExpr(EmptyShell Empty)
: Expr(ExpressionTraitExprClass, Empty), ET(0), Value(false) {}
@@ -3306,13 +3295,15 @@ public:
/// literal is the extent of the enclosing scope.
class ExprWithCleanups final
: public FullExpr,
- private llvm::TrailingObjects<ExprWithCleanups, BlockDecl *> {
+ private llvm::TrailingObjects<
+ ExprWithCleanups,
+ llvm::PointerUnion<BlockDecl *, CompoundLiteralExpr *>> {
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.
- using CleanupObject = BlockDecl *;
+ /// It's useful to remember the set of blocks and block-scoped compound
+ /// literals; we could also remember the set of temporaries, but there's
+ /// currently no need.
+ using CleanupObject = llvm::PointerUnion<BlockDecl *, CompoundLiteralExpr *>;
private:
friend class ASTStmtReader;
@@ -3965,13 +3956,10 @@ class CXXNoexceptExpr : public Expr {
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()),
+ : Expr(CXXNoexceptExprClass, Ty, VK_RValue, OK_Ordinary),
Operand(Operand), Range(Keyword, RParen) {
CXXNoexceptExprBits.Value = Val == CT_Cannot;
+ setDependence(computeDependence(this, Val));
}
CXXNoexceptExpr(EmptyShell Empty) : Expr(CXXNoexceptExprClass, Empty) {}
@@ -4032,12 +4020,12 @@ 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),
+ Pattern->getObjectKind()),
EllipsisLoc(EllipsisLoc),
NumExpansions(NumExpansions ? *NumExpansions + 1 : 0),
- Pattern(Pattern) {}
+ Pattern(Pattern) {
+ setDependence(computeDependence(this));
+ }
PackExpansionExpr(EmptyShell Empty) : Expr(PackExpansionExprClass, Empty) {}
@@ -4124,17 +4112,17 @@ class SizeOfPackExpr final
/// 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),
+ Optional<unsigned> Length,
+ ArrayRef<TemplateArgument> PartialArgs)
+ : Expr(SizeOfPackExprClass, SizeType, VK_RValue, OK_Ordinary),
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");
auto *Args = getTrailingObjects<TemplateArgument>();
std::uninitialized_copy(PartialArgs.begin(), PartialArgs.end(), Args);
+ setDependence(Length ? ExprDependence::None
+ : ExprDependence::ValueInstantiation);
}
/// Create an empty expression.
@@ -4225,12 +4213,10 @@ public:
SourceLocation Loc,
NonTypeTemplateParmDecl *Param,
Expr *Replacement)
- : Expr(SubstNonTypeTemplateParmExprClass, Ty, ValueKind, OK_Ordinary,
- Replacement->isTypeDependent(), Replacement->isValueDependent(),
- Replacement->isInstantiationDependent(),
- Replacement->containsUnexpandedParameterPack()),
+ : Expr(SubstNonTypeTemplateParmExprClass, Ty, ValueKind, OK_Ordinary),
Param(Param), Replacement(Replacement) {
SubstNonTypeTemplateParmExprBits.NameLoc = Loc;
+ setDependence(computeDependence(this));
}
SourceLocation getNameLoc() const {
@@ -4544,13 +4530,12 @@ public:
CXXFoldExpr(QualType T, SourceLocation LParenLoc, Expr *LHS,
BinaryOperatorKind Opcode, SourceLocation EllipsisLoc, Expr *RHS,
SourceLocation RParenLoc, Optional<unsigned> NumExpansions)
- : Expr(CXXFoldExprClass, T, VK_RValue, OK_Ordinary,
- /*Dependent*/ true, true, true,
- /*ContainsUnexpandedParameterPack*/ false),
- LParenLoc(LParenLoc), EllipsisLoc(EllipsisLoc), RParenLoc(RParenLoc),
+ : Expr(CXXFoldExprClass, T, VK_RValue, OK_Ordinary), LParenLoc(LParenLoc),
+ EllipsisLoc(EllipsisLoc), RParenLoc(RParenLoc),
NumExpansions(NumExpansions ? *NumExpansions + 1 : 0), Opcode(Opcode) {
SubExprs[0] = LHS;
SubExprs[1] = RHS;
+ setDependence(computeDependence(this));
}
CXXFoldExpr(EmptyShell Empty) : Expr(CXXFoldExprClass, Empty) {}
@@ -4625,27 +4610,25 @@ public:
Expr *Ready, Expr *Suspend, Expr *Resume,
OpaqueValueExpr *OpaqueValue)
: Expr(SC, Resume->getType(), Resume->getValueKind(),
- Resume->getObjectKind(), Resume->isTypeDependent(),
- Resume->isValueDependent(), Common->isInstantiationDependent(),
- Common->containsUnexpandedParameterPack()),
+ Resume->getObjectKind()),
KeywordLoc(KeywordLoc), OpaqueValue(OpaqueValue) {
SubExprs[SubExpr::Common] = Common;
SubExprs[SubExpr::Ready] = Ready;
SubExprs[SubExpr::Suspend] = Suspend;
SubExprs[SubExpr::Resume] = Resume;
+ setDependence(computeDependence(this));
}
CoroutineSuspendExpr(StmtClass SC, SourceLocation KeywordLoc, QualType Ty,
Expr *Common)
- : Expr(SC, Ty, VK_RValue, OK_Ordinary, true, true, true,
- Common->containsUnexpandedParameterPack()),
- KeywordLoc(KeywordLoc) {
+ : Expr(SC, Ty, VK_RValue, OK_Ordinary), 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;
+ setDependence(computeDependence(this));
}
CoroutineSuspendExpr(StmtClass SC, EmptyShell Empty) : Expr(SC, Empty) {
@@ -4742,10 +4725,7 @@ class DependentCoawaitExpr : public Expr {
public:
DependentCoawaitExpr(SourceLocation KeywordLoc, QualType Ty, Expr *Op,
UnresolvedLookupExpr *OpCoawait)
- : Expr(DependentCoawaitExprClass, Ty, VK_RValue, OK_Ordinary,
- /*TypeDependent*/ true, /*ValueDependent*/ true,
- /*InstantiationDependent*/ true,
- Op->containsUnexpandedParameterPack()),
+ : Expr(DependentCoawaitExprClass, Ty, VK_RValue, OK_Ordinary),
KeywordLoc(KeywordLoc) {
// NOTE: A co_await expression is dependent on the coroutines promise
// type and may be dependent even when the `Op` expression is not.
@@ -4753,6 +4733,7 @@ public:
"wrong constructor for non-dependent co_await/co_yield expression");
SubExprs[0] = Op;
SubExprs[1] = OpCoawait;
+ setDependence(computeDependence(this));
}
DependentCoawaitExpr(EmptyShell Empty)
@@ -4827,6 +4808,8 @@ public:
: ExplicitCastExpr(BuiltinBitCastExprClass, T, VK, CK, SrcExpr, 0,
DstType),
KWLoc(KWLoc), RParenLoc(RParenLoc) {}
+ BuiltinBitCastExpr(EmptyShell Empty)
+ : ExplicitCastExpr(BuiltinBitCastExprClass, Empty, 0) {}
SourceLocation getBeginLoc() const LLVM_READONLY { return KWLoc; }
SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
@@ -4836,99 +4819,6 @@ public:
}
};
-/// \brief Represents the specialization of a concept - evaluates to a prvalue
-/// of type bool.
-///
-/// According to C++2a [expr.prim.id]p3 an id-expression that denotes the
-/// specialization of a concept results in a prvalue of type bool.
-class ConceptSpecializationExpr final : public Expr, public ConceptReference,
- private llvm::TrailingObjects<ConceptSpecializationExpr,
- TemplateArgument> {
- friend class ASTStmtReader;
- friend TrailingObjects;
-public:
- using SubstitutionDiagnostic = std::pair<SourceLocation, std::string>;
-
-protected:
- /// \brief The number of template arguments in the tail-allocated list of
- /// converted template arguments.
- unsigned NumTemplateArgs;
-
- /// \brief Information about the satisfaction of the named concept with the
- /// given arguments. If this expression is value dependent, this is to be
- /// ignored.
- ASTConstraintSatisfaction *Satisfaction;
-
- ConceptSpecializationExpr(const ASTContext &C, NestedNameSpecifierLoc NNS,
- SourceLocation TemplateKWLoc,
- DeclarationNameInfo ConceptNameInfo,
- NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
- const ASTTemplateArgumentListInfo *ArgsAsWritten,
- ArrayRef<TemplateArgument> ConvertedArgs,
- const ConstraintSatisfaction *Satisfaction);
-
- ConceptSpecializationExpr(EmptyShell Empty, unsigned NumTemplateArgs);
-
-public:
-
- static ConceptSpecializationExpr *
- Create(const ASTContext &C, NestedNameSpecifierLoc NNS,
- SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo,
- NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
- const ASTTemplateArgumentListInfo *ArgsAsWritten,
- ArrayRef<TemplateArgument> ConvertedArgs,
- const ConstraintSatisfaction *Satisfaction);
-
- static ConceptSpecializationExpr *
- Create(ASTContext &C, EmptyShell Empty, unsigned NumTemplateArgs);
-
- ArrayRef<TemplateArgument> getTemplateArguments() const {
- return ArrayRef<TemplateArgument>(getTrailingObjects<TemplateArgument>(),
- NumTemplateArgs);
- }
-
- /// \brief Set new template arguments for this concept specialization.
- void setTemplateArguments(ArrayRef<TemplateArgument> Converted);
-
- /// \brief Whether or not the concept with the given arguments was satisfied
- /// when the expression was created.
- /// The expression must not be dependent.
- bool isSatisfied() const {
- assert(!isValueDependent()
- && "isSatisfied called on a dependent ConceptSpecializationExpr");
- return Satisfaction->IsSatisfied;
- }
-
- /// \brief Get elaborated satisfaction info about the template arguments'
- /// satisfaction of the named concept.
- /// The expression must not be dependent.
- const ASTConstraintSatisfaction &getSatisfaction() const {
- assert(!isValueDependent()
- && "getSatisfaction called on dependent ConceptSpecializationExpr");
- return *Satisfaction;
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ConceptSpecializationExprClass;
- }
-
- SourceLocation getBeginLoc() const LLVM_READONLY {
- return ConceptName.getBeginLoc();
- }
-
- SourceLocation getEndLoc() const LLVM_READONLY {
- return ArgsAsWritten->RAngleLoc;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
- const_child_range children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
-};
-
} // namespace clang
#endif // LLVM_CLANG_AST_EXPRCXX_H