2312llvm,匹配clang的语法树

原文

匹配ClangAST

介绍如何使用ClangLibASTMatchers来匹配AST的有趣节点,并执行使用匹配节点的代码.结合LibTooling这里,LibASTMatchers帮助编写代码到代码转换或查询工具.

假定你对ClangAST有基本了解.如果想了解有关AST结构的更多信息,见ClangAST简介.

介绍

ClangAST上,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,在ClangAST中,找到要匹配最外层类.
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匹配器创建宏创建的.
被调,独立函数表明此匹配器只是其他匹配器的组合.

猜你喜欢

转载自blog.csdn.net/fqbqrr/article/details/135225979