clang-query 的编译安装与使用示例

发布于:2024-03-28 ⋅ 阅读:(14) ⋅ 点赞:(0)

1,clang query 概述

作用:
检查一个程序源码的抽象语法树,测试 AST 匹配器;
帮助检查哪些 AST 节点与指定的 AST 匹配器相匹配;


2,clang-query 安装


准备:

git clone --recursive https://github.com/llvm/llvm-project.git
cd llvm-project/
git checkout  llvmorg-3.5.0
cp -r ./clang ./llvm/tools/
cp -r clang-tools-extra ./llvm/tools/clang/tools/extra
mkdir build_d ../local_d
cd build_d #其绝对路径为:/home/hipper/llvm_3_4_0_ex/browse/local_d,如下配置所用

配置:

cmake -G "Unix Makefiles"            \
-DCLANG_ENABLE_STATIC_ANALYZER=1     \
-DLLVM_ENABLE_ASSERTIONS=On          \
-DCMAKE_BUILD_TYPE=Debug             \
-DCMAKE_INSTALL_PREFIX=/home/hipper/llvm_3_4_0_ex/browse/local_d   \
-DLLVM_ENABLE_LIBCXX=1               \
-DLLVM_ENABLE_PROJECTS="all"         \
 ../llvm

编译安装:

make -j34
make install
cp bin/clang-query /home/hipper/llvm_3_4_0_ex/browse/local_d/bin/


3,测试运行

待测试程序源代码:
hello.c
 

hello.c

extern int write(int, const char*, unsigned long);

int main(){
    write(1, "Hello, ", 7);
    write(1, "world", 5);
    write(1, "!\n", 2);
    return 0;

}

测试:
 

$ clang-query hello.c --

效果:

识别出函数调用表达式,并打印出来了

4, 更多测试


wildanimal-sim.cpp

class Plane{

public:

int run(int x)
{
    return 10*x;
}

};


class Animal {
public:
  int position;
public:
  Animal(int pos) : position(pos) {}
  // Return new position
  int run(int quantity) {
    return position += quantity;
  }
};
class Cat : public Animal {
public:
  Cat(int pos) : Animal(pos) {}
  void meow() {}
  void destroySofa() {}
  bool wildMood() {return true;}
  int run(int quantity){
    return position += 2*quantity;
  }
};
int main() {
  Cat c(50); c.meow();
  if (c.wildMood())
    c.destroySofa();
  c.run(2);

  Plane pp;
  pp.run(3);
  return 0;
}

可以直接输出 AST 的clang 命令:

clang -Xclang -ast-dump hello.c
clang -cc1 -ast-dump hello.c

clang-query  wildanimal-sim.cpp

测试如下命令:


 

clang-query> set output dump
clang-query> match recordDecl()
clang-query> match methodDecl(hasName("run"))
clang-query> match     recordDecl(isSameOrDerivedFrom(hasName("Animal")))
clang-query> match     recordDecl(allOf(hasMethod(methodDecl(hasName("run"))),   isSameOrDerivedFrom(hasName("Animal"))))


LLVM-18:
 

clang-query> match cxxMemberCallExpr()
clang-query> match cxxMemberCallExpr(callee(memberExpr(member(hasName("run")))))
# not work。 clang-query> match cxxMemberCallExpr(callee(memberExpr(member(hasName("run")))), thisPointerType(recordDecl(isSameOrDerivedFrom(hasName("Animal")))))

LLVM-3.5
 

clang-query> match memberCallExpr()
clang-query> match memberCallExpr(callee(memberExpr(member(hasName("run")))))
clang-query> match memberCallExpr(callee(memberExpr(member(hasName("run")))), thisPointerType(recordDecl(isSameOrDerivedFrom(hasName("Animal")))))

效果

本文含有隐藏内容,请 开通VIP 后查看