diff --git a/src/common/ast.odin b/src/common/ast.odin index 4f1b25d..267c84d 100644 --- a/src/common/ast.odin +++ b/src/common/ast.odin @@ -207,6 +207,26 @@ unwrap_pointer_expr :: proc(expr: ^ast.Expr) -> (^ast.Expr, int, bool) { return expr, n, true } +array_is_soa :: proc(array: ast.Array_Type) -> bool { + if array.tag != nil { + if basic, ok := array.tag.derived.(^ast.Basic_Directive); + ok && basic.name == "soa" { + return true + } + } + return false +} + +dynamic_array_is_soa :: proc(array: ast.Dynamic_Array_Type) -> bool { + if array.tag != nil { + if basic, ok := array.tag.derived.(^ast.Basic_Directive); + ok && basic.name == "soa" { + return true + } + } + return false +} + expr_contains_poly :: proc(expr: ^ast.Expr) -> bool { if expr == nil { return false diff --git a/src/server/analysis.odin b/src/server/analysis.odin index 14b1aad..8cc5bee 100644 --- a/src/server/analysis.odin +++ b/src/server/analysis.odin @@ -489,7 +489,13 @@ is_symbol_same_typed :: proc( return false } - return is_symbol_same_typed(ast_context, a_symbol, b_symbol) + a_is_soa := .Soa in a_symbol.flags + b_is_soa := .Soa in a_symbol.flags + + return( + is_symbol_same_typed(ast_context, a_symbol, b_symbol) && + a_is_soa == b_is_soa \ + ) case SymbolFixedArrayValue: b_value := b.value.(SymbolFixedArrayValue) @@ -561,7 +567,13 @@ is_symbol_same_typed :: proc( return false } - return is_symbol_same_typed(ast_context, a_symbol, b_symbol) + a_is_soa := .Soa in a_symbol.flags + b_is_soa := .Soa in a_symbol.flags + + return( + is_symbol_same_typed(ast_context, a_symbol, b_symbol) && + a_is_soa == b_is_soa \ + ) case SymbolMapValue: b_value := b.value.(SymbolMapValue) @@ -2826,6 +2838,10 @@ make_symbol_array_from_ast :: proc( } } + if common.array_is_soa(v) { + symbol.flags |= {.Soa} + } + return symbol } @@ -2845,6 +2861,12 @@ make_symbol_dynamic_array_from_ast :: proc( expr = v.elem, } + + if common.dynamic_array_is_soa(v) { + symbol.flags |= {.Soa} + } + + return symbol } diff --git a/src/server/generics.odin b/src/server/generics.odin index 237a271..9b0dc1d 100644 --- a/src/server/generics.odin +++ b/src/server/generics.odin @@ -150,6 +150,27 @@ resolve_poly :: proc( } case ^ast.Dynamic_Array_Type: if call_array, ok := call_node.derived.(^ast.Dynamic_Array_Type); ok { + + a_soa := common.dynamic_array_is_soa(p^) + b_soa := common.dynamic_array_is_soa(call_array^) + + if (a_soa || b_soa) && a_soa != b_soa { + return false + } + + //It's not enough for them to both arrays, they also have to share soa attributes + if p.tag != nil && call_array.tag != nil { + a, ok1 := p.tag.derived.(^ast.Basic_Directive) + b, ok2 := call_array.tag.derived.(^ast.Basic_Directive) + + if ok1 && + ok2 && + (a.name == "soa" || b.name == "soa") && + a.name != b.name { + return false + } + } + if poly_type, ok := p.elem.derived.(^ast.Poly_Type); ok { if ident, ok := unwrap_ident(poly_type.type); ok { save_poly_map(ident, call_array.elem, poly_map) @@ -170,6 +191,27 @@ resolve_poly :: proc( case ^ast.Array_Type: if call_array, ok := call_node.derived.(^ast.Array_Type); ok { found := false + + a_soa := common.array_is_soa(p^) + b_soa := common.array_is_soa(call_array^) + + if (a_soa || b_soa) && a_soa != b_soa { + return false + } + + //It's not enough for them to both arrays, they also have to share soa attributes + if p.tag != nil && call_array.tag != nil { + a, ok1 := p.tag.derived.(^ast.Basic_Directive) + b, ok2 := call_array.tag.derived.(^ast.Basic_Directive) + + if ok1 && + ok2 && + (a.name == "soa" || b.name == "soa") && + a.name != b.name { + return false + } + } + if poly_type, ok := p.elem.derived.(^ast.Poly_Type); ok { if ident, ok := unwrap_ident(poly_type.type); ok { save_poly_map(ident, call_array.elem, poly_map) diff --git a/src/server/symbol.odin b/src/server/symbol.odin index 9e0f154..f34e4b6 100644 --- a/src/server/symbol.odin +++ b/src/server/symbol.odin @@ -146,6 +146,7 @@ SymbolFlag :: enum { Local, ObjC, ObjCIsClassMethod, // should be set true only when ObjC is enabled + Soa, } SymbolFlags :: bit_set[SymbolFlag]