在 Clang 上进行开发
本文档为刚接触 Clang 和/或 LLVM 代码库的开发者提供了一些在 Clang 上进行开发的入门提示。
编码规范
Clang 遵循 LLVM 编码规范。提交补丁时,请务必遵守这些规范,并使代码风格与 Clang 中的代码风格保持一致(例如,在缩进、大括号和语句间距方面)。
Clang 有一些额外的编码规范
- cstdio 被禁止:库代码不应使用cstdio输出诊断或其他信息;调试例程应使用llvm::errs()。其他使用cstdio会对客户端强加行为,并阻止将 Clang 集成为库。库应支持raw_ostream基于的接口用于文本输出。请参阅 编码规范。
开发者文档
Clang 和 LLVM 都使用 doxygen 来提供 API 文档。它们各自的网页(每晚生成)在这里
对于 LLVM IR 生成方面的工作,LLVM 汇编语言 参考手册 也很有用。
调试
在调试器中检查数据结构
- 许多 LLVM 和 Clang 数据结构提供一个dump()方法,该方法将打印数据结构的描述到stderr.
- 结构被广泛使用。这是一个简单的值类,用于用限定符包装类型;您可以使用isConstQualified()例如,获取其中一个限定符,以及getTypePtr()方法获取包装的Type*,然后您可以将其转储。
- 对于 LLDB 用户,在 clang/utils/ClangDataFormat.py 中为 clang 数据结构提供了数据格式化程序。
使用 Visual Studio 进行调试
文件 llvm/utils/LLVMVisualizers/llvm.natvis 和 clang/utils/ClangVisualizers/clang.natvis 提供调试可视化器,使更复杂的数据类型的调试变得更加容易。
根据您配置项目的方式,Visual Studio 可能会在调试时自动使用这些可视化器,或者您可能需要将这些文件放入%USERPROFILE%\Documents\Visual Studio <version>\Visualizers或创建一个符号链接,以便它们自动更新。有关 NATVIS 使用的更多详细信息,请参阅 Microsoft 的文档。
测试
在类 Unix 系统上进行测试
Clang 在树中包含一个基本的回归测试套件,可以使用以下命令运行make test从顶层 clang 目录运行,或者只运行make在 test 子目录中。make VERBOSE=1可用于显示有关正在运行的内容的更多详细信息。
如果您使用 CMake 构建了 LLVM 和 Clang,则可以使用以下命令运行测试套件make check-clang从顶层 LLVM 目录运行。
测试主要由一个测试运行器脚本组成,该脚本在测试目录下子目录中分组的各个测试文件上运行要测试的编译器。各个测试文件开头包含注释,指示要使用的 Clang 编译选项,供测试运行器读取。嵌入式注释还可以执行一些操作,例如告诉测试运行器当前行预期会发生错误。测试产生的任何输出文件都将放置在创建的 Output 目录下。
在运行make test期间,终端输出将显示类似于以下内容的行
--- Running clang tests for i686-pc-linux-gnu ---
,然后是不断被当前正在编译的测试文件覆盖的行,以及总的完成百分比。
在make test运行完成后,如果没有Failing Tests (count)消息,表示没有测试意外失败。如果任何测试失败,该Failing Tests (count)消息将后跟一个失败的测试源文件路径列表。例如
Failing Tests (3): /home/john/llvm/tools/clang/test/SemaCXX/member-name-lookup.cpp /home/john/llvm/tools/clang/test/SemaCXX/namespace-alias.cpp /home/john/llvm/tools/clang/test/SemaCXX/using-directive.cpp
如果您使用了make VERBOSE=1选项,终端输出将反映编译器和测试运行器的错误消息。
回归测试套件也可以使用 Valgrind 运行,方法是在顶层 clang 目录中运行make test VG=1。
对于更密集的更改,建议运行使用 clang 的 LLVM 测试套件。目前,覆盖 LLVMGCC 的最佳方法是,例如make LLVMGCC="clang -std=gnu89" TEST=nightly report(确保clang在您的 PATH 中,或者使用完整路径)。
使用 Visual Studio 在 Windows 上进行测试
Clang 测试套件可以从 Visual Studio 或命令行运行。
请注意,测试运行器基于 Python,必须安装 Python。可以在以下位置找到 Python:https://www.pythonlang.cn/downloads/。下载最新的稳定版本。
运行测试还需要 GnuWin32 工具。可以在以下位置获取这些工具: http://getgnuwin32.sourceforge.net/。如果环境变量%PATH%中没有 GnuWin32,或者如果其他 grep(s) 在%PATH%中优先于 GnuWin32,则应显式地将LLVM_LIT_TOOLS_DIR指定给 CMake。
cmake 构建工具被设置为创建用于运行测试的 Visual Studio 项目文件,“check-clang” 是根节点。因此,要从 Visual Studio 运行测试,请右键单击 check-clang 项目,然后选择“生成”。
另请参阅 使用 Microsoft Visual Studio 入门 LLVM 系统 和 使用 CMake 构建 LLVM。
在命令行上进行测试
如果您希望更深入地控制测试的运行方式,直接在命令行上运行测试运行器可能很方便。在从命令行运行测试之前,您需要确保lit.site.cfg文件已为您的构建创建。您可以通过按前几节所述运行测试来完成此操作。测试开始运行后,您可以使用 Control+C 停止它们,因为文件是在运行任何测试之前生成的。
完成此操作后,要从命令行运行所有测试,请执行以下类似的命令
python (path to llvm)\llvm\utils\lit\lit.py -sv --param=build_mode=Win32 --param=build_config=Debug --param=clang_site_config=(build dir)\tools\clang\test\lit.site.cfg (path to llvm)\llvm\tools\clang\test
对于 CMake 构建,例如在使用 Visual Studio 的 Windows 上,您需要通过--param=build_config=(build config)指定您的构建配置(调试、发布等)。您可能还需要通过--param=build_mode=(build mode).
指定构建模式(Win32 等)。此外,您需要指定位于 (build dir)\tools\clang\test 中的 lit 站点配置,方法是--param=clang_site_config=(build dir)\tools\clang\test\lit.site.cfg.
要运行单个测试
python (path to llvm)\llvm\utils\lit\lit.py -sv --param=build_mode=Win32 --param=build_config=Debug --param=clang_site_config=(build dir)\tools\clang\test\lit.site.cfg (path to llvm)\llvm\tools\clang\test\(dir)\(test)
例如
python C:\Tools\llvm\utils\lit\lit.py -sv --param=build_mode=Win32 --param=build_config=Debug --param=clang_site_config=C:\Tools\build\tools\clang\test\lit.site.cfg C:\Tools\llvm\tools\clang\test\Sema\wchar.c
上面的 -sv 选项告诉运行器在任何测试失败时显示测试输出,以帮助您确定失败的原因。
您还可以传递 --no-progress-bar 选项,如果您希望在测试运行时禁用进度指示。
您的输出可能类似于以下内容
lit.py: lit.cfg:152: note: using clang: 'C:\Tools\llvm\bin\Release\clang.EXE' -- Testing: Testing: 2534 tests, 4 threads -- Testing: 0 .. 10.. 20.. 30.. 40.. 50.. 60.. 70.. 80.. 90.. Testing Time: 81.52s Passed : 2503 Expectedly Failed: 28 Unsupported : 3
统计数据“Failed”(如果所有测试都通过则不会显示)是最重要的一个。
测试影响 libc++ 的更改
Clang 中的一些更改会影响 libc++,例如
- 更改 Clang 诊断的输出。
- 更改编译器内建函数,特别是用于类型特征或替换库函数(如std::move或std::forward.
的内建函数。
调整 libc++ 以适应更改后,下一个版本将通过 libc++ 的 预提交 CI 进行测试。
对于大多数配置,预提交 CI 使用来自 LLVM 主分支的 Clang 的 最新 nightly 构建。这些配置不使用补丁中的 Clang 更改。它们只使用 libc++ 更改。
“引导构建”构建 Clang 并使用它来构建和测试 libc++。此构建确实使用了补丁中的 Clang 更改。
Libc++ 支持多个版本的 Clang。因此,当补丁更改诊断时,可能需要在“预期”测试中使用正则表达式,以使其通过 CI。Libc++ 有更多关于预提交 CI 的 文档。关于 libc++ 的问题,最适合询问的地方是#libcxx
创建补丁文件
频道,位于 LLVM 的 Discord 服务器 上。
LLVM IR 生成
要为 Clang 贡献更改,请参阅 LLVM 的入门页面clang 的 LLVM IR 生成部分负责将 Sema 模块输出的 AST 节点转换为 LLVM 中间表示(IR)。历史上,这被称为“代码生成”,Clang 的代码位于.
lib/CodeGen中。最容易检查输出的方法是使用-emit-llvm选项传递给 clang(可能与-o -一起使用)。您还可以使用-emit-llvm-bc, 来写入 LLVM 位码文件,该文件可以由 LLVM 工具套件(如llvm-dis