type.c 24.4 KB
Newer Older
Christian Würdig's avatar
Christian Würdig committed
1
2
/*
 * This file is part of libFirm.
3
 * Copyright (C) 2012 University of Karlsruhe.
Christian Würdig's avatar
Christian Würdig committed
4
5
 */

Sebastian Felis's avatar
Sebastian Felis committed
6
/**
7
 * @file
Michael Beck's avatar
Michael Beck committed
8
9
 * @brief   Representation of types.
 * @author  Goetz Lindenmaier, Michael Beck
10
 * @brief
Michael Beck's avatar
Michael Beck committed
11
 *
12
 *  Implementation of the data structure to hold
Michael Beck's avatar
Michael Beck committed
13
14
 *  type information.
 *
15
 *  This module supplies a data structure to represent all types
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 *  known in the compiled program.  This includes types specified
 *  in the program as well as types defined by the language.  In the
 *  view of the intermediate representation there is no difference
 *  between these types.
 *
 *  There exist several kinds of types, arranged by the structure of
 *  the type.  A type is described by a set of attributes.  Some of
 *  these attributes are common to all types, others depend on the
 *  kind of the type.
 *
 *  Types are different from the modes defined in irmode:  Types are
 *  on the level of the programming language, modes at the level of
 *  the target processor.
 */
30
#include <string.h>
31
#include <stdlib.h>
32
#include <stddef.h>
33
#include <stdbool.h>
34

35
#include "irnode_t.h"
36
#include "type_t.h"
37

38
39
40
41
42
#include "xmalloc.h"
#include "irprog_t.h"
#include "ircons.h"
#include "tv_t.h"
#include "irhooks.h"
43
#include "util.h"
44
#include "entity_t.h"
Matthias Braun's avatar
Matthias Braun committed
45
#include "panic.h"
46
#include "dbginfo.h"
47
#include "irprog_t.h"
48
#include "bitfiddle.h"
49

50
#include "array.h"
Christian Schäfer's avatar
Christian Schäfer committed
51

52
static ir_type *new_type(tp_opcode opcode, size_t attr_size, ir_mode *mode);
53
static void free_compound_entities(ir_type *type);
Christoph Mallon's avatar
Christoph Mallon committed
54

55
56
57
58
59
60
61
62
63
const char *get_type_opcode_name(tp_opcode const opcode)
{
	switch (opcode) {
	case tpo_array:         return "array";
	case tpo_class:         return "class";
	case tpo_code:          return "code";
	case tpo_method:        return "method";
	case tpo_pointer:       return "pointer";
	case tpo_primitive:     return "primitive";
64
	case tpo_segment:       return "segment";
65
66
67
68
69
70
71
72
	case tpo_struct:        return "struct";
	case tpo_uninitialized: return "uninitialized";
	case tpo_union:         return "union";
	case tpo_unknown:       return "unknown";
	}
	panic("Invalid type opcode");
}

73
74
ir_type *get_code_type(void)
{
75
	return irp->code_type;
76
}
77

78
79
ir_type *get_unknown_type(void)
{
80
	return irp->unknown_type;
81
}
82

83
void ir_init_type(ir_prog *irp)
84
{
85
	irp->code_type = new_type(tpo_code, 0, mode_ANY);
86
	set_type_state(irp->code_type, layout_fixed);
87

88
	irp->unknown_type = new_type(tpo_unknown, 0, mode_ANY);
89
	set_type_state (irp->unknown_type, layout_fixed);
90
91

	irp->dummy_owner = new_type_struct(new_id_from_str("$dummy_owner$"));
92
93
}

94
void ir_finish_type(ir_prog *irp)
95
{
Matthias Braun's avatar
Matthias Braun committed
96
	/** nothing todo. (The code, unknown types are in the global type list
97
98
	 * and freed there */
	(void)irp;
99
100
}

101
ir_visited_t firm_type_visited;
102

103
void set_master_type_visited(ir_visited_t val)
104
{
105
	firm_type_visited = val;
106
107
108
109
}

