shithub: scc

Download patch

ref: bcbe85359f6a31024317c356bcfc19ea63117ca0
parent: 93d27ee2aa2f318960adb9d4f882a9e4fea13327
author: Roberto E. Vargas Caballero <[email protected]>
date: Fri Jul 5 04:09:01 EDT 2013

Add typedef handling

typedef defines a symbol which represent an alias of others type, so
the symbol must be in the NS_TYPEDEF namespace.

--- a/decl.c
+++ b/decl.c
@@ -11,32 +11,35 @@
 char parser_out_home;
 
 static struct symbol *cursym;
-static void declarator(void);
+static void declarator(struct ctype *tp);
 
 static void
-newiden(void)
+newiden(struct ctype *tp)
 {
-	switch (yyval.sym->ns) {
-	case NS_ANY:        /* First aparrence of the symbol */
-		yyval.sym->ns = NS_IDEN;
+	register unsigned char sns, ns;
+
+	ns = tp->c_type ? NS_TYPEDEF : NS_IDEN;
+	sns = yyval.sym->ns;
+
+	if (sns == NS_ANY) {     /* First appearence of the symbol */
+		yyval.sym->ns = ns;
 		cursym = yyval.sym;
-		break;
-	case NS_IDEN:
+		return;
+	} else if (ns == sns) {  /* Duplicated symbol */
 		if (yyval.sym->ctx == curctx)
 			error("redeclaration of '%s'", yytext);
-	default:
-		cursym = lookup(yytext, NS_IDEN);
 	}
+	cursym = lookup(yytext, ns);
 }
 
 static void
-dirdcl(void)
+dirdcl(register struct ctype *tp)
 {
 	if (accept('(')) {
-		declarator();
+		declarator(tp);
 		expect(')');
 	} else if (yytoken == IDEN) {
-		newiden();
+		newiden(tp);
 		next();
 	} else {
 		error("expected '(' or identifier before of '%s'", yytext);
@@ -73,7 +76,7 @@
 struct ctype *
 spec(void)
 {
-	static unsigned char sign, type;
+	unsigned char sign, type;
 	register struct ctype *tp = NULL;
 
 	for (type = sign = 0; ; next()) {
@@ -107,6 +110,18 @@
 		case STRUCT:    /* TODO */
 		case UNION:	/* TODO */
 		case ENUM:	/* TODO */
+		case IDEN: {
+			struct symbol *sym;
+
+			if ((sym = find(yytext, NS_TYPEDEF)) && !type) {
+				register unsigned char tok = ahead();
+
+				if (tok != ';' && tok != ',')  {
+					(tp = sym->ctype)->refcnt++;
+					next();
+				}
+			}
+			}
 		default:
 			if (tp && !tp->type && sign)
 				tp->type = INT;
@@ -118,7 +133,7 @@
 }
 
 static void
-declarator(void)
+declarator(struct ctype *tp)
 {
 	unsigned char qlf[NR_DECLARATORS];
 	register unsigned char *bp, *lim;
@@ -142,7 +157,7 @@
 	if (bp == lim)
 		error("Too much type declarators");
 
-	dirdcl();
+	dirdcl(tp);
 
 	for (lim = bp - 1, bp = qlf; bp < lim; ++bp)
 		pushtype(*bp);
@@ -177,7 +192,7 @@
 		struct node *sp, *np;
 		register struct ctype *tp;
 
-		declarator();
+		declarator(tp);
 		tp = decl_type(base);
 		if (!tp->type) {
 			warning_error(options.implicit,
@@ -214,12 +229,12 @@
 	if (accept(';')) {
 		warning_error(options.useless,
 			      "useless type name in empty declaration");
+		delctype(tp);
 	} else {
 		np = listdcl(tp);
 	}
 
-end:	delctype(tp);
-	return np;
+end:	return np;
 }
 
 void
--- a/types.c
+++ b/types.c
@@ -26,7 +26,8 @@
 {
 	if (!tp)
 		return;
-	if (--tp->refcnt == 0) {
+	tp->c_type = 0;              /* this flag only is important in */
+	if (--tp->refcnt == 0) {        /* the parsing */
 		if (tp->base)
 			delctype(tp->base);
 		free(tp);