[cfe-commits] r59502 - in /cfe/trunk: Driver/ include/clang/Analysis/ include/clang/Analysis/PathSensitive/ include/clang/Basic/ include/clang/Driver/ lib/Analysis/ lib/Basic/ lib/CodeGen/ lib/Driver/ lib/Lex/ lib/Parse/ lib/Sema/

Chris Lattner sabre at nondot.org
Mon Nov 17 23:04:44 PST 2008


Author: lattner
Date: Tue Nov 18 01:04:44 2008
New Revision: 59502

URL: http://llvm.org/viewvc/llvm-project?rev=59502&view=rev
Log:
This reworks some of the Diagnostic interfaces a bit to change how diagnostics
are formed.  In particular, a diagnostic with all its strings and ranges is now
packaged up and sent to DiagnosticClients as a DiagnosticInfo instead of as a 
ton of random stuff.  This has the benefit of simplifying the interface, making
it more extensible, and allowing us to do more checking for things like access
past the end of the various arrays passed in.

In addition to introducing DiagnosticInfo, this also substantially changes how 
Diagnostic::Report works.  Instead of being passed in all of the info required
to issue a diagnostic, Report now takes only the required info (a location and 
ID) and returns a fresh DiagnosticInfo *by value*.  The caller is then free to
stuff strings and ranges into the DiagnosticInfo with the << operator.  When
the dtor runs on the DiagnosticInfo object (which should happen at the end of
the statement), the diagnostic is actually emitted with all of the accumulated
information.  This is a somewhat tricky dance, but it means that the 
accumulated DiagnosticInfo is allowed to keep pointers to other expression 
temporaries without those pointers getting invalidated.

This is just the minimal change to get this stuff working, but this will allow
us to eliminate the zillions of variant "Diag" methods scattered throughout
(e.g.) sema.  For example, instead of calling:

  Diag(BuiltinLoc, diag::err_overload_no_match, typeNames,
       SourceRange(BuiltinLoc, RParenLoc));

We will soon be able to just do:

  Diag(BuiltinLoc, diag::err_overload_no_match)
      << typeNames << SourceRange(BuiltinLoc, RParenLoc));

This scales better to support arbitrary types being passed in (not just 
strings) in a type-safe way.  Go operator overloading?!


Modified:
    cfe/trunk/Driver/RewriteObjC.cpp
    cfe/trunk/include/clang/Analysis/PathDiagnostic.h
    cfe/trunk/include/clang/Analysis/PathSensitive/BugReporter.h
    cfe/trunk/include/clang/Basic/Diagnostic.h
    cfe/trunk/include/clang/Driver/TextDiagnosticBuffer.h
    cfe/trunk/include/clang/Driver/TextDiagnosticPrinter.h
    cfe/trunk/lib/Analysis/BugReporter.cpp
    cfe/trunk/lib/Analysis/PathDiagnostic.cpp
    cfe/trunk/lib/Basic/Diagnostic.cpp
    cfe/trunk/lib/CodeGen/CGObjC.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.cpp
    cfe/trunk/lib/Driver/TextDiagnosticBuffer.cpp
    cfe/trunk/lib/Driver/TextDiagnosticPrinter.cpp
    cfe/trunk/lib/Lex/Preprocessor.cpp
    cfe/trunk/lib/Parse/DeclSpec.cpp
    cfe/trunk/lib/Parse/Parser.cpp
    cfe/trunk/lib/Sema/Sema.cpp

Modified: cfe/trunk/Driver/RewriteObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/RewriteObjC.cpp?rev=59502&r1=59501&r2=59502&view=diff

==============================================================================
--- cfe/trunk/Driver/RewriteObjC.cpp (original)
+++ cfe/trunk/Driver/RewriteObjC.cpp Tue Nov 18 01:04:44 2008
@@ -132,9 +132,8 @@
       if (!Rewrite.ReplaceStmt(Old, New) || SilenceRewriteMacroWarning)
         return;
 
-      SourceRange Range = Old->getSourceRange();
-      Diags.Report(Context->getFullLoc(Old->getLocStart()), RewriteFailedDiag,
-                   0, 0, &Range, 1);
+      Diags.Report(Context->getFullLoc(Old->getLocStart()), RewriteFailedDiag)
+                   << Old->getSourceRange();
     }
     
     void InsertText(SourceLocation Loc, const char *StrData, unsigned StrLen,

Modified: cfe/trunk/include/clang/Analysis/PathDiagnostic.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathDiagnostic.h?rev=59502&r1=59501&r2=59502&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathDiagnostic.h (original)
+++ cfe/trunk/include/clang/Analysis/PathDiagnostic.h Tue Nov 18 01:04:44 2008
@@ -197,14 +197,8 @@
   PathDiagnosticClient() {}
   virtual ~PathDiagnosticClient() {}
     
-  virtual void HandleDiagnostic(Diagnostic &Diags, 
-                                Diagnostic::Level DiagLevel,
-                                FullSourceLoc Pos,
-                                diag::kind ID,
-                                const std::string **Strs,
-                                unsigned NumStrs,
-                                const SourceRange *Ranges, 
-                                unsigned NumRanges);
+  virtual void HandleDiagnostic(Diagnostic::Level DiagLevel,
+                                const DiagnosticInfo &Info);
     
   virtual void HandlePathDiagnostic(const PathDiagnostic* D) = 0;
 };

