PragmaHandler/RecursiveASTVistor: How to pass the state of a pragma?

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
Report Content as Inappropriate

PragmaHandler/RecursiveASTVistor: How to pass the state of a pragma?

Sumner, Brian via cfe-dev

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.



<-- code snippet -->

static bool mypragma_enabled = false;

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

class MyPragmaHandler : public PragmaHandler {
    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> {
    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;

    Rewriter &TheRewriter;

class MyASTConsumer : public ASTConsumer {
    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.

        return true;

    MyASTVisitor Visitor;

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

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

    Rewriter TheRewriter;

int main(int argc, const char **argv) {
    CommonOptionsParser op(argc, argv, MyCategory);
    ClangTool Tool(op.getCompilations(), op.getSourcePathList());

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

cfe-dev mailing list
[hidden email]