mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
563 lines
11 KiB
C
563 lines
11 KiB
C
#pragma once
|
|
// Copyright (c) 2019-2023 Christoffer Lerno. All rights reserved.
|
|
// Use of this source code is governed by the GNU LGPLv3.0 license
|
|
// a copy of which can be found in the LICENSE file.
|
|
|
|
#include "../version.h"
|
|
#include "../utils/lib.h"
|
|
|
|
#define MAX_LIB_DIRS 1024
|
|
#define MAX_FILES 2048
|
|
#define MAX_INCLUDES 2048
|
|
#define MAX_THREADS 0xFFFF
|
|
#define DEFAULT_SYMTAB_SIZE (256 * 1024)
|
|
#define DEFAULT_SWITCHRANGE_MAX_SIZE (256)
|
|
|
|
typedef enum
|
|
{
|
|
BACKEND_LLVM = 1,
|
|
BACKEND_TB = 2
|
|
} CompilerBackend;
|
|
|
|
typedef enum
|
|
{
|
|
COMMAND_MISSING = 0,
|
|
COMMAND_COMPILE,
|
|
COMMAND_COMPILE_ONLY,
|
|
COMMAND_COMPILE_BENCHMARK,
|
|
COMMAND_COMPILE_TEST,
|
|
COMMAND_GENERATE_HEADERS,
|
|
COMMAND_INIT,
|
|
COMMAND_INIT_LIB,
|
|
COMMAND_BUILD,
|
|
COMMAND_COMPILE_RUN,
|
|
COMMAND_STATIC_LIB,
|
|
COMMAND_DYNAMIC_LIB,
|
|
COMMAND_RUN,
|
|
COMMAND_CLEAN_RUN,
|
|
COMMAND_CLEAN,
|
|
COMMAND_VENDOR_FETCH,
|
|
COMMAND_DIST,
|
|
COMMAND_DOCS,
|
|
COMMAND_BENCH,
|
|
COMMAND_BENCHMARK,
|
|
COMMAND_TEST,
|
|
COMMAND_UNIT_TEST,
|
|
COMMAND_PRINT_SYNTAX,
|
|
} CompilerCommand;
|
|
|
|
typedef enum
|
|
{
|
|
DIAG_NONE = 0, // Don't use!
|
|
DIAG_WARNING_TYPE, // Don't use!
|
|
DIAG_UNUSED,
|
|
DIAG_UNUSED_PARAMETER,
|
|
DIAG_UNUSED_FUNCTION,
|
|
DIAG_UNUSED_VARIABLE,
|
|
DIAG_UNUSED_IMPORT,
|
|
DIAG_UNUSED_MODULE,
|
|
DIAG_UNUSED_LABEL,
|
|
DIAG_UNUSED_PUBLIC,
|
|
DIAG_UNUSED_TYPE,
|
|
DIAG_CONVERSION,
|
|
DIAG_COVERED_SWITCH_DEFAULT,
|
|
DIAG_ERROR_TYPE, // Don't use this!
|
|
DIAG_DUPLICATE_ATTRIBUTE,
|
|
DIAG_NOT_IN_ENUM,
|
|
DIAG_MISSING_CASE,
|
|
DIAG_INT_TO_POINTER_CAST,
|
|
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
|
|
{
|
|
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
|
|
{
|
|
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,
|
|
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
|
|
{
|
|
STRUCT_RETURN_DEFAULT = -1,
|
|
STRUCT_RETURN_STACK = 0,
|
|
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_NATIVE = 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
|
|
{
|
|
FP_DEFAULT = -1,
|
|
FP_STRICT = 0,
|
|
FP_RELAXED,
|
|
FP_FAST,
|
|
} FpOpt;
|
|
|
|
typedef enum
|
|
{
|
|
RISCVFLOAT_DEFAULT = -1,
|
|
RISCVFLOAT_NONE = 0,
|
|
RISCVFLOAT_FLOAT = 1,
|
|
RISCVFLOAT_DOUBLE = 2,
|
|
} RiscvFloatCapability;
|
|
|
|
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_STATIC = 2,
|
|
} 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 = 0,
|
|
ELF_AARCH64,
|
|
ELF_RISCV32,
|
|
ELF_RISCV64,
|
|
ELF_X86,
|
|
ELF_X64,
|
|
FREEBSD_X86,
|
|
FREEBSD_X64,
|
|
LINUX_AARCH64,
|
|
LINUX_RISCV32,
|
|
LINUX_RISCV64,
|
|
LINUX_X86,
|
|
LINUX_X64,
|
|
MACOS_AARCH64,
|
|
MACOS_X64,
|
|
MCU_X86,
|
|
MINGW_X64,
|
|
NETBSD_X86,
|
|
NETBSD_X64,
|
|
OPENBSD_X86,
|
|
OPENBSD_X64,
|
|
WASM32,
|
|
WASM64,
|
|
WINDOWS_AARCH64,
|
|
WINDOWS_X64,
|
|
ARCH_OS_TARGET_LAST = WINDOWS_X64
|
|
} ArchOsTarget;
|
|
|
|
#define ANY_WINDOWS_ARCH_OS WINDOWS_AARCH64: case WINDOWS_X64: case MINGW_X64
|
|
|
|
typedef struct BuildOptions_
|
|
{
|
|
const char *lib_dir[MAX_LIB_DIRS];
|
|
int lib_dir_count;
|
|
const char *libs[MAX_LIB_DIRS];
|
|
int lib_count;
|
|
const char* linker_args[MAX_LIB_DIRS];
|
|
int linker_arg_count;
|
|
const char* linker_lib_dir[MAX_LIB_DIRS];
|
|
int linker_lib_dir_count;
|
|
const char* linker_libs[MAX_LIB_DIRS];
|
|
int linker_lib_count;
|
|
const char* std_lib_dir;
|
|
struct {
|
|
const char *sdk;
|
|
WinCrtLinking crt_linking;
|
|
} win;
|
|
struct {
|
|
const char *sysroot;
|
|
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;
|
|
const char **feature_names;
|
|
const char **removed_feature_names;
|
|
const char *output_name;
|
|
const char *project_name;
|
|
const char *target_select;
|
|
const char *path;
|
|
const char *template;
|
|
uint32_t symtab_size;
|
|
unsigned version;
|
|
CompilerBackend backend;
|
|
CompilerCommand command;
|
|
CompileOption compile_option;
|
|
TrustLevel trust_level;
|
|
DiagnosticsSeverity severity[DIAG_END_SENTINEL];
|
|
OptimizationSetting optsetting;
|
|
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_entry;
|
|
bool no_obj;
|
|
bool read_stdin;
|
|
bool print_output;
|
|
const char *panicfn;
|
|
const char *benchfn;
|
|
const char *testfn;
|
|
const char *cc;
|
|
const char *build_dir;
|
|
const char *llvm_out;
|
|
const char *asm_out;
|
|
const char *obj_out;
|
|
const char *script_dir;
|
|
RelocModel reloc_model;
|
|
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 print_keywords;
|
|
bool print_attributes;
|
|
bool print_builtins;
|
|
bool print_operators;
|
|
bool print_type_properties;
|
|
bool print_project_properties;
|
|
bool print_precedence;
|
|
bool print_build_settings;
|
|
bool print_linking;
|
|
bool benchmarking;
|
|
bool testing;
|
|
} BuildOptions;
|
|
|
|
typedef enum
|
|
{
|
|
TARGET_TYPE_EXECUTABLE,
|
|
TARGET_TYPE_STATIC_LIB,
|
|
TARGET_TYPE_DYNAMIC_LIB,
|
|
TARGET_TYPE_OBJECT_FILES,
|
|
TARGET_TYPE_BENCHMARK,
|
|
TARGET_TYPE_TEST,
|
|
} TargetType;
|
|
|
|
typedef struct
|
|
{
|
|
ArchOsTarget arch_os;
|
|
const char **execs;
|
|
const char **link_flags;
|
|
const char **linked_libs;
|
|
const char **depends;
|
|
} LibraryTarget;
|
|
|
|
typedef struct
|
|
{
|
|
const char *dir;
|
|
const char *provides;
|
|
const char **depends;
|
|
const char **execs;
|
|
LibraryTarget *target_used;
|
|
LibraryTarget **targets;
|
|
} Library;
|
|
|
|
|
|
typedef struct
|
|
{
|
|
TargetType type;
|
|
Library **library_list;
|
|
const char *name;
|
|
const char *version;
|
|
const char *langrev;
|
|
const char **source_dirs;
|
|
const char **sources;
|
|
const char **libdirs;
|
|
const char **libs;
|
|
const char **linker_libdirs;
|
|
const char **linker_libs;
|
|
const char *cpu;
|
|
const char **link_args;
|
|
const char *build_dir;
|
|
const char *object_file_dir;
|
|
const char *ir_file_dir;
|
|
const char *asm_file_dir;
|
|
const char *script_dir;
|
|
bool run_after_compile;
|
|
bool generate_benchmark_runner;
|
|
bool generate_test_runner;
|
|
bool benchmark_output;
|
|
bool test_output;
|
|
bool output_headers;
|
|
bool output_ast;
|
|
bool lex_only;
|
|
bool parse_only;
|
|
bool check_only;
|
|
bool emit_llvm;
|
|
bool emit_asm;
|
|
bool emit_object_files;
|
|
bool benchmarking;
|
|
bool testing;
|
|
bool read_stdin;
|
|
bool print_output;
|
|
bool print_linking;
|
|
bool no_entry;
|
|
int build_threads;
|
|
TrustLevel trust_level;
|
|
OptimizationSetting optsetting;
|
|
OptimizationLevel optlevel;
|
|
MemoryEnvironment memory_environment;
|
|
SizeOptimizationLevel optsize;
|
|
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;
|
|
const char *benchfn;
|
|
const char *testfn;
|
|
const char *cc;
|
|
const char *cflags;
|
|
const char **exec;
|
|
const char **csource_dirs;
|
|
const char **csources;
|
|
const char **feature_list;
|
|
struct
|
|
{
|
|
SoftFloat soft_float : 3;
|
|
StructReturn x86_struct_return : 3;
|
|
X86VectorCapability x86_vector_capability : 4;
|
|
RiscvFloatCapability riscv_float_capability : 4;
|
|
bool trap_on_wrap : 1;
|
|
FpOpt fp_math;
|
|
SafetyLevel safe_mode;
|
|
X86CpuSet x86_cpu_set;
|
|
} feature;
|
|
struct
|
|
{
|
|
const char *sysroot;
|
|
const char *min_version;
|
|
const char *sdk_version;
|
|
MacSDK *sdk;
|
|
} macos;
|
|
struct
|
|
{
|
|
const char *sdk;
|
|
WinCrtLinking crt_linking;
|
|
bool use_win_subsystem;
|
|
} win;
|
|
struct
|
|
{
|
|
const char *crt;
|
|
const char *crtbegin;
|
|
} linuxpaths;
|
|
} BuildTarget;
|
|
|
|
static const char *x86_cpu_set[8] = {
|
|
[X86CPU_BASELINE] = "baseline",
|
|
[X86CPU_SSSE3] = "ssse3",
|
|
[X86CPU_SSE4] = "sse4",
|
|
[X86CPU_AVX1] = "avx1",
|
|
[X86CPU_AVX2_V1] = "avx2-v1",
|
|
[X86CPU_AVX2_V2] = "avx2-v2",
|
|
[X86CPU_AVX512] = "avx512",
|
|
[X86CPU_NATIVE] = "native"
|
|
};
|
|
|
|
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,
|
|
};
|
|
|
|
BuildOptions parse_arguments(int argc, const char *argv[]);
|
|
ArchOsTarget arch_os_target_from_string(const char *target);
|
|
bool command_accepts_files(CompilerCommand command);
|
|
void update_build_target_with_opt_level(BuildTarget *target, OptimizationSetting level);
|
|
void create_project(BuildOptions *build_options);
|
|
void create_library(BuildOptions *build_options);
|