28 llvm_unreachable(
"Unhandled ProgramPoint kind");
57 return "BlockEntrance";
63 return "PreStmtPurgeDeadSymbols";
65 return "PostStmtPurgeDeadSymbols";
77 return "PostCondition";
81 return "PostAllocatorCall";
83 return "PostInitializer";
87 return "CallExitBegin";
91 return "FunctionExit";
93 return "PreImplicitCall";
95 return "PostImplicitCall";
101 llvm_unreachable(
"Unknown ProgramPoint kind");
114 if (
const auto *B = castAs<BlockExit>().getBlock()) {
115 if (
const auto *
T = B->getTerminatorStmt()) {
116 return T->getBeginLoc();
131 if (
const Stmt *S = castAs<StmtPoint>().getStmt())
132 return S->getBeginLoc();
135 if (
const auto *
Init = castAs<PostInitializer>().getInitializer())
136 return Init->getSourceLocation();
139 if (
const Stmt *S = castAs<CallEnter>().getCallExpr())
140 return S->getBeginLoc();
143 if (
const Stmt *S = castAs<CallExitBegin>().getReturnStmt())
144 return S->getBeginLoc();
149 if (
const auto *B = castAs<FunctionExitPoint>().getBlock();
150 B && B->getTerminatorStmt())
151 return B->getTerminatorStmt()->getBeginLoc();
154 return castAs<ImplicitCallPoint>().getLocation();
156 return castAs<ImplicitCallPoint>().getLocation();
158 if (
const Stmt *S = castAs<LoopExit>().getLoopStmt())
159 return S->getBeginLoc();
164 llvm_unreachable(
"Unknown ProgramPoint kind");
172 const bool AddQuotes =
true;
174 Out <<
"\"kind\": \"";
177 Out <<
"BlockEntrance\""
178 <<
", \"block_id\": "
179 << castAs<BlockEntrance>().getBlock()->getBlockID();
183 auto FEP = getAs<FunctionExitPoint>();
184 Out <<
"FunctionExit\""
185 <<
", \"block_id\": " << FEP->getBlock()->getBlockID()
186 <<
", \"stmt_id\": ";
189 Out << RS->getID(Context) <<
", \"stmt\": ";
190 RS->printJson(Out,
nullptr, PP, AddQuotes);
192 Out <<
"null, \"stmt\": null";
197 llvm_unreachable(
"BlockExitKind");
200 Out <<
"CallEnter\", \"callee_decl\": \"";
202 castAs<CallEnter>().getCalleeContext()->getDecl())
206 Out <<
"CallExitBegin\"";
209 Out <<
"CallExitEnd\"";
212 Out <<
"EpsilonPoint\"";
216 Out <<
"LoopExit\", \"stmt\": \""
217 << castAs<LoopExit>().getLoopStmt()->getStmtClassName() <<
'\"';
222 Out <<
"PreCall\", \"decl\": \""
224 <<
"\", \"location\": ";
231 Out <<
"PostCall\", \"decl\": \""
233 <<
"\", \"location\": ";
239 Out <<
"PostInitializer\", ";
242 Out <<
"\"field_decl\": \"" << *FD <<
'\"';
244 Out <<
"\"type\": \"";
255 const Stmt *
T =
E.getSrc()->getTerminatorStmt();
256 Out <<
"Edge\", \"src_id\": " <<
E.getSrc()->getBlockID()
257 <<
", \"dst_id\": " <<
E.getDst()->getBlockID() <<
", \"terminator\": ";
260 Out <<
"null, \"term_kind\": null";
264 E.getSrc()->printTerminatorJson(Out, Context.
getLangOpts(),
266 Out <<
", \"location\": ";
269 Out <<
", \"term_kind\": \"";
270 if (isa<SwitchStmt>(
T)) {
271 Out <<
"SwitchStmt\", \"case\": ";
272 if (
const Stmt *
Label =
E.getDst()->getLabel()) {
273 if (
const auto *
C = dyn_cast<CaseStmt>(
Label)) {
274 Out <<
"{ \"lhs\": ";
275 if (
const Stmt *LHS =
C->getLHS()) {
276 LHS->printJson(Out,
nullptr, PP, AddQuotes);
281 Out <<
", \"rhs\": ";
282 if (
const Stmt *RHS =
C->getRHS()) {
283 RHS->printJson(Out,
nullptr, PP, AddQuotes);
289 assert(isa<DefaultStmt>(
Label));
290 Out <<
"\"default\"";
293 Out <<
"\"implicit default\"";
295 }
else if (isa<IndirectGotoStmt>(
T)) {
297 Out <<
"IndirectGotoStmt\"";
299 Out <<
"Condition\", \"value\": "
300 << (*
E.getSrc()->succ_begin() ==
E.getDst() ?
"true" :
"false");
306 const Stmt *S = castAs<StmtPoint>().getStmt();
307 assert(S !=
nullptr &&
"Expecting non-null Stmt");
309 Out <<
"Statement\", \"stmt_kind\": \"" << S->getStmtClassName()
310 <<
"\", \"stmt_id\": " << S->getID(Context)
311 <<
", \"pointer\": \"" << (
const void *)S <<
"\", ";
312 if (
const auto *CS = dyn_cast<CastExpr>(S))
313 Out <<
"\"cast_kind\": \"" << CS->getCastKindName() <<
"\", ";
315 Out <<
"\"pretty\": ";
317 S->printJson(Out,
nullptr, PP, AddQuotes);
319 Out <<
", \"location\": ";
322 Out <<
", \"stmt_point_kind\": \"";
323 if (getAs<PreLoad>())
325 else if (getAs<PreStore>())
327 else if (getAs<PostAllocatorCall>())
328 Out <<
"PostAllocatorCall";
329 else if (getAs<PostCondition>())
330 Out <<
"PostCondition";
331 else if (getAs<PostLoad>())
333 else if (getAs<PostLValue>())
335 else if (getAs<PostStore>())
337 else if (getAs<PostStmt>())
339 else if (getAs<PostStmtPurgeDeadSymbols>())
340 Out <<
"PostStmtPurgeDeadSymbols";
341 else if (getAs<PreStmtPurgeDeadSymbols>())
342 Out <<
"PreStmtPurgeDeadSymbols";
343 else if (getAs<PreStmt>())
346 Out <<
"\nKind: '" <<
getKind();
347 llvm_unreachable(
"' is unhandled StmtPoint kind!");
358 : Desc((MsgProvider +
" : " + Msg).str()) {}
Defines the clang::ASTContext interface.
This file defines AnalysisDeclContext, a class that manages the analysis context data for context sen...
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
SourceManager & getSourceManager()
const LangOptions & getLangOpts() const
const clang::PrintingPolicy & getPrintingPolicy() const
static std::string getFunctionName(const Decl *D)
ASTContext & getASTContext() const
Represents a C++ base or member initializer.
FunctionDecl * getAsFunction() LLVM_READONLY
Returns the function itself, or the templated function if this is a function template.
Represents a member of a struct/union/class.
Represents an implicit call event.
SourceLocation getLocation() const
const Decl * getDecl() const
It wraps the AnalysisDeclContext to represent both the call stack with the help of StackFrameContext ...
LLVM_ATTRIBUTE_RETURNS_NONNULL AnalysisDeclContext * getAnalysisDeclContext() const
std::string getQualifiedNameAsString() const
Represents a point after we ran remove dead bindings AFTER processing the given statement.
Represents a point after we ran remove dead bindings BEFORE processing the given statement.
ProgramPoints can be "tagged" as representing points specific to a given analysis entity.
virtual ~ProgramPointTag()
static ProgramPoint getProgramPoint(const Stmt *S, ProgramPoint::Kind K, const LocationContext *LC, const ProgramPointTag *tag)
static StringRef getProgramPointKindName(Kind K)
LLVM_DUMP_METHOD void dump() const
std::optional< SourceLocation > getSourceLocation() const
void printJson(llvm::raw_ostream &Out, const char *NL="\n") const
@ PreStmtPurgeDeadSymbolsKind
@ PostStmtPurgeDeadSymbolsKind
const LocationContext * getLocationContext() const
A (possibly-)qualified type.
QualType getLocalUnqualifiedType() const
Return this type with all of the instance-specific qualifiers removed, but without removing any quali...
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
ReturnStmt - This represents a return, optionally of an expression: return; return 4;.
StringRef getDebugTag() const override
The description of this program point which will be dumped for debugging purposes.
SimpleProgramPointTag(StringRef MsgProvider, StringRef Msg)
This class handles loading and caching of source files into memory.
Stmt - This represents one statement.
The JSON file list parser is used to communicate input to InstallAPI.
void printSourceLocationAsJson(raw_ostream &Out, SourceLocation Loc, const SourceManager &SM, bool AddBraces=true)
const FunctionProtoType * T
Describes how types, statements, expressions, and declarations should be printed.