entity.c 25 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
 */

Michael Beck's avatar
Michael Beck committed
6
7
8
9
/**
 * @file
 * @brief   Representation of all program known entities.
 * @author  Martin Trapp, Christian Schaefer, Goetz Lindenmaier, Michael Beck
10
 */
Matthias Braun's avatar
Matthias Braun committed
11
#include "config.h"
Boris Boesler's avatar
Boris Boesler committed
12

13
14
#include <stdlib.h>
#include <stddef.h>
15

Michael Beck's avatar
Michael Beck committed
16
17
18
#include "xmalloc.h"
#include "entity_t.h"
#include "array.h"
19
#include "util.h"
Michael Beck's avatar
Michael Beck committed
20
21
22
23
#include "irhooks.h"
#include "irprog_t.h"
#include "ircons.h"
#include "tv_t.h"
24
25
26
#include "irdump.h"
#include "irgraph_t.h"
#include "callgraph.h"
27
#include "error.h"
Götz Lindenmaier's avatar
Götz Lindenmaier committed
28

29
/** The name of the unknown entity. */
30
#define UNKNOWN_ENTITY_NAME "unknown_entity"
31

32
33
34
35
36
ir_entity *get_unknown_entity(void)
{
	return irp->unknown_entity;
}

37
38
39
/*-----------------------------------------------------------------*/
/* ENTITY                                                          */
/*-----------------------------------------------------------------*/
40

Matthias Braun's avatar
Matthias Braun committed
41
42
static ir_entity *intern_new_entity(ir_type *owner, ir_entity_kind kind,
                                    ident *name, ir_type *type, dbg_info *dbgi)
Christian Schäfer's avatar
Christian Schäfer committed
43
{
Matthias Braun's avatar
Matthias Braun committed
44
	assert(owner != NULL);
45

46
	ir_entity *res = XMALLOCZ(ir_entity);
47
48
49
50
51
52
	res->kind    = k_entity;
	res->name    = name;
	res->ld_name = NULL;
	res->type    = type;
	res->owner   = owner;

Matthias Braun's avatar
Matthias Braun committed
53
	res->entity_kind          = kind;
54
	res->volatility           = volatility_non_volatile;
Matthias Braun's avatar
Matthias Braun committed
55
	res->aligned              = align_is_aligned;
56
	res->usage                = ir_usage_unknown;
57
	res->compiler_gen         = 0;
Matthias Braun's avatar
Matthias Braun committed
58
	res->visibility           = ir_visibility_external;
59
60
	res->offset               = -1;
	res->offset_bit_remainder = 0;
Matthias Braun's avatar
Matthias Braun committed
61
	res->alignment            = 0;
62
	res->link                 = NULL;
63
64
65
66
67
#ifdef DEBUG_libfirm
	res->nr = get_irp_new_node_nr();
#endif

	/* Remember entity in its owner. */
68
	if (is_compound_type(owner))
69
70
71
72
73
74
75
76
77
78
79
		add_compound_member(owner, res);

	res->visit = 0;
	set_entity_dbg_info(res, dbgi);

	return res;
}

ir_entity *new_d_entity(ir_type *owner, ident *name, ir_type *type,
                        dbg_info *db)
{
Matthias Braun's avatar
Matthias Braun committed
80
	ir_entity *res;
81
	if (is_Method_type(type)) {
82
		ir_graph *irg = get_const_code_irg();
83
		symconst_symbol sym;
Matthias Braun's avatar
Matthias Braun committed
84
		res = intern_new_entity(owner, IR_ENTITY_METHOD, name, type, db);
85
		sym.entity_p            = res;
Matthias Braun's avatar
Matthias Braun committed
86
87
88
89
90
91
92
		set_atomic_ent_value(res, new_r_SymConst(irg, mode_P_code, sym, symconst_addr_ent));
		res->linkage                     = IR_LINKAGE_CONSTANT;
		res->attr.mtd_attr.properties    = get_method_additional_properties(type);
		res->attr.mtd_attr.vtable_number = IR_VTABLE_NUM_NOT_SET;
		res->attr.mtd_attr.param_access  = NULL;
		res->attr.mtd_attr.param_weight  = NULL;
		res->attr.mtd_attr.irg           = NULL;
93
	} else if (is_compound_type(owner) && !(owner->flags & tf_segment)) {
Matthias Braun's avatar
Matthias Braun committed
94
95
96
		res = intern_new_entity(owner, IR_ENTITY_COMPOUND_MEMBER, name, type, db);
	} else {
		res = intern_new_entity(owner, IR_ENTITY_NORMAL, name, type, db);
97
98
	}

99
100
101
	hook_new_entity(res);
	return res;
}
102

