1. 程式人生 > >編譯器:gcc, clang, llvm

編譯器:gcc, clang, llvm

java clang 打開 分析 卻又 得到 man manual 明顯

clang

Clang是LLVM的前端,可以用來編譯C,C++,ObjectiveC等語言。傳統的編譯器通常分為三個部分,前端(frontEnd),優化器(Optimizer)和後端(backEnd)。在編譯過程中,前端主要負責詞法和語法分析,將源代碼轉化為抽象語法樹;優化器則是在前端的基礎上,對得到的中間代碼進行優化,使代碼更加高效;後端則是將已經優化的中間代碼轉化為針對各自平臺的機器代碼。Clang則是以LLVM為後端的一款高效易用,並且與IDE結合很好的編譯前端。

llvm

LLVM的命名最早來源於底層語言虛擬機(Low Level Virtual Machine)的縮寫。它是一個用於建立編譯器的基礎框架,以C++編寫。創建此工程的目的是對於任意的編程語言,利用該基礎框架,構建一個包括編譯時、鏈接時、執行時等的語言執行器。目前官方的LLVM只支持處理C/C++,Objective-C三種語言,當然也有一些非官方的擴展,使其支持ActionScript、Ada、D語言、Fortran、GLSL、Haskell、Java bytecode、Objective-C、Python、Ruby、Rust、Scala以及C#。

為何llvm/clang可以發展起來

  1. LLVM / Clang License是BSD,這條很重要

  2. GCC代碼搓,歷史包袱巨重,而LLVM / Clang 代碼組織結構非常漂亮,你想要改LLVM / Clang 比 GCC 輕松很多。最近我給GCC和Clang都開過Bug,但是Clang的Bug我都願意去找源碼哪裏可以修改,報Bug的時候也會說我找到的地方,如何修改等(如Bug 23791 – Clang emit wrong mangling of long double type for PPC64 in the Red Hat),但是GCC我都不願意去看源代碼(雖然我也不能看),只報Bug。

  3. LLVM / Clang 自己的表現也確實很出色,編譯速度,執行速度,診斷信息等4. LLVM / Clang 的背後是有錢的蘋果,有錢真的是大爺而背後的動力和推手麽,動力就是對GCC用的很不滿,定制性,可擴展性等都非常的差,而且那時候蘋果的Objective-C在GCC那裏也得不到很好的支持。這裏再次說了License,就說說License這條到底有多重要。比如我們IBM編譯器其實除了我所在IBM XL C/C++ Compiler,我們還有一個組是與GCC有關聯的,叫做Advance Toolchain,簡稱AT,而AT Team的就是專幹GCC的,而在那個組幹過的人就永不能到我們這邊幹活。同樣,由於License的原因,我們根本不準看GCC代碼,只能猜,但是我們卻又要保持與它的兼容性,那麽有了BSD License那可就爽多了。而你說其它開源的東西,如Linux等再造。其它開源的東西姑且不說,如果是類似Linux這樣的東西造起來,那麽先說一下新造出來的操作系統的生態問題吧。即為什麽要用你這個操作系統,還要為你這個操作系統開發軟件呢?

Clang和LLVM的關系

Clang和LLVM到底是什麽關系,這是在研究Clang的過程中所不可避免的一個問題。如果要搞清楚Clang和LLVM之間的關系,首先先要知道宏觀的LLVM和微觀的LLVM。

宏觀的LLVM,指的是整個的LLVM的框架,它肯定包含了Clang,因為Clang是LLVM的框架的一部分,是它的一個C/C++的前端。雖然這個前端占的比重比較大,但是它依然只是個前端,LLVM框架可以有很多個前端和很多個後端,只要你想繼續擴展。

微觀的LLVM指的是以實際開發過程中,包括實際使用過程中,劃分出來的LLVM。比如編譯LLVM和Clang的時候,LLVM的源碼包是不包含Clang的源碼包的,需要單獨下載Clang的源碼包。

所以這裏想討論的就是微觀的LLVM和Clang的關系。從編譯器用戶的角度,Clang使用了LLVM中的一些功能,目前所知道的主要就是對中間格式代碼的優化,或許還有一部分生成代碼的功能。從Clang和微觀LLVM的源碼位置可以看出,Clang是基於微觀的LLVM的一個工具。而從功能的角度來說,微觀的LLVM可以認為是一個編譯器的後端,而Clang是一個編譯器的前端,它們的關系就更加的明了了,一個編譯器前端想要程序最終變成可執行文件,是缺少不了對編譯器後端的介紹的。

這樣基本就確定了Clang和LLVM的關系。這個問題雖然並不復雜,但是對於後續的結構理解和深入研究確是一個很重要的出發點。這個出發點不理清楚的話,後續的研究沒有辦法繼續深入下去。

Clang的整體架構

如果要深入的研究Clang,那麽首先需要知道Clang的整體架構。直接打開Clang的源碼的話,裏面目錄較多,無從下手。可以直接從doxygen文檔看,Clang的doxygen的地址是:http://clang.llvm.org/doxygen/index.html 。從這個首頁選取Directories,可以直接進到文件目錄列表:http://clang.llvm.org/doxygen/dirs.html 。在這個裏面看目錄,就比較清晰了,在clang目錄下面一共就三個目錄: docs、include和lib。為什麽只有這三個呢?仔細研究和對比就會發現,如果你要研究Clang的內部實現,只需要這三個目錄就夠了,其他的目錄和Clang核心沒有任何關系,是一些基於Clang的工具,Clang的一些例子,或者是一些測試用例等。

現在看起來,Clang的結構已經很明顯了。docs很明顯放置的都是一些文檔相關的內容,include放置的都是一些頭文件。就只剩下一個lib目錄了,下面是分類的目錄,這個時候也可以推斷出Clang的總體架構了,它的總體架構是基於庫的。在Clang的官方文檔“Clang" CFE Internals Manual (http://clang.llvm.org/docs/InternalsManual.html )中,對Clang內部的介紹也是依據庫來進行分類的。

編譯器:gcc, clang, llvm