type.c 27.8 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
yb9976's avatar
yb9976 committed
10
 * @brief
Michael Beck's avatar
Michael Beck committed
11
12
13
14
 *
 *  Implementation of the datastructure to hold
 *  type information.
 *
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 *  This module supplies a datastructure to represent all types
 *  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
43
#include "xmalloc.h"
#include "irprog_t.h"
#include "ircons.h"
#include "tpop_t.h"
#include "tv_t.h"
#include "irhooks.h"
44
#include "util.h"
45
#include "entity_t.h"
Matthias Braun's avatar
Matthias Braun committed
46
#include "panic.h"
47
#include "dbginfo.h"
48
#include "irprog_t.h"
49
#include "bitfiddle.h"
50

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

53
static ir_type *new_type(tp_op const *type_op, ir_mode *mode);
54
static void free_compound_entities(ir_type *type);
Christoph Mallon's avatar
Christoph Mallon committed
55

56
57
ir_type *get_code_type(void)
{
58
	return irp->code_type;
59
}
60

61
62
ir_type *get_unknown_type(void)
{
63
	return irp->unknown_type;
64
}
65

66
void ir_init_type(ir_prog *irp)
67
{
68
	irp->code_type = new_type(tpop_code, mode_ANY);
69
	set_type_state(irp->code_type, layout_fixed);
70

71
	irp->unknown_type = new_type(tpop_unknown, mode_ANY);
72
	set_type_state (irp->unknown_type, layout_fixed);
73
74

	irp->dummy_owner = new_type_struct(new_id_from_str("$dummy_owner$"));
75
76
}

77
void ir_finish_type(ir_prog *irp)
78
{
Matthias Braun's avatar
Matthias Braun committed
79
	/** nothing todo. (The code, unknown types are in the global type list
80
81
	 * and freed there */
	(void)irp;
82
83
}

84
ir_visited_t firm_type_visited;
85

86
void set_master_type_visited(ir_visited_t val)
87
{
88
	firm_type_visited = val;
89
90
91
92
}

ir_visited_t (get_master_type_visited)(void)
{
93
	return get_master_type_visited_();
94
}
Christian Schäfer's avatar
Christian Schäfer committed
95

96
void inc_master_type_visited(void)
97
{
98
	++firm_type_visited;
99
100
}

Christoph Mallon's avatar
Christoph Mallon committed
101
102
103
104
105
106
107
108
109
/**
 *   Creates a new type representation:
 *
 *   @param type_op  the kind of this type.  May not be type_id.
 *   @param mode     the mode to be used for this type, may be NULL
 *
 *   @return A new type of the given type.  The remaining private attributes are
 *           not initialized.  The type is in state layout_undefined.
 */
110
static ir_type *new_type(tp_op const *type_op, ir_mode *mode)
111
{
Matthias Braun's avatar
Matthias Braun committed
112
113
	size_t   const node_size = offsetof(ir_type, attr) +  type_op->attr_size;
	ir_type *const res       = (ir_type*)xmalloc(node_size);
114
115
116
117
118
	memset(res, 0, node_size);

	res->kind       = k_type;
	res->type_op    = type_op;
	res->mode       = mode;
119
	res->visibility = ir_visibility_external;
120
	res->flags      = tf_none;
121
122
	res->size       = 0;
	res->align      = 0;
123
124
125
	res->visit      = 0;
	res->link       = NULL;
	res->nr         = get_irp_new_node_nr();
Christian Schäfer's avatar
Christian Schäfer committed
126

127
	add_irp_type(res);   /* Remember the new type global. */
128

129
	return res;
Christian Schäfer's avatar
Christian Schäfer committed
130
131
}

132
void free_type_entities(ir_type *const type)
133
{
134
135
	if (is_compound_type(type))
		free_compound_entities(type);
136
137
138
139
140
141
142
143
144
}

static void free_type_attrs(ir_type *tp)
{
	const tp_op *tpop = get_type_tpop(tp);
	if (tpop->ops.free_attrs)
		tpop->ops.free_attrs(tp);
}

