type.c 32.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
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);
Christoph Mallon's avatar
Christoph Mallon committed
54

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

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

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

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

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

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

83
ir_visited_t firm_type_visited;
84

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

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

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

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

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

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

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

133
134
135
136
137
138
139
140
141
142
143
144
145
146
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);
}

147
148
void free_type(ir_type *tp)
{
149
	const tp_op *op = get_type_tpop(tp);
150

151
	free_type_entities(tp);
152
153
154
155
156
157
158
159
	/* 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... */
160
#ifdef DEBUG_libfirm
161
	tp->kind = k_BAD;
162
#endif
163
	free(tp);
164
165
}

166
167
void *(get_type_link)(const ir_type *tp)
{
168
	return get_type_link_(tp);
169
170
}

171
172
void (set_type_link)(ir_type *tp, void *l)
{
173
	set_type_link_(tp, l);
174
175
}

176
177
const tp_op *(get_type_tpop)(const ir_type *tp)
{
178
	return get_type_tpop_(tp);
Christian Schäfer's avatar
Christian Schäfer committed
179
180
}

181
182
ident *(get_type_tpop_nameid)(const ir_type *tp)
{
183
	return get_type_tpop_nameid_(tp);
Christian Schäfer's avatar
Christian Schäfer committed
184
}
185

186
187
188
189
190
static inline bool is_type(const void *thing)
{
	return get_kind(thing) == k_type;
}

191
192
const char* get_type_tpop_name(const ir_type *tp)
{
Matthias Braun's avatar
Matthias Braun committed
193
	assert(is_type(tp));
194
	return get_id_str(tp->type_op->name);
195
}
196

197
198
tp_opcode (get_type_tpop_code)(const ir_type *tp)
{
199
	return get_type_tpop_code_(tp);
200
}
201

202
203
ir_mode *(get_type_mode)(const ir_type *tp)
{
204
	return get_type_mode_(tp);
205
}
206

207
208
void set_type_mode(ir_type *tp, ir_mode *mode)
{
209
	const tp_op *tpop = get_type_tpop(tp);
210
	if (tpop->ops.set_type_mode) {
211
		tpop->ops.set_type_mode(tp, mode);
212
213
214
	} else {
		panic("setting a mode is NOT allowed for this type");
	}
215
}
216

217
218
long get_type_nr(const ir_type *tp)
{
Matthias Braun's avatar
Matthias Braun committed
219
	assert(is_type(tp));
220
#ifdef DEBUG_libfirm
221
	return tp->nr;
222
#else
223
	return (long)PTR_TO_INT(tp);
224
#endif
225
226
}

227
228
unsigned (get_type_size_bytes)(const ir_type *tp)
{
229
	return get_type_size_bytes_(tp);
230
231
}

232
233
ir_visibility get_type_visibility(const ir_type *tp)
{
234
235
	assert(is_type(tp));
	return tp->visibility;
236
237
}

238
239
void set_type_visibility(ir_type *tp, ir_visibility v)
{
240
241
	assert(is_type(tp));
	tp->visibility = v;
242
243
}

244
245
void set_type_size_bytes(ir_type *tp, unsigned size)
{
246
	const tp_op *tpop = get_type_tpop(tp);
247
	tpop->ops.set_type_size(tp, size);
248
249
}

250
unsigned (get_type_alignment_bytes)(const ir_type *type)
251
{
252
	return get_type_alignment_bytes_(type);
Michael Beck's avatar
Michael Beck committed
253
254
}

255
void set_type_alignment_bytes(ir_type *type, unsigned align)
256
{
257
258
259
	assert(is_type(type));
	assert(align > 0);
	type->align = align;
Michael Beck's avatar
Michael Beck committed
260
261
}

262
263
const char *get_type_state_name(ir_type_state s)
{
264
#define X(a)    case a: return #a
265
266
267
268
269
	switch (s) {
		X(layout_undefined);
		X(layout_fixed);
	}
	return "<unknown>";
Götz Lindenmaier's avatar
Götz Lindenmaier committed
270
271
272
#undef X
}

273
274
ir_type_state (get_type_state)(const ir_type *tp)
{
275
	return get_type_state_(tp);
276
277
}