Modified: cfe/trunk/include/clang/Analysis/PathSensitive/BugReporter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/BugReporter.h?rev=59502&r1=59501&r2=59502&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/BugReporter.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/BugReporter.h Tue Nov 18 01:04:44 2008
@@ -303,26 +303,20 @@
   
   virtual ~DiagCollector() {}
   
-  virtual void HandleDiagnostic(Diagnostic &Diags, 
-                                Diagnostic::Level DiagLevel,
-                                FullSourceLoc Pos,
-                                diag::kind ID,
-                                const std::string **Strs,
-                                unsigned NumStrs,
-                                const SourceRange *Ranges, 
-                                unsigned NumRanges) {
+  virtual void HandleDiagnostic(Diagnostic::Level DiagLevel,
+                                const DiagnosticInfo &Info) {
     
     // FIXME: Use a map from diag::kind to BugType, instead of having just
     //  one BugType.
-    
-    Reports.push_back(DiagBugReport(Diags.getDescription(ID), D, Pos));
+    const char *Desc = Info.getDiags()->getDescription(Info.getID());
+    Reports.push_back(DiagBugReport(Desc, D, Info.getLocation()));
     DiagBugReport& R = Reports.back();
     
-    for ( ; NumRanges ; --NumRanges, ++Ranges)
-      R.addRange(*Ranges);
+    for (unsigned i = 0, e = Info.getNumRanges(); i != e; ++i)
+      R.addRange(Info.getRange(i));
     
-    for ( ; NumStrs ; --NumStrs, ++Strs)
-      R.addString(**Strs);    
+    for (unsigned i = 0, e = Info.getNumArgs(); i != e; ++i)
+      R.addString(Info.getArgStr(i));
   }
   
   // Iterators.

Modified: cfe/trunk/include/clang/Basic/Diagnostic.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Diagnostic.h?rev=59502&r1=59501&r2=59502&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/Diagnostic.h (original)
+++ cfe/trunk/include/clang/Basic/Diagnostic.h Tue Nov 18 01:04:44 2008
@@ -22,6 +22,7 @@
   class DiagnosticClient;
   class SourceRange;
   class SourceManager;
+  class DiagnosticInfo;
   
   // Import the diagnostic enums themselves.
   namespace diag {
@@ -150,7 +151,7 @@
 
   /// getDescription - Given a diagnostic ID, return a description of the
   /// issue.
-  const char *getDescription(unsigned DiagID);
+  const char *getDescription(unsigned DiagID) const;
   
   /// isBuiltinNoteWarningOrExtension - Return true if the unmapped diagnostic
   /// level of the specified diagnostic ID is a Note, Warning, or Extension.
@@ -162,41 +163,146 @@
   /// the DiagnosticClient.
   Level getDiagnosticLevel(unsigned DiagID) const;
   
+  
   /// Report - Issue the message to the client.  DiagID is a member of the
-  /// diag::kind enum.  
-  void Report(FullSourceLoc Pos, unsigned DiagID,
-              const std::string **Strs = 0, unsigned NumStrs = 0,
-              const SourceRange *Ranges = 0, unsigned NumRanges = 0) {
-    Report(NULL, Pos, DiagID, Strs, NumStrs, Ranges, NumRanges);
-  }                                                                      
-  
-  /// Report - Issue the message to the specified client. 
-  ///  DiagID is a member of the diag::kind enum.
-  void Report(DiagnosticClient* C, FullSourceLoc Pos, unsigned DiagID,
-              const std::string **Strs = 0, unsigned NumStrs = 0,
-              const SourceRange *Ranges = 0, unsigned NumRanges = 0);
+  /// diag::kind enum.  This actually returns a new instance of DiagnosticInfo
+  /// which emits the diagnostics (through ProcessDiag) when it is destroyed.
+  inline DiagnosticInfo Report(FullSourceLoc Pos, unsigned DiagID);
+  
+private:
+  // This is private state used by DiagnosticInfo.  We put it here instead of
+  // in DiagnosticInfo in order to keep DiagnosticInfo a small light-weight
+  // object.  This implementation choice means that we can only have one
+  // diagnostic "in flight" at a time, but this seems to be a reasonable
+  // tradeoff to keep these objects small.  Assertions verify that only one
+  // diagnostic is in flight at a time.
+  friend class DiagnosticInfo;
+  
+  /// DiagArguments - The values for the various substitution positions.  It
+  /// currently only support 10 arguments (%0-%9).
+  const std::string *DiagArguments[10];
+  /// DiagRanges - The list of ranges added to this diagnostic.  It currently
+  /// only support 10 ranges, could easily be extended if needed.
+  const SourceRange *DiagRanges[10];
+  
+  /// NumDiagArgs - This is set to -1 when no diag is in flight.  Otherwise it
+  /// is the number of entries in Arguments.
+  signed char NumDiagArgs;
+  /// NumRanges - This is the number of ranges in the DiagRanges array.
+  unsigned char NumDiagRanges;
+  
+  /// ProcessDiag - This is the method used to report a diagnostic that is
+  /// finally fully formed.
+  void ProcessDiag(const DiagnosticInfo &Info);
+};
+  
+/// DiagnosticInfo - This is a little helper class used to produce diagnostics.
+/// This is constructed with an ID and location, and then has some number of
+/// arguments (for %0 substitution) and SourceRanges added to it with the
+/// overloaded operator<<.  Once it is destroyed, it emits the diagnostic with
+/// the accumulated information.
+///
+/// Note that many of these will be created as temporary objects (many call
+/// sites), so we want them to be small to reduce stack space usage etc.  For
+/// this reason, we stick state in the Diagnostic class, see the comment there
+/// for more info.
+class DiagnosticInfo {
+  Diagnostic *DiagObj;
+  FullSourceLoc Loc;
+  unsigned DiagID;
+  void operator=(const DiagnosticInfo&); // DO NOT IMPLEMENT
+public:
+  DiagnosticInfo(Diagnostic *diagObj, FullSourceLoc loc, unsigned diagID) :
+    DiagObj(diagObj), Loc(loc), DiagID(diagID) {
+    assert(DiagObj->NumDiagArgs == -1 &&
+           "Multiple diagnostics in flight at once!");
+    DiagObj->NumDiagArgs = DiagObj->NumDiagRanges = 0;
+  }
+  
+  /// Copy constructor.  When copied, this "takes" the diagnostic info from the
+  /// input and neuters it.
+  DiagnosticInfo(DiagnosticInfo &D) {
+    DiagObj = D.DiagObj;
+    Loc = D.Loc;
+    DiagID = D.DiagID;
+    D.DiagObj = 0;
+  }
+  
+  /// Destructor - The dtor emits the diagnostic.
+  ~DiagnosticInfo() {
+    // If DiagObj is null, then its soul was stolen by the copy ctor.
+    if (!DiagObj) return;
+    
+    DiagObj->ProcessDiag(*this);
+
+    // This diagnostic is no longer in flight.
+    DiagObj->NumDiagArgs = -1;
+  }
+  
+  const Diagnostic *getDiags() const { return DiagObj; }
+  unsigned getID() const { return DiagID; }
+  const FullSourceLoc &getLocation() const { return Loc; }
+
+  unsigned getNumArgs() const { return DiagObj->NumDiagArgs; }
+  
+  /// getArgStr - Return the provided argument string specified by Idx.
+  const std::string &getArgStr(unsigned Idx) const {
+    assert((signed char)Idx < DiagObj->NumDiagArgs &&
+           "Argument out of range!");
+    return *DiagObj->DiagArguments[Idx];
+  }
+  
+  /// getNumRanges - Return the number of source ranges associated with this
+  /// diagnostic.
+  unsigned getNumRanges() const {
+    return DiagObj->NumDiagRanges;
+  }
+  
+  const SourceRange &getRange(unsigned Idx) const {
+    assert(Idx < DiagObj->NumDiagRanges && "Invalid diagnostic range index!");
+    return *DiagObj->DiagRanges[Idx];
+  }
+
+  DiagnosticInfo &operator<<(const std::string &S) {
+    assert((unsigned)DiagObj->NumDiagArgs < 
+           sizeof(DiagObj->DiagArguments)/sizeof(DiagObj->DiagArguments[0]) &&
+           "Too many arguments to diagnostic!");
+    DiagObj->DiagArguments[DiagObj->NumDiagArgs++] = &S;
+    return *this;
+  }
+  
+  DiagnosticInfo &operator<<(const SourceRange &R) {
+    assert((unsigned)DiagObj->NumDiagArgs < 
+           sizeof(DiagObj->DiagRanges)/sizeof(DiagObj->DiagRanges[0]) &&
+           "Too many arguments to diagnostic!");
+    DiagObj->DiagRanges[DiagObj->NumDiagRanges++] = &R;
+    return *this;
+  }
+  
 };
 
+
+/// Report - Issue the message to the client.  DiagID is a member of the
+/// diag::kind enum.  This actually returns a new instance of DiagnosticInfo
+/// which emits the diagnostics (through ProcessDiag) when it is destroyed.
+inline DiagnosticInfo Diagnostic::Report(FullSourceLoc Pos, unsigned DiagID) {
+  DiagnosticInfo D(this, Pos, DiagID);
+  return D;
+}
+  
+
 /// DiagnosticClient - This is an abstract interface implemented by clients of
 /// the front-end, which formats and prints fully processed diagnostics.
 class DiagnosticClient {
 protected:
-  std::string FormatDiagnostic(Diagnostic &Diags, Diagnostic::Level Level,
-                               diag::kind ID,
-                               const std::string **Strs, unsigned NumStrs);
+  std::string FormatDiagnostic(const DiagnosticInfo &Info);
 public:
   virtual ~DiagnosticClient();
 
   /// HandleDiagnostic - Handle this diagnostic, reporting it to the user or
   /// capturing it to a log as needed.
-  virtual void HandleDiagnostic(Diagnostic &Diags, 
-                                Diagnostic::Level DiagLevel,
-                                FullSourceLoc Pos,
-                                diag::kind ID,
-                                const std::string **Strs,
-                                unsigned NumStrs,
-                                const SourceRange *Ranges, 
-                                unsigned NumRanges) = 0;
+  virtual void HandleDiagnostic(Diagnostic::Level DiagLevel,
+                                const DiagnosticInfo &Info) = 0;
 };
 
 }  // end namespace clang

