diff --git a/releasenotes.md b/releasenotes.md index 891c3cd21..6de1552e9 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -11,6 +11,7 @@ - `unsigned % signed` and `unsigned / signed` is no longer allowed without explicit casts, except for const denominators. #2928 - New const enum declaration syntax. - New enum associated value syntax. +- Individual warning settings added. ### Stdlib changes - Summarize sort macros as generic function wrappers to reduce the amount of generated code. #2831 diff --git a/src/build/build.h b/src/build/build.h index a2a8d7e4a..883391380 100644 --- a/src/build/build.h +++ b/src/build/build.h @@ -5,6 +5,7 @@ #include "../utils/lib.h" #include "../version.h" +#include "../compiler/enums.h" #include #define MAX_SYMTAB_SIZE (1024 * 1024) @@ -17,12 +18,6 @@ #define DEFAULT_SWITCH_JUMP_MAX_SIZE (0x3FFF) #define DEFAULT_PATH "." -typedef enum -{ - BACKEND_LLVM = 0, - BACKEND_TB = 1, - BACKEND_C = 2, -} CompilerBackend; typedef enum { @@ -82,346 +77,7 @@ typedef enum DIAG_END_SENTINEL } DiagnosticsType; -typedef enum -{ - DIAG_IGNORE = 0, - DIAG_WARN, - DIAG_ERROR, -} DiagnosticsSeverity; -typedef enum -{ - SAFETY_NOT_SET = -1, - SAFETY_OFF = 0, - SAFETY_ON = 1, -} SafetyLevel; - -typedef enum -{ - LINKER_TYPE_NOT_SET = -1, - LINKER_TYPE_BUILTIN = 0, - LINKER_TYPE_CC = 1, - LINKER_TYPE_CUSTOM = 2, -} LinkerType; - -typedef enum -{ - LINUX_LIBC_NOT_SET = -1, - LINUX_LIBC_GNU = 0, - LINUX_LIBC_MUSL = 1, - LINUX_LIBC_HOST = 2, -} LinuxLibc; - -typedef enum -{ - TRUST_NONE, - TRUST_INCLUDE, - TRUST_FULL -} TrustLevel; - -typedef enum -{ - COMPILE_NORMAL, - COMPILE_LEX_ONLY, - COMPILE_LEX_PARSE_ONLY, - COMPILE_LEX_PARSE_CHECK_ONLY, - COMPILE_OUTPUT_HEADERS, - COMPILE_OUTPUT_AST, -} CompileOption; - -typedef enum -{ - OPT_SETTING_NOT_SET = -1, - OPT_SETTING_O0 = 0, - OPT_SETTING_O1, - OPT_SETTING_O2, - OPT_SETTING_O3, - OPT_SETTING_O4, - OPT_SETTING_O5, - OPT_SETTING_OSMALL, - OPT_SETTING_OTINY, -} OptimizationSetting; - -typedef enum -{ - OPTIMIZATION_NOT_SET = -1, - OPTIMIZATION_NONE = 0, // -O0 - OPTIMIZATION_LESS = 1, // -O1 - OPTIMIZATION_MORE = 2, // -O2 - OPTIMIZATION_AGGRESSIVE = 3, // -O3 -} OptimizationLevel; - -typedef enum -{ - TESTLOGLEVEL_NOT_SET = -1, - TESTLOGLEVEL_VERBOSE = 0, - TESTLOGLEVEL_DEBUG = 1, - TESTLOGLEVEL_INFO = 2, - TESTLOGLEVEL_WARN = 3, - TESTLOGLEVEL_ERROR = 4, - TESTLOGLEVEL_CRITICAL = 5, -} TestLogLevel; - -typedef enum -{ - PANIC_NOT_SET = -1, - PANIC_OFF = 0, - PANIC_ON = 1, -} PanicLevel; - -typedef enum -{ - VALIDATION_NOT_SET = -1, - VALIDATION_LENIENT = 0, - VALIDATION_STRICT = 1, - VALIDATION_OBNOXIOUS = 2, -} ValidationLevel; - -typedef enum -{ - ANSI_DETECT = -1, - ANSI_OFF = 0, - ANSI_ON = 1 -} Ansi; - -typedef enum -{ - SINGLE_MODULE_NOT_SET = -1, - SINGLE_MODULE_OFF = 0, // NOLINT - SINGLE_MODULE_ON = 1 -} SingleModule; - -typedef enum -{ - UNROLL_LOOPS_NOT_SET = -1, - UNROLL_LOOPS_OFF = 0, - UNROLL_LOOPS_ON = 1 -} UnrollLoops; - -typedef enum -{ - MERGE_FUNCTIONS_NOT_SET = -1, - MERGE_FUNCTIONS_OFF = 0, - MERGE_FUNCTIONS_ON = 1 -} MergeFunctions; - -typedef enum -{ - VECTORIZATION_NOT_SET = -1, - VECTORIZATION_OFF = 0, - VECTORIZATION_ON = 1 -} AutoVectorization; -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 -{ - CUSTOM_LIBC_NOT_SET = -1, - CUSTOM_LIBC_OFF = 0, - CUSTOM_LIBC_ON = 1 -} CustomLibc; - -typedef enum -{ - SHOW_BACKTRACE_NOT_SET = -1, - SHOW_BACKTRACE_OFF = 0, - SHOW_BACKTRACE_ON = 1 -} ShowBacktrace; - - -typedef enum -{ - SIZE_OPTIMIZATION_NOT_SET = -1, - SIZE_OPTIMIZATION_NONE = 0, // None - SIZE_OPTIMIZATION_SMALL = 1, // -Os - SIZE_OPTIMIZATION_TINY = 2, // -Oz -} SizeOptimizationLevel; - -typedef enum -{ - SOFT_FLOAT_DEFAULT = -1, - SOFT_FLOAT_NONE = 0, - SOFT_FLOAT_YES = 1 -} SoftFloat; - -typedef enum -{ - WIN_DEBUG_DEFAULT = -1, - WIN_DEBUG_CODEVIEW = 0, - WIN_DEBUG_DWARF = 1 -} WinDebug; - -typedef enum -{ - WIN64_SIMD_DEFAULT = -1, - WIN64_SIMD_FULL = 0, - WIN64_SIMD_ARRAY = 1 -} Win64Simd; - -typedef enum -{ - STRUCT_RETURN_DEFAULT = -1, - STRUCT_RETURN_STACK = 0, // NOLINT - STRUCT_RETURN_REG = 1 -} StructReturn; - -typedef enum -{ - X86VECTOR_DEFAULT = -1, - X86VECTOR_NONE = 0, - X86VECTOR_MMX = 1, - X86VECTOR_SSE = 2, - X86VECTOR_AVX = 3, - X86VECTOR_AVX512 = 4, - X86VECTOR_CPU = 5, -} X86VectorCapability; - -typedef enum -{ - X86CPU_DEFAULT = -1, - X86CPU_BASELINE = 0, - X86CPU_SSSE3 = 1, - X86CPU_SSE4 = 2, - X86CPU_AVX1 = 3, - X86CPU_AVX2_V1 = 4, - X86CPU_AVX2_V2 = 5, - X86CPU_AVX512 = 6, - X86CPU_NATIVE = 7, -} X86CpuSet; - - -typedef enum -{ - RISCV_CPU_DEFAULT = -1, - RISCV_CPU_RVI = 0, - RISCV_CPU_RVIMAC = 1, - RISCV_CPU_RVIMAFC = 2, - RISCV_CPU_RVGC = 3, - RISCV_CPU_RVGCV = 4, -} RiscvCpuSet; - -typedef enum -{ - FP_DEFAULT = -1, - FP_STRICT = 0, - FP_RELAXED, - FP_FAST, -} FpOpt; - -typedef enum -{ - RISCV_ABI_DEFAULT = -1, - RISCV_ABI_INT_ONLY = 0, - RISCV_ABI_FLOAT = 1, - RISCV_ABI_DOUBLE = 2, -} RiscvAbi; - -typedef enum -{ - MEMORY_ENV_NOT_SET = -1, - MEMORY_ENV_NORMAL = 0, - MEMORY_ENV_SMALL = 1, - MEMORY_ENV_TINY = 2, - MEMORY_ENV_NONE = 3, -} MemoryEnvironment; - -typedef enum -{ - WIN_CRT_DEFAULT = -1, - WIN_CRT_NONE = 0, - WIN_CRT_DYNAMIC = 1, - WIN_CRT_DYNAMIC_DEBUG = 2, - WIN_CRT_STATIC = 3, - WIN_CRT_STATIC_DEBUG = 4, -} WinCrtLinking; - - -typedef enum -{ - RELOC_DEFAULT = -1, - RELOC_NONE = 0, - RELOC_SMALL_PIC = 1, - RELOC_BIG_PIC = 2, - RELOC_SMALL_PIE = 3, - RELOC_BIG_PIE = 4, -} RelocModel; - -typedef enum -{ - DEBUG_INFO_NOT_SET = -1, - DEBUG_INFO_NONE, - DEBUG_INFO_LINE_TABLES, - DEBUG_INFO_FULL -} DebugInfo; - -typedef enum -{ - ARCH_OS_TARGET_DEFAULT = -1, - ANDROID_AARCH64 = 0, - ANDROID_X86_64, - ELF_AARCH64, - ELF_RISCV32, - ELF_RISCV64, - ELF_X86, - ELF_X64, - ELF_XTENSA, - FREEBSD_X86, - FREEBSD_X64, - IOS_AARCH64, - LINUX_AARCH64, - LINUX_RISCV32, - LINUX_RISCV64, - LINUX_X86, - LINUX_X64, - MACOS_AARCH64, - MACOS_X64, - MCU_X86, - MINGW_X64, - NETBSD_AARCH64, - NETBSD_X86, - NETBSD_X64, - OPENBSD_X86, - OPENBSD_X64, - WASM32, - WASM64, - WINDOWS_AARCH64, - WINDOWS_X64, - ARCH_OS_TARGET_LAST = WINDOWS_X64 -} ArchOsTarget; - -typedef enum -{ - SANITIZE_NOT_SET = -1, - SANITIZE_NONE, - SANITIZE_ADDRESS, - SANITIZE_MEMORY, - SANITIZE_THREAD, -} SanitizeMode; #define ANY_WINDOWS_ARCH_OS WINDOWS_AARCH64: case WINDOWS_X64: case MINGW_X64 @@ -436,6 +92,13 @@ typedef enum TARGET_TYPE_PREPARE, } TargetType; +typedef struct +{ + WarningLevel deprecation; + WarningLevel methods_not_resolved; + WarningLevel dead_code; +} Warnings; + typedef enum { PROJECT_VIEW_TYPE_AUTHOR, @@ -550,7 +213,7 @@ typedef struct BuildOptions_ const char *custom_linker_path; uint32_t symtab_size; unsigned version; - bool silence_deprecation; + Warnings warnings; CompilerBackend backend; CompilerCommand command; struct @@ -748,7 +411,6 @@ typedef struct bool print_linking; bool no_entry; bool kernel_build; - bool silence_deprecation; bool print_stats; bool old_slice_copy; bool old_enums; @@ -797,6 +459,7 @@ typedef struct AuthorEntry *authors; const char **feature_list; const char *custom_linker_path; + Warnings warnings; struct { WinDebug win_debug; diff --git a/src/build/build_internal.h b/src/build/build_internal.h index 923dbd87c..0f1ca4c26 100644 --- a/src/build/build_internal.h +++ b/src/build/build_internal.h @@ -128,6 +128,13 @@ static const char *backends[3] = { [BACKEND_C] = "c", }; +static const char *warnings[4] = { + [WARNING_NOT_SET] = "%NOTSET%", + [WARNING_SILENT] = "no", + [WARNING_WARN] = "yes", + [WARNING_ERROR] = "error", +}; + static const char *validation_levels[3] = { [VALIDATION_LENIENT] = "lenient", [VALIDATION_STRICT] = "strict", diff --git a/src/build/build_options.c b/src/build/build_options.c index c2d367ae1..2d0a436e6 100644 --- a/src/build/build_options.c +++ b/src/build/build_options.c @@ -140,6 +140,9 @@ static void usage(bool full) print_opt("--use-old-slice-copy", "Use the old slice copy semantics."); print_opt("--use-old-enums", "Use the old enum syntax and semantics."); print_opt("--use-old-compact-eq", "Enable the old ability to use '@compact' to make a struct comparable."); + print_opt("--warn-deadcode=", "Print warning on dead-code: yes, no, error."); + print_opt("--warn-methodsnotresolved=", "Print warning on methods not resolved when accessed: yes, no, error."); + print_opt("--warn-deprecation=", "Print warning when using deprecated code and constructs: yes, no, error."); } PRINTF(""); print_opt("-g", "Emit debug info."); @@ -892,9 +895,25 @@ static void parse_option(BuildOptions *options) options->test_nosort = true; return; } + if ((argopt = match_argopt("warn-deadcode"))) + { + options->warnings.dead_code = parse_opt_select(WarningLevel, argopt, warnings); + return; + } + if ((argopt = match_argopt("warn-methodsnotresolved"))) + { + options->warnings.methods_not_resolved = parse_opt_select(WarningLevel, argopt, warnings); + return; + } + if ((argopt = match_argopt("warn-deprecation"))) + { + options->warnings.deprecation = parse_opt_select(WarningLevel, argopt, warnings); + silence_deprecation = options->warnings.deprecation == WARNING_SILENT; + return; + } if (match_longopt("silence-deprecation")) { - options->silence_deprecation = true; + options->warnings.deprecation = WARNING_SILENT; silence_deprecation = true; return; } diff --git a/src/build/builder.c b/src/build/builder.c index 5e8776538..74e2c2018 100644 --- a/src/build/builder.c +++ b/src/build/builder.c @@ -273,6 +273,17 @@ void update_build_target_with_opt_level(BuildTarget *target, OptimizationSetting COPY_IF_DEFAULT(target->single_module, single_module); } +static inline void update_warning(WarningLevel *level, WarningLevel new_level) +{ + if (new_level != WARNING_NOT_SET) *level = new_level; +} + +static inline void update_warning_if_not_set(WarningLevel *level, WarningLevel new_level) +{ + ASSERT(new_level != WARNING_NOT_SET); + if (*level == WARNING_NOT_SET) *level = new_level; +} + static LinkLibc libc_from_arch_os(ArchOsTarget target) { switch (target) @@ -517,7 +528,31 @@ static void update_build_target_from_options(BuildTarget *target, BuildOptions * if (!target->max_macro_iterations) target->max_macro_iterations = DEFAULT_MAX_MACRO_ITERATIONS; if (target->quiet && !options->verbosity_level) options->verbosity_level = -1; - if (options->silence_deprecation || options->verbosity_level < 0) target->silence_deprecation = true; + switch (target->validation_level) + { + case VALIDATION_LENIENT: + update_warning_if_not_set(&target->warnings.deprecation, WARNING_SILENT); + update_warning_if_not_set(&target->warnings.methods_not_resolved, WARNING_WARN); + update_warning_if_not_set(&target->warnings.dead_code, WARNING_SILENT); + break; + case VALIDATION_NOT_SET: + target->validation_level = VALIDATION_STRICT; + FALLTHROUGH; + case VALIDATION_STRICT: + update_warning_if_not_set(&target->warnings.methods_not_resolved, WARNING_WARN); + update_warning_if_not_set(&target->warnings.deprecation, WARNING_WARN); + update_warning_if_not_set(&target->warnings.dead_code, WARNING_WARN); + break; + case VALIDATION_OBNOXIOUS: + update_warning_if_not_set(&target->warnings.methods_not_resolved, WARNING_ERROR); + update_warning_if_not_set(&target->warnings.deprecation, WARNING_ERROR); + update_warning_if_not_set(&target->warnings.dead_code, WARNING_ERROR); + break; + } + update_warning(&target->warnings.deprecation, options->warnings.deprecation); + update_warning(&target->warnings.dead_code, options->warnings.dead_code); + update_warning(&target->warnings.methods_not_resolved, options->warnings.methods_not_resolved); + target->print_linking = options->print_linking || options->verbosity_level > 1; for (size_t i = 0; i < options->linker_arg_count; i++) diff --git a/src/compiler/compiler_internal.h b/src/compiler/compiler_internal.h index bdf4f486f..81e530339 100644 --- a/src/compiler/compiler_internal.h +++ b/src/compiler/compiler_internal.h @@ -6,7 +6,6 @@ #include "../utils/lib.h" #include "../build/build.h" #include "compiler.h" -#include "enums.h" #include "target.h" #include "utils/malloc.h" #include "subprocess.h" @@ -68,9 +67,9 @@ typedef uint16_t FileId; #define PRINT_ERROR_LAST(...) print_error_at(c->prev_span, __VA_ARGS__) #define RETURN_PRINT_ERROR_LAST(...) do { print_error_at(c->prev_span, __VA_ARGS__); return false; } while (0) #define SEMA_NOTE(_node, ...) sema_note_prev_at((_node)->span, __VA_ARGS__) -#define SEMA_DEPRECATED(_node, ...) do { if (compiler.build.test_output && !compiler.build.silence_deprecation) print_error_at((_node)->span, __VA_ARGS__); if (!compiler.build.silence_deprecation) \ +#define SEMA_DEPRECATED(_node, ...) do { if (compiler.build.test_output && compiler.build.warnings.deprecation > WARNING_SILENT) print_error_at((_node)->span, __VA_ARGS__); if (compiler.build.warnings.deprecation > WARNING_SILENT) \ print_deprecation_at((_node)->span, __VA_ARGS__); } while (0) -#define PRINT_DEPRECATED_AT(span__, ...) do { if (compiler.build.test_output && !compiler.build.silence_deprecation) print_error_at(span__, __VA_ARGS__); if (!compiler.build.silence_deprecation) \ +#define PRINT_DEPRECATED_AT(span__, ...) do { if (compiler.build.test_output && compiler.build.warnings.deprecation > WARNING_SILENT) print_error_at(span__, __VA_ARGS__); if (compiler.build.warnings.deprecation > WARNING_SILENT) \ print_deprecation_at(span__, __VA_ARGS__); } while (0) #define EXPAND_EXPR_STRING(str_) (str_)->const_expr.bytes.len, (str_)->const_expr.bytes.ptr diff --git a/src/compiler/diagnostics.c b/src/compiler/diagnostics.c index 7ac4f4977..aab554020 100644 --- a/src/compiler/diagnostics.c +++ b/src/compiler/diagnostics.c @@ -311,7 +311,7 @@ void print_deprecation_at(SourceSpan loc, const char *message, ...) // Ignore errors if (written <= MAX_ERROR_LEN - 2) { - print_error_type_at(loc, buffer, PRINT_TYPE_NOTE); + print_error_type_at(loc, buffer, compiler.build.warnings.deprecation == WARNING_WARN ? PRINT_TYPE_NOTE : PRINT_TYPE_ERROR); } static bool deprecation_hint = false; if (!compiler.build.lsp_output && !deprecation_hint) diff --git a/src/compiler/enums.h b/src/compiler/enums.h index 82573b066..4ba0ff942 100644 --- a/src/compiler/enums.h +++ b/src/compiler/enums.h @@ -11,6 +11,362 @@ #define FLAG_ATTR #endif +typedef enum +{ + DIAG_IGNORE = 0, + DIAG_WARN, + DIAG_ERROR, +} DiagnosticsSeverity; + +typedef enum +{ + SAFETY_NOT_SET = -1, + SAFETY_OFF = 0, + SAFETY_ON = 1, +} SafetyLevel; + +typedef enum +{ + LINKER_TYPE_NOT_SET = -1, + LINKER_TYPE_BUILTIN = 0, + LINKER_TYPE_CC = 1, + LINKER_TYPE_CUSTOM = 2, +} LinkerType; + +typedef enum +{ + LINUX_LIBC_NOT_SET = -1, + LINUX_LIBC_GNU = 0, + LINUX_LIBC_MUSL = 1, + LINUX_LIBC_HOST = 2, +} LinuxLibc; + +typedef enum +{ + TRUST_NONE, + TRUST_INCLUDE, + TRUST_FULL +} TrustLevel; + +typedef enum +{ + COMPILE_NORMAL, + COMPILE_LEX_ONLY, + COMPILE_LEX_PARSE_ONLY, + COMPILE_LEX_PARSE_CHECK_ONLY, + COMPILE_OUTPUT_HEADERS, + COMPILE_OUTPUT_AST, +} CompileOption; + +typedef enum +{ + OPT_SETTING_NOT_SET = -1, + OPT_SETTING_O0 = 0, + OPT_SETTING_O1, + OPT_SETTING_O2, + OPT_SETTING_O3, + OPT_SETTING_O4, + OPT_SETTING_O5, + OPT_SETTING_OSMALL, + OPT_SETTING_OTINY, +} OptimizationSetting; + +typedef enum +{ + OPTIMIZATION_NOT_SET = -1, + OPTIMIZATION_NONE = 0, // -O0 + OPTIMIZATION_LESS = 1, // -O1 + OPTIMIZATION_MORE = 2, // -O2 + OPTIMIZATION_AGGRESSIVE = 3, // -O3 +} OptimizationLevel; + +typedef enum +{ + TESTLOGLEVEL_NOT_SET = -1, + TESTLOGLEVEL_VERBOSE = 0, + TESTLOGLEVEL_DEBUG = 1, + TESTLOGLEVEL_INFO = 2, + TESTLOGLEVEL_WARN = 3, + TESTLOGLEVEL_ERROR = 4, + TESTLOGLEVEL_CRITICAL = 5, +} TestLogLevel; + +typedef enum +{ + PANIC_NOT_SET = -1, + PANIC_OFF = 0, + PANIC_ON = 1, +} PanicLevel; + +typedef enum +{ + VALIDATION_NOT_SET = -1, + VALIDATION_LENIENT = 0, + VALIDATION_STRICT = 1, + VALIDATION_OBNOXIOUS = 2, +} ValidationLevel; + +typedef enum +{ + ANSI_DETECT = -1, + ANSI_OFF = 0, + ANSI_ON = 1 +} Ansi; + +typedef enum +{ + SINGLE_MODULE_NOT_SET = -1, + SINGLE_MODULE_OFF = 0, // NOLINT + SINGLE_MODULE_ON = 1 +} SingleModule; + +typedef enum +{ + UNROLL_LOOPS_NOT_SET = -1, + UNROLL_LOOPS_OFF = 0, + UNROLL_LOOPS_ON = 1 +} UnrollLoops; + +typedef enum +{ + MERGE_FUNCTIONS_NOT_SET = -1, + MERGE_FUNCTIONS_OFF = 0, + MERGE_FUNCTIONS_ON = 1 +} MergeFunctions; + +typedef enum +{ + VECTORIZATION_NOT_SET = -1, + VECTORIZATION_OFF = 0, + VECTORIZATION_ON = 1 +} AutoVectorization; +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 +{ + CUSTOM_LIBC_NOT_SET = -1, + CUSTOM_LIBC_OFF = 0, + CUSTOM_LIBC_ON = 1 +} CustomLibc; + +typedef enum +{ + SHOW_BACKTRACE_NOT_SET = -1, + SHOW_BACKTRACE_OFF = 0, + SHOW_BACKTRACE_ON = 1 +} ShowBacktrace; + + +typedef enum +{ + SIZE_OPTIMIZATION_NOT_SET = -1, + SIZE_OPTIMIZATION_NONE = 0, // None + SIZE_OPTIMIZATION_SMALL = 1, // -Os + SIZE_OPTIMIZATION_TINY = 2, // -Oz +} SizeOptimizationLevel; + +typedef enum +{ + SOFT_FLOAT_DEFAULT = -1, + SOFT_FLOAT_NONE = 0, + SOFT_FLOAT_YES = 1 +} SoftFloat; + +typedef enum +{ + WIN_DEBUG_DEFAULT = -1, + WIN_DEBUG_CODEVIEW = 0, + WIN_DEBUG_DWARF = 1 +} WinDebug; + +typedef enum +{ + WIN64_SIMD_DEFAULT = -1, + WIN64_SIMD_FULL = 0, + WIN64_SIMD_ARRAY = 1 +} Win64Simd; + +typedef enum +{ + STRUCT_RETURN_DEFAULT = -1, + STRUCT_RETURN_STACK = 0, // NOLINT + STRUCT_RETURN_REG = 1 +} StructReturn; + +typedef enum +{ + X86VECTOR_DEFAULT = -1, + X86VECTOR_NONE = 0, + X86VECTOR_MMX = 1, + X86VECTOR_SSE = 2, + X86VECTOR_AVX = 3, + X86VECTOR_AVX512 = 4, + X86VECTOR_CPU = 5, +} X86VectorCapability; + +typedef enum +{ + X86CPU_DEFAULT = -1, + X86CPU_BASELINE = 0, + X86CPU_SSSE3 = 1, + X86CPU_SSE4 = 2, + X86CPU_AVX1 = 3, + X86CPU_AVX2_V1 = 4, + X86CPU_AVX2_V2 = 5, + X86CPU_AVX512 = 6, + X86CPU_NATIVE = 7, +} X86CpuSet; + + +typedef enum +{ + RISCV_CPU_DEFAULT = -1, + RISCV_CPU_RVI = 0, + RISCV_CPU_RVIMAC = 1, + RISCV_CPU_RVIMAFC = 2, + RISCV_CPU_RVGC = 3, + RISCV_CPU_RVGCV = 4, +} RiscvCpuSet; + +typedef enum +{ + FP_DEFAULT = -1, + FP_STRICT = 0, + FP_RELAXED, + FP_FAST, +} FpOpt; + +typedef enum +{ + RISCV_ABI_DEFAULT = -1, + RISCV_ABI_INT_ONLY = 0, + RISCV_ABI_FLOAT = 1, + RISCV_ABI_DOUBLE = 2, +} RiscvAbi; + +typedef enum +{ + MEMORY_ENV_NOT_SET = -1, + MEMORY_ENV_NORMAL = 0, + MEMORY_ENV_SMALL = 1, + MEMORY_ENV_TINY = 2, + MEMORY_ENV_NONE = 3, +} MemoryEnvironment; + +typedef enum +{ + WIN_CRT_DEFAULT = -1, + WIN_CRT_NONE = 0, + WIN_CRT_DYNAMIC = 1, + WIN_CRT_DYNAMIC_DEBUG = 2, + WIN_CRT_STATIC = 3, + WIN_CRT_STATIC_DEBUG = 4, +} WinCrtLinking; + + +typedef enum +{ + RELOC_DEFAULT = -1, + RELOC_NONE = 0, + RELOC_SMALL_PIC = 1, + RELOC_BIG_PIC = 2, + RELOC_SMALL_PIE = 3, + RELOC_BIG_PIE = 4, +} RelocModel; + +typedef enum +{ + DEBUG_INFO_NOT_SET = -1, + DEBUG_INFO_NONE, + DEBUG_INFO_LINE_TABLES, + DEBUG_INFO_FULL +} DebugInfo; + +typedef enum +{ + ARCH_OS_TARGET_DEFAULT = -1, + ANDROID_AARCH64 = 0, + ANDROID_X86_64, + ELF_AARCH64, + ELF_RISCV32, + ELF_RISCV64, + ELF_X86, + ELF_X64, + ELF_XTENSA, + FREEBSD_X86, + FREEBSD_X64, + IOS_AARCH64, + LINUX_AARCH64, + LINUX_RISCV32, + LINUX_RISCV64, + LINUX_X86, + LINUX_X64, + MACOS_AARCH64, + MACOS_X64, + MCU_X86, + MINGW_X64, + NETBSD_AARCH64, + NETBSD_X86, + NETBSD_X64, + OPENBSD_X86, + OPENBSD_X64, + WASM32, + WASM64, + WINDOWS_AARCH64, + WINDOWS_X64, + ARCH_OS_TARGET_LAST = WINDOWS_X64 +} ArchOsTarget; + +typedef enum +{ + SANITIZE_NOT_SET = -1, + SANITIZE_NONE, + SANITIZE_ADDRESS, + SANITIZE_MEMORY, + SANITIZE_THREAD, +} SanitizeMode; + +typedef enum +{ + BACKEND_LLVM = 0, + BACKEND_TB = 1, + BACKEND_C = 2, +} CompilerBackend; + +typedef enum +{ + WARNING_NOT_SET, + WARNING_SILENT, + WARNING_WARN, + WARNING_ERROR +} WarningLevel; + typedef enum { ABI_UNKNOWN, diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index 6bae6b1b2..4a84ecefa 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -5614,7 +5614,7 @@ CONTINUE: Decl *decl = type->decl; if (!decl->unit || decl->unit->module->stage < ANALYSIS_POST_REGISTER) { - bool err = SEMA_WARN(expr, "Methods are not fully determined for %s at this point.", decl->name); + bool err = SEMA_WARN(expr, methods_not_resolved, "Methods are not fully determined for %s at this point.", decl->name); if (err) return false; } // Interface, prefer interface methods. diff --git a/src/compiler/sema_internal.h b/src/compiler/sema_internal.h index 097a5d664..31646dfe4 100644 --- a/src/compiler/sema_internal.h +++ b/src/compiler/sema_internal.h @@ -17,7 +17,7 @@ #define UINT12_MAX 4095 #define UINT20_MAX 1048575U -#define SEMA_WARN(_node, ...) (sema_warn_at(context, (_node)->span, __VA_ARGS__)) +#define SEMA_WARN(_node, level_, ...) (sema_warn_at(context, (_node)->span, compiler.build.warnings. level_ , __VA_ARGS__)) #define SEMA_ERROR(_node, ...) sema_error_at(context, (_node)->span, __VA_ARGS__) #define RETURN_SEMA_ERROR(_node, ...) do { sema_error_at(context, (_node)->span, __VA_ARGS__); return false; } while (0) #define RETURN_VAL_SEMA_ERROR(val__, _node, ...) do { sema_error_at(context, (_node)->span, __VA_ARGS__); return (val__); } while (0) @@ -58,8 +58,7 @@ SemaContext *context_transform_for_eval(SemaContext *context, SemaContext *temp_ TokenType sema_splitpathref(const char *string, ArraySize len, Path **path_ref, const char **ident_ref); void sema_print_inline(SemaContext *context, SourceSpan span_original); void sema_error_at(SemaContext *context, SourceSpan span, const char *message, ...); -bool sema_warn_at(SemaContext *context, SourceSpan span, const char *message, ...); -bool sema_warn_very_strict(SemaContext *context, SourceSpan span, const char *message, ...); +bool sema_warn_at(SemaContext *context, SourceSpan span, WarningLevel warning, const char *message, ...); void sema_context_init(SemaContext *context, CompilationUnit *unit); void sema_context_destroy(SemaContext *context); @@ -217,13 +216,29 @@ INLINE void sema_display_deprecated_warning_on_use(SemaContext *context, Decl *d // Prevent multiple reports decl->attrs_resolved->deprecated = NULL; - if (compiler.build.silence_deprecation) return; - if (msg[0]) + switch (compiler.build.warnings.deprecation) { - sema_warning_at(span, "'%s' is deprecated: %s.", decl->name, msg); - return; + case WARNING_NOT_SET: + UNREACHABLE_VOID + case WARNING_SILENT: + return; + case WARNING_WARN: + if (msg[0]) + { + sema_warning_at(span, "'%s' is deprecated: %s.", decl->name, msg); + return; + } + sema_warning_at(span, "'%s' is deprecated.", decl->name); + return; + case WARNING_ERROR: + if (msg[0]) + { + print_error_at(span, "'%s' is deprecated: %s.", decl->name, msg); + return; + } + print_error_at(span, "'%s' is deprecated.", decl->name); + return; } - sema_warning_at(span, "'%s' is deprecated.", decl->name); } static inline IndexDiff range_const_len(Range *range) diff --git a/src/compiler/sema_stmts.c b/src/compiler/sema_stmts.c index afb1eb207..67a6514f0 100644 --- a/src/compiler/sema_stmts.c +++ b/src/compiler/sema_stmts.c @@ -2018,8 +2018,8 @@ static inline bool sema_analyse_if_stmt(SemaContext *context, Ast *statement) if (context->active_scope.end_jump.active && !context->active_scope.allow_dead_code) { context->active_scope.allow_dead_code = true; - bool warn = SEMA_WARN(statement, "This code will never execute."); - sema_note_prev_at(context->active_scope.end_jump.span, "This code is preventing it from exectuting"); + bool warn = SEMA_WARN(statement, dead_code, "This code will never execute."); + if (compiler.build.warnings.dead_code > WARNING_SILENT) sema_note_prev_at(context->active_scope.end_jump.span, "This code is preventing it from exectuting"); if (!warn) { success = false; @@ -3285,8 +3285,8 @@ bool sema_analyse_statement(SemaContext *context, Ast *statement) if (statement->ast_kind != AST_ASSERT_STMT && statement->ast_kind != AST_NOP_STMT && !(context->active_scope.flags & SCOPE_MACRO)) { context->active_scope.allow_dead_code = true; - bool warn = SEMA_WARN(statement, "This code will never execute."); - sema_note_prev_at(end_jump.span, "No code will execute after this statement."); + bool warn = SEMA_WARN(statement, dead_code, "This code will never execute."); + if (compiler.build.warnings.dead_code > WARNING_SILENT) sema_note_prev_at(end_jump.span, "No code will execute after this statement."); if (!warn) return ast_poison(statement); } // Remove it diff --git a/src/compiler/semantic_analyser.c b/src/compiler/semantic_analyser.c index 1b7503ce3..76da9002b 100644 --- a/src/compiler/semantic_analyser.c +++ b/src/compiler/semantic_analyser.c @@ -629,20 +629,11 @@ void sema_error_at(SemaContext *context, SourceSpan span, const char *message, . sema_print_inline(context, span); } -bool sema_warn_very_strict(SemaContext *context, SourceSpan span, const char *message, ...) -{ - if (compiler.build.validation_level < VALIDATION_OBNOXIOUS) return false; - va_list list; - va_start(list, message); - sema_verror_range(span, message, list); - va_end(list); - sema_print_inline(context, span); - return true; -} -bool sema_warn_at(SemaContext *context, SourceSpan span, const char *message, ...) +bool sema_warn_at(SemaContext *context, SourceSpan span, WarningLevel level, const char *message, ...) { - bool is_warn = compiler.build.validation_level < VALIDATION_STRICT; + if (level == WARNING_SILENT) return true; + bool is_warn = level != WARNING_ERROR; va_list list; va_start(list, message); if (is_warn) diff --git a/src/compiler/target.h b/src/compiler/target.h index b6e23b2c6..1716135c0 100644 --- a/src/compiler/target.h +++ b/src/compiler/target.h @@ -69,6 +69,7 @@ typedef struct #endif const char *cpu; const char *features; + Warnings warning; ArchType arch; OsType os; VendorType vendor;