| ... | ... | @@ -681,9 +681,29 @@ fn transType(c: *Context, scope: *Scope, raw_ty: Type, qual_handling: Type.QualH |
| 681 | 681 | .float80 => return ZigTag.type.create(c.arena, "f80"), |
| 682 | 682 | .float128 => return ZigTag.type.create(c.arena, "f128"), |
| 683 | 683 | .@"enum" => @panic("TODO"), |
| 684 | | .pointer => @panic("todo"), |
| 685 | | .unspecified_variable_len_array, |
| 686 | | .incomplete_array => { |
| 684 | .pointer => { |
| 685 | const child_type = ty.elemType(); |
| 686 | |
| 687 | const is_fn_proto = child_type.isFunc(); |
| 688 | const is_const = is_fn_proto or child_type.isConst(); |
| 689 | const is_volatile = child_type.qual.@"volatile"; |
| 690 | const elem_type = try transType(c, scope, child_type, qual_handling, source_loc); |
| 691 | const ptr_info = .{ |
| 692 | .is_const = is_const, |
| 693 | .is_volatile = is_volatile, |
| 694 | .elem_type = elem_type, |
| 695 | }; |
| 696 | if (is_fn_proto or |
| 697 | typeIsOpaque(c, child_type) or |
| 698 | typeWasDemotedToOpaque(c, child_type)) |
| 699 | { |
| 700 | const ptr = try ZigTag.single_pointer.create(c.arena, ptr_info); |
| 701 | return ZigTag.optional_type.create(c.arena, ptr); |
| 702 | } |
| 703 | |
| 704 | return ZigTag.c_pointer.create(c.arena, ptr_info); |
| 705 | }, |
| 706 | .unspecified_variable_len_array, .incomplete_array => { |
| 687 | 707 | const child_type = ty.elemType(); |
| 688 | 708 | const is_const = child_type.qual.@"const"; |
| 689 | 709 | const is_volatile = child_type.qual.@"volatile"; |
| ... | ... | @@ -965,6 +985,45 @@ fn transCompoundStmtInline(c: *Context, compound: NodeIndex, block: *Scope.Block |
| 965 | 985 | } |
| 966 | 986 | } |
| 967 | 987 | |
| 988 | fn recordHasBitfield(record: *const Type.Record) bool { |
| 989 | if (record.isIncomplete()) return false; |
| 990 | for (record.fields) |field| { |
| 991 | if (!field.isRegularField()) return true; |
| 992 | } |
| 993 | return false; |
| 994 | } |
| 995 | |
| 996 | fn typeIsOpaque(c: *Context, ty: Type) bool { |
| 997 | return switch (ty.specifier) { |
| 998 | .void => true, |
| 999 | .@"struct", .@"union" => recordHasBitfield(ty.getRecord().?), |
| 1000 | .typeof_type => typeIsOpaque(c, ty.data.sub_type.*), |
| 1001 | .typeof_expr => typeIsOpaque(c, ty.data.expr.ty), |
| 1002 | .attributed => typeIsOpaque(c, ty.data.attributed.base), |
| 1003 | else => false, |
| 1004 | }; |
| 1005 | } |
| 1006 | |
| 1007 | fn typeWasDemotedToOpaque(c: *Context, ty: Type) bool { |
| 1008 | switch (ty.specifier) { |
| 1009 | .@"struct", .@"union" => { |
| 1010 | const record = ty.getRecord().?; |
| 1011 | if (c.opaque_demotes.contains(@intFromPtr(record))) return true; |
| 1012 | for (record.fields) |field| { |
| 1013 | if (typeWasDemotedToOpaque(c, field.ty)) return true; |
| 1014 | } |
| 1015 | return false; |
| 1016 | }, |
| 1017 | |
| 1018 | .@"enum" => return c.opaque_demotes.contains(@intFromPtr(ty.data.@"enum")), |
| 1019 | |
| 1020 | .typeof_type => return typeWasDemotedToOpaque(c, ty.data.sub_type.*), |
| 1021 | .typeof_expr => return typeWasDemotedToOpaque(c, ty.data.expr.ty), |
| 1022 | .attributed => return typeWasDemotedToOpaque(c, ty.data.attributed.base), |
| 1023 | else => return false, |
| 1024 | } |
| 1025 | } |
| 1026 | |
| 968 | 1027 | fn transCompoundStmt(c: *Context, scope: *Scope, compound: NodeIndex) TransError!ZigNode { |
| 969 | 1028 | var block_scope = try Scope.Block.init(c, scope, false); |
| 970 | 1029 | defer block_scope.deinit(); |