[cfe-commits] r156536 - in /cfe/trunk: include/clang/Frontend/DiagnosticRenderer.h include/clang/Frontend/TextDiagnostic.h include/clang/Frontend/TextDiagnosticPrinter.h lib/Frontend/DiagnosticRenderer.cpp lib/Frontend/SerializedDiagnosticPrinter.cpp lib/Frontend/TextDiagnostic.cpp lib/Frontend/TextDiagnosticPrinter.cpp test/Misc/serialized-diags-frontend.c tools/libclang/CIndexDiagnostic.cpp

Argyrios Kyrtzidis akyrtzi at gmail.com
Wed May 9 22:03:46 PDT 2012


Author: akirtzidis
Date: Thu May 10 00:03:45 2012
New Revision: 156536

URL: http://llvm.org/viewvc/llvm-project?rev=156536&view=rev
Log:
Fix an assertion hit when the serialized diagnostics writer receive a diagnostic
from the frontend when the location is invalid and the SourceManager null.

Instead of keeping the SourceManager object in DiagnosticRenderer, propagate it
to the calls accordingly (as reference when it is expected to not be null, or pointer
when it may be null).
This effectively makes DiagnosticRenderer not tied to a specific SourceManager,
removing a hack from TextDiagnosticPrinter.

rdar://11386874

Added:
    cfe/trunk/test/Misc/serialized-diags-frontend.c
Modified:
    cfe/trunk/include/clang/Frontend/DiagnosticRenderer.h
    cfe/trunk/include/clang/Frontend/TextDiagnostic.h
    cfe/trunk/include/clang/Frontend/TextDiagnosticPrinter.h
    cfe/trunk/lib/Frontend/DiagnosticRenderer.cpp
    cfe/trunk/lib/Frontend/SerializedDiagnosticPrinter.cpp
    cfe/trunk/lib/Frontend/TextDiagnostic.cpp
    cfe/trunk/lib/Frontend/TextDiagnosticPrinter.cpp
    cfe/trunk/tools/libclang/CIndexDiagnostic.cpp

Modified: cfe/trunk/include/clang/Frontend/DiagnosticRenderer.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/DiagnosticRenderer.h?rev=156536&r1=156535&r2=156536&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/DiagnosticRenderer.h (original)
+++ cfe/trunk/include/clang/Frontend/DiagnosticRenderer.h Thu May 10 00:03:45 2012
@@ -43,7 +43,6 @@
 /// class.
 class DiagnosticRenderer {
 protected:
-  const SourceManager &SM;
   const LangOptions &LangOpts;
   const DiagnosticOptions &DiagOpts;
   
@@ -66,8 +65,7 @@
   /// which change the amount of information displayed.
   DiagnosticsEngine::Level LastLevel;
 
-  DiagnosticRenderer(const SourceManager &SM,
-                     const LangOptions &LangOpts,
+  DiagnosticRenderer(const LangOptions &LangOpts,
                      const DiagnosticOptions &DiagOpts);
   
   virtual ~DiagnosticRenderer();
@@ -76,20 +74,24 @@
                                      DiagnosticsEngine::Level Level,
                                      StringRef Message,
                                      ArrayRef<CharSourceRange> Ranges,
+                                     const SourceManager *SM,
                                      DiagOrStoredDiag Info) = 0;
   
   virtual void emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
                                  DiagnosticsEngine::Level Level,
-                                 ArrayRef<CharSourceRange> Ranges) = 0;
+                                 ArrayRef<CharSourceRange> Ranges,
+                                 const SourceManager &SM) = 0;
   
   virtual void emitBasicNote(StringRef Message) = 0;
   
   virtual void emitCodeContext(SourceLocation Loc,
                                DiagnosticsEngine::Level Level,
                                SmallVectorImpl<CharSourceRange>& Ranges,
-                               ArrayRef<FixItHint> Hints) = 0;
+                               ArrayRef<FixItHint> Hints,
+                               const SourceManager &SM) = 0;
   
-  virtual void emitIncludeLocation(SourceLocation Loc, PresumedLoc PLoc) = 0;
+  virtual void emitIncludeLocation(SourceLocation Loc, PresumedLoc PLoc,
+                                   const SourceManager &SM) = 0;
   
   virtual void beginDiagnostic(DiagOrStoredDiag D,
                                DiagnosticsEngine::Level Level) {}
@@ -98,12 +100,14 @@
 
   
 private:
