文章目录
- 前言
- 在这里简要概述一下clang的流程
- 1.clang driver代码分析
- 1.1创建诊断(`DIagnosticsEngine`)实例
- 1.2创建Driver(`clang::driver::Driver`)的实例
- 1.3通过`Driver`的`BuildCompilation`方法生成需要执行的命令
- 1.4`Jobs`构建完成,通过`Driver`的`ExecuteCompilation`方法执行命令
- 2.剖析`构建`,对`BuildCompilation`作进一步分析(进入1.3函数)
- 2.1调用`ParseArgStrings`函数处理程序接收的参数、对配置文件解析
- 2.2通过`computeTargetTriple`函数`获取`triple`,并通过`getToolChain`函数获取对应的`ToolChain`
- 2.2.1`getToolChain`函数就根据传递的`triple`的系统信息返回对应的实例
- 2.3创建`Commpilation`持有参数
- 2.4获取输入文件(main.c),通过`BuildInputs`函数
- 2.4.1`BuildInputs`剖析
- 2.4.1.1 `types::ID types::lookupTypeForExtension(llvm::StringRef Ext)` 函数会根据输入文件 `main.c` 的扩展名 `c` 获取该文件的类型 `TY_C`
- 2.5 输入的文件处理完成,通过`BuildUniversalActions`函数构建`Action`
- 2.6随后再通过 `BuildJobs` 函数构建 `Jobs`
- 总结
前言
上一节中我们说了clang main.c -o main
会调用clang driver
,而clang driver
会对要执行的编译器命令和ld
命令进行拼接。clang driver
的处理过程主要分为:
-
Parse:Option Parsing:解析传入的参数
-
Pipeline:Compilation Action Construction:根据每个输入的文件和类型,组建
action
(如PreprocessJobAction
),它具体处理的Action
可以通过clang -ccc-print-phases
来查看。$clang -ccc-print-phases -c min.c min2.c +- 0: input, "min.c", c +- 1: preprocessor, {0}, cpp-output +- 2: compiler, {1}, ir +- 3: backend, {2}, assembler 4: assembler, {3}, object +- 5: input, "min2.c", c +- 6: preprocessor, {5}, cpp-output +- 7: compiler, {6}, ir +- 8: backend, {7}, assembler 9: assembler, {8}, object
-
Bind Tool & FileName Selection:根据
action
选择对应的工具和文件名信息,具体使用的工具和文件名可以通过clang -ccc-print-bindings
查看在这里插入代码片
-
Translate:Tool Specific Arguments Translation:根据输入的参数转为不同的
tool
的参数 -
Execute:调用不同的
tool
执行任务
该步骤会以创建子进程的方式调用tool
,clang driver
会创建两个子线程clang -cc1
和ld
执行最终的编译任务和链接任务。clang -cc1
将源文件.c
转换为目标文件.o
。
在这里简要概述一下clang的流程
以clang min.c -###
会打印clang driver
所驱动的内容
- 第一步:
clang
以clang driver
模式被调用 - 第二步,
clang driver
会根据传入的min.c
构建两个Job- 第一个任务是编译任务,
clang
接收-cc1
参数后会以编译器的身份执行编译任务,输入文件是min.c
,输出文件是min.o
对象文件。 - 第二个任务是链接任务,
ld
会将main.o
链接为min
可执行文件
- 第一个任务是编译任务,
- 最后会根据上面的两个Job创建的新进程执行上面两个Job,来完成编译任务。
1.clang driver代码分析
1.1创建诊断(DIagnosticsEngine
)实例
诊断会在编译过程中同步运行,编译器通过诊断提供Error、Warning 和 Info等
1.2创建Driver(clang::driver::Driver
)的实例
TheDriver
将会负责后续的clang driver
任务
1.3通过Driver
的BuildCompilation
方法生成需要执行的命令
1.4Jobs
构建完成,通过Driver
的ExecuteCompilation
方法执行命令
2.剖析构建
,对BuildCompilation
作进一步分析(进入1.3函数)
2.1调用ParseArgStrings
函数处理程序接收的参数、对配置文件解析
2.2通过computeTargetTriple
函数获取
triple,并通过
getToolChain函数获取对应的
ToolChain`
2.2.1getToolChain
函数就根据传递的triple
的系统信息返回对应的实例
2.3创建Commpilation
持有参数
2.4获取输入文件(main.c),通过BuildInputs
函数
2.4.1BuildInputs
剖析
clang driver
支持一次性编译多个源文件BuildInputs
方法会遍历所有的参数,并筛选Option::InputClass
类型的参数,最后调用函数types::ID types::lookupTypeForExtension(llvm::StringRef Ext)
获取对应的types::ID