[analyzer] Provide useful PathDiagnosticLocations for CallEnter/Exit events.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@161277 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/StaticAnalyzer/Core/PathDiagnostic.cpp b/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
index bd898f2..c482d67 100644
--- a/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
+++ b/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
@@ -276,6 +276,44 @@
return L;
}
+static PathDiagnosticLocation
+getLocationForCaller(const StackFrameContext *SFC,
+ const LocationContext *CallerCtx,
+ const SourceManager &SM) {
+ const CFGBlock &Block = *SFC->getCallSiteBlock();
+ CFGElement Source = Block[SFC->getIndex()];
+
+ switch (Source.getKind()) {
+ case CFGElement::Invalid:
+ llvm_unreachable("Invalid CFGElement");
+ case CFGElement::Statement:
+ return PathDiagnosticLocation(cast<CFGStmt>(Source).getStmt(),
+ SM, CallerCtx);
+ case CFGElement::Initializer: {
+ const CFGInitializer &Init = cast<CFGInitializer>(Source);
+ return PathDiagnosticLocation(Init.getInitializer()->getInit(),
+ SM, CallerCtx);
+ }
+ case CFGElement::AutomaticObjectDtor: {
+ const CFGAutomaticObjDtor &Dtor = cast<CFGAutomaticObjDtor>(Source);
+ return PathDiagnosticLocation::createEnd(Dtor.getTriggerStmt(),
+ SM, CallerCtx);
+ }
+ case CFGElement::BaseDtor:
+ case CFGElement::MemberDtor: {
+ const AnalysisDeclContext *CallerInfo = CallerCtx->getAnalysisDeclContext();
+ if (const Stmt *CallerBody = CallerInfo->getBody())
+ return PathDiagnosticLocation::createEnd(CallerBody, SM, CallerCtx);
+ return PathDiagnosticLocation::create(CallerInfo->getDecl(), SM);
+ }
+ case CFGElement::TemporaryDtor:
+ llvm_unreachable("not yet implemented!");
+ }
+
+ llvm_unreachable("Unknown CFGElement kind");
+}
+
+
PathDiagnosticLocation
PathDiagnosticLocation::createBegin(const Decl *D,
const SourceManager &SM) {
@@ -360,6 +398,19 @@
else if (const PostStmt *PS = dyn_cast<PostStmt>(&P)) {
S = PS->getStmt();
}
+ else if (const PostImplicitCall *PIE = dyn_cast<PostImplicitCall>(&P)) {
+ return PathDiagnosticLocation(PIE->getLocation(), SMng);
+ }
+ else if (const CallEnter *CE = dyn_cast<CallEnter>(&P)) {
+ return getLocationForCaller(CE->getCalleeContext(),
+ CE->getLocationContext(),
+ SMng);
+ }
+ else if (const CallExitEnd *CEE = dyn_cast<CallExitEnd>(&P)) {
+ return getLocationForCaller(CEE->getCalleeContext(),
+ CEE->getLocationContext(),
+ SMng);
+ }
return PathDiagnosticLocation(S, SMng, P.getLocationContext());
}
@@ -516,43 +567,6 @@
// Manipulation of PathDiagnosticCallPieces.
//===----------------------------------------------------------------------===//
-static PathDiagnosticLocation
-getLocationForCaller(const StackFrameContext *SFC,
- const LocationContext *CallerCtx,
- const SourceManager &SM) {
- const CFGBlock &Block = *SFC->getCallSiteBlock();
- CFGElement Source = Block[SFC->getIndex()];
-
- switch (Source.getKind()) {
- case CFGElement::Invalid:
- llvm_unreachable("Invalid CFGElement");
- case CFGElement::Statement:
- return PathDiagnosticLocation(cast<CFGStmt>(Source).getStmt(),
- SM, CallerCtx);
- case CFGElement::Initializer: {
- const CFGInitializer &Init = cast<CFGInitializer>(Source);
- return PathDiagnosticLocation(Init.getInitializer()->getInit(),
- SM, CallerCtx);
- }
- case CFGElement::AutomaticObjectDtor: {
- const CFGAutomaticObjDtor &Dtor = cast<CFGAutomaticObjDtor>(Source);
- return PathDiagnosticLocation::createEnd(Dtor.getTriggerStmt(),
- SM, CallerCtx);
- }
- case CFGElement::BaseDtor:
- case CFGElement::MemberDtor: {
- const AnalysisDeclContext *CallerInfo = CallerCtx->getAnalysisDeclContext();
- if (const Stmt *CallerBody = CallerInfo->getBody())
- return PathDiagnosticLocation::createEnd(CallerBody, SM, CallerCtx);
- return PathDiagnosticLocation::create(CallerInfo->getDecl(), SM);
- }
- case CFGElement::TemporaryDtor:
- llvm_unreachable("not yet implemented!");
- }
-
- llvm_unreachable("Unknown CFGElement kind");
-}
-
PathDiagnosticCallPiece *
PathDiagnosticCallPiece::construct(const ExplodedNode *N,
const CallExitEnd &CE,