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ò)誤.
這里就要說(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.
作為一個(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í);