aboutsummaryrefslogtreecommitdiff
path: root/src/codegen
diff options
context:
space:
mode:
Diffstat (limited to 'src/codegen')
-rw-r--r--src/codegen/llvm.zig171
1 files changed, 95 insertions, 76 deletions
diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig
index 2466eea8a9..bfe520e1b6 100644
--- a/src/codegen/llvm.zig
+++ b/src/codegen/llvm.zig
@@ -1909,6 +1909,9 @@ pub const DeclGen = struct {
const gop = try dg.object.di_type_map.getOrPut(gpa, ty);
if (gop.found_existing) return gop.value_ptr.*;
errdefer assert(dg.object.di_type_map.remove(ty));
+ // The Type memory is ephemeral; since we want to store a longer-lived
+ // reference, we need to copy it here.
+ gop.key_ptr.* = try ty.copy(dg.object.type_map_arena.allocator());
const target = dg.module.getTarget();
const dib = dg.object.di_builder.?;
switch (ty.zigTypeTag()) {
@@ -2084,7 +2087,7 @@ pub const DeclGen = struct {
),
};
- const replacement_di_type = dib.createStructType(
+ const replacement_di_ty = dib.createStructType(
compile_unit_scope,
name.ptr,
di_file,
@@ -2099,10 +2102,10 @@ pub const DeclGen = struct {
null, // vtable holder
"", // unique id
);
- dib.replaceTemporary(fwd_decl, replacement_di_type);
+ dib.replaceTemporary(fwd_decl, replacement_di_ty);
// The recursive call to `lowerDebugType` means we can't use `gop` anymore.
- try dg.object.di_type_map.put(gpa, ty, replacement_di_type);
- return replacement_di_type;
+ try dg.object.di_type_map.put(gpa, ty, replacement_di_ty);
+ return replacement_di_ty;
}
const elem_di_ty = try lowerDebugType(dg, ptr_info.pointee_type);
@@ -2118,6 +2121,10 @@ pub const DeclGen = struct {
return ptr_di_ty;
},
.Opaque => {
+ if (ty.tag() == .anyopaque) {
+ gop.value_ptr.* = dib.createBasicType("anyopaque", 0, DW.ATE.signed);
+ return gop.value_ptr.*;
+ }
const name = try ty.nameAlloc(gpa); // TODO this is a leak
const owner_decl = ty.getOwnerDecl();
const opaque_di_ty = dib.createForwardDeclType(
@@ -2144,7 +2151,15 @@ pub const DeclGen = struct {
return array_di_ty;
},
.Vector => {
- @panic("TODO debug info type for vector");
+ const vector_di_ty = dib.createVectorType(
+ ty.abiSize(target) * 8,
+ ty.abiAlignment(target) * 8,
+ try lowerDebugType(dg, ty.childType()),
+ ty.vectorLen(),
+ );
+ // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
+ try dg.object.di_type_map.put(gpa, ty, vector_di_ty);
+ return vector_di_ty;
},
.Optional => {
const name = try ty.nameAlloc(gpa); // TODO this is a leak
@@ -2209,7 +2224,7 @@ pub const DeclGen = struct {
),
};
- const replacement_di_type = dib.createStructType(
+ const replacement_di_ty = dib.createStructType(
compile_unit_scope,
name.ptr,
di_file,
@@ -2224,10 +2239,10 @@ pub const DeclGen = struct {
null, // vtable holder
"", // unique id
);
- dib.replaceTemporary(fwd_decl, replacement_di_type);
+ dib.replaceTemporary(fwd_decl, replacement_di_ty);
// The recursive call to `lowerDebugType` means we can't use `gop` anymore.
- try dg.object.di_type_map.put(gpa, ty, replacement_di_type);
- return replacement_di_type;
+ try dg.object.di_type_map.put(gpa, ty, replacement_di_ty);
+ return replacement_di_ty;
},
.ErrorUnion => {
const err_set_ty = ty.errorUnionSet();
@@ -2286,7 +2301,7 @@ pub const DeclGen = struct {
),
};
- const replacement_di_type = dib.createStructType(
+ const replacement_di_ty = dib.createStructType(
compile_unit_scope,
name.ptr,
di_file,
@@ -2301,10 +2316,10 @@ pub const DeclGen = struct {
null, // vtable holder
"", // unique id
);
- dib.replaceTemporary(fwd_decl, replacement_di_type);
+ dib.replaceTemporary(fwd_decl, replacement_di_ty);
// The recursive call to `lowerDebugType` means we can't use `gop` anymore.
- try dg.object.di_type_map.put(gpa, ty, replacement_di_type);
- return replacement_di_type;
+ try dg.object.di_type_map.put(gpa, ty, replacement_di_ty);
+ return replacement_di_ty;
},
.ErrorSet => {
// TODO make this a proper enum with all the error codes in it.
@@ -2313,20 +2328,80 @@ pub const DeclGen = struct {
return gop.value_ptr.*;
},
.Struct => {
- const owner_decl = ty.getOwnerDecl();
-
+ const compile_unit_scope = dg.object.di_compile_unit.?.toScope();
const name = try ty.nameAlloc(gpa); // TODO this is a leak
const fwd_decl = dib.createReplaceableCompositeType(
DW.TAG.structure_type,
name.ptr,
- dg.object.di_compile_unit.?.toScope(),
+ compile_unit_scope,
null, // file
0, // line
);
gop.value_ptr.* = fwd_decl;
+ if (ty.isTupleOrAnonStruct()) {
+ const tuple = ty.tupleFields();
+
+ var di_fields: std.ArrayListUnmanaged(*llvm.DIType) = .{};
+ defer di_fields.deinit(gpa);
+
+ try di_fields.ensureUnusedCapacity(gpa, tuple.types.len);
+
+ comptime assert(struct_layout_version == 2);
+ var offset: u64 = 0;
+
+ for (tuple.types) |field_ty, i| {
+ const field_val = tuple.values[i];
+ if (field_val.tag() != .unreachable_value) continue;
+
+ const field_size = field_ty.abiSize(target);
+ const field_align = field_ty.abiAlignment(target);
+ const field_offset = std.mem.alignForwardGeneric(u64, offset, field_align);
+ offset = field_offset + field_size;
+
+ const field_name = if (ty.castTag(.anon_struct)) |payload|
+ try gpa.dupeZ(u8, payload.data.names[i])
+ else
+ try std.fmt.allocPrintZ(gpa, "{d}", .{i});
+ defer gpa.free(field_name);
+
+ try di_fields.append(gpa, dib.createMemberType(
+ fwd_decl.toScope(),
+ field_name,
+ null, // file
+ 0, // line
+ field_size * 8, // size in bits
+ field_align * 8, // align in bits
+ field_offset * 8, // offset in bits
+ 0, // flags
+ try dg.lowerDebugType(field_ty),
+ ));
+ }
+
+ const replacement_di_ty = dib.createStructType(
+ compile_unit_scope,
+ name.ptr,
+ null, // file
+ 0, // line
+ ty.abiSize(target) * 8, // size in bits
+ ty.abiAlignment(target) * 8, // align in bits
+ 0, // flags
+ null, // derived from
+ di_fields.items.ptr,
+ @intCast(c_int, di_fields.items.len),
+ 0, // run time lang
+ null, // vtable holder
+ "", // unique id
+ );
+ dib.replaceTemporary(fwd_decl, replacement_di_ty);
+ // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
+ try dg.object.di_type_map.put(gpa, ty, replacement_di_ty);
+ return replacement_di_ty;
+ }
+
const TODO_implement_this = true; // TODO
if (TODO_implement_this or !ty.hasRuntimeBits()) {
+ const owner_decl = ty.getOwnerDecl();
const struct_di_ty = try dg.makeEmptyNamespaceDIType(owner_decl);
dib.replaceTemporary(fwd_decl, struct_di_ty);
// The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType`
@@ -2336,65 +2411,6 @@ pub const DeclGen = struct {
}
@panic("TODO debug info type for struct");
- //const gop = try dg.object.type_map.getOrPut(gpa, ty);
- //if (gop.found_existing) return gop.value_ptr.*;
-
- //// The Type memory is ephemeral; since we want to store a longer-lived
- //// reference, we need to copy it here.
- //gop.key_ptr.* = try ty.copy(dg.object.type_map_arena.allocator());
-
- //if (ty.isTupleOrAnonStruct()) {
- // const tuple = ty.tupleFields();
- // const llvm_struct_ty = dg.context.structCreateNamed("");
- // gop.value_ptr.* = llvm_struct_ty; // must be done before any recursive calls
-
- // var llvm_field_types: std.ArrayListUnmanaged(*const llvm.Type) = .{};
- // defer llvm_field_types.deinit(gpa);
-
- // try llvm_field_types.ensureUnusedCapacity(gpa, tuple.types.len);
-
- // comptime assert(struct_layout_version == 2);
- // var offset: u64 = 0;
- // var big_align: u32 = 0;
-
- // for (tuple.types) |field_ty, i| {
- // const field_val = tuple.values[i];
- // if (field_val.tag() != .unreachable_value) continue;
-
- // const field_align = field_ty.abiAlignment(target);
- // big_align = @maximum(big_align, field_align);
- // const prev_offset = offset;
- // offset = std.mem.alignForwardGeneric(u64, offset, field_align);
-
- // const padding_len = offset - prev_offset;
- // if (padding_len > 0) {
- // const llvm_array_ty = dg.context.intType(8).arrayType(@intCast(c_uint, padding_len));
- // try llvm_field_types.append(gpa, llvm_array_ty);
- // }
- // const field_llvm_ty = try dg.llvmType(field_ty);
- // try llvm_field_types.append(gpa, field_llvm_ty);
-
- // offset += field_ty.abiSize(target);
- // }
- // {
- // const prev_offset = offset;
- // offset = std.mem.alignForwardGeneric(u64, offset, big_align);
- // const padding_len = offset - prev_offset;
- // if (padding_len > 0) {
- // const llvm_array_ty = dg.context.intType(8).arrayType(@intCast(c_uint, padding_len));
- // try llvm_field_types.append(gpa, llvm_array_ty);
- // }
- // }
-
- // llvm_struct_ty.structSetBody(
- // llvm_field_types.items.ptr,
- // @intCast(c_uint, llvm_field_types.items.len),
- // .False,
- // );
-
- // return llvm_struct_ty;
- //}
-
//const struct_obj = ty.castTag(.@"struct").?.data;
//if (struct_obj.layout == .Packed) {
@@ -2554,7 +2570,10 @@ pub const DeclGen = struct {
defer param_di_types.deinit();
// Return type goes first.
- const di_ret_ty = if (sret) Type.void else fn_info.return_type;
+ const di_ret_ty = if (sret or !fn_info.return_type.hasRuntimeBits())
+ Type.void
+ else
+ fn_info.return_type;
try param_di_types.append(try dg.lowerDebugType(di_ret_ty));
if (sret) {