Updated mangling code.

This commit is contained in:
Christoffer Lerno
2024-06-28 00:57:14 +02:00
parent 043833be7b
commit e2a39aa12e
19 changed files with 222 additions and 161 deletions

View File

@@ -483,3 +483,41 @@ bool ast_supports_continue(Ast *stmt)
if (stmt->ast_kind != AST_FOR_STMT) return false;
return stmt->for_stmt.cond || !stmt->flow.skip_first;
}
void scratch_buffer_set_extern_decl_name(Decl *decl, bool clear)
{
if (clear) scratch_buffer_clear();
if (decl->extname)
{
scratch_buffer_append(decl->extname);
return;
}
if (decl->is_extern)
{
scratch_buffer_append(decl->name);
return;
}
if (decl->decl_kind == DECL_FUNC && decl->func_decl.type_parent)
{
Type *parent = type_infoptr(decl->func_decl.type_parent)->type->canonical;
if (type_is_user_defined(parent))
{
Decl *parent_decl = parent->decl;
if (parent_decl->unit && parent_decl->unit->module) scratch_buffer_append_module(parent_decl->unit->module, decl->is_export);
scratch_buffer_append(decl->is_export ? "__" : ".");
scratch_buffer_append(parent->name);
scratch_buffer_append(decl->is_export ? "__" : ".");
scratch_buffer_append(decl->name);
return;
}
if (decl->unit && decl->unit->module) scratch_buffer_append_module(decl->unit->module, decl->is_export);
scratch_buffer_append(decl->is_export ? "__" : ".");
scratch_buffer_append(parent->name);
scratch_buffer_append(decl->is_export ? "__" : ".");
scratch_buffer_append(decl->name);
return;
}
if (decl->unit && decl->unit->module) scratch_buffer_append_module(decl->unit->module, decl->is_export);
scratch_buffer_append(decl->is_export ? "__" : ".");
scratch_buffer_append(decl->name);
}

View File

@@ -2230,6 +2230,7 @@ bool decl_needs_prefix(Decl *decl);
AlignSize decl_find_member_offset(Decl *decl, Decl *member);
bool decl_is_externally_visible(Decl *decl);
bool decl_is_local(Decl *decl);
void scratch_buffer_set_extern_decl_name(Decl *decl, bool clear);
// --- Expression functions
@@ -2300,7 +2301,7 @@ bool lexer_next_token(Lexer *lexer);
// --- Module functions
void module_copy_extern_name_to_buffer(Module *module);
void scratch_buffer_append_module(Module *module, bool is_export);
Decl *module_find_symbol(Module *module, const char *symbol);
const char *module_create_object_file_name(Module *module);
@@ -3572,10 +3573,6 @@ INLINE Ast *ast_next(AstId *current_ptr)
}
INLINE const char *decl_get_extname(Decl *decl)
{
return decl->extname;
}
INLINE void expr_rewrite_const_bool(Expr *expr, Type *type, bool b)

View File