ir_visited_t (get_master_type_visited)(void)
{
110
	return get_master_type_visited_();
111
}
Christian Schäfer's avatar
Christian Schäfer committed
112

113
void inc_master_type_visited(void)
114
{
115
	++firm_type_visited;
116
117
}

Christoph Mallon's avatar
Christoph Mallon committed
118
119
120
121
122
/**
 *   Creates a new type representation:
 *   @return A new type of the given type.  The remaining private attributes are
 *           not initialized.  The type is in state layout_undefined.
 */
123
124
static ir_type *new_type(tp_opcode const opcode, size_t attr_size,
                         ir_mode *const mode)
125
{
126
	size_t   const node_size = offsetof(ir_type, attr) +  attr_size;
Matthias Braun's avatar
Matthias Braun committed
127
	ir_type *const res       = (ir_type*)xmalloc(node_size);
128
129
	memset(res, 0, node_size);

130
131
132
133
134
135
136
137
138
	res->kind   = k_type;
	res->opcode = opcode;
	res->mode   = mode;
	res->flags  = tf_none;
	res->size   = 0;
	res->align  = 0;
	res->visit  = 0;
	res->link   = NULL;
	res->nr     = get_irp_new_node_nr();
Christian Schäfer's avatar
Christian Schäfer committed
139

140
	add_irp_type(res);   /* Remember the new type global. */
141

142
	return res;
Christian Schäfer's avatar
Christian Schäfer committed
143
144
}

145
void free_type_entities(ir_type *const type)
146
{
147
148
	if (is_compound_type(type))
		free_compound_entities(type);
149
150
}

151
static void free_type_attrs(ir_type *const type)
152
{
153
	switch (get_type_opcode(type)) {
154
155
156
	case tpo_class:
		free_class_attrs(type);
		return;
157
	case tpo_segment:
158
	case tpo_struct:
159
	case tpo_union:
160
161
162
163
164
165
166
167
168
169
170
171
172
173
		free_compound_attrs(type);
		return;
	case tpo_method:
		free_method_attrs(type);
		return;
	case tpo_code:
	case tpo_primitive:
	case tpo_pointer:
	case tpo_array:
	case tpo_unknown:
	case tpo_uninitialized:
		return;
	}
	panic("Invalid type");
174
175
}

176
177
void free_type(ir_type *tp)
{
178
	free_type_entities(tp);
179
180
181
182
183
	/* Remove from list of all types */
	remove_irp_type(tp);
	/* Free the attributes of the type. */
	free_type_attrs(tp);
	/* And now the type itself... */
184
#ifdef DEBUG_libfirm
185
	tp->kind = k_BAD;
186
#endif
187
	free(tp);
188
189
}

190
191
void *(get_type_link)(const ir_type *tp)
{
192
	return get_type_link_(tp);
193
194
}

195
196
void (set_type_link)(ir_type *tp, void *l)
{
197
	set_type_link_(tp, l);
198
199
}

200
201
202
203
204
static inline bool is_type(const void *thing)
{
	return get_kind(thing) == k_type;
}

205
tp_opcode (get_type_opcode)(ir_type const *const type)
206
{
207
	return get_type_opcode_(type);
208
}
209

210
211
ir_mode *(get_type_mode)(const ir_type *tp)
{
212
	return get_type_mode_(tp);
213
}
214

215
216
long get_type_nr(const ir_type *tp)
{
Matthias Braun's avatar
Matthias Braun committed
217
	assert(is_type(tp));
218
	return tp->nr;
219
220
}

221
unsigned (get_type_size)(const ir_type *tp)
222
{
223
	return get_type_size_(tp);
224
225
}

226
void set_type_size(ir_type *tp, unsigned size)
227
{
228
	tp->size = size;
229
230
}

231
unsigned (get_type_alignment)(const ir_type *type)
232
{
233
	return get_type_alignment_(type);
Michael Beck's avatar
Michael Beck committed
234
235
}

