湖南大学 SCCI 并行计算组
LLVM Clang AST 02
使用 libclang (C Routine) 操作 AST
LLVM Clang AST 02
使用 libclang (C Routine) 操作 AST
总头文件
clang-c/Index.h
总依赖库
libclang.a
or
libclang.so
1. CXCursor 类型
CXCursor 类型为 TranslationUnit AST中某个节点的游标。
游标的常见操作包括:
- 获取 Cursor 指向的源文件中的物理位置,
- 获取与 Cursor 关联的名称,
- 获得某个特定 Cursor 的任何子节点的 Cursor。
CXCursor 定义
typedef struct{
enum CXCursorKind kind;
int xdata;
const void * data[3];
}CXCursor;
游标可以通过 clang_getTranslationUnitCursor() 例程为 TranslationUnit 生成一个 Cursor ;也可以进一步使用 clang_visitChildren例程获得 Cursor 子节点的 Cursor。
CXCursorKind 含义
该类型是一个枚举类型,用来描述Cursor的类型。比如有:
- CXCursor_FunctionDecl:一个函数节点
- CXCursor_VarDecl:一个变量节点
- CXCursor_ParmDecl:一个参数节点
2. clang_getTranslationUnitCursor() 例程
clang_getTranslationUnitCursor例程官网解释
该例程用于获得一个 TranslationUnit 的 Cursor(游标),该 Cursor 可用于开始遍历给定 TranslationUnit 内的各个节点。
函数名
clang_getTranslationUnitCursor
函数原型
CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU)
3. clang_getCursor() 例程
该例程可以获得从源代码的位置映射到解析后的 AST 的 Cursor。
函数名
clang_getCursor
函数原型
CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation SL)
4.clang_getCursorExtent() 例程
该例程用于获得给定Cursor所代表的源代码的物理范围。
函数名
clang_getCursorExtent
函数原型
CXSourceRange clang_getCursorExtent(CXCursor Cursor)
该例程需要配合 clang_getRangeStart 和 clang_getRangeEnd 例程使用。
CXSourceRange
CXSourceRange官网解释
类型定义:
typedef struct {
const void *ptr_data[2];
unsigned begin_int_data;
unsigned end_int_data;
} CXSourceRange;
4.1 clang_getRangeStart() 例程
函数名
clang_getRangeStart
函数原型
CXSourceLocation clang_getRangeStart(CXSourceRange range)
4.2 clang_getRangeEnd() 例程
函数名
clang_getRangeEnd
函数原型
CXSourceLocation clang_getRangeEnd(CXSourceRange range)
5. clang_getSpellingLocation()例程
该例程用于获取由给定 CXSourceLocation 的文件、行、列和偏移量。注意,偏移量指的是当前CXSourceLocation对应的源码位置与源码起始开头的偏移字符数(包括空格)。
函数名
clang_getSpellingLocation
函数原型
void clang_getSpellingLocation
(
CXSourceLocation location, //[in]
CXFile * file, //[out]
unsigned * line, //[out]
unsigned * column, //[out]
unsigned * offset //[out]
)
6. clang_getCursorSpelling() 例程
该例程用于返回指定 Cursor 的名称。
函数名
clang_getCursorSpelling
函数原型
CXString clang_getCursorSpelling(CXCursor Cursor)
7. clang_getCursorKind() 例程
该例程用于返回指定 Cursor 的 CursorKind。
函数名
clang_getCursorKind
函数原型
CXCursorKind clang_getCursorKind(CXCursor Cursor)
该例程通常需要配合clang_isXxxxxx()例程使用(见官网资料),如:
unsigned clang_isDeclaration(CXCursorKind CK)
unsigned clang_isReference(CXCursorKind CK)
unsigned clang_isTranslationUnit(CXCursorKind CK)
8.clang_getCursorKindSpelling()例程
clang_getCursorKindSpelling例程官网解释
该例程用于返回指定 CursorKind 的 名字字符串。
函数名
clang_getCursorKindSpelling
函数原型
CXString clang_getCursorKindSpelling(CXCursorKind CK)
到此我们能写一个打印 Cursor 结点对应的源码地址的工具了,如下:
int SCCICOMPLIER_printSourceLocation(CXCursor Cursor)
{
CXString CursorName = clang_getCursorSpelling(Cursor);
enum CXCursorKind curKind = clang_getCursorKind(Cursor);
CXString CursorKindName= clang_getCursorKindSpelling(curKind);
CXString CursorKindName= clang_getCursorKindSpelling(curKind);
CXSourceRange range = clang_getCursorExtent(Cursor);
CXSourceLocation startLocation = clang_getRangeStart(range);
CXSourceLocation endLocation = clang_getRangeEnd(range);
CXFile file;
unsigned s_line;
unsigned s_column;
unsigned s_offset;
unsigned e_line;
unsigned e_column;
unsigned e_offset;
clang_getSpellingLocation(startLocation,&file,&s_line,&s_column,&s_offset);
clang_getSpellingLocation(endLocation,&file,&e_line,&e_column,&e_offset);
printf( "==================This Cursor===================\n"
"= Name: %s\n"
"= Type: %s\n"
"= Location: [line:%d,col:%d] to [line:%d,col:%d]\n"
"= Range: %d\n"
"------------------------------------------------\n",
clang_getCString(CursorName),
clang_getCString(CursorKindName),
s_line,s_column,e_line,e_column,
e_offset-s_offset);
return 0;
}