#include "clang/Basic/SourceManager.h"
#include "clang/Basic/Diagnostic.h"
#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/FoldingSet.h"
#include <vector>
#include <deque>
#include <algorithm>
namespace clang {
-
+
+class Stmt;
+class Decl;
+class Preprocessor;
+
//===----------------------------------------------------------------------===//
// High-level interface for handlers of path-sensitive diagnostics.
//===----------------------------------------------------------------------===//
class PathDiagnostic;
+
class Stmt;
class Decl;
class Preprocessor;
public:
PathDiagnosticClient() {}
virtual ~PathDiagnosticClient() {}
-
virtual void SetPreprocessor(Preprocessor *PP) {}
-
virtual void HandleDiagnostic(Diagnostic::Level DiagLevel,
const DiagnosticInfo &Info);
-
virtual void HandlePathDiagnostic(const PathDiagnostic* D) = 0;
enum PathGenerationScheme { Minimal, Extensive };
void flatten();
const SourceManager& getManager() const { assert(isValid()); return *SM; }
+
+ void Profile(llvm::FoldingSetNodeID &ID) const;
};
class PathDiagnosticLocationPair {
Start.flatten();
End.flatten();
}
+
+ void Profile(llvm::FoldingSetNodeID &ID) const {
+ Start.Profile(ID);
+ End.Profile(ID);
+ }
};
//===----------------------------------------------------------------------===//
static inline bool classof(const PathDiagnosticPiece* P) {
return true;
}
+
+ virtual void Profile(llvm::FoldingSetNodeID &ID) const;
};
class PathDiagnosticSpotPiece : public PathDiagnosticPiece {
PathDiagnosticLocation getLocation() const { return Pos; }
virtual void flattenLocations() { Pos.flatten(); }
+
+ virtual void Profile(llvm::FoldingSetNodeID &ID) const;
};
class PathDiagnosticEventPiece : public PathDiagnosticSpotPiece {
static inline bool classof(const PathDiagnosticPiece* P) {
return P->getKind() == ControlFlow;
}
+
+ virtual void Profile(llvm::FoldingSetNodeID &ID) const;
};
class PathDiagnosticMacroPiece : public PathDiagnosticSpotPiece {
static inline bool classof(const PathDiagnosticPiece* P) {
return P->getKind() == Macro;
}
+
+ virtual void Profile(llvm::FoldingSetNodeID &ID) const;
};
/// PathDiagnostic - PathDiagnostic objects represent a single path-sensitive
/// diagnostic. It represents an ordered-collection of PathDiagnosticPieces,
/// each which represent the pieces of the path.
-class PathDiagnostic {
+class PathDiagnostic : public llvm::FoldingSetNode {
std::deque<PathDiagnosticPiece*> path;
unsigned Size;
std::string BugType;
}
void push_front(PathDiagnosticPiece* piece) {
+ assert(piece);
path.push_front(piece);
++Size;
}
void push_back(PathDiagnosticPiece* piece) {
+ assert(piece);
path.push_back(piece);
++Size;
}
void flattenLocations() {
for (iterator I = begin(), E = end(); I != E; ++I) I->flattenLocations();
}
-};
-
-
+
+ void Profile(llvm::FoldingSetNodeID &ID) const;
+};
} //end clang namespace
#endif
}
}
+//===----------------------------------------------------------------------===//
+// FoldingSet profiling methods.
+//===----------------------------------------------------------------------===//
+
+void PathDiagnosticLocation::Profile(llvm::FoldingSetNodeID &ID) const {
+ ID.AddInteger((unsigned) K);
+ switch (K) {
+ case RangeK:
+ ID.AddInteger(R.getBegin().getRawEncoding());
+ ID.AddInteger(R.getEnd().getRawEncoding());
+ break;
+ case SingleLocK:
+ ID.AddInteger(R.getBegin().getRawEncoding());
+ break;
+ case StmtK:
+ ID.Add(S);
+ break;
+ case DeclK:
+ ID.Add(D);
+ break;
+ }
+ return;
+}
+
+void PathDiagnosticPiece::Profile(llvm::FoldingSetNodeID &ID) const {
+ ID.AddInteger((unsigned) getKind());
+ ID.AddString(str);
+ // FIXME: Add profiling support for code hints.
+ ID.AddInteger((unsigned) getDisplayHint());
+ for (range_iterator I = ranges_begin(), E = ranges_end(); I != E; ++I) {
+ ID.AddInteger(I->getBegin().getRawEncoding());
+ ID.AddInteger(I->getEnd().getRawEncoding());
+ }
+}
+
+void PathDiagnosticSpotPiece::Profile(llvm::FoldingSetNodeID &ID) const {
+ PathDiagnosticPiece::Profile(ID);
+ ID.Add(Pos);
+}
+void PathDiagnosticControlFlowPiece::Profile(llvm::FoldingSetNodeID &ID) const {
+ PathDiagnosticPiece::Profile(ID);
+ for (const_iterator I = begin(), E = end(); I != E; ++I)
+ ID.Add(*I);
+}
+
+void PathDiagnosticMacroPiece::Profile(llvm::FoldingSetNodeID &ID) const {
+ PathDiagnosticSpotPiece::Profile(ID);
+ for (const_iterator I = begin(), E = end(); I != E; ++I)
+ ID.Add(**I);
+}
+
+void PathDiagnostic::Profile(llvm::FoldingSetNodeID &ID) const {
+ ID.AddInteger(Size);
+ ID.AddString(BugType);
+ ID.AddString(Desc);
+ ID.AddString(Category);
+ for (const_iterator I = begin(), E = end(); I != E; ++I)
+ ID.Add(*I);
+
+ for (meta_iterator I = meta_begin(), E = meta_end(); I != E; ++I)
+ ID.AddString(*I);
+}