-  void emitIncludeStack(SourceLocation Loc, DiagnosticsEngine::Level Level);
-  void emitIncludeStackRecursively(SourceLocation Loc);
+  void emitIncludeStack(SourceLocation Loc, DiagnosticsEngine::Level Level,
+                        const SourceManager &SM);
+  void emitIncludeStackRecursively(SourceLocation Loc, const SourceManager &SM);
   void emitMacroExpansionsAndCarets(SourceLocation Loc,
                                     DiagnosticsEngine::Level Level,
                                     SmallVectorImpl<CharSourceRange>& Ranges,
                                     ArrayRef<FixItHint> Hints,
+                                    const SourceManager &SM,
                                     unsigned &MacroDepth,
                                     unsigned OnMacroInst = 0);
 public:
@@ -119,9 +123,12 @@
   /// \param Message The diagnostic message to emit.
   /// \param Ranges The underlined ranges for this code snippet.
   /// \param FixItHints The FixIt hints active for this diagnostic.
+  /// \param SM The SourceManager; will be null if the diagnostic came from the
+  ///        frontend, thus \param Loc will be invalid.
   void emitDiagnostic(SourceLocation Loc, DiagnosticsEngine::Level Level,
                       StringRef Message, ArrayRef<CharSourceRange> Ranges,
                       ArrayRef<FixItHint> FixItHints,
+                      const SourceManager *SM,
                       DiagOrStoredDiag D = (Diagnostic *)0);
 
   void emitStoredDiagnostic(StoredDiagnostic &Diag);
@@ -131,19 +138,20 @@
 /// notes.  It is up to subclasses to further define the behavior.
 class DiagnosticNoteRenderer : public DiagnosticRenderer {
 public:
-  DiagnosticNoteRenderer(const SourceManager &SM,
-                         const LangOptions &LangOpts,
+  DiagnosticNoteRenderer(const LangOptions &LangOpts,
                          const DiagnosticOptions &DiagOpts)
-    : DiagnosticRenderer(SM, LangOpts, DiagOpts) {}
+    : DiagnosticRenderer(LangOpts, DiagOpts) {}
   
   virtual ~DiagnosticNoteRenderer();
   
   virtual void emitBasicNote(StringRef Message);
     
   virtual void emitIncludeLocation(SourceLocation Loc,
-                                   PresumedLoc PLoc);
+                                   PresumedLoc PLoc,
+                                   const SourceManager &SM);
   
-  virtual void emitNote(SourceLocation Loc, StringRef Message) = 0;
+  virtual void emitNote(SourceLocation Loc, StringRef Message,
+                        const SourceManager *SM) = 0;
 };
 } // end clang namespace
 #endif

Modified: cfe/trunk/include/clang/Frontend/TextDiagnostic.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/TextDiagnostic.h?rev=156536&r1=156535&r2=156536&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/TextDiagnostic.h (original)
+++ cfe/trunk/include/clang/Frontend/TextDiagnostic.h Thu May 10 00:03:45 2012
@@ -39,7 +39,6 @@
 
 public:
   TextDiagnostic(raw_ostream &OS,
-                 const SourceManager &SM,
                  const LangOptions &LangOpts,
                  const DiagnosticOptions &DiagOpts);
 
@@ -83,39 +82,46 @@
                                      DiagnosticsEngine::Level Level,
                                      StringRef Message,
                                      ArrayRef<CharSourceRange> Ranges,
+                                     const SourceManager *SM,
                                      DiagOrStoredDiag D);
 
   virtual void emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
                                  DiagnosticsEngine::Level Level,
-                                 ArrayRef<CharSourceRange> Ranges);
+                                 ArrayRef<CharSourceRange> Ranges,
+                                 const SourceManager &SM);
   
   virtual void emitCodeContext(SourceLocation Loc,
                                DiagnosticsEngine::Level Level,
                                SmallVectorImpl<CharSourceRange>& Ranges,
-                               ArrayRef<FixItHint> Hints) {
-    emitSnippetAndCaret(Loc, Level, Ranges, Hints);
+                               ArrayRef<FixItHint> Hints,
+                               const SourceManager &SM) {
+    emitSnippetAndCaret(Loc, Level, Ranges, Hints, SM);
   }
   
   virtual void emitBasicNote(StringRef Message);
   
