diff --git a/Makefile b/Makefile index 5b50c238..5c708e72 100644 --- a/Makefile +++ b/Makefile @@ -26,11 +26,10 @@ c2c: $(C2C) @$(C2C) --version $(C2C): output/bootstrap/bootstrap $(C2C_DEPS) - @echo "---- running (bootstrapped$(C2FLAGS)) c2c ----" - @output/bootstrap/bootstrap c2c $(C2FLAGS) --fast --noplugins - @mv output/c2c/c2c output/bootstrap/c2c - @echo "---- running c2c (no plugins$(C2FLAGS)) ----" - @output/bootstrap/c2c $(C2FLAGS) --noplugins --fast c2c $(PLUGINS) + @echo "---- running bootstrap$(C2FLAGS) c2c ----" + @output/bootstrap/bootstrap $(C2FLAGS) c2c -o c2c-bootstrap --fast --noplugins + @echo "---- running c2c-bootstrap (no plugins$(C2FLAGS)) ----" + @output/c2c-bootstrap/c2c-bootstrap $(C2FLAGS) --fast --noplugins c2c $(PLUGINS) @./install_plugins.sh @echo "---- running c2c (optimized with plugins$(C2FLAGS)) ----" @output/c2c/c2c $(C2FLAGS) diff --git a/common/build_target.c2 b/common/build_target.c2 index ee3478c9..33ee20bb 100644 --- a/common/build_target.c2 +++ b/common/build_target.c2 @@ -156,6 +156,7 @@ public fn u32 Target.numAsmFiles(const Target* t) { return t.asm_files.getCount( public fn const string_list.List* Target.getFeatures(const Target* t) { return &t.features; } public fn void Target.addFeature(Target* t, u32 feature) { + // TODO: handle value t.features.add(feature); } diff --git a/compiler/compiler.c2 b/compiler/compiler.c2 index 77391622..f50b5934 100644 --- a/compiler/compiler.c2 +++ b/compiler/compiler.c2 @@ -87,12 +87,13 @@ public fn void build(string_pool.Pool* auxPool, build_file.Info* build_info, // can be nil build_target.Target* target, const Options* opts, + string_list.List* features, PluginHandler* pluginHandler) { Compiler c = {} plugin_info.Info info = {} - c.build(auxPool, sm, diags, build_info, target, opts, pluginHandler, &info); + c.build(auxPool, sm, diags, build_info, target, opts, features, pluginHandler, &info); if (opts.print_reports) { c.sm.report(opts.print_reports > 1); @@ -168,6 +169,7 @@ fn void Compiler.build(Compiler* c, build_file.Info* build_info, // can be nil build_target.Target* target, const Options* opts, + string_list.List* features, PluginHandler* pluginHandler, plugin_info.Info* info) { @@ -255,15 +257,19 @@ fn void Compiler.build(Compiler* c, c.addGlobalDefine("SYSTEM", c.targetInfo.getSystemName()); c.addGlobalDefine("ARCH", c.targetInfo.getArchName()); if (c.targetInfo.intWidth == 64) { - c.addFeature("ARCH_64BIT", "1"); + c.addFeature("ARCH_64BIT"); } else { - c.addFeature("ARCH_32BIT", "1"); + c.addFeature("ARCH_32BIT"); } - if (opts.asan) c.addFeature("__ASAN__", "1"); - if (opts.msan) c.addFeature("__MSAN__", "1"); - if (opts.ubsan) c.addFeature("__UBSAN__", "1"); + if (opts.asan) c.addFeature("__ASAN__"); + if (opts.msan) c.addFeature("__MSAN__"); + if (opts.ubsan) c.addFeature("__UBSAN__"); - c.addFeature("USE_NATIVE_CTYPES", "1"); + for (u32 i = 0; i < features.length(); i++) { + c.addFeature(features.get(i)); + } + + c.addFeature("USE_NATIVE_CTYPES"); c.parser = c2_parser.create(sm, diags, @@ -463,20 +469,20 @@ fn void Compiler.findTopModule(void* arg, ast.Module* m) { c.mainFunc = c.analyser.findMain(m, c.main_idx); } -fn void Compiler.addFeature(Compiler* c, const char* str, const char* value) { +fn void Compiler.addFeature(Compiler* c, const char* str) { // TODO: handle value c.target.addFeature(c.auxPool.addStr(str, true)); } fn void Compiler.addGlobalDefine(Compiler* c, const char* prefix, const char* tail) { char[32] tmp; - stdio.snprintf(tmp, 32, "%s_%s", prefix, tail); + stdio.snprintf(tmp, elemsof(tmp), "%s_%s", prefix, tail); for (usize i = 0; tmp[i]; i++) { u8 ch = (u8)tmp[i]; tmp[i] = (ch == '-') ? '_' : (char)ctype.toupper(ch); } - c.addFeature(tmp, "1"); + c.addFeature(tmp); } // NOTE: paths are not 0-terminated diff --git a/compiler/main.c2 b/compiler/main.c2 index 2492d926..d345c206 100644 --- a/compiler/main.c2 +++ b/compiler/main.c2 @@ -57,17 +57,20 @@ type Options struct { const char* output_name; string_list.List targets; string_list.List files; + string_list.List features; } fn void Options.init(Options* opts, string_pool.Pool* pool) { memset(opts, 0, sizeof(Options)); opts.targets.init(pool); opts.files.init(pool); + opts.features.init(pool); } fn void Options.free(Options *opts) { opts.targets.free(); opts.files.free(); + opts.features.free(); } fn void write_file_or_die(const char* filename, string_buffer.Buf* buf) { @@ -177,6 +180,7 @@ const char[] Usage_help = " -A print Library ASTs\n" " -b [file] use specified build file\n" " -d [dir] change to [dir] first\n" + " -Dfeature define global feature\n" " -h print this help\n" " -i use IR backend\n" " -I use IR backend and print generated IR\n" @@ -313,7 +317,12 @@ fn void parse_arguments(ArgumentParser *ap, compiler.Options* comp_opts, Options if (arg[1] == '-') { parse_long_opt(ap, arg, comp_opts, opts); } else { - if (strlen(arg) != 2) ap.unknownOption(arg); + const char *argarg = nil; + if (memchr("Ddbo", arg[1], 4)) { // needs argument + argarg = arg[2] ? &arg[2] : ap.getOptionArgument(arg); + } else if (strlen(arg) != 2) { + ap.unknownOption(arg); + } switch (arg[1]) { case '0': // 'hidden' feature, print AST early after parsing, then quit comp_opts.print_ast_early = true; @@ -321,6 +330,9 @@ fn void parse_arguments(ArgumentParser *ap, compiler.Options* comp_opts, Options case 'A': comp_opts.print_lib_ast = true; break; + case 'D': + opts.features.addStr(argarg); + break; case 'I': opts.use_ir_backend = true; comp_opts.print_ir = true; @@ -335,10 +347,10 @@ fn void parse_arguments(ArgumentParser *ap, compiler.Options* comp_opts, Options comp_opts.print_ast = true; break; case 'b': - opts.build_file = ap.getOptionArgument(arg); + opts.build_file = argarg; break; case 'd': - opts.other_dir = ap.getOptionArgument(arg); + opts.other_dir = argarg; break; case '?': case 'h': @@ -351,7 +363,7 @@ fn void parse_arguments(ArgumentParser *ap, compiler.Options* comp_opts, Options comp_opts.print_modules = true; break; case 'o': - opts.output_name = ap.getOptionArgument(arg); + opts.output_name = argarg; break; case 'r': comp_opts.print_reports += 1; @@ -614,7 +626,7 @@ fn bool Context.build_target(Context* c, } } - compiler.build(c.auxPool, c.sm, c.diags, c.build_info, target, &c.comp_opts, &c.pluginHandler); + compiler.build(c.auxPool, c.sm, c.diags, c.build_info, target, &c.comp_opts, &c.opts.features, &c.pluginHandler); // TODO unload target-specific plugins? // TODO fix build_file