--- src/lexer.l.orig	2007-09-28 06:26:49.000000000 +0200
+++ src/lexer.l	2008-01-28 16:04:28.000000000 +0100
@@ -31,6 +31,7 @@
 #include "main.h"
 #include "util.h"
 
+static int bracket_depth = 0;
 static int parenth_depth = 0;
 static int before_comment
 /* New flex is on drugs */
@@ -102,6 +103,7 @@
 
 %x COMMENT
 %x C_CODE
+%x ATTR_CODE
 %x CODE_STRING
 %x CLASS_CODE
 %x CLASS_STRING
@@ -267,7 +269,7 @@
 			add_to_cbuf(yytext);
 		}
 
-<C_CODE>\/\/.*$		{ add_to_cbuf(yytext); /*comment, ignore*/ }
+<C_CODE,ATTR_CODE>\/\/.*$	{ add_to_cbuf(yytext); /*comment, ignore*/ }
 <CLASS_CODE>\/\/.*$	{ ; /*comment, ignore*/ }
 <CLASS_CODE_I>\/\/.*$	{ ; /*comment, ignore*/ }
 <PROPERTY_CODE_I>\/\/.*$	{ ; /*comment, ignore*/ }
@@ -277,20 +279,25 @@
 	BEGIN(COMMENT);
 	before_comment = C_CODE;
 }
+<ATTR_CODE>\/\*	{
+	add_to_cbuf(yytext);
+	BEGIN(COMMENT);
+	before_comment = ATTR_CODE;
+}
 <CLASS_CODE>\/\*	{BEGIN(COMMENT); before_comment = CLASS_CODE; }
 <CLASS_CODE_I>\/\*	{BEGIN(COMMENT); before_comment = CLASS_CODE_I; }
 <PROPERTY_CODE_I>\/\*	{BEGIN(COMMENT); before_comment = PROPERTY_CODE_I; }
 <COMMENT>\*\/	{
-	if(before_comment == C_CODE) add_to_cbuf(yytext);
+	if(before_comment == C_CODE || before_comment == ATTR_CODE) add_to_cbuf(yytext);
 	BEGIN(before_comment);
 		}
 <COMMENT>.	{
 	/* comment, ignore */
-	if(before_comment == C_CODE) add_to_cbuf(yytext);
+	if(before_comment == C_CODE || before_comment == ATTR_CODE) add_to_cbuf(yytext);
 		}
 <COMMENT>\n	{
 	/* comment, ignore */
-	if(before_comment == C_CODE) add_to_cbuf(yytext);
+	if(before_comment == C_CODE || before_comment == ATTR_CODE) add_to_cbuf(yytext);
 		}
 
 ^\%(a|all)\{		{
@@ -353,14 +360,14 @@
 			return code_type;
 		}
 
-<C_CODE>\'\{\'		{ add_to_cbuf(yytext); }
-<C_CODE>\'\\\{\'	{ add_to_cbuf(yytext); }
-<C_CODE>\'\}\'		{ add_to_cbuf(yytext); }
-<C_CODE>\'\\\}\'	{ add_to_cbuf(yytext); }
-<C_CODE>\'\"\'		{ add_to_cbuf(yytext); }
-<C_CODE>\'\\\"\'	{ add_to_cbuf(yytext); }
+<C_CODE,ATTR_CODE>\'\{\'	{ add_to_cbuf(yytext); }
+<C_CODE,ATTR_CODE>\'\\\{\'	{ add_to_cbuf(yytext); }
+<C_CODE,ATTR_CODE>\'\}\'	{ add_to_cbuf(yytext); }
+<C_CODE,ATTR_CODE>\'\\\}\'	{ add_to_cbuf(yytext); }
+<C_CODE,ATTR_CODE>\'\"\'	{ add_to_cbuf(yytext); }
+<C_CODE,ATTR_CODE>\'\\\"\'	{ add_to_cbuf(yytext); }
 	
-<C_CODE>\\.	{ add_to_cbuf(yytext); }
+<C_CODE,ATTR_CODE>\\.	{ add_to_cbuf(yytext); }
 
 
 <C_CODE>\"	{
@@ -368,6 +375,11 @@
 			before_string = C_CODE;
 			add_to_cbuf(yytext);
 		}
