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.

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 ...");


_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Loading...