type_t.h 11.2 KB
Newer Older
Christian Würdig's avatar
Christian Würdig committed
1
2
/*
 * This file is part of libFirm.
3
 * Copyright (C) 2012 University of Karlsruhe.
Christian Würdig's avatar
Christian Würdig committed
4
5
 */

Michael Beck's avatar
Michael Beck committed
6
/**
Matthias Braun's avatar
Matthias Braun committed
7
 * @file
Michael Beck's avatar
Michael Beck committed
8
9
 * @brief   Representation of types -- private header.
 * @author  Goetz Lindenmaier, Michael Beck
10
 * @see     type.h
Michael Beck's avatar
Michael Beck committed
11
 */
Michael Beck's avatar
Michael Beck committed
12
13
#ifndef FIRM_TR_TYPE_T_H
#define FIRM_TR_TYPE_T_H
14

15
#include <stdbool.h>
16

17
#include "array.h"
Matthias Braun's avatar
Matthias Braun committed
18
19
#include "firm_common.h"
#include "typerep.h"
Götz Lindenmaier's avatar
Götz Lindenmaier committed
20

21
22
23
#define get_master_type_visited()         get_master_type_visited_()
#define get_type_link(tp)                 get_type_link_(tp)
#define set_type_link(tp, l)              set_type_link_(tp, l)
24
#define get_type_opcode(tp)               get_type_opcode_(tp)
25
#define get_type_mode(tp)                 get_type_mode_(tp)
26
27
#define get_type_alignment(tp)            get_type_alignment_(tp)
#define get_type_size(tp)                 get_type_size_(tp)
28
29
30
31
32
33
34
#define get_type_state(tp)                get_type_state_(tp)
#define get_type_visited(tp)              get_type_visited_(tp)
#define set_type_visited(tp, num)         set_type_visited_(tp, num)
#define mark_type_visited(tp)             mark_type_visited_(tp)
#define type_visited(tp)                  type_visited_(tp)
#define get_type_dbg_info(tp)             get_type_dbg_info_(tp)
#define set_type_dbg_info(tp, db)         set_type_dbg_info_(tp, db)
Matthias Braun's avatar
Matthias Braun committed
35
36
#define get_compound_n_members(type)      get_compound_n_members_(type)
#define get_compound_member(type, pos)    get_compound_member_(type, pos)
37
38
39
40
#define is_Class_type(clss)               is_class_type_(clss)
#define is_Struct_type(strct)             is_struct_type_(strct)
#define is_Method_type(method)            is_method_type_(method)
#define is_Union_type(uni)                is_union_type_(uni)
41
#define is_segment_type(type)             is_segment_type_(type)
42
43
44
45
46
47
#define is_Array_type(array)              is_array_type_(array)
#define is_Pointer_type(pointer)          is_pointer_type_(pointer)
#define is_Primitive_type(primitive)      is_primitive_type_(primitive)
#define is_atomic_type(tp)                is_atomic_type_(tp)
#define get_method_n_params(method)       get_method_n_params_(method)
#define get_method_n_ress(method)         get_method_n_ress_(method)
48
49
#define get_method_additional_properties(method) get_method_additional_properties_(method)
#define get_method_calling_convention(method)    get_method_calling_convention_(method)
50

51
52
53
54
55
/** Compound type attributes. */
typedef struct {
	ir_entity **members;
} compound_attr;

56
/** Class type attributes. */
Götz Lindenmaier's avatar
new.    
Götz Lindenmaier committed
57
typedef struct {
58
59
60
	compound_attr base;
	ir_type     **subtypes;   /**< Array containing the direct subtypes. */
	ir_type     **supertypes; /**< Array containing the direct supertypes */
61
} class_attr;
Götz Lindenmaier's avatar
new.    
Götz Lindenmaier committed
62

