1178479Sjb/*
2178479Sjb * CDDL HEADER START
3178479Sjb *
4178479Sjb * The contents of this file are subject to the terms of the
5178479Sjb * Common Development and Distribution License, Version 1.0 only
6178479Sjb * (the "License").  You may not use this file except in compliance
7178479Sjb * with the License.
8178479Sjb *
9178479Sjb * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10178479Sjb * or http://www.opensolaris.org/os/licensing.
11178479Sjb * See the License for the specific language governing permissions
12178479Sjb * and limitations under the License.
13178479Sjb *
14178479Sjb * When distributing Covered Code, include this CDDL HEADER in each
15178479Sjb * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16178479Sjb * If applicable, add the following below this CDDL HEADER, with the
17178479Sjb * fields enclosed by brackets "[]" replaced with your own identifying
18178479Sjb * information: Portions Copyright [yyyy] [name of copyright owner]
19178479Sjb *
20178479Sjb * CDDL HEADER END
21178479Sjb */
22178479Sjb/*
23178479Sjb * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24267941Srpaulo * Copyright (c) 2013 by Delphix. All rights reserved.
25267941Srpaulo * Copyright (c) 2013 Joyent, Inc. All rights reserved.
26178479Sjb * Use is subject to license terms.
27178479Sjb */
28178479Sjb
29178479Sjb#pragma ident	"%Z%%M%	%I%	%E% SMI"
30178479Sjb
31178479Sjb#include <strings.h>
32178479Sjb#include <stdlib.h>
33178479Sjb#include <limits.h>
34178479Sjb#include <alloca.h>
35178479Sjb#include <assert.h>
36178479Sjb
37178479Sjb#include <dt_decl.h>
38178479Sjb#include <dt_parser.h>
39178479Sjb#include <dt_module.h>
40178479Sjb#include <dt_impl.h>
41178479Sjb
42178479Sjbstatic dt_decl_t *
43178479Sjbdt_decl_check(dt_decl_t *ddp)
44178479Sjb{
45178479Sjb	if (ddp->dd_kind == CTF_K_UNKNOWN)
46178479Sjb		return (ddp); /* nothing to check if the type is not yet set */
47178479Sjb
48178479Sjb	if (ddp->dd_name != NULL && strcmp(ddp->dd_name, "char") == 0 &&
49178479Sjb	    (ddp->dd_attr & (DT_DA_SHORT | DT_DA_LONG | DT_DA_LONGLONG))) {
50178479Sjb		xyerror(D_DECL_CHARATTR, "invalid type declaration: short and "
51178479Sjb		    "long may not be used with char type\n");
52178479Sjb	}
53178479Sjb
54178479Sjb	if (ddp->dd_name != NULL && strcmp(ddp->dd_name, "void") == 0 &&
55178479Sjb	    (ddp->dd_attr & (DT_DA_SHORT | DT_DA_LONG | DT_DA_LONGLONG |
56178479Sjb	    (DT_DA_SIGNED | DT_DA_UNSIGNED)))) {
57178479Sjb		xyerror(D_DECL_VOIDATTR, "invalid type declaration: attributes "
58178479Sjb		    "may not be used with void type\n");
59178479Sjb	}
60178479Sjb
61178479Sjb	if (ddp->dd_kind != CTF_K_INTEGER &&
62178479Sjb	    (ddp->dd_attr & (DT_DA_SIGNED | DT_DA_UNSIGNED))) {
63178479Sjb		xyerror(D_DECL_SIGNINT, "invalid type declaration: signed and "
64178479Sjb		    "unsigned may only be used with integer type\n");
65178479Sjb	}
66178479Sjb
67178479Sjb	if (ddp->dd_kind != CTF_K_INTEGER && ddp->dd_kind != CTF_K_FLOAT &&
68178479Sjb	    (ddp->dd_attr & (DT_DA_LONG | DT_DA_LONGLONG))) {
69178479Sjb		xyerror(D_DECL_LONGINT, "invalid type declaration: long and "
70178479Sjb		    "long long may only be used with integer or "
71178479Sjb		    "floating-point type\n");
72178479Sjb	}
73178479Sjb
74178479Sjb	return (ddp);
75178479Sjb}
76178479Sjb
77178479Sjbdt_decl_t *
78178479Sjbdt_decl_alloc(ushort_t kind, char *name)
79178479Sjb{
80178479Sjb	dt_decl_t *ddp = malloc(sizeof (dt_decl_t));
81178479Sjb
82178479Sjb	if (ddp == NULL)
83178479Sjb		longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
84178479Sjb
85178479Sjb	ddp->dd_kind = kind;
86178479Sjb	ddp->dd_attr = 0;
87178479Sjb	ddp->dd_ctfp = NULL;
88178479Sjb	ddp->dd_type = CTF_ERR;
89178479Sjb	ddp->dd_name = name;
90178479Sjb	ddp->dd_node = NULL;
91178479Sjb	ddp->dd_next = NULL;
92178479Sjb
93178479Sjb	return (ddp);
94178479Sjb}
95178479Sjb
96178479Sjbvoid
97178479Sjbdt_decl_free(dt_decl_t *ddp)
98178479Sjb{
99178479Sjb	dt_decl_t *ndp;
100178479Sjb
101178479Sjb	for (; ddp != NULL; ddp = ndp) {
102178479Sjb		ndp = ddp->dd_next;
103178479Sjb		free(ddp->dd_name);
104178479Sjb		dt_node_list_free(&ddp->dd_node);
105178479Sjb		free(ddp);
106178479Sjb	}
107178479Sjb}
108178479Sjb
109178479Sjbvoid
110178479Sjbdt_decl_reset(void)
111178479Sjb{
112178479Sjb	dt_scope_t *dsp = &yypcb->pcb_dstack;
113178479Sjb	dt_decl_t *ddp = dsp->ds_decl;
114178479Sjb
115178479Sjb	while (ddp->dd_next != NULL) {
116178479Sjb		dsp->ds_decl = ddp->dd_next;
117178479Sjb		ddp->dd_next = NULL;
118178479Sjb		dt_decl_free(ddp);
119178479Sjb		ddp = dsp->ds_decl;
120178479Sjb	}
121178479Sjb}
122178479Sjb
123178479Sjbdt_decl_t *
124178479Sjbdt_decl_push(dt_decl_t *ddp)
125178479Sjb{
126178479Sjb	dt_scope_t *dsp = &yypcb->pcb_dstack;
127178479Sjb	dt_decl_t *top = dsp->ds_decl;
128178479Sjb
129178479Sjb	if (top != NULL &&
130178479Sjb	    top->dd_kind == CTF_K_UNKNOWN && top->dd_name == NULL) {
131178479Sjb		top->dd_kind = CTF_K_INTEGER;
132178479Sjb		(void) dt_decl_check(top);
133178479Sjb	}
134178479Sjb
135178479Sjb	assert(ddp->dd_next == NULL);
136178479Sjb	ddp->dd_next = top;
137178479Sjb	dsp->ds_decl = ddp;
138178479Sjb
139178479Sjb	return (ddp);
140178479Sjb}
141178479Sjb
142178479Sjbdt_decl_t *
143178479Sjbdt_decl_pop(void)
144178479Sjb{
145178479Sjb	dt_scope_t *dsp = &yypcb->pcb_dstack;
146178479Sjb	dt_decl_t *ddp = dt_decl_top();
147178479Sjb
148178479Sjb	dsp->ds_decl = NULL;
149178479Sjb	free(dsp->ds_ident);
150178479Sjb	dsp->ds_ident = NULL;
151178479Sjb	dsp->ds_ctfp = NULL;
152178479Sjb	dsp->ds_type = CTF_ERR;
153178479Sjb	dsp->ds_class = DT_DC_DEFAULT;
154178479Sjb	dsp->ds_enumval = -1;
155178479Sjb
156178479Sjb	return (ddp);
157178479Sjb}
158178479Sjb
159178479Sjbdt_decl_t *
160178479Sjbdt_decl_pop_param(char **idp)
161178479Sjb{
162178479Sjb	dt_scope_t *dsp = &yypcb->pcb_dstack;
163178479Sjb
164178479Sjb	if (dsp->ds_class != DT_DC_DEFAULT && dsp->ds_class != DT_DC_REGISTER) {
165178479Sjb		xyerror(D_DECL_PARMCLASS, "inappropriate storage class "
166178479Sjb		    "for function or associative array parameter\n");
167178479Sjb	}
168178479Sjb
169178479Sjb	if (idp != NULL && dt_decl_top() != NULL) {
170178479Sjb		*idp = dsp->ds_ident;
171178479Sjb		dsp->ds_ident = NULL;
172178479Sjb	}
173178479Sjb
174178479Sjb	return (dt_decl_pop());
175178479Sjb}
176178479Sjb
177178479Sjbdt_decl_t *
178178479Sjbdt_decl_top(void)
179178479Sjb{
180178479Sjb	dt_decl_t *ddp = yypcb->pcb_dstack.ds_decl;
181178479Sjb
182178479Sjb	if (ddp == NULL)
183178479Sjb		longjmp(yypcb->pcb_jmpbuf, EDT_NODECL);
184178479Sjb
185178479Sjb	if (ddp->dd_kind == CTF_K_UNKNOWN && ddp->dd_name == NULL) {
186178479Sjb		ddp->dd_kind = CTF_K_INTEGER;
187178479Sjb		(void) dt_decl_check(ddp);
188178479Sjb	}
189178479Sjb
190178479Sjb	return (ddp);
191178479Sjb}
192178479Sjb
193178479Sjbdt_decl_t *
194178479Sjbdt_decl_ident(char *name)
195178479Sjb{
196178479Sjb	dt_scope_t *dsp = &yypcb->pcb_dstack;
197178479Sjb	dt_decl_t *ddp = dsp->ds_decl;
198178479Sjb
199178479Sjb	if (dsp->ds_ident != NULL) {
200178479Sjb		free(name);
201178479Sjb		xyerror(D_DECL_IDENT, "old-style declaration or "
202178479Sjb		    "incorrect type specified\n");
203178479Sjb	}
204178479Sjb
205178479Sjb	dsp->ds_ident = name;
206178479Sjb
207178479Sjb	if (ddp == NULL)
208178479Sjb		ddp = dt_decl_push(dt_decl_alloc(CTF_K_UNKNOWN, NULL));
209178479Sjb
210178479Sjb	return (ddp);
211178479Sjb}
212178479Sjb
213178479Sjbvoid
214178479Sjbdt_decl_class(dt_dclass_t class)
215178479Sjb{
216178479Sjb	dt_scope_t *dsp = &yypcb->pcb_dstack;
217178479Sjb
218178479Sjb	if (dsp->ds_class != DT_DC_DEFAULT) {
219178479Sjb		xyerror(D_DECL_CLASS, "only one storage class allowed "
220178479Sjb		    "in a declaration\n");
221178479Sjb	}
222178479Sjb
223178479Sjb	dsp->ds_class = class;
224178479Sjb}
225178479Sjb
226178479Sjb/*
227178479Sjb * Set the kind and name of the current declaration.  If none is allocated,
228178479Sjb * make a new decl and push it on to the top of our stack.  If the name or kind
229178479Sjb * is already set for the current decl, then we need to fail this declaration.
230178479Sjb * This can occur because too many types were given (e.g. "int int"), etc.
231178479Sjb */
232178479Sjbdt_decl_t *
233178479Sjbdt_decl_spec(ushort_t kind, char *name)
234178479Sjb{
235178479Sjb	dt_decl_t *ddp = yypcb->pcb_dstack.ds_decl;
236178479Sjb
237178479Sjb	if (ddp == NULL)
238178479Sjb		return (dt_decl_push(dt_decl_alloc(kind, name)));
239178479Sjb
240178479Sjb	/*
241178479Sjb	 * If we already have a type name specified and we see another type
242178479Sjb	 * name, this is an error if the declaration is a typedef.  If the
243178479Sjb	 * declaration is not a typedef, then the user may be trying to declare
244178479Sjb	 * a variable whose name has been returned by lex as a TNAME token:
245178479Sjb	 * call dt_decl_ident() as if the grammar's IDENT rule was matched.
246178479Sjb	 */
247178479Sjb	if (ddp->dd_name != NULL && kind == CTF_K_TYPEDEF) {
248178479Sjb		if (yypcb->pcb_dstack.ds_class != DT_DC_TYPEDEF)
249178479Sjb			return (dt_decl_ident(name));
250178479Sjb		xyerror(D_DECL_IDRED, "identifier redeclared: %s\n", name);
251178479Sjb	}
252178479Sjb
253178479Sjb	if (ddp->dd_name != NULL || ddp->dd_kind != CTF_K_UNKNOWN)
254178479Sjb		xyerror(D_DECL_COMBO, "invalid type combination\n");
255178479Sjb
256178479Sjb	ddp->dd_kind = kind;
257178479Sjb	ddp->dd_name = name;
258178479Sjb
259178479Sjb	return (dt_decl_check(ddp));
260178479Sjb}
261178479Sjb
262178479Sjbdt_decl_t *
263178479Sjbdt_decl_attr(ushort_t attr)
264178479Sjb{
265178479Sjb	dt_decl_t *ddp = yypcb->pcb_dstack.ds_decl;
266178479Sjb
267178479Sjb	if (ddp == NULL) {
268178479Sjb		ddp = dt_decl_push(dt_decl_alloc(CTF_K_UNKNOWN, NULL));
269178479Sjb		ddp->dd_attr = attr;
270178479Sjb		return (ddp);
271178479Sjb	}
272178479Sjb
273178479Sjb	if (attr == DT_DA_LONG && (ddp->dd_attr & DT_DA_LONG)) {
274178479Sjb		ddp->dd_attr &= ~DT_DA_LONG;
275178479Sjb		attr = DT_DA_LONGLONG;
276178479Sjb	}
277178479Sjb
278178479Sjb	ddp->dd_attr |= attr;
279178479Sjb	return (dt_decl_check(ddp));
280178479Sjb}
281178479Sjb
282178479Sjb/*
283178479Sjb * Examine the list of formal parameters 'flist' and determine if the formal
284178479Sjb * name fnp->dn_string is defined in this list (B_TRUE) or not (B_FALSE).
285178479Sjb * If 'fnp' is in 'flist', do not search beyond 'fnp' itself in 'flist'.
286178479Sjb */
287178479Sjbstatic int
288178479Sjbdt_decl_protoform(dt_node_t *fnp, dt_node_t *flist)
289178479Sjb{
290178479Sjb	dt_node_t *dnp;
291178479Sjb
292178479Sjb	for (dnp = flist; dnp != fnp && dnp != NULL; dnp = dnp->dn_list) {
293178479Sjb		if (dnp->dn_string != NULL &&
294178479Sjb		    strcmp(dnp->dn_string, fnp->dn_string) == 0)
295178479Sjb			return (B_TRUE);
296178479Sjb	}
297178479Sjb
298178479Sjb	return (B_FALSE);
299178479Sjb}
300178479Sjb
301178479Sjb/*
302178479Sjb * Common code for parsing array, function, and probe definition prototypes.
303178479Sjb * The prototype node list is specified as 'plist'.  The formal prototype
304178479Sjb * against which to compare the prototype is specified as 'flist'.  If plist
305178479Sjb * and flist are the same, we require that named parameters are unique.  If
306178479Sjb * plist and flist are different, we require that named parameters in plist
307178479Sjb * match a name that is present in flist.
308178479Sjb */
309178479Sjbint
310178479Sjbdt_decl_prototype(dt_node_t *plist,
311178479Sjb    dt_node_t *flist, const char *kind, uint_t flags)
312178479Sjb{
313178479Sjb	char n[DT_TYPE_NAMELEN];
314178479Sjb	int is_void, v = 0, i = 1;
315178479Sjb	int form = plist != flist;
316178479Sjb	dt_node_t *dnp;
317178479Sjb
318178479Sjb	for (dnp = plist; dnp != NULL; dnp = dnp->dn_list, i++) {
319178479Sjb
320178479Sjb		if (dnp->dn_type == CTF_ERR && !(flags & DT_DP_VARARGS)) {
321178479Sjb			dnerror(dnp, D_DECL_PROTO_VARARGS, "%s prototype may "
322178479Sjb			    "not use a variable-length argument list\n", kind);
323178479Sjb		}
324178479Sjb
325178479Sjb		if (dt_node_is_dynamic(dnp) && !(flags & DT_DP_DYNAMIC)) {
326178479Sjb			dnerror(dnp, D_DECL_PROTO_TYPE, "%s prototype may not "
327178479Sjb			    "use parameter of type %s: %s, parameter #%d\n",
328178479Sjb			    kind, dt_node_type_name(dnp, n, sizeof (n)),
329178479Sjb			    dnp->dn_string ? dnp->dn_string : "(anonymous)", i);
330178479Sjb		}
331178479Sjb
332178479Sjb		is_void = dt_node_is_void(dnp);
333178479Sjb		v += is_void;
334178479Sjb
335178479Sjb		if (is_void && !(flags & DT_DP_VOID)) {
336178479Sjb			dnerror(dnp, D_DECL_PROTO_TYPE, "%s prototype may not "
337178479Sjb			    "use parameter of type %s: %s, parameter #%d\n",
338178479Sjb			    kind, dt_node_type_name(dnp, n, sizeof (n)),
339178479Sjb			    dnp->dn_string ? dnp->dn_string : "(anonymous)", i);
340178479Sjb		}
341178479Sjb
342178479Sjb		if (is_void && dnp->dn_string != NULL) {
343178479Sjb			dnerror(dnp, D_DECL_PROTO_NAME, "void parameter may "
344178479Sjb			    "not have a name: %s\n", dnp->dn_string);
345178479Sjb		}
346178479Sjb
347178479Sjb		if (dnp->dn_string != NULL &&
348178479Sjb		    dt_decl_protoform(dnp, flist) != form) {
349178479Sjb			dnerror(dnp, D_DECL_PROTO_FORM, "parameter is "
350178479Sjb			    "%s declared in %s prototype: %s, parameter #%d\n",
351178479Sjb			    form ? "not" : "already", kind, dnp->dn_string, i);
352178479Sjb		}
353178479Sjb
354178479Sjb		if (dnp->dn_string == NULL &&
355178479Sjb		    !is_void && !(flags & DT_DP_ANON)) {
356178479Sjb			dnerror(dnp, D_DECL_PROTO_NAME, "parameter declaration "
357178479Sjb			    "requires a name: parameter #%d\n", i);
358178479Sjb		}
359178479Sjb	}
360178479Sjb
361178479Sjb	if (v != 0 && plist->dn_list != NULL)
362178479Sjb		xyerror(D_DECL_PROTO_VOID, "void must be sole parameter\n");
363178479Sjb
364178479Sjb	return (v ? 0 : i - 1); /* return zero if sole parameter is 'void' */
365178479Sjb}
366178479Sjb
367178479Sjbdt_decl_t *
368178479Sjbdt_decl_array(dt_node_t *dnp)
369178479Sjb{
370178479Sjb	dt_decl_t *ddp = dt_decl_push(dt_decl_alloc(CTF_K_ARRAY, NULL));
371178479Sjb	dt_scope_t *dsp = &yypcb->pcb_dstack;
372178479Sjb	dt_decl_t *ndp = ddp;
373178479Sjb
374178479Sjb	/*
375178479Sjb	 * After pushing the array on to the decl stack, scan ahead for multi-
376178479Sjb	 * dimensional array declarations and push the current decl to the
377178479Sjb	 * bottom to match the resulting CTF type tree and data layout.  Refer
378178479Sjb	 * to the comments in dt_decl_type() and ISO C 6.5.2.1 for more info.
379178479Sjb	 */
380178479Sjb	while (ndp->dd_next != NULL && ndp->dd_next->dd_kind == CTF_K_ARRAY)
381178479Sjb		ndp = ndp->dd_next; /* skip to bottom-most array declaration */
382178479Sjb
383178479Sjb	if (ndp != ddp) {
384178479Sjb		if (dnp != NULL && dnp->dn_kind == DT_NODE_TYPE) {
385178479Sjb			xyerror(D_DECL_DYNOBJ,
386178479Sjb			    "cannot declare array of associative arrays\n");
387178479Sjb		}
388178479Sjb		dsp->ds_decl = ddp->dd_next;
389178479Sjb		ddp->dd_next = ndp->dd_next;
390178479Sjb		ndp->dd_next = ddp;
391178479Sjb	}
392178479Sjb
393178479Sjb	if (ddp->dd_next->dd_name != NULL &&
394178479Sjb	    strcmp(ddp->dd_next->dd_name, "void") == 0)
395178479Sjb		xyerror(D_DECL_VOIDOBJ, "cannot declare array of void\n");
396178479Sjb
397178479Sjb	if (dnp != NULL && dnp->dn_kind != DT_NODE_TYPE) {
398178479Sjb		dnp = ddp->dd_node = dt_node_cook(dnp, DT_IDFLG_REF);
399178479Sjb
400178479Sjb		if (dt_node_is_posconst(dnp) == 0) {
401178479Sjb			xyerror(D_DECL_ARRSUB, "positive integral constant "
402178479Sjb			    "expression or tuple signature expected as "
403178479Sjb			    "array declaration subscript\n");
404178479Sjb		}
405178479Sjb
406178479Sjb		if (dnp->dn_value > UINT_MAX)
407178479Sjb			xyerror(D_DECL_ARRBIG, "array dimension too big\n");
408178479Sjb
409178479Sjb	} else if (dnp != NULL) {
410178479Sjb		ddp->dd_node = dnp;
411178479Sjb		(void) dt_decl_prototype(dnp, dnp, "array", DT_DP_ANON);
412178479Sjb	}
413178479Sjb
414178479Sjb	return (ddp);
415178479Sjb}
416178479Sjb
417178479Sjb/*
418178479Sjb * When a function is declared, we need to fudge the decl stack a bit if the
419178479Sjb * declaration uses the function pointer (*)() syntax.  In this case, the
420178479Sjb * dt_decl_func() call occurs *after* the dt_decl_ptr() call, even though the
421178479Sjb * resulting type is "pointer to function".  To make the pointer land on top,
422178479Sjb * we check to see if 'pdp' is non-NULL and a pointer.  If it is, we search
423178479Sjb * backward for a decl tagged with DT_DA_PAREN, and if one is found, the func
424178479Sjb * decl is inserted behind this node in the decl list instead of at the top.
425178479Sjb * In all cases, the func decl's dd_next pointer is set to the decl chain
426178479Sjb * for the function's return type and the function parameter list is discarded.
427178479Sjb */
428178479Sjbdt_decl_t *
429178479Sjbdt_decl_func(dt_decl_t *pdp, dt_node_t *dnp)
430178479Sjb{
431178479Sjb	dt_decl_t *ddp = dt_decl_alloc(CTF_K_FUNCTION, NULL);
432178479Sjb
433178479Sjb	ddp->dd_node = dnp;
434178479Sjb
435178479Sjb	(void) dt_decl_prototype(dnp, dnp, "function",
436178479Sjb	    DT_DP_VARARGS | DT_DP_VOID | DT_DP_ANON);
437178479Sjb
438178479Sjb	if (pdp == NULL || pdp->dd_kind != CTF_K_POINTER)
439178479Sjb		return (dt_decl_push(ddp));
440178479Sjb
441178479Sjb	while (pdp->dd_next != NULL && !(pdp->dd_next->dd_attr & DT_DA_PAREN))
442178479Sjb		pdp = pdp->dd_next;
443178479Sjb
444178479Sjb	if (pdp->dd_next == NULL)
445178479Sjb		return (dt_decl_push(ddp));
446178479Sjb
447178479Sjb	ddp->dd_next = pdp->dd_next;
448178479Sjb	pdp->dd_next = ddp;
449178479Sjb
450178479Sjb	return (pdp);
451178479Sjb}
452178479Sjb
453178479Sjbdt_decl_t *
454178479Sjbdt_decl_ptr(void)
455178479Sjb{
456178479Sjb	return (dt_decl_push(dt_decl_alloc(CTF_K_POINTER, NULL)));
457178479Sjb}
458178479Sjb
459178479Sjbdt_decl_t *
460178479Sjbdt_decl_sou(uint_t kind, char *name)
461178479Sjb{
462178479Sjb	dt_decl_t *ddp = dt_decl_spec(kind, name);
463178479Sjb	char n[DT_TYPE_NAMELEN];
464178479Sjb	ctf_file_t *ctfp;
465178479Sjb	ctf_id_t type;
466178479Sjb	uint_t flag;
467178479Sjb
468178479Sjb	if (yypcb->pcb_idepth != 0)
469178479Sjb		ctfp = yypcb->pcb_hdl->dt_cdefs->dm_ctfp;
470178479Sjb	else
471178479Sjb		ctfp = yypcb->pcb_hdl->dt_ddefs->dm_ctfp;
472178479Sjb
473178479Sjb	if (yypcb->pcb_dstack.ds_next != NULL)
474178479Sjb		flag = CTF_ADD_NONROOT;
475178479Sjb	else
476178479Sjb		flag = CTF_ADD_ROOT;
477178479Sjb
478178479Sjb	(void) snprintf(n, sizeof (n), "%s %s",
479178479Sjb	    kind == CTF_K_STRUCT ? "struct" : "union",
480178479Sjb	    name == NULL ? "(anon)" : name);
481178479Sjb
482178479Sjb	if (name != NULL && (type = ctf_lookup_by_name(ctfp, n)) != CTF_ERR &&
483178479Sjb	    ctf_type_kind(ctfp, type) != CTF_K_FORWARD)
484178479Sjb		xyerror(D_DECL_TYPERED, "type redeclared: %s\n", n);
485178479Sjb
486178479Sjb	if (kind == CTF_K_STRUCT)
487178479Sjb		type = ctf_add_struct(ctfp, flag, name);
488178479Sjb	else
489178479Sjb		type = ctf_add_union(ctfp, flag, name);
490178479Sjb
491178479Sjb	if (type == CTF_ERR || ctf_update(ctfp) == CTF_ERR) {
492178479Sjb		xyerror(D_UNKNOWN, "failed to define %s: %s\n",
493178479Sjb		    n, ctf_errmsg(ctf_errno(ctfp)));
494178479Sjb	}
495178479Sjb
496178479Sjb	ddp->dd_ctfp = ctfp;
497178479Sjb	ddp->dd_type = type;
498178479Sjb
499178479Sjb	dt_scope_push(ctfp, type);
500178479Sjb	return (ddp);
501178479Sjb}
502178479Sjb
503178479Sjbvoid
504178479Sjbdt_decl_member(dt_node_t *dnp)
505178479Sjb{
506178479Sjb	dt_scope_t *dsp = yypcb->pcb_dstack.ds_next;
507178479Sjb	dt_decl_t *ddp = yypcb->pcb_dstack.ds_decl;
508178479Sjb	char *ident = yypcb->pcb_dstack.ds_ident;
509178479Sjb
510178479Sjb	const char *idname = ident ? ident : "(anon)";
511178479Sjb	char n[DT_TYPE_NAMELEN];
512178479Sjb
513178479Sjb	dtrace_typeinfo_t dtt;
514178479Sjb	ctf_encoding_t cte;
515178479Sjb	ctf_id_t base;
516178479Sjb	uint_t kind;
517178479Sjb	ssize_t size;
518178479Sjb
519178479Sjb	if (dsp == NULL)
520178479Sjb		longjmp(yypcb->pcb_jmpbuf, EDT_NOSCOPE);
521178479Sjb
522178479Sjb	if (ddp == NULL)
523178479Sjb		longjmp(yypcb->pcb_jmpbuf, EDT_NODECL);
524178479Sjb
525178479Sjb	if (dnp == NULL && ident == NULL)
526178479Sjb		xyerror(D_DECL_MNAME, "member declaration requires a name\n");
527178479Sjb
528178479Sjb	if (ddp->dd_kind == CTF_K_UNKNOWN && ddp->dd_name == NULL) {
529178479Sjb		ddp->dd_kind = CTF_K_INTEGER;
530178479Sjb		(void) dt_decl_check(ddp);
531178479Sjb	}
532178479Sjb
533178479Sjb	if (dt_decl_type(ddp, &dtt) != 0)
534178479Sjb		longjmp(yypcb->pcb_jmpbuf, EDT_COMPILER);
535178479Sjb
536178479Sjb	if (ident != NULL && strchr(ident, '`') != NULL) {
537178479Sjb		xyerror(D_DECL_SCOPE, "D scoping operator may not be used "
538178479Sjb		    "in a member name (%s)\n", ident);
539178479Sjb	}
540178479Sjb
541178479Sjb	if (dtt.dtt_ctfp == DT_DYN_CTFP(yypcb->pcb_hdl) &&
542178479Sjb	    dtt.dtt_type == DT_DYN_TYPE(yypcb->pcb_hdl)) {
543178479Sjb		xyerror(D_DECL_DYNOBJ,
544178479Sjb		    "cannot have dynamic member: %s\n", ident);
545178479Sjb	}
546178479Sjb
547178479Sjb	base = ctf_type_resolve(dtt.dtt_ctfp, dtt.dtt_type);
548178479Sjb	kind = ctf_type_kind(dtt.dtt_ctfp, base);
549178479Sjb	size = ctf_type_size(dtt.dtt_ctfp, base);
550178479Sjb
551178479Sjb	if (kind == CTF_K_FORWARD || ((kind == CTF_K_STRUCT ||
552178479Sjb	    kind == CTF_K_UNION) && size == 0)) {
553178479Sjb		xyerror(D_DECL_INCOMPLETE, "incomplete struct/union/enum %s: "
554178479Sjb		    "%s\n", dt_type_name(dtt.dtt_ctfp, dtt.dtt_type,
555178479Sjb		    n, sizeof (n)), ident);
556178479Sjb	}
557178479Sjb
558178479Sjb	if (size == 0)
559178479Sjb		xyerror(D_DECL_VOIDOBJ, "cannot have void member: %s\n", ident);
560178479Sjb
561178479Sjb	/*
562178479Sjb	 * If a bit-field qualifier was part of the member declaration, create
563178479Sjb	 * a new integer type of the same name and attributes as the base type
564178479Sjb	 * and size equal to the specified number of bits.  We reset 'dtt' to
565178479Sjb	 * refer to this new bit-field type and continue on to add the member.
566178479Sjb	 */
567178479Sjb	if (dnp != NULL) {
568178479Sjb		dnp = dt_node_cook(dnp, DT_IDFLG_REF);
569178479Sjb
570178479Sjb		/*
571178479Sjb		 * A bit-field member with no declarator is permitted to have
572178479Sjb		 * size zero and indicates that no more fields are to be packed
573178479Sjb		 * into the current storage unit.  We ignore these directives
574178479Sjb		 * as the underlying ctf code currently does so for all fields.
575178479Sjb		 */
576178479Sjb		if (ident == NULL && dnp->dn_kind == DT_NODE_INT &&
577178479Sjb		    dnp->dn_value == 0) {
578178479Sjb			dt_node_free(dnp);
579178479Sjb			goto done;
580178479Sjb		}
581178479Sjb
582178479Sjb		if (dt_node_is_posconst(dnp) == 0) {
583178479Sjb			xyerror(D_DECL_BFCONST, "positive integral constant "
584178479Sjb			    "expression expected as bit-field size\n");
585178479Sjb		}
586178479Sjb
587178479Sjb		if (ctf_type_kind(dtt.dtt_ctfp, base) != CTF_K_INTEGER ||
588178479Sjb		    ctf_type_encoding(dtt.dtt_ctfp, base, &cte) == CTF_ERR ||
589178479Sjb		    IS_VOID(cte)) {
590178479Sjb			xyerror(D_DECL_BFTYPE, "invalid type for "
591178479Sjb			    "bit-field: %s\n", idname);
592178479Sjb		}
593178479Sjb
594178479Sjb		if (dnp->dn_value > cte.cte_bits) {
595178479Sjb			xyerror(D_DECL_BFSIZE, "bit-field too big "
596178479Sjb			    "for type: %s\n", idname);
597178479Sjb		}
598178479Sjb
599178479Sjb		cte.cte_offset = 0;
600178479Sjb		cte.cte_bits = (uint_t)dnp->dn_value;
601178479Sjb
602178479Sjb		dtt.dtt_type = ctf_add_integer(dsp->ds_ctfp,
603178479Sjb		    CTF_ADD_NONROOT, ctf_type_name(dtt.dtt_ctfp,
604178479Sjb		    dtt.dtt_type, n, sizeof (n)), &cte);
605178479Sjb
606178479Sjb		if (dtt.dtt_type == CTF_ERR ||
607178479Sjb		    ctf_update(dsp->ds_ctfp) == CTF_ERR) {
608178479Sjb			xyerror(D_UNKNOWN, "failed to create type for "
609178479Sjb			    "member '%s': %s\n", idname,
610178479Sjb			    ctf_errmsg(ctf_errno(dsp->ds_ctfp)));
611178479Sjb		}
612178479Sjb
613178479Sjb		dtt.dtt_ctfp = dsp->ds_ctfp;
614178479Sjb		dt_node_free(dnp);
615178479Sjb	}
616178479Sjb
617178479Sjb	/*
618178479Sjb	 * If the member type is not defined in the same CTF container as the
619178479Sjb	 * one associated with the current scope (i.e. the container for the
620178479Sjb	 * struct or union itself) or its parent, copy the member type into
621178479Sjb	 * this container and reset dtt to refer to the copied type.
622178479Sjb	 */
623178479Sjb	if (dtt.dtt_ctfp != dsp->ds_ctfp &&
624178479Sjb	    dtt.dtt_ctfp != ctf_parent_file(dsp->ds_ctfp)) {
625178479Sjb
626178479Sjb		dtt.dtt_type = ctf_add_type(dsp->ds_ctfp,
627178479Sjb		    dtt.dtt_ctfp, dtt.dtt_type);
628178479Sjb		dtt.dtt_ctfp = dsp->ds_ctfp;
629178479Sjb
630178479Sjb		if (dtt.dtt_type == CTF_ERR ||
631178479Sjb		    ctf_update(dtt.dtt_ctfp) == CTF_ERR) {
632178479Sjb			xyerror(D_UNKNOWN, "failed to copy type of '%s': %s\n",
633178479Sjb			    idname, ctf_errmsg(ctf_errno(dtt.dtt_ctfp)));
634178479Sjb		}
635178479Sjb	}
636178479Sjb
637178479Sjb	if (ctf_add_member(dsp->ds_ctfp, dsp->ds_type,
638178479Sjb	    ident, dtt.dtt_type) == CTF_ERR) {
639178479Sjb		xyerror(D_UNKNOWN, "failed to define member '%s': %s\n",
640178479Sjb		    idname, ctf_errmsg(ctf_errno(dsp->ds_ctfp)));
641178479Sjb	}
642178479Sjb
643178479Sjbdone:
644178479Sjb	free(ident);
645178479Sjb	yypcb->pcb_dstack.ds_ident = NULL;
646178479Sjb	dt_decl_reset();
647178479Sjb}
648178479Sjb
649178479Sjb/*ARGSUSED*/
650178479Sjbstatic int
651178479Sjbdt_decl_hasmembers(const char *name, int value, void *private)
652178479Sjb{
653178479Sjb	return (1); /* abort search and return true if a member exists */
654178479Sjb}
655178479Sjb
656178479Sjbdt_decl_t *
657178479Sjbdt_decl_enum(char *name)
658178479Sjb{
659178479Sjb	dt_decl_t *ddp = dt_decl_spec(CTF_K_ENUM, name);
660178479Sjb	char n[DT_TYPE_NAMELEN];
661178479Sjb	ctf_file_t *ctfp;
662178479Sjb	ctf_id_t type;
663178479Sjb	uint_t flag;
664178479Sjb
665178479Sjb	if (yypcb->pcb_idepth != 0)
666178479Sjb		ctfp = yypcb->pcb_hdl->dt_cdefs->dm_ctfp;
667178479Sjb	else
668178479Sjb		ctfp = yypcb->pcb_hdl->dt_ddefs->dm_ctfp;
669178479Sjb
670178479Sjb	if (yypcb->pcb_dstack.ds_next != NULL)
671178479Sjb		flag = CTF_ADD_NONROOT;
672178479Sjb	else
673178479Sjb		flag = CTF_ADD_ROOT;
674178479Sjb
675178479Sjb	(void) snprintf(n, sizeof (n), "enum %s", name ? name : "(anon)");
676178479Sjb
677178479Sjb	if (name != NULL && (type = ctf_lookup_by_name(ctfp, n)) != CTF_ERR) {
678178479Sjb		if (ctf_enum_iter(ctfp, type, dt_decl_hasmembers, NULL))
679178479Sjb			xyerror(D_DECL_TYPERED, "type redeclared: %s\n", n);
680178479Sjb	} else if ((type = ctf_add_enum(ctfp, flag, name)) == CTF_ERR) {
681178479Sjb		xyerror(D_UNKNOWN, "failed to define %s: %s\n",
682178479Sjb		    n, ctf_errmsg(ctf_errno(ctfp)));
683178479Sjb	}
684178479Sjb
685178479Sjb	ddp->dd_ctfp = ctfp;
686178479Sjb	ddp->dd_type = type;
687178479Sjb
688178479Sjb	dt_scope_push(ctfp, type);
689178479Sjb	return (ddp);
690178479Sjb}
691178479Sjb
692178479Sjbvoid
693178479Sjbdt_decl_enumerator(char *s, dt_node_t *dnp)
694178479Sjb{
695178479Sjb	dt_scope_t *dsp = yypcb->pcb_dstack.ds_next;
696178479Sjb	dtrace_hdl_t *dtp = yypcb->pcb_hdl;
697178479Sjb
698178479Sjb	dt_idnode_t *inp;
699178479Sjb	dt_ident_t *idp;
700178479Sjb	char *name;
701178479Sjb	int value;
702178479Sjb
703178479Sjb	name = alloca(strlen(s) + 1);
704178479Sjb	(void) strcpy(name, s);
705178479Sjb	free(s);
706178479Sjb
707178479Sjb	if (dsp == NULL)
708178479Sjb		longjmp(yypcb->pcb_jmpbuf, EDT_NOSCOPE);
709178479Sjb
710178479Sjb	assert(dsp->ds_decl->dd_kind == CTF_K_ENUM);
711178479Sjb	value = dsp->ds_enumval + 1; /* default is previous value plus one */
712178479Sjb
713178479Sjb	if (strchr(name, '`') != NULL) {
714178479Sjb		xyerror(D_DECL_SCOPE, "D scoping operator may not be used in "
715178479Sjb		    "an enumerator name (%s)\n", name);
716178479Sjb	}
717178479Sjb
718178479Sjb	/*
719178479Sjb	 * If the enumerator is being assigned a value, cook and check the node
720178479Sjb	 * and then free it after we get the value.  We also permit references
721178479Sjb	 * to identifiers which are previously defined enumerators in the type.
722178479Sjb	 */
723178479Sjb	if (dnp != NULL) {
724178479Sjb		if (dnp->dn_kind != DT_NODE_IDENT || ctf_enum_value(
725178479Sjb		    dsp->ds_ctfp, dsp->ds_type, dnp->dn_string, &value) != 0) {
726178479Sjb			dnp = dt_node_cook(dnp, DT_IDFLG_REF);
727178479Sjb
728178479Sjb			if (dnp->dn_kind != DT_NODE_INT) {
729178479Sjb				xyerror(D_DECL_ENCONST, "enumerator '%s' must "
730178479Sjb				    "be assigned to an integral constant "
731178479Sjb				    "expression\n", name);
732178479Sjb			}
733178479Sjb
734178479Sjb			if ((intmax_t)dnp->dn_value > INT_MAX ||
735178479Sjb			    (intmax_t)dnp->dn_value < INT_MIN) {
736178479Sjb				xyerror(D_DECL_ENOFLOW, "enumerator '%s' value "
737178479Sjb				    "overflows INT_MAX (%d)\n", name, INT_MAX);
738178479Sjb			}
739178479Sjb
740178479Sjb			value = (int)dnp->dn_value;
741178479Sjb		}
742178479Sjb		dt_node_free(dnp);
743178479Sjb	}
744178479Sjb
745178479Sjb	if (ctf_add_enumerator(dsp->ds_ctfp, dsp->ds_type,
746178479Sjb	    name, value) == CTF_ERR || ctf_update(dsp->ds_ctfp) == CTF_ERR) {
747178479Sjb		xyerror(D_UNKNOWN, "failed to define enumerator '%s': %s\n",
748178479Sjb		    name, ctf_errmsg(ctf_errno(dsp->ds_ctfp)));
749178479Sjb	}
750178479Sjb
751178479Sjb	dsp->ds_enumval = value; /* save most recent value */
752178479Sjb
753178479Sjb	/*
754178479Sjb	 * If the enumerator name matches an identifier in the global scope,
755178479Sjb	 * flag this as an error.  We only do this for "D" enumerators to
756178479Sjb	 * prevent "C" header file enumerators from conflicting with the ever-
757178479Sjb	 * growing list of D built-in global variables and inlines.  If a "C"
758178479Sjb	 * enumerator conflicts with a global identifier, we add the enumerator
759178479Sjb	 * but do not insert a corresponding inline (i.e. the D variable wins).
760178479Sjb	 */
761178479Sjb	if (dt_idstack_lookup(&yypcb->pcb_globals, name) != NULL) {
762178479Sjb		if (dsp->ds_ctfp == dtp->dt_ddefs->dm_ctfp) {
763178479Sjb			xyerror(D_DECL_IDRED,
764178479Sjb			    "identifier redeclared: %s\n", name);
765178479Sjb		} else
766178479Sjb			return;
767178479Sjb	}
768178479Sjb
769178479Sjb	dt_dprintf("add global enumerator %s = %d\n", name, value);
770178479Sjb
771178479Sjb	idp = dt_idhash_insert(dtp->dt_globals, name, DT_IDENT_ENUM,
772178479Sjb	    DT_IDFLG_INLINE | DT_IDFLG_REF, 0, _dtrace_defattr, 0,
773178479Sjb	    &dt_idops_inline, NULL, dtp->dt_gen);
774178479Sjb
775178479Sjb	if (idp == NULL)
776178479Sjb		longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
777178479Sjb
778178479Sjb	yyintprefix = 0;
779178479Sjb	yyintsuffix[0] = '\0';
780178479Sjb	yyintdecimal = 0;
781178479Sjb
782178479Sjb	dnp = dt_node_int(value);
783267941Srpaulo	dt_node_type_assign(dnp, dsp->ds_ctfp, dsp->ds_type, B_FALSE);
784178479Sjb
785178479Sjb	if ((inp = malloc(sizeof (dt_idnode_t))) == NULL)
786178479Sjb		longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
787178479Sjb
788178479Sjb	/*
789178479Sjb	 * Remove the INT node from the node allocation list and store it in
790178479Sjb	 * din_list and din_root so it persists with and is freed by the ident.
791178479Sjb	 */
792178479Sjb	assert(yypcb->pcb_list == dnp);
793178479Sjb	yypcb->pcb_list = dnp->dn_link;
794178479Sjb	dnp->dn_link = NULL;
795178479Sjb
796178479Sjb	bzero(inp, sizeof (dt_idnode_t));
797178479Sjb	inp->din_list = dnp;
798178479Sjb	inp->din_root = dnp;
799178479Sjb
800178479Sjb	idp->di_iarg = inp;
801178479Sjb	idp->di_ctfp = dsp->ds_ctfp;
802178479Sjb	idp->di_type = dsp->ds_type;
803178479Sjb}
804178479Sjb
805178479Sjb/*
806178479Sjb * Look up the type corresponding to the specified decl stack.  The scoping of
807178479Sjb * the underlying type names is handled by dt_type_lookup().  We build up the
808178479Sjb * name from the specified string and prefixes and then lookup the type.  If
809178479Sjb * we fail, an errmsg is saved and the caller must abort with EDT_COMPILER.
810178479Sjb */
811178479Sjbint
812178479Sjbdt_decl_type(dt_decl_t *ddp, dtrace_typeinfo_t *tip)
813178479Sjb{
814178479Sjb	dtrace_hdl_t *dtp = yypcb->pcb_hdl;
815178479Sjb
816178479Sjb	dt_module_t *dmp;
817178479Sjb	ctf_arinfo_t r;
818178479Sjb	ctf_id_t type;
819178479Sjb
820178479Sjb	char n[DT_TYPE_NAMELEN];
821178479Sjb	uint_t flag;
822178479Sjb	char *name;
823178479Sjb	int rv;
824178479Sjb
825267941Srpaulo	tip->dtt_flags = 0;
826267941Srpaulo
827178479Sjb	/*
828178479Sjb	 * Based on our current #include depth and decl stack depth, determine
829178479Sjb	 * which dynamic CTF module and scope to use when adding any new types.
830178479Sjb	 */
831178479Sjb	dmp = yypcb->pcb_idepth ? dtp->dt_cdefs : dtp->dt_ddefs;
832178479Sjb	flag = yypcb->pcb_dstack.ds_next ? CTF_ADD_NONROOT : CTF_ADD_ROOT;
833178479Sjb
834267941Srpaulo	if (ddp->dd_attr & DT_DA_USER)
835267941Srpaulo		tip->dtt_flags = DTT_FL_USER;
836267941Srpaulo
837178479Sjb	/*
838178479Sjb	 * If we have already cached a CTF type for this decl, then we just
839178479Sjb	 * return the type information for the cached type.
840178479Sjb	 */
841178479Sjb	if (ddp->dd_ctfp != NULL &&
842178479Sjb	    (dmp = dt_module_lookup_by_ctf(dtp, ddp->dd_ctfp)) != NULL) {
843178479Sjb		tip->dtt_object = dmp->dm_name;
844178479Sjb		tip->dtt_ctfp = ddp->dd_ctfp;
845178479Sjb		tip->dtt_type = ddp->dd_type;
846178479Sjb		return (0);
847178479Sjb	}
848178479Sjb
849178479Sjb	/*
850178479Sjb	 * Currently CTF treats all function pointers identically.  We cache a
851178479Sjb	 * representative ID of kind CTF_K_FUNCTION and just return that type.
852178479Sjb	 * If we want to support full function declarations, dd_next refers to
853178479Sjb	 * the declaration of the function return type, and the parameter list
854178479Sjb	 * should be parsed and hung off a new pointer inside of this decl.
855178479Sjb	 */
856178479Sjb	if (ddp->dd_kind == CTF_K_FUNCTION) {
857178479Sjb		tip->dtt_object = dtp->dt_ddefs->dm_name;
858178479Sjb		tip->dtt_ctfp = DT_FUNC_CTFP(dtp);
859178479Sjb		tip->dtt_type = DT_FUNC_TYPE(dtp);
860178479Sjb		return (0);
861178479Sjb	}
862178479Sjb
863178479Sjb	/*
864178479Sjb	 * If the decl is a pointer, resolve the rest of the stack by calling
865178479Sjb	 * dt_decl_type() recursively and then compute a pointer to the result.
866178479Sjb	 * Similar to the code above, we return a cached id for function ptrs.
867178479Sjb	 */
868178479Sjb	if (ddp->dd_kind == CTF_K_POINTER) {
869178479Sjb		if (ddp->dd_next->dd_kind == CTF_K_FUNCTION) {
870178479Sjb			tip->dtt_object = dtp->dt_ddefs->dm_name;
871178479Sjb			tip->dtt_ctfp = DT_FPTR_CTFP(dtp);
872178479Sjb			tip->dtt_type = DT_FPTR_TYPE(dtp);
873178479Sjb			return (0);
874178479Sjb		}
875178479Sjb
876178479Sjb		if ((rv = dt_decl_type(ddp->dd_next, tip)) == 0 &&
877178479Sjb		    (rv = dt_type_pointer(tip)) != 0) {
878178479Sjb			xywarn(D_UNKNOWN, "cannot find type: %s*: %s\n",
879178479Sjb			    dt_type_name(tip->dtt_ctfp, tip->dtt_type,
880178479Sjb			    n, sizeof (n)), ctf_errmsg(dtp->dt_ctferr));
881178479Sjb		}
882178479Sjb
883178479Sjb		return (rv);
884178479Sjb	}
885178479Sjb
886178479Sjb	/*
887178479Sjb	 * If the decl is an array, we must find the base type and then call
888178479Sjb	 * dt_decl_type() recursively and then build an array of the result.
889178479Sjb	 * The C and D multi-dimensional array syntax requires that consecutive
890178479Sjb	 * array declarations be processed from right-to-left (i.e. top-down
891178479Sjb	 * from the perspective of the declaration stack).  For example, an
892178479Sjb	 * array declaration such as int x[3][5] is stored on the stack as:
893178479Sjb	 *
894178479Sjb	 * (bottom) NULL <- ( INT "int" ) <- ( ARR [3] ) <- ( ARR [5] ) (top)
895178479Sjb	 *
896178479Sjb	 * but means that x is declared to be an array of 3 objects each of
897178479Sjb	 * which is an array of 5 integers, or in CTF representation:
898178479Sjb	 *
899178479Sjb	 * type T1:( content=int, nelems=5 ) type T2:( content=T1, nelems=3 )
900178479Sjb	 *
901178479Sjb	 * For more details, refer to K&R[5.7] and ISO C 6.5.2.1.  Rather than
902178479Sjb	 * overcomplicate the implementation of dt_decl_type(), we push array
903178479Sjb	 * declarations down into the stack in dt_decl_array(), above, so that
904178479Sjb	 * by the time dt_decl_type() is called, the decl stack looks like:
905178479Sjb	 *
906178479Sjb	 * (bottom) NULL <- ( INT "int" ) <- ( ARR [5] ) <- ( ARR [3] ) (top)
907178479Sjb	 *
908178479Sjb	 * which permits a straightforward recursive descent of the decl stack
909178479Sjb	 * to build the corresponding CTF type tree in the appropriate order.
910178479Sjb	 */
911178479Sjb	if (ddp->dd_kind == CTF_K_ARRAY) {
912178479Sjb		/*
913178479Sjb		 * If the array decl has a parameter list associated with it,
914178479Sjb		 * this is an associative array declaration: return <DYN>.
915178479Sjb		 */
916178479Sjb		if (ddp->dd_node != NULL &&
917178479Sjb		    ddp->dd_node->dn_kind == DT_NODE_TYPE) {
918178479Sjb			tip->dtt_object = dtp->dt_ddefs->dm_name;
919178479Sjb			tip->dtt_ctfp = DT_DYN_CTFP(dtp);
920178479Sjb			tip->dtt_type = DT_DYN_TYPE(dtp);
921178479Sjb			return (0);
922178479Sjb		}
923178479Sjb
924178479Sjb		if ((rv = dt_decl_type(ddp->dd_next, tip)) != 0)
925178479Sjb			return (rv);
926178479Sjb
927178479Sjb		/*
928178479Sjb		 * If the array base type is not defined in the target
929178479Sjb		 * container or its parent, copy the type to the target
930178479Sjb		 * container and reset dtt_ctfp and dtt_type to the copy.
931178479Sjb		 */
932178479Sjb		if (tip->dtt_ctfp != dmp->dm_ctfp &&
933178479Sjb		    tip->dtt_ctfp != ctf_parent_file(dmp->dm_ctfp)) {
934178479Sjb
935178479Sjb			tip->dtt_type = ctf_add_type(dmp->dm_ctfp,
936178479Sjb			    tip->dtt_ctfp, tip->dtt_type);
937178479Sjb			tip->dtt_ctfp = dmp->dm_ctfp;
938178479Sjb
939178479Sjb			if (tip->dtt_type == CTF_ERR ||
940178479Sjb			    ctf_update(tip->dtt_ctfp) == CTF_ERR) {
941178479Sjb				xywarn(D_UNKNOWN, "failed to copy type: %s\n",
942178479Sjb				    ctf_errmsg(ctf_errno(tip->dtt_ctfp)));
943178479Sjb				return (-1);
944178479Sjb			}
945178479Sjb		}
946178479Sjb
947178479Sjb		/*
948178479Sjb		 * The array index type is irrelevant in C and D: just set it
949178479Sjb		 * to "long" for all array types that we create on-the-fly.
950178479Sjb		 */
951178479Sjb		r.ctr_contents = tip->dtt_type;
952178479Sjb		r.ctr_index = ctf_lookup_by_name(tip->dtt_ctfp, "long");
953178479Sjb		r.ctr_nelems = ddp->dd_node ?
954178479Sjb		    (uint_t)ddp->dd_node->dn_value : 0;
955178479Sjb
956178479Sjb		tip->dtt_object = dmp->dm_name;
957178479Sjb		tip->dtt_ctfp = dmp->dm_ctfp;
958178479Sjb		tip->dtt_type = ctf_add_array(dmp->dm_ctfp, CTF_ADD_ROOT, &r);
959178479Sjb
960178479Sjb		if (tip->dtt_type == CTF_ERR ||
961178479Sjb		    ctf_update(tip->dtt_ctfp) == CTF_ERR) {
962178479Sjb			xywarn(D_UNKNOWN, "failed to create array type: %s\n",
963178479Sjb			    ctf_errmsg(ctf_errno(tip->dtt_ctfp)));
964178479Sjb			return (-1);
965178479Sjb		}
966178479Sjb
967178479Sjb		return (0);
968178479Sjb	}
969178479Sjb
970178479Sjb	/*
971178479Sjb	 * Allocate space for the type name and enough space for the maximum
972178479Sjb	 * additional text ("unsigned long long \0" requires 20 more bytes).
973178479Sjb	 */
974178479Sjb	name = alloca(ddp->dd_name ? strlen(ddp->dd_name) + 20 : 20);
975178479Sjb	name[0] = '\0';
976178479Sjb
977178479Sjb	switch (ddp->dd_kind) {
978178479Sjb	case CTF_K_INTEGER:
979178479Sjb	case CTF_K_FLOAT:
980178479Sjb		if (ddp->dd_attr & DT_DA_SIGNED)
981178479Sjb			(void) strcat(name, "signed ");
982178479Sjb		if (ddp->dd_attr & DT_DA_UNSIGNED)
983178479Sjb			(void) strcat(name, "unsigned ");
984178479Sjb		if (ddp->dd_attr & DT_DA_SHORT)
985178479Sjb			(void) strcat(name, "short ");
986178479Sjb		if (ddp->dd_attr & DT_DA_LONG)
987178479Sjb			(void) strcat(name, "long ");
988178479Sjb		if (ddp->dd_attr & DT_DA_LONGLONG)
989178479Sjb			(void) strcat(name, "long long ");
990178479Sjb		if (ddp->dd_attr == 0 && ddp->dd_name == NULL)
991178479Sjb			(void) strcat(name, "int");
992178479Sjb		break;
993178479Sjb	case CTF_K_STRUCT:
994178479Sjb		(void) strcpy(name, "struct ");
995178479Sjb		break;
996178479Sjb	case CTF_K_UNION:
997178479Sjb		(void) strcpy(name, "union ");
998178479Sjb		break;
999178479Sjb	case CTF_K_ENUM:
1000178479Sjb		(void) strcpy(name, "enum ");
1001178479Sjb		break;
1002178479Sjb	case CTF_K_TYPEDEF:
1003178479Sjb		break;
1004178479Sjb	default:
1005178479Sjb		xywarn(D_UNKNOWN, "internal error -- "
1006178479Sjb		    "bad decl kind %u\n", ddp->dd_kind);
1007178479Sjb		return (-1);
1008178479Sjb	}
1009178479Sjb
1010178479Sjb	/*
1011178479Sjb	 * Add dd_name unless a short, long, or long long is explicitly
1012178479Sjb	 * suffixed by int.  We use the C/CTF canonical names for integers.
1013178479Sjb	 */
1014178479Sjb	if (ddp->dd_name != NULL && (ddp->dd_kind != CTF_K_INTEGER ||
1015178479Sjb	    (ddp->dd_attr & (DT_DA_SHORT | DT_DA_LONG | DT_DA_LONGLONG)) == 0))
1016178479Sjb		(void) strcat(name, ddp->dd_name);
1017178479Sjb
1018178479Sjb	/*
1019178479Sjb	 * Lookup the type.  If we find it, we're done.  Otherwise create a
1020178479Sjb	 * forward tag for the type if it is a struct, union, or enum.  If
1021178479Sjb	 * we can't find it and we can't create a tag, return failure.
1022178479Sjb	 */
1023178479Sjb	if ((rv = dt_type_lookup(name, tip)) == 0)
1024178479Sjb		return (rv);
1025178479Sjb
1026178479Sjb	switch (ddp->dd_kind) {
1027178479Sjb	case CTF_K_STRUCT:
1028178479Sjb	case CTF_K_UNION:
1029178479Sjb	case CTF_K_ENUM:
1030178479Sjb		type = ctf_add_forward(dmp->dm_ctfp, flag,
1031178479Sjb		    ddp->dd_name, ddp->dd_kind);
1032178479Sjb		break;
1033178479Sjb	default:
1034178479Sjb		xywarn(D_UNKNOWN, "failed to resolve type %s: %s\n", name,
1035178479Sjb		    dtrace_errmsg(dtp, dtrace_errno(dtp)));
1036178479Sjb		return (rv);
1037178479Sjb	}
1038178479Sjb
1039178479Sjb	if (type == CTF_ERR || ctf_update(dmp->dm_ctfp) == CTF_ERR) {
1040178479Sjb		xywarn(D_UNKNOWN, "failed to add forward tag for %s: %s\n",
1041178479Sjb		    name, ctf_errmsg(ctf_errno(dmp->dm_ctfp)));
1042178479Sjb		return (-1);
1043178479Sjb	}
1044178479Sjb
1045178479Sjb	ddp->dd_ctfp = dmp->dm_ctfp;
1046178479Sjb	ddp->dd_type = type;
1047178479Sjb
1048178479Sjb	tip->dtt_object = dmp->dm_name;
1049178479Sjb	tip->dtt_ctfp = dmp->dm_ctfp;
1050178479Sjb	tip->dtt_type = type;
1051178479Sjb
1052178479Sjb	return (0);
1053178479Sjb}
1054178479Sjb
1055178479Sjbvoid
1056178479Sjbdt_scope_create(dt_scope_t *dsp)
1057178479Sjb{
1058178479Sjb	dsp->ds_decl = NULL;
1059178479Sjb	dsp->ds_next = NULL;
1060178479Sjb	dsp->ds_ident = NULL;
1061178479Sjb	dsp->ds_ctfp = NULL;
1062178479Sjb	dsp->ds_type = CTF_ERR;
1063178479Sjb	dsp->ds_class = DT_DC_DEFAULT;
1064178479Sjb	dsp->ds_enumval = -1;
1065178479Sjb}
1066178479Sjb
1067178479Sjbvoid
1068178479Sjbdt_scope_destroy(dt_scope_t *dsp)
1069178479Sjb{
1070178479Sjb	dt_scope_t *nsp;
1071178479Sjb
1072178479Sjb	for (; dsp != NULL; dsp = nsp) {
1073178479Sjb		dt_decl_free(dsp->ds_decl);
1074178479Sjb		free(dsp->ds_ident);
1075178479Sjb		nsp = dsp->ds_next;
1076178479Sjb		if (dsp != &yypcb->pcb_dstack)
1077178479Sjb			free(dsp);
1078178479Sjb	}
1079178479Sjb}
1080178479Sjb
1081178479Sjbvoid
1082178479Sjbdt_scope_push(ctf_file_t *ctfp, ctf_id_t type)
1083178479Sjb{
1084178479Sjb	dt_scope_t *rsp = &yypcb->pcb_dstack;
1085178479Sjb	dt_scope_t *dsp = malloc(sizeof (dt_scope_t));
1086178479Sjb
1087178479Sjb	if (dsp == NULL)
1088178479Sjb		longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
1089178479Sjb
1090178479Sjb	dsp->ds_decl = rsp->ds_decl;
1091178479Sjb	dsp->ds_next = rsp->ds_next;
1092178479Sjb	dsp->ds_ident = rsp->ds_ident;
1093178479Sjb	dsp->ds_ctfp = ctfp;
1094178479Sjb	dsp->ds_type = type;
1095178479Sjb	dsp->ds_class = rsp->ds_class;
1096178479Sjb	dsp->ds_enumval = rsp->ds_enumval;
1097178479Sjb
1098178479Sjb	dt_scope_create(rsp);
1099178479Sjb	rsp->ds_next = dsp;
1100178479Sjb}
1101178479Sjb
1102178479Sjbdt_decl_t *
1103178479Sjbdt_scope_pop(void)
1104178479Sjb{
1105178479Sjb	dt_scope_t *rsp = &yypcb->pcb_dstack;
1106178479Sjb	dt_scope_t *dsp = rsp->ds_next;
1107178479Sjb
1108178479Sjb	if (dsp == NULL)
1109178479Sjb		longjmp(yypcb->pcb_jmpbuf, EDT_NOSCOPE);
1110178479Sjb
1111178479Sjb	if (dsp->ds_ctfp != NULL && ctf_update(dsp->ds_ctfp) == CTF_ERR) {
1112178479Sjb		xyerror(D_UNKNOWN, "failed to update type definitions: %s\n",
1113178479Sjb		    ctf_errmsg(ctf_errno(dsp->ds_ctfp)));
1114178479Sjb	}
1115178479Sjb
1116178479Sjb	dt_decl_free(rsp->ds_decl);
1117178479Sjb	free(rsp->ds_ident);
1118178479Sjb
1119178479Sjb	rsp->ds_decl = dsp->ds_decl;
1120178479Sjb	rsp->ds_next = dsp->ds_next;
1121178479Sjb	rsp->ds_ident = dsp->ds_ident;
1122178479Sjb	rsp->ds_ctfp = dsp->ds_ctfp;
1123178479Sjb	rsp->ds_type = dsp->ds_type;
1124178479Sjb	rsp->ds_class = dsp->ds_class;
1125178479Sjb	rsp->ds_enumval = dsp->ds_enumval;
1126178479Sjb
1127178479Sjb	free(dsp);
1128178479Sjb	return (rsp->ds_decl);
1129178479Sjb}
1130