type.c 61.2 KB
Newer Older
Christian Würdig's avatar
Christian Würdig committed
1
/*
2
 * Copyright (C) 1995-2011 University of Karlsruhe.  All right reserved.
Christian Würdig's avatar
Christian Würdig committed
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 *
 * This file is part of libFirm.
 *
 * This file may be distributed and/or modified under the terms of the
 * GNU General Public License version 2 as published by the Free Software
 * Foundation and appearing in the file LICENSE.GPL included in the
 * packaging of this file.
 *
 * Licensees holding valid libFirm Professional Edition licenses may use
 * this file in accordance with the libFirm Commercial License.
 * Agreement provided with the Software.
 *
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE.
 */

Sebastian Felis's avatar
Sebastian Felis committed
20
/**
Michael Beck's avatar
Michael Beck committed
21
22
23
24
 * @file    type.c
 * @brief   Representation of types.
 * @author  Goetz Lindenmaier, Michael Beck
 * @version $Id$
yb9976's avatar
yb9976 committed
25
 * @brief
Michael Beck's avatar
Michael Beck committed
26
27
28
29
 *
 *  Implementation of the datastructure to hold
 *  type information.
 *
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
 *  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.
 */
Matthias Braun's avatar
Matthias Braun committed
45
#include "config.h"
Michael Beck's avatar
Michael Beck committed
46

47
#include <string.h>
48
#include <stdlib.h>
49
#include <stddef.h>
50

51
#include "type_t.h"
52

53
54
55
56
57
58
59
60
#include "xmalloc.h"
#include "irprog_t.h"
#include "ircons.h"
#include "tpop_t.h"
#include "tv_t.h"
#include "irhooks.h"
#include "irtools.h"
#include "entity_t.h"
61
62
#include "error.h"
#include "dbginfo.h"
63

64
#include "array.h"
Christian Schäfer's avatar
Christian Schäfer committed
65

66
67
68
69
70
ir_type *firm_none_type;
ir_type *get_none_type(void)
{
	return firm_none_type;
}
Christian Schäfer's avatar
Christian Schäfer committed
71

72
73
74
75
76
ir_type *firm_code_type;
ir_type *get_code_type(void)
{
	return firm_code_type;
}
77

78
ir_type *firm_unknown_type;
79
80
ir_type *get_unknown_type(void)
{
81
82
	return firm_unknown_type;
}
83

84
85
86
87
/* Suffixes added to types used for pass-by-value representations. */
static ident *value_params_suffix = NULL;
static ident *value_ress_suffix = NULL;

88
void ir_init_type(void)
89
{
90
91
	value_params_suffix = new_id_from_str(VALUE_PARAMS_SUFFIX);
	value_ress_suffix   = new_id_from_str(VALUE_RESS_SUFFIX);
92

93
	/* construct none and unknown type. */
94
	firm_none_type = new_type(tpop_none, mode_BAD, NULL);
95
	set_type_size_bytes(firm_none_type, 0);
96
97
	set_type_state (firm_none_type, layout_fixed);
	remove_irp_type(firm_none_type);
98

99
	firm_code_type = new_type(tpop_code, mode_ANY, NULL);
100
101
102
	set_type_state(firm_code_type, layout_fixed);
	remove_irp_type(firm_code_type);

103
	firm_unknown_type = new_type(tpop_unknown, mode_ANY, NULL);
104
	set_type_size_bytes(firm_unknown_type, 0);
105
106
	set_type_state (firm_unknown_type, layout_fixed);
	remove_irp_type(firm_unknown_type);
107
108
}

109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
void ir_finish_type(void)
{
	if (firm_none_type != NULL) {
		free_type(firm_none_type);
		firm_none_type = NULL;
	}
	if (firm_code_type != NULL) {
		free_type(firm_code_type);
		firm_code_type = NULL;
	}
	if (firm_unknown_type != NULL) {
		free_type(firm_unknown_type);
		firm_unknown_type = NULL;
	}
	value_params_suffix = NULL;
	value_ress_suffix = NULL;
}

127
/** the global type visited flag */
128
ir_visited_t firm_type_visited;
129

130
131
132
133
134
135
136
137
138
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
139

140
141
142
143
144
void (inc_master_type_visited)(void)
{
	_inc_master_type_visited();
}

