Index: cfe/trunk/include/clang/Analysis/CFG.h =================================================================== --- cfe/trunk/include/clang/Analysis/CFG.h +++ cfe/trunk/include/clang/Analysis/CFG.h @@ -882,7 +882,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: cfe/trunk/lib/Analysis/CFG.cpp =================================================================== --- cfe/trunk/lib/Analysis/CFG.cpp +++ cfe/trunk/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" @@ -5561,6 +5562,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 = getTerminatorStmt(); if (!Terminator) Index: cfe/trunk/lib/Analysis/ProgramPoint.cpp =================================================================== --- cfe/trunk/lib/Analysis/ProgramPoint.cpp +++ cfe/trunk/lib/Analysis/ProgramPoint.cpp @@ -149,13 +149,16 @@ const BlockEdge &E = castAs(); const Stmt *T = E.getSrc()->getTerminatorStmt(); 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\": \"";