关于llvm-clang用ASTMatcher查找全局变量的一点心得

论坛 期权论坛 脚本     
匿名技术用户   2021-1-4 18:02   111   0

这学期在软件体系结构课上,被要求基于llvm-clang进行二次开发,查找项目中的全局变量,以及全局变量被调用的相关函数。本来传统思路是写一个checker来完成这个任务,但机缘巧合下了解到ASTMatcher可以作为一个很好的替代方案。由于与ASTMatcher相关的中文资料甚少,所以写下此博客,以记录本蒻的艰辛历程。由于是对学习过程加以记录,如果出现错误和纰漏还请见谅。

llvm-clang作为c/c++的编译器前端,基本工作是进行词法分析、语法分析,生成抽象语法树(AST)。此后将AST交由llvm作为后端进行处理,经由转换成中间代码、代码优化,最后交由与机器相关的底层模块生成相应的可执行文件。其中,抽象语法书AST作为语法分析的结果,包含了源代码所含有的全部信息。

针对具体需求而言,要查找全局变量,可以利用AST查找变量定义的节点(varDecl),且该节点不能有函数定义的父节点(functionDecl)。对于查找AST中节点的操作,clang的开发者提供了很便利的工具ASTMatcher以供使用。关于ASTMatcher的使用方法,请见官方文档如下:

ASTMatcher使用向导:https://clang.llvm.org/docs/LibASTMatchersTutorial.html

ASTMatcher参考文档:https://clang.llvm.org/docs/LibASTMatchersReference.html#narrowing-matchers

在第一篇文档中详细的介绍了如何建立一个自己的ASTMatcher工具以供使用,第二篇文档中则包含了ASTMatcher节点匹配过程中可能用到的匹配规则。例如要匹配全局变量的定义节点,我的匹配器构建如下:

DeclarationMatcher GlobalVarMatcher = varDecl(
hasGlobalStorage(), unless(hasAncestor(functionDecl()))

).bind("gvar");

在建立好匹配器之后,还需要继承MatchFinder::MatchCallback类,重写run方法,作用是确定匹配到节点之后如何使用。最后在main函数中调用写好的匹配器即可完成AST的节点匹配。

……

项目进行中,有时间的时候就来更新吧~~~

/**************更新的分割线**************/

最近有被同学问到如何在clang中去配置一个ASTMatcher,因为文档写的是在linux下的配置,和windows的配置方法有所出入,所以我把配置方法更新在下面:

1.在windows下下载llvm以及clang源码。具体步骤是下载llvm以及clang的源码,然后在clang/tools下git clone https://github.com/llvm-mirror/clang-tools-extra extra。即把clang-tools-extra的源码下载到clang/tools/extra目录下。

2.按照文档所述的步骤新建一个loop-convert文件夹,一个LoopConvert.cpp,并把CMakeLists.txt写好(详见第一篇文档)。这里的CMakeLists.txt包括loop-convert文件夹下的以及extra文件夹下的。写CMakeLists.txt的作用是给cmake工具构建工程提供依据。

3.cmake。在llvm根目录下新建一个build文件夹,在build文件夹下生成项目。我是用的visual studio 2017构建的项目,所以执行的指令是cmake visual studio 15 2017 ../lvm。针对其他的版本,可以通过cmake --help查看。

4.生成项目之后就可以用vs编译项目了,经过漫长的等待,编译完成后,大家就能在LLVM.sln下找到loop-convert子项目,即大家自己构建的ASTMatcher子项目。在之后的编码中,只需要生成loop-convert子项目即可(不是重新生成,是生成)。我自己的机器上每次生成用时不过数秒。

/************************我又是更新分割线**************************/

有人问道cmakelist怎么写,官方文档里给的有点问题,和原llvm的配置有冲突,所以稍作修改:

这是loop-convert文件夹下的CMakeList.txt(文件名字改一下就好了。。。)

set(LLVM_LINK_COMPONENTS support)

add_clang_executable(match-global-variable
MatchGlobalVariable.cpp
)
target_link_libraries(match-global-variable PRIVATE
clangTooling
clangBasic
clangASTMatchers

)

在extra文件夹下的CMakeList.txt中加上一句add_subdirectory(match-global-variable)就好了。







分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:7942463
帖子:1588486
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP