Add more objc attributes

This commit is contained in:
gingerBill
2022-02-11 22:54:51 +00:00
parent 416413bebf
commit f8afda3b22
24 changed files with 588 additions and 142 deletions

View File

@@ -340,6 +340,10 @@ void check_type_decl(CheckerContext *ctx, Entity *e, Ast *init_expr, Type *def)
check_decl_attributes(ctx, decl->attributes, type_decl_attribute, &ac);
if (e->kind == Entity_TypeName && ac.objc_class != "") {
e->TypeName.objc_class_name = ac.objc_class;
if (type_size_of(e->type) > 0) {
error(e->token, "@(objc_class) marked type must be of zero size");
}
}
}
@@ -822,6 +826,65 @@ void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) {
}
e->Procedure.optimization_mode = cast(ProcedureOptimizationMode)ac.optimization_mode;
if (ac.objc_name.len || ac.objc_class_name.len || ac.objc_type) {
if (ac.objc_class_name.len && ac.objc_name.len) {
error(e->token, "@(objc_class_name) and @(objc_name) may not be allowed at the same time");
} else if (ac.objc_type == nullptr) {
if (ac.objc_name.len) {
error(e->token, "@(objc_name) requires that @(objc_type) to be set");
} else {
error(e->token, "@(objc_class_name) requires that @(objc_type) to be set");
}
} else {
Type *t = ac.objc_type;
if (t->kind == Type_Named) {
Entity *tn = t->Named.type_name;
GB_ASSERT(tn->kind == Entity_TypeName);
if (tn->scope != e->scope) {
error(e->token, "@(objc_name) and @(objc_class_name) attributes may only be applied to procedures and types within the same scope");
} else {
mutex_lock(&global_type_name_objc_metadata_mutex);
defer (mutex_unlock(&global_type_name_objc_metadata_mutex));
if (!tn->TypeName.objc_metadata) {
tn->TypeName.objc_metadata = create_type_name_obj_c_metadata();
}
auto *md = tn->TypeName.objc_metadata;
mutex_lock(md->mutex);
defer (mutex_unlock(md->mutex));
if (ac.objc_name.len) {
bool ok = true;
for (TypeNameObjCMetadataEntry const &entry : md->value_entries) {
if (entry.name == ac.objc_name) {
error(e->token, "Previous declaration of @(objc_name=\"%.*s\")", LIT(ac.objc_name));
ok = false;
break;
}
}
if (ok) {
array_add(&md->value_entries, TypeNameObjCMetadataEntry{ac.objc_name, e});
}
} else {
bool ok = true;
for (TypeNameObjCMetadataEntry const &entry : md->type_entries) {
if (entry.name == ac.objc_class_name) {
error(e->token, "Previous declaration of @(objc_class_name=\"%.*s\")", LIT(ac.objc_class_name));
ok = false;
break;
}
}
if (ok) {
array_add(&md->type_entries, TypeNameObjCMetadataEntry{ac.objc_class_name, e});
}
}
}
}
}
}
switch (e->Procedure.optimization_mode) {
case ProcedureOptimizationMode_None: