首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

使用ASTMatcher获取至少具有两个相同访问说明符的类

ASTMatcher 是 Clang 提供的一种用于静态分析 C++ 代码的工具。它可以在编译器的抽象语法树(AST)中查找特定的代码模式,并对其进行匹配和处理。

在 C++ 中,访问说明符用于控制类成员的访问权限。常见的访问说明符有 public、protected 和 private。public 成员可以被类的外部访问,protected 成员可以被类的派生类访问,private 成员只能在类内部访问。

使用 ASTMatcher 可以获取至少具有两个相同访问说明符的类的相关信息。具体步骤如下:

  1. 导入 Clang 的头文件和 ASTMatcher 的头文件:
代码语言:txt
复制
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/Tooling/Tooling.h"
  1. 定义一个回调函数,用于处理匹配到的结果:
代码语言:txt
复制
class MatchHandler : public clang::ast_matchers::MatchFinder::MatchCallback {
public:
  virtual void run(const clang::ast_matchers::MatchFinder::MatchResult &Result) {
    // 处理匹配到的结果
    const clang::CXXRecordDecl *Class1 = Result.Nodes.getNodeAs<clang::CXXRecordDecl>("class1");
    const clang::CXXRecordDecl *Class2 = Result.Nodes.getNodeAs<clang::CXXRecordDecl>("class2");
    
    // 获取类的信息并进行处理
    if (Class1 && Class2) {
      // 获取类名
      std::string ClassName1 = Class1->getNameAsString();
      std::string ClassName2 = Class2->getNameAsString();
      
      // 获取访问说明符
      std::string AccessSpecifier1 = getAccessSpecifier(Class1);
      std::string AccessSpecifier2 = getAccessSpecifier(Class2);
      
      // 处理结果
      // ...
    }
  }
  
private:
  std::string getAccessSpecifier(const clang::CXXRecordDecl *Class) {
    if (Class->getAccess() == clang::AS_public)
      return "public";
    else if (Class->getAccess() == clang::AS_protected)
      return "protected";
    else if (Class->getAccess() == clang::AS_private)
      return "private";
    else
      return "unknown";
  }
};
  1. 在主函数中创建 ASTMatcher,并注册匹配规则和回调函数:
代码语言:txt
复制
int main(int argc, const char **argv) {
  // 创建 Clang 工具
  clang::tooling::CommonOptionsParser OptionsParser(argc, argv);
  clang::tooling::ClangTool Tool(OptionsParser.getCompilations(), OptionsParser.getSourcePathList());
  
  // 创建 ASTMatcher
  clang::ast_matchers::MatchFinder Finder;
  
  // 创建匹配规则
  clang::ast_matchers::DeclarationMatcher Matcher = clang::ast_matchers::cxxRecordDecl(
    clang::ast_matchers::has(
      clang::ast_matchers::forEach(
        clang::ast_matchers::fieldDecl(
          clang::ast_matchers::hasAccessSpecifier(
            clang::ast_matchers::anything()
          )
        )
      )
    ),
    clang::ast_matchers::has(
      clang::ast_matchers::forEach(
        clang::ast_matchers::fieldDecl(
          clang::ast_matchers::hasAccessSpecifier(
            clang::ast_matchers::anything()
          )
        )
      )
    )
  ).bind("class1");

  // 注册匹配规则和回调函数
  MatchHandler Handler;
  Finder.addMatcher(Matcher, &Handler);
  
  // 运行匹配
  Tool.run(clang::tooling::newFrontendActionFactory(&Finder).get());
  
  return 0;
}

以上代码中的匹配规则使用了 ASTMatcher 提供的一些基本匹配器,用于匹配具有至少两个具有相同访问说明符的类。在回调函数中,可以根据需要获取类的信息并进行处理。

