2401llvm,clang插件

Clang插件

在编译时,Clang插件可运行额外的用户定义操作.

介绍

Clang插件在代码上运行FrontendActions.见FrontendAction教程,了解如何使用RecursiveASTVisitor编写FrontendAction.
这里,演示如何编写简单的clang插件.

编写PluginASTAction插件

与编写普通FrontendActions的主要区别在,可处理插件命令行选项.PluginASTAction基类声明一个必须在插件中实现的ParseArgs方法.

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;
}

注册插件

运行时,编译器从动态库加载插件.要在库中注册插件,请使用FrontendPluginRegistry::Add<>:

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

定义编译指示

插件还可通过声明PragmaHandler并使用PragmaHandlerRegistry::Add<>注册它,来定义编译指示:

//定义`#pragma example_pragma`的编译指示处理器
class ExamplePragmaHandler : public PragmaHandler {
public:ExamplePragmaHandler() : PragmaHandler("example_pragma") { }void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer, Token &PragmaTok) {//处理编译指示}
};
static PragmaHandlerRegistry::Add<ExamplePragmaHandler> Y("example_pragma","example pragma description");

定义属性

插件可通过声明ParsedAttrInfo并使用ParsedAttrInfoRegister::Add<>注册它来定义属性:

class ExampleAttrInfo : public ParsedAttrInfo {
public:ExampleAttrInfo() {Spellings.push_back({ParsedAttr::AS_GNU,"example"});}AttrHandling handleDeclAttribute(Sema &S, Decl *D, const ParsedAttr &Attr) const override {//处理属性return AttributeApplied;}
};
static ParsedAttrInfoRegistry::Add<ExampleAttrInfo> Z("example_attr","example attribute description");

插件属性必须定义的ParsedAttrInfo的成员包括:

1,拼写(Spellings),必须用属性的每个,都由属性语法该语法的属性名拼写方式组成的拼写这里填充.
如果语法允许域,则拼写必须为"scope::attr"(如果有域)或"::attr"(如果没有).

2,handleDeclAttribute,这是应用属性到声明的函数.它负责检查属性参数是否有效,且一般给Decl添加Attr应用属性.

它返回AttributeApplied(指示已成功应用属性)或(失败)AttributeNotApplied.

根据属性,可能要定义的ParsedAttrInfo成员包括:
1,NumArgsOptArgs,设置属性的必需参数和可选参数个数.
2,diagAppertainsToDecl,检查属性是否用在正确的声明类型上,如果没有,则发出诊断.
3,diagLangOpts,检查当前语言模式是否允许该属性,如果禁止,则发出诊断.
4,existsInTarget,检查给定目标是否允许该属性.

Attribute.cpp示例,可查看属性插件的工作示例.

放在一起

用打印顶级函数名来示例插件.此例已签入clang仓库;请查看最新版本的PrintFunctionNames.cpp.

运行插件

用编译器驱动

Clang驱动接受-fplugin选项来加载插件.Clang插件可通过fplugin-arg-<pluginname>-<argument>选项,从编译器驱动命令行接收参数.

这样,插件名自身不能包含破折号,但传递给插件的参数可以.

$ export BD=/path/to/build/directory
$ make -C $BD CallSuperAttr
$ clang++ -fplugin=$BD/lib/CallSuperAttr.so \-fplugin-arg-call_super_plugin-help \test.cpp

如果插件名包含破折号,请重命名插件或使用下面列举的cc1命令行选项.

使用cc1命令行

要运行插件,必须通过-load命令行选项,加载包含插件注册表的动态库.这加载所有已注册的插件,可通过指定-plugin选项来选择要运行的插件.

可用-plugin-arg-<plugin-name>传递插件其他参数.

注意,这些选项必须到达clangcc1进程.有两个方法:
1,用-cc1选项直接调用解析过程;缺点是没有配置默认头文件搜索路径,因此要在命令行上指定完整系统路径配置.
2,如常使用clang,但在cc1进程的所有参数前面加上-Xclang.

如,要对clang中的源文件上运行print-function-names插件,请先构建该插件,然后用源码树中的插件调用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插件示例的README这里

使用clang命令行

clang命令行上,使用-fplugin=plugin,在cc1命令行上,按-load参数传递插件.如果插件类实现了getActionType方法,则会自动运行插件.

如,要在主AST操作后自动运行插件(即与用-add-plugin相同):

//在主`AST`操作后自动运行插件
PluginASTAction::ActionType getActionType() override {return AddAfterMainAction;
}

-clear-ast-before-backend的交互

为了减少编译器的内存使用峰值,建议在一般是生成代码主操作前,运行插件.这是因为在codegen操作后运行插件,都会自动关闭-clear-ast-before-backend.

-clear-ast-before-backend通过在生成IR后和运行IR优化前,清理ClangAST来减少峰值内存.按getActionType,使用CmdlineBeforeMainActionAddBeforeMainAction来运行插件,同样受益于-clear-ast-before-backend.

插件必须确保不修改AST,否则应在主操作之后运行它们.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/641598.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

图解CART分类树评估器的参数

图解CART分类树评估器的参数

联邦学习:密码学 + 机器学习 + 分布式 实现隐私计算,破解医学界数据孤岛的长期难题

联邦学习&#xff1a;密码学 机器学习 分布式 提出背景&#xff1a;数据不出本地&#xff0c;又能合力干大事联邦学习的问题 分布式机器学习&#xff1a;解决大数据量处理的问题横向联邦学习&#xff1a;解决跨多个数据源学习的问题纵向联邦学习&#xff1a;解决数据分散在多…

(一)SpringBoot3---尚硅谷总结

目录 示例Demo&#xff1a; 1、我们先来创建一个空工程&#xff1a; 2、我们通过Maven来创建一个Module&#xff1a; 3、让此Maven项目继承父项目: 4、导入web开发的场景启动器 5、创建Springboot项目的主入口程序&#xff1a; 6、举例测试&#xff1a; 7、Springboot还能…

020-信息打点-红蓝队自动化项目资产侦察企查产权武器库部署网络空间

020-信息打点-红蓝队自动化项目&资产侦察&企查产权&武器库部署&网络空间 #知识点&#xff1a; 1、工具项目-红蓝队&自动化部署 2、工具项目-自动化侦查收集提取 3、工具项目-综合&网络空间&信息 演示案例&#xff1a; ➢自动化-武器库部署-F8x ➢自…

初级通信工程师-法律法规

1、《电信条例》修订的目的 ● 《电信条例》在最初颁布之后&#xff0c;陆续进行了两次修订&#xff0c;尤其是2016年做了最新的 修订。 ● 《电信条例》修订的目的是为了适应新的经济发展的需要&#xff0c;包括四个方面&#xff1a; ①规范电信市场秩序&#xff1b; ②维…

leetcode—图 岛屿数量

岛屿数量 给你一个由 1&#xff08;陆地&#xff09;和 0&#xff08;水&#xff09;组成的的二维网格&#xff0c;请你计算网格中岛屿的数量。 岛屿总是被水包围&#xff0c;并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。 此外&#xff0c;你可以假设该网…

RabbitMQ入门篇【图文并茂,超级详细】

&#x1f973;&#x1f973;Welcome 的Huihuis Code World ! !&#x1f973;&#x1f973; 接下来看看由辉辉所写的关于Docker的相关操作吧 目录 &#x1f973;&#x1f973;Welcome 的Huihuis Code World ! !&#x1f973;&#x1f973; 前言 1.什么是MQ 2.理解MQ 3.生活…

记一个奇怪的万能密码

前言 打的站点打多了&#xff0c;什么奇怪的问题都会发生 打点 开局一个登录框 用户枚举到账号爆破 测了一下&#xff0c;没发现admin的弱口令&#xff0c;但是发现存在用户枚举漏洞&#xff0c;因此准备跑一下账号 输入密码为123456 进行账号爆破 成功爆破出账号 是的…

【ARM 嵌入式 编译系列 7.3 -- GCC 链接脚本中 DISCARD 与 .ARM.exidx】

请阅读【嵌入式开发学习必备专栏 之 ARM GCC 编译专栏】 文章目录 背景.ARM.exidx方法一:使用链接器脚本方法二:使用链接器选项注意事项背景 在移植 RT-Thread 到 cortex-m33(RA4M2)上的时候,在编译的时候遇到下面问题: Building target: ra4m2.elf arm

leetcode常见面试题总结 Python

持续维护中... 1. 寻找 k 个最小数 输入整数数组 arr &#xff0c;找出其中最小的 k 个数。例如&#xff0c;输入4、5、1、6、2、7、3、8这8个数字&#xff0c;则最小的4个数字是1、2、3、4。 示例&#xff1a; 输入&#xff1a;arr [3,2,1], k 2 输出&#xff1a;[1,2] …

Spring/Spring boot项目接入traceId

简介 分布式系统中&#xff0c;由多个服务构成&#xff0c;每个请求路由过来后&#xff0c;会在多个服务中留下追踪ID&#xff0c;可以基于此追踪ID排查问题&#xff0c;分析请求的执行链路。 业界也有比较成熟的链路追踪ID方案&#xff0c;比如Skywalking&#xff0c;它基于…

python 抓包tcp数据拷贝转发

在Python中&#xff0c;你可以使用scapy库进行抓包&#xff0c;使用shutil或io库进行数据的拷贝&#xff0c;以及使用socket库进行数据转发。下面是一个简单的示例&#xff0c;展示了如何进行这些操作&#xff1a; 首先&#xff0c;你需要安装必要的库。你可以使用pip来安装它…

Java算法 leetcode简单刷题记录4

Java算法 leetcode简单刷题记录4 买卖股票的最佳时机&#xff1a; https://leetcode.cn/problems/best-time-to-buy-and-sell-stock/ 笨办法&#xff1a; 记录当天的值及之后的最大值&#xff0c;相减得到利润&#xff1b; 所有的天都计算下&#xff0c;比较得到利润最大值&…

PyTorch视觉工具箱:图像变换与上采样技术详解(1)

目录 Pytorch中Vision functions详解 pixel_shuffle 用途 用法 使用技巧 注意事项 参数 数学理论公式 示例代码及输出 pixel_unshuffle 用途 用法 使用技巧 注意事项 参数 数学理论公式 示例代码及输出 pad 用途 用法 使用技巧 注意事项 参数 示例代码…

智能机器人与旋量代数(9)

Chapt 3. 螺旋运动与旋量代数 3.1 螺旋运动 螺旋运动是关于一条空间直线的一个旋转运动&#xff0c;并伴随沿此直线的一个平移。是一种刚体绕空间轴 s s s旋转 θ \theta θ角&#xff0c;再沿该轴平移距离 d d d的复合运动&#xff0c;类似螺母沿螺纹做进给运动的情形。 一…

2024年【焊工(初级)】考试内容及焊工(初级)新版试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 焊工&#xff08;初级&#xff09;考试内容参考答案及焊工&#xff08;初级&#xff09;考试试题解析是安全生产模拟考试一点通题库老师及焊工&#xff08;初级&#xff09;操作证已考过的学员汇总&#xff0c;相对有…

docker 使用 vcs/2018 Verdi等 eda 软件

好不容易在ubuntu 安装好了eda软件&#xff0c;转眼就发现了自己的无知。 有博主几年前就搞定了docker上的EDA工具。而且更全&#xff0c;更简单。只恨自己太无知啊。 Synopsys EDA Tools docker image - EDA资源使用讨论 - EETOP 创芯网论坛 (原名&#xff1a;电子顶级开发网…

python解决从有序数组中寻找中位数

如果给定两个长度分别是m和n的有序数组array1和array2&#xff0c;需要对这两个有序数组找出其中的中位数&#xff0c;需要保证时间复杂度是O(long(min(m,n))&#xff0c;空间复杂度是O(1)。如下例子&#xff1a; 添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#…

【教程】混淆Dart 代码

什么是代码混淆&#xff1f; 代码混淆是一种将应用程序二进制文件转换为功能上等价&#xff0c;但人类难于阅读和理解的行为。在编译 Dart 代码时&#xff0c;混淆会隐藏函数和类的名称&#xff0c;并用其他符号替代每个符号&#xff0c;从而使攻击者难以进行逆向工程。 Flut…

ChatGPT和文心一言哪个更好用?

目录 一、ChatGPT和文心一言大模型的对比分析 1.1 二者训练的数据情况分析 1.2 训练大模型数据规模和参数对比 1.3 二者3.5版本大模型对比总结 二、ChatGPT和文心一言功能对比分析 2.1 二者产品提供的功能情况分析 2.2 测试一下各种功能的特性 2.2.1 文本创作能力 2.2…