type.c 29.2 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
#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
130
	memset(res, 0, node_size);

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

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

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

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

152
static void free_type_attrs(ir_type *const type)
153
{
154
	switch (get_type_opcode(type)) {
155
156
157
	case tpo_class:
		free_class_attrs(type);
		return;
158
	case tpo_segment:
159
	case tpo_struct:
160
	case tpo_union:
161
162
163
164
165
166
167
168
169
170
171
172
173
174
		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");
175
176
}

177
178
void free_type(ir_type *tp)
{
179
	free_type_entities(tp);
180
181
182
183
184
	/* 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... */
185
#ifdef DEBUG_libfirm
186
	tp->kind = k_BAD;
187
#endif
188
	free(tp);
189
190
}

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

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

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

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

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

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

222
223
unsigned (get_type_size_bytes)(const ir_type *tp)
{
224
	return get_type_size_bytes_(tp);
225
226
}

227
228
ir_visibility get_type_visibility(const ir_type *tp)
{
229
230
	assert(is_type(tp));
	return tp->visibility;
231
232
}

233
234
void set_type_visibility(ir_type *tp, ir_visibility v)
{
235
236
	assert(is_type(tp));
	tp->visibility = v;
237
238
}

239
240
void set_type_size_bytes(ir_type *tp, unsigned size)
{
241
	tp->size = size;
242
243
}

244
unsigned (get_type_alignment_bytes)(const ir_type *type)
245
{
246
	return get_type_alignment_bytes_(type);
Michael Beck's avatar
Michael Beck committed
247
248
}

249
void set_type_alignment_bytes(ir_type *type, unsigned align)
250
{
251
252
253
	assert(is_type(type));
	assert(align > 0);
	type->align = align;
Michael Beck's avatar
Michael Beck committed
254
255
}

256
257
const char *get_type_state_name(ir_type_state s)
{
258
#define X(a)    case a: return #a
259
260
261
262
263
	switch (s) {
		X(layout_undefined);
		X(layout_fixed);
	}
	return "<unknown>";
Götz Lindenmaier's avatar
Götz Lindenmaier committed
264
265
266
#undef X
}

267
268
ir_type_state (get_type_state)(const ir_type *tp)
{
269
	return get_type_state_(tp);
270
271
}

272
273
void set_type_state(ir_type *tp, ir_type_state state)
{
Matthias Braun's avatar
Matthias Braun committed
274
	assert(is_type(tp));
275

276
277
278
	tp_opcode opcode = get_type_opcode(tp);
	if (opcode == tpo_pointer || opcode == tpo_primitive
	 || opcode == tpo_method)
279
280
		return;

Matthias Braun's avatar
Matthias Braun committed
281
#ifndef NDEBUG
282
	/* Just a correctness check: */
Matthias Braun's avatar
Matthias Braun committed
283
	if (state == layout_fixed && is_compound_type(tp)
284
	 && !is_segment_type(tp)) {
Matthias Braun's avatar
Matthias Braun committed
285
286
287
288
289
290
		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
291
		}
292
	}
Matthias Braun's avatar
Matthias Braun committed
293
#endif
294
295
296
297
	if (state == layout_fixed)
		tp->flags |= tf_layout_fixed;
	else
		tp->flags &= ~tf_layout_fixed;
298
299
}

300
301
ir_visited_t (get_type_visited)(const ir_type *tp)
{
302
	return get_type_visited_(tp);
303
}
304

305
306
void (set_type_visited)(ir_type *tp, ir_visited_t num)
{
307
	set_type_visited_(tp, num);
308
}
309

310
311
void (mark_type_visited)(ir_type *tp)
{
312
	mark_type_visited_(tp);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
313
314
}