103
104
105
106
ir_entity *new_entity(ir_type *owner, ident *name, ir_type *type)
{
	return new_d_entity(owner, name, type, NULL);
}
107

108
109
110
111
112
113
static ident *make_parameter_entity_name(size_t pos)
{
	char buf[64];
	snprintf(buf, sizeof(buf), "parameter.%lu", (unsigned long) pos);
	return new_id_from_str(buf);
}
Christian Schäfer's avatar
Christian Schäfer committed
114

115
116
117
ir_entity *new_d_parameter_entity(ir_type *owner, size_t pos, ir_type *type,
                                  dbg_info *dbgi)
{
Matthias Braun's avatar
Matthias Braun committed
118
119
120
	ident     *name = make_parameter_entity_name(pos);
	ir_entity *res
		= intern_new_entity(owner, IR_ENTITY_PARAMETER, name, type, dbgi);
121
	res->attr.parameter.number = pos;
122
123
	hook_new_entity(res);
	return res;
124
}
125

126
ir_entity *new_parameter_entity(ir_type *owner, size_t pos, ir_type *type)
127
{
128
	return new_d_parameter_entity(owner, pos, type, NULL);
129
}
130

Matthias Braun's avatar
Matthias Braun committed
131
132
133
134
135
ir_entity *new_d_label_entity(ir_label_t label, dbg_info *dbgi)
{
	ident *name = id_unique("label_%u");
	ir_type *global_type = get_glob_type();
	ir_entity *res
136
		= intern_new_entity(global_type, IR_ENTITY_LABEL, name, get_code_type(),
Matthias Braun's avatar
Matthias Braun committed
137
138
139
140
141
142
143
144
145
146
147
		                    dbgi);
	res->attr.code_attr.label = label;
	hook_new_entity(res);
	return res;
}

ir_entity *new_label_entity(ir_label_t label)
{
	return new_d_label_entity(label, NULL);
}

148
149
150
151
152
/**
 * Free entity attributes.
 *
 * @param ent  the entity
 */
Matthias Braun's avatar
Matthias Braun committed
153
154
static void free_entity_attrs(ir_entity *ent)
{
155
156
157
	if (ent->overwrites != NULL) {
		DEL_ARR_F(ent->overwrites);
		ent->overwrites = NULL;
158
	}
159
160
161
162
163
	if (ent->overwrittenby != NULL) {
		DEL_ARR_F(ent->overwrittenby);
		ent->overwrittenby = NULL;
	}

Matthias Braun's avatar
Matthias Braun committed
164
165
166
	if (ent->initializer != NULL) {
		/* TODO: free initializers */
	}
167
	if (ent->entity_kind == IR_ENTITY_METHOD) {
168
169
170
171
172
173
174
175
176
		if (ent->attr.mtd_attr.param_access) {
			DEL_ARR_F(ent->attr.mtd_attr.param_access);
			ent->attr.mtd_attr.param_access = NULL;
		}
		if (ent->attr.mtd_attr.param_weight) {
			DEL_ARR_F(ent->attr.mtd_attr.param_weight);
			ent->attr.mtd_attr.param_weight = NULL;
		}
	}
177
}
Christian Schäfer's avatar
Christian Schäfer committed
178

179
180
181
182
183
184
185
/**
 * Creates a deep copy of an entity.
 */
static ir_entity *deep_entity_copy(ir_entity *old)
{
	ir_entity *newe = XMALLOC(ir_entity);

186
	*newe = *old;
Matthias Braun's avatar
Matthias Braun committed
187
188
	if (old->initializer != NULL) {
		/* FIXME: the initializers are NOT copied */
189
190
191
192
193
	} else if (is_method_entity(old)) {
		/* do NOT copy them, reanalyze. This might be the best solution */
		newe->attr.mtd_attr.param_access = NULL;
		newe->attr.mtd_attr.param_weight = NULL;
	}
194
195
	newe->overwrites    = NULL;
	newe->overwrittenby = NULL;
196
197
198
199

#ifdef DEBUG_libfirm
	newe->nr = get_irp_new_node_nr();
#endif
200
	hook_new_entity(newe);
201
202
	return newe;
}
203

204
ir_entity *copy_entity_own(ir_entity *old, ir_type *new_owner)
205
{
206
207
	assert(is_entity(old));
	assert(is_compound_type(new_owner));
208
	assert(get_type_state(new_owner) != layout_fixed);
209
210
211
212
	if (old->owner == new_owner)
		return old;

	/* create a deep copy so we are safe of aliasing and double-freeing. */
Matthias Braun's avatar
Matthias Braun committed
213
	ir_entity *newe = deep_entity_copy(old);
214
	newe->owner = new_owner;
215
	add_compound_member(new_owner, newe);
216

217
	return newe;
218
}
219

