From 3bdfe3e05eaf3a34c12dfac409d02e7635a2afb9 Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Mon, 1 Jun 2020 21:00:21 +0200 Subject: [PATCH] Refactored structs. --- resources/testfragments/super_simple.c3 | 91 ++++++++++++++++++++++--- src/compiler/ast.c | 17 ++--- src/compiler/compiler_internal.h | 17 +++-- src/compiler/context.c | 1 + src/compiler/enums.h | 2 +- src/compiler/llvm_codegen.c | 1 + src/compiler/llvm_codegen_debug_info.c | 1 + src/compiler/llvm_codegen_expr.c | 26 ++----- src/compiler/llvm_codegen_function.c | 1 + src/compiler/llvm_codegen_type.c | 3 +- src/compiler/parser.c | 49 +++++++------ src/compiler/sema_casts.c | 1 + src/compiler/sema_decls.c | 47 ++----------- src/compiler/sema_expr.c | 29 ++++---- src/compiler/sema_types.c | 1 + src/compiler/types.c | 2 + 16 files changed, 170 insertions(+), 119 deletions(-) diff --git a/resources/testfragments/super_simple.c3 b/resources/testfragments/super_simple.c3 index 34164b79a..04184c591 100644 --- a/resources/testfragments/super_simple.c3 +++ b/resources/testfragments/super_simple.c3 @@ -92,6 +92,7 @@ enum Inf2 : byte typedef Inf as BooInf; + struct TestStruct { int a; @@ -117,6 +118,36 @@ union SimpleUnion double f; } +struct ExtraSimple +{ + int a; + int b; + struct c + { + double e; + double f0; + double f1; + double f; + double j; + } + struct + { + int r; + int s; + } + union + { + double o0; + int o1; + } + int g; +} +func void testSimple() +{ + ExtraSimple a = { c.j = 3.3 }; + a.c.j = 3.4; + printf("a = %d, c.e = %f, c.f = %f, c.j = %f, g = %d, o0 = %f, r = %d, s = %d\n", a.a, a.c.e, a.c.f, a.c.j, a.g, a.o0, a.r, a.s); +} func void testPointer() { int i = 0; @@ -291,7 +322,12 @@ func void testSimpleStruct(int x) SimpleStruct sinit = { b = 1, d = 3.0, z1 = 1 }; sinit.a = 1; sinit.b = 2; - printf("a = %d, b = %d (1), c = %f, d = %f (3.0), z1 = %d (1), z2 = %d\n", sinit.a, sinit.b, sinit.c, sinit.d, cast(sinit.z1, int), cast(sinit.z2, int)); + printf("Testing:\n"); + printf("a = %d, b = %d (2), c = %f, d = %f (3.0), z1 = %d (1), z2 = %d\n", sinit.a, sinit.b, sinit.c, sinit.d, cast(sinit.z1, int), cast(sinit.z2, int)); + if (sinit.a != 1) printf("ERROR a\n"); + if (sinit.b != 2) printf("ERROR b\n"); + if (sinit.d != 3.0) printf("ERROR d\n"); + if (sinit.z1 != 1) printf("ERROR z1\n"); snoinit.b = 1; snoinit.a = 100; snoinit.d = 3.0; @@ -299,6 +335,9 @@ func void testSimpleStruct(int x) snoinit.z1 = 1; snoinit.z2 = 2; printf("b = %d (1), d = %f (3.0), z1 = %d (1)\n", snoinit.b, snoinit.d, snoinit.z1); + if (snoinit.b != 1) printf("ERROR b\n"); + if (snoinit.d != 3.0) printf("ERROR d\n"); + if (snoinit.z1 != 1) printf("ERROR z1\n"); } struct AnonStruct @@ -338,10 +377,18 @@ func void testAnonStruct2() func void testAnonStruct() { + AnonStruct s = { b2 = 3, b1 = 7, xx.b = 1 }; AnonStruct foo; - printf("a = %d, b = %d (1), c = %d, b1 = %d (7), c1 = %d, b2 = %d (3), c2 = %d (3), x = %d\n", s.a, s.xx.b, s.xx.c, s.b1, s.c1, s.b2, s.c2, s.x); + if (s.a != 0) printf("Error s.a\n"); + if (s.x != 0) printf("Error s.x\n"); + if (s.xx.b != 1) printf("Error s.xx.b = %d\n", s.xx.b); + if (s.xx.c != 0) printf("Error s.xx.c\n"); + if (s.b1 != 7) printf("Error s.b1\n"); + if (s.c1 != 0) printf("Error s.c1\n"); + if (s.b2 != 3) printf("Error s.b2\n"); + if (s.c2 != 3) printf("Error s.c2\n"); s.xx.b = 100; s.xx.c = 99; @@ -349,22 +396,50 @@ func void testAnonStruct() s.b2 = 5; s.c2 = 7; - printf("a = %d, b = %d (100), c = %d (99), b1 = %d (3), c1 = %d, b2 = %d (7), c2 = %d (7), x = %d\n", s.a, s.xx.b, s.xx.c, s.b1, s.c1, s.b2, s.c2, s.x); + if (s.a != 0) printf("Error s.a\n"); + if (s.x != 0) printf("Error s.x\n"); + if (s.xx.b != 100) printf("Error s.xx.b = %d\n", s.xx.b); + if (s.xx.c != 99) printf("Error s.xx.c\n"); + if (s.b1 != 3) printf("Error s.b1\n"); + if (s.c1 != 0) printf("Error s.c1\n"); + if (s.b2 != 7) printf("Error s.b2\n"); + if (s.c2 != 7) printf("Error s.c2\n"); s = { xx = { c = 2 }}; - printf("a = %d, b = %d, c = %d (2), b1 = %d, c1 = %d, b2 = %d, c2 = %d, x = %d\n", s.a, s.xx.b, s.xx.c, s.b1, s.c1, s.b2, s.c2, s.x); + if (s.a != 0) printf("Error s.a\n"); + if (s.x != 0) printf("Error s.x\n"); + if (s.xx.b != 0) printf("Error s.xx.b = %d\n", s.xx.b); + if (s.xx.c != 2) printf("Error s.xx.c\n"); + if (s.b1 != 0) printf("Error s.b1\n"); + if (s.c1 != 0) printf("Error s.c1\n"); + if (s.b2 != 0) printf("Error s.b2\n"); + if (s.c2 != 0) printf("Error s.c2\n"); s.xx.c = 3; s.x = 1212; s.a = 29183; s = AnonStruct { xx = { c = 2 }}; - printf("a = %d, b = %d, c = %d (2), b1 = %d, c1 = %d, b2 = %d, c2 = %d, x = %d\n", s.a, s.xx.b, s.xx.c, s.b1, s.c1, s.b2, s.c2, s.x); + if (s.a != 0) printf("Error s.a\n"); + if (s.x != 0) printf("Error s.x\n"); + if (s.xx.b != 0) printf("Error s.xx.b = %d\n", s.xx.b); + if (s.xx.c != 2) printf("Error s.xx.c\n"); + if (s.b1 != 0) printf("Error s.b1\n"); + if (s.c1 != 0) printf("Error s.c1\n"); + if (s.b2 != 0) printf("Error s.b2\n"); + if (s.c2 != 0) printf("Error s.c2\n"); s = sendAnonStruct(); - printf("Got it sent: a = %d, b = %d (1), c = %d, b1 = %d (7), c1 = %d, b2 = %d (3), c2 = %d (3), x = %d\n", s.a, s.xx.b, s.xx.c, s.b1, s.c1, s.b2, s.c2, s.x); + if (s.a != 1) printf("Error s.a\n"); + if (s.x != 0) printf("Error s.x\n"); + if (s.xx.b != 0) printf("Error s.xx.b = %d\n", s.xx.b); + if (s.xx.c != 2) printf("Error s.xx.c\n"); + if (s.b1 != 0) printf("Error s.b1\n"); + if (s.c1 != 0) printf("Error s.c1\n"); + if (s.b2 != 123) printf("Error s.b2\n"); + if (s.c2 != 123) printf("Error s.c2\n"); } func int boba(int y, int j) @@ -1005,7 +1080,7 @@ union TestUnionSize } func void testTypeValues() { - TestUnionSize.a.sizeof; +// TestUnionSize.a.sizeof; printf("Enum size: %d = 2\n", TestEnumSize.sizeof); printf("Enum size: %d = 4\n", TestEnumSizeDefault.sizeof); printf("Struct size: %d = 12\n", TestStructInt.sizeof); @@ -1016,7 +1091,7 @@ func void testTypeValues() func int main(int x) { - printf("Helo!\n"); + testSimple(); testErrorBug(); testErrors(); testDefault(y = 99); diff --git a/src/compiler/ast.c b/src/compiler/ast.c index 251e3f861..55939f42c 100644 --- a/src/compiler/ast.c +++ b/src/compiler/ast.c @@ -47,7 +47,7 @@ void decl_set_external_name(Decl *decl) return; } char buffer[1024]; - uint32_t len = sprintf(buffer, "%s::%s", decl->module->name->module, decl->name); + uint32_t len = sprintf(buffer, "%s.%s", decl->module->name->module, decl->name); assert(len); TokenType type = TOKEN_INVALID_TOKEN; decl->external_name = symtab_add(buffer, len, fnv1a(buffer, len), &type); @@ -89,6 +89,7 @@ Decl *decl_new_with_type(Token name, DeclKind decl_type, Visibility visibility) case DECL_CT_ELSE: case DECL_CT_ELIF: case DECL_ATTRIBUTE: + case DECL_MEMBER: UNREACHABLE } Type *type = type_new(kind, name.string); @@ -110,8 +111,6 @@ const char *decl_var_to_string(VarDeclKind kind) return "local"; case VARDECL_PARAM: return "param"; - case VARDECL_MEMBER: - return "member"; } UNREACHABLE } @@ -137,7 +136,7 @@ Decl *struct_find_name(Decl *decl, const char* name) VECEACH(compare_members, i) { Decl *member = compare_members[i]; - if (!member->name) + if (member->member_decl.anonymous) { Decl *found = struct_find_name(member, name); if (found) return found; @@ -337,7 +336,7 @@ void fprint_type_recursive(FILE *file, Type *type, int indent) return; case TYPE_MEMBER: DUMPF("(member %s", type->name); - DUMPTYPE(type->decl->parent_struct->type); + DUMPTYPE(type->decl->member_decl.parent->type); DUMPEND(); case TYPE_TYPEDEF: DUMPF("(typedef %s", type->name); @@ -716,7 +715,7 @@ void fprint_decl_recursive(FILE *file, Decl *decl, int indent) switch (decl->decl_kind) { case DECL_VAR: - DUMPF("(var-%s %s", decl_var_to_string(decl->var.kind), decl->name ?: ""); + DUMPF("(var-%s %s", decl_var_to_string(decl->var.kind), decl->name); DUMPTI(decl->var.type_info); switch (decl->var.kind) { @@ -726,8 +725,6 @@ void fprint_decl_recursive(FILE *file, Decl *decl, int indent) case VARDECL_PARAM: DUMPEXPR(decl->var.init_expr); break; - case VARDECL_MEMBER: - break; } DUMPEND(); case DECL_MACRO: @@ -837,6 +834,10 @@ void fprint_decl_recursive(FILE *file, Decl *decl, int indent) DUMPF("(import %s", decl->name); // TODO DUMPEND(); + case DECL_MEMBER: + DUMPF("(member %s", decl->name); + DUMPTI(decl->member_decl.type_info); + DUMPEND(); case DECL_ATTRIBUTE: DUMPF("(attribute %s)", decl->name); if (decl->attr.domains & ATTR_FUNC) diff --git a/src/compiler/compiler_internal.h b/src/compiler/compiler_internal.h index 27ccbbb72..52fc8a843 100644 --- a/src/compiler/compiler_internal.h +++ b/src/compiler/compiler_internal.h @@ -248,7 +248,6 @@ typedef struct typedef struct { uint32_t abi_alignment; - uint32_t id; uint64_t size; Decl **members; } StructDecl; @@ -259,11 +258,7 @@ typedef struct _VarDecl unsigned id : 16; VarDeclKind kind : 3; TypeInfo *type_info; - union - { - Expr *init_expr; - Decl *parent; - }; + Expr *init_expr; void *backend_debug_ref; } VarDecl; @@ -379,6 +374,14 @@ typedef struct Path *path; // For redefinition } GenericDecl; +typedef struct +{ + unsigned index : 32; + bool anonymous : 1; + Decl *parent; + TypeInfo *type_info; + Type *reference_type; +} MemberDecl; typedef struct _Decl { @@ -414,7 +417,6 @@ typedef struct _Decl { union { - Decl* parent_struct; Decl** methods; }; union @@ -438,6 +440,7 @@ typedef struct _Decl Decl** ct_else_decl; Expr *incr_array_decl; TypeInfo *throws; + MemberDecl member_decl; }; } Decl; diff --git a/src/compiler/context.c b/src/compiler/context.c index 51f688007..a9000806f 100644 --- a/src/compiler/context.c +++ b/src/compiler/context.c @@ -131,6 +131,7 @@ void context_register_global_decl(Context *context, Decl *decl) case DECL_CT_ELSE: case DECL_CT_ELIF: case DECL_ATTRIBUTE: + case DECL_MEMBER: UNREACHABLE break; case DECL_CT_IF: diff --git a/src/compiler/enums.h b/src/compiler/enums.h index 03842bd41..2fddbe1cd 100644 --- a/src/compiler/enums.h +++ b/src/compiler/enums.h @@ -184,6 +184,7 @@ typedef enum DECL_ENUM_CONSTANT, DECL_TYPEDEF, DECL_STRUCT, + DECL_MEMBER, DECL_UNION, DECL_ENUM, DECL_ERROR, @@ -545,7 +546,6 @@ typedef enum VARDECL_GLOBAL = 1, VARDECL_LOCAL = 2, VARDECL_PARAM = 3, - VARDECL_MEMBER = 4, } VarDeclKind; typedef enum diff --git a/src/compiler/llvm_codegen.c b/src/compiler/llvm_codegen.c index 4edb2afc6..4ac73777b 100644 --- a/src/compiler/llvm_codegen.c +++ b/src/compiler/llvm_codegen.c @@ -343,6 +343,7 @@ static void gencontext_emit_decl(GenContext *context, Decl *decl) case DECL_CT_ELSE: case DECL_CT_ELIF: case DECL_ATTRIBUTE: + case DECL_MEMBER: UNREACHABLE } } diff --git a/src/compiler/llvm_codegen_debug_info.c b/src/compiler/llvm_codegen_debug_info.c index ff54ad4bb..0aafe7645 100644 --- a/src/compiler/llvm_codegen_debug_info.c +++ b/src/compiler/llvm_codegen_debug_info.c @@ -21,6 +21,7 @@ static inline LLVMMetadataRef gencontext_create_debug_type_from_decl(GenContext case DECL_ERROR_CONSTANT: case DECL_ARRAY_VALUE: case DECL_IMPORT: + case DECL_MEMBER: UNREACHABLE; case DECL_FUNC: { diff --git a/src/compiler/llvm_codegen_expr.c b/src/compiler/llvm_codegen_expr.c index 6d48a411e..dcc63bc9a 100644 --- a/src/compiler/llvm_codegen_expr.c +++ b/src/compiler/llvm_codegen_expr.c @@ -123,30 +123,18 @@ static inline LLVMValueRef gencontext_emit_subscript_addr(GenContext *context, E static LLVMValueRef gencontext_emit_member_addr(GenContext *context, LLVMValueRef value, Decl *parent, Decl *member) { - unsigned index; - Decl *current_parent; assert(member->resolve_status == RESOLVE_DONE); - if (decl_is_struct_type(member)) - { - index = member->strukt.id; - current_parent = member->parent_struct; - } - else - { - index = member->var.id; - current_parent = member->var.parent; - } - assert(current_parent); - if (parent != current_parent) + Decl *current_parent = member->member_decl.parent; + if (current_parent->decl_kind == DECL_MEMBER && current_parent->member_decl.anonymous) { value = gencontext_emit_member_addr(context, value, parent, current_parent); } - if (current_parent->decl_kind == DECL_UNION) + if (current_parent->type->canonical->type_kind == TYPE_UNION) { - return LLVMBuildBitCast(context->builder, value, LLVMPointerType(llvm_type(member->type), 0), member->name ?: "anon"); + return LLVMBuildBitCast(context->builder, value, LLVMPointerType(llvm_type(member->type), 0), member->name); } - return LLVMBuildStructGEP2(context->builder, llvm_type(current_parent->type), value, index, member->name ?: "anon"); + return LLVMBuildStructGEP2(context->builder, llvm_type(current_parent->type), value, member->member_decl.index, member->name); } @@ -384,11 +372,11 @@ static inline LLVMValueRef gencontext_emit_initializer_list_expr_addr(GenContext case DESIGNATED_IDENT: if (parent_type->canonical->type_kind == TYPE_UNION) { - sub_ref = LLVMBuildBitCast(context->builder, sub_ref, LLVMPointerType(llvm_type(path->type), 0), "unionref"); + sub_ref = LLVMBuildBitCast(context->builder, sub_ref, LLVMPointerType(llvm_type(path->type), 0), path->type->name); } else { - sub_ref = LLVMBuildStructGEP2(context->builder, llvm_type(parent_type), sub_ref, path->index, "structref"); + sub_ref = LLVMBuildStructGEP2(context->builder, llvm_type(parent_type), sub_ref, path->index, path->type->name); } break; case DESIGNATED_SUBSCRIPT: diff --git a/src/compiler/llvm_codegen_function.c b/src/compiler/llvm_codegen_function.c index c2fc59348..95e801703 100644 --- a/src/compiler/llvm_codegen_function.c +++ b/src/compiler/llvm_codegen_function.c @@ -300,6 +300,7 @@ void gencontext_emit_extern_decl(GenContext *context, Decl *decl) TODO case DECL_ERROR_CONSTANT: TODO + case DECL_MEMBER: case DECL_ARRAY_VALUE: case DECL_IMPORT: case DECL_MACRO: diff --git a/src/compiler/llvm_codegen_type.c b/src/compiler/llvm_codegen_type.c index 4e286bb10..9acb3f023 100644 --- a/src/compiler/llvm_codegen_type.c +++ b/src/compiler/llvm_codegen_type.c @@ -23,6 +23,7 @@ static inline LLVMTypeRef llvm_type_from_decl(LLVMContextRef context, Decl *decl case DECL_ERROR_CONSTANT: case DECL_ARRAY_VALUE: case DECL_IMPORT: + case DECL_MEMBER: UNREACHABLE; case DECL_FUNC: { @@ -46,7 +47,7 @@ static inline LLVMTypeRef llvm_type_from_decl(LLVMContextRef context, Decl *decl { vec_add(types, llvm_get_type(context, decl->strukt.members[i]->type)); } - LLVMTypeRef type = LLVMStructCreateNamed(context, decl->external_name); + LLVMTypeRef type = LLVMStructCreateNamed(context, decl->name); LLVMStructSetBody(type, types, vec_size(types), decl->is_packed); return type; } diff --git a/src/compiler/parser.c b/src/compiler/parser.c index 9b4f74f58..94cccdfc5 100644 --- a/src/compiler/parser.c +++ b/src/compiler/parser.c @@ -955,6 +955,17 @@ static inline bool parse_opt_parameter_type_list(Context *context, Visibility pa #pragma mark --- Parse types +void add_struct_member(Decl *parent, Decl *parent_struct, Decl *member, TypeInfo *type) +{ + unsigned index = vec_size(parent_struct->strukt.members); + vec_add(parent_struct->strukt.members, member); + member->member_decl.index = index; + member->member_decl.reference_type = type_new(TYPE_MEMBER, member->name); + member->member_decl.reference_type->decl = member; + member->member_decl.type_info = type; + member->member_decl.parent = parent; +} + /** * Expect pointer to after '{' * @@ -973,14 +984,16 @@ static inline bool parse_opt_parameter_type_list(Context *context, Visibility pa * | struct_or_union opt_attributes struct_body * ; * - * @param parent the direct parent. - * @param visible_parent the visible parent when checking duplicate symbols. + * @param parent the parent if this is the body of member + * @param struct_parent the struct this is the body of + * @param visible_parent the visible struct parent for checking duplicates. */ -bool parse_struct_body(Context *context, Decl *parent, Decl *visible_parent) +bool parse_struct_body(Context *context, Decl *parent, Decl *parent_struct, Decl *visible_parent) { CONSUME_OR(TOKEN_LBRACE, false); + assert(decl_is_struct_type(parent_struct)); while (context->tok.type != TOKEN_RBRACE) { TokenType token_type = context->tok.type; @@ -988,17 +1001,19 @@ bool parse_struct_body(Context *context, Decl *parent, Decl *visible_parent) { DeclKind decl_kind = decl_from_token(token_type); Decl *member; + Token name_replacement = context->tok; + name_replacement.string = "anon"; + Decl *strukt_type = decl_new_with_type(name_replacement, decl_kind, visible_parent->visibility); if (context->next_tok.type != TOKEN_IDENT) { - Token name_replacement = context->tok; - name_replacement.string = NULL; - member = decl_new_with_type(name_replacement, decl_kind, parent->visibility); + member = decl_new(DECL_MEMBER, name_replacement, visible_parent->visibility); + member->member_decl.anonymous = true; advance(context); } else { advance(context); - member = decl_new_with_type(context->tok, decl_kind, parent->visibility); + member = decl_new(DECL_MEMBER, context->tok, visible_parent->visibility); Decl *other = struct_find_name(visible_parent, context->tok.string); if (other) { @@ -1007,26 +1022,25 @@ bool parse_struct_body(Context *context, Decl *parent, Decl *visible_parent) decl_poison(visible_parent); decl_poison(other); decl_poison(member); + return false; } advance_and_verify(context, TOKEN_IDENT); } - if (!parse_attributes(context, member)) return false; - member->parent_struct = parent; - member->strukt.id = vec_size(parent->strukt.members); - parent->strukt.members = VECADD(parent->strukt.members, member); - if (!parse_struct_body(context, member, context->tok.type == TOKEN_IDENT ? member : visible_parent)) + if (!parse_attributes(context, strukt_type)) return false; + if (!parse_struct_body(context, member, strukt_type, context->tok.type == TOKEN_IDENT ? strukt_type : visible_parent)) { decl_poison(visible_parent); return false; } + VECADD(context->types, strukt_type); + add_struct_member(parent, parent_struct, member, type_info_new_base(strukt_type->type, strukt_type->span)); continue; } TypeInfo *type = TRY_TYPE_OR(parse_type(context), false); - while (1) { EXPECT_OR(TOKEN_IDENT, false); - Decl *member = decl_new_var(context->tok, type, VARDECL_MEMBER, parent->visibility); + Decl *member = decl_new(DECL_MEMBER, context->tok, visible_parent->visibility); Decl *other = struct_find_name(visible_parent, member->name); if (other) { @@ -1036,10 +1050,7 @@ bool parse_struct_body(Context *context, Decl *parent, Decl *visible_parent) decl_poison(other); decl_poison(member); } - unsigned index = vec_size(parent->strukt.members); - parent->strukt.members = VECADD(parent->strukt.members, member); - member->var.id = index; - member->var.parent = parent; + add_struct_member(parent, parent_struct, member, type); advance(context); if (context->tok.type != TOKEN_COMMA) break; } @@ -1074,7 +1085,7 @@ static inline Decl *parse_struct_declaration(Context *context, Visibility visibi return poisoned_decl; } - if (!parse_struct_body(context, decl, decl)) + if (!parse_struct_body(context, decl, decl, decl)) { return poisoned_decl; } diff --git a/src/compiler/sema_casts.c b/src/compiler/sema_casts.c index c84e54dd4..6cb95c242 100644 --- a/src/compiler/sema_casts.c +++ b/src/compiler/sema_casts.c @@ -281,6 +281,7 @@ bool fpfp(Expr* left, Type *from, Type *canonical, Type *type, CastType cast_typ */ bool fpxi(Expr *left, Type *canonical, Type *type, CastType cast_type) { + if (cast_type == CAST_TYPE_OPTIONAL_IMPLICIT) return true; if (cast_type != CAST_TYPE_EXPLICIT) EXIT_T_MISMATCH(); RETURN_NON_CONST_CAST(CAST_FPUI); diff --git a/src/compiler/sema_decls.c b/src/compiler/sema_decls.c index a9ebfb911..371fe84b0 100644 --- a/src/compiler/sema_decls.c +++ b/src/compiler/sema_decls.c @@ -90,48 +90,9 @@ static inline bool sema_analyse_struct_member(Context *context, Decl *decl) { assert(decl->resolve_status == RESOLVE_NOT_DONE); decl->resolve_status = RESOLVE_RUNNING; - if (decl->decl_kind == DECL_STRUCT || decl->decl_kind == DECL_UNION) - { - DEBUG_LOG("Beginning analysis of inner struct/union"); - VECEACH(decl->strukt.members, i) - { - Decl *member = decl->strukt.members[i]; - if (!decl_ok(member)) - { - decl_poison(decl); - continue; - } - if (!sema_analyse_struct_member(context, decl->strukt.members[i])) - { - if (decl_ok(decl)) - { - decl_poison(decl); - continue; - } - decl_poison(decl); - } - } - if (decl->decl_kind == DECL_UNION) - { - sema_set_union_size(decl); - } - else - { - sema_set_struct_size(decl); - } - DEBUG_LOG("Analysis complete."); - decl->resolve_status = RESOLVE_DONE; - return decl_ok(decl); - } - assert(decl->decl_kind == DECL_VAR); - assert(decl->var.kind == VARDECL_MEMBER); - if (!sema_resolve_type_info(context, decl->var.type_info)) - { - decl_poison(decl); - return false; - } - decl->type = decl->var.type_info->type; - assert(decl->var.type_info->type); + assert(decl->decl_kind == DECL_MEMBER); + if (!sema_resolve_type_info(context, decl->member_decl.type_info)) return decl_poison(decl); + decl->type = decl->member_decl.type_info->type; decl->resolve_status = RESOLVE_DONE; return true; } @@ -767,12 +728,12 @@ bool sema_analyse_decl(Context *context, Decl *decl) case DECL_ARRAY_VALUE: case DECL_CT_ELSE: case DECL_CT_ELIF: + case DECL_MEMBER: UNREACHABLE case DECL_CT_IF: // Handled elsewhere UNREACHABLE } decl->resolve_status = RESOLVE_DONE; - DEBUG_LOG("<<< Analysis of %s successful.", decl->name); return true; } diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index 693fe07e3..9ba5ae4b7 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -672,8 +672,7 @@ static Decl *strukt_recursive_search_member(Decl *strukt, const char *name) VECEACH(strukt->strukt.members, i) { Decl *member = strukt->strukt.members[i]; - if (member->name == name) return member; - if (!member->name && type_is_structlike(member->type->canonical)) + if (member->member_decl.anonymous) { Decl *result = strukt_recursive_search_member(member->type->canonical->decl, name); if (result) @@ -681,6 +680,10 @@ static Decl *strukt_recursive_search_member(Decl *strukt, const char *name) return result; } } + else + { + if (member->name == name) return member; + } } return NULL; } @@ -852,17 +855,7 @@ static DesignatedPath *sema_analyse_init_identifier_string(Context *context, Des VECEACH(members, i) { Decl *member = members[i]; - if (member->name == string) - { - DesignatedPath *sub_path = CALLOCS(DesignatedPath); - sub_path->type = member->type; - sub_path->kind = DESIGNATED_IDENT; - sub_path->index = i; - parent_path->sub_path = sub_path; - *has_found_match = true; - return sub_path; - } - if (!member->name) + if (member->member_decl.anonymous) { DesignatedPath temp_path; temp_path.type = member->type; @@ -876,6 +869,16 @@ static DesignatedPath *sema_analyse_init_identifier_string(Context *context, Des *has_found_match = true; return found; } + if (member->name == string) + { + DesignatedPath *sub_path = CALLOCS(DesignatedPath); + sub_path->type = member->type; + sub_path->kind = DESIGNATED_IDENT; + sub_path->index = i; + parent_path->sub_path = sub_path; + *has_found_match = true; + return sub_path; + } } return NULL; } diff --git a/src/compiler/sema_types.c b/src/compiler/sema_types.c index e3caed94a..41305c7c1 100644 --- a/src/compiler/sema_types.c +++ b/src/compiler/sema_types.c @@ -136,6 +136,7 @@ static bool sema_resolve_type_identifier(Context *context, TypeInfo *type_info) case DECL_CT_IF: case DECL_CT_ELIF: case DECL_ATTRIBUTE: + case DECL_MEMBER: UNREACHABLE } UNREACHABLE diff --git a/src/compiler/types.c b/src/compiler/types.c index d3213346d..c8b036081 100644 --- a/src/compiler/types.c +++ b/src/compiler/types.c @@ -176,6 +176,7 @@ static void type_append_signature_name_user_defined(Decl *decl, char *dst, size_ case DECL_CT_ELSE: case DECL_CT_ELIF: case DECL_ATTRIBUTE: + case DECL_MEMBER: UNREACHABLE case DECL_STRUCT: case DECL_UNION: @@ -230,6 +231,7 @@ size_t type_size(Type *canonical) return alignment_error_code; case TYPE_STRUCT: case TYPE_UNION: + assert(canonical->decl->resolve_status == RESOLVE_DONE); return canonical->decl->strukt.size; case TYPE_VOID: return 1;