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

Michael Beck's avatar
Michael Beck committed
20
21
22
23
24
/**
 * @file
 * @brief   Representation of all program known entities.
 * @author  Martin Trapp, Christian Schaefer, Goetz Lindenmaier, Michael Beck
 * @version $Id$
25
 */
Matthias Braun's avatar
Matthias Braun committed
26
#include "config.h"
Boris Boesler's avatar
Boris Boesler committed
27

28
29
30
#include <string.h>
#include <stdlib.h>
#include <stddef.h>
31

Michael Beck's avatar
Michael Beck committed
32
33
34
35
36
37
#include "xmalloc.h"
#include "entity_t.h"
#include "array.h"
#include "irtools.h"
#include "irhooks.h"
#include "irprintf.h"
38

Michael Beck's avatar
Michael Beck committed
39
40
41
#include "irprog_t.h"
#include "ircons.h"
#include "tv_t.h"
42
43
44
#include "irdump.h"
#include "irgraph_t.h"
#include "callgraph.h"
45
#include "error.h"
Matthias Braun's avatar
Matthias Braun committed
46
#include "compound_path.h"
Götz Lindenmaier's avatar
Götz Lindenmaier committed
47

48
/*-----------------------------------------------------------------*/
Christian Schäfer's avatar
Christian Schäfer committed
49
/** general                                                       **/
50
/*-----------------------------------------------------------------*/
Christian Schäfer's avatar
Christian Schäfer committed
51

Michael Beck's avatar
Michael Beck committed
52
ir_entity *unknown_entity = NULL;
53

Michael Beck's avatar
Michael Beck committed
54
ir_entity *get_unknown_entity(void) { return unknown_entity; }
Christian Schäfer's avatar
Christian Schäfer committed
55

56
/** The name of the unknown entity. */
57
#define UNKNOWN_ENTITY_NAME "unknown_entity"
58

59
60
61
/*-----------------------------------------------------------------*/
/* ENTITY                                                          */
/*-----------------------------------------------------------------*/
62

63
64
ir_entity *new_d_entity(ir_type *owner, ident *name, ir_type *type,
                        dbg_info *db)
Christian Schäfer's avatar
Christian Schäfer committed
65
{
66
67
68
69
	ir_entity *res;

	assert(!id_contains_char(name, ' ') && "entity name should not contain spaces");

70
	res = XMALLOCZ(ir_entity);
71
72
73
74
75
76
77
78

	res->kind    = k_entity;
	res->name    = name;
	res->ld_name = NULL;
	res->type    = type;
	res->owner   = owner;

	res->volatility           = volatility_non_volatile;
Matthias Braun's avatar
Matthias Braun committed
79
	res->aligned              = align_is_aligned;
80
	res->usage                = ir_usage_unknown;
81
	res->compiler_gen         = 0;
82
	res->visibility           = ir_visibility_default;
83
84
	res->offset               = -1;
	res->offset_bit_remainder = 0;
Matthias Braun's avatar
Matthias Braun committed
85
	res->alignment            = 0;
86
87
88
89
	res->link                 = NULL;
	res->repr_class           = NULL;

	if (is_Method_type(type)) {
90
		ir_graph *irg = get_const_code_irg();
91
		symconst_symbol sym;
92
		ir_mode *mode = is_Method_type(type) ? mode_P_code : mode_P_data;
93
		sym.entity_p            = res;
94
		set_atomic_ent_value(res, new_r_SymConst(irg, mode, sym, symconst_addr_ent));
Matthias Braun's avatar
Matthias Braun committed
95
		res->linkage            = IR_LINKAGE_CONSTANT;
96
		res->attr.mtd_attr.irg_add_properties = mtp_property_inherited;
97
		res->attr.mtd_attr.vtable_number      = IR_VTABLE_NUM_NOT_SET;
98
99
100
101
102
103
		res->attr.mtd_attr.param_access       = NULL;
		res->attr.mtd_attr.param_weight       = NULL;
		res->attr.mtd_attr.irg                = NULL;
	} else if (is_compound_type(type)) {
		res->attr.cmpd_attr.values    = NULL;
		res->attr.cmpd_attr.val_paths = NULL;
104
105
	} else if (is_code_type(type)) {
		res->attr.code_attr.label = (ir_label_t) -1;
106
107
	}

108
	/* Remember entity in its owner. */
109
110
111
	if (owner != NULL)
		add_compound_member(owner, res);

112
#ifdef DEBUG_libfirm
113
	res->nr = get_irp_new_node_nr();
114
#endif
115

116
117
	res->visit = 0;
	set_entity_dbg_info(res, db);
Christian Schäfer's avatar
Christian Schäfer committed
118

119
	hook_new_entity(res);
120

121
	return res;
122
}
123

