f5086f14eeb73aa222a1cfb69ef0853e933c27e6
1 /*******************************************************************************
2 Copyright (c) 2016, Michael Wallner <mike@php.net>.
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
8 * Redistributions of source code must retain the above copyright notice,
9 this list of conditions and the following disclaimer.
10 * Redistributions in binary form must reproduce the above copyright
11 notice, this list of conditions and the following disclaimer in the
12 documentation and/or other materials provided with the distribution.
14 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
18 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
20 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
21 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
22 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 *******************************************************************************/
26 #include "php_psi_stdinc.h"
31 #include "php_psi_posix.h"
33 struct psi_decl_type
*psi_decl_type_init(token_t type
, zend_string
*name
)
35 struct psi_decl_type
*t
= pecalloc(1, sizeof(*t
), 1);
37 t
->name
= zend_string_copy(name
);
41 void psi_decl_type_free(struct psi_decl_type
**type_ptr
)
44 struct psi_decl_type
*type
= *type_ptr
;
47 psi_token_free(&type
->token
);
48 if (type
->type
== PSI_T_FUNCTION
) {
49 psi_decl_free(&type
->real
.func
);
51 zend_string_release(type
->name
);
56 struct psi_decl_type
*psi_decl_type_copy(struct psi_decl_type
*src
)
58 struct psi_decl_type
*dst
= pecalloc(1, sizeof(*dst
), 1);
60 dst
->type
= src
->type
;
62 dst
->name
= zend_string_copy(src
->name
);
65 dst
->token
= psi_token_copy(src
->token
);
70 struct psi_plist
*psi_decl_type_get_args(struct psi_decl_type
*dtyp
,
71 struct psi_decl_type
**real_typ_ptr
)
73 struct psi_decl_type
*var_typ
;
75 var_typ
= psi_decl_type_get_real(dtyp
);
77 *real_typ_ptr
= var_typ
;
80 switch (var_typ
->type
) {
82 return var_typ
->real
.strct
->args
;
84 return var_typ
->real
.unn
->args
;
90 size_t psi_decl_type_get_size(struct psi_decl_type
*dtyp
,
91 struct psi_decl_type
**real_typ_ptr
)
93 struct psi_decl_type
*var_typ
;
95 var_typ
= psi_decl_type_get_real(dtyp
);
97 *real_typ_ptr
= var_typ
;
100 switch (var_typ
->type
) {
102 return var_typ
->real
.strct
? var_typ
->real
.strct
->size
: 0;
104 return var_typ
->real
.unn
? var_typ
->real
.unn
->size
: 0;
106 return psi_t_size(var_typ
->type
);
110 bool psi_decl_type_get_alias(struct psi_decl_type
*type
, struct psi_plist
*defs
)
113 struct psi_std_type
*stdtyp
;
114 struct psi_decl_arg
*def
;
116 if (type
->real
.def
) {
120 while (psi_plist_get(defs
, i
++, &def
)) {
121 if (zend_string_equals(def
->var
->name
, type
->name
)) {
122 type
->real
.def
= def
;
127 for (stdtyp
= &psi_std_types
[0]; stdtyp
->type_tag
; ++stdtyp
) {
128 if (!strcmp(type
->name
->val
, stdtyp
->alias
?: stdtyp
->type_name
)) {
129 type
->type
= stdtyp
->type_tag
;
137 bool psi_decl_type_get_struct(struct psi_decl_type
*type
, struct psi_plist
*structs
)
140 struct psi_decl_struct
*s
;
142 if (type
->real
.strct
) {
146 while (psi_plist_get(structs
, i
++, &s
)) {
147 if (zend_string_equals(s
->name
, type
->name
)) {
148 type
->real
.strct
= s
;
156 bool psi_decl_type_get_union(struct psi_decl_type
*type
, struct psi_plist
*unions
)
159 struct psi_decl_union
*u
;
161 if (type
->real
.unn
) {
165 while (psi_plist_get(unions
, i
++, &u
)) {
166 if (zend_string_equals(u
->name
, type
->name
)) {
175 bool psi_decl_type_get_enum(struct psi_decl_type
*type
, struct psi_plist
*enums
)
178 struct psi_decl_enum
*e
;
180 if (type
->real
.enm
) {
184 while (psi_plist_get(enums
, i
++, &e
)) {
185 if (zend_string_equals(e
->name
, type
->name
)) {
194 bool psi_decl_type_get_decl(struct psi_decl_type
*type
, struct psi_plist
*decls
)
197 struct psi_decl
*decl
;
199 if (type
->real
.func
) {
203 while (psi_plist_get(decls
, i
++, &decl
)) {
204 if (zend_string_equals(decl
->func
->var
->name
, type
->name
)) {
205 type
->real
.func
= decl
;
213 bool psi_decl_type_validate(struct psi_data
*data
, struct psi_decl_type
*type
,
214 struct psi_decl_arg
*def
, struct psi_validate_scope
*scope
)
216 if (psi_decl_type_is_weak(type
)) {
217 if (!psi_decl_type_get_alias(type
, data
->types
)) {
218 if (!psi_validate_scope_has_type(scope
, type
->name
)) {
221 type
->real
.def
= psi_validate_scope_get_type(scope
, type
->name
);
223 if (type
->real
.def
) {
224 if (!psi_decl_type_validate(data
, type
->real
.def
->type
,
225 type
->real
.def
, scope
)) {
229 def
->var
->pointer_level
+= type
->real
.def
->var
->pointer_level
;
235 switch (type
->type
) {
237 if (!psi_decl_type_get_struct(type
, data
->structs
)) {
238 if (psi_validate_scope_has_struct(scope
, type
->name
)) {
239 type
->real
.strct
= psi_validate_scope_get_struct(scope
, type
->name
);
240 } else if (def
&& def
->var
->pointer_level
) {
243 data
->error(data
, type
->token
, PSI_WARNING
,
244 "Unknown struct '%s'", type
->name
->val
);
248 if (!psi_decl_struct_validate(data
, type
->real
.strct
, scope
)) {
253 if (!psi_decl_type_get_union(type
, data
->unions
)) {
254 if (psi_validate_scope_has_union(scope
, type
->name
)) {
255 type
->real
.unn
= psi_validate_scope_get_union(scope
, type
->name
);
256 } else if (def
&& def
->var
->pointer_level
) {
259 data
->error(data
, type
->token
, PSI_WARNING
,
260 "Unknown union '%s'", type
->name
->val
);
264 if (!psi_decl_union_validate(data
, type
->real
.unn
, scope
)) {
269 if (!psi_decl_type_get_enum(type
, data
->enums
)) {
270 data
->error(data
, type
->token
, PSI_WARNING
,
271 "Unknown enum '%s'", type
->name
->val
);
276 if (!psi_decl_type_get_decl(type
, data
->decls
)) {
277 data
->error(data
, type
->token
, PSI_WARNING
,
278 "Unknown decl '%s'", type
->name
->val
);
281 if (!psi_decl_validate_nodl(data
, type
->real
.func
, scope
)) {
292 void psi_decl_type_dump_args_with_layout(struct psi_dump
*dump
, struct psi_plist
*args
,
297 PSI_DUMP(dump
, " {\n");
299 struct psi_decl_arg
*sarg
;
302 while (psi_plist_get(args
, i
++, &sarg
)) {
303 PSI_DUMP(dump
, "%s", psi_t_indent(level
));
304 psi_decl_arg_dump(dump
, sarg
, level
);
306 if (sarg
->layout
->bfw
) {
307 PSI_DUMP(dump
, ":%zu", sarg
->layout
->bfw
->len
);
309 PSI_DUMP(dump
, "::(%zu, %zu);\n", sarg
->layout
->pos
,
312 PSI_DUMP(dump
, ";\n");
317 PSI_DUMP(dump
, "%s", psi_t_indent(level
));
321 void psi_decl_type_dump(struct psi_dump
*dump
, struct psi_decl_type
*t
, unsigned level
)
325 PSI_DUMP(dump
, "%s *", t
->name
->val
);
329 if (psi_decl_type_is_anon(t
->name
, "enum")) {
330 psi_decl_enum_dump(dump
, t
->real
.enm
, level
);
333 PSI_DUMP(dump
, "enum ");
337 PSI_DUMP(dump
, "struct ");
338 if (psi_decl_type_is_anon(t
->name
, "struct")) {
339 PSI_DUMP(dump
, "/*::(%zu, %zu)*/", t
->real
.strct
->align
, t
->real
.strct
->size
);
340 psi_decl_type_dump_args_with_layout(dump
, t
->real
.strct
->args
, level
);
346 PSI_DUMP(dump
, "union ");
347 if (psi_decl_type_is_anon(t
->name
, "union")) {
348 PSI_DUMP(dump
, "/*::(%zu, %zu)*/", t
->real
.unn
->align
, t
->real
.unn
->size
);
349 psi_decl_type_dump_args_with_layout(dump
, t
->real
.unn
->args
, level
);
355 psi_decl_type_dump(dump
, t
->real
.func
->func
->type
, level
);
362 PSI_DUMP(dump
, "%s", t
->name
->val
);
365 int psi_decl_type_is_weak(struct psi_decl_type
*type
)
367 switch (type
->type
) {
381 struct psi_decl_type
*psi_decl_type_get_real(struct psi_decl_type
*type
)
383 while (psi_decl_type_is_weak(type
) && type
->real
.def
) {
384 type
= type
->real
.def
->type
;
389 size_t psi_decl_type_get_align(struct psi_decl_type
*t
)
391 struct psi_decl_type
*real
= psi_decl_type_get_real(t
);
394 switch (real
->type
) {
396 align
= psi_decl_struct_get_align(real
->real
.strct
);
399 align
= psi_decl_union_get_align(real
->real
.unn
);
403 align
= psi_t_alignment(real
->type
);
410 size_t psi_decl_type_get_args_align(struct psi_plist
*args
)
412 size_t i
= 0, maxalign
= 0;
413 struct psi_decl_arg
*darg
;
415 while (psi_plist_get(args
, i
++, &darg
)) {
416 size_t align
= psi_decl_arg_get_align(darg
);
418 if (align
> maxalign
) {