Fixes to debug info in function pointer declarations. Incorrect x64 ABI code for structs by val. Change "Compiler" to "GlobalContext" storage of all types inside. Call debug symbol correct.

This commit is contained in:
Christoffer Lerno
2021-05-02 16:42:28 +02:00
parent c6f671a6ca
commit 3bd638bf77
17 changed files with 80 additions and 84 deletions

View File

@@ -23,8 +23,8 @@ ABIArgInfo *abi_arg_new_direct_coerce(AbiType *target_type);
ABIArgInfo *abi_arg_new_expand_coerce(AbiType *target_type, unsigned offset);
ABIArgInfo *abi_arg_new_expand_coerce_pair(AbiType *first_element, unsigned initial_offset, AbiType *second_element, unsigned padding, bool is_packed);
ABIArgInfo *abi_arg_new_expand_padded(Type *padding);
ABIArgInfo *abi_arg_new_indirect_realigned(unsigned alignment);
ABIArgInfo *abi_arg_new_indirect_by_val(void);
ABIArgInfo *abi_arg_new_indirect_realigned(unsigned alignment, Type *by_val_type);
ABIArgInfo *abi_arg_new_indirect_by_val(Type *by_val_type);
ABIArgInfo *abi_arg_new_indirect_not_by_val(void);
ByteSize abi_type_abi_alignment(AbiType *type);

View File