236
void set_type_alignment(ir_type *type, unsigned align)
237
{
238
239
240
	assert(is_type(type));
	assert(align > 0);
	type->align = align;
Michael Beck's avatar
Michael Beck committed
241
242
}

243
244
const char *get_type_state_name(ir_type_state s)
{
245
#define X(a)    case a: return #a
246
247
248
249
250
	switch (s) {
		X(layout_undefined);
		X(layout_fixed);
	}
	return "<unknown>";
Götz Lindenmaier's avatar
Götz Lindenmaier committed
251
252
253
#undef X
}

254
255
ir_type_state (get_type_state)(const ir_type *tp)
{
256
	return get_type_state_(tp);
257
258
}

259
260
void set_type_state(ir_type *tp, ir_type_state state)
{
Matthias Braun's avatar
Matthias Braun committed
261
	assert(is_type(tp));
262

263
264
265
	tp_opcode opcode = get_type_opcode(tp);
	if (opcode == tpo_pointer || opcode == tpo_primitive
	 || opcode == tpo_method)
266
267
		return;

Matthias Braun's avatar
Matthias Braun committed
268
#ifndef NDEBUG
269
	/* Just a correctness check: */
Matthias Braun's avatar
Matthias Braun committed
270
	if (state == layout_fixed && is_compound_type(tp)
271
	 && !is_segment_type(tp)) {
Matthias Braun's avatar
Matthias Braun committed
272
273
274
		for (size_t i = 0, n_mem = get_compound_n_members(tp);
			 i < n_mem; i++) {
			ir_entity *entity = get_compound_member(tp, i);
275
			if (is_method_entity(entity))
Matthias Braun's avatar
Matthias Braun committed
276
				continue;
277
			assert(get_entity_offset(entity) != INVALID_OFFSET);
Eduard Frank's avatar
Eduard Frank committed
278
		}
279
	}
Matthias Braun's avatar
Matthias Braun committed
280
#endif
281
282
283
284
	if (state == layout_fixed)
		tp->flags |= tf_layout_fixed;
	else
		tp->flags &= ~tf_layout_fixed;
285
286
}

287
288
ir_visited_t (get_type_visited)(const ir_type *tp)
{
289
	return get_type_visited_(tp);
290
}
291

292
293
void (set_type_visited)(ir_type *tp, ir_visited_t num)
{
294
	set_type_visited_(tp, num);
295
}
296

297
298
void (mark_type_visited)(ir_type *tp)
{
299
	mark_type_visited_(tp);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
300
301
}

