From dcf0b4c580bfa12219715231831baf26269a3926 Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Tue, 13 Dec 2022 18:54:58 +0100 Subject: [PATCH] Fix an issue with pointer debug info creation. Improve generated parameterized name. Version bump. --- lib/std/priorityqueue.c3 | 8 ++ src/compiler/llvm_codegen_debug_info.c | 25 ++-- src/compiler/sema_decls.c | 155 +++++++++++++++---------- src/compiler/sema_expr.c | 15 ++- src/version.h | 2 +- 5 files changed, 129 insertions(+), 76 deletions(-) diff --git a/lib/std/priorityqueue.c3 b/lib/std/priorityqueue.c3 index 483ea8a8f..dc99a5a29 100644 --- a/lib/std/priorityqueue.c3 +++ b/lib/std/priorityqueue.c3 @@ -103,3 +103,11 @@ fn usz PriorityQueue.len(PriorityQueue* pq) @operator(len) { return pq.heap.len(); } + +/** + * @require pq != null, index < pq.len() + */ +fn Type PriorityQueue.peek_at(PriorityQueue* pq, usz index) @operator([]) +{ + return pq.heap[index]; +} diff --git a/src/compiler/llvm_codegen_debug_info.c b/src/compiler/llvm_codegen_debug_info.c index a050c68a5..191aedd6d 100644 --- a/src/compiler/llvm_codegen_debug_info.c +++ b/src/compiler/llvm_codegen_debug_info.c @@ -192,7 +192,7 @@ void llvm_emit_debug_parameter(GenContext *c, Decl *parameter, unsigned index) unsigned col = parameter->span.col; if (col == 0) col = 1; - parameter->var.backend_debug_ref = LLVMDIBuilderCreateParameterVariable( + parameter->var.backend_debug_ref = LLVMDIBuilderCreateParameterVariable( c->debug.builder, c->debug.function, name, @@ -290,20 +290,13 @@ static LLVMMetadataRef llvm_debug_simple_type(GenContext *context, Type *type, i static LLVMMetadataRef llvm_debug_pointer_type(GenContext *c, Type *type) { - if (!type->pointer->backend_debug_type) - { - type->backend_debug_type = llvm_debug_forward_comp(c, type, type->name, NULL, NULL, LLVMDIFlagZero); - } - LLVMMetadataRef real = LLVMDIBuilderCreatePointerType(c->debug.builder, - llvm_get_debug_type(c, type->pointer), - type_size(type) * 8, - type_abi_alignment(type) * 8, 0, - type->name, strlen(type->name)); - if (type->backend_debug_type) - { - LLVMMetadataReplaceAllUsesWith(type->backend_debug_type, real); - } - return real; + LLVMMetadataRef inner = llvm_get_debug_type(c, type->pointer); + if (type->backend_debug_type) return type->backend_debug_type; + return LLVMDIBuilderCreatePointerType(c->debug.builder, + inner, + type_size(type) * 8, + type_abi_alignment(type) * 8, 0, + type->name, strlen(type->name)); } static LLVMMetadataRef llvm_debug_enum_type(GenContext *c, Type *type, LLVMMetadataRef scope) @@ -405,6 +398,7 @@ static LLVMMetadataRef llvm_debug_subarray_type(GenContext *c, Type *type) static LLVMMetadataRef llvm_debug_any_type(GenContext *c, Type *type) { LLVMMetadataRef forward = llvm_debug_forward_comp(c, type, type->name, NULL, NULL, LLVMDIFlagZero); + type->backend_debug_type = forward; LLVMMetadataRef elements[2] = { @@ -478,6 +472,7 @@ static LLVMMetadataRef llvm_debug_typedef_type(GenContext *c, Type *type) if (type->backend_debug_type) { LLVMMetadataReplaceAllUsesWith(type->backend_debug_type, real); + type->backend_debug_type = real; } return real; } diff --git a/src/compiler/sema_decls.c b/src/compiler/sema_decls.c index 7786edbd1..8271ed196 100644 --- a/src/compiler/sema_decls.c +++ b/src/compiler/sema_decls.c @@ -2582,6 +2582,97 @@ static Module *module_instantiate_generic(Module *module, Path *path, Expr **par return new_module; } +static bool sema_append_generate_parameterized_name(SemaContext *c, Module *module, Decl *decl, bool mangled) +{ + if (mangled) + { + scratch_buffer_append_len(module->name->module, module->name->len); + scratch_buffer_append("$$"); + } + else + { + scratch_buffer_append_char('<'); + } + FOREACH_BEGIN_IDX(i, Expr *param, decl->define_decl.generic_params) + if (i != 0) + { + scratch_buffer_append(mangled ? "." : ", "); + } + if (param->expr_kind == EXPR_TYPEINFO) + { + TypeInfo *type = param->type_expr; + if (!sema_resolve_type_info(c, type)) return decl_poison(decl); + if (type->type->type_kind == TYPE_OPTIONAL) + { + SEMA_ERROR(type, "Expected a non-optional type."); + return poisoned_decl; + } + if (type_is_invalid_storage_type(type->type)) + { + SEMA_ERROR(type, "Expected a runtime type."); + return poisoned_decl; + } + if (mangled) + { + type_mangle_introspect_name_to_buffer(type->type->canonical); + } + else + { + scratch_buffer_append(type->type->name); + } + } + else + { + if (!sema_analyse_ct_expr(c, param)) return decl_poison(decl); + Type *type = param->type->canonical; + if (!type_is_integer_or_bool_kind(type)) + { + SEMA_ERROR(param, "Only integer and boolean types may be generic arguments."); + return poisoned_decl; + } + assert(expr_is_const(param)); + if (type == type_bool) + { + if (mangled) + { + scratch_buffer_append_char(param->const_expr.b ? 't' : 'f'); + } + else + { + scratch_buffer_append(param->const_expr.b ? "true" : "false"); + } + } + else + { + char *maybe_neg = &scratch_buffer.str[scratch_buffer.len]; + if (type->type_kind == TYPE_I128 || type->type_kind == TYPE_U128) + { + char *str = int_to_str(param->const_expr.ixx, 10); + + scratch_buffer_append(str); + } + else + { + if (type_is_signed(type)) + { + scratch_buffer_append_signed_int(param->const_expr.ixx.i.low); + } + else + { + scratch_buffer_append_unsigned_int(param->const_expr.ixx.i.high); + } + } + if (mangled) + { + // Replace - with _ + if (maybe_neg[0] == '-') maybe_neg[0] = '_'; + } + } + } + FOREACH_END(); + if (!mangled) scratch_buffer_append_char('>'); + return true; +} static bool sema_analyse_parameterized_define(SemaContext *c, Decl *decl) { Path *decl_path; @@ -2635,65 +2726,7 @@ static bool sema_analyse_parameterized_define(SemaContext *c, Decl *decl) return decl_poison(decl); } scratch_buffer_clear(); - scratch_buffer_append_len(module->name->module, module->name->len); - scratch_buffer_append("$$"); - FOREACH_BEGIN_IDX(i, Expr *param, decl->define_decl.generic_params) - if (i != 0) scratch_buffer_append_char('.'); - if (param->expr_kind == EXPR_TYPEINFO) - { - TypeInfo *type = param->type_expr; - if (!sema_resolve_type_info(c, type)) return decl_poison(decl); - if (type->type->type_kind == TYPE_OPTIONAL) - { - SEMA_ERROR(type, "Expected a non-optional type."); - return poisoned_decl; - } - if (type_is_invalid_storage_type(type->type)) - { - SEMA_ERROR(type, "Expected a runtime type."); - return poisoned_decl; - } - type_mangle_introspect_name_to_buffer(type->type->canonical); - } - else - { - if (!sema_analyse_ct_expr(c, param)) return decl_poison(decl); - Type *type = param->type->canonical; - if (!type_is_integer_or_bool_kind(type)) - { - SEMA_ERROR(param, "Only integer and boolean types may be generic arguments."); - return poisoned_decl; - } - assert(expr_is_const(param)); - if (type == type_bool) - { - scratch_buffer_append_char(param->const_expr.b ? 't' : 'f'); - } - else - { - char *maybe_neg = &scratch_buffer.str[scratch_buffer.len]; - if (type->type_kind == TYPE_I128 || type->type_kind == TYPE_U128) - { - char *str = int_to_str(param->const_expr.ixx, 10); - - scratch_buffer_append(str); - } - else - { - if (type_is_signed(type)) - { - scratch_buffer_append_signed_int(param->const_expr.ixx.i.low); - } - else - { - scratch_buffer_append_unsigned_int(param->const_expr.ixx.i.high); - } - } - // Replace - with _ - if (maybe_neg[0] == '-') maybe_neg[0] = '_'; - } - } - FOREACH_END(); + if (!sema_append_generate_parameterized_name(c, module, decl, true)) return decl_poison(decl); TokenType ident_type = TOKEN_IDENT; const char *path_string = scratch_buffer_interned(); Module *instantiated_module = global_context_find_module(path_string); @@ -2717,6 +2750,10 @@ static bool sema_analyse_parameterized_define(SemaContext *c, Decl *decl) return true; case DEFINE_TYPE_GENERIC: { + scratch_buffer_clear(); + scratch_buffer_append(symbol->name); + sema_append_generate_parameterized_name(c, module, decl, false); + symbol->type->name = scratch_buffer_interned(); Type *type = type_new(TYPE_TYPEDEF, decl->name); decl->type = type; type->decl = symbol; diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index 5d256558a..d91f6fab3 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -5992,7 +5992,7 @@ static inline bool sema_expr_analyse_flat_element(SemaContext *context, ExprFlat Type *actual_type = type_flatten_distinct(type); if (element->array) { - if (!type_is_arraylike(actual_type) && actual_type->type_kind) + if (!type_is_arraylike(actual_type) && actual_type->type_kind != TYPE_POINTER) { if (is_missing) { @@ -6076,6 +6076,10 @@ static inline bool sema_expr_analyse_flat_element(SemaContext *context, ExprFlat return true; } } + if (actual_type->type_kind == TYPE_POINTER && actual_type->pointer->type_kind != TYPE_POINTER) + { + actual_type = actual_type->pointer; + } if (!type_is_union_or_strukt(actual_type)) { if (is_missing) @@ -6096,6 +6100,15 @@ static inline bool sema_expr_analyse_flat_element(SemaContext *context, ExprFlat Decl *member = sema_decl_stack_find_decl_member(actual_type->decl, element->inner->identifier_expr.ident); if (!member) { + Decl *ambiguous = NULL; + Decl *private = NULL; + member = sema_resolve_method(context->unit, actual_type->decl, kw, &ambiguous, &private); + if (ambiguous) + { + sema_error_at(loc, "'%s' is an ambiguous name and so cannot be resolved, it may refer to method defined in '%s' or one in '%s'", + kw, member->unit->module->name->module, ambiguous->unit->module->name->module); + return false; + } if (is_missing) { *is_missing = true; diff --git a/src/version.h b/src/version.h index 15ba9818f..afac6961e 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define COMPILER_VERSION "0.3.116" \ No newline at end of file +#define COMPILER_VERSION "0.3.117" \ No newline at end of file