diff mc-parse.c @ 461:2a49dfe59540

attribute
author kono
date Thu, 02 Dec 2004 19:38:00 +0900
parents 2859bb9d5fb3
children 50a59dfb4606
line wrap: on
line diff
--- a/mc-parse.c	Thu Dec 02 12:07:16 2004 +0900
+++ b/mc-parse.c	Thu Dec 02 19:38:00 2004 +0900
@@ -37,6 +37,8 @@
 static NMTBL *free_nptr_list;
 
 static int current_scope;
+int attribute;
+
 int inline_funcs;
 
 char linebuf[LBUFSIZE];
@@ -139,7 +141,8 @@
 static NMTBL * make_top_scope(NMTBL *nlist,NMTBL *nptr1,int sc);
 static void extrn_use(NMTBL *nptr);
 static void top_init();
-static void const_volatile();
+static void qualifiers();
+static void attributes();
 
 static struct cheap * new_cheap();
 
@@ -229,7 +232,7 @@
 	top_init();
 	while(getsym(0)==SM) conv->sm_();
 	mode=GDECL;
-	stmode=0; inmode=0;
+	stmode=0; inmode=0; attribute = 0;
 	args=0;
 	decl();
     }
@@ -354,6 +357,7 @@
 	p=(s==RPAR) ? "')'": (s==RBRA) ? "']'": (s==SM) ? "';'":
 	  (s==LPAR) ? "'('": (s==WHILE) ? "'while'":
 	  (s==ASS) ? "'='": 
+	  (s==COMMA) ? "','": 
 	  (s==COLON) ? "':'": "Identifier";
 	fprintf(stderr,"%d:%s expected.\n",lineno,p);
 	errmsg();
@@ -453,10 +457,13 @@
     reserve("enum",ENUM);
     reserve("volatile",VOLATILE);
     reserve("__volatile__",VOLATILE);
+    reserve("restrict",RESTRICT);
     reserve("typeof",TYPEOF);
     reserve("__typeof__",TYPEOF);
     reserve("__builtin_alloca",ALLOCA);
     reserve("__builtin_constant_p",BUILTINP);
+    reserve("__builtin_expect",BUILTIN_EXPECT);
+    reserve("__attribute__",ATTRIBUTE);
     reserve("__label__",LABEL);
 #if ASM_CODE
     reserve("asm",ASM);
@@ -635,7 +642,7 @@
 static void
 storage_class()
 {
-    const_volatile();
+    qualifiers();
     switch(sym) {
     case STATIC:
 	if(mode==LDECL) {
@@ -708,7 +715,8 @@
 decl(void)
 {
     NMTBL *n;
-    int t,sd,ctmode=0;
+    int t,sd;
+    ctmode=0;
     if (mode==GDECL) { typedefed=0;  }
     storage_class();
     if((t=typespec())==0) return;
@@ -725,6 +733,7 @@
 	    error(DCERR); return;
 	}
     }
+    while (sym==ATTRIBUTE) { getsym(0); attributes(); }
     if(sym==LC || ( sym!=SM && sym!=COMMA && sym!=ASS)) {
 	/* function body */
 	if (mode!=GDECL) error(DCERR);
@@ -773,17 +782,48 @@
 }
 
 static void
-const_volatile()
+attributes()
+{
+    int sattribute;
+    checksym(LPAR);
+    while(sym!=RPAR) {
+	if (sym==LPAR) {
+	    sattribute = attribute;
+	    attribute = 0;
+	    attributes();
+	    attribute = list3(ATTRIBUTE,sattribute,attribute);
+	} else if (sym==IDENT) {
+	    attribute = list3(IDENT,attribute,(int)nptr);
+	    getsym(0);
+	} else if (sym==STRING) {
+	    attribute = list3(STRING,attribute,(int)nptr->nm);
+	    getsym(0);
+	} else {
+	    attribute = list3(sym,attribute,symval);
+	    getsym(0);
+	}
+    }
+    getsym(0);
+}
+
+static void
+qualifiers()
 {
     for(;;) {
 	switch (sym) {
 	case KONST:
-	    if (ctmode!=VOLATILE)
-		ctmode = KONST;
+	    ctmode |= KONST_BIT;
 	    break;
 	case VOLATILE:
-	    ctmode = VOLATILE;
+	    ctmode |= VOLATILE_BIT;
+	    break;
+	case RESTRICT:
+	    ctmode |= RESTRICT_BIT;
 	    break;
+	case ATTRIBUTE:
+	    getsym(0);
+	    attributes();
+	    continue;
 	default:
 	    return;
 	}
@@ -803,7 +843,7 @@
     int smode,stype;
     stypedecl = 0;
 
-    const_volatile();
+    qualifiers();
     switch(sym) {
     case VOID:
     case INT:
@@ -911,7 +951,7 @@
 	if(mode==LDECL) return 0;   // not a type
 	t= INT;                     // empty typespec 
     }
-    const_volatile();
+    qualifiers();
     return t;
 }
 
@@ -925,7 +965,7 @@
     NMTBL *n;
     if(sym==MUL) {
 	getsym(0);
-	const_volatile();
+	qualifiers();
 	n=decl0();
 	type=list2(POINTER,type);
 	return n;
@@ -2486,7 +2526,7 @@
     if (!inmode)
 	checkret();
     getsym(0);
-    const_volatile();
+    qualifiers();
     checksym(LPAR);
     // asm string
     if (sym!=STRING) error(DCERR);
@@ -2798,7 +2838,7 @@
 static int
 expr13(void)
 {
-    int e,op,dir;
+    int e,op,dir,t;
     NMTBL *nptr1;
 
     switch (op = sym) {
@@ -2933,7 +2973,7 @@
 	type=list2(POINTER,VOID);
 	return list2(ALLOCA,e);
     case BUILTINP:
-	/* builtin___builtin_constant_p GNU extenstion */
+	/* __builtin_constant_p GNU extenstion */
 	conv->prefix_(sym);
 	getsym(0);
 	checksym(LPAR);
@@ -2944,6 +2984,18 @@
 	    return list2(BUILTINP,rvalue(e));  /* evalue it later */
 	else 
 	    return list2(CONST,is_const(e));
+    case BUILTIN_EXPECT:
+	/* builtin_expect(x,c) used in branch. x is expectet to be c */
+	conv->prefix_(sym);
+	getsym(0);
+	checksym(LPAR);
+	e=expr1();
+	t=type;
+	checksym(COMMA);
+	expr0();  /* ingore */
+	checksym(RPAR);
+	type=t;
+	return e;
     case SIZEOF:
 	conv->prefix_(sym);
 	if(getsym(0)==LPAR) {
@@ -3195,7 +3247,7 @@
     case LPAR:
 	conv->lpar_();
 	getsym(0);
-	const_volatile();
+	qualifiers();
 
 	/* type cast */