aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Analysis/ProgramPoint.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Analysis/ProgramPoint.cpp')
-rw-r--r--clang/lib/Analysis/ProgramPoint.cpp115
1 files changed, 115 insertions, 0 deletions
diff --git a/clang/lib/Analysis/ProgramPoint.cpp b/clang/lib/Analysis/ProgramPoint.cpp
index 7945c5c..e508681 100644
--- a/clang/lib/Analysis/ProgramPoint.cpp
+++ b/clang/lib/Analysis/ProgramPoint.cpp
@@ -49,6 +49,121 @@ LLVM_DUMP_METHOD void ProgramPoint::dump() const {
return printJson(llvm::errs());
}
+StringRef ProgramPoint::getProgramPointKindName(Kind K) {
+ switch (K) {
+ case BlockEdgeKind:
+ return "BlockEdge";
+ case BlockEntranceKind:
+ return "BlockEntrance";
+ case BlockExitKind:
+ return "BlockExit";
+ case PreStmtKind:
+ return "PreStmt";
+ case PreStmtPurgeDeadSymbolsKind:
+ return "PreStmtPurgeDeadSymbols";
+ case PostStmtPurgeDeadSymbolsKind:
+ return "PostStmtPurgeDeadSymbols";
+ case PostStmtKind:
+ return "PostStmt";
+ case PreLoadKind:
+ return "PreLoad";
+ case PostLoadKind:
+ return "PostLoad";
+ case PreStoreKind:
+ return "PreStore";
+ case PostStoreKind:
+ return "PostStore";
+ case PostConditionKind:
+ return "PostCondition";
+ case PostLValueKind:
+ return "PostLValue";
+ case PostAllocatorCallKind:
+ return "PostAllocatorCall";
+ case PostInitializerKind:
+ return "PostInitializer";
+ case CallEnterKind:
+ return "CallEnter";
+ case CallExitBeginKind:
+ return "CallExitBegin";
+ case CallExitEndKind:
+ return "CallExitEnd";
+ case FunctionExitKind:
+ return "FunctionExit";
+ case PreImplicitCallKind:
+ return "PreImplicitCall";
+ case PostImplicitCallKind:
+ return "PostImplicitCall";
+ case LoopExitKind:
+ return "LoopExit";
+ case EpsilonKind:
+ return "Epsilon";
+ }
+ llvm_unreachable("Unknown ProgramPoint kind");
+}
+
+std::optional<SourceLocation> ProgramPoint::getSourceLocation() const {
+ switch (getKind()) {
+ case BlockEdgeKind:
+ // If needed, the source and or destination beginning can be used to get
+ // source location.
+ return std::nullopt;
+ case BlockEntranceKind:
+ // If needed, first statement of the block can be used.
+ return std::nullopt;
+ case BlockExitKind:
+ if (const auto *B = castAs<BlockExit>().getBlock()) {
+ if (const auto *T = B->getTerminatorStmt()) {
+ return T->getBeginLoc();
+ }
+ }
+ return std::nullopt;
+ case PreStmtKind:
+ case PreStmtPurgeDeadSymbolsKind:
+ case PostStmtPurgeDeadSymbolsKind:
+ case PostStmtKind:
+ case PreLoadKind:
+ case PostLoadKind:
+ case PreStoreKind:
+ case PostStoreKind:
+ case PostConditionKind:
+ case PostLValueKind:
+ case PostAllocatorCallKind:
+ if (const Stmt *S = castAs<StmtPoint>().getStmt())
+ return S->getBeginLoc();
+ return std::nullopt;
+ case PostInitializerKind:
+ if (const auto *Init = castAs<PostInitializer>().getInitializer())
+ return Init->getSourceLocation();
+ return std::nullopt;
+ case CallEnterKind:
+ if (const Stmt *S = castAs<CallEnter>().getCallExpr())
+ return S->getBeginLoc();
+ return std::nullopt;
+ case CallExitBeginKind:
+ if (const Stmt *S = castAs<CallExitBegin>().getReturnStmt())
+ return S->getBeginLoc();
+ return std::nullopt;
+ case CallExitEndKind:
+ return std::nullopt;
+ case FunctionExitKind:
+ if (const auto *B = castAs<FunctionExitPoint>().getBlock();
+ B && B->getTerminatorStmt())
+ return B->getTerminatorStmt()->getBeginLoc();
+ return std::nullopt;
+ case PreImplicitCallKind:
+ return castAs<ImplicitCallPoint>().getLocation();
+ case PostImplicitCallKind:
+ return castAs<ImplicitCallPoint>().getLocation();
+ case LoopExitKind:
+ if (const Stmt *S = castAs<LoopExit>().getLoopStmt())
+ return S->getBeginLoc();
+ return std::nullopt;
+ case EpsilonKind:
+ return std::nullopt;
+ }
+ llvm_unreachable("Unknown ProgramPoint kind");
+}
+
void ProgramPoint::printJson(llvm::raw_ostream &Out, const char *NL) const {
const ASTContext &Context =
getLocationContext()->getAnalysisDeclContext()->getASTContext();