From e81ff5af7608f12530df3f6f016e2532e71a78b7 Mon Sep 17 00:00:00 2001 From: lemon Date: Fri, 19 Dec 2025 12:24:08 +0100 Subject: c: hack to support __FUNCTION__ GNU extension --- c/c.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'c/c.c') diff --git a/c/c.c b/c/c.c index 620da7d..1cc37e0 100644 --- a/c/c.c +++ b/c/c.c @@ -908,6 +908,8 @@ tkprec(int tt) static struct expr initializer(struct comp *cm, union type *ty, enum evalmode ev, bool globl, enum qualifier qual, internstr name); +static internstr istr__func__, istr_main, istr_memset; + /* parse an expression with the given operator precedence */ /* param ident is a kludge to support block labels without backtracking or extra lookahead * see stmt() */ @@ -1011,7 +1013,13 @@ Unary: Ident: decl = finddecl(cm, tk.name); if (!decl) { - if (peek(cm, NULL) == '(') { /* implicit function decl? */ + if (cm->env->up && tk.name->c == '_' && (!strcmp(&tk.name->c, "__FUNCTION__") || !strcmp(&tk.name->c, "__PRETTY_FUNCTION__"))) { + /* hack: treat these identifiers as __func__ synonym to support the GNU extension */ + warn(&tk.span, "%'tk is a GNU extension", &tk); + decl = finddecl(cm, istr__func__); + assert(decl && decl->scls == SCSTATIC); + goto Sym; + } else if (peek(cm, NULL) == '(') { /* implicit function decl? */ ex = mkexpr(ESYM, tk.span, mktype(IMPLICITFUNCTY), .sym = (void *)tk.name); } else { error(&tk.span, "undeclared identifier %'tk", &tk); @@ -1022,7 +1030,7 @@ Unary: ex = mkexpr(ESYM, tk.span, decl->ty, .sym = NULL); } else if (decl->isenum) { ex = mkexpr(ENUMLIT, tk.span, decl->ty, .i = decl->value); - } else { + } else Sym: { ex = mkexpr(ESYM, tk.span, decl->ty, .qual = decl->qual, .sym = decl); } break; @@ -2747,8 +2755,6 @@ mkhiddensym(const char *fnname, const char *name, int id) static void geninit(struct function *fn, union type t, union ref dst, const struct expr *src); static union ref condexprvalue(struct function *fn, const struct expr *ex, bool discard); -static internstr istr__func__, istr_main, istr_memset; - union ref expraddr(struct function *fn, const struct expr *ex) { -- cgit v1.2.3