Added support to clang driver to view ASTs using GraphViz. This

functionality is still preliminary.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@42152 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Ted Kremenek 2007-09-19 21:29:43 +00:00
Родитель d2a4a1af10
Коммит 80de08fc6f
5 изменённых файлов: 102 добавлений и 1 удалений

60
AST/StmtViz.cpp Normal file
Просмотреть файл

@ -0,0 +1,60 @@
//===--- StmtViz.cpp - Graphviz visualization for Stmt ASTs -----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by Ted Kremenek and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements Stmt::viewAST, which generates a Graphviz DOT file
// that depicts the AST and then calls Graphviz/dot+gv on it.
//
//===----------------------------------------------------------------------===//
#include "clang/AST/StmtGraphTraits.h"
#include "llvm/Support/GraphWriter.h"
#include <iostream>
#include <sstream>
using namespace clang;
void Stmt::viewAST() const {
#ifndef NDEBUG
llvm::ViewGraph(this,"AST");
#else
std::cerr << "Stmt::viewAST is only available in debug builds on "
<< "systems with Graphviz or gv!\n";
#endif
}
namespace llvm {
template<>
struct DOTGraphTraits<const Stmt*> : public DefaultDOTGraphTraits {
static std::string getNodeLabel(const Stmt* Node, const Stmt* Graph) {
#ifndef NDEBUG
std::ostringstream Out;
if (Node)
Out << Node->getStmtClassName();
else
Out << "<NULL>";
std::string OutStr = Out.str();
if (OutStr[0] == '\n') OutStr.erase(OutStr.begin());
// Process string output to make it nicer...
for (unsigned i = 0; i != OutStr.length(); ++i)
if (OutStr[i] == '\n') { // Left justify
OutStr[i] = '\\';
OutStr.insert(OutStr.begin()+i+1, 'l');
}
return OutStr;
#else
return "";
#endif
}
};
} // end namespace llvm

Просмотреть файл

@ -131,6 +131,31 @@ namespace {
ASTConsumer *clang::CreateASTDumper() { return new ASTDumper(); }
namespace {
class ASTViewer : public ASTConsumer {
SourceManager *SM;
public:
void Initialize(ASTContext &Context, unsigned MainFileID) {
SM = &Context.SourceMgr;
}
virtual void HandleTopLevelDecl(Decl *D) {
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
PrintFunctionDeclStart(FD);
if (FD->getBody()) {
fprintf(stderr, "\n");
FD->getBody()->viewAST();
fprintf(stderr, "\n");
}
}
}
};
}
ASTConsumer *clang::CreateASTViewer() { return new ASTViewer(); }
//===----------------------------------------------------------------------===//
// CFGVisitor & VisitCFGs - Boilerplate interface and logic to visit
// the CFGs for all function definitions.

Просмотреть файл

@ -21,6 +21,7 @@ class Diagnostic;
ASTConsumer *CreateASTPrinter();
ASTConsumer *CreateASTDumper();
ASTConsumer *CreateASTViewer();
ASTConsumer *CreateCFGDumper(bool ViewGraphs = false);
ASTConsumer *CreateLiveVarAnalyzer();
ASTConsumer *CreateDeadStoreChecker(Diagnostic &Diags);

Просмотреть файл

