Header exports implicit.

This commit is contained in:
Christoffer Lerno
2024-06-24 15:04:44 +02:00
parent 83fe94d497
commit 4cff80ecea
3 changed files with 109 additions and 66 deletions

View File

@@ -440,35 +440,34 @@ RETRY:
case TYPE_INTERFACE:
return;
case TYPE_DISTINCT:
if (type->decl->is_export)
{
if (htable_get(table, type)) return;
Type *underlying_type = type->decl->distinct->type;
header_gen_maybe_generate_type(file, table, underlying_type);
PRINTF("typedef ");
header_print_type(file, underlying_type);
PRINTF(" %s;\n", decl_get_extname(type->decl));
return;
}
type = type_flatten(type);
goto RETRY;
{
assert(type->decl->is_export);
if (htable_get(table, type)) return;
Type *underlying_type = type->decl->distinct->type;
htable_set(table, type, type);
header_gen_maybe_generate_type(file, table, underlying_type);
PRINTF("typedef ");
header_print_type(file, underlying_type);
PRINTF(" %s;\n", decl_get_extname(type->decl));
return;
}
case TYPE_TYPEDEF:
if (type->decl->is_export)
{
if (htable_get(table, type)) return;
Type *underlying_type = type->canonical;
header_gen_maybe_generate_type(file, table, underlying_type);
PRINTF("typedef ");
header_print_type(file, underlying_type);
PRINTF(" %s;\n", decl_get_extname(type->decl));
return;
}
type = type->canonical;
goto RETRY;
{
assert(type->decl->is_export);
if (htable_get(table, type)) return;
htable_set(table, type, type);
Type *underlying_type = type->canonical;
header_gen_maybe_generate_type(file, table, underlying_type);
PRINTF("typedef ");
header_print_type(file, underlying_type);
PRINTF(" %s;\n", decl_get_extname(type->decl));
return;
}
case TYPE_BITSTRUCT:
if (type->decl->is_export)
{
assert(type->decl->is_export);
if (htable_get(table, type)) return;
htable_set(table, type, type);
Type *underlying_type = type->decl->bitstruct.base_type->type;
header_gen_maybe_generate_type(file, table, underlying_type);
PRINTF("typedef ");
@@ -476,8 +475,6 @@ RETRY:
PRINTF(" %s;\n", decl_get_extname(type->decl));
return;
}
type = type_flatten(type);
goto RETRY;
case TYPE_POINTER:
case TYPE_FUNC_PTR:
type = type->pointer;
@@ -485,6 +482,7 @@ RETRY:
case TYPE_ENUM:
if (htable_get(table, type)) return;
{
assert(type->decl->is_export);
Decl *decl = type->decl;
htable_set(table, type, type);
Type *underlying_type = decl->enums.type_info->type->canonical;
@@ -513,6 +511,7 @@ RETRY:
case TYPE_UNION:
if (htable_get(table, type)) return;
{
assert(type->decl->is_export);
Decl *decl = type->decl;
PRINTF("typedef %s %s__ %s;\n", struct_union_str(decl), decl_get_extname(decl), decl_get_extname(decl));
htable_set(table, type, type);
@@ -526,31 +525,21 @@ RETRY:
case TYPE_ARRAY:
type = type->array.base;
goto RETRY;
if (htable_get(table, type)) return;
{
Decl *decl = type->decl;
PRINTF("typedef struct %s__slice__ %s;\n", decl_get_extname(decl), decl_get_extname(decl));
htable_set(table, type, type);
header_ensure_member_types_exist(file, table, decl->strukt.members);
PRINTF("%s %s__\n", struct_union_str(decl), decl->extname);
PRINTF("{\n");
header_gen_members(file, 1, decl->strukt.members);
PRINTF("};\n");
return;
}
break;
case TYPE_FLEXIBLE_ARRAY:
type = type->array.base;
goto RETRY;
case TYPE_VECTOR:
{
if (htable_get(table, type)) return;
PRINTF("typedef ");
header_print_type(file, type->array.base);
Type *flat_type = type_flatten(type->array.base);
header_print_type(file, flat_type);
htable_set(table, type, type);
PRINTF(" ");
header_print_type(file, type);
PRINTF(" __attribute__((vector_size(%d)));\n", (int)type_size(type->array.base) * type->array.len);
PRINTF(" __attribute__((vector_size(%d)));\n", (int)type_size(flat_type) * type->array.len);
return;
}
}
}

View File

