首页 > 编程语言 >clang操作源码

clang操作源码

时间:2023-04-02 10:11:30浏览次数:112  
标签:struct float clang 源码 操作 include trivial implicit

生成注释

假设有下面的源码:

struct Vec3 {
  float x, y, z;
};

struct Vec4 {
  float x, y, z, w;
};

生成这样的代码:

//[[CLASS INFO]] class:Vec3, is pod:true, is aggregate:true
struct Vec3 {
  float x, y, z;
};
//[[CLASS INFO]] use struct-binding method :
//const auto &[_m0,_m1,_m2] = Vec3;



//[[CLASS INFO]] class:Vec4, is pod:true, is aggregate:true
struct Vec4 {
  float x, y, z, w;
};
//[[CLASS INFO]] use struct-binding method :
//const auto &[_m0,_m1,_m2,_m3] = Vec4;

 

#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/Frontend/ASTUnit.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendActions.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "clang/Frontend/CompilerInvocation.h"
#include "clang/Frontend/PreprocessorOutputOptions.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "clang/Tooling/Tooling.h"
#include "llvm/Support/raw_ostream.h"
#include "clang/Lex/PreprocessorOptions.h"
#include "clang/Rewrite/Core/Rewriter.h"
#include <format>
#include <iostream>

using namespace clang;

class MyASTVisitor : public RecursiveASTVisitor<MyASTVisitor> {
public:
    MyASTVisitor(Rewriter &w ) : writer{w}{}

