Browse Source

`bit_set` support in debug symbols by treating them like a bit field of 1 bit booleans

gingerBill 4 years ago
parent
commit
d88d6a1fdd
3 changed files with 119 additions and 69 deletions
  1. 1 0
      src/check_type.cpp
  2. 117 69
      src/llvm_backend.cpp
  3. 1 0
      src/types.cpp

+ 1 - 0
src/check_type.cpp

@@ -976,6 +976,7 @@ bool is_type_valid_bit_set_range(Type *t) {
 void check_bit_set_type(CheckerContext *c, Type *type, Type *named_type, Ast *node) {
 void check_bit_set_type(CheckerContext *c, Type *type, Type *named_type, Ast *node) {
 	ast_node(bs, BitSetType, node);
 	ast_node(bs, BitSetType, node);
 	GB_ASSERT(type->kind == Type_BitSet);
 	GB_ASSERT(type->kind == Type_BitSet);
+	type->BitSet.node = node;
 
 
 	i64 const DEFAULT_BITS = cast(i64)(8*build_context.word_size);
 	i64 const DEFAULT_BITS = cast(i64)(8*build_context.word_size);
 	i64 const MAX_BITS = 128;
 	i64 const MAX_BITS = 128;

+ 117 - 69
src/llvm_backend.cpp

@@ -1682,7 +1682,7 @@ LLVMMetadataRef lb_debug_type_internal(lbModule *m, Type *type) {
 
 
 		case Basic_rawptr:
 		case Basic_rawptr:
 			{
 			{
-				LLVMMetadataRef void_type = LLVMDIBuilderCreateBasicType(m->debug_builder, "void", 4, 8, LLVMDWARFTypeEncoding_Unsigned, LLVMDIFlagZero);
+				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);
 				return LLVMDIBuilderCreatePointerType(m->debug_builder, void_type, word_bits, word_bits, LLVMDWARFTypeEncoding_Address, "rawptr", 6);
 			}
 			}
 		case Basic_string:
 		case Basic_string:
@@ -1694,7 +1694,7 @@ LLVMMetadataRef lb_debug_type_internal(lbModule *m, Type *type) {
 			}
 			}
 		case Basic_cstring:
 		case Basic_cstring:
 			{
 			{
-				LLVMMetadataRef char_type = LLVMDIBuilderCreateBasicType(m->debug_builder, "char", 4, 8, 0, LLVMDIFlagZero);
+				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);
 				return LLVMDIBuilderCreatePointerType(m->debug_builder, char_type, word_bits, word_bits, 0, "cstring", 7);
 			}
 			}
 		case Basic_any:
 		case Basic_any:
@@ -1739,12 +1739,11 @@ LLVMMetadataRef lb_debug_type_internal(lbModule *m, Type *type) {
 
 
 
 
 	case Type_Struct:
 	case Type_Struct:
-		type_set_offsets(type);
-		/*fallthrough*/
 	case Type_Union:
 	case Type_Union:
 	case Type_Slice:
 	case Type_Slice:
 	case Type_DynamicArray:
 	case Type_DynamicArray:
 	case Type_Map:
 	case Type_Map:
+	case Type_BitSet:
 		{
 		{
 			unsigned tag = DW_TAG_structure_type;
 			unsigned tag = DW_TAG_structure_type;
 			if (is_type_raw_union(type) || is_type_union(type)) {
 			if (is_type_raw_union(type) || is_type_union(type)) {
@@ -1832,12 +1831,6 @@ LLVMMetadataRef lb_debug_type_internal(lbModule *m, Type *type) {
 		}
 		}
 		break;
 		break;
 
 
-	case Type_BitSet: {
-		LLVMMetadataRef int_type = lb_debug_type(m, bit_set_to_int(type));
-		gbString name = type_to_string(type, temporary_allocator());
-		return LLVMDIBuilderCreateTypedef(m->debug_builder, int_type, name, gb_string_length(name), nullptr, 0, nullptr, cast(u32)(8*type_align_of(type)));
-	}
-
 	case Type_SimdVector:
 	case Type_SimdVector:
 		if (type->SimdVector.is_x86_mmx) {
 		if (type->SimdVector.is_x86_mmx) {
 			return LLVMDIBuilderCreateVectorType(m->debug_builder, 2, 8*cast(unsigned)type_align_of(type), lb_debug_type(m, t_f64), nullptr, 0);
 			return LLVMDIBuilderCreateVectorType(m->debug_builder, 2, 8*cast(unsigned)type_align_of(type), lb_debug_type(m, t_f64), nullptr, 0);
@@ -1933,7 +1926,6 @@ LLVMMetadataRef lb_debug_type(lbModule *m, Type *type) {
 		case Type_EnumeratedArray:
 		case Type_EnumeratedArray:
 		case Type_Tuple:
 		case Type_Tuple:
 		case Type_Proc:
 		case Type_Proc:
-		case Type_BitSet:
 		case Type_SimdVector:
 		case Type_SimdVector:
 		case Type_RelativePointer:
 		case Type_RelativePointer:
 		case Type_RelativeSlice:
 		case Type_RelativeSlice:
@@ -1949,6 +1941,7 @@ LLVMMetadataRef lb_debug_type(lbModule *m, Type *type) {
 		case Type_Map:
 		case Type_Map:
 		case Type_Struct:
 		case Type_Struct:
 		case Type_Union:
 		case Type_Union:
+		case Type_BitSet:
 			LLVMMetadataRef temp_forward_decl = LLVMDIBuilderCreateReplaceableCompositeType(
 			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
 				m->debug_builder, tag, name_text, name_len, nullptr, nullptr, 0, 0, size_in_bits, align_in_bits, flags, "", 0
 			);
 			);
@@ -2004,7 +1997,8 @@ void lb_debug_complete_types(lbModule *m) {
 		case Type_DynamicArray:
 		case Type_DynamicArray:
 		case Type_Map:
 		case Type_Map:
 		case Type_Struct:
 		case Type_Struct:
-		case Type_Union: {
+		case Type_Union:
+		case Type_BitSet: {
 			bool is_union = is_type_raw_union(bt) || is_type_union(bt);
 			bool is_union = is_type_raw_union(bt) || is_type_union(bt);
 
 
 			String name = str_lit("<anonymous-struct>");
 			String name = str_lit("<anonymous-struct>");
@@ -2029,15 +2023,7 @@ void lb_debug_complete_types(lbModule *m) {
 				// TODO(bill): location data for Type_Named
 				// TODO(bill): location data for Type_Named
 
 
 			} else {
 			} else {
-				switch (bt->kind) {
-				case Type_Slice:
-				case Type_DynamicArray:
-				case Type_Map:
-				case Type_Struct:
-				case Type_Union:
-					name = make_string_c(type_to_string(t, temporary_allocator()));
-					break;
-				}
+				name = make_string_c(type_to_string(t, temporary_allocator()));
 			}
 			}
 
 
 
 
@@ -2093,64 +2079,126 @@ void lb_debug_complete_types(lbModule *m) {
 				}
 				}
 				break;
 				break;
 			case Type_Union:
 			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;
-				}
+				{
+					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;
+					}
 
 
-				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;
+					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[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)
-					);
-				}
+					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];
+					for_array(j, bt->Union.variants) {
+						Type *variant = bt->Union.variants[j];
 
 
-					unsigned field_index = cast(unsigned)(index_offset+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);
+						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;
+						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)
-					);
+						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;
+					}
 
 
-				break;
+					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", 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
+							);
+						}
+					}
+				}
 			}
 			}
 
 
 
 

+ 1 - 0
src/types.cpp

@@ -276,6 +276,7 @@ struct TypeProc {
 		Type *underlying;                                 \
 		Type *underlying;                                 \
 		i64   lower;                                      \
 		i64   lower;                                      \
 		i64   upper;                                      \
 		i64   upper;                                      \
+		Ast * node;                                       \
 	})                                                    \
 	})                                                    \
 	TYPE_KIND(SimdVector, struct {                        \
 	TYPE_KIND(SimdVector, struct {                        \
 		i64   count;                                      \
 		i64   count;                                      \