type.c 37 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 "type_t.h"
36

37
38
39
40
41
42
#include "xmalloc.h"
#include "irprog_t.h"
#include "ircons.h"
#include "tpop_t.h"
#include "tv_t.h"
#include "irhooks.h"
43
#include "util.h"
44
#include "entity_t.h"
45
46
#include "error.h"
#include "dbginfo.h"
47
#include "irprog_t.h"
48

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

51
static ir_type *new_type(tp_op const *type_op, ir_mode *mode);
Christoph Mallon's avatar
Christoph Mallon committed
52

53
54
ir_type *get_code_type(void)
{
55
	return irp->code_type;
56
}
57

58
59
ir_type *get_unknown_type(void)
{
60
	return irp->unknown_type;
61
}
62

63
void ir_init_type(ir_prog *irp)
64
{
65
	irp->code_type = new_type(tpop_code, mode_ANY);
66
	set_type_state(irp->code_type, layout_fixed);
67

68
	irp->unknown_type = new_type(tpop_unknown, mode_ANY);
69
	set_type_state (irp->unknown_type, layout_fixed);
70
71
}

72
void ir_finish_type(ir_prog *irp)
73
{
Matthias Braun's avatar
Matthias Braun committed
74
	/** nothing todo. (The code, unknown types are in the global type list
75
76
	 * and freed there */
	(void)irp;
77
78
}

79
ir_visited_t firm_type_visited;
80

81
82
83
84
85
86
87
88
89
void (set_master_type_visited)(ir_visited_t val)
{
	_set_master_type_visited(val);
}

ir_visited_t (get_master_type_visited)(void)
{
	return _get_master_type_visited();
}
Christian Schäfer's avatar
Christian Schäfer committed
90

91
92
93
94
95
void (inc_master_type_visited)(void)
{
	_inc_master_type_visited();
}

Christoph Mallon's avatar
Christoph Mallon committed
96
97
98
99
100
101
102
103
104
/**
 *   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.
 */
105
static ir_type *new_type(tp_op const *type_op, ir_mode *mode)
106
{
Matthias Braun's avatar
Matthias Braun committed
107
108
	size_t   const node_size = offsetof(ir_type, attr) +  type_op->attr_size;
	ir_type *const res       = (ir_type*)xmalloc(node_size);
109
110
111
112
113
	memset(res, 0, node_size);

	res->kind       = k_type;
	res->type_op    = type_op;
	res->mode       = mode;
114
	res->visibility = ir_visibility_external;
115
	res->flags      = tf_none;
116
117
	res->size       = 0;
	res->align      = 0;
118
119
	res->visit      = 0;
	res->link       = NULL;
120
#ifdef DEBUG_libfirm
121
	res->nr         = get_irp_new_node_nr();
Florian Liekweg's avatar
Florian Liekweg committed
122
#endif /* defined DEBUG_libfirm */
Christian Schäfer's avatar
Christian Schäfer committed
123

124
	add_irp_type(res);   /* Remember the new type global. */
125

126
	return res;
Christian Schäfer's avatar
Christian Schäfer committed
127
128
}

129
130
131
132
133
134
135
136
137
138
139
140
141
142
void free_type_entities(ir_type *tp)
{
	const tp_op *op = get_type_tpop(tp);
	if (op->ops.free_entities != NULL)
		op->ops.free_entities(tp);
}

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);
}

143
144
void free_type(ir_type *tp)
{
145
	const tp_op *op = get_type_tpop(tp);
146

147
	free_type_entities(tp);
148
149
150
151
152
153
154
155
	/* Remove from list of all types */
	remove_irp_type(tp);
	/* Free the attributes of the type. */
	free_type_attrs(tp);
	/* Free entities automatically allocated with the ir_type */
	if (op->ops.free_auto_entities)
		op->ops.free_auto_entities(tp);
	/* And now the type itself... */
156
#ifdef DEBUG_libfirm
157
	tp->kind = k_BAD;
158
#endif
159
	free(tp);
160
161
}

162
163
void *(get_type_link)(const ir_type *tp)
{
164
	return _get_type_link(tp);
165
166
}

167
168
void (set_type_link)(ir_type *tp, void *l)
{
169
	_set_type_link(tp, l);
170
171
}

