LLVM编译器实战教程
作者 : [巴西]布鲁诺·卡多索·洛佩斯(Bruno Cardoso Lopes) 拉斐尔·奥勒(Rafael Auler) 著
译者 : 过敏意 冷静文 译
丛书名 : 计算机科学丛书
出版日期 : 2019-08-08
ISBN : 978-7-111-63197-2
定价 : 79.00元
教辅资源下载
扩展信息
语种 : 简体中文
页数 : 226
开本 : 16
原书名 : Getting Started with LLVM Core Libraries
原出版社: Packt Publishing Ltd.
属性分类: 教材
包含CD : 无CD
绝版 :
图书简介

LLVM是一个世界领先水平的编译器框架。它包含有丰富软件库,可以为编译器的初学者提供良好的学习体验,并大大降低编译器开发的学习门槛。
本书的前半部分将向您介绍怎么样去配置、构建、和安装LLVM的不同软件库、工具和外部项目。接下来,本书的后半部分将向您介绍LLVM的各种设计细节,并逐步地讲解LLVM的各个编译步骤:前段、中间表示(IR)、后端、即时编译(JIT)引擎、跨平台编译和插件接口。本书包含有大量翔实的示例和代码片段,以帮助读者平稳顺利的掌握LLVM的编译器开发环境。

图书特色

紧密结合LLVM的源码,系统介绍LLVM的模块化设计理念并详解技术细节

图书前言

