我正在尝试使用 C++ 接口(interface)为预处理器编写一个 clang 插件,并且希望得到一些帮助。我已经阅读了使用 ASTFrontendActions 的 clang 插件教程,并尝试在线搜索预处理器插件,但我只比以前更进一步了。我只是一遍又一遍地寻找对同一教程的引用,或者使用 C 接口(interface)的指导。
经过 3 天的头文件挖掘,我想我已经将插件的父类缩小到 clang::PreprocessorFrontendAction
,但不能确定。当我尝试注册插件时,我只会遇到构建错误,因为它需要 AST 相关的东西。 (我认为是因为教程告诉我使用的函数可以追溯到 this header definition ,它使用 clang::PluginASTAction。)
教程告诉我注册的函数是:
static FrontendPluginRegistry::Add<MyPlugin> X("my-plugin-name", "my plugin description");
我以前从未使用过 clang,所以我肯定会先投入其中。一周后,我感觉自己被头文件淹没了。任何帮助将不胜感激,因为我显然没有足够的创造力将 AST 教程应用于我的预处理器问题。
编辑:所以,我已经克服了构建错误,现在一切都构建得很好。不幸的是,我不知道我是否实际上注册了我的插件。在每个函数中,我尝试打印到屏幕,但运行时看不到任何结果。
这是我到目前为止所拥有的。
//PluginTest.h
template class llvm::Registry<clang::PreprocessorFrontendAction>;
namespace clang {
typedef llvm::Registry<PreprocessorFrontendAction> PreprocessorFrontendPluginRegistry;
} // namespace clang
//PluginTest.cpp
namespace {
class TestPreprocessorFrontendAction : public PreprocessorFrontendAction{
public:
TestPreprocessorFrontendAction(){
cerr << "We have a constructor.\n";
}
protected:
virtual void ExecuteAction() {}
bool BeginSourceFileAction(CompilerInstance &CI, StringRef Filename){
setCompilerInstance(&CI);
cerr << "Inside BeginSourceFileAction. \n";
return true;
}
//This function should not be called by a PreprocessorFrontendAction
//and should be overloaded to return an abort. Or so say the headers.
virtual std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
cerr << "Inside the badness.\n";
return null ptr;
}
void EndSourceFileAction() {
cerr << "We have ignition?\n";
}
};
}
static PreprocessorFrontendPluginRegistry::Add<TestPreprocessorFrontendAction> X(
"test-plugin",
"Test preprocessor plugin");
最佳答案
如果您想编写一个 Hook 预处理器回调的 clang 插件,则必须按以下方式继续:
#include <clang/Frontend/FrontendPluginRegistry.h>
#include <clang/Frontend/FrontendActions.h>
#include <clang/Frontend/CompilerInstance.h>
using namespace clang;
class MyPPCallbacks : public PPCallbacks {
public:
// Implement callbacks here
};
class MyASTConsumer : public ASTConsumer {
public:
MyASTConsumer(CompilerInstance &CI) {
CI.getPreprocessor().addPPCallbacks(std::make_unique<MyPPCallbacks>());
}
};
class MyPluginASTAction : public PluginASTAction {
public:
std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
return std::make_unique<MyASTConsumer>(CI);
}
virtual bool ParseArgs(const CompilerIntance &CI, const std::vector<std::string> &args) {
return true;
}
};
static FrontendPluginRegistry::Add<MyPluginAction> X("my-plugin","My Plugin");
并在 MyPPCallbacks
中实现 clang::PPCallbacks
的任何回调。
关注this tutorial了解如何编译和使用 clang 插件。
关于plugins - 如何注册 clang 预处理器插件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31388228/