Fix JSON and compile issue.

This commit is contained in:
Christoffer Lerno
2024-06-23 17:40:56 +02:00
parent 7020569f45
commit b0b976ee52
4 changed files with 253 additions and 254 deletions

View File

@@ -48,138 +48,138 @@ const char *trust_level[3] = {
};
#define EOUTPUT(string, ...) fprintf(stderr, string "\n", ##__VA_ARGS__)
#define OUTPUT(string, ...) fprintf(stdout, string "\n", ##__VA_ARGS__)
#define PRINTF(string, ...) fprintf(stdout, string "\n", ##__VA_ARGS__) // NOLINT
#define FAIL_WITH_ERR(string, ...) do { fprintf(stderr, "Error: " string "\n\n", ##__VA_ARGS__); usage(); exit_compiler(EXIT_FAILURE); } while (0)
static void usage(void)
{
OUTPUT("Usage: %s [<options>] <command> [<args>]", args[0]);
OUTPUT("");
OUTPUT("Commands:");
OUTPUT("");
OUTPUT(" compile <file1> [<file2> ...] Compile files without a project into an executable.");
OUTPUT(" init <project name> Initialize a new project structure.");
OUTPUT(" init-lib <library name> Initialize a new library structure.");
OUTPUT(" build [<target>] Build the target in the current project.");
OUTPUT(" benchmark Run the benchmarks in the current project.");
OUTPUT(" test Run the unit tests in the current project.");
OUTPUT(" clean Clean all build files.");
OUTPUT(" run [<target>] Run (and build if needed) the target in the current project.");
OUTPUT(" dist [<target>] Clean and build a target for distribution.");
OUTPUT(" directives [<target>] Generate documentation for the target.");
OUTPUT(" bench [<target>] Benchmark a target.");
OUTPUT(" clean-run [<target>] Clean, then run the target.");
OUTPUT(" compile-run <file1> [<file2> ...] Compile files then immediately run the result.");
OUTPUT(" compile-only <file1> [<file2> ...] Compile files but do not perform linking.");
OUTPUT(" compile-benchmark <file1> [<file2> ...] Compile files into an executable and run benchmarks.");
OUTPUT(" compile-test <file1> [<file2> ...] Compile files into an executable and run unit tests.");
OUTPUT(" static-lib <file1> [<file2> ...] Compile files without a project into a static library.");
OUTPUT(" dynamic-lib <file1> [<file2> ...] Compile files without a project into a dynamic library.");
OUTPUT(" headers <file1> [<file2> ...] Analyse files and generate C headers for public methods.");
OUTPUT(" vendor-fetch <library> ... Fetches one or more libraries from the vendor collection.");
OUTPUT("");
OUTPUT("Options:");
OUTPUT(" --tb - Use Tilde Backend for compilation.");
OUTPUT(" --stdlib <dir> - Use this directory as the C3 standard library path.");
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.");
OUTPUT(" --path <dir> - Use this as the base directory for the current command.");
OUTPUT(" --template <template> - Select template for 'init': \"exe\", \"static-lib\", \"dynamic-lib\" or a path.");
OUTPUT(" --about - Prints a short description of C3.");
OUTPUT(" --symtab <value> - Sets the preferred symtab size.");
OUTPUT(" -V --version - Print version information.");
OUTPUT(" -E - Lex only.");
OUTPUT(" -P - Only parse and output the AST as JSON.");
OUTPUT(" -C - Only lex, parse and check.");
OUTPUT(" - - Read code from standard in.");
OUTPUT(" -o <file> - Write output to <file>.");
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, high optimization, single module, emit debug info.");
OUTPUT(" -O4 - Unsafe, highest optimization, relaxed maths, single module, emit debug info, no panic messages.");
OUTPUT(" -O5 - Unsafe, highest optimization, fast maths, single module, emit debug info, no panic messages.");
OUTPUT(" -Os - Unsafe, high optimization, small code, single module, no debug info, no panic messages.");
OUTPUT(" -Oz - Unsafe, high optimization, tiny code, single module, no debug info, no panic messages.");
OUTPUT(" -D <name> - Add feature flag <name>.");
OUTPUT(" -U <name> - Remove feature flag <name>.");
OUTPUT(" --trust=<option> - Trust level: none (default), include ($include allowed), full ($exec / exec allowed).");
OUTPUT(" --output-dir <dir> - Override general output directory.");
OUTPUT(" --build-dir <dir> - Override build output directory.");
OUTPUT(" --obj-out <dir> - Override object file output directory.");
OUTPUT(" --script-dir <dir> - Override the base directory for $exec.");
OUTPUT(" --llvm-out <dir> - Override llvm output directory for '--emit-llvm'.");
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(" --obj - Emit object files. (Enabled by default)");
OUTPUT(" --no-obj - Do not output object files, this is only valid for `compile-only`.");
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(" --panic-msg=<yes|no> - Turn panic message output 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.");
OUTPUT("");
OUTPUT("");
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(" --cc <path> - Set C compiler (for C files in projects and use as system linker).");
OUTPUT(" --linker=<option> [<path>] - Linker: builtin, cc, custom (default is 'cc'), 'custom' requires a path.");
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(" --testfn <name> - Override the test runner function name.");
OUTPUT(" --benchfn <name> - Override the benchmark runner 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, default.");
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=<yes|no> - Strip unused code and globals from the output. (default: yes)");
OUTPUT(" --fp-math=<option> - FP math behaviour: strict, relaxed, fast.");
OUTPUT(" --win64-simd=<option> - Win64 SIMD ABI: array, full.");
OUTPUT("");
OUTPUT(" --debug-stats - Print debug statistics.");
OUTPUT(" --print-linking - Print linker arguments.");
PRINTF("Usage: %s [<options>] <command> [<args>]", args[0]);
PRINTF("");
PRINTF("Commands:");
PRINTF("");
PRINTF(" compile <file1> [<file2> ...] Compile files without a project into an executable.");
PRINTF(" init <project name> Initialize a new project structure.");
PRINTF(" init-lib <library name> Initialize a new library structure.");
PRINTF(" build [<target>] Build the target in the current project.");
PRINTF(" benchmark Run the benchmarks in the current project.");
PRINTF(" test Run the unit tests in the current project.");
PRINTF(" clean Clean all build files.");
PRINTF(" run [<target>] Run (and build if needed) the target in the current project.");
PRINTF(" dist [<target>] Clean and build a target for distribution.");
PRINTF(" directives [<target>] Generate documentation for the target.");
PRINTF(" bench [<target>] Benchmark a target.");
PRINTF(" clean-run [<target>] Clean, then run the target.");
PRINTF(" compile-run <file1> [<file2> ...] Compile files then immediately run the result.");
PRINTF(" compile-only <file1> [<file2> ...] Compile files but do not perform linking.");
PRINTF(" compile-benchmark <file1> [<file2> ...] Compile files into an executable and run benchmarks.");
PRINTF(" compile-test <file1> [<file2> ...] Compile files into an executable and run unit tests.");
PRINTF(" static-lib <file1> [<file2> ...] Compile files without a project into a static library.");
PRINTF(" dynamic-lib <file1> [<file2> ...] Compile files without a project into a dynamic library.");
PRINTF(" headers <file1> [<file2> ...] Analyse files and generate C headers for public methods.");
PRINTF(" vendor-fetch <library> ... Fetches one or more libraries from the vendor collection.");
PRINTF("");
PRINTF("Options:");
PRINTF(" --tb - Use Tilde Backend for compilation.");
PRINTF(" --stdlib <dir> - Use this directory as the C3 standard library path.");
PRINTF(" --no-entry - Do not generate (or require) a main function.");
PRINTF(" --libdir <dir> - Add this directory to the C3 library search paths.");
PRINTF(" --lib <name> - Add this library to the compilation.");
PRINTF(" --path <dir> - Use this as the base directory for the current command.");
PRINTF(" --template <template> - Select template for 'init': \"exe\", \"static-lib\", \"dynamic-lib\" or a path.");
PRINTF(" --about - Prints a short description of C3.");
PRINTF(" --symtab <value> - Sets the preferred symtab size.");
PRINTF(" -V --version - Print version information.");
PRINTF(" -E - Lex only.");
PRINTF(" -P - Only parse and output the AST as JSON.");
PRINTF(" -C - Only lex, parse and check.");
PRINTF(" - - Read code from standard in.");
PRINTF(" -o <file> - Write output to <file>.");
PRINTF(" -O0 - Safe, no optimizations, emit debug info.");
PRINTF(" -O1 - Safe, high optimization, emit debug info.");
PRINTF(" -O2 - Unsafe, high optimization, emit debug info.");
PRINTF(" -O3 - Unsafe, high optimization, single module, emit debug info.");
PRINTF(" -O4 - Unsafe, highest optimization, relaxed maths, single module, emit debug info, no panic messages.");
PRINTF(" -O5 - Unsafe, highest optimization, fast maths, single module, emit debug info, no panic messages.");
PRINTF(" -Os - Unsafe, high optimization, small code, single module, no debug info, no panic messages.");
PRINTF(" -Oz - Unsafe, high optimization, tiny code, single module, no debug info, no panic messages.");
PRINTF(" -D <name> - Add feature flag <name>.");
PRINTF(" -U <name> - Remove feature flag <name>.");
PRINTF(" --trust=<option> - Trust level: none (default), include ($include allowed), full ($exec / exec allowed).");
PRINTF(" --output-dir <dir> - Override general output directory.");
PRINTF(" --build-dir <dir> - Override build output directory.");
PRINTF(" --obj-out <dir> - Override object file output directory.");
PRINTF(" --script-dir <dir> - Override the base directory for $exec.");
PRINTF(" --llvm-out <dir> - Override llvm output directory for '--emit-llvm'.");
PRINTF(" --emit-llvm - Emit LLVM IR as a .ll file per module.");
PRINTF(" --asm-out <dir> - Override asm output directory for '--emit-asm'.");
PRINTF(" --emit-asm - Emit asm as a .s file per module.");
PRINTF(" --obj - Emit object files. (Enabled by default)");
PRINTF(" --no-obj - Do not output object files, this is only valid for `compile-only`.");
PRINTF(" --target <target> - Compile for a particular architecture + OS target.");
PRINTF(" --threads <number> - Set the number of threads to use for compilation.");
PRINTF(" --safe=<yes|no> - Turn safety (contracts, runtime bounds checking, null pointer checks etc) on or off.");
PRINTF(" --panic-msg=<yes|no> - Turn panic message output on or off.");
PRINTF(" --optlevel=<option> - Code optimization level: none, less, more, max.");
PRINTF(" --optsize=<option> - Code size optimization: none, small, tiny.");
PRINTF(" --single-module=<yes|no> - Compile all modules together, enables more inlining.");
PRINTF("");
PRINTF(" -g - Emit debug info.");
PRINTF(" -g0 - Emit no debug info.");
PRINTF("");
PRINTF("");
PRINTF(" -l <library> - Link with the library provided.");
PRINTF(" -L <library dir> - Append the directory to the linker search paths.");
PRINTF(" -z <argument> - Send the <argument> as a parameter to the linker.");
PRINTF(" --cc <path> - Set C compiler (for C files in projects and use as system linker).");
PRINTF(" --linker=<option> [<path>] - Linker: builtin, cc, custom (default is 'cc'), 'custom' requires a path.");
PRINTF("");
PRINTF(" --use-stdlib=<yes|no> - Include the standard library (default: yes).");
PRINTF(" --link-libc=<yes|no> - Link libc other default libraries (default: yes).");
PRINTF(" --emit-stdlib=<yes|no> - Output files for the standard library. (default: yes)");
PRINTF(" --panicfn <name> - Override the panic function name.");
PRINTF(" --testfn <name> - Override the test runner function name.");
PRINTF(" --benchfn <name> - Override the benchmark runner function name.");
PRINTF("");
PRINTF(" --reloc=<option> - Relocation model: none, pic, PIC, pie, PIE.");
PRINTF(" --x86cpu=<option> - Set general level of x64 cpu: baseline, ssse3, sse4, avx1, avx2-v1, avx2-v2 (Skylake/Zen1+), avx512 (Icelake/Zen4+), native.");
PRINTF(" --x86vec=<option> - Set max type of vector use: none, mmx, sse, avx, avx512, default.");
PRINTF(" --riscvfloat=<option> - Set type of RISC-V float support: none, float, double");
PRINTF(" --memory-env=<option> - Set the memory environment: normal, small, tiny, none.");
PRINTF(" --strip-unused=<yes|no> - Strip unused code and globals from the output. (default: yes)");
PRINTF(" --fp-math=<option> - FP math behaviour: strict, relaxed, fast.");
PRINTF(" --win64-simd=<option> - Win64 SIMD ABI: array, full.");
PRINTF("");
PRINTF(" --debug-stats - Print debug statistics.");
PRINTF(" --print-linking - Print linker arguments.");
#ifndef NDEBUG
OUTPUT(" --debug-log - Print debug logging to stdout.");
PRINTF(" --debug-log - Print debug logging to stdout.");
#endif
OUTPUT("");
OUTPUT(" --benchmarking - Run built-in benchmarks.");
OUTPUT(" --testing - Run built-in tests.");
OUTPUT("");
OUTPUT(" --list-attributes - List all attributes.");
OUTPUT(" --list-builtins - List all builtins.");
OUTPUT(" --list-keywords - List all keywords.");
OUTPUT(" --list-operators - List all operators.");
OUTPUT(" --list-precedence - List operator precedence order.");
OUTPUT(" --list-project-properties - List all available keys used in project.json files.");
OUTPUT(" --list-targets - List all architectures the compiler supports.");
OUTPUT(" --list-type-properties - List all type properties.");
OUTPUT("");
OUTPUT(" --print-output - Print the object files created to stdout.");
OUTPUT(" --print-input - Print inputted C3 files to stdout.");
OUTPUT("");
OUTPUT(" --winsdk <dir> - Set the directory for Windows system library files for cross compilation.");
OUTPUT(" --wincrt=<option> - Windows CRT linking: none, static, dynamic (default).");
OUTPUT(" --windef <file> - Use Windows 'def' file for function exports instead of 'dllexport'.");
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.");
PRINTF("");
PRINTF(" --benchmarking - Run built-in benchmarks.");
PRINTF(" --testing - Run built-in tests.");
PRINTF("");
PRINTF(" --list-attributes - List all attributes.");
PRINTF(" --list-builtins - List all builtins.");
PRINTF(" --list-keywords - List all keywords.");
PRINTF(" --list-operators - List all operators.");
PRINTF(" --list-precedence - List operator precedence order.");
PRINTF(" --list-project-properties - List all available keys used in project.json files.");
PRINTF(" --list-targets - List all architectures the compiler supports.");
PRINTF(" --list-type-properties - List all type properties.");
PRINTF("");
PRINTF(" --print-output - Print the object files created to stdout.");
PRINTF(" --print-input - Print inputted C3 files to stdout.");
PRINTF("");
PRINTF(" --winsdk <dir> - Set the directory for Windows system library files for cross compilation.");
PRINTF(" --wincrt=<option> - Windows CRT linking: none, static, dynamic (default).");
PRINTF(" --windef <file> - Use Windows 'def' file for function exports instead of 'dllexport'.");
PRINTF("");
PRINTF(" --macossdk <dir> - Set the directory for the MacOS SDK for cross compilation.");
PRINTF(" --macos-min-version <ver> - Set the minimum MacOS version to compile for.");
PRINTF(" --macos-sdk-version <ver> - Set the MacOS SDK compiled for.");
PRINTF("");
PRINTF(" --linux-crt <dir> - Set the directory to use for finding crt1.o and related files.");
PRINTF(" --linux-crtbegin <dir> - Set the directory to use for finding crtbegin.o and related files.");
}
@@ -391,19 +391,19 @@ static void parse_command(BuildOptions *options)
}
static void print_all_targets(void)
{
OUTPUT("Available targets:");
PRINTF("Available targets:");
for (unsigned i = 1; i <= ARCH_OS_TARGET_LAST; i++)
{
OUTPUT(" %s", arch_os_target[i]);
PRINTF(" %s", arch_os_target[i]);
}
}
static void print_version(void)
{
OUTPUT("C3 Compiler Version: %s%s", COMPILER_VERSION, PRERELEASE ? " (prerelease)" : "");
OUTPUT("Installed directory: %s", find_executable_path());
OUTPUT("LLVM version: %s", llvm_version);
OUTPUT("LLVM default target: %s", llvm_target);
PRINTF("C3 Compiler Version: %s%s", COMPILER_VERSION, PRERELEASE ? " (prerelease)" : "");
PRINTF("Installed directory: %s", find_executable_path());
PRINTF("LLVM version: %s", llvm_version);
PRINTF("LLVM default target: %s", llvm_target);
}
static void add_linker_arg(BuildOptions *options, const char *arg)
@@ -649,7 +649,7 @@ static void parse_option(BuildOptions *options)
if (at_end() || next_is_opt()) error_exit("error: --symtab needs a valid integer.");
const char *symtab_string = next_arg();
int symtab = atoi(symtab_string);
if (symtab < 1024) OUTPUT("Expected a valid positive integer >= 1024.");
if (symtab < 1024) PRINTF("Expected a valid positive integer >= 1024.");
options->symtab_size = next_highest_power_of_2(symtab);
return;
}
@@ -751,8 +751,8 @@ static void parse_option(BuildOptions *options)
}
if (match_longopt("about"))
{
OUTPUT("The C3 Compiler");
OUTPUT("C3 is low level programming language based on C.");
PRINTF("The C3 Compiler");
PRINTF("C3 is low level programming language based on C.");
exit_compiler(COMPILER_SUCCESS_EXIT);
}
if (match_longopt("no-obj"))
@@ -828,8 +828,8 @@ static void parse_option(BuildOptions *options)
if (at_end() || next_is_opt()) error_exit("error: --threads needs a valid integer 1 or higher.");
const char *thread_string = next_arg();
int threads = atoi(thread_string);
if (threads < 1) OUTPUT("Expected a valid integer 1 or higher.");
if (threads > MAX_THREADS) OUTPUT("Cannot exceed %d threads.", MAX_THREADS);
if (threads < 1) PRINTF("Expected a valid integer 1 or higher.");
if (threads > MAX_THREADS) PRINTF("Cannot exceed %d threads.", MAX_THREADS);
options->build_threads = threads;
return;
}
@@ -843,7 +843,7 @@ static void parse_option(BuildOptions *options)
options->arch_os_target_override = target_arch_os;
return;
}
OUTPUT("Available targets:");
PRINTF("Available targets:");
EOUTPUT("Invalid target %s.", target);
EOUTPUT("These targets are supported:");
for (unsigned i = 1; i <= ARCH_OS_TARGET_LAST; i++)

