湖南大学SCCI并行计算组-LLVM Clang AST 02-使用libclang(C Routine)操作AST

Clang官网
Clang AST官网简介


湖南大学 SCCI 并行计算组
LLVM Clang AST 02
使用 libclang (C Routine) 操作 AST

使用 Cursor 访问 AST

总头文件
clang-c/Index.h

总依赖库
libclang.a
or
libclang.so


1. CXCursor 类型

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() 例程

clang_getCursor例程官网解释

该例程可以获得从源代码的位置映射到解析后的 AST 的 Cursor。

函数名
clang_getCursor

函数原型

CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation SL) 


4.clang_getCursorExtent() 例程

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例程官网解释.

函数名

clang_getRangeStart

函数原型

CXSourceLocation clang_getRangeStart(CXSourceRange  range) 

4.2 clang_getRangeEnd() 例程

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() 例程

clang_getCursorSpelling例程官网解释

该例程用于返回指定 Cursor 的名称。

函数名
clang_getCursorSpelling

函数原型

CXString clang_getCursorSpelling(CXCursor Cursor) 


7. clang_getCursorKind() 例程

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值