aboutsummaryrefslogtreecommitdiff
path: root/lib/Analysis/ProgramPoint.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Analysis/ProgramPoint.cpp')
-rw-r--r--lib/Analysis/ProgramPoint.cpp175
1 files changed, 175 insertions, 0 deletions
diff --git a/lib/Analysis/ProgramPoint.cpp b/lib/Analysis/ProgramPoint.cpp
index d9833659d7b3..2d016cb13353 100644
--- a/lib/Analysis/ProgramPoint.cpp
+++ b/lib/Analysis/ProgramPoint.cpp
@@ -43,6 +43,181 @@ ProgramPoint ProgramPoint::getProgramPoint(const Stmt *S, ProgramPoint::Kind K,
}
}
+LLVM_DUMP_METHOD void ProgramPoint::dump() const {
+ return print(/*CR=*/"\n", llvm::errs());
+}
+
+static void printLocation(raw_ostream &Out, SourceLocation SLoc,
+ const SourceManager &SM,
+ StringRef CR,
+ StringRef Postfix) {
+ if (SLoc.isFileID()) {
+ Out << CR << "line=" << SM.getExpansionLineNumber(SLoc)
+ << " col=" << SM.getExpansionColumnNumber(SLoc) << Postfix;
+ }
+}
+
+void ProgramPoint::print(StringRef CR, llvm::raw_ostream &Out) const {
+ const ASTContext &Context =
+ getLocationContext()->getAnalysisDeclContext()->getASTContext();
+ const SourceManager &SM = Context.getSourceManager();
+ switch (getKind()) {
+ case ProgramPoint::BlockEntranceKind:
+ Out << "Block Entrance: B"
+ << castAs<BlockEntrance>().getBlock()->getBlockID();
+ break;
+
+ case ProgramPoint::FunctionExitKind: {
+ auto FEP = getAs<FunctionExitPoint>();
+ Out << "Function Exit: B" << FEP->getBlock()->getBlockID();
+ if (const ReturnStmt *RS = FEP->getStmt()) {
+ Out << CR << " Return: S" << RS->getID(Context) << CR;
+ RS->printPretty(Out, /*helper=*/nullptr, Context.getPrintingPolicy(),
+ /*Indentation=*/2, /*NewlineSymbol=*/CR);
+ }
+ break;
+ }
+ case ProgramPoint::BlockExitKind:
+ assert(false);
+ break;
+
+ case ProgramPoint::CallEnterKind:
+ Out << "CallEnter";
+ break;
+
+ case ProgramPoint::CallExitBeginKind:
+ Out << "CallExitBegin";
+ break;
+
+ case ProgramPoint::CallExitEndKind:
+ Out << "CallExitEnd";
+ break;
+
+ case ProgramPoint::PostStmtPurgeDeadSymbolsKind:
+ Out << "PostStmtPurgeDeadSymbols";
+ break;
+
+ case ProgramPoint::PreStmtPurgeDeadSymbolsKind:
+ Out << "PreStmtPurgeDeadSymbols";
+ break;
+
+ case ProgramPoint::EpsilonKind:
+ Out << "Epsilon Point";
+ break;
+
+ case ProgramPoint::LoopExitKind: {
+ LoopExit LE = castAs<LoopExit>();
+ Out << "LoopExit: " << LE.getLoopStmt()->getStmtClassName();
+ break;
+ }
+
+ case ProgramPoint::PreImplicitCallKind: {
+ ImplicitCallPoint PC = castAs<ImplicitCallPoint>();
+ Out << "PreCall: ";
+ PC.getDecl()->print(Out, Context.getLangOpts());
+ printLocation(Out, PC.getLocation(), SM, CR, /*Postfix=*/CR);
+ break;
+ }
+
+ case ProgramPoint::PostImplicitCallKind: {
+ ImplicitCallPoint PC = castAs<ImplicitCallPoint>();
+ Out << "PostCall: ";
+ PC.getDecl()->print(Out, Context.getLangOpts());
+ printLocation(Out, PC.getLocation(), SM, CR, /*Postfix=*/CR);
+ break;
+ }
+
+ case ProgramPoint::PostInitializerKind: {
+ Out << "PostInitializer: ";
+ const CXXCtorInitializer *Init = castAs<PostInitializer>().getInitializer();
+ if (const FieldDecl *FD = Init->getAnyMember())
+ Out << *FD;
+ else {
+ QualType Ty = Init->getTypeSourceInfo()->getType();
+ Ty = Ty.getLocalUnqualifiedType();
+ Ty.print(Out, Context.getLangOpts());
+ }
+ break;
+ }
+
+ case ProgramPoint::BlockEdgeKind: {
+ const BlockEdge &E = castAs<BlockEdge>();
+ Out << "Edge: (B" << E.getSrc()->getBlockID() << ", B"
+ << E.getDst()->getBlockID() << ')';
+
+ if (const Stmt *T = E.getSrc()->getTerminator()) {
+ SourceLocation SLoc = T->getBeginLoc();
+
+ Out << "\\|Terminator: ";
+ E.getSrc()->printTerminator(Out, Context.getLangOpts());
+ printLocation(Out, SLoc, SM, CR, /*Postfix=*/"");
+
+ if (isa<SwitchStmt>(T)) {
+ const Stmt *Label = E.getDst()->getLabel();
+
+ if (Label) {
+ if (const auto *C = dyn_cast<CaseStmt>(Label)) {
+ Out << CR << "case ";
+ if (C->getLHS())
+ C->getLHS()->printPretty(
+ Out, nullptr, Context.getPrintingPolicy(),
+ /*Indentation=*/0, /*NewlineSymbol=*/CR);
+
+ if (const Stmt *RHS = C->getRHS()) {
+ Out << " .. ";
+ RHS->printPretty(Out, nullptr, Context.getPrintingPolicy(),
+ /*Indetation=*/0, /*NewlineSymbol=*/CR);
+ }
+
+ Out << ":";
+ } else {
+ assert(isa<DefaultStmt>(Label));
+ Out << CR << "default:";
+ }
+ } else
+ Out << CR << "(implicit) default:";
+ } else if (isa<IndirectGotoStmt>(T)) {
+ // FIXME
+ } else {
+ Out << CR << "Condition: ";
+ if (*E.getSrc()->succ_begin() == E.getDst())
+ Out << "true";
+ else
+ Out << "false";
+ }
+
+ Out << CR;
+ }
+
+ break;
+ }
+
+ default: {
+ const Stmt *S = castAs<StmtPoint>().getStmt();
+ assert(S != nullptr && "Expecting non-null Stmt");
+
+ Out << S->getStmtClassName() << " S" << S->getID(Context) << " <"
+ << (const void *)S << "> ";
+ S->printPretty(Out, /*helper=*/nullptr, Context.getPrintingPolicy(),
+ /*Indentation=*/2, /*NewlineSymbol=*/CR);
+ printLocation(Out, S->getBeginLoc(), SM, CR, /*Postfix=*/"");
+
+ if (getAs<PreStmt>())
+ Out << CR << "PreStmt" << CR;
+ else if (getAs<PostLoad>())
+ Out << CR << "PostLoad" << CR;
+ else if (getAs<PostStore>())
+ Out << CR << "PostStore" << CR;
+ else if (getAs<PostLValue>())
+ Out << CR << "PostLValue" << CR;
+ else if (getAs<PostAllocatorCall>())
+ Out << CR << "PostAllocatorCall" << CR;
+
+ break;
+ }
+ }
+}
+
SimpleProgramPointTag::SimpleProgramPointTag(StringRef MsgProvider,
StringRef Msg)
: Desc((MsgProvider + " : " + Msg).str()) {}