LLVM 中的动态数组 - 声明常量/全局

问题描述 投票:0回答:1

我想对动态数组进行建模。这是我提出的计划:我的所有数组都会有一个基

struct
,包括虚函数表指针,以及数组的运行时大小:

%anyarray_base = type {
  %other_stuff,
  i64,           ; runtime size
}
%bytearray = type { %anyarray_base, [0 x i8] }

这适用于完全在运行时创建的数组。我

malloc
记忆
%anyarray_base
加上“有效负载”的大小。我可以使用 getelementptr 访问其中的数据。
我遇到的问题是常数。非常具体的例子:我的程序有一个常量字符串

[0 x i8]

,我想在我的 LLVM 模块中创建一个常量来保存该字符串。所以,我会写

"Hello World"

@myConstantString = global %bytearray {
  %anyarray_base {
    @other_stuff,    ; constant misc data about the array
    i64 12           ; array size, 12 bytes
  },
  [12 x i8] c"Hello, World!"  ; the actual literal from the source code
}

不接受这个:


错误:结构体初始值设定项的元素 1 与结构体元素类型不匹配
(指向全局 %bytearray 常量)


我显然对 LLVM 的工作原理缺乏一些理解。请帮助我用我的玩具语言构建 Hello World :)

llvm llvm-ir
1个回答
0
投票

对于将用作常量的每个数组大小,您需要一种类型。如果您的代码使用长度为 0、1、2、5、10 和 15 的字符串

常量

,则需要六种字符串类型。这些通常位于从 int 到 type 的映射中,由只有两个公共函数的小模块维护:

    一个函数提供并返回一个指向常量数组(例如字符串)的指针。该函数的目的是封装六种类型中的五种。如果字符串是“hello”,那么它会要求 LLVM 模块分配“五字节字符串”类型的实例,然后返回指向该实例的指针。
  1. 另一个函数返回字符串类型。它总是返回“零字节字符串”。
  2. 您编写的大多数代码仅使用一种字符串类型,并且将 getelementptr 超出该类型的末尾(这在 LLVM IR 中有明确定义)。一个小模块可以看到多种字符串类型。

这很容易推广到任何恒定大小元素的数组,并且当您将其与 LLVM 一起使用时,会产生令人愉快、简单的代码。

© www.soinside.com 2019 - 2024. All rights reserved.