LLVM-Clang 學(xué)習(xí)筆記

1.先來(lái)看看什么是 LLVM?

LLVM 是 Low Level Virutal Machine的簡(jiǎn)稱,它是個(gè)編譯器框架,用于優(yōu)化以任意程序語(yǔ)言編寫(xiě)的程序的編譯時(shí)間(compile-time)、鏈接時(shí)間(link-time)、運(yùn)行時(shí)間(run-time)以及空閑時(shí)間(idle-time).在2000年, Chris Lattner開(kāi)發(fā)了這一套編譯器工具庫(kù)套件.后來(lái)隨著 LLVM的發(fā)展,LLVM可以用于常規(guī)編譯器,JIT編譯器,匯編器,調(diào)試器,靜態(tài)分析工具等一系列跟編程語(yǔ)言相關(guān)的工作。

Chris Lattner:
熟悉 Swift 的開(kāi)發(fā)者肯定知道這位大神的名字,他于2010年開(kāi)始編寫(xiě) Swift 語(yǔ)言,而且一個(gè)人實(shí)現(xiàn)了 Swift 的大部分基礎(chǔ)架構(gòu).他也是 LVVM 以及 Clang的主要開(kāi)發(fā)者.

2.GCC -> LLVM

GCC是 Xcode早期使用的一個(gè)強(qiáng)大的編譯器.這個(gè)編譯器被移植到各種系統(tǒng)中,其中就是 Mac OSX 操作系統(tǒng),所以這就反映在 Xcode中,在早期的 Xcode 調(diào)試代碼的一個(gè)工具就是 GDB,它是GNU調(diào)試器.

why換成LLVM呢?

Apple(包括中后期的NeXT) 一直使用GCC作為官方的編譯器。GCC作為開(kāi)源世界的編譯器標(biāo)準(zhǔn)一直做得不錯(cuò),但Apple對(duì)編譯工具會(huì)提出更高的要求。
一方面,是Apple對(duì)Objective-C語(yǔ)言(甚至后來(lái)對(duì)C語(yǔ)言)新增很多特性,但GCC開(kāi)發(fā)者并不買Apple的帳——不給實(shí)現(xiàn),因此索性后來(lái)兩者分成兩條分支分別開(kāi)發(fā),這也造成Apple的編譯器版本遠(yuǎn)落后于GCC的官方版本。另一方面,GCC的代碼耦合度太高,不好獨(dú)立,而且越是后期的版本,代碼質(zhì)量越差,但Apple想做的很多功能(比如更好的IDE支持)需要模塊化的方式來(lái)調(diào)用GCC,但GCC一直不給做。甚至最近,《GCC運(yùn)行環(huán)境豁免條款 (英文版)》從根本上限制了LLVM-GCC的開(kāi)發(fā)。 所以,這種不和讓Apple一直在尋找一個(gè)高效的、模塊化的、協(xié)議更放松的開(kāi)源替代品.原文鏈接

版本 | 編譯器版本
----|------|----
Xcode3之前 | GCC
Xcode3 | GCC與 LLVM混合編譯器
Xcode4 | LLVM-GCC 成為默認(rèn)編譯器
Xcode4.2 | LLVM3.0成為默認(rèn)編譯器
Xcode5 | LLVM5.0, 完成 GCC到LLVM的過(guò)渡

3.LLVM 與 Clang

Clang是一個(gè)C、C++、OC語(yǔ)言的輕量級(jí)編譯器。源代碼發(fā)布于BSD協(xié)議下。Clang是由C++編寫(xiě),基于LLVM,發(fā)布于LLVM BSD許可證下的編譯器。它與GNU C語(yǔ)言規(guī)范幾乎完全兼容,并增加了額外的特性。

如果說(shuō) LLVM是 iOS 的編譯器是不太準(zhǔn)確的,但說(shuō)clang 是 iOS 的編譯器這也不太準(zhǔn)確,因?yàn)?clang 是編譯器前端(下圖中的 Frontend).那編譯器又什么?

簡(jiǎn)單來(lái)說(shuō),編譯器就是把我們的 C,C++,OC 代碼轉(zhuǎn)成 hard code, 在這個(gè)過(guò)程中,編譯器會(huì)對(duì)代碼做各種分析來(lái)保證沒(méi)有無(wú)法編譯的錯(cuò)誤.


Three-Phase編譯器架構(gòu)

這里就要說(shuō)一下LLVM的三層架構(gòu):

1.Frontend: 這第一層就是 clang, 它支持將多種輸入語(yǔ)言(c family)經(jīng)過(guò)一系列處理后生成匯編代碼(LLVM JR).

2.Commer Optimizer:這第二層是一個(gè)優(yōu)化器,對(duì) LLVM JR 做優(yōu)化.

3.Backend:第三層對(duì)不同的平臺(tái)再將匯編轉(zhuǎn)成 machine code.

摘自孫源在 MDCC2016的 session

作為一個(gè) iOS 開(kāi)發(fā)者,個(gè)人在學(xué)習(xí)中主要關(guān)注在第一層,對(duì)第二層第三層只做了解(hello world level).
當(dāng)按下 Xcode上Run這個(gè)按鈕之后,我們的編譯器做了什么呢?

1.預(yù)處理(Prepreocess): import, macro, 預(yù)處理指令...

2.詞法分析:(Lexical Analysis):將預(yù)處理過(guò)的代碼文本轉(zhuǎn)化成Toke流

3.語(yǔ)法分析:(Semantic Analysis):驗(yàn)證語(yǔ)法是否正確,生成語(yǔ)意節(jié)點(diǎn),組合成抽象語(yǔ)法樹(shù).(AST)

4.靜態(tài)分析:(static Analysis):類型檢查,找出非語(yǔ)法錯(cuò)誤.

5.代碼生成:(CodeGen-IR):生成 LLVM-JR(匯編)



TO DO:
1.clang插件的使用和研究;
2.lldb 調(diào)試器的深入學(xué)習(xí);

參考文章:

1.孫源在 MDCC2016的 session鏈接
2.Objc-CN鏈接

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容