添加编译警告,除了使用上文 开发 clang 插件:0 基础感受底层组 提到的 clang 插件 ,
也可以直接开发 clang
1, 开发 clang,使用 ninja ,才能保证正常的开发速度
使用 Xcode 编译 clang, 就慢了
可以使用 ninja + Xcode 配合开发
使用 Xcode 的代码自动补全、代码提示、编译检查、函数跳转,方便
1.1 安装 ninja
采用 ninja 构建
- 检查安装了没有
brew list | grep ^ninja
- 去安装
brew install ninja
1.2 下载工程
下载 llvm-project
git clone https://github.com/llvm/llvm-project
1.3 代码生成与编译
这一步,会在后面反复使用,简称为 job_O
- 使用 Ninja 生成 llvm 项目
进入
cd /Users/jzd/Movies/A_B/llvm-projectX
等价于
cd /yourPath/llvm-project
代码生成
cmake -S llvm -B build -G Ninja -DLLVM_ENABLE_PROJECTS="clang;libcxx;libcxxabi"
- 项目编译
cd /Users/jzd/Movies/A_B/llvm-projectX/build
ninja clang
效果:
➜ build git:(main) ninja clang
[3345/3345] Creating executable symlink bin/clang
补充: Xcode 相关,见上文
1.4 本文的例子是,检查 if 语句的过度嵌套
看下效果,简单的 if 判断,不报错
复杂的,才报错
要解决的问题
怎样算复杂? 至少 3 层不同操作符,计算的嵌套
最后的效果
2. clang 开发,阶段一,识别 if 语句的 AST, 和简单的 warning 处理
添加 if 语句过度嵌套的编译警告
来一小段,编译原理
编译啊,预处理,语法分析,词法分析,语义分析,拿到 AST
拿到完整的抽象语法树,分析 if 的节点,是不是过于复杂
-
先对代码进行解析,parse
-
再语义分析,semantic analysis
2.1 定位到 clang 源代码,对 AST 中的 if 节点,写日志
定位到语义分析文件
/Users/jzd/Movies/A_B/llvm-projectX/clang/lib/Sema/SemaStmt.cpp
里面的这个方法,IF statement
添加两行日志代码,代码生成与编译,就是 job_O
补充: 怎么定位到的,可以看我在 CSDN 的笔记 clang 学习辅助
StmtResult Sema::ActOnIfStmt(SourceLocation IfLoc, bool IsConstexpr,
SourceLocation LParenLoc, Stmt *InitStmt,
ConditionResult Cond, SourceLocation RParenLoc,
Stmt *thenStmt, SourceLocation ElseLoc,
Stmt *elseStmt) {
//...
// 添加下面两句
llvm:: dbgs() << "处于 ActOnIfStmt, 发现了 if 条件判断 \n";
CondExpr->dump();
return BuildIfStmt(IfLoc, IsConstexpr, LParenLoc, InitStmt, Cond, RParenLoc,
thenStmt, ElseLoc, elseStmt);
}
2.1.1, 看简单效果
- 上例子
➜ build git:(main) ✗ cat /Users/jzd/Movies/A_a/Clang/proj/collect/999998/999998/test.cpp
代码很简单
void test(int a, int b){
if (a > 0 && b > 0){
}
}
- 命令, ( 这一步,调试频繁,下文简称为 job_debug )
➜ build git:(main) ✗ /Users/jzd/Movies/A_B/llvm-projectX/build/bin/clang -c /Users/jzd/Movies/A_a/Clang/proj/collect/999998/999998/test.cpp
dump 到的 AST
处于 ActOnIfStmt, 发现了 if 条件判断
BinaryOperator 0x7fe8e9075ea0 '_Bool' '&&'
|-BinaryOperator 0x7fe8e9075e08 '_Bool' '>'
| |-ImplicitCastExpr 0x7fe8e9075df0 'int' <LValueToRValue>
| | `-DeclRefExpr 0x7fe8e9075db0 'int' lvalue ParmVar 0x7fe8e9075b68 'a' 'int'
| `-IntegerLiteral 0x7fe8e9075dd0 'int' 0
`-BinaryOperator 0x7fe8e9075e80 '