shithub: scc

Download patch

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);
 }