aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/AST/ExprCXX.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/AST/ExprCXX.cpp')
-rw-r--r--clang/lib/AST/ExprCXX.cpp207
1 files changed, 137 insertions, 70 deletions
diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp
index 5d99f61c579f..8dc9d4296e14 100644
--- a/clang/lib/AST/ExprCXX.cpp
+++ b/clang/lib/AST/ExprCXX.cpp
@@ -146,6 +146,18 @@ bool CXXTypeidExpr::isPotentiallyEvaluated() const {
return false;
}
+bool CXXTypeidExpr::isMostDerived(ASTContext &Context) const {
+ assert(!isTypeOperand() && "Cannot call isMostDerived for typeid(type)");
+ const Expr *E = getExprOperand()->IgnoreParenNoopCasts(Context);
+ if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
+ QualType Ty = DRE->getDecl()->getType();
+ if (!Ty->isPointerType() && !Ty->isReferenceType())
+ return true;
+ }
+
+ return false;
+}
+
QualType CXXTypeidExpr::getTypeOperand(ASTContext &Context) const {
assert(isTypeOperand() && "Cannot call getTypeOperand for typeid(expr)");
Qualifiers Quals;
@@ -528,17 +540,18 @@ CXXOperatorCallExpr::CXXOperatorCallExpr(OverloadedOperatorKind OpKind,
FPOptionsOverride FPFeatures,
ADLCallKind UsesADL)
: CallExpr(CXXOperatorCallExprClass, Fn, /*PreArgs=*/{}, Args, Ty, VK,
- OperatorLoc, /*MinNumArgs=*/0, UsesADL) {
+ OperatorLoc, FPFeatures, /*MinNumArgs=*/0, UsesADL) {
CXXOperatorCallExprBits.OperatorKind = OpKind;
assert(
(CXXOperatorCallExprBits.OperatorKind == static_cast<unsigned>(OpKind)) &&
"OperatorKind overflow!");
Range = getSourceRangeImpl();
- Overrides = FPFeatures;
}
-CXXOperatorCallExpr::CXXOperatorCallExpr(unsigned NumArgs, EmptyShell Empty)
- : CallExpr(CXXOperatorCallExprClass, /*NumPreArgs=*/0, NumArgs, Empty) {}
+CXXOperatorCallExpr::CXXOperatorCallExpr(unsigned NumArgs, bool HasFPFeatures,
+ EmptyShell Empty)
+ : CallExpr(CXXOperatorCallExprClass, /*NumPreArgs=*/0, NumArgs,
+ HasFPFeatures, Empty) {}
CXXOperatorCallExpr *
CXXOperatorCallExpr::Create(const ASTContext &Ctx,
@@ -548,8 +561,8 @@ CXXOperatorCallExpr::Create(const ASTContext &Ctx,
FPOptionsOverride FPFeatures, ADLCallKind UsesADL) {
// Allocate storage for the trailing objects of CallExpr.
unsigned NumArgs = Args.size();
- unsigned SizeOfTrailingObjects =
- CallExpr::sizeOfTrailingObjects(/*NumPreArgs=*/0, NumArgs);
+ unsigned SizeOfTrailingObjects = CallExpr::sizeOfTrailingObjects(
+ /*NumPreArgs=*/0, NumArgs, FPFeatures.requiresTrailingStorage());
void *Mem = Ctx.Allocate(sizeof(CXXOperatorCallExpr) + SizeOfTrailingObjects,
alignof(CXXOperatorCallExpr));
return new (Mem) CXXOperatorCallExpr(OpKind, Fn, Args, Ty, VK, OperatorLoc,
@@ -558,13 +571,14 @@ CXXOperatorCallExpr::Create(const ASTContext &Ctx,
CXXOperatorCallExpr *CXXOperatorCallExpr::CreateEmpty(const ASTContext &Ctx,
unsigned NumArgs,
+ bool HasFPFeatures,
EmptyShell Empty) {
// Allocate storage for the trailing objects of CallExpr.
unsigned SizeOfTrailingObjects =
- CallExpr::sizeOfTrailingObjects(/*NumPreArgs=*/0, NumArgs);
+ CallExpr::sizeOfTrailingObjects(/*NumPreArgs=*/0, NumArgs, HasFPFeatures);
void *Mem = Ctx.Allocate(sizeof(CXXOperatorCallExpr) + SizeOfTrailingObjects,
alignof(CXXOperatorCallExpr));
- return new (Mem) CXXOperatorCallExpr(NumArgs, Empty);
+ return new (Mem) CXXOperatorCallExpr(NumArgs, HasFPFeatures, Empty);
}
SourceRange CXXOperatorCallExpr::getSourceRangeImpl() const {
@@ -593,36 +607,43 @@ SourceRange CXXOperatorCallExpr::getSourceRangeImpl() const {
CXXMemberCallExpr::CXXMemberCallExpr(Expr *Fn, ArrayRef<Expr *> Args,
QualType Ty, ExprValueKind VK,
- SourceLocation RP, unsigned MinNumArgs)
+ SourceLocation RP,
+ FPOptionsOverride FPOptions,
+ unsigned MinNumArgs)
: CallExpr(CXXMemberCallExprClass, Fn, /*PreArgs=*/{}, Args, Ty, VK, RP,
- MinNumArgs, NotADL) {}
+ FPOptions, MinNumArgs, NotADL) {}
-CXXMemberCallExpr::CXXMemberCallExpr(unsigned NumArgs, EmptyShell Empty)
- : CallExpr(CXXMemberCallExprClass, /*NumPreArgs=*/0, NumArgs, Empty) {}
+CXXMemberCallExpr::CXXMemberCallExpr(unsigned NumArgs, bool HasFPFeatures,
+ EmptyShell Empty)
+ : CallExpr(CXXMemberCallExprClass, /*NumPreArgs=*/0, NumArgs, HasFPFeatures,
+ Empty) {}
CXXMemberCallExpr *CXXMemberCallExpr::Create(const ASTContext &Ctx, Expr *Fn,
ArrayRef<Expr *> Args, QualType Ty,
ExprValueKind VK,
SourceLocation RP,
+ FPOptionsOverride FPFeatures,
unsigned MinNumArgs) {
// Allocate storage for the trailing objects of CallExpr.
unsigned NumArgs = std::max<unsigned>(Args.size(), MinNumArgs);
- unsigned SizeOfTrailingObjects =
- CallExpr::sizeOfTrailingObjects(/*NumPreArgs=*/0, NumArgs);
+ unsigned SizeOfTrailingObjects = CallExpr::sizeOfTrailingObjects(
+ /*NumPreArgs=*/0, NumArgs, FPFeatures.requiresTrailingStorage());
void *Mem = Ctx.Allocate(sizeof(CXXMemberCallExpr) + SizeOfTrailingObjects,
alignof(CXXMemberCallExpr));
- return new (Mem) CXXMemberCallExpr(Fn, Args, Ty, VK, RP, MinNumArgs);
+ return new (Mem)
+ CXXMemberCallExpr(Fn, Args, Ty, VK, RP, FPFeatures, MinNumArgs);
}
CXXMemberCallExpr *CXXMemberCallExpr::CreateEmpty(const ASTContext &Ctx,
unsigned NumArgs,
+ bool HasFPFeatures,
EmptyShell Empty) {
// Allocate storage for the trailing objects of CallExpr.
unsigned SizeOfTrailingObjects =
- CallExpr::sizeOfTrailingObjects(/*NumPreArgs=*/0, NumArgs);
+ CallExpr::sizeOfTrailingObjects(/*NumPreArgs=*/0, NumArgs, HasFPFeatures);
void *Mem = Ctx.Allocate(sizeof(CXXMemberCallExpr) + SizeOfTrailingObjects,
alignof(CXXMemberCallExpr));
- return new (Mem) CXXMemberCallExpr(NumArgs, Empty);
+ return new (Mem) CXXMemberCallExpr(NumArgs, HasFPFeatures, Empty);
}
Expr *CXXMemberCallExpr::getImplicitObjectArgument() const {
@@ -681,19 +702,18 @@ const char *CXXNamedCastExpr::getCastName() const {
}
}
-CXXStaticCastExpr *CXXStaticCastExpr::Create(const ASTContext &C, QualType T,
- ExprValueKind VK,
- CastKind K, Expr *Op,
- const CXXCastPath *BasePath,
- TypeSourceInfo *WrittenTy,
- SourceLocation L,
- SourceLocation RParenLoc,
- SourceRange AngleBrackets) {
+CXXStaticCastExpr *
+CXXStaticCastExpr::Create(const ASTContext &C, QualType T, ExprValueKind VK,
+ CastKind K, Expr *Op, const CXXCastPath *BasePath,
+ TypeSourceInfo *WrittenTy, FPOptionsOverride FPO,
+ SourceLocation L, SourceLocation RParenLoc,
+ SourceRange AngleBrackets) {
unsigned PathSize = (BasePath ? BasePath->size() : 0);
- void *Buffer = C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *>(PathSize));
- auto *E =
- new (Buffer) CXXStaticCastExpr(T, VK, K, Op, PathSize, WrittenTy, L,
- RParenLoc, AngleBrackets);
+ void *Buffer =
+ C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *, FPOptionsOverride>(
+ PathSize, FPO.requiresTrailingStorage()));
+ auto *E = new (Buffer) CXXStaticCastExpr(T, VK, K, Op, PathSize, WrittenTy,
+ FPO, L, RParenLoc, AngleBrackets);
if (PathSize)
std::uninitialized_copy_n(BasePath->data(), BasePath->size(),
E->getTrailingObjects<CXXBaseSpecifier *>());
@@ -701,9 +721,12 @@ CXXStaticCastExpr *CXXStaticCastExpr::Create(const ASTContext &C, QualType T,
}
CXXStaticCastExpr *CXXStaticCastExpr::CreateEmpty(const ASTContext &C,
- unsigned PathSize) {
- void *Buffer = C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *>(PathSize));
- return new (Buffer) CXXStaticCastExpr(EmptyShell(), PathSize);
+ unsigned PathSize,
+ bool HasFPFeatures) {
+ void *Buffer =
+ C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *, FPOptionsOverride>(
+ PathSize, HasFPFeatures));
+ return new (Buffer) CXXStaticCastExpr(EmptyShell(), PathSize, HasFPFeatures);
}
CXXDynamicCastExpr *CXXDynamicCastExpr::Create(const ASTContext &C, QualType T,
@@ -814,25 +837,30 @@ CXXAddrspaceCastExpr *CXXAddrspaceCastExpr::CreateEmpty(const ASTContext &C) {
return new (C) CXXAddrspaceCastExpr(EmptyShell());
}
-CXXFunctionalCastExpr *
-CXXFunctionalCastExpr::Create(const ASTContext &C, QualType T, ExprValueKind VK,
- TypeSourceInfo *Written, CastKind K, Expr *Op,
- const CXXCastPath *BasePath,
- SourceLocation L, SourceLocation R) {
+CXXFunctionalCastExpr *CXXFunctionalCastExpr::Create(
+ const ASTContext &C, QualType T, ExprValueKind VK, TypeSourceInfo *Written,
+ CastKind K, Expr *Op, const CXXCastPath *BasePath, FPOptionsOverride FPO,
+ SourceLocation L, SourceLocation R) {
unsigned PathSize = (BasePath ? BasePath->size() : 0);
- void *Buffer = C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *>(PathSize));
- auto *E =
- new (Buffer) CXXFunctionalCastExpr(T, VK, Written, K, Op, PathSize, L, R);
+ void *Buffer =
+ C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *, FPOptionsOverride>(
+ PathSize, FPO.requiresTrailingStorage()));
+ auto *E = new (Buffer)
+ CXXFunctionalCastExpr(T, VK, Written, K, Op, PathSize, FPO, L, R);
if (PathSize)
std::uninitialized_copy_n(BasePath->data(), BasePath->size(),
E->getTrailingObjects<CXXBaseSpecifier *>());
return E;
}
-CXXFunctionalCastExpr *
-CXXFunctionalCastExpr::CreateEmpty(const ASTContext &C, unsigned PathSize) {
- void *Buffer = C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *>(PathSize));
- return new (Buffer) CXXFunctionalCastExpr(EmptyShell(), PathSize);
+CXXFunctionalCastExpr *CXXFunctionalCastExpr::CreateEmpty(const ASTContext &C,
+ unsigned PathSize,
+ bool HasFPFeatures) {
+ void *Buffer =
+ C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *, FPOptionsOverride>(
+ PathSize, HasFPFeatures));
+ return new (Buffer)
+ CXXFunctionalCastExpr(EmptyShell(), PathSize, HasFPFeatures);
}
SourceLocation CXXFunctionalCastExpr::getBeginLoc() const {
@@ -846,37 +874,43 @@ SourceLocation CXXFunctionalCastExpr::getEndLoc() const {
UserDefinedLiteral::UserDefinedLiteral(Expr *Fn, ArrayRef<Expr *> Args,
QualType Ty, ExprValueKind VK,
SourceLocation LitEndLoc,
- SourceLocation SuffixLoc)
+ SourceLocation SuffixLoc,
+ FPOptionsOverride FPFeatures)
: CallExpr(UserDefinedLiteralClass, Fn, /*PreArgs=*/{}, Args, Ty, VK,
- LitEndLoc, /*MinNumArgs=*/0, NotADL),
+ LitEndLoc, FPFeatures, /*MinNumArgs=*/0, NotADL),
UDSuffixLoc(SuffixLoc) {}
-UserDefinedLiteral::UserDefinedLiteral(unsigned NumArgs, EmptyShell Empty)
- : CallExpr(UserDefinedLiteralClass, /*NumPreArgs=*/0, NumArgs, Empty) {}
+UserDefinedLiteral::UserDefinedLiteral(unsigned NumArgs, bool HasFPFeatures,
+ EmptyShell Empty)
+ : CallExpr(UserDefinedLiteralClass, /*NumPreArgs=*/0, NumArgs,
+ HasFPFeatures, Empty) {}
UserDefinedLiteral *UserDefinedLiteral::Create(const ASTContext &Ctx, Expr *Fn,
ArrayRef<Expr *> Args,
QualType Ty, ExprValueKind VK,
SourceLocation LitEndLoc,
- SourceLocation SuffixLoc) {
+ SourceLocation SuffixLoc,
+ FPOptionsOverride FPFeatures) {
// Allocate storage for the trailing objects of CallExpr.
unsigned NumArgs = Args.size();
- unsigned SizeOfTrailingObjects =
- CallExpr::sizeOfTrailingObjects(/*NumPreArgs=*/0, NumArgs);
+ unsigned SizeOfTrailingObjects = CallExpr::sizeOfTrailingObjects(
+ /*NumPreArgs=*/0, NumArgs, FPFeatures.requiresTrailingStorage());
void *Mem = Ctx.Allocate(sizeof(UserDefinedLiteral) + SizeOfTrailingObjects,
alignof(UserDefinedLiteral));
- return new (Mem) UserDefinedLiteral(Fn, Args, Ty, VK, LitEndLoc, SuffixLoc);
+ return new (Mem)
+ UserDefinedLiteral(Fn, Args, Ty, VK, LitEndLoc, SuffixLoc, FPFeatures);
}
UserDefinedLiteral *UserDefinedLiteral::CreateEmpty(const ASTContext &Ctx,
unsigned NumArgs,
+ bool HasFPOptions,
EmptyShell Empty) {
// Allocate storage for the trailing objects of CallExpr.
unsigned SizeOfTrailingObjects =
- CallExpr::sizeOfTrailingObjects(/*NumPreArgs=*/0, NumArgs);
+ CallExpr::sizeOfTrailingObjects(/*NumPreArgs=*/0, NumArgs, HasFPOptions);
void *Mem = Ctx.Allocate(sizeof(UserDefinedLiteral) + SizeOfTrailingObjects,
alignof(UserDefinedLiteral));
- return new (Mem) UserDefinedLiteral(NumArgs, Empty);
+ return new (Mem) UserDefinedLiteral(NumArgs, HasFPOptions, Empty);
}
UserDefinedLiteral::LiteralOperatorKind
@@ -925,7 +959,7 @@ CXXDefaultInitExpr::CXXDefaultInitExpr(const ASTContext &Ctx,
CXXDefaultInitExprBits.Loc = Loc;
assert(Field->hasInClassInitializer());
- setDependence(ExprDependence::None);
+ setDependence(computeDependence(this));
}
CXXTemporary *CXXTemporary::Create(const ASTContext &C,
@@ -1237,6 +1271,10 @@ ArrayRef<NamedDecl *> LambdaExpr::getExplicitTemplateParameters() const {
return Record->getLambdaExplicitTemplateParameters();
}
+Expr *LambdaExpr::getTrailingRequiresClause() const {
+ return getCallOperator()->getTrailingRequiresClause();
+}
+
bool LambdaExpr::isMutable() const { return !getCallOperator()->isConst(); }
LambdaExpr::child_range LambdaExpr::children() {
@@ -1282,12 +1320,12 @@ ExprWithCleanups *ExprWithCleanups::Create(const ASTContext &C,
return new (buffer) ExprWithCleanups(empty, numObjects);
}
-CXXUnresolvedConstructExpr::CXXUnresolvedConstructExpr(TypeSourceInfo *TSI,
+CXXUnresolvedConstructExpr::CXXUnresolvedConstructExpr(QualType T,
+ TypeSourceInfo *TSI,
SourceLocation LParenLoc,
ArrayRef<Expr *> Args,
SourceLocation RParenLoc)
- : Expr(CXXUnresolvedConstructExprClass,
- TSI->getType().getNonReferenceType(),
+ : Expr(CXXUnresolvedConstructExprClass, T,
(TSI->getType()->isLValueReferenceType()
? VK_LValue
: TSI->getType()->isRValueReferenceType() ? VK_XValue
@@ -1302,10 +1340,11 @@ CXXUnresolvedConstructExpr::CXXUnresolvedConstructExpr(TypeSourceInfo *TSI,
}
CXXUnresolvedConstructExpr *CXXUnresolvedConstructExpr::Create(
- const ASTContext &Context, TypeSourceInfo *TSI, SourceLocation LParenLoc,
+ const ASTContext &Context, QualType T, TypeSourceInfo *TSI, SourceLocation LParenLoc,
ArrayRef<Expr *> Args, SourceLocation RParenLoc) {
void *Mem = Context.Allocate(totalSizeToAlloc<Expr *>(Args.size()));
- return new (Mem) CXXUnresolvedConstructExpr(TSI, LParenLoc, Args, RParenLoc);
+ return new (Mem)
+ CXXUnresolvedConstructExpr(T, TSI, LParenLoc, Args, RParenLoc);
}
CXXUnresolvedConstructExpr *
@@ -1530,6 +1569,15 @@ SizeOfPackExpr *SizeOfPackExpr::CreateDeserialized(ASTContext &Context,
return new (Storage) SizeOfPackExpr(EmptyShell(), NumPartialArgs);
}
+QualType SubstNonTypeTemplateParmExpr::getParameterType(
+ const ASTContext &Context) const {
+ // Note that, for a class type NTTP, we will have an lvalue of type 'const
+ // T', so we can't just compute this from the type and value category.
+ if (isReferenceParameter())
+ return Context.getLValueReferenceType(getType());
+ return getType().getUnqualifiedType();
+}
+
SubstNonTypeTemplateParmPackExpr::SubstNonTypeTemplateParmPackExpr(
QualType T, ExprValueKind ValueKind, NonTypeTemplateParmDecl *Param,
SourceLocation NameLoc, const TemplateArgument &ArgPack)
@@ -1603,6 +1651,20 @@ void MaterializeTemporaryExpr::setExtendingDecl(ValueDecl *ExtendedBy,
ES->ManglingNumber = ManglingNumber;
}
+bool MaterializeTemporaryExpr::isUsableInConstantExpressions(
+ const ASTContext &Context) const {
+ // C++20 [expr.const]p4:
+ // An object or reference is usable in constant expressions if it is [...]
+ // a temporary object of non-volatile const-qualified literal type
+ // whose lifetime is extended to that of a variable that is usable
+ // in constant expressions
+ auto *VD = dyn_cast_or_null<VarDecl>(getExtendingDecl());
+ return VD && getType().isConstant(Context) &&
+ !getType().isVolatileQualified() &&
+ getType()->isLiteralType(Context) &&
+ VD->isUsableInConstantExpressions(Context);
+}
+
TypeTraitExpr::TypeTraitExpr(QualType T, SourceLocation Loc, TypeTrait Kind,
ArrayRef<TypeSourceInfo *> Args,
SourceLocation RParenLoc, bool Value)
@@ -1643,34 +1705,39 @@ TypeTraitExpr *TypeTraitExpr::CreateDeserialized(const ASTContext &C,
CUDAKernelCallExpr::CUDAKernelCallExpr(Expr *Fn, CallExpr *Config,
ArrayRef<Expr *> Args, QualType Ty,
ExprValueKind VK, SourceLocation RP,
+ FPOptionsOverride FPFeatures,
unsigned MinNumArgs)
: CallExpr(CUDAKernelCallExprClass, Fn, /*PreArgs=*/Config, Args, Ty, VK,
- RP, MinNumArgs, NotADL) {}
+ RP, FPFeatures, MinNumArgs, NotADL) {}
-CUDAKernelCallExpr::CUDAKernelCallExpr(unsigned NumArgs, EmptyShell Empty)
+CUDAKernelCallExpr::CUDAKernelCallExpr(unsigned NumArgs, bool HasFPFeatures,
+ EmptyShell Empty)
: CallExpr(CUDAKernelCallExprClass, /*NumPreArgs=*/END_PREARG, NumArgs,
- Empty) {}
+ HasFPFeatures, Empty) {}
CUDAKernelCallExpr *
CUDAKernelCallExpr::Create(const ASTContext &Ctx, Expr *Fn, CallExpr *Config,
ArrayRef<Expr *> Args, QualType Ty, ExprValueKind VK,
- SourceLocation RP, unsigned MinNumArgs) {
+ SourceLocation RP, FPOptionsOverride FPFeatures,
+ unsigned MinNumArgs) {
// Allocate storage for the trailing objects of CallExpr.
unsigned NumArgs = std::max<unsigned>(Args.size(), MinNumArgs);
- unsigned SizeOfTrailingObjects =
- CallExpr::sizeOfTrailingObjects(/*NumPreArgs=*/END_PREARG, NumArgs);
+ unsigned SizeOfTrailingObjects = CallExpr::sizeOfTrailingObjects(
+ /*NumPreArgs=*/END_PREARG, NumArgs, FPFeatures.requiresTrailingStorage());
void *Mem = Ctx.Allocate(sizeof(CUDAKernelCallExpr) + SizeOfTrailingObjects,
alignof(CUDAKernelCallExpr));
- return new (Mem) CUDAKernelCallExpr(Fn, Config, Args, Ty, VK, RP, MinNumArgs);
+ return new (Mem)
+ CUDAKernelCallExpr(Fn, Config, Args, Ty, VK, RP, FPFeatures, MinNumArgs);
}
CUDAKernelCallExpr *CUDAKernelCallExpr::CreateEmpty(const ASTContext &Ctx,
unsigned NumArgs,
+ bool HasFPFeatures,
EmptyShell Empty) {
// Allocate storage for the trailing objects of CallExpr.
- unsigned SizeOfTrailingObjects =
- CallExpr::sizeOfTrailingObjects(/*NumPreArgs=*/END_PREARG, NumArgs);
+ unsigned SizeOfTrailingObjects = CallExpr::sizeOfTrailingObjects(
+ /*NumPreArgs=*/END_PREARG, NumArgs, HasFPFeatures);
void *Mem = Ctx.Allocate(sizeof(CUDAKernelCallExpr) + SizeOfTrailingObjects,
alignof(CUDAKernelCallExpr));
- return new (Mem) CUDAKernelCallExpr(NumArgs, Empty);
+ return new (Mem) CUDAKernelCallExpr(NumArgs, HasFPFeatures, Empty);
}