【发布时间】:2014-05-11 16:00:02
【问题描述】:
在函数中使用结构参数时,clang 会更改函数签名。签名不是使用结构类型,而是大小相等的强制 int。在我的编译器项目中,我使用 llvm 结构类型作为方法签名(这看起来更合乎逻辑)。
这不会是一个问题,除了在使用结构或强制类型时由 LLVM 生成的程序集是不同的并且不调用兼容。这导致我的编译器与带有结构的 C 函数的 ABI 不兼容。
clang 为什么要这样做?这是 C ABI 中指定的内容吗?
这是一个简单的示例 C 源文件:
struct TwoInt { int a, b; };
struct EightChar { char a, b, c, d, e, f, g, h; };
void doTwoInt(struct TwoInt a) {}
void doEightChar(struct EightChar a) {}
int main()
{
struct TwoInt ti;
struct EightChar fc;
doTwoInt(ti);
doEightChar(fc);
return 0;
}
从 Clang 生成的 LLVM-IR
%struct.TwoInt = type { i32, i32 }
%struct.EightChar = type { i8, i8, i8, i8, i8, i8, i8, i8 }
define void @doTwoInt(i64 %a.coerce) nounwind uwtable {
%a = alloca %struct.TwoInt, align 8
%1 = bitcast %struct.TwoInt* %a to i64*
store i64 %a.coerce, i64* %1, align 1
ret void
}
define void @doEightChar(i64 %a.coerce) nounwind uwtable {
%a = alloca %struct.EightChar, align 8
%1 = bitcast %struct.EightChar* %a to i64*
store i64 %a.coerce, i64* %1, align 1
ret void
}
define i32 @main() nounwind uwtable {
%1 = alloca i32, align 4
%ti = alloca %struct.TwoInt, align 4
%fc = alloca %struct.EightChar, align 1
store i32 0, i32* %1
%2 = bitcast %struct.TwoInt* %ti to i64*
%3 = load i64* %2, align 1
call void @doTwoInt(i64 %3)
%4 = bitcast %struct.EightChar* %fc to i64*
%5 = load i64* %4, align 1
call void @doEightChar(i64 %5)
ret i32 0
}
我的预期(以及我的编译器输出):
%TwoInt = type { i32, i32 }
%EightChar = type { i8, i8, i8, i8, i8, i8, i8, i8 }
define void @doTwoInt(%TwoInt %a) {
%1 = alloca i32
%2 = alloca %TwoInt
store %TwoInt %a, %TwoInt* %2
ret void
}
define void @doEightChar(%EightChar %a) {
%1 = alloca i32
%2 = alloca %EightChar
store %EightChar %a, %EightChar* %2
ret void
}
define i32 @main() {
%1 = alloca i32
%ti = alloca %TwoInt
%fc = alloca %EightChar
%2 = load %TwoInt* %ti
call void @doTwoInt(%TwoInt %2)
%3 = load %EightChar* %fc
call void @doEightChar(%EightChar %3)
ret i32 0
}
【问题讨论】:
-
clang 是如何开始的?您的操作系统和 ABI 是什么? ABI 不是在 C/C++ 标准中定义的,而是由操作系统及其库定义的,并且有可能您的编译器不按照 ABI 工作。
-
很好的概述,带有指向更详细页面的链接:What is an application binary interface (ABI)?
标签: compiler-construction struct clang llvm abi