在LLVM中的常量初始值设定项中转换结构

时间:2016-09-03 10:20:36

标签: casting llvm llvm-ir

考虑以下类型:

%foo = type {%bar}
%bar = type {i32, i32}
%baz = type {i8, i8}

%foo应该类似于C联盟,并且能够同时拥有%bar%baz,这通常没问题,因为%bar是比%baz大得多。

%baz写入内存中的%foo可能会通过将指针指向%foo的字段并将指针转换为%baz*来实现。

现在考虑我有以下常数:

@c = constant %foo ...

如何使用%baz内部对其进行初始化?像这样做会产生类型错误:

@c = constant %foo { %bar {i8 0, i8 0} }

在C中,我只是强制转换它,但是LLVM似乎没有可以转换整个结构的强制转换指令。

如何使用%baz初始化常量?

1 个答案:

答案 0 :(得分:0)

此方法类似于clang对C联合所做的工作。首先,使用匿名类型定义常量,该类型的开头有您的并集变体,然后填充至,以便该常量在大小上与并集类型匹配:

@c = constant { %baz, [6 x i8] } { %baz { i8 0, i8 0 }, [6 x i8] undef }

现在您的常量类型错误,因此每次访问它时,都必须将指向它的指针转换为ćorrect类型:

define void @f() {
  %1 = bitcast { %baz, [6 x i8] }* @c to %foo*
  ...
}