36 #include "llvm/ADT/ArrayRef.h" 37 #include "llvm/ADT/FoldingSet.h" 38 #include "llvm/ADT/None.h" 39 #include "llvm/ADT/Optional.h" 40 #include "llvm/ADT/STLExtras.h" 41 #include "llvm/ADT/SmallString.h" 42 #include "llvm/ADT/SmallVector.h" 43 #include "llvm/ADT/StringExtras.h" 44 #include "llvm/ADT/StringRef.h" 45 #include "llvm/Support/Casting.h" 46 #include "llvm/Support/ErrorHandling.h" 47 #include "llvm/Support/raw_ostream.h" 54 using namespace clang;
59 if (isa<PathDiagnosticEventPiece>(*
P))
61 if (
const auto *MP = dyn_cast<PathDiagnosticMacroPiece>(
P.get()))
62 if (MP->containsEvent())
69 for (StringRef::size_type i = s.size(); i != 0; --i)
71 return s.substr(0, i);
80 : kind(k), Hint(hint) {}
95 bool ShouldFlattenMacros)
const {
96 for (
auto &Piece : *
this) {
97 switch (Piece->getKind()) {
99 auto &
Call = cast<PathDiagnosticCallPiece>(*Piece);
102 Call.path.flattenTo(Primary, Primary, ShouldFlattenMacros);
103 if (
auto callExit =
Call.getCallExitEvent())
104 Current.push_back(std::move(callExit));
108 auto &
Macro = cast<PathDiagnosticMacroPiece>(*Piece);
109 if (ShouldFlattenMacros) {
110 Macro.subPieces.flattenTo(Primary, Primary, ShouldFlattenMacros);
112 Current.push_back(Piece);
114 Macro.subPieces.flattenTo(Primary, NewPath, ShouldFlattenMacros);
116 Macro.subPieces = NewPath;
123 Current.push_back(Piece);
132 StringRef
CheckName,
const Decl *declWithIssue, StringRef bugtype,
133 StringRef verboseDesc, StringRef shortDesc, StringRef category,
135 std::unique_ptr<FilesToLineNumsMap> ExecutedLines)
136 : CheckName(CheckName), DeclWithIssue(declWithIssue),
141 UniqueingDecl(DeclToUnique), ExecutedLines(
std::move(ExecutedLines)),
154 "The call piece should not be in a header file.");
166 if (
auto *CPInner = dyn_cast<PathDiagnosticCallPiece>(Path.back().get()))
183 if (
auto *CP = dyn_cast<PathDiagnosticCallPiece>(LastP)) {
187 CP->setAsLastInMainSourceFile();
190 const auto *ND = dyn_cast<
NamedDecl>(CP->getCallee());
193 llvm::raw_svector_ostream os(buf);
194 os <<
" (within a call to '" << ND->getDeclName() <<
"')";
199 DeclWithIssue = CP->getCaller();
200 Loc = CP->getLocation();
207 void PathDiagnosticConsumer::anchor() {}
211 for (
auto &
Diag : Diags)
216 std::unique_ptr<PathDiagnostic> D) {
217 if (!D || D->path.empty())
223 D->flattenLocations();
227 if (!supportsCrossFileDiagnostics()) {
230 const SourceManager &SMgr = D->path.front()->getLocation().getManager();
232 WorkList.push_back(&D->path);
234 llvm::raw_svector_ostream warning(buf);
235 warning <<
"warning: Path diagnostic report is not generated. Current " 236 <<
"output format does not support diagnostics that cross file " 237 <<
"boundaries. Refer to --analyzer-output for valid output " 240 while (!WorkList.empty()) {
243 for (
const auto &I : path) {
250 llvm::errs() << warning.str();
256 for (
const auto &I : Ranges) {
259 llvm::errs() << warning.str();
264 llvm::errs() << warning.str();
269 if (
const auto *call = dyn_cast<PathDiagnosticCallPiece>(piece))
270 WorkList.push_back(&call->path);
271 else if (
const auto *macro = dyn_cast<PathDiagnosticMacroPiece>(piece))
272 WorkList.push_back(¯o->subPieces);
281 llvm::FoldingSetNodeID profile;
283 void *InsertPos =
nullptr;
285 if (
PathDiagnostic *orig = Diags.FindNodeOrInsertPos(profile, InsertPos)) {
290 const unsigned orig_size = orig->full_size();
291 const unsigned new_size = D->full_size();
292 if (orig_size <= new_size)
295 assert(orig != D.get());
296 Diags.RemoveNode(orig);
300 Diags.InsertNode(D.release());
332 if (X_CEWL != Y_CEWL)
359 for (
unsigned i = 0, n = X.
getRanges().size(); i < n; ++i) {
372 cast<PathDiagnosticControlFlowPiece>(Y));
378 cast<PathDiagnosticMacroPiece>(Y));
380 return compareCall(cast<PathDiagnosticCallPiece>(X),
381 cast<PathDiagnosticCallPiece>(Y));
383 llvm_unreachable(
"all cases handled");
387 if (X.size() != Y.size())
388 return X.size() < Y.size();
390 PathPieces::const_iterator X_I = X.begin(), X_end = X.end();
391 PathPieces::const_iterator Y_I = Y.begin(), Y_end = Y.end();
393 for ( ; X_I != X_end && Y_I != Y_end; ++X_I, ++Y_I) {
415 return NameCmp == -1;
450 if (XE - XI != YE - YI)
451 return (XE - XI) < (YE - YI);
452 for ( ; XI != XE ; ++XI, ++YI) {
454 return (*XI) < (*YI);
457 assert(b.hasValue());
468 std::vector<const PathDiagnostic *> BatchDiags;
469 for (
const auto &D : Diags)
470 BatchDiags.push_back(&D);
476 assert(*X != *Y &&
"PathDiagnostics not uniqued!");
479 assert(
compare(**Y, **X) &&
"Not a total order!");
482 array_pod_sort(BatchDiags.begin(), BatchDiags.end(), Comp);
484 FlushDiagnosticsImpl(BatchDiags, Files);
487 for (
const auto D : BatchDiags)
496 Entry.~PDFileEntry();
500 StringRef ConsumerName,
501 StringRef FileName) {
502 llvm::FoldingSetNodeID NodeID;
505 PDFileEntry *Entry = Set.FindNodeOrInsertPos(NodeID, InsertPos);
509 Set.InsertNode(Entry, InsertPos);
513 char *FileName_cstr = (
char*) Alloc.Allocate(FileName.size(), 1);
514 memcpy(FileName_cstr, FileName.data(), FileName.size());
516 Entry->
files.push_back(std::make_pair(ConsumerName,
517 StringRef(FileName_cstr,
523 llvm::FoldingSetNodeID NodeID;
526 PDFileEntry *Entry = Set.FindNodeOrInsertPos(NodeID, InsertPos);
529 return &Entry->
files;
538 bool UseEnd =
false) {
540 assert(!LAC.isNull() &&
"A valid LocationContext or AnalysisDeclContext should " 541 "be passed to PathDiagnosticLocation upon creation.");
556 Parent = PM.getParent(Parent);
608 if (
const Stmt *CallerBody = CallerInfo->
getBody())
626 llvm_unreachable(
"not yet implemented!");
629 llvm_unreachable(
"CFGElement kind should not be on callsite!");
632 llvm_unreachable(
"Unknown CFGElement kind");
653 if (
const auto *CS = dyn_cast<CompoundStmt>(S))
654 return createEndBrace(CS, SM);
696 if (
const auto *CS = dyn_cast_or_null<CompoundStmt>(LC->
getDecl()->
getBody()))
697 if (!CS->body_empty()) {
715 const Stmt* S =
nullptr;
717 const CFGBlock *BSrc = BE->getSrc();
730 CE->getLocationContext(),
734 CEE->getLocationContext(),
737 CFGElement BlockFront = BE->getBlock()->front();
742 NewAllocElt->getAllocatorExpr()->getLocStart(), SMng);
744 llvm_unreachable(
"Unexpected CFG element at front of block");
746 llvm_unreachable(
"Unexpected ProgramPoint");
756 assert(ParentLC &&
"We don't start analysis from autosynthesized code");
757 while (ParentLC->getAnalysisDeclContext()->isBodyAutosynthesized()) {
760 assert(ParentLC &&
"We don't start analysis from autosynthesized code");
778 return SP->getStmt();
780 return BE->getSrc()->getTerminator();
782 return CE->getCallExpr();
784 return CEE->getCalleeContext()->getCallSite();
786 return PIPP->getInitializer()->getInit();
788 return CEB->getReturnStmt();
795 if (
const Stmt *S = getStmt(N)) {
798 switch (S->getStmtClass()) {
799 case Stmt::ChooseExprClass:
800 case Stmt::BinaryConditionalOperatorClass:
801 case Stmt::ConditionalOperatorClass:
803 case Stmt::BinaryOperatorClass: {
805 if (Op == BO_LAnd || Op == BO_LOr)
823 assert(N &&
"Cannot create a location with a null node.");
824 const Stmt *S = getStmt(N);
838 if (
const auto *ME = dyn_cast<MemberExpr>(S))
842 if (
const auto *B = dyn_cast<BinaryOperator>(S))
877 const_cast<SourceManager&>(*
SM));
899 const Stmt *S = asStmt();
903 case Stmt::DeclStmtClass: {
904 const auto *DS = cast<DeclStmt>(S);
905 if (DS->isSingleDecl()) {
908 DS->getSingleDecl()->getLocation());
914 case Stmt::IfStmtClass:
915 case Stmt::WhileStmtClass:
916 case Stmt::DoStmtClass:
917 case Stmt::ForStmtClass:
918 case Stmt::ChooseExprClass:
919 case Stmt::IndirectGotoStmtClass:
920 case Stmt::SwitchStmtClass:
921 case Stmt::BinaryConditionalOperatorClass:
922 case Stmt::ConditionalOperatorClass:
923 case Stmt::ObjCForCollectionStmtClass: {
934 if (
const auto *MD = dyn_cast<ObjCMethodDecl>(D))
935 return MD->getSourceRange();
936 if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
937 if (
Stmt *Body = FD->getBody())
938 return Body->getSourceRange();
955 else if (K == DeclK) {
966 std::shared_ptr<PathDiagnosticCallPiece>
973 return std::shared_ptr<PathDiagnosticCallPiece>(
979 const Decl *caller) {
980 std::shared_ptr<PathDiagnosticCallPiece> C(
984 path.push_front(std::move(C));
1002 if (
const auto *MD = dyn_cast<ObjCMethodDecl>(Callee))
1003 IsCalleeAnAutosynthesizedPropertyAccessor = (
1004 MD->isPropertyAccessor() &&
1011 StringRef Prefix = StringRef(),
1012 StringRef Postfix = StringRef());
1018 if (TArg.
getKind() == TemplateArgument::ArgKind::Pack) {
1028 StringRef Prefix, StringRef Postfix) {
1033 for (
int I = 0,
Last = TAList.size() - 1; I !=
Last; ++I) {
1042 StringRef Prefix = StringRef()) {
1045 Out << Prefix <<
'\'' << *D;
1046 if (
const auto T = dyn_cast<ClassTemplateSpecializationDecl>(D))
1048 D->getASTContext().getLangOpts(),
"<",
">");
1054 bool ExtendedDescription,
1055 StringRef Prefix = StringRef()) {
1059 if (isa<BlockDecl>(D)) {
1060 if (ExtendedDescription)
1061 Out << Prefix <<
"anonymous block";
1062 return ExtendedDescription;
1065 if (
const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
1067 if (ExtendedDescription && !MD->isUserProvided()) {
1068 if (MD->isExplicitlyDefaulted())
1069 Out <<
"defaulted ";
1074 if (
const auto *CD = dyn_cast<CXXConstructorDecl>(MD)) {
1075 if (CD->isDefaultConstructor())
1077 else if (CD->isCopyConstructor())
1079 else if (CD->isMoveConstructor())
1082 Out <<
"constructor";
1084 }
else if (isa<CXXDestructorDecl>(MD)) {
1085 if (!MD->isUserProvided()) {
1086 Out <<
"destructor";
1090 Out <<
"'" << *MD <<
"'";
1092 }
else if (MD->isCopyAssignmentOperator()) {
1093 Out <<
"copy assignment operator";
1095 }
else if (MD->isMoveAssignmentOperator()) {
1096 Out <<
"move assignment operator";
1099 if (MD->getParent()->getIdentifier())
1100 Out <<
"'" << *MD->getParent() <<
"::" << *MD <<
"'";
1102 Out <<
"'" << *MD <<
"'";
1108 Out << Prefix << '\'' << cast<NamedDecl>(*D);
1111 if (
const auto FD = dyn_cast<FunctionDecl>(D))
1113 FD->getTemplateSpecializationArgs())
1115 FD->getASTContext().getLangOpts(),
"<",
">");
1121 std::shared_ptr<PathDiagnosticEventPiece>
1127 if (!Callee || IsCalleeAnAutosynthesizedPropertyAccessor)
1131 llvm::raw_svector_ostream Out(buf);
1136 assert(callEnter.asLocation().isValid());
1137 return std::make_shared<PathDiagnosticEventPiece>(callEnter, Out.str());
1140 std::shared_ptr<PathDiagnosticEventPiece>
1142 if (!callEnterWithin.asLocation().isValid())
1144 if (Callee->isImplicit() || !Callee->hasBody())
1146 if (
const auto *MD = dyn_cast<CXXMethodDecl>(Callee))
1147 if (MD->isDefaulted())
1151 llvm::raw_svector_ostream Out(buf);
1153 Out <<
"Entered call";
1156 return std::make_shared<PathDiagnosticEventPiece>(callEnterWithin, Out.str());
1159 std::shared_ptr<PathDiagnosticEventPiece>
1165 if (NoExit || IsCalleeAnAutosynthesizedPropertyAccessor)
1169 llvm::raw_svector_ostream Out(buf);
1171 if (!CallStackMessage.empty()) {
1172 Out << CallStackMessage;
1178 Out <<
"Returning to caller";
1181 assert(callReturn.asLocation().isValid());
1182 return std::make_shared<PathDiagnosticEventPiece>(callReturn, Out.str());
1186 for (
const auto &I : pieces) {
1188 if (
const auto *cp = dyn_cast<PathDiagnosticCallPiece>(piece))
1206 ID.AddInteger(
Range.getBegin().getRawEncoding());
1207 ID.AddInteger(
Range.getEnd().getRawEncoding());
1208 ID.AddInteger(
Loc.getRawEncoding());
1212 ID.AddInteger((
unsigned)
getKind());
1215 ID.AddInteger((
unsigned) getDisplayHint());
1217 for (
const auto &I : Ranges) {
1218 ID.AddInteger(I.getBegin().getRawEncoding());
1219 ID.AddInteger(I.getEnd().getRawEncoding());
1225 for (
const auto &I :
path)
1236 for (
const auto &I : *
this)
1242 for (
const auto &I : subPieces)
1253 ID.AddString(VerboseDesc);
1254 ID.AddString(Category);
1259 for (
const auto &I :
path)
1269 return getMessageForSymbolNotFound();
1276 const auto *CE = dyn_cast_or_null<CallExpr>(CallSite);
1281 unsigned ArgIndex = 0;
1283 E = CE->arg_end(); I != E; ++I, ++ArgIndex){
1289 return getMessageForArg(*I, ArgIndex);
1295 if ((*I)->getType()->isVoidPointerType())
1300 return getMessageForArg(*I, ArgIndex);
1308 if (RetSym == Sym) {
1309 return getMessageForReturn(CE);
1312 return getMessageForSymbolNotFound();
1316 unsigned ArgIndex) {
1321 llvm::raw_svector_ostream os(buf);
1323 os << Msg <<
" via " << ArgIndex << llvm::getOrdinalSuffix(ArgIndex)
1331 for (PathPieces::const_iterator I = begin(), E = end(); I != E; ++I) {
1332 llvm::errs() <<
"[" << index++ <<
"] ";
1334 llvm::errs() <<
"\n";
1339 llvm::errs() <<
"CALL\n--------------\n";
1343 else if (
const auto *ND = dyn_cast_or_null<NamedDecl>(getCallee()))
1344 llvm::errs() << *ND <<
"\n";
1350 llvm::errs() <<
"EVENT\n--------------\n";
1351 llvm::errs() << getString() <<
"\n";
1352 llvm::errs() <<
" ---- at ----\n";
1357 llvm::errs() <<
"CONTROL\n--------------\n";
1358 getStartLocation().dump();
1359 llvm::errs() <<
" ---- to ----\n";
1360 getEndLocation().dump();
1364 llvm::errs() <<
"MACRO\n--------------\n";
1369 llvm::errs() <<
"NOTE\n--------------\n";
1370 llvm::errs() << getString() <<
"\n";
1371 llvm::errs() <<
" ---- at ----\n";
1377 llvm::errs() <<
"<INVALID>\n";
1384 llvm::errs() <<
"<range>\n";
1387 asLocation().dump();
1388 llvm::errs() <<
"\n";
1394 llvm::errs() <<
"<NULL STMT>\n";
1397 if (
const auto *ND = dyn_cast_or_null<NamedDecl>(D))
1398 llvm::errs() << *ND <<
"\n";
1399 else if (isa<BlockDecl>(D))
1401 llvm::errs() <<
"<block>\n";
1403 llvm::errs() <<
"<unknown decl>\n";
1405 llvm::errs() <<
"<NULL DECL>\n";
SourceLocation getRBracLoc() const
Represents C++ allocator call.
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
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.
ArrayRef< TemplateArgument > getPackAsArray() const
Return the array of arguments in this template argument pack.
Defines the clang::FileManager interface and associated types.
~PathDiagnosticMacroPiece() override
static void compute_path_size(const PathPieces &pieces, unsigned &size)
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()
C Language Family Type Representation.
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
Defines the C++ template declaration subclasses.
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.
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
A Range represents the closed range [from, to].
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)
void dump() const override
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
meta_iterator meta_begin() const
const Stmt * getTriggerStmt() const
Describes how types, statements, expressions, and declarations should be printed. ...
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
Get the identifier that names this declaration, if there is one.
AnalysisDeclContext contains the context data for the function or method under analysis.
Represents C++ object destructor implicitly generated for automatic object or temporary bound to cons...
StringRef getVerboseDescription() const
void dump() const override
static const LocationContext * findTopAutosynthesizedParentContext(const LocationContext *LC)
~PathDiagnosticControlFlowPiece() override
static bool isInCodeFile(SourceLocation SL, const SourceManager &SM)
virtual ~PathDiagnosticConsumer()
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Optional< T > getLocationAs() const LLVM_LVALUE_FUNCTION
Represents a point when we start the call exit sequence (for inlined call).
static PathDiagnosticCallPiece * getFirstStackedCallToHeaderFile(PathDiagnosticCallPiece *CP, const SourceManager &SMgr)
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
std::vector< std::pair< StringRef, StringRef > > ConsumerFiles
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".
void dump() const override
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
void print(const PrintingPolicy &Policy, raw_ostream &Out) const
Print this template argument to the given output stream.
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
void HandlePathDiagnostic(std::unique_ptr< PathDiagnostic > D)
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)
std::pair< FileID, unsigned > getDecomposedLoc() const
Decompose the specified location into a raw FileID + Offset pair.
const FileEntry * getFileEntryForID(FileID FID) const
Returns the FileEntry record for the provided FileID.
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.
static void describeTemplateParameters(raw_ostream &Out, const ArrayRef< TemplateArgument > TAList, const LangOptions &LO, StringRef Prefix=StringRef(), StringRef Postfix=StringRef())
llvm::PointerUnion< const LocationContext *, AnalysisDeclContext * > LocationOrAnalysisDeclContext
void resetDiagnosticLocationToMainFile()
If the last piece of the report point to the header file, resets the location of the report to be the...
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...
PathDiagnosticPiece()=delete
StringRef getCategory() const
static Optional< bool > comparePiece(const PathDiagnosticPiece &X, const PathDiagnosticPiece &Y)
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
StringRef getName() 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
SourceLocation getLocStart() const LLVM_READONLY
void setCallee(const CallEnter &CE, const SourceManager &SM)
Cached information about one file (either on disk or in the virtual file system). ...
std::deque< std::string >::const_iterator meta_iterator
static PathDiagnosticLocation createConditionalColonLoc(const ConditionalOperator *CO, const SourceManager &SM)
std::pair< bool, bool > isInTheSameTranslationUnit(std::pair< FileID, unsigned > &LOffs, std::pair< FileID, unsigned > &ROffs) const
Determines whether the two decomposed source location is in the same translation unit.
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.
const Decl * getDecl() const
FullSourceLoc asLocation() const
SourceLocation getLocEnd() const LLVM_READONLY
SVal getSVal(const Stmt *S) const
Get the value of an arbitrary expression at this node.
void dump() const override
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
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...
Represents a template argument.
ConsumerFiles files
A vector of <consumer,file> pairs.
ArrayRef< SourceRange > getRanges() const
Return the SourceRanges associated with this PathDiagnosticPiece.
Dataflow Directional Tag Classes.
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
static Optional< bool > compareCall(const PathDiagnosticCallPiece &X, const PathDiagnosticCallPiece &Y)
void Profile(llvm::FoldingSetNodeID &ID) const override
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
static void describeTemplateParameter(raw_ostream &Out, const TemplateArgument &TArg, const LangOptions &LO)
const LocationContext * getLocationContext() const
void Profile(llvm::FoldingSetNodeID &ID) const override
A template argument list.
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 ...
const CXXNewExpr * getAllocatorExpr() const
ArgKind getKind() const
Return the kind of stored template argument.
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.
Defines the clang::SourceLocation class and associated facilities.
Represents a C++ struct/union/class.
void dump() const override
static PathDiagnosticLocation createEndOfPath(const ExplodedNode *N, const SourceManager &SM)
Create a location corresponding to the next valid ExplodedNode as end of path location.
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...
FullSourceLoc getSpellingLoc() const
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)
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.
This represents a decl that may have 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 getBegin() const
static Optional< bool > compareControlFlow(const PathDiagnosticControlFlowPiece &X, const PathDiagnosticControlFlowPiece &Y)
This class handles loading and caching of source files into memory.
Represents C++ object destructor implicitly generated at the end of full expression for temporary obj...
SourceLocation getBodyRBrace() const
getBodyRBrace - Gets the right brace of the body, if a body exists.
SourceLocation getLocation() const
static bool compareCrossTUSourceLocs(FullSourceLoc XL, FullSourceLoc YL)
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.