在 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*
...
}
考虑以下类型:
%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*
...
}