145
ir_type *new_type(const tp_op *type_op, ir_mode *mode, type_dbg_info *db)
146
{
147
	ir_type *res;
148
	size_t node_size;
149
150

	node_size = offsetof(ir_type, attr) +  type_op->attr_size;
151
	res = (ir_type*)xmalloc(node_size);
152
153
154
155
156
	memset(res, 0, node_size);

	res->kind       = k_type;
	res->type_op    = type_op;
	res->mode       = mode;
157
	res->visibility = ir_visibility_external;
158
	res->flags      = tf_none;
159
160
	res->size       = 0;
	res->align      = 0;
161
162
163
164
	res->visit      = 0;
	res->link       = NULL;
	res->dbi        = db;
	res->assoc_type = NULL;
165
#ifdef DEBUG_libfirm
166
	res->nr         = get_irp_new_node_nr();
Florian Liekweg's avatar
Florian Liekweg committed
167
#endif /* defined DEBUG_libfirm */
Christian Schäfer's avatar
Christian Schäfer committed
168

169
	add_irp_type(res);   /* Remember the new type global. */
170

171
	return res;
Christian Schäfer's avatar
Christian Schäfer committed
172
173
}

174
175
void free_type(ir_type *tp)
{
176
	const tp_op *op = get_type_tpop(tp);
177

178
179
	if ((get_type_tpop(tp) == tpop_none) || (get_type_tpop(tp) == tpop_unknown)
			|| (get_type_tpop(tp) == tpop_code))
180
181
182
183
184
185
186
187
188
189
190
		return;
	/* 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... */
	tp->kind = k_BAD;
	free(tp);
191
192
}

193
194
void free_type_entities(ir_type *tp)
{
195
	const tp_op *tpop = get_type_tpop(tp);
196

197
198
	if (tpop->ops.free_entities)
		tpop->ops.free_entities(tp);
199
200
}

201
202
void free_type_attrs(ir_type *tp)
{
203
	const tp_op *tpop = get_type_tpop(tp);
204

205
206
	if (tpop->ops.free_attrs)
		tpop->ops.free_attrs(tp);
207
208
}

209
210
void *(get_type_link)(const ir_type *tp)
{
211
	return _get_type_link(tp);
212
213
}

214
215
void (set_type_link)(ir_type *tp, void *l)
{
216
	_set_type_link(tp, l);
217
218
}

219
220
const tp_op *(get_type_tpop)(const ir_type *tp)
{
221
	return _get_type_tpop(tp);
Christian Schäfer's avatar
Christian Schäfer committed
222
223
}

224
225
ident *(get_type_tpop_nameid)(const ir_type *tp)
{
226
	return _get_type_tpop_nameid(tp);
Christian Schäfer's avatar
Christian Schäfer committed
227
}
228

229
230
const char* get_type_tpop_name(const ir_type *tp)
{
231
232
	assert(tp && tp->kind == k_type);
	return get_id_str(tp->type_op->name);
233
}
234

235
236
tp_opcode (get_type_tpop_code)(const ir_type *tp)
{
237
	return _get_type_tpop_code(tp);
238
}
239

240
241
ir_mode *(get_type_mode)(const ir_type *tp)
{
242
	return _get_type_mode(tp);
243
}
244

245
246
void set_type_mode(ir_type *tp, ir_mode *mode)
{
247
	const tp_op *tpop = get_type_tpop(tp);
Götz Lindenmaier's avatar
a    
Götz Lindenmaier committed
248

249
250
251
252
	if (tpop->ops.set_type_mode)
		tpop->ops.set_type_mode(tp, mode);
	else
		assert(0 && "setting a mode is NOT allowed for this type");
253
}
254

255
/* Outputs a unique number for this node */
256
257
long get_type_nr(const ir_type *tp)
{
258
	assert(tp);
259
#ifdef DEBUG_libfirm
260
	return tp->nr;
261
#else
262
	return (long)PTR_TO_INT(tp);
263
#endif
264
265
}

266
267
unsigned (get_type_size_bytes)(const ir_type *tp)
{
268
	return _get_type_size_bytes(tp);
269
270
}

271
272
ir_visibility get_type_visibility(const ir_type *tp)
{
273
274
	assert(is_type(tp));
	return tp->visibility;
275
276
}

277
278
void set_type_visibility(ir_type *tp, ir_visibility v)
{
279
280
	assert(is_type(tp));
	tp->visibility = v;
281
282
}

283
284
void set_type_size_bytes(ir_type *tp, unsigned size)
{
285
	const tp_op *tpop = get_type_tpop(tp);
286

287
288
289
290
	if (tpop->ops.set_type_size)
		tpop->ops.set_type_size(tp, size);
	else
		assert(0 && "Cannot set size for this type");
291
292
}

