LLVM IR实战进阶 函数 if while phi 数组 结构体 指针变量 类 继承

llvm-ir-in-action

LLVM-Essentials-13

模块 LLVMContext Module

#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
using namespace llvm;


static std::unique_ptr<LLVMContext> TheContext;
static std::unique_ptr<Module> TheModule;
static std::unique_ptr<IRBuilder<>> Builder;

static void InitializeModule() {
  TheContext = std::make_unique<LLVMContext>();
  TheModule = std::make_unique<Module>("first module", *TheContext);
  // Create a new builder for the module.
  Builder = std::make_unique<IRBuilder<>>(*TheContext);
}

// 上下文信息
static LLVMContext TheContext;
static LLVMContext& getGlobalContext() {
    return TheContext;
}
static LLVMContext &Context = getGlobalContext();
// 创建模块
static Module *ModuleOb = new Module("my compiler", Context);
ModuleOb->print(errs(), nullptr);

全局变量 GlobalVariable IRBuilder getOrInsertGlobal getNamedGlobal

GlobalVariable *createGlob(IRBuilder<> &Builder, std::string Name) 
{
    ModuleOb->getOrInsertGlobal(Name, Builder.getInt32Ty());// 创建全局变量 (名字 类型)
    GlobalVariable *gVar = ModuleOb->getNamedGlobal(Name);  // 获取全局变量
    gVar->setLinkage(GlobalValue::CommonLinkage);           // 设置链接属性
    gVar->setAlignment(MaybeAlign(4));                      // 设置内存对齐属性
    return gVar;
}

static IRBuilder<> Builder(Context); // 创建代码构建器
GlobalVariable *gVar = createGlob(Builder, "x");

函数


// 无参数函数-------------------
Function *createFunc(IRBuilder<> &Builder, std::string Name) 
{
  //Type *returnType = Type::getInt32Ty(context);//返回值类型
  FunctionType *funcType = llvm::FunctionType::get(Builder.getInt32Ty(), false);// 函数类型 int() 无参数
  // 创建出一个参数个数不可变(最后一个参数false就是这个意思)的函数类型
  // 若为true 则函数参数可变 ...  stdarg.h  va_list va_start va_arg va_end
  Function *fooFunc = llvm::Function::Create(
      funcType, llvm::Function::ExternalLinkage, Name, ModuleOb);// 创建函数
  return fooFunc;
}

static IRBuilder<> Builder(Context);
Function *fooFunc = createFunc(Builder, "foo"); // 创建函数 int foo()

// 有参数函数 ------------------
Function *createFunc(IRBuilder<> &Builder, std::string Name, Type *ret_type, std::vector<Type *> inputs_type) {
  FunctionType *funcType = llvm::FunctionType::get(ret_type, inputs_type, false);
  Function *fooFunc = llvm::Function::Create(
      funcType, llvm::Function::ExternalLinkage, Name, ModuleOb);
  return fooFunc;
}

// 设置函数参数名
void setFuncArgs(Function *fooFunc, std::vector<std::string> FunArgs) {
    unsigned Idx = 0;
    Function::arg_iterator AI, AE;
    for (AI = fooFunc->arg_begin(), AE = fooFunc->arg_end(); AI != AE;
         ++AI, ++Idx)
        AI->setName(FunArgs[Idx]);
}

// 创建函数并给参数命名
Function *createnNamedFunc(IRBuilder<> &Builder, std::string Name) {
  static std::vector<std::string> FunArgs;
  FunArgs.push_back("a");
  FunArgs.push_back("b");
  // 创建返回类型和参数类型
  std::vector<Type *> Integers(FunArgs.size(), Type::getInt32Ty(Context));
  Type *ret_type = Builder.getInt32Ty();
  // 创建函数
  Function *fooFunc = createFunc(Builder, Name, ret_type, Integers);
  // 设置函数参数名
  setFuncArgs(fooFunc, FunArgs);
  return fooFunc;
}



代码块 Block & 函数返回值语句

// 在函数 fooFunc 内创建 名为 Name 的代码块
BasicBlock *createBB(Function *fooFunc, std::string Name) 
{
  return BasicBlock::Create(Context, Name, fooFunc);
}

static IRBuilder<> Builder(Context);
Function *fooFunc = createnNamedFunc(Builder, "foo");
BasicBlock *entry = createBB(fooFunc, "entry");

//配置当前构建器 代码插入点(代码插入的代码块)
Builder.SetInsertPoint(entry);
// 获取一个整数常量 0
ConstantInt* zero = Builder.getInt32(0);
// 创建返回值语句 return 0;
Builder.CreateRet(zero );

数学运算 CreateMul

Value *createArith(IRBuilder<> &Builder, Value *L, Value *R, string left_name) 
{
  // 创建乘法运算 left_name = L *  R
  return Builder.CreateMul(L, R, left_name);
}

static IRBuilder<> Builder(Context);
Function *fooFunc = createnNamedFunc(Builder, "foo");
BasicBlock *entry = createBB(fooFunc, "entry");

//配置当前构建器 代码插入点(代码插入的代码块)
Builder.SetInsertPoint(entry);

Value *Arg1 = fooFunc->arg_begin(); // 获取函数第一个参数值
Value *constant = Builder.getInt32(16); // 创建常量值 16
// 创建 乘法二元运算赋值语句 multmp = a * 16;
Value *val = createArith(Builder, Arg1, constant, "multmp"); 
// 创建返回值语句 return val;
Builder.CreateRet(val);