145
146
void free_type(ir_type *tp)
{
147
	free_type_entities(tp);
148
149
150
151
152
	/* 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... */
153
#ifdef DEBUG_libfirm
154
	tp->kind = k_BAD;
155
#endif
156
	free(tp);
157
158
}

159
160
void *(get_type_link)(const ir_type *tp)
{
161
	return get_type_link_(tp);
162
163
}

164
165
void (set_type_link)(ir_type *tp, void *l)
{
166
	set_type_link_(tp, l);
167
168
}

169
170
const tp_op *(get_type_tpop)(const ir_type *tp)
{
171
	return get_type_tpop_(tp);
Christian Schäfer's avatar
Christian Schäfer committed
172
173
}

174
175
ident *(get_type_tpop_nameid)(const ir_type *tp)
{
176
	return get_type_tpop_nameid_(tp);
Christian Schäfer's avatar
Christian Schäfer committed
177
}
178

179
180
181
182
183
static inline bool is_type(const void *thing)
{
	return get_kind(thing) == k_type;
}

184
185
const char* get_type_tpop_name(const ir_type *tp)
{
Matthias Braun's avatar
Matthias Braun committed
186
	assert(is_type(tp));
187
	return get_id_str(tp->type_op->name);
188
}
189

190
191
tp_opcode (get_type_tpop_code)(const ir_type *tp)
{
192
	return get_type_tpop_code_(tp);
193
}
194

195
196
ir_mode *(get_type_mode)(const ir_type *tp)
{
197
	return get_type_mode_(tp);
198
}
199

200
201
long get_type_nr(const ir_type *tp)
{
Matthias Braun's avatar
Matthias Braun committed
202
	assert(is_type(tp));
203
	return tp->nr;
204
205
}

206
207
unsigned (get_type_size_bytes)(const ir_type *tp)
{
208
	return get_type_size_bytes_(tp);
209
210
}

211
212
ir_visibility get_type_visibility(const ir_type *tp)
{
213
214
	assert(is_type(tp));
	return tp->visibility;
215
216
}

217
218
void set_type_visibility(ir_type *tp, ir_visibility v)
{
219
220
	assert(is_type(tp));
	tp->visibility = v;
221
222
}

223
224
void set_type_size_bytes(ir_type *tp, unsigned size)
{
225
	tp->size = size;
226
227
}

228
unsigned (get_type_alignment_bytes)(const ir_type *type)
229
{
230
	return get_type_alignment_bytes_(type);
Michael Beck's avatar
Michael Beck committed
231
232
}

233
void set_type_alignment_bytes(ir_type *type, unsigned align)
234
{
235
236
237
	assert(is_type(type));
	assert(align > 0);
	type->align = align;
Michael Beck's avatar
Michael Beck committed
238
239
}

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

251
252
ir_type_state (get_type_state)(const ir_type *tp)
{
253
	return get_type_state_(tp);
254
255
}

