sanwou01 updated this revision to Diff 95549.
sanwou01 added a comment.

Don't include the changes from https://reviews.llvm.org/D31709 and 
https://reviews.llvm.org/D32159 in this patch (oops).


https://reviews.llvm.org/D31501

Files:
  include/clang/Basic/Diagnostic.h
  include/clang/Basic/SourceLocation.h
  include/clang/Driver/Options.h
  include/clang/Driver/Options.td
  include/clang/Frontend/DiagnosticRenderer.h
  include/clang/Frontend/TextDiagnostic.h
  lib/Basic/SourceLocation.cpp
  lib/Driver/DriverOptions.cpp
  lib/Driver/ToolChains/Clang.cpp
  lib/Frontend/DiagnosticRenderer.cpp
  lib/Frontend/SerializedDiagnosticPrinter.cpp
  lib/Frontend/TextDiagnostic.cpp
  lib/Frontend/TextDiagnosticPrinter.cpp
  test/Driver/asm-diags.s
  tools/driver/cc1as_main.cpp
  tools/libclang/CIndexDiagnostic.cpp

Index: tools/libclang/CIndexDiagnostic.cpp
===================================================================
--- tools/libclang/CIndexDiagnostic.cpp
+++ tools/libclang/CIndexDiagnostic.cpp
@@ -110,7 +110,7 @@
       CurrentSet = &CD.getChildDiagnostics();
   }
 
-  void emitDiagnosticMessage(FullSourceLoc Loc, PresumedLoc PLoc,
+  void emitDiagnosticMessage(UnifiedSourceLoc Loc, UnifiedPLoc PLoc,
                              DiagnosticsEngine::Level Level, StringRef Message,
                              ArrayRef<CharSourceRange> Ranges,
                              DiagOrStoredDiag D) override {
@@ -126,15 +126,15 @@
         llvm::make_unique<CXDiagnosticCustomNoteImpl>(Message, L));
   }
 
-  void emitDiagnosticLoc(FullSourceLoc Loc, PresumedLoc PLoc,
+  void emitDiagnosticLoc(UnifiedSourceLoc Loc, UnifiedPLoc PLoc,
                          DiagnosticsEngine::Level Level,
                          ArrayRef<CharSourceRange> Ranges) override {}
 
-  void emitCodeContext(FullSourceLoc Loc, DiagnosticsEngine::Level Level,
+  void emitCodeContext(UnifiedSourceLoc Loc, DiagnosticsEngine::Level Level,
                        SmallVectorImpl<CharSourceRange> &Ranges,
                        ArrayRef<FixItHint> Hints) override {}
 
-  void emitNote(FullSourceLoc Loc, StringRef Message) override {
+  void emitNote(UnifiedSourceLoc Loc, StringRef Message) override {
     CXSourceLocation L;
     if (Loc.hasManager())
       L = translateSourceLocation(Loc.getManager(), LangOpts, Loc);
Index: tools/driver/cc1as_main.cpp
===================================================================
--- tools/driver/cc1as_main.cpp
+++ tools/driver/cc1as_main.cpp
@@ -14,6 +14,10 @@
 
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/DiagnosticOptions.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/FileSystemOptions.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/SourceManager.h"
 #include "clang/Driver/DriverDiagnostic.h"
 #include "clang/Driver/Options.h"
 #include "clang/Frontend/DiagnosticOptions.h"
@@ -46,6 +50,7 @@
 #include "llvm/Support/Host.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Path.h"
+#include "llvm/Support/Process.h"
 #include "llvm/Support/Signals.h"
 #include "llvm/Support/SourceMgr.h"
 #include "llvm/Support/TargetRegistry.h"
@@ -284,6 +289,29 @@
   return Out;
 }
 
+struct DiagsHandlerContext {
+  DiagnosticsEngine &Diags;
+  const SourceMgr *SrcMgr;
+};
+
+static void AssemblerDiagsHandler(const SMDiagnostic &D, void *Context) {
+  auto &Diags = *static_cast<DiagnosticsEngine *>(Context);
+  unsigned DiagID;
+  switch (D.getKind()) {
+  case llvm::SourceMgr::DK_Error:
+    DiagID = diag::err_fe_inline_asm;
+    break;
+  case llvm::SourceMgr::DK_Warning:
+    DiagID = diag::warn_fe_inline_asm;
+    break;
+  case llvm::SourceMgr::DK_Note:
+    DiagID = diag::note_fe_inline_asm;
+    break;
+  }
+
+  Diags.Report(D.getSourceMgr(), D.getLoc(), DiagID) << D.getMessage();
+}
+
 static bool ExecuteAssembler(AssemblerInvocation &Opts,
                              DiagnosticsEngine &Diags) {
   // Get the target specific parser.
@@ -309,6 +337,8 @@
   // it later.
   SrcMgr.setIncludeDirs(Opts.IncludePaths);
 
+  SrcMgr.setDiagHandler(AssemblerDiagsHandler, &Diags);
+
   std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(Opts.Triple));
   assert(MRI && "Unable to create target register info!");
 
@@ -475,7 +505,6 @@
   IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
   TextDiagnosticPrinter *DiagClient
     = new TextDiagnosticPrinter(errs(), &*DiagOpts);
-  DiagClient->setPrefix("clang -cc1as");
   IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
   DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagClient);
 
@@ -517,9 +546,35 @@
     llvm::cl::ParseCommandLineOptions(NumArgs + 1, Args);
   }
 
+  ProcessWarningOptions(Diags, Diags.getDiagnosticOptions(), true);
+
+  LangOptions LangOpts;
+  DiagClient->BeginSourceFile(LangOpts, nullptr);
+
   // Execute the invocation, unless there were parsing errors.
   bool Failed = Diags.hasErrorOccurred() || ExecuteAssembler(Asm, Diags);
 
+  DiagClient->EndSourceFile();
+
+  // Notify the diagnostic client that all files were processed.
+  Diags.getClient()->finish();
+
+  if (Diags.getDiagnosticOptions().ShowCarets) {
+    // We can have multiple diagnostics sharing one diagnostic client.
+    // Get the total number of warnings/errors from the client.
+    unsigned NumWarnings = Diags.getClient()->getNumWarnings();
+    unsigned NumErrors = Diags.getClient()->getNumErrors();
+
+    if (NumWarnings)
+      errs() << NumWarnings << " warning" << (NumWarnings == 1 ? "" : "s");
+    if (NumWarnings && NumErrors)
+      errs() << " and ";
+    if (NumErrors)
+      errs() << NumErrors << " error" << (NumErrors == 1 ? "" : "s");
+    if (NumWarnings || NumErrors)
+      errs() << " generated.\n";
+  }
+
   // If any timers were active but haven't been destroyed yet, print their
   // results now.
   TimerGroup::printAll(errs());
Index: test/Driver/asm-diags.s
===================================================================
--- /dev/null
+++ test/Driver/asm-diags.s
@@ -0,0 +1,23 @@
+# RUN: not %clang --target=arm-linux-gnueabi -march=armv8-m.main -c %s 2>&1 | FileCheck %s
+# RUN: not %clang --target=arm-linux-gnueabi -march=armv8-m.main -w -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-NO-WARNINGS
+# RUN: not %clang --target=arm-linux-gnueabi -march=armv8-m.main -Werror -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-FATAL-WARNINGS
+
+.thumb
+	ADD r0, r0, #0xFFFF0001
+	LDM r0, {r1, r0}
+
+# CHECK: asm-diags.s:6:14: error:
+# CHECK: 	ADD r0, r0, #0xFFFF0001
+# CHECK: asm-diags.s:7:15: warning:
+# CHECK: 	LDM r0, {r1, r0}
+# CHECK: 1 warning and 1 error generated.
+
+# CHECK-NO-WARNINGS: asm-diags.s:6:14: error:
+# CHECK-NO-WARNINGS: 	ADD r0, r0, #0xFFFF0001
+# CHECK-NO-WARNINGS: 1 error generated.
+
+# CHECK-FATAL-WARNINGS: asm-diags.s:6:14: error:
+# CHECK-FATAL-WARNINGS: 	ADD r0, r0, #0xFFFF0001
+# CHECK-FATAL-WARNINGS: asm-diags.s:7:15: error:
+# CHECK-FATAL-WARNINGS: 	LDM r0, {r1, r0}
+# CHECK-FATAL-WARNINGS: 2 errors generated.
Index: lib/Frontend/TextDiagnosticPrinter.cpp
===================================================================
--- lib/Frontend/TextDiagnosticPrinter.cpp
+++ lib/Frontend/TextDiagnosticPrinter.cpp
@@ -146,13 +146,9 @@
 
   // 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");
 
-  TextDiag->emitDiagnostic(
-      FullSourceLoc(Info.getLocation(), Info.getSourceManager()), Level,
-      DiagMessageStream.str(), Info.getRanges(), Info.getFixItHints());
-
+  TextDiag->emitDiagnostic(Info.getLocation(), Level, DiagMessageStream.str(),
+                           Info.getRanges(), Info.getFixItHints());
   OS.flush();
 }
