Commit | Line | Data |
---|---|---|
bb2ec1b3 TT |
1 | /* Convert types from GDB to GCC |
2 | ||
32d0add0 | 3 | Copyright (C) 2014-2015 Free Software Foundation, Inc. |
bb2ec1b3 TT |
4 | |
5 | This file is part of GDB. | |
6 | ||
7 | This program is free software; you can redistribute it and/or modify | |
8 | it under the terms of the GNU General Public License as published by | |
9 | the Free Software Foundation; either version 3 of the License, or | |
10 | (at your option) any later version. | |
11 | ||
12 | This program is distributed in the hope that it will be useful, | |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | GNU General Public License for more details. | |
16 | ||
17 | You should have received a copy of the GNU General Public License | |
18 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
19 | ||
20 | ||
21 | #include "defs.h" | |
22 | #include "gdbtypes.h" | |
23 | #include "compile-internal.h" | |
bb2ec1b3 TT |
24 | /* An object that maps a gdb type to a gcc type. */ |
25 | ||
26 | struct type_map_instance | |
27 | { | |
28 | /* The gdb type. */ | |
29 | ||
30 | struct type *type; | |
31 | ||
32 | /* The corresponding gcc type handle. */ | |
33 | ||
34 | gcc_type gcc_type; | |
35 | }; | |
36 | ||
37 | /* Hash a type_map_instance. */ | |
38 | ||
39 | static hashval_t | |
40 | hash_type_map_instance (const void *p) | |
41 | { | |
42 | const struct type_map_instance *inst = p; | |
43 | ||
44 | return htab_hash_pointer (inst->type); | |
45 | } | |
46 | ||
47 | /* Check two type_map_instance objects for equality. */ | |
48 | ||
49 | static int | |
50 | eq_type_map_instance (const void *a, const void *b) | |
51 | { | |
52 | const struct type_map_instance *insta = a; | |
53 | const struct type_map_instance *instb = b; | |
54 | ||
55 | return insta->type == instb->type; | |
56 | } | |
57 | ||
58 | \f | |
59 | ||
60 | /* Insert an entry into the type map associated with CONTEXT that maps | |
61 | from the gdb type TYPE to the gcc type GCC_TYPE. It is ok for a | |
62 | given type to be inserted more than once, provided that the exact | |
63 | same association is made each time. This simplifies how type | |
64 | caching works elsewhere in this file -- see how struct type caching | |
65 | is handled. */ | |
66 | ||
67 | static void | |
68 | insert_type (struct compile_c_instance *context, struct type *type, | |
69 | gcc_type gcc_type) | |
70 | { | |
71 | struct type_map_instance inst, *add; | |
72 | void **slot; | |
73 | ||
74 | inst.type = type; | |
75 | inst.gcc_type = gcc_type; | |
76 | slot = htab_find_slot (context->type_map, &inst, INSERT); | |
77 | ||
78 | add = *slot; | |
79 | /* The type might have already been inserted in order to handle | |
80 | recursive types. */ | |
81 | gdb_assert (add == NULL || add->gcc_type == gcc_type); | |
82 | ||
83 | if (add == NULL) | |
84 | { | |
85 | add = XNEW (struct type_map_instance); | |
86 | *add = inst; | |
87 | *slot = add; | |
88 | } | |
89 | } | |
90 | ||
91 | /* Convert a pointer type to its gcc representation. */ | |
92 | ||
93 | static gcc_type | |
94 | convert_pointer (struct compile_c_instance *context, struct type *type) | |
95 | { | |
96 | gcc_type target = convert_type (context, TYPE_TARGET_TYPE (type)); | |
97 | ||
98 | return C_CTX (context)->c_ops->build_pointer_type (C_CTX (context), | |
99 | target); | |
100 | } | |
101 | ||
102 | /* Convert an array type to its gcc representation. */ | |
103 | ||
104 | static gcc_type | |
105 | convert_array (struct compile_c_instance *context, struct type *type) | |
106 | { | |
107 | gcc_type element_type; | |
108 | struct type *range = TYPE_INDEX_TYPE (type); | |
109 | ||
110 | element_type = convert_type (context, TYPE_TARGET_TYPE (type)); | |
111 | ||
112 | if (TYPE_LOW_BOUND_KIND (range) != PROP_CONST) | |
113 | return C_CTX (context)->c_ops->error (C_CTX (context), | |
114 | _("array type with non-constant" | |
115 | " lower bound is not supported")); | |
116 | if (TYPE_LOW_BOUND (range) != 0) | |
117 | return C_CTX (context)->c_ops->error (C_CTX (context), | |
118 | _("cannot convert array type with " | |
119 | "non-zero lower bound to C")); | |
120 | ||
121 | if (TYPE_HIGH_BOUND_KIND (range) == PROP_LOCEXPR | |
122 | || TYPE_HIGH_BOUND_KIND (range) == PROP_LOCLIST) | |
123 | { | |
124 | gcc_type result; | |
125 | char *upper_bound; | |
126 | ||
127 | if (TYPE_VECTOR (type)) | |
128 | return C_CTX (context)->c_ops->error (C_CTX (context), | |
129 | _("variably-sized vector type" | |
130 | " is not supported")); | |
131 | ||
132 | upper_bound = c_get_range_decl_name (&TYPE_RANGE_DATA (range)->high); | |
133 | result = C_CTX (context)->c_ops->build_vla_array_type (C_CTX (context), | |
134 | element_type, | |
135 | upper_bound); | |
136 | xfree (upper_bound); | |
137 | return result; | |
138 | } | |
139 | else | |
140 | { | |
141 | LONGEST low_bound, high_bound, count; | |
142 | ||
143 | if (get_array_bounds (type, &low_bound, &high_bound) == 0) | |
144 | count = -1; | |
145 | else | |
146 | { | |
147 | gdb_assert (low_bound == 0); /* Ensured above. */ | |
148 | count = high_bound + 1; | |
149 | } | |
150 | ||
151 | if (TYPE_VECTOR (type)) | |
152 | return C_CTX (context)->c_ops->build_vector_type (C_CTX (context), | |
153 | element_type, | |
154 | count); | |
155 | return C_CTX (context)->c_ops->build_array_type (C_CTX (context), | |
156 | element_type, count); | |
157 | } | |
158 | } | |
159 | ||
160 | /* Convert a struct or union type to its gcc representation. */ | |
161 | ||
162 | static gcc_type | |
163 | convert_struct_or_union (struct compile_c_instance *context, struct type *type) | |
164 | { | |
165 | int i; | |
166 | gcc_type result; | |
167 | ||
168 | /* First we create the resulting type and enter it into our hash | |
169 | table. This lets recursive types work. */ | |
170 | if (TYPE_CODE (type) == TYPE_CODE_STRUCT) | |
171 | result = C_CTX (context)->c_ops->build_record_type (C_CTX (context)); | |
172 | else | |
173 | { | |
174 | gdb_assert (TYPE_CODE (type) == TYPE_CODE_UNION); | |
175 | result = C_CTX (context)->c_ops->build_union_type (C_CTX (context)); | |
176 | } | |
177 | insert_type (context, type, result); | |
178 | ||
179 | for (i = 0; i < TYPE_NFIELDS (type); ++i) | |
180 | { | |
181 | gcc_type field_type; | |
182 | unsigned long bitsize = TYPE_FIELD_BITSIZE (type, i); | |
183 | ||
184 | field_type = convert_type (context, TYPE_FIELD_TYPE (type, i)); | |
185 | if (bitsize == 0) | |
186 | bitsize = 8 * TYPE_LENGTH (TYPE_FIELD_TYPE (type, i)); | |
187 | C_CTX (context)->c_ops->build_add_field (C_CTX (context), result, | |
188 | TYPE_FIELD_NAME (type, i), | |
189 | field_type, | |
190 | bitsize, | |
191 | TYPE_FIELD_BITPOS (type, i)); | |
192 | } | |
193 | ||
194 | C_CTX (context)->c_ops->finish_record_or_union (C_CTX (context), result, | |
195 | TYPE_LENGTH (type)); | |
196 | return result; | |
197 | } | |
198 | ||
199 | /* Convert an enum type to its gcc representation. */ | |
200 | ||
201 | static gcc_type | |
202 | convert_enum (struct compile_c_instance *context, struct type *type) | |
203 | { | |
204 | gcc_type int_type, result; | |
205 | int i; | |
206 | struct gcc_c_context *ctx = C_CTX (context); | |
207 | ||
208 | int_type = ctx->c_ops->int_type (ctx, | |
209 | TYPE_UNSIGNED (type), | |
210 | TYPE_LENGTH (type)); | |
211 | ||
212 | result = ctx->c_ops->build_enum_type (ctx, int_type); | |
213 | for (i = 0; i < TYPE_NFIELDS (type); ++i) | |
214 | { | |
215 | ctx->c_ops->build_add_enum_constant (ctx, | |
216 | result, | |
217 | TYPE_FIELD_NAME (type, i), | |
218 | TYPE_FIELD_ENUMVAL (type, i)); | |
219 | } | |
220 | ||
221 | ctx->c_ops->finish_enum_type (ctx, result); | |
222 | ||
223 | return result; | |
224 | } | |
225 | ||
226 | /* Convert a function type to its gcc representation. */ | |
227 | ||
228 | static gcc_type | |
229 | convert_func (struct compile_c_instance *context, struct type *type) | |
230 | { | |
231 | int i; | |
232 | gcc_type result, return_type; | |
233 | struct gcc_type_array array; | |
234 | int is_varargs = TYPE_VARARGS (type) || !TYPE_PROTOTYPED (type); | |
235 | ||
236 | /* This approach means we can't make self-referential function | |
237 | types. Those are impossible in C, though. */ | |
238 | return_type = convert_type (context, TYPE_TARGET_TYPE (type)); | |
239 | ||
240 | array.n_elements = TYPE_NFIELDS (type); | |
241 | array.elements = XNEWVEC (gcc_type, TYPE_NFIELDS (type)); | |
242 | for (i = 0; i < TYPE_NFIELDS (type); ++i) | |
243 | array.elements[i] = convert_type (context, TYPE_FIELD_TYPE (type, i)); | |
244 | ||
245 | result = C_CTX (context)->c_ops->build_function_type (C_CTX (context), | |
246 | return_type, | |
247 | &array, is_varargs); | |
248 | xfree (array.elements); | |
249 | ||
250 | return result; | |
251 | } | |
252 | ||
253 | /* Convert an integer type to its gcc representation. */ | |
254 | ||
255 | static gcc_type | |
256 | convert_int (struct compile_c_instance *context, struct type *type) | |
257 | { | |
258 | return C_CTX (context)->c_ops->int_type (C_CTX (context), | |
259 | TYPE_UNSIGNED (type), | |
260 | TYPE_LENGTH (type)); | |
261 | } | |
262 | ||
263 | /* Convert a floating-point type to its gcc representation. */ | |
264 | ||
265 | static gcc_type | |
266 | convert_float (struct compile_c_instance *context, struct type *type) | |
267 | { | |
268 | return C_CTX (context)->c_ops->float_type (C_CTX (context), | |
269 | TYPE_LENGTH (type)); | |
270 | } | |
271 | ||
272 | /* Convert the 'void' type to its gcc representation. */ | |
273 | ||
274 | static gcc_type | |
275 | convert_void (struct compile_c_instance *context, struct type *type) | |
276 | { | |
277 | return C_CTX (context)->c_ops->void_type (C_CTX (context)); | |
278 | } | |
279 | ||
280 | /* Convert a boolean type to its gcc representation. */ | |
281 | ||
282 | static gcc_type | |
283 | convert_bool (struct compile_c_instance *context, struct type *type) | |
284 | { | |
285 | return C_CTX (context)->c_ops->bool_type (C_CTX (context)); | |
286 | } | |
287 | ||
288 | /* Convert a qualified type to its gcc representation. */ | |
289 | ||
290 | static gcc_type | |
291 | convert_qualified (struct compile_c_instance *context, struct type *type) | |
292 | { | |
293 | struct type *unqual = make_unqualified_type (type); | |
294 | gcc_type unqual_converted; | |
295 | int quals = 0; | |
296 | ||
297 | unqual_converted = convert_type (context, unqual); | |
298 | ||
299 | if (TYPE_CONST (type)) | |
300 | quals |= GCC_QUALIFIER_CONST; | |
301 | if (TYPE_VOLATILE (type)) | |
302 | quals |= GCC_QUALIFIER_VOLATILE; | |
303 | if (TYPE_RESTRICT (type)) | |
304 | quals |= GCC_QUALIFIER_RESTRICT; | |
305 | ||
306 | return C_CTX (context)->c_ops->build_qualified_type (C_CTX (context), | |
307 | unqual_converted, | |
308 | quals); | |
309 | } | |
310 | ||
311 | /* Convert a complex type to its gcc representation. */ | |
312 | ||
313 | static gcc_type | |
314 | convert_complex (struct compile_c_instance *context, struct type *type) | |
315 | { | |
316 | gcc_type base = convert_type (context, TYPE_TARGET_TYPE (type)); | |
317 | ||
318 | return C_CTX (context)->c_ops->build_complex_type (C_CTX (context), base); | |
319 | } | |
320 | ||
321 | /* A helper function which knows how to convert most types from their | |
322 | gdb representation to the corresponding gcc form. This examines | |
323 | the TYPE and dispatches to the appropriate conversion function. It | |
324 | returns the gcc type. */ | |
325 | ||
326 | static gcc_type | |
327 | convert_type_basic (struct compile_c_instance *context, struct type *type) | |
328 | { | |
329 | /* If we are converting a qualified type, first convert the | |
330 | unqualified type and then apply the qualifiers. */ | |
331 | if ((TYPE_INSTANCE_FLAGS (type) & (TYPE_INSTANCE_FLAG_CONST | |
332 | | TYPE_INSTANCE_FLAG_VOLATILE | |
333 | | TYPE_INSTANCE_FLAG_RESTRICT)) != 0) | |
334 | return convert_qualified (context, type); | |
335 | ||
336 | switch (TYPE_CODE (type)) | |
337 | { | |
338 | case TYPE_CODE_PTR: | |
339 | return convert_pointer (context, type); | |
340 | ||
341 | case TYPE_CODE_ARRAY: | |
342 | return convert_array (context, type); | |
343 | ||
344 | case TYPE_CODE_STRUCT: | |
345 | case TYPE_CODE_UNION: | |
346 | return convert_struct_or_union (context, type); | |
347 | ||
348 | case TYPE_CODE_ENUM: | |
349 | return convert_enum (context, type); | |
350 | ||
351 | case TYPE_CODE_FUNC: | |
352 | return convert_func (context, type); | |
353 | ||
354 | case TYPE_CODE_INT: | |
355 | return convert_int (context, type); | |
356 | ||
357 | case TYPE_CODE_FLT: | |
358 | return convert_float (context, type); | |
359 | ||
360 | case TYPE_CODE_VOID: | |
361 | return convert_void (context, type); | |
362 | ||
363 | case TYPE_CODE_BOOL: | |
364 | return convert_bool (context, type); | |
365 | ||
366 | case TYPE_CODE_COMPLEX: | |
367 | return convert_complex (context, type); | |
368 | } | |
369 | ||
370 | return C_CTX (context)->c_ops->error (C_CTX (context), | |
371 | _("cannot convert gdb type " | |
372 | "to gcc type")); | |
373 | } | |
374 | ||
375 | /* See compile-internal.h. */ | |
376 | ||
377 | gcc_type | |
378 | convert_type (struct compile_c_instance *context, struct type *type) | |
379 | { | |
380 | struct type_map_instance inst, *found; | |
381 | gcc_type result; | |
382 | ||
383 | /* We don't ever have to deal with typedefs in this code, because | |
384 | those are only needed as symbols by the C compiler. */ | |
385 | CHECK_TYPEDEF (type); | |
386 | ||
387 | inst.type = type; | |
388 | found = htab_find (context->type_map, &inst); | |
389 | if (found != NULL) | |
390 | return found->gcc_type; | |
391 | ||
392 | result = convert_type_basic (context, type); | |
393 | insert_type (context, type, result); | |
394 | return result; | |
395 | } | |
396 | ||
397 | \f | |
398 | ||
399 | /* Delete the compiler instance C. */ | |
400 | ||
401 | static void | |
402 | delete_instance (struct compile_instance *c) | |
403 | { | |
404 | struct compile_c_instance *context = (struct compile_c_instance *) c; | |
405 | ||
406 | context->base.fe->ops->destroy (context->base.fe); | |
407 | htab_delete (context->type_map); | |
408 | if (context->symbol_err_map != NULL) | |
409 | htab_delete (context->symbol_err_map); | |
410 | xfree (context); | |
411 | } | |
412 | ||
413 | /* See compile-internal.h. */ | |
414 | ||
415 | struct compile_instance * | |
416 | new_compile_instance (struct gcc_c_context *fe) | |
417 | { | |
418 | struct compile_c_instance *result = XCNEW (struct compile_c_instance); | |
419 | ||
420 | result->base.fe = &fe->base; | |
421 | result->base.destroy = delete_instance; | |
422 | result->base.gcc_target_options = ("-std=gnu11" | |
423 | /* Otherwise the .o file may need | |
424 | "_Unwind_Resume" and | |
425 | "__gcc_personality_v0". */ | |
426 | " -fno-exceptions"); | |
427 | ||
428 | result->type_map = htab_create_alloc (10, hash_type_map_instance, | |
429 | eq_type_map_instance, | |
430 | xfree, xcalloc, xfree); | |
431 | ||
432 | fe->c_ops->set_callbacks (fe, gcc_convert_symbol, | |
433 | gcc_symbol_address, result); | |
434 | ||
435 | return &result->base; | |
436 | } |