llvmlite 0.46.0b1__cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of llvmlite might be problematic. Click here for more details.

Files changed (45) hide show
  1. llvmlite/__init__.py +11 -0
  2. llvmlite/_version.py +11 -0
  3. llvmlite/binding/__init__.py +18 -0
  4. llvmlite/binding/analysis.py +69 -0
  5. llvmlite/binding/common.py +34 -0
  6. llvmlite/binding/config.py +143 -0
  7. llvmlite/binding/context.py +31 -0
  8. llvmlite/binding/dylib.py +45 -0
  9. llvmlite/binding/executionengine.py +330 -0
  10. llvmlite/binding/ffi.py +395 -0
  11. llvmlite/binding/initfini.py +85 -0
  12. llvmlite/binding/libllvmlite.so +0 -0
  13. llvmlite/binding/linker.py +20 -0
  14. llvmlite/binding/module.py +349 -0
  15. llvmlite/binding/newpassmanagers.py +1049 -0
  16. llvmlite/binding/object_file.py +82 -0
  17. llvmlite/binding/options.py +17 -0
  18. llvmlite/binding/orcjit.py +342 -0
  19. llvmlite/binding/targets.py +462 -0
  20. llvmlite/binding/typeref.py +267 -0
  21. llvmlite/binding/value.py +632 -0
  22. llvmlite/ir/__init__.py +11 -0
  23. llvmlite/ir/_utils.py +80 -0
  24. llvmlite/ir/builder.py +1120 -0
  25. llvmlite/ir/context.py +20 -0
  26. llvmlite/ir/instructions.py +920 -0
  27. llvmlite/ir/module.py +256 -0
  28. llvmlite/ir/transforms.py +64 -0
  29. llvmlite/ir/types.py +730 -0
  30. llvmlite/ir/values.py +1217 -0
  31. llvmlite/tests/__init__.py +57 -0
  32. llvmlite/tests/__main__.py +3 -0
  33. llvmlite/tests/customize.py +407 -0
  34. llvmlite/tests/refprune_proto.py +330 -0
  35. llvmlite/tests/test_binding.py +3155 -0
  36. llvmlite/tests/test_ir.py +3095 -0
  37. llvmlite/tests/test_refprune.py +574 -0
  38. llvmlite/tests/test_valuerepr.py +60 -0
  39. llvmlite/utils.py +29 -0
  40. llvmlite-0.46.0b1.dist-info/METADATA +145 -0
  41. llvmlite-0.46.0b1.dist-info/RECORD +45 -0
  42. llvmlite-0.46.0b1.dist-info/WHEEL +6 -0
  43. llvmlite-0.46.0b1.dist-info/licenses/LICENSE +24 -0
  44. llvmlite-0.46.0b1.dist-info/licenses/LICENSE.thirdparty +225 -0
  45. llvmlite-0.46.0b1.dist-info/top_level.txt +1 -0