124
ir_entity *new_entity(ir_type *owner, ident *name, ir_type *type)
125
{
126
	return new_d_entity(owner, name, type, NULL);
127
}
128

129
130
131
132
133
/**
 * Free entity attributes.
 *
 * @param ent  the entity
 */
Matthias Braun's avatar
Matthias Braun committed
134
135
static void free_entity_attrs(ir_entity *ent)
{
136
137
138
	if (ent->overwrites != NULL) {
		DEL_ARR_F(ent->overwrites);
		ent->overwrites = NULL;
139
	}
140
141
142
143
144
	if (ent->overwrittenby != NULL) {
		DEL_ARR_F(ent->overwrittenby);
		ent->overwrittenby = NULL;
	}

Matthias Braun's avatar
Matthias Braun committed
145
146
147
	if (ent->initializer != NULL) {
		/* TODO: free initializers */
	} else if (entity_has_compound_ent_values(ent)) {
148
149
150
		/* can't free compound graph path as it might be used
		 * multiple times */
		ent->attr.cmpd_attr.val_paths = NULL;
Matthias Braun's avatar
Matthias Braun committed
151
	}
152
	if (is_compound_entity(ent)) {
Matthias Braun's avatar
Matthias Braun committed
153
		ent->attr.cmpd_attr.values = NULL;
154
155
156
157
158
159
160
161
162
163
	} else if (is_method_entity(ent)) {
		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;
		}
	}
164
}
Christian Schäfer's avatar
Christian Schäfer committed
165

166
167
168
169
170
171
172
/**
 * Creates a deep copy of an entity.
 */
static ir_entity *deep_entity_copy(ir_entity *old)
{
	ir_entity *newe = XMALLOC(ir_entity);

173
	*newe = *old;
Matthias Braun's avatar
Matthias Braun committed
174
175
176
177
178
179
180
181
182
183
184
	if (old->initializer != NULL) {
		/* FIXME: the initializers are NOT copied */
	} else if (entity_has_compound_ent_values(old)) {
		newe->attr.cmpd_attr.values    = NULL;
		newe->attr.cmpd_attr.val_paths = NULL;
		if (old->attr.cmpd_attr.values)
			newe->attr.cmpd_attr.values = DUP_ARR_F(ir_node *, old->attr.cmpd_attr.values);

		/* FIXME: the compound graph paths are NOT copied */
		if (old->attr.cmpd_attr.val_paths)
			newe->attr.cmpd_attr.val_paths = DUP_ARR_F(compound_graph_path *, old->attr.cmpd_attr.val_paths);
185
186
187
188
189
	} 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;
	}
190
191
	newe->overwrites    = NULL;
	newe->overwrittenby = NULL;
192
193
194
195

#ifdef DEBUG_libfirm
	newe->nr = get_irp_new_node_nr();
#endif
196
	hook_new_entity(newe);
197
198
	return newe;
}
199

Michael Beck's avatar
Michael Beck committed
200
201
202
203
/*
 * Copies the entity if the new_owner is different from the
 * owner of the old entity,  else returns the old entity.
 */