@@ -6,7 +6,7 @@
#include "../build/build_options.h"
#include <unistd.h>
Compiler compiler;
GlobalContext global_context;
BuildTarget active_target;
Vmem ast_arena;
@@ -22,8 +22,8 @@ void compiler_init(const char *std_lib_dir)
// Skip library detection.
//compiler.lib_dir = find_lib_dir();
//DEBUG_LOG("Found std library: %s", compiler.lib_dir);
stable_init(&compiler.modules, 64);
stable_init(&compiler.global_symbols, 0x1000);
stable_init(&global_context.modules, 64);
stable_init(&global_context.global_symbols, 0x1000);
vmem_init(&ast_arena, 4 * 1024);
vmem_init(&expr_arena, 4 * 1024);
vmem_init(&decl_arena, 1024);
@@ -37,20 +37,20 @@ void compiler_init(const char *std_lib_dir)
(void) tokdata_calloc();
if (std_lib_dir)
{
compiler.lib_dir = std_lib_dir;
global_context.lib_dir = std_lib_dir;
}
else
{
compiler.lib_dir = find_lib_dir();
global_context.lib_dir = find_lib_dir();
}
}
static void compiler_lex(void)
{
VECEACH(compiler.sources, i)
VECEACH(global_context.sources, i)
{
bool loaded = false;
File *file = source_file_load(compiler.sources[i], &loaded);
File *file = source_file_load(global_context.sources[i], &loaded);
if (loaded) continue;
Lexer lexer;
lexer_init_with_file(&lexer, file);
@@ -68,10 +68,10 @@ static void compiler_lex(void)
void compiler_parse(void)
{
VECEACH(compiler.sources, i)
VECEACH(global_context.sources, i)
{
bool loaded = false;
File *file = source_file_load(compiler.sources[i], &loaded);
File *file = source_file_load(global_context.sources[i], &loaded);
if (loaded) continue;
diag_setup(active_target.test_output);
Context *context = context_create(file);
@@ -85,19 +85,19 @@ void compiler_compile(void)
{
Context **contexts = NULL;
diag_setup(active_target.test_output);
if (compiler.lib_dir)
if (global_context.lib_dir)
{
vec_add(compiler.sources, strformat("%s/std/runtime.c3", compiler.lib_dir));
vec_add(compiler.sources, strformat("%s/std/builtin.c3", compiler.lib_dir));
vec_add(compiler.sources, strformat("%s/std/io.c3", compiler.lib_dir));
vec_add(compiler.sources, strformat("%s/std/mem.c3", compiler.lib_dir));
vec_add(compiler.sources, strformat("%s/std/array.c3", compiler.lib_dir));
vec_add(compiler.sources, strformat("%s/std/math.c3", compiler.lib_dir));
vec_add(global_context.sources, strformat("%s/std/runtime.c3", global_context.lib_dir));
vec_add(global_context.sources, strformat("%s/std/builtin.c3", global_context.lib_dir));
vec_add(global_context.sources, strformat("%s/std/io.c3", global_context.lib_dir));
vec_add(global_context.sources, strformat("%s/std/mem.c3", global_context.lib_dir));
vec_add(global_context.sources, strformat("%s/std/array.c3", global_context.lib_dir));
vec_add(global_context.sources, strformat("%s/std/math.c3", global_context.lib_dir));
}
VECEACH(compiler.sources, i)
VECEACH(global_context.sources, i)
{
bool loaded = false;
File *file = source_file_load(compiler.sources[i], &loaded);
File *file = source_file_load(global_context.sources[i], &loaded);
if (loaded) continue;
Context *context = context_create(file);
vec_add(contexts, context);
@@ -272,7 +272,7 @@ void compile_file_list(BuildOptions *options)
void compile()
{
compiler.sources = active_target.sources;
global_context.sources = active_target.sources;
symtab_init(active_target.symtab_size ? active_target.symtab_size : 64 * 1024);
target_expand_source_names(&active_target);
target_setup(&active_target);
@@ -294,19 +294,19 @@ void compile()
Decl *compiler_find_symbol(const char *string)
{
return stable_get(&compiler.global_symbols, string);
return stable_get(&global_context.global_symbols, string);
}
void compiler_add_type(Type *type)
void global_context_add_type(Type *type)
{
DEBUG_LOG("Created type %s.", type->name);
assert(type_ok(type));
VECADD(compiler.type, type);
VECADD(global_context.type, type);
}
Module *compiler_find_or_create_module(Path *module_name)
{
Module *module = stable_get(&compiler.modules, module_name->module);
Module *module = stable_get(&global_context.modules, module_name->module);
if (module)
{
@@ -324,7 +324,7 @@ Module *compiler_find_or_create_module(Path *module_name)
module = CALLOCS(Module);
module->name = module_name;
stable_init(&module->symbols, 0x10000);
stable_set(&compiler.modules, module_name->module, module);
stable_set(&global_context.modules, module_name->module, module);
// Now find the possible parent array:
Path *parent_path = path_find_parent_path(NULL, module_name);
if (parent_path)
@@ -339,15 +339,15 @@ Module *compiler_find_or_create_module(Path *module_name)
void compiler_register_public_symbol(Decl *decl)
{
assert(decl->name);
Decl *prev = stable_get(&compiler.global_symbols, decl->name);
Decl *prev = stable_get(&global_context.global_symbols, decl->name);
// If the previous symbol was already declared globally, remove it.
stable_set(&compiler.global_symbols, decl->name, prev ? poisoned_decl : decl);
STable *sub_module_space = stable_get(&compiler.qualified_symbols, decl->module->name->module);
stable_set(&global_context.global_symbols, decl->name, prev ? poisoned_decl : decl);
STable *sub_module_space = stable_get(&global_context.qualified_symbols, decl->module->name->module);
if (!sub_module_space)
{
sub_module_space = malloc_arena(sizeof(*sub_module_space));
stable_init(sub_module_space, 0x100);
stable_set(&compiler.qualified_symbols, decl->module->name->module, sub_module_space);
stable_set(&global_context.qualified_symbols, decl->module->name->module, sub_module_space);
}
prev = stable_get(sub_module_space, decl->name);
stable_set(sub_module_space, decl->name, prev ? poisoned_decl : decl);

View File

@@ -206,6 +206,7 @@ typedef struct
typedef struct
{
struct _FunctionSignature *signature;
const char *mangled_function_signature;
} TypeFunc;
struct _Type
@@ -354,7 +355,6 @@ typedef struct _FunctionSignature
struct ABIArgInfo_ *ret_abi_info;
struct ABIArgInfo_ *failable_abi_info;
Decl** params;
const char *mangled_signature;
} FunctionSignature;
typedef struct
@@ -1287,7 +1287,7 @@ typedef struct
Type **type;
const char *lib_dir;
const char **sources;
} Compiler;
} GlobalContext;
typedef enum
{
@@ -1370,13 +1370,13 @@ typedef struct ABIArgInfo_
{
// We may request a certain alignment of the parameters.
AlignSize realignment;
bool by_val : 1;
Type *by_val_type;
} indirect;
};
} ABIArgInfo;
extern Compiler compiler;
extern GlobalContext global_context;
extern BuildTarget active_target;
extern Ast *poisoned_ast;
extern Decl *poisoned_decl;
@@ -1489,7 +1489,7 @@ void llvm_codegen_setup();
void header_gen(Context *context);
void compiler_add_type(Type *type);
void global_context_add_type(Type *type);
Decl *compiler_find_symbol(const char *name);
Module *compiler_find_or_create_module(Path *module_name);
void compiler_register_public_symbol(Decl *decl);
@@ -1850,7 +1850,7 @@ static inline Type *type_new(TypeKind kind, const char *name)
type->type_kind = kind;
assert(name);
type->name = name;
compiler_add_type(type);
global_context_add_type(type);
return type;
}

View File

@@ -84,26 +84,26 @@ bool abi_arg_is_indirect(ABIArgInfo *info)
UNREACHABLE
}
ABIArgInfo *abi_arg_new_indirect_realigned(unsigned alignment)
ABIArgInfo *abi_arg_new_indirect_realigned(unsigned alignment, Type *by_val_type)
{
assert(alignment > 0);
ABIArgInfo *info = abi_arg_new(ABI_ARG_INDIRECT);
info->indirect.realignment = alignment;
info->indirect.by_val = true;
info->indirect.by_val_type = by_val_type;
return info;
}
ABIArgInfo *abi_arg_new_indirect_by_val(void)
ABIArgInfo *abi_arg_new_indirect_by_val(Type *by_val_type)
{
ABIArgInfo *info = abi_arg_new(ABI_ARG_INDIRECT);
info->indirect.by_val = true;
info->indirect.by_val_type = by_val_type;
return info;
}
ABIArgInfo *abi_arg_new_indirect_not_by_val(void)
{
ABIArgInfo *info = abi_arg_new(ABI_ARG_INDIRECT);
info->indirect.by_val = false;
info->indirect.by_val_type = NULL;
return info;
}
@@ -221,9 +221,9 @@ ABIArgInfo *c_abi_classify_argument_type_default(Type *type)
type = type_lowering(type);
// Struct-likes are returned by sret
if (type_is_abi_aggregate(type)) return abi_arg_new_indirect_by_val();
if (type_is_abi_aggregate(type)) return abi_arg_new_indirect_by_val(type);
if (type_is_int128(type) && !platform_target.int128) return abi_arg_new_indirect_by_val();
if (type_is_int128(type) && !platform_target.int128) return abi_arg_new_indirect_by_val(type);
// Otherwise do we have a type that needs promotion?
if (type_is_promotable_integer(type)) return abi_arg_new_direct_int_ext(type);

View File

@@ -134,7 +134,7 @@ ABIArgInfo *aarch64_classify_return_type(Type *type, bool variadic)
return abi_arg_new_direct_coerce(abi_type_new_int_bits(aligned_size * 8));
}
return abi_arg_new_indirect_by_val();
return abi_arg_new_indirect_by_val(type);
}

View File

@@ -113,16 +113,16 @@ ABIArgInfo *x64_indirect_result(Type *type, unsigned free_int_regs)
if (!free_int_regs)
{
unsigned size = type_size(type);
if (align == 8 && size <= 8)
if (align <= 8 && size <= 8)
{
return abi_arg_new_direct_coerce(abi_type_new_int_bits(size * 8));
}
}
if (align < 8)
{
return abi_arg_new_indirect_realigned(8);
return abi_arg_new_indirect_realigned(8, type);
}
return abi_arg_new_direct();
return abi_arg_new_indirect_by_val(type);
}
@@ -794,7 +794,7 @@ static ABIArgInfo *x64_classify_argument_type(Type *type, unsigned free_int_regs
{
X64Class hi_class;
X64Class lo_class;
x64_classify(type, 0, &lo_class, &hi_class, NAMED);
x64_classify(type, 0, &lo_class, &hi_class, is_named);
// Invariants
assert(hi_class != CLASS_MEMORY || lo_class == CLASS_MEMORY);

View File

@@ -72,10 +72,10 @@ static ABIArgInfo *x86_create_indirect_result(Regs *regs, Type *type, ByVal by_v
// Realign if alignment is greater.
if (alignment > stack_alignment)
{
return abi_arg_new_indirect_realigned(stack_alignment);
return abi_arg_new_indirect_realigned(stack_alignment, type);
}
return abi_arg_new_indirect_by_val();
return abi_arg_new_indirect_by_val(type);
}

View File

@@ -470,7 +470,7 @@ static LLVMMetadataRef llvm_debug_typedef_type(GenContext *c, Type *type)
NULL, 0, NULL, 0);
}
Type *original_type = type->type_kind == TYPE_TYPEDEF ? decl->typedef_decl.type_info->type : decl->distinct_decl.base_type;
Type *original_type = type->type_kind == TYPE_TYPEDEF ? type->canonical : decl->distinct_decl.base_type;
SourceLocation *location = TOKLOC(decl->span.loc);
// Use forward references in case we haven't resolved the original type, since we could have this:

View File

@@ -2790,7 +2790,9 @@ void llvm_emit_call_expr(GenContext *c, BEValue *be_value, Expr *expr)
}
}
// 10. Create the actual call
// 10. Create the actual call (remember to emit a loc, because we might have shifted loc emitting the params)
EMIT_LOC(c, expr);
LLVMValueRef call_value = LLVMBuildCall2(c->builder, func_type, func, values, vec_size(values), "");
// 11. Process the return value.

