xref: /titanic_41/usr/src/tools/ndrgen/ndr_anal.c (revision d0e518695adc90b82233b99af7dffbb3d3f92c00)
1*d0e51869Samw /*
2*d0e51869Samw  * CDDL HEADER START
3*d0e51869Samw  *
4*d0e51869Samw  * The contents of this file are subject to the terms of the
5*d0e51869Samw  * Common Development and Distribution License (the "License").
6*d0e51869Samw  * You may not use this file except in compliance with the License.
7*d0e51869Samw  *
8*d0e51869Samw  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*d0e51869Samw  * or http://www.opensolaris.org/os/licensing.
10*d0e51869Samw  * See the License for the specific language governing permissions
11*d0e51869Samw  * and limitations under the License.
12*d0e51869Samw  *
13*d0e51869Samw  * When distributing Covered Code, include this CDDL HEADER in each
14*d0e51869Samw  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*d0e51869Samw  * If applicable, add the following below this CDDL HEADER, with the
16*d0e51869Samw  * fields enclosed by brackets "[]" replaced with your own identifying
17*d0e51869Samw  * information: Portions Copyright [yyyy] [name of copyright owner]
18*d0e51869Samw  *
19*d0e51869Samw  * CDDL HEADER END
20*d0e51869Samw  */
21*d0e51869Samw 
22*d0e51869Samw /*
23*d0e51869Samw  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
24*d0e51869Samw  * Use is subject to license terms.
25*d0e51869Samw  */
26*d0e51869Samw 
27*d0e51869Samw #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*d0e51869Samw 
29*d0e51869Samw #include <strings.h>
30*d0e51869Samw #include <string.h>
31*d0e51869Samw #include "ndrgen.h"
32*d0e51869Samw #include "y.tab.h"
33*d0e51869Samw 
34*d0e51869Samw 
35*d0e51869Samw #define	ALLOW_NOTHING	0
36*d0e51869Samw #define	ALLOW_VARSIZE	1
37*d0e51869Samw #define	ALLOW_INOUT	2
38*d0e51869Samw #define	ALLOW_CASE	4
39*d0e51869Samw #define	ALLOW_NO_UNIONS	8		/* for topmost structures */
40*d0e51869Samw #define	ALLOW_NO_SWITCH 16
41*d0e51869Samw 
42*d0e51869Samw struct tup {
43*d0e51869Samw 	struct tup		*up;
44*d0e51869Samw 	ndr_typeinfo_t		*ti;
45*d0e51869Samw };
46*d0e51869Samw 
47*d0e51869Samw static void type_ident_decl(ndr_typeinfo_t *, char *, size_t, char *);
48*d0e51869Samw static void type_ident_decl1(struct tup *, char *, size_t, char *);
49*d0e51869Samw static void analyze_typeinfo_list(void);
50*d0e51869Samw static void analyze_typeinfo_typedef(ndr_typeinfo_t *);
51*d0e51869Samw static void analyze_typeinfo_struct(ndr_typeinfo_t *);
52*d0e51869Samw static void analyze_typeinfo_union(ndr_typeinfo_t *);
53*d0e51869Samw static void analyze_typeinfo_aggregate_finish(ndr_typeinfo_t *);
54*d0e51869Samw static void analyze_member(ndr_node_t *, ndr_member_t *, unsigned long *, int);
55*d0e51869Samw static void seed_basic_types(void);
56*d0e51869Samw static void seed_construct_types(void);
57*d0e51869Samw static void append_typeinfo(ndr_typeinfo_t *);
58*d0e51869Samw static ndr_typeinfo_t *bind_typeinfo(ndr_typeinfo_t *);
59*d0e51869Samw static ndr_typeinfo_t *find_typeinfo_by_name(ndr_node_t *);
60*d0e51869Samw static void determine_advice(ndr_advice_t *, ndr_node_t *);
61*d0e51869Samw static ndr_node_t *find_advice(ndr_node_t *advice_list, int label);
62*d0e51869Samw 
63*d0e51869Samw 
64*d0e51869Samw void
analyze(void)65*d0e51869Samw analyze(void)
66*d0e51869Samw {
67*d0e51869Samw 	seed_basic_types();
68*d0e51869Samw 	seed_construct_types();
69*d0e51869Samw 
70*d0e51869Samw 	analyze_typeinfo_list();
71*d0e51869Samw }
72*d0e51869Samw 
73*d0e51869Samw void
show_typeinfo_list(void)74*d0e51869Samw show_typeinfo_list(void)
75*d0e51869Samw {
76*d0e51869Samw 	ndr_typeinfo_t		*ti;
77*d0e51869Samw 	ndr_typeinfo_t		*tdti;
78*d0e51869Samw 	int			i;
79*d0e51869Samw 	ndr_member_t		*mem;
80*d0e51869Samw 	char			*p;
81*d0e51869Samw 	char			fname_type[NDLBUFSZ];
82*d0e51869Samw 
83*d0e51869Samw 	for (ti = typeinfo_list; ti; ti = ti->next) {
84*d0e51869Samw 		switch (ti->type_op) {
85*d0e51869Samw 		case STRUCT_KW:
86*d0e51869Samw 			p = "struct";
87*d0e51869Samw 			break;
88*d0e51869Samw 
89*d0e51869Samw 		case UNION_KW:
90*d0e51869Samw 			p = "union";
91*d0e51869Samw 			break;
92*d0e51869Samw 
93*d0e51869Samw 		case TYPEDEF_KW:
94*d0e51869Samw 			p = "typedef";
95*d0e51869Samw 			break;
96*d0e51869Samw 
97*d0e51869Samw 		case STRING_KW:
98*d0e51869Samw 		case STAR:
99*d0e51869Samw 		case LB:
100*d0e51869Samw 		case BASIC_TYPE:
101*d0e51869Samw 			type_extern_suffix(ti, fname_type, NDLBUFSZ);
102*d0e51869Samw 			if (ti->is_extern) {
103*d0e51869Samw 				(void) printf("extern ndr_%s()\n",
104*d0e51869Samw 				    fname_type);
105*d0e51869Samw 			} else if (!ti->is_referenced) {
106*d0e51869Samw 				(void) printf("implied ndr_%s\n", fname_type);
107*d0e51869Samw 			}
108*d0e51869Samw 			continue;
109*d0e51869Samw 
110*d0e51869Samw 		default:
111*d0e51869Samw 			(void) printf("show_typeinfo skipping %d\n",
112*d0e51869Samw 			    ti->type_op);
113*d0e51869Samw 			continue;
114*d0e51869Samw 		}
115*d0e51869Samw 
116*d0e51869Samw 		(void) printf("\n\n");
117*d0e51869Samw 		show_advice(&ti->advice, 0);
118*d0e51869Samw 		(void) printf("%s %s {\n", p, ti->type_name->n_sym->name);
119*d0e51869Samw 
120*d0e51869Samw 		for (i = 0; i < ti->n_member; i++) {
121*d0e51869Samw 			mem = &ti->member[i];
122*d0e51869Samw 			show_advice(&mem->advice, 2);
123*d0e51869Samw 			type_extern_suffix(mem->type, fname_type, NDLBUFSZ);
124*d0e51869Samw 			(void) printf("    %-16s ndr_%-13s",
125*d0e51869Samw 			    mem->name, fname_type);
126*d0e51869Samw 
127*d0e51869Samw 			tdti = mem->type;
128*d0e51869Samw 			(void) printf(" fsiz=%d vsiz=%d algn=%d off=%d\n",
129*d0e51869Samw 			    tdti->size_fixed_part,
130*d0e51869Samw 			    tdti->size_variable_part,
131*d0e51869Samw 			    tdti->alignment,
132*d0e51869Samw 			    mem->pdu_offset);
133*d0e51869Samw 		}
134*d0e51869Samw 
135*d0e51869Samw 		(void) printf("} fsiz=%d vsiz=%d algn=%d comp=%d ptrs=%d\n",
136*d0e51869Samw 		    ti->size_fixed_part,
137*d0e51869Samw 		    ti->size_variable_part,
138*d0e51869Samw 		    ti->alignment,
139*d0e51869Samw 		    ti->complete,
140*d0e51869Samw 		    ti->has_pointers);
141*d0e51869Samw 	}
142*d0e51869Samw }
143*d0e51869Samw 
144*d0e51869Samw void
type_extern_suffix(ndr_typeinfo_t * tsti,char * funcbuf,size_t buflen)145*d0e51869Samw type_extern_suffix(ndr_typeinfo_t *tsti, char *funcbuf, size_t buflen)
146*d0e51869Samw {
147*d0e51869Samw 	ndr_typeinfo_t		*ti;
148*d0e51869Samw 	char			*p_fb = funcbuf;
149*d0e51869Samw 
150*d0e51869Samw 	*p_fb = 0;
151*d0e51869Samw 
152*d0e51869Samw 	for (ti = tsti; ti; ti = ti->type_down) {
153*d0e51869Samw 		switch (ti->type_op) {
154*d0e51869Samw 		case BASIC_TYPE:
155*d0e51869Samw 		case STRUCT_KW:
156*d0e51869Samw 		case TYPEDEF_KW:
157*d0e51869Samw 		case UNION_KW:
158*d0e51869Samw 			(void) snprintf(p_fb, buflen, "_%s",
159*d0e51869Samw 			    ti->type_name->n_sym->name);
160*d0e51869Samw 			break;
161*d0e51869Samw 
162*d0e51869Samw 		case STAR:
163*d0e51869Samw 			(void) strlcpy(p_fb, "p", buflen);
164*d0e51869Samw 			break;
165*d0e51869Samw 
166*d0e51869Samw 		case LB:
167*d0e51869Samw 			if (ti->type_dim) {
168*d0e51869Samw 				(void) snprintf(p_fb, buflen, "a%ld",
169*d0e51869Samw 				    ti->type_dim->n_int);
170*d0e51869Samw 			} else {
171*d0e51869Samw 				(void) snprintf(p_fb, buflen, "ac");
172*d0e51869Samw 			}
173*d0e51869Samw 			break;
174*d0e51869Samw 
175*d0e51869Samw 		case STRING_KW:
176*d0e51869Samw 			(void) strlcpy(p_fb, "s", buflen);
177*d0e51869Samw 			break;
178*d0e51869Samw 
179*d0e51869Samw 		default:
180*d0e51869Samw 			(void) snprintf(p_fb, buflen, "?<%d>", ti->type_op);
181*d0e51869Samw 			break;
182*d0e51869Samw 		}
183*d0e51869Samw 		while (*p_fb)
184*d0e51869Samw 			p_fb++;
185*d0e51869Samw 	}
186*d0e51869Samw }
187*d0e51869Samw 
188*d0e51869Samw static void
type_ident_decl1(struct tup * tup,char * funcbuf,size_t buflen,char * ident)189*d0e51869Samw type_ident_decl1(struct tup *tup, char *funcbuf, size_t buflen, char *ident)
190*d0e51869Samw {
191*d0e51869Samw 	ndr_typeinfo_t		*ti;
192*d0e51869Samw 	char			fb[NDLBUFSZ];
193*d0e51869Samw 	char			*p;
194*d0e51869Samw 
195*d0e51869Samw 	if (!tup) {
196*d0e51869Samw 		(void) strlcpy(funcbuf, ident, buflen);
197*d0e51869Samw 		return;
198*d0e51869Samw 	}
199*d0e51869Samw 	ti = tup->ti;
200*d0e51869Samw 
201*d0e51869Samw 	switch (ti->type_op) {
202*d0e51869Samw 	case BASIC_TYPE:
203*d0e51869Samw 	case TYPEDEF_KW:
204*d0e51869Samw 		type_ident_decl1(tup->up, fb, NDLBUFSZ, ident);
205*d0e51869Samw 		(void) snprintf(funcbuf, buflen, "%s%s%s%s",
206*d0e51869Samw 		    "", ti->type_name->n_sym->name, *fb ? " " : "", fb);
207*d0e51869Samw 		break;
208*d0e51869Samw 
209*d0e51869Samw 	case STRUCT_KW:
210*d0e51869Samw 		type_ident_decl1(tup->up, fb, NDLBUFSZ, ident);
211*d0e51869Samw 		(void) snprintf(funcbuf, buflen, "%s%s%s%s",
212*d0e51869Samw 		    "struct ", ti->type_name->n_sym->name, *fb ? " " : "", fb);
213*d0e51869Samw 		break;
214*d0e51869Samw 
215*d0e51869Samw 	case UNION_KW:
216*d0e51869Samw 		type_ident_decl1(tup->up, fb, NDLBUFSZ, ident);
217*d0e51869Samw 		(void) snprintf(funcbuf, buflen, "%s%s%s%s",
218*d0e51869Samw 		    "union ", ti->type_name->n_sym->name, *fb ? " " : "", fb);
219*d0e51869Samw 		break;
220*d0e51869Samw 
221*d0e51869Samw 	case STAR:
222*d0e51869Samw 		*funcbuf = '*';
223*d0e51869Samw 		type_ident_decl1(tup->up, funcbuf+1, buflen - 1, ident);
224*d0e51869Samw 		break;
225*d0e51869Samw 
226*d0e51869Samw 	case LB:
227*d0e51869Samw 		p = fb;
228*d0e51869Samw 		*p++ = '(';
229*d0e51869Samw 		type_ident_decl1(tup->up, p, NDLBUFSZ - 1, ident);
230*d0e51869Samw 		if (*p == '*') {
231*d0e51869Samw 			p = fb;
232*d0e51869Samw 			(void) strlcat(p, ")", NDLBUFSZ);
233*d0e51869Samw 		}
234*d0e51869Samw 		if (ti->type_dim) {
235*d0e51869Samw 			(void) snprintf(funcbuf, buflen, "%s[%ld]",
236*d0e51869Samw 			    p, ti->type_dim->n_int);
237*d0e51869Samw 		} else {
238*d0e51869Samw 			(void) snprintf(funcbuf, buflen,
239*d0e51869Samw 			    "%s[NDR_ANYSIZE_DIM]", p);
240*d0e51869Samw 		}
241*d0e51869Samw 		break;
242*d0e51869Samw 
243*d0e51869Samw 	case STRING_KW:
244*d0e51869Samw 		p = fb;
245*d0e51869Samw 		*p++ = '(';
246*d0e51869Samw 		type_ident_decl1(tup->up, p, NDLBUFSZ - 1, ident);
247*d0e51869Samw 		if (*p == '*') {
248*d0e51869Samw 			p = fb;
249*d0e51869Samw 			(void) strlcat(p, ")", NDLBUFSZ);
250*d0e51869Samw 		}
251*d0e51869Samw 		(void) snprintf(funcbuf, buflen, "%s[NDR_STRING_DIM]", p);
252*d0e51869Samw 		break;
253*d0e51869Samw 
254*d0e51869Samw 	default:
255*d0e51869Samw 		compile_error("unknown type or keyword <%d>", ti->type_op);
256*d0e51869Samw 		break;
257*d0e51869Samw 	}
258*d0e51869Samw }
259*d0e51869Samw 
260*d0e51869Samw static void
type_ident_decl(ndr_typeinfo_t * tsti,char * funcbuf,size_t buflen,char * ident)261*d0e51869Samw type_ident_decl(ndr_typeinfo_t *tsti, char *funcbuf, size_t buflen, char *ident)
262*d0e51869Samw {
263*d0e51869Samw 	ndr_typeinfo_t		*ti;
264*d0e51869Samw 	struct tup		tup_tab[40];
265*d0e51869Samw 	struct tup		*tup;
266*d0e51869Samw 	struct tup		*up = 0;
267*d0e51869Samw 	int			n_tt = 0;
268*d0e51869Samw 
269*d0e51869Samw 	for (ti = tsti; ti; ti = ti->type_down, n_tt++) {
270*d0e51869Samw 		tup = &tup_tab[n_tt];
271*d0e51869Samw 		tup->up = up;
272*d0e51869Samw 		tup->ti = ti;
273*d0e51869Samw 		up = tup;
274*d0e51869Samw 	}
275*d0e51869Samw 
276*d0e51869Samw 	type_ident_decl1(up, funcbuf, buflen, ident);
277*d0e51869Samw }
278*d0e51869Samw 
279*d0e51869Samw void
type_null_decl(ndr_typeinfo_t * tsti,char * funcbuf,size_t buflen)280*d0e51869Samw type_null_decl(ndr_typeinfo_t *tsti, char *funcbuf, size_t buflen)
281*d0e51869Samw {
282*d0e51869Samw 	funcbuf[0] = '(';
283*d0e51869Samw 	type_ident_decl(tsti, funcbuf+1, buflen, "");
284*d0e51869Samw 	(void) strlcat(funcbuf, ")", buflen);
285*d0e51869Samw }
286*d0e51869Samw 
287*d0e51869Samw void
type_name_decl(ndr_typeinfo_t * tsti,char * funcbuf,size_t buflen,char * name)288*d0e51869Samw type_name_decl(ndr_typeinfo_t *tsti, char *funcbuf, size_t buflen, char *name)
289*d0e51869Samw {
290*d0e51869Samw 	type_ident_decl(tsti, funcbuf, buflen, name);
291*d0e51869Samw }
292*d0e51869Samw 
293*d0e51869Samw void
show_advice(ndr_advice_t * adv,int indent)294*d0e51869Samw show_advice(ndr_advice_t *adv, int indent)
295*d0e51869Samw {
296*d0e51869Samw 	int		i;
297*d0e51869Samw 	int		n = 0;
298*d0e51869Samw 
299*d0e51869Samw 	for (i = 0; i < N_ADVICE; i++) {
300*d0e51869Samw 		if (!adv->a_nodes[i])
301*d0e51869Samw 			continue;
302*d0e51869Samw 
303*d0e51869Samw 		if (n++ == 0)
304*d0e51869Samw 			(void) printf("%-*s[", indent, "");
305*d0e51869Samw 		else
306*d0e51869Samw 			(void) printf(" ");
307*d0e51869Samw 
308*d0e51869Samw 		print_node(adv->a_nodes[i]);
309*d0e51869Samw 	}
310*d0e51869Samw 
311*d0e51869Samw 	if (n)
312*d0e51869Samw 		(void) printf("]\n");
313*d0e51869Samw }
314*d0e51869Samw 
315*d0e51869Samw static void
analyze_typeinfo_list(void)316*d0e51869Samw analyze_typeinfo_list(void)
317*d0e51869Samw {
318*d0e51869Samw 	ndr_typeinfo_t		*ti;
319*d0e51869Samw 
320*d0e51869Samw 	for (ti = typeinfo_list; ti; ti = ti->next) {
321*d0e51869Samw 		switch (ti->type_op) {
322*d0e51869Samw 		case STRUCT_KW:
323*d0e51869Samw 			analyze_typeinfo_struct(ti);
324*d0e51869Samw 			break;
325*d0e51869Samw 
326*d0e51869Samw 		case UNION_KW:
327*d0e51869Samw 			analyze_typeinfo_union(ti);
328*d0e51869Samw 			break;
329*d0e51869Samw 
330*d0e51869Samw 		case TYPEDEF_KW:
331*d0e51869Samw 			analyze_typeinfo_typedef(ti);
332*d0e51869Samw 			break;
333*d0e51869Samw 		}
334*d0e51869Samw 	}
335*d0e51869Samw }
336*d0e51869Samw 
337*d0e51869Samw static void
analyze_typeinfo_typedef(ndr_typeinfo_t * ti)338*d0e51869Samw analyze_typeinfo_typedef(ndr_typeinfo_t *ti)
339*d0e51869Samw {
340*d0e51869Samw 	ndr_node_t		*mem_np;
341*d0e51869Samw 	ndr_member_t		*mem;
342*d0e51869Samw 	int			i;
343*d0e51869Samw 	int			allow;
344*d0e51869Samw 	unsigned long		offset;
345*d0e51869Samw 
346*d0e51869Samw 	assert(ti->type_op == TYPEDEF_KW);
347*d0e51869Samw 
348*d0e51869Samw 	/*
349*d0e51869Samw 	 * Snarf the advice.
350*d0e51869Samw 	 */
351*d0e51869Samw 	determine_advice(&ti->advice, ti->definition->n_c_advice);
352*d0e51869Samw 
353*d0e51869Samw 	/*
354*d0e51869Samw 	 * Convert the members to table.
355*d0e51869Samw 	 * Determine layout metrics along the way.
356*d0e51869Samw 	 */
357*d0e51869Samw 	mem_np = ti->definition->n_c_members;
358*d0e51869Samw 	i = 0;
359*d0e51869Samw 	offset = 0;
360*d0e51869Samw 	assert(i < ti->n_member);
361*d0e51869Samw 	mem = &ti->member[i];
362*d0e51869Samw 
363*d0e51869Samw 	allow = ALLOW_NO_SWITCH;
364*d0e51869Samw 
365*d0e51869Samw 	analyze_member(mem_np, mem,
366*d0e51869Samw 	    &offset,		/* progress offset */
367*d0e51869Samw 	    allow);		/* see above */
368*d0e51869Samw 
369*d0e51869Samw 	assert(1 == ti->n_member);
370*d0e51869Samw 
371*d0e51869Samw 	analyze_typeinfo_aggregate_finish(ti);
372*d0e51869Samw 
373*d0e51869Samw 	/* Align offset to determine overall size */
374*d0e51869Samw 	while (offset & ti->alignment)
375*d0e51869Samw 		offset++;
376*d0e51869Samw 
377*d0e51869Samw 	ti->size_fixed_part = offset;
378*d0e51869Samw }
379*d0e51869Samw 
380*d0e51869Samw static void
analyze_typeinfo_struct(ndr_typeinfo_t * ti)381*d0e51869Samw analyze_typeinfo_struct(ndr_typeinfo_t *ti)
382*d0e51869Samw {
383*d0e51869Samw 	ndr_node_t		*mem_np;
384*d0e51869Samw 	ndr_member_t		*mem;
385*d0e51869Samw 	int			i;
386*d0e51869Samw 	int			allow;
387*d0e51869Samw 	unsigned long		offset;
388*d0e51869Samw 
389*d0e51869Samw 	assert(ti->type_op == STRUCT_KW);
390*d0e51869Samw 
391*d0e51869Samw 	/*
392*d0e51869Samw 	 * Snarf the advice. Only recognize [operation()] for
393*d0e51869Samw 	 * struct definitions.
394*d0e51869Samw 	 */
395*d0e51869Samw 	determine_advice(&ti->advice, ti->definition->n_c_advice);
396*d0e51869Samw 
397*d0e51869Samw 	/*
398*d0e51869Samw 	 * Convert the members from list to table.
399*d0e51869Samw 	 * Determine layout metrics along the way.
400*d0e51869Samw 	 */
401*d0e51869Samw 	mem_np = ti->definition->n_c_members;
402*d0e51869Samw 	i = 0;
403*d0e51869Samw 	offset = 0;
404*d0e51869Samw 	for (; mem_np; i++, mem_np = mem_np->n_next) {
405*d0e51869Samw 		assert(i < ti->n_member);
406*d0e51869Samw 		mem = &ti->member[i];
407*d0e51869Samw 
408*d0e51869Samw 		if (!ti->advice.a_operation /* no var-size in op param */ &&
409*d0e51869Samw 		    i == ti->n_member-1)  /* only last mem may be var-size */
410*d0e51869Samw 			allow = ALLOW_VARSIZE;
411*d0e51869Samw 		else
412*d0e51869Samw 			allow = 0;
413*d0e51869Samw 
414*d0e51869Samw 		analyze_member(mem_np, mem, &offset, allow);
415*d0e51869Samw 	}
416*d0e51869Samw 	assert(i == ti->n_member);
417*d0e51869Samw 
418*d0e51869Samw 	analyze_typeinfo_aggregate_finish(ti);	/* align,complete,ptrs,etc */
419*d0e51869Samw 
420*d0e51869Samw 	/* Align offset to determine overall size */
421*d0e51869Samw 	while (offset & ti->alignment)
422*d0e51869Samw 		offset++;
423*d0e51869Samw 
424*d0e51869Samw 	ti->size_fixed_part = offset;
425*d0e51869Samw 
426*d0e51869Samw 	/* If last member is var-sized, so is this struct */
427*d0e51869Samw 	mem = &ti->member[ti->n_member-1];
428*d0e51869Samw 	ti->size_variable_part = mem->type->size_variable_part;
429*d0e51869Samw 
430*d0e51869Samw 	if (ti->size_variable_part)
431*d0e51869Samw 		ti->is_conformant = 1;
432*d0e51869Samw }
433*d0e51869Samw 
434*d0e51869Samw static void
analyze_typeinfo_union(ndr_typeinfo_t * ti)435*d0e51869Samw analyze_typeinfo_union(ndr_typeinfo_t *ti)
436*d0e51869Samw {
437*d0e51869Samw 	ndr_node_t		*mem_np;
438*d0e51869Samw 	ndr_member_t		*mem;
439*d0e51869Samw 	int			i;
440*d0e51869Samw 	unsigned long		offset;
441*d0e51869Samw 	unsigned long		size;
442*d0e51869Samw 
443*d0e51869Samw 	assert(ti->type_op == UNION_KW);
444*d0e51869Samw 
445*d0e51869Samw 	/*
446*d0e51869Samw 	 * Snarf the advice. None supported for union definitions.
447*d0e51869Samw 	 * Only [switch_is()] supported for union instances.
448*d0e51869Samw 	 */
449*d0e51869Samw 	determine_advice(&ti->advice, ti->definition->n_c_advice);
450*d0e51869Samw 
451*d0e51869Samw 	/*
452*d0e51869Samw 	 * Convert the members from list to table.
453*d0e51869Samw 	 * Determine layout metrics along the way.
454*d0e51869Samw 	 */
455*d0e51869Samw 	mem_np = ti->definition->n_c_members;
456*d0e51869Samw 	i = 0;
457*d0e51869Samw 	size = 0;
458*d0e51869Samw 	for (; mem_np; i++, mem_np = mem_np->n_next) {
459*d0e51869Samw 		assert(i < ti->n_member);
460*d0e51869Samw 		mem = &ti->member[i];
461*d0e51869Samw 
462*d0e51869Samw 		offset = 0;			/* all members offset=0 */
463*d0e51869Samw 		analyze_member(mem_np, mem,
464*d0e51869Samw 		    &offset,
465*d0e51869Samw 		    ALLOW_CASE+ALLOW_NO_UNIONS); /* var-size disallowed */
466*d0e51869Samw 
467*d0e51869Samw 		if (size < mem->type->size_fixed_part)
468*d0e51869Samw 			size = mem->type->size_fixed_part;
469*d0e51869Samw 	}
470*d0e51869Samw 	assert(i == ti->n_member);
471*d0e51869Samw 
472*d0e51869Samw 	analyze_typeinfo_aggregate_finish(ti);	/* align,complete,ptrs,etc */
473*d0e51869Samw 
474*d0e51869Samw 	/* align size to determine overall size */
475*d0e51869Samw 	while (size & ti->alignment)
476*d0e51869Samw 		size++;
477*d0e51869Samw 
478*d0e51869Samw 	ti->size_fixed_part = size;
479*d0e51869Samw }
480*d0e51869Samw 
481*d0e51869Samw static void
analyze_typeinfo_aggregate_finish(ndr_typeinfo_t * ti)482*d0e51869Samw analyze_typeinfo_aggregate_finish(ndr_typeinfo_t *ti)
483*d0e51869Samw {
484*d0e51869Samw 	int			i;
485*d0e51869Samw 	ndr_member_t		*mem;
486*d0e51869Samw 	int			complete = 1;
487*d0e51869Samw 	int			has_pointers = 0;
488*d0e51869Samw 
489*d0e51869Samw 	for (i = 0; i < ti->n_member; i++) {
490*d0e51869Samw 		mem = &ti->member[i];
491*d0e51869Samw 
492*d0e51869Samw 		complete &= mem->type->complete;
493*d0e51869Samw 		has_pointers |= mem->type->has_pointers;
494*d0e51869Samw 		ti->alignment |= mem->type->alignment;
495*d0e51869Samw 	}
496*d0e51869Samw 
497*d0e51869Samw 	ti->complete = complete;
498*d0e51869Samw 	ti->has_pointers = has_pointers;
499*d0e51869Samw }
500*d0e51869Samw 
501*d0e51869Samw static void
analyze_member(ndr_node_t * mem_np,ndr_member_t * mem,unsigned long * offsetp,int allow)502*d0e51869Samw analyze_member(ndr_node_t *mem_np, ndr_member_t *mem,
503*d0e51869Samw     unsigned long *offsetp, int allow)
504*d0e51869Samw {
505*d0e51869Samw 	int			i, n_decl_ops;
506*d0e51869Samw 	ndr_node_t		*decl_ops[NDLBUFSZ];
507*d0e51869Samw 	ndr_typeinfo_t		*type_down;
508*d0e51869Samw 	ndr_typeinfo_t		proto_ti;
509*d0e51869Samw 	ndr_node_t		*np;
510*d0e51869Samw 
511*d0e51869Samw 	/*
512*d0e51869Samw 	 * Set line_number for error reporting (so we know where to look)
513*d0e51869Samw 	 */
514*d0e51869Samw 	line_number = mem_np->line_number;
515*d0e51869Samw 
516*d0e51869Samw 	/*
517*d0e51869Samw 	 * Simple parts of member
518*d0e51869Samw 	 */
519*d0e51869Samw 	mem->definition = mem_np;
520*d0e51869Samw 	determine_advice(&mem->advice, mem_np->n_m_advice);
521*d0e51869Samw 
522*d0e51869Samw 	/*
523*d0e51869Samw 	 * The node list for the declarator is in outside-to-inside
524*d0e51869Samw 	 * order. It is also decorated with the LP nodes for
525*d0e51869Samw 	 * precedence, which are in our way at this point.
526*d0e51869Samw 	 *
527*d0e51869Samw 	 * These two loops reverse the list, which is easier
528*d0e51869Samw 	 * to analyze. For example, the declaration:
529*d0e51869Samw 	 *
530*d0e51869Samw 	 *	ulong *		(id[100]);
531*d0e51869Samw 	 *
532*d0e51869Samw 	 * will have the node list (=> indicates n_d_descend):
533*d0e51869Samw 	 *
534*d0e51869Samw 	 *	ulong  =>  STAR  =>  LP  =>  LB[100]  =>  id
535*d0e51869Samw 	 *
536*d0e51869Samw 	 * and the conversion will result in type info (=> indicates
537*d0e51869Samw 	 * type_down):
538*d0e51869Samw 	 *
539*d0e51869Samw 	 *	id  =>  LB[100]  =>  STAR  =>  ulong
540*d0e51869Samw 	 *
541*d0e51869Samw 	 * which is closer to how you would pronounce the declaration:
542*d0e51869Samw 	 *
543*d0e51869Samw 	 *	id is an array size 100 of pointers to ulong.
544*d0e51869Samw 	 */
545*d0e51869Samw 
546*d0e51869Samw 	/* first pass -- turn the list into a table */
547*d0e51869Samw 	n_decl_ops = 0;
548*d0e51869Samw 	for (np = mem_np->n_m_decl; np; np = np->n_d_descend) {
549*d0e51869Samw 		if (np->label == IDENTIFIER) {
550*d0e51869Samw 			break;		/* done */
551*d0e51869Samw 		}
552*d0e51869Samw 
553*d0e51869Samw 		if (np->label == LP)
554*d0e51869Samw 			continue;	/* ignore precedence nodes */
555*d0e51869Samw 
556*d0e51869Samw 		decl_ops[n_decl_ops++] = np;
557*d0e51869Samw 	}
558*d0e51869Samw 	if (!np) {
559*d0e51869Samw 		compile_error("declaration error");
560*d0e51869Samw 		print_node(mem_np->n_m_decl);
561*d0e51869Samw 		(void) printf("\n");
562*d0e51869Samw 	} else {
563*d0e51869Samw 		mem->name = np->n_sym->name;
564*d0e51869Samw 	}
565*d0e51869Samw 
566*d0e51869Samw 	/* second pass -- turn the table into push-back list */
567*d0e51869Samw 	type_down = find_typeinfo_by_name(mem_np->n_m_type);
568*d0e51869Samw 
569*d0e51869Samw 	if (type_down->type_op == TYPEDEF_KW)
570*d0e51869Samw 		type_down = type_down->member[0].type;
571*d0e51869Samw 
572*d0e51869Samw 	if (mem->advice.a_string) {
573*d0e51869Samw 		bzero(&proto_ti, sizeof (proto_ti));
574*d0e51869Samw 		proto_ti.type_op = STRING_KW;
575*d0e51869Samw 		proto_ti.type_down = type_down;
576*d0e51869Samw 		type_down = bind_typeinfo(&proto_ti);
577*d0e51869Samw 	}
578*d0e51869Samw 
579*d0e51869Samw 	for (i = n_decl_ops; i-- > 0; ) {
580*d0e51869Samw 		np = decl_ops[i];
581*d0e51869Samw 
582*d0e51869Samw 		bzero(&proto_ti, sizeof (proto_ti));
583*d0e51869Samw 
584*d0e51869Samw 		proto_ti.type_op = np->label;
585*d0e51869Samw 		proto_ti.type_down = type_down;
586*d0e51869Samw 
587*d0e51869Samw 		switch (np->label) {
588*d0e51869Samw 		case LB:
589*d0e51869Samw 			proto_ti.type_dim = np->n_d_dim;
590*d0e51869Samw 			break;
591*d0e51869Samw 		}
592*d0e51869Samw 
593*d0e51869Samw 		/*
594*d0e51869Samw 		 * bind_typeinfo() reuses (interns) typeinfo's to
595*d0e51869Samw 		 * make later code generation easier. It will report
596*d0e51869Samw 		 * some errors.
597*d0e51869Samw 		 */
598*d0e51869Samw 		type_down = bind_typeinfo(&proto_ti);
599*d0e51869Samw 	}
600*d0e51869Samw 
601*d0e51869Samw 	/* bind the member to its type info */
602*d0e51869Samw 	mem->type = type_down;
603*d0e51869Samw 	type_down->is_referenced = 1;	/* we handle first-level indirection */
604*d0e51869Samw 
605*d0e51869Samw 	/*
606*d0e51869Samw 	 * Now, apply the type info to the member layout metrics.
607*d0e51869Samw 	 */
608*d0e51869Samw 
609*d0e51869Samw 	/* alignment */
610*d0e51869Samw 	while (*offsetp & type_down->alignment)
611*d0e51869Samw 		++*offsetp;
612*d0e51869Samw 
613*d0e51869Samw 	mem->pdu_offset = *offsetp;
614*d0e51869Samw 
615*d0e51869Samw 	*offsetp += type_down->size_fixed_part;
616*d0e51869Samw 
617*d0e51869Samw 	if (mem->advice.a_length_is)
618*d0e51869Samw 		compile_error("[length_is()] is not supported");
619*d0e51869Samw 
620*d0e51869Samw 	if (mem->advice.a_transmit_as)
621*d0e51869Samw 		compile_error("[transmit_as()] is not supported");
622*d0e51869Samw 
623*d0e51869Samw 	if (mem->advice.a_arg_is)
624*d0e51869Samw 		compile_error("[arg_is()] is not supported");
625*d0e51869Samw 
626*d0e51869Samw 	/*
627*d0e51869Samw 	 * Disallow
628*d0e51869Samw 	 *	[case(x)] TYPE	xxx;
629*d0e51869Samw 	 *	[default] TYPE	xxx;
630*d0e51869Samw 	 *
631*d0e51869Samw 	 * These only make sense within unions.
632*d0e51869Samw 	 */
633*d0e51869Samw 	if (allow & ALLOW_CASE) {
634*d0e51869Samw 		int		n = 0;
635*d0e51869Samw 
636*d0e51869Samw 		if (mem->advice.a_case)
637*d0e51869Samw 			n++;
638*d0e51869Samw 		if (mem->advice.a_default)
639*d0e51869Samw 			n++;
640*d0e51869Samw 
641*d0e51869Samw 		if (n == 0)
642*d0e51869Samw 			compile_error("no [case/default] advice");
643*d0e51869Samw 		else if (n > 1)
644*d0e51869Samw 			compile_error("too many [case/default] advice");
645*d0e51869Samw 	} else {
646*d0e51869Samw 		if (mem->advice.a_case && mem->advice.a_default)
647*d0e51869Samw 			compile_error("[case/default] advice not allowed");
648*d0e51869Samw 	}
649*d0e51869Samw 
650*d0e51869Samw 	/*
651*d0e51869Samw 	 * Disallow
652*d0e51869Samw 	 *	[operation(x)]	TYPE	foo;
653*d0e51869Samw 	 *	[interface(x)]	TYPE	foo;
654*d0e51869Samw 	 *	[uuid(x)]	TYPE	foo;
655*d0e51869Samw 	 *
656*d0e51869Samw 	 * The [operation()] advice may only appear on a struct to
657*d0e51869Samw 	 * indicate that the structure is a top-most (parameter)
658*d0e51869Samw 	 * structure, and the opcode associated with the parameters.
659*d0e51869Samw 	 */
660*d0e51869Samw 	if (mem->advice.a_operation)
661*d0e51869Samw 		compile_error("[operation()] advice not allowed");
662*d0e51869Samw 
663*d0e51869Samw 	if (mem->advice.a_interface)
664*d0e51869Samw 		compile_error("[interface()] advice not allowed");
665*d0e51869Samw 
666*d0e51869Samw 	if (mem->advice.a_uuid)
667*d0e51869Samw 		compile_error("[uuid()] advice not allowed");
668*d0e51869Samw 
669*d0e51869Samw 	/*
670*d0e51869Samw 	 * Allow
671*d0e51869Samw 	 *	[switch_is(x)] union foo	xxx;
672*d0e51869Samw 	 *
673*d0e51869Samw 	 * Disallow [switch_is] on anything which is not a union.
674*d0e51869Samw 	 */
675*d0e51869Samw 	if (mem->advice.a_switch_is && type_down->type_op != UNION_KW) {
676*d0e51869Samw 		compile_error("[switch_is()] advice not allowed");
677*d0e51869Samw 	}
678*d0e51869Samw 
679*d0e51869Samw 	/*
680*d0e51869Samw 	 * Allow
681*d0e51869Samw 	 *	[size_is(x)] TYPE *	ptr;
682*d0e51869Samw 	 *	[size_is(x)] TYPE	arr[];
683*d0e51869Samw 	 *
684*d0e51869Samw 	 * Disallow [size_is()] on anything other than pointer and
685*d0e51869Samw 	 * variable length array.
686*d0e51869Samw 	 */
687*d0e51869Samw 	if (mem->advice.a_size_is &&
688*d0e51869Samw 	    type_down->type_op != STAR &&
689*d0e51869Samw 	    !(type_down->type_op == LB &&
690*d0e51869Samw 	    type_down->type_dim == 0)) {
691*d0e51869Samw 		compile_error("[size_is()] advice not allowed");
692*d0e51869Samw 	}
693*d0e51869Samw 
694*d0e51869Samw 	/*
695*d0e51869Samw 	 * Allow
696*d0e51869Samw 	 *	[string] char *		ptr_string;
697*d0e51869Samw 	 *
698*d0e51869Samw 	 * Disallow [string] on anything else. The determination
699*d0e51869Samw 	 * of size (for the outer header) on anything else is
700*d0e51869Samw 	 * impossible.
701*d0e51869Samw 	 */
702*d0e51869Samw 	if (mem->advice.a_string && type_down->type_op != STAR) {
703*d0e51869Samw 		compile_error("[string] advice not allowed");
704*d0e51869Samw 	}
705*d0e51869Samw 
706*d0e51869Samw 	if (type_down->type_op == LB &&
707*d0e51869Samw 	    type_down->type_dim == 0) { /* var-length array of some sort */
708*d0e51869Samw 
709*d0e51869Samw 		int		n = 0;
710*d0e51869Samw 
711*d0e51869Samw 		/*
712*d0e51869Samw 		 * Requires [size_is()] directive
713*d0e51869Samw 		 *	[size_is(x)] TYPE	array[]
714*d0e51869Samw 		 */
715*d0e51869Samw 
716*d0e51869Samw 		if (mem->advice.a_size_is)
717*d0e51869Samw 			n++;
718*d0e51869Samw 
719*d0e51869Samw 		if (!n)
720*d0e51869Samw 			compile_error("var-size missing sizing directive");
721*d0e51869Samw 		else if (n > 1)
722*d0e51869Samw 			compile_error("var-size too many sizing directives");
723*d0e51869Samw 	}
724*d0e51869Samw 
725*d0e51869Samw 	/*
726*d0e51869Samw 	 * Nested unions and struct members, other than the last one,
727*d0e51869Samw 	 * cannot contain variable sized members.
728*d0e51869Samw 	 */
729*d0e51869Samw 	if (type_down->size_variable_part && !(allow & ALLOW_VARSIZE)) {
730*d0e51869Samw 		compile_error("var-size member not allowed");
731*d0e51869Samw 	}
732*d0e51869Samw 
733*d0e51869Samw 	/*
734*d0e51869Samw 	 * Disallow unions in operations (i.e. [operation()] struct ...),
735*d0e51869Samw 	 * The switch_is() value is not reliably available. DCE/RPC
736*d0e51869Samw 	 * automatically synthesizes an encapsulated union for
737*d0e51869Samw 	 * these situations, which we have to do by hand:
738*d0e51869Samw 	 *
739*d0e51869Samw 	 *	struct { long switch_value; union foo x; } synth;
740*d0e51869Samw 	 *
741*d0e51869Samw 	 * We also can not allow unions within unions because
742*d0e51869Samw 	 * there is no way to pass the separate [switch_is(x)] selector.
743*d0e51869Samw 	 */
744*d0e51869Samw 	if (type_down->type_op == UNION_KW) {
745*d0e51869Samw 		if (allow & ALLOW_NO_UNIONS) {
746*d0e51869Samw 			compile_error("unencapsulated union not allowed");
747*d0e51869Samw 		} else if (!mem->advice.a_switch_is &&
748*d0e51869Samw 		    !(allow & ALLOW_NO_SWITCH)) {
749*d0e51869Samw 			compile_error("union instance without selector");
750*d0e51869Samw 		}
751*d0e51869Samw 	}
752*d0e51869Samw }
753*d0e51869Samw 
754*d0e51869Samw static void
seed_basic_types(void)755*d0e51869Samw seed_basic_types(void)
756*d0e51869Samw {
757*d0e51869Samw 	ndr_symbol_t		*sym;
758*d0e51869Samw 	ndr_typeinfo_t		*ti;
759*d0e51869Samw 	ndr_typeinfo_t		proto_ti;
760*d0e51869Samw 
761*d0e51869Samw 	for (sym = symbol_list; sym; sym = sym->next) {
762*d0e51869Samw 		if (!sym->kw)
763*d0e51869Samw 			continue;
764*d0e51869Samw 
765*d0e51869Samw 		if (sym->kw->token != BASIC_TYPE)
766*d0e51869Samw 			continue;
767*d0e51869Samw 
768*d0e51869Samw 		ti = ndr_alloc(1, sizeof (ndr_typeinfo_t));
769*d0e51869Samw 
770*d0e51869Samw 		ti->type_op = BASIC_TYPE;
771*d0e51869Samw 		ti->definition = &sym->s_node;
772*d0e51869Samw 		ti->type_name = &sym->s_node;
773*d0e51869Samw 		ti->size_fixed_part = sym->kw->value;
774*d0e51869Samw 		ti->alignment = ti->size_fixed_part - 1;
775*d0e51869Samw 		ti->complete = 1;
776*d0e51869Samw 		ti->is_extern = 1;
777*d0e51869Samw 
778*d0e51869Samw 		append_typeinfo(ti);
779*d0e51869Samw 
780*d0e51869Samw 		bzero(&proto_ti, sizeof (proto_ti));
781*d0e51869Samw 		proto_ti.type_op = STRING_KW;
782*d0e51869Samw 		proto_ti.type_down = ti;
783*d0e51869Samw 
784*d0e51869Samw 		ti = bind_typeinfo(&proto_ti);
785*d0e51869Samw 		ti->is_extern = 1;
786*d0e51869Samw 	}
787*d0e51869Samw }
788*d0e51869Samw 
789*d0e51869Samw static void
seed_construct_types(void)790*d0e51869Samw seed_construct_types(void)
791*d0e51869Samw {
792*d0e51869Samw 	ndr_node_t		*construct;
793*d0e51869Samw 	ndr_node_t		*np;
794*d0e51869Samw 	unsigned		n_member;
795*d0e51869Samw 	ndr_typeinfo_t		*ti;
796*d0e51869Samw 
797*d0e51869Samw 	construct = construct_list;
798*d0e51869Samw 	for (; construct; construct = construct->n_next) {
799*d0e51869Samw 		ti = ndr_alloc(1, sizeof (ndr_typeinfo_t));
800*d0e51869Samw 
801*d0e51869Samw 		ti->type_op = construct->label;
802*d0e51869Samw 		ti->definition = construct;
803*d0e51869Samw 
804*d0e51869Samw 		switch (ti->type_op) {
805*d0e51869Samw 		case TYPEDEF_KW:
806*d0e51869Samw 		case STRUCT_KW:
807*d0e51869Samw 		case UNION_KW:
808*d0e51869Samw 			ti->type_name = construct->n_c_typename;
809*d0e51869Samw 
810*d0e51869Samw 			np = construct->n_c_members;
811*d0e51869Samw 			n_member = 0;
812*d0e51869Samw 			for (; np; np = np->n_next)
813*d0e51869Samw 				n_member++;
814*d0e51869Samw 
815*d0e51869Samw 			ti->n_member = n_member;
816*d0e51869Samw 			if (n_member > 0)
817*d0e51869Samw 				ti->member = ndr_alloc(n_member,
818*d0e51869Samw 				    sizeof (ndr_member_t));
819*d0e51869Samw 			break;
820*d0e51869Samw 
821*d0e51869Samw 		default:
822*d0e51869Samw 			fatal_error("seed_construct unknown %d\n", ti->type_op);
823*d0e51869Samw 			break;
824*d0e51869Samw 		}
825*d0e51869Samw 
826*d0e51869Samw 		determine_advice(&ti->advice, construct->n_c_advice);
827*d0e51869Samw 
828*d0e51869Samw 		ti->is_referenced = 1;	/* always generate */
829*d0e51869Samw 
830*d0e51869Samw 		append_typeinfo(ti);
831*d0e51869Samw 	}
832*d0e51869Samw }
833*d0e51869Samw 
834*d0e51869Samw static void
append_typeinfo(ndr_typeinfo_t * ti)835*d0e51869Samw append_typeinfo(ndr_typeinfo_t *ti)
836*d0e51869Samw {
837*d0e51869Samw 	ndr_typeinfo_t		**pp;
838*d0e51869Samw 
839*d0e51869Samw 	for (pp = &typeinfo_list; *pp; pp = &(*pp)->next)
840*d0e51869Samw 		;
841*d0e51869Samw 
842*d0e51869Samw 	*pp = ti;
843*d0e51869Samw 	ti->next = 0;
844*d0e51869Samw }
845*d0e51869Samw 
846*d0e51869Samw static ndr_typeinfo_t *
bind_typeinfo(ndr_typeinfo_t * proto_ti)847*d0e51869Samw bind_typeinfo(ndr_typeinfo_t *proto_ti)
848*d0e51869Samw {
849*d0e51869Samw 	ndr_typeinfo_t		*ti;
850*d0e51869Samw 	ndr_typeinfo_t		*tdti = proto_ti->type_down;
851*d0e51869Samw 
852*d0e51869Samw 	for (ti = typeinfo_list; ti; ti = ti->next) {
853*d0e51869Samw 		if (ti->type_op != proto_ti->type_op)
854*d0e51869Samw 			continue;
855*d0e51869Samw 
856*d0e51869Samw 		switch (ti->type_op) {
857*d0e51869Samw 		case STAR:
858*d0e51869Samw 			if (ti->type_down != proto_ti->type_down)
859*d0e51869Samw 				continue;
860*d0e51869Samw 			break;
861*d0e51869Samw 
862*d0e51869Samw 		case STRING_KW:
863*d0e51869Samw 			if (ti->type_down != proto_ti->type_down)
864*d0e51869Samw 				continue;
865*d0e51869Samw 			break;
866*d0e51869Samw 
867*d0e51869Samw 		case LB:
868*d0e51869Samw 			if (ti->type_down != proto_ti->type_down)
869*d0e51869Samw 				continue;
870*d0e51869Samw 			if (ti->type_dim != proto_ti->type_dim)
871*d0e51869Samw 				continue;
872*d0e51869Samw 			break;
873*d0e51869Samw 
874*d0e51869Samw 		case BASIC_TYPE:
875*d0e51869Samw 		case STRUCT_KW:
876*d0e51869Samw 		case TYPEDEF_KW:
877*d0e51869Samw 		case UNION_KW:
878*d0e51869Samw 			if (ti->type_name != proto_ti->type_name)
879*d0e51869Samw 				continue;
880*d0e51869Samw 			break;
881*d0e51869Samw 
882*d0e51869Samw 		default:
883*d0e51869Samw 			fatal_error("bind_typeinfo unknown %d\n", ti->type_op);
884*d0e51869Samw 			break;
885*d0e51869Samw 		}
886*d0e51869Samw 
887*d0e51869Samw 		return (ti);
888*d0e51869Samw 	}
889*d0e51869Samw 
890*d0e51869Samw 	ti = ndr_alloc(1, sizeof (ndr_typeinfo_t));
891*d0e51869Samw 
892*d0e51869Samw 	*ti = *proto_ti;
893*d0e51869Samw 	append_typeinfo(ti);
894*d0e51869Samw 
895*d0e51869Samw 	switch (ti->type_op) {
896*d0e51869Samw 	case STAR:
897*d0e51869Samw 		ti->size_fixed_part = 4;
898*d0e51869Samw 		ti->alignment = 3;
899*d0e51869Samw 		ti->complete = 1;
900*d0e51869Samw 		ti->has_pointers = 1;
901*d0e51869Samw 		break;
902*d0e51869Samw 
903*d0e51869Samw 	case STRING_KW:
904*d0e51869Samw 	case LB:
905*d0e51869Samw 		if (tdti->complete) {
906*d0e51869Samw 			ti->alignment = tdti->alignment;
907*d0e51869Samw 			if (tdti->size_variable_part) {
908*d0e51869Samw 				compile_error("array of var-size type");
909*d0e51869Samw 			} else if (ti->type_dim) {
910*d0e51869Samw 				ti->size_fixed_part = tdti->size_fixed_part *
911*d0e51869Samw 				    ti->type_dim->n_int;
912*d0e51869Samw 			} else {
913*d0e51869Samw 				ti->size_variable_part = tdti->size_fixed_part;
914*d0e51869Samw 				ti->is_conformant = 1;
915*d0e51869Samw 			}
916*d0e51869Samw 		} else {
917*d0e51869Samw 			compile_error("array of incomplete type");
918*d0e51869Samw 		}
919*d0e51869Samw 
920*d0e51869Samw 		ti->has_pointers = tdti->has_pointers;
921*d0e51869Samw 		ti->complete = 1;
922*d0e51869Samw 		break;
923*d0e51869Samw 
924*d0e51869Samw 	default:
925*d0e51869Samw 		compile_error("bind_type internal error op=%d", ti->type_op);
926*d0e51869Samw 		break;
927*d0e51869Samw 	}
928*d0e51869Samw 
929*d0e51869Samw 	/*
930*d0e51869Samw 	 * Disallow
931*d0e51869Samw 	 *	union foo	*ptrfoo;
932*d0e51869Samw 	 * There is no way to pass the selector (switch_is)in
933*d0e51869Samw 	 */
934*d0e51869Samw 	if (ti->type_op == STAR && ti->type_down->type_op == UNION_KW) {
935*d0e51869Samw 		compile_error("pointers to unions not allowed");
936*d0e51869Samw 	}
937*d0e51869Samw 
938*d0e51869Samw 	/*
939*d0e51869Samw 	 * Disallow
940*d0e51869Samw 	 *	union foo	fooarr[n];
941*d0e51869Samw 	 * Each element needs a distinct selector
942*d0e51869Samw 	 */
943*d0e51869Samw 	if (ti->type_op == LB && ti->type_down->type_op == UNION_KW) {
944*d0e51869Samw 		compile_error("arrays of unions not allowed");
945*d0e51869Samw 	}
946*d0e51869Samw 
947*d0e51869Samw 	return (ti);
948*d0e51869Samw }
949*d0e51869Samw 
950*d0e51869Samw static ndr_typeinfo_t *
find_typeinfo_by_name(ndr_node_t * typename)951*d0e51869Samw find_typeinfo_by_name(ndr_node_t *typename)
952*d0e51869Samw {
953*d0e51869Samw 	ndr_typeinfo_t		*ti;
954*d0e51869Samw 
955*d0e51869Samw 	for (ti = typeinfo_list; ti; ti = ti->next) {
956*d0e51869Samw 		if (ti->type_name == typename)
957*d0e51869Samw 			return (ti);
958*d0e51869Samw 	}
959*d0e51869Samw 
960*d0e51869Samw 	compile_error("unknown type %s", typename->n_sym->name);
961*d0e51869Samw 
962*d0e51869Samw 	/* fake BASIC_TYPE */
963*d0e51869Samw 	ti = ndr_alloc(1, sizeof (ndr_typeinfo_t));
964*d0e51869Samw 	ti->type_op = BASIC_TYPE;
965*d0e51869Samw 	ti->definition = typename;
966*d0e51869Samw 	ti->type_name = typename;
967*d0e51869Samw 	ti->size_fixed_part = 0;
968*d0e51869Samw 	ti->alignment = 0;
969*d0e51869Samw 
970*d0e51869Samw 	append_typeinfo(ti);
971*d0e51869Samw 	return (ti);
972*d0e51869Samw }
973*d0e51869Samw 
974*d0e51869Samw static void
determine_advice(ndr_advice_t * advice,ndr_node_t * advice_list)975*d0e51869Samw determine_advice(ndr_advice_t *advice, ndr_node_t *advice_list)
976*d0e51869Samw {
977*d0e51869Samw 	/* alias for basic types */
978*d0e51869Samw 	advice->a_transmit_as = find_advice(advice_list, TRANSMIT_AS_KW);
979*d0e51869Samw 
980*d0e51869Samw 	/* arg used for size, union, or generic purpose */
981*d0e51869Samw 	advice->a_arg_is = find_advice(advice_list, ARG_IS_KW);
982*d0e51869Samw 
983*d0e51869Samw 	/* operation parameter in/out stuff */
984*d0e51869Samw 	advice->a_operation = find_advice(advice_list, OPERATION_KW);
985*d0e51869Samw 	advice->a_in = find_advice(advice_list, IN_KW);
986*d0e51869Samw 	advice->a_out = find_advice(advice_list, OUT_KW);
987*d0e51869Samw 
988*d0e51869Samw 	/* size stuff */
989*d0e51869Samw 	advice->a_string = find_advice(advice_list, STRING_KW);
990*d0e51869Samw 	advice->a_size_is = find_advice(advice_list, SIZE_IS_KW);
991*d0e51869Samw 	advice->a_length_is = find_advice(advice_list, LENGTH_IS_KW);
992*d0e51869Samw 
993*d0e51869Samw 	/* union stuff */
994*d0e51869Samw 	advice->a_case = find_advice(advice_list, CASE_KW);
995*d0e51869Samw 	advice->a_default = find_advice(advice_list, DEFAULT_KW);
996*d0e51869Samw 	advice->a_switch_is = find_advice(advice_list, SWITCH_IS_KW);
997*d0e51869Samw 
998*d0e51869Samw 	/* interface stuff */
999*d0e51869Samw 	advice->a_interface = find_advice(advice_list, INTERFACE_KW);
1000*d0e51869Samw 	advice->a_uuid = find_advice(advice_list, UUID_KW);
1001*d0e51869Samw 	advice->a_no_reorder = find_advice(advice_list, _NO_REORDER_KW);
1002*d0e51869Samw 	advice->a_extern = find_advice(advice_list, EXTERN_KW);
1003*d0e51869Samw 
1004*d0e51869Samw 	advice->a_reference = find_advice(advice_list, REFERENCE_KW);
1005*d0e51869Samw 	advice->a_align = find_advice(advice_list, ALIGN_KW);
1006*d0e51869Samw }
1007*d0e51869Samw 
1008*d0e51869Samw static ndr_node_t *
find_advice(ndr_node_t * advice_list,int label)1009*d0e51869Samw find_advice(ndr_node_t *advice_list, int label)
1010*d0e51869Samw {
1011*d0e51869Samw 	ndr_node_t		*np;
1012*d0e51869Samw 
1013*d0e51869Samw 	for (np = advice_list; np; np = np->n_next)
1014*d0e51869Samw 		if (np->label == label)
1015*d0e51869Samw 			break;
1016*d0e51869Samw 
1017*d0e51869Samw 	return (np);
1018*d0e51869Samw }
1019*d0e51869Samw 
1020*d0e51869Samw void
member_fixup(ndr_node_t * member_np)1021*d0e51869Samw member_fixup(ndr_node_t *member_np)
1022*d0e51869Samw {
1023*d0e51869Samw 	ndr_node_t		*np;
1024*d0e51869Samw 
1025*d0e51869Samw 	for (np = member_np->n_m_decl; np; np = np->n_d_descend)
1026*d0e51869Samw 		if (np->label == IDENTIFIER)
1027*d0e51869Samw 			break;
1028*d0e51869Samw 
1029*d0e51869Samw 	member_np->n_m_name = np;
1030*d0e51869Samw }
1031*d0e51869Samw 
1032*d0e51869Samw void
construct_fixup(ndr_node_t * construct_np)1033*d0e51869Samw construct_fixup(ndr_node_t *construct_np)
1034*d0e51869Samw {
1035*d0e51869Samw 	construct_np->n_c_typename->n_sym->typedefn = construct_np;
1036*d0e51869Samw }
1037