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"
110 llvm::BumpPtrAllocator Alloc;
111 llvm::FoldingSet<PDFileEntry> Set;
116 bool empty()
const {
return Set.empty(); }
119 StringRef ConsumerName,
126 virtual void anchor();
175 llvm::FoldingSet<PathDiagnostic>
Diags;
192 llvm::PointerUnion<const StackFrame *, AnalysisDeclContext *>;
194class PathDiagnosticLocation {
196 enum Kind { RangeK, SingleLocK, StmtK, DeclK } K = SingleLocK;
198 const Stmt *S =
nullptr;
199 const Decl *D =
nullptr;
205 : K(
kind),
SM(&sm), Loc(genLocation(L)), Range(genRange()) {}
221 : K(
s->getBeginLoc().
isValid() ? StmtK : SingleLocK),
222 S(K == StmtK ?
s :
nullptr), SM(&sm),
224 assert(K == SingleLocK || S);
225 assert(K == SingleLocK || Loc.isValid());
226 assert(K == SingleLocK || Range.isValid());
231 : K(DeclK), D(d), SM(&sm), Loc(genLocation()), Range(genRange()) {
233 assert(Loc.isValid());
234 assert(Range.isValid());
241 : SM(&sm), Loc(
loc, sm), Range(genRange()) {
242 assert(Loc.isValid());
243 assert(Range.isValid());
324 bool UseEndOfStatement =
false);
327 return K ==
X.K && Loc ==
X.Loc && Range ==
X.Range;
331 return !(*
this ==
X);
335 return SM !=
nullptr;
355 bool hasRange()
const {
return K == StmtK || K == RangeK || K == DeclK; }
367 void Profile(llvm::FoldingSetNodeID &ID)
const;
379 : Start(start), End(end) {}
392 void Profile(llvm::FoldingSetNodeID &ID)
const {
408 const std::string str;
414 bool LastInMainSourceFile =
false;
422 std::vector<SourceRange> ranges;
423 std::vector<FixItHint> fixits;
438 void setTag(
const char *tag) { Tag = tag; }
441 const void *
getTag()
const {
return Tag.data(); }
478 virtual void Profile(llvm::FoldingSetNodeID &ID)
const;
481 LastInMainSourceFile =
true;
485 return LastInMainSourceFile;
495 bool ShouldFlattenMacros)
const;
515 bool addPosRange =
true)
517 assert(Pos.isValid() && Pos.hasValidLocation() &&
518 "PathDiagnosticSpotPiece's must have a valid location.");
519 if (addPosRange && Pos.hasRange())
addRange(Pos.asRange());
525 void Profile(llvm::FoldingSetNodeID &ID)
const override;
534 std::optional<bool> IsPrunable;
538 StringRef
s,
bool addPosRange =
true)
546 if (IsPrunable && !
override)
552 bool isPrunable()
const {
return IsPrunable.value_or(
false); }
554 void dump()
const override;
563 const Decl *Callee =
nullptr;
571 bool IsCalleeAnAutosynthesizedPropertyAccessor =
false;
575 std::string CallStackMessage;
577 PathDiagnosticCallPiece(
const Decl *callerD,
604 std::shared_ptr<PathDiagnosticEventPiece>
611 for (
const auto &I :
path)
612 I->flattenLocations();
615 static std::shared_ptr<PathDiagnosticCallPiece>
622 void dump()
const override;
624 void Profile(llvm::FoldingSetNodeID &ID)
const override;
632 std::vector<PathDiagnosticLocationPair> LPairs;
651 assert(!LPairs.empty() &&
652 "PathDiagnosticControlFlowPiece needs at least one location.");
653 return LPairs[0].getStart();
657 assert(!LPairs.empty() &&
658 "PathDiagnosticControlFlowPiece needs at least one location.");
659 return LPairs[0].getEnd();
663 LPairs[0].setStart(L);
676 using iterator = std::vector<PathDiagnosticLocationPair>::iterator;
682 for (
auto &I : *
this)
687 std::vector<PathDiagnosticLocationPair>::const_iterator;
696 void dump()
const override;
698 void Profile(llvm::FoldingSetNodeID &ID)
const override;
712 I->flattenLocations();
719 void dump()
const override;
721 void Profile(llvm::FoldingSetNodeID &ID)
const override;
727 bool AddPosRange =
true)
735 void dump()
const override;
737 void Profile(llvm::FoldingSetNodeID &ID)
const override;
743 bool AddPosRange =
true)
751 void dump()
const override;
753 void Profile(llvm::FoldingSetNodeID &ID)
const override;
763 std::string CheckerName;
764 const Decl *DeclWithIssue;
766 std::string VerboseDesc;
767 std::string ShortDesc;
768 std::string Category;
769 std::deque<std::string> OtherDesc;
780 const Decl *UniqueingDecl;
783 const Decl *AnalysisEntryPoint =
nullptr;
786 std::unique_ptr<FilesToLineNumsMap> ExecutedLines;
791 StringRef bugtype, StringRef verboseDesc, StringRef shortDesc,
793 const Decl *DeclToUnique,
const Decl *AnalysisEntryPoint,
794 std::unique_ptr<FilesToLineNumsMap> ExecutedLines);
802 if (pathStack.empty())
804 return *pathStack.back();
821 assert(!Loc.isValid() &&
"End location already set!");
822 Loc = EndPiece->getLocation();
823 assert(Loc.isValid() &&
"Invalid location for end-of-path piece");
828 if (!ShortDesc.empty())
836 return ShortDesc.empty() ? VerboseDesc : ShortDesc;
847 void addMeta(StringRef
s) { OtherDesc.push_back(std::string(
s)); }
850 return *ExecutedLines;
854 return *ExecutedLines;
884 return UniqueingDecl;
893 for (
const auto &I : pathImpl)
894 I->flattenLocations();
901 void Profile(llvm::FoldingSetNodeID &ID)
const;
907 void FullProfile(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.
*collection of selector each with an associated kind and an ordered *collection of selectors A selector has a kind
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 ?
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.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
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.
It represents a stack frame of the call stack.
Stmt - This represents one statement.
~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.
void Profile(llvm::FoldingSetNodeID &ID)
Used for profiling in the FoldingSet.
ConsumerFiles files
A vector of <consumer,file> pairs.
std::vector< std::pair< StringRef, StringRef > > ConsumerFiles
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 '.
static PathDiagnosticLocation createDeclBegin(const StackFrame *SF, const SourceManager &SM)
Create a location for the beginning of the enclosing declaration body.
const Stmt * asStmt() const
static SourceLocation getValidSourceLocation(const Stmt *S, StackFrameOrAnalysisDeclContext SFAC, bool UseEndOfStatement=false)
Construct a source location that corresponds to either the beginning or the end of the given statemen...
static PathDiagnosticLocation createDeclEnd(const StackFrame *SF, const SourceManager &SM)
Constructs a location for the end 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 createEnd(const Stmt *S, const SourceManager &SM, const StackFrameOrAnalysisDeclContext SFAC)
Create a location for the end of the statement.
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.
PathDiagnosticLocation(const Stmt *s, const SourceManager &sm, StackFrameOrAnalysisDeclContext SFAC)
Create a location corresponding to the given 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 createBegin(const Decl *D, const SourceManager &SM, const StackFrameOrAnalysisDeclContext SFAC)
Create a location for the beginning of the declaration.
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.
const Stmt * getStmtOrNull() const
static PathDiagnosticLocation createSingleLocation(const PathDiagnosticLocation &PDL)
Convert the given location into a single kind location.
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
PathDiagnosticPiece(StringRef s, Kind k, DisplayHint hint=Below)
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
SmallString< 32 > getIssueHash(const SourceManager &SrcMgr, const LangOptions &LangOpts) const
Get a hash that identifies the issue.
PathDiagnosticLocation getLocation() const
PathPieces flatten(bool ShouldFlattenMacros) const
Public enums and private classes that are part of the SourceManager implementation.
llvm::PointerUnion< const StackFrame *, AnalysisDeclContext * > StackFrameOrAnalysisDeclContext
std::shared_ptr< PathDiagnosticPiece > PathDiagnosticPieceRef
std::map< FileID, std::set< unsigned > > FilesToLineNumsMap
File IDs mapped to sets of line numbers.
The JSON file list parser is used to communicate input to InstallAPI.
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
@ 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....