mirror of
https://github.com/odin-lang/Odin.git
synced 2026-01-07 21:43:15 +00:00
Add more objc attributes
This commit is contained in:
@@ -393,6 +393,7 @@ struct Selection {
|
||||
bool indirect; // Set if there was a pointer deref anywhere down the line
|
||||
u8 swizzle_count; // maximum components = 4
|
||||
u8 swizzle_indices; // 2 bits per component, representing which swizzle index
|
||||
bool pseudo_field;
|
||||
};
|
||||
Selection empty_selection = {0};
|
||||
|
||||
@@ -2782,6 +2783,7 @@ Selection lookup_field_from_index(Type *type, i64 index) {
|
||||
}
|
||||
|
||||
Entity *scope_lookup_current(Scope *s, String const &name);
|
||||
bool has_type_got_objc_class_attribute(Type *t);
|
||||
|
||||
Selection lookup_field_with_selection(Type *type_, String field_name, bool is_type, Selection sel, bool allow_blank_ident) {
|
||||
GB_ASSERT(type_ != nullptr);
|
||||
@@ -2794,9 +2796,40 @@ Selection lookup_field_with_selection(Type *type_, String field_name, bool is_ty
|
||||
bool is_ptr = type != type_;
|
||||
sel.indirect = sel.indirect || is_ptr;
|
||||
|
||||
Type *original_type = type;
|
||||
|
||||
type = base_type(type);
|
||||
|
||||
if (is_type) {
|
||||
if (has_type_got_objc_class_attribute(original_type) && original_type->kind == Type_Named) {
|
||||
Entity *e = original_type->Named.type_name;
|
||||
GB_ASSERT(e->kind == Entity_TypeName);
|
||||
if (e->TypeName.objc_metadata) {
|
||||
auto *md = e->TypeName.objc_metadata;
|
||||
mutex_lock(md->mutex);
|
||||
defer (mutex_unlock(md->mutex));
|
||||
for (TypeNameObjCMetadataEntry const &entry : md->type_entries) {
|
||||
GB_ASSERT(entry.entity->kind == Entity_Procedure);
|
||||
if (entry.name == field_name) {
|
||||
sel.entity = entry.entity;
|
||||
sel.pseudo_field = true;
|
||||
return sel;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (type->kind == Type_Struct) {
|
||||
for_array(i, type->Struct.fields) {
|
||||
Entity *f = type->Struct.fields[i];
|
||||
if (f->flags&EntityFlag_Using) {
|
||||
sel = lookup_field_with_selection(f->type, field_name, is_type, sel, allow_blank_ident);
|
||||
if (sel.entity) {
|
||||
return sel;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (is_type_enum(type)) {
|
||||
// NOTE(bill): These may not have been added yet, so check in case
|
||||
for_array(i, type->Enum.fields) {
|
||||
@@ -2843,6 +2876,24 @@ Selection lookup_field_with_selection(Type *type_, String field_name, bool is_ty
|
||||
} else if (type->kind == Type_Union) {
|
||||
|
||||
} else if (type->kind == Type_Struct) {
|
||||
if (has_type_got_objc_class_attribute(original_type) && original_type->kind == Type_Named) {
|
||||
Entity *e = original_type->Named.type_name;
|
||||
GB_ASSERT(e->kind == Entity_TypeName);
|
||||
if (e->TypeName.objc_metadata) {
|
||||
auto *md = e->TypeName.objc_metadata;
|
||||
mutex_lock(md->mutex);
|
||||
defer (mutex_unlock(md->mutex));
|
||||
for (TypeNameObjCMetadataEntry const &entry : md->value_entries) {
|
||||
GB_ASSERT(entry.entity->kind == Entity_Procedure);
|
||||
if (entry.name == field_name) {
|
||||
sel.entity = entry.entity;
|
||||
sel.pseudo_field = true;
|
||||
return sel;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for_array(i, type->Struct.fields) {
|
||||
Entity *f = type->Struct.fields[i];
|
||||
if (f->kind != Entity_Variable || (f->flags & EntityFlag_Field) == 0) {
|
||||
@@ -3792,6 +3843,17 @@ bool is_type_subtype_of(Type *src, Type *dst) {
|
||||
}
|
||||
|
||||
|
||||
bool has_type_got_objc_class_attribute(Type *t) {
|
||||
return t->kind == Type_Named && t->Named.type_name != nullptr && t->Named.type_name->TypeName.objc_class_name != "";
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool is_type_objc_object(Type *t) {
|
||||
bool internal_check_is_assignable_to(Type *src, Type *dst);
|
||||
|
||||
return internal_check_is_assignable_to(t, t_objc_object);
|
||||
}
|
||||
|
||||
Type *get_struct_field_type(Type *t, isize index) {
|
||||
t = base_type(type_deref(t));
|
||||
|
||||
Reference in New Issue
Block a user