Index: clang/include/clang/Analysis/CFG.h =================================================================== --- clang/include/clang/Analysis/CFG.h +++ clang/include/clang/Analysis/CFG.h @@ -861,7 +861,11 @@ void dump(const CFG *cfg, const LangOptions &LO, bool ShowColors = false) const; void print(raw_ostream &OS, const CFG* cfg, const LangOptions &LO, bool ShowColors) const; + void printTerminator(raw_ostream &OS, const LangOptions &LO) const; + void printTerminatorJson(raw_ostream &Out, const LangOptions &LO, + bool AddQuotes) const; + void printAsOperand(raw_ostream &OS, bool /*PrintType*/) { OS << "BB#" << getBlockID(); } Index: clang/lib/Analysis/CFG.cpp =================================================================== --- clang/lib/Analysis/CFG.cpp +++ clang/lib/Analysis/CFG.cpp @@ -27,10 +27,11 @@ #include "clang/AST/StmtObjC.h" #include "clang/AST/StmtVisitor.h" #include "clang/AST/Type.h" -#include "clang/Analysis/Support/BumpVector.h" #include "clang/Analysis/ConstructionContext.h" +#include "clang/Analysis/Support/BumpVector.h" #include "clang/Basic/Builtins.h" #include "clang/Basic/ExceptionSpecificationType.h" +#include "clang/Basic/JsonSupport.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/LangOptions.h" #include "clang/Basic/SourceLocation.h" @@ -5518,6 +5519,17 @@ TPrinter.print(getTerminator()); } +/// printTerminatorJson - Pretty-prints the terminator in JSON format. +void CFGBlock::printTerminatorJson(raw_ostream &Out, const LangOptions &LO, + bool AddQuotes) const { + std::string Buf; + llvm::raw_string_ostream TempOut(Buf); + + printTerminator(TempOut, LO); + + Out << JsonFormat(TempOut.str(), AddQuotes); +} + Stmt *CFGBlock::getTerminatorCondition(bool StripParens) { Stmt *Terminator = this->Terminator; if (!Terminator) Index: clang/lib/Analysis/ProgramPoint.cpp =================================================================== --- clang/lib/Analysis/ProgramPoint.cpp +++ clang/lib/Analysis/ProgramPoint.cpp @@ -151,13 +151,16 @@ const BlockEdge &E = castAs(); const Stmt *T = E.getSrc()->getTerminator(); Out << "Edge\", \"src_id\": " << E.getSrc()->getBlockID() - << ", \"dst_id\": " << E.getDst()->getBlockID() - << ", \"terminator\": " << (!T ? "null, \"term_kind\": null" : "\""); - if (!T) + << ", \"dst_id\": " << E.getDst()->getBlockID() << ", \"terminator\": "; + + if (!T) { + Out << "null, \"term_kind\": null"; break; + } - E.getSrc()->printTerminator(Out, Context.getLangOpts()); - Out << "\", "; + E.getSrc()->printTerminatorJson(Out, Context.getLangOpts(), + /*AddQuotes=*/true); + Out << ", "; printLocJson(Out, T->getBeginLoc(), SM); Out << ", \"term_kind\": \"";