变量名方案¶
此计划是临时的。尚未达成一致。编写它的目的是为了捕捉 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可以忽略或“穿透”给定的提交集。可以向 LLVM git 仓库根目录添加一个.git-blame-ignore-revs
文件,以标识变量重命名提交。正在调查是否可以将类似的功能添加到git blame
本身。
最大限度地减少下游合并的成本¶
LLVM 有许多带有下游更改的分支。合并大规模重命名更改对于分支维护者来说可能很困难。
缓解措施:大规模重命名将是自动化的。分支维护者可以从重命名前的提交立即合并,然后将重命名脚本应用于他们自己的分支。然后他们可以再次从重命名提交合并,通过选择他们自己的版本来解决所有冲突。这可以在[SVE]分支上进行测试。
临时计划¶
这是大爆炸方法的临时计划。尚未达成一致。
研究改进
git blame
。它可以“穿透”提交的程度可能会影响可以进行的更改有多大。编写一个脚本来展开首字母缩略词。
实验并执行各种重构选项的试运行。结果可以在 LLVM Git 仓库的分支中发布。
考虑证据并就新政策达成一致。
同意并宣布入门项目 (LLD) 重命名的日期。
更新策略页面。这将解释新旧规则以及每种规则适用于哪些项目。
在两次提交中重构入门项目
添加或更改项目的 .clang-tidy 以反映商定的规则。(这在单独的提交中,以启用最大限度地减少下游合并的成本中描述的合并过程)。还在策略页面上更新项目列表。
将
clang-tidy
应用于项目的文件,仅启用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
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
Kristof Beyls, http://lists.llvm.org/pipermail/llvm-dev/2019-February/130292.html
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
Bruno Ricci, http://lists.llvm.org/pipermail/llvm-dev/2019-February/130328.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
Zachary Turner, http://lists.llvm.org/pipermail/llvm-dev/2019-February/130213.html