-  virtual void emitIncludeLocation(SourceLocation Loc, PresumedLoc PLoc);
+  virtual void emitIncludeLocation(SourceLocation Loc, PresumedLoc PLoc,
+                                   const SourceManager &SM);
 
 private:
   void emitSnippetAndCaret(SourceLocation Loc, DiagnosticsEngine::Level Level,
                            SmallVectorImpl<CharSourceRange>& Ranges,
-                           ArrayRef<FixItHint> Hints);
+                           ArrayRef<FixItHint> Hints,
+                           const SourceManager &SM);
 
   void emitSnippet(StringRef SourceLine);
 
   void highlightRange(const CharSourceRange &R,
                       unsigned LineNo, FileID FID,
                       const SourceColumnMap &map,
-                      std::string &CaretLine);
+                      std::string &CaretLine,
+                      const SourceManager &SM);
 
   std::string buildFixItInsertionLine(unsigned LineNo,
                                       const SourceColumnMap &map,
-                                      ArrayRef<FixItHint> Hints);
-  void emitParseableFixits(ArrayRef<FixItHint> Hints);
+                                      ArrayRef<FixItHint> Hints,
+                                      const SourceManager &SM);
+  void emitParseableFixits(ArrayRef<FixItHint> Hints, const SourceManager &SM);
 };
 
 } // end namespace clang

Modified: cfe/trunk/include/clang/Frontend/TextDiagnosticPrinter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/TextDiagnosticPrinter.h?rev=156536&r1=156535&r2=156536&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/TextDiagnosticPrinter.h (original)
+++ cfe/trunk/include/clang/Frontend/TextDiagnosticPrinter.h Thu May 10 00:03:45 2012
@@ -26,9 +26,7 @@
 
 class TextDiagnosticPrinter : public DiagnosticConsumer {
   raw_ostream &OS;
-  const LangOptions *LangOpts;
   const DiagnosticOptions *DiagOpts;
-  const SourceManager *SM;
 
   /// \brief Handle to the currently active text diagnostic emitter.
   OwningPtr<TextDiagnostic> TextDiag;

Modified: cfe/trunk/lib/Frontend/DiagnosticRenderer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/DiagnosticRenderer.cpp?rev=156536&r1=156535&r2=156536&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/DiagnosticRenderer.cpp (original)
+++ cfe/trunk/lib/Frontend/DiagnosticRenderer.cpp Thu May 10 00:03:45 2012
@@ -123,10 +123,9 @@
   return SM.getPresumedLoc(Loc);
 }
 