278
279
void set_type_state(ir_type *tp, ir_type_state state)
{
Matthias Braun's avatar
Matthias Braun committed
280
	assert(is_type(tp));
281

Matthias Braun's avatar
Matthias Braun committed
282
283
	if (tp->type_op == type_pointer || tp->type_op == type_primitive
	    || tp->type_op == type_method)
284
285
		return;

Matthias Braun's avatar
Matthias Braun committed
286
#ifndef NDEBUG
287
288
289
290
291
	/* 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
292
293
				for (size_t i = 0, n_mem = get_class_n_members(tp);
				     i < n_mem; i++) {
Eduard Frank's avatar
Eduard Frank committed
294
295
296
297
					ir_entity *entity = get_class_member(tp, i);
					if (is_Method_type(get_entity_type(entity)))
						continue;
					assert(get_entity_offset(entity) > -1);
298
299
300
301
				}
			}
			break;
		case tpo_struct:
Matthias Braun's avatar
Matthias Braun committed
302
303
			for (size_t i = 0, n_members = get_struct_n_members(tp);
			     i < n_members; i++) {
304
305
306
				assert(get_entity_offset(get_struct_member(tp, i)) > -1);
			}
			break;
Matthias Braun's avatar
Matthias Braun committed
307
308
309
310
		case tpo_union:
		case tpo_array:
		default:
			break;
Eduard Frank's avatar
Eduard Frank committed
311
		}
312
	}
Matthias Braun's avatar
Matthias Braun committed
313
#endif
314
315
316
317
	if (state == layout_fixed)
		tp->flags |= tf_layout_fixed;
	else
		tp->flags &= ~tf_layout_fixed;
318
319
}

320
321
ir_visited_t (get_type_visited)(const ir_type *tp)
{
322
	return get_type_visited_(tp);
323
}
324

325
326
void (set_type_visited)(ir_type *tp, ir_visited_t num)
{
327
	set_type_visited_(tp, num);
328
}
329

330
331
void (mark_type_visited)(ir_type *tp)
{
332
	mark_type_visited_(tp);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
333
334
}

335
336
int (type_visited)(const ir_type *tp)
{
337
	return type_visited_(tp);
338
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
339

340
type_dbg_info *(get_type_dbg_info)(const ir_type *tp)
341
{
342
	return get_type_dbg_info_(tp);
343
344
}

345
void (set_type_dbg_info)(ir_type *tp, type_dbg_info *db)
346
{
347
	set_type_dbg_info_(tp, db);
348
349
}

350
static void compound_init(ir_type *const type, ident *const name)
351
{
352
	type->name            = name;
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
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
	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;
		}
	}
}

407
ir_type *new_type_class(ident *name)
408
{
409
	ir_type *res = new_type(type_class, NULL);
410
	compound_init(res, name);
411
412
	res->attr.cla.subtypes   = NEW_ARR_F(ir_type*, 0);
	res->attr.cla.supertypes = NEW_ARR_F(ir_type*, 0);
413
414
	hook_new_type(res);
	return res;
Christian Schäfer's avatar
Christian Schäfer committed
415
}
416

417
418
void free_class_entities(ir_type *clss)
{
419
420
	assert(is_Class_type(clss));
	compound_free_entities(clss);
421
422
}

423
424
void free_class_attrs(ir_type *clss)
{
425
426
427
428
	assert(is_Class_type(clss));
	compound_free_attrs(clss);
	DEL_ARR_F(clss->attr.cla.subtypes);
	DEL_ARR_F(clss->attr.cla.supertypes);
429
}
430

431
432
ident *get_class_ident(const ir_type *clss)
{
433
	assert(is_Class_type(clss));
434
435
436
437
438
	return clss->name;
}

const char *get_class_name(const ir_type *clss)
{
439
440
	if (get_class_ident(clss) == NULL)
		return NULL;
441
442
443
	return get_id_str(get_class_ident(clss));
}

444
static void add_class_member(ir_type *clss, ir_entity *member)
445
{
446
447
	assert(is_Class_type(clss));
	compound_add_member(clss, member);
Christian Schäfer's avatar
Christian Schäfer committed
448
}
449

450
size_t (get_class_n_members)(const ir_type *clss)
451
{
452
	return get_class_n_members_(clss);
Christian Schäfer's avatar
Christian Schäfer committed
453
}
454

455
size_t get_class_member_index(const ir_type *clss, ir_entity *mem)
456
{
457
458
	assert(is_Class_type(clss));
	return compound_get_member_index(clss, mem);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
459
}
460

461
ir_entity *(get_class_member)(const ir_type *clss, size_t pos)
462
{
463
	return get_class_member_(clss, pos);
464
}
465

466
static void remove_class_member(ir_type *clss, ir_entity *member)
467
{
Matthias Braun's avatar
Matthias Braun committed
468
	assert(is_Class_type(clss));
469
	compound_remove_member(clss, member);
470
}
471

472
473
void add_class_subtype(ir_type *clss, ir_type *subtype)
{
Matthias Braun's avatar
Matthias Braun committed
474
	assert(is_Class_type(clss));
475
	ARR_APP1(ir_type *, clss->attr.cla.subtypes, subtype);
Matthias Braun's avatar
Matthias Braun committed
476
477
	for (size_t i = 0, n_supertypes = get_class_n_supertypes(subtype);
	     i < n_supertypes; i++) {
478
479
480
		if (get_class_supertype(subtype, i) == clss)
			/* Class already registered */
			return;
481
	}