63
/** Method type attributes. */
Götz Lindenmaier's avatar
new.    
Götz Lindenmaier committed
64
typedef struct {
65
66
67
68
	size_t                    n_params;         /**< Number of parameters. */
	ir_type                 **params;           /**< Array of parameter types. */
	size_t                    n_res;            /**< Number of results. */
	ir_type                 **res_type;         /**< Array of result types. */
69
	bool                      variadic;         /**< The variadicity of the method. */
70
71
	mtp_additional_properties properties;       /**< Set of additional method properties. */
	unsigned                  irg_calling_conv; /**< A set of calling convention flags. */
72
} method_attr;
Götz Lindenmaier's avatar
new.    
Götz Lindenmaier committed
73

74
/** Array type attributes. */
Götz Lindenmaier's avatar
new.    
Götz Lindenmaier committed
75
typedef struct {
Christoph Mallon's avatar
Christoph Mallon committed
76
	unsigned size;         /**< number of elements in the array. */
Matthias Braun's avatar
cleanup    
Matthias Braun committed
77
	ir_type *element_type; /**< The type of the array elements. */
78
} array_attr;
Götz Lindenmaier's avatar
new.    
Götz Lindenmaier committed
79

80
/** Pointer type attributes. */
Götz Lindenmaier's avatar
new.    
Götz Lindenmaier committed
81
typedef struct {
Michael Beck's avatar
Michael Beck committed
82
	ir_type *points_to;  /**< The type of the ir_entity the pointer points to. */
83
} pointer_attr;
Götz Lindenmaier's avatar
new.    
Götz Lindenmaier committed
84

85
/** Additional type flags. */
86
typedef enum type_flags {
Matthias Braun's avatar
cleanup    
Matthias Braun committed
87
	tf_none          = 0,       /**< No flags. */
88
89
90
	tf_compound      = 1U << 0, /**< Set if type is a compound type. */
	tf_lowered_type  = 1U << 1, /**< Set if this is a lowered type. */
	tf_layout_fixed  = 1U << 2, /**< Set if the layout of a type is fixed */
Matthias Braun's avatar
cleanup    
Matthias Braun committed
91

92
	tf_frame_type    = 1U << 3, /**< Set if this is a frame type. */
93
	tf_info          = 1U << 4, /**< infos (for example constructor, destructor pointers), all members are anonymous */
Christoph Mallon's avatar
Christoph Mallon committed
94
	tf_lowered_dw    = 1U << 5, /**< hack to identify lowered doubleword params */
95
} type_flags;
96
ENUM_BITSET(type_flags)
97

98
99
100
101
102
103
104
105
106
107
108
109
110
111
/**
 *  An abstract data type to represent types.
 *
 *  This is the abstract data type with which any type known in the
 *  compiled program can be represented.  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.  These are distinguished by a type opcode.
 *  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.
 */
112
struct ir_type {
Michael Beck's avatar
Michael Beck committed
113
	firm_kind kind;          /**< the firm kind, must be k_type */
114
	tp_opcode opcode;
Michael Beck's avatar
Michael Beck committed
115
116
	ident *name;             /**< The name of the type */
	unsigned flags;          /**< Type flags, a bitmask of enum type_flags. */
117
118
119
120
121
122
123
	unsigned size;           /**< Size of an ir_entity of this type. This is
	                              determined when fixing the layout of this
	                              class.  Size must be given in bytes. */
	unsigned align;          /**< Alignment of an ir_entity of this type. This
	                              should be set according to the source
	                              language needs. If not set, it's calculated
	                              automatically by get_type_alignment().
124
	                              Alignment must be given in bytes. */
Michael Beck's avatar
Michael Beck committed
125
	ir_mode *mode;           /**< The mode for atomic types */
126
	ir_visited_t visit;      /**< visited counter for walks of the type information */
Michael Beck's avatar
Michael Beck committed
127
	void *link;              /**< holds temporary data - like in irnode_t.h */
128
	type_dbg_info *dbi;      /**< A pointer to information for debug support. */
129
130
	ir_type *higher_type;    /**< link to highlevel type in case of lowered
	                              types */
131
	long nr;                 /**< An unique number for each type. */
132
133
134
135
136
137
138
	union {
		compound_attr compound;
		class_attr    cls;
		method_attr   method;
		array_attr    array;
		pointer_attr  pointer;
	} attr;
Götz Lindenmaier's avatar
new.    
Götz Lindenmaier committed
139
140
};