while 循环

// i = StartVal
// while(i < EndVal)
//    val += 5
//    i += 1

Value *createLoop(IRBuilder<> &Builder, BasicBlock *LoopBodyB, BasicBlock *LoopAfterBB,
                  Value *StartVal, Value *EndVal, Value *body_var) 
{
  BasicBlock *PreheaderBB = Builder.GetInsertBlock(); // 循环前的block

  Builder.CreateBr(LoopBodyB);// 无条件跳转语句  PreheaderBB -> LoopBodyB
  Builder.SetInsertPoint(LoopBodyB);// 当前插入代码点
  
  // 创建分支变量 int i = 2
  PHINode *IndVar = Builder.CreatePHI(Type::getInt32Ty(Context), 2, "i"); // 该分支变量 2种情况
  // 循环变量开始值
  IndVar->addIncoming(StartVal, PreheaderBB); // 配置各分支值表  循环前的block:StartVal
  
  // 创建循环体 addtmp = body_var + 5
  Value *Add = Builder.CreateAdd(body_var, Builder.getInt32(5), "addtmp");
  
  // 构建迭代变量 变化 i += 1
  Value *StepVal = Builder.getInt32(1);
  Value *NextVal = Builder.CreateAdd(IndVar, StepVal, "nextval");

  // 循环 条件
  Value *EndCond = Builder.CreateICmpULT(IndVar, EndVal, "endcond");

  //EndCond = Builder.CreateICmpNE(EndCond, Builder.getInt1(false), "loopcond");
  //BasicBlock *LoopEndBB = Builder.GetInsertBlock();
  //BasicBlock *AfterBB = List[1];
  
  // 条件跳转语句 
  Builder.CreateCondBr(EndCond, LoopBodyB, LoopAfterBB);
  
  // 更新 代码插入点
  Builder.SetInsertPoint(LoopAfterBB);
  
  // 更新 分支变量 分支值表
  IndVar->addIncoming(NextVal, LoopEndBB);
  return Add;
}

static IRBuilder<> Builder(Context);
Function *fooFunc = createnNamedFunc(Builder, "foo");
BasicBlock *entry = createBB(fooFunc, "entry");

//配置当前构建器 代码插入点(代码插入的代码块)
Builder.SetInsertPoint(entry);
Function::arg_iterator AI = fooFunc->arg_begin();
Value *Arg1 = AI++; // 循环内改变的变量
Value *Arg2 = AI;   // 循环范围 end
Value *StartVal = Builder.getInt32(1);// 循环范围 beg

// 循环与具体代码块
BasicBlock *LoopBB = createBB(fooFunc, "loop");
BasicBlock *AfterBB = createBB(fooFunc, "afterloop");
// 创建whie循环 并获取返回值
Value *Res = createLoop(Builder, LoopBB, AfterBB , Arg1, StartVal, Arg2);

// 创建函数返回值语句
Builder.CreateRet(Res);

控制语句

Value *createIfElse(IRBuilder<> &Builder, BBList List, ValList VL) 
{
  Value *Condtn = VL[0]; // 条件变量 if(Condtn)
  Value *Arg1 = VL[1];   // 循环体内相关操作变量
  BasicBlock *ThenBB = List[0]; // 条件为真 的 执行分支
  BasicBlock *ElseBB = List[1]; // 条件为假 的 执行分支
  BasicBlock *MergeBB = List[2];// 控制语句后的 合并分支
  
  // 条件跳转分支 
  Builder.CreateCondBr(Condtn, ThenBB, ElseBB);
  
  // 条件为真 代码块
  Builder.SetInsertPoint(ThenBB);
  // thenaddtmp = Arg1 + 1
  Value *ThenVal = Builder.CreateAdd(Arg1, Builder.getInt32(1), "thenaddtmp");
  // 无条件跳转到 后面的 合并分支 
  Builder.CreateBr(MergeBB);
  
  // 条件为假 代码块
  Builder.SetInsertPoint(ElseBB);
  // elseaddtmp = Arg1 + 2
  Value *ElseVal = Builder.CreateAdd(Arg1, Builder.getInt32(2), "elseaddtmp");
  // 无条件跳转到 后面的 合并分支 
  Builder.CreateBr(MergeBB);

  unsigned PhiBBSize = List.size() - 1; // 2
  Builder.SetInsertPoint(MergeBB);
  // 创建分支变量
  PHINode *Phi = Builder.CreatePHI(Type::getInt32Ty(getGlobalContext()), PhiBBSize, "iftmp");
  
  //====== phi分支汇合变量 ========
  // 分支语句前不创建变量,分支内同名变量赋值,分支后需要使用 phi变量汇合多分支的变量
  // 也可使用 栈变量 在 分支语句前 分配 CreateAlloca 个分支内 存储值 CreateStore(值, 栈变量)
  // 添加个分支变量映射情况 
  Phi->addIncoming(ThenVal, ThenBB);
  Phi->addIncoming(ElseVal, ElseBB);

  return Phi;
}

  static IRBuilder<> Builder(Context);
  Function *fooFunc = createnNamedFunc(Builder, "foo");
  BasicBlock *entry = createBB(fooFunc, "entry");

  typedef SmallVector<BasicBlock *, 16> BBList;
  typedef SmallVector<Value *, 16> ValList;

  Value *Arg1 = fooFunc->arg_begin();
  Value *constant = Builder.getInt32(16);
  Value *val = createArithMul(Builder, Arg1, constant, "mul5"); // mul5 = Arg1 * constant
  
  // 条件 变量
  Value *val2 = Builder.getInt32(100);
  Value *Compare = Builder.CreateICmpULT(val, val2, "cmptmp");
  Value *Condtn = Builder.CreateICmpNE(Compare, Builder.getInt1(false), "ifcond");

  ValList VL;
  VL.push_back(Condtn);
  VL.push_back(Arg1);

  BasicBlock *ThenBB = createBB(fooFunc, "then");
  BasicBlock *ElseBB = createBB(fooFunc, "else");
  BasicBlock *MergeBB = createBB(fooFunc, "ifcont");
  BBList List;
  List.push_back(ThenBB);
  List.push_back(ElseBB);
  List.push_back(MergeBB);

  Value *v = createIfElse(Builder, List, VL);

  Builder.CreateRet(v);

