diff options
Diffstat (limited to 'lib/Analysis/ProgramPoint.cpp')
-rw-r--r-- | lib/Analysis/ProgramPoint.cpp | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/lib/Analysis/ProgramPoint.cpp b/lib/Analysis/ProgramPoint.cpp index d9833659d7b3f..2d016cb133538 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()) {} |