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