在学习OCLint自定义规则的过程中对AST的一些总结

最近在学习自定义规则的时候了解了一下Clang和一些编译知识,就写了一下总结。

Clang和LLVM

不论是OC还是Swift,都是Clang作为编译器前端,LLVM(Low Level Virtual Machine)作为编译器后端。

编译器前端

编译器前端会对代码进行预处理,进行词法分析(Lexical analysis),语法分析(Parsing),生成中间码(生成AST)然后根据CodeGen生成LLVM IR。 编译器后端会把前端输出的LLVM IR进行优化,然后生成机器码,最终生成Mach-O。 OCLint就是依赖于AST进行规制检查的。举个栗子:

31   int main(int i) {
32      if (i<0) {
33         return -i;
34       }
35   return i;
36   }
复制代码

在终端运行clang -Xclang -ast-dump -fsyntax-only $PATH会log出一大堆东西,我们截取了最后一段

`-FunctionDecl 0x7f916b5407f8 <PATH.m:31:1, line:36:1> line:31:5 main 'int (int)'
|-ParmVarDecl 0x7f916b540770 <col:10, col:14> col:14 used i 'int'
`-CompoundStmt 0x7f916b540a50 <col:17, line:36:1>
|-IfStmt 0x7f916b5409c8 <line:32:5, line:34:5>
| |-<<<NULL>>>
| |-BinaryOperator 0x7f916b540908 <line:32:9, col:11> 'int' '<'
| | |-ImplicitCastExpr 0x7f916b5408f0 <col:9> 'int' <LValueToRValue>
| | | `-DeclRefExpr 0x7f916b5408a8 <col:9> 'int' lvalue ParmVar 0x7f916b540770 'i' 'int'
| | `-IntegerLiteral 0x7f916b5408d0 <col:11> 'int' 0
| |-CompoundStmt 0x7f916b5409a8 <col:14, line:34:5>
| | `-ReturnStmt 0x7f916b540990 <line:33:9, col:17>
| |   `-UnaryOperator 0x7f916b540970 <col:16, col:17> 'int' prefix '-'
| |     `-ImplicitCastExpr 0x7f916b540958 <col:17> 'int' <LValueToRValue>
| |       `-DeclRefExpr 0x7f916b540930 <col:17> 'int' lvalue ParmVar 0x7f916b540770 'i' 'int'
| `-<<<NULL>>>
`-ReturnStmt 0x7f916b540a38 <line:35:5, col:12>
`-ImplicitCastExpr 0x7f916b540a20 <col:12> 'int' <LValueToRValue>
`-DeclRefExpr 0x7f916b5409f8 <col:12> 'int' lvalue ParmVar 0x7f916b540770 'i' 'int'
复制代码

以上这一段就是Clang对于main函数解析成的AST。里面有两种类型节点。一种是Stmt(Statement),另外一种是Decl(Declaration)。Stmt很明显,就是表达式的节点,具有操作性,比如CompoundStmt对应的{},ifstmt对应if,以上所有的Operator、Expr、Literal结尾的都是stmt的子类。Decl就对应的var,method,function。 我们可以通过某个节点往下遍历所有节点。比如FucntionDecl往下遍历可以得到ParamVarDeclCompoundStmt,然后通过CompoundStmt可以得到IfStmtReturnStmt.

通过AST我们可以做什么?

1.我们可以通过这些节点做代码扫描。 2.我们可以接管这个过程,然后加入自定义代码。因为AST是属于编译器前端功能,还没有最后翻译成汇编,所以就有改动的余地。具体可以参考阳神的DynamicCocoa,它就是接管了AST,然后将AST利用自己写的Clang插件转换成JS文件。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值