Clang(孙源Clang视频整理)
- LLVM - Low Level Virtual Machine
- Clang /ˈklæŋ/ - C Language Family Frontend for LLVM
Three-Phase 编译器架构
Clang/Swift - LLVM 编译器架构
Clang 命令
- Clang在概念上是编译器前端,同时,在命令行中也作为一个“ 黑盒”的 Driver
- 封装了编译管线、前端命令、LLVM 命令、Toolchain 命令等
- 方便从gcc迁移过来
Clang-LLVM 下,一个源文件的编译过程
1.Preprocess - 预处
- import 头文件
- macro 展开
- 处理‘#’打头的预处理指令,如 #if
$ clang -E main.m
2.Lexical Analysis - 词法分析
- 词法分析,也作Lex或者Tokenization
- 将预处理过的代码文本转化成Token流
- 不校验语义
$clang -fmodules -fsyntax-only -Xclang -dump-tokens main.m
3. Semantic Analysis - 语法分析
- 语法分析,在Clang中由Parser和Sema两个模块配合完成
- 验证语法是否正确
- 根据当前语 的语法,生成语意节点,并将所有节点组合成抽象语法树(AST)
$clang -fmodules -fsyntax-only -Xclang -ast-dump main.m
Static Analysis - 静态分析
- 通过语法树进 代码静态分析,找出非语法性错误
- 模拟代码执路径,分析出control-flow graph (CFG)
- 预置了常用Checker
4. CodeGen - IR 代码生成
- CodeGen负责将语法树从顶至下遍历,翻译成LLVM IR
- LLVM IR是Frontend的输出,也是LLVM Backend的输入,前后端的桥接语
- 与Objective-C Runtime桥接
$clang -S -fobjc-arc -emit-llvm main.m -o main.ll
与 Objective-C Runtime 桥接
Class/Meta Class/Protocol/Category
内存结构生成,并存放在指定section中(如 Class:_DATA,_objc_classrefs)Method/Ivar/Property
内存结构生成组成 method_list/ivar_list/ property_list并填入Class
Non-Fragile ABI:为每个 Ivar 合成 OBJCIVAR$_ 偏移值常量
存取Ivar的语句(ivar = 123; int a = _ivar;) 转写成 base+ OBJC_IVAR$_ 的形式
将语法树中的ObjCMessageExpr翻译成相应版本的
objc_msgSend
,对super
关键字的调用翻译成objc_msgSendSuper
- 根据修饰符
strong/weak/copy/atomic
合成@property
自动实现的 setter/getter 处理
@synthesize
生成
block_layout
的数据结构- 变量的
capture
(__block
/__weak
) 生成
_block_invoke
函数ARC:分析对象引用关系,将
objc_storeStrong
/objc_storeWeak
等ARC代码插入- 将ObjCAutoreleasePoolStmt转译成
objc_autoreleasePoolPush/Pop
- 实现自动调用
[super dealloc]
- 为每个拥有ivar的Class合成
.cxx_destructor
法来自动释放类的成员变量,代替 RC时代的"self.xxx = nil"
5.Optimize - 优化 IR
$clang -O3 -S -fobjc-arc -emit-llvm main.m -o main.ll
6.LLVM Bitcode - 成字节码
$clang -emit-llvm -c main.m -o main.bc
7.Assemble - 生成 Target 相关汇编
$clang -S -fobjc-arc main.m -o main.s
8.Assemble - 生成 Target 相关 Object (Mach-O)
$clang -fmodules -c main.m -o main.o
9.Link 生成 Executable
$clang main.m -o main $./main