|
|
1.1 ! root 1: /* Separate lexical analyzer for GNU C++. ! 2: Copyright (C) 1987, 1989, 1992, 1993, 1994 Free Software Foundation, Inc. ! 3: Hacked by Michael Tiemann ([email protected]) ! 4: ! 5: This file is part of GNU CC. ! 6: ! 7: GNU CC is free software; you can redistribute it and/or modify ! 8: it under the terms of the GNU General Public License as published by ! 9: the Free Software Foundation; either version 2, or (at your option) ! 10: any later version. ! 11: ! 12: GNU CC is distributed in the hope that it will be useful, ! 13: but WITHOUT ANY WARRANTY; without even the implied warranty of ! 14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 15: GNU General Public License for more details. ! 16: ! 17: You should have received a copy of the GNU General Public License ! 18: along with GNU CC; see the file COPYING. If not, write to ! 19: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ! 20: ! 21: ! 22: /* This file is the lexical analyzer for GNU C++. */ ! 23: ! 24: /* Cause the `yydebug' variable to be defined. */ ! 25: #define YYDEBUG 1 ! 26: ! 27: #include <sys/types.h> ! 28: #include <stdio.h> ! 29: #include <errno.h> ! 30: #include <setjmp.h> ! 31: #include "config.h" ! 32: #include "input.h" ! 33: #include "tree.h" ! 34: #include "lex.h" ! 35: #include "parse.h" ! 36: #include "cp-tree.h" ! 37: #include "flags.h" ! 38: #include "obstack.h" ! 39: ! 40: #ifdef MULTIBYTE_CHARS ! 41: #include <stdlib.h> ! 42: #include <locale.h> ! 43: #endif ! 44: ! 45: #ifndef errno ! 46: extern int errno; /* needed for VAX. */ ! 47: #endif ! 48: extern jmp_buf toplevel; ! 49: ! 50: #define obstack_chunk_alloc xmalloc ! 51: #define obstack_chunk_free free ! 52: ! 53: extern struct obstack *expression_obstack, permanent_obstack; ! 54: extern struct obstack *current_obstack, *saveable_obstack; ! 55: ! 56: extern double atof (); ! 57: ! 58: extern char *get_directive_line (); /* In c-common.c */ ! 59: ! 60: /* Given a file name X, return the nondirectory portion. ! 61: Keep in mind that X can be computed more than once. */ ! 62: #ifndef FILE_NAME_NONDIRECTORY ! 63: #define FILE_NAME_NONDIRECTORY(X) \ ! 64: (rindex (X, '/') != 0 ? rindex (X, '/') + 1 : X) ! 65: #endif ! 66: ! 67: extern char *index (); ! 68: extern char *rindex (); ! 69: ! 70: void extract_interface_info (); ! 71: void yyerror (); ! 72: ! 73: /* This obstack is needed to hold text. It is not safe to use ! 74: TOKEN_BUFFER because `check_newline' calls `yylex'. */ ! 75: struct obstack inline_text_obstack; ! 76: static char *inline_text_firstobj; ! 77: ! 78: /* This obstack is used to hold information about methods to be ! 79: synthesized. It should go away when synthesized methods are handled ! 80: properly (i.e. only when needed). */ ! 81: struct obstack synth_obstack; ! 82: static char *synth_firstobj; ! 83: ! 84: int end_of_file; ! 85: ! 86: /* Pending language change. ! 87: Positive is push count, negative is pop count. */ ! 88: int pending_lang_change = 0; ! 89: ! 90: /* Wrap the current header file in extern "C". */ ! 91: static int c_header_level = 0; ! 92: ! 93: extern int first_token; ! 94: extern struct obstack token_obstack; ! 95: ! 96: /* ??? Don't really know where this goes yet. */ ! 97: #if 1 ! 98: #include "input.c" ! 99: #else ! 100: extern void put_back (/* int */); ! 101: extern int input_redirected (); ! 102: extern void feed_input (/* char *, int, struct obstack * */); ! 103: #endif ! 104: ! 105: /* Holds translations from TREE_CODEs to operator name strings, ! 106: i.e., opname_tab[PLUS_EXPR] == "+". */ ! 107: char **opname_tab; ! 108: char **assignop_tab; ! 109: ! 110: extern int yychar; /* the lookahead symbol */ ! 111: extern YYSTYPE yylval; /* the semantic value of the */ ! 112: /* lookahead symbol */ ! 113: ! 114: #if 0 ! 115: YYLTYPE yylloc; /* location data for the lookahead */ ! 116: /* symbol */ ! 117: #endif ! 118: ! 119: ! 120: /* the declaration found for the last IDENTIFIER token read in. ! 121: yylex must look this up to detect typedefs, which get token type TYPENAME, ! 122: so it is left around in case the identifier is not a typedef but is ! 123: used in a context which makes it a reference to a variable. */ ! 124: tree lastiddecl; ! 125: ! 126: /* The elements of `ridpointers' are identifier nodes ! 127: for the reserved type names and storage classes. ! 128: It is indexed by a RID_... value. */ ! 129: tree ridpointers[(int) RID_MAX]; ! 130: ! 131: /* We may keep statistics about how long which files took to compile. */ ! 132: static int header_time, body_time; ! 133: static tree get_time_identifier (); ! 134: static tree filename_times; ! 135: static tree this_filename_time; ! 136: ! 137: /* For implementing #pragma unit. */ ! 138: tree current_unit_name; ! 139: tree current_unit_language; ! 140: ! 141: /* Array for holding counts of the numbers of tokens seen. */ ! 142: extern int *token_count; ! 143: ! 144: /* Textual definition used for default functions. */ ! 145: static void default_copy_constructor_body (); ! 146: static void default_assign_ref_body (); ! 147: ! 148: /* Return something to represent absolute declarators containing a *. ! 149: TARGET is the absolute declarator that the * contains. ! 150: TYPE_QUALS is a list of modifiers such as const or volatile ! 151: to apply to the pointer type, represented as identifiers. ! 152: ! 153: We return an INDIRECT_REF whose "contents" are TARGET ! 154: and whose type is the modifier list. */ ! 155: ! 156: tree ! 157: make_pointer_declarator (type_quals, target) ! 158: tree type_quals, target; ! 159: { ! 160: if (target && TREE_CODE (target) == IDENTIFIER_NODE ! 161: && ANON_AGGRNAME_P (target)) ! 162: error ("type name expected before `*'"); ! 163: target = build_parse_node (INDIRECT_REF, target); ! 164: TREE_TYPE (target) = type_quals; ! 165: return target; ! 166: } ! 167: ! 168: /* Return something to represent absolute declarators containing a &. ! 169: TARGET is the absolute declarator that the & contains. ! 170: TYPE_QUALS is a list of modifiers such as const or volatile ! 171: to apply to the reference type, represented as identifiers. ! 172: ! 173: We return an ADDR_EXPR whose "contents" are TARGET ! 174: and whose type is the modifier list. */ ! 175: ! 176: tree ! 177: make_reference_declarator (type_quals, target) ! 178: tree type_quals, target; ! 179: { ! 180: if (target) ! 181: { ! 182: if (TREE_CODE (target) == ADDR_EXPR) ! 183: { ! 184: error ("cannot declare references to references"); ! 185: return target; ! 186: } ! 187: if (TREE_CODE (target) == INDIRECT_REF) ! 188: { ! 189: error ("cannot declare pointers to references"); ! 190: return target; ! 191: } ! 192: if (TREE_CODE (target) == IDENTIFIER_NODE && ANON_AGGRNAME_P (target)) ! 193: error ("type name expected before `&'"); ! 194: } ! 195: target = build_parse_node (ADDR_EXPR, target); ! 196: TREE_TYPE (target) = type_quals; ! 197: return target; ! 198: } ! 199: ! 200: /* Build names and nodes for overloaded operators. */ ! 201: ! 202: tree ansi_opname[LAST_CPLUS_TREE_CODE]; ! 203: tree ansi_assopname[LAST_CPLUS_TREE_CODE]; ! 204: ! 205: char * ! 206: operator_name_string (name) ! 207: tree name; ! 208: { ! 209: char *opname = IDENTIFIER_POINTER (name) + 2; ! 210: tree *opname_table; ! 211: int i, assign; ! 212: ! 213: /* Works for builtin and user defined types. */ ! 214: if (IDENTIFIER_GLOBAL_VALUE (name) ! 215: && TREE_CODE (IDENTIFIER_GLOBAL_VALUE (name)) == TYPE_DECL) ! 216: return IDENTIFIER_POINTER (name); ! 217: ! 218: if (opname[0] == 'a' && opname[2] != '\0' && opname[2] != '_') ! 219: { ! 220: opname += 1; ! 221: assign = 1; ! 222: opname_table = ansi_assopname; ! 223: } ! 224: else ! 225: { ! 226: assign = 0; ! 227: opname_table = ansi_opname; ! 228: } ! 229: ! 230: for (i = 0; i < (int) LAST_CPLUS_TREE_CODE; i++) ! 231: { ! 232: if (opname[0] == IDENTIFIER_POINTER (opname_table[i])[2+assign] ! 233: && opname[1] == IDENTIFIER_POINTER (opname_table[i])[3+assign]) ! 234: break; ! 235: } ! 236: ! 237: if (i == LAST_CPLUS_TREE_CODE) ! 238: return "<invalid operator>"; ! 239: ! 240: if (assign) ! 241: return assignop_tab[i]; ! 242: else ! 243: return opname_tab[i]; ! 244: } ! 245: ! 246: int interface_only; /* whether or not current file is only for ! 247: interface definitions. */ ! 248: int interface_unknown; /* whether or not we know this class ! 249: to behave according to #pragma interface. */ ! 250: ! 251: /* lexical analyzer */ ! 252: ! 253: /* File used for outputting assembler code. */ ! 254: extern FILE *asm_out_file; ! 255: ! 256: #ifndef WCHAR_TYPE_SIZE ! 257: #ifdef INT_TYPE_SIZE ! 258: #define WCHAR_TYPE_SIZE INT_TYPE_SIZE ! 259: #else ! 260: #define WCHAR_TYPE_SIZE BITS_PER_WORD ! 261: #endif ! 262: #endif ! 263: ! 264: /* Number of bytes in a wide character. */ ! 265: #define WCHAR_BYTES (WCHAR_TYPE_SIZE / BITS_PER_UNIT) ! 266: ! 267: static int maxtoken; /* Current nominal length of token buffer. */ ! 268: char *token_buffer; /* Pointer to token buffer. ! 269: Actual allocated length is maxtoken + 2. */ ! 270: ! 271: #include "hash.h" ! 272: ! 273: int check_newline (); ! 274: ! 275: /* Nonzero tells yylex to ignore \ in string constants. */ ! 276: static int ignore_escape_flag = 0; ! 277: ! 278: static int skip_white_space (); ! 279: ! 280: static tree ! 281: get_time_identifier (name) ! 282: char *name; ! 283: { ! 284: tree time_identifier; ! 285: int len = strlen (name); ! 286: char *buf = (char *) alloca (len + 6); ! 287: strcpy (buf, "file "); ! 288: bcopy (name, buf+5, len); ! 289: buf[len+5] = '\0'; ! 290: time_identifier = get_identifier (buf); ! 291: if (IDENTIFIER_LOCAL_VALUE (time_identifier) == NULL_TREE) ! 292: { ! 293: push_obstacks_nochange (); ! 294: end_temporary_allocation (); ! 295: IDENTIFIER_LOCAL_VALUE (time_identifier) = build_int_2 (0, 0); ! 296: IDENTIFIER_CLASS_VALUE (time_identifier) = build_int_2 (0, 1); ! 297: IDENTIFIER_GLOBAL_VALUE (time_identifier) = filename_times; ! 298: filename_times = time_identifier; ! 299: pop_obstacks (); ! 300: } ! 301: return time_identifier; ! 302: } ! 303: ! 304: #ifdef __GNUC__ ! 305: __inline ! 306: #endif ! 307: static int ! 308: my_get_run_time () ! 309: { ! 310: int old_quiet_flag = quiet_flag; ! 311: int this_time; ! 312: quiet_flag = 0; ! 313: this_time = get_run_time (); ! 314: quiet_flag = old_quiet_flag; ! 315: return this_time; ! 316: } ! 317: ! 318: /* Table indexed by tree code giving a string containing a character ! 319: classifying the tree code. Possibilities are ! 320: t, d, s, c, r, <, 1 and 2. See cp/tree.def for details. */ ! 321: ! 322: #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE, ! 323: ! 324: char *cplus_tree_code_type[] = { ! 325: "x", ! 326: #include "tree.def" ! 327: }; ! 328: #undef DEFTREECODE ! 329: ! 330: /* Table indexed by tree code giving number of expression ! 331: operands beyond the fixed part of the node structure. ! 332: Not used for types or decls. */ ! 333: ! 334: #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH, ! 335: ! 336: int cplus_tree_code_length[] = { ! 337: 0, ! 338: #include "tree.def" ! 339: }; ! 340: #undef DEFTREECODE ! 341: ! 342: /* Names of tree components. ! 343: Used for printing out the tree and error messages. */ ! 344: #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME, ! 345: ! 346: char *cplus_tree_code_name[] = { ! 347: "@@dummy", ! 348: #include "tree.def" ! 349: }; ! 350: #undef DEFTREECODE ! 351: ! 352: /* toplev.c needs to call these. */ ! 353: ! 354: void ! 355: lang_init () ! 356: { ! 357: /* the beginning of the file is a new line; check for # */ ! 358: /* With luck, we discover the real source file's name from that ! 359: and put it in input_filename. */ ! 360: put_back (check_newline ()); ! 361: ! 362: if (flag_cadillac) ! 363: cadillac_start (); ! 364: if (flag_gnu_xref) GNU_xref_begin (input_filename); ! 365: } ! 366: ! 367: void ! 368: lang_finish () ! 369: { ! 370: extern int errorcount, sorrycount; ! 371: if (flag_gnu_xref) GNU_xref_end (errorcount+sorrycount); ! 372: } ! 373: ! 374: char * ! 375: lang_identify () ! 376: { ! 377: return "cplusplus"; ! 378: } ! 379: ! 380: void ! 381: init_filename_times () ! 382: { ! 383: this_filename_time = get_time_identifier ("<top level>"); ! 384: if (flag_detailed_statistics) ! 385: { ! 386: header_time = 0; ! 387: body_time = my_get_run_time (); ! 388: TREE_INT_CST_LOW (IDENTIFIER_LOCAL_VALUE (this_filename_time)) = body_time; ! 389: } ! 390: } ! 391: ! 392: /* Change by Bryan Boreham, Kewill, Thu Jul 27 09:46:05 1989. ! 393: Stuck this hack in to get the files open correctly; this is called ! 394: in place of init_lex if we are an unexec'd binary. */ ! 395: void ! 396: reinit_lang_specific () ! 397: { ! 398: init_filename_times (); ! 399: reinit_search_statistics (); ! 400: } ! 401: ! 402: void ! 403: init_lex () ! 404: { ! 405: extern char *(*decl_printable_name) (); ! 406: ! 407: int i; ! 408: ! 409: /* Initialize the lookahead machinery. */ ! 410: init_spew (); ! 411: ! 412: /* Make identifier nodes long enough for the language-specific slots. */ ! 413: set_identifier_size (sizeof (struct lang_identifier)); ! 414: decl_printable_name = lang_printable_name; ! 415: ! 416: init_cplus_expand (); ! 417: ! 418: tree_code_type ! 419: = (char **) realloc (tree_code_type, ! 420: sizeof (char *) * LAST_CPLUS_TREE_CODE); ! 421: tree_code_length ! 422: = (int *) realloc (tree_code_length, ! 423: sizeof (int) * LAST_CPLUS_TREE_CODE); ! 424: tree_code_name ! 425: = (char **) realloc (tree_code_name, ! 426: sizeof (char *) * LAST_CPLUS_TREE_CODE); ! 427: bcopy ((char *)cplus_tree_code_type, ! 428: (char *)(tree_code_type + (int) LAST_AND_UNUSED_TREE_CODE), ! 429: (LAST_CPLUS_TREE_CODE - (int)LAST_AND_UNUSED_TREE_CODE) * sizeof (char *)); ! 430: bcopy ((char *)cplus_tree_code_length, ! 431: (char *)(tree_code_length + (int) LAST_AND_UNUSED_TREE_CODE), ! 432: (LAST_CPLUS_TREE_CODE - (int)LAST_AND_UNUSED_TREE_CODE) * sizeof (int)); ! 433: bcopy ((char *)cplus_tree_code_name, ! 434: (char *)(tree_code_name + (int) LAST_AND_UNUSED_TREE_CODE), ! 435: (LAST_CPLUS_TREE_CODE - (int)LAST_AND_UNUSED_TREE_CODE) * sizeof (char *)); ! 436: ! 437: opname_tab = (char **)oballoc ((int)LAST_CPLUS_TREE_CODE * sizeof (char *)); ! 438: bzero ((char *)opname_tab, (int)LAST_CPLUS_TREE_CODE * sizeof (char *)); ! 439: assignop_tab = (char **)oballoc ((int)LAST_CPLUS_TREE_CODE * sizeof (char *)); ! 440: bzero ((char *)assignop_tab, (int)LAST_CPLUS_TREE_CODE * sizeof (char *)); ! 441: ! 442: ansi_opname[0] = get_identifier ("<invalid operator>"); ! 443: for (i = 0; i < (int) LAST_CPLUS_TREE_CODE; i++) ! 444: { ! 445: ansi_opname[i] = ansi_opname[0]; ! 446: ansi_assopname[i] = ansi_opname[0]; ! 447: } ! 448: ! 449: ansi_opname[(int) MULT_EXPR] = get_identifier ("__ml"); ! 450: IDENTIFIER_OPNAME_P (ansi_opname[(int) MULT_EXPR]) = 1; ! 451: ansi_opname[(int) INDIRECT_REF] = ansi_opname[(int) MULT_EXPR]; ! 452: ansi_assopname[(int) MULT_EXPR] = get_identifier ("__aml"); ! 453: IDENTIFIER_OPNAME_P (ansi_assopname[(int) MULT_EXPR]) = 1; ! 454: ansi_assopname[(int) INDIRECT_REF] = ansi_assopname[(int) MULT_EXPR]; ! 455: ansi_opname[(int) TRUNC_MOD_EXPR] = get_identifier ("__md"); ! 456: IDENTIFIER_OPNAME_P (ansi_opname[(int) TRUNC_MOD_EXPR]) = 1; ! 457: ansi_assopname[(int) TRUNC_MOD_EXPR] = get_identifier ("__amd"); ! 458: IDENTIFIER_OPNAME_P (ansi_assopname[(int) TRUNC_MOD_EXPR]) = 1; ! 459: ansi_opname[(int) CEIL_MOD_EXPR] = ansi_opname[(int) TRUNC_MOD_EXPR]; ! 460: ansi_opname[(int) FLOOR_MOD_EXPR] = ansi_opname[(int) TRUNC_MOD_EXPR]; ! 461: ansi_opname[(int) ROUND_MOD_EXPR] = ansi_opname[(int) TRUNC_MOD_EXPR]; ! 462: ansi_opname[(int) MINUS_EXPR] = get_identifier ("__mi"); ! 463: IDENTIFIER_OPNAME_P (ansi_opname[(int) MINUS_EXPR]) = 1; ! 464: ansi_opname[(int) NEGATE_EXPR] = ansi_opname[(int) MINUS_EXPR]; ! 465: ansi_assopname[(int) MINUS_EXPR] = get_identifier ("__ami"); ! 466: IDENTIFIER_OPNAME_P (ansi_assopname[(int) MINUS_EXPR]) = 1; ! 467: ansi_assopname[(int) NEGATE_EXPR] = ansi_assopname[(int) MINUS_EXPR]; ! 468: ansi_opname[(int) RSHIFT_EXPR] = get_identifier ("__rs"); ! 469: IDENTIFIER_OPNAME_P (ansi_opname[(int) RSHIFT_EXPR]) = 1; ! 470: ansi_assopname[(int) RSHIFT_EXPR] = get_identifier ("__ars"); ! 471: IDENTIFIER_OPNAME_P (ansi_assopname[(int) RSHIFT_EXPR]) = 1; ! 472: ansi_opname[(int) NE_EXPR] = get_identifier ("__ne"); ! 473: IDENTIFIER_OPNAME_P (ansi_opname[(int) NE_EXPR]) = 1; ! 474: ansi_opname[(int) GT_EXPR] = get_identifier ("__gt"); ! 475: IDENTIFIER_OPNAME_P (ansi_opname[(int) GT_EXPR]) = 1; ! 476: ansi_opname[(int) GE_EXPR] = get_identifier ("__ge"); ! 477: IDENTIFIER_OPNAME_P (ansi_opname[(int) GE_EXPR]) = 1; ! 478: ansi_opname[(int) BIT_IOR_EXPR] = get_identifier ("__or"); ! 479: IDENTIFIER_OPNAME_P (ansi_opname[(int) BIT_IOR_EXPR]) = 1; ! 480: ansi_assopname[(int) BIT_IOR_EXPR] = get_identifier ("__aor"); ! 481: IDENTIFIER_OPNAME_P (ansi_assopname[(int) BIT_IOR_EXPR]) = 1; ! 482: ansi_opname[(int) TRUTH_ANDIF_EXPR] = get_identifier ("__aa"); ! 483: IDENTIFIER_OPNAME_P (ansi_opname[(int) TRUTH_ANDIF_EXPR]) = 1; ! 484: ansi_opname[(int) TRUTH_NOT_EXPR] = get_identifier ("__nt"); ! 485: IDENTIFIER_OPNAME_P (ansi_opname[(int) TRUTH_NOT_EXPR]) = 1; ! 486: ansi_opname[(int) PREINCREMENT_EXPR] = get_identifier ("__pp"); ! 487: IDENTIFIER_OPNAME_P (ansi_opname[(int) PREINCREMENT_EXPR]) = 1; ! 488: ansi_opname[(int) POSTINCREMENT_EXPR] = ansi_opname[(int) PREINCREMENT_EXPR]; ! 489: ansi_opname[(int) MODIFY_EXPR] = get_identifier ("__as"); ! 490: IDENTIFIER_OPNAME_P (ansi_opname[(int) MODIFY_EXPR]) = 1; ! 491: ansi_assopname[(int) NOP_EXPR] = ansi_opname[(int) MODIFY_EXPR]; ! 492: ansi_opname[(int) COMPOUND_EXPR] = get_identifier ("__cm"); ! 493: IDENTIFIER_OPNAME_P (ansi_opname[(int) COMPOUND_EXPR]) = 1; ! 494: ansi_opname[(int) EXACT_DIV_EXPR] = get_identifier ("__dv"); ! 495: IDENTIFIER_OPNAME_P (ansi_opname[(int) EXACT_DIV_EXPR]) = 1; ! 496: ansi_assopname[(int) EXACT_DIV_EXPR] = get_identifier ("__adv"); ! 497: IDENTIFIER_OPNAME_P (ansi_assopname[(int) EXACT_DIV_EXPR]) = 1; ! 498: ansi_opname[(int) TRUNC_DIV_EXPR] = ansi_opname[(int) EXACT_DIV_EXPR]; ! 499: ansi_opname[(int) CEIL_DIV_EXPR] = ansi_opname[(int) EXACT_DIV_EXPR]; ! 500: ansi_opname[(int) FLOOR_DIV_EXPR] = ansi_opname[(int) EXACT_DIV_EXPR]; ! 501: ansi_opname[(int) ROUND_DIV_EXPR] = ansi_opname[(int) EXACT_DIV_EXPR]; ! 502: ansi_opname[(int) PLUS_EXPR] = get_identifier ("__pl"); ! 503: ansi_assopname[(int) TRUNC_DIV_EXPR] = ansi_assopname[(int) EXACT_DIV_EXPR]; ! 504: ansi_assopname[(int) CEIL_DIV_EXPR] = ansi_assopname[(int) EXACT_DIV_EXPR]; ! 505: ansi_assopname[(int) FLOOR_DIV_EXPR] = ansi_assopname[(int) EXACT_DIV_EXPR]; ! 506: ansi_assopname[(int) ROUND_DIV_EXPR] = ansi_assopname[(int) EXACT_DIV_EXPR]; ! 507: IDENTIFIER_OPNAME_P (ansi_opname[(int) PLUS_EXPR]) = 1; ! 508: ansi_assopname[(int) PLUS_EXPR] = get_identifier ("__apl"); ! 509: IDENTIFIER_OPNAME_P (ansi_assopname[(int) PLUS_EXPR]) = 1; ! 510: ansi_opname[(int) CONVERT_EXPR] = ansi_opname[(int) PLUS_EXPR]; ! 511: ansi_assopname[(int) CONVERT_EXPR] = ansi_assopname[(int) PLUS_EXPR]; ! 512: ansi_opname[(int) LSHIFT_EXPR] = get_identifier ("__ls"); ! 513: IDENTIFIER_OPNAME_P (ansi_opname[(int) LSHIFT_EXPR]) = 1; ! 514: ansi_assopname[(int) LSHIFT_EXPR] = get_identifier ("__als"); ! 515: IDENTIFIER_OPNAME_P (ansi_assopname[(int) LSHIFT_EXPR]) = 1; ! 516: ansi_opname[(int) EQ_EXPR] = get_identifier ("__eq"); ! 517: IDENTIFIER_OPNAME_P (ansi_opname[(int) EQ_EXPR]) = 1; ! 518: ansi_opname[(int) LT_EXPR] = get_identifier ("__lt"); ! 519: IDENTIFIER_OPNAME_P (ansi_opname[(int) LT_EXPR]) = 1; ! 520: ansi_opname[(int) LE_EXPR] = get_identifier ("__le"); ! 521: IDENTIFIER_OPNAME_P (ansi_opname[(int) LE_EXPR]) = 1; ! 522: ansi_opname[(int) BIT_AND_EXPR] = get_identifier ("__ad"); ! 523: IDENTIFIER_OPNAME_P (ansi_opname[(int) BIT_AND_EXPR]) = 1; ! 524: ansi_assopname[(int) BIT_AND_EXPR] = get_identifier ("__aad"); ! 525: IDENTIFIER_OPNAME_P (ansi_assopname[(int) BIT_AND_EXPR]) = 1; ! 526: ansi_opname[(int) ADDR_EXPR] = ansi_opname[(int) BIT_AND_EXPR]; ! 527: ansi_assopname[(int) ADDR_EXPR] = ansi_assopname[(int) BIT_AND_EXPR]; ! 528: ansi_opname[(int) BIT_XOR_EXPR] = get_identifier ("__er"); ! 529: IDENTIFIER_OPNAME_P (ansi_opname[(int) BIT_XOR_EXPR]) = 1; ! 530: ansi_assopname[(int) BIT_XOR_EXPR] = get_identifier ("__aer"); ! 531: IDENTIFIER_OPNAME_P (ansi_assopname[(int) BIT_XOR_EXPR]) = 1; ! 532: ansi_opname[(int) TRUTH_ORIF_EXPR] = get_identifier ("__oo"); ! 533: IDENTIFIER_OPNAME_P (ansi_opname[(int) TRUTH_ORIF_EXPR]) = 1; ! 534: ansi_opname[(int) BIT_NOT_EXPR] = get_identifier ("__co"); ! 535: IDENTIFIER_OPNAME_P (ansi_opname[(int) BIT_NOT_EXPR]) = 1; ! 536: ansi_opname[(int) PREDECREMENT_EXPR] = get_identifier ("__mm"); ! 537: IDENTIFIER_OPNAME_P (ansi_opname[(int) PREDECREMENT_EXPR]) = 1; ! 538: ansi_opname[(int) POSTDECREMENT_EXPR] = ansi_opname[(int) PREDECREMENT_EXPR]; ! 539: ansi_opname[(int) COMPONENT_REF] = get_identifier ("__rf"); ! 540: IDENTIFIER_OPNAME_P (ansi_opname[(int) COMPONENT_REF]) = 1; ! 541: ansi_opname[(int) MEMBER_REF] = get_identifier ("__rm"); ! 542: IDENTIFIER_OPNAME_P (ansi_opname[(int) MEMBER_REF]) = 1; ! 543: ansi_opname[(int) CALL_EXPR] = get_identifier ("__cl"); ! 544: IDENTIFIER_OPNAME_P (ansi_opname[(int) CALL_EXPR]) = 1; ! 545: ansi_opname[(int) ARRAY_REF] = get_identifier ("__vc"); ! 546: IDENTIFIER_OPNAME_P (ansi_opname[(int) ARRAY_REF]) = 1; ! 547: ansi_opname[(int) NEW_EXPR] = get_identifier ("__nw"); ! 548: IDENTIFIER_OPNAME_P (ansi_opname[(int) NEW_EXPR]) = 1; ! 549: ansi_opname[(int) DELETE_EXPR] = get_identifier ("__dl"); ! 550: IDENTIFIER_OPNAME_P (ansi_opname[(int) DELETE_EXPR]) = 1; ! 551: ansi_opname[(int) VEC_NEW_EXPR] = get_identifier ("__vn"); ! 552: IDENTIFIER_OPNAME_P (ansi_opname[(int) VEC_NEW_EXPR]) = 1; ! 553: ansi_opname[(int) VEC_DELETE_EXPR] = get_identifier ("__vd"); ! 554: IDENTIFIER_OPNAME_P (ansi_opname[(int) VEC_DELETE_EXPR]) = 1; ! 555: ansi_opname[(int) TYPE_EXPR] = get_identifier ("__op"); ! 556: IDENTIFIER_OPNAME_P (ansi_opname[(int) TYPE_EXPR]) = 1; ! 557: ! 558: /* This is not true: these operators are not defined in ANSI, ! 559: but we need them anyway. */ ! 560: ansi_opname[(int) MIN_EXPR] = get_identifier ("__mn"); ! 561: IDENTIFIER_OPNAME_P (ansi_opname[(int) MIN_EXPR]) = 1; ! 562: ansi_opname[(int) MAX_EXPR] = get_identifier ("__mx"); ! 563: IDENTIFIER_OPNAME_P (ansi_opname[(int) MAX_EXPR]) = 1; ! 564: ansi_opname[(int) COND_EXPR] = get_identifier ("__cn"); ! 565: IDENTIFIER_OPNAME_P (ansi_opname[(int) COND_EXPR]) = 1; ! 566: ansi_opname[(int) METHOD_CALL_EXPR] = get_identifier ("__wr"); ! 567: IDENTIFIER_OPNAME_P (ansi_opname[(int) METHOD_CALL_EXPR]) = 1; ! 568: ! 569: init_method (); ! 570: init_error (); ! 571: gcc_obstack_init (&inline_text_obstack); ! 572: inline_text_firstobj = (char *) obstack_alloc (&inline_text_obstack, 0); ! 573: gcc_obstack_init (&synth_obstack); ! 574: synth_firstobj = (char *) obstack_alloc (&synth_obstack, 0); ! 575: ! 576: /* Start it at 0, because check_newline is called at the very beginning ! 577: and will increment it to 1. */ ! 578: lineno = 0; ! 579: input_filename = "<internal>"; ! 580: current_function_decl = NULL; ! 581: ! 582: maxtoken = 40; ! 583: token_buffer = (char *) xmalloc (maxtoken + 2); ! 584: ! 585: ridpointers[(int) RID_INT] = get_identifier ("int"); ! 586: SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_INT], ! 587: build_tree_list (NULL_TREE, ridpointers[(int) RID_INT])); ! 588: ridpointers[(int) RID_BOOL] = get_identifier ("bool"); ! 589: SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_BOOL], ! 590: build_tree_list (NULL_TREE, ridpointers[(int) RID_BOOL])); ! 591: ridpointers[(int) RID_CHAR] = get_identifier ("char"); ! 592: SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_CHAR], ! 593: build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR])); ! 594: ridpointers[(int) RID_VOID] = get_identifier ("void"); ! 595: SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_VOID], ! 596: build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID])); ! 597: ridpointers[(int) RID_FLOAT] = get_identifier ("float"); ! 598: SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_FLOAT], ! 599: build_tree_list (NULL_TREE, ridpointers[(int) RID_FLOAT])); ! 600: ridpointers[(int) RID_DOUBLE] = get_identifier ("double"); ! 601: SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_DOUBLE], ! 602: build_tree_list (NULL_TREE, ridpointers[(int) RID_DOUBLE])); ! 603: ridpointers[(int) RID_SHORT] = get_identifier ("short"); ! 604: SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_SHORT], ! 605: build_tree_list (NULL_TREE, ridpointers[(int) RID_SHORT])); ! 606: ridpointers[(int) RID_LONG] = get_identifier ("long"); ! 607: SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_LONG], ! 608: build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG])); ! 609: ridpointers[(int) RID_UNSIGNED] = get_identifier ("unsigned"); ! 610: SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_UNSIGNED], ! 611: build_tree_list (NULL_TREE, ridpointers[(int) RID_UNSIGNED])); ! 612: ridpointers[(int) RID_SIGNED] = get_identifier ("signed"); ! 613: SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_SIGNED], ! 614: build_tree_list (NULL_TREE, ridpointers[(int) RID_SIGNED])); ! 615: ridpointers[(int) RID_INLINE] = get_identifier ("inline"); ! 616: SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_INLINE], ! 617: build_tree_list (NULL_TREE, ridpointers[(int) RID_INLINE])); ! 618: ridpointers[(int) RID_CONST] = get_identifier ("const"); ! 619: SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_CONST], ! 620: build_tree_list (NULL_TREE, ridpointers[(int) RID_CONST])); ! 621: ridpointers[(int) RID_VOLATILE] = get_identifier ("volatile"); ! 622: SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_VOLATILE], ! 623: build_tree_list (NULL_TREE, ridpointers[(int) RID_VOLATILE])); ! 624: ridpointers[(int) RID_AUTO] = get_identifier ("auto"); ! 625: SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_AUTO], ! 626: build_tree_list (NULL_TREE, ridpointers[(int) RID_AUTO])); ! 627: ridpointers[(int) RID_STATIC] = get_identifier ("static"); ! 628: SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_STATIC], ! 629: build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC])); ! 630: ridpointers[(int) RID_EXTERN] = get_identifier ("extern"); ! 631: SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_EXTERN], ! 632: build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN])); ! 633: ridpointers[(int) RID_TYPEDEF] = get_identifier ("typedef"); ! 634: SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_TYPEDEF], ! 635: build_tree_list (NULL_TREE, ridpointers[(int) RID_TYPEDEF])); ! 636: ridpointers[(int) RID_REGISTER] = get_identifier ("register"); ! 637: SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_REGISTER], ! 638: build_tree_list (NULL_TREE, ridpointers[(int) RID_REGISTER])); ! 639: ! 640: /* C++ extensions. These are probably not correctly named. */ ! 641: ridpointers[(int) RID_WCHAR] = get_identifier ("__wchar_t"); ! 642: SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_WCHAR], ! 643: build_tree_list (NULL_TREE, ridpointers[(int) RID_WCHAR])); ! 644: class_type_node = build_int_2 (class_type, 0); ! 645: TREE_TYPE (class_type_node) = class_type_node; ! 646: ridpointers[(int) RID_CLASS] = class_type_node; ! 647: ! 648: record_type_node = build_int_2 (record_type, 0); ! 649: TREE_TYPE (record_type_node) = record_type_node; ! 650: ridpointers[(int) RID_RECORD] = record_type_node; ! 651: ! 652: union_type_node = build_int_2 (union_type, 0); ! 653: TREE_TYPE (union_type_node) = union_type_node; ! 654: ridpointers[(int) RID_UNION] = union_type_node; ! 655: ! 656: enum_type_node = build_int_2 (enum_type, 0); ! 657: TREE_TYPE (enum_type_node) = enum_type_node; ! 658: ridpointers[(int) RID_ENUM] = enum_type_node; ! 659: ! 660: ridpointers[(int) RID_VIRTUAL] = get_identifier ("virtual"); ! 661: SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_VIRTUAL], ! 662: build_tree_list (NULL_TREE, ridpointers[(int) RID_VIRTUAL])); ! 663: ridpointers[(int) RID_FRIEND] = get_identifier ("friend"); ! 664: SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_FRIEND], ! 665: build_tree_list (NULL_TREE, ridpointers[(int) RID_FRIEND])); ! 666: ! 667: ridpointers[(int) RID_PUBLIC] = get_identifier ("public"); ! 668: SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_PUBLIC], ! 669: build_tree_list (NULL_TREE, ridpointers[(int) RID_PUBLIC])); ! 670: ridpointers[(int) RID_PRIVATE] = get_identifier ("private"); ! 671: SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_PRIVATE], ! 672: build_tree_list (NULL_TREE, ridpointers[(int) RID_PRIVATE])); ! 673: ridpointers[(int) RID_PROTECTED] = get_identifier ("protected"); ! 674: SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_PROTECTED], ! 675: build_tree_list (NULL_TREE, ridpointers[(int) RID_PROTECTED])); ! 676: ridpointers[(int) RID_TEMPLATE] = get_identifier ("template"); ! 677: SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_TEMPLATE], ! 678: build_tree_list (NULL_TREE, ridpointers[(int) RID_TEMPLATE])); ! 679: /* This is for ANSI C++. */ ! 680: ridpointers[(int) RID_MUTABLE] = get_identifier ("mutable"); ! 681: SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_MUTABLE], ! 682: build_tree_list (NULL_TREE, ridpointers[(int) RID_MUTABLE])); ! 683: ! 684: /* Exception handling extensions. */ ! 685: exception_type_node = build_int_2 (exception_type, 0); ! 686: TREE_TYPE (exception_type_node) = exception_type_node; ! 687: ridpointers[(int) RID_EXCEPTION] = exception_type_node; ! 688: ! 689: /* Signature handling extensions. */ ! 690: signature_type_node = build_int_2 (signature_type, 0); ! 691: TREE_TYPE (signature_type_node) = signature_type_node; ! 692: ridpointers[(int) RID_SIGNATURE] = signature_type_node; ! 693: ! 694: opname_tab[(int) COMPONENT_REF] = "->"; ! 695: opname_tab[(int) MEMBER_REF] = "->*"; ! 696: opname_tab[(int) METHOD_CALL_EXPR] = "->()"; ! 697: opname_tab[(int) INDIRECT_REF] = "(unary *)"; ! 698: opname_tab[(int) ARRAY_REF] = "[]"; ! 699: opname_tab[(int) MODIFY_EXPR] = "="; ! 700: opname_tab[(int) NEW_EXPR] = "new"; ! 701: opname_tab[(int) DELETE_EXPR] = "delete"; ! 702: opname_tab[(int) VEC_NEW_EXPR] = "new []"; ! 703: opname_tab[(int) VEC_DELETE_EXPR] = "delete []"; ! 704: opname_tab[(int) COND_EXPR] = "... ? ... : ..."; ! 705: opname_tab[(int) CALL_EXPR] = "()"; ! 706: opname_tab[(int) PLUS_EXPR] = "+"; ! 707: opname_tab[(int) MINUS_EXPR] = "-"; ! 708: opname_tab[(int) MULT_EXPR] = "*"; ! 709: opname_tab[(int) TRUNC_DIV_EXPR] = "/"; ! 710: opname_tab[(int) CEIL_DIV_EXPR] = "(ceiling /)"; ! 711: opname_tab[(int) FLOOR_DIV_EXPR] = "(floor /)"; ! 712: opname_tab[(int) ROUND_DIV_EXPR] = "(round /)"; ! 713: opname_tab[(int) TRUNC_MOD_EXPR] = "%"; ! 714: opname_tab[(int) CEIL_MOD_EXPR] = "(ceiling %)"; ! 715: opname_tab[(int) FLOOR_MOD_EXPR] = "(floor %)"; ! 716: opname_tab[(int) ROUND_MOD_EXPR] = "(round %)"; ! 717: opname_tab[(int) NEGATE_EXPR] = "-"; ! 718: opname_tab[(int) MIN_EXPR] = "<?"; ! 719: opname_tab[(int) MAX_EXPR] = ">?"; ! 720: opname_tab[(int) ABS_EXPR] = "abs"; ! 721: opname_tab[(int) FFS_EXPR] = "ffs"; ! 722: opname_tab[(int) LSHIFT_EXPR] = "<<"; ! 723: opname_tab[(int) RSHIFT_EXPR] = ">>"; ! 724: opname_tab[(int) BIT_IOR_EXPR] = "|"; ! 725: opname_tab[(int) BIT_XOR_EXPR] = "^"; ! 726: opname_tab[(int) BIT_AND_EXPR] = "&"; ! 727: opname_tab[(int) BIT_ANDTC_EXPR] = "&~"; ! 728: opname_tab[(int) BIT_NOT_EXPR] = "~"; ! 729: opname_tab[(int) TRUTH_ANDIF_EXPR] = "&&"; ! 730: opname_tab[(int) TRUTH_ORIF_EXPR] = "||"; ! 731: opname_tab[(int) TRUTH_AND_EXPR] = "strict &&"; ! 732: opname_tab[(int) TRUTH_OR_EXPR] = "strict ||"; ! 733: opname_tab[(int) TRUTH_NOT_EXPR] = "!"; ! 734: opname_tab[(int) LT_EXPR] = "<"; ! 735: opname_tab[(int) LE_EXPR] = "<="; ! 736: opname_tab[(int) GT_EXPR] = ">"; ! 737: opname_tab[(int) GE_EXPR] = ">="; ! 738: opname_tab[(int) EQ_EXPR] = "=="; ! 739: opname_tab[(int) NE_EXPR] = "!="; ! 740: opname_tab[(int) IN_EXPR] = "in"; ! 741: opname_tab[(int) RANGE_EXPR] = ".."; ! 742: opname_tab[(int) CONVERT_EXPR] = "(unary +)"; ! 743: opname_tab[(int) ADDR_EXPR] = "(unary &)"; ! 744: opname_tab[(int) PREDECREMENT_EXPR] = "--"; ! 745: opname_tab[(int) PREINCREMENT_EXPR] = "++"; ! 746: opname_tab[(int) POSTDECREMENT_EXPR] = "--"; ! 747: opname_tab[(int) POSTINCREMENT_EXPR] = "++"; ! 748: opname_tab[(int) COMPOUND_EXPR] = ","; ! 749: ! 750: assignop_tab[(int) NOP_EXPR] = "="; ! 751: assignop_tab[(int) PLUS_EXPR] = "+="; ! 752: assignop_tab[(int) CONVERT_EXPR] = "+="; ! 753: assignop_tab[(int) MINUS_EXPR] = "-="; ! 754: assignop_tab[(int) NEGATE_EXPR] = "-="; ! 755: assignop_tab[(int) MULT_EXPR] = "*="; ! 756: assignop_tab[(int) INDIRECT_REF] = "*="; ! 757: assignop_tab[(int) TRUNC_DIV_EXPR] = "/="; ! 758: assignop_tab[(int) EXACT_DIV_EXPR] = "(exact /=)"; ! 759: assignop_tab[(int) CEIL_DIV_EXPR] = "(ceiling /=)"; ! 760: assignop_tab[(int) FLOOR_DIV_EXPR] = "(floor /=)"; ! 761: assignop_tab[(int) ROUND_DIV_EXPR] = "(round /=)"; ! 762: assignop_tab[(int) TRUNC_MOD_EXPR] = "%="; ! 763: assignop_tab[(int) CEIL_MOD_EXPR] = "(ceiling %=)"; ! 764: assignop_tab[(int) FLOOR_MOD_EXPR] = "(floor %=)"; ! 765: assignop_tab[(int) ROUND_MOD_EXPR] = "(round %=)"; ! 766: assignop_tab[(int) MIN_EXPR] = "<?="; ! 767: assignop_tab[(int) MAX_EXPR] = ">?="; ! 768: assignop_tab[(int) LSHIFT_EXPR] = "<<="; ! 769: assignop_tab[(int) RSHIFT_EXPR] = ">>="; ! 770: assignop_tab[(int) BIT_IOR_EXPR] = "|="; ! 771: assignop_tab[(int) BIT_XOR_EXPR] = "^="; ! 772: assignop_tab[(int) BIT_AND_EXPR] = "&="; ! 773: assignop_tab[(int) ADDR_EXPR] = "&="; ! 774: ! 775: init_filename_times (); ! 776: ! 777: /* Some options inhibit certain reserved words. ! 778: Clear those words out of the hash table so they won't be recognized. */ ! 779: #define UNSET_RESERVED_WORD(STRING) \ ! 780: do { struct resword *s = is_reserved_word (STRING, sizeof (STRING) - 1); \ ! 781: if (s) s->name = ""; } while (0) ! 782: ! 783: #if 0 ! 784: /* let's parse things, and if they use it, then give them an error. */ ! 785: if (!flag_handle_exceptions) ! 786: { ! 787: UNSET_RESERVED_WORD ("throw"); ! 788: UNSET_RESERVED_WORD ("try"); ! 789: UNSET_RESERVED_WORD ("catch"); ! 790: } ! 791: #endif ! 792: ! 793: if (! (flag_gc || flag_dossier)) ! 794: { ! 795: UNSET_RESERVED_WORD ("classof"); ! 796: UNSET_RESERVED_WORD ("headof"); ! 797: } ! 798: if (! flag_handle_signatures) ! 799: { ! 800: /* Easiest way to not recognize signature ! 801: handling extensions... */ ! 802: UNSET_RESERVED_WORD ("signature"); ! 803: UNSET_RESERVED_WORD ("sigof"); ! 804: } ! 805: if (flag_no_asm) ! 806: UNSET_RESERVED_WORD ("asm"); ! 807: if (flag_no_asm || flag_traditional) ! 808: UNSET_RESERVED_WORD ("typeof"); ! 809: ! 810: token_count = init_parse (); ! 811: interface_unknown = 1; ! 812: } ! 813: ! 814: void ! 815: reinit_parse_for_function () ! 816: { ! 817: current_base_init_list = NULL_TREE; ! 818: current_member_init_list = NULL_TREE; ! 819: } ! 820: ! 821: #ifdef __GNUC__ ! 822: __inline ! 823: #endif ! 824: void ! 825: yyprint (file, yychar, yylval) ! 826: FILE *file; ! 827: int yychar; ! 828: YYSTYPE yylval; ! 829: { ! 830: tree t; ! 831: switch (yychar) ! 832: { ! 833: case IDENTIFIER: ! 834: case TYPENAME: ! 835: case TYPESPEC: ! 836: case PTYPENAME: ! 837: case IDENTIFIER_DEFN: ! 838: case TYPENAME_DEFN: ! 839: case PTYPENAME_DEFN: ! 840: case TYPENAME_ELLIPSIS: ! 841: case SCSPEC: ! 842: case PRE_PARSED_CLASS_DECL: ! 843: t = yylval.ttype; ! 844: my_friendly_assert (TREE_CODE (t) == IDENTIFIER_NODE, 224); ! 845: if (IDENTIFIER_POINTER (t)) ! 846: fprintf (file, " `%s'", IDENTIFIER_POINTER (t)); ! 847: break; ! 848: case AGGR: ! 849: if (yylval.ttype == class_type_node) ! 850: fprintf (file, " `class'"); ! 851: else if (yylval.ttype == record_type_node) ! 852: fprintf (file, " `struct'"); ! 853: else if (yylval.ttype == union_type_node) ! 854: fprintf (file, " `union'"); ! 855: else if (yylval.ttype == enum_type_node) ! 856: fprintf (file, " `enum'"); ! 857: else if (yylval.ttype == signature_type_node) ! 858: fprintf (file, " `signature'"); ! 859: else ! 860: my_friendly_abort (80); ! 861: break; ! 862: } ! 863: } ! 864: ! 865: static int *reduce_count; ! 866: int *token_count; ! 867: ! 868: #define REDUCE_LENGTH (sizeof (yyr2) / sizeof (yyr2[0])) ! 869: #define TOKEN_LENGTH (256 + sizeof (yytname) / sizeof (yytname[0])) ! 870: ! 871: int * ! 872: init_parse () ! 873: { ! 874: #ifdef GATHER_STATISTICS ! 875: reduce_count = (int *)malloc (sizeof (int) * (REDUCE_LENGTH + 1)); ! 876: bzero (reduce_count, sizeof (int) * (REDUCE_LENGTH + 1)); ! 877: reduce_count += 1; ! 878: token_count = (int *)malloc (sizeof (int) * (TOKEN_LENGTH + 1)); ! 879: bzero (token_count, sizeof (int) * (TOKEN_LENGTH + 1)); ! 880: token_count += 1; ! 881: #endif ! 882: return token_count; ! 883: } ! 884: ! 885: #ifdef GATHER_STATISTICS ! 886: void ! 887: yyhook (yyn) ! 888: int yyn; ! 889: { ! 890: reduce_count[yyn] += 1; ! 891: } ! 892: ! 893: static int ! 894: reduce_cmp (p, q) ! 895: int *p, *q; ! 896: { ! 897: return reduce_count[*q] - reduce_count[*p]; ! 898: } ! 899: ! 900: static int ! 901: token_cmp (p, q) ! 902: int *p, *q; ! 903: { ! 904: return token_count[*q] - token_count[*p]; ! 905: } ! 906: #endif ! 907: ! 908: void ! 909: print_parse_statistics () ! 910: { ! 911: #ifdef GATHER_STATISTICS ! 912: #if YYDEBUG != 0 ! 913: int i; ! 914: int maxlen = REDUCE_LENGTH; ! 915: unsigned *sorted; ! 916: ! 917: if (reduce_count[-1] == 0) ! 918: return; ! 919: ! 920: if (TOKEN_LENGTH > REDUCE_LENGTH) ! 921: maxlen = TOKEN_LENGTH; ! 922: sorted = (unsigned *) alloca (sizeof (int) * maxlen); ! 923: ! 924: for (i = 0; i < TOKEN_LENGTH; i++) ! 925: sorted[i] = i; ! 926: qsort (sorted, TOKEN_LENGTH, sizeof (int), token_cmp); ! 927: for (i = 0; i < TOKEN_LENGTH; i++) ! 928: { ! 929: int index = sorted[i]; ! 930: if (token_count[index] == 0) ! 931: break; ! 932: if (token_count[index] < token_count[-1]) ! 933: break; ! 934: fprintf (stderr, "token %d, `%s', count = %d\n", ! 935: index, yytname[YYTRANSLATE (index)], token_count[index]); ! 936: } ! 937: fprintf (stderr, "\n"); ! 938: for (i = 0; i < REDUCE_LENGTH; i++) ! 939: sorted[i] = i; ! 940: qsort (sorted, REDUCE_LENGTH, sizeof (int), reduce_cmp); ! 941: for (i = 0; i < REDUCE_LENGTH; i++) ! 942: { ! 943: int index = sorted[i]; ! 944: if (reduce_count[index] == 0) ! 945: break; ! 946: if (reduce_count[index] < reduce_count[-1]) ! 947: break; ! 948: fprintf (stderr, "rule %d, line %d, count = %d\n", ! 949: index, yyrline[index], reduce_count[index]); ! 950: } ! 951: fprintf (stderr, "\n"); ! 952: #endif ! 953: #endif ! 954: } ! 955: ! 956: /* Sets the value of the 'yydebug' variable to VALUE. ! 957: This is a function so we don't have to have YYDEBUG defined ! 958: in order to build the compiler. */ ! 959: void ! 960: set_yydebug (value) ! 961: int value; ! 962: { ! 963: #if YYDEBUG != 0 ! 964: extern int yydebug; ! 965: yydebug = value; ! 966: #else ! 967: warning ("YYDEBUG not defined."); ! 968: #endif ! 969: } ! 970: ! 971: ! 972: /* Functions and data structures for #pragma interface. ! 973: ! 974: `#pragma implementation' means that the main file being compiled ! 975: is considered to implement (provide) the classes that appear in ! 976: its main body. I.e., if this is file "foo.cc", and class `bar' ! 977: is defined in "foo.cc", then we say that "foo.cc implements bar". ! 978: ! 979: All main input files "implement" themselves automagically. ! 980: ! 981: `#pragma interface' means that unless this file (of the form "foo.h" ! 982: is not presently being included by file "foo.cc", the ! 983: CLASSTYPE_INTERFACE_ONLY bit gets set. The effect is that none ! 984: of the vtables nor any of the inline functions defined in foo.h ! 985: will ever be output. ! 986: ! 987: There are cases when we want to link files such as "defs.h" and ! 988: "main.cc". In this case, we give "defs.h" a `#pragma interface', ! 989: and "main.cc" has `#pragma implementation "defs.h"'. */ ! 990: ! 991: struct impl_files ! 992: { ! 993: char *filename; ! 994: struct impl_files *next; ! 995: }; ! 996: ! 997: static struct impl_files *impl_file_chain; ! 998: ! 999: /* Helper function to load global variables with interface ! 1000: information. */ ! 1001: void ! 1002: extract_interface_info () ! 1003: { ! 1004: tree fileinfo = 0; ! 1005: ! 1006: if (flag_alt_external_templates) ! 1007: { ! 1008: struct tinst_level *til = tinst_for_decl (); ! 1009: ! 1010: if (til) ! 1011: fileinfo = get_time_identifier (til->file); ! 1012: } ! 1013: if (!fileinfo) ! 1014: fileinfo = get_time_identifier (input_filename); ! 1015: fileinfo = IDENTIFIER_CLASS_VALUE (fileinfo); ! 1016: interface_only = TREE_INT_CST_LOW (fileinfo); ! 1017: if (!processing_template_defn || flag_external_templates) ! 1018: interface_unknown = TREE_INT_CST_HIGH (fileinfo); ! 1019: } ! 1020: ! 1021: /* Return nonzero if S is not considered part of an ! 1022: INTERFACE/IMPLEMENTATION pair. Otherwise, return 0. */ ! 1023: static int ! 1024: interface_strcmp (s) ! 1025: char *s; ! 1026: { ! 1027: /* Set the interface/implementation bits for this scope. */ ! 1028: struct impl_files *ifiles; ! 1029: char *s1; ! 1030: ! 1031: for (ifiles = impl_file_chain; ifiles; ifiles = ifiles->next) ! 1032: { ! 1033: char *t1 = ifiles->filename; ! 1034: s1 = s; ! 1035: ! 1036: if (*s1 != *t1 || *s1 == 0) ! 1037: continue; ! 1038: ! 1039: while (*s1 == *t1 && *s1 != 0) ! 1040: s1++, t1++; ! 1041: ! 1042: /* A match. */ ! 1043: if (*s1 == *t1) ! 1044: return 0; ! 1045: ! 1046: /* Don't get faked out by xxx.yyy.cc vs xxx.zzz.cc. */ ! 1047: if (index (s1, '.') || index (t1, '.')) ! 1048: continue; ! 1049: ! 1050: if (*s1 == '\0' || s1[-1] != '.' || t1[-1] != '.') ! 1051: continue; ! 1052: ! 1053: /* A match. */ ! 1054: return 0; ! 1055: } ! 1056: ! 1057: /* No matches. */ ! 1058: return 1; ! 1059: } ! 1060: ! 1061: void ! 1062: set_typedecl_interface_info (prev, vars) ! 1063: tree prev, vars; ! 1064: { ! 1065: tree id = get_time_identifier (DECL_SOURCE_FILE (vars)); ! 1066: tree fileinfo = IDENTIFIER_CLASS_VALUE (id); ! 1067: tree type = TREE_TYPE (vars); ! 1068: ! 1069: CLASSTYPE_INTERFACE_ONLY (type) = TREE_INT_CST_LOW (fileinfo) ! 1070: = interface_strcmp (FILE_NAME_NONDIRECTORY (DECL_SOURCE_FILE (vars))); ! 1071: } ! 1072: ! 1073: void ! 1074: set_vardecl_interface_info (prev, vars) ! 1075: tree prev, vars; ! 1076: { ! 1077: tree type = DECL_CONTEXT (vars); ! 1078: ! 1079: if (CLASSTYPE_INTERFACE_KNOWN (type)) ! 1080: { ! 1081: if (CLASSTYPE_INTERFACE_ONLY (type)) ! 1082: set_typedecl_interface_info (prev, TYPE_NAME (type)); ! 1083: else ! 1084: CLASSTYPE_VTABLE_NEEDS_WRITING (type) = 1; ! 1085: DECL_EXTERNAL (vars) = CLASSTYPE_INTERFACE_ONLY (type); ! 1086: TREE_PUBLIC (vars) = 1; ! 1087: } ! 1088: } ! 1089: ! 1090: /* Called from the top level: if there are any pending inlines to ! 1091: do, set up to process them now. This function sets up the first function ! 1092: to be parsed; after it has been, the rule for fndef in parse.y will ! 1093: call process_next_inline to start working on the next one. */ ! 1094: void ! 1095: do_pending_inlines () ! 1096: { ! 1097: struct pending_inline *t; ! 1098: ! 1099: /* Oops, we're still dealing with the last batch. */ ! 1100: if (yychar == PRE_PARSED_FUNCTION_DECL) ! 1101: return; ! 1102: ! 1103: /* Reverse the pending inline functions, since ! 1104: they were cons'd instead of appended. */ ! 1105: { ! 1106: struct pending_inline *prev = 0, *tail, *bottom = 0; ! 1107: t = pending_inlines; ! 1108: pending_inlines = 0; ! 1109: ! 1110: for (; t; t = tail) ! 1111: { ! 1112: tail = t->next; ! 1113: t->next = prev; ! 1114: t->deja_vu = 1; ! 1115: prev = t; ! 1116: } ! 1117: ! 1118: /* This kludge should go away when synthesized methods are handled ! 1119: properly, i.e. only when needed. */ ! 1120: for (t = prev; t; t = t->next) ! 1121: { ! 1122: if (t->lineno <= 0) ! 1123: { ! 1124: tree f = t->fndecl; ! 1125: DECL_PENDING_INLINE_INFO (f) = 0; ! 1126: interface_unknown = t->interface == 1; ! 1127: interface_only = t->interface == 0; ! 1128: switch (- t->lineno) ! 1129: { ! 1130: case 0: case 1: ! 1131: build_dtor (f); break; ! 1132: case 2: ! 1133: build_default_constructor (f); break; ! 1134: case 3: case 4: ! 1135: build_copy_constructor (f); break; ! 1136: case 5: case 6: ! 1137: build_assign_ref (f); break; ! 1138: default: ! 1139: ; ! 1140: } ! 1141: if (tail) ! 1142: tail->next = t->next; ! 1143: else ! 1144: prev = t->next; ! 1145: if (! bottom) ! 1146: bottom = t; ! 1147: } ! 1148: else ! 1149: tail = t; ! 1150: } ! 1151: if (bottom) ! 1152: { ! 1153: obstack_free (&synth_obstack, bottom); ! 1154: extract_interface_info (); ! 1155: } ! 1156: t = prev; ! 1157: } ! 1158: ! 1159: if (t == 0) ! 1160: return; ! 1161: ! 1162: /* Now start processing the first inline function. */ ! 1163: my_friendly_assert ((t->parm_vec == NULL_TREE) == (t->bindings == NULL_TREE), ! 1164: 226); ! 1165: if (t->parm_vec) ! 1166: push_template_decls (t->parm_vec, t->bindings, 0); ! 1167: if (t->len > 0) ! 1168: { ! 1169: feed_input (t->buf, t->len, t->can_free ? &inline_text_obstack : 0); ! 1170: lineno = t->lineno; ! 1171: #if 0 ! 1172: if (input_filename != t->filename) ! 1173: { ! 1174: input_filename = t->filename; ! 1175: /* Get interface/implementation back in sync. */ ! 1176: extract_interface_info (); ! 1177: } ! 1178: #else ! 1179: input_filename = t->filename; ! 1180: interface_unknown = t->interface == 1; ! 1181: interface_only = t->interface == 0; ! 1182: #endif ! 1183: yychar = PRE_PARSED_FUNCTION_DECL; ! 1184: } ! 1185: /* Pass back a handle on the rest of the inline functions, so that they ! 1186: can be processed later. */ ! 1187: yylval.ttype = build_tree_list ((tree) t, t->fndecl); ! 1188: #if 0 ! 1189: if (flag_default_inline && t->fndecl ! 1190: /* If we're working from a template, don't change ! 1191: the `inline' state. */ ! 1192: && t->parm_vec == NULL_TREE) ! 1193: DECL_INLINE (t->fndecl) = 1; ! 1194: #endif ! 1195: DECL_PENDING_INLINE_INFO (t->fndecl) = 0; ! 1196: } ! 1197: ! 1198: extern struct pending_input *to_be_restored; ! 1199: static int nextchar = -1; ! 1200: ! 1201: /* Called from the fndecl rule in the parser when the function just parsed ! 1202: was declared using a PRE_PARSED_FUNCTION_DECL (i.e. came from ! 1203: do_pending_inlines). */ ! 1204: void ! 1205: process_next_inline (t) ! 1206: tree t; ! 1207: { ! 1208: struct pending_inline *i = (struct pending_inline *) TREE_PURPOSE (t); ! 1209: my_friendly_assert ((i->parm_vec == NULL_TREE) == (i->bindings == NULL_TREE), ! 1210: 227); ! 1211: if (i->parm_vec) ! 1212: pop_template_decls (i->parm_vec, i->bindings, 0); ! 1213: i = i->next; ! 1214: if (yychar == YYEMPTY) ! 1215: yychar = yylex (); ! 1216: if (yychar != END_OF_SAVED_INPUT) ! 1217: { ! 1218: error ("parse error at end of saved function text"); ! 1219: /* restore_pending_input will abort unless yychar is either ! 1220: * END_OF_SAVED_INPUT or YYEMPTY; since we already know we're ! 1221: * hosed, feed back YYEMPTY. ! 1222: * We also need to discard nextchar, since that may have gotten ! 1223: * set as well. ! 1224: */ ! 1225: nextchar = -1; ! 1226: } ! 1227: yychar = YYEMPTY; ! 1228: if (to_be_restored == 0) ! 1229: my_friendly_abort (123); ! 1230: restore_pending_input (to_be_restored); ! 1231: to_be_restored = 0; ! 1232: if (i && i->fndecl != NULL_TREE) ! 1233: { ! 1234: my_friendly_assert ((i->parm_vec == NULL_TREE) == (i->bindings == NULL_TREE), ! 1235: 228); ! 1236: if (i->parm_vec) ! 1237: push_template_decls (i->parm_vec, i->bindings, 0); ! 1238: feed_input (i->buf, i->len, i->can_free ? &inline_text_obstack : 0); ! 1239: lineno = i->lineno; ! 1240: input_filename = i->filename; ! 1241: yychar = PRE_PARSED_FUNCTION_DECL; ! 1242: yylval.ttype = build_tree_list ((tree) i, i->fndecl); ! 1243: #if 0 ! 1244: if (flag_default_inline ! 1245: /* If we're working from a template, don't change ! 1246: the `inline' state. */ ! 1247: && i->parm_vec == NULL_TREE) ! 1248: DECL_INLINE (i->fndecl) = 1; ! 1249: #endif ! 1250: DECL_PENDING_INLINE_INFO (i->fndecl) = 0; ! 1251: } ! 1252: if (i) ! 1253: { ! 1254: interface_unknown = i->interface == 1; ! 1255: interface_only = i->interface == 0; ! 1256: } ! 1257: else ! 1258: extract_interface_info (); ! 1259: } ! 1260: ! 1261: /* Since inline methods can refer to text which has not yet been seen, ! 1262: we store the text of the method in a structure which is placed in the ! 1263: DECL_PENDING_INLINE_INFO field of the FUNCTION_DECL. ! 1264: After parsing the body of the class definition, the FUNCTION_DECL's are ! 1265: scanned to see which ones have this field set. Those are then digested ! 1266: one at a time. ! 1267: ! 1268: This function's FUNCTION_DECL will have a bit set in its common so ! 1269: that we know to watch out for it. */ ! 1270: ! 1271: static void ! 1272: consume_string (this_obstack, matching_char) ! 1273: register struct obstack *this_obstack; ! 1274: int matching_char; ! 1275: { ! 1276: register int c; ! 1277: int starting_lineno = lineno; ! 1278: do ! 1279: { ! 1280: c = getch (); ! 1281: if (c == EOF) ! 1282: { ! 1283: int save_lineno = lineno; ! 1284: lineno = starting_lineno; ! 1285: if (matching_char == '"') ! 1286: error ("end of file encountered inside string constant"); ! 1287: else ! 1288: error ("end of file encountered inside character constant"); ! 1289: lineno = save_lineno; ! 1290: return; ! 1291: } ! 1292: if (c == '\\') ! 1293: { ! 1294: obstack_1grow (this_obstack, c); ! 1295: c = getch (); ! 1296: obstack_1grow (this_obstack, c); ! 1297: ! 1298: /* Make sure we continue the loop */ ! 1299: c = 0; ! 1300: continue; ! 1301: } ! 1302: if (c == '\n') ! 1303: { ! 1304: if (pedantic) ! 1305: pedwarn ("ANSI C++ forbids newline in string constant"); ! 1306: lineno++; ! 1307: } ! 1308: obstack_1grow (this_obstack, c); ! 1309: } ! 1310: while (c != matching_char); ! 1311: } ! 1312: ! 1313: static int nextyychar = YYEMPTY; ! 1314: static YYSTYPE nextyylval; ! 1315: ! 1316: struct pending_input { ! 1317: int nextchar, yychar, nextyychar, eof; ! 1318: YYSTYPE yylval, nextyylval; ! 1319: struct obstack token_obstack; ! 1320: int first_token; ! 1321: }; ! 1322: ! 1323: struct pending_input * ! 1324: save_pending_input () ! 1325: { ! 1326: struct pending_input *p; ! 1327: p = (struct pending_input *) xmalloc (sizeof (struct pending_input)); ! 1328: p->nextchar = nextchar; ! 1329: p->yychar = yychar; ! 1330: p->nextyychar = nextyychar; ! 1331: p->yylval = yylval; ! 1332: p->nextyylval = nextyylval; ! 1333: p->eof = end_of_file; ! 1334: yychar = nextyychar = YYEMPTY; ! 1335: nextchar = -1; ! 1336: p->first_token = first_token; ! 1337: p->token_obstack = token_obstack; ! 1338: ! 1339: first_token = 0; ! 1340: gcc_obstack_init (&token_obstack); ! 1341: end_of_file = 0; ! 1342: return p; ! 1343: } ! 1344: ! 1345: void ! 1346: restore_pending_input (p) ! 1347: struct pending_input *p; ! 1348: { ! 1349: my_friendly_assert (nextchar == -1, 229); ! 1350: nextchar = p->nextchar; ! 1351: my_friendly_assert (yychar == YYEMPTY || yychar == END_OF_SAVED_INPUT, 230); ! 1352: yychar = p->yychar; ! 1353: my_friendly_assert (nextyychar == YYEMPTY, 231); ! 1354: nextyychar = p->nextyychar; ! 1355: yylval = p->yylval; ! 1356: nextyylval = p->nextyylval; ! 1357: first_token = p->first_token; ! 1358: obstack_free (&token_obstack, (char *) 0); ! 1359: token_obstack = p->token_obstack; ! 1360: end_of_file = p->eof; ! 1361: free (p); ! 1362: } ! 1363: ! 1364: /* Return next non-whitespace input character, which may come ! 1365: from `finput', or from `nextchar'. */ ! 1366: static int ! 1367: yynextch () ! 1368: { ! 1369: int c; ! 1370: ! 1371: if (nextchar >= 0) ! 1372: { ! 1373: c = nextchar; ! 1374: nextchar = -1; ! 1375: } ! 1376: else c = getch (); ! 1377: return skip_white_space (c); ! 1378: } ! 1379: ! 1380: /* Unget character CH from the input stream. ! 1381: If RESCAN is non-zero, then we want to `see' this ! 1382: character as the next input token. */ ! 1383: void ! 1384: yyungetc (ch, rescan) ! 1385: int ch; ! 1386: int rescan; ! 1387: { ! 1388: /* Unget a character from the input stream. */ ! 1389: if (yychar == YYEMPTY || rescan == 0) ! 1390: { ! 1391: if (nextchar >= 0) ! 1392: put_back (nextchar); ! 1393: nextchar = ch; ! 1394: } ! 1395: else ! 1396: { ! 1397: my_friendly_assert (nextyychar == YYEMPTY, 232); ! 1398: nextyychar = yychar; ! 1399: nextyylval = yylval; ! 1400: yychar = ch; ! 1401: } ! 1402: } ! 1403: ! 1404: /* This function stores away the text for an inline function that should ! 1405: be processed later. It decides how much later, and may need to move ! 1406: the info between obstacks; therefore, the caller should not refer to ! 1407: the T parameter after calling this function. ! 1408: ! 1409: This function also stores the list of template-parameter bindings that ! 1410: will be needed for expanding the template, if any. */ ! 1411: ! 1412: static void ! 1413: store_pending_inline (decl, t) ! 1414: tree decl; ! 1415: struct pending_inline *t; ! 1416: { ! 1417: extern int processing_template_defn; ! 1418: int delay_to_eof = 0; ! 1419: struct pending_inline **inlines; ! 1420: ! 1421: t->fndecl = decl; ! 1422: /* Default: compile right away, and no extra bindings are needed. */ ! 1423: t->parm_vec = t->bindings = 0; ! 1424: if (processing_template_defn) ! 1425: { ! 1426: tree type = current_class_type; ! 1427: /* Assumption: In this (possibly) nested class sequence, only ! 1428: one name will have template parms. */ ! 1429: while (type && TREE_CODE_CLASS (TREE_CODE (type)) == 't') ! 1430: { ! 1431: tree decl = TYPE_NAME (type); ! 1432: tree tmpl = IDENTIFIER_TEMPLATE (DECL_NAME (decl)); ! 1433: if (tmpl) ! 1434: { ! 1435: t->parm_vec = DECL_TEMPLATE_INFO (TREE_PURPOSE (tmpl))->parm_vec; ! 1436: t->bindings = TREE_VALUE (tmpl); ! 1437: } ! 1438: type = DECL_CONTEXT (decl); ! 1439: } ! 1440: if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE ! 1441: || TREE_CODE (TREE_TYPE (decl)) == FUNCTION_TYPE) ! 1442: { ! 1443: if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE) ! 1444: my_friendly_assert (TYPE_MAX_VALUE (TREE_TYPE (decl)) == current_class_type, ! 1445: 233); ! 1446: ! 1447: /* Inline functions can be compiled immediately. Other functions ! 1448: will be output separately, so if we're in interface-only mode, ! 1449: punt them now, or output them now if we're doing implementations ! 1450: and we know no overrides will exist. Otherwise, we delay until ! 1451: end-of-file, to see if the definition is really required. */ ! 1452: if (DECL_INLINE (decl)) ! 1453: /* delay_to_eof == 0 */; ! 1454: else if (current_class_type && !interface_unknown) ! 1455: { ! 1456: if (interface_only) ! 1457: { ! 1458: #if 0 ! 1459: print_node_brief (stderr, "\ndiscarding text for ", decl, 0); ! 1460: #endif ! 1461: if (t->can_free) ! 1462: obstack_free (&inline_text_obstack, t->buf); ! 1463: DECL_PENDING_INLINE_INFO (decl) = 0; ! 1464: return; ! 1465: } ! 1466: } ! 1467: /* Don't delay the processing of virtual functions. */ ! 1468: else if (DECL_VINDEX (decl) == NULL_TREE) ! 1469: delay_to_eof = 1; ! 1470: } ! 1471: else ! 1472: my_friendly_abort (58); ! 1473: } ! 1474: ! 1475: if (delay_to_eof) ! 1476: { ! 1477: extern struct pending_inline *pending_template_expansions; ! 1478: ! 1479: if (t->can_free) ! 1480: { ! 1481: char *free_to = t->buf; ! 1482: t->buf = (char *) obstack_copy (&permanent_obstack, t->buf, ! 1483: t->len + 1); ! 1484: t = (struct pending_inline *) obstack_copy (&permanent_obstack, ! 1485: (char *)t, sizeof (*t)); ! 1486: obstack_free (&inline_text_obstack, free_to); ! 1487: } ! 1488: inlines = &pending_template_expansions; ! 1489: t->can_free = 0; ! 1490: } ! 1491: else ! 1492: { ! 1493: inlines = &pending_inlines; ! 1494: DECL_PENDING_INLINE_INFO (decl) = t; ! 1495: } ! 1496: ! 1497: /* Because we use obstacks, we must process these in precise order. */ ! 1498: t->next = *inlines; ! 1499: *inlines = t; ! 1500: } ! 1501: ! 1502: void reinit_parse_for_block (); ! 1503: ! 1504: void ! 1505: reinit_parse_for_method (yychar, decl) ! 1506: int yychar; ! 1507: tree decl; ! 1508: { ! 1509: int len; ! 1510: int starting_lineno = lineno; ! 1511: char *starting_filename = input_filename; ! 1512: ! 1513: reinit_parse_for_block (yychar, &inline_text_obstack, 0); ! 1514: ! 1515: len = obstack_object_size (&inline_text_obstack); ! 1516: current_base_init_list = NULL_TREE; ! 1517: current_member_init_list = NULL_TREE; ! 1518: if (decl == void_type_node ! 1519: || (current_class_type && TYPE_REDEFINED (current_class_type))) ! 1520: { ! 1521: /* Happens when we get two declarations of the same ! 1522: function in the same scope. */ ! 1523: char *buf = obstack_finish (&inline_text_obstack); ! 1524: obstack_free (&inline_text_obstack, buf); ! 1525: return; ! 1526: } ! 1527: else ! 1528: { ! 1529: struct pending_inline *t; ! 1530: char *buf = obstack_finish (&inline_text_obstack); ! 1531: ! 1532: t = (struct pending_inline *) obstack_alloc (&inline_text_obstack, ! 1533: sizeof (struct pending_inline)); ! 1534: t->lineno = starting_lineno; ! 1535: t->filename = starting_filename; ! 1536: t->token = YYEMPTY; ! 1537: t->token_value = 0; ! 1538: t->buf = buf; ! 1539: t->len = len; ! 1540: t->can_free = 1; ! 1541: t->deja_vu = 0; ! 1542: if (interface_unknown && processing_template_defn && flag_external_templates && ! DECL_IN_SYSTEM_HEADER (decl)) ! 1543: warn_if_unknown_interface (); ! 1544: t->interface = (interface_unknown ? 1 : (interface_only ? 0 : 2)); ! 1545: store_pending_inline (decl, t); ! 1546: } ! 1547: } ! 1548: ! 1549: /* Consume a block -- actually, a method or template definition beginning ! 1550: with `:' or `{' -- and save it away on the specified obstack. ! 1551: ! 1552: Argument IS_TEMPLATE indicates which set of error messages should be ! 1553: output if something goes wrong. This should really be cleaned up somehow, ! 1554: without loss of clarity. */ ! 1555: void ! 1556: reinit_parse_for_block (yychar, obstackp, is_template) ! 1557: int yychar; ! 1558: struct obstack *obstackp; ! 1559: int is_template; ! 1560: { ! 1561: register int c = 0; ! 1562: int blev = 1; ! 1563: int starting_lineno = lineno; ! 1564: char *starting_filename = input_filename; ! 1565: int len; ! 1566: int look_for_semicolon = 0; ! 1567: int look_for_lbrac = 0; ! 1568: ! 1569: if (yychar == '{') ! 1570: obstack_1grow (obstackp, '{'); ! 1571: else if (yychar == '=') ! 1572: look_for_semicolon = 1; ! 1573: else if (yychar != ':' && (yychar != RETURN || is_template)) ! 1574: { ! 1575: yyerror (is_template ! 1576: ? "parse error in template specification" ! 1577: : "parse error in method specification"); ! 1578: obstack_1grow (obstackp, '{'); ! 1579: } ! 1580: else ! 1581: { ! 1582: obstack_1grow (obstackp, yychar); ! 1583: look_for_lbrac = 1; ! 1584: blev = 0; ! 1585: } ! 1586: ! 1587: if (nextchar != EOF) ! 1588: { ! 1589: c = nextchar; ! 1590: nextchar = EOF; ! 1591: } ! 1592: else ! 1593: c = getch (); ! 1594: ! 1595: while (c != EOF) ! 1596: { ! 1597: int this_lineno = lineno; ! 1598: ! 1599: c = skip_white_space (c); ! 1600: ! 1601: /* Don't lose our cool if there are lots of comments. */ ! 1602: if (lineno == this_lineno + 1) ! 1603: obstack_1grow (obstackp, '\n'); ! 1604: else if (lineno == this_lineno) ! 1605: ; ! 1606: else if (lineno - this_lineno < 10) ! 1607: { ! 1608: int i; ! 1609: for (i = lineno - this_lineno; i > 0; i--) ! 1610: obstack_1grow (obstackp, '\n'); ! 1611: } ! 1612: else ! 1613: { ! 1614: char buf[16]; ! 1615: sprintf (buf, "\n# %d \"", lineno); ! 1616: len = strlen (buf); ! 1617: obstack_grow (obstackp, buf, len); ! 1618: ! 1619: len = strlen (input_filename); ! 1620: obstack_grow (obstackp, input_filename, len); ! 1621: obstack_1grow (obstackp, '\"'); ! 1622: obstack_1grow (obstackp, '\n'); ! 1623: } ! 1624: ! 1625: while (c > ' ') /* ASCII dependent... */ ! 1626: { ! 1627: obstack_1grow (obstackp, c); ! 1628: if (c == '{') ! 1629: { ! 1630: look_for_lbrac = 0; ! 1631: blev++; ! 1632: } ! 1633: else if (c == '}') ! 1634: { ! 1635: blev--; ! 1636: if (blev == 0 && !look_for_semicolon) ! 1637: goto done; ! 1638: } ! 1639: else if (c == '\\') ! 1640: { ! 1641: /* Don't act on the next character...e.g, doing an escaped ! 1642: double-quote. */ ! 1643: c = getch (); ! 1644: if (c == EOF) ! 1645: { ! 1646: error_with_file_and_line (starting_filename, ! 1647: starting_lineno, ! 1648: "end of file read inside definition"); ! 1649: goto done; ! 1650: } ! 1651: obstack_1grow (obstackp, c); ! 1652: } ! 1653: else if (c == '\"') ! 1654: consume_string (obstackp, c); ! 1655: else if (c == '\'') ! 1656: consume_string (obstackp, c); ! 1657: else if (c == ';') ! 1658: { ! 1659: if (look_for_lbrac) ! 1660: { ! 1661: error (is_template ! 1662: ? "template body missing" ! 1663: : "function body for constructor missing"); ! 1664: obstack_1grow (obstackp, '{'); ! 1665: obstack_1grow (obstackp, '}'); ! 1666: len += 2; ! 1667: goto done; ! 1668: } ! 1669: else if (look_for_semicolon && blev == 0) ! 1670: goto done; ! 1671: } ! 1672: c = getch (); ! 1673: } ! 1674: ! 1675: if (c == EOF) ! 1676: { ! 1677: error_with_file_and_line (starting_filename, ! 1678: starting_lineno, ! 1679: "end of file read inside definition"); ! 1680: goto done; ! 1681: } ! 1682: else if (c != '\n') ! 1683: { ! 1684: obstack_1grow (obstackp, c); ! 1685: c = getch (); ! 1686: } ! 1687: } ! 1688: done: ! 1689: obstack_1grow (obstackp, '\0'); ! 1690: } ! 1691: ! 1692: /* Build a default function named NAME for type TYPE. ! 1693: KIND says what to build. ! 1694: ! 1695: When KIND == 0, build default destructor. ! 1696: When KIND == 1, build virtual destructor. ! 1697: When KIND == 2, build default constructor. ! 1698: When KIND == 3, build default X(const X&) constructor. ! 1699: When KIND == 4, build default X(X&) constructor. ! 1700: When KIND == 5, build default operator = (const X&). ! 1701: When KIND == 6, build default operator = (X&). */ ! 1702: ! 1703: tree ! 1704: cons_up_default_function (type, name, kind) ! 1705: tree type, name; ! 1706: int kind; ! 1707: { ! 1708: extern tree void_list_node; ! 1709: char *func_buf = NULL; ! 1710: int func_len = 0; ! 1711: tree declspecs = NULL_TREE; ! 1712: tree fn, args; ! 1713: tree argtype; ! 1714: int retref = 0; ! 1715: ! 1716: name = constructor_name (name); ! 1717: switch (kind) ! 1718: { ! 1719: /* Destructors. */ ! 1720: case 1: ! 1721: declspecs = build_decl_list (NULL_TREE, ridpointers [(int) RID_VIRTUAL]); ! 1722: /* Fall through... */ ! 1723: case 0: ! 1724: name = build_parse_node (BIT_NOT_EXPR, name); ! 1725: /* Fall through... */ ! 1726: case 2: ! 1727: /* Default constructor. */ ! 1728: args = void_list_node; ! 1729: break; ! 1730: ! 1731: case 3: ! 1732: type = build_type_variant (type, 1, 0); ! 1733: /* Fall through... */ ! 1734: case 4: ! 1735: /* According to ARM $12.8, the default copy ctor will be declared, but ! 1736: not defined, unless it's needed. */ ! 1737: argtype = build_reference_type (type); ! 1738: args = tree_cons (NULL_TREE, ! 1739: build_tree_list (hash_tree_chain (argtype, NULL_TREE), ! 1740: get_identifier ("_ctor_arg")), ! 1741: void_list_node); ! 1742: break; ! 1743: ! 1744: case 5: ! 1745: type = build_type_variant (type, 1, 0); ! 1746: /* Fall through... */ ! 1747: case 6: ! 1748: retref = 1; ! 1749: declspecs = build_decl_list (NULL_TREE, name); ! 1750: ! 1751: name = ansi_opname [(int) MODIFY_EXPR]; ! 1752: ! 1753: argtype = build_reference_type (type); ! 1754: args = tree_cons (NULL_TREE, ! 1755: build_tree_list (hash_tree_chain (argtype, NULL_TREE), ! 1756: get_identifier ("_ctor_arg")), ! 1757: void_list_node); ! 1758: break; ! 1759: ! 1760: default: ! 1761: my_friendly_abort (59); ! 1762: } ! 1763: ! 1764: declspecs = decl_tree_cons (NULL_TREE, ridpointers [(int) RID_INLINE], ! 1765: declspecs); ! 1766: ! 1767: TREE_PARMLIST (args) = 1; ! 1768: ! 1769: { ! 1770: tree declarator = build_parse_node (CALL_EXPR, name, args, NULL_TREE); ! 1771: if (retref) ! 1772: declarator = build_parse_node (ADDR_EXPR, declarator); ! 1773: ! 1774: fn = grokfield (declarator, declspecs, NULL_TREE, NULL_TREE, NULL_TREE); ! 1775: } ! 1776: ! 1777: if (fn == void_type_node) ! 1778: return fn; ! 1779: ! 1780: if (CLASSTYPE_TEMPLATE_INSTANTIATION (type)) ! 1781: SET_DECL_IMPLICIT_INSTANTIATION (fn); ! 1782: ! 1783: /* This kludge should go away when synthesized methods are handled ! 1784: properly, i.e. only when needed. */ ! 1785: { ! 1786: struct pending_inline *t; ! 1787: t = (struct pending_inline *) ! 1788: obstack_alloc (&synth_obstack, sizeof (struct pending_inline)); ! 1789: t->lineno = -kind; ! 1790: t->can_free = 0; ! 1791: t->interface = (interface_unknown ? 1 : (interface_only ? 0 : 2)); ! 1792: store_pending_inline (fn, t); ! 1793: } ! 1794: ! 1795: #ifdef DEBUG_DEFAULT_FUNCTIONS ! 1796: { char *fn_type = NULL; ! 1797: tree t = name; ! 1798: switch (kind) ! 1799: { ! 1800: case 0: fn_type = "default destructor"; break; ! 1801: case 1: fn_type = "virtual destructor"; break; ! 1802: case 2: fn_type = "default constructor"; break; ! 1803: case 3: fn_type = "default X(const X&)"; break; ! 1804: case 4: fn_type = "default X(X&)"; break; ! 1805: } ! 1806: if (fn_type) ! 1807: { ! 1808: if (TREE_CODE (name) == BIT_NOT_EXPR) ! 1809: t = TREE_OPERAND (name, 0); ! 1810: fprintf (stderr, "[[[[ %s for %s:\n%s]]]]\n", fn_type, ! 1811: IDENTIFIER_POINTER (t), func_buf); ! 1812: } ! 1813: } ! 1814: #endif /* DEBUG_DEFAULT_FUNCTIONS */ ! 1815: ! 1816: /* Show that this function was generated by the compiler. */ ! 1817: SET_DECL_ARTIFICIAL (fn); ! 1818: ! 1819: return fn; ! 1820: } ! 1821: ! 1822: #if 0 ! 1823: /* Used by default_copy_constructor_body. For the anonymous union ! 1824: in TYPE, return the member that is at least as large as the rest ! 1825: of the members, so we can copy it. */ ! 1826: static tree ! 1827: largest_union_member (type) ! 1828: tree type; ! 1829: { ! 1830: tree f, type_size = TYPE_SIZE (type); ! 1831: ! 1832: for (f = TYPE_FIELDS (type); f; f = TREE_CHAIN (f)) ! 1833: if (simple_cst_equal (DECL_SIZE (f), type_size)) ! 1834: return f; ! 1835: ! 1836: /* We should always find one. */ ! 1837: my_friendly_abort (323); ! 1838: return NULL_TREE; ! 1839: } ! 1840: ! 1841: /* Construct the body of a default assignment operator. ! 1842: Mostly copied directly from default_copy_constructor_body. */ ! 1843: static void ! 1844: default_assign_ref_body (bufp, lenp, type, fields) ! 1845: char **bufp; ! 1846: int *lenp; ! 1847: tree type, fields; ! 1848: { ! 1849: static struct obstack body; ! 1850: static int inited = FALSE; ! 1851: int n_bases = CLASSTYPE_N_BASECLASSES (type); ! 1852: char *tbuf; ! 1853: int tgot, tneed; ! 1854: ! 1855: if (!inited) ! 1856: { ! 1857: obstack_init (&body); ! 1858: inited = TRUE; ! 1859: } ! 1860: body.next_free = body.object_base; ! 1861: ! 1862: obstack_1grow (&body, '{'); ! 1863: ! 1864: /* Small buffer for sprintf(). */ ! 1865: ! 1866: tgot = 100; ! 1867: tbuf = (char *) alloca (tgot); ! 1868: ! 1869: /* If we don't need a real op=, just do a bitwise copy. */ ! 1870: if (! TYPE_HAS_COMPLEX_ASSIGN_REF (type)) ! 1871: { ! 1872: tbuf = "{__builtin_memcpy(this,&_ctor_arg,sizeof(_ctor_arg));return *this;}"; ! 1873: *lenp = strlen (tbuf); ! 1874: *bufp = obstack_alloc (&inline_text_obstack, *lenp + 1); ! 1875: strcpy (*bufp, tbuf); ! 1876: return; ! 1877: } ! 1878: ! 1879: if (TREE_CODE (type) == UNION_TYPE) ! 1880: { ! 1881: if (fields) ! 1882: { ! 1883: tree main = fields; ! 1884: char * s; ! 1885: tree f; ! 1886: ! 1887: for (f = TREE_CHAIN (fields); f; f = TREE_CHAIN (f)) ! 1888: if (tree_int_cst_lt (TYPE_SIZE (TREE_TYPE (main)), ! 1889: TYPE_SIZE (TREE_TYPE (f)))) ! 1890: main = f; ! 1891: ! 1892: s = IDENTIFIER_POINTER (DECL_NAME (main)); ! 1893: ! 1894: tneed = (2 * strlen (s)) + 28; ! 1895: if (tgot < tneed) ! 1896: { ! 1897: tgot = tneed; ! 1898: tbuf = (char *) alloca (tgot); ! 1899: } ! 1900: ! 1901: sprintf (tbuf, "{%s=_ctor_arg.%s;return *this;}", s, s); ! 1902: } ! 1903: else ! 1904: tbuf = "{}"; ! 1905: ! 1906: *lenp = strlen (tbuf); ! 1907: *bufp = obstack_alloc (&inline_text_obstack, *lenp + 1); ! 1908: strcpy (*bufp, tbuf); ! 1909: return; ! 1910: } ! 1911: ! 1912: /* Construct base classes... ! 1913: FIXME: Does not deal with multiple inheritance and virtual bases ! 1914: correctly. See g++.old-deja/g++.jason/opeq5.C for a testcase. ! 1915: We need to do wacky things if everything between us and the virtual ! 1916: base (by all paths) has a "complex" op=. */ ! 1917: ! 1918: if (n_bases) ! 1919: { ! 1920: tree bases = TYPE_BINFO_BASETYPES (type); ! 1921: int i = 0; ! 1922: ! 1923: for (i = 0; i < n_bases; i++) ! 1924: { ! 1925: tree binfo = TREE_VEC_ELT (bases, i); ! 1926: tree btype, name; ! 1927: char *s; ! 1928: ! 1929: btype = BINFO_TYPE (binfo); ! 1930: name = TYPE_NESTED_NAME (btype); ! 1931: s = IDENTIFIER_POINTER (name); ! 1932: ! 1933: tneed = (2 * strlen (s)) + 42; ! 1934: if (tgot < tneed) ! 1935: { ! 1936: tgot = tneed; ! 1937: tbuf = (char *) alloca (tgot); ! 1938: } ! 1939: ! 1940: sprintf (tbuf, "%s::operator=((%s%s ::%s&)_ctor_arg);", s, ! 1941: TYPE_READONLY (type) ? "const " : "", ! 1942: CLASSTYPE_DECLARED_CLASS (btype) ? "class" : "struct", ! 1943: s); ! 1944: obstack_grow (&body, tbuf, strlen (tbuf)); ! 1945: } ! 1946: } ! 1947: ! 1948: /* Construct fields. */ ! 1949: ! 1950: if (fields) ! 1951: { ! 1952: tree f; ! 1953: ! 1954: for (f = fields; f; f = TREE_CHAIN (f)) ! 1955: { ! 1956: if (TREE_CODE (f) == FIELD_DECL && ! DECL_VIRTUAL_P (f)) ! 1957: { ! 1958: char *s; ! 1959: tree x; ! 1960: tree t = TREE_TYPE (f); ! 1961: ! 1962: if (DECL_NAME (f)) ! 1963: x = f; ! 1964: else if (t != NULL_TREE ! 1965: && TREE_CODE (t) == UNION_TYPE ! 1966: && ((TREE_CODE (TYPE_NAME (t)) == IDENTIFIER_NODE ! 1967: && ANON_AGGRNAME_P (TYPE_NAME (t))) ! 1968: || (TREE_CODE (TYPE_NAME (t)) == TYPE_DECL ! 1969: && ANON_AGGRNAME_P (TYPE_IDENTIFIER (t)))) ! 1970: && TYPE_FIELDS (t) != NULL_TREE) ! 1971: x = largest_union_member (t); ! 1972: else ! 1973: continue; ! 1974: ! 1975: s = IDENTIFIER_POINTER (DECL_NAME (x)); ! 1976: tneed = (2 * strlen (s)) + 13; ! 1977: if (tgot < tneed) ! 1978: { ! 1979: tgot = tneed; ! 1980: tbuf = (char *) alloca (tgot); ! 1981: } ! 1982: ! 1983: sprintf (tbuf, "%s=_ctor_arg.%s;", s, s); ! 1984: obstack_grow (&body, tbuf, strlen (tbuf)); ! 1985: } ! 1986: } ! 1987: } ! 1988: ! 1989: obstack_grow (&body, "return *this;}", 15); ! 1990: ! 1991: *lenp = obstack_object_size (&body) - 1; ! 1992: *bufp = obstack_alloc (&inline_text_obstack, *lenp); ! 1993: ! 1994: strcpy (*bufp, body.object_base); ! 1995: } ! 1996: ! 1997: /* Construct the body of a default copy constructor. */ ! 1998: static void ! 1999: default_copy_constructor_body (bufp, lenp, type, fields) ! 2000: char **bufp; ! 2001: int *lenp; ! 2002: tree type, fields; ! 2003: { ! 2004: static struct obstack prologue; ! 2005: static int inited = FALSE; ! 2006: int n_bases = CLASSTYPE_N_BASECLASSES (type); ! 2007: char sep = ':'; ! 2008: char *tbuf; ! 2009: int tgot, tneed; ! 2010: ! 2011: /* Create a buffer to call base class constructors and construct members ! 2012: (fields). */ ! 2013: ! 2014: if (!inited) ! 2015: { ! 2016: obstack_init (&prologue); ! 2017: inited = TRUE; ! 2018: } ! 2019: prologue.next_free = prologue.object_base; ! 2020: ! 2021: /* If we don't need a real copy ctor, just do a bitwise copy. */ ! 2022: if (! TYPE_HAS_COMPLEX_INIT_REF (type)) ! 2023: { ! 2024: tbuf = "{__builtin_memcpy(this,&_ctor_arg,sizeof(_ctor_arg));}"; ! 2025: *lenp = strlen (tbuf); ! 2026: *bufp = obstack_alloc (&inline_text_obstack, *lenp + 1); ! 2027: strcpy (*bufp, tbuf); ! 2028: return; ! 2029: } ! 2030: ! 2031: /* Small buffer for sprintf(). */ ! 2032: ! 2033: tgot = 100; ! 2034: tbuf = (char *) alloca (tgot); ! 2035: ! 2036: if (TREE_CODE (type) == UNION_TYPE) ! 2037: { ! 2038: if (fields) ! 2039: { ! 2040: tree main = fields; ! 2041: char * s; ! 2042: tree f; ! 2043: ! 2044: for (f = TREE_CHAIN (fields); f; f = TREE_CHAIN (f)) ! 2045: if (tree_int_cst_lt (TYPE_SIZE (TREE_TYPE (main)), ! 2046: TYPE_SIZE (TREE_TYPE (f)))) ! 2047: main = f; ! 2048: ! 2049: s = IDENTIFIER_POINTER (DECL_NAME (main)); ! 2050: tneed = (2 * strlen (s)) + 16; ! 2051: if (tgot < tneed) ! 2052: { ! 2053: tgot = tneed; ! 2054: tbuf = (char *) alloca (tgot); ! 2055: } ! 2056: ! 2057: sprintf (tbuf, ":%s(_ctor_arg.%s){}", s, s); ! 2058: } ! 2059: else ! 2060: tbuf = "{}"; ! 2061: ! 2062: *lenp = strlen (tbuf); ! 2063: *bufp = obstack_alloc (&inline_text_obstack, *lenp + 1); ! 2064: strcpy (*bufp, tbuf); ! 2065: return; ! 2066: } ! 2067: ! 2068: /* Construct base classes... */ ! 2069: ! 2070: if (n_bases) ! 2071: { ! 2072: /* Note that CLASSTYPE_VBASECLASSES isn't set yet... */ ! 2073: tree v = get_vbase_types (type); ! 2074: tree bases = TYPE_BINFO_BASETYPES (type); ! 2075: int i = 0; ! 2076: ! 2077: for (;;) ! 2078: { ! 2079: tree binfo, btype, name; ! 2080: char *s; ! 2081: ! 2082: if (v) ! 2083: { ! 2084: binfo = v; ! 2085: v = TREE_CHAIN (v); ! 2086: } ! 2087: else if (i < n_bases) ! 2088: { ! 2089: binfo = TREE_VEC_ELT (bases, i++); ! 2090: if (TREE_VIA_VIRTUAL (binfo)) ! 2091: continue; ! 2092: } ! 2093: else ! 2094: break; ! 2095: ! 2096: btype = BINFO_TYPE (binfo); ! 2097: name = TYPE_NESTED_NAME (btype); ! 2098: s = IDENTIFIER_POINTER (name); ! 2099: ! 2100: tneed = (2 * strlen (s)) + 39; ! 2101: if (tgot < tneed) ! 2102: { ! 2103: tgot = tneed; ! 2104: tbuf = (char *) alloca (tgot); ! 2105: } ! 2106: ! 2107: sprintf (tbuf, "%c%s((%s%s ::%s&)_ctor_arg)", sep, s, ! 2108: TYPE_READONLY (type) ? "const " : "", ! 2109: CLASSTYPE_DECLARED_CLASS (btype) ? "class" : "struct", ! 2110: s); ! 2111: sep = ','; ! 2112: obstack_grow (&prologue, tbuf, strlen (tbuf)); ! 2113: } ! 2114: } ! 2115: ! 2116: /* Construct fields. */ ! 2117: ! 2118: if (fields) ! 2119: { ! 2120: tree f; ! 2121: ! 2122: for (f = fields; f; f = TREE_CHAIN (f)) ! 2123: { ! 2124: if (TREE_CODE (f) == FIELD_DECL && ! DECL_VIRTUAL_P (f)) ! 2125: { ! 2126: char *s; ! 2127: tree x; ! 2128: tree t = TREE_TYPE (f); ! 2129: ! 2130: if (DECL_NAME (f)) ! 2131: x = f; ! 2132: else if (t != NULL_TREE ! 2133: && TREE_CODE (t) == UNION_TYPE ! 2134: && ((TREE_CODE (TYPE_NAME (t)) == IDENTIFIER_NODE ! 2135: && ANON_AGGRNAME_P (TYPE_NAME (t))) ! 2136: || (TREE_CODE (TYPE_NAME (t)) == TYPE_DECL ! 2137: && ANON_AGGRNAME_P (TYPE_IDENTIFIER (t)))) ! 2138: && TYPE_FIELDS (t) != NULL_TREE) ! 2139: x = largest_union_member (t); ! 2140: else ! 2141: continue; ! 2142: ! 2143: s = IDENTIFIER_POINTER (DECL_NAME (x)); ! 2144: tneed = (2 * strlen (s)) + 30; ! 2145: if (tgot < tneed) ! 2146: { ! 2147: tgot = tneed; ! 2148: tbuf = (char *) alloca (tgot); ! 2149: } ! 2150: ! 2151: sprintf (tbuf, "%c%s(_ctor_arg.%s)", sep, s, s); ! 2152: sep = ','; ! 2153: obstack_grow (&prologue, tbuf, strlen (tbuf)); ! 2154: } ! 2155: } ! 2156: } ! 2157: ! 2158: /* Concatenate constructor body to prologue. */ ! 2159: ! 2160: *lenp = obstack_object_size (&prologue) + 2; ! 2161: *bufp = obstack_alloc (&inline_text_obstack, *lenp + 1); ! 2162: ! 2163: obstack_1grow (&prologue, '\0'); ! 2164: ! 2165: strcpy (*bufp, prologue.object_base); ! 2166: strcat (*bufp, "{}"); ! 2167: } ! 2168: #endif ! 2169: ! 2170: /* Heuristic to tell whether the user is missing a semicolon ! 2171: after a struct or enum declaration. Emit an error message ! 2172: if we know the user has blown it. */ ! 2173: void ! 2174: check_for_missing_semicolon (type) ! 2175: tree type; ! 2176: { ! 2177: if (yychar < 0) ! 2178: yychar = yylex (); ! 2179: ! 2180: if ((yychar > 255 ! 2181: && yychar != SCSPEC ! 2182: && yychar != IDENTIFIER ! 2183: && yychar != TYPENAME) ! 2184: || end_of_file) ! 2185: { ! 2186: if (ANON_AGGRNAME_P (TYPE_IDENTIFIER (type))) ! 2187: error ("semicolon missing after %s declaration", ! 2188: TREE_CODE (type) == ENUMERAL_TYPE ? "enum" : "struct"); ! 2189: else ! 2190: cp_error ("semicolon missing after declaration of `%T'", type); ! 2191: shadow_tag (build_tree_list (0, type)); ! 2192: } ! 2193: /* Could probably also hack cases where class { ... } f (); appears. */ ! 2194: clear_anon_tags (); ! 2195: } ! 2196: ! 2197: void ! 2198: note_got_semicolon (type) ! 2199: tree type; ! 2200: { ! 2201: if (TREE_CODE_CLASS (TREE_CODE (type)) != 't') ! 2202: my_friendly_abort (60); ! 2203: if (IS_AGGR_TYPE (type)) ! 2204: CLASSTYPE_GOT_SEMICOLON (type) = 1; ! 2205: } ! 2206: ! 2207: void ! 2208: note_list_got_semicolon (declspecs) ! 2209: tree declspecs; ! 2210: { ! 2211: tree link; ! 2212: ! 2213: for (link = declspecs; link; link = TREE_CHAIN (link)) ! 2214: { ! 2215: tree type = TREE_VALUE (link); ! 2216: if (TREE_CODE_CLASS (TREE_CODE (type)) == 't') ! 2217: note_got_semicolon (type); ! 2218: } ! 2219: clear_anon_tags (); ! 2220: } ! 2221: ! 2222: /* If C is not whitespace, return C. ! 2223: Otherwise skip whitespace and return first nonwhite char read. */ ! 2224: ! 2225: static int ! 2226: skip_white_space (c) ! 2227: register int c; ! 2228: { ! 2229: for (;;) ! 2230: { ! 2231: switch (c) ! 2232: { ! 2233: case '\n': ! 2234: c = check_newline (); ! 2235: break; ! 2236: ! 2237: case ' ': ! 2238: case '\t': ! 2239: case '\f': ! 2240: case '\r': ! 2241: case '\v': ! 2242: case '\b': ! 2243: do ! 2244: c = getch (); ! 2245: while (c == ' ' || c == '\t'); ! 2246: break; ! 2247: ! 2248: case '\\': ! 2249: c = getch (); ! 2250: if (c == '\n') ! 2251: lineno++; ! 2252: else ! 2253: error ("stray '\\' in program"); ! 2254: c = getch (); ! 2255: break; ! 2256: ! 2257: default: ! 2258: return (c); ! 2259: } ! 2260: } ! 2261: } ! 2262: ! 2263: ! 2264: ! 2265: /* Make the token buffer longer, preserving the data in it. ! 2266: P should point to just beyond the last valid character in the old buffer. ! 2267: The value we return is a pointer to the new buffer ! 2268: at a place corresponding to P. */ ! 2269: ! 2270: static char * ! 2271: extend_token_buffer (p) ! 2272: char *p; ! 2273: { ! 2274: int offset = p - token_buffer; ! 2275: ! 2276: maxtoken = maxtoken * 2 + 10; ! 2277: token_buffer = (char *) xrealloc (token_buffer, maxtoken + 2); ! 2278: ! 2279: return token_buffer + offset; ! 2280: } ! 2281: ! 2282: static int ! 2283: get_last_nonwhite_on_line () ! 2284: { ! 2285: register int c; ! 2286: ! 2287: /* Is this the last nonwhite stuff on the line? */ ! 2288: if (nextchar >= 0) ! 2289: c = nextchar, nextchar = -1; ! 2290: else ! 2291: c = getch (); ! 2292: ! 2293: while (c == ' ' || c == '\t') ! 2294: c = getch (); ! 2295: return c; ! 2296: } ! 2297: ! 2298: /* At the beginning of a line, increment the line number ! 2299: and process any #-directive on this line. ! 2300: If the line is a #-directive, read the entire line and return a newline. ! 2301: Otherwise, return the line's first non-whitespace character. */ ! 2302: ! 2303: int ! 2304: check_newline () ! 2305: { ! 2306: register int c; ! 2307: register int token; ! 2308: ! 2309: /* Read first nonwhite char on the line. Do this before incrementing the ! 2310: line number, in case we're at the end of saved text. */ ! 2311: ! 2312: do ! 2313: c = getch (); ! 2314: while (c == ' ' || c == '\t'); ! 2315: ! 2316: lineno++; ! 2317: ! 2318: if (c != '#') ! 2319: { ! 2320: /* If not #, return it so caller will use it. */ ! 2321: return c; ! 2322: } ! 2323: ! 2324: /* Read first nonwhite char after the `#'. */ ! 2325: ! 2326: do ! 2327: c = getch (); ! 2328: while (c == ' ' || c == '\t'); ! 2329: ! 2330: /* If a letter follows, then if the word here is `line', skip ! 2331: it and ignore it; otherwise, ignore the line, with an error ! 2332: if the word isn't `pragma'. */ ! 2333: ! 2334: if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) ! 2335: { ! 2336: if (c == 'p') ! 2337: { ! 2338: if (getch () == 'r' ! 2339: && getch () == 'a' ! 2340: && getch () == 'g' ! 2341: && getch () == 'm' ! 2342: && getch () == 'a') ! 2343: { ! 2344: /* Read first nonwhite char after the `#pragma'. */ ! 2345: ! 2346: do ! 2347: c = getch (); ! 2348: while (c == ' ' || c == '\t'); ! 2349: ! 2350: if (c == 'v' ! 2351: && getch () == 't' ! 2352: && getch () == 'a' ! 2353: && getch () == 'b' ! 2354: && getch () == 'l' ! 2355: && getch () == 'e' ! 2356: && ((c = getch ()) == ' ' || c == '\t' || c == '\n')) ! 2357: { ! 2358: extern tree pending_vtables; ! 2359: ! 2360: /* More follows: it must be a string constant (class name). */ ! 2361: token = real_yylex (); ! 2362: if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST) ! 2363: { ! 2364: error ("invalid #pragma vtable"); ! 2365: goto skipline; ! 2366: } ! 2367: if (write_virtuals != 2) ! 2368: { ! 2369: warning ("use `+e2' option to enable #pragma vtable"); ! 2370: goto skipline; ! 2371: } ! 2372: pending_vtables = perm_tree_cons (NULL_TREE, get_identifier (TREE_STRING_POINTER (yylval.ttype)), pending_vtables); ! 2373: if (nextchar < 0) ! 2374: nextchar = getch (); ! 2375: c = nextchar; ! 2376: if (c != '\n') ! 2377: warning ("trailing characters ignored"); ! 2378: } ! 2379: else if (c == 'u' ! 2380: && getch () == 'n' ! 2381: && getch () == 'i' ! 2382: && getch () == 't' ! 2383: && ((c = getch ()) == ' ' || c == '\t' || c == '\n')) ! 2384: { ! 2385: /* More follows: it must be a string constant (unit name). */ ! 2386: token = real_yylex (); ! 2387: if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST) ! 2388: { ! 2389: error ("invalid #pragma unit"); ! 2390: goto skipline; ! 2391: } ! 2392: current_unit_name = get_identifier (TREE_STRING_POINTER (yylval.ttype)); ! 2393: current_unit_language = current_lang_name; ! 2394: if (nextchar < 0) ! 2395: nextchar = getch (); ! 2396: c = nextchar; ! 2397: if (c != '\n') ! 2398: warning ("trailing characters ignored"); ! 2399: } ! 2400: else if (c == 'i') ! 2401: { ! 2402: tree fileinfo = IDENTIFIER_CLASS_VALUE (get_time_identifier (input_filename)); ! 2403: c = getch (); ! 2404: ! 2405: if (c == 'n' ! 2406: && getch () == 't' ! 2407: && getch () == 'e' ! 2408: && getch () == 'r' ! 2409: && getch () == 'f' ! 2410: && getch () == 'a' ! 2411: && getch () == 'c' ! 2412: && getch () == 'e' ! 2413: && ((c = getch ()) == ' ' || c == '\t' || c == '\n')) ! 2414: { ! 2415: int warned_already = 0; ! 2416: char *main_filename = input_filename; ! 2417: ! 2418: main_filename = FILE_NAME_NONDIRECTORY (main_filename); ! 2419: while (c == ' ' || c == '\t') ! 2420: c = getch (); ! 2421: if (c != '\n') ! 2422: { ! 2423: put_back (c); ! 2424: token = real_yylex (); ! 2425: if (token != STRING ! 2426: || TREE_CODE (yylval.ttype) != STRING_CST) ! 2427: { ! 2428: error ("invalid `#pragma interface'"); ! 2429: goto skipline; ! 2430: } ! 2431: main_filename = TREE_STRING_POINTER (yylval.ttype); ! 2432: c = getch(); ! 2433: put_back (c); ! 2434: } ! 2435: ! 2436: while (c == ' ' || c == '\t') ! 2437: c = getch (); ! 2438: ! 2439: while (c != '\n') ! 2440: { ! 2441: if (!warned_already && extra_warnings ! 2442: && c != ' ' && c != '\t' && c != '\n') ! 2443: { ! 2444: warning ("garbage after `#pragma interface' ignored"); ! 2445: warned_already = 1; ! 2446: } ! 2447: c = getch (); ! 2448: } ! 2449: ! 2450: write_virtuals = 3; ! 2451: ! 2452: if (impl_file_chain == 0) ! 2453: { ! 2454: /* If this is zero at this point, then we are ! 2455: auto-implementing. */ ! 2456: if (main_input_filename == 0) ! 2457: main_input_filename = input_filename; ! 2458: ! 2459: #ifdef AUTO_IMPLEMENT ! 2460: filename = FILE_NAME_NONDIRECTORY (main_input_filename); ! 2461: fi = get_time_identifier (filename); ! 2462: fi = IDENTIFIER_CLASS_VALUE (fi); ! 2463: TREE_INT_CST_LOW (fi) = 0; ! 2464: TREE_INT_CST_HIGH (fi) = 1; ! 2465: /* Get default. */ ! 2466: impl_file_chain = (struct impl_files *)permalloc (sizeof (struct impl_files)); ! 2467: impl_file_chain->filename = filename; ! 2468: impl_file_chain->next = 0; ! 2469: #endif ! 2470: } ! 2471: ! 2472: interface_only = interface_strcmp (main_filename); ! 2473: interface_unknown = 0; ! 2474: TREE_INT_CST_LOW (fileinfo) = interface_only; ! 2475: TREE_INT_CST_HIGH (fileinfo) = interface_unknown; ! 2476: } ! 2477: else if (c == 'm' ! 2478: && getch () == 'p' ! 2479: && getch () == 'l' ! 2480: && getch () == 'e' ! 2481: && getch () == 'm' ! 2482: && getch () == 'e' ! 2483: && getch () == 'n' ! 2484: && getch () == 't' ! 2485: && getch () == 'a' ! 2486: && getch () == 't' ! 2487: && getch () == 'i' ! 2488: && getch () == 'o' ! 2489: && getch () == 'n' ! 2490: && ((c = getch ()) == ' ' || c == '\t' || c == '\n')) ! 2491: { ! 2492: int warned_already = 0; ! 2493: char *main_filename = main_input_filename ? main_input_filename : input_filename; ! 2494: ! 2495: main_filename = FILE_NAME_NONDIRECTORY (main_filename); ! 2496: while (c == ' ' || c == '\t') ! 2497: c = getch (); ! 2498: if (c != '\n') ! 2499: { ! 2500: put_back (c); ! 2501: token = real_yylex (); ! 2502: if (token != STRING ! 2503: || TREE_CODE (yylval.ttype) != STRING_CST) ! 2504: { ! 2505: error ("invalid `#pragma implementation'"); ! 2506: goto skipline; ! 2507: } ! 2508: main_filename = TREE_STRING_POINTER (yylval.ttype); ! 2509: c = getch(); ! 2510: put_back (c); ! 2511: } ! 2512: ! 2513: while (c == ' ' || c == '\t') ! 2514: c = getch (); ! 2515: ! 2516: while (c != '\n') ! 2517: { ! 2518: if (!warned_already && extra_warnings ! 2519: && c != ' ' && c != '\t' && c != '\n') ! 2520: { ! 2521: warning ("garbage after `#pragma implementation' ignored"); ! 2522: warned_already = 1; ! 2523: } ! 2524: c = getch (); ! 2525: } ! 2526: ! 2527: if (write_virtuals == 3) ! 2528: { ! 2529: struct impl_files *ifiles = impl_file_chain; ! 2530: while (ifiles) ! 2531: { ! 2532: if (! strcmp (ifiles->filename, main_filename)) ! 2533: break; ! 2534: ifiles = ifiles->next; ! 2535: } ! 2536: if (ifiles == 0) ! 2537: { ! 2538: ifiles = (struct impl_files*) permalloc (sizeof (struct impl_files)); ! 2539: ifiles->filename = main_filename; ! 2540: ifiles->next = impl_file_chain; ! 2541: impl_file_chain = ifiles; ! 2542: } ! 2543: } ! 2544: else if ((main_input_filename != 0 ! 2545: && ! strcmp (main_input_filename, input_filename)) ! 2546: || ! strcmp (input_filename, main_filename)) ! 2547: { ! 2548: write_virtuals = 3; ! 2549: if (impl_file_chain == 0) ! 2550: { ! 2551: impl_file_chain = (struct impl_files*) permalloc (sizeof (struct impl_files)); ! 2552: impl_file_chain->filename = main_filename; ! 2553: impl_file_chain->next = 0; ! 2554: } ! 2555: } ! 2556: else ! 2557: error ("`#pragma implementation' can only appear at top-level"); ! 2558: interface_only = 0; ! 2559: #if 1 ! 2560: /* We make this non-zero so that we infer decl linkage ! 2561: in the impl file only for variables first declared ! 2562: in the interface file. */ ! 2563: interface_unknown = 1; ! 2564: #else ! 2565: /* We make this zero so that templates in the impl ! 2566: file will be emitted properly. */ ! 2567: interface_unknown = 0; ! 2568: #endif ! 2569: TREE_INT_CST_LOW (fileinfo) = interface_only; ! 2570: TREE_INT_CST_HIGH (fileinfo) = interface_unknown; ! 2571: } ! 2572: } ! 2573: } ! 2574: goto skipline; ! 2575: } ! 2576: else if (c == 'd') ! 2577: { ! 2578: if (getch () == 'e' ! 2579: && getch () == 'f' ! 2580: && getch () == 'i' ! 2581: && getch () == 'n' ! 2582: && getch () == 'e' ! 2583: && ((c = getch ()) == ' ' || c == '\t' || c == '\n')) ! 2584: { ! 2585: #ifdef DWARF_DEBUGGING_INFO ! 2586: if ((debug_info_level == DINFO_LEVEL_VERBOSE) ! 2587: && (write_symbols == DWARF_DEBUG)) ! 2588: dwarfout_define (lineno, get_directive_line (finput)); ! 2589: #endif /* DWARF_DEBUGGING_INFO */ ! 2590: goto skipline; ! 2591: } ! 2592: } ! 2593: else if (c == 'u') ! 2594: { ! 2595: if (getch () == 'n' ! 2596: && getch () == 'd' ! 2597: && getch () == 'e' ! 2598: && getch () == 'f' ! 2599: && ((c = getch ()) == ' ' || c == '\t' || c == '\n')) ! 2600: { ! 2601: #ifdef DWARF_DEBUGGING_INFO ! 2602: if ((debug_info_level == DINFO_LEVEL_VERBOSE) ! 2603: && (write_symbols == DWARF_DEBUG)) ! 2604: dwarfout_undef (lineno, get_directive_line (finput)); ! 2605: #endif /* DWARF_DEBUGGING_INFO */ ! 2606: goto skipline; ! 2607: } ! 2608: } ! 2609: else if (c == 'l') ! 2610: { ! 2611: if (getch () == 'i' ! 2612: && getch () == 'n' ! 2613: && getch () == 'e' ! 2614: && ((c = getch ()) == ' ' || c == '\t')) ! 2615: goto linenum; ! 2616: } ! 2617: else if (c == 'i') ! 2618: { ! 2619: if (getch () == 'd' ! 2620: && getch () == 'e' ! 2621: && getch () == 'n' ! 2622: && getch () == 't' ! 2623: && ((c = getch ()) == ' ' || c == '\t')) ! 2624: { ! 2625: #ifdef ASM_OUTPUT_IDENT ! 2626: extern FILE *asm_out_file; ! 2627: #endif ! 2628: /* #ident. The pedantic warning is now in cccp.c. */ ! 2629: ! 2630: /* Here we have just seen `#ident '. ! 2631: A string constant should follow. */ ! 2632: ! 2633: while (c == ' ' || c == '\t') ! 2634: c = getch (); ! 2635: ! 2636: /* If no argument, ignore the line. */ ! 2637: if (c == '\n') ! 2638: return c; ! 2639: ! 2640: put_back (c); ! 2641: token = real_yylex (); ! 2642: if (token != STRING ! 2643: || TREE_CODE (yylval.ttype) != STRING_CST) ! 2644: { ! 2645: error ("invalid #ident"); ! 2646: goto skipline; ! 2647: } ! 2648: ! 2649: if (! flag_no_ident) ! 2650: { ! 2651: #ifdef ASM_OUTPUT_IDENT ! 2652: ASM_OUTPUT_IDENT (asm_out_file, ! 2653: TREE_STRING_POINTER (yylval.ttype)); ! 2654: #endif ! 2655: } ! 2656: ! 2657: /* Skip the rest of this line. */ ! 2658: goto skipline; ! 2659: } ! 2660: } ! 2661: else if (c == 'n') ! 2662: { ! 2663: if (getch () == 'e' ! 2664: && getch () == 'w' ! 2665: && getch () == 'w' ! 2666: && getch () == 'o' ! 2667: && getch () == 'r' ! 2668: && getch () == 'l' ! 2669: && getch () == 'd' ! 2670: && ((c = getch ()) == ' ' || c == '\t')) ! 2671: { ! 2672: /* Used to test incremental compilation. */ ! 2673: sorry ("#pragma newworld"); ! 2674: goto skipline; ! 2675: } ! 2676: } ! 2677: error ("undefined or invalid # directive"); ! 2678: goto skipline; ! 2679: } ! 2680: ! 2681: linenum: ! 2682: /* Here we have either `#line' or `# <nonletter>'. ! 2683: In either case, it should be a line number; a digit should follow. */ ! 2684: ! 2685: while (c == ' ' || c == '\t') ! 2686: c = getch (); ! 2687: ! 2688: /* If the # is the only nonwhite char on the line, ! 2689: just ignore it. Check the new newline. */ ! 2690: if (c == '\n') ! 2691: return c; ! 2692: ! 2693: /* Something follows the #; read a token. */ ! 2694: ! 2695: put_back (c); ! 2696: token = real_yylex (); ! 2697: ! 2698: if (token == CONSTANT ! 2699: && TREE_CODE (yylval.ttype) == INTEGER_CST) ! 2700: { ! 2701: int old_lineno = lineno; ! 2702: enum { act_none, act_push, act_pop } action = act_none; ! 2703: int entering_system_header = 0; ! 2704: int entering_c_header = 0; ! 2705: ! 2706: /* subtract one, because it is the following line that ! 2707: gets the specified number */ ! 2708: ! 2709: int l = TREE_INT_CST_LOW (yylval.ttype) - 1; ! 2710: c = get_last_nonwhite_on_line (); ! 2711: if (c == '\n') ! 2712: { ! 2713: /* No more: store the line number and check following line. */ ! 2714: lineno = l; ! 2715: return c; ! 2716: } ! 2717: put_back (c); ! 2718: ! 2719: /* More follows: it must be a string constant (filename). */ ! 2720: ! 2721: /* Read the string constant, but don't treat \ as special. */ ! 2722: ignore_escape_flag = 1; ! 2723: token = real_yylex (); ! 2724: ignore_escape_flag = 0; ! 2725: ! 2726: if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST) ! 2727: { ! 2728: error ("invalid #line"); ! 2729: goto skipline; ! 2730: } ! 2731: ! 2732: /* Changing files again. This means currently collected time ! 2733: is charged against header time, and body time starts back ! 2734: at 0. */ ! 2735: if (flag_detailed_statistics) ! 2736: { ! 2737: int this_time = my_get_run_time (); ! 2738: tree time_identifier = get_time_identifier (TREE_STRING_POINTER (yylval.ttype)); ! 2739: header_time += this_time - body_time; ! 2740: TREE_INT_CST_LOW (IDENTIFIER_LOCAL_VALUE (this_filename_time)) ! 2741: += this_time - body_time; ! 2742: this_filename_time = time_identifier; ! 2743: body_time = this_time; ! 2744: } ! 2745: ! 2746: if (flag_cadillac) ! 2747: cadillac_note_source (); ! 2748: ! 2749: input_filename ! 2750: = (char *) permalloc (TREE_STRING_LENGTH (yylval.ttype) + 1); ! 2751: strcpy (input_filename, TREE_STRING_POINTER (yylval.ttype)); ! 2752: lineno = l; ! 2753: GNU_xref_file (input_filename); ! 2754: ! 2755: if (main_input_filename == 0) ! 2756: { ! 2757: struct impl_files *ifiles = impl_file_chain; ! 2758: ! 2759: if (ifiles) ! 2760: { ! 2761: while (ifiles->next) ! 2762: ifiles = ifiles->next; ! 2763: ifiles->filename = FILE_NAME_NONDIRECTORY (input_filename); ! 2764: } ! 2765: ! 2766: main_input_filename = input_filename; ! 2767: if (write_virtuals == 3) ! 2768: walk_vtables (set_typedecl_interface_info, set_vardecl_interface_info); ! 2769: } ! 2770: ! 2771: extract_interface_info (); ! 2772: ! 2773: c = get_last_nonwhite_on_line (); ! 2774: if (c != '\n') ! 2775: { ! 2776: put_back (c); ! 2777: ! 2778: token = real_yylex (); ! 2779: ! 2780: /* `1' after file name means entering new file. ! 2781: `2' after file name means just left a file. */ ! 2782: ! 2783: if (token == CONSTANT ! 2784: && TREE_CODE (yylval.ttype) == INTEGER_CST) ! 2785: { ! 2786: if (TREE_INT_CST_LOW (yylval.ttype) == 1) ! 2787: action = act_push; ! 2788: else if (TREE_INT_CST_LOW (yylval.ttype) == 2) ! 2789: action = act_pop; ! 2790: ! 2791: if (action) ! 2792: { ! 2793: c = get_last_nonwhite_on_line (); ! 2794: if (c != '\n') ! 2795: { ! 2796: put_back (c); ! 2797: token = real_yylex (); ! 2798: } ! 2799: } ! 2800: } ! 2801: ! 2802: /* `3' after file name means this is a system header file. */ ! 2803: ! 2804: if (token == CONSTANT ! 2805: && TREE_CODE (yylval.ttype) == INTEGER_CST ! 2806: && TREE_INT_CST_LOW (yylval.ttype) == 3) ! 2807: { ! 2808: entering_system_header = 1; ! 2809: ! 2810: c = get_last_nonwhite_on_line (); ! 2811: if (c != '\n') ! 2812: { ! 2813: put_back (c); ! 2814: token = real_yylex (); ! 2815: } ! 2816: } ! 2817: ! 2818: /* `4' after file name means this is a C header file. */ ! 2819: ! 2820: if (token == CONSTANT ! 2821: && TREE_CODE (yylval.ttype) == INTEGER_CST ! 2822: && TREE_INT_CST_LOW (yylval.ttype) == 4) ! 2823: { ! 2824: entering_c_header = 1; ! 2825: ! 2826: c = get_last_nonwhite_on_line (); ! 2827: if (c != '\n') ! 2828: { ! 2829: put_back (c); ! 2830: token = real_yylex (); ! 2831: } ! 2832: } ! 2833: ! 2834: /* Do the actions implied by the preceeding numbers. */ ! 2835: ! 2836: if (action == act_push) ! 2837: { ! 2838: /* Pushing to a new file. */ ! 2839: struct file_stack *p; ! 2840: ! 2841: p = (struct file_stack *) xmalloc (sizeof (struct file_stack)); ! 2842: input_file_stack->line = old_lineno; ! 2843: p->next = input_file_stack; ! 2844: p->name = input_filename; ! 2845: input_file_stack = p; ! 2846: input_file_stack_tick++; ! 2847: #ifdef DWARF_DEBUGGING_INFO ! 2848: if (debug_info_level == DINFO_LEVEL_VERBOSE ! 2849: && write_symbols == DWARF_DEBUG) ! 2850: dwarfout_start_new_source_file (input_filename); ! 2851: #endif /* DWARF_DEBUGGING_INFO */ ! 2852: if (flag_cadillac) ! 2853: cadillac_push_source (); ! 2854: in_system_header = entering_system_header; ! 2855: if (c_header_level) ! 2856: ++c_header_level; ! 2857: else if (entering_c_header) ! 2858: { ! 2859: c_header_level = 1; ! 2860: ++pending_lang_change; ! 2861: } ! 2862: } ! 2863: else if (action == act_pop) ! 2864: { ! 2865: /* Popping out of a file. */ ! 2866: if (input_file_stack->next) ! 2867: { ! 2868: struct file_stack *p; ! 2869: ! 2870: if (c_header_level && --c_header_level == 0) ! 2871: { ! 2872: if (entering_c_header) ! 2873: warning ("badly nested C headers from preprocessor"); ! 2874: --pending_lang_change; ! 2875: } ! 2876: if (flag_cadillac) ! 2877: cadillac_pop_source (); ! 2878: in_system_header = entering_system_header; ! 2879: ! 2880: p = input_file_stack; ! 2881: input_file_stack = p->next; ! 2882: free (p); ! 2883: input_file_stack_tick++; ! 2884: #ifdef DWARF_DEBUGGING_INFO ! 2885: if (debug_info_level == DINFO_LEVEL_VERBOSE ! 2886: && write_symbols == DWARF_DEBUG) ! 2887: dwarfout_resume_previous_source_file (input_file_stack->line); ! 2888: #endif /* DWARF_DEBUGGING_INFO */ ! 2889: } ! 2890: else ! 2891: error ("#-lines for entering and leaving files don't match"); ! 2892: } ! 2893: else ! 2894: { ! 2895: in_system_header = entering_system_header; ! 2896: if (flag_cadillac) ! 2897: cadillac_switch_source (-1); ! 2898: } ! 2899: } ! 2900: ! 2901: /* If NEXTCHAR is not end of line, we don't care what it is. */ ! 2902: if (nextchar == '\n') ! 2903: return '\n'; ! 2904: } ! 2905: else ! 2906: error ("invalid #-line"); ! 2907: ! 2908: /* skip the rest of this line. */ ! 2909: skipline: ! 2910: if (c == '\n') ! 2911: return c; ! 2912: while ((c = getch ()) != EOF && c != '\n'); ! 2913: return c; ! 2914: } ! 2915: ! 2916: void ! 2917: do_pending_lang_change () ! 2918: { ! 2919: for (; pending_lang_change > 0; --pending_lang_change) ! 2920: push_lang_context (lang_name_c); ! 2921: for (; pending_lang_change < 0; ++pending_lang_change) ! 2922: pop_lang_context (); ! 2923: } ! 2924: ! 2925: #if 0 ! 2926: #define isalnum(char) (char >= 'a' ? char <= 'z' : char >= '0' ? char <= '9' || (char >= 'A' && char <= 'Z') : 0) ! 2927: #define isdigit(char) (char >= '0' && char <= '9') ! 2928: #else ! 2929: #include <ctype.h> ! 2930: #endif ! 2931: ! 2932: #define ENDFILE -1 /* token that represents end-of-file */ ! 2933: ! 2934: /* Read an escape sequence, returning its equivalent as a character, ! 2935: or store 1 in *ignore_ptr if it is backslash-newline. */ ! 2936: ! 2937: static int ! 2938: readescape (ignore_ptr) ! 2939: int *ignore_ptr; ! 2940: { ! 2941: register int c = getch (); ! 2942: register int code; ! 2943: register unsigned count; ! 2944: unsigned firstdig; ! 2945: int nonnull; ! 2946: ! 2947: switch (c) ! 2948: { ! 2949: case 'x': ! 2950: if (warn_traditional) ! 2951: warning ("the meaning of `\\x' varies with -traditional"); ! 2952: ! 2953: if (flag_traditional) ! 2954: return c; ! 2955: ! 2956: code = 0; ! 2957: count = 0; ! 2958: nonnull = 0; ! 2959: while (1) ! 2960: { ! 2961: c = getch (); ! 2962: if (! isxdigit (c)) ! 2963: { ! 2964: put_back (c); ! 2965: break; ! 2966: } ! 2967: code *= 16; ! 2968: if (c >= 'a' && c <= 'f') ! 2969: code += c - 'a' + 10; ! 2970: if (c >= 'A' && c <= 'F') ! 2971: code += c - 'A' + 10; ! 2972: if (c >= '0' && c <= '9') ! 2973: code += c - '0'; ! 2974: if (code != 0 || count != 0) ! 2975: { ! 2976: if (count == 0) ! 2977: firstdig = code; ! 2978: count++; ! 2979: } ! 2980: nonnull = 1; ! 2981: } ! 2982: if (! nonnull) ! 2983: error ("\\x used with no following hex digits"); ! 2984: else if (count == 0) ! 2985: /* Digits are all 0's. Ok. */ ! 2986: ; ! 2987: else if ((count - 1) * 4 >= TYPE_PRECISION (integer_type_node) ! 2988: || (count > 1 ! 2989: && ((1 << (TYPE_PRECISION (integer_type_node) - (count - 1) * 4)) ! 2990: <= firstdig))) ! 2991: pedwarn ("hex escape out of range"); ! 2992: return code; ! 2993: ! 2994: case '0': case '1': case '2': case '3': case '4': ! 2995: case '5': case '6': case '7': ! 2996: code = 0; ! 2997: count = 0; ! 2998: while ((c <= '7') && (c >= '0') && (count++ < 3)) ! 2999: { ! 3000: code = (code * 8) + (c - '0'); ! 3001: c = getch (); ! 3002: } ! 3003: put_back (c); ! 3004: return code; ! 3005: ! 3006: case '\\': case '\'': case '"': ! 3007: return c; ! 3008: ! 3009: case '\n': ! 3010: lineno++; ! 3011: *ignore_ptr = 1; ! 3012: return 0; ! 3013: ! 3014: case 'n': ! 3015: return TARGET_NEWLINE; ! 3016: ! 3017: case 't': ! 3018: return TARGET_TAB; ! 3019: ! 3020: case 'r': ! 3021: return TARGET_CR; ! 3022: ! 3023: case 'f': ! 3024: return TARGET_FF; ! 3025: ! 3026: case 'b': ! 3027: return TARGET_BS; ! 3028: ! 3029: case 'a': ! 3030: if (warn_traditional) ! 3031: warning ("the meaning of `\\a' varies with -traditional"); ! 3032: ! 3033: if (flag_traditional) ! 3034: return c; ! 3035: return TARGET_BELL; ! 3036: ! 3037: case 'v': ! 3038: return TARGET_VT; ! 3039: ! 3040: case 'e': ! 3041: case 'E': ! 3042: if (pedantic) ! 3043: pedwarn ("non-ANSI-standard escape sequence, `\\%c'", c); ! 3044: return 033; ! 3045: ! 3046: case '?': ! 3047: return c; ! 3048: ! 3049: /* `\(', etc, are used at beginning of line to avoid confusing Emacs. */ ! 3050: case '(': ! 3051: case '{': ! 3052: case '[': ! 3053: /* `\%' is used to prevent SCCS from getting confused. */ ! 3054: case '%': ! 3055: if (pedantic) ! 3056: pedwarn ("unknown escape sequence `\\%c'", c); ! 3057: return c; ! 3058: } ! 3059: if (c >= 040 && c < 0177) ! 3060: pedwarn ("unknown escape sequence `\\%c'", c); ! 3061: else ! 3062: pedwarn ("unknown escape sequence: `\\' followed by char code 0x%x", c); ! 3063: return c; ! 3064: } ! 3065: ! 3066: /* Value is 1 (or 2) if we should try to make the next identifier look like ! 3067: a typename (when it may be a local variable or a class variable). ! 3068: Value is 0 if we treat this name in a default fashion. */ ! 3069: int looking_for_typename = 0; ! 3070: ! 3071: #if 0 ! 3072: /* NO LONGER USED: Value is -1 if we must not see a type name. */ ! 3073: void ! 3074: dont_see_typename () ! 3075: { ! 3076: looking_for_typename = -1; ! 3077: if (yychar == TYPENAME || yychar == PTYPENAME) ! 3078: { ! 3079: yychar = IDENTIFIER; ! 3080: lastiddecl = 0; ! 3081: } ! 3082: } ! 3083: #endif ! 3084: ! 3085: #ifdef __GNUC__ ! 3086: extern __inline int identifier_type (); ! 3087: __inline ! 3088: #endif ! 3089: int ! 3090: identifier_type (decl) ! 3091: tree decl; ! 3092: { ! 3093: if (TREE_CODE (decl) == TEMPLATE_DECL ! 3094: && DECL_TEMPLATE_IS_CLASS (decl)) ! 3095: return PTYPENAME; ! 3096: if (TREE_CODE (decl) != TYPE_DECL) ! 3097: return IDENTIFIER; ! 3098: return TYPENAME; ! 3099: } ! 3100: ! 3101: void ! 3102: see_typename () ! 3103: { ! 3104: looking_for_typename = 0; ! 3105: if (yychar == IDENTIFIER) ! 3106: { ! 3107: lastiddecl = lookup_name (yylval.ttype, -2); ! 3108: if (lastiddecl == 0) ! 3109: { ! 3110: if (flag_labels_ok) ! 3111: lastiddecl = IDENTIFIER_LABEL_VALUE (yylval.ttype); ! 3112: } ! 3113: else ! 3114: yychar = identifier_type (lastiddecl); ! 3115: } ! 3116: } ! 3117: ! 3118: tree ! 3119: do_identifier (token) ! 3120: register tree token; ! 3121: { ! 3122: register tree id = lastiddecl; ! 3123: ! 3124: if (yychar == YYEMPTY) ! 3125: yychar = yylex (); ! 3126: /* Scope class declarations before global ! 3127: declarations. */ ! 3128: if (id == IDENTIFIER_GLOBAL_VALUE (token) ! 3129: && current_class_type != 0 ! 3130: && TYPE_SIZE (current_class_type) == 0 ! 3131: && TREE_CODE (current_class_type) != UNINSTANTIATED_P_TYPE) ! 3132: { ! 3133: /* Could be from one of the base classes. */ ! 3134: tree field = lookup_field (current_class_type, token, 1, 0); ! 3135: if (field == 0) ! 3136: ; ! 3137: else if (field == error_mark_node) ! 3138: /* We have already generated the error message. ! 3139: But we still want to return this value. */ ! 3140: id = lookup_field (current_class_type, token, 0, 0); ! 3141: else if (TREE_CODE (field) == VAR_DECL ! 3142: || TREE_CODE (field) == CONST_DECL) ! 3143: id = field; ! 3144: else if (TREE_CODE (field) != FIELD_DECL) ! 3145: my_friendly_abort (61); ! 3146: else ! 3147: { ! 3148: cp_error ("invalid use of member `%D' from base class `%T'", field, ! 3149: DECL_FIELD_CONTEXT (field)); ! 3150: id = error_mark_node; ! 3151: return id; ! 3152: } ! 3153: } ! 3154: ! 3155: /* Remember that this name has been used in the class definition, as per ! 3156: [class.scope0] */ ! 3157: if (id && current_class_type ! 3158: && TYPE_BEING_DEFINED (current_class_type) ! 3159: && ! IDENTIFIER_CLASS_VALUE (token)) ! 3160: pushdecl_class_level (id); ! 3161: ! 3162: if (!id || id == error_mark_node) ! 3163: { ! 3164: if (id == error_mark_node && current_class_type != NULL_TREE) ! 3165: { ! 3166: id = lookup_nested_field (token, 1); ! 3167: /* In lookup_nested_field(), we marked this so we can gracefully ! 3168: leave this whole mess. */ ! 3169: if (id && id != error_mark_node && TREE_TYPE (id) == error_mark_node) ! 3170: return id; ! 3171: } ! 3172: if (yychar == '(' || yychar == LEFT_RIGHT) ! 3173: { ! 3174: id = implicitly_declare (token); ! 3175: } ! 3176: else if (current_function_decl == 0) ! 3177: { ! 3178: cp_error ("`%D' was not declared in this scope", token); ! 3179: id = error_mark_node; ! 3180: } ! 3181: else ! 3182: { ! 3183: if (IDENTIFIER_GLOBAL_VALUE (token) != error_mark_node ! 3184: || IDENTIFIER_ERROR_LOCUS (token) != current_function_decl) ! 3185: { ! 3186: static int undeclared_variable_notice; ! 3187: ! 3188: cp_error ("`%D' undeclared (first use this function)", token); ! 3189: ! 3190: if (! undeclared_variable_notice) ! 3191: { ! 3192: error ("(Each undeclared identifier is reported only once"); ! 3193: error ("for each function it appears in.)"); ! 3194: undeclared_variable_notice = 1; ! 3195: } ! 3196: } ! 3197: id = error_mark_node; ! 3198: /* Prevent repeated error messages. */ ! 3199: IDENTIFIER_GLOBAL_VALUE (token) = error_mark_node; ! 3200: SET_IDENTIFIER_ERROR_LOCUS (token, current_function_decl); ! 3201: } ! 3202: } ! 3203: /* TREE_USED is set in `hack_identifier'. */ ! 3204: if (TREE_CODE (id) == CONST_DECL) ! 3205: { ! 3206: if (IDENTIFIER_CLASS_VALUE (token) == id) ! 3207: { ! 3208: /* Check access. */ ! 3209: enum access_type access ! 3210: = compute_access (TYPE_BINFO (current_class_type), id); ! 3211: if (access == access_private) ! 3212: cp_error ("enum `%D' is private", id); ! 3213: /* protected is OK, since it's an enum of `this'. */ ! 3214: } ! 3215: id = DECL_INITIAL (id); ! 3216: } ! 3217: else ! 3218: id = hack_identifier (id, token, yychar); ! 3219: return id; ! 3220: } ! 3221: ! 3222: tree ! 3223: identifier_typedecl_value (node) ! 3224: tree node; ! 3225: { ! 3226: tree t, type; ! 3227: type = IDENTIFIER_TYPE_VALUE (node); ! 3228: if (type == NULL_TREE) ! 3229: return NULL_TREE; ! 3230: #define do(X) \ ! 3231: { \ ! 3232: t = (X); \ ! 3233: if (t && TREE_CODE (t) == TYPE_DECL && TREE_TYPE (t) == type) \ ! 3234: return t; \ ! 3235: } ! 3236: do (IDENTIFIER_LOCAL_VALUE (node)); ! 3237: do (IDENTIFIER_CLASS_VALUE (node)); ! 3238: do (IDENTIFIER_GLOBAL_VALUE (node)); ! 3239: #undef do ! 3240: /* Will this one ever happen? */ ! 3241: if (TYPE_NAME (type)) ! 3242: return TYPE_NAME (type); ! 3243: ! 3244: /* We used to do an internal error of 62 here, but instead we will ! 3245: handle the return of a null appropriately in the callers. */ ! 3246: return NULL_TREE; ! 3247: } ! 3248: ! 3249: struct try_type ! 3250: { ! 3251: tree *node_var; ! 3252: char unsigned_flag; ! 3253: char long_flag; ! 3254: char long_long_flag; ! 3255: }; ! 3256: ! 3257: struct try_type type_sequence[] = ! 3258: { ! 3259: { &integer_type_node, 0, 0, 0}, ! 3260: { &unsigned_type_node, 1, 0, 0}, ! 3261: { &long_integer_type_node, 0, 1, 0}, ! 3262: { &long_unsigned_type_node, 1, 1, 0}, ! 3263: { &long_long_integer_type_node, 0, 1, 1}, ! 3264: { &long_long_unsigned_type_node, 1, 1, 1} ! 3265: }; ! 3266: ! 3267: int ! 3268: real_yylex () ! 3269: { ! 3270: register int c; ! 3271: register int value; ! 3272: int wide_flag = 0; ! 3273: int dollar_seen = 0; ! 3274: int i; ! 3275: ! 3276: if (nextchar >= 0) ! 3277: c = nextchar, nextchar = -1; ! 3278: else ! 3279: c = getch (); ! 3280: ! 3281: /* Effectively do c = skip_white_space (c) ! 3282: but do it faster in the usual cases. */ ! 3283: while (1) ! 3284: switch (c) ! 3285: { ! 3286: case ' ': ! 3287: case '\t': ! 3288: case '\f': ! 3289: case '\v': ! 3290: case '\b': ! 3291: c = getch (); ! 3292: break; ! 3293: ! 3294: case '\r': ! 3295: /* Call skip_white_space so we can warn if appropriate. */ ! 3296: ! 3297: case '\n': ! 3298: case '/': ! 3299: case '\\': ! 3300: c = skip_white_space (c); ! 3301: default: ! 3302: goto found_nonwhite; ! 3303: } ! 3304: found_nonwhite: ! 3305: ! 3306: token_buffer[0] = c; ! 3307: token_buffer[1] = 0; ! 3308: ! 3309: /* yylloc.first_line = lineno; */ ! 3310: ! 3311: switch (c) ! 3312: { ! 3313: case EOF: ! 3314: token_buffer[0] = '\0'; ! 3315: end_of_file = 1; ! 3316: if (input_redirected ()) ! 3317: value = END_OF_SAVED_INPUT; ! 3318: else if (do_pending_expansions ()) ! 3319: /* this will set yychar for us */ ! 3320: return yychar; ! 3321: else ! 3322: value = ENDFILE; ! 3323: break; ! 3324: ! 3325: case '$': ! 3326: if (dollars_in_ident) ! 3327: { ! 3328: dollar_seen = 1; ! 3329: goto letter; ! 3330: } ! 3331: value = '$'; ! 3332: goto done; ! 3333: ! 3334: case 'L': ! 3335: /* Capital L may start a wide-string or wide-character constant. */ ! 3336: { ! 3337: register int c = getch (); ! 3338: if (c == '\'') ! 3339: { ! 3340: wide_flag = 1; ! 3341: goto char_constant; ! 3342: } ! 3343: if (c == '"') ! 3344: { ! 3345: wide_flag = 1; ! 3346: goto string_constant; ! 3347: } ! 3348: put_back (c); ! 3349: } ! 3350: ! 3351: case 'A': case 'B': case 'C': case 'D': case 'E': ! 3352: case 'F': case 'G': case 'H': case 'I': case 'J': ! 3353: case 'K': case 'M': case 'N': case 'O': ! 3354: case 'P': case 'Q': case 'R': case 'S': case 'T': ! 3355: case 'U': case 'V': case 'W': case 'X': case 'Y': ! 3356: case 'Z': ! 3357: case 'a': case 'b': case 'c': case 'd': case 'e': ! 3358: case 'f': case 'g': case 'h': case 'i': case 'j': ! 3359: case 'k': case 'l': case 'm': case 'n': case 'o': ! 3360: case 'p': case 'q': case 'r': case 's': case 't': ! 3361: case 'u': case 'v': case 'w': case 'x': case 'y': ! 3362: case 'z': ! 3363: case '_': ! 3364: letter: ! 3365: { ! 3366: register char *p; ! 3367: ! 3368: p = token_buffer; ! 3369: if (input == 0) ! 3370: { ! 3371: /* We know that `token_buffer' can hold at least on char, ! 3372: so we install C immediately. ! 3373: We may have to read the value in `putback_char', so call ! 3374: `getch' once. */ ! 3375: *p++ = c; ! 3376: c = getch (); ! 3377: ! 3378: /* Make this run fast. We know that we are reading straight ! 3379: from FINPUT in this case (since identifiers cannot straddle ! 3380: input sources. */ ! 3381: while (isalnum (c) || (c == '_') || c == '$') ! 3382: { ! 3383: if (c == '$' && ! dollars_in_ident) ! 3384: break; ! 3385: if (p >= token_buffer + maxtoken) ! 3386: p = extend_token_buffer (p); ! 3387: ! 3388: *p++ = c; ! 3389: c = getc (finput); ! 3390: } ! 3391: } ! 3392: else ! 3393: { ! 3394: /* We know that `token_buffer' can hold at least on char, ! 3395: so we install C immediately. */ ! 3396: *p++ = c; ! 3397: c = getch (); ! 3398: ! 3399: while (isalnum (c) || (c == '_') || c == '$') ! 3400: { ! 3401: if (c == '$' && ! dollars_in_ident) ! 3402: break; ! 3403: if (p >= token_buffer + maxtoken) ! 3404: p = extend_token_buffer (p); ! 3405: ! 3406: *p++ = c; ! 3407: c = getch (); ! 3408: } ! 3409: } ! 3410: ! 3411: *p = 0; ! 3412: nextchar = c; ! 3413: ! 3414: value = IDENTIFIER; ! 3415: yylval.itype = 0; ! 3416: ! 3417: /* Try to recognize a keyword. Uses minimum-perfect hash function */ ! 3418: ! 3419: { ! 3420: register struct resword *ptr; ! 3421: ! 3422: if (ptr = is_reserved_word (token_buffer, p - token_buffer)) ! 3423: { ! 3424: if (ptr->rid) ! 3425: { ! 3426: tree old_ttype = ridpointers[(int) ptr->rid]; ! 3427: ! 3428: /* If this provides a type for us, then revert lexical ! 3429: state to standard state. */ ! 3430: if (TREE_CODE (old_ttype) == IDENTIFIER_NODE ! 3431: && IDENTIFIER_GLOBAL_VALUE (old_ttype) != 0 ! 3432: && TREE_CODE (IDENTIFIER_GLOBAL_VALUE (old_ttype)) == TYPE_DECL) ! 3433: looking_for_typename = 0; ! 3434: else if (ptr->token == AGGR || ptr->token == ENUM) ! 3435: looking_for_typename = 1; ! 3436: ! 3437: /* Check if this is a language-type declaration. ! 3438: Just glimpse the next non-white character. */ ! 3439: nextchar = skip_white_space (nextchar); ! 3440: if (nextchar == '"') ! 3441: { ! 3442: /* We are looking at a string. Complain ! 3443: if the token before the string is no `extern'. ! 3444: ! 3445: Could cheat some memory by placing this string ! 3446: on the temporary_, instead of the saveable_ ! 3447: obstack. */ ! 3448: ! 3449: if (ptr->rid != RID_EXTERN) ! 3450: error ("invalid modifier `%s' for language string", ! 3451: ptr->name); ! 3452: real_yylex (); ! 3453: value = EXTERN_LANG_STRING; ! 3454: yylval.ttype = get_identifier (TREE_STRING_POINTER (yylval.ttype)); ! 3455: break; ! 3456: } ! 3457: if (ptr->token == VISSPEC) ! 3458: { ! 3459: switch (ptr->rid) ! 3460: { ! 3461: case RID_PUBLIC: ! 3462: yylval.itype = access_public; ! 3463: break; ! 3464: case RID_PRIVATE: ! 3465: yylval.itype = access_private; ! 3466: break; ! 3467: case RID_PROTECTED: ! 3468: yylval.itype = access_protected; ! 3469: break; ! 3470: default: ! 3471: my_friendly_abort (63); ! 3472: } ! 3473: } ! 3474: else ! 3475: yylval.ttype = old_ttype; ! 3476: } ! 3477: value = (int) ptr->token; ! 3478: } ! 3479: } ! 3480: ! 3481: /* If we did not find a keyword, look for an identifier ! 3482: (or a typename). */ ! 3483: ! 3484: if (strcmp ("catch", token_buffer) == 0 ! 3485: || strcmp ("throw", token_buffer) == 0 ! 3486: || strcmp ("try", token_buffer) == 0) ! 3487: { ! 3488: static int did_warn = 0; ! 3489: if (! did_warn && ! flag_handle_exceptions) ! 3490: { ! 3491: pedwarn ("`catch', `throw', and `try' are all C++ reserved words"); ! 3492: did_warn = 1; ! 3493: } ! 3494: } ! 3495: ! 3496: if (value == IDENTIFIER || value == TYPESPEC) ! 3497: GNU_xref_ref (current_function_decl, token_buffer); ! 3498: ! 3499: if (value == IDENTIFIER) ! 3500: { ! 3501: register tree tmp = get_identifier (token_buffer); ! 3502: ! 3503: #if !defined(VMS) && defined(JOINER) ! 3504: /* Make sure that user does not collide with our internal ! 3505: naming scheme. */ ! 3506: if (JOINER == '$' ! 3507: && dollar_seen ! 3508: && (THIS_NAME_P (tmp) ! 3509: || VPTR_NAME_P (tmp) ! 3510: || DESTRUCTOR_NAME_P (tmp) ! 3511: || VTABLE_NAME_P (tmp) ! 3512: || TEMP_NAME_P (tmp) ! 3513: || ANON_AGGRNAME_P (tmp) ! 3514: || ANON_PARMNAME_P (tmp))) ! 3515: warning ("identifier name `%s' conflicts with GNU C++ internal naming strategy", ! 3516: token_buffer); ! 3517: #endif ! 3518: ! 3519: yylval.ttype = tmp; ! 3520: ! 3521: /* A user-invisible read-only initialized variable ! 3522: should be replaced by its value. We only handle strings ! 3523: since that's the only case used in C (and C++). */ ! 3524: /* Note we go right after the local value for the identifier ! 3525: (e.g., __FUNCTION__ or __PRETTY_FUNCTION__). We used to ! 3526: call lookup_name, but that could result in an error about ! 3527: ambiguities. */ ! 3528: tmp = IDENTIFIER_LOCAL_VALUE (yylval.ttype); ! 3529: if (tmp != NULL_TREE ! 3530: && TREE_CODE (tmp) == VAR_DECL ! 3531: && DECL_IGNORED_P (tmp) ! 3532: && TREE_READONLY (tmp) ! 3533: && DECL_INITIAL (tmp) != NULL_TREE ! 3534: && TREE_CODE (DECL_INITIAL (tmp)) == STRING_CST) ! 3535: { ! 3536: yylval.ttype = DECL_INITIAL (tmp); ! 3537: value = STRING; ! 3538: } ! 3539: } ! 3540: if (value == NEW && ! global_bindings_p ()) ! 3541: { ! 3542: value = NEW; ! 3543: goto done; ! 3544: } ! 3545: } ! 3546: break; ! 3547: ! 3548: case '.': ! 3549: { ! 3550: register int c1 = getch (); ! 3551: token_buffer[0] = c; ! 3552: token_buffer[1] = c1; ! 3553: if (c1 == '*') ! 3554: { ! 3555: value = DOT_STAR; ! 3556: token_buffer[2] = 0; ! 3557: goto done; ! 3558: } ! 3559: if (c1 == '.') ! 3560: { ! 3561: c1 = getch (); ! 3562: if (c1 == '.') ! 3563: { ! 3564: token_buffer[2] = c1; ! 3565: token_buffer[3] = 0; ! 3566: value = ELLIPSIS; ! 3567: goto done; ! 3568: } ! 3569: error ("parse error at `..'"); ! 3570: } ! 3571: if (isdigit (c1)) ! 3572: { ! 3573: put_back (c1); ! 3574: goto resume_numerical_scan; ! 3575: } ! 3576: nextchar = c1; ! 3577: value = '.'; ! 3578: token_buffer[1] = 0; ! 3579: goto done; ! 3580: } ! 3581: case '0': case '1': ! 3582: /* Optimize for most frequent case. */ ! 3583: { ! 3584: register int c1 = getch (); ! 3585: if (! isalnum (c1) && c1 != '.') ! 3586: { ! 3587: /* Terminate string. */ ! 3588: token_buffer[0] = c; ! 3589: token_buffer[1] = 0; ! 3590: if (c == '0') ! 3591: yylval.ttype = integer_zero_node; ! 3592: else ! 3593: yylval.ttype = integer_one_node; ! 3594: nextchar = c1; ! 3595: value = CONSTANT; ! 3596: goto done; ! 3597: } ! 3598: put_back (c1); ! 3599: } ! 3600: /* fall through... */ ! 3601: case '2': case '3': case '4': ! 3602: case '5': case '6': case '7': case '8': case '9': ! 3603: resume_numerical_scan: ! 3604: { ! 3605: register char *p; ! 3606: int base = 10; ! 3607: int count = 0; ! 3608: int largest_digit = 0; ! 3609: int numdigits = 0; ! 3610: /* for multi-precision arithmetic, ! 3611: we actually store only HOST_BITS_PER_CHAR bits in each part. ! 3612: The number of parts is chosen so as to be sufficient to hold ! 3613: the enough bits to fit into the two HOST_WIDE_INTs that contain ! 3614: the integer value (this is always at least as many bits as are ! 3615: in a target `long long' value, but may be wider). */ ! 3616: #define TOTAL_PARTS ((HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR) * 2 + 2) ! 3617: int parts[TOTAL_PARTS]; ! 3618: int overflow = 0; ! 3619: ! 3620: enum anon1 { NOT_FLOAT, AFTER_POINT, TOO_MANY_POINTS} floatflag ! 3621: = NOT_FLOAT; ! 3622: ! 3623: p = token_buffer; ! 3624: *p++ = c; ! 3625: ! 3626: for (count = 0; count < TOTAL_PARTS; count++) ! 3627: parts[count] = 0; ! 3628: ! 3629: if (c == '0') ! 3630: { ! 3631: *p++ = (c = getch ()); ! 3632: if ((c == 'x') || (c == 'X')) ! 3633: { ! 3634: base = 16; ! 3635: *p++ = (c = getch ()); ! 3636: } ! 3637: /* Leading 0 forces octal unless the 0 is the only digit. */ ! 3638: else if (c >= '0' && c <= '9') ! 3639: { ! 3640: base = 8; ! 3641: numdigits++; ! 3642: } ! 3643: else ! 3644: numdigits++; ! 3645: } ! 3646: ! 3647: /* Read all the digits-and-decimal-points. */ ! 3648: ! 3649: while (c == '.' ! 3650: || (isalnum (c) && (c != 'l') && (c != 'L') ! 3651: && (c != 'u') && (c != 'U') ! 3652: && (floatflag == NOT_FLOAT || ((c != 'f') && (c != 'F'))))) ! 3653: { ! 3654: if (c == '.') ! 3655: { ! 3656: if (base == 16) ! 3657: error ("floating constant may not be in radix 16"); ! 3658: if (floatflag == AFTER_POINT) ! 3659: { ! 3660: error ("malformed floating constant"); ! 3661: floatflag = TOO_MANY_POINTS; ! 3662: } ! 3663: else ! 3664: floatflag = AFTER_POINT; ! 3665: ! 3666: base = 10; ! 3667: *p++ = c = getch (); ! 3668: /* Accept '.' as the start of a floating-point number ! 3669: only when it is followed by a digit. ! 3670: Otherwise, unread the following non-digit ! 3671: and use the '.' as a structural token. */ ! 3672: if (p == token_buffer + 2 && !isdigit (c)) ! 3673: { ! 3674: if (c == '.') ! 3675: { ! 3676: c = getch (); ! 3677: if (c == '.') ! 3678: { ! 3679: *p++ = '.'; ! 3680: *p = '\0'; ! 3681: value = ELLIPSIS; ! 3682: goto done; ! 3683: } ! 3684: error ("parse error at `..'"); ! 3685: } ! 3686: nextchar = c; ! 3687: token_buffer[1] = '\0'; ! 3688: value = '.'; ! 3689: goto done; ! 3690: } ! 3691: } ! 3692: else ! 3693: { ! 3694: /* It is not a decimal point. ! 3695: It should be a digit (perhaps a hex digit). */ ! 3696: ! 3697: if (isdigit (c)) ! 3698: { ! 3699: c = c - '0'; ! 3700: } ! 3701: else if (base <= 10) ! 3702: { ! 3703: if (c == 'e' || c == 'E') ! 3704: { ! 3705: base = 10; ! 3706: floatflag = AFTER_POINT; ! 3707: break; /* start of exponent */ ! 3708: } ! 3709: error ("nondigits in number and not hexadecimal"); ! 3710: c = 0; ! 3711: } ! 3712: else if (c >= 'a') ! 3713: { ! 3714: c = c - 'a' + 10; ! 3715: } ! 3716: else ! 3717: { ! 3718: c = c - 'A' + 10; ! 3719: } ! 3720: if (c >= largest_digit) ! 3721: largest_digit = c; ! 3722: numdigits++; ! 3723: ! 3724: for (count = 0; count < TOTAL_PARTS; count++) ! 3725: { ! 3726: parts[count] *= base; ! 3727: if (count) ! 3728: { ! 3729: parts[count] ! 3730: += (parts[count-1] >> HOST_BITS_PER_CHAR); ! 3731: parts[count-1] ! 3732: &= (1 << HOST_BITS_PER_CHAR) - 1; ! 3733: } ! 3734: else ! 3735: parts[0] += c; ! 3736: } ! 3737: ! 3738: /* If the extra highest-order part ever gets anything in it, ! 3739: the number is certainly too big. */ ! 3740: if (parts[TOTAL_PARTS - 1] != 0) ! 3741: overflow = 1; ! 3742: ! 3743: if (p >= token_buffer + maxtoken - 3) ! 3744: p = extend_token_buffer (p); ! 3745: *p++ = (c = getch ()); ! 3746: } ! 3747: } ! 3748: ! 3749: if (numdigits == 0) ! 3750: error ("numeric constant with no digits"); ! 3751: ! 3752: if (largest_digit >= base) ! 3753: error ("numeric constant contains digits beyond the radix"); ! 3754: ! 3755: /* Remove terminating char from the token buffer and delimit the string */ ! 3756: *--p = 0; ! 3757: ! 3758: if (floatflag != NOT_FLOAT) ! 3759: { ! 3760: tree type = double_type_node; ! 3761: char f_seen = 0; ! 3762: char l_seen = 0; ! 3763: int garbage_chars = 0; ! 3764: REAL_VALUE_TYPE value; ! 3765: jmp_buf handler; ! 3766: ! 3767: /* Read explicit exponent if any, and put it in tokenbuf. */ ! 3768: ! 3769: if ((c == 'e') || (c == 'E')) ! 3770: { ! 3771: if (p >= token_buffer + maxtoken - 3) ! 3772: p = extend_token_buffer (p); ! 3773: *p++ = c; ! 3774: c = getch (); ! 3775: if ((c == '+') || (c == '-')) ! 3776: { ! 3777: *p++ = c; ! 3778: c = getch (); ! 3779: } ! 3780: if (! isdigit (c)) ! 3781: error ("floating constant exponent has no digits"); ! 3782: while (isdigit (c)) ! 3783: { ! 3784: if (p >= token_buffer + maxtoken - 3) ! 3785: p = extend_token_buffer (p); ! 3786: *p++ = c; ! 3787: c = getch (); ! 3788: } ! 3789: } ! 3790: ! 3791: *p = 0; ! 3792: errno = 0; ! 3793: ! 3794: /* Convert string to a double, checking for overflow. */ ! 3795: if (setjmp (handler)) ! 3796: { ! 3797: error ("floating constant out of range"); ! 3798: value = dconst0; ! 3799: } ! 3800: else ! 3801: { ! 3802: set_float_handler (handler); ! 3803: /* The second argument, machine_mode, of REAL_VALUE_ATOF ! 3804: tells the desired precision of the binary result of ! 3805: decimal-to-binary conversion. */ ! 3806: ! 3807: /* Read the suffixes to choose a data type. */ ! 3808: switch (c) ! 3809: { ! 3810: case 'f': case 'F': ! 3811: type = float_type_node; ! 3812: value = REAL_VALUE_ATOF (token_buffer, TYPE_MODE (type)); ! 3813: garbage_chars = -1; ! 3814: break; ! 3815: ! 3816: case 'l': case 'L': ! 3817: type = long_double_type_node; ! 3818: value = REAL_VALUE_ATOF (token_buffer, TYPE_MODE (type)); ! 3819: garbage_chars = -1; ! 3820: break; ! 3821: ! 3822: default: ! 3823: value = REAL_VALUE_ATOF (token_buffer, TYPE_MODE (type)); ! 3824: } ! 3825: set_float_handler (NULL_PTR); ! 3826: } ! 3827: if (pedantic ! 3828: && (REAL_VALUE_ISINF (value) ! 3829: #ifdef ERANGE ! 3830: || (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT ! 3831: && errno == ERANGE ! 3832: /* ERANGE is also reported for underflow, so test the ! 3833: value to distinguish overflow from that. */ ! 3834: && (REAL_VALUES_LESS (dconst1, value) ! 3835: || REAL_VALUES_LESS (value, dconstm1))) ! 3836: #endif ! 3837: )) ! 3838: { ! 3839: pedwarn ("floating point number exceeds range of `%s'", ! 3840: IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)))); ! 3841: } ! 3842: /* Note: garbage_chars is -1 if first char is *not* garbage. */ ! 3843: while (isalnum (c)) ! 3844: { ! 3845: if (c == 'f' || c == 'F') ! 3846: { ! 3847: if (f_seen) ! 3848: error ("two `f's in floating constant"); ! 3849: f_seen = 1; ! 3850: } ! 3851: if (c == 'l' || c == 'L') ! 3852: { ! 3853: if (l_seen) ! 3854: error ("two `l's in floating constant"); ! 3855: l_seen = 1; ! 3856: } ! 3857: if (p >= token_buffer + maxtoken - 3) ! 3858: p = extend_token_buffer (p); ! 3859: *p++ = c; ! 3860: c = getch (); ! 3861: garbage_chars++; ! 3862: } ! 3863: ! 3864: if (garbage_chars > 0) ! 3865: error ("garbage at end of number"); ! 3866: ! 3867: /* Create a node with determined type and value. */ ! 3868: yylval.ttype = build_real (type, value); ! 3869: ! 3870: put_back (c); ! 3871: *p = 0; ! 3872: } ! 3873: else ! 3874: { ! 3875: tree type; ! 3876: HOST_WIDE_INT high, low; ! 3877: int spec_unsigned = 0; ! 3878: int spec_long = 0; ! 3879: int spec_long_long = 0; ! 3880: int bytes, warn; ! 3881: ! 3882: while (1) ! 3883: { ! 3884: if (c == 'u' || c == 'U') ! 3885: { ! 3886: if (spec_unsigned) ! 3887: error ("two `u's in integer constant"); ! 3888: spec_unsigned = 1; ! 3889: } ! 3890: else if (c == 'l' || c == 'L') ! 3891: { ! 3892: if (spec_long) ! 3893: { ! 3894: if (spec_long_long) ! 3895: error ("three `l's in integer constant"); ! 3896: else if (pedantic) ! 3897: pedwarn ("ANSI C++ forbids long long integer constants"); ! 3898: spec_long_long = 1; ! 3899: } ! 3900: spec_long = 1; ! 3901: } ! 3902: else ! 3903: { ! 3904: if (isalnum (c)) ! 3905: { ! 3906: error ("garbage at end of number"); ! 3907: while (isalnum (c)) ! 3908: { ! 3909: if (p >= token_buffer + maxtoken - 3) ! 3910: p = extend_token_buffer (p); ! 3911: *p++ = c; ! 3912: c = getch (); ! 3913: } ! 3914: } ! 3915: break; ! 3916: } ! 3917: if (p >= token_buffer + maxtoken - 3) ! 3918: p = extend_token_buffer (p); ! 3919: *p++ = c; ! 3920: c = getch (); ! 3921: } ! 3922: ! 3923: put_back (c); ! 3924: ! 3925: /* If the constant is not long long and it won't fit in an ! 3926: unsigned long, or if the constant is long long and won't fit ! 3927: in an unsigned long long, then warn that the constant is out ! 3928: of range. */ ! 3929: ! 3930: /* ??? This assumes that long long and long integer types are ! 3931: a multiple of 8 bits. This better than the original code ! 3932: though which assumed that long was exactly 32 bits and long ! 3933: long was exactly 64 bits. */ ! 3934: ! 3935: if (spec_long_long) ! 3936: bytes = TYPE_PRECISION (long_long_integer_type_node) / 8; ! 3937: else ! 3938: bytes = TYPE_PRECISION (long_integer_type_node) / 8; ! 3939: ! 3940: warn = overflow; ! 3941: for (i = bytes; i < TOTAL_PARTS; i++) ! 3942: if (parts[i]) ! 3943: warn = 1; ! 3944: if (warn) ! 3945: pedwarn ("integer constant out of range"); ! 3946: ! 3947: /* This is simplified by the fact that our constant ! 3948: is always positive. */ ! 3949: high = low = 0; ! 3950: ! 3951: for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR; i++) ! 3952: { ! 3953: high |= ((HOST_WIDE_INT) parts[i + (HOST_BITS_PER_WIDE_INT ! 3954: / HOST_BITS_PER_CHAR)] ! 3955: << (i * HOST_BITS_PER_CHAR)); ! 3956: low |= (HOST_WIDE_INT) parts[i] << (i * HOST_BITS_PER_CHAR); ! 3957: } ! 3958: ! 3959: ! 3960: yylval.ttype = build_int_2 (low, high); ! 3961: TREE_TYPE (yylval.ttype) = long_long_unsigned_type_node; ! 3962: ! 3963: #if 0 ! 3964: /* Find the first allowable type that the value fits in. */ ! 3965: type = 0; ! 3966: for (i = 0; i < sizeof (type_sequence) / sizeof (type_sequence[0]); ! 3967: i++) ! 3968: if (!(spec_long && !type_sequence[i].long_flag) ! 3969: && !(spec_long_long && !type_sequence[i].long_long_flag) ! 3970: && !(spec_unsigned && !type_sequence[i].unsigned_flag) ! 3971: /* A hex or octal constant traditionally is unsigned. */ ! 3972: && !(base != 10 && flag_traditional ! 3973: && !type_sequence[i].unsigned_flag) ! 3974: /* A decimal constant can't be unsigned int ! 3975: unless explicitly specified. */ ! 3976: && !(base == 10 && !spec_unsigned ! 3977: && *type_sequence[i].node_var == unsigned_type_node)) ! 3978: if (int_fits_type_p (yylval.ttype, *type_sequence[i].node_var)) ! 3979: { ! 3980: type = *type_sequence[i].node_var; ! 3981: break; ! 3982: } ! 3983: if (flag_traditional && type == long_unsigned_type_node ! 3984: && !spec_unsigned) ! 3985: type = long_integer_type_node; ! 3986: ! 3987: if (type == 0) ! 3988: { ! 3989: type = long_long_integer_type_node; ! 3990: warning ("integer constant out of range"); ! 3991: } ! 3992: ! 3993: /* Warn about some cases where the type of a given constant ! 3994: changes from traditional C to ANSI C. */ ! 3995: if (warn_traditional) ! 3996: { ! 3997: tree other_type = 0; ! 3998: ! 3999: /* This computation is the same as the previous one ! 4000: except that flag_traditional is used backwards. */ ! 4001: for (i = 0; i < sizeof (type_sequence) / sizeof (type_sequence[0]); ! 4002: i++) ! 4003: if (!(spec_long && !type_sequence[i].long_flag) ! 4004: && !(spec_long_long && !type_sequence[i].long_long_flag) ! 4005: && !(spec_unsigned && !type_sequence[i].unsigned_flag) ! 4006: /* A hex or octal constant traditionally is unsigned. */ ! 4007: && !(base != 10 && !flag_traditional ! 4008: && !type_sequence[i].unsigned_flag) ! 4009: /* A decimal constant can't be unsigned int ! 4010: unless explicitly specified. */ ! 4011: && !(base == 10 && !spec_unsigned ! 4012: && *type_sequence[i].node_var == unsigned_type_node)) ! 4013: if (int_fits_type_p (yylval.ttype, *type_sequence[i].node_var)) ! 4014: { ! 4015: other_type = *type_sequence[i].node_var; ! 4016: break; ! 4017: } ! 4018: if (!flag_traditional && type == long_unsigned_type_node ! 4019: && !spec_unsigned) ! 4020: type = long_integer_type_node; ! 4021: ! 4022: if (other_type != 0 && other_type != type) ! 4023: { ! 4024: if (flag_traditional) ! 4025: warning ("type of integer constant would be different without -traditional"); ! 4026: else ! 4027: warning ("type of integer constant would be different with -traditional"); ! 4028: } ! 4029: } ! 4030: ! 4031: #else /* 1 */ ! 4032: if (!spec_long && !spec_unsigned ! 4033: && !(flag_traditional && base != 10) ! 4034: && int_fits_type_p (yylval.ttype, integer_type_node)) ! 4035: { ! 4036: #if 0 ! 4037: if (warn_traditional && base != 10) ! 4038: warning ("small nondecimal constant becomes signed in ANSI C++"); ! 4039: #endif ! 4040: type = integer_type_node; ! 4041: } ! 4042: else if (!spec_long && (base != 10 || spec_unsigned) ! 4043: && int_fits_type_p (yylval.ttype, unsigned_type_node)) ! 4044: { ! 4045: /* Nondecimal constants try unsigned even in traditional C. */ ! 4046: type = unsigned_type_node; ! 4047: } ! 4048: ! 4049: else if (!spec_unsigned && !spec_long_long ! 4050: && int_fits_type_p (yylval.ttype, long_integer_type_node)) ! 4051: type = long_integer_type_node; ! 4052: ! 4053: else if (! spec_long_long ! 4054: && int_fits_type_p (yylval.ttype, ! 4055: long_unsigned_type_node)) ! 4056: { ! 4057: #if 0 ! 4058: if (warn_traditional && !spec_unsigned) ! 4059: warning ("large integer constant becomes unsigned in ANSI C++"); ! 4060: #endif ! 4061: if (flag_traditional && !spec_unsigned) ! 4062: type = long_integer_type_node; ! 4063: else ! 4064: type = long_unsigned_type_node; ! 4065: } ! 4066: ! 4067: else if (! spec_unsigned ! 4068: /* Verify value does not overflow into sign bit. */ ! 4069: && TREE_INT_CST_HIGH (yylval.ttype) >= 0 ! 4070: && int_fits_type_p (yylval.ttype, ! 4071: long_long_integer_type_node)) ! 4072: type = long_long_integer_type_node; ! 4073: ! 4074: else if (int_fits_type_p (yylval.ttype, ! 4075: long_long_unsigned_type_node)) ! 4076: { ! 4077: #if 0 ! 4078: if (warn_traditional && !spec_unsigned) ! 4079: warning ("large nondecimal constant is unsigned in ANSI C++"); ! 4080: #endif ! 4081: ! 4082: if (flag_traditional && !spec_unsigned) ! 4083: type = long_long_integer_type_node; ! 4084: else ! 4085: type = long_long_unsigned_type_node; ! 4086: } ! 4087: ! 4088: else ! 4089: { ! 4090: type = long_long_integer_type_node; ! 4091: warning ("integer constant out of range"); ! 4092: ! 4093: if (base == 10 && ! spec_unsigned && TREE_UNSIGNED (type)) ! 4094: warning ("decimal integer constant is so large that it is unsigned"); ! 4095: } ! 4096: #endif ! 4097: ! 4098: TREE_TYPE (yylval.ttype) = type; ! 4099: *p = 0; ! 4100: } ! 4101: ! 4102: value = CONSTANT; break; ! 4103: } ! 4104: ! 4105: case '\'': ! 4106: char_constant: ! 4107: { ! 4108: register int result = 0; ! 4109: register int num_chars = 0; ! 4110: unsigned width = TYPE_PRECISION (char_type_node); ! 4111: int max_chars; ! 4112: ! 4113: if (wide_flag) ! 4114: { ! 4115: width = WCHAR_TYPE_SIZE; ! 4116: #ifdef MULTIBYTE_CHARS ! 4117: max_chars = MB_CUR_MAX; ! 4118: #else ! 4119: max_chars = 1; ! 4120: #endif ! 4121: } ! 4122: else ! 4123: max_chars = TYPE_PRECISION (integer_type_node) / width; ! 4124: ! 4125: while (1) ! 4126: { ! 4127: tryagain: ! 4128: ! 4129: c = getch (); ! 4130: ! 4131: if (c == '\'' || c == EOF) ! 4132: break; ! 4133: ! 4134: if (c == '\\') ! 4135: { ! 4136: int ignore = 0; ! 4137: c = readescape (&ignore); ! 4138: if (ignore) ! 4139: goto tryagain; ! 4140: if (width < HOST_BITS_PER_INT ! 4141: && (unsigned) c >= (1 << width)) ! 4142: pedwarn ("escape sequence out of range for character"); ! 4143: #ifdef MAP_CHARACTER ! 4144: if (isprint (c)) ! 4145: c = MAP_CHARACTER (c); ! 4146: #endif ! 4147: } ! 4148: else if (c == '\n') ! 4149: { ! 4150: if (pedantic) ! 4151: pedwarn ("ANSI C++ forbids newline in character constant"); ! 4152: lineno++; ! 4153: } ! 4154: #ifdef MAP_CHARACTER ! 4155: else ! 4156: c = MAP_CHARACTER (c); ! 4157: #endif ! 4158: ! 4159: num_chars++; ! 4160: if (num_chars > maxtoken - 4) ! 4161: extend_token_buffer (token_buffer); ! 4162: ! 4163: token_buffer[num_chars] = c; ! 4164: ! 4165: /* Merge character into result; ignore excess chars. */ ! 4166: if (num_chars < max_chars + 1) ! 4167: { ! 4168: if (width < HOST_BITS_PER_INT) ! 4169: result = (result << width) | (c & ((1 << width) - 1)); ! 4170: else ! 4171: result = c; ! 4172: } ! 4173: } ! 4174: ! 4175: token_buffer[num_chars + 1] = '\''; ! 4176: token_buffer[num_chars + 2] = 0; ! 4177: ! 4178: if (c != '\'') ! 4179: error ("malformatted character constant"); ! 4180: else if (num_chars == 0) ! 4181: error ("empty character constant"); ! 4182: else if (num_chars > max_chars) ! 4183: { ! 4184: num_chars = max_chars; ! 4185: error ("character constant too long"); ! 4186: } ! 4187: else if (num_chars != 1 && ! flag_traditional) ! 4188: warning ("multi-character character constant"); ! 4189: ! 4190: /* If char type is signed, sign-extend the constant. */ ! 4191: if (! wide_flag) ! 4192: { ! 4193: int num_bits = num_chars * width; ! 4194: if (num_bits == 0) ! 4195: /* We already got an error; avoid invalid shift. */ ! 4196: yylval.ttype = build_int_2 (0, 0); ! 4197: else if (TREE_UNSIGNED (char_type_node) ! 4198: || ((result >> (num_bits - 1)) & 1) == 0) ! 4199: yylval.ttype ! 4200: = build_int_2 (result & ((unsigned HOST_WIDE_INT) ~0 ! 4201: >> (HOST_BITS_PER_WIDE_INT - num_bits)), ! 4202: 0); ! 4203: else ! 4204: yylval.ttype ! 4205: = build_int_2 (result | ~((unsigned HOST_WIDE_INT) ~0 ! 4206: >> (HOST_BITS_PER_WIDE_INT - num_bits)), ! 4207: -1); ! 4208: if (num_chars<=1) ! 4209: TREE_TYPE (yylval.ttype) = char_type_node; ! 4210: else ! 4211: TREE_TYPE (yylval.ttype) = integer_type_node; ! 4212: } ! 4213: else ! 4214: { ! 4215: #ifdef MULTIBYTE_CHARS ! 4216: /* Set the initial shift state and convert the next sequence. */ ! 4217: result = 0; ! 4218: /* In all locales L'\0' is zero and mbtowc will return zero, ! 4219: so don't use it. */ ! 4220: if (num_chars > 1 ! 4221: || (num_chars == 1 && token_buffer[1] != '\0')) ! 4222: { ! 4223: wchar_t wc; ! 4224: (void) mbtowc (NULL, NULL, 0); ! 4225: if (mbtowc (& wc, token_buffer + 1, num_chars) == num_chars) ! 4226: result = wc; ! 4227: else ! 4228: warning ("Ignoring invalid multibyte character"); ! 4229: } ! 4230: #endif ! 4231: yylval.ttype = build_int_2 (result, 0); ! 4232: TREE_TYPE (yylval.ttype) = wchar_type_node; ! 4233: } ! 4234: ! 4235: value = CONSTANT; ! 4236: break; ! 4237: } ! 4238: ! 4239: case '"': ! 4240: string_constant: ! 4241: { ! 4242: register char *p; ! 4243: ! 4244: c = getch (); ! 4245: p = token_buffer + 1; ! 4246: ! 4247: while (c != '"' && c >= 0) ! 4248: { ! 4249: /* ignore_escape_flag is set for reading the filename in #line. */ ! 4250: if (!ignore_escape_flag && c == '\\') ! 4251: { ! 4252: int ignore = 0; ! 4253: c = readescape (&ignore); ! 4254: if (ignore) ! 4255: goto skipnewline; ! 4256: if (!wide_flag ! 4257: && TYPE_PRECISION (char_type_node) < HOST_BITS_PER_INT ! 4258: && c >= ((unsigned) 1 << TYPE_PRECISION (char_type_node))) ! 4259: pedwarn ("escape sequence out of range for character"); ! 4260: } ! 4261: else if (c == '\n') ! 4262: { ! 4263: if (pedantic) ! 4264: pedwarn ("ANSI C++ forbids newline in string constant"); ! 4265: lineno++; ! 4266: } ! 4267: ! 4268: if (p == token_buffer + maxtoken) ! 4269: p = extend_token_buffer (p); ! 4270: *p++ = c; ! 4271: ! 4272: skipnewline: ! 4273: c = getch (); ! 4274: if (c == EOF) { ! 4275: error("Unterminated string"); ! 4276: break; ! 4277: } ! 4278: } ! 4279: *p = 0; ! 4280: ! 4281: /* We have read the entire constant. ! 4282: Construct a STRING_CST for the result. */ ! 4283: ! 4284: if (wide_flag) ! 4285: { ! 4286: /* If this is a L"..." wide-string, convert the multibyte string ! 4287: to a wide character string. */ ! 4288: char *widep = (char *) alloca ((p - token_buffer) * WCHAR_BYTES); ! 4289: int len; ! 4290: ! 4291: #ifdef MULTIBYTE_CHARS ! 4292: len = mbstowcs ((wchar_t *) widep, token_buffer + 1, p - token_buffer); ! 4293: if (len < 0 || len >= (p - token_buffer)) ! 4294: { ! 4295: warning ("Ignoring invalid multibyte string"); ! 4296: len = 0; ! 4297: } ! 4298: bzero (widep + (len * WCHAR_BYTES), WCHAR_BYTES); ! 4299: #else ! 4300: { ! 4301: union { long l; char c[sizeof (long)]; } u; ! 4302: int big_endian; ! 4303: char *wp, *cp; ! 4304: ! 4305: /* Determine whether host is little or big endian. */ ! 4306: u.l = 1; ! 4307: big_endian = u.c[sizeof (long) - 1]; ! 4308: wp = widep + (big_endian ? WCHAR_BYTES - 1 : 0); ! 4309: ! 4310: bzero (widep, (p - token_buffer) * WCHAR_BYTES); ! 4311: for (cp = token_buffer + 1; cp < p; cp++) ! 4312: *wp = *cp, wp += WCHAR_BYTES; ! 4313: len = p - token_buffer - 1; ! 4314: } ! 4315: #endif ! 4316: yylval.ttype = build_string ((len + 1) * WCHAR_BYTES, widep); ! 4317: TREE_TYPE (yylval.ttype) = wchar_array_type_node; ! 4318: } ! 4319: else ! 4320: { ! 4321: yylval.ttype = build_string (p - token_buffer, token_buffer + 1); ! 4322: TREE_TYPE (yylval.ttype) = char_array_type_node; ! 4323: } ! 4324: ! 4325: *p++ = '"'; ! 4326: *p = 0; ! 4327: ! 4328: value = STRING; break; ! 4329: } ! 4330: ! 4331: case '+': ! 4332: case '-': ! 4333: case '&': ! 4334: case '|': ! 4335: case '<': ! 4336: case '>': ! 4337: case '*': ! 4338: case '/': ! 4339: case '%': ! 4340: case '^': ! 4341: case '!': ! 4342: case '=': ! 4343: { ! 4344: register int c1; ! 4345: ! 4346: combine: ! 4347: ! 4348: switch (c) ! 4349: { ! 4350: case '+': ! 4351: yylval.code = PLUS_EXPR; break; ! 4352: case '-': ! 4353: yylval.code = MINUS_EXPR; break; ! 4354: case '&': ! 4355: yylval.code = BIT_AND_EXPR; break; ! 4356: case '|': ! 4357: yylval.code = BIT_IOR_EXPR; break; ! 4358: case '*': ! 4359: yylval.code = MULT_EXPR; break; ! 4360: case '/': ! 4361: yylval.code = TRUNC_DIV_EXPR; break; ! 4362: case '%': ! 4363: yylval.code = TRUNC_MOD_EXPR; break; ! 4364: case '^': ! 4365: yylval.code = BIT_XOR_EXPR; break; ! 4366: case LSHIFT: ! 4367: yylval.code = LSHIFT_EXPR; break; ! 4368: case RSHIFT: ! 4369: yylval.code = RSHIFT_EXPR; break; ! 4370: case '<': ! 4371: yylval.code = LT_EXPR; break; ! 4372: case '>': ! 4373: yylval.code = GT_EXPR; break; ! 4374: } ! 4375: ! 4376: token_buffer[1] = c1 = getch (); ! 4377: token_buffer[2] = 0; ! 4378: ! 4379: if (c1 == '=') ! 4380: { ! 4381: switch (c) ! 4382: { ! 4383: case '<': ! 4384: value = ARITHCOMPARE; yylval.code = LE_EXPR; goto done; ! 4385: case '>': ! 4386: value = ARITHCOMPARE; yylval.code = GE_EXPR; goto done; ! 4387: case '!': ! 4388: value = EQCOMPARE; yylval.code = NE_EXPR; goto done; ! 4389: case '=': ! 4390: value = EQCOMPARE; yylval.code = EQ_EXPR; goto done; ! 4391: } ! 4392: value = ASSIGN; goto done; ! 4393: } ! 4394: else if (c == c1) ! 4395: switch (c) ! 4396: { ! 4397: case '+': ! 4398: value = PLUSPLUS; goto done; ! 4399: case '-': ! 4400: value = MINUSMINUS; goto done; ! 4401: case '&': ! 4402: value = ANDAND; goto done; ! 4403: case '|': ! 4404: value = OROR; goto done; ! 4405: case '<': ! 4406: c = LSHIFT; ! 4407: goto combine; ! 4408: case '>': ! 4409: c = RSHIFT; ! 4410: goto combine; ! 4411: } ! 4412: else if ((c == '-') && (c1 == '>')) ! 4413: { ! 4414: nextchar = skip_white_space (getch ()); ! 4415: if (nextchar == '*') ! 4416: { ! 4417: nextchar = -1; ! 4418: value = POINTSAT_STAR; ! 4419: } ! 4420: else ! 4421: value = POINTSAT; ! 4422: goto done; ! 4423: } ! 4424: else if (c1 == '?' && (c == '<' || c == '>')) ! 4425: { ! 4426: token_buffer[3] = 0; ! 4427: ! 4428: c1 = getch (); ! 4429: yylval.code = (c == '<' ? MIN_EXPR : MAX_EXPR); ! 4430: if (c1 == '=') ! 4431: { ! 4432: /* <?= or >?= expression. */ ! 4433: token_buffer[2] = c1; ! 4434: value = ASSIGN; ! 4435: } ! 4436: else ! 4437: { ! 4438: value = MIN_MAX; ! 4439: nextchar = c1; ! 4440: } ! 4441: if (flag_ansi) ! 4442: pedwarn ("use of `operator %s' is not standard C++", ! 4443: token_buffer); ! 4444: goto done; ! 4445: } ! 4446: ! 4447: nextchar = c1; ! 4448: token_buffer[1] = 0; ! 4449: ! 4450: value = c; ! 4451: goto done; ! 4452: } ! 4453: ! 4454: case ':': ! 4455: c = getch (); ! 4456: if (c == ':') ! 4457: { ! 4458: token_buffer[1] = ':'; ! 4459: token_buffer[2] = '\0'; ! 4460: value = SCOPE; ! 4461: yylval.itype = 1; ! 4462: } ! 4463: else ! 4464: { ! 4465: nextchar = c; ! 4466: value = ':'; ! 4467: } ! 4468: break; ! 4469: ! 4470: case 0: ! 4471: /* Don't make yyparse think this is eof. */ ! 4472: value = 1; ! 4473: break; ! 4474: ! 4475: case '(': ! 4476: /* try, weakly, to handle casts to pointers to functions. */ ! 4477: nextchar = skip_white_space (getch ()); ! 4478: if (nextchar == '*') ! 4479: { ! 4480: int next_c = skip_white_space (getch ()); ! 4481: if (next_c == ')') ! 4482: { ! 4483: nextchar = -1; ! 4484: yylval.ttype = build1 (INDIRECT_REF, 0, 0); ! 4485: value = PAREN_STAR_PAREN; ! 4486: } ! 4487: else ! 4488: { ! 4489: put_back (next_c); ! 4490: value = c; ! 4491: } ! 4492: } ! 4493: else if (nextchar == ')') ! 4494: { ! 4495: nextchar = -1; ! 4496: yylval.ttype = NULL_TREE; ! 4497: value = LEFT_RIGHT; ! 4498: } ! 4499: else value = c; ! 4500: break; ! 4501: ! 4502: default: ! 4503: value = c; ! 4504: } ! 4505: ! 4506: done: ! 4507: /* yylloc.last_line = lineno; */ ! 4508: #ifdef GATHER_STATISTICS ! 4509: token_count[value] += 1; ! 4510: #endif ! 4511: ! 4512: return value; ! 4513: } ! 4514: ! 4515: typedef enum ! 4516: { ! 4517: d_kind, t_kind, s_kind, r_kind, e_kind, c_kind, ! 4518: id_kind, op_id_kind, perm_list_kind, temp_list_kind, ! 4519: vec_kind, x_kind, lang_decl, lang_type, all_kinds ! 4520: } tree_node_kind; ! 4521: extern int tree_node_counts[]; ! 4522: extern int tree_node_sizes[]; ! 4523: extern char *tree_node_kind_names[]; ! 4524: ! 4525: /* Place to save freed lang_decls which were allocated on the ! 4526: permanent_obstack. @@ Not currently used. */ ! 4527: tree free_lang_decl_chain; ! 4528: ! 4529: tree ! 4530: build_lang_decl (code, name, type) ! 4531: enum tree_code code; ! 4532: tree name; ! 4533: tree type; ! 4534: { ! 4535: register tree t = build_decl (code, name, type); ! 4536: struct obstack *obstack = current_obstack; ! 4537: register int i = sizeof (struct lang_decl) / sizeof (int); ! 4538: register int *pi; ! 4539: ! 4540: if (! TREE_PERMANENT (t)) ! 4541: obstack = saveable_obstack; ! 4542: else ! 4543: /* Could be that saveable is permanent and current is not. */ ! 4544: obstack = &permanent_obstack; ! 4545: ! 4546: if (free_lang_decl_chain && obstack == &permanent_obstack) ! 4547: { ! 4548: pi = (int *)free_lang_decl_chain; ! 4549: free_lang_decl_chain = TREE_CHAIN (free_lang_decl_chain); ! 4550: } ! 4551: else ! 4552: pi = (int *) obstack_alloc (obstack, sizeof (struct lang_decl)); ! 4553: ! 4554: while (i > 0) ! 4555: pi[--i] = 0; ! 4556: ! 4557: DECL_LANG_SPECIFIC (t) = (struct lang_decl *) pi; ! 4558: LANG_DECL_PERMANENT ((struct lang_decl *) pi) ! 4559: = obstack == &permanent_obstack; ! 4560: my_friendly_assert (LANG_DECL_PERMANENT ((struct lang_decl *) pi) ! 4561: == TREE_PERMANENT (t), 234); ! 4562: DECL_MAIN_VARIANT (t) = t; ! 4563: if (current_lang_name == lang_name_cplusplus) ! 4564: { ! 4565: DECL_LANGUAGE (t) = lang_cplusplus; ! 4566: #if 0 ! 4567: #ifndef NO_AUTO_OVERLOAD ! 4568: if (code == FUNCTION_DECL && name != 0 ! 4569: && ! (IDENTIFIER_LENGTH (name) == 4 ! 4570: && IDENTIFIER_POINTER (name)[0] == 'm' ! 4571: && strcmp (IDENTIFIER_POINTER (name), "main") == 0) ! 4572: && ! (IDENTIFIER_LENGTH (name) > 10 ! 4573: && IDENTIFIER_POINTER (name)[0] == '_' ! 4574: && IDENTIFIER_POINTER (name)[1] == '_' ! 4575: && strncmp (IDENTIFIER_POINTER (name)+2, "builtin_", 8) == 0)) ! 4576: TREE_OVERLOADED (name) = 1; ! 4577: #endif ! 4578: #endif ! 4579: } ! 4580: else if (current_lang_name == lang_name_c) ! 4581: DECL_LANGUAGE (t) = lang_c; ! 4582: else my_friendly_abort (64); ! 4583: ! 4584: #if 0 /* not yet, should get fixed properly later */ ! 4585: if (code == TYPE_DECL) ! 4586: { ! 4587: tree id; ! 4588: id = get_identifier (build_overload_name (type, 1, 1)); ! 4589: DECL_ASSEMBLER_NAME (t) = id; ! 4590: } ! 4591: ! 4592: #endif ! 4593: #ifdef GATHER_STATISTICS ! 4594: tree_node_counts[(int)lang_decl] += 1; ! 4595: tree_node_sizes[(int)lang_decl] += sizeof(struct lang_decl); ! 4596: #endif ! 4597: ! 4598: return t; ! 4599: } ! 4600: ! 4601: tree ! 4602: build_lang_field_decl (code, name, type) ! 4603: enum tree_code code; ! 4604: tree name; ! 4605: tree type; ! 4606: { ! 4607: extern struct obstack *current_obstack, *saveable_obstack; ! 4608: register tree t = build_decl (code, name, type); ! 4609: struct obstack *obstack = current_obstack; ! 4610: register int i = sizeof (struct lang_decl_flags) / sizeof (int); ! 4611: register int *pi; ! 4612: #if 0 /* not yet, should get fixed properly later */ ! 4613: ! 4614: if (code == TYPE_DECL) ! 4615: { ! 4616: tree id; ! 4617: id = get_identifier (build_overload_name (type, 1, 1)); ! 4618: DECL_ASSEMBLER_NAME (t) = id; ! 4619: } ! 4620: #endif ! 4621: ! 4622: if (! TREE_PERMANENT (t)) ! 4623: obstack = saveable_obstack; ! 4624: else ! 4625: my_friendly_assert (obstack == &permanent_obstack, 235); ! 4626: ! 4627: pi = (int *) obstack_alloc (obstack, sizeof (struct lang_decl_flags)); ! 4628: while (i > 0) ! 4629: pi[--i] = 0; ! 4630: ! 4631: DECL_LANG_SPECIFIC (t) = (struct lang_decl *) pi; ! 4632: return t; ! 4633: } ! 4634: ! 4635: void ! 4636: copy_lang_decl (node) ! 4637: tree node; ! 4638: { ! 4639: int size; ! 4640: int *pi; ! 4641: ! 4642: if (TREE_CODE (node) == FIELD_DECL) ! 4643: size = sizeof (struct lang_decl_flags); ! 4644: else ! 4645: size = sizeof (struct lang_decl); ! 4646: pi = (int *)obstack_alloc (&permanent_obstack, size); ! 4647: bcopy ((char *)DECL_LANG_SPECIFIC (node), (char *)pi, size); ! 4648: DECL_LANG_SPECIFIC (node) = (struct lang_decl *)pi; ! 4649: } ! 4650: ! 4651: tree ! 4652: make_lang_type (code) ! 4653: enum tree_code code; ! 4654: { ! 4655: extern struct obstack *current_obstack, *saveable_obstack; ! 4656: register tree t = make_node (code); ! 4657: struct obstack *obstack = current_obstack; ! 4658: register int i = sizeof (struct lang_type) / sizeof (int); ! 4659: register int *pi; ! 4660: ! 4661: /* Set up some flags that give proper default behavior. */ ! 4662: IS_AGGR_TYPE (t) = 1; ! 4663: ! 4664: if (! TREE_PERMANENT (t)) ! 4665: obstack = saveable_obstack; ! 4666: else ! 4667: my_friendly_assert (obstack == &permanent_obstack, 236); ! 4668: ! 4669: pi = (int *) obstack_alloc (obstack, sizeof (struct lang_type)); ! 4670: while (i > 0) ! 4671: pi[--i] = 0; ! 4672: ! 4673: TYPE_LANG_SPECIFIC (t) = (struct lang_type *) pi; ! 4674: CLASSTYPE_AS_LIST (t) = build_tree_list (NULL_TREE, t); ! 4675: SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown); ! 4676: CLASSTYPE_INTERFACE_ONLY (t) = interface_only; ! 4677: CLASSTYPE_VBASE_SIZE (t) = integer_zero_node; ! 4678: TYPE_BINFO (t) = make_binfo (integer_zero_node, t, NULL_TREE, NULL_TREE, ! 4679: NULL_TREE); ! 4680: CLASSTYPE_BINFO_AS_LIST (t) = build_tree_list (NULL_TREE, TYPE_BINFO (t)); ! 4681: ! 4682: /* Make sure this is laid out, for ease of use later. ! 4683: In the presence of parse errors, the normal was of assuring ! 4684: this might not ever get executed, so we lay it out *immediately*. */ ! 4685: build_pointer_type (t); ! 4686: ! 4687: #ifdef GATHER_STATISTICS ! 4688: tree_node_counts[(int)lang_type] += 1; ! 4689: tree_node_sizes[(int)lang_type] += sizeof(struct lang_type); ! 4690: #endif ! 4691: ! 4692: return t; ! 4693: } ! 4694: ! 4695: void ! 4696: copy_decl_lang_specific (decl) ! 4697: tree decl; ! 4698: { ! 4699: extern struct obstack *current_obstack, *saveable_obstack; ! 4700: register int *old = (int *)DECL_LANG_SPECIFIC (decl); ! 4701: struct obstack *obstack = current_obstack; ! 4702: register int i = sizeof (struct lang_decl) / sizeof (int); ! 4703: register int *pi; ! 4704: ! 4705: if (! TREE_PERMANENT (decl)) ! 4706: obstack = saveable_obstack; ! 4707: else ! 4708: my_friendly_assert (obstack == &permanent_obstack, 237); ! 4709: ! 4710: pi = (int *) obstack_alloc (obstack, sizeof (struct lang_decl)); ! 4711: while (i-- > 0) ! 4712: pi[i] = old[i]; ! 4713: ! 4714: DECL_LANG_SPECIFIC (decl) = (struct lang_decl *) pi; ! 4715: ! 4716: #ifdef GATHER_STATISTICS ! 4717: tree_node_counts[(int)lang_decl] += 1; ! 4718: tree_node_sizes[(int)lang_decl] += sizeof(struct lang_decl); ! 4719: #endif ! 4720: } ! 4721: ! 4722: void ! 4723: dump_time_statistics () ! 4724: { ! 4725: register tree prev = 0, decl, next; ! 4726: int this_time = my_get_run_time (); ! 4727: TREE_INT_CST_LOW (IDENTIFIER_LOCAL_VALUE (this_filename_time)) ! 4728: += this_time - body_time; ! 4729: ! 4730: fprintf (stderr, "\n******\n"); ! 4731: print_time ("header files (total)", header_time); ! 4732: print_time ("main file (total)", this_time - body_time); ! 4733: fprintf (stderr, "ratio = %g : 1\n", ! 4734: (double)header_time / (double)(this_time - body_time)); ! 4735: fprintf (stderr, "\n******\n"); ! 4736: ! 4737: for (decl = filename_times; decl; decl = next) ! 4738: { ! 4739: next = IDENTIFIER_GLOBAL_VALUE (decl); ! 4740: IDENTIFIER_GLOBAL_VALUE (decl) = prev; ! 4741: prev = decl; ! 4742: } ! 4743: ! 4744: for (decl = prev; decl; decl = IDENTIFIER_GLOBAL_VALUE (decl)) ! 4745: print_time (IDENTIFIER_POINTER (decl), ! 4746: TREE_INT_CST_LOW (IDENTIFIER_LOCAL_VALUE (decl))); ! 4747: } ! 4748: ! 4749: void ! 4750: compiler_error (s, v, v2) ! 4751: char *s; ! 4752: HOST_WIDE_INT v, v2; /* @@also used as pointer */ ! 4753: { ! 4754: char buf[1024]; ! 4755: sprintf (buf, s, v, v2); ! 4756: error_with_file_and_line (input_filename, lineno, "%s (compiler error)", buf); ! 4757: } ! 4758: ! 4759: void ! 4760: compiler_error_with_decl (decl, s) ! 4761: tree decl; ! 4762: char *s; ! 4763: { ! 4764: char *name; ! 4765: count_error (0); ! 4766: ! 4767: report_error_function (0); ! 4768: ! 4769: if (TREE_CODE (decl) == PARM_DECL) ! 4770: fprintf (stderr, "%s:%d: ", ! 4771: DECL_SOURCE_FILE (DECL_CONTEXT (decl)), ! 4772: DECL_SOURCE_LINE (DECL_CONTEXT (decl))); ! 4773: else ! 4774: fprintf (stderr, "%s:%d: ", ! 4775: DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl)); ! 4776: ! 4777: name = lang_printable_name (decl); ! 4778: if (name) ! 4779: fprintf (stderr, s, name); ! 4780: else ! 4781: fprintf (stderr, s, "((anonymous))"); ! 4782: fprintf (stderr, " (compiler error)\n"); ! 4783: } ! 4784: ! 4785: void ! 4786: yyerror (string) ! 4787: char *string; ! 4788: { ! 4789: extern int end_of_file; ! 4790: char buf[200]; ! 4791: ! 4792: strcpy (buf, string); ! 4793: ! 4794: /* We can't print string and character constants well ! 4795: because the token_buffer contains the result of processing escapes. */ ! 4796: if (end_of_file) ! 4797: strcat (buf, input_redirected () ! 4798: ? " at end of saved text" ! 4799: : " at end of input"); ! 4800: else if (token_buffer[0] == 0) ! 4801: strcat (buf, " at null character"); ! 4802: else if (token_buffer[0] == '"') ! 4803: strcat (buf, " before string constant"); ! 4804: else if (token_buffer[0] == '\'') ! 4805: strcat (buf, " before character constant"); ! 4806: else if (token_buffer[0] < 040 || (unsigned char) token_buffer[0] >= 0177) ! 4807: sprintf (buf + strlen (buf), " before character 0%o", ! 4808: (unsigned char) token_buffer[0]); ! 4809: else ! 4810: strcat (buf, " before `%s'"); ! 4811: ! 4812: error (buf, token_buffer); ! 4813: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.