llvmlite/ir/types.py ADDED
@@ -0,0 +1,730 @@
1
+ """
2
+ Classes that are LLVM types
3
+ """
4
+
5
+ import struct
6
+
7
+ from llvmlite import ir_layer_typed_pointers_enabled
8
+ from llvmlite.ir._utils import _StrCaching
9
+
10
+
11
+ def _wrapname(x):
12
+ return '"{0}"'.format(x.replace('\\', '\\5c').replace('"', '\\22'))
13
+
14
+
15
+ class Type(_StrCaching):
16
+ """
17
+ The base class for all LLVM types.
18
+ """
19
+ is_pointer = False
20
+ null = 'zeroinitializer'
21
+
22
+ def __repr__(self):
23
+ return "<%s %s>" % (type(self), str(self))
24
+
25
+ def _to_string(self):
26
+ raise NotImplementedError
27
+
28
+ def as_pointer(self, addrspace=0):
29
+ return PointerType(self, addrspace)
30
+
31
+ def __ne__(self, other):
32
+ return not (self == other)
33
+
34
+ def _get_ll_global_value_type(self, target_data, context=None):
35
+ """
36
+ Convert this type object to an LLVM type.
37
+ """
38
+ from llvmlite.ir import Module, GlobalVariable
39
+ from llvmlite.binding import parse_assembly
40
+
41
+ if context is None:
42
+ m = Module()
43
+ else:
44
+ m = Module(context=context)
45
+ foo = GlobalVariable(m, self, name="foo")
46
+ with parse_assembly(str(m)) as llmod:
47
+ return llmod.get_global_variable(foo.name).global_value_type
48
+
49
+ def get_abi_size(self, target_data, context=None):
50
+ """
51
+ Get the ABI size of this type according to data layout *target_data*.
52
+ """
53
+ llty = self._get_ll_global_value_type(target_data, context)
54
+ return target_data.get_abi_size(llty)
55
+
56
+ def get_element_offset(self, target_data, ndx, context=None):
57
+ llty = self._get_ll_global_value_type(target_data, context)
58
+ return target_data.get_element_offset(llty, ndx)
59
+
60
+ def get_abi_alignment(self, target_data, context=None):
61
+ """
62
+ Get the minimum ABI alignment of this type according to data layout
63
+ *target_data*.
64
+ """
65
+ llty = self._get_ll_global_value_type(target_data, context)
66
+ return target_data.get_abi_alignment(llty)
67
+
68
+ def format_constant(self, value):
69
+ """
70
+ Format constant *value* of this type. This method may be overriden
71
+ by subclasses.
72
+ """
73
+ return str(value)
74
+
75
+ def wrap_constant_value(self, value):
76
+ """
77
+ Wrap constant *value* if necessary. This method may be overriden
78
+ by subclasses (especially aggregate types).
79
+ """
80
+ return value
81
+
82
+ def __call__(self, value):
83
+ """
84
+ Create a LLVM constant of this type with the given Python value.
85
+ """
86
+ from llvmlite.ir import Constant
87
+ return Constant(self, value)
88
+
89
+
90
+ class MetaDataType(Type):
91
+
92
+ def _to_string(self):
93
+ return "metadata"
94
+
95
+ def as_pointer(self):
96
+ raise TypeError
97
+
98
+ def __eq__(self, other):
99
+ return isinstance(other, MetaDataType)
100
+
101
+ def __hash__(self):
102
+ return hash(MetaDataType)
103
+
104
+
105
+ class LabelType(Type):
106
+ """
107
+ The label type is the type of e.g. basic blocks.
108
+ """
109
+
110
+ def _to_string(self):
111
+ return "label"
112
+
113
+
114
+ class PointerType(Type):
115
+ """
116
+ The type of all pointer values.
117
+ By default (without specialisation) represents an opaque pointer.
118
+ """
119
+ is_opaque = True
120
+ is_pointer = True
121
+ null = 'null'
122
+
123
+ # Factory to create typed or opaque pointers based on `pointee'.
124
+ def __new__(cls, pointee=None, addrspace=0):
125
+ if cls is PointerType and pointee is not None:
126
+ return super().__new__(_TypedPointerType)
127
+ return super(PointerType, cls).__new__(cls)
128
+
129
+ def __init__(self, addrspace=0):
130
+ self.addrspace = addrspace
131
+
132
+ def _to_string(self):
133
+ if self.addrspace != 0:
134
+ return "ptr addrspace({0})".format(self.addrspace)
135
+ else:
136
+ return "ptr"
137
+
138
+ def __eq__(self, other):
139
+ return (isinstance(other, PointerType) and
140
+ self.addrspace == other.addrspace)
141
+
142
+ def __hash__(self):
143
+ return hash(PointerType)
144
+
145
+ @property
146
+ def intrinsic_name(self):
147
+ return 'p%d' % self.addrspace
148
+
149
+ @classmethod
150
+ def from_llvm(cls, typeref, ir_ctx):
151
+ """
152
+ Create from a llvmlite.binding.TypeRef
153
+ """
154
+ return cls()
155
+
156
+
157
+ class _TypedPointerType(PointerType):
158
+ """
159
+ The type of typed pointer values. To be removed eventually.
160
+ """
161
+
162
+ def __init__(self, pointee, addrspace=0):
163
+ super(_TypedPointerType, self).__init__(addrspace)
164
+ assert pointee is not None
165
+ assert not isinstance(pointee, VoidType)
166
+ self.pointee = pointee
167
+ self.is_opaque = False
168
+
169
+ def _to_string(self):
170
+ if ir_layer_typed_pointers_enabled:
171
+ return "{0}*".format(self.pointee) if self.addrspace == 0 else \
172
+ "{0} addrspace({1})*".format(self.pointee, self.addrspace)
173
+ return super(_TypedPointerType, self)._to_string()
174
+
175
+ # This implements ``isOpaqueOrPointeeTypeEquals''.
176
+ def __eq__(self, other):
177
+ if isinstance(other, _TypedPointerType):
178
+ return (self.pointee, self.addrspace) == (other.pointee,
179
+ other.addrspace)
180
+ return (isinstance(other, PointerType) and
181
+ self.addrspace == other.addrspace)
182
+
183
+ def __hash__(self):
184
+ return hash(_TypedPointerType)
185
+
186
+ def gep(self, i):
187
+ """
188
+ Resolve the type of the i-th element (for getelementptr lookups).
189
+ """
190
+ if not isinstance(i.type, IntType):
191
+ raise TypeError(i.type)
192
+ return self.pointee
193
+
194
+ @property
195
+ def intrinsic_name(self):
196
+ if ir_layer_typed_pointers_enabled:
197
+ return 'p%d%s' % (self.addrspace, self.pointee.intrinsic_name)
198
+ return super(_TypedPointerType, self).intrinsic_name
199
+
200
+
201
+ class VoidType(Type):
202
+ """
203
+ The type for empty values (e.g. a function returning no value).
204
+ """
205
+
206
+ def _to_string(self):
207
+ return 'void'
208
+
209
+ def __eq__(self, other):
210
+ return isinstance(other, VoidType)
211
+
212
+ def __hash__(self):
213
+ return hash(VoidType)
214
+
215
+ @classmethod
216
+ def from_llvm(cls, typeref, ir_ctx):
217
+ """
218
+ Create from a llvmlite.binding.TypeRef
219
+ """
220
+ return cls()
221
+
222
+
223
+ class FunctionType(Type):
224
+ """
225
+ The type for functions.
226
+ """
227
+
228
+ def __init__(self, return_type, args, var_arg=False):
229
+ self.return_type = return_type
230
+ self.args = tuple(args)
231
+ self.var_arg = var_arg
232
+
233
+ def _to_string(self):
234
+ if self.args:
235
+ strargs = ', '.join([str(a) for a in self.args])
236
+ if self.var_arg:
237
+ return '{0} ({1}, ...)'.format(self.return_type, strargs)
238
+ else:
239
+ return '{0} ({1})'.format(self.return_type, strargs)
240
+ elif self.var_arg:
241
+ return '{0} (...)'.format(self.return_type)
242
+ else:
243
+ return '{0} ()'.format(self.return_type)
244
+
245
+ def __eq__(self, other):
246
+ if isinstance(other, FunctionType):
247
+ return (self.return_type == other.return_type and
248
+ self.args == other.args and self.var_arg == other.var_arg)
249
+ else:
250
+ return False
251
+
252
+ def __hash__(self):
253
+ return hash(FunctionType)
254
+
255
+ @classmethod
256
+ def from_llvm(cls, typeref, ir_ctx):
257
+ """
258
+ Create from a llvmlite.binding.TypeRef
259
+ """
260
+ params = tuple(x.as_ir(ir_ctx=ir_ctx)
261
+ for x in typeref.get_function_parameters())
262
+ ret = typeref.get_function_return().as_ir(ir_ctx=ir_ctx)
263
+ is_vararg = typeref.is_function_vararg
264
+ return cls(ret, params, is_vararg)
265
+
266
+
267
+ class IntType(Type):
268
+ """
269
+ The type for integers.
270
+ """
271
+ null = '0'
272
+ _instance_cache = {}
273
+ width: int
274
+
275
+ def __new__(cls, bits):
276
+ # Cache all common integer types
277
+ if 0 <= bits <= 128:
278
+ try:
279
+ return cls._instance_cache[bits]
280
+ except KeyError:
281
+ inst = cls._instance_cache[bits] = cls.__new(bits)
282
+ return inst
283
+ return cls.__new(bits)
284
+
285
+ @classmethod
286
+ def __new(cls, bits):
287
+ assert isinstance(bits, int) and bits >= 0
288
+ self = super(IntType, cls).__new__(cls)
289
+ self.width = bits
290
+ return self
291
+
292
+ def __getnewargs__(self):
293
+ return self.width,
294
+
295
+ def __copy__(self):
296
+ return self
297
+
298
+ def _to_string(self):
299
+ return 'i%u' % (self.width,)
300
+
301
+ def __eq__(self, other):
302
+ if isinstance(other, IntType):
303
+ return self.width == other.width
304
+ else:
305
+ return False
306
+
307
+ def __hash__(self):
308
+ return hash(IntType)
309
+
310
+ def format_constant(self, val):
311
+ if isinstance(val, bool):
312
+ return str(val).lower()
313
+ else:
314
+ return str(val)
315
+
316
+ def wrap_constant_value(self, val):
317
+ if val is None:
318
+ return 0
319
+ return val
320
+
321
+ @property
322
+ def intrinsic_name(self):
323
+ return str(self)
324
+
325
+ @classmethod
326
+ def from_llvm(cls, typeref, ir_ctx):
327
+ """
328
+ Create from a llvmlite.binding.TypeRef
329
+ """
330
+ return IntType(typeref.type_width)
331
+
332
+
333
+ def _as_float(value):
334
+ """
335
+ Truncate to single-precision float.
336
+ """
337
+ return struct.unpack('f', struct.pack('f', value))[0]
338
+
339
+
340
+ def _as_half(value):
341
+ """
342
+ Truncate to half-precision float.
343
+ """
344
+ try:
345
+ return struct.unpack('e', struct.pack('e', value))[0]
346
+ except struct.error:
347
+ # 'e' only added in Python 3.6+
348
+ return _as_float(value)
349
+
350
+
351
+ def _format_float_as_hex(value, packfmt, unpackfmt, numdigits):
352
+ raw = struct.pack(packfmt, float(value))
353
+ intrep = struct.unpack(unpackfmt, raw)[0]
354
+ out = '{{0:#{0}x}}'.format(numdigits).format(intrep)
355
+ return out
356
+
357
+
358
+ def _format_double(value):
359
+ """
360
+ Format *value* as a hexadecimal string of its IEEE double precision
361
+ representation.
362
+ """
363
+ return _format_float_as_hex(value, 'd', 'Q', 16)
364
+
365
+
366
+ class _BaseFloatType(Type):
367
+
368
+ def __new__(cls):
369
+ return cls._instance_cache
370
+
371
+ def __eq__(self, other):
372
+ return isinstance(other, type(self))
373
+
374
+ def __hash__(self):
375
+ return hash(type(self))
376
+
377
+ @classmethod
378
+ def _create_instance(cls):
379
+ cls._instance_cache = super(_BaseFloatType, cls).__new__(cls)
380
+
381
+ @classmethod
382
+ def from_llvm(cls, typeref, ir_ctx):
383
+ """
384
+ Create from a llvmlite.binding.TypeRef
385
+ """
386
+ return cls()
387
+
388
+
389
+ class HalfType(_BaseFloatType):
390
+ """
391
+ The type for single-precision floats.
392
+ """
393
+ null = '0.0'
394
+ intrinsic_name = 'f16'
395
+
396
+ def __str__(self):
397
+ return 'half'
398
+
399
+ def format_constant(self, value):
400
+ return _format_double(_as_half(value))
401
+
402
+
403
+ class FloatType(_BaseFloatType):
404
+ """
405
+ The type for single-precision floats.
406
+ """
407
+ null = '0.0'
408
+ intrinsic_name = 'f32'
409
+
410
+ def __str__(self):
411
+ return 'float'
412
+
413
+ def format_constant(self, value):
414
+ return _format_double(_as_float(value))
415
+
416
+
417
+ class DoubleType(_BaseFloatType):
418
+ """
419
+ The type for double-precision floats.
420
+ """
421
+ null = '0.0'
422
+ intrinsic_name = 'f64'
423
+
424
+ def __str__(self):
425
+ return 'double'
426
+
427
+ def format_constant(self, value):
428
+ return _format_double(value)
429
+
430
+
431
+ for _cls in (HalfType, FloatType, DoubleType):
432
+ _cls._create_instance()
433
+
434
+
435
+ class _Repeat(object):
436
+ def __init__(self, value, size):
437
+ self.value = value
438
+ self.size = size
439
+
440
+ def __len__(self):
441
+ return self.size
442
+
443
+ def __getitem__(self, item):
444
+ if 0 <= item < self.size:
445
+ return self.value
446
+ else:
447
+ raise IndexError(item)
448
+
449
+
450
+ class VectorType(Type):
451
+ """
452
+ The type for vectors of primitive data items (e.g. "<f32 x 4>").
453
+ """
454
+
455
+ def __init__(self, element, count):
456
+ self.element = element
457
+ self.count = count
458
+
459
+ @property
460
+ def elements(self):
461
+ return _Repeat(self.element, self.count)
462
+
463
+ def __len__(self):
464
+ return self.count
465
+
466
+ def _to_string(self):
467
+ return "<%d x %s>" % (self.count, self.element)
468
+
469
+ def __eq__(self, other):
470
+ if isinstance(other, VectorType):
471
+ return self.element == other.element and self.count == other.count
472
+
473
+ def __hash__(self):
474
+ # TODO: why does this not take self.element/self.count into account?
475
+ return hash(VectorType)
476
+
477
+ def __copy__(self):
478
+ return self
479
+
480
+ def format_constant(self, value):
481
+ itemstring = ", " .join(["{0} {1}".format(x.type, x.get_reference())
482
+ for x in value])
483
+ return "<{0}>".format(itemstring)
484
+
485
+ def wrap_constant_value(self, values):
486
+ from . import Value, Constant
487
+ if not isinstance(values, (list, tuple)):
488
+ if isinstance(values, Constant):
489
+ if values.type != self.element:
490
+ raise TypeError("expected {} for {}".format(
491
+ self.element, values.type))
492
+ return (values, ) * self.count
493
+ return (Constant(self.element, values), ) * self.count
494
+ if len(values) != len(self):
495
+ raise ValueError("wrong constant size for %s: got %d elements"
496
+ % (self, len(values)))
497
+ return [Constant(ty, val) if not isinstance(val, Value) else val
498
+ for ty, val in zip(self.elements, values)]
499
+
500
+ @classmethod
501
+ def from_llvm(cls, typeref, ir_ctx):
502
+ """
503
+ Create from a llvmlite.binding.TypeRef
504
+ """
505
+ [elemtyperef] = typeref.elements
506
+ elemty = elemtyperef.as_ir(ir_ctx=ir_ctx)
507
+ count = typeref.element_count
508
+ return cls(elemty, count)
509
+
510
+
511
+ class Aggregate(Type):
512
+ """
513
+ Base class for aggregate types.
514
+ See http://llvm.org/docs/LangRef.html#t-aggregate
515
+ """
516
+
517
+ def wrap_constant_value(self, values):
518
+ from . import Value, Constant
519
+
520
+ if not isinstance(values, (list, tuple)):
521
+ return values
522
+ if len(values) != len(self):
523
+ raise ValueError("wrong constant size for %s: got %d elements"
524
+ % (self, len(values)))
525
+ return [Constant(ty, val) if not isinstance(val, Value) else val
526
+ for ty, val in zip(self.elements, values)]
527
+
528
+
529
+ class ArrayType(Aggregate):
530
+ """
531
+ The type for fixed-size homogenous arrays (e.g. "[f32 x 3]").
532
+ """
533
+
534
+ def __init__(self, element, count):
535
+ self.element = element
536
+ self.count = count
537
+
538
+ @property
539
+ def elements(self):
540
+ return _Repeat(self.element, self.count)
541
+
542
+ def __len__(self):
543
+ return self.count
544
+
545
+ def _to_string(self):
546
+ return "[%d x %s]" % (self.count, self.element)
547
+
548
+ def __eq__(self, other):
549
+ if isinstance(other, ArrayType):
550
+ return self.element == other.element and self.count == other.count
551
+
552
+ def __hash__(self):
553
+ return hash(ArrayType)
554
+
555
+ def gep(self, i):
556
+ """
557
+ Resolve the type of the i-th element (for getelementptr lookups).
558
+ """
559
+ if not isinstance(i.type, IntType):
560
+ raise TypeError(i.type)
561
+ return self.element
562
+
563
+ def format_constant(self, value):
564
+ itemstring = ", " .join(["{0} {1}".format(x.type, x.get_reference())
565
+ for x in value])
566
+ return "[{0}]".format(itemstring)
567
+
568
+ @classmethod
569
+ def from_llvm(cls, typeref, ir_ctx):
570
+ """
571
+ Create from a llvmlite.binding.TypeRef
572
+ """
573
+ [elemtyperef] = typeref.elements
574
+ elemty = elemtyperef.as_ir(ir_ctx=ir_ctx)
575
+ count = typeref.element_count
576
+ return cls(elemty, count)
577
+
578
+
579
+ class BaseStructType(Aggregate):
580
+ """
581
+ The base type for heterogenous struct types.
582
+ """
583
+ _packed = False
584
+
585
+ @property
586
+ def packed(self):
587
+ """
588
+ A boolean attribute that indicates whether the structure uses
589
+ packed layout.
590
+ """
591
+ return self._packed
592
+
593
+ @packed.setter
594
+ def packed(self, val):
595
+ self._packed = bool(val)
596
+
597
+ def __len__(self):
598
+ assert self.elements is not None
599
+ return len(self.elements)
600
+
601
+ def __iter__(self):
602
+ assert self.elements is not None
603
+ return iter(self.elements)
604
+
605
+ @property
606
+ def is_opaque(self):
607
+ return self.elements is None
608
+
609
+ def structure_repr(self):
610
+ """
611
+ Return the LLVM IR for the structure representation
612
+ """
613
+ ret = '{%s}' % ', '.join([str(x) for x in self.elements])
614
+ return self._wrap_packed(ret)
615
+
616
+ def format_constant(self, value):
617
+ itemstring = ", " .join(["{0} {1}".format(x.type, x.get_reference())
618
+ for x in value])
619
+ ret = "{{{0}}}".format(itemstring)
620
+ return self._wrap_packed(ret)
621
+
622
+ def gep(self, i):
623
+ """
624
+ Resolve the type of the i-th element (for getelementptr lookups).
625
+
626
+ *i* needs to be a LLVM constant, so that the type can be determined
627
+ at compile-time.
628
+ """
629
+ if not isinstance(i.type, IntType):
630
+ raise TypeError(i.type)
631
+ return self.elements[i.constant]
632
+
633
+ def _wrap_packed(self, textrepr):
634
+ """
635
+ Internal helper to wrap textual repr of struct type into packed struct
636
+ """
637
+ if self.packed:
638
+ return '<{}>'.format(textrepr)
639
+ else:
640
+ return textrepr
641
+
642
+ @classmethod
643
+ def from_llvm(cls, typeref, ir_ctx):
644
+ """
645
+ Create from a llvmlite.binding.TypeRef
646
+ """
647
+ if typeref.is_literal_struct:
648
+ elems = [el.as_ir(ir_ctx=ir_ctx) for el in typeref.elements]
649
+ return cls(elems, typeref.is_packed_struct)
650
+ else:
651
+ return ir_ctx.get_identified_type(typeref.name)
652
+
653
+
654
+ class LiteralStructType(BaseStructType):
655
+ """
656
+ The type of "literal" structs, i.e. structs with a literally-defined
657
+ type (by contrast with IdentifiedStructType).
658
+ """
659
+
660
+ null = 'zeroinitializer'
661
+
662
+ def __init__(self, elems, packed=False):
663
+ """
664
+ *elems* is a sequence of types to be used as members.
665
+ *packed* controls the use of packed layout.
666
+ """
667
+ self.elements = tuple(elems)
668
+ self.packed = packed
669
+
670
+ def _to_string(self):
671
+ return self.structure_repr()
672
+
673
+ def __eq__(self, other):
674
+ if isinstance(other, LiteralStructType):
675
+ return (self.elements == other.elements
676
+ and self.packed == other.packed)
677
+
678
+ def __hash__(self):
679
+ return hash(LiteralStructType)
680
+
681
+
682
+ class IdentifiedStructType(BaseStructType):
683
+ """
684
+ A type which is a named alias for another struct type, akin to a typedef.
685
+ While literal struct types can be structurally equal (see
686
+ LiteralStructType), identified struct types are compared by name.
687
+
688
+ Do not use this directly.
689
+ """
690
+ null = 'zeroinitializer'
691
+
692
+ def __init__(self, context, name, packed=False):
693
+ """
694
+ *context* is a llvmlite.ir.Context.
695
+ *name* is the identifier for the new struct type.
696
+ *packed* controls the use of packed layout.
697
+ """
698
+ assert name
699
+ self.context = context
700
+ self.name = name
701
+ self.elements = None
702
+ self.packed = packed
703
+
704
+ def _to_string(self):
705
+ return "%{name}".format(name=_wrapname(self.name))
706
+
707
+ def get_declaration(self):
708
+ """
709
+ Returns the string for the declaration of the type
710
+ """
711
+ if self.is_opaque:
712
+ out = "{strrep} = type opaque".format(strrep=str(self))
713
+ else:
714
+ out = "{strrep} = type {struct}".format(
715
+ strrep=str(self), struct=self.structure_repr())
716
+ return out
717
+
718
+ def __eq__(self, other):
719
+ if isinstance(other, IdentifiedStructType):
720
+ return (self.name == other.name
721
+ and self.packed == other.packed)
722
+
723
+ def __hash__(self):
724
+ return hash(IdentifiedStructType)
725
+
726
+ def set_body(self, *elems):
727
+ if not self.is_opaque:
728
+ raise RuntimeError("{name} is already defined".format(
729
+ name=self.name))
730
+ self.elements = tuple(elems)