-declarator2_using_reentrant
- : declarator2 { $$ = $1 ; }
- | declarator2 using_reentrant { addDecl ($1,0,$2); }
+declarator3
+ : declarator2_function_attributes { $$ = $1 ; }
+ | declarator2 { $$ = $1 ; }
+ ;
+
+function_declarator
+ : declarator2_function_attributes { $$ = $1; }
+ | pointer declarator2_function_attributes
+ {
+ addDecl ($2,0,reverseLink($1));
+ $$ = $2 ;
+ }
+ ;
+
+declarator2_function_attributes
+ : function_declarator2 { $$ = $1 ; }
+ | function_declarator2 function_attribute {
+ // copy the functionAttributes (not the args and hasVargs !!)
+ struct value *args;
+ unsigned hasVargs;
+ sym_link *funcType=$1->type;
+
+ while (funcType && !IS_FUNC(funcType))
+ funcType = funcType->next;
+
+ if (!funcType)
+ werror (E_FUNC_ATTR);
+ else
+ {
+ args=FUNC_ARGS(funcType);
+ hasVargs=FUNC_HASVARARGS(funcType);
+
+ memcpy (&funcType->funcAttrs, &$2->funcAttrs,
+ sizeof($2->funcAttrs));
+
+ FUNC_ARGS(funcType)=args;
+ FUNC_HASVARARGS(funcType)=hasVargs;
+
+ // just to be sure
+ memset (&$2->funcAttrs, 0,
+ sizeof($2->funcAttrs));
+
+ addDecl ($1,0,$2);
+ }
+ }