@@ -27,8 +27,8 @@ static inline Decl *operator_in_module(SemaContext *c, Module *module, OperatorO
static inline bool sema_analyse_operator_element_at(SemaContext *context, Decl *method);
static inline bool sema_analyse_operator_element_set(SemaContext *context, Decl *method);
static inline bool sema_analyse_operator_len(Decl *method, SemaContext *context);
static bool sema_require_export_type(SemaContext *context, TypeInfo *type_info);
static bool sema_check_operator_method_validity(SemaContext *context, Decl *method);
static void sema_recursively_import(Type *type);
static inline const char *method_name_by_decl(Decl *method_like);
static bool sema_analyse_struct_union(SemaContext *context, Decl *decl, bool *erase_decl);
@@ -242,8 +242,8 @@ static inline bool sema_analyse_struct_member(SemaContext *context, Decl *parent
assert(type_infoptrzero(decl->var.type_info));
TypeInfo *type_info = type_infoptr(decl->var.type_info);
if (!sema_resolve_type_info(context, type_info, RESOLVE_TYPE_ALLOW_FLEXIBLE)) return decl_poison(decl);
if (is_export && !sema_require_export_type(context, type_info)) return decl_poison(decl);
Type *type = type_info->type;
if (is_export) sema_recursively_import(type);
switch (type_storage_type(type))
{
case STORAGE_NORMAL:
@@ -949,14 +949,70 @@ ERROR:
return decl_poison(decl);
}
static bool sema_require_export_type(SemaContext *context, TypeInfo *type_info)
static void sema_recursively_import(Type *type)
{
Decl *decl = type_no_export(type_info->type);
if (!decl) return true;
SEMA_ERROR(type_info, "%s must also be an exported type, to make this work '%s' needs to be marked '@export'",
type_quoted_error_string(type_info->type), decl->name);
SEMA_NOTE(decl, "The definition is here.");
return false;
if (!type) return;
Decl *decl = type_no_export(type);
printf("Recursively import %s %p.\n", type->name, decl);
if (!decl) return;
decl->is_export = true;
printf("Recursively import %s.\n", type->name);
if (decl->resolve_status != RESOLVE_DONE) return;
decl->extname = NULL;
assert(!decl->has_extname);
decl_set_external_name(decl);
switch (decl->decl_kind)
{
case DECL_POISONED:
case DECL_ATTRIBUTE:
case DECL_BODYPARAM:
case DECL_CT_ASSERT:
case DECL_CT_ECHO:
case DECL_CT_EXEC:
case DECL_CT_INCLUDE:
case DECL_DECLARRAY:
case DECL_DEFINE:
case DECL_ENUM_CONSTANT:
case DECL_ERASED:
case DECL_FAULTVALUE:
case DECL_FUNC:
case DECL_GLOBALS:
case DECL_IMPORT:
case DECL_LABEL:
case DECL_MACRO:
case DECL_INTERFACE:
case DECL_VAR:
UNREACHABLE
case DECL_BITSTRUCT:
sema_recursively_import(decl->bitstruct.base_type->type);
return;
case DECL_DISTINCT:
sema_recursively_import(decl->distinct->type);
return;
case DECL_ENUM:
sema_recursively_import(decl->enums.type_info->type);
FOREACH_BEGIN(Decl *param, decl->enums.parameters)
sema_recursively_import(param->type);
FOREACH_END();
case DECL_TYPEDEF:
sema_recursively_import(type->canonical);
return;
case DECL_FAULT:
return;
case DECL_FNTYPE:
sema_recursively_import(type_infoptr(decl->fntype_decl.rtype)->type);
FOREACH_BEGIN(Decl *param, decl->fntype_decl.params)
sema_recursively_import(param->type);
FOREACH_END();
return;
case DECL_STRUCT:
case DECL_UNION:
FOREACH_BEGIN(Decl *param, decl->strukt.members)
sema_recursively_import(param->type);
FOREACH_END();
return;
}
UNREACHABLE
}
static inline bool sema_analyse_signature(SemaContext *context, Signature *sig, TypeInfoId type_parent, bool is_export)
@@ -977,7 +1033,7 @@ static inline bool sema_analyse_signature(SemaContext *context, Signature *sig,
is_macro ? RESOLVE_TYPE_ALLOW_INFER
: RESOLVE_TYPE_DEFAULT)) return false;
rtype = rtype_info->type;
if (is_export && !sema_require_export_type(context, rtype_info)) return false;
if (is_export) sema_recursively_import(rtype);
if (sig->attrs.nodiscard)
{
if (type_is_void(rtype))
@@ -1014,7 +1070,7 @@ static inline bool sema_analyse_signature(SemaContext *context, Signature *sig,
if (!sema_resolve_type_info(context, method_parent,
is_macro ? RESOLVE_TYPE_MACRO_METHOD : RESOLVE_TYPE_FUNC_METHOD)) return false;
}
if (is_export && method_parent && !sema_require_export_type(context, method_parent)) return false;
if (is_export && method_parent) sema_recursively_import(method_parent->type);
// Fill in the type if the first parameter is lacking a type.
if (method_parent && params && params[0] && !params[0]->var.type_info)
@@ -1087,7 +1143,7 @@ static inline bool sema_analyse_signature(SemaContext *context, Signature *sig,
if (!sema_resolve_type_info(context, type_info,
is_macro ? RESOLVE_TYPE_ALLOW_INFER
: RESOLVE_TYPE_DEFAULT)) return decl_poison(param);
if (is_export && !sema_require_export_type(context, type_info)) return false;
if (is_export) sema_recursively_import(type_info->type);
param->type = type_info->type;
}
switch (var_kind)
@@ -1245,10 +1301,12 @@ static inline bool sema_analyse_typedef(SemaContext *context, Decl *decl, bool *
if (!sema_analyse_attributes(context, decl, decl->attributes, ATTR_DEF, erase_decl)) return decl_poison(decl);
if (*erase_decl) return true;
if (decl->is_export) decl_set_external_name(decl);
bool is_export = decl->is_export;
if (is_export) decl_set_external_name(decl);
if (decl->typedef_decl.is_func)
{
Decl *fn_decl = decl->typedef_decl.decl;
fn_decl->is_export = is_export;
fn_decl->unit = decl->unit;
fn_decl->type = type_new_func(fn_decl, &fn_decl->fntype_decl);
decl->type->canonical = type_get_func_ptr(fn_decl->type);
@@ -1256,6 +1314,7 @@ static inline bool sema_analyse_typedef(SemaContext *context, Decl *decl, bool *
}
TypeInfo *info = decl->typedef_decl.type_info;
if (!sema_resolve_type_info(context, info, RESOLVE_TYPE_DEFAULT)) return false;
if (is_export) sema_recursively_import(info->type);
decl->type->canonical = info->type->canonical;
// Do we need anything else?
return true;
@@ -1279,6 +1338,8 @@ static inline bool sema_analyse_distinct(SemaContext *context, Decl *decl, bool
// Optional isn't allowed of course.
if (type_is_optional(info->type)) RETURN_SEMA_ERROR(decl, "You cannot create a distinct type from an optional.");
if (decl->is_export) sema_recursively_import(info->type);
// Distinct types drop the canonical part.
info->type = info->type->canonical;
return true;
@@ -1353,6 +1414,7 @@ static inline bool sema_analyse_enum(SemaContext *context, Decl *decl, bool *era
break;
}
if (!sema_analyse_enum_param(context, value)) goto ERR;
value->resolve_status = RESOLVE_DONE;
}
sema_decl_stack_restore(state);

View File

@@ -386,7 +386,6 @@ bool type_flat_is_boolintlike(Type *type)
Decl *type_no_export(Type *type)
{
type = type->canonical;
RETRY:
switch (type->type_kind)
{
@@ -416,10 +415,12 @@ Decl *type_no_export(Type *type)
case TYPE_STRUCT:
case TYPE_UNION:
case TYPE_FAULTTYPE:
case TYPE_DISTINCT:
case TYPE_BITSTRUCT:
case TYPE_TYPEDEF:
if (type->decl->is_export) return NULL;
return type->decl;
case TYPE_SLICE:
case TYPE_TYPEDEF:
case TYPE_ARRAY:
case TYPE_FLEXIBLE_ARRAY:
case TYPE_INFERRED_ARRAY:
@@ -428,15 +429,6 @@ Decl *type_no_export(Type *type)
case TYPE_VECTOR:
case TYPE_INFERRED_VECTOR:
return NULL;
case TYPE_BITSTRUCT:
// Can be folded into its primitive version.
return NULL;
case TYPE_DISTINCT:
// Is it exported, then we're fine.
if (type->decl->is_export) return NULL;
// Otherwise the underlying type needs to be exported.
type = type->decl->distinct->type->canonical;
goto RETRY;
case TYPE_OPTIONAL:
type = type->optional;
goto RETRY;