
用 LLVM/Clang LibTooling 编写 C++ 静态分析工具,核心是绕过编译器前端黑盒,直接在 AST 层做语义检查——不是靠正则或字符串匹配,而是真正理解代码结构、类型、作用域和控制流。
一、环境准备:不是装个 clang 就够了
LibTooling 是 LLVM 的 C++ 库接口,必须从源码构建(或使用预编译的 libclang-dev + libc++-dev + llvm-dev 包),仅装 clang 命令行工具无法链接 libTooling。推荐方式:
- Ubuntu/Debian:安装
llvm-dev、libclang-1x-dev(x ≥ 14)、libc++-dev,确保llvm-config和clang++版本一致 -
macOS(Homebrew):
brew install llvm,然后用$(brew --prefix llvm)/bin/clang++编译,链接时指定-lclangTooling -lclangFrontend -lclangSerialization -lclangDriver -lclangAST -lclangParse -lclangSema -lclangLex -lclangBasic -lLLVM - 关键验证:运行
llvm-config --libs tooling frontend ast parse sema看是否输出对应库名
二、最小可运行分析器:从 MatchFinder 入手
别一上来就写 ASTConsumer;用 clang::ast_matchers + MatchFinder 是最稳妥的起点——它把 AST 遍历封装成声明式规则,避免手动递归、生命周期管理出错。
- 定义 matcher:比如找所有调用
std::strcpy的地方:callExpr(callee(functionDecl(hasName("strcpy")))) - 注册回调:继承
MatchCallback,重写run(const MatchResult &),用Result.Nodes.getNodeAs<callexpr>("expr")</callexpr>提取节点 - 注意上下文:
run()中拿到的是 const 节点指针,不能改 AST;如需修改(如自动修复),得用ASTRewriter+SourceManager定位位置并生成新文本
三、超越语法匹配:接入语义信息
单纯匹配函数名没意义。真正静态分析要结合类型、值流、控制流:
标签: js 前端 json node 编码 ubuntu 工具 mac ai c++ macos vs code 作用域 co
还木有评论哦,快来抢沙发吧~