mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 20:11:17 +00:00
When a member is checked, still add it to the environment. Addresses #903.
This commit is contained in:
@@ -134,7 +134,12 @@ static inline bool sema_check_param_uniqueness_and_type(Decl **decls, Decl *curr
|
||||
|
||||
static inline bool sema_analyse_struct_member(SemaContext *context, Decl *parent, Decl *decl, bool *erase_decl)
|
||||
{
|
||||
if (decl->resolve_status == RESOLVE_DONE) return decl_ok(decl);
|
||||
if (decl->resolve_status == RESOLVE_DONE)
|
||||
{
|
||||
if (!decl_ok(decl)) return false;
|
||||
if (decl->name) sema_decl_stack_push(decl);
|
||||
return true;
|
||||
}
|
||||
if (decl->resolve_status == RESOLVE_RUNNING)
|
||||
{
|
||||
RETURN_SEMA_ERROR(decl, "Circular dependency resolving member.");
|
||||
@@ -216,18 +221,12 @@ static bool sema_analyse_union_members(SemaContext *context, Decl *decl, Decl **
|
||||
Decl *member = members[i];
|
||||
if (!decl_ok(member))
|
||||
{
|
||||
decl_poison(decl);
|
||||
continue;
|
||||
return decl_poison(decl);
|
||||
}
|
||||
bool erase_decl = false;
|
||||
if (!sema_analyse_struct_member(context, decl, member, &erase_decl))
|
||||
{
|
||||
if (decl_ok(decl))
|
||||
{
|
||||
decl_poison(decl);
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
return decl_poison(member) || decl_poison(decl);
|
||||
}
|
||||
if (erase_decl)
|
||||
{
|
||||
@@ -239,7 +238,7 @@ static bool sema_analyse_union_members(SemaContext *context, Decl *decl, Decl **
|
||||
if (member->type->type_kind == TYPE_INFERRED_ARRAY)
|
||||
{
|
||||
SEMA_ERROR(member, "Flexible array members not allowed in unions.");
|
||||
return false;
|
||||
return decl_poison(member) || decl_poison(decl);
|
||||
}
|
||||
AlignSize member_alignment;
|
||||
if (!sema_set_abi_alignment(context, member->type, &member_alignment)) return false;
|
||||
@@ -324,16 +323,11 @@ static bool sema_analyse_struct_members(SemaContext *context, Decl *decl, Decl *
|
||||
{
|
||||
AGAIN:;
|
||||
Decl *member = struct_members[i];
|
||||
if (!decl_ok(member))
|
||||
{
|
||||
decl_poison(decl);
|
||||
continue;
|
||||
}
|
||||
if (!decl_ok(member)) return decl_poison(decl);
|
||||
bool erase_decl = false;
|
||||
if (!sema_analyse_struct_member(context, decl, member, &erase_decl))
|
||||
{
|
||||
decl_poison(member);
|
||||
return decl_poison(decl);
|
||||
return decl_poison(member) || decl_poison(decl);
|
||||
}
|
||||
if (erase_decl)
|
||||
{
|
||||
@@ -348,7 +342,7 @@ static bool sema_analyse_struct_members(SemaContext *context, Decl *decl, Decl *
|
||||
if (i != member_count - 1)
|
||||
{
|
||||
SEMA_ERROR(member, "A struct member with a flexible array must be the last element.");
|
||||
return false;
|
||||
return decl_poison(member) || decl_poison(decl);
|
||||
}
|
||||
decl->has_variable_array = true;
|
||||
}
|
||||
@@ -357,12 +351,12 @@ static bool sema_analyse_struct_members(SemaContext *context, Decl *decl, Decl *
|
||||
if (i != member_count - 1)
|
||||
{
|
||||
SEMA_ERROR(member, "The flexible array member must be the last element.");
|
||||
return false;
|
||||
return decl_poison(member) || decl_poison(decl);
|
||||
}
|
||||
if (i == 0)
|
||||
{
|
||||
SEMA_ERROR(member, "The flexible array member cannot be the only element.");
|
||||
return false;
|
||||
return decl_poison(member) || decl_poison(decl);
|
||||
}
|
||||
member->type = type_get_flexible_array(member->type->array.base);
|
||||
decl->has_variable_array = true;
|
||||
@@ -3379,8 +3373,10 @@ RETRY:
|
||||
case TYPE_TYPEINFO:
|
||||
case TYPE_MEMBER:
|
||||
return true;
|
||||
case TYPE_ENUM:
|
||||
case TYPE_FUNC:
|
||||
if (!type->decl) return true;
|
||||
FALLTHROUGH;
|
||||
case TYPE_ENUM:
|
||||
case TYPE_STRUCT:
|
||||
case TYPE_UNION:
|
||||
case TYPE_BITSTRUCT:
|
||||
@@ -3416,6 +3412,7 @@ bool sema_analyse_decl(SemaContext *context, Decl *decl)
|
||||
|
||||
SemaContext temp_context;
|
||||
context = context_transform_for_eval(context, &temp_context, decl->unit);
|
||||
|
||||
DEBUG_LOG(">>> Analysing %s.", decl->name ? decl->name : ".anon");
|
||||
if (decl->resolve_status == RESOLVE_RUNNING)
|
||||
{
|
||||
|
||||
@@ -826,10 +826,11 @@ static inline bool sema_expr_analyse_ternary(SemaContext *context, Expr *expr)
|
||||
static inline bool sema_expr_analyse_enum_constant(SemaContext *context, Expr *expr, const char *name, Decl *decl)
|
||||
{
|
||||
Decl *enum_constant = decl_find_enum_constant(decl, name);
|
||||
|
||||
if (!sema_resolve_type_decl(context, decl->type)) return false;
|
||||
if (!enum_constant) return false;
|
||||
|
||||
// Resolve the structure at this point, since we might want to use the enum_constant
|
||||
if (!sema_resolve_type_structure(context, decl->type, decl->span)) return false;
|
||||
|
||||
assert(enum_constant->resolve_status == RESOLVE_DONE);
|
||||
expr->type = decl->type;
|
||||
|
||||
@@ -2914,6 +2915,9 @@ static inline bool sema_expr_analyse_type_access(SemaContext *context, Expr *exp
|
||||
const char *name = identifier->identifier_expr.ident;
|
||||
bool is_const = identifier->identifier_expr.is_const;
|
||||
|
||||
// Make sure that we have the full type structure.
|
||||
if (!sema_resolve_type_structure(context, parent_type, expr->span)) return false;
|
||||
|
||||
if (!is_const)
|
||||
{
|
||||
if (sema_expr_rewrite_to_type_property(context, expr, canonical, type_property_by_name(name), parent_type)) return true;
|
||||
@@ -3508,6 +3512,7 @@ static bool sema_expr_rewrite_to_type_property(SemaContext *context, Expr *expr,
|
||||
assert(type == type->canonical);
|
||||
if (property == TYPE_PROPERTY_NONE) return false;
|
||||
Type *flat = type_flatten(type);
|
||||
if (!sema_resolve_type_structure(context, flat, expr->span)) return false;
|
||||
switch (property)
|
||||
{
|
||||
case TYPE_PROPERTY_INF:
|
||||
@@ -3931,6 +3936,7 @@ CHECK_DEEPER:
|
||||
|
||||
// 10. Dump all members and methods into the scope.
|
||||
Decl *decl = type->decl;
|
||||
|
||||
Decl *member = sema_decl_stack_find_decl_member(decl, kw);
|
||||
|
||||
if (member && decl_is_enum_kind(decl) && member->decl_kind == DECL_VAR && expr_is_const(parent))
|
||||
@@ -7576,7 +7582,6 @@ static inline bool sema_expr_analyse_compound_literal(SemaContext *context, Expr
|
||||
{
|
||||
if (!sema_resolve_type_info(context, expr->expr_compound_literal.type_info)) return false;
|
||||
Type *type = expr->expr_compound_literal.type_info->type;
|
||||
if (!sema_resolve_type_decl(context, type)) return false;
|
||||
if (type_is_optional(type))
|
||||
{
|
||||
SEMA_ERROR(expr->expr_compound_literal.type_info,
|
||||
|
||||
@@ -20,6 +20,11 @@ union Cc
|
||||
{
|
||||
int a;
|
||||
int a; // #error: Duplicate member name 'a'
|
||||
}
|
||||
|
||||
union Cc2
|
||||
{
|
||||
int a;
|
||||
|
||||
struct b
|
||||
{
|
||||
@@ -27,7 +32,6 @@ union Cc
|
||||
int c; // #error: Duplicate member name 'c'
|
||||
}
|
||||
}
|
||||
|
||||
struct Dd
|
||||
{
|
||||
int b;
|
||||
@@ -37,7 +41,6 @@ struct Dd
|
||||
union
|
||||
{
|
||||
short a; // #error: Duplicate member name 'a'
|
||||
int b; // #error: Duplicate member name 'b'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user