AC_CHECK_ALIGNOF(long double)
PSI_STDTYPE(char, int)
+ AC_CHECK_ALIGNOF(char)
PSI_STDTYPE(signed char, int)
PSI_STDTYPE(unsigned char, uint)
PSI_STDTYPE(short, int)
+ AC_CHECK_ALIGNOF(short)
PSI_STDTYPE(short int, int)
PSI_STDTYPE(signed short, int)
PSI_STDTYPE(signed short int, int)
PSI_STDTYPE(unsigned short, uint)
PSI_STDTYPE(unsigned short int, uint)
PSI_STDTYPE(int, int)
+ AC_CHECK_ALIGNOF(int)
PSI_STDTYPE(signed int, int)
PSI_STDTYPE(signed, int)
PSI_STDTYPE(unsigned int, uint)
PSI_STDTYPE(unsigned, uint)
PSI_STDTYPE(long, int)
+ AC_CHECK_ALIGNOF(long)
PSI_STDTYPE(long int, int)
PSI_STDTYPE(signed long int, int)
PSI_STDTYPE(unsigned long, uint)
PSI_STDTYPE(unsigned long int, uint)
PSI_STDTYPE(long long, int)
+ AC_CHECK_ALIGNOF(long long)
PSI_STDTYPE(signed long long, int)
PSI_STDTYPE(signed long long int, int)
PSI_STDTYPE(unsigned long long, uint)
for (predef_type = &psi_predef_types[0]; predef_type->type_tag; ++predef_type) {
decl_type *type = init_decl_type(predef_type->type_tag, predef_type->type_name);
- decl_typedef *def = init_decl_typedef(predef_type->alias, type);
+ decl_var *var = init_decl_var(predef_type->alias, 0, 0); /* FIXME: indirection */
+ decl_arg *def = init_decl_arg(type, var);
T.defs = add_decl_typedef(T.defs, def);
}
}
}
-static inline void dump_typedef(int fd, decl_typedef *tdef) {
+static inline void dump_typedef(int fd, decl_arg *tdef) {
dprintf(fd, "typedef ");
+ dump_decl_arg(fd, tdef);
+ /*
dump_decl_type(fd, tdef->type);
dprintf(fd, " %s%s;", tdef->type->type == PSI_T_POINTER ? "*":"",
tdef->alias);
+ */
}
static inline void dump_typedefs(int fd, decl_typedefs *defs) {
size_t i;
for (i = 0; i < defs->count; ++i) {
- decl_typedef *tdef = defs->list[i];
+ decl_arg *tdef = defs->list[i];
dump_typedef(fd, tdef);
dprintf(fd, "\n");
if (type->real) {
return 1;
}
- for (i = 0; i < defs->count; ++i) {
- decl_typedef *def = defs->list[i];
+ if (defs) for (i = 0; i < defs->count; ++i) {
+ decl_arg *def = defs->list[i];
- if (def->type->type != type->type && !strcmp(def->alias, type->name)) {
+ if (def->type->type != type->type && !strcmp(def->var->name, type->name)) {
type->real = def->type;
return 1;
}
if (type->strct) {
return 1;
}
- for (i = 0; i < structs->count; ++i) {
+ if (structs) for (i = 0; i < structs->count; ++i) {
if (!strcmp(structs->list[i]->name, type->name)) {
type->strct = structs->list[i];
return 1;
if (type->enm) {
return 1;
}
- for (i = 0; i < enums->count; ++i) {
+ if (enums) for (i = 0; i < enums->count; ++i) {
if (!strcmp(enums->list[i]->name, type->name)) {
type->enm = enums->list[i];
return 1;
case PSI_T_INT:
case PSI_T_LONG:
case PSI_T_NAME:
- if (!data->defs || !locate_decl_type_alias(data->defs, type)) {
+ if (!locate_decl_type_alias(data->defs, type)) {
return 0;
}
if (type->real) {
}
return 1;
case PSI_T_STRUCT:
- if (!data->structs || !locate_decl_type_struct(data->structs, type)) {
+ if (!locate_decl_type_struct(data->structs, type)) {
return 0;
}
break;
case PSI_T_ENUM:
- if (!data->enums || !locate_decl_type_enum(data->enums, type)) {
+ if (!locate_decl_type_enum(data->enums, type)) {
return 0;
}
}
return 1;
}
-static inline int validate_decl_typedef(PSI_Data *data, decl_typedef *def) {
+static inline int validate_decl_typedef(PSI_Data *data, decl_arg *def) {
if (!validate_decl_type(data, def->type)) {
data->error(def->token, PSI_WARNING,
"Type '%s' cannot be aliased to %s'%s'",
- def->type->name, def->type->type == PSI_T_STRUCT?"struct ":"",def->alias);
+ def->type->name, def->type->type == PSI_T_STRUCT?"struct ":"",
+ def->var->name);
return 0;
}
- /* FIXME: check def->alias */
return 1;
}
t = real_decl_type(darg->type)->type;
}
- size = psi_t_size(t) * (darg->var->array_size ?: 1);
+ switch (t) {
+ case PSI_T_STRUCT:
+ if (!validate_decl_struct(data, real_decl_type(darg->type)->strct)) {
+ return 0;
+ }
+ size = real_decl_type(darg->type)->strct->size;
+ break;
+ default:
+ size = psi_t_size(t) * (darg->var->array_size ?: 1);
+ break;
+ }
if (i) {
decl_arg *last = s->args->args[i-1];
return 1;
}
+
static inline int validate_impl(PSI_Data *data, impl *impl) {
if (!validate_impl_args(data, impl)) {
return 0;
{
PSI_Data *D;
void *dlopened = NULL;
- size_t count = C->count++;
+ size_t i, count = C->count++, check_round, check_count;
+ decl_typedefs *check_defs = P->defs;
+ decl_structs *check_structs = P->structs;
+ decl_enums *check_enums = P->enums;
C->data = realloc(C->data, C->count * sizeof(*C->data));
D = PSI_DataExchange(&C->data[count], PSI_DATA(P));
-
+/*
if (D->defs) {
- size_t i;
-
for (i = 0; i < D->defs->count; ++i) {
if (validate_decl_typedef(PSI_DATA(C), D->defs->list[i])) {
C->defs = add_decl_typedef(C->defs, D->defs->list[i]);
+ } else {
+ check_defs = add_decl_typedef(check_defs, D->defs->list[i]);
}
}
}
if (D->structs) {
- size_t i;
-
for (i = 0; i < D->structs->count; ++i) {
if (validate_decl_struct(PSI_DATA(C), D->structs->list[i])) {
C->structs = add_decl_struct(C->structs, D->structs->list[i]);
+ } else {
+ check_structs = add_decl_struct(check_structs, D->structs->list[i]);
}
}
}
if (D->enums) {
- size_t i;
-
for (i = 0; i < D->enums->count; ++i) {
if (validate_decl_enum(PSI_DATA(C), D->enums->list[i])) {
C->enums = add_decl_enum(C->enums, D->enums->list[i]);
+ } else {
+ check_enums = add_decl_enum(check_enums, D->enums->list[i]);
}
}
}
- if (D->consts) {
- size_t i;
+*/
+#define REVALIDATE(what) do { \
+ if (check_round && check_ ##what) { \
+ free(check_ ##what->list); \
+ free(check_ ##what); \
+ } \
+ check_ ##what = recheck_ ##what; \
+} while (0)
+#define CHECK_TOTAL (CHECK_COUNT(defs) + CHECK_COUNT(structs) + CHECK_COUNT(enums))
+#define CHECK_COUNT(of) (check_ ##of ? check_ ##of->count : 0)
+
+ for (check_round = 0, check_count = 0; CHECK_TOTAL && check_count != CHECK_TOTAL; ++check_round) {
+ decl_typedefs *recheck_defs = NULL;
+ decl_structs *recheck_structs = NULL;
+ decl_enums *recheck_enums = NULL;
+
+ check_count = CHECK_TOTAL;
+ fprintf(stderr, "### Validation round %zu with %zu checks\n", check_round, check_count);
+
+ for (i = 0; i < CHECK_COUNT(defs); ++i) {
+ if (validate_decl_typedef(PSI_DATA(C), check_defs->list[i])) {
+ C->defs = add_decl_typedef(C->defs, check_defs->list[i]);
+ } else {
+ recheck_defs = add_decl_typedef(recheck_defs, check_defs->list[i]);
+ }
+ }
+ for (i = 0; i < CHECK_COUNT(structs); ++i) {
+ if (validate_decl_struct(PSI_DATA(C), check_structs->list[i])) {
+ C->structs = add_decl_struct(C->structs, check_structs->list[i]);
+ } else {
+ recheck_structs = add_decl_struct(recheck_structs, check_structs->list[i]);
+ }
+ }
+ for (i = 0; i < CHECK_COUNT(enums); ++i) {
+ if (validate_decl_enum(PSI_DATA(C), check_enums->list[i])) {
+ C->enums = add_decl_enum(C->enums, check_enums->list[i]);
+ } else {
+ recheck_enums = add_decl_enum(recheck_enums, check_enums->list[i]);
+ }
+ }
+ REVALIDATE(defs);
+ REVALIDATE(structs);
+ REVALIDATE(enums);
+ }
+
+
+ if (D->consts) {
for (i = 0; i < D->consts->count; ++i) {
if (validate_constant(PSI_DATA(C), D->consts->list[i])) {
C->consts = add_constant(C->consts, D->consts->list[i]);
add_decl_lib(&C->psi.libs, dlopened);
if (D->decls) {
- size_t i;
-
for (i = 0; i < D->decls->count; ++i) {
if (validate_decl(PSI_DATA(C), dlopened, D->decls->list[i])) {
C->decls = add_decl(C->decls, D->decls->list[i]);
}
}
if (D->impls) {
- size_t i;
-
for (i = 0; i < D->impls->count; ++i) {
if (validate_impl(PSI_DATA(C), D->impls->list[i])) {
C->impls = add_impl(C->impls, D->impls->list[i]);
int errors = 0;
if (source->defs) for (i = 0; i < source->defs->count; ++i) {
- decl_typedef *def = source->defs->list[i];
+ decl_arg *def = source->defs->list[i];
if (validate_decl_typedef(source, def)) {
if (dest) {
case PSI_T_DOUBLE:
return ALIGNOF_DOUBLE;
case PSI_T_POINTER:
+ case PSI_T_FUNCTION:
+ case PSI_T_STRUCT:
return ALIGNOF_VOID_P;
+ case PSI_T_ENUM:
+ return ALIGNOF_INT;
EMPTY_SWITCH_DEFAULT_CASE();
}
return 0;
case PSI_T_DOUBLE:
return SIZEOF_DOUBLE;
case PSI_T_POINTER:
+ case PSI_T_FUNCTION:
return SIZEOF_VOID_P;
+ case PSI_T_ENUM:
+ return SIZEOF_INT;
EMPTY_SWITCH_DEFAULT_CASE();
}
return 0;
char buf[1];
} PSI_Token;
+static inline PSI_Token *PSI_TokenCopy(PSI_Token *src);
+
typedef union impl_val {
char cval;
int8_t i8;
return type;
}
+static inline void free_decl(struct decl *decl);
static inline void free_decl_type(decl_type *type) {
if (type->token) {
free(type->token);
}
+ if (type->type == PSI_T_FUNCTION) {
+ free_decl(type->func);
+ }
free(type->name);
free(type);
}
-typedef struct decl_typedef {
- PSI_Token *token;
- char *alias;
- decl_type *type;
-} decl_typedef;
-
-static inline decl_typedef *init_decl_typedef(const char *name, decl_type *type) {
- decl_typedef *t = calloc(1, sizeof(*t));
- t->alias = strdup(name);
- t->type = type;
- return t;
-}
-
-static inline void free_decl_typedef(decl_typedef *t) {
- if (t->token) {
- free(t->token);
- }
- free(t->alias);
- free_decl_type(t->type);
- free(t);
-}
-
-typedef struct decl_typedefs {
- size_t count;
- decl_typedef **list;
-} decl_typedefs;
-
-static inline decl_typedefs *add_decl_typedef(decl_typedefs *defs, decl_typedef *def) {
- if (!defs) {
- defs = calloc(1, sizeof(*defs));
- }
- defs->list = realloc(defs->list, ++defs->count * sizeof(*defs->list));
- defs->list[defs->count-1] = def;
- return defs;
-}
-
-static void free_decl_typedefs(decl_typedefs *defs) {
- size_t i;
-
- for (i = 0; i < defs->count; ++i) {
- free_decl_typedef(defs->list[i]);
- }
- free(defs->list);
- free(defs);
-}
-
typedef struct decl_var {
PSI_Token *token;
char *name;
return v;
}
+static inline decl_var *copy_decl_var(decl_var *src) {
+ decl_var *dest = calloc(1, sizeof(*dest));
+
+ memcpy(dest, src, sizeof(*dest));
+ dest->name = strdup(dest->name);
+ if (dest->token) {
+ dest->token = PSI_TokenCopy(dest->token);
+ }
+ return dest;
+}
+
static inline void free_decl_var(decl_var *var) {
if (var->token) {
free(var->token);
free(arg);
}
+typedef struct decl_typedefs {
+ size_t count;
+ decl_arg **list;
+} decl_typedefs;
+
+static inline decl_typedefs *add_decl_typedef(decl_typedefs *defs, decl_arg *def) {
+ if (!defs) {
+ defs = calloc(1, sizeof(*defs));
+ }
+ defs->list = realloc(defs->list, ++defs->count * sizeof(*defs->list));
+ defs->list[defs->count-1] = def;
+ return defs;
+}
+
+static void free_decl_typedefs(decl_typedefs *defs) {
+ size_t i;
+
+ for (i = 0; i < defs->count; ++i) {
+ free_decl_arg(defs->list[i]);
+ }
+ free(defs->list);
+ free(defs);
+}
+
typedef struct decl_vars {
decl_var **vars;
size_t count;
return exp;
}
-static inline PSI_Token *PSI_TokenCopy(PSI_Token *src);
static inline num_exp *copy_num_exp(num_exp *exp) {
decl_var *dvar;
num_exp *num = calloc(1, sizeof(*num));
return T;
}
+char *php_strtr(char *str, size_t len, char *str_from, char *str_to, size_t trlen);
static inline PSI_Token *PSI_TokenTranslit(PSI_Token *T, char *from, char *to) {
php_strtr(T->text, T->size, from, to, MIN(strlen(from), strlen(to)));
return T;
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);
+ }
}
block ::= constant(constant). {
P->consts = add_constant(P->consts, constant);
}
}
-
%type decl_enum {decl_enum *}
%destructor decl_enum {free_decl_enum($$);}
decl_enum(e) ::= enum_name(N) LBRACE decl_enum_items(list) RBRACE. {
free(T);
}
-%type decl_typedef {decl_typedef*}
-%destructor decl_typedef {free_decl_typedef($$);}
-decl_typedef(def) ::= TYPEDEF decl_typedef_body(def_) EOS. {
+%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);
+ }
+ if ($$->type->func) {
+ free_decl($$->type->func);
+ }
+}
+decl_typedef(def) ::= TYPEDEF(T) decl_typedef_body(def_) EOS. {
def = def_;
+ def->token = T;
}
-%type decl_typedef_body_ex {decl_typedef*}
-%destructor decl_typedef_body_ex {free_decl_typedef($$);}
-decl_typedef_body_ex(def) ::= struct_name(N) struct_size(size_) decl_struct_args_block(args) NAME(ALIAS). {
- def = init_decl_typedef(ALIAS->text, init_decl_type(PSI_T_STRUCT, N->text));
- def->token = ALIAS;
+%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);
+ }
+ if ($$->type->func) {
+ free_decl($$->type->func);
+ }
+}
+decl_typedef_body_ex(def) ::= struct_name(N) struct_size(size_) 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->size = size_;
}
decl_typedef_body_ex(def) ::= decl_enum(e) NAME(ALIAS). {
- def = init_decl_typedef(ALIAS->text, init_decl_type(PSI_T_ENUM, e->name));
+ 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->token = ALIAS;
def->type->enm = e;
}
-%type decl_typedef_body {decl_typedef*}
-%destructor decl_typedef_body {free_decl_typedef($$);}
+%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);
+ }
+ if ($$->type->func) {
+ free_decl($$->type->func);
+ }
+}
decl_typedef_body(def) ::= decl_typedef_body_ex(def_). {
def = def_;
}
-decl_typedef_body(def) ::= decl_type(type) NAME(ALIAS). {
- def = init_decl_typedef(ALIAS->text, type);
- def->token = ALIAS;
-}
-/* support opaque types */
-decl_typedef_body(def) ::= VOID(V) indirection(i) NAME(ALIAS). {
- def = init_decl_typedef(ALIAS->text, init_decl_type(i?PSI_T_POINTER:V->type, V->text));
- def->token = ALIAS;
- def->type->token = V;
+decl_typedef_body(def) ::= decl_func(func_) LPAREN decl_args(args) RPAREN. {
+ 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);
}
-decl_typedef_body(def) ::= decl_func(func) LPAREN decl_args(args) RPAREN. {
- def = init_decl_typedef(func->var->name, init_decl_type(PSI_T_FUNCTION, func->var->name));
- def->type->token = PSI_TokenCopy(func->token);
- def->type->func = init_decl(init_decl_abi("default"), func, args);
- def->token = PSI_TokenCopy(func->token);
+decl_typedef_body(def) ::= decl_arg(arg). {
+ def = arg;
}
%type decl {decl*}
init_decl_var(N->text, 0, 0)
);
func->type->token = T;
- //free(T);
free(N);
}
%type struct_arg {decl_arg*}
%destructor struct_arg {free_decl_arg($$);}
struct_arg(arg_) ::= decl_typedef_body_ex(def) EOS. {
- arg_ = init_decl_arg(def->type, init_decl_var(def->alias, 0, 0));
- arg_->var->arg = arg_;
- arg_->token = PSI_TokenCopy(def->type->token);
- arg_->var->token = def->token;
- free(def->alias);
- free(def);
+ arg_ = def;
}
struct_arg(arg) ::= decl_arg(arg_) struct_layout(layout_) EOS. {
arg_->layout = layout_;