172
173
const tp_op *(get_type_tpop)(const ir_type *tp)
{
174
	return _get_type_tpop(tp);
Christian Schäfer's avatar
Christian Schäfer committed
175
176
}

177
178
ident *(get_type_tpop_nameid)(const ir_type *tp)
{
179
	return _get_type_tpop_nameid(tp);
Christian Schäfer's avatar
Christian Schäfer committed
180
}
181

182
183
const char* get_type_tpop_name(const ir_type *tp)
{
184
185
	assert(tp && tp->kind == k_type);
	return get_id_str(tp->type_op->name);
186
}
187

188
189
tp_opcode (get_type_tpop_code)(const ir_type *tp)
{
190
	return _get_type_tpop_code(tp);
191
}
192

193
194
ir_mode *(get_type_mode)(const ir_type *tp)
{
195
	return _get_type_mode(tp);
196
}
197

198
199
void set_type_mode(ir_type *tp, ir_mode *mode)
{
200
	const tp_op *tpop = get_type_tpop(tp);
201
	if (tpop->ops.set_type_mode) {
202
		tpop->ops.set_type_mode(tp, mode);
203
204
205
	} else {
		panic("setting a mode is NOT allowed for this type");
	}
206
}
207

208
209
long get_type_nr(const ir_type *tp)
{
210
	assert(tp);
211
#ifdef DEBUG_libfirm
212
	return tp->nr;
213
#else
214
	return (long)PTR_TO_INT(tp);
215
#endif
216
217
}

218
219
unsigned (get_type_size_bytes)(const ir_type *tp)
{
220
	return _get_type_size_bytes(tp);
221
222
}

223
224
ir_visibility get_type_visibility(const ir_type *tp)
{
225
226
	assert(is_type(tp));
	return tp->visibility;
227
228
}

229
230
void set_type_visibility(ir_type *tp, ir_visibility v)
{
231
232
	assert(is_type(tp));
	tp->visibility = v;
233
234
}

235
236
void set_type_size_bytes(ir_type *tp, unsigned size)
{
237
	const tp_op *tpop = get_type_tpop(tp);
238
	tpop->ops.set_type_size(tp, size);
239
240
}

241
242
unsigned get_type_alignment_bytes(ir_type *tp)
{
243
244
245
246
	if (tp->align > 0)
		return tp->align;

	/* alignment NOT set calculate it "on demand" */
Matthias Braun's avatar
Matthias Braun committed
247
	unsigned align;
248
	if (tp->mode)
249
		align = (get_mode_size_bits(tp->mode) + 7) >> 3;
250
	else if (is_Array_type(tp))
251
		align = get_type_alignment_bytes(get_array_element_type(tp));
252
253
	else if (is_compound_type(tp)) {
		align = 0;
Matthias Braun's avatar
Matthias Braun committed
254
		for (size_t i = 0, n = get_compound_n_members(tp); i < n; ++i) {
255
			ir_type  *t = get_entity_type(get_compound_member(tp, i));
Matthias Braun's avatar
Matthias Braun committed
256
			unsigned  a = get_type_alignment_bytes(t);
257
258
259
260
261
262

			if (a > align)
				align = a;
		}
	} else if (is_Method_type(tp)) {
		align = 0;
Matthias Braun's avatar
Matthias Braun committed
263
264
	} else {
		align = 1;
265
	}
Michael Beck's avatar
Michael Beck committed
266

267
268
269
	/* write back */
	tp->align = align;
	return align;
Michael Beck's avatar
Michael Beck committed
270
271
}

272
273
void set_type_alignment_bytes(ir_type *tp, unsigned align)
{
Matthias Braun's avatar
Matthias Braun committed
274
	assert(tp->kind == k_type);
275
276
277
278
	/* Methods don't have an alignment. */
	if (tp->type_op != type_method) {
		tp->align = align;
	}
Michael Beck's avatar
Michael Beck committed
279
280
}

281
282
const char *get_type_state_name(ir_type_state s)
{
283
#define X(a)    case a: return #a
284
285
286
287
288
	switch (s) {
		X(layout_undefined);
		X(layout_fixed);
	}
	return "<unknown>";
Götz Lindenmaier's avatar
Götz Lindenmaier committed
289
290
291
#undef X
}

292
293
ir_type_state (get_type_state)(const ir_type *tp)
{
294
	return _get_type_state(tp);
295
296
}

297
298
void set_type_state(ir_type *tp, ir_type_state state)
{
299
300
	assert(tp && tp->kind == k_type);

Matthias Braun's avatar
Matthias Braun committed
301
302
	if (tp->type_op == type_pointer || tp->type_op == type_primitive
	    || tp->type_op == type_method)
303
304
		return;

Matthias Braun's avatar
Matthias Braun committed
305
#ifndef NDEBUG
306
307
308
309
310
	/* Just a correctness check: */
	if (state == layout_fixed) {
		switch (get_type_tpop_code(tp)) {
		case tpo_class:
			if (tp != get_glob_type()) {
Matthias Braun's avatar
Matthias Braun committed
311
312
				for (size_t i = 0, n_mem = get_class_n_members(tp);
				     i < n_mem; i++) {
Eduard Frank's avatar
Eduard Frank committed
313
314
315
316
					ir_entity *entity = get_class_member(tp, i);
					if (is_Method_type(get_entity_type(entity)))
						continue;
					assert(get_entity_offset(entity) > -1);
317
318
319
320
				}
			}
			break;
		case tpo_struct:
Matthias Braun's avatar
Matthias Braun committed
321
322
			for (size_t i = 0, n_members = get_struct_n_members(tp);
			     i < n_members; i++) {
323
324
325
				assert(get_entity_offset(get_struct_member(tp, i)) > -1);
			}
			break;
Matthias Braun's avatar
Matthias Braun committed
326
327
328
329
		case tpo_union:
		case tpo_array:
		default:
			break;
Eduard Frank's avatar
Eduard Frank committed
330
		}
331
	}
Matthias Braun's avatar
Matthias Braun committed
332
#endif
333
334
335
336
	if (state == layout_fixed)
		tp->flags |= tf_layout_fixed;
	else
		tp->flags &= ~tf_layout_fixed;
337
338
}

339
340
ir_visited_t (get_type_visited)(const ir_type *tp)
{
341
	return _get_type_visited(tp);
342
}
343

344
345
void (set_type_visited)(ir_type *tp, ir_visited_t num)
{
346
	_set_type_visited(tp, num);
347
}
348

349
350
void (mark_type_visited)(ir_type *tp)
{
351
	_mark_type_visited(tp);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
352
353
}