LLVM是一个非常具有启发意义的软件项目,它起始于Chris Lattner个人对编译器的热情。LLVM最初版本发行后出现的一系列事件以及后来被广泛采用的经历也遵循了一种其他开源项目常见的成功发展模式:这些项目通常是人们对某个问题的强烈好奇心的产物,并非始于某个公司。例如,第一个Linux内核的诞生源于一名芬兰学生对操作系统领域的兴趣,因而产生了强烈动机去理解和实践一个真正的操作系统应该如何工作。
对于Linux或LLVM,许多程序员的贡献使它们迅速成长为一流软件,在质量上可以与现有的任何其他竞争对手相媲美。因此,把任何一个大项目的成功归功于特定个人是不公平的。无可否认的是,在开源社区中,一个学生的软件项目想要飞跃成为复杂且健壮的软件需要一个关键因素:吸引那些愿意在该项目上花费时间的贡献者和程序员。
这样的因素天然存在于充满教育气息的校园氛围之中。教育的重要任务是教会学生理解任务的工作原理,因此对学生而言,他们可以在解开错综复杂的机制并最终掌握它们的过程中享受到胜利的喜悦。伊利诺伊大学厄巴纳–香槟分校(UIUC)的LLVM项目正是在这种环境下发展起来的,它既被用作研究原型,也被用作Lattner的硕士导师Vikram Adve讲授编译器课程的教学框架。学生们为最初的bug排查做出了贡献,这也为LLVM最终成为一个设计良好且易于学习的项目奠定了发展方向。
软件理论和实践之间的显著差异使许多计算机科学专业的学生感到困惑。计算理论中一个简洁明了的概念可能涉及多层级的实现细节,这些细节使得现实中的软件项目变得过于复杂而无法让人们掌握,特别是其所有微妙之处。巧妙的抽象设计是帮助人类大脑掌握项目所有层面的关键:从高层级的视图(抽象意义下的程序实现和工作方式)到最低层级的细节。
理论与实践之间的差异在编译器这一软件中尤为显著。对学习编译器工作原理有极大热情的学生,在理解编译器的实际实现时常常面临艰巨的挑战。尽管学校已经教授了编译器的相关理论,但在LLVM项目之前,如果充满好奇心的学生要学习实现真正的编译器,GCC项目是少数开源选项之一。
然而从最纯粹的意义上说,软件项目反映的是其创建者的观点。这些观点通过跨多个组件对模块和数据表示进行抽象来实现。但对于同一主题,程序员可能有不同的看法。因此,对于GCC这样已有近30年历史的老旧软件库而言,其中集合了不同时代的程序员的不同观点,这使得该软件越来越难以被新程序员和好学者理解。
LLVM项目不仅吸引了经验丰富的编译器程序员,还吸引了许多年轻且具有好奇心的从事科研的学生,他们从中看到一片更干净、更简单的黑客土壤,它代表了一个具有很大潜力的编译器。这一点可以从选择LLVM作为研究原型的科学论文的庞大数量得到验证。学生们做出如此选择的原因很简单:在学术界,学生通常负责项目的具体实现,因此对他们来说,掌握实验框架代码库对于研究是至关重要的。由于LLVM使用C++语言(而不是GCC中使用的C)、模块化(而不是GCC的单一庞大结构)以及更容易映射到现代编译器理论的概念,因此,很多研究人员发现修改LLVM代码以实现他们的科研想法是很容易的,并且有很多这方面成功的例子。LLVM在学术界的成功可以说是理论与实践之间缩小差距的结果。
除了作为科研工作的实验框架之外,与GCC的GPL许可证相比,LLVM项目还有更加自由的许可证,因而引起了产业界的兴趣。对于一个从学术界发展起来的项目,编写其代码的研究人员通常会担心写好的代码在用于单独的某个实验后遭遇被丢弃的命运。为了克服这种局限性,在UIUC的硕士项目中,Chris Lattner决定根据伊利诺伊大学/NCSA开源许可协议对该项目进行许可,该许可只要求保留版权声明就允许包括商用目的在内的使用。Chris的目标是使LLVM被最大限度地采用,最终结果超出预期。2012年,LLVM荣获ACM软件系统奖,这是对为科研做出杰出贡献的软件的高度认可。
许多商业公司基于不同的需求使用LLVM项目,也为该项目做出不同的贡献,扩展了基于LLVM的编译器可以使用的语言范围以及能够为其生成代码的机器范围。最终,LLVM项目具备了前所未有的成熟的库和工具,进入了新的阶段:从学术软件的实验状态,进入被商业产品使用的健壮框架状态。因此,项目的名称也从低级虚拟机(Low Level Virtual Machine)更改为缩写LLVM。
停用低级虚拟机的名称,转而使用LLVM,这一决定反映了该项目在不同时期的目标。起初,LLVM是一个硕士科研项目,目标是成为一个可以用于研究程序终身优化的框架。相关工作成果发表在2003年MICRO(微体系结构国际研讨会)的一篇名为《LLVA: A Low-level Virtual Instruction Set Architecture》的论文以及2004年CGO(代码生成和优化国际研讨会)的一篇名为《LLVM: A Compilation Framework for Lifelong Program Analysis & Transformation》的论文中。前者描述了LLVM的指令集,而后者对整个框架进行了描述。
在学术环境之外,LLVM被广泛用作一个设计良好的编译器,它具有将中间表示写入磁盘等有用的特性。在商业系统中,它从未真正像Java虚拟机(JVM)一样被使用,因此继续使用低级虚拟机名称毫无意义。另一方面,其他一些奇怪的名字仍然作为LLVM的历史遗产而存在。在磁盘文件中存储的LLVM中间表示程序称为LLVM位码。位码的名称类似于Java的字节码,但前者反映了LLVM中间表示所需的空间,与Java字节码的含义不同。
我们编写此书有双重目的。首先,由于LLVM项目发展速度很快,我们希望将其循序渐进地呈现给你,使本书的内容尽可能简单易懂,同时让你享受使用功能强大的编译器库的乐趣。 其次,我们希望唤起你开源黑客的精神去探索超出本书的概念,永远不要停止扩充知识的脚步。
祝你阅读愉快!
本书包含的内容
第1章介绍如何在Linux、Windows或Mac上安装Clang / LLVM软件包,包括有关在Visual Studio和Xcode上构建LLVM的讨论。本章还将介绍LLVM不同发行版的风格,以便于你根据自身需要选择最合适的发行版本:预构建的二进制文件、软件分发包或源代码。
第2章介绍包含于单独的软件包或仓库中的外部LLVM项目,例如额外的Clang工具、DragonEgg GCC插件、LLVM调试器(LLDB)和LLVM测试套件。
第3章解释LLVM项目中不同工具的组织形式,并通过一个实例介绍如何使用它们将源代码编译成汇编语言。本章还将介绍编译器驱动程序的工作原理,以及如何编写你的第一个LLVM工具。
第4章介绍LLVM编译器前端,即Clang项目。本章将一步一步地完整呈现前端涉及的所有步骤,同时还将解释如何编写调用前端不同功能的小程序。本章最后介绍如何使用Clang库编写一个小型编译器驱动程序。
第5章解释LLVM设计中的一个关键部分,即其中间表示(IR)。本章将解释它的重要特点、语法、结构以及如何编写生成LLVM IR的工具。
第6章介绍LLVM的编译器后端,它负责将LLVM IR转换为机器代码。本章将逐步介绍后端涉及的所有步骤,并介绍编写自己的LLVM后端所需的知识。本章最后展示如何创建一个后端编译流程。
第7章解释LLVM即时编译基础架构,它允许按需生成和执行机器代码。对于仅在运行时才知道源程序代码的应用程序来说,此技术至关重要,例如Internet浏览器中的JavaScript解释器。 本章将指导你使用正确的库来创建自己的JIT编译器。
第8章介绍如何使用Clang / LLVM在其他平台(如基于ARM的平台)下编译程序。由于程序的最终运行平台和编译平台是不同的,其中的关键步骤在于配置正确的编译环境。
第9章介绍一个功能强大的工具,该工具甚至无须运行程序,直接通过分析代码,即可查找大型源代码库中的错误。本章还将介绍如何使用你自己的错误检查程序扩展Clang静态分析器。
第10章介绍LibTooling框架和一系列基于此库构建的Clang工具,这些工具可以帮助你方便地重构源代码或者进行简单的分析。本章最后将展示如何使用该框架编写自己的C++源代码重构工具。
在撰写本书时,LLVM 3.5尚未发布。虽然本书侧重于LLVM 3.4版本,但我们计划发布附录将书中的示例更新为LLVM 3.5,这样你就可以使用最新版本的LLVM来练习本书的内容。该附录将通过https://www.packtpub.com/sites/default/files/downloads/6924OS_Appendix.pdf提供。
阅读本书需要的前提
要开始探索LLVM世界,可以使用UNIX系统、Mac OS X系统或Windows系统,只要它们配备现代C++编译器即可。LLVM源代码对所用的C++编译器要求很高,因此我们建议读者总是使用最新的C++版本。这意味着在Linux上至少需要GCC 4.8.1,在Max OS X上至少需要Xcode 5.1,在Windows上需要Visual Studio 2012。
尽管我们会解释如何使用Visual Studio在Windows上构建LLVM,但该平台并不是本书的重点,因为某些LLVM功能在该平台上无法使用。例如,LLVM在Windows上缺少可加载模块支持,但是我们要介绍的内容包括如何编写作为共享库构建的LLVM插件。在这种情况下,支持该内容的唯一方法是使用Linux或Mac OS X。
如果读者不想自己构建LLVM,可以使用预构建的二进制包,但是这也限制了读者能够使用的平台范围。
本书目标读者
本书面向有兴趣了解LLVM框架的编程爱好者、计算机科学专业学生和编译器工程师。你需要有C++背景知识,尽管不是强制性的,但至少应该了解一些编译器理论。无论你是新手还是编译专家,本书都提供了LLVM的实用介绍,并避免了过于复杂的场景。如果你对此技术感兴趣或有需求,那么本书绝对适合你。
下载示例代码
本书的示例代码可以从http://www.packtpub.com通过个人账号下载,也可以访问华章图书官网http://www.hzbook.com,通过注册并登录个人账号下载。

上架指导

计算机\编译

封底文字

LLVM是一个正在发展中的前沿编译器技术框架,它易于扩展并设计成多个库,可以为编译器入门者提供流畅的体验,并能使编译器开发所涉及的学习过程变得非常顺畅。本书首先介绍如何配置、构建和安装LLVM库、工具和外部项目,随后介绍LLVM设计以及它在每个LLVM编译器阶段的实际工作方式,这些阶段包括:前端、IR、后端、JIT引擎、交叉编译功能和插件接口。本书还提供了多个实际操作的范例和源代码片段,可以帮助读者坚实而顺利地掌握LLVM编译器开发环境的入门知识。

布鲁诺·卡多索·洛佩斯(Bruno Cardoso Lopes) 在巴西坎皮纳斯大学获得计算机科学博士学位。自2007年以来,他一直是LLVM的贡献者,从头开始实现MIPS后端,并且已经维护了几年。另外,他还编写了x86 AVX支持方案,并改进了ARM汇编器。他的研究兴趣包括代码压缩技术和对ISA进行位宽压缩。之前他还开发了Linux和FreeBSD操作系统的驱动程序。
拉斐尔·奥勒(Rafael Auler) 是巴西坎皮纳斯大学的博士生,并拥有该大学计算机科学硕士学位和计算机工程学士学位。在作为硕士生期间,他编写了一个可以根据体系结构描述文件自动生成LLVM后端的概念验证工具。目前,他的博士研究课题包括动态二进制翻译、即时编译器和计算机体系结构。 Rafael还是微软研究院2013年研究生研究奖学金获得者。

