diff options
author | Chris Lattner <sabre@nondot.org> | 2008-11-19 06:51:40 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2008-11-19 06:51:40 +0000 |
commit | 23be0674074db5a815ba2a0d2aacc36c1372a660 (patch) | |
tree | c991db6f082a1f2800c0ef6adfce7d9454f18a27 /clang/lib/Basic | |
parent | 48fe79e9e161fba7516406d4bcebf3023a0fb60d (diff) | |
download | bcm5719-llvm-23be0674074db5a815ba2a0d2aacc36c1372a660.tar.gz bcm5719-llvm-23be0674074db5a815ba2a0d2aacc36c1372a660.zip |
rewrite FormatDiagnostic to be less gross and a lot more efficient.
This also makes it illegal to have bare '%'s in diagnostics. If you
want a % in a diagnostic, use %%.
llvm-svn: 59596
Diffstat (limited to 'clang/lib/Basic')
-rw-r--r-- | clang/lib/Basic/Diagnostic.cpp | 49 |
1 files changed, 35 insertions, 14 deletions
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; } |