[cfe-dev] Reparse rewritten source

Eric Liu via cfe-dev cfe-dev at lists.llvm.org
Fri Aug 5 05:57:40 PDT 2016


Hi Nicolas,

We had the similar problem in clang-include-fixer
<https://github.com/llvm-mirror/clang-tools-extra/blob/master/include-fixer/tool/ClangIncludeFixer.cpp#L251>
where we need to replace the content of a file without actually writing new
content to file system, and we use `ClangTool::mapVirtualFile
<http://clang.llvm.org/doxygen/classclang_1_1tooling_1_1ClangTool.html#a2fef9bcf06819ffb9418560996ff71c7>`
as an workaround. I hope this would help.

Cheers,
Eric

On Fri, Aug 5, 2016 at 1:58 PM nicolas normand via cfe-dev <
cfe-dev at lists.llvm.org> wrote:

> Hello gentlemen,
>
> I'm trying to write a clang tool which will instrument source code.
> I'm using a FrontEndAction, an ASTConsumer and finally a
> RecursiveASTVisitor, which will use a Rewriter to update the source code.
>
> 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).
>
> 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.
>
> I'd be grateful to anyone helping me.
>   Nicolas
>
> P.S.
> Here's a minimalist source code I'm based on:
>
> static llvm::cl::OptionCategory ToolingSampleCategory("Test");
>
> class myASTVisitor: public clang::RecursiveASTVisitor<myASTVisitor>
> {
>         clang::CompilerInstance& ci__;
>         clang::Rewriter& rewriter__;
>
>         public:
>         myASTVisitor(clang::CompilerInstance& ci, clang::Rewriter& r):
> ci__(ci), rewriter__(r) {}
>
>         bool VisitDeclStmt(clang::DeclStmt* ds)
>         {
>                 // Code which involves the rewriter__
>                 return true;
>         }
> };
>
> class ASTConsumer : public clang::ASTConsumer
> {
>         clang::CompilerInstance& ci__;
>         clang::StringRef file__;
>         clang::Rewriter& rewriter__;
>
>         public:
>         ASTConsumer(clang::CompilerInstance& ci, clang::StringRef file,
> clang::Rewriter& rw): ci__(ci), file__(file), rewriter__(rw) {}
>
>         bool HandleTopLevelDecl(clang::DeclGroupRef DR) override {
>                 for (clang::DeclGroupRef::iterator it = DR.begin(); it !=
> DR.end(); ++it) {
>                         clang::FunctionDecl* fd =
> clang::cast<clang::FunctionDecl>(*it);
>                         if (fd != NULL) {
>                                 myASTVisitor visitor(ci__, rewriter__);
>                                 visitor.TraverseDecl(fd);
>                         }
>                 }
>                 return true;
>         }
> };
>
> class FrontendAction : public clang::ASTFrontendAction
> {
>         clang::Rewriter rewriter__;
>         clang::CompilerInstance* ci__;
>
>         public:
>         FrontendAction() {}
>
>         void EndSourceFileAction() override {
>
> rewriter__.getEditBuffer(ci__->getSourceManager().getMainFileID()).write(llvm::outs());
>                 // write to stdout for now, but there (only if
> appropriate), I would like
>                 // to run a second pass, using another
> ASTVisitor/ASTConsumer
>                 // on the new AST from the rewritten sources
>         }
>
>         std::unique_ptr<clang::ASTConsumer>
> CreateASTConsumer(clang::CompilerInstance& CI, clang::StringRef file)
> override {
>                 ci__ = &CI;
>                 rewriter__.setSourceMgr(CI.getSourceManager(),
> CI.getLangOpts());
>                 return std::unique_ptr<clang::ASTConsumer>(new
> ASTConsumer(CI, file, rewriter__));
>         }
> };
>
> int main(int argc, const char** argv)
> {
>         clang::tooling::CommonOptionsParser op(argc, argv,
> ToolingSampleCategory);
>         clang::tooling::ClangTool Tool(op.getCompilations(),
> op.getSourcePathList());
>
>         return
> Tool.run(clang::tooling::newFrontendActionFactory<FrontendAction>().get());
> }
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20160805/06464ecb/attachment.html>


More information about the cfe-dev mailing list