+ | abstract_declarator2 '(' ')' {
+ // $1 must be a pointer to a function
+ sym_link *p=newLink(DECLARATOR);
+ DCL_TYPE(p) = FUNCTION;
+ if (!$1) {
+ // ((void (code *) ()) 0) ()
+ $1=newLink(DECLARATOR);
+ DCL_TYPE($1)=CPOINTER;
+ $$ = $1;
+ }
+ $1->next=p;
+ }
+ | abstract_declarator2 '(' parameter_type_list ')' {
+ if (!IS_VOID($3->etype)) {
+ // this is nonsense, so let's just burp something
+ werror(E_TOO_FEW_PARMS);
+ } else {
+ // $1 must be a pointer to a function
+ sym_link *p=newLink(DECLARATOR);
+ DCL_TYPE(p) = FUNCTION;
+ if (!$1) {
+ // ((void (code *) (void)) 0) ()
+ $1=newLink(DECLARATOR);
+ DCL_TYPE($1)=CPOINTER;
+ $$ = $1;
+ }
+ $1->next=p;
+ }
+ }