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

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.

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 {
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 CreateASTConsumer(CompilerInstance &CI,
StringRef file) override {
TheRewriter.setSourceMgr(CI.getSourceManager(), CI.getLangOpts());
return llvm::make_unique(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().get());
}

static PragmaHandlerRegistry::Add
Y(“mypragma”, “mypragma enables …”);