[cfe-dev] Plugin: Rewriter does not work?

John Brawn via cfe-dev cfe-dev at lists.llvm.org
Fri Jul 21 10:22:45 PDT 2017


I'm guessing that probably you'd be better off modifying the AST directly
instead of doing a source rewrite then reparsing that, e.g. in the example
given you'd change VisitFunctionDecl to take a non-const FunctionDecl and
call funcDecl->setDeclName(). I have no experience with Rewriter or
RecursiveASTVisitor though, so that maybe isn't the best way to do it.

John

> -----Original Message-----
> From: Marcel Schaible [mailto:marcel at schaible-consulting.de]
> Sent: 20 July 2017 11:28
> To: John Brawn
> Cc: cfe-dev at lists.llvm.org; nd
> Subject: Re: [cfe-dev] Plugin: Rewriter does not work?
> 
> Good point. I'll changed it, but  I think the Rewriter will not change
> the AST and therefore my changes are ignored by further compiler stages.
> 
> Is there a mechanism to rebuild the AST from RewriteBuffer?
> 
> Thanks
> 
> Marcel
> 
> 
> Am 20.07.2017 um 11:36 schrieb John Brawn:
> >  From a quick look at your code MyInstrumentation::getActionType is
> > returning AddAfterMainAction which means it's getting run after code
> > generation. To run it before code generation change that to
> > AddBeforeMainAction, which should hopefully make it do what you want.
> >
> > John
> >
> >> -----Original Message-----
> >> From: cfe-dev [mailto:cfe-dev-bounces at lists.llvm.org] On Behalf Of
> >> Marcel Schaible via cfe-dev
> >> Sent: 19 July 2017 20:26
> >> To: cfe-dev at lists.llvm.org
> >> Subject: Re: [cfe-dev] Plugin: Rewriter does not work?
> >>
> >> Hi,
> >>
> >> I need some advice. I want to create a plugin for clang which for
> e.g.
> >> alters the argument list of specific functions and insert valid c
> >> statements at certain points in the translation unit.
> >>
> >> The Rewriter class is changing the source code as expected and I can
> >> write it to a temporary file and start the clang  compiler without my
> >> plugin again.
> >>
> >> Is there a better solution like calling clang with my plugin and
> apply
> >> my changes on the fly?
> >>
> >>   From my current understanding it is not possible to alter the AST
> in a
> >> plugin. Is this correct?
> >>
> >> Thanks
> >>
> >> Marcel
> >>
> >>
> >> Am 19.07.2017 um 14:28 schrieb Marcel Schaible via cfe-dev:
> >>> Hi,
> >>>
> >>> in my clang plugin I want to rewrite certain parts of the
> translation
> >>> unit. In the MyVisitor I'll setup a rewriter and try to replace for
> >>> e.g. the name of a function decl:
> >>>
> >>> TheRewriter.ReplaceText(funcDecl->getLocation(), funcName.length(),
> >>> "myreturn");
> >>>
> >>> This code is excecuted but the change is not visible in the
> generated
> >>> assembler file.
> >>>
> >>> Any idea what I am doing wrong?
> >>>
> >>> Thanks
> >>>
> >>> Marcel
> >>>
> >>> <---snippet--->
> >>>
> >>> Rewriter    TheRewriter;
> >>>
> >>> namespace {
> >>>
> >>>      class MyVisitor : public RecursiveASTVisitor<MyVisitor> {
> >>>      private:
> >>>          ASTContext *astContext;
> >>>
> >>>      public:
> >>>          explicit MyVisitor(CompilerInstance *CI) :
> >>> m_diag(CI->getDiagnostics()),
> >>>              astContext(&(CI->getASTContext()))
> >>>          {
> >>> TheRewriter.setSourceMgr(astContext->getSourceManager(),
> >>> astContext->getLangOpts());
> >>>          }
> >>>
> >>>          bool VisitFunctionDecl(const FunctionDecl *funcDecl) {
> >>>              string funcName =
> >>> funcDecl->getNameInfo().getName().getAsString();
> >>>              if (funcName == "return_fourtytwo") {
> >>> TheRewriter.ReplaceText(funcDecl->getLocation(), funcName.length(),
> >>> "myreturn");
> >>>                  errs() << "Rewrote function def: " << funcName <<
> >> "\n";
> >>>              }
> >>>
> >>>      private:
> >>>          DiagnosticsEngine &m_diag;
> >>>      };
> >>>
> >>>      class FuncDeclConsumer : public ASTConsumer {
> >>>      public:
> >>>          explicit FuncDeclConsumer(CompilerInstance *CI)
> >>>              : m_visitor(MyVisitor(CI)) {}
> >>>
> >>>          // Called by the parser for each top-level declaration
> group.
> >>>          // Returns true to continue parsing, or false to abort
> >> parsing.
> >>>          virtual bool HandleTopLevelDecl(DeclGroupRef dg) override {
> >>>              for (Decl *decl : dg) {
> >>>                  m_visitor.TraverseDecl(decl);
> >>>              }
> >>>              return true;
> >>>          }
> >>>
> >>>      private:
> >>>          MyVisitor m_visitor;
> >>>      };
> >>>
> >>>      class MyInstrumentation : public PluginASTAction {
> >>>      protected:
> >>>          std::unique_ptr<ASTConsumer>
> >>> CreateASTConsumer(CompilerInstance &ci,
> >>>              llvm::StringRef) override {
> >>>              return llvm::make_unique<FuncDeclConsumer>(&ci);
> >>>          }
> >>>
> >>>          PluginASTAction::ActionType getActionType() override {
> >>>              return AddAfterMainAction;
> >>>          }
> >>>      };
> >>> } // end namespace
> >>>
> >>> static FrontendPluginRegistry::Add<MyInstrumentation>
> >>> X("check-parameter-names", "check for parameter names mismatch");
> >>>
> >>> _______________________________________________
> >>> cfe-dev mailing list
> >>> cfe-dev at lists.llvm.org
> >>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
> >> _______________________________________________
> >> cfe-dev mailing list
> >> cfe-dev at lists.llvm.org
> >> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev



More information about the cfe-dev mailing list