distinct type aliasing
This commit is contained in:
@@ -64,6 +64,7 @@ Kind :: enum u8 {
|
||||
Function,
|
||||
Named,
|
||||
Alias,
|
||||
Distinct,
|
||||
Struct,
|
||||
Union,
|
||||
}
|
||||
@@ -128,7 +129,8 @@ clone_store :: proc(source: ^Store, allocator := context.allocator) -> Store {
|
||||
}
|
||||
|
||||
intern :: proc(store: ^Store, candidate: Node) -> Type {
|
||||
if candidate.kind != .Struct && candidate.kind != .Union && candidate.kind != .Named {
|
||||
if candidate.kind != .Struct && candidate.kind != .Union &&
|
||||
candidate.kind != .Named && candidate.kind != .Distinct {
|
||||
for existing, index in store.nodes {
|
||||
if existing == candidate {
|
||||
return DYNAMIC_START+Type(index)
|
||||
@@ -143,7 +145,8 @@ intern :: proc(store: ^Store, candidate: Node) -> Type {
|
||||
named :: proc(store: ^Store, pkg, name: u32, qualifier: u32 = 0, file: u32 = 0xffff_ffff) -> Type {
|
||||
normalized_file := file if qualifier != 0 else u32(0)
|
||||
for existing, index in store.nodes {
|
||||
if (existing.kind == .Named || existing.kind == .Alias || existing.kind == .Struct || existing.kind == .Union) &&
|
||||
if (existing.kind == .Named || existing.kind == .Alias || existing.kind == .Distinct ||
|
||||
existing.kind == .Struct || existing.kind == .Union) &&
|
||||
existing.pkg == pkg && existing.name == name && existing.qualifier == qualifier &&
|
||||
existing.file == normalized_file {
|
||||
return DYNAMIC_START+Type(index)
|
||||
@@ -154,7 +157,8 @@ named :: proc(store: ^Store, pkg, name: u32, qualifier: u32 = 0, file: u32 = 0xf
|
||||
|
||||
find_named :: proc(store: ^Store, pkg, name: u32, qualifier: u32 = 0) -> Type {
|
||||
for existing, index in store.nodes {
|
||||
if (existing.kind == .Named || existing.kind == .Alias || existing.kind == .Struct || existing.kind == .Union) &&
|
||||
if (existing.kind == .Named || existing.kind == .Alias || existing.kind == .Distinct ||
|
||||
existing.kind == .Struct || existing.kind == .Union) &&
|
||||
existing.pkg == pkg && existing.name == name && existing.qualifier == qualifier {
|
||||
return DYNAMIC_START+Type(index)
|
||||
}
|
||||
@@ -174,6 +178,18 @@ define_alias :: proc(store: ^Store, id, child: Type) -> bool {
|
||||
return true
|
||||
}
|
||||
|
||||
define_distinct :: proc(store: ^Store, id, child: Type) -> bool {
|
||||
existing, ok := node(store, id)
|
||||
if !ok || existing.kind != .Named || existing.declared {
|
||||
return false
|
||||
}
|
||||
index := int(id-DYNAMIC_START)
|
||||
store.nodes[index].kind = .Distinct
|
||||
store.nodes[index].child = child
|
||||
store.nodes[index].declared = true
|
||||
return true
|
||||
}
|
||||
|
||||
define_record :: proc(
|
||||
store: ^Store,
|
||||
id: Type,
|
||||
@@ -440,6 +456,10 @@ is_union :: proc(value: Type, store: ^Store) -> bool {
|
||||
return kind(value, store) == .Union
|
||||
}
|
||||
|
||||
is_distinct :: proc(value: Type, store: ^Store) -> bool {
|
||||
return kind(value, store) == .Distinct
|
||||
}
|
||||
|
||||
resolve_alias :: proc(value: Type, store: ^Store, depth := 0) -> Type {
|
||||
if depth > 64 {
|
||||
return INVALID
|
||||
@@ -456,6 +476,9 @@ is_c_record_field_type :: proc(value: Type, store: ^Store, depth := 0) -> bool {
|
||||
return false
|
||||
}
|
||||
resolved := resolve_alias(value, store)
|
||||
if contains_distinct(resolved, store) {
|
||||
return false
|
||||
}
|
||||
if is_concrete_scalar(resolved) || is_pointer(resolved, store) || is_optional_pointer(resolved, store) {
|
||||
return true
|
||||
}
|
||||
@@ -486,7 +509,10 @@ is_optional_pointer :: proc(value: Type, store: ^Store) -> bool {
|
||||
return ok && item.kind == .Optional && is_pointer(item.child, store)
|
||||
}
|
||||
|
||||
is_runtime_value :: proc(value: Type, store: ^Store) -> bool {
|
||||
is_runtime_value :: proc(value: Type, store: ^Store, depth := 0) -> bool {
|
||||
if depth > 256 {
|
||||
return false
|
||||
}
|
||||
value_kind := kind(value, store)
|
||||
if value_kind == .Scalar || value_kind == .Pointer {
|
||||
return true
|
||||
@@ -498,9 +524,29 @@ is_runtime_value :: proc(value: Type, store: ^Store) -> bool {
|
||||
item, ok := node(store, value)
|
||||
return ok && item.declared && !item.opaque && (!item.c_layout || item.field_count > 0)
|
||||
}
|
||||
if value_kind == .Distinct {
|
||||
item, ok := node(store, value)
|
||||
return ok && item.declared && is_runtime_value(item.child, store, depth+1)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
can_construct_distinct :: proc(from, to: Type, store: ^Store) -> bool {
|
||||
item, ok := node(store, to)
|
||||
return ok && item.kind == .Distinct && item.declared && equal(from, item.child)
|
||||
}
|
||||
|
||||
runtime_representation :: proc(value: Type, store: ^Store, depth := 0) -> Type {
|
||||
if depth > 256 {
|
||||
return INVALID
|
||||
}
|
||||
item, ok := node(store, value)
|
||||
if !ok || item.kind != .Distinct {
|
||||
return value
|
||||
}
|
||||
return runtime_representation(item.child, store, depth+1)
|
||||
}
|
||||
|
||||
contains_c_struct_by_value :: proc(value: Type, store: ^Store, depth := 0) -> bool {
|
||||
if depth > 256 {
|
||||
return true
|
||||
@@ -536,10 +582,41 @@ is_c_signature_type :: proc(value: Type, store: ^Store, allow_void := false) ->
|
||||
if allow_void && is_void(value) {
|
||||
return true
|
||||
}
|
||||
if contains_distinct(value, store) {
|
||||
return false
|
||||
}
|
||||
return is_concrete_scalar(value) || is_pointer(value, store) || is_optional_pointer(value, store) ||
|
||||
(is_c_struct(value, store) && is_runtime_value(value, store))
|
||||
}
|
||||
|
||||
contains_distinct :: proc(value: Type, store: ^Store, depth := 0) -> bool {
|
||||
if depth > 256 {
|
||||
return true
|
||||
}
|
||||
item, ok := node(store, value)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
if item.kind == .Distinct {
|
||||
return true
|
||||
}
|
||||
if item.kind == .Struct || item.kind == .Union {
|
||||
for field in fields_for(store, value) {
|
||||
if contains_distinct(field.type, store, depth+1) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
if item.kind == .Function {
|
||||
for param in params_for(store, value) {
|
||||
if contains_distinct(param.type, store, depth+1) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return is_valid(item.child) && contains_distinct(item.child, store, depth+1)
|
||||
}
|
||||
|
||||
is_c_integer_promotion_candidate :: proc(value: Type) -> bool {
|
||||
return value >= C_CHAR && value <= C_USHORT
|
||||
}
|
||||
@@ -832,6 +909,8 @@ size :: proc(value: Type, store: ^Store, selected := target.DEFAULT) -> u64 {
|
||||
return ((child_size+1+child_align-1)/child_align)*child_align
|
||||
case .Function:
|
||||
return 0
|
||||
case .Distinct:
|
||||
return size(child_type(value, store), store, selected)
|
||||
case .Struct:
|
||||
item, _ := node(store, value)
|
||||
if item.explicit_size > 0 {
|
||||
@@ -873,6 +952,8 @@ alignment_of :: proc(value: Type, store: ^Store, selected := target.DEFAULT) ->
|
||||
return alignment_of(child_type(value, store), store, selected)
|
||||
case .Function:
|
||||
return 1
|
||||
case .Distinct:
|
||||
return alignment_of(child_type(value, store), store, selected)
|
||||
case .Struct:
|
||||
item, _ := node(store, value)
|
||||
if item.explicit_alignment > 0 {
|
||||
|
||||
Reference in New Issue
Block a user