Make DiagnosticOptions intrusively reference-counted, and make sure
the various stakeholders bump up the reference count. In particular,
the diagnostics engine now keeps the DiagnosticOptions object alive.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@166508 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/tools/arcmt-test/arcmt-test.cpp b/tools/arcmt-test/arcmt-test.cpp
index 3983c24..b745893 100644
--- a/tools/arcmt-test/arcmt-test.cpp
+++ b/tools/arcmt-test/arcmt-test.cpp
@@ -105,11 +105,12 @@
 
 static bool checkForMigration(StringRef resourcesPath,
                               ArrayRef<const char *> Args) {
+  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
   DiagnosticConsumer *DiagClient =
-    new TextDiagnosticPrinter(llvm::errs(), DiagnosticOptions());
+    new TextDiagnosticPrinter(llvm::errs(), &*DiagOpts);
   IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
   IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
-      new DiagnosticsEngine(DiagID, DiagClient));
+      new DiagnosticsEngine(DiagID, &*DiagOpts, DiagClient));
   // Chain in -verify checker, if requested.
   VerifyDiagnosticConsumer *verifyDiag = 0;
   if (VerifyDiags) {
@@ -150,11 +151,12 @@
   if (checkForMigration(resourcesPath, Args))
     return true;
 
+  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
   DiagnosticConsumer *DiagClient =
-    new TextDiagnosticPrinter(llvm::errs(), DiagnosticOptions());
+    new TextDiagnosticPrinter(llvm::errs(), &*DiagOpts);
   IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
   IntrusiveRefCntPtr<DiagnosticsEngine> TopDiags(
-      new DiagnosticsEngine(DiagID, DiagClient));
+      new DiagnosticsEngine(DiagID, &*DiagOpts, &*DiagClient));
 
   CompilerInvocation origCI;
   if (!CompilerInvocation::CreateFromArgs(origCI, Args.begin(), Args.end(),
diff --git a/tools/diagtool/ShowEnabledWarnings.cpp b/tools/diagtool/ShowEnabledWarnings.cpp
index 7162451..abd69fd 100644
--- a/tools/diagtool/ShowEnabledWarnings.cpp
+++ b/tools/diagtool/ShowEnabledWarnings.cpp
@@ -60,7 +60,7 @@
   // well formed diagnostic object.
   TextDiagnosticBuffer *DiagsBuffer = new TextDiagnosticBuffer;
   IntrusiveRefCntPtr<DiagnosticsEngine> InterimDiags(
-    new DiagnosticsEngine(DiagIDs, DiagsBuffer));
+    new DiagnosticsEngine(DiagIDs, new DiagnosticOptions(), DiagsBuffer));
 
   // Try to build a CompilerInvocation.
   OwningPtr<CompilerInvocation> Invocation(
@@ -71,7 +71,7 @@
 
   // Build the diagnostics parser
   IntrusiveRefCntPtr<DiagnosticsEngine> FinalDiags =
-    CompilerInstance::createDiagnostics(Invocation->getDiagnosticOpts(),
+    CompilerInstance::createDiagnostics(&Invocation->getDiagnosticOpts(),
                                         argc, argv);
   if (!FinalDiags)
     return NULL;
diff --git a/tools/diagtool/TreeView.cpp b/tools/diagtool/TreeView.cpp
index aee7554..bf9f766 100644
--- a/tools/diagtool/TreeView.cpp
+++ b/tools/diagtool/TreeView.cpp
@@ -14,6 +14,7 @@
 #include "DiagTool.h"
 #include "DiagnosticNames.h"
 #include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/DiagnosticOptions.h"
 #include "llvm/Support/Format.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/DenseSet.h"
@@ -50,7 +51,9 @@
 }
 
 static clang::DiagnosticsEngine::Level getLevel(unsigned DiagID) {
-  static clang::DiagnosticsEngine Diags(new DiagnosticIDs);
+  // FIXME: This feels like a hack.
+  static clang::DiagnosticsEngine Diags(new DiagnosticIDs,
+                                        new DiagnosticOptions);
   return Diags.getDiagnosticLevel(DiagID, SourceLocation());
 }
 
diff --git a/tools/driver/cc1_main.cpp b/tools/driver/cc1_main.cpp
index f8e8a6b..5ad7e00 100644
--- a/tools/driver/cc1_main.cpp
+++ b/tools/driver/cc1_main.cpp
@@ -122,8 +122,10 @@
 
   // Run clang -cc1 test.
   if (ArgBegin != ArgEnd && StringRef(ArgBegin[0]) == "-cc1test") {
-    DiagnosticsEngine Diags(DiagID, new TextDiagnosticPrinter(llvm::errs(), 
-                                                       DiagnosticOptions()));
+    IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
+    DiagnosticsEngine Diags(DiagID, &*DiagOpts,
+                            new TextDiagnosticPrinter(llvm::errs(),
+                                                      &*DiagOpts));
     return cc1_test(Diags, ArgBegin + 1, ArgEnd);
   }
 
@@ -135,8 +137,9 @@
 
   // Buffer diagnostics from argument parsing so that we can output them using a
   // well formed diagnostic object.
+  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
   TextDiagnosticBuffer *DiagsBuffer = new TextDiagnosticBuffer;
-  DiagnosticsEngine Diags(DiagID, DiagsBuffer);
+  DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagsBuffer);
   bool Success;
   Success = CompilerInvocation::CreateFromArgs(Clang->getInvocation(),
                                                ArgBegin, ArgEnd, Diags);
diff --git a/tools/driver/cc1as_main.cpp b/tools/driver/cc1as_main.cpp
index 8bd1e94..c8f7006 100644
--- a/tools/driver/cc1as_main.cpp
+++ b/tools/driver/cc1as_main.cpp
@@ -19,9 +19,9 @@
 #include "clang/Driver/CC1AsOptions.h"
 #include "clang/Driver/OptTable.h"
 #include "clang/Driver/Options.h"
-#include "clang/Frontend/DiagnosticOptions.h"
 #include "clang/Frontend/FrontendDiagnostic.h"
 #include "clang/Frontend/TextDiagnosticPrinter.h"
+#include "clang/Basic/DiagnosticOptions.h"
 #include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/ADT/Triple.h"
@@ -394,11 +394,12 @@
   InitializeAllAsmParsers();
 
   // Construct our diagnostic client.
+  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
   TextDiagnosticPrinter *DiagClient
-    = new TextDiagnosticPrinter(errs(), DiagnosticOptions());
+    = new TextDiagnosticPrinter(errs(), &*DiagOpts);
   DiagClient->setPrefix("clang -cc1as");
   IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
-  DiagnosticsEngine Diags(DiagID, DiagClient);
+  DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagClient);
 
   // Set an error handler, so that any LLVM backend diagnostics go through our
   // error handler.