数组变量 定义 赋值


Function *createFunc(IRBuilder<> &Builder, std::string Name)
{
  Type *u32Ty = Type::getInt32Ty(Context);
  Type *vecTy = VectorType::get(u32Ty, 5, false); // 定义数组类型 int[5];
  FunctionType *funcType = FunctionType::get(Builder.getInt32Ty(), vecTy, false);// 函数类型 int xxx(int[5])
  Function *fooFunc = Function::Create(
      funcType, Function::ExternalLinkage, Name, ModuleOb);
  return fooFunc;
}

// 数组元素赋值
Value *setArrayElement(IRBuilder<> &Builder, Value *Vec, Value *Val, Value *Index)
{
  // Vec[Index] = Val;
  return Builder.CreateInsertElement(Vec, Val, Index);
}
// 获取数组元素
Value *getArrayElement(IRBuilder<> &Builder, Value *Vec, Value *Index)
{
  // return Vec[Index]
  return Builder.CreateExtractElement(Vec, Index);
}



static IRBuilder<> Builder(Context);
Function *fooFunc = createFunc(Builder, "foo");
BasicBlock *entry = createBB(fooFunc, "entry");
Builder.SetInsertPoint(entry);

Value *Vec = fooFunc->arg_begin();

for (unsigned int i = 0; i < 5; i++)
  // 数组元素赋值
  Value *V = setArrayElement(Builder, Vec, Builder.getInt32((i + 1) * 10), Builder.getInt32(i));

SmallVector<Value *, 4> V;
for (unsigned int i = 0; i < 5; i++) {
  // 获取数组元素
  V.push_back(getExtractElement(Builder, Vec, Builder.getInt32(i)));
}

  Value *add1 = createArith(Builder, V[0], V[1]); // add1 = V[0] * V[1]
  Value *add2 = createArith(Builder, add1, V[2]); // add2 = add1 * V[2]
  Value *add = createArith(Builder, add2, V[3]);  // add = add2 * V[3]

  Builder.CreateRet(add);

指针变量修改内容

Function *createFunc(IRBuilder<> &Builder, std::string Name) {
  Type *u32Ty = Type::getInt32Ty(Context);
  Type *vecTy = VectorType::get(u32Ty, 5, false); // 数组类型 int[5];
  Type *ptrTy = vecTy->getPointerTo(0); // 数组类型指针 int[5] *
  FunctionType *funcType = FunctionType::get(Builder.getInt32Ty(), ptrTy, false);// 函数类型 int (int[5] *)
  Function *fooFunc = Function::Create(
      funcType, Function::ExternalLinkage, Name, ModuleOb);
  return fooFunc;
}

Value *getGEP(IRBuilder<> &Builder, Value *Base, ArrayRef<Value *>  Offset) {
    // 获取指针 变量的 元素的指针
    // Offset-> block_id,value_id  第几个元素的第几个值
    // get element pointer
    return Builder.CreateGEP(Base, Offset, "a1");
}

static IRBuilder<> Builder(Context);
Function *fooFunc = createFunc(Builder, "foo");
BasicBlock *entry = createBB(fooFunc, "entry");
Builder.SetInsertPoint(entry);

Value *Base = fooFunc->arg_begin();
// 获取 第0 个 int[5]  的 第1个元素的指针
Value *Base_0_1 = getGEP(Builder, Base, {Builder.getInt32(0), Builder.getInt32(1)});
// int[1] = 0;  元素赋值
builder.CreateStore(Builder.getInt32(0), Base_0_1); // 值, 指针变量
// 载入指针变量指向的值
llvm::Value* ret_var_0 = builder_->CreateLoad(Base_0_1);

Builder.CreateRet(ret_var_0);

结构体类型

// 创建函数
Function *createFunc(Type *RetTy, ArrayRef<Type *> Params, std::string Name, bool isVarArg = false) {
  FunctionType *funcType = FunctionType::get(RetTy, Params, isVarArg);// 最后一个参数 是否为 变参数函数
  Function *fooFunc = Function::Create(funcType, Function::ExternalLinkage, Name, TheModule.get());
  return fooFunc;
}
// 设置函数参数名
void setFuncArgs(Function *Func, std::vector<std::string> FuncArgs) {
  unsigned Idx = 0;
  Function::arg_iterator AI, AE;
  for(AI = Func->arg_begin(), AE = Func->arg_end(); AI != AE; ++AI, ++Idx) {
      AI->setName(FuncArgs[Idx]);
    }
}

