From: Ted Kremenek Date: Fri, 18 Sep 2009 22:33:39 +0000 (+0000) Subject: Reintroduce FoldingSet profiling for PathDiagnostics. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=db8338a35fa729c08bc2dfd87cdc43533506f548;p=clang Reintroduce FoldingSet profiling for PathDiagnostics. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@82299 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Analysis/PathDiagnostic.h b/include/clang/Analysis/PathDiagnostic.h index 809c83161f..a08afe2bb9 100644 --- a/include/clang/Analysis/PathDiagnostic.h +++ b/include/clang/Analysis/PathDiagnostic.h @@ -17,6 +17,7 @@ #include "clang/Basic/SourceManager.h" #include "clang/Basic/Diagnostic.h" #include "llvm/ADT/OwningPtr.h" +#include "llvm/ADT/FoldingSet.h" #include #include @@ -24,12 +25,17 @@ #include 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; @@ -38,12 +44,9 @@ class PathDiagnosticClient : public DiagnosticClient { 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 }; @@ -125,6 +128,8 @@ public: void flatten(); const SourceManager& getManager() const { assert(isValid()); return *SM; } + + void Profile(llvm::FoldingSetNodeID &ID) const; }; class PathDiagnosticLocationPair { @@ -142,6 +147,11 @@ public: Start.flatten(); End.flatten(); } + + void Profile(llvm::FoldingSetNodeID &ID) const { + Start.Profile(ID); + End.Profile(ID); + } }; //===----------------------------------------------------------------------===// @@ -220,6 +230,8 @@ public: static inline bool classof(const PathDiagnosticPiece* P) { return true; } + + virtual void Profile(llvm::FoldingSetNodeID &ID) const; }; class PathDiagnosticSpotPiece : public PathDiagnosticPiece { @@ -238,6 +250,8 @@ public: PathDiagnosticLocation getLocation() const { return Pos; } virtual void flattenLocations() { Pos.flatten(); } + + virtual void Profile(llvm::FoldingSetNodeID &ID) const; }; class PathDiagnosticEventPiece : public PathDiagnosticSpotPiece { @@ -317,6 +331,8 @@ public: static inline bool classof(const PathDiagnosticPiece* P) { return P->getKind() == ControlFlow; } + + virtual void Profile(llvm::FoldingSetNodeID &ID) const; }; class PathDiagnosticMacroPiece : public PathDiagnosticSpotPiece { @@ -347,12 +363,14 @@ public: 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 path; unsigned Size; std::string BugType; @@ -386,11 +404,13 @@ public: } void push_front(PathDiagnosticPiece* piece) { + assert(piece); path.push_front(piece); ++Size; } void push_back(PathDiagnosticPiece* piece) { + assert(piece); path.push_back(piece); ++Size; } @@ -480,8 +500,8 @@ public: void flattenLocations() { for (iterator I = begin(), E = end(); I != E; ++I) I->flattenLocations(); } -}; - - + + void Profile(llvm::FoldingSetNodeID &ID) const; +}; } //end clang namespace #endif diff --git a/lib/Analysis/PathDiagnostic.cpp b/lib/Analysis/PathDiagnostic.cpp index ceead6a3ac..800496a161 100644 --- a/lib/Analysis/PathDiagnostic.cpp +++ b/lib/Analysis/PathDiagnostic.cpp @@ -239,4 +239,66 @@ void PathDiagnosticLocation::flatten() { } } +//===----------------------------------------------------------------------===// +// 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); +}