1103856Stjr/* -*- indented-text -*- */ 2103856Stjr/* Process source files and output type information. 3103856Stjr Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc. 4103856Stjr 5103856StjrThis file is part of GCC. 6103856Stjr 7103856StjrGCC is free software; you can redistribute it and/or modify it under 8227753Stheraventhe terms of the GNU General Public License as published by the Free 9227753StheravenSoftware Foundation; either version 2, or (at your option) any later 10227753Stheravenversion. 11227753Stheraven 12227753StheravenGCC is distributed in the hope that it will be useful, but WITHOUT ANY 13103856StjrWARRANTY; without even the implied warranty of MERCHANTABILITY or 14103856StjrFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15103856Stjrfor more details. 16103856Stjr 17103856StjrYou should have received a copy of the GNU General Public License 18103856Stjralong with GCC; see the file COPYING. If not, write to the Free 19103856StjrSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 20103856Stjr02110-1301, USA. */ 21249808Semaste 22103856Stjr%{ 23103856Stjr#include "bconfig.h" 24103856Stjr#include "coretypes.h" 25103856Stjr#include "system.h" 26103856Stjr 27103856Stjr#define malloc xmalloc 28103856Stjr#define realloc xrealloc 29103856Stjr 30103856Stjr#include "gengtype.h" 31103856Stjr#include "gengtype-yacc.h" 32103856Stjr 33103856Stjr#define YY_INPUT(BUF,RESULT,SIZE) ((RESULT) = macro_input (BUF,SIZE)) 34103856Stjr 35103856Stjrstatic unsigned macro_input (char *buffer, unsigned); 36103856Stjrstatic const char *push_macro_expansion (const char *, unsigned, 37103856Stjr const char *, unsigned); 38103856Stjrstatic char *mangle_macro_name (const char *, unsigned, 39103856Stjr const char *, unsigned); 40103856Stjrstatic void update_lineno (const char *l, size_t len); 41103856Stjr 42103856Stjrstruct fileloc lexer_line; 43103856Stjrint lexer_toplevel_done; 44103856Stjr 45103856Stjrstatic void 46103856Stjrupdate_lineno (const char *l, size_t len) 47103856Stjr{ 48103856Stjr while (len-- > 0) 49103856Stjr if (*l++ == '\n') 50103856Stjr lexer_line.line++; 51103856Stjr} 52103856Stjr 53103856Stjr%} 54227753Stheraven 55103856StjrID [[:alpha:]_][[:alnum:]_]* 56103856StjrWS [[:space:]]+ 57103856StjrIWORD short|long|(un)?signed|char|int|HOST_WIDE_INT|HOST_WIDEST_INT|bool|size_t|BOOL_BITFIELD 58103856StjrITYPE {IWORD}({WS}{IWORD})* 59103856Stjr 60103856Stjr%x in_struct in_struct_comment in_comment in_yacc_escape 61103856Stjr%option warn noyywrap nounput nodefault perf-report 62103856Stjr%option 8bit never-interactive 63103856Stjr%% 64103856Stjr 65103856Stjr[^[:alnum:]_]typedef{WS}(struct|union){WS}{ID}{WS}?[*[:space:]]{WS}?{ID}{WS}?";" { 66227753Stheraven char *tagstart; 67227753Stheraven size_t taglen; 68103856Stjr char *namestart; 69128002Stjr size_t namelen; 70128002Stjr int is_pointer = 0; 71205021Sjhb struct type *t; 72103856Stjr int union_p; 73103856Stjr 74103856Stjr tagstart = yytext + strlen (" typedef "); 75187302Srdivacky while (ISSPACE (*tagstart)) 76227753Stheraven tagstart++; 77103856Stjr union_p = tagstart[0] == 'u'; 78103856Stjr tagstart += strlen ("union "); 79103856Stjr while (ISSPACE (*tagstart)) 80103856Stjr tagstart++; 81103856Stjr for (taglen = 1; ISIDNUM (tagstart[taglen]); taglen++) 82103856Stjr ; 83103856Stjr for (namestart = tagstart + taglen; 84128002Stjr ! ISIDNUM (*namestart); 85187302Srdivacky namestart++) 86227753Stheraven if (*namestart == '*') 87103856Stjr is_pointer = 1; 88103856Stjr for (namelen = 1; ISIDNUM (namestart[namelen]); namelen++) 89103856Stjr ; 90103856Stjr t = find_structure ((const char *) xmemdup (tagstart, taglen, taglen+1), 91103856Stjr union_p); 92103856Stjr if (is_pointer) 93103856Stjr t = create_pointer (t); 94227753Stheraven namestart = (char *) xmemdup (namestart, namelen, namelen+1); 95103856Stjr#ifdef USE_MAPPED_LOCATION 96103856Stjr /* temporary kludge - gentype doesn't handle cpp conditionals */ 97103856Stjr if (strcmp (namestart, "location_t") != 0 98103856Stjr && strcmp (namestart, "expanded_location") != 0) 99227753Stheraven#endif 100227753Stheraven do_typedef (namestart, t, &lexer_line); 101227753Stheraven update_lineno (yytext, yyleng); 102227753Stheraven} 103227753Stheraven 104227753Stheraven[^[:alnum:]_]typedef{WS}{ITYPE}{WS}{ID}{WS}?";" { 105 106 char *namestart; 107 size_t namelen; 108 struct type *t; 109 char *typestart; 110 size_t typelen; 111 112 for (namestart = yytext + yyleng - 2; ISSPACE (*namestart); namestart--) 113 ; 114 for (namelen = 1; !ISSPACE (namestart[-namelen]); namelen++) 115 ; 116 namestart -= namelen - 1; 117 for (typestart = yytext + strlen (" typedef "); 118 ISSPACE(*typestart); 119 typestart++) 120 ; 121 for (typelen = namestart - typestart; 122 ISSPACE (typestart[typelen-1]); 123 typelen--) 124 ; 125 126 t = create_scalar_type (typestart, typelen); 127 do_typedef ((const char *) xmemdup (namestart, namelen, namelen+1), t, 128 &lexer_line); 129 update_lineno (yytext, yyleng); 130} 131 132[^[:alnum:]_]typedef{WS}{ID}{WS}{ID}{WS}PARAMS { 133 char *namestart; 134 size_t namelen; 135 struct type *t; 136 137 for (namestart = yytext + yyleng - 7; ISSPACE (*namestart); namestart--) 138 ; 139 for (namelen = 1; !ISSPACE (namestart[-namelen]); namelen++) 140 ; 141 namestart -= namelen - 1; 142 143 t = create_scalar_type ("function type", sizeof ("function type")-1); 144 do_typedef ((const char *) xmemdup (namestart, namelen, namelen+1), t, 145 &lexer_line); 146 update_lineno (yytext, yyleng); 147} 148 149[^[:alnum:]_]typedef{WS}{ID}{WS}{ID}{WS}"(" { 150 char *namestart; 151 size_t namelen; 152 struct type *t; 153 154 for (namestart = yytext + yyleng - 2; ISSPACE (*namestart); namestart--) 155 ; 156 for (namelen = 1; !ISSPACE (namestart[-namelen]); namelen++) 157 ; 158 namestart -= namelen - 1; 159 160 t = create_scalar_type ("function type", sizeof ("function type")-1); 161 do_typedef ((const char *) xmemdup (namestart, namelen, namelen+1), t, 162 &lexer_line); 163 update_lineno (yytext, yyleng); 164} 165 166[^[:alnum:]_]typedef{WS}{ID}{WS}?"*"?{WS}?"("{WS}?"*"{WS}?{ID}{WS}?")"{WS}?PARAMS { 167 char *namestart; 168 size_t namelen; 169 struct type *t; 170 171 for (namestart = yytext + yyleng - 7; !ISIDNUM (*namestart); namestart--) 172 ; 173 for (namelen = 1; ISIDNUM (namestart[-namelen]); namelen++) 174 ; 175 namestart -= namelen - 1; 176 177 t = create_scalar_type ("function type", sizeof ("function type")-1); 178 do_typedef ((const char *) xmemdup (namestart, namelen, namelen+1), t, 179 &lexer_line); 180 update_lineno (yytext, yyleng); 181} 182 183[^[:alnum:]_]typedef{WS}{ID}{WS}?"*"?{WS}?"("{WS}?"*"{WS}?{ID}{WS}?")"{WS}?"(" { 184 char *namestart; 185 size_t namelen; 186 struct type *t; 187 188 for (namestart = yytext + yyleng - 2; !ISIDNUM (*namestart); namestart--) 189 ; 190 for (namelen = 1; ISIDNUM (namestart[-namelen]); namelen++) 191 ; 192 namestart -= namelen - 1; 193 194 t = create_scalar_type ("function type", sizeof ("function type")-1); 195 do_typedef ((const char *) xmemdup (namestart, namelen, namelen+1), t, 196 &lexer_line); 197 update_lineno (yytext, yyleng); 198} 199 200[^[:alnum:]_](typedef{WS})?(struct|union){WS}{ID}{WS}/"GTY" { 201 char *tagstart; 202 size_t taglen; 203 int typedef_p; 204 int union_p; 205 206 typedef_p = yytext[1] == 't'; 207 if (typedef_p) 208 for (tagstart = yytext + strlen (" typedef "); 209 ISSPACE(*tagstart); 210 tagstart++) 211 ; 212 else 213 tagstart = yytext + 1; 214 215 union_p = tagstart[0] == 'u'; 216 tagstart += strlen ("union "); 217 while (ISSPACE (*tagstart)) 218 tagstart++; 219 for (taglen = 1; ISIDNUM (tagstart[taglen]); taglen++) 220 ; 221 222 yylval.t = find_structure ((const char *) xmemdup (tagstart, taglen, 223 taglen + 1), 224 union_p); 225 BEGIN(in_struct); 226 update_lineno (yytext, yyleng); 227 return typedef_p ? ENT_TYPEDEF_STRUCT : ENT_STRUCT; 228} 229 230[^[:alnum:]_](extern|static){WS}/"GTY" { 231 BEGIN(in_struct); 232 update_lineno (yytext, yyleng); 233 return ENT_EXTERNSTATIC; 234} 235 236^"%union"{WS}"{"{WS}/"GTY" { 237 BEGIN(in_struct); 238 update_lineno (yytext, yyleng); 239 return ENT_YACCUNION; 240} 241 242^"DEF_VEC_"[[:alnum:]_]*{WS}?"("{WS}?{ID}{WS}?(","{WS}?{ID}{WS}?)*")" { 243 char *macro, *arg; 244 unsigned macro_len, arg_len; 245 char *ptr = yytext; 246 const char *additional; 247 type_p t; 248 249 /* Find the macro name. */ 250 for (macro = ptr; *ptr != '(' && !ISSPACE (*ptr); ptr++) 251 continue; 252 for (macro_len = ptr - macro; !(ISALNUM (*ptr) || *ptr == '_'); ptr++) 253 continue; 254 255 /* Find the argument(s). */ 256 for (arg = ptr; *ptr != ')'; ptr++) 257 continue; 258 arg_len = ptr - arg; 259 260 /* Create the struct and typedef. */ 261 ptr = mangle_macro_name ("VEC", 3, arg, arg_len); 262 263 t = find_structure (ptr, 0); 264 do_typedef (ptr, t, &lexer_line); 265 266 /* Push the macro for later expansion. */ 267 additional = push_macro_expansion (macro, macro_len, arg, arg_len); 268 269 if (additional) 270 { 271 ptr = mangle_macro_name (ptr, strlen (ptr), 272 additional, strlen (additional)); 273 t = find_structure (ptr, 0); 274 do_typedef (ptr, t, &lexer_line); 275 } 276} 277 278<in_struct>{ 279 280"/*" { BEGIN(in_struct_comment); } 281 282^"%{" { BEGIN(in_yacc_escape); } /* } */ 283 284{WS} { update_lineno (yytext, yyleng); } 285 286"const"/[^[:alnum:]_] /* don't care */ 287"GTY"/[^[:alnum:]_] { return GTY_TOKEN; } 288"union"/[^[:alnum:]_] { return UNION; } 289"struct"/[^[:alnum:]_] { return STRUCT; } 290"enum"/[^[:alnum:]_] { return ENUM; } 291"ptr_alias"/[^[:alnum:]_] { return ALIAS; } 292"nested_ptr"/[^[:alnum:]_] { return NESTED_PTR; } 293[0-9]+ { return NUM; } 294"param"[0-9]*"_is"/[^[:alnum:]_] { 295 yylval.s = (const char *) xmemdup (yytext, yyleng, yyleng+1); 296 return PARAM_IS; 297} 298 299{IWORD}({WS}{IWORD})*/[^[:alnum:]_] | 300"ENUM_BITFIELD"{WS}?"("{WS}?{ID}{WS}?")" { 301 size_t len; 302 303 for (len = yyleng; ISSPACE (yytext[len-1]); len--) 304 ; 305 306 yylval.t = create_scalar_type (yytext, len); 307 update_lineno (yytext, yyleng); 308 return SCALAR; 309} 310 311"VEC"{WS}?"("{WS}?{ID}{WS}?(","{WS}?{ID}{WS}?)*")" { 312 char *macro, *arg; 313 unsigned macro_len, arg_len; 314 char *ptr = yytext; 315 316 /* Find the macro name */ 317 for (macro = ptr; *ptr != '(' && !ISSPACE (*ptr); ptr++) 318 continue; 319 for (macro_len = ptr - macro; !(ISALNUM(*ptr) || *ptr == '_'); ptr++) 320 continue; 321 322 /* Find the arguments. */ 323 for (arg = ptr; *ptr != ')'; ptr++) 324 continue; 325 arg_len = ptr - arg; 326 327 ptr = mangle_macro_name (macro, macro_len, arg, arg_len); 328 yylval.s = ptr; 329 return ID; 330} 331 332{ID}/[^[:alnum:]_] { 333 yylval.s = (const char *) xmemdup (yytext, yyleng, yyleng+1); 334 return ID; 335} 336 337\"([^"\\]|\\.)*\" { 338 yylval.s = (const char *) xmemdup (yytext+1, yyleng-2, yyleng-1); 339 return STRING; 340} 341"["[^\[\]]*"]" { 342 yylval.s = (const char *) xmemdup (yytext+1, yyleng-2, yyleng-1); 343 return ARRAY; 344} 345^"%"{ID} { 346 yylval.s = (const char *) xmemdup (yytext+1, yyleng-1, yyleng); 347 return PERCENT_ID; 348} 349"'"("\\".|[^\\])"'" { 350 yylval.s = (const char *) xmemdup (yytext+1, yyleng-2, yyleng); 351 return CHAR; 352} 353 354[(){},*:<>] { return yytext[0]; } 355 356[;=] { 357 if (lexer_toplevel_done) 358 { 359 BEGIN(INITIAL); 360 lexer_toplevel_done = 0; 361 } 362 return yytext[0]; 363} 364 365^"%%" { 366 BEGIN(INITIAL); 367 return PERCENTPERCENT; 368} 369 370"#define"[^\n]*\n {lexer_line.line++;} 371 372. { 373 error_at_line (&lexer_line, "unexpected character `%s'", yytext); 374} 375} 376 377"/*" { BEGIN(in_comment); } 378\n { lexer_line.line++; } 379{ID} | 380"'"("\\".|[^\\])"'" | 381[^"/\n] /* do nothing */ 382\"([^"\\]|\\.|\\\n)*\" { update_lineno (yytext, yyleng); } 383"/"/[^*] /* do nothing */ 384 385<in_comment,in_struct_comment>{ 386\n { lexer_line.line++; } 387[^*\n]{16} | 388[^*\n] /* do nothing */ 389"*"/[^/] /* do nothing */ 390} 391<in_comment>"*/" { BEGIN(INITIAL); } 392<in_struct_comment>"*/" { BEGIN(in_struct); } 393 394<in_yacc_escape>{ 395\n { lexer_line.line++; } 396[^%]{16} | 397[^%] /* do nothing */ 398"%"/[^}] /* do nothing */ 399"%}" { BEGIN(in_struct); } 400"%" { 401 error_at_line (&lexer_line, 402 "unterminated %%{; unexpected EOF"); 403} 404} 405 406 407["/] | 408<in_struct_comment,in_comment>"*" { 409 error_at_line (&lexer_line, 410 "unterminated comment or string; unexpected EOF"); 411} 412 413^"#define"{WS}"GTY(" /* do nothing */ 414{WS}"GTY"{WS}?"(" { 415 error_at_line (&lexer_line, "stray GTY marker"); 416} 417 418%% 419 420/* Deal with the expansion caused by the DEF_VEC_x macros. */ 421 422/* Mangle a macro and argument list as done by cpp concatenation in 423 the compiler proper. */ 424static char * 425mangle_macro_name (const char *macro, unsigned macro_len, 426 const char *arg, unsigned arg_len) 427{ 428 char *ptr = (char *) xmemdup (macro, macro_len, macro_len + arg_len + 2); 429 430 /* Now copy and concatenate each argument */ 431 while (arg_len) 432 { 433 ptr[macro_len++] = '_'; 434 for (; arg_len && (ISALNUM(*arg) || *arg == '_'); arg_len--) 435 ptr[macro_len++] = *arg++; 436 for (; arg_len && !(ISALNUM(*arg) || *arg == '_'); arg_len--) 437 arg++; 438 } 439 ptr[macro_len] = 0; 440 441 return ptr; 442} 443 444typedef struct macro_def 445{ 446 const char *name; 447 const char *expansion; 448 const char *additional; 449} macro_def_t; 450 451typedef struct macro 452{ 453 const macro_def_t *def; 454 struct macro *next; 455 const char *args[10]; 456} macro_t; 457 458static const macro_def_t macro_defs[] = 459{ 460#define IN_GENGTYPE 1 461#include "vec.h" 462 {NULL, NULL, NULL} 463}; 464 465/* Chain of macro expansions to do at end of scanning. */ 466static macro_t *macro_expns; 467static macro_t *macro_expns_end; 468 469/* Push macro NAME (NAME_LEN) with argument ARG (ARG_LEN) onto the 470 expansion queue. We ensure NAME is known at this point. */ 471 472static const char * 473push_macro_expansion (const char *name, unsigned name_len, 474 const char *arg, unsigned arg_len) 475{ 476 unsigned ix; 477 478 for (ix = 0; macro_defs[ix].name; ix++) 479 if (strlen (macro_defs[ix].name) == name_len 480 && !memcmp (name, macro_defs[ix].name, name_len)) 481 { 482 macro_t *expansion = XNEW (macro_t); 483 char *args; 484 unsigned argno, last_arg; 485 486 expansion->def = ¯o_defs[ix]; 487 expansion->next = NULL; 488 args = (char *) xmemdup (arg, arg_len, arg_len+1); 489 args[arg_len] = 0; 490 for (argno = 0; *args;) 491 { 492 expansion->args[argno++] = args; 493 while (*args && (ISALNUM (*args) || *args == '_')) 494 args++; 495 if (argno == 1) 496 expansion->args[argno++] = "base"; 497 if (!*args) 498 break; 499 *args++ = 0; 500 while (*args && !(ISALNUM (*args) || *args == '_')) 501 args++; 502 } 503 last_arg = argno; 504 for (; argno != 10; argno++) 505 expansion->args[argno] = NULL; 506 if (macro_expns_end) 507 macro_expns_end->next = expansion; 508 else 509 macro_expns = expansion; 510 macro_expns_end = expansion; 511 if (macro_defs[ix].additional) 512 { 513 macro_t *expn2 = XNEW (macro_t); 514 memcpy (expn2, expansion, sizeof (*expn2)); 515 expansion = expn2; 516 expansion->def += 1; 517 expansion->args[last_arg++] = macro_defs[ix].additional; 518 macro_expns_end->next = expansion; 519 macro_expns_end = expansion; 520 } 521 if (last_arg > 2 && strcmp (expansion->args[last_arg - 1], "heap")) 522 expansion->args[last_arg++] = "GTY (())"; 523 return macro_defs[ix].additional; 524 } 525 error_at_line (&lexer_line, "unrecognized macro `%.*s(%.*s)'", 526 name_len, name, arg_len, arg); 527 return NULL; 528} 529 530/* Attempt to read some input. Use fread until we're at the end of 531 file. At end of file expand the next queued macro. We presume the 532 buffer is large enough for the entire expansion. */ 533 534static unsigned 535macro_input (char *buffer, unsigned size) 536{ 537 unsigned result; 538 539 result = fread (buffer, 1, size, yyin); 540 if (result) 541 /*NOP*/; 542 else if (ferror (yyin)) 543 YY_FATAL_ERROR ("read of source file failed"); 544 else if (macro_expns) 545 { 546 const char *expn; 547 unsigned len; 548 549 for (expn = macro_expns->def->expansion; *expn; expn++) 550 { 551 if (*expn == '#') 552 { 553 int argno; 554 555 argno = expn[1] - '0'; 556 expn += 1; 557 558 /* Remove inserted space? */ 559 if (buffer[result-1] == ' ' && buffer[result-2] == '_') 560 result--; 561 562 /* Insert the argument value */ 563 if (macro_expns->args[argno]) 564 { 565 len = strlen (macro_expns->args[argno]); 566 memcpy (&buffer[result], macro_expns->args[argno], len); 567 result += len; 568 } 569 570 /* Skip next space? */ 571 if (expn[1] == ' ' && expn[2] == '_') 572 expn++; 573 } 574 else 575 { 576 buffer[result++] = *expn; 577 if (*expn == ';' || *expn == '{') 578 buffer[result++] = '\n'; 579 } 580 } 581 if (result > size) 582 YY_FATAL_ERROR ("buffer too small to expand macro"); 583 macro_expns = macro_expns->next; 584 if (!macro_expns) 585 macro_expns_end = NULL; 586 } 587 return result; 588} 589 590void 591yyerror (const char *s) 592{ 593 error_at_line (&lexer_line, "%s", s); 594} 595 596void 597parse_file (const char *fname) 598{ 599 yyin = fopen (fname, "r"); 600 lexer_line.file = fname; 601 lexer_line.line = 1; 602 if (yyin == NULL) 603 { 604 perror (fname); 605 exit (1); 606 } 607 if (yyparse() != 0) 608 exit (1); 609 fclose (yyin); 610} 611