// 定义结构体类型 type struct {int shape[5]; int size; void *data}
Type* u32Ty = Type::getInt32Ty(Context);
Type* t_void_p = Type::getInt8Ty(Context)->getPointerTo();
Type* t_shape = VectorType::get(u32Ty, 5, false);// 定长数组
Type* t_tensor = StructType::create({t_shape, u32Ty, t_void_p});

// 创建函数 t_tensor* Bar(int a)
Function *fooFunc = createFunc(PointerType::get(Foo, 0), {Builder->getInt32Ty()}, "Bar");
std::vector<std::string> FuncArgs;
FuncArgs.push_back("a");
setFuncArgs(fooFunc, FuncArgs);

BasicBlock *entry = BasicBlock::Create(*Context, "entry", fooFunc);
Builder->SetInsertPoint(entry);

Function::arg_iterator AI = fooFunc->arg_begin();
Value *Arg_a = AI++;
Value *result = Builder->CreateAdd(Arg_a , Builder->getInt32(10), "result");

// 创建结构体变量
Value *fooBar = Builder->CreateAlloca(t_tensor, nullptr, "fooBar");
// 获取结构体元素指针
Value *shape = Builder->CreateGEP(Foo, fooBar, {Builder->getInt32(0), Builder->getInt32(0)}, "shape");
// TODO
for (unsigned int i = 0; i < 5; i++)
  // 数组元素赋值
  Value *V = setArrayElement(Builder, shape, Builder.getInt32(i), Builder.getInt32(i));

// 设置结构体元素值
Value *size = Builder->CreateGEP(Foo, fooBar, {Builder->getInt32(0), Builder->getInt32(1)}, "size");
// fooBar.size = 10
Builder->CreateStore(Builder->getInt32(10), size);
// CreateLoad 取出结构体元素值

// 函数返回 结构指针变量
Builder->CreateRet(fooBar);

结构体实现 类 class


typedef struct class_Box {
    double length;
    double breadth;
    double height;     
}class_Box;

double get(class_Box *this)
{
    double temp = this->length * this->breadth;
    double getRet = temp * this->height;
    return Ret 
}

void set (class_Box *this, double x, double y, double z)
{
    this->length  = x;
    this->breadth = y;
    this->height  = z;
        
}



//===== create Box class struct 创建结构体 包含三个 double类型 元素 长宽高  立体盒子 ======
StructType *Box = StructType::create(*TheContext, "class.Box");
Box->setBody({Builder->getDoubleTy(), Builder->getDoubleTy(), Builder->getDoubleTy()});

//===== create double Box::get(void) 创建函数 获取  长方体 体积 ========
Function *Box3getEv = createFunc(Builder->getDoubleTy(), { PointerType::get(Box, 0) }, "Box3getEv");
std::vector<std::string> BoxGetFuncArgs;
BoxGetFuncArgs.push_back("this");
setFuncArgs(Box3getEv, BoxGetFuncArgs);

// 构建函数体
BasicBlock *entry = BasicBlock::Create(*TheContext, "entry", Box3getEv);
Builder->SetInsertPoint(entry);
// 取函数参数
Function::arg_iterator getAI = Box3getEv->arg_begin();
Value *getThis = getAI;
// 获取结构体元素
  Value *member_length = getMemberValue(Box, getThis, 0, "length");
  Value *member_breadth = getMemberValue(Box, getThis, 1, "breadth");
  Value *member_height = getMemberValue(Box, getThis, 2, "height");
// 构建运算  长*宽*高
  Value *temp = Builder->CreateMul(member_length, member_breadth);
  Value *getRet = Builder->CreateMul(temp, member_height);
  Builder->CreateRet(getRet);
  verifyFunction(*Box3getEv);


// ====== 创建函数 设置 长方体 尺寸

  // void Box::set(double len, double bre, double hei)
// 创建函数 签名 
  Type *memberType = Builder->getDoubleTy();
  Type *retType = Builder->getVoidTy();
  Function *Box3setEddd = createFunc(retType, { PointerType::get(Box, 0), memberType, memberType, memberType }, "Box3setEddd");
  std::vector<std::string> Box3setEdddArgs;
  Box3setEdddArgs.push_back("this");
  Box3setEdddArgs.push_back("len");
  Box3setEdddArgs.push_back("bre");
  Box3setEdddArgs.push_back("hei");
  setFuncArgs(Box3setEddd, Box3setEdddArgs);

// 设置函数体
  BasicBlock *setEntry = BasicBlock::Create(*TheContext, "entry", Box3setEddd);
  Builder->SetInsertPoint(setEntry);
// 获取函数参数
  Function::arg_iterator setAI = Box3setEddd->arg_begin();
  Value *setThis = setAI++;
  Value *lenVal = Builder->CreateLoad(memberType, setAI++, "lenVal");
  Value *breVal = Builder->CreateLoad(memberType, setAI++, "breVal");
  Value *heiVal = Builder->CreateLoad(memberType, setAI++, "heiVal");
// 设置 相关结构体参数 各个 元素的值
  setMemberValue(Box, setThis, 0, "length", lenVal);
  setMemberValue(Box, setThis, 1, "breadth", breVal);
  setMemberValue(Box, setThis, 2, "height", heiVal);
  verifyFunction(*Box3setEddd);


类继承

typedef struct Box{
    double a;
}
void setA(Box *this, double a)
{
    this->a = a;
}

