前文Clang的RISCV支持1介绍了Clang中有关RISCV的代码主要集中在三个地方:Driver部分、Basic部分和CodeGen部分,并且对Basic部分和CodeGen部分的内容和关系进行了介绍,只有Driver部分因为涉及到了ToolChain、Tool和Command(job)等概念体系而未进行深入介绍。
在介绍完ToolChain、Tool和Command(job)等概念和调用关系之后,我们在本文再对Clang的RISCV支持的Driver部分进行深入分析。
一、Driver部分涉及到RISCV是从ToolChain相关操作开始的,这里最早的介入点位于clang/lib/Driver/Driver.cpp中的Compilation *Driver::BuildCompilation(ArrayRef<constchar *> ArgList) 函数,它首先调用了getToolChain函数。位于同个文件下的getToolChain函数之中,逐步拆解了目标的操作系统、环境和目标平台,具体代码如下:
const ToolChain &Driver::getToolChain(const ArgList &Args,
const llvm::Triple &Target) const {
auto &TC = ToolChains[Target.str()];
if (!TC) {
switch (Target.getOS()) {
case llvm::Triple::AIX:
TC = std::make_unique<toolchains::AIX>(*this, Target, Args);
break;
...
case llvm::Triple::Win32:
switch (Target.getEnvironment()) {
default:
if (Target.isOSBinFormatELF())
TC = std::make_unique<toolchains::Generic_ELF>(*this, Target, Args);
else if (Target.isOSBinFormatMachO())
TC = std::make_unique<toolchains::MachO>(*this, Target, Args);
else
TC = std::make_unique<toolchains::Generic_GCC>