diff options
| author | 2025-11-15 19:53:47 +0100 | |
|---|---|---|
| committer | 2025-11-15 19:53:47 +0100 | |
| commit | 2ca9a54daaa0a955dabf38862cd777be359252e0 (patch) | |
| tree | 51a0e9470a5bbd4bbe0b1d00fc50da2dc9ad9d93 /c/lex.c | |
| parent | 1910d875cfcad320cbb87c5e8c846d5c53846a1a (diff) | |
ir: 'trap' jump; c: __builtin_trap; lex: __has_builtin
Diffstat (limited to 'c/lex.c')
| -rw-r--r-- | c/lex.c | 29 |
1 files changed, 25 insertions, 4 deletions
@@ -612,6 +612,7 @@ struct macro { const struct token *tk; int n; } rlist; + void (*handlerfn)(struct lexer *, struct token *ret, struct rlist arg); }; }; @@ -988,7 +989,7 @@ tryexpand(struct lexer *lx, struct token *tk) if (l->macno == macidx) return 0; - if (mac->special) { + if (mac->special && !mac->fnlike) { mac->handler(lx, tk); pushmacstk(lx, &span, &(struct macrostack){ .rlist = { alloccopy(lx->tmparena, tk, sizeof *tk, 0), 1 }, @@ -1080,9 +1081,13 @@ expandfnmacro(struct lexer *lx, struct span *span, struct macro *mac) joinspan(&excessspan.ex, tk.span.ex); error(&excessspan, "macro `%s' passed %d arguments, but takes just %d", mac->name, narg, mac->nparam); } - - /* make new rlist with args replaced */ - if (mac->nparam) { + if (mac->special) { + mac->handlerfn(lx, &tk, (struct rlist){argsbuf.p, argsbuf.n}); + pushmacstk(lx, span, &(struct macrostack){ + .rlist = { alloccopy(lx->tmparena, &tk, sizeof tk, 0), 1 }, + .macno = mac - macros.p, + }); + } else if (mac->nparam) { /* make new rlist with args replaced */ struct token lhsargforpaste; bool lhsargpaste = 0, rhsargpaste = 0; for (int i = 0; i < mac->rlist.n; ++i) { @@ -1897,6 +1902,21 @@ mac__time__handler(struct lexer *lx, struct token *tk) } static void +mac__has_builtin(struct lexer *lx, struct token *tk, struct rlist arg) +{ + extern bool hasbuiltin(const char *, uint n); + bool has = 0; + tk->t = TKNUMLIT, tk->len = 1; + if (arg.n == 1) { + if (arg.tk->t == TKIDENT) + has = hasbuiltin(arg.tk->s, arg.tk->len); + else if (in_range(arg.tk->t, TKWBEGIN_, TKWEND_)) + has = arg.tk->len >= sizeof "__builtin_" && !memcmp(arg.tk->s, "__builtin_", 10); + } + tk->s = &"01"[has]; +} + +static void addpredefmacros(void) { static const struct token tok_1 = { TKNUMLIT, .s = "1", .len = 1 }; @@ -1906,6 +1926,7 @@ addpredefmacros(void) { "__LINE__", .predefined = 1, .special = 1, .handler = mac__line__handler }, { "__DATE__", .predefined = 1, .special = 1, .handler = mac__date__handler }, { "__TIME__", .predefined = 1, .special = 1, .handler = mac__time__handler }, + { "__has_builtin", .predefined = 1, .nparam = 1, .fnlike = 1, .special = 1, .handlerfn = mac__has_builtin }, { "__STDC__", .predefined = 1, .rlist = { &tok_1, 1 } }, { "__STDC_VERSION__", .predefined = 1, .rlist = { &tok_ver, 1 } }, { "__STDC_HOSTED__", .predefined = 1, .rlist = { &tok_1, 1 } }, |