From 1f9bd0fbf5894b41bba5f2fdb0c6546a7a6ef3d8 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Thu, 26 Mar 2009 21:21:35 +0000 Subject: [PATCH] PathDiagnostics (analyzer): - Added a new class, 'PathDiagnosticLocation', that is a variant for SourceLocation, SourceRange, or Stmt*. This will be used soon by PathDiagnosticPieces to describe locations for targets of branches, locations of events, etc. - Did some prep. refactoring of PathDiagnosticPieces to prepare them for adopting the new PathDiagnosticLocation git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67767 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Analysis/PathDiagnostic.h | 88 +++++++++++++++++-------- lib/Analysis/PathDiagnostic.cpp | 24 ++----- 2 files changed, 68 insertions(+), 44 deletions(-) diff --git a/include/clang/Analysis/PathDiagnostic.h b/include/clang/Analysis/PathDiagnostic.h index 02b19b8f27..abf37f7079 100644 --- a/include/clang/Analysis/PathDiagnostic.h +++ b/include/clang/Analysis/PathDiagnostic.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_PATH_DIAGNOSTIC_H #define LLVM_CLANG_PATH_DIAGNOSTIC_H +#include "clang/Basic/SourceManager.h" #include "clang/Basic/Diagnostic.h" #include "llvm/ADT/OwningPtr.h" @@ -28,8 +29,8 @@ namespace clang { // High-level interface for handlers of path-sensitive diagnostics. //===----------------------------------------------------------------------===// - class PathDiagnostic; +class Stmt; class PathDiagnosticClient : public DiagnosticClient { public: @@ -47,6 +48,27 @@ public: //===----------------------------------------------------------------------===// class PathDiagnosticPiece; + +class PathDiagnosticLocation { +private: + enum Kind { Range, SingleLoc, Statement } K; + SourceRange R; + const Stmt *S; + const SourceManager &SM; +public: + PathDiagnosticLocation(FullSourceLoc L) + : K(SingleLoc), R(L, L), S(0), SM(L.getManager()) {} + + PathDiagnosticLocation(const Stmt *s, const SourceManager &sm) + : K(Statement), S(s), SM(sm) {} + + PathDiagnosticLocation(SourceRange r, const SourceManager &sm) + : K(Range), R(r), S(0), SM(sm) {} + + FullSourceLoc asLocation() const; + SourceRange asRange() const; + const Stmt *asStmt() const; +}; class PathDiagnostic { std::list path; @@ -68,7 +90,7 @@ public: const std::string& getDescription() const { return Desc; } const std::string& getBugType() const { return BugType; } - const std::string& getCategory() const { return Category; } + const std::string& getCategory() const { return Category; } typedef std::list::const_iterator meta_iterator; meta_iterator meta_begin() const { return OtherDesc.begin(); } @@ -180,7 +202,6 @@ public: enum DisplayHint { Above, Below }; private: - const FullSourceLoc Pos; const std::string str; std::vector CodeModificationHints; const Kind kind; @@ -193,13 +214,11 @@ private: PathDiagnosticPiece& operator=(const PathDiagnosticPiece &P); protected: - PathDiagnosticPiece(FullSourceLoc pos, const std::string& s, - Kind k, DisplayHint hint = Below); + PathDiagnosticPiece(const std::string& s, Kind k, DisplayHint hint = Below); - PathDiagnosticPiece(FullSourceLoc pos, const char* s, - Kind k, DisplayHint hint = Below); + PathDiagnosticPiece(const char* s, Kind k, DisplayHint hint = Below); - PathDiagnosticPiece(FullSourceLoc pos, Kind k, DisplayHint hint = Below); + PathDiagnosticPiece(Kind k, DisplayHint hint = Below); public: virtual ~PathDiagnosticPiece(); @@ -210,6 +229,8 @@ public: /// be displayed by the PathDiagnosticClient. DisplayHint getDisplayHint() const { return Hint; } + virtual FullSourceLoc getLocation() const = 0; + Kind getKind() const { return kind; } void addRange(SourceRange R) { ranges.push_back(R); } @@ -243,24 +264,33 @@ public: : &CodeModificationHints[0] + CodeModificationHints.size(); } - const SourceManager& getSourceManager() const { - return Pos.getManager(); - } - - FullSourceLoc getLocation() const { return Pos; } - static inline bool classof(const PathDiagnosticPiece* P) { return true; } }; -class PathDiagnosticEventPiece : public PathDiagnosticPiece { +class PathDiagnosticSpotPiece : public PathDiagnosticPiece { +private: + FullSourceLoc Pos; +public: + PathDiagnosticSpotPiece(FullSourceLoc pos, const std::string& s, + PathDiagnosticPiece::Kind k) + : PathDiagnosticPiece(s, k), Pos(pos) { + assert(Pos.isValid() && + "PathDiagnosticSpotPiece's must have a valid location."); + } + + FullSourceLoc getLocation() const { return Pos; } +}; + +class PathDiagnosticEventPiece : public PathDiagnosticSpotPiece { + public: PathDiagnosticEventPiece(FullSourceLoc pos, const std::string& s) - : PathDiagnosticPiece(pos, s, Event) {} + : PathDiagnosticSpotPiece(pos, s, Event) {} PathDiagnosticEventPiece(FullSourceLoc pos, const char* s) - : PathDiagnosticPiece(pos, s, Event) {} + : PathDiagnosticSpotPiece(pos, s, Event) {} ~PathDiagnosticEventPiece(); @@ -270,34 +300,40 @@ public: }; class PathDiagnosticControlFlowPiece : public PathDiagnosticPiece { - const SourceLocation EndPos; + FullSourceLoc StartPos; + SourceLocation EndPos; public: PathDiagnosticControlFlowPiece(FullSourceLoc startPos, SourceLocation endPos, const std::string& s) - : PathDiagnosticPiece(startPos, s, ControlFlow), EndPos(endPos) {} + : PathDiagnosticPiece(s, ControlFlow), StartPos(startPos), EndPos(endPos) {} PathDiagnosticControlFlowPiece(FullSourceLoc startPos, SourceLocation endPos, const char* s) - : PathDiagnosticPiece(startPos, s, ControlFlow), EndPos(endPos) {} + : PathDiagnosticPiece(s, ControlFlow), StartPos(startPos), EndPos(endPos) {} PathDiagnosticControlFlowPiece(FullSourceLoc startPos, SourceLocation endPos) - : PathDiagnosticPiece(startPos, ControlFlow), EndPos(endPos) {} + : PathDiagnosticPiece(ControlFlow), StartPos(startPos), EndPos(endPos) {} ~PathDiagnosticControlFlowPiece(); - SourceLocation getStartLocation() const { return getLocation(); } - SourceLocation getEndLocation() const { return EndPos; } + FullSourceLoc getStartLocation() const { return StartPos; } + FullSourceLoc getEndLocation() const { + return FullSourceLoc(EndPos, + const_cast(StartPos.getManager())); + } + + virtual FullSourceLoc getLocation() const { return StartPos; } static inline bool classof(const PathDiagnosticPiece* P) { return P->getKind() == ControlFlow; } }; -class PathDiagnosticMacroPiece : public PathDiagnosticPiece { - std::vector SubPieces; +class PathDiagnosticMacroPiece : public PathDiagnosticSpotPiece { + std::vector SubPieces; public: PathDiagnosticMacroPiece(FullSourceLoc pos) - : PathDiagnosticPiece(pos, "", Macro) {} + : PathDiagnosticSpotPiece(pos, "", Macro) {} ~PathDiagnosticMacroPiece(); diff --git a/lib/Analysis/PathDiagnostic.cpp b/lib/Analysis/PathDiagnostic.cpp index 86b113cf87..0ccb900645 100644 --- a/lib/Analysis/PathDiagnostic.cpp +++ b/lib/Analysis/PathDiagnostic.cpp @@ -49,28 +49,16 @@ static inline size_t GetNumCharsToLastNonPeriod(const std::string &s) { return s.empty () ? 0 : GetNumCharsToLastNonPeriod(&s[0]); } -PathDiagnosticPiece::PathDiagnosticPiece(FullSourceLoc pos, - const std::string& s, +PathDiagnosticPiece::PathDiagnosticPiece(const std::string& s, Kind k, DisplayHint hint) - : Pos(pos), str(s, 0, GetNumCharsToLastNonPeriod(s)), kind(k), Hint(hint) { - assert(Pos.isValid() && - "PathDiagnosticPiece's must have a valid location."); -} + : str(s, 0, GetNumCharsToLastNonPeriod(s)), kind(k), Hint(hint) {} -PathDiagnosticPiece::PathDiagnosticPiece(FullSourceLoc pos, - const char* s, Kind k, +PathDiagnosticPiece::PathDiagnosticPiece(const char* s, Kind k, DisplayHint hint) - : Pos(pos), str(s, GetNumCharsToLastNonPeriod(s)), kind(k), Hint(hint) { - assert(Pos.isValid() && - "PathDiagnosticPiece's must have a valid location."); -} + : str(s, GetNumCharsToLastNonPeriod(s)), kind(k), Hint(hint) {} -PathDiagnosticPiece::PathDiagnosticPiece(FullSourceLoc pos, Kind k, - DisplayHint hint) - : Pos(pos), kind(k), Hint(hint) { - assert(Pos.isValid() && - "PathDiagnosticPiece's must have a valid location."); -} +PathDiagnosticPiece::PathDiagnosticPiece(Kind k, DisplayHint hint) + : kind(k), Hint(hint) {} PathDiagnosticPiece::~PathDiagnosticPiece() {} PathDiagnosticEventPiece::~PathDiagnosticEventPiece() {} -- 2.40.0