diff --git a/tools/driver/driver.cpp b/tools/driver/driver.cpp
index 12a9329..81979ec 100644
--- a/tools/driver/driver.cpp
+++ b/tools/driver/driver.cpp
@@ -12,6 +12,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Driver/ArgList.h"
 #include "clang/Driver/Options.h"
 #include "clang/Driver/Compilation.h"
@@ -19,7 +20,6 @@
 #include "clang/Driver/Option.h"
 #include "clang/Driver/OptTable.h"
 #include "clang/Frontend/CompilerInvocation.h"
-#include "clang/Frontend/DiagnosticOptions.h"
 #include "clang/Frontend/TextDiagnosticPrinter.h"
 #include "clang/Frontend/Utils.h"
 
@@ -375,7 +375,7 @@
 
   llvm::sys::Path Path = GetExecutablePath(argv[0], CanonicalPrefixes);
 
-  DiagnosticOptions DiagOpts;
+  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions;
   {
     // Note that ParseDiagnosticArgs() uses the cc1 option table.
     OwningPtr<OptTable> CC1Opts(createDriverOptTable());
@@ -385,17 +385,17 @@
     // We ignore MissingArgCount and the return value of ParseDiagnosticArgs.
     // Any errors that would be diagnosed here will also be diagnosed later,
     // when the DiagnosticsEngine actually exists.
-    (void) ParseDiagnosticArgs(DiagOpts, *Args);
+    (void) ParseDiagnosticArgs(*DiagOpts, *Args);
   }
   // Now we can create the DiagnosticsEngine with a properly-filled-out
   // DiagnosticOptions instance.
   TextDiagnosticPrinter *DiagClient
-    = new TextDiagnosticPrinter(llvm::errs(), DiagOpts);
+    = new TextDiagnosticPrinter(llvm::errs(), &*DiagOpts);
   DiagClient->setPrefix(llvm::sys::path::stem(Path.str()));
   IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
 
-  DiagnosticsEngine Diags(DiagID, DiagClient);
-  ProcessWarningOptions(Diags, DiagOpts);
+  DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagClient);
+  ProcessWarningOptions(Diags, *DiagOpts);
 
 #ifdef CLANG_IS_PRODUCTION
   const bool IsProduction = true;
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp
index f3c91e3..3a6c408 100644
--- a/tools/libclang/CIndex.cpp
+++ b/tools/libclang/CIndex.cpp
@@ -2559,10 +2559,10 @@
   bool ForSerialization = options & CXTranslationUnit_ForSerialization;
 
   // Configure the diagnostics.
