使用LLVM通过参数传递结构

时间:2012-10-06 01:20:04

标签: c llvm

是否可以通过参数传递结构?

它与C abi兼容吗?

[编辑]

基本上,我想要一个包含两个成员的C ++ POD(结构将是一个胖指针,带有一个指针和一个整数),并且能够将这个结构作为函数参数传递给调用指令(甚至在调用C代码时。)

我现在不使用胖指针(指针和整数各自都在不同的函数参数中),我想知道在开始一个相当大的重构之前是否可能!

2 个答案:

答案 0 :(得分:1)

你可以这样做。

通过在http://llvm.org/demo/index.cgi将C代码复制并粘贴到LLVM的在线演示中,您可以弄清楚样本C的LLVM代码是什么。

如果您将代码复制并粘贴到codepad.org中,您将看到LLVM为myFunction生成以下内容:

define void @_Z10myFunction10MyStruct_t(i8* %myStructAsParam.coerce0, i32     %myStructAsParam.coerce1) nounwind uwtable {
  %1 = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([23 x i8]* @.str, i64 0, i64 0), i8* %myStructAsParam.coerce0, i32 %myStructAsParam.coerce1)
  ret void
}

当然,如果你看一下电话,你会注意到没有复制。这取决于调用函数。如果我们写一个小C函数:

void myCallingFunction(MyStruct_t *foobar)
{
  myFunction(*foobar);
}

我们可以看到为myCallingFunction生成的LLVM bitcode是:

define void @_Z17myCallingFunctionP10MyStruct_t(%struct.MyStruct_t* nocapture %foobar)   nounwind uwtable {
  %foobar.0 = getelementptr inbounds %struct.MyStruct_t* %foobar, i64 0, i32 0
  %tmp = load i8** %foobar.0, align 8
  %foobar.1 = getelementptr inbounds %struct.MyStruct_t* %foobar, i64 0, i32 1
  %tmp1 = load i32* %foobar.1, align 8
  %1 = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([23 x i8]* @.str, i64 0, i64 0), i8* %tmp, i32 %tmp1) nounwind
  ret void
}

调用函数生成结构的副本,然后传入副本的地址。

答案 1 :(得分:0)

当然,你可以。这是一个例子:

struct MyStruct_t {
    char *charPointer;
    int number;
};

void myFunction(MyStruct_t myStructAsParam) {

    printf("String: %s, Number: %i", myStructAsParam.charPointer, myStructAsParam.number);
    // Your stuff here.
}