http://www.ibm.com/developerworks/cn/opensource/os-cn-clang/
RecursiveASTVisitor,这是一个重要的函数模板。通过介绍这个模板,我们将向您简单介绍遍历抽象语法树的一些基本概念。
RecursiveASTVisitor 是一个深度优先遍历 AST 和访问节点的类。对于一个已经构造好的语法树,它将完成以下三方面的工作:
- 遍历 AST 的每个节点;
- 在某一个节点,访问这个节点的层次结构 ( 每个节点也是一个树 );
- 如果某一个节点是一种类型的动态类别 ( 比如是一个子类等 ),调用一个用户重载的函数来访问这个节点;
上述工作由下面三组方法完成,分别是:
- TraverseDecl(Decl *x) 完成工作 1,它是遍历 AST 的入口。这个方法是用来访问有关变量和函数的声明。TraverseDecl 只是简单的根据节点的类型来调用相应的 TraverseFoo(Foo *x),然后递归访问 x 的子节点。TraverseStmt(Stmt *x) 和 TraverseType(QualType x) 则是用来访问一条语句和一个类型的(如结构体),它们的工作方式和 TraverseDecl 类似。
- WalkUpFromFoo(Foo *x) 完成工作 2。它不会尝试访问 x 的任何子节点,而是先调用 WalkUpFromBar(x),其中 Bar 是 Foo 的直接父类(除非 Foo 没有父类), 然后调用 VisitFoo(x)。
- VisitFoo(Foo *x)完成工作 3。
上述三组方法是分层次的 (Traverse* > WalkUpFrom * > Visit*)。一个方法 ( 如 Traverse*) 可以调用同一层次的方法 ( 例如其他 Traverse*) 或低一层次的方法 ( 如 WalkUpFrom*),它不能调用更高层次的方法。这个结构确保同样类型的 AST 节点会被同时访问,也就是说不会出现交替访问不同节点的情况。
使用方法: 申明一个类A,时期继承模板类RecursiveASTVisitor<A>,当需要访问某种节点时,就重载函数VisitXXX(XXX b)【如VisitNameDecl(NameDecl)】。