220
ir_entity *copy_entity_name(ir_entity *old, ident *new_name)
221
{
Matthias Braun's avatar
Matthias Braun committed
222
	assert(old->kind == k_entity);
223
224
225
	if (old->name == new_name)
		return old;

Matthias Braun's avatar
Matthias Braun committed
226
227
	ir_entity *newe = deep_entity_copy(old);
	newe->name    = new_name;
228
	newe->ld_name = NULL;
229
	add_compound_member(old->owner, newe);
230

231
	return newe;
232
}
233

234
void free_entity(ir_entity *ent)
235
{
236
	if (is_compound_type(ent->owner))
237
		remove_compound_member(ent->owner, ent);
238

Matthias Braun's avatar
Matthias Braun committed
239
	assert(ent->kind == k_entity);
240
	free_entity_attrs(ent);
241
#ifdef DEBUG_libfirm
242
	ent->kind = k_BAD;
243
#endif
244
	free(ent);
245
}
246

247
long get_entity_nr(const ir_entity *ent)
248
{
Matthias Braun's avatar
Matthias Braun committed
249
	assert(ent->kind == k_entity);
250
#ifdef DEBUG_libfirm
251
	return ent->nr;
252
#else
253
	return (long)PTR_TO_INT(ent);
254
#endif
255
}
256

257
258
const char *(get_entity_name)(const ir_entity *ent)
{
259
	return _get_entity_name(ent);
Matthias Braun's avatar
Matthias Braun committed
260
}
Christian Schäfer's avatar
Christian Schäfer committed
261

262
263
ident *(get_entity_ident)(const ir_entity *ent)
{
264
	return _get_entity_ident(ent);
Matthias Braun's avatar
Matthias Braun committed
265
}
Michael Beck's avatar
Michael Beck committed
266