Modified: cfe/trunk/include/clang/Driver/TextDiagnosticBuffer.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/TextDiagnosticBuffer.h?rev=59502&r1=59501&r2=59502&view=diff

==============================================================================
--- cfe/trunk/include/clang/Driver/TextDiagnosticBuffer.h (original)
+++ cfe/trunk/include/clang/Driver/TextDiagnosticBuffer.h Tue Nov 18 01:04:44 2008
@@ -39,14 +39,8 @@
   const_iterator note_begin() const { return Notes.begin(); }
   const_iterator note_end() const   { return Notes.end(); }
 
-  virtual void HandleDiagnostic(Diagnostic &Diags,
-                                Diagnostic::Level DiagLevel,
-                                FullSourceLoc Pos,
-                                diag::kind ID,
-                                const std::string **Strs,
-                                unsigned NumStrs,
-                                const SourceRange *Ranges, 
-                                unsigned NumRanges);
+  virtual void HandleDiagnostic(Diagnostic::Level DiagLevel,
+                                const DiagnosticInfo &Info);
 };
 
 } // end namspace clang

Modified: cfe/trunk/include/clang/Driver/TextDiagnosticPrinter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/TextDiagnosticPrinter.h?rev=59502&r1=59501&r2=59502&view=diff

==============================================================================
--- cfe/trunk/include/clang/Driver/TextDiagnosticPrinter.h (original)
+++ cfe/trunk/include/clang/Driver/TextDiagnosticPrinter.h Tue Nov 18 01:04:44 2008
@@ -36,19 +36,13 @@
   void PrintIncludeStack(FullSourceLoc Pos);
 
   void HighlightRange(const SourceRange &R,
-                      SourceManager& SrcMgr,
+                      const SourceManager& SrcMgr,
                       unsigned LineNo, unsigned FileID,
                       std::string &CaretLine,
                       const std::string &SourceLine);
 
