[clang] [clang-tools-extra] [lldb] [clang] Remove intrusive reference count from `DiagnosticOptions` (PR #139584)

Jan Svoboda via cfe-commits cfe-commits at lists.llvm.org
Tue May 20 11:04:11 PDT 2025


https://github.com/jansvoboda11 updated https://github.com/llvm/llvm-project/pull/139584

>From 858846b9c9a8c05f5f3dcc86a2747921238ea23f Mon Sep 17 00:00:00 2001
From: Jan Svoboda <jan_svoboda at apple.com>
Date: Fri, 9 May 2025 16:39:16 -0700
Subject: [PATCH 1/8] Make clang build

---
 clang/include/clang/Basic/Diagnostic.h        |  6 +-
 clang/include/clang/Basic/DiagnosticOptions.h |  4 +-
 clang/include/clang/Basic/SourceManager.h     |  1 +
 .../include/clang/Frontend/CompilerInstance.h |  2 +-
 .../clang/Frontend/CompilerInvocation.h       |  2 +-
 .../clang/Frontend/DiagnosticRenderer.h       |  6 +-
 .../clang/Frontend/LogDiagnosticPrinter.h     |  4 +-
 .../include/clang/Frontend/SARIFDiagnostic.h  |  2 +-
 .../clang/Frontend/SARIFDiagnosticPrinter.h   |  4 +-
 .../Frontend/SerializedDiagnosticPrinter.h    |  2 +-
 clang/include/clang/Frontend/TextDiagnostic.h |  2 +-
 .../clang/Frontend/TextDiagnosticPrinter.h    |  4 +-
 clang/include/clang/Serialization/ASTReader.h |  9 +--
 clang/lib/Basic/Diagnostic.cpp                | 10 +--
 clang/lib/Basic/SourceManager.cpp             |  4 +-
 clang/lib/CrossTU/CrossTranslationUnit.cpp    |  9 +--
 clang/lib/Frontend/ASTMerge.cpp               |  2 +-
 clang/lib/Frontend/ChainedIncludesSource.cpp  |  4 +-
 clang/lib/Frontend/CompilerInstance.cpp       | 26 +++----
 clang/lib/Frontend/CompilerInvocation.cpp     | 27 ++-----
 .../CreateInvocationFromCommandLine.cpp       | 14 ++--
 clang/lib/Frontend/DiagnosticRenderer.cpp     | 14 ++--
 clang/lib/Frontend/FrontendAction.cpp         |  2 +-
 clang/lib/Frontend/FrontendActions.cpp        | 12 +--
 clang/lib/Frontend/LogDiagnosticPrinter.cpp   |  4 +-
 clang/lib/Frontend/SARIFDiagnostic.cpp        |  4 +-
 clang/lib/Frontend/SARIFDiagnosticPrinter.cpp |  7 +-
 .../Frontend/SerializedDiagnosticPrinter.cpp  | 20 ++---
 clang/lib/Frontend/TextDiagnostic.cpp         | 74 +++++++++----------
 clang/lib/Frontend/TextDiagnosticPrinter.cpp  | 13 ++--
 clang/lib/Rewrite/HTMLRewrite.cpp             |  4 +-
 clang/lib/Serialization/ASTReader.cpp         | 22 +++---
 clang/lib/Tooling/Core/Replacement.cpp        |  4 +-
 clang/tools/driver/cc1_main.cpp               |  4 +-
 clang/tools/driver/cc1as_main.cpp             |  6 +-
 clang/tools/driver/cc1gen_reproducer_main.cpp |  6 +-
 clang/tools/driver/driver.cpp                 |  9 +--
 37 files changed, 167 insertions(+), 182 deletions(-)

diff --git a/clang/include/clang/Basic/Diagnostic.h b/clang/include/clang/Basic/Diagnostic.h
index 0ba4edcc5d54c..1e90263e2f2f6 100644
--- a/clang/include/clang/Basic/Diagnostic.h
+++ b/clang/include/clang/Basic/Diagnostic.h
@@ -333,7 +333,7 @@ class DiagnosticsEngine : public RefCountedBase<DiagnosticsEngine> {
   unsigned ConstexprBacktraceLimit = 0;
 
   IntrusiveRefCntPtr<DiagnosticIDs> Diags;
-  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
+  DiagnosticOptions &DiagOpts;
   DiagnosticConsumer *Client = nullptr;
   std::unique_ptr<DiagnosticConsumer> Owner;
   SourceManager *SourceMgr = nullptr;
@@ -571,7 +571,7 @@ class DiagnosticsEngine : public RefCountedBase<DiagnosticsEngine> {
 
 public:
   explicit DiagnosticsEngine(IntrusiveRefCntPtr<DiagnosticIDs> Diags,
-                             IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts,
+                             DiagnosticOptions &DiagOpts,
                              DiagnosticConsumer *client = nullptr,
                              bool ShouldOwnClient = true);
   DiagnosticsEngine(const DiagnosticsEngine &) = delete;
@@ -587,7 +587,7 @@ class DiagnosticsEngine : public RefCountedBase<DiagnosticsEngine> {
   }
 
   /// Retrieve the diagnostic options.
-  DiagnosticOptions &getDiagnosticOptions() const { return *DiagOpts; }
+  DiagnosticOptions &getDiagnosticOptions() const { return DiagOpts; }
 
   using diag_mapping_range = llvm::iterator_range<DiagState::const_iterator>;
 
diff --git a/clang/include/clang/Basic/DiagnosticOptions.h b/clang/include/clang/Basic/DiagnosticOptions.h
index 29146532f9524..a230022224de5 100644
--- a/clang/include/clang/Basic/DiagnosticOptions.h
+++ b/clang/include/clang/Basic/DiagnosticOptions.h
@@ -10,7 +10,6 @@
 #define LLVM_CLANG_BASIC_DIAGNOSTICOPTIONS_H
 
 #include "clang/Basic/LLVM.h"
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
 #include <string>
 #include <type_traits>
 #include <vector>
@@ -67,8 +66,7 @@ inline DiagnosticLevelMask operator&(DiagnosticLevelMask LHS,
 raw_ostream& operator<<(raw_ostream& Out, DiagnosticLevelMask M);
 
 /// Options for controlling the compiler diagnostics engine.
-class DiagnosticOptions
-    : public llvm::ThreadSafeRefCountedBase<DiagnosticOptions> {
+class DiagnosticOptions {
   friend bool ParseDiagnosticArgs(DiagnosticOptions &, llvm::opt::ArgList &,
                                   clang::DiagnosticsEngine *, bool);
 
diff --git a/clang/include/clang/Basic/SourceManager.h b/clang/include/clang/Basic/SourceManager.h
index e0f1ea435d54e..07e36aef9745f 100644
--- a/clang/include/clang/Basic/SourceManager.h
+++ b/clang/include/clang/Basic/SourceManager.h
@@ -2032,6 +2032,7 @@ class SourceManagerForFile {
   // as they are created in `createSourceManagerForFile` so that they can be
   // deleted in the reverse order as they are created.
   std::unique_ptr<FileManager> FileMgr;
+  std::unique_ptr<DiagnosticOptions> DiagOpts;
   std::unique_ptr<DiagnosticsEngine> Diagnostics;
   std::unique_ptr<SourceManager> SourceMgr;
 };
diff --git a/clang/include/clang/Frontend/CompilerInstance.h b/clang/include/clang/Frontend/CompilerInstance.h
index 5f25a932c5052..0ae490f0e8073 100644
--- a/clang/include/clang/Frontend/CompilerInstance.h
+++ b/clang/include/clang/Frontend/CompilerInstance.h
@@ -674,7 +674,7 @@ class CompilerInstance : public ModuleLoader {
   ///
   /// \return The new object on success, or null on failure.
   static IntrusiveRefCntPtr<DiagnosticsEngine>
-  createDiagnostics(llvm::vfs::FileSystem &VFS, DiagnosticOptions *Opts,
+  createDiagnostics(llvm::vfs::FileSystem &VFS, DiagnosticOptions &Opts,
                     DiagnosticConsumer *Client = nullptr,
                     bool ShouldOwnClient = true,
                     const CodeGenOptions *CodeGenOpts = nullptr);
diff --git a/clang/include/clang/Frontend/CompilerInvocation.h b/clang/include/clang/Frontend/CompilerInvocation.h
index 3ca900729b4a8..e147d2ba6087e 100644
--- a/clang/include/clang/Frontend/CompilerInvocation.h
+++ b/clang/include/clang/Frontend/CompilerInvocation.h
@@ -80,7 +80,7 @@ class CompilerInvocationBase {
   std::shared_ptr<TargetOptions> TargetOpts;
 
   /// Options controlling the diagnostic engine.
-  IntrusiveRefCntPtr<DiagnosticOptions> DiagnosticOpts;
+  std::shared_ptr<DiagnosticOptions> DiagnosticOpts;
 
   /// Options controlling the \#include directive.
   std::shared_ptr<HeaderSearchOptions> HSOpts;
diff --git a/clang/include/clang/Frontend/DiagnosticRenderer.h b/clang/include/clang/Frontend/DiagnosticRenderer.h
index b939ebe979e71..4c65692399490 100644
--- a/clang/include/clang/Frontend/DiagnosticRenderer.h
+++ b/clang/include/clang/Frontend/DiagnosticRenderer.h
@@ -47,7 +47,7 @@ using DiagOrStoredDiag =
 class DiagnosticRenderer {
 protected:
   const LangOptions &LangOpts;
-  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
+  DiagnosticOptions &DiagOpts;
 
   /// The location of the previous diagnostic if known.
   ///
@@ -69,7 +69,7 @@ class DiagnosticRenderer {
   DiagnosticsEngine::Level LastLevel = DiagnosticsEngine::Ignored;
 
   DiagnosticRenderer(const LangOptions &LangOpts,
-                     DiagnosticOptions *DiagOpts);
+                     DiagnosticOptions &DiagOpts);
 
   virtual ~DiagnosticRenderer();
 
@@ -142,7 +142,7 @@ class DiagnosticRenderer {
 class DiagnosticNoteRenderer : public DiagnosticRenderer {
 public:
   DiagnosticNoteRenderer(const LangOptions &LangOpts,
-                         DiagnosticOptions *DiagOpts)
+                         DiagnosticOptions &DiagOpts)
       : DiagnosticRenderer(LangOpts, DiagOpts) {}
 
   ~DiagnosticNoteRenderer() override;
diff --git a/clang/include/clang/Frontend/LogDiagnosticPrinter.h b/clang/include/clang/Frontend/LogDiagnosticPrinter.h
index ec22a8b6cc5fb..b43b0da13967a 100644
--- a/clang/include/clang/Frontend/LogDiagnosticPrinter.h
+++ b/clang/include/clang/Frontend/LogDiagnosticPrinter.h
@@ -51,7 +51,7 @@ class LogDiagnosticPrinter : public DiagnosticConsumer {
   raw_ostream &OS;
   std::unique_ptr<raw_ostream> StreamOwner;
   const LangOptions *LangOpts;
-  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
+  DiagnosticOptions &DiagOpts;
 
   SourceLocation LastWarningLoc;
   FullSourceLoc LastLoc;
@@ -62,7 +62,7 @@ class LogDiagnosticPrinter : public DiagnosticConsumer {
   std::string DwarfDebugFlags;
 
 public:
-  LogDiagnosticPrinter(raw_ostream &OS, DiagnosticOptions *Diags,
+  LogDiagnosticPrinter(raw_ostream &OS, DiagnosticOptions &DiagOpts,
                        std::unique_ptr<raw_ostream> StreamOwner);
 
   void setDwarfDebugFlags(StringRef Value) {
diff --git a/clang/include/clang/Frontend/SARIFDiagnostic.h b/clang/include/clang/Frontend/SARIFDiagnostic.h
index ec1d0b8e6a7c9..780f36c874109 100644
--- a/clang/include/clang/Frontend/SARIFDiagnostic.h
+++ b/clang/include/clang/Frontend/SARIFDiagnostic.h
@@ -23,7 +23,7 @@ namespace clang {
 class SARIFDiagnostic : public DiagnosticRenderer {
 public:
   SARIFDiagnostic(raw_ostream &OS, const LangOptions &LangOpts,
-                  DiagnosticOptions *DiagOpts, SarifDocumentWriter *Writer);
+                  DiagnosticOptions &DiagOpts, SarifDocumentWriter *Writer);
 
   ~SARIFDiagnostic() = default;
 
diff --git a/clang/include/clang/Frontend/SARIFDiagnosticPrinter.h b/clang/include/clang/Frontend/SARIFDiagnosticPrinter.h
index f2652833b3c18..3406ed16c2fba 100644
--- a/clang/include/clang/Frontend/SARIFDiagnosticPrinter.h
+++ b/clang/include/clang/Frontend/SARIFDiagnosticPrinter.h
@@ -29,7 +29,7 @@ class SarifDocumentWriter;
 
 class SARIFDiagnosticPrinter : public DiagnosticConsumer {
 public:
-  SARIFDiagnosticPrinter(raw_ostream &OS, DiagnosticOptions *Diags);
+  SARIFDiagnosticPrinter(raw_ostream &OS, DiagnosticOptions &DiagOpts);
   ~SARIFDiagnosticPrinter() = default;
 
   SARIFDiagnosticPrinter &operator=(const SARIFDiagnosticPrinter &&) = delete;
@@ -60,7 +60,7 @@ class SARIFDiagnosticPrinter : public DiagnosticConsumer {
 
 private:
   raw_ostream &OS;
-  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
+  DiagnosticOptions &DiagOpts;
 
   /// Handle to the currently active SARIF diagnostic emitter.
   std::unique_ptr<SARIFDiagnostic> SARIFDiag;
diff --git a/clang/include/clang/Frontend/SerializedDiagnosticPrinter.h b/clang/include/clang/Frontend/SerializedDiagnosticPrinter.h
index 5586ef65e393f..2b6d2e4477d58 100644
--- a/clang/include/clang/Frontend/SerializedDiagnosticPrinter.h
+++ b/clang/include/clang/Frontend/SerializedDiagnosticPrinter.h
@@ -32,7 +32,7 @@ namespace serialized_diags {
 /// (via libclang) without needing to parse Clang's command line output.
 ///
 std::unique_ptr<DiagnosticConsumer> create(StringRef OutputFile,
-                                           DiagnosticOptions *Diags,
+                                           DiagnosticOptions &DiagOpts,
                                            bool MergeChildRecords = false);
 
 } // end serialized_diags namespace
diff --git a/clang/include/clang/Frontend/TextDiagnostic.h b/clang/include/clang/Frontend/TextDiagnostic.h
index a2fe8ae995423..e2e88d4d648a2 100644
--- a/clang/include/clang/Frontend/TextDiagnostic.h
+++ b/clang/include/clang/Frontend/TextDiagnostic.h
@@ -38,7 +38,7 @@ class TextDiagnostic : public DiagnosticRenderer {
 
 public:
   TextDiagnostic(raw_ostream &OS, const LangOptions &LangOpts,
-                 DiagnosticOptions *DiagOpts, const Preprocessor *PP = nullptr);
+                 DiagnosticOptions &DiagOpts, const Preprocessor *PP = nullptr);
 
   ~TextDiagnostic() override;
 
diff --git a/clang/include/clang/Frontend/TextDiagnosticPrinter.h b/clang/include/clang/Frontend/TextDiagnosticPrinter.h
index 2610bde7513a1..dd1ca6b2248b7 100644
--- a/clang/include/clang/Frontend/TextDiagnosticPrinter.h
+++ b/clang/include/clang/Frontend/TextDiagnosticPrinter.h
@@ -26,7 +26,7 @@ class TextDiagnostic;
 
 class TextDiagnosticPrinter : public DiagnosticConsumer {
   raw_ostream &OS;
-  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
+  DiagnosticOptions &DiagOpts;
 
   /// Handle to the currently active text diagnostic emitter.
   std::unique_ptr<TextDiagnostic> TextDiag;
@@ -38,7 +38,7 @@ class TextDiagnosticPrinter : public DiagnosticConsumer {
   unsigned OwnsOutputStream : 1;
 
 public:
-  TextDiagnosticPrinter(raw_ostream &os, DiagnosticOptions *diags,
+  TextDiagnosticPrinter(raw_ostream &os, DiagnosticOptions &DiagOpts,
                         bool OwnsOutputStream = false);
   ~TextDiagnosticPrinter() override;
 
diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h
index 57b0266af26bb..6963611c6a815 100644
--- a/clang/include/clang/Serialization/ASTReader.h
+++ b/clang/include/clang/Serialization/ASTReader.h
@@ -151,9 +151,8 @@ class ASTReaderListener {
   ///
   /// \returns true to indicate the diagnostic options are invalid, or false
   /// otherwise.
-  virtual bool
-  ReadDiagnosticOptions(IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts,
-                        StringRef ModuleFilename, bool Complain) {
+  virtual bool ReadDiagnosticOptions(DiagnosticOptions &DiagOpts,
+                                     StringRef ModuleFilename, bool Complain) {
     return false;
   }
 
@@ -285,7 +284,7 @@ class ChainedASTReaderListener : public ASTReaderListener {
   bool ReadTargetOptions(const TargetOptions &TargetOpts,
                          StringRef ModuleFilename, bool Complain,
                          bool AllowCompatibleDifferences) override;
-  bool ReadDiagnosticOptions(IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts,
+  bool ReadDiagnosticOptions(DiagnosticOptions &DiagOpts,
                              StringRef ModuleFilename, bool Complain) override;
   bool ReadFileSystemOptions(const FileSystemOptions &FSOpts,
                              bool Complain) override;
@@ -326,7 +325,7 @@ class PCHValidator : public ASTReaderListener {
   bool ReadTargetOptions(const TargetOptions &TargetOpts,
                          StringRef ModuleFilename, bool Complain,
                          bool AllowCompatibleDifferences) override;
-  bool ReadDiagnosticOptions(IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts,
+  bool ReadDiagnosticOptions(DiagnosticOptions &DiagOpts,
                              StringRef ModuleFilename, bool Complain) override;
   bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts,
                                StringRef ModuleFilename, bool ReadMacros,
diff --git a/clang/lib/Basic/Diagnostic.cpp b/clang/lib/Basic/Diagnostic.cpp
index 538c1d18a8ac1..0219e1c159db4 100644
--- a/clang/lib/Basic/Diagnostic.cpp
+++ b/clang/lib/Basic/Diagnostic.cpp
@@ -77,11 +77,11 @@ static void DummyArgToStringFn(DiagnosticsEngine::ArgumentKind AK, intptr_t QT,
   Output.append(Str.begin(), Str.end());
 }
 
-DiagnosticsEngine::DiagnosticsEngine(
-    IntrusiveRefCntPtr<DiagnosticIDs> diags,
-    IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts, DiagnosticConsumer *client,
-    bool ShouldOwnClient)
-    : Diags(std::move(diags)), DiagOpts(std::move(DiagOpts)) {
+DiagnosticsEngine::DiagnosticsEngine(IntrusiveRefCntPtr<DiagnosticIDs> diags,
+                                     DiagnosticOptions &DiagOpts,
+                                     DiagnosticConsumer *client,
+                                     bool ShouldOwnClient)
+    : Diags(std::move(diags)), DiagOpts(DiagOpts) {
   setClient(client, ShouldOwnClient);
   ArgToStringFn = DummyArgToStringFn;
 
diff --git a/clang/lib/Basic/SourceManager.cpp b/clang/lib/Basic/SourceManager.cpp
index 6d6e54b1bec69..8575204dc62d2 100644
--- a/clang/lib/Basic/SourceManager.cpp
+++ b/clang/lib/Basic/SourceManager.cpp
@@ -2391,11 +2391,11 @@ SourceManagerForFile::SourceManagerForFile(StringRef FileName,
   // in `Environment` so that `FileMgr` can out-live this function scope.
   FileMgr =
       std::make_unique<FileManager>(FileSystemOptions(), InMemoryFileSystem);
+  DiagOpts = std::make_unique<DiagnosticOptions>();
   // This is passed to `SM` as reference, so the pointer has to be referenced
   // by `Environment` due to the same reason above.
   Diagnostics = std::make_unique<DiagnosticsEngine>(
-      IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),
-      new DiagnosticOptions);
+      IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs), *DiagOpts);
   SourceMgr = std::make_unique<SourceManager>(*Diagnostics, *FileMgr);
   FileEntryRef FE = llvm::cantFail(FileMgr->getFileRef(FileName));
   FileID ID =
diff --git a/clang/lib/CrossTU/CrossTranslationUnit.cpp b/clang/lib/CrossTU/CrossTranslationUnit.cpp
index ef395f497216c..9401587456f0e 100644
--- a/clang/lib/CrossTU/CrossTranslationUnit.cpp
+++ b/clang/lib/CrossTU/CrossTranslationUnit.cpp
@@ -560,12 +560,12 @@ CrossTranslationUnitContext::ASTLoader::load(StringRef Identifier) {
 
 CrossTranslationUnitContext::LoadResultTy
 CrossTranslationUnitContext::ASTLoader::loadFromDump(StringRef ASTDumpPath) {
-  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
+  DiagnosticOptions DiagOpts;
   TextDiagnosticPrinter *DiagClient =
-      new TextDiagnosticPrinter(llvm::errs(), &*DiagOpts);
+      new TextDiagnosticPrinter(llvm::errs(), DiagOpts);
   IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
   IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
-      new DiagnosticsEngine(DiagID, &*DiagOpts, DiagClient));
+      new DiagnosticsEngine(DiagID, DiagOpts, DiagClient));
   return ASTUnit::LoadFromASTFile(
       ASTDumpPath, CI.getPCHContainerOperations()->getRawReader(),
       ASTUnit::LoadEverything, Diags, CI.getFileSystemOpts(),
@@ -603,12 +603,11 @@ CrossTranslationUnitContext::ASTLoader::loadFromSource(
                  CommandLineArgs.begin(),
                  [](auto &&CmdPart) { return CmdPart.c_str(); });
 
-  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts{&CI.getDiagnosticOpts()};
   auto *DiagClient = new ForwardingDiagnosticConsumer{CI.getDiagnosticClient()};
   IntrusiveRefCntPtr<DiagnosticIDs> DiagID{
       CI.getDiagnostics().getDiagnosticIDs()};
   IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
-      new DiagnosticsEngine{DiagID, &*DiagOpts, DiagClient});
+      new DiagnosticsEngine{DiagID, CI.getDiagnosticOpts(), DiagClient});
 
   return ASTUnit::LoadFromCommandLine(CommandLineArgs.begin(),
                                       (CommandLineArgs.end()),
diff --git a/clang/lib/Frontend/ASTMerge.cpp b/clang/lib/Frontend/ASTMerge.cpp
index b6b06440bc3f8..c2e6779d19f0d 100644
--- a/clang/lib/Frontend/ASTMerge.cpp
+++ b/clang/lib/Frontend/ASTMerge.cpp
@@ -42,7 +42,7 @@ void ASTMergeAction::ExecuteAction() {
       *CI.getASTContext().getTranslationUnitDecl());
   for (unsigned I = 0, N = ASTFiles.size(); I != N; ++I) {
     IntrusiveRefCntPtr<DiagnosticsEngine>
-        Diags(new DiagnosticsEngine(DiagIDs, &CI.getDiagnosticOpts(),
+        Diags(new DiagnosticsEngine(DiagIDs, CI.getDiagnosticOpts(),
                                     new ForwardingDiagnosticConsumer(
                                           *CI.getDiagnostics().getClient()),
                                     /*ShouldOwnClient=*/true));
diff --git a/clang/lib/Frontend/ChainedIncludesSource.cpp b/clang/lib/Frontend/ChainedIncludesSource.cpp
index 95b0ed248d545..338fd81ea1a80 100644
--- a/clang/lib/Frontend/ChainedIncludesSource.cpp
+++ b/clang/lib/Frontend/ChainedIncludesSource.cpp
@@ -117,10 +117,10 @@ IntrusiveRefCntPtr<ExternalSemaSource> clang::createChainedIncludesSource(
     CInvok->getFrontendOpts().Inputs.push_back(InputFile);
 
     TextDiagnosticPrinter *DiagClient =
-      new TextDiagnosticPrinter(llvm::errs(), new DiagnosticOptions());
+      new TextDiagnosticPrinter(llvm::errs(), CI.getDiagnosticOpts());
     IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
     IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
-        new DiagnosticsEngine(DiagID, &CI.getDiagnosticOpts(), DiagClient));
+        new DiagnosticsEngine(DiagID, CI.getDiagnosticOpts(), DiagClient));
 
     auto Clang = std::make_unique<CompilerInstance>(
         std::move(CInvok), CI.getPCHContainerOperations());
diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp
index 503d36467653e..7fecb40d7187a 100644
--- a/clang/lib/Frontend/CompilerInstance.cpp
+++ b/clang/lib/Frontend/CompilerInstance.cpp
@@ -280,20 +280,20 @@ static void collectVFSEntries(CompilerInstance &CI,
 }
 
 // Diagnostics
-static void SetUpDiagnosticLog(DiagnosticOptions *DiagOpts,
+static void SetUpDiagnosticLog(DiagnosticOptions &DiagOpts,
                                const CodeGenOptions *CodeGenOpts,
                                DiagnosticsEngine &Diags) {
   std::error_code EC;
   std::unique_ptr<raw_ostream> StreamOwner;
   raw_ostream *OS = &llvm::errs();
-  if (DiagOpts->DiagnosticLogFile != "-") {
+  if (DiagOpts.DiagnosticLogFile != "-") {
     // Create the output stream.
     auto FileOS = std::make_unique<llvm::raw_fd_ostream>(
-        DiagOpts->DiagnosticLogFile, EC,
+        DiagOpts.DiagnosticLogFile, EC,
         llvm::sys::fs::OF_Append | llvm::sys::fs::OF_TextWithCRLF);
     if (EC) {
       Diags.Report(diag::warn_fe_cc_log_diagnostics_failure)
-          << DiagOpts->DiagnosticLogFile << EC.message();
+          << DiagOpts.DiagnosticLogFile << EC.message();
     } else {
       FileOS->SetUnbuffered();
       OS = FileOS.get();
@@ -315,7 +315,7 @@ static void SetUpDiagnosticLog(DiagnosticOptions *DiagOpts,
   }
 }
 
-static void SetupSerializedDiagnostics(DiagnosticOptions *DiagOpts,
+static void SetupSerializedDiagnostics(DiagnosticOptions &DiagOpts,
                                        DiagnosticsEngine &Diags,
                                        StringRef OutputFile) {
   auto SerializedConsumer =
@@ -333,12 +333,12 @@ static void SetupSerializedDiagnostics(DiagnosticOptions *DiagOpts,
 void CompilerInstance::createDiagnostics(llvm::vfs::FileSystem &VFS,
                                          DiagnosticConsumer *Client,
                                          bool ShouldOwnClient) {
-  Diagnostics = createDiagnostics(VFS, &getDiagnosticOpts(), Client,
+  Diagnostics = createDiagnostics(VFS, getDiagnosticOpts(), Client,
                                   ShouldOwnClient, &getCodeGenOpts());
 }
 
 IntrusiveRefCntPtr<DiagnosticsEngine> CompilerInstance::createDiagnostics(
-    llvm::vfs::FileSystem &VFS, DiagnosticOptions *Opts,
+    llvm::vfs::FileSystem &VFS, DiagnosticOptions &Opts,
     DiagnosticConsumer *Client, bool ShouldOwnClient,
     const CodeGenOptions *CodeGenOpts) {
   IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
@@ -349,25 +349,25 @@ IntrusiveRefCntPtr<DiagnosticsEngine> CompilerInstance::createDiagnostics(
   // implementing -verify.
   if (Client) {
     Diags->setClient(Client, ShouldOwnClient);
-  } else if (Opts->getFormat() == DiagnosticOptions::SARIF) {
+  } else if (Opts.getFormat() == DiagnosticOptions::SARIF) {
     Diags->setClient(new SARIFDiagnosticPrinter(llvm::errs(), Opts));
   } else
     Diags->setClient(new TextDiagnosticPrinter(llvm::errs(), Opts));
 
   // Chain in -verify checker, if requested.
-  if (Opts->VerifyDiagnostics)
+  if (Opts.VerifyDiagnostics)
     Diags->setClient(new VerifyDiagnosticConsumer(*Diags));
 
   // Chain in -diagnostic-log-file dumper, if requested.
-  if (!Opts->DiagnosticLogFile.empty())
+  if (!Opts.DiagnosticLogFile.empty())
     SetUpDiagnosticLog(Opts, CodeGenOpts, *Diags);
 
-  if (!Opts->DiagnosticSerializationFile.empty())
+  if (!Opts.DiagnosticSerializationFile.empty())
     SetupSerializedDiagnostics(Opts, *Diags,
-                               Opts->DiagnosticSerializationFile);
+                               Opts.DiagnosticSerializationFile);
 
   // Configure our handling of diagnostics.
-  ProcessWarningOptions(*Diags, *Opts, VFS);
+  ProcessWarningOptions(*Diags, Opts, VFS);
 
   return Diags;
 }
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 394512978b521..a7a90d790a146 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -125,21 +125,14 @@ static Expected<std::optional<uint32_t>> parseToleranceOption(StringRef Arg) {
 // Initialization.
 //===----------------------------------------------------------------------===//
 
-namespace {
 template <class T> std::shared_ptr<T> make_shared_copy(const T &X) {
   return std::make_shared<T>(X);
 }
 
-template <class T>
-llvm::IntrusiveRefCntPtr<T> makeIntrusiveRefCntCopy(const T &X) {
-  return llvm::makeIntrusiveRefCnt<T>(X);
-}
-} // namespace
-
 CompilerInvocationBase::CompilerInvocationBase()
     : LangOpts(std::make_shared<LangOptions>()),
       TargetOpts(std::make_shared<TargetOptions>()),
-      DiagnosticOpts(llvm::makeIntrusiveRefCnt<DiagnosticOptions>()),
+      DiagnosticOpts(std::make_shared<DiagnosticOptions>()),
       HSOpts(std::make_shared<HeaderSearchOptions>()),
       PPOpts(std::make_shared<PreprocessorOptions>()),
       AnalyzerOpts(std::make_shared<AnalyzerOptions>()),
@@ -156,7 +149,7 @@ CompilerInvocationBase::deep_copy_assign(const CompilerInvocationBase &X) {
   if (this != &X) {
     LangOpts = make_shared_copy(X.getLangOpts());
     TargetOpts = make_shared_copy(X.getTargetOpts());
-    DiagnosticOpts = makeIntrusiveRefCntCopy(X.getDiagnosticOpts());
+    DiagnosticOpts = make_shared_copy(X.getDiagnosticOpts());
     HSOpts = make_shared_copy(X.getHeaderSearchOpts());
     PPOpts = make_shared_copy(X.getPreprocessorOpts());
     AnalyzerOpts = make_shared_copy(X.getAnalyzerOpts());
@@ -202,7 +195,6 @@ CompilerInvocation::operator=(const CowCompilerInvocation &X) {
   return *this;
 }
 
-namespace {
 template <typename T>
 T &ensureOwned(std::shared_ptr<T> &Storage) {
   if (Storage.use_count() > 1)
@@ -210,14 +202,6 @@ T &ensureOwned(std::shared_ptr<T> &Storage) {
   return *Storage;
 }
 
-template <typename T>
-T &ensureOwned(llvm::IntrusiveRefCntPtr<T> &Storage) {
-  if (Storage.useCount() > 1)
-    Storage = llvm::makeIntrusiveRefCnt<T>(*Storage);
-  return *Storage;
-}
-} // namespace
-
 LangOptions &CowCompilerInvocation::getMutLangOpts() {
   return ensureOwned(LangOpts);
 }
@@ -844,7 +828,8 @@ static bool RoundTrip(ParseFn Parse, GenerateFn Generate,
   };
 
   // Setup a dummy DiagnosticsEngine.
-  DiagnosticsEngine DummyDiags(new DiagnosticIDs(), new DiagnosticOptions());
+  DiagnosticOptions DummyDiagOpts;
+  DiagnosticsEngine DummyDiags(new DiagnosticIDs(), DummyDiagOpts);
   DummyDiags.setClient(new TextDiagnosticBuffer());
 
   // Run the first parse on the original arguments with the dummy invocation and
@@ -2664,9 +2649,11 @@ clang::CreateAndPopulateDiagOpts(ArrayRef<const char *> Argv) {
 bool clang::ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args,
                                 DiagnosticsEngine *Diags,
                                 bool DefaultDiagColor) {
+  std::optional<DiagnosticOptions> IgnoringDiagOpts;
   std::optional<DiagnosticsEngine> IgnoringDiags;
   if (!Diags) {
-    IgnoringDiags.emplace(new DiagnosticIDs(), new DiagnosticOptions(),
+    IgnoringDiagOpts.emplace();
+    IgnoringDiags.emplace(new DiagnosticIDs(), *IgnoringDiagOpts,
                           new IgnoringDiagConsumer());
     Diags = &*IgnoringDiags;
   }
diff --git a/clang/lib/Frontend/CreateInvocationFromCommandLine.cpp b/clang/lib/Frontend/CreateInvocationFromCommandLine.cpp
index d0b855fff2534..99212b81fe064 100644
--- a/clang/lib/Frontend/CreateInvocationFromCommandLine.cpp
+++ b/clang/lib/Frontend/CreateInvocationFromCommandLine.cpp
@@ -31,11 +31,15 @@ std::unique_ptr<CompilerInvocation>
 clang::createInvocation(ArrayRef<const char *> ArgList,
                         CreateInvocationOptions Opts) {
   assert(!ArgList.empty());
-  auto Diags = Opts.Diags
-                   ? std::move(Opts.Diags)
-                   : CompilerInstance::createDiagnostics(
-                         Opts.VFS ? *Opts.VFS : *llvm::vfs::getRealFileSystem(),
-                         new DiagnosticOptions);
+  std::optional<DiagnosticOptions> LocalDiagOpts;
+  IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
+  if (Opts.Diags) {
+    Diags = std::move(Opts.Diags);
+  } else {
+    LocalDiagOpts.emplace();
+    Diags = CompilerInstance::createDiagnostics(
+        Opts.VFS ? *Opts.VFS : *llvm::vfs::getRealFileSystem(), *LocalDiagOpts);
+  }
 
   SmallVector<const char *, 16> Args(ArgList);
 
diff --git a/clang/lib/Frontend/DiagnosticRenderer.cpp b/clang/lib/Frontend/DiagnosticRenderer.cpp
index b11806637efda..7f3ccd38e6006 100644
--- a/clang/lib/Frontend/DiagnosticRenderer.cpp
+++ b/clang/lib/Frontend/DiagnosticRenderer.cpp
@@ -30,7 +30,7 @@
 using namespace clang;
 
 DiagnosticRenderer::DiagnosticRenderer(const LangOptions &LangOpts,
-                                       DiagnosticOptions *DiagOpts)
+                                       DiagnosticOptions &DiagOpts)
     : LangOpts(LangOpts), DiagOpts(DiagOpts), LastLevel() {}
 
 DiagnosticRenderer::~DiagnosticRenderer() = default;
@@ -115,7 +115,7 @@ void DiagnosticRenderer::emitDiagnostic(FullSourceLoc Loc,
     // Find the ultimate expansion location for the diagnostic.
     Loc = Loc.getFileLoc();
 
-    PresumedLoc PLoc = Loc.getPresumedLoc(DiagOpts->ShowPresumedLoc);
+    PresumedLoc PLoc = Loc.getPresumedLoc(DiagOpts.ShowPresumedLoc);
 
     // First, if this diagnostic is not in the main file, print out the
     // "included from" lines.
@@ -172,7 +172,7 @@ void DiagnosticRenderer::emitIncludeStack(FullSourceLoc Loc, PresumedLoc PLoc,
 
   LastIncludeLoc = IncludeLoc;
 
-  if (!DiagOpts->ShowNoteIncludeStack && Level == DiagnosticsEngine::Note)
+  if (!DiagOpts.ShowNoteIncludeStack && Level == DiagnosticsEngine::Note)
     return;
 
   if (IncludeLoc.isValid())
@@ -191,7 +191,7 @@ void DiagnosticRenderer::emitIncludeStackRecursively(FullSourceLoc Loc) {
     return;
   }
 
-  PresumedLoc PLoc = Loc.getPresumedLoc(DiagOpts->ShowPresumedLoc);
+  PresumedLoc PLoc = Loc.getPresumedLoc(DiagOpts.ShowPresumedLoc);
   if (PLoc.isInvalid())
     return;
 
@@ -232,7 +232,7 @@ void DiagnosticRenderer::emitImportStackRecursively(FullSourceLoc Loc,
     return;
   }
 
-  PresumedLoc PLoc = Loc.getPresumedLoc(DiagOpts->ShowPresumedLoc);
+  PresumedLoc PLoc = Loc.getPresumedLoc(DiagOpts.ShowPresumedLoc);
 
   // Emit the other import frames first.
   std::pair<FullSourceLoc, StringRef> NextImportLoc = Loc.getModuleImportLoc();
@@ -248,7 +248,7 @@ void DiagnosticRenderer::emitModuleBuildStack(const SourceManager &SM) {
   ModuleBuildStack Stack = SM.getModuleBuildStack();
   for (const auto &I : Stack) {
     emitBuildingModuleLocation(I.second, I.second.getPresumedLoc(
-                                              DiagOpts->ShowPresumedLoc),
+                                              DiagOpts.ShowPresumedLoc),
                                I.first);
   }
 }
@@ -540,7 +540,7 @@ void DiagnosticRenderer::emitMacroExpansions(FullSourceLoc Loc,
                       LocationStack.begin() + IgnoredEnd);
 
   unsigned MacroDepth = LocationStack.size();
-  unsigned MacroLimit = DiagOpts->MacroBacktraceLimit;
+  unsigned MacroLimit = DiagOpts.MacroBacktraceLimit;
   if (MacroDepth <= MacroLimit || MacroLimit == 0) {
     for (auto I = LocationStack.rbegin(), E = LocationStack.rend();
          I != E; ++I)
diff --git a/clang/lib/Frontend/FrontendAction.cpp b/clang/lib/Frontend/FrontendAction.cpp
index f09eb9832e692..e39041bef1459 100644
--- a/clang/lib/Frontend/FrontendAction.cpp
+++ b/clang/lib/Frontend/FrontendAction.cpp
@@ -772,7 +772,7 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
     // The AST unit populates its own diagnostics engine rather than ours.
     IntrusiveRefCntPtr<DiagnosticsEngine> ASTDiags(
         new DiagnosticsEngine(Diags->getDiagnosticIDs(),
-                              &Diags->getDiagnosticOptions()));
+                              Diags->getDiagnosticOptions()));
     ASTDiags->setClient(Diags->getClient(), /*OwnsClient*/false);
 
     // FIXME: What if the input is a memory buffer?
diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp
index 8c75e1a46da54..48d4453810fc6 100644
--- a/clang/lib/Frontend/FrontendActions.cpp
+++ b/clang/lib/Frontend/FrontendActions.cpp
@@ -685,21 +685,21 @@ namespace {
       return false;
     }
 
-    bool ReadDiagnosticOptions(IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts,
+    bool ReadDiagnosticOptions(DiagnosticOptions &DiagOpts,
                                StringRef ModuleFilename,
                                bool Complain) override {
       Out.indent(2) << "Diagnostic options:\n";
-#define DIAGOPT(Name, Bits, Default) DUMP_BOOLEAN(DiagOpts->Name, #Name);
+#define DIAGOPT(Name, Bits, Default) DUMP_BOOLEAN(DiagOpts.Name, #Name);
 #define ENUM_DIAGOPT(Name, Type, Bits, Default) \
-      Out.indent(4) << #Name << ": " << DiagOpts->get##Name() << "\n";
+      Out.indent(4) << #Name << ": " << DiagOpts.get##Name() << "\n";
 #define VALUE_DIAGOPT(Name, Bits, Default) \
-      Out.indent(4) << #Name << ": " << DiagOpts->Name << "\n";
+      Out.indent(4) << #Name << ": " << DiagOpts.Name << "\n";
 #include "clang/Basic/DiagnosticOptions.def"
 
       Out.indent(4) << "Diagnostic flags:\n";
-      for (const std::string &Warning : DiagOpts->Warnings)
+      for (const std::string &Warning : DiagOpts.Warnings)
         Out.indent(6) << "-W" << Warning << "\n";
-      for (const std::string &Remark : DiagOpts->Remarks)
+      for (const std::string &Remark : DiagOpts.Remarks)
         Out.indent(6) << "-R" << Remark << "\n";
 
       return false;
diff --git a/clang/lib/Frontend/LogDiagnosticPrinter.cpp b/clang/lib/Frontend/LogDiagnosticPrinter.cpp
index 4e963af837f01..2d188931e4f8a 100644
--- a/clang/lib/Frontend/LogDiagnosticPrinter.cpp
+++ b/clang/lib/Frontend/LogDiagnosticPrinter.cpp
@@ -18,10 +18,10 @@ using namespace clang;
 using namespace markup;
 
 LogDiagnosticPrinter::LogDiagnosticPrinter(
-    raw_ostream &os, DiagnosticOptions *diags,
+    raw_ostream &os, DiagnosticOptions &DiagOpts,
     std::unique_ptr<raw_ostream> StreamOwner)
     : OS(os), StreamOwner(std::move(StreamOwner)), LangOpts(nullptr),
-      DiagOpts(diags) {}
+      DiagOpts(DiagOpts) {}
 
 static StringRef getLevelName(DiagnosticsEngine::Level Level) {
   switch (Level) {
diff --git a/clang/lib/Frontend/SARIFDiagnostic.cpp b/clang/lib/Frontend/SARIFDiagnostic.cpp
index 4e36153ed5391..e2aec7f677f12 100644
--- a/clang/lib/Frontend/SARIFDiagnostic.cpp
+++ b/clang/lib/Frontend/SARIFDiagnostic.cpp
@@ -31,7 +31,7 @@
 namespace clang {
 
 SARIFDiagnostic::SARIFDiagnostic(raw_ostream &OS, const LangOptions &LangOpts,
-                                 DiagnosticOptions *DiagOpts,
+                                 DiagnosticOptions &DiagOpts,
                                  SarifDocumentWriter *Writer)
     : DiagnosticRenderer(LangOpts, DiagOpts), Writer(Writer) {}
 
@@ -163,7 +163,7 @@ SARIFDiagnostic::addDiagnosticLevelToRule(SarifRule Rule,
 
 llvm::StringRef SARIFDiagnostic::emitFilename(StringRef Filename,
                                               const SourceManager &SM) {
-  if (DiagOpts->AbsolutePath) {
+  if (DiagOpts.AbsolutePath) {
     auto File = SM.getFileManager().getOptionalFileRef(Filename);
     if (File) {
       // We want to print a simplified absolute path, i. e. without "dots".
diff --git a/clang/lib/Frontend/SARIFDiagnosticPrinter.cpp b/clang/lib/Frontend/SARIFDiagnosticPrinter.cpp
index 73928d19a031a..23fbc3e4fa92b 100644
--- a/clang/lib/Frontend/SARIFDiagnosticPrinter.cpp
+++ b/clang/lib/Frontend/SARIFDiagnosticPrinter.cpp
@@ -26,15 +26,15 @@
 namespace clang {
 
 SARIFDiagnosticPrinter::SARIFDiagnosticPrinter(raw_ostream &OS,
-                                               DiagnosticOptions *Diags)
-    : OS(OS), DiagOpts(Diags) {}
+                                               DiagnosticOptions &DiagOpts)
+    : OS(OS), DiagOpts(DiagOpts) {}
 
 void SARIFDiagnosticPrinter::BeginSourceFile(const LangOptions &LO,
                                              const Preprocessor *PP) {
   // Build the SARIFDiagnostic utility.
   assert(hasSarifWriter() && "Writer not set!");
   assert(!SARIFDiag && "SARIFDiagnostic already set.");
-  SARIFDiag = std::make_unique<SARIFDiagnostic>(OS, LO, &*DiagOpts, &*Writer);
+  SARIFDiag = std::make_unique<SARIFDiagnostic>(OS, LO, DiagOpts, &*Writer);
   // Initialize the SARIF object.
   Writer->createRun("clang", Prefix);
 }
@@ -72,7 +72,6 @@ void SARIFDiagnosticPrinter::HandleDiagnostic(DiagnosticsEngine::Level Level,
   }
 
   // Assert that the rest of our infrastructure is setup properly.
-  assert(DiagOpts && "Unexpected diagnostic without options set");
   assert(Info.hasSourceManager() &&
          "Unexpected diagnostic with no source manager");
 
diff --git a/clang/lib/Frontend/SerializedDiagnosticPrinter.cpp b/clang/lib/Frontend/SerializedDiagnosticPrinter.cpp
index 02aa3e8e4d984..c9b8c8cd5755a 100644
--- a/clang/lib/Frontend/SerializedDiagnosticPrinter.cpp
+++ b/clang/lib/Frontend/SerializedDiagnosticPrinter.cpp
@@ -57,7 +57,7 @@ class SDiagsRenderer : public DiagnosticNoteRenderer {
   SDiagsWriter &Writer;
 public:
   SDiagsRenderer(SDiagsWriter &Writer, const LangOptions &LangOpts,
-                 DiagnosticOptions *DiagOpts)
+                 DiagnosticOptions &DiagOpts)
     : DiagnosticNoteRenderer(LangOpts, DiagOpts), Writer(Writer) {}
 
   ~SDiagsRenderer() override {}
@@ -140,7 +140,7 @@ class SDiagsWriter : public DiagnosticConsumer {
         State(std::move(State)) {}
 
 public:
-  SDiagsWriter(StringRef File, DiagnosticOptions *Diags, bool MergeChildRecords)
+  SDiagsWriter(StringRef File, DiagnosticOptions &Diags, bool MergeChildRecords)
       : LangOpts(nullptr), OriginalInstance(true),
         MergeChildRecords(MergeChildRecords),
         State(std::make_shared<SharedState>(File, Diags)) {
@@ -242,12 +242,12 @@ class SDiagsWriter : public DiagnosticConsumer {
   /// State that is shared among the various clones of this diagnostic
   /// consumer.
   struct SharedState {
-    SharedState(StringRef File, DiagnosticOptions *Diags)
-        : DiagOpts(Diags), Stream(Buffer), OutputFile(File.str()),
+    SharedState(StringRef File, DiagnosticOptions &DiagOpts)
+        : DiagOpts(DiagOpts), Stream(Buffer), OutputFile(File.str()),
           EmittedAnyDiagBlocks(false) {}
 
     /// Diagnostic options.
-    IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
+    DiagnosticOptions DiagOpts;
 
     /// The byte buffer for the serialized content.
     SmallString<1024> Buffer;
@@ -296,8 +296,8 @@ class SDiagsWriter : public DiagnosticConsumer {
 namespace clang {
 namespace serialized_diags {
 std::unique_ptr<DiagnosticConsumer>
-create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords) {
-  return std::make_unique<SDiagsWriter>(OutputFile, Diags, MergeChildRecords);
+create(StringRef OutputFile, DiagnosticOptions &DiagOpts, bool MergeChildRecords) {
+  return std::make_unique<SDiagsWriter>(OutputFile, DiagOpts, MergeChildRecords);
 }
 
 } // end namespace serialized_diags
@@ -617,7 +617,7 @@ void SDiagsWriter::HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
 
   assert(Info.hasSourceManager() && LangOpts &&
          "Unexpected diagnostic with valid location outside of a source file");
-  SDiagsRenderer Renderer(*this, *LangOpts, &*State->DiagOpts);
+  SDiagsRenderer Renderer(*this, *LangOpts, State->DiagOpts);
   Renderer.emitDiagnostic(
       FullSourceLoc(Info.getLocation(), Info.getSourceManager()), DiagLevel,
       State->diagBuf, Info.getRanges(), Info.getFixItHints(), &Info);
@@ -756,9 +756,9 @@ DiagnosticsEngine *SDiagsWriter::getMetaDiags() {
   if (!State->MetaDiagnostics) {
     IntrusiveRefCntPtr<DiagnosticIDs> IDs(new DiagnosticIDs());
     auto Client =
-        new TextDiagnosticPrinter(llvm::errs(), State->DiagOpts.get());
+        new TextDiagnosticPrinter(llvm::errs(), State->DiagOpts);
     State->MetaDiagnostics = std::make_unique<DiagnosticsEngine>(
-        IDs, State->DiagOpts.get(), Client);
+        IDs, State->DiagOpts, Client);
   }
   return State->MetaDiagnostics.get();
 }
diff --git a/clang/lib/Frontend/TextDiagnostic.cpp b/clang/lib/Frontend/TextDiagnostic.cpp
index 4119ce6048d45..ba4c1accc2a44 100644
--- a/clang/lib/Frontend/TextDiagnostic.cpp
+++ b/clang/lib/Frontend/TextDiagnostic.cpp
@@ -654,7 +654,7 @@ static bool printWordWrapped(raw_ostream &OS, StringRef Str, unsigned Columns,
 }
 
 TextDiagnostic::TextDiagnostic(raw_ostream &OS, const LangOptions &LangOpts,
-                               DiagnosticOptions *DiagOpts,
+                               DiagnosticOptions &DiagOpts,
                                const Preprocessor *PP)
     : DiagnosticRenderer(LangOpts, DiagOpts), OS(OS), PP(PP) {}
 
@@ -670,15 +670,15 @@ void TextDiagnostic::emitDiagnosticMessage(
   if (Loc.isValid())
     emitDiagnosticLoc(Loc, PLoc, Level, Ranges);
 
-  if (DiagOpts->ShowColors)
+  if (DiagOpts.ShowColors)
     OS.resetColor();
 
-  if (DiagOpts->ShowLevel)
-    printDiagnosticLevel(OS, Level, DiagOpts->ShowColors);
+  if (DiagOpts.ShowLevel)
+    printDiagnosticLevel(OS, Level, DiagOpts.ShowColors);
   printDiagnosticMessage(OS,
                          /*IsSupplemental*/ Level == DiagnosticsEngine::Note,
                          Message, OS.tell() - StartOfLocationInfo,
-                         DiagOpts->MessageLength, DiagOpts->ShowColors);
+                         DiagOpts.MessageLength, DiagOpts.ShowColors);
 }
 
 /*static*/ void
@@ -743,7 +743,7 @@ void TextDiagnostic::emitFilename(StringRef Filename, const SourceManager &SM) {
 #ifdef _WIN32
   SmallString<4096> TmpFilename;
 #endif
-  if (DiagOpts->AbsolutePath) {
+  if (DiagOpts.AbsolutePath) {
     auto File = SM.getFileManager().getOptionalFileRef(Filename);
     if (File) {
       // We want to print a simplified absolute path, i. e. without "dots".
@@ -796,27 +796,27 @@ void TextDiagnostic::emitDiagnosticLoc(FullSourceLoc Loc, PresumedLoc PLoc,
   }
   unsigned LineNo = PLoc.getLine();
 
-  if (!DiagOpts->ShowLocation)
+  if (!DiagOpts.ShowLocation)
     return;
 
-  if (DiagOpts->ShowColors)
+  if (DiagOpts.ShowColors)
     OS.changeColor(savedColor, true);
 
   emitFilename(PLoc.getFilename(), Loc.getManager());
-  switch (DiagOpts->getFormat()) {
+  switch (DiagOpts.getFormat()) {
   case DiagnosticOptions::SARIF:
   case DiagnosticOptions::Clang:
-    if (DiagOpts->ShowLine)
+    if (DiagOpts.ShowLine)
       OS << ':' << LineNo;
     break;
   case DiagnosticOptions::MSVC:  OS << '('  << LineNo; break;
   case DiagnosticOptions::Vi:    OS << " +" << LineNo; break;
   }
 
-  if (DiagOpts->ShowColumn)
+  if (DiagOpts.ShowColumn)
     // Compute the column number.
     if (unsigned ColNo = PLoc.getColumn()) {
-      if (DiagOpts->getFormat() == DiagnosticOptions::MSVC) {
+      if (DiagOpts.getFormat() == DiagnosticOptions::MSVC) {
         OS << ',';
         // Visual Studio 2010 or earlier expects column number to be off by one
         if (LangOpts.MSCompatibilityVersion &&
@@ -826,7 +826,7 @@ void TextDiagnostic::emitDiagnosticLoc(FullSourceLoc Loc, PresumedLoc PLoc,
         OS << ':';
       OS << ColNo;
     }
-  switch (DiagOpts->getFormat()) {
+  switch (DiagOpts.getFormat()) {
   case DiagnosticOptions::SARIF:
   case DiagnosticOptions::Clang:
   case DiagnosticOptions::Vi:    OS << ':';    break;
@@ -841,7 +841,7 @@ void TextDiagnostic::emitDiagnosticLoc(FullSourceLoc Loc, PresumedLoc PLoc,
     break;
   }
 
-  if (DiagOpts->ShowSourceRanges && !Ranges.empty()) {
+  if (DiagOpts.ShowSourceRanges && !Ranges.empty()) {
     FileID CaretFileID = Loc.getExpansionLoc().getFileID();
     bool PrintedRange = false;
     const SourceManager &SM = Loc.getManager();
@@ -881,7 +881,7 @@ void TextDiagnostic::emitDiagnosticLoc(FullSourceLoc Loc, PresumedLoc PLoc,
 }
 
 void TextDiagnostic::emitIncludeLocation(FullSourceLoc Loc, PresumedLoc PLoc) {
-  if (DiagOpts->ShowLocation && PLoc.isValid()) {
+  if (DiagOpts.ShowLocation && PLoc.isValid()) {
     OS << "In file included from ";
     emitFilename(PLoc.getFilename(), Loc.getManager());
     OS << ':' << PLoc.getLine() << ":\n";
@@ -891,7 +891,7 @@ void TextDiagnostic::emitIncludeLocation(FullSourceLoc Loc, PresumedLoc PLoc) {
 
 void TextDiagnostic::emitImportLocation(FullSourceLoc Loc, PresumedLoc PLoc,
                                         StringRef ModuleName) {
-  if (DiagOpts->ShowLocation && PLoc.isValid())
+  if (DiagOpts.ShowLocation && PLoc.isValid())
     OS << "In module '" << ModuleName << "' imported from "
        << PLoc.getFilename() << ':' << PLoc.getLine() << ":\n";
   else
@@ -901,7 +901,7 @@ void TextDiagnostic::emitImportLocation(FullSourceLoc Loc, PresumedLoc PLoc,
 void TextDiagnostic::emitBuildingModuleLocation(FullSourceLoc Loc,
                                                 PresumedLoc PLoc,
                                                 StringRef ModuleName) {
-  if (DiagOpts->ShowLocation && PLoc.isValid())
+  if (DiagOpts.ShowLocation && PLoc.isValid())
     OS << "While building module '" << ModuleName << "' imported from "
       << PLoc.getFilename() << ':' << PLoc.getLine() << ":\n";
   else
@@ -1003,9 +1003,9 @@ static std::string buildFixItInsertionLine(FileID FID,
                                            const SourceColumnMap &map,
                                            ArrayRef<FixItHint> Hints,
                                            const SourceManager &SM,
-                                           const DiagnosticOptions *DiagOpts) {
+                                           const DiagnosticOptions &DiagOpts) {
   std::string FixItInsertionLine;
-  if (Hints.empty() || !DiagOpts->ShowFixits)
+  if (Hints.empty() || !DiagOpts.ShowFixits)
     return FixItInsertionLine;
   unsigned PrevHintEndCol = 0;
 
@@ -1057,7 +1057,7 @@ static std::string buildFixItInsertionLine(FileID FID,
     }
   }
 
-  expandTabs(FixItInsertionLine, DiagOpts->TabStop);
+  expandTabs(FixItInsertionLine, DiagOpts.TabStop);
 
   return FixItInsertionLine;
 }
@@ -1296,7 +1296,7 @@ void TextDiagnostic::emitSnippetAndCaret(
   // was part of a different warning or error diagnostic, or if the
   // diagnostic has ranges.  We don't want to emit the same caret
   // multiple times if one loc has multiple diagnostics.
-  if (!DiagOpts->ShowCarets)
+  if (!DiagOpts.ShowCarets)
     return;
   if (Loc == LastLoc && Ranges.empty() && Hints.empty() &&
       (LastLevel != DiagnosticsEngine::Note || Level == LastLevel))
@@ -1322,7 +1322,7 @@ void TextDiagnostic::emitSnippetAndCaret(
     return;
 
   // Find the set of lines to include.
-  const unsigned MaxLines = DiagOpts->SnippetLineLimit;
+  const unsigned MaxLines = DiagOpts.SnippetLineLimit;
   std::pair<unsigned, unsigned> Lines = {CaretLineNo, CaretLineNo};
   unsigned DisplayLineNo = Loc.getPresumedLoc().getLine();
   for (const auto &I : Ranges) {
@@ -1338,7 +1338,7 @@ void TextDiagnostic::emitSnippetAndCaret(
   // Where [number] is MaxLineNoDisplayWidth columns
   // and the full thing is therefore MaxLineNoDisplayWidth + 4 columns.
   unsigned MaxLineNoDisplayWidth =
-      DiagOpts->ShowLineNumbers
+      DiagOpts.ShowLineNumbers
           ? std::max(4u, getNumDisplayWidth(DisplayLineNo + MaxLines))
           : 0;
   auto indentForLineNumbers = [&] {
@@ -1350,7 +1350,7 @@ void TextDiagnostic::emitSnippetAndCaret(
   // emit, starting from the first line.
   std::unique_ptr<SmallVector<StyleRange>[]> SourceStyles =
       highlightLines(BufData, Lines.first, Lines.second, PP, LangOpts,
-                     DiagOpts->ShowColors, FID, SM);
+                     DiagOpts.ShowColors, FID, SM);
 
   SmallVector<LineRange> LineRanges =
       prepareAndFilterRanges(Ranges, SM, Lines, FID, LangOpts);
@@ -1382,7 +1382,7 @@ void TextDiagnostic::emitSnippetAndCaret(
       SourceLine.pop_back();
 
     // Build the byte to column map.
-    const SourceColumnMap sourceColMap(SourceLine, DiagOpts->TabStop);
+    const SourceColumnMap sourceColMap(SourceLine, DiagOpts.TabStop);
 
     std::string CaretLine;
     // Highlight all of the characters covered by Ranges with ~ characters.
@@ -1399,11 +1399,11 @@ void TextDiagnostic::emitSnippetAndCaret(
     }
 
     std::string FixItInsertionLine = buildFixItInsertionLine(
-        FID, LineNo, sourceColMap, Hints, SM, DiagOpts.get());
+        FID, LineNo, sourceColMap, Hints, SM, DiagOpts);
 
     // If the source line is too long for our terminal, select only the
     // "interesting" source region within that line.
-    unsigned Columns = DiagOpts->MessageLength;
+    unsigned Columns = DiagOpts.MessageLength;
     if (Columns)
       selectInterestingSourceRegion(SourceLine, CaretLine, FixItInsertionLine,
                                     Columns, sourceColMap);
@@ -1412,7 +1412,7 @@ void TextDiagnostic::emitSnippetAndCaret(
     // to produce easily machine parsable output.  Add a space before the
     // source line and the caret to make it trivial to tell the main diagnostic
     // line from what the user is intended to see.
-    if (DiagOpts->ShowSourceRanges && !SourceLine.empty()) {
+    if (DiagOpts.ShowSourceRanges && !SourceLine.empty()) {
       SourceLine = ' ' + SourceLine;
       CaretLine = ' ' + CaretLine;
     }
@@ -1423,22 +1423,22 @@ void TextDiagnostic::emitSnippetAndCaret(
 
     if (!CaretLine.empty()) {
       indentForLineNumbers();
-      if (DiagOpts->ShowColors)
+      if (DiagOpts.ShowColors)
         OS.changeColor(caretColor, true);
       OS << CaretLine << '\n';
-      if (DiagOpts->ShowColors)
+      if (DiagOpts.ShowColors)
         OS.resetColor();
     }
 
     if (!FixItInsertionLine.empty()) {
       indentForLineNumbers();
-      if (DiagOpts->ShowColors)
+      if (DiagOpts.ShowColors)
         // Print fixit line in color
         OS.changeColor(fixitColor, false);
-      if (DiagOpts->ShowSourceRanges)
+      if (DiagOpts.ShowSourceRanges)
         OS << ' ';
       OS << FixItInsertionLine << '\n';
-      if (DiagOpts->ShowColors)
+      if (DiagOpts.ShowColors)
         OS.resetColor();
     }
   }
@@ -1464,10 +1464,10 @@ void TextDiagnostic::emitSnippet(StringRef SourceLine,
   size_t I = 0;
   while (I < SourceLine.size()) {
     auto [Str, WasPrintable] =
-        printableTextForNextCharacter(SourceLine, &I, DiagOpts->TabStop);
+        printableTextForNextCharacter(SourceLine, &I, DiagOpts.TabStop);
 
     // Toggle inverted colors on or off for this character.
-    if (DiagOpts->ShowColors) {
+    if (DiagOpts.ShowColors) {
       if (WasPrintable == PrintReversed) {
         PrintReversed = !PrintReversed;
         if (PrintReversed)
@@ -1498,7 +1498,7 @@ void TextDiagnostic::emitSnippet(StringRef SourceLine,
     OS << Str;
   }
 
-  if (DiagOpts->ShowColors)
+  if (DiagOpts.ShowColors)
     OS.resetColor();
 
   OS << '\n';
@@ -1506,7 +1506,7 @@ void TextDiagnostic::emitSnippet(StringRef SourceLine,
 
 void TextDiagnostic::emitParseableFixits(ArrayRef<FixItHint> Hints,
                                          const SourceManager &SM) {
-  if (!DiagOpts->ShowParseableFixits)
+  if (!DiagOpts.ShowParseableFixits)
     return;
 
   // We follow FixItRewriter's example in not (yet) handling
diff --git a/clang/lib/Frontend/TextDiagnosticPrinter.cpp b/clang/lib/Frontend/TextDiagnosticPrinter.cpp
index 28f7218dc23f5..f264f7794740a 100644
--- a/clang/lib/Frontend/TextDiagnosticPrinter.cpp
+++ b/clang/lib/Frontend/TextDiagnosticPrinter.cpp
@@ -22,9 +22,9 @@
 using namespace clang;
 
 TextDiagnosticPrinter::TextDiagnosticPrinter(raw_ostream &os,
-                                             DiagnosticOptions *diags,
+                                             DiagnosticOptions &DiagOpts,
                                              bool _OwnsOutputStream)
-  : OS(os), DiagOpts(diags),
+  : OS(os), DiagOpts(DiagOpts),
     OwnsOutputStream(_OwnsOutputStream) {
 }
 
@@ -36,7 +36,7 @@ TextDiagnosticPrinter::~TextDiagnosticPrinter() {
 void TextDiagnosticPrinter::BeginSourceFile(const LangOptions &LO,
                                             const Preprocessor *PP) {
   // Build the TextDiagnostic utility.
-  TextDiag.reset(new TextDiagnostic(OS, LO, &*DiagOpts, PP));
+  TextDiag.reset(new TextDiagnostic(OS, LO, DiagOpts, PP));
 }
 
 void TextDiagnosticPrinter::EndSourceFile() {
@@ -121,7 +121,7 @@ void TextDiagnosticPrinter::HandleDiagnostic(DiagnosticsEngine::Level Level,
   Info.FormatDiagnostic(OutStr);
 
   llvm::raw_svector_ostream DiagMessageStream(OutStr);
-  printDiagnosticOptions(DiagMessageStream, Level, Info, *DiagOpts);
+  printDiagnosticOptions(DiagMessageStream, Level, Info, DiagOpts);
 
   // Keeps track of the starting position of the location
   // information (e.g., "foo.c:10:4:") that precedes the error
@@ -137,17 +137,16 @@ void TextDiagnosticPrinter::HandleDiagnostic(DiagnosticsEngine::Level Level,
   // diagnostics in a context that lacks language options, a source manager, or
   // other infrastructure necessary when emitting more rich diagnostics.
   if (!Info.getLocation().isValid()) {
-    TextDiagnostic::printDiagnosticLevel(OS, Level, DiagOpts->ShowColors);
+    TextDiagnostic::printDiagnosticLevel(OS, Level, DiagOpts.ShowColors);
     TextDiagnostic::printDiagnosticMessage(
         OS, /*IsSupplemental=*/Level == DiagnosticsEngine::Note,
         DiagMessageStream.str(), OS.tell() - StartOfLocationInfo,
-        DiagOpts->MessageLength, DiagOpts->ShowColors);
+        DiagOpts.MessageLength, DiagOpts.ShowColors);
     OS.flush();
     return;
   }
 
   // Assert that the rest of our infrastructure is setup properly.
-  assert(DiagOpts && "Unexpected diagnostic without options set");
   assert(Info.hasSourceManager() &&
          "Unexpected diagnostic with no source manager");
   assert(TextDiag && "Unexpected diagnostic outside source file processing");
diff --git a/clang/lib/Rewrite/HTMLRewrite.cpp b/clang/lib/Rewrite/HTMLRewrite.cpp
index c75835df2c98e..1829a4ff3504a 100644
--- a/clang/lib/Rewrite/HTMLRewrite.cpp
+++ b/clang/lib/Rewrite/HTMLRewrite.cpp
@@ -636,8 +636,8 @@ static void HighlightMacrosImpl(
   // Temporarily change the diagnostics object so that we ignore any generated
   // diagnostics from this pass.
   DiagnosticsEngine TmpDiags(PP.getDiagnostics().getDiagnosticIDs(),
-                             &PP.getDiagnostics().getDiagnosticOptions(),
-                      new IgnoringDiagConsumer);
+                             PP.getDiagnostics().getDiagnosticOptions(),
+                             new IgnoringDiagConsumer);
 
   // FIXME: This is a huge hack; we reuse the input preprocessor because we want
   // its state, but we aren't actually changing it (we hope). This should really
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index d068f5e163176..44ae8bf41abb8 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -193,7 +193,7 @@ bool ChainedASTReaderListener::ReadTargetOptions(
 }
 
 bool ChainedASTReaderListener::ReadDiagnosticOptions(
-    IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts, StringRef ModuleFilename,
+    DiagnosticOptions &DiagOpts, StringRef ModuleFilename,
     bool Complain) {
   return First->ReadDiagnosticOptions(DiagOpts, ModuleFilename, Complain) ||
          Second->ReadDiagnosticOptions(DiagOpts, ModuleFilename, Complain);
@@ -595,16 +595,16 @@ static Module *getTopImportImplicitModule(ModuleManager &ModuleMgr,
   return M;
 }
 
-bool PCHValidator::ReadDiagnosticOptions(
-    IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts, StringRef ModuleFilename,
-    bool Complain) {
+bool PCHValidator::ReadDiagnosticOptions(DiagnosticOptions &DiagOpts,
+                                         StringRef ModuleFilename,
+                                         bool Complain) {
   DiagnosticsEngine &ExistingDiags = PP.getDiagnostics();
   IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(ExistingDiags.getDiagnosticIDs());
   IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
-      new DiagnosticsEngine(DiagIDs, DiagOpts.get()));
+      new DiagnosticsEngine(DiagIDs, DiagOpts));
   // This should never fail, because we would have processed these options
   // before writing them to an ASTFile.
-  ProcessWarningOptions(*Diags, *DiagOpts,
+  ProcessWarningOptions(*Diags, DiagOpts,
                         PP.getFileManager().getVirtualFileSystem(),
                         /*Report*/ false);
 
@@ -6422,17 +6422,17 @@ bool ASTReader::ParseTargetOptions(const RecordData &Record,
 bool ASTReader::ParseDiagnosticOptions(const RecordData &Record,
                                        StringRef ModuleFilename, bool Complain,
                                        ASTReaderListener &Listener) {
-  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts(new DiagnosticOptions);
+  DiagnosticOptions DiagOpts;
   unsigned Idx = 0;
-#define DIAGOPT(Name, Bits, Default) DiagOpts->Name = Record[Idx++];
+#define DIAGOPT(Name, Bits, Default) DiagOpts.Name = Record[Idx++];
 #define ENUM_DIAGOPT(Name, Type, Bits, Default) \
-  DiagOpts->set##Name(static_cast<Type>(Record[Idx++]));
+  DiagOpts.set##Name(static_cast<Type>(Record[Idx++]));
 #include "clang/Basic/DiagnosticOptions.def"
 
   for (unsigned N = Record[Idx++]; N; --N)
-    DiagOpts->Warnings.push_back(ReadString(Record, Idx));
+    DiagOpts.Warnings.push_back(ReadString(Record, Idx));
   for (unsigned N = Record[Idx++]; N; --N)
-    DiagOpts->Remarks.push_back(ReadString(Record, Idx));
+    DiagOpts.Remarks.push_back(ReadString(Record, Idx));
 
   return Listener.ReadDiagnosticOptions(DiagOpts, ModuleFilename, Complain);
 }
diff --git a/clang/lib/Tooling/Core/Replacement.cpp b/clang/lib/Tooling/Core/Replacement.cpp
index 92e9859ca206e..9e2582ee53c59 100644
--- a/clang/lib/Tooling/Core/Replacement.cpp
+++ b/clang/lib/Tooling/Core/Replacement.cpp
@@ -585,9 +585,9 @@ llvm::Expected<std::string> applyAllReplacements(StringRef Code,
   IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem(
       new llvm::vfs::InMemoryFileSystem);
   FileManager Files(FileSystemOptions(), InMemoryFileSystem);
+  DiagnosticOptions DiagOpts;
   DiagnosticsEngine Diagnostics(
-      IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),
-      new DiagnosticOptions);
+      IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs), DiagOpts);
   SourceManager SourceMgr(Diagnostics, Files);
   Rewriter Rewrite(SourceMgr, LangOptions());
   InMemoryFileSystem->addFile(
diff --git a/clang/tools/driver/cc1_main.cpp b/clang/tools/driver/cc1_main.cpp
index 6638a15ff7e12..2c17f28621f5f 100644
--- a/clang/tools/driver/cc1_main.cpp
+++ b/clang/tools/driver/cc1_main.cpp
@@ -232,9 +232,9 @@ int cc1_main(ArrayRef<const char *> Argv, const char *Argv0, void *MainAddr) {
 
   // Buffer diagnostics from argument parsing so that we can output them using a
   // well formed diagnostic object.
-  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
+  DiagnosticOptions DiagOpts;
   TextDiagnosticBuffer *DiagsBuffer = new TextDiagnosticBuffer;
-  DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagsBuffer);
+  DiagnosticsEngine Diags(DiagID, DiagOpts, DiagsBuffer);
 
   // Setup round-trip remarks for the DiagnosticsEngine used in CreateFromArgs.
   if (find(Argv, StringRef("-Rround-trip-cc1-args")) != Argv.end())
diff --git a/clang/tools/driver/cc1as_main.cpp b/clang/tools/driver/cc1as_main.cpp
index b98fc5ead100f..9dc9a891b8d28 100644
--- a/clang/tools/driver/cc1as_main.cpp
+++ b/clang/tools/driver/cc1as_main.cpp
@@ -658,12 +658,12 @@ int cc1as_main(ArrayRef<const char *> Argv, const char *Argv0, void *MainAddr) {
   InitializeAllAsmParsers();
 
   // Construct our diagnostic client.
-  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
+  DiagnosticOptions DiagOpts;
   TextDiagnosticPrinter *DiagClient
-    = new TextDiagnosticPrinter(errs(), &*DiagOpts);
+    = new TextDiagnosticPrinter(errs(), DiagOpts);
   DiagClient->setPrefix("clang -cc1as");
   IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
-  DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagClient);
+  DiagnosticsEngine Diags(DiagID, DiagOpts, DiagClient);
 
   // Set an error handler, so that any LLVM backend diagnostics go through our
   // error handler.
diff --git a/clang/tools/driver/cc1gen_reproducer_main.cpp b/clang/tools/driver/cc1gen_reproducer_main.cpp
index df59b53f9ef18..8d7171eb2e5e0 100644
--- a/clang/tools/driver/cc1gen_reproducer_main.cpp
+++ b/clang/tools/driver/cc1gen_reproducer_main.cpp
@@ -117,12 +117,12 @@ generateReproducerForInvocationArguments(ArrayRef<const char *> Argv,
   using namespace driver;
   auto TargetAndMode = ToolChain::getTargetAndModeFromProgramName(Argv[0]);
 
-  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions;
+  DiagnosticOptions DiagOpts;
 
   IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
-  DiagnosticsEngine Diags(DiagID, &*DiagOpts, new IgnoringDiagConsumer());
+  DiagnosticsEngine Diags(DiagID, DiagOpts, new IgnoringDiagConsumer());
   auto VFS = llvm::vfs::getRealFileSystem();
-  ProcessWarningOptions(Diags, *DiagOpts, *VFS, /*ReportDiags=*/false);
+  ProcessWarningOptions(Diags, DiagOpts, *VFS, /*ReportDiags=*/false);
   Driver TheDriver(ToolContext.Path, llvm::sys::getDefaultTargetTriple(), Diags,
                    /*Title=*/"clang LLVM compiler", VFS);
   TheDriver.setTargetAndMode(TargetAndMode);
diff --git a/clang/tools/driver/driver.cpp b/clang/tools/driver/driver.cpp
index 82f47ab973064..1cce0bf0eee41 100644
--- a/clang/tools/driver/driver.cpp
+++ b/clang/tools/driver/driver.cpp
@@ -321,25 +321,24 @@ int clang_main(int Argc, char **Argv, const llvm::ToolContext &ToolContext) {
                            .Case("-fintegrated-cc1", false)
                            .Default(UseNewCC1Process);
 
-  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts =
-      CreateAndPopulateDiagOpts(Args);
+  std::unique_ptr<DiagnosticOptions> DiagOpts = CreateAndPopulateDiagOpts(Args);
   // Driver's diagnostics don't use suppression mappings, so don't bother
   // parsing them. CC1 still receives full args, so this doesn't impact other
   // actions.
   DiagOpts->DiagnosticSuppressionMappingsFile.clear();
 
   TextDiagnosticPrinter *DiagClient
-    = new TextDiagnosticPrinter(llvm::errs(), &*DiagOpts);
+    = new TextDiagnosticPrinter(llvm::errs(), *DiagOpts);
   FixupDiagPrefixExeName(DiagClient, ProgName);
 
   IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
 
-  DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagClient);
+  DiagnosticsEngine Diags(DiagID, *DiagOpts, DiagClient);
 
   if (!DiagOpts->DiagnosticSerializationFile.empty()) {
     auto SerializedConsumer =
         clang::serialized_diags::create(DiagOpts->DiagnosticSerializationFile,
-                                        &*DiagOpts, /*MergeChildRecords=*/true);
+                                        *DiagOpts, /*MergeChildRecords=*/true);
     Diags.setClient(new ChainedDiagnosticConsumer(
         Diags.takeClient(), std::move(SerializedConsumer)));
   }

>From 5fa1d9b3a3dd7f2ce41a06c29a8c85980cedfa3c Mon Sep 17 00:00:00 2001
From: Jan Svoboda <jan_svoboda at apple.com>
Date: Mon, 12 May 2025 08:05:00 -0700
Subject: [PATCH 2/8] Make check-clang build

---
 clang/lib/Interpreter/Interpreter.cpp         |  8 +--
 clang/lib/Testing/TestAST.cpp                 |  2 +-
 clang/lib/Tooling/CompilationDatabase.cpp     |  6 +-
 .../DependencyScanningWorker.cpp              |  6 +-
 clang/lib/Tooling/Refactoring.cpp             |  6 +-
 clang/lib/Tooling/Tooling.cpp                 |  8 +--
 clang/tools/c-index-test/core_main.cpp        |  6 +-
 .../ClangExtDefMapGen.cpp                     | 12 ++--
 clang/tools/clang-format/ClangFormat.cpp      |  7 +-
 .../clang-import-test/clang-import-test.cpp   |  4 +-
 .../clang-installapi/ClangInstallAPI.cpp      |  8 +--
 clang/tools/clang-scan-deps/ClangScanDeps.cpp |  9 +--
 clang/tools/diagtool/ShowEnabledWarnings.cpp  |  5 +-
 clang/tools/diagtool/TreeView.cpp             |  4 +-
 clang/tools/libclang/CIndex.cpp               |  5 +-
 clang/tools/libclang/CIndexCodeCompletion.cpp |  6 +-
 clang/tools/libclang/CIndexDiagnostic.cpp     |  6 +-
 clang/tools/libclang/Indexing.cpp             |  3 +-
 clang/unittests/AST/ASTVectorTest.cpp         |  3 +-
 clang/unittests/AST/CommentLexer.cpp          |  3 +-
 clang/unittests/AST/CommentParser.cpp         |  3 +-
 clang/unittests/AST/CommentTextTest.cpp       |  3 +-
 clang/unittests/AST/ExternalASTSourceTest.cpp |  4 +-
 .../UncheckedOptionalAccessModelTest.cpp      |  5 +-
 .../Analysis/MacroExpansionContextTest.cpp    |  6 +-
 .../Analysis/UnsafeBufferUsageTest.cpp        |  3 +-
 clang/unittests/Basic/DiagnosticTest.cpp      | 21 ++++--
 clang/unittests/Basic/SarifTest.cpp           |  6 +-
 clang/unittests/Basic/SourceManagerTest.cpp   |  3 +-
 clang/unittests/Driver/DXCModeTest.cpp        | 12 ++--
 clang/unittests/Driver/SanitizerArgsTest.cpp  |  6 +-
 .../Driver/SimpleDiagnosticConsumer.h         |  5 +-
 clang/unittests/Driver/ToolChainTest.cpp      | 71 ++++++++++---------
 clang/unittests/Frontend/ASTUnitTest.cpp      |  9 +--
 .../Frontend/CompilerInstanceTest.cpp         |  9 +--
 .../Frontend/CompilerInvocationTest.cpp       |  3 +-
 clang/unittests/Frontend/OutputStreamTest.cpp |  8 +--
 clang/unittests/Frontend/PCHPreambleTest.cpp  |  3 +-
 .../Frontend/ReparseWorkingDirTest.cpp        |  3 +-
 clang/unittests/Frontend/SearchPathTest.cpp   |  4 +-
 .../unittests/Frontend/TextDiagnosticTest.cpp |  8 +--
 clang/unittests/Frontend/UtilsTest.cpp        |  9 +--
 .../unittests/Interpreter/InterpreterTest.cpp | 15 ++--
 clang/unittests/Lex/HeaderSearchTest.cpp      |  3 +-
 clang/unittests/Lex/LexerTest.cpp             |  3 +-
 clang/unittests/Lex/ModuleDeclStateTest.cpp   |  3 +-
 clang/unittests/Lex/PPCallbacksTest.cpp       |  8 +--
 .../Lex/PPConditionalDirectiveRecordTest.cpp  |  3 +-
 .../Lex/PPDependencyDirectivesTest.cpp        |  3 +-
 .../unittests/Lex/PPMemoryAllocationsTest.cpp |  3 +-
 .../Parse/ParseHLSLRootSignatureTest.cpp      |  3 +-
 clang/unittests/Sema/SemaNoloadLookupTest.cpp |  4 +-
 .../Serialization/ForceCheckFileInputTest.cpp |  8 +--
 .../Serialization/LoadSpecLazilyTest.cpp      |  3 +-
 .../Serialization/ModuleCacheTest.cpp         |  6 +-
 .../Serialization/NoCommentsTest.cpp          |  3 +-
 .../PreambleInNamedModulesTest.cpp            |  3 +-
 .../Serialization/VarDeclConstantInitTest.cpp |  3 +-
 clang/unittests/Support/TimeProfilerTest.cpp  |  4 +-
 clang/unittests/Tooling/RewriterTestContext.h |  7 +-
 clang/unittests/Tooling/Syntax/TokensTest.cpp |  3 +-
 .../unittests/Tooling/Syntax/TreeTestBase.cpp |  2 +-
 clang/unittests/Tooling/Syntax/TreeTestBase.h |  4 +-
 clang/unittests/Tooling/ToolingTest.cpp       |  8 +--
 64 files changed, 233 insertions(+), 190 deletions(-)

diff --git a/clang/lib/Interpreter/Interpreter.cpp b/clang/lib/Interpreter/Interpreter.cpp
index c04b2099a4b9a..4ced33410137e 100644
--- a/clang/lib/Interpreter/Interpreter.cpp
+++ b/clang/lib/Interpreter/Interpreter.cpp
@@ -95,9 +95,9 @@ CreateCI(const llvm::opt::ArgStringList &Argv) {
 
   // Buffer diagnostics from argument parsing so that we can output them using
   // a well formed diagnostic object.
-  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
+  DiagnosticOptions DiagOpts;
   TextDiagnosticBuffer *DiagsBuffer = new TextDiagnosticBuffer;
-  DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagsBuffer);
+  DiagnosticsEngine Diags(DiagID, DiagOpts, DiagsBuffer);
   bool Success = CompilerInvocation::CreateFromArgs(
       Clang->getInvocation(), llvm::ArrayRef(Argv.begin(), Argv.size()), Diags);
 
@@ -173,10 +173,10 @@ IncrementalCompilerBuilder::create(std::string TT,
   // Buffer diagnostics from argument parsing so that we can output them using a
   // well formed diagnostic object.
   IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
-  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts =
+  std::unique_ptr<DiagnosticOptions> DiagOpts =
       CreateAndPopulateDiagOpts(ClangArgv);
   TextDiagnosticBuffer *DiagsBuffer = new TextDiagnosticBuffer;
-  DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagsBuffer);
+  DiagnosticsEngine Diags(DiagID, *DiagOpts, DiagsBuffer);
 
   driver::Driver Driver(/*MainBinaryName=*/ClangArgv[0], TT, Diags);
   Driver.setCheckInputsExist(false); // the input comes from mem buffers
diff --git a/clang/lib/Testing/TestAST.cpp b/clang/lib/Testing/TestAST.cpp
index 748f59b856e83..b59a8d55129de 100644
--- a/clang/lib/Testing/TestAST.cpp
+++ b/clang/lib/Testing/TestAST.cpp
@@ -44,7 +44,7 @@ class StoreDiagnostics : public DiagnosticConsumer {
       std::string Text;
       llvm::raw_string_ostream OS(Text);
       TextDiagnostic Renderer(OS, LangOpts,
-                              &Info.getDiags()->getDiagnosticOptions());
+                              Info.getDiags()->getDiagnosticOptions());
       Renderer.emitStoredDiagnostic(Out.back());
       ADD_FAILURE() << Text;
     }
diff --git a/clang/lib/Tooling/CompilationDatabase.cpp b/clang/lib/Tooling/CompilationDatabase.cpp
index af18194ae0fe4..9c7827c4f85dd 100644
--- a/clang/lib/Tooling/CompilationDatabase.cpp
+++ b/clang/lib/Tooling/CompilationDatabase.cpp
@@ -243,13 +243,13 @@ std::string GetClangToolCommand() {
 static bool stripPositionalArgs(std::vector<const char *> Args,
                                 std::vector<std::string> &Result,
                                 std::string &ErrorMsg) {
-  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
+  DiagnosticOptions DiagOpts;
   llvm::raw_string_ostream Output(ErrorMsg);
-  TextDiagnosticPrinter DiagnosticPrinter(Output, &*DiagOpts);
+  TextDiagnosticPrinter DiagnosticPrinter(Output, DiagOpts);
   UnusedInputDiagConsumer DiagClient(DiagnosticPrinter);
   DiagnosticsEngine Diagnostics(
       IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()),
-      &*DiagOpts, &DiagClient, false);
+      DiagOpts, &DiagClient, false);
 
   // The clang executable path isn't required since the jobs the driver builds
   // will not be executed.
diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
index 21eea72b198b3..207b0a96aaf27 100644
--- a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
+++ b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
@@ -642,7 +642,7 @@ llvm::Error DependencyScanningWorker::computeDependencies(
   std::string DiagnosticOutput;
   llvm::raw_string_ostream DiagnosticsOS(DiagnosticOutput);
   auto DiagOpts = createDiagOptions(CommandLine);
-  TextDiagnosticPrinter DiagPrinter(DiagnosticsOS, DiagOpts.release());
+  TextDiagnosticPrinter DiagPrinter(DiagnosticsOS, *DiagOpts);
 
   if (computeDependencies(WorkingDirectory, CommandLine, Consumer, Controller,
                           DiagPrinter, TUBuffer))
@@ -660,7 +660,7 @@ llvm::Error DependencyScanningWorker::computeDependencies(
   std::string DiagnosticOutput;
   llvm::raw_string_ostream DiagnosticsOS(DiagnosticOutput);
   auto DiagOpts = createDiagOptions(CommandLine);
-  TextDiagnosticPrinter DiagPrinter(DiagnosticsOS, DiagOpts.release());
+  TextDiagnosticPrinter DiagPrinter(DiagnosticsOS, *DiagOpts);
 
   if (computeDependencies(WorkingDirectory, CommandLine, Consumer, Controller,
                           DiagPrinter, ModuleName))
@@ -744,7 +744,7 @@ bool DependencyScanningWorker::scanDependencies(
   sanitizeDiagOpts(*DiagOpts);
   IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
       CompilerInstance::createDiagnostics(FileMgr->getVirtualFileSystem(),
-                                          DiagOpts.release(), &DC,
+                                          *DiagOpts, &DC,
                                           /*ShouldOwnClient=*/false);
 
   // Although `Diagnostics` are used only for command-line parsing, the
diff --git a/clang/lib/Tooling/Refactoring.cpp b/clang/lib/Tooling/Refactoring.cpp
index 961fc1c180154..43ae68052d137 100644
--- a/clang/lib/Tooling/Refactoring.cpp
+++ b/clang/lib/Tooling/Refactoring.cpp
@@ -39,11 +39,11 @@ int RefactoringTool::runAndSave(FrontendActionFactory *ActionFactory) {
   }
 
   LangOptions DefaultLangOptions;
-  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
-  TextDiagnosticPrinter DiagnosticPrinter(llvm::errs(), &*DiagOpts);
+  DiagnosticOptions DiagOpts;
+  TextDiagnosticPrinter DiagnosticPrinter(llvm::errs(), DiagOpts);
   DiagnosticsEngine Diagnostics(
       IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()),
-      &*DiagOpts, &DiagnosticPrinter, false);
+      DiagOpts, &DiagnosticPrinter, false);
   SourceManager Sources(Diagnostics, getFiles());
   Rewriter Rewrite(Sources, DefaultLangOptions);
 
diff --git a/clang/lib/Tooling/Tooling.cpp b/clang/lib/Tooling/Tooling.cpp
index 3c72f52040142..0f8da8b260292 100644
--- a/clang/lib/Tooling/Tooling.cpp
+++ b/clang/lib/Tooling/Tooling.cpp
@@ -377,17 +377,17 @@ bool ToolInvocation::run() {
 
   // Parse diagnostic options from the driver command-line only if none were
   // explicitly set.
-  IntrusiveRefCntPtr<DiagnosticOptions> ParsedDiagOpts;
+  std::unique_ptr<DiagnosticOptions> ParsedDiagOpts;
   DiagnosticOptions *DiagOpts = this->DiagOpts;
   if (!DiagOpts) {
     ParsedDiagOpts = CreateAndPopulateDiagOpts(Argv);
     DiagOpts = &*ParsedDiagOpts;
   }
 
-  TextDiagnosticPrinter DiagnosticPrinter(llvm::errs(), DiagOpts);
+  TextDiagnosticPrinter DiagnosticPrinter(llvm::errs(), *DiagOpts);
   IntrusiveRefCntPtr<DiagnosticsEngine> Diagnostics =
       CompilerInstance::createDiagnostics(
-          Files->getVirtualFileSystem(), &*DiagOpts,
+          Files->getVirtualFileSystem(), *DiagOpts,
           DiagConsumer ? DiagConsumer : &DiagnosticPrinter, false);
   // Although `Diagnostics` are used only for command-line parsing, the custom
   // `DiagConsumer` might expect a `SourceManager` to be present.
@@ -654,7 +654,7 @@ class ASTBuilderAction : public ToolAction {
     std::unique_ptr<ASTUnit> AST = ASTUnit::LoadFromCompilerInvocation(
         Invocation, std::move(PCHContainerOps),
         CompilerInstance::createDiagnostics(Files->getVirtualFileSystem(),
-                                            &Invocation->getDiagnosticOpts(),
+                                            Invocation->getDiagnosticOpts(),
                                             DiagConsumer,
                                             /*ShouldOwnClient=*/false),
         Files);
diff --git a/clang/tools/c-index-test/core_main.cpp b/clang/tools/c-index-test/core_main.cpp
index 8d023a0b22121..27f62cba2e713 100644
--- a/clang/tools/c-index-test/core_main.cpp
+++ b/clang/tools/c-index-test/core_main.cpp
@@ -220,9 +220,10 @@ static bool printSourceSymbols(const char *Executable,
   SmallVector<const char *, 4> ArgsWithProgName;
   ArgsWithProgName.push_back(Executable);
   ArgsWithProgName.append(Args.begin(), Args.end());
+  DiagnosticOptions DiagOpts;
   IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
       CompilerInstance::createDiagnostics(*llvm::vfs::getRealFileSystem(),
-                                          new DiagnosticOptions));
+                                          DiagOpts));
   CreateInvocationOptions CIOpts;
   CIOpts.Diags = Diags;
   CIOpts.ProbePrecompiled = true; // FIXME: historical default. Needed?
@@ -274,9 +275,10 @@ static bool printSourceSymbolsFromModule(StringRef modulePath,
 
   HeaderSearchOptions HSOpts;
 
+  DiagnosticOptions DiagOpts;
   IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
       CompilerInstance::createDiagnostics(*llvm::vfs::getRealFileSystem(),
-                                          new DiagnosticOptions());
+                                          DiagOpts);
   std::unique_ptr<ASTUnit> AU =
       ASTUnit::LoadFromASTFile(modulePath, *pchRdr, ASTUnit::LoadASTOnly, Diags,
                                FileSystemOpts, HSOpts, /*LangOpts=*/nullptr,
diff --git a/clang/tools/clang-extdef-mapping/ClangExtDefMapGen.cpp b/clang/tools/clang-extdef-mapping/ClangExtDefMapGen.cpp
index ff684d20c150c..016e50737da7b 100644
--- a/clang/tools/clang-extdef-mapping/ClangExtDefMapGen.cpp
+++ b/clang/tools/clang-extdef-mapping/ClangExtDefMapGen.cpp
@@ -123,21 +123,21 @@ static cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage);
 
 static IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
 
-IntrusiveRefCntPtr<DiagnosticsEngine> GetDiagnosticsEngine() {
+IntrusiveRefCntPtr<DiagnosticsEngine>
+GetDiagnosticsEngine(DiagnosticOptions &DiagOpts) {
   if (Diags) {
     // Call reset to make sure we don't mix errors
     Diags->Reset(false);
     return Diags;
   }
 
-  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
   TextDiagnosticPrinter *DiagClient =
-      new TextDiagnosticPrinter(llvm::errs(), &*DiagOpts);
+      new TextDiagnosticPrinter(llvm::errs(), DiagOpts);
   DiagClient->setPrefix("clang-extdef-mappping");
   IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
 
   IntrusiveRefCntPtr<DiagnosticsEngine> DiagEngine(
-      new DiagnosticsEngine(DiagID, &*DiagOpts, DiagClient));
+      new DiagnosticsEngine(DiagID, DiagOpts, DiagClient));
   Diags.swap(DiagEngine);
 
   // Retain this one time so it's not destroyed by ASTUnit::LoadFromASTFile
@@ -152,7 +152,9 @@ static bool HandleAST(StringRef AstPath) {
   if (!CI)
     CI = new CompilerInstance();
 
-  IntrusiveRefCntPtr<DiagnosticsEngine> DiagEngine = GetDiagnosticsEngine();
+  DiagnosticOptions DiagOpts;
+  IntrusiveRefCntPtr<DiagnosticsEngine> DiagEngine =
+      GetDiagnosticsEngine(DiagOpts);
 
   std::unique_ptr<ASTUnit> Unit = ASTUnit::LoadFromASTFile(
       AstPath, CI->getPCHContainerOperations()->getRawReader(),
diff --git a/clang/tools/clang-format/ClangFormat.cpp b/clang/tools/clang-format/ClangFormat.cpp
index c45e3a2c28327..ed096e3a37111 100644
--- a/clang/tools/clang-format/ClangFormat.cpp
+++ b/clang/tools/clang-format/ClangFormat.cpp
@@ -240,9 +240,10 @@ static bool fillRanges(MemoryBuffer *Code,
   IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem(
       new llvm::vfs::InMemoryFileSystem);
   FileManager Files(FileSystemOptions(), InMemoryFileSystem);
+  DiagnosticOptions DiagOpts;
   DiagnosticsEngine Diagnostics(
       IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),
-      new DiagnosticOptions);
+      DiagOpts);
   SourceManager Sources(Diagnostics, Files);
   FileID ID = createInMemoryFile("<irrelevant>", *Code, Sources, Files,
                                  InMemoryFileSystem.get());
@@ -520,10 +521,10 @@ static bool format(StringRef FileName, bool ErrorOnIncompleteFormat = false) {
         new llvm::vfs::InMemoryFileSystem);
     FileManager Files(FileSystemOptions(), InMemoryFileSystem);
 
-    IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts(new DiagnosticOptions());
+    DiagnosticOptions DiagOpts;
     ClangFormatDiagConsumer IgnoreDiagnostics;
     DiagnosticsEngine Diagnostics(
-        IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs), &*DiagOpts,
+        IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs), DiagOpts,
         &IgnoreDiagnostics, false);
     SourceManager Sources(Diagnostics, Files);
     FileID ID = createInMemoryFile(AssumedFileName, *Code, Sources, Files,
diff --git a/clang/tools/clang-import-test/clang-import-test.cpp b/clang/tools/clang-import-test/clang-import-test.cpp
index 765f342947046..aefc2f5728eda 100644
--- a/clang/tools/clang-import-test/clang-import-test.cpp
+++ b/clang/tools/clang-import-test/clang-import-test.cpp
@@ -162,10 +162,10 @@ class TestDiagnosticConsumer : public DiagnosticConsumer {
 };
 
 std::unique_ptr<CompilerInstance> BuildCompilerInstance() {
-  auto DiagOpts = llvm::makeIntrusiveRefCnt<DiagnosticOptions>();
+  DiagnosticOptions DiagOpts;
   auto DC = std::make_unique<TestDiagnosticConsumer>();
   auto Diags = CompilerInstance::createDiagnostics(
-      *llvm::vfs::getRealFileSystem(), DiagOpts.get(), DC.get(),
+      *llvm::vfs::getRealFileSystem(), DiagOpts, DC.get(),
       /*ShouldOwnClient=*/false);
 
   auto Inv = std::make_unique<CompilerInvocation>();
diff --git a/clang/tools/clang-installapi/ClangInstallAPI.cpp b/clang/tools/clang-installapi/ClangInstallAPI.cpp
index 14e7b53d74b09..f68236abaa6c9 100644
--- a/clang/tools/clang-installapi/ClangInstallAPI.cpp
+++ b/clang/tools/clang-installapi/ClangInstallAPI.cpp
@@ -70,16 +70,16 @@ static bool runFrontend(StringRef ProgName, Twine Label, bool Verbose,
 
 static bool run(ArrayRef<const char *> Args, const char *ProgName) {
   // Setup Diagnostics engine.
-  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
+  DiagnosticOptions DiagOpts;
   const llvm::opt::OptTable &ClangOpts = clang::driver::getDriverOptTable();
   unsigned MissingArgIndex, MissingArgCount;
   llvm::opt::InputArgList ParsedArgs = ClangOpts.ParseArgs(
       ArrayRef(Args).slice(1), MissingArgIndex, MissingArgCount);
-  ParseDiagnosticArgs(*DiagOpts, ParsedArgs);
+  ParseDiagnosticArgs(DiagOpts, ParsedArgs);
 
   IntrusiveRefCntPtr<DiagnosticsEngine> Diag = new clang::DiagnosticsEngine(
-      new clang::DiagnosticIDs(), DiagOpts.get(),
-      new clang::TextDiagnosticPrinter(llvm::errs(), DiagOpts.get()));
+      new clang::DiagnosticIDs(), DiagOpts,
+      new clang::TextDiagnosticPrinter(llvm::errs(), DiagOpts));
 
   // Create file manager for all file operations and holding in-memory generated
   // inputs.
diff --git a/clang/tools/clang-scan-deps/ClangScanDeps.cpp b/clang/tools/clang-scan-deps/ClangScanDeps.cpp
index dae2b9a9fe683..eccea1be008df 100644
--- a/clang/tools/clang-scan-deps/ClangScanDeps.cpp
+++ b/clang/tools/clang-scan-deps/ClangScanDeps.cpp
@@ -449,11 +449,11 @@ class FullDeps {
   // Returns \c true if any command lines fail to round-trip. We expect
   // commands already be canonical when output by the scanner.
   bool roundTripCommands(raw_ostream &ErrOS) {
-    IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions{};
-    TextDiagnosticPrinter DiagConsumer(ErrOS, &*DiagOpts);
+    DiagnosticOptions DiagOpts;
+    TextDiagnosticPrinter DiagConsumer(ErrOS, DiagOpts);
     IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
         CompilerInstance::createDiagnostics(*llvm::vfs::getRealFileSystem(),
-                                            &*DiagOpts, &DiagConsumer,
+                                            DiagOpts, &DiagConsumer,
                                             /*ShouldOwnClient=*/false);
 
     for (auto &&M : Modules)
@@ -771,9 +771,10 @@ getCompilationDatabase(int argc, char **argv, std::string &ErrorMessage) {
         CompilationDB, ErrorMessage,
         tooling::JSONCommandLineSyntax::AutoDetect);
 
+  DiagnosticOptions DiagOpts;
   llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
       CompilerInstance::createDiagnostics(*llvm::vfs::getRealFileSystem(),
-                                          new DiagnosticOptions);
+                                          DiagOpts);
   driver::Driver TheDriver(CommandLine[0], llvm::sys::getDefaultTargetTriple(),
                            *Diags);
   TheDriver.setCheckInputsExist(false);
diff --git a/clang/tools/diagtool/ShowEnabledWarnings.cpp b/clang/tools/diagtool/ShowEnabledWarnings.cpp
index 1f32f791de082..6b4136c32f23f 100644
--- a/clang/tools/diagtool/ShowEnabledWarnings.cpp
+++ b/clang/tools/diagtool/ShowEnabledWarnings.cpp
@@ -56,6 +56,7 @@ static char getCharForLevel(DiagnosticsEngine::Level Level) {
 static IntrusiveRefCntPtr<DiagnosticsEngine>
 createDiagnostics(unsigned int argc, char **argv) {
   IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(new DiagnosticIDs());
+  DiagnosticOptions DiagOpts;
 
   // Buffer diagnostics from argument parsing so that we can output them using a
   // well formed diagnostic object.
@@ -67,7 +68,7 @@ createDiagnostics(unsigned int argc, char **argv) {
   Args.append(argv, argv + argc);
   CreateInvocationOptions CIOpts;
   CIOpts.Diags =
-      new DiagnosticsEngine(DiagIDs, new DiagnosticOptions(), DiagsBuffer);
+      new DiagnosticsEngine(DiagIDs, DiagOpts, DiagsBuffer);
   std::unique_ptr<CompilerInvocation> Invocation =
       createInvocation(Args, CIOpts);
   if (!Invocation)
@@ -76,7 +77,7 @@ createDiagnostics(unsigned int argc, char **argv) {
   // Build the diagnostics parser
   IntrusiveRefCntPtr<DiagnosticsEngine> FinalDiags =
       CompilerInstance::createDiagnostics(*llvm::vfs::getRealFileSystem(),
-                                          &Invocation->getDiagnosticOpts());
+                                          Invocation->getDiagnosticOpts());
   if (!FinalDiags)
     return nullptr;
 
diff --git a/clang/tools/diagtool/TreeView.cpp b/clang/tools/diagtool/TreeView.cpp
index 8d1ce14b0f520..7e47c748af959 100644
--- a/clang/tools/diagtool/TreeView.cpp
+++ b/clang/tools/diagtool/TreeView.cpp
@@ -31,8 +31,8 @@ class TreePrinter {
 
   static bool isIgnored(unsigned DiagID) {
     // FIXME: This feels like a hack.
-    static clang::DiagnosticsEngine Diags(new DiagnosticIDs,
-                                          new DiagnosticOptions);
+    static DiagnosticOptions DiagOpts;
+    static clang::DiagnosticsEngine Diags(new DiagnosticIDs, DiagOpts);
     return Diags.isIgnored(DiagID, SourceLocation());
   }
 
diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp
index fa5df3b5a06e6..6ab078a997e17 100644
--- a/clang/tools/libclang/CIndex.cpp
+++ b/clang/tools/libclang/CIndex.cpp
@@ -4227,9 +4227,10 @@ enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
   FileSystemOptions FileSystemOpts;
   HeaderSearchOptions HSOpts;
 
+  DiagnosticOptions DiagOpts;
   IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
       CompilerInstance::createDiagnostics(*llvm::vfs::getRealFileSystem(),
-                                          new DiagnosticOptions());
+                                          DiagOpts);
   std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
       ast_filename, CXXIdx->getPCHContainerOperations()->getRawReader(),
       ASTUnit::LoadEverything, Diags, FileSystemOpts, HSOpts,
@@ -4303,7 +4304,7 @@ clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
       llvm::ArrayRef(command_line_args, num_command_line_args));
   IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
       CompilerInstance::createDiagnostics(*llvm::vfs::getRealFileSystem(),
-                                          DiagOpts.release()));
+                                          *DiagOpts));
 
   if (options & CXTranslationUnit_KeepGoing)
     Diags->setFatalsAsError(true);
diff --git a/clang/tools/libclang/CIndexCodeCompletion.cpp b/clang/tools/libclang/CIndexCodeCompletion.cpp
index 850c004680fd9..c7c70b51e7f63 100644
--- a/clang/tools/libclang/CIndexCodeCompletion.cpp
+++ b/clang/tools/libclang/CIndexCodeCompletion.cpp
@@ -256,7 +256,7 @@ struct AllocatedCXCodeCompleteResults : public CXCodeCompleteResults {
   /// Allocated API-exposed wrappters for Diagnostics.
   SmallVector<std::unique_ptr<CXStoredDiagnostic>, 8> DiagnosticsWrappers;
 
-  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
+  DiagnosticOptions DiagOpts;
   
   /// Diag object
   IntrusiveRefCntPtr<DiagnosticsEngine> Diag;
@@ -356,9 +356,9 @@ static std::atomic<unsigned> CodeCompletionResultObjects;
 
 AllocatedCXCodeCompleteResults::AllocatedCXCodeCompleteResults(
     IntrusiveRefCntPtr<FileManager> FileMgr)
-    : CXCodeCompleteResults(), DiagOpts(new DiagnosticOptions),
+    : CXCodeCompleteResults(),
       Diag(new DiagnosticsEngine(
-          IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs), &*DiagOpts)),
+          IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs), DiagOpts)),
       FileMgr(std::move(FileMgr)),
       SourceMgr(new SourceManager(*Diag, *this->FileMgr)),
       CodeCompletionAllocator(
diff --git a/clang/tools/libclang/CIndexDiagnostic.cpp b/clang/tools/libclang/CIndexDiagnostic.cpp
index 92271d9c37f86..b6fdb71b6acc3 100644
--- a/clang/tools/libclang/CIndexDiagnostic.cpp
+++ b/clang/tools/libclang/CIndexDiagnostic.cpp
@@ -82,7 +82,7 @@ class CXDiagnosticCustomNoteImpl : public CXDiagnosticImpl {
 class CXDiagnosticRenderer : public DiagnosticNoteRenderer {
 public:  
   CXDiagnosticRenderer(const LangOptions &LangOpts,
-                       DiagnosticOptions *DiagOpts,
+                       DiagnosticOptions &DiagOpts,
                        CXDiagnosticSetImpl *mainSet)
   : DiagnosticNoteRenderer(LangOpts, DiagOpts),
     CurrentSet(mainSet), MainSet(mainSet) {}
@@ -182,9 +182,9 @@ CXDiagnosticSetImpl *cxdiag::lazyCreateDiags(CXTranslationUnit TU,
   if (!TU->Diagnostics) {
     CXDiagnosticSetImpl *Set = new CXDiagnosticSetImpl();
     TU->Diagnostics = Set;
-    IntrusiveRefCntPtr<DiagnosticOptions> DOpts = new DiagnosticOptions;
+    DiagnosticOptions DOpts;
     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/clang/tools/libclang/Indexing.cpp b/clang/tools/libclang/Indexing.cpp
index e1441bce15f88..ccea99984abc9 100644
--- a/clang/tools/libclang/Indexing.cpp
+++ b/clang/tools/libclang/Indexing.cpp
@@ -480,9 +480,10 @@ static CXErrorCode clang_indexSourceFile_Impl(
     CaptureDiag = new CaptureDiagnosticConsumer();
 
   // Configure the diagnostics.
+  DiagnosticOptions DiagOpts;
   IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
       CompilerInstance::createDiagnostics(*llvm::vfs::getRealFileSystem(),
-                                          new DiagnosticOptions, CaptureDiag,
+                                          DiagOpts, CaptureDiag,
                                           /*ShouldOwnClient=*/true));
 
   // Recover resources if we crash before exiting this function.
diff --git a/clang/unittests/AST/ASTVectorTest.cpp b/clang/unittests/AST/ASTVectorTest.cpp
index 1c17eb9210ac3..66003b49eccb2 100644
--- a/clang/unittests/AST/ASTVectorTest.cpp
+++ b/clang/unittests/AST/ASTVectorTest.cpp
@@ -27,13 +27,14 @@ class ASTVectorTest : public ::testing::Test {
 protected:
   ASTVectorTest()
       : FileMgr(FileMgrOpts), DiagID(new DiagnosticIDs()),
-        Diags(DiagID, new DiagnosticOptions, new IgnoringDiagConsumer()),
+        Diags(DiagID, DiagOpts, new IgnoringDiagConsumer()),
         SourceMgr(Diags, FileMgr), Idents(LangOpts, nullptr),
         Ctxt(LangOpts, SourceMgr, Idents, Sels, Builtins, TU_Complete) {}
 
   FileSystemOptions FileMgrOpts;
   FileManager FileMgr;
   IntrusiveRefCntPtr<DiagnosticIDs> DiagID;
+  DiagnosticOptions DiagOpts;
   DiagnosticsEngine Diags;
   SourceManager SourceMgr;
   LangOptions LangOpts;
diff --git a/clang/unittests/AST/CommentLexer.cpp b/clang/unittests/AST/CommentLexer.cpp
index 22866f0eb23ed..97d6bcfd6c5a6 100644
--- a/clang/unittests/AST/CommentLexer.cpp
+++ b/clang/unittests/AST/CommentLexer.cpp
@@ -29,7 +29,7 @@ class CommentLexerTest : public ::testing::Test {
   CommentLexerTest()
     : FileMgr(FileMgrOpts),
       DiagID(new DiagnosticIDs()),
-      Diags(DiagID, new DiagnosticOptions, new IgnoringDiagConsumer()),
+      Diags(DiagID, DiagOpts, new IgnoringDiagConsumer()),
       SourceMgr(Diags, FileMgr),
       Traits(Allocator, CommentOptions()) {
   }
@@ -37,6 +37,7 @@ class CommentLexerTest : public ::testing::Test {
   FileSystemOptions FileMgrOpts;
   FileManager FileMgr;
   IntrusiveRefCntPtr<DiagnosticIDs> DiagID;
+  DiagnosticOptions DiagOpts;
   DiagnosticsEngine Diags;
   SourceManager SourceMgr;
   llvm::BumpPtrAllocator Allocator;
diff --git a/clang/unittests/AST/CommentParser.cpp b/clang/unittests/AST/CommentParser.cpp
index aa08b6718e506..c82e8dc5eeba7 100644
--- a/clang/unittests/AST/CommentParser.cpp
+++ b/clang/unittests/AST/CommentParser.cpp
@@ -35,7 +35,7 @@ class CommentParserTest : public ::testing::Test {
   CommentParserTest()
     : FileMgr(FileMgrOpts),
       DiagID(new DiagnosticIDs()),
-      Diags(DiagID, new DiagnosticOptions, new IgnoringDiagConsumer()),
+      Diags(DiagID, DiagOpts, new IgnoringDiagConsumer()),
       SourceMgr(Diags, FileMgr),
       Traits(Allocator, CommentOptions()) {
   }
@@ -43,6 +43,7 @@ class CommentParserTest : public ::testing::Test {
   FileSystemOptions FileMgrOpts;
   FileManager FileMgr;
   IntrusiveRefCntPtr<DiagnosticIDs> DiagID;
+  DiagnosticOptions DiagOpts;
   DiagnosticsEngine Diags;
   SourceManager SourceMgr;
   llvm::BumpPtrAllocator Allocator;
diff --git a/clang/unittests/AST/CommentTextTest.cpp b/clang/unittests/AST/CommentTextTest.cpp
index b697828698d85..84ec51a308360 100644
--- a/clang/unittests/AST/CommentTextTest.cpp
+++ b/clang/unittests/AST/CommentTextTest.cpp
@@ -43,7 +43,8 @@ class CommentTextTest : public ::testing::Test {
     // FIXME: technically, merged that we set here is incorrect, but that
     // shouldn't matter.
     RawComment Comment(SourceMgr, CommentRange, EmptyOpts, /*Merged=*/true);
-    DiagnosticsEngine Diags(new DiagnosticIDs, new DiagnosticOptions);
+    DiagnosticOptions DiagOpts;
+    DiagnosticsEngine Diags(new DiagnosticIDs, DiagOpts);
     return Comment.getFormattedText(SourceMgr, Diags);
   }
 };
diff --git a/clang/unittests/AST/ExternalASTSourceTest.cpp b/clang/unittests/AST/ExternalASTSourceTest.cpp
index 807bab1b3dd81..11715bb8ce7cd 100644
--- a/clang/unittests/AST/ExternalASTSourceTest.cpp
+++ b/clang/unittests/AST/ExternalASTSourceTest.cpp
@@ -51,9 +51,9 @@ bool testExternalASTSource(ExternalASTSource *Source, StringRef FileContents) {
       "test.cc", MemoryBuffer::getMemBuffer(FileContents).release());
   const char *Args[] = { "test.cc" };
 
-  auto InvocationDiagOpts = llvm::makeIntrusiveRefCnt<DiagnosticOptions>();
+  DiagnosticOptions InvocationDiagOpts;
   auto InvocationDiags = CompilerInstance::createDiagnostics(
-      *llvm::vfs::getRealFileSystem(), InvocationDiagOpts.get());
+      *llvm::vfs::getRealFileSystem(), InvocationDiagOpts);
   CompilerInvocation::CreateFromArgs(*Invocation, Args, *InvocationDiags);
 
   CompilerInstance Compiler(std::move(Invocation));
diff --git a/clang/unittests/Analysis/FlowSensitive/UncheckedOptionalAccessModelTest.cpp b/clang/unittests/Analysis/FlowSensitive/UncheckedOptionalAccessModelTest.cpp
index 6f69ccbd36552..1dd07834bfd7e 100644
--- a/clang/unittests/Analysis/FlowSensitive/UncheckedOptionalAccessModelTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/UncheckedOptionalAccessModelTest.cpp
@@ -1388,10 +1388,9 @@ class UncheckedOptionalAccessTest
             unsigned Line = SrcMgr.getPresumedLineNumber(Diag.Range.getBegin());
             DiagnosticLines.insert(Line);
             if (!AnnotationLines.contains(Line)) {
-              IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts(
-                  new DiagnosticOptions());
+              DiagnosticOptions DiagOpts;
               TextDiagnostic TD(llvm::errs(), AO.ASTCtx.getLangOpts(),
-                                DiagOpts.get());
+                                DiagOpts);
               TD.emitDiagnostic(FullSourceLoc(Diag.Range.getBegin(), SrcMgr),
                                 DiagnosticsEngine::Error,
                                 "unexpected diagnostic", {Diag.Range}, {});
diff --git a/clang/unittests/Analysis/MacroExpansionContextTest.cpp b/clang/unittests/Analysis/MacroExpansionContextTest.cpp
index 929d4122cdec7..9874ea687f3ed 100644
--- a/clang/unittests/Analysis/MacroExpansionContextTest.cpp
+++ b/clang/unittests/Analysis/MacroExpansionContextTest.cpp
@@ -35,8 +35,8 @@ class MacroExpansionContextTest : public ::testing::Test {
   MacroExpansionContextTest()
       : InMemoryFileSystem(new llvm::vfs::InMemoryFileSystem),
         FileMgr(FileSystemOptions(), InMemoryFileSystem),
-        DiagID(new DiagnosticIDs()), DiagOpts(new DiagnosticOptions()),
-        Diags(DiagID, DiagOpts.get(), new IgnoringDiagConsumer()),
+        DiagID(new DiagnosticIDs()),
+        Diags(DiagID, DiagOpts, new IgnoringDiagConsumer()),
         SourceMgr(Diags, FileMgr), TargetOpts(new TargetOptions()) {
     TargetOpts->Triple = "x86_64-pc-linux-unknown";
     Target = TargetInfo::CreateTargetInfo(Diags, *TargetOpts);
@@ -46,7 +46,7 @@ class MacroExpansionContextTest : public ::testing::Test {
   IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem;
   FileManager FileMgr;
   IntrusiveRefCntPtr<DiagnosticIDs> DiagID;
-  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
+  DiagnosticOptions DiagOpts;
   DiagnosticsEngine Diags;
   SourceManager SourceMgr;
   LangOptions LangOpts;
diff --git a/clang/unittests/Analysis/UnsafeBufferUsageTest.cpp b/clang/unittests/Analysis/UnsafeBufferUsageTest.cpp
index e48f39bf13f44..9da2c58970b84 100644
--- a/clang/unittests/Analysis/UnsafeBufferUsageTest.cpp
+++ b/clang/unittests/Analysis/UnsafeBufferUsageTest.cpp
@@ -13,12 +13,13 @@ class UnsafeBufferUsageTest : public ::testing::Test {
 protected:
   UnsafeBufferUsageTest()
       : FileMgr(FileMgrOpts), DiagID(new DiagnosticIDs()),
-        Diags(DiagID, new DiagnosticOptions, new IgnoringDiagConsumer()),
+        Diags(DiagID, DiagOpts, new IgnoringDiagConsumer()),
         SourceMgr(Diags, FileMgr) {}
 
   FileSystemOptions FileMgrOpts;
   FileManager FileMgr;
   IntrusiveRefCntPtr<DiagnosticIDs> DiagID;
+  DiagnosticOptions DiagOpts;
   DiagnosticsEngine Diags;
   SourceManager SourceMgr;
 };
diff --git a/clang/unittests/Basic/DiagnosticTest.cpp b/clang/unittests/Basic/DiagnosticTest.cpp
index 88fa1800f0ff2..19d063abee96b 100644
--- a/clang/unittests/Basic/DiagnosticTest.cpp
+++ b/clang/unittests/Basic/DiagnosticTest.cpp
@@ -46,8 +46,9 @@ using testing::IsEmpty;
 
 // Check that DiagnosticErrorTrap works with SuppressAllDiagnostics.
 TEST(DiagnosticTest, suppressAndTrap) {
+  DiagnosticOptions DiagOpts;
   DiagnosticsEngine Diags(new DiagnosticIDs(),
-                          new DiagnosticOptions,
+                          DiagOpts,
                           new IgnoringDiagConsumer());
   Diags.setSuppressAllDiagnostics(true);
 
@@ -77,8 +78,9 @@ TEST(DiagnosticTest, suppressAndTrap) {
 // Check that FatalsAsError works as intended
 TEST(DiagnosticTest, fatalsAsError) {
   for (unsigned FatalsAsError = 0; FatalsAsError != 2; ++FatalsAsError) {
+    DiagnosticOptions DiagOpts;
     DiagnosticsEngine Diags(new DiagnosticIDs(),
-                            new DiagnosticOptions,
+                            DiagOpts,
                             new IgnoringDiagConsumer());
     Diags.setFatalsAsError(FatalsAsError);
 
@@ -101,7 +103,8 @@ TEST(DiagnosticTest, fatalsAsError) {
 }
 
 TEST(DiagnosticTest, tooManyErrorsIsAlwaysFatal) {
-  DiagnosticsEngine Diags(new DiagnosticIDs(), new DiagnosticOptions,
+  DiagnosticOptions DiagOpts;
+  DiagnosticsEngine Diags(new DiagnosticIDs(), DiagOpts,
                           new IgnoringDiagConsumer());
   Diags.setFatalsAsError(true);
 
@@ -117,7 +120,8 @@ TEST(DiagnosticTest, tooManyErrorsIsAlwaysFatal) {
 
 // Check that soft RESET works as intended
 TEST(DiagnosticTest, softReset) {
-  DiagnosticsEngine Diags(new DiagnosticIDs(), new DiagnosticOptions,
+  DiagnosticOptions DiagOpts;
+  DiagnosticsEngine Diags(new DiagnosticIDs(), DiagOpts,
                           new IgnoringDiagConsumer());
 
   unsigned numWarnings = 0U, numErrors = 0U;
@@ -140,7 +144,8 @@ TEST(DiagnosticTest, softReset) {
 }
 
 TEST(DiagnosticTest, diagnosticError) {
-  DiagnosticsEngine Diags(new DiagnosticIDs(), new DiagnosticOptions,
+  DiagnosticOptions DiagOpts;
+  DiagnosticsEngine Diags(new DiagnosticIDs(), DiagOpts,
                           new IgnoringDiagConsumer());
   PartialDiagnostic::DiagStorageAllocator Alloc;
   llvm::Expected<std::pair<int, int>> Value = DiagnosticError::create(
@@ -162,7 +167,8 @@ TEST(DiagnosticTest, diagnosticError) {
 }
 
 TEST(DiagnosticTest, storedDiagEmptyWarning) {
-  DiagnosticsEngine Diags(new DiagnosticIDs(), new DiagnosticOptions);
+  DiagnosticOptions DiagOpts;
+  DiagnosticsEngine Diags(new DiagnosticIDs(), DiagOpts);
 
   class CaptureDiagnosticConsumer : public DiagnosticConsumer {
   public:
@@ -192,7 +198,8 @@ class SuppressionMappingTest : public testing::Test {
 protected:
   llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> FS =
       llvm::makeIntrusiveRefCnt<llvm::vfs::InMemoryFileSystem>();
-  DiagnosticsEngine Diags{new DiagnosticIDs(), new DiagnosticOptions};
+  DiagnosticOptions DiagOpts;
+  DiagnosticsEngine Diags{new DiagnosticIDs(), DiagOpts};
 
   llvm::ArrayRef<StoredDiagnostic> diags() {
     return CaptureConsumer.StoredDiags;
diff --git a/clang/unittests/Basic/SarifTest.cpp b/clang/unittests/Basic/SarifTest.cpp
index febfbabe8695e..ad9f8ecc208a4 100644
--- a/clang/unittests/Basic/SarifTest.cpp
+++ b/clang/unittests/Basic/SarifTest.cpp
@@ -43,14 +43,14 @@ class SarifDocumentWriterTest : public ::testing::Test {
   SarifDocumentWriterTest()
       : InMemoryFileSystem(new llvm::vfs::InMemoryFileSystem),
         FileMgr(FileSystemOptions(), InMemoryFileSystem),
-        DiagID(new DiagnosticIDs()), DiagOpts(new DiagnosticOptions()),
-        Diags(DiagID, DiagOpts.get(), new IgnoringDiagConsumer()),
+        DiagID(new DiagnosticIDs()),
+        Diags(DiagID, DiagOpts, new IgnoringDiagConsumer()),
         SourceMgr(Diags, FileMgr) {}
 
   IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem;
   FileManager FileMgr;
   IntrusiveRefCntPtr<DiagnosticIDs> DiagID;
-  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
+  DiagnosticOptions DiagOpts;
   DiagnosticsEngine Diags;
   SourceManager SourceMgr;
   LangOptions LangOpts;
diff --git a/clang/unittests/Basic/SourceManagerTest.cpp b/clang/unittests/Basic/SourceManagerTest.cpp
index 1f0986f61dfa9..cbbaf390f3c7e 100644
--- a/clang/unittests/Basic/SourceManagerTest.cpp
+++ b/clang/unittests/Basic/SourceManagerTest.cpp
@@ -42,7 +42,7 @@ class SourceManagerTest : public ::testing::Test {
   SourceManagerTest()
     : FileMgr(FileMgrOpts),
       DiagID(new DiagnosticIDs()),
-      Diags(DiagID, new DiagnosticOptions, new IgnoringDiagConsumer()),
+      Diags(DiagID, DiagOpts, new IgnoringDiagConsumer()),
       SourceMgr(Diags, FileMgr),
       TargetOpts(new TargetOptions) {
     TargetOpts->Triple = "x86_64-apple-darwin11.1.0";
@@ -52,6 +52,7 @@ class SourceManagerTest : public ::testing::Test {
   FileSystemOptions FileMgrOpts;
   FileManager FileMgr;
   IntrusiveRefCntPtr<DiagnosticIDs> DiagID;
+  DiagnosticOptions DiagOpts;
   DiagnosticsEngine Diags;
   SourceManager SourceMgr;
   LangOptions LangOpts;
diff --git a/clang/unittests/Driver/DXCModeTest.cpp b/clang/unittests/Driver/DXCModeTest.cpp
index 616c07c0d389d..f6845939d04b4 100644
--- a/clang/unittests/Driver/DXCModeTest.cpp
+++ b/clang/unittests/Driver/DXCModeTest.cpp
@@ -64,8 +64,8 @@ TEST(DxcModeTest, TargetProfileValidation) {
                               llvm::MemoryBuffer::getMemBuffer("\n"));
 
   auto *DiagConsumer = new SimpleDiagnosticConsumer;
-  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
-  DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagConsumer);
+  DiagnosticOptions DiagOpts;
+  DiagnosticsEngine Diags(DiagID, DiagOpts, DiagConsumer);
 
   validateTargetProfile("-Tvs_6_0", "dxilv1.0--shadermodel6.0-vertex",
                         InMemoryFileSystem, Diags);
@@ -114,8 +114,8 @@ TEST(DxcModeTest, ValidatorVersionValidation) {
                               llvm::MemoryBuffer::getMemBuffer("\n"));
 
   auto *DiagConsumer = new SimpleDiagnosticConsumer;
-  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
-  DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagConsumer);
+  DiagnosticOptions DiagOpts;
+  DiagnosticsEngine Diags(DiagID, DiagOpts, DiagConsumer);
   Driver TheDriver("/bin/clang", "", Diags, "", InMemoryFileSystem);
   std::unique_ptr<Compilation> C(TheDriver.BuildCompilation(
       {"clang", "--driver-mode=dxc", "-Tlib_6_7", "foo.hlsl"}));
@@ -218,9 +218,9 @@ TEST(DxcModeTest, DefaultEntry) {
 
   const char *Args[] = {"clang", "--driver-mode=dxc", "-Tcs_6_7", "foo.hlsl"};
 
+  DiagnosticOptions DiagOpts;
   IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
-      CompilerInstance::createDiagnostics(*InMemoryFileSystem,
-                                          new DiagnosticOptions());
+      CompilerInstance::createDiagnostics(*InMemoryFileSystem, DiagOpts);
 
   CreateInvocationOptions CIOpts;
   CIOpts.Diags = Diags;
diff --git a/clang/unittests/Driver/SanitizerArgsTest.cpp b/clang/unittests/Driver/SanitizerArgsTest.cpp
index 5a4221023c950..8b5b26ad94162 100644
--- a/clang/unittests/Driver/SanitizerArgsTest.cpp
+++ b/clang/unittests/Driver/SanitizerArgsTest.cpp
@@ -52,10 +52,10 @@ class SanitizerArgsTest : public ::testing::Test {
                                           std::vector<std::string> ExtraFiles) {
     assert(!DriverInstance && "Running twice is not allowed");
 
-    llvm::IntrusiveRefCntPtr<DiagnosticOptions> Opts = new DiagnosticOptions;
+    DiagnosticOptions DiagOpts;
     DiagnosticsEngine Diags(
-        new DiagnosticIDs, Opts,
-        new TextDiagnosticPrinter(llvm::errs(), Opts.get()));
+        new DiagnosticIDs, DiagOpts,
+        new TextDiagnosticPrinter(llvm::errs(), DiagOpts));
     DriverInstance.emplace(ClangBinary, "x86_64-unknown-linux-gnu", Diags,
                            "clang LLVM compiler", prepareFS(ExtraFiles));
 
diff --git a/clang/unittests/Driver/SimpleDiagnosticConsumer.h b/clang/unittests/Driver/SimpleDiagnosticConsumer.h
index 6515bdedb3d5d..c3772baade566 100644
--- a/clang/unittests/Driver/SimpleDiagnosticConsumer.h
+++ b/clang/unittests/Driver/SimpleDiagnosticConsumer.h
@@ -47,9 +47,8 @@ inline clang::driver::Driver diagnostic_test_driver() {
   llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem(
       new llvm::vfs::InMemoryFileSystem);
   auto *DiagConsumer = new SimpleDiagnosticConsumer;
-  llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> DiagOpts =
-      new clang::DiagnosticOptions();
-  clang::DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagConsumer);
+  clang::DiagnosticOptions DiagOpts;
+  clang::DiagnosticsEngine Diags(DiagID, DiagOpts, DiagConsumer);
   return clang::driver::Driver("/bin/clang", "", Diags, "", InMemoryFileSystem);
 }
 
diff --git a/clang/unittests/Driver/ToolChainTest.cpp b/clang/unittests/Driver/ToolChainTest.cpp
index 9fe8cd18beb9b..60de82623a834 100644
--- a/clang/unittests/Driver/ToolChainTest.cpp
+++ b/clang/unittests/Driver/ToolChainTest.cpp
@@ -38,7 +38,7 @@ using namespace clang::driver;
 namespace {
 
 TEST(ToolChainTest, VFSGCCInstallation) {
-  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
+  DiagnosticOptions DiagOpts;
 
   IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
   struct TestDiagnosticConsumer : public DiagnosticConsumer {};
@@ -84,7 +84,7 @@ TEST(ToolChainTest, VFSGCCInstallation) {
                                 llvm::MemoryBuffer::getMemBuffer("\n"));
 
   {
-    DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer);
+    DiagnosticsEngine Diags(DiagID, DiagOpts, new TestDiagnosticConsumer);
     Driver TheDriver("/bin/clang", "arm-linux-gnueabihf", Diags,
                      "clang LLVM compiler", InMemoryFileSystem);
     std::unique_ptr<Compilation> C(TheDriver.BuildCompilation(
@@ -107,7 +107,8 @@ TEST(ToolChainTest, VFSGCCInstallation) {
   }
 
   {
-    DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer);
+    DiagnosticOptions DiagOpts;
+    DiagnosticsEngine Diags(DiagID, DiagOpts, new TestDiagnosticConsumer);
     Driver TheDriver("/bin/clang", "arm-linux-gnueabihf", Diags,
                      "clang LLVM compiler", InMemoryFileSystem);
     std::unique_ptr<Compilation> C(TheDriver.BuildCompilation(
@@ -134,11 +135,11 @@ TEST(ToolChainTest, VFSGCCInstallation) {
 }
 
 TEST(ToolChainTest, VFSGCCInstallationRelativeDir) {
-  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
+  DiagnosticOptions DiagOpts;
 
   IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
   struct TestDiagnosticConsumer : public DiagnosticConsumer {};
-  DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer);
+  DiagnosticsEngine Diags(DiagID, DiagOpts, new TestDiagnosticConsumer);
   IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem(
       new llvm::vfs::InMemoryFileSystem);
   Driver TheDriver("/home/test/bin/clang", "arm-linux-gnueabi", Diags,
@@ -173,7 +174,7 @@ TEST(ToolChainTest, VFSGCCInstallationRelativeDir) {
 }
 
 TEST(ToolChainTest, VFSSolarisMultiGCCInstallation) {
-  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
+  DiagnosticOptions DiagOpts;
 
   IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
   struct TestDiagnosticConsumer : public DiagnosticConsumer {};
@@ -201,7 +202,7 @@ TEST(ToolChainTest, VFSSolarisMultiGCCInstallation) {
                                 llvm::MemoryBuffer::getMemBuffer("\n"));
 
   {
-    DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer);
+    DiagnosticsEngine Diags(DiagID, DiagOpts, new TestDiagnosticConsumer);
     Driver TheDriver("/bin/clang", "i386-pc-solaris2.11", Diags,
                      "clang LLVM compiler", InMemoryFileSystem);
     std::unique_ptr<Compilation> C(
@@ -225,7 +226,7 @@ TEST(ToolChainTest, VFSSolarisMultiGCCInstallation) {
   }
 
   {
-    DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer);
+    DiagnosticsEngine Diags(DiagID, DiagOpts, new TestDiagnosticConsumer);
     Driver TheDriver("/bin/clang", "amd64-pc-solaris2.11", Diags,
                      "clang LLVM compiler", InMemoryFileSystem);
     std::unique_ptr<Compilation> C(
@@ -249,7 +250,7 @@ TEST(ToolChainTest, VFSSolarisMultiGCCInstallation) {
   }
 
   {
-    DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer);
+    DiagnosticsEngine Diags(DiagID, DiagOpts, new TestDiagnosticConsumer);
     Driver TheDriver("/bin/clang", "x86_64-pc-solaris2.11", Diags,
                      "clang LLVM compiler", InMemoryFileSystem);
     std::unique_ptr<Compilation> C(
@@ -273,7 +274,7 @@ TEST(ToolChainTest, VFSSolarisMultiGCCInstallation) {
   }
 
   {
-    DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer);
+    DiagnosticsEngine Diags(DiagID, DiagOpts, new TestDiagnosticConsumer);
     Driver TheDriver("/bin/clang", "sparc-sun-solaris2.11", Diags,
                      "clang LLVM compiler", InMemoryFileSystem);
     std::unique_ptr<Compilation> C(
@@ -296,7 +297,7 @@ TEST(ToolChainTest, VFSSolarisMultiGCCInstallation) {
               S);
   }
   {
-    DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer);
+    DiagnosticsEngine Diags(DiagID, DiagOpts, new TestDiagnosticConsumer);
     Driver TheDriver("/bin/clang", "sparcv9-sun-solaris2.11", Diags,
                      "clang LLVM compiler", InMemoryFileSystem);
     std::unique_ptr<Compilation> C(
@@ -337,7 +338,7 @@ MATCHER_P(jobHasArgs, Substr, "") {
 }
 
 TEST(ToolChainTest, VFSGnuLibcxxPathNoSysroot) {
-  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
+  DiagnosticOptions DiagOpts;
 
   IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
   struct TestDiagnosticConsumer : public DiagnosticConsumer {};
@@ -355,7 +356,7 @@ TEST(ToolChainTest, VFSGnuLibcxxPathNoSysroot) {
                                 llvm::MemoryBuffer::getMemBuffer("\n"));
 
   {
-    DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer);
+    DiagnosticsEngine Diags(DiagID, DiagOpts, new TestDiagnosticConsumer);
     Driver TheDriver("/bin/clang", "x86_64-unknown-linux-gnu", Diags,
                      "clang LLVM compiler", InMemoryFileSystem);
     std::unique_ptr<Compilation> C(TheDriver.BuildCompilation(
@@ -368,11 +369,11 @@ TEST(ToolChainTest, VFSGnuLibcxxPathNoSysroot) {
 }
 
 TEST(ToolChainTest, DefaultDriverMode) {
-  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
+  DiagnosticOptions DiagOpts;
 
   IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
   struct TestDiagnosticConsumer : public DiagnosticConsumer {};
-  DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer);
+  DiagnosticsEngine Diags(DiagID, DiagOpts, new TestDiagnosticConsumer);
   IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem(
       new llvm::vfs::InMemoryFileSystem);
 
@@ -403,8 +404,8 @@ TEST(ToolChainTest, DefaultDriverMode) {
 TEST(ToolChainTest, InvalidArgument) {
   IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
   struct TestDiagnosticConsumer : public DiagnosticConsumer {};
-  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
-  DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer);
+  DiagnosticOptions DiagOpts;
+  DiagnosticsEngine Diags(DiagID, DiagOpts, new TestDiagnosticConsumer);
   Driver TheDriver("/bin/clang", "arm-linux-gnueabihf", Diags);
   std::unique_ptr<Compilation> C(TheDriver.BuildCompilation(
       {"-fsyntax-only", "-fan-unknown-option", "foo.cpp"}));
@@ -514,11 +515,11 @@ TEST(ToolChainTest, GetTargetAndMode) {
 }
 
 TEST(ToolChainTest, CommandOutput) {
-  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
+  DiagnosticOptions DiagOpts;
 
   IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
   struct TestDiagnosticConsumer : public DiagnosticConsumer {};
-  DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer);
+  DiagnosticsEngine Diags(DiagID, DiagOpts, new TestDiagnosticConsumer);
   IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem(
       new llvm::vfs::InMemoryFileSystem);
 
@@ -543,10 +544,10 @@ TEST(ToolChainTest, CommandOutput) {
 }
 
 TEST(ToolChainTest, PostCallback) {
-  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
+  DiagnosticOptions DiagOpts;
   IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
   struct TestDiagnosticConsumer : public DiagnosticConsumer {};
-  DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer);
+  DiagnosticsEngine Diags(DiagID, DiagOpts, new TestDiagnosticConsumer);
   IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem(
       new llvm::vfs::InMemoryFileSystem);
 
@@ -596,10 +597,10 @@ TEST(ToolChainTest, UEFICallingConventionTest) {
 }
 
 TEST(ToolChainTest, UEFIDefaultDebugFormatTest) {
-  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
+  DiagnosticOptions DiagOpts;
   IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
   struct TestDiagnosticConsumer : public DiagnosticConsumer {};
-  DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer);
+  DiagnosticsEngine Diags(DiagID, DiagOpts, new TestDiagnosticConsumer);
   IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem(
       new llvm::vfs::InMemoryFileSystem);
   Driver CCDriver("/home/test/bin/clang", "x86_64-unknown-uefi", Diags,
@@ -638,10 +639,10 @@ struct SimpleDiagnosticConsumer : public DiagnosticConsumer {
 };
 
 TEST(ToolChainTest, ConfigFileSearch) {
-  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
+  DiagnosticOptions DiagOpts;
   IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
   struct TestDiagnosticConsumer : public DiagnosticConsumer {};
-  DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer);
+  DiagnosticsEngine Diags(DiagID, DiagOpts, new TestDiagnosticConsumer);
   IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> FS(
       new llvm::vfs::InMemoryFileSystem);
 
@@ -715,11 +716,11 @@ struct FileSystemWithError : public llvm::vfs::FileSystem {
 };
 
 TEST(ToolChainTest, ConfigFileError) {
-  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
+  DiagnosticOptions DiagOpts;
   IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
   std::unique_ptr<SimpleDiagnosticConsumer> DiagConsumer(
       new SimpleDiagnosticConsumer());
-  DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagConsumer.get(), false);
+  DiagnosticsEngine Diags(DiagID, DiagOpts, DiagConsumer.get(), false);
   IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS(new FileSystemWithError);
 
   Driver TheDriver("/home/test/bin/clang", "arm-linux-gnueabi", Diags,
@@ -736,11 +737,11 @@ TEST(ToolChainTest, ConfigFileError) {
 }
 
 TEST(ToolChainTest, BadConfigFile) {
-  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
+  DiagnosticOptions DiagOpts;
   IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
   std::unique_ptr<SimpleDiagnosticConsumer> DiagConsumer(
       new SimpleDiagnosticConsumer());
-  DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagConsumer.get(), false);
+  DiagnosticsEngine Diags(DiagID, DiagOpts, DiagConsumer.get(), false);
   IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> FS(
       new llvm::vfs::InMemoryFileSystem);
 
@@ -810,11 +811,11 @@ TEST(ToolChainTest, BadConfigFile) {
 }
 
 TEST(ToolChainTest, ConfigInexistentInclude) {
-  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
+  DiagnosticOptions DiagOpts;
   IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
   std::unique_ptr<SimpleDiagnosticConsumer> DiagConsumer(
       new SimpleDiagnosticConsumer());
-  DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagConsumer.get(), false);
+  DiagnosticsEngine Diags(DiagID, DiagOpts, DiagConsumer.get(), false);
   IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> FS(
       new llvm::vfs::InMemoryFileSystem);
 
@@ -851,11 +852,11 @@ TEST(ToolChainTest, ConfigInexistentInclude) {
 }
 
 TEST(ToolChainTest, ConfigRecursiveInclude) {
-  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
+  DiagnosticOptions DiagOpts;
   IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
   std::unique_ptr<SimpleDiagnosticConsumer> DiagConsumer(
       new SimpleDiagnosticConsumer());
-  DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagConsumer.get(), false);
+  DiagnosticsEngine Diags(DiagID, DiagOpts, DiagConsumer.get(), false);
   IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> FS(
       new llvm::vfs::InMemoryFileSystem);
 
@@ -897,10 +898,10 @@ TEST(ToolChainTest, ConfigRecursiveInclude) {
 }
 
 TEST(ToolChainTest, NestedConfigFile) {
-  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
+  DiagnosticOptions DiagOpts;
   IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
   struct TestDiagnosticConsumer : public DiagnosticConsumer {};
-  DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer);
+  DiagnosticsEngine Diags(DiagID, DiagOpts, new TestDiagnosticConsumer);
   IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> FS(
       new llvm::vfs::InMemoryFileSystem);
 
diff --git a/clang/unittests/Frontend/ASTUnitTest.cpp b/clang/unittests/Frontend/ASTUnitTest.cpp
index 08daca9111e64..ffb082ce545bc 100644
--- a/clang/unittests/Frontend/ASTUnitTest.cpp
+++ b/clang/unittests/Frontend/ASTUnitTest.cpp
@@ -30,6 +30,7 @@ class ASTUnitTest : public ::testing::Test {
   int FD;
   llvm::SmallString<256> InputFileName;
   std::unique_ptr<ToolOutputFile> input_file;
+  DiagnosticOptions DiagOpts;
   IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
   std::shared_ptr<CompilerInvocation> CInvok;
   std::shared_ptr<PCHContainerOperations> PCHContainerOps;
@@ -43,7 +44,7 @@ class ASTUnitTest : public ::testing::Test {
     const char *Args[] = {"clang", "-xc++", InputFileName.c_str()};
 
     auto VFS = llvm::vfs::getRealFileSystem();
-    Diags = CompilerInstance::createDiagnostics(*VFS, new DiagnosticOptions());
+    Diags = CompilerInstance::createDiagnostics(*VFS, DiagOpts);
 
     CreateInvocationOptions CIOpts;
     CIOpts.Diags = Diags;
@@ -137,7 +138,7 @@ TEST_F(ASTUnitTest, ModuleTextualHeader) {
   const char *Args[] = {"clang", "test.cpp", "-fmodule-map-file=m.modulemap",
                         "-fmodule-name=M"};
   Diags =
-      CompilerInstance::createDiagnostics(*InMemoryFs, new DiagnosticOptions());
+      CompilerInstance::createDiagnostics(*InMemoryFs, DiagOpts);
   CreateInvocationOptions CIOpts;
   CIOpts.Diags = Diags;
   CInvok = createInvocation(Args, std::move(CIOpts));
@@ -166,7 +167,7 @@ TEST_F(ASTUnitTest, LoadFromCommandLineEarlyError) {
   const char *Args[] = {"clang", "-target", "foobar", InputFileName.c_str()};
 
   auto Diags = CompilerInstance::createDiagnostics(
-      *llvm::vfs::getRealFileSystem(), new DiagnosticOptions());
+      *llvm::vfs::getRealFileSystem(), DiagOpts);
   auto PCHContainerOps = std::make_shared<PCHContainerOperations>();
   std::unique_ptr<clang::ASTUnit> ErrUnit;
 
@@ -194,7 +195,7 @@ TEST_F(ASTUnitTest, LoadFromCommandLineWorkingDirectory) {
                         InputFileName.c_str()};
 
   auto Diags = CompilerInstance::createDiagnostics(
-      *llvm::vfs::getRealFileSystem(), new DiagnosticOptions());
+      *llvm::vfs::getRealFileSystem(), DiagOpts);
   auto PCHContainerOps = std::make_shared<PCHContainerOperations>();
   std::unique_ptr<clang::ASTUnit> ErrUnit;
 
diff --git a/clang/unittests/Frontend/CompilerInstanceTest.cpp b/clang/unittests/Frontend/CompilerInstanceTest.cpp
index 6e9a6f5f728a5..df987027b3bdc 100644
--- a/clang/unittests/Frontend/CompilerInstanceTest.cpp
+++ b/clang/unittests/Frontend/CompilerInstanceTest.cpp
@@ -53,9 +53,10 @@ TEST(CompilerInstance, DefaultVFSOverlayFromInvocation) {
   const std::string VFSArg = "-ivfsoverlay" + FileNameStr;
   const char *Args[] = {"clang", VFSArg.c_str(), "-xc++", "-"};
 
+  DiagnosticOptions DiagOpts;
   IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
       CompilerInstance::createDiagnostics(*llvm::vfs::getRealFileSystem(),
-                                          new DiagnosticOptions());
+                                          DiagOpts);
 
   CreateInvocationOptions CIOpts;
   CIOpts.Diags = Diags;
@@ -76,17 +77,17 @@ TEST(CompilerInstance, DefaultVFSOverlayFromInvocation) {
 }
 
 TEST(CompilerInstance, AllowDiagnosticLogWithUnownedDiagnosticConsumer) {
-  auto DiagOpts = new DiagnosticOptions();
+  DiagnosticOptions DiagOpts;
   // Tell the diagnostics engine to emit the diagnostic log to STDERR. This
   // ensures that a chained diagnostic consumer is created so that the test can
   // exercise the unowned diagnostic consumer in a chained consumer.
-  DiagOpts->DiagnosticLogFile = "-";
+  DiagOpts.DiagnosticLogFile = "-";
 
   // Create the diagnostic engine with unowned consumer.
   std::string DiagnosticOutput;
   llvm::raw_string_ostream DiagnosticsOS(DiagnosticOutput);
   auto DiagPrinter = std::make_unique<TextDiagnosticPrinter>(
-      DiagnosticsOS, new DiagnosticOptions());
+      DiagnosticsOS, DiagOpts);
   CompilerInstance Instance;
   IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
       Instance.createDiagnostics(*llvm::vfs::getRealFileSystem(), DiagOpts,
diff --git a/clang/unittests/Frontend/CompilerInvocationTest.cpp b/clang/unittests/Frontend/CompilerInvocationTest.cpp
index 94ab9fe8451e0..75390aa42d00e 100644
--- a/clang/unittests/Frontend/CompilerInvocationTest.cpp
+++ b/clang/unittests/Frontend/CompilerInvocationTest.cpp
@@ -29,6 +29,7 @@ using ::testing::StartsWith;
 namespace {
 class CommandLineTest : public ::testing::Test {
 public:
+  DiagnosticOptions DiagOpts;
   IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
   SmallVector<const char *, 32> GeneratedArgs;
   BumpPtrAllocator Alloc;
@@ -41,7 +42,7 @@ class CommandLineTest : public ::testing::Test {
 
   CommandLineTest()
       : Diags(CompilerInstance::createDiagnostics(
-            *llvm::vfs::getRealFileSystem(), new DiagnosticOptions(),
+            *llvm::vfs::getRealFileSystem(), DiagOpts,
             new TextDiagnosticBuffer())),
         StringPool(Alloc) {}
 };
diff --git a/clang/unittests/Frontend/OutputStreamTest.cpp b/clang/unittests/Frontend/OutputStreamTest.cpp
index 0eda3a1dab403..cb656c0750b64 100644
--- a/clang/unittests/Frontend/OutputStreamTest.cpp
+++ b/clang/unittests/Frontend/OutputStreamTest.cpp
@@ -61,10 +61,10 @@ TEST(FrontendOutputTests, TestVerboseOutputStreamShared) {
   raw_string_ostream VerboseStream(VerboseBuffer);
 
   Compiler.setOutputStream(std::make_unique<raw_null_ostream>());
-  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
+  DiagnosticOptions DiagOpts;
   Compiler.createDiagnostics(
       *llvm::vfs::getRealFileSystem(),
-      new TextDiagnosticPrinter(llvm::nulls(), &*DiagOpts), true);
+      new TextDiagnosticPrinter(llvm::nulls(), DiagOpts), true);
   Compiler.setVerboseOutputStream(VerboseStream);
 
   bool Success = ExecuteCompilerInvocation(&Compiler);
@@ -91,10 +91,10 @@ TEST(FrontendOutputTests, TestVerboseOutputStreamOwned) {
         std::make_unique<raw_string_ostream>(VerboseBuffer);
 
     Compiler.setOutputStream(std::make_unique<raw_null_ostream>());
-    IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
+    DiagnosticOptions DiagOpts;
     Compiler.createDiagnostics(
         *llvm::vfs::getRealFileSystem(),
-        new TextDiagnosticPrinter(llvm::nulls(), &*DiagOpts), true);
+        new TextDiagnosticPrinter(llvm::nulls(), DiagOpts), true);
     Compiler.setVerboseOutputStream(std::move(VerboseStream));
 
     Success = ExecuteCompilerInvocation(&Compiler);
diff --git a/clang/unittests/Frontend/PCHPreambleTest.cpp b/clang/unittests/Frontend/PCHPreambleTest.cpp
index 58ec2e2ce7058..266372066aefe 100644
--- a/clang/unittests/Frontend/PCHPreambleTest.cpp
+++ b/clang/unittests/Frontend/PCHPreambleTest.cpp
@@ -94,8 +94,9 @@ class PCHPreambleTest : public ::testing::Test {
     PreprocessorOptions &PPOpts = CI->getPreprocessorOpts();
     PPOpts.RemappedFilesKeepOriginalName = true;
 
+    DiagnosticOptions DiagOpts;
     IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
-        CompilerInstance::createDiagnostics(*VFS, new DiagnosticOptions,
+        CompilerInstance::createDiagnostics(*VFS, DiagOpts,
                                             new DiagnosticConsumer));
 
     FileManager *FileMgr = new FileManager(FSOpts, VFS);
diff --git a/clang/unittests/Frontend/ReparseWorkingDirTest.cpp b/clang/unittests/Frontend/ReparseWorkingDirTest.cpp
index b0f2d51b80b9e..bddb72490f6b1 100644
--- a/clang/unittests/Frontend/ReparseWorkingDirTest.cpp
+++ b/clang/unittests/Frontend/ReparseWorkingDirTest.cpp
@@ -57,8 +57,9 @@ class ReparseWorkingDirTest : public ::testing::Test {
     CI->getFileSystemOpts().WorkingDir = *VFS->getCurrentWorkingDirectory();
     CI->getTargetOpts().Triple = "i386-unknown-linux-gnu";
 
+    DiagnosticOptions DiagOpts;
     IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
-        CompilerInstance::createDiagnostics(*VFS, new DiagnosticOptions,
+        CompilerInstance::createDiagnostics(*VFS, DiagOpts,
                                             new DiagnosticConsumer));
 
     FileManager *FileMgr = new FileManager(CI->getFileSystemOpts(), VFS);
diff --git a/clang/unittests/Frontend/SearchPathTest.cpp b/clang/unittests/Frontend/SearchPathTest.cpp
index 5d382a4ee20a8..094956e993916 100644
--- a/clang/unittests/Frontend/SearchPathTest.cpp
+++ b/clang/unittests/Frontend/SearchPathTest.cpp
@@ -40,12 +40,12 @@ namespace {
 class SearchPathTest : public ::testing::Test {
 protected:
   SearchPathTest()
-      : Diags(new DiagnosticIDs(), new DiagnosticOptions,
-              new IgnoringDiagConsumer()),
+      : Diags(new DiagnosticIDs(), DiagOpts, new IgnoringDiagConsumer()),
         VFS(new llvm::vfs::InMemoryFileSystem),
         FileMgr(FileSystemOptions(), VFS), SourceMgr(Diags, FileMgr),
         Invocation(std::make_unique<CompilerInvocation>()) {}
 
+  DiagnosticOptions DiagOpts;
   DiagnosticsEngine Diags;
   IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> VFS;
   FileManager FileMgr;
diff --git a/clang/unittests/Frontend/TextDiagnosticTest.cpp b/clang/unittests/Frontend/TextDiagnosticTest.cpp
index fef5726f053f1..8fd8187134b63 100644
--- a/clang/unittests/Frontend/TextDiagnosticTest.cpp
+++ b/clang/unittests/Frontend/TextDiagnosticTest.cpp
@@ -20,13 +20,12 @@ namespace {
 
 /// Prints a diagnostic with the given DiagnosticOptions and the given
 /// SourceLocation and returns the printed diagnostic text.
-static std::string PrintDiag(const DiagnosticOptions &Opts, FullSourceLoc Loc) {
+static std::string PrintDiag(DiagnosticOptions &Opts, FullSourceLoc Loc) {
   std::string Out;
   llvm::raw_string_ostream OS(Out);
   clang::LangOptions LangOpts;
   // Owned by TextDiagnostic.
-  DiagnosticOptions *DiagOpts = new DiagnosticOptions(Opts);
-  TextDiagnostic Diag(OS, LangOpts, DiagOpts);
+  TextDiagnostic Diag(OS, LangOpts, Opts);
   // Emit a dummy diagnostic that is just 'message'.
   Diag.emitDiagnostic(Loc, DiagnosticsEngine::Level::Warning, "message",
                       /*Ranges=*/{}, /*FixItHints=*/{});
@@ -38,7 +37,8 @@ TEST(TextDiagnostic, ShowLine) {
   FileSystemOptions FSOpts;
   FileManager FileMgr(FSOpts);
   IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs);
-  DiagnosticsEngine DiagEngine(DiagID, new DiagnosticOptions,
+  DiagnosticOptions DiagEngineOpts;
+  DiagnosticsEngine DiagEngine(DiagID, DiagEngineOpts,
                                new IgnoringDiagConsumer());
   SourceManager SrcMgr(DiagEngine, FileMgr);
 
diff --git a/clang/unittests/Frontend/UtilsTest.cpp b/clang/unittests/Frontend/UtilsTest.cpp
index 47ca3210ab596..cf385a5323c61 100644
--- a/clang/unittests/Frontend/UtilsTest.cpp
+++ b/clang/unittests/Frontend/UtilsTest.cpp
@@ -26,11 +26,12 @@ TEST(BuildCompilerInvocationTest, RecoverMultipleJobs) {
   std::vector<const char *> Args = {"clang", "--target=macho", "-arch",  "i386",
                                     "-arch", "x86_64",         "foo.cpp"};
   clang::IgnoringDiagConsumer D;
+  clang::DiagnosticOptions DiagOpts;
   CreateInvocationOptions Opts;
   Opts.RecoverOnError = true;
   Opts.VFS = new llvm::vfs::InMemoryFileSystem();
-  Opts.Diags = clang::CompilerInstance::createDiagnostics(
-      *Opts.VFS, new DiagnosticOptions, &D, false);
+  Opts.Diags = clang::CompilerInstance::createDiagnostics(*Opts.VFS, DiagOpts,
+                                                          &D, false);
   std::unique_ptr<CompilerInvocation> CI = createInvocation(Args, Opts);
   ASSERT_TRUE(CI);
   EXPECT_THAT(CI->getTargetOpts().Triple, testing::StartsWith("i386-"));
@@ -45,9 +46,9 @@ TEST(BuildCompilerInvocationTest, ProbePrecompiled) {
   FS->addFile("foo.h.pch", 0, llvm::MemoryBuffer::getMemBuffer(""));
 
   clang::IgnoringDiagConsumer D;
+  clang::DiagnosticOptions DiagOpts;
   llvm::IntrusiveRefCntPtr<DiagnosticsEngine> CommandLineDiagsEngine =
-      clang::CompilerInstance::createDiagnostics(*FS, new DiagnosticOptions, &D,
-                                                 false);
+      clang::CompilerInstance::createDiagnostics(*FS, DiagOpts, &D, false);
   // Default: ProbePrecompiled=false
   CreateInvocationOptions CIOpts;
   CIOpts.Diags = CommandLineDiagsEngine;
diff --git a/clang/unittests/Interpreter/InterpreterTest.cpp b/clang/unittests/Interpreter/InterpreterTest.cpp
index 03b9c33232080..b97f5ae17c9f0 100644
--- a/clang/unittests/Interpreter/InterpreterTest.cpp
+++ b/clang/unittests/Interpreter/InterpreterTest.cpp
@@ -95,8 +95,9 @@ TEST_F(InterpreterTest, Errors) {
   // Create the diagnostic engine with unowned consumer.
   std::string DiagnosticOutput;
   llvm::raw_string_ostream DiagnosticsOS(DiagnosticOutput);
-  auto DiagPrinter = std::make_unique<TextDiagnosticPrinter>(
-      DiagnosticsOS, new DiagnosticOptions());
+  DiagnosticOptions DiagOpts;
+  auto DiagPrinter =
+      std::make_unique<TextDiagnosticPrinter>(DiagnosticsOS, DiagOpts);
 
   auto Interp = createInterpreter(ExtraArgs, DiagPrinter.get());
   auto Err = Interp->Parse("intentional_error v1 = 42; ").takeError();
@@ -126,8 +127,9 @@ TEST_F(InterpreterTest, DeclsAndStatements) {
   // Create the diagnostic engine with unowned consumer.
   std::string DiagnosticOutput;
   llvm::raw_string_ostream DiagnosticsOS(DiagnosticOutput);
-  auto DiagPrinter = std::make_unique<TextDiagnosticPrinter>(
-      DiagnosticsOS, new DiagnosticOptions());
+  DiagnosticOptions DiagOpts;
+  auto DiagPrinter =
+      std::make_unique<TextDiagnosticPrinter>(DiagnosticsOS, DiagOpts);
 
   auto Interp = createInterpreter(ExtraArgs, DiagPrinter.get());
   auto R1 = Interp->Parse(
@@ -148,8 +150,9 @@ TEST_F(InterpreterTest, UndoCommand) {
   // Create the diagnostic engine with unowned consumer.
   std::string DiagnosticOutput;
   llvm::raw_string_ostream DiagnosticsOS(DiagnosticOutput);
-  auto DiagPrinter = std::make_unique<TextDiagnosticPrinter>(
-      DiagnosticsOS, new DiagnosticOptions());
+  DiagnosticOptions DiagOpts;
+  auto DiagPrinter =
+      std::make_unique<TextDiagnosticPrinter>(DiagnosticsOS, DiagOpts);
 
   auto Interp = createInterpreter(ExtraArgs, DiagPrinter.get());
 
diff --git a/clang/unittests/Lex/HeaderSearchTest.cpp b/clang/unittests/Lex/HeaderSearchTest.cpp
index b8896261703cd..9903c1246d33d 100644
--- a/clang/unittests/Lex/HeaderSearchTest.cpp
+++ b/clang/unittests/Lex/HeaderSearchTest.cpp
@@ -30,7 +30,7 @@ class HeaderSearchTest : public ::testing::Test {
   HeaderSearchTest()
       : VFS(new llvm::vfs::InMemoryFileSystem), FileMgr(FileMgrOpts, VFS),
         DiagID(new DiagnosticIDs()),
-        Diags(DiagID, new DiagnosticOptions, new IgnoringDiagConsumer()),
+        Diags(DiagID, DiagOpts, new IgnoringDiagConsumer()),
         SourceMgr(Diags, FileMgr), TargetOpts(new TargetOptions),
         Search(HSOpts, SourceMgr, Diags, LangOpts, Target.get()) {
     TargetOpts->Triple = "x86_64-apple-darwin11.1.0";
@@ -81,6 +81,7 @@ class HeaderSearchTest : public ::testing::Test {
   FileSystemOptions FileMgrOpts;
   FileManager FileMgr;
   IntrusiveRefCntPtr<DiagnosticIDs> DiagID;
+  DiagnosticOptions DiagOpts;
   DiagnosticsEngine Diags;
   SourceManager SourceMgr;
   LangOptions LangOpts;
diff --git a/clang/unittests/Lex/LexerTest.cpp b/clang/unittests/Lex/LexerTest.cpp
index 9806d4c7bf145..66e7055acf30c 100644
--- a/clang/unittests/Lex/LexerTest.cpp
+++ b/clang/unittests/Lex/LexerTest.cpp
@@ -43,7 +43,7 @@ class LexerTest : public ::testing::Test {
   LexerTest()
     : FileMgr(FileMgrOpts),
       DiagID(new DiagnosticIDs()),
-      Diags(DiagID, new DiagnosticOptions, new IgnoringDiagConsumer()),
+      Diags(DiagID, DiagOpts, new IgnoringDiagConsumer()),
       SourceMgr(Diags, FileMgr),
       TargetOpts(new TargetOptions)
   {
@@ -104,6 +104,7 @@ class LexerTest : public ::testing::Test {
   FileSystemOptions FileMgrOpts;
   FileManager FileMgr;
   IntrusiveRefCntPtr<DiagnosticIDs> DiagID;
+  DiagnosticOptions DiagOpts;
   DiagnosticsEngine Diags;
   SourceManager SourceMgr;
   LangOptions LangOpts;
diff --git a/clang/unittests/Lex/ModuleDeclStateTest.cpp b/clang/unittests/Lex/ModuleDeclStateTest.cpp
index 6fbc6bff12d8a..6ecba4de3187c 100644
--- a/clang/unittests/Lex/ModuleDeclStateTest.cpp
+++ b/clang/unittests/Lex/ModuleDeclStateTest.cpp
@@ -55,7 +55,7 @@ class ModuleDeclStateTest : public ::testing::Test {
 protected:
   ModuleDeclStateTest()
       : FileMgr(FileMgrOpts), DiagID(new DiagnosticIDs()),
-        Diags(DiagID, new DiagnosticOptions, new IgnoringDiagConsumer()),
+        Diags(DiagID, DiagOpts, new IgnoringDiagConsumer()),
         SourceMgr(Diags, FileMgr), TargetOpts(new TargetOptions) {
     TargetOpts->Triple = "x86_64-unknown-linux-gnu";
     Target = TargetInfo::CreateTargetInfo(Diags, *TargetOpts);
@@ -94,6 +94,7 @@ class ModuleDeclStateTest : public ::testing::Test {
   FileSystemOptions FileMgrOpts;
   FileManager FileMgr;
   IntrusiveRefCntPtr<DiagnosticIDs> DiagID;
+  DiagnosticOptions DiagOpts;
   DiagnosticsEngine Diags;
   SourceManager SourceMgr;
   std::shared_ptr<TargetOptions> TargetOpts;
diff --git a/clang/unittests/Lex/PPCallbacksTest.cpp b/clang/unittests/Lex/PPCallbacksTest.cpp
index c2a84d974dd39..af86c1888f2c7 100644
--- a/clang/unittests/Lex/PPCallbacksTest.cpp
+++ b/clang/unittests/Lex/PPCallbacksTest.cpp
@@ -135,8 +135,8 @@ class PPCallbacksTest : public ::testing::Test {
   PPCallbacksTest()
       : InMemoryFileSystem(new llvm::vfs::InMemoryFileSystem),
         FileMgr(FileSystemOptions(), InMemoryFileSystem),
-        DiagID(new DiagnosticIDs()), DiagOpts(new DiagnosticOptions()),
-        Diags(DiagID, DiagOpts.get(), new IgnoringDiagConsumer()),
+        DiagID(new DiagnosticIDs()),
+        Diags(DiagID, DiagOpts, new IgnoringDiagConsumer()),
         SourceMgr(Diags, FileMgr), TargetOpts(new TargetOptions()) {
     TargetOpts->Triple = "x86_64-apple-darwin11.1.0";
     Target = TargetInfo::CreateTargetInfo(Diags, *TargetOpts);
@@ -145,7 +145,7 @@ class PPCallbacksTest : public ::testing::Test {
   IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem;
   FileManager FileMgr;
   IntrusiveRefCntPtr<DiagnosticIDs> DiagID;
-  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
+  DiagnosticOptions DiagOpts;
   DiagnosticsEngine Diags;
   SourceManager SourceMgr;
   LangOptions LangOpts;
@@ -437,7 +437,7 @@ TEST_F(PPCallbacksTest, FileNotFoundSkipped) {
   HeaderSearch HeaderInfo(HSOpts, SourceMgr, Diags, LangOpts, Target.get());
 
   DiagnosticConsumer *DiagConsumer = new DiagnosticConsumer;
-  DiagnosticsEngine FileNotFoundDiags(DiagID, DiagOpts.get(), DiagConsumer);
+  DiagnosticsEngine FileNotFoundDiags(DiagID, DiagOpts, DiagConsumer);
   Preprocessor PP(PPOpts, FileNotFoundDiags, LangOpts, SourceMgr, HeaderInfo,
                   ModLoader, /*IILookup=*/nullptr, /*OwnsHeaderSearch=*/false);
   PP.Initialize(*Target);
diff --git a/clang/unittests/Lex/PPConditionalDirectiveRecordTest.cpp b/clang/unittests/Lex/PPConditionalDirectiveRecordTest.cpp
index 5c3ce6fa33012..ce7433e35fd56 100644
--- a/clang/unittests/Lex/PPConditionalDirectiveRecordTest.cpp
+++ b/clang/unittests/Lex/PPConditionalDirectiveRecordTest.cpp
@@ -31,7 +31,7 @@ class PPConditionalDirectiveRecordTest : public ::testing::Test {
   PPConditionalDirectiveRecordTest()
     : FileMgr(FileMgrOpts),
       DiagID(new DiagnosticIDs()),
-      Diags(DiagID, new DiagnosticOptions, new IgnoringDiagConsumer()),
+      Diags(DiagID, DiagOpts, new IgnoringDiagConsumer()),
       SourceMgr(Diags, FileMgr),
       TargetOpts(new TargetOptions)
   {
@@ -42,6 +42,7 @@ class PPConditionalDirectiveRecordTest : public ::testing::Test {
   FileSystemOptions FileMgrOpts;
   FileManager FileMgr;
   IntrusiveRefCntPtr<DiagnosticIDs> DiagID;
+  DiagnosticOptions DiagOpts;
   DiagnosticsEngine Diags;
   SourceManager SourceMgr;
   LangOptions LangOpts;
diff --git a/clang/unittests/Lex/PPDependencyDirectivesTest.cpp b/clang/unittests/Lex/PPDependencyDirectivesTest.cpp
index 74e3c00b451ba..061cb136a552a 100644
--- a/clang/unittests/Lex/PPDependencyDirectivesTest.cpp
+++ b/clang/unittests/Lex/PPDependencyDirectivesTest.cpp
@@ -32,7 +32,7 @@ class PPDependencyDirectivesTest : public ::testing::Test {
 protected:
   PPDependencyDirectivesTest()
       : FileMgr(FileMgrOpts), DiagID(new DiagnosticIDs()),
-        Diags(DiagID, new DiagnosticOptions, new IgnoringDiagConsumer()),
+        Diags(DiagID, DiagOpts, new IgnoringDiagConsumer()),
         SourceMgr(Diags, FileMgr), TargetOpts(new TargetOptions) {
     TargetOpts->Triple = "x86_64-apple-macos12";
     Target = TargetInfo::CreateTargetInfo(Diags, *TargetOpts);
@@ -41,6 +41,7 @@ class PPDependencyDirectivesTest : public ::testing::Test {
   FileSystemOptions FileMgrOpts;
   FileManager FileMgr;
   IntrusiveRefCntPtr<DiagnosticIDs> DiagID;
+  DiagnosticOptions DiagOpts;
   DiagnosticsEngine Diags;
   SourceManager SourceMgr;
   LangOptions LangOpts;
diff --git a/clang/unittests/Lex/PPMemoryAllocationsTest.cpp b/clang/unittests/Lex/PPMemoryAllocationsTest.cpp
index 304a66ab96caa..4d83003e28b36 100644
--- a/clang/unittests/Lex/PPMemoryAllocationsTest.cpp
+++ b/clang/unittests/Lex/PPMemoryAllocationsTest.cpp
@@ -28,7 +28,7 @@ class PPMemoryAllocationsTest : public ::testing::Test {
 protected:
   PPMemoryAllocationsTest()
       : FileMgr(FileMgrOpts), DiagID(new DiagnosticIDs()),
-        Diags(DiagID, new DiagnosticOptions, new IgnoringDiagConsumer()),
+        Diags(DiagID, DiagOpts, new IgnoringDiagConsumer()),
         SourceMgr(Diags, FileMgr), TargetOpts(new TargetOptions) {
     TargetOpts->Triple = "x86_64-apple-darwin11.1.0";
     Target = TargetInfo::CreateTargetInfo(Diags, *TargetOpts);
@@ -37,6 +37,7 @@ class PPMemoryAllocationsTest : public ::testing::Test {
   FileSystemOptions FileMgrOpts;
   FileManager FileMgr;
   IntrusiveRefCntPtr<DiagnosticIDs> DiagID;
+  DiagnosticOptions DiagOpts;
   DiagnosticsEngine Diags;
   SourceManager SourceMgr;
   LangOptions LangOpts;
diff --git a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
index c97f8d0b392d1..cd6dea55ac632 100644
--- a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
+++ b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
@@ -68,7 +68,7 @@ class ParseHLSLRootSignatureTest : public ::testing::Test {
   ParseHLSLRootSignatureTest()
       : FileMgr(FileMgrOpts), DiagID(new DiagnosticIDs()),
         Consumer(new ExpectedDiagConsumer()),
-        Diags(DiagID, new DiagnosticOptions, Consumer),
+        Diags(DiagID, DiagOpts, Consumer),
         SourceMgr(Diags, FileMgr), TargetOpts(new TargetOptions) {
     // This is an arbitrarily chosen target triple to create the target info.
     TargetOpts->Triple = "dxil";
@@ -95,6 +95,7 @@ class ParseHLSLRootSignatureTest : public ::testing::Test {
   FileSystemOptions FileMgrOpts;
   FileManager FileMgr;
   IntrusiveRefCntPtr<DiagnosticIDs> DiagID;
+  DiagnosticOptions DiagOpts;
   ExpectedDiagConsumer *Consumer;
   DiagnosticsEngine Diags;
   SourceManager SourceMgr;
diff --git a/clang/unittests/Sema/SemaNoloadLookupTest.cpp b/clang/unittests/Sema/SemaNoloadLookupTest.cpp
index c68a71ae05d3f..5a04f42697b99 100644
--- a/clang/unittests/Sema/SemaNoloadLookupTest.cpp
+++ b/clang/unittests/Sema/SemaNoloadLookupTest.cpp
@@ -59,9 +59,9 @@ class NoloadLookupTest : public ::testing::Test {
 
     CreateInvocationOptions CIOpts;
     CIOpts.VFS = llvm::vfs::createPhysicalFileSystem();
+    DiagnosticOptions DiagOpts;
     IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
-        CompilerInstance::createDiagnostics(*CIOpts.VFS,
-                                            new DiagnosticOptions());
+        CompilerInstance::createDiagnostics(*CIOpts.VFS, DiagOpts);
     CIOpts.Diags = Diags;
 
     std::string CacheBMIPath =
diff --git a/clang/unittests/Serialization/ForceCheckFileInputTest.cpp b/clang/unittests/Serialization/ForceCheckFileInputTest.cpp
index 16742a6cb01e8..970eeef3c953e 100644
--- a/clang/unittests/Serialization/ForceCheckFileInputTest.cpp
+++ b/clang/unittests/Serialization/ForceCheckFileInputTest.cpp
@@ -66,9 +66,9 @@ export int aa = 43;
     CreateInvocationOptions CIOpts;
     CIOpts.VFS = llvm::vfs::createPhysicalFileSystem();
 
+    DiagnosticOptions DiagOpts;
     IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
-        CompilerInstance::createDiagnostics(*CIOpts.VFS,
-                                            new DiagnosticOptions());
+        CompilerInstance::createDiagnostics(*CIOpts.VFS, DiagOpts);
     CIOpts.Diags = Diags;
 
     const char *Args[] = {"clang++",       "-std=c++20",
@@ -106,9 +106,9 @@ export int aa = 43;
   {
     CreateInvocationOptions CIOpts;
     CIOpts.VFS = llvm::vfs::createPhysicalFileSystem();
+    DiagnosticOptions DiagOpts;
     IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
-        CompilerInstance::createDiagnostics(*CIOpts.VFS,
-                                            new DiagnosticOptions());
+        CompilerInstance::createDiagnostics(*CIOpts.VFS, DiagOpts);
     CIOpts.Diags = Diags;
 
     std::string BMIPath = llvm::Twine(TestDir + "/a.pcm").str();
diff --git a/clang/unittests/Serialization/LoadSpecLazilyTest.cpp b/clang/unittests/Serialization/LoadSpecLazilyTest.cpp
index d62d669149f51..631547431ce7c 100644
--- a/clang/unittests/Serialization/LoadSpecLazilyTest.cpp
+++ b/clang/unittests/Serialization/LoadSpecLazilyTest.cpp
@@ -53,8 +53,9 @@ class LoadSpecLazilyTest : public ::testing::Test {
 
     IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS =
         llvm::vfs::createPhysicalFileSystem();
+    DiagnosticOptions DiagOpts;
     IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
-        CompilerInstance::createDiagnostics(*VFS, new DiagnosticOptions());
+        CompilerInstance::createDiagnostics(*VFS, DiagOpts);
     CreateInvocationOptions CIOpts;
     CIOpts.Diags = Diags;
     CIOpts.VFS = VFS;
diff --git a/clang/unittests/Serialization/ModuleCacheTest.cpp b/clang/unittests/Serialization/ModuleCacheTest.cpp
index 38003e93c5d9d..de6e13a738cb8 100644
--- a/clang/unittests/Serialization/ModuleCacheTest.cpp
+++ b/clang/unittests/Serialization/ModuleCacheTest.cpp
@@ -108,8 +108,9 @@ TEST_F(ModuleCacheTest, CachedModuleNewPath) {
   MCPArg.append(ModuleCachePath);
   CreateInvocationOptions CIOpts;
   CIOpts.VFS = llvm::vfs::createPhysicalFileSystem();
+  DiagnosticOptions DiagOpts;
   IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
-      CompilerInstance::createDiagnostics(*CIOpts.VFS, new DiagnosticOptions());
+      CompilerInstance::createDiagnostics(*CIOpts.VFS, DiagOpts);
   CIOpts.Diags = Diags;
 
   // First run should pass with no errors
@@ -157,8 +158,9 @@ TEST_F(ModuleCacheTest, CachedModuleNewPathAllowErrors) {
   MCPArg.append(ModuleCachePath);
   CreateInvocationOptions CIOpts;
   CIOpts.VFS = llvm::vfs::createPhysicalFileSystem();
+  DiagnosticOptions DiagOpts;
   IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
-      CompilerInstance::createDiagnostics(*CIOpts.VFS, new DiagnosticOptions());
+      CompilerInstance::createDiagnostics(*CIOpts.VFS, DiagOpts);
   CIOpts.Diags = Diags;
 
   // First run should pass with no errors
diff --git a/clang/unittests/Serialization/NoCommentsTest.cpp b/clang/unittests/Serialization/NoCommentsTest.cpp
index 3aaaa548c6eff..05efeef990d43 100644
--- a/clang/unittests/Serialization/NoCommentsTest.cpp
+++ b/clang/unittests/Serialization/NoCommentsTest.cpp
@@ -85,8 +85,9 @@ void foo() {}
 
   CreateInvocationOptions CIOpts;
   CIOpts.VFS = llvm::vfs::createPhysicalFileSystem();
+  DiagnosticOptions DiagOpts;
   IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
-      CompilerInstance::createDiagnostics(*CIOpts.VFS, new DiagnosticOptions());
+      CompilerInstance::createDiagnostics(*CIOpts.VFS, DiagOpts);
   CIOpts.Diags = Diags;
 
   std::string CacheBMIPath = llvm::Twine(TestDir + "/Comments.pcm").str();
diff --git a/clang/unittests/Serialization/PreambleInNamedModulesTest.cpp b/clang/unittests/Serialization/PreambleInNamedModulesTest.cpp
index 7a037d22d5c0d..c43520f79b02c 100644
--- a/clang/unittests/Serialization/PreambleInNamedModulesTest.cpp
+++ b/clang/unittests/Serialization/PreambleInNamedModulesTest.cpp
@@ -77,8 +77,9 @@ export using ::E;
 
   IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS =
       llvm::vfs::createPhysicalFileSystem();
+  DiagnosticOptions DiagOpts;
   IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
-      CompilerInstance::createDiagnostics(*VFS, new DiagnosticOptions());
+      CompilerInstance::createDiagnostics(*VFS, DiagOpts);
 
   CreateInvocationOptions CIOpts;
   CIOpts.Diags = Diags;
diff --git a/clang/unittests/Serialization/VarDeclConstantInitTest.cpp b/clang/unittests/Serialization/VarDeclConstantInitTest.cpp
index 33c3c6b5e61fd..5b2988ed26336 100644
--- a/clang/unittests/Serialization/VarDeclConstantInitTest.cpp
+++ b/clang/unittests/Serialization/VarDeclConstantInitTest.cpp
@@ -92,8 +92,9 @@ export namespace Fibonacci
 
   CreateInvocationOptions CIOpts;
   CIOpts.VFS = llvm::vfs::createPhysicalFileSystem();
+  DiagnosticOptions DiagOpts;
   IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
-      CompilerInstance::createDiagnostics(*CIOpts.VFS, new DiagnosticOptions());
+      CompilerInstance::createDiagnostics(*CIOpts.VFS, DiagOpts);
   CIOpts.Diags = Diags;
 
   const char *Args[] = {"clang++",       "-std=c++20",
diff --git a/clang/unittests/Support/TimeProfilerTest.cpp b/clang/unittests/Support/TimeProfilerTest.cpp
index 7698742426dfc..b2b77ec530c27 100644
--- a/clang/unittests/Support/TimeProfilerTest.cpp
+++ b/clang/unittests/Support/TimeProfilerTest.cpp
@@ -58,9 +58,9 @@ bool compileFromString(StringRef Code, StringRef Standard, StringRef File,
 
   auto Invocation = std::make_shared<CompilerInvocation>();
   std::vector<const char *> Args = {Standard.data(), File.data()};
-  auto InvocationDiagOpts = llvm::makeIntrusiveRefCnt<DiagnosticOptions>();
+  DiagnosticOptions InvocationDiagOpts;
   auto InvocationDiags =
-      CompilerInstance::createDiagnostics(*FS, InvocationDiagOpts.get());
+      CompilerInstance::createDiagnostics(*FS, InvocationDiagOpts);
   CompilerInvocation::CreateFromArgs(*Invocation, Args, *InvocationDiags);
 
   CompilerInstance Compiler(std::move(Invocation));
diff --git a/clang/unittests/Tooling/RewriterTestContext.h b/clang/unittests/Tooling/RewriterTestContext.h
index b7aa1a133c83e..8ad164fe7183a 100644
--- a/clang/unittests/Tooling/RewriterTestContext.h
+++ b/clang/unittests/Tooling/RewriterTestContext.h
@@ -49,9 +49,8 @@ struct RewriterDiagnosticConsumer : public DiagnosticConsumer {
 class RewriterTestContext {
  public:
    RewriterTestContext()
-       : DiagOpts(new DiagnosticOptions()),
-         Diagnostics(IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),
-                     &*DiagOpts),
+       : Diagnostics(IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),
+                     DiagOpts),
          InMemoryFileSystem(new llvm::vfs::InMemoryFileSystem),
          OverlayFileSystem(
              new llvm::vfs::OverlayFileSystem(llvm::vfs::getRealFileSystem())),
@@ -124,7 +123,7 @@ class RewriterTestContext {
     return std::string((*FileBuffer)->getBuffer());
   }
 
-  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
+  DiagnosticOptions DiagOpts;
   DiagnosticsEngine Diagnostics;
   RewriterDiagnosticConsumer DiagnosticPrinter;
   IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem;
diff --git a/clang/unittests/Tooling/Syntax/TokensTest.cpp b/clang/unittests/Tooling/Syntax/TokensTest.cpp
index d42273be1858c..b5f44454e862d 100644
--- a/clang/unittests/Tooling/Syntax/TokensTest.cpp
+++ b/clang/unittests/Tooling/Syntax/TokensTest.cpp
@@ -248,8 +248,9 @@ class TokenCollectorTest : public ::testing::Test {
   }
 
   // Data fields.
+  DiagnosticOptions DiagOpts;
   llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
-      new DiagnosticsEngine(new DiagnosticIDs, new DiagnosticOptions);
+      new DiagnosticsEngine(new DiagnosticIDs, DiagOpts);
   IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> FS =
       new llvm::vfs::InMemoryFileSystem;
   llvm::IntrusiveRefCntPtr<FileManager> FileMgr =
diff --git a/clang/unittests/Tooling/Syntax/TreeTestBase.cpp b/clang/unittests/Tooling/Syntax/TreeTestBase.cpp
index 7710a9cc5a743..9f22b1d64c913 100644
--- a/clang/unittests/Tooling/Syntax/TreeTestBase.cpp
+++ b/clang/unittests/Tooling/Syntax/TreeTestBase.cpp
@@ -126,7 +126,7 @@ SyntaxTreeTest::buildTree(StringRef Code, const TestClangConfig &ClangConfig) {
   FS->addFile(FileName, time_t(), llvm::MemoryBuffer::getMemBufferCopy(""));
 
   if (!Diags->getClient())
-    Diags->setClient(new TextDiagnosticPrinter(llvm::errs(), DiagOpts.get()));
+    Diags->setClient(new TextDiagnosticPrinter(llvm::errs(), DiagOpts));
   Diags->setSeverityForGroup(diag::Flavor::WarningOrError, "unused-value",
                              diag::Severity::Ignored, SourceLocation());
 
diff --git a/clang/unittests/Tooling/Syntax/TreeTestBase.h b/clang/unittests/Tooling/Syntax/TreeTestBase.h
index 1176f457cf8b3..6110cffa708d9 100644
--- a/clang/unittests/Tooling/Syntax/TreeTestBase.h
+++ b/clang/unittests/Tooling/Syntax/TreeTestBase.h
@@ -40,9 +40,9 @@ class SyntaxTreeTest : public ::testing::Test,
   syntax::Node *nodeByRange(llvm::Annotations::Range R, syntax::Node *Root);
 
   // Data fields.
-  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
+  DiagnosticOptions DiagOpts;
   IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
-      new DiagnosticsEngine(new DiagnosticIDs, DiagOpts.get());
+      new DiagnosticsEngine(new DiagnosticIDs, DiagOpts);
   IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> FS =
       new llvm::vfs::InMemoryFileSystem;
   IntrusiveRefCntPtr<FileManager> FileMgr =
diff --git a/clang/unittests/Tooling/ToolingTest.cpp b/clang/unittests/Tooling/ToolingTest.cpp
index 8cdfffb54390e..0c726f0835ebe 100644
--- a/clang/unittests/Tooling/ToolingTest.cpp
+++ b/clang/unittests/Tooling/ToolingTest.cpp
@@ -294,8 +294,8 @@ TEST(ToolInvocation, CustomDiagnosticOptionsOverwriteParsedOnes) {
   Invocation.setDiagnosticConsumer(&Consumer);
 
   // Inject custom `DiagnosticOptions` for command-line parsing.
-  auto DiagOpts = llvm::makeIntrusiveRefCnt<DiagnosticOptions>();
-  Invocation.setDiagnosticOptions(&*DiagOpts);
+  DiagnosticOptions DiagOpts;
+  Invocation.setDiagnosticOptions(&DiagOpts);
 
   EXPECT_TRUE(Invocation.run());
   // Check that the warning was issued during command-line parsing due to the
@@ -392,14 +392,14 @@ overlayRealFS(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) {
 
 struct CommandLineExtractorTest : public ::testing::Test {
   llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFS;
+  DiagnosticOptions DiagOpts;
   llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
   driver::Driver Driver;
 
 public:
   CommandLineExtractorTest()
       : InMemoryFS(new llvm::vfs::InMemoryFileSystem),
-        Diags(CompilerInstance::createDiagnostics(*InMemoryFS,
-                                                  new DiagnosticOptions)),
+        Diags(CompilerInstance::createDiagnostics(*InMemoryFS, DiagOpts)),
         Driver("clang", llvm::sys::getDefaultTargetTriple(), *Diags,
                "clang LLVM compiler", overlayRealFS(InMemoryFS)) {}
 

>From 79d809af3d853d7f8e530795a85a12d212fc76aa Mon Sep 17 00:00:00 2001
From: Jan Svoboda <jan_svoboda at apple.com>
Date: Mon, 12 May 2025 08:50:46 -0700
Subject: [PATCH 3/8] Fixup ASTUnit lifetimes

---
 clang/include/clang/Frontend/ASTUnit.h       |  2 ++
 clang/lib/CrossTU/CrossTranslationUnit.cpp   |  3 ++-
 clang/lib/Frontend/ASTUnit.cpp               |  2 ++
 clang/tools/libclang/CIndex.cpp              |  4 ++--
 clang/unittests/Frontend/ASTUnitTest.cpp     | 15 ++++++++-------
 clang/unittests/Frontend/PCHPreambleTest.cpp |  5 +++--
 6 files changed, 19 insertions(+), 12 deletions(-)

diff --git a/clang/include/clang/Frontend/ASTUnit.h b/clang/include/clang/Frontend/ASTUnit.h
index ac99f0fb2b471..b1fbc9f9f8ee3 100644
--- a/clang/include/clang/Frontend/ASTUnit.h
+++ b/clang/include/clang/Frontend/ASTUnit.h
@@ -107,6 +107,7 @@ class ASTUnit {
 
 private:
   std::unique_ptr<LangOptions> LangOpts;
+  std::shared_ptr<DiagnosticOptions> DiagOpts;
   IntrusiveRefCntPtr<DiagnosticsEngine>   Diagnostics;
   IntrusiveRefCntPtr<FileManager>         FileMgr;
   IntrusiveRefCntPtr<SourceManager>       SourceMgr;
@@ -837,6 +838,7 @@ class ASTUnit {
   static std::unique_ptr<ASTUnit> LoadFromCommandLine(
       const char **ArgBegin, const char **ArgEnd,
       std::shared_ptr<PCHContainerOperations> PCHContainerOps,
+      std::shared_ptr<DiagnosticOptions> DiagOpts,
       IntrusiveRefCntPtr<DiagnosticsEngine> Diags, StringRef ResourceFilesPath,
       bool StorePreamblesInMemory = false,
       StringRef PreambleStoragePath = StringRef(), bool OnlyLocalDecls = false,
diff --git a/clang/lib/CrossTU/CrossTranslationUnit.cpp b/clang/lib/CrossTU/CrossTranslationUnit.cpp
index 9401587456f0e..c268b5996bd75 100644
--- a/clang/lib/CrossTU/CrossTranslationUnit.cpp
+++ b/clang/lib/CrossTU/CrossTranslationUnit.cpp
@@ -604,6 +604,7 @@ CrossTranslationUnitContext::ASTLoader::loadFromSource(
                  [](auto &&CmdPart) { return CmdPart.c_str(); });
 
   auto *DiagClient = new ForwardingDiagnosticConsumer{CI.getDiagnosticClient()};
+  auto DiagOpts = std::make_shared<DiagnosticOptions>(CI.getDiagnosticOpts());
   IntrusiveRefCntPtr<DiagnosticIDs> DiagID{
       CI.getDiagnostics().getDiagnosticIDs()};
   IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
@@ -611,7 +612,7 @@ CrossTranslationUnitContext::ASTLoader::loadFromSource(
 
   return ASTUnit::LoadFromCommandLine(CommandLineArgs.begin(),
                                       (CommandLineArgs.end()),
-                                      CI.getPCHContainerOperations(), Diags,
+                                      CI.getPCHContainerOperations(),DiagOpts, Diags,
                                       CI.getHeaderSearchOpts().ResourceDir);
 }
 
diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp
index 35f823e9407db..29cb5c9f6835e 100644
--- a/clang/lib/Frontend/ASTUnit.cpp
+++ b/clang/lib/Frontend/ASTUnit.cpp
@@ -1766,6 +1766,7 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromCompilerInvocation(
 std::unique_ptr<ASTUnit> ASTUnit::LoadFromCommandLine(
     const char **ArgBegin, const char **ArgEnd,
     std::shared_ptr<PCHContainerOperations> PCHContainerOps,
+    std::shared_ptr<DiagnosticOptions> DiagOpts,
     IntrusiveRefCntPtr<DiagnosticsEngine> Diags, StringRef ResourceFilesPath,
     bool StorePreamblesInMemory, StringRef PreambleStoragePath,
     bool OnlyLocalDecls, CaptureDiagsKind CaptureDiagnostics,
@@ -1828,6 +1829,7 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromCommandLine(
   AST->NumStoredDiagnosticsFromDriver = StoredDiagnostics.size();
   AST->StoredDiagnostics.swap(StoredDiagnostics);
   ConfigureDiags(Diags, *AST, CaptureDiagnostics);
+  AST->DiagOpts = DiagOpts;
   AST->Diagnostics = Diags;
   AST->FileSystemOpts = CI->getFileSystemOpts();
   VFS = createVFSFromCompilerInvocation(*CI, *Diags, VFS);
diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp
index 6ab078a997e17..16cca3e1b0059 100644
--- a/clang/tools/libclang/CIndex.cpp
+++ b/clang/tools/libclang/CIndex.cpp
@@ -4300,7 +4300,7 @@ clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
   }
 
   // Configure the diagnostics.
-  std::unique_ptr<DiagnosticOptions> DiagOpts = CreateAndPopulateDiagOpts(
+  std::shared_ptr<DiagnosticOptions> DiagOpts = CreateAndPopulateDiagOpts(
       llvm::ArrayRef(command_line_args, num_command_line_args));
   IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
       CompilerInstance::createDiagnostics(*llvm::vfs::getRealFileSystem(),
@@ -4388,7 +4388,7 @@ clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
       options, llvm::ArrayRef(*Args), /*InvocationArgs=*/{}, unsaved_files);
   std::unique_ptr<ASTUnit> Unit = ASTUnit::LoadFromCommandLine(
       Args->data(), Args->data() + Args->size(),
-      CXXIdx->getPCHContainerOperations(), Diags,
+      CXXIdx->getPCHContainerOperations(), DiagOpts, Diags,
       CXXIdx->getClangResourcesPath(), CXXIdx->getStorePreamblesInMemory(),
       CXXIdx->getPreambleStoragePath(), CXXIdx->getOnlyLocalDecls(),
       CaptureDiagnostics, *RemappedFiles.get(),
diff --git a/clang/unittests/Frontend/ASTUnitTest.cpp b/clang/unittests/Frontend/ASTUnitTest.cpp
index ffb082ce545bc..a091d93860248 100644
--- a/clang/unittests/Frontend/ASTUnitTest.cpp
+++ b/clang/unittests/Frontend/ASTUnitTest.cpp
@@ -30,7 +30,8 @@ class ASTUnitTest : public ::testing::Test {
   int FD;
   llvm::SmallString<256> InputFileName;
   std::unique_ptr<ToolOutputFile> input_file;
-  DiagnosticOptions DiagOpts;
+  std::shared_ptr<DiagnosticOptions> DiagOpts =
+      std::make_shared<DiagnosticOptions>();
   IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
   std::shared_ptr<CompilerInvocation> CInvok;
   std::shared_ptr<PCHContainerOperations> PCHContainerOps;
@@ -44,7 +45,7 @@ class ASTUnitTest : public ::testing::Test {
     const char *Args[] = {"clang", "-xc++", InputFileName.c_str()};
 
     auto VFS = llvm::vfs::getRealFileSystem();
-    Diags = CompilerInstance::createDiagnostics(*VFS, DiagOpts);
+    Diags = CompilerInstance::createDiagnostics(*VFS, *DiagOpts);
 
     CreateInvocationOptions CIOpts;
     CIOpts.Diags = Diags;
@@ -138,7 +139,7 @@ TEST_F(ASTUnitTest, ModuleTextualHeader) {
   const char *Args[] = {"clang", "test.cpp", "-fmodule-map-file=m.modulemap",
                         "-fmodule-name=M"};
   Diags =
-      CompilerInstance::createDiagnostics(*InMemoryFs, DiagOpts);
+      CompilerInstance::createDiagnostics(*InMemoryFs, *DiagOpts);
   CreateInvocationOptions CIOpts;
   CIOpts.Diags = Diags;
   CInvok = createInvocation(Args, std::move(CIOpts));
@@ -167,12 +168,12 @@ TEST_F(ASTUnitTest, LoadFromCommandLineEarlyError) {
   const char *Args[] = {"clang", "-target", "foobar", InputFileName.c_str()};
 
   auto Diags = CompilerInstance::createDiagnostics(
-      *llvm::vfs::getRealFileSystem(), DiagOpts);
+      *llvm::vfs::getRealFileSystem(), *DiagOpts);
   auto PCHContainerOps = std::make_shared<PCHContainerOperations>();
   std::unique_ptr<clang::ASTUnit> ErrUnit;
 
   std::unique_ptr<ASTUnit> AST = ASTUnit::LoadFromCommandLine(
-      &Args[0], &Args[4], PCHContainerOps, Diags, "", false, "", false,
+      &Args[0], &Args[4], PCHContainerOps, DiagOpts, Diags, "", false, "", false,
       CaptureDiagsKind::All, {}, true, 0, TU_Complete, false, false, false,
       SkipFunctionBodiesScope::None, false, true, false, false, std::nullopt,
       &ErrUnit, nullptr);
@@ -195,12 +196,12 @@ TEST_F(ASTUnitTest, LoadFromCommandLineWorkingDirectory) {
                         InputFileName.c_str()};
 
   auto Diags = CompilerInstance::createDiagnostics(
-      *llvm::vfs::getRealFileSystem(), DiagOpts);
+      *llvm::vfs::getRealFileSystem(), *DiagOpts);
   auto PCHContainerOps = std::make_shared<PCHContainerOperations>();
   std::unique_ptr<clang::ASTUnit> ErrUnit;
 
   std::unique_ptr<ASTUnit> AST = ASTUnit::LoadFromCommandLine(
-      &Args[0], &Args[4], PCHContainerOps, Diags, "", false, "", false,
+      &Args[0], &Args[4], PCHContainerOps, DiagOpts, Diags, "", false, "", false,
       CaptureDiagsKind::All, {}, true, 0, TU_Complete, false, false, false,
       SkipFunctionBodiesScope::None, false, true, false, false, std::nullopt,
       &ErrUnit, nullptr);
diff --git a/clang/unittests/Frontend/PCHPreambleTest.cpp b/clang/unittests/Frontend/PCHPreambleTest.cpp
index 266372066aefe..50a35f2270bf9 100644
--- a/clang/unittests/Frontend/PCHPreambleTest.cpp
+++ b/clang/unittests/Frontend/PCHPreambleTest.cpp
@@ -53,6 +53,8 @@ class PCHPreambleTest : public ::testing::Test {
   IntrusiveRefCntPtr<ReadCountingInMemoryFileSystem> VFS;
   StringMap<std::string> RemappedFiles;
   std::shared_ptr<PCHContainerOperations> PCHContainerOpts;
+  std::shared_ptr<DiagnosticOptions> DiagOpts =
+      std::make_shared<DiagnosticOptions>();
   FileSystemOptions FSOpts;
 
 public:
@@ -94,9 +96,8 @@ class PCHPreambleTest : public ::testing::Test {
     PreprocessorOptions &PPOpts = CI->getPreprocessorOpts();
     PPOpts.RemappedFilesKeepOriginalName = true;
 
-    DiagnosticOptions DiagOpts;
     IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
-        CompilerInstance::createDiagnostics(*VFS, DiagOpts,
+        CompilerInstance::createDiagnostics(*VFS, *DiagOpts,
                                             new DiagnosticConsumer));
 
     FileManager *FileMgr = new FileManager(FSOpts, VFS);

>From e5e3fcf633557b34f4f341f17c8cc75f8df11fb8 Mon Sep 17 00:00:00 2001
From: Jan Svoboda <jan_svoboda at apple.com>
Date: Mon, 12 May 2025 09:09:49 -0700
Subject: [PATCH 4/8] Make check-clang-tools build

---
 .../tool/ClangApplyReplacementsMain.cpp       |  4 ++--
 .../tool/ClangChangeNamespace.cpp             |  6 ++---
 .../tool/ClangIncludeFixer.cpp                |  6 ++---
 .../clang-move/tool/ClangMove.cpp             |  6 ++---
 clang-tools-extra/clang-query/Query.cpp       |  2 +-
 .../tool/ClangReorderFields.cpp               |  6 ++---
 clang-tools-extra/clang-tidy/ClangTidy.cpp    | 22 +++++++++----------
 .../ClangTidyDiagnosticConsumer.cpp           |  4 ++--
 .../clang-tidy/ClangTidyDiagnosticConsumer.h  |  5 ++++-
 .../ExpandModularHeadersPPCallbacks.cpp       |  2 +-
 .../ExpandModularHeadersPPCallbacks.h         |  1 +
 clang-tools-extra/clangd/Compiler.cpp         |  3 ++-
 clang-tools-extra/clangd/ModulesBuilder.cpp   |  3 ++-
 clang-tools-extra/clangd/ParsedAST.cpp        |  3 ++-
 clang-tools-extra/clangd/Preamble.cpp         |  2 +-
 .../clangd/SystemIncludeExtractor.cpp         |  3 ++-
 .../clangd/unittests/ConfigCompileTests.cpp   |  3 ++-
 .../clangd/unittests/tweaks/TweakTests.cpp    |  3 ++-
 .../include-cleaner/unittests/RecordTest.cpp  |  4 ++--
 .../include-cleaner/unittests/WalkASTTest.cpp |  6 ++---
 .../modularize/ModularizeUtilities.cpp        |  5 ++---
 .../modularize/ModularizeUtilities.h          |  2 +-
 .../ApplyReplacementsTest.cpp                 |  4 ++--
 .../clang-tidy/ClangTidyOptionsTest.cpp       | 15 ++++++++-----
 .../unittests/clang-tidy/ClangTidyTest.h      |  5 +++--
 clang/lib/CrossTU/CrossTranslationUnit.cpp    |  4 ++--
 26 files changed, 71 insertions(+), 58 deletions(-)

diff --git a/clang-tools-extra/clang-apply-replacements/tool/ClangApplyReplacementsMain.cpp b/clang-tools-extra/clang-apply-replacements/tool/ClangApplyReplacementsMain.cpp
index 68b5743c6540f..062e236d3e51f 100644
--- a/clang-tools-extra/clang-apply-replacements/tool/ClangApplyReplacementsMain.cpp
+++ b/clang-tools-extra/clang-apply-replacements/tool/ClangApplyReplacementsMain.cpp
@@ -96,9 +96,9 @@ int main(int argc, char **argv) {
   cl::SetVersionPrinter(printVersion);
   cl::ParseCommandLineOptions(argc, argv);
 
-  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts(new DiagnosticOptions());
+  DiagnosticOptions DiagOpts;
   DiagnosticsEngine Diagnostics(
-      IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()), DiagOpts.get());
+      IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()), DiagOpts);
 
   // Determine a formatting style from options.
   auto FormatStyleOrError = format::getStyle(FormatStyleOpt, FormatStyleConfig,
diff --git a/clang-tools-extra/clang-change-namespace/tool/ClangChangeNamespace.cpp b/clang-tools-extra/clang-change-namespace/tool/ClangChangeNamespace.cpp
index 22d26db0c11bc..2a8fe2d06d185 100644
--- a/clang-tools-extra/clang-change-namespace/tool/ClangChangeNamespace.cpp
+++ b/clang-tools-extra/clang-change-namespace/tool/ClangChangeNamespace.cpp
@@ -126,10 +126,10 @@ int main(int argc, const char **argv) {
   if (int Result = Tool.run(Factory.get()))
     return Result;
   LangOptions DefaultLangOptions;
-  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
-  clang::TextDiagnosticPrinter DiagnosticPrinter(errs(), &*DiagOpts);
+  DiagnosticOptions DiagOpts;
+  clang::TextDiagnosticPrinter DiagnosticPrinter(errs(), DiagOpts);
   DiagnosticsEngine Diagnostics(
-      IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()), &*DiagOpts,
+      IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()), DiagOpts,
       &DiagnosticPrinter, false);
   auto &FileMgr = Tool.getFiles();
   SourceManager Sources(Diagnostics, FileMgr);
diff --git a/clang-tools-extra/clang-include-fixer/tool/ClangIncludeFixer.cpp b/clang-tools-extra/clang-include-fixer/tool/ClangIncludeFixer.cpp
index 6e51f25a66407..746ba7bcea015 100644
--- a/clang-tools-extra/clang-include-fixer/tool/ClangIncludeFixer.cpp
+++ b/clang-tools-extra/clang-include-fixer/tool/ClangIncludeFixer.cpp
@@ -455,9 +455,9 @@ int includeFixerMain(int argc, const char **argv) {
   }
 
   // Set up a new source manager for applying the resulting replacements.
-  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts(new DiagnosticOptions);
-  DiagnosticsEngine Diagnostics(new DiagnosticIDs, &*DiagOpts);
-  TextDiagnosticPrinter DiagnosticPrinter(outs(), &*DiagOpts);
+  DiagnosticOptions DiagOpts;
+  DiagnosticsEngine Diagnostics(new DiagnosticIDs, DiagOpts);
+  TextDiagnosticPrinter DiagnosticPrinter(outs(), DiagOpts);
   SourceManager SM(Diagnostics, tool.getFiles());
   Diagnostics.setClient(&DiagnosticPrinter, false);
 
diff --git a/clang-tools-extra/clang-move/tool/ClangMove.cpp b/clang-tools-extra/clang-move/tool/ClangMove.cpp
index 655ea81ee37d4..750eb952714f7 100644
--- a/clang-tools-extra/clang-move/tool/ClangMove.cpp
+++ b/clang-tools-extra/clang-move/tool/ClangMove.cpp
@@ -176,10 +176,10 @@ int main(int argc, const char **argv) {
     }
   }
 
-  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts(new DiagnosticOptions());
-  clang::TextDiagnosticPrinter DiagnosticPrinter(errs(), &*DiagOpts);
+  DiagnosticOptions DiagOpts;
+  clang::TextDiagnosticPrinter DiagnosticPrinter(errs(), DiagOpts);
   DiagnosticsEngine Diagnostics(
-      IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()), &*DiagOpts,
+      IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()), DiagOpts,
       &DiagnosticPrinter, false);
   auto &FileMgr = Tool.getFiles();
   SourceManager SM(Diagnostics, FileMgr);
diff --git a/clang-tools-extra/clang-query/Query.cpp b/clang-tools-extra/clang-query/Query.cpp
index 382aa5d6fe25e..574b64ee0f759 100644
--- a/clang-tools-extra/clang-query/Query.cpp
+++ b/clang-tools-extra/clang-query/Query.cpp
@@ -172,7 +172,7 @@ bool MatchQuery::run(llvm::raw_ostream &OS, QuerySession &QS) const {
           clang::SourceRange R = BI->second.getSourceRange();
           if (R.isValid()) {
             TextDiagnostic TD(OS, AST->getASTContext().getLangOpts(),
-                              &AST->getDiagnostics().getDiagnosticOptions());
+                              AST->getDiagnostics().getDiagnosticOptions());
             TD.emitDiagnostic(
                 FullSourceLoc(R.getBegin(), AST->getSourceManager()),
                 DiagnosticsEngine::Note, "\"" + BI->first + "\" binds here",
diff --git a/clang-tools-extra/clang-reorder-fields/tool/ClangReorderFields.cpp b/clang-tools-extra/clang-reorder-fields/tool/ClangReorderFields.cpp
index 5b77ee7b5738c..03502525417b2 100644
--- a/clang-tools-extra/clang-reorder-fields/tool/ClangReorderFields.cpp
+++ b/clang-tools-extra/clang-reorder-fields/tool/ClangReorderFields.cpp
@@ -72,10 +72,10 @@ int main(int argc, const char **argv) {
 
   int ExitCode = Tool.run(Factory.get());
   LangOptions DefaultLangOptions;
-  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts(new DiagnosticOptions());
-  TextDiagnosticPrinter DiagnosticPrinter(errs(), &*DiagOpts);
+  DiagnosticOptions DiagOpts;
+  TextDiagnosticPrinter DiagnosticPrinter(errs(), DiagOpts);
   DiagnosticsEngine Diagnostics(
-      IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()), &*DiagOpts,
+      IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()), DiagOpts,
       &DiagnosticPrinter, false);
 
   auto &FileMgr = Tool.getFiles();
diff --git a/clang-tools-extra/clang-tidy/ClangTidy.cpp b/clang-tools-extra/clang-tidy/ClangTidy.cpp
index 733a53a0f5dcc..3c0531ffdc593 100644
--- a/clang-tools-extra/clang-tidy/ClangTidy.cpp
+++ b/clang-tools-extra/clang-tidy/ClangTidy.cpp
@@ -97,15 +97,14 @@ class ErrorReporter {
   ErrorReporter(ClangTidyContext &Context, FixBehaviour ApplyFixes,
                 llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS)
       : Files(FileSystemOptions(), std::move(BaseFS)),
-        DiagOpts(new DiagnosticOptions()),
-        DiagPrinter(new TextDiagnosticPrinter(llvm::outs(), &*DiagOpts)),
-        Diags(IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs), &*DiagOpts,
+        DiagPrinter(new TextDiagnosticPrinter(llvm::outs(), DiagOpts)),
+        Diags(IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs), DiagOpts,
               DiagPrinter),
         SourceMgr(Diags, Files), Context(Context), ApplyFixes(ApplyFixes) {
-    DiagOpts->ShowColors = Context.getOptions().UseColor.value_or(
+    DiagOpts.ShowColors = Context.getOptions().UseColor.value_or(
         llvm::sys::Process::StandardOutHasColors());
     DiagPrinter->BeginSourceFile(LangOpts);
-    if (DiagOpts->ShowColors && !llvm::sys::Process::StandardOutIsDisplayed()) {
+    if (DiagOpts.ShowColors && !llvm::sys::Process::StandardOutIsDisplayed()) {
       llvm::sys::Process::UseANSIEscapeCodes(true);
     }
   }
@@ -308,7 +307,7 @@ class ErrorReporter {
 
   FileManager Files;
   LangOptions LangOpts; // FIXME: use langopts from each original file
-  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
+  DiagnosticOptions DiagOpts;
   DiagnosticConsumer *DiagPrinter;
   DiagnosticsEngine Diags;
   SourceManager SourceMgr;
@@ -516,10 +515,10 @@ getCheckOptions(const ClangTidyOptions &Options,
                                                 Options),
       AllowEnablingAnalyzerAlphaCheckers);
   ClangTidyDiagnosticConsumer DiagConsumer(Context);
-  DiagnosticsEngine DE(llvm::makeIntrusiveRefCnt<DiagnosticIDs>(),
-                       llvm::makeIntrusiveRefCnt<DiagnosticOptions>(),
+  auto DiagOpts = std::make_unique<DiagnosticOptions>();
+  DiagnosticsEngine DE(llvm::makeIntrusiveRefCnt<DiagnosticIDs>(), *DiagOpts,
                        &DiagConsumer, /*ShouldOwnClient=*/false);
-  Context.setDiagnosticsEngine(&DE);
+  Context.setDiagnosticsEngine(std::move(DiagOpts), &DE);
   ClangTidyASTConsumerFactory Factory(Context);
   return Factory.getCheckOptions();
 }
@@ -558,9 +557,10 @@ runClangTidy(clang::tidy::ClangTidyContext &Context,
   Context.setProfileStoragePrefix(StoreCheckProfile);
 
   ClangTidyDiagnosticConsumer DiagConsumer(Context, nullptr, true, ApplyAnyFix);
-  DiagnosticsEngine DE(new DiagnosticIDs(), new DiagnosticOptions(),
+  auto DiagOpts = std::make_unique<DiagnosticOptions>();
+  DiagnosticsEngine DE(new DiagnosticIDs(), *DiagOpts,
                        &DiagConsumer, /*ShouldOwnClient=*/false);
-  Context.setDiagnosticsEngine(&DE);
+  Context.setDiagnosticsEngine(std::move(DiagOpts), &DE);
   Tool.setDiagnosticConsumer(&DiagConsumer);
 
   class ActionFactory : public FrontendActionFactory {
diff --git a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
index b216970bfbd8c..a0253a5fd1a48 100644
--- a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
+++ b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
@@ -49,7 +49,7 @@ namespace {
 class ClangTidyDiagnosticRenderer : public DiagnosticRenderer {
 public:
   ClangTidyDiagnosticRenderer(const LangOptions &LangOpts,
-                              DiagnosticOptions *DiagOpts,
+                              DiagnosticOptions &DiagOpts,
                               ClangTidyError &Error)
       : DiagnosticRenderer(LangOpts, DiagOpts), Error(Error) {}
 
@@ -429,7 +429,7 @@ void ClangTidyDiagnosticConsumer::HandleDiagnostic(
     forwardDiagnostic(Info);
   } else {
     ClangTidyDiagnosticRenderer Converter(
-        Context.getLangOpts(), &Context.DiagEngine->getDiagnosticOptions(),
+        Context.getLangOpts(), Context.DiagEngine->getDiagnosticOptions(),
         Errors.back());
     SmallString<100> Message;
     Info.FormatDiagnostic(Message);
diff --git a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h
index d6cf6a2b2731e..bd7a1bf2c11c7 100644
--- a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h
+++ b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h
@@ -75,7 +75,9 @@ class ClangTidyContext {
   /// Sets the DiagnosticsEngine that diag() will emit diagnostics to.
   // FIXME: this is required initialization, and should be a constructor param.
   // Fix the context -> diag engine -> consumer -> context initialization cycle.
-  void setDiagnosticsEngine(DiagnosticsEngine *DiagEngine) {
+  void setDiagnosticsEngine(std::unique_ptr<DiagnosticOptions> DiagOpts,
+                            DiagnosticsEngine *DiagEngine) {
+    this->DiagOpts = std::move(DiagOpts);
     this->DiagEngine = DiagEngine;
   }
 
@@ -231,6 +233,7 @@ class ClangTidyContext {
   // Writes to Stats.
   friend class ClangTidyDiagnosticConsumer;
 
+  std::unique_ptr<DiagnosticOptions> DiagOpts = nullptr;
   DiagnosticsEngine *DiagEngine = nullptr;
   std::unique_ptr<ClangTidyOptionsProvider> OptionsProvider;
 
diff --git a/clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.cpp b/clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.cpp
index 03a3e8404e069..6a84704434c33 100644
--- a/clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.cpp
+++ b/clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.cpp
@@ -71,7 +71,7 @@ ExpandModularHeadersPPCallbacks::ExpandModularHeadersPPCallbacks(
       InMemoryFs(new llvm::vfs::InMemoryFileSystem),
       Sources(Compiler.getSourceManager()),
       // Forward the new diagnostics to the original DiagnosticConsumer.
-      Diags(new DiagnosticIDs, new DiagnosticOptions,
+      Diags(new DiagnosticIDs, DiagOpts,
             new ForwardingDiagnosticConsumer(Compiler.getDiagnosticClient())),
       LangOpts(Compiler.getLangOpts()), HSOpts(Compiler.getHeaderSearchOpts()) {
   // Add a FileSystem containing the extra files needed in place of modular
diff --git a/clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.h b/clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.h
index a263681b3c633..c3478917ef498 100644
--- a/clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.h
+++ b/clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.h
@@ -128,6 +128,7 @@ class ExpandModularHeadersPPCallbacks : public PPCallbacks {
   llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFs;
 
   SourceManager &Sources;
+  DiagnosticOptions DiagOpts;
   DiagnosticsEngine Diags;
   LangOptions LangOpts;
   HeaderSearchOptions HSOpts;
diff --git a/clang-tools-extra/clangd/Compiler.cpp b/clang-tools-extra/clangd/Compiler.cpp
index 9be0152afd2f7..45096dff9f636 100644
--- a/clang-tools-extra/clangd/Compiler.cpp
+++ b/clang-tools-extra/clangd/Compiler.cpp
@@ -110,8 +110,9 @@ buildCompilerInvocation(const ParseInputs &Inputs, clang::DiagnosticConsumer &D,
   CIOpts.VFS = Inputs.TFS->view(Inputs.CompileCommand.Directory);
   CIOpts.CC1Args = CC1Args;
   CIOpts.RecoverOnError = true;
+  DiagnosticOptions DiagOpts;
   CIOpts.Diags = CompilerInstance::createDiagnostics(
-      *CIOpts.VFS, new DiagnosticOptions, &D, false);
+      *CIOpts.VFS, DiagOpts, &D, false);
   CIOpts.ProbePrecompiled = false;
   std::unique_ptr<CompilerInvocation> CI = createInvocation(ArgStrs, CIOpts);
   if (!CI)
diff --git a/clang-tools-extra/clangd/ModulesBuilder.cpp b/clang-tools-extra/clangd/ModulesBuilder.cpp
index c1878f91b5e16..4e4918f5650db 100644
--- a/clang-tools-extra/clangd/ModulesBuilder.cpp
+++ b/clang-tools-extra/clangd/ModulesBuilder.cpp
@@ -187,8 +187,9 @@ bool IsModuleFileUpToDate(PathRef ModuleFilePath,
   HSOpts.ValidateASTInputFilesContent = true;
 
   clang::clangd::IgnoreDiagnostics IgnoreDiags;
+  DiagnosticOptions DiagOpts;
   IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
-      CompilerInstance::createDiagnostics(*VFS, new DiagnosticOptions,
+      CompilerInstance::createDiagnostics(*VFS, DiagOpts,
                                           &IgnoreDiags,
                                           /*ShouldOwnClient=*/false);
 
diff --git a/clang-tools-extra/clangd/ParsedAST.cpp b/clang-tools-extra/clangd/ParsedAST.cpp
index 3f63daaf400db..9e1f6bb977226 100644
--- a/clang-tools-extra/clangd/ParsedAST.cpp
+++ b/clang-tools-extra/clangd/ParsedAST.cpp
@@ -556,7 +556,8 @@ ParsedAST::build(llvm::StringRef Filename, const ParseInputs &Inputs,
         *AllCTFactories, Cfg.Diagnostics.ClangTidy.FastCheckFilter);
     CTContext.emplace(std::make_unique<tidy::DefaultOptionsProvider>(
         tidy::ClangTidyGlobalOptions(), ClangTidyOpts));
-    CTContext->setDiagnosticsEngine(&Clang->getDiagnostics());
+    // The lifetime of DiagnosticOptions is managed by \c Clang.
+    CTContext->setDiagnosticsEngine(nullptr, &Clang->getDiagnostics());
     CTContext->setASTContext(&Clang->getASTContext());
     CTContext->setCurrentFile(Filename);
     CTContext->setSelfContainedDiags(true);
diff --git a/clang-tools-extra/clangd/Preamble.cpp b/clang-tools-extra/clangd/Preamble.cpp
index ba9a53db8a0dc..7b4d63ff197e7 100644
--- a/clang-tools-extra/clangd/Preamble.cpp
+++ b/clang-tools-extra/clangd/Preamble.cpp
@@ -615,7 +615,7 @@ buildPreamble(PathRef FileName, CompilerInvocation CI,
       });
   auto VFS = Inputs.TFS->view(Inputs.CompileCommand.Directory);
   llvm::IntrusiveRefCntPtr<DiagnosticsEngine> PreambleDiagsEngine =
-      CompilerInstance::createDiagnostics(*VFS, &CI.getDiagnosticOpts(),
+      CompilerInstance::createDiagnostics(*VFS, CI.getDiagnosticOpts(),
                                           &PreambleDiagnostics,
                                           /*ShouldOwnClient=*/false);
   const Config &Cfg = Config::current();
diff --git a/clang-tools-extra/clangd/SystemIncludeExtractor.cpp b/clang-tools-extra/clangd/SystemIncludeExtractor.cpp
index 6417bf8765622..0b067e8b0b2b2 100644
--- a/clang-tools-extra/clangd/SystemIncludeExtractor.cpp
+++ b/clang-tools-extra/clangd/SystemIncludeExtractor.cpp
@@ -253,7 +253,8 @@ namespace {
 bool isValidTarget(llvm::StringRef Triple) {
   std::shared_ptr<TargetOptions> TargetOpts(new TargetOptions);
   TargetOpts->Triple = Triple.str();
-  DiagnosticsEngine Diags(new DiagnosticIDs, new DiagnosticOptions,
+  DiagnosticOptions DiagOpts;
+  DiagnosticsEngine Diags(new DiagnosticIDs, DiagOpts,
                           new IgnoringDiagConsumer);
   llvm::IntrusiveRefCntPtr<TargetInfo> Target =
       TargetInfo::CreateTargetInfo(Diags, *TargetOpts);
diff --git a/clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp b/clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp
index c3e484a1a79c4..75d0ff244038d 100644
--- a/clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp
+++ b/clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp
@@ -298,7 +298,8 @@ TEST_F(ConfigCompileTests, DiagnosticSuppression) {
                                    "unreachable-code", "unused-variable",
                                    "typecheck_bool_condition",
                                    "unexpected_friend", "warn_alloca"));
-  clang::DiagnosticsEngine DiagEngine(new DiagnosticIDs, nullptr,
+  clang::DiagnosticOptions DiagOpts;
+  clang::DiagnosticsEngine DiagEngine(new DiagnosticIDs, DiagOpts,
                                       new clang::IgnoringDiagConsumer);
 
   using Diag = clang::Diagnostic;
diff --git a/clang-tools-extra/clangd/unittests/tweaks/TweakTests.cpp b/clang-tools-extra/clangd/unittests/tweaks/TweakTests.cpp
index 8bd40c1429012..e39b70224d97c 100644
--- a/clang-tools-extra/clangd/unittests/tweaks/TweakTests.cpp
+++ b/clang-tools-extra/clangd/unittests/tweaks/TweakTests.cpp
@@ -44,7 +44,8 @@ TEST(FileEdits, AbsolutePath) {
   for (const auto *Path : RelPaths)
     MemFS->addFile(Path, 0, llvm::MemoryBuffer::getMemBuffer("", Path));
   FileManager FM(FileSystemOptions(), MemFS);
-  DiagnosticsEngine DE(new DiagnosticIDs, new DiagnosticOptions);
+  DiagnosticOptions DiagOpts;
+  DiagnosticsEngine DE(new DiagnosticIDs, DiagOpts);
   SourceManager SM(DE, FM);
 
   for (const auto *Path : RelPaths) {
diff --git a/clang-tools-extra/include-cleaner/unittests/RecordTest.cpp b/clang-tools-extra/include-cleaner/unittests/RecordTest.cpp
index a10c0d5a54a95..91d2697712b6e 100644
--- a/clang-tools-extra/include-cleaner/unittests/RecordTest.cpp
+++ b/clang-tools-extra/include-cleaner/unittests/RecordTest.cpp
@@ -618,8 +618,8 @@ TEST_F(PragmaIncludeTest, ExportInUnnamedBuffer) {
                  llvm::MemoryBuffer::getMemBufferCopy(Extra.getValue(),
                                                       /*BufferName=*/""));
 
-  auto DiagOpts = llvm::makeIntrusiveRefCnt<DiagnosticOptions>();
-  auto Diags = CompilerInstance::createDiagnostics(*VFS, DiagOpts.get());
+  DiagnosticOptions DiagOpts;
+  auto Diags = CompilerInstance::createDiagnostics(*VFS, DiagOpts);
   auto Invocation = std::make_unique<CompilerInvocation>();
   ASSERT_TRUE(CompilerInvocation::CreateFromArgs(*Invocation, {Filename.data()},
                                                  *Diags, "clang"));
diff --git a/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp b/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
index e45ea36f7938e..5223eb563e4cb 100644
--- a/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
+++ b/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
@@ -85,9 +85,9 @@ std::vector<Decl::Kind> testWalk(llvm::StringRef TargetCode,
   // For each difference, show the target point in context, like a diagnostic.
   std::string DiagBuf;
   llvm::raw_string_ostream DiagOS(DiagBuf);
-  auto *DiagOpts = new DiagnosticOptions();
-  DiagOpts->ShowLevel = 0;
-  DiagOpts->ShowNoteIncludeStack = 0;
+  DiagnosticOptions DiagOpts;
+  DiagOpts.ShowLevel = 0;
+  DiagOpts.ShowNoteIncludeStack = 0;
   TextDiagnostic Diag(DiagOS, AST.context().getLangOpts(), DiagOpts);
   auto DiagnosePoint = [&](llvm::StringRef Message, unsigned Offset) {
     Diag.emitDiagnostic(
diff --git a/clang-tools-extra/modularize/ModularizeUtilities.cpp b/clang-tools-extra/modularize/ModularizeUtilities.cpp
index 576e863c8a9d2..919e51e607e79 100644
--- a/clang-tools-extra/modularize/ModularizeUtilities.cpp
+++ b/clang-tools-extra/modularize/ModularizeUtilities.cpp
@@ -48,10 +48,9 @@ ModularizeUtilities::ModularizeUtilities(std::vector<std::string> &InputPaths,
       MissingHeaderCount(0),
       // Init clang stuff needed for loading the module map and preprocessing.
       LangOpts(new LangOptions()), DiagIDs(new DiagnosticIDs()),
-      DiagnosticOpts(new DiagnosticOptions()),
-      DC(llvm::errs(), DiagnosticOpts.get()),
+      DC(llvm::errs(), DiagnosticOpts),
       Diagnostics(
-          new DiagnosticsEngine(DiagIDs, DiagnosticOpts.get(), &DC, false)),
+          new DiagnosticsEngine(DiagIDs, DiagnosticOpts, &DC, false)),
       TargetOpts(new ModuleMapTargetOptions()),
       Target(TargetInfo::CreateTargetInfo(*Diagnostics, *TargetOpts)),
       FileMgr(new FileManager(FileSystemOpts)),
diff --git a/clang-tools-extra/modularize/ModularizeUtilities.h b/clang-tools-extra/modularize/ModularizeUtilities.h
index 7b4c16a492b89..3242ea0c4b97e 100644
--- a/clang-tools-extra/modularize/ModularizeUtilities.h
+++ b/clang-tools-extra/modularize/ModularizeUtilities.h
@@ -198,7 +198,7 @@ class ModularizeUtilities {
   /// Diagnostic IDs.
   const llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> DiagIDs;
   /// Options controlling the diagnostic engine.
-  llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> DiagnosticOpts;
+  clang::DiagnosticOptions DiagnosticOpts;
   /// Diagnostic consumer.
   clang::TextDiagnosticPrinter DC;
   /// Diagnostic engine.
diff --git a/clang-tools-extra/unittests/clang-apply-replacements/ApplyReplacementsTest.cpp b/clang-tools-extra/unittests/clang-apply-replacements/ApplyReplacementsTest.cpp
index 4fe57e618004d..87b0d69f4654a 100644
--- a/clang-tools-extra/unittests/clang-apply-replacements/ApplyReplacementsTest.cpp
+++ b/clang-tools-extra/unittests/clang-apply-replacements/ApplyReplacementsTest.cpp
@@ -32,9 +32,9 @@ makeTUDiagnostics(const std::string &MainSourceFile, StringRef DiagnosticName,
 // Test to ensure diagnostics with no fixes, will be merged correctly
 // before applying.
 TEST(ApplyReplacementsTest, mergeDiagnosticsWithNoFixes) {
-  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts(new DiagnosticOptions());
+  DiagnosticOptions DiagOpts;
   DiagnosticsEngine Diagnostics(
-      IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()), DiagOpts.get());
+      IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()), DiagOpts);
   FileManager Files((FileSystemOptions()));
   SourceManager SM(Diagnostics, Files);
   TUReplacements TURs;
diff --git a/clang-tools-extra/unittests/clang-tidy/ClangTidyOptionsTest.cpp b/clang-tools-extra/unittests/clang-tidy/ClangTidyOptionsTest.cpp
index aaec0e6b50bbf..620e320257e16 100644
--- a/clang-tools-extra/unittests/clang-tidy/ClangTidyOptionsTest.cpp
+++ b/clang-tools-extra/unittests/clang-tidy/ClangTidyOptionsTest.cpp
@@ -317,9 +317,10 @@ TEST(CheckOptionsValidation, MissingOptions) {
   ClangTidyContext Context(std::make_unique<DefaultOptionsProvider>(
       ClangTidyGlobalOptions(), Options));
   ClangTidyDiagnosticConsumer DiagConsumer(Context);
-  DiagnosticsEngine DE(new DiagnosticIDs(), new DiagnosticOptions,
+  auto DiagOpts = std::make_unique<DiagnosticOptions>();
+  DiagnosticsEngine DE(new DiagnosticIDs(), *DiagOpts,
                        &DiagConsumer, false);
-  Context.setDiagnosticsEngine(&DE);
+  Context.setDiagnosticsEngine(std::move(DiagOpts), &DE);
   TestCheck TestCheck(&Context);
   EXPECT_FALSE(TestCheck.getLocal("Opt"));
   EXPECT_EQ(TestCheck.getLocal("Opt", "Unknown"), "Unknown");
@@ -347,9 +348,10 @@ TEST(CheckOptionsValidation, ValidIntOptions) {
   ClangTidyContext Context(std::make_unique<DefaultOptionsProvider>(
       ClangTidyGlobalOptions(), Options));
   ClangTidyDiagnosticConsumer DiagConsumer(Context);
-  DiagnosticsEngine DE(new DiagnosticIDs(), new DiagnosticOptions,
+  auto DiagOpts = std::make_unique<DiagnosticOptions>();
+  DiagnosticsEngine DE(new DiagnosticIDs(), *DiagOpts,
                        &DiagConsumer, false);
-  Context.setDiagnosticsEngine(&DE);
+  Context.setDiagnosticsEngine(std::move(DiagOpts), &DE);
   TestCheck TestCheck(&Context);
 
   CHECK_VAL(TestCheck.getIntLocal("IntExpected"), 1);
@@ -409,9 +411,10 @@ TEST(ValidConfiguration, ValidEnumOptions) {
   ClangTidyContext Context(std::make_unique<DefaultOptionsProvider>(
       ClangTidyGlobalOptions(), Options));
   ClangTidyDiagnosticConsumer DiagConsumer(Context);
-  DiagnosticsEngine DE(new DiagnosticIDs(), new DiagnosticOptions,
+  auto DiagOpts = std::make_unique<DiagnosticOptions>();
+  DiagnosticsEngine DE(new DiagnosticIDs(), *DiagOpts,
                        &DiagConsumer, false);
-  Context.setDiagnosticsEngine(&DE);
+  Context.setDiagnosticsEngine(std::move(DiagOpts), &DE);
   TestCheck TestCheck(&Context);
 
   CHECK_VAL(TestCheck.getIntLocal<Colours>("Valid"), Colours::Red);
diff --git a/clang-tools-extra/unittests/clang-tidy/ClangTidyTest.h b/clang-tools-extra/unittests/clang-tidy/ClangTidyTest.h
index e511eb6e49e8d..d1ab4ad4852e5 100644
--- a/clang-tools-extra/unittests/clang-tidy/ClangTidyTest.h
+++ b/clang-tools-extra/unittests/clang-tidy/ClangTidyTest.h
@@ -96,9 +96,10 @@ runCheckOnCode(StringRef Code, std::vector<ClangTidyError> *Errors = nullptr,
   ClangTidyContext Context(std::make_unique<DefaultOptionsProvider>(
       ClangTidyGlobalOptions(), Options));
   ClangTidyDiagnosticConsumer DiagConsumer(Context);
-  DiagnosticsEngine DE(new DiagnosticIDs(), new DiagnosticOptions,
+  auto DiagOpts = std::make_unique<DiagnosticOptions>();
+  DiagnosticsEngine DE(new DiagnosticIDs(), *DiagOpts,
                        &DiagConsumer, false);
-  Context.setDiagnosticsEngine(&DE);
+  Context.setDiagnosticsEngine(std::move(DiagOpts), &DE);
 
   std::vector<std::string> Args(1, "clang-tidy");
   Args.push_back("-fsyntax-only");
diff --git a/clang/lib/CrossTU/CrossTranslationUnit.cpp b/clang/lib/CrossTU/CrossTranslationUnit.cpp
index c268b5996bd75..b634fef3dc610 100644
--- a/clang/lib/CrossTU/CrossTranslationUnit.cpp
+++ b/clang/lib/CrossTU/CrossTranslationUnit.cpp
@@ -603,12 +603,12 @@ CrossTranslationUnitContext::ASTLoader::loadFromSource(
                  CommandLineArgs.begin(),
                  [](auto &&CmdPart) { return CmdPart.c_str(); });
 
-  auto *DiagClient = new ForwardingDiagnosticConsumer{CI.getDiagnosticClient()};
   auto DiagOpts = std::make_shared<DiagnosticOptions>(CI.getDiagnosticOpts());
+  auto *DiagClient = new ForwardingDiagnosticConsumer{CI.getDiagnosticClient()};
   IntrusiveRefCntPtr<DiagnosticIDs> DiagID{
       CI.getDiagnostics().getDiagnosticIDs()};
   IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
-      new DiagnosticsEngine{DiagID, CI.getDiagnosticOpts(), DiagClient});
+      new DiagnosticsEngine{DiagID, *DiagOpts, DiagClient});
 
   return ASTUnit::LoadFromCommandLine(CommandLineArgs.begin(),
                                       (CommandLineArgs.end()),

>From a9b41ab632f4b336a1094106d6f7efad3653f7e9 Mon Sep 17 00:00:00 2001
From: Jan Svoboda <jan_svoboda at apple.com>
Date: Mon, 12 May 2025 09:18:57 -0700
Subject: [PATCH 5/8] Make LLDB build

---
 .../Clang/ClangExpressionParser.cpp              | 10 +++++-----
 .../Clang/ClangExpressionSourceCode.cpp          |  3 +--
 .../Clang/ClangModulesDeclVendor.cpp             | 16 +++++++++++-----
 .../Language/ClangCommon/ClangHighlighter.cpp    |  3 +--
 .../Plugins/TypeSystem/Clang/TypeSystemClang.cpp |  3 ++-
 .../Plugins/TypeSystem/Clang/TypeSystemClang.h   |  1 +
 6 files changed, 21 insertions(+), 15 deletions(-)

diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
index 25b4c8b876265..959cbb282b043 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
@@ -166,13 +166,12 @@ static void AddAllFixIts(ClangDiagnostic *diag, const clang::Diagnostic &Info) {
 class ClangDiagnosticManagerAdapter : public clang::DiagnosticConsumer {
 public:
   ClangDiagnosticManagerAdapter(DiagnosticOptions &opts, StringRef filename)
-      : m_filename(filename) {
-    DiagnosticOptions *options = new DiagnosticOptions(opts);
-    options->ShowPresumedLoc = true;
-    options->ShowLevel = false;
+      : m_options(opts), m_filename(filename) {
+    m_options.ShowPresumedLoc = true;
+    m_options.ShowLevel = false;
     m_os = std::make_shared<llvm::raw_string_ostream>(m_output);
     m_passthrough =
-        std::make_shared<clang::TextDiagnosticPrinter>(*m_os, options);
+        std::make_shared<clang::TextDiagnosticPrinter>(*m_os, m_options);
   }
 
   void ResetManager(DiagnosticManager *manager = nullptr) {
@@ -313,6 +312,7 @@ class ClangDiagnosticManagerAdapter : public clang::DiagnosticConsumer {
 
 private:
   DiagnosticManager *m_manager = nullptr;
+  DiagnosticOptions m_options;
   std::shared_ptr<clang::TextDiagnosticPrinter> m_passthrough;
   /// Output stream of m_passthrough.
   std::shared_ptr<llvm::raw_string_ostream> m_os;
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp
index 3b601726388d6..d824c7e8d2911 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp
@@ -261,8 +261,7 @@ TokenVerifier::TokenVerifier(std::string body) {
   // Let's build the actual source code Clang needs and setup some utility
   // objects.
   llvm::IntrusiveRefCntPtr<DiagnosticIDs> diag_ids(new DiagnosticIDs());
-  llvm::IntrusiveRefCntPtr<DiagnosticOptions> diags_opts(
-      new DiagnosticOptions());
+  DiagnosticOptions diags_opts;
   DiagnosticsEngine diags(diag_ids, diags_opts);
   clang::SourceManager SM(diags, file_mgr);
   auto buf = llvm::MemoryBuffer::getMemBuffer(body);
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
index eee6166e43f98..99637610dafd1 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
@@ -66,6 +66,7 @@ class StoringDiagnosticConsumer : public clang::DiagnosticConsumer {
   typedef std::pair<clang::DiagnosticsEngine::Level, std::string>
       IDAndDiagnostic;
   std::vector<IDAndDiagnostic> m_diagnostics;
+  std::unique_ptr<clang::DiagnosticOptions> m_diag_opts;
   /// The DiagnosticPrinter used for creating the full diagnostic messages
   /// that are stored in m_diagnostics.
   std::unique_ptr<clang::TextDiagnosticPrinter> m_diag_printer;
@@ -83,6 +84,7 @@ class StoringDiagnosticConsumer : public clang::DiagnosticConsumer {
 class ClangModulesDeclVendorImpl : public ClangModulesDeclVendor {
 public:
   ClangModulesDeclVendorImpl(
+      std::unique_ptr<clang::DiagnosticOptions> diagnostic_options,
       llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> diagnostics_engine,
       std::shared_ptr<clang::CompilerInvocation> compiler_invocation,
       std::unique_ptr<clang::CompilerInstance> compiler_instance,
@@ -115,6 +117,7 @@ class ClangModulesDeclVendorImpl : public ClangModulesDeclVendor {
 
   bool m_enabled = false;
 
+  std::unique_ptr<clang::DiagnosticOptions> m_diagnostic_options;
   llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> m_diagnostics_engine;
   std::shared_ptr<clang::CompilerInvocation> m_compiler_invocation;
   std::unique_ptr<clang::CompilerInstance> m_compiler_instance;
@@ -134,10 +137,10 @@ class ClangModulesDeclVendorImpl : public ClangModulesDeclVendor {
 } // anonymous namespace
 
 StoringDiagnosticConsumer::StoringDiagnosticConsumer() {
-  auto *options = new clang::DiagnosticOptions();
+  m_diag_opts = std::make_unique<clang::DiagnosticOptions>();
   m_os = std::make_unique<llvm::raw_string_ostream>(m_output);
   m_diag_printer =
-      std::make_unique<clang::TextDiagnosticPrinter>(*m_os, options);
+      std::make_unique<clang::TextDiagnosticPrinter>(*m_os, *m_diag_opts);
 }
 
 void StoringDiagnosticConsumer::HandleDiagnostic(
@@ -228,11 +231,13 @@ ClangModulesDeclVendor::ClangModulesDeclVendor()
 ClangModulesDeclVendor::~ClangModulesDeclVendor() = default;
 
 ClangModulesDeclVendorImpl::ClangModulesDeclVendorImpl(
+    std::unique_ptr<clang::DiagnosticOptions> diagnostic_options,
     llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> diagnostics_engine,
     std::shared_ptr<clang::CompilerInvocation> compiler_invocation,
     std::unique_ptr<clang::CompilerInstance> compiler_instance,
     std::unique_ptr<clang::Parser> parser)
-    : m_diagnostics_engine(std::move(diagnostics_engine)),
+    : m_diagnostic_options(std::move(diagnostic_options)),
+      m_diagnostics_engine(std::move(diagnostics_engine)),
       m_compiler_invocation(std::move(compiler_invocation)),
       m_compiler_instance(std::move(compiler_instance)),
       m_parser(std::move(parser)) {
@@ -707,7 +712,7 @@ ClangModulesDeclVendor::Create(Target &target) {
   llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> diagnostics_engine =
       clang::CompilerInstance::createDiagnostics(
           *FileSystem::Instance().GetVirtualFileSystem(),
-          diag_options_up.release(), new StoringDiagnosticConsumer);
+          *diag_options_up, new StoringDiagnosticConsumer);
 
   Log *log = GetLog(LLDBLog::Expressions);
   LLDB_LOG(log, "ClangModulesDeclVendor's compiler flags {0:$[ ]}",
@@ -767,7 +772,8 @@ ClangModulesDeclVendor::Create(Target &target) {
   while (!parser->ParseTopLevelDecl(parsed, ImportState))
     ;
 
-  return new ClangModulesDeclVendorImpl(std::move(diagnostics_engine),
+  return new ClangModulesDeclVendorImpl(std::move(diag_options_up),
+                                        std::move(diagnostics_engine),
                                         std::move(invocation),
                                         std::move(instance), std::move(parser));
 }
diff --git a/lldb/source/Plugins/Language/ClangCommon/ClangHighlighter.cpp b/lldb/source/Plugins/Language/ClangCommon/ClangHighlighter.cpp
index 6e56e29f8c31c..8cc5714d0f0fc 100644
--- a/lldb/source/Plugins/Language/ClangCommon/ClangHighlighter.cpp
+++ b/lldb/source/Plugins/Language/ClangCommon/ClangHighlighter.cpp
@@ -163,8 +163,7 @@ void ClangHighlighter::Highlight(const HighlightStyle &options,
   // objects.
   std::string full_source = previous_lines.str() + line.str();
   llvm::IntrusiveRefCntPtr<DiagnosticIDs> diag_ids(new DiagnosticIDs());
-  llvm::IntrusiveRefCntPtr<DiagnosticOptions> diags_opts(
-      new DiagnosticOptions());
+  DiagnosticOptions diags_opts;
   DiagnosticsEngine diags(diag_ids, diags_opts);
   clang::SourceManager SM(diags, file_mgr);
   auto buf = llvm::MemoryBuffer::getMemBuffer(full_source);
diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
index 3b286885cc37f..ff2242a42dbdf 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
@@ -680,8 +680,9 @@ void TypeSystemClang::CreateASTContext() {
       file_system_options, FileSystem::Instance().GetVirtualFileSystem());
 
   llvm::IntrusiveRefCntPtr<DiagnosticIDs> diag_id_sp(new DiagnosticIDs());
+  m_diagnostic_options_up = std::make_unique<DiagnosticOptions>();
   m_diagnostics_engine_up =
-      std::make_unique<DiagnosticsEngine>(diag_id_sp, new DiagnosticOptions());
+      std::make_unique<DiagnosticsEngine>(diag_id_sp, *m_diagnostic_options_up);
 
   m_source_manager_up = std::make_unique<clang::SourceManager>(
       *m_diagnostics_engine_up, *m_file_manager_up);
diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
index 93933846d114d..fa411a6dc1445 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
@@ -1198,6 +1198,7 @@ class TypeSystemClang : public TypeSystem {
   std::unique_ptr<clang::LangOptions> m_language_options_up;
   std::unique_ptr<clang::FileManager> m_file_manager_up;
   std::unique_ptr<clang::SourceManager> m_source_manager_up;
+  std::unique_ptr<clang::DiagnosticOptions> m_diagnostic_options_up;
   std::unique_ptr<clang::DiagnosticsEngine> m_diagnostics_engine_up;
   std::unique_ptr<clang::DiagnosticConsumer> m_diagnostic_consumer_up;
   std::shared_ptr<clang::TargetOptions> m_target_options_rp;

>From 01c9500bda71c12a5bc2fee4a89cba414232241c Mon Sep 17 00:00:00 2001
From: Jan Svoboda <jan_svoboda at apple.com>
Date: Mon, 12 May 2025 09:19:57 -0700
Subject: [PATCH 6/8] git-clang-format

---
 clang-tools-extra/clang-tidy/ClangTidy.cpp    |  4 ++--
 clang-tools-extra/clangd/Compiler.cpp         |  4 ++--
 clang-tools-extra/clangd/ModulesBuilder.cpp   |  3 +--
 .../modularize/ModularizeUtilities.cpp        |  3 +--
 .../clang-tidy/ClangTidyOptionsTest.cpp       |  9 +++------
 .../unittests/clang-tidy/ClangTidyTest.h      |  3 +--
 .../clang/Frontend/DiagnosticRenderer.h       |  3 +--
 clang/lib/CrossTU/CrossTranslationUnit.cpp    |  8 ++++----
 clang/lib/Frontend/ASTMerge.cpp               |  9 ++++-----
 clang/lib/Frontend/ChainedIncludesSource.cpp  |  2 +-
 clang/lib/Frontend/CompilerInstance.cpp       |  3 +--
 clang/lib/Frontend/DiagnosticRenderer.cpp     |  5 ++---
 clang/lib/Frontend/FrontendAction.cpp         |  5 ++---
 clang/lib/Frontend/FrontendActions.cpp        |  8 ++++----
 .../Frontend/SerializedDiagnosticPrinter.cpp  | 17 +++++++++--------
 clang/lib/Frontend/TextDiagnostic.cpp         |  7 +++----
 clang/lib/Frontend/TextDiagnosticPrinter.cpp  |  4 +---
 clang/lib/Serialization/ASTReader.cpp         |  5 ++---
 clang/lib/Tooling/CompilationDatabase.cpp     |  4 ++--
 clang/lib/Tooling/Refactoring.cpp             |  4 ++--
 clang/tools/clang-format/ClangFormat.cpp      |  3 +--
 clang/tools/diagtool/ShowEnabledWarnings.cpp  |  3 +--
 clang/tools/driver/cc1as_main.cpp             |  4 ++--
 clang/tools/driver/driver.cpp                 |  4 ++--
 clang/tools/libclang/CIndexCodeCompletion.cpp |  4 ++--
 clang/tools/libclang/CIndexDiagnostic.cpp     | 15 +++++++--------
 clang/unittests/AST/CommentLexer.cpp          |  9 +++------
 clang/unittests/AST/CommentParser.cpp         |  9 +++------
 clang/unittests/Basic/DiagnosticTest.cpp      |  6 ++----
 clang/unittests/Basic/SourceManagerTest.cpp   |  8 +++-----
 clang/unittests/Driver/SanitizerArgsTest.cpp  |  5 ++---
 clang/unittests/Frontend/ASTUnitTest.cpp      | 19 +++++++++----------
 .../Frontend/CompilerInstanceTest.cpp         |  4 ++--
 clang/unittests/Frontend/OutputStreamTest.cpp |  6 +++---
 clang/unittests/Lex/LexerTest.cpp             |  9 +++------
 .../Lex/PPConditionalDirectiveRecordTest.cpp  |  9 +++------
 .../Parse/ParseHLSLRootSignatureTest.cpp      |  3 +--
 clang/unittests/Tooling/RewriterTestContext.h |  2 +-
 .../Clang/ClangModulesDeclVendor.cpp          | 11 +++++------
 39 files changed, 103 insertions(+), 140 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/ClangTidy.cpp b/clang-tools-extra/clang-tidy/ClangTidy.cpp
index 3c0531ffdc593..26f9afbc0880e 100644
--- a/clang-tools-extra/clang-tidy/ClangTidy.cpp
+++ b/clang-tools-extra/clang-tidy/ClangTidy.cpp
@@ -558,8 +558,8 @@ runClangTidy(clang::tidy::ClangTidyContext &Context,
 
   ClangTidyDiagnosticConsumer DiagConsumer(Context, nullptr, true, ApplyAnyFix);
   auto DiagOpts = std::make_unique<DiagnosticOptions>();
-  DiagnosticsEngine DE(new DiagnosticIDs(), *DiagOpts,
-                       &DiagConsumer, /*ShouldOwnClient=*/false);
+  DiagnosticsEngine DE(new DiagnosticIDs(), *DiagOpts, &DiagConsumer,
+                       /*ShouldOwnClient=*/false);
   Context.setDiagnosticsEngine(std::move(DiagOpts), &DE);
   Tool.setDiagnosticConsumer(&DiagConsumer);
 
diff --git a/clang-tools-extra/clangd/Compiler.cpp b/clang-tools-extra/clangd/Compiler.cpp
index 45096dff9f636..8b3865c8a8e5c 100644
--- a/clang-tools-extra/clangd/Compiler.cpp
+++ b/clang-tools-extra/clangd/Compiler.cpp
@@ -111,8 +111,8 @@ buildCompilerInvocation(const ParseInputs &Inputs, clang::DiagnosticConsumer &D,
   CIOpts.CC1Args = CC1Args;
   CIOpts.RecoverOnError = true;
   DiagnosticOptions DiagOpts;
-  CIOpts.Diags = CompilerInstance::createDiagnostics(
-      *CIOpts.VFS, DiagOpts, &D, false);
+  CIOpts.Diags =
+      CompilerInstance::createDiagnostics(*CIOpts.VFS, DiagOpts, &D, false);
   CIOpts.ProbePrecompiled = false;
   std::unique_ptr<CompilerInvocation> CI = createInvocation(ArgStrs, CIOpts);
   if (!CI)
diff --git a/clang-tools-extra/clangd/ModulesBuilder.cpp b/clang-tools-extra/clangd/ModulesBuilder.cpp
index 4e4918f5650db..bf77f43bd28bb 100644
--- a/clang-tools-extra/clangd/ModulesBuilder.cpp
+++ b/clang-tools-extra/clangd/ModulesBuilder.cpp
@@ -189,8 +189,7 @@ bool IsModuleFileUpToDate(PathRef ModuleFilePath,
   clang::clangd::IgnoreDiagnostics IgnoreDiags;
   DiagnosticOptions DiagOpts;
   IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
-      CompilerInstance::createDiagnostics(*VFS, DiagOpts,
-                                          &IgnoreDiags,
+      CompilerInstance::createDiagnostics(*VFS, DiagOpts, &IgnoreDiags,
                                           /*ShouldOwnClient=*/false);
 
   LangOptions LangOpts;
diff --git a/clang-tools-extra/modularize/ModularizeUtilities.cpp b/clang-tools-extra/modularize/ModularizeUtilities.cpp
index 919e51e607e79..b04eb80a67717 100644
--- a/clang-tools-extra/modularize/ModularizeUtilities.cpp
+++ b/clang-tools-extra/modularize/ModularizeUtilities.cpp
@@ -49,8 +49,7 @@ ModularizeUtilities::ModularizeUtilities(std::vector<std::string> &InputPaths,
       // Init clang stuff needed for loading the module map and preprocessing.
       LangOpts(new LangOptions()), DiagIDs(new DiagnosticIDs()),
       DC(llvm::errs(), DiagnosticOpts),
-      Diagnostics(
-          new DiagnosticsEngine(DiagIDs, DiagnosticOpts, &DC, false)),
+      Diagnostics(new DiagnosticsEngine(DiagIDs, DiagnosticOpts, &DC, false)),
       TargetOpts(new ModuleMapTargetOptions()),
       Target(TargetInfo::CreateTargetInfo(*Diagnostics, *TargetOpts)),
       FileMgr(new FileManager(FileSystemOpts)),
diff --git a/clang-tools-extra/unittests/clang-tidy/ClangTidyOptionsTest.cpp b/clang-tools-extra/unittests/clang-tidy/ClangTidyOptionsTest.cpp
index 620e320257e16..d3ca26a19dd63 100644
--- a/clang-tools-extra/unittests/clang-tidy/ClangTidyOptionsTest.cpp
+++ b/clang-tools-extra/unittests/clang-tidy/ClangTidyOptionsTest.cpp
@@ -318,8 +318,7 @@ TEST(CheckOptionsValidation, MissingOptions) {
       ClangTidyGlobalOptions(), Options));
   ClangTidyDiagnosticConsumer DiagConsumer(Context);
   auto DiagOpts = std::make_unique<DiagnosticOptions>();
-  DiagnosticsEngine DE(new DiagnosticIDs(), *DiagOpts,
-                       &DiagConsumer, false);
+  DiagnosticsEngine DE(new DiagnosticIDs(), *DiagOpts, &DiagConsumer, false);
   Context.setDiagnosticsEngine(std::move(DiagOpts), &DE);
   TestCheck TestCheck(&Context);
   EXPECT_FALSE(TestCheck.getLocal("Opt"));
@@ -349,8 +348,7 @@ TEST(CheckOptionsValidation, ValidIntOptions) {
       ClangTidyGlobalOptions(), Options));
   ClangTidyDiagnosticConsumer DiagConsumer(Context);
   auto DiagOpts = std::make_unique<DiagnosticOptions>();
-  DiagnosticsEngine DE(new DiagnosticIDs(), *DiagOpts,
-                       &DiagConsumer, false);
+  DiagnosticsEngine DE(new DiagnosticIDs(), *DiagOpts, &DiagConsumer, false);
   Context.setDiagnosticsEngine(std::move(DiagOpts), &DE);
   TestCheck TestCheck(&Context);
 
@@ -412,8 +410,7 @@ TEST(ValidConfiguration, ValidEnumOptions) {
       ClangTidyGlobalOptions(), Options));
   ClangTidyDiagnosticConsumer DiagConsumer(Context);
   auto DiagOpts = std::make_unique<DiagnosticOptions>();
-  DiagnosticsEngine DE(new DiagnosticIDs(), *DiagOpts,
-                       &DiagConsumer, false);
+  DiagnosticsEngine DE(new DiagnosticIDs(), *DiagOpts, &DiagConsumer, false);
   Context.setDiagnosticsEngine(std::move(DiagOpts), &DE);
   TestCheck TestCheck(&Context);
 
diff --git a/clang-tools-extra/unittests/clang-tidy/ClangTidyTest.h b/clang-tools-extra/unittests/clang-tidy/ClangTidyTest.h
index d1ab4ad4852e5..789cc2afb4f0c 100644
--- a/clang-tools-extra/unittests/clang-tidy/ClangTidyTest.h
+++ b/clang-tools-extra/unittests/clang-tidy/ClangTidyTest.h
@@ -97,8 +97,7 @@ runCheckOnCode(StringRef Code, std::vector<ClangTidyError> *Errors = nullptr,
       ClangTidyGlobalOptions(), Options));
   ClangTidyDiagnosticConsumer DiagConsumer(Context);
   auto DiagOpts = std::make_unique<DiagnosticOptions>();
-  DiagnosticsEngine DE(new DiagnosticIDs(), *DiagOpts,
-                       &DiagConsumer, false);
+  DiagnosticsEngine DE(new DiagnosticIDs(), *DiagOpts, &DiagConsumer, false);
   Context.setDiagnosticsEngine(std::move(DiagOpts), &DE);
 
   std::vector<std::string> Args(1, "clang-tidy");
diff --git a/clang/include/clang/Frontend/DiagnosticRenderer.h b/clang/include/clang/Frontend/DiagnosticRenderer.h
index 4c65692399490..3f03a6e02da4b 100644
--- a/clang/include/clang/Frontend/DiagnosticRenderer.h
+++ b/clang/include/clang/Frontend/DiagnosticRenderer.h
@@ -68,8 +68,7 @@ class DiagnosticRenderer {
   /// which change the amount of information displayed.
   DiagnosticsEngine::Level LastLevel = DiagnosticsEngine::Ignored;
 
-  DiagnosticRenderer(const LangOptions &LangOpts,
-                     DiagnosticOptions &DiagOpts);
+  DiagnosticRenderer(const LangOptions &LangOpts, DiagnosticOptions &DiagOpts);
 
   virtual ~DiagnosticRenderer();
 
diff --git a/clang/lib/CrossTU/CrossTranslationUnit.cpp b/clang/lib/CrossTU/CrossTranslationUnit.cpp
index b634fef3dc610..d72d3724fc4b2 100644
--- a/clang/lib/CrossTU/CrossTranslationUnit.cpp
+++ b/clang/lib/CrossTU/CrossTranslationUnit.cpp
@@ -610,10 +610,10 @@ CrossTranslationUnitContext::ASTLoader::loadFromSource(
   IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
       new DiagnosticsEngine{DiagID, *DiagOpts, DiagClient});
 
-  return ASTUnit::LoadFromCommandLine(CommandLineArgs.begin(),
-                                      (CommandLineArgs.end()),
-                                      CI.getPCHContainerOperations(),DiagOpts, Diags,
-                                      CI.getHeaderSearchOpts().ResourceDir);
+  return ASTUnit::LoadFromCommandLine(
+      CommandLineArgs.begin(), (CommandLineArgs.end()),
+      CI.getPCHContainerOperations(), DiagOpts, Diags,
+      CI.getHeaderSearchOpts().ResourceDir);
 }
 
 llvm::Expected<InvocationListTy>
diff --git a/clang/lib/Frontend/ASTMerge.cpp b/clang/lib/Frontend/ASTMerge.cpp
index c2e6779d19f0d..e6a2e3394f42a 100644
--- a/clang/lib/Frontend/ASTMerge.cpp
+++ b/clang/lib/Frontend/ASTMerge.cpp
@@ -41,11 +41,10 @@ void ASTMergeAction::ExecuteAction() {
   auto SharedState = std::make_shared<ASTImporterSharedState>(
       *CI.getASTContext().getTranslationUnitDecl());
   for (unsigned I = 0, N = ASTFiles.size(); I != N; ++I) {
-    IntrusiveRefCntPtr<DiagnosticsEngine>
-        Diags(new DiagnosticsEngine(DiagIDs, CI.getDiagnosticOpts(),
-                                    new ForwardingDiagnosticConsumer(
-                                          *CI.getDiagnostics().getClient()),
-                                    /*ShouldOwnClient=*/true));
+    IntrusiveRefCntPtr<DiagnosticsEngine> Diags(new DiagnosticsEngine(
+        DiagIDs, CI.getDiagnosticOpts(),
+        new ForwardingDiagnosticConsumer(*CI.getDiagnostics().getClient()),
+        /*ShouldOwnClient=*/true));
     std::unique_ptr<ASTUnit> Unit = ASTUnit::LoadFromASTFile(
         ASTFiles[I], CI.getPCHContainerReader(), ASTUnit::LoadEverything, Diags,
         CI.getFileSystemOpts(), CI.getHeaderSearchOpts());
diff --git a/clang/lib/Frontend/ChainedIncludesSource.cpp b/clang/lib/Frontend/ChainedIncludesSource.cpp
index 338fd81ea1a80..f9a398dbfb90f 100644
--- a/clang/lib/Frontend/ChainedIncludesSource.cpp
+++ b/clang/lib/Frontend/ChainedIncludesSource.cpp
@@ -117,7 +117,7 @@ IntrusiveRefCntPtr<ExternalSemaSource> clang::createChainedIncludesSource(
     CInvok->getFrontendOpts().Inputs.push_back(InputFile);
 
     TextDiagnosticPrinter *DiagClient =
-      new TextDiagnosticPrinter(llvm::errs(), CI.getDiagnosticOpts());
+        new TextDiagnosticPrinter(llvm::errs(), CI.getDiagnosticOpts());
     IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
     IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
         new DiagnosticsEngine(DiagID, CI.getDiagnosticOpts(), DiagClient));
diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp
index 7fecb40d7187a..cc39049167687 100644
--- a/clang/lib/Frontend/CompilerInstance.cpp
+++ b/clang/lib/Frontend/CompilerInstance.cpp
@@ -363,8 +363,7 @@ IntrusiveRefCntPtr<DiagnosticsEngine> CompilerInstance::createDiagnostics(
     SetUpDiagnosticLog(Opts, CodeGenOpts, *Diags);
 
   if (!Opts.DiagnosticSerializationFile.empty())
-    SetupSerializedDiagnostics(Opts, *Diags,
-                               Opts.DiagnosticSerializationFile);
+    SetupSerializedDiagnostics(Opts, *Diags, Opts.DiagnosticSerializationFile);
 
   // Configure our handling of diagnostics.
   ProcessWarningOptions(*Diags, Opts, VFS);
diff --git a/clang/lib/Frontend/DiagnosticRenderer.cpp b/clang/lib/Frontend/DiagnosticRenderer.cpp
index 7f3ccd38e6006..4e6993bdb76e6 100644
--- a/clang/lib/Frontend/DiagnosticRenderer.cpp
+++ b/clang/lib/Frontend/DiagnosticRenderer.cpp
@@ -247,9 +247,8 @@ void DiagnosticRenderer::emitImportStackRecursively(FullSourceLoc Loc,
 void DiagnosticRenderer::emitModuleBuildStack(const SourceManager &SM) {
   ModuleBuildStack Stack = SM.getModuleBuildStack();
   for (const auto &I : Stack) {
-    emitBuildingModuleLocation(I.second, I.second.getPresumedLoc(
-                                              DiagOpts.ShowPresumedLoc),
-                               I.first);
+    emitBuildingModuleLocation(
+        I.second, I.second.getPresumedLoc(DiagOpts.ShowPresumedLoc), I.first);
   }
 }
 
diff --git a/clang/lib/Frontend/FrontendAction.cpp b/clang/lib/Frontend/FrontendAction.cpp
index e39041bef1459..83b04596e8e44 100644
--- a/clang/lib/Frontend/FrontendAction.cpp
+++ b/clang/lib/Frontend/FrontendAction.cpp
@@ -770,9 +770,8 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
     IntrusiveRefCntPtr<DiagnosticsEngine> Diags(&CI.getDiagnostics());
 
     // The AST unit populates its own diagnostics engine rather than ours.
-    IntrusiveRefCntPtr<DiagnosticsEngine> ASTDiags(
-        new DiagnosticsEngine(Diags->getDiagnosticIDs(),
-                              Diags->getDiagnosticOptions()));
+    IntrusiveRefCntPtr<DiagnosticsEngine> ASTDiags(new DiagnosticsEngine(
+        Diags->getDiagnosticIDs(), Diags->getDiagnosticOptions()));
     ASTDiags->setClient(Diags->getClient(), /*OwnsClient*/false);
 
     // FIXME: What if the input is a memory buffer?
diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp
index 48d4453810fc6..d14d091e3fe38 100644
--- a/clang/lib/Frontend/FrontendActions.cpp
+++ b/clang/lib/Frontend/FrontendActions.cpp
@@ -690,10 +690,10 @@ namespace {
                                bool Complain) override {
       Out.indent(2) << "Diagnostic options:\n";
 #define DIAGOPT(Name, Bits, Default) DUMP_BOOLEAN(DiagOpts.Name, #Name);
-#define ENUM_DIAGOPT(Name, Type, Bits, Default) \
-      Out.indent(4) << #Name << ": " << DiagOpts.get##Name() << "\n";
-#define VALUE_DIAGOPT(Name, Bits, Default) \
-      Out.indent(4) << #Name << ": " << DiagOpts.Name << "\n";
+#define ENUM_DIAGOPT(Name, Type, Bits, Default)                              \
+    Out.indent(4) << #Name << ": " << DiagOpts.get##Name() << "\n";
+#define VALUE_DIAGOPT(Name, Bits, Default)                                   \
+    Out.indent(4) << #Name << ": " << DiagOpts.Name << "\n";
 #include "clang/Basic/DiagnosticOptions.def"
 
       Out.indent(4) << "Diagnostic flags:\n";
diff --git a/clang/lib/Frontend/SerializedDiagnosticPrinter.cpp b/clang/lib/Frontend/SerializedDiagnosticPrinter.cpp
index c9b8c8cd5755a..ee49cdd84e79e 100644
--- a/clang/lib/Frontend/SerializedDiagnosticPrinter.cpp
+++ b/clang/lib/Frontend/SerializedDiagnosticPrinter.cpp
@@ -58,7 +58,7 @@ class SDiagsRenderer : public DiagnosticNoteRenderer {
 public:
   SDiagsRenderer(SDiagsWriter &Writer, const LangOptions &LangOpts,
                  DiagnosticOptions &DiagOpts)
-    : DiagnosticNoteRenderer(LangOpts, DiagOpts), Writer(Writer) {}
+      : DiagnosticNoteRenderer(LangOpts, DiagOpts), Writer(Writer) {}
 
   ~SDiagsRenderer() override {}
 
@@ -295,9 +295,11 @@ class SDiagsWriter : public DiagnosticConsumer {
 
 namespace clang {
 namespace serialized_diags {
-std::unique_ptr<DiagnosticConsumer>
-create(StringRef OutputFile, DiagnosticOptions &DiagOpts, bool MergeChildRecords) {
-  return std::make_unique<SDiagsWriter>(OutputFile, DiagOpts, MergeChildRecords);
+std::unique_ptr<DiagnosticConsumer> create(StringRef OutputFile,
+                                           DiagnosticOptions &DiagOpts,
+                                           bool MergeChildRecords) {
+  return std::make_unique<SDiagsWriter>(OutputFile, DiagOpts,
+                                        MergeChildRecords);
 }
 
 } // end namespace serialized_diags
@@ -755,10 +757,9 @@ DiagnosticsEngine *SDiagsWriter::getMetaDiags() {
   //    normally not be used.
   if (!State->MetaDiagnostics) {
     IntrusiveRefCntPtr<DiagnosticIDs> IDs(new DiagnosticIDs());
-    auto Client =
-        new TextDiagnosticPrinter(llvm::errs(), State->DiagOpts);
-    State->MetaDiagnostics = std::make_unique<DiagnosticsEngine>(
-        IDs, State->DiagOpts, Client);
+    auto Client = new TextDiagnosticPrinter(llvm::errs(), State->DiagOpts);
+    State->MetaDiagnostics =
+        std::make_unique<DiagnosticsEngine>(IDs, State->DiagOpts, Client);
   }
   return State->MetaDiagnostics.get();
 }
diff --git a/clang/lib/Frontend/TextDiagnostic.cpp b/clang/lib/Frontend/TextDiagnostic.cpp
index ba4c1accc2a44..25ab13b7ae6c2 100644
--- a/clang/lib/Frontend/TextDiagnostic.cpp
+++ b/clang/lib/Frontend/TextDiagnostic.cpp
@@ -998,8 +998,7 @@ static void highlightRange(const LineRange &R, const SourceColumnMap &Map,
   std::fill(CaretLine.begin() + StartColNo, CaretLine.begin() + EndColNo, '~');
 }
 
-static std::string buildFixItInsertionLine(FileID FID,
-                                           unsigned LineNo,
+static std::string buildFixItInsertionLine(FileID FID, unsigned LineNo,
                                            const SourceColumnMap &map,
                                            ArrayRef<FixItHint> Hints,
                                            const SourceManager &SM,
@@ -1398,8 +1397,8 @@ void TextDiagnostic::emitSnippetAndCaret(
       CaretLine[Col] = '^';
     }
 
-    std::string FixItInsertionLine = buildFixItInsertionLine(
-        FID, LineNo, sourceColMap, Hints, SM, DiagOpts);
+    std::string FixItInsertionLine =
+        buildFixItInsertionLine(FID, LineNo, sourceColMap, Hints, SM, DiagOpts);
 
     // If the source line is too long for our terminal, select only the
     // "interesting" source region within that line.
diff --git a/clang/lib/Frontend/TextDiagnosticPrinter.cpp b/clang/lib/Frontend/TextDiagnosticPrinter.cpp
index f264f7794740a..e878c630fa01d 100644
--- a/clang/lib/Frontend/TextDiagnosticPrinter.cpp
+++ b/clang/lib/Frontend/TextDiagnosticPrinter.cpp
@@ -24,9 +24,7 @@ using namespace clang;
 TextDiagnosticPrinter::TextDiagnosticPrinter(raw_ostream &os,
                                              DiagnosticOptions &DiagOpts,
                                              bool _OwnsOutputStream)
-  : OS(os), DiagOpts(DiagOpts),
-    OwnsOutputStream(_OwnsOutputStream) {
-}
+    : OS(os), DiagOpts(DiagOpts), OwnsOutputStream(_OwnsOutputStream) {}
 
 TextDiagnosticPrinter::~TextDiagnosticPrinter() {
   if (OwnsOutputStream)
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 44ae8bf41abb8..c113fd7cbb911 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -193,8 +193,7 @@ bool ChainedASTReaderListener::ReadTargetOptions(
 }
 
 bool ChainedASTReaderListener::ReadDiagnosticOptions(
-    DiagnosticOptions &DiagOpts, StringRef ModuleFilename,
-    bool Complain) {
+    DiagnosticOptions &DiagOpts, StringRef ModuleFilename, bool Complain) {
   return First->ReadDiagnosticOptions(DiagOpts, ModuleFilename, Complain) ||
          Second->ReadDiagnosticOptions(DiagOpts, ModuleFilename, Complain);
 }
@@ -6425,7 +6424,7 @@ bool ASTReader::ParseDiagnosticOptions(const RecordData &Record,
   DiagnosticOptions DiagOpts;
   unsigned Idx = 0;
 #define DIAGOPT(Name, Bits, Default) DiagOpts.Name = Record[Idx++];
-#define ENUM_DIAGOPT(Name, Type, Bits, Default) \
+#define ENUM_DIAGOPT(Name, Type, Bits, Default)                                \
   DiagOpts.set##Name(static_cast<Type>(Record[Idx++]));
 #include "clang/Basic/DiagnosticOptions.def"
 
diff --git a/clang/lib/Tooling/CompilationDatabase.cpp b/clang/lib/Tooling/CompilationDatabase.cpp
index 9c7827c4f85dd..09596b9799833 100644
--- a/clang/lib/Tooling/CompilationDatabase.cpp
+++ b/clang/lib/Tooling/CompilationDatabase.cpp
@@ -248,8 +248,8 @@ static bool stripPositionalArgs(std::vector<const char *> Args,
   TextDiagnosticPrinter DiagnosticPrinter(Output, DiagOpts);
   UnusedInputDiagConsumer DiagClient(DiagnosticPrinter);
   DiagnosticsEngine Diagnostics(
-      IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()),
-      DiagOpts, &DiagClient, false);
+      IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()), DiagOpts,
+      &DiagClient, false);
 
   // The clang executable path isn't required since the jobs the driver builds
   // will not be executed.
diff --git a/clang/lib/Tooling/Refactoring.cpp b/clang/lib/Tooling/Refactoring.cpp
index 43ae68052d137..874d44ff6731c 100644
--- a/clang/lib/Tooling/Refactoring.cpp
+++ b/clang/lib/Tooling/Refactoring.cpp
@@ -42,8 +42,8 @@ int RefactoringTool::runAndSave(FrontendActionFactory *ActionFactory) {
   DiagnosticOptions DiagOpts;
   TextDiagnosticPrinter DiagnosticPrinter(llvm::errs(), DiagOpts);
   DiagnosticsEngine Diagnostics(
-      IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()),
-      DiagOpts, &DiagnosticPrinter, false);
+      IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()), DiagOpts,
+      &DiagnosticPrinter, false);
   SourceManager Sources(Diagnostics, getFiles());
   Rewriter Rewrite(Sources, DefaultLangOptions);
 
diff --git a/clang/tools/clang-format/ClangFormat.cpp b/clang/tools/clang-format/ClangFormat.cpp
index ed096e3a37111..53b11bc816d30 100644
--- a/clang/tools/clang-format/ClangFormat.cpp
+++ b/clang/tools/clang-format/ClangFormat.cpp
@@ -242,8 +242,7 @@ static bool fillRanges(MemoryBuffer *Code,
   FileManager Files(FileSystemOptions(), InMemoryFileSystem);
   DiagnosticOptions DiagOpts;
   DiagnosticsEngine Diagnostics(
-      IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),
-      DiagOpts);
+      IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs), DiagOpts);
   SourceManager Sources(Diagnostics, Files);
   FileID ID = createInMemoryFile("<irrelevant>", *Code, Sources, Files,
                                  InMemoryFileSystem.get());
diff --git a/clang/tools/diagtool/ShowEnabledWarnings.cpp b/clang/tools/diagtool/ShowEnabledWarnings.cpp
index 6b4136c32f23f..0d1455d270436 100644
--- a/clang/tools/diagtool/ShowEnabledWarnings.cpp
+++ b/clang/tools/diagtool/ShowEnabledWarnings.cpp
@@ -67,8 +67,7 @@ createDiagnostics(unsigned int argc, char **argv) {
   Args.push_back("diagtool");
   Args.append(argv, argv + argc);
   CreateInvocationOptions CIOpts;
-  CIOpts.Diags =
-      new DiagnosticsEngine(DiagIDs, DiagOpts, DiagsBuffer);
+  CIOpts.Diags = new DiagnosticsEngine(DiagIDs, DiagOpts, DiagsBuffer);
   std::unique_ptr<CompilerInvocation> Invocation =
       createInvocation(Args, CIOpts);
   if (!Invocation)
diff --git a/clang/tools/driver/cc1as_main.cpp b/clang/tools/driver/cc1as_main.cpp
index 9dc9a891b8d28..8c90d7a58d599 100644
--- a/clang/tools/driver/cc1as_main.cpp
+++ b/clang/tools/driver/cc1as_main.cpp
@@ -659,8 +659,8 @@ int cc1as_main(ArrayRef<const char *> Argv, const char *Argv0, void *MainAddr) {
 
   // Construct our diagnostic client.
   DiagnosticOptions DiagOpts;
-  TextDiagnosticPrinter *DiagClient
-    = new TextDiagnosticPrinter(errs(), DiagOpts);
+  TextDiagnosticPrinter *DiagClient =
+      new TextDiagnosticPrinter(errs(), DiagOpts);
   DiagClient->setPrefix("clang -cc1as");
   IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
   DiagnosticsEngine Diags(DiagID, DiagOpts, DiagClient);
diff --git a/clang/tools/driver/driver.cpp b/clang/tools/driver/driver.cpp
index 1cce0bf0eee41..d21a34e961394 100644
--- a/clang/tools/driver/driver.cpp
+++ b/clang/tools/driver/driver.cpp
@@ -327,8 +327,8 @@ int clang_main(int Argc, char **Argv, const llvm::ToolContext &ToolContext) {
   // actions.
   DiagOpts->DiagnosticSuppressionMappingsFile.clear();
 
-  TextDiagnosticPrinter *DiagClient
-    = new TextDiagnosticPrinter(llvm::errs(), *DiagOpts);
+  TextDiagnosticPrinter *DiagClient =
+      new TextDiagnosticPrinter(llvm::errs(), *DiagOpts);
   FixupDiagPrefixExeName(DiagClient, ProgName);
 
   IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
diff --git a/clang/tools/libclang/CIndexCodeCompletion.cpp b/clang/tools/libclang/CIndexCodeCompletion.cpp
index c7c70b51e7f63..8f6729b83ffa0 100644
--- a/clang/tools/libclang/CIndexCodeCompletion.cpp
+++ b/clang/tools/libclang/CIndexCodeCompletion.cpp
@@ -257,7 +257,7 @@ struct AllocatedCXCodeCompleteResults : public CXCodeCompleteResults {
   SmallVector<std::unique_ptr<CXStoredDiagnostic>, 8> DiagnosticsWrappers;
 
   DiagnosticOptions DiagOpts;
-  
+
   /// Diag object
   IntrusiveRefCntPtr<DiagnosticsEngine> Diag;
   
@@ -369,7 +369,7 @@ AllocatedCXCodeCompleteResults::AllocatedCXCodeCompleteResults(
     fprintf(stderr, "+++ %u completion results\n",
             ++CodeCompletionResultObjects);
 }
-  
+
 AllocatedCXCodeCompleteResults::~AllocatedCXCodeCompleteResults() {
   delete [] Results;
 
diff --git a/clang/tools/libclang/CIndexDiagnostic.cpp b/clang/tools/libclang/CIndexDiagnostic.cpp
index b6fdb71b6acc3..d37597e747a84 100644
--- a/clang/tools/libclang/CIndexDiagnostic.cpp
+++ b/clang/tools/libclang/CIndexDiagnostic.cpp
@@ -80,12 +80,11 @@ class CXDiagnosticCustomNoteImpl : public CXDiagnosticImpl {
 };    
     
 class CXDiagnosticRenderer : public DiagnosticNoteRenderer {
-public:  
-  CXDiagnosticRenderer(const LangOptions &LangOpts,
-                       DiagnosticOptions &DiagOpts,
+public:
+  CXDiagnosticRenderer(const LangOptions &LangOpts, DiagnosticOptions &DiagOpts,
                        CXDiagnosticSetImpl *mainSet)
-  : DiagnosticNoteRenderer(LangOpts, DiagOpts),
-    CurrentSet(mainSet), MainSet(mainSet) {}
+      : DiagnosticNoteRenderer(LangOpts, DiagOpts), CurrentSet(mainSet),
+        MainSet(mainSet) {}
 
   ~CXDiagnosticRenderer() override {}
 
@@ -183,9 +182,9 @@ CXDiagnosticSetImpl *cxdiag::lazyCreateDiags(CXTranslationUnit TU,
     CXDiagnosticSetImpl *Set = new CXDiagnosticSetImpl();
     TU->Diagnostics = Set;
     DiagnosticOptions DOpts;
-    CXDiagnosticRenderer Renderer(AU->getASTContext().getLangOpts(),
-                                  DOpts, Set);
-    
+    CXDiagnosticRenderer Renderer(AU->getASTContext().getLangOpts(), DOpts,
+                                  Set);
+
     for (ASTUnit::stored_diag_iterator it = AU->stored_diag_begin(),
          ei = AU->stored_diag_end(); it != ei; ++it) {
       Renderer.emitStoredDiagnostic(*it);
diff --git a/clang/unittests/AST/CommentLexer.cpp b/clang/unittests/AST/CommentLexer.cpp
index 97d6bcfd6c5a6..dc10dae7a2f8f 100644
--- a/clang/unittests/AST/CommentLexer.cpp
+++ b/clang/unittests/AST/CommentLexer.cpp
@@ -27,12 +27,9 @@ namespace {
 class CommentLexerTest : public ::testing::Test {
 protected:
   CommentLexerTest()
-    : FileMgr(FileMgrOpts),
-      DiagID(new DiagnosticIDs()),
-      Diags(DiagID, DiagOpts, new IgnoringDiagConsumer()),
-      SourceMgr(Diags, FileMgr),
-      Traits(Allocator, CommentOptions()) {
-  }
+      : FileMgr(FileMgrOpts), DiagID(new DiagnosticIDs()),
+        Diags(DiagID, DiagOpts, new IgnoringDiagConsumer()),
+        SourceMgr(Diags, FileMgr), Traits(Allocator, CommentOptions()) {}
 
   FileSystemOptions FileMgrOpts;
   FileManager FileMgr;
diff --git a/clang/unittests/AST/CommentParser.cpp b/clang/unittests/AST/CommentParser.cpp
index c82e8dc5eeba7..67fabe5181798 100644
--- a/clang/unittests/AST/CommentParser.cpp
+++ b/clang/unittests/AST/CommentParser.cpp
@@ -33,12 +33,9 @@ const bool MY_DEBUG = true;
 class CommentParserTest : public ::testing::Test {
 protected:
   CommentParserTest()
-    : FileMgr(FileMgrOpts),
-      DiagID(new DiagnosticIDs()),
-      Diags(DiagID, DiagOpts, new IgnoringDiagConsumer()),
-      SourceMgr(Diags, FileMgr),
-      Traits(Allocator, CommentOptions()) {
-  }
+      : FileMgr(FileMgrOpts), DiagID(new DiagnosticIDs()),
+        Diags(DiagID, DiagOpts, new IgnoringDiagConsumer()),
+        SourceMgr(Diags, FileMgr), Traits(Allocator, CommentOptions()) {}
 
   FileSystemOptions FileMgrOpts;
   FileManager FileMgr;
diff --git a/clang/unittests/Basic/DiagnosticTest.cpp b/clang/unittests/Basic/DiagnosticTest.cpp
index 19d063abee96b..b0a034e9af1cd 100644
--- a/clang/unittests/Basic/DiagnosticTest.cpp
+++ b/clang/unittests/Basic/DiagnosticTest.cpp
@@ -47,8 +47,7 @@ using testing::IsEmpty;
 // Check that DiagnosticErrorTrap works with SuppressAllDiagnostics.
 TEST(DiagnosticTest, suppressAndTrap) {
   DiagnosticOptions DiagOpts;
-  DiagnosticsEngine Diags(new DiagnosticIDs(),
-                          DiagOpts,
+  DiagnosticsEngine Diags(new DiagnosticIDs(), DiagOpts,
                           new IgnoringDiagConsumer());
   Diags.setSuppressAllDiagnostics(true);
 
@@ -79,8 +78,7 @@ TEST(DiagnosticTest, suppressAndTrap) {
 TEST(DiagnosticTest, fatalsAsError) {
   for (unsigned FatalsAsError = 0; FatalsAsError != 2; ++FatalsAsError) {
     DiagnosticOptions DiagOpts;
-    DiagnosticsEngine Diags(new DiagnosticIDs(),
-                            DiagOpts,
+    DiagnosticsEngine Diags(new DiagnosticIDs(), DiagOpts,
                             new IgnoringDiagConsumer());
     Diags.setFatalsAsError(FatalsAsError);
 
diff --git a/clang/unittests/Basic/SourceManagerTest.cpp b/clang/unittests/Basic/SourceManagerTest.cpp
index cbbaf390f3c7e..cbe047b5e599a 100644
--- a/clang/unittests/Basic/SourceManagerTest.cpp
+++ b/clang/unittests/Basic/SourceManagerTest.cpp
@@ -40,11 +40,9 @@ namespace {
 class SourceManagerTest : public ::testing::Test {
 protected:
   SourceManagerTest()
-    : FileMgr(FileMgrOpts),
-      DiagID(new DiagnosticIDs()),
-      Diags(DiagID, DiagOpts, new IgnoringDiagConsumer()),
-      SourceMgr(Diags, FileMgr),
-      TargetOpts(new TargetOptions) {
+      : FileMgr(FileMgrOpts), DiagID(new DiagnosticIDs()),
+        Diags(DiagID, DiagOpts, new IgnoringDiagConsumer()),
+        SourceMgr(Diags, FileMgr), TargetOpts(new TargetOptions) {
     TargetOpts->Triple = "x86_64-apple-darwin11.1.0";
     Target = TargetInfo::CreateTargetInfo(Diags, *TargetOpts);
   }
diff --git a/clang/unittests/Driver/SanitizerArgsTest.cpp b/clang/unittests/Driver/SanitizerArgsTest.cpp
index 8b5b26ad94162..b8bfc6806da6d 100644
--- a/clang/unittests/Driver/SanitizerArgsTest.cpp
+++ b/clang/unittests/Driver/SanitizerArgsTest.cpp
@@ -53,9 +53,8 @@ class SanitizerArgsTest : public ::testing::Test {
     assert(!DriverInstance && "Running twice is not allowed");
 
     DiagnosticOptions DiagOpts;
-    DiagnosticsEngine Diags(
-        new DiagnosticIDs, DiagOpts,
-        new TextDiagnosticPrinter(llvm::errs(), DiagOpts));
+    DiagnosticsEngine Diags(new DiagnosticIDs, DiagOpts,
+                            new TextDiagnosticPrinter(llvm::errs(), DiagOpts));
     DriverInstance.emplace(ClangBinary, "x86_64-unknown-linux-gnu", Diags,
                            "clang LLVM compiler", prepareFS(ExtraFiles));
 
diff --git a/clang/unittests/Frontend/ASTUnitTest.cpp b/clang/unittests/Frontend/ASTUnitTest.cpp
index a091d93860248..e795b9d28bba2 100644
--- a/clang/unittests/Frontend/ASTUnitTest.cpp
+++ b/clang/unittests/Frontend/ASTUnitTest.cpp
@@ -138,8 +138,7 @@ TEST_F(ASTUnitTest, ModuleTextualHeader) {
 
   const char *Args[] = {"clang", "test.cpp", "-fmodule-map-file=m.modulemap",
                         "-fmodule-name=M"};
-  Diags =
-      CompilerInstance::createDiagnostics(*InMemoryFs, *DiagOpts);
+  Diags = CompilerInstance::createDiagnostics(*InMemoryFs, *DiagOpts);
   CreateInvocationOptions CIOpts;
   CIOpts.Diags = Diags;
   CInvok = createInvocation(Args, std::move(CIOpts));
@@ -173,10 +172,10 @@ TEST_F(ASTUnitTest, LoadFromCommandLineEarlyError) {
   std::unique_ptr<clang::ASTUnit> ErrUnit;
 
   std::unique_ptr<ASTUnit> AST = ASTUnit::LoadFromCommandLine(
-      &Args[0], &Args[4], PCHContainerOps, DiagOpts, Diags, "", false, "", false,
-      CaptureDiagsKind::All, {}, true, 0, TU_Complete, false, false, false,
-      SkipFunctionBodiesScope::None, false, true, false, false, std::nullopt,
-      &ErrUnit, nullptr);
+      &Args[0], &Args[4], PCHContainerOps, DiagOpts, Diags, "", false, "",
+      false, CaptureDiagsKind::All, {}, true, 0, TU_Complete, false, false,
+      false, SkipFunctionBodiesScope::None, false, true, false, false,
+      std::nullopt, &ErrUnit, nullptr);
 
   ASSERT_EQ(AST, nullptr);
   ASSERT_NE(ErrUnit, nullptr);
@@ -201,10 +200,10 @@ TEST_F(ASTUnitTest, LoadFromCommandLineWorkingDirectory) {
   std::unique_ptr<clang::ASTUnit> ErrUnit;
 
   std::unique_ptr<ASTUnit> AST = ASTUnit::LoadFromCommandLine(
-      &Args[0], &Args[4], PCHContainerOps, DiagOpts, Diags, "", false, "", false,
-      CaptureDiagsKind::All, {}, true, 0, TU_Complete, false, false, false,
-      SkipFunctionBodiesScope::None, false, true, false, false, std::nullopt,
-      &ErrUnit, nullptr);
+      &Args[0], &Args[4], PCHContainerOps, DiagOpts, Diags, "", false, "",
+      false, CaptureDiagsKind::All, {}, true, 0, TU_Complete, false, false,
+      false, SkipFunctionBodiesScope::None, false, true, false, false,
+      std::nullopt, &ErrUnit, nullptr);
 
   ASSERT_NE(AST, nullptr);
   ASSERT_FALSE(Diags->hasErrorOccurred());
diff --git a/clang/unittests/Frontend/CompilerInstanceTest.cpp b/clang/unittests/Frontend/CompilerInstanceTest.cpp
index df987027b3bdc..a7b258d5e537e 100644
--- a/clang/unittests/Frontend/CompilerInstanceTest.cpp
+++ b/clang/unittests/Frontend/CompilerInstanceTest.cpp
@@ -86,8 +86,8 @@ TEST(CompilerInstance, AllowDiagnosticLogWithUnownedDiagnosticConsumer) {
   // Create the diagnostic engine with unowned consumer.
   std::string DiagnosticOutput;
   llvm::raw_string_ostream DiagnosticsOS(DiagnosticOutput);
-  auto DiagPrinter = std::make_unique<TextDiagnosticPrinter>(
-      DiagnosticsOS, DiagOpts);
+  auto DiagPrinter =
+      std::make_unique<TextDiagnosticPrinter>(DiagnosticsOS, DiagOpts);
   CompilerInstance Instance;
   IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
       Instance.createDiagnostics(*llvm::vfs::getRealFileSystem(), DiagOpts,
diff --git a/clang/unittests/Frontend/OutputStreamTest.cpp b/clang/unittests/Frontend/OutputStreamTest.cpp
index cb656c0750b64..dfb5a544cb88a 100644
--- a/clang/unittests/Frontend/OutputStreamTest.cpp
+++ b/clang/unittests/Frontend/OutputStreamTest.cpp
@@ -62,9 +62,9 @@ TEST(FrontendOutputTests, TestVerboseOutputStreamShared) {
 
   Compiler.setOutputStream(std::make_unique<raw_null_ostream>());
   DiagnosticOptions DiagOpts;
-  Compiler.createDiagnostics(
-      *llvm::vfs::getRealFileSystem(),
-      new TextDiagnosticPrinter(llvm::nulls(), DiagOpts), true);
+  Compiler.createDiagnostics(*llvm::vfs::getRealFileSystem(),
+                             new TextDiagnosticPrinter(llvm::nulls(), DiagOpts),
+                             true);
   Compiler.setVerboseOutputStream(VerboseStream);
 
   bool Success = ExecuteCompilerInvocation(&Compiler);
diff --git a/clang/unittests/Lex/LexerTest.cpp b/clang/unittests/Lex/LexerTest.cpp
index 66e7055acf30c..381755d4d1b6f 100644
--- a/clang/unittests/Lex/LexerTest.cpp
+++ b/clang/unittests/Lex/LexerTest.cpp
@@ -41,12 +41,9 @@ using testing::ElementsAre;
 class LexerTest : public ::testing::Test {
 protected:
   LexerTest()
-    : FileMgr(FileMgrOpts),
-      DiagID(new DiagnosticIDs()),
-      Diags(DiagID, DiagOpts, new IgnoringDiagConsumer()),
-      SourceMgr(Diags, FileMgr),
-      TargetOpts(new TargetOptions)
-  {
+      : FileMgr(FileMgrOpts), DiagID(new DiagnosticIDs()),
+        Diags(DiagID, DiagOpts, new IgnoringDiagConsumer()),
+        SourceMgr(Diags, FileMgr), TargetOpts(new TargetOptions) {
     TargetOpts->Triple = "x86_64-apple-darwin11.1.0";
     Target = TargetInfo::CreateTargetInfo(Diags, *TargetOpts);
   }
diff --git a/clang/unittests/Lex/PPConditionalDirectiveRecordTest.cpp b/clang/unittests/Lex/PPConditionalDirectiveRecordTest.cpp
index ce7433e35fd56..54c1d020aa0ea 100644
--- a/clang/unittests/Lex/PPConditionalDirectiveRecordTest.cpp
+++ b/clang/unittests/Lex/PPConditionalDirectiveRecordTest.cpp
@@ -29,12 +29,9 @@ namespace {
 class PPConditionalDirectiveRecordTest : public ::testing::Test {
 protected:
   PPConditionalDirectiveRecordTest()
-    : FileMgr(FileMgrOpts),
-      DiagID(new DiagnosticIDs()),
-      Diags(DiagID, DiagOpts, new IgnoringDiagConsumer()),
-      SourceMgr(Diags, FileMgr),
-      TargetOpts(new TargetOptions)
-  {
+      : FileMgr(FileMgrOpts), DiagID(new DiagnosticIDs()),
+        Diags(DiagID, DiagOpts, new IgnoringDiagConsumer()),
+        SourceMgr(Diags, FileMgr), TargetOpts(new TargetOptions) {
     TargetOpts->Triple = "x86_64-apple-darwin11.1.0";
     Target = TargetInfo::CreateTargetInfo(Diags, *TargetOpts);
   }
diff --git a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
index cd6dea55ac632..48de5536e3d06 100644
--- a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
+++ b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
@@ -67,8 +67,7 @@ class ParseHLSLRootSignatureTest : public ::testing::Test {
 protected:
   ParseHLSLRootSignatureTest()
       : FileMgr(FileMgrOpts), DiagID(new DiagnosticIDs()),
-        Consumer(new ExpectedDiagConsumer()),
-        Diags(DiagID, DiagOpts, Consumer),
+        Consumer(new ExpectedDiagConsumer()), Diags(DiagID, DiagOpts, Consumer),
         SourceMgr(Diags, FileMgr), TargetOpts(new TargetOptions) {
     // This is an arbitrarily chosen target triple to create the target info.
     TargetOpts->Triple = "dxil";
diff --git a/clang/unittests/Tooling/RewriterTestContext.h b/clang/unittests/Tooling/RewriterTestContext.h
index 8ad164fe7183a..2d697e276c5e8 100644
--- a/clang/unittests/Tooling/RewriterTestContext.h
+++ b/clang/unittests/Tooling/RewriterTestContext.h
@@ -60,7 +60,7 @@ class RewriterTestContext {
      // FIXME: To make these tests truly in-memory, we need to overlay the
      // builtin headers.
      OverlayFileSystem->pushOverlay(InMemoryFileSystem);
-  }
+   }
 
   ~RewriterTestContext() {}
 
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
index 99637610dafd1..eb62cb618f254 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
@@ -711,8 +711,8 @@ ClangModulesDeclVendor::Create(Target &target) {
       clang::CreateAndPopulateDiagOpts(compiler_invocation_argument_cstrs);
   llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> diagnostics_engine =
       clang::CompilerInstance::createDiagnostics(
-          *FileSystem::Instance().GetVirtualFileSystem(),
-          *diag_options_up, new StoringDiagnosticConsumer);
+          *FileSystem::Instance().GetVirtualFileSystem(), *diag_options_up,
+          new StoringDiagnosticConsumer);
 
   Log *log = GetLog(LLDBLog::Expressions);
   LLDB_LOG(log, "ClangModulesDeclVendor's compiler flags {0:$[ ]}",
@@ -772,8 +772,7 @@ ClangModulesDeclVendor::Create(Target &target) {
   while (!parser->ParseTopLevelDecl(parsed, ImportState))
     ;
 
-  return new ClangModulesDeclVendorImpl(std::move(diag_options_up),
-                                        std::move(diagnostics_engine),
-                                        std::move(invocation),
-                                        std::move(instance), std::move(parser));
+  return new ClangModulesDeclVendorImpl(
+      std::move(diag_options_up), std::move(diagnostics_engine),
+      std::move(invocation), std::move(instance), std::move(parser));
 }

>From 40446a876d8b69a389b362b46998df5ad80d06bc Mon Sep 17 00:00:00 2001
From: Jan Svoboda <jan_svoboda at apple.com>
Date: Wed, 14 May 2025 08:23:44 -0700
Subject: [PATCH 7/8] Add a FIXME to ASTUnit

---
 clang/include/clang/Frontend/ASTUnit.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/clang/include/clang/Frontend/ASTUnit.h b/clang/include/clang/Frontend/ASTUnit.h
index b1fbc9f9f8ee3..2bcfe7911e7c4 100644
--- a/clang/include/clang/Frontend/ASTUnit.h
+++ b/clang/include/clang/Frontend/ASTUnit.h
@@ -107,6 +107,10 @@ class ASTUnit {
 
 private:
   std::unique_ptr<LangOptions> LangOpts;
+  // FIXME: The documentation on \c LoadFrom* member functions states that the
+  // DiagnosticsEngine (and therefore DiagnosticOptions) must outlive the
+  // returned ASTUnit. This is not the case. Enfore it by storing non-owning
+  // pointers here.
   std::shared_ptr<DiagnosticOptions> DiagOpts;
   IntrusiveRefCntPtr<DiagnosticsEngine>   Diagnostics;
   IntrusiveRefCntPtr<FileManager>         FileMgr;

>From 8a253316aa54180779866286898ba1518f1c33a6 Mon Sep 17 00:00:00 2001
From: Jan Svoboda <jan_svoboda at apple.com>
Date: Tue, 20 May 2025 11:03:46 -0700
Subject: [PATCH 8/8] Always pass DiagnosticOptions to ASTUnit with
 DiagnosticsEngine

---
 clang/include/clang/Frontend/ASTUnit.h |  6 +++++-
 clang/lib/Frontend/ASTUnit.cpp         | 12 ++++++++++--
 2 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/clang/include/clang/Frontend/ASTUnit.h b/clang/include/clang/Frontend/ASTUnit.h
index 2bcfe7911e7c4..1485192e8f1e3 100644
--- a/clang/include/clang/Frontend/ASTUnit.h
+++ b/clang/include/clang/Frontend/ASTUnit.h
@@ -679,6 +679,7 @@ class ASTUnit {
   /// Create a ASTUnit. Gets ownership of the passed CompilerInvocation.
   static std::unique_ptr<ASTUnit>
   create(std::shared_ptr<CompilerInvocation> CI,
+         std::shared_ptr<DiagnosticOptions> DiagOpts,
          IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
          CaptureDiagsKind CaptureDiagnostics, bool UserFilesAreVolatile);
 
@@ -705,7 +706,8 @@ class ASTUnit {
   /// \returns - The initialized ASTUnit or null if the AST failed to load.
   static std::unique_ptr<ASTUnit> LoadFromASTFile(
       StringRef Filename, const PCHContainerReader &PCHContainerRdr,
-      WhatToLoad ToLoad, IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
+      WhatToLoad ToLoad, std::shared_ptr<DiagnosticOptions> DiagOpts,
+      IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
       const FileSystemOptions &FileSystemOpts,
       const HeaderSearchOptions &HSOpts, const LangOptions *LangOpts = nullptr,
       bool OnlyLocalDecls = false,
@@ -767,6 +769,7 @@ class ASTUnit {
   static ASTUnit *LoadFromCompilerInvocationAction(
       std::shared_ptr<CompilerInvocation> CI,
       std::shared_ptr<PCHContainerOperations> PCHContainerOps,
+      std::shared_ptr<DiagnosticOptions> DiagOpts,
       IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
       FrontendAction *Action = nullptr, ASTUnit *Unit = nullptr,
       bool Persistent = true, StringRef ResourceFilesPath = StringRef(),
@@ -794,6 +797,7 @@ class ASTUnit {
   static std::unique_ptr<ASTUnit> LoadFromCompilerInvocation(
       std::shared_ptr<CompilerInvocation> CI,
       std::shared_ptr<PCHContainerOperations> PCHContainerOps,
+      std::shared_ptr<DiagnosticOptions> DiagOpts,
       IntrusiveRefCntPtr<DiagnosticsEngine> Diags, FileManager *FileMgr,
       bool OnlyLocalDecls = false,
       CaptureDiagsKind CaptureDiagnostics = CaptureDiagsKind::None,
diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp
index 29cb5c9f6835e..1037b0a2d4634 100644
--- a/clang/lib/Frontend/ASTUnit.cpp
+++ b/clang/lib/Frontend/ASTUnit.cpp
@@ -803,7 +803,8 @@ void ASTUnit::ConfigureDiags(IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
 
 std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile(
     StringRef Filename, const PCHContainerReader &PCHContainerRdr,
-    WhatToLoad ToLoad, IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
+    WhatToLoad ToLoad, std::shared_ptr<DiagnosticOptions> DiagOpts,
+    IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
     const FileSystemOptions &FileSystemOpts, const HeaderSearchOptions &HSOpts,
     const LangOptions *LangOpts, bool OnlyLocalDecls,
     CaptureDiagsKind CaptureDiagnostics, bool AllowASTWithCompilerErrors,
@@ -823,6 +824,7 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile(
                            : std::make_unique<LangOptions>();
   AST->OnlyLocalDecls = OnlyLocalDecls;
   AST->CaptureDiagnostics = CaptureDiagnostics;
+  AST->DiagOpts = DiagOpts;
   AST->Diagnostics = Diags;
   AST->FileMgr = new FileManager(FileSystemOpts, VFS);
   AST->UserFilesAreVolatile = UserFilesAreVolatile;
@@ -1534,6 +1536,7 @@ StringRef ASTUnit::getASTFileName() const {
 
 std::unique_ptr<ASTUnit>
 ASTUnit::create(std::shared_ptr<CompilerInvocation> CI,
+                std::shared_ptr<DiagnosticOptions> DiagOpts,
                 IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
                 CaptureDiagsKind CaptureDiagnostics,
                 bool UserFilesAreVolatile) {
@@ -1541,6 +1544,7 @@ ASTUnit::create(std::shared_ptr<CompilerInvocation> CI,
   ConfigureDiags(Diags, *AST, CaptureDiagnostics);
   IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS =
       createVFSFromCompilerInvocation(*CI, *Diags);
+  AST->DiagOpts = DiagOpts;
   AST->Diagnostics = Diags;
   AST->FileSystemOpts = CI->getFileSystemOpts();
   AST->Invocation = std::move(CI);
@@ -1556,6 +1560,7 @@ ASTUnit::create(std::shared_ptr<CompilerInvocation> CI,
 ASTUnit *ASTUnit::LoadFromCompilerInvocationAction(
     std::shared_ptr<CompilerInvocation> CI,
     std::shared_ptr<PCHContainerOperations> PCHContainerOps,
+    std::shared_ptr<DiagnosticOptions> DiagOpts,
     IntrusiveRefCntPtr<DiagnosticsEngine> Diags, FrontendAction *Action,
     ASTUnit *Unit, bool Persistent, StringRef ResourceFilesPath,
     bool OnlyLocalDecls, CaptureDiagsKind CaptureDiagnostics,
@@ -1567,7 +1572,8 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocationAction(
   ASTUnit *AST = Unit;
   if (!AST) {
     // Create the AST unit.
-    OwnAST = create(CI, Diags, CaptureDiagnostics, UserFilesAreVolatile);
+    OwnAST =
+        create(CI, DiagOpts, Diags, CaptureDiagnostics, UserFilesAreVolatile);
     AST = OwnAST.get();
     if (!AST)
       return nullptr;
@@ -1729,6 +1735,7 @@ bool ASTUnit::LoadFromCompilerInvocation(
 std::unique_ptr<ASTUnit> ASTUnit::LoadFromCompilerInvocation(
     std::shared_ptr<CompilerInvocation> CI,
     std::shared_ptr<PCHContainerOperations> PCHContainerOps,
+    std::shared_ptr<DiagnosticOptions> DiagOpts,
     IntrusiveRefCntPtr<DiagnosticsEngine> Diags, FileManager *FileMgr,
     bool OnlyLocalDecls, CaptureDiagsKind CaptureDiagnostics,
     unsigned PrecompilePreambleAfterNParses, TranslationUnitKind TUKind,
@@ -1737,6 +1744,7 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromCompilerInvocation(
   // Create the AST unit.
   std::unique_ptr<ASTUnit> AST(new ASTUnit(false));
   ConfigureDiags(Diags, *AST, CaptureDiagnostics);
+  AST->DiagOpts = DiagOpts;
   AST->Diagnostics = Diags;
   AST->OnlyLocalDecls = OnlyLocalDecls;
   AST->CaptureDiagnostics = CaptureDiagnostics;



More information about the cfe-commits mailing list