diff options
author | Bruno Ricci <riccibrun@gmail.com> | 2019-01-07 15:04:45 +0000 |
---|---|---|
committer | Bruno Ricci <riccibrun@gmail.com> | 2019-01-07 15:04:45 +0000 |
commit | 7eadfa4ba2821e7394224da7023128dc9b36eebd (patch) | |
tree | 6b1dbedb6e0174ca7ea7beb6707d658da5a7af09 /lib | |
parent | 4d27dbbf8ec35d8c58f80938a8383da37e9f3800 (diff) |
[AST] Store some data of CXXNewExpr as trailing objects
Store the optional array size expression, optional initialization expression
and optional placement new arguments in a trailing array. Additionally store
the range for the parenthesized type-id in a trailing object if needed since
in the vast majority of cases the type is not parenthesized (not a single new
expression in the translation unit of SemaDecl.cpp has a parenthesized type-id).
This saves 2 pointers per CXXNewExpr in all cases, and 2 pointers + 8 bytes
per CXXNewExpr in the common case where the type is not parenthesized.
Differential Revision: https://reviews.llvm.org/D56134
Reviewed By: rjmccall
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350527 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/ASTImporter.cpp | 2 | ||||
-rw-r--r-- | lib/AST/ExprCXX.cpp | 144 | ||||
-rw-r--r-- | lib/CodeGen/CGExprCXX.cpp | 4 | ||||
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 10 | ||||
-rw-r--r-- | lib/Serialization/ASTReaderStmt.cpp | 42 | ||||
-rw-r--r-- | lib/Serialization/ASTWriterStmt.cpp | 19 |
6 files changed, 145 insertions, 76 deletions
diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp index 251d078635..44832557e9 100644 --- a/lib/AST/ASTImporter.cpp +++ b/lib/AST/ASTImporter.cpp @@ -6910,7 +6910,7 @@ ExpectedStmt ASTNodeImporter::VisitCXXNewExpr(CXXNewExpr *E) { ImportContainerChecked(E->placement_arguments(), ToPlacementArgs)) return std::move(Err); - return new (Importer.getToContext()) CXXNewExpr( + return CXXNewExpr::Create( Importer.getToContext(), E->isGlobalNew(), ToOperatorNew, ToOperatorDelete, E->passAlignment(), E->doesUsualArrayDeleteWantSize(), ToPlacementArgs, ToTypeIdParens, ToArraySize, E->getInitializationStyle(), diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp index 7aa80c0392..4eb3d333bc 100644 --- a/lib/AST/ExprCXX.cpp +++ b/lib/AST/ExprCXX.cpp @@ -94,83 +94,127 @@ SourceLocation CXXScalarValueInitExpr::getBeginLoc() const { } // CXXNewExpr -CXXNewExpr::CXXNewExpr(const ASTContext &C, bool globalNew, - FunctionDecl *operatorNew, FunctionDecl *operatorDelete, - bool PassAlignment, bool usualArrayDeleteWantsSize, - ArrayRef<Expr*> placementArgs, - SourceRange typeIdParens, Expr *arraySize, - InitializationStyle initializationStyle, - Expr *initializer, QualType ty, - TypeSourceInfo *allocatedTypeInfo, - SourceRange Range, SourceRange directInitRange) - : Expr(CXXNewExprClass, ty, VK_RValue, OK_Ordinary, ty->isDependentType(), - ty->isDependentType(), ty->isInstantiationDependentType(), - ty->containsUnexpandedParameterPack()), - OperatorNew(operatorNew), OperatorDelete(operatorDelete), - AllocatedTypeInfo(allocatedTypeInfo), TypeIdParens(typeIdParens), - Range(Range), DirectInitRange(directInitRange), GlobalNew(globalNew), - PassAlignment(PassAlignment), - UsualArrayDeleteWantsSize(usualArrayDeleteWantsSize) { - assert((initializer != nullptr || initializationStyle == NoInit) && - "Only NoInit can have no initializer."); - StoredInitializationStyle = initializer ? initializationStyle + 1 : 0; - AllocateArgsArray(C, arraySize != nullptr, placementArgs.size(), - initializer != nullptr); - unsigned i = 0; - if (Array) { - if (arraySize->isInstantiationDependent()) +CXXNewExpr::CXXNewExpr(bool IsGlobalNew, FunctionDecl *OperatorNew, + FunctionDecl *OperatorDelete, bool ShouldPassAlignment, + bool UsualArrayDeleteWantsSize, + ArrayRef<Expr *> PlacementArgs, SourceRange TypeIdParens, + Expr *ArraySize, InitializationStyle InitializationStyle, + Expr *Initializer, QualType Ty, + TypeSourceInfo *AllocatedTypeInfo, SourceRange Range, + SourceRange DirectInitRange) + : Expr(CXXNewExprClass, Ty, VK_RValue, OK_Ordinary, Ty->isDependentType(), + Ty->isDependentType(), Ty->isInstantiationDependentType(), + Ty->containsUnexpandedParameterPack()), + OperatorNew(OperatorNew), OperatorDelete(OperatorDelete), + AllocatedTypeInfo(AllocatedTypeInfo), Range(Range), + DirectInitRange(DirectInitRange) { + + assert((Initializer != nullptr || InitializationStyle == NoInit) && + "Only NoInit can have no initializer!"); + + CXXNewExprBits.IsGlobalNew = IsGlobalNew; + CXXNewExprBits.IsArray = ArraySize != nullptr; + CXXNewExprBits.ShouldPassAlignment = ShouldPassAlignment; + CXXNewExprBits.UsualArrayDeleteWantsSize = UsualArrayDeleteWantsSize; + CXXNewExprBits.StoredInitializationStyle = + Initializer ? InitializationStyle + 1 : 0; + bool IsParenTypeId = TypeIdParens.isValid(); + CXXNewExprBits.IsParenTypeId = IsParenTypeId; + CXXNewExprBits.NumPlacementArgs = PlacementArgs.size(); + + if (ArraySize) { + if (ArraySize->isInstantiationDependent()) ExprBits.InstantiationDependent = true; - - if (arraySize->containsUnexpandedParameterPack()) + if (ArraySize->containsUnexpandedParameterPack()) ExprBits.ContainsUnexpandedParameterPack = true; - SubExprs[i++] = arraySize; + getTrailingObjects<Stmt *>()[arraySizeOffset()] = ArraySize; } - if (initializer) { - if (initializer->isInstantiationDependent()) + if (Initializer) { + if (Initializer->isInstantiationDependent()) ExprBits.InstantiationDependent = true; - - if (initializer->containsUnexpandedParameterPack()) + if (Initializer->containsUnexpandedParameterPack()) ExprBits.ContainsUnexpandedParameterPack = true; - SubExprs[i++] = initializer; + getTrailingObjects<Stmt *>()[initExprOffset()] = Initializer; } - for (unsigned j = 0; j != placementArgs.size(); ++j) { - if (placementArgs[j]->isInstantiationDependent()) + for (unsigned I = 0; I != PlacementArgs.size(); ++I) { + if (PlacementArgs[I]->isInstantiationDependent()) ExprBits.InstantiationDependent = true; - if (placementArgs[j]->containsUnexpandedParameterPack()) + if (PlacementArgs[I]->containsUnexpandedParameterPack()) ExprBits.ContainsUnexpandedParameterPack = true; - SubExprs[i++] = placementArgs[j]; + getTrailingObjects<Stmt *>()[placementNewArgsOffset() + I] = + PlacementArgs[I]; } + if (IsParenTypeId) + getTrailingObjects<SourceRange>()[0] = TypeIdParens; + switch (getInitializationStyle()) { case CallInit: - this->Range.setEnd(DirectInitRange.getEnd()); break; + this->Range.setEnd(DirectInitRange.getEnd()); + break; case ListInit: - this->Range.setEnd(getInitializer()->getSourceRange().getEnd()); break; + this->Range.setEnd(getInitializer()->getSourceRange().getEnd()); + break; default: - if (TypeIdParens.isValid()) + if (IsParenTypeId) this->Range.setEnd(TypeIdParens.getEnd()); break; } } -void CXXNewExpr::AllocateArgsArray(const ASTContext &C, bool isArray, - unsigned numPlaceArgs, bool hasInitializer){ - assert(SubExprs == nullptr && "SubExprs already allocated"); - Array = isArray; - NumPlacementArgs = numPlaceArgs; +CXXNewExpr::CXXNewExpr(EmptyShell Empty, bool IsArray, + unsigned NumPlacementArgs, bool IsParenTypeId) + : Expr(CXXNewExprClass, Empty) { + CXXNewExprBits.IsArray = IsArray; + CXXNewExprBits.NumPlacementArgs = NumPlacementArgs; + CXXNewExprBits.IsParenTypeId = IsParenTypeId; +} + +CXXNewExpr * +CXXNewExpr::Create(const ASTContext &Ctx, bool IsGlobalNew, + FunctionDecl *OperatorNew, FunctionDecl *OperatorDelete, + bool ShouldPassAlignment, bool UsualArrayDeleteWantsSize, + ArrayRef<Expr *> PlacementArgs, SourceRange TypeIdParens, + Expr *ArraySize, InitializationStyle InitializationStyle, + Expr *Initializer, QualType Ty, + TypeSourceInfo *AllocatedTypeInfo, SourceRange Range, + SourceRange DirectInitRange) { + bool IsArray = ArraySize != nullptr; + bool HasInit = Initializer != nullptr; + unsigned NumPlacementArgs = PlacementArgs.size(); + bool IsParenTypeId = TypeIdParens.isValid(); + void *Mem = + Ctx.Allocate(totalSizeToAlloc<Stmt *, SourceRange>( + IsArray + HasInit + NumPlacementArgs, IsParenTypeId), + alignof(CXXNewExpr)); + return new (Mem) + CXXNewExpr(IsGlobalNew, OperatorNew, OperatorDelete, ShouldPassAlignment, + UsualArrayDeleteWantsSize, PlacementArgs, TypeIdParens, + ArraySize, InitializationStyle, Initializer, Ty, + AllocatedTypeInfo, Range, DirectInitRange); +} - unsigned TotalSize = Array + hasInitializer + NumPlacementArgs; - SubExprs = new (C) Stmt*[TotalSize]; +CXXNewExpr *CXXNewExpr::CreateEmpty(const ASTContext &Ctx, bool IsArray, + bool HasInit, unsigned NumPlacementArgs, + bool IsParenTypeId) { + void *Mem = + Ctx.Allocate(totalSizeToAlloc<Stmt *, SourceRange>( + IsArray + HasInit + NumPlacementArgs, IsParenTypeId), + alignof(CXXNewExpr)); + return new (Mem) + CXXNewExpr(EmptyShell(), IsArray, NumPlacementArgs, IsParenTypeId); } -bool CXXNewExpr::shouldNullCheckAllocation(const ASTContext &Ctx) const { - return getOperatorNew()->getType()->castAs<FunctionProtoType>() - ->isNothrow() && +bool CXXNewExpr::shouldNullCheckAllocation() const { + return getOperatorNew() + ->getType() + ->castAs<FunctionProtoType>() + ->isNothrow() && !getOperatorNew()->isReservedGlobalPlacementOperator(); } diff --git a/lib/CodeGen/CGExprCXX.cpp b/lib/CodeGen/CGExprCXX.cpp index 2e0d4ca767..fabbb4ca54 100644 --- a/lib/CodeGen/CGExprCXX.cpp +++ b/lib/CodeGen/CGExprCXX.cpp @@ -1657,8 +1657,8 @@ llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) { // function is allowed to return null (because it has a non-throwing // exception spec or is the reserved placement new) and we have an // interesting initializer. - bool nullCheck = E->shouldNullCheckAllocation(getContext()) && - (!allocType.isPODType(getContext()) || E->hasInitializer()); + bool nullCheck = E->shouldNullCheckAllocation() && + (!allocType.isPODType(getContext()) || E->hasInitializer()); llvm::BasicBlock *nullCheckBB = nullptr; llvm::BasicBlock *contBB = nullptr; diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 1c210d332e..e963058b73 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -2179,11 +2179,11 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, } } - return new (Context) - CXXNewExpr(Context, UseGlobal, OperatorNew, OperatorDelete, PassAlignment, - UsualArrayDeleteWantsSize, PlacementArgs, TypeIdParens, - ArraySize, initStyle, Initializer, ResultType, AllocTypeInfo, - Range, DirectInitRange); + return CXXNewExpr::Create(Context, UseGlobal, OperatorNew, OperatorDelete, + PassAlignment, UsualArrayDeleteWantsSize, + PlacementArgs, TypeIdParens, ArraySize, initStyle, + Initializer, ResultType, AllocTypeInfo, Range, + DirectInitRange); } /// Checks that a type is suitable as the allocated type diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp index e789e20f57..80b987a662 100644 --- a/lib/Serialization/ASTReaderStmt.cpp +++ b/lib/Serialization/ASTReaderStmt.cpp @@ -1507,25 +1507,38 @@ void ASTStmtReader::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) { void ASTStmtReader::VisitCXXNewExpr(CXXNewExpr *E) { VisitExpr(E); - E->GlobalNew = Record.readInt(); - bool isArray = Record.readInt(); - E->PassAlignment = Record.readInt(); - E->UsualArrayDeleteWantsSize = Record.readInt(); + + bool IsArray = Record.readInt(); + bool HasInit = Record.readInt(); unsigned NumPlacementArgs = Record.readInt(); - E->StoredInitializationStyle = Record.readInt(); + bool IsParenTypeId = Record.readInt(); + + E->CXXNewExprBits.IsGlobalNew = Record.readInt(); + E->CXXNewExprBits.ShouldPassAlignment = Record.readInt(); + E->CXXNewExprBits.UsualArrayDeleteWantsSize = Record.readInt(); + E->CXXNewExprBits.StoredInitializationStyle = Record.readInt(); + + assert((IsArray == E->isArray()) && "Wrong IsArray!"); + assert((HasInit == E->hasInitializer()) && "Wrong HasInit!"); + assert((NumPlacementArgs == E->getNumPlacementArgs()) && + "Wrong NumPlacementArgs!"); + assert((IsParenTypeId == E->isParenTypeId()) && "Wrong IsParenTypeId!"); + (void)IsArray; + (void)HasInit; + (void)NumPlacementArgs; + E->setOperatorNew(ReadDeclAs<FunctionDecl>()); E->setOperatorDelete(ReadDeclAs<FunctionDecl>()); E->AllocatedTypeInfo = GetTypeSourceInfo(); - E->TypeIdParens = ReadSourceRange(); + if (IsParenTypeId) + E->getTrailingObjects<SourceRange>()[0] = ReadSourceRange(); E->Range = ReadSourceRange(); E->DirectInitRange = ReadSourceRange(); - E->AllocateArgsArray(Record.getContext(), isArray, NumPlacementArgs, - E->StoredInitializationStyle != 0); - // Install all the subexpressions. - for (CXXNewExpr::raw_arg_iterator I = E->raw_arg_begin(),e = E->raw_arg_end(); - I != e; ++I) + for (CXXNewExpr::raw_arg_iterator I = E->raw_arg_begin(), + N = E->raw_arg_end(); + I != N; ++I) *I = Record.readSubStmt(); } @@ -3189,7 +3202,12 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { break; case EXPR_CXX_NEW: - S = new (Context) CXXNewExpr(Empty); + S = CXXNewExpr::CreateEmpty( + Context, + /*IsArray=*/Record[ASTStmtReader::NumExprFields], + /*HasInit=*/Record[ASTStmtReader::NumExprFields + 1], + /*NumPlacementArgs=*/Record[ASTStmtReader::NumExprFields + 2], + /*IsParenTypeId=*/Record[ASTStmtReader::NumExprFields + 3]); break; case EXPR_CXX_DELETE: diff --git a/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp index 26a01706dc..14c3b3278e 100644 --- a/lib/Serialization/ASTWriterStmt.cpp +++ b/lib/Serialization/ASTWriterStmt.cpp @@ -1483,20 +1483,27 @@ void ASTStmtWriter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) { void ASTStmtWriter::VisitCXXNewExpr(CXXNewExpr *E) { VisitExpr(E); - Record.push_back(E->isGlobalNew()); + Record.push_back(E->isArray()); + Record.push_back(E->hasInitializer()); + Record.push_back(E->getNumPlacementArgs()); + Record.push_back(E->isParenTypeId()); + + Record.push_back(E->isGlobalNew()); Record.push_back(E->passAlignment()); Record.push_back(E->doesUsualArrayDeleteWantSize()); - Record.push_back(E->getNumPlacementArgs()); - Record.push_back(E->StoredInitializationStyle); + Record.push_back(E->CXXNewExprBits.StoredInitializationStyle); + Record.AddDeclRef(E->getOperatorNew()); Record.AddDeclRef(E->getOperatorDelete()); Record.AddTypeSourceInfo(E->getAllocatedTypeSourceInfo()); - Record.AddSourceRange(E->getTypeIdParens()); + if (E->isParenTypeId()) + Record.AddSourceRange(E->getTypeIdParens()); Record.AddSourceRange(E->getSourceRange()); Record.AddSourceRange(E->getDirectInitRange()); - for (CXXNewExpr::arg_iterator I = E->raw_arg_begin(), e = E->raw_arg_end(); - I != e; ++I) + + for (CXXNewExpr::arg_iterator I = E->raw_arg_begin(), N = E->raw_arg_end(); + I != N; ++I) Record.AddStmt(*I); Code = serialization::EXPR_CXX_NEW; |