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

Casting a struct in a constant initializer in LLVM

考虑以下类型:

%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 初始化常量?

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

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

现在您的常量类型错误,因此无论何时访问它,您都必须将指向它的指针转换为正确的类型:

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