mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Fix an issue with pointer debug info creation. Improve generated parameterized name. Version bump.
This commit is contained in:
committed by
Christoffer Lerno
parent
a9ed514fe5
commit
dcf0b4c580
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -1 +1 @@
|
||||
#define COMPILER_VERSION "0.3.116"
|
||||
#define COMPILER_VERSION "0.3.117"
|
||||
Reference in New Issue
Block a user