-  virtual void HandleDiagnostic(Diagnostic &Diags,
-                                Diagnostic::Level DiagLevel,
-                                FullSourceLoc Pos,
-                                diag::kind ID,
-                                const std::string **Strs,
-                                unsigned NumStrs,
-                                const SourceRange *Ranges, 
-                                unsigned NumRanges);
+  virtual void HandleDiagnostic(Diagnostic::Level DiagLevel,
+                                const DiagnosticInfo &Info);
 };
 
 } // end namspace clang

Modified: cfe/trunk/lib/Analysis/BugReporter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/BugReporter.cpp?rev=59502&r1=59501&r2=59502&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/BugReporter.cpp (original)
+++ cfe/trunk/lib/Analysis/BugReporter.cpp Tue Nov 18 01:04:44 2008
@@ -773,21 +773,26 @@
 
     D->push_back(piece);
     PD->HandlePathDiagnostic(D.take());
+    return;
   }
   else {
-    std::ostringstream os;
+    std::string str;
 
     if (D->empty())
-      os << R.getDescription();
+      str = R.getDescription();
     else
-      os << D->back()->getString();
-
+      str = D->back()->getString();
 
     Diagnostic& Diag = getDiagnostic();
-    unsigned ErrorDiag = Diag.getCustomDiagID(Diagnostic::Warning,
-                                              os.str().c_str());
+    unsigned ErrorDiag = Diag.getCustomDiagID(Diagnostic::Warning, str.c_str());
 
-    Diag.Report(L, ErrorDiag, NULL, 0, Beg, End - Beg);
+    switch (End-Beg) {
+    default: assert(0 && "Don't handle this many ranges yet!");
+    case 0: Diag.Report(L, ErrorDiag); break;
+    case 1: Diag.Report(L, ErrorDiag) << Beg[0]; break;
+    case 2: Diag.Report(L, ErrorDiag) << Beg[0] << Beg[1]; break;
+    case 3: Diag.Report(L, ErrorDiag) << Beg[0] << Beg[1] << Beg[2]; break;
+    }
   }
 }
 
@@ -807,9 +812,17 @@
   
   DiagnosticClient *OldClient = Diag.getClient();
   Diag.setClient(&C);
-  Diag.Report(getContext().getFullLoc(Loc),
-              Diag.getCustomDiagID(Diagnostic::Warning, str),
-              0, 0, RBeg, NumRanges);
+  FullSourceLoc L = getContext().getFullLoc(Loc);
+  unsigned DiagID = Diag.getCustomDiagID(Diagnostic::Warning, str);
+  
+  switch (NumRanges) {
+  default: assert(0 && "Don't handle this many ranges yet!");
+  case 0: Diag.Report(L, DiagID); break;
+  case 1: Diag.Report(L, DiagID) << RBeg[0]; break;
+  case 2: Diag.Report(L, DiagID) << RBeg[0] << RBeg[1]; break;
+  case 3: Diag.Report(L, DiagID) << RBeg[0] << RBeg[1] << RBeg[2]; break;
+  }
+  
   Diag.setClient(OldClient);
   
   for (DiagCollector::iterator I = C.begin(), E = C.end(); I != E; ++I)

Modified: cfe/trunk/lib/Analysis/PathDiagnostic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/PathDiagnostic.cpp?rev=59502&r1=59501&r2=59502&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/PathDiagnostic.cpp (original)
+++ cfe/trunk/lib/Analysis/PathDiagnostic.cpp Tue Nov 18 01:04:44 2008
@@ -20,14 +20,8 @@
   for (iterator I = begin(), E = end(); I != E; ++I) delete &*I;
 }
 
