24 #include "llvm/ADT/SmallString.h"
25 #include "llvm/ADT/StringExtras.h"
26 #include "llvm/Support/raw_ostream.h"
28 using namespace clang;
33 if (isa<PathDiagnosticEventPiece>(*
P))
35 if (
auto *MP = dyn_cast<PathDiagnosticMacroPiece>(
P.get()))
36 if (MP->containsEvent())
43 for (StringRef::size_type i = s.size(); i != 0; --i)
45 return s.substr(0, i);
49 PathDiagnosticPiece::PathDiagnosticPiece(StringRef s,
52 LastInMainSourceFile(
false) {}
55 :
kind(k), Hint(hint), LastInMainSourceFile(
false) {}
65 bool ShouldFlattenMacros)
const {
66 for (
auto &Piece : *
this) {
67 switch (Piece->getKind()) {
69 auto &Call = cast<PathDiagnosticCallPiece>(*Piece);
70 if (
auto CallEnter = Call.getCallEnterEvent())
72 Call.path.flattenTo(Primary, Primary, ShouldFlattenMacros);
73 if (
auto callExit = Call.getCallExitEvent())
74 Current.push_back(std::move(callExit));
78 auto &Macro = cast<PathDiagnosticMacroPiece>(*Piece);
79 if (ShouldFlattenMacros) {
80 Macro.subPieces.flattenTo(Primary, Primary, ShouldFlattenMacros);
82 Current.push_back(Piece);
84 Macro.subPieces.flattenTo(Primary, NewPath, ShouldFlattenMacros);
86 Macro.subPieces = NewPath;
93 Current.push_back(Piece);
101 PathDiagnostic::PathDiagnostic(StringRef
CheckName,
const Decl *declWithIssue,
102 StringRef bugtype, StringRef verboseDesc,
103 StringRef shortDesc, StringRef category,
105 const Decl *DeclToUnique)
106 : CheckName(CheckName),
107 DeclWithIssue(declWithIssue),
112 UniqueingLoc(LocationToUnique),
113 UniqueingDecl(DeclToUnique),
126 "The call piece should be in the main file.");
139 dyn_cast<PathDiagnosticCallPiece>(Path.back().get())) {
161 CP->setAsLastInMainSourceFile();
167 llvm::raw_svector_ostream os(buf);
168 os <<
" (within a call to '" << ND->
getDeclName() <<
"')";
173 DeclWithIssue = CP->getCaller();
174 Loc = CP->getLocation();
181 void PathDiagnosticConsumer::anchor() { }
185 for (llvm::FoldingSet<PathDiagnostic>::iterator it =
186 Diags.begin(), et =
Diags.end() ; it != et ; ++it) {
192 std::unique_ptr<PathDiagnostic> D) {
193 if (!D || D->path.empty())
199 D->flattenLocations();
206 const SourceManager &SMgr = D->path.front()->getLocation().getManager();
208 WorkList.push_back(&D->path);
210 llvm::raw_svector_ostream warning(buf);
211 warning <<
"warning: Path diagnostic report is not generated. Current "
212 <<
"output format does not support diagnostics that cross file "
213 <<
"boundaries. Refer to --analyzer-output for valid output "
216 while (!WorkList.empty()) {
217 const PathPieces &path = *WorkList.pop_back_val();
219 for (PathPieces::const_iterator
I = path.begin(),
E = path.end();
I !=
E;
227 llvm::errs() << warning.str();
234 E = Ranges.end();
I !=
E; ++
I) {
237 llvm::errs() << warning.str();
242 llvm::errs() << warning.str();
248 dyn_cast<PathDiagnosticCallPiece>(piece)) {
249 WorkList.push_back(&call->path);
252 dyn_cast<PathDiagnosticMacroPiece>(piece)) {
253 WorkList.push_back(¯o->subPieces);
263 llvm::FoldingSetNodeID profile;
265 void *InsertPos =
nullptr;
272 const unsigned orig_size = orig->full_size();
273 const unsigned new_size = D->full_size();
274 if (orig_size <= new_size)
277 assert(orig != D.get());
278 Diags.RemoveNode(orig);
282 Diags.InsertNode(D.release());
314 if (X_CEWL != Y_CEWL)
341 for (
unsigned i = 0, n = X.
getRanges().size(); i < n; ++i) {
354 cast<PathDiagnosticControlFlowPiece>(Y));
360 cast<PathDiagnosticMacroPiece>(Y));
362 return compareCall(cast<PathDiagnosticCallPiece>(X),
363 cast<PathDiagnosticCallPiece>(Y));
365 llvm_unreachable(
"all cases handled");
369 if (X.size() != Y.size())
370 return X.size() < Y.size();
372 PathPieces::const_iterator X_I = X.begin(), X_end = X.end();
373 PathPieces::const_iterator Y_I = Y.begin(), Y_end = Y.end();
375 for ( ; X_I != X_end && Y_I != Y_end; ++X_I, ++Y_I) {
413 if (XE - XI != YE - YI)
414 return (XE - XI) < (YE - YI);
415 for ( ; XI != XE ; ++XI, ++YI) {
417 return (*XI) < (*YI);
420 assert(b.hasValue());
431 std::vector<const PathDiagnostic *> BatchDiags;
432 for (llvm::FoldingSet<PathDiagnostic>::iterator it =
Diags.begin(),
433 et =
Diags.end(); it != et; ++it) {
435 BatchDiags.push_back(D);
442 assert(*X != *Y &&
"PathDiagnostics not uniqued!");
445 assert(
compare(**Y, **X) &&
"Not a total order!");
448 array_pod_sort(BatchDiags.begin(), BatchDiags.end(), Comp);
453 for (std::vector<const PathDiagnostic *>::iterator it = BatchDiags.begin(),
454 et = BatchDiags.end(); it != et; ++it) {
465 Entry.~PDFileEntry();
469 StringRef ConsumerName,
471 llvm::FoldingSetNodeID NodeID;
474 PDFileEntry *Entry = Set.FindNodeOrInsertPos(NodeID, InsertPos);
478 Set.InsertNode(Entry, InsertPos);
482 char *FileName_cstr = (
char*) Alloc.Allocate(FileName.size(), 1);
483 memcpy(FileName_cstr, FileName.data(), FileName.size());
485 Entry->
files.push_back(std::make_pair(ConsumerName,
486 StringRef(FileName_cstr,
492 llvm::FoldingSetNodeID NodeID;
495 PDFileEntry *Entry = Set.FindNodeOrInsertPos(NodeID, InsertPos);
498 return &Entry->
files;
507 bool UseEnd =
false) {
509 assert(!LAC.isNull() &&
"A valid LocationContext or AnalysisDeclContext should "
510 "be passed to PathDiagnosticLocation upon creation.");
523 const Stmt *Parent =
S;
525 Parent = PM.getParent(Parent);
575 if (
const Stmt *CallerBody = CallerInfo->
getBody())
582 llvm_unreachable(
"not yet implemented!");
585 llvm_unreachable(
"Unknown CFGElement kind");
607 return createEndBrace(CS, SM);
652 if (!CS->body_empty()) {
670 const Stmt*
S =
nullptr;
672 const CFGBlock *BSrc = BE->getSrc();
685 CE->getLocationContext(),
689 CEE->getLocationContext(),
692 llvm_unreachable(
"Unexpected ProgramPoint");
702 assert(ParentLC &&
"We don't start analysis from autosynthesized code");
703 while (ParentLC->getAnalysisDeclContext()->isBodyAutosynthesized()) {
706 assert(ParentLC &&
"We don't start analysis from autosynthesized code");
724 return SP->getStmt();
726 return BE->getSrc()->getTerminator();
728 return CE->getCallExpr();
730 return CEE->getCalleeContext()->getCallSite();
732 return PIPP->getInitializer()->getInit();
739 if (
const Stmt *
S = getStmt(N)) {
742 switch (
S->getStmtClass()) {
743 case Stmt::ChooseExprClass:
744 case Stmt::BinaryConditionalOperatorClass:
745 case Stmt::ConditionalOperatorClass:
747 case Stmt::BinaryOperatorClass: {
749 if (Op == BO_LAnd || Op == BO_LOr)
767 assert(N &&
"Cannot create a location with a null node.");
768 const Stmt *
S = getStmt(N);
782 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(S))
821 const_cast<SourceManager&>(*
SM));
843 const Stmt *
S = asStmt();
847 case Stmt::DeclStmtClass: {
858 case Stmt::IfStmtClass:
859 case Stmt::WhileStmtClass:
860 case Stmt::DoStmtClass:
861 case Stmt::ForStmtClass:
862 case Stmt::ChooseExprClass:
863 case Stmt::IndirectGotoStmtClass:
864 case Stmt::SwitchStmtClass:
865 case Stmt::BinaryConditionalOperatorClass:
866 case Stmt::ConditionalOperatorClass:
867 case Stmt::ObjCForCollectionStmtClass: {
879 return MD->getSourceRange();
880 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
881 if (
Stmt *Body = FD->getBody())
882 return Body->getSourceRange();
899 else if (K == DeclK) {
910 std::shared_ptr<PathDiagnosticCallPiece>
917 return std::shared_ptr<PathDiagnosticCallPiece>(
923 const Decl *caller) {
924 std::shared_ptr<PathDiagnosticCallPiece> C(
928 path.push_front(std::move(C));
947 IsCalleeAnAutosynthesizedPropertyAccessor = (
948 MD->isPropertyAccessor() &&
953 StringRef Prefix = StringRef()) {
956 Out << Prefix <<
'\'' << *D <<
'\'';
960 bool ExtendedDescription,
961 StringRef Prefix = StringRef()) {
965 if (isa<BlockDecl>(D)) {
966 if (ExtendedDescription)
967 Out << Prefix <<
"anonymous block";
968 return ExtendedDescription;
973 if (ExtendedDescription && !MD->isUserProvided()) {
974 if (MD->isExplicitlyDefaulted())
981 if (CD->isDefaultConstructor())
983 else if (CD->isCopyConstructor())
985 else if (CD->isMoveConstructor())
988 Out <<
"constructor";
991 }
else if (isa<CXXDestructorDecl>(MD)) {
992 if (!MD->isUserProvided()) {
997 Out <<
"'" << *MD <<
"'";
1000 }
else if (MD->isCopyAssignmentOperator()) {
1001 Out <<
"copy assignment operator";
1004 }
else if (MD->isMoveAssignmentOperator()) {
1005 Out <<
"move assignment operator";
1009 if (MD->getParent()->getIdentifier())
1010 Out <<
"'" << *MD->getParent() <<
"::" << *MD <<
"'";
1012 Out <<
"'" << *MD <<
"'";
1018 Out << Prefix << '\'' << cast<NamedDecl>(*D) <<
'\'';
1022 std::shared_ptr<PathDiagnosticEventPiece>
1028 if (!Callee || IsCalleeAnAutosynthesizedPropertyAccessor)
1032 llvm::raw_svector_ostream Out(buf);
1037 assert(callEnter.asLocation().isValid());
1038 return std::make_shared<PathDiagnosticEventPiece>(callEnter, Out.str());
1041 std::shared_ptr<PathDiagnosticEventPiece>
1043 if (!callEnterWithin.asLocation().isValid())
1045 if (Callee->isImplicit() || !Callee->hasBody())
1047 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Callee))
1048 if (MD->isDefaulted())
1052 llvm::raw_svector_ostream Out(buf);
1054 Out <<
"Entered call";
1057 return std::make_shared<PathDiagnosticEventPiece>(callEnterWithin, Out.str());
1060 std::shared_ptr<PathDiagnosticEventPiece>
1066 if (NoExit || IsCalleeAnAutosynthesizedPropertyAccessor)
1070 llvm::raw_svector_ostream Out(buf);
1072 if (!CallStackMessage.empty()) {
1073 Out << CallStackMessage;
1079 Out <<
"Returning to caller";
1082 assert(callReturn.asLocation().isValid());
1083 return std::make_shared<PathDiagnosticEventPiece>(callReturn, Out.str());
1087 for (PathPieces::const_iterator it = pieces.begin(),
1088 et = pieces.end(); it != et; ++it) {
1091 dyn_cast<PathDiagnosticCallPiece>(piece)) {
1110 ID.AddInteger(Range.getBegin().getRawEncoding());
1111 ID.AddInteger(Range.getEnd().getRawEncoding());
1112 ID.AddInteger(
Loc.getRawEncoding());
1116 ID.AddInteger((
unsigned)
getKind());
1119 ID.AddInteger((
unsigned) getDisplayHint());
1123 ID.AddInteger(
I->getBegin().getRawEncoding());
1124 ID.AddInteger(
I->getEnd().getRawEncoding());
1130 for (PathPieces::const_iterator it = path.begin(),
1131 et = path.end(); it != et; ++it) {
1149 for (PathPieces::const_iterator
I = subPieces.begin(),
E = subPieces.end();
1159 ID.Add(getLocation());
1161 ID.AddString(VerboseDesc);
1167 for (PathPieces::const_iterator
I = path.begin(),
E = path.end();
I !=
E; ++
I)
1181 const CallExpr *CE = dyn_cast_or_null<CallExpr>(CallSite);
1186 return getMessageForSymbolNotFound();
1191 unsigned ArgIndex = 0;
1194 SVal SV = State->getSVal(*
I, LCtx);
1199 return getMessageForArg(*
I, ArgIndex);
1204 SVal PSV = State->getSVal(Reg->getRegion());
1207 return getMessageForArg(*
I, ArgIndex);
1213 SVal SV = State->getSVal(CE, LCtx);
1215 if (RetSym == Sym) {
1216 return getMessageForReturn(CE);
1219 return getMessageForSymbolNotFound();
1223 unsigned ArgIndex) {
1228 llvm::raw_svector_ostream os(buf);
1230 os << Msg <<
" via " << ArgIndex << llvm::getOrdinalSuffix(ArgIndex)
SourceLocation getEnd() const
StmtClass getStmtClass() const
FunctionDecl - An instance of this class is created to represent a function declaration or definition...
static Optional< bool > compareMacro(const PathDiagnosticMacroPiece &X, const PathDiagnosticMacroPiece &Y)
~PathDiagnosticMacroPiece() override
static void compute_path_size(const PathPieces &pieces, unsigned &size)
IdentifierInfo * getIdentifier() const
getIdentifier - Get the identifier that names this declaration, if there is one.
std::deque< std::string >::const_iterator meta_iterator
Stmt - This represents one statement.
const StackFrameContext * getCalleeContext() const
virtual ~PathDiagnosticPiece()
Defines the SourceManager interface.
ProgramPoint getLocation() const
getLocation - Returns the edge associated with the given node.
Decl - This represents one declaration (or definition), e.g.
Represents a point when we begin processing an inlined call.
static PathDiagnosticLocation createBeginBrace(const CompoundStmt *CS, const SourceManager &SM)
Create a location for the beginning of the compound statement.
~PathDiagnosticEventPiece() override
StringRef getCategory() const
std::shared_ptr< PathDiagnosticEventPiece > getCallEnterWithinCallerEvent() const
const SourceManager & getManager() const
CFGDeleteDtor - Represents C++ object destructor generated from a call to delete. ...
virtual std::string getMessageForArg(const Expr *ArgE, unsigned ArgIndex)
Produces the message of the following form: 'Msg via Nth parameter'.
Represents a program point just before an implicit call event.
const CXXDeleteExpr * getDeleteExpr() const
virtual ~StackHintGenerator()=0
SourceLocation getOperatorLoc() const
SourceLocation getLocEnd() const LLVM_READONLY
static std::shared_ptr< PathDiagnosticCallPiece > construct(const ExplodedNode *N, const CallExitEnd &CE, const SourceManager &SM)
Represents a C++ constructor within a class.
static PathDiagnosticLocation createEndBrace(const CompoundStmt *CS, const SourceManager &SM)
Create a location for the end of the compound statement.
ArrayRef< SourceRange > getRanges() const
Return the SourceRanges associated with this PathDiagnosticPiece.
PathDiagnosticLocation getLocation() const
Expr * getInit() const
Get the initializer.
ObjCMethodDecl - Represents an instance or class method declaration.
std::shared_ptr< PathDiagnosticEventPiece > getCallExitEvent() const
const Decl * getDeclWithIssue() const
Return the semantic context where an issue occurred.
static PathDiagnosticLocation createDeclEnd(const LocationContext *LC, const SourceManager &SM)
Constructs a location for the end of the enclosing declaration body.
Defines the clang::Expr interface and subclasses for C++ expressions.
static PathDiagnosticLocation createSingleLocation(const PathDiagnosticLocation &PDL)
Convert the given location into a single kind location.
FullSourceLoc asLocation() const
PathDiagnostic - PathDiagnostic objects represent a single path-sensitive diagnostic.
bool isBodyAutosynthesized() const
Checks if the body of the Decl is generated by the BodyFarm.
AnalysisDeclContext contains the context data for the function or method under analysis.
CFGAutomaticObjDtor - Represents C++ object destructor implicitly generated for automatic object or t...
AnalysisDeclContext * getAnalysisDeclContext() const
SymbolRef getAsLocSymbol(bool IncludeBaseRegions=false) const
If this SVal is a location and wraps a symbol, return that SymbolRef.
StringRef getString() const
T castAs() const
Convert to the specified CFGElement type, asserting that this CFGElement is of the desired type...
static const LocationContext * findTopAutosynthesizedParentContext(const LocationContext *LC)
~PathDiagnosticControlFlowPiece() override
bool containsEvent() const
virtual ~PathDiagnosticConsumer()
SourceLocation getLBracLoc() const
Optional< T > getLocationAs() const LLVM_LVALUE_FUNCTION
virtual void Profile(llvm::FoldingSetNodeID &ID) const
static PathDiagnosticCallPiece * getFirstStackedCallToHeaderFile(PathDiagnosticCallPiece *CP, const SourceManager &SMgr)
llvm::FoldingSet< PathDiagnostic > Diags
std::vector< PathDiagnosticLocationPair >::const_iterator const_iterator
unsigned getIndex() const
void Profile(llvm::FoldingSetNodeID &ID) const override
const CFGBlock * getCallSiteBlock() const
A builtin binary operation expression such as "x + y" or "x <= y".
const Stmt * getCallSite() const
std::string getMessage(const ExplodedNode *N) override
Search the call expression for the symbol Sym and dispatch the 'getMessageForX()' methods to construc...
Represents a point after we ran remove dead bindings AFTER processing the given statement.
static PathDiagnosticLocation create(const Decl *D, const SourceManager &SM)
Create a location corresponding to the given declaration.
static Optional< bool > comparePath(const PathPieces &X, const PathPieces &Y)
const Decl * getDecl() const
meta_iterator meta_begin() const
PathDiagnosticLocation callEnter
detail::InMemoryDirectory::const_iterator I
virtual PathDiagnosticLocation getLocation() const =0
const Stmt * getTriggerStmt() const
static SourceLocation getValidSourceLocation(const Stmt *S, LocationOrAnalysisDeclContext LAC, bool UseEnd=false)
const LocationContext * getLocationContext() const
static PathDiagnosticLocation createMemberLoc(const MemberExpr *ME, const SourceManager &SM)
For member expressions, return the location of the '.
ConditionalOperator - The ?: ternary operator.
Const iterator for iterating over Stmt * arrays that contain only Expr *.
CompoundStmt - This represents a group of statements like { stmt stmt }.
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
SourceLocation getLocEnd() const LLVM_READONLY
void HandlePathDiagnostic(std::unique_ptr< PathDiagnostic > D)
CFGBlock - Represents a single basic block in a source-level CFG.
PDFileEntry::ConsumerFiles * getFiles(const PathDiagnostic &PD)
SourceLocation getBodyRBrace() const
getBodyRBrace - Gets the right brace of the body, if a body exists.
Stmt * getBody() const
Get the body of the Declaration.
Represents a point when we finish the call exit sequence (for inlined call).
Expr - This represents one expression.
const ProgramStateRef & getState() const
void FullProfile(llvm::FoldingSetNodeID &ID) const
Profiles the diagnostic, including its path.
Stmt * getTerminatorCondition(bool StripParens=true)
static bool compare(const PathDiagnostic &X, const PathDiagnostic &Y)
bool isBeforeInTranslationUnit(SourceLocation LHS, SourceLocation RHS) const
Determines the order of 2 source locations in the translation unit.
StringRef getShortDescription() const
const SourceManager & getManager() const
CXXCtorInitializer * getInitializer() const
Optional< T > getAs() const
Convert to the specified SVal type, returning None if this SVal is not of the desired type...
const ExplodedNode * getFirstSucc() const
PathDiagnosticLocation getEndLocation() const
static PathDiagnosticLocation getLocationForCaller(const StackFrameContext *SFC, const LocationContext *CallerCtx, const SourceManager &SM)
static const Stmt * getNextStmt(const ExplodedNode *N)
Retrieve the statement corresponding to the successor node.
T castAs() const
Convert to the specified ProgramPoint type, asserting that this ProgramPoint is of the desired type...
void resetDiagnosticLocationToMainFile()
If the last piece of the report point to the header file, resets the location of the report to be the...
std::vector< std::pair< StringRef, StringRef > > ConsumerFiles
DeclarationName getDeclName() const
getDeclName - Get the actual, stored name of the declaration, which may be a special name...
std::shared_ptr< PathDiagnosticEventPiece > getCallEnterEvent() const
virtual bool supportsCrossFileDiagnostics() const
Return true if the PathDiagnosticConsumer supports individual PathDiagnostics that span multiple file...
PathDiagnosticLocation getStartLocation() const
static Optional< bool > comparePiece(const PathDiagnosticPiece &X, const PathDiagnosticPiece &Y)
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...
bool isInMainFile(SourceLocation Loc) const
Returns whether the PresumedLoc for a given SourceLocation is in the main file.
SourceLocation getLocStart() const LLVM_READONLY
static PathDiagnosticLocation createDeclBegin(const LocationContext *LC, const SourceManager &SM)
Create a location for the beginning of the enclosing declaration body.
static PathDiagnosticLocation createBegin(const Decl *D, const SourceManager &SM)
Create a location for the beginning of the declaration.
~PathDiagnosticCallPiece() override
virtual void FlushDiagnosticsImpl(std::vector< const PathDiagnostic * > &Diags, FilesMade *filesMade)=0
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
StringRef getVerboseDescription() const
bool isSingleDecl() const
isSingleDecl - This method returns true if this DeclStmt refers to a single Decl. ...
PathDiagnosticLocation callReturn
void Profile(llvm::FoldingSetNodeID &ID) const
DeclStmt - Adaptor class for mixing declarations with statements and expressions. ...
void setCallee(const CallEnter &CE, const SourceManager &SM)
static PathDiagnosticLocation createConditionalColonLoc(const ConditionalOperator *CO, const SourceManager &SM)
Represents a static or instance method of a struct/union/class.
const Stmt * getStmt() const
static bool describeCodeDecl(raw_ostream &Out, const Decl *D, bool ExtendedDescription, StringRef Prefix=StringRef())
SVal - This represents a symbolic expression, which can be either an L-value or an R-value...
virtual Stmt * getBody() const
getBody - If this Decl represents a declaration for a body of code, such as a function or method defi...
static PathDiagnosticLocation createEnd(const Stmt *S, const SourceManager &SM, const LocationOrAnalysisDeclContext LAC)
Create a location for the end of the statement.
const StackFrameContext * getCalleeContext() const
const Decl * getDecl() const
SourceLocation getBegin() const
const Decl * getSingleDecl() const
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
ConsumerFiles files
A vector of <consumer,file> pairs.
const LocationContext * getParent() const
SourceLocation getLocStart() const LLVM_READONLY
Represents a program point just after an implicit call event.
static void describeClass(raw_ostream &Out, const CXXRecordDecl *D, StringRef Prefix=StringRef())
const LocationContext * getLocationContext() const
void FlushDiagnostics(FilesMade *FilesMade)
BinaryOperator::Opcode getOpcode(const SymExpr *SE)
static Optional< bool > compareCall(const PathDiagnosticCallPiece &X, const PathDiagnosticCallPiece &Y)
detail::InMemoryDirectory::const_iterator E
void Profile(llvm::FoldingSetNodeID &ID) const override
Optional< T > getAs() const
Convert to the specified ProgramPoint type, returning None if this ProgramPoint is not of the desired...
void appendToDesc(StringRef S)
SourceLocation getMemberLoc() const
getMemberLoc - Return the location of the "member", in X->F, it is the location of 'F'...
void Profile(llvm::FoldingSetNodeID &ID) const
Profiles the diagnostic, independent of the path it references.
void Profile(llvm::FoldingSetNodeID &ID) const override
static PathDiagnosticLocation createOperatorLoc(const BinaryOperator *BO, const SourceManager &SM)
Create the location for the operator of the binary expression.
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
bool isBeforeInTranslationUnitThan(SourceLocation Loc) const
Determines the order of 2 source locations in the translation unit.
Represents a C++ struct/union/class.
static PathDiagnosticLocation createEndOfPath(const ExplodedNode *N, const SourceManager &SM)
Create a location corresponding to the next valid ExplodedNode as end of path location.
CFGElement - Represents a top-level expression in a basic block.
static StringRef StripTrailingDots(StringRef s)
unsigned kind
All of the diagnostics that can be emitted by the frontend.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
A SourceLocation and its associated SourceManager.
PathDiagnosticLocation callEnterWithin
SourceLocation getRBracLoc() const
static Decl::Kind getKind(const Decl *D)
void Profile(llvm::FoldingSetNodeID &ID) const override
StringRef getBugType() const
void addDiagnostic(const PathDiagnostic &PD, StringRef ConsumerName, StringRef fileName)
FullSourceLoc getExpansionLoc() const
CFGInitializer - Represents C++ base or member initializer from constructor's initialization list...
~PathDiagnosticNotePiece() override
ParentMap & getParentMap()
A trivial tuple used to represent a source range.
SourceLocation getLocation() const
NamedDecl - This represents a decl with a name.
SourceLocation getExpansionLoc(SourceLocation Loc) const
Given a SourceLocation object Loc, return the expansion location referenced by the ID...
SourceLocation getLocStart() const LLVM_READONLY
static Optional< bool > compareControlFlow(const PathDiagnosticControlFlowPiece &X, const PathDiagnosticControlFlowPiece &Y)
This class handles loading and caching of source files into memory.
SourceLocation getColonLoc() const
unsigned full_size()
Return the unrolled size of the path.
void Profile(llvm::FoldingSetNodeID &ID) const override