[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.