From 6ebd437a5f8e6a8eed3fdd063086798bcf3c956d Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Fri, 25 Aug 2023 14:11:01 +0200 Subject: [PATCH] Fix bug when converting from typedef to distinct. Ordered struct fields. Update debug type when returning an optional. --- src/compiler/abi/c_abi_x64.c | 20 +--- src/compiler/abi/c_abi_x86.c | 10 +- src/compiler/ast.c | 122 +++++++++---------------- src/compiler/enums.h | 20 ++-- src/compiler/json_output.c | 20 ++-- src/compiler/llvm_codegen_debug_info.c | 36 ++++++-- src/compiler/llvm_codegen_expr.c | 26 +----- src/compiler/llvm_codegen_type.c | 12 +-- src/compiler/parse_global.c | 3 +- src/compiler/sema_casts.c | 6 +- src/version.h | 2 +- 11 files changed, 102 insertions(+), 175 deletions(-) diff --git a/src/compiler/abi/c_abi_x64.c b/src/compiler/abi/c_abi_x64.c index 964bb7f83..a1180170d 100644 --- a/src/compiler/abi/c_abi_x64.c +++ b/src/compiler/abi/c_abi_x64.c @@ -380,16 +380,8 @@ static void x64_classify(Type *type, ByteSize offset_base, X64Class *lo_class, X type = type_lowering(type); switch (type->type_kind) { - case TYPE_ENUM: - case TYPE_TYPEDEF: - case TYPE_TYPEID: + case LOWERED_TYPES: case TYPE_FUNC: - case TYPE_DISTINCT: - case TYPE_ANYFAULT: - case TYPE_FAULTTYPE: - case TYPE_BITSTRUCT: - case TYPE_OPTIONAL: - case CT_TYPES: UNREACHABLE case TYPE_VOID: *current = CLASS_NO_CLASS; @@ -615,16 +607,8 @@ AbiType x64_get_int_type_at_offset(Type *type, unsigned offset, Type *source_typ return x64_get_int_type_at_offset(element, offset - element_offset, source_type, source_offset); } case TYPE_VOID: - case TYPE_TYPEID: - case TYPE_ENUM: + case LOWERED_TYPES: case TYPE_FUNC: - case TYPE_TYPEDEF: - case TYPE_DISTINCT: - case TYPE_ANYFAULT: - case TYPE_FAULTTYPE: - case TYPE_BITSTRUCT: - case TYPE_OPTIONAL: - case CT_TYPES: UNREACHABLE case TYPE_I128: case TYPE_U128: diff --git a/src/compiler/abi/c_abi_x86.c b/src/compiler/abi/c_abi_x86.c index 1631d2ab9..1e3773199 100644 --- a/src/compiler/abi/c_abi_x86.c +++ b/src/compiler/abi/c_abi_x86.c @@ -453,17 +453,9 @@ static ABIArgInfo *x86_classify_argument(CallABI call, Regs *regs, Type *type) switch (type->type_kind) { - case TYPE_TYPEDEF: + case LOWERED_TYPES: case TYPE_VOID: - case TYPE_ENUM: - case TYPE_ANYFAULT: - case TYPE_FAULTTYPE: - case TYPE_DISTINCT: case TYPE_FUNC: - case TYPE_TYPEID: - case TYPE_BITSTRUCT: - case TYPE_OPTIONAL: - case CT_TYPES: case TYPE_FLEXIBLE_ARRAY: UNREACHABLE case ALL_FLOATS: diff --git a/src/compiler/ast.c b/src/compiler/ast.c index 603d51a48..e43d05a73 100644 --- a/src/compiler/ast.c +++ b/src/compiler/ast.c @@ -97,90 +97,50 @@ const char *decl_to_a_name(Decl *decl) { switch (decl->decl_kind) { - case DECL_ERASED: - return "an erased declaration"; - case DECL_BODYPARAM: - return "a body parameter"; - case DECL_DECLARRAY: - return "a declarray"; - case DECL_BITSTRUCT: - return "a bitstruct"; - case DECL_POISONED: - return "a poisoned decl"; - case DECL_CT_ASSERT: - return "a compile time assert"; - case DECL_CT_ECHO: - return "a compile time echo"; - case DECL_CT_EXEC: - return "compile time exec include"; - case DECL_IMPORT: - return "an import"; - case DECL_LABEL: - return "a label"; - case DECL_ATTRIBUTE: - return "an attribute"; - case DECL_DEFINE: - case DECL_TYPEDEF: - return "a define"; - case DECL_DISTINCT: - return "a distinct type"; - case DECL_ENUM: - return "an enum"; - case DECL_ENUM_CONSTANT: - return "an enum value"; - case DECL_FAULTVALUE: - return "a fault value"; - case DECL_FAULT: - return "a fault"; - case DECL_FNTYPE: - return "a function type"; - case DECL_FUNC: - return "a function"; - case DECL_MACRO: - return "a macro"; - case DECL_STRUCT: - return "a struct"; - case DECL_UNION: - return "a union"; - case DECL_INITIALIZE: - return "a static initializer"; - case DECL_FINALIZE: - return "a static finalizer"; - case DECL_CT_INCLUDE: - return "an include"; - case DECL_GLOBALS: - return "globals"; + case DECL_ATTRIBUTE: return "an attribute"; + case DECL_BITSTRUCT: return "a bitstruct"; + case DECL_BODYPARAM: return "a body parameter"; + case DECL_CT_ASSERT: return "a compile time assert"; + case DECL_CT_ECHO: return "a compile time echo"; + case DECL_CT_EXEC: return "compile time exec include"; + case DECL_CT_INCLUDE: return "an include"; + case DECL_DECLARRAY: return "a declarray"; + case DECL_DEFINE: case DECL_TYPEDEF: return "a define"; + case DECL_DISTINCT: return "a distinct type"; + case DECL_ENUM: return "an enum"; + case DECL_ENUM_CONSTANT: return "an enum value"; + case DECL_ERASED: return "an erased declaration"; + case DECL_FAULT: return "a fault"; + case DECL_FAULTVALUE: return "a fault value"; + case DECL_FINALIZE: return "a static finalizer"; + case DECL_FNTYPE: return "a function type"; + case DECL_FUNC: return "a function"; + case DECL_GLOBALS: return "globals"; + case DECL_IMPORT: return "an import"; + case DECL_INITIALIZE: return "a static initializer"; + case DECL_LABEL: return "a label"; + case DECL_MACRO: return "a macro"; + case DECL_POISONED: return "a poisoned decl"; + case DECL_STRUCT: return "a struct"; + case DECL_UNION: return "a union"; case DECL_VAR: switch (decl->var.kind) { - case VARDECL_ERASE: - case VARDECL_REWRAPPED: - UNREACHABLE - case VARDECL_CONST: - return "a constant"; - case VARDECL_GLOBAL: - return "a global variable"; - case VARDECL_LOCAL: - return "a variable"; - case VARDECL_PARAM: - return "a parameter"; - case VARDECL_MEMBER: - case VARDECL_BITMEMBER: - return "a member"; - case VARDECL_PARAM_CT: - return "a compile time parameter"; - case VARDECL_PARAM_CT_TYPE: - return "a compile time type parameter"; - case VARDECL_PARAM_REF: - return "a ref parameter"; - case VARDECL_PARAM_EXPR: - return "a expression parameter"; - case VARDECL_LOCAL_CT: - return "a compile time variable"; - case VARDECL_LOCAL_CT_TYPE: - return "a compile time type variable"; - case VARDECL_UNWRAPPED: - return "an unwrapped variable"; + case VARDECL_BITMEMBER: return "a bitstruct member"; + case VARDECL_CONST: return "a constant"; + case VARDECL_ERASE: UNREACHABLE + case VARDECL_GLOBAL: return "a global variable"; + case VARDECL_LOCAL: return "a variable"; + case VARDECL_LOCAL_CT: return "a compile time variable"; + case VARDECL_LOCAL_CT_TYPE: return "a compile time type variable"; + case VARDECL_MEMBER: return "a member"; + case VARDECL_PARAM: return "a parameter"; + case VARDECL_PARAM_CT: return "a compile time parameter"; + case VARDECL_PARAM_CT_TYPE: return "a compile time type parameter"; + case VARDECL_PARAM_EXPR: return "a expression parameter"; + case VARDECL_PARAM_REF: return "a ref parameter"; + case VARDECL_REWRAPPED: UNREACHABLE + case VARDECL_UNWRAPPED: return "an unwrapped variable"; } UNREACHABLE } diff --git a/src/compiler/enums.h b/src/compiler/enums.h index 975ebaf46..79865b586 100644 --- a/src/compiler/enums.h +++ b/src/compiler/enums.h @@ -126,33 +126,33 @@ typedef enum typedef enum { DECL_POISONED = 0, - DECL_ERASED, DECL_ATTRIBUTE, DECL_BITSTRUCT, + DECL_BODYPARAM, DECL_CT_ASSERT, DECL_CT_ECHO, - DECL_CT_INCLUDE, DECL_CT_EXEC, + DECL_CT_INCLUDE, + DECL_DECLARRAY, DECL_DEFINE, DECL_DISTINCT, DECL_ENUM, DECL_ENUM_CONSTANT, + DECL_ERASED, DECL_FAULT, DECL_FAULTVALUE, - DECL_FUNC, - DECL_FNTYPE, - DECL_GLOBALS, - DECL_INITIALIZE, DECL_FINALIZE, + DECL_FNTYPE, + DECL_FUNC, + DECL_GLOBALS, DECL_IMPORT, + DECL_INITIALIZE, DECL_LABEL, DECL_MACRO, DECL_STRUCT, DECL_TYPEDEF, DECL_UNION, DECL_VAR, - DECL_DECLARRAY, - DECL_BODYPARAM, } DeclKind; #define NON_TYPE_DECLS DECL_IMPORT: case DECL_MACRO: \ @@ -679,6 +679,10 @@ typedef enum TYPE_LAST = TYPE_ANY } TypeKind; +#define FLATTENED_TYPES TYPE_DISTINCT: case TYPE_OPTIONAL: case TYPE_TYPEDEF +#define LOWERED_TYPES CT_TYPES: case TYPE_ENUM: case TYPE_TYPEDEF: case TYPE_TYPEID: \ + case TYPE_DISTINCT: case TYPE_ANYFAULT: case TYPE_FAULTTYPE: case TYPE_BITSTRUCT: \ + case TYPE_OPTIONAL #define CT_TYPES TYPE_TYPEINFO: case TYPE_INFERRED_ARRAY: case TYPE_INFERRED_VECTOR: case TYPE_UNTYPED_LIST: \ case TYPE_POISONED: case TYPE_MEMBER: case TYPE_WILDCARD #define ALL_INTS TYPE_I8: case TYPE_I16: case TYPE_I32: case TYPE_I64: case TYPE_I128: \ diff --git a/src/compiler/json_output.c b/src/compiler/json_output.c index 65b072ddc..a474723ab 100644 --- a/src/compiler/json_output.c +++ b/src/compiler/json_output.c @@ -40,29 +40,29 @@ static inline const char *decl_type_to_string(Decl *type) case DECL_CT_ASSERT: return "$assert"; case DECL_CT_ECHO: return "$echo"; case DECL_CT_EXEC: return "$exec"; + case DECL_CT_INCLUDE: return "$include"; case DECL_DEFINE: return "def"; case DECL_DISTINCT: return "distinct"; case DECL_ENUM: return "enum"; case DECL_ENUM_CONSTANT: return "enum_const"; case DECL_FAULT: return "fault"; case DECL_FAULTVALUE: return "fault_val"; - case DECL_FUNC: return "function"; - case DECL_FNTYPE: return "fntype"; - case DECL_GLOBALS: return "global"; - case DECL_INITIALIZE: return "initializer"; case DECL_FINALIZE: return "finalizer"; + case DECL_FNTYPE: return "fntype"; + case DECL_FUNC: return "function"; + case DECL_GLOBALS: return "global"; case DECL_IMPORT: return "import"; - case DECL_CT_INCLUDE: return "$include"; + case DECL_INITIALIZE: return "initializer"; case DECL_MACRO: return "macro"; case DECL_STRUCT: return "struct"; - case DECL_TYPEDEF: return "typedef"; case DECL_UNION: return "union"; - case DECL_VAR: - case DECL_LABEL: - case DECL_DECLARRAY: + case DECL_TYPEDEF: return "typedef"; case DECL_BODYPARAM: - case DECL_POISONED: + case DECL_DECLARRAY: case DECL_ERASED: + case DECL_LABEL: + case DECL_POISONED: + case DECL_VAR: UNREACHABLE } UNREACHABLE diff --git a/src/compiler/llvm_codegen_debug_info.c b/src/compiler/llvm_codegen_debug_info.c index 8712bbd78..e352121de 100644 --- a/src/compiler/llvm_codegen_debug_info.c +++ b/src/compiler/llvm_codegen_debug_info.c @@ -276,6 +276,16 @@ void llvm_debug_push_lexical_scope(GenContext *context, SourceSpan location) } +static LLVMMetadataRef llvm_debug_typeid_type(GenContext *context, Type *type) +{ + return type->backend_debug_type = LLVMDIBuilderCreateBasicType(context->debug.builder, + "typeid", + strlen("typeid"), + type_bit_size(type_voidptr), + (LLVMDWARFTypeEncoding)DW_ATE_address, + LLVMDIFlagZero); + +} static LLVMMetadataRef llvm_debug_simple_type(GenContext *context, Type *type, int dwarf_code) { return type->backend_debug_type = LLVMDIBuilderCreateBasicType(context->debug.builder, @@ -507,7 +517,16 @@ static LLVMMetadataRef llvm_debug_func_type(GenContext *c, Type *type) // 3. Otherwise generate: static LLVMMetadataRef *buffer = NULL; vec_resize(buffer, 0); - vec_add(buffer, llvm_get_debug_type(c, prototype->rtype)); + Type *return_type = prototype->rtype; + if (!type_is_optional(return_type)) + { + vec_add(buffer, llvm_get_debug_type(c, return_type)); + } + else + { + vec_add(buffer, llvm_get_debug_type(c, type_anyfault)); + vec_add(buffer, llvm_get_debug_type(c, type_get_ptr(type_no_optional(return_type)))); + } VECEACH(prototype->param_types, i) { vec_add(buffer, llvm_get_debug_type(c, prototype->param_types[i])); @@ -526,20 +545,19 @@ static LLVMMetadataRef llvm_debug_func_type(GenContext *c, Type *type) static inline LLVMMetadataRef llvm_get_debug_type_internal(GenContext *c, Type *type, LLVMMetadataRef scope) { if (type->backend_debug_type) return type->backend_debug_type; - Type *lowered = type_lowering(type); - if (lowered != type) + Type *canonical = type->canonical; + if (canonical != type) { - return type->backend_debug_type = llvm_get_debug_type(c, lowered); + return type->backend_debug_type = llvm_get_debug_type(c, canonical); } // Consider special handling of UTF8 arrays. switch (type->type_kind) { - case TYPE_TYPEID: case CT_TYPES: UNREACHABLE + case TYPE_BITSTRUCT: case TYPE_OPTIONAL: - // If this is reachable then we're not doing the proper lowering. - UNREACHABLE + return type->backend_debug_type = llvm_get_debug_type(c, type_lowering(type)); case TYPE_BOOL: return llvm_debug_simple_type(c, type, DW_ATE_boolean); case TYPE_I8: @@ -566,6 +584,8 @@ static inline LLVMMetadataRef llvm_get_debug_type_internal(GenContext *c, Type * return type->backend_debug_type = llvm_debug_vector_type(c, type); case TYPE_VOID: return NULL; + case TYPE_TYPEID: + return type->backend_debug_type = llvm_debug_typeid_type(c, type); case TYPE_POINTER: return type->backend_debug_type = llvm_debug_pointer_type(c, type); case TYPE_ENUM: @@ -574,8 +594,6 @@ static inline LLVMMetadataRef llvm_get_debug_type_internal(GenContext *c, Type * return type->backend_debug_type = llvm_debug_enum_type(c, type, scope); case TYPE_FUNC: return type->backend_debug_type = llvm_debug_func_type(c, type); - case TYPE_BITSTRUCT: - UNREACHABLE case TYPE_STRUCT: case TYPE_UNION: return type->backend_debug_type = llvm_debug_structlike_type(c, type, scope); diff --git a/src/compiler/llvm_codegen_expr.c b/src/compiler/llvm_codegen_expr.c index 2fd15bbc8..973903e83 100644 --- a/src/compiler/llvm_codegen_expr.c +++ b/src/compiler/llvm_codegen_expr.c @@ -3730,21 +3730,12 @@ void llvm_emit_comp(GenContext *c, BEValue *result, BEValue *lhs, BEValue *rhs, case TYPE_ARRAY: llvm_emit_array_comp(c, result, lhs, rhs, binary_op); return; - case TYPE_ANY: - case TYPE_ANYFAULT: - case TYPE_TYPEID: - case TYPE_ENUM: - case TYPE_FAULTTYPE: - case TYPE_TYPEDEF: - case TYPE_DISTINCT: - case TYPE_OPTIONAL: - case CT_TYPES: - UNREACHABLE case TYPE_FUNC: break; + case LOWERED_TYPES: + case TYPE_ANY: case TYPE_STRUCT: case TYPE_UNION: - case TYPE_BITSTRUCT: case TYPE_FLEXIBLE_ARRAY: UNREACHABLE case TYPE_SUBARRAY: @@ -4817,19 +4808,11 @@ static void llvm_expand_struct_to_args(GenContext *context, Type *param_type, LL static void llvm_expand_type_to_args(GenContext *context, Type *param_type, LLVMValueRef expand_ptr, LLVMValueRef *args, unsigned *arg_count_ref, AlignSize alignment) { - REDO: switch (type_lowering(param_type)->type_kind) { + case LOWERED_TYPES: case TYPE_VOID: - case TYPE_TYPEID: case TYPE_FUNC: - case TYPE_DISTINCT: - case TYPE_ENUM: - case TYPE_FAULTTYPE: - case TYPE_ANYFAULT: - case TYPE_BITSTRUCT: - case TYPE_OPTIONAL: - case CT_TYPES: case TYPE_FLEXIBLE_ARRAY: UNREACHABLE break; @@ -4843,9 +4826,6 @@ static void llvm_expand_type_to_args(GenContext *context, Type *param_type, LLVM alignment, "loadexpanded"); return; - case TYPE_TYPEDEF: - param_type = param_type->canonical; - goto REDO; case TYPE_STRUCT: llvm_expand_struct_to_args(context, param_type, expand_ptr, args, arg_count_ref, alignment); break; diff --git a/src/compiler/llvm_codegen_type.c b/src/compiler/llvm_codegen_type.c index d39a28c57..6953606ca 100644 --- a/src/compiler/llvm_codegen_type.c +++ b/src/compiler/llvm_codegen_type.c @@ -311,21 +311,11 @@ LLVMTypeRef llvm_get_type(GenContext *c, Type *any_type) } switch (any_type->type_kind) { - case CT_TYPES: - UNREACHABLE - case TYPE_OPTIONAL: - case TYPE_TYPEDEF: - case TYPE_DISTINCT: - case TYPE_ENUM: + case LOWERED_TYPES: // If this is reachable, then we're not doing the proper lowering. UNREACHABLE - case TYPE_TYPEID: - case TYPE_ANYFAULT: - case TYPE_FAULTTYPE: - return any_type->backend_type = llvm_get_type(c, type_iptr->canonical); case TYPE_STRUCT: case TYPE_UNION: - case TYPE_BITSTRUCT: return any_type->backend_type = llvm_type_from_decl(c, any_type->decl); case TYPE_FUNC: return any_type->backend_type = llvm_func_type(c, type_get_resolved_prototype(any_type)); diff --git a/src/compiler/parse_global.c b/src/compiler/parse_global.c index 78ea04054..e0461760b 100644 --- a/src/compiler/parse_global.c +++ b/src/compiler/parse_global.c @@ -15,7 +15,7 @@ static Decl *parse_exec(ParseContext *c); static bool parse_attributes_for_global(ParseContext *c, Decl *decl); INLINE bool parse_decl_initializer(ParseContext *c, Decl *decl); INLINE Decl *decl_new_var_current(ParseContext *c, TypeInfo *type, VarDeclKind kind); - +static bool parse_contracts(ParseContext *c, AstId *contracts_ref); INLINE Decl *decl_new_var_current(ParseContext *c, TypeInfo *type, VarDeclKind kind) { @@ -1776,6 +1776,7 @@ static inline Decl *parse_def_type(ParseContext *c) decl->is_substruct = is_inline; TypedefDecl typedef_decl = decl->typedef_decl; // Ensure value semantics. decl->distinct_decl.typedef_decl = typedef_decl; + decl->methods = NULL; decl->type->type_kind = TYPE_DISTINCT; decl->decl_kind = DECL_DISTINCT; } diff --git a/src/compiler/sema_casts.c b/src/compiler/sema_casts.c index 1b30ac055..828482d06 100644 --- a/src/compiler/sema_casts.c +++ b/src/compiler/sema_casts.c @@ -685,10 +685,8 @@ CastKind cast_to_bool_kind(Type *type) return CAST_PTRBOOL; case TYPE_FAULTTYPE: return CAST_ERBOOL; - case TYPE_TYPEDEF: - case TYPE_DISTINCT: - case TYPE_OPTIONAL: case TYPE_ENUM: + case FLATTENED_TYPES: // These are not possible due to flattening. UNREACHABLE case TYPE_INFERRED_ARRAY: @@ -1918,7 +1916,7 @@ static bool cast_inner(Expr *expr, Type *from_type, Type *to, Type *to_type) if (to->type_kind == TYPE_BOOL) return pointer_to_bool(expr, to_type); if (to->type_kind == TYPE_POINTER) return pointer_to_pointer(expr, to_type); if (to->type_kind == TYPE_SUBARRAY) return insert_cast(expr, CAST_APTSA, to_type); - if (to->type_kind == TYPE_ANY) return insert_cast(expr, CAST_PTRANY, to_type); + if (to->type_kind == TYPE_ANY || to_type->type_kind == TYPE_ANY) return insert_cast(expr, CAST_PTRANY, to_type); break; case TYPE_ANY: if (to->type_kind == TYPE_POINTER) return insert_cast(expr, CAST_ANYPTR, to_type); diff --git a/src/version.h b/src/version.h index c4d521bff..36b1dcb06 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define COMPILER_VERSION "0.4.618" \ No newline at end of file +#define COMPILER_VERSION "0.4.619" \ No newline at end of file