204
ir_entity *copy_entity_own(ir_entity *old, ir_type *new_owner)
205
{
206
207
208
	ir_entity *newe;
	assert(is_entity(old));
	assert(is_compound_type(new_owner));
209
	assert(get_type_state(new_owner) != layout_fixed);
210

211
212
213
214
	if (old->owner == new_owner)
		return old;

	/* create a deep copy so we are safe of aliasing and double-freeing. */
215
	newe        = deep_entity_copy(old);
216
	newe->owner = new_owner;
217
	add_compound_member(new_owner, newe);
218

219
	return newe;
220
}
221

222
ir_entity *copy_entity_name(ir_entity *old, ident *new_name)
223
{
224
225
226
	ir_entity *newe;
	assert(old && old->kind == k_entity);

227
228
229
	if (old->name == new_name)
		return old;

230
	newe       = deep_entity_copy(old);
231
232
	newe->name = new_name;
	newe->ld_name = NULL;
233
	add_compound_member(old->owner, newe);
234

235
	return newe;
236
}
237

238
void free_entity(ir_entity *ent)
239
{
240
	if (ent->owner != NULL && !is_Array_type(ent->owner))
241
		remove_compound_member(ent->owner, ent);
242

243
244
245
	assert(ent && ent->kind == k_entity);
	free_entity_attrs(ent);
	ent->kind = k_BAD;
246
	xfree(ent);
247
}
248

249
/* Outputs a unique number for this node */
250
long get_entity_nr(const ir_entity *ent)
251
{
252
	assert(ent && ent->kind == k_entity);
253
#ifdef DEBUG_libfirm
254
	return ent->nr;
255
#else
256
	return (long)PTR_TO_INT(ent);
257
#endif
258
}
259

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

265
266
ident *(get_entity_ident)(const ir_entity *ent)
{
267
	return _get_entity_ident(ent);
Matthias Braun's avatar
Matthias Braun committed
268
}
Michael Beck's avatar
Michael Beck committed
269

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

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

280
void set_entity_owner(ir_entity *ent, ir_type *owner)
281
{
282
283
	assert(is_entity(ent));
	assert(is_compound_type(owner));
284
285
286

	remove_compound_member(ent->owner, ent);
	add_compound_member(owner, ent);
287
	ent->owner = owner;
Matthias Braun's avatar
Matthias Braun committed
288
}
Christian Schäfer's avatar
Christian Schäfer committed
289

Matthias Braun's avatar
Matthias Braun committed
290
291
ident *(get_entity_ld_ident)(const ir_entity *ent)
{
292
	return _get_entity_ld_ident(ent);
Matthias Braun's avatar
Matthias Braun committed
293
}
294

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

Matthias Braun's avatar
Matthias Braun committed
300
301
const char *(get_entity_ld_name)(const ir_entity *ent)
{
302
	return _get_entity_ld_name(ent);
Matthias Braun's avatar
Matthias Braun committed
303
}
304

305
306
307
308
309
int entity_has_ld_ident(const ir_entity *entity)
{
	return entity->ld_name != NULL;
}

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

315
316
void (set_entity_type)(ir_entity *ent, ir_type *type)
{
317
	_set_entity_type(ent, type);
Matthias Braun's avatar
Matthias Braun committed
318
}
Götz Lindenmaier's avatar
a    
Götz Lindenmaier committed
319

320
321
ir_volatility (get_entity_volatility)(const ir_entity *ent)
{
322
	return _get_entity_volatility(ent);
Matthias Braun's avatar
Matthias Braun committed
323
}
Götz Lindenmaier's avatar
a    
Götz Lindenmaier committed
324

325
326
void (set_entity_volatility)(ir_entity *ent, ir_volatility vol)
{
327
	_set_entity_volatility(ent, vol);
Matthias Braun's avatar
Matthias Braun committed
328
}
Götz Lindenmaier's avatar
a    
Götz Lindenmaier committed
329

Michael Beck's avatar
Michael Beck committed
330
/* Return the name of the volatility. */
331
const char *get_volatility_name(ir_volatility var)
332
{
333
#define X(a)    case a: return #a
334
335
336
	switch (var) {
	X(volatility_non_volatile);
	X(volatility_is_volatile);
337
    default: return "BAD VALUE";
338
	}
339
#undef X
340
}
341