+<ATTR_CODE>\"	{
+			BEGIN(CODE_STRING);
+			before_string = ATTR_CODE;
+			add_to_cbuf(yytext);
+		}
 <PROPERTY_CODE_I>\"	{
 			BEGIN(CODE_STRING);
 			before_string = PROPERTY_CODE_I;
@@ -391,6 +403,10 @@
 			parenth_depth++;
 			add_to_cbuf(yytext);
 		}
+<ATTR_CODE>\[	{
+			bracket_depth++;
+			add_to_cbuf(yytext);
+		}
 <C_CODE>\}	{
 			parenth_depth--;
 			if(parenth_depth<0) {
@@ -403,9 +419,21 @@
 			}
 			add_to_cbuf(yytext);
 		}
+<ATTR_CODE>\]	{
+			bracket_depth--;
+			if(bracket_depth<0) {
+				REJECT;
+			} else if(bracket_depth==0) {
+				BEGIN(CLASS_CODE_I);
+				yylval.cbuf = cbuf;
+				cbuf = NULL;
+				return CCODE;
+			}
+			add_to_cbuf(yytext);
+		}
 
-<C_CODE>.	{ add_to_cbuf(yytext); }
-<C_CODE>\n	{ add_to_cbuf(yytext); }
+<C_CODE,ATTR_CODE>.	{ add_to_cbuf(yytext); }
+<C_CODE,ATTR_CODE>\n	{ add_to_cbuf(yytext); }
 
 class		{
 			static int found_classes = 0;
@@ -612,6 +640,13 @@
 				BEGIN(INITIAL);
 				return '}';
 			}
+<CLASS_CODE_I>\[	{
+			BEGIN(ATTR_CODE);
+			bracket_depth=1;
+			yylval.line = line_no;
+			clear_cbuf();
+			return '[';
+		}
 
 <CLASS_CODE,CLASS_CODE_I,INITIAL,PROPERTY_CODE,PROPERTY_CODE_I>[\f\t ]	;  /*ignore*/
 
--- src/main.c.orig	2007-10-17 16:49:04.000000000 +0200
+++ src/main.c	2008-01-28 17:01:49.000000000 +0100
@@ -189,21 +189,25 @@
 	g_free(s);
 }
 
-
-static void
-print_method (FILE *fp,
-	      const char *typeprefix,
-	      const char *nameprefix,
-	      const char *subnameprefix,
-	      const char *namepostfix,
-	      const char *afterargs,
-	      const char *postfix,
-	      const Method *m,
-	      gboolean one_arg_per_line,
-	      gboolean no_funcbase,
-	      gboolean kill_underscore,
-	      gboolean first_unused,
-	      gboolean fake_names)
+typedef enum
+{
+  PRINT_METHOD_ONE_ARG_PER_LINE		= 1 << 0,
+  PRINT_METHOD_NO_FUNCBASE		= 1 << 1,
+  PRINT_METHOD_FIRST_UNUSED		= 1 << 2,
+  PRINT_METHOD_FAKE_NAMES		= 1 << 3,
+  PRINT_METHOD_NO_ATTR			= 1 << 4
+} PrintMethodFlags;
+
+static void
+print_method2 (FILE *fp,
+	       const char *typeprefix,
+	       const char *nameprefix,
+	       const char *subnameprefix,
+	       const char *namepostfix,
+	       const char *afterargs,
+	       const char *postfix,
+	       const Method *m,
+	       PrintMethodFlags flags)
 {
 	GList *li;
 	const char *id;
@@ -213,7 +217,7 @@
 
 	id = m->id;
 
-	if(no_funcbase)
+	if ((flags & PRINT_METHOD_NO_FUNCBASE) != 0)
 		out_printf(fp, "%s%s%s%s(",
 			   nameprefix, subnameprefix, id, namepostfix); 
 	else
@@ -229,19 +233,19 @@
 			if ( ! no_gnu &&
 			     ! for_cpp && /* g++ has a cow with this */
 			    li == m->args &&
-			    first_unused) {
+			     (flags & PRINT_METHOD_FIRST_UNUSED) != 0) {
 				unused = " G_GNUC_UNUSED";
 			}
 
 			print_type(fp, arg->atype, FALSE);
-			if (fake_names)
+			if ((flags & PRINT_METHOD_FAKE_NAMES) != 0)
 				out_printf (fp, "___fake___");
 			if(li->next)
 				out_printf(fp, "%s%s%s,%s", arg->name,
 					   arg->atype->postfix ?
 					   arg->atype->postfix : "",
 					   unused,
-					   one_arg_per_line ? "\n\t\t\t\t\t" : " ");
+					   (flags & PRINT_METHOD_ONE_ARG_PER_LINE) != 0 ? "\n\t\t\t\t\t" : " ");
 			else
 				out_printf(fp, "%s%s%s", arg->name,
 					   arg->atype->postfix ?
@@ -250,11 +254,54 @@
 		}
 		if(m->vararg)
 			out_printf(fp, ",%s...",
-				   one_arg_per_line ? "\n\t\t\t\t\t" : " "); 
+				   (flags & PRINT_METHOD_ONE_ARG_PER_LINE) != 0 ? "\n\t\t\t\t\t" : " "); 
 	} else {
 		out_printf(fp, "void"); 
 	}
