Fix an issue with pointer debug info creation. Improve generated parameterized name. Version bump.

This commit is contained in:
Christoffer Lerno
2022-12-13 18:54:58 +01:00
committed by Christoffer Lerno
parent a9ed514fe5
commit dcf0b4c580
5 changed files with 129 additions and 76 deletions

View File

@@ -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];
}

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -1 +1 @@
#define COMPILER_VERSION "0.3.116"
#define COMPILER_VERSION "0.3.117"