-DiagnosticRenderer::DiagnosticRenderer(const SourceManager &SM,
-                                       const LangOptions &LangOpts,
+DiagnosticRenderer::DiagnosticRenderer(const LangOptions &LangOpts,
                                        const DiagnosticOptions &DiagOpts)
-: SM(SM), LangOpts(LangOpts), DiagOpts(DiagOpts), LastLevel() {}
+: LangOpts(LangOpts), DiagOpts(DiagOpts), LastLevel() {}
 
 DiagnosticRenderer::~DiagnosticRenderer() {}
 
@@ -184,18 +183,23 @@
                                         StringRef Message,
                                         ArrayRef<CharSourceRange> Ranges,
                                         ArrayRef<FixItHint> FixItHints,
+                                        const SourceManager *SM,
                                         DiagOrStoredDiag D) {
+  assert(SM || Loc.isInvalid());
   
   beginDiagnostic(D, Level);
   
-  PresumedLoc PLoc = getDiagnosticPresumedLoc(SM, Loc);
+  PresumedLoc PLoc;
+  if (Loc.isValid()) {
+    PLoc = getDiagnosticPresumedLoc(*SM, Loc);
   
-  // First, if this diagnostic is not in the main file, print out the
-  // "included from" lines.
-  emitIncludeStack(PLoc.getIncludeLoc(), Level);
+    // First, if this diagnostic is not in the main file, print out the
+    // "included from" lines.
+    emitIncludeStack(PLoc.getIncludeLoc(), Level, *SM);
+  }
   
   // Next, emit the actual diagnostic message.
-  emitDiagnosticMessage(Loc, PLoc, Level, Message, Ranges, D);
+  emitDiagnosticMessage(Loc, PLoc, Level, Message, Ranges, SM, D);
   
   // Only recurse if we have a valid location.
   if (Loc.isValid()) {
@@ -205,7 +209,7 @@
     
     llvm::SmallVector<FixItHint, 8> MergedFixits;
     if (!FixItHints.empty()) {
-      mergeFixits(FixItHints, SM, LangOpts, MergedFixits);
+      mergeFixits(FixItHints, *SM, LangOpts, MergedFixits);
       FixItHints = MergedFixits;
     }
 
@@ -216,7 +220,7 @@
         MutableRanges.push_back(I->RemoveRange);
     
     unsigned MacroDepth = 0;
-    emitMacroExpansionsAndCarets(Loc, Level, MutableRanges, FixItHints,
+    emitMacroExpansionsAndCarets(Loc, Level, MutableRanges, FixItHints, *SM,
                                  MacroDepth);
   }
   
@@ -230,6 +234,8 @@
 void DiagnosticRenderer::emitStoredDiagnostic(StoredDiagnostic &Diag) {
   emitDiagnostic(Diag.getLocation(), Diag.getLevel(), Diag.getMessage(),
                  Diag.getRanges(), Diag.getFixIts(),
+                 Diag.getLocation().isValid() ? &Diag.getLocation().getManager()
+                                              : 0,
                  &Diag);
 }
 
@@ -245,7 +251,8 @@
 /// \param Loc   The include location of the current file (not the diagnostic
 ///              location).
 void DiagnosticRenderer::emitIncludeStack(SourceLocation Loc,
-                                          DiagnosticsEngine::Level Level) {
+                                          DiagnosticsEngine::Level Level,
+                                          const SourceManager &SM) {
   // Skip redundant include stacks altogether.
   if (LastIncludeLoc == Loc)
     return;
@@ -254,12 +261,13 @@
   if (!DiagOpts.ShowNoteIncludeStack && Level == DiagnosticsEngine::Note)
     return;
   
-  emitIncludeStackRecursively(Loc);
+  emitIncludeStackRecursively(Loc, SM);
 }
 
 /// \brief Helper to recursivly walk up the include stack and print each layer
 /// on the way back down.
-void DiagnosticRenderer::emitIncludeStackRecursively(SourceLocation Loc) {
+void DiagnosticRenderer::emitIncludeStackRecursively(SourceLocation Loc,
+                                                     const SourceManager &SM) {
   if (Loc.isInvalid())
     return;
   
@@ -268,10 +276,10 @@
     return;
   
   // Emit the other include frames first.
-  emitIncludeStackRecursively(PLoc.getIncludeLoc());
+  emitIncludeStackRecursively(PLoc.getIncludeLoc(), SM);
   
   // Emit the inclusion text/note.
-  emitIncludeLocation(Loc, PLoc);
+  emitIncludeLocation(Loc, PLoc, SM);
 }
 
 /// \brief Recursively emit notes for each macro expansion and caret
@@ -292,6 +300,7 @@
        DiagnosticsEngine::Level Level,
        SmallVectorImpl<CharSourceRange>& Ranges,
        ArrayRef<FixItHint> Hints,
+       const SourceManager &SM,
        unsigned &MacroDepth,
        unsigned OnMacroInst)
 {
@@ -302,7 +311,7 @@
   if (Loc.isFileID()) {
     assert(MacroDepth == 0 && "We shouldn't hit a leaf node twice!");
     MacroDepth = OnMacroInst;
-    emitCodeContext(Loc, Level, Ranges, Hints);
+    emitCodeContext(Loc, Level, Ranges, Hints, SM);
     return;
   }
   // Otherwise recurse through each macro expansion layer.
@@ -314,7 +323,7 @@
   SourceLocation OneLevelUp = getImmediateMacroCallerLoc(SM, Loc);
   
   // FIXME: Map ranges?
-  emitMacroExpansionsAndCarets(OneLevelUp, Level, Ranges, Hints, MacroDepth,
+  emitMacroExpansionsAndCarets(OneLevelUp, Level, Ranges, Hints, SM, MacroDepth,
                                OnMacroInst + 1);
   
   // Save the original location so we can find the spelling of the macro call.
@@ -365,22 +374,23 @@
           << getImmediateMacroName(MacroLoc, SM, LangOpts) << "'";
   emitDiagnostic(SM.getSpellingLoc(Loc), DiagnosticsEngine::Note,
                  Message.str(),
-                 Ranges, ArrayRef<FixItHint>());
+                 Ranges, ArrayRef<FixItHint>(), &SM);
 }
 
 DiagnosticNoteRenderer::~DiagnosticNoteRenderer() {}
 
 void DiagnosticNoteRenderer::emitIncludeLocation(SourceLocation Loc,
-                                                 PresumedLoc PLoc) {
+                                                 PresumedLoc PLoc,
+                                                 const SourceManager &SM) {
   // 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());
+  emitNote(Loc, Message.str(), &SM);
 }
 
 void DiagnosticNoteRenderer::emitBasicNote(StringRef Message) {
-  emitNote(SourceLocation(), Message);  
+  emitNote(SourceLocation(), Message, 0);  
 }
 

Modified: cfe/trunk/lib/Frontend/SerializedDiagnosticPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/SerializedDiagnosticPrinter.cpp?rev=156536&r1=156535&r2=156536&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/SerializedDiagnosticPrinter.cpp (original)
+++ cfe/trunk/lib/Frontend/SerializedDiagnosticPrinter.cpp Thu May 10 00:03:45 2012
@@ -53,10 +53,9 @@
   RecordData &Record;
 public:
   SDiagsRenderer(SDiagsWriter &Writer, RecordData &Record,
-                 const SourceManager &SM,
                  const LangOptions &LangOpts,
                  const DiagnosticOptions &DiagOpts)
-    : DiagnosticNoteRenderer(SM, LangOpts, DiagOpts),
+    : DiagnosticNoteRenderer(LangOpts, DiagOpts),
       Writer(Writer), Record(Record){}
 
   virtual ~SDiagsRenderer() {}
@@ -67,18 +66,21 @@
                                      DiagnosticsEngine::Level Level,
                                      StringRef Message,
                                      ArrayRef<CharSourceRange> Ranges,
+                                     const SourceManager *SM,
                                      DiagOrStoredDiag D);
   
   virtual void emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
                                  DiagnosticsEngine::Level Level,
-                                 ArrayRef<CharSourceRange> Ranges) {}
+                                 ArrayRef<CharSourceRange> Ranges,
+                                 const SourceManager &SM) {}
   