256
257
void set_type_state(ir_type *tp, ir_type_state state)
{
Matthias Braun's avatar
Matthias Braun committed
258
	assert(is_type(tp));
259

Matthias Braun's avatar
Matthias Braun committed
260
261
	if (tp->type_op == type_pointer || tp->type_op == type_primitive
	    || tp->type_op == type_method)
262
263
		return;

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

283
284
ir_visited_t (get_type_visited)(const ir_type *tp)
{
285
	return get_type_visited_(tp);
286
}
287

288
289
void (set_type_visited)(ir_type *tp, ir_visited_t num)
{
290
	set_type_visited_(tp, num);
291
}
292

293
294
void (mark_type_visited)(ir_type *tp)
{
295
	mark_type_visited_(tp);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
296
297
}

298
299
int (type_visited)(const ir_type *tp)
{
300
	return type_visited_(tp);
301
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
302

303
type_dbg_info *(get_type_dbg_info)(const ir_type *tp)
304
{
305
	return get_type_dbg_info_(tp);
306
307
}

308
void (set_type_dbg_info)(ir_type *tp, type_dbg_info *db)
309
{
310
	set_type_dbg_info_(tp, db);
311
312
}

313
static void compound_init(ir_type *const type, ident *const name)
314
{
315
	type->name            = name;
316
317
318
	type->attr.ca.members = NEW_ARR_F(ir_entity*, 0);
}

319
void free_compound_attrs(ir_type *type)
320
321
322
323
{
	DEL_ARR_F(type->attr.ca.members);
}

324
static void free_compound_entities(ir_type *type)
325
{
Matthias Braun's avatar
Matthias Braun committed
326
327
	for (size_t i = get_compound_n_members(type); i-- > 0; )
		free_entity(get_compound_member(type, i));
328
329
}

330
ir_type *new_type_class(ident *name)
331
{
332
	ir_type *res = new_type(type_class, NULL);
333
	compound_init(res, name);
334
335
	res->attr.cla.subtypes   = NEW_ARR_F(ir_type*, 0);
	res->attr.cla.supertypes = NEW_ARR_F(ir_type*, 0);
336
337
	hook_new_type(res);
	return res;
Christian Schäfer's avatar
Christian Schäfer committed
338
}
339

340
341
void free_class_attrs(ir_type *clss)
{
342
	assert(is_Class_type(clss));
343
	free_compound_attrs(clss);
344
345
	DEL_ARR_F(clss->attr.cla.subtypes);
	DEL_ARR_F(clss->attr.cla.supertypes);
346
}
347

348
349
ident *get_class_ident(const ir_type *clss)
{
350
	assert(is_Class_type(clss));
351
352
353
354
355
	return clss->name;
}

const char *get_class_name(const ir_type *clss)
{
356
357
	if (get_class_ident(clss) == NULL)
		return NULL;
358
359
360
	return get_id_str(get_class_ident(clss));
}

Matthias Braun's avatar
Matthias Braun committed
361
size_t get_class_n_members(const ir_type *clss)
362
{
Matthias Braun's avatar
Matthias Braun committed
363
364
	assert(is_Class_type(clss));
	return get_compound_n_members(clss);
Christian Schäfer's avatar
Christian Schäfer committed
365
}
366

Matthias Braun's avatar
Matthias Braun committed
367
ir_entity *get_class_member(ir_type const *const clss, size_t const pos)
368
{
369
	assert(is_Class_type(clss));
Matthias Braun's avatar
Matthias Braun committed
370
	return get_compound_member(clss, pos);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
371
}
372

Matthias Braun's avatar
Matthias Braun committed
373
size_t get_class_member_index(ir_type const *clss, ir_entity const *const mem)
374
{
Matthias Braun's avatar
Matthias Braun committed
375
376
	assert(is_Class_type(clss));
	return get_compound_member_index(clss, mem);
377
}
378

379
380
void add_class_subtype(ir_type *clss, ir_type *subtype)
{
Matthias Braun's avatar
Matthias Braun committed
381
	assert(is_Class_type(clss));
382
	ARR_APP1(ir_type *, clss->attr.cla.subtypes, subtype);
Matthias Braun's avatar
Matthias Braun committed
383
384
	for (size_t i = 0, n_supertypes = get_class_n_supertypes(subtype);
	     i < n_supertypes; i++) {
385
386
387
		if (get_class_supertype(subtype, i) == clss)
			/* Class already registered */
			return;
388
	}
389
	ARR_APP1(ir_type *, subtype->attr.cla.supertypes, clss);
390
391
}

392
size_t get_class_n_subtypes(const ir_type *clss)
393
{
Matthias Braun's avatar
Matthias Braun committed
394
	assert(is_Class_type(clss));
395
	return ARR_LEN(clss->attr.cla.subtypes);
396
397
}

398
ir_type *get_class_subtype(const ir_type *clss, size_t pos)
399
{
Matthias Braun's avatar
Matthias Braun committed
400
	assert(is_Class_type(clss));
401
	assert(pos < get_class_n_subtypes(clss));
402
	return clss->attr.cla.subtypes[pos];
403
404
}

405
size_t get_class_subtype_index(const ir_type *clss, const ir_type *subclass)
406
{
Matthias Braun's avatar
Matthias Braun committed
407
	assert(is_Class_type(clss) && is_Class_type(subclass));
Matthias Braun's avatar
Matthias Braun committed
408
409
	for (size_t i = 0, n_subtypes = get_class_n_subtypes(clss);
	     i < n_subtypes; ++i) {
410
411
		if (get_class_subtype(clss, i) == subclass)
			return i;
412
	}
413
	return (size_t)-1;
414
415
}

416
void set_class_subtype(ir_type *clss, ir_type *subtype, size_t pos)
417
{
Matthias Braun's avatar
Matthias Braun committed
418
	assert(is_Class_type(clss));
419
	assert(pos < get_class_n_subtypes(clss));
420
	clss->attr.cla.subtypes[pos] = subtype;
421
422
}

423
424
void remove_class_subtype(ir_type *clss, ir_type *subtype)
{
Matthias Braun's avatar
Matthias Braun committed
425
	assert(is_Class_type(clss));
426
427
428
429
430
	for (size_t i = 0; i < ARR_LEN(clss->attr.cla.subtypes); ++i) {
		if (clss->attr.cla.subtypes[i] == subtype) {
			for (; i < ARR_LEN(clss->attr.cla.subtypes) - 1; ++i)
				clss->attr.cla.subtypes[i] = clss->attr.cla.subtypes[i+1];
			ARR_SETLEN(ir_type*, clss->attr.cla.subtypes, ARR_LEN(clss->attr.cla.subtypes) - 1);
431
432
			break;
		}
433
	}
434
435
}

436
437
void add_class_supertype(ir_type *clss, ir_type *supertype)
{
Matthias Braun's avatar
Matthias Braun committed
438
	assert(is_Class_type(clss));
Matthias Braun's avatar
Matthias Braun committed
439
	assert(supertype->type_op == type_class);
440
	ARR_APP1(ir_type *, clss->attr.cla.supertypes, supertype);
Matthias Braun's avatar
Matthias Braun committed
441
	for (size_t i = 0, n = get_class_n_subtypes(supertype); i < n; ++i) {
442
443
444
		if (get_class_subtype(supertype, i) == clss)
			/* Class already registered */
			return;
445
	}
446
	ARR_APP1(ir_type *, supertype->attr.cla.subtypes, clss);
447
448
}

449
size_t get_class_n_supertypes(const ir_type *clss)
450
{
Matthias Braun's avatar
Matthias Braun committed
451
	assert(is_Class_type(clss));
452
	return ARR_LEN(clss->attr.cla.supertypes);
453
454
}

455
size_t get_class_supertype_index(const ir_type *clss, const ir_type *super_clss)
456
{
Matthias Braun's avatar
Matthias Braun committed
457
	assert(is_Class_type(clss) && is_Class_type(super_clss));
Matthias Braun's avatar
Matthias Braun committed
458
459
	for (size_t i = 0, n_supertypes = get_class_n_supertypes(clss);
	     i < n_supertypes; i++) {
460
461
		if (get_class_supertype(clss, i) == super_clss)
			return i;
462
463
	}
	return (size_t)-1;
464
}
465

466
ir_type *get_class_supertype(const ir_type *clss, size_t pos)
467
{
Matthias Braun's avatar
Matthias Braun committed
468
	assert(is_Class_type(clss));
469
	assert(pos < get_class_n_supertypes(clss));
470
	return clss->attr.cla.supertypes[pos];
471
472
}

473
void set_class_supertype(ir_type *clss, ir_type *supertype, size_t pos)
474
{
Matthias Braun's avatar
Matthias Braun committed
475
	assert(is_Class_type(clss));
476
	assert(pos < get_class_n_supertypes(clss));
477
	clss->attr.cla.supertypes[pos] = supertype;
478
479
}

480
481
void remove_class_supertype(ir_type *clss, ir_type *supertype)
{
Matthias Braun's avatar
Matthias Braun committed
482
	assert(is_Class_type(clss));
483
484
485
486
487
	for (size_t i = 0; i < ARR_LEN(clss->attr.cla.supertypes); ++i) {
		if (clss->attr.cla.supertypes[i] == supertype) {
			for (; i < ARR_LEN(clss->attr.cla.supertypes) - 1; ++i)
				clss->attr.cla.supertypes[i] = clss->attr.cla.supertypes[i+1];
			ARR_SETLEN(ir_type*, clss->attr.cla.supertypes, ARR_LEN(clss->attr.cla.supertypes) - 1);
488
489
			break;
		}
490
	}
491
492
}

493
494
int (is_Class_type)(const ir_type *clss)
{
495
	return is_class_type_(clss);
496
}
Christian Schäfer's avatar
Christian Schäfer committed
497
498


499
ir_type *new_type_struct(ident *name)
500
{
501
	ir_type *res = new_type(type_struct, NULL);
502
	compound_init(res, name);
503
504
	hook_new_type(res);
	return res;
Christian Schäfer's avatar
Christian Schäfer committed
505
}
506

507
508
ident *get_struct_ident(const ir_type *strct)
{
509
	assert(is_Struct_type(strct));
510
511
512
513
514
	return strct->name;
}

const char *get_struct_name(const ir_type *strct)
{
Matthias Braun's avatar
Matthias Braun committed
515
516
	ident *id = get_struct_ident(strct);
	if (id == NULL)
517
		return NULL;
Matthias Braun's avatar
Matthias Braun committed
518
	return get_id_str(id);
519
520
}

521
size_t get_struct_n_members(const ir_type *strct)
522
{
523
	assert(is_Struct_type(strct));
Matthias Braun's avatar
Matthias Braun committed
524
	return get_compound_n_members(strct);
525
}
526

527
ir_entity *get_struct_member(const ir_type *strct, size_t pos)
528
{
529
	assert(is_Struct_type(strct));
Matthias Braun's avatar
Matthias Braun committed
530
	return get_compound_member(strct, pos);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
531
}
532

Matthias Braun's avatar
Matthias Braun committed
533
size_t get_struct_member_index(ir_type const *strct, ir_entity const *const mem)
534
{
535
	assert(is_Struct_type(strct));
Matthias Braun's avatar
Matthias Braun committed
536
	return get_compound_member_index(strct, mem);
537
538
}

539
540
int (is_Struct_type)(const ir_type *strct)
{
541
	return is_struct_type_(strct);
Christian Schäfer's avatar
Christian Schäfer committed
542
543
}

544
ir_type *new_type_method(size_t n_param, size_t n_res)
545
{
546
	ir_type *res = new_type(type_method, mode_P);
547
548
549
550
551
552
553
554
	res->flags             |= tf_layout_fixed;
	res->size               = get_mode_size_bytes(mode_P);
	res->attr.ma.n_params   = n_param;
	res->attr.ma.params     = XMALLOCNZ(ir_type*, n_param);
	res->attr.ma.n_res      = n_res;
	res->attr.ma.res_type   = XMALLOCNZ(ir_type*, n_res);
	res->attr.ma.variadic   = false;
	res->attr.ma.properties = mtp_no_property;
555
	set_type_alignment_bytes(res, 1);
556
557
	hook_new_type(res);
	return res;
Christian Schäfer's avatar
Christian Schäfer committed
558
}
Michael Beck's avatar
fixed:    
Michael Beck committed
559

560
ir_type *clone_type_method(ir_type *tp)
561
{
Michael Beck's avatar
Michael Beck committed
562
	assert(is_Method_type(tp));
Matthias Braun's avatar
Matthias Braun committed
563
564
565
566
	ir_mode       *mode     = tp->mode;
	size_t         n_params = tp->attr.ma.n_params;
	size_t         n_res    = tp->attr.ma.n_res;
	type_dbg_info *db       = tp->dbi;
567
568
	ir_type       *res      = new_type(type_method, mode);
	set_type_dbg_info(res, db);
Michael Beck's avatar
Michael Beck committed
569

Matthias Braun's avatar
Matthias Braun committed
570
571
572
573
	res->flags                    = tp->flags;
	res->higher_type              = tp->higher_type;
	res->size                     = tp->size;
	res->attr.ma.n_params         = n_params;
574
	res->attr.ma.params           = XMALLOCN(ir_type*, n_params);
Christoph Mallon's avatar
Christoph Mallon committed
575
	MEMCPY(res->attr.ma.params, tp->attr.ma.params, n_params);
Matthias Braun's avatar
Matthias Braun committed
576
	res->attr.ma.n_res            = n_res;
577
	res->attr.ma.res_type         = XMALLOCN(ir_type*, n_res);
Christoph Mallon's avatar
Christoph Mallon committed
578
	MEMCPY(res->attr.ma.res_type, tp->attr.ma.res_type, n_res);
579
	res->attr.ma.variadic         = tp->attr.ma.variadic;
Matthias Braun's avatar
Matthias Braun committed
580
581
	res->attr.ma.properties       = tp->attr.ma.properties;
	res->attr.ma.irg_calling_conv = tp->attr.ma.irg_calling_conv;
582
	set_type_alignment_bytes(res, get_type_alignment_bytes(tp));
Michael Beck's avatar
Michael Beck committed
583
584
585
586
	hook_new_type(res);
	return res;
}

587
588
void free_method_attrs(ir_type *method)
{
Matthias Braun's avatar
Matthias Braun committed
589
	assert(is_Method_type(method));
590
591
	free(method->attr.ma.params);
	free(method->attr.ma.res_type);
592
}
Michael Beck's avatar
fixed:    
Michael Beck committed
593

594
size_t (get_method_n_params)(const ir_type *method)
595
{
596
	return get_method_n_params_(method);
Christian Schäfer's avatar
Christian Schäfer committed
597
}
598

599
ir_type *get_method_param_type(const ir_type *method, size_t pos)
600
{
Matthias Braun's avatar
Matthias Braun committed
601
	assert(is_Method_type(method));
602
	assert(pos < get_method_n_params(method));
603
	ir_type *res = method->attr.ma.params[pos];
Matthias Braun's avatar
Matthias Braun committed
604
	return res;
Christian Schäfer's avatar
Christian Schäfer committed
605
}
606

607
void set_method_param_type(ir_type *method, size_t pos, ir_type *tp)
608
{
Matthias Braun's avatar
Matthias Braun committed
609
	assert(is_Method_type(method));
610
	assert(pos < get_method_n_params(method));
611
	method->attr.ma.params[pos] = tp;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
612
613
}

614
size_t (get_method_n_ress)(const ir_type *method)
615
{
616
	return get_method_n_ress_(method);
Christian Schäfer's avatar
Christian Schäfer committed
617
}
618

619
ir_type *get_method_res_type(const ir_type *method, size_t pos)
620
{
Matthias Braun's avatar
Matthias Braun committed
621
	assert(is_Method_type(method));
622
	assert(pos < get_method_n_ress(method));
623
	ir_type *res = method->attr.ma.res_type[pos];
Matthias Braun's avatar
Matthias Braun committed
624
	return res;
625
}
626

627
void set_method_res_type(ir_type *method, size_t pos, ir_type *tp)
628
{
Matthias Braun's avatar
Matthias Braun committed
629
	assert(is_Method_type(method));
630
	assert(pos < get_method_n_ress(method));
631
	method->attr.ma.res_type[pos] = tp;
632
633
}

634
int is_method_variadic(ir_type const *const method)
635
{
Matthias Braun's avatar
Matthias Braun committed
636
	assert(is_Method_type(method));
637
	return method->attr.ma.variadic;
638
639
}

640
void set_method_variadic(ir_type *const method, int const is_variadic)
641
{
Matthias Braun's avatar
Matthias Braun committed
642
	assert(is_Method_type(method));
643
	method->attr.ma.variadic = is_variadic;
644
645
}

646
mtp_additional_properties (get_method_additional_properties)(const ir_type *method)
647
{
648
	return get_method_additional_properties_(method);
649
650
}

651
void (set_method_additional_properties)(ir_type *method, mtp_additional_properties mask)
652
{
653
	set_method_additional_properties_(method, mask);
654
655
}

Matthias Braun's avatar
Matthias Braun committed
656
657
void (add_method_additional_properties)(ir_type *method,
                                        mtp_additional_properties flag)
658
{
659
	add_method_additional_properties_(method, flag);
660
661
}

662
663
unsigned (get_method_calling_convention)(const ir_type *method)
{
664
	return get_method_calling_convention_(method);
665
666
}

667
668
void (set_method_calling_convention)(ir_type *method, unsigned cc_mask)
{
669
	set_method_calling_convention_(method, cc_mask);
670
671
}

672
673
unsigned get_method_n_regparams(ir_type *method)
{
674
675
	unsigned cc = get_method_calling_convention(method);
	assert(IS_FASTCALL(cc));
676

677
	return cc & ~cc_bits;
678
679
}

680
681
void set_method_n_regparams(ir_type *method, unsigned n_regs)
{
682
683
	unsigned cc = get_method_calling_convention(method);
	assert(IS_FASTCALL(cc));
684

685
	set_method_calling_convention(method, (cc & cc_bits) | (n_regs & ~cc_bits));
686
687
}

688
689
int (is_Method_type)(const ir_type *method)
{
690
	return is_method_type_(method);
691
}
Christian Schäfer's avatar
Christian Schäfer committed
692

693
ir_type *new_type_union(ident *name)
694
{
695
	ir_type *res = new_type(type_union, NULL);
696
	compound_init(res, name);
697
698
	hook_new_type(res);
	return res;
Christian Schäfer's avatar
Christian Schäfer committed
699
}
700

701
702
ident *get_union_ident(const ir_type *uni)
{
703
	assert(is_Union_type(uni));
704
705
706
707
708
	return uni->name;
}

const char *get_union_name(const ir_type *uni)
{
Matthias Braun's avatar
Matthias Braun committed
709
710
	ident *id = get_union_ident(uni);
	if (id == NULL)
711
		return NULL;
Matthias Braun's avatar
Matthias Braun committed
712
	return get_id_str(id);
713
714
}

715
size_t get_union_n_members(const ir_type *uni)
716
{
717
	assert(is_Union_type(uni));
Matthias Braun's avatar
Matthias Braun committed
718
	return get_compound_n_members(uni);
719
720
}

721
ir_entity *get_union_member(const ir_type *uni, size_t pos)
722
{
723
	assert(is_Union_type(uni));
Matthias Braun's avatar
Matthias Braun committed
724
	return get_compound_member(uni, pos);
725
726
}

Matthias Braun's avatar
Matthias Braun committed
727
size_t get_union_member_index(ir_type const *uni, ir_entity const *const mem)
728
{
729
	assert(is_Union_type(uni));
Matthias Braun's avatar
Matthias Braun committed
730
	return get_compound_member_index(uni, mem);
731
732
}

733
734
int (is_Union_type)(const ir_type *uni)
{
735
	return is_union_type_(uni);
Christian Schäfer's avatar
Christian Schäfer committed
736
737
}

738
739
740
741
742
743
744
ir_type *new_type_segment(ident *const name, type_flags const flags)
{
	ir_type *const seg = new_type_class(name);
	seg->flags |= tf_segment | flags;
	return seg;
}

745
746
747
748
749
int is_segment_type(const ir_type *type)
{
	return (type->flags & tf_segment) != 0;
}