@ -52,8 +52,9 @@ enum ProgActions {
EmitLLVM, // Emit a .ll file.
ParseASTPrint, // Parse ASTs and print them.
ParseASTDump, // Parse ASTs and dump them.
ParseASTView, // Parse ASTs and view them in Graphviz.
ParseASTCheck, // Parse ASTs and check diagnostics.
BuildAST, // Parse ASTs.
BuildAST, // Parse ASTs.
ParseCFGDump, // Parse ASTS. Build CFGs. Print CFGs.
ParseCFGView, // Parse ASTS. Build CFGs. View CFGs.
AnalysisLiveVariables, // Print results of live-variable analysis.
@ -89,6 +90,8 @@ ProgAction(llvm::cl::desc("Choose output type:"), llvm::cl::ZeroOrMore,
"Run parser, build ASTs, then print ASTs"),
clEnumValN(ParseASTDump, "parse-ast-dump",
"Run parser, build ASTs, then dump them"),
clEnumValN(ParseASTView, "parse-ast-view",
"Run parser, build ASTs, and view them with GraphViz."),
clEnumValN(ParseASTCheck, "parse-ast-check",
"Run parser, build ASTs, then check diagnostics"),
clEnumValN(ParseCFGDump, "dump-cfg",
@ -857,6 +860,11 @@ static void ProcessInputFile(Preprocessor &PP, unsigned MainFileID,
ParseAST(PP, MainFileID, *C.get(), Stats);
break;
}
case ParseASTView: {
std::auto_ptr<ASTConsumer> C(CreateASTViewer());
ParseAST(PP, MainFileID, *C.get(), Stats);
break;
}
case ParseCFGDump:
case ParseCFGView: {
std::auto_ptr<ASTConsumer> C(CreateCFGDumper(ProgAction == ParseCFGView));

Просмотреть файл

@ -16,6 +16,7 @@
35260CA50C7F75C000D66CE9 /* ExprCXX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35260CA40C7F75C000D66CE9 /* ExprCXX.cpp */; };
355CF6840C90A8D400A08AA3 /* DeadStores.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 355CF6830C90A8D400A08AA3 /* DeadStores.cpp */; };
356EF9B50C8F7DDF006650F5 /* LiveVariables.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 356EF9B40C8F7DDF006650F5 /* LiveVariables.cpp */; };
35CFFE000CA1CBCB00E6F2BE /* StmtViz.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35CFFDFF0CA1CBCB00E6F2BE /* StmtViz.cpp */; };
84D9A8880C1A57E100AC7ABC /* AttributeList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84D9A8870C1A57E100AC7ABC /* AttributeList.cpp */; };
84D9A88C0C1A581300AC7ABC /* AttributeList.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 84D9A88B0C1A581300AC7ABC /* AttributeList.h */; };
DE01DA490B12ADA300AC22CE /* PPCallbacks.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE01DA480B12ADA300AC22CE /* PPCallbacks.h */; };
@ -226,6 +227,8 @@
35AE0F660C9B4CA300CC1279 /* UninitializedValues.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UninitializedValues.h; path = clang/Analysis/UninitializedValues.h; sourceTree = "<group>"; };
35AE0F670C9B4CC200CC1279 /* DataflowSolver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DataflowSolver.h; path = Analysis/DataflowSolver.h; sourceTree = "<group>"; };
35BFBD2B0C9EDE1E006CB644 /* ASTConsumer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASTConsumer.h; path = clang/AST/ASTConsumer.h; sourceTree = "<group>"; };
35CFFDFF0CA1CBCB00E6F2BE /* StmtViz.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StmtViz.cpp; path = AST/StmtViz.cpp; sourceTree = "<group>"; };
35CFFE010CA1CBDD00E6F2BE /* StmtGraphTraits.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StmtGraphTraits.h; path = clang/AST/StmtGraphTraits.h; sourceTree = "<group>"; };
84D9A8870C1A57E100AC7ABC /* AttributeList.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = AttributeList.cpp; path = Parse/AttributeList.cpp; sourceTree = "<group>"; };
84D9A88B0C1A581300AC7ABC /* AttributeList.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AttributeList.h; path = clang/Parse/AttributeList.h; sourceTree = "<group>"; };
8DD76F6C0486A84900D96B5E /* clang */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = clang; sourceTree = BUILT_PRODUCTS_DIR; };
@ -561,6 +564,7 @@
DE3452800AEF1B1800DBC861 /* Stmt.h */,
DE345F210AFD347900DBC861 /* StmtNodes.def */,
DE345C190AFC658B00DBC861 /* StmtVisitor.h */,
35CFFE010CA1CBDD00E6F2BE /* StmtGraphTraits.h */,
DE3464210B03040900DBC861 /* Type.h */,
);
name = AST;
@ -579,6 +583,7 @@
DE75EDF00B06880E0020CF81 /* Type.cpp */,
DEF2EDA60C6A4252000C4259 /* StmtDumper.cpp */,
DE34621C0AFEB19B00DBC861 /* StmtPrinter.cpp */,
35CFFDFF0CA1CBCB00E6F2BE /* StmtViz.cpp */,
);
name = AST;
sourceTree = "<group>";
@ -708,6 +713,7 @@
08FB7793FE84155DC02AAC07 /* Project object */ = {
isa = PBXProject;
buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "clang" */;
compatibilityVersion = "Xcode 2.4";
hasScannedForEncodings = 1;
mainGroup = 08FB7794FE84155DC02AAC07 /* clang */;
projectDirPath = "";
@ -792,6 +798,7 @@
355CF6840C90A8D400A08AA3 /* DeadStores.cpp in Sources */,
DEF7D9F90C9C8B1D0001F598 /* Rewriter.cpp in Sources */,
3513BD550C9F207900FA56C6 /* UninitializedValues.cpp in Sources */,
35CFFE000CA1CBCB00E6F2BE /* StmtViz.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};