Clang 新手教程来啦!

2023-11-01

长话短说!

这篇新手教程会让你弄清楚什么是clang、clang AST、clang plugins 和clang tools 等等,让你大概知道clang 可以解决什么问题,而且小白也是可以用clang libraries 来开发工具的 :)

01 Clang 是什么

Clang 是一个以LLVM为后端的编译前端。编译前端主要负责parse 源码、检查错误,并生成抽象语法树 Abstract Syntax Tree (AST)。

相较于其他编译器生成的AST,clang 生成的AST 更加接近C++ 源码,所以我们可以更加准确地在源码中进行查找和定位。并且,clang 还提供了丰富的库和API,让我们能在AST 上很方便地做遍历,搜索和修改等操作。

我们在vscode 上用的代码自动补全工具clangd(或vim 的YouCompleteMe)就是用clang 来实现的。

(点击查看大图)

Ref:https://jonasdevlieghere.com/understanding-the-clang-ast/#clangfrontendast

02 什么时候会用到Clang

‣ 需要基于编译器的AST 对源码做精确的编辑

   ‣ 自动纠正不符合coding style 的源码

‣ 需要引入自定义的编译错误和警告

   ‣ 禁止用裸指针创建共享指针

   ‣ 声明了变量但是没有使用

‣ 基于C/C++  源码的代码生成(code generation)

   ‣ 自动生成数据结构的序列化方法,反射方法

03 Clang AST 是什么

‣ Clang AST 的节点是由几种没有共同基类的类来组成(建模)的

