mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 20:11:17 +00:00
Header exports implicit.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user