[cfe-dev] PragmaHandler/RecursiveASTVistor: How to pass the state of a pragma?

Marcel Schaible via cfe-dev cfe-dev at lists.llvm.org
Fri Jul 28 05:43:18 PDT 2017


Hello everyone,

I am still struggling with my tool and I need some advice:

I have defined my own pragma, which enables/disables certain functionality.

The PragmaHandler is called, but I have no idea how to pass the state of 
the pragma into my RecursiveASTVisitor.

 From my understanding the PragmaHandler is called by the Preprocessor 
for all found #pragma instances and after

that my Visitor is executed.  But the pragma state changes 
PUSH/POP/enable are lost at this point.

How can I pass the pragma state to my Visitor? I want to attach an 
implicit attribute to the affected AStNodes.

I have attached a stripped version of the problem.

Thanks

Marcel

<-- code snippet -->

static bool mypragma_enabled = false;

// #pragma mypragma PUSH
// #pragma mypragma
// #pragma mypragma POP

class MyPragmaHandler : public PragmaHandler {
public:
     MyPragmaHandler() : PragmaHandler("mypragma") {}

     void HandlePragma(Preprocessor &PP, PragmaIntroducerKind 
Introducer, Token &Tok)
     {
              SourceLocation PragmaLocation = Tok.getLocation();
              StringRef PragmaName = Tok.getIdentifierInfo()->getName();

              mypragma_enabled = true;

             // how to attach the pragma information to an ASTContext here?
     }
};

class MyASTVisitor : public RecursiveASTVisitor<MyASTVisitor> {
public:
     MyASTVisitor(Rewriter &R) : TheRewriter(R) {}

     bool VisitFunctionDecl(FunctionDecl *f) {

         // How the get current state of the pragma here?

         // This is not working:

         if (!mypragma_enabled) {
             llvm::errs() << "VisitFunctionDecl: skip function\n";
             return false;
         }

                 // processing...

         return true;
     }

private:
     Rewriter &TheRewriter;
};

class MyASTConsumer : public ASTConsumer {
public:
     MyASTConsumer(Rewriter &R) : Visitor(R) {}

     // Override the method that gets called for each parsed top-level
     // declaration.
     bool HandleTopLevelDecl(DeclGroupRef DR) override {
         for (DeclGroupRef::iterator b = DR.begin(), e = DR.end(); b != 
e; ++b) {
             // Traverse the declaration using our AST visitor.
             Visitor.TraverseDecl(*b);
             (*b)->dump();
         }

         return true;
     }

private:
     MyASTVisitor Visitor;
};

class MyFrontendAction : public ASTFrontendAction {
public:
     MyFrontendAction() {}
     void EndSourceFileAction() override {
         SourceManager &SM = TheRewriter.getSourceMgr();
         // Now emit the rewritten buffer.
TheRewriter.getEditBuffer(SM.getMainFileID()).write(llvm::outs());
     }

     std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
         StringRef file) override {
         TheRewriter.setSourceMgr(CI.getSourceManager(), CI.getLangOpts());
         return llvm::make_unique<MyASTConsumer>(TheRewriter);
     }

private:
     Rewriter TheRewriter;
};

int main(int argc, const char **argv) {
     CommonOptionsParser op(argc, argv, MyCategory);
     ClangTool Tool(op.getCompilations(), op.getSourcePathList());
     return Tool.run(newFrontendActionFactory<MyFrontendAction>().get());
}

static PragmaHandlerRegistry::Add<MyPragmaHandler>
Y("mypragma", "mypragma enables ...");

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20170728/4a4bd260/attachment.html>


More information about the cfe-dev mailing list