-void PathDiagnosticClient::HandleDiagnostic(Diagnostic &Diags, 
-                                            Diagnostic::Level DiagLevel,
-                                            FullSourceLoc Pos,
-                                            diag::kind ID,
-                                            const std::string **Strs,
-                                            unsigned NumStrs,
-                                            const SourceRange *Ranges, 
-                                            unsigned NumRanges) {
+void PathDiagnosticClient::HandleDiagnostic(Diagnostic::Level DiagLevel,
+                                            const DiagnosticInfo &Info) {
   
   // Create a PathDiagnostic with a single piece.
   
@@ -42,16 +36,13 @@
   case Diagnostic::Fatal:   LevelStr = "fatal error: "; break;
   }
 
-  std::string Msg = FormatDiagnostic(Diags, DiagLevel, ID, Strs, NumStrs);
+  std::string Msg = FormatDiagnostic(Info);
   
-  PathDiagnosticPiece* P = new PathDiagnosticPiece(Pos, LevelStr+Msg);
-  
-  while (NumRanges) {
-    P->addRange(*Ranges);
-    --NumRanges;
-    ++Ranges;
-  }
+  PathDiagnosticPiece *P =
+    new PathDiagnosticPiece(Info.getLocation(), LevelStr+Msg);
   
+  for (unsigned i = 0, e = Info.getNumRanges(); i != e; ++i)
+    P->addRange(Info.getRange(i));
   D->push_front(P);
 
   HandlePathDiagnostic(D);  

Modified: cfe/trunk/lib/Basic/Diagnostic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Diagnostic.cpp?rev=59502&r1=59501&r2=59502&view=diff

==============================================================================
--- cfe/trunk/lib/Basic/Diagnostic.cpp (original)
+++ cfe/trunk/lib/Basic/Diagnostic.cpp Tue Nov 18 01:04:44 2008
@@ -127,6 +127,7 @@
   NumDiagnostics = 0;
   NumErrors = 0;
   CustomDiagInfo = 0;
+  NumDiagArgs = -1;
 }
 
 Diagnostic::~Diagnostic() {
@@ -154,7 +155,7 @@
 
 /// getDescription - Given a diagnostic ID, return a description of the
 /// issue.
-const char *Diagnostic::getDescription(unsigned DiagID) {
+const char *Diagnostic::getDescription(unsigned DiagID) const {
   if (DiagID < diag::NUM_BUILTIN_DIAGNOSTICS)
     return DiagnosticText[DiagID];
   else 
@@ -210,66 +211,51 @@
   }
 }
 
-/// Report - Issue the message to the client.
-///  DiagID is a member of the diag::kind enum.  
-void Diagnostic::Report(DiagnosticClient* C,
-                        FullSourceLoc Loc, unsigned DiagID,
-                        const std::string **Strs, unsigned NumStrs,
-                        const SourceRange *Ranges, unsigned NumRanges) {
-  
+/// ProcessDiag - This is the method used to report a diagnostic that is
+/// finally fully formed.
+void Diagnostic::ProcessDiag(const DiagnosticInfo &Info) {
   // Figure out the diagnostic level of this message.
-  Diagnostic::Level DiagLevel = getDiagnosticLevel(DiagID);
+  Diagnostic::Level DiagLevel = getDiagnosticLevel(Info.getID());
   
   // If the client doesn't care about this message, don't issue it.
   if (DiagLevel == Diagnostic::Ignored)
     return;
 
-  // Set the diagnostic client if it isn't set already.
-  if (!C) C = Client;
-
   // If this is not an error and we are in a system header, ignore it.  We
-  // have to check on the original DiagID here, because we also want to
+  // have to check on the original Diag ID here, because we also want to
   // ignore extensions and warnings in -Werror and -pedantic-errors modes,
   // which *map* warnings/extensions to errors.
   if (SuppressSystemWarnings &&
-      DiagID < diag::NUM_BUILTIN_DIAGNOSTICS &&
-      getBuiltinDiagClass(DiagID) != ERROR &&
-      Loc.isValid() && Loc.getPhysicalLoc().isInSystemHeader())
+      Info.getID() < diag::NUM_BUILTIN_DIAGNOSTICS &&
+      getBuiltinDiagClass(Info.getID()) != ERROR &&
+      Info.getLocation().isValid() &&
+      Info.getLocation().getPhysicalLoc().isInSystemHeader())
     return;
   
   if (DiagLevel >= Diagnostic::Error) {
     ErrorOccurred = true;
 
-    if (C != 0 && C == Client)
-      ++NumErrors;
+    ++NumErrors;
   }
 
   // Finally, report it.
- 
-  if (C != 0)
-    C->HandleDiagnostic(*this, DiagLevel, Loc, (diag::kind)DiagID,
-                        Strs, NumStrs, Ranges, NumRanges);
-
-  if (C != 0 && C == Client)
-    ++NumDiagnostics;
+  Client->HandleDiagnostic(DiagLevel, Info);
+  ++NumDiagnostics;
 }
 
 
 DiagnosticClient::~DiagnosticClient() {}
 
-std::string DiagnosticClient::FormatDiagnostic(Diagnostic &Diags,
-                                               Diagnostic::Level Level,
-                                               diag::kind ID,
-                                               const std::string **Strs,
-                                               unsigned NumStrs) {
-  std::string Msg = Diags.getDescription(ID);
+std::string DiagnosticClient::FormatDiagnostic(const DiagnosticInfo &Info) {
+  std::string Msg = Info.getDiags()->getDescription(Info.getID());
   
-  // Replace all instances of %0 in Msg with 'Extra'.
+  // Replace all instances of %0 in Msg with 'Extra'.  This is a pretty horrible
+  // and inefficient way to do this, we could improve this a lot if we care.
   for (unsigned i = 0; i < Msg.size() - 1; ++i) {
     if (Msg[i] == '%' && isdigit(Msg[i + 1])) {
       unsigned StrNo = Msg[i + 1] - '0';
       Msg = std::string(Msg.begin(), Msg.begin() + i) +
-            (StrNo < NumStrs ? *Strs[StrNo] : "<<<INTERNAL ERROR>>>") +
+            Info.getArgStr(StrNo) +
             std::string(Msg.begin() + i + 2, Msg.end());
     }
   }

Modified: cfe/trunk/lib/CodeGen/CGObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjC.cpp?rev=59502&r1=59501&r2=59502&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjC.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjC.cpp Tue Nov 18 01:04:44 2008
@@ -303,10 +303,9 @@
       S = Setter->getSelector();
     } else {
       // FIXME: This should be diagnosed by sema.
-      SourceRange Range = E->getSourceRange();
       CGM.getDiags().Report(getContext().getFullLoc(E->getLocStart()),
-                            diag::err_typecheck_assign_const, 0, 0,
-                            &Range, 1);
+                            diag::err_typecheck_assign_const)
+        << E->getSourceRange();
       return;
     }
   } else {

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=59502&r1=59501&r2=59502&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Tue Nov 18 01:04:44 2008
@@ -106,11 +106,9 @@
     return;
   unsigned DiagID = getDiags().getCustomDiagID(Diagnostic::Error, 
                                                "cannot codegen this %0 yet");
-  SourceRange Range = S->getSourceRange();
   std::string Msg = Type;
-  const std::string *Strs[] = { &Msg };
-  getDiags().Report(Context.getFullLoc(S->getLocStart()), DiagID,
-                    Strs, 1, &Range, 1);
+  getDiags().Report(Context.getFullLoc(S->getLocStart()), DiagID)
+    << Msg << S->getSourceRange();
 }
 
 /// ErrorUnsupported - Print out an error that codegen doesn't support the
