[cfe-commits] r59593 - in /cfe/trunk: include/clang/Analysis/PathSensitive/BugReporter.h include/clang/Basic/Diagnostic.h lib/Basic/Diagnostic.cpp

Chris Lattner sabre at nondot.org
Tue Nov 18 22:04:55 PST 2008


Author: lattner
Date: Wed Nov 19 00:04:55 2008
New Revision: 59593

URL: http://llvm.org/viewvc/llvm-project?rev=59593&view=rev
Log:
implement a transparent optimization with the diagnostics stuff:
const char*'s are now not converted to std::strings when the diagnostic
is formed, we just hold onto their pointer and format as needed.

This commit makes DiagnosticClient::FormatDiagnostic even more of a 
mess, I'll fix it in the next commit.

Modified:
    cfe/trunk/include/clang/Analysis/PathSensitive/BugReporter.h
    cfe/trunk/include/clang/Basic/Diagnostic.h
    cfe/trunk/lib/Basic/Diagnostic.cpp

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=59593&r1=59592&r2=59593&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/BugReporter.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/BugReporter.h Wed Nov 19 00:04:55 2008
@@ -315,8 +315,16 @@
     for (unsigned i = 0, e = Info.getNumRanges(); i != e; ++i)
       R.addRange(Info.getRange(i));
     
-    for (unsigned i = 0, e = Info.getNumArgs(); i != e; ++i)
-      R.addString(Info.getArgStr(i));
+    for (unsigned i = 0, e = Info.getNumArgs(); i != e; ++i) {
+      switch (Info.getArgKind(i)) {
+      case DiagnosticInfo::ak_std_string:   
+        R.addString(Info.getArgStdStr(i));
+        break;
+      case DiagnosticInfo::ak_c_string:   
+        R.addString(Info.getArgCStr(i));
+        break;
+      }
+    }
   }
   
   // Iterators.

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

==============================================================================
--- cfe/trunk/include/clang/Basic/Diagnostic.h (original)
+++ cfe/trunk/include/clang/Basic/Diagnostic.h Wed Nov 19 00:04:55 2008
@@ -178,9 +178,29 @@
   // 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).
-  std::string DiagArguments[10];
+  enum {
+    /// MaxArguments - The maximum number of arguments we can hold. We currently
+    /// only support up to 10 arguments (%0-%9).  A single diagnostic with more
+    /// than that almost certainly has to be simplified anyway.
+    MaxArguments = 10
+  };
+  
+  /// DiagArgumentsKind - This is an array of ArgumentKind::ArgumentKind enum
+  /// values, with one for each argument.  This specifies whether the argument
+  /// is in DiagArgumentsStr or in DiagArguments.
+  unsigned char DiagArgumentsKind[MaxArguments];
+  
+  /// DiagArgumentsStr - This holds the values of each string argument for the
+  /// current diagnostic.  This value is only used when the corresponding
+  /// ArgumentKind is ak_std_string.
+  std::string DiagArgumentsStr[MaxArguments];
+
+  /// DiagArgumentsVal - The values for the various substitution positions. This
+  /// is used when the argument is not an std::string.  The specific value is
+  /// mangled into an intptr_t and the intepretation depends on exactly what
+  /// sort of argument kind it is.
+  intptr_t DiagArgumentsVal[MaxArguments];
+  
   /// 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];
@@ -212,6 +232,12 @@
   unsigned DiagID;
   void operator=(const DiagnosticInfo&); // DO NOT IMPLEMENT
 public:
+  enum ArgumentKind {
+    ak_std_string,   // std::string
+    ak_c_string      // const char *
+  };
+  
+  
   DiagnosticInfo(Diagnostic *diagObj, FullSourceLoc loc, unsigned diagID) :
     DiagObj(diagObj), Loc(loc), DiagID(diagID) {
     if (DiagObj == 0) return;
@@ -251,11 +277,25 @@
 
   unsigned getNumArgs() const { return DiagObj->NumDiagArgs; }
   
-  /// getArgStr - Return the provided argument string specified by Idx.
-  const std::string &getArgStr(unsigned Idx) const {
+  
+  /// getArgKind - Return the kind of the specified index.  Based on the kind
+  /// of argument, the accessors below can be used to get the value.
+  ArgumentKind getArgKind(unsigned Idx) const {
     assert((signed char)Idx < DiagObj->NumDiagArgs &&
-           "Argument out of range!");
-    return DiagObj->DiagArguments[Idx];
+           "Argument index out of range!");
+    return (ArgumentKind)DiagObj->DiagArgumentsKind[Idx];
+  }
+  
+  /// getArgStdStr - Return the provided argument string specified by Idx.
+  const std::string &getArgStdStr(unsigned Idx) const {
+    assert(getArgKind(Idx) == ak_std_string && "invalid argument accessor!");
+    return DiagObj->DiagArgumentsStr[Idx];
+  }
+
+  /// getArgCStr - Return the specified C string argument.
+  const char *getArgCStr(unsigned Idx) const {
+    assert(getArgKind(Idx) == ak_c_string && "invalid argument accessor!");
+    return reinterpret_cast<const char*>(DiagObj->DiagArgumentsVal[Idx]);
   }
   
   /// getNumRanges - Return the number of source ranges associated with this
@@ -270,10 +310,19 @@
   }
   
   DiagnosticInfo &operator<<(const std::string &S) {
-    assert((unsigned)DiagObj->NumDiagArgs < 
-           sizeof(DiagObj->DiagArguments)/sizeof(DiagObj->DiagArguments[0]) &&
+    assert((unsigned)DiagObj->NumDiagArgs < Diagnostic::MaxArguments &&
+           "Too many arguments to diagnostic!");
+    DiagObj->DiagArgumentsKind[DiagObj->NumDiagArgs] = ak_std_string;
+    DiagObj->DiagArgumentsStr[DiagObj->NumDiagArgs++] = S;
+    return *this;
+  }
+  
+  DiagnosticInfo &operator<<(const char *Str) {
+    assert((unsigned)DiagObj->NumDiagArgs < Diagnostic::MaxArguments &&
            "Too many arguments to diagnostic!");
-    DiagObj->DiagArguments[DiagObj->NumDiagArgs++] = S;
+    DiagObj->DiagArgumentsKind[DiagObj->NumDiagArgs] = ak_c_string;
+    DiagObj->DiagArgumentsVal[DiagObj->NumDiagArgs++] =
+      reinterpret_cast<intptr_t>(Str);
     return *this;
   }
   

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

==============================================================================
--- cfe/trunk/lib/Basic/Diagnostic.cpp (original)
+++ cfe/trunk/lib/Basic/Diagnostic.cpp Wed Nov 19 00:04:55 2008
@@ -255,7 +255,8 @@
     if (Msg[i] == '%' && isdigit(Msg[i + 1])) {
       unsigned StrNo = Msg[i + 1] - '0';
       Msg = std::string(Msg.begin(), Msg.begin() + i) +
-            Info.getArgStr(StrNo) +
+      (Info.getArgKind(StrNo) == DiagnosticInfo::ak_std_string ? 
+      Info.getArgStdStr(StrNo) : std::string(Info.getArgCStr(StrNo))) +
             std::string(Msg.begin() + i + 2, Msg.end());
     }
   }





More information about the cfe-commits mailing list