From c52629d60fb0d91d9184606d086d54fe89eb73ab Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Thu, 16 Dec 2021 23:31:27 +0100 Subject: [PATCH] Main arguments are now slices if desired. --- src/compiler/ast.c | 1 + src/compiler/compiler_internal.h | 12 ++ src/compiler/copying.c | 1 + src/compiler/enums.h | 1 + src/compiler/llvm_codegen.c | 3 + src/compiler/llvm_codegen_expr.c | 84 +++++++++++ src/compiler/sema_casts.c | 2 + src/compiler/sema_decls.c | 140 +++++++++++++++++- src/compiler/sema_expr.c | 4 + src/compiler/sema_passes.c | 5 + src/compiler/symtab.c | 7 + test/test_suite/abi/regcall_expand.c3t | 7 +- .../bitstruct/array_with_boolean.c3t | 2 +- test/test_suite/bitstruct/bitfield_access.c3t | 2 +- .../bitstruct/bitstruct_access_signed.c3t | 2 +- .../test_suite/bitstruct/bitstruct_arrays.c3t | 2 +- .../test_suite/bitstruct/bitstruct_to_int.c3t | 8 - .../bitstruct/embedded_bitstruct.c3t | 2 +- test/test_suite/compile_time/ct_switch.c3t | 2 +- .../compile_time/ct_switch_type_check.c3t | 2 +- .../compile_time_introspection/defined.c3t | 2 +- .../compile_time_introspection/qnameof.c3t | 2 +- test/test_suite/errors/anyerr_void.c3t | 2 +- test/test_suite/errors/failable_inits.c3t | 2 +- .../errors/failable_taddr_and_access.c3t | 2 +- .../errors/general_error_regression.c3t | 2 +- .../errors/simple_static_failable.c3t | 2 +- test/test_suite/errors/try_assign.c3t | 2 +- .../errors/try_with_chained_unwrap.c3t | 2 +- test/test_suite/errors/try_with_unwrap.c3t | 2 +- test/test_suite/expressions/addr_compiles.c3t | 2 +- test/test_suite/expressions/ternary_bool.c3t | 2 +- test/test_suite/failable_catch.c3t | 7 +- test/test_suite/from_docs/examples_defer.c3t | 4 +- .../from_docs/examples_functionpointer.c3t | 2 +- .../from_docs/examples_if_catch.c3t | 2 +- test/test_suite/functions/test_regression.c3t | 2 +- .../functions/test_regression_mingw.c3t | 2 +- test/test_suite/initializer_lists/fasta.c3t | 14 +- .../test_suite/macros/macro_nested_labels.c3t | 2 +- test/test_suite/macros/macro_with_body.c3t | 2 +- test/test_suite/macros/userland_bitcast.c3t | 2 +- .../methods/enum_distinct_err_methods.c3t | 7 +- test/test_suite/methods/extension_method.c3t | 7 +- .../pointers/array_pointer_decay.c3t | 2 +- .../pointers/subarray_variant_to_ptr.c3t | 2 +- test/test_suite/scoping/general_scoping.c3t | 2 +- test/test_suite/slices/slice_assign.c3t | 21 ++- .../statements/custom_foreach_with_ref.c3t | 2 +- test/test_suite/statements/defer_break.c3t | 47 ++++-- .../statements/defer_break_simple.c3t | 23 +-- test/test_suite/statements/defer_return.c3t | 37 ++--- test/test_suite/statements/fallthough_do.c3t | 2 +- test/test_suite/statements/foreach_custom.c3t | 2 +- .../statements/foreach_custom_macro.c3t | 2 +- test/test_suite/statements/ranged_switch.c3t | 2 +- test/test_suite/statements/simple_do.c3t | 2 +- .../statements/various_switching.c3t | 2 +- test/test_suite/strings/string_escape.c3t | 13 +- test/test_suite/strings/string_to_array.c3t | 7 +- .../test_suite/subarrays/slice_comparison.c3t | 2 +- test/test_suite/variant/variant_test.c3t | 2 +- test/test_suite/vector/vector_bit.c3t | 8 - test/test_suite/vector/vector_incdec.c3t | 3 +- test/test_suite/vector/vector_init.c3t | 2 +- test/test_suite/vector/vector_ops.c3t | 9 -- 66 files changed, 421 insertions(+), 139 deletions(-) diff --git a/src/compiler/ast.c b/src/compiler/ast.c index 791d65a54..072f19590 100644 --- a/src/compiler/ast.c +++ b/src/compiler/ast.c @@ -223,6 +223,7 @@ bool expr_is_pure(Expr *expr) case EXPR_NOP: case EXPR_PTR: return true; + case EXPR_ARGV_TO_SUBARRAY: case EXPR_BITASSIGN: return false; case EXPR_VARIANTSWITCH: diff --git a/src/compiler/compiler_internal.h b/src/compiler/compiler_internal.h index eb29e6fde..ea1accf86 100644 --- a/src/compiler/compiler_internal.h +++ b/src/compiler/compiler_internal.h @@ -936,6 +936,12 @@ typedef struct }; } ExprVariantSwitch; +typedef struct +{ + Decl *argc; + Decl *argv; +} ExprArgv; + struct Expr_ { ExprKind expr_kind : 8; @@ -948,6 +954,7 @@ struct Expr_ ExprCast cast_expr; TypeInfo *type_expr; ExprConst const_expr; + ExprArgv argv_expr; ExprGuard rethrow_expr; Decl *decl_expr; ExprOrError or_error_expr; @@ -1381,6 +1388,7 @@ typedef struct Context_ Decl **types; Decl **generic_defines; Decl **functions; + Decl *main_function; Decl **macros; Decl **generics; Decl **generic_methods; @@ -1609,6 +1617,10 @@ extern const char *kw_builtin_exp; extern const char *kw_builtin_fabs; extern const char *kw_builtin_fma; extern const char *kw_builtin_cmpxchg; +extern const char *kw_argc; +extern const char *kw_argv; +extern const char *kw_mainstub; + #define AST_NEW_TOKEN(_kind, _token) new_ast(_kind, source_span_from_token_id((_token).id)) diff --git a/src/compiler/copying.c b/src/compiler/copying.c index 12cee3922..ec7e45a92 100644 --- a/src/compiler/copying.c +++ b/src/compiler/copying.c @@ -71,6 +71,7 @@ Expr *copy_expr(Expr *source_expr) { case EXPR_MACRO_BODY_EXPANSION: case EXPR_VARIANTSWITCH: + case EXPR_ARGV_TO_SUBARRAY: UNREACHABLE case EXPR_FLATPATH: case EXPR_UNDEF: diff --git a/src/compiler/enums.h b/src/compiler/enums.h index a1fccfb11..ed3d77810 100644 --- a/src/compiler/enums.h +++ b/src/compiler/enums.h @@ -211,6 +211,7 @@ typedef enum EXPR_SLICE_ASSIGN, EXPR_SUBSCRIPT, EXPR_SUBSCRIPT_ADDR, + EXPR_ARGV_TO_SUBARRAY, EXPR_TERNARY, EXPR_TRY, EXPR_TRY_UNWRAP, diff --git a/src/compiler/llvm_codegen.c b/src/compiler/llvm_codegen.c index 00c69e918..f78228344 100644 --- a/src/compiler/llvm_codegen.c +++ b/src/compiler/llvm_codegen.c @@ -1014,6 +1014,7 @@ void *llvm_gen(Module *module) { llvm_emit_function_decl(gen_context, context->functions[i]); } + if (context->main_function) llvm_emit_function_decl(gen_context, context->main_function); } VECEACH(module->contexts, j) @@ -1035,6 +1036,8 @@ void *llvm_gen(Module *module) Decl *decl = context->functions[i]; if (decl->func_decl.body) llvm_emit_function_body(gen_context, decl); } + if (context->main_function) llvm_emit_function_body(gen_context, context->main_function); + VECEACH(context->methods, i) { Decl *decl = context->methods[i]; diff --git a/src/compiler/llvm_codegen_expr.c b/src/compiler/llvm_codegen_expr.c index 3caf80ad4..b24c86f85 100644 --- a/src/compiler/llvm_codegen_expr.c +++ b/src/compiler/llvm_codegen_expr.c @@ -5159,6 +5159,87 @@ void llvm_emit_try_unwrap_chain(GenContext *c, BEValue *value, Expr *expr) } +static inline void llvm_emit_argv_to_subarray(GenContext *c, BEValue *value, Expr *expr) +{ + BEValue argc_value; + BEValue argv_value; + llvm_value_set_decl_address(&argc_value, expr->argv_expr.argc); + llvm_value_set_decl_address(&argv_value, expr->argv_expr.argv); + llvm_value_rvalue(c, &argc_value); + llvm_value_rvalue(c, &argv_value); + LLVMValueRef argv_ptr = argv_value.value; + LLVMValueRef count = argc_value.value; + Type *arg_array_type = type_get_subarray(type_char); + AlignSize alignment = type_alloca_alignment(type_get_array(arg_array_type, 1)); + LLVMTypeRef arg_array_elem_type = llvm_get_type(c, arg_array_type); + LLVMValueRef arg_array = LLVMBuildArrayAlloca(c->builder, arg_array_elem_type, count, "argarray"); + LLVMSetAlignment(arg_array, alignment); + + // Store the addresses. + LLVMTypeRef temp_type = llvm_get_type(c, expr->type); + LLVMTypeRef loop_type = llvm_get_type(c, type_usize); + LLVMTypeRef char_ptr_type = llvm_get_ptr_type(c, type_char); + LLVMValueRef size = llvm_zext_trunc(c, count, loop_type); + LLVMValueRef result = LLVMGetUndef(temp_type); + result = LLVMBuildInsertValue(c->builder, result, size, 1, ""); + result = LLVMBuildInsertValue(c->builder, result, arg_array, 0, ""); + llvm_value_set(value, result, expr->type); + + // Check if zero: + BEValue cond; + llvm_value_set_bool(&cond, LLVMBuildICmp(c->builder, LLVMIntEQ, count, llvm_get_zero(c, argc_value.type), "")); + LLVMBasicBlockRef exit_block = llvm_basic_block_new(c, "exit_loop"); + LLVMBasicBlockRef pre_loop_block = llvm_basic_block_new(c, "pre_loop"); + + // Jump to exit if zero + llvm_emit_cond_br(c, &cond, exit_block, pre_loop_block); + + // Now we create the pre loop block + llvm_emit_block(c, pre_loop_block); + LLVMBasicBlockRef body_block = llvm_basic_block_new(c, "body_loop"); + LLVMValueRef zero = LLVMConstNull(loop_type); + + // Jump to the first entry + llvm_emit_br(c, body_block); + llvm_emit_block(c, body_block); + LLVMValueRef index_var = LLVMBuildPhi(c->builder, loop_type, ""); + + // Find the current substring + LLVMValueRef index = LLVMBuildInBoundsGEP2(c->builder, arg_array_elem_type, arg_array, &index_var, 1, "indexfe"); + LLVMValueRef pointer_to_arg = LLVMBuildInBoundsGEP2(c->builder, char_ptr_type, argv_ptr, &index_var, 1, ""); + + // Get the char* to the argument + LLVMValueRef pointer_value = llvm_emit_load_aligned(c, llvm_get_ptr_type(c, type_char), pointer_to_arg, + type_abi_alignment(type_get_ptr(type_char)), ""); + AlignSize index_align; + + // Get strlen to calculate length + LLVMValueRef strlen = LLVMGetNamedFunction(c->module, "strlen"); + LLVMTypeRef strlen_type = LLVMFunctionType(loop_type, &char_ptr_type, 1, false); + if (!strlen) + { + strlen = LLVMAddFunction(c->module, "strlen", strlen_type); + } + LLVMValueRef len = LLVMBuildCall2(c->builder, strlen_type, strlen, &pointer_value, 1, ""); + + // We first set the pointer + AlignSize align = type_abi_alignment(arg_array_type); + LLVMValueRef ptr_loc = llvm_emit_struct_gep_raw(c, index, arg_array_elem_type, 0, align, &index_align); + llvm_store_aligned(c, ptr_loc, pointer_value, index_align); + // Then the length + LLVMValueRef len_loc = llvm_emit_struct_gep_raw(c, index, arg_array_elem_type, 1, align, &index_align); + llvm_store_aligned(c, len_loc, len, index_align); + + // Add index + LLVMValueRef index_plus = LLVMBuildNUWAdd(c->builder, index_var, llvm_const_int(c, type_usize, 1), ""); + llvm_value_set_bool(&cond, LLVMBuildICmp(c->builder, LLVMIntULT, index_plus, size, "")); + llvm_emit_cond_br(c, &cond, body_block, exit_block); + LLVMValueRef values[2] = { index_plus, zero }; + LLVMBasicBlockRef blocks[2] = { body_block, pre_loop_block }; + LLVMAddIncoming(index_var, values, blocks, 2); + llvm_emit_block(c, exit_block); +} + void llvm_emit_expr(GenContext *c, BEValue *value, Expr *expr) { EMIT_LOC(c, expr); @@ -5176,6 +5257,9 @@ void llvm_emit_expr(GenContext *c, BEValue *value, Expr *expr) case EXPR_FLATPATH: case EXPR_VARIANTSWITCH: UNREACHABLE + case EXPR_ARGV_TO_SUBARRAY: + llvm_emit_argv_to_subarray(c, value, expr); + return; case EXPR_TRY_UNWRAP_CHAIN: llvm_emit_try_unwrap_chain(c, value, expr); return; diff --git a/src/compiler/sema_casts.c b/src/compiler/sema_casts.c index f5eabf179..ab8880f09 100644 --- a/src/compiler/sema_casts.c +++ b/src/compiler/sema_casts.c @@ -810,6 +810,7 @@ Expr *recursive_may_narrow_float(Expr *expr, Type *type) case EXPR_TYPEOFANY: case EXPR_PTR: case EXPR_VARIANTSWITCH: + case EXPR_ARGV_TO_SUBARRAY: UNREACHABLE case EXPR_POST_UNARY: return recursive_may_narrow_float(expr->unary_expr.expr, type); @@ -963,6 +964,7 @@ Expr *recursive_may_narrow_int(Expr *expr, Type *type) case EXPR_SUBSCRIPT_ADDR: case EXPR_TYPEOFANY: case EXPR_PTR: + case EXPR_ARGV_TO_SUBARRAY: case EXPR_VARIANTSWITCH: UNREACHABLE case EXPR_POST_UNARY: diff --git a/src/compiler/sema_decls.c b/src/compiler/sema_decls.c index f1538e997..764ee4801 100644 --- a/src/compiler/sema_decls.c +++ b/src/compiler/sema_decls.c @@ -1270,6 +1270,139 @@ static inline bool sema_update_call_convention(Decl *decl, CallABI abi) return had; } +static inline bool sema_analyse_main_function(Context *context, Decl *decl) +{ + if (decl == context->main_function) return true; + + if (decl->visibility == VISIBLE_LOCAL) + { + SEMA_ERROR(decl, "A main function may not have local visibility."); + return false; + } + FunctionSignature *signature = &decl->func_decl.function_signature; + Type *rtype = type_flatten_distinct(signature->rtype->type); + bool is_int_return = true; + bool is_err_return = false; + if (rtype->type_kind == TYPE_FAILABLE_ANY) is_err_return = true; + if (!is_err_return && type_is_failable(rtype)) + { + if (rtype->failable->type_kind != TYPE_VOID) + { + SEMA_ERROR(signature->rtype, "The return type of 'main' cannot be a failable, unless it is 'void!'."); + return false; + } + is_int_return = false; + is_err_return = true; + } + if (rtype->type_kind == TYPE_VOID) is_int_return = false; + + if (type_is_integer(rtype) && rtype != type_cint()) + { + SEMA_ERROR(signature->rtype, "Expected a return type of 'void' or %s.", type_quoted_error_string(type_cint())); + return false; + } + // At this point the style is either MAIN_INT_VOID, MAIN_VOID_VOID or MAIN_ERR_VOID + Decl **params = signature->params; + unsigned param_count = vec_size(params); + bool subarray_param = false; + bool cparam = false; + switch (param_count) + { + case 0: + // This is the default style already set + break; + case 1: + if (type_flatten_distinct(params[0]->type) != type_get_subarray(type_get_subarray(type_char))) + { + SEMA_ERROR(params[0], "Expected a parameter of type 'char[][]'"); + return false; + } + subarray_param = true; + break; + case 2: + if (type_flatten_distinct(params[0]->type) != type_cint()) + { + SEMA_ERROR(params[0], "Expected a parameter of type %s for a C-style main.", type_quoted_error_string(type_cint())); + return false; + } + if (type_flatten_distinct(params[1]->type) != type_get_ptr(type_get_ptr(type_char))) + { + SEMA_ERROR(params[1], "Expected a parameter of type 'char**' for a C-style main."); + return false; + } + cparam = true; + break; + default: + SEMA_ERROR(params[0], "Expected zero, 1 or 2 parameters for main."); + return false; + } + if (!subarray_param && is_int_return) + { + // Int return is pass-through at the moment. + decl->visibility = VISIBLE_EXTERN; + return true; + } + Decl *function = decl_new(DECL_FUNC, decl->name_token, VISIBLE_EXTERN); + function->name = kw_mainstub; + function->extname = kw_main; + function->func_decl.function_signature.rtype = type_info_new_base(type_cint(), decl->span); + Decl *param1 = decl_new_generated_var(kw_argv, type_cint(), VARDECL_PARAM, decl->span); + Decl *param2 = decl_new_generated_var(kw_argc, type_get_ptr(type_get_ptr(type_char)), VARDECL_PARAM, decl->span); + Decl **main_params = NULL; + vec_add(main_params, param1); + vec_add(main_params, param2); + function->func_decl.function_signature.params = main_params; + Ast *body = new_ast(AST_COMPOUND_STMT, decl->span); + Ast *ret_stmt = new_ast(AST_RETURN_STMT, decl->span); + Expr *call = expr_new(EXPR_CALL, decl->span); + call->call_expr.function = expr_variable(decl); + if (subarray_param) + { + Expr *subarray = expr_new(EXPR_ARGV_TO_SUBARRAY, decl->span); + subarray->argv_expr.argc = param1; + subarray->argv_expr.argv = param2; + vec_add(call->call_expr.arguments, subarray); + } + else if (cparam) + { + vec_add(call->call_expr.arguments, expr_variable(param1)); + vec_add(call->call_expr.arguments, expr_variable(param2)); + } + // Unresolve them or the params cannot be resolved later. + param1->resolve_status = RESOLVE_NOT_DONE; + param2->resolve_status = RESOLVE_NOT_DONE; + if (is_int_return) + { + ret_stmt->return_stmt.expr = call; + } + else if (is_err_return) + { + Expr *try_expr = expr_new(EXPR_TRY, decl->span); + try_expr->inner_expr = call; + Expr *not_expr = expr_new(EXPR_UNARY, decl->span); + not_expr->unary_expr.expr = try_expr; + not_expr->unary_expr.operator = UNARYOP_NOT; + Expr *cast_expr = expr_new(EXPR_CAST, decl->span); + cast_expr->cast_expr.expr = not_expr; + cast_expr->cast_expr.type_info = type_info_new_base(type_cint(), decl->span); + ret_stmt->return_stmt.expr = cast_expr; + } + else + { + Ast *stmt = new_ast(AST_EXPR_STMT, decl->span); + stmt->expr_stmt = call; + vec_add(body->compound_stmt.stmts, stmt); + Expr *c = expr_new(EXPR_CONST, decl->span); + c->type = type_cint(); + expr_const_set_int(&c->const_expr, 0, c->type->type_kind); + c->resolve_status = RESOLVE_DONE; + ret_stmt->expr_stmt = c; + } + vec_add(body->compound_stmt.stmts, ret_stmt); + function->func_decl.body = body; + context->main_function = function; + return true; +} static inline bool sema_analyse_func(Context *context, Decl *decl) { DEBUG_LOG("----Analysing function %s", decl->name); @@ -1375,12 +1508,7 @@ static inline bool sema_analyse_func(Context *context, Decl *decl) { if (decl->name == kw_main) { - if (decl->visibility == VISIBLE_LOCAL) - { - SEMA_ERROR(decl, "'main' cannot have local visibility."); - return false; - } - decl->visibility = VISIBLE_EXTERN; + if (!sema_analyse_main_function(context, decl)) return decl_poison(decl); } decl_set_external_name(decl); } diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index f72c824da..b2d279304 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -452,6 +452,7 @@ bool expr_is_constant_eval(Expr *expr, ConstantEvalKind eval_kind) case EXPR_MACRO_EXPANSION: case EXPR_PLACEHOLDER: case EXPR_POISONED: + case EXPR_ARGV_TO_SUBARRAY: UNREACHABLE case EXPR_NOP: return true; @@ -6730,6 +6731,9 @@ static inline bool sema_analyse_expr_dispatch(Context *context, Expr *expr) case EXPR_PTR: case EXPR_VARIANTSWITCH: UNREACHABLE + case EXPR_ARGV_TO_SUBARRAY: + expr->type = type_get_subarray(type_get_subarray(type_char)); + return true; case EXPR_DECL: if (!sema_analyse_var_decl(context, expr->decl_expr, true)) return false; expr->type = expr->decl_expr->type; diff --git a/src/compiler/sema_passes.c b/src/compiler/sema_passes.c index 1d3b58493..a04871d51 100644 --- a/src/compiler/sema_passes.c +++ b/src/compiler/sema_passes.c @@ -224,6 +224,10 @@ void sema_analysis_pass_decls(Module *module) { sema_analyse_decl(context, context->functions[i]); } + if (context->main_function) + { + sema_analyse_decl(context, context->main_function); + } VECEACH(context->generic_defines, i) { sema_analyse_decl(context, context->generic_defines[i]); @@ -247,6 +251,7 @@ void sema_analysis_pass_functions(Module *module) { analyse_func_body(context, context->functions[i]); } + if (context->main_function) analyse_func_body(context, context->main_function); } diff --git a/src/compiler/symtab.c b/src/compiler/symtab.c index e1d982d95..ebf1b0984 100644 --- a/src/compiler/symtab.c +++ b/src/compiler/symtab.c @@ -88,6 +88,9 @@ const char *kw_builtin_exp; const char *kw_builtin_fabs; const char *kw_builtin_fma; const char *kw_builtin_cmpxchg; +const char *kw_argc; +const char *kw_argv; +const char *kw_mainstub;; void symtab_init(uint32_t capacity) { @@ -153,6 +156,10 @@ void symtab_init(uint32_t capacity) kw_default_iterator = KW_DEF("default_iterator"); kw_check_assign = KW_DEF("check_assign"); + kw_argc = KW_DEF("_$argc"); + kw_argv = KW_DEF("_$argv"); + kw_mainstub = KW_DEF("_$mainstub"); + builtin_list[BUILTIN_CEIL] = KW_DEF("ceil"); builtin_list[BUILTIN_TRUNC] = KW_DEF("trunc"); builtin_list[BUILTIN_SIN] = KW_DEF("sin"); diff --git a/test/test_suite/abi/regcall_expand.c3t b/test/test_suite/abi/regcall_expand.c3t index 0f45bcadf..7f5f63764 100644 --- a/test/test_suite/abi/regcall_expand.c3t +++ b/test/test_suite/abi/regcall_expand.c3t @@ -11,9 +11,10 @@ fn void test(Foo x) @regcall { } -fn void main() +fn int main() { test(Foo { }); + return 0; } /* #expect: test.ll @@ -38,7 +39,7 @@ entry: } ; Function Attrs: nounwind -define void @main() #0 { +define i32 @main() #0 { entry: %literal = alloca %Foo, align 4 %0 = getelementptr inbounds %Foo, %Foo* %literal, i32 0, i32 0 @@ -52,5 +53,5 @@ entry: %5 = getelementptr inbounds [2 x float], [2 x float]* %3, i64 0, i64 1 %loadexpanded1 = load float, float* %5, align 4 call x86_regcallcc void @test.test(float %loadexpanded, float %loadexpanded1) - ret void + ret i32 0 } diff --git a/test/test_suite/bitstruct/array_with_boolean.c3t b/test/test_suite/bitstruct/array_with_boolean.c3t index 4e05a0ebd..71730664d 100644 --- a/test/test_suite/bitstruct/array_with_boolean.c3t +++ b/test/test_suite/bitstruct/array_with_boolean.c3t @@ -23,7 +23,7 @@ fn void main() /* #expect: foo.ll -define void @main() #0 { +define void @foo.main() #0 { entry: %xx = alloca [3 x i8], align 1 %xy = alloca [3 x i8], align 1 diff --git a/test/test_suite/bitstruct/bitfield_access.c3t b/test/test_suite/bitstruct/bitfield_access.c3t index 27e0544b5..39ab1199c 100644 --- a/test/test_suite/bitstruct/bitfield_access.c3t +++ b/test/test_suite/bitstruct/bitfield_access.c3t @@ -93,7 +93,7 @@ fn void main() /* #expect: foo.ll -define void @main() #0 { +define void @foo.main() #0 { entry: %b = alloca i8, align 1 %c1 = alloca i16, align 2 diff --git a/test/test_suite/bitstruct/bitstruct_access_signed.c3t b/test/test_suite/bitstruct/bitstruct_access_signed.c3t index ae8a0bafe..0b7a7f054 100644 --- a/test/test_suite/bitstruct/bitstruct_access_signed.c3t +++ b/test/test_suite/bitstruct/bitstruct_access_signed.c3t @@ -30,7 +30,7 @@ fn void main() /* #expect: foo.ll -define void @main() #0 { +define void @foo.main() #0 { entry: %xx = alloca [3 x i8], align 1 %xxu = alloca [3 x i8], align 1 diff --git a/test/test_suite/bitstruct/bitstruct_arrays.c3t b/test/test_suite/bitstruct/bitstruct_arrays.c3t index 01a7b2753..85284a673 100644 --- a/test/test_suite/bitstruct/bitstruct_arrays.c3t +++ b/test/test_suite/bitstruct/bitstruct_arrays.c3t @@ -122,7 +122,7 @@ fn void test3() /* #expect: foo.ll -define void @main() #0 { +define void @foo.main() #0 { entry: call void @foo.test1() call void @foo.test2() diff --git a/test/test_suite/bitstruct/bitstruct_to_int.c3t b/test/test_suite/bitstruct/bitstruct_to_int.c3t index f9a801f1c..14f75a442 100644 --- a/test/test_suite/bitstruct/bitstruct_to_int.c3t +++ b/test/test_suite/bitstruct/bitstruct_to_int.c3t @@ -107,11 +107,3 @@ entry: store [4 x i8]* %12, [4 x i8]** %y2, align 8 ret void } - -; Function Attrs: nounwind -define void @main() #0 { -entry: - call void @foo.test() - call void @foo.test2() - ret void -} \ No newline at end of file diff --git a/test/test_suite/bitstruct/embedded_bitstruct.c3t b/test/test_suite/bitstruct/embedded_bitstruct.c3t index 59d7b3954..29e5fe010 100644 --- a/test/test_suite/bitstruct/embedded_bitstruct.c3t +++ b/test/test_suite/bitstruct/embedded_bitstruct.c3t @@ -46,7 +46,7 @@ fn void main() /* #expect: foo.ll -define void @main() #0 { +define void @foo.main() #0 { entry: %b = alloca %Bar, align 4 %f = alloca %Foo, align 4 diff --git a/test/test_suite/compile_time/ct_switch.c3t b/test/test_suite/compile_time/ct_switch.c3t index 449a3d30b..0b2f1b096 100644 --- a/test/test_suite/compile_time/ct_switch.c3t +++ b/test/test_suite/compile_time/ct_switch.c3t @@ -52,7 +52,7 @@ fn void main() ; Function Attrs: nounwind declare void @printf(i8*, ...) #0 ; Function Attrs: nounwind -define void @main() #0 { +define void @test.main() #0 { entry: call void (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), [5 x i8]* bitcast ([6 x i8]* @.str.1 to [5 x i8]*)) call void (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.2, i32 0, i32 0), [9 x i8]* bitcast ([10 x i8]* @.str.3 to [9 x i8]*)) diff --git a/test/test_suite/compile_time/ct_switch_type_check.c3t b/test/test_suite/compile_time/ct_switch_type_check.c3t index e20f06348..55bccbe95 100644 --- a/test/test_suite/compile_time/ct_switch_type_check.c3t +++ b/test/test_suite/compile_time/ct_switch_type_check.c3t @@ -35,7 +35,7 @@ fn void main() ; Function Attrs: nounwind declare void @printf(i8*, ...) #0 ; Function Attrs: nounwind -define void @main() #0 { +define void @test.main() #0 { entry: call void (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), [3 x i8]* bitcast ([4 x i8]* @.str.1 to [3 x i8]*)) call void (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.2, i32 0, i32 0), [6 x i8]* bitcast ([7 x i8]* @.str.3 to [6 x i8]*)) diff --git a/test/test_suite/compile_time_introspection/defined.c3t b/test/test_suite/compile_time_introspection/defined.c3t index fda07d901..1bb88877f 100644 --- a/test/test_suite/compile_time_introspection/defined.c3t +++ b/test/test_suite/compile_time_introspection/defined.c3t @@ -61,7 +61,7 @@ fn void main() // #expect: mymodule.ll -define void @main() #0 { +define void @mymodule.main() #0 { entry: %x = alloca i32, align 4 %y = alloca i32, align 4 diff --git a/test/test_suite/compile_time_introspection/qnameof.c3t b/test/test_suite/compile_time_introspection/qnameof.c3t index 58058569f..c669e6496 100644 --- a/test/test_suite/compile_time_introspection/qnameof.c3t +++ b/test/test_suite/compile_time_introspection/qnameof.c3t @@ -40,7 +40,7 @@ fn void main() @.str.16 = private constant [15 x i8] c"Blob**[3]: %s\0A\00", align 1 @.str.17 = private constant [10 x i8] c"Blob**[3]\00", align 1 -define void @main() +define void @qnametest.main() %help = alloca i32, align 4 store i32 0, i32* %help, align 4 %0 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([12 x i8], [12 x i8]* @.str, i32 0, i32 0), [6 x i8]* bitcast ([7 x i8]* @.str.1 to [6 x i8]*)) diff --git a/test/test_suite/errors/anyerr_void.c3t b/test/test_suite/errors/anyerr_void.c3t index 3b5396e19..3b4916078 100644 --- a/test/test_suite/errors/anyerr_void.c3t +++ b/test/test_suite/errors/anyerr_void.c3t @@ -52,7 +52,7 @@ entry: declare void @printf(i8*, ...) #0 ; Function Attrs: nounwind -define void @main() #0 { +define void @anyerr_void.main() #0 { entry: %z = alloca i64, align 8 %error_var = alloca i64, align 8 diff --git a/test/test_suite/errors/failable_inits.c3t b/test/test_suite/errors/failable_inits.c3t index 7e2800ecb..cf065855b 100644 --- a/test/test_suite/errors/failable_inits.c3t +++ b/test/test_suite/errors/failable_inits.c3t @@ -94,7 +94,7 @@ noerr_block: ; preds = %after_check } ; Function Attrs: nounwind -define void @main() #0 { +define void @test.main() #0 { entry: %0 = call i64 @test.test1() %not_err = icmp eq i64 %0, 0 diff --git a/test/test_suite/errors/failable_taddr_and_access.c3t b/test/test_suite/errors/failable_taddr_and_access.c3t index dd6920e26..486cb67f5 100644 --- a/test/test_suite/errors/failable_taddr_and_access.c3t +++ b/test/test_suite/errors/failable_taddr_and_access.c3t @@ -37,7 +37,7 @@ fn void main() declare i32 @printf(i8*, ...) #0 ; Function Attrs: nounwind -define void @main() #0 { +define void @test.main() #0 { entry: %z = alloca i32, align 4 %z.f = alloca i64, align 8 diff --git a/test/test_suite/errors/general_error_regression.c3t b/test/test_suite/errors/general_error_regression.c3t index b6927d9bd..42c7942fc 100644 --- a/test/test_suite/errors/general_error_regression.c3t +++ b/test/test_suite/errors/general_error_regression.c3t @@ -95,7 +95,7 @@ entry: ret void } -define void @main() #0 { +define void @foo.main() #0 { entry: %f = alloca i64, align 8 %ef = alloca i64, align 8 diff --git a/test/test_suite/errors/simple_static_failable.c3t b/test/test_suite/errors/simple_static_failable.c3t index 373ce2e0d..6d3cf7c3b 100644 --- a/test/test_suite/errors/simple_static_failable.c3t +++ b/test/test_suite/errors/simple_static_failable.c3t @@ -15,7 +15,7 @@ fn void main() // #expect: foo.ll -define void @main() #0 { +define void @foo.main() #0 { entry: %i = alloca i32, align 4 %i.f = alloca i64, align 8 diff --git a/test/test_suite/errors/try_assign.c3t b/test/test_suite/errors/try_assign.c3t index 262a81b29..711b6f629 100644 --- a/test/test_suite/errors/try_assign.c3t +++ b/test/test_suite/errors/try_assign.c3t @@ -27,7 +27,7 @@ fn void main() // #expect: try_assign.ll -define void @main() #0 { +define void @try_assign.main() #0 { entry: %x = alloca i32, align 4 %z = alloca i32, align 4 diff --git a/test/test_suite/errors/try_with_chained_unwrap.c3t b/test/test_suite/errors/try_with_chained_unwrap.c3t index adc67dfea..b8e886ac3 100644 --- a/test/test_suite/errors/try_with_chained_unwrap.c3t +++ b/test/test_suite/errors/try_with_chained_unwrap.c3t @@ -18,7 +18,7 @@ fn void main() // #expect: try_with_chained_unwrap.ll -define void @main() #0 { +define void @try_with_chained_unwrap.main() #0 { entry: %val = alloca i32, align 4 %retparam = alloca i32, align 4 diff --git a/test/test_suite/errors/try_with_unwrap.c3t b/test/test_suite/errors/try_with_unwrap.c3t index d2133805d..d7a448258 100644 --- a/test/test_suite/errors/try_with_unwrap.c3t +++ b/test/test_suite/errors/try_with_unwrap.c3t @@ -21,7 +21,7 @@ fn void main() // #expect: try_with_unwrap.ll - define void @main() #0 { + define void @try_with_unwrap.main() #0 { entry: %line = alloca i8*, align 8 %line.f = alloca i64, align 8 diff --git a/test/test_suite/expressions/addr_compiles.c3t b/test/test_suite/expressions/addr_compiles.c3t index 454122aaa..ec96331ca 100644 --- a/test/test_suite/expressions/addr_compiles.c3t +++ b/test/test_suite/expressions/addr_compiles.c3t @@ -49,7 +49,7 @@ fn void test3() /* #expect: test.ll -define void @main() #0 { +define void @test.main() #0 { entry: call void @test.test() call void @test.test2() diff --git a/test/test_suite/expressions/ternary_bool.c3t b/test/test_suite/expressions/ternary_bool.c3t index efe97999a..c66c6b693 100644 --- a/test/test_suite/expressions/ternary_bool.c3t +++ b/test/test_suite/expressions/ternary_bool.c3t @@ -15,7 +15,7 @@ fn void main() // #expect: ternary_bool.ll -define void @main() #0 { +define void @ternary_bool.main() #0 { entry: %b = alloca i8, align 1 %c = alloca i8*, align 8 diff --git a/test/test_suite/failable_catch.c3t b/test/test_suite/failable_catch.c3t index 2e952e951..ba258ede6 100644 --- a/test/test_suite/failable_catch.c3t +++ b/test/test_suite/failable_catch.c3t @@ -13,7 +13,7 @@ macro foo(int x) extern fn void printf(char*, ...); -fn void main() +fn int main() { int! a = @foo(1); @@ -25,11 +25,12 @@ fn void main() if (catch(c)) printf("c had error\n"); c = 3; printf("c = %d\n", c); + return 0; } // #expect: failable_catch.ll -define void @main() #0 { +define i32 @main() #0 { entry: %a = alloca i32, align 4 %a.f = alloca i64, align 8 @@ -171,5 +172,5 @@ entry: br label %voiderr27 voiderr27: ; preds = %after_check26, %if.exit24 - ret void + ret i32 0 } diff --git a/test/test_suite/from_docs/examples_defer.c3t b/test/test_suite/from_docs/examples_defer.c3t index d0adc8762..ab16b1a91 100644 --- a/test/test_suite/from_docs/examples_defer.c3t +++ b/test/test_suite/from_docs/examples_defer.c3t @@ -80,10 +80,10 @@ exit10: ; preds = %exit9 } ; Function Attrs: nounwind -define void @main() #0 { +define void @defer1.main() #0 { entry: call void @defer1.test(i32 1) call void @defer1.test(i32 0) call void @defer1.test(i32 10) ret void -} \ No newline at end of file +} diff --git a/test/test_suite/from_docs/examples_functionpointer.c3t b/test/test_suite/from_docs/examples_functionpointer.c3t index 0a5a74b8f..44272343a 100644 --- a/test/test_suite/from_docs/examples_functionpointer.c3t +++ b/test/test_suite/from_docs/examples_functionpointer.c3t @@ -27,7 +27,7 @@ entry: ret i32 0 } -define void @main() #0 { +define void @demo.main() #0 { entry: %result = alloca i32, align 4 %0 = load i32 (i8*, i32)*, i32 (i8*, i32)** @demo.cb, align 8 diff --git a/test/test_suite/from_docs/examples_if_catch.c3t b/test/test_suite/from_docs/examples_if_catch.c3t index ae3eed530..2c04d4e30 100644 --- a/test/test_suite/from_docs/examples_if_catch.c3t +++ b/test/test_suite/from_docs/examples_if_catch.c3t @@ -105,7 +105,7 @@ noerr_block: ; preds = %after.errcheck ret i64 0 } -define void @main() #0 { +define void @demo.main() #0 { entry: %ratio = alloca double, align 8 %ratio.f = alloca i64, align 8 diff --git a/test/test_suite/functions/test_regression.c3t b/test/test_suite/functions/test_regression.c3t index 90585871c..ac5f873b1 100644 --- a/test/test_suite/functions/test_regression.c3t +++ b/test/test_suite/functions/test_regression.c3t @@ -439,7 +439,7 @@ loop.exit: ; preds = %loop.cond } ; Function Attrs: nounwind -define void @main() #0 { +define void @test.main() #0 { entry: %list = alloca %LinkedList, align 8 %i = alloca i32, align 4 diff --git a/test/test_suite/functions/test_regression_mingw.c3t b/test/test_suite/functions/test_regression_mingw.c3t index 25f30d39c..c8e45800e 100644 --- a/test/test_suite/functions/test_regression_mingw.c3t +++ b/test/test_suite/functions/test_regression_mingw.c3t @@ -495,7 +495,7 @@ loop.exit: ; preds = %loop.cond } ; Function Attrs: nounwind -define void @main() #0 { +define void @test.main() #0 { entry: %list = alloca %LinkedList, align 8 %i = alloca i32, align 4 diff --git a/test/test_suite/initializer_lists/fasta.c3t b/test/test_suite/initializer_lists/fasta.c3t index ce651a91a..c785af137 100644 --- a/test/test_suite/initializer_lists/fasta.c3t +++ b/test/test_suite/initializer_lists/fasta.c3t @@ -338,7 +338,7 @@ if.exit15: ; preds = %if.then14, %loop.ex } ; Function Attrs: nounwind -define void @main(i32 %0, i8** %1) #0 { +define void @fasta.main(i32 %0, i8** %1) #0 { entry: %argc = alloca i32, align 4 %argv = alloca i8**, align 8 @@ -383,3 +383,15 @@ if.exit: ; preds = %if.then, %entry call void @fasta.random_fasta(i8* %lo6, i64 %hi7, i8* %lo8, i64 %hi9, i32 %mul10) ret void } + +define i32 @main(i32 %0, i8** %1) #0 { +entry: + %"_$argv" = alloca i32, align 4 + %"_$argc" = alloca i8**, align 8 + store i32 %0, i32* %"_$argv", align 4 + store i8** %1, i8*** %"_$argc", align 8 + %2 = load i32, i32* %"_$argv", align 4 + %3 = load i8**, i8*** %"_$argc", align 8 + call void @fasta.main(i32 %2, i8** %3) + ret i32 0 +} \ No newline at end of file diff --git a/test/test_suite/macros/macro_nested_labels.c3t b/test/test_suite/macros/macro_nested_labels.c3t index f0f1355bc..f8a8b4794 100644 --- a/test/test_suite/macros/macro_nested_labels.c3t +++ b/test/test_suite/macros/macro_nested_labels.c3t @@ -28,7 +28,7 @@ fn void main() /* #expect: test.ll -define void @main() #0 { +define void @test.main() #0 { entry: %ab = alloca i32, align 4 %x = alloca i32, align 4 diff --git a/test/test_suite/macros/macro_with_body.c3t b/test/test_suite/macros/macro_with_body.c3t index 5767d802e..cc39729ff 100644 --- a/test/test_suite/macros/macro_with_body.c3t +++ b/test/test_suite/macros/macro_with_body.c3t @@ -60,7 +60,7 @@ entry: ret i32 %mul } -define void @main() #0 { +define void @withbody.main() #0 { entry: %f = alloca %Foo, align 4 %y = alloca i32, align 4 diff --git a/test/test_suite/macros/userland_bitcast.c3t b/test/test_suite/macros/userland_bitcast.c3t index 92b7945e0..f26d9ee80 100644 --- a/test/test_suite/macros/userland_bitcast.c3t +++ b/test/test_suite/macros/userland_bitcast.c3t @@ -186,7 +186,7 @@ loop.exit: ; preds = %loop.cond } ; Function Attrs: nounwind -define void @main() #0 { +define void @userland_bitcast.main() #0 { entry: %f = alloca float, align 4 %i = alloca i32, align 4 diff --git a/test/test_suite/methods/enum_distinct_err_methods.c3t b/test/test_suite/methods/enum_distinct_err_methods.c3t index 15176704e..5a0cf22c6 100644 --- a/test/test_suite/methods/enum_distinct_err_methods.c3t +++ b/test/test_suite/methods/enum_distinct_err_methods.c3t @@ -30,7 +30,7 @@ fn void MyEnum.hello(MyEnum *myenum) { io::println("Hello from MyEnum"); } -fn void main() +fn int main() { Foo f; Bar b; @@ -38,6 +38,7 @@ fn void main() f.hello(); b.hello(); a.hello(); + return 0; } // #expect: foo.ll @@ -60,7 +61,7 @@ define void @foo.MyEnum__hello(i32* %0) %1 = call i32 @"std::io.println"(i8* getelementptr inbounds ([18 x i8], [18 x i8]* @.str.2, i32 0, i32 0)) ret void -define void @main() +define i32 @main() entry: %f = alloca i64, align 8 %b = alloca i32, align 4 @@ -71,4 +72,4 @@ entry: call void @foo.Foo__hello(i64* %f) call void @foo.Bar__hello(i32* %b) call void @foo.MyEnum__hello(i32* %a) - ret void + ret i32 0 diff --git a/test/test_suite/methods/extension_method.c3t b/test/test_suite/methods/extension_method.c3t index 2b1281421..84994d510 100644 --- a/test/test_suite/methods/extension_method.c3t +++ b/test/test_suite/methods/extension_method.c3t @@ -18,20 +18,21 @@ module abc; import foo; import baz; -fn void main() +fn int main() { Bar bar; bar.test(); + return 0; } // #expect: abc.ll declare void @foo.Bar__test(%Bar*) -define void @main() +define i32 @main() entry: %bar = alloca %Bar, align 4 %0 = bitcast %Bar* %bar to i32* store i32 0, i32* %0, align 4 call void @foo.Bar__test(%Bar* %bar) - ret void + ret i32 0 diff --git a/test/test_suite/pointers/array_pointer_decay.c3t b/test/test_suite/pointers/array_pointer_decay.c3t index adae1464c..a7db7da96 100644 --- a/test/test_suite/pointers/array_pointer_decay.c3t +++ b/test/test_suite/pointers/array_pointer_decay.c3t @@ -20,7 +20,7 @@ fn void main() /* #expect: foo.ll -define void @main() #0 { +define void @foo.main() #0 { entry: %x = alloca [3 x i32], align 4 %y = alloca [3 x i32]*, align 8 diff --git a/test/test_suite/pointers/subarray_variant_to_ptr.c3t b/test/test_suite/pointers/subarray_variant_to_ptr.c3t index c9ffadff9..5ff4d043b 100644 --- a/test/test_suite/pointers/subarray_variant_to_ptr.c3t +++ b/test/test_suite/pointers/subarray_variant_to_ptr.c3t @@ -63,7 +63,7 @@ entry: ret void } -define void @main() #0 { +define void @foo.main() #0 { entry: %x = alloca i32, align 4 %y = alloca i32, align 4 diff --git a/test/test_suite/scoping/general_scoping.c3t b/test/test_suite/scoping/general_scoping.c3t index a56d736fc..70a53a8a6 100644 --- a/test/test_suite/scoping/general_scoping.c3t +++ b/test/test_suite/scoping/general_scoping.c3t @@ -39,7 +39,7 @@ fn void main() declare void @printf(i8*, ...) #0 ; Function Attrs: nounwind -define void @main() #0 { +define void @test.main() #0 { entry: %y = alloca i32, align 4 %x = alloca i32, align 4 diff --git a/test/test_suite/slices/slice_assign.c3t b/test/test_suite/slices/slice_assign.c3t index 0ac292681..037d565d1 100644 --- a/test/test_suite/slices/slice_assign.c3t +++ b/test/test_suite/slices/slice_assign.c3t @@ -19,10 +19,10 @@ fn void main() /* #expect: test.ll @.str = private constant [4 x i8] c"%d\0A\00", align 1 -; Function Attrs: nounwind + declare void @printf(i8*, ...) #0 -; Function Attrs: nounwind -define void @main() #0 { + +define void @test.main() #0 { entry: %x = alloca [8 x i32], align 16 %"__idx$" = alloca i64, align 8 @@ -50,6 +50,7 @@ loop.cond: ; preds = %loop.body, %entry %8 = load i64, i64* %"__idx$", align 8 %gt = icmp ugt i64 8, %8 br i1 %gt, label %loop.body, label %loop.exit + loop.body: ; preds = %loop.cond %9 = load i64, i64* %"__idx$", align 8 %10 = getelementptr inbounds [8 x i32], [8 x i32]* %x, i64 0, i64 %9 @@ -61,17 +62,31 @@ loop.body: ; preds = %loop.cond %add = add i64 %13, 1 store i64 %add, i64* %"__idx$", align 8 br label %loop.cond + loop.exit: ; preds = %loop.cond br label %cond + cond: ; preds = %assign, %loop.exit %14 = phi i64 [ 0, %loop.exit ], [ %add1, %assign ] %le = icmp sle i64 %14, 7 br i1 %le, label %assign, label %exit + assign: ; preds = %cond %15 = getelementptr inbounds [8 x i32], [8 x i32]* %x, i64 0, i64 %14 store i32 123, i32* %15, align 4 %add1 = add i64 %14, 1 br label %cond + exit: ; preds = %cond ret void } + +define i32 @main(i32 %0, i8** %1) #0 { +entry: + %"_$argv" = alloca i32, align 4 + %"_$argc" = alloca i8**, align 8 + store i32 %0, i32* %"_$argv", align 4 + store i8** %1, i8*** %"_$argc", align 8 + call void @test.main() + ret i32 0 +} diff --git a/test/test_suite/statements/custom_foreach_with_ref.c3t b/test/test_suite/statements/custom_foreach_with_ref.c3t index b769e78c6..8fb3def29 100644 --- a/test/test_suite/statements/custom_foreach_with_ref.c3t +++ b/test/test_suite/statements/custom_foreach_with_ref.c3t @@ -133,7 +133,7 @@ entry: ret %Foo* %1 } ; Function Attrs: nounwind -define void @main() #0 { +define void @foo.main() #0 { entry: %x = alloca %Foo, align 4 %a = alloca i32, align 4 diff --git a/test/test_suite/statements/defer_break.c3t b/test/test_suite/statements/defer_break.c3t index 3278bbe20..347c0bd73 100644 --- a/test/test_suite/statements/defer_break.c3t +++ b/test/test_suite/statements/defer_break.c3t @@ -14,7 +14,7 @@ fn void defer9() {} fn void defer10() {} fn void defer11() {} -fn int main(int argc) +fn int main(int argc, char** argv) { int a = 0; { @@ -48,75 +48,98 @@ fn int main(int argc) /* #expect: foo.ll -define i32 @main(i32 %0) #0 { +define i32 @main(i32 %0, i8** %1) #0 { entry: %argc = alloca i32, align 4 + %argv = alloca i8**, align 8 %a = alloca i32, align 4 store i32 %0, i32* %argc, align 4 + store i8** %1, i8*** %argv, align 8 store i32 0, i32* %a, align 4 call void @foo.defer2() - %1 = load i32, i32* %a, align 4 - %eq = icmp eq i32 %1, 1 + %2 = load i32, i32* %a, align 4 + %eq = icmp eq i32 %2, 1 br i1 %eq, label %if.then, label %if.exit + if.then: ; preds = %entry br label %exit + if.exit: ; preds = %entry call void @foo.defer1() br label %exit + exit: ; preds = %if.exit, %if.then br label %loop.cond + loop.cond: ; preds = %exit6, %exit - %2 = load i32, i32* %a, align 4 - %intbool = icmp ne i32 %2, 0 + %3 = load i32, i32* %a, align 4 + %intbool = icmp ne i32 %3, 0 br i1 %intbool, label %loop.body, label %loop.exit + loop.body: ; preds = %loop.cond - %3 = load i32, i32* %argc, align 4 - %eq1 = icmp eq i32 %3, 1 + %4 = load i32, i32* %argc, align 4 + %eq1 = icmp eq i32 %4, 1 br i1 %eq1, label %if.then2, label %if.exit4 + if.then2: ; preds = %loop.body call void @foo.defer4() br label %exit3 + exit3: ; preds = %if.then2 br label %loop.exit + if.exit4: ; preds = %loop.body call void @foo.defer6() call void @foo.defer5() br label %exit5 + exit5: ; preds = %if.exit4 call void @foo.defer4() br label %exit6 + exit6: ; preds = %exit5 br label %loop.cond + loop.exit: ; preds = %exit3, %loop.cond br label %loop.cond7 + loop.cond7: ; preds = %loop.exit - %4 = load i32, i32* %a, align 4 - %intbool8 = icmp ne i32 %4, 0 + %5 = load i32, i32* %a, align 4 + %intbool8 = icmp ne i32 %5, 0 br i1 %intbool8, label %loop.body9, label %loop.exit18 + loop.body9: ; preds = %loop.cond7 - %5 = load i32, i32* %argc, align 4 - %eq10 = icmp eq i32 %5, 1 + %6 = load i32, i32* %argc, align 4 + %eq10 = icmp eq i32 %6, 1 br i1 %eq10, label %if.then11, label %if.exit13 + if.then11: ; preds = %loop.body9 call void @foo.defer8() br label %exit12 + exit12: ; preds = %if.then11 br label %loop.exit18 + if.exit13: ; preds = %loop.body9 call void @foo.defer10() call void @foo.defer9() br label %exit14 + exit14: ; preds = %if.exit13 call void @foo.defer8() br label %exit15 + exit15: ; preds = %exit14 br label %loop.exit18 + loop.exit18: ; preds = %exit15, %exit12, %loop.cond7 call void @foo.defer7() br label %exit19 + exit19: ; preds = %loop.exit18 call void @foo.defer3() br label %exit20 + exit20: ; preds = %exit19 ret i32 0 } \ No newline at end of file diff --git a/test/test_suite/statements/defer_break_simple.c3t b/test/test_suite/statements/defer_break_simple.c3t index 91a8ea516..67f0102d8 100644 --- a/test/test_suite/statements/defer_break_simple.c3t +++ b/test/test_suite/statements/defer_break_simple.c3t @@ -6,7 +6,7 @@ fn void testA() {} fn void testB() {} fn void test3() {} -fn int main(int argc) +fn int main(int argc, char** argv) { int a = 0; while (a) @@ -26,49 +26,42 @@ fn int main(int argc) // #expect: test.ll -define i32 @main(i32 %0) #0 { +define i32 @main(i32 %0, i8** %1) #0 { entry: %argc = alloca i32, align 4 + %argv = alloca i8**, align 8 %a = alloca i32, align 4 store i32 %0, i32* %argc, align 4 + store i8** %1, i8*** %argv, align 8 store i32 0, i32* %a, align 4 br label %loop.cond - loop.cond: ; preds = %exit3, %entry - %1 = load i32, i32* %a, align 4 - %intbool = icmp ne i32 %1, 0 + %2 = load i32, i32* %a, align 4 + %intbool = icmp ne i32 %2, 0 br i1 %intbool, label %loop.body, label %loop.exit - loop.body: ; preds = %loop.cond - %2 = load i32, i32* %argc, align 4 - %eq = icmp eq i32 %2, 1 + %3 = load i32, i32* %argc, align 4 + %eq = icmp eq i32 %3, 1 br i1 %eq, label %if.then, label %if.exit - if.then: ; preds = %loop.body call void @test.testA() call void @test.testB() br label %exit - exit: ; preds = %if.then call void @test.test2() br label %exit1 - exit1: ; preds = %exit br label %loop.exit - if.exit: ; preds = %loop.body call void @test.test3() call void @test.testA() call void @test.testB() br label %exit2 - exit2: ; preds = %if.exit call void @test.test2() br label %exit3 - exit3: ; preds = %exit2 br label %loop.cond - loop.exit: ; preds = %exit1, %loop.cond ret i32 0 } diff --git a/test/test_suite/statements/defer_return.c3t b/test/test_suite/statements/defer_return.c3t index 648dbc6b9..44adb4d60 100644 --- a/test/test_suite/statements/defer_return.c3t +++ b/test/test_suite/statements/defer_return.c3t @@ -10,7 +10,7 @@ fn void test7() {} fn void test8() {} fn void test9() {} -fn int main(int argc) +fn int main(int argc, char **argv) { defer test1(); int a = 0; @@ -36,29 +36,30 @@ fn int main(int argc) /* #expect: test.ll - -define i32 @main(i32 %0) #0 { +define i32 @main(i32 %0, i8** %1) #0 { entry: %argc = alloca i32, align 4 + %argv = alloca i8**, align 8 %a = alloca i32, align 4 store i32 %0, i32* %argc, align 4 + store i8** %1, i8*** %argv, align 8 store i32 0, i32* %a, align 4 br label %loop.cond loop.cond: ; preds = %exit3, %entry - %1 = load i32, i32* %a, align 4 - %intbool = icmp ne i32 %1, 0 + %2 = load i32, i32* %a, align 4 + %intbool = icmp ne i32 %2, 0 br i1 %intbool, label %loop.body, label %loop.exit loop.body: ; preds = %loop.cond - %2 = load i32, i32* %argc, align 4 - %eq = icmp eq i32 %2, 1 + %3 = load i32, i32* %argc, align 4 + %eq = icmp eq i32 %3, 1 br i1 %eq, label %if.then, label %if.exit if.then: ; preds = %loop.body - %3 = load i32, i32* %a, align 4 - %4 = load i32, i32* %argc, align 4 - %add = add i32 %3, %4 + %4 = load i32, i32* %a, align 4 + %5 = load i32, i32* %argc, align 4 + %add = add i32 %4, %5 call void @test.test2() br label %exit @@ -85,18 +86,18 @@ loop.exit: ; preds = %loop.cond br label %loop.cond4 loop.cond4: ; preds = %loop.exit - %5 = load i32, i32* %a, align 4 - %intbool5 = icmp ne i32 %5, 0 + %6 = load i32, i32* %a, align 4 + %intbool5 = icmp ne i32 %6, 0 br i1 %intbool5, label %loop.body6, label %loop.exit21 loop.body6: ; preds = %loop.cond4 - %6 = load i32, i32* %argc, align 4 - %eq7 = icmp eq i32 %6, 1 + %7 = load i32, i32* %argc, align 4 + %eq7 = icmp eq i32 %7, 1 br i1 %eq7, label %if.then8, label %if.exit13 if.then8: ; preds = %loop.body6 - %7 = load i32, i32* %a, align 4 - %add9 = add i32 %7, 2 + %8 = load i32, i32* %a, align 4 + %add9 = add i32 %8, 2 call void @test.test6() br label %exit10 @@ -132,8 +133,8 @@ exit17: ; preds = %exit16 ret i32 4 loop.exit21: ; preds = %loop.cond4 - %8 = load i32, i32* %argc, align 4 - %add22 = add i32 0, %8 + %9 = load i32, i32* %argc, align 4 + %add22 = add i32 0, %9 call void @test.test5() br label %exit23 diff --git a/test/test_suite/statements/fallthough_do.c3t b/test/test_suite/statements/fallthough_do.c3t index e0d175dbf..949e0e5df 100644 --- a/test/test_suite/statements/fallthough_do.c3t +++ b/test/test_suite/statements/fallthough_do.c3t @@ -40,7 +40,7 @@ fn void main() @.str = private constant [4 x i8] c"%d\0A\00", align 1 @.str.1 = private constant [8 x i8] c"%d, %d\0A\00", align 1 -define void @main() #0 { +define void @foo.main() #0 { entry: %i = alloca i32, align 4 store i32 10, i32* %i, align 4 diff --git a/test/test_suite/statements/foreach_custom.c3t b/test/test_suite/statements/foreach_custom.c3t index 55af3127c..42f849563 100644 --- a/test/test_suite/statements/foreach_custom.c3t +++ b/test/test_suite/statements/foreach_custom.c3t @@ -34,7 +34,7 @@ extern fn int printf(char *fmt, ...); // #expect: foo.ll ; Function Attrs: nounwind -define void @main() #0 { +define void @foo.main() #0 { entry: %i = alloca [3 x i32], align 4 %x = alloca %Foo, align 8 diff --git a/test/test_suite/statements/foreach_custom_macro.c3t b/test/test_suite/statements/foreach_custom_macro.c3t index a16226da7..556c1f8fb 100644 --- a/test/test_suite/statements/foreach_custom_macro.c3t +++ b/test/test_suite/statements/foreach_custom_macro.c3t @@ -32,7 +32,7 @@ extern fn int printf(char *fmt, ...); // #expect: foo.ll -define void @main() #0 { +define void @foo.main() #0 { entry: %i = alloca [3 x i32], align 4 %x = alloca %Foo, align 8 diff --git a/test/test_suite/statements/ranged_switch.c3t b/test/test_suite/statements/ranged_switch.c3t index 50531ce00..cf894443a 100644 --- a/test/test_suite/statements/ranged_switch.c3t +++ b/test/test_suite/statements/ranged_switch.c3t @@ -48,7 +48,7 @@ fn void main() /* #expect: foo.ll -define void @main() #0 { +define void @foo.main() #0 { entry: %i = alloca i32, align 4 %switch = alloca i32, align 4 diff --git a/test/test_suite/statements/simple_do.c3t b/test/test_suite/statements/simple_do.c3t index 1b38decec..4f2b80e52 100644 --- a/test/test_suite/statements/simple_do.c3t +++ b/test/test_suite/statements/simple_do.c3t @@ -27,7 +27,7 @@ fn void main() // #expect: foo.ll -define void @main() #0 { +define void @foo.main() #0 { entry: %i = alloca i32, align 4 store i32 10, i32* %i, align 4 diff --git a/test/test_suite/statements/various_switching.c3t b/test/test_suite/statements/various_switching.c3t index 83f30c57f..314ec0c28 100644 --- a/test/test_suite/statements/various_switching.c3t +++ b/test/test_suite/statements/various_switching.c3t @@ -200,7 +200,7 @@ switch.exit26: ; preds = %switch.default25, % } ; Function Attrs: nounwind -define void @main() #0 { +define void @mymodule.main() #0 { entry: call void @mymodule.test() call void (i8*, ...) @printf(i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str.8, i32 0, i32 0)) diff --git a/test/test_suite/strings/string_escape.c3t b/test/test_suite/strings/string_escape.c3t index bc31121da..12a5b9337 100644 --- a/test/test_suite/strings/string_escape.c3t +++ b/test/test_suite/strings/string_escape.c3t @@ -7,8 +7,19 @@ fn void main() @.str = private constant [18 x i8] c"Hello\00 world! now\00", align 1 -define void @main() +define void @string_escape.main() #0 { entry: %s = alloca i8*, align 8 store i8* getelementptr inbounds ([18 x i8], [18 x i8]* @.str, i32 0, i32 0), i8** %s, align 8 ret void +} + +define i32 @main(i32 %0, i8** %1) #0 { +entry: + %"_$argv" = alloca i32, align 4 + %"_$argc" = alloca i8**, align 8 + store i32 %0, i32* %"_$argv", align 4 + store i8** %1, i8*** %"_$argc", align 8 + call void @string_escape.main() + ret i32 0 +} \ No newline at end of file diff --git a/test/test_suite/strings/string_to_array.c3t b/test/test_suite/strings/string_to_array.c3t index 56f4ca522..3c1d3f323 100644 --- a/test/test_suite/strings/string_to_array.c3t +++ b/test/test_suite/strings/string_to_array.c3t @@ -1,10 +1,11 @@ // #target: x64-darwin module foo; -fn void main() +fn int main() { char[2] x = "ab"; char[*] y = "abc"; + return 0; } /* #expect: foo.ll @@ -12,7 +13,7 @@ fn void main() @.str = private constant [3 x i8] c"ab\00", align 1 @.str.1 = private constant [4 x i8] c"abc\00", align 1 -define void @main() #0 { +define i32 @main() #0 { entry: %x = alloca [2 x i8], align 1 %y = alloca [3 x i8], align 1 @@ -20,5 +21,5 @@ entry: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %0, i8* align 8 getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i32 0, i32 0), i32 2, i1 false) %1 = bitcast [3 x i8]* %y to i8* call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %1, i8* align 8 getelementptr inbounds ([4 x i8], [4 x i8]* @.str.1, i32 0, i32 0), i32 3, i1 false) - ret void + ret i32 0 } diff --git a/test/test_suite/subarrays/slice_comparison.c3t b/test/test_suite/subarrays/slice_comparison.c3t index d8cf849df..fef1be027 100644 --- a/test/test_suite/subarrays/slice_comparison.c3t +++ b/test/test_suite/subarrays/slice_comparison.c3t @@ -33,7 +33,7 @@ fn void main() // #expect: mymodule.ll -define void @main() #0 { +define void @mymodule.main() #0 { entry: %y = alloca %"char[]", align 8 %z = alloca %"char[]", align 8 diff --git a/test/test_suite/variant/variant_test.c3t b/test/test_suite/variant/variant_test.c3t index e32c431b7..6e225e9f2 100644 --- a/test/test_suite/variant/variant_test.c3t +++ b/test/test_suite/variant/variant_test.c3t @@ -175,7 +175,7 @@ loop.exit: ; preds = %loop.cond } ; Function Attrs: nounwind -define void @main() #0 { +define void @foo.main() #0 { entry: %x = alloca %variant, align 8 %taddr = alloca i32, align 4 diff --git a/test/test_suite/vector/vector_bit.c3t b/test/test_suite/vector/vector_bit.c3t index c1969ed1d..f9a5e2242 100644 --- a/test/test_suite/vector/vector_bit.c3t +++ b/test/test_suite/vector/vector_bit.c3t @@ -153,11 +153,3 @@ entry: %66 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([17 x i8], [17 x i8]* @.str.6, i32 0, i32 0), i32 %59, i32 %61, i32 %63, i32 %65) ret void } - -; Function Attrs: nounwind -define void @main() #0 { -entry: - call void @vector_bit.testf() - call void @vector_bit.testi() - ret void -} \ No newline at end of file diff --git a/test/test_suite/vector/vector_incdec.c3t b/test/test_suite/vector/vector_incdec.c3t index c1718e7c0..cacf9eb0b 100644 --- a/test/test_suite/vector/vector_incdec.c3t +++ b/test/test_suite/vector/vector_incdec.c3t @@ -182,8 +182,7 @@ entry: ret void } -; Function Attrs: nounwind -define void @main() #0 { +define void @vector_incdec.main() #0 { entry: call void @vector_incdec.testf() call void @vector_incdec.testi() diff --git a/test/test_suite/vector/vector_init.c3t b/test/test_suite/vector/vector_init.c3t index c3dc6d460..00fabc35e 100644 --- a/test/test_suite/vector/vector_init.c3t +++ b/test/test_suite/vector/vector_init.c3t @@ -17,7 +17,7 @@ fn void main() @vector_init.baz = global <4 x i32> , align 16 ; Function Attrs: nounwind -define void @main() #0 { +define void @vector_init.main() #0 { entry: %foo = alloca <4 x i32>, align 16 %z = alloca i32, align 4 diff --git a/test/test_suite/vector/vector_ops.c3t b/test/test_suite/vector/vector_ops.c3t index 62e23f6a0..a3fe5a924 100644 --- a/test/test_suite/vector/vector_ops.c3t +++ b/test/test_suite/vector/vector_ops.c3t @@ -278,12 +278,3 @@ entry: %91 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str.12, i32 0, i32 0), i32 %84, i32 %86, i32 %88, i32 %90) ret void } - -; Function Attrs: nounwind -define void @main() #0 { -entry: - call void @vector_ops.testf() - call void @vector_ops.testi() - call void @vector_ops.testb() - ret void -} \ No newline at end of file