对于这个问题,腾讯云没有特定的产品与之直接相关。然而,腾讯云提供了一系列云计算服务,如云服务器、云数据库、云存储等,可以帮助开发者构建和部署各种应用。您可以访问腾讯云官方网站(https://cloud.tencent.com/)了解更多相关信息。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

ASTMatcher分析函数调用链(上)

存在问题是ASTMatcher没有在编译阶段获取AST,获取节点数据可能没有clang plugin数据全。...:允许用户编写一个程序来匹配AST节点并能通过访问节点c++接口来获取该AST节点属性、源位置等任何信息,其主要由宏与模板驱动,用法和函数式编程类似,其可实现简单精准高效匹配。...获取函数调用,也需要获取函数被调用函数名和名。...() (3)拿到函数调用后,还需要获取该函数调用方法定义:objcMethodDecl(),以及声明:objcImplementationDecl() (4)创建匹配表达式,通过clang-query...5、使用ASTMatcher 文件中若import其他文件,ASTMatcher是分析不到,这时你必须告诉ASTMatcher你import文件来自哪里,所以被分析文件import文件目录必须通过参数

6.9K81

ASTMatcher分析函数调用链(下)

上一篇文章(ASTMatcher分析函数调用链(上))讲到ASTMatcher原理以及创建,本文将详细介绍ASTMatcher获取函数调用链在iOS app中应用。...一、ASTMatcher部分 1、无消息调用函数定义获取 上篇中ASTMatcher只能获取有消息调用函数定义,那没有消息调用函数定义就无法匹配到,所以无消息调用函数定义也需要获取 DeclarationMatcher....m和.mm文件list,循环通过func-call分析(这里使用func-call和func-call-category-only两个ASTMatcher,3.5章节有解释) for file_one...这就导致了普通函数获取与category函数获取不能在同一个ASTMatcher中,所以需要两个ASTMatcher来分析整个工程,这里后续再优化~ 5、categroy函数通过分析all file...四、ASTMatcher无法分析情况 1、系统方法 由于系统方法在我们调用链中没有用处,所以这里就放弃了对系统方法获取,包括系统category以及方法。

2.5K50
  • C++初识-有了对象之后

    它们就是访问说明符: public说明符:在其之后成员在整个程序内可以被访问,通常用于定义接口 private说明符:在其之后成员不能被使用该类外码使用,但是可以被成员函数访问,通常用于数据成员...protected说明符:与private成员类似,但是其基访问 另外也可以使用class代替struct,只是他们默认访问权限不一样,class定义成员默认是private,而struct...因此我们可以看到在前面的main函数中,可以直接使用.运算符访问数据成员,但是如果换成class就不太一样了,这个时候就会报错,因为在这种情况下,构造函数也是不可访问: error: ‘Human::...C++标准里规定,为了避免不同对象具有相同地址,对象大小不允许为0。...总结 我们从前面的内容可以看到,与C语言相比,C++至少多了以下特点: 成员函数定义在中,即操作和数据都在中,而不像C语言中数据与操作分离 使用特定函数,即构造函数进行初始化 使用访问说明符来封装

    50810

    有效只读属性

    [] } } } 在访问属性地方,表达式将被视为具有 getter 上列出效果,需要使用await和try来修饰表达式。...继承 有效属性和下标可以从基继承。关键不同点是,如果要重载继承有效属性(或者下标),子类属性效果说明符数量不能超过被重载属性。...此规则是子类化本质结果:基必须考虑其子类可能展示所有效果说明符。本质上,该规则和协议一致性规则相同。...但是,已有使用有效只读属性 APIs 将会破坏向后兼容性。因为 APIs 使用者会使用await和try包装属性访问。...因为位置 D 被采用,D 比 C 使用更有意义。 D: 最终在本提案中采纳位置。这个位置在语法中没有使用,把效果说明符放置在访问器上而不是变量或者类型上。

    1.8K60

    100道最新Java面试题,常见面试题及答案汇总

    答案:Java中访问说明符是放在名之前,用于定义访问范围关键字,常见访问说明符有以下几类: Public:公共,能被项目中任何一个Class、Method、Field访问。...答案:可以定义重名方法,但是其参数数量和类型是不同,调用哪个方法取决于传递参数。 例如在下面的中,我们有两个具有相同名称但不同参数打印方法。...答案:变量和方法默认访问说明符是protected,即变量和可用于同一个包中任何其他。 Q50:举一个在Java使用指针例子。 答案:Java中没有指针。...Q51:如何限制一个不被继承? 答案:使用关键字Final。 在下面的例子中,Stone就不能被继承了。 Q52:访问说明符访问范围是什么? 答案: Q53:栈和队列之间有什么区别?...答案:Java中,==操作比较两个变量值是否相等,对于引用型变量表示两个变量在堆中存储地址是否相同,即栈中内容是否相同

    5.1K21

    【C】Storage Class

    什么是Storage Class Storage Class翻译成中文为存储(总感觉翻译成汉语不太好),用来修饰C中变量和函数。如果没有显式指定storage class,会使用默认值。...每个变量都需要一定空间来存储,经常用到存储单元就是内存,除了内存之外,CPU中寄存器也可以存储变量,而且一般来说寄存器访问速度要远远大于内存访问速度。 决定变量生命周期。...如果没有显示使用说明符,则会使用以下默认规则: 在函数内部声明变量默认使用 auto 说明符 在函数内部声明函数默认使用 extern 说明符 在函数外部声明变量和函数默认使用static说明符...,并且具有外部链接(external linkage) 具有外部链接变量和函数可以作用于程序中所有文件,单纯使用static变量和函数具有文件作用域(File Scope),它们只有内部链接(internal...当修饰全局变量或者函数时,static会限定该变量作用域为当前文件(具有内部链接),其他文件并不能使用该变量或者函数。

    78100

    文件操作(File等)API摘要

    绝对路径名是完整路径名,不需要任何其他信息就可以定位它所表示文件。相反,相对路径名必须使用取自其他路径名信息进行解释。默认情况下,java.io 包中总是根据当前用户目录来解析相对路径名。...此方法只提供了临时文件部分功能。要安排自动删除此方法创建文件,可使用 deleteOnExit() 方法。 prefix 参数至少必须是三个字节长。...如果用户不具有更改此抽象路径名访问权限权限,那么操作将失败。...如果用户不具有更改此抽象路径名访问权限权限,那么操作将失败。...sync 方法由要求物理存储(比例文件)处于某种已知状态下代码使用。例如,提供简单事务处理设施可以使用 sync 来确保某个文件所有由给定事务造成更改都记录在存储介质上。

    77020

    Visual C++ 中重大更改

    重大更改为,如果你之前使用具有相同签名运算符 delete(以与 placement new 运算符对应),你将收到编译器错误(C2956,在使用 placement new 点位置出现,因为在代码中该位置...你无需为此使用枚举;具有 size_t 成员类型也将起作用。 你还可以将 placement new 全部消除作为备选解决方案。...现在相同输出是“1.1A2B3C4D5E6F7p+111”。 若要获取旧版本行为,则可以指定精度(例如,%.6A)。 请参阅 精度规范。  %F 说明符 现在支持 %F 格式/转换说明符。...指定 %c 格式说明符生成当前区域设置“相应日期和时间表示形式”。 在 C 区域设置中,要求这种表示形式与 %a %b %e %T %Y 相同。 这与 asctime 生成形式相同。...至少更改 Visual Studio 2015 RC 两个标头才会影响用户代码。 首先, 不再包括 。

    4.7K00

    Visual C++ 中重大更改

    重大更改为,如果你之前使用具有相同签名运算符 delete(以与 placement new 运算符对应),你将收到编译器错误(C2956,在使用 placement new 点位置出现,因为在代码中该位置...你无需为此使用枚举;具有 size_t 成员类型也将起作用。 你还可以将 placement new 全部消除作为备选解决方案。...现在相同输出是“1.1A2B3C4D5E6F7p+111”。 若要获取旧版本行为,则可以指定精度(例如,%.6A)。 请参阅 精度规范。  %F 说明符 现在支持 %F 格式/转换说明符。...指定 %c 格式说明符生成当前区域设置“相应日期和时间表示形式”。 在 C 区域设置中,要求这种表示形式与 %a %b %e %T %Y 相同。 这与 asctime 生成形式相同。...至少更改 Visual Studio 2015 RC 两个标头才会影响用户代码。 首先, 不再包括 。

    5.2K10

    scanf使用,cin和scanf区别

    例如,下面的示例代码演示了如何获取两个格式化数字之间空间偏量: int main(void) { int pos=0; int x = 123; int y = 456;...,那么将忽略0) 在数字前增加符号“+”(正号)或“-”(负号) 塑符是o、x、X吋,增加前缀0、0x、0X;类型符是e、E、f、F、g、G时,一定要使用小数点;类型符是g、G时,尾部 0 保留 0...即 scanf 函数从格式串最左端开始,每遇到一个字符便将其与下一个输入字符进行“匹配”,如果二者匹配(相同)则继续,否则结束对后面输入处理。...关于在OI中使用printf和scanf好处有如下: 我实验机器配置是: 处理器:Intel® Core™ i3-7100U CPU @ 2.40GHz 2.40GHz 随机访问存储器:4.00GB...画成柱状图如下: 以10000数量级时间为1,可得到这样表格: 由此可见,cin读入相同数据时间是scanf3.5~4倍。

    1K40

    【笔记】《C++Primer》—— 第15章:面向对象程序设计

    派生列表就是在名后面加一个单冒号和一个访问说明符,其中访问说明符有public,protected,private三种,如果不写则默认是private 派生会继承基成员数据和成员函数,其中对这些继承来成员访问权限由成员本身说明符和派生列表里访问说明符一同决定...某个对其继承来成员访问权限受到两个因素影响: 基中此成员访问说明符,这是最重要一部分,private成员不管怎么样都无法被其他使用,其他级别受到下一项影响 派生派生列表访问说明符...,这一项决定是派生对继承来成员对外表现出最高权限,也就是这一项并不会影响派生内部使用,但是一旦外部想调用派生使用成员: 如果此时访问说明符为public,则成员对外表现如基权限 如果此时为...例如通过在FOOpublic中加入using BASE::pub;可以使得上面的第一个语句不会报错 派生对基转换也与派生列表访问说明符有关,本质上与类型转换函数权限有关 public继承时用户代码才能使用派生到基转换...因此除了重载虚函数外最好不要让名称同名 假如基和派生虚函数形参不同,我们就无法使用引用或指针来动态调用派生函数了,此时两个函数将被判断为独立函数并将外层隐藏。

    51720

    C++中作用域与生命周期

    - 注意:只要文件不互相包含,如果在两个源文件中定义了同名构造,不会出现重定义错误,因为数据类型不具有外部连接性。...; - 内存分布:全局/静态存储区; - 注意:如果在两个文件中都定义了相同名字全局变量,连接出错:变量重定义。...); - 生命周期:程序运行期一直存在; - 内存分布:全局/静态存储区; - 定义方法:static关键字,const 关键字; - 注意:只要文件不互相包含,在两个不同文件中是可以定义完全相同两个静态变量...四种存储类别说明符有两种存储期:自动存储期和静态存储期。其中auto和register对应自动存储期。具有自动存储期变量在进入声明该变量程序块是被建立,它在该程序块活动时存在,退出该程序块时撤销。...2.static使用建议 (1)若全局变量仅在单个C文件中访问,则可以将这个变量修改为静态全局变量,以降低模块间耦合度; (2)若全局变量仅由单个函数访问,则可以将这个变量改为该函数静态局部变量

    1.1K20

    C 语言用户输入详解:scanf、fgets、内存地址解析及实用指南

    // 获取并保存用户输入数字 scanf("%d", &myNum); // 输出用户输入数字 printf("您数字是:%d", myNum); scanf() 函数接受两个参数:变量格式说明符.../数组大小(在本例中我们使用了一个非常高数字 30,但至少可以确定它可以存储足够名字首字母),并且您不必使用引用运算符 (&)。...要访问它,可以使用引用运算符 (&),结果表示变量存储位置: int myAge = 43; printf("%p", &myAge); // 输出 0x7ffe5367e044 注意:内存地址是以十六进制形式表示...在您程序中,您可能不会得到相同结果,因为这取决于变量在计算机内存中存储位置。 您还应该注意,&myAge 通常被称为 "指针"。指针基本上是将变量内存地址作为其值存储。...要打印指针值,我们使用 %p 格式说明符。 为什么知道内存地址有用? 指针在 C 语言中很重要,因为它们允许我们操作计算机内存中数据 - 这可以减少代码量并提高性能。

    51810

    第 15 章 面向对象程序设计

    对基成员访问权限只与基访问说明符有关。...派生访问说明符目的是控制派生用户(包括派生派生在内)对于基成员访问权限。 派生向基转换是否可访问使用该转换代码决定,同时派生派生访问说明符也会有影响。...struct,两个说明符都默认为 public class, 两个说明符都默认为 private ---- 15.6 继承中作用域 派生作用域嵌套在其基作用域之内,所使用对象、引用或指针静态类型决定了哪些成员能被使用...using声明语句不能指定 explicit或 constexpr,继承构造函数将与基相应函数具有相同属性。...派生定义构造函数与基构造函数具有相同形参列表时,则该构造函数不会被继承,派生使用是自己定义相应函数。 默认、拷贝和移动构造函数不会被继承,这些构造函数按照正常规则被合成。

    1K30

    用于用户输入|内置库函数scanf, fscanf, sscanf, scanf_s, fscanf_s, sscanf_s

    可在 scanf 中使用类型说明符: %c — Character %d — Signed integer %f — Floating point %s — String //C 程序演示scanf语句...format: 包含类型说明符字符串 … : 参数包含用于分配具有适当类型存储指针。...这些参数数量应至少与格式说明符存储数量相同。 成功后,该函数返回填充变量数。在输入失败情况下,在成功读取任何数据之前,将返回 EOF。...C 不会捕获或警告您,它可能会也可能不会使程序崩溃,具体取决于是否有内容试图访问并写入不属于颜色内存插槽。这就是scanf_s发挥作用地方。scanf_s检查用户输入是否适合给定内存空间。...输入大于缓冲区大小将无助于任何操作并给出相同错误。 fscanf_s() : fscanf() 和 fscanf_s() 之间区别与 scanf() 和 scanf_s() 区别相同

    1.6K30

    Python基础教程 读书笔记 第三章 使用字符串

    print y None 应该是: >>> x=[4,5,3,1,7] >>> y=x[:] >>> y.sort() >>> x [4, 5, 3, 1, 7] >>> y [1, 3, 4, 5, 7] 获取已排序列表副本...2.5小结 cmp(x, y)比较两个值 len(seq)返回序列长度 list(seq)把序列转换成列表 max(args)返回序列或者参数集合中最大值 min(args)返回序列或者参数集合中最小值...3.3字符串格式化:完整版 如果右操作数是元组的话,则其中每一个元素都会被单独格式化,每个值都 需要一个对应转换说明符。 基本转换说明符: (1)%字符:标记转换说明符开始。...(3)最小字段宽度(可选):转换后字符串至少应该具有该值指定宽度。如果是*,则宽度会从值元组中读出。 (4)点(.)后跟精度值(可选):如果转换是实数,精度值就表示出现在小数点后位数。...(大写) f.F十进制浮点数 g如果指数大于一或者小于精度值则和e相同,其他情况与f相同 G如果指数大于一或者小于精度值则和〔相同,其他情况与F相同 C单字符(接受整数或者单字符字符串) r字符串(使用

    48810

    c++存储

    C++ 存储存储定义 C++ 程序中变量/函数范围(可见性)和生命周期。这些说明符放置在它们所修饰类型之前。...{ register int miles;}寄存器只用于需要快速访问变量,比如计数器。...extern 修饰符通常用于当有两个或多个文件共享相同全局变量或函数时候,如下所示:第一个文件:main.cpp实例#include int count ;extern void.../writeCount is 5mutable 存储mutable 说明符仅适用于对象,这将在本教程最后进行讲解。它允许对象成员替代常量。...thread_local 存储使用 thread_local 说明符声明变量仅可在它在其上创建线程上访问。 变量在创建线程时创建,并在销毁线程时销毁。 每个线程都有其自己变量副本。

    70520

    c++存储

    C++ 存储 存储定义 C++ 程序中变量/函数范围(可见性)和生命周期。这些说明符放置在它们所修饰类型之前。...C++ 存储说明符,且 register 关键字被弃用。...extern 修饰符通常用于当有两个或多个文件共享相同全局变量或函数时候,如下所示: 第一个文件:main.cpp 实例 #include int count ; extern.../write Count is 5 mutable 存储 mutable 说明符仅适用于对象,这将在本教程最后进行讲解。它允许对象成员替代常量。...thread_local 存储 使用 thread_local 说明符声明变量仅可在它在其上创建线程上访问。 变量在创建线程时创建,并在销毁线程时销毁。 每个线程都有其自己变量副本。

    61050
    领券