@@ -122,8 +120,7 @@
   unsigned DiagID = getDiags().getCustomDiagID(Diagnostic::Error, 
                                                "cannot codegen this %0 yet");
   std::string Msg = Type;
-  const std::string *Strs[] = { &Msg };
-  getDiags().Report(Context.getFullLoc(D->getLocation()), DiagID, Strs, 1);
+  getDiags().Report(Context.getFullLoc(D->getLocation()), DiagID) << Msg;
 }
 
 /// setGlobalVisibility - Set the visibility for the given LLVM

Modified: cfe/trunk/lib/Driver/TextDiagnosticBuffer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/TextDiagnosticBuffer.cpp?rev=59502&r1=59501&r2=59502&view=diff

==============================================================================
--- cfe/trunk/lib/Driver/TextDiagnosticBuffer.cpp (original)
+++ cfe/trunk/lib/Driver/TextDiagnosticBuffer.cpp Tue Nov 18 01:04:44 2008
@@ -17,30 +17,21 @@
 /// HandleDiagnostic - Store the errors, warnings, and notes that are
 /// reported.
 /// 
-void TextDiagnosticBuffer::HandleDiagnostic(Diagnostic &Diags,
-                                            Diagnostic::Level Level,
-                                            FullSourceLoc Pos,
-                                            diag::kind ID,
-                                            const std::string **Strs,
-                                            unsigned NumStrs,
-                                            const SourceRange *,
-                                            unsigned) {
+void TextDiagnosticBuffer::HandleDiagnostic(Diagnostic::Level Level,
+                                            const DiagnosticInfo &Info) {
   switch (Level) {
   default: assert(0 && "Diagnostic not handled during diagnostic buffering!");
   case Diagnostic::Note:
-    Notes.push_back(std::make_pair(Pos.getLocation(),
-                                   FormatDiagnostic(Diags, Level, ID, 
-                                                    Strs, NumStrs)));
+    Notes.push_back(std::make_pair(Info.getLocation().getLocation(),
+                                   FormatDiagnostic(Info)));
     break;
   case Diagnostic::Warning:
-    Warnings.push_back(std::make_pair(Pos.getLocation(),
-                                      FormatDiagnostic(Diags, Level, ID, 
-                                                       Strs, NumStrs)));
+    Warnings.push_back(std::make_pair(Info.getLocation().getLocation(),
+                                      FormatDiagnostic(Info)));
     break;
   case Diagnostic::Error:
-    Errors.push_back(std::make_pair(Pos.getLocation(),
-                                    FormatDiagnostic(Diags, Level, ID,
-                                                     Strs, NumStrs)));
+    Errors.push_back(std::make_pair(Info.getLocation().getLocation(),
+                                    FormatDiagnostic(Info)));
     break;
   }
 }

Modified: cfe/trunk/lib/Driver/TextDiagnosticPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/TextDiagnosticPrinter.cpp?rev=59502&r1=59501&r2=59502&view=diff

==============================================================================
--- cfe/trunk/lib/Driver/TextDiagnosticPrinter.cpp (original)
+++ cfe/trunk/lib/Driver/TextDiagnosticPrinter.cpp Tue Nov 18 01:04:44 2008
@@ -34,7 +34,7 @@
 /// HighlightRange - Given a SourceRange and a line number, highlight (with ~'s)
 /// any characters in LineNo that intersect the SourceRange.
 void TextDiagnosticPrinter::HighlightRange(const SourceRange &R,
-                                           SourceManager& SourceMgr,
+                                           const SourceManager& SourceMgr,
                                            unsigned LineNo, unsigned FileID,
                                            std::string &CaretLine,
                                            const std::string &SourceLine) {
@@ -92,17 +92,12 @@
     CaretLine[i] = '~';
 }
 
-void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic &Diags,
-                                             Diagnostic::Level Level, 
-                                             FullSourceLoc Pos,
-                                             diag::kind ID,
-                                             const std::string **Strs,
-                                             unsigned NumStrs,
-                                             const SourceRange *Ranges,
-                                             unsigned NumRanges) {
+void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level, 
+                                             const DiagnosticInfo &Info) {
   unsigned LineNo = 0, ColNo = 0;
   unsigned FileID = 0;
   const char *LineStart = 0, *LineEnd = 0;
+  const FullSourceLoc &Pos = Info.getLocation();
   
   if (Pos.isValid()) {
     FullSourceLoc LPos = Pos.getLogicalLoc();
@@ -146,9 +141,10 @@
     break;
   }
   
-  OS << FormatDiagnostic(Diags, Level, ID, Strs, NumStrs) << "\n";
+  OS << FormatDiagnostic(Info) << "\n";
   
-  if (CaretDiagnostics && Pos.isValid() && ((LastLoc != Pos) || Ranges)) {
+  if (CaretDiagnostics && Pos.isValid() && ((LastLoc != Pos) ||
+                                            Info.getNumRanges())) {
     // Cache the LastLoc, it allows us to omit duplicate source/caret spewage.
     LastLoc = Pos;
     
@@ -160,8 +156,8 @@
     std::string CaretLine(LineEnd-LineStart, ' ');
     
     // Highlight all of the characters covered by Ranges with ~ characters.
-    for (unsigned i = 0; i != NumRanges; ++i)
-      HighlightRange(Ranges[i], Pos.getManager(), LineNo, FileID,
+    for (unsigned i = 0; i != Info.getNumRanges(); ++i)
+      HighlightRange(Info.getRange(i), Pos.getManager(), LineNo, FileID,
                      CaretLine, SourceLine);
     
     // Next, insert the caret itself.

Modified: cfe/trunk/lib/Lex/Preprocessor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/Preprocessor.cpp?rev=59502&r1=59501&r2=59502&view=diff

==============================================================================
--- cfe/trunk/lib/Lex/Preprocessor.cpp (original)
+++ cfe/trunk/lib/Lex/Preprocessor.cpp Tue Nov 18 01:04:44 2008
@@ -124,28 +124,24 @@
 
 void Preprocessor::Diag(SourceLocation Loc, unsigned DiagID, 
                         const std::string &Msg) {
-  const std::string *Strs[] = { &Msg };
-  Diags.Report(getFullLoc(Loc), DiagID, Strs, 1);
+  Diags.Report(getFullLoc(Loc), DiagID) << Msg;
 }
 
 void Preprocessor::Diag(SourceLocation Loc, unsigned DiagID,
                         const std::string &Msg,
                         const SourceRange &R1, const SourceRange &R2) {
-  const std::string *Strs[] = { &Msg };
-  SourceRange R[] = {R1, R2};
-  Diags.Report(getFullLoc(Loc), DiagID, Strs, 1, R, 2);
+  Diags.Report(getFullLoc(Loc), DiagID) << Msg << R1 << R2;
 }
 
 
 void Preprocessor::Diag(SourceLocation Loc, unsigned DiagID,
                         const SourceRange &R) {
-  Diags.Report(getFullLoc(Loc), DiagID, 0, 0, &R, 1);
+  Diags.Report(getFullLoc(Loc), DiagID) << R;
 }
 
 void Preprocessor::Diag(SourceLocation Loc, unsigned DiagID,
                         const SourceRange &R1, const SourceRange &R2) {
-  SourceRange R[] = {R1, R2};
-  Diags.Report(getFullLoc(Loc), DiagID, 0, 0, R, 2);
+  Diags.Report(getFullLoc(Loc), DiagID) << R1 << R2;
 }
 
 

Modified: cfe/trunk/lib/Parse/DeclSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/DeclSpec.cpp?rev=59502&r1=59501&r2=59502&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/DeclSpec.cpp (original)
+++ cfe/trunk/lib/Parse/DeclSpec.cpp Tue Nov 18 01:04:44 2008
@@ -311,7 +311,6 @@
 }
   
 void DeclSpec::Diag(Diagnostic &D, SourceLocation Loc, SourceManager& SrcMgr,
-          unsigned DiagID, const std::string &Info) {
-  const std::string *Strs[] = { &Info };
-  D.Report(FullSourceLoc(Loc,SrcMgr), DiagID, Strs, 1);
+                    unsigned DiagID, const std::string &Info) {
+  D.Report(FullSourceLoc(Loc,SrcMgr), DiagID) << Info;
 }

Modified: cfe/trunk/lib/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=59502&r1=59501&r2=59502&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/Parser.cpp (original)
+++ cfe/trunk/lib/Parse/Parser.cpp Tue Nov 18 01:04:44 2008
@@ -43,21 +43,18 @@
 
 bool Parser::Diag(SourceLocation Loc, unsigned DiagID,
                   const std::string &Msg) {
-  const std::string *Strs[] = { &Msg };
-  Diags.Report(FullSourceLoc(Loc,PP.getSourceManager()), DiagID, Strs, 1);
+  Diags.Report(FullSourceLoc(Loc,PP.getSourceManager()), DiagID) << Msg;
   return true;
 }
 
 bool Parser::Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg,
                   const SourceRange& Range) {
-  const std::string *Strs[] = { &Msg };
-  Diags.Report(PP.getFullLoc(Loc), DiagID, Strs, 1, &Range,1);
+  Diags.Report(PP.getFullLoc(Loc), DiagID) << Msg << Range;
   return true;
 }
 
 bool Parser::Diag(SourceLocation Loc, unsigned DiagID, const SourceRange &R) {
-  Diags.Report(FullSourceLoc(Loc,PP.getSourceManager()), DiagID, 0, 0,
-               &R, 1);
+  Diags.Report(FullSourceLoc(Loc,PP.getSourceManager()), DiagID) << R;
   return true;
 }
 

Modified: cfe/trunk/lib/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=59502&r1=59501&r2=59502&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.cpp (original)
+++ cfe/trunk/lib/Sema/Sema.cpp Tue Nov 18 01:04:44 2008
@@ -18,11 +18,9 @@
 #include "clang/AST/Expr.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Basic/Diagnostic.h"
-
 using namespace clang;
 
-static inline RecordDecl *CreateStructDecl(ASTContext &C, const char *Name)
-{
+static inline RecordDecl *CreateStructDecl(ASTContext &C, const char *Name) {
   if (C.getLangOptions().CPlusPlus)
     return CXXRecordDecl::Create(C, TagDecl::TK_struct, 
                                  C.getTranslationUnitDecl(),
@@ -176,66 +174,58 @@
 }
 
 bool Sema::Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg) {
-  const std::string *Strs[] = { &Msg };
-  PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID, Strs, 1);
+  PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID) << Msg;
   return true;
 }
 
 bool Sema::Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg1,
                 const std::string &Msg2) {
-  const std::string *MsgArr[] = { &Msg1, &Msg2 };
-  PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID,  MsgArr, 2);
+  PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID) << Msg1 << Msg2;
   return true;
 }
 
 bool Sema::Diag(SourceLocation Loc, unsigned DiagID, const SourceRange& Range) {
-  PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID, 0, 0, &Range,1);
+  PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID) << Range;
   return true;
 }
 
 bool Sema::Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg,
                 const SourceRange& Range) {
-  const std::string *Strs[] = { &Msg };
-  PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID, Strs, 1, &Range,1);
+  PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID) << Msg << Range;
   return true;
 }
 
 bool Sema::Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg1,
