summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorBruno Ricci <riccibrun@gmail.com>2019-01-07 15:04:45 +0000
committerBruno Ricci <riccibrun@gmail.com>2019-01-07 15:04:45 +0000
commit7eadfa4ba2821e7394224da7023128dc9b36eebd (patch)
tree6b1dbedb6e0174ca7ea7beb6707d658da5a7af09 /lib
parent4d27dbbf8ec35d8c58f80938a8383da37e9f3800 (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.cpp2
-rw-r--r--lib/AST/ExprCXX.cpp144
-rw-r--r--lib/CodeGen/CGExprCXX.cpp4
-rw-r--r--lib/Sema/SemaExprCXX.cpp10
-rw-r--r--lib/Serialization/ASTReaderStmt.cpp42
-rw-r--r--lib/Serialization/ASTWriterStmt.cpp19
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;