typedef struct Square{
    Box fa;
    double b;
}
void setB(Square *this, double b)
{
    Box *base = (Box*)this; // 派生类转化为基类
    base->a = b;
    this->b = b;
}





StructType *createBoxTy() {
  // create Box class struct
  StructType *Box = StructType::create(*TheContext, "class.Box");
  Box->setBody(Builder->getDoubleTy());

  // create void Box::SetA(double value)
  Function *Box3getEv = createFunc(Builder->getVoidTy(), { PointerType::get(Box, 0), Builder->getDoubleTy()}, "Box_SetA");
  std::vector<std::string> BoxGetFuncArgs;
  BoxGetFuncArgs.push_back("this");
  BoxGetFuncArgs.push_back("value");
  setFuncArgs(Box3getEv, BoxGetFuncArgs);

  BasicBlock *entry = BasicBlock::Create(*TheContext, "entry", Box3getEv);
  Builder->SetInsertPoint(entry);

  Function::arg_iterator getAI = Box3getEv->arg_begin();
  Value *getThis = getAI++;
  Value *value = getAI++;
  setMemberValue(Box, getThis, 0, "_a", value); // this->a = value;
  verifyFunction(*Box3getEv);
  return Box;
}


StructType *createSquareTy(StructType *BoxTy) {
  // Square class struct
  StructType *Square = StructType::create(*TheContext, "class.Square");
  Square->setBody(BoxTy, Builder->getDoubleTy());

//typedef struct Square{
//    Box fa;
//    double b;
//}

  // create void Square::Square_SetB(double value)
  Function *Square_SetB = createFunc(Builder->getVoidTy(), { PointerType::get(Square, 0), Builder->getDoubleTy()}, "Square_SetB");
  std::vector<std::string> FuncArgs;
  FuncArgs.push_back("this");
  FuncArgs.push_back("value");
  setFuncArgs(Square_SetB, FuncArgs);

  BasicBlock *entry = BasicBlock::Create(*TheContext, "entry", Square_SetB);
  Builder->SetInsertPoint(entry);
  // 获取函数参数
  Function::arg_iterator getAI = Square_SetB->arg_begin();
  Value *This = getAI++;
  Value *value = getAI++;

  // 指针类型 转换 CreateBitCast 派生类转换为基类 设置基类中的属性
  Value *baseObj = Builder->CreateBitCast(This, PointerType::get(BoxTy, 0), "box");
  // 获取函数 并调用
  Function *Box_SetA = TheModule->getFunction("Box_SetA");
  Builder->CreateCall(Box_SetA, {baseObj, value});
  
  // 设置派生类中 属性
  setMemberValue(Square, This, 1, "_b", value);
  verifyFunction(*Square_SetB);
  return Square;
}

多继承 继承多个父类

typedef struct Box{
    double a;
}
void setA(Box *this, double a)
{
    this->a = a;
}

typedef struct Square{
    double b;
}
void setB(Square *this, double b)
{
    this->b = b;
}


typedef struct Cube{
    Box *a;
    Square *b;
    double c;
}
void setC(Cube *this, double c)
{
    Box *Boxobj = (Box *)this;
    setA(Boxobj , c);
    Square *Sqobj = (Square *)this;
    setB(Sqobj, c);
    this->c = c;
}


#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Verifier.h"

using namespace llvm;

static std::unique_ptr<LLVMContext> TheContext;
static std::unique_ptr<Module> TheModule;
static std::unique_ptr<IRBuilder<>> Builder;

static void InitializeModule() {
  TheContext = std::make_unique<LLVMContext>();
  TheModule = std::make_unique<Module>("first module", *TheContext);
  // Create a new builder for the module.
  Builder = std::make_unique<IRBuilder<>>(*TheContext);
}

Function *createFunc(Type *RetTy, ArrayRef<Type *> Params, std::string Name, bool isVarArg = false) {
  FunctionType *funcType = FunctionType::get(RetTy, Params, isVarArg);
  Function *fooFunc = Function::Create(funcType, Function::ExternalLinkage, Name, TheModule.get());
  return fooFunc;
}

void setFuncArgs(Function *Func, std::vector<std::string> FuncArgs) {
  unsigned Idx = 0;
  Function::arg_iterator AI, AE;
  for(AI = Func->arg_begin(), AE = Func->arg_end(); AI != AE; ++AI, ++Idx) {
      AI->setName(FuncArgs[Idx]);
    }
}

GlobalVariable *createGlob(Type *type, std::string name) {
    TheModule->getOrInsertGlobal(name, type);
    GlobalVariable *gVar = TheModule->getNamedGlobal(name);
    return gVar;
}

Value *getMemberValue(StructType *type, Value *value, int index, std::string name) {
    Value *memberPtr = Builder->CreateGEP(type, value, {Builder->getInt32(0), Builder->getInt32(index)}, name);
    return Builder->CreateLoad(Builder->getDoubleTy(), memberPtr, name + "_value");
}

void setMemberValue(StructType *type, Value *value, int index, std::string name, Value *target) {
    Value *memberPtr = Builder->CreateGEP(type, value, {Builder->getInt32(0), Builder->getInt32(index)}, name);
    Builder->CreateStore(target, memberPtr);
}