@@ -108,7 +108,7 @@ bool context_set_module(ParseContext *context, Path *path, const char **generic_
void unit_register_external_symbol(CompilationUnit *unit, Decl *decl)
{
if (decl_module(decl) == unit->module || !decl->extname) return;
if (decl_module(decl) == unit->module) return;
decl->is_external_visible = true;
}
@@ -174,7 +174,6 @@ void unit_register_global_decl(CompilationUnit *unit, Decl *decl)
{
vec_add(unit->macros, decl);
}
decl_set_external_name(decl);
decl_register(decl);
break;
case DECL_FUNC:
@@ -193,7 +192,6 @@ void unit_register_global_decl(CompilationUnit *unit, Decl *decl)
case DECL_VAR:
assert(decl->name);
vec_add(unit->vars, decl);
decl_set_external_name(decl);
decl_register(decl);
break;
case DECL_INTERFACE:
@@ -205,19 +203,16 @@ void unit_register_global_decl(CompilationUnit *unit, Decl *decl)
case DECL_BITSTRUCT:
assert(decl->name);
vec_add(unit->types, decl);
decl_set_external_name(decl);
decl_register(decl);
break;
case DECL_DEFINE:
assert(decl->name);
vec_add(unit->generic_defines, decl);
decl_set_external_name(decl);
decl_register(decl);
break;
case DECL_ENUM:
assert(decl->name);
vec_add(unit->enums, decl);
decl_set_external_name(decl);
decl_register(decl);
break;
case DECL_ATTRIBUTE:

View File

@@ -11,6 +11,11 @@
static void header_gen_struct_union(FILE *file, int indent, Decl *decl);
static void header_gen_maybe_generate_type(FILE *file, HTable *table, Type *type);
INLINE const char *decl_get_extname(Decl *decl)
{
return decl->extname;
}
static bool type_is_func_pointer(Type *type)
{
if (type->type_kind != TYPE_DISTINCT && type->type_kind != TYPE_TYPEDEF) return false;

View File

@@ -518,10 +518,29 @@ void llvm_emit_global_variable_init(GenContext *c, Decl *decl)
LLVMValueRef old = decl->backend_ref;
LLVMValueRef global_ref = decl->backend_ref = llvm_add_global_raw(c,
decl_get_extname(decl),
LLVMTypeOf(init_value),
decl->alignment);
scratch_buffer_set_extern_decl_name(decl, true);
char *name = scratch_buffer_copy();
LLVMValueRef global_ref = decl->backend_ref = llvm_add_global_raw(c, name, LLVMTypeOf(init_value), decl->alignment);
if (llvm_use_debug(c))
{
SourceSpan loc = decl->span;
decl->var.backend_debug_ref = LLVMDIBuilderCreateGlobalVariableExpression(
c->debug.builder,
c->debug.file.debug_file,
decl->name,
strlen(decl->name),
name,
strlen(name),
c->debug.file.debug_file,
loc.row ? loc.row : 1,
llvm_get_debug_type(c, decl->type),
decl_is_local(decl),
LLVMDIBuilderCreateExpression(c->debug.builder, NULL, 0),
NULL,
decl->alignment);
LLVMGlobalSetMetadata(llvm_get_ref(c, decl), 0, decl->var.backend_debug_ref);
}
if (decl->var.is_addr)
{
LLVMSetUnnamedAddress(global_ref, LLVMNoUnnamedAddr);
@@ -586,11 +605,6 @@ void llvm_emit_global_variable_init(GenContext *c, Decl *decl)
LLVMDeleteGlobal(old);
}
// Should we set linkage here?
if (llvm_use_debug(c))
{
llvm_emit_debug_global_var(c, decl);
}
}
static void gencontext_verify_ir(GenContext *context)
{
@@ -1012,13 +1026,23 @@ const char *llvm_codegen(void *context)
return object_name;
}
void llvm_add_global_decl(GenContext *c, Decl *decl)
{
assert(decl->var.kind == VARDECL_GLOBAL || decl->var.kind == VARDECL_CONST);
bool same_module = decl_module(decl) == c->code_module;
const char *name = same_module ? "temp_global" : decl_get_extname(decl);
decl->backend_ref = llvm_add_global(c, name, decl->type, decl->alignment);
LLVMTypeRef type = llvm_get_type(c, decl->type);
if (same_module)
{
// If we initialize it later, we must use a temp name.
decl->backend_ref = llvm_add_global_raw(c, ".tempglobal", type, decl->alignment);
}
else
{
scratch_buffer_set_extern_decl_name(decl, true);
decl->backend_ref = llvm_add_global_raw(c, scratch_buffer_to_string(), type, decl->alignment);
}
if (!same_module)
{
LLVMSetLinkage(decl->backend_ref, LLVMExternalLinkage);
@@ -1029,10 +1053,10 @@ void llvm_add_global_decl(GenContext *c, Decl *decl)
}
if (IS_OPTIONAL(decl))
{
scratch_buffer_clear();
scratch_buffer_append(decl_get_extname(decl));
LLVMTypeRef anyfault = llvm_get_type(c, type_anyfault);
scratch_buffer_set_extern_decl_name(decl, true);
scratch_buffer_append(".f");
decl->var.optional_ref = llvm_add_global(c, scratch_buffer_to_string(), type_anyfault, 0);
decl->var.optional_ref = llvm_add_global_raw(c, scratch_buffer_to_string(), anyfault, 0);
}
llvm_set_global_tls(decl);
}
@@ -1136,12 +1160,14 @@ void llvm_append_function_attributes(GenContext *c, Decl *decl)
{
if (c->code_module == decl_module(decl))
{
llvm_attribute_add_string(c, function, "wasm-export-name", decl_get_extname(decl), -1);
scratch_buffer_set_extern_decl_name(decl, true);
llvm_attribute_add_string(c, function, "wasm-export-name", scratch_buffer_to_string(), -1);
}
}
if (decl->is_extern && arch_is_wasm(platform_target.arch))
{
llvm_attribute_add_string(c, function, "wasm-import-name", decl_get_extname(decl), -1);
scratch_buffer_set_extern_decl_name(decl, true);
llvm_attribute_add_string(c, function, "wasm-import-name", scratch_buffer_to_string(), -1);
}
if (decl->alignment != type_abi_alignment(decl->type))
{
@@ -1186,7 +1212,9 @@ LLVMValueRef llvm_get_ref(GenContext *c, Decl *decl)
{
return decl->backend_ref = llvm_get_selector(c, decl->name);
}
backend_ref = decl->backend_ref = LLVMAddFunction(c->module, decl_get_extname(decl), llvm_get_type(c, decl->type));
LLVMTypeRef type = llvm_get_type(c, decl->type);
scratch_buffer_set_extern_decl_name(decl, true);
backend_ref = decl->backend_ref = LLVMAddFunction(c->module, scratch_buffer_to_string(), type);
llvm_append_function_attributes(c, decl);
if (decl->is_export && platform_target.os == OS_TYPE_WIN32 && !active_target.win.def && decl->name != kw_main && decl->name != kw_mainstub)
{
@@ -1246,7 +1274,8 @@ static void llvm_gen_test_main(GenContext *c)
LLVMTypeRef main_type = LLVMFunctionType(cint, NULL, 0, true);
LLVMTypeRef runner_type = LLVMFunctionType(c->byte_type, NULL, 0, true);
LLVMValueRef func = LLVMAddFunction(c->module, kw_main, main_type);
LLVMValueRef other_func = LLVMAddFunction(c->module, test_runner->extname, runner_type);
scratch_buffer_set_extern_decl_name(test_runner, true);
LLVMValueRef other_func = LLVMAddFunction(c->module, scratch_buffer_to_string(), runner_type);
LLVMBuilderRef builder = llvm_create_function_entry(c, func, NULL);
LLVMValueRef val = LLVMBuildCall2(builder, runner_type, other_func, NULL, 0, "");
val = LLVMBuildSelect(builder, LLVMBuildTrunc(builder, val, c->bool_type, ""),
@@ -1275,7 +1304,8 @@ INLINE GenContext *llvm_gen_tests(Module** modules, unsigned module_count, LLVMC
FOREACH_BEGIN(Decl *test, module->tests)
LLVMValueRef ref;
LLVMTypeRef type = opt_test;
ref = LLVMAddFunction(c->module, test->extname, type);
scratch_buffer_set_extern_decl_name(test, true);
ref = LLVMAddFunction(c->module, scratch_buffer_to_string(), type);
scratch_buffer_clear();
scratch_buffer_printf("%s::%s", module->name->module, test->name);
LLVMValueRef name = llvm_emit_string_const(c, scratch_buffer_to_string(), ".test.name");
@@ -1342,7 +1372,8 @@ static void llvm_gen_benchmark_main(GenContext *c)
LLVMTypeRef main_type = LLVMFunctionType(cint, NULL, 0, true);
LLVMTypeRef runner_type = LLVMFunctionType(c->byte_type, NULL, 0, true);
LLVMValueRef func = LLVMAddFunction(c->module, kw_main, main_type);
LLVMValueRef other_func = LLVMAddFunction(c->module, benchmark_runner->extname, runner_type);
scratch_buffer_set_extern_decl_name(benchmark_runner, true);
LLVMValueRef other_func = LLVMAddFunction(c->module, scratch_buffer_to_string(), runner_type);
LLVMBuilderRef builder = llvm_create_function_entry(c, func, NULL);
LLVMValueRef val = LLVMBuildCall2(builder, runner_type, other_func, NULL, 0, "");
val = LLVMBuildSelect(builder, LLVMBuildTrunc(builder, val, c->bool_type, ""),
@@ -1371,7 +1402,8 @@ INLINE GenContext *llvm_gen_benchmarks(Module** modules, unsigned module_count,
FOREACH_BEGIN(Decl *benchmark, module->benchmarks)
LLVMValueRef ref;
LLVMTypeRef type = opt_benchmark;
ref = LLVMAddFunction(c->module, benchmark->extname, type);
scratch_buffer_set_extern_decl_name(benchmark, true);
ref = LLVMAddFunction(c->module, scratch_buffer_to_string(), type);
scratch_buffer_clear();
scratch_buffer_printf("%s::%s", module->name->module, benchmark->name);
LLVMValueRef name = llvm_emit_string_const(c, scratch_buffer_to_string(), ".benchmark.name");

View File

@@ -40,7 +40,7 @@ static inline LLVMMetadataRef llvm_get_debug_struct(GenContext *c, Type *type, c
}
LLVMMetadataRef real = LLVMDIBuilderCreateStructType(c->debug.builder,
scope,
external_name_len ? type->name : "", external_name_len ? strlen(type->name) : 0,
type->name ? type->name : "", type->name ? strlen(type->name) : 0,
file,
row,
type_size(type) * 8,
@@ -80,26 +80,6 @@ LLVMMetadataRef llvm_debug_current_scope(GenContext *context)
return context->debug.compile_unit;
}
void llvm_emit_debug_global_var(GenContext *c, Decl *global)
{
SourceSpan loc = global->span;
global->var.backend_debug_ref = LLVMDIBuilderCreateGlobalVariableExpression(
c->debug.builder,
c->debug.file.debug_file,
global->name,
strlen(global->name),
global->extname,
strlen(global->extname),
c->debug.file.debug_file,
loc.row ? loc.row : 1,
llvm_get_debug_type(c, global->type),
decl_is_local(global),
LLVMDIBuilderCreateExpression(c->debug.builder, NULL, 0),
NULL,
global->alignment);
LLVMGlobalSetMetadata(llvm_get_ref(c, global), 0, global->var.backend_debug_ref);
}
void llvm_emit_debug_function(GenContext *c, Decl *decl)
{
if (!decl->func_decl.body) return;
@@ -110,13 +90,13 @@ void llvm_emit_debug_function(GenContext *c, Decl *decl)
uint32_t row = decl->span.row;
if (!row) row = 1;
assert(decl->name);
assert(decl->extname);
assert(c->debug.file.debug_file);
LLVMMetadataRef debug_type = llvm_get_debug_type(c, decl->type);
scratch_buffer_set_extern_decl_name(decl, true);
c->debug.function = LLVMDIBuilderCreateFunction(c->debug.builder,
c->debug.file.debug_file,
decl->name, strlen(decl->name),
decl->extname, strlen(decl->extname),
scratch_buffer_to_string(), scratch_buffer.len,
c->debug.file.debug_file,
row,
debug_type,
@@ -264,8 +244,8 @@ static LLVMMetadataRef llvm_debug_forward_comp(GenContext *c, Type *type, const
type_size(type) * 8,
type_abi_alignment(type) * 8,
flags,
external_name,
strlen(external_name));
"temp",
4);
}
@@ -348,7 +328,7 @@ static LLVMMetadataRef llvm_debug_enum_type(GenContext *c, Type *type, LLVMMetad
{
Decl *decl = type->decl;
LLVMMetadataRef forward = llvm_debug_forward_comp(c, type, decl->extname, &decl->span, scope, LLVMDIFlagZero);
LLVMMetadataRef forward = llvm_debug_forward_comp(c, type, "temp_enum", &decl->span, scope, LLVMDIFlagZero);
type->backend_debug_type = forward;
Type *enum_real_type = decl->enums.type_info->type->canonical;
@@ -389,7 +369,7 @@ static LLVMMetadataRef llvm_debug_structlike_type(GenContext *c, Type *type, LLV
LLVMDIFlags flags = 0;
// Create a forward reference in case of recursive data.
LLVMMetadataRef forward = llvm_debug_forward_comp(c, type, decl->extname, &decl->span, scope, flags);
LLVMMetadataRef forward = llvm_debug_forward_comp(c, type, "temp", &decl->span, scope, flags);
type->backend_debug_type = forward;
LLVMMetadataRef *elements = NULL;
@@ -408,24 +388,33 @@ static LLVMMetadataRef llvm_debug_structlike_type(GenContext *c, Type *type, LLV
}
LLVMMetadataRef real;
const char *extname = "";
unsigned extname_len = 0;
if (decl->name)
{
scratch_buffer_set_extern_decl_name(decl, true);
extname = scratch_buffer_to_string();
extname_len = scratch_buffer.len;
}
if (type->type_kind == TYPE_UNION)
{
unsigned row = decl->span.row;
real = LLVMDIBuilderCreateUnionType(c->debug.builder,
scope,
type->decl->name ? type->decl->name : "",
type->decl->name ? strlen(type->decl->name) : 0,
decl->name ? decl->name : "",
decl->name ? strlen(decl->name) : 0,
c->debug.file.debug_file, row ? row : 1, type_size(type) * 8,
type_abi_alignment(type) * 8,
LLVMDIFlagZero,
elements, vec_size(members),
c->debug.runtime_version,
type->decl->name ? decl->extname : "",
type->decl->name ? strlen(decl->extname) : 0);
extname,
extname_len);
LLVMMetadataReplaceAllUsesWith(forward, real);
return real;
}
return llvm_get_debug_struct(c, type, decl->name ? decl->extname : "", elements, vec_size(elements), &decl->span, scope, LLVMDIFlagZero);
return llvm_get_debug_struct(c, type, extname, elements, vec_size(elements), &decl->span, scope, LLVMDIFlagZero);
}
static LLVMMetadataRef llvm_debug_slice_type(GenContext *c, Type *type)

View File

@@ -404,7 +404,7 @@ void llvm_emit_return_implicit(GenContext *c)
void llvm_emit_function_body(GenContext *c, Decl *decl)
{
DEBUG_LOG("Generating function %s.", decl->extname);
DEBUG_LOG("Generating function %s.", decl->name);
if (decl->func_decl.attr_dynamic) vec_add(c->dynamic_functions, decl);
assert(decl->backend_ref);
if (decl->func_decl.attr_init || decl->func_decl.attr_finalizer)
@@ -577,8 +577,8 @@ void llvm_emit_dynamic_functions(GenContext *c, Decl **funcs)
Type *type = typeget(decl->func_decl.type_parent);
scratch_buffer_clear();
scratch_buffer_append("$ct.dyn.");
scratch_buffer_append(decl_get_extname(decl));
LLVMValueRef global = llvm_add_global_raw(c, scratch_buffer_to_string(), c->dtable_type, 0);
scratch_buffer_set_extern_decl_name(decl, false);
LLVMValueRef global = llvm_add_global_raw(c, scratch_buffer_copy(), c->dtable_type, 0);
Decl *proto = declptrzero(decl->func_decl.interface_method);
LLVMValueRef proto_ref = proto ? llvm_get_ref(c, proto) : llvm_get_selector(c, decl->name);
LLVMValueRef vals[3] = { llvm_get_ref(c, decl), proto_ref, LLVMConstNull(c->ptr_type) };

View File

@@ -560,7 +560,6 @@ void llvm_emit_debug_location(GenContext *c, SourceSpan location);
LLVMMetadataRef llvm_create_debug_location(GenContext *c, SourceSpan location);
void llvm_emit_debug_parameter(GenContext *c, Decl *parameter, unsigned index);
void llvm_emit_debug_local_var(GenContext *c, Decl *var);
void llvm_emit_debug_global_var(GenContext *c, Decl *global);
#define FRAMEPOINTER (platform_target.arch == ARCH_TYPE_AARCH64 ? 1 : 2)
#define UWTABLE (active_target.arch_os_target == MACOS_AARCH64 ? 1 : 2)

View File

@@ -43,13 +43,15 @@ void llvm_emit_local_static(GenContext *c, Decl *decl, BEValue *value)
c->builder = c->global_builder;
// Emit the global.
decl->backend_ref = llvm_add_global(c, "temp", type_lowering(decl->type), decl->alignment);
decl->backend_ref = llvm_add_global(c, "temp", decl->type, decl->alignment);
if (IS_OPTIONAL(decl))
{
scratch_buffer_clear();
scratch_buffer_append(decl_get_extname(decl));
LLVMTypeRef anyfault = llvm_get_type(c, type_anyfault);
scratch_buffer_append(c->cur_func.name);
scratch_buffer_append_char('.');
scratch_buffer_append(decl->name);
scratch_buffer_append(".f");
decl->var.optional_ref = llvm_add_global(c, scratch_buffer_to_string(), type_anyfault, 0);
decl->var.optional_ref = llvm_add_global_raw(c, scratch_buffer_to_string(), anyfault, 0);
}
llvm_emit_global_variable_init(c, decl);

View File

@@ -555,8 +555,7 @@ static LLVMValueRef llvm_get_introspection_for_enum(GenContext *c, Type *type)
Decl *associated_value = associated_values[ai];
LLVMValueRef associated_value_arr = mixed ? llvm_get_packed_struct(c, values, elements)
: llvm_get_array(val_type, values, elements);
scratch_buffer_clear();
scratch_buffer_append(decl->extname);
scratch_buffer_set_extern_decl_name(decl, true);
scratch_buffer_append("$");
scratch_buffer_append(associated_value->name);
LLVMValueRef global_ref = llvm_add_global_raw(c,
@@ -598,8 +597,7 @@ static LLVMValueRef llvm_get_introspection_for_fault(GenContext *c, Type *type)
LLVMValueRef ref = llvm_generate_temp_introspection_global(c, type);
for (unsigned i = 0; i < elements; i++)
{
scratch_buffer_clear();
scratch_buffer_append(decl_get_extname(decl));
scratch_buffer_set_extern_decl_name(decl, true);
scratch_buffer_append_char('$');
Decl *val = fault_vals[i];
scratch_buffer_append(val->name);

View File

@@ -9,7 +9,7 @@ Decl *module_find_symbol(Module *module, const char *symbol)
return htable_get(&module->symbols, (void*)symbol);
}
void module_copy_extern_name_to_buffer(Module *module)
void scratch_buffer_append_module(Module *module, bool is_export)
{
if (module->extname)
{
@@ -24,7 +24,7 @@ void module_copy_extern_name_to_buffer(Module *module)
{
case ':':
assert(name[0] == ':');
scratch_buffer_append_char('_');
scratch_buffer_append_char(is_export ? '_' : '.');
name++;
break;
default:

View File

@@ -846,13 +846,6 @@ static bool sema_analyse_interface(SemaContext *context, Decl *decl, bool *erase
return false;
}
}
if (!method->extname)
{
scratch_buffer_clear();
type_mangle_introspect_name_to_buffer(decl->type);
scratch_buffer_printf(".%s", name);
method->extname = scratch_buffer_copy();
}
}
return true;
}
@@ -1231,7 +1224,6 @@ static inline bool sema_analyse_typedef(SemaContext *context, Decl *decl, bool *
if (*erase_decl) return true;
bool is_export = decl->is_export;
if (is_export) decl_set_external_name(decl);
if (decl->typedef_decl.is_func)
{
Decl *fn_decl = decl->typedef_decl.decl;
@@ -1610,39 +1602,6 @@ static bool sema_check_operator_method_validity(SemaContext *context, Decl *meth
UNREACHABLE
}
INLINE void sema_set_method_ext_name(CompilationUnit *unit, const char *parent_name, Decl *method_like)
{
if (method_like->has_extname) return;
scratch_buffer_clear();
if (method_like->is_export)
{
scratch_buffer_append(parent_name);
scratch_buffer_append("_");
scratch_buffer_append(method_like->name);
method_like->extname = scratch_buffer_copy();
return;
}
switch (method_like->visibility)
{
case VISIBLE_PUBLIC:
case VISIBLE_PRIVATE:
scratch_buffer_append(parent_name);
scratch_buffer_append_char('.');
scratch_buffer_append(method_like->name);
break;
case VISIBLE_LOCAL:
scratch_buffer_append(unit->file->name);
scratch_buffer_append_char('.');
scratch_buffer_append(parent_name);
scratch_buffer_append_char('.');
scratch_buffer_append(method_like->name);
break;
default:
UNREACHABLE
}
method_like->extname = scratch_buffer_copy();
}
bool sema_decl_if_cond(SemaContext *context, Decl *decl)
{
Attr *attr = attr_find_kind(decl->attributes, ATTRIBUTE_IF);
@@ -1686,9 +1645,6 @@ unit_add_base_extension_method(SemaContext *context, CompilationUnit *unit, Type
"Only user-defined types support operator oveloading.");
}
// As with normal methods, update the name.
sema_set_method_ext_name(unit, parent_type->name, method);
// Add it to the right list of extensions.
switch (method->visibility)
{
@@ -1890,8 +1846,6 @@ static inline bool unit_add_method(SemaContext *context, Type *parent_type, Decl
if (!sema_analyse_operator_method(context, parent_type, method)) return false;
}
// Set the external name
sema_set_method_ext_name(unit, parent->extname, method);
DEBUG_LOG("Method-like '%s.%s' analysed.", parent->name, method->name);
// Add it to the correct place: type methods, private extensions, local method extensions
@@ -3145,7 +3099,6 @@ static inline bool sema_analyse_func(SemaContext *context, Decl *decl, bool *era
}
if (!sema_analyse_main_function(context, decl)) return false;
}
decl_set_external_name(decl);
}
// Do we have fn void any.foo(void*) { ... }?
@@ -3464,6 +3417,7 @@ bool sema_analyse_var_decl(SemaContext *context, Decl *decl, bool local)
case VARDECL_GLOBAL:
is_global = true;
break;
case VARDECL_CONST:
default:
break;
}
@@ -3499,14 +3453,6 @@ bool sema_analyse_var_decl(SemaContext *context, Decl *decl, bool local)
bool is_static = decl->var.is_static;
bool global_level_var = is_static || decl->var.kind == VARDECL_CONST || is_global;
if (global_level_var && !decl->has_extname)
{
scratch_buffer_clear();
scratch_buffer_append(context->call_env.kind == CALL_ENV_FUNCTION ? context->call_env.current_function->name : ".global");
scratch_buffer_append_char('.');
scratch_buffer_append(decl->name);
decl->extname = scratch_buffer_copy();
}
if (decl->is_extern && decl->var.init_expr)
{
assert(is_global);
@@ -3650,6 +3596,15 @@ bool sema_analyse_var_decl(SemaContext *context, Decl *decl, bool local)
}
}
EXIT_OK:;
// Patch the external name for local consts and static variables.
if ((decl->var.kind == VARDECL_CONST || is_static) && !decl->extname && context->call_env.kind == CALL_ENV_FUNCTION)
{
scratch_buffer_clear();
scratch_buffer_append(context->call_env.current_function->name);
scratch_buffer_append_char('.');
scratch_buffer_append(decl->name);
decl->extname = scratch_buffer_copy();
}
if (!decl->alignment)
{
if (!sema_set_alloca_alignment(context, decl->type, &decl->alignment)) return false;
@@ -4109,23 +4064,19 @@ bool sema_analyse_decl(SemaContext *context, Decl *decl)
decl->resolve_status = RESOLVE_RUNNING;
assert(decl->unit);
bool erase_decl = false;
bool set_external_name = false;
switch (decl->decl_kind)
{
case DECL_ERASED:
break;
case DECL_INTERFACE:
if (!sema_analyse_interface(context, decl, &erase_decl)) goto FAILED;
set_external_name = true;
break;
case DECL_BITSTRUCT:
if (!sema_analyse_bitstruct(context, decl, &erase_decl)) goto FAILED;
set_external_name = true;
break;
case DECL_STRUCT:
case DECL_UNION:
if (!sema_analyse_struct_union(context, decl, &erase_decl)) goto FAILED;
set_external_name = true;
break;
case DECL_FNTYPE:
if (!sema_analyse_fntype(context, decl, &erase_decl)) goto FAILED;
@@ -4138,25 +4089,21 @@ bool sema_analyse_decl(SemaContext *context, Decl *decl)
break;
case DECL_VAR:
if (!sema_analyse_var_decl(context, decl, false)) goto FAILED;
set_external_name = true;
break;
case DECL_ATTRIBUTE:
if (!sema_analyse_attribute_decl(context, context, decl, &erase_decl)) goto FAILED;
break;
case DECL_DISTINCT:
if (!sema_analyse_distinct(context, decl, &erase_decl)) goto FAILED;
set_external_name = true;
break;
case DECL_TYPEDEF:
if (!sema_analyse_typedef(context, decl, &erase_decl)) goto FAILED;
break;
case DECL_ENUM:
if (!sema_analyse_enum(context, decl, &erase_decl)) goto FAILED;
set_external_name = true;
break;
case DECL_FAULT:
if (!sema_analyse_error(context, decl, &erase_decl)) goto FAILED;
set_external_name = true;
break;
case DECL_DEFINE:
if (!sema_analyse_define(context, decl, &erase_decl)) goto FAILED;
@@ -4178,9 +4125,7 @@ bool sema_analyse_decl(SemaContext *context, Decl *decl)
if (erase_decl)
{
decl->decl_kind = DECL_ERASED;
set_external_name = false;
}
if (set_external_name) decl_set_external_name(decl);
decl->resolve_status = RESOLVE_DONE;
sema_context_destroy(&temp_context);

View File

@@ -7372,7 +7372,15 @@ static inline void sema_expr_rewrite_to_type_nameof(Expr *expr, Type *type, Toke
if (type_is_func_ptr(type)) type = type->pointer->function.prototype->raw_type;
if (name_type == TOKEN_CT_EXTNAMEOF)
{
expr_rewrite_to_string(expr, type->decl->extname);
if (type_is_user_defined(type))
{
scratch_buffer_set_extern_decl_name(type->decl, true);
expr_rewrite_to_string(expr, scratch_buffer_copy());
}
else
{
expr_rewrite_to_string(expr, type->name);
}
return;
}
@@ -7409,12 +7417,64 @@ static inline bool sema_expr_analyse_ct_nameof(SemaContext *context, Expr *expr)
if (name_type == TOKEN_CT_EXTNAMEOF)
{
if (!decl->extname)
switch (decl->decl_kind)
{
SEMA_ERROR(main_var, "'%s' does not have an external name.", decl->name);
return false;
case DECL_VAR:
switch (decl->var.kind)
{
case VARDECL_CONST:
case VARDECL_GLOBAL:
goto RETURN_CT;
case VARDECL_LOCAL:
case VARDECL_PARAM:
case VARDECL_MEMBER:
case VARDECL_BITMEMBER:
case VARDECL_PARAM_REF:
case VARDECL_PARAM_EXPR:
case VARDECL_UNWRAPPED:
case VARDECL_ERASE:
case VARDECL_REWRAPPED:
case VARDECL_PARAM_CT:
case VARDECL_PARAM_CT_TYPE:
case VARDECL_LOCAL_CT:
case VARDECL_LOCAL_CT_TYPE:
// TODO verify that all of these are correct.
break;
}
FALLTHROUGH;
case DECL_POISONED:
case DECL_ATTRIBUTE:
case DECL_BODYPARAM:
case DECL_CT_ASSERT:
case DECL_CT_ECHO:
case DECL_CT_EXEC:
case DECL_CT_INCLUDE:
case DECL_DECLARRAY:
case DECL_ERASED:
case DECL_GLOBALS:
case DECL_IMPORT:
case DECL_LABEL:
case DECL_MACRO:
case DECL_DEFINE:
RETURN_SEMA_ERROR(main_var, "'%s' does not have an external name.", decl->name);
case DECL_BITSTRUCT:
case DECL_DISTINCT:
case DECL_ENUM:
case DECL_ENUM_CONSTANT:
case DECL_FAULT:
case DECL_FAULTVALUE:
case DECL_FNTYPE:
case DECL_FUNC:
case DECL_INTERFACE:
case DECL_STRUCT:
case DECL_TYPEDEF:
case DECL_UNION:
// TODO verify that all of these are correct
goto RETURN_CT;
}
expr_rewrite_to_string(expr, decl->extname);
RETURN_CT:
scratch_buffer_set_extern_decl_name(decl, true);
expr_rewrite_to_string(expr, scratch_buffer_to_string());
return true;
}
if (!decl->unit || name_type == TOKEN_CT_NAMEOF || decl_is_var_local(decl))
@@ -7808,7 +7868,8 @@ static inline bool sema_expr_analyse_lambda(SemaContext *context, Type *target_t
}
scratch_buffer_append("$lambda");
scratch_buffer_append_unsigned_int(++unit->lambda_count);
decl->extname = decl->name = scratch_buffer_copy();
decl->name = scratch_buffer_copy();
decl->extname = decl->name;
decl->type = type_new_func(decl, sig);
if (!sema_analyse_function_signature(context, decl, sig->abi, sig)) return false;
if (target_type && flat->pointer->function.prototype->raw_type != decl->type->function.prototype->raw_type)

View File

@@ -633,7 +633,7 @@ void type_mangle_introspect_name_to_buffer(Type *type)
type = type->function.prototype->raw_type;
if (type->function.decl)
{
module_copy_extern_name_to_buffer(decl_module(type->function.decl));
scratch_buffer_append_module(decl_module(type->function.decl), true);
scratch_buffer_append("$");
scratch_buffer_append(type->name);
}

View File

@@ -690,11 +690,11 @@ no_match: ; preds = %compare
!106 = !{!12}
!107 = !DILocalVariable(name: "scratch", scope: !108, file: !5, line: 110, type: !109, align: 8)
!108 = distinct !DISubprogram(name: "@scratch", linkageName: "@scratch", scope: !5, file: !5, line: 109, scopeLine: 109, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit:
!109 = !DICompositeType(tag: DW_TAG_structure_type, name: "Arena_Cursor", scope: !5, file: !5, line: 88, size: 128, align: 64, elements: !110, identifier: "foo_Arena_Cursor")
!109 = !DICompositeType(tag: DW_TAG_structure_type, name: "Arena_Cursor", scope: !5, file: !5, line: 88, size: 128, align: 64, elements: !110, identifier: "foo__Arena_Cursor")
!110 = !{!111, !116}
!111 = !DIDerivedType(tag: DW_TAG_member, name: "arena", scope: !109, file: !5, line: 89, baseType: !112, size: 64, align: 64)
!112 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "Arena*", baseType: !113, size: 64, align: 64, dwarfAddressSpace: 0)
!113 = !DICompositeType(tag: DW_TAG_structure_type, name: "Arena", scope: !5, file: !5, line: 84, size: 64, align: 64, elements: !114, identifier: "foo_Arena")
!113 = !DICompositeType(tag: DW_TAG_structure_type, name: "Arena", scope: !5, file: !5, line: 84, size: 64, align: 64, elements: !114, identifier: "foo__Arena")
!114 = !{!115}
!115 = !DIDerivedType(tag: DW_TAG_member, name: "cursor", scope: !113, file: !5, line: 85, baseType: !44, size: 64, align: 64)
!116 = !DIDerivedType(tag: DW_TAG_member, name: "cursor", scope: !109, file: !5, line: 90, baseType: !44, size: 64, align: 64, offset: 64)

View File

@@ -12,7 +12,7 @@ fn int main()
/* #expect: foo.ll
@foo_data = local_unnamed_addr global <{ { { { float, [4 x float], float, [4 x float], float, [4 x float], float } } }, { { { float, [4 x float], float, [4 x float], float, [4 x float], float } } } }> <{ { { { float, [4 x float], float, [4 x float], float, [4 x float], float } } } { { { float, [4 x float], float, [4 x float], float, [4 x float], float } } { { float, [4 x float], float, [4 x float], float, [4 x float], float } { float 1.000000e+00, [4 x float] zeroinitializer, float 1.000000e+00, [4 x float] zeroinitializer, float 1.000000e+00, [4 x float] zeroinitializer, float 1.000000e+00 } } }, { { { float, [4 x float], float, [4 x float], float, [4 x float], float } } } { { { float, [4 x float], float, [4 x float], float, [4 x float], float } } { { float, [4 x float], float, [4 x float], float, [4 x float], float } { float 1.000000e+00, [4 x float] zeroinitializer, float 1.000000e+00, [4 x float] zeroinitializer, float 1.000000e+00, [4 x float] zeroinitializer, float 1.000000e+00 } } } }>, align 16
@foo__data = local_unnamed_addr global <{ { { { float, [4 x float], float, [4 x float], float, [4 x float], float } } }, { { { float, [4 x float], float, [4 x float], float, [4 x float], float } } } }> <{ { { { float, [4 x float], float, [4 x float], float, [4 x float], float } } } { { { float, [4 x float], float, [4 x float], float, [4 x float], float } } { { float, [4 x float], float, [4 x float], float, [4 x float], float } { float 1.000000e+00, [4 x float] zeroinitializer, float 1.000000e+00, [4 x float] zeroinitializer, float 1.000000e+00, [4 x float] zeroinitializer, float 1.000000e+00 } } }, { { { float, [4 x float], float, [4 x float], float, [4 x float], float } } } { { { float, [4 x float], float, [4 x float], float, [4 x float], float } } { { float, [4 x float], float, [4 x float], float, [4 x float], float } { float 1.000000e+00, [4 x float] zeroinitializer, float 1.000000e+00, [4 x float] zeroinitializer, float 1.000000e+00, [4 x float] zeroinitializer, float 1.000000e+00 } } } }>, align 16
@foo.x = local_unnamed_addr global { { { float, [4 x float], float, [4 x float], float, [4 x float], float } } } { { { float, [4 x float], float, [4 x float], float, [4 x float], float } } { { float, [4 x float], float, [4 x float], float, [4 x float], float } { float 1.000000e+00, [4 x float] zeroinitializer, float 1.000000e+00, [4 x float] zeroinitializer, float 1.000000e+00, [4 x float] zeroinitializer, float 1.000000e+00 } } }, align 4
entry:

View File

@@ -19,11 +19,11 @@ int d @private;
/* #expect: test.ll
@TEST_a = local_unnamed_addr global i32 0, align 4
@TEST__a = local_unnamed_addr global i32 0, align 4
@TEST.b = internal unnamed_addr global i32 0, align 4
@TEST_c = local_unnamed_addr global i32 0, align 4
@TEST_d = local_unnamed_addr global i32 0, align 4
@TEST__c = local_unnamed_addr global i32 0, align 4
@TEST__d = local_unnamed_addr global i32 0, align 4
define internal void @TEST.hello()
define void @TEST_hello2()
define void @TEST_helloe()
define void @TEST__hello2()
define void @TEST__helloe()

View File

@@ -17,7 +17,7 @@ fn int foo(int x) @export
}
/* #expect: test.ll
define i32 @test_foo(i32 %0) #0 {
define i32 @test__foo(i32 %0) #0 {
entry:
%x = alloca i32, align 4
%switch = alloca i32, align 4

View File

@@ -718,7 +718,7 @@ entry:
br i1 %eq, label %and.rhs, label %and.phi
and.rhs: ; preds = %entry
%2 = call i8 @char.is_alpha(i8 zeroext %1)
%2 = call i8 @std.ascii.char.is_alpha(i8 zeroext %1)
%3 = trunc i8 %2 to i1
br label %and.phi
@@ -731,7 +731,7 @@ or.rhs: ; preds = %and.phi
br i1 %lt, label %and.rhs1, label %and.phi2
and.rhs1: ; preds = %or.rhs
%4 = call i8 @char.is_alnum(i8 zeroext %1)
%4 = call i8 @std.ascii.char.is_alnum(i8 zeroext %1)
%5 = trunc i8 %4 to i1
br label %and.phi2