293
294
unsigned get_type_alignment_bytes(ir_type *tp)
{
295
	unsigned align = 1;
296
297
298
299
300
301

	if (tp->align > 0)
		return tp->align;

	/* alignment NOT set calculate it "on demand" */
	if (tp->mode)
302
		align = (get_mode_size_bits(tp->mode) + 7) >> 3;
303
	else if (is_Array_type(tp))
304
		align = get_type_alignment_bytes(get_array_element_type(tp));
305
306
307
308
309
	else if (is_compound_type(tp)) {
		int i, n = get_compound_n_members(tp);

		align = 0;
		for (i = 0; i < n; ++i) {
310
311
			ir_type  *t = get_entity_type(get_compound_member(tp, i));
			unsigned a  = get_type_alignment_bytes(t);
312
313
314
315
316
317
318

			if (a > align)
				align = a;
		}
	} else if (is_Method_type(tp)) {
		align = 0;
	}
Michael Beck's avatar
Michael Beck committed
319

320
321
	/* write back */
	tp->align = align;
Michael Beck's avatar
Michael Beck committed
322

323
	return align;
Michael Beck's avatar
Michael Beck committed
324
325
}

326
327
void set_type_alignment_bytes(ir_type *tp, unsigned align)
{
328
329
330
331
332
	assert(tp && tp->kind == k_type);
	/* Methods don't have an alignment. */
	if (tp->type_op != type_method) {
		tp->align = align;
	}
Michael Beck's avatar
Michael Beck committed
333
334
}

335
336
const char *get_type_state_name(ir_type_state s)
{
Götz Lindenmaier's avatar
Götz Lindenmaier committed
337
#define X(a)    case a: return #a;
338
339
340
341
342
	switch (s) {
		X(layout_undefined);
		X(layout_fixed);
	}
	return "<unknown>";
Götz Lindenmaier's avatar
Götz Lindenmaier committed
343
344
345
#undef X
}

346
347
ir_type_state (get_type_state)(const ir_type *tp)
{
348
	return _get_type_state(tp);
349
350
}

351
352
void set_type_state(ir_type *tp, ir_type_state state)
{
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
	assert(tp && tp->kind == k_type);

	if ((tp->type_op == type_pointer) || (tp->type_op == type_primitive) ||
		(tp->type_op == type_method))
		return;

	/* Just a correctness check: */
	if (state == layout_fixed) {
		int i;
		switch (get_type_tpop_code(tp)) {
		case tpo_class:
			if (tp != get_glob_type()) {
				int n_mem = get_class_n_members(tp);
				for (i = 0; i < n_mem; i++) {
					assert(get_entity_offset(get_class_member(tp, i)) > -1);
					/* TR ??
					assert(is_Method_type(get_entity_type(get_class_member(tp, i))) ||
					(get_entity_allocation(get_class_member(tp, i)) == allocation_automatic));
					*/
				}
			}
			break;
		case tpo_struct:
			for (i = 0; i < get_struct_n_members(tp); i++) {
				assert(get_entity_offset(get_struct_member(tp, i)) > -1);
			}
			break;
		case tpo_union:
			/* ?? */
			break;
		case tpo_array:
			/* ??
			   Check order?
			   Assure that only innermost dimension is dynamic? */
			break;
		case tpo_enumeration:
389
#ifndef NDEBUG
390
			assert(get_type_mode(tp) != NULL);
391
392
			for (i = get_enumeration_n_enums(tp) - 1; i >= 0; --i) {
				ir_enum_const *ec = get_enumeration_const(tp, i);
Matthias Braun's avatar
Matthias Braun committed
393
				ir_tarval     *tv = get_enumeration_value(ec);
394
395
				assert(tv != NULL && tv != tarval_bad);
			}
396
#endif
397
398
399
400
401
402
403
404
			break;
		default: break;
		} /* switch (tp) */
	}
	if (state == layout_fixed)
		tp->flags |= tf_layout_fixed;
	else
		tp->flags &= ~tf_layout_fixed;
405
406
}

407
408
ir_visited_t (get_type_visited)(const ir_type *tp)
{
409
	return _get_type_visited(tp);
410
}
411

412
413
void (set_type_visited)(ir_type *tp, ir_visited_t num)
{
414
	_set_type_visited(tp, num);
415
}
416

417
418
void (mark_type_visited)(ir_type *tp)
{
419
	_mark_type_visited(tp);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
420
421
}

