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