342
343
ir_align (get_entity_aligned)(const ir_entity *ent)
{
Matthias Braun's avatar
Matthias Braun committed
344
345
	return _get_entity_aligned(ent);
}
346

347
348
void (set_entity_aligned)(ir_entity *ent, ir_align a)
{
Matthias Braun's avatar
Matthias Braun committed
349
350
	_set_entity_aligned(ent, a);
}
351

352
353
unsigned (get_entity_alignment)(const ir_entity *ent)
{
354
355
356
	return _get_entity_alignment(ent);
}

357
358
void (set_entity_alignment)(ir_entity *ent, unsigned alignment)
{
359
360
361
	_set_entity_alignment(ent, alignment);
}

Michael Beck's avatar
Michael Beck committed
362
363
364
365
366
367
368
/* Return the name of the alignment. */
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);
369
	default: return "BAD VALUE";
Michael Beck's avatar
Michael Beck committed
370
371
	}
#undef X
372
}
Michael Beck's avatar
Michael Beck committed
373

374
void set_entity_label(ir_entity *ent, ir_label_t label)
375
376
377
378
379
380
381
382
383
{
	ent->attr.code_attr.label = label;
}

ir_label_t get_entity_label(const ir_entity *ent)
{
	return ent->attr.code_attr.label;
}

384
static void verify_visibility(const ir_entity *entity)
Matthias Braun's avatar
Matthias Braun committed
385
{
386
387
	if (get_entity_visibility(entity) == ir_visibility_external
			&& !is_method_entity(entity)) {
388
389
		assert(!entity_has_definition(entity));
	}
390
391
392
393
394
395
396
397
398
399
}

void set_entity_visibility(ir_entity *entity, ir_visibility visibility)
{
	entity->visibility = visibility;
	verify_visibility(entity);
}

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

Matthias Braun's avatar
Matthias Braun committed
403
404
405
406
407
408
409
410
411
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);
}
412

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

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

423
/* Checks if an entity is compiler generated */
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

/* Sets/resets the compiler generated flag */
430
431
void (set_entity_compiler_generated)(ir_entity *ent, int flag)
{
Michael Beck's avatar
Michael Beck committed
432
	_set_entity_compiler_generated(ent, flag);
433
}
434

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

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

Matthias Braun's avatar
Matthias Braun committed
445
446
447
448
/* Set has no effect for existent entities of type method. */
ir_node *get_atomic_ent_value(ir_entity *entity)
{
	ir_initializer_t *initializer = get_entity_initializer(entity);
449

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

Matthias Braun's avatar
Matthias Braun committed
456
457
458
459
460
461
462
	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
463
		ir_tarval *tv = get_initializer_tarval_value(initializer);
Matthias Braun's avatar
Matthias Braun committed
464
465
466
467
468
469
470
471
472
473
474
475
		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);
	}

	panic("invalid initializer kind in get_atomic_ent_value(%+F)", entity);
}

void set_atomic_ent_value(ir_entity *entity, ir_node *val)
476
{
Matthias Braun's avatar
Matthias Braun committed
477
	ir_initializer_t *initializer;
478

Matthias Braun's avatar
Matthias Braun committed
479
480
481
482
483
484
	assert(is_atomic_entity(entity));

	assert(is_Dummy(val) || get_irn_mode(val) == get_type_mode(entity->type));
	initializer = create_initializer_const(val);
	entity->initializer = initializer;
}
485

Matthias Heil's avatar
Matthias Heil committed
486
487
/* Returns true if the the node is representable as code on
 *  const_code_irg. */
488
489
int is_irn_const_expression(ir_node *n)
{
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
	/* we are in danger iff an exception will arise. TODO: be more precisely,
	 * for instance Div. will NOT rise if divisor != 0
	 */
	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:
	case iro_Cast:
		return is_irn_const_expression(get_irn_n(n, 0));
	default:
		break;
	}
	return 0;
