diff options
author | Ted Kremenek <kremenek@apple.com> | 2012-02-24 00:38:56 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2012-02-24 00:38:56 +0000 |
commit | f2131e7d953ce9cd751a05073c0d46ab1db87419 (patch) | |
tree | 82d5929eadf537451962e03d9b795f7c56e40fa1 /clang/lib/StaticAnalyzer/Core/PathDiagnostic.cpp | |
parent | eee9bca03de4602cd8e899c708f0c8dc677e8bba (diff) | |
download | bcm5719-llvm-f2131e7d953ce9cd751a05073c0d46ab1db87419.tar.gz bcm5719-llvm-f2131e7d953ce9cd751a05073c0d46ab1db87419.zip |
Rework PathDiagnostic creation so that call stacks are captured by a nested PathDiagnosticCallPiece.
llvm-svn: 151317
Diffstat (limited to 'clang/lib/StaticAnalyzer/Core/PathDiagnostic.cpp')
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/PathDiagnostic.cpp | 80 |
1 files changed, 76 insertions, 4 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/PathDiagnostic.cpp b/clang/lib/StaticAnalyzer/Core/PathDiagnostic.cpp index bc03a2bc30e..9a128ff8e2a 100644 --- a/clang/lib/StaticAnalyzer/Core/PathDiagnostic.cpp +++ b/clang/lib/StaticAnalyzer/Core/PathDiagnostic.cpp @@ -51,11 +51,10 @@ PathDiagnosticPiece::PathDiagnosticPiece(Kind k, DisplayHint hint) PathDiagnosticPiece::~PathDiagnosticPiece() {} PathDiagnosticEventPiece::~PathDiagnosticEventPiece() {} -PathDiagnosticCallEnterPiece::~PathDiagnosticCallEnterPiece() {} -PathDiagnosticCallExitPiece::~PathDiagnosticCallExitPiece() {} +PathDiagnosticCallPiece::~PathDiagnosticCallPiece() {} PathDiagnosticControlFlowPiece::~PathDiagnosticControlFlowPiece() {} PathDiagnosticMacroPiece::~PathDiagnosticMacroPiece() {} -PathDiagnostic::PathDiagnostic() {} +PathDiagnostic::PathDiagnostic() : path(pathImpl) {} PathPieces::~PathPieces() {} PathDiagnostic::~PathDiagnostic() {} @@ -63,7 +62,8 @@ PathDiagnostic::PathDiagnostic(StringRef bugtype, StringRef desc, StringRef category) : BugType(StripTrailingDots(bugtype)), Desc(StripTrailingDots(desc)), - Category(StripTrailingDots(category)) {} + Category(StripTrailingDots(category)), + path(pathImpl) {} void PathDiagnosticConsumer::anchor() { } @@ -421,6 +421,78 @@ void PathDiagnosticLocation::flatten() { } } + +//===----------------------------------------------------------------------===// +// Manipulation of PathDiagnosticCallPieces. +//===----------------------------------------------------------------------===// + +static PathDiagnosticLocation getLastStmtLoc(const ExplodedNode *N, + const SourceManager &SM) { + while (N) { + ProgramPoint PP = N->getLocation(); + if (const StmtPoint *SP = dyn_cast<StmtPoint>(&PP)) + return PathDiagnosticLocation(SP->getStmt(), SM, PP.getLocationContext()); + if (N->pred_empty()) + break; + N = *N->pred_begin(); + } + return PathDiagnosticLocation(); +} + +PathDiagnosticCallPiece * +PathDiagnosticCallPiece::construct(const ExplodedNode *N, + const CallExit &CE, + const SourceManager &SM) { + const Decl *caller = CE.getLocationContext()->getParent()->getDecl(); + PathDiagnosticLocation pos = getLastStmtLoc(N, SM); + return new PathDiagnosticCallPiece(caller, pos); +} + +PathDiagnosticCallPiece * +PathDiagnosticCallPiece::construct(PathPieces &path) { + PathDiagnosticCallPiece *C = new PathDiagnosticCallPiece(path); + path.clear(); + path.push_front(C); + return C; +} + +void PathDiagnosticCallPiece::setCallee(const CallEnter &CE, + const SourceManager &SM) { + const Decl *D = CE.getCalleeContext()->getDecl(); + Caller = D; + callEnter = PathDiagnosticLocation(CE.getCallExpr(), SM, + CE.getLocationContext()); +} + +IntrusiveRefCntPtr<PathDiagnosticEventPiece> +PathDiagnosticCallPiece::getCallEnterEvent() const { + if (!Callee) + return 0; + SmallString<256> buf; + llvm::raw_svector_ostream Out(buf); + if (isa<BlockDecl>(Callee)) + Out << "Entering call to block"; + else if (const NamedDecl *ND = dyn_cast<NamedDecl>(Callee)) + Out << "Entering call to '" << *ND << "'"; + StringRef msg = Out.str(); + if (msg.empty()) + return 0; + return new PathDiagnosticEventPiece(callEnter, msg); +} + +IntrusiveRefCntPtr<PathDiagnosticEventPiece> +PathDiagnosticCallPiece::getCallExitEvent() const { + if (!Caller) + return 0; + SmallString<256> buf; + llvm::raw_svector_ostream Out(buf); + if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(Caller)) + Out << "Returning to '" << *ND << "'"; + else + Out << "Returning to caller"; + return new PathDiagnosticEventPiece(callReturn, Out.str()); +} + //===----------------------------------------------------------------------===// // FoldingSet profiling methods. //===----------------------------------------------------------------------===// |