匹配ClangAST
介绍如何使用Clang
的LibASTMatchers
来匹配AST
的有趣节点,并执行使用匹配节点
的代码.结合LibTooling
这里,LibASTMatchers
帮助编写代码到代码
转换或查询工具.
假定你对ClangAST
有基本了解.如果想了解有关AST
结构的更多信息,见ClangAST
简介.
介绍
在Clang
的AST
上,LibASTMatchers
提供了领域相关语言
创建判定
.该DSL
是用C++
编写的,可在C++
中使用,允许用户编写程序
来匹配AST
节点,并访问节点的C++
接口以提取
属性,源位置
或AST
级别的其他信息
.
AST
匹配器是AST
中节点上的判定
.匹配器
是调用,允许构建
内部用来使匹配
更具体的匹配器树
的创建者
函数创建的.
如,要创建
与翻译单元的AST
中的所有类或联声明
匹配的匹配器,可调用recordDecl()
这里.
要缩小
匹配区间,如,要查找
名字叫"Foo"
的所有类或联声明
,请插入hasName
匹配器:调用recordDecl(hasName("Foo"))
返回一个与名字空间
中名字为"Foo"
的类或联
匹配的匹配器.
默认,接受多个内部
匹配器的匹配器使用隐式allOf()
这里.
这允许进一步缩小匹配区间
,如匹配从"Bar"
继承的所有类:
recordDecl(hasName("Foo"), isDerivedFrom("Bar"))
如何创建匹配器
ClangAST
中有一千多个
类,在试弄清如何为指定模式
创建匹配器时,很快就会迷失
方向.这里为如何用严格步骤
模式来构建
感兴趣的匹配器.
注意,AST
某些部分总是会缺少
匹配器.
先要了解要匹配
内容的AST
的外观.ClangAST
简介有如何按人类可读格式转储
翻译单元的AST
.
一般,创建正确
匹配器策略
是:
1,在Clang
的AST
中,找到要匹配
的最外层类
.
2,查看AST
匹配器参考,了解匹配感兴趣的节点
或缩小节点属性区间
的匹配器.
3,创建外部匹配式
.验证是否按期望
工作.
4,检查
匹配器,了解要匹配
的下个内部节点
.
5,重复上述步骤,直到完成匹配器
.
在匹配式中绑定节点
对指定任务
,匹配器式
允许指定感兴趣的AST
部分.一般,需要处理匹配
节点,如构建源码转换
.
为此,可绑定匹配
指定AST
节点的匹配器(即节点匹配器
);如,
recordDecl(hasName("MyClass")).bind("id")
会绑定匹配recordDecl
节点到稍后在匹配回调
中提取的"id"
串.回调
编写自己的匹配器
根据类型和灵活性
,有多种不同方法
可定义匹配器.
VariadicDynCastAllOfMatcher<Base, Derived>
如果可把Base
类型节点,动态
转换为Derived
,则会匹配所有Base
节点.与Derived
类似,这些匹配器名
是名词.
VariadicDynCastAllOfMatchers
是匹配器层次的主干.一般,从其中一个可把表示它们的节点
绑定到id
,以便以后处理的式开始
匹配.
VariadicDynCastAllOfMatchers
是按C++03
变参模板函数建模
的可调用
类.它可带任意多个Matcher<Derived>
并返回Matcher<Base>
.
AST_MATCHER_P(Type, Name, ParamType, Param)
大多数匹配器,用匹配器创建宏
来定义
.它们定义了Matcher<Type>
类型的匹配器自身
,及叫Name
的带ParamType
类型参数并返回相应匹配器
的匹配器创建函数
.
有多个
匹配器定义宏,来处理多态返回值
及不同的参数个数
.见ASTMatchersMacros.h
这里.
匹配器创建函数
通过嵌套
调用匹配器创建函数
生成匹配器
.一般,这些函数是使用VariadicDynCastAllOfMatcher
或匹配器创建宏
创建的.
如被调,独立函数
表明此匹配器
只是其他
匹配器的组合.