iOS编译器

Objective-C 和 Swift都是编译语言

编译语言在执行的时候,必须先通过编译器生成机器码

CPU执行机器码

LLVM 编译编译语言

LLVM 是一个模块化和可重用的编译器和工具链技术的集合

LLVM 核心库提供一个优化器,对流行的 CPU 做代码生成支持

Clang 是 LLVM 的子项目,是 C,C++ 和 Objective-C 编译器

clang static analyzer 主要是进行语法分析,语义分析和生成中间代码,对代码进行检查,出错的和需要警告的会标注出来。

lld 是 Clang / LLVM 的内置链接器,clang 必须调用链接器(lld)来产生可执行文件

1,编译源文件的时候,编译器首先做的是一些预处理工作。比如预处理器会处理源文件中的宏定义,将代码中的宏用其对应定义的具体内容进行替换。

扫描二维码关注公众号,回复: 2018187 查看本文章

2,.m 源文件里都有一堆的声明和定义,这些代码文本都会从string 转化成特殊的标记流,每一个标记流都包含了对应的 源码内容 和在源码中的位置.

注意这里的位置是宏展开之前的位置,这样一来,如果编译过程中遇到什么问

题,clang 能够在源码中指出出错的具体位置

3,标记流将会被解析成一棵抽象语法树 (abstract syntax tree -- AST),在抽象语法树中的每个节点都标注了其对应源码中的位置,同样的,如果产生了什么问题,clang 可以定位到问题所在处的源码位置.

4,一旦编译器把源码生成了抽象语法树,编译器可以对这棵树做分析处理,以找出代码中的错误,比如类型检查:即检查程序中是否有类型错误。例如:如果代码中给某个对象发送了一个消息,编译器会检查这个对象是否实现了这个消息(函数、方法)。此外,clang 对整个程序还做了其它更高级的一些分析,以确保程序没有错误。

细化:

类型检查(动态的和静态的)

每当开发人员编写代码的时候,clang 都会帮忙检查错误。其中最常见的就是检查程序是否发送正确的消息给正确的对象,是否在正确的值上调用了正确的函数。如果你给一个单纯的 NSObject* 对象发送了一个 hello 消息,那么 clang 就会报错。同样,如果你创建了 NSObject 的一个子类 Test,然后试图给这个子类中某个属性设置一个与其自身类型不相符的对象,编译器会给出

一个可能使用不正确的警告

动态的在运行时做检查,静态的在编译时做检查。以往,编写代码时可以向任意对象发送任何消息,在运行时,才会检查对象是否能够响应这些消息。由于只是在运行时做此类检查,所以叫做动态类型。

静态类型,是在编译时做检查。当在代码中使用 ARC 时,编译器在编译期间,会做许多的类型检查:因为编译器需要知道哪个对象该如何使用。例如,如果 myObject没有 hello 方法,那么就不能写如下这行代码

clang 在静态分析阶段,除了类型检查外,还会做许多其它一些分析。如果你把 clang的代码仓库 clone 到本地,然后进入目录 lib/StaticAnalyzer/Checkers,你会看到所有静态检查内容。比如 ObjCUnusedIVarsChecker.cpp 是用来检查是否有定义了,但是从未使用过的变量。而 ObjCSelfInitChecker.cpp 则是检查在 你的初始化方法中中调用

self 之前,是否已经调用 [self initWith...] 或 [super init] 了。编译器还进行了一些其它的检查,例如在 lib/Sema/SemaExprObjC.cpp 的 2,534 行,有这样一句:Diag(SelLoc, diag::warn_arc_perform_selector_leaks);这个会生成严重错误的警告 “performSelector may cause a leak because its selector

is unknown” 。

5,clang 完成代码的标记,解析和分析后,接着就会生成 LLVM 代码。

6,LVVM优化器会进行BitCode的生成,链接期优化等等。

 手机执行IPA包的简单过程

一个手机,拿到IPA包里面的OC代码之后,编译器Clang进行编译链接成机器语言后,在手机显示屏中显示,

Xcode执行源代码的简单过程

Xcode软件里面有个编译器(clang)把项目里面的代码资源编译成机器语言后,利用mac电脑的CPU来执行机器语言,然后在通过模拟器显示.

猜你喜欢

转载自www.cnblogs.com/zhangmazi/p/9286802.html