141
void free_type_entities(ir_type *tp);
142

143
void free_compound_attrs(ir_type *type);
Michael Beck's avatar
Michael Beck committed
144

Matthias Braun's avatar
cleanup    
Matthias Braun committed
145
146
void free_class_attrs(ir_type *clss);
void free_method_attrs(ir_type *method);
Michael Beck's avatar
Michael Beck committed
147

148
149
void add_compound_member(ir_type *compound, ir_entity *entity);

150
/** Initialize the type module. */
151
void ir_init_type(ir_prog *irp);
152

153
/** free internal data structures of type module */
154
void ir_finish_type(ir_prog *irp);
155

156
157
/** Clone an existing method type.
 *
158
159
160
 * @param tp             the method type to clone.
 * @param is_variadic    whether the cloned type is variadic
 * @param property_mask  additional method properties for the cloned type
161
162
163
 *
 * @return the cloned method type.
 */
164
ir_type *clone_type_method(ir_type *tp, bool is_variadic, mtp_additional_properties property_mask);
165

166
extern ir_visited_t firm_type_visited;
167

168
static inline ir_visited_t get_master_type_visited_(void)
169
170
171
172
{
	return firm_type_visited;
}

173
174
175
176
177
static inline int is_lowered_type(const ir_type *tp)
{
	return tp->flags & tf_lowered_type;
}

178
static inline ir_type *get_higher_type(const ir_type *tp)
179
{
180
	return tp->higher_type;
181
182
}

183
static inline void set_higher_type(ir_type *tp, ir_type *higher_type)
184
{
185
186
	tp->flags |= tf_lowered_type;
	tp->higher_type = higher_type;
187
}
188

189
static inline void *get_type_link_(const ir_type *tp)
190
{
191
	assert(tp->kind == k_type);
Michael Beck's avatar
Michael Beck committed
192
	return(tp -> link);
193
194
}

195
static inline void set_type_link_(ir_type *tp, void *l)
196
{
197
	assert(tp->kind == k_type);
Michael Beck's avatar
Michael Beck committed
198
	tp -> link = l;
199
200
}

201
static inline tp_opcode get_type_opcode_(const ir_type *tp)
202
{
203
	assert(tp->kind == k_type);
204
	return tp->opcode;
205
206
}

207
static inline ir_mode *get_type_mode_(const ir_type *tp)
208
{
209
	assert(tp->kind == k_type);
Michael Beck's avatar
Michael Beck committed
210
	return tp->mode;
211
212
}

213
static inline unsigned get_type_alignment_(const ir_type *type)
214
{
215
	assert(type->kind == k_type);
216
217
218
	return type->align;
}

219
static inline unsigned get_type_size_(const ir_type *tp)
220
{
221
	assert(tp->kind == k_type);
Michael Beck's avatar
Michael Beck committed
222
	return tp->size;
223
224
}

225
static inline ir_type_state get_type_state_(const ir_type *tp)
226
{
227
	assert(tp->kind == k_type);
Michael Beck's avatar
Michael Beck committed
228
	return tp->flags & tf_layout_fixed ? layout_fixed : layout_undefined;
229
230
}

231
static inline ir_visited_t get_type_visited_(const ir_type *tp)
232
{
233
	assert(tp->kind == k_type);
Michael Beck's avatar
Michael Beck committed
234
	return tp->visit;
235
236
}

237
static inline void set_type_visited_(ir_type *tp, ir_visited_t num)
238
{
239
	assert(tp->kind == k_type);
Michael Beck's avatar
Michael Beck committed
240
	tp->visit = num;
241
242
}

