Clang - ShenYj/ShenYj.github.io GitHub Wiki
Clang是一个C语言、C++、Objective-C语言的轻量级编译器。源代码发布于BSD协议下。 Clang将支持其普通lambda表达式、返回类型的简化处理以及更好的处理constexpr关键字。
Clang是一个由Apple主导编写,基于LLVM的C/C++/Objective-C编译器 2013年4月,Clang已经全面支持C++11标准,并开始实现C++1y特性(也就是C++14,这是 C++的下一个小更新版本)。Clang将支持其普通lambda表达式、返回类型的简化处理以及更 好的处理constexpr关键字。
Clang是一个C++编写、基于LLVM、发布于LLVM BSD许可证下的C/C++/Objective-C/ Objective-C++编译器。它与GNU C语言规范几乎完全兼容(当然,也有部分不兼容的内容, 包括编译命令选项也会有点差异),并在此基础上增加了额外的语法特性,比如C函数重载 (通过__attribute__((overloadable))来修饰函数),其目标(之一)就是超越GCC
1、预处理(preprocessor)
预处理会替进行头文件引入,宏替换,注释处理,条件编译(#ifdef)等操作
2、词法分析(lexical anaysis)
读入源文件的字符流,将他们组织成有意义的词素(lexeme)序列,对于每个词素,此法分析器产生词法单元(token)作为输出
3、语法分析(semantic analysis)
词法分析的Token流会被解析成一颗抽象语法树(abstract syntax tree - AST)。AST是开发者编写clang插件主要交互的数据结构,clang也提供很多API去读取AST。更多细节:Introduction to the Clang AST。
4、CodeGen
CodeGen遍历语法树,生成LLVM IR代码。LLVM IR是前端的输出,后端的输入。
5、生成汇编代码
LLVM对IR进行优化后,会针对不同架构生成不同的目标代码,最后以汇编代码的格式输出
6、汇编器生成 .o文件
汇编器以汇编代码作为输入,将汇编代码转换为机器代码,最后输出目标文件(object file)
7、连接器
把编译产生的.o文件和(dylib,a,tbd)文件,生成一个mach-o文件
-
把目标文件编译成c++文件
clang -rewrite-objc main.m -o main.cpp
-
指定SDK路径
clang -rewrite-objc -fobjc-arc -fobjc-runtime=ios-13.0.0 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/ iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator13.0.sdk main.m
-
clang编译
.o
文件、链接等操作可以参考之前整理的静态库相关笔记 -
查看源码的编译阶段
clang -ccc-print-phases
❯ clang -ccc-print-phases main.m +- 0: input, "main.m", objective-c +- 1: preprocessor, {0}, objective-c-cpp-output +- 2: compiler, {1}, ir +- 3: backend, {2}, assembler +- 4: assembler, {3}, object +- 5: linker, {4}, image 6: bind-arch, "x86_64", {5}, image
0-> 输出文件:找到源文件
1-> 预处理阶段:这个过程处理包扩宏的替换,头文件的导入
2-> 编译阶段:进行此法分析、语法分析、检测语法是否正确,最终生成IR
3-> 后端:这里LLVM会通过一个个Pass去优化,每个Pass做一些事情,最终生成汇编代码
4-> 生成目标文件
5-> 链接:链接需要的动态库和静态库,生成可执行文件
6-> 通过不同的架构,省测绘功能对应的可执行文件-
预处理阶段
clang -E main.m
执行完毕后可以看到头文件的导入和宏的替换 -
编译阶段
-
词法分析 与处理完成后就会进行词法分析,这里会把代码切成一个个Token,比如大小括号、关键词、等于号和其他字符串等,clang指令为
clang -fmodules -fsyntax-only -Xclang -dump-tokens main.m
-
语法分析 词法分析完成之后就是语法分析,它的任务是验证语法是否正确。在词法分析的基础上将单词序列组合成各类语法短语,如“程序”,“语句”,“表达式”等等,然后将所有节点组成抽象语法书(Abstract Syntax Tree, AST)。语法分析程序判断源程序在接受上是否正确。clang指令为
clang -fmodules -fsyntax-only -Xclang -ast-dump mian.m
-
生成中间代码IR 完成上述步骤后就开始生成中间代码IR了,代码生成器(Code Generation)会将语法树自顶向下逐步翻译成LLVM IR。通过下面指令可以生成.ll的文本文件,查看IR代码
clang -S -fobjc-arc -emit-llvm main.m
Object-C代码在这一部会进行runtime的桥接:property合成,ARC处理等- IR 的部分基础语法
@: 全局标识
%: 局部标识
alloca:开辟空间
align: 内存对齐
i32: 32个bit,4个字节
store:写入内存
load:读取数据(从内存读取到cpu)
call: 调用函数
ret: 返回 - IR 的优化
LLVM的优化级别分别是
-O0
-O1
-O2
-O3
-Os
e.g.:clang -Os -S -fobjc-arc -emit-llvm main.m -o main.ll
- IR 的部分基础语法
-
-
xcode
安装的时候顺带安装了xcrun
命令,xcrun
命令在clang
的基础上进行了一些封装,要更好用一些
-
xcrun -sdk iphonesimulator clang -arch arm64 -rewrite-objc main.m -o main-arm64.cpp
(模拟器) -
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m -o main- arm64.cpp
(手机)