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

Marcel Schaible via cfe-dev cfe-dev at lists.llvm.org
Wed Jul 19 12:25:59 PDT 2017


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




More information about the cfe-dev mailing list