14 #ifndef LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_PATHDIAGNOSTIC_H 15 #define LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_PATHDIAGNOSTIC_H 21 #include "llvm/ADT/ArrayRef.h" 22 #include "llvm/ADT/FoldingSet.h" 23 #include "llvm/ADT/Optional.h" 24 #include "llvm/ADT/PointerUnion.h" 25 #include "llvm/ADT/SmallVector.h" 26 #include "llvm/ADT/StringRef.h" 27 #include "llvm/Support/Allocator.h" 41 class AnalysisDeclContext;
46 class ConditionalOperator;
49 class LocationContext;
86 llvm::BumpPtrAllocator Alloc;
87 llvm::FoldingSet<PDFileEntry> Set;
92 bool empty()
const {
return Set.empty(); }
95 StringRef ConsumerName,
102 virtual void anchor();
111 FilesMade *filesMade) = 0;
113 virtual StringRef
getName()
const = 0;
137 llvm::FoldingSet<PathDiagnostic>
Diags;
146 bool isPoint =
false;
154 llvm::PointerUnion<const LocationContext *, AnalysisDeclContext *>;
158 enum Kind { RangeK, SingleLocK, StmtK, DeclK } K = SingleLocK;
160 const Stmt *S =
nullptr;
161 const Decl *D =
nullptr;
167 : K(kind),
SM(&sm), Loc(genLocation(L)), Range(genRange()) {}
184 : K(s->getLocStart().isValid() ? StmtK : SingleLocK),
185 S(K == StmtK ? s : nullptr), SM(&sm),
187 assert(K == SingleLocK || S);
188 assert(K == SingleLocK || Loc.
isValid());
189 assert(K == SingleLocK || Range.
isValid());
194 : K(DeclK), D(d), SM(&sm), Loc(genLocation()), Range(genRange()) {
204 : SM(&sm), Loc(loc, sm), Range(genRange()) {
225 return createBegin(D, SM);
288 return K == X.K && Loc == X.Loc && Range == X.Range;
292 return !(*
this ==
X);
296 return SM !=
nullptr;
316 bool hasRange()
const {
return K == StmtK || K == RangeK || K == DeclK; }
326 void Profile(llvm::FoldingSetNodeID &
ID)
const;
345 : Start(start), End(end) {}
370 enum Kind { ControlFlow, Event, Macro, Call, Note };
374 const std::string str;
380 bool LastInMainSourceFile =
false;
388 std::vector<SourceRange> ranges;
403 void setTag(
const char *tag) { Tag = tag; }
406 const void *
getTag()
const {
return Tag.data(); }
417 virtual void flattenLocations() = 0;
436 virtual void Profile(llvm::FoldingSetNodeID &
ID)
const;
439 LastInMainSourceFile =
true;
443 return LastInMainSourceFile;
446 virtual void dump()
const = 0;
449 class PathPieces :
public std::list<std::shared_ptr<PathDiagnosticPiece>> {
451 bool ShouldFlattenMacros)
const;
456 flattenTo(Result, Result, ShouldFlattenMacros);
471 bool addPosRange =
true)
474 "PathDiagnosticSpotPiece's must have a valid location.");
481 void Profile(llvm::FoldingSetNodeID &
ID)
const override;
498 virtual std::string getMessage(
const ExplodedNode *N) = 0;
522 virtual std::string getMessageForArg(
const Expr *ArgE,
unsigned ArgIndex);
540 std::unique_ptr<StackHintGenerator> CallStackHint;
544 StringRef s,
bool addPosRange =
true,
547 CallStackHint(stackHint) {}
554 if (IsPrunable.hasValue() && !
override)
556 IsPrunable = isPrunable;
561 return IsPrunable.hasValue() ? IsPrunable.getValue() :
false;
570 return CallStackHint->getMessage(N);
574 void dump()
const override;
583 const Decl *Callee =
nullptr;
591 bool IsCalleeAnAutosynthesizedPropertyAccessor =
false;
595 std::string CallStackMessage;
600 callReturn(callReturnPos) {}
623 std::shared_ptr<PathDiagnosticEventPiece> getCallEnterEvent()
const;
624 std::shared_ptr<PathDiagnosticEventPiece>
625 getCallEnterWithinCallerEvent()
const;
626 std::shared_ptr<PathDiagnosticEventPiece> getCallExitEvent()
const;
631 for (
const auto &I : path)
632 I->flattenLocations();
635 static std::shared_ptr<PathDiagnosticCallPiece>
642 void dump()
const override;
644 void Profile(llvm::FoldingSetNodeID &
ID)
const override;
652 std::vector<PathDiagnosticLocationPair> LPairs;
671 assert(!LPairs.empty() &&
672 "PathDiagnosticControlFlowPiece needs at least one location.");
673 return LPairs[0].getStart();
677 assert(!LPairs.empty() &&
678 "PathDiagnosticControlFlowPiece needs at least one location.");
679 return LPairs[0].getEnd();
683 LPairs[0].setStart(L);
693 return getStartLocation();
696 using iterator = std::vector<PathDiagnosticLocationPair>::iterator;
702 for (
auto &I : *
this)
707 std::vector<PathDiagnosticLocationPair>::const_iterator;
713 return P->
getKind() == ControlFlow;
716 void dump()
const override;
718 void Profile(llvm::FoldingSetNodeID &
ID)
const override;
729 bool containsEvent()
const;
733 for (
const auto &I : subPieces)
734 I->flattenLocations();
741 void dump()
const override;
743 void Profile(llvm::FoldingSetNodeID &
ID)
const override;
749 bool AddPosRange =
true)
757 void dump()
const override;
759 void Profile(llvm::FoldingSetNodeID &
ID)
const override;
770 const Decl *DeclWithIssue;
772 std::string VerboseDesc;
773 std::string ShortDesc;
775 std::deque<std::string> OtherDesc;
786 const Decl *UniqueingDecl;
789 std::unique_ptr<FilesToLineNumsMap> ExecutedLines;
794 StringRef bugtype, StringRef verboseDesc, StringRef shortDesc,
796 const Decl *DeclToUnique,
797 std::unique_ptr<FilesToLineNumsMap> ExecutedLines);
805 if (pathStack.empty())
807 return *pathStack.back();
816 unsigned full_size();
824 assert(!Loc.
isValid() &&
"End location already set!");
825 Loc = EndPiece->getLocation();
826 assert(Loc.isValid() &&
"Invalid location for end-of-path piece");
827 getActivePath().push_back(std::move(EndPiece));
831 if (!ShortDesc.empty())
839 void resetDiagnosticLocationToMainFile();
844 return ShortDesc.empty() ? VerboseDesc : ShortDesc;
860 void addMeta(StringRef s) { OtherDesc.push_back(s); }
865 return ExecutedLines->begin();
881 return UniqueingDecl;
886 for (
const auto &I : pathImpl)
887 I->flattenLocations();
894 void Profile(llvm::FoldingSetNodeID &
ID)
const;
900 void FullProfile(llvm::FoldingSetNodeID &ID)
const;
907 #endif // LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_PATHDIAGNOSTIC_H
bool isLastInMainSourceFile() const
PathDiagnosticSpotPiece(const PathDiagnosticLocation &pos, StringRef s, PathDiagnosticPiece::Kind k, bool addPosRange=true)
virtual void FlushDiagnosticsImpl(std::vector< const PathDiagnostic *> &Diags, FilesMade *filesMade)=0
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
Stmt - This represents one statement.
Decl - This represents one declaration (or definition), e.g.
virtual StringRef getName() const =0
Represents a point when we begin processing an inlined call.
Constructs a Stack hint for the given symbol.
void Profile(llvm::FoldingSetNodeID &ID) const
A Range represents the closed range [from, to].
PathDiagnosticMacroPiece(const PathDiagnosticLocation &pos)
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
void setPrunable(bool isPrunable, bool override=false)
Mark the diagnostic piece as being potentially prunable.
void flattenLocations() override
std::map< unsigned, std::set< unsigned > > FilesToLineNumsMap
File IDs mapped to sets of line numbers.
PathDiagnosticLocation getStartLocation() const
const PathDiagnosticLocation & getEnd() const
bool operator==(const PathDiagnosticLocation &X) const
void setAsLastInMainSourceFile()
meta_iterator meta_begin() const
void addRange(SourceRange R)
PathDiagnosticLocation getLocation() const
PathDiagnostic - PathDiagnostic objects represent a single path-sensitive diagnostic.
filesmap_iterator executedLines_begin() const
PathDiagnosticNotePiece(const PathDiagnosticLocation &Pos, StringRef S, bool AddPosRange=true)
void setStartLocation(const PathDiagnosticLocation &L)
void addRange(SourceLocation B, SourceLocation E)
AnalysisDeclContext contains the context data for the function or method under analysis.
static bool classof(const PathDiagnosticPiece *P)
StringRef getVerboseDescription() const
void pushActivePath(PathPieces *p)
virtual ~PathDiagnosticConsumer()
virtual bool supportsLogicalOpControlFlow() const
PathPieces & getMutablePieces()
Return a mutable version of 'path'.
const Decl * asDecl() const
PDFileEntry(llvm::FoldingSetNodeID &NodeID)
const_iterator begin() const
llvm::FoldingSet< PathDiagnostic > Diags
void setStart(const PathDiagnosticLocation &L)
const Stmt * asStmt() const
virtual std::string getMessageForReturn(const CallExpr *CallExpr)
static void dump(llvm::raw_ostream &OS, StringRef FunctionName, ArrayRef< CounterExpression > Expressions, ArrayRef< CounterMappingRegion > Regions)
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
std::vector< std::pair< StringRef, StringRef > > ConsumerFiles
bool operator!=(const PathDiagnosticLocation &X) const
A builtin binary operation expression such as "x + y" or "x <= y".
StringRef getBugType() const
void setEndOfPath(std::shared_ptr< PathDiagnosticPiece > EndPiece)
meta_iterator meta_end() const
static PathDiagnosticLocation create(const Decl *D, const SourceManager &SM)
Create a location corresponding to the given declaration.
StringRef getCheckName() const
PathDiagnosticLocation callEnter
PathDiagnosticLocation(const Stmt *s, const SourceManager &sm, LocationOrAnalysisDeclContext lac)
Create a location corresponding to the given statement.
PathDiagnosticLocation getEndLocation() const
ConditionalOperator - The ?: ternary operator.
CompoundStmt - This represents a group of statements like { stmt stmt }.
const void * getTag() const
Return the opaque tag (if any) on the PathDiagnosticPiece.
const Stmt * getStmtOrNull() const
void HandlePathDiagnostic(std::unique_ptr< PathDiagnostic > D)
std::vector< PathDiagnosticLocationPair >::const_iterator const_iterator
Represents a point when we finish the call exit sequence (for inlined call).
DisplayHint getDisplayHint() const
getDisplayHint - Return a hint indicating where the diagnostic should be displayed by the PathDiagnos...
Expr - This represents one expression.
bool isPrunable() const
Return true if the diagnostic piece is prunable.
PathDiagnosticLocation getUniqueingLoc() const
Get the location on which the report should be uniqued.
std::vector< PathDiagnosticLocationPair >::iterator iterator
const SourceManager & getManager() const
llvm::PointerUnion< const LocationContext *, AnalysisDeclContext * > LocationOrAnalysisDeclContext
const_iterator end() const
PathDiagnosticRange(SourceRange R, bool isP=false)
virtual std::string getMessageForSymbolNotFound()
Interface for classes constructing Stack hints.
PathPieces flatten(bool ShouldFlattenMacros) const
StringRef getCategory() const
Only runs visitors, no output generated.
PathDiagnosticConsumer()=default
const Decl * getCallee() const
const llvm::FoldingSetNodeID NodeID
A precomputed hash tag used for uniquing PDFileEntry objects.
void flattenLocations() override
void Profile(llvm::FoldingSetNodeID &ID) const
Encodes a location in the source.
std::string getCallStackMessage(const ExplodedNode *N)
Produce the hint for the given node.
void addMeta(StringRef s)
PathDiagnosticLocation callReturn
std::deque< std::string >::const_iterator meta_iterator
FullSourceLoc asLocation() const
virtual bool supportsCrossFileDiagnostics() const
Return true if the PathDiagnosticConsumer supports individual PathDiagnostics that span multiple file...
PathDiagnosticLocation getLocation() const override
Used for plist output, used for "arrows" generation.
void flattenLocations() override
ConsumerFiles files
A vector of <consumer,file> pairs.
static PathDiagnosticLocation createBegin(const Decl *D, const SourceManager &SM, const LocationOrAnalysisDeclContext LAC)
Create a location for the beginning of the declaration.
ArrayRef< SourceRange > getRanges() const
Return the SourceRanges associated with this PathDiagnosticPiece.
Dataflow Directional Tag Classes.
const PathDiagnosticLocation & getStart() const
bool isValid() const
Return true if this is a valid SourceLocation object.
PathDiagnosticControlFlowPiece(const PathDiagnosticLocation &startPos, const PathDiagnosticLocation &endPos)
void FlushDiagnostics(FilesMade *FilesMade)
PathDiagnosticRange asRange() const
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
PathDiagnosticEventPiece(const PathDiagnosticLocation &pos, StringRef s, bool addPosRange=true, StackHintGenerator *stackHint=nullptr)
void setEndLocation(const PathDiagnosticLocation &L)
PathDiagnosticLocationPair(const PathDiagnosticLocation &start, const PathDiagnosticLocation &end)
bool isWithinCall() const
void appendToDesc(StringRef S)
virtual PathGenerationScheme getGenerationScheme() const
PathDiagnosticLocation(SourceLocation loc, const SourceManager &sm)
Create a location at an explicit offset in the source.
PathDiagnosticLocation(const Decl *d, const SourceManager &sm)
Create a location corresponding to the given declaration.
void setCallStackMessage(StringRef st)
void push_back(const PathDiagnosticLocationPair &X)
static bool classof(const PathDiagnosticPiece *P)
void Profile(llvm::FoldingSetNodeID &ID)
Used for profiling in the FoldingSet.
PathDiagnosticLocation getLocation() const override
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
Used for HTML and text output.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
Defines the clang::SourceLocation class and associated facilities.
PathPieces & getActivePath()
Return the path currently used by builders for constructing the PathDiagnostic.
const Decl * getCaller() const
unsigned kind
All of the diagnostics that can be emitted by the frontend.
static bool classof(const PathDiagnosticPiece *P)
void flattenLocations() override
StringRef getTagStr() const
Return the string representation of the tag.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
A SourceLocation and its associated SourceManager.
PathDiagnosticLocation callEnterWithin
FilesToLineNumsMap::const_iterator filesmap_iterator
const Decl * getUniqueingDecl() const
Get the declaration containing the uniqueing location.
A trivial tuple used to represent a source range.
static bool classof(const PathDiagnosticPiece *P)
StackHintGeneratorForSymbol(SymbolRef S, StringRef M)
StringRef getString() const
filesmap_iterator executedLines_end() const
This class handles loading and caching of source files into memory.
static bool classof(const PathDiagnosticPiece *P)
StringRef getShortDescription() const
const Decl * getDeclWithIssue() const
Return the semantic context where an issue occurred.
void setEnd(const PathDiagnosticLocation &L)
static bool classof(const PathDiagnosticPiece *P)