354
355
int (type_visited)(const ir_type *tp)
{
356
	return _type_visited(tp);
357
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
358

359
360
int (type_not_visited)(const ir_type *tp)
{
361
	return _type_not_visited(tp);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
362
363
}

364
type_dbg_info *(get_type_dbg_info)(const ir_type *tp)
365
{
366
367
368
	return _get_type_dbg_info(tp);
}

369
void (set_type_dbg_info)(ir_type *tp, type_dbg_info *db)
370
{
371
372
373
	_set_type_dbg_info(tp, db);
}

374
375
376
int (is_type)(const void *thing)
{
	return _is_type(thing);
377
}
378

379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
static void compound_init(ir_type *type)
{
	type->attr.ca.members = NEW_ARR_F(ir_entity*, 0);
}

static void compound_free_attrs(ir_type *type)
{
	DEL_ARR_F(type->attr.ca.members);
}

static size_t compound_get_n_members(const ir_type *type)
{
	return ARR_LEN(type->attr.ca.members);
}

static ir_entity *compound_get_member(const ir_type *type, size_t index)
{
	assert(index < ARR_LEN(type->attr.ca.members));
	return type->attr.ca.members[index];
}

static void compound_add_member(ir_type *type, ir_entity *entity)
{
	/* try to detect double-add */
	assert(get_entity_type(entity) != type);
	ARR_APP1(ir_entity *, type->attr.ca.members, entity);
}

static void compound_free_entities(ir_type *type)
{
	for (size_t i = compound_get_n_members(type); i-- > 0; )
		free_entity(compound_get_member(type, i));
}

static size_t compound_get_member_index(const ir_type *type,
                                        const ir_entity *entity)
{
	for (size_t i = 0, n = compound_get_n_members(type); i < n; ++i) {
		if (compound_get_member(type, i) == entity)
			return i;
	}
	return INVALID_MEMBER_INDEX;
}

static void compound_remove_member(ir_type *type, const ir_entity *member)
{
	for (size_t i = 0, n = ARR_LEN(type->attr.ca.members); i < n; ++i) {
		if (compound_get_member(type, i) == member) {
			for (; i < n - 1; ++i)
				type->attr.ca.members[i] = type->attr.ca.members[i+1];
			ARR_SETLEN(ir_entity*, type->attr.ca.members, n-1);
			break;
		}
	}
}

435
ir_type *new_type_class(ident *name)
436
{
437
	ir_type *res = new_type(type_class, NULL);
438
	res->name = name;
439
	compound_init(res);
440
441
	res->attr.cla.subtypes   = NEW_ARR_F(ir_type*, 0);
	res->attr.cla.supertypes = NEW_ARR_F(ir_type*, 0);
442
443
	hook_new_type(res);
	return res;
Christian Schäfer's avatar
Christian Schäfer committed
444
}
445

446
447
void free_class_entities(ir_type *clss)
{
448
449
	assert(is_Class_type(clss));
	compound_free_entities(clss);
450
451
}

452
453
void free_class_attrs(ir_type *clss)
{
454
455
456
457
	assert(is_Class_type(clss));
	compound_free_attrs(clss);
	DEL_ARR_F(clss->attr.cla.subtypes);
	DEL_ARR_F(clss->attr.cla.supertypes);
458
}
459

460
461
ident *get_class_ident(const ir_type *clss)
{
462
	assert(is_Class_type(clss));
463
464
465
466
467
	return clss->name;
}

const char *get_class_name(const ir_type *clss)
{
468
469
	if (get_class_ident(clss) == NULL)
		return NULL;
470
471
472
	return get_id_str(get_class_ident(clss));
}

473
static void add_class_member(ir_type *clss, ir_entity *member)
474
{
475
476
	assert(is_Class_type(clss));
	compound_add_member(clss, member);
Christian Schäfer's avatar
Christian Schäfer committed
477
}
478

479
size_t (get_class_n_members)(const ir_type *clss)
480
{
481
	return _get_class_n_members(clss);
Christian Schäfer's avatar
Christian Schäfer committed
482
}
483

484
size_t get_class_member_index(const ir_type *clss, ir_entity *mem)
485
{
486
487
	assert(is_Class_type(clss));
	return compound_get_member_index(clss, mem);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
488
}
489

490
ir_entity *(get_class_member)(const ir_type *clss, size_t pos)
491
{
492
	return _get_class_member(clss, pos);
493
}
494

495
static void remove_class_member(ir_type *clss, ir_entity *member)
496
{
Matthias Braun's avatar
Matthias Braun committed
497
	assert(is_Class_type(clss));
498
	compound_remove_member(clss, member);
499
}
500

501
502
void add_class_subtype(ir_type *clss, ir_type *subtype)
{
Matthias Braun's avatar
Matthias Braun committed
503
	assert(is_Class_type(clss));
504
	ARR_APP1(ir_type *, clss->attr.cla.subtypes, subtype);
Matthias Braun's avatar
Matthias Braun committed
505
506
	for (size_t i = 0, n_supertypes = get_class_n_supertypes(subtype);
	     i < n_supertypes; i++) {
507
508
509
		if (get_class_supertype(subtype, i) == clss)
			/* Class already registered */
			return;
510
	}
511
	ARR_APP1(ir_type *, subtype->attr.cla.supertypes, clss);
512
513
}

514
size_t get_class_n_subtypes(const ir_type *clss)
515
{
Matthias Braun's avatar
Matthias Braun committed
516
	assert(is_Class_type(clss));
517
	return ARR_LEN(clss->attr.cla.subtypes);
518
519
}

520
ir_type *get_class_subtype(const ir_type *clss, size_t pos)
521
{
Matthias Braun's avatar
Matthias Braun committed
522
	assert(is_Class_type(clss));
523
	assert(pos < get_class_n_subtypes(clss));
524
	return clss->attr.cla.subtypes[pos];
525
526
}

527
size_t get_class_subtype_index(const ir_type *clss, const ir_type *subclass)
528
{
Matthias Braun's avatar
Matthias Braun committed
529
	assert(is_Class_type(clss) && is_Class_type(subclass));
Matthias Braun's avatar
Matthias Braun committed
530
531
	for (size_t i = 0, n_subtypes = get_class_n_subtypes(clss);
	     i < n_subtypes; ++i) {
532
533
		if (get_class_subtype(clss, i) == subclass)
			return i;
534
	}
535
	return (size_t)-1;
536
537
}

538
void set_class_subtype(ir_type *clss, ir_type *subtype, size_t pos)
539
{
Matthias Braun's avatar
Matthias Braun committed
540
	assert(is_Class_type(clss));
541
	assert(pos < get_class_n_subtypes(clss));
542
	clss->attr.cla.subtypes[pos] = subtype;
543
544
}

545
546
void remove_class_subtype(ir_type *clss, ir_type *subtype)
{
Matthias Braun's avatar
Matthias Braun committed
547
	assert(is_Class_type(clss));
548
549
550
551
552
	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);
553
554
			break;
		}
