From: Michal Sojka Date: Fri, 20 Jul 2012 03:52:21 +0000 (+0200) Subject: Convert to Clang plugin API X-Git-Url: http://rtime.felk.cvut.cz/gitweb/boost-statechart-viewer.git/commitdiff_plain/1ce4f09f6980c533c5459acd27a880fc232744f3 Convert to Clang plugin API http://clang.llvm.org/docs/ClangPlugins.html I can compile it with clang-3.1 and it does not crash. For some reason transitions are missing in the generated graph. --- diff --git a/examples/Makefile b/examples/Makefile index ec1bb56..2706a64 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -1,11 +1,16 @@ .PHONY: all all: test.pdf StopWatch.pdf main.pdf -%.dot: %.cpp ../src/visualizer - ../src/visualizer $< -o $@ +VISUALIZER = -Xclang -load -Xclang ../src/visualizer.so -Xclang -plugin -Xclang visualize-statechart -%.pdf: %.dot - dot -Tps $< | epstopdf --filter > $@ +%.o %.dot: %.cpp ../src/visualizer.so + clang++ $(VISUALIZER) -c -o $(<:.cpp=.o) $< + +%.eps: %.dot + dot -Tps $< > $@ + +%.pdf: %.eps + epstopdf $< > $@ ../src/visualizer: $(MAKE) -C ../src diff --git a/src/Makefile b/src/Makefile index 12d4085..b1bcb4b 100644 --- a/src/Makefile +++ b/src/Makefile @@ -4,8 +4,8 @@ LLVM_CONFIG ?= llvm-config LLVM_FLAGS := $(shell $(LLVM_CONFIG) --cxxflags --ldflags --libs jit core) -visualizer: visualizer.cpp stringoper.h iooper.h - $(CXX) $< -o $@ -g -fno-rtti -Wall -lclangParse -lclangFrontend -lclangSerialization \ +visualizer.so: visualizer.cpp stringoper.h iooper.h + $(CXX) $< -o $@ -g -fno-rtti -shared -fpic -Wall -lclangParse -lclangFrontend -lclangSerialization \ -lclangDriver -lclangCodeGen -lclangSema \ -lclangAnalysis -lclangRewrite -lclangAST -lclangLex -lclangBasic -lclangEdit \ $(LLVM_FLAGS) diff --git a/src/visualizer.cpp b/src/visualizer.cpp index 39191d3..59008b3 100644 --- a/src/visualizer.cpp +++ b/src/visualizer.cpp @@ -41,6 +41,12 @@ #include "clang/Driver/Driver.h" #include "clang/Driver/Compilation.h" +#include "clang/Frontend/FrontendPluginRegistry.h" +#include "clang/AST/ASTConsumer.h" +#include "clang/AST/AST.h" +#include "clang/Frontend/CompilerInstance.h" +#include "llvm/Support/raw_ostream.h" + //my own header files #include "iooper.h" @@ -124,9 +130,12 @@ class FindStates : public ASTConsumer list states; string name_of_machine; string name_of_start; + string dest; FullSourceLoc *fsloc; /** Full Source Location instance for holding Source Manager. */ public: + FindStates(string dest) : dest(dest) {} + list getStates() /** Return list of states of the state machine. */ { return states; @@ -418,92 +427,45 @@ class FindStates : public ASTConsumer } } + virtual void HandleTranslationUnit(clang::ASTContext &Context) { + IO_operations io(dest, getStateMachine(), getNameOfFirstState(), getTransitions(), getStates(), getEvents()); + io.save_to_file(); + io.print_stats(); + } }; -/** - * Main function provides all initialization before starting analysis of AST. Diagnostic Client is initialized, - * Command line options are processed. - */ -int main(int argc, char **argv) -{ - if(argc==1 || strncmp(argv[1],"-help",5)==0) - { - cout< dis(new DiagnosticIDs()); - DiagnosticsEngine diag(dis,mdc); - FileManager fm( * new FileSystemOptions()); - SourceManager sm (diag, fm); - - Driver TheDriver(LLVM_BINDIR, llvm::sys::getDefaultTargetTriple(), "", false, diag); - TheDriver.setCheckInputsExist(true); - TheDriver.CCCIsCXX = 1; - TheDriver.ResourceDir = LLVM_PREFIX "/lib/clang/" CLANG_VERSION_STRING; - CompilerInvocation compInv; - llvm::SmallVector Args(argv, argv + argc); - llvm::OwningPtr C(TheDriver.BuildCompilation(Args)); - const driver::JobList &Jobs = C->getJobs(); - const driver::Command *Cmd = cast(*Jobs.begin()); - const driver::ArgStringList &CCArgs = Cmd->getArguments(); - for(unsigned i = 0; i2) - { - string str = Args[i]; - outputFilename = str.substr(2); - } - else outputFilename = Args[i+1]; - break; - } - } - - CompilerInvocation::CreateFromArgs(compInv, - const_cast(CCArgs.data()), - const_cast(CCArgs.data())+CCArgs.size(), - diag); +class VisualizeStatechartAction : public PluginASTAction { +protected: + ASTConsumer *CreateASTConsumer(CompilerInstance &CI, llvm::StringRef) { + size_t dot = getCurrentFile().find_last_of('.'); + std::string dest = getCurrentFile().substr(0, dot); + dest.append(".dot"); + return new FindStates(dest); + } - HeaderSearchOptions hsopts = compInv.getHeaderSearchOpts(); - LangOptions *lang = compInv.getLangOpts(); - CompilerInvocation::setLangDefaults(*lang, IK_ObjCXX); - TargetInfo *ti = TargetInfo::CreateTargetInfo(diag, compInv.getTargetOpts()); - FrontendOptions f = compInv.getFrontendOpts(); - inputFilename = f.Inputs[0].File; - HeaderSearch *headers = new HeaderSearch(fm, diag, *lang, ti); + bool ParseArgs(const CompilerInstance &CI, + const std::vector& args) { + for (unsigned i = 0, e = args.size(); i != e; ++i) { + llvm::errs() << "Visualizer arg = " << args[i] << "\n"; - cout<<"Input filename: "<BeginSourceFile(*lang, &pp);//start using diagnostic - ParseAST(pp, &c, ctx, false, TU_Complete); - mdc->EndSourceFile(); //end using diagnostic - IO_operations *io = new IO_operations(outputFilename, c.getStateMachine(), c.getNameOfFirstState(), c.getTransitions(), c.getStates(), c.getEvents()); - io->save_to_file(); - io->print_stats(); - mdc->print_stats(); - return 0; -} +}; + +static FrontendPluginRegistry::Add X("visualize-statechart", "visualize statechart");