made the real decl_type a union
authorMichael Wallner <mike@php.net>
Tue, 16 Feb 2016 13:19:06 +0000 (14:19 +0100)
committerMichael Wallner <mike@php.net>
Tue, 16 Feb 2016 13:19:06 +0000 (14:19 +0100)
src/context_dump.c
src/context_validate.c
src/engine.c
src/libffi.c
src/libjit.c
src/marshal.c
src/parser.h
src/parser.re
src/parser_proc.y
tests/parser/validate001.phpt

index 2c6e8c0..f138671 100644 (file)
@@ -24,7 +24,7 @@ static inline void dump_decl_type(int fd, decl_type *t, unsigned level) {
        case PSI_T_STRUCT:
                dprintf(fd, "struct ");
                if (!strncmp(t->name, "struct@", sizeof("struct"))) {
-                       dump_struct_args(fd, t->strct->args, level);
+                       dump_struct_args(fd, t->real.strct->args, level);
                        return;
                }
                break;
@@ -32,7 +32,7 @@ static inline void dump_decl_type(int fd, decl_type *t, unsigned level) {
        case PSI_T_ENUM:
                dprintf(fd, "enum ");
                if (!strncmp(t->name, "enum@", sizeof("enum"))) {
-                       dump_enum_items(fd, t->enm->items, level);
+                       dump_enum_items(fd, t->real.enm->items, level);
                        return;
                }
                break;
@@ -40,7 +40,7 @@ static inline void dump_decl_type(int fd, decl_type *t, unsigned level) {
        case PSI_T_UNION:
                dprintf(fd, "union ");
                if (!strncmp(t->name, "union@", sizeof("union"))) {
-                       dump_struct_args(fd, t->unn->args, level);
+                       dump_struct_args(fd, t->real.unn->args, level);
                        return;
                }
                break;
@@ -57,20 +57,20 @@ static inline void dump_decl_var(int fd, decl_var *v) {
 
 static inline void dump_decl_arg(int fd, decl_arg *a, unsigned level) {
        if (a->type->type == PSI_T_FUNCTION) {
-               dump_decl_type(fd, a->type->func->func->type, level);
+               dump_decl_type(fd, a->type->real.func->func->type, level);
                dprintf(fd, " (");
                dump_decl_var(fd, a->var);
                dprintf(fd, ")(");
-               if (a->type->func->args) {
+               if (a->type->real.func->args) {
                        size_t j;
 
-                       for (j = 0; j < a->type->func->args->count; ++j) {
+                       for (j = 0; j < a->type->real.func->args->count; ++j) {
                                if (j) {
                                        dprintf(fd, ", ");
                                }
-                               dump_decl_arg(fd, a->type->func->args->args[j], level+1);
+                               dump_decl_arg(fd, a->type->real.func->args->args[j], level+1);
                        }
-                       if (a->type->func->args->varargs) {
+                       if (a->type->real.func->args->varargs) {
                                dprintf(fd, ", ...");
                        }
                }
index a5d3604..5ad642f 100644 (file)
@@ -46,14 +46,14 @@ static inline int locate_decl_type_alias(decl_typedefs *defs, decl_type *type) {
        size_t i;
        struct psi_std_type *stdtyp;
 
-       if (type->real) {
+       if (type->real.def) {
                return 1;
        }
        if (defs) for (i = 0; i < defs->count; ++i) {
                decl_arg *def = defs->list[i];
 
                if (def->type->type != type->type && !strcmp(def->var->name, type->name)) {
-                       type->real = def->type;
+                       type->real.def = def;
                        return 1;
                }
        }
@@ -70,12 +70,12 @@ static inline int locate_decl_type_alias(decl_typedefs *defs, decl_type *type) {
 static inline int locate_decl_type_struct(decl_structs *structs, decl_type *type) {
        size_t i;
 
-       if (type->strct) {
+       if (type->real.strct) {
                return 1;
        }
        if (structs) for (i = 0; i < structs->count; ++i) {
                if (!strcmp(structs->list[i]->name, type->name)) {
-                       type->strct = structs->list[i];
+                       type->real.strct = structs->list[i];
                        return 1;
                }
        }
@@ -85,12 +85,12 @@ static inline int locate_decl_type_struct(decl_structs *structs, decl_type *type
 static inline int locate_decl_type_union(decl_unions *unions, decl_type *type) {
        size_t i;
 
-       if (type->unn) {
+       if (type->real.unn) {
                return 1;
        }
        if (unions) for (i = 0; i < unions->count; ++i) {
                if (!strcmp(unions->list[i]->name, type->name)) {
-                       type->unn = unions->list[i];
+                       type->real.unn = unions->list[i];
                        return 1;
                }
        }
@@ -100,12 +100,12 @@ static inline int locate_decl_type_union(decl_unions *unions, decl_type *type) {
 static inline int locate_decl_type_enum(decl_enums *enums, decl_type *type) {
        size_t i;
 
-       if (type->enm) {
+       if (type->real.enm) {
                return 1;
        }
        if (enums) for (i = 0; i < enums->count; ++i) {
                if (!strcmp(enums->list[i]->name, type->name)) {
-                       type->enm = enums->list[i];
+                       type->real.enm = enums->list[i];
                        return 1;
                }
        }
@@ -115,12 +115,12 @@ static inline int locate_decl_type_enum(decl_enums *enums, decl_type *type) {
 static inline int locate_decl_type_decl(decls *decls, decl_type *type) {
        size_t i;
 
-       if (type->func) {
+       if (type->real.func) {
                return 1;
        }
        if (decls) for (i = 0; i < decls->count; ++i) {
                if (!strcmp(decls->list[i]->func->var->name, type->name)) {
-                       type->func = decls->list[i];
+                       type->real.func = decls->list[i];
                        return 1;
                }
        }
@@ -133,19 +133,17 @@ static inline int validate_decl_union(PSI_Data *data, decl_union *u);
 static inline int validate_decl_enum(PSI_Data *data, decl_enum *e);
 
 static inline int validate_decl_type(PSI_Data *data, decl_type *type) {
-       switch (type->type) {
-       case PSI_T_CHAR:
-       case PSI_T_SHORT:
-       case PSI_T_INT:
-       case PSI_T_LONG:
-       case PSI_T_NAME:
+       if (weak_decl_type(type)) {
                if (!locate_decl_type_alias(data->defs, type)) {
                        return 0;
                }
-               if (type->real) {
-                       return validate_decl_type(data, type->real);
+               if (type->real.def) {
+                       return validate_decl_type(data, type->real.def->type);
                }
                return 1;
+       }
+
+       switch (type->type) {
        case PSI_T_STRUCT:
                if (!locate_decl_type_struct(data->structs, type)) {
                        return 0;
@@ -252,26 +250,35 @@ static inline int validate_decl_struct_darg(PSI_Data *data, decl_arg *darg, void
        /* pre-validate any structs/unions/enums */
        switch (real->type) {
        case PSI_T_STRUCT:
-               if (current && current == real->strct) {
+               if (current && current == real->real.strct) {
                        return 1;
                }
-               if (!validate_decl_struct(data, real->strct)) {
+               if (!locate_decl_type_struct(data->structs, real)) {
+                       return 0;
+               }
+               if (!validate_decl_struct(data, real->real.strct)) {
                        return 0;
                }
                break;
        case PSI_T_UNION:
-               if (current && current == real->unn) {
+               if (current && current == real->real.unn) {
                        return 1;
                }
-               if (!validate_decl_union(data, real->unn)) {
+               if (!locate_decl_type_union(data->unions, real)) {
+                       return 0;
+               }
+               if (!validate_decl_union(data, real->real.unn)) {
                        return 0;
                }
                break;
        case PSI_T_ENUM:
-               if (current && current == real->enm) {
+               if (current && current == real->real.enm) {
                        return 1;
                }
-               if (!validate_decl_enum(data, real->enm)) {
+               if (!locate_decl_type_enum(data->enums, real)) {
+                       return 0;
+               }
+               if (!validate_decl_enum(data, real->real.enm)) {
                        return 0;
                }
                break;
@@ -295,10 +302,10 @@ static inline size_t sizeof_decl_arg(decl_arg *darg) {
        } else {
                switch (real->type) {
                case PSI_T_UNION:
-                       size = real->unn->size;
+                       size = real->real.unn->size;
                        break;
                case PSI_T_STRUCT:
-                       size = real->strct->size;
+                       size = real->real.strct->size;
                        break;
                case PSI_T_ENUM:
                default:
@@ -352,10 +359,10 @@ static inline size_t alignof_decl_type(decl_type *t) {
 
        switch (real->type) {
        case PSI_T_STRUCT:
-               align = alignof_decl_struct(real->strct);
+               align = alignof_decl_struct(real->real.strct);
                break;
        case PSI_T_UNION:
-               align = alignof_decl_union(real->unn);
+               align = alignof_decl_union(real->real.unn);
                break;
        case PSI_T_ENUM:
        default:
@@ -820,10 +827,10 @@ static inline int validate_set_value_ex(PSI_Data *data, set_value *set, decl_arg
                if (!set->outer.set || set->outer.set->inner->vals != set->inner->vals) {
                        for (i = 0; i < set->inner->count; ++i) {
                                decl_var *sub_var = set->inner->vals[i]->vars->vars[0];
-                               decl_arg *sub_ref = locate_struct_member(ref_type->strct, sub_var);
+                               decl_arg *sub_ref = locate_struct_member(ref_type->real.strct, sub_var);
 
                                if (sub_ref) {
-                                       if (!validate_set_value_ex(data, set->inner->vals[i], sub_ref, ref_type->strct->args)) {
+                                       if (!validate_set_value_ex(data, set->inner->vals[i], sub_ref, ref_type->real.strct->args)) {
                                                return 0;
                                        }
                                }
@@ -968,7 +975,7 @@ static inline int validate_let_callback(PSI_Data *data, decl_var *cb_var, let_ca
                data->error(data, cb_var->token, PSI_WARNING, "Not a function: %s", cb_var->name);
                return 0;
        }
-       cb_func = cb_type->func;
+       cb_func = cb_type->real.func;
        for (i = 0; i < cb->args->count; ++i) {
                if (!validate_set_value(data, cb->args->vals[i], cb_func->args->count, cb_func->args->args, 0)) {
                        return 0;
index aa4feeb..a4bf0d7 100644 (file)
@@ -339,7 +339,7 @@ static inline void psi_clean_array_struct(let_stmt *let, decl_arg *darg) {
                decl_type *type = real_decl_type(darg->type);
 
                if (type->type == PSI_T_STRUCT) {
-                       void **ptr = (void **) ((char *) darg->mem + type->strct->size);
+                       void **ptr = (void **) ((char *) darg->mem + type->real.strct->size);
 
                        while (*ptr) {
                                efree(*ptr++);
@@ -427,7 +427,7 @@ static inline void psi_do_args(impl *impl) {
 
                switch (real->type) {
                case PSI_T_STRUCT:
-                       impl->decl->func->ptr = psi_array_to_struct(real->strct, NULL);
+                       impl->decl->func->ptr = psi_array_to_struct(real->real.strct, NULL);
                        break;
                }
        }
index 19afda0..627c97f 100644 (file)
@@ -271,21 +271,21 @@ static inline ffi_type *psi_ffi_decl_type(decl_type *type) {
 
        switch (real->type) {
        case PSI_T_STRUCT:
-               if (!real->strct->engine.type) {
+               if (!real->real.strct->engine.type) {
                        ffi_type *strct = calloc(1, sizeof(ffi_type));
 
                        strct->type = FFI_TYPE_STRUCT;
                        strct->size = 0;
-                       strct->elements = psi_ffi_struct_type_elements(real->strct);
+                       strct->elements = psi_ffi_struct_type_elements(real->real.strct);
 
-                       real->strct->engine.type = strct;
-                       real->strct->engine.dtor = psi_ffi_struct_type_dtor;
+                       real->real.strct->engine.type = strct;
+                       real->real.strct->engine.dtor = psi_ffi_struct_type_dtor;
                }
 
-               return real->strct->engine.type;
+               return real->real.strct->engine.type;
 
        case PSI_T_UNION:
-               return psi_ffi_decl_arg_type(real->unn->args->args[0]);
+               return psi_ffi_decl_arg_type(real->real.unn->args->args[0]);
 
        default:
                return psi_ffi_token_type(real->type);
index feb6e3d..62540cc 100644 (file)
@@ -147,21 +147,21 @@ static inline jit_type_t psi_jit_decl_type(decl_type *type) {
 
        switch (real->type) {
        case PSI_T_STRUCT:
-               if (!real->strct->engine.type) {
+               if (!real->real.strct->engine.type) {
                        unsigned count;
                        jit_type_t strct, *fields = NULL;
 
-                       count = psi_jit_struct_type_elements(real->strct, &fields);
+                       count = psi_jit_struct_type_elements(real->real.strct, &fields);
                        strct = jit_type_create_struct(fields, count, 0);
 
-                       real->strct->engine.type = strct;
-                       real->strct->engine.dtor = psi_jit_struct_type_dtor;
+                       real->real.strct->engine.type = strct;
+                       real->real.strct->engine.dtor = psi_jit_struct_type_dtor;
                }
 
-               return real->strct->engine.type;
+               return real->real.strct->engine.type;
 
        case PSI_T_UNION:
-               return psi_jit_decl_arg_type(real->unn->args->args[0]);
+               return psi_jit_decl_arg_type(real->real.unn->args->args[0]);
 
        default:
                return psi_jit_token_type(real->type);
index 2ec3329..ce5cc24 100644 (file)
@@ -334,7 +334,7 @@ void psi_from_zval_ex(impl_val **ptr, decl_arg *spec, token_t cast, zval *zv, vo
                val->ival = zval_get_long(zv);
                break;
        case PSI_T_STRUCT:
-               *tmp = *ptr = psi_array_to_struct(real->strct, HASH_OF(zv));
+               *tmp = *ptr = psi_array_to_struct(real->real.strct, HASH_OF(zv));
                break;
        }
 }
@@ -501,7 +501,7 @@ impl_val *psi_let_arrval(impl_val *tmp, decl_type *type, impl_arg *iarg, void **
 
        switch (real->type) {
        case PSI_T_STRUCT:
-               *to_free = tmp = psi_array_to_struct(real->strct, arr);
+               *to_free = tmp = psi_array_to_struct(real->real.strct, arr);
                break;
        EMPTY_SWITCH_DEFAULT_CASE();
        }
index c9e9f75..105e974 100644 (file)
@@ -66,11 +66,13 @@ typedef struct decl_type {
        PSI_Token *token;
        char *name;
        token_t type;
-       struct decl_type *real;
-       struct decl_struct *strct;
-       struct decl_union *unn;
-       struct decl_enum *enm;
-       struct decl *func;
+       union {
+               struct decl_arg *def;
+               struct decl_struct *strct;
+               struct decl_union *unn;
+               struct decl_enum *enm;
+               struct decl *func;
+       } real;
 } decl_type;
 
 static inline decl_type *init_decl_type(token_t type, const char *name) {
@@ -80,11 +82,17 @@ static inline decl_type *init_decl_type(token_t type, const char *name) {
        return t;
 }
 
-static inline decl_type *real_decl_type(decl_type *type) {
-       while (type->real) {
-               type = type->real;
+static inline int weak_decl_type(decl_type *type) {
+       switch (type->type) {
+       case PSI_T_CHAR:
+       case PSI_T_SHORT:
+       case PSI_T_INT:
+       case PSI_T_LONG:
+       case PSI_T_NAME:
+               return type->type;
+       default:
+               return 0;
        }
-       return type;
 }
 
 static inline void free_decl(struct decl *decl);
@@ -93,7 +101,7 @@ static inline void free_decl_type(decl_type *type) {
                free(type->token);
        }
        if (type->type == PSI_T_FUNCTION) {
-               free_decl(type->func);
+               free_decl(type->real.func);
        }
        free(type->name);
        free(type);
@@ -185,6 +193,13 @@ static inline void free_decl_arg(decl_arg *arg) {
        free(arg);
 }
 
+static inline decl_type *real_decl_type(decl_type *type) {
+       while (weak_decl_type(type)) {
+               type = type->real.def->type;
+       }
+       return type;
+}
+
 typedef struct decl_typedefs {
        size_t count;
        decl_arg **list;
index 61c328d..10279ed 100644 (file)
@@ -37,8 +37,8 @@ PSI_Parser *PSI_ParserInit(PSI_Parser *P, const char *filename, psi_error_cb err
        P->line = 1;
        P->error = error;
        P->flags = flags;
-
        P->proc = PSI_ParserProcAlloc(malloc);
+
        if (flags & PSI_PARSER_DEBUG) {
                PSI_ParserProcTrace(stderr, "PSI> ");
        }
index 8ec585d..b46053a 100644 (file)
@@ -57,11 +57,22 @@ block ::= impl(impl). {
 }
 block ::= decl_typedef(def). {
        P->defs = add_decl_typedef(P->defs, def);
-       if (def->type->strct) {
-               P->structs = add_decl_struct(P->structs, def->type->strct);
-       }
-       if (def->type->enm) {
-               P->enums = add_decl_enum(P->enums, def->type->enm);
+       switch (def->type->type) {
+               case PSI_T_STRUCT:
+                       if (def->type->real.strct) {
+                               P->structs = add_decl_struct(P->structs, def->type->real.strct);
+                       }
+                       break;
+               case PSI_T_UNION:
+                       if (def->type->real.unn) {
+                               P->unions = add_decl_union(P->unions, def->type->real.unn);
+                       }
+                       break;
+               case PSI_T_ENUM:
+                       if (def->type->real.enm) {
+                               P->enums = add_decl_enum(P->enums, def->type->real.enm);
+                       }
+                       break;
        }
 }
 block ::= constant(constant). {
@@ -208,16 +219,16 @@ constant(constant) ::= CONST const_type(type) NSNAME(T) EQUALS impl_def_val(val)
 
 %type decl_typedef {decl_arg*}
 %destructor decl_typedef {
-       free_decl_arg($$);
-       if ($$->type->strct) {
-               free_decl_struct($$->type->strct);
-       }
-       if ($$->type->enm) {
-               free_decl_enum($$->type->enm);
+       free_decl_arg($$);/*
+       if ($$->type->real.strct) {
+               free_decl_struct($$->type->real.strct);
        }
-       if ($$->type->func) {
-               free_decl($$->type->func);
+       if ($$->type->real.enm) {
+               free_decl_enum($$->type->real.enm);
        }
+       if ($$->type->real.func) {
+               free_decl($$->type->real.func);
+       }*/
 }
 decl_typedef(def) ::= TYPEDEF(T) decl_typedef_body(def_) EOS. {
        def = def_;
@@ -225,57 +236,57 @@ decl_typedef(def) ::= TYPEDEF(T) decl_typedef_body(def_) EOS. {
 }
 %type decl_typedef_body_ex {decl_arg*}
 %destructor decl_typedef_body_ex {
-       free_decl_arg($$);
-       if ($$->type->strct) {
-               free_decl_struct($$->type->strct);
-       }
-       if ($$->type->enm) {
-               free_decl_enum($$->type->enm);
+       free_decl_arg($$);/*
+       if ($$->type->real.strct) {
+               free_decl_struct($$->type->real.strct);
        }
-       if ($$->type->unn) {
-               free_decl_union($$->type->unn);
+       if ($$->type->real.enm) {
+               free_decl_enum($$->type->real.enm);
        }
-       if ($$->type->func) {
-               free_decl($$->type->func);
+       if ($$->type->real.unn) {
+               free_decl_union($$->type->real.unn);
        }
+       if ($$->type->real.func) {
+               free_decl($$->type->real.func);
+       }*/
 }
 decl_typedef_body_ex(def) ::= struct_name(N) align_and_size(as) decl_struct_args_block(args) decl_var(var). {
        def = init_decl_arg(init_decl_type(PSI_T_STRUCT, N->text), var);
        def->type->token = PSI_TokenCopy(N);
-       def->type->strct = init_decl_struct(N->text, args);
-       def->type->strct->token = N;
-       def->type->strct->align = as.a;
-       def->type->strct->size = as.s;
+       def->type->real.strct = init_decl_struct(N->text, args);
+       def->type->real.strct->token = N;
+       def->type->real.strct->align = as.a;
+       def->type->real.strct->size = as.s;
 }
 decl_typedef_body_ex(def) ::= union_name(N) align_and_size(as) decl_struct_args_block(args) decl_var(var). {
        def = init_decl_arg(init_decl_type(PSI_T_UNION, N->text), var);
        def->type->token = PSI_TokenCopy(N);
-       def->type->unn = init_decl_union(N->text, args);
-       def->type->unn->token = N;
-       def->type->unn->align = as.a;
-       def->type->unn->size = as.s;
+       def->type->real.unn = init_decl_union(N->text, args);
+       def->type->real.unn->token = N;
+       def->type->real.unn->align = as.a;
+       def->type->real.unn->size = as.s;
 }
 decl_typedef_body_ex(def) ::= decl_enum(e) NAME(ALIAS). {
        def = init_decl_arg(init_decl_type(PSI_T_ENUM, e->name), init_decl_var(ALIAS->text, 0, 0));
        def->var->token = ALIAS;
        def->type->token = PSI_TokenCopy(e->token);
-       def->type->enm = e;
+       def->type->real.enm = e;
 }
 %type decl_typedef_body {decl_arg*}
 %destructor decl_typedef_body {
-       free_decl_arg($$);
-       if ($$->type->strct) {
-               free_decl_struct($$->type->strct);
-       }
-       if ($$->type->enm) {
-               free_decl_enum($$->type->enm);
+       free_decl_arg($$);/*
+       if ($$->type->real.strct) {
+               free_decl_struct($$->type->real.strct);
        }
-       if ($$->type->unn) {
-               free_decl_union($$->type->unn);
+       if ($$->type->real.enm) {
+               free_decl_enum($$->type->real.enm);
        }
-       if ($$->type->func) {
-               free_decl($$->type->func);
+       if ($$->type->real.unn) {
+               free_decl_union($$->type->real.unn);
        }
+       if ($$->type->real.func) {
+               free_decl($$->type->real.func);
+       }*/
 }
 decl_typedef_body(def) ::= decl_typedef_body_ex(def_). {
        def = def_;
@@ -288,7 +299,7 @@ decl_typedef_body_fn_args(args) ::= LPAREN decl_args(args_) RPAREN. {
 decl_typedef_body(def) ::= decl_func(func_) decl_typedef_body_fn_args(args). {
        def = init_decl_arg(init_decl_type(PSI_T_FUNCTION, func_->var->name), copy_decl_var(func_->var));
        def->type->token = PSI_TokenCopy(func_->token);
-       def->type->func = init_decl(init_decl_abi("default"), func_, args);
+       def->type->real.func = init_decl(init_decl_abi("default"), func_, args);
 }
 decl_typedef_body(def) ::= decl_arg(arg). {
        def = arg;
@@ -330,7 +341,7 @@ decl_typedef_body(def) ::= VOID(T) indirection(decl_i) LPAREN indirection(type_i
        );
        def->var->pointer_level = type_i;
        def->type->token = PSI_TokenCopy(func_->token);
-       def->type->func = init_decl(init_decl_abi("default"), func_, args);
+       def->type->real.func = init_decl(init_decl_abi("default"), func_, args);
 }
 decl_typedef_body(def) ::= CONST VOID(T) pointers(decl_i) LPAREN indirection(type_i) NAME(N) RPAREN decl_typedef_body_fn_args(args). {
        decl_arg *func_ = init_decl_arg(
@@ -347,7 +358,7 @@ decl_typedef_body(def) ::= CONST VOID(T) pointers(decl_i) LPAREN indirection(typ
        );
        def->var->pointer_level = type_i;
        def->type->token = PSI_TokenCopy(func_->token);
-       def->type->func = init_decl(init_decl_abi("default"), func_, args);
+       def->type->real.func = init_decl(init_decl_abi("default"), func_, args);
 }
 
 %type decl_abi {decl_abi*}
@@ -397,7 +408,7 @@ decl_typedef_body(def) ::= const_decl_type(type_) indirection(decl_i) LPAREN ind
        );
        def->var->pointer_level = type_i;
        def->type->token = PSI_TokenCopy(func_->token);
-       def->type->func = init_decl(init_decl_abi("default"), func_, args);
+       def->type->real.func = init_decl(init_decl_abi("default"), func_, args);
 }
 
 /* void pointers need a specific rule */
@@ -445,23 +456,35 @@ struct_args(args) ::= struct_args(args_) struct_arg(arg). {
 %type struct_arg {decl_arg*}
 %destructor struct_arg {
        free_decl_arg($$);
-       if ($$->type->strct) {
-               free_decl_struct($$->type->strct);
+       /*
+       if ($$->type->real.strct) {
+               free_decl_struct($$->type->real.strct);
        }
-       if ($$->type->enm) {
-               free_decl_enum($$->type->enm);
-       }
-       if ($$->type->func) {
-               free_decl($$->type->func);
+       if ($$->type->real.enm) {
+               free_decl_enum($$->type->real.enm);
        }
+       if ($$->type->real.func) {
+               free_decl($$->type->real.func);
+       }*/
 }
 struct_arg(arg_) ::= decl_typedef_body_ex(def) EOS. {
        arg_ = def;
-       if (def->type->strct) {
-               P->structs = add_decl_struct(P->structs, def->type->strct);
-       }
-       if (def->type->enm) {
-               P->enums = add_decl_enum(P->enums, def->type->enm);
+       switch (def->type->type) {
+       case PSI_T_STRUCT:
+               if (def->type->real.strct) {
+                       P->structs = add_decl_struct(P->structs, def->type->real.strct);
+               }
+               break;
+       case PSI_T_UNION:
+               if (def->type->real.unn) {
+                       P->unions = add_decl_union(P->unions, def->type->real.unn);
+               }
+               break;
+       case PSI_T_ENUM:
+               if (def->type->real.enm) {
+                       P->enums = add_decl_enum(P->enums, def->type->real.enm);
+               }
+               break;
        }
 }
 struct_arg(arg) ::= decl_arg(arg_) struct_layout(layout_) EOS. {
index f9869a8..b9a9a61 100644 (file)
@@ -11,7 +11,8 @@ function validate($check, $psi) {
        $file = __DIR__."/001.psi";
        file_put_contents($file, $psi);
        if ($check !== psi_validate($file)) {
-               echo "Assertion failed!\n";
+               printf("Assertion failed!\nExpected: %s\n\n%s\n\n",
+                               $check ? "true" : "false", $psi);
        }
 }
 
@@ -21,9 +22,9 @@ validate(false, "typedef long int;");
 validate(true, "typedef long foo;");
 validate(false, "typedef struct foo bar;");
 validate(true, "typedef struct {int a;} foo;");
-validate(false, "struct a; \n typedef struct a a_t;");
-validate(true, "struct a::(8,8); \n typedef struct a a_t;");
-validate(true, "typedef struct a a_t; \n struct a::(8,8);");
+validate(false, "struct a; \ntypedef struct a a_t;");
+validate(true, "struct a::(8,8); \ntypedef struct a a_t;");
+validate(true, "typedef struct a a_t; \nstruct a::(8,8);");
 
 validate(true,
 <<<PSI
@@ -72,8 +73,8 @@ validate(true, "typedef int (foo)(int bar);");
 validate(true, "typedef int (*foo)(int bar);");
 validate(true, "typedef int *(*foo)(int bar);");
 validate(false, "typedef int *(*foo)(int *(*bar)(int baz));");
-validate(true, "typedef int *(*bar)(int baz); \n typedef int *(*foo)(bar bar);");
-validate(false, "typedef int bar(int baz); \n typedef int *(*foo)(bar bar);");
+validate(true, "typedef int *(*bar)(int baz); \ntypedef int *(*foo)(bar bar);");
+validate(false, "typedef int bar(int baz); \ntypedef int *(*foo)(bar bar);");
 
 ?>
 ===DONE===