555
	}
556
557
}

558
559
void add_class_supertype(ir_type *clss, ir_type *supertype)
{
Matthias Braun's avatar
Matthias Braun committed
560
	assert(is_Class_type(clss));
Matthias Braun's avatar
Matthias Braun committed
561
	assert(supertype->type_op == type_class);
562
	ARR_APP1(ir_type *, clss->attr.cla.supertypes, supertype);
Matthias Braun's avatar
Matthias Braun committed
563
	for (size_t i = 0, n = get_class_n_subtypes(supertype); i < n; ++i) {
564
565
566
		if (get_class_subtype(supertype, i) == clss)
			/* Class already registered */
			return;
567
	}
568
	ARR_APP1(ir_type *, supertype->attr.cla.subtypes, clss);
569
570
}

571
size_t get_class_n_supertypes(const ir_type *clss)
572
{
Matthias Braun's avatar
Matthias Braun committed
573
	assert(is_Class_type(clss));
574
	return ARR_LEN(clss->attr.cla.supertypes);
575
576
}

577
size_t get_class_supertype_index(const ir_type *clss, const ir_type *super_clss)
578
{
Matthias Braun's avatar
Matthias Braun committed
579
	assert(is_Class_type(clss) && is_Class_type(super_clss));
Matthias Braun's avatar
Matthias Braun committed
580
581
	for (size_t i = 0, n_supertypes = get_class_n_supertypes(clss);
	     i < n_supertypes; i++) {
582
583
		if (get_class_supertype(clss, i) == super_clss)
			return i;
584
585
	}
	return (size_t)-1;
586
}
587

588
ir_type *get_class_supertype(const ir_type *clss, size_t pos)
589
{
Matthias Braun's avatar
Matthias Braun committed
590
	assert(is_Class_type(clss));
591
	assert(pos < get_class_n_supertypes(clss));
592
	return clss->attr.cla.supertypes[pos];
593
594
}

595
void set_class_supertype(ir_type *clss, ir_type *supertype, size_t pos)
596
{
Matthias Braun's avatar
Matthias Braun committed
597
	assert(is_Class_type(clss));
598
	assert(pos < get_class_n_supertypes(clss));
599
	clss->attr.cla.supertypes[pos] = supertype;
600
601
}

602
603
void remove_class_supertype(ir_type *clss, ir_type *supertype)
{
Matthias Braun's avatar
Matthias Braun committed
604
	assert(is_Class_type(clss));
605
606
607
608
609
	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);
610
611
			break;
		}
612
	}
613
614
}

615
616
int (is_Class_type)(const ir_type *clss)
{
617
	return _is_class_type(clss);
618
}
Christian Schäfer's avatar
Christian Schäfer committed
619

620
621
void set_class_mode(ir_type *tp, ir_mode *mode)
{
Matthias Braun's avatar
Matthias Braun committed
622
623
	/* for classes and structs we allow to set a mode if the layout is fixed
	 * AND the size matches */
624
	assert(get_type_state(tp) == layout_fixed &&
Matthias Braun's avatar
Matthias Braun committed
625
	       tp->size == get_mode_size_bytes(mode));
626
	tp->mode = mode;
627
628
}

