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;
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;
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;
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, ", ...");
}
}
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;
}
}
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;
}
}
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;
}
}
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;
}
}
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;
}
}
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;
/* 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;
} 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:
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:
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;
}
}
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;
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++);
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;
}
}
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);
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);
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;
}
}
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();
}
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) {
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);
free(type->token);
}
if (type->type == PSI_T_FUNCTION) {
- free_decl(type->func);
+ free_decl(type->real.func);
}
free(type->name);
free(type);
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;
P->line = 1;
P->error = error;
P->flags = flags;
-
P->proc = PSI_ParserProcAlloc(malloc);
+
if (flags & PSI_PARSER_DEBUG) {
PSI_ParserProcTrace(stderr, "PSI> ");
}
}
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). {
%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_;
}
%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_;
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;
);
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(
);
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*}
);
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 */
%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. {
$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);
}
}
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
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===