315
316
int (type_visited)(const ir_type *tp)
{
317
	return type_visited_(tp);
318
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
319

320
type_dbg_info *(get_type_dbg_info)(const ir_type *tp)
321
{
322
	return get_type_dbg_info_(tp);
323
324
}

325
void (set_type_dbg_info)(ir_type *tp, type_dbg_info *db)
326
{
327
	set_type_dbg_info_(tp, db);
328
329
}

330
static void compound_init(ir_type *const type, ident *const name)
331
{
332
	type->flags          |= tf_compound;
333
	type->name            = name;
334
335
336
	type->attr.ca.members = NEW_ARR_F(ir_entity*, 0);
}

337
void free_compound_attrs(ir_type *type)
338
339
340
341
{
	DEL_ARR_F(type->attr.ca.members);
}

342
static void free_compound_entities(ir_type *type)
343
{
Matthias Braun's avatar
Matthias Braun committed
344
345
	for (size_t i = get_compound_n_members(type); i-- > 0; )
		free_entity(get_compound_member(type, i));
346
347
}

348
ir_type *new_type_class(ident *name)
349
{
350
	ir_type *res = new_type(tpo_class, sizeof(cls_attr), NULL);
351
	compound_init(res, name);
352
353
	res->attr.cla.subtypes   = NEW_ARR_F(ir_type*, 0);
	res->attr.cla.supertypes = NEW_ARR_F(ir_type*, 0);
354
355
	hook_new_type(res);
	return res;
Christian Schäfer's avatar
Christian Schäfer committed
356
}
357

358
359
void free_class_attrs(ir_type *clss)
{
360
	assert(is_Class_type(clss));
361
	free_compound_attrs(clss);
362
363
	DEL_ARR_F(clss->attr.cla.subtypes);
	DEL_ARR_F(clss->attr.cla.supertypes);
364
}
365

366
367
ident *get_class_ident(const ir_type *clss)
{
368
	assert(is_Class_type(clss));
369
370
371
372
373
	return clss->name;
}

const char *get_class_name(const ir_type *clss)
{
374
375
	if (get_class_ident(clss) == NULL)
		return NULL;
376
377
378
	return get_id_str(get_class_ident(clss));
}

Matthias Braun's avatar
Matthias Braun committed
379
size_t get_class_n_members(const ir_type *clss)
380
{
Matthias Braun's avatar
Matthias Braun committed
381
382
	assert(is_Class_type(clss));
	return get_compound_n_members(clss);
Christian Schäfer's avatar
Christian Schäfer committed
383
}
384

Matthias Braun's avatar
Matthias Braun committed
385
ir_entity *get_class_member(ir_type const *const clss, size_t const pos)
386
{
387
	assert(is_Class_type(clss));
Matthias Braun's avatar
Matthias Braun committed
388
	return get_compound_member(clss, pos);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
389
}
390

Matthias Braun's avatar
Matthias Braun committed
391
size_t get_class_member_index(ir_type const *clss, ir_entity const *const mem)
392
{
Matthias Braun's avatar
Matthias Braun committed
393
394
	assert(is_Class_type(clss));
	return get_compound_member_index(clss, mem);
395
}
396

397
398
void add_class_subtype(ir_type *clss, ir_type *subtype)
{
Matthias Braun's avatar
Matthias Braun committed
399
	assert(is_Class_type(clss));
400
	ARR_APP1(ir_type *, clss->attr.cla.subtypes, subtype);
Matthias Braun's avatar
Matthias Braun committed
401
402
	for (size_t i = 0, n_supertypes = get_class_n_supertypes(subtype);
	     i < n_supertypes; i++) {
403
404
405
		if (get_class_supertype(subtype, i) == clss)
			/* Class already registered */
			return;
406
	}
407
	ARR_APP1(ir_type *, subtype->attr.cla.supertypes, clss);
408
409
}

410
size_t get_class_n_subtypes(const ir_type *clss)
411
{
Matthias Braun's avatar
Matthias Braun committed
412
	assert(is_Class_type(clss));
413
	return ARR_LEN(clss->attr.cla.subtypes);
414
415
}

416
ir_type *get_class_subtype(const ir_type *clss, 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
	return clss->attr.cla.subtypes[pos];
421
422
}

423
size_t get_class_subtype_index(const ir_type *clss, const ir_type *subclass)
424
{
Matthias Braun's avatar
Matthias Braun committed
425
	assert(is_Class_type(clss) && is_Class_type(subclass));
Matthias Braun's avatar
Matthias Braun committed
426
427
	for (size_t i = 0, n_subtypes = get_class_n_subtypes(clss);
	     i < n_subtypes; ++i) {
428
429
		if (get_class_subtype(clss, i) == subclass)
			return i;
430
	}
431
	return (size_t)-1;
432
433
}

434
void set_class_subtype(ir_type *clss, ir_type *subtype, size_t pos)
435
{
Matthias Braun's avatar
Matthias Braun committed
436
	assert(is_Class_type(clss));
437
	assert(pos < get_class_n_subtypes(clss));
438
	clss->attr.cla.subtypes[pos] = subtype;
439
440
}

441
442
void remove_class_subtype(ir_type *clss, ir_type *subtype)
{
Matthias Braun's avatar
Matthias Braun committed
443
	assert(is_Class_type(clss));
444
445
446
447
448
	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);
449
450
			break;
		}
