LLVM Clang 學習筆記

一銘發表於2017-12-13

1.先來看看什麼是 LLVM?

LLVM 是 Low Level Virutal Machine的簡稱,它是個編譯器框架,用於優化以任意程式語言編寫的程式的編譯時間(compile-time)、連結時間(link-time)、執行時間(run-time)以及空閒時間(idle-time).在2000年, Chris Lattner開發了這一套編譯器工具庫套件.後來隨著 LLVM的發展,LLVM可以用於常規編譯器,JIT編譯器,彙編器,偵錯程式,靜態分析工具等一系列跟程式語言相關的工作。

Chris Lattner: 熟悉 Swift 的開發者肯定知道這位大神的名字,他於2010年開始編寫 Swift 語言,而且一個人實現了 Swift 的大部分基礎架構.他也是 LVVM 以及 Clang的主要開發者.

2.GCC -> LLVM

GCC是 Xcode早期使用的一個強大的編譯器.這個編譯器被移植到各種系統中,其中就是 Mac OSX 作業系統,所以這就反映在 Xcode中,在早期的 Xcode 除錯程式碼的一個工具就是 GDB,它是GNU偵錯程式. ####why換成LLVM呢? Apple(包括中後期的NeXT) 一直使用GCC作為官方的編譯器。GCC作為開源世界的編譯器標準一直做得不錯,但Apple對編譯工具會提出更高的要求。 一方面,是Apple對Objective-C語言(甚至後來對C語言)新增很多特性,但GCC開發者並不買Apple的帳——不給實現,因此索性後來兩者分成兩條分支分別開發,這也造成Apple的編譯器版本遠落後於GCC的官方版本。另一方面,GCC的程式碼耦合度太高,不好獨立,而且越是後期的版本,程式碼質量越差,但Apple想做的很多功能(比如更好的IDE支援)需要模組化的方式來呼叫GCC,但GCC一直不給做。甚至最近,《GCC執行環境豁免條款 (英文版)》從根本上限制了LLVM-GCC的開發。 所以,這種不和讓Apple一直在尋找一個高效的、模組化的、協議更放鬆的開源替代品.原文連結

版本 編譯器版本
Xcode3之前 GCC
Xcode3 GCC與 LLVM混合編譯器
Xcode4 LLVM-GCC 成為預設編譯器
Xcode4.2 LLVM3.0成為預設編譯器
Xcode5 LLVM5.0, 完成 GCC到LLVM的過渡

3.LLVM 與 Clang

Clang是一個C、C++、OC語言的輕量級編譯器。原始碼釋出於BSD協議下。Clang是由C++編寫,基於LLVM,釋出於LLVM BSD許可證下的編譯器。它與GNU C語言規範幾乎完全相容,並增加了額外的特性。

如果說 LLVM是 iOS 的編譯器是不太準確的,但說clang 是 iOS 的編譯器這也不太準確,因為 clang 是編譯器前端(下圖中的 Frontend).那編譯器又什麼? ######簡單來說,編譯器就是把我們的 C,C++,OC 程式碼轉成 hard code, 在這個過程中,編譯器會對程式碼做各種分析來保證沒有無法編譯的錯誤. 

Three-Phase編譯器架構
這裡就要說一下LLVM的三層架構: ####1.Frontend: 這第一層就是 clang, 它支援將多種輸入語言(c family)經過一系列處理後生成彙編程式碼(LLVM JR). ####2.Commer Optimizer:這第二層是一個優化器,對 LLVM JR 做優化. ####3.Backend:第三層對不同的平臺再將彙編轉成 machine code.
摘自孫源在 MDCC2016的 session

作為一個 iOS 開發者,個人在學習中主要關注在第一層,對第二層第三層只做瞭解(hello world level). 當按下 Xcode上Run這個按鈕之後,我們的編譯器做了什麼呢? ####1.預處理(Prepreocess): import, macro, 預處理指令... ####2.詞法分析:(Lexical Analysis):將預處理過的程式碼文字轉化成Toke流 ####3.語法分析:(Semantic Analysis):驗證語法是否正確,生成語意節點,組合成抽象語法樹.(AST) ####4.靜態分析:(static Analysis):型別檢查,找出非語法錯誤. ####5.程式碼生成:(CodeGen-IR):生成 LLVM-JR(彙編)


TO DO: 1.clang外掛的使用和研究; 2.lldb 偵錯程式的深入學習;

###參考文章: 1.孫源在 MDCC2016的 session連結 2.Objc-CN連結

相關文章