變數名稱計畫¶
本計畫為「臨時」性質。尚未達成共識。撰寫本計畫的目的是為了收集 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
套用至專案檔案,僅啟用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.dev.org.tw/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.python.org/dev/peps/pep-0008/#function-and-variable-names
Mozilla 編碼風格:前綴 https://firefox-source-docs.mozilla.org/tools/lint/coding-style/coding_style_cpp.html#prefixes
支援 SVE 的 LLVM https://github.com/ARM-software/LLVM-SVE
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
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
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