451
	}
452
453
}

454
455
void add_class_supertype(ir_type *clss, ir_type *supertype)
{
Matthias Braun's avatar
Matthias Braun committed
456
	assert(is_Class_type(clss));
457
	assert(is_Class_type(supertype));
458
	ARR_APP1(ir_type *, clss->attr.cla.supertypes, supertype);
Matthias Braun's avatar
Matthias Braun committed
459
	for (size_t i = 0, n = get_class_n_subtypes(supertype); i < n; ++i) {
460
461
462
		if (get_class_subtype(supertype, i) == clss)
			/* Class already registered */
			return;
463
	}
464
	ARR_APP1(ir_type *, supertype->attr.cla.subtypes, clss);
465
466
}

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

473
size_t get_class_supertype_index(const ir_type *clss, const ir_type *super_clss)
474
{
Matthias Braun's avatar
Matthias Braun committed
475
	assert(is_Class_type(clss) && is_Class_type(super_clss));
Matthias Braun's avatar
Matthias Braun committed
476
477
	for (size_t i = 0, n_supertypes = get_class_n_supertypes(clss);
	     i < n_supertypes; i++) {
478
479
		if (get_class_supertype(clss, i) == super_clss)
			return i;
480
481
	}
	return (size_t)-1;
482
}
483

484
ir_type *get_class_supertype(const ir_type *clss, size_t pos)
485
{
Matthias Braun's avatar
Matthias Braun committed
486
	assert(is_Class_type(clss));
487
	assert(pos < get_class_n_supertypes(clss));
488
	return clss->attr.cla.supertypes[pos];
489
490
}

491
void set_class_supertype(ir_type *clss, ir_type *supertype, size_t pos)
492
{
Matthias Braun's avatar
Matthias Braun committed
493
	assert(is_Class_type(clss));
494
	assert(pos < get_class_n_supertypes(clss));
495
	clss->attr.cla.supertypes[pos] = supertype;
496
497
}

498
499
void remove_class_supertype(ir_type *clss, ir_type *supertype)
{
Matthias Braun's avatar
Matthias Braun committed
500
	assert(is_Class_type(clss));
501
502
503
504
505
	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);
506
507
			break;
		}
508
	}
509
510
}

511
512
int (is_Class_type)(const ir_type *clss)
{
513
	return is_class_type_(clss);
514
}
Christian Schäfer's avatar
Christian Schäfer committed
515
516


517
ir_type *new_type_struct(ident *name)
518
{
519
	ir_type *res = new_type(tpo_struct, sizeof(compound_attr), NULL);
520
	compound_init(res, name);
521
522
	hook_new_type(res);
	return res;
Christian Schäfer's avatar
Christian Schäfer committed
523
}
524

525
526
ident *get_struct_ident(const ir_type *strct)
{
527
	assert(is_Struct_type(strct));
528
529
530
531
532
	return strct->name;
}

const char *get_struct_name(const ir_type *strct)
{
Matthias Braun's avatar
Matthias Braun committed
533
534
	ident *id = get_struct_ident(strct);
	if (id == NULL)
535
		return NULL;
Matthias Braun's avatar
Matthias Braun committed
536
	return get_id_str(id);
537
538
}

539
size_t get_struct_n_members(const ir_type *strct)
540
{
541
	assert(is_Struct_type(strct));
Matthias Braun's avatar
Matthias Braun committed
542
	return get_compound_n_members(strct);
543
}
544

