(TL;DontWannaRead - skip to the end of this answer)
要正确回答您的问题,您首先需要了解编译器之间的区别前端 http://en.wikipedia.org/wiki/Compiler#Front_end and back-end http://en.wikipedia.org/wiki/Compiler#Back_end(尤其是第一个)。
Clang 是一个编译器前端 (http://en.wikipedia.org/wiki/Clang http://en.wikipedia.org/wiki/Clang) 适用于 C、C++、Objective C 和 Objective C++ 语言。
Clang 的职责如下:
即从 C++ 源代码(或 C、Objective C 等)翻译为LLVM IR http://llvm.org/docs/LangRef.html,该代码应该做什么的文本低级表示。为了做到这一点,Clang 使用了许多子模块,您可以在任何像样的编译器构建书籍中找到这些子模块的描述:词法分析器、解析器 + 语义分析器 (Sema) 等。
LLVM http://en.wikipedia.org/wiki/LLVM是一组库,其主要任务如下:假设我们有以下 C++ 函数的 LLVM IR 表示
int double_this_number(int num) {
int result = 0;
result = num;
result = result * 2;
return result;
}
LLVM 传递的核心应该optimizeLLVM 红外代码:
如何处理优化的 LLVM IR 代码完全取决于您:您可以将其转换为 x86_64 可执行代码或对其进行修改,然后将其吐出为 ARM 可执行代码或 GPU 可执行代码。这取决于您的项目的目标。
“后端”一词经常令人困惑,因为有许多论文将 LLVM 库定义为编译器链中的“中间端”,并将“后端”定义为执行代码生成的最终模块(LLVM IR 到可执行代码或其他不再需要编译器处理的代码)。其他来源将 LLVM 称为 Clang 的后端。无论哪种方式,它们的角色都很明确,并且提供了强大的机制:无论您的目标语言是什么(C++、C、Objective C、Python 等),如果您有一个将其转换为 LLVM IR 的前端,您就可以将其转换为 LLVM IR。可以使用同一组 LLVM 库来对其进行优化,并且只要您有适合您的目标架构的后端,就可以生成优化的可执行代码。
回想一下 LLVM 是一组库(不仅是优化过程,还包括数据结构 http://llvm.org/docs/ProgrammersManual.html#picking-the-right-data-structure-for-a-task、实用模块、诊断模块等),Clang 还利用manyLLVM 库在其前端过程。你真的无法撕裂everyLLVM 模块远离 Clang,因为后者是建立在前一组之上的。
至于为什么 Clang 被称为“编译驱动程序”:Clang 管理解释命令行参数(描述和许多声明是TableGen http://llvm.org/docs/TableGen/d 并且他们可能需要的不仅仅是一个简单的 grep 来浏览源代码),决定哪个Jobs
和要执行的阶段,设置CodeGenOptions
根据所需/可能的优化和转换级别并调用适当的模块(clangCodeGen
in BackendUtil.cpp
是用要应用的优化填充模块传递管理器的工具)和工具(例如 Windowsld
链接器)。它从头到尾引导编译过程。
最后,我建议阅读 Clang 和 LLVM 文档,它们非常具有解释性,您的大多数问题应该首先在那里寻找答案。