当前位置: 首页 > news >正文

2312clang,基于访问者的前端动作

原文

基于RecursiveASTVisitorASTFrontendActions.

创建用RecursiveASTVisitor查找特定名字的CXXRecordDeclAST节点的FrontendAction.

创建FrontendAction

编写基于clang的工具(如Clang插件或基于LibTooling的独立工具)时,常见入口是允许在编译过程中执行用户特定操作的FrontendAction接口.

为了在ASTclang上运行工具,提供了方便的负责执行操作的ASTFrontendAction接口.你只需要实现对每个转换单元返回一个ASTConsumerCreateASTConsumer方法.

class FindNamedClassAction : public clang::ASTFrontendAction {
public:virtual std::unique_ptr<clang::ASTConsumer> CreateASTConsumer(clang::CompilerInstance &Compiler, llvm::StringRef InFile) {return std::make_unique<FindNamedClassConsumer>();}//FindNamedClassAction
};

创建ASTConsumer

ASTConsumer是一个,不管如何生成的AST,在AST编写的通用操作接口.ASTConsumer提供了许多不同的入口,但在此,只需要用ASTContext调用翻译单元HandleTranslationUnit.

class FindNamedClassConsumer : public clang::ASTConsumer {
public:virtual void HandleTranslationUnit(clang::ASTContext &Context) {//通过`RecursiveASTVisitor`遍历翻译单元声明,会访问`AST`中的所有节点.Visitor.TraverseDecl(Context.getTranslationUnitDecl());}
private://`RecursiveASTVisitor`实现.FindNamedClassVisitor Visitor;
};

使用RecursiveASTVisitor

现在已连接了,下一步是实现RecursiveASTVisitor以从AST中提取相关信息.

除了按值传递的TypeLoc节点,RecursiveASTVisitor为大多数AST节点提供bool VisitNodeType(NodeType*)形式的勾挂.只需要为相关节点类型实现方法,就可以了.
首先编写一个访问所有CXXRecordDeclRecursiveASTVisitor.

class FindNamedClassVisitor: public RecursiveASTVisitor<FindNamedClassVisitor> {
public:bool VisitCXXRecordDecl(CXXRecordDecl *Declaration) {//为了调试,转储`AST`节点,会显示已访问的节点.Declaration->dump();//返回值指示是否想继续访问.返回`假`以停止`AST`的遍历.return true;}
};

RecursiveASTVisitor的方法中,现在可用ClangAST全部功能来深入感兴趣部分.如,要查找带特定名字的所有类声明,可检查全名:

bool VisitCXXRecordDecl(CXXRecordDecl *Declaration) {if (Declaration->getQualifiedNameAsString() == "n::m::C")Declaration->dump();return true;
}

访问SourceManagerASTContext

有关AST的某些信息(如源位置和全局标识信息)不在AST节点自身中,而是在ASTContext及其关联的源管理器中存储.

要提取它们,需要传递ASTContextRecursiveASTVisitor实现中.

调用CreateASTConsumer时,CompilerInstance可访问ASTContext.因此,可从那里提取,并把它交给新创建的FindNamedClassConsumer:

virtual std::unique_ptr<clang::ASTConsumer> CreateASTConsumer(clang::CompilerInstance &Compiler, llvm::StringRef InFile) {return std::make_unique<FindNamedClassConsumer>(&Compiler.getASTContext());
}

现在在RecursiveASTVisitor中,可访问ASTContext,可利用AST节点,查找源位置等:

bool VisitCXXRecordDecl(CXXRecordDecl *Declaration) {if (Declaration->getQualifiedNameAsString() == "n::m::C") {//`getFullLoc`使用`ASTContext`的`SourceManager`来解析源位置,并分解为`行和列`部分.FullSourceLoc FullLocation = Context->getFullLoc(Declaration->getBeginLoc());if (FullLocation.isValid())llvm::outs() << "Found declaration at "<< FullLocation.getSpellingLineNumber() << ":"<< FullLocation.getSpellingColumnNumber() << "\n";}return true;
}

组合在一起

如下:

#include "clang/AST/ASTConsumer.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendAction.h"
#include "clang/Tooling/Tooling.h"
using namespace clang;
class FindNamedClassVisitor: public RecursiveASTVisitor<FindNamedClassVisitor> {
public:explicit FindNamedClassVisitor(ASTContext *Context): Context(Context) {}bool VisitCXXRecordDecl(CXXRecordDecl *Declaration) {if (Declaration->getQualifiedNameAsString() == "n::m::C") {FullSourceLoc FullLocation = Context->getFullLoc(Declaration->getBeginLoc());if (FullLocation.isValid())llvm::outs() << "Found declaration at "<< FullLocation.getSpellingLineNumber() << ":"<< FullLocation.getSpellingColumnNumber() << "\n";}return true;}
private:ASTContext *Context;
};
class FindNamedClassConsumer : public clang::ASTConsumer {
public:explicit FindNamedClassConsumer(ASTContext *Context): Visitor(Context) {}virtual void HandleTranslationUnit(clang::ASTContext &Context) {Visitor.TraverseDecl(Context.getTranslationUnitDecl());}
private:FindNamedClassVisitor Visitor;
};
class FindNamedClassAction : public clang::ASTFrontendAction {
public:virtual std::unique_ptr<clang::ASTConsumer> CreateASTConsumer(clang::CompilerInstance &Compiler, llvm::StringRef InFile) {return std::make_unique<FindNamedClassConsumer>(&Compiler.getASTContext());}
};
int main(int argc, char **argv) {if (argc > 1) {clang::tooling::runToolOnCode(std::make_unique<FindNamedClassAction>(), argv[1]);}
}

FindClassDecls.cpp文件中存储它,并创建以下CMakeLists.txt来链接它:

set(LLVM_LINK_COMPONENTSSupport)
add_clang_executable(find-class-decls FindClassDecls.cpp)
target_link_libraries(find-class-declsPRIVATEclangASTclangBasicclangFrontendclangSerializationclangTooling)

对代码片运行此工具时,输出找到的n::m::C类的所有声明:

$ ./bin/find-class-decls "namespace n { namespace m { class C {}; } }"

1:29找到声明

相关文章:

2312clang,基于访问者的前端动作

原文 基于RecursiveASTVisitor的ASTFrontendActions. 创建用RecursiveASTVisitor查找特定名字的CXXRecordDeclAST节点的FrontendAction. 创建FrontendAction 编写基于clang的工具(如Clang插件或基于LibTooling的独立工具)时,常见入口是允许在编译过程中执行用户特定操作的F…...

怎么搭建实时渲染云传输服务器

实时渲染云传输技术方案&#xff0c;在数字孪生、虚拟仿真领域使用越来越多&#xff0c;可能很多想使用该技术方案项目还不知道具体该怎么搭建云传输服务器&#xff0c;具体怎么使用实时云渲染平台系统。点量云小芹将对这两个问题做集中分享。 一、实时渲染服务器怎么搭建&…...

如何在生产环境正确使用Redis

一、在生产环境使用Redis 如果在生产环境使用Redis&#xff0c;需要遵守一定的使用规范&#xff0c;以保障服务稳定、高效。。 1.1、明确Redis集群的服务定位 1、仅适用于缓存场景&#xff1a;Redis定位于高性能缓存服务&#xff0c;强调快速读写和低延迟的特性&#xff0c;…...

LeetCode-环形链表问题

1.环形链表&#xff08;141&#xff09; 题目描述&#xff1a; 给你一个链表的头节点 head &#xff0c;判断链表中是否有环。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&#xff0c;评测系统…...

C# 读取Word表格到DataSet

目录 功能需求 Office 数据源的一些映射关系 范例运行环境 配置Office DCOM 关键代码 组件库引入 ​核心代码 杀掉进程 总结 功能需求 在应用项目里&#xff0c;多数情况下我们会遇到导入 Excel 文件数据到数据库的功能需求&#xff0c;但某些情况下&#xff0c;也存…...

构建外卖系统:从技术到实战

在当今高度数字化的社会中&#xff0c;外卖系统的开发变得愈发重要。本文将从技术角度出发&#xff0c;带领读者一步步构建一个基础的外卖系统&#xff0c;并涵盖关键技术和实际代码。 1. 技术选型 1.1 后端开发 选择Node.js和Express框架进行后端开发&#xff0c;搭建一个灵…...

城市之眼:数据可视化在智慧城市的角色

作为智慧城市建设的核心组成部分&#xff0c;数据可视化扮演着至关重要的角色。在城市中&#xff0c;数据源源不断地产生&#xff0c;涵盖了从交通流量、环境质量到市民需求等各个方面。而数据可视化作为将这些数据呈现出来的手段&#xff0c;对智慧城市的发展起着关键性的作用…...

Nature | Baker团队用AI设计出史上最高互作强度的蛋白质

蛋白质是生命的基础&#xff0c;是生命功能的主要执行者&#xff0c;其结构与功能由氨基酸序列所决定。蛋白质设计是指对新蛋白质分子进行人为的合理设计&#xff0c;旨在设计新的活性&#xff0c;行为或目的&#xff0c;并增进对蛋白质功能的基本了解。可以从头开始设计蛋白质…...

C# 初识System.IO.Pipelines

写在前面 在进一步了解Socket粘包分包的过程中&#xff0c;了解到了.NET 中的 System.IO.Pipelines&#xff0c;可以更优雅高效的解决这个问题&#xff1b;先跟随官方的示例做个初步的认识。 System.IO.Pipelines 是一个库&#xff0c;旨在使在 .NET 中执行高性能 I/O 更加容…...

嵌入式——RTC内置实时时钟

学习目标 理解原理图RTC设计部分掌握初始化RTC掌握设置时间掌握读取时间学习内容 RTC原理图 RTC结构框图 RTC时钟 开发流程 加载依赖。gd32f4xx_rtc.c,gd32f4xx_pmu.c初始化RTC。时钟配置。获取时钟。RTC初始化 // 电池管理加载 rcu_periph_clock_enable(RCU_PMU); pmu_back…...

nodejs微信小程序+python+PHP的热带野生动物园景点预约订票系统的设计与实现-计算机毕业设计推荐

目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1 nodejs简介 4 2.2 express框架介绍 6 2.4 MySQL数据库 4 第3章 系统分析 5 3.1 需求分析 5 3.2 系统可行性分析 5 3.2.1技术可行性&#xff1a;…...

ASP.NET MVC的5种AuthorizationFilter

一、IAuthorizationFilter 所有的AuthorizationFilter实现了接口IAuthorizationFilter。如下面的代码片断所示&#xff0c;IAuthorizationFilter定义了一个OnAuthorization方法用于实现授权的操作。作为该方法的参数filterContext是一个表示授权上下文的AuthorizationContext对…...

C语言初学8:函数和作用域

一、函数 函数声明告诉编译器函数的名称、返回值类型和参数。在一个源文件中定义函数且在另一个文件中调用函数时&#xff0c;函数声明是必需的。函数定义提供了函数的实际主体。...

2024年科技盛宴“上海智博会·上海软博会”招商工作接近尾声

2024年上海智博会和上海软博会即将于3月份在上海跨国采购会展中心盛大召开。作为全球科技和软件行业的盛会&#xff0c;这两大展会汇集了业界顶尖的企业、创新技术和前瞻思想&#xff0c;吸引了来自世界各地的专业人士和参展商。 今年的展会将一如既往地为大家呈现最前沿的科技…...

深圳锐科达SIP矿用电话模块SV-2801VP

深圳锐科达SIP矿用电话模块SV-2801VP 一、简介 SV-2800VP系列模块是我司设计研发的一款用于井下的矿用IP音频传输模块&#xff0c;可用此模块打造一套低延迟、高效率、高灵活和多扩展的IP矿用广播对讲系统&#xff0c;亦可对传统煤矿电话系统加装此模块&#xff0c;进行智能化…...

【Qt-数据库】

Qt编程指南 ■ SQLite■ CSV■ JSON ■ SQLite Qt 提供了很多操作数据库的类&#xff0c; SQLite 是非常小的&#xff0c;是轻量级的&#xff0c;完全配置时小于 400KiB&#xff0c;省略可选功能配置时小于 250KiB。 SQLite 是一个进程内的库&#xff0c;实现了自给自足的、无…...

windows文件名命名规范(文件名规范、命名规则、避免特殊字符、注意文件名长度限制260个字符)

文章目录 Windows文件名命名规范1. 基本规则1.1 避免使用特殊字符1.2 限制文件名长度1.3 避免使用预留名称 2. 最佳实践2.1 使用描述性名称2.2 使用连字符或下划线代替空格2.3 使用日期和版本号 3. 实用技巧3.1 批量重命名文件3.2 使用PowerShell进行高级文件操作 Windows文件名…...

如何修改MySQL的默认端口

MySQL是世界上最流行的开源关系型数据库管理系统之一。在某些情况下&#xff0c;由于安全性、网络策略或端口冲突的原因&#xff0c;数据库管理员可能需要更改MySQL服务的默认监听端口。本文将指导您如何在不同的操作系统上更改MySQL的默认端口。 理解MySQL配置文件 MySQL的配…...

Android笔记(二十一):Room组件实现Android应用的持久化处理

一、Room组件概述 Room是Android JetPack架构组件之一&#xff0c;是一个持久处理的库。Room提供了在SQLite数据库上提供抽象层&#xff0c;使之实现数据访问。 &#xff08;1&#xff09;实体类&#xff08;Entity&#xff09;&#xff1a;映射并封装了数据库对应的数据表中…...

uniapp中各种状态的按钮

当涉及状态按钮时&#xff0c;UniApp提供了丰富的选择。UniApp中的状态按钮可以是开关按钮、单选按钮、多选按钮等。开发者可以根据具体需求选择使用合适的状态按钮组件。对于状态按钮&#xff0c;UniApp提供了丰富的API和事件&#xff0c;可以轻松实现状态切换、状态监听等功能…...

2024年赣州旅游投资集团社会招聘笔试真

2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...

全球首个30米分辨率湿地数据集(2000—2022)

数据简介 今天我们分享的数据是全球30米分辨率湿地数据集&#xff0c;包含8种湿地亚类&#xff0c;该数据以0.5X0.5的瓦片存储&#xff0c;我们整理了所有属于中国的瓦片名称与其对应省份&#xff0c;方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

HarmonyOS运动开发:如何用mpchart绘制运动配速图表

##鸿蒙核心技术##运动开发##Sensor Service Kit&#xff08;传感器服务&#xff09;# 前言 在运动类应用中&#xff0c;运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据&#xff0c;如配速、距离、卡路里消耗等&#xff0c;用户可以更清晰…...

VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP

编辑-虚拟网络编辑器-更改设置 选择桥接模式&#xff0c;然后找到相应的网卡&#xff08;可以查看自己本机的网络连接&#xff09; windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置&#xff0c;选择刚才配置的桥接模式 静态ip设置&#xff1a; 我用的ubuntu24桌…...

C#学习第29天:表达式树(Expression Trees)

目录 什么是表达式树&#xff1f; 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持&#xff1a; 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...

人工智能--安全大模型训练计划:基于Fine-tuning + LLM Agent

安全大模型训练计划&#xff1a;基于Fine-tuning LLM Agent 1. 构建高质量安全数据集 目标&#xff1a;为安全大模型创建高质量、去偏、符合伦理的训练数据集&#xff0c;涵盖安全相关任务&#xff08;如有害内容检测、隐私保护、道德推理等&#xff09;。 1.1 数据收集 描…...

AI语音助手的Python实现

引言 语音助手(如小爱同学、Siri)通过语音识别、自然语言处理(NLP)和语音合成技术,为用户提供直观、高效的交互体验。随着人工智能的普及,Python开发者可以利用开源库和AI模型,快速构建自定义语音助手。本文由浅入深,详细介绍如何使用Python开发AI语音助手,涵盖基础功…...

什么是VR全景技术

VR全景技术&#xff0c;全称为虚拟现实全景技术&#xff0c;是通过计算机图像模拟生成三维空间中的虚拟世界&#xff0c;使用户能够在该虚拟世界中进行全方位、无死角的观察和交互的技术。VR全景技术模拟人在真实空间中的视觉体验&#xff0c;结合图文、3D、音视频等多媒体元素…...

rknn toolkit2搭建和推理

安装Miniconda Miniconda - Anaconda Miniconda 选择一个 新的 版本 &#xff0c;不用和RKNN的python版本保持一致 使用 ./xxx.sh进行安装 下面配置一下载源 # 清华大学源&#xff08;最常用&#xff09; conda config --add channels https://mirrors.tuna.tsinghua.edu.cn…...

自然语言处理——文本分类

文本分类 传统机器学习方法文本表示向量空间模型 特征选择文档频率互信息信息增益&#xff08;IG&#xff09; 分类器设计贝叶斯理论&#xff1a;线性判别函数 文本分类性能评估P-R曲线ROC曲线 将文本文档或句子分类为预定义的类或类别&#xff0c; 有单标签多类别文本分类和多…...