-  void emitNote(SourceLocation Loc, StringRef Message);
+  void emitNote(SourceLocation Loc, StringRef Message, const SourceManager *SM);
   
   virtual void emitCodeContext(SourceLocation Loc,
                                DiagnosticsEngine::Level Level,
                                SmallVectorImpl<CharSourceRange>& Ranges,
-                               ArrayRef<FixItHint> Hints);
+                               ArrayRef<FixItHint> Hints,
+                               const SourceManager &SM);
   
   virtual void beginDiagnostic(DiagOrStoredDiag D,
                                DiagnosticsEngine::Level Level);
@@ -137,15 +139,16 @@
   unsigned getEmitFile(const char *Filename);
 
   /// \brief Add SourceLocation information the specified record.  
-  void AddLocToRecord(SourceLocation Loc, const SourceManager &SM,
+  void AddLocToRecord(SourceLocation Loc, const SourceManager *SM,
                       PresumedLoc PLoc, RecordDataImpl &Record,
                       unsigned TokSize = 0);
 
   /// \brief Add SourceLocation information the specified record.
   void AddLocToRecord(SourceLocation Loc, RecordDataImpl &Record,
-                      const SourceManager &SM,
+                      const SourceManager *SM,
                       unsigned TokSize = 0) {
-    AddLocToRecord(Loc, SM, SM.getPresumedLoc(Loc), Record, TokSize);
+    AddLocToRecord(Loc, SM, SM ? SM->getPresumedLoc(Loc) : PresumedLoc(),
+                   Record, TokSize);
   }
 
   /// \brief Add CharSourceRange information the specified record.
@@ -241,7 +244,7 @@
 }
 
 void SDiagsWriter::AddLocToRecord(SourceLocation Loc,
-                                  const SourceManager &SM,
+                                  const SourceManager *SM,
                                   PresumedLoc PLoc,
                                   RecordDataImpl &Record,
                                   unsigned TokSize) {
@@ -257,19 +260,19 @@
   Record.push_back(getEmitFile(PLoc.getFilename()));
   Record.push_back(PLoc.getLine());
   Record.push_back(PLoc.getColumn()+TokSize);
-  Record.push_back(SM.getFileOffset(Loc));
+  Record.push_back(SM->getFileOffset(Loc));
 }
 
 void SDiagsWriter::AddCharSourceRangeToRecord(CharSourceRange Range,
                                               RecordDataImpl &Record,
                                               const SourceManager &SM) {
-  AddLocToRecord(Range.getBegin(), Record, SM);
+  AddLocToRecord(Range.getBegin(), Record, &SM);
   unsigned TokSize = 0;
   if (Range.isTokenRange())
     TokSize = Lexer::MeasureTokenLength(Range.getEnd(),
                                         SM, *LangOpts);
   
-  AddLocToRecord(Range.getEnd(), Record, SM, TokSize);
+  AddLocToRecord(Range.getEnd(), Record, &SM, TokSize);
 }
 
 unsigned SDiagsWriter::getEmitFile(const char *FileName){
@@ -484,13 +487,15 @@
   diagBuf.clear();   
   Info.FormatDiagnostic(diagBuf);
 
-  SourceManager &SM = Info.getSourceManager();
-  SDiagsRenderer Renderer(*this, Record, SM, *LangOpts, DiagOpts);
+  const SourceManager *
+    SM = Info.hasSourceManager() ? &Info.getSourceManager() : 0;
+  SDiagsRenderer Renderer(*this, Record, *LangOpts, DiagOpts);
   Renderer.emitDiagnostic(Info.getLocation(), DiagLevel,
                           diagBuf.str(),
                           Info.getRanges(),
                           llvm::makeArrayRef(Info.getFixItHints(),
                                              Info.getNumFixItHints()),
+                          SM,
                           &Info);
 }
 