422
423
int (type_visited)(const ir_type *tp)
{
424
	return _type_visited(tp);
425
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
426

427
428
int (type_not_visited)(const ir_type *tp)
{
429
	return _type_not_visited(tp);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
430
431
}

432
type_dbg_info *(get_type_dbg_info)(const ir_type *tp)
433
{
434
435
436
	return _get_type_dbg_info(tp);
}

437
void (set_type_dbg_info)(ir_type *tp, type_dbg_info *db)
438
{
439
440
441
	_set_type_dbg_info(tp, db);
}

442
443
444
int (is_type)(const void *thing)
{
	return _is_type(thing);
445
}
446

Michael Beck's avatar
Michael Beck committed
447
/* Checks whether two types are structural equal.*/
448
449
int equal_type(ir_type *typ1, ir_type *typ2)
{
450
451
452
453
454
455
456
	ir_entity **m;
	ir_type **t;
	int i, j;

	if (typ1 == typ2) return 1;

	if ((get_type_tpop_code(typ1) != get_type_tpop_code(typ2)) ||
457
	    typ1->name != typ2->name ||
458
459
460
461
	    (get_type_mode(typ1) != get_type_mode(typ2)) ||
	    (get_type_state(typ1) != get_type_state(typ2)))
		return 0;
	if ((get_type_state(typ1) == layout_fixed) &&
462
		(get_type_size_bytes(typ1) != get_type_size_bytes(typ2)))
463
464
465
466
467
468
469
470
471
		return 0;

	switch (get_type_tpop_code(typ1)) {
	case tpo_class:
		if (get_class_n_members(typ1) != get_class_n_members(typ2)) return 0;
		if (get_class_n_subtypes(typ1) != get_class_n_subtypes(typ2)) return 0;
		if (get_class_n_supertypes(typ1) != get_class_n_supertypes(typ2)) return 0;
		if (get_class_peculiarity(typ1) != get_class_peculiarity(typ2)) return 0;
		/** Compare the members **/
472
		m = ALLOCANZ(ir_entity*, get_class_n_members(typ1));
473
474
475
476
477
478
479
480
481
482
		/* First sort the members of typ2 */
		for (i = 0; i < get_class_n_members(typ1); i++) {
			ir_entity *e1 = get_class_member(typ1, i);
			for (j = 0; j < get_class_n_members(typ2); j++) {
				ir_entity *e2 = get_class_member(typ2, j);
				if (get_entity_name(e1) == get_entity_name(e2))
					m[i] = e2;
			}
		}
		for (i = 0; i < get_class_n_members(typ1); i++) {
483
			if (!m[i] || get_class_member(typ1, i) != m[i])
484
485
486
				return 0;
		}
		/** Compare the supertypes **/
487
		t = ALLOCANZ(ir_type*, get_class_n_supertypes(typ1));
488
489
490
491
492
		/* First sort the supertypes of typ2 */
		for (i = 0; i < get_class_n_supertypes(typ1); i++) {
			ir_type *t1 = get_class_supertype(typ1, i);
			for (j = 0; j < get_class_n_supertypes(typ2); j++) {
				ir_type *t2 = get_class_supertype(typ2, j);
493
				if (t2->name == t1->name)
494
495
496
497
498
499
500
501
502
503
504
505
					t[i] = t2;
			}
		}
		for (i = 0; i < get_class_n_supertypes(typ1); i++) {
			if (!t[i]  ||  /* Found no counterpart */
				get_class_supertype(typ1, i) != t[i])
				return 0;
		}
		break;

	case tpo_struct:
		if (get_struct_n_members(typ1) != get_struct_n_members(typ2)) return 0;
506
		m = ALLOCANZ(ir_entity*, get_struct_n_members(typ1));
507
508
509
510
511
512
513
514
515
516
		/* First sort the members of lt */
		for (i = 0; i < get_struct_n_members(typ1); i++) {
			ir_entity *e1 = get_struct_member(typ1, i);
			for (j = 0; j < get_struct_n_members(typ2); j++) {
				ir_entity *e2 = get_struct_member(typ2, j);
				if (get_entity_name(e1) == get_entity_name(e2))
					m[i] = e2;
			}
		}
		for (i = 0; i < get_struct_n_members(typ1); i++) {
517
			if (!m[i] || get_struct_member(typ1, i) != m[i])
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
				return 0;
		}
		break;

	case tpo_method: {
		int n_param1, n_param2;

		if (get_method_variadicity(typ1) != get_method_variadicity(typ2)) return 0;
		if (get_method_n_ress(typ1)      != get_method_n_ress(typ2)) return 0;
		if (get_method_calling_convention(typ1) !=
		    get_method_calling_convention(typ2)) return 0;

		if (get_method_variadicity(typ1) == variadicity_non_variadic) {
			n_param1 = get_method_n_params(typ1);
			n_param2 = get_method_n_params(typ2);
		} else {
			n_param1 = get_method_first_variadic_param_index(typ1);
			n_param2 = get_method_first_variadic_param_index(typ2);
		}

		if (n_param1 != n_param2) return 0;

		for (i = 0; i < n_param1; i++) {
			if (!equal_type(get_method_param_type(typ1, i), get_method_param_type(typ2, i)))
				return 0;
		}
		for (i = 0; i < get_method_n_ress(typ1); i++) {
			if (!equal_type(get_method_res_type(typ1, i), get_method_res_type(typ2, i)))
				return 0;
		}
	} break;

	case tpo_union:
		if (get_union_n_members(typ1) != get_union_n_members(typ2)) return 0;
552
		m = ALLOCANZ(ir_entity*, get_union_n_members(typ1));
553
554
555
556
557
558
559
560
561
562
		/* First sort the members of lt */
		for (i = 0; i < get_union_n_members(typ1); i++) {
			ir_entity *e1 = get_union_member(typ1, i);
			for (j = 0; j < get_union_n_members(typ2); j++) {
				ir_entity *e2 = get_union_member(typ2, j);
				if (get_entity_name(e1) == get_entity_name(e2))
					m[i] = e2;
			}
		}
		for (i = 0; i < get_union_n_members(typ1); i++) {
563
			if (!m[i] || get_union_member(typ1, i) != m[i])
564
565
566
567
568
569
570
571
572
				return 0;
		}
		break;

	case tpo_array:
		if (get_array_n_dimensions(typ1) != get_array_n_dimensions(typ2))
			return 0;
		if (!equal_type(get_array_element_type(typ1), get_array_element_type(typ2)))
			return 0;
573
		for (i = 0; i < get_array_n_dimensions(typ1); i++) {
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
			if (get_array_lower_bound(typ1, i) != get_array_lower_bound(typ2, i) ||
				get_array_upper_bound(typ1, i) != get_array_upper_bound(typ2, i))
				return 0;
			if (get_array_order(typ1, i) != get_array_order(typ2, i))
				assert(0 && "type compare with different dimension orders not implemented");
		}
		break;

	case tpo_enumeration:
		assert(0 && "enumerations not implemented");
		break;

	case tpo_pointer:
		if (get_pointer_points_to_type(typ1) != get_pointer_points_to_type(typ2))
			return 0;
		break;

	case tpo_primitive:
		break;

	default: break;
	}
	return 1;
597
598
}

599
600
int smaller_type(ir_type *st, ir_type *lt)
{
601
602
603
604
605
606
607
608
	ir_entity **m;
	int i, j, n_st_members;

	if (st == lt) return 1;

	if (get_type_tpop_code(st) != get_type_tpop_code(lt))
		return 0;

609
	switch (get_type_tpop_code(st)) {
610
611
612
613
614
615
616
617
	case tpo_class:
		return is_SubClass_of(st, lt);

	case tpo_struct:
		n_st_members = get_struct_n_members(st);
		if (n_st_members != get_struct_n_members(lt))
			return 0;

618
		m = ALLOCANZ(ir_entity*, n_st_members);
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
		/* First sort the members of lt */
		for (i = 0; i < n_st_members; ++i) {
			ir_entity *se = get_struct_member(st, i);
			int n = get_struct_n_members(lt);
			for (j = 0; j < n; ++j) {
				ir_entity *le = get_struct_member(lt, j);
				if (get_entity_name(le) == get_entity_name(se))
					m[i] = le;
			}
		}
		for (i = 0; i < n_st_members; i++) {
			if (!m[i]  ||  /* Found no counterpart */
			    !smaller_type(get_entity_type(get_struct_member(st, i)), get_entity_type(m[i])))
				return 0;
		}
		break;

	case tpo_method: {
		int n_param1, n_param2;

		/** FIXME: is this still 1? */
		if (get_method_variadicity(st) != get_method_variadicity(lt)) return 0;
		if (get_method_n_ress(st) != get_method_n_ress(lt)) return 0;
		if (get_method_calling_convention(st) !=
		    get_method_calling_convention(lt)) return 0;

		if (get_method_variadicity(st) == variadicity_non_variadic) {
			n_param1 = get_method_n_params(st);
			n_param2 = get_method_n_params(lt);
		} else {
			n_param1 = get_method_first_variadic_param_index(st);
			n_param2 = get_method_first_variadic_param_index(lt);
		}

		if (n_param1 != n_param2) return 0;

		for (i = 0; i < get_method_n_params(st); i++) {
			if (!smaller_type(get_method_param_type(st, i), get_method_param_type(lt, i)))
				return 0;
		}
		for (i = 0; i < get_method_n_ress(st); i++) {
			if (!smaller_type(get_method_res_type(st, i), get_method_res_type(lt, i)))
				return 0;
		}
	} break;

	case tpo_union:
		n_st_members = get_union_n_members(st);
		if (n_st_members != get_union_n_members(lt)) return 0;
668
		m = ALLOCANZ(ir_entity*, n_st_members);
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
		/* First sort the members of lt */
		for (i = 0; i < n_st_members; ++i) {
			ir_entity *se = get_union_member(st, i);
			int n = get_union_n_members(lt);
			for (j = 0; j < n; ++j) {
				ir_entity *le = get_union_member(lt, j);
				if (get_entity_name(le) == get_entity_name(se))
					m[i] = le;
			}
		}
		for (i = 0; i < n_st_members; ++i) {
			if (!m[i]  ||  /* Found no counterpart */
				!smaller_type(get_entity_type(get_union_member(st, i)), get_entity_type(m[i])))
				return 0;
		}
		break;

	case tpo_array: {
		ir_type *set, *let;  /* small/large elt. ir_type */
		if (get_array_n_dimensions(st) != get_array_n_dimensions(lt))
			return 0;
		set = get_array_element_type(st);
		let = get_array_element_type(lt);
		if (set != let) {
			/* If the element types are different, set must be convertible
			   to let, and they must have the same size so that address
			   computations work out.  To have a size the layout must
			   be fixed. */
			if ((get_type_state(set) != layout_fixed) ||
			    (get_type_state(let) != layout_fixed))
				return 0;
			if (!smaller_type(set, let) ||
701
			    get_type_size_bytes(set) != get_type_size_bytes(let))
702
703
				return 0;
		}
704
		for (i = 0; i < get_array_n_dimensions(st); i++) {
705
			if (get_array_lower_bound(lt, i))
706
				if (get_array_lower_bound(st, i) != get_array_lower_bound(lt, i))
707
708
					return 0;
				if (get_array_upper_bound(lt, i))
709
					if (get_array_upper_bound(st, i) != get_array_upper_bound(lt, i))
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
						return 0;
		}
	} break;

	case tpo_enumeration:
		assert(0 && "enumerations not implemented");
		break;

	case tpo_pointer:
		if (!smaller_type(get_pointer_points_to_type(st), get_pointer_points_to_type(lt)))
			return 0;
		break;

	case tpo_primitive:
		if (!smaller_mode(get_type_mode(st), get_type_mode(lt)))
			return 0;
		break;

	default: break;
	}
	return 1;
731
732
}

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

734
ir_type *new_d_type_class(ident *name, type_dbg_info *db)
735
{
736
	ir_type *res;
Christian Schäfer's avatar
Christian Schäfer committed
737

738
739
	res = new_type(type_class, NULL, db);
	res->name = name;
Christian Schäfer's avatar
Christian Schäfer committed
740

741
742
743
744
745
746
747
748
749
750
	res->attr.ca.members     = NEW_ARR_F (ir_entity *, 0);
	res->attr.ca.subtypes    = NEW_ARR_F (ir_type *, 0);
	res->attr.ca.supertypes  = NEW_ARR_F (ir_type *, 0);
	res->attr.ca.peculiarity = peculiarity_existent;
	res->attr.ca.type_info   = NULL;
	res->attr.ca.vtable_size = 0;
	res->attr.ca.clss_flags  = cf_none;
	res->attr.ca.dfn         = 0;
	hook_new_type(res);
	return res;
Christian Schäfer's avatar
Christian Schäfer committed
751
}
752

753
754
ir_type *new_type_class(ident *name)
{
755
	return new_d_type_class (name, NULL);
756
}
757

758
759
void free_class_entities(ir_type *clss)
{
760
761
762
763
764
	int i;
	assert(clss && (clss->type_op == type_class));
	for (i = get_class_n_members(clss) - 1; i >= 0; --i)
		free_entity(get_class_member(clss, i));
	/* do NOT free the type info here. It belongs to another class */
765
766
}

767
768
void free_class_attrs(ir_type *clss)
{
769
770
771
772
	assert(clss && (clss->type_op == type_class));
	DEL_ARR_F(clss->attr.ca.members);
	DEL_ARR_F(clss->attr.ca.subtypes);
	DEL_ARR_F(clss->attr.ca.supertypes);
773
}
774

775
776
777
778
779
780
781
782
ident *get_class_ident(const ir_type *clss)
{
	assert(clss->type_op == type_class);
	return clss->name;
}

const char *get_class_name(const ir_type *clss)
{
783
784
	if (get_class_ident(clss) == NULL)
		return NULL;
785
786
787
	return get_id_str(get_class_ident(clss));
}

788
static void add_class_member(ir_type *clss, ir_entity *member)
789
{
790
791
792
	assert(clss && (clss->type_op == type_class));
	assert(clss != get_entity_type(member) && "recursive type");
	ARR_APP1 (ir_entity *, clss->attr.ca.members, member);
Christian Schäfer's avatar
Christian Schäfer committed
793
}
794

795
796
int (get_class_n_members)(const ir_type *clss)
{
797
	return _get_class_n_members(clss);
Christian Schäfer's avatar
Christian Schäfer committed
798
}
799

800
801
int get_class_member_index(const ir_type *clss, ir_entity *mem)
{
802
803
804
805
806
807
	int i, n;
	assert(clss && (clss->type_op == type_class));
	for (i = 0, n = get_class_n_members(clss); i < n; ++i)
		if (get_class_member(clss, i) == mem)
			return i;
		return -1;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
808
}
809

810
811
ir_entity *(get_class_member)(const ir_type *clss, int pos)
{
812
	return _get_class_member(clss, pos);
813
}
814

815
816
ir_entity *get_class_member_by_name(ir_type *clss, ident *name)
{
817
818
819
820
821
822
823
824
825
826
	int i, n_mem;
	assert(clss && (clss->type_op == type_class));
	n_mem = get_class_n_members(clss);
	for (i = 0; i < n_mem; ++i) {
		ir_entity *mem = get_class_member(clss, i);
		if (get_entity_ident(mem) == name) return mem;
	}
	return NULL;
}

827
static void remove_class_member(ir_type *clss, ir_entity *member)
828
{
829
	size_t i;
830
	assert(clss && (clss->type_op == type_class));
831
	for (i = 0; i < ARR_LEN(clss->attr.ca.members); ++i) {
832
		if (clss->attr.ca.members[i] == member) {
833
			for (; i < ARR_LEN(clss->attr.ca.members) - 1; ++i)
834
835
836
837
838
				clss->attr.ca.members[i] = clss->attr.ca.members[i + 1];
			ARR_SETLEN(ir_entity*, clss->attr.ca.members, ARR_LEN(clss->attr.ca.members) - 1);
			break;
		}
	}
839
}
840

841
842
void add_class_subtype(ir_type *clss, ir_type *subtype)
{
843
844
845
846
847
848
849
850
851
852
	int i;
	assert(clss && (clss->type_op == type_class));
	ARR_APP1 (ir_type *, clss->attr.ca.subtypes, subtype);
	for (i = 0; i < get_class_n_supertypes(subtype); i++)
		if (get_class_supertype(subtype, i) == clss)
			/* Class already registered */
			return;
		ARR_APP1(ir_type *, subtype->attr.ca.supertypes, clss);
}

853
854
int get_class_n_subtypes(const ir_type *clss)
{
855
856
857
858
	assert(clss && (clss->type_op == type_class));
	return (ARR_LEN (clss->attr.ca.subtypes));
}

859
860
ir_type *get_class_subtype(ir_type *clss, int pos)
{
861
862
	assert(clss && (clss->type_op == type_class));
	assert(pos >= 0 && pos < get_class_n_subtypes(clss));
Matthias Braun's avatar
Matthias Braun committed
863
	return clss->attr.ca.subtypes[pos];
864
865
}

866
867
int get_class_subtype_index(ir_type *clss, const ir_type *subclass)
{
868
869
870
871
872
873
874
875
	int i, n_subtypes = get_class_n_subtypes(clss);
	assert(is_Class_type(subclass));
	for (i = 0; i < n_subtypes; ++i) {
		if (get_class_subtype(clss, i) == subclass) return i;
	}
	return -1;
}

876
877
void set_class_subtype(ir_type *clss, ir_type *subtype, int pos)
{
878
879
880
881
882
	assert(clss && (clss->type_op == type_class));
	assert(pos >= 0 && pos < get_class_n_subtypes(clss));
	clss->attr.ca.subtypes[pos] = subtype;
}

883
884
void remove_class_subtype(ir_type *clss, ir_type *subtype)
{
885
	size_t i;
886
	assert(clss && (clss->type_op == type_class));
887
	for (i = 0; i < ARR_LEN(clss->attr.ca.subtypes); ++i)
888
		if (clss->attr.ca.subtypes[i] == subtype) {
889
			for (; i < ARR_LEN(clss->attr.ca.subtypes) - 1; ++i)
890
				clss->attr.ca.subtypes[i] = clss->attr.ca.subtypes[i+1];
Matthias Braun's avatar
Matthias Braun committed
891
			ARR_SETLEN(ir_type*, clss->attr.ca.subtypes, ARR_LEN(clss->attr.ca.subtypes) - 1);
892
893
894
895
			break;
		}
}

896
897
void add_class_supertype(ir_type *clss, ir_type *supertype)
{
898
899
900
901
902
903
904
905
906
907
908
	int i;
	assert(clss && (clss->type_op == type_class));
	assert(supertype && (supertype -> type_op == type_class));
	ARR_APP1 (ir_type *, clss->attr.ca.supertypes, supertype);
	for (i = get_class_n_subtypes(supertype) - 1; i >= 0; --i)
		if (get_class_subtype(supertype, i) == clss)
			/* Class already registered */
			return;
	ARR_APP1(ir_type *, supertype->attr.ca.subtypes, clss);
}

909
910
int get_class_n_supertypes(const ir_type *clss)
{
911
912
913
914
	assert(clss && (clss->type_op == type_class));
	return ARR_LEN(clss->attr.ca.supertypes);
}

915
916
int get_class_supertype_index(ir_type *clss, ir_type *super_clss)
{
917
918
919
920
921
922
	int i, n_supertypes = get_class_n_supertypes(clss);
	assert(super_clss && (super_clss->type_op == type_class));
	for (i = 0; i < n_supertypes; i++)
		if (get_class_supertype(clss, i) == super_clss)
			return i;
		return -1;
923
}
924

925
926
ir_type *get_class_supertype(ir_type *clss, int pos)
{
927
928
	assert(clss && (clss->type_op == type_class));
	assert(pos >= 0 && pos < get_class_n_supertypes(clss));
Matthias Braun's avatar
Matthias Braun committed
929
	return clss->attr.ca.supertypes[pos];
930
931
}

932
933
void set_class_supertype(ir_type *clss, ir_type *supertype, int pos)
{
934
935
936
937
938
	assert(clss && (clss->type_op == type_class));
	assert(pos >= 0 && pos < get_class_n_supertypes(clss));
	clss->attr.ca.supertypes[pos] = supertype;
}

939
940
void remove_class_supertype(ir_type *clss, ir_type *supertype)
{
941
	size_t i;
942
	assert(clss && (clss->type_op == type_class));
943
	for (i = 0; i < ARR_LEN(clss->attr.ca.supertypes); ++i)
944
		if (clss->attr.ca.supertypes[i] == supertype) {
945
			for (; i < ARR_LEN(clss->attr.ca.supertypes) - 1; ++i)
946
				clss->attr.ca.supertypes[i] = clss->attr.ca.supertypes[i+1];
Matthias Braun's avatar
Matthias Braun committed
947
			ARR_SETLEN(ir_type*, clss->attr.ca.supertypes, ARR_LEN(clss->attr.ca.supertypes) - 1);
948
949
950
951
			break;
		}
}

952
953
ir_entity *get_class_type_info(const ir_type *clss)
{
954
	return clss->attr.ca.type_info;
955
}
956

957
958
void set_class_type_info(ir_type *clss, ir_entity *ent)
{
959
960
961
	clss->attr.ca.type_info = ent;
	if (ent)
		ent->repr_class = clss;
962
}
963

964
965
ir_peculiarity get_class_peculiarity(const ir_type *clss)
{
966
967
	assert(clss && (clss->type_op == type_class));
	return clss->attr.ca.peculiarity;
968
}
Michael Beck's avatar
Michael Beck committed
969

970
971
void set_class_peculiarity(ir_type *clss, ir_peculiarity pec)
{
972
973
974
	assert(clss && (clss->type_op == type_class));
	assert(pec != peculiarity_inherited);  /* There is no inheritance of types in libFirm. */
	clss->attr.ca.peculiarity = pec;
975
976
}

977
978
unsigned (get_class_vtable_size)(const ir_type *clss)
{
979
	return _get_class_vtable_size(clss);
980
981
}

982
983
void (set_class_vtable_size)(ir_type *clss, unsigned size)
{
984
	_set_class_vtable_size(clss, size);
985
986
}

987
988
int (is_class_final)(const ir_type *clss)
{
989
	return _is_class_final(clss);
990
991
}

992
993
void (set_class_final)(ir_type *clss, int flag)
{
994
	_set_class_final(clss, flag);
995
996
}

997
998
int (is_class_interface)(const ir_type *clss)
{
999
	return _is_class_interface(clss);
1000
}
For faster browsing, not all history is shown. View entire blame