StructType *createBoxTy() {
  // create Box class struct
  StructType *Box = StructType::create(*TheContext, "class.Box");
  Box->setBody(Builder->getDoubleTy());

  // create void Box::SetA(double value)
  Function *Box3getEv = createFunc(Builder->getVoidTy(), { PointerType::get(Box, 0), Builder->getDoubleTy()}, "Box_SetA");
  std::vector<std::string> BoxGetFuncArgs;
  BoxGetFuncArgs.push_back("this");
  BoxGetFuncArgs.push_back("value");
  setFuncArgs(Box3getEv, BoxGetFuncArgs);

  BasicBlock *entry = BasicBlock::Create(*TheContext, "entry", Box3getEv);
  Builder->SetInsertPoint(entry);

  Function::arg_iterator getAI = Box3getEv->arg_begin();
  Value *getThis = getAI++;
  Value *value = getAI++;
  setMemberValue(Box, getThis, 0, "_a", value);
  verifyFunction(*Box3getEv);
  return Box;
}

StructType *createSquareTy() {
  // Square class struct
  StructType *Square = StructType::create(*TheContext, "class.Square");
  Square->setBody(Builder->getDoubleTy());

  // create void Square::Square_SetB(double value)
  Function *Square_SetB = createFunc(Builder->getVoidTy(), { PointerType::get(Square, 0), Builder->getDoubleTy()}, "Square_SetB");
  std::vector<std::string> FuncArgs;
  FuncArgs.push_back("this");
  FuncArgs.push_back("value");
  setFuncArgs(Square_SetB, FuncArgs);
  BasicBlock *entry = BasicBlock::Create(*TheContext, "entry", Square_SetB);
  Builder->SetInsertPoint(entry);
  Function::arg_iterator getAI = Square_SetB->arg_begin();
  Value *This = getAI++;
  Value *value = getAI++;
  setMemberValue(Square, This, 0, "_b", value);
  verifyFunction(*Square_SetB);
  return Square;
}

StructType *createCubeTy(StructType *BoxTy, StructType *SquareTy) {
  // Cube class struct
  StructType *Cube = StructType::create(*TheContext, "class.Cube");
  Cube->setBody(BoxTy, SquareTy, Builder->getDoubleTy());

  // create void Cube::Cube_SetC(double value)
  Function *Cube_SetC = createFunc(Builder->getVoidTy(), { PointerType::get(Cube, 0), Builder->getDoubleTy()}, "Cube_SetC");
  std::vector<std::string> FuncArgs;
  FuncArgs.push_back("this");
  FuncArgs.push_back("value");
  setFuncArgs(Cube_SetC, FuncArgs);
  BasicBlock *entry = BasicBlock::Create(*TheContext, "entry", Cube_SetC);
  Builder->SetInsertPoint(entry);
  Function::arg_iterator getAI = Cube_SetC->arg_begin();
  Value *This = getAI++;
  Value *value = getAI++;
  
// 指针类型强转  Box *Boxobj = (Box *)this;
  Value *boxObj = Builder->CreateBitCast(This, PointerType::get(BoxTy, 0), "box");
// 函数调用
  Function *Box_SetA = TheModule->getFunction("Box_SetA");
  Builder->CreateCall(Box_SetA, {boxObj, value});

// 指针类型强转 Square *Sqobj = (Square *)this;
  Value *squareObj = Builder->CreateBitCast(This, PointerType::get(SquareTy, 0), "square");
  Function *Square_SetB = TheModule->getFunction("Square_SetB");
  Builder->CreateCall(Square_SetB, {squareObj, value});

  setMemberValue(Cube, This, 2, "_c", value);
  verifyFunction(*Cube_SetC);
  return Cube;
}

int main(int argc, char *argv[]) {
  InitializeModule();
  StructType *BoxTy = createBoxTy();
  StructType *SquareTy = createSquareTy();
  StructType *Cube = createCubeTy(BoxTy, SquareTy);

  TheModule->print(errs(), nullptr);
  return 0;
}

类 虚继承 类 虚函数表


#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Verifier.h"

using namespace llvm;

static std::unique_ptr<LLVMContext> TheContext;
static std::unique_ptr<Module> TheModule;
static std::unique_ptr<IRBuilder<>> Builder;

// 初始化全局相关的 上下文 模块 构建器
static void InitializeModule() {
  TheContext = std::make_unique<LLVMContext>();
  TheModule = std::make_unique<Module>("first module", *TheContext);
  // Create a new builder for the module.
  Builder = std::make_unique<IRBuilder<>>(*TheContext);
}
// 创建函数  返回类型 参数类型 函数名  是否是变参数函数 ...
Function *createFunc(Type *RetTy, ArrayRef<Type *> Params, std::string Name, bool isVarArg = false) {
  FunctionType *funcType = FunctionType::get(RetTy, Params, isVarArg);
  Function *fooFunc = Function::Create(funcType, Function::ExternalLinkage, Name, TheModule.get());
  return fooFunc;
}
// 设置函数参数名
void setFuncArgs(Function *Func, std::vector<std::string> FuncArgs) {
  unsigned Idx = 0;
  Function::arg_iterator AI, AE;
  for(AI = Func->arg_begin(), AE = Func->arg_end(); AI != AE; ++AI, ++Idx) {
      AI->setName(FuncArgs[Idx]);
    }
}
// 获取全局变量或函数
GlobalVariable *createGlob(Type *type, std::string name) {
    TheModule->getOrInsertGlobal(name, type);
    GlobalVariable *gVar = TheModule->getNamedGlobal(name);
    return gVar;
}
// 获取结构体元素的值
// 获取类型为 type 的结构体变量 value的第index个元素的值 名字为 name
Value *getMemberValue(StructType *type, Value *value, int index, std::string name) {
    Value *memberPtr = Builder->CreateGEP(type, value, {Builder->getInt32(0), Builder->getInt32(index)}, name);
    return Builder->CreateLoad(Builder->getDoubleTy(), memberPtr, name + "_value");
}

