@@ -7,8 +7,7 @@ use support::LLVMString;
7
7
use types:: { ArrayType , BasicTypeEnum , Type , traits:: AsTypeRef , FunctionType , PointerType } ;
8
8
use values:: { AsValueRef , ArrayValue , BasicValue , PointerValue , VectorValue , IntValue } ;
9
9
10
- // REVIEW: vec_type() is impl for IntType & FloatType. Need to
11
- // find out if it is valid for other types too. Maybe PointerType?
10
+ /// A `VectorType` is the type of a multiple value SIMD constant or variable.
12
11
#[ derive( Debug , PartialEq , Eq , Clone , Copy ) ]
13
12
pub struct VectorType {
14
13
vec_type : Type ,
@@ -24,13 +23,38 @@ impl VectorType {
24
23
}
25
24
26
25
// REVIEW: Can be unsized if inner type is opaque struct
26
+ /// Gets whether or not this `VectorType` is sized or not.
27
+ ///
28
+ /// # Example
29
+ ///
30
+ /// ```no_run
31
+ /// use inkwell::context::Context;
32
+ ///
33
+ /// let context = Context::create();
34
+ /// let f32_type = context.f32_type();
35
+ /// let f32_vec_type = f32_type.vec_type(40);
36
+ ///
37
+ /// assert!(f32_vec_type.is_sized());
38
+ /// ```
27
39
pub fn is_sized ( & self ) -> bool {
28
40
self . vec_type . is_sized ( )
29
41
}
30
42
31
43
// TODO: impl only for VectorType<!StructType<Opaque>>
32
44
// REVIEW: What about Opaque struct hiding in deeper levels?
33
45
// like VectorType<ArrayType<StructType<Opaque>>>?
46
+ /// Gets the size of this `VectorType`. Value may vary depending on the target architecture.
47
+ ///
48
+ /// # Example
49
+ ///
50
+ /// ```no_run
51
+ /// use inkwell::context::Context;
52
+ ///
53
+ /// let context = Context::create();
54
+ /// let f32_type = context.f32_type();
55
+ /// let f32_vec_type = f32_type.vec_type(3);
56
+ /// let f32_vec_type_size = f32_vec_type.size_of();
57
+ /// ```
34
58
pub fn size_of ( & self ) -> Option < IntValue > {
35
59
if self . is_sized ( ) {
36
60
return Some ( self . vec_type . size_of ( ) )
@@ -39,10 +63,36 @@ impl VectorType {
39
63
None
40
64
}
41
65
66
+ /// Gets the aligment of this `VectorType`. Value may vary depending on the target architecture.
67
+ ///
68
+ /// # Example
69
+ ///
70
+ /// ```no_run
71
+ /// use inkwell::context::Context;
72
+ ///
73
+ /// let context = Context::create();
74
+ /// let f32_type = context.f32_type();
75
+ /// let f32_vec_type = f32_type.vec_type(7);
76
+ /// let f32_type_alignment = f32_vec_type.get_alignment();
77
+ /// ```
42
78
pub fn get_alignment ( & self ) -> IntValue {
43
79
self . vec_type . get_alignment ( )
44
80
}
45
81
82
+ /// Gets the size of this `VectorType`.
83
+ ///
84
+ /// # Example
85
+ ///
86
+ /// ```no_run
87
+ /// use inkwell::context::Context;
88
+ ///
89
+ /// let context = Context::create();
90
+ /// let f32_type = context.f32_type();
91
+ /// let f32_vector_type = f32_type.vec_type(3);
92
+ ///
93
+ /// assert_eq!(f32_vector_type.get_size(), 3);
94
+ /// assert_eq!(f32_vector_type.get_element_type().into_float_type(), f32_type);
95
+ /// ```
46
96
pub fn get_size ( & self ) -> u32 {
47
97
unsafe {
48
98
LLVMGetVectorSize ( self . as_type_ref ( ) )
@@ -57,6 +107,21 @@ impl VectorType {
57
107
// REVIEW: Maybe we could make this use &self if the vector size
58
108
// is stored as a const and the input values took a const size?
59
109
// Something like: values: &[&V; self.size]. Doesn't sound possible though
110
+ /// Creates a constant `VectorValue`.
111
+ ///
112
+ /// # Example
113
+ /// ```no_run
114
+ /// use inkwell::context::Context;
115
+ /// use inkwell::types::VectorType;
116
+ ///
117
+ /// let context = Context::create();
118
+ /// let f32_type = context.f32_type();
119
+ /// let f32_val = f32_type.const_float(0.);
120
+ /// let f32_val2 = f32_type.const_float(2.);
121
+ /// let f32_vec_val = VectorType::const_vector(&[f32_val, f32_val2]);
122
+ ///
123
+ /// assert!(f32_vec_val.is_constant_vector());
124
+ /// ```
60
125
pub fn const_vector < V : BasicValue > ( values : & [ V ] ) -> VectorValue {
61
126
let mut values: Vec < LLVMValueRef > = values. iter ( )
62
127
. map ( |val| val. as_value_ref ( ) )
@@ -68,10 +133,44 @@ impl VectorType {
68
133
VectorValue :: new ( vec_value)
69
134
}
70
135
136
+ /// Creates a `PointerValue` representing a constant value of zero (null pointer) pointing to this `VectorType`.
137
+ /// It will be automatically assigned this `FloatType`'s `Context`.
138
+ ///
139
+ /// # Example
140
+ /// ```
141
+ /// use inkwell::context::Context;
142
+ /// use inkwell::types::FloatType;
143
+ ///
144
+ /// // Global Context
145
+ /// let f32_type = FloatType::f32_type();
146
+ /// let f32_vec_type = f32_type.vec_type(7);
147
+ /// let f32_value = f32_vec_type.const_null_ptr();
148
+ ///
149
+ /// // Custom Context
150
+ /// let context = Context::create();
151
+ /// let f32_type = context.f32_type();
152
+ /// let f32_vec_type = f32_type.vec_type(7);
153
+ /// let f32_value = f32_vec_type.const_null_ptr();
154
+ /// ```
71
155
pub fn const_null_ptr ( & self ) -> PointerValue {
72
156
self . vec_type . const_null_ptr ( )
73
157
}
74
158
159
+ /// Creates a constant null (zero) value of this `FloatType`.
160
+ ///
161
+ /// # Example
162
+ ///
163
+ /// ```no_run
164
+ /// use inkwell::context::Context;
165
+ ///
166
+ /// let context = Context::create();
167
+ /// let f32_type = context.f32_type();
168
+ /// let f32_vec_type = f32_type.vec_type(7);
169
+ /// let f32_vec_zero = f32_vec_type.const_null();
170
+ ///
171
+ /// assert!(f32_vec_zero.is_null());
172
+ /// assert_eq!(f32_vec_zero.print_to_string().to_string(), "f32 0");
173
+ /// ```
75
174
pub fn const_null ( & self ) -> VectorValue {
76
175
let null = unsafe {
77
176
LLVMConstNull ( self . as_type_ref ( ) )
@@ -80,41 +179,145 @@ impl VectorType {
80
179
VectorValue :: new ( null)
81
180
}
82
181
182
+ /// Prints the definition of a `VectorType` to a `LLVMString`.
83
183
pub fn print_to_string ( & self ) -> LLVMString {
84
184
self . vec_type . print_to_string ( )
85
185
}
86
186
87
187
// See Type::print_to_stderr note on 5.0+ status
88
- #[ cfg( not( any( feature = "llvm3-6" , feature = "llvm5-0" ) ) ) ]
188
+ /// Prints the definition of an `IntType` to stderr. Not available in newer LLVM versions.
189
+ #[ cfg( any( feature = "llvm3-7" , feature = "llvm3-8" , feature = "llvm3-9" , feature = "llvm4-0" ) ) ]
89
190
pub fn print_to_stderr ( & self ) {
90
191
self . vec_type . print_to_stderr ( )
91
192
}
92
193
194
+ /// Creates an undefined instance of a `VectorType`.
195
+ ///
196
+ /// # Example
197
+ /// ```no_run
198
+ /// use inkwell::context::Context;
199
+ /// use inkwell::AddressSpace;
200
+ ///
201
+ /// let context = Context::create();
202
+ /// let f32_type = context.f32_type();
203
+ /// let f32_vec_type = f32_type.vec_type(3);
204
+ /// let f32_vec_undef = f32_vec_type.get_undef();
205
+ ///
206
+ /// assert!(f32_vec_undef.is_undef());
207
+ /// ```
93
208
pub fn get_undef ( & self ) -> VectorValue {
94
209
VectorValue :: new ( self . vec_type . get_undef ( ) )
95
210
}
96
211
97
212
// SubType: VectorType<BT> -> BT?
213
+ /// Gets the element type of this `VectorType`.
214
+ ///
215
+ /// # Example
216
+ ///
217
+ /// ```no_run
218
+ /// use inkwell::context::Context;
219
+ ///
220
+ /// let context = Context::create();
221
+ /// let f32_type = context.f32_type();
222
+ /// let f32_vector_type = f32_type.vec_type(3);
223
+ ///
224
+ /// assert_eq!(f32_vector_type.get_size(), 3);
225
+ /// assert_eq!(f32_vector_type.get_element_type().into_float_type(), f32_type);
226
+ /// ```
98
227
pub fn get_element_type ( & self ) -> BasicTypeEnum {
99
228
self . vec_type . get_element_type ( )
100
229
}
101
230
231
+ /// Creates a `VectorType` with this `VectorType` for its element type.
232
+ ///
233
+ /// # Example
234
+ ///
235
+ /// ```no_run
236
+ /// use inkwell::context::Context;
237
+ ///
238
+ /// let context = Context::create();
239
+ /// let f32_type = context.f32_type();
240
+ /// let f32_vector_type = f32_type.vec_type(3);
241
+ /// let f32_vector_vector_type = f32_vector_type.vec_type(3);
242
+ ///
243
+ /// assert_eq!(f32_vector_vector_type.get_size(), 3);
244
+ /// assert_eq!(f32_vector_vector_type.get_element_type().into_vector_type(), f32_vector_type);
245
+ /// ```
102
246
pub fn vec_type ( & self , size : u32 ) -> VectorType {
103
247
self . vec_type . vec_type ( size)
104
248
}
105
249
250
+ /// Creates a `PointerType` with this `VectorType` for its element type.
251
+ ///
252
+ /// # Example
253
+ ///
254
+ /// ```no_run
255
+ /// use inkwell::context::Context;
256
+ /// use inkwell::AddressSpace;
257
+ ///
258
+ /// let context = Context::create();
259
+ /// let f32_type = context.f32_type();
260
+ /// let f32_vec_type = f32_type.vec_type(3);
261
+ /// let f32_vec_ptr_type = f32_vec_type.ptr_type(AddressSpace::Generic);
262
+ ///
263
+ /// assert_eq!(f32_vec_ptr_type.get_element_type().into_vector_type(), f32_vec_type);
264
+ /// ```
106
265
pub fn ptr_type ( & self , address_space : AddressSpace ) -> PointerType {
107
266
self . vec_type . ptr_type ( address_space)
108
267
}
109
268
269
+ /// Creates a `FunctionType` with this `VectorType` for its return type.
270
+ ///
271
+ /// # Example
272
+ ///
273
+ /// ```no_run
274
+ /// use inkwell::context::Context;
275
+ ///
276
+ /// let context = Context::create();
277
+ /// let f32_type = context.f32_type();
278
+ /// let f32_vec_type = f32_type.vec_type(3);
279
+ /// let fn_type = f32_vec_type.fn_type(&[], false);
280
+ /// ```
110
281
pub fn fn_type ( & self , param_types : & [ BasicTypeEnum ] , is_var_args : bool ) -> FunctionType {
111
282
self . vec_type . fn_type ( param_types, is_var_args)
112
283
}
113
284
285
+ /// Creates an `ArrayType` with this `VectorType` for its element type.
286
+ ///
287
+ /// # Example
288
+ ///
289
+ /// ```no_run
290
+ /// use inkwell::context::Context;
291
+ ///
292
+ /// let context = Context::create();
293
+ /// let f32_type = context.f32_type();
294
+ /// let f32_vec_type = f32_type.vec_type(3);
295
+ /// let f32_vec_array_type = f32_vec_type.array_type(3);
296
+ ///
297
+ /// assert_eq!(f32_vec_array_type.len(), 3);
298
+ /// assert_eq!(f32_vec_array_type.get_element_type().into_vector_type(), f32_vec_type);
299
+ /// ```
114
300
pub fn array_type ( & self , size : u32 ) -> ArrayType {
115
301
self . vec_type . array_type ( size)
116
302
}
117
303
304
+ /// Creates a constant `ArrayValue`.
305
+ ///
306
+ /// # Example
307
+ /// ```no_run
308
+ /// use inkwell::context::Context;
309
+ /// use inkwell::types::VectorType;
310
+ ///
311
+ /// let context = Context::create();
312
+ /// let f32_type = context.f32_type();
313
+ /// let f32_val = f32_type.const_float(0.);
314
+ /// let f32_val2 = f32_type.const_float(2.);
315
+ /// let f32_vec_type = f32_type.vec_type(2);
316
+ /// let f32_vec_val = VectorType::const_vector(&[f32_val, f32_val2]);
317
+ /// let f32_array = f32_vec_type.const_array(&[f32_vec_val, f32_vec_val]);
318
+ ///
319
+ /// assert!(f32_array.is_const());
320
+ /// ```
118
321
pub fn const_array ( & self , values : & [ VectorValue ] ) -> ArrayValue {
119
322
let mut values: Vec < LLVMValueRef > = values. iter ( )
120
323
. map ( |val| val. as_value_ref ( ) )
@@ -126,6 +329,19 @@ impl VectorType {
126
329
ArrayValue :: new ( value)
127
330
}
128
331
332
+ /// Gets a reference to the `Context` this `VectorType` was created in.
333
+ ///
334
+ /// # Example
335
+ ///
336
+ /// ```no_run
337
+ /// use inkwell::context::Context;
338
+ ///
339
+ /// let context = Context::create();
340
+ /// let f32_type = context.f32_type();
341
+ /// let f32_vec_type = f32_type.vec_type(7);
342
+ ///
343
+ /// assert_eq!(*f32_vec_type.get_context(), context);
344
+ /// ```
129
345
pub fn get_context ( & self ) -> ContextRef {
130
346
self . vec_type . get_context ( )
131
347
}
0 commit comments