Christian Schäfer's avatar
Christian Schäfer committed
629

630
ir_type *new_type_struct(ident *name)
631
{
632
	ir_type *res = new_type(type_struct, NULL);
633
	res->name = name;
634
	compound_init(res);
635
636
	hook_new_type(res);
	return res;
Christian Schäfer's avatar
Christian Schäfer committed
637
}
638

639
640
void free_struct_entities(ir_type *strct)
{
641
642
	assert(is_Struct_type(strct));
	compound_free_entities(strct);
643
}
644

645
646
void free_struct_attrs(ir_type *strct)
{
647
648
	assert(is_Struct_type(strct));
	compound_free_attrs(strct);
649
}
650

651
652
ident *get_struct_ident(const ir_type *strct)
{
653
	assert(is_Struct_type(strct));
654
655
656
657
658
	return strct->name;
}

const char *get_struct_name(const ir_type *strct)
{
Matthias Braun's avatar
Matthias Braun committed
659
660
	ident *id = get_struct_ident(strct);
	if (id == NULL)
661
		return NULL;
Matthias Braun's avatar
Matthias Braun committed
662
	return get_id_str(id);
663
664
}

665
size_t get_struct_n_members(const ir_type *strct)
666
{
667
668
	assert(is_Struct_type(strct));
	return compound_get_n_members(strct);
669
}
670

671
static void add_struct_member(ir_type *strct, ir_entity *member)
672
{
673
	assert(is_Struct_type(strct));
674
	assert(get_type_tpop(get_entity_type(member)) != type_method);
675
	compound_add_member(strct, member);
Christian Schäfer's avatar
Christian Schäfer committed
676
}
677

678
ir_entity *get_struct_member(const ir_type *strct, size_t pos)
679
{
680
681
	assert(is_Struct_type(strct));
	return compound_get_member(strct, pos);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
682
}
683

684
size_t get_struct_member_index(const ir_type *strct, ir_entity *mem)
685
{
686
687
	assert(is_Struct_type(strct));
	return compound_get_member_index(strct, mem);
688
689
}

690
static void remove_struct_member(ir_type *strct, ir_entity *member)
691
{
692
693
	assert(is_Struct_type(strct));
	return compound_remove_member(strct, member);
694
}
695

696
697
int (is_Struct_type)(const ir_type *strct)
{
698
	return _is_struct_type(strct);
Christian Schäfer's avatar
Christian Schäfer committed
699
700
}

701
702
void set_struct_mode(ir_type *tp, ir_mode *mode)
{
Matthias Braun's avatar
Matthias Braun committed
703
704
	/* for classes and structs we allow to set a mode if the layout is fixed
	 * AND the size matches */
705
	assert(get_type_state(tp) == layout_fixed &&
Matthias Braun's avatar
Matthias Braun committed
706
	       tp->size == get_mode_size_bytes(mode));
707
	tp->mode = mode;
708
709
}

710
ir_type *new_type_method(size_t n_param, size_t n_res)
711
{
712
	ir_type *res = new_type(type_method, mode_P_code);
Matthias Braun's avatar
Matthias Braun committed
713
714
715
	res->flags               |= tf_layout_fixed;
	res->size                 = get_mode_size_bytes(mode_P_code);
	res->attr.ma.n_params     = n_param;
716
	res->attr.ma.params       = XMALLOCNZ(ir_type*, n_param);
Matthias Braun's avatar
Matthias Braun committed
717
	res->attr.ma.n_res        = n_res;
718
	res->attr.ma.res_type     = XMALLOCNZ(ir_type*, n_res);
Matthias Braun's avatar
Matthias Braun committed
719
720
	res->attr.ma.variadicity  = variadicity_non_variadic;
	res->attr.ma.properties   = mtp_no_property;
721
722
	hook_new_type(res);
	return res;
Christian Schäfer's avatar
Christian Schäfer committed
723
}
Michael Beck's avatar
fixed:    
Michael Beck committed
724