545
ir_entity *get_struct_member(const ir_type *strct, size_t pos)
546
{
547
	assert(is_Struct_type(strct));
Matthias Braun's avatar
Matthias Braun committed
548
	return get_compound_member(strct, pos);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
549
}
550

Matthias Braun's avatar
Matthias Braun committed
551
size_t get_struct_member_index(ir_type const *strct, ir_entity const *const mem)
552
{
553
	assert(is_Struct_type(strct));
Matthias Braun's avatar
Matthias Braun committed
554
	return get_compound_member_index(strct, mem);
555
556
}

557
558
int (is_Struct_type)(const ir_type *strct)
{
559
	return is_struct_type_(strct);
Christian Schäfer's avatar
Christian Schäfer committed
560
561
}

562
ir_type *new_type_method(size_t n_param, size_t n_res)
563
{
564
	ir_type *res = new_type(tpo_method, sizeof(mtd_attr), mode_P);
565
566
567
568
569
570
571
572
	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;
573
	set_type_alignment_bytes(res, 1);
574
575
	hook_new_type(res);
	return res;
Christian Schäfer's avatar
Christian Schäfer committed
576
}
Michael Beck's avatar
fixed:    
Michael Beck committed
577

578
ir_type *clone_type_method(ir_type *tp)
579
{
Michael Beck's avatar
Michael Beck committed
580
	assert(is_Method_type(tp));
Matthias Braun's avatar
Matthias Braun committed
581
582
583
584
	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;
585
	ir_type       *res      = new_type(tpo_method, sizeof(mtd_attr), mode);
586
	set_type_dbg_info(res, db);
Michael Beck's avatar
Michael Beck committed
587

Matthias Braun's avatar
Matthias Braun committed
588
589
590
591
	res->flags                    = tp->flags;
	res->higher_type              = tp->higher_type;
	res->size                     = tp->size;
	res->attr.ma.n_params         = n_params;
592
	res->attr.ma.params           = XMALLOCN(ir_type*, n_params);
Christoph Mallon's avatar
Christoph Mallon committed
593
	MEMCPY(res->attr.ma.params, tp->attr.ma.params, n_params);
Matthias Braun's avatar
Matthias Braun committed
594
	res->attr.ma.n_res            = n_res;
595
	res->attr.ma.res_type         = XMALLOCN(ir_type*, n_res);
Christoph Mallon's avatar
Christoph Mallon committed
596
	MEMCPY(res->attr.ma.res_type, tp->attr.ma.res_type, n_res);
597
	res->attr.ma.variadic         = tp->attr.ma.variadic;
Matthias Braun's avatar
Matthias Braun committed
598
599
	res->attr.ma.properties       = tp->attr.ma.properties;
	res->attr.ma.irg_calling_conv = tp->attr.ma.irg_calling_conv;
600
	set_type_alignment_bytes(res, get_type_alignment_bytes(tp));
Michael Beck's avatar
Michael Beck committed
601
602
603
604
	hook_new_type(res);
	return res;
}

605
606
void free_method_attrs(ir_type *method)
{
Matthias Braun's avatar
Matthias Braun committed
607
	assert(is_Method_type(method));
608
609
	free(method->attr.ma.params);
	free(method->attr.ma.res_type);
610
}
Michael Beck's avatar
fixed:    
Michael Beck committed
611

612
size_t (get_method_n_params)(const ir_type *method)
613
{
614
	return get_method_n_params_(method);
Christian Schäfer's avatar
Christian Schäfer committed
615
}
616

617
ir_type *get_method_param_type(const ir_type *method, size_t pos)
618
{
Matthias Braun's avatar
Matthias Braun committed
619
	assert(is_Method_type(method));
620
	assert(pos < get_method_n_params(method));
621
	ir_type *res = method->attr.ma.params[pos];
Matthias Braun's avatar
Matthias Braun committed
622
	return res;
Christian Schäfer's avatar
Christian Schäfer committed
623
}
624

625
void set_method_param_type(ir_type *method, size_t pos, ir_type *tp)
626
{
Matthias Braun's avatar
Matthias Braun committed
627
	assert(is_Method_type(method));
628
	assert(pos < get_method_n_params(method));
629
	method->attr.ma.params[pos] = tp;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
630
631
}

