14 #ifndef LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_PATHDIAGNOSTIC_H
15 #define LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_PATHDIAGNOSTIC_H
19 #include "llvm/ADT/FoldingSet.h"
20 #include "llvm/ADT/IntrusiveRefCntPtr.h"
21 #include "llvm/ADT/Optional.h"
22 #include "llvm/ADT/PointerUnion.h"
30 class ConditionalOperator;
31 class AnalysisDeclContext;
35 class LocationContext;
74 llvm::BumpPtrAllocator Alloc;
75 llvm::FoldingSet<PDFileEntry> Set;
80 bool empty()
const {
return Set.empty(); }
83 StringRef ConsumerName,
90 virtual void anchor();
98 FilesMade *filesMade) = 0;
100 virtual StringRef
getName()
const = 0;
114 llvm::FoldingSet<PathDiagnostic>
Diags;
131 typedef llvm::PointerUnion<const LocationContext*, AnalysisDeclContext*>
136 enum Kind { RangeK, SingleLocK, StmtK, DeclK } K;
145 : K(kind), S(
nullptr), D(
nullptr), SM(&sm),
146 Loc(genLocation(L)), Range(genRange()) {
159 : K(SingleLocK), S(nullptr), D(nullptr), SM(nullptr) {}
165 : K(s->getLocStart().
isValid() ? StmtK : SingleLocK),
166 S(K == StmtK ? s : nullptr),
169 Range(genRange(lac)) {
170 assert(K == SingleLocK || S);
171 assert(K == SingleLocK ||
Loc.isValid());
172 assert(K == SingleLocK || Range.
isValid());
177 : K(DeclK), S(nullptr), D(d), SM(&sm),
178 Loc(genLocation()), Range(genRange()) {
180 assert(
Loc.isValid());
188 : K(SingleLocK), S(nullptr), D(nullptr), SM(&sm),
Loc(loc, sm),
190 assert(
Loc.isValid());
264 return K == X.K &&
Loc == X.Loc && Range == X.Range;
268 return !(*
this ==
X);
272 return SM !=
nullptr;
286 bool hasRange()
const {
return K == StmtK || K == RangeK || K == DeclK; }
296 void Profile(llvm::FoldingSetNodeID &
ID)
const;
314 : Start(start), End(end) {}
343 const std::string str;
349 bool LastInMainSourceFile;
357 std::vector<SourceRange> ranges;
374 void setTag(
const char *tag) { Tag = tag; }
377 const void *
getTag()
const {
return Tag.data(); }
407 virtual void Profile(llvm::FoldingSetNodeID &
ID)
const;
410 LastInMainSourceFile =
true;
414 return LastInMainSourceFile;
417 virtual void dump()
const = 0;
421 class PathPieces :
public std::list<IntrusiveRefCntPtr<PathDiagnosticPiece> > {
423 bool ShouldFlattenMacros)
const;
429 flattenTo(Result, Result, ShouldFlattenMacros);
443 bool addPosRange =
true)
446 "PathDiagnosticSpotPiece's must have a valid location.");
453 void Profile(llvm::FoldingSetNodeID &
ID)
const override;
509 std::unique_ptr<StackHintGenerator> CallStackHint;
513 StringRef s,
bool addPosRange =
true,
516 CallStackHint(stackHint) {}
524 if (IsPrunable.hasValue() && !
override)
531 return IsPrunable.hasValue() ? IsPrunable.getValue() :
false;
540 return CallStackHint->getMessage(N);
544 void dump()
const override;
559 NoExit(
true),
path(oldPath) {}
570 std::string CallStackMessage;
587 CallStackMessage = st;
602 for (PathPieces::iterator I =
path.begin(),
603 E =
path.end(); I != E; ++I) (*I)->flattenLocations();
613 void dump()
const override;
615 void Profile(llvm::FoldingSetNodeID &
ID)
const override;
623 std::vector<PathDiagnosticLocationPair> LPairs;
641 assert(!LPairs.empty() &&
642 "PathDiagnosticControlFlowPiece needs at least one location.");
643 return LPairs[0].getStart();
647 assert(!LPairs.empty() &&
648 "PathDiagnosticControlFlowPiece needs at least one location.");
649 return LPairs[0].getEnd();
653 LPairs[0].setStart(L);
666 typedef std::vector<PathDiagnosticLocationPair>::iterator
iterator;
674 typedef std::vector<PathDiagnosticLocationPair>::const_iterator
683 void dump()
const override;
685 void Profile(llvm::FoldingSetNodeID &
ID)
const override;
701 for (PathPieces::iterator I =
subPieces.begin(),
702 E =
subPieces.end(); I != E; ++I) (*I)->flattenLocations();
709 void dump()
const override;
711 void Profile(llvm::FoldingSetNodeID &
ID)
const override;
719 const Decl *DeclWithIssue;
721 std::string VerboseDesc;
722 std::string ShortDesc;
723 std::string Category;
724 std::deque<std::string> OtherDesc;
735 const Decl *UniqueingDecl;
740 StringRef bugtype, StringRef verboseDesc, StringRef shortDesc,
742 const Decl *DeclToUnique);
751 if (pathStack.empty())
753 return *pathStack.back();
770 assert(!
Loc.isValid() &&
"End location already set!");
771 Loc = EndPiece->getLocation();
772 assert(Loc.isValid() &&
"Invalid location for end-of-path piece");
777 if (!ShortDesc.empty())
779 VerboseDesc.append(S);
795 return ShortDesc.empty() ? VerboseDesc : ShortDesc;
809 void addMeta(StringRef s) { OtherDesc.push_back(s); }
812 assert(
Loc.isValid() &&
"No report location set yet!");
823 return UniqueingDecl;
828 for (PathPieces::iterator I = pathImpl.begin(), E = pathImpl.end();
829 I != E; ++I) (*I)->flattenLocations();
836 void Profile(llvm::FoldingSetNodeID &
ID)
const;
PathDiagnosticLocation getUniqueingLoc() const
Get the location on which the report should be uniqued.
PathDiagnosticSpotPiece(const PathDiagnosticLocation &pos, StringRef s, PathDiagnosticPiece::Kind k, bool addPosRange=true)
void setTag(const char *tag)
Tag this PathDiagnosticPiece with the given C-string.
PathDiagnosticControlFlowPiece(const PathDiagnosticLocation &startPos, const PathDiagnosticLocation &endPos, StringRef s)
bool hasCallStackMessage()
PathDiagnosticLocation getLocation() const override
~PathDiagnosticMacroPiece() override
std::deque< std::string >::const_iterator meta_iterator
const SymExpr * SymbolRef
virtual StringRef getName() const =0
static PathDiagnosticLocation createBeginBrace(const CompoundStmt *CS, const SourceManager &SM)
~PathDiagnosticEventPiece() override
PathPieces flatten(bool ShouldFlattenMacros) const
StringRef getCategory() const
Constructs a Stack hint for the given symbol.
const_iterator begin() const
virtual std::string getMessageForArg(const Expr *ArgE, unsigned ArgIndex)
PathDiagnosticMacroPiece(const PathDiagnosticLocation &pos)
virtual ~StackHintGenerator()=0
void setPrunable(bool isPrunable, bool override=false)
void flattenLocations() override
static PathDiagnosticLocation createEndBrace(const CompoundStmt *CS, const SourceManager &SM)
ArrayRef< SourceRange > getRanges() const
Return the SourceRanges associated with this PathDiagnosticPiece.
PathDiagnosticLocation getLocation() const
void setAsLastInMainSourceFile()
const Decl * getDeclWithIssue() const
void dump() const override
static PathDiagnosticLocation createDeclEnd(const LocationContext *LC, const SourceManager &SM)
~PathDiagnosticPiece() override
void addRange(SourceRange R)
static PathDiagnosticLocation createSingleLocation(const PathDiagnosticLocation &PDL)
Convert the given location into a single kind location.
FullSourceLoc asLocation() const
Symbolic value. These values used to capture symbolic execution of the program.
void setStartLocation(const PathDiagnosticLocation &L)
void addRange(SourceLocation B, SourceLocation E)
bool operator==(const PathDiagnosticLocation &X) const
StringRef getString() const
~PathDiagnosticControlFlowPiece() override
void pushActivePath(PathPieces *p)
bool containsEvent() const
virtual ~PathDiagnosticConsumer()
std::vector< PathDiagnosticLocationPair >::iterator iterator
PathPieces & getMutablePieces()
Return a mutable version of 'path'.
bool isPrunable() const
Return true if the diagnostic piece is prunable.
virtual void Profile(llvm::FoldingSetNodeID &ID) const
PDFileEntry(llvm::FoldingSetNodeID &NodeID)
llvm::FoldingSet< PathDiagnostic > Diags
void setStart(const PathDiagnosticLocation &L)
std::vector< PathDiagnosticLocationPair >::const_iterator const_iterator
virtual std::string getMessageForReturn(const CallExpr *CallExpr)
IntrusiveRefCntPtr< PathDiagnosticEventPiece > getCallExitEvent() const
const Decl * asDecl() const
A builtin binary operation expression such as "x + y" or "x <= y".
std::string getMessage(const ExplodedNode *N) override
Search the call expression for the symbol Sym and dispatch the 'getMessageForX()' methods to construc...
static PathDiagnosticCallPiece * construct(const ExplodedNode *N, const CallExitEnd &CE, const SourceManager &SM)
static PathDiagnosticLocation create(const Decl *D, const SourceManager &SM)
Create a location corresponding to the given declaration.
const void * getTag() const
Return the opaque tag (if any) on the PathDiagnosticPiece.
meta_iterator meta_begin() const
PathDiagnosticLocation callEnter
void dump() const override
PathDiagnosticLocation(const Stmt *s, const SourceManager &sm, LocationOrAnalysisDeclContext lac)
Create a location corresponding to the given statement.
virtual PathDiagnosticLocation getLocation() const =0
const_iterator end() const
const Stmt * asStmt() const
static PathDiagnosticLocation createMemberLoc(const MemberExpr *ME, const SourceManager &SM)
void Profile(llvm::FoldingSetNodeID &ID) const
void HandlePathDiagnostic(std::unique_ptr< PathDiagnostic > D)
PDFileEntry::ConsumerFiles * getFiles(const PathDiagnostic &PD)
IntrusiveRefCntPtr< PathDiagnosticEventPiece > getCallEnterWithinCallerEvent() const
ID
Defines the set of possible language-specific address spaces.
const Decl * getCallee() const
void FullProfile(llvm::FoldingSetNodeID &ID) const
StringRef getShortDescription() const
const SourceManager & getManager() const
PathDiagnosticLocation getEndLocation() const
IntrusiveRefCntPtr< PathDiagnosticEventPiece > getCallEnterEvent() const
static const Stmt * getNextStmt(const ExplodedNode *N)
Retrieve the statement corresponding to the successor node.
virtual bool supportsLogicalOpControlFlow() const
void resetDiagnosticLocationToMainFile()
If the last piece of the report point to the header file, resets the location of the report to be the...
virtual std::string getMessageForSymbolNotFound()
PathDiagnosticRange(const SourceRange &R, bool isP=false)
std::vector< std::pair< StringRef, StringRef > > ConsumerFiles
Interface for classes constructing Stack hints.
The result type of a method or function.
virtual bool supportsCrossFileDiagnostics() const
PathDiagnosticLocation getStartLocation() const
llvm::PointerUnion< const LocationContext *, AnalysisDeclContext * > LocationOrAnalysisDeclContext
meta_iterator meta_end() const
static const Stmt * getStmt(const ExplodedNode *N)
Given an exploded node, retrieve the statement that should be used for the diagnostic location...
static PathDiagnosticLocation createDeclBegin(const LocationContext *LC, const SourceManager &SM)
static PathDiagnosticLocation createBegin(const Decl *D, const SourceManager &SM)
Create a location for the beginning of the declaration.
~PathDiagnosticCallPiece() override
const llvm::FoldingSetNodeID NodeID
A precomputed hash tag used for uniquing PDFileEntry objects.
void flattenLocations() override
virtual void FlushDiagnosticsImpl(std::vector< const PathDiagnostic * > &Diags, FilesMade *filesMade)=0
Encodes a location in the source. The SourceManager can decode this to get at the full include stack...
std::string getCallStackMessage(const ExplodedNode *N)
void addMeta(StringRef s)
virtual PathGenerationScheme getGenerationScheme() const
bool isValid() const
Return true if this is a valid SourceLocation object.
StringRef getVerboseDescription() const
virtual void flattenLocations()=0
PathDiagnosticLocation callReturn
void Profile(llvm::FoldingSetNodeID &ID) const
void setCallee(const CallEnter &CE, const SourceManager &SM)
static PathDiagnosticLocation createConditionalColonLoc(const ConditionalOperator *CO, const SourceManager &SM)
const PathDiagnosticLocation & getStart() const
static PathDiagnosticLocation createEnd(const Stmt *S, const SourceManager &SM, const LocationOrAnalysisDeclContext LAC)
const Decl * getUniqueingDecl() const
Get the declaration containing the uniqueing location.
PathDiagnosticLocation getLocation() const override
void flattenLocations() override
ConsumerFiles files
A vector of <consumer,file> pairs.
virtual void dump() const =0
PathDiagnosticControlFlowPiece(const PathDiagnosticLocation &startPos, const PathDiagnosticLocation &endPos)
static __inline__ uint32_t volatile uint32_t * p
void FlushDiagnostics(FilesMade *FilesMade)
bool isLastInMainSourceFile() const
DisplayHint getDisplayHint() const
PathDiagnosticEventPiece(const PathDiagnosticLocation &pos, StringRef s, bool addPosRange=true, StackHintGenerator *stackHint=nullptr)
void Profile(llvm::FoldingSetNodeID &ID) const override
void setEndLocation(const PathDiagnosticLocation &L)
PathDiagnosticLocationPair(const PathDiagnosticLocation &start, const PathDiagnosticLocation &end)
void appendToDesc(StringRef S)
virtual std::string getMessage(const ExplodedNode *N)=0
Construct the Diagnostic message for the given ExplodedNode.
~StackHintGeneratorForSymbol() override
void Profile(llvm::FoldingSetNodeID &ID) const
void setEndOfPath(std::unique_ptr< PathDiagnosticPiece > EndPiece)
PathDiagnosticLocation(SourceLocation loc, const SourceManager &sm)
PathDiagnosticLocation(const Decl *d, const SourceManager &sm)
Create a location corresponding to the given declaration.
void setCallStackMessage(StringRef st)
const Decl * getCaller() const
void push_back(const PathDiagnosticLocationPair &X)
static bool classof(const PathDiagnosticPiece *P)
void dump() const override
void Profile(llvm::FoldingSetNodeID &ID) const override
void Profile(llvm::FoldingSetNodeID &ID)
Used for profiling in the FoldingSet.
static PathDiagnosticLocation createOperatorLoc(const BinaryOperator *BO, const SourceManager &SM)
PathDiagnosticLocation getLocation() const override
PathDiagnosticRange asRange() const
StringRef getTagStr() const
Defines the clang::SourceLocation class and associated facilities.
PathPieces & getActivePath()
const PathDiagnosticLocation & getEnd() const
static PathDiagnosticLocation createEndOfPath(const ExplodedNode *N, const SourceManager &SM)
unsigned kind
All of the diagnostics that can be emitted by the frontend.
PathDiagnosticLocation()
Create an invalid location.
static bool classof(const PathDiagnosticPiece *P)
void flattenLocations() override
A SourceLocation and its associated SourceManager.
PathDiagnosticLocation callEnterWithin
void Profile(llvm::FoldingSetNodeID &ID) const override
StringRef getBugType() const
void addDiagnostic(const PathDiagnostic &PD, StringRef ConsumerName, StringRef fileName)
A trivial tuple used to represent a source range.
static bool classof(const PathDiagnosticPiece *P)
bool isWithinCall() const
StringRef getCheckName() const
StackHintGeneratorForSymbol(SymbolRef S, StringRef M)
bool operator!=(const PathDiagnosticLocation &X) const
This class handles loading and caching of source files into memory.
static bool classof(const PathDiagnosticPiece *P)
unsigned full_size()
Return the unrolled size of the path.
void Profile(llvm::FoldingSetNodeID &ID) const override
void dump() const override
void setEnd(const PathDiagnosticLocation &L)
static bool classof(const PathDiagnosticPiece *P)