Index: lib/Frontend/TextDiagnostic.cpp
===================================================================
--- lib/Frontend/TextDiagnostic.cpp
+++ lib/Frontend/TextDiagnostic.cpp
@@ -673,7 +673,7 @@
 TextDiagnostic::~TextDiagnostic() {}
 
 void TextDiagnostic::emitDiagnosticMessage(
-    FullSourceLoc Loc, PresumedLoc PLoc, DiagnosticsEngine::Level Level,
+    UnifiedSourceLoc Loc, UnifiedPLoc PLoc, DiagnosticsEngine::Level Level,
     StringRef Message, ArrayRef<clang::CharSourceRange> Ranges,
     DiagOrStoredDiag D) {
   uint64_t StartOfLocationInfo = OS.tell();
@@ -761,13 +761,13 @@
   OS << '\n';
 }
 
-void TextDiagnostic::emitFilename(StringRef Filename, const SourceManager &SM) {
+void TextDiagnostic::emitFilename(StringRef Filename, const SourceManager *SM) {
   SmallVector<char, 128> AbsoluteFilename;
-  if (DiagOpts->AbsolutePath) {
-    const DirectoryEntry *Dir = SM.getFileManager().getDirectory(
+  if (SM && DiagOpts->AbsolutePath) {
+    const DirectoryEntry *Dir = SM->getFileManager().getDirectory(
         llvm::sys::path::parent_path(Filename));
     if (Dir) {
-      StringRef DirName = SM.getFileManager().getCanonicalName(Dir);
+      StringRef DirName = SM->getFileManager().getCanonicalName(Dir);
       llvm::sys::path::append(AbsoluteFilename, DirName,
                               llvm::sys::path::filename(Filename));
       Filename = StringRef(AbsoluteFilename.data(), AbsoluteFilename.size());
@@ -783,16 +783,16 @@
 /// This includes extracting as much location information as is present for
 /// the diagnostic and printing it, as well as any include stack or source
 /// ranges necessary.
-void TextDiagnostic::emitDiagnosticLoc(FullSourceLoc Loc, PresumedLoc PLoc,
+void TextDiagnostic::emitDiagnosticLoc(UnifiedSourceLoc Loc, UnifiedPLoc PLoc,
                                        DiagnosticsEngine::Level Level,
                                        ArrayRef<CharSourceRange> Ranges) {
   if (PLoc.isInvalid()) {
     // At least print the file name if available:
     FileID FID = Loc.getFileID();
     if (FID.isValid()) {
       const FileEntry *FE = Loc.getFileEntry();
       if (FE && FE->isValid()) {
-        emitFilename(FE->getName(), Loc.getManager());
+        emitFilename(FE->getName(), &Loc.getManager());
         if (FE->isInPCH())
           OS << " (in PCH)";
         OS << ": ";
@@ -808,7 +808,8 @@
   if (DiagOpts->ShowColors)
     OS.changeColor(savedColor, true);
 
-  emitFilename(PLoc.getFilename(), Loc.getManager());
+  emitFilename(PLoc.getFilename(),
+               Loc.hasManager() ? &Loc.getManager() : nullptr);
   switch (DiagOpts->getFormat()) {
   case DiagnosticOptions::Clang: OS << ':'  << LineNo; break;
   case DiagnosticOptions::MSVC:  OS << '('  << LineNo; break;
@@ -852,18 +853,18 @@
       // Ignore invalid ranges.
       if (!RI->isValid()) continue;
 
-      FullSourceLoc B =
-          FullSourceLoc(RI->getBegin(), Loc.getManager()).getExpansionLoc();
-      FullSourceLoc E =
-          FullSourceLoc(RI->getEnd(), Loc.getManager()).getExpansionLoc();
+      UnifiedSourceLoc B =
+          UnifiedSourceLoc(RI->getBegin(), Loc.getManager()).getExpansionLoc();
+      UnifiedSourceLoc E =
+          UnifiedSourceLoc(RI->getEnd(), Loc.getManager()).getExpansionLoc();
 
       // If the End location and the start location are the same and are a
       // macro location, then the range was something that came from a
       // macro expansion or _Pragma.  If this is an object-like macro, the
       // best we can do is to highlight the range.  If this is a
       // function-like macro, we'd also like to highlight the arguments.
       if (B == E && RI->getEnd().isMacroID())
-        E = FullSourceLoc(RI->getEnd(), Loc.getManager())
+        E = UnifiedSourceLoc(RI->getEnd(), Loc.getManager())
                 .getExpansionRange()
                 .second;
 
@@ -892,25 +893,26 @@
   OS << ' ';
 }
 
-void TextDiagnostic::emitIncludeLocation(FullSourceLoc Loc, PresumedLoc PLoc) {
+void TextDiagnostic::emitIncludeLocation(UnifiedSourceLoc Loc,
+                                         UnifiedPLoc PLoc) {
   if (DiagOpts->ShowLocation && PLoc.isValid())
     OS << "In file included from " << PLoc.getFilename() << ':'
        << PLoc.getLine() << ":\n";
   else
     OS << "In included file:\n"; 
 }
 
-void TextDiagnostic::emitImportLocation(FullSourceLoc Loc, PresumedLoc PLoc,
+void TextDiagnostic::emitImportLocation(UnifiedSourceLoc Loc, UnifiedPLoc PLoc,
                                         StringRef ModuleName) {
   if (DiagOpts->ShowLocation && PLoc.isValid())
     OS << "In module '" << ModuleName << "' imported from "
        << PLoc.getFilename() << ':' << PLoc.getLine() << ":\n";
   else
     OS << "In module '" << ModuleName << "':\n";
 }
 
-void TextDiagnostic::emitBuildingModuleLocation(FullSourceLoc Loc,
-                                                PresumedLoc PLoc,
+void TextDiagnostic::emitBuildingModuleLocation(UnifiedSourceLoc Loc,
+                                                UnifiedPLoc PLoc,
                                                 StringRef ModuleName) {
   if (DiagOpts->ShowLocation && PLoc.isValid())
     OS << "While building module '" << ModuleName << "' imported from "
@@ -1072,7 +1074,7 @@
 /// \param Ranges The underlined ranges for this code snippet.
 /// \param Hints The FixIt hints active for this diagnostic.
 void TextDiagnostic::emitSnippetAndCaret(
-    FullSourceLoc Loc, DiagnosticsEngine::Level Level,
+    UnifiedSourceLoc Loc, DiagnosticsEngine::Level Level,
     SmallVectorImpl<CharSourceRange> &Ranges, ArrayRef<FixItHint> Hints) {
   assert(Loc.isValid() && "must have a valid source location here");
   assert(Loc.isFileID() && "must have a file location here");
@@ -1085,9 +1087,11 @@
   // multiple times if one loc has multiple diagnostics.
   if (!DiagOpts->ShowCarets)
     return;
+
   if (Loc == LastLoc && Ranges.empty() && Hints.empty() &&
-      (LastLevel != DiagnosticsEngine::Note || Level == LastLevel))
+      (LastLevel != DiagnosticsEngine::Note || Level == LastLevel)) {
     return;
+  }
 
   // Decompose the location into a FID/Offset pair.
   std::pair<FileID, unsigned> LocInfo = Loc.getDecomposedLoc();
@@ -1153,8 +1157,10 @@
     CaretLine.resize(ColNo+1, ' ');
   CaretLine[ColNo] = '^';
 
-  std::string FixItInsertionLine = buildFixItInsertionLine(
-      LineNo, sourceColMap, Hints, Loc.getManager(), DiagOpts.get());
+  std::string FixItInsertionLine;
+  if (!Hints.empty())
+    FixItInsertionLine = buildFixItInsertionLine(
+        LineNo, sourceColMap, Hints, Loc.getManager(), DiagOpts.get());
 
   // If the source line is too long for our terminal, select only the
   // "interesting" source region within that line.
@@ -1197,7 +1203,8 @@
   }
 
   // Print out any parseable fixit information requested by the options.
-  emitParseableFixits(Hints, Loc.getManager());
+  if (!Hints.empty())
+    emitParseableFixits(Hints, Loc.getManager());
 }
 
 void TextDiagnostic::emitSnippet(StringRef line) {
@@ -1265,7 +1272,7 @@
 
     // We specifically do not do word-wrapping or tab-expansion here,
     // because this is supposed to be easy to parse.
-    PresumedLoc PLoc = SM.getPresumedLoc(BLoc);
+    UnifiedPLoc PLoc = SM.getPresumedLoc(BLoc);
     if (PLoc.isInvalid())
       break;
 
Index: lib/Frontend/SerializedDiagnosticPrinter.cpp
===================================================================
--- lib/Frontend/SerializedDiagnosticPrinter.cpp
+++ lib/Frontend/SerializedDiagnosticPrinter.cpp
@@ -63,18 +63,18 @@
   ~SDiagsRenderer() override {}
 
 protected:
-  void emitDiagnosticMessage(FullSourceLoc Loc, PresumedLoc PLoc,
+  void emitDiagnosticMessage(UnifiedSourceLoc Loc, UnifiedPLoc PLoc,
                              DiagnosticsEngine::Level Level, StringRef Message,
                              ArrayRef<CharSourceRange> Ranges,
                              DiagOrStoredDiag D) override;
 
-  void emitDiagnosticLoc(FullSourceLoc Loc, PresumedLoc PLoc,
+  void emitDiagnosticLoc(UnifiedSourceLoc Loc, UnifiedPLoc PLoc,
                          DiagnosticsEngine::Level Level,
                          ArrayRef<CharSourceRange> Ranges) override {}
 
-  void emitNote(FullSourceLoc Loc, StringRef Message) override;
+  void emitNote(UnifiedSourceLoc Loc, StringRef Message) override;
 
-  void emitCodeContext(FullSourceLoc Loc, DiagnosticsEngine::Level Level,
+  void emitCodeContext(UnifiedSourceLoc Loc, DiagnosticsEngine::Level Level,
                        SmallVectorImpl<CharSourceRange> &Ranges,
                        ArrayRef<FixItHint> Hints) override;
 
@@ -653,7 +653,7 @@
 }
 
 void SDiagsRenderer::emitDiagnosticMessage(
-    FullSourceLoc Loc, PresumedLoc PLoc, DiagnosticsEngine::Level Level,
+    UnifiedSourceLoc Loc, UnifiedPLoc PLoc, DiagnosticsEngine::Level Level,
     StringRef Message, ArrayRef<clang::CharSourceRange> Ranges,
     DiagOrStoredDiag D) {
   Writer.EmitDiagnosticMessage(Loc, PLoc, Level, Message, D);
@@ -709,14 +709,14 @@
   }
 }
 
-void SDiagsRenderer::emitCodeContext(FullSourceLoc Loc,
+void SDiagsRenderer::emitCodeContext(UnifiedSourceLoc Loc,
                                      DiagnosticsEngine::Level Level,
                                      SmallVectorImpl<CharSourceRange> &Ranges,
                                      ArrayRef<FixItHint> Hints) {
   Writer.EmitCodeContext(Ranges, Hints, Loc.getManager());
 }
 
-void SDiagsRenderer::emitNote(FullSourceLoc Loc, StringRef Message) {
+void SDiagsRenderer::emitNote(UnifiedSourceLoc Loc, StringRef Message) {
   Writer.EnterDiagBlock();
   PresumedLoc PLoc = Loc.hasManager() ? Loc.getPresumedLoc() : PresumedLoc();
   Writer.EmitDiagnosticMessage(Loc, PLoc, DiagnosticsEngine::Note, Message,
Index: lib/Frontend/DiagnosticRenderer.cpp
===================================================================
--- lib/Frontend/DiagnosticRenderer.cpp
+++ lib/Frontend/DiagnosticRenderer.cpp
@@ -76,19 +76,17 @@
   }
 }
 
-void DiagnosticRenderer::emitDiagnostic(FullSourceLoc Loc,
+void DiagnosticRenderer::emitDiagnostic(UnifiedSourceLoc Loc,
                                         DiagnosticsEngine::Level Level,
                                         StringRef Message,
                                         ArrayRef<CharSourceRange> Ranges,
                                         ArrayRef<FixItHint> FixItHints,
                                         DiagOrStoredDiag D) {
-  assert(Loc.hasManager() || Loc.isInvalid());
-
   beginDiagnostic(D, Level);
 
   if (!Loc.isValid())
     // If we have no source location, just emit the diagnostic message.
-    emitDiagnosticMessage(Loc, PresumedLoc(), Level, Message, Ranges, D);
+    emitDiagnosticMessage(Loc, UnifiedPLoc(), Level, Message, Ranges, D);
   else {
     // Get the ranges into a local array we can hack on.
     SmallVector<CharSourceRange, 20> MutableRanges(Ranges.begin(),
@@ -106,16 +104,17 @@
       if (I->RemoveRange.isValid())
         MutableRanges.push_back(I->RemoveRange);
 
-    FullSourceLoc UnexpandedLoc = Loc;
+    UnifiedSourceLoc UnexpandedLoc = Loc;
 
     // Find the ultimate expansion location for the diagnostic.
     Loc = Loc.getFileLoc();
 
-    PresumedLoc PLoc = Loc.getPresumedLoc(DiagOpts->ShowPresumedLoc);
+    UnifiedPLoc PLoc = Loc.getPresumedLoc(DiagOpts->ShowPresumedLoc);
 
     // First, if this diagnostic is not in the main file, print out the
     // "included from" lines.
-    emitIncludeStack(Loc, PLoc, Level);
+    if (!Loc.isLLVMLocation())
+      emitIncludeStack(Loc, PLoc, Level);
 
     // Next, emit the actual diagnostic message and caret.
     emitDiagnosticMessage(Loc, PLoc, Level, Message, Ranges, D);
@@ -145,8 +144,9 @@
 }
 
 void DiagnosticRenderer::emitBasicNote(StringRef Message) {
-  emitDiagnosticMessage(FullSourceLoc(), PresumedLoc(), DiagnosticsEngine::Note,
-                        Message, None, DiagOrStoredDiag());
+  emitDiagnosticMessage(UnifiedSourceLoc(), UnifiedPLoc(),
+                        DiagnosticsEngine::Note, Message, None,
+                        DiagOrStoredDiag());
 }
 
 /// \brief Prints an include stack when appropriate for a particular
@@ -160,11 +160,13 @@
 /// \param Loc   The diagnostic location.
 /// \param PLoc  The presumed location of the diagnostic location.
 /// \param Level The diagnostic level of the message this stack pertains to.
-void DiagnosticRenderer::emitIncludeStack(FullSourceLoc Loc, PresumedLoc PLoc,
+void DiagnosticRenderer::emitIncludeStack(UnifiedSourceLoc Loc,
+                                          UnifiedPLoc PLoc,
                                           DiagnosticsEngine::Level Level) {
-  FullSourceLoc IncludeLoc =
-      PLoc.isInvalid() ? FullSourceLoc()
-                       : FullSourceLoc(PLoc.getIncludeLoc(), Loc.getManager());
+  UnifiedSourceLoc IncludeLoc =
+      PLoc.isInvalid()
+          ? UnifiedSourceLoc()
+          : UnifiedSourceLoc(PLoc.getIncludeLoc(), Loc.getManager());
 
   // Skip redundant include stacks altogether.
   if (LastIncludeLoc == IncludeLoc)
@@ -185,57 +187,59 @@
 
 /// \brief Helper to recursivly walk up the include stack and print each layer
 /// on the way back down.
-void DiagnosticRenderer::emitIncludeStackRecursively(FullSourceLoc Loc) {
+void DiagnosticRenderer::emitIncludeStackRecursively(UnifiedSourceLoc Loc) {
   if (Loc.isInvalid()) {
     emitModuleBuildStack(Loc.getManager());
     return;
   }
 
-  PresumedLoc PLoc = Loc.getPresumedLoc(DiagOpts->ShowPresumedLoc);
+  UnifiedPLoc PLoc = Loc.getPresumedLoc(DiagOpts->ShowPresumedLoc);
   if (PLoc.isInvalid())
     return;
 
   // If this source location was imported from a module, print the module
   // import stack rather than the 
   // FIXME: We want submodule granularity here.
-  std::pair<FullSourceLoc, StringRef> Imported = Loc.getModuleImportLoc();
+  std::pair<UnifiedSourceLoc, StringRef> Imported = Loc.getModuleImportLoc();
   if (!Imported.second.empty()) {
     // This location was imported by a module. Emit the module import stack.
     emitImportStackRecursively(Imported.first, Imported.second);
     return;
   }
 
   // Emit the other include frames first.
   emitIncludeStackRecursively(
-      FullSourceLoc(PLoc.getIncludeLoc(), Loc.getManager()));
+      UnifiedSourceLoc(PLoc.getIncludeLoc(), Loc.getManager()));
 
   // Emit the inclusion text/note.
   emitIncludeLocation(Loc, PLoc);
 }
 
 /// \brief Emit the module import stack associated with the current location.
-void DiagnosticRenderer::emitImportStack(FullSourceLoc Loc) {
+void DiagnosticRenderer::emitImportStack(UnifiedSourceLoc Loc) {
   if (Loc.isInvalid()) {
     emitModuleBuildStack(Loc.getManager());
     return;
   }
 
-  std::pair<FullSourceLoc, StringRef> NextImportLoc = Loc.getModuleImportLoc();
+  std::pair<UnifiedSourceLoc, StringRef> NextImportLoc =
+      Loc.getModuleImportLoc();
   emitImportStackRecursively(NextImportLoc.first, NextImportLoc.second);
 }
 
 /// \brief Helper to recursivly walk up the import stack and print each layer
 /// on the way back down.
-void DiagnosticRenderer::emitImportStackRecursively(FullSourceLoc Loc,
+void DiagnosticRenderer::emitImportStackRecursively(UnifiedSourceLoc Loc,
                                                     StringRef ModuleName) {
   if (ModuleName.empty()) {
     return;
   }
 
-  PresumedLoc PLoc = Loc.getPresumedLoc(DiagOpts->ShowPresumedLoc);
+  UnifiedPLoc PLoc = Loc.getPresumedLoc(DiagOpts->ShowPresumedLoc);
 
   // Emit the other import frames first.
-  std::pair<FullSourceLoc, StringRef> NextImportLoc = Loc.getModuleImportLoc();
+  std::pair<UnifiedSourceLoc, StringRef> NextImportLoc =
+      Loc.getModuleImportLoc();
   emitImportStackRecursively(NextImportLoc.first, NextImportLoc.second);
 
   // Emit the inclusion text/note.
@@ -339,7 +343,7 @@
 // each chain. Two locations are part of the same macro expansion
 // iff the FileID is the same.
 static void
-mapDiagnosticRanges(FullSourceLoc CaretLoc, ArrayRef<CharSourceRange> Ranges,
+mapDiagnosticRanges(UnifiedSourceLoc CaretLoc, ArrayRef<CharSourceRange> Ranges,
                     SmallVectorImpl<CharSourceRange> &SpellingRanges) {
   FileID CaretLocFileID = CaretLoc.getFileID();
 
@@ -394,23 +398,24 @@
   }
 }
 
-void DiagnosticRenderer::emitCaret(FullSourceLoc Loc,
+void DiagnosticRenderer::emitCaret(UnifiedSourceLoc Loc,
                                    DiagnosticsEngine::Level Level,
                                    ArrayRef<CharSourceRange> Ranges,
                                    ArrayRef<FixItHint> Hints) {
   SmallVector<CharSourceRange, 4> SpellingRanges;
-  mapDiagnosticRanges(Loc, Ranges, SpellingRanges);
+  if (!Ranges.empty())
+    mapDiagnosticRanges(Loc, Ranges, SpellingRanges);
   emitCodeContext(Loc, Level, SpellingRanges, Hints);
 }
 
 /// \brief A helper function for emitMacroExpansion to print the
 /// macro expansion message
 void DiagnosticRenderer::emitSingleMacroExpansion(
-    FullSourceLoc Loc, DiagnosticsEngine::Level Level,
+    UnifiedSourceLoc Loc, DiagnosticsEngine::Level Level,
     ArrayRef<CharSourceRange> Ranges) {
   // Find the spelling location for the macro definition. We must use the
   // spelling location here to avoid emitting a macro backtrace for the note.
-  FullSourceLoc SpellingLoc = Loc.getSpellingLoc();
+  UnifiedSourceLoc SpellingLoc = Loc.getSpellingLoc();
 
   // Map the ranges into the FileID of the diagnostic location.
   SmallVector<CharSourceRange, 4> SpellingRanges;
@@ -460,7 +465,7 @@
 
 /// A helper function to check if the current ranges are all inside the same
 /// macro argument expansion as Loc.
-static bool checkRangesForMacroArgExpansion(FullSourceLoc Loc,
+static bool checkRangesForMacroArgExpansion(UnifiedSourceLoc Loc,
                                             ArrayRef<CharSourceRange> Ranges) {
   assert(Loc.isMacroID() && "Must be a macro expansion!");
 
@@ -476,7 +481,7 @@
     return false;
 
   /// To store the source location of the argument location.
-  FullSourceLoc ArgumentLoc;
+  UnifiedSourceLoc ArgumentLoc;
 
   /// Set the ArgumentLoc to the beginning location of the expansion of Loc
   /// so to check if the ranges expands to the same beginning location.
@@ -502,14 +507,14 @@
 /// \param Level The diagnostic level currently being emitted.
 /// \param Ranges The underlined ranges for this code snippet.
 /// \param Hints The FixIt hints active for this diagnostic.
-void DiagnosticRenderer::emitMacroExpansions(FullSourceLoc Loc,
+void DiagnosticRenderer::emitMacroExpansions(UnifiedSourceLoc Loc,
                                              DiagnosticsEngine::Level Level,
                                              ArrayRef<CharSourceRange> Ranges,
                                              ArrayRef<FixItHint> Hints) {
   assert(Loc.isValid() && "must have a valid source location here");
 
   // Produce a stack of macro backtraces.
-  SmallVector<FullSourceLoc, 8> LocationStack;
+  SmallVector<UnifiedSourceLoc, 8> LocationStack;
   unsigned IgnoredEnd = 0;
   while (Loc.isMacroID()) {
     // If this is the expansion of a macro argument, point the caret at the
@@ -567,18 +572,18 @@
 
 DiagnosticNoteRenderer::~DiagnosticNoteRenderer() {}
 
-void DiagnosticNoteRenderer::emitIncludeLocation(FullSourceLoc Loc,
-                                                 PresumedLoc PLoc) {
+void DiagnosticNoteRenderer::emitIncludeLocation(UnifiedSourceLoc Loc,
+                                                 UnifiedPLoc PLoc) {
   // Generate a note indicating the include location.
   SmallString<200> MessageStorage;
   llvm::raw_svector_ostream Message(MessageStorage);
   Message << "in file included from " << PLoc.getFilename() << ':'
           << PLoc.getLine() << ":";
   emitNote(Loc, Message.str());
 }
 
-void DiagnosticNoteRenderer::emitImportLocation(FullSourceLoc Loc,
-                                                PresumedLoc PLoc,
+void DiagnosticNoteRenderer::emitImportLocation(UnifiedSourceLoc Loc,
+                                                UnifiedPLoc PLoc,
                                                 StringRef ModuleName) {
   // Generate a note indicating the include location.
   SmallString<200> MessageStorage;
@@ -591,8 +596,8 @@
   emitNote(Loc, Message.str());
 }
 
-void DiagnosticNoteRenderer::emitBuildingModuleLocation(FullSourceLoc Loc,
-                                                        PresumedLoc PLoc,
+void DiagnosticNoteRenderer::emitBuildingModuleLocation(UnifiedSourceLoc Loc,
+                                                        UnifiedPLoc PLoc,
                                                         StringRef ModuleName) {
   // Generate a note indicating the include location.
   SmallString<200> MessageStorage;
Index: lib/Driver/ToolChains/Clang.cpp
===================================================================
--- lib/Driver/ToolChains/Clang.cpp
+++ lib/Driver/ToolChains/Clang.cpp
@@ -28,6 +28,7 @@
 #include "clang/Driver/Options.h"
 #include "clang/Driver/SanitizerArgs.h"
 #include "clang/Driver/XRayArgs.h"
+#include "clang/Frontend/TextDiagnosticPrinter.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Option/ArgList.h"
 #include "llvm/Support/CodeGen.h"
@@ -1684,6 +1685,33 @@
   CDB << ", \"" << escape(Buf) << "\"]},\n";
 }
 
+static void CollectArgsForColorDiagnostics(const ArgList &Args,
+                                           ArgStringList &CmdArgs,
+                                           const Driver &D) {
+  // Color diagnostics are parsed by the driver directly from argv
+  // and later re-parsed to construct this job; claim any possible
+  // color diagnostic here to avoid warn_drv_unused_argument and
+  // diagnose bad OPT_fdiagnostics_color_EQ values.
+  for (Arg *A : Args) {
+    const Option &O = A->getOption();
+    if (!O.matches(options::OPT_fcolor_diagnostics) &&
+        !O.matches(options::OPT_fdiagnostics_color) &&
+        !O.matches(options::OPT_fno_color_diagnostics) &&
+        !O.matches(options::OPT_fno_diagnostics_color) &&
+        !O.matches(options::OPT_fdiagnostics_color_EQ))
+      continue;
+    if (O.matches(options::OPT_fdiagnostics_color_EQ)) {
+      StringRef Value(A->getValue());
+      if (Value != "always" && Value != "never" && Value != "auto")
+        D.Diag(diag::err_drv_clang_unsupported)
+            << ("-fdiagnostics-color=" + Value).str();
+    }
+    A->claim();
+  }
+  if (D.getDiags().getDiagnosticOptions().ShowColors)
+    CmdArgs.push_back("-fcolor-diagnostics");
+}
+
 static void CollectArgsForIntegratedAssembler(Compilation &C,
                                               const ArgList &Args,
                                               ArgStringList &CmdArgs,
@@ -4005,28 +4033,7 @@
       CmdArgs.push_back("-fno-diagnostics-show-note-include-stack");
   }
 
-  // Color diagnostics are parsed by the driver directly from argv
-  // and later re-parsed to construct this job; claim any possible
-  // color diagnostic here to avoid warn_drv_unused_argument and
-  // diagnose bad OPT_fdiagnostics_color_EQ values.
-  for (Arg *A : Args) {
-    const Option &O = A->getOption();
-    if (!O.matches(options::OPT_fcolor_diagnostics) &&
-        !O.matches(options::OPT_fdiagnostics_color) &&
-        !O.matches(options::OPT_fno_color_diagnostics) &&
-        !O.matches(options::OPT_fno_diagnostics_color) &&
-        !O.matches(options::OPT_fdiagnostics_color_EQ))
-      continue;
-    if (O.matches(options::OPT_fdiagnostics_color_EQ)) {
-      StringRef Value(A->getValue());
-      if (Value != "always" && Value != "never" && Value != "auto")
-        getToolChain().getDriver().Diag(diag::err_drv_clang_unsupported)
-              << ("-fdiagnostics-color=" + Value).str();
-    }
-    A->claim();
-  }
-  if (D.getDiags().getDiagnosticOptions().ShowColors)
-    CmdArgs.push_back("-fcolor-diagnostics");
+  CollectArgsForColorDiagnostics(Args, CmdArgs, getToolChain().getDriver());
 
   if (Args.hasArg(options::OPT_fansi_escape_codes))
     CmdArgs.push_back("-fansi-escape-codes");
@@ -4857,9 +4864,7 @@
   const llvm::Triple &Triple = getToolChain().getEffectiveTriple();
   const std::string &TripleStr = Triple.getTriple();
 
-  // Don't warn about "clang -w -c foo.s"
-  Args.ClaimAllArgs(options::OPT_w);
-  // and "clang -emit-llvm -c foo.s"
+  // Don't warn about "clang -emit-llvm -c foo.s"
   Args.ClaimAllArgs(options::OPT_emit_llvm);
 
   claimNoWarnArgs(Args);
@@ -4998,12 +5003,11 @@
     break;
   }
 
-  // Consume all the warning flags. Usually this would be handled more
-  // gracefully by -cc1 (warning about unknown warning flags, etc) but -cc1as
-  // doesn't handle that so rather than warning about unused flags that are
-  // actually used, we'll lie by omission instead.
-  // FIXME: Stop lying and consume only the appropriate driver flags
-  Args.ClaimAllArgs(options::OPT_W_Group);
+  // Pass all warning flags to -cc1as.
+  Args.AddAllArgs(CmdArgs, options::OPT_W_Group);
+  Args.AddLastArg(CmdArgs, options::OPT_w);
+
+  CollectArgsForColorDiagnostics(Args, CmdArgs, getToolChain().getDriver());
 
   CollectArgsForIntegratedAssembler(C, Args, CmdArgs,
                                     getToolChain().getDriver());
Index: lib/Driver/DriverOptions.cpp
===================================================================
--- lib/Driver/DriverOptions.cpp
+++ lib/Driver/DriverOptions.cpp
@@ -7,10 +7,17 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/DiagnosticOptions.h"
+#include "clang/Driver/DriverDiagnostic.h"
 #include "clang/Driver/Options.h"
+#include "clang/Frontend/Utils.h"
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Option/ArgList.h"
 #include "llvm/Option/OptTable.h"
 #include "llvm/Option/Option.h"
+#include "llvm/Support/Process.h"
 
 using namespace clang::driver;
 using namespace clang::driver::options;
Index: lib/Basic/SourceLocation.cpp
===================================================================
--- lib/Basic/SourceLocation.cpp
+++ lib/Basic/SourceLocation.cpp
@@ -101,8 +101,7 @@
 std::pair<FullSourceLoc, FullSourceLoc>
 FullSourceLoc::getImmediateExpansionRange() const {
   assert(isValid());
-  std::pair<SourceLocation, SourceLocation> Range =
-      SrcMgr->getImmediateExpansionRange(*this);
+  auto Range = SrcMgr->getImmediateExpansionRange(*this);
   return std::make_pair(FullSourceLoc(Range.first, *SrcMgr),
                         FullSourceLoc(Range.second, *SrcMgr));
 }
@@ -128,8 +127,7 @@
   if (!isValid())
     return std::make_pair(FullSourceLoc(), StringRef());
 
-  std::pair<SourceLocation, StringRef> ImportLoc =
-      SrcMgr->getModuleImportLoc(*this);
+  auto ImportLoc = SrcMgr->getModuleImportLoc(*this);
   return std::make_pair(FullSourceLoc(ImportLoc.first, *SrcMgr),
                         ImportLoc.second);
 }
@@ -152,8 +150,7 @@
 std::pair<FullSourceLoc, FullSourceLoc>
 FullSourceLoc::getExpansionRange() const {
   assert(isValid());
-  std::pair<SourceLocation, SourceLocation> Range =
-      SrcMgr->getExpansionRange(*this);
+  auto Range = SrcMgr->getExpansionRange(*this);
   return std::make_pair(FullSourceLoc(Range.first, *SrcMgr),
                         FullSourceLoc(Range.second, *SrcMgr));
 }
@@ -211,4 +208,100 @@
   return SrcMgr->getDecomposedLoc(*this);
 }
 
+bool UnifiedSourceLoc::isValid() const {
+  if (!SrcMgr)
+    return FullSourceLoc::isValid();
+
+  return Loc.isValid();
+}
+
+UnifiedSourceLoc UnifiedSourceLoc::getFileLoc() const {
+  if (!SrcMgr)
+    return FullSourceLoc::getFileLoc();
+
+  // Just return the current location.
+  return *this;
+}
+
+UnifiedPLoc UnifiedSourceLoc::getPresumedLoc(bool UseLineDirectives) const {
+  if (!SrcMgr)
+    return FullSourceLoc::getPresumedLoc(UseLineDirectives);
+
+  // Return the current location as a PresumedLoc.
+  return UnifiedPLoc(Loc, *SrcMgr);
+}
+
+bool UnifiedSourceLoc::isLLVMLocation() const { return !!SrcMgr; }
+
+std::pair<FileID, unsigned> UnifiedSourceLoc::getDecomposedLoc() const {
+  if (!SrcMgr)
+    return FullSourceLoc::getDecomposedLoc();
+
+  unsigned Offset = Loc.getPointer() - getBufferData().data();
+  return std::make_pair(FileID(), Offset);
+}
+
+StringRef UnifiedSourceLoc::getBufferData(bool *Invalid) const {
+  if (!SrcMgr)
+    return FullSourceLoc::getBufferData(Invalid);
+
+  unsigned BufID = SrcMgr->FindBufferContainingLoc(Loc);
+  return SrcMgr->getMemoryBuffer(BufID)->getBuffer();
+}
+
+unsigned UnifiedSourceLoc::getLineNumber() const {
+  if (!SrcMgr)
+    return FullSourceLoc::getLineNumber();
+
+  return SrcMgr->getLineAndColumn(Loc).first;
+}
+
+unsigned UnifiedSourceLoc::getColumnNumber() const {
+  if (!SrcMgr)
+    return FullSourceLoc::getColumnNumber();
+
+  return SrcMgr->getLineAndColumn(Loc).second;
+}
+
+bool UnifiedPLoc::isValid() const {
+  if (!SrcMgr)
+    return PresumedLoc::isValid();
+
+  return Loc.isValid();
+}
+
+bool UnifiedPLoc::isInvalid() const { return !isValid(); }
+
+unsigned UnifiedPLoc::getLine() const {
+  if (!SrcMgr)
+    return PresumedLoc::getLine();
+
+  return SrcMgr->getLineAndColumn(Loc).first;
+}
+
+unsigned UnifiedPLoc::getColumn() const {
+  if (!SrcMgr)
+    return PresumedLoc::getColumn();
+
+  return SrcMgr->getLineAndColumn(Loc).second;
+}
+
+StringRef UnifiedPLoc::getFilename() const {
+  if (!SrcMgr)
+    return PresumedLoc::getFilename();
+
+  unsigned CurBuf = SrcMgr->FindBufferContainingLoc(Loc);
+  assert(CurBuf && "Invalid or unspecified location!");
+
+  const llvm::MemoryBuffer *CurMB = SrcMgr->getMemoryBuffer(CurBuf);
+  return CurMB->getBufferIdentifier();
+}
+
+SourceLocation UnifiedPLoc::getIncludeLoc() const {
+  if (!SrcMgr)
+    return PresumedLoc::getIncludeLoc();
+
+  return SourceLocation();
+}
+
 } // end namespace clang
Index: include/clang/Frontend/TextDiagnostic.h
===================================================================
--- include/clang/Frontend/TextDiagnostic.h
+++ include/clang/Frontend/TextDiagnostic.h
@@ -75,33 +75,33 @@
                                      unsigned Columns, bool ShowColors);
 
 protected:
-  void emitDiagnosticMessage(FullSourceLoc Loc, PresumedLoc PLoc,
+  void emitDiagnosticMessage(UnifiedSourceLoc Loc, UnifiedPLoc PLoc,
                              DiagnosticsEngine::Level Level, StringRef Message,
                              ArrayRef<CharSourceRange> Ranges,
                              DiagOrStoredDiag D) override;
 
-  void emitDiagnosticLoc(FullSourceLoc Loc, PresumedLoc PLoc,
+  void emitDiagnosticLoc(UnifiedSourceLoc Loc, UnifiedPLoc PLoc,
                          DiagnosticsEngine::Level Level,
                          ArrayRef<CharSourceRange> Ranges) override;
 
-  void emitCodeContext(FullSourceLoc Loc, DiagnosticsEngine::Level Level,
+  void emitCodeContext(UnifiedSourceLoc Loc, DiagnosticsEngine::Level Level,
                        SmallVectorImpl<CharSourceRange> &Ranges,
                        ArrayRef<FixItHint> Hints) override {
     emitSnippetAndCaret(Loc, Level, Ranges, Hints);
   }
 
-  void emitIncludeLocation(FullSourceLoc Loc, PresumedLoc PLoc) override;
+  void emitIncludeLocation(UnifiedSourceLoc Loc, UnifiedPLoc PLoc) override;
 
-  void emitImportLocation(FullSourceLoc Loc, PresumedLoc PLoc,
+  void emitImportLocation(UnifiedSourceLoc Loc, UnifiedPLoc PLoc,
                           StringRef ModuleName) override;
 
-  void emitBuildingModuleLocation(FullSourceLoc Loc, PresumedLoc PLoc,
+  void emitBuildingModuleLocation(UnifiedSourceLoc Loc, UnifiedPLoc PLoc,
                                   StringRef ModuleName) override;
 
 private:
-  void emitFilename(StringRef Filename, const SourceManager &SM);
+  void emitFilename(StringRef Filename, const SourceManager *SM);
 
-  void emitSnippetAndCaret(FullSourceLoc Loc, DiagnosticsEngine::Level Level,
+  void emitSnippetAndCaret(UnifiedSourceLoc Loc, DiagnosticsEngine::Level Level,
                            SmallVectorImpl<CharSourceRange> &Ranges,
                            ArrayRef<FixItHint> Hints);
 
Index: include/clang/Frontend/DiagnosticRenderer.h
===================================================================
--- include/clang/Frontend/DiagnosticRenderer.h
+++ include/clang/Frontend/DiagnosticRenderer.h
@@ -52,8 +52,8 @@
   /// This will be invalid in cases where there is no (known) previous
   /// diagnostic location, or that location itself is invalid or comes from
   /// a different source manager than SM.
-  SourceLocation LastLoc;
-  
+  UnifiedSourceLoc LastLoc;
+
   /// \brief The location of the last include whose stack was printed if known.
   ///
   /// Same restriction as LastLoc essentially, but tracking include stack
@@ -71,25 +71,26 @@
   
   virtual ~DiagnosticRenderer();
 
-  virtual void emitDiagnosticMessage(FullSourceLoc Loc, PresumedLoc PLoc,
+  virtual void emitDiagnosticMessage(UnifiedSourceLoc Loc, UnifiedPLoc PLoc,
                                      DiagnosticsEngine::Level Level,
                                      StringRef Message,
                                      ArrayRef<CharSourceRange> Ranges,
                                      DiagOrStoredDiag Info) = 0;
 
-  virtual void emitDiagnosticLoc(FullSourceLoc Loc, PresumedLoc PLoc,
+  virtual void emitDiagnosticLoc(UnifiedSourceLoc Loc, UnifiedPLoc PLoc,
                                  DiagnosticsEngine::Level Level,
                                  ArrayRef<CharSourceRange> Ranges) = 0;
 
-  virtual void emitCodeContext(FullSourceLoc Loc,
+  virtual void emitCodeContext(UnifiedSourceLoc Loc,
                                DiagnosticsEngine::Level Level,
                                SmallVectorImpl<CharSourceRange> &Ranges,
                                ArrayRef<FixItHint> Hints) = 0;
 
-  virtual void emitIncludeLocation(FullSourceLoc Loc, PresumedLoc PLoc) = 0;
-  virtual void emitImportLocation(FullSourceLoc Loc, PresumedLoc PLoc,
+  virtual void emitIncludeLocation(UnifiedSourceLoc Loc, UnifiedPLoc PLoc) = 0;
+  virtual void emitImportLocation(UnifiedSourceLoc Loc, UnifiedPLoc PLoc,
                                   StringRef ModuleName) = 0;
-  virtual void emitBuildingModuleLocation(FullSourceLoc Loc, PresumedLoc PLoc,
+  virtual void emitBuildingModuleLocation(UnifiedSourceLoc Loc,
+                                          UnifiedPLoc PLoc,
                                           StringRef ModuleName) = 0;
 
   virtual void beginDiagnostic(DiagOrStoredDiag D,
@@ -100,18 +101,18 @@
   
 private:
   void emitBasicNote(StringRef Message);
-  void emitIncludeStack(FullSourceLoc Loc, PresumedLoc PLoc,
+  void emitIncludeStack(UnifiedSourceLoc Loc, UnifiedPLoc PLoc,
                         DiagnosticsEngine::Level Level);
-  void emitIncludeStackRecursively(FullSourceLoc Loc);
-  void emitImportStack(FullSourceLoc Loc);
-  void emitImportStackRecursively(FullSourceLoc Loc, StringRef ModuleName);
+  void emitIncludeStackRecursively(UnifiedSourceLoc Loc);
+  void emitImportStack(UnifiedSourceLoc Loc);
+  void emitImportStackRecursively(UnifiedSourceLoc Loc, StringRef ModuleName);
   void emitModuleBuildStack(const SourceManager &SM);
-  void emitCaret(FullSourceLoc Loc, DiagnosticsEngine::Level Level,
+  void emitCaret(UnifiedSourceLoc Loc, DiagnosticsEngine::Level Level,
                  ArrayRef<CharSourceRange> Ranges, ArrayRef<FixItHint> Hints);
-  void emitSingleMacroExpansion(FullSourceLoc Loc,
+  void emitSingleMacroExpansion(UnifiedSourceLoc Loc,
                                 DiagnosticsEngine::Level Level,
                                 ArrayRef<CharSourceRange> Ranges);
-  void emitMacroExpansions(FullSourceLoc Loc, DiagnosticsEngine::Level Level,
+  void emitMacroExpansions(UnifiedSourceLoc Loc, DiagnosticsEngine::Level Level,
                            ArrayRef<CharSourceRange> Ranges,
                            ArrayRef<FixItHint> Hints);
 
@@ -130,7 +131,7 @@
   /// \param FixItHints The FixIt hints active for this diagnostic.
   /// \param SM The SourceManager; will be null if the diagnostic came from the
   ///        frontend, thus \p Loc will be invalid.
-  void emitDiagnostic(FullSourceLoc Loc, DiagnosticsEngine::Level Level,
+  void emitDiagnostic(UnifiedSourceLoc Loc, DiagnosticsEngine::Level Level,
                       StringRef Message, ArrayRef<CharSourceRange> Ranges,
                       ArrayRef<FixItHint> FixItHints,
                       DiagOrStoredDiag D = (Diagnostic *)nullptr);
@@ -148,15 +149,15 @@
 
   ~DiagnosticNoteRenderer() override;
 
-  void emitIncludeLocation(FullSourceLoc Loc, PresumedLoc PLoc) override;
+  void emitIncludeLocation(UnifiedSourceLoc Loc, UnifiedPLoc PLoc) override;
 
-  void emitImportLocation(FullSourceLoc Loc, PresumedLoc PLoc,
+  void emitImportLocation(UnifiedSourceLoc Loc, UnifiedPLoc PLoc,
                           StringRef ModuleName) override;
 
-  void emitBuildingModuleLocation(FullSourceLoc Loc, PresumedLoc PLoc,
+  void emitBuildingModuleLocation(UnifiedSourceLoc Loc, UnifiedPLoc PLoc,
                                   StringRef ModuleName) override;
 
-  virtual void emitNote(FullSourceLoc Loc, StringRef Message) = 0;
+  virtual void emitNote(UnifiedSourceLoc Loc, StringRef Message) = 0;
 };
 } // end clang namespace
 #endif
Index: include/clang/Driver/Options.td
===================================================================
--- include/clang/Driver/Options.td
+++ include/clang/Driver/Options.td
@@ -433,7 +433,7 @@
   MetaVarName<"<arg>">, Group<Preprocessor_Group>;
 def Wwrite_strings : Flag<["-"], "Wwrite-strings">, Group<W_Group>, Flags<[CC1Option, HelpHidden]>;
 def Wno_write_strings : Flag<["-"], "Wno-write-strings">, Group<W_Group>, Flags<[CC1Option, HelpHidden]>;
-def W_Joined : Joined<["-"], "W">, Group<W_Group>, Flags<[CC1Option, CoreOption]>,
+def W_Joined : Joined<["-"], "W">, Group<W_Group>, Flags<[CC1Option, CC1AsOption, CoreOption]>,
   MetaVarName<"<warning>">, HelpText<"Enable the specified warning">;
 def Xanalyzer : Separate<["-"], "Xanalyzer">,
   HelpText<"Pass <arg> to the static analyzer">, MetaVarName<"<arg>">,
@@ -685,7 +685,7 @@
 def fcaret_diagnostics : Flag<["-"], "fcaret-diagnostics">, Group<f_Group>;
 def fclasspath_EQ : Joined<["-"], "fclasspath=">, Group<f_Group>;
 def fcolor_diagnostics : Flag<["-"], "fcolor-diagnostics">, Group<f_Group>,
-  Flags<[CoreOption, CC1Option]>, HelpText<"Use colors in diagnostics">;
+  Flags<[CoreOption, CC1Option, CC1AsOption]>, HelpText<"Use colors in diagnostics">;
 def fdiagnostics_color : Flag<["-"], "fdiagnostics-color">, Group<f_Group>,
   Flags<[CoreOption, DriverOption]>;
 def fdiagnostics_color_EQ : Joined<["-"], "fdiagnostics-color=">, Group<f_Group>;
@@ -2208,7 +2208,7 @@
 def weak__reference__mismatches : Separate<["-"], "weak_reference_mismatches">;
 def whatsloaded : Flag<["-"], "whatsloaded">;
 def whyload : Flag<["-"], "whyload">;
-def w : Flag<["-"], "w">, HelpText<"Suppress all warnings">, Flags<[CC1Option]>;
+def w : Flag<["-"], "w">, HelpText<"Suppress all warnings">, Flags<[CC1Option,CC1AsOption]>;
 def x : JoinedOrSeparate<["-"], "x">, Flags<[DriverOption,CC1Option]>,
   HelpText<"Treat subsequent input files as having type <language>">,
   MetaVarName<"<language>">;
Index: include/clang/Driver/Options.h
===================================================================
--- include/clang/Driver/Options.h
+++ include/clang/Driver/Options.h
@@ -15,10 +15,13 @@
 namespace llvm {
 namespace opt {
 class OptTable;
+class ArgList;
 }
 }
 
 namespace clang {
+class DiagnosticOptions;
+class DiagnosticsEngine;
 namespace driver {
 
 namespace options {
Index: include/clang/Basic/SourceLocation.h
===================================================================
--- include/clang/Basic/SourceLocation.h
+++ include/clang/Basic/SourceLocation.h
@@ -18,13 +18,15 @@
 #include "clang/Basic/LLVM.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/PointerLikeTypeTraits.h"
+#include "llvm/Support/SMLoc.h"
 #include <cassert>
 #include <functional>
 #include <string>
 #include <utility>
 
 namespace llvm {
   class MemoryBuffer;
+  class SourceMgr;
   template <typename T> struct DenseMapInfo;
   template <typename T> struct isPodLike;
 }
@@ -418,7 +420,59 @@
 
 };
 
+class UnifiedPLoc : public PresumedLoc {
+  const llvm::SourceMgr *SrcMgr = nullptr;
+  llvm::SMLoc Loc = llvm::SMLoc();
 
+public:
+  UnifiedPLoc() : PresumedLoc() {}
+  UnifiedPLoc(PresumedLoc Loc) : PresumedLoc(Loc) {}
+  explicit UnifiedPLoc(llvm::SMLoc Loc, const llvm::SourceMgr &SM)
+      : PresumedLoc(), SrcMgr(&SM), Loc(Loc) {}
+
+  bool isValid() const;
+  bool isInvalid() const;
+  unsigned getLine() const;
+  unsigned getColumn() const;
+  StringRef getFilename() const;
+
+  SourceLocation getIncludeLoc() const;
+};
+
+class UnifiedSourceLoc : public FullSourceLoc {
+  const llvm::SourceMgr *SrcMgr = nullptr;
+  llvm::SMLoc Loc = llvm::SMLoc();
+
+public:
+  UnifiedSourceLoc() : FullSourceLoc() {}
+  UnifiedSourceLoc(FullSourceLoc Loc) : FullSourceLoc(Loc) {}
+  UnifiedSourceLoc(SourceLocation Loc, const SourceManager &SM)
+      : FullSourceLoc(Loc, SM) {}
+  explicit UnifiedSourceLoc(llvm::SMLoc Loc, const llvm::SourceMgr &SM)
+      : FullSourceLoc(), SrcMgr(&SM), Loc(Loc) {}
+
+  bool isValid() const;
+  UnifiedSourceLoc getFileLoc() const;
+  UnifiedPLoc getPresumedLoc(bool UseLineDirectives = true) const;
+  bool isLLVMLocation() const;
+  std::pair<FileID, unsigned> getDecomposedLoc() const;
+  StringRef getBufferData(bool *Invalid = nullptr) const;
+  unsigned getLineNumber() const;
+  unsigned getColumnNumber() const;
+
+  friend inline bool operator==(const UnifiedSourceLoc &LHS,
+                                const UnifiedSourceLoc &RHS) {
+    if (!LHS.SrcMgr && !RHS.SrcMgr)
+      return static_cast<FullSourceLoc>(LHS) == static_cast<FullSourceLoc>(RHS);
+
+    return LHS.Loc == RHS.Loc && LHS.SrcMgr == RHS.SrcMgr;
+  }
+
+  friend inline bool operator!=(const UnifiedSourceLoc &LHS,
+                                const UnifiedSourceLoc &RHS) {
+    return !(LHS == RHS);
+  }
+};
 
 }  // end namespace clang
 
Index: include/clang/Basic/Diagnostic.h
===================================================================
--- include/clang/Basic/Diagnostic.h
+++ include/clang/Basic/Diagnostic.h
@@ -22,9 +22,10 @@
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/iterator_range.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/Support/SMLoc.h"
 #include <algorithm>
 #include <cassert>
 #include <cstdint>
@@ -36,6 +37,11 @@
 #include <utility>
 #include <vector>
 
+namespace llvm {
+
+class SourceMgr;
+}
+
 namespace clang {
 
 class DeclContext;
@@ -733,6 +739,8 @@
   /// which can be an invalid location if no position information is available.
   inline DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID);
   inline DiagnosticBuilder Report(unsigned DiagID);
+  inline DiagnosticBuilder Report(const llvm::SourceMgr *SM, llvm::SMLoc Loc,
+                                  unsigned DiagID);
 
   void Report(const StoredDiagnostic &storedDiag);
 
@@ -786,7 +794,7 @@
   friend class DiagnosticErrorTrap;
   
   /// \brief The location of the current diagnostic that is in flight.
-  SourceLocation CurDiagLoc;
+  UnifiedSourceLoc CurDiagLoc;
 
   /// \brief The ID of the current diagnostic that is in flight.
   ///
@@ -1180,7 +1188,12 @@
 inline DiagnosticBuilder DiagnosticsEngine::Report(SourceLocation Loc,
                                                    unsigned DiagID) {
   assert(CurDiagID == ~0U && "Multiple diagnostics in flight at once!");
-  CurDiagLoc = Loc;
+
+  if (!Loc.isValid() || !hasSourceManager())
+    CurDiagLoc = UnifiedSourceLoc();
+  else
+    CurDiagLoc = UnifiedSourceLoc(Loc, getSourceManager());
+
   CurDiagID = DiagID;
   FlagValue.clear();
   return DiagnosticBuilder(this);
@@ -1190,6 +1203,19 @@
   return Report(SourceLocation(), DiagID);
 }
 
+inline DiagnosticBuilder DiagnosticsEngine::Report(const llvm::SourceMgr *SM,
+                                                   llvm::SMLoc Loc,
+                                                   unsigned DiagID) {
+  auto DB = Report(DiagID);
+
+  if (!Loc.isValid() || !SM)
+    CurDiagLoc = UnifiedSourceLoc();
+  else
+    CurDiagLoc = UnifiedSourceLoc(Loc, *SM);
+
+  return DB;
+}
+
 //===----------------------------------------------------------------------===//
 // Diagnostic
 //===----------------------------------------------------------------------===//
@@ -1208,7 +1234,7 @@
 
   const DiagnosticsEngine *getDiags() const { return DiagObj; }
   unsigned getID() const { return DiagObj->CurDiagID; }
-  const SourceLocation &getLocation() const { return DiagObj->CurDiagLoc; }
+  const UnifiedSourceLoc &getLocation() const { return DiagObj->CurDiagLoc; }
   bool hasSourceManager() const { return DiagObj->hasSourceManager(); }
   SourceManager &getSourceManager() const { return DiagObj->getSourceManager();}
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to