@@ -102,8 +102,14 @@ export ConstantAggregateZero
102
102
end
103
103
identify (:: Type{Value} , :: Val{API.LLVMConstantAggregateZeroValueKind} ) = ConstantAggregateZero
104
104
105
- # there currently seems to be no function in the LLVM-C interface which returns a
106
- # ConstantAggregateZero value directly, but values can occur through calls to LLVMConstNull
105
+ # array interface
106
+ # FIXME : can we reuse the ::ConstantArray functionality with ConstantAggregateZero values?
107
+ # probably works fine if we just get rid of the refcheck
108
+ Base. eltype (caz:: ConstantAggregateZero ) = eltype (llvmtype (caz))
109
+ Base. size (caz:: ConstantAggregateZero ) = (0 ,)
110
+ Base. length (caz:: ConstantAggregateZero ) = 0
111
+ Base. axes (caz:: ConstantAggregateZero ) = (Base. OneTo (0 ),)
112
+ Base. collect (caz:: ConstantAggregateZero ) = Value[]
107
113
108
114
109
115
# # regular aggregate
@@ -118,13 +124,15 @@ end
118
124
identify (:: Type{Value} , :: Val{API.LLVMConstantArrayValueKind} ) = ConstantArray
119
125
identify (:: Type{Value} , :: Val{API.LLVMConstantDataArrayValueKind} ) = ConstantArray
120
126
127
+ ConstantArrayOrAggregateZero (value) = Value (value):: Union{ConstantArray,ConstantAggregateZero}
128
+
121
129
# generic constructor taking an array of constants
122
130
function ConstantArray (data:: AbstractArray{<:Constant,N} ,
123
131
typ:: LLVMType = llvmtype (first (data))) where {N}
124
132
@assert all (x-> x== typ, llvmtype .(data))
125
133
126
134
if N == 1
127
- return ConstantArray (API. LLVMConstArray (typ, Array (data), length (data)))
135
+ return ConstantArrayOrAggregateZero (API. LLVMConstArray (typ, Array (data), length (data)))
128
136
end
129
137
130
138
if VERSION >= v " 1.1"
@@ -156,7 +164,6 @@ function Base.collect(ca::ConstantArray)
156
164
return constants
157
165
end
158
166
159
-
160
167
# array interface
161
168
Base. eltype (ca:: ConstantArray ) = eltype (llvmtype (ca))
162
169
function Base. size (ca:: ConstantArray )
@@ -195,20 +202,24 @@ end
195
202
end
196
203
identify (:: Type{Value} , :: Val{API.LLVMConstantStructValueKind} ) = ConstantStruct
197
204
205
+ ConstantStructOrAggregateZero (value) = Value (value):: Union{ConstantStruct,ConstantAggregateZero}
206
+
198
207
# anonymous
199
208
ConstantStruct (values:: Vector{<:Constant} ; packed:: Core.Bool = false ) =
200
- ConstantStruct (API. LLVMConstStruct (values, length (values), convert (Bool, packed)))
209
+ ConstantStructOrAggregateZero (API. LLVMConstStruct (values, length (values), convert (Bool, packed)))
201
210
ConstantStruct (values:: Vector{<:Constant} , ctx:: Context ; packed:: Core.Bool = false ) =
202
- ConstantStruct (API. LLVMConstStructInContext (ctx, values, length (values), convert (Bool, packed)))
211
+ ConstantStructOrAggregateZero (API. LLVMConstStructInContext (ctx, values, length (values), convert (Bool, packed)))
203
212
204
213
# named
205
214
ConstantStruct (typ:: StructType , values:: Vector{<:Constant} ) =
206
- ConstantStruct (API. LLVMConstNamedStruct (typ, values, length (values)))
215
+ ConstantStructOrAggregateZero (API. LLVMConstNamedStruct (typ, values, length (values)))
207
216
208
217
# create a ConstantStruct from a Julia object
209
218
function ConstantStruct (value:: T , ctx:: Context = GlobalContext (); name= String (nameof (T)),
210
219
anonymous:: Core.Bool = false , packed:: Core.Bool = false ) where {T}
211
220
isbitstype (T) || throw (ArgumentError (" Can only create a ConstantStruct from an isbits struct" ))
221
+ isprimitivetype (T) && throw (ArgumentError (" Cannot create a ConstantStruct from a primitive value" ))
222
+
212
223
constants = Vector {Constant} ()
213
224
for fieldname in fieldnames (T)
214
225
field = getfield (value, fieldname)
0 commit comments