class Decl;
class LocationContext;
+class ProgramPoint;
class SourceManager;
class Stmt;
/// Constructs a location when no specific statement is available.
/// Defaults to end of brace for the enclosing function body.
- PathDiagnosticLocation(const LocationContext *lc, const SourceManager &sm)
- : K(SingleLocK), S(0), D(0), SM(&sm), LC(lc) {}
-
+ PathDiagnosticLocation(const LocationContext *lc, const SourceManager &sm);
+
PathDiagnosticLocation(const Stmt *s,
const SourceManager &sm,
const LocationContext *lc)
PathDiagnosticLocation(const Decl *d, const SourceManager &sm)
: K(DeclK), S(0), D(d), SM(&sm), LC(0) {}
- /// Create a location corresponding to the next valid ExplodedNode.
- static PathDiagnosticLocation create(const ExplodedNode* N,
- const SourceManager &SM);
+ /// Create a location corresponding to the given valid ExplodedNode.
+ PathDiagnosticLocation(const ProgramPoint& P, const SourceManager &SMng);
+
+ /// Create a location corresponding to the next valid ExplodedNode as end
+ /// of path location.
+ static PathDiagnosticLocation createEndOfPath(const ExplodedNode* N,
+ const SourceManager &SM);
bool operator==(const PathDiagnosticLocation &X) const {
return K == X.K && R == X.R && S == X.S && D == X.D && LC == X.LC;
llvm::tie(AllocNode, FirstBinding) =
GetAllocationSite(BRC.getStateManager(), EndN, Sym);
- SourceManager& SMgr = BRC.getSourceManager();
+ SourceManager& SM = BRC.getSourceManager();
// Compute an actual location for the leak. Sometimes a leak doesn't
// occur at an actual statement (e.g., transition between blocks; end
// of function) so we need to walk the graph and compute a real location.
const ExplodedNode *LeakN = EndN;
- PathDiagnosticLocation L = PathDiagnosticLocation::create(LeakN, SMgr);
+ PathDiagnosticLocation L = PathDiagnosticLocation::createEndOfPath(LeakN, SM);
std::string sbuf;
llvm::raw_string_ostream os(sbuf);
return NULL;
}
- // FIXME: Refactor this into BugReporterContext.
- const Stmt *S = 0;
+ // Construct a new PathDiagnosticPiece.
ProgramPoint P = N->getLocation();
-
- if (BlockEdge *BE = dyn_cast<BlockEdge>(&P)) {
- const CFGBlock *BSrc = BE->getSrc();
- S = BSrc->getTerminatorCondition();
- }
- else if (PostStmt *PS = dyn_cast<PostStmt>(&P)) {
- S = PS->getStmt();
- }
-
- if (!S)
+ PathDiagnosticLocation L = PathDiagnosticLocation(P,BRC.getSourceManager());
+ if (!L.isValid())
return NULL;
-
- // Construct a new PathDiagnosticPiece.
- PathDiagnosticLocation L(S, BRC.getSourceManager(), P.getLocationContext());
return new PathDiagnosticEventPiece(L, os.str());
}
if (os.str().empty())
return NULL;
- // FIXME: Refactor this into BugReporterContext.
- const Stmt *S = 0;
+ // Construct a new PathDiagnosticPiece.
ProgramPoint P = N->getLocation();
-
- if (BlockEdge *BE = dyn_cast<BlockEdge>(&P)) {
- const CFGBlock *BSrc = BE->getSrc();
- S = BSrc->getTerminatorCondition();
- }
- else if (PostStmt *PS = dyn_cast<PostStmt>(&P)) {
- S = PS->getStmt();
- }
-
- if (!S)
+ PathDiagnosticLocation L = PathDiagnosticLocation(P,BRC.getSourceManager());
+ if (!L.isValid())
return NULL;
-
- // Construct a new PathDiagnosticPiece.
- PathDiagnosticLocation L(S, BRC.getSourceManager(), P.getLocationContext());
return new PathDiagnosticEventPiece(L, os.str());
}
// PathDiagnosticLocation methods.
//===----------------------------------------------------------------------===//
-PathDiagnosticLocation PathDiagnosticLocation::create(const ExplodedNode* N,
+PathDiagnosticLocation::PathDiagnosticLocation(const LocationContext *lc,
+ const SourceManager &sm)
+ : K(RangeK), S(0), D(0), SM(&sm), LC(lc) {
+ SourceLocation L = LC->getDecl()->getBodyRBrace();
+ R = SourceRange(L, L);
+}
+
+PathDiagnosticLocation::PathDiagnosticLocation(const ProgramPoint& P,
+ const SourceManager &SMng)
+ : K(StmtK), S(0), D(0), SM(&SMng), LC(P.getLocationContext()) {
+
+ if (const BlockEdge *BE = dyn_cast<BlockEdge>(&P)) {
+ const CFGBlock *BSrc = BE->getSrc();
+ S = BSrc->getTerminatorCondition();
+ }
+ else if (const PostStmt *PS = dyn_cast<PostStmt>(&P)) {
+ S = PS->getStmt();
+ }
+
+ if (!S)
+ invalidate();
+}
+
+PathDiagnosticLocation PathDiagnosticLocation::createEndOfPath(
+ const ExplodedNode* N,
const SourceManager &SM) {
assert(N && "Cannot create a location with a null node.");
NI = NI->succ_empty() ? 0 : *(NI->succ_begin());
}
- const Decl &D = N->getCodeDecl();
- return PathDiagnosticLocation(D.getBodyRBrace(), SM);
+ return PathDiagnosticLocation(N->getLocationContext(), SM);
}
static SourceLocation getValidSourceLocation(const Stmt* S,
return FullSourceLoc(D->getLocation(), const_cast<SourceManager&>(*SM));
}
- if (!R.isValid())
- return FullSourceLoc(LC->getDecl()->getBodyRBrace(),
- const_cast<SourceManager&>(*SM));
-
return FullSourceLoc(R.getBegin(), const_cast<SourceManager&>(*SM));
}