482
	ARR_APP1(ir_type *, subtype->attr.cla.supertypes, clss);
483
484
}

485
size_t get_class_n_subtypes(const ir_type *clss)
486
{
Matthias Braun's avatar
Matthias Braun committed
487
	assert(is_Class_type(clss));
488
	return ARR_LEN(clss->attr.cla.subtypes);
489
490
}

491
ir_type *get_class_subtype(const ir_type *clss, size_t pos)
492
{
Matthias Braun's avatar
Matthias Braun committed
493
	assert(is_Class_type(clss));
494
	assert(pos < get_class_n_subtypes(clss));
495
	return clss->attr.cla.subtypes[pos];
496
497
}

498
size_t get_class_subtype_index(const ir_type *clss, const ir_type *subclass)
499
{
Matthias Braun's avatar
Matthias Braun committed
500
	assert(is_Class_type(clss) && is_Class_type(subclass));
Matthias Braun's avatar
Matthias Braun committed
501
502
	for (size_t i = 0, n_subtypes = get_class_n_subtypes(clss);
	     i < n_subtypes; ++i) {
503
504
		if (get_class_subtype(clss, i) == subclass)
			return i;
505
	}
506
	return (size_t)-1;
507
508
}

509
void set_class_subtype(ir_type *clss, ir_type *subtype, size_t pos)
510
{
Matthias Braun's avatar
Matthias Braun committed
511
	assert(is_Class_type(clss));
512
	assert(pos < get_class_n_subtypes(clss));
513
	clss->attr.cla.subtypes[pos] = subtype;
514
515
}

516
517
void remove_class_subtype(ir_type *clss, ir_type *subtype)
{
Matthias Braun's avatar
Matthias Braun committed
518
	assert(is_Class_type(clss));
519
520
521
522
523
	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);
524
525
			break;
		}
526
	}
527
528
}

529
530
void add_class_supertype(ir_type *clss, ir_type *supertype)
{
Matthias Braun's avatar
Matthias Braun committed
531
	assert(is_Class_type(clss));
Matthias Braun's avatar
Matthias Braun committed
532
	assert(supertype->type_op == type_class);
533
	ARR_APP1(ir_type *, clss->attr.cla.supertypes, supertype);
Matthias Braun's avatar
Matthias Braun committed
534
	for (size_t i = 0, n = get_class_n_subtypes(supertype); i < n; ++i) {
535
536
537
		if (get_class_subtype(supertype, i) == clss)
			/* Class already registered */
			return;
538
	}
539
	ARR_APP1(ir_type *, supertype->attr.cla.subtypes, clss);
540
541
}

542
size_t get_class_n_supertypes(const ir_type *clss)
543
{
Matthias Braun's avatar
Matthias Braun committed
544
	assert(is_Class_type(clss));
545
	return ARR_LEN(clss->attr.cla.supertypes);
546
547
}

548
size_t get_class_supertype_index(const ir_type *clss, const ir_type *super_clss)
549
{
Matthias Braun's avatar
Matthias Braun committed
550
	assert(is_Class_type(clss) && is_Class_type(super_clss));
Matthias Braun's avatar
Matthias Braun committed
551
552
	for (size_t i = 0, n_supertypes = get_class_n_supertypes(clss);
	     i < n_supertypes; i++) {
553
554
		if (get_class_supertype(clss, i) == super_clss)
			return i;
555
556
	}
	return (size_t)-1;
557
}
558

559
ir_type *get_class_supertype(const ir_type *clss, size_t pos)
560
{
Matthias Braun's avatar
Matthias Braun committed
561
	assert(is_Class_type(clss));
562
	assert(pos < get_class_n_supertypes(clss));
563
	return clss->attr.cla.supertypes[pos];
564
565
}

566
void set_class_supertype(ir_type *clss, ir_type *supertype, size_t pos)
567
{
Matthias Braun's avatar
Matthias Braun committed
568
	assert(is_Class_type(clss));
569
	assert(pos < get_class_n_supertypes(clss));
570
	clss->attr.cla.supertypes[pos] = supertype;
571
572
}

