diff options
author | George Karpenkov <ekarpenkov@apple.com> | 2018-09-28 18:49:21 +0000 |
---|---|---|
committer | George Karpenkov <ekarpenkov@apple.com> | 2018-09-28 18:49:21 +0000 |
commit | c704f4fbd0a41090e68aaf056b31803481f535ff (patch) | |
tree | 38ee7223806a6c6df95f5f9655c6314ed1014f32 /clang/lib/StaticAnalyzer/Core/ExprEngine.cpp | |
parent | 86714886d94262d9c0acbc7b31ef8ea332cb66d3 (diff) | |
download | bcm5719-llvm-c704f4fbd0a41090e68aaf056b31803481f535ff.tar.gz bcm5719-llvm-c704f4fbd0a41090e68aaf056b31803481f535ff.zip |
[analyzer] Provide an option to dump generated exploded graphs to a given file.
Dumping graphs instead of opening them is often very useful,
e.g. for transfer or converting to SVG.
Basic sanity check for generated exploded graphs.
Differential Revision: https://reviews.llvm.org/D52637
llvm-svn: 343352
Diffstat (limited to 'clang/lib/StaticAnalyzer/Core/ExprEngine.cpp')
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/ExprEngine.cpp | 35 |
1 files changed, 30 insertions, 5 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp index 90f89209275..c19f0563d11 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -3058,6 +3058,23 @@ struct DOTGraphTraits<ExplodedGraph*> : public DefaultDOTGraphTraits { void ExprEngine::ViewGraph(bool trim) { #ifndef NDEBUG + std::string Filename = DumpGraph(trim); + llvm::DisplayGraph(Filename, false, llvm::GraphProgram::DOT); +#endif + llvm::errs() << "Warning: viewing graph requires assertions" << "\n"; +} + + +void ExprEngine::ViewGraph(ArrayRef<const ExplodedNode*> Nodes) { +#ifndef NDEBUG + std::string Filename = DumpGraph(Nodes); + llvm::DisplayGraph(Filename, false, llvm::GraphProgram::DOT); +#endif + llvm::errs() << "Warning: viewing graph requires assertions" << "\n"; +} + +std::string ExprEngine::DumpGraph(bool trim, StringRef Filename) { +#ifndef NDEBUG if (trim) { std::vector<const ExplodedNode *> Src; @@ -3067,22 +3084,30 @@ void ExprEngine::ViewGraph(bool trim) { const auto *N = const_cast<ExplodedNode *>(EI->begin()->getErrorNode()); if (N) Src.push_back(N); } - - ViewGraph(Src); + return DumpGraph(Src, Filename); } else { - llvm::ViewGraph(&G, "ExprEngine"); + return llvm::WriteGraph(&G, "ExprEngine", /*ShortNames=*/false, + /*Title=*/"Exploded Graph", /*Filename=*/Filename); } #endif + llvm::errs() << "Warning: dumping graph requires assertions" << "\n"; + return ""; } -void ExprEngine::ViewGraph(ArrayRef<const ExplodedNode*> Nodes) { +std::string ExprEngine::DumpGraph(ArrayRef<const ExplodedNode*> Nodes, + StringRef Filename) { #ifndef NDEBUG std::unique_ptr<ExplodedGraph> TrimmedG(G.trim(Nodes)); if (!TrimmedG.get()) { llvm::errs() << "warning: Trimmed ExplodedGraph is empty.\n"; } else { - llvm::ViewGraph(TrimmedG.get(), "TrimmedExprEngine"); + return llvm::WriteGraph(TrimmedG.get(), "TrimmedExprEngine", + /*ShortNames=*/false, + /*Title=*/"Trimmed Exploded Graph", + /*Filename=*/Filename); } #endif + llvm::errs() << "Warning: dumping graph requires assertions" << "\n"; + return ""; } |