diff options
| author | Bradley Lewis <22850972+BradLewis@users.noreply.github.com> | 2025-08-17 17:27:01 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-08-17 17:27:01 -0400 |
| commit | 6282669ff2438cdeb1b90b05af0f573602ad3144 (patch) | |
| tree | b0742fba35e2bb3ea94560140dc3d5b0866c416e /src/server | |
| parent | d62633a2c020859b169baaece4f416670f1efc66 (diff) | |
| parent | 6d891495d9b3b96eff830a874ae36ee9f0496157 (diff) | |
Merge pull request #899 from BradLewis/feat/struct-tags
Diffstat (limited to 'src/server')
| -rw-r--r-- | src/server/clone.odin | 3 | ||||
| -rw-r--r-- | src/server/collector.odin | 19 | ||||
| -rw-r--r-- | src/server/documentation.odin | 43 | ||||
| -rw-r--r-- | src/server/symbol.odin | 90 |
4 files changed, 120 insertions, 35 deletions
diff --git a/src/server/clone.odin b/src/server/clone.odin index d761a42..70d6d44 100644 --- a/src/server/clone.odin +++ b/src/server/clone.odin @@ -205,6 +205,9 @@ clone_node :: proc(node: ^ast.Node, allocator: mem.Allocator, unique_strings: ^m r.align = clone_type(r.align, allocator, unique_strings) r.fields = auto_cast clone_type(r.fields, allocator, unique_strings) r.where_clauses = clone_type(r.where_clauses, allocator, unique_strings) + r.align = clone_type(r.align, allocator, unique_strings) + r.max_field_align = clone_type(r.max_field_align, allocator, unique_strings) + r.min_field_align = clone_type(r.min_field_align, allocator, unique_strings) case ^Field: r.names = clone_type(r.names, allocator, unique_strings) r.type = clone_type(r.type, allocator, unique_strings) diff --git a/src/server/collector.odin b/src/server/collector.odin index 7f345c9..541522d 100644 --- a/src/server/collector.odin +++ b/src/server/collector.odin @@ -119,7 +119,11 @@ collect_procedure_fields :: proc( orig_arg_types = args[:], generic = is_procedure_generic(proc_type), diverging = proc_type.diverging, - calling_convention = clone_calling_convention(proc_type.calling_convention, collection.allocator, &collection.unique_strings), + calling_convention = clone_calling_convention( + proc_type.calling_convention, + collection.allocator, + &collection.unique_strings, + ), tags = proc_type.tags, attributes = attrs[:], inlining = inlining, @@ -162,6 +166,19 @@ collect_struct_fields :: proc( } } + b.align = clone_expr(struct_type.align, collection.allocator, &collection.unique_strings) + b.max_field_align = clone_expr(struct_type.max_field_align, collection.allocator, &collection.unique_strings) + b.min_field_align = clone_expr(struct_type.min_field_align, collection.allocator, &collection.unique_strings) + if struct_type.is_no_copy { + b.tags |= {.Is_No_Copy} + } + if struct_type.is_packed { + b.tags |= {.Is_Packed} + } + if struct_type.is_raw_union { + b.tags |= {.Is_Raw_Union} + } + b.poly = cast(^ast.Field_List)clone_type(struct_type.poly_params, collection.allocator, &collection.unique_strings) value := to_symbol_struct_value(b) diff --git a/src/server/documentation.odin b/src/server/documentation.odin index c7b9f0c..2f73ed2 100644 --- a/src/server/documentation.odin +++ b/src/server/documentation.odin @@ -195,13 +195,6 @@ write_signature :: proc(sb: ^strings.Builder, ast_context: ^AstContext, symbol: if .Distinct in symbol.flags { strings.write_string(sb, "distinct ") } - if len(v.names) == 0 { - strings.write_string(sb, "struct {}") - if symbol.comment != "" { - fmt.sbprintf(sb, " %s", symbol.comment) - } - return - } write_struct_hover(sb, ast_context, v, depth) return case SymbolUnionValue: @@ -530,6 +523,39 @@ write_procedure_symbol_signature :: proc(sb: ^strings.Builder, value: SymbolProc } write_struct_hover :: proc(sb: ^strings.Builder, ast_context: ^AstContext, v: SymbolStructValue, depth: int) { + strings.write_string(sb, "struct") + write_poly_list(sb, v.poly, v.poly_names) + + if v.max_field_align != nil { + strings.write_string(sb, " #max_field_align") + build_string_node(v.max_field_align, sb, false) + } + + if v.min_field_align != nil { + strings.write_string(sb, " #min_field_align") + build_string_node(v.min_field_align, sb, false) + } + + if v.align != nil { + strings.write_string(sb, " #align") + build_string_node(v.align, sb, false) + } + + for tag in v.tags { + switch tag { + case .Is_Raw_Union: + strings.write_string(sb, " #raw_union") + case .Is_Packed: + strings.write_string(sb, " #packed") + case .Is_No_Copy: + strings.write_string(sb, " #no_copy") + } + } + if len(v.names) == 0 { + strings.write_string(sb, " {}") + return + } + using_prefix := "using " longestNameLen := 0 for name, i in v.names { @@ -553,9 +579,6 @@ write_struct_hover :: proc(sb: ^strings.Builder, ast_context: ^AstContext, v: Sy } using_index := -1 - - strings.write_string(sb, "struct") - write_poly_list(sb, v.poly, v.poly_names) strings.write_string(sb, " {\n") for i in 0 ..< len(v.names) { diff --git a/src/server/symbol.odin b/src/server/symbol.odin index 26c48aa..2e2f26b 100644 --- a/src/server/symbol.odin +++ b/src/server/symbol.odin @@ -19,6 +19,14 @@ SymbolAndNode :: struct { node: ^ast.Node, } +SymbolStructTag :: enum { + Is_Packed, + Is_Raw_Union, + Is_No_Copy, +} + +SymbolStructTags :: bit_set[SymbolStructTag] + SymbolStructValue :: struct { names: []string, ranges: []common.Range, @@ -37,12 +45,10 @@ SymbolStructValue :: struct { bit_sizes: map[int]^ast.Expr, // the bit size of the bit field field // Tag information - align: ^ast.Expr, - min_field_align: ^ast.Expr, - max_field_align: ^ast.Expr, - is_packed: bool, - is_raw_union: bool, - is_no_copy: bool, + align: ^ast.Expr, + min_field_align: ^ast.Expr, + max_field_align: ^ast.Expr, + tags: SymbolStructTags, } SymbolBitFieldValue :: struct { @@ -241,26 +247,34 @@ SymbolStructValueBuilder :: struct { unexpanded_usings: [dynamic]int, poly: ^ast.Field_List, poly_names: [dynamic]string, + + // Extra fields for embedded bit fields via usings backing_types: map[int]^ast.Expr, bit_sizes: map[int]^ast.Expr, + + // Tag information + align: ^ast.Expr, + min_field_align: ^ast.Expr, + max_field_align: ^ast.Expr, + tags: SymbolStructTags, } symbol_struct_value_builder_make_none :: proc(allocator := context.allocator) -> SymbolStructValueBuilder { return SymbolStructValueBuilder { - names = make([dynamic]string, allocator), - types = make([dynamic]^ast.Expr, allocator), - args = make([dynamic]^ast.Expr, allocator), - ranges = make([dynamic]common.Range, allocator), - docs = make([dynamic]^ast.Comment_Group, allocator), - comments = make([dynamic]^ast.Comment_Group, allocator), + names = make([dynamic]string, allocator), + types = make([dynamic]^ast.Expr, allocator), + args = make([dynamic]^ast.Expr, allocator), + ranges = make([dynamic]common.Range, allocator), + docs = make([dynamic]^ast.Comment_Group, allocator), + comments = make([dynamic]^ast.Comment_Group, allocator), // Set it to an arbitary size due to issues with crashes // See https://github.com/DanielGavin/ols/issues/787 - usings = make(map[int]struct{}, 16, allocator), - from_usings = make([dynamic]int, allocator), + usings = make(map[int]struct{}, 16, allocator), + from_usings = make([dynamic]int, allocator), unexpanded_usings = make([dynamic]int, allocator), - poly_names = make([dynamic]string, allocator), - backing_types = make(map[int]^ast.Expr, allocator), - bit_sizes = make(map[int]^ast.Expr, allocator), + poly_names = make([dynamic]string, allocator), + backing_types = make(map[int]^ast.Expr, allocator), + bit_sizes = make(map[int]^ast.Expr, allocator), } } @@ -304,6 +318,10 @@ symbol_struct_value_builder_make_symbol_symbol_struct_value :: proc( poly_names = slice.to_dynamic(v.poly_names, allocator), backing_types = v.backing_types, bit_sizes = v.bit_sizes, + tags = v.tags, + align = v.align, + max_field_align = v.max_field_align, + min_field_align = v.min_field_align, } } @@ -334,6 +352,10 @@ to_symbol_struct_value :: proc(b: SymbolStructValueBuilder) -> SymbolStructValue poly_names = b.poly_names[:], backing_types = b.backing_types, bit_sizes = b.bit_sizes, + align = b.align, + max_field_align = b.max_field_align, + min_field_align = b.min_field_align, + tags = b.tags, } } @@ -381,6 +403,22 @@ write_struct_type :: proc( resolve_poly_struct(ast_context, b, v.poly_params) } + if base_using_index == -1 { + // only map tags for the base struct + b.align = v.align + b.max_field_align = v.max_field_align + b.min_field_align = v.min_field_align + if v.is_no_copy { + b.tags |= {.Is_No_Copy} + } + if v.is_packed { + b.tags |= {.Is_Packed} + } + if v.is_raw_union { + b.tags |= {.Is_Raw_Union} + } + } + expand_objc(ast_context, b) expand_usings(ast_context, b) } @@ -418,16 +456,16 @@ write_symbol_struct_value :: proc( } } for u in v.unexpanded_usings { - append(&b.unexpanded_usings, u+base_index) + append(&b.unexpanded_usings, u + base_index) } for k, value in v.backing_types { - b.backing_types[k+base_index] = value + b.backing_types[k + base_index] = value } for k, value in v.bit_sizes { - b.bit_sizes[k+base_index] = value + b.bit_sizes[k + base_index] = value } for k in v.usings { - b.usings[k+base_index] = struct{}{} + b.usings[k + base_index] = struct{}{} } expand_usings(ast_context, b) } @@ -457,10 +495,9 @@ write_symbol_bitfield_value :: proc( } b.backing_types[base_using_index] = v.backing_type for bit_size, i in v.bit_sizes { - b.bit_sizes[i+base_index] = bit_size + b.bit_sizes[i + base_index] = bit_size } expand_usings(ast_context, b) - } expand_usings :: proc(ast_context: ^AstContext, b: ^SymbolStructValueBuilder) { @@ -812,7 +849,12 @@ construct_struct_field_symbol :: proc(symbol: ^Symbol, parent_name: string, valu symbol.comment = get_comment(value.comments[index]) } -construct_bit_field_field_symbol :: proc(symbol: ^Symbol, parent_name: string, value: SymbolBitFieldValue, index: int) { +construct_bit_field_field_symbol :: proc( + symbol: ^Symbol, + parent_name: string, + value: SymbolBitFieldValue, + index: int, +) { symbol.name = value.names[index] symbol.pkg = parent_name symbol.type = .Field |