X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-psi;a=blobdiff_plain;f=src%2Ftypes%2Fdecl_type.c;h=afab9e307cae40995b9bd14abb91e6336d0f6a1b;hp=4f494d69394a372067b9d108c0b51b90ff9b3c99;hb=848d77002c2c0451ccb76b9059cb352fabbdd8bc;hpb=9bcb1df0786a8193d65949c857baaba2f4296e84 diff --git a/src/types/decl_type.c b/src/types/decl_type.c index 4f494d6..afab9e3 100644 --- a/src/types/decl_type.c +++ b/src/types/decl_type.c @@ -25,9 +25,11 @@ #include "php_psi_stdinc.h" #include "token.h" -#include "php_psi_stdtypes.h" #include "data.h" +#define PSI_STD_TYPES +#include "php_psi_posix.h" + struct psi_decl_type *psi_decl_type_init(token_t type, const char *name) { struct psi_decl_type *t = calloc(1, sizeof(*t)); @@ -53,6 +55,20 @@ void psi_decl_type_free(struct psi_decl_type **type_ptr) } } +struct psi_decl_type *psi_decl_type_copy(struct psi_decl_type *src) +{ + struct psi_decl_type *dst = calloc(1, sizeof(*dst)); + + dst->type = src->type; + if (src->name) { + dst->name = strdup(src->name); + } + if (src->token) { + dst->token = psi_token_copy(src->token); + } + return dst; +} + struct psi_plist *psi_decl_type_get_args(struct psi_decl_type *dtyp, struct psi_decl_type **real_typ_ptr) { @@ -85,9 +101,9 @@ size_t psi_decl_type_get_size(struct psi_decl_type *dtyp, switch (var_typ->type) { case PSI_T_STRUCT: - return var_typ->real.strct->size; + return var_typ->real.strct ? var_typ->real.strct->size : 0; case PSI_T_UNION: - return var_typ->real.unn->size; + return var_typ->real.unn ? var_typ->real.unn->size : 0; default: return psi_t_size(var_typ->type); } @@ -102,7 +118,7 @@ bool psi_decl_type_get_alias(struct psi_decl_type *type, struct psi_plist *defs) if (type->real.def) { return true; } - if (defs) + if (defs) { while (psi_plist_get(defs, i++, &def)) { if (def->type->type != type->type && !strcmp(def->var->name, type->name)) { @@ -110,6 +126,7 @@ bool psi_decl_type_get_alias(struct psi_decl_type *type, struct psi_plist *defs) return true; } } + } for (stdtyp = &psi_std_types[0]; stdtyp->type_tag; ++stdtyp) { if (!strcmp(type->name, stdtyp->alias ?: stdtyp->type_name)) { type->type = stdtyp->type_tag; @@ -197,36 +214,57 @@ bool psi_decl_type_get_decl(struct psi_decl_type *type, struct psi_plist *decls) } bool psi_decl_type_validate(struct psi_data *data, struct psi_decl_type *type, - struct psi_decl_arg *def) + bool is_pointer, struct psi_validate_stack *type_stack) { if (psi_decl_type_is_weak(type)) { if (!psi_decl_type_get_alias(type, data->types)) { - return false; + if (!psi_validate_stack_has_type(type_stack, type->name)) { + return false; + } + type->real.def = psi_validate_stack_get_type(type_stack, type->name); } if (type->real.def) { return psi_decl_type_validate(data, type->real.def->type, - type->real.def); + is_pointer, type_stack); } return true; } switch (type->type) { case PSI_T_STRUCT: - if (!psi_decl_type_get_struct(type, data->structs) && !def) { - data->error(data, type->token, PSI_WARNING, - "Unknown struct '%s'", type->name); + if (!psi_decl_type_get_struct(type, data->structs)) { + if (psi_validate_stack_has_struct(type_stack, type->name)) { + type->real.strct = psi_validate_stack_get_struct(type_stack, type->name); + } else if (is_pointer) { + return true; + } else { + data->error(data, type->token, PSI_WARNING, + "Unknown struct '%s'", type->name); + return false; + } + } + if (!psi_decl_struct_validate(data, type->real.strct, type_stack)) { return false; } break; case PSI_T_UNION: - if (!psi_decl_type_get_union(type, data->unions) && !def) { - data->error(data, type->token, PSI_WARNING, - "Unknown union '%s'", type->name); + if (!psi_decl_type_get_union(type, data->unions)) { + if (psi_validate_stack_has_union(type_stack, type->name)) { + type->real.unn = psi_validate_stack_get_union(type_stack, type->name); + } else if (is_pointer) { + return true; + } else { + data->error(data, type->token, PSI_WARNING, + "Unknown union '%s'", type->name); + return false; + } + } + if (!psi_decl_union_validate(data, type->real.unn, type_stack)) { return false; } break; case PSI_T_ENUM: - if (!psi_decl_type_get_enum(type, data->enums) && !def) { + if (!psi_decl_type_get_enum(type, data->enums)) { data->error(data, type->token, PSI_WARNING, "Unknown enum '%s'", type->name); return false; @@ -238,11 +276,14 @@ bool psi_decl_type_validate(struct psi_data *data, struct psi_decl_type *type, "Unknown decl '%s'", type->name); return false; } - if (!psi_decl_validate_nodl(data, type->real.func)) { + if (!psi_decl_validate_nodl(data, type->real.func, type_stack)) { return false; } break; + default: + break; } + return true; } @@ -259,6 +300,9 @@ void psi_decl_type_dump_args_with_layout(int fd, struct psi_plist *args, while (psi_plist_get(args, i++, &sarg)) { dprintf(fd, "%s", psi_t_indent(level)); psi_decl_arg_dump(fd, sarg, level); + if (sarg->layout->bfw) { + dprintf(fd, ":%zu", sarg->layout->bfw->len); + } dprintf(fd, "::(%zu, %zu);\n", sarg->layout->pos, sarg->layout->len); } @@ -291,7 +335,7 @@ void psi_decl_type_dump(int fd, struct psi_decl_type *t, unsigned level) } } --level; - dprintf(fd, "%s} ", psi_t_indent(level)); + dprintf(fd, "%s\n} ", psi_t_indent(level)); return; } break; @@ -322,6 +366,8 @@ int psi_decl_type_is_weak(struct psi_decl_type *type) case PSI_T_SHORT: case PSI_T_INT: case PSI_T_LONG: + case PSI_T_UNSIGNED: + case PSI_T_SIGNED: case PSI_T_NAME: return type->type; default: