Line data Source code
1 : // Copyright (C) 2020-2026 Free Software Foundation, Inc.
2 :
3 : // This file is part of GCC.
4 :
5 : // GCC is free software; you can redistribute it and/or modify it under
6 : // the terms of the GNU General Public License as published by the Free
7 : // Software Foundation; either version 3, or (at your option) any later
8 : // version.
9 :
10 : // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11 : // WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 : // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 : // for more details.
14 :
15 : // You should have received a copy of the GNU General Public License
16 : // along with GCC; see the file COPYING3. If not see
17 : // <http://www.gnu.org/licenses/>.
18 :
19 : #include "rust-compile-type.h"
20 : #include "rust-type-util.h"
21 :
22 : #include "rust-tyty.h"
23 : #include "tree.h"
24 : #include "fold-const.h"
25 : #include "stor-layout.h"
26 :
27 : namespace Rust {
28 : namespace Compile {
29 :
30 : static const std::string RUST_ENUM_DISR_FIELD_NAME = "RUST$ENUM$DISR";
31 :
32 : static bool
33 61999 : type_reaches_adt (TyTy::BaseType *type, DefId target, bool indirect,
34 : std::set<std::pair<DefId, bool>> &visited)
35 : {
36 63165 : type = type->destructure ();
37 63165 : switch (type->get_kind ())
38 : {
39 405 : case TyTy::TypeKind::POINTER:
40 405 : return type_reaches_adt (
41 : static_cast<TyTy::PointerType *> (type)->get_base (), target, true,
42 405 : visited);
43 :
44 231 : case TyTy::TypeKind::REF:
45 231 : return type_reaches_adt (
46 : static_cast<TyTy::ReferenceType *> (type)->get_base (), target, true,
47 231 : visited);
48 :
49 : case TyTy::TypeKind::TUPLE:
50 : {
51 : auto *tuple = static_cast<TyTy::TupleType *> (type);
52 240 : for (size_t i = 0; i < tuple->num_fields (); i++)
53 : {
54 95 : if (type_reaches_adt (tuple->get_field (i), target, indirect,
55 : visited))
56 : return true;
57 : }
58 : return false;
59 : }
60 :
61 484 : case TyTy::TypeKind::ARRAY:
62 484 : return type_reaches_adt (
63 : static_cast<TyTy::ArrayType *> (type)->get_element_type (), target,
64 484 : indirect, visited);
65 :
66 47 : case TyTy::TypeKind::FNPTR:
67 47 : {
68 47 : auto *fn = static_cast<TyTy::FnPtr *> (type);
69 79 : for (const auto ¶m : fn->get_params ())
70 : {
71 33 : if (type_reaches_adt (param.get_tyty (), target, true, visited))
72 61999 : return true;
73 : }
74 :
75 46 : return type_reaches_adt (fn->get_return_type (), target, true, visited);
76 : }
77 :
78 26452 : case TyTy::TypeKind::ADT:
79 26452 : break;
80 :
81 : default:
82 : return false;
83 : }
84 :
85 26452 : auto *adt = static_cast<TyTy::ADTType *> (type);
86 48968 : if (adt->get_id () == target && indirect)
87 19 : return true;
88 :
89 26433 : auto key = std::make_pair (adt->get_id (), indirect);
90 26433 : bool found = visited.find (key) != visited.end ();
91 26433 : if (found)
92 : return false;
93 26199 : visited.insert (key);
94 :
95 64754 : for (auto *variant : adt->get_variants ())
96 : {
97 77939 : for (auto *field : variant->get_fields ())
98 : {
99 39384 : if (type_reaches_adt (field->get_field_type (), target, indirect,
100 : visited))
101 61999 : return true;
102 : }
103 : }
104 :
105 : return false;
106 : }
107 :
108 : static bool
109 22487 : is_recursive_adt (const TyTy::ADTType &type)
110 : {
111 22487 : std::set<std::pair<DefId, bool>> visited;
112 22487 : return type_reaches_adt (const_cast<TyTy::ADTType *> (&type), type.get_id (),
113 22487 : false, visited);
114 22487 : }
115 :
116 339975 : TyTyResolveCompile::TyTyResolveCompile (Context *ctx, bool trait_object_mode)
117 339975 : : ctx (ctx), trait_object_mode (trait_object_mode),
118 339975 : translated (error_mark_node)
119 339975 : {}
120 :
121 : tree
122 339975 : TyTyResolveCompile::compile (Context *ctx, const TyTy::BaseType *ty,
123 : bool trait_object_mode)
124 : {
125 339975 : TyTyResolveCompile compiler (ctx, trait_object_mode);
126 339975 : const TyTy::BaseType *destructured = ty->destructure ();
127 :
128 339975 : if (const auto *adt = destructured->try_as<const TyTy::ADTType> ())
129 : {
130 22525 : tree compiled_adt = NULL_TREE;
131 22525 : if (ctx->lookup_compiled_adt (*adt, &compiled_adt))
132 38 : return compiled_adt;
133 : }
134 :
135 339937 : destructured->accept_vis (compiler);
136 :
137 339937 : if (compiler.translated != error_mark_node
138 339937 : && TYPE_NAME (compiler.translated) != NULL)
139 : {
140 : // canonicalize the type
141 294014 : compiler.translated = ctx->insert_compiled_type (compiler.translated);
142 : }
143 :
144 339937 : return compiler.translated;
145 : }
146 :
147 : // see: gcc/c/c-decl.cc:8230-8241
148 : // https://github.com/Rust-GCC/gccrs/blob/0024bc2f028369b871a65ceb11b2fddfb0f9c3aa/gcc/c/c-decl.c#L8229-L8241
149 : tree
150 6752 : TyTyResolveCompile::get_implicit_enumeral_node_type (TyTy::BaseType *repr)
151 : {
152 : // static tree enum_node = NULL_TREE;
153 : // if (enum_node == NULL_TREE)
154 : // {
155 : // enum_node = make_node (ENUMERAL_TYPE);
156 : // SET_TYPE_MODE (enum_node, TYPE_MODE (unsigned_type_node));
157 : // SET_TYPE_ALIGN (enum_node, TYPE_ALIGN (unsigned_type_node));
158 : // TYPE_USER_ALIGN (enum_node) = 0;
159 : // TYPE_UNSIGNED (enum_node) = 1;
160 : // TYPE_PRECISION (enum_node) = TYPE_PRECISION (unsigned_type_node);
161 : // TYPE_MIN_VALUE (enum_node) = TYPE_MIN_VALUE (unsigned_type_node);
162 : // TYPE_MAX_VALUE (enum_node) = TYPE_MAX_VALUE (unsigned_type_node);
163 :
164 : // // tree identifier = ctx->get_backend ()->get_identifier_node
165 : // // ("enumeral"); tree enum_decl
166 : // // = build_decl (BUILTINS_LOCATION, TYPE_DECL, identifier,
167 : // enum_node);
168 : // // TYPE_NAME (enum_node) = enum_decl;
169 : // }
170 : // return enum_node;
171 :
172 6752 : return compile (ctx, repr);
173 : }
174 :
175 : tree
176 33141 : TyTyResolveCompile::get_unit_type (Context *ctx)
177 : {
178 33141 : static tree unit_type;
179 33141 : if (unit_type == nullptr)
180 : {
181 4742 : auto cn = ctx->get_mappings ().crate.get_current_crate ();
182 4742 : auto &c = ctx->get_mappings ().crate.get_ast_crate (cn);
183 4742 : location_t locus = BUILTINS_LOCATION;
184 4742 : if (c.items.size () > 0)
185 : {
186 4736 : auto &item = c.items[0];
187 4736 : locus = item->get_locus ();
188 : }
189 :
190 4742 : auto unit_type_node = Backend::struct_type ({});
191 4742 : unit_type = Backend::named_type ("()", unit_type_node, locus);
192 : }
193 33141 : return unit_type;
194 : }
195 :
196 : void
197 0 : TyTyResolveCompile::visit (const TyTy::ErrorType &)
198 : {
199 0 : translated = error_mark_node;
200 0 : }
201 :
202 : void
203 617 : TyTyResolveCompile::visit (const TyTy::InferType &type)
204 : {
205 617 : const TyTy::BaseType *orig = &type;
206 617 : TyTy::BaseType *lookup = nullptr;
207 617 : bool ok = ctx->get_tyctx ()->lookup_type (type.get_ref (), &lookup);
208 617 : if (!ok)
209 : {
210 0 : translated = error_mark_node;
211 7 : return;
212 : }
213 :
214 617 : if (orig == lookup)
215 : {
216 7 : TyTy::BaseType *def = nullptr;
217 7 : if (type.default_type (&def))
218 : {
219 7 : translated = TyTyResolveCompile::compile (ctx, def);
220 7 : return;
221 : }
222 :
223 0 : translated = error_mark_node;
224 0 : return;
225 : }
226 :
227 610 : translated = TyTyResolveCompile::compile (ctx, lookup);
228 : }
229 :
230 : void
231 1 : TyTyResolveCompile::visit (const TyTy::ParamType &type)
232 : {
233 1 : translated = error_mark_node;
234 1 : }
235 :
236 : void
237 0 : TyTyResolveCompile::visit (const TyTy::ConstParamType &type)
238 : {
239 0 : translated = error_mark_node;
240 0 : }
241 :
242 : void
243 0 : TyTyResolveCompile::visit (const TyTy::ConstValueType &type)
244 : {
245 0 : translated = error_mark_node;
246 0 : }
247 :
248 : void
249 0 : TyTyResolveCompile::visit (const TyTy::ConstInferType &type)
250 : {
251 0 : translated = error_mark_node;
252 0 : }
253 :
254 : void
255 0 : TyTyResolveCompile::visit (const TyTy::ConstErrorType &type)
256 : {
257 0 : translated = error_mark_node;
258 0 : }
259 :
260 : void
261 378 : TyTyResolveCompile::visit (const TyTy::ProjectionType &type)
262 : {
263 : // workaround to get around const here
264 378 : TyTy::ProjectionType *projection
265 378 : = static_cast<TyTy::ProjectionType *> (type.clone ());
266 378 : auto normalized
267 378 : = Resolver::normalize_projection (projection, BUILTINS_LOCATION, false,
268 : false);
269 378 : if (normalized == projection)
270 : {
271 0 : translated = error_mark_node;
272 0 : return;
273 : }
274 :
275 378 : translated = TyTyResolveCompile::compile (ctx, normalized, false);
276 : }
277 :
278 : void
279 0 : TyTyResolveCompile::visit (const TyTy::PlaceholderType &type)
280 : {
281 0 : translated = error_mark_node;
282 0 : }
283 :
284 : void
285 243 : TyTyResolveCompile::visit (const TyTy::ClosureType &type)
286 : {
287 243 : auto &mappings = ctx->get_mappings ();
288 :
289 243 : std::vector<Backend::typed_identifier> fields;
290 :
291 243 : size_t i = 0;
292 334 : for (const auto &capture : type.get_captures ())
293 : {
294 : // lookup the HirId
295 91 : tl::optional<HirId> hid = mappings.lookup_node_to_hir (capture);
296 91 : rust_assert (hid.has_value ());
297 91 : auto ref = hid.value ();
298 :
299 : // lookup the var decl type
300 91 : TyTy::BaseType *lookup = nullptr;
301 91 : bool found = ctx->get_tyctx ()->lookup_type (ref, &lookup);
302 91 : rust_assert (found);
303 :
304 : // FIXME get the var pattern name
305 91 : std::string mappings_name = "capture_" + std::to_string (i);
306 :
307 : // FIXME
308 : // this should be based on the closure move-ability
309 91 : tree decl_type = TyTyResolveCompile::compile (ctx, lookup);
310 91 : tree capture_type = build_reference_type (decl_type);
311 91 : fields.emplace_back (mappings_name, capture_type,
312 91 : type.get_ident ().locus);
313 91 : }
314 :
315 243 : tree type_record = Backend::struct_type (fields);
316 243 : RS_CLOSURE_FLAG (type_record) = 1;
317 :
318 243 : std::string named_struct_str
319 486 : = type.get_ident ().path.get () + "::{{closure}}";
320 243 : translated = Backend::named_type (named_struct_str, type_record,
321 243 : type.get_ident ().locus);
322 243 : }
323 :
324 : void
325 19026 : TyTyResolveCompile::visit (const TyTy::FnType &type)
326 : {
327 19026 : Backend::typed_identifier receiver ("", NULL_TREE, UNKNOWN_LOCATION);
328 19026 : std::vector<Backend::typed_identifier> parameters;
329 19026 : std::vector<Backend::typed_identifier> results;
330 :
331 : // we can only return unit-type if its not the C ABI because it will expect
332 : // void
333 19026 : auto hir_type = type.get_return_type ()->destructure ();
334 19026 : bool return_is_unit = hir_type->is_unit ();
335 19026 : bool is_c_abi = type.get_abi () == ABI::C;
336 19026 : bool should_be_void = is_c_abi && return_is_unit;
337 19026 : if (!should_be_void)
338 : {
339 17925 : auto ret = TyTyResolveCompile::compile (ctx, hir_type, trait_object_mode);
340 17925 : location_t return_type_locus
341 17925 : = ctx->get_mappings ().lookup_location (hir_type->get_ref ());
342 17925 : results.emplace_back ("_", ret, return_type_locus);
343 : }
344 :
345 38391 : for (auto ¶m_pair : type.get_params ())
346 : {
347 19365 : auto param_tyty = param_pair.get_type ();
348 19365 : auto compiled_param_type
349 19365 : = TyTyResolveCompile::compile (ctx, param_tyty, trait_object_mode);
350 :
351 19365 : parameters.emplace_back (param_pair.get_pattern ().to_string (),
352 : compiled_param_type,
353 38730 : ctx->get_mappings ().lookup_location (
354 : param_tyty->get_ref ()));
355 : }
356 :
357 19026 : if (!type.is_variadic ())
358 36286 : translated = Backend::function_type (receiver, parameters, results, NULL,
359 18143 : type.get_ident ().locus);
360 : else
361 883 : translated
362 883 : = Backend::function_type_variadic (receiver, parameters, results, NULL,
363 883 : type.get_ident ().locus);
364 19026 : }
365 :
366 : void
367 112 : TyTyResolveCompile::visit (const TyTy::FnPtr &type)
368 : {
369 112 : tree result_type = TyTyResolveCompile::compile (ctx, type.get_return_type ());
370 :
371 112 : std::vector<tree> parameters;
372 :
373 112 : auto ¶ms = type.get_params ();
374 204 : for (auto &p : params)
375 : {
376 92 : tree pty = TyTyResolveCompile::compile (ctx, p.get_tyty ());
377 92 : parameters.push_back (pty);
378 : }
379 :
380 112 : translated = Backend::function_ptr_type (result_type, parameters,
381 112 : type.get_ident ().locus);
382 112 : }
383 :
384 : void
385 22487 : TyTyResolveCompile::visit (const TyTy::ADTType &type)
386 : {
387 22487 : tree type_record = error_mark_node;
388 :
389 22487 : TyTy::ADTType::ReprOptions repr = type.get_repr_options ();
390 22487 : bool cached_incomplete_record = false;
391 :
392 22487 : if (is_recursive_adt (type)
393 19 : && repr.repr_kind != TyTy::ADTType::ReprKind::TRANSPARENT
394 22506 : && repr.repr_kind != TyTy::ADTType::ReprKind::SIMD)
395 : {
396 38 : tree aggregate = make_node (type.is_union () ? UNION_TYPE : RECORD_TYPE);
397 19 : std::string name
398 19 : = type.get_ident ().path.get () + type.subst_as_string ();
399 :
400 19 : tree decl = build_decl (type.get_ident ().locus, TYPE_DECL,
401 : Backend::get_identifier_node (name), aggregate);
402 19 : TYPE_NAME (aggregate) = decl;
403 19 : type_record = aggregate;
404 19 : ctx->insert_compiled_adt (type, type_record);
405 19 : cached_incomplete_record = true;
406 19 : }
407 :
408 22487 : if (repr.repr_kind == TyTy::ADTType::ReprKind::TRANSPARENT)
409 : {
410 90 : rust_assert (type.number_of_variants () == 1);
411 90 : TyTy::VariantDef &variant = *type.get_variants ().at (0);
412 :
413 90 : if (variant.num_fields () == 0)
414 : {
415 : // 0-field transparent repr
416 : // Rustonomicon states that transparent structs should have a single
417 : // non-zero-sized field, but rustc compiles one with 0 fields happily
418 : // without errors, so not sure what's the correct treatment.
419 : //
420 : // For now, treat it as a unit struct
421 0 : type_record = Backend::struct_type ({});
422 : }
423 90 : else if (variant.num_fields () == 1)
424 : {
425 : // single field transparent repr
426 90 : const TyTy::StructFieldType *field = variant.get_field_at_index (0);
427 90 : type_record
428 90 : = TyTyResolveCompile::compile (ctx, field->get_field_type ());
429 : }
430 : else
431 : {
432 : // more than one field - typechecking already ensures there's only one
433 : // non-zero-sized field, just compile accessor for that
434 : // non-zero-sized.
435 0 : for (size_t i = 0; i < variant.num_fields (); i++)
436 : {
437 0 : auto field_ty = variant.get_field_at_index (i)->get_field_type ();
438 0 : if (!field_ty->is_zero_sized ())
439 : {
440 0 : type_record = TyTyResolveCompile::compile (ctx, field_ty);
441 : }
442 : }
443 : }
444 : }
445 22397 : else if (repr.repr_kind == TyTy::ADTType::ReprKind::SIMD)
446 : {
447 16 : TyTy::VariantDef &variant = *type.get_variants ().at (0);
448 16 : auto element = variant.get_fields ().at (0)->get_field_type ();
449 16 : auto inner_type = compile (ctx, element);
450 :
451 16 : type_record = build_vector_type (inner_type, variant.num_fields ());
452 : }
453 22381 : else if (type.get_adt_kind () == TyTy::ADTType::ADTKind::EXTERN)
454 : {
455 : // Extern types are codegen'd as C's void type. They can only be used
456 : // through indirection, so they're effectively always codegen'd as
457 : // `void *` types.
458 6 : type_record = void_type_node;
459 : }
460 22375 : else if (!type.is_enum ())
461 : {
462 15623 : rust_assert (type.number_of_variants () == 1);
463 :
464 15623 : TyTy::VariantDef &variant = *type.get_variants ().at (0);
465 15623 : std::vector<Backend::typed_identifier> fields;
466 43192 : for (size_t i = 0; i < variant.num_fields (); i++)
467 : {
468 27569 : const TyTy::StructFieldType *field = variant.get_field_at_index (i);
469 27569 : tree compiled_field_ty
470 27569 : = TyTyResolveCompile::compile (ctx, field->get_field_type ());
471 :
472 27569 : fields.emplace_back (field->get_name (), compiled_field_ty,
473 55138 : ctx->get_mappings ().lookup_location (
474 : type.get_ty_ref ()));
475 : }
476 :
477 15623 : if (!type.is_union () && variant.num_fields () > 0)
478 : {
479 13242 : const TyTy::StructFieldType *tail_field
480 13242 : = variant.get_field_at_index (variant.num_fields () - 1);
481 13242 : TyTy::BaseType *tail_ty = tail_field->get_field_type ();
482 :
483 13242 : if (tail_ty->is_unsized ())
484 : {
485 57 : tree raw_dst_type = error_mark_node;
486 :
487 57 : if (tail_ty->get_kind () == TyTy::TypeKind::SLICE)
488 : {
489 40 : auto slice = static_cast<TyTy::SliceType *> (tail_ty);
490 40 : tree elem_type
491 40 : = TyTyResolveCompile::compile (ctx,
492 40 : slice->get_element_type ());
493 40 : raw_dst_type = build_array_type (elem_type, NULL_TREE);
494 : }
495 17 : else if (tail_ty->get_kind () == TyTy::TypeKind::DYNAMIC)
496 : {
497 10 : raw_dst_type = make_node (RECORD_TYPE);
498 10 : TYPE_SIZE (raw_dst_type) = bitsize_zero_node;
499 10 : TYPE_SIZE_UNIT (raw_dst_type) = size_zero_node;
500 10 : layout_type (raw_dst_type);
501 : }
502 : else
503 : {
504 7 : raw_dst_type = fields.back ().type;
505 : }
506 57 : fields.pop_back ();
507 57 : fields.emplace_back (tail_field->get_name (), raw_dst_type,
508 114 : type.get_locus ());
509 : }
510 : }
511 15623 : if (cached_incomplete_record)
512 19 : type_record = Backend::fill_in_fields (type_record, fields, false);
513 : else
514 15604 : type_record = type.is_union () ? Backend::union_type (fields, false)
515 15384 : : Backend::struct_type (fields, false);
516 15623 : }
517 : else
518 : {
519 : // see:
520 : // https://github.com/bminor/binutils-gdb/blob/527b8861cd472385fa9160a91dd6d65a25c41987/gdb/dwarf2/read.c#L9010-L9241
521 : //
522 : // enums are actually a big union so for example the rust enum:
523 : //
524 : // enum AnEnum {
525 : // A,
526 : // B,
527 : // C (char),
528 : // D { x: i64, y: i64 },
529 : // }
530 : //
531 : // we actually turn this into
532 : //
533 : // union {
534 : // struct A { int RUST$ENUM$DISR; }; <- this is a data-less variant
535 : // struct B { int RUST$ENUM$DISR; }; <- this is a data-less variant
536 : // struct C { int RUST$ENUM$DISR; char __0; };
537 : // struct D { int RUST$ENUM$DISR; i64 x; i64 y; };
538 : // }
539 : //
540 : // Ada, qual_union_types might still work for this but I am not 100% sure.
541 : // I ran into some issues lets reuse our normal union and ask Ada people
542 : // about it.
543 : //
544 : // I think the above is actually wrong and it should actually be this
545 : //
546 : // struct {
547 : // int RUST$ENUM$DISR; // take into account the repr for this TODO
548 : // union {
549 : // // Variant A
550 : // struct {
551 : // // No additional fields
552 : // } A;
553 :
554 : // // Variant B
555 : // struct {
556 : // // No additional fields
557 : // } B;
558 :
559 : // // Variant C
560 : // struct {
561 : // char c;
562 : // } C;
563 :
564 : // // Variant D
565 : // struct {
566 : // int64_t x;
567 : // int64_t y;
568 : // } D;
569 : // } payload; // The union of all variant data
570 : // };
571 :
572 6752 : std::vector<tree> variant_records;
573 23639 : for (auto &variant : type.get_variants ())
574 : {
575 16887 : std::vector<Backend::typed_identifier> fields;
576 23255 : for (size_t i = 0; i < variant->num_fields (); i++)
577 : {
578 6368 : const TyTy::StructFieldType *field
579 6368 : = variant->get_field_at_index (i);
580 6368 : tree compiled_field_ty
581 6368 : = TyTyResolveCompile::compile (ctx, field->get_field_type ());
582 :
583 6368 : std::string field_name = field->get_name ();
584 6368 : if (variant->get_variant_type ()
585 : == TyTy::VariantDef::VariantType::TUPLE)
586 4863 : field_name = "__" + field->get_name ();
587 :
588 12736 : fields.emplace_back (field_name, compiled_field_ty,
589 6368 : ctx->get_mappings ().lookup_location (
590 : type.get_ty_ref ()));
591 6368 : }
592 :
593 16887 : tree variant_record = Backend::struct_type (fields);
594 16887 : tree named_variant_record
595 16887 : = Backend::named_type (variant->get_ident ().path.get (),
596 33774 : variant_record, variant->get_ident ().locus);
597 :
598 : // add them to the list
599 16887 : variant_records.push_back (named_variant_record);
600 16887 : }
601 :
602 : // now we need to make the actual union, but first we need to make
603 : // named_type TYPE_DECL's out of the variants
604 :
605 6752 : size_t i = 0;
606 6752 : std::vector<Backend::typed_identifier> enum_fields;
607 23639 : for (auto &variant_record : variant_records)
608 : {
609 16887 : TyTy::VariantDef *variant = type.get_variants ().at (i++);
610 16887 : std::string implicit_variant_name = variant->get_identifier ();
611 :
612 33774 : enum_fields.emplace_back (implicit_variant_name, variant_record,
613 16887 : ctx->get_mappings ().lookup_location (
614 : type.get_ty_ref ()));
615 16887 : }
616 :
617 : //
618 6752 : location_t locus = ctx->get_mappings ().lookup_location (type.get_ref ());
619 :
620 : // finally make the union or the enum
621 6752 : tree variants_union = Backend::union_type (enum_fields, false);
622 6752 : layout_type (variants_union);
623 6752 : tree named_union_record
624 6752 : = Backend::named_type ("payload", variants_union, locus);
625 :
626 : // create the overall struct
627 6752 : tree enumeral_type = TyTyResolveCompile::get_implicit_enumeral_node_type (
628 6752 : type.get_repr_options ().repr);
629 6752 : Backend::typed_identifier discrim (RUST_ENUM_DISR_FIELD_NAME,
630 6752 : enumeral_type, locus);
631 6752 : Backend::typed_identifier variants_union_field ("payload",
632 : named_union_record,
633 6752 : locus);
634 :
635 6752 : std::vector<Backend::typed_identifier> fields
636 6752 : = {discrim, variants_union_field};
637 6752 : if (cached_incomplete_record)
638 0 : type_record = Backend::fill_in_fields (type_record, fields, false);
639 : else
640 6752 : type_record = Backend::struct_type (fields, false);
641 6752 : }
642 :
643 : // Handle repr options
644 : // TODO: "packed" should only narrow type alignment and "align" should only
645 : // widen it. Do we need to check and enforce this here, or is it taken care of
646 : // later on in the gcc middle-end?
647 22487 : if (repr.repr_kind != TyTy::ADTType::ReprKind::TRANSPARENT)
648 : {
649 22397 : if (repr.pack)
650 : {
651 10 : TYPE_PACKED (type_record) = 1;
652 10 : if (repr.pack > 1)
653 : {
654 5 : SET_TYPE_ALIGN (type_record, repr.pack * 8);
655 5 : TYPE_USER_ALIGN (type_record) = 1;
656 : }
657 : }
658 22387 : else if (repr.align)
659 : {
660 10 : SET_TYPE_ALIGN (type_record, repr.align * 8);
661 10 : TYPE_USER_ALIGN (type_record) = 1;
662 : }
663 22397 : layout_type (type_record);
664 : }
665 :
666 22487 : if (cached_incomplete_record)
667 : {
668 : // see gcc/c/c-decl.cc this sets up any incomplete variants of the tree
669 31 : for (tree variant = TYPE_NEXT_VARIANT (type_record); variant != NULL_TREE;
670 12 : variant = TYPE_NEXT_VARIANT (variant))
671 12 : TYPE_FIELDS (variant) = TYPE_FIELDS (type_record);
672 :
673 19 : translated = type_record;
674 : }
675 : else
676 : {
677 22468 : std::string named_struct_str
678 22468 : = type.get_ident ().path.get () + type.subst_as_string ();
679 22468 : translated = Backend::named_type (named_struct_str, type_record,
680 22468 : type.get_ident ().locus);
681 22468 : }
682 22487 : }
683 :
684 : void
685 18705 : TyTyResolveCompile::visit (const TyTy::TupleType &type)
686 : {
687 18705 : if (type.num_fields () == 0)
688 : {
689 16538 : translated = get_unit_type (ctx);
690 16538 : return;
691 : }
692 :
693 : // create implicit struct
694 2167 : std::vector<Backend::typed_identifier> fields;
695 6675 : for (size_t i = 0; i < type.num_fields (); i++)
696 : {
697 4508 : TyTy::BaseType *field = type.get_field (i);
698 4508 : tree compiled_field_ty = TyTyResolveCompile::compile (ctx, field);
699 :
700 : // rustc uses the convention __N, where N is an integer, to
701 : // name the fields of a tuple. We follow this as well,
702 : // because this is used by GDB. One further reason to prefer
703 : // this, rather than simply emitting the integer, is that this
704 : // approach makes it simpler to use a C-only debugger, or
705 : // GDB's C mode, when debugging Rust.
706 4508 : fields.emplace_back ("__" + std::to_string (i), compiled_field_ty,
707 9016 : ctx->get_mappings ().lookup_location (
708 : type.get_ty_ref ()));
709 : }
710 :
711 2167 : tree struct_type_record = Backend::struct_type (fields);
712 2167 : translated = Backend::named_type (type.get_name (), struct_type_record,
713 2167 : type.get_ident ().locus);
714 2167 : }
715 :
716 : void
717 4597 : TyTyResolveCompile::visit (const TyTy::ArrayType &type)
718 : {
719 4597 : tree element_type
720 4597 : = TyTyResolveCompile::compile (ctx, type.get_element_type ());
721 4597 : auto const_capacity = type.get_capacity ();
722 :
723 : // Check if capacity is a const type
724 4597 : if (const_capacity->get_kind () != TyTy::TypeKind::CONST)
725 : {
726 0 : rust_error_at (type.get_locus (), "array capacity is not a const type");
727 0 : translated = error_mark_node;
728 0 : return;
729 : }
730 :
731 4597 : auto *capacity_const = const_capacity->as_const_type ();
732 :
733 4597 : rust_assert (capacity_const->const_kind ()
734 : == TyTy::BaseConstType::ConstKind::Value);
735 4597 : auto &capacity_value = *static_cast<TyTy::ConstValueType *> (capacity_const);
736 4597 : auto folded_capacity_expr = capacity_value.get_value ();
737 :
738 : // build_index_type takes the maximum index, which is one less than
739 : // the length.
740 4597 : tree index_type_tree = build_index_type (
741 : fold_build2 (MINUS_EXPR, sizetype, folded_capacity_expr, size_one_node));
742 :
743 4597 : translated = build_array_type (element_type, index_type_tree, false);
744 : }
745 :
746 : void
747 252 : TyTyResolveCompile::visit (const TyTy::SliceType &type)
748 : {
749 252 : tree type_record = create_slice_type_record (type);
750 :
751 252 : std::string named_struct_str
752 504 : = std::string ("[") + type.get_element_type ()->get_name () + "]";
753 252 : translated = Backend::named_type (named_struct_str, type_record,
754 252 : type.get_ident ().locus);
755 252 : }
756 :
757 : void
758 11051 : TyTyResolveCompile::visit (const TyTy::BoolType &)
759 : {
760 11051 : translated
761 11051 : = Backend::named_type ("bool", boolean_type_node, BUILTINS_LOCATION);
762 11051 : }
763 :
764 : void
765 80351 : TyTyResolveCompile::visit (const TyTy::IntType &type)
766 : {
767 80351 : switch (type.get_int_kind ())
768 : {
769 10556 : case TyTy::IntType::I8:
770 10556 : translated = Backend::named_type ("i8", Backend::integer_type (false, 8),
771 : BUILTINS_LOCATION);
772 10556 : return;
773 :
774 5929 : case TyTy::IntType::I16:
775 5929 : translated
776 5929 : = Backend::named_type ("i16", Backend::integer_type (false, 16),
777 : BUILTINS_LOCATION);
778 5929 : return;
779 :
780 52293 : case TyTy::IntType::I32:
781 52293 : translated
782 52293 : = Backend::named_type ("i32", Backend::integer_type (false, 32),
783 : BUILTINS_LOCATION);
784 52293 : return;
785 :
786 6102 : case TyTy::IntType::I64:
787 6102 : translated
788 6102 : = Backend::named_type ("i64", Backend::integer_type (false, 64),
789 : BUILTINS_LOCATION);
790 6102 : return;
791 :
792 5471 : case TyTy::IntType::I128:
793 5471 : translated
794 5471 : = Backend::named_type ("i128", Backend::integer_type (false, 128),
795 : BUILTINS_LOCATION);
796 5471 : return;
797 : }
798 : }
799 :
800 : void
801 62001 : TyTyResolveCompile::visit (const TyTy::UintType &type)
802 : {
803 62001 : switch (type.get_uint_kind ())
804 : {
805 16553 : case TyTy::UintType::U8:
806 16553 : translated = Backend::named_type ("u8", Backend::integer_type (true, 8),
807 : BUILTINS_LOCATION);
808 16553 : return;
809 :
810 9967 : case TyTy::UintType::U16:
811 9967 : translated = Backend::named_type ("u16", Backend::integer_type (true, 16),
812 : BUILTINS_LOCATION);
813 9967 : return;
814 :
815 14912 : case TyTy::UintType::U32:
816 14912 : translated = Backend::named_type ("u32", Backend::integer_type (true, 32),
817 : BUILTINS_LOCATION);
818 14912 : return;
819 :
820 15272 : case TyTy::UintType::U64:
821 15272 : translated = Backend::named_type ("u64", Backend::integer_type (true, 64),
822 : BUILTINS_LOCATION);
823 15272 : return;
824 :
825 5297 : case TyTy::UintType::U128:
826 5297 : translated
827 5297 : = Backend::named_type ("u128", Backend::integer_type (true, 128),
828 : BUILTINS_LOCATION);
829 5297 : return;
830 : }
831 : }
832 :
833 : void
834 15646 : TyTyResolveCompile::visit (const TyTy::FloatType &type)
835 : {
836 15646 : switch (type.get_float_kind ())
837 : {
838 7614 : case TyTy::FloatType::F32:
839 7614 : translated = Backend::named_type ("f32", Backend::float_type (32),
840 : BUILTINS_LOCATION);
841 7614 : return;
842 :
843 8032 : case TyTy::FloatType::F64:
844 8032 : translated = Backend::named_type ("f64", Backend::float_type (64),
845 : BUILTINS_LOCATION);
846 8032 : return;
847 : }
848 : }
849 :
850 : void
851 38321 : TyTyResolveCompile::visit (const TyTy::USizeType &)
852 : {
853 38321 : translated
854 38321 : = Backend::named_type ("usize",
855 : Backend::integer_type (true,
856 : Backend::get_pointer_size ()),
857 : BUILTINS_LOCATION);
858 38321 : }
859 :
860 : void
861 19562 : TyTyResolveCompile::visit (const TyTy::ISizeType &)
862 : {
863 19562 : translated
864 19562 : = Backend::named_type ("isize",
865 : Backend::integer_type (false,
866 : Backend::get_pointer_size ()),
867 : BUILTINS_LOCATION);
868 19562 : }
869 :
870 : void
871 5728 : TyTyResolveCompile::visit (const TyTy::CharType &)
872 : {
873 5728 : translated
874 5728 : = Backend::named_type ("char", Backend::wchar_type (), BUILTINS_LOCATION);
875 5728 : }
876 :
877 : void
878 19502 : TyTyResolveCompile::visit (const TyTy::ReferenceType &type)
879 : {
880 19502 : const TyTy::SliceType *slice = nullptr;
881 19502 : const TyTy::StrType *str = nullptr;
882 19502 : const TyTy::DynamicObjectType *dyn = nullptr;
883 19502 : const TyTy::ADTType *adt = nullptr;
884 19502 : if (type.is_dyn_slice_type (&slice))
885 : {
886 625 : tree type_record = create_slice_type_record (*slice);
887 625 : std::string dyn_slice_type_str
888 1874 : = std::string (type.is_mutable () ? "&mut " : "&") + "["
889 1875 : + slice->get_element_type ()->get_name () + "]";
890 :
891 625 : translated = Backend::named_type (dyn_slice_type_str, type_record,
892 : slice->get_locus ());
893 :
894 625 : return;
895 625 : }
896 18877 : else if (type.is_dyn_str_type (&str))
897 : {
898 4162 : tree type_record = create_str_type_record (*str);
899 4162 : std::string dyn_str_type_str
900 12486 : = std::string (type.is_mutable () ? "&mut " : "&") + "str";
901 :
902 4162 : translated = Backend::named_type (dyn_str_type_str, type_record,
903 : str->get_locus ());
904 :
905 4162 : return;
906 4162 : }
907 14715 : else if (type.is_dyn_obj_type (&dyn))
908 : {
909 526 : tree type_record = create_dyn_obj_record (*dyn);
910 526 : std::string dyn_str_type_str
911 1052 : = std::string (type.is_mutable () ? "&mut " : "& ") + dyn->get_name ();
912 :
913 526 : translated = Backend::named_type (dyn_str_type_str, type_record,
914 : dyn->get_locus ());
915 :
916 526 : return;
917 526 : }
918 14189 : else if (type.is_dyn_adt_type (&adt))
919 : {
920 76 : tree type_record = create_dyn_adt_record (*adt);
921 76 : std::string dyn_str_type_str
922 152 : = std::string (type.is_mutable () ? "&mut" : "& ") + adt->get_name ();
923 :
924 76 : translated = Backend::named_type (dyn_str_type_str, type_record,
925 : adt->get_locus ());
926 76 : return;
927 76 : }
928 : // Check for CStr, create a specific record for it
929 14113 : else if (type.is_dyn_cstr_type (&adt))
930 : {
931 : // CStr in core crate is defined as the following:
932 : //
933 : // #[repr(transparent)]
934 : // pub struct CStr {
935 : // inner: [u8]
936 : // }
937 : //
938 : // Reuse the c_char (u8) slice fat-pointer layout
939 0 : TyTy::BaseType *u8 = nullptr;
940 0 : ctx->get_tyctx ()->lookup_builtin ("u8", &u8);
941 : // Create a synthetic SliceType over u8 and use that record layout
942 0 : TyTy::SliceType synthetic_slice (adt->get_ref (), adt->get_ident ().locus,
943 0 : TyTy::TyVar (u8->get_ref ()));
944 0 : tree type_record = create_slice_type_record (synthetic_slice);
945 0 : translated
946 0 : = Backend::named_type ("&CStr", type_record, adt->get_ident ().locus);
947 :
948 0 : return;
949 0 : }
950 :
951 14113 : tree base_compiled_type
952 14113 : = TyTyResolveCompile::compile (ctx, type.get_base (), trait_object_mode);
953 14113 : if (type.is_mutable ())
954 : {
955 1346 : translated = Backend::reference_type (base_compiled_type);
956 : }
957 : else
958 : {
959 : // https://doc.rust-lang.org/core/cell/struct.UnsafeCell.html
960 : // If you have a reference &T, then normally in Rust the compiler performs
961 : // optimizations based on the knowledge that &T points to immutable data.
962 : // Mutating that data, for example through an alias or by transmuting a &T
963 : // into a &mut T, is considered undefined behavior. UnsafeCell<T> opts-out
964 : // of the immutability guarantee for &T: a shared reference &UnsafeCell<T>
965 : // may point to data that is being mutated. This is called “interior
966 : // mutability”.
967 12767 : auto base = type.get_base ()->contains_unsafe_cell ()
968 12767 : ? base_compiled_type
969 12765 : : Backend::immutable_type (base_compiled_type);
970 12767 : translated = Backend::reference_type (base);
971 : }
972 : }
973 :
974 : void
975 11346 : TyTyResolveCompile::visit (const TyTy::PointerType &type)
976 : {
977 11346 : const TyTy::SliceType *slice = nullptr;
978 11346 : const TyTy::StrType *str = nullptr;
979 11346 : const TyTy::DynamicObjectType *dyn = nullptr;
980 11346 : const TyTy::ADTType *adt = nullptr;
981 11346 : if (type.is_dyn_slice_type (&slice))
982 : {
983 576 : tree type_record = create_slice_type_record (*slice);
984 576 : std::string dyn_slice_type_str
985 1668 : = std::string (type.is_mutable () ? "*mut " : "*const ") + "["
986 1728 : + slice->get_element_type ()->get_name () + "]";
987 :
988 576 : translated = Backend::named_type (dyn_slice_type_str, type_record,
989 : slice->get_locus ());
990 :
991 576 : return;
992 576 : }
993 10770 : else if (type.is_dyn_str_type (&str))
994 : {
995 2671 : tree type_record = create_str_type_record (*str);
996 2671 : std::string dyn_str_type_str
997 8013 : = std::string (type.is_mutable () ? "*mut " : "*const ") + "str";
998 :
999 2671 : translated = Backend::named_type (dyn_str_type_str, type_record,
1000 : str->get_locus ());
1001 :
1002 2671 : return;
1003 2671 : }
1004 8099 : else if (type.is_dyn_obj_type (&dyn))
1005 : {
1006 19 : tree type_record = create_dyn_obj_record (*dyn);
1007 19 : std::string dyn_str_type_str
1008 55 : = std::string (type.is_mutable () ? "*mut " : "*const ")
1009 38 : + dyn->get_name ();
1010 :
1011 19 : translated = Backend::named_type (dyn_str_type_str, type_record,
1012 : dyn->get_locus ());
1013 :
1014 19 : return;
1015 19 : }
1016 8080 : else if (type.is_dyn_adt_type (&adt))
1017 : {
1018 21 : tree type_record = create_dyn_adt_record (*adt);
1019 21 : std::string dyn_str_type_str
1020 63 : = std::string (type.is_mutable () ? "*mut" : "*const ")
1021 42 : + adt->get_name ();
1022 :
1023 21 : translated = Backend::named_type (dyn_str_type_str, type_record,
1024 : adt->get_locus ());
1025 21 : return;
1026 21 : }
1027 :
1028 8059 : tree base_compiled_type
1029 8059 : = TyTyResolveCompile::compile (ctx, type.get_base (), trait_object_mode);
1030 8059 : if (type.is_mutable ())
1031 : {
1032 2087 : translated = Backend::pointer_type (base_compiled_type);
1033 : }
1034 : else
1035 : {
1036 5972 : auto base = Backend::immutable_type (base_compiled_type);
1037 5972 : translated = Backend::pointer_type (base);
1038 : }
1039 : }
1040 :
1041 : void
1042 4768 : TyTyResolveCompile::visit (const TyTy::StrType &type)
1043 : {
1044 4768 : tree raw_str = create_str_type_record (type);
1045 4768 : translated = Backend::named_type ("str", raw_str, BUILTINS_LOCATION);
1046 4768 : }
1047 :
1048 : void
1049 5055 : TyTyResolveCompile::visit (const TyTy::NeverType &)
1050 : {
1051 5055 : translated = get_unit_type (ctx);
1052 5055 : }
1053 :
1054 : void
1055 188 : TyTyResolveCompile::visit (const TyTy::DynamicObjectType &type)
1056 : {
1057 188 : if (trait_object_mode)
1058 : {
1059 0 : translated = Backend::integer_type (true, Backend::get_pointer_size ());
1060 0 : return;
1061 : }
1062 :
1063 188 : tree type_record = create_dyn_obj_record (type);
1064 188 : translated = Backend::named_type (type.get_name (), type_record,
1065 188 : type.get_ident ().locus);
1066 : }
1067 :
1068 : void
1069 0 : TyTyResolveCompile::visit (const TyTy::OpaqueType &type)
1070 : {
1071 0 : rust_assert (type.can_resolve ());
1072 0 : auto underlying = type.resolve ();
1073 0 : translated = TyTyResolveCompile::compile (ctx, underlying, trait_object_mode);
1074 0 : }
1075 :
1076 : tree
1077 742 : TyTyResolveCompile::create_dyn_obj_record (const TyTy::DynamicObjectType &type)
1078 : {
1079 742 : location_t locus = ctx->get_mappings ().lookup_location (type.get_ty_ref ());
1080 : // create implicit struct
1081 742 : std::vector<Backend::typed_identifier> fields;
1082 :
1083 742 : tree voidptr_ty = build_pointer_type (void_type_node);
1084 :
1085 742 : fields.emplace_back ("data", voidptr_ty, locus);
1086 :
1087 742 : std::vector<Backend::typed_identifier> vtable_fields;
1088 :
1089 : // drop_in_place is not implemented yet!
1090 742 : vtable_fields.emplace_back ("__drop_in_place", voidptr_ty, locus);
1091 742 : vtable_fields.emplace_back ("__size", size_type_node, locus);
1092 742 : vtable_fields.emplace_back ("__align", size_type_node, locus);
1093 :
1094 742 : size_t items_size = type.get_object_items ().size ();
1095 1745 : for (size_t method_idx = 0; method_idx < items_size; method_idx++)
1096 1003 : vtable_fields.emplace_back ("__method_" + std::to_string (method_idx),
1097 : voidptr_ty, locus);
1098 :
1099 742 : tree vtable_record = Backend::struct_type (vtable_fields);
1100 742 : tree vtable_ptr_ty = build_pointer_type (vtable_record);
1101 :
1102 742 : fields.emplace_back ("vtable", vtable_ptr_ty, locus);
1103 :
1104 742 : tree record = Backend::struct_type (fields);
1105 742 : RS_DST_FLAG (record) = 1;
1106 742 : TYPE_MAIN_VARIANT (record) = ctx->insert_main_variant (record);
1107 :
1108 742 : return record;
1109 742 : }
1110 :
1111 : tree
1112 1453 : TyTyResolveCompile::create_slice_type_record (const TyTy::SliceType &type)
1113 : {
1114 : // lookup usize
1115 1453 : TyTy::BaseType *usize = nullptr;
1116 1453 : bool ok = ctx->get_tyctx ()->lookup_builtin ("usize", &usize);
1117 1453 : rust_assert (ok);
1118 :
1119 1453 : tree element_type
1120 1453 : = TyTyResolveCompile::compile (ctx, type.get_element_type ());
1121 1453 : tree data_field_ty = build_pointer_type (element_type);
1122 1453 : Backend::typed_identifier data_field ("data", data_field_ty,
1123 1453 : type.get_locus ());
1124 :
1125 1453 : tree len_field_ty = TyTyResolveCompile::compile (ctx, usize);
1126 1453 : Backend::typed_identifier len_field ("len", len_field_ty, type.get_locus ());
1127 :
1128 1453 : tree record = Backend::struct_type ({data_field, len_field});
1129 1453 : RS_DST_FLAG (record) = 1;
1130 1453 : TYPE_MAIN_VARIANT (record) = ctx->insert_main_variant (record);
1131 :
1132 1453 : return record;
1133 : }
1134 :
1135 : tree
1136 11601 : TyTyResolveCompile::create_str_type_record (const TyTy::StrType &type)
1137 : {
1138 : // lookup usize
1139 11601 : TyTy::BaseType *usize = nullptr;
1140 11601 : bool ok = ctx->get_tyctx ()->lookup_builtin ("usize", &usize);
1141 11601 : rust_assert (ok);
1142 :
1143 11601 : tree char_ptr = build_pointer_type (char_type_node);
1144 11601 : tree const_char_type = build_qualified_type (char_ptr, TYPE_QUAL_CONST);
1145 :
1146 11601 : tree element_type = const_char_type;
1147 11601 : tree data_field_ty = build_pointer_type (element_type);
1148 11601 : Backend::typed_identifier data_field ("data", data_field_ty,
1149 11601 : type.get_locus ());
1150 :
1151 11601 : tree len_field_ty = TyTyResolveCompile::compile (ctx, usize);
1152 11601 : Backend::typed_identifier len_field ("len", len_field_ty, type.get_locus ());
1153 :
1154 11601 : tree record = Backend::struct_type ({data_field, len_field});
1155 11601 : RS_DST_FLAG (record) = 1;
1156 11601 : TYPE_MAIN_VARIANT (record) = ctx->insert_main_variant (record);
1157 :
1158 11601 : return record;
1159 : }
1160 :
1161 : tree
1162 103 : TyTyResolveCompile::create_dyn_adt_record (const TyTy::ADTType &type)
1163 : {
1164 103 : location_t locus = type.get_locus ();
1165 :
1166 103 : tree adt_record = TyTyResolveCompile::compile (ctx, &type);
1167 103 : tree data_field_ty = build_pointer_type (adt_record);
1168 103 : Backend::typed_identifier data_field ("data", data_field_ty, locus);
1169 :
1170 103 : rust_assert (type.number_of_variants () > 0);
1171 103 : TyTy::VariantDef &variant = *type.get_variants ().front ();
1172 103 : rust_assert (variant.num_fields () > 0);
1173 :
1174 103 : const TyTy::BaseType *tail_field
1175 103 : = variant.get_field_at_index (variant.num_fields () - 1)->get_field_type ();
1176 :
1177 103 : tree meta_field_ty = error_mark_node;
1178 103 : std::string meta = "meta";
1179 :
1180 103 : if (tail_field->get_kind () == TyTy::TypeKind::SLICE
1181 103 : || tail_field->get_kind () == TyTy::TypeKind::STR)
1182 : {
1183 88 : TyTy::BaseType *usize = nullptr;
1184 88 : bool ok = ctx->get_tyctx ()->lookup_builtin ("usize", &usize);
1185 88 : rust_assert (ok);
1186 88 : meta_field_ty = TyTyResolveCompile::compile (ctx, usize);
1187 88 : meta = "len";
1188 : }
1189 15 : else if (tail_field->get_kind () == TyTy::TypeKind::DYNAMIC)
1190 : {
1191 9 : const TyTy::DynamicObjectType *dyn
1192 : = static_cast<const TyTy::DynamicObjectType *> (tail_field);
1193 9 : tree dyn_record = create_dyn_obj_record (*dyn);
1194 9 : tree vtable_field = DECL_CHAIN (TYPE_FIELDS (dyn_record));
1195 9 : meta_field_ty = TREE_TYPE (vtable_field);
1196 9 : meta = "vtable";
1197 : }
1198 6 : else if (tail_field->get_kind () == TyTy::TypeKind::ADT)
1199 : {
1200 6 : const TyTy::ADTType *inner_adt
1201 : = static_cast<const TyTy::ADTType *> (tail_field);
1202 6 : tree inner_fat_ptr = create_dyn_adt_record (*inner_adt);
1203 6 : tree inner_meta_field = DECL_CHAIN (TYPE_FIELDS (inner_fat_ptr));
1204 6 : meta_field_ty = TREE_TYPE (inner_meta_field);
1205 6 : tree name_ident = DECL_NAME (inner_meta_field);
1206 6 : if (name_ident != NULL_TREE)
1207 6 : meta = IDENTIFIER_POINTER (name_ident);
1208 : }
1209 : else
1210 0 : rust_unreachable ();
1211 :
1212 103 : Backend::typed_identifier meta_field (meta, meta_field_ty, locus);
1213 103 : tree record = Backend::struct_type ({data_field, meta_field});
1214 103 : RS_DST_FLAG (record) = 1;
1215 103 : TYPE_MAIN_VARIANT (record) = ctx->insert_main_variant (record);
1216 :
1217 103 : return record;
1218 103 : }
1219 :
1220 : } // namespace Compile
1221 : } // namespace Rust
|