-                const std::string &Msg2, const SourceRange& Range) {
-  const std::string *MsgArr[] = { &Msg1, &Msg2 };
-  PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID, MsgArr, 2, &Range, 1);
+                const std::string &Msg2, const SourceRange &R) {
+  PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID) << Msg1 << Msg2 << R;
   return true;
 }
 
 bool Sema::Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg1, 
                 const std::string &Msg2, const std::string &Msg3, 
                 const SourceRange &R1) {
-  const std::string *MsgArr[] = { &Msg1, &Msg2, &Msg3 };
-  PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID, MsgArr, 3, &R1, 1);
+  PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID)
+    << Msg1 << Msg2 << Msg3 << R1;
   return true;
 }
 
 bool Sema::Diag(SourceLocation Loc, unsigned DiagID,
                 const SourceRange& R1, const SourceRange& R2) {
-  SourceRange RangeArr[] = { R1, R2 };
-  PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID, 0, 0, RangeArr, 2);
+  PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID) << R1 << R2;
   return true;
 }
 
 bool Sema::Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg,
                 const SourceRange& R1, const SourceRange& R2) {
-  SourceRange RangeArr[] = { R1, R2 };
-  const std::string *Strs[] = { &Msg };
-  PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID, Strs, 1, RangeArr, 2);
+  PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID) << Msg << R1 << R2;
   return true;
 }
 
 bool Sema::Diag(SourceLocation Range, unsigned DiagID, const std::string &Msg1,
                 const std::string &Msg2, const SourceRange& R1,
                 const SourceRange& R2) {
-  const std::string *MsgArr[] = { &Msg1, &Msg2 };
-  SourceRange RangeArr[] = { R1, R2 };
-  PP.getDiagnostics().Report(PP.getFullLoc(Range),DiagID, MsgArr,2,RangeArr, 2);
+  PP.getDiagnostics().Report(PP.getFullLoc(Range),DiagID)
+    << Msg1 << Msg2 << R1 << R2;
   return true;
 }
 





More information about the cfe-commits mailing list