267
268
void (set_entity_ident)(ir_entity *ent, ident *id)
{
269
	_set_entity_ident(ent, id);
Matthias Braun's avatar
Matthias Braun committed
270
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
271

272
273
ir_type *(get_entity_owner)(const ir_entity *ent)
{
274
	return _get_entity_owner(ent);
Matthias Braun's avatar
Matthias Braun committed
275
}
Christian Schäfer's avatar
Christian Schäfer committed
276

277
void set_entity_owner(ir_entity *ent, ir_type *owner)
278
{
279
280
	assert(is_entity(ent));
	assert(is_compound_type(owner));
281
282
283

	remove_compound_member(ent->owner, ent);
	add_compound_member(owner, ent);
284
	ent->owner = owner;
Matthias Braun's avatar
Matthias Braun committed
285
}
Christian Schäfer's avatar
Christian Schäfer committed
286

Matthias Braun's avatar
Matthias Braun committed
287
288
ident *(get_entity_ld_ident)(const ir_entity *ent)
{
289
	return _get_entity_ld_ident(ent);
Matthias Braun's avatar
Matthias Braun committed
290
}
291

292
293
void (set_entity_ld_ident)(ir_entity *ent, ident *ld_ident)
{
294
	_set_entity_ld_ident(ent, ld_ident);
Matthias Braun's avatar
Matthias Braun committed
295
}
Christian Schäfer's avatar
Christian Schäfer committed
296

Matthias Braun's avatar
Matthias Braun committed
297
298
const char *(get_entity_ld_name)(const ir_entity *ent)
{
299
	return _get_entity_ld_name(ent);
Matthias Braun's avatar
Matthias Braun committed
300
}
301

302
303
304
305
306
int entity_has_ld_ident(const ir_entity *entity)
{
	return entity->ld_name != NULL;
}

307
308
ir_type *(get_entity_type)(const ir_entity *ent)
{
309
	return _get_entity_type(ent);
Matthias Braun's avatar
Matthias Braun committed
310
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
311

Matthias Braun's avatar
Matthias Braun committed
312
313
314
315
316
317
318
319
320
321
void set_entity_type(ir_entity *ent, ir_type *type)
{
	switch (ent->entity_kind) {
	case IR_ENTITY_METHOD:
		assert(is_Method_type(type));
		break;
	case IR_ENTITY_NORMAL:
		assert(!is_Method_type(type));
		break;
	case IR_ENTITY_LABEL:
322
		assert(type == get_code_type());
Matthias Braun's avatar
Matthias Braun committed
323
324
325
326
327
		break;
	case IR_ENTITY_COMPOUND_MEMBER:
		break;
	}
	ent->type = type;
Matthias Braun's avatar
Matthias Braun committed
328
}
Götz Lindenmaier's avatar
a    
Götz Lindenmaier committed
329

330
331
ir_volatility (get_entity_volatility)(const ir_entity *ent)
{
332
	return _get_entity_volatility(ent);
Matthias Braun's avatar
Matthias Braun committed
333
}
Götz Lindenmaier's avatar
a    
Götz Lindenmaier committed
334

335
336
void (set_entity_volatility)(ir_entity *ent, ir_volatility vol)
{
337
	_set_entity_volatility(ent, vol);
Matthias Braun's avatar
Matthias Braun committed
338
}
Götz Lindenmaier's avatar
a    
Götz Lindenmaier committed
339

340
const char *get_volatility_name(ir_volatility var)
341
{
342
#define X(a)    case a: return #a
343
344
345
346
	switch (var) {
	X(volatility_non_volatile);
	X(volatility_is_volatile);
	}
347
#undef X
Matthias Braun's avatar
Matthias Braun committed
348
	return "BAD VALUE";
349
}
350

351
352
ir_align (get_entity_aligned)(const ir_entity *ent)
{
Matthias Braun's avatar
Matthias Braun committed
353
354
	return _get_entity_aligned(ent);
}
355

356
357
void (set_entity_aligned)(ir_entity *ent, ir_align a)
{
Matthias Braun's avatar
Matthias Braun committed
358
359
	_set_entity_aligned(ent, a);
}
360

361
362
unsigned (get_entity_alignment)(const ir_entity *ent)
{
363
364
365
	return _get_entity_alignment(ent);
}

366
367
void (set_entity_alignment)(ir_entity *ent, unsigned alignment)
{
368
369
370
	_set_entity_alignment(ent, alignment);
}

Michael Beck's avatar
Michael Beck committed
371
372
373
374
375
376
377
378
const char *get_align_name(ir_align a)
{
#define X(a)    case a: return #a
	switch (a) {
	X(align_non_aligned);
	X(align_is_aligned);
	}
#undef X
Matthias Braun's avatar
Matthias Braun committed
379
	return "BAD VALUE";
380
}
Michael Beck's avatar
Michael Beck committed
381

382
void set_entity_label(ir_entity *ent, ir_label_t label)
383
{
Matthias Braun's avatar
Matthias Braun committed
384
	assert(ent->entity_kind == IR_ENTITY_LABEL);
385
386
387
388
389
	ent->attr.code_attr.label = label;
}

ir_label_t get_entity_label(const ir_entity *ent)
{
Matthias Braun's avatar
Matthias Braun committed
390
	assert(ent->entity_kind == IR_ENTITY_LABEL);
391
392
393
	return ent->attr.code_attr.label;
}

394
395
396
397
398
399
400
void set_entity_visibility(ir_entity *entity, ir_visibility visibility)
{
	entity->visibility = visibility;
}

ir_visibility get_entity_visibility(const ir_entity *entity)
{
401
	return (ir_visibility)entity->visibility;
402
403
}

Matthias Braun's avatar
Matthias Braun committed
404
405
406
407
408
409
410
411
412
void set_entity_linkage(ir_entity *entity, ir_linkage linkage)
{
	entity->linkage = linkage;
}

ir_linkage (get_entity_linkage)(const ir_entity *entity)
{
	return get_entity_linkage(entity);
}
413

Matthias Braun's avatar
Matthias Braun committed
414
415
416
417
void add_entity_linkage(ir_entity *entity, ir_linkage linkage)
{
	entity->linkage |= linkage;
}
418

Matthias Braun's avatar
Matthias Braun committed
419
420
421
422
void remove_entity_linkage(ir_entity *entity, ir_linkage linkage)
{
	entity->linkage &= ~linkage;
}
423

424
425
int (is_entity_compiler_generated)(const ir_entity *ent)
{
Michael Beck's avatar
Michael Beck committed
426
	return _is_entity_compiler_generated(ent);
427
}
428

429
430
void (set_entity_compiler_generated)(ir_entity *ent, int flag)
{
Michael Beck's avatar
Michael Beck committed
431
	_set_entity_compiler_generated(ent, flag);
432
}
433

434
435
ir_entity_usage (get_entity_usage)(const ir_entity *ent)
{
436
437
	return _get_entity_usage(ent);
}
Michael Beck's avatar
Michael Beck committed
438

439
440
void (set_entity_usage)(ir_entity *ent, ir_entity_usage flags)
{
441
442
	_set_entity_usage(ent, flags);
}
443

444
ir_node *get_atomic_ent_value(const ir_entity *entity)
Matthias Braun's avatar
Matthias Braun committed
445
446
{
	ir_initializer_t *initializer = get_entity_initializer(entity);
447

Matthias Braun's avatar
Matthias Braun committed
448
	assert(is_atomic_entity(entity));
Matthias Braun's avatar
Matthias Braun committed
449
450
451
452
	if (initializer == NULL) {
		ir_type *type = get_entity_type(entity);
		return new_r_Unknown(get_const_code_irg(), get_type_mode(type));
	}
453

Matthias Braun's avatar
Matthias Braun committed
454
455
456
457
458
459
460
	switch (get_initializer_kind(initializer)) {
	case IR_INITIALIZER_NULL: {
		ir_type *type = get_entity_type(entity);
		ir_mode *mode = get_type_mode(type);
		return new_r_Const(get_const_code_irg(), get_mode_null(mode));
	}
	case IR_INITIALIZER_TARVAL: {
Matthias Braun's avatar
Matthias Braun committed
461
		ir_tarval *tv = get_initializer_tarval_value(initializer);
Matthias Braun's avatar
Matthias Braun committed
462
463
464
465
466
467
468
469
		return new_r_Const(get_const_code_irg(), tv);
	}
	case IR_INITIALIZER_CONST:
		return get_initializer_const_value(initializer);
	case IR_INITIALIZER_COMPOUND:
		panic("compound initializer in atomic entity not allowed (%+F)", entity);
	}

470
	panic("invalid initializer kind (%+F)", entity);
Matthias Braun's avatar
Matthias Braun committed
471
472
473
}

void set_atomic_ent_value(ir_entity *entity, ir_node *val)
474
{
Matthias Braun's avatar
Matthias Braun committed
475
476
	assert(is_atomic_entity(entity));
	assert(is_Dummy(val) || get_irn_mode(val) == get_type_mode(entity->type));
Matthias Braun's avatar
Matthias Braun committed
477
	ir_initializer_t *initializer = create_initializer_const(val);
Matthias Braun's avatar
Matthias Braun committed
478
479
	entity->initializer = initializer;
}
480

481
482
int is_irn_const_expression(ir_node *n)
{
483
	/* we are in danger iff an exception will arise. TODO: be more precisely,
Matthias Braun's avatar
Matthias Braun committed
484
	 * for instance Div. will NOT rise if divisor != 0 */
485
486
487
488
489
490
491
492
493
494
495
496
497
498
	if (is_binop(n) && !is_fragile_op(n))
		return is_irn_const_expression(get_binop_left(n)) && is_irn_const_expression(get_binop_right(n));

	switch (get_irn_opcode(n)) {
	case iro_Const:
	case iro_SymConst:
	case iro_Unknown:
		return 1;
	case iro_Conv:
		return is_irn_const_expression(get_irn_n(n, 0));
	default:
		break;
	}
	return 0;
499
}
Matthias Heil's avatar
Matthias Heil committed
500

501
ir_node *copy_const_value(dbg_info *dbg, ir_node *n, ir_node *block)
502
{
503
	ir_graph *irg = get_irn_irg(block);
504

Matthias Braun's avatar
Matthias Braun committed
505
506
507
508
	/* @@@ GL I think we should implement this using the routines from irgopt
	 * for dead node elimination/inlineing. */
	ir_mode *m = get_irn_mode(n);
	ir_node *nn;
509
510
	switch (get_irn_opcode(n)) {
	case iro_Const:
511
		nn = new_rd_Const(dbg, irg, get_Const_tarval(n));
512
513
		break;
	case iro_SymConst:
514
		nn = new_rd_SymConst(dbg, irg, get_irn_mode(n), get_SymConst_symbol(n), get_SymConst_kind(n));
515
516
		break;
	case iro_Add:
517
518
519
520
		nn = new_rd_Add(dbg, block,
		                copy_const_value(dbg, get_Add_left(n), block),
		                copy_const_value(dbg, get_Add_right(n), block), m);
		break;
521
	case iro_Sub:
522
523
524
525
		nn = new_rd_Sub(dbg, block,
		                copy_const_value(dbg, get_Sub_left(n), block),
		                copy_const_value(dbg, get_Sub_right(n), block), m);
		break;
526
	case iro_Mul:
527
528
529
530
		nn = new_rd_Mul(dbg, block,
		                copy_const_value(dbg, get_Mul_left(n), block),
		                copy_const_value(dbg, get_Mul_right(n), block), m);
		break;
531
	case iro_And:
532
533
534
535
		nn = new_rd_And(dbg, block,
		                copy_const_value(dbg, get_And_left(n), block),
		                copy_const_value(dbg, get_And_right(n), block), m);
		break;
536
	case iro_Or:
537
538
539
540
		nn = new_rd_Or(dbg, block,
		               copy_const_value(dbg, get_Or_left(n), block),
		               copy_const_value(dbg, get_Or_right(n), block), m);
		break;
541
	case iro_Eor:
542
543
544
545
		nn = new_rd_Eor(dbg, block,
		                copy_const_value(dbg, get_Eor_left(n), block),
		                copy_const_value(dbg, get_Eor_right(n), block), m);
		break;
546
	case iro_Conv:
547
548
549
		nn = new_rd_Conv(dbg, block,
		                 copy_const_value(dbg, get_Conv_op(n), block), m);
		break;
550
551
552
553
554
555
556
557
	case iro_Minus:
		nn = new_rd_Minus(dbg, block,
		                  copy_const_value(dbg, get_Minus_op(n), block), m);
		break;
	case iro_Not:
		nn = new_rd_Not(dbg, block,
		                copy_const_value(dbg, get_Not_op(n), block), m);
		break;
558
	case iro_Unknown:
Matthias Braun's avatar
Matthias Braun committed
559
560
		nn = new_r_Unknown(irg, m);
		break;
561
	default:
562
		panic("opcode invalid or not implemented %+F", n);
563
564
	}
	return nn;
565
}
566

567
568
569
570
571
572
573
574
575
576
const char *get_initializer_kind_name(ir_initializer_kind_t ini)
{
#define X(a)    case a: return #a
	switch (ini) {
	X(IR_INITIALIZER_CONST);
	X(IR_INITIALIZER_TARVAL);
	X(IR_INITIALIZER_NULL);
	X(IR_INITIALIZER_COMPOUND);
	}
#undef X
Matthias Braun's avatar
Matthias Braun committed
577
	return "BAD VALUE";
578
579
}

580
581
582
583
584
585
586
587
588
589
590
591
static ir_initializer_t null_initializer = { IR_INITIALIZER_NULL };

ir_initializer_t *get_initializer_null(void)
{
	return &null_initializer;
}

ir_initializer_t *create_initializer_const(ir_node *value)
{
	struct obstack *obst = get_irg_obstack(get_const_code_irg());

	ir_initializer_t *initializer
592
		= (ir_initializer_t*)OALLOC(obst, ir_initializer_const_t);
593
594
595
596
597
598
	initializer->kind         = IR_INITIALIZER_CONST;
	initializer->consti.value = value;

	return initializer;
}

Matthias Braun's avatar
Matthias Braun committed
599
ir_initializer_t *create_initializer_tarval(ir_tarval *tv)
600
601
602
603
{
	struct obstack *obst = get_irg_obstack(get_const_code_irg());

	ir_initializer_t *initializer
604
		= (ir_initializer_t*)OALLOC(obst, ir_initializer_tarval_t);
605
606
607
608
609
610
	initializer->kind         = IR_INITIALIZER_TARVAL;
	initializer->tarval.value = tv;

	return initializer;
}

611
ir_initializer_t *create_initializer_compound(size_t n_entries)
612
613
614
{
	struct obstack *obst = get_irg_obstack(get_const_code_irg());

Matthias Braun's avatar
Matthias Braun committed
615
616
617
	size_t size = sizeof(ir_initializer_compound_t)
	            + n_entries * sizeof(ir_initializer_t*)
	            - sizeof(ir_initializer_t*);
618

619
620
	ir_initializer_t *initializer
		= (ir_initializer_t*)obstack_alloc(obst, size);
621
622
623
	initializer->kind                    = IR_INITIALIZER_COMPOUND;
	initializer->compound.n_initializers = n_entries;

Matthias Braun's avatar
Matthias Braun committed
624
	for (size_t i = 0; i < n_entries; ++i) {
625
626
627
628
629
630
631
632
633
		initializer->compound.initializers[i] = get_initializer_null();
	}

	return initializer;
}

ir_node *get_initializer_const_value(const ir_initializer_t *initializer)
{
	assert(initializer->kind == IR_INITIALIZER_CONST);
634
	return skip_Id(initializer->consti.value);
635
636
}

Matthias Braun's avatar
Matthias Braun committed
637
ir_tarval *get_initializer_tarval_value(const ir_initializer_t *initializer)
638
639
640
641
642
{
	assert(initializer->kind == IR_INITIALIZER_TARVAL);
	return initializer->tarval.value;
}

643
size_t get_initializer_compound_n_entries(const ir_initializer_t *initializer)
644
645
646
647
648
649
{
	assert(initializer->kind == IR_INITIALIZER_COMPOUND);
	return initializer->compound.n_initializers;
}

void set_initializer_compound_value(ir_initializer_t *initializer,
650
                                    size_t index, ir_initializer_t *value)
651
652
653
654
655
656
657
658
{
	assert(initializer->kind == IR_INITIALIZER_COMPOUND);
	assert(index < initializer->compound.n_initializers);

	initializer->compound.initializers[index] = value;
}

ir_initializer_t *get_initializer_compound_value(
659
		const ir_initializer_t *initializer, size_t index)
660
661
662
663
664
665
666
667
668
669
670
671
672
673
{
	assert(initializer->kind == IR_INITIALIZER_COMPOUND);
	assert(index < initializer->compound.n_initializers);

	return initializer->compound.initializers[index];
}

ir_initializer_kind_t get_initializer_kind(const ir_initializer_t *initializer)
{
	return initializer->kind;
}

static void check_entity_initializer(ir_entity *entity)
{
Matthias Braun's avatar
Matthias Braun committed
674
675
#ifndef NDEBUG
	ir_initializer_t *initializer = entity->initializer;
676
	ir_type          *entity_tp   = get_entity_type(entity);
Matthias Braun's avatar
Matthias Braun committed
677
678
	switch (initializer->kind) {
	case IR_INITIALIZER_COMPOUND:
679
		assert(is_compound_type(entity_tp) || is_Array_type(entity_tp));
Matthias Braun's avatar
Matthias Braun committed
680
681
		break;
	case IR_INITIALIZER_CONST:
682
683
684
		/* methods are initialized by a SymConst */
		assert(is_atomic_type(entity_tp) || is_Method_type(entity_tp));
		break;
Matthias Braun's avatar
Matthias Braun committed
685
	case IR_INITIALIZER_TARVAL:
686
		assert(is_atomic_type(entity_tp));
Matthias Braun's avatar
Matthias Braun committed
687
688
689
690
		break;
	case IR_INITIALIZER_NULL:
		break;
	}
yb9976's avatar
yb9976 committed
691
692
#else
	(void)entity;
Matthias Braun's avatar
Matthias Braun committed
693
#endif
694
695
696
697
}

void set_entity_initializer(ir_entity *entity, ir_initializer_t *initializer)
{
Matthias Braun's avatar
Matthias Braun committed
698
	entity->initializer = initializer;
699
700
701
	check_entity_initializer(entity);
}

702
703
int has_entity_initializer(const ir_entity *entity)
{
Matthias Braun's avatar
Matthias Braun committed
704
	return entity->initializer != NULL;
705
706
}

707
708
ir_initializer_t *get_entity_initializer(const ir_entity *entity)
{
Matthias Braun's avatar
Matthias Braun committed
709
	return entity->initializer;
710
711
}

712
713
int (get_entity_offset)(const ir_entity *ent)
{
714
	return _get_entity_offset(ent);
715
}
Michael Beck's avatar
Michael Beck committed
716

717
718
void (set_entity_offset)(ir_entity *ent, int offset)
{
719
	_set_entity_offset(ent, offset);
720
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
721

722
723
unsigned char (get_entity_offset_bits_remainder)(const ir_entity *ent)
{
724
	return _get_entity_offset_bits_remainder(ent);
725
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
726

727
728
void (set_entity_offset_bits_remainder)(ir_entity *ent, unsigned char offset)
{
729
	_set_entity_offset_bits_remainder(ent, offset);
730
}
Michael Beck's avatar
Michael Beck committed
731

732
733
void add_entity_overwrites(ir_entity *ent, ir_entity *overwritten)
{
734
735
736
	if (ent->overwrites == NULL) {
		ent->overwrites = NEW_ARR_F(ir_entity*, 0);
	}
737
	ARR_APP1(ir_entity *, ent->overwrites, overwritten);
738
739
740
	if (overwritten->overwrittenby == NULL) {
		overwritten->overwrittenby = NEW_ARR_F(ir_entity*, 0);
	}
741
	ARR_APP1(ir_entity *, overwritten->overwrittenby, ent);
742
}
743

744
size_t get_entity_n_overwrites(const ir_entity *ent)
745
{
746
747
748
	if (ent->overwrites == NULL)
		return 0;
	return ARR_LEN(ent->overwrites);
749
}
750

751
size_t get_entity_overwrites_index(const ir_entity *ent, ir_entity *overwritten)
752
{
Matthias Braun's avatar
Matthias Braun committed
753
	for (size_t i = 0, n = get_entity_n_overwrites(ent); i < n; ++i) {
754
755
		if (get_entity_overwrites(ent, i) == overwritten)
			return i;
756
	}
757
	return (size_t)-1;
758
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
759

760
ir_entity *get_entity_overwrites(const ir_entity *ent, size_t pos)
761
{
762
763
	assert(pos < get_entity_n_overwrites(ent));
	return ent->overwrites[pos];
764
}
765

766
void set_entity_overwrites(ir_entity *ent, size_t pos, ir_entity *overwritten)
767
{
768
769
	assert(pos < get_entity_n_overwrites(ent));
	ent->overwrites[pos] = overwritten;
770
}
771

772
773
void remove_entity_overwrites(ir_entity *ent, ir_entity *overwritten)
{
Matthias Braun's avatar
Matthias Braun committed
774
	for (size_t i = 0, n = get_entity_n_overwrites(ent); i < n; ++i) {
775
		if (ent->overwrites[i] == overwritten) {
776
			for (; i < n - 1; i++)
777
				ent->overwrites[i] = ent->overwrites[i+1];
778
			ARR_SETLEN(ir_entity*, ent->overwrites, n - 1);
779
780
			break;
		}
781
	}
782
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
783

784

785
size_t get_entity_n_overwrittenby(const ir_entity *ent)
786
{
787
788
	if (ent->overwrittenby == NULL)
		return 0;
789
	return ARR_LEN(ent->overwrittenby);
790
}
791

792
793
size_t get_entity_overwrittenby_index(const ir_entity *ent,
                                      ir_entity *overwrites)
794
{
Matthias Braun's avatar
Matthias Braun committed
795
	for (size_t i = 0, n = get_entity_n_overwrittenby(ent); i < n; ++i) {
796
797
		if (get_entity_overwrittenby(ent, i) == overwrites)
			return i;
798
	}
799
	return (size_t)-1;
800
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
801

802
ir_entity *get_entity_overwrittenby(const ir_entity *ent, size_t pos)
803
{
804
805
	assert(pos < get_entity_n_overwrittenby(ent));
	return ent->overwrittenby[pos];
806
}
807

808
void set_entity_overwrittenby(ir_entity *ent, size_t pos, ir_entity *overwrites)
809
{
810
811
	assert(pos < get_entity_n_overwrittenby(ent));
	ent->overwrittenby[pos] = overwrites;
812
}
813

814
815
void remove_entity_overwrittenby(ir_entity *ent, ir_entity *overwrites)
{
Matthias Braun's avatar
Matthias Braun committed
816
	for (size_t i = 0, n = get_entity_n_overwrittenby(ent); i < n; ++i) {
817
		if (ent->overwrittenby[i] == overwrites) {
818
			for (; i < n - 1; ++i)
819
				ent->overwrittenby[i] = ent->overwrittenby[i+1];
820
			ARR_SETLEN(ir_entity*, ent->overwrittenby, n - 1);
821
822
			break;
		}
823
	}
824
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
825

826
827
void *(get_entity_link)(const ir_entity *ent)
{
828
	return _get_entity_link(ent);
829
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
830

831
832
void (set_entity_link)(ir_entity *ent, void *l)
{
833
	_set_entity_link(ent, l);
834
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
835

836
837
ir_graph *(get_entity_irg)(const ir_entity *ent)
{
838
	return _get_entity_irg(ent);
839
}
Christian Schäfer's avatar
Christian Schäfer committed
840

841
842
void set_entity_irg(ir_entity *ent, ir_graph *irg)
{
843
	assert(is_method_entity(ent));
Matthias Braun's avatar
Matthias Braun committed
844
	assert(get_entity_peculiarity(ent) == peculiarity_existent);
845
	ent->attr.mtd_attr.irg = irg;
846
}
847

848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
int (is_parameter_entity)(const ir_entity *entity)
{
	return _is_parameter_entity(entity);
}

size_t (get_entity_parameter_number)(const ir_entity *entity)
{
	return _get_entity_parameter_number(entity);
}

void set_entity_parameter_number(ir_entity *entity, size_t n)
{
	assert(is_parameter_entity(entity));
	entity->attr.parameter.number = n;
}

864
865
unsigned get_entity_vtable_number(const ir_entity *ent)
{
866
867
	assert(is_method_entity((ir_entity *)ent));
	return ent->attr.mtd_attr.vtable_number;
868
}
869

870
871
void set_entity_vtable_number(ir_entity *ent, unsigned vtable_number)
{
872
873
	assert(is_method_entity(ent));
	ent->attr.mtd_attr.vtable_number = vtable_number;
874
}
875

876
877
878
879
880
int is_unknown_entity(const ir_entity *entity)
{
	return entity->entity_kind == IR_ENTITY_UNKNOWN;
}

881
882
int (is_entity)(const void *thing)