[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