]>
Commit | Line | Data |
---|---|---|
bb2ec1b3 TT |
1 | /* Convert types from GDB to GCC |
2 | ||
3666a048 | 3 | Copyright (C) 2014-2021 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" | |
b7dc48b4 | 24 | #include "compile-c.h" |
7022349d PA |
25 | #include "objfiles.h" |
26 | ||
bb2ec1b3 TT |
27 | /* Convert a pointer type to its gcc representation. */ |
28 | ||
29 | static gcc_type | |
9cdfd9a2 | 30 | convert_pointer (compile_c_instance *context, struct type *type) |
bb2ec1b3 | 31 | { |
9cdfd9a2 | 32 | gcc_type target = context->convert_type (TYPE_TARGET_TYPE (type)); |
bb2ec1b3 | 33 | |
9cdfd9a2 | 34 | return context->plugin ().build_pointer_type (target); |
bb2ec1b3 TT |
35 | } |
36 | ||
37 | /* Convert an array type to its gcc representation. */ | |
38 | ||
39 | static gcc_type | |
9cdfd9a2 | 40 | convert_array (compile_c_instance *context, struct type *type) |
bb2ec1b3 TT |
41 | { |
42 | gcc_type element_type; | |
3d967001 | 43 | struct type *range = type->index_type (); |
bb2ec1b3 | 44 | |
9cdfd9a2 | 45 | element_type = context->convert_type (TYPE_TARGET_TYPE (type)); |
bb2ec1b3 | 46 | |
3b606f38 | 47 | if (range->bounds ()->low.kind () != PROP_CONST) |
9cdfd9a2 | 48 | return context->plugin ().error (_("array type with non-constant" |
18cdc6d8 | 49 | " lower bound is not supported")); |
5537ddd0 | 50 | if (range->bounds ()->low.const_val () != 0) |
9cdfd9a2 | 51 | return context->plugin ().error (_("cannot convert array type with " |
18cdc6d8 | 52 | "non-zero lower bound to C")); |
bb2ec1b3 | 53 | |
3b606f38 SM |
54 | if (range->bounds ()->high.kind () == PROP_LOCEXPR |
55 | || range->bounds ()->high.kind () == PROP_LOCLIST) | |
bb2ec1b3 TT |
56 | { |
57 | gcc_type result; | |
bb2ec1b3 | 58 | |
bd63c870 | 59 | if (type->is_vector ()) |
9cdfd9a2 | 60 | return context->plugin ().error (_("variably-sized vector type" |
18cdc6d8 | 61 | " is not supported")); |
bb2ec1b3 | 62 | |
8f84fb0e | 63 | std::string upper_bound |
599088e3 | 64 | = c_get_range_decl_name (&range->bounds ()->high); |
9cdfd9a2 | 65 | result = context->plugin ().build_vla_array_type (element_type, |
18cdc6d8 | 66 | upper_bound.c_str ()); |
bb2ec1b3 TT |
67 | return result; |
68 | } | |
69 | else | |
70 | { | |
71 | LONGEST low_bound, high_bound, count; | |
72 | ||
584903d3 | 73 | if (!get_array_bounds (type, &low_bound, &high_bound)) |
bb2ec1b3 TT |
74 | count = -1; |
75 | else | |
76 | { | |
77 | gdb_assert (low_bound == 0); /* Ensured above. */ | |
78 | count = high_bound + 1; | |
79 | } | |
80 | ||
bd63c870 | 81 | if (type->is_vector ()) |
9cdfd9a2 KS |
82 | return context->plugin ().build_vector_type (element_type, count); |
83 | return context->plugin ().build_array_type (element_type, count); | |
bb2ec1b3 TT |
84 | } |
85 | } | |
86 | ||
87 | /* Convert a struct or union type to its gcc representation. */ | |
88 | ||
89 | static gcc_type | |
9cdfd9a2 | 90 | convert_struct_or_union (compile_c_instance *context, struct type *type) |
bb2ec1b3 TT |
91 | { |
92 | int i; | |
93 | gcc_type result; | |
94 | ||
95 | /* First we create the resulting type and enter it into our hash | |
96 | table. This lets recursive types work. */ | |
78134374 | 97 | if (type->code () == TYPE_CODE_STRUCT) |
9cdfd9a2 | 98 | result = context->plugin ().build_record_type (); |
bb2ec1b3 TT |
99 | else |
100 | { | |
78134374 | 101 | gdb_assert (type->code () == TYPE_CODE_UNION); |
9cdfd9a2 | 102 | result = context->plugin ().build_union_type (); |
bb2ec1b3 | 103 | } |
9cdfd9a2 | 104 | context->insert_type (type, result); |
bb2ec1b3 | 105 | |
1f704f76 | 106 | for (i = 0; i < type->num_fields (); ++i) |
bb2ec1b3 TT |
107 | { |
108 | gcc_type field_type; | |
109 | unsigned long bitsize = TYPE_FIELD_BITSIZE (type, i); | |
110 | ||
940da03e | 111 | field_type = context->convert_type (type->field (i).type ()); |
bb2ec1b3 | 112 | if (bitsize == 0) |
940da03e | 113 | bitsize = 8 * TYPE_LENGTH (type->field (i).type ()); |
9cdfd9a2 | 114 | context->plugin ().build_add_field (result, |
18cdc6d8 KS |
115 | TYPE_FIELD_NAME (type, i), |
116 | field_type, | |
117 | bitsize, | |
118 | TYPE_FIELD_BITPOS (type, i)); | |
bb2ec1b3 TT |
119 | } |
120 | ||
9cdfd9a2 | 121 | context->plugin ().finish_record_or_union (result, TYPE_LENGTH (type)); |
bb2ec1b3 TT |
122 | return result; |
123 | } | |
124 | ||
125 | /* Convert an enum type to its gcc representation. */ | |
126 | ||
127 | static gcc_type | |
9cdfd9a2 | 128 | convert_enum (compile_c_instance *context, struct type *type) |
bb2ec1b3 TT |
129 | { |
130 | gcc_type int_type, result; | |
131 | int i; | |
bb2ec1b3 | 132 | |
c6d940a9 | 133 | int_type = context->plugin ().int_type_v0 (type->is_unsigned (), |
9cdfd9a2 | 134 | TYPE_LENGTH (type)); |
bb2ec1b3 | 135 | |
9cdfd9a2 | 136 | result = context->plugin ().build_enum_type (int_type); |
1f704f76 | 137 | for (i = 0; i < type->num_fields (); ++i) |
bb2ec1b3 | 138 | { |
9cdfd9a2 KS |
139 | context->plugin ().build_add_enum_constant |
140 | (result, TYPE_FIELD_NAME (type, i), TYPE_FIELD_ENUMVAL (type, i)); | |
bb2ec1b3 TT |
141 | } |
142 | ||
9cdfd9a2 | 143 | context->plugin ().finish_enum_type (result); |
bb2ec1b3 TT |
144 | |
145 | return result; | |
146 | } | |
147 | ||
148 | /* Convert a function type to its gcc representation. */ | |
149 | ||
150 | static gcc_type | |
9cdfd9a2 | 151 | convert_func (compile_c_instance *context, struct type *type) |
bb2ec1b3 TT |
152 | { |
153 | int i; | |
154 | gcc_type result, return_type; | |
155 | struct gcc_type_array array; | |
a409645d | 156 | int is_varargs = type->has_varargs () || !type->is_prototyped (); |
bb2ec1b3 | 157 | |
7022349d PA |
158 | struct type *target_type = TYPE_TARGET_TYPE (type); |
159 | ||
160 | /* Functions with no debug info have no return type. Ideally we'd | |
161 | want to fallback to the type of the cast just before the | |
162 | function, like GDB's built-in expression parser, but we don't | |
163 | have access to that type here. For now, fallback to int, like | |
164 | GDB's parser used to do. */ | |
165 | if (target_type == NULL) | |
166 | { | |
167 | if (TYPE_OBJFILE_OWNED (type)) | |
168 | target_type = objfile_type (TYPE_OWNER (type).objfile)->builtin_int; | |
169 | else | |
170 | target_type = builtin_type (TYPE_OWNER (type).gdbarch)->builtin_int; | |
171 | warning (_("function has unknown return type; assuming int")); | |
172 | } | |
173 | ||
bb2ec1b3 TT |
174 | /* This approach means we can't make self-referential function |
175 | types. Those are impossible in C, though. */ | |
9cdfd9a2 | 176 | return_type = context->convert_type (target_type); |
bb2ec1b3 | 177 | |
1f704f76 | 178 | array.n_elements = type->num_fields (); |
ebe824f5 TT |
179 | std::vector<gcc_type> elements (array.n_elements); |
180 | array.elements = elements.data (); | |
1f704f76 | 181 | for (i = 0; i < type->num_fields (); ++i) |
940da03e | 182 | array.elements[i] = context->convert_type (type->field (i).type ()); |
bb2ec1b3 | 183 | |
9cdfd9a2 | 184 | result = context->plugin ().build_function_type (return_type, |
18cdc6d8 | 185 | &array, is_varargs); |
bb2ec1b3 TT |
186 | |
187 | return result; | |
188 | } | |
189 | ||
190 | /* Convert an integer type to its gcc representation. */ | |
191 | ||
192 | static gcc_type | |
9cdfd9a2 | 193 | convert_int (compile_c_instance *context, struct type *type) |
bb2ec1b3 | 194 | { |
9cdfd9a2 | 195 | if (context->plugin ().version () >= GCC_C_FE_VERSION_1) |
476d250e | 196 | { |
20ce4123 | 197 | if (type->has_no_signedness ()) |
476d250e AO |
198 | { |
199 | gdb_assert (TYPE_LENGTH (type) == 1); | |
9cdfd9a2 | 200 | return context->plugin ().char_type (); |
476d250e | 201 | } |
c6d940a9 | 202 | return context->plugin ().int_type (type->is_unsigned (), |
18cdc6d8 | 203 | TYPE_LENGTH (type), |
7d93a1e0 | 204 | type->name ()); |
476d250e AO |
205 | } |
206 | else | |
c6d940a9 | 207 | return context->plugin ().int_type_v0 (type->is_unsigned (), |
18cdc6d8 | 208 | TYPE_LENGTH (type)); |
bb2ec1b3 TT |
209 | } |
210 | ||
211 | /* Convert a floating-point type to its gcc representation. */ | |
212 | ||
213 | static gcc_type | |
9cdfd9a2 | 214 | convert_float (compile_c_instance *context, struct type *type) |
bb2ec1b3 | 215 | { |
9cdfd9a2 KS |
216 | if (context->plugin ().version () >= GCC_C_FE_VERSION_1) |
217 | return context->plugin ().float_type (TYPE_LENGTH (type), | |
7d93a1e0 | 218 | type->name ()); |
476d250e | 219 | else |
9cdfd9a2 | 220 | return context->plugin ().float_type_v0 (TYPE_LENGTH (type)); |
bb2ec1b3 TT |
221 | } |
222 | ||
223 | /* Convert the 'void' type to its gcc representation. */ | |
224 | ||
225 | static gcc_type | |
9cdfd9a2 | 226 | convert_void (compile_c_instance *context, struct type *type) |
bb2ec1b3 | 227 | { |
9cdfd9a2 | 228 | return context->plugin ().void_type (); |
bb2ec1b3 TT |
229 | } |
230 | ||
231 | /* Convert a boolean type to its gcc representation. */ | |
232 | ||
233 | static gcc_type | |
9cdfd9a2 | 234 | convert_bool (compile_c_instance *context, struct type *type) |
bb2ec1b3 | 235 | { |
9cdfd9a2 | 236 | return context->plugin ().bool_type (); |
bb2ec1b3 TT |
237 | } |
238 | ||
239 | /* Convert a qualified type to its gcc representation. */ | |
240 | ||
241 | static gcc_type | |
9cdfd9a2 | 242 | convert_qualified (compile_c_instance *context, struct type *type) |
bb2ec1b3 TT |
243 | { |
244 | struct type *unqual = make_unqualified_type (type); | |
245 | gcc_type unqual_converted; | |
8d297bbf | 246 | gcc_qualifiers_flags quals = 0; |
bb2ec1b3 | 247 | |
9cdfd9a2 | 248 | unqual_converted = context->convert_type (unqual); |
bb2ec1b3 TT |
249 | |
250 | if (TYPE_CONST (type)) | |
251 | quals |= GCC_QUALIFIER_CONST; | |
252 | if (TYPE_VOLATILE (type)) | |
253 | quals |= GCC_QUALIFIER_VOLATILE; | |
254 | if (TYPE_RESTRICT (type)) | |
255 | quals |= GCC_QUALIFIER_RESTRICT; | |
256 | ||
04902b09 PA |
257 | return context->plugin ().build_qualified_type (unqual_converted, |
258 | quals.raw ()); | |
bb2ec1b3 TT |
259 | } |
260 | ||
261 | /* Convert a complex type to its gcc representation. */ | |
262 | ||
263 | static gcc_type | |
9cdfd9a2 | 264 | convert_complex (compile_c_instance *context, struct type *type) |
bb2ec1b3 | 265 | { |
9cdfd9a2 | 266 | gcc_type base = context->convert_type (TYPE_TARGET_TYPE (type)); |
bb2ec1b3 | 267 | |
9cdfd9a2 | 268 | return context->plugin ().build_complex_type (base); |
bb2ec1b3 TT |
269 | } |
270 | ||
271 | /* A helper function which knows how to convert most types from their | |
272 | gdb representation to the corresponding gcc form. This examines | |
273 | the TYPE and dispatches to the appropriate conversion function. It | |
274 | returns the gcc type. */ | |
275 | ||
276 | static gcc_type | |
9cdfd9a2 | 277 | convert_type_basic (compile_c_instance *context, struct type *type) |
bb2ec1b3 TT |
278 | { |
279 | /* If we are converting a qualified type, first convert the | |
280 | unqualified type and then apply the qualifiers. */ | |
10242f36 SM |
281 | if ((type->instance_flags () & (TYPE_INSTANCE_FLAG_CONST |
282 | | TYPE_INSTANCE_FLAG_VOLATILE | |
283 | | TYPE_INSTANCE_FLAG_RESTRICT)) != 0) | |
bb2ec1b3 TT |
284 | return convert_qualified (context, type); |
285 | ||
78134374 | 286 | switch (type->code ()) |
bb2ec1b3 TT |
287 | { |
288 | case TYPE_CODE_PTR: | |
289 | return convert_pointer (context, type); | |
290 | ||
291 | case TYPE_CODE_ARRAY: | |
292 | return convert_array (context, type); | |
293 | ||
294 | case TYPE_CODE_STRUCT: | |
295 | case TYPE_CODE_UNION: | |
296 | return convert_struct_or_union (context, type); | |
297 | ||
298 | case TYPE_CODE_ENUM: | |
299 | return convert_enum (context, type); | |
300 | ||
301 | case TYPE_CODE_FUNC: | |
302 | return convert_func (context, type); | |
303 | ||
304 | case TYPE_CODE_INT: | |
305 | return convert_int (context, type); | |
306 | ||
307 | case TYPE_CODE_FLT: | |
308 | return convert_float (context, type); | |
309 | ||
310 | case TYPE_CODE_VOID: | |
311 | return convert_void (context, type); | |
312 | ||
313 | case TYPE_CODE_BOOL: | |
314 | return convert_bool (context, type); | |
315 | ||
316 | case TYPE_CODE_COMPLEX: | |
317 | return convert_complex (context, type); | |
46a4882b PA |
318 | |
319 | case TYPE_CODE_ERROR: | |
320 | { | |
321 | /* Ideally, if we get here due to a cast expression, we'd use | |
322 | the cast-to type as the variable's type, like GDB's | |
323 | built-in parser does. For now, assume "int" like GDB's | |
324 | built-in parser used to do, but at least warn. */ | |
325 | struct type *fallback; | |
326 | if (TYPE_OBJFILE_OWNED (type)) | |
327 | fallback = objfile_type (TYPE_OWNER (type).objfile)->builtin_int; | |
328 | else | |
329 | fallback = builtin_type (TYPE_OWNER (type).gdbarch)->builtin_int; | |
330 | warning (_("variable has unknown type; assuming int")); | |
331 | return convert_int (context, fallback); | |
332 | } | |
bb2ec1b3 TT |
333 | } |
334 | ||
9cdfd9a2 | 335 | return context->plugin ().error (_("cannot convert gdb type to gcc type")); |
bb2ec1b3 TT |
336 | } |
337 | ||
9cdfd9a2 KS |
338 | /* Default compile flags for C. */ |
339 | ||
340 | const char *compile_c_instance::m_default_cflags = "-std=gnu11" | |
341 | /* Otherwise the .o file may need | |
342 | "_Unwind_Resume" and | |
343 | "__gcc_personality_v0". */ | |
344 | " -fno-exceptions" | |
345 | " -Wno-implicit-function-declaration"; | |
346 | ||
347 | /* See compile-c.h. */ | |
bb2ec1b3 TT |
348 | |
349 | gcc_type | |
9cdfd9a2 | 350 | compile_c_instance::convert_type (struct type *type) |
bb2ec1b3 | 351 | { |
bb2ec1b3 TT |
352 | /* We don't ever have to deal with typedefs in this code, because |
353 | those are only needed as symbols by the C compiler. */ | |
f168693b | 354 | type = check_typedef (type); |
bb2ec1b3 | 355 | |
9cdfd9a2 | 356 | gcc_type result; |
d82b3862 | 357 | if (get_cached_type (type, &result)) |
9cdfd9a2 | 358 | return result; |
bb2ec1b3 | 359 | |
9cdfd9a2 KS |
360 | result = convert_type_basic (this, type); |
361 | insert_type (type, result); | |
bb2ec1b3 TT |
362 | return result; |
363 | } | |
364 | ||
365 | \f | |
366 | ||
18cdc6d8 KS |
367 | /* C plug-in wrapper. */ |
368 | ||
369 | #define FORWARD(OP,...) m_context->c_ops->OP(m_context, ##__VA_ARGS__) | |
370 | #define GCC_METHOD0(R, N) \ | |
371 | R gcc_c_plugin::N () const \ | |
372 | { return FORWARD (N); } | |
373 | #define GCC_METHOD1(R, N, A) \ | |
374 | R gcc_c_plugin::N (A a) const \ | |
375 | { return FORWARD (N, a); } | |
376 | #define GCC_METHOD2(R, N, A, B) \ | |
377 | R gcc_c_plugin::N (A a, B b) const \ | |
378 | { return FORWARD (N, a, b); } | |
379 | #define GCC_METHOD3(R, N, A, B, C) \ | |
380 | R gcc_c_plugin::N (A a, B b, C c) const \ | |
381 | { return FORWARD (N, a, b, c); } | |
382 | #define GCC_METHOD4(R, N, A, B, C, D) \ | |
383 | R gcc_c_plugin::N (A a, B b, C c, D d) const \ | |
384 | { return FORWARD (N, a, b, c, d); } | |
385 | #define GCC_METHOD5(R, N, A, B, C, D, E) \ | |
386 | R gcc_c_plugin::N (A a, B b, C c, D d, E e) const \ | |
387 | { return FORWARD (N, a, b, c, d, e); } | |
388 | #define GCC_METHOD7(R, N, A, B, C, D, E, F, G) \ | |
389 | R gcc_c_plugin::N (A a, B b, C c, D d, E e, F f, G g) const \ | |
390 | { return FORWARD (N, a, b, c, d, e, f, g); } | |
391 | ||
392 | #include "gcc-c-fe.def" | |
393 | ||
394 | #undef GCC_METHOD0 | |
395 | #undef GCC_METHOD1 | |
396 | #undef GCC_METHOD2 | |
397 | #undef GCC_METHOD3 | |
398 | #undef GCC_METHOD4 | |
399 | #undef GCC_METHOD5 | |
400 | #undef GCC_METHOD7 | |
401 | #undef FORWARD |