    bool VisitCXXRecordDecl(CXXRecordDecl *declaration) {
        auto sourceBeginLoc = declaration->getSourceRange().getBegin();
        auto sourceEndLoc = declaration->getSourceRange().getEnd();  

        declaration->dump();
auto name = declaration->getNameAsString(); bool isPod = declaration->isPOD(); auto isAggregate = declaration->isAggregate(); auto fieldCount = std::distance(declaration->field_begin(), declaration->field_end()); std::string fieldBinding{"const auto &["}; for(auto i=0;i<fieldCount;i++){ fieldBinding += "_m" + std::to_string(i); if(i!=fieldCount-1) fieldBinding += ","; } fieldBinding += "] = "; fieldBinding += name; auto classInfo = std::format("//[[CLASS INFO]] class:{}, is pod:{}, is aggregate:{}\n", name, isPod, isAggregate); auto howToBind = std::format("\n//[[CLASS INFO]] use struct-binding method : \n//{};\n\n", fieldBinding); writer.InsertText(sourceBeginLoc, classInfo, true, true); writer.InsertText(declaration->getEndLoc().getLocWithOffset(2), howToBind,true, true); // location使用sourceEndLoc变量也可以 return true; } private: Rewriter &writer; }; class MyASTConsumer : public ASTConsumer { public: MyASTConsumer(Rewriter &w) : writer{w}{} void HandleTranslationUnit(ASTContext &context) override { MyASTVisitor visitor{writer}; visitor.TraverseDecl(context.getTranslationUnitDecl()); } Rewriter &writer; }; class MyFrontendAction : public ASTFrontendAction { public: void EndSourceFileAction() override{ auto &sm = writer.getSourceMgr(); writer.getEditBuffer(sm.getMainFileID()).write(llvm::outs()); } std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &compiler, StringRef file) override { llvm::outs() << "create ast consumer for: " << file << "\n"; compiler.getLangOpts().CPlusPlus = true; compiler.getPreprocessorOpts().addMacroDef("__cplusplus"); compiler.getPreprocessorOpts().addMacroDef("Vec3=struct Vec3"); compiler.getLangOpts().CPlusPlus2b = true; writer.setSourceMgr(compiler.getSourceManager(), compiler.getLangOpts()); return std::make_unique<MyASTConsumer>(writer); } private: Rewriter writer; }; int main(int argc, const char **argv) { auto code= R"( struct Vec3 { float x, y, z; }; struct Vec4 { float x, y, z, w; }; )"; clang::tooling::runToolOnCode(std::make_unique<MyFrontendAction>(), code); return 0; }

 

输出:

D:\Plugin_Dev\CPP\LLVM\modify_ast\cmake-build-debug\xxx.exe

create ast consumer for: input.cc
CXXRecordDecl 0x23cdd3e7c48 <input.cc:3:1, line:5:1> line:3:8 struct Vec3 definition
|-DefinitionData pass_in_registers aggregate standard_layout trivially_copyable pod trivial literal
| |-DefaultConstructor exists trivial needs_implicit
| |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
| |-MoveConstructor exists simple trivial needs_implicit
| |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param
| |-MoveAssignment exists simple trivial needs_implicit
| `-Destructor simple irrelevant trivial needs_implicit
|-CXXRecordDecl 0x23cdd3e7d68 <col:1, col:8> col:8 implicit struct Vec3
|-FieldDecl 0x23cdd3e7e10 <line:4:3, col:9> col:9 x 'float'
|-FieldDecl 0x23cdd3e7e80 <col:3, col:12> col:12 y 'float'
`-FieldDecl 0x23cdd3e7ef0 <col:3, col:15> col:15 z 'float'
CXXRecordDecl 0x23cdd3e7f80 <input.cc:7:1, line:9:1> line:7:8 struct Vec4 definition
|-DefinitionData pass_in_registers aggregate standard_layout trivially_copyable pod trivial literal
| |-DefaultConstructor exists trivial needs_implicit
| |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
| |-MoveConstructor exists simple trivial needs_implicit
| |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param 
| |-MoveAssignment exists simple trivial needs_implicit
| `-Destructor simple irrelevant trivial needs_implicit
|-CXXRecordDecl 0x23cdd3e8098 <col:1, col:8> col:8 implicit struct Vec4
|-FieldDecl 0x23cdd3e8140 <line:8:3, col:9> col:9 x 'float'
|-FieldDecl 0x23cdd3e81b0 <col:3, col:12> col:12 y 'float'
|-FieldDecl 0x23cdd3e8220 <col:3, col:15> col:15 z 'float'                                
`-FieldDecl 0x23cdd3e8290 <col:3, col:18> col:18 w 'float'


//[[CLASS INFO]] class:Vec3, is pod:true, is aggregate:true
struct Vec3 {
  float x, y, z;
};
//[[CLASS INFO]] use struct-binding method :
//const auto &[_m0,_m1,_m2] = Vec3;



//[[CLASS INFO]] class:Vec4, is pod:true, is aggregate:true
struct Vec4 {
  float x, y, z, w;
};
//[[CLASS INFO]] use struct-binding method :
//const auto &[_m0,_m1,_m2,_m3] = Vec4;



Process finished with exit code 0

 

 

 

参考:

编译器 LLVM Clang原理与实战 制作自己的编译器 source-to-source 源代码转换 编译遍 compile pass 代码插桩_llvm emitobjaction_EwenWanW的博客-CSDN博客

标签:struct,float,clang,源码,操作,include,trivial,implicit
From: https://www.cnblogs.com/gearslogy/p/17279979.html

相关文章

  • 一篇关于异或操作的题解 (来源:杭电oj: find your present (2))
    害惭愧惭愧老长时间没写代码了——————————转回正题,对于杭电这个题先说我超时的错误想法—————————————————————————————————————————————————————————————— 一开始我的想法是开一个大小为100000......
  • Django笔记十三之select_for_update等选择和更新等相关操作
    本篇笔记将介绍update和create的一些其他用法,目录如下:get_or_createupdate_or_createselect_for_updatebulk_createbulk_update1、get_or_create前面我们介绍过get()和create()的用法,那么get_or_create()的意思很简单,就是获取或者创建,如果存在就返回,不存在就......
  • 事件的操作
        第一种方式: 第二种方式: ......
  • DOM元素的操作
           ......
  • DOM文本的操作
         ......
  • DOM属性的操作
         ......
  • 《30天自制操作系统笔记》---第一天
    第一天第一个实验:用二进制写一个显示helloworld的“操作系统”使用工具:1、HxD-二进制编辑器2、qumu模拟器下载了HxD–二进制编辑器编辑好了书上的二进制程序helloos0.img然后按照书上写了bat脚本。Install脚本:用来制作系统启动盘Run脚本,用来启动qumu模拟器运行。不过......
  • docker笔记-安装、操作和Registry
    注意事项强烈建议docker宿主机关闭firewalld,改用iptables1docker安装1.1离线安装下载Docker二进制文件(https://download.docker.com/linux/static/stable/x86_64/)tarzxfdocker-xxxx-ce.tgzcpdocker/*/usr/bin/dockerd&验证dockerinfo注册成服务vi/usr/l......
  • Linux服务器MySQL操作总结
    目录1.Navicat连接服务器MySQL2.如何查看MySQL用户名和密码3.修改MySQL的登录密码4.安装MySQL开发包(Centos7版)错误:error1045(28000):accessdeniedforuser'root'@'localhost'(usingpassword:yes)1.Navicat连接服务器MySQL1.选择数据库直接使用第一个MySQL即可......
  • Linux下编译Sqlite源码
    1.下载wgethttps://www.sqlite.org/2023/sqlite-autoconf-3410200.tar.gz--no-check-certificate2.解压tarzxvfsqlite-autoconf-3410200.tar.gz 3.配置路径cdsqlite-autoconf-3410200/./configure--prefix=/data/sqlite#先建立该路径 4.编译make&&ma......