-	out_printf(fp, "%s)%s", afterargs, postfix); 
+
+	out_printf(fp, "%s)", afterargs);
+
+	if (m->attr && (flags & PRINT_METHOD_NO_ATTR) == 0)
+		out_printf(fp, " %s", m->attr);
+
+	out_printf(fp, "%s", postfix);
+}
+
+static void
+print_method (FILE *fp,
+	      const char *typeprefix,
+	      const char *nameprefix,
+	      const char *subnameprefix,
+	      const char *namepostfix,
+	      const char *afterargs,
+	      const char *postfix,
+	      const Method *m,
+	      gboolean one_arg_per_line,
+	      gboolean no_funcbase,
+	      gboolean kill_underscore,
+	      gboolean first_unused,
+	      gboolean fake_names)
+{
+	PrintMethodFlags flags = 0;
+
+	if (one_arg_per_line)
+		flags |= PRINT_METHOD_ONE_ARG_PER_LINE;
+	if (no_funcbase)
+		flags |= PRINT_METHOD_NO_FUNCBASE;
+	if (first_unused)
+		flags |= PRINT_METHOD_FIRST_UNUSED;
+	if (fake_names)
+		flags |= PRINT_METHOD_FAKE_NAMES;
+
+	print_method2(fp,
+		      typeprefix,
+		      nameprefix,
+		      subnameprefix,
+		      namepostfix,
+		      afterargs,
+		      postfix,
+		      m,
+		      flags);
 }
 
 static gboolean
@@ -371,11 +418,13 @@
 
 	/* if a signal mark it as such */
 	if(m->method != VIRTUAL_METHOD)
-		print_method(outh, "\t/*signal*/", "(* ", "", ") ", "", ";\n",
-			     m, FALSE, TRUE, TRUE, FALSE, FALSE);
+		print_method2(outh, "\t/*signal*/", "(* ", "", ") ", "", ";\n",
+			      m, PRINT_METHOD_NO_FUNCBASE |
+			      PRINT_METHOD_NO_ATTR);
 	else
-		print_method(outh, "\t", "(* ", "", ") ", "", ";\n",
-			     m, FALSE, TRUE, TRUE, FALSE, FALSE);
+		print_method2(outh, "\t", "(* ", "", ") ", "", ";\n",
+			      m, PRINT_METHOD_NO_FUNCBASE |
+			      PRINT_METHOD_NO_ATTR);
 }
 
 static void
@@ -422,8 +471,11 @@
 			    "\"%s\","
 			    "(GCallback) __extension__ ({",
 			    funcbase, m->id, macrobase, typebase, m->id);
-		print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
-			      " = (func); ", m, FALSE, TRUE, TRUE, FALSE, TRUE);
+		print_method2 (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
+			       " = (func); ", m,
+			       PRINT_METHOD_NO_FUNCBASE
+			       | PRINT_METHOD_FAKE_NAMES
+			       | PRINT_METHOD_NO_ATTR);
 		out_printf (outh, "___%s; }), (data))\n", m->id);
 
 		/* connect_after */
