使用Clang作为库 —— Clang Plugins


本文为译文,点击 此处查看原文。

Clang Plugins可以在编译期间运行额外的用户定义的操作。本文档将提供如何编写和运行一个 Clang Plugins 的基本步骤。

1. 介绍

Clang Plugins在代码上运行FrontendActions。请参阅关于如何使用RecursiveASTVisitor编写一个FrontendActionFrontendAction教程。在本教程中,我们将演示如何编写一个简单的clang plugin

2. 编写一个PluginASTAction

编写PluginASTAction与编写普通FrontendActions的主要区别在于,您可以处理plugin命令行选项PluginASTAction基类声明了一个ParseArgs方法,您必须在您的 plugin 中实现这个方法。

bool ParseArgs(const CompilerInstance &CI,
               const std::vector<std::string>& args) {
  for (unsigned i = 0, e = args.size(); i != e; ++i) {
    if (args[i] == "-some-arg") {
      // 处理命令行参数
    }
  }
  return true;
}

3. 注册一个plugin

编译器在运行时从一个动态库加载一个 plugin。要在库中注册一个 plugin,使用FrontendPluginRegistry::Add<>

static FrontendPluginRegistry::Add<MyPlugin> X("my-plugin-name", "my plugin description");

4. 定义pragmas

Plugins 还可以通过声明一个PragmaHandler来定义 pragmas 并使用PragmaHandlerRegistry::Add<>来注册它:

// Define a pragma handler for #pragma example_pragma
class ExamplePragmaHandler : public PragmaHandler {
public:
  ExamplePragmaHandler() : PragmaHandler("example_pragma") { }
  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
                    Token &PragmaTok) {
    // Handle the pragma
  }
};

static PragmaHandlerRegistry::Add<ExamplePragmaHandler> Y("example_pragma","example pragma description");

5. 把它们放在一起

让我们看一个示例plugin,它打印顶级函数名。这个例子被检入clang存储库;请查看PrintFunctionNames.cpp的最新版本

6. 运行此plugin

6.1 使用cc1命令行

要运行一个 plugin,必须通过-load命令行选项加载包含这个 plugin 注册表的动态库。这将加载所有已注册的 plugin,您可以通过指定-plugin选项来选择要运行的 plugin。plugin的附加参数可以通过-plugin-arg-<plugin-name>来传递。

注意,这些选项必须到达 clang 的cc1过程。有两种方法可以做到这一点:

  • 使用-cc1选项直接调用解析过程;这样做的缺点是没有配置默认的头文件搜索路径,因此需要在命令行上指定完整的系统路径配置。
  • 像往常一样使用 clang,但是在cc1过程的所有参数前面加上-Xclang

例如,要在 clang 中一个源文件上运行 print-function-names plugin,首先构建此 plugin,然后从源文件树中使用 plugin 调用 clang:

$ export BD=/path/to/build/directory
$ (cd $BD && make PrintFunctionNames )
$ clang++ -D_GNU_SOURCE -D_DEBUG -D__STDC_CONSTANT_MACROS \
          -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -D_GNU_SOURCE \
          -I$BD/tools/clang/include -Itools/clang/include -I$BD/include -Iinclude \
          tools/clang/tools/clang-check/ClangCheck.cpp -fsyntax-only \
          -Xclang -load -Xclang $BD/lib/PrintFunctionNames.so -Xclang \
          -plugin -Xclang print-fns

还请参阅 print-function-name plugin示例的README

6.2 使用clang命令行

在 clang 命令行上使用-fplugin=plugin将 plugin 作为一个参数传递给 cc1命令行上的-load。如果 plugin 类实现了getActionType方法,那么此 plugin 将自动运行。例如,在 main AST action 之后自动运行此 plugin(即与使用-add-plugin相同):

// Automatically run the plugin after the main AST action
PluginASTAction::ActionType getActionType() override {
  return AddAfterMainAction;
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值