diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index abe4256a30..763dde170b 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -1507,6 +1507,11 @@ pub const Object = struct { }; const field_index_val = Value.initPayload(&buf_field_index.base); + var buffer: Type.Payload.Bits = undefined; + const int_ty = ty.intTagType(&buffer); + const int_info = ty.intInfo(target); + assert(int_info.bits != 0); + for (field_names) |field_name, i| { const field_name_z = try gpa.dupeZ(u8, field_name); defer gpa.free(field_name_z); @@ -1514,9 +1519,25 @@ pub const Object = struct { buf_field_index.data = @intCast(u32, i); var buf_u64: Value.Payload.U64 = undefined; const field_int_val = field_index_val.enumToInt(ty, &buf_u64); - // See https://github.com/ziglang/zig/issues/645 - const field_int = field_int_val.toSignedInt(); - enumerators[i] = dib.createEnumerator(field_name_z, field_int); + + var bigint_space: Value.BigIntSpace = undefined; + const bigint = field_int_val.toBigInt(&bigint_space, target); + + if (bigint.limbs.len == 1) { + enumerators[i] = dib.createEnumerator(field_name_z, bigint.limbs[0], int_info.signedness == .unsigned); + continue; + } + if (@sizeOf(usize) == @sizeOf(u64)) { + enumerators[i] = dib.createEnumerator2( + field_name_z, + @intCast(c_uint, bigint.limbs.len), + bigint.limbs.ptr, + int_info.bits, + int_info.signedness == .unsigned, + ); + continue; + } + @panic("TODO implement bigint debug enumerators to llvm int for 32-bit compiler builds"); } const di_file = try o.getDIFile(gpa, owner_decl.src_namespace.file_scope); @@ -1524,8 +1545,6 @@ pub const Object = struct { const name = try ty.nameAlloc(gpa, o.module); defer gpa.free(name); - var buffer: Type.Payload.Bits = undefined; - const int_ty = ty.intTagType(&buffer); const enum_di_ty = dib.createEnumerationType( di_scope, diff --git a/src/codegen/llvm/bindings.zig b/src/codegen/llvm/bindings.zig index a5b01d6ddf..1b462312cd 100644 --- a/src/codegen/llvm/bindings.zig +++ b/src/codegen/llvm/bindings.zig @@ -1662,7 +1662,18 @@ pub const DIBuilder = opaque { extern fn ZigLLVMCreateDebugEnumerator( dib: *DIBuilder, name: [*:0]const u8, - val: i64, + val: u64, + is_unsigned: bool, + ) *DIEnumerator; + + pub const createEnumerator2 = ZigLLVMCreateDebugEnumeratorOfArbitraryPrecision; + extern fn ZigLLVMCreateDebugEnumeratorOfArbitraryPrecision( + dib: *DIBuilder, + name: [*:0]const u8, + num_words: c_uint, + words: [*]const u64, + bits: c_uint, + is_unsigned: bool, ) *DIEnumerator; pub const createEnumerationType = ZigLLVMCreateDebugEnumerationType; diff --git a/src/stage1/analyze.cpp b/src/stage1/analyze.cpp index 59ca43644a..94ed3a2162 100644 --- a/src/stage1/analyze.cpp +++ b/src/stage1/analyze.cpp @@ -9117,7 +9117,7 @@ static void resolve_llvm_types_enum(CodeGen *g, ZigType *enum_type, ResolveStatu // https://github.com/ziglang/zig/issues/645 di_enumerators[i] = ZigLLVMCreateDebugEnumerator(g->dbuilder, buf_ptr(enum_field->name), - bigint_as_signed(&enum_field->value)); + bigint_as_signed(&enum_field->value), false); } ZigType *tag_int_type = enum_type->data.enumeration.tag_int_type; @@ -9728,10 +9728,10 @@ static void resolve_llvm_types_anyerror(CodeGen *g) { entry->llvm_type = get_llvm_type(g, g->err_tag_type); ZigList err_enumerators = {}; // reserve index 0 to indicate no error - err_enumerators.append(ZigLLVMCreateDebugEnumerator(g->dbuilder, "(none)", 0)); + err_enumerators.append(ZigLLVMCreateDebugEnumerator(g->dbuilder, "(none)", 0, false)); for (size_t i = 1; i < g->errors_by_index.length; i += 1) { ErrorTableEntry *error_entry = g->errors_by_index.at(i); - err_enumerators.append(ZigLLVMCreateDebugEnumerator(g->dbuilder, buf_ptr(&error_entry->name), i)); + err_enumerators.append(ZigLLVMCreateDebugEnumerator(g->dbuilder, buf_ptr(&error_entry->name), i, false)); } // create debug type for error sets diff --git a/src/zig_llvm.cpp b/src/zig_llvm.cpp index b5edb336a5..7134df6a9c 100644 --- a/src/zig_llvm.cpp +++ b/src/zig_llvm.cpp @@ -594,8 +594,16 @@ ZigLLVMDIType *ZigLLVMCreateDebugArrayType(ZigLLVMDIBuilder *dibuilder, uint64_t return reinterpret_cast(di_type); } -ZigLLVMDIEnumerator *ZigLLVMCreateDebugEnumerator(ZigLLVMDIBuilder *dibuilder, const char *name, int64_t val) { - DIEnumerator *di_enumerator = reinterpret_cast(dibuilder)->createEnumerator(name, val); +ZigLLVMDIEnumerator *ZigLLVMCreateDebugEnumerator(ZigLLVMDIBuilder *dibuilder, const char *name, uint64_t val, bool isUnsigned) { + DIEnumerator *di_enumerator = reinterpret_cast(dibuilder)->createEnumerator(name, val, isUnsigned); + return reinterpret_cast(di_enumerator); +} + +ZigLLVMDIEnumerator *ZigLLVMCreateDebugEnumeratorOfArbitraryPrecision(ZigLLVMDIBuilder *dibuilder, + const char *name, unsigned NumWords, const uint64_t Words[], unsigned int bits, bool isUnsigned) +{ + DIEnumerator *di_enumerator = reinterpret_cast(dibuilder)->createEnumerator(name, + APSInt(APInt(bits, makeArrayRef(Words, NumWords)), isUnsigned)); return reinterpret_cast(di_enumerator); } diff --git a/src/zig_llvm.h b/src/zig_llvm.h index 1a4d5481b6..0e210f9545 100644 --- a/src/zig_llvm.h +++ b/src/zig_llvm.h @@ -176,7 +176,11 @@ ZIG_EXTERN_C struct ZigLLVMDIType *ZigLLVMCreateDebugArrayType(struct ZigLLVMDIB int elem_count); ZIG_EXTERN_C struct ZigLLVMDIEnumerator *ZigLLVMCreateDebugEnumerator(struct ZigLLVMDIBuilder *dibuilder, - const char *name, int64_t val); + const char *name, uint64_t val, bool isUnsigned); + + +ZIG_EXTERN_C struct ZigLLVMDIEnumerator *ZigLLVMCreateDebugEnumeratorOfArbitraryPrecision(struct ZigLLVMDIBuilder *dibuilder, + const char *name, unsigned NumWords, const uint64_t Words[], unsigned int bits, bool isUnsigned); ZIG_EXTERN_C struct ZigLLVMDIType *ZigLLVMCreateDebugEnumerationType(struct ZigLLVMDIBuilder *dibuilder, struct ZigLLVMDIScope *scope, const char *name, struct ZigLLVMDIFile *file, unsigned line_number,