[cfe-dev] Reparse rewritten source

nicolas normand via cfe-dev cfe-dev at lists.llvm.org
Mon Aug 8 00:37:28 PDT 2016


Hi Eric,

I have to instantiate and initialize a second clang::tooling::ClangTool
object (I can live with it), but it works like a charm.

Thank you very much,
  Nicolas


2016-08-05 14:57 GMT+02:00 Eric Liu <ioeric at google.com>:

> 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/20160808/6c1fd8bc/attachment.html>


More information about the cfe-dev mailing list