diff --git a/tools/gcg/ChangeLog b/tools/gcg/ChangeLog index dc85bc6086..04cf76a3e6 100644 --- a/tools/gcg/ChangeLog +++ b/tools/gcg/ChangeLog @@ -1,3 +1,8 @@ +1998-11-18 Lauri Alanko + + * Signal marshalling should be pretty complete now. Demarshalling + isn't quite yet, though.. + 1998-11-17 Lauri Alanko * Misc enhancements. diff --git a/tools/gcg/db.c b/tools/gcg/db.c index 8729b83924..a2bbde2fd4 100644 --- a/tools/gcg/db.c +++ b/tools/gcg/db.c @@ -14,7 +14,7 @@ PrimType* get_type(Id modname, Id name){ p=g_new(PrimType, 1); p->module=m; p->name=name; - p->kind=GTK_TYPE_INVALID; + p->kind=TYPE_INVALID; p->decl_header=NULL; p->def_header=NULL; p->definition=NULL; diff --git a/tools/gcg/gcg.h b/tools/gcg/gcg.h index 6cfabab96d..d11d75b7d6 100644 --- a/tools/gcg/gcg.h +++ b/tools/gcg/gcg.h @@ -1,7 +1,6 @@ #ifndef __GCG_H__ #define __GCG_H__ #include -#include extern gboolean in_ident; @@ -25,6 +24,17 @@ typedef struct _DefClass DefClass; typedef struct _Param Param; typedef struct _Module Module; +typedef enum{ + TYPE_INVALID, + TYPE_NONE, + TYPE_INT, + TYPE_LONG, + TYPE_DOUBLE, + TYPE_ENUM, + TYPE_FLAGS, + TYPE_FOREIGN, + TYPE_OBJECT +} TypeKind; struct _Module { Id name; @@ -35,7 +45,7 @@ struct _Module { struct _PrimType { Module* module; Id name; - GtkFundamentalType kind; + TypeKind kind; Id decl_header; Id def_header; Def* definition; diff --git a/tools/gcg/gimpimage.def b/tools/gcg/gimpimage.def index 7027a00c10..f0af7bedb3 100644 --- a/tools/gcg/gimpimage.def +++ b/tools/gcg/gimpimage.def @@ -37,8 +37,8 @@ class Image : Object{ g.int num-cols; read-only BaseType base-type; read-write g.int foobar; - Layer* active-layer; - Layer* floating-sel; + read-write Layer& active-layer; + read-write Layer* floating-sel; public static Image* new(g.int width, g.int height, BaseType base-type); @@ -46,6 +46,19 @@ class Image : Object{ public static g.int foo-1(Layer* x); public direct g.int foo-2(Layer* x); public abstract void foo-3(g.int x); - public pre-emit void foo-4(g.int x) const; - public post-emit void foo-5(g.int x, Drawable**& n, Image* z); + protected pre-emit void foo-4(g.int x) const; + public post-emit g.int foo-5(g.int x, Drawable**& n, Image* z); + public post-emit g.int foo-6(g.int a1, +g.int a2, +g.int a3, +g.int a4, +g.int a5, +g.int a6, +g.int a7, +g.int a8, +g.int a9, +g.int a10, +g.int a11, +g.int a12, +g.int a13); }; diff --git a/tools/gcg/marshall.c b/tools/gcg/marshall.c index 954113e8c3..2311f093c9 100644 --- a/tools/gcg/marshall.c +++ b/tools/gcg/marshall.c @@ -2,12 +2,47 @@ #include "output.h" #include "marshall.h" + +typedef enum { + MARSHALL_INT, + MARSHALL_DOUBLE, + MARSHALL_POINTER, + MARSHALL_VOID, + MARSHALL_LONG +} MarshallType; + + struct _SignalType { Id package; - GtkType rettype; + MarshallType rettype; GSList* argtypes; }; +MarshallType marshalling_type(Type* t){ + if(!t) + return MARSHALL_VOID; + if(t->indirection) + return MARSHALL_POINTER; + if(!t->prim) + return MARSHALL_VOID; + switch(t->prim->kind){ + case TYPE_INT: + case TYPE_FLAGS: + case TYPE_ENUM: + return MARSHALL_INT; + case TYPE_LONG: + return MARSHALL_LONG; + case TYPE_DOUBLE: + return MARSHALL_DOUBLE; + case TYPE_NONE: + return MARSHALL_VOID; + default: + g_assert_not_reached(); + return MARSHALL_VOID; + } +} + + SignalType* sig_type(Method* m){ SignalType *t=g_new(SignalType, 1); GSList* p=m->params, *a=NULL; @@ -15,7 +50,7 @@ SignalType* sig_type(Method* m){ t->rettype = marshalling_type(&m->ret_type); while(p){ Param* param=p->data; - GtkType* t=g_new(GtkType, 1); + MarshallType* t=g_new(MarshallType, 1); *t=marshalling_type(¶m->type); a=g_slist_prepend(a, t); p=p->next; @@ -35,63 +70,61 @@ void sig_type_free(SignalType* t){ g_free(t); } -PNode* p_gtype_name(GtkType t, gboolean abbr){ +PNode* p_gtype_name(MarshallType t, gboolean abbr){ static const struct GTypeName{ - GtkType type; + MarshallType type; Id name; Id aname; }names[]={ - {GTK_TYPE_POINTER, "POINTER", "P"}, - {GTK_TYPE_INT, "INT", "I"}, - {GTK_TYPE_DOUBLE, "DOUBLE", "D"}, - {GTK_TYPE_LONG, "LONG", "L"}, - {GTK_TYPE_CHAR, "CHAR", "C"}, - {GTK_TYPE_NONE, "NONE", "0"}, + {MARSHALL_POINTER, "POINTER", "P"}, + {MARSHALL_INT, "INT", "I"}, + {MARSHALL_DOUBLE, "DOUBLE", "D"}, + {MARSHALL_LONG, "LONG", "L"}, + {MARSHALL_VOID, "NONE", "0"}, }; gint i; - for(i=0;iprim) - return GTK_TYPE_NONE; - - g_assert(t->prim->kind!=GTK_TYPE_INVALID); - if(t->indirection) - return GTK_TYPE_POINTER; - switch(t->prim->kind){ - case GTK_TYPE_UINT: - case GTK_TYPE_BOOL: - case GTK_TYPE_FLAGS: - case GTK_TYPE_ENUM: - return GTK_TYPE_INT; - case GTK_TYPE_STRING: - return GTK_TYPE_POINTER; - case GTK_TYPE_UCHAR: - return GTK_TYPE_CHAR; - case GTK_TYPE_ULONG: - return GTK_TYPE_LONG; - default: - return t->prim->kind; - } +PNode* p_gtktype(Type* t){ + if(t->indirection==0){ + if(!t->prim) + return p_str("GTK_TYPE_NONE"); + switch(t->prim->kind){ + case TYPE_INT: + return p_str("GTK_TYPE_INT"); + case TYPE_DOUBLE: + return p_str("GTK_TYPE_DOUBLE"); + case TYPE_ENUM: + case TYPE_FLAGS: + return p_macro_name(t->prim, "TYPE", NULL); + default: + g_assert_not_reached(); + return p_str("GTK_TYPE_NONE"); + } + }else if(t->indirection==1 + && t->prim + && (t->prim->kind==TYPE_FOREIGN + || t->prim->kind==TYPE_OBJECT)) + return p_macro_name(t->prim, "TYPE", NULL); + else + return p_str("GTK_TYPE_POINTER"); } - + PNode* p_signal_func_name(SignalType* t, PNode* basename){ return p_fmt("_~_~_~_~", @@ -116,15 +149,65 @@ PNode* p_handler_type(SignalType* t){ p_for(t->argtypes, p_gtabbr, p_nil)); } +PNode* p_signal_id(Method* s){ + PrimType* t=DEF(MEMBER(s)->my_class)->type; + return p_fmt("_~_~_signal_~", + p_c_ident(t->module->name), + p_c_ident(t->name), + p_c_ident(MEMBER(s)->name)); +} typedef struct{ PNode* args; gint idx; }ArgMarshData; - PNode* p_arg_marsh(gpointer p, gpointer d){ - GtkType* t=p; + Param* par=p; + gint* idx=d; + (*idx)++; + return p_fmt(/* "\targs[~].type=~;\n" unnecessary... */ + "\tGTK_VALUE_~(args[~]) = ~;\n", + /* p_prf("%d", *idx), + p_gtktype(&par->type), */ + p_gtype_name(marshalling_type(&par->type), FALSE), + p_prf("%d", *idx), + p_c_ident(par->name)); +} + +PNode* p_sig_marshalling(Method* m){ + gint idx=-1; + gboolean ret=marshalling_type(&m->ret_type)!=MARSHALL_VOID; + return p_fmt("\t{\n" + "\tGtkArg args[~];\n" + "~" + "~" + "~" + "\tgtk_signal_emitv((GtkObject*)~, ~, args);\n" + "~" + "\t}\n", + p_prf("%d", + g_slist_length(m->params)+ret), + ret + ?p_fmt("\t~ retval;\n", + p_type(&m->ret_type)) + :p_nil, + p_for(m->params, p_arg_marsh, &idx), + ret + /* cannot use retloc here, ansi forbids casted lvalues */ + ?p_fmt("\tGTK_VALUE_POINTER(args[~]) = &retval;\n", + p_prf("%d", g_slist_length(m->params))) + :p_nil, + p_c_ident(DEF(MEMBER(m)->my_class)->type->name), + p_signal_id(m), + ret + ?p_str("\treturn retval;\n") + :p_nil); +} + + +PNode* p_arg_demarsh(gpointer p, gpointer d){ + MarshallType* t=p; ArgMarshData* data=d; return p_fmt("\t\tGTK_VALUE_~(~[~]),\n", p_gtype_name(*t, FALSE), @@ -136,7 +219,7 @@ PNode* p_demarshaller(SignalType* t){ gint idx=0; - return p_lst((t->rettype==GTK_TYPE_NONE) + return p_lst((t->rettype==TYPE_NONE) ? p_fmt("\t*(GTK_RETLOC_~(args[~])) =\n", p_gtype_name(t->rettype, FALSE), p_prf("%d", g_slist_length(t->argtypes))) @@ -145,7 +228,7 @@ PNode* p_demarshaller(SignalType* t){ "~" "\tuser_data);\n", p_cast(p_handler_type(t), p_str("func")), - p_for(t->argtypes, p_arg_marsh, &idx)), + p_for(t->argtypes, p_arg_demarsh, &idx)), p_nil); } diff --git a/tools/gcg/marshall.h b/tools/gcg/marshall.h index 3b1bf0abff..4708d84c68 100644 --- a/tools/gcg/marshall.h +++ b/tools/gcg/marshall.h @@ -7,11 +7,13 @@ typedef struct _SignalType SignalType; SignalType* sig_type(Method* m); void sig_type_free(SignalType* t); -PNode* p_gtype_name(GtkType t, gboolean abbr); PNode* p_gtabbr(gpointer p); -GtkType marshalling_type(Type* t); PNode* p_signal_marshaller_name(SignalType* s); PNode* p_signal_demarshaller_name(SignalType* s); PNode* p_arg_marsh(gpointer p, gpointer d); +PNode* p_gtktype(Type* t); +PNode* p_signal_id(Method* s); +PNode* p_sig_marshalling(Method* m); + #endif diff --git a/tools/gcg/output.c b/tools/gcg/output.c index a744928784..aa1edff70d 100644 --- a/tools/gcg/output.c +++ b/tools/gcg/output.c @@ -129,7 +129,7 @@ PNode* p_type_guard(Type* t, PNode* var){ ((t->indirection && t->notnull ? p_fmt("\tg_assert (~);\n", var) : p_nil), - ((t->indirection==1 && p->kind == GTK_TYPE_OBJECT) + ((t->indirection==1 && p->kind == TYPE_OBJECT) ? (t->notnull ? p_fmt("\tg_assert (~(~));\n", p_macro_name(p, "IS", NULL), @@ -139,11 +139,11 @@ PNode* p_type_guard(Type* t, PNode* var){ p_macro_name(p, "IS", NULL), var)) : (t->indirection==0 - ? ((p->kind == GTK_TYPE_ENUM) + ? ((p->kind == TYPE_ENUM) ? p_fmt("\tg_assert (~ <= ~);\n", var, p_macro_name(p, NULL, "LAST")) - : ((p->kind == GTK_TYPE_FLAGS) + : ((p->kind == TYPE_FLAGS) ? p_fmt("\tg_assert ((~ << 1) < ~);\n", var, p_macro_name(p, NULL, "LAST")) @@ -172,6 +172,23 @@ PNode* p_prototype(Type* rettype, PNode* name, p_params(args2, &o)); } +void output_var_alias(PRoot* out, PrimType* t, PNode* basename){ + pr_add(out, "import_alias", + p_fmt("#define ~ ~_~\n", + basename, + p_c_ident(t->module->name), + basename)); +} + +void output_type_alias(PRoot* out, PrimType* t, PNode* basename){ + pr_add(out, "import_alias", + p_fmt("typedef ~~ ~;\n", + p_str(t->module->name), + basename, + basename)); +} + + void output_func(PRoot* out, Id tag, Type* rettype, @@ -239,13 +256,13 @@ void output_def(PRoot* out, Def* d){ p_str("GtkType"), type_var); switch(d->type->kind){ - case GTK_TYPE_OBJECT: + case TYPE_OBJECT: output_object(out, d); break; - case GTK_TYPE_ENUM: + case TYPE_ENUM: output_enum(out, d); break; - case GTK_TYPE_FLAGS: + case TYPE_FLAGS: output_flags(out, d); break; default: diff --git a/tools/gcg/output_object.c b/tools/gcg/output_object.c index a370e9b9de..b54a615cff 100644 --- a/tools/gcg/output_object.c +++ b/tools/gcg/output_object.c @@ -1,6 +1,10 @@ #include "output.h" #include "marshall.h" +PNode* p_self_name(Member* o){ + return p_c_ident(DEF(o->my_class)->type->name); +} + PNode* p_object_member(Member* m){ DataMember* d; if(m->membertype != MEMBER_DATA) @@ -94,13 +98,6 @@ PNode* p_real_varname(PrimType* t, PNode* name){ p_varname(t, name)); } -PNode* p_signal_id(Method* s){ - PrimType* t=DEF(MEMBER(s)->my_class)->type; - return p_fmt("_~_~_signal_~", - p_c_ident(t->module->name), - p_c_ident(t->name), - p_c_ident(MEMBER(s)->name)); -} PNode* p_signal_handler_type(Method* s){ Member* m=MEMBER(s); @@ -112,9 +109,9 @@ PNode* p_signal_handler_type(Method* s){ void output_connector(PRoot* out, Method* m){ FunParams* par=fparams("t", - &MEMBER(m)->my_class->self_type[m->self_const], - p_c_ident(DEF(MEMBER(m)->my_class)->type->name), - p_nil); + &MEMBER(m)->my_class->self_type[m->self_const], + p_self_name(MEMBER(m)), + p_nil); output_func(out, "functions", &m->ret_type, @@ -129,7 +126,7 @@ void output_connector(PRoot* out, Method* m){ "\t\t(GtkSignalFunc)handler,\n" "\t\tuser_data);\n", m->ret_type.prim?p_str("return "):p_nil, - p_c_ident(DEF(MEMBER(m)->my_class)->type->name), + p_self_name(MEMBER(m)), p_str(MEMBER(m)->name))); } @@ -148,9 +145,9 @@ void output_method(PRoot* out, Method* m){ else par = fparams("tp", &MEMBER(m)->my_class->self_type[m->self_const], - p_c_ident(t->name), - p_nil, - m->params); + p_self_name(MEMBER(m)), + p_nil, + m->params); switch(k){ SignalType* sig; case METH_EMIT_PRE: @@ -158,22 +155,19 @@ void output_method(PRoot* out, Method* m){ case METH_EMIT_BOTH: sig=sig_type(m); output_var(out, NULL, - p_str("GtkSignal"), + p_str("GtkSignalID"), p_signal_id(m)); o.names=FALSE; o.types=TRUE; pr_add(out, "functions", - p_fmt("typedef ~ (*~)(~);\n", + p_fmt("typedef ~ (*~)(~, gpointer);\n", p_type(&m->ret_type), p_signal_handler_type(m), p_params(par, &o))); output_connector(out, m); o.names=TRUE; o.types=FALSE; - dispatch=p_fmt("~(~, (GtkObject*)~)", - p_signal_marshaller_name(sig), - p_signal_id(m), - p_params(par, &o)); + dispatch=p_sig_marshalling(m); break; case METH_STATIC: case METH_DIRECT: @@ -185,12 +179,18 @@ void output_method(PRoot* out, Method* m){ p_real_varname(t, name), p_params(par, &o))); o.types=FALSE; - dispatch=p_fmt("~(~)", + dispatch=p_fmt("\t~ ~(~);\n", + m->ret_type.prim? + p_str("return "): + p_nil, p_real_varname(t, name), p_params(par, &o)); break; case METH_VIRTUAL: - dispatch=p_fmt("((~*)((GtkObject*)~)->klass)->~(~)", + dispatch=p_fmt("\t~((~*)((GtkObject*)~)->klass)->~(~);\n", + m->ret_type.prim? + p_str("return "): + p_nil, p_class_name(DEF(MEMBER(m)->my_class)->type), p_c_ident(t->name), name, @@ -204,21 +204,22 @@ void output_method(PRoot* out, Method* m){ p_varname(t, name), p_nil, par, - p_fmt("\t~~;\n", - m->ret_type.prim ? p_str("return ") : p_nil, - dispatch)); - fparams_free(par); + dispatch); + + fparams_free(par); } void output_data_member(PRoot* out, DataMember* m){ PrimType* t=DEF(MEMBER(m)->my_class)->type; PNode* name = p_c_ident(MEMBER(m)->name); + PNode* self = p_self_name(MEMBER(m)); + switch(m->prot){ FunParams* par; case DATA_READWRITE: { par=fparams("tt", &MEMBER(m)->my_class->self_type[FALSE], - p_str("self"), + self, p_nil, &m->type, name, @@ -229,7 +230,32 @@ void output_data_member(PRoot* out, DataMember* m){ p_varname(t, p_fmt("set_~", name)), p_nil, par, - p_fmt("\tself->~ = ~;\n", + p_fmt("~" + "\t~->~ = ~;\n", + (m->type.prim->kind==TYPE_OBJECT + && m->type.indirection==1) + ?m->type.notnull + ?p_fmt("\tgtk_object_ref " + "((GtkObject*) ~);\n" + "\tgtk_object_unref " + "((GtkObject*) ~->~);\n", + name, + self, + name) + :p_fmt("\tif(~)\n" + "\t\tgtk_object_ref " + "((GtkObject*) ~);\n" + "\tif(~->~)\n" + "\t\tgtk_object_unref " + "((GtkObject*) ~->~);\n", + name, + name, + self, + name, + self, + name) + :p_nil, + self, name, name)); fparams_free(par); @@ -237,7 +263,7 @@ void output_data_member(PRoot* out, DataMember* m){ /* fall through */ case DATA_READONLY: par=fparams("t", &MEMBER(m)->my_class->self_type[TRUE], - p_str("self"), + self, p_nil); output_func(out, "functions", @@ -245,7 +271,8 @@ void output_data_member(PRoot* out, DataMember* m){ p_varname(t, name), p_nil, par, - p_fmt("\treturn self->~;\n", + p_fmt("\treturn ~->~;\n", + self, name)); fparams_free(par); case DATA_PROTECTED: @@ -310,8 +337,8 @@ void output_object_type_init(PRoot* out, ObjectDef* o){ PNode* p_param_marshtype(gpointer p){ Param* param=p; - return p_fmt(",\n\t\tGTK_TYPE_~", - p_gtype_name(marshalling_type(¶m->type), FALSE)); + return p_fmt(",\n\t\t~", + p_gtktype(¶m->type)); } PNode* p_member_class_init(gpointer m, gpointer o){ @@ -327,18 +354,23 @@ PNode* p_member_class_init(gpointer m, gpointer o){ case METH_EMIT_PRE: case METH_EMIT_POST: case METH_EMIT_BOTH: - return p_fmt("\t~ =\n" + return p_fmt("\t{\n" + "\textern void ~ (GtkObject*, GtkSignalFunc, " + "gpointer, GtkArg*);\n" + "\t~ =\n" "\tgtk_signal_new(\"~\",\n" "\t\tGTK_RUN_~,\n" "\t\tobklass->type,\n" "\t\tGTK_SIGNAL_OFFSET (~, ~),\n" "\t\t~,\n" - "\t\tGTK_TYPE_~,\n" + "\t\t~,\n" "\t\t~" "~);\n" "\tgtk_object_class_add_signals(obklass,\n" "\t\t&~,\n" - "\t\t1);\n", + "\t\t1);\n" + "\t}\n", + p_signal_demarshaller_name(sig), p_signal_id(meth), p_str(mem->name), p_str(meth->kind==METH_EMIT_PRE @@ -349,8 +381,7 @@ PNode* p_member_class_init(gpointer m, gpointer o){ p_class_name(DEF(ob)->type), p_c_ident(mem->name), p_signal_demarshaller_name(sig), - p_gtype_name(marshalling_type(&meth->ret_type), - FALSE), + p_gtktype(&meth->ret_type), p_prf("%d", g_slist_length(meth->params)), p_for(meth->params, p_param_marshtype, p_nil), p_signal_id(meth)); @@ -377,7 +408,7 @@ void output_object_init(PRoot* out, ObjectDef* o){ p_type(&o->self_type[FALSE]), p_c_ident(DEF(o)->type->name)), NULL, - p_fmt("\t\t~ (~);\n", + p_fmt("\t~ (~);\n", p_varname(DEF(o)->type, p_str("init_real")), p_c_ident(DEF(o)->type->name))); } @@ -396,7 +427,7 @@ void output_class_init(PRoot* out, ObjectDef* o){ p_fmt("\tGtkObjectClass* obklass = \n" "\t\t(GtkObjectClass*) klass;\n" "~" - "\t\t~ (klass);\n", + "\t~ (klass);\n", p_for(o->members, p_member_class_init, o), p_varname(DEF(o)->type, p_str("class_init_real")))); } diff --git a/tools/gcg/parser.y b/tools/gcg/parser.y index 396b3aaa54..267241872c 100644 --- a/tools/gcg/parser.y +++ b/tools/gcg/parser.y @@ -29,7 +29,7 @@ static GSList* imports_list; EmitDef emit_def; gboolean bool; Type type; - GtkFundamentalType fund_type; + TypeKind fund_type; }; %token T_MODULE @@ -135,21 +135,21 @@ decllist: /* empty */ | decllist decl; decl: simpledecl ;/* | classdecl | opaquedecl | protclassdecl;*/ fundtype: T_INT { - $$ = GTK_TYPE_INT; + $$ = TYPE_INT; } | T_DOUBLE { - $$ = GTK_TYPE_DOUBLE; + $$ = TYPE_DOUBLE; } | T_BOXED { - $$ = GTK_TYPE_BOXED; + $$ = TYPE_FOREIGN; } | T_CLASS { - $$ = GTK_TYPE_OBJECT; + $$ = TYPE_OBJECT; } | T_ENUM { - $$ = GTK_TYPE_ENUM; + $$ = TYPE_ENUM; } | T_FLAGS { - $$ = GTK_TYPE_FLAGS; + $$ = TYPE_FLAGS; } simpledecl: fundtype primtype T_END { - g_assert($2->kind==GTK_TYPE_INVALID); + g_assert($2->kind==TYPE_INVALID); $2->kind = $1; }; @@ -273,7 +273,7 @@ def: classdef | enumdef | flagsdef; enumdef: T_ENUM primtype T_OPEN_B idlist T_CLOSE_B docstring T_END { EnumDef* d=g_new(EnumDef, 1); - g_assert($2->kind==GTK_TYPE_ENUM); + g_assert($2->kind==TYPE_ENUM); d->alternatives = $4; $$=DEF(d); $$->type=$2; @@ -282,7 +282,7 @@ enumdef: T_ENUM primtype T_OPEN_B idlist T_CLOSE_B docstring T_END { flagsdef: T_FLAGS primtype T_OPEN_B idlist T_CLOSE_B docstring T_END { FlagsDef* d=g_new(FlagsDef, 1); - g_assert($2->kind==GTK_TYPE_ENUM); + g_assert($2->kind==TYPE_ENUM); d->flags = $4; $$=DEF(d); $$->type=$2; @@ -296,8 +296,8 @@ parent: /* empty */{ } classdef: T_CLASS primtype parent docstring T_OPEN_B { - g_assert($2->kind==GTK_TYPE_OBJECT); - g_assert(!$3 || $3->kind==GTK_TYPE_OBJECT); + g_assert($2->kind==TYPE_OBJECT); + g_assert(!$3 || $3->kind==TYPE_OBJECT); current_class=g_new(ObjectDef, 1); } classbody T_CLOSE_B T_END { Type t={FALSE, 1, TRUE, $2}; @@ -305,7 +305,7 @@ classdef: T_CLASS primtype parent docstring T_OPEN_B { t.is_const=TRUE; current_class->self_type[1]=t; current_class->parent = $3; - current_class->members = $7; + current_class->members = g_slist_reverse($7); $$=DEF(current_class); current_class=NULL; $$->type = $2;