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

使用clang Libtooling API打印完全限定类型的参数(ParmVarDecl)或字段(FieldDecl

使用clang Libtooling API打印完全限定类型的参数(ParmVarDecl)或字段(FieldDecl)的步骤如下:

  1. 导入必要的头文件:
代码语言:txt
复制
#include "clang/AST/AST.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/Tooling/CommonOptionsParser.h"
#include "clang/Tooling/Tooling.h"
#include "llvm/Support/CommandLine.h"
  1. 创建一个ASTConsumer类,用于处理AST节点:
代码语言:txt
复制
class MyASTConsumer : public clang::ASTConsumer {
public:
  virtual bool HandleTopLevelDecl(clang::DeclGroupRef DG) {
    for (clang::DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I) {
      clang::Decl *D = *I;
      if (clang::ParmVarDecl *PVD = llvm::dyn_cast<clang::ParmVarDecl>(D)) {
        // 处理参数(ParmVarDecl)
        llvm::outs() << "参数类型: " << PVD->getType().getAsString() << "\n";
      } else if (clang::FieldDecl *FD = llvm::dyn_cast<clang::FieldDecl>(D)) {
        // 处理字段(FieldDecl)
        llvm::outs() << "字段类型: " << FD->getType().getAsString() << "\n";
      }
    }
    return true;
  }
};
  1. 创建一个ASTMatcher类,用于匹配参数或字段:
代码语言:txt
复制
class MyASTMatcher : public clang::ast_matchers::MatchFinder::MatchCallback {
public:
  virtual void run(const clang::ast_matchers::MatchFinder::MatchResult &Result) {
    if (const clang::ParmVarDecl *PVD = Result.Nodes.getNodeAs<clang::ParmVarDecl>("parmVarDecl")) {
      // 匹配到参数(ParmVarDecl)
      llvm::outs() << "参数类型: " << PVD->getType().getAsString() << "\n";
    } else if (const clang::FieldDecl *FD = Result.Nodes.getNodeAs<clang::FieldDecl>("fieldDecl")) {
      // 匹配到字段(FieldDecl)
      llvm::outs() << "字段类型: " << FD->getType().getAsString() << "\n";
    }
  }
};
  1. 在主函数中创建一个ClangTool对象,并注册ASTConsumer和ASTMatcher:
代码语言:txt
复制
int main(int argc, const char **argv) {
  clang::tooling::CommonOptionsParser OptionsParser(argc, argv);
  clang::tooling::ClangTool Tool(OptionsParser.getCompilations(), OptionsParser.getSourcePathList());

  MyASTConsumer Consumer;
  Tool.setASTConsumer(&Consumer);

  MyASTMatcher Matcher;
  clang::ast_matchers::MatchFinder Finder;
  Finder.addMatcher(clang::ast_matchers::parmVarDecl().bind("parmVarDecl"), &Matcher);
  Finder.addMatcher(clang::ast_matchers::fieldDecl().bind("fieldDecl"), &Matcher);

  return Tool.run(clang::tooling::newFrontendActionFactory(&Finder).get());
}
  1. 编译并运行代码,将会打印出参数(ParmVarDecl)和字段(FieldDecl)的完全限定类型。

这是一个使用clang Libtooling API打印完全限定类型的参数(ParmVarDecl)或字段(FieldDecl)的示例代码。你可以根据实际需求进行修改和扩展。

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

相关·内容

www6663388com请拨18687679362环球国际iOS 微信编译速度优化分享

Xcode 编译源文件时,会根据 Header Search Paths 自动添加 -I 参数,如果递归引用的路径下子目录越多,-I 参数也越多,编译器预处理头文件效率就越低,所以不能简单的设置路径递归引用...数字常量 numeric_constant 等等 语法分析(Semantic Analysis):将 token 流组成抽象语法树 AST 静态分析(Static Analysis):检查代码错误,例如参数类型是否错误...接下来修改工程 CC={YOUR PATH}/clang,让 Xcode 编译时使用自己的编译器;同时编译选项 OTHER_CFLAGS 后面增加 -ftime-trace,每个源文件编译后输出耗时报告...bool VisitFunctionDecl(clang::FunctionDecl* decl) { // FunctionDecl 下的所有参数声明允许前置声明取代 include...不过早在 2011 年 Google 内部做了个基于 Clang libTooling 的工具 include-what-you-use,用来整理 C/C++ 头文件,效果如下: ➜ include-what-you-use

2.4K20

iOS 微信编译速度优化分享

Xcode 编译源文件时,会根据 Header Search Paths 自动添加 -I 参数,如果递归引用的路径下子目录越多,-I 参数也越多,编译器预处理头文件效率就越低,所以不能简单的设置路径递归引用...数字常量 numeric_constant 等等 语法分析(Semantic Analysis):将 token 流组成抽象语法树 AST 静态分析(Static Analysis):检查代码错误,例如参数类型是否错误...接下来修改工程 CC={YOUR PATH}/clang,让 Xcode 编译时使用自己的编译器;同时编译选项 OTHER_CFLAGS 后面增加 -ftime-trace,每个源文件编译后输出耗时报告...bool VisitFunctionDecl(clang::FunctionDecl* decl) { // FunctionDecl 下的所有参数声明允许前置声明取代 include...不过早在 2011 年 Google 内部做了个基于 Clang libTooling 的工具 include-what-you-use,用来整理 C/C++ 头文件,效果如下: ➜ include-what-you-use

10.1K128
  • 微信团队分享:极致优化,iOS版微信编译速度3倍提升的实践总结

    Xcode 编译源文件时,会根据 Header Search Paths 自动添加 -I 参数,如果递归引用的路径下子目录越多,-I 参数也越多,编译器预处理头文件效率就越低,所以不能简单的设置路径递归引用...静态分析(Static Analysis):检查代码错误,例如参数类型是否错误,调用对象方法是否有实现; d....接下来修改工程 CC={YOUR PATH}/clang,让 Xcode 编译时使用自己的编译器;同时编译选项 OTHER_CFLAGS 后面增加 -ftime-trace,每个源文件编译后输出耗时报告...因此我们可以做这样的工具,通过 AST 找到代码里出现的标识符(包括类型、函数、宏),以及标识符定义所在文件,然后分析是否需要 include 它定义所在文件。...不过早在 2011 年 Google 内部做了个基于 Clang libTooling 的工具 include-what-you-use,用来整理 C/C++ 头文件。

    2.7K43

    ASTMatcher分析函数调用链(上)

    plugin,二是libtooling 1、clang plugin clang plugin:clang插件作为编译的一部分,在编译器运行时加载,很容易集成到构建环境中。...这样通过替换xcode中clang编译器和加载clang插件分析AST,可以完全控制clang AST。编写插件有三步:自定义类继承、重载、注册插件。...2、libtooling libtooling:代码本身是一个正常的C++程序,以正常的main()函数作为入口。...在官网AST Matcher Reference中可以查看clang提供的所有不同类型的匹配器以及说明,主要分为三类(取自【clang】ASTMatcher & clang-query的描述): Note...5、使用ASTMatcher 文件中若import其他文件,ASTMatcher是分析不到的,这时你必须告诉ASTMatcher你import的文件来自哪里,所以被分析文件import的文件的目录必须通过参数

    7.2K81

    【AI系统】LLVM 前端和优化层

    RecordType:描述了记录类型,例如 struct __NSConstantString_tag。FunctionDecl:表示函数声明,包括函数名称、返回类型和参数信息。...ParmVarDecl:参数变量的声明,包括参数名称和类型。CompoundStmt:表示由多个语句组成的语句块。函数调用表达式、声明引用表达式和隐式类型转换表达式等,用于描述不同的语法结构。...每次对 a 和 b 的使用都生成一个到 int 类型的 ImplicitCastExpr,如 C 标准的要求。ASTContext 类包含翻译单元的完整 AST。...它们通常用于收集程序的信息或执行静态分析,以便其他 Pass 可以使用这些信息进行进一步的优化。分析 Pass 通常是只读的,不会修改程序代码。...常见的这些子类如下:ModulePass:这是最通用的 Pass;它一次分析整个模块,函数的次序不确定。它不限定使用者的行为,允许删除函数和其它修改。

    15610

    iOS底层原理之LLVM & Clang

    1.3: LLVM的设计 当编译器决定支持多种源语言或多种硬件架构时,LLVM最重要的地方就来了。 LLVM设计的最重要方面是,使用通用的代码表示形式(IR),它是用来在编译器中表示代码的形式。...2.1: 编译流程 通过下面命令可以打印源码的编译阶段: clang -ccc-print-phases main.m 打印结果如下: 输入文件:找到源文件。...char **)' // 第一个参数 |-ParmVarDecl 0x1298ad4e0 col:14 argc 'int' // 第二个参数 |-ParmVarDecl.../main (滑动显示更多) 大家可能会疑惑,生成汇编文件就已经是编译器后端的工作了,为什么还是使用的clang命令呢?这是因为我们使用clang提供的接口调起后端相应的功能。...本文主要介绍了下LLVM和Clang相关的概念、设计思想和编译流程,下篇文章将使用LLVM和Clang实现一个简单的插件,敬请期待。

    1.5K10

    深入剖析 iOS 编译 Clang LLVM

    .m 文件的 clang 参数信息,这些参数都是通过Build Setting。...attribute((const)) 重复调用相同数值参数优化返回 用于数值类型参数的函数,多次调用相同的数值型参数,返回是相同的,只在第一次是需要进行运算,后面只返回第一次的结果,这时编译器的一种优化处理方式...使用这个库可以直接使用 C 的 API,官方也提供了 python binding。...LibTooling 对语法树完全的控制 因为 LibTooling 能够完全控制语法树,那么可以做的事情就非常多了。 可以改变 clang 生成代码的方式。 增加更强的类型检查。...按照自己的定义进行代码的检查分析。 对源码做任意类型分析,甚至重写程序。 给 clang 添加一些自定义的分析,创建自己的重构器。 基于现有代码做出大量的修改。 基于工程生成相关图形或文档。

    8K20

    微信安全下一代特征计算引擎的探索与实践

    每个方案都有各自的优劣,实际工程可以根据需求进行选择或组合。在业界,许多选择使用Python引擎、Lua引擎或两者的组合来执行用户编辑的Python脚本或Lua脚本。...Sema语义检查 语义检查包括变量或过程未经声明就使用、变量或过程名重复声明、运算分量类型不匹配、操作符与操作数之间的类型不匹配。...) BuiltInType(内置类型) PointerType(指针类型) ArrayType(数组类型) 使用Clang的-ast-dump查看输出的AST的详细结构 clang -c -Xclang...**函数,EmitGlobalFunctionDefiniton为函数factorial输出LLVM IR,递归访问FunctionDecl的AST子节点 调用栈10-8: 函数定义由参数列表ParmVarDecl...考虑到微信后台主要使用C/C++语言,因此采用C/C++语言的WebAssembly方案和类C/C++语言的DSL是不错的选择,结合Python和Lua完全能满足业务需求。

    28810

    Objective-C源文件编译过程

    如下命令可以对.c、.m源文件进行预处理,其中参数-E就是对源文件进行预处理操作: clang -E xxx.m 如果我们的.m文件中import(文件包含)了其他的文件或者其他的库,执行以上命令对OC...比如类型不匹配,未实现对应的方法。 AST是开发者编写clang插件主要交互的数据结构,clang也提供很多API去读取AST。详情参考:Introduction to the Clang AST。...语义分析的过程同时也收集类型信息,并把类型信息存储在语法树或符号表中,以便随后的中间代码生成过程中使用。 语义分析一个重要的部分就是“类型检查”和“自动类型转换”。...如果a和b都是整型或浮点型,这说明“+”运算符具有匹配的运算分量。如果a或b其中一个是字符串类型,则说明“+”运算符不具备匹配的运算分量。...那么语法分析和语义分析都完成后,clang会遍历AST生成一种明确的、低级的或类机器语言的中间表示。

    9.6K51

    NumPy 1.26 中文文档(五十六)

    (gh-15006) f2py 支持从派生类型语句中读取访问类型属性 因此,不需要使用public或private语句来指定派生类型的访问属性。...使用quotechar='"'将读取 Excel CSV 方言中使用的带引号字段。 此外,现在可以传递单个可调用对象而不是字典作为converters参数。...(gh-15006) f2py 支持从派生类型语句中读取访问类型属性 因此,不需要使用public或private语句来指定派生类型的访问属性。...使用quotechar='"'将读取 Excel CSV 方言中使用的带引号的字段。 此外,现在可以传递单个可调用对象而不是字典给converters参数。...(gh-15006) f2py 支持从派生类型语句中读取访问类型属性 因此,不需要使用 public 或 private 语句来指定派生类型的访问属性。

    17310

    BCC和libbpf的转换

    此外,注意BPF CO-RE用到的很多Clang特性都比较新,需要用到Clang 10或更新的版本 可以参照官方文档升级Clang: git clone https://github.com/llvm...配置用户空间 生成必要的内容 构建基于libbpf的BPF应用需要使用BPF CO-RE包含的几个步骤: 生成带所有内核类型的头文件vmlinux.h 使用Clang(版本10或更新版本)将BPF程序的源代码编译为...BPF应用包含一组BPF程序(合作或完全独立),以及在所有的BPF程序间共享的BPF maps和全局变量(允许操作共同的数据)。...在大多数情况下,用于访问tracepoint 上下文数据的代码完全相同,但特殊的可变长度字符串字段除外。...这种情况下,使用日志输出是最好的选择。使用bpf_printk(fmt, args...)打印输出额外的信息来理解发生的事情。该函数接受printf类的格式,最大支持3个参数。

    1.9K00

    “C不再是一种编程语言”

    这是说要以 C 语言头文件的方式描述接口的类型和函数,并以某种方式做一些事情: 匹配这些类型的布局; 用链接器做一些事情,将函数的符号解析为指针; 用适当的 ABI 来调用这些函数(比如把参数放在正确的寄存器中...这是一个相当重要的、表现良好的平台。这里测试的是一些非常令人厌烦的情况,即一些整型参数在两个由 clang 和 gcc 编译的静态库之间按值传递……而且失败了!...让你的“codegen”直接生成 C(++),这样用户就需要一个 C 编译器。 基于一个成熟的主流 C 编译器(gcc 或 clang)构建自己的编译器。...如果有多个东西基于你的库构建,它们在类型不透明的情况下相互调用,就会出现糟糕的情况: lib1:开发一个 API,使用类型 MyRadType* 调用 use_val; lib2:调用 make_val...当然,libc 可以适当地使用符号版本化技巧,使其 API 可以适应新的定义,但是,改变一个基本数据类型(像 intmax_t)的大小,会在更大的平台生态系统中引发混乱。

    57920

    “C不再是一种编程语言”

    这是说要以 C 语言头文件的方式描述接口的类型和函数,并以某种方式做一些事情: 匹配这些类型的布局; 用链接器做一些事情,将函数的符号解析为指针; 用适当的 ABI 来调用这些函数(比如把参数放在正确的寄存器中...这是一个相当重要的、表现良好的平台。这里测试的是一些非常令人厌烦的情况,即一些整型参数在两个由 clang 和 gcc 编译的静态库之间按值传递……而且失败了!...让你的“codegen”直接生成 C(++),这样用户就需要一个 C 编译器。 基于一个成熟的主流 C 编译器(gcc 或 clang)构建自己的编译器。...如果有多个东西基于你的库构建,它们在类型不透明的情况下相互调用,就会出现糟糕的情况: lib1:开发一个 API,使用类型 MyRadType* 调用 use_val; lib2:调用 make_val...当然,libc 可以适当地使用符号版本化技巧,使其 API 可以适应新的定义,但是,改变一个基本数据类型(像 intmax_t)的大小,会在更大的平台生态系统中引发混乱。

    66121

    C 不再是一种编程语言

    结果发现,一些整数参数在两个由Clang和GCC编译的静态库之间按值传递失败了! Aria发现,Clang和GCC甚至不能就Linux x64上_int128的ABI达成一致。...C编译器 将你的编译器建立在一个成熟的主要C编译器(Clang或GCC)之上 但上面这些也只能让你走这么远,因为除非你的语言真的暴露了unsigned long long,否则你将继承C的巨大可移植性混乱...你有两个选择来处理这个问题: 1.说这是被禁止的,责备那些无论如何都要这么做的人,然后伤心 2.以一种向前兼容的方式设计MyRadType,这样混合就可以了 常见的前向兼容技巧包括: 保留未使用的字段供未来版本使用...如果他们需要在最后增加更多的字段,那也没关系,因为旧版本可以使用这个值来检测头的“版本”,也可以跳过任何他们不知道的字段。 SizeOfDescriptor是数组中每个元素的大小。...当然,libc可以适当地使用符号版本技巧来使其API与新的定义兼容,但改变像 intmax_t这样的基本数据类型的大小,是在一个平台的大生态系统中寻求混乱。

    76410

    C 不再是一种编程语言

    结果发现,一些整数参数在两个由Clang和GCC编译的静态库之间按值传递失败了! Aria发现,Clang和GCC甚至不能就Linux x64上_int128的ABI达成一致。...C编译器 将你的编译器建立在一个成熟的主要C编译器(Clang或GCC)之上 但上面这些也只能让你走这么远,因为除非你的语言真的暴露了unsigned long long,否则你将继承C的巨大可移植性混乱...你有两个选择来处理这个问题: 1.说这是被禁止的,责备那些无论如何都要这么做的人,然后伤心 2.以一种向前兼容的方式设计MyRadType,这样混合就可以了 常见的前向兼容技巧包括: 保留未使用的字段供未来版本使用...如果他们需要在最后增加更多的字段,那也没关系,因为旧版本可以使用这个值来检测头的“版本”,也可以跳过任何他们不知道的字段。 SizeOfDescriptor是数组中每个元素的大小。...当然,libc可以适当地使用符号版本技巧来使其API与新的定义兼容,但改变像 intmax_t这样的基本数据类型的大小,是在一个平台的大生态系统中寻求混乱。

    69730

    BTF:实践指南

    现在在更高版本的内核中,在该变量之前添加了其他字段,导致访问的字段的偏移量变成了 24,这会导致 BPF 程序在偏移量 8 读取的数据可能为垃圾数据。...在目标机器上执行期间,BCC 使用其嵌入式 Clang/LLVM 组合并使用本地安装的内核头文件动态编译程序。 然而,这种方法引入了更多问题。...使用 BTF,我们可以消除在目标机器上安装内核头文件或将 Clang/LLVM 嵌入应用程序并在目标机器上编译的需要。 2. BTF 是什么?...使用 Clang 编译代码: $ clang -O2 -Wall -g -target bpf -c xdp_count.c -o xdp_count.o 接下来,使用 bpftool 加载程序: $...使用 Clang 编译代码: clang -O2 -Wall -g -target bpf -c xdp_count_btf.c -o xdp_count_btf.o 使用 -g 标志将创建调试信息并生成

    40710

    gRPC in ASP.NET Core 3.0 -- Protocol Buffer(1)

    是指字段(Field)的类型 4. 字段的名称 5. 字段的数值(也叫Tag),这个数字是唯一的。它们是用来在信息格式里识别你的字段的,一旦该类型被使用了,那么这个数字就不要再改变了。...重复字段(Repeated) 与singular相对的就是repeated。如果你想做一个list或数组的话,你可以使用重复字段这个概念。这个list可以有任何数量(包括0)的元素。...保留的字段 如果你对你定义的消息类型进行了更新,例如删除某个字段或者注释掉某个字段,那么其它开发者在以后更新这个消息类型的时候可能会重新使用被你删除/注释掉的字段的数值(tag)。...那么一种避免此类事情发生的解决办法就是将你删除/注释掉的这些字段的数值(或/并且包括字段名,因为字段名可引起JSON序列化的问题)标记为reserved,如果其他人再使用这个数值作为字段标识符,那么编译器就会有错误提示...数值和常量名也必须分开使用两个reserved语句。 其中max表示可能的最大的值。 使用其它的信息类型 可以使用其它的信息类型作为字段的类型。

    1.1K30
    领券