LLVM自己並不是編譯器,是開源的編譯器(compiler)架構,是一套用於開發編譯器、解釋器等程序語言相關工具的庫,主要聚焦於編譯器後端功能,如代碼生成、代碼優化、JIT等。前端
Clang是一個基於LLVM開發的C/C++/Obj-C編譯器。有一套獨立的前端,後端直接採用LLVM。另外一個較爲早期的相關項目LLVM-GCC,是一個將GCC的前端嫁接到LLVM之上拼接而成的一個完整的編譯器。編程
什麼是GCC的前端呢,這要從經典編譯器提及。後端
經典編譯器架構
一、經典編譯器介紹編程語言
一個傳統靜態編譯器(像大多數C編譯器)最流行的設計是3階段的設計,當中主要組件是前端。優化器及後端(下圖)。函數
前端解析源碼。檢查錯誤。並構建一個特定於語言的抽象語法樹(AST)來表明輸入的代碼。工具
可選地AST被轉換到一個新的用於優化的表示。優化器及後端可以執行這個代碼。post
優化器負責進行各類轉換嘗試改進代碼的執行時間,比方反覆計算消除。一般或多或少與語言及目標無關。性能
而後後端(也被稱爲代碼產生器)把代碼映射入目標指令集。優化
除了製做正確的代碼,它負責產生利用所支持架構不日常功能的好代碼。
一個編譯器後端的通用部分包含指令選擇,寄存器分配。及指令調度。
這個模型相同適用於解釋器及JIT編譯器。Java性能機(JVM)也是這個模型的一個實現,它使用Java字節碼做爲前端及優化器間的接口。
二、當一個編譯器決定支持多個源語言或目標架構時。這樣的經典設計最重要的收益出現了。
假設編譯器在其優化器中使用一個通用的代碼表示,那麼可以不論什麼可以編譯到這個表示的語言編寫一個前端,且可以爲不論什麼可以從這個表示編譯獲得的目標編寫一個後端,如圖所看到的。
LLVM
LLVM是開源的編譯器(compiler)架構,以C++編寫而成,用於優化以隨意程序語言編寫的程序的編譯時間(compile-time)、連接時間(link-time)、執行時間(run-time)以及空暇時間(idle-time),對開發人員保持開放,併兼容已有腳本。
LLVM的設計就採用了上述三個階段的設計。例如如下圖所看到的。
這樣作的長處是假設需要支持一種新的編程語言。那麼咱們僅僅需要實現一種新的前端。
假設咱們需要支持一種新的硬件設備。那咱們僅僅需要實現一個新的後端。
而優化階段因爲是針對了統一的LLVM IR,因此它是一個通用的階段,不管是支持新的編程語言。仍是支持新的硬件設備,這裏都不需要對優化階段作改動。
依據可讀的IR,咱們可以知道終於生成目標代碼以前。咱們已經生成了什麼樣的代碼。而且依據IR。咱們可以選擇使用不一樣的後端而生成不一樣的可運行代碼。同一時候,因爲使用了統一的IR,因此咱們可以重用LLVM的優化功能。即便咱們使用的是本身設計的編程語言。
-S -emit-llvm
選項執行時會生成 LLVM 字節代碼。
Clang ( 發音爲 /klæŋ/)
Clang是一個C++編寫、基於LLVM,C、C++、Objective-C、Objective-C++語言的輕量級編譯器。源碼公佈於BSD協議下。
它與GNU C語言規範差點兒全然兼容(固然,也有部分不兼容的內容。包含編譯命令選項也會有點差別),並在此基礎上添加了額外的語法特性,比方C函數重載(經過__attribute__((overloadable))來修飾函數),其目標(之中的一個)就是超越GCC。
Clang 是一個編譯器前端,這也就是說:Clang 將目標程序進行分析,而後生成結構化的,樹狀的語法表示 , 即抽象語法樹 AST(Abstract Syntax Tree)。
一、Clang 的開發背景
由於 GNU 編譯器套裝 (GCC) 系統龐大,而且 Apple 大量使用的 Objective-C 在 GCC 中優先級較低。同一時候 GCC 做爲一個純粹的編譯系統。與 IDE 配合並不優秀。Apple 決定從零開始寫 C family 的前端。也就是基於 LLVM 的 Clang 了。Clang 由 Apple 公司開發。源碼受權使用 BSD 的開源受權。
二、基於 Clang 的編程
與不少編譯器前端相比。Clang 的最大特色就是良好的結構化設計,每部分都是一個單獨的庫 (library)。
也就是說您可以單獨的使用當中的一部分。來編寫本身的程序。