mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Compare commits
9 Commits
0.4ubuntu2
...
0.4godbolt
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
266dba466c | ||
|
|
379a5f670f | ||
|
|
8eaad81800 | ||
|
|
4baacc7d52 | ||
|
|
0de47d7c83 | ||
|
|
cfd21f8ca2 | ||
|
|
d0e8944c56 | ||
|
|
3e54d13b62 | ||
|
|
b30d130d92 |
2
.github/workflows/main.yml
vendored
2
.github/workflows/main.yml
vendored
@@ -184,7 +184,7 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
build_type: [Release, Debug]
|
||||
llvm_version: [16]
|
||||
llvm_version: [16, 17]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
@@ -38,6 +38,26 @@ fn void List.tinit(List* list, usz initial_capacity = 16)
|
||||
list.init(initial_capacity, mem::temp()) @inline;
|
||||
}
|
||||
|
||||
fn String List.to_string(List* list, Allocator* using = mem::heap()) @dynamic
|
||||
{
|
||||
if (!list.size) return "[]".copy(using);
|
||||
if (list.size == 1) return string::printf("[%s]", list.entries[0], .using = using);
|
||||
|
||||
@stack_mem(512 + 128; Allocator* mem)
|
||||
{
|
||||
DString str;
|
||||
str.init(512, mem);
|
||||
str.append("[");
|
||||
foreach (i, element : list.entries[:list.size])
|
||||
{
|
||||
if (i != 0) str.append(", ");
|
||||
str.printf("%s", element);
|
||||
}
|
||||
str.printf("]");
|
||||
return str.copy_str(using);
|
||||
};
|
||||
}
|
||||
|
||||
fn void List.push(List* list, Type element) @inline
|
||||
{
|
||||
list.append(element);
|
||||
|
||||
@@ -135,9 +135,9 @@ macro bool! Formatter.print_with_function(Formatter* this, any arg)
|
||||
this.width = old_width;
|
||||
this.prec = old_prec;
|
||||
}
|
||||
@pool()
|
||||
@stack_mem(512; Allocator* mem)
|
||||
{
|
||||
this.out_substr(arg.to_string(mem::temp()))!;
|
||||
this.out_substr(arg.to_string(mem))!;
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -50,18 +50,18 @@ fn void! InetAddress.to_format(InetAddress* addr, Formatter* formatter) @dynamic
|
||||
formatter.printf("%d.%d.%d.%d", addr.ipv4.a, addr.ipv4.b, addr.ipv4.c, addr.ipv4.d)!;
|
||||
}
|
||||
|
||||
fn String! InetAddress.to_string(InetAddress* addr, Allocator* using = mem::heap()) @dynamic
|
||||
fn String InetAddress.to_string(InetAddress* addr, Allocator* using = mem::heap()) @dynamic
|
||||
{
|
||||
if (addr.is_ipv6)
|
||||
{
|
||||
char[8 * 5 + 1] buffer;
|
||||
String res = (String)io::bprintf(&buffer, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x",
|
||||
addr.ipv6.a, addr.ipv6.b, addr.ipv6.c, addr.ipv6.d,
|
||||
addr.ipv6.e, addr.ipv6.f, addr.ipv6.g, addr.ipv6.h)!;
|
||||
addr.ipv6.e, addr.ipv6.f, addr.ipv6.g, addr.ipv6.h)!!;
|
||||
return res.copy(using);
|
||||
}
|
||||
char[3 * 4 + 3 + 1] buffer;
|
||||
String res = (String)io::bprintf(&buffer, "%d.%d.%d.%d", addr.ipv4.a, addr.ipv4.b, addr.ipv4.c, addr.ipv4.d)!;
|
||||
String res = (String)io::bprintf(&buffer, "%d.%d.%d.%d", addr.ipv4.a, addr.ipv4.b, addr.ipv4.c, addr.ipv4.d)!!;
|
||||
return res.copy(using);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ module std::thread::os;
|
||||
|
||||
$if thread::THREAD_MODEL == ThreadModel.WIN32:
|
||||
|
||||
typedef NativeThread = Win32_HANDLE;
|
||||
def NativeThread = Win32_HANDLE;
|
||||
|
||||
struct NativeMutex
|
||||
{
|
||||
|
||||
@@ -8,8 +8,8 @@ struct Darwin_mach_timebase_info
|
||||
uint denom;
|
||||
}
|
||||
|
||||
typedef Darwin_mach_timebase_info_t = Darwin_mach_timebase_info;
|
||||
typedef Darwin_mach_timebase_info_data_t = Darwin_mach_timebase_info;
|
||||
def Darwin_mach_timebase_info_t = Darwin_mach_timebase_info;
|
||||
def Darwin_mach_timebase_info_data_t = Darwin_mach_timebase_info;
|
||||
|
||||
extern fn void mach_timebase_info(Darwin_mach_timebase_info_data_t* timebase);
|
||||
extern fn ulong mach_absolute_time();
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
module std::time;
|
||||
|
||||
typedef Time @inline = distinct long;
|
||||
typedef TimeDuration @inline = distinct long;
|
||||
typedef Clock @inline = distinct ulong;
|
||||
typedef NanoDuration @inline = distinct long;
|
||||
def Time @inline = distinct long;
|
||||
def TimeDuration @inline = distinct long;
|
||||
def Clock @inline = distinct ulong;
|
||||
def NanoDuration @inline = distinct long;
|
||||
|
||||
const TimeDuration MICROSECONDS_PER_SECOND = 1_000_000;
|
||||
const TimeDuration MICROSECONDS_PER_MINUTE = MICROSECONDS_PER_SECOND * 60;
|
||||
|
||||
@@ -95,9 +95,9 @@ int comment_level = 0;
|
||||
"char" { count(); return(CHAR); }
|
||||
"const" { count(); return(CONST); }
|
||||
"continue" { count(); return(CONTINUE); }
|
||||
"def" { count(); return(DEF); }
|
||||
"default" { count(); return(DEFAULT); }
|
||||
"defer" { count(); return(DEFER); }
|
||||
"define" { count(); return(DEFINE); }
|
||||
"distinct" { count(); return(DISTINCT); }
|
||||
"do" { count(); return(DO); }
|
||||
"double" { count(); return(DOUBLE); }
|
||||
@@ -137,7 +137,6 @@ int comment_level = 0;
|
||||
"tlocal" { count(); return(TLOCAL); }
|
||||
"true" { count(); return(TRUE); }
|
||||
"try" { count(); return(TRY); }
|
||||
"typedef" { count(); return(TYPEDEF); }
|
||||
"typeid" { count(); return(TYPEID); }
|
||||
"uint" { count(); return(UINT); }
|
||||
"uint128" { count(); return(UINT128); }
|
||||
|
||||
@@ -17,7 +17,7 @@ void yyerror(char *s);
|
||||
%token AND_OP OR_OP MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN
|
||||
%token SUB_ASSIGN SHL_ASSIGN SHR_ASSIGN AND_ASSIGN
|
||||
%token XOR_ASSIGN OR_ASSIGN VAR NUL ELVIS NEXTCASE ANYFAULT
|
||||
%token TYPEDEF MODULE IMPORT DEFINE EXTERN
|
||||
%token MODULE IMPORT DEF EXTERN
|
||||
%token CHAR SHORT INT LONG FLOAT DOUBLE CONST VOID USZ ISZ UPTR IPTR ANY
|
||||
%token ICHAR USHORT UINT ULONG BOOL INT128 UINT128 FLOAT16 FLOAT128 BFLOAT16
|
||||
%token TYPEID BITSTRUCT STATIC BANGBANG AT_CONST_IDENT HASH_TYPE_IDENT
|
||||
@@ -1110,9 +1110,6 @@ typedef_type
|
||||
| type opt_generic_parameters
|
||||
;
|
||||
|
||||
typedef_declaration
|
||||
: TYPEDEF TYPE_IDENT opt_attributes '=' opt_distinct_inline typedef_type ';'
|
||||
;
|
||||
|
||||
|
||||
multi_declaration
|
||||
@@ -1166,8 +1163,9 @@ define_ident
|
||||
;
|
||||
|
||||
define_declaration
|
||||
: DEFINE define_ident ';'
|
||||
| DEFINE define_attribute ';'
|
||||
: DEF define_ident ';'
|
||||
| DEF define_attribute ';'
|
||||
| DEF TYPE_IDENT opt_attributes '=' opt_distinct_inline typedef_type ';'
|
||||
;
|
||||
|
||||
tl_ct_if
|
||||
@@ -1233,7 +1231,6 @@ top_level
|
||||
| fault_declaration
|
||||
| enum_declaration
|
||||
| macro_declaration
|
||||
| typedef_declaration
|
||||
| define_declaration
|
||||
| static_declaration
|
||||
| bitstruct_declaration
|
||||
|
||||
@@ -231,8 +231,8 @@ fn void hello() throws Errors
|
||||
return;
|
||||
}
|
||||
|
||||
typedef Foo* as Bar;
|
||||
typedef fn void(int, Foo*) as Zoo;
|
||||
def Foo* as Bar;
|
||||
def fn void(int, Foo*) as Zoo;
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ const uint SDL_WINDOWPOS_UNDEFINED = UndefinedDisplay(x);
|
||||
#define SDL_WINDOWPOS_ISCENTERED(X) \
|
||||
(((X)&0xFFFF0000) == SDL_WINDOWPOS_CENTERED_MASK)
|
||||
|
||||
typedef enum
|
||||
def enum
|
||||
{
|
||||
SDL_ORIENTATION_UNKNOWN, /**< The display orientation can't be determined */
|
||||
SDL_ORIENTATION_LANDSCAPE, /**< The display is in landscape mode, with the right side up, relative to portrait mode */
|
||||
@@ -115,7 +115,7 @@ typedef enum
|
||||
/**
|
||||
* \brief An opaque handle to an OpenGL context.
|
||||
*/
|
||||
typedef void *SDL_GLContext;
|
||||
def void *SDL_GLContext;
|
||||
|
||||
|
||||
enum GLAttr
|
||||
@@ -149,14 +149,14 @@ enum GLAttr
|
||||
GL_CONTEXT_NO_ERROR
|
||||
}
|
||||
|
||||
typedef enum
|
||||
def enum
|
||||
{
|
||||
SDL_GL_CONTEXT_PROFILE_CORE = 0x0001,
|
||||
SDL_GL_CONTEXT_PROFILE_COMPATIBILITY = 0x0002,
|
||||
SDL_GL_CONTEXT_PROFILE_ES = 0x0004 /**< GLX_CONTEXT_ES2_PROFILE_BIT_EXT */
|
||||
} SDL_GLprofile;
|
||||
|
||||
typedef enum
|
||||
def enum
|
||||
{
|
||||
SDL_GL_CONTEXT_DEBUG_FLAG = 0x0001,
|
||||
SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG = 0x0002,
|
||||
@@ -164,13 +164,13 @@ typedef enum
|
||||
SDL_GL_CONTEXT_RESET_ISOLATION_FLAG = 0x0008
|
||||
} SDL_GLcontextFlag;
|
||||
|
||||
typedef enum
|
||||
def enum
|
||||
{
|
||||
SDL_GL_CONTEXT_RELEASE_BEHAVIOR_NONE = 0x0000,
|
||||
SDL_GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH = 0x0001
|
||||
} SDL_GLcontextReleaseFlag;
|
||||
|
||||
typedef enum
|
||||
def enum
|
||||
{
|
||||
SDL_GL_CONTEXT_RESET_NO_NOTIFICATION = 0x0000,
|
||||
SDL_GL_CONTEXT_RESET_LOSE_CONTEXT = 0x0001
|
||||
@@ -810,7 +810,7 @@ extern DECLSPEC int SDLCALL SDL_GetWindowGammaRamp(SDL_Window * window,
|
||||
*
|
||||
* \sa SDL_HitTest
|
||||
*/
|
||||
typedef enum
|
||||
def enum
|
||||
{
|
||||
SDL_HITTEST_NORMAL, /**< Region is normal. No special properties. */
|
||||
SDL_HITTEST_DRAGGABLE, /**< Region can drag entire window. */
|
||||
@@ -829,7 +829,7 @@ typedef enum
|
||||
*
|
||||
* \sa SDL_SetWindowHitTest
|
||||
*/
|
||||
typedef SDL_HitTestResult (SDLCALL *SDL_HitTest)(SDL_Window *win,
|
||||
def SDL_HitTestResult (SDLCALL *SDL_HitTest)(SDL_Window *win,
|
||||
const SDL_Point *area,
|
||||
void *data);
|
||||
|
||||
|
||||
@@ -114,6 +114,8 @@ static void usage(void)
|
||||
OUTPUT(" --emit-llvm - Emit LLVM IR as a .ll file per module.");
|
||||
OUTPUT(" --asm-out <dir> - Override asm output directory for '--emit-asm'.");
|
||||
OUTPUT(" --emit-asm - Emit asm as a .s file per module.");
|
||||
OUTPUT(" --no-obj - Do not output object files, this is only valid for `compile-only`.");
|
||||
OUTPUT(" --no-emit-stdlib - Do not output object files (nor asm or ir) for the standard library.");
|
||||
OUTPUT(" --target <target> - Compile for a particular architecture + OS target.");
|
||||
OUTPUT(" --threads <number> - Set the number of threads to use for compilation.");
|
||||
OUTPUT(" --safe - Set mode to 'safe', generating runtime traps on overflows and contract violations.");
|
||||
@@ -134,7 +136,7 @@ static void usage(void)
|
||||
OUTPUT(" --x86vec=<option> - Set max type of vector use: none, mmx, sse, avx, avx512, native.");
|
||||
OUTPUT(" --riscvfloat=<option> - Set type of RISC-V float support: none, float, double");
|
||||
OUTPUT(" --memory-env=<option> - Set the memory environment: normal, small, tiny, none.");
|
||||
OUTPUT(" --strip-unused - Strip unused code and globals from the output (experimental)");
|
||||
OUTPUT(" --no-strip-unused - Do not strip unused code and globals from the output.");
|
||||
OUTPUT("");
|
||||
OUTPUT(" --debug-stats - Print debug statistics.");
|
||||
#ifndef NDEBUG
|
||||
@@ -159,7 +161,11 @@ static void usage(void)
|
||||
OUTPUT(" --wincrt=<option> - Windows CRT linking: none, static, dynamic (default).");
|
||||
OUTPUT("");
|
||||
OUTPUT(" --macossdk <dir> - Set the directory for the MacOS SDK for cross compilation.");
|
||||
|
||||
OUTPUT(" --macos-min-version <ver> - Set the minimum MacOS version to compile for.");
|
||||
OUTPUT(" --macos-sdk-version <ver> - Set the MacOS SDK compiled for.");
|
||||
OUTPUT("");
|
||||
OUTPUT(" --linux-crt <dir> - Set the directory to use for finding crt1.o and related files.");
|
||||
OUTPUT(" --linux-crtbegin <dir> - Set the directory to use for finding crtbegin.o and related files.");
|
||||
}
|
||||
|
||||
|
||||
@@ -545,9 +551,9 @@ static void parse_option(BuildOptions *options)
|
||||
print_version();
|
||||
exit_compiler(COMPILER_SUCCESS_EXIT);
|
||||
}
|
||||
if (match_longopt("strip-unused"))
|
||||
if (match_longopt("no-strip-unused"))
|
||||
{
|
||||
options->strip_unused = true;
|
||||
options->no_strip_unused = true;
|
||||
return;
|
||||
}
|
||||
if ((argopt = match_argopt("x86vec")))
|
||||
@@ -581,6 +587,16 @@ static void parse_option(BuildOptions *options)
|
||||
OUTPUT("C3 is low level programming language based on C.");
|
||||
exit_compiler(COMPILER_SUCCESS_EXIT);
|
||||
}
|
||||
if (match_longopt("no-obj"))
|
||||
{
|
||||
options->no_obj = true;
|
||||
return;
|
||||
}
|
||||
if (match_longopt("no-emit-stdlib"))
|
||||
{
|
||||
options->no_emit_stdlib = true;
|
||||
return;
|
||||
}
|
||||
if (match_longopt("debug-log"))
|
||||
{
|
||||
debug_log = true;
|
||||
@@ -807,6 +823,18 @@ static void parse_option(BuildOptions *options)
|
||||
options->path = check_dir(next_arg());
|
||||
return;
|
||||
}
|
||||
if (match_longopt("linux-crt"))
|
||||
{
|
||||
if (at_end() || next_is_opt()) error_exit("error: --linux-crt needs a directory.");
|
||||
options->linuxpaths.crt = check_dir(next_arg());
|
||||
return;
|
||||
}
|
||||
if (match_longopt("linux-crtbegin"))
|
||||
{
|
||||
if (at_end() || next_is_opt()) error_exit("error: --linux-crtbegin needs a directory.");
|
||||
options->linuxpaths.crtbegin = check_dir(next_arg());
|
||||
return;
|
||||
}
|
||||
if (match_longopt("safe"))
|
||||
{
|
||||
options->safe_mode = 1;
|
||||
@@ -855,7 +883,6 @@ BuildOptions parse_arguments(int argc, const char *argv[])
|
||||
BuildOptions build_options = {
|
||||
.path = ".",
|
||||
.emit_llvm = false,
|
||||
.emit_bitcode = true,
|
||||
.optimization_setting_override = OPT_SETTING_NOT_SET,
|
||||
.debug_info_override = DEBUG_INFO_NOT_SET,
|
||||
.safe_mode = -1,
|
||||
|
||||
@@ -297,6 +297,10 @@ typedef struct BuildOptions_
|
||||
const char *min_version;
|
||||
const char *sdk_version;
|
||||
} macos;
|
||||
struct {
|
||||
const char *crt;
|
||||
const char *crtbegin;
|
||||
} linuxpaths;
|
||||
int build_threads;
|
||||
const char** libraries_to_fetch;
|
||||
const char** files;
|
||||
@@ -317,11 +321,12 @@ typedef struct BuildOptions_
|
||||
int safe_mode;
|
||||
bool emit_llvm;
|
||||
bool emit_asm;
|
||||
bool emit_bitcode;
|
||||
bool test_mode;
|
||||
bool no_stdlib;
|
||||
bool no_entry;
|
||||
bool no_libc;
|
||||
bool no_obj;
|
||||
bool no_emit_stdlib;
|
||||
bool force_linker;
|
||||
bool read_stdin;
|
||||
bool print_output;
|
||||
@@ -336,7 +341,7 @@ typedef struct BuildOptions_
|
||||
X86CpuSet x86_cpu_set;
|
||||
RiscvFloatCapability riscv_float_capability;
|
||||
MemoryEnvironment memory_environment;
|
||||
bool strip_unused;
|
||||
bool no_strip_unused;
|
||||
bool print_keywords;
|
||||
bool print_attributes;
|
||||
bool print_builtins;
|
||||
@@ -410,7 +415,7 @@ typedef struct
|
||||
bool emit_asm;
|
||||
bool no_stdlib;
|
||||
bool no_libc;
|
||||
bool strip_unused;
|
||||
bool no_strip_unused;
|
||||
bool emit_object_files;
|
||||
bool force_linker;
|
||||
bool benchmarking;
|
||||
@@ -418,6 +423,7 @@ typedef struct
|
||||
bool read_stdin;
|
||||
bool print_output;
|
||||
bool no_entry;
|
||||
bool no_emit_stdlib;
|
||||
int build_threads;
|
||||
OptimizationLevel optimization_level;
|
||||
MemoryEnvironment memory_environment;
|
||||
@@ -456,6 +462,11 @@ typedef struct
|
||||
WinCrtLinking crt_linking;
|
||||
bool use_win_subsystem;
|
||||
} win;
|
||||
struct
|
||||
{
|
||||
const char *crt;
|
||||
const char *crtbegin;
|
||||
} linuxpaths;
|
||||
} BuildTarget;
|
||||
|
||||
|
||||
|
||||
@@ -199,7 +199,7 @@ static void update_build_target_from_options(BuildTarget *target, BuildOptions *
|
||||
{
|
||||
target->feature.safe_mode = options->safe_mode == 1;
|
||||
}
|
||||
if (options->strip_unused) target->strip_unused = true;
|
||||
if (options->no_strip_unused || options->test_mode) target->no_strip_unused = true;
|
||||
|
||||
if (options->memory_environment != MEMORY_ENV_NOT_SET)
|
||||
{
|
||||
@@ -243,6 +243,8 @@ static void update_build_target_from_options(BuildTarget *target, BuildOptions *
|
||||
if (options->macos.min_version) target->macos.min_version = options->macos.min_version;
|
||||
if (options->macos.sdk_version) target->macos.sdk_version = options->macos.sdk_version;
|
||||
if (options->win.crt_linking != WIN_CRT_DEFAULT) target->win.crt_linking = options->win.crt_linking;
|
||||
if (options->linuxpaths.crt) target->linuxpaths.crt = options->linuxpaths.crt;
|
||||
if (options->linuxpaths.crtbegin) target->linuxpaths.crtbegin = options->linuxpaths.crtbegin;
|
||||
if (options->x86_vector_capability != X86VECTOR_DEFAULT)
|
||||
{
|
||||
target->feature.x86_vector_capability = options->x86_vector_capability;
|
||||
@@ -300,6 +302,11 @@ static void update_build_target_from_options(BuildTarget *target, BuildOptions *
|
||||
target->emit_asm = false;
|
||||
target->emit_object_files = false;
|
||||
}
|
||||
if (options->no_obj)
|
||||
{
|
||||
target->emit_object_files = false;
|
||||
}
|
||||
target->no_emit_stdlib = options->no_emit_stdlib;
|
||||
for (int i = 0; i < options->lib_dir_count; i++)
|
||||
{
|
||||
vec_add(target->libdirs, options->lib_dir[i]);
|
||||
|
||||
@@ -374,6 +374,12 @@ static void load_into_build_target(JSONObject *json, const char *type, BuildTarg
|
||||
// macos-sdk-version
|
||||
target->macos.sdk_version = get_valid_string(json, "macos-sdk-version", type, false);
|
||||
|
||||
// Linux crt
|
||||
target->linuxpaths.crt = get_valid_string(json, "linux-crt", type, false);
|
||||
|
||||
// Linux crtbegin
|
||||
target->linuxpaths.crtbegin = get_valid_string(json, "linux-crtbegin", type, false);
|
||||
|
||||
// version
|
||||
const char *version = get_valid_string(json, "version", type, false);
|
||||
if (version) target->version = version;
|
||||
|
||||
@@ -432,8 +432,7 @@ void compiler_compile(void)
|
||||
}
|
||||
else if (task_count > 1)
|
||||
{
|
||||
TaskQueueRef queue = taskqueue_create(active_target.build_threads > task_count ? task_count : active_target.build_threads, tasks);
|
||||
taskqueue_wait_for_completion(queue);
|
||||
taskqueue_run(active_target.build_threads > task_count ? task_count : active_target.build_threads, tasks);
|
||||
}
|
||||
|
||||
if (active_target.print_output)
|
||||
@@ -485,21 +484,29 @@ void compiler_compile(void)
|
||||
printf("Program finished with exit code %d.\n", ret);
|
||||
}
|
||||
}
|
||||
if (output_static)
|
||||
else if (output_static)
|
||||
{
|
||||
if (!static_lib_linker(output_static, obj_files, output_file_count))
|
||||
{
|
||||
error_exit("Failed to produce static library '%s'.", output_static);
|
||||
}
|
||||
compiler_link_time = bench_mark();
|
||||
compiler_print_bench();
|
||||
printf("Static library '%s' created.", output_static);
|
||||
}
|
||||
if (output_dynamic)
|
||||
else if (output_dynamic)
|
||||
{
|
||||
if (!dynamic_lib_linker(output_dynamic, obj_files, output_file_count))
|
||||
{
|
||||
error_exit("Failed to produce static library '%s'.", output_dynamic);
|
||||
}
|
||||
printf("Dynamic library '%s' created.", output_dynamic);
|
||||
compiler_link_time = bench_mark();
|
||||
compiler_print_bench();
|
||||
}
|
||||
else
|
||||
{
|
||||
compiler_print_bench();
|
||||
}
|
||||
free(obj_files);
|
||||
}
|
||||
|
||||
@@ -286,7 +286,7 @@ static void linker_setup_macos(const char ***args_ref, LinkerType linker_type)
|
||||
}
|
||||
add_arg("-arch");
|
||||
add_arg(arch_to_linker_arch(platform_target.arch));
|
||||
if (active_target.strip_unused && active_target.type == TARGET_TYPE_EXECUTABLE)
|
||||
if (!active_target.no_strip_unused && active_target.type == TARGET_TYPE_EXECUTABLE)
|
||||
{
|
||||
add_arg("-no_exported_symbols");
|
||||
add_arg("-dead_strip");
|
||||
@@ -340,6 +340,7 @@ static const char *find_freebsd_crt(void)
|
||||
|
||||
static const char *find_linux_crt(void)
|
||||
{
|
||||
if (active_target.linuxpaths.crt) return active_target.linuxpaths.crt;
|
||||
#if PLATFORM_POSIX
|
||||
glob_t globbuf;
|
||||
if (!glob("/usr/lib/*/crt1.o", 0, NULL, &globbuf) && globbuf.gl_pathc)
|
||||
@@ -362,6 +363,7 @@ static const char *find_linux_crt(void)
|
||||
|
||||
static const char *find_linux_crt_begin(void)
|
||||
{
|
||||
if (active_target.linuxpaths.crtbegin) return active_target.linuxpaths.crtbegin;
|
||||
#if PLATFORM_POSIX
|
||||
glob_t globbuf;
|
||||
if (!glob("/usr/lib/gcc/*/*/crtbegin.o", 0, NULL, &globbuf) && globbuf.gl_pathc)
|
||||
@@ -396,9 +398,9 @@ static void linker_setup_linux(const char ***args_ref, LinkerType linker_type)
|
||||
const char *crt_begin_dir = find_linux_crt_begin();
|
||||
const char *crt_dir = find_linux_crt();
|
||||
|
||||
if (active_target.strip_unused && active_target.type == TARGET_TYPE_EXECUTABLE)
|
||||
if (!active_target.no_strip_unused && active_target.type == TARGET_TYPE_EXECUTABLE)
|
||||
{
|
||||
add_arg("-dead_strip");
|
||||
add_arg("--gc-sections");
|
||||
}
|
||||
|
||||
if (!crt_begin_dir || !crt_dir)
|
||||
@@ -446,9 +448,9 @@ static void linker_setup_freebsd(const char ***args_ref, LinkerType linker_type)
|
||||
{
|
||||
error_exit("Failed to find the C runtime at link time.");
|
||||
}
|
||||
if (active_target.strip_unused && active_target.type == TARGET_TYPE_EXECUTABLE)
|
||||
if (!active_target.no_strip_unused && active_target.type == TARGET_TYPE_EXECUTABLE)
|
||||
{
|
||||
add_arg("-dead_strip");
|
||||
add_arg("--gc-sections");
|
||||
}
|
||||
|
||||
if (is_pie_pic(platform_target.reloc_model))
|
||||
|
||||
@@ -1265,9 +1265,21 @@ LLVMMetadataRef llvm_get_debug_file(GenContext *c, FileId file_id)
|
||||
return file;
|
||||
}
|
||||
|
||||
static bool module_is_stdlib(Module *module)
|
||||
{
|
||||
if (module->name->len < 3) return false;
|
||||
if (module->name->len == 3 && strcmp(module->name->module, "std") == 0) return true;
|
||||
if (module->name->len > 5 && memcmp(module->name->module, "std::", 5) == 0) return true;
|
||||
if (module->name->len == 4 && strcmp(module->name->module, "libc") == 0) return true;
|
||||
if (module->name->len > 6 && memcmp(module->name->module, "libc::", 6) == 0) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static GenContext *llvm_gen_module(Module *module, LLVMContextRef shared_context)
|
||||
{
|
||||
if (!vec_size(module->units)) return NULL;
|
||||
if (active_target.no_emit_stdlib && module_is_stdlib(module)) return NULL;
|
||||
|
||||
assert(intrinsics_setup);
|
||||
|
||||
bool has_elements = false;
|
||||
@@ -1275,7 +1287,7 @@ static GenContext *llvm_gen_module(Module *module, LLVMContextRef shared_context
|
||||
gencontext_init(gen_context, module, shared_context);
|
||||
gencontext_begin_module(gen_context);
|
||||
|
||||
bool only_used = active_target.strip_unused && !active_target.testing;
|
||||
bool only_used = !active_target.no_strip_unused;
|
||||
|
||||
FOREACH_BEGIN(CompilationUnit *unit, module->units)
|
||||
|
||||
@@ -1296,10 +1308,12 @@ static GenContext *llvm_gen_module(Module *module, LLVMContextRef shared_context
|
||||
FOREACH_END();
|
||||
|
||||
FOREACH_BEGIN(Decl *type_decl, unit->types)
|
||||
if (only_used && !type_decl->is_live) continue;
|
||||
llvm_emit_type_decls(gen_context, type_decl);
|
||||
FOREACH_END();
|
||||
|
||||
FOREACH_BEGIN(Decl *enum_decl, unit->enums)
|
||||
if (only_used && !enum_decl->is_live) continue;
|
||||
llvm_emit_type_decls(gen_context, enum_decl);
|
||||
FOREACH_END();
|
||||
|
||||
@@ -1384,8 +1398,6 @@ static GenContext *llvm_gen_module(Module *module, LLVMContextRef shared_context
|
||||
|
||||
llvm_emit_constructors_and_destructors(gen_context);
|
||||
|
||||
// EmitDeferred()
|
||||
|
||||
if (llvm_use_debug(gen_context))
|
||||
{
|
||||
LLVMDIBuilderFinalize(gen_context->debug.builder);
|
||||
|
||||
@@ -1745,7 +1745,11 @@ static inline void decl_add_type(Decl *decl, TypeKind kind)
|
||||
*/
|
||||
static inline Decl *parse_typedef_declaration(ParseContext *c)
|
||||
{
|
||||
if (!try_consume(c, TOKEN_DEF)) advance_and_verify(c, TOKEN_TYPEDEF);
|
||||
if (!try_consume(c, TOKEN_DEF))
|
||||
{
|
||||
sema_warning_at(c->span, "The use of 'typedef' is deprecated, please use 'def'.");
|
||||
advance_and_verify(c, TOKEN_TYPEDEF);
|
||||
}
|
||||
|
||||
Decl *decl = decl_new(DECL_POISONED, symstr(c), c->span);
|
||||
DEBUG_LOG("Parse typedef %s", decl->name);
|
||||
@@ -1849,20 +1853,28 @@ static inline Decl *parse_typedef_declaration(ParseContext *c)
|
||||
static inline Decl *parse_define_ident(ParseContext *c)
|
||||
{
|
||||
// 1. Store the beginning of the "define".
|
||||
if (!try_consume(c, TOKEN_DEF)) advance_and_verify(c, TOKEN_DEFINE);
|
||||
if (!try_consume(c, TOKEN_DEF))
|
||||
{
|
||||
sema_warning_at(c->span, "The use of 'define' is deprecated, please use 'def'.");
|
||||
advance_and_verify(c, TOKEN_DEFINE);
|
||||
}
|
||||
|
||||
// 2. At this point we expect an ident or a const token.
|
||||
// since the Type is handled.
|
||||
TokenType alias_type = c->tok;
|
||||
if (alias_type != TOKEN_IDENT && alias_type != TOKEN_CONST_IDENT && alias_type != TOKEN_AT_IDENT)
|
||||
{
|
||||
if (alias_type == TOKEN_TYPE_IDENT)
|
||||
if (token_is_keyword_ident(alias_type) && alias_type != TOKEN_FN)
|
||||
{
|
||||
SEMA_ERROR_HERE("'%s' is a reserved keyword, try another name.", token_type_to_string(alias_type));
|
||||
}
|
||||
else if (alias_type == TOKEN_TYPE_IDENT)
|
||||
{
|
||||
SEMA_ERROR_HERE("A variable, constant or attribute name was expected here. If you want to define a new type, use 'typedef' instead.");
|
||||
}
|
||||
else
|
||||
{
|
||||
SEMA_ERROR_HERE("A variable, constant or attribute name was expected here.");
|
||||
SEMA_ERROR_HERE("A type, variable, constant or attribute name was expected here.");
|
||||
}
|
||||
return poisoned_decl;
|
||||
}
|
||||
|
||||
@@ -2332,6 +2332,7 @@ static inline bool sema_analyse_func(SemaContext *context, Decl *decl)
|
||||
return false;
|
||||
}
|
||||
global_context.test_func = decl;
|
||||
if (active_target.testing) decl->no_strip = true;
|
||||
}
|
||||
bool is_test = decl->func_decl.attr_test;
|
||||
Signature *sig = &decl->func_decl.signature;
|
||||
|
||||
@@ -178,12 +178,14 @@ static void sema_trace_stmt_liveness(Ast *ast)
|
||||
|
||||
static void sema_trace_const_initializer_liveness(ConstInitializer *const_init)
|
||||
{
|
||||
RETRY:
|
||||
switch (const_init->kind)
|
||||
{
|
||||
case CONST_INIT_ZERO:
|
||||
return;
|
||||
case CONST_INIT_ARRAY_VALUE:
|
||||
UNREACHABLE
|
||||
const_init = const_init->init_array_value.element;
|
||||
goto RETRY;
|
||||
case CONST_INIT_ARRAY_FULL:
|
||||
{
|
||||
bool was_modified = false;
|
||||
@@ -204,8 +206,8 @@ static void sema_trace_const_initializer_liveness(ConstInitializer *const_init)
|
||||
return;
|
||||
}
|
||||
case CONST_INIT_UNION:
|
||||
sema_trace_const_initializer_liveness(const_init->init_union.element);
|
||||
return;
|
||||
const_init = const_init->init_union.element;
|
||||
goto RETRY;
|
||||
case CONST_INIT_STRUCT:
|
||||
{
|
||||
Decl *decl = const_init->type->decl;
|
||||
@@ -353,8 +355,16 @@ RETRY:
|
||||
sema_trace_expr_list_liveness(expr->designated_init_list);
|
||||
return;
|
||||
case EXPR_EXPR_BLOCK:
|
||||
sema_trace_stmt_liveness(astptr(expr->expr_block.first_stmt));
|
||||
{
|
||||
AstId current = expr->expr_block.first_stmt;
|
||||
if (!current) return;
|
||||
do
|
||||
{
|
||||
Ast *value = ast_next(¤t);
|
||||
sema_trace_stmt_liveness(value);
|
||||
} while (current);
|
||||
return;
|
||||
}
|
||||
case EXPR_IDENTIFIER:
|
||||
sema_trace_decl_liveness(expr->identifier_expr.decl);
|
||||
return;
|
||||
@@ -452,10 +462,15 @@ void sema_trace_liveness(void)
|
||||
{
|
||||
sema_trace_decl_liveness(global_context.main);
|
||||
}
|
||||
bool keep_tests = active_target.testing;
|
||||
FOREACH_BEGIN(Decl *function, global_context.method_extensions)
|
||||
if (function->func_decl.attr_dynamic) function->no_strip = true;
|
||||
if (function->is_export || function->no_strip) sema_trace_decl_liveness(function);
|
||||
FOREACH_END();
|
||||
FOREACH_BEGIN(Module *module, global_context.module_list)
|
||||
FOREACH_BEGIN(CompilationUnit *unit, module->units)
|
||||
FOREACH_BEGIN(Decl *function, unit->functions)
|
||||
if (function->is_export || function->no_strip) sema_trace_decl_liveness(function);
|
||||
if (function->is_export || function->no_strip || (function->func_decl.attr_test && keep_tests)) sema_trace_decl_liveness(function);
|
||||
FOREACH_END();
|
||||
FOREACH_BEGIN(Decl *method, unit->methods)
|
||||
if (method->is_export || method->no_strip) sema_trace_decl_liveness(method);
|
||||
@@ -463,26 +478,67 @@ void sema_trace_liveness(void)
|
||||
FOREACH_BEGIN(Decl *var, unit->vars)
|
||||
if (var->is_export || var->no_strip) sema_trace_decl_liveness(var);
|
||||
FOREACH_END();
|
||||
FOREACH_BEGIN(Decl *method, unit->local_method_extensions)
|
||||
if (method->is_export || method->no_strip) sema_trace_decl_liveness(method);
|
||||
FOREACH_END();
|
||||
FOREACH_BEGIN(Decl *xxlizer, unit->xxlizers)
|
||||
sema_trace_decl_liveness(xxlizer);
|
||||
FOREACH_END();
|
||||
FOREACH_END();
|
||||
FOREACH_END();
|
||||
}
|
||||
|
||||
INLINE void sema_trace_type_liveness(Type *type)
|
||||
{
|
||||
if (!type || !type_is_user_defined(type)) return;
|
||||
sema_trace_decl_liveness(type->decl);
|
||||
}
|
||||
|
||||
INLINE void sema_trace_decl_dynamic_methods(Decl *decl)
|
||||
{
|
||||
Decl **methods = decl->methods;
|
||||
unsigned method_count = vec_size(methods);
|
||||
if (!method_count) return;
|
||||
for (unsigned i = 0; i < method_count; i++)
|
||||
{
|
||||
Decl *method = methods[i];
|
||||
if (!method->func_decl.attr_dynamic) continue;
|
||||
sema_trace_decl_liveness(method);
|
||||
}
|
||||
}
|
||||
|
||||
static void sema_trace_decl_liveness(Decl *decl)
|
||||
{
|
||||
RETRY:
|
||||
if (!decl || decl->is_live) return;
|
||||
decl->is_live = true;
|
||||
switch (decl->decl_kind)
|
||||
{
|
||||
case DECL_POISONED:
|
||||
case DECL_ATTRIBUTE:
|
||||
case DECL_BITSTRUCT:
|
||||
case DECL_TYPEDEF:
|
||||
if (!decl->typedef_decl.is_func)
|
||||
{
|
||||
sema_trace_type_liveness(decl->typedef_decl.type_info->type);
|
||||
return;
|
||||
}
|
||||
FOREACH_BEGIN(Decl *param, decl->typedef_decl.function_signature.params)
|
||||
sema_trace_decl_liveness(param);
|
||||
FOREACH_END();
|
||||
sema_trace_type_liveness(typeinfotype(decl->typedef_decl.function_signature.rtype));
|
||||
return;
|
||||
case DECL_DEFINE:
|
||||
decl = decl->define_decl.alias;
|
||||
goto RETRY;
|
||||
case DECL_DISTINCT:
|
||||
case DECL_ENUM:
|
||||
case DECL_ENUM_CONSTANT:
|
||||
case DECL_BITSTRUCT:
|
||||
case DECL_FAULT:
|
||||
case DECL_STRUCT:
|
||||
case DECL_UNION:
|
||||
sema_trace_decl_dynamic_methods(decl);
|
||||
return;
|
||||
case DECL_POISONED:
|
||||
case DECL_ATTRIBUTE:
|
||||
case DECL_ENUM_CONSTANT:
|
||||
case DECL_FAULTVALUE:
|
||||
return;
|
||||
case DECL_CT_CASE:
|
||||
@@ -508,20 +564,27 @@ static void sema_trace_decl_liveness(Decl *decl)
|
||||
{
|
||||
case VARDECL_REWRAPPED:
|
||||
case VARDECL_UNWRAPPED:
|
||||
return;
|
||||
break;
|
||||
case VARDECL_PARAM_EXPR:
|
||||
case VARDECL_PARAM_CT:
|
||||
case VARDECL_PARAM_REF:
|
||||
case VARDECL_PARAM:
|
||||
sema_trace_type_liveness(decl->type);
|
||||
if (decl->var.init_expr && decl->var.init_expr->resolve_status == RESOLVE_DONE)
|
||||
{
|
||||
sema_trace_expr_liveness(decl->var.init_expr);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
sema_trace_type_liveness(decl->type);
|
||||
sema_trace_expr_liveness(decl->var.init_expr);
|
||||
break;
|
||||
}
|
||||
sema_trace_expr_liveness(decl->var.init_expr);
|
||||
return;
|
||||
case DECL_INITIALIZE:
|
||||
case DECL_FINALIZE:
|
||||
sema_trace_stmt_liveness(astptrzero(decl->xxlizer.init));
|
||||
return;
|
||||
case DECL_STRUCT:
|
||||
case DECL_TYPEDEF:
|
||||
case DECL_UNION:
|
||||
return;
|
||||
case DECL_DECLARRAY:
|
||||
UNREACHABLE
|
||||
}
|
||||
|
||||
@@ -2927,6 +2927,49 @@ bool sema_analyse_function_body(SemaContext *context, Decl *func)
|
||||
func->name);
|
||||
return false;
|
||||
}
|
||||
|
||||
Signature any_sig = any->func_decl.signature;
|
||||
Signature this_sig = func->func_decl.signature;
|
||||
Type *any_rtype = typeinfotype(any_sig.rtype);
|
||||
Type *this_rtype = typeinfotype(this_sig.rtype);
|
||||
if (any_rtype->canonical != this_rtype->canonical)
|
||||
{
|
||||
SEMA_ERROR(type_infoptr(this_sig.rtype), "The prototype method has a return type %s, but this function returns %s, they need to match.",
|
||||
type_quoted_error_string(any_rtype), type_quoted_error_string(this_rtype));
|
||||
SEMA_NOTE(type_infoptr(any_sig.rtype), "The interface definition is here.");
|
||||
return false;
|
||||
}
|
||||
Decl **any_params = any_sig.params;
|
||||
Decl **this_params = this_sig.params;
|
||||
unsigned any_param_count = vec_size(any_params);
|
||||
unsigned this_param_count = vec_size(this_params);
|
||||
if (any_param_count != this_param_count)
|
||||
{
|
||||
if (any_param_count > this_param_count)
|
||||
{
|
||||
SEMA_ERROR(func, "This function is missing parameters, %d parameters were expected.", any_param_count);
|
||||
SEMA_NOTE(any_params[this_param_count], "Compare with the interface definition.");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
SEMA_ERROR(this_params[any_param_count], "This function has too many parameters (%d).", this_param_count);
|
||||
SEMA_NOTE(any, "Compare with the interface, which has only %d parameter%s.",
|
||||
any_param_count, any_param_count == 1 ? "" : "s");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
FOREACH_BEGIN_IDX(i, Decl *param, this_params)
|
||||
if (i == 0) continue;
|
||||
if (param->type->canonical != any_params[i]->type->canonical)
|
||||
{
|
||||
SEMA_ERROR(param->var.type_info, "The prototype argument has type %s, but in this function it has type %s. Please make them match.",
|
||||
type_quoted_error_string(any_params[i]->type), type_quoted_error_string(param->type));
|
||||
SEMA_NOTE(any_params[i]->var.type_info, "The interface definition is here.");
|
||||
return false;
|
||||
}
|
||||
|
||||
FOREACH_END();
|
||||
func->func_decl.any_prototype = declid(any);
|
||||
}
|
||||
Signature *signature = &func->func_decl.signature;
|
||||
|
||||
@@ -261,6 +261,8 @@ static void assign_panicfn(void)
|
||||
error_exit("Expected panic function to have the signature fn void(String, String, String, uint).");
|
||||
}
|
||||
global_context.panic_var = decl;
|
||||
decl->no_strip = true;
|
||||
|
||||
if (active_target.no_stdlib) return;
|
||||
|
||||
const char *panicf = "std::core::builtin::panicf";
|
||||
@@ -275,6 +277,8 @@ static void assign_panicfn(void)
|
||||
return;
|
||||
}
|
||||
|
||||
panicf_decl->no_strip = true;
|
||||
|
||||
Type *panicf_fn_type = panicf_decl->type->canonical;
|
||||
if (panicf_decl->decl_kind != DECL_FUNC)
|
||||
{
|
||||
@@ -369,12 +373,13 @@ RESOLVE_LAMBDA:;
|
||||
if (found_lambda) goto RESOLVE_LAMBDA;
|
||||
halt_on_error();
|
||||
|
||||
if (active_target.strip_unused && !active_target.testing)
|
||||
assign_panicfn();
|
||||
|
||||
if (!active_target.no_strip_unused)
|
||||
{
|
||||
sema_trace_liveness();
|
||||
}
|
||||
|
||||
assign_panicfn();
|
||||
|
||||
compiler_sema_time = bench_mark();
|
||||
|
||||
|
||||
@@ -25,6 +25,15 @@ static void cleanup()
|
||||
|
||||
int main_real(int argc, const char *argv[])
|
||||
{
|
||||
printf("------------------------------------------------------------\n"
|
||||
" PLEASE NOTE, this version of the compiler has enabled dead\n"
|
||||
" code stripping by default. This functionality has not been\n"
|
||||
" completely audited, so if you run into any linking error, \n"
|
||||
" please use --no-strip-unused to disable the feature. \n"
|
||||
" If possible, file an error here: \n"
|
||||
" https://github.com/c3lang/c3c/issues\n"
|
||||
" Thank you!\n"
|
||||
"------------------------------------------------------------\n");
|
||||
bench_begin();
|
||||
|
||||
// Setjmp will allow us to add things like fuzzing with
|
||||
|
||||
@@ -57,8 +57,6 @@ typedef struct Task_
|
||||
void *arg;
|
||||
} Task;
|
||||
|
||||
typedef void *TaskQueueRef;
|
||||
|
||||
uint16_t *win_utf8to16(const char *name);
|
||||
char *win_utf16to8(const uint16_t *name);
|
||||
// Use as if it was mkdir(..., 0755) == 0
|
||||
@@ -98,8 +96,7 @@ char *calloc_string(size_t len);
|
||||
void free_arena(void);
|
||||
void print_arena_status(void);
|
||||
void run_arena_allocator_tests(void);
|
||||
TaskQueueRef taskqueue_create(int threads, Task **task_list);
|
||||
void taskqueue_wait_for_completion(TaskQueueRef queue);
|
||||
void taskqueue_run(int threads, Task **task_list);
|
||||
int cpus(void);
|
||||
const char *date_get(void);
|
||||
const char *time_get(void);
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
|
||||
typedef struct TaskQueue_
|
||||
{
|
||||
pthread_t *threads;
|
||||
int thread_count;
|
||||
pthread_mutex_t lock;
|
||||
Task **queue;
|
||||
} TaskQueue;
|
||||
@@ -35,48 +33,80 @@ SHUTDOWN:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
TaskQueueRef taskqueue_create(int threads, Task **task_list)
|
||||
void taskqueue_run(int threads, Task **task_list)
|
||||
{
|
||||
assert(threads > 0);
|
||||
TaskQueue *queue = CALLOCS(TaskQueue);
|
||||
queue->threads = MALLOC(sizeof(pthread_t) * (unsigned)threads);
|
||||
queue->thread_count = threads;
|
||||
queue->queue = task_list;
|
||||
if (pthread_mutex_init(&queue->lock, NULL)) error_exit("Failed to set up mutex");
|
||||
pthread_t *pthreads = malloc(sizeof(pthread_t) * (unsigned)threads);
|
||||
TaskQueue queue = { .queue = task_list };
|
||||
if (pthread_mutex_init(&queue.lock, NULL)) error_exit("Failed to set up mutex");
|
||||
for (int i = 0; i < threads; i++)
|
||||
{
|
||||
if (pthread_create(queue->threads + i, NULL, taskqueue_thread, queue)) error_exit("Fail to set up thread pool");
|
||||
if (pthread_create(&pthreads[i], NULL, taskqueue_thread, &queue)) error_exit("Fail to set up thread pool");
|
||||
}
|
||||
return queue;
|
||||
}
|
||||
|
||||
void taskqueue_wait_for_completion(TaskQueueRef queue_ref)
|
||||
{
|
||||
assert(queue_ref);
|
||||
TaskQueue *queue = queue_ref;
|
||||
for (int i = 0; i < queue->thread_count; i++)
|
||||
for (int i = 0; i < threads; i++)
|
||||
{
|
||||
if (pthread_join(queue->threads[i], NULL) != 0) error_exit("Failed to join thread.");
|
||||
if (pthread_join(pthreads[i], NULL) != 0) error_exit("Failed to join thread.");
|
||||
}
|
||||
pthread_mutex_destroy(&queue->lock);
|
||||
free(pthreads);
|
||||
pthread_mutex_destroy(&queue.lock);
|
||||
}
|
||||
|
||||
#elif PLATFORM_WINDOWS
|
||||
|
||||
#include <Windows.h>
|
||||
#include <process.h>
|
||||
|
||||
typedef struct TaskQueue_
|
||||
{
|
||||
CRITICAL_SECTION lock;
|
||||
Task **queue;
|
||||
} TaskQueue;
|
||||
|
||||
static DWORD WINAPI taskqueue_thread(LPVOID lpParam)
|
||||
{
|
||||
TaskQueue *task_queue = (TaskQueue *)lpParam;
|
||||
bool is_active = false;
|
||||
while (1)
|
||||
{
|
||||
EnterCriticalSection(&task_queue->lock);
|
||||
unsigned task_count = vec_size(task_queue->queue);
|
||||
if (!task_count) goto SHUTDOWN;
|
||||
Task *task = (Task*)task_queue->queue[task_count - 1];
|
||||
vec_pop(task_queue->queue);
|
||||
LeaveCriticalSection(&task_queue->lock);
|
||||
task->task(task->arg);
|
||||
}
|
||||
SHUTDOWN:
|
||||
LeaveCriticalSection(&task_queue->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void taskqueue_run(int threads, Task **task_list)
|
||||
{
|
||||
assert(threads > 0);
|
||||
HANDLE *handles = malloc(sizeof(HANDLE) * (unsigned)threads);
|
||||
TaskQueue queue = { .queue = task_list };
|
||||
InitializeCriticalSection(&queue.lock);
|
||||
for (int i = 0; i < threads; i++)
|
||||
{
|
||||
handles[i] = (HANDLE)_beginthreadex(NULL, 0, taskqueue_thread, &queue, 0, NULL);
|
||||
if (handles[i] == NULL) error_exit("Fail to set up thread pool");
|
||||
}
|
||||
WaitForMultipleObjects(threads, handles, TRUE, INFINITE);
|
||||
|
||||
for (int i = 0; i < threads; i++)
|
||||
{
|
||||
CloseHandle(handles[i]);
|
||||
}
|
||||
free((void*)handles);
|
||||
DeleteCriticalSection(&queue.lock);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void taskqueue_add(TaskQueueRef queue_ref, Task *task)
|
||||
void taskqueue_run(int threads, Task **task_list)
|
||||
{
|
||||
}
|
||||
|
||||
TaskQueueRef taskqueue_create(int threads, Task **tasks)
|
||||
{
|
||||
return tasks;
|
||||
}
|
||||
|
||||
void taskqueue_wait_for_completion(TaskQueueRef queue)
|
||||
{
|
||||
Task **tasks = queue;
|
||||
FOREACH_BEGIN(Task *task, tasks)
|
||||
FOREACH_BEGIN(Task *task, task_list)
|
||||
task->task(task->arg);
|
||||
FOREACH_END();
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
#define COMPILER_VERSION "0.4.518"
|
||||
#define COMPILER_VERSION "0.4.524"
|
||||
@@ -1,7 +1,7 @@
|
||||
// #target: macos-aarch64
|
||||
module test;
|
||||
typedef Int8x16 = ichar[<16>];
|
||||
typedef Float32x3 = float[<3>];
|
||||
def Int8x16 = ichar[<16>];
|
||||
def Float32x3 = float[<3>];
|
||||
|
||||
struct HFAv3
|
||||
{
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// #opt: --x86cpu=avx1
|
||||
module test;
|
||||
|
||||
typedef Mm256 = float[<8>];
|
||||
def Mm256 = float[<8>];
|
||||
struct St256 {
|
||||
Mm256 m;
|
||||
}
|
||||
@@ -19,7 +19,7 @@ fn void f39() { f38(x38); f37(x37); }
|
||||
|
||||
// CHECK: declare void @func40(%struct.t128* byval(%struct.t128) align 16)
|
||||
|
||||
typedef Mm128 = float[<4>];
|
||||
def Mm128 = float[<4>];
|
||||
struct Two128 {
|
||||
Mm128 m;
|
||||
Mm128 n;
|
||||
@@ -44,7 +44,7 @@ fn void func43(Sa s) {
|
||||
}
|
||||
|
||||
|
||||
typedef Vec46 = float[<2>];
|
||||
def Vec46 = float[<2>];
|
||||
extern fn void f46(Vec46,Vec46,Vec46,Vec46,Vec46,Vec46,Vec46,Vec46,Vec46,Vec46);
|
||||
fn void test46() { Vec46 x = {1,2}; f46(x,x,x,x,x,x,x,x,x,x); }
|
||||
|
||||
@@ -69,7 +69,7 @@ fn void test54() {
|
||||
test54_helper(x54, x54, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, Complex { 0, 1.0 });
|
||||
}
|
||||
|
||||
typedef Mm512 = float[<16>];
|
||||
def Mm512 = float[<16>];
|
||||
struct St512 {
|
||||
Mm512 m;
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
// #opt: --x86cpu=avx512
|
||||
module test;
|
||||
|
||||
typedef Mm256 = float[<8>];
|
||||
typedef Mm512 = float[<16>];
|
||||
def Mm256 = float[<8>];
|
||||
def Mm512 = float[<16>];
|
||||
struct St512 {
|
||||
Mm512 m;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// #opt: --x86cpu=sse4
|
||||
module test;
|
||||
|
||||
typedef Mm256 = float[<8>];
|
||||
def Mm256 = float[<8>];
|
||||
struct St256 {
|
||||
Mm256 m;
|
||||
}
|
||||
@@ -19,7 +19,7 @@ fn void f39() { f38(x38); f37(x37); }
|
||||
|
||||
// CHECK: declare void @func40(%struct.t128* byval(%struct.t128) align 16)
|
||||
|
||||
typedef Mm128 = float[<4>];
|
||||
def Mm128 = float[<4>];
|
||||
struct Two128 {
|
||||
Mm128 m;
|
||||
Mm128 n;
|
||||
|
||||
@@ -86,7 +86,7 @@ fn V4f32wrapper f27(V4f32wrapper x) {
|
||||
// PR22563 - We should unwrap simple structs and arrays to pass
|
||||
// and return them in the appropriate vector registers if possible.
|
||||
|
||||
typedef V8f32 = float[<8>];
|
||||
def V8f32 = float[<8>];
|
||||
struct V8f32wrapper {
|
||||
V8f32 v;
|
||||
}
|
||||
@@ -133,15 +133,15 @@ fn float f31(F31foo x) {
|
||||
return x.c;
|
||||
}
|
||||
|
||||
typedef V1i64 = ulong[<1>];
|
||||
def V1i64 = ulong[<1>];
|
||||
|
||||
fn V1i64 f34(V1i64 arg) { return arg; }
|
||||
|
||||
|
||||
typedef V1i64_2 = uint[<2>];
|
||||
def V1i64_2 = uint[<2>];
|
||||
fn V1i64_2 f35(V1i64_2 arg) { return arg+arg; }
|
||||
|
||||
typedef V2i32 = float[<2>];
|
||||
def V2i32 = float[<2>];
|
||||
fn V2i32 f36(V2i32 arg) { return arg; }
|
||||
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ struct Large {
|
||||
long a, b, c, d;
|
||||
}
|
||||
|
||||
typedef V32i8 = char[<32>];
|
||||
def V32i8 = char[<32>];
|
||||
|
||||
fn int f_scalar_stack_1(int a, int128 b, float c, float128 d, V32i8 e,
|
||||
char f, char g, char h) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module abc;
|
||||
|
||||
define @Foo = { @inline };
|
||||
def @Foo = { @inline };
|
||||
|
||||
module bar;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// #target: macos-x64
|
||||
module test;
|
||||
const int FOO @private = 4;
|
||||
define @Align(x) = { @align(x * FOO) };
|
||||
def @Align(x) = { @align(x * FOO) };
|
||||
|
||||
module test2;
|
||||
import test;
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
|
||||
module test;
|
||||
|
||||
define @Foo = { @noreturn @weak };
|
||||
def @Foo = { @noreturn @weak };
|
||||
|
||||
define @Align(y) = { @align(y) };
|
||||
define @Align16(x) @private = { @Align(8 * x) @align(1024) };
|
||||
define @Test = { @noinline };
|
||||
define @TestZero = { };
|
||||
def @Align(y) = { @align(y) };
|
||||
def @Align16(x) @private = { @Align(8 * x) @align(1024) };
|
||||
def @Test = { @noinline };
|
||||
def @TestZero = { };
|
||||
struct Foo
|
||||
{
|
||||
int z;
|
||||
|
||||
@@ -5,8 +5,8 @@ bitstruct Test : int
|
||||
float a : 1..3; // #error: 'float' is not supported in a bitstruct, only enums, integer and boolean values may be used.
|
||||
}
|
||||
|
||||
typedef Baz = distinct float;
|
||||
typedef Foo = distinct bool;
|
||||
def Baz = distinct float;
|
||||
def Foo = distinct bool;
|
||||
enum Boo
|
||||
{
|
||||
BAR
|
||||
|
||||
@@ -22,8 +22,8 @@ fn void test1()
|
||||
$endswitch
|
||||
}
|
||||
|
||||
typedef Foo = int;
|
||||
typedef Bar = double;
|
||||
def Foo = int;
|
||||
def Bar = double;
|
||||
fn void test2()
|
||||
{
|
||||
$switch (int.typeid)
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
module foo;
|
||||
|
||||
// define <name> = <name>
|
||||
// def <name> = <name>
|
||||
def standard_foo = __stdin;
|
||||
def someFunctionIntBool = someFunction<int, bool>;
|
||||
def FooInt = Foo<int>;
|
||||
def A_CONST_INT = A_CONST<int>;
|
||||
|
||||
def standard_foo<int> = ofke; // #error: Expected '='
|
||||
def fn foo = fef; // #error: A variable, constant or attribute name was expected here.
|
||||
def fn foo = fef; // #error: A type, variable, constant or attribute name was expected here
|
||||
def feokfe = fn void(int); // #error: Expected a function or variable name here
|
||||
def AOFKE = ofek; // #error: Expected a constant name here
|
||||
def okfoe = OFKEOK; // #error: Expected a function or variable name here
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
|
||||
typedef int = int; // #error: 'int' is the name of a built-in type and can't be used as an alias.
|
||||
def int = int; // #error: 'int' is a reserved keyword, try another name
|
||||
def main = foo; // #error: 'main' is reserved and cannot be used as an alias.
|
||||
|
||||
typedef hello = int; // #error: uppercase letter
|
||||
typedef hello = Foo; // #error: uppercase letter
|
||||
def hello = int; // #error: uppercase letter
|
||||
def hello = Foo; // #error: uppercase letter
|
||||
|
||||
typedef HELLO = int; // #error: uppercase letter
|
||||
typedef HELLO = Foo; // #error: uppercase letter
|
||||
def HELLO = int; // #error: uppercase letter
|
||||
def HELLO = Foo; // #error: uppercase letter
|
||||
@@ -1,3 +1,3 @@
|
||||
typedef Abc = int[*]; // #error: Inferred array types can only
|
||||
typedef Bcd = anyfault; // #error: 'anyfault' may not be aliased.
|
||||
typedef Efd = any; // #error: 'any' may not be aliased.
|
||||
def Abc = int[*]; // #error: Inferred array types can only
|
||||
def Bcd = anyfault; // #error: 'anyfault' may not be aliased.
|
||||
def Efd = any; // #error: 'any' may not be aliased.
|
||||
|
||||
@@ -3,8 +3,8 @@ fault Error
|
||||
ABC
|
||||
}
|
||||
|
||||
typedef Foo1 = distinct Error; // #error: You cannot create a distinct type
|
||||
def Foo1 = distinct Error; // #error: You cannot create a distinct type
|
||||
|
||||
typedef Foo3 = distinct void; // #error: create a distinct type from 'void'
|
||||
def Foo3 = distinct void; // #error: create a distinct type from 'void'
|
||||
|
||||
typedef Foo4 = distinct typeid; // #error: create a distinct type from 'typeid'
|
||||
def Foo4 = distinct typeid; // #error: create a distinct type from 'typeid'
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
typedef Foo = distinct double[];
|
||||
def Foo = distinct double[];
|
||||
|
||||
fn void main()
|
||||
{
|
||||
|
||||
@@ -5,7 +5,7 @@ struct Struct
|
||||
double y;
|
||||
}
|
||||
|
||||
typedef Foo = distinct Struct;
|
||||
def Foo = distinct Struct;
|
||||
|
||||
struct Struct2
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module test;
|
||||
|
||||
typedef Foo = distinct int;
|
||||
def Foo = distinct int;
|
||||
|
||||
struct Struct
|
||||
{
|
||||
@@ -8,8 +8,8 @@ struct Struct
|
||||
int y;
|
||||
}
|
||||
|
||||
typedef Struct2 = distinct Struct;
|
||||
typedef StructArr = distinct Struct2[3];
|
||||
def Struct2 = distinct Struct;
|
||||
def StructArr = distinct Struct2[3];
|
||||
|
||||
fn void test(int x)
|
||||
{
|
||||
|
||||
@@ -6,7 +6,7 @@ union Union
|
||||
double y;
|
||||
}
|
||||
|
||||
typedef Foo = distinct Union;
|
||||
def Foo = distinct Union;
|
||||
|
||||
union Union2
|
||||
{
|
||||
@@ -19,9 +19,9 @@ union Union2
|
||||
}
|
||||
Foo f = { .x = 1 };
|
||||
|
||||
typedef Union3 = distinct Union2;
|
||||
def Union3 = distinct Union2;
|
||||
|
||||
typedef UnionArr = distinct Union3[3];
|
||||
def UnionArr = distinct Union3[3];
|
||||
|
||||
fn void test(int x)
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module test;
|
||||
|
||||
typedef Int2 = distinct int;
|
||||
def Int2 = distinct int;
|
||||
|
||||
fn void test()
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module test;
|
||||
|
||||
typedef Foo = distinct int;
|
||||
def Foo = distinct int;
|
||||
|
||||
fn int test1()
|
||||
{
|
||||
|
||||
@@ -6,7 +6,7 @@ struct Struct
|
||||
double y;
|
||||
}
|
||||
|
||||
typedef Foo = distinct Struct;
|
||||
def Foo = distinct Struct;
|
||||
|
||||
struct Struct2
|
||||
{
|
||||
|
||||
21
test/test_suite/dynamic/dynamic_mismatch.c3
Normal file
21
test/test_suite/dynamic/dynamic_mismatch.c3
Normal file
@@ -0,0 +1,21 @@
|
||||
fn int any.test(void* a, int ag) @interface;
|
||||
|
||||
struct Foo { int a; }
|
||||
|
||||
fn int! Foo.test(Foo* f) @dynamic { return 1; } // #error: The prototype method has a return type 'int'
|
||||
|
||||
struct Foo1 { int a; }
|
||||
|
||||
fn int Foo1.test(Foo1* f, int a) @dynamic { return 1; }
|
||||
|
||||
struct Foo2 { int a; }
|
||||
|
||||
fn int Foo2.test(Foo2* f) @dynamic { return 1; } // #error: This function is missing parameters, 2
|
||||
|
||||
struct Foo3 { int a; }
|
||||
|
||||
fn int Foo3.test(Foo3* f, double a) @dynamic { return 1; } // #error: The prototype argument has type 'int'
|
||||
|
||||
struct Foo4 { int a; }
|
||||
|
||||
fn int Foo4.test(Foo4* f, double a, int x) @dynamic { return 1; } // #error: This function has too many parameters
|
||||
@@ -60,8 +60,8 @@ fn void test6()
|
||||
int[]* e = &arr[1..2]; // #error: To take the address of a temporary value, use '&&' instead of '&'
|
||||
}
|
||||
|
||||
typedef Baz = Foo;
|
||||
typedef Bar = distinct int;
|
||||
def Baz = Foo;
|
||||
def Bar = distinct int;
|
||||
fault Err { FOO }
|
||||
union Un { int x; }
|
||||
enum MyEnum { BAR }
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
typedef Number = int;
|
||||
def Number = int;
|
||||
|
||||
fn void test1()
|
||||
{
|
||||
|
||||
@@ -2,7 +2,7 @@ enum Foo
|
||||
{
|
||||
ABC
|
||||
}
|
||||
typedef Abc = distinct int;
|
||||
def Abc = distinct int;
|
||||
fn void main()
|
||||
{
|
||||
Abc d = Foo.ABC; // #error: Implicitly casting
|
||||
|
||||
@@ -13,7 +13,7 @@ enum EnumB : char
|
||||
C, D
|
||||
}
|
||||
|
||||
typedef Func = fn void(Enum);
|
||||
def Func = fn void(Enum);
|
||||
|
||||
fn void test1(Enum e)
|
||||
{
|
||||
|
||||
@@ -8,9 +8,9 @@ enum Enum : uptr
|
||||
A, B
|
||||
}
|
||||
|
||||
typedef Func = fn void(int);
|
||||
typedef FuncOther = fn bool(char*);
|
||||
typedef FuncSame = fn void(int);
|
||||
def Func = fn void(int);
|
||||
def FuncOther = fn bool(char*);
|
||||
def FuncSame = fn void(int);
|
||||
|
||||
|
||||
fn void test1(Func arg)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
typedef Number = int;
|
||||
def Number = int;
|
||||
|
||||
fn void test1()
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
typedef Number8 = char;
|
||||
typedef Number32 = int;
|
||||
typedef DNumber32 = distinct int;
|
||||
def Number8 = char;
|
||||
def Number32 = int;
|
||||
def DNumber32 = distinct int;
|
||||
fn void test1()
|
||||
{
|
||||
int a = (ichar)(10);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
typedef Foo = distinct double;
|
||||
typedef Bar = distinct void*;
|
||||
def Foo = distinct double;
|
||||
def Bar = distinct void*;
|
||||
fn int main()
|
||||
{
|
||||
float f = 1;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module test;
|
||||
|
||||
typedef Foo = distinct int;
|
||||
def Foo = distinct int;
|
||||
|
||||
fn void test1()
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
typedef Callback = fn int(char c);
|
||||
def Callback = fn int(char c);
|
||||
struct Person { int i; }
|
||||
struct Company { int j; }
|
||||
enum Status : int
|
||||
|
||||
@@ -65,8 +65,8 @@ fn int Foo2.mutate(Foo2 *foo)
|
||||
return ++foo.x;
|
||||
}
|
||||
|
||||
define oopsInt = test2::argh<int>;
|
||||
define oopsDouble = test2::argh<int>;
|
||||
def oopsInt = test2::argh<int>;
|
||||
def oopsDouble = test2::argh<int>;
|
||||
typedef Argh = fn int(double, Bobo);
|
||||
typedef Argh2 = fn int(double, Bobo);
|
||||
|
||||
@@ -95,12 +95,12 @@ struct Foo
|
||||
int b;
|
||||
}
|
||||
|
||||
define getValueInt = test2::getValue<int>;
|
||||
define getValueDouble = test2::getValue<double>;
|
||||
def getValueInt = test2::getValue<int>;
|
||||
def getValueDouble = test2::getValue<double>;
|
||||
typedef IntBlob = test2::Blob<int>;
|
||||
typedef DoubleBlob = Blob<double>;
|
||||
define getMultInt = test2::getMult<int>;
|
||||
define getMultDouble = test2::getMult<double>;
|
||||
def getMultInt = test2::getMult<int>;
|
||||
def getMultDouble = test2::getMult<double>;
|
||||
|
||||
typedef IntArray = List<int>;
|
||||
typedef IntList = LinkedList<int>;
|
||||
@@ -173,7 +173,7 @@ module hello_world;
|
||||
import foo;
|
||||
|
||||
extern fn int printf(char *, ...);
|
||||
define doubleMult = foo::check<double>;
|
||||
def doubleMult = foo::check<double>;
|
||||
|
||||
fn void hello()
|
||||
{
|
||||
@@ -219,8 +219,8 @@ macro Hello wut()
|
||||
}
|
||||
|
||||
typedef Bye = Hello;
|
||||
define wat = wut;
|
||||
define byebye = hello;
|
||||
def wat = wut;
|
||||
def byebye = hello;
|
||||
|
||||
fn int hello()
|
||||
{
|
||||
|
||||
@@ -67,8 +67,8 @@ fn int Foo2.mutate(Foo2 *foo)
|
||||
|
||||
|
||||
|
||||
define oopsInt = test2::argh<int>;
|
||||
define oopsDouble = test2::argh<int>;
|
||||
def oopsInt = test2::argh<int>;
|
||||
def oopsDouble = test2::argh<int>;
|
||||
typedef Argh = fn int(double, Bobo);
|
||||
typedef Argh2 = fn int(double, Bobo);
|
||||
|
||||
@@ -97,12 +97,12 @@ struct Foo
|
||||
int b;
|
||||
}
|
||||
|
||||
define getValueInt = test2::getValue<int>;
|
||||
define getValueDouble = test2::getValue<double>;
|
||||
def getValueInt = test2::getValue<int>;
|
||||
def getValueDouble = test2::getValue<double>;
|
||||
typedef IntBlob = test2::Blob<int>;
|
||||
typedef DoubleBlob = Blob<double>;
|
||||
define getMultInt = test2::getMult<int>;
|
||||
define getMultDouble = test2::getMult<double>;
|
||||
def getMultInt = test2::getMult<int>;
|
||||
def getMultDouble = test2::getMult<double>;
|
||||
|
||||
typedef IntArray = List<int>;
|
||||
typedef IntList = LinkedList<int>;
|
||||
@@ -175,7 +175,7 @@ module hello_world;
|
||||
import foo;
|
||||
|
||||
extern fn int printf(char *, ...);
|
||||
define doubleMult = foo::check<double>;
|
||||
def doubleMult = foo::check<double>;
|
||||
|
||||
fn void hello()
|
||||
{
|
||||
@@ -221,8 +221,8 @@ macro Hello wut()
|
||||
}
|
||||
|
||||
typedef Bye = Hello;
|
||||
define wat = wut;
|
||||
define byebye = hello;
|
||||
def wat = wut;
|
||||
def byebye = hello;
|
||||
|
||||
fn int hello()
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import std::io;
|
||||
typedef Tester = fn int(int x, int y, int z);
|
||||
def Tester = fn int(int x, int y, int z);
|
||||
|
||||
fn int test1(
|
||||
int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, // 20
|
||||
|
||||
@@ -9,4 +9,4 @@ fn void abc()
|
||||
module tester;
|
||||
import foo;
|
||||
|
||||
define abc_my = foo::abc<int>;
|
||||
def abc_my = foo::abc<int>;
|
||||
@@ -2,7 +2,7 @@
|
||||
module test;
|
||||
import bar;
|
||||
|
||||
typedef BazTest = Baz<Test>;
|
||||
def BazTest = Baz<Test>;
|
||||
|
||||
struct Test // #error: Recursive definition of 'Test'
|
||||
{
|
||||
|
||||
@@ -13,8 +13,8 @@ fn Type addMult(Type x, Type a, Type b)
|
||||
module test;
|
||||
import gen;
|
||||
|
||||
define intMult = gen::mult<int>;
|
||||
define doubleAddMult = gen::addMult<double>;
|
||||
def intMult = gen::mult<int>;
|
||||
def doubleAddMult = gen::addMult<double>;
|
||||
|
||||
fn int getIt(int i)
|
||||
{
|
||||
|
||||
@@ -8,7 +8,7 @@ fn Type x(Type t)
|
||||
|
||||
module test;
|
||||
import hello;
|
||||
define xint = hello::x<int, -123>;
|
||||
def xint = hello::x<int, -123>;
|
||||
|
||||
import std::io;
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ struct An3
|
||||
An2 y;
|
||||
}
|
||||
|
||||
typedef AnCall = fn void();
|
||||
def AnCall = fn void();
|
||||
|
||||
struct An2
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
typedef NodeNotifyHandler = fn void(TreeView* this, TreeNode* node, String prop, void* data);
|
||||
def NodeNotifyHandler = fn void(TreeView* this, TreeNode* node, String prop, void* data);
|
||||
fn void TreeView.nodeNotifyHandler(TreeView* this, TreeNode* node, String prop, void* data) @private {}
|
||||
|
||||
struct TreeNode { int abc; NodeNotifyHandler notifyHandler; }
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
module compiler_c3;
|
||||
import std::collections::list;
|
||||
|
||||
typedef IntArray = List<int>;
|
||||
def IntArray = List<int>;
|
||||
|
||||
extern fn void printf(char*, ...);
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
typedef NodeNotifyHandler = fn void(TreeView* this, TreeNode* node, String prop, void* data);
|
||||
def NodeNotifyHandler = fn void(TreeView* this, TreeNode* node, String prop, void* data);
|
||||
fn void TreeView.nodeNotifyHandler(TreeView* this, TreeNode* node, String prop, void* data) @private {}
|
||||
|
||||
struct TreeNode { int abc; NodeNotifyHandler notifyHandler; }
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
|
||||
typedef Foo = fn void(int a = 10);
|
||||
def Foo = fn void(int a = 10);
|
||||
fn int abc() { return 1; }
|
||||
typedef Foo2 = fn void(int a = abc());
|
||||
def Foo2 = fn void(int a = abc());
|
||||
|
||||
@@ -4,7 +4,7 @@ fn void test1()
|
||||
foreach (a : x) { }; // #error: It's not possible to enumerate an expression of type 'int'
|
||||
}
|
||||
|
||||
typedef Test1 = distinct int;
|
||||
def Test1 = distinct int;
|
||||
|
||||
fn void test2()
|
||||
{
|
||||
|
||||
@@ -4,7 +4,7 @@ fn void test1()
|
||||
foreach_r (a : x) { }; // #error: It's not possible to enumerate an expression of type 'int'
|
||||
}
|
||||
|
||||
typedef Test1 = distinct int;
|
||||
def Test1 = distinct int;
|
||||
|
||||
fn void test2()
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
typedef Func = fn int(int);
|
||||
def Func = fn int(int);
|
||||
|
||||
typedef Func2 = fn int(Foo*, int);
|
||||
def Func2 = fn int(Foo*, int);
|
||||
|
||||
struct Foo
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
typedef Foo = int[0]; // #error: An array may not have zero
|
||||
def Foo = int[0]; // #error: An array may not have zero
|
||||
|
||||
struct Bar
|
||||
{
|
||||
|
||||
@@ -4,7 +4,7 @@ struct Foo
|
||||
int y;
|
||||
}
|
||||
|
||||
typedef Foo = float; // #error: shadow a previous declaration
|
||||
def Foo = float; // #error: shadow a previous declaration
|
||||
|
||||
enum Bar
|
||||
{
|
||||
@@ -12,4 +12,4 @@ enum Bar
|
||||
TEST2
|
||||
}
|
||||
|
||||
typedef Bar = float; // #error: shadow a previous declaration
|
||||
def Bar = float; // #error: shadow a previous declaration
|
||||
@@ -49,7 +49,7 @@ fn void test7()
|
||||
int v = array[1];
|
||||
}
|
||||
|
||||
typedef Number = int;
|
||||
def Number = int;
|
||||
|
||||
fn void test8()
|
||||
{
|
||||
|
||||
@@ -13,7 +13,7 @@ enum Inf2 : char
|
||||
C,
|
||||
}
|
||||
|
||||
typedef BooInf = Inf;
|
||||
def BooInf = Inf;
|
||||
|
||||
|
||||
fn void enumInferenceTest()
|
||||
|
||||
@@ -4,7 +4,7 @@ enum EnumTest : long
|
||||
VALUE2
|
||||
}
|
||||
|
||||
typedef Frob = long;
|
||||
def Frob = long;
|
||||
|
||||
enum EnumTestAlias : Frob
|
||||
{
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
typedef Number2 = Number1; // #error: Recursive definition of 'Number2'
|
||||
typedef Number1 = Number2;
|
||||
def Number2 = Number1; // #error: Recursive definition of 'Number2'
|
||||
def Number1 = Number2;
|
||||
|
||||
typedef Number = Number; // #error: Recursive definition of 'Number'
|
||||
def Number = Number; // #error: Recursive definition of 'Number'
|
||||
|
||||
|
||||
typedef Loop2 = Loop; // #error: Recursive definition of 'Loop2'
|
||||
typedef Loop3 = Loop2;
|
||||
typedef Loop = Loop3;
|
||||
def Loop2 = Loop; // #error: Recursive definition of 'Loop2'
|
||||
def Loop3 = Loop2;
|
||||
def Loop = Loop3;
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
typedef Number = int;
|
||||
typedef Number = uint; // #error: 'Number' would shadow a previous declaration.
|
||||
def Number = int;
|
||||
def Number = uint; // #error: 'Number' would shadow a previous declaration.
|
||||
@@ -1,4 +1,4 @@
|
||||
typedef Arr = int[4];
|
||||
def Arr = int[4];
|
||||
|
||||
Arr a = { 3, 4, 5, 6 };
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ enum FooEnum
|
||||
THREE,
|
||||
}
|
||||
|
||||
typedef FooEnumMap = EnumMap<FooEnum, uint>;
|
||||
def FooEnumMap = EnumMap<FooEnum, uint>;
|
||||
|
||||
fn void! enums()
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
module linkedlist_test @test;
|
||||
import std::collections::linkedlist;
|
||||
|
||||
typedef IntList = LinkedList<int>;
|
||||
def IntList = LinkedList<int>;
|
||||
|
||||
fn void! test_push()
|
||||
{
|
||||
|
||||
@@ -12,14 +12,14 @@ fn void test_ipv4()
|
||||
fn void! test_ipv4_to_string()
|
||||
{
|
||||
InetAddress a = net::ipv4_from_str("127.0.0.1")!;
|
||||
assert(a.to_string()! == "127.0.0.1");
|
||||
assert(a.to_string() == "127.0.0.1");
|
||||
}
|
||||
|
||||
fn void! test_ipv6_to_string()
|
||||
{
|
||||
InetAddress a = net::ipv6_from_str("2001:db8::2:1")!;
|
||||
a.to_string()!;
|
||||
assert(a.to_string()! == "2001:0db8:0000:0000:0000:0000:0002:0001");
|
||||
a.to_string();
|
||||
assert(a.to_string() == "2001:0db8:0000:0000:0000:0000:0002:0001");
|
||||
assert(net::ipv6_from_str("2001:db8::1").to_string()! == "2001:0db8:0000:0000:0000:0000:0000:0001");
|
||||
assert(net::ipv6_from_str("::1").to_string()! == "0000:0000:0000:0000:0000:0000:0000:0001");
|
||||
assert(net::ipv6_from_str("2001::1").to_string()! == "2001:0000:0000:0000:0000:0000:0000:0001");
|
||||
|
||||
Reference in New Issue
Block a user