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);
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();
203 if (!supportsCrossFileDiagnostics()) {
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()) {
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;
267 if (
PathDiagnostic *orig = Diags.FindNodeOrInsertPos(profile, InsertPos)) {
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);
450 FlushDiagnosticsImpl(BatchDiags, Files);
453 for (std::vector<const PathDiagnostic *>::iterator it = BatchDiags.begin(),
454 et = BatchDiags.end(); it != et; ++it) {
465 Entry.~PDFileEntry();
469 StringRef ConsumerName,
470 StringRef FileName) {
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.");
525 Parent = PM.getParent(Parent);
575 if (
const Stmt *CallerBody = CallerInfo->
getBody())
581 llvm_unreachable(
"not yet implemented!");
584 llvm_unreachable(
"CFGElement kind should not be on callsite!");
587 llvm_unreachable(
"Unknown CFGElement kind");
609 return createEndBrace(CS, SM);
654 if (!CS->body_empty()) {
672 const Stmt* S =
nullptr;
674 const CFGBlock *BSrc = BE->getSrc();
687 CE->getLocationContext(),
691 CEE->getLocationContext(),
694 CFGElement BlockFront = BE->getBlock()->front();
699 NewAllocElt->getAllocatorExpr()->getLocStart(), SMng);
701 llvm_unreachable(
"Unexpected CFG element at front of block");
703 llvm_unreachable(
"Unexpected ProgramPoint");
713 assert(ParentLC &&
"We don't start analysis from autosynthesized code");
714 while (ParentLC->getAnalysisDeclContext()->isBodyAutosynthesized()) {
717 assert(ParentLC &&
"We don't start analysis from autosynthesized code");
735 return SP->getStmt();
737 return BE->getSrc()->getTerminator();
739 return CE->getCallExpr();
741 return CEE->getCalleeContext()->getCallSite();
743 return PIPP->getInitializer()->getInit();
750 if (
const Stmt *S = getStmt(N)) {
753 switch (S->getStmtClass()) {
754 case Stmt::ChooseExprClass:
755 case Stmt::BinaryConditionalOperatorClass:
756 case Stmt::ConditionalOperatorClass:
758 case Stmt::BinaryOperatorClass: {
760 if (Op == BO_LAnd || Op == BO_LOr)
778 assert(N &&
"Cannot create a location with a null node.");
779 const Stmt *S = getStmt(N);
793 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(S))
832 const_cast<SourceManager&>(*
SM));
854 const Stmt *S = asStmt();
858 case Stmt::DeclStmtClass: {
859 const DeclStmt *DS = cast<DeclStmt>(S);
869 case Stmt::IfStmtClass:
870 case Stmt::WhileStmtClass:
871 case Stmt::DoStmtClass:
872 case Stmt::ForStmtClass:
873 case Stmt::ChooseExprClass:
874 case Stmt::IndirectGotoStmtClass:
875 case Stmt::SwitchStmtClass:
876 case Stmt::BinaryConditionalOperatorClass:
877 case Stmt::ConditionalOperatorClass:
878 case Stmt::ObjCForCollectionStmtClass: {
890 return MD->getSourceRange();
891 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
892 if (
Stmt *Body = FD->getBody())
893 return Body->getSourceRange();
910 else if (K == DeclK) {
921 std::shared_ptr<PathDiagnosticCallPiece>
928 return std::shared_ptr<PathDiagnosticCallPiece>(
934 const Decl *caller) {
935 std::shared_ptr<PathDiagnosticCallPiece> C(
939 path.push_front(std::move(C));
958 IsCalleeAnAutosynthesizedPropertyAccessor = (
959 MD->isPropertyAccessor() &&
964 StringRef Prefix = StringRef()) {
967 Out << Prefix <<
'\'' << *D <<
'\'';
971 bool ExtendedDescription,
972 StringRef Prefix = StringRef()) {
976 if (isa<BlockDecl>(D)) {
977 if (ExtendedDescription)
978 Out << Prefix <<
"anonymous block";
979 return ExtendedDescription;
984 if (ExtendedDescription && !MD->isUserProvided()) {
985 if (MD->isExplicitlyDefaulted())
992 if (CD->isDefaultConstructor())
994 else if (CD->isCopyConstructor())
996 else if (CD->isMoveConstructor())
999 Out <<
"constructor";
1002 }
else if (isa<CXXDestructorDecl>(MD)) {
1003 if (!MD->isUserProvided()) {
1004 Out <<
"destructor";
1008 Out <<
"'" << *MD <<
"'";
1011 }
else if (MD->isCopyAssignmentOperator()) {
1012 Out <<
"copy assignment operator";
1015 }
else if (MD->isMoveAssignmentOperator()) {
1016 Out <<
"move assignment operator";
1020 if (MD->getParent()->getIdentifier())
1021 Out <<
"'" << *MD->getParent() <<
"::" << *MD <<
"'";
1023 Out <<
"'" << *MD <<
"'";
1029 Out << Prefix << '\'' << cast<NamedDecl>(*D) <<
'\'';
1033 std::shared_ptr<PathDiagnosticEventPiece>
1039 if (!Callee || IsCalleeAnAutosynthesizedPropertyAccessor)
1043 llvm::raw_svector_ostream Out(buf);
1048 assert(callEnter.asLocation().isValid());
1049 return std::make_shared<PathDiagnosticEventPiece>(callEnter, Out.str());
1052 std::shared_ptr<PathDiagnosticEventPiece>
1054 if (!callEnterWithin.asLocation().isValid())
1056 if (Callee->isImplicit() || !Callee->hasBody())
1058 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Callee))
1059 if (MD->isDefaulted())
1063 llvm::raw_svector_ostream Out(buf);
1065 Out <<
"Entered call";
1068 return std::make_shared<PathDiagnosticEventPiece>(callEnterWithin, Out.str());
1071 std::shared_ptr<PathDiagnosticEventPiece>
1077 if (NoExit || IsCalleeAnAutosynthesizedPropertyAccessor)
1081 llvm::raw_svector_ostream Out(buf);
1083 if (!CallStackMessage.empty()) {
1084 Out << CallStackMessage;
1090 Out <<
"Returning to caller";
1093 assert(callReturn.asLocation().isValid());
1094 return std::make_shared<PathDiagnosticEventPiece>(callReturn, Out.str());
1098 for (PathPieces::const_iterator it = pieces.begin(),
1099 et = pieces.end(); it != et; ++it) {
1102 dyn_cast<PathDiagnosticCallPiece>(piece)) {
1121 ID.AddInteger(Range.getBegin().getRawEncoding());
1122 ID.AddInteger(Range.getEnd().getRawEncoding());
1123 ID.AddInteger(
Loc.getRawEncoding());
1127 ID.AddInteger((
unsigned)
getKind());
1130 ID.AddInteger((
unsigned) getDisplayHint());
1134 ID.AddInteger(I->getBegin().getRawEncoding());
1135 ID.AddInteger(I->getEnd().getRawEncoding());
1141 for (PathPieces::const_iterator it =
path.begin(),
1142 et =
path.end(); it != et; ++it) {
1160 for (PathPieces::const_iterator I = subPieces.begin(), E = subPieces.end();
1172 ID.AddString(VerboseDesc);
1173 ID.AddString(Category);
1178 for (PathPieces::const_iterator I =
path.begin(), E =
path.end(); I != E; ++I)
1192 const CallExpr *CE = dyn_cast_or_null<CallExpr>(CallSite);
1197 return getMessageForSymbolNotFound();
1202 unsigned ArgIndex = 0;
1204 E = CE->
arg_end(); I != E; ++I, ++ArgIndex){
1205 SVal SV = State->getSVal(*I, LCtx);
1210 return getMessageForArg(*I, ArgIndex);
1215 SVal PSV = State->getSVal(Reg->getRegion());
1218 return getMessageForArg(*I, ArgIndex);
1224 SVal SV = State->getSVal(CE, LCtx);
1226 if (RetSym == Sym) {
1227 return getMessageForReturn(CE);
1230 return getMessageForSymbolNotFound();
1234 unsigned ArgIndex) {
1239 llvm::raw_svector_ostream os(buf);
1241 os << Msg <<
" via " << ArgIndex << llvm::getOrdinalSuffix(ArgIndex)
SourceLocation getRBracLoc() const
CFGNewAllocator - Represents C++ allocator call.
An instance of this class is created to represent a function declaration or definition.
Expr * getInit() const
Get the initializer.
static Optional< bool > compareMacro(const PathDiagnosticMacroPiece &X, const PathDiagnosticMacroPiece &Y)
const Stmt * getStmt() const
Stmt * getBody() const
Get the body of the Declaration.
~PathDiagnosticMacroPiece() override
static void compute_path_size(const PathPieces &pieces, unsigned &size)
std::deque< std::string >::const_iterator meta_iterator
virtual Stmt * getBody() const
getBody - If this Decl represents a declaration for a body of code, such as a function or method defi...
FullSourceLoc getExpansionLoc() const
Stmt - This represents one statement.
virtual ~PathDiagnosticPiece()
Defines the SourceManager interface.
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
void Profile(llvm::FoldingSetNodeID &ID) const
Profiles the diagnostic, independent of the path it references.
bool isBeforeInTranslationUnit(SourceLocation LHS, SourceLocation RHS) const
Determines the order of 2 source locations in the translation unit.
CFGDeleteDtor - Represents C++ object destructor generated from a call to delete. ...
std::shared_ptr< PathDiagnosticEventPiece > getCallEnterWithinCallerEvent() const
virtual std::string getMessageForArg(const Expr *ArgE, unsigned ArgIndex)
Produces the message of the following form: 'Msg via Nth parameter'.
void Profile(llvm::FoldingSetNodeID &ID) const
Represents a program point just before an implicit call event.
virtual ~StackHintGenerator()=0
T castAs() const
Convert to the specified CFGElement type, asserting that this CFGElement is of the desired type...
SourceLocation getLocEnd() const LLVM_READONLY
const ProgramStateRef & getState() const
static std::shared_ptr< PathDiagnosticCallPiece > construct(const ExplodedNode *N, const CallExitEnd &CE, const SourceManager &SM)
Represents a C++ constructor within a class.
PathDiagnosticLocation getStartLocation() const
static PathDiagnosticLocation createEndBrace(const CompoundStmt *CS, const SourceManager &SM)
Create a location for the end of the compound statement.
SymbolRef getAsLocSymbol(bool IncludeBaseRegions=false) const
If this SVal is a location and wraps a symbol, return that SymbolRef.
SourceLocation getColonLoc() const
ObjCMethodDecl - Represents an instance or class method declaration.
meta_iterator meta_begin() const
const Stmt * getTriggerStmt() const
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.
PathDiagnosticLocation getLocation() const
PathDiagnostic - PathDiagnostic objects represent a single path-sensitive diagnostic.
IdentifierInfo * getIdentifier() const
getIdentifier - Get the identifier that names this declaration, if there is one.
DeclarationName getDeclName() const
getDeclName - Get the actual, stored name of the declaration, which may be a special name...
AnalysisDeclContext contains the context data for the function or method under analysis.
CFGAutomaticObjDtor - Represents C++ object destructor implicitly generated for automatic object or t...
StringRef getVerboseDescription() const
static const LocationContext * findTopAutosynthesizedParentContext(const LocationContext *LC)
~PathDiagnosticControlFlowPiece() override
virtual ~PathDiagnosticConsumer()
Optional< T > getLocationAs() const LLVM_LVALUE_FUNCTION
static PathDiagnosticCallPiece * getFirstStackedCallToHeaderFile(PathDiagnosticCallPiece *CP, const SourceManager &SMgr)
std::vector< PathDiagnosticLocationPair >::const_iterator const_iterator
SourceLocation getLBracLoc() const
void Profile(llvm::FoldingSetNodeID &ID) const override
SourceLocation getExpansionLoc(SourceLocation Loc) const
Given a SourceLocation object Loc, return the expansion location referenced by the ID...
const LocationContext * getLocationContext() const
const LocationContext * getParent() 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...
StringRef getBugType() const
meta_iterator meta_end() const
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)
PathDiagnosticLocation callEnter
virtual PathDiagnosticLocation getLocation() const =0
PathDiagnosticLocation getEndLocation() const
static SourceLocation getValidSourceLocation(const Stmt *S, LocationOrAnalysisDeclContext LAC, bool UseEnd=false)
const CFGBlock * getCallSiteBlock() const
static PathDiagnosticLocation createMemberLoc(const MemberExpr *ME, const SourceManager &SM)
For member expressions, return the location of the '.
CXXCtorInitializer * getInitializer() const
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 }.
const Stmt * getCallSite() const
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)
Represents a point when we finish the call exit sequence (for inlined call).
void FullProfile(llvm::FoldingSetNodeID &ID) const
Profiles the diagnostic, including its path.
Expr - This represents one expression.
Stmt * getTerminatorCondition(bool StripParens=true)
static bool compare(const PathDiagnostic &X, const PathDiagnostic &Y)
const SourceManager & getManager() const
const SourceManager & getManager() 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.
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
bool isBodyAutosynthesized() const
Checks if the body of the Decl is generated by the BodyFarm.
SourceLocation getEnd() const
SourceLocation getMemberLoc() const
getMemberLoc - Return the location of the "member", in X->F, it is the location of 'F'...
Optional< T > getAs() const
Convert to the specified SVal type, returning None if this SVal is not of the desired type...
StringRef getCategory() const
static Optional< bool > comparePiece(const PathDiagnosticPiece &X, const PathDiagnosticPiece &Y)
llvm::PointerUnion< const LocationContext *, AnalysisDeclContext * > LocationOrAnalysisDeclContext
static const Stmt * getStmt(const ExplodedNode *N)
Given an exploded node, retrieve the statement that should be used for the diagnostic location...
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
std::shared_ptr< PathDiagnosticEventPiece > getCallEnterEvent() const
bool isBeforeInTranslationUnitThan(SourceLocation Loc) const
Determines the order of 2 source locations in the translation unit.
Encodes a location in the source.
SourceLocation getOperatorLoc() const
std::shared_ptr< PathDiagnosticEventPiece > getCallExitEvent() const
T castAs() const
Convert to the specified ProgramPoint type, asserting that this ProgramPoint is of the desired type...
PathDiagnosticLocation callReturn
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.
static bool describeCodeDecl(raw_ostream &Out, const Decl *D, bool ExtendedDescription, StringRef Prefix=StringRef())
ProgramPoint getLocation() const
getLocation - Returns the edge associated with the given node.
SVal - This represents a symbolic expression, which can be either an L-value or an R-value...
static PathDiagnosticLocation createEnd(const Stmt *S, const SourceManager &SM, const LocationOrAnalysisDeclContext LAC)
Create a location for the end of the statement.
bool isInMainFile(SourceLocation Loc) const
Returns whether the PresumedLoc for a given SourceLocation is in the main file.
const Decl * getDecl() const
FullSourceLoc asLocation() const
Optional< T > getAs() const
Convert to the specified CFGElement type, returning None if this CFGElement is not of the desired typ...
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
ConsumerFiles files
A vector of <consumer,file> pairs.
ArrayRef< SourceRange > getRanges() const
Return the SourceRanges associated with this PathDiagnosticPiece.
Dataflow Directional Tag Classes.
SourceLocation getLocStart() const LLVM_READONLY
bool isValid() const
Return true if this is a valid SourceLocation object.
Represents a program point just after an implicit call event.
virtual void Profile(llvm::FoldingSetNodeID &ID) const
static void describeClass(raw_ostream &Out, const CXXRecordDecl *D, StringRef Prefix=StringRef())
const StackFrameContext * getCalleeContext() const
void FlushDiagnostics(FilesMade *FilesMade)
BinaryOperator::Opcode getOpcode(const SymExpr *SE)
const StackFrameContext * getCalleeContext() const
const ExplodedNode * getFirstSucc() const
StmtClass getStmtClass() const
const Decl * getSingleDecl() const
static Optional< bool > compareCall(const PathDiagnosticCallPiece &X, const PathDiagnosticCallPiece &Y)
void Profile(llvm::FoldingSetNodeID &ID) const override
bool isSingleDecl() const
isSingleDecl - This method returns true if this DeclStmt refers to a single Decl. ...
const Decl * getDecl() const
const CXXDeleteExpr * getDeleteExpr() const
void appendToDesc(StringRef S)
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
unsigned getIndex() const
const LocationContext * getLocationContext() const
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.
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)
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
static Decl::Kind getKind(const Decl *D)
void Profile(llvm::FoldingSetNodeID &ID) const override
void addDiagnostic(const PathDiagnostic &PD, StringRef ConsumerName, StringRef fileName)
CFGInitializer - Represents C++ base or member initializer from constructor's initialization list...
~PathDiagnosticNotePiece() override
bool containsEvent() const
ParentMap & getParentMap()
A trivial tuple used to represent a source range.
NamedDecl - This represents a decl with a name.
Optional< T > getAs() const
Convert to the specified ProgramPoint type, returning None if this ProgramPoint is not of the desired...
AnalysisDeclContext * getAnalysisDeclContext() const
StringRef getString() const
SourceLocation getLocStart() const LLVM_READONLY
SourceLocation getBegin() const
static Optional< bool > compareControlFlow(const PathDiagnosticControlFlowPiece &X, const PathDiagnosticControlFlowPiece &Y)
This class handles loading and caching of source files into memory.
SourceLocation getBodyRBrace() const
getBodyRBrace - Gets the right brace of the body, if a body exists.
SourceLocation getLocation() const
unsigned full_size()
Return the unrolled size of the path.
void Profile(llvm::FoldingSetNodeID &ID) const override
StringRef getShortDescription() const
const Decl * getDeclWithIssue() const
Return the semantic context where an issue occurred.