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