我正在尝试使用LLVM并打一些墙,就像这样。 当我编译并运行下面的代码时,而不是获得当前年份,我得到了一周中的那一天:
target datalayout = "e"
declare dllimport x86_stdcallcc void @GetLocalTime(%SYSTEMTIME*)
%SYSTEMTIME = type {
i16, ; wYear
i16, ; wMonth
i16, ; wDayOfWeek
i16, ; wDay
i16, ; wHour
i16, ; wMinute
i16, ; wSecond
i16 ; wMilliseconds
}
define i32 @main() {
%now = alloca %SYSTEMTIME
call void @GetLocalTime(%SYSTEMTIME* %now)
%ptr = getelementptr %SYSTEMTIME* %now, %i32 0, %i32 0
%day = load i16* %ptr
%int = zext i16 %day to i32
ret i32 %int
}
请注意,我不是在编写C或C ++代码,我正在编写上面的代码。 有人能指出我做错了吗? SYSTEMTIME的所有成员似乎都被2个职位关闭......
答案 0 :(得分:1)
你写道:
SYSTEMTIME的所有成员似乎都被2个职位拒绝......
这可能是错误对齐造成的。特别是,您在堆栈上分配结构,而LLVM默认数据布局不指定堆栈对齐,而Windows 32位requires 4 bytes。要满足此要求,请将S32
添加到数据布局字符串(或者S128
,我想,对于64位Windows。)
为了验证这一点,我检查了Clang在我的Windows系统上插入了什么数据布局字符串,实际上你最后可以看到S32
:
"e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S32"
答案 1 :(得分:0)
你声明:
declare dllimport x86_stdcallcc void @GetLocalTime(%SYSTEMTIME*)
这是绝对正确的;但是当你打电话给它时:
call void @GetLocalTime(%SYSTEMTIME* %now)
您忘记了x86_stdcallcc
调用约定。来自the documentation of call
:
调用的调用约定必须与目标函数的调用约定匹配,否则行为未定义。
所以也许添加cc会解决这个问题。