Clang’s AST nodes are modeled on a class hierarchy that does not have a common ancestor.  -- 《Introduction to the Clang AST》(https://clang.llvm.org/docs/IntroductionToTheClangAST.html#introduction-to-the-clang-ast)

   ‣ 其中比较常用的四种class 是 Type , Decl ,  DeclContext ,  Stmt 

‣ 每种节点都有专门的遍历函数来获取子节点

‣ ASTContext 里可以获取AST 的额外信息,比如源码的地址

‣ 例子:下面是一段简单的c++ 源码,我们可以看一下这段源码对应的AST

(点击查看大图)

运行结果:

先忽略掉上面的(一堆看不懂而且很吓人的东西 TranslationUnitDecl ) ,我们可以看到我们定义的两个函数在AST 的节点类型是 FunctionDecl  (也就是 Decl 的子类)。另外, CompoundStmt  是函数体的节点类型。其他的节点类型如果我们对照着源码来看的话,其实还是很好看懂的,比如 VarDecl 变量声明, IntegerLiteral 是整数文字。

(点击查看大图)

Ref:https://clang.llvm.org/docs/IntroductionToTheClangAST.html

04 Clang APIs

‣ Clang 提供C 和C++ API

   ‣ C API (libClang) 稳定但是不完整

   ‣ C++ API(LibTooling)完整但是不稳定

‣ LibTooling 主要用于开发standalone 工具,并且plugins 只能使用LibTooling 开发

下面的教程都是关于C++ API —— LibTooling 的

Ref:https://clang.llvm.org/docs/Tooling.html

什么是Clang plugins 和Clang tools

用LibTooling 可以开发两种形式的clang 工具:plugins (clang 插件) 或standalone tools (不依赖clang 运行的独立工具)。

Clang plugins 会在编译时对AST 进行一些额外的检查或操作。plugin是动态库(.so),在运行时由编译器(也就是clang)加载,所以可以很容易地集成到编译环境中。

Clang tools 是独立的(standalone) 可执行程序,比如clang-check,clang-format,clang-tidy 这些llvm project 官方提供的standalone tools。

有时候两种形式的工具都能解决问题。例如下面是一个叫LAComment 的工具,提供了两种工具形式:

(点击查看大图)

这时候我们可以思考下面的问题,来决定是开发plugin 还standlone 工具:

‣ 能不能选择用哪个编译器?clang / gcc?

‣ 需不需要make 或者break build

‣ Clang 6.0 写的plugin Clang 7.0 不一定能用(API 不稳定!)

‣ 部署环境(如CI pipeline)使用哪种工具用户接入成本更低?

RecursiveASTVisitor v.s. ASTMatcher

上面提到的LibTooling 库有两种API framework: RecursiveASTVisitor 和ASTMatcher:

‣ RecursiveASTVisitor 为大多数的AST 节点提供访问节点的hook  bool VisitNodeType(NodeType *) ;

‣ ASTMatcher 是一套用来匹配和遍历AST 的DSL;

‣ 两种framework 的选择并不互斥,必要时可以一起使用来解决比较复杂的问题!

例子:https://github.com/banach-space/clang-tutor/blob/main/README.md#unusedforloopvar

‣ 建议优先考虑用ASTMatcher,因为可以用clang-query 来验证DSL 是否正确。

感兴趣的同学可以尝试运行下面的命令,用clang-query 查看test.cc 里的函数节点。

(点击查看大图)

Ref:https://clang.llvm.org/docs/LibASTMatchersTutorial.html

05  如何写一个Clang 工具

1. 想清楚目的。这应该是最值得花时间,也有可能是最难的一步。因为当我们剖析清楚目的之后,我们可能会发现我们要做的事情其实可以用比clang 更简单的工具来完成。而且,如果我们一定要用clang,只有当目的足够清晰,我们才能知道要在AST 上查找哪种类型的节点,并对其进行操作;

2. 写一些最小的测试用例源码并用 clang -Xclang -ast-dump 来观察生成的AST;

3. 找到想要匹配的AST 节点;

4. 使用clang-query 来在测试用例上检验ASTMatcher;

5. 将ASTMatcher 的DSL集成到clang LibTooling 的脚手架里。

06  怎么创建Clang 工具项目

Llvm 的官方教程是用in tree的方法来创建工具的(即在 clang-llvm 的目录内加入工具代码) 。In tree 虽然setup 会比较简单,但是不便于做代码管理。

https://clang.llvm.org/docs/LibASTMatchersTutorial.html

所以如果我想要有更好的版本管理,甚至是接入CI/CD,就应该用Out of tree 的方式来创建工具(即在 clang-llvm 目录外创建工具代码)。Out of tree 创建方式下面的开源教程非常详细,感兴趣的同学可以参考一下:

https://github.com/banach-space/clang-tutor/blob/main/README.md

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Clang 新手教程来啦! 的相关文章

随机推荐

  • 谈文本分类

    本文来自对 文本分类研究综述 汪岿的阅读 文章目录 1 为什么要进行文本分类 2 文本分类的分类 应用 3 当前文本分类面临的挑战 4 文本分类的前景 1 为什么要进行文本分类 在大数据时代 网络上的文本数据日益增长 采用文本分类技术对海量
  • 04-Java框架-MyBatis

    一 MyBatis的介绍 1 1 回顾一下JDBC 下面这个代码是使用JDBC实现基于id查询员工信息 我们来分析分析有什么弊端 public Employee selectById Long id Connection conn null
  • 【解决】pytorch单机多卡问题:ERROR: torch.distributed.elastic.multiprocessing.api:failed

    最近在使用单机多卡进行分布式 DDP 训练时遇到一个错误 ERROR torch distributed elastic multiprocessing api failed 而实际报错的内容是 ValueError sampler opt
  • LeetCode·每日一题·722. 删除注释·模拟

    题目 示例 思路 题意 gt 给定一段代码 将代码中的注释删除并返回 由于注释只有两种类型 字符串 表示行注释 表示 和其右侧的其余字符应该被忽略 字符串 表示一个块注释 它表示直到下一个 非重叠 出现的 之间的所有字符都应该被忽略 阅读顺
  • Vuforia AR学习

    传送门 1 搜索 Vuforia 下载相关 SDK 和 Samples 2 这个就有点坑了 想运行 sample demo 需要把下载好的sample拷贝至sdk目录下的sample文件夹下 如图 3 也可以修改修改 Samples dem
  • Linux中nginx配置ssl证书实现https访问(nginx-1.16.1为例)

    配置ssl证书之前 先准备好SSL证书 至于获取的途径很多 不清楚的可以自行搜索 也可以留言 准备好证书后 找到nginx的安装目录 我的安装位置为 usr local nginx 1 16 1 进入 conf nginx conf 编辑n
  • 数据结构:哈夫曼树算法(内含Select函数算法解析)全网最全解释

    引言 学习数据结构的都应该清楚 哈夫曼树是书章节的最后一个内容 也是相对重要的一个知识 他可以应用在生活的各个例子中 如下图所示 假设有ABCD 四个货物架D货架物品被人购买的概率是20 C货架是 35 B货架是 60 D货架是80 那么显
  • python 数组-(列表遍历)(元素互换)

    lisName 张三丰 李四 王麻子 饭桶 遍历列表中所有元素 print 20 for obj in lisName print obj print 20 通过 下标 索引获取值 for i in range 0 len lisName
  • blender快捷键

    tab 模式切换 可以shift多物体切换 主键盘 1点 2线 3面 按住shift 点击点面 可以多选 或者shift 1 2 3多选 ctrl alt q 四象视图 小键盘1前 3右 7顶 9切换前后 也可以按crl 1后视图 小键盘
  • STL系列之十 全排列(百度迅雷笔试题)

    转载自 http blog csdn net morewindows article details 7370155 全排列在笔试面试中很热门 因为它难度适中 既可以考察递归实现 又能进一步考察非递归的实现 便于区分出考生的水平 所以在百度
  • GlidedShy 第一题 实现自动登录和数据爬取

    python 自动登录 控制以及接管浏览器 爬取信息练习 GlidedShy官网 爬虫练习网站 代码仅供学习参考 功能实现步骤 自动登录 输入账号密码 选择题目 爬取数据 自动提交后返回 验证邮箱 注册时已人工验证 框架 Seleium控制
  • spdlog和fork冲突问题

    遇到个问题 使用spdlog的async logger打印日志 一直都是正常的 但是调用了fork之后就不打印了 先使用打印TODO大法 使用的spdlog的default logger打印 走的console打印 结果发现console打
  • win10 WSL2 Docker 与 Linux Docker

    项目场景 项目场景 用win10 wsl2 docker开发使用GPU tensorflow onnx TensorRT 的镜像 然后部署到Linux生产环境进行使用 发现不识别cuda驱动 问题描述 在Linux上运行wsl2 save
  • 优化算法基本原理

    优化算法基本原理 机器学习就两个问题 一个是model的定义 一个就是如何优化 model是战略 优化则是执行 在Caffe现在的版本中 主要使用了三种优化算法SGD AdaGrad 以及NAG 这三种算法快速 高效 缺点就是极容易收敛到局
  • iOS架构-组件化(项目实战-项目首页架构)

    UI架构设计 设计模式 外观模式 代理模式 适配器模式 adapter 注意 一版本只是搭建结构 一 1 0 Tab搭建 二 1 1 新增UICollectionView 主页 gt 整体设计基于 gt UICollectionView 滑
  • protobuf介绍和语法

    目录 前言 语法 标识符 字段 字段类型 proto2和proto3区别 前言 Protobuf即Protocol Buffers 是Google公司开发的一种跨语言和平台的序列化数据结构的方式 是一个灵活的 高效的用于序列化数据的协议 与
  • 用CSS实现宽度自适应100%,宽高比例为16: 9的矩形

    宽度自适应100 宽高比为16 9 即100 h 16 9 计算出来矩形高度 h 56 25 父元素设置height 0 padding bottom 56 25 是为了让子元素适应父元素的高度 子元素高度 父元素的 padding bot
  • python 崇天_python 从入门到放弃-----认识python的过程

    因为初来匝道 这样子写不知道会不会有问题 这里我先写下来 后期如果有问题 再修改 这里只记录一个小渣渣的学习过程和总结 中途学习爬虫也断断续续 还在继续努力中 但也总结自己的一些个人经验 1 零基础学习爬虫 还是要学python和HTML的
  • 2023年第二届服务机器人国际会议(ICoSR 2023)

    会议简介 Brief Introduction 2023年第二届服务机器人国际会议 ICoSR 2023 会议时间 2023年7月21日 23日 召开地点 中国 上海 大会官网 www iwosr org ICoSR 2023将围绕 服务机
  • Clang 新手教程来啦!

    长话短说 这篇新手教程会让你弄清楚什么是clang clang AST clang plugins 和clang tools 等等 让你大概知道clang 可以解决什么问题 而且小白也是可以用clang libraries 来开发工具的 0