Shuffle VerifyDiagnosticsClient API to be less fragile.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@88765 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Frontend/VerifyDiagnosticsClient.h b/include/clang/Frontend/VerifyDiagnosticsClient.h
index 3b841cb..bac1ccf 100644
--- a/include/clang/Frontend/VerifyDiagnosticsClient.h
+++ b/include/clang/Frontend/VerifyDiagnosticsClient.h
@@ -48,11 +48,10 @@
 ///
 class VerifyDiagnosticsClient : public DiagnosticClient {
 public:
+  Diagnostic &Diags;
   llvm::OwningPtr<DiagnosticClient> PrimaryClient;
   llvm::OwningPtr<TextDiagnosticBuffer> Buffer;
   Preprocessor *CurrentPreprocessor;
-  Diagnostic *Diags;
-  SourceManager *SourceMgr;
   bool NumErrors;
 
 private:
@@ -63,14 +62,14 @@
   /// PrimaryClient when a diagnostic does not match what is expected (as
   /// indicated in the source file). The verifying diagnostic client takes
   /// ownership of \arg PrimaryClient.
-  VerifyDiagnosticsClient(DiagnosticClient *PrimaryClient);
+  VerifyDiagnosticsClient(Diagnostic &Diags, DiagnosticClient *PrimaryClient);
   ~VerifyDiagnosticsClient();
 
   virtual void BeginSourceFile(const LangOptions &LangOpts,
                                const Preprocessor *PP);
 
   virtual void EndSourceFile();
-                               
+
   virtual void HandleDiagnostic(Diagnostic::Level DiagLevel,
                                 const DiagnosticInfo &Info);
 
diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp
index b5277ac..42352df 100644
--- a/lib/Frontend/CompilerInstance.cpp
+++ b/lib/Frontend/CompilerInstance.cpp
@@ -113,6 +113,8 @@
 
 Diagnostic *CompilerInstance::createDiagnostics(const DiagnosticOptions &Opts,
                                                 int Argc, char **Argv) {
+  llvm::OwningPtr<Diagnostic> Diags(new Diagnostic());
+
   // Create the diagnostic client for reporting errors or for
   // implementing -verify.
   llvm::OwningPtr<DiagnosticClient> DiagClient(
@@ -120,17 +122,17 @@
 
   // Chain in -verify checker, if requested.
   if (Opts.VerifyDiagnostics)
-    DiagClient.reset(new VerifyDiagnosticsClient(DiagClient.take()));
+    DiagClient.reset(new VerifyDiagnosticsClient(*Diags, DiagClient.take()));
 
   if (!Opts.DumpBuildInformation.empty())
     SetUpBuildDumpLog(Opts, Argc, Argv, DiagClient);
 
   // Configure our handling of diagnostics.
-  Diagnostic *Diags = new Diagnostic(DiagClient.take());
+  Diags->setClient(DiagClient.take());
   if (ProcessWarningOptions(*Diags, Opts))
     return 0;
 
-  return Diags;
+  return Diags.take();
 }
 
 // File Manager
diff --git a/lib/Frontend/VerifyDiagnosticsClient.cpp b/lib/Frontend/VerifyDiagnosticsClient.cpp
index abcca09..2891aec 100644
--- a/lib/Frontend/VerifyDiagnosticsClient.cpp
+++ b/lib/Frontend/VerifyDiagnosticsClient.cpp
@@ -19,9 +19,10 @@
 #include "llvm/Support/raw_ostream.h"
 using namespace clang;
 
-VerifyDiagnosticsClient::VerifyDiagnosticsClient(DiagnosticClient *_Primary)
-  : PrimaryClient(_Primary), Buffer(new TextDiagnosticBuffer()),
-    CurrentPreprocessor(0), Diags(0), SourceMgr(0), NumErrors(0) {
+VerifyDiagnosticsClient::VerifyDiagnosticsClient(Diagnostic &_Diags,
+                                                 DiagnosticClient *_Primary)
+  : Diags(_Diags), PrimaryClient(_Primary),
+    Buffer(new TextDiagnosticBuffer()), CurrentPreprocessor(0), NumErrors(0) {
 }
 
 VerifyDiagnosticsClient::~VerifyDiagnosticsClient() {
@@ -36,14 +37,6 @@
   // because it doesn't get reused. It would be better if we could make a copy
   // though.
   CurrentPreprocessor = const_cast<Preprocessor*>(PP);
-  
-  // FIXME: HACK. Remember the source manager, and just expect that its lifetime
-  // exceeds when we need it.
-  SourceMgr = PP ? &PP->getSourceManager() : 0;
-
-  // FIXME: HACK. Remember the diagnostic engine, and just expect that its
-  // lifetime exceeds when we need it.
-  Diags = PP ? &PP->getDiagnostics() : 0;
 
   PrimaryClient->BeginSourceFile(LangOpts, PP);
 }
@@ -55,7 +48,7 @@
 
   CurrentPreprocessor = 0;
 }
-                               
+
 void VerifyDiagnosticsClient::HandleDiagnostic(Diagnostic::Level DiagLevel,
                                               const DiagnosticInfo &Info) {
   // Send the diagnostic to the buffer, we will check it once we reach the end
@@ -209,7 +202,7 @@
 /// happened. Print the map out in a nice format and return "true". If the map
 /// is empty and we're not going to print things, then return "false".
 ///
-static unsigned PrintProblem(Diagnostic &Diags, SourceManager &SourceMgr,
+static unsigned PrintProblem(Diagnostic &Diags, SourceManager *SourceMgr,
                              const_diag_iterator diag_begin,
                              const_diag_iterator diag_end,
                              const char *Kind, bool Expected) {
@@ -218,15 +211,15 @@
   llvm::SmallString<256> Fmt;
   llvm::raw_svector_ostream OS(Fmt);
   for (const_diag_iterator I = diag_begin, E = diag_end; I != E; ++I) {
-    if (I->first.isInvalid())
+    if (I->first.isInvalid() || !SourceMgr)
       OS << "\n  (frontend)";
     else
-      OS << "\n  Line " << SourceMgr.getInstantiationLineNumber(I->first);
+      OS << "\n  Line " << SourceMgr->getInstantiationLineNumber(I->first);
     OS << ": " << I->second;
   }
 
   Diags.Report(diag::err_verify_inconsistent_diags)
-    << Kind << Expected << OS.str();
+    << Kind << !Expected << OS.str();
   return std::distance(diag_begin, diag_end);
 }
 
@@ -269,10 +262,10 @@
   }
   // Now all that's left in Right are those that were not matched.
 
-  return (PrintProblem(Diags, SourceMgr,
-                      LeftOnly.begin(), LeftOnly.end(), Label, false) +
-          PrintProblem(Diags, SourceMgr,
-                       Right.begin(), Right.end(), Label, true));
+  return (PrintProblem(Diags, &SourceMgr,
+                      LeftOnly.begin(), LeftOnly.end(), Label, true) +
+          PrintProblem(Diags, &SourceMgr,
+                       Right.begin(), Right.end(), Label, false));
 }
 
 /// CheckResults - This compares the expected results to those that
@@ -296,7 +289,7 @@
                                   ExpectedErrors.begin(), ExpectedErrors.end(),
                                   Buffer.err_begin(), Buffer.err_end(),
                                   "error");
-  
+
   // See if there are warning mismatches.
   NumProblems += CompareDiagLists(Diags, SourceMgr,
                                   ExpectedWarnings.begin(),
@@ -319,21 +312,32 @@
   DiagList ExpectedErrors, ExpectedWarnings, ExpectedNotes;
 
   // Ensure any diagnostics go to the primary client.
-  DiagnosticClient *CurClient = Diags->getClient();
-  Diags->setClient(PrimaryClient.get());
+  DiagnosticClient *CurClient = Diags.getClient();
+  Diags.setClient(PrimaryClient.get());
 
   // If we have a preprocessor, scan the source for expected diagnostic
   // markers. If not then any diagnostics are unexpected.
   if (CurrentPreprocessor) {
     FindExpectedDiags(*CurrentPreprocessor, ExpectedErrors, ExpectedWarnings,
                       ExpectedNotes);
+
+    // Check that the expected diagnostics occurred.
+    NumErrors += CheckResults(Diags, CurrentPreprocessor->getSourceManager(),
+                              *Buffer,
+                              ExpectedErrors, ExpectedWarnings, ExpectedNotes);
+  } else {
+    NumErrors += (PrintProblem(Diags, 0,
+                               Buffer->err_begin(), Buffer->err_end(),
+                               "error", false) +
+                  PrintProblem(Diags, 0,
+                               Buffer->warn_begin(), Buffer->warn_end(),
+                               "warn", false) +
+                  PrintProblem(Diags, 0,
+                               Buffer->note_begin(), Buffer->note_end(),
+                               "note", false));
   }
 
-  // Check that the expected diagnostics occurred.
-  NumErrors += CheckResults(*Diags, *SourceMgr, *Buffer,
-                            ExpectedErrors, ExpectedWarnings, ExpectedNotes);
-
-  Diags->setClient(CurClient);
+  Diags.setClient(CurClient);
 
   // Reset the buffer, we have processed all the diagnostics in it.
   Buffer.reset(new TextDiagnosticBuffer());