573
574
void remove_class_supertype(ir_type *clss, ir_type *supertype)
{
Matthias Braun's avatar
Matthias Braun committed
575
	assert(is_Class_type(clss));
576
577
578
579
580
	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);
581
582
			break;
		}
583
	}
584
585
}

586
587
int (is_Class_type)(const ir_type *clss)
{
588
	return is_class_type_(clss);
589
}
Christian Schäfer's avatar
Christian Schäfer committed
590

591
592
void set_class_mode(ir_type *tp, ir_mode *mode)
{
Matthias Braun's avatar
Matthias Braun committed
593
594
	/* for classes and structs we allow to set a mode if the layout is fixed
	 * AND the size matches */
595
	assert(get_type_state(tp) == layout_fixed &&
Matthias Braun's avatar
Matthias Braun committed
596
	       tp->size == get_mode_size_bytes(mode));
597
	tp->mode = mode;
598
599
}

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

601
ir_type *new_type_struct(ident *name)
602
{
603
	ir_type *res = new_type(type_struct, NULL);
604
	compound_init(res, name);
605
606
	hook_new_type(res);
	return res;
Christian Schäfer's avatar
Christian Schäfer committed
607
}
608

609
610
void free_struct_entities(ir_type *strct)
{
611
612
	assert(is_Struct_type(strct));
	compound_free_entities(strct);
613
}
614

615
616
void free_struct_attrs(ir_type *strct)
{
617
618
	assert(is_Struct_type(strct));
	compound_free_attrs(strct);
619
}
620

621
622
ident *get_struct_ident(const ir_type *strct)
{
623
	assert(is_Struct_type(strct));
624
625
626
627
628
	return strct->name;
}

const char *get_struct_name(const ir_type *strct)
{
Matthias Braun's avatar
Matthias Braun committed
629
630
	ident *id = get_struct_ident(strct);
	if (id == NULL)
631
		return NULL;
Matthias Braun's avatar
Matthias Braun committed
632
	return get_id_str(id);
633
634
}

635
size_t get_struct_n_members(const ir_type *strct)
636
{
637
638
	assert(is_Struct_type(strct));
	return compound_get_n_members(strct);
639
}
640

641
static void add_struct_member(ir_type *strct, ir_entity *member)
642
{
643
	assert(is_Struct_type(strct));
644
	assert(get_type_tpop(get_entity_type(member)) != type_method);
645
	compound_add_member(strct, member);
Christian Schäfer's avatar
Christian Schäfer committed
646
}
647

648
ir_entity *get_struct_member(const ir_type *strct, size_t pos)
649
{
650
651
	assert(is_Struct_type(strct));
	return compound_get_member(strct, pos);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
652
}
653

654
size_t get_struct_member_index(const ir_type *strct, ir_entity *mem)
655
{
656
657
	assert(is_Struct_type(strct));
	return compound_get_member_index(strct, mem);
658
659
}

660
static void remove_struct_member(ir_type *strct, ir_entity *member)
661
{
662
	assert(is_Struct_type(strct));
Matthias Braun's avatar
Matthias Braun committed
663
	compound_remove_member(strct, member);
664
}
665

666
667
int (is_Struct_type)(const ir_type *strct)
{
668
	return is_struct_type_(strct);
Christian Schäfer's avatar
Christian Schäfer committed
669
670
}

671
672
void set_struct_mode(ir_type *tp, ir_mode *mode)
{
Matthias Braun's avatar
Matthias Braun committed
673
674
	/* for classes and structs we allow to set a mode if the layout is fixed
	 * AND the size matches */
675
	assert(get_type_state(tp) == layout_fixed &&
Matthias Braun's avatar
Matthias Braun committed
676
	       tp->size == get_mode_size_bytes(mode));
677
	tp->mode = mode;
678
679
}

680
ir_type *new_type_method(size_t n_param, size_t n_res)
681
{
682
	ir_type *res = new_type(type_method, mode_P);
Matthias Braun's avatar
Matthias Braun committed
683
	res->flags               |= tf_layout_fixed;
684
	res->size                 = get_mode_size_bytes(mode_P);
Matthias Braun's avatar
Matthias Braun committed
685
	res->attr.ma.n_params     = n_param;
686
	res->attr.ma.params       = XMALLOCNZ(ir_type*, n_param);
Matthias Braun's avatar
Matthias Braun committed
687
	res->attr.ma.n_res        = n_res;
688
	res->attr.ma.res_type     = XMALLOCNZ(ir_type*, n_res);
Matthias Braun's avatar
Matthias Braun committed
689
690
	res->attr.ma.variadicity  = variadicity_non_variadic;
	res->attr.ma.properties   = mtp_no_property;
691
	set_type_alignment_bytes(res, 1);
692
693
	hook_new_type(res);
	return res;
Christian Schäfer's avatar
Christian Schäfer committed
694
}
Michael Beck's avatar
fixed:    
Michael Beck committed
695

