• Clang AST 学习(四):使用libclang (C Routine) 操作 AST


    Clang官网
    Clang AST官网简介


    Clang AST 学习(四):使用libclang (C Routine) 操作 AST

    访问AST子结点

    总头文件
    clang-c/Index.h

    总依赖库
    libclang.a
    or
    libclang.so


    1. CXCursorVisitor类型的例程

    CXCursorVisitor类型官方解释

    CXCursorVisitor类型定义

    typedef enum CXChildVisitResult (*CXCursorVisitor)(CXCursor cursor, CXCursor parent, CXClientData client_data);
    
    • 1

    这是一个 Function 的类型定义,目的是用 CXCursorVisitor 作为这一系列函数的类型,简化函数写法,可以便于作为其他Function的参数使用。

    2. CXChildVisitResult类型的枚举

    CXChildVisitResult类型官方解释

    CXCursorVisitor类型定义

    enum CXChildVisitResult
    {
    	//终止游标遍历
    	CXChildVisit_Break,
    	
    	//继续遍历其兄弟结点
    	CXChildVisit_Continue,
    	
    	//递归遍历该游标的子结点, 使用相同的访问者和客户端数据。
    	CXChildVisit_Recurse
    };
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    该枚举类型的值,用来控制clang_visitChildren例程的访问模式。

    3. clang_visitChildren() 例程

    clang_visitChildren例程官方解释

    函数名
    clang_visitChildren()

    函数原型

    unsigned clang_visitChildren
    (   
    	CXCursor         parent, 
    	CXCursorVisitor  visitor, 
    	CXClientData     client_data
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    参数

    • CXCursor parent
      给定的 Cursor

    • CXCursorVisitor visitor
      给定的函数 visitor,该函数的参数列表必须符合 CXCursorVisitor 函数类型。

    • CXClientData client_data
      尚不清楚

    详细解释
    该例程为给定 Cursor(即参数列表第一个参数,parent)的所有子结点都调用传入的 CXCursorVisitor 类型的函数 visitor,每个子节点都将完成给定 visitor 函数的内容。

    enum CXChildVisitResult HelloCursor(CXCursor cursor, CXCursor parent, CXClientData client_data)
    {
    	CXString CursorName = clang_getCursorSpelling(Cursor);
    	CXString parentName = clang_getCursorSpelling(parent);
    	printf("Hello! I am %s,my father is %s\n",clang_getCString(CursorName),clang_getCString(parentName));
    	
    	//用来控制是否继续遍历,以及怎么遍历。遍历所有兄弟结点用CXChildVisit_Continue,递归遍历所有子节点用CXChildVisit_Recurse,不接着遍历了用CXChildVisit_Break
    	return CXChildVisit_Continue;
    }
    
    
    int main(int argc, char ** argv)
    {
    	//创键TransactionUnit所需的上下文环境
    	CXIndex Index = clang_createIndex(0,0);
    	
    	//解析代码,并获得对应的TransactionUnit
        CXTranslationUnit TU =clang_parseTranslationUnit(Index,NULL,argv,argc,0,0,CXTranslationUnit_None);
        
        //从TU中获取Cursor
    	CXCursor Cursor = clang_getTranslationUnitCursor(TU);
        
    	//访问Cursor的子结点,每个子结点调用HelloCursor函数
        clang_visitChildren(Cursor, HelloCursor, NULL);
    
        //销毁TransactionUnit
        clang_disposeTranslationUnit(TU);
    
        //销毁Index
        clang_disposeIndex(Index);
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33


  • 相关阅读:
    CCF CSP认证 历年题目自练Day30
    你真的看懂扩散模型(diffusion model)了吗?(从DALL·E 2讲起,GAN、VAE、MAE都有)
    C#语言进阶(三) 元组
    Linux高性能服务器编程——ch1笔记
    01 使用docker搭建wordpress博客网站
    React Native 环境配置(mac)
    WiFi模块引领零售数字化转型:智能零售体验再定义
    C# I/O流: FileStream
    Request
    投稿期刊选择-中科院期刊分区排名查询(以光学类为例) -论文投稿经验总结-第2期
  • 原文地址:https://blog.csdn.net/E2MCC/article/details/125444665