From a281dbe8128cf626274f0d1e868722b228892c5b Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Thu, 6 Oct 2022 11:12:22 +0200 Subject: [PATCH] Added $$TIME, $$DATE, $$FUNCTION. Builtin defines listed. --- CMakeLists.txt | 2 +- src/compiler/compiler.c | 5 + src/compiler/compiler_internal.h | 6 +- src/compiler/enums.h | 13 ++ src/compiler/sema_expr.c | 182 ++++++++++-------- src/compiler/symtab.c | 28 +-- src/utils/lib.h | 2 + src/utils/time.c | 27 +++ src/version.h | 2 +- .../compile_time/ct_builtin_time_date.c3t | 150 +++++++++++++++ test/test_suite/compile_time/ct_funcptr.c3t | 2 +- .../compile_time/ct_builtin_time_date.c3t | 139 +++++++++++++ test/test_suite2/compile_time/ct_funcptr.c3t | 2 +- 13 files changed, 457 insertions(+), 103 deletions(-) create mode 100644 src/utils/time.c create mode 100644 test/test_suite/compile_time/ct_builtin_time_date.c3t create mode 100644 test/test_suite2/compile_time/ct_builtin_time_date.c3t diff --git a/CMakeLists.txt b/CMakeLists.txt index faf76593d..89be6ebed 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -259,7 +259,7 @@ add_executable(c3c src/compiler/codegen_asm.c src/compiler/asm_target.c src/compiler/llvm_codegen_builtins.c - src/compiler/expr.c) + src/compiler/expr.c src/utils/time.c) target_include_directories(c3c PRIVATE diff --git a/src/compiler/compiler.c b/src/compiler/compiler.c index 992ba0147..159e24232 100644 --- a/src/compiler/compiler.c +++ b/src/compiler/compiler.c @@ -591,6 +591,11 @@ void print_syntax(BuildOptions *options) { printf("%2d $$%s\n", i + 1, builtin_list[i]); } + puts("---"); + for (int i = 0; i < NUMBER_OF_BUILTIN_DEFINES; i++) + { + printf("%2d $$%s\n", i + 1, builtin_defines[i]); + } } if (options->print_precedence) { diff --git a/src/compiler/compiler_internal.h b/src/compiler/compiler_internal.h index cf593d912..6abb06912 100644 --- a/src/compiler/compiler_internal.h +++ b/src/compiler/compiler_internal.h @@ -1806,6 +1806,7 @@ extern Type *type_chars; extern const char *attribute_list[NUMBER_OF_ATTRIBUTES]; extern const char *builtin_list[NUMBER_OF_BUILTINS]; +extern const char *builtin_defines[NUMBER_OF_BUILTIN_DEFINES]; extern const char *kw_std__core; extern const char *kw_std__core__types; @@ -1842,11 +1843,6 @@ extern const char *kw_ptr; extern const char *kw_values; extern const char *kw_return; extern const char *kw_type; -extern const char *kw_FILE; -extern const char *kw_FUNC; -extern const char *kw_FUNCPTR; -extern const char *kw_LINE; -extern const char *kw_LINEREAL; extern const char *kw_incr; extern const char *kw_check_assign; extern const char *kw_argc; diff --git a/src/compiler/enums.h b/src/compiler/enums.h index 4a834e6d7..522b6ca65 100644 --- a/src/compiler/enums.h +++ b/src/compiler/enums.h @@ -864,6 +864,19 @@ typedef enum BUILTIN_LROUND, } BuiltinFunction; +typedef enum +{ + BUILTIN_DEF_DATE, + BUILTIN_DEF_FILE, + BUILTIN_DEF_FUNC, + BUILTIN_DEF_FUNCTION, + BUILTIN_DEF_LINE, + BUILTIN_DEF_LINE_RAW, + BUILTIN_DEF_MODULE, + BUILTIN_DEF_TIME, + BUILTIN_DEF_NONE, + NUMBER_OF_BUILTIN_DEFINES = BUILTIN_DEF_NONE +} BuiltinDefine; typedef enum { ATOMIC_NONE, diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index 29d8a7891..a5d90a65a 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -48,7 +48,7 @@ static inline bool sema_expr_analyse_typeid(SemaContext *context, Expr *expr); static inline bool sema_expr_analyse_call(SemaContext *context, Expr *expr); static inline bool sema_expr_analyse_expr_block(SemaContext *context, Type *infer_type, Expr *expr); static inline bool sema_expr_analyse_failable(SemaContext *context, Expr *expr); -static inline bool sema_expr_analyse_compiler_const(SemaContext *context, Expr *expr); +static inline bool sema_expr_analyse_compiler_const(SemaContext *context, Expr *expr, bool report_missing); static inline bool sema_expr_analyse_ct_arg(SemaContext *context, Expr *expr); static inline bool sema_expr_analyse_ct_stringify(SemaContext *context, Expr *expr); static inline bool sema_expr_analyse_ct_offsetof(SemaContext *context, Expr *expr); @@ -5622,99 +5622,118 @@ static inline bool sema_expr_analyse_failable(SemaContext *context, Expr *expr) return true; } -static inline bool sema_expr_analyse_compiler_const(SemaContext *context, Expr *expr) +static inline bool sema_expr_analyse_compiler_const(SemaContext *context, Expr *expr, bool report_missing) { const char *string = expr->builtin_expr.ident; - if (string == kw_FILE) + BuiltinDefine def = BUILTIN_DEF_NONE; + for (unsigned i = 0; i < NUMBER_OF_BUILTIN_DEFINES; i++) { - expr_rewrite_to_string(expr, context->compilation_unit->file->name); - return true; - } - if (string == kw_FUNCPTR) - { - - switch (context->call_env.kind) + if (string == builtin_defines[i]) { - case CALL_ENV_GLOBAL_INIT: - case CALL_ENV_CHECKS: - case CALL_ENV_INITIALIZER: - case CALL_ENV_FINALIZER: - case CALL_ENV_ATTR: - expr_rewrite_to_const_zero(expr, type_voidptr); - return true; - case CALL_ENV_FUNCTION: - expr->expr_kind = EXPR_IDENTIFIER; - expr->resolve_status = RESOLVE_DONE; - expr->identifier_expr.decl = context->call_env.current_function; - expr->type = expr->identifier_expr.decl->type; - expr_insert_addr(expr); - return true; + def = (BuiltinDefine)i; + break; } - UNREACHABLE } - if (string == kw_FUNC) + switch (def) { - switch (context->call_env.kind) - { - case CALL_ENV_GLOBAL_INIT: - expr_rewrite_to_string(expr, ""); - return true; - case CALL_ENV_CHECKS: - expr_rewrite_to_string(expr, ""); - return true; - case CALL_ENV_FUNCTION: + case BUILTIN_DEF_TIME: + expr_rewrite_to_string(expr, time_get()); + return true; + case BUILTIN_DEF_DATE: + expr_rewrite_to_string(expr, date_get()); + return true; + case BUILTIN_DEF_FILE: + expr_rewrite_to_string(expr, context->compilation_unit->file->name); + return true; + case BUILTIN_DEF_MODULE: + expr_rewrite_to_string(expr, context->compilation_unit->module->name->module); + return true; + case BUILTIN_DEF_LINE: + if (context->original_inline_line) { - Decl *current_func = context->call_env.current_function; - TypeInfo *func_type = type_infoptrzero(current_func->func_decl.type_parent); - if (func_type) + expr_rewrite_const_int(expr, type_isize, context->original_inline_line, true); + } + else + { + expr_rewrite_const_int(expr, type_isize, expr->span.row, true); + } + return true; + case BUILTIN_DEF_LINE_RAW: + expr_rewrite_const_int(expr, type_isize, expr->span.row, true); + return true; + case BUILTIN_DEF_FUNCTION: + switch (context->call_env.kind) + { + case CALL_ENV_GLOBAL_INIT: + case CALL_ENV_CHECKS: + case CALL_ENV_INITIALIZER: + case CALL_ENV_FINALIZER: + case CALL_ENV_ATTR: + if (report_missing) + { + SEMA_ERROR(expr, "$$FUNCEXPR is not defined outside of a function."); + } + return false; + case CALL_ENV_FUNCTION: + expr->expr_kind = EXPR_IDENTIFIER; + expr->resolve_status = RESOLVE_DONE; + expr->identifier_expr.decl = context->call_env.current_function; + expr->type = expr->identifier_expr.decl->type; + return true; + } + UNREACHABLE + case BUILTIN_DEF_FUNC: + switch (context->call_env.kind) + { + case CALL_ENV_GLOBAL_INIT: + expr_rewrite_to_string(expr, ""); + return true; + case CALL_ENV_CHECKS: + expr_rewrite_to_string(expr, ""); + return true; + case CALL_ENV_FUNCTION: { - scratch_buffer_clear(); - scratch_buffer_append(func_type->type->name); - scratch_buffer_append_char('.'); - scratch_buffer_append(current_func->name); - expr_rewrite_to_string(expr, scratch_buffer_copy()); + Decl *current_func = context->call_env.current_function; + TypeInfo *func_type = type_infoptrzero(current_func->func_decl.type_parent); + if (func_type) + { + scratch_buffer_clear(); + scratch_buffer_append(func_type->type->name); + scratch_buffer_append_char('.'); + scratch_buffer_append(current_func->name); + expr_rewrite_to_string(expr, scratch_buffer_copy()); + return true; + } + expr_rewrite_to_string(expr, current_func->name); return true; } - expr_rewrite_to_string(expr, current_func->name); - return true; + case CALL_ENV_INITIALIZER: + expr_rewrite_to_string(expr, ""); + return true; + case CALL_ENV_FINALIZER: + expr_rewrite_to_string(expr, ""); + return true; + case CALL_ENV_ATTR: + expr_rewrite_to_string(expr, ""); + return true; } - case CALL_ENV_INITIALIZER: - expr_rewrite_to_string(expr, ""); - return true; - case CALL_ENV_FINALIZER: - expr_rewrite_to_string(expr, ""); - return true; - case CALL_ENV_ATTR: - expr_rewrite_to_string(expr, ""); - return true; - } - UNREACHABLE - } - if (string == kw_LINEREAL) - { - expr_rewrite_const_int(expr, type_isize, expr->span.row, true); - return true; - } - if (string == kw_LINE) - { - if (context->original_inline_line) + UNREACHABLE + case BUILTIN_DEF_NONE: { - expr_rewrite_const_int(expr, type_isize, context->original_inline_line, true); + Expr *value = htable_get(&global_context.compiler_defines, string); + if (!value) + { + if (report_missing) + { + SEMA_ERROR(expr, "The compiler constant '%s' was not defined, did you mistype or forget to add it?", string); + } + return false; + } + expr_replace(expr, value); + return true; } - else - { - expr_rewrite_const_int(expr, type_isize, expr->span.row, true); - } - return true; } - Expr *value = htable_get(&global_context.compiler_defines, string); - if (!value) - { - SEMA_ERROR(expr, "The compiler constant '%s' was not defined, did you mistype or forget to add it?", string); - return false; - } - expr_replace(expr, value); - return true; + UNREACHABLE } @@ -6163,6 +6182,9 @@ RETRY: if (!decl) goto NOT_DEFINED; type = decl->type; break; + case EXPR_COMPILER_CONST: + if (!sema_expr_analyse_compiler_const(context, main_var, false)) goto NOT_DEFINED; + break; case EXPR_TYPEINFO: { type = sema_expr_check_type_exists(context, main_var->type_expr); @@ -6526,7 +6548,7 @@ static inline bool sema_analyse_expr_dispatch(SemaContext *context, Expr *expr) case EXPR_FAILABLE: return sema_expr_analyse_failable(context, expr); case EXPR_COMPILER_CONST: - return sema_expr_analyse_compiler_const(context, expr); + return sema_expr_analyse_compiler_const(context, expr, true); case EXPR_POINTER_OFFSET: return sema_expr_analyse_pointer_offset(context, expr); case EXPR_POISONED: diff --git a/src/compiler/symtab.c b/src/compiler/symtab.c index dd8f4b7f5..a14d53d7f 100644 --- a/src/compiler/symtab.c +++ b/src/compiler/symtab.c @@ -38,7 +38,7 @@ static SymTab symtab; const char *attribute_list[NUMBER_OF_ATTRIBUTES]; const char *builtin_list[NUMBER_OF_BUILTINS]; - +const char *builtin_defines[NUMBER_OF_BUILTIN_DEFINES]; const char *kw_FILE; const char *kw_FUNC; const char *kw_FUNCPTR; @@ -128,12 +128,14 @@ void symtab_init(uint32_t capacity) // Init some constant idents #define KW_DEF(x) symtab_add(x, sizeof(x) - 1, fnv1a(x, sizeof(x) - 1), &type) TokenType type = TOKEN_CONST_IDENT; - kw_LINE = KW_DEF("LINE"); - kw_LINEREAL = KW_DEF("LINEREAL"); - kw_FILE = KW_DEF("FILE"); - kw_FUNC = KW_DEF("FUNC"); - kw_FUNCPTR = KW_DEF("FUNCPTR"); - + builtin_defines[BUILTIN_DEF_DATE] = KW_DEF("DATE"); + builtin_defines[BUILTIN_DEF_FILE] = KW_DEF("FILE"); + builtin_defines[BUILTIN_DEF_FUNCTION] = KW_DEF("FUNCTION"); + builtin_defines[BUILTIN_DEF_FUNC] = KW_DEF("FUNC"); + builtin_defines[BUILTIN_DEF_LINE] = KW_DEF("LINE"); + builtin_defines[BUILTIN_DEF_LINE_RAW] = KW_DEF("LINE_RAW"); + builtin_defines[BUILTIN_DEF_MODULE] = KW_DEF("MODULE"); + builtin_defines[BUILTIN_DEF_TIME] = KW_DEF("TIME"); type = TOKEN_TYPE_IDENT; kw_typekind = KW_DEF("TypeKind"); @@ -229,18 +231,16 @@ void symtab_init(uint32_t capacity) builtin_list[BUILTIN_VOLATILE_LOAD] = KW_DEF("volatile_load"); builtin_list[BUILTIN_VOLATILE_STORE] = KW_DEF("volatile_store"); -// Disabled for now! - -// builtin_list[BUILTIN_LLRINT] = KW_DEF("llrint"); -// builtin_list[BUILTIN_LLROUND] = KW_DEF("llround"); -// builtin_list[BUILTIN_LRINT] = KW_DEF("lrint"); -// builtin_list[BUILTIN_LROUND] = KW_DEF("lround"); - for (unsigned i = 0; i < NUMBER_OF_BUILTINS; i++) { assert(builtin_list[i] && "Missing builtin"); } + for (unsigned i = 0; i < NUMBER_OF_BUILTIN_DEFINES; i++) + { + assert(builtin_defines[i] && "Missing builtin define"); + } + type = TOKEN_AT_IDENT; kw_at_checked = KW_DEF("@checked"); diff --git a/src/utils/lib.h b/src/utils/lib.h index 9022e0267..a7504a32b 100644 --- a/src/utils/lib.h +++ b/src/utils/lib.h @@ -98,6 +98,8 @@ void taskqueue_add(TaskQueueRef queue, Task *task); void taskqueue_destroy(TaskQueueRef queue); void taskqueue_wait_for_completion(TaskQueueRef queue); +const char *date_get(void); +const char *time_get(void); const char *str_remove_suffix(const char *name, const char *suffix); bool str_has_suffix(const char *name, const char *suffix); diff --git a/src/utils/time.c b/src/utils/time.c new file mode 100644 index 000000000..4117a5b98 --- /dev/null +++ b/src/utils/time.c @@ -0,0 +1,27 @@ +// Copyright (c) 2022 Christoffer Lerno. All rights reserved. +// Use of this source code is governed by a LGPLv3.0 +// a copy of which can be found in the LICENSE file. +#include "lib.h" +#include + +const char *time_get(void) +{ + time_t rawtime; + struct tm *timeinfo; + time(&rawtime); + timeinfo = localtime(&rawtime); + scratch_buffer_clear(); + scratch_buffer_printf("%02d:%02d:%02d", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec); + return scratch_buffer_copy(); +} + +const char *date_get(void) +{ + time_t rawtime; + struct tm *timeinfo; + time(&rawtime); + timeinfo = localtime(&rawtime); + scratch_buffer_clear(); + scratch_buffer_printf("%02d-%02d-%02d", timeinfo->tm_year + 1900, timeinfo->tm_mon, timeinfo->tm_mday); + return scratch_buffer_copy(); +} \ No newline at end of file diff --git a/src/version.h b/src/version.h index e2a0aafae..ac902d666 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define COMPILER_VERSION "0.3.69" \ No newline at end of file +#define COMPILER_VERSION "0.3.70" \ No newline at end of file diff --git a/test/test_suite/compile_time/ct_builtin_time_date.c3t b/test/test_suite/compile_time/ct_builtin_time_date.c3t new file mode 100644 index 000000000..ab1b459a1 --- /dev/null +++ b/test/test_suite/compile_time/ct_builtin_time_date.c3t @@ -0,0 +1,150 @@ +// #target: macos-x64 +module test; +import std::io; + +macro printline() +{ + io::printfln("%d", $$LINE); io::printfln("%d", $$LINE_RAW); +} +fn void test(int x) +{ + io::printfln("%d", x); + if (x > 0) $$FUNCTION(x - 1); + io::println($$TIME); + io::println($$DATE); + printline(); + io::println($$FILE); + io::println($$MODULE); +} + +bool is_def = $defined($$FUNCTION); +fn void main() +{ + bool is_def2 = $defined($$FUNCTION); + test(10); +} + +/* #expect: test.ll + +define void @test_test(i32 %0) #0 { +entry: + %retparam = alloca i64, align 8 + %taddr = alloca %"char[]", align 8 + %vararg = alloca %"variant[]", align 8 + %varargslots = alloca [1 x %variant], align 16 + %taddr1 = alloca i32, align 4 + %retparam4 = alloca i64, align 8 + %taddr5 = alloca %"char[]", align 8 + %vararg8 = alloca %"variant[]", align 8 + %varargslots9 = alloca [1 x %variant], align 16 + %taddr10 = alloca i64, align 8 + %retparam16 = alloca i64, align 8 + %taddr17 = alloca %"char[]", align 8 + %vararg20 = alloca %"variant[]", align 8 + %varargslots21 = alloca [1 x %variant], align 16 + %taddr22 = alloca i64, align 8 + store %"char[]" { i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i32 0, i32 0), i64 2 }, %"char[]"* %taddr, align 8 + %1 = bitcast %"char[]"* %taddr to { i8*, i64 }* + %2 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %1, i32 0, i32 0 + %lo = load i8*, i8** %2, align 8 + %3 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %1, i32 0, i32 1 + %hi = load i64, i64* %3, align 8 + store i32 %0, i32* %taddr1, align 4 + %4 = bitcast i32* %taddr1 to i8* + %5 = insertvalue %variant undef, i8* %4, 0 + %6 = insertvalue %variant %5, i64 ptrtoint (%.introspect* @"ct$int" to i64), 1 + %7 = getelementptr inbounds [1 x %variant], [1 x %variant]* %varargslots, i64 0, i64 0 + store %variant %6, %variant* %7, align 16 + %8 = getelementptr inbounds %"variant[]", %"variant[]"* %vararg, i32 0, i32 1 + store i64 1, i64* %8, align 8 + %9 = getelementptr inbounds %"variant[]", %"variant[]"* %vararg, i32 0, i32 0 + %10 = bitcast [1 x %variant]* %varargslots to %variant* + store %variant* %10, %variant** %9, align 8 + %11 = bitcast %"variant[]"* %vararg to { i8*, i64 }* + %12 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %11, i32 0, i32 0 + %lo2 = load i8*, i8** %12, align 8 + %13 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %11, i32 0, i32 1 + %hi3 = load i64, i64* %13, align 8 + %14 = call i64 @std_io_printfln(i64* %retparam, i8* %lo, i64 %hi, i8* %lo2, i64 %hi3) + %not_err = icmp eq i64 %14, 0 + br i1 %not_err, label %after_check, label %voiderr + +after_check: ; preds = %entry + br label %voiderr + +voiderr: ; preds = %after_check, %entry + %gt = icmp sgt i32 %0, 0 + br i1 %gt, label %if.then, label %if.exit + +if.then: ; preds = %voiderr + %sub = sub i32 %0, 1 + call void @test_test(i32 %sub) + br label %if.exit + +if.exit: ; preds = %if.then, %voiderr + %15 = call i32 @std_io_println(i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str.1, i32 0, i32 0)) #1 + %16 = call i32 @std_io_println(i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str.2, i32 0, i32 0)) #1 + store %"char[]" { i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.3, i32 0, i32 0), i64 2 }, %"char[]"* %taddr5, align 8 + %17 = bitcast %"char[]"* %taddr5 to { i8*, i64 }* + %18 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %17, i32 0, i32 0 + %lo6 = load i8*, i8** %18, align 8 + %19 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %17, i32 0, i32 1 + %hi7 = load i64, i64* %19, align 8 + store i64 14, i64* %taddr10, align 8 + %20 = bitcast i64* %taddr10 to i8* + %21 = insertvalue %variant undef, i8* %20, 0 + %22 = insertvalue %variant %21, i64 ptrtoint (%.introspect* @"ct$long" to i64), 1 + %23 = getelementptr inbounds [1 x %variant], [1 x %variant]* %varargslots9, i64 0, i64 0 + store %variant %22, %variant* %23, align 16 + %24 = getelementptr inbounds %"variant[]", %"variant[]"* %vararg8, i32 0, i32 1 + store i64 1, i64* %24, align 8 + %25 = getelementptr inbounds %"variant[]", %"variant[]"* %vararg8, i32 0, i32 0 + %26 = bitcast [1 x %variant]* %varargslots9 to %variant* + store %variant* %26, %variant** %25, align 8 + %27 = bitcast %"variant[]"* %vararg8 to { i8*, i64 }* + %28 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %27, i32 0, i32 0 + %lo11 = load i8*, i8** %28, align 8 + %29 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %27, i32 0, i32 1 + %hi12 = load i64, i64* %29, align 8 + %30 = call i64 @std_io_printfln(i64* %retparam4, i8* %lo6, i64 %hi7, i8* %lo11, i64 %hi12) + %not_err13 = icmp eq i64 %30, 0 + br i1 %not_err13, label %after_check14, label %voiderr15 + +after_check14: ; preds = %if.exit + br label %voiderr15 + +voiderr15: ; preds = %after_check14, %if.exit + store %"char[]" { i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.4, i32 0, i32 0), i64 2 }, %"char[]"* %taddr17, align 8 + %31 = bitcast %"char[]"* %taddr17 to { i8*, i64 }* + %32 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %31, i32 0, i32 0 + %lo18 = load i8*, i8** %32, align 8 + %33 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %31, i32 0, i32 1 + %hi19 = load i64, i64* %33, align 8 + store i64 6, i64* %taddr22, align 8 + %34 = bitcast i64* %taddr22 to i8* + %35 = insertvalue %variant undef, i8* %34, 0 + %36 = insertvalue %variant %35, i64 ptrtoint (%.introspect* @"ct$long" to i64), 1 + %37 = getelementptr inbounds [1 x %variant], [1 x %variant]* %varargslots21, i64 0, i64 0 + store %variant %36, %variant* %37, align 16 + %38 = getelementptr inbounds %"variant[]", %"variant[]"* %vararg20, i32 0, i32 1 + store i64 1, i64* %38, align 8 + %39 = getelementptr inbounds %"variant[]", %"variant[]"* %vararg20, i32 0, i32 0 + %40 = bitcast [1 x %variant]* %varargslots21 to %variant* + store %variant* %40, %variant** %39, align 8 + %41 = bitcast %"variant[]"* %vararg20 to { i8*, i64 }* + %42 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %41, i32 0, i32 0 + %lo23 = load i8*, i8** %42, align 8 + %43 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %41, i32 0, i32 1 + %hi24 = load i64, i64* %43, align 8 + %44 = call i64 @std_io_printfln(i64* %retparam16, i8* %lo18, i64 %hi19, i8* %lo23, i64 %hi24) + %not_err25 = icmp eq i64 %44, 0 + br i1 %not_err25, label %after_check26, label %voiderr27 + +after_check26: ; preds = %voiderr15 + br label %voiderr27 + +voiderr27: ; preds = %after_check26, %voiderr15 + %45 = call i32 @std_io_println(i8* getelementptr inbounds ([24 x i8], [24 x i8]* @.str.5, i32 0, i32 0)) #1 + %46 = call i32 @std_io_println(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.6, i32 0, i32 0)) #1 + ret void +} diff --git a/test/test_suite/compile_time/ct_funcptr.c3t b/test/test_suite/compile_time/ct_funcptr.c3t index 946a379e3..d20eb10b4 100644 --- a/test/test_suite/compile_time/ct_funcptr.c3t +++ b/test/test_suite/compile_time/ct_funcptr.c3t @@ -4,7 +4,7 @@ import std::io; fn void test(int x) { - $typeof($$FUNCPTR) ptr = $$FUNCPTR; + $typeof(&$$FUNCTION) ptr = &$$FUNCTION; io::printfln("%d", x); if (x > 0) ptr(x - 1); } diff --git a/test/test_suite2/compile_time/ct_builtin_time_date.c3t b/test/test_suite2/compile_time/ct_builtin_time_date.c3t new file mode 100644 index 000000000..c0e59a2a5 --- /dev/null +++ b/test/test_suite2/compile_time/ct_builtin_time_date.c3t @@ -0,0 +1,139 @@ +// #target: macos-x64 +module test; +import std::io; + +macro printline() +{ + io::printfln("%d", $$LINE); io::printfln("%d", $$LINE_RAW); +} +fn void test(int x) +{ + io::printfln("%d", x); + if (x > 0) $$FUNCTION(x - 1); + io::println($$TIME); + io::println($$DATE); + printline(); + io::println($$FILE); + io::println($$MODULE); +} + +bool is_def = $defined($$FUNCTION); +fn void main() +{ + bool is_def2 = $defined($$FUNCTION); + test(10); +} + +/* #expect: test.ll +target triple = "x86_64-apple-darwin" + +define void @test_test(i32 %0) #0 { +entry: + %retparam = alloca i64, align 8 + %taddr = alloca %"char[]", align 8 + %vararg = alloca %"variant[]", align 8 + %varargslots = alloca [1 x %variant], align 16 + %taddr1 = alloca i32, align 4 + %retparam4 = alloca i64, align 8 + %taddr5 = alloca %"char[]", align 8 + %vararg8 = alloca %"variant[]", align 8 + %varargslots9 = alloca [1 x %variant], align 16 + %taddr10 = alloca i64, align 8 + %retparam16 = alloca i64, align 8 + %taddr17 = alloca %"char[]", align 8 + %vararg20 = alloca %"variant[]", align 8 + %varargslots21 = alloca [1 x %variant], align 16 + %taddr22 = alloca i64, align 8 + store %"char[]" { ptr @.str, i64 2 }, ptr %taddr, align 8 + %1 = getelementptr inbounds { ptr, i64 }, ptr %taddr, i32 0, i32 0 + %lo = load ptr, ptr %1, align 8 + %2 = getelementptr inbounds { ptr, i64 }, ptr %taddr, i32 0, i32 1 + %hi = load i64, ptr %2, align 8 + store i32 %0, ptr %taddr1, align 4 + %3 = insertvalue %variant undef, ptr %taddr1, 0 + %4 = insertvalue %variant %3, i64 ptrtoint (ptr @"ct$int" to i64), 1 + %5 = getelementptr inbounds [1 x %variant], ptr %varargslots, i64 0, i64 0 + store %variant %4, ptr %5, align 16 + %6 = getelementptr inbounds %"variant[]", ptr %vararg, i32 0, i32 1 + store i64 1, ptr %6, align 8 + %7 = getelementptr inbounds %"variant[]", ptr %vararg, i32 0, i32 0 + store ptr %varargslots, ptr %7, align 8 + %8 = getelementptr inbounds { ptr, i64 }, ptr %vararg, i32 0, i32 0 + %lo2 = load ptr, ptr %8, align 8 + %9 = getelementptr inbounds { ptr, i64 }, ptr %vararg, i32 0, i32 1 + %hi3 = load i64, ptr %9, align 8 + %10 = call i64 @std_io_printfln(ptr %retparam, ptr %lo, i64 %hi, ptr %lo2, i64 %hi3) + %not_err = icmp eq i64 %10, 0 + br i1 %not_err, label %after_check, label %voiderr + +after_check: ; preds = %entry + br label %voiderr + +voiderr: ; preds = %after_check, %entry + %gt = icmp sgt i32 %0, 0 + br i1 %gt, label %if.then, label %if.exit + +if.then: ; preds = %voiderr + %sub = sub i32 %0, 1 + call void @test_test(i32 %sub) + br label %if.exit + +if.exit: ; preds = %if.then, %voiderr + %11 = call i32 @std_io_println(ptr @.str.1) #1 + %12 = call i32 @std_io_println(ptr @.str.2) #1 + store %"char[]" { ptr @.str.3, i64 2 }, ptr %taddr5, align 8 + %13 = getelementptr inbounds { ptr, i64 }, ptr %taddr5, i32 0, i32 0 + %lo6 = load ptr, ptr %13, align 8 + %14 = getelementptr inbounds { ptr, i64 }, ptr %taddr5, i32 0, i32 1 + %hi7 = load i64, ptr %14, align 8 + store i64 14, ptr %taddr10, align 8 + %15 = insertvalue %variant undef, ptr %taddr10, 0 + %16 = insertvalue %variant %15, i64 ptrtoint (ptr @"ct$long" to i64), 1 + %17 = getelementptr inbounds [1 x %variant], ptr %varargslots9, i64 0, i64 0 + store %variant %16, ptr %17, align 16 + %18 = getelementptr inbounds %"variant[]", ptr %vararg8, i32 0, i32 1 + store i64 1, ptr %18, align 8 + %19 = getelementptr inbounds %"variant[]", ptr %vararg8, i32 0, i32 0 + store ptr %varargslots9, ptr %19, align 8 + %20 = getelementptr inbounds { ptr, i64 }, ptr %vararg8, i32 0, i32 0 + %lo11 = load ptr, ptr %20, align 8 + %21 = getelementptr inbounds { ptr, i64 }, ptr %vararg8, i32 0, i32 1 + %hi12 = load i64, ptr %21, align 8 + %22 = call i64 @std_io_printfln(ptr %retparam4, ptr %lo6, i64 %hi7, ptr %lo11, i64 %hi12) + %not_err13 = icmp eq i64 %22, 0 + br i1 %not_err13, label %after_check14, label %voiderr15 + +after_check14: ; preds = %if.exit + br label %voiderr15 + +voiderr15: ; preds = %after_check14, %if.exit + store %"char[]" { ptr @.str.4, i64 2 }, ptr %taddr17, align 8 + %23 = getelementptr inbounds { ptr, i64 }, ptr %taddr17, i32 0, i32 0 + %lo18 = load ptr, ptr %23, align 8 + %24 = getelementptr inbounds { ptr, i64 }, ptr %taddr17, i32 0, i32 1 + %hi19 = load i64, ptr %24, align 8 + store i64 6, ptr %taddr22, align 8 + %25 = insertvalue %variant undef, ptr %taddr22, 0 + %26 = insertvalue %variant %25, i64 ptrtoint (ptr @"ct$long" to i64), 1 + %27 = getelementptr inbounds [1 x %variant], ptr %varargslots21, i64 0, i64 0 + store %variant %26, ptr %27, align 16 + %28 = getelementptr inbounds %"variant[]", ptr %vararg20, i32 0, i32 1 + store i64 1, ptr %28, align 8 + %29 = getelementptr inbounds %"variant[]", ptr %vararg20, i32 0, i32 0 + store ptr %varargslots21, ptr %29, align 8 + %30 = getelementptr inbounds { ptr, i64 }, ptr %vararg20, i32 0, i32 0 + %lo23 = load ptr, ptr %30, align 8 + %31 = getelementptr inbounds { ptr, i64 }, ptr %vararg20, i32 0, i32 1 + %hi24 = load i64, ptr %31, align 8 + %32 = call i64 @std_io_printfln(ptr %retparam16, ptr %lo18, i64 %hi19, ptr %lo23, i64 %hi24) + %not_err25 = icmp eq i64 %32, 0 + br i1 %not_err25, label %after_check26, label %voiderr27 + +after_check26: ; preds = %voiderr15 + br label %voiderr27 + +voiderr27: ; preds = %after_check26, %voiderr15 + %33 = call i32 @std_io_println(ptr @.str.5) #1 + %34 = call i32 @std_io_println(ptr @.str.6) #1 + ret void +} diff --git a/test/test_suite2/compile_time/ct_funcptr.c3t b/test/test_suite2/compile_time/ct_funcptr.c3t index 82166656e..4a2467bc3 100644 --- a/test/test_suite2/compile_time/ct_funcptr.c3t +++ b/test/test_suite2/compile_time/ct_funcptr.c3t @@ -4,7 +4,7 @@ import std::io; fn void test(int x) { - $typeof($$FUNCPTR) ptr = $$FUNCPTR; + $typeof(&$$FUNCTION) ptr = &$$FUNCTION; io::printfln("%d", x); if (x > 0) ptr(x - 1); }