Clang 新手教程

长话短说

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

Clang 是什么?

Clang 是一个以LLVM为后端的编译前端。

编译前端主要负责parse 源码,检查错误,并生成Abstract Syntax Tree (AST)。

Ref: Understanding the Clang AST

什么时候会用到Clang?

  • 需要基于编译器的AST 对源码做精确的编辑
  • 需要引入自定义的编译错误和警告
  • 基于C/C++ 源码的代码生成(code generation),比如生成数据结构的序列化,语言交互接(Foreign function interface)

Clang AST 是什么?

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

Clang’s AST nodes are modeled on a class hierarchy that does not have a common ancestor.

  • 其中比较常用的四种class 是Type,Decl,DeclContext,Stmt
  • 每种节点都有专门的遍历函数来获取子节点
  • ASTContext 里可以获取AST 的额外信息,比如源码的地址
  • 例子
// test.cc
int foo(int num) {
  int result = (num / 2);
  return result;
}

void test_f() {
  int i = 10;
  int b = foo(i);
}
clang -Xclang -ast-dump -fsyntax-only test.cc

Ref: Introduction to the Clang AST - Clang 15.0.0git documentation

Clang APIs

  • Clang 提供C 和C++ API

    • C API (libClang) 稳定但是不完整
    • C++ API(LibTooling)完整但是不稳定
  • LibTooling 主要用于开发standalone 工具,并且plugins 只能使用LibTooling

Ref: Choosing the Right Interface for Your Application - Clang 15.0.0git documentation

Clang plugins v.s. Clang tools

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

Clang tools 是由LibTooling 开发的可执行程序,比如clang-check,clang-format,clang-tidy 这些llvm project 提供的。

有时候两种方式都能解决问题:

# 1. As a loadable Clang plugin:
clang -cc1 -load <BUILD_DIR>/lib/libLACommenter.so '\'
      -plugin LACPlugin test/LACInt.cpp
# 2. As a standalone tool:
<BUILD_DIR>/bin/ct-la-commenter test/LACInt.cpp

考虑点:

  • 能不能控制用哪个编译器?clang / gcc?
  • 需不需要make 或者break build
  • Clang 6.0 写的plugin Clang 7.0 不一定能用(API 不稳定!)
  • CI 环境使用哪种工具用户接入成本更低?

RecursiveASTVisitor v.s. ASTMatcher

LibTooling 有两种framework: RecursiveASTVisitor 和ASTMatcher

clang-query test.cc
# some useful commands to setup clang-query
set output dump
set bind-root false
set traversal IgnoreUnlessSpelledInSource

m functionDecl()
m functionDecl(hasName("foo"))

Ref:

How to write RecursiveASTVisitor based ASTFrontendActions. - Clang 15.0.0git documentation

Tutorial for building tools using LibTooling and LibASTMatchers - Clang 15.0.0git documentation

AST Matcher Reference

如何写一个Clang 工具?

  1. 想清楚目的
  2. 写一些最小的测试用例源码并用clang -Xclang -ast-dump 来观察生成的AST
  3. 找到想要匹配的AST 节点
  4. 使用clang-query 来在测试用例上检验ASTMatcher
  5. 将ASTMatcher 的DSL集成到clang LibTooling 的脚手架里

怎么创建Clang 工具项目?

注意:llvm 编译linking 占用内存非常高!所以要用单线程make,而且16G 内存的话,要将swap file 增加到16G 才能编译。ref: How to increase swap space?

有用的资源

Last modification:April 6th, 2023 at 11:25 am