1*753d2d2eSraf %{ 2*753d2d2eSraf /* 3*753d2d2eSraf * CDDL HEADER START 4*753d2d2eSraf * 5*753d2d2eSraf * The contents of this file are subject to the terms of the 6*753d2d2eSraf * Common Development and Distribution License, Version 1.0 only 7*753d2d2eSraf * (the "License"). You may not use this file except in compliance 8*753d2d2eSraf * with the License. 9*753d2d2eSraf * 10*753d2d2eSraf * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 11*753d2d2eSraf * or http://www.opensolaris.org/os/licensing. 12*753d2d2eSraf * See the License for the specific language governing permissions 13*753d2d2eSraf * and limitations under the License. 14*753d2d2eSraf * 15*753d2d2eSraf * When distributing Covered Code, include this CDDL HEADER in each 16*753d2d2eSraf * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 17*753d2d2eSraf * If applicable, add the following below this CDDL HEADER, with the 18*753d2d2eSraf * fields enclosed by brackets "[]" replaced with your own identifying 19*753d2d2eSraf * information: Portions Copyright [yyyy] [name of copyright owner] 20*753d2d2eSraf * 21*753d2d2eSraf * CDDL HEADER END 22*753d2d2eSraf */ 23*753d2d2eSraf 24*753d2d2eSraf /* 25*753d2d2eSraf * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 26*753d2d2eSraf * Use is subject to license terms. 27*753d2d2eSraf */ 28*753d2d2eSraf 29*753d2d2eSraf #pragma ident "%Z%%M% %I% %E% SMI" 30*753d2d2eSraf 31*753d2d2eSraf #include "parseproto.h" 32*753d2d2eSraf #include <assert.h> 33*753d2d2eSraf 34*753d2d2eSraf static decl_spec_t *declspec_Construct(void); 35*753d2d2eSraf static void declspec_Destroy(decl_spec_t *); 36*753d2d2eSraf static decl_spec_t *declspec_Init(stt_t, char *); 37*753d2d2eSraf static char *declspec_VerifySTT(stt_t, stt_t); 38*753d2d2eSraf static decl_spec_t *declspec_AddSTT(decl_spec_t *, stt_t, const char **); 39*753d2d2eSraf static decl_spec_t *declspec_AddDS(decl_spec_t *, 40*753d2d2eSraf decl_spec_t *, const char **); 41*753d2d2eSraf static stt_t declspec_GetSTT(decl_spec_t *); 42*753d2d2eSraf static char *declspec_GetTag(decl_spec_t *); 43*753d2d2eSraf static type_t *type_Construct(void); 44*753d2d2eSraf static void type_Destroy(type_t *); 45*753d2d2eSraf static type_t *type_SetPtr(type_t *, stt_t); 46*753d2d2eSraf static type_t *type_SetFun(type_t *, decl_t *); 47*753d2d2eSraf static type_t *type_AddTail(type_t *, type_t *); 48*753d2d2eSraf static const char *type_Verify(type_t *); 49*753d2d2eSraf 50*753d2d2eSraf static decl_t *decl_Construct(void); 51*753d2d2eSraf static decl_t *decl_AddArg(decl_t *, decl_t *); 52*753d2d2eSraf static int decl_IsVoid(decl_t *); 53*753d2d2eSraf static int decl_IsVoidArray(decl_t *); 54*753d2d2eSraf static const char *decl_VerifyArgs(decl_t *); 55*753d2d2eSraf static decl_t *decl_AddDS(decl_t *, decl_spec_t *, const char **); 56*753d2d2eSraf static decl_t *decl_AddTypeTail(decl_t *, type_t *); 57*753d2d2eSraf static decl_t *decl_addptr(decl_t *, type_t *); 58*753d2d2eSraf static decl_t *decl_addary(decl_t *, char *); 59*753d2d2eSraf static decl_t *decl_addfun(decl_t *, decl_t *); 60*753d2d2eSraf static decl_t *decl_addellipsis(decl_t *); 61*753d2d2eSraf 62*753d2d2eSraf #if defined(DEBUG) 63*753d2d2eSraf static void type_PrintType(type_t *, int); 64*753d2d2eSraf static void decl_PrintDecl(decl_t *, int); 65*753d2d2eSraf static void decl_PrintTraceInfo(decl_t *); 66*753d2d2eSraf static char *de_const(char *); 67*753d2d2eSraf #endif 68*753d2d2eSraf 69*753d2d2eSraf 70*753d2d2eSraf 71*753d2d2eSraf static int yylex(void); 72*753d2d2eSraf static void yyerror(const char *); 73*753d2d2eSraf static int yyparse(void); 74*753d2d2eSraf 75*753d2d2eSraf #if defined(MEM_DEBUG) 76*753d2d2eSraf static int declspec_Construct_calls; 77*753d2d2eSraf static int type_Construct_calls; 78*753d2d2eSraf static int decl_Construct_calls; 79*753d2d2eSraf #endif 80*753d2d2eSraf 81*753d2d2eSraf #if defined(DEBUG) 82*753d2d2eSraf static char *de_const(char *); 83*753d2d2eSraf #endif 84*753d2d2eSraf %} 85*753d2d2eSraf 86*753d2d2eSraf %union { 87*753d2d2eSraf char *s_val; 88*753d2d2eSraf int i_val; 89*753d2d2eSraf stt_t stt_val; 90*753d2d2eSraf decl_spec_t *ds_val; 91*753d2d2eSraf type_t *t_val; 92*753d2d2eSraf decl_t *d_val; 93*753d2d2eSraf } 94*753d2d2eSraf 95*753d2d2eSraf %token <i_val> ELLIPSIS 96*753d2d2eSraf 97*753d2d2eSraf %token <s_val> INTEGER 98*753d2d2eSraf %token <s_val> IDENTIFIER 99*753d2d2eSraf %token <s_val> TYPEDEF_NAME 100*753d2d2eSraf %type <s_val> constant_expression 101*753d2d2eSraf 102*753d2d2eSraf %token <stt_val> REGISTER 103*753d2d2eSraf %token <stt_val> TYPEDEF EXTERN AUTO STATIC 104*753d2d2eSraf %token <stt_val> VOID CHAR SHORT INT LONG 105*753d2d2eSraf %token <stt_val> FLOAT DOUBLE SIGNED UNSIGNED 106*753d2d2eSraf %token <stt_val> CONST VOLATILE RESTRICT RESTRICT_KYWD 107*753d2d2eSraf %type <stt_val> struct_or_union 108*753d2d2eSraf %type <ds_val> storage_class_specifier 109*753d2d2eSraf %type <ds_val> type_qualifier 110*753d2d2eSraf %type <ds_val> type_qualifier_list 111*753d2d2eSraf 112*753d2d2eSraf %token <ds_val> STRUCT UNION 113*753d2d2eSraf %token <ds_val> ENUM 114*753d2d2eSraf %type <ds_val> declaration_specifiers 115*753d2d2eSraf %type <ds_val> type_specifier 116*753d2d2eSraf %type <ds_val> struct_or_union_specifier enum_specifier 117*753d2d2eSraf %type <ds_val> typedef_name 118*753d2d2eSraf 119*753d2d2eSraf %type <t_val> pointer 120*753d2d2eSraf 121*753d2d2eSraf %type <d_val> declaration 122*753d2d2eSraf %type <d_val> init_declarator_list init_declarator 123*753d2d2eSraf %type <d_val> declarator 124*753d2d2eSraf %type <d_val> direct_declarator 125*753d2d2eSraf %type <d_val> parameter_type_list parameter_list 126*753d2d2eSraf %type <d_val> parameter_declaration 127*753d2d2eSraf %type <d_val> abstract_declarator 128*753d2d2eSraf %type <d_val> direct_abstract_declarator 129*753d2d2eSraf 130*753d2d2eSraf %start declaration 131*753d2d2eSraf 132*753d2d2eSraf %% 133*753d2d2eSraf 134*753d2d2eSraf /* 135*753d2d2eSraf * The grammar is derived from ANSI/ISO 9899-1990. 136*753d2d2eSraf */ 137*753d2d2eSraf 138*753d2d2eSraf declaration 139*753d2d2eSraf : declaration_specifiers init_declarator_list ';' 140*753d2d2eSraf { 141*753d2d2eSraf decl_t *dp; 142*753d2d2eSraf 143*753d2d2eSraf protop = $$ = $2; 144*753d2d2eSraf 145*753d2d2eSraf /* only one declaration allowed */ 146*753d2d2eSraf assert(protop->d_next == NULL); 147*753d2d2eSraf 148*753d2d2eSraf for (dp = $2; dp && (errstr == NULL); 149*753d2d2eSraf dp = dp->d_next) { 150*753d2d2eSraf const char *sp; 151*753d2d2eSraf 152*753d2d2eSraf decl_AddDS(dp, $1, &errstr); 153*753d2d2eSraf if (sp = decl_Verify(dp)) 154*753d2d2eSraf errstr = sp; 155*753d2d2eSraf } 156*753d2d2eSraf declspec_Destroy($1); 157*753d2d2eSraf } 158*753d2d2eSraf | error ';' 159*753d2d2eSraf { 160*753d2d2eSraf protop = $$ = NULL; 161*753d2d2eSraf errstr = "function prototype syntax error"; 162*753d2d2eSraf } 163*753d2d2eSraf /* 164*753d2d2eSraf * XXX - Does not support a "stand-alone" declaration specifier. It is 165*753d2d2eSraf * essentially a type declaration, for example: 166*753d2d2eSraf * 167*753d2d2eSraf * typedef enum { FALSE = 0, TRUE = 1 } boolean_t; 168*753d2d2eSraf * or 169*753d2d2eSraf * struct _name { char *first; char *last }; 170*753d2d2eSraf */ 171*753d2d2eSraf 172*753d2d2eSraf /* XXX | declaration_specifiers */ 173*753d2d2eSraf ; 174*753d2d2eSraf 175*753d2d2eSraf declaration_specifiers 176*753d2d2eSraf : storage_class_specifier declaration_specifiers 177*753d2d2eSraf { 178*753d2d2eSraf char const *ep; 179*753d2d2eSraf 180*753d2d2eSraf $$ = declspec_AddDS($2, $1, &ep); 181*753d2d2eSraf declspec_Destroy($1); 182*753d2d2eSraf 183*753d2d2eSraf if (errstr == NULL) 184*753d2d2eSraf errstr = ep; 185*753d2d2eSraf } 186*753d2d2eSraf | storage_class_specifier 187*753d2d2eSraf | type_specifier declaration_specifiers 188*753d2d2eSraf { 189*753d2d2eSraf const char *ep; 190*753d2d2eSraf 191*753d2d2eSraf $$ = declspec_AddDS($2, $1, &ep); 192*753d2d2eSraf declspec_Destroy($1); 193*753d2d2eSraf 194*753d2d2eSraf if (errstr == NULL) 195*753d2d2eSraf errstr = ep; 196*753d2d2eSraf } 197*753d2d2eSraf | type_specifier 198*753d2d2eSraf | type_qualifier declaration_specifiers 199*753d2d2eSraf { 200*753d2d2eSraf const char *ep; 201*753d2d2eSraf 202*753d2d2eSraf $$ = declspec_AddDS($2, $1, &ep); 203*753d2d2eSraf declspec_Destroy($1); 204*753d2d2eSraf 205*753d2d2eSraf if (errstr == NULL) 206*753d2d2eSraf errstr = ep; 207*753d2d2eSraf } 208*753d2d2eSraf | type_qualifier 209*753d2d2eSraf ; 210*753d2d2eSraf 211*753d2d2eSraf storage_class_specifier 212*753d2d2eSraf : REGISTER 213*753d2d2eSraf { 214*753d2d2eSraf $$ = declspec_Init(SCS_REGISTER, NULL); 215*753d2d2eSraf } 216*753d2d2eSraf /* 217*753d2d2eSraf * XXX - Does not support any storage class specifier other than 218*753d2d2eSraf * register, and then only for function arguments. 219*753d2d2eSraf * 220*753d2d2eSraf | TYPEDEF 221*753d2d2eSraf { 222*753d2d2eSraf $$ = declspec_Init(SCS_TYPEDEF, NULL); 223*753d2d2eSraf } 224*753d2d2eSraf | EXTERN 225*753d2d2eSraf { 226*753d2d2eSraf $$ = declspec_Init(SCS_EXTERN, NULL); 227*753d2d2eSraf } 228*753d2d2eSraf | STATIC 229*753d2d2eSraf { 230*753d2d2eSraf $$ = declspec_Init(SCS_STATIC, NULL); 231*753d2d2eSraf } 232*753d2d2eSraf | AUTO 233*753d2d2eSraf { 234*753d2d2eSraf $$ = declspec_Init(SCS_AUTO, NULL); 235*753d2d2eSraf } 236*753d2d2eSraf */ 237*753d2d2eSraf ; 238*753d2d2eSraf 239*753d2d2eSraf type_specifier 240*753d2d2eSraf : VOID 241*753d2d2eSraf { 242*753d2d2eSraf $$ = declspec_Init(TS_VOID, NULL); 243*753d2d2eSraf atIDENT = 1; 244*753d2d2eSraf } 245*753d2d2eSraf | CHAR 246*753d2d2eSraf { 247*753d2d2eSraf $$ = declspec_Init(TS_CHAR, NULL); 248*753d2d2eSraf atIDENT = 1; 249*753d2d2eSraf } 250*753d2d2eSraf | SHORT 251*753d2d2eSraf { 252*753d2d2eSraf $$ = declspec_Init(TS_SHORT, NULL); 253*753d2d2eSraf atIDENT = 1; 254*753d2d2eSraf } 255*753d2d2eSraf | INT 256*753d2d2eSraf { 257*753d2d2eSraf $$ = declspec_Init(TS_INT, NULL); 258*753d2d2eSraf atIDENT = 1; 259*753d2d2eSraf } 260*753d2d2eSraf | LONG 261*753d2d2eSraf { 262*753d2d2eSraf $$ = declspec_Init(TS_LONG, NULL); 263*753d2d2eSraf atIDENT = 1; 264*753d2d2eSraf } 265*753d2d2eSraf | FLOAT 266*753d2d2eSraf { 267*753d2d2eSraf $$ = declspec_Init(TS_FLOAT, NULL); 268*753d2d2eSraf atIDENT = 1; 269*753d2d2eSraf } 270*753d2d2eSraf | DOUBLE 271*753d2d2eSraf { 272*753d2d2eSraf $$ = declspec_Init(TS_DOUBLE, NULL); 273*753d2d2eSraf atIDENT = 1; 274*753d2d2eSraf } 275*753d2d2eSraf | SIGNED 276*753d2d2eSraf { 277*753d2d2eSraf $$ = declspec_Init(TS_SIGNED, NULL); 278*753d2d2eSraf atIDENT = 1; 279*753d2d2eSraf } 280*753d2d2eSraf | UNSIGNED 281*753d2d2eSraf { 282*753d2d2eSraf $$ = declspec_Init(TS_UNSIGNED, NULL); 283*753d2d2eSraf atIDENT = 1; 284*753d2d2eSraf } 285*753d2d2eSraf | struct_or_union_specifier 286*753d2d2eSraf | enum_specifier 287*753d2d2eSraf | typedef_name 288*753d2d2eSraf ; 289*753d2d2eSraf 290*753d2d2eSraf typedef_name 291*753d2d2eSraf : TYPEDEF_NAME 292*753d2d2eSraf { 293*753d2d2eSraf $$ = declspec_Init(TS_TYPEDEF, $1); 294*753d2d2eSraf atIDENT = 1; 295*753d2d2eSraf free($1); 296*753d2d2eSraf } 297*753d2d2eSraf ; 298*753d2d2eSraf 299*753d2d2eSraf /* 300*753d2d2eSraf * The "restrict" keyword is new in the C99 standard. 301*753d2d2eSraf * It is type qualifier like const and volatile. 302*753d2d2eSraf * We are using "_RESTRICT_KYWD" in headers and source code so 303*753d2d2eSraf * it is easily turned on and off by various macros at compile time. 304*753d2d2eSraf * In order for the "restrict" keyword to be recognized you must 305*753d2d2eSraf * be using a C99 compliant compiler in its native mode. 306*753d2d2eSraf */ 307*753d2d2eSraf type_qualifier 308*753d2d2eSraf : CONST 309*753d2d2eSraf { 310*753d2d2eSraf $$ = declspec_Init(TQ_CONST, NULL); 311*753d2d2eSraf } 312*753d2d2eSraf | VOLATILE 313*753d2d2eSraf { 314*753d2d2eSraf $$ = declspec_Init(TQ_VOLATILE, NULL); 315*753d2d2eSraf } 316*753d2d2eSraf | RESTRICT 317*753d2d2eSraf { 318*753d2d2eSraf $$ = declspec_Init(TQ_RESTRICT, NULL); 319*753d2d2eSraf } 320*753d2d2eSraf | RESTRICT_KYWD 321*753d2d2eSraf { 322*753d2d2eSraf $$ = declspec_Init(TQ_RESTRICT_KYWD, NULL); 323*753d2d2eSraf } 324*753d2d2eSraf ; 325*753d2d2eSraf 326*753d2d2eSraf struct_or_union_specifier 327*753d2d2eSraf : struct_or_union { atIDENT = 1; } IDENTIFIER 328*753d2d2eSraf { 329*753d2d2eSraf $$ = declspec_Init($1, $3); 330*753d2d2eSraf free($3); 331*753d2d2eSraf } 332*753d2d2eSraf /* 333*753d2d2eSraf * XXX - struct or union definitions are not supported. It is generally 334*753d2d2eSraf * not done within the context of a function declaration (prototype) or 335*753d2d2eSraf * variable definition. 336*753d2d2eSraf 337*753d2d2eSraf | struct_or_union IDENTIFIER '{' struct_declaration_list '}' 338*753d2d2eSraf | struct_or_union '{' struct_declaration_list '}' 339*753d2d2eSraf */ 340*753d2d2eSraf ; 341*753d2d2eSraf 342*753d2d2eSraf struct_or_union 343*753d2d2eSraf : STRUCT 344*753d2d2eSraf { 345*753d2d2eSraf $$ = TS_STRUCT; 346*753d2d2eSraf } 347*753d2d2eSraf | UNION 348*753d2d2eSraf { 349*753d2d2eSraf $$ = TS_UNION; 350*753d2d2eSraf } 351*753d2d2eSraf ; 352*753d2d2eSraf 353*753d2d2eSraf init_declarator_list 354*753d2d2eSraf : init_declarator 355*753d2d2eSraf { 356*753d2d2eSraf $$ = $1; 357*753d2d2eSraf atIDENT = 1; 358*753d2d2eSraf } 359*753d2d2eSraf /* 360*753d2d2eSraf * XXX - Does not support a comma separated list of declarations or 361*753d2d2eSraf * definitions. Function prototypes or variable definitions must be 362*753d2d2eSraf * given as one per C statement. 363*753d2d2eSraf 364*753d2d2eSraf | init_declarator_list ',' init_declarator 365*753d2d2eSraf { 366*753d2d2eSraf $$ = decl_AddArg($1, $3); 367*753d2d2eSraf atIDENT = 1; 368*753d2d2eSraf } 369*753d2d2eSraf */ 370*753d2d2eSraf ; 371*753d2d2eSraf 372*753d2d2eSraf init_declarator 373*753d2d2eSraf : declarator 374*753d2d2eSraf /* 375*753d2d2eSraf * XXX - Initialization is not supported. 376*753d2d2eSraf 377*753d2d2eSraf | declarator '=' initializer 378*753d2d2eSraf */ 379*753d2d2eSraf ; 380*753d2d2eSraf 381*753d2d2eSraf 382*753d2d2eSraf enum_specifier 383*753d2d2eSraf : ENUM { atIDENT = 1; } IDENTIFIER 384*753d2d2eSraf { 385*753d2d2eSraf $$ = declspec_Init(TS_ENUM, $3); 386*753d2d2eSraf free($3); 387*753d2d2eSraf } 388*753d2d2eSraf /* 389*753d2d2eSraf * XXX - enumerator definition is not supported for the same reasons 390*753d2d2eSraf * struct|union definition is not supported. 391*753d2d2eSraf 392*753d2d2eSraf | ENUM IDENTIFIER '{' enumerator_list '}' 393*753d2d2eSraf | ENUM '{' enumerator_list '}' 394*753d2d2eSraf */ 395*753d2d2eSraf ; 396*753d2d2eSraf 397*753d2d2eSraf 398*753d2d2eSraf declarator 399*753d2d2eSraf : pointer direct_declarator 400*753d2d2eSraf { 401*753d2d2eSraf $$ = decl_addptr($2, $1); 402*753d2d2eSraf } 403*753d2d2eSraf | direct_declarator 404*753d2d2eSraf ; 405*753d2d2eSraf 406*753d2d2eSraf direct_declarator 407*753d2d2eSraf : IDENTIFIER 408*753d2d2eSraf { 409*753d2d2eSraf $$ = decl_SetName(decl_Construct(), $1); 410*753d2d2eSraf atIDENT = 0; 411*753d2d2eSraf free($1); 412*753d2d2eSraf } 413*753d2d2eSraf | '(' declarator ')' 414*753d2d2eSraf { 415*753d2d2eSraf $$ = $2; 416*753d2d2eSraf } 417*753d2d2eSraf | direct_declarator '[' constant_expression ']' 418*753d2d2eSraf { 419*753d2d2eSraf $$ = decl_addary($1, $3); 420*753d2d2eSraf free($3); 421*753d2d2eSraf } 422*753d2d2eSraf | direct_declarator '[' ']' 423*753d2d2eSraf { 424*753d2d2eSraf $$ = decl_addary($1, NULL); 425*753d2d2eSraf } 426*753d2d2eSraf | direct_declarator '(' parameter_type_list ')' 427*753d2d2eSraf { 428*753d2d2eSraf $$ = decl_addfun($1, $3); 429*753d2d2eSraf } 430*753d2d2eSraf | direct_declarator '(' ')' 431*753d2d2eSraf { 432*753d2d2eSraf $$ = decl_addfun($1, NULL); 433*753d2d2eSraf } 434*753d2d2eSraf ; 435*753d2d2eSraf 436*753d2d2eSraf pointer 437*753d2d2eSraf : '*' type_qualifier_list 438*753d2d2eSraf { 439*753d2d2eSraf $$ = type_SetPtr(type_Construct(), ($2)->ds_stt); 440*753d2d2eSraf declspec_Destroy($2); 441*753d2d2eSraf } 442*753d2d2eSraf | '*' 443*753d2d2eSraf { 444*753d2d2eSraf $$ = type_SetPtr(type_Construct(), TQ_NONE); 445*753d2d2eSraf } 446*753d2d2eSraf | '*' type_qualifier_list pointer 447*753d2d2eSraf { 448*753d2d2eSraf type_t *tp = type_Construct(); 449*753d2d2eSraf 450*753d2d2eSraf type_SetPtr(tp, ($2)->ds_stt); 451*753d2d2eSraf declspec_Destroy($2); 452*753d2d2eSraf $$ = type_AddTail($3, tp); 453*753d2d2eSraf } 454*753d2d2eSraf | '*' pointer 455*753d2d2eSraf { 456*753d2d2eSraf type_t *tp = type_Construct(); 457*753d2d2eSraf 458*753d2d2eSraf type_SetPtr(tp, TQ_NONE); 459*753d2d2eSraf $$ = type_AddTail($2, tp); 460*753d2d2eSraf } 461*753d2d2eSraf ; 462*753d2d2eSraf 463*753d2d2eSraf type_qualifier_list 464*753d2d2eSraf : type_qualifier 465*753d2d2eSraf | type_qualifier_list type_qualifier 466*753d2d2eSraf { 467*753d2d2eSraf const char *ep; 468*753d2d2eSraf 469*753d2d2eSraf /* XXX - ignore any error */ 470*753d2d2eSraf $$ = declspec_AddDS($1, $2, &ep); 471*753d2d2eSraf declspec_Destroy($2); 472*753d2d2eSraf } 473*753d2d2eSraf ; 474*753d2d2eSraf 475*753d2d2eSraf parameter_type_list 476*753d2d2eSraf : parameter_list 477*753d2d2eSraf | parameter_list ',' ELLIPSIS 478*753d2d2eSraf { 479*753d2d2eSraf $$ = decl_addellipsis($1); 480*753d2d2eSraf } 481*753d2d2eSraf ; 482*753d2d2eSraf 483*753d2d2eSraf parameter_list 484*753d2d2eSraf : parameter_declaration 485*753d2d2eSraf { 486*753d2d2eSraf const char *sp = type_Verify($1->d_type); 487*753d2d2eSraf 488*753d2d2eSraf if (sp) 489*753d2d2eSraf errstr = sp; 490*753d2d2eSraf 491*753d2d2eSraf $$ = $1; 492*753d2d2eSraf atIDENT = 0; 493*753d2d2eSraf } 494*753d2d2eSraf | parameter_list ',' parameter_declaration 495*753d2d2eSraf { 496*753d2d2eSraf const char *sp = type_Verify($3->d_type); 497*753d2d2eSraf 498*753d2d2eSraf if (sp) 499*753d2d2eSraf errstr = sp; 500*753d2d2eSraf 501*753d2d2eSraf $$ = decl_AddArg($1, $3); 502*753d2d2eSraf atIDENT = 0; 503*753d2d2eSraf } 504*753d2d2eSraf ; 505*753d2d2eSraf 506*753d2d2eSraf parameter_declaration 507*753d2d2eSraf : declaration_specifiers declarator 508*753d2d2eSraf { 509*753d2d2eSraf const char *ep; 510*753d2d2eSraf 511*753d2d2eSraf $$ = decl_AddDS($2, $1, &ep); 512*753d2d2eSraf declspec_Destroy($1); 513*753d2d2eSraf 514*753d2d2eSraf if (errstr == NULL) 515*753d2d2eSraf errstr = ep; 516*753d2d2eSraf } 517*753d2d2eSraf | declaration_specifiers abstract_declarator 518*753d2d2eSraf { 519*753d2d2eSraf const char *ep; 520*753d2d2eSraf 521*753d2d2eSraf $$ = decl_AddDS($2, $1, &ep); 522*753d2d2eSraf declspec_Destroy($1); 523*753d2d2eSraf 524*753d2d2eSraf if (errstr == NULL) 525*753d2d2eSraf errstr = ep; 526*753d2d2eSraf } 527*753d2d2eSraf | declaration_specifiers 528*753d2d2eSraf { 529*753d2d2eSraf const char *ep; 530*753d2d2eSraf 531*753d2d2eSraf $$ = decl_AddDS(decl_Construct(), $1, &ep); 532*753d2d2eSraf declspec_Destroy($1); 533*753d2d2eSraf 534*753d2d2eSraf if (errstr == NULL) 535*753d2d2eSraf errstr = ep; 536*753d2d2eSraf } 537*753d2d2eSraf ; 538*753d2d2eSraf 539*753d2d2eSraf abstract_declarator 540*753d2d2eSraf : pointer 541*753d2d2eSraf { 542*753d2d2eSraf $$ = decl_addptr(decl_Construct(), $1); 543*753d2d2eSraf } 544*753d2d2eSraf | pointer direct_abstract_declarator 545*753d2d2eSraf { 546*753d2d2eSraf $$ = decl_addptr($2, $1); 547*753d2d2eSraf } 548*753d2d2eSraf | direct_abstract_declarator 549*753d2d2eSraf ; 550*753d2d2eSraf 551*753d2d2eSraf direct_abstract_declarator 552*753d2d2eSraf : '(' abstract_declarator ')' 553*753d2d2eSraf { 554*753d2d2eSraf $$ = $2; 555*753d2d2eSraf } 556*753d2d2eSraf | direct_abstract_declarator '[' constant_expression ']' 557*753d2d2eSraf { 558*753d2d2eSraf $$ = decl_addary($1, $3); 559*753d2d2eSraf free($3); 560*753d2d2eSraf } 561*753d2d2eSraf | '[' constant_expression ']' 562*753d2d2eSraf { 563*753d2d2eSraf $$ = decl_addary(decl_Construct(), $2); 564*753d2d2eSraf free($2); 565*753d2d2eSraf } 566*753d2d2eSraf | direct_abstract_declarator '[' ']' 567*753d2d2eSraf { 568*753d2d2eSraf $$ = decl_addary($1, NULL); 569*753d2d2eSraf } 570*753d2d2eSraf | '[' ']' 571*753d2d2eSraf { 572*753d2d2eSraf $$ = decl_addary(decl_Construct(), NULL); 573*753d2d2eSraf } 574*753d2d2eSraf | direct_abstract_declarator '(' parameter_type_list ')' 575*753d2d2eSraf { 576*753d2d2eSraf $$ = decl_addfun($1, $3); 577*753d2d2eSraf } 578*753d2d2eSraf | '(' parameter_type_list ')' 579*753d2d2eSraf { 580*753d2d2eSraf $$ = decl_addfun(decl_Construct(), $2); 581*753d2d2eSraf } 582*753d2d2eSraf | direct_abstract_declarator '(' ')' 583*753d2d2eSraf { 584*753d2d2eSraf $$ = decl_addfun($1, NULL); 585*753d2d2eSraf } 586*753d2d2eSraf | '(' ')' 587*753d2d2eSraf { 588*753d2d2eSraf $$ = decl_addfun(decl_Construct(), NULL); 589*753d2d2eSraf } 590*753d2d2eSraf ; 591*753d2d2eSraf 592*753d2d2eSraf /* 593*753d2d2eSraf * XXX - General case constant expressions are not supported. It would 594*753d2d2eSraf * be easy to implement (for the most part), but there are no cases to 595*753d2d2eSraf * date that require such a facility. The grammar does allow an 596*753d2d2eSraf * identifier (or typedef name) to be used since the prototype is not 597*753d2d2eSraf * processed by CPP. The only integer constant that is supported is 598*753d2d2eSraf * decimal. 599*753d2d2eSraf */ 600*753d2d2eSraf 601*753d2d2eSraf constant_expression 602*753d2d2eSraf : INTEGER 603*753d2d2eSraf | IDENTIFIER 604*753d2d2eSraf | TYPEDEF_NAME 605*753d2d2eSraf ; 606*753d2d2eSraf 607*753d2d2eSraf %% 608*753d2d2eSraf 609*753d2d2eSraf /* Data Declarations */ 610*753d2d2eSraf 611*753d2d2eSraf typedef struct { 612*753d2d2eSraf char *name; 613*753d2d2eSraf int token; 614*753d2d2eSraf stt_t stt; 615*753d2d2eSraf } keyword_t; 616*753d2d2eSraf 617*753d2d2eSraf typedef struct { 618*753d2d2eSraf stt_t s_stt; 619*753d2d2eSraf char *s_str; 620*753d2d2eSraf } sttpair_t; 621*753d2d2eSraf 622*753d2d2eSraf /* External Declarations */ 623*753d2d2eSraf 624*753d2d2eSraf static const keyword_t *lookup_keyword(const char *); 625*753d2d2eSraf static const char *lookup_sttpair(stt_t); 626*753d2d2eSraf static int getch(void); 627*753d2d2eSraf static void ungetch(int); 628*753d2d2eSraf static void skipwhitespace(void); 629*753d2d2eSraf static int lookahead(int); 630*753d2d2eSraf static void skipcomment(void); 631*753d2d2eSraf 632*753d2d2eSraf /* External Definitions */ 633*753d2d2eSraf 634*753d2d2eSraf static char *input = NULL; /* current place in the input stream */ 635*753d2d2eSraf /* at point in stream were identifier is expected */ 636*753d2d2eSraf static int atIDENT = 0; 637*753d2d2eSraf static decl_t *protop = NULL; /* pointer to prototype */ 638*753d2d2eSraf static const char *errstr = NULL; /* error message */ 639*753d2d2eSraf 640*753d2d2eSraf /* 641*753d2d2eSraf * lookup_keyword - Given a string, return the keyword_t or NULL. 642*753d2d2eSraf */ 643*753d2d2eSraf 644*753d2d2eSraf static const keyword_t * 645*753d2d2eSraf lookup_keyword(const char *name) { 646*753d2d2eSraf static const keyword_t keytbl[] = { 647*753d2d2eSraf { "register", REGISTER, SCS_REGISTER }, 648*753d2d2eSraf #if UNSUPPORTED 649*753d2d2eSraf { "typedef", TYPEDEF, SCS_TYPEDEF }, 650*753d2d2eSraf { "auto", AUTO, SCS_AUTO }, 651*753d2d2eSraf { "static", STATIC, SCS_STATIC }, 652*753d2d2eSraf { "extern", EXTERN, SCS_EXTERN }, 653*753d2d2eSraf #endif /* UNSUPPORTED */ 654*753d2d2eSraf { "void", VOID, TS_VOID }, 655*753d2d2eSraf { "char", CHAR, TS_CHAR }, 656*753d2d2eSraf { "short", SHORT, TS_SHORT }, 657*753d2d2eSraf { "int", INT, TS_INT }, 658*753d2d2eSraf { "long", LONG, TS_LONG }, 659*753d2d2eSraf { "float", FLOAT, TS_FLOAT }, 660*753d2d2eSraf { "double", DOUBLE, TS_DOUBLE }, 661*753d2d2eSraf { "signed", SIGNED, TS_SIGNED }, 662*753d2d2eSraf { "unsigned", UNSIGNED, TS_UNSIGNED }, 663*753d2d2eSraf { "struct", STRUCT, TS_STRUCT }, 664*753d2d2eSraf { "union", UNION, TS_UNION }, 665*753d2d2eSraf { "enum", ENUM, TS_ENUM }, 666*753d2d2eSraf 667*753d2d2eSraf { "const", CONST, TQ_CONST }, 668*753d2d2eSraf { "volatile", VOLATILE, TQ_VOLATILE }, 669*753d2d2eSraf { "restrict", RESTRICT, TQ_RESTRICT }, 670*753d2d2eSraf { "_RESTRICT_KYWD",RESTRICT_KYWD, TQ_RESTRICT_KYWD}, 671*753d2d2eSraf }; 672*753d2d2eSraf #define NKEYWORD (sizeof (keytbl)/sizeof (keyword_t)) 673*753d2d2eSraf 674*753d2d2eSraf int i; 675*753d2d2eSraf 676*753d2d2eSraf for (i = 0; i < NKEYWORD; ++i) { 677*753d2d2eSraf char *s = keytbl[i].name; 678*753d2d2eSraf 679*753d2d2eSraf if ((*s == *name) && (strcmp(s, name) == 0)) 680*753d2d2eSraf return (&keytbl[i]); 681*753d2d2eSraf } 682*753d2d2eSraf 683*753d2d2eSraf return (NULL); 684*753d2d2eSraf } 685*753d2d2eSraf 686*753d2d2eSraf /* 687*753d2d2eSraf * lookup_sttpair - Given an stt_t return a string or NULL. 688*753d2d2eSraf * 689*753d2d2eSraf */ 690*753d2d2eSraf 691*753d2d2eSraf static const char * 692*753d2d2eSraf lookup_sttpair(stt_t s) { 693*753d2d2eSraf /* valid type specifier combinations */ 694*753d2d2eSraf static const sttpair_t stttbl[] = { 695*753d2d2eSraf { TS_VOID, "void" }, 696*753d2d2eSraf { TS_CHAR, "char" }, 697*753d2d2eSraf { TS_SIGNED | TS_CHAR, "signed char" }, 698*753d2d2eSraf { TS_UNSIGNED | TS_CHAR, "unsigned char" }, 699*753d2d2eSraf { TS_SHORT, "short" }, 700*753d2d2eSraf { TS_SIGNED | TS_SHORT, "signed short" }, 701*753d2d2eSraf { TS_SHORT | TS_INT, "short int" }, 702*753d2d2eSraf { TS_SIGNED | TS_SHORT | TS_INT, 703*753d2d2eSraf "signed short int" }, 704*753d2d2eSraf { TS_UNSIGNED | TS_SHORT, 705*753d2d2eSraf "unsigned short" }, 706*753d2d2eSraf { TS_UNSIGNED | TS_SHORT | TS_INT, 707*753d2d2eSraf "unsigned short int" }, 708*753d2d2eSraf { TS_INT, "int" }, 709*753d2d2eSraf { TS_SIGNED, "signed" }, 710*753d2d2eSraf { TS_SIGNED | TS_INT, "signed int" }, 711*753d2d2eSraf { TS_NO_TS, "" }, 712*753d2d2eSraf { TS_UNSIGNED, "unsigned" }, 713*753d2d2eSraf { TS_UNSIGNED | TS_INT, "unsigned int" }, 714*753d2d2eSraf { TS_LONG, "long" }, 715*753d2d2eSraf { TS_SIGNED | TS_LONG, "signed long" }, 716*753d2d2eSraf { TS_LONG | TS_INT, "long int" }, 717*753d2d2eSraf { TS_SIGNED | TS_LONG | TS_INT, 718*753d2d2eSraf "signed long int" }, 719*753d2d2eSraf { TS_UNSIGNED | TS_LONG, "unsigned long" }, 720*753d2d2eSraf { TS_UNSIGNED | TS_LONG | TS_INT, 721*753d2d2eSraf "unsigned long int" }, 722*753d2d2eSraf { TS_FLOAT, "float" }, 723*753d2d2eSraf { TS_DOUBLE, "double" }, 724*753d2d2eSraf { TS_LONG | TS_DOUBLE, "long double" }, 725*753d2d2eSraf { TS_STRUCT, "struct" }, 726*753d2d2eSraf { TS_UNION, "union" }, 727*753d2d2eSraf { TS_ENUM, "enum" }, 728*753d2d2eSraf { TS_TYPEDEF, "" }, 729*753d2d2eSraf /* non-ANSI type: long long */ 730*753d2d2eSraf { TS_LONGLONG, "long long" }, 731*753d2d2eSraf { TS_LONGLONG | TS_INT, "long long int" }, 732*753d2d2eSraf { TS_SIGNED | TS_LONGLONG, 733*753d2d2eSraf "signed long long" }, 734*753d2d2eSraf { TS_UNSIGNED | TS_LONGLONG, 735*753d2d2eSraf "unsigned long long" }, 736*753d2d2eSraf { TS_SIGNED | TS_LONGLONG | TS_INT, 737*753d2d2eSraf "signed long long int" }, 738*753d2d2eSraf { TS_UNSIGNED | TS_LONGLONG | TS_INT, 739*753d2d2eSraf "unsigned long long int" }, 740*753d2d2eSraf }; 741*753d2d2eSraf 742*753d2d2eSraf #define NDECLSPEC (sizeof (stttbl)/sizeof (sttpair_t)) 743*753d2d2eSraf 744*753d2d2eSraf int i; 745*753d2d2eSraf 746*753d2d2eSraf for (i = 0; i < NDECLSPEC; ++i) 747*753d2d2eSraf if (s == stttbl[i].s_stt) 748*753d2d2eSraf return (stttbl[i].s_str); 749*753d2d2eSraf 750*753d2d2eSraf return (NULL); 751*753d2d2eSraf } 752*753d2d2eSraf 753*753d2d2eSraf /* 754*753d2d2eSraf * yylex - return next token from the the input stream. 755*753d2d2eSraf * 756*753d2d2eSraf * The lexical analyzer does not recognize all possible C lexical 757*753d2d2eSraf * elements. It only recognizes those associated with function 758*753d2d2eSraf * declarations (read: prototypes) and data definitions. 759*753d2d2eSraf */ 760*753d2d2eSraf 761*753d2d2eSraf static int 762*753d2d2eSraf yylex(void) { 763*753d2d2eSraf char buf[BUFSIZ]; /* string version of token */ 764*753d2d2eSraf int c; 765*753d2d2eSraf int i = 0; 766*753d2d2eSraf 767*753d2d2eSraf restart: 768*753d2d2eSraf skipwhitespace(); 769*753d2d2eSraf 770*753d2d2eSraf switch (c = getch()) { 771*753d2d2eSraf case '/': 772*753d2d2eSraf if (lookahead('*')) { 773*753d2d2eSraf skipcomment(); 774*753d2d2eSraf goto restart; 775*753d2d2eSraf } 776*753d2d2eSraf 777*753d2d2eSraf case '.': 778*753d2d2eSraf if (lookahead('.')) { 779*753d2d2eSraf if (lookahead('.')) 780*753d2d2eSraf return (ELLIPSIS); 781*753d2d2eSraf } 782*753d2d2eSraf 783*753d2d2eSraf case EOF: 784*753d2d2eSraf case '(': 785*753d2d2eSraf case ')': 786*753d2d2eSraf case ',': 787*753d2d2eSraf case '[': 788*753d2d2eSraf case ']': 789*753d2d2eSraf case ';': 790*753d2d2eSraf case '*': 791*753d2d2eSraf return (c); 792*753d2d2eSraf 793*753d2d2eSraf default: 794*753d2d2eSraf if ((c == '_') || isalpha(c)) { 795*753d2d2eSraf const keyword_t *kp; 796*753d2d2eSraf 797*753d2d2eSraf do { 798*753d2d2eSraf buf[i++] = c; 799*753d2d2eSraf c = getch(); 800*753d2d2eSraf } while ((c == '_') || isalnum(c)); 801*753d2d2eSraf 802*753d2d2eSraf ungetch(c); 803*753d2d2eSraf 804*753d2d2eSraf buf[i] = '\0'; 805*753d2d2eSraf 806*753d2d2eSraf if ((kp = lookup_keyword(buf)) != NULL) { 807*753d2d2eSraf yylval.stt_val = kp->stt; 808*753d2d2eSraf return (kp->token); 809*753d2d2eSraf } else { 810*753d2d2eSraf yylval.s_val = strdup(buf); 811*753d2d2eSraf 812*753d2d2eSraf return ((atIDENT) ? IDENTIFIER : TYPEDEF_NAME); 813*753d2d2eSraf } 814*753d2d2eSraf } else if (isdigit(c)) { 815*753d2d2eSraf do { 816*753d2d2eSraf buf[i++] = c; 817*753d2d2eSraf } while (isdigit(c = getch())); 818*753d2d2eSraf 819*753d2d2eSraf ungetch(c); 820*753d2d2eSraf 821*753d2d2eSraf buf[i] = '\0'; 822*753d2d2eSraf yylval.s_val = strdup(buf); 823*753d2d2eSraf 824*753d2d2eSraf return (INTEGER); 825*753d2d2eSraf } else 826*753d2d2eSraf return (c); 827*753d2d2eSraf } 828*753d2d2eSraf /* NOTREACHED */ 829*753d2d2eSraf } 830*753d2d2eSraf 831*753d2d2eSraf /* getch - return the next character from the input stream. */ 832*753d2d2eSraf 833*753d2d2eSraf static int 834*753d2d2eSraf getch(void) { 835*753d2d2eSraf int c; 836*753d2d2eSraf 837*753d2d2eSraf if ((c = *input) == '\0') 838*753d2d2eSraf c = EOF; 839*753d2d2eSraf else /* only advance on non-NULL */ 840*753d2d2eSraf input++; 841*753d2d2eSraf 842*753d2d2eSraf return (c); 843*753d2d2eSraf } 844*753d2d2eSraf 845*753d2d2eSraf /* ungetch - return a character to the input stream. */ 846*753d2d2eSraf 847*753d2d2eSraf static void 848*753d2d2eSraf ungetch(int c) { 849*753d2d2eSraf *(--input) = c; 850*753d2d2eSraf } 851*753d2d2eSraf 852*753d2d2eSraf /* skipwhitespace - skip over whitespace in the input stream. */ 853*753d2d2eSraf 854*753d2d2eSraf static void 855*753d2d2eSraf skipwhitespace(void) { 856*753d2d2eSraf int c; 857*753d2d2eSraf 858*753d2d2eSraf while (isspace(c = getch())) 859*753d2d2eSraf ; 860*753d2d2eSraf 861*753d2d2eSraf ungetch(c); 862*753d2d2eSraf } 863*753d2d2eSraf 864*753d2d2eSraf /* skipcomment - scan ahead to the next end of comment. */ 865*753d2d2eSraf 866*753d2d2eSraf static void 867*753d2d2eSraf skipcomment(void) { 868*753d2d2eSraf loop { 869*753d2d2eSraf int c; 870*753d2d2eSraf 871*753d2d2eSraf switch (c = getch()) { 872*753d2d2eSraf case EOF: 873*753d2d2eSraf return; 874*753d2d2eSraf 875*753d2d2eSraf case '*': 876*753d2d2eSraf if (lookahead('/')) 877*753d2d2eSraf return; 878*753d2d2eSraf } 879*753d2d2eSraf } 880*753d2d2eSraf /* NOTREACHED */ 881*753d2d2eSraf } 882*753d2d2eSraf 883*753d2d2eSraf /* lookahead - does next character match 'c'? */ 884*753d2d2eSraf 885*753d2d2eSraf static int 886*753d2d2eSraf lookahead(int c) { 887*753d2d2eSraf int ch = getch(); 888*753d2d2eSraf int match; 889*753d2d2eSraf 890*753d2d2eSraf if (!(match = (ch == c))) 891*753d2d2eSraf ungetch(ch); 892*753d2d2eSraf 893*753d2d2eSraf return (match); 894*753d2d2eSraf } 895*753d2d2eSraf 896*753d2d2eSraf /* putNtabs - write N '\t' to standard output. */ 897*753d2d2eSraf 898*753d2d2eSraf #if defined(DEBUG) 899*753d2d2eSraf 900*753d2d2eSraf static void 901*753d2d2eSraf putNTabs(int n) { 902*753d2d2eSraf int i; 903*753d2d2eSraf 904*753d2d2eSraf for (i = 0; i < n; ++i) 905*753d2d2eSraf putchar('\t'); 906*753d2d2eSraf } 907*753d2d2eSraf #endif /* DEBUG */ 908*753d2d2eSraf 909*753d2d2eSraf /* D E C L A R A T I O N S P E C I F I E R S */ 910*753d2d2eSraf 911*753d2d2eSraf /* 912*753d2d2eSraf * Declaration specifiers encode storage class, type specifier and type 913*753d2d2eSraf * qualifier information. This includes any identifiers associated with 914*753d2d2eSraf * struct, union or enum declarations. Typedef names are also encoded 915*753d2d2eSraf * in declaration specifiers. 916*753d2d2eSraf */ 917*753d2d2eSraf 918*753d2d2eSraf /* declspec_Construct - allocate and initialize a declspec_t. */ 919*753d2d2eSraf 920*753d2d2eSraf static decl_spec_t * 921*753d2d2eSraf declspec_Construct(void) { 922*753d2d2eSraf decl_spec_t *dsp = malloc(sizeof (decl_spec_t)); 923*753d2d2eSraf 924*753d2d2eSraf assert(dsp != NULL); 925*753d2d2eSraf dsp->ds_stt = SCS_NONE | TS_NO_TS | TQ_NONE; 926*753d2d2eSraf dsp->ds_id = NULL; 927*753d2d2eSraf #if defined(MEM_DEBUG) 928*753d2d2eSraf ++declspec_Construct_calls; 929*753d2d2eSraf #endif 930*753d2d2eSraf return (dsp); 931*753d2d2eSraf } 932*753d2d2eSraf 933*753d2d2eSraf /* declspec_Destroy - free a declspec_t. */ 934*753d2d2eSraf 935*753d2d2eSraf static void 936*753d2d2eSraf declspec_Destroy(decl_spec_t *dsp) { 937*753d2d2eSraf free(dsp->ds_id); 938*753d2d2eSraf free(dsp); 939*753d2d2eSraf #if defined(MEM_DEBUG) 940*753d2d2eSraf --declspec_Construct_calls; 941*753d2d2eSraf #endif 942*753d2d2eSraf } 943*753d2d2eSraf 944*753d2d2eSraf /* 945*753d2d2eSraf * declspec_Init - allocate and initialize a declspec_t given an 946*753d2d2eSraf * stt_t and identifier. 947*753d2d2eSraf * 948*753d2d2eSraf * Note: 949*753d2d2eSraf * 1) identifier can be NULL. 950*753d2d2eSraf * 2) errors resulting in the stt_t and identifier are ignored. 951*753d2d2eSraf */ 952*753d2d2eSraf 953*753d2d2eSraf static decl_spec_t * 954*753d2d2eSraf declspec_Init(stt_t s, char *tagp) { 955*753d2d2eSraf const char *p; 956*753d2d2eSraf decl_spec_t *dsp = declspec_Construct(); 957*753d2d2eSraf decl_spec_t tmp; 958*753d2d2eSraf 959*753d2d2eSraf tmp.ds_stt = s; 960*753d2d2eSraf tmp.ds_id = tagp; 961*753d2d2eSraf 962*753d2d2eSraf declspec_AddDS(dsp, &tmp, &p); /* XXX ignore any error */ 963*753d2d2eSraf 964*753d2d2eSraf return (dsp); 965*753d2d2eSraf } 966*753d2d2eSraf 967*753d2d2eSraf /* 968*753d2d2eSraf * declspec_VerifySTT - verify that the two given stt_t can be combined. 969*753d2d2eSraf * 970*753d2d2eSraf * Note: 971*753d2d2eSraf * 1) The return value is a const char *, non-NULL to indicate an error. 972*753d2d2eSraf */ 973*753d2d2eSraf 974*753d2d2eSraf static char * 975*753d2d2eSraf declspec_VerifySTT(stt_t s1, stt_t s2) { 976*753d2d2eSraf stt_t result; 977*753d2d2eSraf 978*753d2d2eSraf if ((s1 | s2) != (s1 ^ s2)) 979*753d2d2eSraf return ("attempt to add declaration specifier " 980*753d2d2eSraf "that is already present"); 981*753d2d2eSraf 982*753d2d2eSraf result = (s1 | s2) & TS_MASK; 983*753d2d2eSraf 984*753d2d2eSraf if (lookup_sttpair(result) == NULL) { 985*753d2d2eSraf if (STT_isbasic(result) && STT_isderived(result)) 986*753d2d2eSraf return ("attempt to combine basic and " 987*753d2d2eSraf "derived types"); 988*753d2d2eSraf 989*753d2d2eSraf if (STT_isvoid(result) && 990*753d2d2eSraf (STT_isbasic(result) || STT_isderived(result))) 991*753d2d2eSraf return ("attempt to combine void with " 992*753d2d2eSraf "other type specifiers"); 993*753d2d2eSraf 994*753d2d2eSraf if (STT_isfloat(result) && STT_isint(result)) 995*753d2d2eSraf return ("attempt to combine floating and " 996*753d2d2eSraf "integer type specifiers"); 997*753d2d2eSraf 998*753d2d2eSraf if (STT_ischar(result) && STT_isint(result)) 999*753d2d2eSraf return ("attempt to combine character and " 1000*753d2d2eSraf "integer type specifiers"); 1001*753d2d2eSraf 1002*753d2d2eSraf if (STT_has_explicit_sign(result) && 1003*753d2d2eSraf (STT_isfloat(result) || STT_isderived(result))) 1004*753d2d2eSraf return ("attempt to combine signed or " 1005*753d2d2eSraf "unsigned with float or derived type"); 1006*753d2d2eSraf 1007*753d2d2eSraf return ("invalid declaration specifier"); 1008*753d2d2eSraf } 1009*753d2d2eSraf 1010*753d2d2eSraf return (NULL); 1011*753d2d2eSraf } 1012*753d2d2eSraf 1013*753d2d2eSraf /* 1014*753d2d2eSraf * declspec_AddSTT - add an stt_t to a decl_spec_t. 1015*753d2d2eSraf * 1016*753d2d2eSraf * Note: 1017*753d2d2eSraf * 1) The "long long" type is handled here. 1018*753d2d2eSraf * If both stt_t include TS_LONG then this is an attempt to use 1019*753d2d2eSraf * "long long". The TS_LONG is cleared from the s1 and s2 and 1020*753d2d2eSraf * then TS_LONGLONG is added to s2. The resulting s1 and s2 are 1021*753d2d2eSraf * passed to declspec_VerifySTT to determine if the result is valid. 1022*753d2d2eSraf * 1023*753d2d2eSraf * 2) This method of handling "long long" does detect the case of 1024*753d2d2eSraf * "long double long" and all it's variant forms. 1025*753d2d2eSraf */ 1026*753d2d2eSraf 1027*753d2d2eSraf static decl_spec_t * 1028*753d2d2eSraf declspec_AddSTT(decl_spec_t *dsp, stt_t s2, const char **err) { 1029*753d2d2eSraf stt_t s1 = dsp->ds_stt; 1030*753d2d2eSraf 1031*753d2d2eSraf /* non-ANSI type: long long */ 1032*753d2d2eSraf if ((s1 & TS_LONG) && (s2 & TS_LONG)) { 1033*753d2d2eSraf s1 &= ~(TS_LONG); 1034*753d2d2eSraf dsp->ds_stt = s1; 1035*753d2d2eSraf s2 &= ~(TS_LONG); 1036*753d2d2eSraf s2 |= TS_LONGLONG; 1037*753d2d2eSraf } 1038*753d2d2eSraf 1039*753d2d2eSraf if ((*err = declspec_VerifySTT(s1, s2)) == NULL) 1040*753d2d2eSraf dsp->ds_stt |= s2; 1041*753d2d2eSraf 1042*753d2d2eSraf return (dsp); 1043*753d2d2eSraf } 1044*753d2d2eSraf 1045*753d2d2eSraf /* 1046*753d2d2eSraf * declpec_AddDS - add a decl_spec_t to an existing decl_spec_t. 1047*753d2d2eSraf */ 1048*753d2d2eSraf 1049*753d2d2eSraf static decl_spec_t * 1050*753d2d2eSraf declspec_AddDS(decl_spec_t *dsp, decl_spec_t *tsp, const char **err) { 1051*753d2d2eSraf declspec_AddSTT(dsp, tsp->ds_stt, err); 1052*753d2d2eSraf 1053*753d2d2eSraf if ((*err == NULL) && tsp->ds_id) { 1054*753d2d2eSraf free(dsp->ds_id); 1055*753d2d2eSraf dsp->ds_id = strdup(tsp->ds_id); 1056*753d2d2eSraf 1057*753d2d2eSraf assert(dsp->ds_id != NULL); 1058*753d2d2eSraf } 1059*753d2d2eSraf 1060*753d2d2eSraf return (dsp); 1061*753d2d2eSraf } 1062*753d2d2eSraf 1063*753d2d2eSraf /* 1064*753d2d2eSraf * declspec_GetSTT - return the stt_t within a decl_spec_t. 1065*753d2d2eSraf */ 1066*753d2d2eSraf 1067*753d2d2eSraf static stt_t 1068*753d2d2eSraf declspec_GetSTT(decl_spec_t *dsp) { 1069*753d2d2eSraf return (dsp->ds_stt); 1070*753d2d2eSraf } 1071*753d2d2eSraf 1072*753d2d2eSraf /* 1073*753d2d2eSraf * declspec_GetTag - return the identifier within a decl_spec_t. 1074*753d2d2eSraf */ 1075*753d2d2eSraf 1076*753d2d2eSraf static char * 1077*753d2d2eSraf declspec_GetTag(decl_spec_t *dsp) { 1078*753d2d2eSraf return (dsp->ds_id); 1079*753d2d2eSraf } 1080*753d2d2eSraf 1081*753d2d2eSraf /* 1082*753d2d2eSraf * declspec_ToString - convert a decl_spec_t into a string. 1083*753d2d2eSraf * 1084*753d2d2eSraf * Note: 1085*753d2d2eSraf * 1) The form of the resulting string is always the same, i.e. 1086*753d2d2eSraf * 1087*753d2d2eSraf * [register] [type_specifier] [const] [volatile] 1088*753d2d2eSraf * 1089*753d2d2eSraf * dsp must be correct 1090*753d2d2eSraf * 1091*753d2d2eSraf */ 1092*753d2d2eSraf 1093*753d2d2eSraf char * 1094*753d2d2eSraf declspec_ToString(char *bufp, decl_spec_t *dsp) { 1095*753d2d2eSraf const char *s; 1096*753d2d2eSraf int something = 0; 1097*753d2d2eSraf 1098*753d2d2eSraf *bufp = '\0'; 1099*753d2d2eSraf 1100*753d2d2eSraf /* storage class specifier */ 1101*753d2d2eSraf switch (dsp->ds_stt & SCS_MASK) { 1102*753d2d2eSraf case SCS_REGISTER: 1103*753d2d2eSraf strcat(bufp, "register"); 1104*753d2d2eSraf something = 1; 1105*753d2d2eSraf break; 1106*753d2d2eSraf } 1107*753d2d2eSraf 1108*753d2d2eSraf s = lookup_sttpair(dsp->ds_stt & TS_MASK); 1109*753d2d2eSraf 1110*753d2d2eSraf /* type specifier */ 1111*753d2d2eSraf switch (dsp->ds_stt & TS_MASK) { 1112*753d2d2eSraf case TS_STRUCT: 1113*753d2d2eSraf case TS_UNION: 1114*753d2d2eSraf case TS_ENUM: 1115*753d2d2eSraf if (something) 1116*753d2d2eSraf strcat(bufp, " "); 1117*753d2d2eSraf 1118*753d2d2eSraf strcat(bufp, s); 1119*753d2d2eSraf strcat(bufp, " "); 1120*753d2d2eSraf strcat(bufp, dsp->ds_id); 1121*753d2d2eSraf break; 1122*753d2d2eSraf 1123*753d2d2eSraf case TS_TYPEDEF: 1124*753d2d2eSraf if (something) 1125*753d2d2eSraf strcat(bufp, " "); 1126*753d2d2eSraf 1127*753d2d2eSraf strcat(bufp, dsp->ds_id); 1128*753d2d2eSraf break; 1129*753d2d2eSraf 1130*753d2d2eSraf default: 1131*753d2d2eSraf if (something) 1132*753d2d2eSraf strcat(bufp, " "); 1133*753d2d2eSraf 1134*753d2d2eSraf strcat(bufp, s); 1135*753d2d2eSraf break; 1136*753d2d2eSraf } 1137*753d2d2eSraf 1138*753d2d2eSraf if (s) 1139*753d2d2eSraf something = 1; 1140*753d2d2eSraf 1141*753d2d2eSraf if (something && (dsp->ds_stt & TQ_MASK)) 1142*753d2d2eSraf strcat(bufp, " "); 1143*753d2d2eSraf 1144*753d2d2eSraf if (dsp->ds_stt & TQ_CONST) /* type qualifier */ 1145*753d2d2eSraf strcat(bufp, "const"); 1146*753d2d2eSraf 1147*753d2d2eSraf if (dsp->ds_stt & TQ_VOLATILE) { 1148*753d2d2eSraf if (dsp->ds_stt & TQ_CONST) 1149*753d2d2eSraf strcat(bufp, " "); 1150*753d2d2eSraf 1151*753d2d2eSraf strcat(bufp, "volatile"); 1152*753d2d2eSraf } 1153*753d2d2eSraf 1154*753d2d2eSraf /* 1155*753d2d2eSraf * It currently acknowledges and ignores restrict or _RESTRICT_KYWD 1156*753d2d2eSraf * in code generation because of the uncertain behavior of "restrict". 1157*753d2d2eSraf */ 1158*753d2d2eSraf if (dsp->ds_stt & TQ_RESTRICT) 1159*753d2d2eSraf strcat(bufp, ""); 1160*753d2d2eSraf 1161*753d2d2eSraf if (dsp->ds_stt & TQ_RESTRICT_KYWD) 1162*753d2d2eSraf strcat(bufp, ""); 1163*753d2d2eSraf 1164*753d2d2eSraf return (bufp); 1165*753d2d2eSraf } 1166*753d2d2eSraf 1167*753d2d2eSraf /* T Y P E M O D I F I E R S */ 1168*753d2d2eSraf 1169*753d2d2eSraf /* 1170*753d2d2eSraf * Type modifiers encode the "array of...", "pointer to ..." and 1171*753d2d2eSraf * "function returning ..." aspects of C types. The modifiers are kept 1172*753d2d2eSraf * as a linked list in precedence order. The grammar encodes the 1173*753d2d2eSraf * precedence order described by the standard. 1174*753d2d2eSraf * 1175*753d2d2eSraf * Type modifiers are always added at the end of list and the list is 1176*753d2d2eSraf * always traversed from head to tail. 1177*753d2d2eSraf */ 1178*753d2d2eSraf 1179*753d2d2eSraf /* type_Construct - allocate and initialize a type_t. */ 1180*753d2d2eSraf 1181*753d2d2eSraf static type_t * 1182*753d2d2eSraf type_Construct(void) { 1183*753d2d2eSraf type_t *tp = malloc(sizeof (type_t)); 1184*753d2d2eSraf 1185*753d2d2eSraf assert(tp != NULL); 1186*753d2d2eSraf 1187*753d2d2eSraf tp->t_next = NULL; /* generic */ 1188*753d2d2eSraf tp->t_dt = DD_NONE; 1189*753d2d2eSraf 1190*753d2d2eSraf tp->t_nargs = 0; /* DD_FUN */ 1191*753d2d2eSraf tp->t_ellipsis = 0; 1192*753d2d2eSraf tp->t_args = NULL; 1193*753d2d2eSraf /* DD_PTR */ 1194*753d2d2eSraf tp->t_stt = (SCS_NONE | TS_NO_TS | TQ_NONE); 1195*753d2d2eSraf 1196*753d2d2eSraf tp->t_sizestr = NULL; /* DD_ARY */ 1197*753d2d2eSraf #if defined(MEM_DEBUG) 1198*753d2d2eSraf ++type_Construct_calls; 1199*753d2d2eSraf #endif 1200*753d2d2eSraf return (tp); 1201*753d2d2eSraf } 1202*753d2d2eSraf 1203*753d2d2eSraf /* type_Destroy - free a type_t list. */ 1204*753d2d2eSraf 1205*753d2d2eSraf static void 1206*753d2d2eSraf type_Destroy(type_t *tp) { 1207*753d2d2eSraf while (tp) { 1208*753d2d2eSraf type_t *nextp = tp->t_next; 1209*753d2d2eSraf 1210*753d2d2eSraf switch (tp->t_dt) { 1211*753d2d2eSraf case DD_FUN: 1212*753d2d2eSraf decl_Destroy(tp->t_args); 1213*753d2d2eSraf break; 1214*753d2d2eSraf 1215*753d2d2eSraf case DD_PTR: 1216*753d2d2eSraf break; 1217*753d2d2eSraf 1218*753d2d2eSraf case DD_ARY: 1219*753d2d2eSraf free(tp->t_sizestr); 1220*753d2d2eSraf break; 1221*753d2d2eSraf } 1222*753d2d2eSraf 1223*753d2d2eSraf free(tp); 1224*753d2d2eSraf 1225*753d2d2eSraf tp = nextp; 1226*753d2d2eSraf #if defined(MEM_DEBUG) 1227*753d2d2eSraf --type_Construct_calls; 1228*753d2d2eSraf #endif 1229*753d2d2eSraf } 1230*753d2d2eSraf } 1231*753d2d2eSraf 1232*753d2d2eSraf /* 1233*753d2d2eSraf * type_SetPtr - make a type_t into a "pointer to ..." variant. 1234*753d2d2eSraf * 1235*753d2d2eSraf * Note: 1236*753d2d2eSraf * 1) The stt_t will encode any type qualifiers (const, volatile). 1237*753d2d2eSraf */ 1238*753d2d2eSraf 1239*753d2d2eSraf static type_t * 1240*753d2d2eSraf type_SetPtr(type_t *tp, stt_t s) { 1241*753d2d2eSraf assert(tp->t_dt == DD_NONE); 1242*753d2d2eSraf 1243*753d2d2eSraf tp->t_dt = DD_PTR; 1244*753d2d2eSraf tp->t_stt = s & TQ_MASK; 1245*753d2d2eSraf 1246*753d2d2eSraf return (tp); 1247*753d2d2eSraf } 1248*753d2d2eSraf 1249*753d2d2eSraf /* 1250*753d2d2eSraf * type_SetAry - make a type_t into an "array of ...", variant. 1251*753d2d2eSraf * 1252*753d2d2eSraf * Note: 1253*753d2d2eSraf * 1) The array dimension can be NULL to indicate undefined, i.e. []. 1254*753d2d2eSraf */ 1255*753d2d2eSraf 1256*753d2d2eSraf static type_t * 1257*753d2d2eSraf type_SetAry(type_t *tp, char *dim) { 1258*753d2d2eSraf assert(tp->t_dt == DD_NONE); 1259*753d2d2eSraf assert(tp->t_sizestr == NULL); 1260*753d2d2eSraf 1261*753d2d2eSraf tp->t_dt = DD_ARY; 1262*753d2d2eSraf 1263*753d2d2eSraf if (dim) { 1264*753d2d2eSraf tp->t_sizestr = strdup(dim); 1265*753d2d2eSraf assert(tp->t_sizestr != NULL); 1266*753d2d2eSraf } else 1267*753d2d2eSraf tp->t_sizestr = NULL; 1268*753d2d2eSraf 1269*753d2d2eSraf return (tp); 1270*753d2d2eSraf } 1271*753d2d2eSraf 1272*753d2d2eSraf /* 1273*753d2d2eSraf * type_SetFun - make a type_t into a "function returning ..." variant. 1274*753d2d2eSraf * 1275*753d2d2eSraf * Note: 1276*753d2d2eSraf * 1) The argument list can be NULL to indicate undefined, i.e. (). 1277*753d2d2eSraf */ 1278*753d2d2eSraf 1279*753d2d2eSraf static type_t * 1280*753d2d2eSraf type_SetFun(type_t *tp, decl_t *arglist) { 1281*753d2d2eSraf assert(tp->t_dt == DD_NONE); 1282*753d2d2eSraf 1283*753d2d2eSraf tp->t_dt = DD_FUN; 1284*753d2d2eSraf 1285*753d2d2eSraf if (arglist) { 1286*753d2d2eSraf tp->t_nargs = decl_GetArgLength(arglist); 1287*753d2d2eSraf tp->t_args = arglist; 1288*753d2d2eSraf tp->t_ellipsis = arglist->d_ellipsis; 1289*753d2d2eSraf } 1290*753d2d2eSraf 1291*753d2d2eSraf return (tp); 1292*753d2d2eSraf } 1293*753d2d2eSraf 1294*753d2d2eSraf /* 1295*753d2d2eSraf * type_AddTail - add a type_t to the end of an existing type_t list. 1296*753d2d2eSraf * 1297*753d2d2eSraf * Note: 1298*753d2d2eSraf * 1) The type_t *tp is added to the end of the type_t *dp list. 1299*753d2d2eSraf */ 1300*753d2d2eSraf 1301*753d2d2eSraf static type_t * 1302*753d2d2eSraf type_AddTail(type_t *dp, type_t *tp) { 1303*753d2d2eSraf type_t *lastp = dp; 1304*753d2d2eSraf type_t *p; 1305*753d2d2eSraf 1306*753d2d2eSraf while (p = lastp->t_next) 1307*753d2d2eSraf lastp = p; 1308*753d2d2eSraf 1309*753d2d2eSraf lastp->t_next = tp; 1310*753d2d2eSraf 1311*753d2d2eSraf return (dp); 1312*753d2d2eSraf } 1313*753d2d2eSraf 1314*753d2d2eSraf #if defined(DEBUG) 1315*753d2d2eSraf 1316*753d2d2eSraf /* type_PrintType - print a type_t list onto standard output. */ 1317*753d2d2eSraf 1318*753d2d2eSraf static void 1319*753d2d2eSraf type_PrintType(type_t *tp, int lvl) { 1320*753d2d2eSraf decl_spec_t tmp; 1321*753d2d2eSraf char buf[BUFSIZ]; 1322*753d2d2eSraf 1323*753d2d2eSraf while (tp) { 1324*753d2d2eSraf putNTabs(lvl); 1325*753d2d2eSraf 1326*753d2d2eSraf switch (tp->t_dt) { 1327*753d2d2eSraf case DD_PTR: 1328*753d2d2eSraf tmp.ds_stt = tp->t_stt; 1329*753d2d2eSraf tmp.ds_id = NULL; 1330*753d2d2eSraf 1331*753d2d2eSraf printf("[%s] ptr to\n", declspec_ToString(buf, &tmp)); 1332*753d2d2eSraf break; 1333*753d2d2eSraf 1334*753d2d2eSraf case DD_FUN: 1335*753d2d2eSraf printf("fun [%d%c] %s\n", 1336*753d2d2eSraf tp->t_nargs, 1337*753d2d2eSraf (tp->t_ellipsis)? '+' : '=', 1338*753d2d2eSraf (tp->t_args)? "with arguments" : 1339*753d2d2eSraf "undefined arguments"); 1340*753d2d2eSraf 1341*753d2d2eSraf if (tp->t_args) { 1342*753d2d2eSraf decl_PrintDecl(tp->t_args, lvl + 1); 1343*753d2d2eSraf 1344*753d2d2eSraf if (tp->t_ellipsis) { 1345*753d2d2eSraf putNTabs(lvl + 1); 1346*753d2d2eSraf printf("...\n"); 1347*753d2d2eSraf } 1348*753d2d2eSraf } 1349*753d2d2eSraf break; 1350*753d2d2eSraf 1351*753d2d2eSraf case DD_ARY: 1352*753d2d2eSraf printf("ary [%s] of\n", 1353*753d2d2eSraf (tp->t_sizestr)? tp->t_sizestr : ""); 1354*753d2d2eSraf break; 1355*753d2d2eSraf } 1356*753d2d2eSraf 1357*753d2d2eSraf tp = tp->t_next; 1358*753d2d2eSraf } 1359*753d2d2eSraf } 1360*753d2d2eSraf #endif /* DEBUG */ 1361*753d2d2eSraf 1362*753d2d2eSraf /* 1363*753d2d2eSraf * type_Verify - verify a type_t list for semantic correctness. 1364*753d2d2eSraf * 1365*753d2d2eSraf * Note: 1366*753d2d2eSraf * 1) C supports most combinations of type modifiers. 1367*753d2d2eSraf * It does not support three combinations, they are: 1368*753d2d2eSraf * 1369*753d2d2eSraf * function returning array 1370*753d2d2eSraf * array of functions 1371*753d2d2eSraf * function returning function 1372*753d2d2eSraf * 1373*753d2d2eSraf * 2) The enum values associated with type modifiers (i.e. DD_*) 1374*753d2d2eSraf * cannot be modified without changing the table included within the 1375*753d2d2eSraf * function. 1376*753d2d2eSraf * 1377*753d2d2eSraf * 3) The function returns NULL to indicate that the type modifier 1378*753d2d2eSraf * list is valid and non-NULL to indicate an error. 1379*753d2d2eSraf * 1380*753d2d2eSraf * 4) A type_t of NULL is permitted to indicate an empty type_t list. 1381*753d2d2eSraf */ 1382*753d2d2eSraf 1383*753d2d2eSraf static const char * 1384*753d2d2eSraf type_Verify(type_t *tp) { 1385*753d2d2eSraf static const char *dttbl[4][4] = { 1386*753d2d2eSraf /* NONE ARY FUN PTR */ 1387*753d2d2eSraf /* NONE */ {NULL, NULL, NULL, NULL}, 1388*753d2d2eSraf /* ARY */ {NULL, NULL, "array of functions", NULL}, 1389*753d2d2eSraf /* FUN */ {NULL, "function returning array", 1390*753d2d2eSraf "function returning function", NULL}, 1391*753d2d2eSraf /* PTR */ {NULL, NULL, NULL, NULL}, 1392*753d2d2eSraf }; 1393*753d2d2eSraf 1394*753d2d2eSraf if (tp) { 1395*753d2d2eSraf type_t *nextp; 1396*753d2d2eSraf 1397*753d2d2eSraf do { 1398*753d2d2eSraf const char *p; 1399*753d2d2eSraf decl_type_t nt; 1400*753d2d2eSraf 1401*753d2d2eSraf nt = (nextp = tp->t_next)? nextp->t_dt : DD_NONE; 1402*753d2d2eSraf 1403*753d2d2eSraf if ((p = dttbl[tp->t_dt][nt]) != NULL) 1404*753d2d2eSraf return (p); 1405*753d2d2eSraf 1406*753d2d2eSraf } while (tp = nextp); 1407*753d2d2eSraf } 1408*753d2d2eSraf 1409*753d2d2eSraf return (NULL); 1410*753d2d2eSraf } 1411*753d2d2eSraf 1412*753d2d2eSraf /* type_GetNext - return the next type_t in the list. */ 1413*753d2d2eSraf 1414*753d2d2eSraf type_t * 1415*753d2d2eSraf type_GetNext(type_t *tp) { 1416*753d2d2eSraf return (tp->t_next); 1417*753d2d2eSraf } 1418*753d2d2eSraf 1419*753d2d2eSraf /* 1420*753d2d2eSraf * The following group of functions return and or 1421*753d2d2eSraf * test various aspects of type modifiers. 1422*753d2d2eSraf * 1423*753d2d2eSraf * 1) The three functions: type_IsPtrTo, type_IsFunction and 1424*753d2d2eSraf * type_IsArray will accept an argument of NULL. 1425*753d2d2eSraf * 1426*753d2d2eSraf * 2) All other functions require one of the above three to be true. 1427*753d2d2eSraf * Various asserts are in place to verify correct usage. 1428*753d2d2eSraf */ 1429*753d2d2eSraf 1430*753d2d2eSraf int 1431*753d2d2eSraf type_IsArray(type_t *tp) { 1432*753d2d2eSraf return (tp && (tp->t_dt == DD_ARY)); 1433*753d2d2eSraf } 1434*753d2d2eSraf 1435*753d2d2eSraf char * 1436*753d2d2eSraf type_GetArraySize(type_t *tp) { 1437*753d2d2eSraf assert(tp->t_dt == DD_ARY); 1438*753d2d2eSraf 1439*753d2d2eSraf return (tp->t_sizestr); 1440*753d2d2eSraf } 1441*753d2d2eSraf 1442*753d2d2eSraf int 1443*753d2d2eSraf type_IsPtrTo(type_t *tp) { 1444*753d2d2eSraf return (tp && (tp->t_dt == DD_PTR)); 1445*753d2d2eSraf } 1446*753d2d2eSraf 1447*753d2d2eSraf stt_t 1448*753d2d2eSraf type_GetPtrToTypeQual(type_t *tp) { 1449*753d2d2eSraf assert(tp->t_dt == DD_PTR); 1450*753d2d2eSraf 1451*753d2d2eSraf return (tp->t_stt); 1452*753d2d2eSraf } 1453*753d2d2eSraf 1454*753d2d2eSraf int 1455*753d2d2eSraf type_IsFunction(type_t *tp) { 1456*753d2d2eSraf return (tp && (tp->t_dt == DD_FUN)); 1457*753d2d2eSraf } 1458*753d2d2eSraf 1459*753d2d2eSraf int 1460*753d2d2eSraf type_GetArgLength(type_t *tp) { 1461*753d2d2eSraf assert(tp->t_dt == DD_FUN); 1462*753d2d2eSraf 1463*753d2d2eSraf return (tp->t_nargs); 1464*753d2d2eSraf } 1465*753d2d2eSraf 1466*753d2d2eSraf int 1467*753d2d2eSraf type_IsVarargs(type_t *tp) { 1468*753d2d2eSraf while (tp && tp->t_dt == DD_PTR) 1469*753d2d2eSraf tp = tp->t_next; 1470*753d2d2eSraf 1471*753d2d2eSraf assert(tp->t_dt == DD_FUN); 1472*753d2d2eSraf 1473*753d2d2eSraf return (tp->t_ellipsis); 1474*753d2d2eSraf } 1475*753d2d2eSraf 1476*753d2d2eSraf decl_t * 1477*753d2d2eSraf type_GetArg(type_t *tp) { 1478*753d2d2eSraf assert(tp->t_dt == DD_FUN); 1479*753d2d2eSraf 1480*753d2d2eSraf return (tp->t_args); 1481*753d2d2eSraf } 1482*753d2d2eSraf 1483*753d2d2eSraf /* 1484*753d2d2eSraf * type_IsPtrFun - determine if the type_t results in a call-able function. 1485*753d2d2eSraf * 1486*753d2d2eSraf * Note: 1487*753d2d2eSraf * 1) The argument can be NULL. 1488*753d2d2eSraf * 1489*753d2d2eSraf * 2) The test is true if the type_t list is number of DD_PTR followed 1490*753d2d2eSraf * by a DD_FUN. 1491*753d2d2eSraf */ 1492*753d2d2eSraf 1493*753d2d2eSraf int 1494*753d2d2eSraf type_IsPtrFun(type_t *tp) { 1495*753d2d2eSraf 1496*753d2d2eSraf if (! (tp && (tp->t_dt == DD_PTR))) 1497*753d2d2eSraf return (0); 1498*753d2d2eSraf 1499*753d2d2eSraf tp = tp->t_next; 1500*753d2d2eSraf 1501*753d2d2eSraf while (tp && (tp->t_dt == DD_PTR)) 1502*753d2d2eSraf tp = tp->t_next; 1503*753d2d2eSraf 1504*753d2d2eSraf return (tp && (tp->t_dt == DD_FUN)); 1505*753d2d2eSraf } 1506*753d2d2eSraf 1507*753d2d2eSraf /* D E C L A R A T O R */ 1508*753d2d2eSraf 1509*753d2d2eSraf /* 1510*753d2d2eSraf * A decl_t encodes the name, 1511*753d2d2eSraf * declaration specifiers and type modifiers of an object. 1512*753d2d2eSraf */ 1513*753d2d2eSraf 1514*753d2d2eSraf /* decl_Construct - allocate a decl_t. */ 1515*753d2d2eSraf 1516*753d2d2eSraf static decl_t * 1517*753d2d2eSraf decl_Construct(void) { 1518*753d2d2eSraf decl_t *dp = malloc(sizeof (decl_t)); 1519*753d2d2eSraf 1520*753d2d2eSraf assert(dp != NULL); 1521*753d2d2eSraf 1522*753d2d2eSraf dp->d_name = NULL; 1523*753d2d2eSraf dp->d_type = NULL; 1524*753d2d2eSraf dp->d_next = NULL; 1525*753d2d2eSraf dp->d_ds = declspec_Construct(); 1526*753d2d2eSraf dp->d_ellipsis = 0; 1527*753d2d2eSraf #if defined(MEM_DEBUG) 1528*753d2d2eSraf ++decl_Construct_calls; 1529*753d2d2eSraf #endif 1530*753d2d2eSraf return (dp); 1531*753d2d2eSraf } 1532*753d2d2eSraf 1533*753d2d2eSraf /* decl_Destroy - free a decl_t list. */ 1534*753d2d2eSraf 1535*753d2d2eSraf void 1536*753d2d2eSraf decl_Destroy(decl_t *dp) { 1537*753d2d2eSraf while (dp) { 1538*753d2d2eSraf decl_t *nextp = dp->d_next; 1539*753d2d2eSraf 1540*753d2d2eSraf type_Destroy(dp->d_type); 1541*753d2d2eSraf declspec_Destroy(dp->d_ds); 1542*753d2d2eSraf free(dp->d_name); 1543*753d2d2eSraf free(dp); 1544*753d2d2eSraf 1545*753d2d2eSraf dp = nextp; 1546*753d2d2eSraf #if defined(MEM_DEBUG) 1547*753d2d2eSraf --decl_Construct_calls; 1548*753d2d2eSraf #endif 1549*753d2d2eSraf } 1550*753d2d2eSraf } 1551*753d2d2eSraf 1552*753d2d2eSraf /* 1553*753d2d2eSraf * decl_GetArgLength - return the length of a decl_t list. 1554*753d2d2eSraf * 1555*753d2d2eSraf * Note: 1556*753d2d2eSraf * 1) The argument may be NULL to indicate an empty list, len == 0. 1557*753d2d2eSraf */ 1558*753d2d2eSraf 1559*753d2d2eSraf int 1560*753d2d2eSraf decl_GetArgLength(decl_t *dp) { 1561*753d2d2eSraf int len; 1562*753d2d2eSraf 1563*753d2d2eSraf for (len = 0; dp; dp = dp->d_next) 1564*753d2d2eSraf ++len; 1565*753d2d2eSraf 1566*753d2d2eSraf return (len); 1567*753d2d2eSraf } 1568*753d2d2eSraf 1569*753d2d2eSraf /* 1570*753d2d2eSraf * The following group of functions get or test various aspects of a decl_t. 1571*753d2d2eSraf */ 1572*753d2d2eSraf 1573*753d2d2eSraf decl_t * 1574*753d2d2eSraf decl_GetNext(decl_t *dp) { 1575*753d2d2eSraf return (dp->d_next); 1576*753d2d2eSraf } 1577*753d2d2eSraf 1578*753d2d2eSraf stt_t 1579*753d2d2eSraf decl_GetDeclSpec(decl_t *dp) { 1580*753d2d2eSraf return (declspec_GetSTT(dp->d_ds)); 1581*753d2d2eSraf } 1582*753d2d2eSraf 1583*753d2d2eSraf char * 1584*753d2d2eSraf decl_GetDSName(decl_t *dp) { 1585*753d2d2eSraf return (declspec_GetTag(dp->d_ds)); 1586*753d2d2eSraf } 1587*753d2d2eSraf 1588*753d2d2eSraf type_t * 1589*753d2d2eSraf decl_GetType(decl_t *dp) { 1590*753d2d2eSraf return (dp->d_type); 1591*753d2d2eSraf } 1592*753d2d2eSraf 1593*753d2d2eSraf int 1594*753d2d2eSraf decl_IsVarargs(decl_t *dp) { 1595*753d2d2eSraf return (dp->d_ellipsis); 1596*753d2d2eSraf } 1597*753d2d2eSraf 1598*753d2d2eSraf int 1599*753d2d2eSraf decl_IsFunction(decl_t *dp) { 1600*753d2d2eSraf return (type_IsFunction(dp->d_type)); 1601*753d2d2eSraf } 1602*753d2d2eSraf 1603*753d2d2eSraf char * 1604*753d2d2eSraf decl_GetName(decl_t *dp) { 1605*753d2d2eSraf return (dp->d_name); 1606*753d2d2eSraf } 1607*753d2d2eSraf 1608*753d2d2eSraf /* 1609*753d2d2eSraf * decl_AddArg - add a decl_t to the end of an decl_t list. 1610*753d2d2eSraf */ 1611*753d2d2eSraf 1612*753d2d2eSraf static decl_t * 1613*753d2d2eSraf decl_AddArg(decl_t *dp, decl_t *tp) { 1614*753d2d2eSraf decl_t *lastp = dp; 1615*753d2d2eSraf decl_t *p; 1616*753d2d2eSraf 1617*753d2d2eSraf while (p = lastp->d_next) 1618*753d2d2eSraf lastp = p; 1619*753d2d2eSraf 1620*753d2d2eSraf lastp->d_next = tp; 1621*753d2d2eSraf 1622*753d2d2eSraf return (dp); 1623*753d2d2eSraf } 1624*753d2d2eSraf 1625*753d2d2eSraf /* 1626*753d2d2eSraf * decl_IsVoid - return true if the decl_t is a "pure" void declaration. 1627*753d2d2eSraf */ 1628*753d2d2eSraf 1629*753d2d2eSraf static int 1630*753d2d2eSraf decl_IsVoid(decl_t *dp) { 1631*753d2d2eSraf return ((declspec_GetSTT(dp->d_ds) & TS_VOID) && (dp->d_type == NULL)); 1632*753d2d2eSraf } 1633*753d2d2eSraf 1634*753d2d2eSraf /* 1635*753d2d2eSraf * decl_IsVoidArray - return true if the decl_t includes "void []". 1636*753d2d2eSraf */ 1637*753d2d2eSraf 1638*753d2d2eSraf static int 1639*753d2d2eSraf decl_IsVoidArray(decl_t *dp) { 1640*753d2d2eSraf int retval = 0; 1641*753d2d2eSraf type_t *tp = dp->d_type; 1642*753d2d2eSraf 1643*753d2d2eSraf if (tp) { 1644*753d2d2eSraf type_t *np; 1645*753d2d2eSraf 1646*753d2d2eSraf while (np = type_GetNext(tp)) 1647*753d2d2eSraf tp = np; 1648*753d2d2eSraf 1649*753d2d2eSraf retval = type_IsArray(tp) && 1650*753d2d2eSraf (declspec_GetSTT(dp->d_ds) & TS_VOID); 1651*753d2d2eSraf } 1652*753d2d2eSraf 1653*753d2d2eSraf return (retval); 1654*753d2d2eSraf } 1655*753d2d2eSraf 1656*753d2d2eSraf /* 1657*753d2d2eSraf * decl_Verify - verify a decl_t. 1658*753d2d2eSraf */ 1659*753d2d2eSraf 1660*753d2d2eSraf static const char * 1661*753d2d2eSraf decl_Verify(decl_t *dp) { 1662*753d2d2eSraf const char *ep = NULL; 1663*753d2d2eSraf 1664*753d2d2eSraf if (decl_IsVoid(dp)) 1665*753d2d2eSraf ep = "type is void"; 1666*753d2d2eSraf else if (decl_IsVoidArray(dp)) 1667*753d2d2eSraf ep = "type is void []"; 1668*753d2d2eSraf else 1669*753d2d2eSraf ep = type_Verify(dp->d_type); 1670*753d2d2eSraf 1671*753d2d2eSraf return (ep); 1672*753d2d2eSraf } 1673*753d2d2eSraf 1674*753d2d2eSraf /* 1675*753d2d2eSraf * decl_VerifyArgs - verify a decl_t list. 1676*753d2d2eSraf */ 1677*753d2d2eSraf 1678*753d2d2eSraf static const char * 1679*753d2d2eSraf decl_VerifyArgs(decl_t *dp) { 1680*753d2d2eSraf decl_t *tp = dp; 1681*753d2d2eSraf const char *ep = NULL; 1682*753d2d2eSraf 1683*753d2d2eSraf if (dp) { 1684*753d2d2eSraf int nv = 0; 1685*753d2d2eSraf int nargs = decl_GetArgLength(dp); 1686*753d2d2eSraf 1687*753d2d2eSraf for (; dp; dp = dp->d_next) 1688*753d2d2eSraf if (decl_IsVoid(dp)) { 1689*753d2d2eSraf ++nv; 1690*753d2d2eSraf 1691*753d2d2eSraf if (decl_GetName(dp)) 1692*753d2d2eSraf ep = "argument list includes " 1693*753d2d2eSraf "void with identifier"; 1694*753d2d2eSraf } else if (decl_IsVoidArray(dp)) 1695*753d2d2eSraf ep = "argument list includes void []"; 1696*753d2d2eSraf 1697*753d2d2eSraf if (nv) { /* there was some void */ 1698*753d2d2eSraf if (nargs > 1) 1699*753d2d2eSraf ep = "argument list includes void"; 1700*753d2d2eSraf 1701*753d2d2eSraf if (tp->d_ellipsis) 1702*753d2d2eSraf ep = "argument list includes void and \"...\""; 1703*753d2d2eSraf } 1704*753d2d2eSraf } 1705*753d2d2eSraf 1706*753d2d2eSraf return (ep); 1707*753d2d2eSraf } 1708*753d2d2eSraf 1709*753d2d2eSraf /* decl_AddDS - add a decl_spec_t to a decl_t. */ 1710*753d2d2eSraf 1711*753d2d2eSraf static decl_t * 1712*753d2d2eSraf decl_AddDS(decl_t *dp, decl_spec_t *dsp, const char **err) { 1713*753d2d2eSraf declspec_AddDS(dp->d_ds, dsp, err); 1714*753d2d2eSraf 1715*753d2d2eSraf return (dp); 1716*753d2d2eSraf } 1717*753d2d2eSraf 1718*753d2d2eSraf /* 1719*753d2d2eSraf * decl_SetName - set the name associated with a decl_t. 1720*753d2d2eSraf * 1721*753d2d2eSraf * Note: 1722*753d2d2eSraf * 1) Any previously known name is free'd. 1723*753d2d2eSraf */ 1724*753d2d2eSraf 1725*753d2d2eSraf decl_t * 1726*753d2d2eSraf decl_SetName(decl_t *dp, char *s) { 1727*753d2d2eSraf free(dp->d_name); 1728*753d2d2eSraf dp->d_name = strdup(s); 1729*753d2d2eSraf assert(dp->d_name != NULL); 1730*753d2d2eSraf 1731*753d2d2eSraf return (dp); 1732*753d2d2eSraf } 1733*753d2d2eSraf 1734*753d2d2eSraf /* 1735*753d2d2eSraf * decl_AddTypeTail - add a type_t to the end of a decl_t type_t list. 1736*753d2d2eSraf */ 1737*753d2d2eSraf 1738*753d2d2eSraf static decl_t * 1739*753d2d2eSraf decl_AddTypeTail(decl_t *dp, type_t *tp) { 1740*753d2d2eSraf if (dp->d_type) 1741*753d2d2eSraf type_AddTail(dp->d_type, tp); 1742*753d2d2eSraf else 1743*753d2d2eSraf dp->d_type = tp; 1744*753d2d2eSraf 1745*753d2d2eSraf return (dp); 1746*753d2d2eSraf } 1747*753d2d2eSraf 1748*753d2d2eSraf /* 1749*753d2d2eSraf * decl_addptr - add a DD_PTR type_t to the end of a decl_t type_t list. 1750*753d2d2eSraf */ 1751*753d2d2eSraf 1752*753d2d2eSraf static decl_t * 1753*753d2d2eSraf decl_addptr(decl_t *dp, type_t *tp) { 1754*753d2d2eSraf decl_AddTypeTail(dp, tp); 1755*753d2d2eSraf 1756*753d2d2eSraf return (dp); 1757*753d2d2eSraf } 1758*753d2d2eSraf 1759*753d2d2eSraf /* 1760*753d2d2eSraf * decl_addary - allocate and add a DD_ARY type_t to the end of 1761*753d2d2eSraf * a decl_t type_t list. 1762*753d2d2eSraf */ 1763*753d2d2eSraf 1764*753d2d2eSraf static decl_t * 1765*753d2d2eSraf decl_addary(decl_t *dp, char *sizep) { 1766*753d2d2eSraf type_t *tp = type_Construct(); 1767*753d2d2eSraf 1768*753d2d2eSraf type_SetAry(tp, sizep); 1769*753d2d2eSraf decl_AddTypeTail(dp, tp); 1770*753d2d2eSraf 1771*753d2d2eSraf return (dp); 1772*753d2d2eSraf } 1773*753d2d2eSraf 1774*753d2d2eSraf /* 1775*753d2d2eSraf * decl_addfun - allocate and add a DD_FUN type_t to the end of a 1776*753d2d2eSraf * decl_t type_t list. 1777*753d2d2eSraf */ 1778*753d2d2eSraf 1779*753d2d2eSraf static decl_t * 1780*753d2d2eSraf decl_addfun(decl_t *dp, decl_t *arglist) { 1781*753d2d2eSraf const char *sp; 1782*753d2d2eSraf type_t *tp = type_Construct(); 1783*753d2d2eSraf 1784*753d2d2eSraf if (sp = decl_VerifyArgs(arglist)) 1785*753d2d2eSraf yyerror(sp); 1786*753d2d2eSraf 1787*753d2d2eSraf type_SetFun(tp, arglist); 1788*753d2d2eSraf decl_AddTypeTail(dp, tp); 1789*753d2d2eSraf 1790*753d2d2eSraf return (dp); 1791*753d2d2eSraf } 1792*753d2d2eSraf 1793*753d2d2eSraf /* 1794*753d2d2eSraf * decl_addellipsis - set the ellipsis state in a decl_t. 1795*753d2d2eSraf * 1796*753d2d2eSraf * Note: 1797*753d2d2eSraf * 1) This function is only used in the grammar in the 1798*753d2d2eSraf * parameter list parsing. 1799*753d2d2eSraf */ 1800*753d2d2eSraf 1801*753d2d2eSraf static decl_t * 1802*753d2d2eSraf decl_addellipsis(decl_t *dp) { 1803*753d2d2eSraf dp->d_ellipsis = 1; 1804*753d2d2eSraf 1805*753d2d2eSraf return (dp); 1806*753d2d2eSraf } 1807*753d2d2eSraf 1808*753d2d2eSraf #if defined(DEBUG) 1809*753d2d2eSraf 1810*753d2d2eSraf static void 1811*753d2d2eSraf decl_PrintDecl(decl_t *dp, int lvl) { 1812*753d2d2eSraf char buf[BUFSIZ]; 1813*753d2d2eSraf 1814*753d2d2eSraf while (dp) { 1815*753d2d2eSraf putNTabs(lvl); 1816*753d2d2eSraf 1817*753d2d2eSraf printf("name = %s, ds = %s\n", 1818*753d2d2eSraf (dp->d_name)? dp->d_name : "<null>", 1819*753d2d2eSraf declspec_ToString(buf, dp->d_ds)); 1820*753d2d2eSraf 1821*753d2d2eSraf if (dp->d_type) 1822*753d2d2eSraf type_PrintType(dp->d_type, lvl + 1); 1823*753d2d2eSraf 1824*753d2d2eSraf dp = dp->d_next; 1825*753d2d2eSraf } 1826*753d2d2eSraf } 1827*753d2d2eSraf #endif /* DEBUG */ 1828*753d2d2eSraf 1829*753d2d2eSraf static char * 1830*753d2d2eSraf char_getend(char *s) { 1831*753d2d2eSraf while (*s != '\0') 1832*753d2d2eSraf ++s; 1833*753d2d2eSraf 1834*753d2d2eSraf return (s); 1835*753d2d2eSraf } 1836*753d2d2eSraf 1837*753d2d2eSraf char * 1838*753d2d2eSraf decl_ToString(char *bufp, decl_dts_t out, decl_t *dp, 1839*753d2d2eSraf const char *altname) { 1840*753d2d2eSraf char tmp[BUFSIZ]; 1841*753d2d2eSraf char tmp2[BUFSIZ]; 1842*753d2d2eSraf const char *namep; 1843*753d2d2eSraf char *bend = bufp; 1844*753d2d2eSraf type_t *tp = dp->d_type; 1845*753d2d2eSraf int ffun = 1; 1846*753d2d2eSraf 1847*753d2d2eSraf switch (out) { 1848*753d2d2eSraf default: 1849*753d2d2eSraf out = DTS_DECL; 1850*753d2d2eSraf /* FALLTHRU */ 1851*753d2d2eSraf case DTS_DECL: 1852*753d2d2eSraf if (altname == NULL) { 1853*753d2d2eSraf namep = dp->d_name; 1854*753d2d2eSraf } else { 1855*753d2d2eSraf namep = altname; 1856*753d2d2eSraf } 1857*753d2d2eSraf break; 1858*753d2d2eSraf case DTS_CAST: 1859*753d2d2eSraf namep = "(*)"; 1860*753d2d2eSraf break; 1861*753d2d2eSraf case DTS_RET: 1862*753d2d2eSraf if (altname == NULL) { 1863*753d2d2eSraf namep = "_return"; 1864*753d2d2eSraf } else { 1865*753d2d2eSraf namep = altname; 1866*753d2d2eSraf } 1867*753d2d2eSraf break; 1868*753d2d2eSraf } 1869*753d2d2eSraf 1870*753d2d2eSraf *bufp = '\0'; 1871*753d2d2eSraf 1872*753d2d2eSraf strcpy(tmp, (namep) ? namep : ""); 1873*753d2d2eSraf 1874*753d2d2eSraf while (tp) { 1875*753d2d2eSraf switch (tp->t_dt) { 1876*753d2d2eSraf case DD_PTR: 1877*753d2d2eSraf if (tp->t_next && 1878*753d2d2eSraf ((tp->t_next->t_dt == DD_ARY) || 1879*753d2d2eSraf (tp->t_next->t_dt == DD_FUN))) { 1880*753d2d2eSraf if (out == DTS_RET) { 1881*753d2d2eSraf sprintf(bufp, "(*%s)", namep); 1882*753d2d2eSraf } else { 1883*753d2d2eSraf sprintf(bufp, "(*%s)", tmp); 1884*753d2d2eSraf } 1885*753d2d2eSraf } else if (tp->t_stt == TQ_CONST) { 1886*753d2d2eSraf sprintf(bufp, "*const %s", tmp); 1887*753d2d2eSraf } else if (tp->t_stt == TQ_VOLATILE) { 1888*753d2d2eSraf sprintf(bufp, "*volatile %s", tmp); 1889*753d2d2eSraf /* 1890*753d2d2eSraf * It currently acknowledges and ignores restrict 1891*753d2d2eSraf * or _RESTRICT_KYWD in code generation because 1892*753d2d2eSraf * of the uncertain behavior of "restrict". 1893*753d2d2eSraf */ 1894*753d2d2eSraf } else if (tp->t_stt == TQ_RESTRICT) { 1895*753d2d2eSraf sprintf(bufp, "*%s", tmp); 1896*753d2d2eSraf } else if (tp->t_stt == TQ_RESTRICT_KYWD) { 1897*753d2d2eSraf sprintf(bufp, "*%s", tmp); 1898*753d2d2eSraf } else { 1899*753d2d2eSraf sprintf(bufp, "*%s", tmp); 1900*753d2d2eSraf } 1901*753d2d2eSraf 1902*753d2d2eSraf break; 1903*753d2d2eSraf 1904*753d2d2eSraf case DD_ARY: 1905*753d2d2eSraf sprintf(bufp, "%s[%s]", 1906*753d2d2eSraf tmp, (tp->t_sizestr)? tp->t_sizestr : ""); 1907*753d2d2eSraf break; 1908*753d2d2eSraf 1909*753d2d2eSraf case DD_FUN: 1910*753d2d2eSraf if (out == DTS_RET && ffun == 1) { 1911*753d2d2eSraf strcpy(bufp, namep); 1912*753d2d2eSraf ffun = 0; 1913*753d2d2eSraf } else if (tp->t_args == NULL) { 1914*753d2d2eSraf sprintf(bufp, "%s()", tmp); 1915*753d2d2eSraf } else { 1916*753d2d2eSraf char buf2[BUFSIZ]; 1917*753d2d2eSraf decl_t *argp = tp->t_args; 1918*753d2d2eSraf 1919*753d2d2eSraf sprintf(bufp, "%s(", tmp); 1920*753d2d2eSraf bend = char_getend(bufp); 1921*753d2d2eSraf 1922*753d2d2eSraf for (argp = tp->t_args; argp; /* noinc */) { 1923*753d2d2eSraf decl_ToString(buf2, DTS_DECL, argp, 1924*753d2d2eSraf NULL); 1925*753d2d2eSraf sprintf(bend, " %s", buf2); 1926*753d2d2eSraf 1927*753d2d2eSraf bend = char_getend(bend); 1928*753d2d2eSraf 1929*753d2d2eSraf if (argp = argp->d_next) { 1930*753d2d2eSraf sprintf(bend, ","); 1931*753d2d2eSraf bend = char_getend(bend); 1932*753d2d2eSraf } 1933*753d2d2eSraf } 1934*753d2d2eSraf 1935*753d2d2eSraf if (tp->t_ellipsis) { 1936*753d2d2eSraf sprintf(bend, ", ..."); 1937*753d2d2eSraf bend = char_getend(bend); 1938*753d2d2eSraf } 1939*753d2d2eSraf 1940*753d2d2eSraf sprintf(bend, ")"); 1941*753d2d2eSraf } 1942*753d2d2eSraf break; 1943*753d2d2eSraf } 1944*753d2d2eSraf 1945*753d2d2eSraf tp = tp->t_next; 1946*753d2d2eSraf 1947*753d2d2eSraf strcpy(tmp, bufp); 1948*753d2d2eSraf } 1949*753d2d2eSraf 1950*753d2d2eSraf if (out == DTS_CAST) { 1951*753d2d2eSraf sprintf(bufp, "(%s %s)", 1952*753d2d2eSraf declspec_ToString(tmp2, dp->d_ds), tmp); 1953*753d2d2eSraf } else { 1954*753d2d2eSraf sprintf(bufp, "%s %s", 1955*753d2d2eSraf declspec_ToString(tmp2, dp->d_ds), tmp); 1956*753d2d2eSraf } 1957*753d2d2eSraf 1958*753d2d2eSraf return (bufp); 1959*753d2d2eSraf } 1960*753d2d2eSraf 1961*753d2d2eSraf decl_t * 1962*753d2d2eSraf decl_AddArgNames(decl_t *dp) { 1963*753d2d2eSraf int argno = 0; 1964*753d2d2eSraf decl_t *p = dp; 1965*753d2d2eSraf 1966*753d2d2eSraf if (decl_IsFunction(dp)) { 1967*753d2d2eSraf int argno = 0; 1968*753d2d2eSraf decl_t *p = dp->d_type->t_args; 1969*753d2d2eSraf 1970*753d2d2eSraf while (p) { 1971*753d2d2eSraf char *s = decl_GetName(p); 1972*753d2d2eSraf 1973*753d2d2eSraf if ((s == NULL) && !decl_IsVoid(p)) { 1974*753d2d2eSraf char buf[BUFSIZ]; 1975*753d2d2eSraf 1976*753d2d2eSraf sprintf(buf, "arg%d", argno); 1977*753d2d2eSraf s = strdup(buf); 1978*753d2d2eSraf decl_SetName(p, s); 1979*753d2d2eSraf } 1980*753d2d2eSraf 1981*753d2d2eSraf p = p->d_next; 1982*753d2d2eSraf ++argno; 1983*753d2d2eSraf } 1984*753d2d2eSraf } 1985*753d2d2eSraf return (dp); 1986*753d2d2eSraf } 1987*753d2d2eSraf 1988*753d2d2eSraf const char * 1989*753d2d2eSraf decl_Parse(char *str, decl_t **dpp) { 1990*753d2d2eSraf errstr = NULL; /* setup the (static) globals */ 1991*753d2d2eSraf input = str; 1992*753d2d2eSraf atIDENT = 0; 1993*753d2d2eSraf protop = NULL; 1994*753d2d2eSraf 1995*753d2d2eSraf yyparse(); /* parse the prototype */ 1996*753d2d2eSraf 1997*753d2d2eSraf if (errstr == NULL) { /* success */ 1998*753d2d2eSraf *dpp = protop; 1999*753d2d2eSraf decl_AddArgNames(protop); 2000*753d2d2eSraf } else { /* failure */ 2001*753d2d2eSraf *dpp = NULL; 2002*753d2d2eSraf decl_Destroy(protop); 2003*753d2d2eSraf } 2004*753d2d2eSraf 2005*753d2d2eSraf return (errstr); 2006*753d2d2eSraf } 2007*753d2d2eSraf 2008*753d2d2eSraf static void 2009*753d2d2eSraf yyerror(const char *err) { 2010*753d2d2eSraf errstr = err; 2011*753d2d2eSraf } 2012*753d2d2eSraf 2013*753d2d2eSraf #if defined(DEBUG) 2014*753d2d2eSraf 2015*753d2d2eSraf /* main */ 2016*753d2d2eSraf 2017*753d2d2eSraf static int yydebug = 1; 2018*753d2d2eSraf 2019*753d2d2eSraf int 2020*753d2d2eSraf main(int argc, char *argv[]) { 2021*753d2d2eSraf int i; 2022*753d2d2eSraf 2023*753d2d2eSraf yydebug = 1; 2024*753d2d2eSraf 2025*753d2d2eSraf for (i = 1; i < argc; ++i) { 2026*753d2d2eSraf const char *es; 2027*753d2d2eSraf char buf[BUFSIZ]; 2028*753d2d2eSraf decl_t *pp; 2029*753d2d2eSraf 2030*753d2d2eSraf if (es = decl_Parse(argv[i], &pp)) 2031*753d2d2eSraf printf("parse failure: %s\n", es); 2032*753d2d2eSraf else { 2033*753d2d2eSraf #if GR_DEBUG 2034*753d2d2eSraf decl_PrintDecl(pp, 0); 2035*753d2d2eSraf decl_AddArgNames(pp); 2036*753d2d2eSraf #endif 2037*753d2d2eSraf printf("---\n%s;\n", 2038*753d2d2eSraf decl_ToString(buf, DTS_DECL, pp, NULL)); 2039*753d2d2eSraf printf("%s\n", 2040*753d2d2eSraf decl_ToString(buf, DTS_CAST, pp, NULL)); 2041*753d2d2eSraf printf("%s;\n", 2042*753d2d2eSraf decl_ToString(buf, DTS_RET, pp, "%s")); 2043*753d2d2eSraf 2044*753d2d2eSraf #ifdef TRACE 2045*753d2d2eSraf printf("\n\nTrace Info\n"); 2046*753d2d2eSraf decl_PrintTraceInfo(pp); 2047*753d2d2eSraf #endif 2048*753d2d2eSraf } 2049*753d2d2eSraf 2050*753d2d2eSraf decl_Destroy(pp); 2051*753d2d2eSraf 2052*753d2d2eSraf #if defined(MEM_DEBUG) 2053*753d2d2eSraf printf("declspec : %d\n", declspec_Construct_calls); 2054*753d2d2eSraf printf("type : %d\n", type_Construct_calls); 2055*753d2d2eSraf printf("decl : %d\n", decl_Construct_calls); 2056*753d2d2eSraf #endif 2057*753d2d2eSraf } 2058*753d2d2eSraf 2059*753d2d2eSraf return (0); 2060*753d2d2eSraf } 2061*753d2d2eSraf 2062*753d2d2eSraf #ifdef TRACE 2063*753d2d2eSraf void 2064*753d2d2eSraf decl_PrintTraceInfo(decl_t *dp) { 2065*753d2d2eSraf char buf[BUFSIZ]; 2066*753d2d2eSraf char f_type[BUFSIZ]; 2067*753d2d2eSraf char f_print[BUFSIZ]; 2068*753d2d2eSraf char a_name[BUFSIZ]; 2069*753d2d2eSraf char a_type[BUFSIZ]; 2070*753d2d2eSraf char a_print[BUFSIZ]; 2071*753d2d2eSraf decl_t *funargs; 2072*753d2d2eSraf type_t *tp; 2073*753d2d2eSraf int isptrfun; 2074*753d2d2eSraf 2075*753d2d2eSraf if (dp == NULL) 2076*753d2d2eSraf return; 2077*753d2d2eSraf 2078*753d2d2eSraf fprintf(stderr, "interface = %s\n", 2079*753d2d2eSraf (dp->d_name) ? dp->d_name : "<null>"); 2080*753d2d2eSraf 2081*753d2d2eSraf isptrfun = type_IsPtrFun(dp->d_type); 2082*753d2d2eSraf if (type_IsFunction(dp->d_type) || isptrfun) 2083*753d2d2eSraf decl_GetTraceInfo(dp, f_type, f_print, &funargs); 2084*753d2d2eSraf else 2085*753d2d2eSraf return; 2086*753d2d2eSraf 2087*753d2d2eSraf fprintf(stderr, "return type = %s\n", f_type); 2088*753d2d2eSraf fprintf(stderr, "print function = %s\n", f_print); 2089*753d2d2eSraf 2090*753d2d2eSraf if (isptrfun) 2091*753d2d2eSraf fprintf(stderr, "function is function pointer\n"); 2092*753d2d2eSraf 2093*753d2d2eSraf if (type_IsVarargs(dp->d_type)) 2094*753d2d2eSraf fprintf(stderr, "function is varargs\n"); 2095*753d2d2eSraf 2096*753d2d2eSraf while (funargs) { 2097*753d2d2eSraf snprintf(a_type, BUFSIZ, "%s ", 2098*753d2d2eSraf declspec_ToString(buf, funargs->d_ds)); 2099*753d2d2eSraf snprintf(a_print, BUFSIZ, "%s", 2100*753d2d2eSraf de_const(declspec_ToString(buf, funargs->d_ds))); 2101*753d2d2eSraf 2102*753d2d2eSraf tp = funargs->d_type; 2103*753d2d2eSraf 2104*753d2d2eSraf while (tp) { 2105*753d2d2eSraf if (tp->t_dt == DD_PTR || tp->t_dt == DD_ARY) { 2106*753d2d2eSraf strcat(a_type, "*"); 2107*753d2d2eSraf strcat(a_print, "_P"); 2108*753d2d2eSraf } 2109*753d2d2eSraf tp = tp->t_next; 2110*753d2d2eSraf } 2111*753d2d2eSraf 2112*753d2d2eSraf if (funargs->d_name) { 2113*753d2d2eSraf snprintf(a_name, BUFSIZ, "%s", 2114*753d2d2eSraf funargs->d_name ? funargs->d_name : "<nil>"); 2115*753d2d2eSraf fprintf(stderr, "arg name = %s\n", a_name); 2116*753d2d2eSraf fprintf(stderr, "arg type = %s\n", a_type); 2117*753d2d2eSraf fprintf(stderr, "print function = %s\n", a_print); 2118*753d2d2eSraf } else { 2119*753d2d2eSraf strcpy(a_name, ""); 2120*753d2d2eSraf strcpy(a_print, ""); 2121*753d2d2eSraf fprintf(stderr, "arg type = %s\n", a_type); 2122*753d2d2eSraf } 2123*753d2d2eSraf 2124*753d2d2eSraf funargs = funargs->d_next; 2125*753d2d2eSraf } 2126*753d2d2eSraf } 2127*753d2d2eSraf #endif /* TRACE */ 2128*753d2d2eSraf #endif /* DEBUG */ 2129*753d2d2eSraf 2130*753d2d2eSraf static char * 2131*753d2d2eSraf de_const(char *str) 2132*753d2d2eSraf { 2133*753d2d2eSraf return (str); 2134*753d2d2eSraf } 2135*753d2d2eSraf 2136*753d2d2eSraf 2137*753d2d2eSraf void 2138*753d2d2eSraf decl_GetTraceInfo(decl_t *dp, char *f_type, char *f_print, decl_t **funargs) 2139*753d2d2eSraf { 2140*753d2d2eSraf char buf[BUFSIZ]; 2141*753d2d2eSraf type_t *tp; 2142*753d2d2eSraf 2143*753d2d2eSraf if (dp == NULL) 2144*753d2d2eSraf return; 2145*753d2d2eSraf 2146*753d2d2eSraf snprintf(f_type, BUFSIZ, "%s ", 2147*753d2d2eSraf declspec_ToString(buf, dp->d_ds)); 2148*753d2d2eSraf snprintf(f_print, BUFSIZ, "%s", 2149*753d2d2eSraf de_const(declspec_ToString(buf, dp->d_ds))); 2150*753d2d2eSraf tp = dp->d_type; 2151*753d2d2eSraf while (tp) { 2152*753d2d2eSraf if (tp->t_dt == DD_PTR) { 2153*753d2d2eSraf strcat(f_type, "*"); 2154*753d2d2eSraf strcat(f_print, "*"); 2155*753d2d2eSraf } 2156*753d2d2eSraf tp = tp->t_next; 2157*753d2d2eSraf } 2158*753d2d2eSraf 2159*753d2d2eSraf strcat(f_type, "%s"); 2160*753d2d2eSraf 2161*753d2d2eSraf tp = decl_GetType(dp); 2162*753d2d2eSraf if (type_IsPtrFun(tp)) { 2163*753d2d2eSraf while (tp->t_dt != DD_FUN) 2164*753d2d2eSraf tp = tp->t_next; 2165*753d2d2eSraf *funargs = tp->t_args; 2166*753d2d2eSraf } else { 2167*753d2d2eSraf *funargs = dp->d_type->t_args; 2168*753d2d2eSraf } 2169*753d2d2eSraf } 2170*753d2d2eSraf 2171*753d2d2eSraf char * 2172*753d2d2eSraf decl_ToFormal(decl_t *dp) 2173*753d2d2eSraf { 2174*753d2d2eSraf char tmp[BUFSIZ]; 2175*753d2d2eSraf static char bufp[BUFSIZ]; 2176*753d2d2eSraf char *bend; 2177*753d2d2eSraf type_t *tp = dp->d_type; 2178*753d2d2eSraf 2179*753d2d2eSraf tmp[0] = 0; 2180*753d2d2eSraf bufp[0] = 0; 2181*753d2d2eSraf bend = bufp; 2182*753d2d2eSraf 2183*753d2d2eSraf while (tp) { 2184*753d2d2eSraf switch (tp->t_dt) { 2185*753d2d2eSraf case DD_ARY: 2186*753d2d2eSraf sprintf(bufp, "%s[%s]", tmp, 2187*753d2d2eSraf (tp->t_sizestr)? tp->t_sizestr : ""); 2188*753d2d2eSraf break; 2189*753d2d2eSraf 2190*753d2d2eSraf case DD_FUN: 2191*753d2d2eSraf if (tp->t_args != NULL) { 2192*753d2d2eSraf char buf2[BUFSIZ]; 2193*753d2d2eSraf decl_t *argp = tp->t_args; 2194*753d2d2eSraf 2195*753d2d2eSraf bend = char_getend(bufp); 2196*753d2d2eSraf 2197*753d2d2eSraf for (argp = tp->t_args; argp; /* noinc */) { 2198*753d2d2eSraf decl_ToString(buf2, DTS_DECL, argp, 2199*753d2d2eSraf NULL); 2200*753d2d2eSraf sprintf(bend, " %s", buf2); 2201*753d2d2eSraf 2202*753d2d2eSraf bend = char_getend(bend); 2203*753d2d2eSraf 2204*753d2d2eSraf if (argp = argp->d_next) { 2205*753d2d2eSraf sprintf(bend, ","); 2206*753d2d2eSraf bend = char_getend(bend); 2207*753d2d2eSraf } 2208*753d2d2eSraf } 2209*753d2d2eSraf if (tp->t_ellipsis) { 2210*753d2d2eSraf sprintf(bend, ", ..."); 2211*753d2d2eSraf bend = char_getend(bend); 2212*753d2d2eSraf } 2213*753d2d2eSraf 2214*753d2d2eSraf sprintf(bend, ""); 2215*753d2d2eSraf } 2216*753d2d2eSraf break; 2217*753d2d2eSraf } 2218*753d2d2eSraf 2219*753d2d2eSraf tp = tp->t_next; 2220*753d2d2eSraf 2221*753d2d2eSraf strcpy(tmp, bufp); 2222*753d2d2eSraf } 2223*753d2d2eSraf 2224*753d2d2eSraf sprintf(bufp, "%s", tmp); 2225*753d2d2eSraf 2226*753d2d2eSraf return (bufp); 2227*753d2d2eSraf } 2228