<div dir="ltr"><div><div><div><div>Hello gentlemen,<br><br></div>I'm trying to write a clang tool which will instrument source code.<br></div>I'm
 using a FrontEndAction, an ASTConsumer and finally a 
RecursiveASTVisitor, which will use a Rewriter to update the source 
code.<br><br></div>Now, I'd like to add another pass with an updated AST
 (which should match the rewritten source code), and I can't get how to 
do this (I searched for a long time before posting here).<br><br>I 
could, of course, dump new source code on the file system, and then 
parse the new file. But this method is rather inelegant, probably time 
consuming and inappropriate for my needs.<br><br></div><div>I'd be grateful to anyone helping me.<br></div><div>  Nicolas<br><br></div><div>P.S.<br></div>Here's a minimalist source code I'm based on:<br><br>static llvm::cl::OptionCategory ToolingSampleCategory("Test");<br><br>class myASTVisitor: public clang::RecursiveASTVisitor<myASTVisitor><br>{<br>        clang::CompilerInstance& ci__;<br>        clang::Rewriter& rewriter__;<br><br>        public:<br>        myASTVisitor(clang::CompilerInstance& ci, clang::Rewriter& r): ci__(ci), rewriter__(r) {}<br><br>        bool VisitDeclStmt(clang::DeclStmt* ds)<br>        {<br>                // Code which involves the rewriter__<br>                return true;<br>        }<br>};<br><br>class ASTConsumer : public clang::ASTConsumer<br>{<br>        clang::CompilerInstance& ci__;<br>        clang::StringRef file__;<br>        clang::Rewriter& rewriter__;<br><br>        public:<br>        ASTConsumer(clang::CompilerInstance& ci, clang::StringRef file, clang::Rewriter& rw): ci__(ci), file__(file), rewriter__(rw) {}<br><br>        bool HandleTopLevelDecl(clang::DeclGroupRef DR) override {<br>                for (clang::DeclGroupRef::iterator it = DR.begin(); it != DR.end(); ++it) {<br>                        clang::FunctionDecl* fd = clang::cast<clang::FunctionDecl>(*it);<br>                        if (fd != NULL) {<br>                                myASTVisitor visitor(ci__, rewriter__);<br>                                visitor.TraverseDecl(fd);<br>                        }<br>                }<br>                return true;<br>        }<br>};<br><br>class FrontendAction : public clang::ASTFrontendAction<br>{<br>        clang::Rewriter rewriter__;<br>        clang::CompilerInstance* ci__;<br><br>        public:<br>        FrontendAction() {}<br><br>        void EndSourceFileAction() override {<br>                rewriter__.getEditBuffer(ci__->getSourceManager().getMainFileID()).write(llvm::outs());<br><div>                // write to stdout for now, but there (only if appropriate), I would like <br></div><div>                // to run a second pass, using another ASTVisitor/ASTConsumer<br></div><div>                // on the new AST from the rewritten sources<br></div>        }<br><br>        std::unique_ptr<clang::ASTConsumer> CreateASTConsumer(clang::CompilerInstance& CI, clang::StringRef file) override {<br>                ci__ = &CI;<br>                rewriter__.setSourceMgr(CI.getSourceManager(), CI.getLangOpts());<br>                return std::unique_ptr<clang::ASTConsumer>(new ASTConsumer(CI, file, rewriter__));<br>        }<br>};<br><br>int main(int argc, const char** argv)<br>{<br>        clang::tooling::CommonOptionsParser op(argc, argv, ToolingSampleCategory);<br>        clang::tooling::ClangTool Tool(op.getCompilations(), op.getSourcePathList());<br><br>        return Tool.run(clang::tooling::newFrontendActionFactory<FrontendAction>().get());<br>}<br></div>