302
303
int (type_visited)(const ir_type *tp)
{
304
	return type_visited_(tp);
305
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
306

307
type_dbg_info *(get_type_dbg_info)(const ir_type *tp)
308
{
309
	return get_type_dbg_info_(tp);
310
311
}

312
void (set_type_dbg_info)(ir_type *tp, type_dbg_info *db)
313
{
314
	set_type_dbg_info_(tp, db);
315
316
}

317
static void compound_init(ir_type *const type, ident *const name)
318
{
319
320
321
	type->flags                |= tf_compound;
	type->name                  = name;
	type->attr.compound.members = NEW_ARR_F(ir_entity*, 0);
322
323
}

324
void free_compound_attrs(ir_type *type)
325
{
326
	DEL_ARR_F(type->attr.compound.members);
327
328
}

329
static void free_compound_entities(ir_type *type)
330
{
Matthias Braun's avatar
Matthias Braun committed
331
332
	for (size_t i = get_compound_n_members(type); i-- > 0; )
		free_entity(get_compound_member(type, i));
333
334
}

335
ir_type *new_type_class(ident *name)
336
{
337
	ir_type *res = new_type(tpo_class, sizeof(class_attr), NULL);
338
	compound_init(res, name);
339
340
	res->attr.cls.subtypes   = NEW_ARR_F(ir_type*, 0);
	res->attr.cls.supertypes = NEW_ARR_F(ir_type*, 0);
341
342
	hook_new_type(res);
	return res;
Christian Schäfer's avatar
Christian Schäfer committed
343
}
344

345
346
void free_class_attrs(ir_type *clss)
{
347
	assert(is_Class_type(clss));
348
	free_compound_attrs(clss);
349
350
	DEL_ARR_F(clss->attr.cls.subtypes);
	DEL_ARR_F(clss->attr.cls.supertypes);
351
}
352

Matthias Braun's avatar
Matthias Braun committed
353
size_t get_class_n_members(const ir_type *clss)
354
{
Matthias Braun's avatar
Matthias Braun committed
355
356
	assert(is_Class_type(clss));
	return get_compound_n_members(clss);
Christian Schäfer's avatar
Christian Schäfer committed
357
}
358

Matthias Braun's avatar
Matthias Braun committed
359
ir_entity *get_class_member(ir_type const *const clss, size_t const pos)
360
{
361
	assert(is_Class_type(clss));
Matthias Braun's avatar
Matthias Braun committed
362
	return get_compound_member(clss, pos);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
363
}
364

Matthias Braun's avatar
Matthias Braun committed
365
size_t get_class_member_index(ir_type const *clss, ir_entity const *const mem)
366
{
Matthias Braun's avatar
Matthias Braun committed
367
368
	assert(is_Class_type(clss));
	return get_compound_member_index(clss, mem);
369
}
370

371
372
void add_class_subtype(ir_type *clss, ir_type *subtype)
{
Matthias Braun's avatar
Matthias Braun committed
373
	assert(is_Class_type(clss));
374
	ARR_APP1(ir_type *, clss->attr.cls.subtypes, subtype);
Matthias Braun's avatar
Matthias Braun committed
375
376
	for (size_t i = 0, n_supertypes = get_class_n_supertypes(subtype);
	     i < n_supertypes; i++) {
377
378
379
		if (get_class_supertype(subtype, i) == clss)
			/* Class already registered */
			return;
380
	}
381
	ARR_APP1(ir_type *, subtype->attr.cls.supertypes, clss);
382
383
}

384
size_t get_class_n_subtypes(const ir_type *clss)
385
{
Matthias Braun's avatar
Matthias Braun committed
386
	assert(is_Class_type(clss));
387
	return ARR_LEN(clss->attr.cls.subtypes);
388
389
}

390
ir_type *get_class_subtype(const ir_type *clss, size_t pos)
391
{
Matthias Braun's avatar
Matthias Braun committed
392
	assert(is_Class_type(clss));
393
	assert(pos < get_class_n_subtypes(clss));
394
	return clss->attr.cls.subtypes[pos];
395
396
}

397
size_t get_class_subtype_index(const ir_type *clss, const ir_type *subclass)
398
{
Matthias Braun's avatar
Matthias Braun committed
399
	assert(is_Class_type(clss) && is_Class_type(subclass));
Matthias Braun's avatar
Matthias Braun committed
400
401
	for (size_t i = 0, n_subtypes = get_class_n_subtypes(clss);
	     i < n_subtypes; ++i) {
402
403
		if (get_class_subtype(clss, i) == subclass)
			return i;
404
	}
405
	return (size_t)-1;
406
407
}

408
void set_class_subtype(ir_type *clss, ir_type *subtype, size_t pos)
409
{
Matthias Braun's avatar
Matthias Braun committed
410
	assert(is_Class_type(clss));
411
	assert(pos < get_class_n_subtypes(clss));
412
	clss->attr.cls.subtypes[pos] = subtype;
413
414
}

415
416
void remove_class_subtype(ir_type *clss, ir_type *subtype)
{
Matthias Braun's avatar
Matthias Braun committed
417
	assert(is_Class_type(clss));
418
419
420
421
422
	for (size_t i = 0; i < ARR_LEN(clss->attr.cls.subtypes); ++i) {
		if (clss->attr.cls.subtypes[i] == subtype) {
			for (; i < ARR_LEN(clss->attr.cls.subtypes) - 1; ++i)
				clss->attr.cls.subtypes[i] = clss->attr.cls.subtypes[i+1];
			ARR_SETLEN(ir_type*, clss->attr.cls.subtypes, ARR_LEN(clss->attr.cls.subtypes) - 1);
423
424
			break;
		}
425
	}
426
427
}

428
429
void add_class_supertype(ir_type *clss, ir_type *supertype)
{
Matthias Braun's avatar
Matthias Braun committed
430
	assert(is_Class_type(clss));
431
	assert(is_Class_type(supertype));
432
	ARR_APP1(ir_type *, clss->attr.cls.supertypes, supertype);
Matthias Braun's avatar
Matthias Braun committed
433
	for (size_t i = 0, n = get_class_n_subtypes(supertype); i < n; ++i) {
434
435
436
		if (get_class_subtype(supertype, i) == clss)
			/* Class already registered */
			return;
437
	}
438
	ARR_APP1(ir_type *, supertype->attr.cls.subtypes, clss);
439
440
}

441
size_t get_class_n_supertypes(const ir_type *clss)
442
{
Matthias Braun's avatar
Matthias Braun committed
443
	assert(is_Class_type(clss));
444
	return ARR_LEN(clss->attr.cls.supertypes);
445
446
}

447
size_t get_class_supertype_index(const ir_type *clss, const ir_type *super_clss)
448
{
Matthias Braun's avatar
Matthias Braun committed
449
	assert(is_Class_type(clss) && is_Class_type(super_clss));
Matthias Braun's avatar
Matthias Braun committed
450
451
	for (size_t i = 0, n_supertypes = get_class_n_supertypes(clss);
	     i < n_supertypes; i++) {
452
453
		if (get_class_supertype(clss, i) == super_clss)
			return i;
454
455
	}
	return (size_t)-1;
456
}
457

458
ir_type *get_class_supertype(const ir_type *clss, size_t pos)
459
{
Matthias Braun's avatar
Matthias Braun committed
460
	assert(is_Class_type(clss));
461
	assert(pos < get_class_n_supertypes(clss));
462
	return clss->attr.cls.supertypes[pos];
463
464
}

465
void set_class_supertype(ir_type *clss, ir_type *supertype, size_t pos)
466
{
Matthias Braun's avatar
Matthias Braun committed
467
	assert(is_Class_type(clss));
468
	assert(pos < get_class_n_supertypes(clss));
469
	clss->attr.cls.supertypes[pos] = supertype;
470
471
}

472
473
void remove_class_supertype(ir_type *clss, ir_type *supertype)
{
Matthias Braun's avatar
Matthias Braun committed
474
	assert(is_Class_type(clss));
475
476
477
478
479
	for (size_t i = 0; i < ARR_LEN(clss->attr.cls.supertypes); ++i) {
		if (clss->attr.cls.supertypes[i] == supertype) {
			for (; i < ARR_LEN(clss->attr.cls.supertypes) - 1; ++i)
				clss->attr.cls.supertypes[i] = clss->attr.cls.supertypes[i+1];
			ARR_SETLEN(ir_type*, clss->attr.cls.supertypes, ARR_LEN(clss->attr.cls.supertypes) - 1);
480
481
			break;
		}
482
	}
483
484
}

485
486
int (is_Class_type)(const ir_type *clss)
{
487
	return is_class_type_(clss);
488
}
Christian Schäfer's avatar
Christian Schäfer committed
489
490


491
ir_type *new_type_struct(ident *name)
492
{
493
	ir_type *res = new_type(tpo_struct, sizeof(compound_attr), NULL);
494
	compound_init(res, name);
495
496
	hook_new_type(res);
	return res;
Christian Schäfer's avatar
Christian Schäfer committed
497
}
498

499
size_t get_struct_n_members(const ir_type *strct)
500
{
501
	assert(is_Struct_type(strct));
Matthias Braun's avatar
Matthias Braun committed
502
	return get_compound_n_members(strct);
503
}
504

505
ir_entity *get_struct_member(const ir_type *strct, size_t pos)
506
{
507
	assert(is_Struct_type(strct));
Matthias Braun's avatar
Matthias Braun committed
508
	return get_compound_member(strct, pos);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
509
}
510

Matthias Braun's avatar
Matthias Braun committed
511
size_t get_struct_member_index(ir_type const *strct, ir_entity const *const mem)
512
{
513
	assert(is_Struct_type(strct));
Matthias Braun's avatar
Matthias Braun committed
514
	return get_compound_member_index(strct, mem);
515
516
}

517
518
int (is_Struct_type)(const ir_type *strct)
{
519
	return is_struct_type_(strct);
Christian Schäfer's avatar
Christian Schäfer committed
520
521
}

522
ir_type *new_type_method(size_t const n_param, size_t const n_res, int const is_variadic, unsigned const cc_mask, mtp_additional_properties const property_mask)
523
{
524
	ir_type *res = new_type(tpo_method, sizeof(method_attr), mode_P);
525
526
527
528
529
530
531
532
	res->flags                       |= tf_layout_fixed;
	res->size                         = get_mode_size_bytes(mode_P);
	res->attr.method.n_params         = n_param;
	res->attr.method.params           = XMALLOCNZ(ir_type*, n_param);
	res->attr.method.n_res            = n_res;
	res->attr.method.res_type         = XMALLOCNZ(ir_type*, n_res);
	res->attr.method.variadic         = is_variadic;
	res->attr.method.irg_calling_conv = cc_mask;
533
	res->attr.method.properties       = property_mask;
534
	set_type_alignment(res, 1);
535
536
	hook_new_type(res);
	return res;
Christian Schäfer's avatar
Christian Schäfer committed
537
}
Michael Beck's avatar
fixed:    
Michael Beck committed
538

539
ir_type *clone_type_method(ir_type *const tp, bool const is_variadic, mtp_additional_properties const property_mask)
540
{
Michael Beck's avatar
Michael Beck committed
541
	assert(is_Method_type(tp));
Matthias Braun's avatar
Matthias Braun committed
542
	ir_mode       *mode     = tp->mode;
543
544
	size_t         n_params = tp->attr.method.n_params;
	size_t         n_res    = tp->attr.method.n_res;
Matthias Braun's avatar
Matthias Braun committed
545
	type_dbg_info *db       = tp->dbi;
546
	ir_type       *res      = new_type(tpo_method, sizeof(method_attr), mode);
547
	set_type_dbg_info(res, db);
Michael Beck's avatar
Michael Beck committed
548

549
550
551
552
553
554
555
556
557
	res->flags                        = tp->flags;
	res->higher_type                  = tp->higher_type;
	res->size                         = tp->size;
	res->attr.method.n_params         = n_params;
	res->attr.method.params           = XMALLOCN(ir_type*, n_params);
	MEMCPY(res->attr.method.params, tp->attr.method.params, n_params);
	res->attr.method.n_res            = n_res;
	res->attr.method.res_type         = XMALLOCN(ir_type*, n_res);
	MEMCPY(res->attr.method.res_type, tp->attr.method.res_type, n_res);
558
	res->attr.method.variadic         = is_variadic;
559
	res->attr.method.properties       = property_mask;
560
	res->attr.method.irg_calling_conv = tp->attr.method.irg_calling_conv;
561
	set_type_alignment(res, get_type_alignment(tp));
Michael Beck's avatar
Michael Beck committed
562
563
564
565
	hook_new_type(res);
	return res;
}

566
567
void free_method_attrs(ir_type *method)
{
Matthias Braun's avatar
Matthias Braun committed
568
	assert(is_Method_type(method));
569
570
	free(method->attr.method.params);
	free(method->attr.method.res_type);
571
}
Michael Beck's avatar
fixed:    
Michael Beck committed
572

573
size_t (get_method_n_params)(const ir_type *method)
574
{
575
	return get_method_n_params_(method);
Christian Schäfer's avatar
Christian Schäfer committed
576
}
577

578
ir_type *get_method_param_type(const ir_type *method, size_t pos)
579
{
Matthias Braun's avatar
Matthias Braun committed
580
	assert(is_Method_type(method));
581
	assert(pos < get_method_n_params(method));
582
	ir_type *res = method->attr.method.params[pos];
Matthias Braun's avatar
Matthias Braun committed
583
	return res;
Christian Schäfer's avatar
Christian Schäfer committed
584
}
585

586
void set_method_param_type(ir_type *method, size_t pos, ir_type *tp)
587
{
Matthias Braun's avatar
Matthias Braun committed
588
	assert(is_Method_type(method));
589
	assert(pos < get_method_n_params(method));
590
	method->attr.method.params[pos] = tp;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
591
592
}

593
size_t (get_method_n_ress)(const ir_type *method)
594
{
595
	return get_method_n_ress_(method);
Christian Schäfer's avatar
Christian Schäfer committed
596
}
597

598
ir_type *get_method_res_type(const ir_type *method, size_t pos)
599
{
Matthias Braun's avatar
Matthias Braun committed
600
	assert(is_Method_type(method));
601
	assert(pos < get_method_n_ress(method));
602
	ir_type *res = method->attr.method.res_type[pos];
Matthias Braun's avatar
Matthias Braun committed
603
	return res;
604
}
605

606
void set_method_res_type(ir_type *method, size_t pos, ir_type *tp)
607
{
Matthias Braun's avatar
Matthias Braun committed
608
	assert(is_Method_type(method));
609
	assert(pos < get_method_n_ress(method));
610
	method->attr.method.res_type[pos] = tp;
611
612
}

613
int is_method_variadic(ir_type const *const method)
614
{
Matthias Braun's avatar
Matthias Braun committed
615
	assert(is_Method_type(method));
616
	return method->attr.method.variadic;
617
618
}

619
mtp_additional_properties (get_method_additional_properties)(const ir_type *method)
620
{
621
	return get_method_additional_properties_(method);
622
623
}

624
625
unsigned (get_method_calling_convention)(const ir_type *method)
{
626
	return get_method_calling_convention_(method);
627
628
}

629
630
unsigned get_method_n_regparams(ir_type *method)
{
631
632
	unsigned cc = get_method_calling_convention(method);
	assert(IS_FASTCALL(cc));
633

634
	return cc & ~cc_bits;
635
636
}

637
638
int (is_Method_type)(const ir_type *method)
{
639
	return is_method_type_(method);
640
}
Christian Schäfer's avatar
Christian Schäfer committed
641

642
ir_type *new_type_union(ident *name)
643
{
644
	ir_type *res = new_type(tpo_union, sizeof(compound_attr), NULL);
645
	compound_init(res, name);
646
647
	hook_new_type(res);
	return res;
Christian Schäfer's avatar
Christian Schäfer committed
648
}
649

650
size_t get_union_n_members(const ir_type *uni)
651
{
652
	assert(is_Union_type(uni));
Matthias Braun's avatar
Matthias Braun committed
653
	return get_compound_n_members(uni);
654
655
}

656
ir_entity *get_union_member(const ir_type *uni, size_t pos)
657
{
658
	assert(is_Union_type(uni));
Matthias Braun's avatar
Matthias Braun committed
659
	return get_compound_member(uni, pos);
660
661
}

Matthias Braun's avatar
Matthias Braun committed
662
size_t get_union_member_index(ir_type const *uni, ir_entity const *const mem)
663
{
664
	assert(is_Union_type(uni));
Matthias Braun's avatar
Matthias Braun committed
665
	return get_compound_member_index(uni, mem);
666
667
}

668
669
int (is_Union_type)(const ir_type *uni)
{
670
	return is_union_type_(uni);
Christian Schäfer's avatar
Christian Schäfer committed
671
672
}

673
674
ir_type *new_type_segment(ident *const name, type_flags const flags)
{
675
676
677
678
679
680
681
682
683
	ir_type *const res = new_type(tpo_segment, sizeof(compound_attr), NULL);
	compound_init(res, name);
	res->flags |= flags;
	return res;
}

int (is_segment_type)(ir_type const *const type)
{
	return is_segment_type_(type);
684
685
}

Christoph Mallon's avatar
Christoph Mallon committed
686
ir_type *new_type_array(ir_type *const element_type, unsigned const n_elements)
687
{
688
689
	assert(!is_Method_type(element_type));

Christoph Mallon's avatar
Christoph Mallon committed
690
	ir_type *const res = new_type(tpo_array, sizeof(array_attr), NULL);
691
	res->attr.array.element_type = element_type;
Christoph Mallon's avatar
Christoph Mallon committed
692
	res->attr.array.size         = n_elements;
693
	set_type_alignment(res, get_type_alignment(element_type));
Christoph Mallon's avatar
Christoph Mallon committed
694
695
696
697
	if (n_elements != 0) {
		set_type_size(res, n_elements * get_type_size(element_type));
		set_type_state(res, layout_fixed);
	}
698
699
700

	hook_new_type(res);
	return res;
Christian Schäfer's avatar
Christian Schäfer committed
701
}
702

Christoph Mallon's avatar
Christoph Mallon committed
703
unsigned get_array_size(const ir_type *array)
704
{
Matthias Braun's avatar
Matthias Braun committed
705
	assert(is_Array_type(array));
706
	return array->attr.array.size;
Christian Schäfer's avatar
Christian Schäfer committed
707
}
708

709
ir_type *get_array_element_type(const ir_type *array)
710
{
Matthias Braun's avatar
Matthias Braun committed
711
	assert(is_Array_type(array));
712
	return array->attr.array.element_type;
Christian Schäfer's avatar
Christian Schäfer committed
713
}
714

715
716
int (is_Array_type)(const ir_type *array)
{
717
	return is_array_type_(array);
Christian Schäfer's avatar
Christian Schäfer committed
718
719
}

720

721
ir_type *new_type_pointer(ir_type *points_to)
722
{
723
	ir_mode *const mode = mode_P;
724
725
	ir_type *const res  = new_type(tpo_pointer, sizeof(pointer_attr), mode);
	res->attr.pointer.points_to = points_to;
726
727
	unsigned size = get_mode_size_bytes(mode);
	res->size = size;
728
	res->flags |= tf_layout_fixed;
729
	set_type_alignment(res, size);
730
731
	hook_new_type(res);
	return res;
Christian Schäfer's avatar
Christian Schäfer committed
732
}
733

734
735
void set_pointer_points_to_type(ir_type *pointer, ir_type *tp)
{
Matthias Braun's avatar
Matthias Braun committed
736
	assert(is_Pointer_type(pointer));
737
	pointer->attr.pointer.points_to = tp;
Christian Schäfer's avatar
Christian Schäfer committed
738
}
739

740
ir_type *get_pointer_points_to_type(const ir_type *pointer)
741
{
Matthias Braun's avatar
Matthias Braun committed
742
	assert(is_Pointer_type(pointer));
743
	return pointer->attr.pointer.points_to;
Christian Schäfer's avatar
Christian Schäfer committed
744
745
}

746
747
int (is_Pointer_type)(const ir_type *pointer)
{
748
	return is_pointer_type_(pointer);
Christian Schäfer's avatar
Christian Schäfer committed
749
750
}

751

752
ir_type *new_type_primitive(ir_mode *mode)
753
{
754
755
756
757
	unsigned size  = get_mode_size_bytes(mode);
	unsigned align = (size > 0 && size != (unsigned)-1)
	               ? ceil_po2(size) : 1;

758
	ir_type *res = new_type(tpo_primitive, 0, mode);