-  DiagnosticOptions DiagOpts;
   IntrusiveRefCntPtr<DiagnosticsEngine>
-    Diags(CompilerInstance::createDiagnostics(DiagOpts, num_command_line_args, 
-                                                command_line_args));
+    Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions,
+                                              num_command_line_args,
+                                              command_line_args));
 
   // Recover resources if we crash before exiting this function.
   llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
diff --git a/tools/libclang/CIndexCodeCompletion.cpp b/tools/libclang/CIndexCodeCompletion.cpp
index 2676b53..46af661 100644
--- a/tools/libclang/CIndexCodeCompletion.cpp
+++ b/tools/libclang/CIndexCodeCompletion.cpp
@@ -246,6 +246,8 @@
   /// \brief Diagnostics produced while performing code completion.
   SmallVector<StoredDiagnostic, 8> Diagnostics;
 
+  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
+  
   /// \brief Diag object
   IntrusiveRefCntPtr<DiagnosticsEngine> Diag;
   
@@ -305,8 +307,10 @@
 AllocatedCXCodeCompleteResults::AllocatedCXCodeCompleteResults(
                                       const FileSystemOptions& FileSystemOpts)
   : CXCodeCompleteResults(),
+    DiagOpts(new DiagnosticOptions),
     Diag(new DiagnosticsEngine(
-                   IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs))),
+                   IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),
+                   &*DiagOpts)),
     FileSystemOpts(FileSystemOpts),
     FileMgr(new FileManager(FileSystemOpts)),
     SourceMgr(new SourceManager(*Diag, *FileMgr)),
diff --git a/tools/libclang/CIndexDiagnostic.cpp b/tools/libclang/CIndexDiagnostic.cpp
index 14722e0..3154480 100644
--- a/tools/libclang/CIndexDiagnostic.cpp
+++ b/tools/libclang/CIndexDiagnostic.cpp
@@ -19,7 +19,7 @@
 #include "clang/Frontend/ASTUnit.h"
 #include "clang/Frontend/FrontendDiagnostic.h"
 #include "clang/Frontend/DiagnosticRenderer.h"
-#include "clang/Frontend/DiagnosticOptions.h"
+#include "clang/Basic/DiagnosticOptions.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/Twine.h"
 #include "llvm/Support/MemoryBuffer.h"
@@ -87,7 +87,7 @@
 class CXDiagnosticRenderer : public DiagnosticNoteRenderer {
 public:  
   CXDiagnosticRenderer(const LangOptions &LangOpts,
-                       const DiagnosticOptions &DiagOpts,
+                       DiagnosticOptions *DiagOpts,
                        CXDiagnosticSetImpl *mainSet)
   : DiagnosticNoteRenderer(LangOpts, DiagOpts),
     CurrentSet(mainSet), MainSet(mainSet) {}
@@ -191,9 +191,9 @@
   if (!TU->Diagnostics) {
     CXDiagnosticSetImpl *Set = new CXDiagnosticSetImpl();
     TU->Diagnostics = Set;
-    DiagnosticOptions DOpts;
+    llvm::IntrusiveRefCntPtr<DiagnosticOptions> DOpts = new DiagnosticOptions;
     CXDiagnosticRenderer Renderer(AU->getASTContext().getLangOpts(),
-                                  DOpts, Set);
+                                  &*DOpts, Set);
     
     for (ASTUnit::stored_diag_iterator it = AU->stored_diag_begin(),
          ei = AU->stored_diag_end(); it != ei; ++it) {
diff --git a/tools/libclang/Indexing.cpp b/tools/libclang/Indexing.cpp
index 36442fa..714a36e 100644
--- a/tools/libclang/Indexing.cpp
+++ b/tools/libclang/Indexing.cpp
@@ -290,13 +290,13 @@
   CaptureDiagnosticConsumer *CaptureDiag = new CaptureDiagnosticConsumer();
 
   // Configure the diagnostics.
-  DiagnosticOptions DiagOpts;
   IntrusiveRefCntPtr<DiagnosticsEngine>
-    Diags(CompilerInstance::createDiagnostics(DiagOpts, num_command_line_args, 
-                                                command_line_args,
-                                                CaptureDiag,
-                                                /*ShouldOwnClient=*/true,
-                                                /*ShouldCloneClient=*/false));
+    Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions,
+                                              num_command_line_args,
+                                              command_line_args,
+                                              CaptureDiag,
+                                              /*ShouldOwnClient=*/true,
+                                              /*ShouldCloneClient=*/false));
 
   // Recover resources if we crash before exiting this function.
   llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,