725
ir_type *clone_type_method(ir_type *tp)
726
{
Michael Beck's avatar
Michael Beck committed
727
	assert(is_Method_type(tp));
Matthias Braun's avatar
Matthias Braun committed
728
729
730
731
	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;
732
733
	ir_type       *res      = new_type(type_method, mode);
	set_type_dbg_info(res, db);
Michael Beck's avatar
Michael Beck committed
734

Matthias Braun's avatar
Matthias Braun committed
735
736
737
738
	res->flags                    = tp->flags;
	res->higher_type              = tp->higher_type;
	res->size                     = tp->size;
	res->attr.ma.n_params         = n_params;
739
	res->attr.ma.params           = XMALLOCN(ir_type*, n_params);
Michael Beck's avatar
Michael Beck committed
740
	memcpy(res->attr.ma.params, tp->attr.ma.params, n_params * sizeof(res->attr.ma.params[0]));
Matthias Braun's avatar
Matthias Braun committed
741
	res->attr.ma.n_res            = n_res;
742
	res->attr.ma.res_type         = XMALLOCN(ir_type*, n_res);
Michael Beck's avatar
Michael Beck committed
743
	memcpy(res->attr.ma.res_type, tp->attr.ma.res_type, n_res * sizeof(res->attr.ma.res_type[0]));
Matthias Braun's avatar
Matthias Braun committed
744
745
746
	res->attr.ma.variadicity      = tp->attr.ma.variadicity;
	res->attr.ma.properties       = tp->attr.ma.properties;
	res->attr.ma.irg_calling_conv = tp->attr.ma.irg_calling_conv;
Michael Beck's avatar
Michael Beck committed
747
748
749
750
	hook_new_type(res);
	return res;
}

751
752
753
void free_method_entities(ir_type *method)
{
	(void) method;
Matthias Braun's avatar
Matthias Braun committed
754
	assert(method->type_op == type_method);
755
}
756

757
758
void free_method_attrs(ir_type *method)
{
Matthias Braun's avatar
Matthias Braun committed
759
	assert(method->type_op == type_method);
760
761
	free(method->attr.ma.params);
	free(method->attr.ma.res_type);
762
}
Michael Beck's avatar
fixed:    
Michael Beck committed
763

764
size_t (get_method_n_params)(const ir_type *method)
765
{
766
	return _get_method_n_params(method);
Christian Schäfer's avatar
Christian Schäfer committed
767
}
768

769
ir_type *get_method_param_type(const ir_type *method, size_t pos)
770
{
771
772
	assert(method->type_op == type_method);
	assert(pos < get_method_n_params(method));
773
	ir_type *res = method->attr.ma.params[pos];
Matthias Braun's avatar
Matthias Braun committed
774
	return res;
Christian Schäfer's avatar
Christian Schäfer committed
775
}
776

777
void set_method_param_type(ir_type *method, size_t pos, ir_type *tp)
778
{
779
780
	assert(method->type_op == type_method);
	assert(pos < get_method_n_params(method));
781
	method->attr.ma.params[pos] = tp;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
782
783
}

784
size_t (get_method_n_ress)(const ir_type *method)
785
{
786
	return _get_method_n_ress(method);
Christian Schäfer's avatar
Christian Schäfer committed
787
}
788

789
ir_type *get_method_res_type(const ir_type *method, size_t pos)
790
{
791
792
	assert(method->type_op == type_method);
	assert(pos < get_method_n_ress(method));
793
	ir_type *res = method->attr.ma.res_type[pos];
Matthias Braun's avatar
Matthias Braun committed
794
	return res;
795
}
796

797
void set_method_res_type(ir_type *method, size_t pos, ir_type *tp)
798
{
799
800
	assert(method->type_op == type_method);
	assert(pos < get_method_n_ress(method));
801
	method->attr.ma.res_type[pos] = tp;
802
803
}

804
805
const char *get_variadicity_name(ir_variadicity vari)
{
Florian Liekweg's avatar
Florian Liekweg committed
806
#define X(a)    case a: return #a
807
808
809
810
811
812
	switch (vari) {
	X(variadicity_non_variadic);
	X(variadicity_variadic);
	default:
		return "BAD VALUE";
	}