我正在使用 LLVM 3.3 C++-API。我的代码使用ConstantArray::get
, 和使用递归代码创建多维数组(最内层首先转换为 Constant*s 的向量,如上所述,然后用于初始化下一个最内层,依此类推)。
我试图通过说如果数组的元素类型满足ConstantDataArray::isElementTypeCompatible
谓词来优化这一点,那么它应该使用ConstantDataArray::get
.
这是一个更具体的例子来说明我的意思:
假设我要创建的数组将在 C++ 中这样声明:
诠释 x[2][3] = {{1,2,3},{4,5,6}};
最内层(类型 int[3])是一个简单的数组类型,因此创建了两个 CDA。
下一个等级是两个 int[3] 的数组。它不是一个简单的类型,所以
ConstantArray
创建了一个正则。参数是ArrayRef<Constant*>
包含两个 CDA 的。
在第 3 步,ConstantArray
因为初始化程序没有完全正确的类型而抱怨。这是消息:
.../llvm-3.3.src/lib/IR/Constants.cpp:754:
static llvm::Constant* llvm::ConstantArray::get(llvm::ArrayType*,
llvm::ArrayRef<llvm::Constant*>):
Assertion `V[i]->getType() == Ty->getElementType()
&& "Wrong type in array element initializer"' failed.
我虽然ConstantDataArray
是一个替代品ConstantArray
是元素类型足够简单时的正确的理解方式是什么?
更新
这看起来像是我的代码中的一个错误(在 LLVM 之外)。 ConstantDataArray
似乎确实是ConstantArray
.
这是我用来演示问题的代码。它实际上在没有任何来自 LLVM 的投诉的情况下运行:
// int[2][3] = {{1,2,3},{4,5,6}};
IntegerType* i64 = IntegerType::get(mod->getContext(), 64);
Constant* one = ConstantInt::get(i64, 1);
Constant* two = ConstantInt::get(i64, 2);
Constant* three = ConstantInt::get(i64, 3);
Constant* four = ConstantInt::get(i64, 4);
Constant* five = ConstantInt::get(i64, 5);
Constant* six = ConstantInt::get(i64, 6);
ArrayType* int_3 = ArrayType::get(i64, 3);
ArrayType* int_2_3 = ArrayType::get(int_3, 2);
// Constant* array123 = ConstantArray::get(int_3, std::vector<Constant*>{one,two,three});
Constant* array123 = ConstantDataArray::get(mod->getContext(), std::vector<uint64_t>{1,2,3});
// Constant* array456 = ConstantArray::get(int_3, std::vector<Constant*>{four,five,six});
Constant* array456 = ConstantDataArray::get(mod->getContext(), std::vector<uint64_t>{4,5,6});
Constant* array = ConstantArray::get(int_2_3, std::vector<Constant*>{array123, array456});
如果有人感兴趣,断言源于我反转数组范围。 int[2][3]
是一个由两个三个数组组成的数组。我正在重载operator[]
构建一个数组类型 as i64[2][3]
,其中i64
是一个包含 anIntegerType*
和重载的对象operator[]
。问题是这构建了一个由三个数组组成的数组,每组两个。