Skip to content

Commit a00c0a3

Browse files
committed
Compiler: simplify argument parsing, add -Dxxx for features
* add `unknown_option()` to factor error handling * simplify option parsing, add `argarg` for options with an arguments * add `-DFeature` to define features from the command line * simplify `Compiler.addFeature()`: feature values are not supported yet and could be specified as `Feature=value` later * simplify Makefile for bootstrap phases
1 parent 32a49c1 commit a00c0a3

File tree

4 files changed

+58
-47
lines changed

4 files changed

+58
-47
lines changed

Makefile

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,10 @@ c2c: $(C2C)
2424
@$(C2C) --version
2525

2626
$(C2C): output/bootstrap/bootstrap $(C2C_DEPS)
27-
@echo "---- running (bootstrapped$(C2FLAGS)) c2c ----"
28-
@output/bootstrap/bootstrap c2c $(C2FLAGS) --fast --noplugins
29-
@mv output/c2c/c2c output/bootstrap/c2c
30-
@echo "---- running c2c (no plugins$(C2FLAGS)) ----"
31-
@output/bootstrap/c2c $(C2FLAGS) --noplugins --fast
27+
@echo "---- running bootstrap$(C2FLAGS) c2c ----"
28+
@output/bootstrap/bootstrap $(C2FLAGS) c2c -o c2c-bootstrap --fast --noplugins
29+
@echo "---- running c2c-bootstrap (no plugins$(C2FLAGS)) ----"
30+
@output/c2c-bootstrap/c2c-bootstrap $(C2FLAGS) --fast --noplugins
3231
@./install_plugins.sh
3332
@echo "---- running c2c (optimized with plugins$(C2FLAGS)) ----"
3433
@output/c2c/c2c $(C2FLAGS)

common/build_target.c2

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ public fn u32 Target.numAsmFiles(const Target* t) { return t.asm_file_count; }
163163
public fn const string_list.List* Target.getFeatures(const Target* t) { return &t.features; }
164164

165165
public fn void Target.addFeature(Target* t, u32 feature) {
166+
// TODO: handle value
166167
t.features.add(feature);
167168
}
168169

