From 120187de4be187a6b0f903c05175bfa05af8002f Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Thu, 27 Mar 2008 06:16:40 +0000 Subject: [PATCH] PathDiagnosticPiece no longer contains a vector of strings; just one string. PathDiagnostic no longer contains a diagnostic ID or diagnostic level. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@48864 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Analysis/PathDiagnostic.h | 67 ++++++++++++++----------- lib/Analysis/PathDiagnostic.cpp | 36 ++++++++++--- 2 files changed, 67 insertions(+), 36 deletions(-) diff --git a/include/clang/Analysis/PathDiagnostic.h b/include/clang/Analysis/PathDiagnostic.h index 8ba1bc1f77..bf855054bd 100644 --- a/include/clang/Analysis/PathDiagnostic.h +++ b/include/clang/Analysis/PathDiagnostic.h @@ -20,29 +20,21 @@ #include #include #include +#include namespace clang { class PathDiagnosticPiece { FullSourceLoc Pos; - std::vector strs; + std::string str; std::vector ranges; public: - PathDiagnosticPiece(FullSourceLoc pos) : Pos(pos) {} - - void addString(const std::string& s) { - strs.push_back(s); - } - - const std::string* strs_begin() const { - return strs.empty() ? NULL : &strs[0]; - } - - const std::string* strs_end() const { - return strs_begin() + strs.size(); - } + PathDiagnosticPiece(FullSourceLoc pos, const std::string& s) + : Pos(pos), str(s) {} + const std::string& getString() const { return str; } + void addRange(SourceRange R) { ranges.push_back(R); } @@ -68,14 +60,11 @@ public: class PathDiagnostic { std::list path; - Diagnostic::Level DiagLevel; - diag::kind ID; unsigned Size; public: - PathDiagnostic(Diagnostic::Level lvl, diag::kind i) - : DiagLevel(lvl), ID(i), Size(0) {} + PathDiagnostic() : Size(0) {} ~PathDiagnostic(); @@ -89,10 +78,19 @@ public: ++Size; } + unsigned size() const { return Size; } + bool empty() const { return Size == 0; } + class iterator { public: typedef std::list::iterator ImplTy; + typedef PathDiagnosticPiece value_type; + typedef value_type& reference; + typedef value_type* pointer; + typedef ptrdiff_t difference_type; + typedef std::bidirectional_iterator_tag iterator_category; + private: ImplTy I; @@ -113,6 +111,12 @@ public: public: typedef std::list::const_iterator ImplTy; + typedef const PathDiagnosticPiece value_type; + typedef value_type& reference; + typedef value_type* pointer; + typedef ptrdiff_t difference_type; + typedef std::bidirectional_iterator_tag iterator_category; + private: ImplTy I; @@ -122,24 +126,30 @@ public: bool operator==(const const_iterator& X) const { return I == X.I; } bool operator!=(const const_iterator& X) const { return I != X.I; } - const PathDiagnosticPiece& operator*() const { return **I; } - const PathDiagnosticPiece* operator->() const { return *I; } + reference operator*() const { return **I; } + pointer operator->() const { return *I; } const_iterator& operator++() { ++I; return *this; } const_iterator& operator--() { --I; return *this; } }; - + + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; + + + // forward iterator creation methods. + iterator begin() { return path.begin(); } iterator end() { return path.end(); } - + const_iterator begin() const { return path.begin(); } const_iterator end() const { return path.end(); } - unsigned size() const { return Size; } - bool empty() const { return Size == 0; } - - Diagnostic::Level getLevel() const { return DiagLevel; } - diag::kind getDiagKind() const { return ID; } + // reverse iterator creation methods. + reverse_iterator rbegin() { return reverse_iterator(end()); } + const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); } + reverse_iterator rend() { return reverse_iterator(begin()); } + const_reverse_iterator rend() const { return const_reverse_iterator(begin());} }; class PathDiagnosticClient : public DiagnosticClient { @@ -156,8 +166,7 @@ public: const SourceRange *Ranges, unsigned NumRanges); - virtual void HandlePathDiagnostic(Diagnostic& Diag, - const PathDiagnostic& D) = 0; + virtual void HandlePathDiagnostic(const PathDiagnostic& D) = 0; }; } //end clang namespace diff --git a/lib/Analysis/PathDiagnostic.cpp b/lib/Analysis/PathDiagnostic.cpp index a0be80aa5b..e4228c7744 100644 --- a/lib/Analysis/PathDiagnostic.cpp +++ b/lib/Analysis/PathDiagnostic.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "clang/Analysis/PathDiagnostic.h" +#include using namespace clang; @@ -30,16 +31,37 @@ void PathDiagnosticClient::HandleDiagnostic(Diagnostic &Diags, // Create a PathDiagnostic with a single piece. - PathDiagnostic D(DiagLevel, ID); + PathDiagnostic D; - PathDiagnosticPiece* P = new PathDiagnosticPiece(Pos); + // Ripped from TextDiagnostics::FormatDiagnostic. Perhaps we should + // centralize it somewhere? - while (NumStrs) { - P->addString(*Strs); - --NumStrs; - ++Strs; + std::ostringstream os; + + switch (DiagLevel) { + default: assert(0 && "Unknown diagnostic type!"); + case Diagnostic::Note: os << "note: "; break; + case Diagnostic::Warning: os << "warning: "; break; + case Diagnostic::Error: os << "error: "; break; + case Diagnostic::Fatal: os << "fatal error: "; break; + break; + } + + std::string Msg = Diags.getDescription(ID); + + 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] : "<<>>") + + std::string(Msg.begin() + i + 2, Msg.end()); + } } + os << Msg; + + PathDiagnosticPiece* P = new PathDiagnosticPiece(Pos, os.str()); + while (NumRanges) { P->addRange(*Ranges); --NumRanges; @@ -48,5 +70,5 @@ void PathDiagnosticClient::HandleDiagnostic(Diagnostic &Diags, D.push_front(P); - HandlePathDiagnostic(Diags, D); + HandlePathDiagnostic(D); } -- 2.40.0