【发布时间】:2016-09-18 09:21:28
【问题描述】:
目前我正在尝试为我的语言构建一个编译器。在我的语言中,我希望像在 Java 中一样对对象/结构使用隐式指针。在下面的程序中,我正在测试这个功能。但是,程序并没有像我预期的那样运行。我不希望你们通读我的整个编译器代码,因为那会浪费时间。相反,我希望我能解释我打算让程序做什么,并且你们可以在 llvm ir 中发现哪里出了问题。这样,我可以调整编译器以生成正确的 llvm ir。
流量:
[函数] Main - [返回:Int] {
-> 为一个 i32 的结构分配空间
-> 调用 createObj 函数并将返回值存储在先前分配的空间中
-> 返回结构的 i32
}
[函数] createObj - [返回:struct { i32 }] {
-> 为一个 i32 的结构分配空间
-> 在这个空间上调用 Object 函数(确实是指针)
-> 返回这个空间(确实是指针)
}
[函数] 对象 - [返回:void] {
-> 将 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;
}
}
【问题讨论】: