[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;
|
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,
|
||||||
|
|
Loading…
Reference in New Issue