Commit | Line | Data |
---|---|---|
bb2ec1b3 TT |
1 | /* Convert types from GDB to GCC |
2 | ||
42a4f53d | 3 | Copyright (C) 2014-2019 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; | |
43 | struct type *range = TYPE_INDEX_TYPE (type); | |
44 | ||
9cdfd9a2 | 45 | element_type = context->convert_type (TYPE_TARGET_TYPE (type)); |
bb2ec1b3 TT |
46 | |
47 | if (TYPE_LOW_BOUND_KIND (range) != PROP_CONST) | |
9cdfd9a2 | 48 | return context->plugin ().error (_("array type with non-constant" |
18cdc6d8 | 49 | " lower bound is not supported")); |
bb2ec1b3 | 50 | if (TYPE_LOW_BOUND (range) != 0) |
9cdfd9a2 | 51 | return context->plugin ().error (_("cannot convert array type with " |
18cdc6d8 | 52 | "non-zero lower bound to C")); |
bb2ec1b3 TT |
53 | |
54 | if (TYPE_HIGH_BOUND_KIND (range) == PROP_LOCEXPR | |
55 | || TYPE_HIGH_BOUND_KIND (range) == PROP_LOCLIST) | |
56 | { | |
57 | gcc_type result; | |
bb2ec1b3 TT |
58 | |
59 | if (TYPE_VECTOR (type)) | |
9cdfd9a2 | 60 | return context->plugin ().error (_("variably-sized vector type" |
18cdc6d8 | 61 | " is not supported")); |
bb2ec1b3 | 62 | |
8f84fb0e TT |
63 | std::string upper_bound |
64 | = c_get_range_decl_name (&TYPE_RANGE_DATA (range)->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 | ||
73 | if (get_array_bounds (type, &low_bound, &high_bound) == 0) | |
74 | count = -1; | |
75 | else | |
76 | { | |
77 | gdb_assert (low_bound == 0); /* Ensured above. */ | |
78 | count = high_bound + 1; | |
79 | } | |
80 | ||
81 | if (TYPE_VECTOR (type)) | |
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. */ | |
97 | if (TYPE_CODE (type) == TYPE_CODE_STRUCT) | |
9cdfd9a2 | 98 | result = context->plugin ().build_record_type (); |
bb2ec1b3 TT |
99 | else |
100 | { | |
101 | gdb_assert (TYPE_CODE (type) == TYPE_CODE_UNION); | |
9cdfd9a2 | 102 | result = context->plugin ().build_union_type (); |
bb2ec1b3 | 103 | } |
9cdfd9a2 | 104 | context->insert_type (type, result); |
bb2ec1b3 TT |
105 | |
106 | for (i = 0; i < TYPE_NFIELDS (type); ++i) | |
107 | { | |
108 | gcc_type field_type; | |
109 | unsigned long bitsize = TYPE_FIELD_BITSIZE (type, i); | |
110 | ||
9cdfd9a2 | 111 | field_type = context->convert_type (TYPE_FIELD_TYPE (type, i)); |
bb2ec1b3 TT |
112 | if (bitsize == 0) |
113 | bitsize = 8 * TYPE_LENGTH (TYPE_FIELD_TYPE (type, i)); | |
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 | |
9cdfd9a2 KS |
133 | int_type = context->plugin ().int_type_v0 (TYPE_UNSIGNED (type), |
134 | TYPE_LENGTH (type)); | |
bb2ec1b3 | 135 | |
9cdfd9a2 | 136 | result = context->plugin ().build_enum_type (int_type); |
bb2ec1b3 TT |
137 | for (i = 0; i < TYPE_NFIELDS (type); ++i) |
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; | |
156 | int is_varargs = TYPE_VARARGS (type) || !TYPE_PROTOTYPED (type); | |
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 TT |
177 | |
178 | array.n_elements = TYPE_NFIELDS (type); | |
179 | array.elements = XNEWVEC (gcc_type, TYPE_NFIELDS (type)); | |
180 | for (i = 0; i < TYPE_NFIELDS (type); ++i) | |
9cdfd9a2 | 181 | array.elements[i] = context->convert_type (TYPE_FIELD_TYPE (type, i)); |
bb2ec1b3 | 182 | |
9cdfd9a2 | 183 | result = context->plugin ().build_function_type (return_type, |
18cdc6d8 | 184 | &array, is_varargs); |
bb2ec1b3 TT |
185 | xfree (array.elements); |
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 AO |
196 | { |
197 | if (TYPE_NOSIGN (type)) | |
198 | { | |
199 | gdb_assert (TYPE_LENGTH (type) == 1); | |
9cdfd9a2 | 200 | return context->plugin ().char_type (); |
476d250e | 201 | } |
9cdfd9a2 | 202 | return context->plugin ().int_type (TYPE_UNSIGNED (type), |
18cdc6d8 KS |
203 | TYPE_LENGTH (type), |
204 | TYPE_NAME (type)); | |
476d250e AO |
205 | } |
206 | else | |
9cdfd9a2 | 207 | return context->plugin ().int_type_v0 (TYPE_UNSIGNED (type), |
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), | |
18cdc6d8 | 218 | TYPE_NAME (type)); |
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 | ||
9cdfd9a2 | 257 | return context->plugin ().build_qualified_type (unqual_converted, quals); |
bb2ec1b3 TT |
258 | } |
259 | ||
260 | /* Convert a complex type to its gcc representation. */ | |
261 | ||
262 | static gcc_type | |
9cdfd9a2 | 263 | convert_complex (compile_c_instance *context, struct type *type) |
bb2ec1b3 | 264 | { |
9cdfd9a2 | 265 | gcc_type base = context->convert_type (TYPE_TARGET_TYPE (type)); |
bb2ec1b3 | 266 | |
9cdfd9a2 | 267 | return context->plugin ().build_complex_type (base); |
bb2ec1b3 TT |
268 | } |
269 | ||
270 | /* A helper function which knows how to convert most types from their | |
271 | gdb representation to the corresponding gcc form. This examines | |
272 | the TYPE and dispatches to the appropriate conversion function. It | |
273 | returns the gcc type. */ | |
274 | ||
275 | static gcc_type | |
9cdfd9a2 | 276 | convert_type_basic (compile_c_instance *context, struct type *type) |
bb2ec1b3 TT |
277 | { |
278 | /* If we are converting a qualified type, first convert the | |
279 | unqualified type and then apply the qualifiers. */ | |
280 | if ((TYPE_INSTANCE_FLAGS (type) & (TYPE_INSTANCE_FLAG_CONST | |
281 | | TYPE_INSTANCE_FLAG_VOLATILE | |
282 | | TYPE_INSTANCE_FLAG_RESTRICT)) != 0) | |
283 | return convert_qualified (context, type); | |
284 | ||
285 | switch (TYPE_CODE (type)) | |
286 | { | |
287 | case TYPE_CODE_PTR: | |
288 | return convert_pointer (context, type); | |
289 | ||
290 | case TYPE_CODE_ARRAY: | |
291 | return convert_array (context, type); | |
292 | ||
293 | case TYPE_CODE_STRUCT: | |
294 | case TYPE_CODE_UNION: | |
295 | return convert_struct_or_union (context, type); | |
296 | ||
297 | case TYPE_CODE_ENUM: | |
298 | return convert_enum (context, type); | |
299 | ||
300 | case TYPE_CODE_FUNC: | |
301 | return convert_func (context, type); | |
302 | ||
303 | case TYPE_CODE_INT: | |
304 | return convert_int (context, type); | |
305 | ||
306 | case TYPE_CODE_FLT: | |
307 | return convert_float (context, type); | |
308 | ||
309 | case TYPE_CODE_VOID: | |
310 | return convert_void (context, type); | |
311 | ||
312 | case TYPE_CODE_BOOL: | |
313 | return convert_bool (context, type); | |
314 | ||
315 | case TYPE_CODE_COMPLEX: | |
316 | return convert_complex (context, type); | |
46a4882b PA |
317 | |
318 | case TYPE_CODE_ERROR: | |
319 | { | |
320 | /* Ideally, if we get here due to a cast expression, we'd use | |
321 | the cast-to type as the variable's type, like GDB's | |
322 | built-in parser does. For now, assume "int" like GDB's | |
323 | built-in parser used to do, but at least warn. */ | |
324 | struct type *fallback; | |
325 | if (TYPE_OBJFILE_OWNED (type)) | |
326 | fallback = objfile_type (TYPE_OWNER (type).objfile)->builtin_int; | |
327 | else | |
328 | fallback = builtin_type (TYPE_OWNER (type).gdbarch)->builtin_int; | |
329 | warning (_("variable has unknown type; assuming int")); | |
330 | return convert_int (context, fallback); | |
331 | } | |
bb2ec1b3 TT |
332 | } |
333 | ||
9cdfd9a2 | 334 | return context->plugin ().error (_("cannot convert gdb type to gcc type")); |
bb2ec1b3 TT |
335 | } |
336 | ||
9cdfd9a2 KS |
337 | /* Default compile flags for C. */ |
338 | ||
339 | const char *compile_c_instance::m_default_cflags = "-std=gnu11" | |
340 | /* Otherwise the .o file may need | |
341 | "_Unwind_Resume" and | |
342 | "__gcc_personality_v0". */ | |
343 | " -fno-exceptions" | |
344 | " -Wno-implicit-function-declaration"; | |
345 | ||
346 | /* See compile-c.h. */ | |
bb2ec1b3 TT |
347 | |
348 | gcc_type | |
9cdfd9a2 | 349 | compile_c_instance::convert_type (struct type *type) |
bb2ec1b3 | 350 | { |
bb2ec1b3 TT |
351 | /* We don't ever have to deal with typedefs in this code, because |
352 | those are only needed as symbols by the C compiler. */ | |
f168693b | 353 | type = check_typedef (type); |
bb2ec1b3 | 354 | |
9cdfd9a2 | 355 | gcc_type result; |
d82b3862 | 356 | if (get_cached_type (type, &result)) |
9cdfd9a2 | 357 | return result; |
bb2ec1b3 | 358 | |
9cdfd9a2 KS |
359 | result = convert_type_basic (this, type); |
360 | insert_type (type, result); | |
bb2ec1b3 TT |
361 | return result; |
362 | } | |
363 | ||
364 | \f | |
365 | ||
18cdc6d8 KS |
366 | /* C plug-in wrapper. */ |
367 | ||
368 | #define FORWARD(OP,...) m_context->c_ops->OP(m_context, ##__VA_ARGS__) | |
369 | #define GCC_METHOD0(R, N) \ | |
370 | R gcc_c_plugin::N () const \ | |
371 | { return FORWARD (N); } | |
372 | #define GCC_METHOD1(R, N, A) \ | |
373 | R gcc_c_plugin::N (A a) const \ | |
374 | { return FORWARD (N, a); } | |
375 | #define GCC_METHOD2(R, N, A, B) \ | |
376 | R gcc_c_plugin::N (A a, B b) const \ | |
377 | { return FORWARD (N, a, b); } | |
378 | #define GCC_METHOD3(R, N, A, B, C) \ | |
379 | R gcc_c_plugin::N (A a, B b, C c) const \ | |
380 | { return FORWARD (N, a, b, c); } | |
381 | #define GCC_METHOD4(R, N, A, B, C, D) \ | |
382 | R gcc_c_plugin::N (A a, B b, C c, D d) const \ | |
383 | { return FORWARD (N, a, b, c, d); } | |
384 | #define GCC_METHOD5(R, N, A, B, C, D, E) \ | |
385 | R gcc_c_plugin::N (A a, B b, C c, D d, E e) const \ | |
386 | { return FORWARD (N, a, b, c, d, e); } | |
387 | #define GCC_METHOD7(R, N, A, B, C, D, E, F, G) \ | |
388 | R gcc_c_plugin::N (A a, B b, C c, D d, E e, F f, G g) const \ | |
389 | { return FORWARD (N, a, b, c, d, e, f, g); } | |
390 | ||
391 | #include "gcc-c-fe.def" | |
392 | ||
393 | #undef GCC_METHOD0 | |
394 | #undef GCC_METHOD1 | |
395 | #undef GCC_METHOD2 | |
396 | #undef GCC_METHOD3 | |
397 | #undef GCC_METHOD4 | |
398 | #undef GCC_METHOD5 | |
399 | #undef GCC_METHOD7 | |
400 | #undef FORWARD |