diff options
-rw-r--r-- | include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h | 39 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/PathDiagnostic.cpp | 40 |
2 files changed, 55 insertions, 24 deletions
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h b/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h index 1b16ec50a0..0e6b75278b 100644 --- a/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h +++ b/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h @@ -27,6 +27,7 @@ class BinaryOperator; class CompoundStmt; class Decl; class LocationContext; +class ParentMap; class ProgramPoint; class SourceManager; class Stmt; @@ -79,10 +80,12 @@ protected: class PathDiagnosticRange : public SourceRange { public: - const bool isPoint; + bool isPoint; PathDiagnosticRange(const SourceRange &R, bool isP = false) : SourceRange(R), isPoint(isP) {} + + PathDiagnosticRange() : isPoint(false) {} }; class PathDiagnosticLocation { @@ -93,24 +96,36 @@ private: const Decl *D; const SourceManager *SM; const LocationContext *LC; + FullSourceLoc Loc; + PathDiagnosticRange Range; + + FullSourceLoc genLocation(const ParentMap *PM=0) const; + PathDiagnosticRange genRange(const ParentMap *PM=0) const; + public: PathDiagnosticLocation() - : K(SingleLocK), S(0), D(0), SM(0), LC(0) {} + : K(SingleLocK), S(0), D(0), SM(0), LC(0) { + } PathDiagnosticLocation(FullSourceLoc L) - : K(SingleLocK), R(L, L), S(0), D(0), SM(&L.getManager()), LC(0) {} + : K(SingleLocK), R(L, L), S(0), D(0), SM(&L.getManager()), LC(0), + Loc(genLocation()), Range(genRange()) { + } PathDiagnosticLocation(SourceLocation L, const SourceManager &sm, Kind kind = SingleLocK) - : K(kind), R(L, L), S(0), D(0), SM(&sm), LC(0) {} + : K(kind), R(L, L), S(0), D(0), SM(&sm), LC(0), + Loc(genLocation()), Range(genRange()) { + } PathDiagnosticLocation(const Stmt *s, const SourceManager &sm, - const LocationContext *lc) - : K(StmtK), S(s), D(0), SM(&sm), LC(lc) {} + const LocationContext *lc); PathDiagnosticLocation(const Decl *d, const SourceManager &sm) - : K(DeclK), S(0), D(d), SM(&sm), LC(0) {} + : K(DeclK), S(0), D(d), SM(&sm), LC(0), + Loc(genLocation()), Range(genRange()) { + } // Create a location for the beginning of the statement. static PathDiagnosticLocation createBeginStmt(const Stmt *S, @@ -167,8 +182,14 @@ public: return SM != 0; } - FullSourceLoc asLocation() const; - PathDiagnosticRange asRange() const; + FullSourceLoc asLocation() const { + return Loc; + } + + PathDiagnosticRange asRange() const { + return Range; + } + const Stmt *asStmt() const { assert(isValid()); return S; } const Decl *asDecl() const { assert(isValid()); return D; } diff --git a/lib/StaticAnalyzer/Core/PathDiagnostic.cpp b/lib/StaticAnalyzer/Core/PathDiagnostic.cpp index 1faace5464..40b73deacb 100644 --- a/lib/StaticAnalyzer/Core/PathDiagnostic.cpp +++ b/lib/StaticAnalyzer/Core/PathDiagnostic.cpp @@ -131,32 +131,40 @@ void PathDiagnosticClient::HandlePathDiagnostic(const PathDiagnostic *D) { //===----------------------------------------------------------------------===// static SourceLocation getValidSourceLocation(const Stmt* S, - const LocationContext *LC) { - assert(LC); + const ParentMap &PM) { SourceLocation L = S->getLocStart(); // S might be a temporary statement that does not have a location in the // source code, so find an enclosing statement and use it's location. - if (!L.isValid()) { - ParentMap & PM = LC->getParentMap(); - - while (!L.isValid()) { - S = PM.getParent(S); - L = S->getLocStart(); - } + while (!L.isValid()) { + S = PM.getParent(S); + L = S->getLocStart(); } return L; } +PathDiagnosticLocation::PathDiagnosticLocation(const Stmt *s, + const SourceManager &sm, + const LocationContext *lc) + : K(StmtK), S(s), D(0), SM(&sm), LC(lc) +{ + const ParentMap* PM = 0; + if (lc) + PM = &lc->getParentMap(); + + Loc = genLocation(PM); + Range = genRange(PM); +} + PathDiagnosticLocation PathDiagnosticLocation::createBeginStmt(const Stmt *S, const SourceManager &SM, const LocationContext *LC) { - return PathDiagnosticLocation(getValidSourceLocation(S, LC), SM, SingleLocK); + return PathDiagnosticLocation(getValidSourceLocation(S, LC->getParentMap()), + SM, SingleLocK); } - PathDiagnosticLocation PathDiagnosticLocation::createOperatorLoc(const BinaryOperator *BO, const SourceManager &SM) { @@ -246,7 +254,8 @@ PathDiagnosticLocation PathDiagnosticLocation::createSingleLocation( return PathDiagnosticLocation(L, L.getManager(), SingleLocK); } -FullSourceLoc PathDiagnosticLocation::asLocation() const { +FullSourceLoc + PathDiagnosticLocation::genLocation(const ParentMap *PM) const { assert(isValid()); // Note that we want a 'switch' here so that the compiler can warn us in // case we add more cases. @@ -255,7 +264,7 @@ FullSourceLoc PathDiagnosticLocation::asLocation() const { case RangeK: break; case StmtK: - return FullSourceLoc(getValidSourceLocation(S, LC), + return FullSourceLoc(getValidSourceLocation(S, LC->getParentMap()), const_cast<SourceManager&>(*SM)); case DeclK: return FullSourceLoc(D->getLocation(), const_cast<SourceManager&>(*SM)); @@ -264,7 +273,8 @@ FullSourceLoc PathDiagnosticLocation::asLocation() const { return FullSourceLoc(R.getBegin(), const_cast<SourceManager&>(*SM)); } -PathDiagnosticRange PathDiagnosticLocation::asRange() const { +PathDiagnosticRange + PathDiagnosticLocation::genRange(const ParentMap *PM) const { assert(isValid()); // Note that we want a 'switch' here so that the compiler can warn us in // case we add more cases. @@ -299,7 +309,7 @@ PathDiagnosticRange PathDiagnosticLocation::asRange() const { case Stmt::BinaryConditionalOperatorClass: case Stmt::ConditionalOperatorClass: case Stmt::ObjCForCollectionStmtClass: { - SourceLocation L = getValidSourceLocation(S, LC); + SourceLocation L = getValidSourceLocation(S, LC->getParentMap()); return SourceRange(L, L); } } |