508
}
Matthias Heil's avatar
Matthias Heil committed
509

510
511
/*
 * Copies a firm subgraph that complies to the restrictions for
512
 * constant expressions to block.
513
 */
514
ir_node *copy_const_value(dbg_info *dbg, ir_node *n, ir_node *block)
515
{
516
	ir_graph *irg = get_irn_irg(block);
517
518
519
520
521
522
523
524
525
	ir_node *nn;
	ir_mode *m;

	/* @@@ GL I think  we should implement this using the routines from irgopt for
	       dead node elimination/inlineing. */

	m = get_irn_mode(n);
	switch (get_irn_opcode(n)) {
	case iro_Const:
526
		nn = new_rd_Const(dbg, irg, get_Const_tarval(n));
527
528
		break;
	case iro_SymConst:
529
		nn = new_rd_SymConst(dbg, irg, get_irn_mode(n), get_SymConst_symbol(n), get_SymConst_kind(n));
530
531
		break;
	case iro_Add:
532
533
534
535
		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;
536
	case iro_Sub:
537
538
539
540
		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;
541
	case iro_Mul:
542
543
544
545
		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;
546
	case iro_And:
547
548
549
550
		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;
551
	case iro_Or:
552
553
554
555
		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;
556
	case iro_Eor:
557
558
559
560
		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;
561
	case iro_Cast:
562
563
564
565
		nn = new_rd_Cast(dbg, block,
		                 copy_const_value(dbg, get_Cast_op(n), block),
		                 get_Cast_type(n));
		break;
566
	case iro_Conv:
567
568
569
		nn = new_rd_Conv(dbg, block,
		                 copy_const_value(dbg, get_Conv_op(n), block), m);
		break;
570
	case iro_Unknown:
571
		nn = new_r_Unknown(irg, m); break;
572
	default:
573
		panic("opcode invalid or not implemented");
574
575
	}
	return nn;
576
}
577

578
579
580
581
582
583
584
585
586
587
588
589
590
591
/** Return the name of the initializer kind. */
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);
    default: return "BAD VALUE";
	}
#undef X
}

592
593
594
595
596
597
598
599
600
601
602
603
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
604
		= (ir_initializer_t*)OALLOC(obst, ir_initializer_const_t);
605
606
607
608
609
610
	initializer->kind         = IR_INITIALIZER_CONST;
	initializer->consti.value = value;

	return initializer;
}

Matthias Braun's avatar
Matthias Braun committed
611
ir_initializer_t *create_initializer_tarval(ir_tarval *tv)
612
613
614
615
{
	struct obstack *obst = get_irg_obstack(get_const_code_irg());

	ir_initializer_t *initializer
616
		= (ir_initializer_t*)OALLOC(obst, ir_initializer_tarval_t);
617
618
619
620
621
622
	initializer->kind         = IR_INITIALIZER_TARVAL;
	initializer->tarval.value = tv;

	return initializer;
}

623
ir_initializer_t *create_initializer_compound(size_t n_entries)
624
625
626
627
{
	struct obstack *obst = get_irg_obstack(get_const_code_irg());

	size_t i;
Michael Beck's avatar
Michael Beck committed
628
	size_t size  = sizeof(ir_initializer_compound_t)
629
630
	             + n_entries * sizeof(ir_initializer_t*)
	             - sizeof(ir_initializer_t*);
631

632
633
	ir_initializer_t *initializer
		= (ir_initializer_t*)obstack_alloc(obst, size);
634
635
636
	initializer->kind                    = IR_INITIALIZER_COMPOUND;
	initializer->compound.n_initializers = n_entries;

637
	for (i = 0; i < n_entries; ++i) {
638
639
640
641
642
643
644
645
646
		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);
647
	return skip_Id(initializer->consti.value);
648
649
}

