变量命名方案¶
此方案为临时方案。尚未达成一致。编写此方案的目的是捕捉 LLVM 社区的愿望和顾虑,并将它们形成一个可以达成一致的方案。最初的作者对 LLVM 的运作方式有些生疏,因此不可避免地会有一些细节存在缺陷。您可以提供帮助 - 您可以编辑此页面(对于较大的更改,最好使用 Phabricator 进行审查)或回复征求意见邮件线程。
太长不看¶
提高 LLVM 代码的可读性。
简介¶
当前的变量命名规则规定
变量名应为名词(因为它们表示状态)。名称应使用驼峰命名法,并以大写字母开头(例如 Leader 或 Boats)。
此规则与类型名相同。这是一个问题,因为类型名不能重复用作变量名[*]。LLVM 开发人员倾向于通过以下两种方式解决此问题:在类型名前添加The
Triple TheTriple;
…或者更常见的是使用缩略词,尽管编码标准规定“除非是众所周知的缩略词,否则避免使用缩略词”
Triple T;
缩略词的泛滥导致代码难以阅读,例如此处
InnerLoopVectorizer LB(L, PSE, LI, DT, TLI, TTI, AC, ORE, VF.Width, IC,
&LVL, &CM);
许多其他编码指南[LLDB] [Google] [WebKit] [Qt] [Rust] [Swift] [Python] 要求变量名以小写字母开头,而类名则以大写字母开头。此约定意味着最易读的变量名也需要最少的思考
Triple triple;
有些人一致认为当前规则存在问题[LattnerAgree] [ArsenaultAgree] [RobinsonAgree],并且缩略词是阅读新代码的障碍[MalyutinDistinguish] [CarruthAcronym] [PicusAcronym]。也有一些相反的观点[ParzyszekAcronym2] [RicciAcronyms]。
此正在进行中的提案是为了更改变量名的编码标准,要求它们以小写字母开头。
变量命名编码标准选项¶
对于以小写字母开头的变量名,主要有两个选项:camelBack
和 lower_case
。(这些也以其他名称而闻名,但这里我们使用 clang-tidy 中的术语)。
camelBack
与[WebKit]、[Qt] 和[Swift] 一致,而 lower_case
与[LLDB]、[Google]、[Rust] 和[Python] 一致。
camelBack
已经用于函数名,这可能被认为是一个优势[LattnerFunction] 或一个劣势[CarruthFunction]。
对 camelBack
的批准由[DenisovCamelBack] [LattnerFunction] [IvanovicDistinguish] 表达。对 camelBack
的反对由[CarruthCamelBack] [TurnerCamelBack] 表达。对 lower_case
的批准由[CarruthLower] [CarruthCamelBack] [TurnerLLDB] 表达。对 lower_case
的反对由[LattnerLower] 表达。
区分变量类型¶
另一个请求的更改是区分不同类型的变量[RobinsonDistinguish] [RobinsonDistinguish2] [JonesDistinguish] [IvanovicDistinguish] [CarruthDistinguish] [MalyutinDistinguish]。
其他人反对这个想法[HähnleDistinguish] [GreeneDistinguish] [HendersonPrefix]。
一种可能性是为成员变量添加 m_
前缀,为全局变量添加 g_
前缀,以将它们与局部变量区分开来。这与[LLDB] 一致。m_
前缀与[WebKit] 一致。
另一种变体是为成员变量添加 m
前缀[IvanovicDistinguish] [BeylsDistinguish]。这与[Mozilla] 一致。
另一个选项是为成员变量添加 _
后缀,这与[Google] 一致,并且类似于[Python]。遭到[ParzyszekDistinguish] 反对。
减少缩略词的数量¶
虽然切换编码标准将使新代码更容易使用非缩略词名称,但它并不能改善现有的广泛使用缩略词的代码库,从而损害其可读性。此外,新代码自然且通常鼓励以周围代码的风格编写。因此,尽管编码标准怎么说,许多新编写的代码也可能使用缩略词,就像今天一样。
除了更改变量名的大小写之外,还可以将它们扩展为非缩略词形式,例如 Triple T
→ Triple triple
。
有些人支持扩展许多缩略词[CarruthAcronym] [PicusAcronym],但也有人更倾向于延迟扩展缩略词[ParzyszekAcronym] [CarruthAcronym]。
社区内部的共识似乎是,至少某些缩略词是有价值的[ParzyszekAcronym] [LattnerAcronym]。最常引用的缩略词是 TLI
,但它同时用于指代 TargetLowering
和 TargetLibraryInfo
[GreeneDistinguish]。
以下是被认为足够有用,以至于使用它们的益处大于学习它们的成本的缩略词列表。不在列表中或用于指代不同类型的缩略词应予以扩展。
类名 |
变量名 |
---|---|
DeterministicFiniteAutomaton |
dfa |
DominatorTree |
dt |
LoopInfo |
li |
MachineFunction |
mf |
MachineInstr |
mi |
MachineRegisterInfo |
mri |
ScalarEvolution |
se |
TargetInstrInfo |
tii |
TargetLibraryInfo |
tli |
TargetRegisterInfo |
tri |
在某些情况下,将缩略词重命名为完整类型名称会导致代码过于冗长。与大多数类不同,变量的作用域是有限的,因此它的一些目的可以从该作用域中推断出来,这意味着不需要太多单词即可为其提供清晰的名称。例如,在优化过程中,读者可以假设变量的目的与优化有关,因此 OptimizationRemarkEmitter
变量可以命名为 remarkEmitter
甚至 remarker
。
以下是较长的类名与其对应的较短变量名的列表。
类名 |
变量名 |
---|---|
BasicBlock |
block |
ConstantExpr |
expr |
ExecutionEngine |
engine |
MachineOperand |
operand |
OptimizationRemarkEmitter |
remarker |
PreservedAnalyses |
analyses |
PreservedAnalysesChecker |
checker |
TargetLowering |
lowering |
TargetMachine |
machine |
转换选项¶
有三种主要的转换选项
保留当前编码标准
自由放任
大爆炸式迁移
保留当前的编码规范¶
保留当前编码规范的支持者(即根本不进行转换)质疑转换的成本是否超过了收益 [EmersonConcern] [ReamesConcern] [BradburyConcern]。成本在于 git blame
将变得不太可用;并且合并更改对于下游维护者来说成本很高。有关潜在的缓解措施,请参阅 大爆炸。
自由放任¶
编码规范可以允许 CamelCase
和 camelBack
两种样式的变量名 [LattnerTransition]。
实施此项的代码审查位于 https://reviews.llvm.org/D57896。
优点¶
最初实施起来非常容易。
缺点¶
不一致意味着很难猜测变量的名称 [DasInconsistent] [CarruthInconsistent]。
无论如何,可能会发生一些大规模重命名,从而导致其缺点而没有任何缓解措施。
大爆炸¶
使用这种方法,变量将通过一系列大型提交中的自动化脚本进行重命名。
这种方法的主要优点是它最大程度地降低了不一致的成本 [BradburyTransition] [RobinsonTransition]。
它违反了避免对现有代码进行大规模重新格式化的策略 [GreeneDistinguish]。
有人建议 LLD 将成为重命名的良好入门项目 [Ueyama]。
保持 git blame 可用¶
git blame
(或 git annotate
)允许快速识别更改文件中给定行的提交。在重命名变量后,许多行将显示为由该提交更改,需要进一步调用 git blame
来识别之前更有趣的提交 [GreeneGitBlame] [RicciAcronyms]。
缓解措施:git-hyper-blame 可以忽略或“查看”给定的提交集。可以将一个 .git-blame-ignore-revs
文件添加到 LLVM git 存储库的根目录中,该文件标识变量重命名提交。正在调查是否可以向 git blame
本身添加类似的功能。
最大程度地降低下游合并的成本¶
LLVM 有许多带有下游更改的分支。合并大规模重命名更改对于分支维护者来说可能很困难。
缓解措施:大规模重命名将是自动化的。分支维护者可以从重命名之前的提交合并,然后将重命名脚本应用到他们自己的分支。然后,他们可以再次从重命名提交合并,通过选择他们自己的版本来解决所有冲突。这可以在 [SVE] 分支上进行测试。
临时计划¶
这是 大爆炸 方法的临时计划。尚未达成一致。
调查改进
git blame
。它可以“查看”提交的程度可能会影响可以进行多大更改。编写一个脚本以扩展首字母缩略词。
试验并执行各种重构选项的预运行。结果可以在 LLVM Git 存储库的分支中发布。
考虑证据并就新策略达成一致。
商定并宣布入门项目 (LLD) 重命名的日期。
更新 策略页面。这将解释旧规则和新规则,以及每个规则适用于哪些项目。
在两个提交中重构入门项目
添加或更改项目的 .clang-tidy 以反映商定的规则。(这在单独的提交中,以启用 最大程度地降低下游合并的成本 中描述的合并过程)。还在策略页面上更新项目列表。
将
clang-tidy
应用于项目的files,仅启用readability-identifier-naming
规则。clang-tidy
还会根据.clang-format
中的规则重新格式化受影响的行。预计这将是 clang-tidy 的一个很好的试用机会,并且在此过程中应修复错误,可能包括
收集反馈并根据需要改进流程。
将此流程应用于以下项目,并在每个项目之间设置适当的延迟(至少在第一次更改后 4 周,之后至少 2 周),以便收集更多反馈。此列表应排除必须遵守外部定义标准(例如 libcxx)的项目。此列表大致按重命名的顺序排列。某些项目可能没有意义单独重命名 - 预计此列表将在试验后发生变化
TableGen
llvm/tools
clang-tools-extra
clang
ARM 后端
AArch64 后端
AMDGPU 后端
ARC 后端
AVR 后端
BPF 后端
Hexagon 后端
Lanai 后端
MIPS 后端
NVPTX 后端
PowerPC 后端
RISC-V 后端
Sparc 后端
SystemZ 后端
WebAssembly 后端
X86 后端
XCore 后端
libLTO
调试信息
llvm 的其余部分
compiler-rt
libunwind
openmp
parallel-libs
polly
lldb
从策略页面中删除旧的变量名规则。
重复序列中的许多步骤,使用脚本扩展首字母缩略词。
参考文献¶
LLDB 编码约定 https://llvm.net.cn/svn/llvm-project/lldb/branches/release_39/www/lldb-coding-conventions.html
Swift API 设计指南 https://swift.org/documentation/api-design-guidelines/#general-conventions
Python 代码风格指南 https://www.pythonlang.cn/dev/peps/pep-0008/#function-and-variable-names
Mozilla 编码风格:前缀 https://firefox-source-docs.mozilla.ac.cn/tools/lint/coding-style/coding_style_cpp.html#prefixes
支持 SVE 的 LLVM https://github.com/ARM-software/LLVM-SVE
Alex Bradbury,http://lists.llvm.org/pipermail/llvm-dev/2019-February/130266.html
Alex Bradbury,http://lists.llvm.org/pipermail/llvm-dev/2019-February/130388.html
Chandler Carruth,http://lists.llvm.org/pipermail/llvm-dev/2019-February/130313.html
Chandler Carruth,http://lists.llvm.org/pipermail/llvm-dev/2019-February/130214.html
Chandler Carruth,http://lists.llvm.org/pipermail/llvm-dev/2019-February/130310.html
Chandler Carruth,http://lists.llvm.org/pipermail/llvm-dev/2019-February/130309.html
Chandler Carruth,http://lists.llvm.org/pipermail/llvm-dev/2019-February/130312.html
Chandler Carruth,http://lists.llvm.org/pipermail/llvm-dev/2019-February/130430.html
Alex Denisov,http://lists.llvm.org/pipermail/llvm-dev/2019-February/130179.html
David Greene,http://lists.llvm.org/pipermail/llvm-dev/2019-February/130425.html
James Henderson,http://lists.llvm.org/pipermail/llvm-dev/2019-February/130465.html
Nicolai Hähnle,http://lists.llvm.org/pipermail/llvm-dev/2019-February/129923.html
Nemanja Ivanovic,http://lists.llvm.org/pipermail/llvm-dev/2019-February/130249.html
Chris Lattner,http://lists.llvm.org/pipermail/llvm-dev/2019-February/130630.html
Chris Lattner,http://lists.llvm.org/pipermail/llvm-dev/2019-February/130355.html
Danila Malyutin,http://lists.llvm.org/pipermail/llvm-dev/2019-February/130320.html
Krzysztof Parzyszek,http://lists.llvm.org/pipermail/llvm-dev/2019-February/130306.html
Krzysztof Parzyszek,http://lists.llvm.org/pipermail/llvm-dev/2019-February/130323.html
Krzysztof Parzyszek,http://lists.llvm.org/pipermail/llvm-dev/2019-February/129941.html
Paul Robinson,http://lists.llvm.org/pipermail/llvm-dev/2019-February/129920.html
Paul Robinson,http://lists.llvm.org/pipermail/llvm-dev/2019-February/130229.html
Paul Robinson,http://lists.llvm.org/pipermail/llvm-dev/2019-February/130415.html
Zachary Turner,https://reviews.llvm.org/D57896#1402264