LLVM IR - 有人可以解释这种行为吗?

时间:2016-05-21 01:37:58

标签: llvm llvm-ir

我正试图为我的语言构建一个编译器。在我的语言中,我希望像Java一样对对象/结构使用隐式指针。在下面的程序中,我正在测试这个功能。但是,该程序没有像我预期的那样运行。我不希望你们读完我的整个编译器代码,因为那样浪费时间。相反,我希望我可以解释我打算为该计划做什么,你们可以在llvm中发现出了什么问题。这样,我可以调整编译器以生成正确的llvm ir。

<小时/> 流量:
[功能] Main - [Return:Int] {
- &GT;为一个i32的结构分配空间 - &GT;调用createObj函数并将返回值存储在先前分配的空间内 - &GT;返回结构的i32 }

[功能] createObj - [返回:struct {i32}] {
- &GT;为一个i32的结构分配空间 - &GT;在这个空间上调用对象函数(指针真的)
- &GT;返回此空格(指针确实)
}

[功能]对象 - [返回:无效] {
- &GT;在结构指针参数
的内部存储i32值5 }

<小时/> 程序是main保持返回一些随机数而不是5.一个这样的数字是159383856.我猜这是指针地址的十进制表示,但是我不确定它为什么打印出来指针地址。

; ModuleID = 'main'

%Object = type { i32 }

define i32 @main() {
entry:
  %0 = call %Object* @createObj()
  %o = alloca %Object*
  store %Object* %0, %Object** %o
  %1 = load %Object** %o
  %2 = getelementptr inbounds %Object* %1, i32 0, i32 0
  %3 = load i32* %2
  ret i32 %3
}

define %Object* @createObj() {
entry:
  %0 = alloca %Object
  call void @-Object(%Object* %0)
  %o = alloca %Object*
  store %Object* %0, %Object** %o
  %1 = load %Object** %o
  ret %Object* %1
}

define void @-Object(%Object* %this) {
entry:
  %0 = getelementptr inbounds %Object* %this, i32 0, i32 0
  store i32 5, i32* %0
  ret void
}

此llvm ir是根据此语法生成的。

func () > main > (int) {
    Object o = createObj();

    return o.id;
}

// Create an object and returns it
func () > createObj > (Object) { 
    Object o = make Object < ();

    return o;
}

// Object decl
tmpl Object {
    int id; // Property

    // This is run every time an object is created.
    constructor < () {
        this.id = 5;
    }
}

1 个答案:

答案 0 :(得分:4)

在createObj中,您似乎正在返回一个指向堆栈变量的指针,该函数在函数返回后将不再有效。

如果您正在进行像Java这样的隐式对象指针,那么您将需要调用像malloc这样的堆分配,而我认为你没有。