aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/compiler/aro/aro/Type.zig4
-rw-r--r--lib/compiler/aro_translate_c.zig493
2 files changed, 407 insertions, 90 deletions
diff --git a/lib/compiler/aro/aro/Type.zig b/lib/compiler/aro/aro/Type.zig
index 3588d46e7c..a2ba4707c4 100644
--- a/lib/compiler/aro/aro/Type.zig
+++ b/lib/compiler/aro/aro/Type.zig
@@ -1142,12 +1142,14 @@ pub fn alignof(ty: Type, comp: *const Compilation) u29 {
};
}
+pub const QualHandling = enum { standard, preserve_quals };
+
/// Canonicalize a possibly-typeof() type. If the type is not a typeof() type, simply
/// return it. Otherwise, determine the actual qualified type.
/// The `qual_handling` parameter can be used to return the full set of qualifiers
/// added by typeof() operations, which is useful when determining the elemType of
/// arrays and pointers.
-pub fn canonicalize(ty: Type, qual_handling: enum { standard, preserve_quals }) Type {
+pub fn canonicalize(ty: Type, qual_handling: QualHandling) Type {
var cur = ty;
if (cur.specifier == .attributed) {
cur = cur.data.attributed.base;
diff --git a/lib/compiler/aro_translate_c.zig b/lib/compiler/aro_translate_c.zig
index 1c481bf1a7..dcfd9d8657 100644
--- a/lib/compiler/aro_translate_c.zig
+++ b/lib/compiler/aro_translate_c.zig
@@ -52,18 +52,17 @@ fn getMangle(c: *Context) u32 {
return c.mangle_count;
}
-/// Convert a clang source location to a file:line:column string
-fn locStr(c: *Context, loc: TokenIndex) ![]const u8 {
- _ = c;
- _ = loc;
- // const spelling_loc = c.source_manager.getSpellingLoc(loc);
- // const filename_c = c.source_manager.getFilename(spelling_loc);
- // const filename = if (filename_c) |s| try c.str(s) else @as([]const u8, "(no file)");
-
- // const line = c.source_manager.getSpellingLineNumber(spelling_loc);
- // const column = c.source_manager.getSpellingColumnNumber(spelling_loc);
- // return std.fmt.allocPrint(c.arena, "{s}:{d}:{d}", .{ filename, line, column });
- return "somewhere";
+/// Convert an aro TokenIndex to a 'file:line:column' string
+fn locStr(c: *Context, tok_idx: TokenIndex) ![]const u8 {
+ const token_loc = c.tree.tokens.items(.loc)[tok_idx];
+ const source = c.comp.getSource(token_loc.id);
+ const line_col = source.lineCol(token_loc);
+ const filename = source.path;
+
+ const line = source.physicalLine(token_loc);
+ const col = line_col.col;
+
+ return std.fmt.allocPrint(c.arena, "{s}:{d}:{d}", .{ filename, line, col });
}
fn maybeSuppressResult(c: *Context, used: ResultUsed, result: ZigNode) TransError!ZigNode {
@@ -184,26 +183,30 @@ fn prepopulateGlobalNameTable(c: *Context) !void {
const node_data = c.tree.nodes.items(.data);
for (c.tree.root_decls) |node| {
const data = node_data[@intFromEnum(node)];
- const decl_name = switch (node_tags[@intFromEnum(node)]) {
+ switch (node_tags[@intFromEnum(node)]) {
.typedef => @panic("TODO"),
- .static_assert,
.struct_decl_two,
.union_decl_two,
.struct_decl,
.union_decl,
- => blk: {
- const ty = node_types[@intFromEnum(node)];
- const name_id = ty.data.record.name;
- break :blk c.mapper.lookup(name_id);
- },
-
+ .struct_forward_decl,
+ .union_forward_decl,
.enum_decl_two,
.enum_decl,
- => blk: {
- const ty = node_types[@intFromEnum(node)];
- const name_id = ty.data.@"enum".name;
- break :blk c.mapper.lookup(name_id);
+ .enum_forward_decl,
+ => {
+ const raw_ty = node_types[@intFromEnum(node)];
+ const ty = raw_ty.canonicalize(.standard);
+ const name_id = if (ty.isRecord()) ty.data.record.name else ty.data.@"enum".name;
+ const decl_name = c.mapper.lookup(name_id);
+ const container_prefix = if (ty.is(.@"struct")) "struct" else if (ty.is(.@"union")) "union" else "enum";
+ const prefixed_name = try std.fmt.allocPrint(c.arena, "{s}_{s}", .{ container_prefix, decl_name });
+ // `decl_name` and `prefixed_name` are the preferred names for this type.
+ // However, we can name it anything else if necessary, so these are "weak names".
+ try c.weak_global_names.ensureUnusedCapacity(c.gpa, 2);
+ c.weak_global_names.putAssumeCapacity(decl_name, {});
+ c.weak_global_names.putAssumeCapacity(prefixed_name, {});
},
.fn_proto,
@@ -215,80 +218,256 @@ fn prepopulateGlobalNameTable(c: *Context) !void {
.inline_fn_def,
.inline_static_fn_def,
.@"var",
+ .extern_var,
.static_var,
.threadlocal_var,
- .threadlocal_static_var,
- .extern_var,
.threadlocal_extern_var,
- => c.tree.tokSlice(data.decl.name),
+ .threadlocal_static_var,
+ => {
+ const decl_name = c.tree.tokSlice(data.decl.name);
+ try c.global_names.put(c.gpa, decl_name, {});
+ },
else => unreachable,
- };
- try c.global_names.put(c.gpa, decl_name, {});
+ }
}
}
fn transTopLevelDecls(c: *Context) !void {
+ for (c.tree.root_decls) |node| {
+ try transDecl(c, &c.global_scope.base, node);
+ }
+}
+
+fn transDecl(c: *Context, scope: *Scope, decl: NodeIndex) !void {
const node_tags = c.tree.nodes.items(.tag);
const node_data = c.tree.nodes.items(.data);
- for (c.tree.root_decls) |node| {
- const data = node_data[@intFromEnum(node)];
- switch (node_tags[@intFromEnum(node)]) {
- .typedef => {
- try transTypeDef(c, &c.global_scope.base, node);
- },
+ const data = node_data[@intFromEnum(decl)];
+ switch (node_tags[@intFromEnum(decl)]) {
+ .typedef => {
+ try transTypeDef(c, scope, decl);
+ },
- .static_assert,
- .struct_decl_two,
- .union_decl_two,
- .struct_decl,
- .union_decl,
- => {
- try transRecordDecl(c, &c.global_scope.base, node);
- },
+ .struct_decl_two,
+ .union_decl_two,
+ => {
+ var fields = [2]NodeIndex{ data.bin.lhs, data.bin.rhs };
+ var field_count: u2 = 0;
+ if (fields[0] != .none) field_count += 1;
+ if (fields[1] != .none) field_count += 1;
+ try transRecordDecl(c, scope, decl, fields[0..field_count]);
+ },
+ .struct_decl,
+ .union_decl,
+ => {
+ const fields = c.tree.data[data.range.start..data.range.end];
+ try transRecordDecl(c, scope, decl, fields);
+ },
- .enum_decl_two => {
- var fields = [2]NodeIndex{ data.bin.lhs, data.bin.rhs };
- var field_count: u8 = 0;
- if (fields[0] != .none) field_count += 1;
- if (fields[1] != .none) field_count += 1;
- try transEnumDecl(c, &c.global_scope.base, node, fields[0..field_count]);
- },
- .enum_decl => {
- const fields = c.tree.data[data.range.start..data.range.end];
- try transEnumDecl(c, &c.global_scope.base, node, fields);
- },
+ .enum_decl_two => {
+ var fields = [2]NodeIndex{ data.bin.lhs, data.bin.rhs };
+ var field_count: u8 = 0;
+ if (fields[0] != .none) field_count += 1;
+ if (fields[1] != .none) field_count += 1;
+ try transEnumDecl(c, scope, decl, fields[0..field_count]);
+ },
+ .enum_decl => {
+ const fields = c.tree.data[data.range.start..data.range.end];
+ try transEnumDecl(c, scope, decl, fields);
+ },
- .fn_proto,
- .static_fn_proto,
- .inline_fn_proto,
- .inline_static_fn_proto,
- .fn_def,
- .static_fn_def,
- .inline_fn_def,
- .inline_static_fn_def,
- => {
- try transFnDecl(c, node);
- },
+ .enum_field_decl,
+ .record_field_decl,
+ .indirect_record_field_decl,
+ .struct_forward_decl,
+ .union_forward_decl,
+ .enum_forward_decl,
+ => return,
+
+ .fn_proto,
+ .static_fn_proto,
+ .inline_fn_proto,
+ .inline_static_fn_proto,
+ .fn_def,
+ .static_fn_def,
+ .inline_fn_def,
+ .inline_static_fn_def,
+ => {
+ try transFnDecl(c, decl);
+ },
- .@"var",
- .static_var,
- .threadlocal_var,
- .threadlocal_static_var,
- .extern_var,
- .threadlocal_extern_var,
- => {
- try transVarDecl(c, node, null);
- },
- else => unreachable,
- }
+ .@"var",
+ .extern_var,
+ .static_var,
+ .threadlocal_var,
+ .threadlocal_extern_var,
+ .threadlocal_static_var,
+ => {
+ try transVarDecl(c, decl, null);
+ },
+ else => unreachable,
}
}
fn transTypeDef(_: *Context, _: *Scope, _: NodeIndex) Error!void {
@panic("TODO");
}
-fn transRecordDecl(_: *Context, _: *Scope, _: NodeIndex) Error!void {
- @panic("TODO");
+
+fn mangleWeakGlobalName(c: *Context, want_name: []const u8) ![]const u8 {
+ var cur_name = want_name;
+
+ if (!c.weak_global_names.contains(want_name)) {
+ // This type wasn't noticed by the name detection pass, so nothing has been treating this as
+ // a weak global name. We must mangle it to avoid conflicts with locals.
+ cur_name = try std.fmt.allocPrint(c.arena, "{s}_{d}", .{ want_name, c.getMangle() });
+ }
+
+ while (c.global_names.contains(cur_name)) {
+ cur_name = try std.fmt.allocPrint(c.arena, "{s}_{d}", .{ want_name, c.getMangle() });
+ }
+ return cur_name;
+}
+
+fn transRecordDecl(c: *Context, scope: *Scope, record_node: NodeIndex, field_nodes: []const NodeIndex) Error!void {
+ const node_types = c.tree.nodes.items(.ty);
+ const raw_record_ty = node_types[@intFromEnum(record_node)];
+ const record_decl = raw_record_ty.getRecord().?;
+ if (c.decl_table.get(@intFromPtr(record_decl))) |_|
+ return; // Avoid processing this decl twice
+ const toplevel = scope.id == .root;
+ const bs: *Scope.Block = if (!toplevel) try scope.findBlockScope(c) else undefined;
+
+ const container_kind: ZigTag = if (raw_record_ty.is(.@"union")) .@"union" else .@"struct";
+ const container_kind_name: []const u8 = @tagName(container_kind);
+
+ var is_unnamed = false;
+ var bare_name: []const u8 = c.mapper.lookup(record_decl.name);
+ var name = bare_name;
+
+ if (c.unnamed_typedefs.get(@intFromPtr(record_decl))) |typedef_name| {
+ bare_name = typedef_name;
+ name = typedef_name;
+ } else {
+ if (raw_record_ty.isAnonymousRecord(c.comp)) {
+ bare_name = try std.fmt.allocPrint(c.arena, "unnamed_{d}", .{c.getMangle()});
+ is_unnamed = true;
+ }
+ name = try std.fmt.allocPrint(c.arena, "{s}_{s}", .{ container_kind_name, bare_name });
+ if (toplevel and !is_unnamed) {
+ name = try mangleWeakGlobalName(c, name);
+ }
+ }
+ if (!toplevel) name = try bs.makeMangledName(c, name);
+ try c.decl_table.putNoClobber(c.gpa, @intFromPtr(record_decl), name);
+
+ const is_pub = toplevel and !is_unnamed;
+ const init_node = blk: {
+ var fields = try std.ArrayList(ast.Payload.Record.Field).initCapacity(c.gpa, record_decl.fields.len);
+ defer fields.deinit();
+
+ // TODO: Add support for flexible array field functions
+ var functions = std.ArrayList(ZigNode).init(c.gpa);
+ defer functions.deinit();
+
+ var unnamed_field_count: u32 = 0;
+
+ // If a record doesn't have any attributes that would affect the alignment and
+ // layout, then we can just use a simple `extern` type. If it does have attributes,
+ // then we need to inspect the layout and assign an `align` value for each field.
+ const has_alignment_attributes = record_decl.field_attributes != null or
+ raw_record_ty.hasAttribute(.@"packed") or
+ raw_record_ty.hasAttribute(.aligned);
+ const head_field_alignment: ?c_uint = headFieldAlignment(record_decl);
+
+ // Iterate over field nodes so that we translate any type decls included in this record decl.
+ // TODO: Move this logic into `fn transType()` instead of handling decl translation here.
+ for (field_nodes) |field_node| {
+ const field_raw_ty = node_types[@intFromEnum(field_node)];
+ if (field_raw_ty.isEnumOrRecord()) try transDecl(c, scope, field_node);
+ }
+
+ for (record_decl.fields, 0..) |field, field_index| {
+ const field_loc = field.name_tok;
+
+ // Demote record to opaque if it contains a bitfield
+ if (!field.isRegularField()) {
+ try c.opaque_demotes.put(c.gpa, @intFromPtr(record_decl), {});
+ try warn(c, scope, field_loc, "{s} demoted to opaque type - has bitfield", .{container_kind_name});
+ break :blk ZigTag.opaque_literal.init();
+ }
+
+ var field_name = c.mapper.lookup(field.name);
+ if (!field.isNamed()) {
+ field_name = try std.fmt.allocPrint(c.arena, "unnamed_{d}", .{unnamed_field_count});
+ unnamed_field_count += 1;
+ }
+ const field_type = transType(c, scope, field.ty, .preserve_quals, field_loc) catch |err| switch (err) {
+ error.UnsupportedType => {
+ try c.opaque_demotes.put(c.gpa, @intFromPtr(record_decl), {});
+ try warn(c, scope, 0, "{s} demoted to opaque type - unable to translate type of field {s}", .{
+ container_kind_name,
+ field_name,
+ });
+ break :blk ZigTag.opaque_literal.init();
+ },
+ else => |e| return e,
+ };
+
+ const field_alignment = if (has_alignment_attributes)
+ alignmentForField(record_decl, head_field_alignment, field_index)
+ else
+ null;
+
+ // C99 introduced designated initializers for structs. Omitted fields are implicitly
+ // initialized to zero. Some C APIs are designed with this in mind. Defaulting to zero
+ // values for translated struct fields permits Zig code to comfortably use such an API.
+ const default_value = if (container_kind == .@"struct")
+ try ZigTag.std_mem_zeroes.create(c.arena, field_type)
+ else
+ null;
+
+ fields.appendAssumeCapacity(.{
+ .name = field_name,
+ .type = field_type,
+ .alignment = field_alignment,
+ .default_value = default_value,
+ });
+ }
+
+ const record_payload = try c.arena.create(ast.Payload.Record);
+ record_payload.* = .{
+ .base = .{ .tag = container_kind },
+ .data = .{
+ .layout = .@"extern",
+ .fields = try c.arena.dupe(ast.Payload.Record.Field, fields.items),
+ .functions = try c.arena.dupe(ZigNode, functions.items),
+ .variables = &.{},
+ },
+ };
+ break :blk ZigNode.initPayload(&record_payload.base);
+ };
+
+ const payload = try c.arena.create(ast.Payload.SimpleVarDecl);
+ payload.* = .{
+ .base = .{ .tag = ([2]ZigTag{ .var_simple, .pub_var_simple })[@intFromBool(is_pub)] },
+ .data = .{
+ .name = name,
+ .init = init_node,
+ },
+ };
+ const node = ZigNode.initPayload(&payload.base);
+ if (toplevel) {
+ try addTopLevelDecl(c, name, node);
+ // Only add the alias if the name is available *and* it was caught by
+ // name detection. Don't bother performing a weak mangle, since a
+ // mangled name is of no real use here.
+ if (!is_unnamed and !c.global_names.contains(bare_name) and c.weak_global_names.contains(bare_name))
+ try c.alias_list.append(.{ .alias = bare_name, .name = name });
+ } else {
+ try scope.appendNode(node);
+ if (node.tag() != .pub_var_simple) {
+ try bs.discardVariable(c, name);
+ }
+ }
}
fn transFnDecl(c: *Context, fn_decl: NodeIndex) Error!void {
@@ -419,7 +598,7 @@ fn transEnumDecl(c: *Context, scope: *Scope, enum_decl: NodeIndex, field_nodes:
enum_val_name = try bs.makeMangledName(c, enum_val_name);
}
- const enum_const_type_node: ?ZigNode = transType(c, scope, field.ty, field.name_tok) catch |err| switch (err) {
+ const enum_const_type_node: ?ZigNode = transType(c, scope, field.ty, .standard, field.name_tok) catch |err| switch (err) {
error.UnsupportedType => null,
else => |e| return e,
};
@@ -439,7 +618,7 @@ fn transEnumDecl(c: *Context, scope: *Scope, enum_decl: NodeIndex, field_nodes:
}
}
- break :blk transType(c, scope, ty.data.@"enum".tag_ty, 0) catch |err| switch (err) {
+ break :blk transType(c, scope, ty.data.@"enum".tag_ty, .standard, 0) catch |err| switch (err) {
error.UnsupportedType => {
return failDecl(c, 0, name, "unable to translate enum integer type", .{});
},
@@ -472,8 +651,8 @@ fn transEnumDecl(c: *Context, scope: *Scope, enum_decl: NodeIndex, field_nodes:
}
}
-fn transType(c: *Context, scope: *Scope, raw_ty: Type, source_loc: TokenIndex) TypeError!ZigNode {
- const ty = raw_ty.canonicalize(.standard);
+fn transType(c: *Context, scope: *Scope, raw_ty: Type, qual_handling: Type.QualHandling, source_loc: TokenIndex) TypeError!ZigNode {
+ const ty = raw_ty.canonicalize(qual_handling);
switch (ty.specifier) {
.void => return ZigTag.type.create(c.arena, "anyopaque"),
.bool => return ZigTag.type.create(c.arena, "bool"),
@@ -496,16 +675,152 @@ fn transType(c: *Context, scope: *Scope, raw_ty: Type, source_loc: TokenIndex) T
.long_double => return ZigTag.type.create(c.arena, "c_longdouble"),
.float80 => return ZigTag.type.create(c.arena, "f80"),
.float128 => return ZigTag.type.create(c.arena, "f128"),
+ .@"enum" => @panic("TODO"),
+ .pointer,
+ .unspecified_variable_len_array,
+ .array,
+ .static_array,
+ .incomplete_array,
+ => @panic("TODO"),
.func,
.var_args_func,
.old_style_func,
- => return transFnType(c, scope, raw_ty, ty, source_loc, .{}),
+ => return transFnType(c, scope, ty, ty, source_loc, .{}),
+ .@"struct",
+ .@"union",
+ => {
+ var trans_scope = scope;
+ if (ty.isAnonymousRecord(c.comp)) {
+ const record_decl = ty.data.record;
+ const name_id = c.mapper.lookup(record_decl.name);
+ if (c.weak_global_names.contains(name_id)) trans_scope = &c.global_scope.base;
+ }
+ const name = c.decl_table.get(@intFromPtr(ty.data.record)).?;
+ return ZigTag.identifier.create(c.arena, name);
+ },
+ .attributed,
+ .typeof_type,
+ .typeof_expr,
+ => unreachable,
else => return error.UnsupportedType,
}
}
-fn zigAlignment(bit_alignment: u29) u32 {
- return bit_alignment / 8;
+/// Look ahead through the fields of the record to determine what the alignment of the record
+/// would be without any align/packed/etc. attributes. This helps us determine whether or not
+/// the fields with 0 offset need an `align` qualifier. Strictly speaking, we could just
+/// pedantically assign those fields the same alignment as the parent's pointer alignment,
+/// but this helps the generated code to be a little less verbose.
+fn headFieldAlignment(record_decl: *const Type.Record) ?c_uint {
+ const bits_per_byte = 8;
+ const parent_ptr_alignment_bits = record_decl.type_layout.pointer_alignment_bits;
+ const parent_ptr_alignment = parent_ptr_alignment_bits / bits_per_byte;
+ var max_field_alignment_bits: u64 = 0;
+ for (record_decl.fields) |field| {
+ if (field.ty.getRecord()) |field_record_decl| {
+ const child_record_alignment = field_record_decl.type_layout.field_alignment_bits;
+ if (child_record_alignment > max_field_alignment_bits)
+ max_field_alignment_bits = child_record_alignment;
+ } else {
+ const field_size = field.layout.size_bits;
+ if (field_size > max_field_alignment_bits)
+ max_field_alignment_bits = field_size;
+ }
+ }
+ if (max_field_alignment_bits != parent_ptr_alignment_bits) {
+ return parent_ptr_alignment;
+ } else {
+ return null;
+ }
+}
+
+/// This function returns a ?c_uint to match Clang's behaviour of using c_uint.
+/// This can be changed to a u29 after the Clang frontend for translate-c is removed.
+fn alignmentForField(
+ record_decl: *const Type.Record,
+ head_field_alignment: ?c_uint,
+ field_index: usize,
+) ?c_uint {
+ const fields = record_decl.fields;
+ assert(fields.len != 0);
+ const field = fields[field_index];
+
+ const bits_per_byte = 8;
+ const parent_ptr_alignment_bits = record_decl.type_layout.pointer_alignment_bits;
+ const parent_ptr_alignment = parent_ptr_alignment_bits / bits_per_byte;
+
+ // bitfields aren't supported yet. Until support is added, records with bitfields
+ // should be demoted to opaque, and this function shouldn't be called for them.
+ if (!field.isRegularField()) {
+ @panic("TODO: add bitfield support for records");
+ }
+
+ const field_offset_bits: u64 = field.layout.offset_bits;
+ const field_size_bits: u64 = field.layout.size_bits;
+
+ // Fields with zero width always have an alignment of 1
+ if (field_size_bits == 0) {
+ return 1;
+ }
+
+ // Fields with 0 offset inherit the parent's pointer alignment.
+ if (field_offset_bits == 0) {
+ return head_field_alignment;
+ }
+
+ // Records have a natural alignment when used as a field, and their size is
+ // a multiple of this alignment value. For all other types, the natural alignment
+ // is their size.
+ const field_natural_alignment_bits: u64 = if (field.ty.getRecord()) |record| record.type_layout.field_alignment_bits else field_size_bits;
+ const rem_bits = field_offset_bits % field_natural_alignment_bits;
+
+ // If there's a remainder, then the alignment is smaller than the field's
+ // natural alignment
+ if (rem_bits > 0) {
+ const rem_alignment = rem_bits / bits_per_byte;
+ if (rem_alignment > 0 and std.math.isPowerOfTwo(rem_alignment)) {
+ const actual_alignment = @min(rem_alignment, parent_ptr_alignment);
+ return @as(c_uint, @truncate(actual_alignment));
+ } else {
+ return 1;
+ }
+ }
+
+ // A field may have an offset which positions it to be naturally aligned, but the
+ // parent's pointer alignment determines if this is actually true, so we take the minimum
+ // value.
+ // For example, a float field (4 bytes wide) with a 4 byte offset is positioned to have natural
+ // alignment, but if the parent pointer alignment is 2, then the actual alignment of the
+ // float is 2.
+ const field_natural_alignment: u64 = field_natural_alignment_bits / bits_per_byte;
+ const offset_alignment = field_offset_bits / bits_per_byte;
+ const possible_alignment = @min(parent_ptr_alignment, offset_alignment);
+ if (possible_alignment == field_natural_alignment) {
+ return null;
+ } else if (possible_alignment < field_natural_alignment) {
+ if (std.math.isPowerOfTwo(possible_alignment)) {
+ return possible_alignment;
+ } else {
+ return 1;
+ }
+ } else { // possible_alignment > field_natural_alignment
+ // Here, the field is positioned be at a higher alignment than it's natural alignment. This means we
+ // need to determine whether it's a specified alignment. We can determine that from the padding preceding
+ // the field.
+ const padding_from_prev_field: u64 = blk: {
+ if (field_offset_bits != 0) {
+ const previous_field = fields[field_index - 1];
+ break :blk (field_offset_bits - previous_field.layout.offset_bits) - previous_field.layout.size_bits;
+ } else {
+ break :blk 0;
+ }
+ };
+ if (padding_from_prev_field < field_natural_alignment_bits) {
+ return null;
+ } else {
+ return possible_alignment;
+ }
+ }
}
const FnProtoContext = struct {
@@ -536,7 +851,7 @@ fn transFnType(
else
c.mapper.lookup(param_info.name);
- const type_node = try transType(c, scope, param_ty, param_info.name_tok);
+ const type_node = try transType(c, scope, param_ty, .standard, param_info.name_tok);
param_node.* = .{
.is_noalias = is_noalias,
.name = param_name,
@@ -551,7 +866,7 @@ fn transFnType(
break :blk null;
};
- const alignment = if (raw_ty.requestedAlignment(c.comp)) |alignment| zigAlignment(alignment) else null;
+ const alignment: ?c_uint = raw_ty.requestedAlignment(c.comp) orelse null;
const explicit_callconv = null;
// const explicit_callconv = if ((ctx.is_inline or ctx.is_export or ctx.is_extern) and ctx.cc == .C) null else ctx.cc;
@@ -565,7 +880,7 @@ fn transFnType(
// convert primitive anyopaque to actual void (only for return type)
break :blk ZigTag.void_type.init();
} else {
- break :blk transType(c, scope, return_ty, source_loc) catch |err| switch (err) {
+ break :blk transType(c, scope, return_ty, .standard, source_loc) catch |err| switch (err) {
error.UnsupportedType => {
try warn(c, scope, source_loc, "unsupported function proto return type", .{});
return err;
@@ -642,7 +957,7 @@ fn transExpr(c: *Context, node: NodeIndex, result_used: ResultUsed) TransError!Z
// TODO handle other values
const int = try transCreateNodeAPInt(c, val);
const as_node = try ZigTag.as.create(c.arena, .{
- .lhs = try transType(c, undefined, ty, undefined),
+ .lhs = try transType(c, undefined, ty, .standard, undefined),
.rhs = int,
});
return maybeSuppressResult(c, result_used, as_node);