// 设置结构体元素的
void setMemberValue(StructType *type, Value *value, int index, std::string name, Value *target) {
    Value *memberPtr = Builder->CreateGEP(type, value, {Builder->getInt32(0), Builder->getInt32(index)}, name);
    Builder->CreateStore(target, memberPtr);
}

// 设置虚函数表 函数指针数组 / 函数指针指针
PointerType *createVtable() {
  // function type: i32 (...) 函数类型   可变输入参数类型
  FunctionType *funcType = FunctionType::get(Builder->getInt32Ty(), {}, true);
  // 函数指针类型 int (*f)(...)
  PointerType* pfuncType   = PointerType::get(funcType, 0);
  // 函数指针的指针类型
  PointerType* vtable = PointerType::get(pfuncType, 0);
  return vtable 
}

// 创建类  class BaseA{int a;}
StructType *CreateBaseA() {
  StructType *BaseA = StructType::create(*TheContext, "class.BaseA");
  BaseA->setBody(Builder->getInt32Ty());

  return BaseA;
}

// 创建类 class BaseB{vtable v; int b; BaseA a; }
StructType *CreateBaseB(PointerType *vtable, StructType *BaseA) {
  StructType *BaseB = StructType::create(*TheContext, "class.BaseB");
  BaseB->setBody({vtable, Builder->getInt32Ty(), BaseA}, true);

  // BaseB4sumBEv  创建函数
  // int BaseB4sumBEv(BaseB * this, )
  // return this->b + ((BaseA *)(this->a)->a)
  Function *getArea = createFunc(Builder->getInt32Ty(), {PointerType::get(BaseB, 0)}, "BaseB4sumBEv");
  std::vector<std::string> FuncArgs;
  FuncArgs.push_back("this");
  setFuncArgs(getArea, FuncArgs); // 设置函数参数名
  
  BasicBlock *entry = BasicBlock::Create(*TheContext, "entry", getArea);
  Builder->SetInsertPoint(entry);
  Function::arg_iterator getAI = getArea->arg_begin();
  Value *getThis = getAI;// 获取函数参数

  PointerType *pBaseB = PointerType::get(BaseB, 0);// 结构体指针类型 BaseB *
  Value *thisTmp = Builder->CreateAlloca(pBaseB);  // 创建 栈变量
  Builder->CreateStore(getThis, thisTmp); // thisTmp = getThis 
  Value *ptrBaseB = Builder->CreateLoad(pBaseB, thisTmp, "ptrBaseB");// 读取结构体变量

  Type *i8Ty = Builder->getInt8Ty();
  Type *i64Ty = Builder->getInt64Ty();
  PointerType *pi8Ty = PointerType::get(i8Ty, 0);// int *
  PointerType *pi64Ty = PointerType::get(i64Ty, 0);// double *
  PointerType *ppi8Ty = PointerType::get(pi8Ty, 0);// int **
  Value *ppi8 = Builder->CreateBitCast(ptrBaseB, ppi8Ty); // 指针类型强制转换 int **
  Value *pi8Value = Builder->CreateLoad(pi8Ty, ppi8);// int *
  Value *tmp6 = Builder->CreateGEP(i8Ty, pi8Value, Builder->getInt64(-24), "tmp6");
  Value *temp7 = Builder->CreateBitCast(tmp6, pi64Ty, "temp7");
  Value *temp8 = Builder->CreateLoad(i64Ty, temp7, "temp8");
  Value *temp9 = Builder->CreateBitCast(ptrBaseB, pi8Ty, "temp9");
  Value *temp10 = Builder->CreateGEP(i8Ty, temp9, temp8, "temp10");
  Value *ptrBaseA = Builder->CreateBitCast(temp10, PointerType::get(BaseA, 0), "baseA");
  Value *a = getMemberValue(BaseA, ptrBaseA, 0, "a");
  Value *b = getMemberValue(BaseB, ptrBaseB, 1, "b");
  // this->b + ((BaseA *)(this->a)->a)
  Value *ret = Builder->CreateAdd(a, b, "ret");
  Builder->CreateRet(ret);
  return BaseB;
}

