class CompoundStmt;
class Decl;
class LocationContext;
+class ParentMap;
class ProgramPoint;
class SourceManager;
class Stmt;
class PathDiagnosticRange : public SourceRange {
public:
- const bool isPoint;
+ bool isPoint;
PathDiagnosticRange(const SourceRange &R, bool isP = false)
: SourceRange(R), isPoint(isP) {}
+
+ PathDiagnosticRange() : isPoint(false) {}
};
class PathDiagnosticLocation {
const Decl *D;
const SourceManager *SM;
const LocationContext *LC;
+ FullSourceLoc Loc;
+ PathDiagnosticRange Range;
+
+ FullSourceLoc genLocation(const ParentMap *PM=0) const;
+ PathDiagnosticRange genRange(const ParentMap *PM=0) const;
+
public:
PathDiagnosticLocation()
- : K(SingleLocK), S(0), D(0), SM(0), LC(0) {}
+ : K(SingleLocK), S(0), D(0), SM(0), LC(0) {
+ }
PathDiagnosticLocation(FullSourceLoc L)
- : K(SingleLocK), R(L, L), S(0), D(0), SM(&L.getManager()), LC(0) {}
+ : K(SingleLocK), R(L, L), S(0), D(0), SM(&L.getManager()), LC(0),
+ Loc(genLocation()), Range(genRange()) {
+ }
PathDiagnosticLocation(SourceLocation L, const SourceManager &sm,
Kind kind = SingleLocK)
- : K(kind), R(L, L), S(0), D(0), SM(&sm), LC(0) {}
+ : K(kind), R(L, L), S(0), D(0), SM(&sm), LC(0),
+ Loc(genLocation()), Range(genRange()) {
+ }
PathDiagnosticLocation(const Stmt *s,
const SourceManager &sm,
- const LocationContext *lc)
- : K(StmtK), S(s), D(0), SM(&sm), LC(lc) {}
+ const LocationContext *lc);
PathDiagnosticLocation(const Decl *d, const SourceManager &sm)
- : K(DeclK), S(0), D(d), SM(&sm), LC(0) {}
+ : K(DeclK), S(0), D(d), SM(&sm), LC(0),
+ Loc(genLocation()), Range(genRange()) {
+ }
// Create a location for the beginning of the statement.
static PathDiagnosticLocation createBeginStmt(const Stmt *S,
return SM != 0;
}
- FullSourceLoc asLocation() const;
- PathDiagnosticRange asRange() const;
+ FullSourceLoc asLocation() const {
+ return Loc;
+ }
+
+ PathDiagnosticRange asRange() const {
+ return Range;
+ }
+
const Stmt *asStmt() const { assert(isValid()); return S; }
const Decl *asDecl() const { assert(isValid()); return D; }
//===----------------------------------------------------------------------===//
static SourceLocation getValidSourceLocation(const Stmt* S,
- const LocationContext *LC) {
- assert(LC);
+ const ParentMap &PM) {
SourceLocation L = S->getLocStart();
// S might be a temporary statement that does not have a location in the
// source code, so find an enclosing statement and use it's location.
- if (!L.isValid()) {
- ParentMap & PM = LC->getParentMap();
-
- while (!L.isValid()) {
- S = PM.getParent(S);
- L = S->getLocStart();
- }
+ while (!L.isValid()) {
+ S = PM.getParent(S);
+ L = S->getLocStart();
}
return L;
}
+PathDiagnosticLocation::PathDiagnosticLocation(const Stmt *s,
+ const SourceManager &sm,
+ const LocationContext *lc)
+ : K(StmtK), S(s), D(0), SM(&sm), LC(lc)
+{
+ const ParentMap* PM = 0;
+ if (lc)
+ PM = &lc->getParentMap();
+
+ Loc = genLocation(PM);
+ Range = genRange(PM);
+}
+
PathDiagnosticLocation
PathDiagnosticLocation::createBeginStmt(const Stmt *S,
const SourceManager &SM,
const LocationContext *LC) {
- return PathDiagnosticLocation(getValidSourceLocation(S, LC), SM, SingleLocK);
+ return PathDiagnosticLocation(getValidSourceLocation(S, LC->getParentMap()),
+ SM, SingleLocK);
}
-
PathDiagnosticLocation
PathDiagnosticLocation::createOperatorLoc(const BinaryOperator *BO,
const SourceManager &SM) {
return PathDiagnosticLocation(L, L.getManager(), SingleLocK);
}
-FullSourceLoc PathDiagnosticLocation::asLocation() const {
+FullSourceLoc
+ PathDiagnosticLocation::genLocation(const ParentMap *PM) const {
assert(isValid());
// Note that we want a 'switch' here so that the compiler can warn us in
// case we add more cases.
case RangeK:
break;
case StmtK:
- return FullSourceLoc(getValidSourceLocation(S, LC),
+ return FullSourceLoc(getValidSourceLocation(S, LC->getParentMap()),
const_cast<SourceManager&>(*SM));
case DeclK:
return FullSourceLoc(D->getLocation(), const_cast<SourceManager&>(*SM));
return FullSourceLoc(R.getBegin(), const_cast<SourceManager&>(*SM));
}
-PathDiagnosticRange PathDiagnosticLocation::asRange() const {
+PathDiagnosticRange
+ PathDiagnosticLocation::genRange(const ParentMap *PM) const {
assert(isValid());
// Note that we want a 'switch' here so that the compiler can warn us in
// case we add more cases.
case Stmt::BinaryConditionalOperatorClass:
case Stmt::ConditionalOperatorClass:
case Stmt::ObjCForCollectionStmtClass: {
- SourceLocation L = getValidSourceLocation(S, LC);
+ SourceLocation L = getValidSourceLocation(S, LC->getParentMap());
return SourceRange(L, L);
}
}