12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238 |
- gb_internal LLVMMetadataRef lb_get_llvm_metadata(lbModule *m, void *key) {
- if (key == nullptr) {
- return nullptr;
- }
- auto found = map_get(&m->debug_values, key);
- if (found) {
- return *found;
- }
- return nullptr;
- }
- gb_internal void lb_set_llvm_metadata(lbModule *m, void *key, LLVMMetadataRef value) {
- if (key != nullptr) {
- map_set(&m->debug_values, key, value);
- }
- }
- gb_internal LLVMMetadataRef lb_get_llvm_file_metadata_from_node(lbModule *m, Ast *node) {
- if (node == nullptr) {
- return nullptr;
- }
- return lb_get_llvm_metadata(m, node->file());
- }
- gb_internal LLVMMetadataRef lb_get_current_debug_scope(lbProcedure *p) {
- GB_ASSERT_MSG(p->debug_info != nullptr, "missing debug information for %.*s", LIT(p->name));
- for (isize i = p->scope_stack.count-1; i >= 0; i--) {
- Scope *s = p->scope_stack[i];
- LLVMMetadataRef md = lb_get_llvm_metadata(p->module, s);
- if (md) {
- return md;
- }
- }
- return p->debug_info;
- }
- gb_internal LLVMMetadataRef lb_debug_location_from_token_pos(lbProcedure *p, TokenPos pos) {
- LLVMMetadataRef scope = lb_get_current_debug_scope(p);
- GB_ASSERT_MSG(scope != nullptr, "%.*s", LIT(p->name));
- return LLVMDIBuilderCreateDebugLocation(p->module->ctx, cast(unsigned)pos.line, cast(unsigned)pos.column, scope, nullptr);
- }
- gb_internal LLVMMetadataRef lb_debug_location_from_ast(lbProcedure *p, Ast *node) {
- GB_ASSERT(node != nullptr);
- return lb_debug_location_from_token_pos(p, ast_token(node).pos);
- }
- gb_internal LLVMMetadataRef lb_debug_end_location_from_ast(lbProcedure *p, Ast *node) {
- GB_ASSERT(node != nullptr);
- return lb_debug_location_from_token_pos(p, ast_end_token(node).pos);
- }
- gb_internal LLVMMetadataRef lb_debug_type_internal_proc(lbModule *m, Type *type) {
- i64 size = type_size_of(type); // Check size
- gb_unused(size);
- GB_ASSERT(type != t_invalid);
- /* unsigned const word_size = cast(unsigned)build_context.word_size;
- unsigned const word_bits = cast(unsigned)(8*build_context.word_size); */
- GB_ASSERT(type->kind == Type_Proc);
- unsigned parameter_count = 1;
- for (i32 i = 0; i < type->Proc.param_count; i++) {
- Entity *e = type->Proc.params->Tuple.variables[i];
- if (e->kind == Entity_Variable) {
- parameter_count += 1;
- }
- }
- LLVMMetadataRef *parameters = gb_alloc_array(permanent_allocator(), LLVMMetadataRef, parameter_count);
- unsigned param_index = 0;
- if (type->Proc.result_count == 0) {
- parameters[param_index++] = nullptr;
- } else {
- parameters[param_index++] = lb_debug_type(m, type->Proc.results);
- }
- LLVMMetadataRef file = nullptr;
- for (i32 i = 0; i < type->Proc.param_count; i++) {
- Entity *e = type->Proc.params->Tuple.variables[i];
- if (e->kind != Entity_Variable) {
- continue;
- }
- parameters[param_index] = lb_debug_type(m, e->type);
- param_index += 1;
- }
- LLVMDIFlags flags = LLVMDIFlagZero;
- if (type->Proc.diverging) {
- flags = LLVMDIFlagNoReturn;
- }
- return LLVMDIBuilderCreateSubroutineType(m->debug_builder, file, parameters, parameter_count, flags);
- }
- gb_internal LLVMMetadataRef lb_debug_struct_field(lbModule *m, String const &name, Type *type, u64 offset_in_bits) {
- unsigned field_line = 1;
- LLVMDIFlags field_flags = LLVMDIFlagZero;
- AstPackage *pkg = m->info->runtime_package;
- GB_ASSERT(pkg->files.count != 0);
- LLVMMetadataRef file = lb_get_llvm_metadata(m, pkg->files[0]);
- LLVMMetadataRef scope = file;
- return LLVMDIBuilderCreateMemberType(m->debug_builder, scope, cast(char const *)name.text, name.len, file, field_line,
- 8*cast(u64)type_size_of(type), 8*cast(u32)type_align_of(type), offset_in_bits,
- field_flags, lb_debug_type(m, type)
- );
- }
- gb_internal LLVMMetadataRef lb_debug_basic_struct(lbModule *m, String const &name, u64 size_in_bits, u32 align_in_bits, LLVMMetadataRef *elements, unsigned element_count) {
- AstPackage *pkg = m->info->runtime_package;
- GB_ASSERT(pkg->files.count != 0);
- LLVMMetadataRef file = lb_get_llvm_metadata(m, pkg->files[0]);
- LLVMMetadataRef scope = file;
- return LLVMDIBuilderCreateStructType(m->debug_builder, scope, cast(char const *)name.text, name.len, file, 1, size_in_bits, align_in_bits, LLVMDIFlagZero, nullptr, elements, element_count, 0, nullptr, "", 0);
- }
- gb_internal LLVMMetadataRef lb_debug_type_basic_type(lbModule *m, String const &name, u64 size_in_bits, LLVMDWARFTypeEncoding encoding, LLVMDIFlags flags = LLVMDIFlagZero) {
- LLVMMetadataRef basic_type = LLVMDIBuilderCreateBasicType(m->debug_builder, cast(char const *)name.text, name.len, size_in_bits, encoding, flags);
- #if 1
- LLVMMetadataRef final_decl = LLVMDIBuilderCreateTypedef(m->debug_builder, basic_type, cast(char const *)name.text, name.len, nullptr, 0, nullptr, cast(u32)size_in_bits);
- return final_decl;
- #else
- return basic_type;
- #endif
- }
- gb_internal LLVMMetadataRef lb_debug_type_internal(lbModule *m, Type *type) {
- i64 size = type_size_of(type); // Check size
- gb_unused(size);
- GB_ASSERT(type != t_invalid);
- /* unsigned const word_size = cast(unsigned)build_context.word_size; */
- unsigned const word_bits = cast(unsigned)(8*build_context.word_size);
- switch (type->kind) {
- case Type_Basic:
- switch (type->Basic.kind) {
- case Basic_llvm_bool: return lb_debug_type_basic_type(m, str_lit("llvm bool"), 1, LLVMDWARFTypeEncoding_Boolean);
- case Basic_bool: return lb_debug_type_basic_type(m, str_lit("bool"), 8, LLVMDWARFTypeEncoding_Boolean);
- case Basic_b8: return lb_debug_type_basic_type(m, str_lit("b8"), 8, LLVMDWARFTypeEncoding_Boolean);
- case Basic_b16: return lb_debug_type_basic_type(m, str_lit("b16"), 16, LLVMDWARFTypeEncoding_Boolean);
- case Basic_b32: return lb_debug_type_basic_type(m, str_lit("b32"), 32, LLVMDWARFTypeEncoding_Boolean);
- case Basic_b64: return lb_debug_type_basic_type(m, str_lit("b64"), 64, LLVMDWARFTypeEncoding_Boolean);
- case Basic_i8: return lb_debug_type_basic_type(m, str_lit("i8"), 8, LLVMDWARFTypeEncoding_Signed);
- case Basic_u8: return lb_debug_type_basic_type(m, str_lit("u8"), 8, LLVMDWARFTypeEncoding_Unsigned);
- case Basic_i16: return lb_debug_type_basic_type(m, str_lit("i16"), 16, LLVMDWARFTypeEncoding_Signed);
- case Basic_u16: return lb_debug_type_basic_type(m, str_lit("u16"), 16, LLVMDWARFTypeEncoding_Unsigned);
- case Basic_i32: return lb_debug_type_basic_type(m, str_lit("i32"), 32, LLVMDWARFTypeEncoding_Signed);
- case Basic_u32: return lb_debug_type_basic_type(m, str_lit("u32"), 32, LLVMDWARFTypeEncoding_Unsigned);
- case Basic_i64: return lb_debug_type_basic_type(m, str_lit("i64"), 64, LLVMDWARFTypeEncoding_Signed);
- case Basic_u64: return lb_debug_type_basic_type(m, str_lit("u64"), 64, LLVMDWARFTypeEncoding_Unsigned);
- case Basic_i128: return lb_debug_type_basic_type(m, str_lit("i128"), 128, LLVMDWARFTypeEncoding_Signed);
- case Basic_u128: return lb_debug_type_basic_type(m, str_lit("u128"), 128, LLVMDWARFTypeEncoding_Unsigned);
- case Basic_rune: return lb_debug_type_basic_type(m, str_lit("rune"), 32, LLVMDWARFTypeEncoding_Utf);
- case Basic_f16: return lb_debug_type_basic_type(m, str_lit("f16"), 16, LLVMDWARFTypeEncoding_Float);
- case Basic_f32: return lb_debug_type_basic_type(m, str_lit("f32"), 32, LLVMDWARFTypeEncoding_Float);
- case Basic_f64: return lb_debug_type_basic_type(m, str_lit("f64"), 64, LLVMDWARFTypeEncoding_Float);
- case Basic_int: return lb_debug_type_basic_type(m, str_lit("int"), word_bits, LLVMDWARFTypeEncoding_Signed);
- case Basic_uint: return lb_debug_type_basic_type(m, str_lit("uint"), word_bits, LLVMDWARFTypeEncoding_Unsigned);
- case Basic_uintptr: return lb_debug_type_basic_type(m, str_lit("uintptr"), word_bits, LLVMDWARFTypeEncoding_Unsigned);
- case Basic_typeid:
- return lb_debug_type_basic_type(m, str_lit("typeid"), word_bits, LLVMDWARFTypeEncoding_Unsigned);
- // Endian Specific Types
- case Basic_i16le: return lb_debug_type_basic_type(m, str_lit("i16le"), 16, LLVMDWARFTypeEncoding_Signed, LLVMDIFlagLittleEndian);
- case Basic_u16le: return lb_debug_type_basic_type(m, str_lit("u16le"), 16, LLVMDWARFTypeEncoding_Unsigned, LLVMDIFlagLittleEndian);
- case Basic_i32le: return lb_debug_type_basic_type(m, str_lit("i32le"), 32, LLVMDWARFTypeEncoding_Signed, LLVMDIFlagLittleEndian);
- case Basic_u32le: return lb_debug_type_basic_type(m, str_lit("u32le"), 32, LLVMDWARFTypeEncoding_Unsigned, LLVMDIFlagLittleEndian);
- case Basic_i64le: return lb_debug_type_basic_type(m, str_lit("i64le"), 64, LLVMDWARFTypeEncoding_Signed, LLVMDIFlagLittleEndian);
- case Basic_u64le: return lb_debug_type_basic_type(m, str_lit("u64le"), 64, LLVMDWARFTypeEncoding_Unsigned, LLVMDIFlagLittleEndian);
- case Basic_i128le: return lb_debug_type_basic_type(m, str_lit("i128le"), 128, LLVMDWARFTypeEncoding_Signed, LLVMDIFlagLittleEndian);
- case Basic_u128le: return lb_debug_type_basic_type(m, str_lit("u128le"), 128, LLVMDWARFTypeEncoding_Unsigned, LLVMDIFlagLittleEndian);
- case Basic_f16le: return lb_debug_type_basic_type(m, str_lit("f16le"), 16, LLVMDWARFTypeEncoding_Float, LLVMDIFlagLittleEndian);
- case Basic_f32le: return lb_debug_type_basic_type(m, str_lit("f32le"), 32, LLVMDWARFTypeEncoding_Float, LLVMDIFlagLittleEndian);
- case Basic_f64le: return lb_debug_type_basic_type(m, str_lit("f64le"), 64, LLVMDWARFTypeEncoding_Float, LLVMDIFlagLittleEndian);
- case Basic_i16be: return lb_debug_type_basic_type(m, str_lit("i16be"), 16, LLVMDWARFTypeEncoding_Signed, LLVMDIFlagBigEndian);
- case Basic_u16be: return lb_debug_type_basic_type(m, str_lit("u16be"), 16, LLVMDWARFTypeEncoding_Unsigned, LLVMDIFlagBigEndian);
- case Basic_i32be: return lb_debug_type_basic_type(m, str_lit("i32be"), 32, LLVMDWARFTypeEncoding_Signed, LLVMDIFlagBigEndian);
- case Basic_u32be: return lb_debug_type_basic_type(m, str_lit("u32be"), 32, LLVMDWARFTypeEncoding_Unsigned, LLVMDIFlagBigEndian);
- case Basic_i64be: return lb_debug_type_basic_type(m, str_lit("i64be"), 64, LLVMDWARFTypeEncoding_Signed, LLVMDIFlagBigEndian);
- case Basic_u64be: return lb_debug_type_basic_type(m, str_lit("u64be"), 64, LLVMDWARFTypeEncoding_Unsigned, LLVMDIFlagBigEndian);
- case Basic_i128be: return lb_debug_type_basic_type(m, str_lit("i128be"), 128, LLVMDWARFTypeEncoding_Signed, LLVMDIFlagBigEndian);
- case Basic_u128be: return lb_debug_type_basic_type(m, str_lit("u128be"), 128, LLVMDWARFTypeEncoding_Unsigned, LLVMDIFlagBigEndian);
- case Basic_f16be: return lb_debug_type_basic_type(m, str_lit("f16be"), 16, LLVMDWARFTypeEncoding_Float, LLVMDIFlagLittleEndian);
- case Basic_f32be: return lb_debug_type_basic_type(m, str_lit("f32be"), 32, LLVMDWARFTypeEncoding_Float, LLVMDIFlagLittleEndian);
- case Basic_f64be: return lb_debug_type_basic_type(m, str_lit("f64be"), 64, LLVMDWARFTypeEncoding_Float, LLVMDIFlagLittleEndian);
- case Basic_complex32:
- {
- LLVMMetadataRef elements[2] = {};
- elements[0] = lb_debug_struct_field(m, str_lit("real"), t_f16, 0);
- elements[1] = lb_debug_struct_field(m, str_lit("imag"), t_f16, 4);
- return lb_debug_basic_struct(m, str_lit("complex32"), 64, 32, elements, gb_count_of(elements));
- }
- case Basic_complex64:
- {
- LLVMMetadataRef elements[2] = {};
- elements[0] = lb_debug_struct_field(m, str_lit("real"), t_f32, 0);
- elements[1] = lb_debug_struct_field(m, str_lit("imag"), t_f32, 4);
- return lb_debug_basic_struct(m, str_lit("complex64"), 64, 32, elements, gb_count_of(elements));
- }
- case Basic_complex128:
- {
- LLVMMetadataRef elements[2] = {};
- elements[0] = lb_debug_struct_field(m, str_lit("real"), t_f64, 0);
- elements[1] = lb_debug_struct_field(m, str_lit("imag"), t_f64, 8);
- return lb_debug_basic_struct(m, str_lit("complex128"), 128, 64, elements, gb_count_of(elements));
- }
- case Basic_quaternion64:
- {
- LLVMMetadataRef elements[4] = {};
- elements[0] = lb_debug_struct_field(m, str_lit("imag"), t_f16, 0);
- elements[1] = lb_debug_struct_field(m, str_lit("jmag"), t_f16, 4);
- elements[2] = lb_debug_struct_field(m, str_lit("kmag"), t_f16, 8);
- elements[3] = lb_debug_struct_field(m, str_lit("real"), t_f16, 12);
- return lb_debug_basic_struct(m, str_lit("quaternion64"), 128, 32, elements, gb_count_of(elements));
- }
- case Basic_quaternion128:
- {
- LLVMMetadataRef elements[4] = {};
- elements[0] = lb_debug_struct_field(m, str_lit("imag"), t_f32, 0);
- elements[1] = lb_debug_struct_field(m, str_lit("jmag"), t_f32, 4);
- elements[2] = lb_debug_struct_field(m, str_lit("kmag"), t_f32, 8);
- elements[3] = lb_debug_struct_field(m, str_lit("real"), t_f32, 12);
- return lb_debug_basic_struct(m, str_lit("quaternion128"), 128, 32, elements, gb_count_of(elements));
- }
- case Basic_quaternion256:
- {
- LLVMMetadataRef elements[4] = {};
- elements[0] = lb_debug_struct_field(m, str_lit("imag"), t_f64, 0);
- elements[1] = lb_debug_struct_field(m, str_lit("jmag"), t_f64, 8);
- elements[2] = lb_debug_struct_field(m, str_lit("kmag"), t_f64, 16);
- elements[3] = lb_debug_struct_field(m, str_lit("real"), t_f64, 24);
- return lb_debug_basic_struct(m, str_lit("quaternion256"), 256, 32, elements, gb_count_of(elements));
- }
- case Basic_rawptr:
- {
- LLVMMetadataRef void_type = lb_debug_type_basic_type(m, str_lit("void"), 8, LLVMDWARFTypeEncoding_Unsigned);
- return LLVMDIBuilderCreatePointerType(m->debug_builder, void_type, word_bits, word_bits, LLVMDWARFTypeEncoding_Address, "rawptr", 6);
- }
- case Basic_string:
- {
- LLVMMetadataRef elements[2] = {};
- elements[0] = lb_debug_struct_field(m, str_lit("data"), t_u8_ptr, 0);
- elements[1] = lb_debug_struct_field(m, str_lit("len"), t_int, word_bits);
- return lb_debug_basic_struct(m, str_lit("string"), 2*word_bits, word_bits, elements, gb_count_of(elements));
- }
- case Basic_cstring:
- {
- LLVMMetadataRef char_type = lb_debug_type_basic_type(m, str_lit("char"), 8, LLVMDWARFTypeEncoding_Unsigned);
- return LLVMDIBuilderCreatePointerType(m->debug_builder, char_type, word_bits, word_bits, 0, "cstring", 7);
- }
- case Basic_any:
- {
- LLVMMetadataRef elements[2] = {};
- elements[0] = lb_debug_struct_field(m, str_lit("data"), t_rawptr, 0);
- elements[1] = lb_debug_struct_field(m, str_lit("id"), t_typeid, word_bits);
- return lb_debug_basic_struct(m, str_lit("any"), 2*word_bits, word_bits, elements, gb_count_of(elements));
- }
- // Untyped types
- case Basic_UntypedBool: GB_PANIC("Basic_UntypedBool"); break;
- case Basic_UntypedInteger: GB_PANIC("Basic_UntypedInteger"); break;
- case Basic_UntypedFloat: GB_PANIC("Basic_UntypedFloat"); break;
- case Basic_UntypedComplex: GB_PANIC("Basic_UntypedComplex"); break;
- case Basic_UntypedQuaternion: GB_PANIC("Basic_UntypedQuaternion"); break;
- case Basic_UntypedString: GB_PANIC("Basic_UntypedString"); break;
- case Basic_UntypedRune: GB_PANIC("Basic_UntypedRune"); break;
- case Basic_UntypedNil: GB_PANIC("Basic_UntypedNil"); break;
- case Basic_UntypedUndef: GB_PANIC("Basic_UntypedUndef"); break;
- default: GB_PANIC("Basic Unhandled"); break;
- }
- break;
- case Type_Named:
- GB_PANIC("Type_Named should be handled in lb_debug_type separately");
- case Type_SoaPointer:
- return LLVMDIBuilderCreatePointerType(m->debug_builder, lb_debug_type(m, type->SoaPointer.elem), word_bits, word_bits, 0, nullptr, 0);
- case Type_Pointer:
- return LLVMDIBuilderCreatePointerType(m->debug_builder, lb_debug_type(m, type->Pointer.elem), word_bits, word_bits, 0, nullptr, 0);
- case Type_MultiPointer:
- return LLVMDIBuilderCreatePointerType(m->debug_builder, lb_debug_type(m, type->MultiPointer.elem), word_bits, word_bits, 0, nullptr, 0);
- case Type_Array: {
- LLVMMetadataRef subscripts[1] = {};
- subscripts[0] = LLVMDIBuilderGetOrCreateSubrange(m->debug_builder,
- 0ll,
- type->Array.count
- );
- return LLVMDIBuilderCreateArrayType(m->debug_builder,
- 8*cast(uint64_t)type_size_of(type),
- 8*cast(unsigned)type_align_of(type),
- lb_debug_type(m, type->Array.elem),
- subscripts, gb_count_of(subscripts));
- }
- case Type_EnumeratedArray: {
- LLVMMetadataRef subscripts[1] = {};
- subscripts[0] = LLVMDIBuilderGetOrCreateSubrange(m->debug_builder,
- 0ll,
- type->EnumeratedArray.count
- );
- LLVMMetadataRef array_type = LLVMDIBuilderCreateArrayType(m->debug_builder,
- 8*cast(uint64_t)type_size_of(type),
- 8*cast(unsigned)type_align_of(type),
- lb_debug_type(m, type->EnumeratedArray.elem),
- subscripts, gb_count_of(subscripts));
- gbString name = type_to_string(type, temporary_allocator());
- return LLVMDIBuilderCreateTypedef(m->debug_builder, array_type, name, gb_string_length(name), nullptr, 0, nullptr, cast(u32)(8*type_align_of(type)));
- }
- case Type_Struct:
- case Type_Union:
- case Type_Slice:
- case Type_DynamicArray:
- case Type_Map:
- case Type_BitSet:
- {
- unsigned tag = DW_TAG_structure_type;
- if (is_type_raw_union(type) || is_type_union(type)) {
- tag = DW_TAG_union_type;
- }
- u64 size_in_bits = cast(u64)(8*type_size_of(type));
- u32 align_in_bits = cast(u32)(8*type_size_of(type));
- LLVMDIFlags flags = LLVMDIFlagZero;
- LLVMMetadataRef temp_forward_decl = LLVMDIBuilderCreateReplaceableCompositeType(
- m->debug_builder, tag, "", 0, nullptr, nullptr, 0, 0, size_in_bits, align_in_bits, flags, "", 0
- );
- lbIncompleteDebugType idt = {};
- idt.type = type;
- idt.metadata = temp_forward_decl;
- array_add(&m->debug_incomplete_types, idt);
- lb_set_llvm_metadata(m, type, temp_forward_decl);
- return temp_forward_decl;
- }
- case Type_Enum:
- {
- LLVMMetadataRef scope = nullptr;
- LLVMMetadataRef file = nullptr;
- unsigned line = 0;
- unsigned element_count = cast(unsigned)type->Enum.fields.count;
- LLVMMetadataRef *elements = gb_alloc_array(permanent_allocator(), LLVMMetadataRef, element_count);
- Type *bt = base_enum_type(type);
- LLVMBool is_unsigned = is_type_unsigned(bt);
- for (unsigned i = 0; i < element_count; i++) {
- Entity *f = type->Enum.fields[i];
- GB_ASSERT(f->kind == Entity_Constant);
- String name = f->token.string;
- i64 value = exact_value_to_i64(f->Constant.value);
- elements[i] = LLVMDIBuilderCreateEnumerator(m->debug_builder, cast(char const *)name.text, cast(size_t)name.len, value, is_unsigned);
- }
- LLVMMetadataRef class_type = lb_debug_type(m, bt);
- return LLVMDIBuilderCreateEnumerationType(m->debug_builder, scope, "", 0, file, line, 8*type_size_of(type), 8*cast(unsigned)type_align_of(type), elements, element_count, class_type);
- }
- case Type_Tuple:
- if (type->Tuple.variables.count == 1) {
- return lb_debug_type(m, type->Tuple.variables[0]->type);
- } else {
- type_set_offsets(type);
- LLVMMetadataRef parent_scope = nullptr;
- LLVMMetadataRef scope = nullptr;
- LLVMMetadataRef file = nullptr;
- unsigned line = 0;
- u64 size_in_bits = 8*cast(u64)type_size_of(type);
- u32 align_in_bits = 8*cast(u32)type_align_of(type);
- LLVMDIFlags flags = LLVMDIFlagZero;
- unsigned element_count = cast(unsigned)type->Tuple.variables.count;
- LLVMMetadataRef *elements = gb_alloc_array(permanent_allocator(), LLVMMetadataRef, element_count);
- for (unsigned i = 0; i < element_count; i++) {
- Entity *f = type->Tuple.variables[i];
- GB_ASSERT(f->kind == Entity_Variable);
- String name = f->token.string;
- unsigned field_line = 0;
- LLVMDIFlags field_flags = LLVMDIFlagZero;
- u64 offset_in_bits = 8*cast(u64)type->Tuple.offsets[i];
- elements[i] = LLVMDIBuilderCreateMemberType(m->debug_builder, scope, cast(char const *)name.text, name.len, file, field_line,
- 8*cast(u64)type_size_of(f->type), 8*cast(u32)type_align_of(f->type), offset_in_bits,
- field_flags, lb_debug_type(m, f->type)
- );
- }
- return LLVMDIBuilderCreateStructType(m->debug_builder, parent_scope, "", 0, file, line,
- size_in_bits, align_in_bits, flags,
- nullptr, elements, element_count, 0, nullptr,
- "", 0
- );
- }
- case Type_Proc:
- {
- LLVMMetadataRef proc_underlying_type = lb_debug_type_internal_proc(m, type);
- LLVMMetadataRef pointer_type = LLVMDIBuilderCreatePointerType(m->debug_builder, proc_underlying_type, word_bits, word_bits, 0, nullptr, 0);
- gbString name = type_to_string(type, temporary_allocator());
- return LLVMDIBuilderCreateTypedef(m->debug_builder, pointer_type, name, gb_string_length(name), nullptr, 0, nullptr, cast(u32)(8*type_align_of(type)));
- }
- break;
- case Type_SimdVector:
- {
- LLVMMetadataRef elem = lb_debug_type(m, type->SimdVector.elem);
- LLVMMetadataRef subscripts[1] = {};
- subscripts[0] = LLVMDIBuilderGetOrCreateSubrange(m->debug_builder,
- 0ll,
- type->SimdVector.count
- );
- return LLVMDIBuilderCreateVectorType(
- m->debug_builder,
- 8*cast(unsigned)type_size_of(type), 8*cast(unsigned)type_align_of(type),
- elem, subscripts, gb_count_of(subscripts));
- }
- case Type_RelativePointer: {
- LLVMMetadataRef base_integer = lb_debug_type(m, type->RelativePointer.base_integer);
- gbString name = type_to_string(type, temporary_allocator());
- return LLVMDIBuilderCreateTypedef(m->debug_builder, base_integer, name, gb_string_length(name), nullptr, 0, nullptr, cast(u32)(8*type_align_of(type)));
- }
- case Type_RelativeSlice:
- {
- unsigned element_count = 0;
- LLVMMetadataRef elements[2] = {};
- Type *base_integer = type->RelativeSlice.base_integer;
- elements[0] = lb_debug_struct_field(m, str_lit("data_offset"), base_integer, 0);
- elements[1] = lb_debug_struct_field(m, str_lit("len"), base_integer, 8*type_size_of(base_integer));
- gbString name = type_to_string(type, temporary_allocator());
- return LLVMDIBuilderCreateStructType(m->debug_builder, nullptr, name, gb_string_length(name), nullptr, 0, 2*word_bits, word_bits, LLVMDIFlagZero, nullptr, elements, element_count, 0, nullptr, "", 0);
- }
-
- case Type_Matrix: {
- LLVMMetadataRef subscripts[1] = {};
- subscripts[0] = LLVMDIBuilderGetOrCreateSubrange(m->debug_builder,
- 0ll,
- matrix_type_total_internal_elems(type)
- );
- return LLVMDIBuilderCreateArrayType(m->debug_builder,
- 8*cast(uint64_t)type_size_of(type),
- 8*cast(unsigned)type_align_of(type),
- lb_debug_type(m, type->Matrix.elem),
- subscripts, gb_count_of(subscripts));
- }
- }
- GB_PANIC("Invalid type %s", type_to_string(type));
- return nullptr;
- }
- gb_internal LLVMMetadataRef lb_get_base_scope_metadata(lbModule *m, Scope *scope) {
- LLVMMetadataRef found = nullptr;
- for (;;) {
- if (scope == nullptr) {
- return nullptr;
- }
- if (scope->flags & ScopeFlag_Proc) {
- found = lb_get_llvm_metadata(m, scope->procedure_entity);
- if (found) {
- return found;
- }
- }
- if (scope->flags & ScopeFlag_File) {
- found = lb_get_llvm_metadata(m, scope->file);
- if (found) {
- return found;
- }
- }
- scope = scope->parent;
- }
- }
- gb_internal LLVMMetadataRef lb_debug_type(lbModule *m, Type *type) {
- GB_ASSERT(type != nullptr);
- LLVMMetadataRef found = lb_get_llvm_metadata(m, type);
- if (found != nullptr) {
- return found;
- }
- if (type->kind == Type_Named) {
- LLVMMetadataRef file = nullptr;
- unsigned line = 0;
- LLVMMetadataRef scope = nullptr;
- if (type->Named.type_name != nullptr) {
- Entity *e = type->Named.type_name;
- scope = lb_get_base_scope_metadata(m, e->scope);
- if (scope != nullptr) {
- file = LLVMDIScopeGetFile(scope);
- }
- line = cast(unsigned)e->token.pos.line;
- }
- // TODO(bill): location data for Type_Named
- u64 size_in_bits = 8*type_size_of(type);
- u32 align_in_bits = 8*cast(u32)type_align_of(type);
- String name = type->Named.name;
- char const *name_text = cast(char const *)name.text;
- size_t name_len = cast(size_t)name.len;
- unsigned tag = DW_TAG_structure_type;
- if (is_type_raw_union(type) || is_type_union(type)) {
- tag = DW_TAG_union_type;
- }
- LLVMDIFlags flags = LLVMDIFlagZero;
- Type *bt = base_type(type->Named.base);
- lbIncompleteDebugType idt = {};
- idt.type = type;
- switch (bt->kind) {
- case Type_Enum:
- {
- unsigned line = 0;
- unsigned element_count = cast(unsigned)bt->Enum.fields.count;
- LLVMMetadataRef *elements = gb_alloc_array(permanent_allocator(), LLVMMetadataRef, element_count);
- Type *ct = base_enum_type(type);
- LLVMBool is_unsigned = is_type_unsigned(ct);
- for (unsigned i = 0; i < element_count; i++) {
- Entity *f = bt->Enum.fields[i];
- GB_ASSERT(f->kind == Entity_Constant);
- String name = f->token.string;
- i64 value = exact_value_to_i64(f->Constant.value);
- elements[i] = LLVMDIBuilderCreateEnumerator(m->debug_builder, cast(char const *)name.text, cast(size_t)name.len, value, is_unsigned);
- }
- LLVMMetadataRef class_type = lb_debug_type(m, ct);
- return LLVMDIBuilderCreateEnumerationType(m->debug_builder, scope, name_text, name_len, file, line, 8*type_size_of(type), 8*cast(unsigned)type_align_of(type), elements, element_count, class_type);
- }
- default:
- {
- LLVMMetadataRef debug_bt = lb_debug_type(m, bt);
- LLVMMetadataRef final_decl = LLVMDIBuilderCreateTypedef(m->debug_builder, debug_bt, name_text, name_len, file, line, scope, align_in_bits);
- lb_set_llvm_metadata(m, type, final_decl);
- return final_decl;
- }
- case Type_Slice:
- case Type_DynamicArray:
- case Type_Map:
- case Type_Struct:
- case Type_Union:
- case Type_BitSet:
- {
- LLVMMetadataRef temp_forward_decl = LLVMDIBuilderCreateReplaceableCompositeType(
- m->debug_builder, tag, name_text, name_len, nullptr, nullptr, 0, 0, size_in_bits, align_in_bits, flags, "", 0
- );
- idt.metadata = temp_forward_decl;
- array_add(&m->debug_incomplete_types, idt);
- lb_set_llvm_metadata(m, type, temp_forward_decl);
- LLVMMetadataRef dummy = nullptr;
- switch (bt->kind) {
- case Type_Slice:
- dummy = lb_debug_type(m, bt->Slice.elem);
- dummy = lb_debug_type(m, alloc_type_pointer(bt->Slice.elem));
- dummy = lb_debug_type(m, t_int);
- break;
- case Type_DynamicArray:
- dummy = lb_debug_type(m, bt->DynamicArray.elem);
- dummy = lb_debug_type(m, alloc_type_pointer(bt->DynamicArray.elem));
- dummy = lb_debug_type(m, t_int);
- dummy = lb_debug_type(m, t_allocator);
- break;
- case Type_Map:
- dummy = lb_debug_type(m, bt->Map.key);
- dummy = lb_debug_type(m, bt->Map.value);
- dummy = lb_debug_type(m, t_int);
- dummy = lb_debug_type(m, t_allocator);
- dummy = lb_debug_type(m, t_uintptr);
- break;
- case Type_BitSet:
- if (bt->BitSet.elem) dummy = lb_debug_type(m, bt->BitSet.elem);
- if (bt->BitSet.underlying) dummy = lb_debug_type(m, bt->BitSet.underlying);
- break;
- }
- return temp_forward_decl;
- }
- }
- }
- LLVMMetadataRef dt = lb_debug_type_internal(m, type);
- lb_set_llvm_metadata(m, type, dt);
- return dt;
- }
- gb_internal void lb_debug_complete_types(lbModule *m) {
- /* unsigned const word_size = cast(unsigned)build_context.word_size; */
- unsigned const word_bits = cast(unsigned)(8*build_context.word_size);
- for_array(debug_incomplete_type_index, m->debug_incomplete_types) {
- auto const &idt = m->debug_incomplete_types[debug_incomplete_type_index];
- GB_ASSERT(idt.type != nullptr);
- GB_ASSERT(idt.metadata != nullptr);
- Type *t = idt.type;
- Type *bt = base_type(t);
- LLVMMetadataRef parent_scope = nullptr;
- LLVMMetadataRef file = nullptr;
- unsigned line_number = 0;
- u64 size_in_bits = 8*type_size_of(t);
- u32 align_in_bits = cast(u32)(8*type_align_of(t));
- LLVMDIFlags flags = LLVMDIFlagZero;
- LLVMMetadataRef derived_from = nullptr;
- LLVMMetadataRef *elements = nullptr;
- unsigned element_count = 0;
- unsigned runtime_lang = 0; // Objective-C runtime version
- char const *unique_id = "";
- LLVMMetadataRef vtable_holder = nullptr;
- size_t unique_id_len = 0;
- LLVMMetadataRef record_scope = nullptr;
- switch (bt->kind) {
- case Type_Slice:
- case Type_DynamicArray:
- case Type_Map:
- case Type_Struct:
- case Type_Union:
- case Type_BitSet: {
- bool is_union = is_type_raw_union(bt) || is_type_union(bt);
- String name = str_lit("<anonymous-struct>");
- if (t->kind == Type_Named) {
- name = t->Named.name;
- if (t->Named.type_name && t->Named.type_name->pkg && t->Named.type_name->pkg->name.len != 0) {
- name = concatenate3_strings(temporary_allocator(), t->Named.type_name->pkg->name, str_lit("."), t->Named.name);
- }
- LLVMMetadataRef file = nullptr;
- unsigned line = 0;
- LLVMMetadataRef file_scope = nullptr;
- if (t->Named.type_name != nullptr) {
- Entity *e = t->Named.type_name;
- file_scope = lb_get_llvm_metadata(m, e->scope);
- if (file_scope != nullptr) {
- file = LLVMDIScopeGetFile(file_scope);
- }
- line = cast(unsigned)e->token.pos.line;
- }
- // TODO(bill): location data for Type_Named
- } else {
- name = make_string_c(type_to_string(t, temporary_allocator()));
- }
- switch (bt->kind) {
- case Type_Slice:
- element_count = 2;
- elements = gb_alloc_array(temporary_allocator(), LLVMMetadataRef, element_count);
- #if defined(GB_SYSTEM_WINDOWS)
- elements[0] = lb_debug_struct_field(m, str_lit("data"), alloc_type_pointer(bt->Slice.elem), 0*word_bits);
- #else
- // FIX HACK TODO(bill): For some reason this causes a crash in *nix systems due to the reference counting
- // of the debug type information
- elements[0] = lb_debug_struct_field(m, str_lit("data"), t_rawptr, 0*word_bits);
- #endif
- elements[1] = lb_debug_struct_field(m, str_lit("len"), t_int, 1*word_bits);
- break;
- case Type_DynamicArray:
- element_count = 4;
- elements = gb_alloc_array(temporary_allocator(), LLVMMetadataRef, element_count);
- #if defined(GB_SYSTEM_WINDOWS)
- elements[0] = lb_debug_struct_field(m, str_lit("data"), alloc_type_pointer(bt->DynamicArray.elem), 0*word_bits);
- #else
- // FIX HACK TODO(bill): For some reason this causes a crash in *nix systems due to the reference counting
- // of the debug type information
- elements[0] = lb_debug_struct_field(m, str_lit("data"), t_rawptr, 0*word_bits);
- #endif
- elements[1] = lb_debug_struct_field(m, str_lit("len"), t_int, 1*word_bits);
- elements[2] = lb_debug_struct_field(m, str_lit("cap"), t_int, 2*word_bits);
- elements[3] = lb_debug_struct_field(m, str_lit("allocator"), t_allocator, 3*word_bits);
- break;
- case Type_Map:
- GB_ASSERT(t_raw_map != nullptr);
- bt = base_type(t_raw_map);
- /*fallthrough*/
- case Type_Struct:
- if (file == nullptr) {
- if (bt->Struct.node) {
- file = lb_get_llvm_metadata(m, bt->Struct.node->file());
- line_number = cast(unsigned)ast_token(bt->Struct.node).pos.line;
- }
- }
- type_set_offsets(bt);
- {
- isize element_offset = 0;
- record_scope = lb_get_llvm_metadata(m, bt->Struct.scope);
- switch (bt->Struct.soa_kind) {
- case StructSoa_Slice: element_offset = 1; break;
- case StructSoa_Dynamic: element_offset = 3; break;
- }
- element_count = cast(unsigned)(bt->Struct.fields.count + element_offset);
- elements = gb_alloc_array(temporary_allocator(), LLVMMetadataRef, element_count);
-
- isize field_size_bits = 8*type_size_of(bt) - element_offset*word_bits;
-
- switch (bt->Struct.soa_kind) {
- case StructSoa_Slice:
- elements[0] = LLVMDIBuilderCreateMemberType(
- m->debug_builder, record_scope,
- ".len", 4,
- file, 0,
- 8*cast(u64)type_size_of(t_int), 8*cast(u32)type_align_of(t_int),
- field_size_bits,
- LLVMDIFlagZero, lb_debug_type(m, t_int)
- );
- break;
- case StructSoa_Dynamic:
- elements[0] = LLVMDIBuilderCreateMemberType(
- m->debug_builder, record_scope,
- ".len", 4,
- file, 0,
- 8*cast(u64)type_size_of(t_int), 8*cast(u32)type_align_of(t_int),
- field_size_bits + 0*word_bits,
- LLVMDIFlagZero, lb_debug_type(m, t_int)
- );
- elements[1] = LLVMDIBuilderCreateMemberType(
- m->debug_builder, record_scope,
- ".cap", 4,
- file, 0,
- 8*cast(u64)type_size_of(t_int), 8*cast(u32)type_align_of(t_int),
- field_size_bits + 1*word_bits,
- LLVMDIFlagZero, lb_debug_type(m, t_int)
- );
- elements[2] = LLVMDIBuilderCreateMemberType(
- m->debug_builder, record_scope,
- ".allocator", 10,
- file, 0,
- 8*cast(u64)type_size_of(t_int), 8*cast(u32)type_align_of(t_int),
- field_size_bits + 2*word_bits,
- LLVMDIFlagZero, lb_debug_type(m, t_allocator)
- );
- break;
- }
- for_array(j, bt->Struct.fields) {
- Entity *f = bt->Struct.fields[j];
- String fname = f->token.string;
- unsigned field_line = 0;
- LLVMDIFlags field_flags = LLVMDIFlagZero;
- GB_ASSERT(bt->Struct.offsets != nullptr);
- u64 offset_in_bits = 8*cast(u64)bt->Struct.offsets[j];
- elements[element_offset+j] = LLVMDIBuilderCreateMemberType(
- m->debug_builder, record_scope,
- cast(char const *)fname.text, cast(size_t)fname.len,
- file, field_line,
- 8*cast(u64)type_size_of(f->type), 8*cast(u32)type_align_of(f->type),
- offset_in_bits,
- field_flags, lb_debug_type(m, f->type)
- );
- }
- }
- break;
- case Type_Union:
- {
- if (file == nullptr) {
- GB_ASSERT(bt->Union.node != nullptr);
- file = lb_get_llvm_metadata(m, bt->Union.node->file());
- line_number = cast(unsigned)ast_token(bt->Union.node).pos.line;
- }
- isize index_offset = 1;
- if (is_type_union_maybe_pointer(bt)) {
- index_offset = 0;
- }
- record_scope = lb_get_llvm_metadata(m, bt->Union.scope);
- element_count = cast(unsigned)bt->Union.variants.count;
- if (index_offset > 0) {
- element_count += 1;
- }
- elements = gb_alloc_array(temporary_allocator(), LLVMMetadataRef, element_count);
- if (index_offset > 0) {
- Type *tag_type = union_tag_type(bt);
- unsigned field_line = 0;
- u64 offset_in_bits = 8*cast(u64)bt->Union.variant_block_size;
- LLVMDIFlags field_flags = LLVMDIFlagZero;
- elements[0] = LLVMDIBuilderCreateMemberType(
- m->debug_builder, record_scope,
- "tag", 3,
- file, field_line,
- 8*cast(u64)type_size_of(tag_type), 8*cast(u32)type_align_of(tag_type),
- offset_in_bits,
- field_flags, lb_debug_type(m, tag_type)
- );
- }
- for_array(j, bt->Union.variants) {
- Type *variant = bt->Union.variants[j];
- unsigned field_index = cast(unsigned)(index_offset+j);
- char name[16] = {};
- gb_snprintf(name, gb_size_of(name), "v%u", field_index);
- isize name_len = gb_strlen(name);
- unsigned field_line = 0;
- LLVMDIFlags field_flags = LLVMDIFlagZero;
- u64 offset_in_bits = 0;
- elements[field_index] = LLVMDIBuilderCreateMemberType(
- m->debug_builder, record_scope,
- name, name_len,
- file, field_line,
- 8*cast(u64)type_size_of(variant), 8*cast(u32)type_align_of(variant),
- offset_in_bits,
- field_flags, lb_debug_type(m, variant)
- );
- }
- }
- break;
- case Type_BitSet:
- {
- if (file == nullptr) {
- GB_ASSERT(bt->BitSet.node != nullptr);
- file = lb_get_llvm_metadata(m, bt->BitSet.node->file());
- line_number = cast(unsigned)ast_token(bt->BitSet.node).pos.line;
- }
- LLVMMetadataRef bit_set_field_type = lb_debug_type(m, t_bool);
- LLVMMetadataRef scope = file;
- Type *elem = base_type(bt->BitSet.elem);
- if (elem->kind == Type_Enum) {
- element_count = cast(unsigned)elem->Enum.fields.count;
- elements = gb_alloc_array(temporary_allocator(), LLVMMetadataRef, element_count);
- for_array(i, elem->Enum.fields) {
- Entity *f = elem->Enum.fields[i];
- GB_ASSERT(f->kind == Entity_Constant);
- i64 val = exact_value_to_i64(f->Constant.value);
- String name = f->token.string;
- u64 offset_in_bits = cast(u64)(val - bt->BitSet.lower);
- elements[i] = LLVMDIBuilderCreateBitFieldMemberType(
- m->debug_builder,
- scope,
- cast(char const *)name.text, name.len,
- file, line_number,
- 1,
- offset_in_bits,
- 0,
- LLVMDIFlagZero,
- bit_set_field_type
- );
- }
- } else {
- char name[32] = {};
- GB_ASSERT(is_type_integer(elem));
- i64 count = bt->BitSet.upper - bt->BitSet.lower + 1;
- GB_ASSERT(0 <= count);
- element_count = cast(unsigned)count;
- elements = gb_alloc_array(temporary_allocator(), LLVMMetadataRef, element_count);
- for (unsigned i = 0; i < element_count; i++) {
- u64 offset_in_bits = i;
- i64 val = bt->BitSet.lower + cast(i64)i;
- gb_snprintf(name, gb_count_of(name), "%lld", cast(long long)val);
- elements[i] = LLVMDIBuilderCreateBitFieldMemberType(
- m->debug_builder,
- scope,
- name, gb_strlen(name),
- file, line_number,
- 1,
- offset_in_bits,
- 0,
- LLVMDIFlagZero,
- bit_set_field_type
- );
- }
- }
- }
- }
- LLVMMetadataRef final_metadata = nullptr;
- if (is_union) {
- final_metadata = LLVMDIBuilderCreateUnionType(
- m->debug_builder,
- parent_scope,
- cast(char const *)name.text, cast(size_t)name.len,
- file, line_number,
- size_in_bits, align_in_bits,
- flags,
- elements, element_count,
- runtime_lang,
- unique_id, unique_id_len
- );
- } else {
- final_metadata = LLVMDIBuilderCreateStructType(
- m->debug_builder,
- parent_scope,
- cast(char const *)name.text, cast(size_t)name.len,
- file, line_number,
- size_in_bits, align_in_bits,
- flags,
- derived_from,
- elements, element_count,
- runtime_lang,
- vtable_holder,
- unique_id, unique_id_len
- );
- }
- LLVMMetadataReplaceAllUsesWith(idt.metadata, final_metadata);
- lb_set_llvm_metadata(m, idt.type, final_metadata);
- } break;
- default:
- GB_PANIC("invalid incomplete debug type");
- break;
- }
- }
- array_clear(&m->debug_incomplete_types);
- }
- gb_internal void lb_add_debug_local_variable(lbProcedure *p, LLVMValueRef ptr, Type *type, Token const &token) {
- if (p->debug_info == nullptr) {
- return;
- }
- if (type == nullptr) {
- return;
- }
- if (type == t_invalid) {
- return;
- }
- if (p->body == nullptr) {
- return;
- }
- lbModule *m = p->module;
- String const &name = token.string;
- if (name == "" || name == "_") {
- return;
- }
- if (lb_get_llvm_metadata(m, ptr) != nullptr) {
- // Already been set
- return;
- }
- AstFile *file = p->body->file();
- LLVMMetadataRef llvm_scope = lb_get_current_debug_scope(p);
- LLVMMetadataRef llvm_file = lb_get_llvm_metadata(m, file);
- GB_ASSERT(llvm_scope != nullptr);
- if (llvm_file == nullptr) {
- llvm_file = LLVMDIScopeGetFile(llvm_scope);
- }
- if (llvm_file == nullptr) {
- return;
- }
- unsigned alignment_in_bits = cast(unsigned)(8*type_align_of(type));
- LLVMDIFlags flags = LLVMDIFlagZero;
- LLVMBool always_preserve = build_context.optimization_level == 0;
- LLVMMetadataRef debug_type = lb_debug_type(m, type);
- LLVMMetadataRef var_info = LLVMDIBuilderCreateAutoVariable(
- m->debug_builder, llvm_scope,
- cast(char const *)name.text, cast(size_t)name.len,
- llvm_file, token.pos.line,
- debug_type,
- always_preserve, flags, alignment_in_bits
- );
- LLVMValueRef storage = ptr;
- LLVMBasicBlockRef block = p->curr_block->block;
- LLVMMetadataRef llvm_debug_loc = lb_debug_location_from_token_pos(p, token.pos);
- LLVMMetadataRef llvm_expr = LLVMDIBuilderCreateExpression(m->debug_builder, nullptr, 0);
- lb_set_llvm_metadata(m, ptr, llvm_expr);
- LLVMDIBuilderInsertDeclareAtEnd(m->debug_builder, storage, var_info, llvm_expr, llvm_debug_loc, block);
- }
- gb_internal void lb_add_debug_param_variable(lbProcedure *p, LLVMValueRef ptr, Type *type, Token const &token, unsigned arg_number, lbBlock *block, lbArgKind arg_kind) {
- if (p->debug_info == nullptr) {
- return;
- }
- if (type == nullptr) {
- return;
- }
- if (type == t_invalid) {
- return;
- }
- if (p->body == nullptr) {
- return;
- }
- lbModule *m = p->module;
- String const &name = token.string;
- if (name == "" || name == "_") {
- return;
- }
- if (lb_get_llvm_metadata(m, ptr) != nullptr) {
- // Already been set
- return;
- }
- AstFile *file = p->body->file();
- LLVMMetadataRef llvm_scope = lb_get_current_debug_scope(p);
- LLVMMetadataRef llvm_file = lb_get_llvm_metadata(m, file);
- GB_ASSERT(llvm_scope != nullptr);
- if (llvm_file == nullptr) {
- llvm_file = LLVMDIScopeGetFile(llvm_scope);
- }
- if (llvm_file == nullptr) {
- return;
- }
- LLVMDIFlags flags = LLVMDIFlagZero;
- LLVMBool always_preserve = build_context.optimization_level == 0;
- LLVMMetadataRef debug_type = lb_debug_type(m, type);
- LLVMMetadataRef var_info = LLVMDIBuilderCreateParameterVariable(
- m->debug_builder, llvm_scope,
- cast(char const *)name.text, cast(size_t)name.len,
- arg_number,
- llvm_file, token.pos.line,
- debug_type,
- always_preserve, flags
- );
- LLVMValueRef storage = ptr;
- LLVMMetadataRef llvm_debug_loc = lb_debug_location_from_token_pos(p, token.pos);
- LLVMMetadataRef llvm_expr = LLVMDIBuilderCreateExpression(m->debug_builder, nullptr, 0);
- lb_set_llvm_metadata(m, ptr, llvm_expr);
- // NOTE(bill, 2022-02-01): For parameter values, you must insert them at the end of the decl block
- // The reason is that if the parameter is at index 0 and a pointer, there is not such things as an
- // instruction "before" it.
- switch (arg_kind) {
- case lbArg_Direct:
- LLVMDIBuilderInsertDbgValueAtEnd(m->debug_builder, storage, var_info, llvm_expr, llvm_debug_loc, block->block);
- break;
- case lbArg_Indirect:
- LLVMDIBuilderInsertDeclareAtEnd(m->debug_builder, storage, var_info, llvm_expr, llvm_debug_loc, block->block);
- break;
- }
- }
- gb_internal void lb_add_debug_context_variable(lbProcedure *p, lbAddr const &ctx) {
- if (!p->debug_info || !p->body) {
- return;
- }
- LLVMMetadataRef loc = LLVMGetCurrentDebugLocation2(p->builder);
- if (!loc) {
- return;
- }
- TokenPos pos = {};
- pos.file_id = p->body->file_id;
- pos.line = LLVMDILocationGetLine(loc);
- pos.column = LLVMDILocationGetColumn(loc);
- Token token = {};
- token.kind = Token_context;
- token.string = str_lit("context");
- token.pos = pos;
- LLVMValueRef ptr = ctx.addr.value;
- while (LLVMIsABitCastInst(ptr)) {
- ptr = LLVMGetOperand(ptr, 0);
- }
- lb_add_debug_local_variable(p, ptr, t_context, token);
- }
- gb_internal String debug_info_mangle_constant_name(Entity *e, bool *did_allocate_) {
- String name = e->token.string;
- if (e->pkg && e->pkg->name.len > 0) {
- // NOTE(bill): C++ NONSENSE FOR DEBUG SHITE!
- name = concatenate3_strings(heap_allocator(), e->pkg->name, str_lit("::"), name);
- if (did_allocate_) *did_allocate_ = true;
- }
- return name;
- }
- gb_internal void add_debug_info_global_variable_expr(lbModule *m, String const &name, LLVMMetadataRef dtype, LLVMMetadataRef expr) {
- LLVMMetadataRef scope = nullptr;
- LLVMMetadataRef file = nullptr;
- unsigned line = 0;
- LLVMMetadataRef decl = nullptr;
- LLVMDIBuilderCreateGlobalVariableExpression(
- m->debug_builder, scope,
- cast(char const *)name.text, cast(size_t)name.len,
- "", 0, // Linkage
- file, line, dtype,
- false, // local to unit
- expr, decl, 8/*AlignInBits*/);
- }
- gb_internal void add_debug_info_for_global_constant_internal_i64(lbModule *m, Entity *e, LLVMMetadataRef dtype, i64 v) {
- LLVMMetadataRef expr = LLVMDIBuilderCreateConstantValueExpression(m->debug_builder, v);
- bool did_allocate = false;
- String name = debug_info_mangle_constant_name(e, &did_allocate);
- defer (if (did_allocate) {
- gb_free(heap_allocator(), name.text);
- });
- add_debug_info_global_variable_expr(m, name, dtype, expr);
- if ((e->pkg && e->pkg->kind == Package_Init) ||
- (e->scope && (e->scope->flags & ScopeFlag_Global))) {
- add_debug_info_global_variable_expr(m, e->token.string, dtype, expr);
- }
- }
- gb_internal void add_debug_info_for_global_constant_from_entity(lbGenerator *gen, Entity *e) {
- if (e == nullptr || e->kind != Entity_Constant) {
- return;
- }
- if (is_blank_ident(e->token)) {
- return;
- }
- lbModule *m = &gen->default_module;
- if (USE_SEPARATE_MODULES) {
- m = lb_pkg_module(gen, e->pkg);
- }
- if (is_type_integer(e->type)) {
- ExactValue const &value = e->Constant.value;
- if (value.kind == ExactValue_Integer) {
- LLVMMetadataRef dtype = nullptr;
- i64 v = 0;
- bool is_signed = false;
- if (big_int_is_neg(&value.value_integer)) {
- v = exact_value_to_i64(value);
- is_signed = true;
- } else {
- v = cast(i64)exact_value_to_u64(value);
- }
- if (is_type_untyped(e->type)) {
- dtype = lb_debug_type(m, is_signed ? t_i64 : t_u64);
- } else {
- dtype = lb_debug_type(m, e->type);
- }
- add_debug_info_for_global_constant_internal_i64(m, e, dtype, v);
- }
- } else if (is_type_rune(e->type)) {
- ExactValue const &value = e->Constant.value;
- if (value.kind == ExactValue_Integer) {
- LLVMMetadataRef dtype = lb_debug_type(m, t_rune);
- i64 v = exact_value_to_i64(value);
- add_debug_info_for_global_constant_internal_i64(m, e, dtype, v);
- }
- } else if (is_type_boolean(e->type)) {
- ExactValue const &value = e->Constant.value;
- if (value.kind == ExactValue_Bool) {
- LLVMMetadataRef dtype = lb_debug_type(m, default_type(e->type));
- i64 v = cast(i64)value.value_bool;
- add_debug_info_for_global_constant_internal_i64(m, e, dtype, v);
- }
- } else if (is_type_enum(e->type)) {
- ExactValue const &value = e->Constant.value;
- if (value.kind == ExactValue_Integer) {
- LLVMMetadataRef dtype = lb_debug_type(m, default_type(e->type));
- i64 v = 0;
- if (big_int_is_neg(&value.value_integer)) {
- v = exact_value_to_i64(value);
- } else {
- v = cast(i64)exact_value_to_u64(value);
- }
- add_debug_info_for_global_constant_internal_i64(m, e, dtype, v);
- }
- } else if (is_type_pointer(e->type)) {
- ExactValue const &value = e->Constant.value;
- if (value.kind == ExactValue_Integer) {
- LLVMMetadataRef dtype = lb_debug_type(m, default_type(e->type));
- i64 v = cast(i64)exact_value_to_u64(value);
- add_debug_info_for_global_constant_internal_i64(m, e, dtype, v);
- }
- }
- }
|