@@ -500,6 +505,7 @@
                                       DiagnosticsEngine::Level Level,
                                       StringRef Message,
                                       ArrayRef<clang::CharSourceRange> Ranges,
+                                      const SourceManager *SM,
                                       DiagOrStoredDiag D) {
   // Emit the RECORD_DIAG record.
   Writer.Record.clear();
@@ -539,7 +545,8 @@
 void SDiagsRenderer::emitCodeContext(SourceLocation Loc,
                                      DiagnosticsEngine::Level Level,
                                      SmallVectorImpl<CharSourceRange> &Ranges,
-                                     ArrayRef<FixItHint> Hints) {  
+                                     ArrayRef<FixItHint> Hints,
+                                     const SourceManager &SM) {  
   // Emit Source Ranges.
   for (ArrayRef<CharSourceRange>::iterator it=Ranges.begin(), ei=Ranges.end();
        it != ei; ++it) {
@@ -562,7 +569,8 @@
   }
 }
 
-void SDiagsRenderer::emitNote(SourceLocation Loc, StringRef Message) {
+void SDiagsRenderer::emitNote(SourceLocation Loc, StringRef Message,
+                              const SourceManager *SM) {
   Writer.Stream.EnterSubblock(BLOCK_DIAG, 4);
   RecordData Record;
   Record.push_back(RECORD_DIAG);

Modified: cfe/trunk/lib/Frontend/TextDiagnostic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/TextDiagnostic.cpp?rev=156536&r1=156535&r2=156536&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/TextDiagnostic.cpp (original)
+++ cfe/trunk/lib/Frontend/TextDiagnostic.cpp Thu May 10 00:03:45 2012
@@ -602,10 +602,9 @@
 }
 
 TextDiagnostic::TextDiagnostic(raw_ostream &OS,
-                               const SourceManager &SM,
                                const LangOptions &LangOpts,
                                const DiagnosticOptions &DiagOpts)
-  : DiagnosticRenderer(SM, LangOpts, DiagOpts), OS(OS) {}
+  : DiagnosticRenderer(LangOpts, DiagOpts), OS(OS) {}
 
 TextDiagnostic::~TextDiagnostic() {}
 
@@ -615,11 +614,13 @@
                                       DiagnosticsEngine::Level Level,
                                       StringRef Message,
                                       ArrayRef<clang::CharSourceRange> Ranges,
+                                      const SourceManager *SM,
                                       DiagOrStoredDiag D) {
   uint64_t StartOfLocationInfo = OS.tell();
 
   // Emit the location of this particular diagnostic.
-  emitDiagnosticLoc(Loc, PLoc, Level, Ranges);
+  if (Loc.isValid())
+    emitDiagnosticLoc(Loc, PLoc, Level, Ranges, *SM);
   
   if (DiagOpts.ShowColors)
     OS.resetColor();
@@ -693,7 +694,8 @@
 /// ranges necessary.
 void TextDiagnostic::emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
                                        DiagnosticsEngine::Level Level,
-                                       ArrayRef<CharSourceRange> Ranges) {
+                                       ArrayRef<CharSourceRange> Ranges,
+                                       const SourceManager &SM) {
   if (PLoc.isInvalid()) {
     // At least print the file name if available:
     FileID FID = SM.getFileID(Loc);
@@ -799,7 +801,8 @@
 }
 
 void TextDiagnostic::emitIncludeLocation(SourceLocation Loc,
-                                         PresumedLoc PLoc) {
+                                         PresumedLoc PLoc,
+                                         const SourceManager &SM) {
   if (DiagOpts.ShowLocation)
     OS << "In file included from " << PLoc.getFilename() << ':'
        << PLoc.getLine() << ":\n";
@@ -817,7 +820,8 @@
 void TextDiagnostic::emitSnippetAndCaret(
     SourceLocation Loc, DiagnosticsEngine::Level Level,
     SmallVectorImpl<CharSourceRange>& Ranges,
-    ArrayRef<FixItHint> Hints) {
+    ArrayRef<FixItHint> Hints,
+    const SourceManager &SM) {
   assert(!Loc.isInvalid() && "must have a valid source location here");
   assert(Loc.isFileID() && "must have a file location here");
 
@@ -878,7 +882,7 @@
   for (SmallVectorImpl<CharSourceRange>::iterator I = Ranges.begin(),
                                                   E = Ranges.end();
        I != E; ++I)
-    highlightRange(*I, LineNo, FID, sourceColMap, CaretLine);
+    highlightRange(*I, LineNo, FID, sourceColMap, CaretLine, SM);
 
   // Next, insert the caret itself.
   ColNo = sourceColMap.byteToColumn(ColNo-1);
@@ -888,7 +892,7 @@
 
   std::string FixItInsertionLine = buildFixItInsertionLine(LineNo,
                                                            sourceColMap,
-                                                           Hints);
+                                                           Hints, SM);
 
   // If the source line is too long for our terminal, select only the
   // "interesting" source region within that line.
@@ -931,7 +935,7 @@
   }
 
   // Print out any parseable fixit information requested by the options.
-  emitParseableFixits(Hints);
+  emitParseableFixits(Hints, SM);
 }
 
 void TextDiagnostic::emitSnippet(StringRef line) {
@@ -974,7 +978,8 @@
 void TextDiagnostic::highlightRange(const CharSourceRange &R,
                                     unsigned LineNo, FileID FID,
                                     const SourceColumnMap &map,
-                                    std::string &CaretLine) {
+                                    std::string &CaretLine,
+                                    const SourceManager &SM) {
   if (!R.isValid()) return;
 
   SourceLocation Begin = SM.getExpansionLoc(R.getBegin());
@@ -1059,7 +1064,8 @@
 std::string TextDiagnostic::buildFixItInsertionLine(
   unsigned LineNo,
   const SourceColumnMap &map,
-  ArrayRef<FixItHint> Hints) {
+  ArrayRef<FixItHint> Hints,
+  const SourceManager &SM) {
 
   std::string FixItInsertionLine;
   if (Hints.empty() || !DiagOpts.ShowFixits)
@@ -1114,7 +1120,8 @@
   return FixItInsertionLine;
 }
 
-void TextDiagnostic::emitParseableFixits(ArrayRef<FixItHint> Hints) {
+void TextDiagnostic::emitParseableFixits(ArrayRef<FixItHint> Hints,
+                                         const SourceManager &SM) {
   if (!DiagOpts.ShowParseableFixits)
     return;
 

Modified: cfe/trunk/lib/Frontend/TextDiagnosticPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/TextDiagnosticPrinter.cpp?rev=156536&r1=156535&r2=156536&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/TextDiagnosticPrinter.cpp (original)
+++ cfe/trunk/lib/Frontend/TextDiagnosticPrinter.cpp Thu May 10 00:03:45 2012
@@ -27,7 +27,7 @@
 TextDiagnosticPrinter::TextDiagnosticPrinter(raw_ostream &os,
                                              const DiagnosticOptions &diags,
                                              bool _OwnsOutputStream)
-  : OS(os), LangOpts(0), DiagOpts(&diags), SM(0),
+  : OS(os), DiagOpts(&diags),
     OwnsOutputStream(_OwnsOutputStream) {
 }
 
@@ -38,11 +38,11 @@
 
 void TextDiagnosticPrinter::BeginSourceFile(const LangOptions &LO,
                                             const Preprocessor *PP) {
-  LangOpts = &LO;
+  // Build the TextDiagnostic utility.
+  TextDiag.reset(new TextDiagnostic(OS, LO, *DiagOpts));
 }
 
 void TextDiagnosticPrinter::EndSourceFile() {
-  LangOpts = 0;
   TextDiag.reset(0);
 }
 
@@ -152,22 +152,16 @@
   }
 
   // Assert that the rest of our infrastructure is setup properly.
-  assert(LangOpts && "Unexpected diagnostic outside source file processing");
   assert(DiagOpts && "Unexpected diagnostic without options set");
   assert(Info.hasSourceManager() &&
          "Unexpected diagnostic with no source manager");
-
-  // Rebuild the TextDiagnostic utility if missing or the source manager has
-  // changed.
-  if (!TextDiag || SM != &Info.getSourceManager()) {
-    SM = &Info.getSourceManager();
-    TextDiag.reset(new TextDiagnostic(OS, *SM, *LangOpts, *DiagOpts));
-  }
+  assert(TextDiag && "Unexpected diagnostic outside source file processing");
 
   TextDiag->emitDiagnostic(Info.getLocation(), Level, DiagMessageStream.str(),
                            Info.getRanges(),
                            llvm::makeArrayRef(Info.getFixItHints(),
-                                              Info.getNumFixItHints()));
+                                              Info.getNumFixItHints()),
+                           &Info.getSourceManager());
 
   OS.flush();
 }

Added: cfe/trunk/test/Misc/serialized-diags-frontend.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Misc/serialized-diags-frontend.c?rev=156536&view=auto
==============================================================================
--- cfe/trunk/test/Misc/serialized-diags-frontend.c (added)
+++ cfe/trunk/test/Misc/serialized-diags-frontend.c Thu May 10 00:03:45 2012
@@ -0,0 +1,8 @@
+// RUN: rm -f %t
+// RUN: %clang -fsyntax-only %s -Wblahblah --serialize-diagnostics %t > /dev/null 2>&1 || true
+// RUN: c-index-test -read-diagnostics %t 2>&1 | FileCheck %s
+
+// This test case tests that we can handle frontend diagnostics.
+
+// CHECK: warning: unknown warning option '-Wblahblah'
+// CHECK: Number of diagnostics: 1

Modified: cfe/trunk/tools/libclang/CIndexDiagnostic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndexDiagnostic.cpp?rev=156536&r1=156535&r2=156536&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndexDiagnostic.cpp (original)
+++ cfe/trunk/tools/libclang/CIndexDiagnostic.cpp Thu May 10 00:03:45 2012
@@ -86,11 +86,10 @@
     
 class CXDiagnosticRenderer : public DiagnosticNoteRenderer {
 public:  
-  CXDiagnosticRenderer(const SourceManager &SM,
-                       const LangOptions &LangOpts,
+  CXDiagnosticRenderer(const LangOptions &LangOpts,
                        const DiagnosticOptions &DiagOpts,
                        CXDiagnosticSetImpl *mainSet)
-  : DiagnosticNoteRenderer(SM, LangOpts, DiagOpts),
+  : DiagnosticNoteRenderer(LangOpts, DiagOpts),
     CurrentSet(mainSet), MainSet(mainSet) {}
   
   virtual ~CXDiagnosticRenderer() {}
@@ -116,26 +115,38 @@
                                      DiagnosticsEngine::Level Level,
                                      StringRef Message,
                                      ArrayRef<CharSourceRange> Ranges,
+                                     const SourceManager *SM,
                                      DiagOrStoredDiag D) {
     if (!D.isNull())
       return;
     
-    CXSourceLocation L = translateSourceLocation(SM, LangOpts, Loc);
+    CXSourceLocation L;
+    if (SM)
+      L = translateSourceLocation(*SM, LangOpts, Loc);
+    else
+      L = clang_getNullLocation();
     CXDiagnosticImpl *CD = new CXDiagnosticCustomNoteImpl(Message, L);
     CurrentSet->appendDiagnostic(CD);
   }
   
   virtual void emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
                                  DiagnosticsEngine::Level Level,
-                                 ArrayRef<CharSourceRange> Ranges) {}
+                                 ArrayRef<CharSourceRange> Ranges,
+                                 const SourceManager &SM) {}
 
   virtual void emitCodeContext(SourceLocation Loc,
                                DiagnosticsEngine::Level Level,
                                SmallVectorImpl<CharSourceRange>& Ranges,
-                               ArrayRef<FixItHint> Hints) {}
+                               ArrayRef<FixItHint> Hints,
+                               const SourceManager &SM) {}
   
-  virtual void emitNote(SourceLocation Loc, StringRef Message) {
-    CXSourceLocation L = translateSourceLocation(SM, LangOpts, Loc);
+  virtual void emitNote(SourceLocation Loc, StringRef Message,
+                        const SourceManager *SM) {
+    CXSourceLocation L;
+    if (SM)
+      L = translateSourceLocation(*SM, LangOpts, Loc);
+    else
+      L = clang_getNullLocation();
     CurrentSet->appendDiagnostic(new CXDiagnosticCustomNoteImpl(Message,
                                                                 L));
   }
@@ -181,8 +192,7 @@
     CXDiagnosticSetImpl *Set = new CXDiagnosticSetImpl();
     TU->Diagnostics = Set;
     DiagnosticOptions DOpts;
-    CXDiagnosticRenderer Renderer(AU->getSourceManager(),
-                                  AU->getASTContext().getLangOpts(),
+    CXDiagnosticRenderer Renderer(AU->getASTContext().getLangOpts(),
                                   DOpts, Set);
     
     for (ASTUnit::stored_diag_iterator it = AU->stored_diag_begin(),





More information about the cfe-commits mailing list