LLVM是一個(gè)*水平的編譯器框架。它包含有豐富軟件庫(kù),可以為編譯器的初學(xué)者提供良好的學(xué)習(xí)體驗(yàn),并大大降低編譯器開發(fā)的學(xué)習(xí)門檻。
本書的前半部分將向您介紹怎么樣去配置、構(gòu)建、和安裝LLVM的不同軟件庫(kù)、工具和外部項(xiàng)目。接下來(lái),本書的后半部分將向您介紹LLVM的各種設(shè)計(jì)細(xì)節(jié),并逐步地講解LLVM的各個(gè)編譯步驟:前段、中間表示(IR)、后端、即時(shí)編譯(JIT)引擎、跨平臺(tái)編譯和插件接口。本書包含有大量翔實(shí)的示例和代碼片段,以幫助讀者平穩(wěn)順利的掌握LLVM的編譯器開發(fā)環(huán)境。
LLVM是一個(gè)非常具有啟發(fā)意義的軟件項(xiàng)目,它起始于Chris Lattner個(gè)人對(duì)編譯器的熱情。LLVM最初版本發(fā)行后出現(xiàn)的一系列事件以及后來(lái)被廣泛采用的經(jīng)歷也遵循了一種其他開源項(xiàng)目常見的成功發(fā)展模式:這些項(xiàng)目通常是人們對(duì)某個(gè)問(wèn)題的強(qiáng)烈好奇心的產(chǎn)物,并非始于某個(gè)公司。例如,第一個(gè)Linux內(nèi)核的誕生源于一名芬蘭學(xué)生對(duì)操作系統(tǒng)領(lǐng)域的興趣,因而產(chǎn)生了強(qiáng)烈動(dòng)機(jī)去理解和實(shí)踐一個(gè)真正的操作系統(tǒng)應(yīng)該如何工作。
對(duì)于Linux或LLVM,許多程序員的貢獻(xiàn)使它們迅速成長(zhǎng)為一流軟件,在質(zhì)量上可以與現(xiàn)有的任何其他競(jìng)爭(zhēng)對(duì)手相媲美。因此,把任何一個(gè)大項(xiàng)目的成功歸功于特定個(gè)人是不公平的。無(wú)可否認(rèn)的是,在開源社區(qū)中,一個(gè)學(xué)生的軟件項(xiàng)目想要飛躍成為復(fù)雜且健壯的軟件需要一個(gè)關(guān)鍵因素:吸引那些愿意在該項(xiàng)目上花費(fèi)時(shí)間的貢獻(xiàn)者和程序員。
這樣的因素天然存在于充滿教育氣息的校園氛圍之中。教育的重要任務(wù)是教會(huì)學(xué)生理解任務(wù)的工作原理,因此對(duì)學(xué)生而言,他們可以在解開錯(cuò)綜復(fù)雜的機(jī)制并最終掌握它們的過(guò)程中享受到勝利的喜悅。伊利諾伊大學(xué)厄巴納–香檳分校(UIUC)的LLVM項(xiàng)目正是在這種環(huán)境下發(fā)展起來(lái)的,它既被用作研究原型,也被用作Lattner的碩士導(dǎo)師Vikram Adve講授編譯器課程的教學(xué)框架。學(xué)生們?yōu)樽畛醯腷ug排查做出了貢獻(xiàn),這也為L(zhǎng)LVM最終成為一個(gè)設(shè)計(jì)良好且易于學(xué)習(xí)的項(xiàng)目奠定了發(fā)展方向。
軟件理論和實(shí)踐之間的顯著差異使許多計(jì)算機(jī)科學(xué)專業(yè)的學(xué)生感到困惑。計(jì)算理論中一個(gè)簡(jiǎn)潔明了的概念可能涉及多層級(jí)的實(shí)現(xiàn)細(xì)節(jié),這些細(xì)節(jié)使得現(xiàn)實(shí)中的軟件項(xiàng)目變得過(guò)于復(fù)雜而無(wú)法讓人們掌握,特別是其所有微妙之處。巧妙的抽象設(shè)計(jì)是幫助人類大腦掌握項(xiàng)目所有層面的關(guān)鍵:從高層級(jí)的視圖(抽象意義下的程序?qū)崿F(xiàn)和工作方式)到最低層級(jí)的細(xì)節(jié)。
理論與實(shí)踐之間的差異在編譯器這一軟件中尤為顯著。對(duì)學(xué)習(xí)編譯器工作原理有極大熱情的學(xué)生,在理解編譯器的實(shí)際實(shí)現(xiàn)時(shí)常常面臨艱巨的挑戰(zhàn)。盡管學(xué)校已經(jīng)教授了編譯器的相關(guān)理論,但在LLVM項(xiàng)目之前,如果充滿好奇心的學(xué)生要學(xué)習(xí)實(shí)現(xiàn)真正的編譯器,GCC項(xiàng)目是少數(shù)開源選項(xiàng)之一。
然而從最純粹的意義上說(shuō),軟件項(xiàng)目反映的是其創(chuàng)建者的觀點(diǎn)。這些觀點(diǎn)通過(guò)跨多個(gè)組件對(duì)模塊和數(shù)據(jù)表示進(jìn)行抽象來(lái)實(shí)現(xiàn)。但對(duì)于同一主題,程序員可能有不同的看法。因此,對(duì)于GCC這樣已有近30年歷史的老舊軟件庫(kù)而言,其中集合了不同時(shí)代的程序員的不同觀點(diǎn),這使得該軟件越來(lái)越難以被新程序員和好學(xué)者理解。
LLVM項(xiàng)目不僅吸引了經(jīng)驗(yàn)豐富的編譯器程序員,還吸引了許多年輕且具有好奇心的從事科研的學(xué)生,他們從中看到一片更干凈、更簡(jiǎn)單的黑客土壤,它代表了一個(gè)具有很大潛力的編譯器。這一點(diǎn)可以從選擇LLVM作為研究原型的科學(xué)論文的龐大數(shù)量得到驗(yàn)證。學(xué)生們做出如此選擇的原因很簡(jiǎn)單:在學(xué)術(shù)界,學(xué)生通常負(fù)責(zé)項(xiàng)目的具體實(shí)現(xiàn),因此對(duì)他們來(lái)說(shuō),掌握實(shí)驗(yàn)框架代碼庫(kù)對(duì)于研究是至關(guān)重要的。由于LLVM使用C++語(yǔ)言(而不是GCC中使用的C)、模塊化(而不是GCC的單一龐大結(jié)構(gòu))以及更容易映射到現(xiàn)代編譯器理論的概念,因此,很多研究人員發(fā)現(xiàn)修改LLVM代碼以實(shí)現(xiàn)他們的科研想法是很容易的,并且有很多這方面成功的例子。LLVM在學(xué)術(shù)界的成功可以說(shuō)是理論與實(shí)踐之間縮小差距的結(jié)果。
除了作為科研工作的實(shí)驗(yàn)框架之外,與GCC的GPL許可證相比,LLVM項(xiàng)目還有更加自由的許可證,因而引起了產(chǎn)業(yè)界的興趣。對(duì)于一個(gè)從學(xué)術(shù)界發(fā)展起來(lái)的項(xiàng)目,編寫其代碼的研究人員通常會(huì)擔(dān)心寫好的代碼在用于單獨(dú)的某個(gè)實(shí)驗(yàn)后遭遇被丟棄的命運(yùn)。為了克服這種局限性,在UIUC的碩士項(xiàng)目中,Chris Lattner決定根據(jù)伊利諾伊大學(xué)/NCSA開源許可協(xié)議對(duì)該項(xiàng)目進(jìn)行許可,該許可只要求保留版權(quán)聲明就允許包括商用目的在內(nèi)的使用。Chris的目標(biāo)是使LLVM被最大限度地采用,最終結(jié)果超出預(yù)期。2012年,LLVM榮獲ACM軟件系統(tǒng)獎(jiǎng),這是對(duì)為科研做出杰出貢獻(xiàn)的軟件的高度認(rèn)可。
許多商業(yè)公司基于不同的需求使用LLVM項(xiàng)目,也為該項(xiàng)目做出不同的貢獻(xiàn),擴(kuò)展了基于LLVM的編譯器可以使用的語(yǔ)言范圍以及能夠?yàn)槠渖纱a的機(jī)器范圍。最終,LLVM項(xiàng)目具備了前所未有的成熟的庫(kù)和工具,進(jìn)入了新的階段:從學(xué)術(shù)軟件的實(shí)驗(yàn)狀態(tài),進(jìn)入被商業(yè)產(chǎn)品使用的健壯框架狀態(tài)。因此,項(xiàng)目的名稱也從低級(jí)虛擬機(jī)(Low Level Virtual Machine)更改為縮寫LLVM。
停用低級(jí)虛擬機(jī)的名稱,轉(zhuǎn)而使用LLVM,這一決定反映了該項(xiàng)目在不同時(shí)期的目標(biāo)。起初,LLVM是一個(gè)碩士科研項(xiàng)目,目標(biāo)是成為一個(gè)可以用于研究程序終身優(yōu)化的框架。相關(guān)工作成果發(fā)表在2003年MICRO(微體系結(jié)構(gòu)國(guó)際研討會(huì))的一篇名為《LLVA: A Low-level Virtual Instruction Set Architecture》的論文以及2004年CGO(代碼生成和優(yōu)化國(guó)際研討會(huì))的一篇名為《LLVM: A Compilation Framework for Lifelong Program Analysis & Transformation》的論文中。前者描述了LLVM的指令集,而后者對(duì)整個(gè)框架進(jìn)行了描述。
在學(xué)術(shù)環(huán)境之外,LLVM被廣泛用作一個(gè)設(shè)計(jì)良好的編譯器,它具有將中間表示寫入磁盤等有用的特性。在商業(yè)系統(tǒng)中,它從未真正像Java虛擬機(jī)(JVM)一樣被使用,因此繼續(xù)使用低級(jí)虛擬機(jī)名稱毫無(wú)意義。另一方面,其他一些奇怪的名字仍然作為L(zhǎng)LVM的歷史遺產(chǎn)而存在。在磁盤文件中存儲(chǔ)的LLVM中間表示程序稱為L(zhǎng)LVM位碼。位碼的名稱類似于Java的字節(jié)碼,但前者反映了LLVM中間表示所需的空間,與Java字節(jié)碼的含義不同。
我們編寫此書有雙重目的。首先,由于LLVM項(xiàng)目發(fā)展速度很快,我們希望將其循序漸進(jìn)地呈現(xiàn)給你,使本書的內(nèi)容盡可能簡(jiǎn)單易懂,同時(shí)讓你享受使用功能強(qiáng)大的編譯器庫(kù)的樂(lè)趣。 其次,我們希望喚起你開源黑客的精神去探索超出本書的概念,永遠(yuǎn)不要停止擴(kuò)充知識(shí)的腳步。
祝你閱讀愉快!
本書包含的內(nèi)容
第1章介紹如何在Linux、Windows或Mac上安裝Clang / LLVM軟件包,包括有關(guān)在Visual Studio和Xcode上構(gòu)建LLVM的討論。本章還將介紹LLVM不同發(fā)行版的風(fēng)格,以便于你根據(jù)自身需要選擇最合適的發(fā)行版本:預(yù)構(gòu)建的二進(jìn)制文件、軟件分發(fā)包或源代碼。
第2章介紹包含于單獨(dú)的軟件包或倉(cāng)庫(kù)中的外部LLVM項(xiàng)目,例如額外的Clang工具、DragonEgg GCC插件、LLVM調(diào)試器(LLDB)和LLVM測(cè)試套件。
第3章解釋LLVM項(xiàng)目中不同工具的組織形式,并通過(guò)一個(gè)實(shí)例介紹如何使用它們將源代碼編譯成匯編語(yǔ)言。本章還將介紹編譯器驅(qū)動(dòng)程序的工作原理,以及如何編寫你的第一個(gè)LLVM工具。
第4章介紹LLVM編譯器前端,即Clang項(xiàng)目。本章將一步一步地完整呈現(xiàn)前端涉及的所有步驟,同時(shí)還將解釋如何編寫調(diào)用前端不同功能的小程序。本章最后介紹如何使用Clang庫(kù)編寫一個(gè)小型編譯器驅(qū)動(dòng)程序。
第5章解釋LLVM設(shè)計(jì)中的一個(gè)關(guān)鍵部分,即其中間表示(IR)。本章將解釋它的重要特點(diǎn)、語(yǔ)法、結(jié)構(gòu)以及如何編寫生成LLVM IR的工具。
第6章介紹LLVM的編譯器后端,它負(fù)責(zé)將LLVM IR轉(zhuǎn)換為機(jī)器代碼。本章將逐步介紹后端涉及的所有步驟,并介紹編寫自己的LLVM后端所需的知識(shí)。本章最后展示如何創(chuàng)建一個(gè)后端編譯流程。
第7章解釋LLVM即時(shí)編譯基礎(chǔ)架構(gòu),它允許按需生成和執(zhí)行機(jī)器代碼。對(duì)于僅在運(yùn)行時(shí)才知道源程序代碼的應(yīng)用程序來(lái)說(shuō),此技術(shù)至關(guān)重要,例如Internet瀏覽器中的JavaScript解釋器。 本章將指導(dǎo)你使用正確的庫(kù)來(lái)創(chuàng)建自己的JIT編譯器。
第8章介紹如何使用Clang / LLVM在其他平臺(tái)(如基于ARM的平臺(tái))下編譯程序。由于程序的最終運(yùn)行平臺(tái)和編譯平臺(tái)是不同的,其中的關(guān)鍵步驟在于配置正確的編譯環(huán)境。
第9章介紹一個(gè)功能強(qiáng)大的工具,該工具甚至無(wú)須運(yùn)行程序,直接通過(guò)分析代碼,即可查找大型源代碼庫(kù)中的錯(cuò)誤。本章還將介紹如何使用你自己的錯(cuò)誤檢查程序擴(kuò)展Clang靜態(tài)分析器。
第10章介紹LibTooling框架和一系列基于此庫(kù)構(gòu)建的Clang工具,這些工具可以幫助你方便地重構(gòu)源代碼或者進(jìn)行簡(jiǎn)單的分析。本章最后將展示如何使用該框架編寫自己的C++源代碼重構(gòu)工具。
在撰寫本書時(shí),LLVM 3.5尚未發(fā)布。雖然本書側(cè)重于LLVM 3.4版本,但我們計(jì)劃發(fā)布附錄將書中的示例更新為L(zhǎng)LVM 3.5,這樣你就可以使用最新版本的LLVM來(lái)練習(xí)本書的內(nèi)容。該附錄將通過(guò)https://www.packtpub.com/sites/default/files/downloads/6924OS_Appendix.pdf提供。
閱讀本書需要的前提
要開始探索LLVM世界,可以使用UNIX系統(tǒng)、Mac OS X系統(tǒng)或Windows系統(tǒng),只要它們配備現(xiàn)代C++編譯器即可。LLVM源代碼對(duì)所用的C++編譯器要求很高,因此我們建議讀者總是使用最新的C++版本。這意味著在Linux上至少需要GCC 4.8.1,在Max OS X上至少需要Xcode 5.1,在Windows上需要Visual Studio 2012。
盡管我們會(huì)解釋如何使用Visual Studio在Windows上構(gòu)建LLVM,但該平臺(tái)并不是本書的重點(diǎn),因?yàn)槟承㎜LVM功能在該平臺(tái)上無(wú)法使用。例如,LLVM在Windows上缺少可加載模塊支持,但是我們要介紹的內(nèi)容包括如何編寫作為共享庫(kù)構(gòu)建的LLVM插件。在這種情況下,支持該內(nèi)容的唯一方法是使用Linux或Mac OS X。
如果讀者不想自己構(gòu)建LLVM,可以使用預(yù)構(gòu)建的二進(jìn)制包,但是這也限制了讀者能夠使用的平臺(tái)范圍。
本書目標(biāo)讀者
本書面向有興趣了解LLVM框架的編程愛好者、計(jì)算機(jī)科學(xué)專業(yè)學(xué)生和編譯器工程師。你需要有C++背景知識(shí),盡管不是強(qiáng)制性的,但至少應(yīng)該了解一些編譯器理論。無(wú)論你是新手還是編譯專家,本書都提供了LLVM的實(shí)用介紹,并避免了過(guò)于復(fù)雜的場(chǎng)景。如果你對(duì)此技術(shù)感興趣或有需求,那么本書絕對(duì)適合你。
下載示例代碼
本書的示例代碼可以從http://www.packtpub.com通過(guò)個(gè)人賬號(hào)下載,也可以訪問(wèn)華章圖書官網(wǎng)http://www.hzbook.com,通過(guò)注冊(cè)并登錄個(gè)人賬號(hào)下載。
布魯諾·卡多索·洛佩斯(Bruno Cardoso Lopes)在巴西坎皮納斯大學(xué)獲得計(jì)算機(jī)科學(xué)博士學(xué)位。自2007年以來(lái),他一直是LLVM的貢獻(xiàn)者,從頭開始實(shí)現(xiàn)MIPS后端,并且已經(jīng)維護(hù)了幾年。另外,他還編寫了x86 AVX支持方案,并改進(jìn)了ARM匯編器。他的研究興趣包括代碼壓縮技術(shù)和對(duì)ISA進(jìn)行位寬壓縮。之前他還開發(fā)了Linux和FreeBSD操作系統(tǒng)的驅(qū)動(dòng)程序。
拉斐爾·奧勒(Rafael Auler)是巴西坎皮納斯大學(xué)的博士生,并擁有該大學(xué)計(jì)算機(jī)科學(xué)碩士學(xué)位和計(jì)算機(jī)工程學(xué)士學(xué)位。在作為碩士生期間,他編寫了一個(gè)可以根據(jù)體系結(jié)構(gòu)描述文件自動(dòng)生成LLVM后端的概念驗(yàn)證工具。目前,他的博士研究課題包括動(dòng)態(tài)二進(jìn)制翻譯、即時(shí)編譯器和計(jì)算機(jī)體系結(jié)構(gòu)。 Rafael還是微軟研究院2013年研究生研究獎(jiǎng)學(xué)金獲得者。
出版者的話
譯者序
前言
關(guān)于作者
關(guān)于審稿人
第1章 構(gòu)建和安裝LLVM 1
1.1 了解LLVM版本 1
1.2 獲取預(yù)構(gòu)建包 2
1.2.1 獲取官方預(yù)構(gòu)建二進(jìn)制文件 2
1.2.2 使用軟件包管理器 3
1.3 從源代碼構(gòu)建 4
1.3.1 系統(tǒng)要求 4
1.3.2 獲取源代碼 4
1.3.3 構(gòu)建和安裝LLVM 5
1.3.4 Windows和Microsoft Visual Studio 10
1.3.5 Mac OS X和Xcode 12
1.4 總結(jié) 14
第2章 外部項(xiàng)目 15
2.1 Clang外部項(xiàng)目介紹 15
2.1.1 構(gòu)建和安裝Clang外部工具 16
2.1.2 理解Compiler-RT 17
2.1.3 實(shí)驗(yàn)Compiler-RT 17
2.2 使用DragonEgg插件 18
2.2.1 構(gòu)建DragonEgg 19
2.2.2 使用DragonEgg和LLVM工具了解編譯流程 19
2.2.3 理解LLVM測(cè)試套件 20
2.2.4 使用LLDB 21
2.2.5 libc++標(biāo)準(zhǔn)庫(kù)介紹 23
2.3 總結(jié) 25
第3章 工具和設(shè)計(jì) 26
3.1 LLVM的基本設(shè)計(jì)原理及其歷史 26
3.2 理解目前的LLVM 27
3.3 與編譯器驅(qū)動(dòng)程序交互 29
3.4 使用獨(dú)立工具 30
3.5 深入LLVM內(nèi)部設(shè)計(jì) 33
3.5.1 了解LLVM的基本庫(kù) 33
3.5.2 介紹LLVM的C++慣例 34
3.5.3 演示可插拔的流程接口 37
3.6 編寫你的第一個(gè)LLVM項(xiàng)目 38
3.6.1 編寫Makefile 38
3.6.2 編寫代碼 40
3.7 關(guān)于LLVM源代碼的一般建議 41
3.7.1 將代碼理解為文檔 42
3.7.2 請(qǐng)求社區(qū)的幫助 42
3.7.3 應(yīng)對(duì)更新:使用SVN日志作為文檔 42
3.7.4 結(jié)束語(yǔ) 44
3.8 總結(jié) 44
第4章 前端 45
4.1 Clang簡(jiǎn)介 45
4.1.1 前端操作 46
4.1.2 庫(kù) 47
4.1.3 理解Clang診斷 49
4.2 Clang前端階段介紹 52
4.2.1 詞法分析 52
4.2.2 語(yǔ)法分析 58
4.2.3 語(yǔ)義分析 63
4.2.4 生成LLVM IR代碼 65
4.3 完整的例子 65
4.4 總結(jié) 68
第5章 LLVM中間表示 69
5.1 概述 69
5.2 操作IR格式的基本工具示例 71
5.3 LLVM IR語(yǔ)法介紹 71
5.4 編寫自定義的LLVM IR生成器 76
5.4.1 構(gòu)建和運(yùn)行IR生成器 79
5.4.2 使用C++后端編寫代碼來(lái)生成IR構(gòu)造 80
5.5 在IR層執(zhí)行優(yōu)化 80
5.5.1 編譯時(shí)優(yōu)化和鏈接時(shí)優(yōu)化 80
5.5.2 發(fā)現(xiàn)最佳編譯器流程 82
5.5.3 流程間的依賴關(guān)系 83
5.5.4 了解流程API 85
5.5.5 自定義流程 85
5.6 總結(jié) 89
第6章 后端 90
6.1 概述 90
6.2 后端代碼結(jié)構(gòu)介紹 92
6.3 后端庫(kù)介紹 93
6.4 如何使用TableGen實(shí)現(xiàn)LLVM后端 94
6.4.1 TableGen語(yǔ)言 95
6.4.2 代碼生成器.td文件介紹 96
6.5 指令選擇階段介紹 100
6.5.1 SelectionDAG類 100
6.5.2 降級(jí) 102
6.5.3 DAG合并以及合法化 103
6.5.4 DAG到DAG指令選擇 104
6.5.5 指令選擇過(guò)程可視化 107
6.5.6 快速指令選擇 107
6.6 調(diào)度器 107
6.6.1 指令執(zhí)行進(jìn)程表 108
6.6.2 競(jìng)爭(zhēng)檢測(cè) 109
6.6.3 調(diào)度單元 109
6.7 機(jī)器指令 109
6.8 寄存器分配 110
6.8.1 寄存器合并器 111
6.8.2 虛擬寄存器重寫 114
6.8.3 編譯目標(biāo)的信息 115
6.9 前序代碼和結(jié)束代碼 116
6.10 機(jī)器代碼框架介紹 116
6.10.1 MC指令 116
6.10.2 代碼輸出 117
6.11 自定義機(jī)器流程 119
6.12 總結(jié) 121
第7章 即時(shí)編譯器 122
7.1 LLVM JIT引擎的基礎(chǔ)知識(shí)介紹 122
7.1.1 介紹執(zhí)行引擎 123
7.1.2 內(nèi)存管理 124
7.2 llvm::JIT框架介紹 124
7.2.1 將二進(jìn)制大對(duì)象寫入內(nèi)存 125
7.2.2 使用JITMemoryManager 125
7.2.3 目標(biāo)代碼輸出器 125
7.2.4 目標(biāo)信息 127
7.2.5 學(xué)習(xí)如何使用JIT類 127
7.3 llvm::MCJIT框架介紹 131
7.3.1 MCJIT引擎 131
7.3.2 MCJIT中模塊編譯過(guò)程 132
7.3.3 使用MCJIT引擎 135
7.4 使用LLVM JIT編譯工具 137
7.4.1 使用lli工具 137
7.4.2 使用llvm-rtdyld工具 138
7.5 其他資源 139
7.6 總結(jié) 139
第8章 跨平臺(tái)編譯 140
8.1 GCC和LLVM對(duì)比 140
8.2 目標(biāo)三元組介紹 141
8.3 準(zhǔn)備自己的工具鏈 142
8.3.1 標(biāo)準(zhǔn)C/C++庫(kù) 143
8.3.2 運(yùn)行時(shí)庫(kù) 143
8.3.3 匯編器和鏈接器 144
8.3.4 Clang前端 144
8.4 用Clang命令行參數(shù)進(jìn)行交叉編譯 145
8.4.1 針對(duì)目標(biāo)的驅(qū)動(dòng)程序選項(xiàng) 145
8.4.2 依賴包 145
8.4.3 交叉編譯 146
8.4.4 更改系統(tǒng)根目錄 148
8.5 生成Clang交叉編譯器 149
8.5.1 配置選項(xiàng) 149
8.5.2 構(gòu)建和安裝基于Clang的交叉編譯器 149
8.5.3 其他構(gòu)建方法 150
8.6 測(cè)試 151
8.6.1 開發(fā)板 151
8.6.2 模擬器 151
8.7 其他資源 152
8.8 總結(jié) 152
第9章 Clang靜態(tài)分析器 153
9.1 靜態(tài)分析器的作用 153
9.1.1 傳統(tǒng)警告信息和Clang靜態(tài)分析器比較 153
9.1.2 符號(hào)執(zhí)行引擎的高效性 156
9.2 測(cè)試靜態(tài)分析器 158
9.2.1 使用驅(qū)動(dòng)程序與使用編譯器 158
9.2.2 了解可用的檢查器 158
9.2.3 在Xcode IDE中使用靜態(tài)分析器 160
9.2.4 生成HTML格式的圖形
9.2.5 處理大型項(xiàng)目 161
9.3 使用自定義的檢查器擴(kuò)展靜態(tài)分析器 164
9.3.1 熟悉項(xiàng)目架構(gòu) 164
9.3.2 自定義檢查器