0

I am using llvmpy to (attempt to) generate IR code. However, I am stuck using printf and an array of int8.

The following is an excerpt of what is giving me issues:

# Defining the print function.
# -----
fntype = Type.function(Type.void(), [Type.pointer(Type.int(8))])
myprint = module.add_function(fntype, 'print')
cb = CBuilder(myprint)
x = cb.printf("%s\n", cb.args[0])
cb.ret()
cb.close()

# Creating the string.
# -----
chartype = Type.int(8)
chars = [Constant.int(chartype, ord(c)) for c in "Hello World!"]
string = Constant.array(chartype, chars)
ptr = string.gep([Constant.int(Type.int(8)), 0])

# Calling the print function.
# -----
cfn = exe.get_ctype_function(module.get_function_named('print'), 
                             None, ct.c_char_p)
cfn(ptr)

When I run this code I receive

ctypes.ArgumentError: argument 1: : wrong type

What am I doing wrong? I feel that my usage of .gep() is at fault, but I'm not sure in what way. Or is there something else that I don't understand?

Also, is there a way to get the expected type from the function?

4

1 回答 1

2

是的,您的用法gep不正确:

  1. gep方法接收一组索引,因此不确定类型在那里做什么。
  2. 方法的接收者gep需要是一个指针(或指针向量),而你的接收者是一个数组。

但这里的根本问题是您试图获取编译时常量的地址——即从未分配任何内存的东西的地址。

做你想做的事情的正确方法是创建一个全局变量,它是

  1. 初始化为你的“hello world”和
  2. 标记为常数

这样的变量被分配了一个地址(类型指针指向 i8 数组) - 然后您可以使用gepbitcast常量表达式来获取i8*并将其发送到您的打印函数。

例如,尝试将带有字符串文字的 ac 程序编译到 LLVM IR中,您会看到字符串文字被放置在这样的全局变量中。

于 2013-09-03T12:41:33.930 回答