Author: kjs
Date: Tue Jan 27 14:10:21 2009
New Revision: 36067

Modified:
   trunk/compilers/pirc/src/pircompunit.c

Log:
[pirc] fix adding of "self" parameter with :vtable and :method flags. If either 
of these has been set, then don't add "self" again.

Modified: trunk/compilers/pirc/src/pircompunit.c
==============================================================================
--- trunk/compilers/pirc/src/pircompunit.c      (original)
+++ trunk/compilers/pirc/src/pircompunit.c      Tue Jan 27 14:10:21 2009
@@ -158,6 +158,27 @@
 
 /*
 
+=item C<static void
+add_self_parameter(lexer_state * const lexer)>
+
+Add a parameter named C<"self"> to the current subroutine, but only
+if both :vtable and :method flags have I<not> been set yet. If either
+of these flags has been set, then that means "self" was already added.
+
+=cut
+
+*/
+static void
+add_self_parameter(lexer_state * const lexer) {
+    /* only add "self" parameter if :vtable and :method flags have not been 
set yet */
+    if (!TEST_FLAG(CURRENT_SUB(lexer)->flags, (PIRC_SUB_FLAG_VTABLE | 
PIRC_SUB_FLAG_METHOD))) {
+
+        add_param(lexer, PMC_TYPE, "self");
+    }
+}
+
+/*
+
 =item C<void
 set_sub_vtable(lexer_state * const lexer, char const * vtablename)>
 
@@ -185,12 +206,20 @@
     if (vtable_index == -1)
         yypirerror(lexer->yyscanner, lexer,
                    "'%s' is not a vtable method but was used with :vtable 
flag", vtablename);
+
     else {
-        CURRENT_SUB(lexer)->info.vtable_index = vtable_index;
-        SET_FLAG(lexer->subs->flags, PIRC_SUB_FLAG_VTABLE);
+        /* test for duplicate :vtable on a sub */
+        if (CURRENT_SUB(lexer)->info.vtable_index != -1)
+            yypirerror(lexer->yyscanner, lexer, ":vtable flag was already set 
on sub");
+        else
+            CURRENT_SUB(lexer)->info.vtable_index = vtable_index;
 
-        /* :vtable methods have an automatic "self" parameter */
-        add_param(lexer, PMC_TYPE, "self");
+        add_self_parameter(lexer);
+
+        /* always set the :vtable flag, even if :method was already set.
+         * XXX emit a warning or somethign? Is :vtable + :method still useful?
+         */
+        SET_FLAG(CURRENT_SUB(lexer)->flags, PIRC_SUB_FLAG_VTABLE);
     }
 }
 
@@ -228,10 +257,10 @@
     else /* :method without a value defaults to the subname. */
         CURRENT_SUB(lexer)->methodname = CURRENT_SUB(lexer)->info.subname;
 
-    SET_FLAG(lexer->subs->flags, PIRC_SUB_FLAG_METHOD);
-
     /* :methods have an automatic "self" parameter */
-    add_param(lexer, PMC_TYPE, "self");
+    add_self_parameter(lexer);
+
+    SET_FLAG(lexer->subs->flags, PIRC_SUB_FLAG_METHOD);
 }
 
 /*

Reply via email to