View File

@@ -4,7 +4,7 @@
#include "compiler_internal.h"
#define OUTPUT(x, ...) fprintf(file, x, ## __VA_ARGS__)
#define PRINTF(x, ...) fprintf(file, x, ## __VA_ARGS__)
#define INDENT() indent_line(file, indent)
#define OUT(file, x, ...) fprintf(file, x, ## __VA_ARGS__)
@@ -37,7 +37,7 @@ static void header_print_type(FILE *file, Type *type)
{
if (type_is_func_pointer(type))
{
OUTPUT("%s", decl_get_extname(type->decl));
PRINTF("%s", decl_get_extname(type->decl));
return;
}
assert(!type_is_optional(type));
@@ -48,116 +48,116 @@ static void header_print_type(FILE *file, Type *type)
case TYPE_OPTIONAL:
UNREACHABLE
case TYPE_VOID:
OUTPUT("void");
PRINTF("void");
return;
case TYPE_BOOL:
OUTPUT("bool");
PRINTF("bool");
return;
case TYPE_I8:
OUTPUT("int8_t");
PRINTF("int8_t");
return;
case TYPE_I16:
OUTPUT("int16_t");
PRINTF("int16_t");
return;
case TYPE_I32:
OUTPUT("int32_t");
PRINTF("int32_t");
return;
case TYPE_I64:
OUTPUT("int64_t");
PRINTF("int64_t");
return;
case TYPE_I128:
OUTPUT("__int128");
PRINTF("__int128");
return;
case TYPE_U8:
OUTPUT("uint8_t");
PRINTF("uint8_t");
return;
case TYPE_U16:
OUTPUT("uint16_t");
PRINTF("uint16_t");
return;
case TYPE_U32:
OUTPUT("uint32_t");
PRINTF("uint32_t");
return;
case TYPE_U64:
OUTPUT("uint64_t");
PRINTF("uint64_t");
return;
case TYPE_U128:
OUTPUT("unsigned __int128");
PRINTF("unsigned __int128");
return;
case TYPE_BF16:
OUTPUT("__bf16");
PRINTF("__bf16");
return;
case TYPE_F16:
OUTPUT("__fp16");
PRINTF("__fp16");
return;
case TYPE_F32:
OUTPUT("float");
PRINTF("float");
return;
case TYPE_F64:
OUTPUT("double");
PRINTF("double");
return;
case TYPE_F128:
OUTPUT("__float128");
PRINTF("__float128");
return;
case TYPE_TYPEID:
OUTPUT("c3typeid_t");
PRINTF("c3typeid_t");
return;
case TYPE_POINTER:
header_print_type(file, type->pointer);
OUTPUT("*");
PRINTF("*");
return;
case TYPE_FUNC_PTR:
type = type->pointer;
FALLTHROUGH;
case TYPE_FUNC_RAW:
OUTPUT("%s", decl_get_extname(type->function.decl));
PRINTF("%s", decl_get_extname(type->function.decl));
return;
case TYPE_STRUCT:
case TYPE_UNION:
case TYPE_ENUM:
OUTPUT("%s", decl_get_extname(type->decl));
PRINTF("%s", decl_get_extname(type->decl));
return;
case TYPE_BITSTRUCT:
header_print_type(file, type->decl->bitstruct.base_type->type);
return;
case TYPE_ANYFAULT:
case TYPE_FAULTTYPE:
OUTPUT("c3fault_t");
PRINTF("c3fault_t");
return;
case TYPE_DISTINCT:
case TYPE_TYPEDEF:
UNREACHABLE
case TYPE_FLEXIBLE_ARRAY:
header_print_type(file, type->array.base);
OUTPUT("[]");
PRINTF("[]");
return;
case TYPE_ARRAY:
OUTPUT("struct { ");
PRINTF("struct { ");
header_print_type(file, type->array.base);
OUTPUT(" arr[%d]; }", type->array.len);
PRINTF(" arr[%d]; }", type->array.len);
return;
case TYPE_ANY:
case TYPE_INTERFACE:
OUTPUT("c3any_t");
PRINTF("c3any_t");
return;
case TYPE_SLICE:
OUTPUT("c3slice_t");
PRINTF("c3slice_t");
return;
case TYPE_VECTOR:
switch (type->array.base->type_kind)
{
case ALL_SIGNED_INTS:
OUTPUT("int");
PRINTF("int");
break;
case ALL_UNSIGNED_INTS:
OUTPUT("uint");
PRINTF("uint");
break;
case ALL_FLOATS:
OUTPUT("float");
PRINTF("float");
break;
default:
UNREACHABLE;
}
OUTPUT("%dx%d", (int)type_bit_size(type->array.base), type->array.len);
PRINTF("%dx%d", (int)type_bit_size(type->array.base), type->array.len);
return;
}
}
@@ -179,32 +179,32 @@ static void header_gen_function_ptr(FILE *file, HTable *table, Type *type)
header_gen_maybe_generate_type(file, table, param->type);
FOREACH_END();
OUTPUT("typedef ");
PRINTF("typedef ");
header_print_type(file, rtype);
OUTPUT("(*%s)(", decl_get_extname(type->decl));
PRINTF("(*%s)(", decl_get_extname(type->decl));
if (!vec_size(sig->params) && !extra_ret)
{
OUTPUT("void);\n");
PRINTF("void);\n");
return;
}
if (extra_ret)
{
header_print_type(file, type_get_ptr(extra_ret));
OUTPUT(" return_ref");
PRINTF(" return_ref");
}
FOREACH_BEGIN_IDX(i, Decl *param, sig->params)
if (i || extra_ret) OUTPUT(", ");
if (i || extra_ret) PRINTF(", ");
header_print_type(file, param->type);
if (param->name) OUTPUT(" %s", param->name);
if (param->name) PRINTF(" %s", param->name);
FOREACH_END();
OUTPUT(");\n");
PRINTF(");\n");
}
static void header_gen_function(FILE *file, FILE *file_types, HTable *table, Decl *decl)
{
if (!decl->is_export) return;
Signature *sig = &decl->func_decl.signature;
OUTPUT("extern ");
PRINTF("extern ");
Type *rtype = typeget(sig->rtype);
Type *extra_ret = NULL;
if (type_is_optional(rtype))
@@ -215,24 +215,24 @@ static void header_gen_function(FILE *file, FILE *file_types, HTable *table, Dec
}
header_gen_maybe_generate_type(file_types, table, rtype);
header_print_type(file, rtype);
OUTPUT(" %s(", decl_get_extname(decl));
PRINTF(" %s(", decl_get_extname(decl));
if (!vec_size(sig->params) && !extra_ret)
{
OUTPUT("void);\n");
PRINTF("void);\n");
return;
}
if (extra_ret)
{
header_print_type(file, type_get_ptr(extra_ret));
OUTPUT(" return_ref");
PRINTF(" return_ref");
}
FOREACH_BEGIN_IDX(i, Decl *param, sig->params)
if (i || extra_ret) OUTPUT(", ");
if (i || extra_ret) PRINTF(", ");
header_print_type(file, param->type);
header_gen_maybe_generate_type(file_types, table, param->type);
if (param->name) OUTPUT(" %s", param->name);
if (param->name) PRINTF(" %s", param->name);
FOREACH_END();
OUTPUT(");\n");
PRINTF(");\n");
}
static void header_gen_members(FILE *file, int indent, Decl **members)
@@ -247,11 +247,11 @@ static void header_gen_members(FILE *file, int indent, Decl **members)
if (member->type->canonical->type_kind == TYPE_ARRAY)
{
header_print_type(file, member->type->canonical->array.base);
OUTPUT(" %s[%d];\n", member->name, member->type->canonical->array.len);
PRINTF(" %s[%d];\n", member->name, member->type->canonical->array.len);
break;
}
header_print_type(file, member->type);
OUTPUT(" %s;\n", member->name);
PRINTF(" %s;\n", member->name);
break;
case DECL_STRUCT:
case DECL_UNION:
@@ -266,22 +266,22 @@ static void header_gen_struct_union(FILE *file, int indent, Decl *decl)
{
if (!indent)
{
OUTPUT("typedef struct %s__ %s;\n", decl->extname, decl->extname);
PRINTF("typedef struct %s__ %s;\n", decl->extname, decl->extname);
}
INDENT();
if (decl->name)
{
OUTPUT("%s %s__\n", struct_union_str(decl), decl->extname);
PRINTF("%s %s__\n", struct_union_str(decl), decl->extname);
}
else
{
OUTPUT("%s\n", struct_union_str(decl));
PRINTF("%s\n", struct_union_str(decl));
}
INDENT();
OUTPUT("{\n");
PRINTF("{\n");
header_gen_members(file, indent + 1, decl->strukt.members);
INDENT();
OUTPUT("};\n");
PRINTF("};\n");
}
@@ -292,10 +292,10 @@ static void header_gen_enum(FILE *file, int indent, Decl *decl)
static void header_gen_err(FILE *file, int indent, Decl *decl)
{
OUTPUT("typedef struct %s_error__ %s_error;\n", decl_get_extname(decl), decl_get_extname(decl));
OUTPUT("struct %s_error__\n{\n", decl_get_extname(decl));
PRINTF("typedef struct %s_error__ %s_error;\n", decl_get_extname(decl), decl_get_extname(decl));
PRINTF("struct %s_error__\n{\n", decl_get_extname(decl));
header_gen_members(file, indent, decl->strukt.members);
OUTPUT("};\n");
PRINTF("};\n");
}
@@ -395,19 +395,19 @@ RETRY:
Type *underlying_type = decl->enums.type_info->type->canonical;
if (underlying_type == type_cint->canonical)
{
OUTPUT("typedef enum %s__ %s;\n", decl_get_extname(decl), decl_get_extname(decl));
OUTPUT("enum %s__\n{\n", decl_get_extname(decl));
PRINTF("typedef enum %s__ %s;\n", decl_get_extname(decl), decl_get_extname(decl));
PRINTF("enum %s__\n{\n", decl_get_extname(decl));
FOREACH_BEGIN(Decl *enum_member, decl->enums.values)
OUTPUT("\t %s_%s,\n", decl_get_extname(decl), enum_member->name);
PRINTF("\t %s_%s,\n", decl_get_extname(decl), enum_member->name);
FOREACH_END();
OUTPUT("};\n");
PRINTF("};\n");
return;
}
OUTPUT("typedef ");
PRINTF("typedef ");
header_print_type(file, underlying_type);
OUTPUT(" %s;\n", decl_get_extname(decl));
PRINTF(" %s;\n", decl_get_extname(decl));
FOREACH_BEGIN_IDX(i, Decl *enum_member, decl->enums.values)
OUTPUT("%s %s_%s = %d;\n", decl_get_extname(decl), decl_get_extname(decl), enum_member->name, i);
PRINTF("%s %s_%s = %d;\n", decl_get_extname(decl), decl_get_extname(decl), enum_member->name, i);
FOREACH_END();
return;
}
@@ -419,13 +419,13 @@ RETRY:
if (htable_get(table, type)) return;
{
Decl *decl = type->decl;
OUTPUT("typedef struct %s__ %s;\n", decl_get_extname(decl), decl_get_extname(decl));
PRINTF("typedef struct %s__ %s;\n", decl_get_extname(decl), decl_get_extname(decl));
htable_set(table, type, type);
header_ensure_member_types_exist(file, table, decl->strukt.members);
OUTPUT("%s %s__\n", struct_union_str(decl), decl->extname);
OUTPUT("{\n");
PRINTF("%s %s__\n", struct_union_str(decl), decl->extname);
PRINTF("{\n");
header_gen_members(file, 1, decl->strukt.members);
OUTPUT("};\n");
PRINTF("};\n");
return;
}
case TYPE_ARRAY:
@@ -434,13 +434,13 @@ RETRY:
if (htable_get(table, type)) return;
{
Decl *decl = type->decl;
OUTPUT("typedef struct %s__slice__ %s;\n", decl_get_extname(decl), decl_get_extname(decl));
PRINTF("typedef struct %s__slice__ %s;\n", decl_get_extname(decl), decl_get_extname(decl));
htable_set(table, type, type);
header_ensure_member_types_exist(file, table, decl->strukt.members);
OUTPUT("%s %s__\n", struct_union_str(decl), decl->extname);
OUTPUT("{\n");
PRINTF("%s %s__\n", struct_union_str(decl), decl->extname);
PRINTF("{\n");
header_gen_members(file, 1, decl->strukt.members);
OUTPUT("};\n");
PRINTF("};\n");
return;
}
break;
@@ -449,11 +449,11 @@ RETRY:
goto RETRY;
case TYPE_VECTOR:
if (htable_get(table, type)) return;
OUTPUT("typedef ");
PRINTF("typedef ");
header_print_type(file, type->array.base);
OUTPUT(" ");
PRINTF(" ");
header_print_type(file, type);
OUTPUT(" __attribute__((vector_size(%d)));\n", (int)type_size(type->array.base) * type->array.len);
PRINTF(" __attribute__((vector_size(%d)));\n", (int)type_size(type->array.base) * type->array.len);
return;
}
}
@@ -477,26 +477,26 @@ static void header_gen_global_var(FILE *file, FILE *file_type, HTable *table, De
{
Expr *init = decl->var.init_expr;
if (type_is_arraylike(type) || type_is_user_defined(type) || !init) return;
OUTPUT("#define %s ", decl_get_extname(decl));
PRINTF("#define %s ", decl_get_extname(decl));
assert(expr_is_const(init));
switch (init->const_expr.const_kind)
{
case CONST_INTEGER:
OUTPUT("%s\n", int_to_str(init->const_expr.ixx, 10));
PRINTF("%s\n", int_to_str(init->const_expr.ixx, 10));
return;
case CONST_FLOAT:
OUTPUT("%.15g\n", init->const_expr.fxx.f);
PRINTF("%.15g\n", init->const_expr.fxx.f);
return;
case CONST_BOOL:
OUTPUT("%s\n", init->const_expr.b ? "true" : "false");
PRINTF("%s\n", init->const_expr.b ? "true" : "false");
return;
case CONST_POINTER:
if (!init->const_expr.ptr)
{
OUTPUT("(void*)0\n");
PRINTF("(void*)0\n");
return;
}
OUTPUT("(void*)0x%llx\n", (unsigned long long)init->const_expr.ptr);
PRINTF("(void*)0x%llx\n", (unsigned long long)init->const_expr.ptr);
return;
case CONST_STRING:
putc('\"', file);
@@ -508,13 +508,13 @@ static void header_gen_global_var(FILE *file, FILE *file_type, HTable *table, De
fputc(ch, file);
continue;
}
OUTPUT("\\x%02x", ch);
PRINTF("\\x%02x", ch);
}
OUTPUT("\"\n");
PRINTF("\"\n");
return;
case CONST_ENUM:
case CONST_ERR:
OUTPUT("%s\n", decl_get_extname(init->const_expr.enum_err_val));
PRINTF("%s\n", decl_get_extname(init->const_expr.enum_err_val));
return;
case CONST_TYPEID:
case CONST_MEMBER:
@@ -525,11 +525,11 @@ static void header_gen_global_var(FILE *file, FILE *file_type, HTable *table, De
}
}
assert(decl->var.kind == VARDECL_GLOBAL || decl->var.kind == VARDECL_CONST);
OUTPUT("extern ");
if (decl->var.kind == VARDECL_CONST) OUTPUT("const ");
PRINTF("extern ");
if (decl->var.kind == VARDECL_CONST) PRINTF("const ");
header_gen_maybe_generate_type(file_type, table, decl->type);
header_print_type(file, decl->type);
OUTPUT(" %s;\n", decl_get_extname(decl));
PRINTF(" %s;\n", decl_get_extname(decl));
}
@@ -551,7 +551,7 @@ void header_gen(Module **modules, unsigned module_count)
OUT(file_types, "typedef struct { void* ptr; size_t len; } c3slice_t;\n");
OUT(file_types, "typedef struct { void* ptr; c3typeid_t type; } c3any_t;\n");
OUT(file_types, "\n#endif\n\n");
OUTPUT("#include \"%s_types.h\"\n", name);
PRINTF("#include \"%s_types.h\"\n", name);
for (unsigned i = 0; i < module_count; i++)
{
@@ -565,7 +565,7 @@ void header_gen(Module **modules, unsigned module_count)
FOREACH_END();
}
OUTPUT("/* Constants */\n");
PRINTF("/* Constants */\n");
for (unsigned i = 0; i < module_count; i++)
{
Module *module = modules[i];
@@ -578,7 +578,7 @@ void header_gen(Module **modules, unsigned module_count)
FOREACH_END();
}
OUTPUT("\n/* Globals */\n");
PRINTF("\n/* Globals */\n");
for (unsigned i = 0; i < module_count; i++)
{
Module *module = modules[i];
@@ -592,7 +592,7 @@ void header_gen(Module **modules, unsigned module_count)
FOREACH_END();
}
OUTPUT("\n/* Functions */\n");
PRINTF("\n/* Functions */\n");
for (unsigned i = 0; i < module_count; i++)
{
Module *module = modules[i];
@@ -605,7 +605,7 @@ void header_gen(Module **modules, unsigned module_count)
FOREACH_END();
}
OUTPUT("\n/* Methods */\n");
PRINTF("\n/* Methods */\n");
for (unsigned i = 0; i < module_count; i++)
{
// Ignore stdlib modules

View File

@@ -10,25 +10,25 @@
unsigned decl_count_ = vec_size(unit->global_decls); \
for (unsigned k_ = 0; k_ < decl_count_; k_++) { \
a__ = unit->global_decls[k_];
#define PRINTF(string, ...) fprintf(file, string, ##__VA_ARGS__) /* NOLINT */
#define FOREACH_DECL_END } } }
#define INERT_COMMA do { if (first) { first = false; } else { fputs(",\n", file); } } while(0)
static inline void emit_modules(FILE *file)
{
fputs("\t\"modules\": {\n", file);
fputs("\t\"modules\": [\n", file);
FOREACH_BEGIN_IDX(i, Module *module, global_context.module_list)
if (i != 0) fputs(",\n", file);
fprintf(file, "\t\t\"%s\"", module->name->module);
PRINTF("\t\t\"%s\"", module->name->module);
FOREACH_END();
fputs("\n\t},\n", file);
fputs("\t\"generic_modules\": {\n", file);
fputs("\n\t],\n", file);
fputs("\t\"generic_modules\": [\n", file);
FOREACH_BEGIN_IDX(i, Module *module, global_context.generic_module_list)
if (i != 0) fputs(",\n", file);
fprintf(file, "\t\t\"%s\"", module->name->module);
PRINTF("\t\t\"%s\"", module->name->module);
FOREACH_END();
fputs("\n\t}\n", file);
fputs("\n\t]\n", file);
}
static inline const char *decl_type_to_string(Decl *type)
@@ -68,14 +68,14 @@ static inline const char *decl_type_to_string(Decl *type)
}
static inline void emit_type_data(FILE *file, Module *module, Decl *type)
{
fprintf(file, "\t\t\"%s::%s\": {\n", module->name->module, type->name);
fprintf(file, "\t\t\t\"kind\": \"%s\"", decl_type_to_string(type));
PRINTF("\t\t\"%s::%s\": {\n", module->name->module, type->name);
PRINTF("\t\t\t\"kind\": \"%s\"", decl_type_to_string(type));
if (type->decl_kind == DECL_STRUCT || type->decl_kind == DECL_UNION)
{
fputs(",\n\t\t\t\"members\": {\n", file);
FOREACH_BEGIN_IDX(i, Decl *member, type->strukt.members)
if (i != 0) fputs(",\n", file);
fprintf(file, "\t\t\t\t\"%s\"", member->name);
PRINTF("\t\t\t\t\"%s\"", member->name);
FOREACH_END();
fputs("\n\t\t\t}", file);
}
@@ -97,35 +97,35 @@ void print_type(FILE *file, TypeInfo *type)
case TYPE_INFO_CT_IDENTIFIER:
if (type->unresolved.path)
{
fprintf(file, "%s::", type->unresolved.path->module);
PRINTF("%s::", type->unresolved.path->module);
}
fputs(type->unresolved.name, file);
break;
case TYPE_INFO_TYPEOF:
scratch_buffer_clear();
span_to_scratch(type->unresolved_type_expr->span);
fprintf(file, "$typeof(%s)", scratch_buffer_to_string());
PRINTF("$typeof(%s)", scratch_buffer_to_string());
break;
case TYPE_INFO_VATYPE:
fprintf(file, "$vatype(...)");
PRINTF("$vatype(...)");
break;
case TYPE_INFO_EVALTYPE:
fprintf(file, "$evaltype(...)");
PRINTF("$evaltype(...)");
break;
case TYPE_INFO_TYPEFROM:
fprintf(file, "$typefrom(...)");
PRINTF("$typefrom(...)");
break;
case TYPE_INFO_ARRAY:
print_type(file, type->array.base);
scratch_buffer_clear();
span_to_scratch(type->array.len->span);
fprintf(file, "[%s]", scratch_buffer_to_string());
PRINTF("[%s]", scratch_buffer_to_string());
break;
case TYPE_INFO_VECTOR:
print_type(file, type->array.base);
scratch_buffer_clear();
span_to_scratch(type->array.len->span);
fprintf(file, "[<%s>]", scratch_buffer_to_string());
PRINTF("[<%s>]", scratch_buffer_to_string());
break;
case TYPE_INFO_INFERRED_ARRAY:
print_type(file, type->array.base);
@@ -174,17 +174,17 @@ void print_type(FILE *file, TypeInfo *type)
}
static inline void emit_func_data(FILE *file, Module *module, Decl *func)
{
fprintf(file, "\t\t\"%s::%s\": {\n", module->name->module, func->name);
fprintf(file, "\t\t\t\"rtype\": \"");
PRINTF("\t\t\"%s::%s\": {\n", module->name->module, func->name);
PRINTF("\t\t\t\"rtype\": \"");
print_type(file, type_infoptr(func->func_decl.signature.rtype));
fprintf(file, "\",\n");
PRINTF("\",\n");
fputs("\t\t\t\"params\": [\n", file);
FOREACH_BEGIN_IDX(i, Decl *decl, func->func_decl.signature.params)
if (i != 0) fputs(",\n", file);
if (!decl) continue;
fputs("\t\t\t\t{\n", file);
fprintf(file, "\t\t\t\t\t\"name\": \"%s\",\n", decl->name ? decl->name : "");
fprintf(file, "\t\t\t\t\t\"type\": \"");
PRINTF("\t\t\t\t\t\"name\": \"%s\",\n", decl->name ? decl->name : "");
PRINTF("\t\t\t\t\t\"type\": \"");
if (decl->var.type_info)
{
print_type(file, type_infoptr(decl->var.type_info));

View File

@@ -635,8 +635,7 @@ Decl *sema_resolve_method(CompilationUnit *unit, Decl *type, const char *method_
return sema_resolve_type_method(unit, type->type, method_name, ambiguous_ref, private_ref);
}
__attribute__((unused))
bool sema_check_type_variable_array(SemaContext *context, TypeInfo *type_info)
UNUSED bool sema_check_type_variable_array(SemaContext *context, TypeInfo *type_info)
{
if (!type_info_ok(type_info)) return false;
Type *type = type_info->type;