+/* () or (....) */
+siglistornull: /* NULL */
+ { $$ = NULL; }
+ | siglist
+ { $$ = $1; }
+
+/* optional subroutine signature */
+optsubsignature: /* NULL */
+ { $$ = NULL; }
+ | subsignature
+ { $$ = $1; }
+
+/* Subroutine signature */
+subsignature: '(' subsigguts ')'
+ { $$ = $2; }
+
+subsigguts:
+ {
+ ENTER;
+ SAVEIV(parser->sig_elems);
+ SAVEIV(parser->sig_optelems);
+ SAVEI8(parser->sig_slurpy);
+ parser->sig_elems = 0;
+ parser->sig_optelems = 0;
+ parser->sig_slurpy = 0;
+ parser->in_my = KEY_sigvar;
+ }
+ siglistornull
+ {
+ OP *sigops = $2;
+ struct op_argcheck_aux *aux;
+ OP *check;
+
+ if (!FEATURE_SIGNATURES_IS_ENABLED)
+ Perl_croak(aTHX_ "Experimental "
+ "subroutine signatures not enabled");
+
+ /* We shouldn't get here otherwise */
+ Perl_ck_warner_d(aTHX_
+ packWARN(WARN_EXPERIMENTAL__SIGNATURES),
+ "The signatures feature is experimental");
+
+ aux = (struct op_argcheck_aux*)
+ PerlMemShared_malloc(
+ sizeof(struct op_argcheck_aux));
+ aux->params = parser->sig_elems;
+ aux->opt_params = parser->sig_optelems;
+ aux->slurpy = parser->sig_slurpy;
+ check = newUNOP_AUX(OP_ARGCHECK, 0, NULL,
+ (UNOP_AUX_item *)aux);
+ sigops = op_prepend_elem(OP_LINESEQ, check, sigops);
+ sigops = op_prepend_elem(OP_LINESEQ,
+ newSTATEOP(0, NULL, NULL),
+ sigops);
+ /* a nextstate at the end handles context
+ * correctly for an empty sub body */
+ sigops = op_append_elem(OP_LINESEQ,
+ sigops,
+ newSTATEOP(0, NULL, NULL));
+ /* wrap the list of arg ops in a NULL aux op.
+ This serves two purposes. First, it makes
+ the arg list a separate subtree from the
+ body of the sub, and secondly the null op
+ may in future be upgraded to an OP_SIGNATURE
+ when implemented. For now leave it as
+ ex-argcheck */
+ $$ = newUNOP_AUX(OP_ARGCHECK, 0, sigops, NULL);
+ op_null($$);
+
+ parser->in_my = 0;
+ /* tell the toker that attrributes can follow
+ * this sig, but only so that the toker
+ * can skip through any (illegal) trailing
+ * attribute text then give a useful error
+ * message about "attributes before sig",
+ * rather than falling over ina mess at
+ * unrecognised syntax.
+ */
+ parser->expect = XATTRBLOCK;
+ parser->sig_seen = TRUE;
+ LEAVE;