ReactOS 0.4.15-dev-7788-g1ad9096
typegen.c
Go to the documentation of this file.
1/*
2 * Format String Generator for IDL Compiler
3 *
4 * Copyright 2005-2006 Eric Kohl
5 * Copyright 2005-2006 Robert Shearman
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22#include "config.h"
23#include "wine/port.h"
24
25#include <stdio.h>
26#include <stdlib.h>
27#ifdef HAVE_UNISTD_H
28# include <unistd.h>
29#endif
30#include <string.h>
31#include <assert.h>
32#include <ctype.h>
33#include <limits.h>
34
35#include "widl.h"
36#include "utils.h"
37#include "parser.h"
38#include "header.h"
39#include "typetree.h"
40
41#include "typegen.h"
42#include "expr.h"
43
44/* round size up to multiple of alignment */
45#define ROUND_SIZE(size, alignment) (((size) + ((alignment) - 1)) & ~((alignment) - 1))
46/* value to add on to round size up to a multiple of alignment */
47#define ROUNDING(size, alignment) (((alignment) - 1) - (((size) + ((alignment) - 1)) & ((alignment) - 1)))
48
50static const var_t *current_func;
51static const type_t *current_iface;
52
55{
56 struct list entry;
57 const type_t *iface;
59 char *name;
60 unsigned int baseoff;
61 const expr_t *expr;
62};
63
65{
70};
71
72/* parameter flags in Oif mode */
73static const unsigned short MustSize = 0x0001;
74static const unsigned short MustFree = 0x0002;
75static const unsigned short IsPipe = 0x0004;
76static const unsigned short IsIn = 0x0008;
77static const unsigned short IsOut = 0x0010;
78static const unsigned short IsReturn = 0x0020;
79static const unsigned short IsBasetype = 0x0040;
80static const unsigned short IsByValue = 0x0080;
81static const unsigned short IsSimpleRef = 0x0100;
82/* static const unsigned short IsDontCallFreeInst = 0x0200; */
83/* static const unsigned short SaveForAsyncFinish = 0x0400; */
84
85static unsigned int field_memsize(const type_t *type, unsigned int *offset);
86static unsigned int fields_memsize(const var_list_t *fields, unsigned int *align);
87static unsigned int write_array_tfs(FILE *file, const attr_list_t *attrs, type_t *type,
88 const char *name, unsigned int *typestring_offset);
89static unsigned int write_struct_tfs(FILE *file, type_t *type, const char *name, unsigned int *tfsoff);
90static int write_embedded_types(FILE *file, const attr_list_t *attrs, type_t *type,
91 const char *name, int write_ptr, unsigned int *tfsoff);
93static unsigned int write_string_tfs(FILE *file, const attr_list_t *attrs,
95 const char *name, unsigned int *typestring_offset);
96static unsigned int get_required_buffer_size_type( const type_t *type, const char *name,
97 const attr_list_t *attrs, int toplevel_param,
98 unsigned int *alignment );
99static unsigned int get_function_buffer_size( const var_t *func, enum pass pass );
100
101static const char *string_of_type(unsigned char type)
102{
103 switch (type)
104 {
105 case FC_BYTE: return "FC_BYTE";
106 case FC_CHAR: return "FC_CHAR";
107 case FC_SMALL: return "FC_SMALL";
108 case FC_USMALL: return "FC_USMALL";
109 case FC_WCHAR: return "FC_WCHAR";
110 case FC_SHORT: return "FC_SHORT";
111 case FC_USHORT: return "FC_USHORT";
112 case FC_LONG: return "FC_LONG";
113 case FC_ULONG: return "FC_ULONG";
114 case FC_FLOAT: return "FC_FLOAT";
115 case FC_HYPER: return "FC_HYPER";
116 case FC_DOUBLE: return "FC_DOUBLE";
117 case FC_ENUM16: return "FC_ENUM16";
118 case FC_ENUM32: return "FC_ENUM32";
119 case FC_IGNORE: return "FC_IGNORE";
120 case FC_ERROR_STATUS_T: return "FC_ERROR_STATUS_T";
121 case FC_RP: return "FC_RP";
122 case FC_UP: return "FC_UP";
123 case FC_OP: return "FC_OP";
124 case FC_FP: return "FC_FP";
125 case FC_ENCAPSULATED_UNION: return "FC_ENCAPSULATED_UNION";
126 case FC_NON_ENCAPSULATED_UNION: return "FC_NON_ENCAPSULATED_UNION";
127 case FC_STRUCT: return "FC_STRUCT";
128 case FC_PSTRUCT: return "FC_PSTRUCT";
129 case FC_CSTRUCT: return "FC_CSTRUCT";
130 case FC_CPSTRUCT: return "FC_CPSTRUCT";
131 case FC_CVSTRUCT: return "FC_CVSTRUCT";
132 case FC_BOGUS_STRUCT: return "FC_BOGUS_STRUCT";
133 case FC_SMFARRAY: return "FC_SMFARRAY";
134 case FC_LGFARRAY: return "FC_LGFARRAY";
135 case FC_SMVARRAY: return "FC_SMVARRAY";
136 case FC_LGVARRAY: return "FC_LGVARRAY";
137 case FC_CARRAY: return "FC_CARRAY";
138 case FC_CVARRAY: return "FC_CVARRAY";
139 case FC_BOGUS_ARRAY: return "FC_BOGUS_ARRAY";
140 case FC_ALIGNM2: return "FC_ALIGNM2";
141 case FC_ALIGNM4: return "FC_ALIGNM4";
142 case FC_ALIGNM8: return "FC_ALIGNM8";
143 case FC_POINTER: return "FC_POINTER";
144 case FC_C_CSTRING: return "FC_C_CSTRING";
145 case FC_C_WSTRING: return "FC_C_WSTRING";
146 case FC_CSTRING: return "FC_CSTRING";
147 case FC_WSTRING: return "FC_WSTRING";
148 case FC_BYTE_COUNT_POINTER: return "FC_BYTE_COUNT_POINTER";
149 case FC_TRANSMIT_AS: return "FC_TRANSMIT_AS";
150 case FC_REPRESENT_AS: return "FC_REPRESENT_AS";
151 case FC_IP: return "FC_IP";
152 case FC_BIND_CONTEXT: return "FC_BIND_CONTEXT";
153 case FC_BIND_GENERIC: return "FC_BIND_GENERIC";
154 case FC_BIND_PRIMITIVE: return "FC_BIND_PRIMITIVE";
155 case FC_AUTO_HANDLE: return "FC_AUTO_HANDLE";
156 case FC_CALLBACK_HANDLE: return "FC_CALLBACK_HANDLE";
157 case FC_STRUCTPAD1: return "FC_STRUCTPAD1";
158 case FC_STRUCTPAD2: return "FC_STRUCTPAD2";
159 case FC_STRUCTPAD3: return "FC_STRUCTPAD3";
160 case FC_STRUCTPAD4: return "FC_STRUCTPAD4";
161 case FC_STRUCTPAD5: return "FC_STRUCTPAD5";
162 case FC_STRUCTPAD6: return "FC_STRUCTPAD6";
163 case FC_STRUCTPAD7: return "FC_STRUCTPAD7";
164 case FC_STRING_SIZED: return "FC_STRING_SIZED";
165 case FC_NO_REPEAT: return "FC_NO_REPEAT";
166 case FC_FIXED_REPEAT: return "FC_FIXED_REPEAT";
167 case FC_VARIABLE_REPEAT: return "FC_VARIABLE_REPEAT";
168 case FC_FIXED_OFFSET: return "FC_FIXED_OFFSET";
169 case FC_VARIABLE_OFFSET: return "FC_VARIABLE_OFFSET";
170 case FC_PP: return "FC_PP";
171 case FC_EMBEDDED_COMPLEX: return "FC_EMBEDDED_COMPLEX";
172 case FC_DEREFERENCE: return "FC_DEREFERENCE";
173 case FC_DIV_2: return "FC_DIV_2";
174 case FC_MULT_2: return "FC_MULT_2";
175 case FC_ADD_1: return "FC_ADD_1";
176 case FC_SUB_1: return "FC_SUB_1";
177 case FC_CALLBACK: return "FC_CALLBACK";
178 case FC_CONSTANT_IID: return "FC_CONSTANT_IID";
179 case FC_END: return "FC_END";
180 case FC_PAD: return "FC_PAD";
181 case FC_USER_MARSHAL: return "FC_USER_MARSHAL";
182 case FC_RANGE: return "FC_RANGE";
183 case FC_INT3264: return "FC_INT3264";
184 case FC_UINT3264: return "FC_UINT3264";
185 default:
186 error("string_of_type: unknown type 0x%02x\n", type);
187 return NULL;
188 }
189}
190
192{
193 const type_t *t = type;
194 for (;;)
195 {
196 if (is_attr(t->attrs, attr))
197 return get_attrp(t->attrs, attr);
198 else if (type_is_alias(t))
200 else return NULL;
201 }
202}
203
204unsigned char get_basic_fc(const type_t *type)
205{
207 switch (type_basic_get_type(type))
208 {
209 case TYPE_BASIC_INT8: return (sign <= 0 ? FC_SMALL : FC_USMALL);
210 case TYPE_BASIC_INT16: return (sign <= 0 ? FC_SHORT : FC_USHORT);
211 case TYPE_BASIC_INT32:
212 case TYPE_BASIC_LONG: return (sign <= 0 ? FC_LONG : FC_ULONG);
213 case TYPE_BASIC_INT64: return FC_HYPER;
214 case TYPE_BASIC_INT: return (sign <= 0 ? FC_LONG : FC_ULONG);
215 case TYPE_BASIC_INT3264: return (sign <= 0 ? FC_INT3264 : FC_UINT3264);
216 case TYPE_BASIC_BYTE: return FC_BYTE;
217 case TYPE_BASIC_CHAR: return FC_CHAR;
218 case TYPE_BASIC_WCHAR: return FC_WCHAR;
219 case TYPE_BASIC_HYPER: return FC_HYPER;
220 case TYPE_BASIC_FLOAT: return FC_FLOAT;
221 case TYPE_BASIC_DOUBLE: return FC_DOUBLE;
224 }
225 return 0;
226}
227
228static unsigned char get_basic_fc_signed(const type_t *type)
229{
230 switch (type_basic_get_type(type))
231 {
232 case TYPE_BASIC_INT8: return FC_SMALL;
233 case TYPE_BASIC_INT16: return FC_SHORT;
234 case TYPE_BASIC_INT32: return FC_LONG;
235 case TYPE_BASIC_INT64: return FC_HYPER;
236 case TYPE_BASIC_INT: return FC_LONG;
237 case TYPE_BASIC_INT3264: return FC_INT3264;
238 case TYPE_BASIC_LONG: return FC_LONG;
239 case TYPE_BASIC_BYTE: return FC_BYTE;
240 case TYPE_BASIC_CHAR: return FC_CHAR;
241 case TYPE_BASIC_WCHAR: return FC_WCHAR;
242 case TYPE_BASIC_HYPER: return FC_HYPER;
243 case TYPE_BASIC_FLOAT: return FC_FLOAT;
244 case TYPE_BASIC_DOUBLE: return FC_DOUBLE;
247 }
248 return 0;
249}
250
251static inline unsigned int clamp_align(unsigned int align)
252{
253 unsigned int packing = (pointer_size == 4) ? win32_packing : win64_packing;
254 if(align > packing) align = packing;
255 return align;
256}
257
258unsigned char get_pointer_fc(const type_t *type, const attr_list_t *attrs, int toplevel_param)
259{
260 const type_t *t;
261 int pointer_type;
262
264
265 pointer_type = get_attrv(attrs, ATTR_POINTERTYPE);
266 if (pointer_type)
267 return pointer_type;
268
270 {
271 pointer_type = get_attrv(t->attrs, ATTR_POINTERTYPE);
272 if (pointer_type)
273 return pointer_type;
274 }
275
276 if (toplevel_param)
277 return FC_RP;
278 else if (is_ptr(type))
280 else
282}
283
284static unsigned char get_pointer_fc_context( const type_t *type, const attr_list_t *attrs,
285 enum type_context context )
286{
287 int pointer_fc = get_pointer_fc(type, attrs, context == TYPE_CONTEXT_TOPLEVELPARAM);
288
289 if (pointer_fc == FC_UP && is_attr( attrs, ATTR_OUT ) &&
291 pointer_fc = FC_OP;
292
293 return pointer_fc;
294}
295
296static unsigned char get_enum_fc(const type_t *type)
297{
300 return FC_ENUM32;
301 else
302 return FC_ENUM16;
303}
304
305static type_t *get_user_type(const type_t *t, const char **pname)
306{
307 for (;;)
308 {
309 type_t *ut = get_attrp(t->attrs, ATTR_WIREMARSHAL);
310 if (ut)
311 {
312 if (pname)
313 *pname = t->name;
314 return ut;
315 }
316
317 if (type_is_alias(t))
319 else
320 return NULL;
321 }
322}
323
324static int is_user_type(const type_t *t)
325{
326 return get_user_type(t, NULL) != NULL;
327}
328
329enum typegen_type typegen_detect_type(const type_t *type, const attr_list_t *attrs, unsigned int flags)
330{
331 if (is_user_type(type))
332 return TGT_USER_TYPE;
333
335 return TGT_CTXT_HANDLE;
336
337 if (!(flags & TDT_IGNORE_STRINGS) && is_string_type(attrs, type))
338 return TGT_STRING;
339
340 switch (type_get_type(type))
341 {
342 case TYPE_BASIC:
343 if (!(flags & TDT_IGNORE_RANGES) &&
345 return TGT_RANGE;
346 return TGT_BASIC;
347 case TYPE_ENUM:
348 if (!(flags & TDT_IGNORE_RANGES) &&
350 return TGT_RANGE;
351 return TGT_ENUM;
352 case TYPE_POINTER:
355 return TGT_IFACE_POINTER;
358 else
359 return TGT_POINTER;
360 case TYPE_STRUCT:
361 return TGT_STRUCT;
363 case TYPE_UNION:
364 return TGT_UNION;
365 case TYPE_ARRAY:
366 return TGT_ARRAY;
367 case TYPE_FUNCTION:
368 case TYPE_COCLASS:
369 case TYPE_INTERFACE:
370 case TYPE_MODULE:
371 case TYPE_VOID:
372 case TYPE_ALIAS:
373 case TYPE_BITFIELD:
374 break;
375 }
376 return TGT_INVALID;
377}
378
379static int cant_be_null(const var_t *v)
380{
381 switch (typegen_detect_type(v->type, v->attrs, TDT_IGNORE_STRINGS))
382 {
383 case TGT_ARRAY:
384 if (!type_array_is_decl_as_ptr( v->type )) return 0;
385 /* fall through */
386 case TGT_POINTER:
387 return (get_pointer_fc(v->type, v->attrs, TRUE) == FC_RP);
389 return TRUE;
390 default:
391 return 0;
392 }
393
394}
395
396static int get_padding(const var_list_t *fields)
397{
398 unsigned short offset = 0;
399 unsigned int salign = 1;
400 const var_t *f;
401
402 if (!fields)
403 return 0;
404
406 {
407 type_t *ft = f->type;
408 unsigned int align = 0;
409 unsigned int size = type_memsize_and_alignment(ft, &align);
411 if (align > salign) salign = align;
413 offset += size;
414 }
415
416 return ROUNDING(offset, salign);
417}
418
419static unsigned int get_stack_size( const var_t *var, int *by_value )
420{
421 unsigned int stack_size;
422 int by_val;
423
424 switch (typegen_detect_type( var->type, var->attrs, TDT_ALL_TYPES ))
425 {
426 case TGT_BASIC:
427 case TGT_ENUM:
428 case TGT_RANGE:
429 case TGT_STRUCT:
430 case TGT_UNION:
431 case TGT_USER_TYPE:
432 stack_size = type_memsize( var->type );
433 by_val = (pointer_size < 8 || stack_size <= pointer_size); /* FIXME: should be platform-specific */
434 break;
435 default:
436 by_val = 0;
437 break;
438 }
439 if (!by_val) stack_size = pointer_size;
440 if (by_value) *by_value = by_val;
441 return ROUND_SIZE( stack_size, pointer_size );
442}
443
444static unsigned char get_contexthandle_flags( const type_t *iface, const attr_list_t *attrs,
445 const type_t *type )
446{
447 unsigned char flags = 0;
448
450
451 if (is_ptr(type) &&
452 !is_attr( type->attrs, ATTR_CONTEXTHANDLE ) &&
453 !is_attr( attrs, ATTR_CONTEXTHANDLE ))
454 flags |= 0x80;
455
456 if (is_attr(attrs, ATTR_IN))
457 {
458 flags |= 0x40;
460 }
461 if (is_attr(attrs, ATTR_OUT)) flags |= 0x20;
462
463 return flags;
464}
465
466static unsigned int get_rpc_flags( const attr_list_t *attrs )
467{
468 unsigned int flags = 0;
469
470 if (is_attr( attrs, ATTR_IDEMPOTENT )) flags |= 0x0001;
471 if (is_attr( attrs, ATTR_BROADCAST )) flags |= 0x0002;
472 if (is_attr( attrs, ATTR_MAYBE )) flags |= 0x0004;
473 if (is_attr( attrs, ATTR_MESSAGE )) flags |= 0x0100;
474 if (is_attr( attrs, ATTR_ASYNC )) flags |= 0x4000;
475 return flags;
476}
477
478unsigned char get_struct_fc(const type_t *type)
479{
480 int has_pointer = 0;
481 int has_conformance = 0;
482 int has_variance = 0;
483 var_t *field;
485
487
488 if (get_padding(fields))
489 return FC_BOGUS_STRUCT;
490
492 {
493 type_t *t = field->type;
495
497
499 {
500 if (is_string_type(field->attrs, field->type))
501 {
503 has_conformance = 1;
504 has_variance = 1;
505 continue;
506 }
507
509 return FC_BOGUS_STRUCT;
510
512 {
513 has_conformance = 1;
514 if (list_next(fields, &field->entry))
515 error_loc("field '%s' deriving from a conformant array must be the last field in the structure\n",
516 field->name);
517 }
519 has_variance = 1;
520
523 }
524
525 switch (typegen_type)
526 {
527 case TGT_USER_TYPE:
529 return FC_BOGUS_STRUCT;
530 case TGT_BASIC:
532 return FC_BOGUS_STRUCT;
533 break;
534 case TGT_ENUM:
535 if (get_enum_fc(t) == FC_ENUM16)
536 return FC_BOGUS_STRUCT;
537 break;
538 case TGT_POINTER:
539 case TGT_ARRAY:
540 if (get_pointer_fc(t, field->attrs, FALSE) == FC_RP || pointer_size != 4)
541 return FC_BOGUS_STRUCT;
542 has_pointer = 1;
543 break;
544 case TGT_UNION:
545 return FC_BOGUS_STRUCT;
546 case TGT_STRUCT:
547 {
548 unsigned char fc = get_struct_fc(t);
549 switch (fc)
550 {
551 case FC_STRUCT:
552 break;
553 case FC_CVSTRUCT:
554 has_conformance = 1;
555 has_variance = 1;
556 has_pointer = 1;
557 break;
558
559 case FC_CPSTRUCT:
560 has_conformance = 1;
561 if (list_next( fields, &field->entry ))
562 error_loc("field '%s' deriving from a conformant array must be the last field in the structure\n",
563 field->name);
564 has_pointer = 1;
565 break;
566
567 case FC_CSTRUCT:
568 has_conformance = 1;
569 if (list_next( fields, &field->entry ))
570 error_loc("field '%s' deriving from a conformant array must be the last field in the structure\n",
571 field->name);
572 break;
573
574 case FC_PSTRUCT:
575 has_pointer = 1;
576 break;
577
578 default:
579 error_loc("Unknown struct member %s with type (0x%02x)\n", field->name, fc);
580 /* fallthru - treat it as complex */
581
582 /* as soon as we see one of these these members, it's bogus... */
583 case FC_BOGUS_STRUCT:
584 return FC_BOGUS_STRUCT;
585 }
586 break;
587 }
588 case TGT_RANGE:
589 return FC_BOGUS_STRUCT;
590 case TGT_STRING:
591 /* shouldn't get here because of TDT_IGNORE_STRINGS above. fall through */
592 case TGT_INVALID:
593 case TGT_CTXT_HANDLE:
595 /* checking after parsing should mean that we don't get here. if we do,
596 * it's a checker bug */
597 assert(0);
598 }
599 }
600
601 if( has_variance )
602 {
603 if ( has_conformance )
604 return FC_CVSTRUCT;
605 else
606 return FC_BOGUS_STRUCT;
607 }
608 if( has_conformance && has_pointer )
609 return FC_CPSTRUCT;
610 if( has_conformance )
611 return FC_CSTRUCT;
612 if( has_pointer )
613 return FC_PSTRUCT;
614 return FC_STRUCT;
615}
616
617static unsigned char get_array_fc(const type_t *type)
618{
619 unsigned char fc;
620 const expr_t *size_is;
621 const type_t *elem_type;
622
623 elem_type = type_array_get_element(type);
625
626 if (!size_is)
627 {
628 unsigned int size = type_memsize(elem_type);
629 if (size * type_array_get_dim(type) > 0xffffuL)
630 fc = FC_LGFARRAY;
631 else
632 fc = FC_SMFARRAY;
633 }
634 else
635 fc = FC_CARRAY;
636
638 {
639 if (fc == FC_SMFARRAY)
640 fc = FC_SMVARRAY;
641 else if (fc == FC_LGFARRAY)
642 fc = FC_LGVARRAY;
643 else if (fc == FC_CARRAY)
644 fc = FC_CVARRAY;
645 }
646
647 switch (typegen_detect_type(elem_type, NULL, TDT_IGNORE_STRINGS))
648 {
649 case TGT_USER_TYPE:
651 break;
652 case TGT_BASIC:
653 if (type_basic_get_type(elem_type) == TYPE_BASIC_INT3264 &&
654 pointer_size != 4)
656 break;
657 case TGT_STRUCT:
658 switch (get_struct_fc(elem_type))
659 {
660 case FC_BOGUS_STRUCT:
662 break;
663 }
664 break;
665 case TGT_ENUM:
666 /* is 16-bit enum - if so, wire size differs from mem size and so
667 * the array cannot be block copied, which means the array is complex */
668 if (get_enum_fc(elem_type) == FC_ENUM16)
670 break;
671 case TGT_UNION:
674 break;
675 case TGT_POINTER:
676 /* ref pointers cannot just be block copied. unique pointers to
677 * interfaces need special treatment. either case means the array is
678 * complex */
679 if (get_pointer_fc(elem_type, NULL, FALSE) == FC_RP || pointer_size != 4)
681 break;
682 case TGT_RANGE:
684 break;
685 case TGT_CTXT_HANDLE:
687 case TGT_STRING:
688 case TGT_INVALID:
689 case TGT_ARRAY:
690 /* nothing to do for everything else */
691 break;
692 }
693
694 return fc;
695}
696
698{
699 return (type_get_type(type) == TYPE_STRUCT &&
701}
702
703static int type_has_pointers(const type_t *type)
704{
706 {
707 case TGT_USER_TYPE:
708 return FALSE;
709 case TGT_POINTER:
710 return TRUE;
711 case TGT_ARRAY:
713 case TGT_STRUCT:
714 {
716 const var_t *field;
718 {
720 return TRUE;
721 }
722 break;
723 }
724 case TGT_UNION:
725 {
727 const var_t *field;
730 {
732 return TRUE;
733 }
734 break;
735 }
736 case TGT_CTXT_HANDLE:
738 case TGT_STRING:
740 case TGT_BASIC:
741 case TGT_ENUM:
742 case TGT_RANGE:
743 case TGT_INVALID:
744 break;
745 }
746
747 return FALSE;
748}
749
750static int type_has_full_pointer(const type_t *type, const attr_list_t *attrs,
751 int toplevel_param)
752{
754 {
755 case TGT_USER_TYPE:
756 return FALSE;
757 case TGT_POINTER:
758 if (get_pointer_fc(type, attrs, toplevel_param) == FC_FP)
759 return TRUE;
760 else
761 return FALSE;
762 case TGT_ARRAY:
763 if (get_pointer_fc(type, attrs, toplevel_param) == FC_FP)
764 return TRUE;
765 else
767 case TGT_STRUCT:
768 {
770 const var_t *field;
772 {
774 return TRUE;
775 }
776 break;
777 }
778 case TGT_UNION:
779 {
781 const var_t *field;
784 {
786 return TRUE;
787 }
788 break;
789 }
790 case TGT_CTXT_HANDLE:
792 case TGT_STRING:
794 case TGT_BASIC:
795 case TGT_ENUM:
796 case TGT_RANGE:
797 case TGT_INVALID:
798 break;
799 }
800
801 return FALSE;
802}
803
804static unsigned short user_type_offset(const char *name)
805{
806 user_type_t *ut;
807 unsigned short off = 0;
809 {
810 if (strcmp(name, ut->name) == 0)
811 return off;
812 ++off;
813 }
814 error("user_type_offset: couldn't find type (%s)\n", name);
815 return 0;
816}
817
818static void update_tfsoff(type_t *type, unsigned int offset, FILE *file)
819{
820 type->typestring_offset = offset;
821 if (file) type->tfswrite = FALSE;
822}
823
824static void guard_rec(type_t *type)
825{
826 /* types that contain references to themselves (like a linked list),
827 need to be shielded from infinite recursion when writing embedded
828 types */
829 if (type->typestring_offset)
830 type->tfswrite = FALSE;
831 else
832 type->typestring_offset = 1;
833}
834
836{
838 {
839 case TGT_USER_TYPE:
840 case TGT_STRUCT:
841 case TGT_UNION:
842 case TGT_ARRAY:
844 return TRUE;
845 default:
846 return FALSE;
847 }
848}
849
850static const char *get_context_handle_type_name(const type_t *type)
851{
852 const type_t *t;
853 for (t = type;
854 is_ptr(t) || type_is_alias(t);
856 if (is_attr(t->attrs, ATTR_CONTEXTHANDLE))
857 return t->name;
858 assert(0);
859 return NULL;
860}
861
862#define WRITE_FCTYPE(file, fctype, typestring_offset) \
863 do { \
864 if (file) \
865 fprintf(file, "/* %2u */\n", typestring_offset); \
866 print_file((file), 2, "0x%02x,\t/* " #fctype " */\n", fctype); \
867 } \
868 while (0)
869
870static void print_file(FILE *file, int indent, const char *format, ...) __attribute__((format (printf, 3, 4)));
871static void print_file(FILE *file, int indent, const char *format, ...)
872{
873 va_list va;
874 va_start(va, format);
875 print(file, indent, format, va);
876 va_end(va);
877}
878
879void print(FILE *file, int indent, const char *format, va_list va)
880{
881 if (file)
882 {
883 if (format[0] != '\n')
884 while (0 < indent--)
885 fprintf(file, " ");
886 vfprintf(file, format, va);
887 }
888}
889
890
891static void write_var_init(FILE *file, int indent, const type_t *t, const char *n, const char *local_var_prefix)
892{
893 if (decl_indirect(t))
894 {
895 print_file(file, indent, "MIDL_memset(&%s%s, 0, sizeof(%s%s));\n",
896 local_var_prefix, n, local_var_prefix, n);
897 print_file(file, indent, "%s_p_%s = &%s%s;\n", local_var_prefix, n, local_var_prefix, n);
898 }
899 else if (is_ptr(t) || is_array(t))
900 print_file(file, indent, "%s%s = 0;\n", local_var_prefix, n);
901}
902
903void write_parameters_init(FILE *file, int indent, const var_t *func, const char *local_var_prefix)
904{
905 const var_t *var = type_function_get_retval(func->type);
906
907 if (!is_void(var->type))
908 write_var_init(file, indent, var->type, var->name, local_var_prefix);
909
910 if (!type_get_function_args(func->type))
911 return;
912
914 write_var_init(file, indent, var->type, var->name, local_var_prefix);
915
916 fprintf(file, "\n");
917}
918
919static void write_formatdesc(FILE *f, int indent, const char *str)
920{
921 print_file(f, indent, "typedef struct _MIDL_%s_FORMAT_STRING\n", str);
922 print_file(f, indent, "{\n");
923 print_file(f, indent + 1, "short Pad;\n");
924 print_file(f, indent + 1, "unsigned char Format[%s_FORMAT_STRING_SIZE];\n", str);
925 print_file(f, indent, "} MIDL_%s_FORMAT_STRING;\n", str);
926 print_file(f, indent, "\n");
927}
928
930{
932
933 print_file(f, indent, "#define TYPE_FORMAT_STRING_SIZE %d\n",
934 get_size_typeformatstring(stmts, pred));
935
936 print_file(f, indent, "#define PROC_FORMAT_STRING_SIZE %d\n",
937 get_size_procformatstring(stmts, pred));
938
939 fprintf(f, "\n");
940 write_formatdesc(f, indent, "TYPE");
941 write_formatdesc(f, indent, "PROC");
942 fprintf(f, "\n");
943 print_file(f, indent, "static const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString;\n");
944 print_file(f, indent, "static const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString;\n");
945 print_file(f, indent, "\n");
946}
947
949{
950 if (is_user_type(t))
951 return TRUE;
952 return (type_get_type(t) != TYPE_BASIC &&
956}
957
958static unsigned char get_parameter_fc( const var_t *var, int is_return, unsigned short *flags,
959 unsigned int *stack_size, unsigned int *typestring_offset )
960{
961 unsigned int alignment, server_size = 0, buffer_size = 0;
962 unsigned char fc = 0;
963 int is_byval;
964 int is_in = is_attr(var->attrs, ATTR_IN);
965 int is_out = is_attr(var->attrs, ATTR_OUT);
966
967 if (is_return) is_out = TRUE;
968 else if (!is_in && !is_out) is_in = TRUE;
969
970 *flags = 0;
971 *stack_size = get_stack_size( var, &is_byval );
972 *typestring_offset = var->typestring_offset;
973
974 if (is_in) *flags |= IsIn;
975 if (is_out) *flags |= IsOut;
976 if (is_return) *flags |= IsReturn;
977
978 if (!is_string_type( var->attrs, var->type ))
979 buffer_size = get_required_buffer_size_type( var->type, NULL, var->attrs, TRUE, &alignment );
980
981 switch (typegen_detect_type( var->type, var->attrs, TDT_ALL_TYPES ))
982 {
983 case TGT_BASIC:
984 *flags |= IsBasetype;
985 fc = get_basic_fc_signed( var->type );
986 if (fc == FC_BIND_PRIMITIVE)
987 {
988 buffer_size = 4; /* actually 0 but avoids setting MustSize */
989 fc = FC_LONG;
990 }
991 break;
992 case TGT_ENUM:
993 *flags |= IsBasetype;
994 fc = get_enum_fc( var->type );
995 break;
996 case TGT_RANGE:
997 *flags |= IsByValue;
998 break;
999 case TGT_STRUCT:
1000 case TGT_UNION:
1001 case TGT_USER_TYPE:
1002 *flags |= MustFree | (is_byval ? IsByValue : IsSimpleRef);
1003 break;
1004 case TGT_IFACE_POINTER:
1005 *flags |= MustFree;
1006 break;
1007 case TGT_ARRAY:
1008 *flags |= MustFree;
1009 if (type_array_is_decl_as_ptr(var->type) && var->type->details.array.ptr_tfsoff &&
1010 get_pointer_fc( var->type, var->attrs, !is_return ) == FC_RP)
1011 {
1012 *typestring_offset = var->type->typestring_offset;
1013 *flags |= IsSimpleRef;
1014 }
1015 break;
1016 case TGT_STRING:
1017 *flags |= MustFree;
1018 if (is_declptr( var->type ) && get_pointer_fc( var->type, var->attrs, !is_return ) == FC_RP)
1019 {
1020 /* skip over pointer description straight to string description */
1021 if (is_conformant_array( var->type )) *typestring_offset += 4;
1022 else *typestring_offset += 2;
1023 *flags |= IsSimpleRef;
1024 }
1025 break;
1027 *flags |= IsSimpleRef;
1028 *typestring_offset += 4;
1029 /* fall through */
1030 case TGT_CTXT_HANDLE:
1031 buffer_size = 20;
1032 break;
1033 case TGT_POINTER:
1034 if (get_pointer_fc( var->type, var->attrs, !is_return ) == FC_RP)
1035 {
1036 const type_t *ref = type_pointer_get_ref( var->type );
1037
1038 if (!is_string_type( var->attrs, ref ))
1040
1042 {
1043 case TGT_BASIC:
1045 fc = get_basic_fc( ref );
1046 if (!is_in && is_out) server_size = pointer_size;
1047 break;
1048 case TGT_ENUM:
1049 if ((fc = get_enum_fc( ref )) == FC_ENUM32)
1050 {
1052 if (!is_in && is_out) server_size = pointer_size;
1053 }
1054 else
1055 {
1056 server_size = pointer_size;
1057 }
1058 break;
1059 case TGT_UNION:
1060 case TGT_USER_TYPE:
1061 case TGT_RANGE:
1062 case TGT_ARRAY:
1064 *typestring_offset = ref->typestring_offset;
1065 if (!is_in && is_out) server_size = type_memsize( ref );
1066 break;
1067 case TGT_STRING:
1068 case TGT_POINTER:
1069 case TGT_CTXT_HANDLE:
1071 *flags |= MustFree;
1072 server_size = pointer_size;
1073 break;
1074 case TGT_IFACE_POINTER:
1075 *flags |= MustFree;
1076 if (is_in && is_out) server_size = pointer_size;
1077 break;
1078 case TGT_STRUCT:
1080 *typestring_offset = ref->typestring_offset;
1081 switch (get_struct_fc(ref))
1082 {
1083 case FC_STRUCT:
1084 case FC_PSTRUCT:
1085 case FC_BOGUS_STRUCT:
1086 if (!is_in && is_out) server_size = type_memsize( ref );
1087 break;
1088 default:
1089 break;
1090 }
1091 break;
1092 case TGT_INVALID:
1093 assert(0);
1094 }
1095 }
1096 else /* not ref pointer */
1097 {
1098 *flags |= MustFree;
1099 }
1100 break;
1101 case TGT_INVALID:
1102 assert(0);
1103 }
1104
1105 if (!buffer_size) *flags |= MustSize;
1106
1107 if (server_size)
1108 {
1109 server_size = (server_size + 7) / 8;
1110 if (server_size < 8) *flags |= server_size << 13;
1111 }
1112 return fc;
1113}
1114
1115static unsigned char get_func_oi2_flags( const var_t *func )
1116{
1117 const var_t *var;
1119 var_t *retval = type_function_get_retval( func->type );
1120 unsigned char oi2_flags = 0x40; /* HasExtensions */
1121 unsigned short flags;
1122 unsigned int stack_size, typestring_offset;
1123
1124 if (args) LIST_FOR_EACH_ENTRY( var, args, const var_t, entry )
1125 {
1126 get_parameter_fc( var, 0, &flags, &stack_size, &typestring_offset );
1127 if (flags & MustSize)
1128 {
1129 if (flags & IsIn) oi2_flags |= 0x02; /* ClientMustSize */
1130 if (flags & IsOut) oi2_flags |= 0x01; /* ServerMustSize */
1131 }
1132 }
1133
1134 if (!is_void( retval->type ))
1135 {
1136 oi2_flags |= 0x04; /* HasRet */
1137 get_parameter_fc( retval, 1, &flags, &stack_size, &typestring_offset );
1138 if (flags & MustSize) oi2_flags |= 0x01; /* ServerMustSize */
1139 }
1140 return oi2_flags;
1141}
1142
1143static unsigned int write_new_procformatstring_type(FILE *file, int indent, const var_t *var,
1144 int is_return, unsigned int *stack_offset)
1145{
1146 char buffer[128];
1147 unsigned int stack_size, typestring_offset;
1148 unsigned short flags;
1149 unsigned char fc = get_parameter_fc( var, is_return, &flags, &stack_size, &typestring_offset );
1150
1151 strcpy( buffer, "/* flags:" );
1152 if (flags & MustSize) strcat( buffer, " must size," );
1153 if (flags & MustFree) strcat( buffer, " must free," );
1154 if (flags & IsPipe) strcat( buffer, " pipe," );
1155 if (flags & IsIn) strcat( buffer, " in," );
1156 if (flags & IsOut) strcat( buffer, " out," );
1157 if (flags & IsReturn) strcat( buffer, " return," );
1158 if (flags & IsBasetype) strcat( buffer, " base type," );
1159 if (flags & IsByValue) strcat( buffer, " by value," );
1160 if (flags & IsSimpleRef) strcat( buffer, " simple ref," );
1161 if (flags >> 13) sprintf( buffer + strlen(buffer), " srv size=%u,", (flags >> 13) * 8 );
1162 strcpy( buffer + strlen( buffer ) - 1, " */" );
1163 print_file( file, indent, "NdrFcShort(0x%hx),\t%s\n", flags, buffer );
1164 print_file( file, indent, "NdrFcShort(0x%x), /* stack offset = %u */\n",
1166 if (flags & IsBasetype)
1167 {
1168 print_file( file, indent, "0x%02x, /* %s */\n", fc, string_of_type(fc) );
1169 print_file( file, indent, "0x0,\n" );
1170 }
1171 else
1172 print_file( file, indent, "NdrFcShort(0x%x), /* type offset = %u */\n",
1173 typestring_offset, typestring_offset );
1174 *stack_offset += max( stack_size, pointer_size );
1175 return 6;
1176}
1177
1178static unsigned int write_old_procformatstring_type(FILE *file, int indent, const var_t *var,
1179 int is_return, int is_interpreted)
1180{
1181 unsigned int size;
1182
1183 int is_in = is_attr(var->attrs, ATTR_IN);
1184 int is_out = is_attr(var->attrs, ATTR_OUT);
1185
1186 if (!is_in && !is_out) is_in = TRUE;
1187
1188 if (type_get_type(var->type) == TYPE_BASIC ||
1189 type_get_type(var->type) == TYPE_ENUM)
1190 {
1191 unsigned char fc;
1192
1193 if (is_return)
1194 print_file(file, indent, "0x53, /* FC_RETURN_PARAM_BASETYPE */\n");
1195 else
1196 print_file(file, indent, "0x4e, /* FC_IN_PARAM_BASETYPE */\n");
1197
1198 if (type_get_type(var->type) == TYPE_ENUM)
1199 {
1200 fc = get_enum_fc(var->type);
1201 }
1202 else
1203 {
1204 fc = get_basic_fc_signed(var->type);
1205
1206 if (fc == FC_BIND_PRIMITIVE)
1207 fc = FC_IGNORE;
1208 }
1209
1210 print_file(file, indent, "0x%02x, /* %s */\n",
1211 fc, string_of_type(fc));
1212 size = 2; /* includes param type prefix */
1213 }
1214 else
1215 {
1216 unsigned short offset = var->typestring_offset;
1217
1218 if (!is_interpreted && is_array(var->type) &&
1220 var->type->details.array.ptr_tfsoff)
1221 offset = var->type->typestring_offset;
1222
1223 if (is_return)
1224 print_file(file, indent, "0x52, /* FC_RETURN_PARAM */\n");
1225 else if (is_in && is_out)
1226 print_file(file, indent, "0x50, /* FC_IN_OUT_PARAM */\n");
1227 else if (is_out)
1228 print_file(file, indent, "0x51, /* FC_OUT_PARAM */\n");
1229 else
1230 print_file(file, indent, "0x4d, /* FC_IN_PARAM */\n");
1231
1233 print_file(file, indent, "0x%02x,\n", size / pointer_size );
1234 print_file(file, indent, "NdrFcShort(0x%x), /* type offset = %u */\n", offset, offset);
1235 size = 4; /* includes param type prefix */
1236 }
1237 return size;
1238}
1239
1240int is_interpreted_func( const type_t *iface, const var_t *func )
1241{
1242 const char *str;
1243 const var_t *var;
1244 const var_list_t *args = type_get_function_args( func->type );
1245 const type_t *ret_type = type_function_get_rettype( func->type );
1246
1247 if (type_get_type( ret_type ) == TYPE_BASIC)
1248 {
1249 switch (type_basic_get_type( ret_type ))
1250 {
1251 case TYPE_BASIC_INT64:
1252 case TYPE_BASIC_HYPER:
1253 /* return value must fit in a long_ptr */
1254 if (pointer_size < 8) return 0;
1255 break;
1256 case TYPE_BASIC_FLOAT:
1257 case TYPE_BASIC_DOUBLE:
1258 /* floating point values can't be returned */
1259 return 0;
1260 default:
1261 break;
1262 }
1263 }
1264 if (get_stub_mode() != MODE_Oif && args)
1265 {
1267 switch (type_get_type( var->type ))
1268 {
1269 case TYPE_BASIC:
1270 switch (type_basic_get_type( var->type ))
1271 {
1272 /* floating point arguments are not supported in Oi mode */
1273 case TYPE_BASIC_FLOAT: return 0;
1274 case TYPE_BASIC_DOUBLE: return 0;
1275 default: break;
1276 }
1277 break;
1278 /* unions passed by value are not supported in Oi mode */
1279 case TYPE_UNION: return 0;
1280 case TYPE_ENCAPSULATED_UNION: return 0;
1281 default: break;
1282 }
1283 }
1284
1285 if ((str = get_attrp( func->attrs, ATTR_OPTIMIZE ))) return !strcmp( str, "i" );
1286 if ((str = get_attrp( iface->attrs, ATTR_OPTIMIZE ))) return !strcmp( str, "i" );
1287 return (get_stub_mode() != MODE_Os);
1288}
1289
1290static void write_proc_func_header( FILE *file, int indent, const type_t *iface,
1291 const var_t *func, unsigned int *offset,
1292 unsigned short num_proc )
1293{
1294 var_t *var;
1296 unsigned char explicit_fc, implicit_fc;
1297 unsigned char handle_flags;
1298 const var_t *handle_var = get_func_handle_var( iface, func, &explicit_fc, &implicit_fc );
1299 unsigned char oi_flags = Oi_HAS_RPCFLAGS | Oi_USE_NEW_INIT_ROUTINES;
1300 unsigned int rpc_flags = get_rpc_flags( func->attrs );
1301 unsigned int nb_args = 0;
1302 unsigned int stack_size = 0;
1303 unsigned short param_num = 0;
1304 unsigned short handle_stack_offset = 0;
1305 unsigned short handle_param_num = 0;
1306
1308 if (is_object( iface ))
1309 {
1310 oi_flags |= Oi_OBJECT_PROC;
1311 if (get_stub_mode() == MODE_Oif) oi_flags |= Oi_OBJ_USE_V2_INTERPRETER;
1312 stack_size += pointer_size;
1313 }
1314
1316 {
1317 if (var == handle_var)
1318 {
1319 handle_stack_offset = stack_size;
1320 handle_param_num = param_num;
1321 }
1322 stack_size += get_stack_size( var, NULL );
1323 param_num++;
1324
1325 if (var != handle_var || implicit_fc || explicit_fc != FC_BIND_PRIMITIVE)
1326 nb_args++;
1327 }
1328 if (!is_void( type_function_get_rettype( func->type )))
1329 {
1330 stack_size += pointer_size;
1331 nb_args++;
1332 }
1333
1334 print_file( file, 0, "/* %u (procedure %s::%s) */\n", *offset, iface->name, func->name );
1335 print_file( file, indent, "0x%02x,\t/* %s */\n", implicit_fc,
1336 implicit_fc ? string_of_type(implicit_fc) : "explicit handle" );
1337 print_file( file, indent, "0x%02x,\n", oi_flags );
1338 print_file( file, indent, "NdrFcLong(0x%x),\n", rpc_flags );
1339 print_file( file, indent, "NdrFcShort(0x%hx),\t/* method %hu */\n", num_proc, num_proc );
1340 print_file( file, indent, "NdrFcShort(0x%x),\t/* stack size = %u */\n", stack_size, stack_size );
1341 *offset += 10;
1342
1343 if (!implicit_fc)
1344 {
1345 switch (explicit_fc)
1346 {
1347 case FC_BIND_PRIMITIVE:
1348 handle_flags = 0;
1349 print_file( file, indent, "0x%02x,\t/* %s */\n", explicit_fc, string_of_type(explicit_fc) );
1350 print_file( file, indent, "0x%02x,\n", handle_flags );
1351 print_file( file, indent, "NdrFcShort(0x%hx),\t/* stack offset = %hu */\n",
1352 handle_stack_offset, handle_stack_offset );
1353 *offset += 4;
1354 break;
1355 case FC_BIND_GENERIC:
1356 handle_flags = type_memsize( handle_var->type );
1357 print_file( file, indent, "0x%02x,\t/* %s */\n", explicit_fc, string_of_type(explicit_fc) );
1358 print_file( file, indent, "0x%02x,\n", handle_flags );
1359 print_file( file, indent, "NdrFcShort(0x%hx),\t/* stack offset = %hu */\n",
1360 handle_stack_offset, handle_stack_offset );
1361 print_file( file, indent, "0x%02x,\n", get_generic_handle_offset( handle_var->type ) );
1362 print_file( file, indent, "0x%x,\t/* FC_PAD */\n", FC_PAD);
1363 *offset += 6;
1364 break;
1365 case FC_BIND_CONTEXT:
1366 handle_flags = get_contexthandle_flags( iface, handle_var->attrs, handle_var->type );
1367 print_file( file, indent, "0x%02x,\t/* %s */\n", explicit_fc, string_of_type(explicit_fc) );
1368 print_file( file, indent, "0x%02x,\n", handle_flags );
1369 print_file( file, indent, "NdrFcShort(0x%hx),\t/* stack offset = %hu */\n",
1370 handle_stack_offset, handle_stack_offset );
1371 print_file( file, indent, "0x%02x,\n", get_context_handle_offset( handle_var->type ) );
1372 print_file( file, indent, "0x%02x,\t/* param %hu */\n", handle_param_num, handle_param_num );
1373 *offset += 6;
1374 break;
1375 }
1376 }
1377
1378 if (get_stub_mode() == MODE_Oif)
1379 {
1380 unsigned char oi2_flags = get_func_oi2_flags( func );
1381 unsigned char ext_flags = 0;
1382 unsigned int size;
1383
1384 if (is_attr( func->attrs, ATTR_NOTIFY )) ext_flags |= 0x08; /* HasNotify */
1385 if (is_attr( func->attrs, ATTR_NOTIFYFLAG )) ext_flags |= 0x10; /* HasNotify2 */
1386 if (iface == iface->details.iface->async_iface) oi2_flags |= 0x20;
1387
1389 print_file( file, indent, "NdrFcShort(0x%x),\t/* client buffer = %u */\n", size, size );
1391 print_file( file, indent, "NdrFcShort(0x%x),\t/* server buffer = %u */\n", size, size );
1392 print_file( file, indent, "0x%02x,\n", oi2_flags );
1393 print_file( file, indent, "0x%02x,\t/* %u params */\n", nb_args, nb_args );
1394 print_file( file, indent, "0x%02x,\n", pointer_size == 8 ? 10 : 8 );
1395 print_file( file, indent, "0x%02x,\n", ext_flags );
1396 print_file( file, indent, "NdrFcShort(0x0),\n" ); /* server corr hint */
1397 print_file( file, indent, "NdrFcShort(0x0),\n" ); /* client corr hint */
1398 print_file( file, indent, "NdrFcShort(0x0),\n" ); /* FIXME: notify index */
1399 *offset += 14;
1400 if (pointer_size == 8)
1401 {
1402 unsigned short pos = 0, fpu_mask = 0;
1403
1404 if (is_object( iface )) pos += 2;
1406 {
1407 if (type_get_type( var->type ) == TYPE_BASIC)
1408 {
1409 switch (type_basic_get_type( var->type ))
1410 {
1411 case TYPE_BASIC_FLOAT: fpu_mask |= 1 << pos; break;
1412 case TYPE_BASIC_DOUBLE: fpu_mask |= 2 << pos; break;
1413 default: break;
1414 }
1415 }
1416 pos += 2;
1417 if (pos >= 16) break;
1418 }
1419 print_file( file, indent, "NdrFcShort(0x%x),\n", fpu_mask ); /* floating point mask */
1420 *offset += 2;
1421 }
1422 }
1423}
1424
1425static void write_procformatstring_func( FILE *file, int indent, const type_t *iface,
1426 const var_t *func, unsigned int *offset,
1427 unsigned short num_proc )
1428{
1429 unsigned int stack_offset = is_object( iface ) ? pointer_size : 0;
1430 int is_interpreted = is_interpreted_func( iface, func );
1431 int is_new_style = is_interpreted && (get_stub_mode() == MODE_Oif);
1432 var_t *retval = type_function_get_retval( func->type );
1433 unsigned char explicit_fc, implicit_fc;
1434 const var_t *handle_var = get_func_handle_var( iface, func, &explicit_fc, &implicit_fc );
1435
1436 if (is_interpreted) write_proc_func_header( file, indent, iface, func, offset, num_proc );
1437
1438 /* emit argument data */
1439 if (type_get_function_args(func->type))
1440 {
1441 const var_t *var;
1443 {
1444 if (var != handle_var || implicit_fc || explicit_fc != FC_BIND_PRIMITIVE)
1445 {
1446 print_file( file, 0, "/* %u (parameter %s) */\n", *offset, var->name );
1447 if (is_new_style)
1449 else
1451 }
1452 else
1453 {
1455 }
1456 }
1457 }
1458
1459 /* emit return value data */
1460 if (is_void(retval->type))
1461 {
1462 if (!is_new_style)
1463 {
1464 print_file(file, 0, "/* %u (void) */\n", *offset);
1465 print_file(file, indent, "0x5b,\t/* FC_END */\n");
1466 print_file(file, indent, "0x5c,\t/* FC_PAD */\n");
1467 *offset += 2;
1468 }
1469 }
1470 else
1471 {
1472 print_file( file, 0, "/* %u (return value) */\n", *offset );
1473 if (is_new_style)
1475 else
1476 *offset += write_old_procformatstring_type(file, indent, retval, TRUE, is_interpreted);
1477 }
1478}
1479
1480static void for_each_iface(const statement_list_t *stmts,
1481 void (*proc)(type_t *iface, FILE *file, int indent, unsigned int *offset),
1482 type_pred_t pred, FILE *file, int indent, unsigned int *offset)
1483{
1484 const statement_t *stmt;
1485 type_t *iface;
1486
1487 if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry )
1488 {
1489 if (stmt->type != STMT_TYPE || type_get_type(stmt->u.type) != TYPE_INTERFACE)
1490 continue;
1491 iface = stmt->u.type;
1492 if (!pred(iface)) continue;
1493 proc(iface, file, indent, offset);
1494 if (iface->details.iface->async_iface)
1495 proc(iface->details.iface->async_iface, file, indent, offset);
1496 }
1497}
1498
1499static void write_iface_procformatstring(type_t *iface, FILE *file, int indent, unsigned int *offset)
1500{
1501 const statement_t *stmt;
1502 const type_t *parent = type_iface_get_inherit( iface );
1503 int count = parent ? count_methods( parent ) : 0;
1504
1506 {
1507 var_t *func = stmt->u.var;
1508 if (is_local(func->attrs)) continue;
1510 }
1511}
1512
1514{
1515 int indent = 0;
1516 unsigned int offset = 0;
1517
1518 print_file(file, indent, "static const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString =\n");
1519 print_file(file, indent, "{\n");
1520 indent++;
1521 print_file(file, indent, "0,\n");
1522 print_file(file, indent, "{\n");
1523 indent++;
1524
1526
1527 print_file(file, indent, "0x0\n");
1528 indent--;
1529 print_file(file, indent, "}\n");
1530 indent--;
1531 print_file(file, indent, "};\n");
1532 print_file(file, indent, "\n");
1533}
1534
1536{
1537 const statement_t *stmt;
1538 int indent = 0;
1539
1540 print_file( file, indent, "static const unsigned short %s_FormatStringOffsetTable[] =\n",
1541 iface->name );
1542 print_file( file, indent, "{\n" );
1543 indent++;
1545 {
1546 var_t *func = stmt->u.var;
1547 if (is_local( func->attrs )) continue;
1548 print_file( file, indent, "%u, /* %s */\n", func->procstring_offset, func->name );
1549 }
1550 indent--;
1551 print_file( file, indent, "};\n\n" );
1552}
1553
1554static int write_base_type(FILE *file, const type_t *type, unsigned int *typestring_offset)
1555{
1556 unsigned char fc;
1557
1560 else if (type_get_type(type) == TYPE_ENUM)
1561 fc = get_enum_fc(type);
1562 else
1563 return 0;
1564
1565 print_file(file, 2, "0x%02x,\t/* %s */\n", fc, string_of_type(fc));
1566 *typestring_offset += 1;
1567 return 1;
1568}
1569
1570/* write conformance / variance descriptor */
1571static unsigned int write_conf_or_var_desc(FILE *file, const type_t *cont_type,
1572 unsigned int baseoff, const type_t *type,
1573 const expr_t *expr)
1574{
1575 unsigned char operator_type = 0;
1576 unsigned char conftype = FC_NORMAL_CONFORMANCE;
1577 const char *conftype_string = "field";
1578 const expr_t *subexpr;
1579 const type_t *iface = NULL;
1580 const char *name;
1581
1582 if (!expr)
1583 {
1584 print_file(file, 2, "NdrFcLong(0xffffffff),\t/* -1 */\n");
1585 return 4;
1586 }
1587
1588 if (expr->is_const)
1589 {
1590 if (expr->cval > UCHAR_MAX * (USHRT_MAX + 1) + USHRT_MAX)
1591 error("write_conf_or_var_desc: constant value %d is greater than "
1592 "the maximum constant size of %d\n", expr->cval,
1593 UCHAR_MAX * (USHRT_MAX + 1) + USHRT_MAX);
1594
1595 print_file(file, 2, "0x%x, /* Corr desc: constant, val = %d */\n",
1597 print_file(file, 2, "0x%x,\n", expr->cval >> 16);
1598 print_file(file, 2, "NdrFcShort(0x%hx),\n", (unsigned short)expr->cval);
1599
1600 return 4;
1601 }
1602
1603 if (!cont_type) /* top-level conformance */
1604 {
1605 conftype = FC_TOP_LEVEL_CONFORMANCE;
1606 conftype_string = "parameter";
1607 cont_type = current_func->type;
1609 iface = current_iface;
1610 }
1611 else
1612 {
1613 name = cont_type->name;
1615 {
1616 conftype = FC_POINTER_CONFORMANCE;
1617 conftype_string = "field pointer";
1618 }
1619 }
1620
1621 subexpr = expr;
1622 switch (subexpr->type)
1623 {
1624 case EXPR_PPTR:
1625 subexpr = subexpr->ref;
1626 operator_type = FC_DEREFERENCE;
1627 break;
1628 case EXPR_DIV:
1629 if (subexpr->u.ext->is_const && (subexpr->u.ext->cval == 2))
1630 {
1631 subexpr = subexpr->ref;
1632 operator_type = FC_DIV_2;
1633 }
1634 break;
1635 case EXPR_MUL:
1636 if (subexpr->u.ext->is_const && (subexpr->u.ext->cval == 2))
1637 {
1638 subexpr = subexpr->ref;
1639 operator_type = FC_MULT_2;
1640 }
1641 break;
1642 case EXPR_SUB:
1643 if (subexpr->u.ext->is_const && (subexpr->u.ext->cval == 1))
1644 {
1645 subexpr = subexpr->ref;
1646 operator_type = FC_SUB_1;
1647 }
1648 break;
1649 case EXPR_ADD:
1650 if (subexpr->u.ext->is_const && (subexpr->u.ext->cval == 1))
1651 {
1652 subexpr = subexpr->ref;
1653 operator_type = FC_ADD_1;
1654 }
1655 break;
1656 default:
1657 break;
1658 }
1659
1660 if (subexpr->type == EXPR_IDENTIFIER)
1661 {
1662 const type_t *correlation_variable = NULL;
1663 unsigned char param_type = 0;
1664 unsigned int offset = 0;
1665 const var_t *var;
1666 struct expr_loc expr_loc;
1667
1668 if (type_get_type(cont_type) == TYPE_FUNCTION)
1669 {
1670 var_list_t *args = type_get_function_args( cont_type );
1671
1672 if (is_object( iface )) offset += pointer_size;
1673 if (args) LIST_FOR_EACH_ENTRY( var, args, const var_t, entry )
1674 {
1675 if (var->name && !strcmp(var->name, subexpr->u.sval))
1676 {
1677 expr_loc.v = var;
1678 correlation_variable = var->type;
1679 break;
1680 }
1682 }
1683 }
1684 else
1685 {
1687
1689 {
1690 unsigned int size = field_memsize( var->type, &offset );
1691 if (var->name && !strcmp(var->name, subexpr->u.sval))
1692 {
1693 expr_loc.v = var;
1694 correlation_variable = var->type;
1695 break;
1696 }
1697 offset += size;
1698 }
1699 }
1700
1701 if (!correlation_variable)
1702 error("write_conf_or_var_desc: couldn't find variable %s in %s\n", subexpr->u.sval, name);
1703 expr_loc.attr = NULL;
1704 correlation_variable = expr_resolve_type(&expr_loc, cont_type, expr);
1705
1706 offset -= baseoff;
1707
1708 if (type_get_type(correlation_variable) == TYPE_BASIC)
1709 {
1710 switch (get_basic_fc(correlation_variable))
1711 {
1712 case FC_CHAR:
1713 case FC_SMALL:
1714 param_type = FC_SMALL;
1715 break;
1716 case FC_BYTE:
1717 case FC_USMALL:
1718 param_type = FC_USMALL;
1719 break;
1720 case FC_WCHAR:
1721 case FC_SHORT:
1722 param_type = FC_SHORT;
1723 break;
1724 case FC_USHORT:
1725 param_type = FC_USHORT;
1726 break;
1727 case FC_LONG:
1728 param_type = FC_LONG;
1729 break;
1730 case FC_ULONG:
1731 param_type = FC_ULONG;
1732 break;
1733 default:
1734 error("write_conf_or_var_desc: conformance variable type not supported 0x%x\n",
1735 get_basic_fc(correlation_variable));
1736 }
1737 }
1738 else if (type_get_type(correlation_variable) == TYPE_ENUM)
1739 {
1740 if (get_enum_fc(correlation_variable) == FC_ENUM32)
1741 param_type = FC_LONG;
1742 else
1743 param_type = FC_SHORT;
1744 }
1745 else if (type_get_type(correlation_variable) == TYPE_POINTER)
1746 {
1747 if (pointer_size == 8)
1748 param_type = FC_HYPER;
1749 else
1750 param_type = FC_LONG;
1751 }
1752 else
1753 {
1754 error("write_conf_or_var_desc: non-arithmetic type used as correlation variable %s\n",
1755 subexpr->u.sval);
1756 return 0;
1757 }
1758
1759 print_file(file, 2, "0x%x,\t/* Corr desc: %s %s, %s */\n",
1760 conftype | param_type, conftype_string, subexpr->u.sval, string_of_type(param_type));
1761 print_file(file, 2, "0x%x,\t/* %s */\n", operator_type,
1762 operator_type ? string_of_type(operator_type) : "no operators");
1763 print_file(file, 2, "NdrFcShort(0x%hx),\t/* offset = %d */\n",
1764 (unsigned short)offset, offset);
1765 }
1766 else if (!iface || is_interpreted_func( iface, current_func ))
1767 {
1768 unsigned int callback_offset = 0;
1769 struct expr_eval_routine *eval;
1770 int found = 0;
1771
1773 {
1774 if (eval->cont_type == cont_type ||
1776 eval->iface == iface &&
1777 eval->name && name && !strcmp(eval->name, name) &&
1778 !compare_expr(eval->expr, expr)))
1779 {
1780 found = 1;
1781 break;
1782 }
1783 callback_offset++;
1784 }
1785
1786 if (!found)
1787 {
1788 eval = xmalloc (sizeof(*eval));
1789 eval->iface = iface;
1790 eval->cont_type = cont_type;
1791 eval->name = xstrdup( name );
1792 eval->baseoff = baseoff;
1793 eval->expr = expr;
1795 }
1796
1797 if (callback_offset > USHRT_MAX)
1798 error("Maximum number of callback routines reached\n");
1799
1800 print_file(file, 2, "0x%x,\t/* Corr desc: %s in %s */\n", conftype, conftype_string, name);
1801 print_file(file, 2, "0x%x,\t/* %s */\n", FC_CALLBACK, "FC_CALLBACK");
1802 print_file(file, 2, "NdrFcShort(0x%hx),\t/* %u */\n", (unsigned short)callback_offset, callback_offset);
1803 }
1804 else /* output a dummy corr desc that isn't used */
1805 {
1806 print_file(file, 2, "0x%x,\t/* Corr desc: unused for %s */\n", conftype, name);
1807 print_file(file, 2, "0x0,\n" );
1808 print_file(file, 2, "NdrFcShort(0x0),\n" );
1809 }
1810 return 4;
1811}
1812
1813/* return size and start offset of a data field based on current offset */
1814static unsigned int field_memsize(const type_t *type, unsigned int *offset)
1815{
1816 unsigned int align = 0;
1817 unsigned int size = type_memsize_and_alignment( type, &align );
1818
1819 *offset = ROUND_SIZE( *offset, align );
1820 return size;
1821}
1822
1823static unsigned int fields_memsize(const var_list_t *fields, unsigned int *align)
1824{
1825 unsigned int size = 0;
1826 unsigned int max_align;
1827 const var_t *v;
1828
1829 if (!fields) return 0;
1831 {
1832 unsigned int falign = 0;
1833 unsigned int fsize = type_memsize_and_alignment(v->type, &falign);
1834 if (*align < falign) *align = falign;
1835 falign = clamp_align(falign);
1836 size = ROUND_SIZE(size, falign);
1837 size += fsize;
1838 }
1839
1840 max_align = clamp_align(*align);
1841 size = ROUND_SIZE(size, max_align);
1842
1843 return size;
1844}
1845
1846static unsigned int union_memsize(const var_list_t *fields, unsigned int *pmaxa)
1847{
1848 unsigned int size, maxs = 0;
1849 unsigned int align = *pmaxa;
1850 const var_t *v;
1851
1852 if (fields) LIST_FOR_EACH_ENTRY( v, fields, const var_t, entry )
1853 {
1854 /* we could have an empty default field with NULL type */
1855 if (v->type)
1856 {
1858 if (maxs < size) maxs = size;
1859 if (*pmaxa < align) *pmaxa = align;
1860 }
1861 }
1862
1863 return maxs;
1864}
1865
1866unsigned int type_memsize_and_alignment(const type_t *t, unsigned int *align)
1867{
1868 unsigned int size = 0;
1869
1870 switch (type_get_type(t))
1871 {
1872 case TYPE_BASIC:
1873 switch (get_basic_fc(t))
1874 {
1875 case FC_BYTE:
1876 case FC_CHAR:
1877 case FC_USMALL:
1878 case FC_SMALL:
1879 size = 1;
1880 if (size > *align) *align = size;
1881 break;
1882 case FC_WCHAR:
1883 case FC_USHORT:
1884 case FC_SHORT:
1885 size = 2;
1886 if (size > *align) *align = size;
1887 break;
1888 case FC_ULONG:
1889 case FC_LONG:
1890 case FC_ERROR_STATUS_T:
1891 case FC_FLOAT:
1892 size = 4;
1893 if (size > *align) *align = size;
1894 break;
1895 case FC_HYPER:
1896 case FC_DOUBLE:
1897 size = 8;
1898 if (size > *align) *align = size;
1899 break;
1900 case FC_INT3264:
1901 case FC_UINT3264:
1902 case FC_BIND_PRIMITIVE:
1905 if (size > *align) *align = size;
1906 break;
1907 default:
1908 error("type_memsize: Unknown type 0x%x\n", get_basic_fc(t));
1909 size = 0;
1910 }
1911 break;
1912 case TYPE_ENUM:
1913 switch (get_enum_fc(t))
1914 {
1915 case FC_ENUM16:
1916 case FC_ENUM32:
1917 size = 4;
1918 if (size > *align) *align = size;
1919 break;
1920 default:
1921 error("type_memsize: Unknown enum type\n");
1922 size = 0;
1923 }
1924 break;
1925 case TYPE_STRUCT:
1927 break;
1930 break;
1931 case TYPE_UNION:
1933 break;
1934 case TYPE_POINTER:
1935 case TYPE_INTERFACE:
1938 if (size > *align) *align = size;
1939 break;
1940 case TYPE_ARRAY:
1942 {
1944 {
1946 size = 0;
1947 }
1948 else
1951 }
1952 else /* declared as a pointer */
1953 {
1956 if (size > *align) *align = size;
1957 }
1958 break;
1959 case TYPE_ALIAS:
1960 case TYPE_VOID:
1961 case TYPE_COCLASS:
1962 case TYPE_MODULE:
1963 case TYPE_FUNCTION:
1964 case TYPE_BITFIELD:
1965 /* these types should not be encountered here due to language
1966 * restrictions (interface, void, coclass, module), logical
1967 * restrictions (alias - due to type_get_type call above) or
1968 * checking restrictions (function, bitfield). */
1969 assert(0);
1970 }
1971
1972 return size;
1973}
1974
1975unsigned int type_memsize(const type_t *t)
1976{
1977 unsigned int align = 0;
1979}
1980
1981static unsigned int type_buffer_alignment(const type_t *t)
1982{
1983 const var_list_t *fields;
1984 const var_t *var;
1985 unsigned int max = 0, align;
1986
1987 switch (type_get_type(t))
1988 {
1989 case TYPE_BASIC:
1990 switch (get_basic_fc(t))
1991 {
1992 case FC_BYTE:
1993 case FC_CHAR:
1994 case FC_USMALL:
1995 case FC_SMALL:
1996 return 1;
1997 case FC_WCHAR:
1998 case FC_USHORT:
1999 case FC_SHORT:
2000 return 2;
2001 case FC_ULONG:
2002 case FC_LONG:
2003 case FC_ERROR_STATUS_T:
2004 case FC_FLOAT:
2005 case FC_INT3264:
2006 case FC_UINT3264:
2007 return 4;
2008 case FC_HYPER:
2009 case FC_DOUBLE:
2010 return 8;
2011 default:
2012 error("type_buffer_alignment: Unknown type 0x%x\n", get_basic_fc(t));
2013 }
2014 break;
2015 case TYPE_ENUM:
2016 switch (get_enum_fc(t))
2017 {
2018 case FC_ENUM16:
2019 return 2;
2020 case FC_ENUM32:
2021 return 4;
2022 default:
2023 error("type_buffer_alignment: Unknown enum type\n");
2024 }
2025 break;
2026 case TYPE_STRUCT:
2027 if (!(fields = type_struct_get_fields(t))) break;
2029 {
2030 if (!var->type) continue;
2031 align = type_buffer_alignment( var->type );
2032 if (max < align) max = align;
2033 }
2034 break;
2038 {
2039 if (!var->type) continue;
2040 align = type_buffer_alignment( var->type );
2041 if (max < align) max = align;
2042 }
2043 break;
2044 case TYPE_UNION:
2045 if (!(fields = type_union_get_cases(t))) break;
2047 {
2048 if (!var->type) continue;
2049 align = type_buffer_alignment( var->type );
2050 if (max < align) max = align;
2051 }
2052 break;
2053 case TYPE_ARRAY:
2056 /* else fall through */
2057 case TYPE_POINTER:
2058 return 4;
2059 case TYPE_INTERFACE:
2060 case TYPE_ALIAS:
2061 case TYPE_VOID:
2062 case TYPE_COCLASS:
2063 case TYPE_MODULE:
2064 case TYPE_FUNCTION:
2065 case TYPE_BITFIELD:
2066 /* these types should not be encountered here due to language
2067 * restrictions (interface, void, coclass, module), logical
2068 * restrictions (alias - due to type_get_type call above) or
2069 * checking restrictions (function, bitfield). */
2070 assert(0);
2071 }
2072 return max;
2073}
2074
2076{
2077 const var_t *var;
2079 return TRUE;
2080 if (!type_get_function_args(func->type))
2081 return FALSE;
2083 if (type_has_full_pointer( var->type, var->attrs, TRUE ))
2084 return TRUE;
2085 return FALSE;
2086}
2087
2088void write_full_pointer_init(FILE *file, int indent, const var_t *func, int is_server)
2089{
2090 print_file(file, indent, "__frame->_StubMsg.FullPtrXlatTables = NdrFullPointerXlatInit(0,%s);\n",
2091 is_server ? "XLAT_SERVER" : "XLAT_CLIENT");
2092 fprintf(file, "\n");
2093}
2094
2096{
2097 print_file(file, indent, "NdrFullPointerXlatFree(__frame->_StubMsg.FullPtrXlatTables);\n");
2098 fprintf(file, "\n");
2099}
2100
2101static unsigned int write_nonsimple_pointer(FILE *file, const attr_list_t *attrs,
2102 const type_t *type,
2103 enum type_context context,
2104 unsigned int offset,
2105 unsigned int *typeformat_offset)
2106{
2107 unsigned int start_offset = *typeformat_offset;
2108 short reloff = offset - (*typeformat_offset + 2);
2109 int in_attr, out_attr;
2110 int pointer_type;
2111 unsigned char flags = 0;
2112
2113 pointer_type = get_pointer_fc_context(type, attrs, context);
2114
2115 in_attr = is_attr(attrs, ATTR_IN);
2116 out_attr = is_attr(attrs, ATTR_OUT);
2117 if (!in_attr && !out_attr) in_attr = 1;
2118
2120 {
2121 if (out_attr && !in_attr && pointer_type == FC_RP)
2123 }
2124 else if (get_stub_mode() == MODE_Oif)
2125 {
2126 if (context == TYPE_CONTEXT_TOPLEVELPARAM && is_ptr(type) && pointer_type == FC_RP)
2127 {
2129 {
2130 case TGT_STRING:
2131 case TGT_POINTER:
2132 case TGT_CTXT_HANDLE:
2135 break;
2136 case TGT_IFACE_POINTER:
2137 if (in_attr && out_attr)
2139 break;
2140 default:
2141 break;
2142 }
2143 }
2144 }
2145
2146 if (is_ptr(type))
2147 {
2149 if(is_declptr(ref) && !is_user_type(ref))
2151 if (pointer_type != FC_RP) {
2152 flags |= get_attrv(type->attrs, ATTR_ALLOCATE);
2153 }
2154 }
2155
2156 print_file(file, 2, "0x%x, 0x%x,\t\t/* %s",
2157 pointer_type,
2158 flags,
2159 string_of_type(pointer_type));
2160 if (file)
2161 {
2163 fprintf(file, " [allocated_on_stack]");
2164 if (flags & FC_POINTER_DEREF)
2165 fprintf(file, " [pointer_deref]");
2166 if (flags & FC_DONT_FREE)
2167 fprintf(file, " [dont_free]");
2169 fprintf(file, " [all_nodes]");
2170 fprintf(file, " */\n");
2171 }
2172
2173 print_file(file, 2, "NdrFcShort(0x%hx),\t/* Offset= %hd (%u) */\n", reloff, reloff, offset);
2174 *typeformat_offset += 4;
2175
2176 return start_offset;
2177}
2178
2179static unsigned int write_simple_pointer(FILE *file, const attr_list_t *attrs,
2180 const type_t *type, enum type_context context)
2181{
2182 unsigned char fc;
2183 unsigned char pointer_fc;
2184 const type_t *ref;
2185 int in_attr = is_attr(attrs, ATTR_IN);
2186 int out_attr = is_attr(attrs, ATTR_OUT);
2187 unsigned char flags = FC_SIMPLE_POINTER;
2188
2189 /* for historical reasons, write_simple_pointer also handled string types,
2190 * but no longer does. catch bad uses of the function with this check */
2191 if (is_string_type(attrs, type))
2192 error("write_simple_pointer: can't handle type %s which is a string type\n", type->name);
2193
2194 pointer_fc = get_pointer_fc_context(type, attrs, context);
2195
2197 if (type_get_type(ref) == TYPE_ENUM)
2198 fc = get_enum_fc(ref);
2199 else
2200 fc = get_basic_fc(ref);
2201
2203 {
2204 if (out_attr && !in_attr && pointer_fc == FC_RP)
2206 }
2207 else if (get_stub_mode() == MODE_Oif)
2208 {
2209 if (context == TYPE_CONTEXT_TOPLEVELPARAM && fc == FC_ENUM16 && pointer_fc == FC_RP)
2211 }
2212
2213 print_file(file, 2, "0x%02x, 0x%x,\t/* %s %s[simple_pointer] */\n",
2214 pointer_fc, flags, string_of_type(pointer_fc),
2215 flags & FC_ALLOCED_ON_STACK ? "[allocated_on_stack] " : "");
2216 print_file(file, 2, "0x%02x,\t/* %s */\n", fc, string_of_type(fc));
2217 print_file(file, 2, "0x5c,\t/* FC_PAD */\n");
2218 return 4;
2219}
2220
2221static void print_start_tfs_comment(FILE *file, type_t *t, unsigned int tfsoff)
2222{
2223 print_file(file, 0, "/* %u (", tfsoff);
2225 print_file(file, 0, ") */\n");
2226}
2227
2228static unsigned int write_pointer_tfs(FILE *file, const attr_list_t *attrs,
2229 type_t *type, unsigned int ref_offset,
2230 enum type_context context,
2231 unsigned int *typestring_offset)
2232{
2233 unsigned int offset = *typestring_offset;
2235
2238
2239 switch (typegen_detect_type(ref, attrs, TDT_ALL_TYPES))
2240 {
2241 case TGT_BASIC:
2242 case TGT_ENUM:
2243 *typestring_offset += write_simple_pointer(file, attrs, type, context);
2244 break;
2245 default:
2246 if (ref_offset)
2247 write_nonsimple_pointer(file, attrs, type, context, ref_offset, typestring_offset);
2248 break;
2249 }
2250
2251 return offset;
2252}
2253
2254static int processed(const type_t *type)
2255{
2256 return type->typestring_offset && !type->tfswrite;
2257}
2258
2260{
2261 if (is_ptr(t))
2262 return TRUE;
2263 else if (type_get_type(t) == TYPE_STRUCT)
2264 {
2265 switch (get_struct_fc(t))
2266 {
2267 case FC_PSTRUCT:
2268 case FC_CSTRUCT:
2269 case FC_CPSTRUCT:
2270 case FC_CVSTRUCT:
2271 return TRUE;
2272 }
2273 }
2274 /* Note: Since this only applies to user types, we can't have a conformant
2275 array here, and strings should get filed under pointer in this case. */
2276 return FALSE;
2277}
2278
2279static unsigned int write_user_tfs(FILE *file, type_t *type, unsigned int *tfsoff)
2280{
2281 unsigned int start, absoff, flags;
2282 const char *name = NULL;
2283 type_t *utype = get_user_type(type, &name);
2284 unsigned int usize = type_memsize(utype);
2285 unsigned int ualign = type_buffer_alignment(utype);
2286 unsigned int size = type_memsize(type);
2287 unsigned short funoff = user_type_offset(name);
2288 short reloff;
2289
2290 if (processed(type)) return type->typestring_offset;
2291
2292 guard_rec(type);
2293
2294 if(user_type_has_variable_size(utype)) usize = 0;
2295
2296 if (type_get_type(utype) == TYPE_BASIC ||
2297 type_get_type(utype) == TYPE_ENUM)
2298 {
2299 unsigned char fc;
2300
2301 if (type_get_type(utype) == TYPE_ENUM)
2302 fc = get_enum_fc(utype);
2303 else
2304 fc = get_basic_fc(utype);
2305
2306 absoff = *tfsoff;
2307 print_start_tfs_comment(file, utype, absoff);
2308 print_file(file, 2, "0x%x,\t/* %s */\n", fc, string_of_type(fc));
2309 print_file(file, 2, "0x5c,\t/* FC_PAD */\n");
2310 *tfsoff += 2;
2311 }
2312 else
2313 {
2314 if (!processed(utype))
2315 write_embedded_types(file, NULL, utype, utype->name, TRUE, tfsoff);
2316 absoff = utype->typestring_offset;
2317 }
2318
2319 if (type_get_type(utype) == TYPE_POINTER && get_pointer_fc(utype, NULL, FALSE) == FC_RP)
2320 flags = 0x40;
2321 else if (type_get_type(utype) == TYPE_POINTER && get_pointer_fc(utype, NULL, FALSE) == FC_UP)
2322 flags = 0x80;
2323 else
2324 flags = 0;
2325
2326 start = *tfsoff;
2329 print_file(file, 2, "0x%x,\t/* FC_USER_MARSHAL */\n", FC_USER_MARSHAL);
2330 print_file(file, 2, "0x%x,\t/* Alignment= %d, Flags= %02x */\n",
2331 flags | (ualign - 1), ualign - 1, flags);
2332 print_file(file, 2, "NdrFcShort(0x%hx),\t/* Function offset= %hu */\n", funoff, funoff);
2333 print_file(file, 2, "NdrFcShort(0x%hx),\t/* %u */\n", (unsigned short)size, size);
2334 print_file(file, 2, "NdrFcShort(0x%hx),\t/* %u */\n", (unsigned short)usize, usize);
2335 *tfsoff += 8;
2336 reloff = absoff - *tfsoff;
2337 print_file(file, 2, "NdrFcShort(0x%hx),\t/* Offset= %hd (%u) */\n", reloff, reloff, absoff);
2338 *tfsoff += 2;
2339 return start;
2340}
2341
2342static void write_member_type(FILE *file, const type_t *cont,
2343 int cont_is_complex, const attr_list_t *attrs,
2344 const type_t *type, unsigned int *corroff,
2345 unsigned int *tfsoff)
2346{
2348 {
2349 unsigned int absoff;
2350 short reloff;
2351
2353 {
2354 absoff = *corroff;
2355 *corroff += 8;
2356 }
2357 else
2358 {
2359 absoff = type->typestring_offset;
2360 }
2361 reloff = absoff - (*tfsoff + 2);
2362
2363 print_file(file, 2, "0x4c,\t/* FC_EMBEDDED_COMPLEX */\n");
2364 /* padding is represented using FC_STRUCTPAD* types, so presumably
2365 * this is left over in the format for historical purposes in MIDL
2366 * or rpcrt4. */
2367 print_file(file, 2, "0x0,\n");
2368 print_file(file, 2, "NdrFcShort(0x%hx),\t/* Offset= %hd (%u) */\n",
2369 reloff, reloff, absoff);
2370 *tfsoff += 4;
2371 }
2372 else if (is_ptr(type) || is_conformant_array(type))
2373 {
2374 unsigned char fc = cont_is_complex ? FC_POINTER : FC_LONG;
2375 print_file(file, 2, "0x%x,\t/* %s */\n", fc, string_of_type(fc));
2376 *tfsoff += 1;
2377 }
2378 else if (!write_base_type(file, type, tfsoff))
2379 error("Unsupported member type %d\n", type_get_type(type));
2380}
2381
2382static void write_array_element_type(FILE *file, const attr_list_t *attrs, const type_t *type,
2383 int cont_is_complex, unsigned int *tfsoff)
2384{
2386
2388 {
2390
2391 if (processed(ref))
2392 {
2394 ref->typestring_offset, tfsoff);
2395 return;
2396 }
2397 if (cont_is_complex && is_string_type(attrs, elem))
2398 {
2400 return;
2401 }
2402 if (!is_string_type(NULL, elem) &&
2404 {
2406 return;
2407 }
2408 }
2409 write_member_type(file, type, cont_is_complex, NULL, elem, NULL, tfsoff);
2410}
2411
2412static void write_end(FILE *file, unsigned int *tfsoff)
2413{
2414 if (*tfsoff % 2 == 0)
2415 {
2416 print_file(file, 2, "0x%x,\t/* FC_PAD */\n", FC_PAD);
2417 *tfsoff += 1;
2418 }
2419 print_file(file, 2, "0x%x,\t/* FC_END */\n", FC_END);
2420 *tfsoff += 1;
2421}
2422
2423static void write_descriptors(FILE *file, type_t *type, unsigned int *tfsoff)
2424{
2425 unsigned int offset = 0;
2427 var_t *f;
2428
2430 {
2431 type_t *ft = f->type;
2432 unsigned int size = field_memsize( ft, &offset );
2433 if (type_get_type(ft) == TYPE_UNION && is_attr(f->attrs, ATTR_SWITCHIS))
2434 {
2435 short reloff;
2436 unsigned int absoff = ft->typestring_offset;
2437 if (is_attr(ft->attrs, ATTR_SWITCHTYPE))
2438 absoff += 8; /* we already have a corr descr, skip it */
2439 reloff = absoff - (*tfsoff + 6);
2440 print_file(file, 0, "/* %d */\n", *tfsoff);
2441 print_file(file, 2, "0x%x,\t/* FC_NON_ENCAPSULATED_UNION */\n", FC_NON_ENCAPSULATED_UNION);
2442 print_file(file, 2, "0x%x,\t/* FIXME: always FC_LONG */\n", FC_LONG);
2444 get_attrp(f->attrs, ATTR_SWITCHIS));
2445 print_file(file, 2, "NdrFcShort(0x%hx),\t/* Offset= %hd (%u) */\n",
2446 (unsigned short)reloff, reloff, absoff);
2447 *tfsoff += 8;
2448 }
2449 offset += size;
2450 }
2451}
2452
2454 FILE *file, const attr_list_t *attrs, type_t *type,
2455 unsigned int *offset_in_memory, unsigned int *offset_in_buffer,
2456 unsigned int *typestring_offset)
2457{
2458 int written = 0;
2459
2462 {
2463 if (offset_in_memory && offset_in_buffer)
2464 {
2465 unsigned int memsize;
2466
2467 /* pointer instance
2468 *
2469 * note that MSDN states that for pointer layouts in structures,
2470 * this is a negative offset from the end of the structure, but
2471 * this statement is incorrect. all offsets are positive */
2472 print_file(file, 2, "NdrFcShort(0x%hx),\t/* Memory offset = %d */\n", (unsigned short)*offset_in_memory, *offset_in_memory);
2473 print_file(file, 2, "NdrFcShort(0x%hx),\t/* Buffer offset = %d */\n", (unsigned short)*offset_in_buffer, *offset_in_buffer);
2474
2475 memsize = type_memsize(type);
2476 *offset_in_memory += memsize;
2477 /* increment these separately as in the case of conformant (varying)
2478 * structures these start at different values */
2479 *offset_in_buffer += memsize;
2480 }
2481 *typestring_offset += 4;
2482
2483 if (is_ptr(type))
2484 {
2486
2487 if (is_string_type(attrs, type))
2488 write_string_tfs(file, attrs, type, TYPE_CONTEXT_CONTAINER, NULL, typestring_offset);
2489 else if (processed(ref))
2491 ref->typestring_offset, typestring_offset);
2493 *typestring_offset += write_simple_pointer(file, attrs, type, TYPE_CONTEXT_CONTAINER);
2494 else
2495 error("write_pointer_description_offsets: type format string unknown\n");
2496 }
2497 else
2498 {
2499 unsigned int offset = type->typestring_offset;
2500 /* skip over the pointer that is written for strings, since a
2501 * pointer has to be written in-place here */
2502 if (is_string_type(attrs, type))
2503 offset += 4;
2504 write_nonsimple_pointer(file, attrs, type, TYPE_CONTEXT_CONTAINER, offset, typestring_offset);
2505 }
2506
2507 return 1;
2508 }
2509
2510 if (is_array(type))
2511 {
2513 file, attrs, type_array_get_element(type), offset_in_memory,
2514 offset_in_buffer, typestring_offset);
2515 }
2516 else if (is_non_complex_struct(type))
2517 {
2518 /* otherwise search for interesting fields to parse */
2519 const var_t *v;
2521 {
2522 if (offset_in_memory && offset_in_buffer)
2523 {
2524 unsigned int padding;
2525 unsigned int align = 0;
2527 padding = ROUNDING(*offset_in_memory, align);
2528 *offset_in_memory += padding;
2529 *offset_in_buffer += padding;
2530 }
2532 file, v->attrs, v->type, offset_in_memory, offset_in_buffer,
2533 typestring_offset);
2534 }
2535 }
2536 else
2537 {
2538 if (offset_in_memory && offset_in_buffer)
2539 {
2540 unsigned int memsize = type_memsize(type);
2541 *offset_in_memory += memsize;
2542 /* increment these separately as in the case of conformant (varying)
2543 * structures these start at different values */
2544 *offset_in_buffer += memsize;
2545 }
2546 }
2547
2548 return written;
2549}
2550
2552 FILE *file, const attr_list_t *attrs, type_t *type,
2553 unsigned int *offset_in_memory, unsigned int *offset_in_buffer,
2554 unsigned int *typestring_offset)
2555{
2556 int written = 0;
2557
2558 if (is_ptr(type) ||
2560 {
2561 print_file(file, 2, "0x%02x, /* FC_NO_REPEAT */\n", FC_NO_REPEAT);
2562 print_file(file, 2, "0x%02x, /* FC_PAD */\n", FC_PAD);
2563 *typestring_offset += 2;
2564
2566 offset_in_memory, offset_in_buffer, typestring_offset);
2567 }
2568
2570 {
2571 const var_t *v;
2573 {
2574 if (offset_in_memory && offset_in_buffer)
2575 {
2576 unsigned int padding;
2577 unsigned int align = 0;
2579 padding = ROUNDING(*offset_in_memory, align);
2580 *offset_in_memory += padding;
2581 *offset_in_buffer += padding;
2582 }
2584 file, v->attrs, v->type,
2585 offset_in_memory, offset_in_buffer, typestring_offset);
2586 }
2587 }
2588 else
2589 {
2590 unsigned int memsize = type_memsize(type);
2591 *offset_in_memory += memsize;
2592 /* increment these separately as in the case of conformant (varying)
2593 * structures these start at different values */
2594 *offset_in_buffer += memsize;
2595 }
2596
2597 return written;
2598}
2599
2600/* Note: if file is NULL return value is number of pointers to write, else
2601 * it is the number of type format characters written */
2603 FILE *file, const attr_list_t *attrs, type_t *type,
2604 unsigned int *offset_in_memory, unsigned int *offset_in_buffer,
2605 unsigned int *typestring_offset)
2606{
2607 int pointer_count = 0;
2608
2609 if (type_get_type(type) == TYPE_ARRAY &&
2611 {
2612 unsigned int temp = 0;
2613 /* unfortunately, this needs to be done in two passes to avoid
2614 * writing out redundant FC_FIXED_REPEAT descriptions */
2615 pointer_count = write_pointer_description_offsets(
2617 if (pointer_count > 0)
2618 {
2619 unsigned int increment_size;
2620 unsigned int offset_of_array_pointer_mem = 0;
2621 unsigned int offset_of_array_pointer_buf = 0;
2622
2623 increment_size = type_memsize(type_array_get_element(type));
2624
2625 print_file(file, 2, "0x%02x, /* FC_FIXED_REPEAT */\n", FC_FIXED_REPEAT);
2626 print_file(file, 2, "0x%02x, /* FC_PAD */\n", FC_PAD);
2627 print_file(file, 2, "NdrFcShort(0x%hx),\t/* Iterations = %d */\n", (unsigned short)type_array_get_dim(type), type_array_get_dim(type));
2628 print_file(file, 2, "NdrFcShort(0x%hx),\t/* Increment = %d */\n", (unsigned short)increment_size, increment_size);
2629 print_file(file, 2, "NdrFcShort(0x%hx),\t/* Offset to array = %d */\n", (unsigned short)*offset_in_memory, *offset_in_memory);
2630 print_file(file, 2, "NdrFcShort(0x%hx),\t/* Number of pointers = %d */\n", (unsigned short)pointer_count, pointer_count);
2631 *typestring_offset += 10;
2632
2633 pointer_count = write_pointer_description_offsets(
2634 file, attrs, type, &offset_of_array_pointer_mem,
2635 &offset_of_array_pointer_buf, typestring_offset);
2636 }
2637 }
2638 else if (type_get_type(type) == TYPE_STRUCT)
2639 {
2640 const var_t *v;
2642 {
2643 if (offset_in_memory && offset_in_buffer)
2644 {
2645 unsigned int padding;
2646 unsigned int align = 0;
2648 padding = ROUNDING(*offset_in_memory, align);
2649 *offset_in_memory += padding;
2650 *offset_in_buffer += padding;
2651 }
2653 file, v->attrs, v->type, offset_in_memory, offset_in_buffer,
2654 typestring_offset);
2655 }
2656 }
2657 else
2658 {
2659 if (offset_in_memory && offset_in_buffer)
2660 {
2661 unsigned int memsize;
2662 memsize = type_memsize(type);
2663 *offset_in_memory += memsize;
2664 /* increment these separately as in the case of conformant (varying)
2665 * structures these start at different values */
2666 *offset_in_buffer += memsize;
2667 }
2668 }
2669
2670 return pointer_count;
2671}
2672
2673/* Note: if file is NULL return value is number of pointers to write, else
2674 * it is the number of type format characters written */
2676 FILE *file, const attr_list_t *attrs, type_t *type,
2677 unsigned int offset_in_memory, unsigned int *typestring_offset)
2678{
2679 int pointer_count = 0;
2680
2682 {
2683 unsigned int temp = 0;
2684 /* unfortunately, this needs to be done in two passes to avoid
2685 * writing out redundant FC_VARIABLE_REPEAT descriptions */
2686 pointer_count = write_pointer_description_offsets(
2688 if (pointer_count > 0)
2689 {
2690 unsigned int increment_size;
2691 unsigned int offset_of_array_pointer_mem = offset_in_memory;
2692 unsigned int offset_of_array_pointer_buf = offset_in_memory;
2693
2694 increment_size = type_memsize(type_array_get_element(type));
2695
2696 if (increment_size > USHRT_MAX)
2697 error("array size of %u bytes is too large\n", increment_size);
2698
2699 print_file(file, 2, "0x%02x, /* FC_VARIABLE_REPEAT */\n", FC_VARIABLE_REPEAT);
2700 print_file(file, 2, "0x%02x, /* FC_FIXED_OFFSET */\n", FC_FIXED_OFFSET);
2701 print_file(file, 2, "NdrFcShort(0x%hx),\t/* Increment = %d */\n", (unsigned short)increment_size, increment_size);
2702 print_file(file, 2, "NdrFcShort(0x%hx),\t/* Offset to array = %d */\n", (unsigned short)offset_in_memory, offset_in_memory);
2703 print_file(file, 2, "NdrFcShort(0x%hx),\t/* Number of pointers = %d */\n", (unsigned short)pointer_count, pointer_count);
2704 *typestring_offset += 8;
2705
2706 pointer_count = write_pointer_description_offsets(
2708 &offset_of_array_pointer_mem, &offset_of_array_pointer_buf,
2709 typestring_offset);
2710 }
2711 }
2712
2713 return pointer_count;
2714}
2715
2716/* Note: if file is NULL return value is number of pointers to write, else
2717 * it is the number of type format characters written */
2719 FILE *file, const attr_list_t *attrs, type_t *type,
2720 unsigned int *offset_in_memory, unsigned int *offset_in_buffer,
2721 unsigned int *typestring_offset)
2722{
2723 int pointer_count = 0;
2724
2726 {
2727 unsigned int temp = 0;
2728 /* unfortunately, this needs to be done in two passes to avoid
2729 * writing out redundant FC_VARIABLE_REPEAT descriptions */
2730 pointer_count = write_pointer_description_offsets(
2732 if (pointer_count > 0)
2733 {
2734 unsigned int increment_size;
2735
2736 increment_size = type_memsize(type_array_get_element(type));
2737
2738 if (increment_size > USHRT_MAX)
2739 error("array size of %u bytes is too large\n", increment_size);
2740
2741 print_file(file, 2, "0x%02x, /* FC_VARIABLE_REPEAT */\n", FC_VARIABLE_REPEAT);
2742 print_file(file, 2, "0x%02x, /* FC_VARIABLE_OFFSET */\n", FC_VARIABLE_OFFSET);
2743 print_file(file, 2, "NdrFcShort(0x%hx),\t/* Increment = %d */\n", (unsigned short)increment_size, increment_size);
2744 print_file(file, 2, "NdrFcShort(0x%hx),\t/* Offset to array = %d */\n", (unsigned short)*offset_in_memory, *offset_in_memory);
2745 print_file(file, 2, "NdrFcShort(0x%hx),\t/* Number of pointers = %d */\n", (unsigned short)pointer_count, pointer_count);
2746 *typestring_offset += 8;
2747
2748 pointer_count = write_pointer_description_offsets(
2749 file, attrs, type_array_get_element(type), offset_in_memory,
2750 offset_in_buffer, typestring_offset);
2751 }
2752 }
2753 else if (type_get_type(type) == TYPE_STRUCT)
2754 {
2755 const var_t *v;
2757 {
2758 if (offset_in_memory && offset_in_buffer)
2759 {
2760 unsigned int align = 0, padding;
2761
2762 if (is_array(v->type) && type_array_has_variance(v->type))
2763 {
2764 *offset_in_buffer = ROUND_SIZE(*offset_in_buffer, 4);
2765 /* skip over variance and offset in buffer */
2766 *offset_in_buffer += 8;
2767 }
2768
2770 padding = ROUNDING(*offset_in_memory, align);
2771 *offset_in_memory += padding;
2772 *offset_in_buffer += padding;
2773 }
2775 file, v->attrs, v->type, offset_in_memory, offset_in_buffer,
2776 typestring_offset);
2777 }
2778 }
2779 else
2780 {
2781 if (offset_in_memory && offset_in_buffer)
2782 {
2783 unsigned int memsize = type_memsize(type);
2784 *offset_in_memory += memsize;
2785 /* increment these separately as in the case of conformant (varying)
2786 * structures these start at different values */
2787 *offset_in_buffer += memsize;
2788 }
2789 }
2790
2791 return pointer_count;
2792}
2793
2795 unsigned int *typestring_offset)
2796{
2797 unsigned int offset_in_buffer;
2798 unsigned int offset_in_memory;
2799
2800 /* pass 1: search for single instance of a pointer (i.e. don't descend
2801 * into arrays) */
2802 if (!is_array(type))
2803 {
2804 offset_in_memory = 0;
2805 offset_in_buffer = 0;
2807 file, NULL, type,
2808 &offset_in_memory, &offset_in_buffer, typestring_offset);
2809 }
2810
2811 /* pass 2: search for pointers in fixed arrays */
2812 offset_in_memory = 0;
2813 offset_in_buffer = 0;
2815 file, NULL, type,
2816 &offset_in_memory, &offset_in_buffer, typestring_offset);
2817
2818 /* pass 3: search for pointers in conformant only arrays (but don't descend
2819 * into conformant varying or varying arrays) */
2823 file, attrs, type, 0, typestring_offset);
2824 else if (type_get_type(type) == TYPE_STRUCT &&
2826 {
2829 type_memsize(type), typestring_offset);
2830 }
2831
2832 /* pass 4: search for pointers in varying arrays */
2833 offset_in_memory = 0;
2834 offset_in_buffer = 0;
2836 file, NULL, type,
2837 &offset_in_memory, &offset_in_buffer, typestring_offset);
2838}
2839
2840static unsigned int write_string_tfs(FILE *file, const attr_list_t *attrs,
2842 const char *name, unsigned int *typestring_offset)
2843{
2844 unsigned int start_offset;
2845 unsigned char rtype;
2846 type_t *elem_type;
2847 int is_processed = processed(type);
2848
2849 start_offset = *typestring_offset;
2850
2851 if (is_declptr(type))
2852 {
2853 unsigned char flag = is_conformant_array(type) ? 0 : FC_SIMPLE_POINTER;
2854 int pointer_type = get_pointer_fc_context(type, attrs, context);
2855 if (!pointer_type)
2856 pointer_type = FC_RP;
2857 print_start_tfs_comment(file, type, *typestring_offset);
2858 print_file(file, 2,"0x%x, 0x%x,\t/* %s%s */\n",
2859 pointer_type, flag, string_of_type(pointer_type),
2860 flag ? " [simple_pointer]" : "");
2861 *typestring_offset += 2;
2862 if (!flag)
2863 {
2864 print_file(file, 2, "NdrFcShort(0x2),\n");
2865 *typestring_offset += 2;
2866 }
2867 is_processed = FALSE;
2868 }
2869
2870 if (is_array(type))
2871 elem_type = type_array_get_element(type);
2872 else
2873 elem_type = type_pointer_get_ref(type);
2874
2875 if (type_get_type(elem_type) == TYPE_POINTER && is_array(type))
2876 return write_array_tfs(file, attrs, type, name, typestring_offset);
2877
2878 if (type_get_type(elem_type) != TYPE_BASIC)
2879 {
2880 error("write_string_tfs: Unimplemented for non-basic type %s\n", name);
2881 return start_offset;
2882 }
2883
2884 rtype = get_basic_fc(elem_type);
2885 if ((rtype != FC_BYTE) && (rtype != FC_CHAR) && (rtype != FC_WCHAR))
2886 {
2887 error("write_string_tfs: Unimplemented for type 0x%x of name: %s\n", rtype, name);
2888 return start_offset;
2889 }
2890
2892 {
2893 unsigned int dim = type_array_get_dim(type);
2894
2895 if (is_processed) return start_offset;
2896
2897 /* FIXME: multi-dimensional array */
2898 if (0xffffu < dim)
2899 error("array size for parameter %s exceeds %u bytes by %u bytes\n",
2900 name, 0xffffu, dim - 0xffffu);
2901
2902 if (rtype == FC_WCHAR)
2903 WRITE_FCTYPE(file, FC_WSTRING, *typestring_offset);
2904 else
2905 WRITE_FCTYPE(file, FC_CSTRING, *typestring_offset);
2906 print_file(file, 2, "0x%x,\t/* FC_PAD */\n", FC_PAD);
2907 *typestring_offset += 2;
2908
2909 print_file(file, 2, "NdrFcShort(0x%hx),\t/* %d */\n", (unsigned short)dim, dim);
2910 *typestring_offset += 2;
2911
2912 update_tfsoff(type, start_offset, file);
2913 return start_offset;
2914 }
2915 else if (is_conformant_array(type))
2916 {
2917 if (rtype == FC_WCHAR)
2918 WRITE_FCTYPE(file, FC_C_WSTRING, *typestring_offset);
2919 else
2920 WRITE_FCTYPE(file, FC_C_CSTRING, *typestring_offset);
2921 print_file(file, 2, "0x%x,\t/* FC_STRING_SIZED */\n", FC_STRING_SIZED);
2922 *typestring_offset += 2;
2923
2924 *typestring_offset += write_conf_or_var_desc(
2928 : 0),
2930
2931 update_tfsoff(type, start_offset, file);
2932 return start_offset;
2933 }
2934 else
2935 {
2936 if (is_processed) return start_offset;
2937
2938 if (rtype == FC_WCHAR)
2939 WRITE_FCTYPE(file, FC_C_WSTRING, *typestring_offset);
2940 else
2941 WRITE_FCTYPE(file, FC_C_CSTRING, *typestring_offset);
2942 print_file(file, 2, "0x%x,\t/* FC_PAD */\n", FC_PAD);
2943 *typestring_offset += 2;
2944
2945 update_tfsoff(type, start_offset, file);
2946 return start_offset;
2947 }
2948}
2949
2950static unsigned int write_array_tfs(FILE *file, const attr_list_t *attrs, type_t *type,
2951 const char *name, unsigned int *typestring_offset)
2952{
2953 const expr_t *length_is = type_array_get_variance(type);
2954 const expr_t *size_is = type_array_get_conformance(type);
2955 unsigned int align;
2956 unsigned int size;
2957 unsigned int start_offset;
2958 unsigned char fc;
2959 int pointer_type = get_attrv(attrs, ATTR_POINTERTYPE);
2960 unsigned int baseoff
2963 : 0;
2964
2965 if (!pointer_type)
2966 pointer_type = FC_RP;
2967
2969 write_embedded_types(file, attrs, type_array_get_element(type), name, FALSE, typestring_offset);
2970
2973 fc = get_array_fc(type);
2974
2975 start_offset = *typestring_offset;
2976 update_tfsoff(type, start_offset, file);
2977 print_start_tfs_comment(file, type, start_offset);
2978 print_file(file, 2, "0x%02x,\t/* %s */\n", fc, string_of_type(fc));
2979 print_file(file, 2, "0x%x,\t/* %d */\n", align - 1, align - 1);
2980 *typestring_offset += 2;
2981
2982 align = 0;
2983 if (fc != FC_BOGUS_ARRAY)
2984 {
2985 if (fc == FC_LGFARRAY || fc == FC_LGVARRAY)
2986 {
2987 print_file(file, 2, "NdrFcLong(0x%x),\t/* %u */\n", size, size);
2988 *typestring_offset += 4;
2989 }
2990 else
2991 {
2992 print_file(file, 2, "NdrFcShort(0x%hx),\t/* %u */\n", (unsigned short)size, size);
2993 *typestring_offset += 2;
2994 }
2995
2997 *typestring_offset
2999 type, size_is);
3000
3001 if (fc == FC_SMVARRAY || fc == FC_LGVARRAY)
3002 {
3003 unsigned int elsize = type_memsize(type_array_get_element(type));
3004 unsigned int dim = type_array_get_dim(type);
3005
3006 if (fc == FC_LGVARRAY)
3007 {
3008 print_file(file, 2, "NdrFcLong(0x%x),\t/* %u */\n", dim, dim);
3009 *typestring_offset += 4;
3010 }
3011 else
3012 {
3013 print_file(file, 2, "NdrFcShort(0x%hx),\t/* %u */\n", (unsigned short)dim, dim);
3014 *typestring_offset += 2;
3015 }
3016
3017 print_file(file, 2, "NdrFcShort(0x%hx),\t/* %u */\n", (unsigned short)elsize, elsize);
3018 *typestring_offset += 2;
3019 }
3020
3021 if (length_is)
3022 *typestring_offset
3024 type, length_is);
3025
3028 {
3029 print_file(file, 2, "0x%x,\t/* FC_PP */\n", FC_PP);
3030 print_file(file, 2, "0x%x,\t/* FC_PAD */\n", FC_PAD);
3031 *typestring_offset += 2;
3032 write_pointer_description(file, is_string_type(attrs, type) ? attrs : NULL, type, typestring_offset);
3033 print_file(file, 2, "0x%x,\t/* FC_END */\n", FC_END);
3034 *typestring_offset += 1;
3035 }
3036
3037 write_array_element_type(file, is_string_type(attrs, type) ? attrs : NULL, type, FALSE, typestring_offset);
3038 write_end(file, typestring_offset);
3039 }
3040 else
3041 {
3042 unsigned int dim = size_is ? 0 : type_array_get_dim(type);
3043 print_file(file, 2, "NdrFcShort(0x%hx),\t/* %u */\n", (unsigned short)dim, dim);
3044 *typestring_offset += 2;
3045 *typestring_offset
3047 type, size_is);
3048 *typestring_offset
3050 type, length_is);
3051
3052 write_array_element_type(file, is_string_type(attrs, type) ? attrs : NULL, type, TRUE, typestring_offset);
3053 write_end(file, typestring_offset);
3054 }
3055
3056 return start_offset;
3057}
3058
3060{
3062 const var_t *last_field;
3063 const type_t *ft;
3064
3065 if (!fields || list_empty(fields))
3066 return NULL;
3067
3068 last_field = LIST_ENTRY( list_tail(fields), const var_t, entry );
3069 ft = last_field->type;
3070
3072 return last_field;
3073
3074 if (type_get_type(ft) == TYPE_STRUCT)
3076 else
3077 return NULL;
3078}
3079
3081 int is_complex, unsigned int *corroff,
3082 unsigned int *typestring_offset)
3083{
3084 const var_t *field;
3085 unsigned short offset = 0;
3086 unsigned int salign = 1;
3087 int padding;
3089
3091 {
3092 type_t *ft = field->type;
3093 unsigned int align = 0;
3094 unsigned int size = type_memsize_and_alignment(ft, &align);
3096 if (salign < align) salign = align;
3097
3099 {
3100 if ((align - 1) & offset)
3101 {
3102 unsigned char fc = 0;
3103 switch (align)
3104 {
3105 case 2:
3106 fc = FC_ALIGNM2;
3107 break;
3108 case 4:
3109 fc = FC_ALIGNM4;
3110 break;
3111 case 8:
3112 fc = FC_ALIGNM8;
3113 break;
3114 default:
3115 error("write_struct_members: cannot align type %d\n", type_get_type(ft));
3116 }
3117 print_file(file, 2, "0x%x,\t/* %s */\n", fc, string_of_type(fc));
3119 *typestring_offset += 1;
3120 }
3121 write_member_type(file, type, is_complex, field->attrs, field->type, corroff,
3122 typestring_offset);
3123 offset += size;
3124 }
3125 }
3126
3127 padding = ROUNDING(offset, salign);
3128 if (padding)
3129 {
3130 print_file(file, 2, "0x%x,\t/* FC_STRUCTPAD%d */\n",
3131 FC_STRUCTPAD1 + padding - 1,
3132 padding);
3133 *typestring_offset += 1;
3134 }
3135
3136 write_end(file, typestring_offset);
3137}
3138
3139static unsigned int write_struct_tfs(FILE *file, type_t *type,
3140 const char *name, unsigned int *tfsoff)
3141{
3142 const type_t *save_current_structure = current_structure;
3143 unsigned int total_size;
3144 const var_t *array;
3145 unsigned int start_offset;
3146 unsigned int align;
3147 unsigned int corroff;
3148 var_t *f;
3149 unsigned char fc = get_struct_fc(type);
3151
3152 if (processed(type)) return type->typestring_offset;
3153
3154 guard_rec(type);
3156
3157 total_size = type_memsize(type);
3159 if (total_size > USHRT_MAX)
3160 error("structure size for %s exceeds %d bytes by %d bytes\n",
3161 name, USHRT_MAX, total_size - USHRT_MAX);
3162
3164 write_embedded_types(file, f->attrs, f->type, f->name, FALSE, tfsoff);
3165
3167 if (array && !processed(array->type))
3168 {
3169 if(is_string_type(array->attrs, array->type))
3170 write_string_tfs(file, array->attrs, array->type, TYPE_CONTEXT_CONTAINER, array->name, tfsoff);
3171 else
3172 write_array_tfs(file, array->attrs, array->type, array->name, tfsoff);
3173 }
3174
3175 corroff = *tfsoff;
3176 write_descriptors(file, type, tfsoff);
3177
3178 start_offset = *tfsoff;
3179 update_tfsoff(type, start_offset, file);
3180 print_start_tfs_comment(file, type, start_offset);
3181 print_file(file, 2, "0x%x,\t/* %s */\n", fc, string_of_type(fc));
3182 print_file(file, 2, "0x%x,\t/* %d */\n", align - 1, align - 1);
3183 print_file(file, 2, "NdrFcShort(0x%hx),\t/* %d */\n", (unsigned short)total_size, total_size);
3184 *tfsoff += 4;
3185
3186 if (array)
3187 {
3188 unsigned int absoff = array->type->typestring_offset;
3189 short reloff = absoff - *tfsoff;
3190 print_file(file, 2, "NdrFcShort(0x%hx),\t/* Offset= %hd (%u) */\n",
3191 reloff, reloff, absoff);
3192 *tfsoff += 2;
3193 }
3194 else if (fc == FC_BOGUS_STRUCT)
3195 {
3196 print_file(file, 2, "NdrFcShort(0x0),\n");
3197 *tfsoff += 2;
3198 }
3199
3200 if (fc == FC_BOGUS_STRUCT)
3201 {
3202 /* On the sizing pass, type->ptrdesc may be zero, but it's ok as
3203 nothing is written to file yet. On the actual writing pass,
3204 this will have been updated. */
3205 unsigned int absoff = type->ptrdesc ? type->ptrdesc : *tfsoff;
3206 int reloff = absoff - *tfsoff;
3207 assert( reloff >= 0 );
3208 print_file(file, 2, "NdrFcShort(0x%hx),\t/* Offset= %d (%u) */\n",
3209 (unsigned short)reloff, reloff, absoff);
3210 *tfsoff += 2;
3211 }
3212 else if ((fc == FC_PSTRUCT) ||
3213 (fc == FC_CPSTRUCT) ||
3215 {
3216 print_file(file, 2, "0x%x,\t/* FC_PP */\n", FC_PP);
3217 print_file(file, 2, "0x%x,\t/* FC_PAD */\n", FC_PAD);
3218 *tfsoff += 2;
3220 print_file(file, 2, "0x%x,\t/* FC_END */\n", FC_END);
3221 *tfsoff += 1;
3222 }
3223
3225 tfsoff);
3226
3227 if (fc == FC_BOGUS_STRUCT)
3228 {
3229 const var_t *f;
3230
3231 type->ptrdesc = *tfsoff;
3233 {
3234 type_t *ft = f->type;
3236 {
3237 case TGT_POINTER:
3238 if (is_string_type(f->attrs, ft))
3239 write_string_tfs(file, f->attrs, ft, TYPE_CONTEXT_CONTAINER, f->name, tfsoff);
3240 else
3241 write_pointer_tfs(file, f->attrs, ft,
3242 type_pointer_get_ref(ft)->typestring_offset,
3243 TYPE_CONTEXT_CONTAINER, tfsoff);
3244 break;
3245 case TGT_ARRAY:
3247 {
3248 unsigned int offset;
3249
3250 print_file(file, 0, "/* %d */\n", *tfsoff);
3251
3253 /* skip over the pointer that is written for strings, since a
3254 * pointer has to be written in-place here */
3255 if (is_string_type(f->attrs, ft))
3256 offset += 4;
3258 }
3259 break;
3260 default:
3261 break;
3262 }
3263 }
3264 if (type->ptrdesc == *tfsoff)
3265 type->ptrdesc = 0;
3266 }
3267
3268 current_structure = save_current_structure;
3269 return start_offset;
3270}
3271
3272static void write_branch_type(FILE *file, const type_t *t, unsigned int *tfsoff)
3273{
3274 if (t == NULL)
3275 {
3276 print_file(file, 2, "NdrFcShort(0x0),\t/* No type */\n");
3277 }
3278 else
3279 {
3281 {
3282 unsigned char fc;
3283 if (type_get_type(t) == TYPE_BASIC)
3284 fc = get_basic_fc(t);
3285 else
3286 fc = get_enum_fc(t);
3287 print_file(file, 2, "NdrFcShort(0x80%02x),\t/* Simple arm type: %s */\n",
3288 fc, string_of_type(fc));
3289 }
3290 else if (t->typestring_offset)
3291 {
3292 short reloff = t->typestring_offset - *tfsoff;
3293 print_file(file, 2, "NdrFcShort(0x%hx),\t/* Offset= %d (%d) */\n",
3294 reloff, reloff, t->typestring_offset);
3295 }
3296 else
3297 error("write_branch_type: type unimplemented %d\n", type_get_type(t));
3298 }
3299
3300 *tfsoff += 2;
3301}
3302
3303static unsigned int write_union_tfs(FILE *file, const attr_list_t *attrs,
3304 type_t *type, unsigned int *tfsoff)
3305{
3306 unsigned int start_offset;
3307 unsigned int size;
3309 unsigned int nbranch = 0;
3310 type_t *deftype = NULL;
3311 short nodeftype = 0xffff;
3312 unsigned int dummy;
3313 var_t *f;
3314
3315 if (processed(type) &&
3317 return type->typestring_offset;
3318
3319 guard_rec(type);
3320
3322
3324
3326 {
3327 expr_list_t *cases = get_attrp(f->attrs, ATTR_CASE);
3328 if (cases)
3329 nbranch += list_count(cases);
3330 if (f->type)
3331 write_embedded_types(file, f->attrs, f->type, f->name, TRUE, tfsoff);
3332 }
3333
3334 start_offset = *tfsoff;
3335 update_tfsoff(type, start_offset, file);
3336 print_start_tfs_comment(file, type, start_offset);
3338 {
3340 const type_t *st = sv->type;
3341 unsigned int align = 0;
3342 unsigned char fc;
3343
3344 if (type_get_type(st) == TYPE_BASIC)
3345 {
3346 fc = get_basic_fc(st);
3347 switch (fc)
3348 {
3349 case FC_CHAR:
3350 case FC_SMALL:
3351 case FC_BYTE:
3352 case FC_USMALL:
3353 case FC_WCHAR:
3354 case FC_SHORT:
3355 case FC_USHORT:
3356 case FC_LONG:
3357 case FC_ULONG:
3358 break;
3359 default:
3360 fc = 0;
3361 error("union switch type must be an integer, char, or enum\n");
3362 }
3363 }
3364 else if (type_get_type(st) == TYPE_ENUM)
3365 fc = get_enum_fc(st);
3366 else
3367 error("union switch type must be an integer, char, or enum\n");
3368
3371 {
3372 if (f->type)
3374 }
3375
3376 print_file(file, 2, "0x%x,\t/* FC_ENCAPSULATED_UNION */\n", FC_ENCAPSULATED_UNION);
3377 print_file(file, 2, "0x%x,\t/* Switch type= %s */\n",
3378 (align << 4) | fc, string_of_type(fc));
3379 *tfsoff += 2;
3380 }
3381 else if (is_attr(type->attrs, ATTR_SWITCHTYPE))
3382 {
3383 const expr_t *switch_is = get_attrp(attrs, ATTR_SWITCHIS);
3384 const type_t *st = get_attrp(type->attrs, ATTR_SWITCHTYPE);
3385 unsigned char fc;
3386
3387 if (type_get_type(st) == TYPE_BASIC)
3388 {
3389 fc = get_basic_fc(st);
3390 switch (fc)
3391 {
3392 case FC_CHAR:
3393 case FC_SMALL:
3394 case FC_USMALL:
3395 case FC_SHORT:
3396 case FC_USHORT:
3397 case FC_LONG:
3398 case FC_ULONG:
3399 case FC_ENUM16:
3400 case FC_ENUM32:
3401 break;
3402 default:
3403 fc = 0;
3404 error("union switch type must be an integer, char, or enum\n");
3405 }
3406 }
3407 else if (type_get_type(st) == TYPE_ENUM)
3408 fc = get_enum_fc(st);
3409 else
3410 error("union switch type must be an integer, char, or enum\n");
3411
3412 print_file(file, 2, "0x%x,\t/* FC_NON_ENCAPSULATED_UNION */\n", FC_NON_ENCAPSULATED_UNION);
3413 print_file(file, 2, "0x%x,\t/* Switch type= %s */\n",
3414 fc, string_of_type(fc));
3415 *tfsoff += 2;
3416 *tfsoff += write_conf_or_var_desc(file, current_structure, 0, st, switch_is );
3417 print_file(file, 2, "NdrFcShort(0x2),\t/* Offset= 2 (%u) */\n", *tfsoff + 2);
3418 *tfsoff += 2;
3419 print_file(file, 0, "/* %u */\n", *tfsoff);
3420 }
3421
3422 print_file(file, 2, "NdrFcShort(0x%hx),\t/* %d */\n", (unsigned short)size, size);
3423 print_file(file, 2, "NdrFcShort(0x%hx),\t/* %d */\n", (unsigned short)nbranch, nbranch);
3424 *tfsoff += 4;
3425
3427 {
3428 type_t *ft = f->type;
3429 expr_list_t *cases = get_attrp(f->attrs, ATTR_CASE);
3430 int deflt = is_attr(f->attrs, ATTR_DEFAULT);
3431 expr_t *c;
3432
3433 if (cases == NULL && !deflt)
3434 error("union field %s with neither case nor default attribute\n", f->name);
3435
3436 if (cases) LIST_FOR_EACH_ENTRY(c, cases, expr_t, entry)
3437 {
3438 /* MIDL doesn't check for duplicate cases, even though that seems
3439 like a reasonable thing to do, it just dumps them to the TFS
3440 like we're going to do here. */
3441 print_file(file, 2, "NdrFcLong(0x%x),\t/* %d */\n", c->cval, c->cval);
3442 *tfsoff += 4;
3443 write_branch_type(file, ft, tfsoff);
3444 }
3445
3446 /* MIDL allows multiple default branches, even though that seems
3447 illogical, it just chooses the last one, which is what we will
3448 do. */
3449 if (deflt)
3450 {
3451 deftype = ft;
3452 nodeftype = 0;
3453 }
3454 }
3455
3456 if (deftype)
3457 {
3458 write_branch_type(file, deftype, tfsoff);
3459 }
3460 else
3461 {
3462 print_file(file, 2, "NdrFcShort(0x%hx),\n", nodeftype);
3463 *tfsoff += 2;
3464 }
3465
3466 return start_offset;
3467}
3468
3469static unsigned int write_ip_tfs(FILE *file, const attr_list_t *attrs, type_t *type,
3470 unsigned int *typeformat_offset)
3471{
3472 unsigned int i;
3473 unsigned int start_offset = *typeformat_offset;
3474 expr_t *iid = get_attrp(attrs, ATTR_IIDIS);
3475
3476 if (!iid && processed(type)) return type->typestring_offset;
3477
3478 print_start_tfs_comment(file, type, start_offset);
3479 update_tfsoff(type, start_offset, file);
3480
3481 if (iid)
3482 {
3483 print_file(file, 2, "0x2f, /* FC_IP */\n");
3484 print_file(file, 2, "0x5c, /* FC_PAD */\n");
3485 *typeformat_offset
3487 }
3488 else
3489 {
3491 const UUID *uuid = get_attrp(base->attrs, ATTR_UUID);
3492
3493 if (! uuid)
3494 error("%s: interface %s missing UUID\n", __FUNCTION__, base->name);
3495
3496 print_file(file, 2, "0x2f,\t/* FC_IP */\n");
3497 print_file(file, 2, "0x5a,\t/* FC_CONSTANT_IID */\n");
3498 print_file(file, 2, "NdrFcLong(0x%08x),\n", uuid->Data1);
3499 print_file(file, 2, "NdrFcShort(0x%04x),\n", uuid->Data2);
3500 print_file(file, 2, "NdrFcShort(0x%04x),\n", uuid->Data3);
3501 for (i = 0; i < 8; ++i)
3502 print_file(file, 2, "0x%02x,\n", uuid->Data4[i]);
3503
3504 if (file)
3505 fprintf(file, "\n");
3506
3507 *typeformat_offset += 18;
3508 }
3509 return start_offset;
3510}
3511
3512static unsigned int write_contexthandle_tfs(FILE *file,
3513 const attr_list_t *attrs,
3514 type_t *type,
3515 int toplevel_param,
3516 unsigned int *typeformat_offset)
3517{
3518 unsigned int start_offset = *typeformat_offset;
3519 unsigned char flags = get_contexthandle_flags( current_iface, attrs, type );
3520
3521 print_start_tfs_comment(file, type, start_offset);
3522
3523 if (flags & 0x80) /* via ptr */
3524 {
3525 int pointer_type = get_pointer_fc( type, attrs, toplevel_param );
3526 if (!pointer_type) pointer_type = FC_RP;
3527 *typeformat_offset += 4;
3528 print_file(file, 2,"0x%x, 0x0,\t/* %s */\n", pointer_type, string_of_type(pointer_type) );
3529 print_file(file, 2, "NdrFcShort(0x2),\t /* Offset= 2 (%u) */\n", *typeformat_offset);
3530 print_file(file, 0, "/* %2u */\n", *typeformat_offset);
3531 }
3532
3533 print_file(file, 2, "0x%02x,\t/* FC_BIND_CONTEXT */\n", FC_BIND_CONTEXT);
3534 print_file(file, 2, "0x%x,\t/* Context flags: ", flags);
3535 /* return and can't be null values overlap */
3536 if (((flags & 0x21) != 0x21) && (flags & NDR_CONTEXT_HANDLE_CANNOT_BE_NULL))
3537 print_file(file, 0, "can't be null, ");
3539 print_file(file, 0, "serialize, ");
3541 print_file(file, 0, "no serialize, ");
3543 print_file(file, 0, "strict, ");
3544 if ((flags & 0x21) == 0x20)
3545 print_file(file, 0, "out, ");
3546 if ((flags & 0x21) == 0x21)
3547 print_file(file, 0, "return, ");
3548 if (flags & 0x40)
3549 print_file(file, 0, "in, ");
3550 if (flags & 0x80)
3551 print_file(file, 0, "via ptr, ");
3552 print_file(file, 0, "*/\n");
3553 print_file(file, 2, "0x%x,\t/* rundown routine */\n", get_context_handle_offset( type ));
3554 print_file(file, 2, "0, /* FIXME: param num */\n");
3555 *typeformat_offset += 4;
3556
3557 update_tfsoff( type, start_offset, file );
3558 return start_offset;
3559}
3560
3561static unsigned int write_range_tfs(FILE *file, const attr_list_t *attrs,
3562 type_t *type, expr_list_t *range_list,
3563 unsigned int *typeformat_offset)
3564{
3565 unsigned char fc;
3566 unsigned int start_offset = *typeformat_offset;
3567 const expr_t *range_min = LIST_ENTRY(list_head(range_list), const expr_t, entry);
3568 const expr_t *range_max = LIST_ENTRY(list_next(range_list, list_head(range_list)), const expr_t, entry);
3569
3571 fc = get_basic_fc(type);
3572 else
3573 fc = get_enum_fc(type);
3574
3575 /* fc must fit in lower 4-bits of 8-bit field below */
3576 assert(fc <= 0xf);
3577
3578 print_file(file, 0, "/* %u */\n", *typeformat_offset);
3579 print_file(file, 2, "0x%x,\t/* FC_RANGE */\n", FC_RANGE);
3580 print_file(file, 2, "0x%x,\t/* %s */\n", fc, string_of_type(fc));
3581 print_file(file, 2, "NdrFcLong(0x%x),\t/* %u */\n", range_min->cval, range_min->cval);
3582 print_file(file, 2, "NdrFcLong(0x%x),\t/* %u */\n", range_max->cval, range_max->cval);
3583 update_tfsoff( type, start_offset, file );
3584 *typeformat_offset += 10;
3585
3586 return start_offset;
3587}
3588
3589static unsigned int write_type_tfs(FILE *file, int indent,
3590 const attr_list_t *attrs, type_t *type,
3591 const char *name,
3592 enum type_context context,
3593 unsigned int *typeformat_offset)
3594{
3595 unsigned int offset;
3596
3597 switch (typegen_detect_type(type, attrs, TDT_ALL_TYPES))
3598 {
3599 case TGT_CTXT_HANDLE:
3601 return write_contexthandle_tfs(file, attrs, type,
3602 context == TYPE_CONTEXT_TOPLEVELPARAM, typeformat_offset);
3603 case TGT_USER_TYPE:
3604 return write_user_tfs(file, type, typeformat_offset);
3605 case TGT_STRING:
3606 return write_string_tfs(file, attrs, type, context, name, typeformat_offset);
3607 case TGT_ARRAY:
3608 {
3609 unsigned int off;
3610 /* conformant and pointer arrays are handled specially */
3614 off = write_array_tfs(file, attrs, type, name, typeformat_offset);
3615 else
3616 off = 0;
3619 {
3620 int ptr_type;
3621 ptr_type = get_pointer_fc(type, attrs,
3623 if (ptr_type != FC_RP || type_array_is_decl_as_ptr(type))
3624 {
3625 unsigned int absoff = type->typestring_offset;
3626 short reloff = absoff - (*typeformat_offset + 2);
3627 off = *typeformat_offset;
3628 print_file(file, 0, "/* %d */\n", off);
3629 print_file(file, 2, "0x%x, 0x0,\t/* %s */\n", ptr_type,
3630 string_of_type(ptr_type));
3631 print_file(file, 2, "NdrFcShort(0x%hx),\t/* Offset= %hd (%u) */\n",
3632 reloff, reloff, absoff);
3633 if (ptr_type != FC_RP) update_tfsoff( type, off, file );
3634 *typeformat_offset += 4;
3635 }
3636 type->details.array.ptr_tfsoff = off;
3637 }
3638 return off;
3639 }
3640 case TGT_STRUCT:
3641 return write_struct_tfs(file, type, name, typeformat_offset);
3642 case TGT_UNION:
3643 return write_union_tfs(file, attrs, type, typeformat_offset);
3644 case TGT_ENUM:
3645 case TGT_BASIC:
3646 /* nothing to do */
3647 return 0;
3648 case TGT_RANGE:
3649 {
3650 expr_list_t *range_list = get_attrp(attrs, ATTR_RANGE);
3651 if (!range_list)
3652 range_list = get_aliaschain_attrp(type, ATTR_RANGE);
3653 return write_range_tfs(file, attrs, type, range_list, typeformat_offset);
3654 }
3655 case TGT_IFACE_POINTER:
3656 return write_ip_tfs(file, attrs, type, typeformat_offset);
3657 case TGT_POINTER:
3658 {
3659 enum type_context ref_context;
3660 unsigned int toplevel_offset = *typeformat_offset;
3662
3664 ref_context = TYPE_CONTEXT_PARAM;
3666 ref_context = TYPE_CONTEXT_CONTAINER;
3667 else
3668 ref_context = context;
3669
3670 if (is_string_type(attrs, ref))
3671 {
3673 write_pointer_tfs(file, attrs, type, *typeformat_offset + 4, context, typeformat_offset);
3674
3675 offset = write_type_tfs(file, indent, attrs, ref, name, ref_context, typeformat_offset);
3677 return 0;
3678 return (context == TYPE_CONTEXT_TOPLEVELPARAM) ? toplevel_offset : offset;
3679 }
3680
3682 ref_context, typeformat_offset);
3684 return 0;
3685 return write_pointer_tfs(file, attrs, type, offset, context, typeformat_offset);
3686 }
3687 case TGT_INVALID:
3688 break;
3689 }
3690 error("invalid type %s for var %s\n", type->name, name);
3691 return 0;
3692}
3693
3695 const char *name, int write_ptr, unsigned int *tfsoff)
3696{
3697 return write_type_tfs(file, 2, attrs, type, name, write_ptr ? TYPE_CONTEXT_CONTAINER : TYPE_CONTEXT_CONTAINER_NO_POINTERS, tfsoff);
3698}
3699
3700static void process_tfs_iface(type_t *iface, FILE *file, int indent, unsigned int *offset)
3701{
3703 const statement_t *stmt;
3704 var_t *var;
3705
3707 if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, statement_t, entry )
3708 {
3709 switch(stmt->type)
3710 {
3711 case STMT_DECLARATION:
3712 {
3713 const var_t *func = stmt->u.var;
3714
3715 if(stmt->u.var->stgclass != STG_NONE
3717 continue;
3718
3720 if (is_local(func->attrs)) continue;
3721
3723 if (!is_void(var->type))
3724 var->typestring_offset = write_type_tfs( file, 2, func->attrs, var->type, func->name,
3726
3727 if (type_get_function_args(func->type))
3729 var->typestring_offset = write_type_tfs( file, 2, var->attrs, var->type, var->name,
3731 break;
3732
3733 }
3734 case STMT_TYPEDEF:
3735 {
3736 const type_list_t *type_entry;
3737 for (type_entry = stmt->u.type_list; type_entry; type_entry = type_entry->next)
3738 {
3739 if (is_attr(type_entry->type->attrs, ATTR_ENCODE)
3740 || is_attr(type_entry->type->attrs, ATTR_DECODE))
3741 type_entry->type->typestring_offset = write_type_tfs( file, 2,
3742 type_entry->type->attrs, type_entry->type, type_entry->type->name,
3744 }
3745 break;
3746 }
3747 default:
3748 break;
3749 }
3750 }
3751}
3752
3753static unsigned int process_tfs(FILE *file, const statement_list_t *stmts, type_pred_t pred)
3754{
3755 unsigned int typeformat_offset = 2;
3756 for_each_iface(stmts, process_tfs_iface, pred, file, 0, &typeformat_offset);
3757 return typeformat_offset + 1;
3758}
3759
3760
3762{
3763 int indent = 0;
3764
3765 print_file(file, indent, "static const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString =\n");
3766 print_file(file, indent, "{\n");
3767 indent++;
3768 print_file(file, indent, "0,\n");
3769 print_file(file, indent, "{\n");
3770 indent++;
3771 print_file(file, indent, "NdrFcShort(0x0),\n");
3772
3774 process_tfs(file, stmts, pred);
3775
3776 print_file(file, indent, "0x0\n");
3777 indent--;
3778 print_file(file, indent, "}\n");
3779 indent--;
3780 print_file(file, indent, "};\n");
3781 print_file(file, indent, "\n");
3782}
3783
3785 const type_t *type, const char *name, const attr_list_t *attrs, int toplevel_param, unsigned int *alignment)
3786{
3787 *alignment = 0;
3789 {
3790 case TGT_USER_TYPE:
3791 {
3792 const char *uname = NULL;
3793 const type_t *utype = get_user_type(type, &uname);
3794 return get_required_buffer_size_type(utype, uname, NULL, FALSE, alignment);
3795 }
3796 case TGT_BASIC:
3797 switch (get_basic_fc(type))
3798 {
3799 case FC_BYTE:
3800 case FC_CHAR:
3801 case FC_USMALL:
3802 case FC_SMALL:
3803 *alignment = 4;
3804 return 1;
3805
3806 case FC_WCHAR:
3807 case FC_USHORT:
3808 case FC_SHORT:
3809 *alignment = 4;
3810 return 2;
3811
3812 case FC_ULONG:
3813 case FC_LONG:
3814 case FC_FLOAT:
3815 case FC_ERROR_STATUS_T:
3816 *alignment = 4;
3817 return 4;
3818
3819 case FC_HYPER:
3820 case FC_DOUBLE:
3821 *alignment = 8;
3822 return 8;
3823
3824 case FC_INT3264:
3825 case FC_UINT3264:
3827 *alignment = pointer_size;
3828 return pointer_size;
3829
3830 case FC_IGNORE:
3831 case FC_BIND_PRIMITIVE:
3832 return 0;
3833
3834 default:
3835 error("get_required_buffer_size: unknown basic type 0x%02x\n",
3837 return 0;
3838 }
3839 break;
3840
3841 case TGT_ENUM:
3842 switch (get_enum_fc(type))
3843 {
3844 case FC_ENUM32:
3845 *alignment = 4;
3846 return 4;
3847 case FC_ENUM16:
3848 *alignment = 4;
3849 return 2;
3850 }
3851 break;
3852
3853 case TGT_STRUCT:
3855 {
3856 if (!type_struct_get_fields(type)) return 0;
3857 return fields_memsize(type_struct_get_fields(type), alignment);
3858 }
3859 break;
3860
3861 case TGT_POINTER:
3862 {
3863 unsigned int size, align;
3865 if (is_string_type( attrs, ref )) break;
3866 if (!(size = get_required_buffer_size_type( ref, name, NULL, FALSE, &align ))) break;
3867 if (get_pointer_fc(type, attrs, toplevel_param) != FC_RP)
3868 {
3869 size += 4 + align;
3870 align = 4;
3871 }
3872 *alignment = align;
3873 return size;
3874 }
3875
3876 case TGT_ARRAY:
3877 if (get_pointer_fc(type, attrs, toplevel_param) == FC_RP)
3878 {
3879 switch (get_array_fc(type))
3880 {
3881 case FC_SMFARRAY:
3882 case FC_LGFARRAY:
3883 return type_array_get_dim(type) *
3885 NULL, FALSE, alignment);
3886 }
3887 }
3888 break;
3889
3890 default:
3891 break;
3892 }
3893 return 0;
3894}
3895
3896static unsigned int get_required_buffer_size(const var_t *var, unsigned int *alignment, enum pass pass)
3897{
3898 int in_attr = is_attr(var->attrs, ATTR_IN);
3899 int out_attr = is_attr(var->attrs, ATTR_OUT);
3900
3901 if (!in_attr && !out_attr)
3902 in_attr = 1;
3903
3904 *alignment = 0;
3905
3906 if ((pass == PASS_IN && in_attr) || (pass == PASS_OUT && out_attr) ||
3907 pass == PASS_RETURN)
3908 {
3910 {
3911 *alignment = 4;
3912 return 20;
3913 }
3914
3915 if (!is_string_type(var->attrs, var->type))
3916 return get_required_buffer_size_type(var->type, var->name,
3917 var->attrs, TRUE, alignment);
3918 }
3919 return 0;
3920}
3921
3922static unsigned int get_function_buffer_size( const var_t *func, enum pass pass )
3923{
3924 const var_t *var;
3925 unsigned int total_size = 0, alignment;
3926
3927 if (type_get_function_args(func->type))
3928 {
3930 {
3931 total_size += get_required_buffer_size(var, &alignment, pass);
3932 total_size += alignment;
3933 }
3934 }
3935
3937 {
3938 var_t v = *func;
3939 v.type = type_function_get_rettype(func->type);
3940 total_size += get_required_buffer_size(&v, &alignment, PASS_RETURN);
3941 total_size += alignment;
3942 }
3943 return total_size;
3944}
3945
3946static void print_phase_function(FILE *file, int indent, const char *type,
3947 const char *local_var_prefix, enum remoting_phase phase,
3948 const var_t *var, unsigned int type_offset)
3949{
3950 const char *function;
3951 switch (phase)
3952 {
3953 case PHASE_BUFFERSIZE:
3954 function = "BufferSize";
3955 break;
3956 case PHASE_MARSHAL:
3957 function = "Marshall";
3958 break;
3959 case PHASE_UNMARSHAL:
3960 function = "Unmarshall";
3961 break;
3962 case PHASE_FREE:
3963 function = "Free";
3964 break;
3965 default:
3966 assert(0);
3967 return;
3968 }
3969
3970 print_file(file, indent, "Ndr%s%s(\n", type, function);
3971 indent++;
3972 print_file(file, indent, "&__frame->_StubMsg,\n");
3973 print_file(file, indent, "%s%s%s%s%s,\n",
3974 (phase == PHASE_UNMARSHAL) ? "(unsigned char **)" : "(unsigned char *)",
3975 (phase == PHASE_UNMARSHAL || decl_indirect(var->type)) ? "&" : "",
3976 local_var_prefix,
3977 (phase == PHASE_UNMARSHAL && decl_indirect(var->type)) ? "_p_" : "",
3978 var->name);
3979 print_file(file, indent, "(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%d]%s\n",
3980 type_offset, (phase == PHASE_UNMARSHAL) ? "," : ");");
3981 if (phase == PHASE_UNMARSHAL)
3982 print_file(file, indent, "0);\n");
3983 indent--;
3984}
3985
3986void print_phase_basetype(FILE *file, int indent, const char *local_var_prefix,
3987 enum remoting_phase phase, enum pass pass, const var_t *var,
3988 const char *varname)
3989{
3990 type_t *type = var->type;
3991 unsigned int alignment = 0;
3992
3993 /* no work to do for other phases, buffer sizing is done elsewhere */
3994 if (phase != PHASE_MARSHAL && phase != PHASE_UNMARSHAL)
3995 return;
3996
3997 if (type_get_type(type) == TYPE_ENUM ||
4000 pointer_size != 4))
4001 {
4002 unsigned char fc;
4003
4005 fc = get_enum_fc(type);
4006 else
4007 fc = get_basic_fc(type);
4008
4009 if (phase == PHASE_MARSHAL)
4010 print_file(file, indent, "NdrSimpleTypeMarshall(\n");
4011 else
4012 print_file(file, indent, "NdrSimpleTypeUnmarshall(\n");
4013 print_file(file, indent+1, "&__frame->_StubMsg,\n");
4014 print_file(file, indent+1, "(unsigned char *)&%s%s,\n",
4015 local_var_prefix,
4016 var->name);
4017 print_file(file, indent+1, "0x%02x /* %s */);\n", fc, string_of_type(fc));
4018 }
4019 else
4020 {
4022 switch (get_basic_fc(ref))
4023 {
4024 case FC_BYTE:
4025 case FC_CHAR:
4026 case FC_SMALL:
4027 case FC_USMALL:
4028 alignment = 1;
4029 break;
4030
4031 case FC_WCHAR:
4032 case FC_USHORT:
4033 case FC_SHORT:
4034 alignment = 2;
4035 break;
4036
4037 case FC_ULONG:
4038 case FC_LONG:
4039 case FC_FLOAT:
4040 case FC_ERROR_STATUS_T:
4041 /* pointer_size must be 4 if we got here in these two cases */
4042 case FC_INT3264:
4043 case FC_UINT3264:
4044 alignment = 4;
4045 break;
4046
4047 case FC_HYPER:
4048 case FC_DOUBLE:
4049 alignment = 8;
4050 break;
4051
4052 case FC_IGNORE:
4053 case FC_BIND_PRIMITIVE:
4054 /* no marshalling needed */
4055 return;
4056
4057 default:
4058 error("print_phase_basetype: Unsupported type: %s (0x%02x, ptr_level: 0)\n",
4059 var->name, get_basic_fc(ref));
4060 }
4061
4062 if (phase == PHASE_MARSHAL && alignment > 1)
4063 print_file(file, indent, "MIDL_memset(__frame->_StubMsg.Buffer, 0, (0x%x - (ULONG_PTR)__frame->_StubMsg.Buffer) & 0x%x);\n", alignment, alignment - 1);
4064 print_file(file, indent, "__frame->_StubMsg.Buffer = (unsigned char *)(((ULONG_PTR)__frame->_StubMsg.Buffer + %u) & ~0x%x);\n",
4065 alignment - 1, alignment - 1);
4066
4067 if (phase == PHASE_MARSHAL)
4068 {
4069 print_file(file, indent, "*(");
4071 if (is_ptr(type))
4072 fprintf(file, " *)__frame->_StubMsg.Buffer = *");
4073 else
4074 fprintf(file, " *)__frame->_StubMsg.Buffer = ");
4075 fprintf(file, "%s%s", local_var_prefix, varname);
4076 fprintf(file, ";\n");
4077 }
4078 else if (phase == PHASE_UNMARSHAL)
4079 {
4080 print_file(file, indent, "if (__frame->_StubMsg.Buffer + sizeof(");
4082 fprintf(file, ") > __frame->_StubMsg.BufferEnd)\n");
4083 print_file(file, indent, "{\n");
4084 print_file(file, indent + 1, "RpcRaiseException(RPC_X_BAD_STUB_DATA);\n");
4085 print_file(file, indent, "}\n");
4086 print_file(file, indent, "%s%s%s",
4087 (pass == PASS_IN || pass == PASS_RETURN) ? "" : "*",
4088 local_var_prefix, varname);
4089 if (pass == PASS_IN && is_ptr(type))
4090 fprintf(file, " = (");
4091 else
4092 fprintf(file, " = *(");
4094 fprintf(file, " *)__frame->_StubMsg.Buffer;\n");
4095 }
4096
4097 print_file(file, indent, "__frame->_StubMsg.Buffer += sizeof(");
4099 fprintf(file, ");\n");
4100 }
4101}
4102
4103/* returns whether the MaxCount, Offset or ActualCount members need to be
4104 * filled in for the specified phase */
4106{
4107 return (phase != PHASE_UNMARSHAL);
4108}
4109
4110expr_t *get_size_is_expr(const type_t *t, const char *name)
4111{
4112 expr_t *x = NULL;
4113
4114 for ( ; is_array(t); t = type_array_get_element(t))
4117 {
4118 if (!x)
4120 else
4121 error("%s: multidimensional conformant"
4122 " arrays not supported at the top level\n",
4123 name);
4124 }
4125
4126 return x;
4127}
4128
4129void write_parameter_conf_or_var_exprs(FILE *file, int indent, const char *local_var_prefix,
4130 enum remoting_phase phase, const var_t *var, int valid_variance)
4131{
4132 const type_t *type = var->type;
4133 /* get fundamental type for the argument */
4134 for (;;)
4135 {
4137 {
4138 case TGT_ARRAY:
4140 {
4143 {
4144 print_file(file, indent, "__frame->_StubMsg.MaxCount = (ULONG_PTR)");
4145 write_expr(file, type_array_get_conformance(type), 1, 1, NULL, NULL, local_var_prefix);
4146 fprintf(file, ";\n\n");
4147 }
4149 {
4150 print_file(file, indent, "__frame->_StubMsg.Offset = 0;\n"); /* FIXME */
4151 if (valid_variance)
4152 {
4153 print_file(file, indent, "__frame->_StubMsg.ActualCount = (ULONG_PTR)");
4154 write_expr(file, type_array_get_variance(type), 1, 1, NULL, NULL, local_var_prefix);
4155 fprintf(file, ";\n\n");
4156 }
4157 else
4158 print_file(file, indent, "__frame->_StubMsg.ActualCount = __frame->_StubMsg.MaxCount;\n\n");
4159 }
4160 }
4161 break;
4162 case TGT_UNION:
4163 if (type_get_type(type) == TYPE_UNION &&
4165 {
4166 print_file(file, indent, "__frame->_StubMsg.MaxCount = (ULONG_PTR)");
4167 write_expr(file, get_attrp(var->attrs, ATTR_SWITCHIS), 1, 1, NULL, NULL, local_var_prefix);
4168 fprintf(file, ";\n\n");
4169 }
4170 break;
4171 case TGT_IFACE_POINTER:
4172 {
4173 expr_t *iid;
4174
4175 if (is_conformance_needed_for_phase(phase) && (iid = get_attrp( var->attrs, ATTR_IIDIS )))
4176 {
4177 print_file( file, indent, "__frame->_StubMsg.MaxCount = (ULONG_PTR) " );
4178 write_expr( file, iid, 1, 1, NULL, NULL, local_var_prefix );
4179 fprintf( file, ";\n\n" );
4180 }
4181 break;
4182 }
4183 case TGT_POINTER:
4185 continue;
4186 case TGT_INVALID:
4187 case TGT_USER_TYPE:
4188 case TGT_CTXT_HANDLE:
4190 case TGT_STRING:
4191 case TGT_BASIC:
4192 case TGT_ENUM:
4193 case TGT_STRUCT:
4194 case TGT_RANGE:
4195 break;
4196 }
4197 break;
4198 }
4199}
4200
4201static void write_remoting_arg(FILE *file, int indent, const var_t *func, const char *local_var_prefix,
4202 enum pass pass, enum remoting_phase phase, const var_t *var)
4203{
4204 int in_attr, out_attr, pointer_type;
4205 const char *type_str = NULL;
4206 const type_t *type = var->type;
4207 unsigned int alignment, start_offset = type->typestring_offset;
4208
4209 if (is_ptr(type) || is_array(type))
4210 pointer_type = get_pointer_fc(type, var->attrs, pass != PASS_RETURN);
4211 else
4212 pointer_type = 0;
4213
4214 in_attr = is_attr(var->attrs, ATTR_IN);
4215 out_attr = is_attr(var->attrs, ATTR_OUT);
4216 if (!in_attr && !out_attr)
4217 in_attr = 1;
4218
4219 if (phase != PHASE_FREE)
4220 switch (pass)
4221 {
4222 case PASS_IN:
4223 if (!in_attr) return;
4224 break;
4225 case PASS_OUT:
4226 if (!out_attr) return;
4227 break;
4228 case PASS_RETURN:
4229 break;
4230 }
4231
4232 if (phase == PHASE_BUFFERSIZE && get_required_buffer_size( var, &alignment, pass )) return;
4233
4234 write_parameter_conf_or_var_exprs(file, indent, local_var_prefix, phase, var, TRUE);
4235
4236 switch (typegen_detect_type(type, var->attrs, TDT_ALL_TYPES))
4237 {
4238 case TGT_CTXT_HANDLE:
4240 if (phase == PHASE_MARSHAL)
4241 {
4242 if (pass == PASS_IN)
4243 {
4244 /* if the context_handle attribute appears in the chain of types
4245 * without pointers being followed, then the context handle must
4246 * be direct, otherwise it is a pointer */
4247 const char *ch_ptr = is_aliaschain_attr(type, ATTR_CONTEXTHANDLE) ? "" : "*";
4248 print_file(file, indent, "NdrClientContextMarshall(\n");
4249 print_file(file, indent + 1, "&__frame->_StubMsg,\n");
4250 print_file(file, indent + 1, "(NDR_CCONTEXT)%s%s%s,\n", ch_ptr, local_var_prefix,
4251 var->name);
4252 print_file(file, indent + 1, "%s);\n", in_attr && out_attr ? "1" : "0");
4253 }
4254 else
4255 {
4256 print_file(file, indent, "NdrServerContextNewMarshall(\n");
4257 print_file(file, indent + 1, "&__frame->_StubMsg,\n");
4258 print_file(file, indent + 1, "(NDR_SCONTEXT)%s%s,\n", local_var_prefix, var->name);
4259 print_file(file, indent + 1, "(NDR_RUNDOWN)%s_rundown,\n", get_context_handle_type_name(var->type));
4260 print_file(file, indent + 1, "(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%d]);\n", start_offset);
4261 }
4262 }
4263 else if (phase == PHASE_UNMARSHAL)
4264 {
4265 if (pass == PASS_OUT)
4266 {
4267 if (!in_attr)
4268 print_file(file, indent, "*%s%s = 0;\n", local_var_prefix, var->name);
4269 print_file(file, indent, "NdrClientContextUnmarshall(\n");
4270 print_file(file, indent + 1, "&__frame->_StubMsg,\n");
4271 print_file(file, indent + 1, "(NDR_CCONTEXT *)%s%s,\n", local_var_prefix, var->name);
4272 print_file(file, indent + 1, "__frame->_Handle);\n");
4273 }
4274 else
4275 {
4276 print_file(file, indent, "%s%s = NdrServerContextNewUnmarshall(\n", local_var_prefix, var->name);
4277 print_file(file, indent + 1, "&__frame->_StubMsg,\n");
4278 print_file(file, indent + 1, "(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%d]);\n", start_offset);
4279 }
4280 }
4281 break;
4282 case TGT_USER_TYPE:
4283 print_phase_function(file, indent, "UserMarshal", local_var_prefix, phase, var, start_offset);
4284 break;
4285 case TGT_STRING:
4286 if (phase == PHASE_FREE || pass == PASS_RETURN ||
4287 pointer_type != FC_RP)
4288 {
4289 /* strings returned are assumed to be global and hence don't
4290 * need freeing */
4291 if (is_declptr(type) && !(phase == PHASE_FREE && pass == PASS_RETURN))
4292 print_phase_function(file, indent, "Pointer", local_var_prefix,
4293 phase, var, start_offset);
4294 else if (pointer_type == FC_RP && phase == PHASE_FREE &&
4295 !in_attr && is_conformant_array(type))
4296 {
4297 print_file(file, indent, "if (%s%s)\n", local_var_prefix, var->name);
4298 indent++;
4299 print_file(file, indent, "__frame->_StubMsg.pfnFree(%s%s);\n", local_var_prefix, var->name);
4300 }
4301 }
4302 else
4303 {
4304 unsigned int real_start_offset = start_offset;
4305 /* skip over pointer description straight to string description */
4306 if (is_declptr(type))
4307 {
4309 real_start_offset += 4;
4310 else
4311 real_start_offset += 2;
4312 }
4314 print_phase_function(file, indent, "NonConformantString",
4315 local_var_prefix, phase, var,
4316 real_start_offset);
4317 else
4318 print_phase_function(file, indent, "ConformantString", local_var_prefix,
4319 phase, var, real_start_offset);
4320 }
4321 break;
4322 case TGT_ARRAY:
4323 {
4324 unsigned char tc = get_array_fc(type);
4325 const char *array_type = NULL;
4326
4327 /* We already have the size_is expression since it's at the
4328 top level, but do checks for multidimensional conformant
4329 arrays. When we handle them, we'll need to extend this
4330 function to return a list, and then we'll actually use
4331 the return value. */
4332 get_size_is_expr(type, var->name);
4333
4334 switch (tc)
4335 {
4336 case FC_SMFARRAY:
4337 case FC_LGFARRAY:
4338 array_type = "FixedArray";
4339 break;
4340 case FC_SMVARRAY:
4341 case FC_LGVARRAY:
4342 array_type = "VaryingArray";
4343 break;
4344 case FC_CARRAY:
4345 array_type = "ConformantArray";
4346 break;
4347 case FC_CVARRAY:
4348 array_type = "ConformantVaryingArray";
4349 break;
4350 case FC_BOGUS_ARRAY:
4351 array_type = "ComplexArray";
4352 break;
4353 }
4354
4355 if (pointer_type != FC_RP) array_type = "Pointer";
4356
4357 if (phase == PHASE_FREE && pointer_type == FC_RP)
4358 {
4359 /* these are all unmarshalled by allocating memory */
4360 if (tc == FC_BOGUS_ARRAY ||
4361 tc == FC_CVARRAY ||
4362 ((tc == FC_SMVARRAY || tc == FC_LGVARRAY) && in_attr) ||
4363 (tc == FC_CARRAY && !in_attr))
4364 {
4365 if (type_array_is_decl_as_ptr(type) && type->details.array.ptr_tfsoff)
4366 {
4367 print_phase_function(file, indent, "Pointer", local_var_prefix, phase, var,
4368 type->details.array.ptr_tfsoff);
4369 break;
4370 }
4371 print_phase_function(file, indent, array_type, local_var_prefix, phase, var, start_offset);
4372 print_file(file, indent, "if (%s%s)\n", local_var_prefix, var->name);
4373 indent++;
4374 print_file(file, indent, "__frame->_StubMsg.pfnFree(%s%s);\n", local_var_prefix, var->name);
4375 break;
4376 }
4377 }
4378 print_phase_function(file, indent, array_type, local_var_prefix, phase, var, start_offset);
4379 break;
4380 }
4381 case TGT_BASIC:
4382 print_phase_basetype(file, indent, local_var_prefix, phase, pass, var, var->name);
4383 break;
4384 case TGT_ENUM:
4385 print_phase_basetype(file, indent, local_var_prefix, phase, pass, var, var->name);
4386 break;
4387 case TGT_RANGE:
4388 print_phase_basetype(file, indent, local_var_prefix, phase, pass, var, var->name);
4389 /* Note: this goes beyond what MIDL does - it only supports arguments
4390 * with the [range] attribute in Oicf mode */
4391 if (phase == PHASE_UNMARSHAL)
4392 {
4393 const expr_t *range_min;
4394 const expr_t *range_max;
4395 expr_list_t *range_list = get_attrp(var->attrs, ATTR_RANGE);
4396 if (!range_list)
4397 range_list = get_aliaschain_attrp(type, ATTR_RANGE);
4398 range_min = LIST_ENTRY(list_head(range_list), const expr_t, entry);
4399 range_max = LIST_ENTRY(list_next(range_list, list_head(range_list)), const expr_t, entry);
4400
4401 print_file(file, indent, "if ((%s%s < (", local_var_prefix, var->name);
4402 write_type_decl(file, var->type, NULL);
4403 fprintf(file, ")0x%x) || (%s%s > (", range_min->cval, local_var_prefix, var->name);
4404 write_type_decl(file, var->type, NULL);
4405 fprintf(file, ")0x%x))\n", range_max->cval);
4406 print_file(file, indent, "{\n");
4407 print_file(file, indent+1, "RpcRaiseException(RPC_S_INVALID_BOUND);\n");
4408 print_file(file, indent, "}\n");
4409 }
4410 break;
4411 case TGT_STRUCT:
4412 switch (get_struct_fc(type))
4413 {
4414 case FC_STRUCT:
4415 if (phase == PHASE_MARSHAL || phase == PHASE_UNMARSHAL)
4416 print_phase_function(file, indent, "SimpleStruct", local_var_prefix, phase, var, start_offset);
4417 break;
4418 case FC_PSTRUCT:
4419 print_phase_function(file, indent, "SimpleStruct", local_var_prefix, phase, var, start_offset);
4420 break;
4421 case FC_CSTRUCT:
4422 case FC_CPSTRUCT:
4423 print_phase_function(file, indent, "ConformantStruct", local_var_prefix, phase, var, start_offset);
4424 break;
4425 case FC_CVSTRUCT:
4426 print_phase_function(file, indent, "ConformantVaryingStruct", local_var_prefix, phase, var, start_offset);
4427 break;
4428 case FC_BOGUS_STRUCT:
4429 print_phase_function(file, indent, "ComplexStruct", local_var_prefix, phase, var, start_offset);
4430 break;
4431 default:
4432 error("write_remoting_arguments: Unsupported type: %s (0x%02x)\n", var->name, get_struct_fc(type));
4433 }
4434 break;
4435 case TGT_UNION:
4436 {
4437 const char *union_type = NULL;
4438
4440 union_type = "NonEncapsulatedUnion";
4442 union_type = "EncapsulatedUnion";
4443
4444 print_phase_function(file, indent, union_type, local_var_prefix,
4445 phase, var, start_offset);
4446 break;
4447 }
4448 case TGT_POINTER:
4449 {
4451 if (pointer_type == FC_RP) switch (typegen_detect_type(ref, NULL, TDT_ALL_TYPES))
4452 {
4453 case TGT_BASIC:
4454 print_phase_basetype(file, indent, local_var_prefix, phase, pass, var, var->name);
4455 break;
4456 case TGT_ENUM:
4457 /* base types have known sizes, so don't need a sizing pass
4458 * and don't have any memory to free and so don't need a
4459 * freeing pass */
4460 if (phase == PHASE_MARSHAL || phase == PHASE_UNMARSHAL)
4461 print_phase_function(file, indent, "Pointer", local_var_prefix, phase, var, start_offset);
4462 break;
4463 case TGT_STRUCT:
4464 switch (get_struct_fc(ref))
4465 {
4466 case FC_STRUCT:
4467 /* simple structs have known sizes, so don't need a sizing
4468 * pass and don't have any memory to free and so don't
4469 * need a freeing pass */
4470 if (phase == PHASE_MARSHAL || phase == PHASE_UNMARSHAL)
4471 type_str = "SimpleStruct";
4472 else if (phase == PHASE_FREE && pass == PASS_RETURN)
4473 {
4474 print_file(file, indent, "if (%s%s)\n", local_var_prefix, var->name);
4475 indent++;
4476 print_file(file, indent, "__frame->_StubMsg.pfnFree(%s%s);\n", local_var_prefix, var->name);
4477 indent--;
4478 }
4479 break;
4480 case FC_PSTRUCT:
4481 type_str = "SimpleStruct";
4482 break;
4483 case FC_CSTRUCT:
4484 case FC_CPSTRUCT:
4485 type_str = "ConformantStruct";
4486 break;
4487 case FC_CVSTRUCT:
4488 type_str = "ConformantVaryingStruct";
4489 break;
4490 case FC_BOGUS_STRUCT:
4491 type_str = "ComplexStruct";
4492 break;
4493 default:
4494 error("write_remoting_arguments: Unsupported type: %s (0x%02x)\n", var->name, get_struct_fc(ref));
4495 }
4496
4497 if (type_str)
4498 {
4499 if (phase == PHASE_FREE)
4500 type_str = "Pointer";
4501 else
4502 start_offset = ref->typestring_offset;
4503 print_phase_function(file, indent, type_str, local_var_prefix, phase, var, start_offset);
4504 }
4505 break;
4506 case TGT_UNION:
4507 if (phase == PHASE_FREE)
4508 type_str = "Pointer";
4509 else
4510 {
4512 type_str = "NonEncapsulatedUnion";
4514 type_str = "EncapsulatedUnion";
4515
4516 start_offset = ref->typestring_offset;
4517 }
4518
4519 print_phase_function(file, indent, type_str, local_var_prefix,
4520 phase, var, start_offset);
4521 break;
4522 case TGT_USER_TYPE:
4523 if (phase != PHASE_FREE)
4524 {
4525 type_str = "UserMarshal";
4526 start_offset = ref->typestring_offset;
4527 }
4528 else type_str = "Pointer";
4529
4530 print_phase_function(file, indent, type_str, local_var_prefix, phase, var, start_offset);
4531 break;
4532 case TGT_STRING:
4533 case TGT_POINTER:
4534 case TGT_ARRAY:
4535 case TGT_RANGE:
4536 case TGT_IFACE_POINTER:
4537 case TGT_CTXT_HANDLE:
4539 print_phase_function(file, indent, "Pointer", local_var_prefix, phase, var, start_offset);
4540 break;
4541 case TGT_INVALID:
4542 assert(0);
4543 break;
4544 }
4545 else
4546 print_phase_function(file, indent, "Pointer", local_var_prefix, phase, var, start_offset);
4547 break;
4548 }
4549 case TGT_IFACE_POINTER:
4550 print_phase_function(file, indent, "InterfacePointer", local_var_prefix, phase, var, start_offset);
4551 break;
4552 case TGT_INVALID:
4553 assert(0);
4554 break;
4555 }
4556 fprintf(file, "\n");
4557}
4558
4559void write_remoting_arguments(FILE *file, int indent, const var_t *func, const char *local_var_prefix,
4560 enum pass pass, enum remoting_phase phase)
4561{
4562 if (phase == PHASE_BUFFERSIZE && pass != PASS_RETURN)
4563 {
4564 unsigned int size = get_function_buffer_size( func, pass );
4565 print_file(file, indent, "__frame->_StubMsg.BufferLength = %u;\n", size);
4566 }
4567
4568 if (pass == PASS_RETURN)
4569 {
4570 write_remoting_arg( file, indent, func, local_var_prefix, pass, phase,
4572 }
4573 else
4574 {
4575 const var_t *var;
4576 if (!type_get_function_args(func->type))
4577 return;
4579 write_remoting_arg( file, indent, func, local_var_prefix, pass, phase, var );
4580 }
4581}
4582
4583
4585{
4586 unsigned int offset = 0;
4588 return offset;
4589}
4590
4592{
4593 const statement_t *stmt;
4595 {
4596 const var_t *func = stmt->u.var;
4597 if (!is_local(func->attrs))
4599 }
4600}
4601
4603{
4604 unsigned int size = 1;
4606 return size;
4607}
4608
4610{
4612 return process_tfs(NULL, stmts, pred);
4613}
4614
4616{
4617 int in_attr, out_attr;
4618 int i = 0;
4619 const var_t *var = type_function_get_retval(func->type);
4620
4621 /* declare return value */
4622 if (!is_void(var->type))
4623 {
4624 print_file(file, indent, "%s", "");
4625 write_type_decl(file, var->type, var->name);
4626 fprintf(file, ";\n");
4627 }
4628
4629 if (!type_get_function_args(func->type))
4630 return;
4631
4633 {
4634 in_attr = is_attr(var->attrs, ATTR_IN);
4635 out_attr = is_attr(var->attrs, ATTR_OUT);
4636 if (!out_attr && !in_attr)
4637 in_attr = 1;
4638
4639 if (is_context_handle(var->type))
4640 print_file(file, indent, "NDR_SCONTEXT %s;\n", var->name);
4641 else
4642 {
4643 if (!in_attr && !is_conformant_array(var->type))
4644 {
4645 type_t *type_to_print;
4646 char name[16];
4647 print_file(file, indent, "%s", "");
4648 if (type_get_type(var->type) == TYPE_ARRAY &&
4650 type_to_print = var->type;
4651 else
4652 type_to_print = type_pointer_get_ref(var->type);
4653 sprintf(name, "_W%u", i++);
4654 write_type_decl(file, type_to_print, name);
4655 fprintf(file, ";\n");
4656 }
4657
4658 print_file(file, indent, "%s", "");
4660 fprintf(file, " ");
4661 if (type_get_type(var->type) == TYPE_ARRAY &&
4663 fprintf(file, "(*%s)", var->name);
4664 } else
4665 fprintf(file, "%s", var->name);
4666 write_type_right(file, var->type, FALSE);
4667 fprintf(file, ";\n");
4668
4669 if (decl_indirect(var->type))
4670 print_file(file, indent, "void *_p_%s;\n", var->name);
4671 }
4672 }
4673}
4674
4675
4676void assign_stub_out_args( FILE *file, int indent, const var_t *func, const char *local_var_prefix )
4677{
4678 int in_attr, out_attr;
4679 int i = 0, sep = 0;
4680 const var_t *var;
4681 type_t *ref;
4682
4683 if (!type_get_function_args(func->type))
4684 return;
4685
4687 {
4688 in_attr = is_attr(var->attrs, ATTR_IN);
4689 out_attr = is_attr(var->attrs, ATTR_OUT);
4690 if (!out_attr && !in_attr)
4691 in_attr = 1;
4692
4693 if (!in_attr)
4694 {
4695 print_file(file, indent, "%s%s", local_var_prefix, var->name);
4696
4697 switch (typegen_detect_type(var->type, var->attrs, TDT_IGNORE_STRINGS))
4698 {
4700 fprintf(file, " = NdrContextHandleInitialize(\n");
4701 print_file(file, indent + 1, "&__frame->_StubMsg,\n");
4702 print_file(file, indent + 1, "(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%d]);\n",
4703 var->typestring_offset);
4704 break;
4705 case TGT_ARRAY:
4707 {
4708 unsigned int size;
4709 type_t *type;
4710
4711 fprintf(file, " = NdrAllocate(&__frame->_StubMsg, ");
4712 for (type = var->type;
4715 {
4717 TRUE, NULL, NULL, local_var_prefix);
4718 fprintf(file, " * ");
4719 }
4721 fprintf(file, "%u);\n", size);
4722
4723 print_file(file, indent, "memset(%s%s, 0, ", local_var_prefix, var->name);
4724 for (type = var->type;
4727 {
4729 TRUE, NULL, NULL, local_var_prefix);
4730 fprintf(file, " * ");
4731 }
4733 fprintf(file, "%u);\n", size);
4734 }
4735 else
4736 fprintf(file, " = &%s_W%u;\n", local_var_prefix, i++);
4737 break;
4738 case TGT_POINTER:
4739 fprintf(file, " = &%s_W%u;\n", local_var_prefix, i);
4740 ref = type_pointer_get_ref(var->type);
4742 {
4743 case TGT_BASIC:
4744 case TGT_ENUM:
4745 case TGT_POINTER:
4746 case TGT_RANGE:
4747 case TGT_IFACE_POINTER:
4748 print_file(file, indent, "%s_W%u = 0;\n", local_var_prefix, i);
4749 break;
4750 case TGT_USER_TYPE:
4751 print_file(file, indent, "memset(&%s_W%u, 0, sizeof(%s_W%u));\n",
4752 local_var_prefix, i, local_var_prefix, i);
4753 break;
4754 case TGT_ARRAY:
4756 {
4757 print_file(file, indent, "%s_W%u = 0;\n", local_var_prefix, i);
4758 break;
4759 }
4761 /* fall through */
4762 case TGT_STRUCT:
4763 case TGT_UNION:
4765 print_file(file, indent, "memset(&%s_W%u, 0, sizeof(%s_W%u));\n",
4766 local_var_prefix, i, local_var_prefix, i);
4767 break;
4768 case TGT_CTXT_HANDLE:
4770 case TGT_INVALID:
4771 case TGT_STRING:
4772 /* not initialised */
4773 break;
4774 }
4775 i++;
4776 break;
4777 default:
4778 break;
4779 }
4780
4781 sep = 1;
4782 }
4783 }
4784 if (sep)
4785 fprintf(file, "\n");
4786}
4787
4788
4790 const char *var_decl, int add_retval )
4791{
4792 var_t *retval = type_function_get_retval( func );
4794 const var_t *arg;
4795 int needs_packing;
4796 unsigned int align = 0;
4797
4798 if (args)
4800 if (!is_array( arg->type )) type_memsize_and_alignment( arg->type, &align );
4801
4802 needs_packing = (align > pointer_size);
4803
4804 if (needs_packing) print_file( file, 0, "#include <pshpack%u.h>\n", pointer_size );
4805 print_file(file, 1, "struct _PARAM_STRUCT\n" );
4806 print_file(file, 1, "{\n" );
4807 if (is_object( iface )) print_file(file, 2, "%s *This;\n", iface->name );
4808
4809 if (args) LIST_FOR_EACH_ENTRY( arg, args, const var_t, entry )
4810 {
4811 print_file(file, 2, "%s", "");
4813 if (needs_space_after( arg->type )) fputc( ' ', file );
4814 if (is_array( arg->type ) && !type_array_is_decl_as_ptr( arg->type )) fputc( '*', file );
4815
4816 /* FIXME: should check for large args being passed by pointer */
4817 align = 0;
4818 if (is_array( arg->type ) || is_ptr( arg->type )) align = pointer_size;
4819 else type_memsize_and_alignment( arg->type, &align );
4820
4821 if (align >= pointer_size)
4822 fprintf( file, "%s;\n", arg->name );
4823 else
4824#ifdef __REACTOS__
4825 fprintf( file, "DECLSPEC_ALIGN(%u) %s;\n", pointer_size, arg->name );
4826#else
4827 fprintf( file, "%s DECLSPEC_ALIGN(%u);\n", arg->name, pointer_size );
4828#endif
4829 }
4830 if (add_retval && !is_void( retval->type ))
4831 {
4832 print_file(file, 2, "%s", "");
4833 write_type_decl( file, retval->type, retval->name );
4834 if (is_array( retval->type ) || is_ptr( retval->type ) ||
4835 type_memsize( retval->type ) == pointer_size)
4836 fprintf( file, ";\n" );
4837 else
4838 fprintf( file, " DECLSPEC_ALIGN(%u);\n", pointer_size );
4839 }
4840 print_file(file, 1, "} %s;\n", var_decl );
4841 if (needs_packing) print_file( file, 0, "#include <poppack.h>\n" );
4842 print_file( file, 0, "\n" );
4843}
4844
4846{
4847 const var_list_t *args = type_get_function_args( func->type );
4848 const var_t *var;
4849
4850 if (!args) return;
4851
4853 if (cant_be_null( var ))
4854 print_file( file, indent, "if (!%s) RpcRaiseException(RPC_X_NULL_REF_POINTER);\n", var->name );
4855}
4856
4858{
4859 static const char *var_name = "pS";
4860 static const char *var_name_expr = "pS->";
4861 int result = 0;
4862 struct expr_eval_routine *eval;
4863 unsigned short callback_offset = 0;
4864
4866 {
4867 const char *name = eval->name;
4868 result = 1;
4869
4870 print_file(file, 0, "static void __RPC_USER %s_%sExprEval_%04u(PMIDL_STUB_MESSAGE pStubMsg)\n",
4871 eval->iface ? eval->iface->name : iface, name, callback_offset);
4872 print_file(file, 0, "{\n");
4873 if (type_get_type( eval->cont_type ) == TYPE_FUNCTION)
4874 {
4876 "*pS = (struct _PARAM_STRUCT *)pStubMsg->StackTop", FALSE );
4877 }
4878 else
4879 {
4880 print_file(file, 1, "%s", "");
4882 fprintf(file, " *%s = (", var_name);
4884 fprintf(file, " *)(pStubMsg->StackTop - %u);\n", eval->baseoff);
4885 }
4886 print_file(file, 1, "pStubMsg->Offset = 0;\n"); /* FIXME */
4887 print_file(file, 1, "pStubMsg->MaxCount = (ULONG_PTR)");
4888 write_expr(file, eval->expr, 1, 1, var_name_expr, eval->cont_type, "");
4889 fprintf(file, ";\n");
4890 print_file(file, 0, "}\n\n");
4891 callback_offset++;
4892 }
4893 return result;
4894}
4895
4897{
4898 struct expr_eval_routine *eval;
4899 struct expr_eval_routine *cursor;
4900 unsigned short callback_offset = 0;
4901
4902 fprintf(file, "static const EXPR_EVAL ExprEvalRoutines[] =\n");
4903 fprintf(file, "{\n");
4904
4906 {
4907 print_file(file, 1, "%s_%sExprEval_%04u,\n",
4908 eval->iface ? eval->iface->name : iface, eval->name, callback_offset);
4909 callback_offset++;
4910 list_remove(&eval->entry);
4911 free(eval->name);
4912 free(eval);
4913 }
4914
4915 fprintf(file, "};\n\n");
4916}
4917
4919{
4920 user_type_t *ut;
4921
4923 return;
4924
4925 fprintf(file, "static const USER_MARSHAL_ROUTINE_QUADRUPLE UserMarshalRoutines[] =\n");
4926 fprintf(file, "{\n");
4928 {
4929 const char *sep = &ut->entry == list_tail(&user_type_list) ? "" : ",";
4930 print_file(file, 1, "{\n");
4931 print_file(file, 2, "(USER_MARSHAL_SIZING_ROUTINE)%s_UserSize,\n", ut->name);
4932 print_file(file, 2, "(USER_MARSHAL_MARSHALLING_ROUTINE)%s_UserMarshal,\n", ut->name);
4933 print_file(file, 2, "(USER_MARSHAL_UNMARSHALLING_ROUTINE)%s_UserUnmarshal,\n", ut->name);
4934 print_file(file, 2, "(USER_MARSHAL_FREEING_ROUTINE)%s_UserFree\n", ut->name);
4935 print_file(file, 1, "}%s\n", sep);
4936 }
4937 fprintf(file, "};\n\n");
4938}
4939
4940void write_endpoints( FILE *f, const char *prefix, const str_list_t *list )
4941{
4942 const struct str_list_entry_t *endpoint;
4943 const char *p;
4944
4945 /* this should be an array of RPC_PROTSEQ_ENDPOINT but we want const strings */
4946 print_file( f, 0, "static const unsigned char * const %s__RpcProtseqEndpoint[][2] =\n{\n", prefix );
4948 {
4949 print_file( f, 1, "{ (const unsigned char *)\"" );
4950 for (p = endpoint->str; *p && *p != ':'; p++)
4951 {
4952 if (*p == '"' || *p == '\\') fputc( '\\', f );
4953 fputc( *p, f );
4954 }
4955 if (!*p) goto error;
4956 if (p[1] != '[') goto error;
4957
4958 fprintf( f, "\", (const unsigned char *)\"" );
4959 for (p += 2; *p && *p != ']'; p++)
4960 {
4961 if (*p == '"' || *p == '\\') fputc( '\\', f );
4962 fputc( *p, f );
4963 }
4964 if (*p != ']') goto error;
4965 fprintf( f, "\" },\n" );
4966 }
4967 print_file( f, 0, "};\n\n" );
4968 return;
4969
4970error:
4971 error("Invalid endpoint syntax '%s'\n", endpoint->str);
4972}
4973
4975 const char *prefix, unsigned int proc_offset )
4976{
4977 type_t *rettype = type_function_get_rettype( func->type );
4978 int has_ret = !is_void( rettype );
4979 const var_list_t *args = type_get_function_args( func->type );
4980 const var_t *arg;
4981 int len, needs_params = 0;
4982
4983 /* we need a param structure if we have more than one arg */
4984 if (pointer_size == 4 && args) needs_params = is_object( iface ) || list_count( args ) > 1;
4985
4986 print_file( file, 0, "{\n");
4987 if (needs_params)
4988 {
4989 if (has_ret) print_file( file, 1, "%s", "CLIENT_CALL_RETURN _RetVal;\n" );
4990 write_func_param_struct( file, iface, func->type, "__params", FALSE );
4991 if (is_object( iface )) print_file( file, 1, "__params.This = This;\n" );
4992 if (args)
4994 print_file( file, 1, "__params.%s = %s;\n", arg->name, arg->name );
4995 }
4996 else if (has_ret) print_file( file, 1, "%s", "CLIENT_CALL_RETURN _RetVal;\n\n" );
4997
4998 len = fprintf( file, " %s%s( ",
4999 has_ret ? "_RetVal = " : "",
5000 get_stub_mode() == MODE_Oif ? "NdrClientCall2" : "NdrClientCall" );
5001 fprintf( file, "&%s_StubDesc,", prefix );
5002 fprintf( file, "\n%*s&__MIDL_ProcFormatString.Format[%u]", len, "", proc_offset );
5003 if (needs_params)
5004 {
5005 fprintf( file, ",\n%*s&__params", len, "" );
5006 }
5007 else if (pointer_size == 8)
5008 {
5009 if (is_object( iface )) fprintf( file, ",\n%*sThis", len, "" );
5010 if (args)
5012 fprintf( file, ",\n%*s%s", len, "", arg->name );
5013 }
5014 else
5015 {
5016 if (is_object( iface )) fprintf( file, ",\n%*s&This", len, "" );
5017 else if (args)
5018 {
5019 arg = LIST_ENTRY( list_head(args), const var_t, entry );
5020 fprintf( file, ",\n%*s&%s", len, "", arg->name );
5021 }
5022 }
5023 fprintf( file, " );\n" );
5024 if (has_ret)
5025 {
5026 print_file( file, 1, "return (" );
5027 write_type_decl_left(file, rettype);
5028 fprintf( file, ")%s;\n", pointer_size == 8 ? "_RetVal.Simple" : "*(LONG_PTR *)&_RetVal" );
5029 }
5030 print_file( file, 0, "}\n\n");
5031}
5032
5034{
5035 fprintf( file, "#ifndef USE_COMPILER_EXCEPTIONS\n");
5036 fprintf( file, "\n");
5037 fprintf( file, "#include \"wine/exception.h\"\n");
5038 fprintf( file, "#undef RpcTryExcept\n");
5039 fprintf( file, "#undef RpcExcept\n");
5040 fprintf( file, "#undef RpcEndExcept\n");
5041 fprintf( file, "#undef RpcTryFinally\n");
5042 fprintf( file, "#undef RpcFinally\n");
5043 fprintf( file, "#undef RpcEndFinally\n");
5044 fprintf( file, "#undef RpcExceptionCode\n");
5045 fprintf( file, "#undef RpcAbnormalTermination\n");
5046 fprintf( file, "\n");
5047 fprintf( file, "struct __exception_frame;\n");
5048 fprintf( file, "typedef int (*__filter_func)(struct __exception_frame *);\n");
5049 fprintf( file, "typedef void (*__finally_func)(struct __exception_frame *);\n");
5050 fprintf( file, "\n");
5051 fprintf( file, "#define __DECL_EXCEPTION_FRAME \\\n");
5052 fprintf( file, " EXCEPTION_REGISTRATION_RECORD frame; \\\n");
5053 fprintf( file, " __filter_func filter; \\\n");
5054 fprintf( file, " __finally_func finally; \\\n");
5055 fprintf( file, " sigjmp_buf jmp; \\\n");
5056 fprintf( file, " DWORD code; \\\n");
5057 fprintf( file, " unsigned char abnormal_termination; \\\n");
5058 fprintf( file, " unsigned char filter_level; \\\n");
5059 fprintf( file, " unsigned char finally_level;\n");
5060 fprintf( file, "\n");
5061 fprintf( file, "struct __exception_frame\n{\n");
5062 fprintf( file, " __DECL_EXCEPTION_FRAME\n");
5063 fprintf( file, "};\n");
5064 fprintf( file, "\n");
5065 fprintf( file, "static inline void __widl_unwind_target(void)\n" );
5066 fprintf( file, "{\n");
5067 fprintf( file, " struct __exception_frame *exc_frame = (struct __exception_frame *)__wine_get_frame();\n" );
5068 fprintf( file, " if (exc_frame->finally_level > exc_frame->filter_level)\n" );
5069 fprintf( file, " {\n");
5070 fprintf( file, " exc_frame->abnormal_termination = 1;\n");
5071 fprintf( file, " exc_frame->finally( exc_frame );\n");
5072 fprintf( file, " __wine_pop_frame( &exc_frame->frame );\n");
5073 fprintf( file, " }\n");
5074 fprintf( file, " exc_frame->filter_level = 0;\n");
5075 fprintf( file, " siglongjmp( exc_frame->jmp, 1 );\n");
5076 fprintf( file, "}\n");
5077 fprintf( file, "\n");
5078 fprintf( file, "static DWORD __widl_exception_handler( EXCEPTION_RECORD *record,\n");
5079 fprintf( file, " EXCEPTION_REGISTRATION_RECORD *frame,\n");
5080 fprintf( file, " CONTEXT *context,\n");
5081 fprintf( file, " EXCEPTION_REGISTRATION_RECORD **pdispatcher )\n");
5082 fprintf( file, "{\n");
5083 fprintf( file, " struct __exception_frame *exc_frame = (struct __exception_frame *)frame;\n");
5084 fprintf( file, "\n");
5085 fprintf( file, " if (record->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND | EH_NESTED_CALL))\n");
5086 fprintf( file, " {\n" );
5087 fprintf( file, " if (exc_frame->finally_level && (record->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND)))\n");
5088 fprintf( file, " {\n" );
5089 fprintf( file, " exc_frame->abnormal_termination = 1;\n");
5090 fprintf( file, " exc_frame->finally( exc_frame );\n");
5091 fprintf( file, " }\n" );
5092 fprintf( file, " return ExceptionContinueSearch;\n");
5093 fprintf( file, " }\n" );
5094 fprintf( file, " exc_frame->code = record->ExceptionCode;\n");
5095 fprintf( file, " if (exc_frame->filter_level && exc_frame->filter( exc_frame ) == EXCEPTION_EXECUTE_HANDLER)\n" );
5096 fprintf( file, " __wine_rtl_unwind( frame, record, __widl_unwind_target );\n");
5097 fprintf( file, " return ExceptionContinueSearch;\n");
5098 fprintf( file, "}\n");
5099 fprintf( file, "\n");
5100 fprintf( file, "#define RpcTryExcept \\\n");
5101 fprintf( file, " if (!sigsetjmp( __frame->jmp, 0 )) \\\n");
5102 fprintf( file, " { \\\n");
5103 fprintf( file, " if (!__frame->finally_level) \\\n" );
5104 fprintf( file, " __wine_push_frame( &__frame->frame ); \\\n");
5105 fprintf( file, " __frame->filter_level = __frame->finally_level + 1;\n" );
5106 fprintf( file, "\n");
5107 fprintf( file, "#define RpcExcept(expr) \\\n");
5108 fprintf( file, " if (!__frame->finally_level) \\\n" );
5109 fprintf( file, " __wine_pop_frame( &__frame->frame ); \\\n");
5110 fprintf( file, " __frame->filter_level = 0; \\\n" );
5111 fprintf( file, " } \\\n");
5112 fprintf( file, " else \\\n");
5113 fprintf( file, "\n");
5114 fprintf( file, "#define RpcEndExcept\n");
5115 fprintf( file, "\n");
5116 fprintf( file, "#define RpcExceptionCode() (__frame->code)\n");
5117 fprintf( file, "\n");
5118 fprintf( file, "#define RpcTryFinally \\\n");
5119 fprintf( file, " if (!__frame->filter_level) \\\n");
5120 fprintf( file, " __wine_push_frame( &__frame->frame ); \\\n");
5121 fprintf( file, " __frame->finally_level = __frame->filter_level + 1;\n");
5122 fprintf( file, "\n");
5123 fprintf( file, "#define RpcFinally \\\n");
5124 fprintf( file, " if (!__frame->filter_level) \\\n");
5125 fprintf( file, " __wine_pop_frame( &__frame->frame ); \\\n");
5126 fprintf( file, " __frame->finally_level = 0;\n");
5127 fprintf( file, "\n");
5128 fprintf( file, "#define RpcEndFinally\n");
5129 fprintf( file, "\n");
5130 fprintf( file, "#define RpcAbnormalTermination() (__frame->abnormal_termination)\n");
5131 fprintf( file, "\n");
5132 fprintf( file, "#define RpcExceptionInit(filter_func,finally_func) \\\n");
5133 fprintf( file, " do { \\\n");
5134 fprintf( file, " __frame->frame.Handler = __widl_exception_handler; \\\n");
5135 fprintf( file, " __frame->filter = (__filter_func)(filter_func); \\\n" );
5136 fprintf( file, " __frame->finally = (__finally_func)(finally_func); \\\n");
5137 fprintf( file, " __frame->abnormal_termination = 0; \\\n");
5138 fprintf( file, " __frame->filter_level = 0; \\\n");
5139 fprintf( file, " __frame->finally_level = 0; \\\n");
5140 fprintf( file, " } while (0)\n");
5141 fprintf( file, "\n");
5142 fprintf( file, "#else /* USE_COMPILER_EXCEPTIONS */\n");
5143 fprintf( file, "\n");
5144 fprintf( file, "#define RpcExceptionInit(filter_func,finally_func) \\\n");
5145 fprintf( file, " do { (void)(filter_func); } while(0)\n");
5146 fprintf( file, "\n");
5147 fprintf( file, "#define __DECL_EXCEPTION_FRAME \\\n");
5148 fprintf( file, " DWORD code;\n");
5149 fprintf( file, "\n");
5150 fprintf( file, "#endif /* USE_COMPILER_EXCEPTIONS */\n");
5151}
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
char * va_list
Definition: acmsvcex.h:78
#define va_end(ap)
Definition: acmsvcex.h:90
#define va_start(ap, A)
Definition: acmsvcex.h:91
char * xstrdup(const char *s)
Definition: uimain.c:768
void * xmalloc(int size)
Definition: uimain.c:747
static void list_remove(struct list_entry *entry)
Definition: list.h:90
static int list_empty(struct list_entry *head)
Definition: list.h:58
static void list_add_tail(struct list_entry *head, struct list_entry *entry)
Definition: list.h:83
PFOR_CONTEXT fc
Definition: for.c:57
static const int carray[3]
Definition: ckconfig.c:184
Definition: list.h:37
#define free
Definition: debug_ros.c:5
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static const WCHAR indent[]
Definition: object.c:1156
@ EXPR_VOID
Definition: parser.h:231
@ EXPR_DIV
Definition: parser.h:228
@ EXPR_ADD
Definition: parser.h:225
@ EXPR_MUL
Definition: parser.h:227
@ EXPR_SUB
Definition: parser.h:226
#define assert(x)
Definition: debug.h:53
r parent
Definition: btrfs.c:3010
#define __FUNCTION__
Definition: types.h:116
int align(int length, int align)
Definition: dsound8.c:36
int compare_expr(const expr_t *a, const expr_t *b)
Definition: expr.c:867
const type_t * expr_resolve_type(const struct expr_loc *expr_loc, const type_t *cont_type, const expr_t *expr)
Definition: expr.c:684
void write_expr(FILE *h, const expr_t *e, int brackets, int toplevel, const char *toplevel_prefix, const type_t *cont_type, const char *local_var_prefix)
Definition: expr.c:691
#define printf
Definition: freeldr.h:93
GLuint start
Definition: gl.h:1545
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
const GLdouble * v
Definition: gl.h:2040
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
GLdouble GLdouble t
Definition: gl.h:2047
GLsizeiptr size
Definition: glext.h:5919
GLenum func
Definition: glext.h:6028
GLdouble n
Definition: glext.h:7729
GLuint buffer
Definition: glext.h:5915
const GLfloat * tc
Definition: glext.h:8925
const GLubyte * c
Definition: glext.h:8905
GLenum pname
Definition: glext.h:5645
GLfloat f
Definition: glext.h:7540
GLbitfield flags
Definition: glext.h:7161
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLuint64EXT * result
Definition: glext.h:11304
GLintptr offset
Definition: glext.h:5920
GLint fsize
Definition: glext.h:9408
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean flag
Definition: glfuncs.h:52
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static int is_declptr(const type_t *t)
Definition: header.h:74
static int is_context_handle(const type_t *type)
Definition: header.h:100
static int is_void(const type_t *t)
Definition: header.h:69
static int is_conformant_array(const type_t *t)
Definition: header.h:79
int count_methods(const type_t *iface)
Definition: proxy.c:465
static int is_string_type(const attr_list_t *attrs, const type_t *type)
Definition: header.h:94
static int is_ptr(const type_t *t)
Definition: header.h:59
static int is_array(const type_t *t)
Definition: header.h:64
const char cursor[]
Definition: icontest.c:13
#define UCHAR_MAX
Definition: limits.h:25
#define USHRT_MAX
Definition: limits.h:38
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
_Check_return_opt_ _CRTIMP int __cdecl vfprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format, va_list _ArgList)
_Check_return_opt_ _CRTIMP int __cdecl fputc(_In_ int _Ch, _Inout_ FILE *_File)
Definition: msctf.idl:550
uint32_t entry
Definition: isohybrid.c:63
#define f
Definition: ke_i.h:83
#define c
Definition: ke_i.h:80
#define sign(x)
Definition: mapdesc.cc:613
#define error(str)
Definition: mkdosfs.c:1605
#define sprintf(buf, format,...)
Definition: sprintf.c:55
const char * var
Definition: shader.c:5666
static size_t elem
Definition: string.c:68
static const DWORD padding[]
Definition: mciwnd.c:89
const char * fields[10]
Definition: parser.c:313
static HANDLE proc()
Definition: pdb.c:34
static uint64_t range_max(IN const pnfs_layout *layout)
Definition: pnfs_layout.c:220
#define FC_POINTER_DEREF
Definition: ndrtypes.h:276
#define FC_DONT_FREE
Definition: ndrtypes.h:273
#define FC_TOP_LEVEL_CONFORMANCE
Definition: ndrtypes.h:300
#define FC_POINTER_CONFORMANCE
Definition: ndrtypes.h:299
#define Oi_FULL_PTR_USED
Definition: ndrtypes.h:290
#define NDR_CONTEXT_HANDLE_CANNOT_BE_NULL
Definition: ndrtypes.h:288
#define FC_ALLOCATE_ALL_NODES
Definition: ndrtypes.h:272
#define NDR_CONTEXT_HANDLE_SERIALIZE
Definition: ndrtypes.h:287
@ FC_STRUCTPAD4
Definition: ndrtypes.h:213
@ FC_BIND_PRIMITIVE
Definition: ndrtypes.h:194
@ FC_ADD_1
Definition: ndrtypes.h:246
@ FC_USMALL
Definition: ndrtypes.h:138
@ FC_INT3264
Definition: ndrtypes.h:268
@ FC_STRUCT
Definition: ndrtypes.h:157
@ FC_BIND_GENERIC
Definition: ndrtypes.h:193
@ FC_SUB_1
Definition: ndrtypes.h:247
@ FC_SMALL
Definition: ndrtypes.h:137
@ FC_BOGUS_STRUCT
Definition: ndrtypes.h:162
@ FC_CPSTRUCT
Definition: ndrtypes.h:160
@ FC_DEREFERENCE
Definition: ndrtypes.h:243
@ FC_C_CSTRING
Definition: ndrtypes.h:172
@ FC_IGNORE
Definition: ndrtypes.h:149
@ FC_ALIGNM4
Definition: ndrtypes.h:203
@ FC_DOUBLE
Definition: ndrtypes.h:146
@ FC_SMFARRAY
Definition: ndrtypes.h:166
@ FC_USHORT
Definition: ndrtypes.h:141
@ FC_ALIGNM2
Definition: ndrtypes.h:202
@ FC_ENUM16
Definition: ndrtypes.h:147
@ FC_C_WSTRING
Definition: ndrtypes.h:175
@ FC_ERROR_STATUS_T
Definition: ndrtypes.h:150
@ FC_BYTE_COUNT_POINTER
Definition: ndrtypes.h:184
@ FC_LONG
Definition: ndrtypes.h:142
@ FC_ENCAPSULATED_UNION
Definition: ndrtypes.h:181
@ FC_CHAR
Definition: ndrtypes.h:136
@ FC_RANGE
Definition: ndrtypes.h:266
@ FC_OP
Definition: ndrtypes.h:154
@ FC_HYPER
Definition: ndrtypes.h:145
@ FC_NO_REPEAT
Definition: ndrtypes.h:222
@ FC_CONSTANT_IID
Definition: ndrtypes.h:251
@ FC_LGVARRAY
Definition: ndrtypes.h:169
@ FC_STRUCTPAD1
Definition: ndrtypes.h:210
@ FC_CVSTRUCT
Definition: ndrtypes.h:161
@ FC_EMBEDDED_COMPLEX
Definition: ndrtypes.h:233
@ FC_CSTRING
Definition: ndrtypes.h:176
@ FC_BOGUS_ARRAY
Definition: ndrtypes.h:170
@ FC_ULONG
Definition: ndrtypes.h:143
@ FC_STRUCTPAD7
Definition: ndrtypes.h:216
@ FC_PP
Definition: ndrtypes.h:228
@ FC_ALIGNM8
Definition: ndrtypes.h:204
@ FC_MULT_2
Definition: ndrtypes.h:245
@ FC_AUTO_HANDLE
Definition: ndrtypes.h:195
@ FC_UP
Definition: ndrtypes.h:153
@ FC_CARRAY
Definition: ndrtypes.h:164
@ FC_SMVARRAY
Definition: ndrtypes.h:168
@ FC_NON_ENCAPSULATED_UNION
Definition: ndrtypes.h:182
@ FC_POINTER
Definition: ndrtypes.h:200
@ FC_CALLBACK
Definition: ndrtypes.h:249
@ FC_PAD
Definition: ndrtypes.h:254
@ FC_STRING_SIZED
Definition: ndrtypes.h:218
@ FC_RP
Definition: ndrtypes.h:152
@ FC_FIXED_REPEAT
Definition: ndrtypes.h:223
@ FC_PSTRUCT
Definition: ndrtypes.h:158
@ FC_STRUCTPAD5
Definition: ndrtypes.h:214
@ FC_WSTRING
Definition: ndrtypes.h:179
@ FC_FLOAT
Definition: ndrtypes.h:144
@ FC_STRUCTPAD2
Definition: ndrtypes.h:211
@ FC_USER_MARSHAL
Definition: ndrtypes.h:261
@ FC_CSTRUCT
Definition: ndrtypes.h:159
@ FC_ENUM32
Definition: ndrtypes.h:148
@ FC_BIND_CONTEXT
Definition: ndrtypes.h:191
@ FC_CVARRAY
Definition: ndrtypes.h:165
@ FC_VARIABLE_OFFSET
Definition: ndrtypes.h:226
@ FC_FIXED_OFFSET
Definition: ndrtypes.h:225
@ FC_STRUCTPAD6
Definition: ndrtypes.h:215
@ FC_FP
Definition: ndrtypes.h:155
@ FC_BYTE
Definition: ndrtypes.h:135
@ FC_REPRESENT_AS
Definition: ndrtypes.h:187
@ FC_END
Definition: ndrtypes.h:253
@ FC_DIV_2
Definition: ndrtypes.h:244
@ FC_UINT3264
Definition: ndrtypes.h:269
@ FC_CALLBACK_HANDLE
Definition: ndrtypes.h:196
@ FC_TRANSMIT_AS
Definition: ndrtypes.h:186
@ FC_STRUCTPAD3
Definition: ndrtypes.h:212
@ FC_IP
Definition: ndrtypes.h:189
@ FC_LGFARRAY
Definition: ndrtypes.h:167
@ FC_VARIABLE_REPEAT
Definition: ndrtypes.h:224
@ FC_SHORT
Definition: ndrtypes.h:140
@ FC_WCHAR
Definition: ndrtypes.h:139
#define FC_NORMAL_CONFORMANCE
Definition: ndrtypes.h:298
#define Oi_USE_NEW_INIT_ROUTINES
Definition: ndrtypes.h:296
#define FC_SIMPLE_POINTER
Definition: ndrtypes.h:275
#define NDR_CONTEXT_HANDLE_NOSERIALIZE
Definition: ndrtypes.h:286
#define Oi_OBJ_USE_V2_INTERPRETER
Definition: ndrtypes.h:294
#define FC_CONSTANT_CONFORMANCE
Definition: ndrtypes.h:301
#define Oi_HAS_RPCFLAGS
Definition: ndrtypes.h:293
#define FC_ALLOCED_ON_STACK
Definition: ndrtypes.h:274
#define Oi_OBJECT_PROC
Definition: ndrtypes.h:292
#define NDR_STRICT_CONTEXT_HANDLE
Definition: ndrtypes.h:285
const WCHAR * str
static calc_node_t temp
Definition: rpn_ieee.c:38
__WINE_SERVER_LIST_INLINE unsigned int list_count(const struct list *list)
Definition: list.h:155
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198
#define LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, list, type, field)
Definition: list.h:204
__WINE_SERVER_LIST_INLINE struct list * list_next(const struct list *list, const struct list *elem)
Definition: list.h:115
__WINE_SERVER_LIST_INLINE struct list * list_tail(const struct list *list)
Definition: list.h:137
void write_type_right(FILE *h, type_t *t, int is_field)
Definition: header.c:437
unsigned int get_generic_handle_offset(const type_t *type)
Definition: header.c:618
const var_t * get_func_handle_var(const type_t *iface, const var_t *func, unsigned char *explicit_fc, unsigned char *implicit_fc)
Definition: header.c:867
int is_local(const attr_list_t *a)
Definition: header.c:938
int is_attr(const attr_list_t *list, enum attr_type t)
Definition: header.c:99
unsigned int get_context_handle_offset(const type_t *type)
Definition: header.c:598
void write_type_decl_left(FILE *f, type_t *t)
Definition: header.c:566
void write_type_decl(FILE *f, type_t *t, const char *name)
Definition: header.c:561
unsigned int get_attrv(const attr_list_t *list, enum attr_type t)
Definition: header.c:115
int is_aliaschain_attr(const type_t *type, enum attr_type attr)
Definition: header.c:86
void * get_attrp(const attr_list_t *list, enum attr_type t)
Definition: header.c:107
user_type_list_t user_type_list
Definition: header.c:42
int is_object(const type_t *iface)
Definition: header.c:928
int needs_space_after(type_t *t)
Definition: header.c:282
void write_type_left(FILE *h, type_t *t, enum name_type name_type, int declonly)
Definition: header.c:297
int is_ptrchain_attr(const var_t *var, enum attr_type t)
Definition: header.c:66
void error_loc(const char *s,...)
Definition: utils.c:69
const char * sval
Definition: widltypes.h:313
enum expr_type type
Definition: widltypes.h:308
int is_const
Definition: widltypes.h:318
const expr_t * ext
Definition: widltypes.h:314
union _expr_t::@5023 u
const expr_t * ref
Definition: widltypes.h:309
int cval
Definition: widltypes.h:319
statement_type_t type
Definition: parser.h:124
union _statement_t::@5025 u
type_list_t * type_list
Definition: widltypes.h:541
var_t * var
Definition: widltypes.h:539
struct _type_list_t * next
Definition: widltypes.h:528
type_t * type
Definition: widltypes.h:527
attr_list_t * attrs
Definition: widltypes.h:422
unsigned int typestring_offset
Definition: widltypes.h:438
union _type_t::@5024 details
struct iface_details * iface
Definition: widltypes.h:428
const char * name
Definition: widltypes.h:419
struct list entry
Definition: widltypes.h:522
const char * name
Definition: widltypes.h:523
type_t * type
Definition: widltypes.h:453
char * name
Definition: widltypes.h:452
attr_list_t * attrs
Definition: widltypes.h:454
enum storage_class stgclass
Definition: widltypes.h:456
Definition: match.c:390
Definition: cookie.c:202
Definition: http.c:7252
Definition: nis.h:10
unsigned int baseoff
Definition: typegen.c:60
const type_t * cont_type
Definition: typegen.c:58
const expr_t * expr
Definition: typegen.c:61
struct list entry
Definition: typegen.c:56
const type_t * iface
Definition: typegen.c:57
Definition: expr.h:23
const var_t * v
Definition: expr.h:24
const char * attr
Definition: expr.h:25
Definition: query.h:87
Definition: parser.c:44
Definition: fci.c:127
char name[1]
Definition: fci.c:135
Definition: ffs.h:70
Definition: list.h:15
Definition: name.c:39
Definition: send.c:48
Definition: widltypes.h:292
#define max(a, b)
Definition: svc.c:63
static void buffer_size(GLcontext *ctx, GLuint *width, GLuint *height)
Definition: swimpl.c:888
#define LIST_INIT(head)
Definition: queue.h:197
#define LIST_ENTRY(type)
Definition: queue.h:175
static void write_proc_func_header(FILE *file, int indent, const type_t *iface, const var_t *func, unsigned int *offset, unsigned short num_proc)
Definition: typegen.c:1290
static int cant_be_null(const var_t *v)
Definition: typegen.c:379
static const unsigned short IsReturn
Definition: typegen.c:78
static unsigned int field_memsize(const type_t *type, unsigned int *offset)
Definition: typegen.c:1814
static unsigned int write_range_tfs(FILE *file, const attr_list_t *attrs, type_t *type, expr_list_t *range_list, unsigned int *typeformat_offset)
Definition: typegen.c:3561
type_context
Definition: typegen.c:65
@ TYPE_CONTEXT_PARAM
Definition: typegen.c:67
@ TYPE_CONTEXT_CONTAINER
Definition: typegen.c:68
@ TYPE_CONTEXT_CONTAINER_NO_POINTERS
Definition: typegen.c:69
@ TYPE_CONTEXT_TOPLEVELPARAM
Definition: typegen.c:66
static int is_conformance_needed_for_phase(enum remoting_phase phase)
Definition: typegen.c:4105
static int write_pointer_description_offsets(FILE *file, const attr_list_t *attrs, type_t *type, unsigned int *offset_in_memory, unsigned int *offset_in_buffer, unsigned int *typestring_offset)
Definition: typegen.c:2453
static const unsigned short IsBasetype
Definition: typegen.c:79
static type_t * get_user_type(const type_t *t, const char **pname)
Definition: typegen.c:305
static const unsigned short IsSimpleRef
Definition: typegen.c:81
static unsigned int get_stack_size(const var_t *var, int *by_value)
Definition: typegen.c:419
static unsigned int get_required_buffer_size(const var_t *var, unsigned int *alignment, enum pass pass)
Definition: typegen.c:3896
static unsigned int get_required_buffer_size_type(const type_t *type, const char *name, const attr_list_t *attrs, int toplevel_param, unsigned int *alignment)
Definition: typegen.c:3784
void write_pointer_checks(FILE *file, int indent, const var_t *func)
Definition: typegen.c:4845
void declare_stub_args(FILE *file, int indent, const var_t *func)
Definition: typegen.c:4615
enum typegen_type typegen_detect_type(const type_t *type, const attr_list_t *attrs, unsigned int flags)
Definition: typegen.c:329
static unsigned int fields_memsize(const var_list_t *fields, unsigned int *align)
Definition: typegen.c:1823
static unsigned int write_simple_pointer(FILE *file, const attr_list_t *attrs, const type_t *type, enum type_context context)
Definition: typegen.c:2179
static const unsigned short IsOut
Definition: typegen.c:77
static void * get_aliaschain_attrp(const type_t *type, enum attr_type attr)
Definition: typegen.c:191
static void write_branch_type(FILE *file, const type_t *t, unsigned int *tfsoff)
Definition: typegen.c:3272
static int write_base_type(FILE *file, const type_t *type, unsigned int *typestring_offset)
Definition: typegen.c:1554
static unsigned char get_pointer_fc_context(const type_t *type, const attr_list_t *attrs, enum type_context context)
Definition: typegen.c:284
static const unsigned short MustSize
Definition: typegen.c:73
static void write_procformatstring_func(FILE *file, int indent, const type_t *iface, const var_t *func, unsigned int *offset, unsigned short num_proc)
Definition: typegen.c:1425
static void write_remoting_arg(FILE *file, int indent, const var_t *func, const char *local_var_prefix, enum pass pass, enum remoting_phase phase, const var_t *var)
Definition: typegen.c:4201
void write_procformatstring(FILE *file, const statement_list_t *stmts, type_pred_t pred)
Definition: typegen.c:1513
static const char * string_of_type(unsigned char type)
Definition: typegen.c:101
static unsigned int write_nonsimple_pointer(FILE *file, const attr_list_t *attrs, const type_t *type, enum type_context context, unsigned int offset, unsigned int *typeformat_offset)
Definition: typegen.c:2101
static const var_t * find_array_or_string_in_struct(const type_t *type)
Definition: typegen.c:3059
static unsigned int write_array_tfs(FILE *file, const attr_list_t *attrs, type_t *type, const char *name, unsigned int *typestring_offset)
Definition: typegen.c:2950
unsigned int get_size_typeformatstring(const statement_list_t *stmts, type_pred_t pred)
Definition: typegen.c:4609
static int write_embedded_types(FILE *file, const attr_list_t *attrs, type_t *type, const char *name, int write_ptr, unsigned int *tfsoff)
Definition: typegen.c:3694
void write_parameters_init(FILE *file, int indent, const var_t *func, const char *local_var_prefix)
Definition: typegen.c:903
static void get_size_procformatstring_iface(type_t *iface, FILE *file, int indent, unsigned int *size)
Definition: typegen.c:4591
static struct list expr_eval_routines
Definition: typegen.c:53
static void write_formatdesc(FILE *f, int indent, const char *str)
Definition: typegen.c:919
static unsigned int write_pointer_tfs(FILE *file, const attr_list_t *attrs, type_t *type, unsigned int ref_offset, enum type_context context, unsigned int *typestring_offset)
Definition: typegen.c:2228
void write_endpoints(FILE *f, const char *prefix, const str_list_t *list)
Definition: typegen.c:4940
static unsigned char get_basic_fc_signed(const type_t *type)
Definition: typegen.c:228
static const unsigned short MustFree
Definition: typegen.c:74
static unsigned int write_user_tfs(FILE *file, type_t *type, unsigned int *tfsoff)
Definition: typegen.c:2279
void write_user_quad_list(FILE *file)
Definition: typegen.c:4918
void print_phase_basetype(FILE *file, int indent, const char *local_var_prefix, enum remoting_phase phase, enum pass pass, const var_t *var, const char *varname)
Definition: typegen.c:3986
static unsigned int write_type_tfs(FILE *file, int indent, const attr_list_t *attrs, type_t *type, const char *name, enum type_context context, unsigned int *typeformat_offset)
Definition: typegen.c:3589
static void guard_rec(type_t *type)
Definition: typegen.c:824
expr_t * get_size_is_expr(const type_t *t, const char *name)
Definition: typegen.c:4110
static void write_pointer_description(FILE *file, const attr_list_t *attrs, type_t *type, unsigned int *typestring_offset)
Definition: typegen.c:2794
static int is_user_type(const type_t *t)
Definition: typegen.c:324
static unsigned int get_function_buffer_size(const var_t *func, enum pass pass)
static int type_has_full_pointer(const type_t *type, const attr_list_t *attrs, int toplevel_param)
Definition: typegen.c:750
static unsigned int write_old_procformatstring_type(FILE *file, int indent, const var_t *var, int is_return, int is_interpreted)
Definition: typegen.c:1178
static unsigned char get_func_oi2_flags(const var_t *func)
Definition: typegen.c:1115
void write_full_pointer_init(FILE *file, int indent, const var_t *func, int is_server)
Definition: typegen.c:2088
void print(FILE *file, int indent, const char *format, va_list va)
Definition: typegen.c:879
void write_func_param_struct(FILE *file, const type_t *iface, const type_t *func, const char *var_decl, int add_retval)
Definition: typegen.c:4789
static int write_no_repeat_pointer_descriptions(FILE *file, const attr_list_t *attrs, type_t *type, unsigned int *offset_in_memory, unsigned int *offset_in_buffer, unsigned int *typestring_offset)
Definition: typegen.c:2551
static unsigned int write_conf_or_var_desc(FILE *file, const type_t *cont_type, unsigned int baseoff, const type_t *type, const expr_t *expr)
Definition: typegen.c:1571
unsigned char get_pointer_fc(const type_t *type, const attr_list_t *attrs, int toplevel_param)
Definition: typegen.c:258
static unsigned int write_union_tfs(FILE *file, const attr_list_t *attrs, type_t *type, unsigned int *tfsoff)
Definition: typegen.c:3303
static int write_varying_array_pointer_descriptions(FILE *file, const attr_list_t *attrs, type_t *type, unsigned int *offset_in_memory, unsigned int *offset_in_buffer, unsigned int *typestring_offset)
Definition: typegen.c:2718
void write_expr_eval_routine_list(FILE *file, const char *iface)
Definition: typegen.c:4896
static unsigned char get_array_fc(const type_t *type)
Definition: typegen.c:617
static unsigned short user_type_offset(const char *name)
Definition: typegen.c:804
static unsigned char get_contexthandle_flags(const type_t *iface, const attr_list_t *attrs, const type_t *type)
Definition: typegen.c:444
int decl_indirect(const type_t *t)
Definition: typegen.c:948
void write_typeformatstring(FILE *file, const statement_list_t *stmts, type_pred_t pred)
Definition: typegen.c:3761
#define ROUND_SIZE(size, alignment)
Definition: typegen.c:45
static const unsigned short IsByValue
Definition: typegen.c:80
void write_exceptions(FILE *file)
Definition: typegen.c:5033
static int is_embedded_complex(const type_t *type)
Definition: typegen.c:835
static int is_non_complex_struct(const type_t *type)
Definition: typegen.c:697
unsigned char get_struct_fc(const type_t *type)
Definition: typegen.c:478
void write_remoting_arguments(FILE *file, int indent, const var_t *func, const char *local_var_prefix, enum pass pass, enum remoting_phase phase)
Definition: typegen.c:4559
static void write_array_element_type(FILE *file, const attr_list_t *attrs, const type_t *type, int cont_is_complex, unsigned int *tfsoff)
Definition: typegen.c:2382
int is_full_pointer_function(const var_t *func)
Definition: typegen.c:2075
static unsigned char get_parameter_fc(const var_t *var, int is_return, unsigned short *flags, unsigned int *stack_size, unsigned int *typestring_offset)
Definition: typegen.c:958
static unsigned int write_ip_tfs(FILE *file, const attr_list_t *attrs, type_t *type, unsigned int *typeformat_offset)
Definition: typegen.c:3469
unsigned int get_size_procformatstring_func(const type_t *iface, const var_t *func)
Definition: typegen.c:4584
static unsigned int write_new_procformatstring_type(FILE *file, int indent, const var_t *var, int is_return, unsigned int *stack_offset)
Definition: typegen.c:1143
unsigned char get_basic_fc(const type_t *type)
Definition: typegen.c:204
void write_client_call_routine(FILE *file, const type_t *iface, const var_t *func, const char *prefix, unsigned int proc_offset)
Definition: typegen.c:4974
unsigned int type_memsize(const type_t *t)
Definition: typegen.c:1975
static int get_padding(const var_list_t *fields)
Definition: typegen.c:396
static const unsigned short IsIn
Definition: typegen.c:76
int is_interpreted_func(const type_t *iface, const var_t *func)
Definition: typegen.c:1240
static int write_fixed_array_pointer_descriptions(FILE *file, const attr_list_t *attrs, type_t *type, unsigned int *offset_in_memory, unsigned int *offset_in_buffer, unsigned int *typestring_offset)
Definition: typegen.c:2602
static void write_end(FILE *file, unsigned int *tfsoff)
Definition: typegen.c:2412
int write_expr_eval_routines(FILE *file, const char *iface)
Definition: typegen.c:4857
static const char * get_context_handle_type_name(const type_t *type)
Definition: typegen.c:850
void write_parameter_conf_or_var_exprs(FILE *file, int indent, const char *local_var_prefix, enum remoting_phase phase, const var_t *var, int valid_variance)
Definition: typegen.c:4129
static int processed(const type_t *type)
Definition: typegen.c:2254
static const type_t * current_iface
Definition: typegen.c:51
unsigned int get_size_procformatstring(const statement_list_t *stmts, type_pred_t pred)
Definition: typegen.c:4602
#define ROUNDING(size, alignment)
Definition: typegen.c:47
void write_procformatstring_offsets(FILE *file, const type_t *iface)
Definition: typegen.c:1535
static void print_file(FILE *file, int indent, const char *format,...) __attribute__((format(printf
Definition: typegen.c:871
static void write_iface_procformatstring(type_t *iface, FILE *file, int indent, unsigned int *offset)
Definition: typegen.c:1499
static void write_var_init(FILE *file, int indent, const type_t *t, const char *n, const char *local_var_prefix)
Definition: typegen.c:891
static unsigned int write_contexthandle_tfs(FILE *file, const attr_list_t *attrs, type_t *type, int toplevel_param, unsigned int *typeformat_offset)
Definition: typegen.c:3512
static void print_start_tfs_comment(FILE *file, type_t *t, unsigned int tfsoff)
Definition: typegen.c:2221
static void write_member_type(FILE *file, const type_t *cont, int cont_is_complex, const attr_list_t *attrs, const type_t *type, unsigned int *corroff, unsigned int *tfsoff)
Definition: typegen.c:2342
static void for_each_iface(const statement_list_t *stmts, void(*proc)(type_t *iface, FILE *file, int indent, unsigned int *offset), type_pred_t pred, FILE *file, int indent, unsigned int *offset)
Definition: typegen.c:1480
static unsigned char get_enum_fc(const type_t *type)
Definition: typegen.c:296
static unsigned int clamp_align(unsigned int align)
Definition: typegen.c:251
static void process_tfs_iface(type_t *iface, FILE *file, int indent, unsigned int *offset)
Definition: typegen.c:3700
static unsigned int process_tfs(FILE *file, const statement_list_t *stmts, type_pred_t pred)
Definition: typegen.c:3753
static int user_type_has_variable_size(const type_t *t)
Definition: typegen.c:2259
static int write_conformant_array_pointer_descriptions(FILE *file, const attr_list_t *attrs, type_t *type, unsigned int offset_in_memory, unsigned int *typestring_offset)
Definition: typegen.c:2675
static unsigned int write_struct_tfs(FILE *file, type_t *type, const char *name, unsigned int *tfsoff)
Definition: typegen.c:3139
unsigned int type_memsize_and_alignment(const type_t *t, unsigned int *align)
Definition: typegen.c:1866
void write_full_pointer_free(FILE *file, int indent, const var_t *func)
Definition: typegen.c:2095
static int type_has_pointers(const type_t *type)
Definition: typegen.c:703
static void write_descriptors(FILE *file, type_t *type, unsigned int *tfsoff)
Definition: typegen.c:2423
static unsigned int write_string_tfs(FILE *file, const attr_list_t *attrs, type_t *type, enum type_context context, const char *name, unsigned int *typestring_offset)
Definition: typegen.c:2840
static const type_t * current_structure
Definition: typegen.c:49
void write_formatstringsdecl(FILE *f, int indent, const statement_list_t *stmts, type_pred_t pred)
Definition: typegen.c:929
static void write_struct_members(FILE *file, const type_t *type, int is_complex, unsigned int *corroff, unsigned int *typestring_offset)
Definition: typegen.c:3080
static void update_tfsoff(type_t *type, unsigned int offset, FILE *file)
Definition: typegen.c:818
static void print_phase_function(FILE *file, int indent, const char *type, const char *local_var_prefix, enum remoting_phase phase, const var_t *var, unsigned int type_offset)
Definition: typegen.c:3946
static const unsigned short IsPipe
Definition: typegen.c:75
static unsigned int union_memsize(const var_list_t *fields, unsigned int *pmaxa)
Definition: typegen.c:1846
void assign_stub_out_args(FILE *file, int indent, const var_t *func, const char *local_var_prefix)
Definition: typegen.c:4676
#define WRITE_FCTYPE(file, fctype, typestring_offset)
Definition: typegen.c:862
static const var_t * current_func
Definition: typegen.c:50
static unsigned int type_buffer_alignment(const type_t *t)
Definition: typegen.c:1981
static unsigned int get_rpc_flags(const attr_list_t *attrs)
Definition: typegen.c:466
pass
Definition: typegen.h:25
@ PASS_RETURN
Definition: typegen.h:28
@ PASS_OUT
Definition: typegen.h:27
@ PASS_IN
Definition: typegen.h:26
int(* type_pred_t)(const type_t *)
Definition: typegen.h:63
remoting_phase
Definition: typegen.h:32
@ PHASE_MARSHAL
Definition: typegen.h:34
@ PHASE_BUFFERSIZE
Definition: typegen.h:33
@ PHASE_FREE
Definition: typegen.h:36
@ PHASE_UNMARSHAL
Definition: typegen.h:35
@ TDT_IGNORE_STRINGS
Definition: typegen.h:42
@ TDT_ALL_TYPES
Definition: typegen.h:41
@ TDT_IGNORE_RANGES
Definition: typegen.h:43
typegen_type
Definition: typegen.h:47
@ TGT_INVALID
Definition: typegen.h:48
@ TGT_USER_TYPE
Definition: typegen.h:49
@ TGT_POINTER
Definition: typegen.h:53
@ TGT_UNION
Definition: typegen.h:59
@ TGT_STRUCT
Definition: typegen.h:58
@ TGT_ARRAY
Definition: typegen.h:54
@ TGT_CTXT_HANDLE_POINTER
Definition: typegen.h:51
@ TGT_ENUM
Definition: typegen.h:57
@ TGT_CTXT_HANDLE
Definition: typegen.h:50
@ TGT_RANGE
Definition: typegen.h:60
@ TGT_STRING
Definition: typegen.h:52
@ TGT_BASIC
Definition: typegen.h:56
@ TGT_IFACE_POINTER
Definition: typegen.h:55
static int type_array_is_decl_as_ptr(const type_t *type)
Definition: typetree.h:260
static enum type_type type_get_type(const type_t *type)
Definition: typetree.h:68
static unsigned char type_pointer_get_default_fc(const type_t *type)
Definition: typetree.h:299
static unsigned char type_array_get_ptr_default_fc(const type_t *type)
Definition: typetree.h:267
static int type_basic_get_sign(const type_t *type)
Definition: typetree.h:80
static var_t * type_union_get_switch_value(const type_t *type)
Definition: typetree.h:120
static type_t * type_function_get_rettype(const type_t *type)
Definition: typetree.h:108
static expr_t * type_array_get_variance(const type_t *type)
Definition: typetree.h:246
static int type_array_has_conformance(const type_t *type)
Definition: typetree.h:218
static var_list_t * type_union_get_cases(const type_t *type)
Definition: typetree.h:134
@ NAME_DEFAULT
Definition: typetree.h:28
static enum type_basic_type type_basic_get_type(const type_t *type)
Definition: typetree.h:73
static type_t * type_alias_get_aliasee(const type_t *type)
Definition: typetree.h:279
static var_t * type_function_get_retval(const type_t *type)
Definition: typetree.h:101
static expr_t * type_array_get_conformance(const type_t *type)
Definition: typetree.h:239
static var_list_t * type_struct_get_fields(const type_t *type)
Definition: typetree.h:87
static var_list_t * type_encapsulated_union_get_fields(const type_t *type)
Definition: typetree.h:127
static int type_is_alias(const type_t *type)
Definition: typetree.h:274
static type_t * type_iface_get_inherit(const type_t *type)
Definition: typetree.h:158
static type_t * type_array_get_element(const type_t *type)
Definition: typetree.h:253
static unsigned int type_array_get_dim(const type_t *type)
Definition: typetree.h:232
static statement_list_t * type_iface_get_stmts(const type_t *type)
Definition: typetree.h:151
static type_t * type_pointer_get_ref(const type_t *type)
Definition: typetree.h:292
static int type_array_has_variance(const type_t *type)
Definition: typetree.h:225
static unsigned stack_offset(compile_ctx_t *ctx)
Definition: compile.c:349
unsigned int pointer_size
Definition: widl.c:158
int win64_packing
Definition: widl.c:128
int win32_packing
Definition: widl.c:127
enum stub_mode get_stub_mode(void)
Definition: widl.c:211
@ MODE_Os
Definition: widl.h:87
@ MODE_Oif
Definition: widl.h:89
void set_all_tfswrite(int val)
@ TYPE_ENUM
Definition: widltypes.h:404
@ TYPE_BITFIELD
Definition: widltypes.h:415
@ TYPE_BASIC
Definition: widltypes.h:403
@ TYPE_UNION
Definition: widltypes.h:407
@ TYPE_ALIAS
Definition: widltypes.h:408
@ TYPE_POINTER
Definition: widltypes.h:413
@ TYPE_VOID
Definition: widltypes.h:402
@ TYPE_ENCAPSULATED_UNION
Definition: widltypes.h:406
@ TYPE_COCLASS
Definition: widltypes.h:410
@ TYPE_STRUCT
Definition: widltypes.h:405
@ TYPE_MODULE
Definition: widltypes.h:409
@ TYPE_INTERFACE
Definition: widltypes.h:412
@ TYPE_ARRAY
Definition: widltypes.h:414
@ TYPE_FUNCTION
Definition: widltypes.h:411
@ EXPR_IDENTIFIER
Definition: widltypes.h:180
@ EXPR_PPTR
Definition: widltypes.h:183
@ STG_NONE
Definition: widltypes.h:232
void clear_all_offsets(void)
attr_type
Definition: widltypes.h:69
@ ATTR_BROADCAST
Definition: widltypes.h:78
@ ATTR_IN
Definition: widltypes.h:118
@ ATTR_POINTERTYPE
Definition: widltypes.h:142
@ ATTR_SWITCHTYPE
Definition: widltypes.h:160
@ ATTR_CONTEXTHANDLE
Definition: widltypes.h:85
@ ATTR_DECODE
Definition: widltypes.h:87
@ ATTR_ASYNC
Definition: widltypes.h:74
@ ATTR_CASE
Definition: widltypes.h:81
@ ATTR_NOTIFY
Definition: widltypes.h:131
@ ATTR_ENCODE
Definition: widltypes.h:99
@ ATTR_UUID
Definition: widltypes.h:166
@ ATTR_DEFAULT
Definition: widltypes.h:88
@ ATTR_RANGE
Definition: widltypes.h:149
@ ATTR_ALLOCATE
Definition: widltypes.h:71
@ ATTR_MAYBE
Definition: widltypes.h:125
@ ATTR_MESSAGE
Definition: widltypes.h:126
@ ATTR_IDEMPOTENT
Definition: widltypes.h:113
@ ATTR_IIDIS
Definition: widltypes.h:115
@ ATTR_OUT
Definition: widltypes.h:138
@ ATTR_OPTIMIZE
Definition: widltypes.h:136
@ ATTR_STRICTCONTEXTHANDLE
Definition: widltypes.h:157
@ ATTR_NOTIFYFLAG
Definition: widltypes.h:132
@ ATTR_V1ENUM
Definition: widltypes.h:167
@ ATTR_WIREMARSHAL
Definition: widltypes.h:171
@ ATTR_SWITCHIS
Definition: widltypes.h:159
@ STMT_TYPE
Definition: widltypes.h:242
@ STMT_DECLARATION
Definition: widltypes.h:241
@ STMT_TYPEDEF
Definition: widltypes.h:245
static enum type_type type_get_type_detect_alias(const type_t *type)
Definition: widltypes.h:590
static var_list_t * type_get_function_args(const type_t *func_type)
Definition: widltypes.h:585
@ TYPE_BASIC_DOUBLE
Definition: widltypes.h:275
@ TYPE_BASIC_INT32
Definition: widltypes.h:265
@ TYPE_BASIC_ERROR_STATUS_T
Definition: widltypes.h:276
@ TYPE_BASIC_CHAR
Definition: widltypes.h:270
@ TYPE_BASIC_WCHAR
Definition: widltypes.h:273
@ TYPE_BASIC_INT16
Definition: widltypes.h:264
@ TYPE_BASIC_HYPER
Definition: widltypes.h:271
@ TYPE_BASIC_HANDLE
Definition: widltypes.h:277
@ TYPE_BASIC_INT8
Definition: widltypes.h:263
@ TYPE_BASIC_INT3264
Definition: widltypes.h:268
@ TYPE_BASIC_LONG
Definition: widltypes.h:269
@ TYPE_BASIC_INT64
Definition: widltypes.h:266
@ TYPE_BASIC_BYTE
Definition: widltypes.h:272
@ TYPE_BASIC_INT
Definition: widltypes.h:267
@ TYPE_BASIC_FLOAT
Definition: widltypes.h:274
#define STATEMENTS_FOR_EACH_FUNC(stmt, stmts)
Definition: widltypes.h:597
void * arg
Definition: msvc.h:10
#define const
Definition: zconf.h:233