243
static inline void mark_type_visited_(ir_type *tp)
244
{
245
	assert(tp->kind == k_type);
Michael Beck's avatar
Michael Beck committed
246
247
	assert(tp->visit < firm_type_visited);
	tp->visit = firm_type_visited;
248
249
}

250
static inline int type_visited_(const ir_type *tp)
251
{
252
	assert(tp->kind == k_type);
Michael Beck's avatar
Michael Beck committed
253
	return tp->visit >= firm_type_visited;
254
255
}

256
static inline type_dbg_info *get_type_dbg_info_(const ir_type *tp)
257
{
258
259
260
	return tp->dbi;
}

261
static inline void set_type_dbg_info_(ir_type *tp, type_dbg_info *db)
262
{
263
264
265
	tp->dbi = db;
}

266
static inline int is_class_type_(const ir_type *type)
267
{
268
	return get_type_opcode(type) == tpo_class;
269
270
}

Matthias Braun's avatar
Matthias Braun committed
271
static inline size_t get_compound_n_members_(const ir_type *type)
272
{
Matthias Braun's avatar
Matthias Braun committed
273
	assert(is_compound_type(type));
274
	return ARR_LEN(type->attr.compound.members);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
275
276
}

Matthias Braun's avatar
Matthias Braun committed
277
278
static inline ir_entity *get_compound_member_(ir_type const *const type,
                                             size_t const pos)
279
{
Matthias Braun's avatar
Matthias Braun committed
280
281
	assert(is_compound_type(type));
	assert(pos < get_compound_n_members(type));
282
	return type->attr.compound.members[pos];
Götz Lindenmaier's avatar
Götz Lindenmaier committed
283
284
}

285
static inline int is_struct_type_(ir_type const *const type)
286
{
287
	return get_type_opcode(type) == tpo_struct;
288
289
}

290
static inline int is_method_type_(ir_type const *const type)
291
{
292
	return get_type_opcode(type) == tpo_method;
293
294
}

295
static inline int is_union_type_(ir_type const *const type)
296
{
297
	return get_type_opcode(type) == tpo_union;
298
299
}

300
301
302
303
304
static inline int is_segment_type_(ir_type const *const type)
{
	return get_type_opcode(type) == tpo_segment;
}

305
static inline int is_array_type_(ir_type const *const type)
306
{
307
	return get_type_opcode(type) == tpo_array;
308
309
}

310
static inline int is_pointer_type_(ir_type const *const type)
311
{
312
	return get_type_opcode(type) == tpo_pointer;
313
314
}

315
static inline int is_primitive_type_(ir_type const *const type)
316
{
317
	return get_type_opcode(type) == tpo_primitive;
318
319
}

320
static inline int is_atomic_type_(ir_type const *const type)
321
{
322
	return is_Primitive_type(type) || is_Pointer_type(type);
323
324
}

325
static inline size_t get_method_n_params_(const ir_type *method)
326
{
327
	assert(is_Method_type(method));
328
	return method->attr.method.n_params;
329
330
}

331
static inline size_t get_method_n_ress_(const ir_type *method)
332
{
333
	assert(is_Method_type(method));
334
	return method->attr.method.n_res;
335
336
}

337
static inline mtp_additional_properties get_method_additional_properties_(const ir_type *method)
338
{
339
	assert(is_Method_type(method));
340
	return method->attr.method.properties;
341
342
}

343
static inline unsigned get_method_calling_convention_(const ir_type *method)
344
{
345
	assert(is_Method_type(method));
346
	return method->attr.method.irg_calling_conv;
347
348
}

349
350
351
352
353
354
355
356
357
358
359
/**
 * Check if type is a compound or array type.
 * This function returns true iff a value of this type cannot be represented by
 * a firm mode and need therefore special handling in lower_calls when used as
 * a parameter or return type.
 */
static inline bool is_aggregate_type(const ir_type *type)
{
	return is_compound_type(type) || is_Array_type(type);
}

360
361
ir_type *new_type_segment(ident *name, type_flags flags);

362
#endif