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);
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)
{
FunctionType *funcType = llvm::FunctionType::get(Builder.getInt32Ty(), false);
Function *fooFunc = llvm::Function::Create(
funcType, llvm::Function::ExternalLinkage, Name, ModuleOb);
return fooFunc;
}
static IRBuilder<> Builder(Context);
Function *fooFunc = createFunc(Builder, "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 & 函数返回值语句
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);
ConstantInt* zero = Builder.getInt32(0);
Builder.CreateRet(zero );
数学运算 CreateMul
Value *createArith(IRBuilder<> &Builder, Value *L, Value *R, string left_name)
{
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);
Value *val = createArith(Builder, Arg1, constant, "multmp");
Builder.CreateRet(val);
while 循环
Value *createLoop(IRBuilder<> &Builder, BasicBlock *LoopBodyB, BasicBlock *LoopAfterBB,
Value *StartVal, Value *EndVal, Value *body_var)
{
BasicBlock *PreheaderBB = Builder.GetInsertBlock();
Builder.CreateBr(LoopBodyB);
Builder.SetInsertPoint(LoopBodyB);
PHINode *IndVar = Builder.CreatePHI(Type::getInt32Ty(Context), 2, "i");
IndVar->addIncoming(StartVal, PreheaderBB);
Value *Add = Builder.CreateAdd(body_var, Builder.getInt32(5), "addtmp");
Value *StepVal = Builder.getInt32(1);
Value *NextVal = Builder.CreateAdd(IndVar, StepVal, "nextval");
Value *EndCond = Builder.CreateICmpULT(IndVar, EndVal, "endcond");
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;
Value *StartVal = Builder.getInt32(1);
BasicBlock *LoopBB = createBB(fooFunc, "loop");
BasicBlock *AfterBB = createBB(fooFunc, "afterloop");
Value *Res = createLoop(Builder, LoopBB, AfterBB , Arg1, StartVal, Arg2);
Builder.CreateRet(Res);
控制语句
Value *createIfElse(IRBuilder<> &Builder, BBList List, ValList VL)
{
Value *Condtn = VL[0];
Value *Arg1 = VL[1];
BasicBlock *ThenBB = List[0];
BasicBlock *ElseBB = List[1];
BasicBlock *MergeBB = List[2];
Builder.CreateCondBr(Condtn, ThenBB, ElseBB);
Builder.SetInsertPoint(ThenBB);
Value *ThenVal = Builder.CreateAdd(Arg1, Builder.getInt32(1), "thenaddtmp");
Builder.CreateBr(MergeBB);
Builder.SetInsertPoint(ElseBB);
Value *ElseVal = Builder.CreateAdd(Arg1, Builder.getInt32(2), "elseaddtmp");
Builder.CreateBr(MergeBB);
unsigned PhiBBSize = List.size() - 1;
Builder.SetInsertPoint(MergeBB);
PHINode *Phi = Builder.CreatePHI(Type::getInt32Ty(getGlobalContext()), PhiBBSize, "iftmp");
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");
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);
FunctionType *funcType = FunctionType::get(Builder.getInt32Ty(), vecTy, false);
Function *fooFunc = Function::Create(
funcType, Function::ExternalLinkage, Name, ModuleOb);
return fooFunc;
}
Value *setArrayElement(IRBuilder<> &Builder, Value *Vec, Value *Val, Value *Index)
{
return Builder.CreateInsertElement(Vec, Val, Index);
}
Value *getArrayElement(IRBuilder<> &Builder, Value *Vec, Value *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]);
Value *add2 = createArith(Builder, add1, V[2]);
Value *add = createArith(Builder, 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);
Type *ptrTy = vecTy->getPointerTo(0);
FunctionType *funcType = FunctionType::get(Builder.getInt32Ty(), ptrTy, false);
Function *fooFunc = Function::Create(
funcType, Function::ExternalLinkage, Name, ModuleOb);
return fooFunc;
}
Value *getGEP(IRBuilder<> &Builder, Value *Base, ArrayRef<Value *> Offset) {
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();
Value *Base_0_1 = getGEP(Builder, Base, {Builder.getInt32(0), Builder.getInt32(1)});
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* 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});
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");
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");
Builder->CreateStore(Builder->getInt32(10), size);
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;
}
StructType *Box = StructType::create(*TheContext, "class.Box");
Box->setBody({Builder->getDoubleTy(), Builder->getDoubleTy(), Builder->getDoubleTy()});
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);
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() {
StructType *Box = StructType::create(*TheContext, "class.Box");
Box->setBody(Builder->getDoubleTy());
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(StructType *BoxTy) {
StructType *Square = StructType::create(*TheContext, "class.Square");
Square->setBody(BoxTy, Builder->getDoubleTy());
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++;
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);
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() {
StructType *Box = StructType::create(*TheContext, "class.Box");
Box->setBody(Builder->getDoubleTy());
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() {
StructType *Square = StructType::create(*TheContext, "class.Square");
Square->setBody(Builder->getDoubleTy());
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) {
StructType *Cube = StructType::create(*TheContext, "class.Cube");
Cube->setBody(BoxTy, SquareTy, Builder->getDoubleTy());
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++;
Value *boxObj = Builder->CreateBitCast(This, PointerType::get(BoxTy, 0), "box");
Function *Box_SetA = TheModule->getFunction("Box_SetA");
Builder->CreateCall(Box_SetA, {boxObj, value});
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);
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);
}
PointerType *createVtable() {
FunctionType *funcType = FunctionType::get(Builder->getInt32Ty(), {}, true);
PointerType* pfuncType = PointerType::get(funcType, 0);
PointerType* vtable = PointerType::get(pfuncType, 0);
return vtable
}
StructType *CreateBaseA() {
StructType *BaseA = StructType::create(*TheContext, "class.BaseA");
BaseA->setBody(Builder->getInt32Ty());
return BaseA;
}
StructType *CreateBaseB(PointerType *vtable, StructType *BaseA) {
StructType *BaseB = StructType::create(*TheContext, "class.BaseB");
BaseB->setBody({vtable, Builder->getInt32Ty(), BaseA}, true);
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);
Value *thisTmp = Builder->CreateAlloca(pBaseB);
Builder->CreateStore(getThis, thisTmp);
Value *ptrBaseB = Builder->CreateLoad(pBaseB, thisTmp, "ptrBaseB");
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(ptrBaseB, 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(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");
Value *ret = Builder->CreateAdd(a, b, "ret");
Builder->CreateRet(ret);
return BaseB;
}
StructType *CreateBaseC(PointerType *vtable, StructType *BaseA) {
StructType *BaseC = StructType::create(*TheContext, "class.BaseC");
BaseC->setBody({vtable, Builder->getInt32Ty(), BaseA}, true);
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;
}
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;
}