<div dir="ltr"><div><div><div>Hi Eric,<br><br></div>I have to instantiate and initialize a second clang::tooling::ClangTool object (I can live with it), but it works like a charm.<br></div><br>Thank you very much,<br></div> Nicolas<br><br></div><div class="gmail_extra"><br><div class="gmail_quote">2016-08-05 14:57 GMT+02:00 Eric Liu <span dir="ltr"><<a href="mailto:ioeric@google.com" target="_blank">ioeric@google.com</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hi Nicolas,<div><br></div><div>We had the similar problem in <a href="https://github.com/llvm-mirror/clang-tools-extra/blob/master/include-fixer/tool/ClangIncludeFixer.cpp#L251" target="_blank">clang-include-fixer</a> where we need to replace the content of a file without actually writing new content to file system, and we use `<a href="http://clang.llvm.org/doxygen/classclang_1_1tooling_1_1ClangTool.html#a2fef9bcf06819ffb9418560996ff71c7" target="_blank">ClangTool::mapVirtualFile</a>` as an workaround. I hope this would help.</div><div><br></div><div>Cheers,</div><div>Eric</div><br><div class="gmail_quote"><div><div class="h5"><div dir="ltr">On Fri, Aug 5, 2016 at 1:58 PM nicolas normand via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>> wrote:<br></div></div></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div class="h5"><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<<wbr>myASTVisitor><br>{<br> clang::CompilerInstance& ci__;<br> clang::Rewriter& rewriter__;<br><br> public:<br> myASTVisitor(clang::<wbr>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::<wbr>CompilerInstance& ci, clang::StringRef file, clang::Rewriter& rw): ci__(ci), file__(file), rewriter__(rw) {}<br><br> bool HandleTopLevelDecl(clang::<wbr>DeclGroupRef DR) override {<br> for (clang::DeclGroupRef::iterator it = DR.begin(); it != DR.end(); ++it) {<br> clang::FunctionDecl* fd = clang::cast<clang::<wbr>FunctionDecl>(*it);<br> if (fd != NULL) {<br> <wbr> myASTVisitor visitor(ci__, rewriter__);<br> <wbr> 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__-<wbr>>getSourceManager().<wbr>getMainFileID()).write(llvm::<wbr>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::<wbr>ASTConsumer> CreateASTConsumer(clang::<wbr>CompilerInstance& CI, clang::StringRef file) override {<br> ci__ = &CI;<br> rewriter__.setSourceMgr(CI.<wbr>getSourceManager(), CI.getLangOpts());<br> return std::unique_ptr<clang::<wbr>ASTConsumer>(new ASTConsumer(CI, file, rewriter__));<br> }<br>};<br><br>int main(int argc, const char** argv)<br>{<br> clang::tooling::<wbr>CommonOptionsParser op(argc, argv, ToolingSampleCategory);<br> clang::tooling::ClangTool Tool(op.getCompilations(), op.getSourcePathList());<br><br> return Tool.run(clang::tooling::<wbr>newFrontendActionFactory<<wbr>FrontendAction>().get());<br>}<br></div></div></div>
______________________________<wbr>_________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-dev</a><br>
</blockquote></div></div>
</blockquote></div><br></div>