Optimize PartialDiagnostic's memory-allocation behavior by placing a
cache of PartialDiagnostic::Storage objects into an allocator within
the ASTContext. This eliminates a significant amount of malloc
traffic, for a 10% performance improvement in -fsyntax-only wall-clock
time with 403.gcc's combine.c.

Also, eliminate the RequireNonAbstractType hack I put in earlier,
which was but a symptom of this larger problem.

Fixes <rdar://problem/7806091>.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@99849 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 9c661ba..859e497 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -312,30 +312,33 @@
 
     bool isMemberAccess() const { return IsMember; }
 
-    AccessedEntity(MemberNonce _,
+    AccessedEntity(ASTContext &Context, 
+                   MemberNonce _,
                    CXXRecordDecl *NamingClass,
                    AccessSpecifier Access,
                    NamedDecl *Target)
       : Access(Access), IsMember(true), 
         Target(Target), NamingClass(NamingClass),
-        Diag(0) {
+        Diag(0, Context.getDiagAllocator()) {
     }
 
-    AccessedEntity(MemberNonce _,
+    AccessedEntity(ASTContext &Context, 
+                   MemberNonce _,
                    CXXRecordDecl *NamingClass,
                    DeclAccessPair FoundDecl)
       : Access(FoundDecl.getAccess()), IsMember(true), 
         Target(FoundDecl.getDecl()), NamingClass(NamingClass),
-        Diag(0) {
+        Diag(0, Context.getDiagAllocator()) {
     }
 
-    AccessedEntity(BaseNonce _,
+    AccessedEntity(ASTContext &Context, 
+                   BaseNonce _,
                    CXXRecordDecl *BaseClass,
                    CXXRecordDecl *DerivedClass,
                    AccessSpecifier Access)
       : Access(Access), IsMember(false),
         Target(BaseClass), NamingClass(DerivedClass),
-        Diag(0) {
+        Diag(0, Context.getDiagAllocator()) {
     }
 
     bool isQuiet() const { return Diag.getDiagID() == 0; }
@@ -363,7 +366,7 @@
     PartialDiagnostic &setDiag(unsigned DiagID) {
       assert(isQuiet() && "partial diagnostic already defined");
       assert(DiagID && "creating null diagnostic");
-      Diag = PartialDiagnostic(DiagID);
+      Diag.Reset(DiagID);
       return Diag;
     }
     const PartialDiagnostic &getDiag() const {
@@ -615,6 +618,11 @@
   /// \brief Emit a partial diagnostic.
   SemaDiagnosticBuilder Diag(SourceLocation Loc, const PartialDiagnostic& PD);
 
+  /// \brief Build a partial diagnostic. 
+  PartialDiagnostic PDiag(unsigned DiagID = 0) {
+    return PartialDiagnostic(DiagID, Context.getDiagAllocator());
+  }
+  
   virtual void DeleteExpr(ExprTy *E);
   virtual void DeleteStmt(StmtTy *S);
 
@@ -732,10 +740,12 @@
 
   bool RequireCompleteType(SourceLocation Loc, QualType T,
                            const PartialDiagnostic &PD,
-                           std::pair<SourceLocation,
-                                     PartialDiagnostic> Note =
-                            std::make_pair(SourceLocation(), PDiag()));
-
+                           std::pair<SourceLocation, PartialDiagnostic> Note);
+  bool RequireCompleteType(SourceLocation Loc, QualType T,
+                           const PartialDiagnostic &PD);
+  bool RequireCompleteType(SourceLocation Loc, QualType T,
+                           unsigned DiagID);
+  
   QualType getQualifiedNameType(const CXXScopeSpec &SS, QualType T);
 
   QualType BuildTypeofExprType(Expr *E);