compiler/compiler.c2

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -91,12 +91,13 @@ public fn void build(string_pool.Pool* auxPool,
9191
build_file.Info* build_info, // can be nil
9292
build_target.Target* target,
9393
const Options* opts,
94+
string_list.List* features,
9495
PluginHandler* pluginHandler)
9596
{
9697
Compiler c = {}
9798
plugin_info.Info info = {}
9899

99-
c.build(auxPool, sm, diags, build_info, target, opts, pluginHandler, &info);
100+
c.build(auxPool, sm, diags, build_info, target, opts, features, pluginHandler, &info);
100101

101102
if (opts.print_reports) {
102103
c.sm.report();
@@ -206,6 +207,7 @@ fn void Compiler.build(Compiler* c,
206207
build_file.Info* build_info, // can be nil
207208
build_target.Target* target,
208209
const Options* opts,
210+
string_list.List* features,
209211
PluginHandler* pluginHandler,
210212
plugin_info.Info* info)
211213
{
@@ -288,13 +290,17 @@ fn void Compiler.build(Compiler* c,
288290
c.addGlobalDefine("SYSTEM", c.targetInfo.getSystemName());
289291
c.addGlobalDefine("ARCH", c.targetInfo.getArchName());
290292
if (c.targetInfo.intWidth == 64) {
291-
c.addFeature("ARCH_64BIT", "1");
293+
c.addFeature("ARCH_64BIT");
292294
} else {
293-
c.addFeature("ARCH_32BIT", "1");
295+
c.addFeature("ARCH_32BIT");
296+
}
297+
if (opts.asan) c.addFeature("__ASAN__");
298+
if (opts.msan) c.addFeature("__MSAN__");
299+
if (opts.ubsan) c.addFeature("__UBSAN__");
300+
301+
for (u32 i = 0; i < features.length(); i++) {
302+
c.addFeature(features.get(i));
294303
}
295-
if (opts.asan) c.addFeature("__ASAN__", "1");
296-
if (opts.msan) c.addFeature("__MSAN__", "1");
297-
if (opts.ubsan) c.addFeature("__UBSAN__", "1");
298304

299305
c.parser = c2_parser.create(sm,
300306
diags,
@@ -362,12 +368,10 @@ fn void Compiler.build(Compiler* c,
362368
const build_target.File* f = target.getFile(j);
363369
i32 file_id = sm.open(f.name, f.loc, true);
364370
if (file_id == -1) return; // note: error already printed
365-
366371
console.debug("parsing %s", sm.getFileName(file_id));
367372

368373
// parse error indicator updated in c.parser state
369374
c.parser.parse(file_id, false, false);
370-
371375
sm.close(file_id);
372376
}
373377
u64 t1_end = utils.now();
@@ -644,18 +648,17 @@ fn void Compiler.checkMain(Compiler* c) {
644648
}
645649
}
646650

647-
fn void Compiler.addFeature(Compiler* c, const char* str, const char* value) {
648-
// TODO: handle value
651+
fn void Compiler.addFeature(Compiler* c, const char* str) {
649652
c.target.addFeature(c.auxPool.addStr(str, true));
650653
}
651654

652655
fn void Compiler.addGlobalDefine(Compiler* c, const char* prefix, const char* tail) {
653656
char[32] tmp;
654-
stdio.snprintf(tmp, 32, "%s_%s", prefix, tail);
657+
stdio.snprintf(tmp, elemsof(tmp), "%s_%s", prefix, tail);
655658
for (usize i = 0; tmp[i]; i++) {
656-
u8 ch = cast<u8>(tmp[i]);
657-
tmp[i] = (ch == '-') ? '_' : cast<char>(ctype.toupper(ch));
659+
u8 ch = tmp[i];
660+
tmp[i] = (char)((ch == '-') ? '_' : ctype.toupper(ch));
658661
}
659662

660-
c.addFeature(tmp, "1");
663+
c.addFeature(tmp);
661664
}

compiler/main.c2

Lines changed: 36 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -56,17 +56,20 @@ type Options struct {
5656
const char* output_name;
5757
string_list.List targets;
5858
string_list.List files;
59+
string_list.List features;
5960
}
6061

6162
fn void Options.init(Options* opts, string_pool.Pool* pool) {
6263
memset(opts, 0, sizeof(Options));
6364
opts.targets.init(pool);
6465
opts.files.init(pool);
66+
opts.features.init(pool);
6567
}
6668

6769
fn void Options.free(Options *opts) {
6870
opts.targets.free();
6971
opts.files.free();
72+
opts.features.free();
7073
}
7174

7275
fn void write_file_or_die(const char* filename, string_buffer.Buf* buf) {
@@ -175,6 +178,7 @@ const char[] Usage_help =
175178
" -A print Library ASTs\n"
176179
" -b [file] use specified build file\n"
177180
" -d [dir] change to [dir] first\n"
181+
" -Dfeature define global feature\n"
178182
" -h print this help\n"
179183
" -i use IR backend\n"
180184
" -I use IR backend and print generated IR\n"
@@ -215,8 +219,12 @@ fn void missing_arg(const char* option) {
215219
exit(EXIT_FAILURE);
216220
}
217221

218-
fn i32 parse_long_opt(i32 i, i32 argc, char** argv, compiler.Options* comp_opts, Options* opts) {
219-
const char* arg = argv[i];
222+
fn void unknown_option(const char* option) {
223+
console.error("c2c: unknown option: '%s'", option);
224+
exit(EXIT_FAILURE);
225+
}
226+
227+
fn i32 parse_long_opt(const char* arg, i32 i, i32 argc, char** argv, compiler.Options* comp_opts, Options* opts) {
220228
switch (arg+2) {
221229
case "I2":
222230
opts.use_ir_backend = true;
@@ -226,9 +234,8 @@ fn i32 parse_long_opt(i32 i, i32 argc, char** argv, compiler.Options* comp_opts,
226234
comp_opts.check_only = true;
227235
break;
228236
case "create":
229-
if (i==argc-1) missing_arg(arg);
230-
i++;
231-
create_project(argv[i]);
237+
if (i >= argc) missing_arg(arg);
238+
create_project(argv[i++]);
232239
break;
233240
case "fast":
234241
comp_opts.fast_build = true;
@@ -249,9 +256,8 @@ fn i32 parse_long_opt(i32 i, i32 argc, char** argv, compiler.Options* comp_opts,
249256
opts.show_plugins = true;
250257
break;
251258
case "target":
252-
if (i==argc-1) missing_arg(arg);
253-
i++;
254-
comp_opts.target_triple = argv[i];
259+
if (i >= argc) missing_arg(arg);
260+
comp_opts.target_triple = argv[i++];
255261
break;
256262
case "targets":
257263
opts.show_targets = true;
@@ -275,22 +281,28 @@ fn i32 parse_long_opt(i32 i, i32 argc, char** argv, compiler.Options* comp_opts,
275281
print_version();
276282
exit(EXIT_SUCCESS);
277283
default:
278-
console.error("c2c: unknown option: %s", arg);
279-
exit(EXIT_FAILURE);
284+
unknown_option(arg);
285+
break;
280286
}
281287
return i;
282288
}
283289

284290
fn void parse_opts(i32 argc, char** argv, compiler.Options* comp_opts, Options* opts) {
285-
for (i32 i=1; i<argc; i++) {
286-
const char* arg = argv[i];
291+
for (i32 i = 1; i < argc;) {
292+
const char* arg = argv[i++];
287293
if (arg[0] == '-') {
288294
if (arg[1] == '-') {
289-
i = parse_long_opt(i, argc, argv, comp_opts, opts);
295+
i = parse_long_opt(arg, i, argc, argv, comp_opts, opts);
290296
} else {
291-
if (strlen(arg) != 2) {
292-
console.error("c2c: unknown option '%s'", arg);
293-
exit(EXIT_FAILURE);
297+
const char *argarg = nil;
298+
if (memchr("Ddbo", arg[1], 4)) { // needs argument
299+
argarg = &arg[2];
300+
if (!*argarg) {
301+
if (i >= argc) missing_arg(arg);
302+
argarg = argv[i++];
303+
}
304+
} else if (strlen(arg) != 2) {
305+
unknown_option(arg);
294306
}
295307
switch (arg[1]) {
296308
case '0': // 'hidden' feature, print AST early after parsing, then quit
@@ -299,6 +311,9 @@ fn void parse_opts(i32 argc, char** argv, compiler.Options* comp_opts, Options*
299311
case 'A':
300312
comp_opts.print_lib_ast = true;
301313
break;
314+
case 'D':
315+
opts.features.addStr(argarg);
316+
break;
302317
case 'I':
303318
opts.use_ir_backend = true;
304319
comp_opts.print_ir = true;
@@ -313,14 +328,10 @@ fn void parse_opts(i32 argc, char** argv, compiler.Options* comp_opts, Options*
313328
comp_opts.print_ast = true;
314329
break;
315330
case 'b':
316-
if (i==argc-1) missing_arg(arg);
317-
i++;
318-
opts.build_file = argv[i];
331+
opts.build_file = argarg;
319332
break;
320333
case 'd':
321-
if (i==argc-1) missing_arg(arg);
322-
i++;
323-
opts.other_dir = argv[i];
334+
opts.other_dir = argarg;
324335
break;
325336
case '?':
326337
case 'h':
@@ -333,9 +344,7 @@ fn void parse_opts(i32 argc, char** argv, compiler.Options* comp_opts, Options*
333344
comp_opts.print_modules = true;
334345
break;
335346
case 'o':
336-
if (i==argc-1) missing_arg(arg);
337-
i++;
338-
opts.output_name = argv[i];
347+
opts.output_name = argarg;
339348
break;
340349
case 'r':
341350
comp_opts.print_reports = true;
@@ -353,8 +362,7 @@ fn void parse_opts(i32 argc, char** argv, compiler.Options* comp_opts, Options*
353362
opts.force_warnings = true;
354363
break;
355364
default:
356-
console.error("c2c: unknown option '-%c'", arg[1]);
357-
exit(EXIT_FAILURE);
365+
unknown_option(arg);
358366
break;
359367
}
360368
}
@@ -596,7 +604,7 @@ fn bool Context.build_target(Context* c,
596604

597605
target.addLib(c.auxPool.add("c2", 2, true), false);
598606

599-
compiler.build(c.auxPool, c.sm, c.diags, c.build_info, target, &c.comp_opts, &c.pluginHandler);
607+
compiler.build(c.auxPool, c.sm, c.diags, c.build_info, target, &c.comp_opts, &c.opts.features, &c.pluginHandler);
600608

601609
// TODO unload target-specific plugins?
602610
// TODO fix build_file

0 commit comments

Comments
 (0)