diff --git a/nac3artiq/src/symbol_resolver.rs b/nac3artiq/src/symbol_resolver.rs index 125e1bbf..cc4e92e9 100644 --- a/nac3artiq/src/symbol_resolver.rs +++ b/nac3artiq/src/symbol_resolver.rs @@ -1073,6 +1073,8 @@ impl InnerResolver { unpack_ndarray_var_tys(&mut ctx.unifier, ndarray_ty); let llvm_usize = generator.get_size_type(ctx.ctx); + // TODO: Special handling required for strings, since there are two representations: + // struct %str and [n x i8]. let ndarray_dtype_llvm_ty = ctx.get_llvm_type(generator, ndarray_dtype); let ndarray_llvm_ty = NDArrayType::new(generator, ctx.ctx, ndarray_dtype_llvm_ty); @@ -1140,30 +1142,43 @@ impl InnerResolver { }) }) .collect(); - let data = data?.unwrap().into_iter(); - let data = match ndarray_dtype_llvm_ty { - BasicTypeEnum::ArrayType(ty) => { - ty.const_array(&data.map(BasicValueEnum::into_array_value).collect_vec()) - } + let data = data?.unwrap(); - BasicTypeEnum::FloatType(ty) => { - ty.const_array(&data.map(BasicValueEnum::into_float_value).collect_vec()) - } + let make_llvm_array = + |llvm_ty: BasicTypeEnum<'ctx>, elems: Vec>| { + debug_assert!(elems.iter().all(|elem| elem.get_type() == llvm_ty)); - BasicTypeEnum::IntType(ty) => { - ty.const_array(&data.map(BasicValueEnum::into_int_value).collect_vec()) - } + match llvm_ty { + BasicTypeEnum::ArrayType(ty) => ty.const_array( + &elems.into_iter().map(BasicValueEnum::into_array_value).collect_vec(), + ), - BasicTypeEnum::PointerType(ty) => { - ty.const_array(&data.map(BasicValueEnum::into_pointer_value).collect_vec()) - } + BasicTypeEnum::FloatType(ty) => ty.const_array( + &elems.into_iter().map(BasicValueEnum::into_float_value).collect_vec(), + ), - BasicTypeEnum::StructType(ty) => { - ty.const_array(&data.map(BasicValueEnum::into_struct_value).collect_vec()) - } + BasicTypeEnum::IntType(ty) => ty.const_array( + &elems.into_iter().map(BasicValueEnum::into_int_value).collect_vec(), + ), - BasicTypeEnum::VectorType(_) => unreachable!(), - }; + BasicTypeEnum::PointerType(ty) => ty.const_array( + &elems + .into_iter() + .map(BasicValueEnum::into_pointer_value) + .collect_vec(), + ), + + BasicTypeEnum::StructType(ty) => ty.const_array( + &elems.into_iter().map(BasicValueEnum::into_struct_value).collect_vec(), + ), + + BasicTypeEnum::VectorType(_) => unreachable!(), + } + }; + + let ndarray_dtype_llvm_ty = + if data.is_empty() { ndarray_dtype_llvm_ty } else { data[0].get_type() }; + let data = make_llvm_array(ndarray_dtype_llvm_ty, data); // create a global for ndarray.data and initialize it using the elements let data_global = ctx.module.add_global(