aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2025-12-06 11:41:44 +0100
committerlemon <lsof@mailbox.org>2025-12-06 11:55:41 +0100
commitd82f3052c813f671561362126d0fbe08568542d3 (patch)
treed82546bdf7f62e3461906c49fa3f3715d13422a6
parent2054983775165f3ae50b241aae71ccb4969eade4 (diff)
add command-line predefined macros (-D, -U)
-rw-r--r--amd64/sysv.c1
-rw-r--r--c/lex.c56
-rw-r--r--common.h3
-rw-r--r--io.c39
-rw-r--r--ir/ir.h2
-rw-r--r--main.c7
-rw-r--r--obj/elf.c6
-rw-r--r--targ.c4
-rw-r--r--test/07-pp.c6
-rwxr-xr-xtest/run.sh3
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,
diff --git a/c/lex.c b/c/lex.c
index ca10233..971b81f 100644
--- a/c/lex.c
+++ b/c/lex.c
@@ -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);
diff --git a/common.h b/common.h
index 20716d2..1e34ba5 100644
--- a/common.h
+++ b/common.h
@@ -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);
diff --git a/io.c b/io.c
index 6e1d425..f9e34b7 100644
--- a/io.c
+++ b/io.c
@@ -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;
diff --git a/ir/ir.h b/ir/ir.h
index 6cab245..b2077a0 100644
--- a/ir/ir.h
+++ b/ir/ir.h
@@ -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
diff --git a/main.c b/main.c
index 4b904a0..ac45cc5 100644
--- a/main.c
+++ b/main.c
@@ -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') {
diff --git a/obj/elf.c b/obj/elf.c
index 5578452..771d3c0 100644
--- a/obj/elf.c
+++ b/obj/elf.c
@@ -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) {
diff --git a/targ.c b/targ.c
index 019f784..6a4a5bd 100644
--- a/targ.c
+++ b/targ.c
@@ -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 '-------'