关键词:
前文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>(*this, Target, Args);
break;
case llvm::Triple::GNU:
TC = std::make_unique<toolchains::MinGW>(*this, Target, Args);
break;
...
break;
...
default:
// Of these targets, Hexagon is the only one that might have
// an OS of Linux, in which case it got handled above already.
switch (Target.getArch())
case llvm::Triple::tce:
TC = std::make_unique<toolchains::TCEToolChain>(*this, Target, Args);
break;
...
case llvm::Triple::riscv32:
case llvm::Triple::riscv64:
TC = std::make_unique<toolchains::RISCVToolChain>(*this, Target, Args);
break;
default:
...
// Intentionally omitted from the switch above: llvm::Triple::CUDA. CUDA
// compiles always need two toolchains, the CUDA toolchain and the host
// toolchain. So the only valid way to create a CUDA toolchain is via
// CreateOffloadingDeviceToolChains.
return *TC;
这里最早出现了有关RISCV的内容,构建所需要的ToolChain:
case llvm::Triple::riscv32:
case llvm::Triple::riscv64:
TC = std::make_unique<toolchains::RISCVToolChain>(*this, Target, Args);
break;
二、上文RISCVToolChain的定义和实现,以及为其所用的RISCV相关的Tool,均位于下列两个文件里:
clang/lib/Driver/ToolChains/RISCVToolchain.h
clang/lib/Driver/ToolChains/RISCVToolchain.cpp
下面进行分类讨论:
1、ToolChain方面:定义了RISCVToolChain,它继承于Generic_ELF,Generic_ELF继承于Generic_GCC,Generic_GCC继承于ToolChain。在源码上的体现:
clang/lib/Driver/ToolChains/RISCVToolchain.h
class LLVM_LIBRARY_VISIBILITY RISCVToolChain : public Generic_ELF
clang/lib/Driver/ToolChains/Gnu.h
namespace toolchains
/// Generic_GCC - A tool chain using the 'gcc' command to perform
/// all subcommands; this relies on gcc translating the majority of
/// command line options.
class LLVM_LIBRARY_VISIBILITY Generic_GCC : public ToolChain
class LLVM_LIBRARY_VISIBILITY Generic_ELF : public Generic_GCC
2、Tool方面:定义了RISCV::Linker,它继承于GnuTool ,GnuTool 继承于Tool。源码上的体现:
clang/lib/Driver/ToolChains/RISCVToolchain.h
namespace tools
namespace RISCV
class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool
clang/lib/Driver/ToolChains/Gnu.h
namespace tools
/// Base class for all GNU tools that provide the same behavior when
/// it comes to response files support
class LLVM_LIBRARY_VISIBILITY GnuTool : public Tool
三、Driver部分,还有两个相关文件RISCV.h和RISCV.cpp,他们的完整路径为:
clang/lib/Driver/ToolChains/Arch/RISCV.h
clang/lib/Driver/ToolChains/Arch/RISCV.cpp
这两个文件主要提供了获取ABI、Arch和RISCV目标特征的接口,具体代码表示如下:
clang/lib/Driver/ToolChains/Arch/RISCV.h
namespace clang
namespace driver
namespace tools
namespace riscv
void getRISCVTargetFeatures(const Driver &D, const llvm::Triple &Triple,
const llvm::opt::ArgList &Args,
std::vector<llvm::StringRef> &Features);
StringRef getRISCVABI(const llvm::opt::ArgList &Args,
const llvm::Triple &Triple);
StringRef getRISCVArch(const llvm::opt::ArgList &Args,
const llvm::Triple &Triple);
// end namespace riscv
// namespace tools
// end namespace driver
// end namespace clang
其中,在实现层面,getRISCVTargetFeatures还会调用getRISCVArch,并且调用getArchFeatures获取Arch特征。getArchFeatures则通过getExtensionVersion获取扩展版本号,然后通过getExtensionFeatures获取扩展特征。所以,具体的扩展版本号、以及扩展特征要进行改动的话,都是在clang/lib/Driver/ToolChains/Arch/RISCV.cpp这个文件里更新。
这里的信息与Basic部分信息不同,Basic部分主要是生成代码所需要的基本信息,而这里则是详细的扩展版本、扩展特征检查和校验。后续会对这里getRISCVABI、getRISCVArch和getRISCVTargetFeatures的被调用关系进行分析。
1、上面所提到的getRISCVABI函数,被调用的地方主要有:
1)Clang、ClangAs这两个Tool子类的AddRISCVTargetArgs函数;(clang/lib/Driver/ToolChains/Clang.h、clang/lib/Driver/ToolChains/Clang.cpp)
2)Assembler这个tool的tools::gnutools::Assembler::ConstructJob函数;
(clang/lib/Driver/ToolChains/Gnu.h、clang/lib/Driver/ToolChains/Gnu.cpp)
3)Generic_GCC::GCCInstallationDetector::ScanGCCForMultilibs函数所调用的findRISCVMultilibs函数之中,以及findRISCVMultilibs函数所调用的findRISCVBareMetalMultilibs函数之中;
(clang/lib/Driver/ToolChains/Gnu.h、clang/lib/Driver/ToolChains/Gnu.cpp)
4)Linux这个toolchain的构造函数,以及它的std::string Linux::getDynamicLinker函数之中。
(clang/lib/Driver/ToolChains/Linux.h、clang/lib/Driver/ToolChains/Linux.cpp)
2、上面所提到的getRISCVArch,被调用的地方在:
1) Assembler这个tool的tools::gnutools::Assembler::ConstructJob函数;
(clang/lib/Driver/ToolChains/Gnu.h、clang/lib/Driver/ToolChains/Gnu.cpp)
2)Generic_GCC::GCCInstallationDetector::ScanGCCForMultilibs函数所调用的findRISCVMultilibs函数所调用的findRISCVBareMetalMultilibs函数之中;
(clang/lib/Driver/ToolChains/Gnu.h、clang/lib/Driver/ToolChains/Gnu.cpp)
3、上面所提到的getRISCVTargetFeatures,被调用的地方在getTargetFeatures函数之中,这个函数主要被Clang这个tool的Clang::RenderTargetOptions函数和Clang::ConstructJob函数、ClangAs这个tool的ClangAs::ConstructJob函数所调用。(clang/lib/Driver/ToolChains/Clang.cpp)
可以看到,这三个函数主要的应用场景还是给Tool的一些子类进行调用。
深入研究clang(十五)clang的riscv支持1(代码片段)
一、Clang/LLVM对RISCV的支持概况目前已经有一系列的C类编译器和库开始支持RISCV,这其中包括了GCC和Clang/LLVM。从RISCV的官方网站,可以获取目前的支持状态。具体内容如下:网址:https://riscv.org/software-status/#c-compilers... 查看详情
深入研究clang(十三)clang-tidy简介
最近几天在关注clang-tidy,有一些体会,简单做一些笔记。分享给感兴趣的朋友们,也是给将来的自己看。1、clang-tidy是基于AST的静态检查工具。因为它基于AST,所以要比基于正则表达式的静态检查工具更为精准,但... 查看详情
深入研究clang(十六)clangdriver库的toolchain(代码片段)
ToolChain是Clang的Driver库里的一个类,它是用来获取具体某个平台的工具集合,代码注释中的原文是:ToolChain-Accesstotoolsforasingleplatform.(clang/include/clang/Driver/ToolChain.h)这里涉及到的Tool也是Clang的Driver库里 查看详情
深入研究clang(十七)clangdriver库的tool(代码片段)
Tool也是Clang的Driver库里的一个类,它是具体编译工具的信息,代码注释中的原文是:Tool-Informationonaspecificcompilationtool.(clang/include/clang/Driver/Tool.h)本文将对Tool的实现以及其相关调用关系做一个简单的分析。一、Tool... 查看详情
深入研究clang(十八)clangdriver库的job(代码片段)
Clang的Tool最终会调用ConstructJob来为Compilation添加job。根据源码中的注释,Tool中保存的是一个特定编译工具的信息(Tool-Informationonaspecificcompilationtool.,clang/include/clang/Driver/Tool.h)。而job则是通过Command类去进行具体实现... 查看详情
深入研究clang(十八)clangdriver库的job(代码片段)
Clang的Tool最终会调用ConstructJob来为Compilation添加job。根据源码中的注释,Tool中保存的是一个特定编译工具的信息(Tool-Informationonaspecificcompilationtool.,clang/include/clang/Driver/Tool.h)。而job则是通过Command类去进行具体实现... 查看详情
深入研究clang(十六)clangdriver库的toolchain(代码片段)
ToolChain是Clang的Driver库里的一个类,它是用来获取具体某个平台的工具集合,代码注释中的原文是:ToolChain-Accesstotoolsforasingleplatform.(clang/include/clang/Driver/ToolChain.h)这里涉及到的Tool也是Clang的Driver库里的一个... 查看详情
深入研究clang(十七)clangdriver库的tool(代码片段)
Tool也是Clang的Driver库里的一个类,它是具体编译工具的信息,代码注释中的原文是:Tool-Informationonaspecificcompilationtool.(clang/include/clang/Driver/Tool.h)本文将对Tool的实现以及其相关调用关系做一个简单的分析。一、Tool... 查看详情
block深入浅出
研究工具clang 为了研究编译器的实现原理,我们需要使用clang命令。clang命令可以将Objetive-C的源码改写成C/C++语言的,借此可以研究block中各个特性的源码实现方式。clang -rewrite-objcmain.mmain.m中不能包含UIKit框架,命令行中... 查看详情
clang和llvm-发布与调试版本(代码片段)
...对较小比例的用户-大多数人都希望使用Clang+LLVM,而不是深入研究优化编译器设计的复杂性。我打算只使用Clang代替GCC来利用我所听到的更好的错误信息,但我需要调试它在GDB下生成的程序。Clang的发布版本是否足够?(请注意,... 查看详情
llvm/clang编译相关研究
https://blog.csdn.net/guojin08/article/details/54310858https://juejin.im/entry/5c64da44518825620b450918https://www.jianshu.com/p/269d68d25df4https://blog.csdn.net/Deft_MKJing/article/details/84943381https://www.itcodemonkey.com/article/7459.htmlhttps://www.jianshu.com/p/377ed3f0138e 查看详情
se是啥编译器
...其先前专有编译器的开发。考虑到所有这些,我们决定更深入地研究Clang,以使用它创建我们自己的编译器为目标。_EGGER将所有内容打包到一个易于下载的“软件包”中,完全集成并且可以立即使用。Clang和GCC都有非常先进的前... 查看详情
clang消除警告
clang命令,它的作用是用来消除特定区域的clang的编译警告,-Wgnu则是消除?:警告,例:#pragmaclangdiagnosticpush#pragmaclangdiagnosticignored"-Wgnu"//消除警告代码#pragmaclangdiagnosticpop 下边的链接是clang的警告信息列表WhichClangWarningIsGeneratingT... 查看详情
pleaseinstall[clang](http://clang.llvm.org/)orcheckconfiguration`clang.executable`
解决方法: 1.安装clang 第一步:首先打开VScode编辑器 第二步:点击左侧“应用商店”栏 第三步:在“应用商店搜索拓展”栏输入关键字“clang” 第四步:安装提示的“C/c++clangcommand”插... 查看详情
Clang 格式中断 #include 双引号
】Clang格式中断#include双引号【英文标题】:Clang-formatbreaks#includedoublequotes【发布时间】:2014-07-0512:34:27【问题描述】:我是Clang格式的新手。我使用./bin/clang-format-style=google-dump-config>.clang-format作为我的基本.clang-format。在此基础... 查看详情
如何在每个工作区中配置没有 .clang-format 文件的 clang 格式?
】如何在每个工作区中配置没有.clang-format文件的clang格式?【英文标题】:Howcaniconfigureclangformatwithout.clang-formatfileineveryworkspace?【发布时间】:2017-03-1518:38:21【问题描述】:我想配置clang-format而不必将我的.clang-format文件复制到每... 查看详情
clang:错误:没有这样的文件或目录:'dynamic_lookup' clang:错误:没有这样的文件或目录:'suppress'
】clang:错误:没有这样的文件或目录:\\\'dynamic_lookup\\\'clang:错误:没有这样的文件或目录:\\\'suppress\\\'【英文标题】:clang:error:nosuchfileordirectory:\'dynamic_lookup\'clang:error:nosuchfileordirectory:\'suppress\'clang:错误:没有这样的文件... 查看详情
如何在mac中更改clang的std标志?当前的 clang 版本 10.0.1 使用 c++98 标志
】如何在mac中更改clang的std标志?当前的clang版本10.0.1使用c++98标志【英文标题】:howtochangestdflagofclanginmac?currentclangversion10.0.1isusingc++98flag【发布时间】:2020-11-2105:01:22【问题描述】:虽然clang的文档说版本10.0.1使用c++11,但我正... 查看详情