@@ -433,8 +485,11 @@
 			    "\"%s\","
 			    "(GCallback) __extension__ ({",
 			    funcbase, m->id, macrobase, typebase, m->id);
-		print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
-			      " = (func); ", m, FALSE, TRUE, TRUE, FALSE, TRUE);
+		print_method2 (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
+			       " = (func); ", m,
+			       PRINT_METHOD_NO_FUNCBASE
+			       | PRINT_METHOD_FAKE_NAMES
+			       | PRINT_METHOD_NO_ATTR);
 		out_printf (outh, "___%s; }), (data))\n", m->id);
 
 		/* connect_data */
@@ -445,8 +500,11 @@
 			    "\"%s\","
 			    "(GCallback) __extension__ ({",
 			    funcbase, m->id, macrobase, typebase, m->id);
-		print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
-			      " = (func); ", m, FALSE, TRUE, TRUE, FALSE, TRUE);
+		print_method2 (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
+			       " = (func); ", m,
+			       PRINT_METHOD_NO_FUNCBASE
+			       | PRINT_METHOD_FAKE_NAMES
+			       | PRINT_METHOD_NO_ATTR);
 		out_printf (outh, "___%s; }), (data), (destroy_data), (GConnectFlags)(flags))\n", m->id);
 	}
 }
@@ -526,9 +584,9 @@
 	   m->method == SIGNAL_FIRST_METHOD ||
 	   m->method == VIRTUAL_METHOD) {
 		if(m->cbuf)
-			print_method(out,
-				     "static ", "___real_", "", " ", "", ";\n",
-				     m, FALSE, FALSE, TRUE, FALSE, FALSE);
+			print_method2(out,
+				      "static ", "___real_", "", " ", "", ";\n",
+				      m, PRINT_METHOD_NO_ATTR);
 	}
 	/* no else, here, it might still have a private prototype, it's not
 	 * exclusive */
