Refactoring of Diagnostic class.

-Move the stuff of Diagnostic related to creating/querying diagnostic IDs into a new DiagnosticIDs class.
-DiagnosticIDs can be shared among multiple Diagnostics for multiple translation units.
-The rest of the state in Diagnostic object is considered related and tied to one translation unit.
-Have Diagnostic point to the SourceManager that is related with. Diagnostic can now accept just a
   SourceLocation instead of a FullSourceLoc.
-Reflect the changes to various interfaces.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@119730 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Frontend/ASTMerge.cpp b/lib/Frontend/ASTMerge.cpp
index f270846..7c8763d 100644
--- a/lib/Frontend/ASTMerge.cpp
+++ b/lib/Frontend/ASTMerge.cpp
@@ -38,21 +38,18 @@
                                          CI.getASTContext().getLangOptions());
   CI.getDiagnostics().SetArgToStringFn(&FormatASTNodeDiagnosticArgument,
                                        &CI.getASTContext());
-  llvm::IntrusiveRefCntPtr<Diagnostic> Diags(&CI.getDiagnostics());
+  llvm::IntrusiveRefCntPtr<DiagnosticIDs>
+      DiagIDs(CI.getDiagnostics().getDiagnosticIDs());
   for (unsigned I = 0, N = ASTFiles.size(); I != N; ++I) {
+    llvm::IntrusiveRefCntPtr<Diagnostic>
+        Diags(new Diagnostic(DiagIDs, CI.getDiagnostics().getClient(),
+                             /*ShouldOwnClient=*/false));
     ASTUnit *Unit = ASTUnit::LoadFromASTFile(ASTFiles[I], Diags,
                                              CI.getFileSystemOpts(), false);
     if (!Unit)
       continue;
 
-    // Reset the argument -> string function so that it has the AST
-    // context we want, since the Sema object created by
-    // LoadFromASTFile will override it.
-    CI.getDiagnostics().SetArgToStringFn(&FormatASTNodeDiagnosticArgument,
-                                         &CI.getASTContext());
-
-    ASTImporter Importer(CI.getDiagnostics(),
-                         CI.getASTContext(), 
+    ASTImporter Importer(CI.getASTContext(), 
                          CI.getFileManager(),
                          CI.getFileSystemOpts(),
                          Unit->getASTContext(), 
@@ -72,6 +69,15 @@
       Importer.Import(*D);
     }
 
+    // Aggregate the number of warnings/errors from all diagnostics so
+    // that at CompilerInstance::ExecuteAction we can report the total numbers.
+    // FIXME: This is hacky, maybe keep track of total number of warnings/errors
+    // in DiagnosticClient and have CompilerInstance query that ?
+    CI.getDiagnostics().setNumWarnings(CI.getDiagnostics().getNumWarnings() +
+                                       Diags->getNumWarnings());
+    CI.getDiagnostics().setNumErrors(CI.getDiagnostics().getNumErrors() +
+                                     Diags->getNumErrors());
+
     delete Unit;
   }
 
diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp
index 7cfcd1c..dafbef1 100644
--- a/lib/Frontend/CompilerInstance.cpp
+++ b/lib/Frontend/CompilerInstance.cpp
@@ -122,7 +122,8 @@
 CompilerInstance::createDiagnostics(const DiagnosticOptions &Opts,
                                     int Argc, const char* const *Argv,
                                     DiagnosticClient *Client) {
-  llvm::IntrusiveRefCntPtr<Diagnostic> Diags(new Diagnostic());
+  llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
+  llvm::IntrusiveRefCntPtr<Diagnostic> Diags(new Diagnostic(DiagID));
 
   // Create the diagnostic client for reporting errors or for
   // implementing -verify.
diff --git a/lib/Frontend/TextDiagnosticPrinter.cpp b/lib/Frontend/TextDiagnosticPrinter.cpp
index 4fd0552..2528777 100644
--- a/lib/Frontend/TextDiagnosticPrinter.cpp
+++ b/lib/Frontend/TextDiagnosticPrinter.cpp
@@ -776,7 +776,7 @@
   // If the location is specified, print out a file/line/col and include trace
   // if enabled.
   if (Info.getLocation().isValid()) {
-    const SourceManager &SM = Info.getLocation().getManager();
+    const SourceManager &SM = Info.getSourceManager();
     PresumedLoc PLoc = SM.getPresumedLoc(Info.getLocation());
     if (PLoc.isInvalid())
       return;
@@ -884,7 +884,8 @@
 
   std::string OptionName;
   if (DiagOpts->ShowOptionNames) {
-    if (const char *Opt = Diagnostic::getWarningOptionForDiag(Info.getID())) {
+    if (const char *
+          Opt = DiagnosticIDs::getWarningOptionForDiag(Info.getID())) {
       OptionName = "-W";
       OptionName += Opt;
     } else if (Info.getID() == diag::fatal_too_many_errors) {
@@ -893,7 +894,8 @@
       // If the diagnostic is an extension diagnostic and not enabled by default
       // then it must have been turned on with -pedantic.
       bool EnabledByDefault;
-      if (Diagnostic::isBuiltinExtensionDiag(Info.getID(), EnabledByDefault) &&
+      if (DiagnosticIDs::isBuiltinExtensionDiag(Info.getID(),
+                                                EnabledByDefault) &&
           !EnabledByDefault)
         OptionName = "-pedantic";
     }
@@ -902,7 +904,7 @@
   // If the user wants to see category information, include it too.
   unsigned DiagCategory = 0;
   if (DiagOpts->ShowCategories)
-    DiagCategory = Diagnostic::getCategoryNumberForDiag(Info.getID());
+    DiagCategory = DiagnosticIDs::getCategoryNumberForDiag(Info.getID());
 
   // If there is any categorization information, include it.
   if (!OptionName.empty() || DiagCategory != 0) {
@@ -920,7 +922,7 @@
         OutStr += llvm::utostr(DiagCategory);
       else {
         assert(DiagOpts->ShowCategories == 2 && "Invalid ShowCategories value");
-        OutStr += Diagnostic::getCategoryNameFromID(DiagCategory);
+        OutStr += DiagnosticIDs::getCategoryNameFromID(DiagCategory);
       }
     }
     
@@ -962,7 +964,7 @@
        (LastCaretDiagnosticWasNote && Level != Diagnostic::Note) ||
        Info.getNumFixItHints())) {
     // Cache the LastLoc, it allows us to omit duplicate source/caret spewage.
-    LastLoc = Info.getLocation();
+    LastLoc = FullSourceLoc(Info.getLocation(), Info.getSourceManager());
     LastCaretDiagnosticWasNote = (Level == Diagnostic::Note);
 
     // Get the ranges into a local array we can hack on.