(TL; DontWannaRead – 跳到这个答案的结尾)
要正确回答您的问题,您首先需要了解编译器的front-end和back-end(特别是第一个)之间的区别.
Clang是C,C,Objective C和Objective C语言的编译器前端(http://en.wikipedia.org/wiki/Clang).
Clang的职责如下:
即从C源代码(或C或Objective C等)转换为LLVM IR,该代码应该是什么文本的较低级别的代表.为了做到这一点,Clang采用了一些子模块,其描述可以在任何体面的编译器构建书中找到:lexer,parser语义分析器(Sema)等.
LLVM是一组库,其主要任务如下:假设我们具有以下C函数的LLVM IR表示
int double_this_number(int num) {
int result = 0;
result = num;
result = result * 2;
return result;
}
LLVM传递的核心应该是优化LLVM IR代码:
使用优化的LLVM IR代码执行的操作完全取决于您:您可以将其转换为x86_64可执行代码或修改它,然后将其作为ARM可执行代码或GPU可执行代码进行排除.这取决于你的项目的目标.
术语“后端”常常令人困惑,因为有许多论文将LLVM库定义为编译器链中的“中端”,并将“后端”定义为执行代码生成的最终模块(LLVM IR到可执行代码或其他不再需要编译器处理的东西).其他来源指LLVM作为Clang的后端.无论哪种方式,他们的角色都很清楚,它们提供了一个强大的机制:无论您使用哪种语言(C,C,Objective C,Python等),如果您有将前端转换为LLVM IR的前端可以使用同一组LLVM库进行优化,只要您的目标体系结构具有后端,就可以生成优化的可执行代码.
回想起LLVM是一组库(不仅仅是优化通行证,还有data structures,实用程序模块,诊断模块等),Clang还在其前端过程中利用了许多LLVM库.您不能真正将每个LLVM模块从Clang中脱离出来,因为后者基于前者.
至于为什么Clang被认为是一个“编译驱动程序”的原因:Clang管理解释命令行参数(描述和许多声明是TableGen‘d,他们可能需要一点点简单的grep来游泳源)决定要执行哪些作业和阶段,根据所需/可能的优化和转换级别设置CodeGenOptions,并调用相应的模块(BackendUtil.cpp中的clangCodeGen是填充模块传递管理器并使用优化)和工具(例如Windows ld链接器).它从一开始就引导编译过程到最后.
最后,我建议您阅读Clang和LLVM文档,它们是非常明确的,大部分的问题首先应该在那里找到答案.