原文
ClangAST
简介
幻灯片
介绍
Clang
的AST
与其他一些编译器
生成的AST
不同,因为它与编写的C++
代码和C++
标准类似.如,在AST
中,按非简化
形式提供括号式和编译时常量
.
这使得Clang
的AST
非常适合重构
.
可通过生成的Doxygen
获得所有ClangAST
节点的文档.搜索引擎也会索引doxygen
的在线文档,它搜索clang
,并且AST
节点的类名
一般会显示要查找类的doxygen
(如,搜索:clangParenExpr
).
检查AST
熟悉ClangAST
的一个好方法是在一些简单示例
代码中,实际查看它.Clang
有可用-ast-dump
标志启用的内置AST-dump
模式.
看看简单AST
示例:
$ cat test.cc
int f(int x) {int result = (x / 42);return result;
}
# Clang by default is a frontend for many tools; -Xclang is used to pass
# options directly to the C++ frontend.
$ clang -Xclang -ast-dump -fsyntax-only test.cc
TranslationUnitDecl 0x5aea0d0 <<invalid sloc>>
... 略clang...
`-FunctionDecl 0x5aeab50 <test.cc:1:1, line:4:1> f 'int (int)'|-ParmVarDecl 0x5aeaa90 <line:1:7, col:11> x 'int'`-CompoundStmt 0x5aead88 <col:14, line:4:1>|-DeclStmt 0x5aead10 <line:2:3, col:24>| `-VarDecl 0x5aeac10 <col:3, col:23> result 'int'| `-ParenExpr 0x5aeacf0 <col:16, col:23> 'int'| `-BinaryOperator 0x5aeacc8 <col:17, col:21> 'int' '/'| |-ImplicitCastExpr 0x5aeacb0 <col:17> 'int' <LValueToRValue>| | `-DeclRefExpr 0x5aeac68 <col:17> 'int' lvalue ParmVar 0x5aeaa90 'x' 'int'| `-IntegerLiteral 0x5aeac90 <col:21> 'int' 42`-ReturnStmt 0x5aead68 <line:3:3, col:10>`-ImplicitCastExpr 0x5aead50 <col:10> 'int' <LValueToRValue>`-DeclRefExpr 0x5aead28 <col:10> 'int' lvalue Var 0x5aeac10 'result' 'int'
翻译单元
中的顶级声明
总是为翻译单元声明
这里.本例中,第一个用户书面声明
是"f"
函数声明."f"
的主体是个复合语句
这里,其子节点是声明
结果变量的声明语句和返回语句.
AST
环境
有关翻译单元
的AST
的所有信息
都绑定在ASTContext
类中.它允许从getTranslationUnitDecl
开始遍历整个翻译单元,或对已解析翻译单元
,访问Clang
的标识表.
AST
节点
Clang
的AST
节点是按没有共同祖先
类层次建模的.相反,(对如Decl
和Stmt
)基本节点类型
有多个
较大的层次1,2.
许多重要的AST
节点从Type,Decl,DeclContext
或Stmt
继承,有些类从Decl
和DeclContext
继承1,2.
AST
中还有许多节点
不属于更大的层次
,只能从指定的其他节点
(如CXXBaseSpecifier
)访问1.
因此,要遍历完整的AST
,需要从TranslationUnitDecl
开始,然后递归遍历
可从该节点
访问的所有内容
,必须针对每个指定节点类型
编码此信息
.
也在RecursiveASTVisitor
这里中编码此算法.见RecursiveASTVisitor
教程.
ClangAST
中的两个最基本节点
是(Stmt)
语句和(Decl)
声明.注意,(Expr)
式也是Clang
的AST
中的语句
.