ref: 3dca060d1ad6e41aa5ec4c4bc26bfff2fff54a1d
parent: af0a60913386396971fb0c4311370d68ae247c26
author: Roberto E. Vargas Caballero <[email protected]>
date: Fri Jul 11 05:50:31 EDT 2014
Allow labels with same name that a previous typedef Labels have a separate namespace, so it is correct this combination, but the problem is the lexer returns a different token for an identifier after a typedef for it. For example: main() { typedef int pepe; pepe: return 0; } The easier solution is a hack, where we modify the grammar to accept an IDEN or a TYPE when creating labels.
--- a/cc1/stmt.c
+++ b/cc1/stmt.c
@@ -170,11 +170,16 @@
static void
Label(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
{
- emitlabel(label(yytext, 1));
-
- expect(IDEN);
- expect(':');
- stmt(lbreak, lcont, lswitch);
+ switch (yytoken) {
+ case IDEN: case TYPE:
+ emitlabel(label(yytext, 1));
+ next();
+ expect(':');
+ stmt(lbreak, lcont, lswitch);
+ break;
+ default:
+ unexpected();
+ }
}
static void
@@ -297,10 +302,15 @@
case '}':
next();
return;
- case TYPE: case SCLASS: case TQUALIFIER:
+ case TYPE:
+ if (ahead() == ':')
+ goto statement;
+ /* pass through */
+ case SCLASS: case TQUALIFIER:
decl();
break;
default:
+ statement:
stmt(lbreak, lcont, lswitch);
}
}
@@ -325,7 +335,9 @@
case CASE: fun = Case; break;
case DEFAULT: fun = Default; break;
default: fun = stmtexp; break;
- case IDEN: fun = (ahead() == ':') ? Label : stmtexp; break;
+ case TYPE: case IDEN:
+ fun = (ahead() == ':') ? Label : stmtexp;
+ break;
}
(*fun)(lbreak, lcont, lswitch);
}