作者简介

[巴西]布鲁诺·卡多索·洛佩斯(Bruno Cardoso Lopes) 拉斐尔·奥勒(Rafael Auler) 著:布鲁诺·卡多索·洛佩斯(Bruno Cardoso Lopes)在巴西坎皮纳斯大学获得计算机科学博士学位。自2007年以来,他一直是LLVM的贡献者,从头开始实现MIPS后端,并且已经维护了几年。另外,他还编写了x86 AVX支持方案,并改进了ARM汇编器。他的研究兴趣包括代码压缩技术和对ISA进行位宽压缩。之前他还开发了Linux和FreeBSD操作系统的驱动程序。

拉斐尔·奥勒(Rafael Auler)是巴西坎皮纳斯大学的博士生,并拥有该大学计算机科学硕士学位和计算机工程学士学位。在作为硕士生期间,他编写了一个可以根据体系结构描述文件自动生成LLVM后端的概念验证工具。目前,他的博士研究课题包括动态二进制翻译、即时编译器和计算机体系结构。 Rafael还是微软研究院2013年研究生研究奖学金获得者。

译者序

众所周知,编译器是连接软件和硬件的桥梁,是核心基础软件。尤其是近年来计算机体系结构发展迅速,大数据、人工智能等上层应用对算力提出了更高的要求,编译器变得越来越重要了。编译器本质是将一种高级语言翻译为低级语言的程序,通常包括前端、优化器、后端等。前端负责解析高级语言,将程序转换为内部的中间表示格式;优化器基于中间表示进行优化;而后端则负责低级语言代码生成。
由于编译器的特殊性,它涉及的计算机知识包括计算理论、体系结构和软件工程。在解析高级语言时,编译器涉及的计算理论包括正则语法、有限状态自动机、上下文无关文法、下推自动机等。编译器需要生成的低级语言通常是目标体系结构的机器语言,因此需要结合体系结构的特点进行指令选择、寄存器分配等。从软件工程的角度来说,编译器有着和操作系统内核相近的复杂度。例如,运用广泛的GCC编译器有700万行代码,而Linux内核代码有1500万行左右。
LLVM起源于伊利诺伊大学厄巴纳–香槟分校的一个开源项目,初始目的是开发一套程序的低层表达。这也是LLVM名称的来源,即Low Level Virtual Machine(低级虚拟机)的缩写。LLVM的低层表达采用静态单赋值(SSA)形式,它在开源后受到广泛的好评和关注,目前已经发展出完整的编译器基础设施。它支持C、C++、Objective-C等高级语言,并支持静态和动态编译方式。现在采用和开发LLVM的公司包括Apple、Google和NVIDIA等主流计算机企业。
LLVM荣获2012年ACM软件系统奖,其成功之处主要在于统一的低层中间表达以及极致、模块化的软件工程方法。LLVM也采用了编译器中常见的“前端–优化器–后端”组织形式,只是不同的前端和后端都采用统一的低层中间表示格式(LLVM IR)将二者进行解耦并最大可能地复用优化器的代码。另外,LLVM抽象和剥离了不同的编译流程,用户可以调用指定的单个或者多个编译流程。这也是LLVM和GCC编译器的区别所在。GCC是一个庞大的软件,很难对其进行二次修改。而LLVM通过良好设计的编译流程的接口,有着更为广泛和灵活的应用场景:它既可以用于静态编译器,也可以用于即时编译器,甚至可以仅仅调用其中的某些API。LLVM现在被作为实现各种静态和运行时编译语言(GCC家族、Java、.NET、Python、Ruby、Scheme、Haskell、D等)的通用基础设施。
由于其良好的设计,LLVM的意义不仅仅在于一个编译器。LLVM对于新的编程语言和新型芯片开发也有很好的促进作用。LLVM 的 IR(中间表示)设计理念从一开始就具有可移植特性,可以适配多种编程语言和多种硬件平台。因此,新的编程语言开发只需设计一个新的前端,而新型芯片的开发只需设计一个新的后端,这样大大缩短了开发流程。此外,LLVM还可以用于编译器插件开发,例如代码规范检查、代码优化等。总而言之,LLVM在现代计算机系统栈中的地位举足轻重。
LLVM的优点使得它比传统GCC编译器更加简单易懂,代码更具可读性。特别是LLVM的模块化代码设计使其代码修改或者增加更加容易,因此国外很多大学都把LLVM用于教学实践。本书主要阐述LLVM的模块化设计理念并详解不同模块的细节,两位作者Bruno Cardoso Lopes和Rafael Auler都是LLVM项目的贡献者。
作为本书的译者,我们在编译器领域有着丰富的经验,一位长期从事编译和并行计算研究,另一位在博士期间协助导师将LLVM运用于编译课程的教学之中。我们所在的科研团队在使用LLVM开发面向系统底层的软件(比如任务调度器、GPU加速程序等)和教学过程中,深感需要一本系统介绍LLVM的中文书籍,这是译者翻译本书的初衷。在翻译过程中,译者尽最大的努力还原作品的原意,遵循了专有名词的通用翻译,对于没有约定俗成的术语翻译,则在给出译文的同时也把英文原文附上。本书的特点是紧密结合LLVM的源码,帮助有一定编译器知识基础的读者快速掌握LLVM。
在本书的翻译过程中,上海交通大学新兴并行计算团队的研究生张蔚、蔡晓晴、邱宇贤、郭聪、崔炜皞、周杨杰、刘子汉为本书的译文和校对出力良多,在此均致谢忱!
限于译者中英文水平,译文可能存在欠妥之处,敬请读者不吝赐正。

