forked from OSchip/llvm-project
Change PathDiagnosticPieces to be reference counted (simplifying their management), and introduce 'PathPieces' as a common container for PathDiagnosticPieces.
llvm-svn: 150054
This commit is contained in:
parent
3116c4e5cd
commit
afa6e249cb
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include "clang/Basic/SourceLocation.h"
|
||||
#include "llvm/ADT/FoldingSet.h"
|
||||
#include "llvm/ADT/IntrusiveRefCntPtr.h"
|
||||
#include "llvm/ADT/PointerUnion.h"
|
||||
#include <deque>
|
||||
#include <iterator>
|
||||
|
@ -44,12 +45,6 @@ class ExplodedNode;
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
class PathDiagnostic;
|
||||
class PathDiagnosticPiece;
|
||||
|
||||
class PathPieces : public std::deque<PathDiagnosticPiece *> {
|
||||
public:
|
||||
~PathPieces();
|
||||
};
|
||||
|
||||
class PathDiagnosticConsumer {
|
||||
virtual void anchor();
|
||||
|
@ -265,7 +260,7 @@ public:
|
|||
// Path "pieces" for path-sensitive diagnostics.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
class PathDiagnosticPiece {
|
||||
class PathDiagnosticPiece : public llvm::RefCountedBaseVPTR {
|
||||
public:
|
||||
enum Kind { ControlFlow, Event, Macro, CallEnter, CallExit };
|
||||
enum DisplayHint { Above, Below };
|
||||
|
@ -328,6 +323,13 @@ public:
|
|||
|
||||
virtual void Profile(llvm::FoldingSetNodeID &ID) const;
|
||||
};
|
||||
|
||||
|
||||
class PathPieces :
|
||||
public std::deque<llvm::IntrusiveRefCntPtr<PathDiagnosticPiece> > {
|
||||
public:
|
||||
~PathPieces();
|
||||
};
|
||||
|
||||
class PathDiagnosticSpotPiece : public PathDiagnosticPiece {
|
||||
private:
|
||||
|
@ -446,30 +448,22 @@ public:
|
|||
};
|
||||
|
||||
class PathDiagnosticMacroPiece : public PathDiagnosticSpotPiece {
|
||||
std::vector<PathDiagnosticPiece*> SubPieces;
|
||||
public:
|
||||
PathDiagnosticMacroPiece(const PathDiagnosticLocation &pos)
|
||||
: PathDiagnosticSpotPiece(pos, "", Macro) {}
|
||||
|
||||
~PathDiagnosticMacroPiece();
|
||||
|
||||
PathPieces subPieces;
|
||||
|
||||
bool containsEvent() const;
|
||||
|
||||
void push_back(PathDiagnosticPiece *P) { SubPieces.push_back(P); }
|
||||
|
||||
typedef std::vector<PathDiagnosticPiece*>::iterator iterator;
|
||||
iterator begin() { return SubPieces.begin(); }
|
||||
iterator end() { return SubPieces.end(); }
|
||||
|
||||
virtual void flattenLocations() {
|
||||
PathDiagnosticSpotPiece::flattenLocations();
|
||||
for (iterator I=begin(), E=end(); I!=E; ++I) (*I)->flattenLocations();
|
||||
for (PathPieces::iterator I = subPieces.begin(),
|
||||
E = subPieces.end(); I != E; ++I) (*I)->flattenLocations();
|
||||
}
|
||||
|
||||
typedef std::vector<PathDiagnosticPiece*>::const_iterator const_iterator;
|
||||
const_iterator begin() const { return SubPieces.begin(); }
|
||||
const_iterator end() const { return SubPieces.end(); }
|
||||
|
||||
static inline bool classof(const PathDiagnosticPiece *P) {
|
||||
return P->getKind() == Macro;
|
||||
}
|
||||
|
@ -481,16 +475,14 @@ public:
|
|||
/// diagnostic. It represents an ordered-collection of PathDiagnosticPieces,
|
||||
/// each which represent the pieces of the path.
|
||||
class PathDiagnostic : public llvm::FoldingSetNode {
|
||||
PathPieces path;
|
||||
unsigned Size;
|
||||
std::string BugType;
|
||||
std::string Desc;
|
||||
std::string Category;
|
||||
std::deque<std::string> OtherDesc;
|
||||
|
||||
public:
|
||||
PathDiagnostic();
|
||||
PathPieces path;
|
||||
|
||||
PathDiagnostic();
|
||||
PathDiagnostic(StringRef bugtype, StringRef desc,
|
||||
StringRef category);
|
||||
|
||||
|
@ -499,6 +491,7 @@ public:
|
|||
StringRef getDescription() const { return Desc; }
|
||||
StringRef getBugType() const { return BugType; }
|
||||
StringRef getCategory() const { return Category; }
|
||||
|
||||
|
||||
typedef std::deque<std::string>::const_iterator meta_iterator;
|
||||
meta_iterator meta_begin() const { return OtherDesc.begin(); }
|
||||
|
@ -506,106 +499,14 @@ public:
|
|||
void addMeta(StringRef s) { OtherDesc.push_back(s); }
|
||||
|
||||
PathDiagnosticLocation getLocation() const {
|
||||
assert(Size > 0 && "getLocation() requires a non-empty PathDiagnostic.");
|
||||
return rbegin()->getLocation();
|
||||
assert(path.size() > 0 &&
|
||||
"getLocation() requires a non-empty PathDiagnostic.");
|
||||
return (*path.rbegin())->getLocation();
|
||||
}
|
||||
|
||||
void push_front(PathDiagnosticPiece *piece) {
|
||||
assert(piece);
|
||||
path.push_front(piece);
|
||||
++Size;
|
||||
}
|
||||
|
||||
void push_back(PathDiagnosticPiece *piece) {
|
||||
assert(piece);
|
||||
path.push_back(piece);
|
||||
++Size;
|
||||
}
|
||||
|
||||
PathDiagnosticPiece *back() {
|
||||
return path.back();
|
||||
}
|
||||
|
||||
const PathDiagnosticPiece *back() const {
|
||||
return path.back();
|
||||
}
|
||||
|
||||
unsigned size() const { return Size; }
|
||||
bool empty() const { return Size == 0; }
|
||||
|
||||
void resetPath(bool deletePieces = true);
|
||||
|
||||
class iterator {
|
||||
public:
|
||||
typedef std::deque<PathDiagnosticPiece*>::iterator ImplTy;
|
||||
|
||||
typedef PathDiagnosticPiece value_type;
|
||||
typedef value_type& reference;
|
||||
typedef value_type* pointer;
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef std::bidirectional_iterator_tag iterator_category;
|
||||
|
||||
private:
|
||||
ImplTy I;
|
||||
|
||||
public:
|
||||
iterator(const ImplTy& i) : I(i) {}
|
||||
|
||||
bool operator==(const iterator &X) const { return I == X.I; }
|
||||
bool operator!=(const iterator &X) const { return I != X.I; }
|
||||
|
||||
PathDiagnosticPiece& operator*() const { return **I; }
|
||||
PathDiagnosticPiece *operator->() const { return *I; }
|
||||
|
||||
iterator &operator++() { ++I; return *this; }
|
||||
iterator &operator--() { --I; return *this; }
|
||||
};
|
||||
|
||||
class const_iterator {
|
||||
public:
|
||||
typedef std::deque<PathDiagnosticPiece*>::const_iterator ImplTy;
|
||||
|
||||
typedef const PathDiagnosticPiece value_type;
|
||||
typedef value_type& reference;
|
||||
typedef value_type* pointer;
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef std::bidirectional_iterator_tag iterator_category;
|
||||
|
||||
private:
|
||||
ImplTy I;
|
||||
|
||||
public:
|
||||
const_iterator(const ImplTy& i) : I(i) {}
|
||||
|
||||
bool operator==(const const_iterator &X) const { return I == X.I; }
|
||||
bool operator!=(const const_iterator &X) const { return I != X.I; }
|
||||
|
||||
reference operator*() const { return **I; }
|
||||
pointer operator->() const { return *I; }
|
||||
|
||||
const_iterator &operator++() { ++I; return *this; }
|
||||
const_iterator &operator--() { --I; return *this; }
|
||||
};
|
||||
|
||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
|
||||
// forward iterator creation methods.
|
||||
|
||||
iterator begin() { return path.begin(); }
|
||||
iterator end() { return path.end(); }
|
||||
|
||||
const_iterator begin() const { return path.begin(); }
|
||||
const_iterator end() const { return path.end(); }
|
||||
|
||||
// reverse iterator creation methods.
|
||||
reverse_iterator rbegin() { return reverse_iterator(end()); }
|
||||
const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); }
|
||||
reverse_iterator rend() { return reverse_iterator(begin()); }
|
||||
const_reverse_iterator rend() const { return const_reverse_iterator(begin());}
|
||||
|
||||
void flattenLocations() {
|
||||
for (iterator I = begin(), E = end(); I != E; ++I) I->flattenLocations();
|
||||
for (PathPieces::iterator I = path.begin(), E = path.end();
|
||||
I != E; ++I) (*I)->flattenLocations();
|
||||
}
|
||||
|
||||
void Profile(llvm::FoldingSetNodeID &ID) const;
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/OwningPtr.h"
|
||||
#include "llvm/ADT/IntrusiveRefCntPtr.h"
|
||||
#include <queue>
|
||||
|
||||
using namespace clang;
|
||||
|
@ -446,7 +447,7 @@ public:
|
|||
PathDiagnosticLocation L =
|
||||
PathDiagnosticLocation::createBegin(S, BR.getSourceManager(),
|
||||
Pred->getLocationContext());
|
||||
PD.push_front(new PathDiagnosticEventPiece(L, os.str()));
|
||||
PD.path.push_front(new PathDiagnosticEventPiece(L, os.str()));
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -558,8 +559,8 @@ static void GenerateMinimalPathDiagnostic(PathDiagnostic& PD,
|
|||
|
||||
os << "Control jumps to line "
|
||||
<< End.asLocation().getExpansionLineNumber();
|
||||
PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
|
||||
os.str()));
|
||||
PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End,
|
||||
os.str()));
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -610,13 +611,13 @@ static void GenerateMinimalPathDiagnostic(PathDiagnostic& PD,
|
|||
break;
|
||||
}
|
||||
}
|
||||
PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
|
||||
PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End,
|
||||
os.str()));
|
||||
}
|
||||
else {
|
||||
os << "'Default' branch taken. ";
|
||||
const PathDiagnosticLocation &End = PDB.ExecutionContinues(os, N);
|
||||
PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
|
||||
PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End,
|
||||
os.str()));
|
||||
}
|
||||
|
||||
|
@ -628,7 +629,7 @@ static void GenerateMinimalPathDiagnostic(PathDiagnostic& PD,
|
|||
std::string sbuf;
|
||||
llvm::raw_string_ostream os(sbuf);
|
||||
PathDiagnosticLocation End = PDB.ExecutionContinues(os, N);
|
||||
PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
|
||||
PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End,
|
||||
os.str()));
|
||||
break;
|
||||
}
|
||||
|
@ -650,7 +651,7 @@ static void GenerateMinimalPathDiagnostic(PathDiagnostic& PD,
|
|||
if (const Stmt *S = End.asStmt())
|
||||
End = PDB.getEnclosingStmtLocation(S);
|
||||
|
||||
PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
|
||||
PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End,
|
||||
os.str()));
|
||||
break;
|
||||
}
|
||||
|
@ -673,14 +674,14 @@ static void GenerateMinimalPathDiagnostic(PathDiagnostic& PD,
|
|||
PathDiagnosticLocation End(B->getLHS(), SMgr, LC);
|
||||
PathDiagnosticLocation Start =
|
||||
PathDiagnosticLocation::createOperatorLoc(B, SMgr);
|
||||
PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
|
||||
PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End,
|
||||
os.str()));
|
||||
}
|
||||
else {
|
||||
os << "true";
|
||||
PathDiagnosticLocation Start(B->getLHS(), SMgr, LC);
|
||||
PathDiagnosticLocation End = PDB.ExecutionContinues(N);
|
||||
PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
|
||||
PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End,
|
||||
os.str()));
|
||||
}
|
||||
}
|
||||
|
@ -692,7 +693,7 @@ static void GenerateMinimalPathDiagnostic(PathDiagnostic& PD,
|
|||
os << "false";
|
||||
PathDiagnosticLocation Start(B->getLHS(), SMgr, LC);
|
||||
PathDiagnosticLocation End = PDB.ExecutionContinues(N);
|
||||
PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
|
||||
PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End,
|
||||
os.str()));
|
||||
}
|
||||
else {
|
||||
|
@ -700,7 +701,7 @@ static void GenerateMinimalPathDiagnostic(PathDiagnostic& PD,
|
|||
PathDiagnosticLocation End(B->getLHS(), SMgr, LC);
|
||||
PathDiagnosticLocation Start =
|
||||
PathDiagnosticLocation::createOperatorLoc(B, SMgr);
|
||||
PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
|
||||
PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End,
|
||||
os.str()));
|
||||
}
|
||||
}
|
||||
|
@ -719,7 +720,7 @@ static void GenerateMinimalPathDiagnostic(PathDiagnostic& PD,
|
|||
if (const Stmt *S = End.asStmt())
|
||||
End = PDB.getEnclosingStmtLocation(S);
|
||||
|
||||
PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
|
||||
PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End,
|
||||
os.str()));
|
||||
}
|
||||
else {
|
||||
|
@ -728,7 +729,7 @@ static void GenerateMinimalPathDiagnostic(PathDiagnostic& PD,
|
|||
if (const Stmt *S = End.asStmt())
|
||||
End = PDB.getEnclosingStmtLocation(S);
|
||||
|
||||
PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
|
||||
PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End,
|
||||
"Loop condition is false. Exiting loop"));
|
||||
}
|
||||
|
||||
|
@ -746,7 +747,7 @@ static void GenerateMinimalPathDiagnostic(PathDiagnostic& PD,
|
|||
if (const Stmt *S = End.asStmt())
|
||||
End = PDB.getEnclosingStmtLocation(S);
|
||||
|
||||
PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
|
||||
PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End,
|
||||
os.str()));
|
||||
}
|
||||
else {
|
||||
|
@ -754,7 +755,7 @@ static void GenerateMinimalPathDiagnostic(PathDiagnostic& PD,
|
|||
if (const Stmt *S = End.asStmt())
|
||||
End = PDB.getEnclosingStmtLocation(S);
|
||||
|
||||
PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
|
||||
PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End,
|
||||
"Loop condition is true. Entering loop body"));
|
||||
}
|
||||
|
||||
|
@ -768,10 +769,10 @@ static void GenerateMinimalPathDiagnostic(PathDiagnostic& PD,
|
|||
End = PDB.getEnclosingStmtLocation(S);
|
||||
|
||||
if (*(Src->succ_begin()+1) == Dst)
|
||||
PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
|
||||
PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End,
|
||||
"Taking false branch"));
|
||||
else
|
||||
PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
|
||||
PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End,
|
||||
"Taking true branch"));
|
||||
|
||||
break;
|
||||
|
@ -785,7 +786,7 @@ static void GenerateMinimalPathDiagnostic(PathDiagnostic& PD,
|
|||
for (BugReport::visitor_iterator I = R->visitor_begin(),
|
||||
E = R->visitor_end(); I!=E; ++I) {
|
||||
if (PathDiagnosticPiece *p = (*I)->VisitNode(N, NextNode, PDB, *R))
|
||||
PD.push_front(p);
|
||||
PD.path.push_front(p);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -906,8 +907,8 @@ public:
|
|||
|
||||
// If the PathDiagnostic already has pieces, add the enclosing statement
|
||||
// of the first piece as a context as well.
|
||||
if (!PD.empty()) {
|
||||
PrevLoc = PD.begin()->getLocation();
|
||||
if (!PD.path.empty()) {
|
||||
PrevLoc = (*PD.path.begin())->getLocation();
|
||||
|
||||
if (const Stmt *S = PrevLoc.asStmt())
|
||||
addExtendedContext(PDB.getEnclosingStmtLocation(S).asStmt());
|
||||
|
@ -1018,7 +1019,7 @@ void EdgeBuilder::rawAddEdge(PathDiagnosticLocation NewLoc) {
|
|||
PrevLocClean.asLocation().getExpansionLoc())
|
||||
return;
|
||||
|
||||
PD.push_front(new PathDiagnosticControlFlowPiece(NewLocClean, PrevLocClean));
|
||||
PD.path.push_front(new PathDiagnosticControlFlowPiece(NewLocClean, PrevLocClean));
|
||||
PrevLoc = NewLoc;
|
||||
}
|
||||
|
||||
|
@ -1178,7 +1179,7 @@ static void GenerateExtensivePathDiagnostic(PathDiagnostic& PD,
|
|||
"Looping back to the head of the loop");
|
||||
|
||||
EB.addEdge(p->getLocation(), true);
|
||||
PD.push_front(p);
|
||||
PD.path.push_front(p);
|
||||
|
||||
if (CS) {
|
||||
PathDiagnosticLocation BL =
|
||||
|
@ -1220,7 +1221,7 @@ static void GenerateExtensivePathDiagnostic(PathDiagnostic& PD,
|
|||
if (PathDiagnosticPiece *p = (*I)->VisitNode(N, NextNode, PDB, *R)) {
|
||||
const PathDiagnosticLocation &Loc = p->getLocation();
|
||||
EB.addEdge(Loc, true);
|
||||
PD.push_front(p);
|
||||
PD.path.push_front(p);
|
||||
if (const Stmt *S = Loc.asStmt())
|
||||
EB.addExtendedContext(PDB.getEnclosingStmtLocation(S).asStmt());
|
||||
}
|
||||
|
@ -1549,18 +1550,18 @@ MakeReportGraph(const ExplodedGraph* G,
|
|||
/// CompactPathDiagnostic - This function postprocesses a PathDiagnostic object
|
||||
/// and collapses PathDiagosticPieces that are expanded by macros.
|
||||
static void CompactPathDiagnostic(PathDiagnostic &PD, const SourceManager& SM) {
|
||||
typedef std::vector<std::pair<PathDiagnosticMacroPiece*, SourceLocation> >
|
||||
typedef std::vector<std::pair<llvm::IntrusiveRefCntPtr<PathDiagnosticMacroPiece>, SourceLocation> >
|
||||
MacroStackTy;
|
||||
|
||||
typedef std::vector<PathDiagnosticPiece*>
|
||||
typedef std::vector<llvm::IntrusiveRefCntPtr<PathDiagnosticPiece> >
|
||||
PiecesTy;
|
||||
|
||||
MacroStackTy MacroStack;
|
||||
PiecesTy Pieces;
|
||||
|
||||
for (PathDiagnostic::iterator I = PD.begin(), E = PD.end(); I!=E; ++I) {
|
||||
for (PathPieces::iterator I = PD.path.begin(), E = PD.path.end(); I!=E; ++I) {
|
||||
// Get the location of the PathDiagnosticPiece.
|
||||
const FullSourceLoc Loc = I->getLocation().asLocation();
|
||||
const FullSourceLoc Loc = (*I)->getLocation().asLocation();
|
||||
|
||||
// Determine the instantiation location, which is the location we group
|
||||
// related PathDiagnosticPieces.
|
||||
|
@ -1570,7 +1571,7 @@ static void CompactPathDiagnostic(PathDiagnostic &PD, const SourceManager& SM) {
|
|||
|
||||
if (Loc.isFileID()) {
|
||||
MacroStack.clear();
|
||||
Pieces.push_back(&*I);
|
||||
Pieces.push_back(*I);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1578,13 +1579,13 @@ static void CompactPathDiagnostic(PathDiagnostic &PD, const SourceManager& SM) {
|
|||
|
||||
// Is the PathDiagnosticPiece within the same macro group?
|
||||
if (!MacroStack.empty() && InstantiationLoc == MacroStack.back().second) {
|
||||
MacroStack.back().first->push_back(&*I);
|
||||
MacroStack.back().first->subPieces.push_back(*I);
|
||||
continue;
|
||||
}
|
||||
|
||||
// We aren't in the same group. Are we descending into a new macro
|
||||
// or are part of an old one?
|
||||
PathDiagnosticMacroPiece *MacroGroup = 0;
|
||||
llvm::IntrusiveRefCntPtr<PathDiagnosticMacroPiece> MacroGroup;
|
||||
|
||||
SourceLocation ParentInstantiationLoc = InstantiationLoc.isMacroID() ?
|
||||
SM.getExpansionLoc(Loc) :
|
||||
|
@ -1609,10 +1610,10 @@ static void CompactPathDiagnostic(PathDiagnostic &PD, const SourceManager& SM) {
|
|||
// Create a new macro group and add it to the stack.
|
||||
PathDiagnosticMacroPiece *NewGroup =
|
||||
new PathDiagnosticMacroPiece(
|
||||
PathDiagnosticLocation::createSingleLocation(I->getLocation()));
|
||||
PathDiagnosticLocation::createSingleLocation((*I)->getLocation()));
|
||||
|
||||
if (MacroGroup)
|
||||
MacroGroup->push_back(NewGroup);
|
||||
MacroGroup->subPieces.push_back(NewGroup);
|
||||
else {
|
||||
assert(InstantiationLoc.isFileID());
|
||||
Pieces.push_back(NewGroup);
|
||||
|
@ -1623,11 +1624,11 @@ static void CompactPathDiagnostic(PathDiagnostic &PD, const SourceManager& SM) {
|
|||
}
|
||||
|
||||
// Finally, add the PathDiagnosticPiece to the group.
|
||||
MacroGroup->push_back(&*I);
|
||||
MacroGroup->subPieces.push_back(*I);
|
||||
}
|
||||
|
||||
// Now take the pieces and construct a new PathDiagnostic.
|
||||
PD.resetPath(false);
|
||||
PD.path.clear();
|
||||
|
||||
for (PiecesTy::iterator I=Pieces.begin(), E=Pieces.end(); I!=E; ++I) {
|
||||
if (PathDiagnosticMacroPiece *MP=dyn_cast<PathDiagnosticMacroPiece>(*I))
|
||||
|
@ -1636,7 +1637,7 @@ static void CompactPathDiagnostic(PathDiagnostic &PD, const SourceManager& SM) {
|
|||
continue;
|
||||
}
|
||||
|
||||
PD.push_back(*I);
|
||||
PD.path.push_back(*I);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1692,7 +1693,7 @@ void GRBugReporter::GeneratePathDiagnostic(PathDiagnostic& PD,
|
|||
if (!LastPiece)
|
||||
LastPiece = BugReporterVisitor::getDefaultEndPath(PDB, N, *R);
|
||||
if (LastPiece)
|
||||
PD.push_back(LastPiece);
|
||||
PD.path.push_back(LastPiece);
|
||||
else
|
||||
return;
|
||||
|
||||
|
@ -1951,13 +1952,13 @@ void BugReporter::FlushReport(BugReportEquivClass& EQ) {
|
|||
if (!PD)
|
||||
return;
|
||||
|
||||
if (D->empty()) {
|
||||
if (D->path.empty()) {
|
||||
PathDiagnosticPiece *piece = new PathDiagnosticEventPiece(
|
||||
exampleReport->getLocation(getSourceManager()),
|
||||
exampleReport->getDescription());
|
||||
|
||||
for ( ; Beg != End; ++Beg) piece->addRange(*Beg);
|
||||
D->push_back(piece);
|
||||
D->path.push_back(piece);
|
||||
}
|
||||
|
||||
PD->HandlePathDiagnostic(D.take());
|
||||
|
|
|
@ -119,12 +119,13 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D,
|
|||
if (noDir)
|
||||
return;
|
||||
|
||||
const SourceManager &SMgr = D.begin()->getLocation().getManager();
|
||||
const SourceManager &SMgr = (*D.path.begin())->getLocation().getManager();
|
||||
FileID FID;
|
||||
|
||||
// Verify that the entire path is from the same FileID.
|
||||
for (PathDiagnostic::const_iterator I = D.begin(), E = D.end(); I != E; ++I) {
|
||||
FullSourceLoc L = I->getLocation().asLocation().getExpansionLoc();
|
||||
for (PathPieces::const_iterator I = D.path.begin(), E = D.path.end();
|
||||
I != E; ++I) {
|
||||
FullSourceLoc L = (*I)->getLocation().asLocation().getExpansionLoc();
|
||||
|
||||
if (FID.isInvalid()) {
|
||||
FID = SMgr.getFileID(L);
|
||||
|
@ -132,16 +133,13 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D,
|
|||
return; // FIXME: Emit a warning?
|
||||
|
||||
// Check the source ranges.
|
||||
for (PathDiagnosticPiece::range_iterator RI=I->ranges_begin(),
|
||||
RE=I->ranges_end(); RI!=RE; ++RI) {
|
||||
|
||||
for (PathDiagnosticPiece::range_iterator RI = (*I)->ranges_begin(),
|
||||
RE = (*I)->ranges_end();
|
||||
RI != RE; ++RI) {
|
||||
SourceLocation L = SMgr.getExpansionLoc(RI->getBegin());
|
||||
|
||||
if (!L.isFileID() || SMgr.getFileID(L) != FID)
|
||||
return; // FIXME: Emit a warning?
|
||||
|
||||
L = SMgr.getExpansionLoc(RI->getEnd());
|
||||
|
||||
if (!L.isFileID() || SMgr.getFileID(L) != FID)
|
||||
return; // FIXME: Emit a warning?
|
||||
}
|
||||
|
@ -154,12 +152,12 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D,
|
|||
Rewriter R(const_cast<SourceManager&>(SMgr), PP.getLangOptions());
|
||||
|
||||
// Process the path.
|
||||
unsigned n = D.size();
|
||||
unsigned n = D.path.size();
|
||||
unsigned max = n;
|
||||
|
||||
for (PathDiagnostic::const_reverse_iterator I=D.rbegin(), E=D.rend();
|
||||
I!=E; ++I, --n)
|
||||
HandlePiece(R, FID, *I, n, max);
|
||||
for (PathPieces::const_reverse_iterator I = D.path.rbegin(), E=D.path.rend();
|
||||
I != E; ++I, --n)
|
||||
HandlePiece(R, FID, **I, n, max);
|
||||
|
||||
// Add line numbers, header, footer, etc.
|
||||
|
||||
|
@ -202,9 +200,9 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D,
|
|||
<< html::EscapeText(Entry->getName())
|
||||
<< "</td></tr>\n<tr><td class=\"rowname\">Location:</td><td>"
|
||||
"<a href=\"#EndPath\">line "
|
||||
<< (*D.rbegin()).getLocation().asLocation().getExpansionLineNumber()
|
||||
<< (*D.path.rbegin())->getLocation().asLocation().getExpansionLineNumber()
|
||||
<< ", column "
|
||||
<< (*D.rbegin()).getLocation().asLocation().getExpansionColumnNumber()
|
||||
<< (*D.path.rbegin())->getLocation().asLocation().getExpansionColumnNumber()
|
||||
<< "</a></td></tr>\n"
|
||||
"<tr><td class=\"rowname\">Description:</td><td>"
|
||||
<< D.getDescription() << "</td></tr>\n";
|
||||
|
@ -242,10 +240,10 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D,
|
|||
os << "\n<!-- BUGFILE " << DirName << Entry->getName() << " -->\n";
|
||||
|
||||
os << "\n<!-- BUGLINE "
|
||||
<< D.back()->getLocation().asLocation().getExpansionLineNumber()
|
||||
<< D.path.back()->getLocation().asLocation().getExpansionLineNumber()
|
||||
<< " -->\n";
|
||||
|
||||
os << "\n<!-- BUGPATHLENGTH " << D.size() << " -->\n";
|
||||
os << "\n<!-- BUGPATHLENGTH " << D.path.size() << " -->\n";
|
||||
|
||||
// Mark the end of the tags.
|
||||
os << "\n<!-- BUGMETAEND -->\n";
|
||||
|
@ -501,7 +499,7 @@ unsigned HTMLDiagnostics::ProcessMacroPiece(raw_ostream &os,
|
|||
const PathDiagnosticMacroPiece& P,
|
||||
unsigned num) {
|
||||
|
||||
for (PathDiagnosticMacroPiece::const_iterator I=P.begin(), E=P.end();
|
||||
for (PathPieces::const_iterator I = P.subPieces.begin(), E=P.subPieces.end();
|
||||
I!=E; ++I) {
|
||||
|
||||
if (const PathDiagnosticMacroPiece *MP =
|
||||
|
|
|
@ -24,15 +24,14 @@ using namespace clang;
|
|||
using namespace ento;
|
||||
|
||||
bool PathDiagnosticMacroPiece::containsEvent() const {
|
||||
for (const_iterator I = begin(), E = end(); I!=E; ++I) {
|
||||
for (PathPieces::const_iterator I = subPieces.begin(), E = subPieces.end();
|
||||
I!=E; ++I) {
|
||||
if (isa<PathDiagnosticEventPiece>(*I))
|
||||
return true;
|
||||
|
||||
if (PathDiagnosticMacroPiece *MP = dyn_cast<PathDiagnosticMacroPiece>(*I))
|
||||
if (MP->containsEvent())
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -55,34 +54,14 @@ PathDiagnosticEventPiece::~PathDiagnosticEventPiece() {}
|
|||
PathDiagnosticCallEnterPiece::~PathDiagnosticCallEnterPiece() {}
|
||||
PathDiagnosticCallExitPiece::~PathDiagnosticCallExitPiece() {}
|
||||
PathDiagnosticControlFlowPiece::~PathDiagnosticControlFlowPiece() {}
|
||||
|
||||
PathDiagnosticMacroPiece::~PathDiagnosticMacroPiece() {
|
||||
for (iterator I = begin(), E = end(); I != E; ++I) delete *I;
|
||||
}
|
||||
|
||||
PathDiagnostic::PathDiagnostic() : Size(0) {}
|
||||
|
||||
PathPieces::~PathPieces() {
|
||||
for (iterator I = begin(), E = end(); I != E; ++I) delete *I;
|
||||
}
|
||||
|
||||
PathDiagnosticMacroPiece::~PathDiagnosticMacroPiece() {}
|
||||
PathDiagnostic::PathDiagnostic() {}
|
||||
PathPieces::~PathPieces() {}
|
||||
PathDiagnostic::~PathDiagnostic() {}
|
||||
|
||||
void PathDiagnostic::resetPath(bool deletePieces) {
|
||||
Size = 0;
|
||||
|
||||
if (deletePieces)
|
||||
for (iterator I=begin(), E=end(); I!=E; ++I)
|
||||
delete &*I;
|
||||
|
||||
path.clear();
|
||||
}
|
||||
|
||||
|
||||
PathDiagnostic::PathDiagnostic(StringRef bugtype, StringRef desc,
|
||||
StringRef category)
|
||||
: Size(0),
|
||||
BugType(StripTrailingDots(bugtype)),
|
||||
: BugType(StripTrailingDots(bugtype)),
|
||||
Desc(StripTrailingDots(desc)),
|
||||
Category(StripTrailingDots(category)) {}
|
||||
|
||||
|
@ -100,7 +79,7 @@ void PathDiagnosticConsumer::HandlePathDiagnostic(PathDiagnostic *D) {
|
|||
if (!D)
|
||||
return;
|
||||
|
||||
if (D->empty()) {
|
||||
if (D->path.empty()) {
|
||||
delete D;
|
||||
return;
|
||||
}
|
||||
|
@ -117,9 +96,9 @@ void PathDiagnosticConsumer::HandlePathDiagnostic(PathDiagnostic *D) {
|
|||
|
||||
if (PathDiagnostic *orig = Diags.FindNodeOrInsertPos(profile, InsertPos)) {
|
||||
// Keep the PathDiagnostic with the shorter path.
|
||||
if (orig->size() <= D->size()) {
|
||||
if (orig->path.size() <= D->path.size()) {
|
||||
bool shouldKeepOriginal = true;
|
||||
if (orig->size() == D->size()) {
|
||||
if (orig->path.size() == D->path.size()) {
|
||||
// Here we break ties in a fairly arbitrary, but deterministic, way.
|
||||
llvm::FoldingSetNodeID fullProfile, fullProfileOrig;
|
||||
D->FullProfile(fullProfile);
|
||||
|
@ -476,12 +455,13 @@ void PathDiagnosticControlFlowPiece::Profile(llvm::FoldingSetNodeID &ID) const {
|
|||
|
||||
void PathDiagnosticMacroPiece::Profile(llvm::FoldingSetNodeID &ID) const {
|
||||
PathDiagnosticSpotPiece::Profile(ID);
|
||||
for (const_iterator I = begin(), E = end(); I != E; ++I)
|
||||
for (PathPieces::const_iterator I = subPieces.begin(), E = subPieces.end();
|
||||
I != E; ++I)
|
||||
ID.Add(**I);
|
||||
}
|
||||
|
||||
void PathDiagnostic::Profile(llvm::FoldingSetNodeID &ID) const {
|
||||
if (Size)
|
||||
if (!path.empty())
|
||||
getLocation().Profile(ID);
|
||||
ID.AddString(BugType);
|
||||
ID.AddString(Desc);
|
||||
|
@ -490,8 +470,8 @@ void PathDiagnostic::Profile(llvm::FoldingSetNodeID &ID) const {
|
|||
|
||||
void PathDiagnostic::FullProfile(llvm::FoldingSetNodeID &ID) const {
|
||||
Profile(ID);
|
||||
for (const_iterator I = begin(), E = end(); I != E; ++I)
|
||||
ID.Add(*I);
|
||||
for (PathPieces::const_iterator I = path.begin(), E = path.end(); I != E; ++I)
|
||||
ID.Add(**I);
|
||||
for (meta_iterator I = meta_begin(), E = meta_end(); I != E; ++I)
|
||||
ID.AddString(*I);
|
||||
}
|
||||
|
|
|
@ -246,7 +246,7 @@ static void ReportMacro(raw_ostream &o,
|
|||
const LangOptions &LangOpts,
|
||||
unsigned indent) {
|
||||
|
||||
for (PathDiagnosticMacroPiece::const_iterator I=P.begin(), E=P.end();
|
||||
for (PathPieces::const_iterator I = P.subPieces.begin(), E=P.subPieces.end();
|
||||
I!=E; ++I) {
|
||||
|
||||
switch ((*I)->getKind()) {
|
||||
|
@ -298,18 +298,19 @@ void PlistDiagnostics::FlushDiagnosticsImpl(
|
|||
const SourceManager* SM = 0;
|
||||
|
||||
if (!Diags.empty())
|
||||
SM = &(*Diags.begin())->begin()->getLocation().getManager();
|
||||
SM = &(*(*Diags.begin())->path.begin())->getLocation().getManager();
|
||||
|
||||
for (std::vector<const PathDiagnostic*>::iterator DI = Diags.begin(),
|
||||
DE = Diags.end(); DI != DE; ++DI) {
|
||||
|
||||
const PathDiagnostic *D = *DI;
|
||||
|
||||
for (PathDiagnostic::const_iterator I=D->begin(), E=D->end(); I!=E; ++I) {
|
||||
AddFID(FM, Fids, SM, I->getLocation().asLocation());
|
||||
for (PathPieces::const_iterator I = D->path.begin(), E = D->path.end();
|
||||
I!=E; ++I) {
|
||||
AddFID(FM, Fids, SM, (*I)->getLocation().asLocation());
|
||||
|
||||
for (PathDiagnosticPiece::range_iterator RI=I->ranges_begin(),
|
||||
RE=I->ranges_end(); RI!=RE; ++RI) {
|
||||
for (PathDiagnosticPiece::range_iterator RI = (*I)->ranges_begin(),
|
||||
RE= (*I)->ranges_end(); RI != RE; ++RI) {
|
||||
AddFID(FM, Fids, SM, RI->getBegin());
|
||||
AddFID(FM, Fids, SM, RI->getEnd());
|
||||
}
|
||||
|
@ -357,8 +358,9 @@ void PlistDiagnostics::FlushDiagnosticsImpl(
|
|||
|
||||
o << " <array>\n";
|
||||
|
||||
for (PathDiagnostic::const_iterator I=D->begin(), E=D->end(); I != E; ++I)
|
||||
ReportDiag(o, *I, FM, *SM, LangOpts);
|
||||
for (PathPieces::const_iterator I = D->path.begin(), E = D->path.end();
|
||||
I != E; ++I)
|
||||
ReportDiag(o, **I, FM, *SM, LangOpts);
|
||||
|
||||
o << " </array>\n";
|
||||
|
||||
|
|
|
@ -58,11 +58,12 @@ void TextPathDiagnostics::FlushDiagnosticsImpl(
|
|||
for (std::vector<const PathDiagnostic *>::iterator it = Diags.begin(),
|
||||
et = Diags.end(); it != et; ++it) {
|
||||
const PathDiagnostic *D = *it;
|
||||
for (PathDiagnostic::const_iterator I=D->begin(), E=D->end(); I != E; ++I) {
|
||||
for (PathPieces::const_iterator I = D->path.begin(), E = D->path.end();
|
||||
I != E; ++I) {
|
||||
unsigned diagID =
|
||||
Diag.getDiagnosticIDs()->getCustomDiagID(DiagnosticIDs::Note,
|
||||
I->getString());
|
||||
Diag.Report(I->getLocation().asLocation(), diagID);
|
||||
(*I)->getString());
|
||||
Diag.Report((*I)->getLocation().asLocation(), diagID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue