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