diff options
| author | 2025-12-06 11:41:44 +0100 | |
|---|---|---|
| committer | 2025-12-06 11:55:41 +0100 | |
| commit | d82f3052c813f671561362126d0fbe08568542d3 (patch) | |
| tree | d82546bdf7f62e3461906c49fa3f3715d13422a6 | |
| parent | 2054983775165f3ae50b241aae71ccb4969eade4 (diff) | |
add command-line predefined macros (-D, -U)
| -rw-r--r-- | amd64/sysv.c | 1 | ||||
| -rw-r--r-- | c/lex.c | 56 | ||||
| -rw-r--r-- | common.h | 3 | ||||
| -rw-r--r-- | io.c | 39 | ||||
| -rw-r--r-- | ir/ir.h | 2 | ||||
| -rw-r--r-- | main.c | 7 | ||||
| -rw-r--r-- | obj/elf.c | 6 | ||||
| -rw-r--r-- | targ.c | 4 | ||||
| -rw-r--r-- | test/07-pp.c | 6 | ||||
| -rwxr-xr-x | test/run.sh | 3 |
10 files changed, 107 insertions, 20 deletions
diff --git a/amd64/sysv.c b/amd64/sysv.c index 712652a..299d35c 100644 --- a/amd64/sysv.c +++ b/amd64/sysv.c @@ -298,7 +298,6 @@ const struct mctarg t_amd64_sysv = { .rglob = 1<<RSP | 1<<RBP, .rnames = amd64_rnames, .objkind = OBJELF, - .isa = ISamd64, .abiret = abiret, .abiarg = abiarg, .vastart = vastart, @@ -1836,6 +1836,23 @@ lexpeek(struct lexer *lx, struct token *tk_) return t; } +/* Predefined/builtin macros */ + +static vec_of(uchar) ppcmdline; + +void +cpppredef(bool undef, const char *cmd) +{ + const char *sep = strchr(cmd, '='), *body = sep ? sep+1 : "1"; + uint namelen = sep ? sep - cmd : strlen(cmd); + char line[1024]; + struct wbuf wbuf = MEMBUF(line, sizeof line); + if (!ppcmdline.p) vinit(&ppcmdline, NULL, 1<<10); + int n = bfmt(&wbuf, "%s %S %s\n", undef ? "#undef" : "#define", cmd, namelen, body); + assert(n <= sizeof line); + vpushn(&ppcmdline, line, n); +} + static void mac__file__handler(struct lexer *lx, struct token *tk) { @@ -1916,10 +1933,21 @@ mac__has_builtin(struct lexer *lx, struct token *tk, struct rlist arg) tk->s = &"01"[has]; } +static const struct token tok_1 = { TKNUMLIT, .s = "1", .len = 1, .litlit = 1 }; static void -addpredefmacros(void) +putdef1(const char *name) +{ + struct macro mac = { + .name = intern(name), + .predefined = 1, + .rlist = { &tok_1, 1 }, + }; + putmac(&mac); +} + +static void +addpredefmacros(struct arena **tmparena) { - static const struct token tok_1 = { TKNUMLIT, .s = "1", .len = 1 }; static struct token tok_ver = { TKNUMLIT }; static struct macro macs[] = { { "__FILE__", .predefined = 1, .special = 1, .handler = mac__file__handler }, @@ -1931,7 +1959,6 @@ addpredefmacros(void) { "__STDC_VERSION__", .predefined = 1, .rlist = { &tok_ver, 1 } }, { "__STDC_HOSTED__", .predefined = 1, .rlist = { &tok_1, 1 } }, { "__antcc__", .predefined = 1, .rlist = { &tok_1, 1 } }, - { "__x86_64__", .predefined = 1, .rlist = { &tok_1, 1 } }, }; switch (ccopt.cstd) { default: assert(0); @@ -1945,6 +1972,27 @@ addpredefmacros(void) macs[i].name = intern(macs[i].name); putmac(&macs[i]); } + + switch (targ_mcisa) { + case ISamd64: + putdef1("__x86_64__"); + putdef1("__x86_64"); + break; + } + + if (ppcmdline.n) { + struct memfile *f; + struct lexer lx[1] = {0}; + vpushn(&ppcmdline, "\0\0\0\0", 5); + lx->fileid = getpredeffile(&f, "<command line>"); + assert(!f->p); + lx->dat = f->p = ppcmdline.p; + lx->ndat = f->n = ppcmdline.n; + lx->tmparena = tmparena; + lx->chrbuf0 = arraylength(lx->chrbuf); + lx->firstdirective = 1; + while (!lx->eof) lex(lx, NULL); + } } enum initlexer @@ -1954,8 +2002,8 @@ initlexer(struct lexer *lx, const char **err, const char *file) static union { char m[sizeof(struct arena) + NARENA]; struct arena *_align; } amem; static struct arena *tmparena = (void *)amem.m; - if (!macros.n) addpredefmacros(); if (!tmparena->cap) tmparena->cap = NARENA; + if (!macros.n) addpredefmacros(&tmparena); struct memfile *f; int fileid = openfile(err, &f, file); @@ -148,7 +148,9 @@ extern struct inclpaths { /* Target */ /**********/ +enum mcisa { ISamd64 }; extern const struct mctarg *mctarg; +extern enum mcisa targ_mcisa; void targ_init(const char *); /*********/ @@ -377,6 +379,7 @@ struct memfile mapopen(const char **err, const char *path); void mapclose(struct memfile *); void *mapzeros(uint); int munmap(void *, size_t); +int getpredeffile(struct memfile **, const char *name); int openfile(const char **err, struct memfile **, const char *path); const char *getfilename(int id); struct memfile *getfile(int id); @@ -828,6 +828,37 @@ static struct file { static int nfiles; int +getpredeffile(struct memfile **pf, const char *name) +{ + struct file *f; + struct fileuid uid; + uint h, id, n = arraylength(fileht); + + uid.dev = -11; + uid.ino = hashs(0, name); + for (id = h = uid.dev ^ uid.ino;; ++id) { + id &= arraylength(fileht) - 1; + f = fileht[id]; + if (f && f->uid.dev == uid.dev && f->uid.ino == uid.ino) { + break; + } else if (!f) { + f = allocz(&globarena, sizeof *f, 0); + f->uid = uid; + f->path = name; + f->f = (struct memfile) { .statik = 1 }; + fileht[id] = f; + vinit(&f->lineoffs, NULL, 10); + vpush(&f->lineoffs, 0); + ++nfiles; + break; + } + assert(--n > 0 && "fileht full"); + } + *pf = &f->f; + return id; +} + +int openfile(const char **err, struct memfile **pf, const char *path) { struct stat st; @@ -873,14 +904,14 @@ openfile(const char **err, struct memfile **pf, const char *path) const char * getfilename(int id) { - assert(id < arraylength(fileht) && fileht[id]); + assert((uint)id < arraylength(fileht) && fileht[id]); return fileht[id]->path; } struct memfile * getfile(int id) { - assert(id < arraylength(fileht) && fileht[id]); + assert((uint)id < arraylength(fileht) && fileht[id]); return &fileht[id]->f; } @@ -889,7 +920,7 @@ addfileline(int id, uint off) { vec_of(uint) *lineoffs; - assert(id < arraylength(fileht) && fileht[id]); + assert((uint)id < arraylength(fileht) && fileht[id]); lineoffs = (void *)&fileht[id]->lineoffs; if (lineoffs->n && off > lineoffs->p[lineoffs->n-1]) vpush(lineoffs, off); @@ -901,7 +932,7 @@ getfilepos(int *line, int *col, int id, uint off) uint *offs, n; int l = 0, h, i = 0; - assert(id < arraylength(fileht) && fileht[id]); + assert((uint)id < arraylength(fileht) && fileht[id]); offs = fileht[id]->lineoffs.p; n = fileht[id]->lineoffs.n; h = n - 1; @@ -179,7 +179,6 @@ struct function { #define FREQUIRE(_prop) assert((fn->prop & (_prop)) && "preconditions not met") enum objkind { OBJELF }; -enum mcisa { ISamd64 }; struct mctarg { short gpr0, /* first gpr */ @@ -192,7 +191,6 @@ struct mctarg { rglob; /* globally live (never used for regalloc) */ const char (*rnames)[6]; enum objkind objkind; - enum mcisa isa; /* abiret: lower return type: * scalar/small struct -> returns number of regs (1..2), * r & cls filled with reg and irclass of each scalar return @@ -179,8 +179,11 @@ optparse(char **args) } } else if (*arg == 'g') { /* TODO debug info */ - } else if (*arg == 'D') { - /* TODO cmdline defines */ + } else if (*arg == 'D' || *arg == 'U') { + void cpppredef(bool undef, const char *cmd); + const char *def = arg[1] ? arg+1 : *++args; + if (!def) fatal(NULL, "macro name missing after `-%c`", *arg); + cpppredef(*arg == 'U', def); } else if (*arg == 'O') { /* TODO optimization level */ } else if (*arg == 'I') { @@ -42,7 +42,7 @@ elfinit(void) hdr.i_osabi = ELFOSABI_SYSV; hdr.i_abiversion = 0; hdr.h32.type = ET_REL; - switch (mctarg->isa) { + switch (targ_mcisa) { case ISamd64: hdr.h32.machine = EM_X86_64; break; } hdr.h32.version = ELFVERSION; @@ -148,7 +148,7 @@ elfreloc(const char *sym, enum relockind kind, enum section section, uint off, v case Sdata: ++ndatarel; break; } assert(kind < NRELOCKIND); - vpush(&relocs, ((struct reloc) { section, relktab[mctarg->isa][kind], snam, off, addend })); + vpush(&relocs, ((struct reloc) { section, relktab[targ_mcisa][kind], snam, off, addend })); } static void @@ -365,7 +365,7 @@ elffini(struct wbuf *out) shnam_strtab = 36, shnam_symtab = 44, shnam_reltext = 52, shnam_relrodata = 63, shnam_reldata = 76 }; int align = targ_64bit ? 8 : 4; - bool userela = userelatab[mctarg->isa]; + bool userela = userelatab[targ_mcisa]; char shstrs[] = "\0.text\0.rodata\0.data\0.bss\0.shstrtab\0.strtab\0.symtab\0" ".rela.text\0.rela.rodata\0.rela.data"; if (!userela) { @@ -9,8 +9,9 @@ static const struct targ { bool charsigned; uchar sizetype, ptrdifftype, wchartype; const struct mctarg *mctarg; + enum mcisa isa; } targs[] = { - { "amd64-sysv", {8, 8, 8, 24}, {8, 8, 8, 8}, 1, TYULONG, TYLONG, TYINT, &t_amd64_sysv }, + { "amd64-sysv", {8, 8, 8, 24}, {8, 8, 8, 8}, 1, TYULONG, TYLONG, TYINT, &t_amd64_sysv, ISamd64 }, { "i686-sysv", {4, 8, 4, 8}, {4, 4, 4, 4}, 1, TYUINT, TYINT, TYINT } }; @@ -19,6 +20,7 @@ uchar targ_primalign[TYPTR+1]; uint targ_valistsize; enum typetag targ_sizetype, targ_ptrdifftype, targ_wchartype; bool targ_charsigned, targ_bigendian, targ_64bit; +enum mcisa targ_mcisa; const struct mctarg *mctarg; void diff --git a/test/07-pp.c b/test/07-pp.c index c26105d..6a50571 100644 --- a/test/07-pp.c +++ b/test/07-pp.c @@ -1,3 +1,4 @@ +/* CFLAGS: -D CMD_WORKING -DV=void */ /* EXPECT: ok /1 "\n"n ;.& 05.5 ADD(1,2) hi from header ;73 @@ -30,9 +31,10 @@ u\ t\ s - +#ifdef CMD_WORKING int -main(void) +main(V) +#endif { int CATl(foo); ++foobar; diff --git a/test/run.sh b/test/run.sh index 5e0bc0f..34d8101 100755 --- a/test/run.sh +++ b/test/run.sh @@ -16,11 +16,12 @@ run() { echo ---- $f ---- >> log.txt mkdir -p build/ args=$(awk '/\/\* ARGS:.*$/ {ORS=" ";for (i=3;i<NF;++i)print $i;ORS="\n";print""}' "$f") + cflags=$(awk '/\/\* CFLAGS:.*$/ {ORS=" ";for (i=3;i<NF;++i)print $i;ORS="\n";print""}' "$f") awk '/\/\* EXPECT:$/ {x=k=any=1} x && /\*\// {x=0} x {if (!k)print $0;k=0} END{if(x||!any)exit 1;}' "$f" > "$expected" if [ $? == 0 ]; then obj=build/"$(echo "$f" | sed -s 's/\.c$/.o/')" exe=build/"$(echo "$f" | sed -s 's/\.c$//')" - if ! ( x $ANTCC "$f" -c -o "$obj" && x $ANTCC "$obj" -o "$exe" ); then + if ! ( x $ANTCC $cflags "$f" -c -o "$obj" && x $ANTCC $cflags "$obj" -o "$exe" ); then echo !TEST ERROR $f echo !FAILED TO COMPILE echo '-------' |