diff options
Diffstat (limited to 'clang/lib/AST/ExprCXX.cpp')
| -rw-r--r-- | clang/lib/AST/ExprCXX.cpp | 207 |
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); } |
