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. */ | |
08464196 JK |
81 | if (add != NULL && add->gcc_type != gcc_type) |
82 | error (_("Unexpected type id from GCC, check you use recent enough GCC.")); | |
bb2ec1b3 TT |
83 | |
84 | if (add == NULL) | |
85 | { | |
86 | add = XNEW (struct type_map_instance); | |
87 | *add = inst; | |
88 | *slot = add; | |
89 | } | |
90 | } | |
91 | ||
92 | /* Convert a pointer type to its gcc representation. */ | |
93 | ||
94 | static gcc_type | |
95 | convert_pointer (struct compile_c_instance *context, struct type *type) | |
96 | { | |
97 | gcc_type target = convert_type (context, TYPE_TARGET_TYPE (type)); | |
98 | ||
99 | return C_CTX (context)->c_ops->build_pointer_type (C_CTX (context), | |
100 | target); | |
101 | } | |
102 | ||
103 | /* Convert an array type to its gcc representation. */ | |
104 | ||
105 | static gcc_type | |
106 | convert_array (struct compile_c_instance *context, struct type *type) | |
107 | { | |
108 | gcc_type element_type; | |
109 | struct type *range = TYPE_INDEX_TYPE (type); | |
110 | ||
111 | element_type = convert_type (context, TYPE_TARGET_TYPE (type)); | |
112 | ||
113 | if (TYPE_LOW_BOUND_KIND (range) != PROP_CONST) | |
114 | return C_CTX (context)->c_ops->error (C_CTX (context), | |
115 | _("array type with non-constant" | |
116 | " lower bound is not supported")); | |
117 | if (TYPE_LOW_BOUND (range) != 0) | |
118 | return C_CTX (context)->c_ops->error (C_CTX (context), | |
119 | _("cannot convert array type with " | |
120 | "non-zero lower bound to C")); | |
121 | ||
122 | if (TYPE_HIGH_BOUND_KIND (range) == PROP_LOCEXPR | |
123 | || TYPE_HIGH_BOUND_KIND (range) == PROP_LOCLIST) | |
124 | { | |
125 | gcc_type result; | |
126 | char *upper_bound; | |
127 | ||
128 | if (TYPE_VECTOR (type)) | |
129 | return C_CTX (context)->c_ops->error (C_CTX (context), | |
130 | _("variably-sized vector type" | |
131 | " is not supported")); | |
132 | ||
133 | upper_bound = c_get_range_decl_name (&TYPE_RANGE_DATA (range)->high); | |
134 | result = C_CTX (context)->c_ops->build_vla_array_type (C_CTX (context), | |
135 | element_type, | |
136 | upper_bound); | |
137 | xfree (upper_bound); | |
138 | return result; | |
139 | } | |
140 | else | |
141 | { | |
142 | LONGEST low_bound, high_bound, count; | |
143 | ||
144 | if (get_array_bounds (type, &low_bound, &high_bound) == 0) | |
145 | count = -1; | |
146 | else | |
147 | { | |
148 | gdb_assert (low_bound == 0); /* Ensured above. */ | |
149 | count = high_bound + 1; | |
150 | } | |
151 | ||
152 | if (TYPE_VECTOR (type)) | |
153 | return C_CTX (context)->c_ops->build_vector_type (C_CTX (context), | |
154 | element_type, | |
155 | count); | |
156 | return C_CTX (context)->c_ops->build_array_type (C_CTX (context), | |
157 | element_type, count); | |
158 | } | |
159 | } | |
160 | ||
161 | /* Convert a struct or union type to its gcc representation. */ | |
162 | ||
163 | static gcc_type | |
164 | convert_struct_or_union (struct compile_c_instance *context, struct type *type) | |
165 | { | |
166 | int i; | |
167 | gcc_type result; | |
168 | ||
169 | /* First we create the resulting type and enter it into our hash | |
170 | table. This lets recursive types work. */ | |
171 | if (TYPE_CODE (type) == TYPE_CODE_STRUCT) | |
172 | result = C_CTX (context)->c_ops->build_record_type (C_CTX (context)); | |
173 | else | |
174 | { | |
175 | gdb_assert (TYPE_CODE (type) == TYPE_CODE_UNION); | |
176 | result = C_CTX (context)->c_ops->build_union_type (C_CTX (context)); | |
177 | } | |
178 | insert_type (context, type, result); | |
179 | ||
180 | for (i = 0; i < TYPE_NFIELDS (type); ++i) | |
181 | { | |
182 | gcc_type field_type; | |
183 | unsigned long bitsize = TYPE_FIELD_BITSIZE (type, i); | |
184 | ||
185 | field_type = convert_type (context, TYPE_FIELD_TYPE (type, i)); | |
186 | if (bitsize == 0) | |
187 | bitsize = 8 * TYPE_LENGTH (TYPE_FIELD_TYPE (type, i)); | |
188 | C_CTX (context)->c_ops->build_add_field (C_CTX (context), result, | |
189 | TYPE_FIELD_NAME (type, i), | |
190 | field_type, | |
191 | bitsize, | |
192 | TYPE_FIELD_BITPOS (type, i)); | |
193 | } | |
194 | ||
195 | C_CTX (context)->c_ops->finish_record_or_union (C_CTX (context), result, | |
196 | TYPE_LENGTH (type)); | |
197 | return result; | |
198 | } | |
199 | ||
200 | /* Convert an enum type to its gcc representation. */ | |
201 | ||
202 | static gcc_type | |
203 | convert_enum (struct compile_c_instance *context, struct type *type) | |
204 | { | |
205 | gcc_type int_type, result; | |
206 | int i; | |
207 | struct gcc_c_context *ctx = C_CTX (context); | |
208 | ||
209 | int_type = ctx->c_ops->int_type (ctx, | |
210 | TYPE_UNSIGNED (type), | |
211 | TYPE_LENGTH (type)); | |
212 | ||
213 | result = ctx->c_ops->build_enum_type (ctx, int_type); | |
214 | for (i = 0; i < TYPE_NFIELDS (type); ++i) | |
215 | { | |
216 | ctx->c_ops->build_add_enum_constant (ctx, | |
217 | result, | |
218 | TYPE_FIELD_NAME (type, i), | |
219 | TYPE_FIELD_ENUMVAL (type, i)); | |
220 | } | |
221 | ||
222 | ctx->c_ops->finish_enum_type (ctx, result); | |
223 | ||
224 | return result; | |
225 | } | |
226 | ||
227 | /* Convert a function type to its gcc representation. */ | |
228 | ||
229 | static gcc_type | |
230 | convert_func (struct compile_c_instance *context, struct type *type) | |
231 | { | |
232 | int i; | |
233 | gcc_type result, return_type; | |
234 | struct gcc_type_array array; | |
235 | int is_varargs = TYPE_VARARGS (type) || !TYPE_PROTOTYPED (type); | |
236 | ||
237 | /* This approach means we can't make self-referential function | |
238 | types. Those are impossible in C, though. */ | |
239 | return_type = convert_type (context, TYPE_TARGET_TYPE (type)); | |
240 | ||
241 | array.n_elements = TYPE_NFIELDS (type); | |
242 | array.elements = XNEWVEC (gcc_type, TYPE_NFIELDS (type)); | |
243 | for (i = 0; i < TYPE_NFIELDS (type); ++i) | |
244 | array.elements[i] = convert_type (context, TYPE_FIELD_TYPE (type, i)); | |
245 | ||
246 | result = C_CTX (context)->c_ops->build_function_type (C_CTX (context), | |
247 | return_type, | |
248 | &array, is_varargs); | |
249 | xfree (array.elements); | |
250 | ||
251 | return result; | |
252 | } | |
253 | ||
254 | /* Convert an integer type to its gcc representation. */ | |
255 | ||
256 | static gcc_type | |
257 | convert_int (struct compile_c_instance *context, struct type *type) | |
258 | { | |
259 | return C_CTX (context)->c_ops->int_type (C_CTX (context), | |
260 | TYPE_UNSIGNED (type), | |
261 | TYPE_LENGTH (type)); | |
262 | } | |
263 | ||
264 | /* Convert a floating-point type to its gcc representation. */ | |
265 | ||
266 | static gcc_type | |
267 | convert_float (struct compile_c_instance *context, struct type *type) | |
268 | { | |
269 | return C_CTX (context)->c_ops->float_type (C_CTX (context), | |
270 | TYPE_LENGTH (type)); | |
271 | } | |
272 | ||
273 | /* Convert the 'void' type to its gcc representation. */ | |
274 | ||
275 | static gcc_type | |
276 | convert_void (struct compile_c_instance *context, struct type *type) | |
277 | { | |
278 | return C_CTX (context)->c_ops->void_type (C_CTX (context)); | |
279 | } | |
280 | ||
281 | /* Convert a boolean type to its gcc representation. */ | |
282 | ||
283 | static gcc_type | |
284 | convert_bool (struct compile_c_instance *context, struct type *type) | |
285 | { | |
286 | return C_CTX (context)->c_ops->bool_type (C_CTX (context)); | |
287 | } | |
288 | ||
289 | /* Convert a qualified type to its gcc representation. */ | |
290 | ||
291 | static gcc_type | |
292 | convert_qualified (struct compile_c_instance *context, struct type *type) | |
293 | { | |
294 | struct type *unqual = make_unqualified_type (type); | |
295 | gcc_type unqual_converted; | |
296 | int quals = 0; | |
297 | ||
298 | unqual_converted = convert_type (context, unqual); | |
299 | ||
300 | if (TYPE_CONST (type)) | |
301 | quals |= GCC_QUALIFIER_CONST; | |
302 | if (TYPE_VOLATILE (type)) | |
303 | quals |= GCC_QUALIFIER_VOLATILE; | |
304 | if (TYPE_RESTRICT (type)) | |
305 | quals |= GCC_QUALIFIER_RESTRICT; | |
306 | ||
307 | return C_CTX (context)->c_ops->build_qualified_type (C_CTX (context), | |
308 | unqual_converted, | |
309 | quals); | |
310 | } | |
311 | ||
312 | /* Convert a complex type to its gcc representation. */ | |
313 | ||
314 | static gcc_type | |
315 | convert_complex (struct compile_c_instance *context, struct type *type) | |
316 | { | |
317 | gcc_type base = convert_type (context, TYPE_TARGET_TYPE (type)); | |
318 | ||
319 | return C_CTX (context)->c_ops->build_complex_type (C_CTX (context), base); | |
320 | } | |
321 | ||
322 | /* A helper function which knows how to convert most types from their | |
323 | gdb representation to the corresponding gcc form. This examines | |
324 | the TYPE and dispatches to the appropriate conversion function. It | |
325 | returns the gcc type. */ | |
326 | ||
327 | static gcc_type | |
328 | convert_type_basic (struct compile_c_instance *context, struct type *type) | |
329 | { | |
330 | /* If we are converting a qualified type, first convert the | |
331 | unqualified type and then apply the qualifiers. */ | |
332 | if ((TYPE_INSTANCE_FLAGS (type) & (TYPE_INSTANCE_FLAG_CONST | |
333 | | TYPE_INSTANCE_FLAG_VOLATILE | |
334 | | TYPE_INSTANCE_FLAG_RESTRICT)) != 0) | |
335 | return convert_qualified (context, type); | |
336 | ||
337 | switch (TYPE_CODE (type)) | |
338 | { | |
339 | case TYPE_CODE_PTR: | |
340 | return convert_pointer (context, type); | |
341 | ||
342 | case TYPE_CODE_ARRAY: | |
343 | return convert_array (context, type); | |
344 | ||
345 | case TYPE_CODE_STRUCT: | |
346 | case TYPE_CODE_UNION: | |
347 | return convert_struct_or_union (context, type); | |
348 | ||
349 | case TYPE_CODE_ENUM: | |
350 | return convert_enum (context, type); | |
351 | ||
352 | case TYPE_CODE_FUNC: | |
353 | return convert_func (context, type); | |
354 | ||
355 | case TYPE_CODE_INT: | |
356 | return convert_int (context, type); | |
357 | ||
358 | case TYPE_CODE_FLT: | |
359 | return convert_float (context, type); | |
360 | ||
361 | case TYPE_CODE_VOID: | |
362 | return convert_void (context, type); | |
363 | ||
364 | case TYPE_CODE_BOOL: | |
365 | return convert_bool (context, type); | |
366 | ||
367 | case TYPE_CODE_COMPLEX: | |
368 | return convert_complex (context, type); | |
369 | } | |
370 | ||
371 | return C_CTX (context)->c_ops->error (C_CTX (context), | |
372 | _("cannot convert gdb type " | |
373 | "to gcc type")); | |
374 | } | |
375 | ||
376 | /* See compile-internal.h. */ | |
377 | ||
378 | gcc_type | |
379 | convert_type (struct compile_c_instance *context, struct type *type) | |
380 | { | |
381 | struct type_map_instance inst, *found; | |
382 | gcc_type result; | |
383 | ||
384 | /* We don't ever have to deal with typedefs in this code, because | |
385 | those are only needed as symbols by the C compiler. */ | |
f168693b | 386 | type = check_typedef (type); |
bb2ec1b3 TT |
387 | |
388 | inst.type = type; | |
389 | found = htab_find (context->type_map, &inst); | |
390 | if (found != NULL) | |
391 | return found->gcc_type; | |
392 | ||
393 | result = convert_type_basic (context, type); | |
394 | insert_type (context, type, result); | |
395 | return result; | |
396 | } | |
397 | ||
398 | \f | |
399 | ||
400 | /* Delete the compiler instance C. */ | |
401 | ||
402 | static void | |
403 | delete_instance (struct compile_instance *c) | |
404 | { | |
405 | struct compile_c_instance *context = (struct compile_c_instance *) c; | |
406 | ||
407 | context->base.fe->ops->destroy (context->base.fe); | |
408 | htab_delete (context->type_map); | |
409 | if (context->symbol_err_map != NULL) | |
410 | htab_delete (context->symbol_err_map); | |
411 | xfree (context); | |
412 | } | |
413 | ||
414 | /* See compile-internal.h. */ | |
415 | ||
416 | struct compile_instance * | |
417 | new_compile_instance (struct gcc_c_context *fe) | |
418 | { | |
419 | struct compile_c_instance *result = XCNEW (struct compile_c_instance); | |
420 | ||
421 | result->base.fe = &fe->base; | |
422 | result->base.destroy = delete_instance; | |
423 | result->base.gcc_target_options = ("-std=gnu11" | |
424 | /* Otherwise the .o file may need | |
425 | "_Unwind_Resume" and | |
426 | "__gcc_personality_v0". */ | |
427 | " -fno-exceptions"); | |
428 | ||
429 | result->type_map = htab_create_alloc (10, hash_type_map_instance, | |
430 | eq_type_map_instance, | |
431 | xfree, xcalloc, xfree); | |
432 | ||
433 | fe->c_ops->set_callbacks (fe, gcc_convert_symbol, | |
434 | gcc_symbol_address, result); | |
435 | ||
436 | return &result->base; | |
437 | } |