mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Update build options --nostdlib --nolibc --emit-stdlib --forcelinker … (#999)
Update build options --nostdlib --nolibc --emit-stdlib --forcelinker --strip-unused. Fix error with vectors in $foreach. Also error if a $foreach iterating over an empty list. Rename forcelinker -> system-linker
This commit is contained in:
committed by
GitHub
parent
d49365b4a7
commit
8ed9be9c58
6
.github/workflows/main.yml
vendored
6
.github/workflows/main.yml
vendored
@@ -273,7 +273,7 @@ jobs:
|
||||
- name: Build testproject direct linker
|
||||
run: |
|
||||
cd resources/testproject
|
||||
../../build/c3c run --debug-log --forcelinker
|
||||
../../build/c3c run --debug-log --system-linker=no
|
||||
|
||||
- name: run compiler tests
|
||||
run: |
|
||||
@@ -378,7 +378,7 @@ jobs:
|
||||
- name: Build testproject direct linker
|
||||
run: |
|
||||
cd resources/testproject
|
||||
../../build/c3c run --debug-log --forcelinker
|
||||
../../build/c3c run --debug-log --system-linker=no
|
||||
|
||||
- name: run compiler tests
|
||||
run: |
|
||||
@@ -450,7 +450,7 @@ jobs:
|
||||
- name: Build testproject direct linker
|
||||
run: |
|
||||
cd resources/testproject
|
||||
../../build/c3c run --debug-log --forcelinker
|
||||
../../build/c3c run --debug-log --system-linker=no
|
||||
|
||||
- name: Build testproject lib
|
||||
run: |
|
||||
|
||||
@@ -7,8 +7,7 @@
|
||||
#include "utils/lib.h"
|
||||
#include "utils/json.h"
|
||||
#include "build_options.h"
|
||||
#define DEFAULT_SYMTAB_SIZE (256 * 1024)
|
||||
#define DEFAULT_SWITCHRANGE_MAX_SIZE (256)
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
||||
@@ -83,8 +83,6 @@ static void usage(void)
|
||||
OUTPUT("Options:");
|
||||
OUTPUT(" --tb - Use Tilde Backend for compilation.");
|
||||
OUTPUT(" --stdlib <dir> - Use this directory as the C3 standard library path.");
|
||||
OUTPUT(" --nostdlib - Do not include the standard library.");
|
||||
OUTPUT(" --nolibc - Do not implicitly link libc nor any associated files.");
|
||||
OUTPUT(" --no-entry - Do not generate (or require) a main function.");
|
||||
OUTPUT(" --libdir <dir> - Add this directory to the C3 library search paths.");
|
||||
OUTPUT(" --lib <name> - Add this library to the compilation.");
|
||||
@@ -101,17 +99,11 @@ static void usage(void)
|
||||
OUTPUT(" -O0 - Safe, no optimizations, emit debug info.");
|
||||
OUTPUT(" -O1 - Safe, high optimization, emit debug info.");
|
||||
OUTPUT(" -O2 - Unsafe, high optimization, emit debug info.");
|
||||
OUTPUT(" -O3 - Unsafe, highest optimization, relaxed maths, emit debug info.");
|
||||
OUTPUT(" -O4 - Unsafe, highest optimization, fast maths, emit debug info.");
|
||||
OUTPUT(" -Os - Unsafe, high optimization, small code, no debug info.");
|
||||
OUTPUT(" -Oz - Unsafe, high optimization, tiny code, no debug info.");
|
||||
OUTPUT(" -O0+ - O0, single module.");
|
||||
OUTPUT(" -O1+ - O1, single module.");
|
||||
OUTPUT(" -O2+ - O2, single module.");
|
||||
OUTPUT(" -O3+ - O3, single module.");
|
||||
OUTPUT(" -O4+ - O4, single module.");
|
||||
OUTPUT(" -Os+ - Os, single module.");
|
||||
OUTPUT(" -Oz+ - Oz, single module.");
|
||||
OUTPUT(" -O3 - Unsafe, high optimization, single module, emit debug info.");
|
||||
OUTPUT(" -O4 - Unsafe, highest optimization, relaxed maths, single module, emit debug info.");
|
||||
OUTPUT(" -O5 - Unsafe, highest optimization, fast maths, single module, emit debug info.");
|
||||
OUTPUT(" -Os - Unsafe, high optimization, small code, single module, no debug info.");
|
||||
OUTPUT(" -Oz - Unsafe, high optimization, tiny code, single module, no debug info.");
|
||||
OUTPUT(" -t1 - Trust level 1 - don't allow $include nor $exec (default).");
|
||||
OUTPUT(" -t2 - Trust level 2 - allow $include but not $exec / exec directives.");
|
||||
OUTPUT(" -t3 - Trust level 3 - full trust, allow both include and exec.");
|
||||
@@ -125,13 +117,12 @@ static void usage(void)
|
||||
OUTPUT(" --emit-asm - Emit asm as a .s file per module.");
|
||||
OUTPUT(" --obj - Emit object files. (Enabled by default)");
|
||||
OUTPUT(" --no-obj - Do not output object files, this is only valid for `compile-only`.");
|
||||
OUTPUT(" --emit-stdlib - Output files for the standard library. (Enabled by default)");
|
||||
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=<yes|no> - Turn safety (contracts, runtime bounds checking, null pointer checks etc) on or off.");
|
||||
OUTPUT(" --optlevel=<option> - Code optimization level: none, less, more, max.");
|
||||
OUTPUT(" --optsize=<option> - Code size optimization: none, small, tiny.");
|
||||
OUTPUT(" --single-module=<yes|no> - Compile all modules together, enables more inlining.");
|
||||
OUTPUT("");
|
||||
OUTPUT(" -g - Emit debug info.");
|
||||
OUTPUT(" -g0 - Emit no debug info.");
|
||||
@@ -140,15 +131,19 @@ static void usage(void)
|
||||
OUTPUT(" -l <library> - Link with the library provided.");
|
||||
OUTPUT(" -L <library dir> - Append the directory to the linker search paths.");
|
||||
OUTPUT(" -z <argument> - Send the <argument> as a parameter to the linker.");
|
||||
OUTPUT(" --forcelinker - Force built in linker usage when doing non-cross linking.");
|
||||
OUTPUT(" --system-linker=<yes|no> - Use the system linker (default: no for cross compilation, yes otherwise).");
|
||||
OUTPUT("");
|
||||
OUTPUT(" --use-stdlib=<yes|no> - Include the standard library (default: yes).");
|
||||
OUTPUT(" --link-libc=<yes|no> - Link libc other default libraries (default: yes).");
|
||||
OUTPUT(" --emit-stdlib=<yes|no> - Output files for the standard library. (default: yes)");
|
||||
OUTPUT(" --panicfn <name> - Override the panic function name.");
|
||||
OUTPUT("");
|
||||
OUTPUT(" --reloc=<option> - Relocation model: none, pic, PIC, pie, PIE.");
|
||||
OUTPUT(" --x86cpu=<option> - Set general level of x64 cpu: baseline, ssse3, sse4, avx1, avx2-v1, avx2-v2 (Skylake/Zen1+), avx512 (Icelake/Zen4+), native.");
|
||||
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. (Enabled by default)");
|
||||
OUTPUT(" --no-strip-unused - Do not strip unused code and globals from the output.");
|
||||
OUTPUT(" --strip-unused=<yes|no> - Strip unused code and globals from the output. (default: yes)");
|
||||
OUTPUT(" --fp-math=<option> - FP math behaviour: strict, relaxed, fast.");
|
||||
OUTPUT("");
|
||||
OUTPUT(" --debug-stats - Print debug statistics.");
|
||||
@@ -533,65 +528,41 @@ static void parse_option(BuildOptions *options)
|
||||
}
|
||||
break;
|
||||
case 'O':
|
||||
if (match_shortopt("O0+"))
|
||||
{
|
||||
options->optsetting = OPT_SETTING_O0_PLUS;
|
||||
}
|
||||
else if (match_shortopt("O0"))
|
||||
if (match_shortopt("O0"))
|
||||
{
|
||||
options->optsetting = OPT_SETTING_O0;
|
||||
}
|
||||
else if (match_shortopt("O1+"))
|
||||
{
|
||||
options->optsetting = OPT_SETTING_O1_PLUS;
|
||||
}
|
||||
else if (match_shortopt("O1"))
|
||||
{
|
||||
options->optsetting = OPT_SETTING_O1;
|
||||
}
|
||||
else if (match_shortopt("O2+"))
|
||||
{
|
||||
options->optsetting = OPT_SETTING_O2_PLUS;
|
||||
}
|
||||
else if (match_shortopt("O2"))
|
||||
{
|
||||
options->optsetting = OPT_SETTING_O2;
|
||||
}
|
||||
else if (match_shortopt("O3+"))
|
||||
{
|
||||
options->optsetting = OPT_SETTING_O3_PLUS;
|
||||
}
|
||||
else if (match_shortopt("O3"))
|
||||
{
|
||||
options->optsetting = OPT_SETTING_O3;
|
||||
}
|
||||
else if (match_shortopt("O4+"))
|
||||
{
|
||||
options->optsetting = OPT_SETTING_O4_PLUS;
|
||||
}
|
||||
else if (match_shortopt("O4"))
|
||||
{
|
||||
options->optsetting = OPT_SETTING_O4;
|
||||
}
|
||||
else if (match_shortopt("Os+"))
|
||||
else if (match_shortopt("O5"))
|
||||
{
|
||||
options->optsetting = OPT_SETTING_OSMALL_PLUS;
|
||||
options->optsetting = OPT_SETTING_O5;
|
||||
}
|
||||
else if (match_shortopt("Os"))
|
||||
{
|
||||
options->optsetting = OPT_SETTING_OSMALL;
|
||||
}
|
||||
else if (match_shortopt("Oz+"))
|
||||
{
|
||||
options->optsetting = OPT_SETTING_OTINY_PLUS;
|
||||
}
|
||||
else if (match_shortopt("Oz"))
|
||||
{
|
||||
options->optsetting = OPT_SETTING_OTINY;
|
||||
}
|
||||
else
|
||||
{
|
||||
FAIL_WITH_ERR("Invalid optimization level.");
|
||||
FAIL_WITH_ERR("Invalid optimization level, expected O0 - O5, Os or Oz.");
|
||||
}
|
||||
return;
|
||||
case 'E':
|
||||
@@ -658,21 +629,11 @@ static void parse_option(BuildOptions *options)
|
||||
options->symtab_size = next_highest_power_of_2(symtab);
|
||||
return;
|
||||
}
|
||||
if (match_longopt("forcelinker"))
|
||||
{
|
||||
options->force_linker = true;
|
||||
return;
|
||||
}
|
||||
if (match_longopt("version"))
|
||||
{
|
||||
print_version();
|
||||
exit_compiler(COMPILER_SUCCESS_EXIT);
|
||||
}
|
||||
if (match_longopt("no-strip-unused"))
|
||||
{
|
||||
options->no_strip_unused = true;
|
||||
return;
|
||||
}
|
||||
if ((argopt = match_argopt("fp-math")))
|
||||
{
|
||||
options->fp_math = (FpOpt)parse_multi_option(argopt, 3, fp_math);
|
||||
@@ -690,12 +651,37 @@ static void parse_option(BuildOptions *options)
|
||||
}
|
||||
if ((argopt = match_argopt("safe")))
|
||||
{
|
||||
options->safety_level = (SafetyLevel)parse_multi_option(argopt, 2, safety_levels);
|
||||
options->safety_level = (SafetyLevel)parse_multi_option(argopt, 2, on_off);
|
||||
return;
|
||||
}
|
||||
if (match_longopt("strip-unused"))
|
||||
if ((argopt = match_argopt("single-module")))
|
||||
{
|
||||
options->no_strip_unused = false;
|
||||
options->single_module = (SingleModule)parse_multi_option(argopt, 2, on_off);
|
||||
return;
|
||||
}
|
||||
if ((argopt = match_argopt("system-linker")))
|
||||
{
|
||||
options->system_linker = (SystemLinker)parse_multi_option(argopt, 2, on_off);
|
||||
return;
|
||||
}
|
||||
if ((argopt = match_argopt("link-libc")))
|
||||
{
|
||||
options->link_libc = (LinkLibc)parse_multi_option(argopt, 2, on_off);
|
||||
return;
|
||||
}
|
||||
if ((argopt = match_argopt("strip-unused")))
|
||||
{
|
||||
options->strip_unused = (StripUnused)parse_multi_option(argopt, 2, on_off);
|
||||
return;
|
||||
}
|
||||
if ((argopt = match_argopt("emit-stdlib")))
|
||||
{
|
||||
options->emit_stdlib = (EmitStdlib)parse_multi_option(argopt, 2, on_off);
|
||||
return;
|
||||
}
|
||||
if ((argopt = match_argopt("use-stdlib")))
|
||||
{
|
||||
options->use_stdlib = (UseStdlib)parse_multi_option(argopt, 2, on_off);
|
||||
return;
|
||||
}
|
||||
if ((argopt = match_argopt("x86vec")))
|
||||
@@ -739,16 +725,6 @@ static void parse_option(BuildOptions *options)
|
||||
options->no_obj = false;
|
||||
return;
|
||||
}
|
||||
if (match_longopt("no-emit-stdlib"))
|
||||
{
|
||||
options->no_emit_stdlib = true;
|
||||
return;
|
||||
}
|
||||
if (match_longopt("emit-stdlib"))
|
||||
{
|
||||
options->no_emit_stdlib = false;
|
||||
return;
|
||||
}
|
||||
if (match_longopt("debug-log"))
|
||||
{
|
||||
debug_log = true;
|
||||
@@ -866,17 +842,7 @@ static void parse_option(BuildOptions *options)
|
||||
{
|
||||
if (at_end() || next_is_opt()) error_exit("error: --stdlib needs a directory.");
|
||||
options->std_lib_dir = check_dir(next_arg());
|
||||
options->no_stdlib = false;
|
||||
return;
|
||||
}
|
||||
if (match_longopt("nostdlib"))
|
||||
{
|
||||
options->no_stdlib = true;
|
||||
return;
|
||||
}
|
||||
if (match_longopt("nolibc"))
|
||||
{
|
||||
options->no_libc = true;
|
||||
options->emit_stdlib = EMIT_STDLIB_ON;
|
||||
return;
|
||||
}
|
||||
if (match_longopt("panicfn"))
|
||||
@@ -966,6 +932,7 @@ static void parse_option(BuildOptions *options)
|
||||
if (match_longopt("test"))
|
||||
{
|
||||
options->test_mode = true;
|
||||
options->strip_unused = STRIP_UNUSED_OFF;
|
||||
return;
|
||||
}
|
||||
if (match_longopt("template"))
|
||||
@@ -1045,6 +1012,12 @@ BuildOptions parse_arguments(int argc, const char *argv[])
|
||||
.riscv_float_capability = RISCVFLOAT_DEFAULT,
|
||||
.memory_environment = MEMORY_ENV_NOT_SET,
|
||||
.win.crt_linking = WIN_CRT_DEFAULT,
|
||||
.emit_stdlib = EMIT_STDLIB_NOT_SET,
|
||||
.link_libc = LINK_LIBC_NOT_SET,
|
||||
.use_stdlib = USE_STDLIB_NOT_SET,
|
||||
.system_linker = SYSTEM_LINKER_NOT_SET,
|
||||
.strip_unused = STRIP_UNUSED_NOT_SET,
|
||||
.single_module = SINGLE_MODULE_NOT_SET,
|
||||
.files = NULL,
|
||||
.build_dir = NULL,
|
||||
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
#define MAX_FILES 2048
|
||||
#define MAX_INCLUDES 2048
|
||||
#define MAX_THREADS 0xFFFF
|
||||
#define DEFAULT_SYMTAB_SIZE (256 * 1024)
|
||||
#define DEFAULT_SWITCHRANGE_MAX_SIZE (256)
|
||||
|
||||
void update_feature_flags(const char ***flags, const char ***removed_flag, const char *arg, bool add);
|
||||
|
||||
@@ -103,19 +105,13 @@ typedef enum
|
||||
{
|
||||
OPT_SETTING_NOT_SET = -1,
|
||||
OPT_SETTING_O0 = 0,
|
||||
OPT_SETTING_O0_PLUS,
|
||||
OPT_SETTING_O1,
|
||||
OPT_SETTING_O1_PLUS,
|
||||
OPT_SETTING_O2,
|
||||
OPT_SETTING_O2_PLUS,
|
||||
OPT_SETTING_O3,
|
||||
OPT_SETTING_O3_PLUS,
|
||||
OPT_SETTING_O4,
|
||||
OPT_SETTING_O4_PLUS,
|
||||
OPT_SETTING_O5,
|
||||
OPT_SETTING_OSMALL,
|
||||
OPT_SETTING_OSMALL_PLUS,
|
||||
OPT_SETTING_OTINY,
|
||||
OPT_SETTING_OTINY_PLUS
|
||||
} OptimizationSetting;
|
||||
|
||||
typedef enum
|
||||
@@ -127,6 +123,48 @@ typedef enum
|
||||
OPTIMIZATION_AGGRESSIVE = 3, // -O3
|
||||
} OptimizationLevel;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SINGLE_MODULE_NOT_SET = -1,
|
||||
SINGLE_MODULE_OFF = 0,
|
||||
SINGLE_MODULE_ON = 1
|
||||
} SingleModule;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SYSTEM_LINKER_NOT_SET = -1,
|
||||
SYSTEM_LINKER_OFF = 0,
|
||||
SYSTEM_LINKER_ON = 1
|
||||
} SystemLinker;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
STRIP_UNUSED_NOT_SET = -1,
|
||||
STRIP_UNUSED_OFF = 0,
|
||||
STRIP_UNUSED_ON = 1
|
||||
} StripUnused;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LINK_LIBC_NOT_SET = -1,
|
||||
LINK_LIBC_OFF = 0,
|
||||
LINK_LIBC_ON = 1
|
||||
} LinkLibc;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
EMIT_STDLIB_NOT_SET = -1,
|
||||
EMIT_STDLIB_OFF = 0,
|
||||
EMIT_STDLIB_ON = 1
|
||||
} EmitStdlib;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
USE_STDLIB_NOT_SET = -1,
|
||||
USE_STDLIB_OFF = 0,
|
||||
USE_STDLIB_ON = 1
|
||||
} UseStdlib;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SIZE_OPTIMIZATION_NOT_SET = -1,
|
||||
@@ -229,7 +267,7 @@ static const char *optsizes[3] = {
|
||||
[SIZE_OPTIMIZATION_TINY] = "more",
|
||||
};
|
||||
|
||||
static const char *safety_levels[2] = {
|
||||
static const char *on_off[2] = {
|
||||
[SAFETY_OFF] = "no",
|
||||
[SAFETY_ON] = "yes",
|
||||
};
|
||||
@@ -373,16 +411,13 @@ typedef struct BuildOptions_
|
||||
DebugInfo debug_info_override;
|
||||
ArchOsTarget arch_os_target_override;
|
||||
SafetyLevel safety_level;
|
||||
SingleModule single_module;
|
||||
bool emit_llvm;
|
||||
bool emit_asm;
|
||||
bool benchmark_mode;
|
||||
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;
|
||||
const char *panicfn;
|
||||
@@ -395,11 +430,15 @@ typedef struct BuildOptions_
|
||||
X86VectorCapability x86_vector_capability;
|
||||
X86CpuSet x86_cpu_set;
|
||||
FpOpt fp_math;
|
||||
EmitStdlib emit_stdlib;
|
||||
UseStdlib use_stdlib;
|
||||
LinkLibc link_libc;
|
||||
SystemLinker system_linker;
|
||||
StripUnused strip_unused;
|
||||
OptimizationLevel optlevel;
|
||||
SizeOptimizationLevel optsize;
|
||||
RiscvFloatCapability riscv_float_capability;
|
||||
MemoryEnvironment memory_environment;
|
||||
bool no_strip_unused;
|
||||
bool print_keywords;
|
||||
bool print_attributes;
|
||||
bool print_builtins;
|
||||
@@ -476,28 +515,28 @@ typedef struct
|
||||
bool check_only;
|
||||
bool emit_llvm;
|
||||
bool emit_asm;
|
||||
bool no_stdlib;
|
||||
bool no_libc;
|
||||
bool no_strip_unused;
|
||||
bool emit_object_files;
|
||||
bool force_linker;
|
||||
bool benchmarking;
|
||||
bool testing;
|
||||
bool read_stdin;
|
||||
bool print_output;
|
||||
bool no_entry;
|
||||
bool no_emit_stdlib;
|
||||
int build_threads;
|
||||
TrustLevel trust_level;
|
||||
OptimizationSetting optsetting;
|
||||
OptimizationLevel optlevel;
|
||||
MemoryEnvironment memory_environment;
|
||||
SizeOptimizationLevel optsize;
|
||||
bool single_module;
|
||||
SingleModule single_module;
|
||||
UseStdlib use_stdlib;
|
||||
EmitStdlib emit_stdlib;
|
||||
LinkLibc link_libc;
|
||||
StripUnused strip_unused;
|
||||
DebugInfo debug_info;
|
||||
RelocModel reloc_model;
|
||||
ArchOsTarget arch_os_target;
|
||||
CompilerBackend backend;
|
||||
SystemLinker system_linker;
|
||||
uint32_t symtab_size;
|
||||
uint32_t switchrange_max_size;
|
||||
const char *panicfn;
|
||||
@@ -540,4 +579,36 @@ typedef struct
|
||||
BuildOptions parse_arguments(int argc, const char *argv[]);
|
||||
ArchOsTarget arch_os_target_from_string(const char *target);
|
||||
bool command_is_projectless(CompilerCommand command);
|
||||
void update_build_target_with_opt_level(BuildTarget *target, OptimizationSetting level);
|
||||
void update_build_target_with_opt_level(BuildTarget *target, OptimizationSetting level);
|
||||
|
||||
static BuildTarget default_build_target = {
|
||||
.optlevel = OPTIMIZATION_NOT_SET,
|
||||
.optsetting = OPT_SETTING_NOT_SET,
|
||||
.memory_environment = MEMORY_ENV_NORMAL,
|
||||
.optsize = SIZE_OPTIMIZATION_NOT_SET,
|
||||
.arch_os_target = ARCH_OS_TARGET_DEFAULT,
|
||||
.debug_info = DEBUG_INFO_NOT_SET,
|
||||
.use_stdlib = USE_STDLIB_NOT_SET,
|
||||
.link_libc = LINK_LIBC_NOT_SET,
|
||||
.emit_stdlib = EMIT_STDLIB_NOT_SET,
|
||||
.system_linker = SYSTEM_LINKER_NOT_SET,
|
||||
.single_module = SINGLE_MODULE_NOT_SET,
|
||||
.strip_unused = STRIP_UNUSED_NOT_SET,
|
||||
.symtab_size = DEFAULT_SYMTAB_SIZE,
|
||||
.reloc_model = RELOC_DEFAULT,
|
||||
.cc = "cc",
|
||||
.version = "1.0.0",
|
||||
.langrev = "1",
|
||||
.cpu = "generic",
|
||||
.type = TARGET_TYPE_EXECUTABLE,
|
||||
.feature.x86_struct_return = STRUCT_RETURN_DEFAULT,
|
||||
.feature.soft_float = SOFT_FLOAT_DEFAULT,
|
||||
.feature.fp_math = FP_DEFAULT,
|
||||
.feature.trap_on_wrap = false,
|
||||
.feature.riscv_float_capability = RISCVFLOAT_DEFAULT,
|
||||
.feature.x86_vector_capability = X86VECTOR_DEFAULT,
|
||||
.feature.x86_cpu_set = X86CPU_DEFAULT,
|
||||
.feature.safe_mode = SAFETY_NOT_SET,
|
||||
.win.crt_linking = WIN_CRT_DEFAULT,
|
||||
.switchrange_max_size = DEFAULT_SWITCHRANGE_MAX_SIZE,
|
||||
};
|
||||
@@ -103,55 +103,43 @@ void update_build_target_with_opt_level(BuildTarget *target, OptimizationSetting
|
||||
FpOpt fp_opt = FP_STRICT;
|
||||
switch (level)
|
||||
{
|
||||
case OPT_SETTING_O0_PLUS:
|
||||
single_module = true;
|
||||
break;
|
||||
case OPT_SETTING_O0:
|
||||
break;
|
||||
case OPT_SETTING_O1_PLUS:
|
||||
single_module = true;
|
||||
FALLTHROUGH;
|
||||
case OPT_SETTING_O1:
|
||||
optlevel = OPTIMIZATION_MORE;
|
||||
break;
|
||||
case OPT_SETTING_O2_PLUS:
|
||||
single_module = true;
|
||||
FALLTHROUGH;
|
||||
case OPT_SETTING_O2:
|
||||
optlevel = OPTIMIZATION_MORE;
|
||||
safety_level = false;
|
||||
break;
|
||||
case OPT_SETTING_O3_PLUS:
|
||||
single_module = true;
|
||||
FALLTHROUGH;
|
||||
case OPT_SETTING_O3:
|
||||
optlevel = OPTIMIZATION_AGGRESSIVE;
|
||||
safety_level = SAFETY_OFF;
|
||||
fp_opt = FP_RELAXED;
|
||||
break;
|
||||
case OPT_SETTING_O4_PLUS:
|
||||
optlevel = OPTIMIZATION_MORE;
|
||||
safety_level = false;
|
||||
single_module = true;
|
||||
FALLTHROUGH;
|
||||
break;
|
||||
case OPT_SETTING_O4:
|
||||
optlevel = OPTIMIZATION_AGGRESSIVE;
|
||||
safety_level = SAFETY_OFF;
|
||||
fp_opt = FP_FAST;
|
||||
break;
|
||||
case OPT_SETTING_OSMALL_PLUS:
|
||||
fp_opt = FP_RELAXED;
|
||||
single_module = true;
|
||||
FALLTHROUGH;
|
||||
break;
|
||||
case OPT_SETTING_O5:
|
||||
single_module = true;
|
||||
optlevel = OPTIMIZATION_AGGRESSIVE;
|
||||
safety_level = SAFETY_OFF;
|
||||
fp_opt = FP_FAST;
|
||||
single_module = true;
|
||||
break;
|
||||
case OPT_SETTING_OSMALL:
|
||||
optlevel = OPTIMIZATION_MORE;
|
||||
optsize = SIZE_OPTIMIZATION_SMALL;
|
||||
safety_level = SAFETY_OFF;
|
||||
break;
|
||||
case OPT_SETTING_OTINY_PLUS:
|
||||
target->single_module = true;
|
||||
FALLTHROUGH;
|
||||
case OPT_SETTING_OTINY:
|
||||
optlevel = OPTIMIZATION_MORE;
|
||||
optsize = SIZE_OPTIMIZATION_TINY;
|
||||
safety_level = SAFETY_OFF;
|
||||
single_module = true;
|
||||
debug = DEBUG_INFO_NONE;
|
||||
break;
|
||||
case OPT_SETTING_NOT_SET:
|
||||
@@ -163,7 +151,7 @@ void update_build_target_with_opt_level(BuildTarget *target, OptimizationSetting
|
||||
if (target->feature.safe_mode == SAFETY_NOT_SET) target->feature.safe_mode = safety_level;
|
||||
if (target->debug_info == DEBUG_INFO_NOT_SET) target->debug_info = debug;
|
||||
if (target->feature.fp_math == FP_DEFAULT) target->feature.fp_math = fp_opt;
|
||||
if (single_module) target->single_module = true;
|
||||
if (target->single_module == SINGLE_MODULE_NOT_SET && single_module) target->single_module = SINGLE_MODULE_ON;
|
||||
}
|
||||
static void update_build_target_from_options(BuildTarget *target, BuildOptions *options)
|
||||
{
|
||||
@@ -235,6 +223,9 @@ static void update_build_target_from_options(BuildTarget *target, BuildOptions *
|
||||
FOREACH_END();
|
||||
|
||||
|
||||
target->read_stdin = options->read_stdin;
|
||||
|
||||
|
||||
if (options->cc) target->cc = options->cc;
|
||||
if (options->optlevel != OPTIMIZATION_NOT_SET)
|
||||
{
|
||||
@@ -248,7 +239,7 @@ static void update_build_target_from_options(BuildTarget *target, BuildOptions *
|
||||
{
|
||||
target->feature.safe_mode = options->safety_level;
|
||||
}
|
||||
if (options->no_strip_unused || options->test_mode) target->no_strip_unused = true;
|
||||
if (options->strip_unused != STRIP_UNUSED_NOT_SET) target->strip_unused = options->strip_unused;
|
||||
|
||||
if (options->memory_environment != MEMORY_ENV_NOT_SET)
|
||||
{
|
||||
@@ -264,6 +255,8 @@ static void update_build_target_from_options(BuildTarget *target, BuildOptions *
|
||||
}
|
||||
if (options->reloc_model != RELOC_DEFAULT) target->reloc_model = options->reloc_model;
|
||||
|
||||
if (options->symtab_size) target->symtab_size = options->symtab_size;
|
||||
|
||||
for (int i = 0; i < options->linker_arg_count; i++)
|
||||
{
|
||||
vec_add(target->link_args, options->linker_args[i]);
|
||||
@@ -277,14 +270,15 @@ static void update_build_target_from_options(BuildTarget *target, BuildOptions *
|
||||
vec_add(target->linker_libs, options->linker_libs[i]);
|
||||
}
|
||||
target->trust_level = options->trust_level;
|
||||
if (options->no_stdlib) target->no_stdlib = true;
|
||||
if (options->no_libc) target->no_libc = true;
|
||||
if (options->use_stdlib != USE_STDLIB_NOT_SET) target->use_stdlib = options->use_stdlib;
|
||||
if (options->link_libc != LINK_LIBC_NOT_SET) target->link_libc = options->link_libc;
|
||||
if (options->system_linker != SYSTEM_LINKER_NOT_SET) target->system_linker = options->system_linker;
|
||||
if (options->emit_stdlib != EMIT_STDLIB_NOT_SET) target->emit_stdlib = options->emit_stdlib;
|
||||
if (options->no_entry) target->no_entry = true;
|
||||
target->print_output = options->print_output;
|
||||
target->emit_llvm = options->emit_llvm;
|
||||
target->build_threads = options->build_threads;
|
||||
target->emit_asm = options->emit_asm;
|
||||
target->force_linker = options->force_linker;
|
||||
target->panicfn = options->panicfn;
|
||||
target->benchmarking = options->benchmarking;
|
||||
target->testing = options->testing;
|
||||
@@ -367,7 +361,6 @@ static void update_build_target_from_options(BuildTarget *target, BuildOptions *
|
||||
{
|
||||
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]);
|
||||
@@ -381,33 +374,13 @@ static void update_build_target_from_options(BuildTarget *target, BuildOptions *
|
||||
target->optsetting = options->optsetting;
|
||||
}
|
||||
update_build_target_with_opt_level(target, target->optsetting);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void init_default_build_target(BuildTarget *target, BuildOptions *options)
|
||||
{
|
||||
*target = (BuildTarget) {
|
||||
.read_stdin = options->read_stdin,
|
||||
.type = TARGET_TYPE_EXECUTABLE,
|
||||
.source_dirs = options->files,
|
||||
.name = options->output_name,
|
||||
.optsetting = OPT_SETTING_NOT_SET,
|
||||
.optlevel = OPTIMIZATION_NOT_SET,
|
||||
.memory_environment = MEMORY_ENV_NORMAL,
|
||||
.optsize = SIZE_OPTIMIZATION_NOT_SET,
|
||||
.symtab_size = options->symtab_size ? options->symtab_size : DEFAULT_SYMTAB_SIZE,
|
||||
.switchrange_max_size = DEFAULT_SWITCHRANGE_MAX_SIZE,
|
||||
.debug_info = DEBUG_INFO_NOT_SET,
|
||||
.arch_os_target = ARCH_OS_TARGET_DEFAULT,
|
||||
.reloc_model = RELOC_DEFAULT,
|
||||
.feature.x86_vector_capability = X86VECTOR_DEFAULT,
|
||||
.feature.x86_cpu_set = X86CPU_DEFAULT,
|
||||
.feature.fp_math = FP_DEFAULT,
|
||||
.feature.riscv_float_capability = RISCVFLOAT_DEFAULT,
|
||||
.feature.safe_mode = SAFETY_NOT_SET,
|
||||
.win.crt_linking = WIN_CRT_DEFAULT,
|
||||
};
|
||||
*target = default_build_target;
|
||||
target->source_dirs = options->files;
|
||||
target->name = options->output_name;
|
||||
update_build_target_from_options(target, options);
|
||||
}
|
||||
|
||||
|
||||
@@ -298,21 +298,17 @@ static void load_into_build_target(JSONObject *json, const char *type, BuildTarg
|
||||
DebugInfo info = get_valid_string_setting(json, "debug-info", type, debug_infos, 0, 3, "one of 'full' 'line-table' or 'none'.");
|
||||
if (info > -1) target->debug_info = info;
|
||||
|
||||
static const char *opt_settings[14] = {
|
||||
static const char *opt_settings[8] = {
|
||||
[OPT_SETTING_O0] = "O0",
|
||||
[OPT_SETTING_O0_PLUS] = "O0+",
|
||||
[OPT_SETTING_O1] = "O1",
|
||||
[OPT_SETTING_O1_PLUS] = "O1+",
|
||||
[OPT_SETTING_O2] = "O2",
|
||||
[OPT_SETTING_O2_PLUS] = "O2+",
|
||||
[OPT_SETTING_O3] = "O3",
|
||||
[OPT_SETTING_O3_PLUS] = "O3+",
|
||||
[OPT_SETTING_O4] = "O4",
|
||||
[OPT_SETTING_O5] = "O5",
|
||||
[OPT_SETTING_OSMALL] = "Os",
|
||||
[OPT_SETTING_OSMALL_PLUS] = "Os+",
|
||||
[OPT_SETTING_OTINY] = "Oz",
|
||||
[OPT_SETTING_OTINY_PLUS] = "Oz+"
|
||||
[OPT_SETTING_OTINY] = "Oz"
|
||||
};
|
||||
OptimizationSetting opt = (OptimizationSetting)get_valid_string_setting(json, "opt", type, opt_settings, 0, 14, "'O0', 'O1' etc.");
|
||||
OptimizationSetting opt = (OptimizationSetting)get_valid_string_setting(json, "opt", type, opt_settings, 0, 8, "'O0', 'O1' etc.");
|
||||
update_build_target_with_opt_level(target, opt);
|
||||
|
||||
MemoryEnvironment env = get_valid_string_setting(json, "memory-env", type, memory_environment, 0, 4, "one of 'normal', 'small', 'tiny' or 'none'.");
|
||||
@@ -413,14 +409,20 @@ static void load_into_build_target(JSONObject *json, const char *type, BuildTarg
|
||||
const char *panicfn = get_valid_string(json, "panicfn", type, false);
|
||||
target->panicfn = panicfn;
|
||||
|
||||
// nolibc
|
||||
target->no_libc = get_valid_bool(json, "nolibc", type, target->no_libc);
|
||||
// link-libc
|
||||
target->link_libc = (LinkLibc)get_valid_bool(json, "nolibc", type, target->link_libc);
|
||||
|
||||
// no-entry
|
||||
target->no_entry = get_valid_bool(json, "no-entry", type, target->no_entry);
|
||||
|
||||
// nostdlib
|
||||
target->no_stdlib = get_valid_bool(json, "nostdlib", type, target->no_stdlib);
|
||||
// use-stdlib
|
||||
target->use_stdlib = (UseStdlib)get_valid_bool(json, "use-stdlib", type, target->use_stdlib);
|
||||
|
||||
// emit-stdlib
|
||||
target->emit_stdlib = (EmitStdlib)get_valid_bool(json, "emit-stdlib", type, target->emit_stdlib);
|
||||
|
||||
// single-module
|
||||
target->single_module = (SingleModule)get_valid_bool(json, "single-module", type, target->single_module);
|
||||
|
||||
// Trap on wrap
|
||||
target->feature.trap_on_wrap = get_valid_bool(json, "trap-on-wrap", type, target->feature.trap_on_wrap);
|
||||
@@ -468,26 +470,7 @@ static void project_add_targets(Project *project, JSONObject *project_data)
|
||||
[TARGET_TYPE_TEST] = "test suite",
|
||||
[TARGET_TYPE_OBJECT_FILES] = "object files"};
|
||||
|
||||
BuildTarget default_target = {
|
||||
.optlevel = OPTIMIZATION_NOT_SET,
|
||||
.optsetting = OPT_SETTING_NOT_SET,
|
||||
.memory_environment = MEMORY_ENV_NORMAL,
|
||||
.optsize = SIZE_OPTIMIZATION_NOT_SET,
|
||||
.arch_os_target = ARCH_OS_TARGET_DEFAULT,
|
||||
.debug_info = DEBUG_INFO_NOT_SET,
|
||||
.symtab_size = DEFAULT_SYMTAB_SIZE,
|
||||
.cc = "cc",
|
||||
.version = "1.0.0",
|
||||
.langrev = "1",
|
||||
.cpu = "generic",
|
||||
.feature.x86_struct_return = STRUCT_RETURN_DEFAULT,
|
||||
.feature.soft_float = SOFT_FLOAT_DEFAULT,
|
||||
.feature.trap_on_wrap = false,
|
||||
.feature.x86_vector_capability = X86VECTOR_DEFAULT,
|
||||
.feature.x86_cpu_set = X86CPU_DEFAULT,
|
||||
.feature.safe_mode = SAFETY_NOT_SET,
|
||||
.win.crt_linking = WIN_CRT_DEFAULT,
|
||||
};
|
||||
BuildTarget default_target = default_build_target;
|
||||
load_into_build_target(project_data, "default target", &default_target, true);
|
||||
JSONObject *targets_json = json_obj_get(project_data, "targets");
|
||||
if (!targets_json)
|
||||
|
||||
@@ -278,7 +278,7 @@ void compiler_parse(void)
|
||||
global_context_clear_errors();
|
||||
|
||||
// Add the standard library
|
||||
if (global_context.lib_dir && !active_target.no_stdlib)
|
||||
if (global_context.lib_dir && !no_stdlib())
|
||||
{
|
||||
file_add_wildcard_files(&global_context.sources, global_context.lib_dir, true, c3_suffix_list, 3);
|
||||
}
|
||||
@@ -485,7 +485,8 @@ void compiler_compile(void)
|
||||
|
||||
if (output_exe)
|
||||
{
|
||||
if (!active_target.no_libc && platform_target.os != OS_TYPE_WIN32 && active_target.arch_os_target == default_target && !active_target.force_linker)
|
||||
if (link_libc() && platform_target.os != OS_TYPE_WIN32
|
||||
&& active_target.arch_os_target == default_target && active_target.system_linker != SYSTEM_LINKER_OFF)
|
||||
{
|
||||
platform_linker(output_exe, obj_files, output_file_count);
|
||||
compiler_link_time = bench_mark();
|
||||
@@ -855,11 +856,11 @@ void compile()
|
||||
setup_bool_define("PLATFORM_F16_SUPPORTED", platform_target.float16);
|
||||
setup_int_define("ARCH_TYPE", (uint64_t)platform_target.arch, type_int);
|
||||
setup_int_define("MEMORY_ENVIRONMENT", (uint64_t)active_target.memory_environment, type_int);
|
||||
setup_bool_define("COMPILER_LIBC_AVAILABLE", !active_target.no_libc);
|
||||
setup_bool_define("COMPILER_LIBC_AVAILABLE", link_libc());
|
||||
setup_int_define("COMPILER_OPT_LEVEL", (uint64_t)active_target.optlevel, type_int);
|
||||
setup_int_define("OS_TYPE", (uint64_t)platform_target.os, type_int);
|
||||
setup_int_define("COMPILER_SIZE_OPT_LEVEL", (uint64_t)active_target.optsize, type_int);
|
||||
setup_bool_define("COMPILER_SAFE_MODE", active_target.feature.safe_mode);
|
||||
setup_bool_define("COMPILER_SAFE_MODE", safe_mode_enabled());
|
||||
setup_bool_define("DEBUG_SYMBOLS", active_target.debug_info == DEBUG_INFO_FULL);
|
||||
setup_int_define("LLVM_VERSION", llvm_version_major, type_int);
|
||||
setup_bool_define("BENCHMARKING", active_target.benchmarking);
|
||||
|
||||
@@ -1941,6 +1941,26 @@ INLINE Type *typeinfotype(TypeInfoId id_)
|
||||
return id_ ? type_infoptr(id_)->type : NULL;
|
||||
}
|
||||
|
||||
INLINE bool safe_mode_enabled(void)
|
||||
{
|
||||
return active_target.feature.safe_mode != SAFETY_OFF;
|
||||
}
|
||||
|
||||
INLINE bool link_libc(void)
|
||||
{
|
||||
return active_target.link_libc != LINK_LIBC_OFF;
|
||||
}
|
||||
|
||||
INLINE bool strip_unused(void)
|
||||
{
|
||||
return active_target.strip_unused != STRIP_UNUSED_OFF;
|
||||
}
|
||||
|
||||
INLINE bool no_stdlib(void)
|
||||
{
|
||||
return active_target.use_stdlib == USE_STDLIB_OFF;
|
||||
}
|
||||
|
||||
bool ast_is_not_empty(Ast *ast);
|
||||
bool ast_is_compile_time(Ast *ast);
|
||||
bool ast_supports_continue(Ast *stmt);
|
||||
|
||||
@@ -96,7 +96,7 @@ static void linker_setup_windows(const char ***args_ref, LinkerType linker_type,
|
||||
default:
|
||||
UNREACHABLE
|
||||
}
|
||||
if (active_target.no_libc) return;
|
||||
if (!link_libc()) return;
|
||||
if (!active_target.win.sdk)
|
||||
{
|
||||
const char *path = windows_cross_compile_library();
|
||||
@@ -287,14 +287,14 @@ 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.no_strip_unused && active_target.type == TARGET_TYPE_EXECUTABLE)
|
||||
if (strip_unused() && active_target.type == TARGET_TYPE_EXECUTABLE)
|
||||
{
|
||||
add_arg("-no_exported_symbols");
|
||||
add_arg("-dead_strip");
|
||||
}
|
||||
|
||||
// Skip if no libc.
|
||||
if (active_target.no_libc) return;
|
||||
if (!link_libc()) return;
|
||||
|
||||
const char *sysroot = active_target.macos.sdk ? active_target.macos.sdk : macos_sysroot();
|
||||
if (!sysroot)
|
||||
@@ -395,11 +395,11 @@ static void linker_setup_linux(const char ***args_ref, LinkerType linker_type)
|
||||
if (is_no_pie(platform_target.reloc_model)) add_arg("-no-pie");
|
||||
if (is_pie(platform_target.reloc_model)) add_arg("-pie");
|
||||
if (platform_target.arch == ARCH_TYPE_X86_64) add_arg("--eh-frame-hdr");
|
||||
if (active_target.no_libc) return;
|
||||
if (!link_libc()) return;
|
||||
const char *crt_begin_dir = find_linux_crt_begin();
|
||||
const char *crt_dir = find_linux_crt();
|
||||
|
||||
if (!active_target.no_strip_unused && active_target.type == TARGET_TYPE_EXECUTABLE)
|
||||
if (strip_unused() && active_target.type == TARGET_TYPE_EXECUTABLE)
|
||||
{
|
||||
add_arg("--gc-sections");
|
||||
}
|
||||
@@ -442,14 +442,14 @@ static void linker_setup_freebsd(const char ***args_ref, LinkerType linker_type)
|
||||
if (is_pie(platform_target.reloc_model)) add_arg("-pie");
|
||||
if (platform_target.arch == ARCH_TYPE_X86_64) add_arg("--eh-frame-hdr");
|
||||
|
||||
if (active_target.no_libc) return;
|
||||
if (!link_libc()) return;
|
||||
|
||||
const char *crt_dir = find_freebsd_crt();
|
||||
if (!crt_dir)
|
||||
{
|
||||
error_exit("Failed to find the C runtime at link time.");
|
||||
}
|
||||
if (!active_target.no_strip_unused && active_target.type == TARGET_TYPE_EXECUTABLE)
|
||||
if (strip_unused() && active_target.type == TARGET_TYPE_EXECUTABLE)
|
||||
{
|
||||
add_arg("--gc-sections");
|
||||
}
|
||||
@@ -572,7 +572,7 @@ static bool linker_setup(const char ***args_ref, const char **files_to_link, uns
|
||||
linker_setup_linux(args_ref, linker_type);
|
||||
break;
|
||||
case OS_TYPE_UNKNOWN:
|
||||
if (!active_target.no_libc)
|
||||
if (link_libc())
|
||||
{
|
||||
error_exit("Linking is not supported for unknown OS.");
|
||||
}
|
||||
@@ -754,7 +754,7 @@ void platform_linker(const char *output_file, const char **files, unsigned file_
|
||||
vec_add(parts, active_target.cc ? active_target.cc : "cc");
|
||||
append_fpie_pic_options(platform_target.reloc_model, &parts);
|
||||
linker_setup(&parts, files, file_count, output_file, LINKER_CC);
|
||||
if (!active_target.no_libc)
|
||||
if (link_libc())
|
||||
{
|
||||
vec_add(parts, "-lm");
|
||||
}
|
||||
|
||||
@@ -1334,7 +1334,7 @@ void **llvm_gen(Module** modules, unsigned module_count)
|
||||
if (!module_count) return NULL;
|
||||
GenContext **gen_contexts = NULL;
|
||||
llvm_codegen_setup();
|
||||
if (active_target.single_module)
|
||||
if (active_target.single_module == SINGLE_MODULE_ON)
|
||||
{
|
||||
GenContext *first_context;
|
||||
unsigned first_element;
|
||||
@@ -1413,7 +1413,7 @@ static bool module_is_stdlib(Module *module)
|
||||
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;
|
||||
if (active_target.emit_stdlib == EMIT_STDLIB_OFF && module_is_stdlib(module)) return NULL;
|
||||
|
||||
assert(intrinsics_setup);
|
||||
|
||||
@@ -1422,7 +1422,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.no_strip_unused;
|
||||
bool only_used = strip_unused();
|
||||
|
||||
FOREACH_BEGIN(CompilationUnit *unit, module->units)
|
||||
|
||||
|
||||
@@ -667,13 +667,13 @@ static inline void gencontext_emit_subscript(GenContext *c, BEValue *value, Expr
|
||||
bool needs_len = false;
|
||||
if (parent_type_kind == TYPE_SUBARRAY)
|
||||
{
|
||||
needs_len = active_target.feature.safe_mode || expr->subscript_expr.range.start_from_end;
|
||||
needs_len = safe_mode_enabled() || expr->subscript_expr.range.start_from_end;
|
||||
}
|
||||
else if (parent_type_kind == TYPE_ARRAY)
|
||||
{
|
||||
// From back should always be folded.
|
||||
assert(!expr_is_const(expr) || !expr->subscript_expr.range.start_from_end);
|
||||
needs_len = (active_target.feature.safe_mode && !expr_is_const(expr)) || expr->subscript_expr.range.start_from_end;
|
||||
needs_len = (safe_mode_enabled() && !expr_is_const(expr)) || expr->subscript_expr.range.start_from_end;
|
||||
}
|
||||
if (needs_len)
|
||||
{
|
||||
@@ -694,7 +694,7 @@ static inline void gencontext_emit_subscript(GenContext *c, BEValue *value, Expr
|
||||
assert(needs_len);
|
||||
index.value = LLVMBuildNUWSub(c->builder, llvm_zext_trunc(c, len.value, llvm_get_type(c, index.type)), index.value, "");
|
||||
}
|
||||
if (needs_len && active_target.feature.safe_mode && !llvm_is_global_eval(c))
|
||||
if (needs_len && safe_mode_enabled() && !llvm_is_global_eval(c))
|
||||
{
|
||||
llvm_emit_array_bounds_check(c, &index, len.value, index_expr->span);
|
||||
}
|
||||
@@ -1510,7 +1510,7 @@ void llvm_emit_cast(GenContext *c, CastKind cast_kind, Expr *expr, BEValue *valu
|
||||
value->type = to_type;
|
||||
return;
|
||||
case CAST_INTENUM:
|
||||
if (active_target.feature.safe_mode && c->builder != c->global_builder)
|
||||
if (safe_mode_enabled() && c->builder != c->global_builder)
|
||||
{
|
||||
llvm_value_rvalue(c, value);
|
||||
BEValue check;
|
||||
@@ -2490,7 +2490,7 @@ static inline void llvm_emit_deref(GenContext *c, BEValue *value, Expr *inner, T
|
||||
}
|
||||
llvm_emit_expr(c, value, inner);
|
||||
llvm_value_rvalue(c, value);
|
||||
if (active_target.feature.safe_mode)
|
||||
if (safe_mode_enabled())
|
||||
{
|
||||
LLVMValueRef check = LLVMBuildICmp(c->builder, LLVMIntEQ, value->value, llvm_get_zero(c, inner->type), "checknull");
|
||||
scratch_buffer_clear();
|
||||
@@ -2714,7 +2714,7 @@ void llvm_emit_len_for_expr(GenContext *c, BEValue *be_value, BEValue *expr_to_l
|
||||
static void llvm_emit_trap_negative(GenContext *c, Expr *expr, LLVMValueRef value, const char *error,
|
||||
BEValue *index_val)
|
||||
{
|
||||
if (!active_target.feature.safe_mode) return;
|
||||
if (!safe_mode_enabled()) return;
|
||||
if (type_is_integer_unsigned(expr->type->canonical)) return;
|
||||
|
||||
LLVMValueRef zero = llvm_const_int(c, expr->type, 0);
|
||||
@@ -2724,7 +2724,7 @@ static void llvm_emit_trap_negative(GenContext *c, Expr *expr, LLVMValueRef valu
|
||||
|
||||
static void llvm_emit_trap_zero(GenContext *c, Type *type, LLVMValueRef value, const char *error, SourceSpan loc)
|
||||
{
|
||||
if (!active_target.feature.safe_mode) return;
|
||||
if (!safe_mode_enabled()) return;
|
||||
|
||||
assert(type == type_flatten(type));
|
||||
|
||||
@@ -2753,7 +2753,7 @@ static void llvm_emit_trap_zero(GenContext *c, Type *type, LLVMValueRef value, c
|
||||
|
||||
static void llvm_emit_trap_invalid_shift(GenContext *c, LLVMValueRef value, Type *type, const char *error, SourceSpan loc)
|
||||
{
|
||||
if (!active_target.feature.safe_mode) return;
|
||||
if (!safe_mode_enabled()) return;
|
||||
BEValue val;
|
||||
type = type_flatten(type);
|
||||
llvm_value_set(&val, value, type);
|
||||
@@ -2843,7 +2843,7 @@ static void llvm_emit_slice_values(GenContext *c, Expr *slice, BEValue *parent_r
|
||||
bool check_end = true;
|
||||
bool start_from_end = slice->subscript_expr.range.start_from_end;
|
||||
bool end_from_end = slice->subscript_expr.range.end_from_end;
|
||||
if (!end || start_from_end || end_from_end || active_target.feature.safe_mode)
|
||||
if (!end || start_from_end || end_from_end || safe_mode_enabled())
|
||||
{
|
||||
switch (parent_type->type_kind)
|
||||
{
|
||||
@@ -2872,7 +2872,7 @@ static void llvm_emit_slice_values(GenContext *c, Expr *slice, BEValue *parent_r
|
||||
}
|
||||
|
||||
// Check that index does not extend beyond the length.
|
||||
if (check_end && active_target.feature.safe_mode)
|
||||
if (check_end && safe_mode_enabled())
|
||||
{
|
||||
assert(len.value);
|
||||
BEValue exceeds_size;
|
||||
@@ -2908,7 +2908,7 @@ static void llvm_emit_slice_values(GenContext *c, Expr *slice, BEValue *parent_r
|
||||
}
|
||||
|
||||
// This will trap any bad negative index, so we're fine.
|
||||
if (active_target.feature.safe_mode && !is_len_range)
|
||||
if (safe_mode_enabled() && !is_len_range)
|
||||
{
|
||||
BEValue excess;
|
||||
llvm_emit_int_comp(c, &excess, &start_index, &end_index, BINARYOP_GT);
|
||||
@@ -3004,7 +3004,7 @@ static void llvm_emit_slice_copy(GenContext *c, BEValue *be_value, Expr *expr)
|
||||
llvm_emit_subarray_len(c, be_value, &from_len);
|
||||
llvm_value_rvalue(c, &from_len);
|
||||
|
||||
if (active_target.feature.safe_mode)
|
||||
if (safe_mode_enabled())
|
||||
{
|
||||
BEValue to_len;
|
||||
llvm_emit_subarray_len(c, &assigned_to, &to_len);
|
||||
@@ -6345,7 +6345,7 @@ static inline void llvm_emit_typeid_info(GenContext *c, BEValue *value, Expr *ex
|
||||
llvm_value_set(value, parent_value, expr->type);
|
||||
return;
|
||||
}
|
||||
bool safe_mode = active_target.feature.safe_mode;
|
||||
bool safe_mode = safe_mode_enabled();
|
||||
if (safe_mode || info_kind == TYPEID_INFO_KIND)
|
||||
{
|
||||
kind = llvm_emit_struct_gep_raw(c, ref, c->introspect_type, INTROSPECT_INDEX_KIND, align, &alignment);
|
||||
|
||||
@@ -176,7 +176,7 @@ static inline void llvm_process_parameter_value(GenContext *c, Decl *decl, ABIAr
|
||||
DIRECT_FROM_COERCE:
|
||||
{
|
||||
LLVMValueRef param_value = llvm_get_next_param(c, index);
|
||||
if (decl->var.not_null && active_target.feature.safe_mode)
|
||||
if (decl->var.not_null && safe_mode_enabled())
|
||||
{
|
||||
LLVMValueRef is_null = LLVMBuildIsNull(c->builder, param_value, "");
|
||||
scratch_buffer_clear();
|
||||
|
||||
@@ -157,7 +157,7 @@ void gencontext_begin_module(GenContext *c)
|
||||
|
||||
c->debug.runtime_version = 1;
|
||||
c->debug.builder = LLVMCreateDIBuilder(c->module);
|
||||
if (active_target.debug_info == DEBUG_INFO_FULL && active_target.feature.safe_mode)
|
||||
if (active_target.debug_info == DEBUG_INFO_FULL && safe_mode_enabled())
|
||||
{
|
||||
c->debug.stack_type = LLVMStructCreateNamed(c->context, ".$callstack");
|
||||
LLVMTypeRef types[5] = { c->ptr_type,
|
||||
|
||||
@@ -1001,7 +1001,7 @@ static inline void llvm_emit_assert_stmt(GenContext *c, Ast *ast)
|
||||
ExprId exprid = ast->assert_stmt.expr;
|
||||
Expr *assert_expr = exprptr(exprid);
|
||||
|
||||
if (active_target.feature.safe_mode)
|
||||
if (safe_mode_enabled())
|
||||
{
|
||||
BEValue value;
|
||||
llvm_emit_expr(c, &value, assert_expr);
|
||||
|
||||
@@ -150,7 +150,7 @@ static void sema_trace_stmt_liveness(Ast *ast)
|
||||
case AST_ASSERT_STMT:
|
||||
{
|
||||
Expr *e = exprptr(ast->assert_stmt.expr);
|
||||
if (active_target.feature.safe_mode || expr_is_pure(e))
|
||||
if (safe_mode_enabled() || expr_is_pure(e))
|
||||
{
|
||||
sema_trace_expr_liveness(e);
|
||||
}
|
||||
|
||||
@@ -2511,7 +2511,7 @@ static inline bool sema_analyse_ct_foreach_stmt(SemaContext *context, Ast *state
|
||||
initializer = collection->const_expr.initializer;
|
||||
ConstInitType init_type = initializer->kind;
|
||||
const_list_type = type_flatten(collection->type);
|
||||
if (const_list_type->type_kind == TYPE_ARRAY)
|
||||
if (const_list_type->type_kind == TYPE_ARRAY || const_list_type->type_kind == TYPE_VECTOR)
|
||||
{
|
||||
count = const_list_type->array.len;
|
||||
}
|
||||
@@ -2521,6 +2521,7 @@ static inline bool sema_analyse_ct_foreach_stmt(SemaContext *context, Ast *state
|
||||
if (init_type == CONST_INIT_ZERO)
|
||||
{
|
||||
sema_context_pop_ct_stack(context, ct_context);
|
||||
statement->ast_kind = AST_NOP_STMT;
|
||||
return true;
|
||||
}
|
||||
if (init_type != CONST_INIT_ARRAY_FULL)
|
||||
|
||||
@@ -241,7 +241,7 @@ static void sema_analyze_to_stage(AnalysisStage stage)
|
||||
|
||||
static void assign_panicfn(void)
|
||||
{
|
||||
if (!active_target.panicfn && active_target.no_stdlib)
|
||||
if (!active_target.panicfn && no_stdlib())
|
||||
{
|
||||
global_context.panic_var = NULL;
|
||||
global_context.panicf = NULL;
|
||||
@@ -272,7 +272,7 @@ static void assign_panicfn(void)
|
||||
global_context.panic_var = decl;
|
||||
decl->no_strip = true;
|
||||
|
||||
if (active_target.no_stdlib) return;
|
||||
if (no_stdlib()) return;
|
||||
|
||||
const char *panicf = "std::core::builtin::panicf";
|
||||
if (sema_splitpathref(panicf, strlen(panicf), &path, &ident) != TOKEN_IDENT || path == NULL || !ident)
|
||||
@@ -359,7 +359,7 @@ RESOLVE_LAMBDA:;
|
||||
|
||||
assign_panicfn();
|
||||
|
||||
if (!active_target.no_strip_unused)
|
||||
if (strip_unused())
|
||||
{
|
||||
sema_trace_liveness();
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
#define COMPILER_VERSION "0.4.649"
|
||||
#define COMPILER_VERSION "0.4.650"
|
||||
Reference in New Issue
Block a user