xref: /freebsd-src/cddl/contrib/opensolaris/lib/libdtrace/common/dt_decl.c (revision 6ff6d951ade3f3379932df7f878ef3ea272cfc59)
1*6ff6d951SJohn Birrell /*
2*6ff6d951SJohn Birrell  * CDDL HEADER START
3*6ff6d951SJohn Birrell  *
4*6ff6d951SJohn Birrell  * The contents of this file are subject to the terms of the
5*6ff6d951SJohn Birrell  * Common Development and Distribution License, Version 1.0 only
6*6ff6d951SJohn Birrell  * (the "License").  You may not use this file except in compliance
7*6ff6d951SJohn Birrell  * with the License.
8*6ff6d951SJohn Birrell  *
9*6ff6d951SJohn Birrell  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*6ff6d951SJohn Birrell  * or http://www.opensolaris.org/os/licensing.
11*6ff6d951SJohn Birrell  * See the License for the specific language governing permissions
12*6ff6d951SJohn Birrell  * and limitations under the License.
13*6ff6d951SJohn Birrell  *
14*6ff6d951SJohn Birrell  * When distributing Covered Code, include this CDDL HEADER in each
15*6ff6d951SJohn Birrell  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*6ff6d951SJohn Birrell  * If applicable, add the following below this CDDL HEADER, with the
17*6ff6d951SJohn Birrell  * fields enclosed by brackets "[]" replaced with your own identifying
18*6ff6d951SJohn Birrell  * information: Portions Copyright [yyyy] [name of copyright owner]
19*6ff6d951SJohn Birrell  *
20*6ff6d951SJohn Birrell  * CDDL HEADER END
21*6ff6d951SJohn Birrell  */
22*6ff6d951SJohn Birrell /*
23*6ff6d951SJohn Birrell  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24*6ff6d951SJohn Birrell  * Use is subject to license terms.
25*6ff6d951SJohn Birrell  */
26*6ff6d951SJohn Birrell 
27*6ff6d951SJohn Birrell #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*6ff6d951SJohn Birrell 
29*6ff6d951SJohn Birrell #include <strings.h>
30*6ff6d951SJohn Birrell #include <stdlib.h>
31*6ff6d951SJohn Birrell #include <limits.h>
32*6ff6d951SJohn Birrell #include <alloca.h>
33*6ff6d951SJohn Birrell #include <assert.h>
34*6ff6d951SJohn Birrell 
35*6ff6d951SJohn Birrell #include <dt_decl.h>
36*6ff6d951SJohn Birrell #include <dt_parser.h>
37*6ff6d951SJohn Birrell #include <dt_module.h>
38*6ff6d951SJohn Birrell #include <dt_impl.h>
39*6ff6d951SJohn Birrell 
40*6ff6d951SJohn Birrell static dt_decl_t *
41*6ff6d951SJohn Birrell dt_decl_check(dt_decl_t *ddp)
42*6ff6d951SJohn Birrell {
43*6ff6d951SJohn Birrell 	if (ddp->dd_kind == CTF_K_UNKNOWN)
44*6ff6d951SJohn Birrell 		return (ddp); /* nothing to check if the type is not yet set */
45*6ff6d951SJohn Birrell 
46*6ff6d951SJohn Birrell 	if (ddp->dd_name != NULL && strcmp(ddp->dd_name, "char") == 0 &&
47*6ff6d951SJohn Birrell 	    (ddp->dd_attr & (DT_DA_SHORT | DT_DA_LONG | DT_DA_LONGLONG))) {
48*6ff6d951SJohn Birrell 		xyerror(D_DECL_CHARATTR, "invalid type declaration: short and "
49*6ff6d951SJohn Birrell 		    "long may not be used with char type\n");
50*6ff6d951SJohn Birrell 	}
51*6ff6d951SJohn Birrell 
52*6ff6d951SJohn Birrell 	if (ddp->dd_name != NULL && strcmp(ddp->dd_name, "void") == 0 &&
53*6ff6d951SJohn Birrell 	    (ddp->dd_attr & (DT_DA_SHORT | DT_DA_LONG | DT_DA_LONGLONG |
54*6ff6d951SJohn Birrell 	    (DT_DA_SIGNED | DT_DA_UNSIGNED)))) {
55*6ff6d951SJohn Birrell 		xyerror(D_DECL_VOIDATTR, "invalid type declaration: attributes "
56*6ff6d951SJohn Birrell 		    "may not be used with void type\n");
57*6ff6d951SJohn Birrell 	}
58*6ff6d951SJohn Birrell 
59*6ff6d951SJohn Birrell 	if (ddp->dd_kind != CTF_K_INTEGER &&
60*6ff6d951SJohn Birrell 	    (ddp->dd_attr & (DT_DA_SIGNED | DT_DA_UNSIGNED))) {
61*6ff6d951SJohn Birrell 		xyerror(D_DECL_SIGNINT, "invalid type declaration: signed and "
62*6ff6d951SJohn Birrell 		    "unsigned may only be used with integer type\n");
63*6ff6d951SJohn Birrell 	}
64*6ff6d951SJohn Birrell 
65*6ff6d951SJohn Birrell 	if (ddp->dd_kind != CTF_K_INTEGER && ddp->dd_kind != CTF_K_FLOAT &&
66*6ff6d951SJohn Birrell 	    (ddp->dd_attr & (DT_DA_LONG | DT_DA_LONGLONG))) {
67*6ff6d951SJohn Birrell 		xyerror(D_DECL_LONGINT, "invalid type declaration: long and "
68*6ff6d951SJohn Birrell 		    "long long may only be used with integer or "
69*6ff6d951SJohn Birrell 		    "floating-point type\n");
70*6ff6d951SJohn Birrell 	}
71*6ff6d951SJohn Birrell 
72*6ff6d951SJohn Birrell 	return (ddp);
73*6ff6d951SJohn Birrell }
74*6ff6d951SJohn Birrell 
75*6ff6d951SJohn Birrell dt_decl_t *
76*6ff6d951SJohn Birrell dt_decl_alloc(ushort_t kind, char *name)
77*6ff6d951SJohn Birrell {
78*6ff6d951SJohn Birrell 	dt_decl_t *ddp = malloc(sizeof (dt_decl_t));
79*6ff6d951SJohn Birrell 
80*6ff6d951SJohn Birrell 	if (ddp == NULL)
81*6ff6d951SJohn Birrell 		longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
82*6ff6d951SJohn Birrell 
83*6ff6d951SJohn Birrell 	ddp->dd_kind = kind;
84*6ff6d951SJohn Birrell 	ddp->dd_attr = 0;
85*6ff6d951SJohn Birrell 	ddp->dd_ctfp = NULL;
86*6ff6d951SJohn Birrell 	ddp->dd_type = CTF_ERR;
87*6ff6d951SJohn Birrell 	ddp->dd_name = name;
88*6ff6d951SJohn Birrell 	ddp->dd_node = NULL;
89*6ff6d951SJohn Birrell 	ddp->dd_next = NULL;
90*6ff6d951SJohn Birrell 
91*6ff6d951SJohn Birrell 	return (ddp);
92*6ff6d951SJohn Birrell }
93*6ff6d951SJohn Birrell 
94*6ff6d951SJohn Birrell void
95*6ff6d951SJohn Birrell dt_decl_free(dt_decl_t *ddp)
96*6ff6d951SJohn Birrell {
97*6ff6d951SJohn Birrell 	dt_decl_t *ndp;
98*6ff6d951SJohn Birrell 
99*6ff6d951SJohn Birrell 	for (; ddp != NULL; ddp = ndp) {
100*6ff6d951SJohn Birrell 		ndp = ddp->dd_next;
101*6ff6d951SJohn Birrell 		free(ddp->dd_name);
102*6ff6d951SJohn Birrell 		dt_node_list_free(&ddp->dd_node);
103*6ff6d951SJohn Birrell 		free(ddp);
104*6ff6d951SJohn Birrell 	}
105*6ff6d951SJohn Birrell }
106*6ff6d951SJohn Birrell 
107*6ff6d951SJohn Birrell void
108*6ff6d951SJohn Birrell dt_decl_reset(void)
109*6ff6d951SJohn Birrell {
110*6ff6d951SJohn Birrell 	dt_scope_t *dsp = &yypcb->pcb_dstack;
111*6ff6d951SJohn Birrell 	dt_decl_t *ddp = dsp->ds_decl;
112*6ff6d951SJohn Birrell 
113*6ff6d951SJohn Birrell 	while (ddp->dd_next != NULL) {
114*6ff6d951SJohn Birrell 		dsp->ds_decl = ddp->dd_next;
115*6ff6d951SJohn Birrell 		ddp->dd_next = NULL;
116*6ff6d951SJohn Birrell 		dt_decl_free(ddp);
117*6ff6d951SJohn Birrell 		ddp = dsp->ds_decl;
118*6ff6d951SJohn Birrell 	}
119*6ff6d951SJohn Birrell }
120*6ff6d951SJohn Birrell 
121*6ff6d951SJohn Birrell dt_decl_t *
122*6ff6d951SJohn Birrell dt_decl_push(dt_decl_t *ddp)
123*6ff6d951SJohn Birrell {
124*6ff6d951SJohn Birrell 	dt_scope_t *dsp = &yypcb->pcb_dstack;
125*6ff6d951SJohn Birrell 	dt_decl_t *top = dsp->ds_decl;
126*6ff6d951SJohn Birrell 
127*6ff6d951SJohn Birrell 	if (top != NULL &&
128*6ff6d951SJohn Birrell 	    top->dd_kind == CTF_K_UNKNOWN && top->dd_name == NULL) {
129*6ff6d951SJohn Birrell 		top->dd_kind = CTF_K_INTEGER;
130*6ff6d951SJohn Birrell 		(void) dt_decl_check(top);
131*6ff6d951SJohn Birrell 	}
132*6ff6d951SJohn Birrell 
133*6ff6d951SJohn Birrell 	assert(ddp->dd_next == NULL);
134*6ff6d951SJohn Birrell 	ddp->dd_next = top;
135*6ff6d951SJohn Birrell 	dsp->ds_decl = ddp;
136*6ff6d951SJohn Birrell 
137*6ff6d951SJohn Birrell 	return (ddp);
138*6ff6d951SJohn Birrell }
139*6ff6d951SJohn Birrell 
140*6ff6d951SJohn Birrell dt_decl_t *
141*6ff6d951SJohn Birrell dt_decl_pop(void)
142*6ff6d951SJohn Birrell {
143*6ff6d951SJohn Birrell 	dt_scope_t *dsp = &yypcb->pcb_dstack;
144*6ff6d951SJohn Birrell 	dt_decl_t *ddp = dt_decl_top();
145*6ff6d951SJohn Birrell 
146*6ff6d951SJohn Birrell 	dsp->ds_decl = NULL;
147*6ff6d951SJohn Birrell 	free(dsp->ds_ident);
148*6ff6d951SJohn Birrell 	dsp->ds_ident = NULL;
149*6ff6d951SJohn Birrell 	dsp->ds_ctfp = NULL;
150*6ff6d951SJohn Birrell 	dsp->ds_type = CTF_ERR;
151*6ff6d951SJohn Birrell 	dsp->ds_class = DT_DC_DEFAULT;
152*6ff6d951SJohn Birrell 	dsp->ds_enumval = -1;
153*6ff6d951SJohn Birrell 
154*6ff6d951SJohn Birrell 	return (ddp);
155*6ff6d951SJohn Birrell }
156*6ff6d951SJohn Birrell 
157*6ff6d951SJohn Birrell dt_decl_t *
158*6ff6d951SJohn Birrell dt_decl_pop_param(char **idp)
159*6ff6d951SJohn Birrell {
160*6ff6d951SJohn Birrell 	dt_scope_t *dsp = &yypcb->pcb_dstack;
161*6ff6d951SJohn Birrell 
162*6ff6d951SJohn Birrell 	if (dsp->ds_class != DT_DC_DEFAULT && dsp->ds_class != DT_DC_REGISTER) {
163*6ff6d951SJohn Birrell 		xyerror(D_DECL_PARMCLASS, "inappropriate storage class "
164*6ff6d951SJohn Birrell 		    "for function or associative array parameter\n");
165*6ff6d951SJohn Birrell 	}
166*6ff6d951SJohn Birrell 
167*6ff6d951SJohn Birrell 	if (idp != NULL && dt_decl_top() != NULL) {
168*6ff6d951SJohn Birrell 		*idp = dsp->ds_ident;
169*6ff6d951SJohn Birrell 		dsp->ds_ident = NULL;
170*6ff6d951SJohn Birrell 	}
171*6ff6d951SJohn Birrell 
172*6ff6d951SJohn Birrell 	return (dt_decl_pop());
173*6ff6d951SJohn Birrell }
174*6ff6d951SJohn Birrell 
175*6ff6d951SJohn Birrell dt_decl_t *
176*6ff6d951SJohn Birrell dt_decl_top(void)
177*6ff6d951SJohn Birrell {
178*6ff6d951SJohn Birrell 	dt_decl_t *ddp = yypcb->pcb_dstack.ds_decl;
179*6ff6d951SJohn Birrell 
180*6ff6d951SJohn Birrell 	if (ddp == NULL)
181*6ff6d951SJohn Birrell 		longjmp(yypcb->pcb_jmpbuf, EDT_NODECL);
182*6ff6d951SJohn Birrell 
183*6ff6d951SJohn Birrell 	if (ddp->dd_kind == CTF_K_UNKNOWN && ddp->dd_name == NULL) {
184*6ff6d951SJohn Birrell 		ddp->dd_kind = CTF_K_INTEGER;
185*6ff6d951SJohn Birrell 		(void) dt_decl_check(ddp);
186*6ff6d951SJohn Birrell 	}
187*6ff6d951SJohn Birrell 
188*6ff6d951SJohn Birrell 	return (ddp);
189*6ff6d951SJohn Birrell }
190*6ff6d951SJohn Birrell 
191*6ff6d951SJohn Birrell dt_decl_t *
192*6ff6d951SJohn Birrell dt_decl_ident(char *name)
193*6ff6d951SJohn Birrell {
194*6ff6d951SJohn Birrell 	dt_scope_t *dsp = &yypcb->pcb_dstack;
195*6ff6d951SJohn Birrell 	dt_decl_t *ddp = dsp->ds_decl;
196*6ff6d951SJohn Birrell 
197*6ff6d951SJohn Birrell 	if (dsp->ds_ident != NULL) {
198*6ff6d951SJohn Birrell 		free(name);
199*6ff6d951SJohn Birrell 		xyerror(D_DECL_IDENT, "old-style declaration or "
200*6ff6d951SJohn Birrell 		    "incorrect type specified\n");
201*6ff6d951SJohn Birrell 	}
202*6ff6d951SJohn Birrell 
203*6ff6d951SJohn Birrell 	dsp->ds_ident = name;
204*6ff6d951SJohn Birrell 
205*6ff6d951SJohn Birrell 	if (ddp == NULL)
206*6ff6d951SJohn Birrell 		ddp = dt_decl_push(dt_decl_alloc(CTF_K_UNKNOWN, NULL));
207*6ff6d951SJohn Birrell 
208*6ff6d951SJohn Birrell 	return (ddp);
209*6ff6d951SJohn Birrell }
210*6ff6d951SJohn Birrell 
211*6ff6d951SJohn Birrell void
212*6ff6d951SJohn Birrell dt_decl_class(dt_dclass_t class)
213*6ff6d951SJohn Birrell {
214*6ff6d951SJohn Birrell 	dt_scope_t *dsp = &yypcb->pcb_dstack;
215*6ff6d951SJohn Birrell 
216*6ff6d951SJohn Birrell 	if (dsp->ds_class != DT_DC_DEFAULT) {
217*6ff6d951SJohn Birrell 		xyerror(D_DECL_CLASS, "only one storage class allowed "
218*6ff6d951SJohn Birrell 		    "in a declaration\n");
219*6ff6d951SJohn Birrell 	}
220*6ff6d951SJohn Birrell 
221*6ff6d951SJohn Birrell 	dsp->ds_class = class;
222*6ff6d951SJohn Birrell }
223*6ff6d951SJohn Birrell 
224*6ff6d951SJohn Birrell /*
225*6ff6d951SJohn Birrell  * Set the kind and name of the current declaration.  If none is allocated,
226*6ff6d951SJohn Birrell  * make a new decl and push it on to the top of our stack.  If the name or kind
227*6ff6d951SJohn Birrell  * is already set for the current decl, then we need to fail this declaration.
228*6ff6d951SJohn Birrell  * This can occur because too many types were given (e.g. "int int"), etc.
229*6ff6d951SJohn Birrell  */
230*6ff6d951SJohn Birrell dt_decl_t *
231*6ff6d951SJohn Birrell dt_decl_spec(ushort_t kind, char *name)
232*6ff6d951SJohn Birrell {
233*6ff6d951SJohn Birrell 	dt_decl_t *ddp = yypcb->pcb_dstack.ds_decl;
234*6ff6d951SJohn Birrell 
235*6ff6d951SJohn Birrell 	if (ddp == NULL)
236*6ff6d951SJohn Birrell 		return (dt_decl_push(dt_decl_alloc(kind, name)));
237*6ff6d951SJohn Birrell 
238*6ff6d951SJohn Birrell 	/*
239*6ff6d951SJohn Birrell 	 * If we already have a type name specified and we see another type
240*6ff6d951SJohn Birrell 	 * name, this is an error if the declaration is a typedef.  If the
241*6ff6d951SJohn Birrell 	 * declaration is not a typedef, then the user may be trying to declare
242*6ff6d951SJohn Birrell 	 * a variable whose name has been returned by lex as a TNAME token:
243*6ff6d951SJohn Birrell 	 * call dt_decl_ident() as if the grammar's IDENT rule was matched.
244*6ff6d951SJohn Birrell 	 */
245*6ff6d951SJohn Birrell 	if (ddp->dd_name != NULL && kind == CTF_K_TYPEDEF) {
246*6ff6d951SJohn Birrell 		if (yypcb->pcb_dstack.ds_class != DT_DC_TYPEDEF)
247*6ff6d951SJohn Birrell 			return (dt_decl_ident(name));
248*6ff6d951SJohn Birrell 		xyerror(D_DECL_IDRED, "identifier redeclared: %s\n", name);
249*6ff6d951SJohn Birrell 	}
250*6ff6d951SJohn Birrell 
251*6ff6d951SJohn Birrell 	if (ddp->dd_name != NULL || ddp->dd_kind != CTF_K_UNKNOWN)
252*6ff6d951SJohn Birrell 		xyerror(D_DECL_COMBO, "invalid type combination\n");
253*6ff6d951SJohn Birrell 
254*6ff6d951SJohn Birrell 	ddp->dd_kind = kind;
255*6ff6d951SJohn Birrell 	ddp->dd_name = name;
256*6ff6d951SJohn Birrell 
257*6ff6d951SJohn Birrell 	if (name != NULL && strchr(name, '`') != NULL) {
258*6ff6d951SJohn Birrell 		xyerror(D_DECL_SCOPE, "D scoping operator may not be used "
259*6ff6d951SJohn Birrell 		    "in a type name\n");
260*6ff6d951SJohn Birrell 	}
261*6ff6d951SJohn Birrell 
262*6ff6d951SJohn Birrell 	return (dt_decl_check(ddp));
263*6ff6d951SJohn Birrell }
264*6ff6d951SJohn Birrell 
265*6ff6d951SJohn Birrell dt_decl_t *
266*6ff6d951SJohn Birrell dt_decl_attr(ushort_t attr)
267*6ff6d951SJohn Birrell {
268*6ff6d951SJohn Birrell 	dt_decl_t *ddp = yypcb->pcb_dstack.ds_decl;
269*6ff6d951SJohn Birrell 
270*6ff6d951SJohn Birrell 	if (ddp == NULL) {
271*6ff6d951SJohn Birrell 		ddp = dt_decl_push(dt_decl_alloc(CTF_K_UNKNOWN, NULL));
272*6ff6d951SJohn Birrell 		ddp->dd_attr = attr;
273*6ff6d951SJohn Birrell 		return (ddp);
274*6ff6d951SJohn Birrell 	}
275*6ff6d951SJohn Birrell 
276*6ff6d951SJohn Birrell 	if (attr == DT_DA_LONG && (ddp->dd_attr & DT_DA_LONG)) {
277*6ff6d951SJohn Birrell 		ddp->dd_attr &= ~DT_DA_LONG;
278*6ff6d951SJohn Birrell 		attr = DT_DA_LONGLONG;
279*6ff6d951SJohn Birrell 	}
280*6ff6d951SJohn Birrell 
281*6ff6d951SJohn Birrell 	ddp->dd_attr |= attr;
282*6ff6d951SJohn Birrell 	return (dt_decl_check(ddp));
283*6ff6d951SJohn Birrell }
284*6ff6d951SJohn Birrell 
285*6ff6d951SJohn Birrell /*
286*6ff6d951SJohn Birrell  * Examine the list of formal parameters 'flist' and determine if the formal
287*6ff6d951SJohn Birrell  * name fnp->dn_string is defined in this list (B_TRUE) or not (B_FALSE).
288*6ff6d951SJohn Birrell  * If 'fnp' is in 'flist', do not search beyond 'fnp' itself in 'flist'.
289*6ff6d951SJohn Birrell  */
290*6ff6d951SJohn Birrell static int
291*6ff6d951SJohn Birrell dt_decl_protoform(dt_node_t *fnp, dt_node_t *flist)
292*6ff6d951SJohn Birrell {
293*6ff6d951SJohn Birrell 	dt_node_t *dnp;
294*6ff6d951SJohn Birrell 
295*6ff6d951SJohn Birrell 	for (dnp = flist; dnp != fnp && dnp != NULL; dnp = dnp->dn_list) {
296*6ff6d951SJohn Birrell 		if (dnp->dn_string != NULL &&
297*6ff6d951SJohn Birrell 		    strcmp(dnp->dn_string, fnp->dn_string) == 0)
298*6ff6d951SJohn Birrell 			return (B_TRUE);
299*6ff6d951SJohn Birrell 	}
300*6ff6d951SJohn Birrell 
301*6ff6d951SJohn Birrell 	return (B_FALSE);
302*6ff6d951SJohn Birrell }
303*6ff6d951SJohn Birrell 
304*6ff6d951SJohn Birrell /*
305*6ff6d951SJohn Birrell  * Common code for parsing array, function, and probe definition prototypes.
306*6ff6d951SJohn Birrell  * The prototype node list is specified as 'plist'.  The formal prototype
307*6ff6d951SJohn Birrell  * against which to compare the prototype is specified as 'flist'.  If plist
308*6ff6d951SJohn Birrell  * and flist are the same, we require that named parameters are unique.  If
309*6ff6d951SJohn Birrell  * plist and flist are different, we require that named parameters in plist
310*6ff6d951SJohn Birrell  * match a name that is present in flist.
311*6ff6d951SJohn Birrell  */
312*6ff6d951SJohn Birrell int
313*6ff6d951SJohn Birrell dt_decl_prototype(dt_node_t *plist,
314*6ff6d951SJohn Birrell     dt_node_t *flist, const char *kind, uint_t flags)
315*6ff6d951SJohn Birrell {
316*6ff6d951SJohn Birrell 	char n[DT_TYPE_NAMELEN];
317*6ff6d951SJohn Birrell 	int is_void, v = 0, i = 1;
318*6ff6d951SJohn Birrell 	int form = plist != flist;
319*6ff6d951SJohn Birrell 	dt_node_t *dnp;
320*6ff6d951SJohn Birrell 
321*6ff6d951SJohn Birrell 	for (dnp = plist; dnp != NULL; dnp = dnp->dn_list, i++) {
322*6ff6d951SJohn Birrell 
323*6ff6d951SJohn Birrell 		if (dnp->dn_type == CTF_ERR && !(flags & DT_DP_VARARGS)) {
324*6ff6d951SJohn Birrell 			dnerror(dnp, D_DECL_PROTO_VARARGS, "%s prototype may "
325*6ff6d951SJohn Birrell 			    "not use a variable-length argument list\n", kind);
326*6ff6d951SJohn Birrell 		}
327*6ff6d951SJohn Birrell 
328*6ff6d951SJohn Birrell 		if (dt_node_is_dynamic(dnp) && !(flags & DT_DP_DYNAMIC)) {
329*6ff6d951SJohn Birrell 			dnerror(dnp, D_DECL_PROTO_TYPE, "%s prototype may not "
330*6ff6d951SJohn Birrell 			    "use parameter of type %s: %s, parameter #%d\n",
331*6ff6d951SJohn Birrell 			    kind, dt_node_type_name(dnp, n, sizeof (n)),
332*6ff6d951SJohn Birrell 			    dnp->dn_string ? dnp->dn_string : "(anonymous)", i);
333*6ff6d951SJohn Birrell 		}
334*6ff6d951SJohn Birrell 
335*6ff6d951SJohn Birrell 		is_void = dt_node_is_void(dnp);
336*6ff6d951SJohn Birrell 		v += is_void;
337*6ff6d951SJohn Birrell 
338*6ff6d951SJohn Birrell 		if (is_void && !(flags & DT_DP_VOID)) {
339*6ff6d951SJohn Birrell 			dnerror(dnp, D_DECL_PROTO_TYPE, "%s prototype may not "
340*6ff6d951SJohn Birrell 			    "use parameter of type %s: %s, parameter #%d\n",
341*6ff6d951SJohn Birrell 			    kind, dt_node_type_name(dnp, n, sizeof (n)),
342*6ff6d951SJohn Birrell 			    dnp->dn_string ? dnp->dn_string : "(anonymous)", i);
343*6ff6d951SJohn Birrell 		}
344*6ff6d951SJohn Birrell 
345*6ff6d951SJohn Birrell 		if (is_void && dnp->dn_string != NULL) {
346*6ff6d951SJohn Birrell 			dnerror(dnp, D_DECL_PROTO_NAME, "void parameter may "
347*6ff6d951SJohn Birrell 			    "not have a name: %s\n", dnp->dn_string);
348*6ff6d951SJohn Birrell 		}
349*6ff6d951SJohn Birrell 
350*6ff6d951SJohn Birrell 		if (dnp->dn_string != NULL &&
351*6ff6d951SJohn Birrell 		    dt_decl_protoform(dnp, flist) != form) {
352*6ff6d951SJohn Birrell 			dnerror(dnp, D_DECL_PROTO_FORM, "parameter is "
353*6ff6d951SJohn Birrell 			    "%s declared in %s prototype: %s, parameter #%d\n",
354*6ff6d951SJohn Birrell 			    form ? "not" : "already", kind, dnp->dn_string, i);
355*6ff6d951SJohn Birrell 		}
356*6ff6d951SJohn Birrell 
357*6ff6d951SJohn Birrell 		if (dnp->dn_string == NULL &&
358*6ff6d951SJohn Birrell 		    !is_void && !(flags & DT_DP_ANON)) {
359*6ff6d951SJohn Birrell 			dnerror(dnp, D_DECL_PROTO_NAME, "parameter declaration "
360*6ff6d951SJohn Birrell 			    "requires a name: parameter #%d\n", i);
361*6ff6d951SJohn Birrell 		}
362*6ff6d951SJohn Birrell 	}
363*6ff6d951SJohn Birrell 
364*6ff6d951SJohn Birrell 	if (v != 0 && plist->dn_list != NULL)
365*6ff6d951SJohn Birrell 		xyerror(D_DECL_PROTO_VOID, "void must be sole parameter\n");
366*6ff6d951SJohn Birrell 
367*6ff6d951SJohn Birrell 	return (v ? 0 : i - 1); /* return zero if sole parameter is 'void' */
368*6ff6d951SJohn Birrell }
369*6ff6d951SJohn Birrell 
370*6ff6d951SJohn Birrell dt_decl_t *
371*6ff6d951SJohn Birrell dt_decl_array(dt_node_t *dnp)
372*6ff6d951SJohn Birrell {
373*6ff6d951SJohn Birrell 	dt_decl_t *ddp = dt_decl_push(dt_decl_alloc(CTF_K_ARRAY, NULL));
374*6ff6d951SJohn Birrell 	dt_scope_t *dsp = &yypcb->pcb_dstack;
375*6ff6d951SJohn Birrell 	dt_decl_t *ndp = ddp;
376*6ff6d951SJohn Birrell 
377*6ff6d951SJohn Birrell 	/*
378*6ff6d951SJohn Birrell 	 * After pushing the array on to the decl stack, scan ahead for multi-
379*6ff6d951SJohn Birrell 	 * dimensional array declarations and push the current decl to the
380*6ff6d951SJohn Birrell 	 * bottom to match the resulting CTF type tree and data layout.  Refer
381*6ff6d951SJohn Birrell 	 * to the comments in dt_decl_type() and ISO C 6.5.2.1 for more info.
382*6ff6d951SJohn Birrell 	 */
383*6ff6d951SJohn Birrell 	while (ndp->dd_next != NULL && ndp->dd_next->dd_kind == CTF_K_ARRAY)
384*6ff6d951SJohn Birrell 		ndp = ndp->dd_next; /* skip to bottom-most array declaration */
385*6ff6d951SJohn Birrell 
386*6ff6d951SJohn Birrell 	if (ndp != ddp) {
387*6ff6d951SJohn Birrell 		if (dnp != NULL && dnp->dn_kind == DT_NODE_TYPE) {
388*6ff6d951SJohn Birrell 			xyerror(D_DECL_DYNOBJ,
389*6ff6d951SJohn Birrell 			    "cannot declare array of associative arrays\n");
390*6ff6d951SJohn Birrell 		}
391*6ff6d951SJohn Birrell 		dsp->ds_decl = ddp->dd_next;
392*6ff6d951SJohn Birrell 		ddp->dd_next = ndp->dd_next;
393*6ff6d951SJohn Birrell 		ndp->dd_next = ddp;
394*6ff6d951SJohn Birrell 	}
395*6ff6d951SJohn Birrell 
396*6ff6d951SJohn Birrell 	if (ddp->dd_next->dd_name != NULL &&
397*6ff6d951SJohn Birrell 	    strcmp(ddp->dd_next->dd_name, "void") == 0)
398*6ff6d951SJohn Birrell 		xyerror(D_DECL_VOIDOBJ, "cannot declare array of void\n");
399*6ff6d951SJohn Birrell 
400*6ff6d951SJohn Birrell 	if (dnp != NULL && dnp->dn_kind != DT_NODE_TYPE) {
401*6ff6d951SJohn Birrell 		dnp = ddp->dd_node = dt_node_cook(dnp, DT_IDFLG_REF);
402*6ff6d951SJohn Birrell 
403*6ff6d951SJohn Birrell 		if (dt_node_is_posconst(dnp) == 0) {
404*6ff6d951SJohn Birrell 			xyerror(D_DECL_ARRSUB, "positive integral constant "
405*6ff6d951SJohn Birrell 			    "expression or tuple signature expected as "
406*6ff6d951SJohn Birrell 			    "array declaration subscript\n");
407*6ff6d951SJohn Birrell 		}
408*6ff6d951SJohn Birrell 
409*6ff6d951SJohn Birrell 		if (dnp->dn_value > UINT_MAX)
410*6ff6d951SJohn Birrell 			xyerror(D_DECL_ARRBIG, "array dimension too big\n");
411*6ff6d951SJohn Birrell 
412*6ff6d951SJohn Birrell 	} else if (dnp != NULL) {
413*6ff6d951SJohn Birrell 		ddp->dd_node = dnp;
414*6ff6d951SJohn Birrell 		(void) dt_decl_prototype(dnp, dnp, "array", DT_DP_ANON);
415*6ff6d951SJohn Birrell 	}
416*6ff6d951SJohn Birrell 
417*6ff6d951SJohn Birrell 	return (ddp);
418*6ff6d951SJohn Birrell }
419*6ff6d951SJohn Birrell 
420*6ff6d951SJohn Birrell /*
421*6ff6d951SJohn Birrell  * When a function is declared, we need to fudge the decl stack a bit if the
422*6ff6d951SJohn Birrell  * declaration uses the function pointer (*)() syntax.  In this case, the
423*6ff6d951SJohn Birrell  * dt_decl_func() call occurs *after* the dt_decl_ptr() call, even though the
424*6ff6d951SJohn Birrell  * resulting type is "pointer to function".  To make the pointer land on top,
425*6ff6d951SJohn Birrell  * we check to see if 'pdp' is non-NULL and a pointer.  If it is, we search
426*6ff6d951SJohn Birrell  * backward for a decl tagged with DT_DA_PAREN, and if one is found, the func
427*6ff6d951SJohn Birrell  * decl is inserted behind this node in the decl list instead of at the top.
428*6ff6d951SJohn Birrell  * In all cases, the func decl's dd_next pointer is set to the decl chain
429*6ff6d951SJohn Birrell  * for the function's return type and the function parameter list is discarded.
430*6ff6d951SJohn Birrell  */
431*6ff6d951SJohn Birrell dt_decl_t *
432*6ff6d951SJohn Birrell dt_decl_func(dt_decl_t *pdp, dt_node_t *dnp)
433*6ff6d951SJohn Birrell {
434*6ff6d951SJohn Birrell 	dt_decl_t *ddp = dt_decl_alloc(CTF_K_FUNCTION, NULL);
435*6ff6d951SJohn Birrell 
436*6ff6d951SJohn Birrell 	ddp->dd_node = dnp;
437*6ff6d951SJohn Birrell 
438*6ff6d951SJohn Birrell 	(void) dt_decl_prototype(dnp, dnp, "function",
439*6ff6d951SJohn Birrell 	    DT_DP_VARARGS | DT_DP_VOID | DT_DP_ANON);
440*6ff6d951SJohn Birrell 
441*6ff6d951SJohn Birrell 	if (pdp == NULL || pdp->dd_kind != CTF_K_POINTER)
442*6ff6d951SJohn Birrell 		return (dt_decl_push(ddp));
443*6ff6d951SJohn Birrell 
444*6ff6d951SJohn Birrell 	while (pdp->dd_next != NULL && !(pdp->dd_next->dd_attr & DT_DA_PAREN))
445*6ff6d951SJohn Birrell 		pdp = pdp->dd_next;
446*6ff6d951SJohn Birrell 
447*6ff6d951SJohn Birrell 	if (pdp->dd_next == NULL)
448*6ff6d951SJohn Birrell 		return (dt_decl_push(ddp));
449*6ff6d951SJohn Birrell 
450*6ff6d951SJohn Birrell 	ddp->dd_next = pdp->dd_next;
451*6ff6d951SJohn Birrell 	pdp->dd_next = ddp;
452*6ff6d951SJohn Birrell 
453*6ff6d951SJohn Birrell 	return (pdp);
454*6ff6d951SJohn Birrell }
455*6ff6d951SJohn Birrell 
456*6ff6d951SJohn Birrell dt_decl_t *
457*6ff6d951SJohn Birrell dt_decl_ptr(void)
458*6ff6d951SJohn Birrell {
459*6ff6d951SJohn Birrell 	return (dt_decl_push(dt_decl_alloc(CTF_K_POINTER, NULL)));
460*6ff6d951SJohn Birrell }
461*6ff6d951SJohn Birrell 
462*6ff6d951SJohn Birrell dt_decl_t *
463*6ff6d951SJohn Birrell dt_decl_sou(uint_t kind, char *name)
464*6ff6d951SJohn Birrell {
465*6ff6d951SJohn Birrell 	dt_decl_t *ddp = dt_decl_spec(kind, name);
466*6ff6d951SJohn Birrell 	char n[DT_TYPE_NAMELEN];
467*6ff6d951SJohn Birrell 	ctf_file_t *ctfp;
468*6ff6d951SJohn Birrell 	ctf_id_t type;
469*6ff6d951SJohn Birrell 	uint_t flag;
470*6ff6d951SJohn Birrell 
471*6ff6d951SJohn Birrell 	if (yypcb->pcb_idepth != 0)
472*6ff6d951SJohn Birrell 		ctfp = yypcb->pcb_hdl->dt_cdefs->dm_ctfp;
473*6ff6d951SJohn Birrell 	else
474*6ff6d951SJohn Birrell 		ctfp = yypcb->pcb_hdl->dt_ddefs->dm_ctfp;
475*6ff6d951SJohn Birrell 
476*6ff6d951SJohn Birrell 	if (yypcb->pcb_dstack.ds_next != NULL)
477*6ff6d951SJohn Birrell 		flag = CTF_ADD_NONROOT;
478*6ff6d951SJohn Birrell 	else
479*6ff6d951SJohn Birrell 		flag = CTF_ADD_ROOT;
480*6ff6d951SJohn Birrell 
481*6ff6d951SJohn Birrell 	(void) snprintf(n, sizeof (n), "%s %s",
482*6ff6d951SJohn Birrell 	    kind == CTF_K_STRUCT ? "struct" : "union",
483*6ff6d951SJohn Birrell 	    name == NULL ? "(anon)" : name);
484*6ff6d951SJohn Birrell 
485*6ff6d951SJohn Birrell 	if (name != NULL && (type = ctf_lookup_by_name(ctfp, n)) != CTF_ERR &&
486*6ff6d951SJohn Birrell 	    ctf_type_kind(ctfp, type) != CTF_K_FORWARD)
487*6ff6d951SJohn Birrell 		xyerror(D_DECL_TYPERED, "type redeclared: %s\n", n);
488*6ff6d951SJohn Birrell 
489*6ff6d951SJohn Birrell 	if (kind == CTF_K_STRUCT)
490*6ff6d951SJohn Birrell 		type = ctf_add_struct(ctfp, flag, name);
491*6ff6d951SJohn Birrell 	else
492*6ff6d951SJohn Birrell 		type = ctf_add_union(ctfp, flag, name);
493*6ff6d951SJohn Birrell 
494*6ff6d951SJohn Birrell 	if (type == CTF_ERR || ctf_update(ctfp) == CTF_ERR) {
495*6ff6d951SJohn Birrell 		xyerror(D_UNKNOWN, "failed to define %s: %s\n",
496*6ff6d951SJohn Birrell 		    n, ctf_errmsg(ctf_errno(ctfp)));
497*6ff6d951SJohn Birrell 	}
498*6ff6d951SJohn Birrell 
499*6ff6d951SJohn Birrell 	ddp->dd_ctfp = ctfp;
500*6ff6d951SJohn Birrell 	ddp->dd_type = type;
501*6ff6d951SJohn Birrell 
502*6ff6d951SJohn Birrell 	dt_scope_push(ctfp, type);
503*6ff6d951SJohn Birrell 	return (ddp);
504*6ff6d951SJohn Birrell }
505*6ff6d951SJohn Birrell 
506*6ff6d951SJohn Birrell void
507*6ff6d951SJohn Birrell dt_decl_member(dt_node_t *dnp)
508*6ff6d951SJohn Birrell {
509*6ff6d951SJohn Birrell 	dt_scope_t *dsp = yypcb->pcb_dstack.ds_next;
510*6ff6d951SJohn Birrell 	dt_decl_t *ddp = yypcb->pcb_dstack.ds_decl;
511*6ff6d951SJohn Birrell 	char *ident = yypcb->pcb_dstack.ds_ident;
512*6ff6d951SJohn Birrell 
513*6ff6d951SJohn Birrell 	const char *idname = ident ? ident : "(anon)";
514*6ff6d951SJohn Birrell 	char n[DT_TYPE_NAMELEN];
515*6ff6d951SJohn Birrell 
516*6ff6d951SJohn Birrell 	dtrace_typeinfo_t dtt;
517*6ff6d951SJohn Birrell 	ctf_encoding_t cte;
518*6ff6d951SJohn Birrell 	ctf_id_t base;
519*6ff6d951SJohn Birrell 	uint_t kind;
520*6ff6d951SJohn Birrell 	ssize_t size;
521*6ff6d951SJohn Birrell 
522*6ff6d951SJohn Birrell 	if (dsp == NULL)
523*6ff6d951SJohn Birrell 		longjmp(yypcb->pcb_jmpbuf, EDT_NOSCOPE);
524*6ff6d951SJohn Birrell 
525*6ff6d951SJohn Birrell 	if (ddp == NULL)
526*6ff6d951SJohn Birrell 		longjmp(yypcb->pcb_jmpbuf, EDT_NODECL);
527*6ff6d951SJohn Birrell 
528*6ff6d951SJohn Birrell 	if (dnp == NULL && ident == NULL)
529*6ff6d951SJohn Birrell 		xyerror(D_DECL_MNAME, "member declaration requires a name\n");
530*6ff6d951SJohn Birrell 
531*6ff6d951SJohn Birrell 	if (ddp->dd_kind == CTF_K_UNKNOWN && ddp->dd_name == NULL) {
532*6ff6d951SJohn Birrell 		ddp->dd_kind = CTF_K_INTEGER;
533*6ff6d951SJohn Birrell 		(void) dt_decl_check(ddp);
534*6ff6d951SJohn Birrell 	}
535*6ff6d951SJohn Birrell 
536*6ff6d951SJohn Birrell 	if (dt_decl_type(ddp, &dtt) != 0)
537*6ff6d951SJohn Birrell 		longjmp(yypcb->pcb_jmpbuf, EDT_COMPILER);
538*6ff6d951SJohn Birrell 
539*6ff6d951SJohn Birrell 	if (ident != NULL && strchr(ident, '`') != NULL) {
540*6ff6d951SJohn Birrell 		xyerror(D_DECL_SCOPE, "D scoping operator may not be used "
541*6ff6d951SJohn Birrell 		    "in a member name (%s)\n", ident);
542*6ff6d951SJohn Birrell 	}
543*6ff6d951SJohn Birrell 
544*6ff6d951SJohn Birrell 	if (dtt.dtt_ctfp == DT_DYN_CTFP(yypcb->pcb_hdl) &&
545*6ff6d951SJohn Birrell 	    dtt.dtt_type == DT_DYN_TYPE(yypcb->pcb_hdl)) {
546*6ff6d951SJohn Birrell 		xyerror(D_DECL_DYNOBJ,
547*6ff6d951SJohn Birrell 		    "cannot have dynamic member: %s\n", ident);
548*6ff6d951SJohn Birrell 	}
549*6ff6d951SJohn Birrell 
550*6ff6d951SJohn Birrell 	base = ctf_type_resolve(dtt.dtt_ctfp, dtt.dtt_type);
551*6ff6d951SJohn Birrell 	kind = ctf_type_kind(dtt.dtt_ctfp, base);
552*6ff6d951SJohn Birrell 	size = ctf_type_size(dtt.dtt_ctfp, base);
553*6ff6d951SJohn Birrell 
554*6ff6d951SJohn Birrell 	if (kind == CTF_K_FORWARD || ((kind == CTF_K_STRUCT ||
555*6ff6d951SJohn Birrell 	    kind == CTF_K_UNION) && size == 0)) {
556*6ff6d951SJohn Birrell 		xyerror(D_DECL_INCOMPLETE, "incomplete struct/union/enum %s: "
557*6ff6d951SJohn Birrell 		    "%s\n", dt_type_name(dtt.dtt_ctfp, dtt.dtt_type,
558*6ff6d951SJohn Birrell 		    n, sizeof (n)), ident);
559*6ff6d951SJohn Birrell 	}
560*6ff6d951SJohn Birrell 
561*6ff6d951SJohn Birrell 	if (size == 0)
562*6ff6d951SJohn Birrell 		xyerror(D_DECL_VOIDOBJ, "cannot have void member: %s\n", ident);
563*6ff6d951SJohn Birrell 
564*6ff6d951SJohn Birrell 	/*
565*6ff6d951SJohn Birrell 	 * If a bit-field qualifier was part of the member declaration, create
566*6ff6d951SJohn Birrell 	 * a new integer type of the same name and attributes as the base type
567*6ff6d951SJohn Birrell 	 * and size equal to the specified number of bits.  We reset 'dtt' to
568*6ff6d951SJohn Birrell 	 * refer to this new bit-field type and continue on to add the member.
569*6ff6d951SJohn Birrell 	 */
570*6ff6d951SJohn Birrell 	if (dnp != NULL) {
571*6ff6d951SJohn Birrell 		dnp = dt_node_cook(dnp, DT_IDFLG_REF);
572*6ff6d951SJohn Birrell 
573*6ff6d951SJohn Birrell 		/*
574*6ff6d951SJohn Birrell 		 * A bit-field member with no declarator is permitted to have
575*6ff6d951SJohn Birrell 		 * size zero and indicates that no more fields are to be packed
576*6ff6d951SJohn Birrell 		 * into the current storage unit.  We ignore these directives
577*6ff6d951SJohn Birrell 		 * as the underlying ctf code currently does so for all fields.
578*6ff6d951SJohn Birrell 		 */
579*6ff6d951SJohn Birrell 		if (ident == NULL && dnp->dn_kind == DT_NODE_INT &&
580*6ff6d951SJohn Birrell 		    dnp->dn_value == 0) {
581*6ff6d951SJohn Birrell 			dt_node_free(dnp);
582*6ff6d951SJohn Birrell 			goto done;
583*6ff6d951SJohn Birrell 		}
584*6ff6d951SJohn Birrell 
585*6ff6d951SJohn Birrell 		if (dt_node_is_posconst(dnp) == 0) {
586*6ff6d951SJohn Birrell 			xyerror(D_DECL_BFCONST, "positive integral constant "
587*6ff6d951SJohn Birrell 			    "expression expected as bit-field size\n");
588*6ff6d951SJohn Birrell 		}
589*6ff6d951SJohn Birrell 
590*6ff6d951SJohn Birrell 		if (ctf_type_kind(dtt.dtt_ctfp, base) != CTF_K_INTEGER ||
591*6ff6d951SJohn Birrell 		    ctf_type_encoding(dtt.dtt_ctfp, base, &cte) == CTF_ERR ||
592*6ff6d951SJohn Birrell 		    IS_VOID(cte)) {
593*6ff6d951SJohn Birrell 			xyerror(D_DECL_BFTYPE, "invalid type for "
594*6ff6d951SJohn Birrell 			    "bit-field: %s\n", idname);
595*6ff6d951SJohn Birrell 		}
596*6ff6d951SJohn Birrell 
597*6ff6d951SJohn Birrell 		if (dnp->dn_value > cte.cte_bits) {
598*6ff6d951SJohn Birrell 			xyerror(D_DECL_BFSIZE, "bit-field too big "
599*6ff6d951SJohn Birrell 			    "for type: %s\n", idname);
600*6ff6d951SJohn Birrell 		}
601*6ff6d951SJohn Birrell 
602*6ff6d951SJohn Birrell 		cte.cte_offset = 0;
603*6ff6d951SJohn Birrell 		cte.cte_bits = (uint_t)dnp->dn_value;
604*6ff6d951SJohn Birrell 
605*6ff6d951SJohn Birrell 		dtt.dtt_type = ctf_add_integer(dsp->ds_ctfp,
606*6ff6d951SJohn Birrell 		    CTF_ADD_NONROOT, ctf_type_name(dtt.dtt_ctfp,
607*6ff6d951SJohn Birrell 		    dtt.dtt_type, n, sizeof (n)), &cte);
608*6ff6d951SJohn Birrell 
609*6ff6d951SJohn Birrell 		if (dtt.dtt_type == CTF_ERR ||
610*6ff6d951SJohn Birrell 		    ctf_update(dsp->ds_ctfp) == CTF_ERR) {
611*6ff6d951SJohn Birrell 			xyerror(D_UNKNOWN, "failed to create type for "
612*6ff6d951SJohn Birrell 			    "member '%s': %s\n", idname,
613*6ff6d951SJohn Birrell 			    ctf_errmsg(ctf_errno(dsp->ds_ctfp)));
614*6ff6d951SJohn Birrell 		}
615*6ff6d951SJohn Birrell 
616*6ff6d951SJohn Birrell 		dtt.dtt_ctfp = dsp->ds_ctfp;
617*6ff6d951SJohn Birrell 		dt_node_free(dnp);
618*6ff6d951SJohn Birrell 	}
619*6ff6d951SJohn Birrell 
620*6ff6d951SJohn Birrell 	/*
621*6ff6d951SJohn Birrell 	 * If the member type is not defined in the same CTF container as the
622*6ff6d951SJohn Birrell 	 * one associated with the current scope (i.e. the container for the
623*6ff6d951SJohn Birrell 	 * struct or union itself) or its parent, copy the member type into
624*6ff6d951SJohn Birrell 	 * this container and reset dtt to refer to the copied type.
625*6ff6d951SJohn Birrell 	 */
626*6ff6d951SJohn Birrell 	if (dtt.dtt_ctfp != dsp->ds_ctfp &&
627*6ff6d951SJohn Birrell 	    dtt.dtt_ctfp != ctf_parent_file(dsp->ds_ctfp)) {
628*6ff6d951SJohn Birrell 
629*6ff6d951SJohn Birrell 		dtt.dtt_type = ctf_add_type(dsp->ds_ctfp,
630*6ff6d951SJohn Birrell 		    dtt.dtt_ctfp, dtt.dtt_type);
631*6ff6d951SJohn Birrell 		dtt.dtt_ctfp = dsp->ds_ctfp;
632*6ff6d951SJohn Birrell 
633*6ff6d951SJohn Birrell 		if (dtt.dtt_type == CTF_ERR ||
634*6ff6d951SJohn Birrell 		    ctf_update(dtt.dtt_ctfp) == CTF_ERR) {
635*6ff6d951SJohn Birrell 			xyerror(D_UNKNOWN, "failed to copy type of '%s': %s\n",
636*6ff6d951SJohn Birrell 			    idname, ctf_errmsg(ctf_errno(dtt.dtt_ctfp)));
637*6ff6d951SJohn Birrell 		}
638*6ff6d951SJohn Birrell 	}
639*6ff6d951SJohn Birrell 
640*6ff6d951SJohn Birrell 	if (ctf_add_member(dsp->ds_ctfp, dsp->ds_type,
641*6ff6d951SJohn Birrell 	    ident, dtt.dtt_type) == CTF_ERR) {
642*6ff6d951SJohn Birrell 		xyerror(D_UNKNOWN, "failed to define member '%s': %s\n",
643*6ff6d951SJohn Birrell 		    idname, ctf_errmsg(ctf_errno(dsp->ds_ctfp)));
644*6ff6d951SJohn Birrell 	}
645*6ff6d951SJohn Birrell 
646*6ff6d951SJohn Birrell done:
647*6ff6d951SJohn Birrell 	free(ident);
648*6ff6d951SJohn Birrell 	yypcb->pcb_dstack.ds_ident = NULL;
649*6ff6d951SJohn Birrell 	dt_decl_reset();
650*6ff6d951SJohn Birrell }
651*6ff6d951SJohn Birrell 
652*6ff6d951SJohn Birrell /*ARGSUSED*/
653*6ff6d951SJohn Birrell static int
654*6ff6d951SJohn Birrell dt_decl_hasmembers(const char *name, int value, void *private)
655*6ff6d951SJohn Birrell {
656*6ff6d951SJohn Birrell 	return (1); /* abort search and return true if a member exists */
657*6ff6d951SJohn Birrell }
658*6ff6d951SJohn Birrell 
659*6ff6d951SJohn Birrell dt_decl_t *
660*6ff6d951SJohn Birrell dt_decl_enum(char *name)
661*6ff6d951SJohn Birrell {
662*6ff6d951SJohn Birrell 	dt_decl_t *ddp = dt_decl_spec(CTF_K_ENUM, name);
663*6ff6d951SJohn Birrell 	char n[DT_TYPE_NAMELEN];
664*6ff6d951SJohn Birrell 	ctf_file_t *ctfp;
665*6ff6d951SJohn Birrell 	ctf_id_t type;
666*6ff6d951SJohn Birrell 	uint_t flag;
667*6ff6d951SJohn Birrell 
668*6ff6d951SJohn Birrell 	if (yypcb->pcb_idepth != 0)
669*6ff6d951SJohn Birrell 		ctfp = yypcb->pcb_hdl->dt_cdefs->dm_ctfp;
670*6ff6d951SJohn Birrell 	else
671*6ff6d951SJohn Birrell 		ctfp = yypcb->pcb_hdl->dt_ddefs->dm_ctfp;
672*6ff6d951SJohn Birrell 
673*6ff6d951SJohn Birrell 	if (yypcb->pcb_dstack.ds_next != NULL)
674*6ff6d951SJohn Birrell 		flag = CTF_ADD_NONROOT;
675*6ff6d951SJohn Birrell 	else
676*6ff6d951SJohn Birrell 		flag = CTF_ADD_ROOT;
677*6ff6d951SJohn Birrell 
678*6ff6d951SJohn Birrell 	(void) snprintf(n, sizeof (n), "enum %s", name ? name : "(anon)");
679*6ff6d951SJohn Birrell 
680*6ff6d951SJohn Birrell 	if (name != NULL && (type = ctf_lookup_by_name(ctfp, n)) != CTF_ERR) {
681*6ff6d951SJohn Birrell 		if (ctf_enum_iter(ctfp, type, dt_decl_hasmembers, NULL))
682*6ff6d951SJohn Birrell 			xyerror(D_DECL_TYPERED, "type redeclared: %s\n", n);
683*6ff6d951SJohn Birrell 	} else if ((type = ctf_add_enum(ctfp, flag, name)) == CTF_ERR) {
684*6ff6d951SJohn Birrell 		xyerror(D_UNKNOWN, "failed to define %s: %s\n",
685*6ff6d951SJohn Birrell 		    n, ctf_errmsg(ctf_errno(ctfp)));
686*6ff6d951SJohn Birrell 	}
687*6ff6d951SJohn Birrell 
688*6ff6d951SJohn Birrell 	ddp->dd_ctfp = ctfp;
689*6ff6d951SJohn Birrell 	ddp->dd_type = type;
690*6ff6d951SJohn Birrell 
691*6ff6d951SJohn Birrell 	dt_scope_push(ctfp, type);
692*6ff6d951SJohn Birrell 	return (ddp);
693*6ff6d951SJohn Birrell }
694*6ff6d951SJohn Birrell 
695*6ff6d951SJohn Birrell void
696*6ff6d951SJohn Birrell dt_decl_enumerator(char *s, dt_node_t *dnp)
697*6ff6d951SJohn Birrell {
698*6ff6d951SJohn Birrell 	dt_scope_t *dsp = yypcb->pcb_dstack.ds_next;
699*6ff6d951SJohn Birrell 	dtrace_hdl_t *dtp = yypcb->pcb_hdl;
700*6ff6d951SJohn Birrell 
701*6ff6d951SJohn Birrell 	dt_idnode_t *inp;
702*6ff6d951SJohn Birrell 	dt_ident_t *idp;
703*6ff6d951SJohn Birrell 	char *name;
704*6ff6d951SJohn Birrell 	int value;
705*6ff6d951SJohn Birrell 
706*6ff6d951SJohn Birrell 	name = alloca(strlen(s) + 1);
707*6ff6d951SJohn Birrell 	(void) strcpy(name, s);
708*6ff6d951SJohn Birrell 	free(s);
709*6ff6d951SJohn Birrell 
710*6ff6d951SJohn Birrell 	if (dsp == NULL)
711*6ff6d951SJohn Birrell 		longjmp(yypcb->pcb_jmpbuf, EDT_NOSCOPE);
712*6ff6d951SJohn Birrell 
713*6ff6d951SJohn Birrell 	assert(dsp->ds_decl->dd_kind == CTF_K_ENUM);
714*6ff6d951SJohn Birrell 	value = dsp->ds_enumval + 1; /* default is previous value plus one */
715*6ff6d951SJohn Birrell 
716*6ff6d951SJohn Birrell 	if (strchr(name, '`') != NULL) {
717*6ff6d951SJohn Birrell 		xyerror(D_DECL_SCOPE, "D scoping operator may not be used in "
718*6ff6d951SJohn Birrell 		    "an enumerator name (%s)\n", name);
719*6ff6d951SJohn Birrell 	}
720*6ff6d951SJohn Birrell 
721*6ff6d951SJohn Birrell 	/*
722*6ff6d951SJohn Birrell 	 * If the enumerator is being assigned a value, cook and check the node
723*6ff6d951SJohn Birrell 	 * and then free it after we get the value.  We also permit references
724*6ff6d951SJohn Birrell 	 * to identifiers which are previously defined enumerators in the type.
725*6ff6d951SJohn Birrell 	 */
726*6ff6d951SJohn Birrell 	if (dnp != NULL) {
727*6ff6d951SJohn Birrell 		if (dnp->dn_kind != DT_NODE_IDENT || ctf_enum_value(
728*6ff6d951SJohn Birrell 		    dsp->ds_ctfp, dsp->ds_type, dnp->dn_string, &value) != 0) {
729*6ff6d951SJohn Birrell 			dnp = dt_node_cook(dnp, DT_IDFLG_REF);
730*6ff6d951SJohn Birrell 
731*6ff6d951SJohn Birrell 			if (dnp->dn_kind != DT_NODE_INT) {
732*6ff6d951SJohn Birrell 				xyerror(D_DECL_ENCONST, "enumerator '%s' must "
733*6ff6d951SJohn Birrell 				    "be assigned to an integral constant "
734*6ff6d951SJohn Birrell 				    "expression\n", name);
735*6ff6d951SJohn Birrell 			}
736*6ff6d951SJohn Birrell 
737*6ff6d951SJohn Birrell 			if ((intmax_t)dnp->dn_value > INT_MAX ||
738*6ff6d951SJohn Birrell 			    (intmax_t)dnp->dn_value < INT_MIN) {
739*6ff6d951SJohn Birrell 				xyerror(D_DECL_ENOFLOW, "enumerator '%s' value "
740*6ff6d951SJohn Birrell 				    "overflows INT_MAX (%d)\n", name, INT_MAX);
741*6ff6d951SJohn Birrell 			}
742*6ff6d951SJohn Birrell 
743*6ff6d951SJohn Birrell 			value = (int)dnp->dn_value;
744*6ff6d951SJohn Birrell 		}
745*6ff6d951SJohn Birrell 		dt_node_free(dnp);
746*6ff6d951SJohn Birrell 	}
747*6ff6d951SJohn Birrell 
748*6ff6d951SJohn Birrell 	if (ctf_add_enumerator(dsp->ds_ctfp, dsp->ds_type,
749*6ff6d951SJohn Birrell 	    name, value) == CTF_ERR || ctf_update(dsp->ds_ctfp) == CTF_ERR) {
750*6ff6d951SJohn Birrell 		xyerror(D_UNKNOWN, "failed to define enumerator '%s': %s\n",
751*6ff6d951SJohn Birrell 		    name, ctf_errmsg(ctf_errno(dsp->ds_ctfp)));
752*6ff6d951SJohn Birrell 	}
753*6ff6d951SJohn Birrell 
754*6ff6d951SJohn Birrell 	dsp->ds_enumval = value; /* save most recent value */
755*6ff6d951SJohn Birrell 
756*6ff6d951SJohn Birrell 	/*
757*6ff6d951SJohn Birrell 	 * If the enumerator name matches an identifier in the global scope,
758*6ff6d951SJohn Birrell 	 * flag this as an error.  We only do this for "D" enumerators to
759*6ff6d951SJohn Birrell 	 * prevent "C" header file enumerators from conflicting with the ever-
760*6ff6d951SJohn Birrell 	 * growing list of D built-in global variables and inlines.  If a "C"
761*6ff6d951SJohn Birrell 	 * enumerator conflicts with a global identifier, we add the enumerator
762*6ff6d951SJohn Birrell 	 * but do not insert a corresponding inline (i.e. the D variable wins).
763*6ff6d951SJohn Birrell 	 */
764*6ff6d951SJohn Birrell 	if (dt_idstack_lookup(&yypcb->pcb_globals, name) != NULL) {
765*6ff6d951SJohn Birrell 		if (dsp->ds_ctfp == dtp->dt_ddefs->dm_ctfp) {
766*6ff6d951SJohn Birrell 			xyerror(D_DECL_IDRED,
767*6ff6d951SJohn Birrell 			    "identifier redeclared: %s\n", name);
768*6ff6d951SJohn Birrell 		} else
769*6ff6d951SJohn Birrell 			return;
770*6ff6d951SJohn Birrell 	}
771*6ff6d951SJohn Birrell 
772*6ff6d951SJohn Birrell 	dt_dprintf("add global enumerator %s = %d\n", name, value);
773*6ff6d951SJohn Birrell 
774*6ff6d951SJohn Birrell 	idp = dt_idhash_insert(dtp->dt_globals, name, DT_IDENT_ENUM,
775*6ff6d951SJohn Birrell 	    DT_IDFLG_INLINE | DT_IDFLG_REF, 0, _dtrace_defattr, 0,
776*6ff6d951SJohn Birrell 	    &dt_idops_inline, NULL, dtp->dt_gen);
777*6ff6d951SJohn Birrell 
778*6ff6d951SJohn Birrell 	if (idp == NULL)
779*6ff6d951SJohn Birrell 		longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
780*6ff6d951SJohn Birrell 
781*6ff6d951SJohn Birrell 	yyintprefix = 0;
782*6ff6d951SJohn Birrell 	yyintsuffix[0] = '\0';
783*6ff6d951SJohn Birrell 	yyintdecimal = 0;
784*6ff6d951SJohn Birrell 
785*6ff6d951SJohn Birrell 	dnp = dt_node_int(value);
786*6ff6d951SJohn Birrell 	dt_node_type_assign(dnp, dsp->ds_ctfp, dsp->ds_type);
787*6ff6d951SJohn Birrell 
788*6ff6d951SJohn Birrell 	if ((inp = malloc(sizeof (dt_idnode_t))) == NULL)
789*6ff6d951SJohn Birrell 		longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
790*6ff6d951SJohn Birrell 
791*6ff6d951SJohn Birrell 	/*
792*6ff6d951SJohn Birrell 	 * Remove the INT node from the node allocation list and store it in
793*6ff6d951SJohn Birrell 	 * din_list and din_root so it persists with and is freed by the ident.
794*6ff6d951SJohn Birrell 	 */
795*6ff6d951SJohn Birrell 	assert(yypcb->pcb_list == dnp);
796*6ff6d951SJohn Birrell 	yypcb->pcb_list = dnp->dn_link;
797*6ff6d951SJohn Birrell 	dnp->dn_link = NULL;
798*6ff6d951SJohn Birrell 
799*6ff6d951SJohn Birrell 	bzero(inp, sizeof (dt_idnode_t));
800*6ff6d951SJohn Birrell 	inp->din_list = dnp;
801*6ff6d951SJohn Birrell 	inp->din_root = dnp;
802*6ff6d951SJohn Birrell 
803*6ff6d951SJohn Birrell 	idp->di_iarg = inp;
804*6ff6d951SJohn Birrell 	idp->di_ctfp = dsp->ds_ctfp;
805*6ff6d951SJohn Birrell 	idp->di_type = dsp->ds_type;
806*6ff6d951SJohn Birrell }
807*6ff6d951SJohn Birrell 
808*6ff6d951SJohn Birrell /*
809*6ff6d951SJohn Birrell  * Look up the type corresponding to the specified decl stack.  The scoping of
810*6ff6d951SJohn Birrell  * the underlying type names is handled by dt_type_lookup().  We build up the
811*6ff6d951SJohn Birrell  * name from the specified string and prefixes and then lookup the type.  If
812*6ff6d951SJohn Birrell  * we fail, an errmsg is saved and the caller must abort with EDT_COMPILER.
813*6ff6d951SJohn Birrell  */
814*6ff6d951SJohn Birrell int
815*6ff6d951SJohn Birrell dt_decl_type(dt_decl_t *ddp, dtrace_typeinfo_t *tip)
816*6ff6d951SJohn Birrell {
817*6ff6d951SJohn Birrell 	dtrace_hdl_t *dtp = yypcb->pcb_hdl;
818*6ff6d951SJohn Birrell 
819*6ff6d951SJohn Birrell 	dt_module_t *dmp;
820*6ff6d951SJohn Birrell 	ctf_arinfo_t r;
821*6ff6d951SJohn Birrell 	ctf_id_t type;
822*6ff6d951SJohn Birrell 
823*6ff6d951SJohn Birrell 	char n[DT_TYPE_NAMELEN];
824*6ff6d951SJohn Birrell 	uint_t flag;
825*6ff6d951SJohn Birrell 	char *name;
826*6ff6d951SJohn Birrell 	int rv;
827*6ff6d951SJohn Birrell 
828*6ff6d951SJohn Birrell 	/*
829*6ff6d951SJohn Birrell 	 * Based on our current #include depth and decl stack depth, determine
830*6ff6d951SJohn Birrell 	 * which dynamic CTF module and scope to use when adding any new types.
831*6ff6d951SJohn Birrell 	 */
832*6ff6d951SJohn Birrell 	dmp = yypcb->pcb_idepth ? dtp->dt_cdefs : dtp->dt_ddefs;
833*6ff6d951SJohn Birrell 	flag = yypcb->pcb_dstack.ds_next ? CTF_ADD_NONROOT : CTF_ADD_ROOT;
834*6ff6d951SJohn Birrell 
835*6ff6d951SJohn Birrell 	/*
836*6ff6d951SJohn Birrell 	 * If we have already cached a CTF type for this decl, then we just
837*6ff6d951SJohn Birrell 	 * return the type information for the cached type.
838*6ff6d951SJohn Birrell 	 */
839*6ff6d951SJohn Birrell 	if (ddp->dd_ctfp != NULL &&
840*6ff6d951SJohn Birrell 	    (dmp = dt_module_lookup_by_ctf(dtp, ddp->dd_ctfp)) != NULL) {
841*6ff6d951SJohn Birrell 		tip->dtt_object = dmp->dm_name;
842*6ff6d951SJohn Birrell 		tip->dtt_ctfp = ddp->dd_ctfp;
843*6ff6d951SJohn Birrell 		tip->dtt_type = ddp->dd_type;
844*6ff6d951SJohn Birrell 		return (0);
845*6ff6d951SJohn Birrell 	}
846*6ff6d951SJohn Birrell 
847*6ff6d951SJohn Birrell 	/*
848*6ff6d951SJohn Birrell 	 * Currently CTF treats all function pointers identically.  We cache a
849*6ff6d951SJohn Birrell 	 * representative ID of kind CTF_K_FUNCTION and just return that type.
850*6ff6d951SJohn Birrell 	 * If we want to support full function declarations, dd_next refers to
851*6ff6d951SJohn Birrell 	 * the declaration of the function return type, and the parameter list
852*6ff6d951SJohn Birrell 	 * should be parsed and hung off a new pointer inside of this decl.
853*6ff6d951SJohn Birrell 	 */
854*6ff6d951SJohn Birrell 	if (ddp->dd_kind == CTF_K_FUNCTION) {
855*6ff6d951SJohn Birrell 		tip->dtt_object = dtp->dt_ddefs->dm_name;
856*6ff6d951SJohn Birrell 		tip->dtt_ctfp = DT_FUNC_CTFP(dtp);
857*6ff6d951SJohn Birrell 		tip->dtt_type = DT_FUNC_TYPE(dtp);
858*6ff6d951SJohn Birrell 		return (0);
859*6ff6d951SJohn Birrell 	}
860*6ff6d951SJohn Birrell 
861*6ff6d951SJohn Birrell 	/*
862*6ff6d951SJohn Birrell 	 * If the decl is a pointer, resolve the rest of the stack by calling
863*6ff6d951SJohn Birrell 	 * dt_decl_type() recursively and then compute a pointer to the result.
864*6ff6d951SJohn Birrell 	 * Similar to the code above, we return a cached id for function ptrs.
865*6ff6d951SJohn Birrell 	 */
866*6ff6d951SJohn Birrell 	if (ddp->dd_kind == CTF_K_POINTER) {
867*6ff6d951SJohn Birrell 		if (ddp->dd_next->dd_kind == CTF_K_FUNCTION) {
868*6ff6d951SJohn Birrell 			tip->dtt_object = dtp->dt_ddefs->dm_name;
869*6ff6d951SJohn Birrell 			tip->dtt_ctfp = DT_FPTR_CTFP(dtp);
870*6ff6d951SJohn Birrell 			tip->dtt_type = DT_FPTR_TYPE(dtp);
871*6ff6d951SJohn Birrell 			return (0);
872*6ff6d951SJohn Birrell 		}
873*6ff6d951SJohn Birrell 
874*6ff6d951SJohn Birrell 		if ((rv = dt_decl_type(ddp->dd_next, tip)) == 0 &&
875*6ff6d951SJohn Birrell 		    (rv = dt_type_pointer(tip)) != 0) {
876*6ff6d951SJohn Birrell 			xywarn(D_UNKNOWN, "cannot find type: %s*: %s\n",
877*6ff6d951SJohn Birrell 			    dt_type_name(tip->dtt_ctfp, tip->dtt_type,
878*6ff6d951SJohn Birrell 			    n, sizeof (n)), ctf_errmsg(dtp->dt_ctferr));
879*6ff6d951SJohn Birrell 		}
880*6ff6d951SJohn Birrell 
881*6ff6d951SJohn Birrell 		return (rv);
882*6ff6d951SJohn Birrell 	}
883*6ff6d951SJohn Birrell 
884*6ff6d951SJohn Birrell 	/*
885*6ff6d951SJohn Birrell 	 * If the decl is an array, we must find the base type and then call
886*6ff6d951SJohn Birrell 	 * dt_decl_type() recursively and then build an array of the result.
887*6ff6d951SJohn Birrell 	 * The C and D multi-dimensional array syntax requires that consecutive
888*6ff6d951SJohn Birrell 	 * array declarations be processed from right-to-left (i.e. top-down
889*6ff6d951SJohn Birrell 	 * from the perspective of the declaration stack).  For example, an
890*6ff6d951SJohn Birrell 	 * array declaration such as int x[3][5] is stored on the stack as:
891*6ff6d951SJohn Birrell 	 *
892*6ff6d951SJohn Birrell 	 * (bottom) NULL <- ( INT "int" ) <- ( ARR [3] ) <- ( ARR [5] ) (top)
893*6ff6d951SJohn Birrell 	 *
894*6ff6d951SJohn Birrell 	 * but means that x is declared to be an array of 3 objects each of
895*6ff6d951SJohn Birrell 	 * which is an array of 5 integers, or in CTF representation:
896*6ff6d951SJohn Birrell 	 *
897*6ff6d951SJohn Birrell 	 * type T1:( content=int, nelems=5 ) type T2:( content=T1, nelems=3 )
898*6ff6d951SJohn Birrell 	 *
899*6ff6d951SJohn Birrell 	 * For more details, refer to K&R[5.7] and ISO C 6.5.2.1.  Rather than
900*6ff6d951SJohn Birrell 	 * overcomplicate the implementation of dt_decl_type(), we push array
901*6ff6d951SJohn Birrell 	 * declarations down into the stack in dt_decl_array(), above, so that
902*6ff6d951SJohn Birrell 	 * by the time dt_decl_type() is called, the decl stack looks like:
903*6ff6d951SJohn Birrell 	 *
904*6ff6d951SJohn Birrell 	 * (bottom) NULL <- ( INT "int" ) <- ( ARR [5] ) <- ( ARR [3] ) (top)
905*6ff6d951SJohn Birrell 	 *
906*6ff6d951SJohn Birrell 	 * which permits a straightforward recursive descent of the decl stack
907*6ff6d951SJohn Birrell 	 * to build the corresponding CTF type tree in the appropriate order.
908*6ff6d951SJohn Birrell 	 */
909*6ff6d951SJohn Birrell 	if (ddp->dd_kind == CTF_K_ARRAY) {
910*6ff6d951SJohn Birrell 		/*
911*6ff6d951SJohn Birrell 		 * If the array decl has a parameter list associated with it,
912*6ff6d951SJohn Birrell 		 * this is an associative array declaration: return <DYN>.
913*6ff6d951SJohn Birrell 		 */
914*6ff6d951SJohn Birrell 		if (ddp->dd_node != NULL &&
915*6ff6d951SJohn Birrell 		    ddp->dd_node->dn_kind == DT_NODE_TYPE) {
916*6ff6d951SJohn Birrell 			tip->dtt_object = dtp->dt_ddefs->dm_name;
917*6ff6d951SJohn Birrell 			tip->dtt_ctfp = DT_DYN_CTFP(dtp);
918*6ff6d951SJohn Birrell 			tip->dtt_type = DT_DYN_TYPE(dtp);
919*6ff6d951SJohn Birrell 			return (0);
920*6ff6d951SJohn Birrell 		}
921*6ff6d951SJohn Birrell 
922*6ff6d951SJohn Birrell 		if ((rv = dt_decl_type(ddp->dd_next, tip)) != 0)
923*6ff6d951SJohn Birrell 			return (rv);
924*6ff6d951SJohn Birrell 
925*6ff6d951SJohn Birrell 		/*
926*6ff6d951SJohn Birrell 		 * If the array base type is not defined in the target
927*6ff6d951SJohn Birrell 		 * container or its parent, copy the type to the target
928*6ff6d951SJohn Birrell 		 * container and reset dtt_ctfp and dtt_type to the copy.
929*6ff6d951SJohn Birrell 		 */
930*6ff6d951SJohn Birrell 		if (tip->dtt_ctfp != dmp->dm_ctfp &&
931*6ff6d951SJohn Birrell 		    tip->dtt_ctfp != ctf_parent_file(dmp->dm_ctfp)) {
932*6ff6d951SJohn Birrell 
933*6ff6d951SJohn Birrell 			tip->dtt_type = ctf_add_type(dmp->dm_ctfp,
934*6ff6d951SJohn Birrell 			    tip->dtt_ctfp, tip->dtt_type);
935*6ff6d951SJohn Birrell 			tip->dtt_ctfp = dmp->dm_ctfp;
936*6ff6d951SJohn Birrell 
937*6ff6d951SJohn Birrell 			if (tip->dtt_type == CTF_ERR ||
938*6ff6d951SJohn Birrell 			    ctf_update(tip->dtt_ctfp) == CTF_ERR) {
939*6ff6d951SJohn Birrell 				xywarn(D_UNKNOWN, "failed to copy type: %s\n",
940*6ff6d951SJohn Birrell 				    ctf_errmsg(ctf_errno(tip->dtt_ctfp)));
941*6ff6d951SJohn Birrell 				return (-1);
942*6ff6d951SJohn Birrell 			}
943*6ff6d951SJohn Birrell 		}
944*6ff6d951SJohn Birrell 
945*6ff6d951SJohn Birrell 		/*
946*6ff6d951SJohn Birrell 		 * The array index type is irrelevant in C and D: just set it
947*6ff6d951SJohn Birrell 		 * to "long" for all array types that we create on-the-fly.
948*6ff6d951SJohn Birrell 		 */
949*6ff6d951SJohn Birrell 		r.ctr_contents = tip->dtt_type;
950*6ff6d951SJohn Birrell 		r.ctr_index = ctf_lookup_by_name(tip->dtt_ctfp, "long");
951*6ff6d951SJohn Birrell 		r.ctr_nelems = ddp->dd_node ?
952*6ff6d951SJohn Birrell 		    (uint_t)ddp->dd_node->dn_value : 0;
953*6ff6d951SJohn Birrell 
954*6ff6d951SJohn Birrell 		tip->dtt_object = dmp->dm_name;
955*6ff6d951SJohn Birrell 		tip->dtt_ctfp = dmp->dm_ctfp;
956*6ff6d951SJohn Birrell 		tip->dtt_type = ctf_add_array(dmp->dm_ctfp, CTF_ADD_ROOT, &r);
957*6ff6d951SJohn Birrell 
958*6ff6d951SJohn Birrell 		if (tip->dtt_type == CTF_ERR ||
959*6ff6d951SJohn Birrell 		    ctf_update(tip->dtt_ctfp) == CTF_ERR) {
960*6ff6d951SJohn Birrell 			xywarn(D_UNKNOWN, "failed to create array type: %s\n",
961*6ff6d951SJohn Birrell 			    ctf_errmsg(ctf_errno(tip->dtt_ctfp)));
962*6ff6d951SJohn Birrell 			return (-1);
963*6ff6d951SJohn Birrell 		}
964*6ff6d951SJohn Birrell 
965*6ff6d951SJohn Birrell 		return (0);
966*6ff6d951SJohn Birrell 	}
967*6ff6d951SJohn Birrell 
968*6ff6d951SJohn Birrell 	/*
969*6ff6d951SJohn Birrell 	 * Allocate space for the type name and enough space for the maximum
970*6ff6d951SJohn Birrell 	 * additional text ("unsigned long long \0" requires 20 more bytes).
971*6ff6d951SJohn Birrell 	 */
972*6ff6d951SJohn Birrell 	name = alloca(ddp->dd_name ? strlen(ddp->dd_name) + 20 : 20);
973*6ff6d951SJohn Birrell 	name[0] = '\0';
974*6ff6d951SJohn Birrell 
975*6ff6d951SJohn Birrell 	switch (ddp->dd_kind) {
976*6ff6d951SJohn Birrell 	case CTF_K_INTEGER:
977*6ff6d951SJohn Birrell 	case CTF_K_FLOAT:
978*6ff6d951SJohn Birrell 		if (ddp->dd_attr & DT_DA_SIGNED)
979*6ff6d951SJohn Birrell 			(void) strcat(name, "signed ");
980*6ff6d951SJohn Birrell 		if (ddp->dd_attr & DT_DA_UNSIGNED)
981*6ff6d951SJohn Birrell 			(void) strcat(name, "unsigned ");
982*6ff6d951SJohn Birrell 		if (ddp->dd_attr & DT_DA_SHORT)
983*6ff6d951SJohn Birrell 			(void) strcat(name, "short ");
984*6ff6d951SJohn Birrell 		if (ddp->dd_attr & DT_DA_LONG)
985*6ff6d951SJohn Birrell 			(void) strcat(name, "long ");
986*6ff6d951SJohn Birrell 		if (ddp->dd_attr & DT_DA_LONGLONG)
987*6ff6d951SJohn Birrell 			(void) strcat(name, "long long ");
988*6ff6d951SJohn Birrell 		if (ddp->dd_attr == 0 && ddp->dd_name == NULL)
989*6ff6d951SJohn Birrell 			(void) strcat(name, "int");
990*6ff6d951SJohn Birrell 		break;
991*6ff6d951SJohn Birrell 	case CTF_K_STRUCT:
992*6ff6d951SJohn Birrell 		(void) strcpy(name, "struct ");
993*6ff6d951SJohn Birrell 		break;
994*6ff6d951SJohn Birrell 	case CTF_K_UNION:
995*6ff6d951SJohn Birrell 		(void) strcpy(name, "union ");
996*6ff6d951SJohn Birrell 		break;
997*6ff6d951SJohn Birrell 	case CTF_K_ENUM:
998*6ff6d951SJohn Birrell 		(void) strcpy(name, "enum ");
999*6ff6d951SJohn Birrell 		break;
1000*6ff6d951SJohn Birrell 	case CTF_K_TYPEDEF:
1001*6ff6d951SJohn Birrell 		break;
1002*6ff6d951SJohn Birrell 	default:
1003*6ff6d951SJohn Birrell 		xywarn(D_UNKNOWN, "internal error -- "
1004*6ff6d951SJohn Birrell 		    "bad decl kind %u\n", ddp->dd_kind);
1005*6ff6d951SJohn Birrell 		return (-1);
1006*6ff6d951SJohn Birrell 	}
1007*6ff6d951SJohn Birrell 
1008*6ff6d951SJohn Birrell 	/*
1009*6ff6d951SJohn Birrell 	 * Add dd_name unless a short, long, or long long is explicitly
1010*6ff6d951SJohn Birrell 	 * suffixed by int.  We use the C/CTF canonical names for integers.
1011*6ff6d951SJohn Birrell 	 */
1012*6ff6d951SJohn Birrell 	if (ddp->dd_name != NULL && (ddp->dd_kind != CTF_K_INTEGER ||
1013*6ff6d951SJohn Birrell 	    (ddp->dd_attr & (DT_DA_SHORT | DT_DA_LONG | DT_DA_LONGLONG)) == 0))
1014*6ff6d951SJohn Birrell 		(void) strcat(name, ddp->dd_name);
1015*6ff6d951SJohn Birrell 
1016*6ff6d951SJohn Birrell 	/*
1017*6ff6d951SJohn Birrell 	 * Lookup the type.  If we find it, we're done.  Otherwise create a
1018*6ff6d951SJohn Birrell 	 * forward tag for the type if it is a struct, union, or enum.  If
1019*6ff6d951SJohn Birrell 	 * we can't find it and we can't create a tag, return failure.
1020*6ff6d951SJohn Birrell 	 */
1021*6ff6d951SJohn Birrell 	if ((rv = dt_type_lookup(name, tip)) == 0)
1022*6ff6d951SJohn Birrell 		return (rv);
1023*6ff6d951SJohn Birrell 
1024*6ff6d951SJohn Birrell 	switch (ddp->dd_kind) {
1025*6ff6d951SJohn Birrell 	case CTF_K_STRUCT:
1026*6ff6d951SJohn Birrell 	case CTF_K_UNION:
1027*6ff6d951SJohn Birrell 	case CTF_K_ENUM:
1028*6ff6d951SJohn Birrell 		type = ctf_add_forward(dmp->dm_ctfp, flag,
1029*6ff6d951SJohn Birrell 		    ddp->dd_name, ddp->dd_kind);
1030*6ff6d951SJohn Birrell 		break;
1031*6ff6d951SJohn Birrell 	default:
1032*6ff6d951SJohn Birrell 		xywarn(D_UNKNOWN, "failed to resolve type %s: %s\n", name,
1033*6ff6d951SJohn Birrell 		    dtrace_errmsg(dtp, dtrace_errno(dtp)));
1034*6ff6d951SJohn Birrell 		return (rv);
1035*6ff6d951SJohn Birrell 	}
1036*6ff6d951SJohn Birrell 
1037*6ff6d951SJohn Birrell 	if (type == CTF_ERR || ctf_update(dmp->dm_ctfp) == CTF_ERR) {
1038*6ff6d951SJohn Birrell 		xywarn(D_UNKNOWN, "failed to add forward tag for %s: %s\n",
1039*6ff6d951SJohn Birrell 		    name, ctf_errmsg(ctf_errno(dmp->dm_ctfp)));
1040*6ff6d951SJohn Birrell 		return (-1);
1041*6ff6d951SJohn Birrell 	}
1042*6ff6d951SJohn Birrell 
1043*6ff6d951SJohn Birrell 	ddp->dd_ctfp = dmp->dm_ctfp;
1044*6ff6d951SJohn Birrell 	ddp->dd_type = type;
1045*6ff6d951SJohn Birrell 
1046*6ff6d951SJohn Birrell 	tip->dtt_object = dmp->dm_name;
1047*6ff6d951SJohn Birrell 	tip->dtt_ctfp = dmp->dm_ctfp;
1048*6ff6d951SJohn Birrell 	tip->dtt_type = type;
1049*6ff6d951SJohn Birrell 
1050*6ff6d951SJohn Birrell 	return (0);
1051*6ff6d951SJohn Birrell }
1052*6ff6d951SJohn Birrell 
1053*6ff6d951SJohn Birrell void
1054*6ff6d951SJohn Birrell dt_scope_create(dt_scope_t *dsp)
1055*6ff6d951SJohn Birrell {
1056*6ff6d951SJohn Birrell 	dsp->ds_decl = NULL;
1057*6ff6d951SJohn Birrell 	dsp->ds_next = NULL;
1058*6ff6d951SJohn Birrell 	dsp->ds_ident = NULL;
1059*6ff6d951SJohn Birrell 	dsp->ds_ctfp = NULL;
1060*6ff6d951SJohn Birrell 	dsp->ds_type = CTF_ERR;
1061*6ff6d951SJohn Birrell 	dsp->ds_class = DT_DC_DEFAULT;
1062*6ff6d951SJohn Birrell 	dsp->ds_enumval = -1;
1063*6ff6d951SJohn Birrell }
1064*6ff6d951SJohn Birrell 
1065*6ff6d951SJohn Birrell void
1066*6ff6d951SJohn Birrell dt_scope_destroy(dt_scope_t *dsp)
1067*6ff6d951SJohn Birrell {
1068*6ff6d951SJohn Birrell 	dt_scope_t *nsp;
1069*6ff6d951SJohn Birrell 
1070*6ff6d951SJohn Birrell 	for (; dsp != NULL; dsp = nsp) {
1071*6ff6d951SJohn Birrell 		dt_decl_free(dsp->ds_decl);
1072*6ff6d951SJohn Birrell 		free(dsp->ds_ident);
1073*6ff6d951SJohn Birrell 		nsp = dsp->ds_next;
1074*6ff6d951SJohn Birrell 		if (dsp != &yypcb->pcb_dstack)
1075*6ff6d951SJohn Birrell 			free(dsp);
1076*6ff6d951SJohn Birrell 	}
1077*6ff6d951SJohn Birrell }
1078*6ff6d951SJohn Birrell 
1079*6ff6d951SJohn Birrell void
1080*6ff6d951SJohn Birrell dt_scope_push(ctf_file_t *ctfp, ctf_id_t type)
1081*6ff6d951SJohn Birrell {
1082*6ff6d951SJohn Birrell 	dt_scope_t *rsp = &yypcb->pcb_dstack;
1083*6ff6d951SJohn Birrell 	dt_scope_t *dsp = malloc(sizeof (dt_scope_t));
1084*6ff6d951SJohn Birrell 
1085*6ff6d951SJohn Birrell 	if (dsp == NULL)
1086*6ff6d951SJohn Birrell 		longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
1087*6ff6d951SJohn Birrell 
1088*6ff6d951SJohn Birrell 	dsp->ds_decl = rsp->ds_decl;
1089*6ff6d951SJohn Birrell 	dsp->ds_next = rsp->ds_next;
1090*6ff6d951SJohn Birrell 	dsp->ds_ident = rsp->ds_ident;
1091*6ff6d951SJohn Birrell 	dsp->ds_ctfp = ctfp;
1092*6ff6d951SJohn Birrell 	dsp->ds_type = type;
1093*6ff6d951SJohn Birrell 	dsp->ds_class = rsp->ds_class;
1094*6ff6d951SJohn Birrell 	dsp->ds_enumval = rsp->ds_enumval;
1095*6ff6d951SJohn Birrell 
1096*6ff6d951SJohn Birrell 	dt_scope_create(rsp);
1097*6ff6d951SJohn Birrell 	rsp->ds_next = dsp;
1098*6ff6d951SJohn Birrell }
1099*6ff6d951SJohn Birrell 
1100*6ff6d951SJohn Birrell dt_decl_t *
1101*6ff6d951SJohn Birrell dt_scope_pop(void)
1102*6ff6d951SJohn Birrell {
1103*6ff6d951SJohn Birrell 	dt_scope_t *rsp = &yypcb->pcb_dstack;
1104*6ff6d951SJohn Birrell 	dt_scope_t *dsp = rsp->ds_next;
1105*6ff6d951SJohn Birrell 
1106*6ff6d951SJohn Birrell 	if (dsp == NULL)
1107*6ff6d951SJohn Birrell 		longjmp(yypcb->pcb_jmpbuf, EDT_NOSCOPE);
1108*6ff6d951SJohn Birrell 
1109*6ff6d951SJohn Birrell 	if (dsp->ds_ctfp != NULL && ctf_update(dsp->ds_ctfp) == CTF_ERR) {
1110*6ff6d951SJohn Birrell 		xyerror(D_UNKNOWN, "failed to update type definitions: %s\n",
1111*6ff6d951SJohn Birrell 		    ctf_errmsg(ctf_errno(dsp->ds_ctfp)));
1112*6ff6d951SJohn Birrell 	}
1113*6ff6d951SJohn Birrell 
1114*6ff6d951SJohn Birrell 	dt_decl_free(rsp->ds_decl);
1115*6ff6d951SJohn Birrell 	free(rsp->ds_ident);
1116*6ff6d951SJohn Birrell 
1117*6ff6d951SJohn Birrell 	rsp->ds_decl = dsp->ds_decl;
1118*6ff6d951SJohn Birrell 	rsp->ds_next = dsp->ds_next;
1119*6ff6d951SJohn Birrell 	rsp->ds_ident = dsp->ds_ident;
1120*6ff6d951SJohn Birrell 	rsp->ds_ctfp = dsp->ds_ctfp;
1121*6ff6d951SJohn Birrell 	rsp->ds_type = dsp->ds_type;
1122*6ff6d951SJohn Birrell 	rsp->ds_class = dsp->ds_class;
1123*6ff6d951SJohn Birrell 	rsp->ds_enumval = dsp->ds_enumval;
1124*6ff6d951SJohn Birrell 
1125*6ff6d951SJohn Birrell 	free(dsp);
1126*6ff6d951SJohn Birrell 	return (rsp->ds_decl);
1127*6ff6d951SJohn Birrell }
1128