Refactored driver so that any action that is implemented using an
ASTConsumer can also be verified using the diagnostics checker.  From
the command line, users may activate diagnostic checking using the
"-verify" option.  For example, "clang -verify -warn-dead-stores"
checks if the warnings flagged by the dead store checker match those
in the comments.

Note that we still have the option "-parse-ast-check" for backwards
comptability with existing test cases.  This option is now equivalent to 
"-parse-ast -verify".


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@42362 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/Driver/clang.cpp b/Driver/clang.cpp
index 6ff5580..630ab07 100644
--- a/Driver/clang.cpp
+++ b/Driver/clang.cpp
@@ -103,8 +103,6 @@
                         "Print results of live variable analysis."),
              clEnumValN(WarnDeadStores, "warn-dead-stores",
                         "Flag warnings of stores to dead variables."),
-             clEnumValN(WarnDeadStoresCheck, "warn-dead-stores-check",
-                        "Check diagnostics emitted by --warn-dead-stores."),
              clEnumValN(WarnUninitVals, "warn-uninit-values",
                         "Flag warnings of uses of unitialized variables."),
              clEnumValN(EmitLLVM, "emit-llvm",
@@ -348,6 +346,9 @@
 WarnUnusedMacros("Wunused_macros",
          llvm::cl::desc("Warn for unused macros in the main translation unit"));
 
+static llvm::cl::opt<bool>
+VerifyDiagnostics("verify",
+                  llvm::cl::desc("Verify emitted diagnostics and warnings."));
 
 /// InitializeDiagnostics - Initialize the diagnostic object, based on the
 /// current command line option settings.
@@ -805,7 +806,11 @@
                              TextDiagnostics &OurDiagnosticClient,
                              HeaderSearch &HeaderInfo,
                              const LangOptions &LangInfo) {
+
+  ASTConsumer* Consumer = NULL;
   bool ClearSourceMgr = false;
+  bool PerformDiagnosticsCheck = VerifyDiagnostics;
+  
   switch (ProgAction) {
   default:
     fprintf(stderr, "Unexpected program action!\n");
@@ -847,62 +852,55 @@
     ParseFile(PP, CreatePrintParserActionsAction(), MainFileID);
     ClearSourceMgr = true;
     break;
-  case ParseSyntaxOnly:              // -fsyntax-only
-  case BuildAST: {
-    ASTConsumer NullConsumer;
-    ParseAST(PP, MainFileID, NullConsumer, Stats);
-    break;
-  }
-  case ParseASTPrint: {
-    std::auto_ptr<ASTConsumer> C(CreateASTPrinter());
-    ParseAST(PP, MainFileID, *C.get(), Stats);
-    break;
-  }
-  case ParseASTDump: {
-    std::auto_ptr<ASTConsumer> C(CreateASTDumper());
-    ParseAST(PP, MainFileID, *C.get(), Stats);
-    break;
-  }
-  case ParseASTView: {
-    std::auto_ptr<ASTConsumer> C(CreateASTViewer());
-    ParseAST(PP, MainFileID, *C.get(), Stats);
-    break;
-  }
-  case ParseCFGDump:
-  case ParseCFGView: {
-    std::auto_ptr<ASTConsumer> C(CreateCFGDumper(ProgAction == ParseCFGView));
-    ParseAST(PP, MainFileID, *C.get(), Stats);
-    break;
-  }
-  case AnalysisLiveVariables: {
-    std::auto_ptr<ASTConsumer> C(CreateLiveVarAnalyzer());
-    ParseAST(PP, MainFileID, *C.get(), Stats);
-    break;
-  }
-  case WarnDeadStores: {
-    std::auto_ptr<ASTConsumer> C(CreateDeadStoreChecker(PP.getDiagnostics()));
-    ParseAST(PP, MainFileID, *C.get(), Stats);
-    break;
-  }
-  case WarnDeadStoresCheck: {
-    std::auto_ptr<ASTConsumer> C(CreateDeadStoreChecker(PP.getDiagnostics()));
-    exit (CheckASTConsumer(PP, MainFileID, C));
-    break;
-  }
       
-  case WarnUninitVals: {
-    std::auto_ptr<ASTConsumer> C(CreateUnitValsChecker(PP.getDiagnostics()));
-    ParseAST(PP, MainFileID, *C.get(), Stats);
+  case ParseASTCheck:
+    PerformDiagnosticsCheck = true;
+  case ParseSyntaxOnly:              // -fsyntax-only
+  case BuildAST:
+    Consumer = new ASTConsumer();
     break;
-  }    
-  case EmitLLVM: {
-    std::auto_ptr<ASTConsumer> C(CreateLLVMEmitter(PP.getDiagnostics()));
-    ParseAST(PP, MainFileID, *C.get(), Stats);
+
+  case ParseASTPrint:
+    Consumer = CreateASTPrinter();
+    break;
+
+  case ParseASTDump:
+    Consumer = CreateASTDumper();
+    break;
+
+  case ParseASTView:
+    Consumer = CreateASTViewer();      
+    break;
+
+  case ParseCFGDump:
+  case ParseCFGView:
+    Consumer = CreateCFGDumper(ProgAction == ParseCFGView);
+    break;
+      
+  case AnalysisLiveVariables:
+    Consumer = CreateLiveVarAnalyzer();
+    break;
+
+  case WarnDeadStores:    
+    Consumer = CreateDeadStoreChecker(PP.getDiagnostics());
+    break;
+      
+  case WarnUninitVals:
+    Consumer = CreateUnitValsChecker(PP.getDiagnostics());
+    break;
+
+  case EmitLLVM:
+    Consumer = CreateLLVMEmitter(PP.getDiagnostics());
     break;
   }
-  case ParseASTCheck:
-    exit(CheckDiagnostics(PP, MainFileID));
-    break;
+  
+  if (Consumer) {
+    if (PerformDiagnosticsCheck)
+      exit (CheckASTConsumer(PP, MainFileID, Consumer));
+    else
+      ParseAST(PP, MainFileID, *Consumer, Stats);
+
+    delete Consumer;
   }
   
   if (Stats) {