Matthias Braun's avatar
Matthias Braun committed
650
ir_tarval *get_initializer_tarval_value(const ir_initializer_t *initializer)
651
652
653
654
655
{
	assert(initializer->kind == IR_INITIALIZER_TARVAL);
	return initializer->tarval.value;
}

656
size_t get_initializer_compound_n_entries(const ir_initializer_t *initializer)
657
658
659
660
661
662
{
	assert(initializer->kind == IR_INITIALIZER_COMPOUND);
	return initializer->compound.n_initializers;
}

void set_initializer_compound_value(ir_initializer_t *initializer,
663
                                    size_t index, ir_initializer_t *value)
664
665
666
667
668
669
670
671
{
	assert(initializer->kind == IR_INITIALIZER_COMPOUND);
	assert(index < initializer->compound.n_initializers);

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

ir_initializer_t *get_initializer_compound_value(
672
		const ir_initializer_t *initializer, size_t index)
673
674
675
676
677
678
679
680
681
682
683
684
685
686
{
	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
687
688
#ifndef NDEBUG
	ir_initializer_t *initializer = entity->initializer;
689
	ir_type          *entity_tp   = get_entity_type(entity);
Matthias Braun's avatar
Matthias Braun committed
690
691
	switch (initializer->kind) {
	case IR_INITIALIZER_COMPOUND:
692
		assert(is_compound_type(entity_tp) || is_Array_type(entity_tp));
Matthias Braun's avatar
Matthias Braun committed
693
694
		break;
	case IR_INITIALIZER_CONST:
695
696
697
		/* 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
698
	case IR_INITIALIZER_TARVAL:
699
		assert(is_atomic_type(entity_tp));
Matthias Braun's avatar
Matthias Braun committed
700
701
702
703
704
		break;
	case IR_INITIALIZER_NULL:
		break;
	}
#endif
705
706
707
708
}

void set_entity_initializer(ir_entity *entity, ir_initializer_t *initializer)
{
Matthias Braun's avatar
Matthias Braun committed
709
	entity->initializer = initializer;
710
711
712
	check_entity_initializer(entity);
}

713
714
int has_entity_initializer(const ir_entity *entity)
{
Matthias Braun's avatar
Matthias Braun committed
715
	return entity->initializer != NULL;
716
717
}

718
719
ir_initializer_t *get_entity_initializer(const ir_entity *entity)
{
Matthias Braun's avatar
Matthias Braun committed
720
	return entity->initializer;
721
722
}

723
724
int (get_entity_offset)(const ir_entity *ent)
{
725
	return _get_entity_offset(ent);
726
}
Michael Beck's avatar
Michael Beck committed
727

728
729
void (set_entity_offset)(ir_entity *ent, int offset)
{
730
	_set_entity_offset(ent, offset);
731
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
732

733
734
unsigned char (get_entity_offset_bits_remainder)(const ir_entity *ent)
{
735
	return _get_entity_offset_bits_remainder(ent);
736
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
737

738
739
void (set_entity_offset_bits_remainder)(ir_entity *ent, unsigned char offset)
{
740
	_set_entity_offset_bits_remainder(ent, offset);
741
}
Michael Beck's avatar
Michael Beck committed
742

743
744
void add_entity_overwrites(ir_entity *ent, ir_entity *overwritten)
{
745
746
747
	if (ent->overwrites == NULL) {
		ent->overwrites = NEW_ARR_F(ir_entity*, 0);
	}
748
	ARR_APP1(ir_entity *, ent->overwrites, overwritten);
749
750
751
	if (overwritten->overwrittenby == NULL) {
		overwritten->overwrittenby = NEW_ARR_F(ir_entity*, 0);
	}
752
	ARR_APP1(ir_entity *, overwritten->overwrittenby, ent);
753
}
754

755
size_t get_entity_n_overwrites(const ir_entity *ent)
756
{
757
758
759
	if (ent->overwrites == NULL)
		return 0;
	return ARR_LEN(ent->overwrites);
760
}
761

762
size_t get_entity_overwrites_index(const ir_entity *ent, ir_entity *overwritten)
763
{
764
765
	size_t i;
	size_t n = get_entity_n_overwrites(ent);
766
	for (i = 0; i < n; ++i) {
767
768
		if (get_entity_overwrites(ent, i) == overwritten)
			return i;
769
	}
770
	return (size_t)-1;
771
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
772

773
ir_entity *get_entity_overwrites(const ir_entity *ent, size_t pos)
774
{
775
776
	assert(pos < get_entity_n_overwrites(ent));
	return ent->overwrites[pos];
777
}
778

779
void set_entity_overwrites(ir_entity *ent, size_t pos, ir_entity *overwritten)
780
{
781
782
	assert(pos < get_entity_n_overwrites(ent));
	ent->overwrites[pos] = overwritten;
783
}
784

785
786
void remove_entity_overwrites(ir_entity *ent, ir_entity *overwritten)
{
787
788
	size_t i;
	size_t n = get_entity_n_overwrites(ent);
789
	for (i = 0; i < n; ++i) {
790
		if (ent->overwrites[i] == overwritten) {
791
			for (; i < n - 1; i++)
792
				ent->overwrites[i] = ent->overwrites[i+1];
793
			ARR_SETLEN(ir_entity*, ent->overwrites, n - 1);
794
795
			break;
		}
796
	}
797
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
798

799

800
size_t get_entity_n_overwrittenby(const ir_entity *ent)
801
{
802
803
	if (ent->overwrittenby == NULL)
		return 0;
804
	return ARR_LEN(ent->overwrittenby);
805
}
806

807
808
size_t get_entity_overwrittenby_index(const ir_entity *ent,
                                      ir_entity *overwrites)
809
{
810
811
	size_t i;
	size_t n = get_entity_n_overwrittenby(ent);
812
	for (i = 0; i < n; ++i) {
813
814
		if (get_entity_overwrittenby(ent, i) == overwrites)
			return i;
815
	}
816
	return (size_t)-1;
817
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
818

819
ir_entity *get_entity_overwrittenby(const ir_entity *ent, size_t pos)
820
{
821
822
	assert(pos < get_entity_n_overwrittenby(ent));
	return ent->overwrittenby[pos];
823
}
824

825
void set_entity_overwrittenby(ir_entity *ent, size_t pos, ir_entity *overwrites)
826
{
827
828
	assert(pos < get_entity_n_overwrittenby(ent));
	ent->overwrittenby[pos] = overwrites;
829
}
830

831
832
void remove_entity_overwrittenby(ir_entity *ent, ir_entity *overwrites)
{
833
834
	size_t i;
	size_t n = get_entity_n_overwrittenby(ent);
835
	for (i = 0; i < n; ++i) {
836
		if (ent->overwrittenby[i] == overwrites) {
837
			for (; i < n - 1; ++i)
838
				ent->overwrittenby[i] = ent->overwrittenby[i+1];
839
			ARR_SETLEN(ir_entity*, ent->overwrittenby, n - 1);
840
841
			break;
		}
842
	}
843
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
844

845
846
void *(get_entity_link)(const ir_entity *ent)
{
847
	return _get_entity_link(ent);
848
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
849

850
851
void (set_entity_link)(ir_entity *ent, void *l)
{
852
	_set_entity_link(ent, l);
853
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
854

855
856
ir_graph *(get_entity_irg)(const ir_entity *ent)
{
857
	return _get_entity_irg(ent);
858
}
Christian Schäfer's avatar
Christian Schäfer committed
859

860
861
void set_entity_irg(ir_entity *ent, ir_graph *irg)
{
862
	assert(is_method_entity(ent));
Matthias Braun's avatar
Matthias Braun committed
863
	assert(get_entity_peculiarity(ent) == peculiarity_existent);
864
	ent->attr.mtd_attr.irg = irg;
865
}
866

867
868
unsigned get_entity_vtable_number(const ir_entity *ent)
{
869
870
	assert(is_method_entity((ir_entity *)ent));
	return ent->attr.mtd_attr.vtable_number;
871
}
872

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