aboutsummaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
authorBradley Lewis <22850972+BradLewis@users.noreply.github.com>2025-08-17 17:27:01 -0400
committerGitHub <noreply@github.com>2025-08-17 17:27:01 -0400
commit6282669ff2438cdeb1b90b05af0f573602ad3144 (patch)
treeb0742fba35e2bb3ea94560140dc3d5b0866c416e /src/server
parentd62633a2c020859b169baaece4f416670f1efc66 (diff)
parent6d891495d9b3b96eff830a874ae36ee9f0496157 (diff)
Merge pull request #899 from BradLewis/feat/struct-tags
Diffstat (limited to 'src/server')
-rw-r--r--src/server/clone.odin3
-rw-r--r--src/server/collector.odin19
-rw-r--r--src/server/documentation.odin43
-rw-r--r--src/server/symbol.odin90
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