From f62a094f7507a5e9fbb1d13be66470fc18ab1e07 Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Tue, 5 May 2020 16:57:11 +0200 Subject: [PATCH] Simple globals now work correctly, but structs don't. --- missing.txt | 5 ++- resources/testfragments/super_simple.c3 | 19 +++++++++++ src/build/build_options.c | 2 +- src/compiler/llvm_codegen.c | 42 +++++++++---------------- src/compiler/llvm_codegen_debug_info.c | 22 +++++++------ src/compiler/llvm_codegen_internal.h | 2 +- src/compiler/llvm_codegen_type.c | 1 + src/compiler/sema_decls.c | 1 + 8 files changed, 51 insertions(+), 43 deletions(-) diff --git a/missing.txt b/missing.txt index 82a492c5e..aefeb1574 100644 --- a/missing.txt +++ b/missing.txt @@ -18,6 +18,7 @@ Things missing: - Vararray initializers - Incremental array initializers - Slice initializers +- Constant initializers for globals * Asserts - assert, $assert @@ -60,13 +61,11 @@ Things missing: * Functions - C ABI - Safe varargs +- Malloc/free * Pre-post conditions - Breakdown here -* Error handling -- Try goto/return/break/continue/throw - * Enum - Values: min, max, array - Functions: fomOrdinal, ordinal, fromName, name, fromFullName, fullName, fromQualifiedName, qualifiedName, (), fromValue() diff --git a/resources/testfragments/super_simple.c3 b/resources/testfragments/super_simple.c3 index 7c39472d2..fb377f1c3 100644 --- a/resources/testfragments/super_simple.c3 +++ b/resources/testfragments/super_simple.c3 @@ -594,9 +594,12 @@ func void testDefault(int x = 2, int y = 100, int z = -100) printf("x = %d, y = %d, z = %d\n", x, y, z); } +int foofei = 3; + func int testReturnDefer() { int i = 0; + foofei++; i++; defer ++i; return i; @@ -651,6 +654,7 @@ func int testThrow6(int x) throws Err, Err2 func int testThrow(int x) throws Err { + throwsDone.times++; if (x < 0) throw Err.TEST_ERR1; return x * x; } @@ -704,16 +708,30 @@ func void throwAOrB(int i) throws Err, Err2 printf("None\n"); } +struct ThrowsDone +{ + long x; + long y; + long z; + int times; +} +ThrowsDone throwsDone; + func void testErrors() { + printf("Throws: %d\n", throwsDone.times); + int x = try testThrow(20) else 1; printf("Value was %d, expected 400.\n", x); + printf("Throws: %d\n", throwsDone.times); x = try testThrow(-1) else 20; printf("Value was %d, expected 20.\n", x); + printf("Throws: %d\n", throwsDone.times); + printf("Begin\n"); int y = try testThrow(-1); @@ -758,6 +776,7 @@ func void testErrors() { printf("Wut\n"); } + printf("Throws: %d\n", throwsDone.times); printf("End of errors\n"); } diff --git a/src/build/build_options.c b/src/build/build_options.c index e4eee10ce..01a2ee023 100644 --- a/src/build/build_options.c +++ b/src/build/build_options.c @@ -315,7 +315,7 @@ void parse_arguments(int argc, const char *argv[]) build_options.emit_bitcode = true; build_options.optimization_level = OPTIMIZATION_NOT_SET; build_options.size_optimization_level = SIZE_OPTIMIZATION_NOT_SET; - build_options.debug_info = DEBUG_INFO_NONE; + build_options.debug_info = DEBUG_INFO_FULL; build_options.debug_mode = false; build_options.command = COMMAND_MISSING; build_options.symtab_size = DEFAULT_SYMTAB_SIZE; diff --git a/src/compiler/llvm_codegen.c b/src/compiler/llvm_codegen.c index 607249aa3..4a3e87cdf 100644 --- a/src/compiler/llvm_codegen.c +++ b/src/compiler/llvm_codegen.c @@ -60,40 +60,22 @@ LLVMValueRef gencontext_emit_memclear(GenContext *context, LLVMValueRef ref, Typ -static LLVMValueRef gencontext_emit_null_constant(GenContext *context, Type *type) -{ - TODO -} -static LLVMValueRef gencontext_emit_initializer(GenContext *context, Expr *expr) -{ - TODO -} - -static void gencontext_emit_global_variable_definition(GenContext *context, Decl *decl, bool is_tentative) +static void gencontext_emit_global_variable_definition(GenContext *context, Decl *decl) { assert(decl->var.kind == VARDECL_GLOBAL); - LLVMValueRef init = NULL; - - if (!decl->var.init_expr) - { - // Tentative definition, initialized to zero, but only - // emitted at the end of the translation unit. - init = gencontext_emit_null_constant(context, decl->type); - } - else - { - init = gencontext_emit_initializer(context, decl->var.init_expr); - } - - - assert(!init); - // TODO fix name decl->var.backend_ref = LLVMAddGlobal(context->module, llvm_type(decl->type), decl->name); - + if (decl->var.init_expr) + { + LLVMSetInitializer(decl->var.backend_ref, gencontext_emit_expr(context, decl->var.init_expr)); + } + else + { + LLVMSetInitializer(decl->var.backend_ref, LLVMConstInt(llvm_type(type_bool), 0, false)); + } // If read only: LLVMSetGlobalConstant(decl->var.backend_ref, 1); switch (decl->visibility) @@ -122,7 +104,7 @@ static void gencontext_emit_global_variable_definition(GenContext *context, Decl 2, context->debug.file, 12 /* lineno */, - decl->type->backend_debug_type, + llvm_debug_type(decl->type), decl->visibility == VISIBLE_LOCAL, /* expr */ NULL, /** declaration **/ @@ -385,6 +367,10 @@ void llvm_codegen(Context *context) { gencontext_emit_error_decl(&gen_context, context->error_types[i]); } + VECEACH(context->vars, i) + { + gencontext_emit_global_variable_definition(&gen_context, context->vars[i]); + } VECEACH(context->functions, i) { Decl *decl = context->functions[i]; diff --git a/src/compiler/llvm_codegen_debug_info.c b/src/compiler/llvm_codegen_debug_info.c index 844462d06..bf769b9fb 100644 --- a/src/compiler/llvm_codegen_debug_info.c +++ b/src/compiler/llvm_codegen_debug_info.c @@ -132,19 +132,21 @@ LLVMMetadataRef gencontext_get_debug_type(GenContext *context, Type *type) case TYPE_POINTER: return type->backend_debug_type = LLVMDIBuilderCreatePointerType(context->debug.builder, type->pointer->backend_debug_type, type_size(type->canonical->pointer), 0, 0, type->name, strlen(type->name)); case TYPE_ENUM: - break; + TODO case TYPE_ERROR: - break; + TODO case TYPE_FUNC: - break; + // TODO + return NULL; case TYPE_STRUCT: - break; +// LLVMDIBuilderCreateStructType(context->debug.builder, NULL, type->decl->name, strlen(type->decl->name), type->decl->module->) + TODO case TYPE_UNION: - break; + TODO case TYPE_TYPEDEF: - break; + TODO case TYPE_STRING: - break; + TODO case TYPE_ARRAY: { LLVMMetadataRef *ranges = NULL; @@ -162,11 +164,11 @@ LLVMMetadataRef gencontext_get_debug_type(GenContext *context, Type *type) ranges, vec_size(ranges)); } case TYPE_VARARRAY: - break; + TODO case TYPE_SUBARRAY: - break; + TODO case TYPE_ERROR_UNION: TODO } - TODO + UNREACHABLE } diff --git a/src/compiler/llvm_codegen_internal.h b/src/compiler/llvm_codegen_internal.h index d4a960988..21f13699f 100644 --- a/src/compiler/llvm_codegen_internal.h +++ b/src/compiler/llvm_codegen_internal.h @@ -220,7 +220,7 @@ static inline LLVMCallConv llvm_call_convention_from_call(CallABI abi) } #define llvm_type(type) gencontext_get_llvm_type(context, type) -#define DEBUG_TYPE(type) gencontext_get_debug_type(context, type) +#define llvm_debug_type(type) gencontext_get_debug_type(context, type) static inline LLVMValueRef gencontext_emit_const_int(GenContext *context, Type *type, uint64_t val) { diff --git a/src/compiler/llvm_codegen_type.c b/src/compiler/llvm_codegen_type.c index 4d8fd94fd..74f6ba492 100644 --- a/src/compiler/llvm_codegen_type.c +++ b/src/compiler/llvm_codegen_type.c @@ -231,6 +231,7 @@ LLVMTypeRef llvm_get_type(LLVMContextRef context, Type *type) LLVMTypeRef gencontext_get_llvm_type(GenContext *context, Type *type) { + // gencontext_get_debug_type(context, type); return llvm_get_type(context->context, type); } diff --git a/src/compiler/sema_decls.c b/src/compiler/sema_decls.c index 33f4e6576..8138a51ed 100644 --- a/src/compiler/sema_decls.c +++ b/src/compiler/sema_decls.c @@ -488,6 +488,7 @@ static inline bool sema_analyse_macro(Context *context, Decl *decl) static inline bool sema_analyse_global(Context *context, Decl *decl) { if (!sema_resolve_type_info(context, decl->var.type_info)) return false; + decl->type = decl->var.type_info->type; if (decl->var.init_expr) { if (!sema_analyse_expr_of_required_type(context, decl->type, decl->var.init_expr)) return false;