[AST] Store the results in OverloadExpr in a trailing array
Use the newly available space in the bit-fields of Stmt to pack
OverloadExpr, UnresolvedLookupExpr and UnresolvedMemberExpr.
Additionally store the results in the overload set in a trailing array.
This saves 1 pointer + 8 bytes per UnresolvedLookupExpr and
UnresolvedMemberExpr.
Differential Revision: https://reviews.llvm.org/D56368
Reviewed By: rjmccall
llvm-svn: 350732
diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp
index 9a724cd..699baa7 100644
--- a/clang/lib/AST/ExprCXX.cpp
+++ b/clang/lib/AST/ExprCXX.cpp
@@ -302,68 +302,95 @@
}
// UnresolvedLookupExpr
-UnresolvedLookupExpr *
-UnresolvedLookupExpr::Create(const ASTContext &C,
- CXXRecordDecl *NamingClass,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc,
- const DeclarationNameInfo &NameInfo,
- bool ADL,
- const TemplateArgumentListInfo *Args,
- UnresolvedSetIterator Begin,
- UnresolvedSetIterator End) {
+UnresolvedLookupExpr::UnresolvedLookupExpr(
+ const ASTContext &Context, CXXRecordDecl *NamingClass,
+ NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc,
+ const DeclarationNameInfo &NameInfo, bool RequiresADL, bool Overloaded,
+ const TemplateArgumentListInfo *TemplateArgs, UnresolvedSetIterator Begin,
+ UnresolvedSetIterator End)
+ : OverloadExpr(UnresolvedLookupExprClass, Context, QualifierLoc,
+ TemplateKWLoc, NameInfo, TemplateArgs, Begin, End, false,
+ false, false),
+ NamingClass(NamingClass) {
+ UnresolvedLookupExprBits.RequiresADL = RequiresADL;
+ UnresolvedLookupExprBits.Overloaded = Overloaded;
+}
+
+UnresolvedLookupExpr::UnresolvedLookupExpr(EmptyShell Empty,
+ unsigned NumResults,
+ bool HasTemplateKWAndArgsInfo)
+ : OverloadExpr(UnresolvedLookupExprClass, Empty, NumResults,
+ HasTemplateKWAndArgsInfo) {}
+
+UnresolvedLookupExpr *UnresolvedLookupExpr::Create(
+ const ASTContext &Context, CXXRecordDecl *NamingClass,
+ NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo,
+ bool RequiresADL, bool Overloaded, UnresolvedSetIterator Begin,
+ UnresolvedSetIterator End) {
+ unsigned NumResults = End - Begin;
+ unsigned Size = totalSizeToAlloc<DeclAccessPair, ASTTemplateKWAndArgsInfo,
+ TemplateArgumentLoc>(NumResults, 0, 0);
+ void *Mem = Context.Allocate(Size, alignof(UnresolvedLookupExpr));
+ return new (Mem) UnresolvedLookupExpr(Context, NamingClass, QualifierLoc,
+ SourceLocation(), NameInfo, RequiresADL,
+ Overloaded, nullptr, Begin, End);
+}
+
+UnresolvedLookupExpr *UnresolvedLookupExpr::Create(
+ const ASTContext &Context, CXXRecordDecl *NamingClass,
+ NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc,
+ const DeclarationNameInfo &NameInfo, bool RequiresADL,
+ const TemplateArgumentListInfo *Args, UnresolvedSetIterator Begin,
+ UnresolvedSetIterator End) {
assert(Args || TemplateKWLoc.isValid());
- unsigned num_args = Args ? Args->size() : 0;
-
- std::size_t Size =
- totalSizeToAlloc<ASTTemplateKWAndArgsInfo, TemplateArgumentLoc>(1,
- num_args);
- void *Mem = C.Allocate(Size, alignof(UnresolvedLookupExpr));
- return new (Mem) UnresolvedLookupExpr(C, NamingClass, QualifierLoc,
- TemplateKWLoc, NameInfo,
- ADL, /*Overload*/ true, Args,
- Begin, End);
+ unsigned NumResults = End - Begin;
+ unsigned NumTemplateArgs = Args ? Args->size() : 0;
+ unsigned Size =
+ totalSizeToAlloc<DeclAccessPair, ASTTemplateKWAndArgsInfo,
+ TemplateArgumentLoc>(NumResults, 1, NumTemplateArgs);
+ void *Mem = Context.Allocate(Size, alignof(UnresolvedLookupExpr));
+ return new (Mem) UnresolvedLookupExpr(Context, NamingClass, QualifierLoc,
+ TemplateKWLoc, NameInfo, RequiresADL,
+ /*Overloaded*/ true, Args, Begin, End);
}
-UnresolvedLookupExpr *
-UnresolvedLookupExpr::CreateEmpty(const ASTContext &C,
- bool HasTemplateKWAndArgsInfo,
- unsigned NumTemplateArgs) {
+UnresolvedLookupExpr *UnresolvedLookupExpr::CreateEmpty(
+ const ASTContext &Context, unsigned NumResults,
+ bool HasTemplateKWAndArgsInfo, unsigned NumTemplateArgs) {
assert(NumTemplateArgs == 0 || HasTemplateKWAndArgsInfo);
- std::size_t Size =
- totalSizeToAlloc<ASTTemplateKWAndArgsInfo, TemplateArgumentLoc>(
- HasTemplateKWAndArgsInfo, NumTemplateArgs);
- void *Mem = C.Allocate(Size, alignof(UnresolvedLookupExpr));
- auto *E = new (Mem) UnresolvedLookupExpr(EmptyShell());
- E->HasTemplateKWAndArgsInfo = HasTemplateKWAndArgsInfo;
- return E;
+ unsigned Size = totalSizeToAlloc<DeclAccessPair, ASTTemplateKWAndArgsInfo,
+ TemplateArgumentLoc>(
+ NumResults, HasTemplateKWAndArgsInfo, NumTemplateArgs);
+ void *Mem = Context.Allocate(Size, alignof(UnresolvedLookupExpr));
+ return new (Mem)
+ UnresolvedLookupExpr(EmptyShell(), NumResults, HasTemplateKWAndArgsInfo);
}
-OverloadExpr::OverloadExpr(StmtClass K, const ASTContext &C,
+OverloadExpr::OverloadExpr(StmtClass SC, const ASTContext &Context,
NestedNameSpecifierLoc QualifierLoc,
SourceLocation TemplateKWLoc,
const DeclarationNameInfo &NameInfo,
const TemplateArgumentListInfo *TemplateArgs,
UnresolvedSetIterator Begin,
- UnresolvedSetIterator End,
- bool KnownDependent,
+ UnresolvedSetIterator End, bool KnownDependent,
bool KnownInstantiationDependent,
bool KnownContainsUnexpandedParameterPack)
- : Expr(K, C.OverloadTy, VK_LValue, OK_Ordinary, KnownDependent,
- KnownDependent,
- (KnownInstantiationDependent ||
- NameInfo.isInstantiationDependent() ||
- (QualifierLoc &&
+ : Expr(
+ SC, Context.OverloadTy, VK_LValue, OK_Ordinary, KnownDependent,
+ KnownDependent,
+ (KnownInstantiationDependent || NameInfo.isInstantiationDependent() ||
+ (QualifierLoc &&
QualifierLoc.getNestedNameSpecifier()->isInstantiationDependent())),
- (KnownContainsUnexpandedParameterPack ||
- NameInfo.containsUnexpandedParameterPack() ||
- (QualifierLoc &&
- QualifierLoc.getNestedNameSpecifier()
- ->containsUnexpandedParameterPack()))),
- NameInfo(NameInfo), QualifierLoc(QualifierLoc), NumResults(End - Begin),
- HasTemplateKWAndArgsInfo(TemplateArgs != nullptr ||
- TemplateKWLoc.isValid()) {
- NumResults = End - Begin;
+ (KnownContainsUnexpandedParameterPack ||
+ NameInfo.containsUnexpandedParameterPack() ||
+ (QualifierLoc && QualifierLoc.getNestedNameSpecifier()
+ ->containsUnexpandedParameterPack()))),
+ NameInfo(NameInfo), QualifierLoc(QualifierLoc) {
+ unsigned NumResults = End - Begin;
+ OverloadExprBits.NumResults = NumResults;
+ OverloadExprBits.HasTemplateKWAndArgsInfo =
+ (TemplateArgs != nullptr ) || TemplateKWLoc.isValid();
+
if (NumResults) {
// Determine whether this expression is type-dependent.
for (UnresolvedSetImpl::const_iterator I = Begin; I != End; ++I) {
@@ -375,8 +402,9 @@
}
}
- Results = static_cast<DeclAccessPair *>(C.Allocate(
- sizeof(DeclAccessPair) * NumResults, alignof(DeclAccessPair)));
+ // Copy the results to the trailing array past UnresolvedLookupExpr
+ // or UnresolvedMemberExpr.
+ DeclAccessPair *Results = getTrailingResults();
memcpy(Results, Begin.I, NumResults * sizeof(DeclAccessPair));
}
@@ -404,28 +432,14 @@
}
if (isTypeDependent())
- setType(C.DependentTy);
+ setType(Context.DependentTy);
}
-void OverloadExpr::initializeResults(const ASTContext &C,
- UnresolvedSetIterator Begin,
- UnresolvedSetIterator End) {
- assert(!Results && "Results already initialized!");
- NumResults = End - Begin;
- if (NumResults) {
- Results = static_cast<DeclAccessPair *>(
- C.Allocate(sizeof(DeclAccessPair) * NumResults,
-
- alignof(DeclAccessPair)));
- memcpy(Results, Begin.I, NumResults * sizeof(DeclAccessPair));
- }
-}
-
-CXXRecordDecl *OverloadExpr::getNamingClass() const {
- if (isa<UnresolvedLookupExpr>(this))
- return cast<UnresolvedLookupExpr>(this)->getNamingClass();
- else
- return cast<UnresolvedMemberExpr>(this)->getNamingClass();
+OverloadExpr::OverloadExpr(StmtClass SC, EmptyShell Empty, unsigned NumResults,
+ bool HasTemplateKWAndArgsInfo)
+ : Expr(SC, Empty) {
+ OverloadExprBits.NumResults = NumResults;
+ OverloadExprBits.HasTemplateKWAndArgsInfo = HasTemplateKWAndArgsInfo;
}
// DependentScopeDeclRefExpr
@@ -1401,19 +1415,15 @@
return true;
}
-UnresolvedMemberExpr::UnresolvedMemberExpr(const ASTContext &C,
- bool HasUnresolvedUsing,
- Expr *Base, QualType BaseType,
- bool IsArrow,
- SourceLocation OperatorLoc,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc,
- const DeclarationNameInfo &MemberNameInfo,
- const TemplateArgumentListInfo *TemplateArgs,
- UnresolvedSetIterator Begin,
- UnresolvedSetIterator End)
+UnresolvedMemberExpr::UnresolvedMemberExpr(
+ const ASTContext &Context, bool HasUnresolvedUsing, Expr *Base,
+ QualType BaseType, bool IsArrow, SourceLocation OperatorLoc,
+ NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc,
+ const DeclarationNameInfo &MemberNameInfo,
+ const TemplateArgumentListInfo *TemplateArgs, UnresolvedSetIterator Begin,
+ UnresolvedSetIterator End)
: OverloadExpr(
- UnresolvedMemberExprClass, C, QualifierLoc, TemplateKWLoc,
+ UnresolvedMemberExprClass, Context, QualifierLoc, TemplateKWLoc,
MemberNameInfo, TemplateArgs, Begin, End,
// Dependent
((Base && Base->isTypeDependent()) || BaseType->isDependentType()),
@@ -1422,14 +1432,22 @@
// Contains unexpanded parameter pack
((Base && Base->containsUnexpandedParameterPack()) ||
BaseType->containsUnexpandedParameterPack())),
- IsArrow(IsArrow), HasUnresolvedUsing(HasUnresolvedUsing), Base(Base),
- BaseType(BaseType), OperatorLoc(OperatorLoc) {
+ Base(Base), BaseType(BaseType), OperatorLoc(OperatorLoc) {
+ UnresolvedMemberExprBits.IsArrow = IsArrow;
+ UnresolvedMemberExprBits.HasUnresolvedUsing = HasUnresolvedUsing;
+
// Check whether all of the members are non-static member functions,
// and if so, mark give this bound-member type instead of overload type.
if (hasOnlyNonStaticMemberFunctions(Begin, End))
- setType(C.BoundMemberTy);
+ setType(Context.BoundMemberTy);
}
+UnresolvedMemberExpr::UnresolvedMemberExpr(EmptyShell Empty,
+ unsigned NumResults,
+ bool HasTemplateKWAndArgsInfo)
+ : OverloadExpr(UnresolvedMemberExprClass, Empty, NumResults,
+ HasTemplateKWAndArgsInfo) {}
+
bool UnresolvedMemberExpr::isImplicitAccess() const {
if (!Base)
return true;
@@ -1438,39 +1456,37 @@
}
UnresolvedMemberExpr *UnresolvedMemberExpr::Create(
- const ASTContext &C, bool HasUnresolvedUsing, Expr *Base, QualType BaseType,
- bool IsArrow, SourceLocation OperatorLoc,
+ const ASTContext &Context, bool HasUnresolvedUsing, Expr *Base,
+ QualType BaseType, bool IsArrow, SourceLocation OperatorLoc,
NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc,
const DeclarationNameInfo &MemberNameInfo,
const TemplateArgumentListInfo *TemplateArgs, UnresolvedSetIterator Begin,
UnresolvedSetIterator End) {
+ unsigned NumResults = End - Begin;
bool HasTemplateKWAndArgsInfo = TemplateArgs || TemplateKWLoc.isValid();
- std::size_t Size =
- totalSizeToAlloc<ASTTemplateKWAndArgsInfo, TemplateArgumentLoc>(
- HasTemplateKWAndArgsInfo, TemplateArgs ? TemplateArgs->size() : 0);
-
- void *Mem = C.Allocate(Size, alignof(UnresolvedMemberExpr));
+ unsigned NumTemplateArgs = TemplateArgs ? TemplateArgs->size() : 0;
+ unsigned Size = totalSizeToAlloc<DeclAccessPair, ASTTemplateKWAndArgsInfo,
+ TemplateArgumentLoc>(
+ NumResults, HasTemplateKWAndArgsInfo, NumTemplateArgs);
+ void *Mem = Context.Allocate(Size, alignof(UnresolvedMemberExpr));
return new (Mem) UnresolvedMemberExpr(
- C, HasUnresolvedUsing, Base, BaseType, IsArrow, OperatorLoc, QualifierLoc,
- TemplateKWLoc, MemberNameInfo, TemplateArgs, Begin, End);
+ Context, HasUnresolvedUsing, Base, BaseType, IsArrow, OperatorLoc,
+ QualifierLoc, TemplateKWLoc, MemberNameInfo, TemplateArgs, Begin, End);
}
-UnresolvedMemberExpr *
-UnresolvedMemberExpr::CreateEmpty(const ASTContext &C,
- bool HasTemplateKWAndArgsInfo,
- unsigned NumTemplateArgs) {
+UnresolvedMemberExpr *UnresolvedMemberExpr::CreateEmpty(
+ const ASTContext &Context, unsigned NumResults,
+ bool HasTemplateKWAndArgsInfo, unsigned NumTemplateArgs) {
assert(NumTemplateArgs == 0 || HasTemplateKWAndArgsInfo);
- std::size_t Size =
- totalSizeToAlloc<ASTTemplateKWAndArgsInfo, TemplateArgumentLoc>(
- HasTemplateKWAndArgsInfo, NumTemplateArgs);
-
- void *Mem = C.Allocate(Size, alignof(UnresolvedMemberExpr));
- auto *E = new (Mem) UnresolvedMemberExpr(EmptyShell());
- E->HasTemplateKWAndArgsInfo = HasTemplateKWAndArgsInfo;
- return E;
+ unsigned Size = totalSizeToAlloc<DeclAccessPair, ASTTemplateKWAndArgsInfo,
+ TemplateArgumentLoc>(
+ NumResults, HasTemplateKWAndArgsInfo, NumTemplateArgs);
+ void *Mem = Context.Allocate(Size, alignof(UnresolvedMemberExpr));
+ return new (Mem)
+ UnresolvedMemberExpr(EmptyShell(), NumResults, HasTemplateKWAndArgsInfo);
}
-CXXRecordDecl *UnresolvedMemberExpr::getNamingClass() const {
+CXXRecordDecl *UnresolvedMemberExpr::getNamingClass() {
// Unlike for UnresolvedLookupExpr, it is very easy to re-derive this.
// If there was a nested name specifier, it names the naming class.