[analyzer] Provide useful PathDiagnosticLocations for CallEnter/Exit events.
llvm-svn: 161277
This commit is contained in:
parent
adec516f4e
commit
80880ac7ee
|
@ -276,6 +276,44 @@ static SourceLocation getValidSourceLocation(const Stmt* S,
|
|||
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 @@ PathDiagnosticLocation
|
|||
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 @@ PathDiagnosticLocation PathDiagnostic::getLocation() const {
|
|||
// 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,
|
||||
|
|
Loading…
Reference in New Issue