summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Analysis/PathDiagnostic.cpp9
-rw-r--r--clang/lib/Basic/Diagnostic.cpp49
-rw-r--r--clang/lib/Driver/TextDiagnosticBuffer.cpp13
-rw-r--r--clang/lib/Driver/TextDiagnosticPrinter.cpp11
4 files changed, 55 insertions, 27 deletions
diff --git a/clang/lib/Analysis/PathDiagnostic.cpp b/clang/lib/Analysis/PathDiagnostic.cpp
index aed83ea84fb..29ea8c0e375 100644
--- a/clang/lib/Analysis/PathDiagnostic.cpp
+++ b/clang/lib/Analysis/PathDiagnostic.cpp
@@ -12,8 +12,8 @@
//===----------------------------------------------------------------------===//
#include "clang/Analysis/PathDiagnostic.h"
+#include "llvm/ADT/SmallString.h"
#include <sstream>
-
using namespace clang;
PathDiagnostic::~PathDiagnostic() {
@@ -36,10 +36,13 @@ void PathDiagnosticClient::HandleDiagnostic(Diagnostic::Level DiagLevel,
case Diagnostic::Fatal: LevelStr = "fatal error: "; break;
}
- std::string Msg = FormatDiagnostic(Info);
+ llvm::SmallString<100> StrC;
+ StrC += LevelStr;
+ Info.FormatDiagnostic(StrC);
PathDiagnosticPiece *P =
- new PathDiagnosticPiece(Info.getLocation(), LevelStr+Msg);
+ new PathDiagnosticPiece(Info.getLocation(),
+ std::string(StrC.begin(), StrC.end()));
for (unsigned i = 0, e = Info.getNumRanges(); i != e; ++i)
P->addRange(Info.getRange(i));
diff --git a/clang/lib/Basic/Diagnostic.cpp b/clang/lib/Basic/Diagnostic.cpp
index 35d454b1b9a..e8c24ab0a71 100644
--- a/clang/lib/Basic/Diagnostic.cpp
+++ b/clang/lib/Basic/Diagnostic.cpp
@@ -13,7 +13,7 @@
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/SourceLocation.h"
-#include <cassert>
+#include "llvm/ADT/SmallVector.h"
#include <vector>
#include <map>
#include <cstring>
@@ -246,20 +246,41 @@ void Diagnostic::ProcessDiag(const DiagnosticInfo &Info) {
DiagnosticClient::~DiagnosticClient() {}
-std::string DiagnosticClient::FormatDiagnostic(const DiagnosticInfo &Info) {
- std::string Msg = Info.getDiags()->getDescription(Info.getID());
+
+/// FormatDiagnostic - Format this diagnostic into a string, substituting the
+/// formal arguments into the %0 slots. The result is appended onto the Str
+/// array.
+void DiagnosticInfo::
+FormatDiagnostic(llvm::SmallVectorImpl<char> &OutStr) const {
+ const char *DiagStr = getDiags()->getDescription(getID());
+ const char *DiagEnd = DiagStr+strlen(DiagStr);
- // 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) +
- (Info.getArgKind(StrNo) == DiagnosticInfo::ak_std_string ?
- Info.getArgStdStr(StrNo) : std::string(Info.getArgCStr(StrNo))) +
- std::string(Msg.begin() + i + 2, Msg.end());
+ while (DiagStr != DiagEnd) {
+ if (DiagStr[0] != '%') {
+ // Append non-%0 substrings to Str if we have one.
+ const char *StrEnd = std::find(DiagStr, DiagEnd, '%');
+ OutStr.append(DiagStr, StrEnd);
+ DiagStr = StrEnd;
+ } else if (DiagStr[1] == '%') {
+ OutStr.push_back('%'); // %% -> %.
+ DiagStr += 2;
+ } else {
+ assert(isdigit(DiagStr[1]) && "Must escape % with %%");
+ unsigned StrNo = DiagStr[1] - '0';
+
+ switch (getArgKind(StrNo)) {
+ case DiagnosticInfo::ak_std_string: {
+ const std::string &S = getArgStdStr(StrNo);
+ OutStr.append(S.begin(), S.end());
+ break;
+ }
+ case DiagnosticInfo::ak_c_string: {
+ const char *S = getArgCStr(StrNo);
+ OutStr.append(S, S + strlen(S));
+ break;
+ }
+ }
+ DiagStr += 2;
}
}
-
- return Msg;
}
diff --git a/clang/lib/Driver/TextDiagnosticBuffer.cpp b/clang/lib/Driver/TextDiagnosticBuffer.cpp
index b138b1a24d2..5032cdb0b5d 100644
--- a/clang/lib/Driver/TextDiagnosticBuffer.cpp
+++ b/clang/lib/Driver/TextDiagnosticBuffer.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "clang/Driver/TextDiagnosticBuffer.h"
+#include "llvm/ADT/SmallString.h"
using namespace clang;
/// HandleDiagnostic - Store the errors, warnings, and notes that are
@@ -19,19 +20,19 @@ using namespace clang;
///
void TextDiagnosticBuffer::HandleDiagnostic(Diagnostic::Level Level,
const DiagnosticInfo &Info) {
+ llvm::SmallString<100> StrC;
+ Info.FormatDiagnostic(StrC);
+ std::string Str(StrC.begin(), StrC.end());
switch (Level) {
default: assert(0 && "Diagnostic not handled during diagnostic buffering!");
case Diagnostic::Note:
- Notes.push_back(std::make_pair(Info.getLocation().getLocation(),
- FormatDiagnostic(Info)));
+ Notes.push_back(std::make_pair(Info.getLocation().getLocation(), Str));
break;
case Diagnostic::Warning:
- Warnings.push_back(std::make_pair(Info.getLocation().getLocation(),
- FormatDiagnostic(Info)));
+ Warnings.push_back(std::make_pair(Info.getLocation().getLocation(), Str));
break;
case Diagnostic::Error:
- Errors.push_back(std::make_pair(Info.getLocation().getLocation(),
- FormatDiagnostic(Info)));
+ Errors.push_back(std::make_pair(Info.getLocation().getLocation(), Str));
break;
}
}
diff --git a/clang/lib/Driver/TextDiagnosticPrinter.cpp b/clang/lib/Driver/TextDiagnosticPrinter.cpp
index 3b8ec10ec81..cfbe8a7f927 100644
--- a/clang/lib/Driver/TextDiagnosticPrinter.cpp
+++ b/clang/lib/Driver/TextDiagnosticPrinter.cpp
@@ -15,6 +15,7 @@
#include "clang/Basic/SourceManager.h"
#include "clang/Lex/Lexer.h"
#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/ADT/SmallString.h"
using namespace clang;
void TextDiagnosticPrinter::
@@ -138,13 +139,15 @@ void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level,
case Diagnostic::Warning: OS << "warning: "; break;
case Diagnostic::Error: OS << "error: "; break;
case Diagnostic::Fatal: OS << "fatal error: "; break;
- break;
}
- OS << FormatDiagnostic(Info) << "\n";
+ llvm::SmallString<100> OutStr;
+ Info.FormatDiagnostic(OutStr);
+ OS.write(OutStr.begin(), OutStr.size());
+ OS << '\n';
- if (CaretDiagnostics && Pos.isValid() && ((LastLoc != Pos) ||
- Info.getNumRanges())) {
+ if (CaretDiagnostics && Pos.isValid() &&
+ ((LastLoc != Pos) || Info.getNumRanges())) {
// Cache the LastLoc, it allows us to omit duplicate source/caret spewage.
LastLoc = Pos;
OpenPOWER on IntegriCloud