@@ -537,15 +595,13 @@
 	    m->cbuf)) {
 		/* add unique ID */
 		char *s = g_strdup_printf("___%x_", (guint)m->unique_id);
-		print_method(out, "static ", s, "", " ", "",
-			     no_gnu?";\n":" G_GNUC_UNUSED;\n",
+		print_method(out, "static ", s, "", " ", "", ";\n",
 			     m, FALSE, FALSE, FALSE, FALSE, FALSE);
 		g_free(s);
 	} else if(m->scope == PRIVATE_SCOPE ||
 		  m->method == INIT_METHOD ||
 		  m->method == CLASS_INIT_METHOD) {
-		print_method(out, "static ", "", "", " ", "",
-			     no_gnu?";\n":" G_GNUC_UNUSED;\n",
+		print_method(out, "static ", "", "", " ", "", ";\n",
 			     m, FALSE, FALSE, TRUE, FALSE, FALSE);
 	}
 }
@@ -2831,11 +2887,11 @@
 		if(m->line_no > 0)
 			out_addline_infile(out, m->line_no);
 		if(m->scope == PRIVATE_SCOPE)
-			print_method(out, "static ", "\n", "", " ", "", "\n",
-				     m, FALSE, FALSE, TRUE, FALSE, FALSE);
+			print_method2(out, "static ", "\n", "", " ", "", "\n",
+				      m, PRINT_METHOD_NO_ATTR);
 		else /* PUBLIC, PROTECTED */
-			print_method(out, "", "\n", "", " ", "", "\n",
-				     m, FALSE, FALSE, TRUE, FALSE, FALSE);
+			print_method2(out, "", "\n", "", " ", "", "\n",
+				      m, PRINT_METHOD_NO_ATTR);
 		print_method_body(m, TRUE, TRUE);
 		/* the outfile line was added above */
 		break;
@@ -2844,11 +2900,11 @@
 		if(m->line_no > 0)
 			out_addline_infile(out, m->line_no);
 		if(m->scope == PRIVATE_SCOPE)
-			print_method(out, "static ", "\n", "", " ", "", "\n",
-				     m, FALSE, FALSE, TRUE, FALSE, FALSE);
+			print_method2(out, "static ", "\n", "", " ", "", "\n",
+				      m, PRINT_METHOD_NO_ATTR);
 		else /* PUBLIC, PROTECTED */
-			print_method(out, "", "\n", "", " ", "", "\n",
-				     m, FALSE, FALSE, TRUE, FALSE, FALSE);
+			print_method2(out, "", "\n", "", " ", "", "\n",
+				      m, PRINT_METHOD_NO_ATTR);
 		out_addline_outfile (out);
 
 		out_printf (out, "{\n");
@@ -2966,8 +3022,8 @@
 			break;
 		if(m->line_no > 0)
 			out_addline_infile(out, m->line_no);
-		print_method(out, "static ", "\n___real_", "", " ", "", "\n",
-			     m, FALSE, FALSE, TRUE, TRUE, FALSE);
+		print_method2(out, "static ", "\n___real_", "", " ", "", "\n",
+			      m, PRINT_METHOD_NO_ATTR);
 		print_method_body(m, FALSE, TRUE);
 		/* the outfile line was added above */
 		break;
@@ -2975,11 +3031,11 @@
 		if(m->line_no > 0)
 			out_addline_infile(out, m->line_no);
 		if(m->scope==PRIVATE_SCOPE)
-			print_method(out, "static ", "\n", "", " ", "", "\n",
-				     m, FALSE, FALSE, TRUE, FALSE, FALSE);
+			print_method2(out, "static ", "\n", "", " ", "", "\n",
+				      m, PRINT_METHOD_NO_ATTR);
 		else /* PUBLIC, PROTECTED */
-			print_method(out, "", "\n", "", " ", "", "\n",
-				     m, FALSE, FALSE, TRUE, FALSE, FALSE);
+			print_method2(out, "", "\n", "", " ", "", "\n",
+				      m, PRINT_METHOD_NO_ATTR);
 		out_addline_outfile(out);
 		out_printf(out, "{\n"
 			"\t%sClass *klass;\n", typebase);
@@ -3024,8 +3080,9 @@
 			break;
 		if(m->line_no > 0)
 			out_addline_infile(out, m->line_no);
-		print_method(out, "static ", "\n___real_", "", " ", "", "\n",
-			     m, FALSE, FALSE, TRUE, TRUE, FALSE);
+		print_method2(out, "static ", "\n___real_", "", " ", "", "\n",
+			      m, PRINT_METHOD_FIRST_UNUSED
+			      | PRINT_METHOD_NO_ATTR);
 		print_method_body(m, FALSE, TRUE);
 		/* the outfile line was added above */
 		break;
--- src/parse.y.orig	2007-03-09 18:46:14.000000000 +0100
+++ src/parse.y	2008-01-28 16:58:25.000000000 +0100
@@ -146,7 +146,7 @@
 
 static void
 push_function (int scope, int method, char *oid, char *id,
-	       GString *cbuf, int line_no, int ccode_line,
+	       GString *attr, GString *cbuf, int line_no, int ccode_line,
 	       gboolean vararg, GList *flags)
 {
 	Node *node;
@@ -207,6 +207,7 @@
 			 "args:steal", funcargs,
 			 "onerror:steal", onerror,
 			 "defreturn:steal", defreturn,
+			 "attr:steal", attr ? attr->str : NULL,
 			 "cbuf:steal", c_cbuf,
 			 "line_no", line_no,
 			 "ccode_line", ccode_line,
@@ -216,6 +217,8 @@
 
 	last_added_method = (Method *)node;
 
+	if(attr)
+		g_string_free(attr, FALSE);
 	if(cbuf)
 		g_string_free(cbuf,
 			      /*only free segment if we haven't passed it
@@ -405,7 +408,7 @@
 		push_funcarg ("self", FALSE);
 		
 		push_function (PUBLIC_SCOPE, REGULAR_METHOD, NULL,
-			       get_id, get_cbuf, get_lineno,
+			       get_id, NULL, get_cbuf, get_lineno,
 			       lineno, FALSE, NULL);
 	}
 	
@@ -439,7 +442,7 @@
 	
 		typestack = g_list_prepend (typestack, node2);
 		push_function (PUBLIC_SCOPE, REGULAR_METHOD, NULL,
-			       set_id, set_cbuf, set_lineno,
+			       set_id, NULL, set_cbuf, set_lineno,
 			       lineno, FALSE, NULL);
 	}
 
@@ -1678,9 +1681,25 @@
 				YYERROR;
 			}
 			push_function(the_scope, $<sigtype>3,NULL,
-				      $<id>5, $<cbuf>10,$<line>1,
+				      $<id>5, NULL, $<cbuf>10,$<line>1,
 				      ccode_line, vararg, $<list>2);
 									}
+	|	'[' CCODE SIGNAL flags fullsigtype type TOKEN '(' funcargs ')' returnvals codenocode {
+			if(!has_self) {
+				yyerror(_("signal without 'self' as "
+					  "first parameter"));
+				free_all_global_state();
+				YYERROR;
+			}
+			if(the_scope == CLASS_SCOPE) {
+				yyerror(_("a method cannot be of class scope"));
+				free_all_global_state();
+				YYERROR;
+			}
+			push_function(the_scope, $<sigtype>5,NULL,
+				      $<id>7, $<cbuf>2, $<cbuf>12,$<line>3,
+				      ccode_line, vararg, $<list>4);
+									}
 	|	scope SIGNAL flags simplesigtype type TOKEN '(' funcargs ')' returnvals codenocode {
 			if(!has_self) {
 				yyerror(_("signal without 'self' as "
@@ -1694,9 +1713,25 @@
 				YYERROR;
 			}
 			push_function(the_scope, $<sigtype>4, NULL,
-				      $<id>6, $<cbuf>11, $<line>2,
+				      $<id>6, NULL, $<cbuf>11, $<line>2,
 				      ccode_line, vararg, $<list>3);
 									}
+	|	'[' CCODE scope SIGNAL flags simplesigtype type TOKEN '(' funcargs ')' returnvals codenocode {
+			if(!has_self) {
+				yyerror(_("signal without 'self' as "
+					  "first parameter"));
+				free_all_global_state();
+				YYERROR;
+			}
+			if(the_scope == CLASS_SCOPE) {
+				yyerror(_("a method cannot be of class scope"));
+				free_all_global_state();
+				YYERROR;
+			}
+			push_function(the_scope, $<sigtype>6, NULL,
+				      $<id>8, $<cbuf>2, $<cbuf>13, $<line>4,
+				      ccode_line, vararg, $<list>5);
+									}
 	|	VIRTUAL scope type TOKEN '(' funcargs ')' returnvals codenocode	{
 			if(!has_self) {
 				yyerror(_("virtual method without 'self' as "
@@ -1710,7 +1745,23 @@
 				YYERROR;
 			}
 			push_function(the_scope, VIRTUAL_METHOD, NULL, $<id>4,
-				      $<cbuf>9, $<line>1,
+				      NULL, $<cbuf>9, $<line>1,
+				      ccode_line, vararg, NULL);
+									}
+	|	'[' CCODE VIRTUAL scope type TOKEN '(' funcargs ')' returnvals codenocode	{
+			if(!has_self) {
+				yyerror(_("virtual method without 'self' as "
+					  "first parameter"));
+				free_all_global_state();
+				YYERROR;
+			}
+			if(the_scope == CLASS_SCOPE) {
+				yyerror(_("a method cannot be of class scope"));
+				free_all_global_state();
+				YYERROR;
+			}
+			push_function(the_scope, VIRTUAL_METHOD, NULL, $<id>6,
+				      $<cbuf>2, $<cbuf>11, $<line>3,
 				      ccode_line, vararg, NULL);
 									}
 	|	scope VIRTUAL type TOKEN '(' funcargs ')' returnvals codenocode	{
@@ -1726,7 +1777,23 @@
 				YYERROR;
 			}
 			push_function(the_scope, VIRTUAL_METHOD, NULL, $<id>4,
-				      $<cbuf>9, $<line>2,
+				      NULL, $<cbuf>9, $<line>2,
+				      ccode_line, vararg, NULL);
+									}
+	|	'[' CCODE scope VIRTUAL type TOKEN '(' funcargs ')' returnvals codenocode	{
+			if(!has_self) {
+				yyerror(_("virtual method without 'self' as "
+					  "first parameter"));
+				free_all_global_state();
+				YYERROR;
+			}
+			if(the_scope == CLASS_SCOPE) {
+				yyerror(_("a method cannot be of class scope"));
+				free_all_global_state();
+				YYERROR;
+			}
+			push_function(the_scope, VIRTUAL_METHOD, NULL, $<id>6,
+				      $<cbuf>2, $<cbuf>11, $<line>4,
 				      ccode_line, vararg, NULL);
 									}
 	|	VIRTUAL type TOKEN '(' funcargs ')' returnvals codenocode	{
@@ -1737,12 +1804,23 @@
 				YYERROR;
 			}
 			push_function(PUBLIC_SCOPE, VIRTUAL_METHOD, NULL,
-				      $<id>3, $<cbuf>8, $<line>1,
+				      $<id>3, NULL, $<cbuf>8, $<line>1,
+				      ccode_line, vararg, NULL);
+									}
+	|	'[' CCODE VIRTUAL type TOKEN '(' funcargs ')' returnvals codenocode	{
+			if(!has_self) {
+				yyerror(_("virtual method without 'self' as "
+					  "first parameter"));
+				free_all_global_state();
+				YYERROR;
+			}
+			push_function(PUBLIC_SCOPE, VIRTUAL_METHOD, NULL,
+				      $<id>5, $<cbuf>2, $<cbuf>10, $<line>3,
 				      ccode_line, vararg, NULL);
 									}
 	|	OVERRIDE '(' TYPETOKEN ')' type TOKEN '(' funcargs ')' returnvals codenocode	{
 			push_function(NO_SCOPE, OVERRIDE_METHOD, $<id>3,
-				      $<id>6, $<cbuf>11,
+				      $<id>6, NULL, $<cbuf>11,
 				      $<line>1, ccode_line,
 				      vararg, NULL);
 									}
@@ -1753,19 +1831,29 @@
 				YYERROR;
 			}
 			push_function(the_scope, REGULAR_METHOD, NULL, $<id>3,
-				      $<cbuf>8, $<line>1, ccode_line,
+				      NULL, $<cbuf>8, $<line>1, ccode_line,
+				      vararg, NULL);
+								}
+	|	'[' CCODE scope type TOKEN '(' funcargs ')' returnvals codenocode {
+			if(the_scope == CLASS_SCOPE) {
+				yyerror(_("a method cannot be of class scope"));
+				free_all_global_state();
+				YYERROR;
+			}
+			push_function(the_scope, REGULAR_METHOD, NULL, $<id>5,
+				      $<cbuf>2, $<cbuf>10, $<line>3, ccode_line,
 				      vararg, NULL);
 								}
 	|	TOKEN '(' TOKEN ')' codenocode	{
 			if(strcmp($<id>1, "init")==0) {
 				push_init_arg($<id>3,FALSE);
 				push_function(NO_SCOPE, INIT_METHOD, NULL,
-					      $<id>1, $<cbuf>5, $<line>2,
+					      $<id>1, NULL, $<cbuf>5, $<line>2,
 					      ccode_line, FALSE, NULL);
 			} else if(strcmp($<id>1, "class_init")==0) {
 				push_init_arg($<id>3,TRUE);
 				push_function(NO_SCOPE, CLASS_INIT_METHOD, NULL,
-					      $<id>1, $<cbuf>5, $<line>2,
+					      $<id>1, NULL, $<cbuf>5, $<line>2,
 					      ccode_line, FALSE, NULL);
 			} else {
 				g_free($<id>1);
--- src/treefuncs.def.orig	2007-03-09 18:46:14.000000000 +0100
+++ src/treefuncs.def	2008-01-28 16:16:21.000000000 +0100
@@ -126,6 +126,7 @@
   NODELIST	args
   STRING	onerror
   STRING	defreturn
+  STRING	attr
   STRING	cbuf
   INT		line_no
   INT		ccode_line