// 创建类 class BaseC{vtable v; int c; BaseA a; }
StructType *CreateBaseC(PointerType *vtable, StructType *BaseA) {
  StructType *BaseC = StructType::create(*TheContext, "class.BaseC");
  BaseC->setBody({vtable, Builder->getInt32Ty(), BaseA}, true);

  // BaseC4sumCEv 创建函数
  // int BaseB4sumBEv(BaseB * this, )
  // return this->c + ((BaseA *)(this->a)->a)
  Function *getArea = createFunc(Builder->getInt32Ty(), {PointerType::get(BaseC, 0)}, "BaseC4sumCEv");
  std::vector<std::string> FuncArgs;
  FuncArgs.push_back("this");
  setFuncArgs(getArea, FuncArgs);
  BasicBlock *entry = BasicBlock::Create(*TheContext, "entry", getArea);
  Builder->SetInsertPoint(entry);
  Function::arg_iterator getAI = getArea->arg_begin();
  Value *getThis = getAI;

  PointerType *pBaseC = PointerType::get(BaseC, 0);
  Value *thisTmp = Builder->CreateAlloca(pBaseC);
  Builder->CreateStore(getThis, thisTmp);
  Value *ptrBaseC = Builder->CreateLoad(pBaseC, thisTmp, "ptrBaseC");

  Type *i8Ty = Builder->getInt8Ty();
  Type *i64Ty = Builder->getInt64Ty();
  PointerType *pi8Ty = PointerType::get(i8Ty, 0);
  PointerType *pi64Ty = PointerType::get(i64Ty, 0);
  PointerType *ppi8Ty = PointerType::get(pi8Ty, 0);
  Value *ppi8 = Builder->CreateBitCast(ptrBaseC, ppi8Ty);
  Value *pi8Value = Builder->CreateLoad(pi8Ty, ppi8);
  Value *tmp6 = Builder->CreateGEP(i8Ty, pi8Value, Builder->getInt64(-24), "tmp6");
  Value *temp7 = Builder->CreateBitCast(tmp6, pi64Ty, "temp7");
  Value *temp8 = Builder->CreateLoad(i64Ty, temp7, "temp8");
  Value *temp9 = Builder->CreateBitCast(ptrBaseC, pi8Ty, "temp9");
  Value *temp10 = Builder->CreateGEP(i8Ty, temp9, temp8, "temp10");
  Value *ptrBaseA = Builder->CreateBitCast(temp10, PointerType::get(BaseA, 0), "baseA");
  Value *a = getMemberValue(BaseA, ptrBaseA, 0, "a");
  Value *c = getMemberValue(BaseC, ptrBaseC, 1, "c");
  Value *ret = Builder->CreateAdd(a, c, "ret");
  Builder->CreateRet(ret);
  return BaseC;
}

// 继承两个类
// 创建 类 Derived {BaseBBase a; int8[4] b; BaseCBase c; BaseA d, int8[4] e }
StructType *CreateBaseDerived(PointerType *vtable, StructType *BaseA, StructType *BaseB, StructType *BaseC) {
  StructType *BaseBBase = StructType::create(*TheContext, "class.BaseB.Base");
  BaseBBase->setBody({vtable, Builder->getInt32Ty()}, true);
  StructType *BaseCBase = StructType::create(*TheContext, "class.BaseC.Base");
  BaseCBase->setBody({vtable, Builder->getInt32Ty()}, true);
  StructType *Derived = StructType::create(*TheContext, "class.Derived");
  
  Type *i8Ty = Builder->getInt8Ty();
  ArrayType *array = ArrayType::get(i8Ty, 4); // 数组类型
  Derived->setBody({BaseBBase, array, BaseCBase, BaseA, array});

  Function *getArea = createFunc(Builder->getInt32Ty(), {PointerType::get(Derived, 0)}, "Derived6sumDerEv");
  std::vector<std::string> FuncArgs;
  FuncArgs.push_back("this");
  setFuncArgs(getArea, FuncArgs);
  BasicBlock *entry = BasicBlock::Create(*TheContext, "entry", getArea);
  Builder->SetInsertPoint(entry);
  Function::arg_iterator getAI = getArea->arg_begin();
  Value *getThis = getAI;

  PointerType *pDerived = PointerType::get(Derived, 0);
  Value *thisTmp = Builder->CreateAlloca(pDerived);
  Builder->CreateStore(getThis, thisTmp);
  Value *ptrDerived = Builder->CreateLoad(pDerived, thisTmp, "ptrDerived");
  Value *baseB = Builder->CreateBitCast(ptrDerived, PointerType::get(BaseB, 0), "baseB");
  Function *BaseB4sumBEv = TheModule->getFunction("BaseB4sumBEv");
  Value *sumB = Builder->CreateCall(BaseB4sumBEv, {baseB}, "sumB");


  PointerType *pi8Ty = PointerType::get(i8Ty, 0);
  Value *ptrI8 = Builder->CreateBitCast(ptrDerived, pi8Ty, "ptrI8");
  Value *tmp7 = Builder->CreateGEP(i8Ty, ptrI8, Builder->getInt64(16), "temp7");
  Value *baseC = Builder->CreateBitCast(tmp7, PointerType::get(BaseC, 0), "baseC");
  Function *BaseC4sumCEv = TheModule->getFunction("BaseC4sumCEv");
  Value *sumC = Builder->CreateCall(BaseC4sumCEv, {baseC}, "sumC");
  Value *sum1 = Builder->CreateAdd(sumB, sumC, "sum1");
  Value *ptrd = Builder->CreateGEP(Derived, ptrDerived, {Builder->getInt32(0), Builder->getInt32(3)}, "ptrd");
  Value *d = Builder->CreateLoad(Builder->getInt32Ty(), ptrd, "d");
  Value *ret = Builder->CreateAdd(sum1, d);
  Builder->CreateRet(ret);

  return Derived;
}

int main(int argc, char *argv[]) {
  InitializeModule();
  PointerType* vtable = createVtable();
  StructType *BaseA = CreateBaseA();
  StructType *BaseB = CreateBaseB(vtable, BaseA);
  StructType *BaseC = CreateBaseC(vtable, BaseA);
  CreateBaseDerived(vtable, BaseA, BaseB, BaseC);

  TheModule->print(errs(), nullptr);
  return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

EwenWanW

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值