| ... | @@ -681,9 +681,29 @@ fn transType(c: *Context, scope: *Scope, raw_ty: Type, qual_handling: Type.QualH | ... | @@ -681,9 +681,29 @@ fn transType(c: *Context, scope: *Scope, raw_ty: Type, qual_handling: Type.QualH |
| 681 | .float80 => return ZigTag.type.create(c.arena, "f80"), | 681 | .float80 => return ZigTag.type.create(c.arena, "f80"), |
| 682 | .float128 => return ZigTag.type.create(c.arena, "f128"), | 682 | .float128 => return ZigTag.type.create(c.arena, "f128"), |
| 683 | .@"enum" => @panic("TODO"), | 683 | .@"enum" => @panic("TODO"), |
| 684 | .pointer => @panic("todo"), | 684 | .pointer => { |
| 685 | .unspecified_variable_len_array, | 685 | const child_type = ty.elemType(); |
| 686 | .incomplete_array => { | 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 | const child_type = ty.elemType(); | 707 | const child_type = ty.elemType(); |
| 688 | const is_const = child_type.qual.@"const"; | 708 | const is_const = child_type.qual.@"const"; |
| 689 | const is_volatile = child_type.qual.@"volatile"; | 709 | const is_volatile = child_type.qual.@"volatile"; |
| ... | @@ -965,6 +985,45 @@ fn transCompoundStmtInline(c: *Context, compound: NodeIndex, block: *Scope.Block | ... | @@ -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 | fn transCompoundStmt(c: *Context, scope: *Scope, compound: NodeIndex) TransError!ZigNode { | 1027 | fn transCompoundStmt(c: *Context, scope: *Scope, compound: NodeIndex) TransError!ZigNode { |
| 969 | var block_scope = try Scope.Block.init(c, scope, false); | 1028 | var block_scope = try Scope.Block.init(c, scope, false); |
| 970 | defer block_scope.deinit(); | 1029 | defer block_scope.deinit(); |