13#ifndef LLVM_CLANG_ANALYSIS_PATHDIAGNOSTIC_H
14#define LLVM_CLANG_ANALYSIS_PATHDIAGNOSTIC_H
20#include "llvm/ADT/ArrayRef.h"
21#include "llvm/ADT/FoldingSet.h"
22#include "llvm/ADT/PointerUnion.h"
23#include "llvm/ADT/SmallVector.h"
24#include "llvm/ADT/StringRef.h"
25#include "llvm/Support/Allocator.h"
40class AnalysisDeclContext;
44class ConditionalOperator;
111 llvm::BumpPtrAllocator Alloc;
112 llvm::FoldingSet<PDFileEntry> Set;
120 StringRef ConsumerName,
127 virtual void anchor();
176 llvm::FoldingSet<PathDiagnostic>
Diags;
193 llvm::PointerUnion<const LocationContext *, AnalysisDeclContext *>;
197 enum Kind { RangeK, SingleLocK, StmtK, DeclK } K = SingleLocK;
199 const Stmt *S =
nullptr;
200 const Decl *D =
nullptr;
206 : K(kind),
SM(&sm),
Loc(genLocation(L)),
Range(genRange()) {}
222 : K(
s->getBeginLoc().
isValid() ? StmtK : SingleLocK),
223 S(K == StmtK ?
s : nullptr),
SM(&sm),
225 assert(K == SingleLocK || S);
227 assert(K == SingleLocK ||
Range.isValid());
232 : K(DeclK),
D(d),
SM(&sm),
Loc(genLocation()),
Range(genRange()) {
235 assert(
Range.isValid());
244 assert(
Range.isValid());
325 bool UseEndOfStatement =
false);
328 return K ==
X.K &&
Loc ==
X.Loc &&
Range ==
X.Range;
332 return !(*
this ==
X);
336 return SM !=
nullptr;
356 bool hasRange()
const {
return K == StmtK || K == RangeK || K == DeclK; }
368 void Profile(llvm::FoldingSetNodeID &
ID)
const;
380 : Start(start), End(end) {}
409 const std::string str;
415 bool LastInMainSourceFile =
false;
423 std::vector<SourceRange> ranges;
424 std::vector<FixItHint> fixits;
439 void setTag(
const char *tag) { Tag = tag; }
442 const void *
getTag()
const {
return Tag.data(); }
479 virtual void Profile(llvm::FoldingSetNodeID &
ID)
const;
482 LastInMainSourceFile =
true;
486 return LastInMainSourceFile;
496 bool ShouldFlattenMacros)
const;
516 bool addPosRange =
true)
519 "PathDiagnosticSpotPiece's must have a valid location.");
526 void Profile(llvm::FoldingSetNodeID &
ID)
const override;
529 return P->getKind() ==
Event ||
P->getKind() ==
Macro ||
535 std::optional<bool> IsPrunable;
539 StringRef
s,
bool addPosRange =
true)
547 if (IsPrunable && !
override)
553 bool isPrunable()
const {
return IsPrunable.value_or(
false); }
555 void dump()
const override;
558 return P->getKind() ==
Event;
564 const Decl *Callee =
nullptr;
572 bool IsCalleeAnAutosynthesizedPropertyAccessor =
false;
576 std::string CallStackMessage;
605 std::shared_ptr<PathDiagnosticEventPiece>
612 for (
const auto &I :
path)
613 I->flattenLocations();
616 static std::shared_ptr<PathDiagnosticCallPiece>
623 void dump()
const override;
625 void Profile(llvm::FoldingSetNodeID &
ID)
const override;
628 return P->getKind() ==
Call;
633 std::vector<PathDiagnosticLocationPair> LPairs;
652 assert(!LPairs.empty() &&
653 "PathDiagnosticControlFlowPiece needs at least one location.");
654 return LPairs[0].getStart();
658 assert(!LPairs.empty() &&
659 "PathDiagnosticControlFlowPiece needs at least one location.");
660 return LPairs[0].getEnd();
664 LPairs[0].setStart(L);
677 using iterator = std::vector<PathDiagnosticLocationPair>::iterator;
683 for (
auto &I : *
this)
688 std::vector<PathDiagnosticLocationPair>::const_iterator;
697 void dump()
const override;
699 void Profile(llvm::FoldingSetNodeID &
ID)
const override;
713 I->flattenLocations();
717 return P->getKind() ==
Macro;
720 void dump()
const override;
722 void Profile(llvm::FoldingSetNodeID &
ID)
const override;
728 bool AddPosRange =
true)
733 return P->getKind() ==
Note;
736 void dump()
const override;
738 void Profile(llvm::FoldingSetNodeID &
ID)
const override;
744 bool AddPosRange =
true)
749 return P->getKind() ==
PopUp;
752 void dump()
const override;
754 void Profile(llvm::FoldingSetNodeID &
ID)
const override;
764 std::string CheckerName;
765 const Decl *DeclWithIssue;
767 std::string VerboseDesc;
768 std::string ShortDesc;
769 std::string Category;
770 std::deque<std::string> OtherDesc;
781 const Decl *UniqueingDecl;
784 const Decl *AnalysisEntryPoint =
nullptr;
787 std::unique_ptr<FilesToLineNumsMap> ExecutedLines;
792 StringRef bugtype, StringRef verboseDesc, StringRef shortDesc,
794 const Decl *DeclToUnique,
const Decl *AnalysisEntryPoint,
795 std::unique_ptr<FilesToLineNumsMap> ExecutedLines);
803 if (pathStack.empty())
805 return *pathStack.back();
822 assert(!
Loc.
isValid() &&
"End location already set!");
823 Loc = EndPiece->getLocation();
824 assert(
Loc.
isValid() &&
"Invalid location for end-of-path piece");
829 if (!ShortDesc.empty())
837 return ShortDesc.empty() ? VerboseDesc : ShortDesc;
848 void addMeta(StringRef
s) { OtherDesc.push_back(std::string(
s)); }
851 return *ExecutedLines;
855 return *ExecutedLines;
885 return UniqueingDecl;
890 for (
const auto &I : pathImpl)
891 I->flattenLocations();
898 void Profile(llvm::FoldingSetNodeID &
ID)
const;
This file defines AnalysisDeclContext, a class that manages the analysis context data for context sen...
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::SourceLocation class and associated facilities.
__device__ __2f16 float __ockl_bool s
AnalysisDeclContext contains the context data for the function, method or block under analysis.
A builtin binary operation expression such as "x + y" or "x <= y".
Represents a point when we begin processing an inlined call.
Represents a point when we finish the call exit sequence (for inlined call).
CompoundStmt - This represents a group of statements like { stmt stmt }.
ConditionalOperator - The ?: ternary operator.
Decl - This represents one declaration (or definition), e.g.
Annotates a diagnostic with some code that should be inserted, removed, or replaced to fix the proble...
A SourceLocation and its associated SourceManager.
It wraps the AnalysisDeclContext to represent both the call stack with the help of StackFrameContext ...
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
This class handles loading and caching of source files into memory.
A trivial tuple used to represent a source range.
Stmt - This represents one statement.
bool isValid() const =delete
~PathDiagnosticCallPiece() override
PathDiagnosticLocation getLocation() const override
void setCallee(const CallEnter &CE, const SourceManager &SM)
PathDiagnosticLocation callEnter
void dump() const override
std::shared_ptr< PathDiagnosticEventPiece > getCallExitEvent() const
void setCallStackMessage(StringRef st)
bool hasCallStackMessage()
static bool classof(const PathDiagnosticPiece *P)
const Decl * getCallee() const
static std::shared_ptr< PathDiagnosticCallPiece > construct(const CallExitEnd &CE, const SourceManager &SM)
PathDiagnosticLocation callReturn
void flattenLocations() override
std::shared_ptr< PathDiagnosticEventPiece > getCallEnterWithinCallerEvent() const
void Profile(llvm::FoldingSetNodeID &ID) const override
const Decl * getCaller() const
std::shared_ptr< PathDiagnosticEventPiece > getCallEnterEvent() const
PathDiagnosticLocation callEnterWithin
PDFileEntry::ConsumerFiles * getFiles(const PathDiagnostic &PD)
void addDiagnostic(const PathDiagnostic &PD, StringRef ConsumerName, StringRef fileName)
const llvm::FoldingSetNodeID NodeID
A precomputed hash tag used for uniquing PDFileEntry objects.
std::vector< std::pair< StringRef, StringRef > > ConsumerFiles
void Profile(llvm::FoldingSetNodeID &ID)
Used for profiling in the FoldingSet.
ConsumerFiles files
A vector of <consumer,file> pairs.
PDFileEntry(llvm::FoldingSetNodeID &NodeID)
@ None
Only runs visitors, no output generated.
@ Everything
Used for HTML, shows both "arrows" and control notes.
@ Extensive
Used for plist output, used for "arrows" generation.
@ Minimal
Used for SARIF and text output.
PathDiagnosticConsumer()=default
virtual bool supportsLogicalOpControlFlow() const
virtual void FlushDiagnosticsImpl(std::vector< const PathDiagnostic * > &Diags, FilesMade *filesMade)=0
bool shouldAddPathEdges() const
virtual bool supportsCrossFileDiagnostics() const
Return true if the PathDiagnosticConsumer supports individual PathDiagnostics that span multiple file...
void HandlePathDiagnostic(std::unique_ptr< PathDiagnostic > D)
virtual StringRef getName() const =0
virtual PathGenerationScheme getGenerationScheme() const
llvm::FoldingSet< PathDiagnostic > Diags
virtual ~PathDiagnosticConsumer()
void FlushDiagnostics(FilesMade *FilesMade)
bool shouldAddControlNotes() const
bool shouldGenerateDiagnostics() const
PathDiagnosticLocation getStartLocation() const
PathDiagnosticControlFlowPiece(const PathDiagnosticLocation &startPos, const PathDiagnosticLocation &endPos)
std::vector< PathDiagnosticLocationPair >::const_iterator const_iterator
void push_back(const PathDiagnosticLocationPair &X)
void setEndLocation(const PathDiagnosticLocation &L)
static bool classof(const PathDiagnosticPiece *P)
void dump() const override
PathDiagnosticControlFlowPiece(const PathDiagnosticLocation &startPos, const PathDiagnosticLocation &endPos, StringRef s)
std::vector< PathDiagnosticLocationPair >::iterator iterator
const_iterator begin() const
PathDiagnosticLocation getLocation() const override
void setStartLocation(const PathDiagnosticLocation &L)
const_iterator end() const
~PathDiagnosticControlFlowPiece() override
PathDiagnosticLocation getEndLocation() const
void Profile(llvm::FoldingSetNodeID &ID) const override
void flattenLocations() override
void setPrunable(bool isPrunable, bool override=false)
Mark the diagnostic piece as being potentially prunable.
static bool classof(const PathDiagnosticPiece *P)
~PathDiagnosticEventPiece() override
PathDiagnosticEventPiece(const PathDiagnosticLocation &pos, StringRef s, bool addPosRange=true)
void dump() const override
bool isPrunable() const
Return true if the diagnostic piece is prunable.
const PathDiagnosticLocation & getEnd() const
void Profile(llvm::FoldingSetNodeID &ID) const
const PathDiagnosticLocation & getStart() const
void setStart(const PathDiagnosticLocation &L)
void setEnd(const PathDiagnosticLocation &L)
PathDiagnosticLocationPair(const PathDiagnosticLocation &start, const PathDiagnosticLocation &end)
static PathDiagnosticLocation createMemberLoc(const MemberExpr *ME, const SourceManager &SM)
For member expressions, return the location of the '.
const Stmt * asStmt() const
static PathDiagnosticLocation createDeclBegin(const LocationContext *LC, const SourceManager &SM)
Create a location for the beginning of the enclosing declaration body.
void Profile(llvm::FoldingSetNodeID &ID) const
PathDiagnosticLocation(const Decl *d, const SourceManager &sm)
Create a location corresponding to the given declaration.
PathDiagnosticRange asRange() const
const Decl * asDecl() const
bool operator!=(const PathDiagnosticLocation &X) const
const SourceManager & getManager() const
static PathDiagnosticLocation createOperatorLoc(const BinaryOperator *BO, const SourceManager &SM)
Create the location for the operator of the binary expression.
static PathDiagnosticLocation createEndBrace(const CompoundStmt *CS, const SourceManager &SM)
Create a location for the end of the compound statement.
static PathDiagnosticLocation createBeginBrace(const CompoundStmt *CS, const SourceManager &SM)
Create a location for the beginning of the compound statement.
static SourceLocation getValidSourceLocation(const Stmt *S, LocationOrAnalysisDeclContext LAC, bool UseEndOfStatement=false)
Construct a source location that corresponds to either the beginning or the end of the given statemen...
static PathDiagnosticLocation createEnd(const Stmt *S, const SourceManager &SM, const LocationOrAnalysisDeclContext LAC)
Create a location for the end of the statement.
static PathDiagnosticLocation createBegin(const Decl *D, const SourceManager &SM)
Create a location for the beginning of the declaration.
FullSourceLoc asLocation() const
bool operator==(const PathDiagnosticLocation &X) const
PathDiagnosticLocation(SourceLocation loc, const SourceManager &sm)
Create a location at an explicit offset in the source.
static PathDiagnosticLocation create(const Decl *D, const SourceManager &SM)
Create a location corresponding to the given declaration.
static PathDiagnosticLocation createConditionalColonLoc(const ConditionalOperator *CO, const SourceManager &SM)
PathDiagnosticLocation()=default
Create an invalid location.
static PathDiagnosticLocation createDeclEnd(const LocationContext *LC, const SourceManager &SM)
Constructs a location for the end of the enclosing declaration body.
PathDiagnosticLocation(const Stmt *s, const SourceManager &sm, LocationOrAnalysisDeclContext lac)
Create a location corresponding to the given statement.
const Stmt * getStmtOrNull() const
static PathDiagnosticLocation createSingleLocation(const PathDiagnosticLocation &PDL)
Convert the given location into a single kind location.
static PathDiagnosticLocation createBegin(const Decl *D, const SourceManager &SM, const LocationOrAnalysisDeclContext LAC)
Create a location for the beginning of the declaration.
bool hasValidLocation() const
void dump() const override
void flattenLocations() override
PathDiagnosticMacroPiece(const PathDiagnosticLocation &pos)
static bool classof(const PathDiagnosticPiece *P)
void Profile(llvm::FoldingSetNodeID &ID) const override
~PathDiagnosticMacroPiece() override
void Profile(llvm::FoldingSetNodeID &ID) const override
void dump() const override
PathDiagnosticNotePiece(const PathDiagnosticLocation &Pos, StringRef S, bool AddPosRange=true)
~PathDiagnosticNotePiece() override
static bool classof(const PathDiagnosticPiece *P)
ArrayRef< SourceRange > getRanges() const
Return the SourceRanges associated with this PathDiagnosticPiece.
void addRange(SourceRange R)
virtual PathDiagnosticLocation getLocation() const =0
void addFixit(FixItHint F)
void setAsLastInMainSourceFile()
virtual void dump() const =0
void setTag(const char *tag)
Tag this PathDiagnosticPiece with the given C-string.
bool isLastInMainSourceFile() const
PathDiagnosticPiece(const PathDiagnosticPiece &)=delete
virtual void Profile(llvm::FoldingSetNodeID &ID) const
StringRef getTagStr() const
Return the string representation of the tag.
PathDiagnosticPiece & operator=(const PathDiagnosticPiece &)=delete
virtual ~PathDiagnosticPiece()
void addRange(SourceLocation B, SourceLocation E)
PathDiagnosticPiece()=delete
virtual void flattenLocations()=0
DisplayHint getDisplayHint() const
getDisplayHint - Return a hint indicating where the diagnostic should be displayed by the PathDiagnos...
const void * getTag() const
Return the opaque tag (if any) on the PathDiagnosticPiece.
StringRef getString() const
ArrayRef< FixItHint > getFixits() const
Return the fix-it hints associated with this PathDiagnosticPiece.
PathDiagnosticRange()=default
PathDiagnosticRange(SourceRange R, bool isP=false)
void flattenLocations() override
void Profile(llvm::FoldingSetNodeID &ID) const override
static bool classof(const PathDiagnosticPiece *P)
PathDiagnosticSpotPiece(const PathDiagnosticLocation &pos, StringRef s, PathDiagnosticPiece::Kind k, bool addPosRange=true)
PathDiagnosticLocation getLocation() const override
PathDiagnostic - PathDiagnostic objects represent a single path-sensitive diagnostic.
StringRef getCheckerName() const
PathPieces & getActivePath()
Return the path currently used by builders for constructing the PathDiagnostic.
void addMeta(StringRef s)
meta_iterator meta_end() const
void setDeclWithIssue(const Decl *D)
FilesToLineNumsMap & getExecutedLines()
void FullProfile(llvm::FoldingSetNodeID &ID) const
Profiles the diagnostic, including its path.
PathDiagnosticLocation getUniqueingLoc() const
Get the location on which the report should be uniqued.
std::deque< std::string >::const_iterator meta_iterator
StringRef getVerboseDescription() const
void appendToDesc(StringRef S)
const Decl * getDeclWithIssue() const
Return the semantic context where an issue occurred.
void pushActivePath(PathPieces *p)
const Decl * getAnalysisEntryPoint() const
Get the top-level entry point from which this issue was discovered.
void Profile(llvm::FoldingSetNodeID &ID) const
Profiles the diagnostic, independent of the path it references.
void setLocation(PathDiagnosticLocation NewLoc)
const FilesToLineNumsMap & getExecutedLines() const
unsigned full_size()
Return the unrolled size of the path.
void setEndOfPath(PathDiagnosticPieceRef EndPiece)
StringRef getBugType() const
const Decl * getUniqueingDecl() const
Get the declaration containing the uniqueing location.
PathPieces & getMutablePieces()
Return a mutable version of 'path'.
StringRef getCategory() const
StringRef getShortDescription() const
meta_iterator meta_begin() const
bool isWithinCall() const
PathDiagnosticLocation getLocation() const
PathPieces flatten(bool ShouldFlattenMacros) const
A Range represents the closed range [from, to].
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
std::map< FileID, std::set< unsigned > > FilesToLineNumsMap
File IDs mapped to sets of line numbers.
llvm::PointerUnion< const LocationContext *, AnalysisDeclContext * > LocationOrAnalysisDeclContext
std::shared_ptr< PathDiagnosticPiece > PathDiagnosticPieceRef
The JSON file list parser is used to communicate input to InstallAPI.
@ Result
The result type of a method or function.
These options tweak the behavior of path diangostic consumers.
bool ShouldDisplayMacroExpansions
Whether to include additional information about macro expansions with the diagnostics,...
bool ShouldDisplayWarningsAsErrors
Whether the consumer should treat consumed diagnostics as hard errors.
bool ShouldApplyFixIts
Whether the consumer should attempt to rewrite the source file with fix-it hints attached to the diag...
bool ShouldWriteVerboseReportFilename
If the consumer intends to produce multiple output files, should it use a pseudo-random file name or ...
bool ShouldSerializeStats
Whether to include LLVM statistics of the process in the diagnostic.
std::string ToolInvocation
Run-line of the tool that produced the diagnostic.
bool ShouldDisplayDiagnosticName
Whether the consumer should present the name of the entity that emitted the diagnostic (eg....