696
ir_type *clone_type_method(ir_type *tp)
697
{
Michael Beck's avatar
Michael Beck committed
698
	assert(is_Method_type(tp));
Matthias Braun's avatar
Matthias Braun committed
699
700
701
702
	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;
703
704
	ir_type       *res      = new_type(type_method, mode);
	set_type_dbg_info(res, db);
Michael Beck's avatar
Michael Beck committed
705

Matthias Braun's avatar
Matthias Braun committed
706
707
708
709
	res->flags                    = tp->flags;
	res->higher_type              = tp->higher_type;
	res->size                     = tp->size;
	res->attr.ma.n_params         = n_params;
710
	res->attr.ma.params           = XMALLOCN(ir_type*, n_params);
Christoph Mallon's avatar
Christoph Mallon committed
711
	MEMCPY(res->attr.ma.params, tp->attr.ma.params, n_params);
Matthias Braun's avatar
Matthias Braun committed
712
	res->attr.ma.n_res            = n_res;
713
	res->attr.ma.res_type         = XMALLOCN(ir_type*, n_res);
Christoph Mallon's avatar
Christoph Mallon committed
714
	MEMCPY(res->attr.ma.res_type, tp->attr.ma.res_type, n_res);
Matthias Braun's avatar
Matthias Braun committed
715
716
717
	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;
718
	set_type_alignment_bytes(res, get_type_alignment_bytes(tp));
Michael Beck's avatar
Michael Beck committed
719
720
721
722
	hook_new_type(res);
	return res;
}

723
724
void free_method_attrs(ir_type *method)
{
Matthias Braun's avatar
Matthias Braun committed
725
	assert(is_Method_type(method));
726
727
	free(method->attr.ma.params);
	free(method->attr.ma.res_type);
728
}
Michael Beck's avatar
fixed:    
Michael Beck committed
729

730
size_t (get_method_n_params)(const ir_type *method)
731
{
732
	return get_method_n_params_(method);
Christian Schäfer's avatar
Christian Schäfer committed
733
}
734

735
ir_type *get_method_param_type(const ir_type *method, size_t pos)
736
{
Matthias Braun's avatar
Matthias Braun committed
737
	assert(is_Method_type(method));
738
	assert(pos < get_method_n_params(method));
739
	ir_type *res = method->attr.ma.params[pos];
Matthias Braun's avatar
Matthias Braun committed
740
	return res;
Christian Schäfer's avatar
Christian Schäfer committed
741
}
742

743
void set_method_param_type(ir_type *method, size_t pos, ir_type *tp)
744
{
Matthias Braun's avatar
Matthias Braun committed
745
	assert(is_Method_type(method));
746
	assert(pos < get_method_n_params(method));
747
	method->attr.ma.params[pos] = tp;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
748
749
}

750
size_t (get_method_n_ress)(const ir_type *method)
751
{
752
	return get_method_n_ress_(method);
Christian Schäfer's avatar
Christian Schäfer committed
753
}
754

755
ir_type *get_method_res_type(const ir_type *method, size_t pos)
756
{
Matthias Braun's avatar
Matthias Braun committed
757
	assert(is_Method_type(method));
758
	assert(pos < get_method_n_ress(method));
759
	ir_type *res = method->attr.ma.res_type[pos];
Matthias Braun's avatar
Matthias Braun committed
760
	return res;
761
}
762

763
void set_method_res_type(ir_type *method, size_t pos, ir_type *tp)
764
{
Matthias Braun's avatar
Matthias Braun committed
765
	assert(is_Method_type(method));
766
	assert(pos < get_method_n_ress(method));
767
	method->attr.ma.res_type[pos] = tp;
768
769
}

770
771
const char *get_variadicity_name(ir_variadicity vari)
{
Florian Liekweg's avatar
Florian Liekweg committed
772
#define X(a)    case a: return #a
773
774
775
776
777
778
	switch (vari) {
	X(variadicity_non_variadic);
	X(variadicity_variadic);
	default:
		return "BAD VALUE";
	}
Michael Beck's avatar
Michael Beck committed
779
780
781
#undef X
}

782
783
ir_variadicity get_method_variadicity(const ir_type *method)
{
Matthias Braun's avatar
Matthias Braun committed
784
	assert(is_Method_type(method));