过敏意 冷静文
于上海交通大学闵行校区
2019年3月12日

图书目录

出版者的话
译者序
前言
关于作者
关于审稿人
第1章 构建和安装LLVM 1
1.1 了解LLVM版本 1
1.2 获取预构建包 2
1.2.1 获取官方预构建二进制文件 2
1.2.2 使用软件包管理器 3
1.3 从源代码构建 4
1.3.1 系统要求 4
1.3.2 获取源代码 4
1.3.3 构建和安装LLVM 5
1.3.4 Windows和Microsoft Visual Studio 10
1.3.5 Mac OS X和Xcode 12
1.4 总结 14
第2章 外部项目 15
2.1 Clang外部项目介绍 15
2.1.1 构建和安装Clang外部工具 16
2.1.2 理解Compiler-RT 17
2.1.3 实验Compiler-RT 17
2.2 使用DragonEgg插件 18
2.2.1 构建DragonEgg 19
2.2.2 使用DragonEgg和LLVM工具了解编译流程 19
2.2.3 理解LLVM测试套件 20
2.2.4 使用LLDB 21
2.2.5 libc++标准库介绍 23
2.3 总结 25
第3章 工具和设计 26
3.1 LLVM的基本设计原理及其历史 26
3.2 理解目前的LLVM 27
3.3 与编译器驱动程序交互 29
3.4 使用独立工具 30
3.5 深入LLVM内部设计 33
3.5.1 了解LLVM的基本库 33
3.5.2 介绍LLVM的C++惯例 34
3.5.3 演示可插拔的流程接口 37
3.6 编写你的第一个LLVM项目 38
3.6.1 编写Makefile 38
3.6.2 编写代码 40
3.7 关于LLVM源代码的一般建议 41
3.7.1 将代码理解为文档 42
3.7.2 请求社区的帮助 42
3.7.3 应对更新:使用SVN日志作为文档 42
3.7.4 结束语 44
3.8 总结 44
第4章 前端 45
4.1 Clang简介 45
4.1.1 前端操作 46
4.1.2 库 47
4.1.3 理解Clang诊断 49
4.2 Clang前端阶段介绍 52
4.2.1 词法分析 52
4.2.2 语法分析 58
4.2.3 语义分析 63
4.2.4 生成LLVM IR代码 65
4.3 完整的例子 65
4.4 总结 68
第5章 LLVM中间表示 69
5.1 概述 69
5.2 操作IR格式的基本工具示例 71
5.3 LLVM IR语法介绍 71
5.4 编写自定义的LLVM IR生成器 76
5.4.1 构建和运行IR生成器 79
5.4.2 使用C++后端编写代码来生成IR构造 80
5.5 在IR层执行优化 80
5.5.1 编译时优化和链接时优化 80
5.5.2 发现最佳编译器流程 82
5.5.3 流程间的依赖关系 83
5.5.4 了解流程API 85
5.5.5 自定义流程 85
5.6 总结 89
第6章 后端 90
6.1 概述 90
6.2 后端代码结构介绍 92
6.3 后端库介绍 93
6.4 如何使用TableGen实现LLVM后端 94
6.4.1 TableGen语言 95
6.4.2 代码生成器.td文件介绍 96
6.5 指令选择阶段介绍 100
6.5.1 SelectionDAG类 100
6.5.2 降级 102
6.5.3 DAG合并以及合法化 103
6.5.4 DAG到DAG指令选择 104
6.5.5 指令选择过程可视化 107
6.5.6 快速指令选择 107
6.6 调度器 107
6.6.1 指令执行进程表 108
6.6.2 竞争检测 109
6.6.3 调度单元 109
6.7 机器指令 109
6.8 寄存器分配 110
6.8.1 寄存器合并器 111
6.8.2 虚拟寄存器重写 114
6.8.3 编译目标的信息 115
6.9 前序代码和结束代码 116
6.10  机器代码框架介绍 116
6.10.1  MC指令 116
6.10.2  代码输出 117
6.11  自定义机器流程 119
6.12 总结 121
第7章 即时编译器 122
7.1 LLVM JIT引擎的基础知识介绍 122
7.1.1 介绍执行引擎 123
7.1.2 内存管理 124
7.2 llvm::JIT框架介绍 124
7.2.1 将二进制大对象写入内存 125
7.2.2 使用JITMemoryManager 125
7.2.3 目标代码输出器 125
7.2.4 目标信息 127
7.2.5 学习如何使用JIT类 127
7.3 llvm::MCJIT框架介绍 131
7.3.1 MCJIT引擎 131
7.3.2 MCJIT中模块编译过程 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 总结 139
第8章 跨平台编译 140
8.1 GCC和LLVM对比 140
8.2 目标三元组介绍 141
8.3 准备自己的工具链 142
8.3.1 标准C/C++库 143
8.3.2 运行时库 143
8.3.3 汇编器和链接器 144
8.3.4 Clang前端 144
8.4 用Clang命令行参数进行交叉编译 145
8.4.1 针对目标的驱动程序选项 145
8.4.2 依赖包 145
8.4.3 交叉编译 146
8.4.4 更改系统根目录 148
8.5 生成Clang交叉编译器 149
8.5.1 配置选项 149
8.5.2 构建和安装基于Clang的交叉编译器 149
8.5.3 其他构建方法 150
8.6 测试 151
8.6.1 开发板 151
8.6.2 模拟器 151
8.7 其他资源 152
8.8 总结 152
第9章 Clang静态分析器 153
9.1 静态分析器的作用 153
9.1.1 传统警告信息和Clang静态分析器比较 153
9.1.2 符号执行引擎的高效性 156
9.2 测试静态分析器 158
9.2.1 使用驱动程序与使用编译器 158
9.2.2 了解可用的检查器 158
9.2.3 在Xcode IDE中使用静态分析器 160
9.2.4 生成HTML格式的图形
9.2.5 处理大型项目 161
9.3 使用自定义的检查器扩展静态分析器 164
9.3.1 熟悉项目架构 164
9.3.2 自定义检查器 165
9.4 其他资源 173
9.5 总结 174
第10章 基于LibTooling的Clang工具 175
10.1 生成编译命令数据库 175
10.2 clang-tidy工具 176
10.3 代码重构工具 178
10.3.1 Clang Modernizer(代码转换器) 178
10.3.2 Clang Apply Replacements(替换执行器) 178
10.3.3 ClangFormat (格式化工具) 180
10.3.4 Modularize(模块化工具) 181
10.3.5 Module Map Checker(模块映射检查器) 187
10.3.6 PPTrace(追踪工具) 187
10.3.7 Clang Query(查询工具) 189
10.3.8 Clang Check(检查工具) 190
10.3.9 remove-cstr-calls(调用移除工具) 190
10.4 编写自己的工具 190
10.4.1 问题定义:编写一个C++代码重构工具 191
10.4.2 配置源代码位置 191
10.4.3 剖析工具的模板代码 192
10.4.4 使用AST匹配器 195
10.4.5 编写回调函数 199
10.4.6 测试编写的重构工具 200
10.5 其他资源 201
10.6 总结 201
索引 202

教学资源推荐
作者: (美)利迪(Leedy,P.D.),(美)奥姆罗德(Ormrod,J.E.)
作者: (美)丹尼斯·布伊德(Denise Boyd) 海伦·比(Helen Bee)著
作者: (美)罗伯特 J.格雷戈里(Robert J.Gregory)伊利诺伊州威顿学院 著
作者: (美)德博拉 C.贝德尔 (Deborah C. Beidel)中佛罗里达大学辛西娅 M. 布利克(Cynthia M. Bulik)北卡罗来纳大学教堂山分校梅琳达&
参考读物推荐
作者: 庄晓丹
作者: (美)杰弗里·伯恩斯坦 (Jeffrey Bernstein) 著
作者: [美]戴夫·格雷(Dave Gray) 著
作者: [美]大卫·艾尔曼(Dave Elman) 著