632
size_t (get_method_n_ress)(const ir_type *method)
633
{
634
	return get_method_n_ress_(method);
Christian Schäfer's avatar
Christian Schäfer committed
635
}
636

637
ir_type *get_method_res_type(const ir_type *method, size_t pos)
638
{
Matthias Braun's avatar
Matthias Braun committed
639
	assert(is_Method_type(method));
640
	assert(pos < get_method_n_ress(method));
641
	ir_type *res = method->attr.ma.res_type[pos];
Matthias Braun's avatar
Matthias Braun committed
642
	return res;
643
}
644

645
void set_method_res_type(ir_type *method, size_t pos, ir_type *tp)
646
{
Matthias Braun's avatar
Matthias Braun committed
647
	assert(is_Method_type(method));
648
	assert(pos < get_method_n_ress(method));
649
	method->attr.ma.res_type[pos] = tp;
650
651
}

652
int is_method_variadic(ir_type const *const method)
653
{
Matthias Braun's avatar
Matthias Braun committed
654
	assert(is_Method_type(method));
655
	return method->attr.ma.variadic;
656
657
}

658
void set_method_variadic(ir_type *const method, int const is_variadic)
659
{
Matthias Braun's avatar
Matthias Braun committed
660
	assert(is_Method_type(method));
661
	method->attr.ma.variadic = is_variadic;
662
663
}

664
mtp_additional_properties (get_method_additional_properties)(const ir_type *method)
665
{
666
	return get_method_additional_properties_(method);
667
668
}

669
void (set_method_additional_properties)(ir_type *method, mtp_additional_properties mask)
670
{
671
	set_method_additional_properties_(method, mask);
672
673
}

Matthias Braun's avatar
Matthias Braun committed
674
675
void (add_method_additional_properties)(ir_type *method,
                                        mtp_additional_properties flag)
676
{
677
	add_method_additional_properties_(method, flag);
678
679
}

680
681
unsigned (get_method_calling_convention)(const ir_type *method)
{
682
	return get_method_calling_convention_(method);
683
684
}

685
686
void (set_method_calling_convention)(ir_type *method, unsigned cc_mask)
{
687
	set_method_calling_convention_(method, cc_mask);
688
689
}

690
691
unsigned get_method_n_regparams(ir_type *method)
{
692
693
	unsigned cc = get_method_calling_convention(method);
	assert(IS_FASTCALL(cc));
694

695
	return cc & ~cc_bits;
696
697
}

698
699
void set_method_n_regparams(ir_type *method, unsigned n_regs)
{
700
701
	unsigned cc = get_method_calling_convention(method);
	assert(IS_FASTCALL(cc));
702

703
	set_method_calling_convention(method, (cc & cc_bits) | (n_regs & ~cc_bits));
704
705
}

706
707
int (is_Method_type)(const ir_type *method)
{
708
	return is_method_type_(method);
709
}
Christian Schäfer's avatar
Christian Schäfer committed
710

711
ir_type *new_type_union(ident *name)
712
{
713
	ir_type *res = new_type(tpo_union, sizeof(compound_attr), NULL);
714
	compound_init(res, name);
715
716
	hook_new_type(res);
	return res;
Christian Schäfer's avatar
Christian Schäfer committed
717
}
718

719
720
ident *get_union_ident(const ir_type *uni)
{
721
	assert(is_Union_type(uni));
722
723
724
725
726
	return uni->name;
}

const char *get_union_name(const ir_type *uni)
{
Matthias Braun's avatar
Matthias Braun committed
727
728
	ident *id = get_union_ident(uni);
	if (id == NULL)
729
		return NULL;
Matthias Braun's avatar
Matthias Braun committed
730
	return get_id_str(id);
731
732
}

733
size_t get_union_n_members(const ir_type *uni)
734
{
735
	assert(is_Union_type(uni));
Matthias Braun's avatar
Matthias Braun committed
736
	return get_compound_n_members(uni);
737
738
}

739
ir_entity *get_union_member(const ir_type *uni, size_t pos)
740
{
741
	assert(is_Union_type(uni));
Matthias Braun's avatar
Matthias Braun committed
742
	return get_compound_member(uni, pos);
743
744
}