[analyzer] Provide useful PathDiagnosticLocations for CallEnter/Exit events.

llvm-svn: 161277
This commit is contained in:
Jordan Rose 2012-08-03 23:08:44 +00:00
parent adec516f4e
commit 80880ac7ee
1 changed files with 51 additions and 37 deletions

View File

@ -276,6 +276,44 @@ static SourceLocation getValidSourceLocation(const Stmt* S,
return L; 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
PathDiagnosticLocation::createBegin(const Decl *D, PathDiagnosticLocation::createBegin(const Decl *D,
const SourceManager &SM) { const SourceManager &SM) {
@ -360,6 +398,19 @@ PathDiagnosticLocation
else if (const PostStmt *PS = dyn_cast<PostStmt>(&P)) { else if (const PostStmt *PS = dyn_cast<PostStmt>(&P)) {
S = PS->getStmt(); 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()); return PathDiagnosticLocation(S, SMng, P.getLocationContext());
} }
@ -516,43 +567,6 @@ PathDiagnosticLocation PathDiagnostic::getLocation() const {
// Manipulation of PathDiagnosticCallPieces. // 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 *
PathDiagnosticCallPiece::construct(const ExplodedNode *N, PathDiagnosticCallPiece::construct(const ExplodedNode *N,
const CallExitEnd &CE, const CallExitEnd &CE,