+| qualified_decl_type[rval_type] indirection[i] LPAREN indirection[unused1] name_token[NAME] LPAREN decl_args[args] RPAREN RPAREN LPAREN decl_args[rval_args] RPAREN array_size[as] {
+ (void) $unused1;
+ $NAME->type = PSI_T_NAME;
+
+ struct psi_token *type_token = psi_token_append("@", psi_token_copy($NAME), 1, "rval");
+ struct psi_decl_arg *rval_func = psi_decl_arg_init($rval_type, psi_decl_var_init(type_token->text, $i, 0));
+ struct psi_decl *rval_decl = psi_decl_init(rval_func, $rval_args);
+
+ rval_func->var->token = psi_token_copy(type_token);
+ rval_func->token = psi_token_copy(type_token);
+ if ($as) {
+ rval_func->var->pointer_level += 1;
+ rval_func->var->array_size = $as;
+ }
+
+ struct psi_decl_type *type = psi_decl_type_init(PSI_T_FUNCTION, type_token->text);
+ struct psi_decl_arg *func = psi_decl_arg_init(type, psi_decl_var_init($NAME->text, 1, 0));
+
+ type->real.func = rval_decl;
+ func->var->token = psi_token_copy($NAME);
+ func->token = psi_token_copy($NAME);
+
+ $decl = psi_decl_init(func, $args);
+}
+| qualified_decl_type[rval_type] indirection[i] LPAREN indirection[unused1] LPAREN indirection[unused2] name_token[NAME] RPAREN LPAREN decl_args[args] RPAREN RPAREN LPAREN decl_args[rval_args] RPAREN array_size[as] {
+ (void) $unused1;
+ (void) $unused2;
+ $NAME->type = PSI_T_NAME;
+
+ struct psi_token *type_token = psi_token_append("@", psi_token_copy($NAME), 1, "rval");
+ struct psi_decl_arg *rval_func = psi_decl_arg_init($rval_type, psi_decl_var_init(type_token->text, $i, 0));
+ struct psi_decl *rval_decl = psi_decl_init(rval_func, $rval_args);
+
+ rval_func->var->token = psi_token_copy(type_token);
+ rval_func->token = psi_token_copy(type_token);
+ if ($as) {
+ rval_func->var->pointer_level += 1;
+ rval_func->var->array_size = $as;
+ }
+
+ struct psi_decl_type *type = psi_decl_type_init(PSI_T_FUNCTION, type_token->text);
+ struct psi_decl_arg *func = psi_decl_arg_init(type, psi_decl_var_init($NAME->text, 1, 0));
+
+ type->real.func = rval_decl;
+ func->var->token = psi_token_copy($NAME);
+ func->token = psi_token_copy($NAME);
+ type->token = type_token;
+
+ $decl = psi_decl_init(func, $args);
+}
+;
+
+decl_anon_functor_body[decl]:
+ decl_anon_functor[func] LPAREN decl_args[args] RPAREN array_size[as] {
+ $decl = psi_decl_init($func, $args);
+ if ($as) {
+ $decl->func->var->pointer_level += 1;
+ $decl->func->var->array_size = $as;
+ }
+}
+| decl_anon_functor[func] LPAREN decl_args[args] COMMA ELLIPSIS RPAREN array_size[as] {
+ $decl = psi_decl_init($func, $args);
+ $decl->varargs = 1;
+ if ($as) {
+ $decl->func->var->pointer_level += 1;
+ $decl->func->var->array_size = $as;
+ }
+}