forked from OSchip/llvm-project
- Add class PathDiagosticLocationPair.
- Have PathDiagnosticControlFlowPiece use a vector of PathDiagnosticLocationPairs to represent transitions. llvm-svn: 67786
This commit is contained in:
parent
d88ebc352c
commit
46dee7b0f6
|
@ -54,22 +54,34 @@ private:
|
|||
enum Kind { Range, SingleLoc, Statement } K;
|
||||
SourceRange R;
|
||||
const Stmt *S;
|
||||
const SourceManager &SM;
|
||||
const SourceManager *SM;
|
||||
public:
|
||||
PathDiagnosticLocation(FullSourceLoc L)
|
||||
: K(SingleLoc), R(L, L), S(0), SM(L.getManager()) {}
|
||||
: K(SingleLoc), R(L, L), S(0), SM(&L.getManager()) {}
|
||||
|
||||
PathDiagnosticLocation(const Stmt *s, const SourceManager &sm)
|
||||
: K(Statement), S(s), SM(sm) {}
|
||||
: K(Statement), S(s), SM(&sm) {}
|
||||
|
||||
PathDiagnosticLocation(SourceRange r, const SourceManager &sm)
|
||||
: K(Range), R(r), S(0), SM(sm) {}
|
||||
: K(Range), R(r), S(0), SM(&sm) {}
|
||||
|
||||
FullSourceLoc asLocation() const;
|
||||
SourceRange asRange() const;
|
||||
const Stmt *asStmt() const { return S ? S : 0; }
|
||||
};
|
||||
|
||||
class PathDiagnosticLocationPair {
|
||||
private:
|
||||
PathDiagnosticLocation Start, End;
|
||||
public:
|
||||
PathDiagnosticLocationPair(const PathDiagnosticLocation &start,
|
||||
const PathDiagnosticLocation &end)
|
||||
: Start(start), End(end) {}
|
||||
|
||||
const PathDiagnosticLocation &getStart() const { return Start; }
|
||||
const PathDiagnosticLocation &getEnd() const { return End; }
|
||||
};
|
||||
|
||||
class PathDiagnostic {
|
||||
std::list<PathDiagnosticPiece*> path;
|
||||
unsigned Size;
|
||||
|
@ -302,29 +314,42 @@ public:
|
|||
};
|
||||
|
||||
class PathDiagnosticControlFlowPiece : public PathDiagnosticPiece {
|
||||
FullSourceLoc StartPos;
|
||||
SourceLocation EndPos;
|
||||
std::vector<PathDiagnosticLocationPair> LPairs;
|
||||
public:
|
||||
PathDiagnosticControlFlowPiece(FullSourceLoc startPos, SourceLocation endPos,
|
||||
PathDiagnosticControlFlowPiece(FullSourceLoc startPos, FullSourceLoc endPos,
|
||||
const std::string& s)
|
||||
: PathDiagnosticPiece(s, ControlFlow), StartPos(startPos), EndPos(endPos) {}
|
||||
: PathDiagnosticPiece(s, ControlFlow) {
|
||||
LPairs.push_back(PathDiagnosticLocationPair(startPos, endPos));
|
||||
}
|
||||
|
||||
PathDiagnosticControlFlowPiece(FullSourceLoc startPos, SourceLocation endPos,
|
||||
PathDiagnosticControlFlowPiece(FullSourceLoc startPos, FullSourceLoc endPos,
|
||||
const char* s)
|
||||
: PathDiagnosticPiece(s, ControlFlow), StartPos(startPos), EndPos(endPos) {}
|
||||
: PathDiagnosticPiece(s, ControlFlow) {
|
||||
LPairs.push_back(PathDiagnosticLocationPair(startPos, endPos));
|
||||
}
|
||||
|
||||
PathDiagnosticControlFlowPiece(FullSourceLoc startPos, SourceLocation endPos)
|
||||
: PathDiagnosticPiece(ControlFlow), StartPos(startPos), EndPos(endPos) {}
|
||||
PathDiagnosticControlFlowPiece(FullSourceLoc startPos, FullSourceLoc endPos)
|
||||
: PathDiagnosticPiece(ControlFlow) {
|
||||
LPairs.push_back(PathDiagnosticLocationPair(startPos, endPos));
|
||||
}
|
||||
|
||||
~PathDiagnosticControlFlowPiece();
|
||||
|
||||
FullSourceLoc getStartLocation() const { return StartPos; }
|
||||
FullSourceLoc getStartLocation() const {
|
||||
assert(!LPairs.empty() &&
|
||||
"PathDiagnosticControlFlowPiece needs at least one location.");
|
||||
return LPairs[0].getStart().asLocation();
|
||||
}
|
||||
|
||||
FullSourceLoc getEndLocation() const {
|
||||
return FullSourceLoc(EndPos,
|
||||
const_cast<SourceManager&>(StartPos.getManager()));
|
||||
assert(!LPairs.empty() &&
|
||||
"PathDiagnosticControlFlowPiece needs at least one location.");
|
||||
return LPairs[0].getEnd().asLocation();
|
||||
}
|
||||
|
||||
virtual FullSourceLoc getLocation() const { return StartPos; }
|
||||
void push_back(const PathDiagnosticLocationPair &X) { LPairs.push_back(X); }
|
||||
|
||||
virtual FullSourceLoc getLocation() const { return getStartLocation(); }
|
||||
|
||||
static inline bool classof(const PathDiagnosticPiece* P) {
|
||||
return P->getKind() == ControlFlow;
|
||||
|
|
|
@ -85,31 +85,31 @@ static inline Stmt* GetCurrentOrNextStmt(const ExplodedNode<GRState>* N) {
|
|||
// Diagnostics for 'execution continues on line XXX'.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
static SourceLocation ExecutionContinues(SourceManager& SMgr,
|
||||
const ExplodedNode<GRState>* N,
|
||||
const Decl& D,
|
||||
bool* OutHasStmt = 0) {
|
||||
static FullSourceLoc ExecutionContinues(SourceManager& SMgr,
|
||||
const ExplodedNode<GRState>* N,
|
||||
const Decl& D,
|
||||
bool* OutHasStmt = 0) {
|
||||
if (Stmt *S = GetNextStmt(N)) {
|
||||
if (OutHasStmt) *OutHasStmt = true;
|
||||
return S->getLocStart();
|
||||
return FullSourceLoc(S->getLocStart(), SMgr);
|
||||
}
|
||||
else {
|
||||
if (OutHasStmt) *OutHasStmt = false;
|
||||
return D.getBody()->getRBracLoc();
|
||||
return FullSourceLoc(D.getBody()->getRBracLoc(), SMgr);
|
||||
}
|
||||
}
|
||||
|
||||
static SourceLocation ExecutionContinues(llvm::raw_string_ostream& os,
|
||||
SourceManager& SMgr,
|
||||
const ExplodedNode<GRState>* N,
|
||||
const Decl& D) {
|
||||
static FullSourceLoc ExecutionContinues(llvm::raw_string_ostream& os,
|
||||
SourceManager& SMgr,
|
||||
const ExplodedNode<GRState>* N,
|
||||
const Decl& D) {
|
||||
|
||||
// Slow, but probably doesn't matter.
|
||||
if (os.str().empty())
|
||||
os << ' ';
|
||||
|
||||
bool hasStmt;
|
||||
SourceLocation Loc = ExecutionContinues(SMgr, N, D, &hasStmt);
|
||||
FullSourceLoc Loc = ExecutionContinues(SMgr, N, D, &hasStmt);
|
||||
|
||||
if (hasStmt)
|
||||
os << "Execution continues on line "
|
||||
|
@ -749,7 +749,7 @@ void GRBugReporter::GeneratePathDiagnostic(PathDiagnostic& PD,
|
|||
|
||||
std::string sbuf;
|
||||
llvm::raw_string_ostream os(sbuf);
|
||||
SourceLocation End = S->getLocStart();
|
||||
FullSourceLoc End(S->getLocStart(), SMgr);
|
||||
|
||||
os << "Control jumps to line " << SMgr.getInstantiationLineNumber(End);
|
||||
PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
|
||||
|
@ -761,10 +761,10 @@ void GRBugReporter::GeneratePathDiagnostic(PathDiagnostic& PD,
|
|||
// Figure out what case arm we took.
|
||||
std::string sbuf;
|
||||
llvm::raw_string_ostream os(sbuf);
|
||||
SourceLocation End;
|
||||
FullSourceLoc End;
|
||||
|
||||
if (Stmt* S = Dst->getLabel()) {
|
||||
End = S->getLocStart();
|
||||
End = FullSourceLoc(S->getLocStart(), SMgr);
|
||||
|
||||
switch (S->getStmtClass()) {
|
||||
default:
|
||||
|
@ -832,8 +832,8 @@ void GRBugReporter::GeneratePathDiagnostic(PathDiagnostic& PD,
|
|||
case Stmt::ContinueStmtClass: {
|
||||
std::string sbuf;
|
||||
llvm::raw_string_ostream os(sbuf);
|
||||
SourceLocation End = ExecutionContinues(os, SMgr, N,
|
||||
getStateManager().getCodeDecl());
|
||||
FullSourceLoc End =
|
||||
ExecutionContinues(os, SMgr, N, getStateManager().getCodeDecl());
|
||||
PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
|
||||
os.str()));
|
||||
break;
|
||||
|
@ -849,7 +849,7 @@ void GRBugReporter::GeneratePathDiagnostic(PathDiagnostic& PD,
|
|||
else
|
||||
os << "true";
|
||||
|
||||
SourceLocation End =
|
||||
FullSourceLoc End =
|
||||
ExecutionContinues(SMgr, N, getStateManager().getCodeDecl());
|
||||
|
||||
PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
|
||||
|
@ -863,13 +863,13 @@ void GRBugReporter::GeneratePathDiagnostic(PathDiagnostic& PD,
|
|||
llvm::raw_string_ostream os(sbuf);
|
||||
|
||||
os << "Loop condition is true. ";
|
||||
SourceLocation End =
|
||||
FullSourceLoc End =
|
||||
ExecutionContinues(os, SMgr, N, getStateManager().getCodeDecl());
|
||||
PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
|
||||
os.str()));
|
||||
}
|
||||
else {
|
||||
SourceLocation End =
|
||||
FullSourceLoc End =
|
||||
ExecutionContinues(SMgr, N, getStateManager().getCodeDecl());
|
||||
PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
|
||||
"Loop condition is false. Exiting loop"));
|
||||
|
@ -885,14 +885,14 @@ void GRBugReporter::GeneratePathDiagnostic(PathDiagnostic& PD,
|
|||
llvm::raw_string_ostream os(sbuf);
|
||||
|
||||
os << "Loop condition is false. ";
|
||||
SourceLocation End =
|
||||
FullSourceLoc End =
|
||||
ExecutionContinues(os, SMgr, N, getStateManager().getCodeDecl());
|
||||
|
||||
PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
|
||||
os.str()));
|
||||
}
|
||||
else {
|
||||
SourceLocation End =
|
||||
FullSourceLoc End =
|
||||
ExecutionContinues(SMgr, N, getStateManager().getCodeDecl());
|
||||
|
||||
PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
|
||||
|
@ -903,7 +903,7 @@ void GRBugReporter::GeneratePathDiagnostic(PathDiagnostic& PD,
|
|||
}
|
||||
|
||||
case Stmt::IfStmtClass: {
|
||||
SourceLocation End =
|
||||
FullSourceLoc End =
|
||||
ExecutionContinues(SMgr, N, getStateManager().getCodeDecl());
|
||||
|
||||
if (*(Src->succ_begin()+1) == Dst)
|
||||
|
|
|
@ -147,10 +147,10 @@ FullSourceLoc PathDiagnosticLocation::asLocation() const {
|
|||
case Range:
|
||||
break;
|
||||
case Statement:
|
||||
return FullSourceLoc(S->getLocStart(), const_cast<SourceManager&>(SM));
|
||||
return FullSourceLoc(S->getLocStart(), const_cast<SourceManager&>(*SM));
|
||||
}
|
||||
|
||||
return FullSourceLoc(R.getBegin(), const_cast<SourceManager&>(SM));
|
||||
return FullSourceLoc(R.getBegin(), const_cast<SourceManager&>(*SM));
|
||||
}
|
||||
|
||||
SourceRange PathDiagnosticLocation::asRange() const {
|
||||
|
|
Loading…
Reference in New Issue