View File

@@ -507,8 +507,11 @@ static void llvm_emit_param_attributes(GenContext *context, LLVMValueRef functio
else
{
// TODO then type attributes are added to LLVM-C, use that for byval.
if (info->indirect.by_val) llvm_attribute_add(context, function, attribute_byval, index);
llvm_attribute_add(context, function, attribute_noalias, index);
if (info->indirect.by_val_type) llvm_attribute_add(context, function, attribute_byval, index);
if (!info->indirect.realignment)
{
llvm_attribute_add_int(context, function, attribute_align, type_abi_alignment(info->indirect.by_val_type), index);
}
}
break;

View File

@@ -21,6 +21,8 @@
#include <llvm-c/Comdat.h>
#include "dwarf.h"
typedef enum
{
BE_VALUE,
@@ -45,11 +47,6 @@ typedef struct
LLVMBasicBlockRef next_block;
} BreakContinue;
typedef struct
{
unsigned runtime_version : 8;

View File

@@ -65,9 +65,10 @@ void gencontext_begin_module(GenContext *c)
c->block_global_unique_count = 0;
c->ast_alloca_addr_space = target_alloca_addr_space();
VECEACH(compiler.type, i)
VECEACH(global_context.type, i)
{
compiler.type[i]->backend_type = NULL;
global_context.type[i]->backend_type = NULL;
global_context.type[i]->backend_debug_type = NULL;
}
}

View File

@@ -323,11 +323,11 @@ LLVMTypeRef llvm_get_pointee_type(GenContext *c, Type *any_type)
LLVMTypeRef llvm_get_type(GenContext *c, Type *any_type)
{
if (any_type->backend_type && LLVMGetTypeContext(any_type->backend_type) == c->context)
if (any_type->backend_type)
{
assert(LLVMGetTypeContext(any_type->backend_type) == c->context && "Should have been purged");
return any_type->backend_type;
}
DEBUG_LOG("Generating type %s", any_type->name);
switch (any_type->type_kind)
{
case TYPE_POISONED:

View File

@@ -420,15 +420,16 @@ static inline Type *sema_analyse_function_signature(Context *context, FunctionSi
if (!all_ok) return NULL;
TokenType type = TOKEN_INVALID_TOKEN;
signature->mangled_signature = symtab_add(buffer, buffer_write_offset, fnv1a(buffer, buffer_write_offset), &type);
Type *func_type = stable_get(&context->local_symbols, signature->mangled_signature);
const char *mangled_signature = symtab_add(buffer, buffer_write_offset, fnv1a(buffer, buffer_write_offset), &type);
Type *func_type = stable_get(&context->local_symbols, mangled_signature);
c_abi_func_create(signature);
if (!func_type)
{
func_type = type_new(TYPE_FUNC, signature->mangled_signature);
func_type = type_new(TYPE_FUNC, mangled_signature);
func_type->canonical = func_type;
func_type->func.signature = signature;
stable_set(&context->local_symbols, signature->mangled_signature, func_type);
func_type->func.mangled_function_signature = mangled_signature;
stable_set(&context->local_symbols, mangled_signature, func_type);
}
return func_type;

View File

@@ -25,7 +25,7 @@ void sema_analysis_pass_process_imports(Context *context)
Decl *import = context->imports[i];
import->resolve_status = RESOLVE_RUNNING;
Path *path = import->import.path;
Module *module = stable_get(&compiler.modules, path->module);
Module *module = stable_get(&global_context.modules, path->module);
DEBUG_LOG("- Import of %s.", path->module);
if (!module)
{

View File

@@ -122,17 +122,7 @@ const char *type_to_error_string(Type *type)
case TYPE_VIRTUAL:
return type->name;
case TYPE_FUNC:
{
asprintf(&buffer, type->func.signature->failable ? "func %s!(" : "func %s(",
type_to_error_string(type->func.signature->rtype->type));
VECEACH(type->func.signature->params, i)
{
if (i != 0) buffer = strcat_arena(buffer, ", ");
strcat_arena(buffer, type_to_error_string(type->func.signature->params[i]->type));
}
return strcat_arena(buffer, ")");
}
return strcat_arena("func ", type->func.mangled_function_signature);
case TYPE_COMPLEX:
switch (type->complex->type_kind)
{
@@ -1037,6 +1027,7 @@ static void type_create(const char *name, Type *location, TypeKind kind, unsigne
};
location->name = name;
location->canonical = location;
global_context_add_type(location);
}
static void type_create_alias(const char *name, Type *location, Type *canonical)
@@ -1046,6 +1037,7 @@ static void type_create_alias(const char *name, Type *location, Type *canonical)
.name = name,
.canonical = canonical
};
global_context_add_type(location);
}

View File

@@ -23,17 +23,17 @@ func void test1(Func arg)
func void test2(Func arg)
{
ichar b = cast(arg as ichar); // #error: Cannot cast 'Func' (func void()) to 'ichar'.
ichar b = cast(arg as ichar); // #error: Cannot cast 'Func' (func void(int)) to 'ichar'.
}
func void test3(Func arg)
{
uint c = cast(arg as uint); // #error: Cannot cast 'Func' (func void()) to 'uint'.
uint c = cast(arg as uint); // #error: Cannot cast 'Func' (func void(int)) to 'uint'.
}
func void test4(Func arg)
{
float d = cast(arg as float); // #error: Cannot cast 'Func' (func void()) to 'float'.
float d = cast(arg as float); // #error: Cannot cast 'Func' (func void(int)) to 'float'.
}
func void test7(Func arg)
@@ -41,7 +41,7 @@ func void test7(Func arg)
usize g = cast(arg as usize);
FuncOther k = cast(arg as FuncOther);
FuncSame l = cast(arg as FuncSame);
FuncOther ke = arg; // #error: Cannot implicitly cast 'Func' (func void()) to 'FuncOther' (func bool())
FuncOther ke = arg; // #error: Cannot implicitly cast 'Func' (func void(int)) to 'FuncOther' (func bool(char*))
FuncSame fe = arg;
Enum j = cast(arg as Enum); // #error: Cannot cast 'Func' (func void()) to 'Enum'.
Enum j = cast(arg as Enum); // #error: Cannot cast 'Func' (func void(int)) to 'Enum'.
}