|
|
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: } ! 3316: 1.1 root 3317: value = (int) ptr->token; 3318: } 3319: } 3320: 3321: /* If we did not find a keyword, look for an identifier 3322: (or a typename). */ 3323: 3324: if (strcmp ("catch", token_buffer) == 0 3325: || strcmp ("throw", token_buffer) == 0 3326: || strcmp ("try", token_buffer) == 0) 3327: { 3328: static int did_warn = 0; 3329: if (! did_warn && ! flag_handle_exceptions) 3330: { 3331: pedwarn ("`catch', `throw', and `try' are all C++ reserved words"); 3332: did_warn = 1; 3333: } 3334: } 3335: 3336: if (value == IDENTIFIER || value == TYPESPEC) 3337: GNU_xref_ref (current_function_decl, token_buffer); 3338: 3339: if (value == IDENTIFIER) 3340: { 3341: register tree tmp = get_identifier (token_buffer); 3342: 3343: #if !defined(VMS) && defined(JOINER) 3344: /* Make sure that user does not collide with our internal 3345: naming scheme. */ 3346: if (JOINER == '$' 3347: && dollar_seen 3348: && (THIS_NAME_P (tmp) 3349: || VPTR_NAME_P (tmp) 3350: || DESTRUCTOR_NAME_P (tmp) 3351: || VTABLE_NAME_P (tmp) 3352: || TEMP_NAME_P (tmp) 3353: || ANON_AGGRNAME_P (tmp) 3354: || ANON_PARMNAME_P (tmp))) 3355: warning ("identifier name `%s' conflicts with GNU C++ internal naming strategy", 3356: token_buffer); 3357: #endif 3358: 3359: yylval.ttype = tmp; 3360: 3361: /* A user-invisible read-only initialized variable 3362: should be replaced by its value. We only handle strings 3363: since that's the only case used in C (and C++). */ 3364: /* Note we go right after the local value for the identifier 3365: (e.g., __FUNCTION__ or __PRETTY_FUNCTION__). We used to 3366: call lookup_name, but that could result in an error about 3367: ambiguities. */ 3368: tmp = IDENTIFIER_LOCAL_VALUE (yylval.ttype); 3369: if (tmp != NULL_TREE 3370: && TREE_CODE (tmp) == VAR_DECL 3371: && DECL_IGNORED_P (tmp) 3372: && TREE_READONLY (tmp) 3373: && DECL_INITIAL (tmp) != NULL_TREE 3374: && TREE_CODE (DECL_INITIAL (tmp)) == STRING_CST) 3375: { 3376: yylval.ttype = DECL_INITIAL (tmp); 3377: value = STRING; 3378: } 3379: } 3380: if (value == NEW && ! global_bindings_p ()) 3381: { 3382: value = NEW; 3383: goto done; 3384: } 3385: } 3386: break; 3387: 3388: case '.': 3389: { 3390: register int c1 = getch (); 3391: token_buffer[0] = c; 3392: token_buffer[1] = c1; 3393: if (c1 == '*') 3394: { 3395: value = DOT_STAR; 3396: token_buffer[2] = 0; 3397: goto done; 3398: } 3399: if (c1 == '.') 3400: { 3401: c1 = getch (); 3402: if (c1 == '.') 3403: { 3404: token_buffer[2] = c1; 3405: token_buffer[3] = 0; 3406: value = ELLIPSIS; 3407: goto done; 3408: } 3409: error ("parse error at `..'"); 3410: } 3411: if (isdigit (c1)) 3412: { 3413: put_back (c1); 3414: goto resume_numerical_scan; 3415: } 3416: nextchar = c1; 3417: value = '.'; 3418: token_buffer[1] = 0; 3419: goto done; 3420: } 3421: case '0': case '1': 3422: /* Optimize for most frequent case. */ 3423: { 3424: register int c1 = getch (); 3425: if (! isalnum (c1) && c1 != '.') 3426: { 3427: /* Terminate string. */ 3428: token_buffer[0] = c; 3429: token_buffer[1] = 0; 3430: if (c == '0') 3431: yylval.ttype = integer_zero_node; 3432: else 3433: yylval.ttype = integer_one_node; 3434: nextchar = c1; 3435: value = CONSTANT; 3436: goto done; 3437: } 3438: put_back (c1); 3439: } 3440: /* fall through... */ 3441: case '2': case '3': case '4': 3442: case '5': case '6': case '7': case '8': case '9': 3443: resume_numerical_scan: 3444: { 3445: register char *p; 3446: int base = 10; 3447: int count = 0; 3448: int largest_digit = 0; 3449: int numdigits = 0; 3450: /* for multi-precision arithmetic, 3451: we actually store only HOST_BITS_PER_CHAR bits in each part. 3452: The number of parts is chosen so as to be sufficient to hold 3453: the enough bits to fit into the two HOST_WIDE_INTs that contain 3454: the integer value (this is always at least as many bits as are 3455: in a target `long long' value, but may be wider). */ 3456: #define TOTAL_PARTS ((HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR) * 2 + 2) 3457: int parts[TOTAL_PARTS]; 3458: int overflow = 0; 3459: 3460: enum anon1 { NOT_FLOAT, AFTER_POINT, TOO_MANY_POINTS} floatflag 3461: = NOT_FLOAT; 3462: 3463: p = token_buffer; 3464: *p++ = c; 3465: 3466: for (count = 0; count < TOTAL_PARTS; count++) 3467: parts[count] = 0; 3468: 3469: if (c == '0') 3470: { 3471: *p++ = (c = getch ()); 3472: if ((c == 'x') || (c == 'X')) 3473: { 3474: base = 16; 3475: *p++ = (c = getch ()); 3476: } 3477: /* Leading 0 forces octal unless the 0 is the only digit. */ 3478: else if (c >= '0' && c <= '9') 3479: { 3480: base = 8; 3481: numdigits++; 3482: } 3483: else 3484: numdigits++; 3485: } 3486: 3487: /* Read all the digits-and-decimal-points. */ 3488: 3489: while (c == '.' 3490: || (isalnum (c) && (c != 'l') && (c != 'L') 3491: && (c != 'u') && (c != 'U') 3492: && (floatflag == NOT_FLOAT || ((c != 'f') && (c != 'F'))))) 3493: { 3494: if (c == '.') 3495: { 3496: if (base == 16) 3497: error ("floating constant may not be in radix 16"); 3498: if (floatflag == AFTER_POINT) 3499: { 3500: error ("malformed floating constant"); 3501: floatflag = TOO_MANY_POINTS; 3502: } 3503: else 3504: floatflag = AFTER_POINT; 3505: 3506: base = 10; 3507: *p++ = c = getch (); 3508: /* Accept '.' as the start of a floating-point number 3509: only when it is followed by a digit. 3510: Otherwise, unread the following non-digit 3511: and use the '.' as a structural token. */ 3512: if (p == token_buffer + 2 && !isdigit (c)) 3513: { 3514: if (c == '.') 3515: { 3516: c = getch (); 3517: if (c == '.') 3518: { 3519: *p++ = '.'; 3520: *p = '\0'; 3521: value = ELLIPSIS; 3522: goto done; 3523: } 3524: error ("parse error at `..'"); 3525: } 3526: nextchar = c; 3527: token_buffer[1] = '\0'; 3528: value = '.'; 3529: goto done; 3530: } 3531: } 3532: else 3533: { 3534: /* It is not a decimal point. 3535: It should be a digit (perhaps a hex digit). */ 3536: 3537: if (isdigit (c)) 3538: { 3539: c = c - '0'; 3540: } 3541: else if (base <= 10) 3542: { 3543: if (c == 'e' || c == 'E') 3544: { 3545: base = 10; 3546: floatflag = AFTER_POINT; 3547: break; /* start of exponent */ 3548: } 3549: error ("nondigits in number and not hexadecimal"); 3550: c = 0; 3551: } 3552: else if (c >= 'a') 3553: { 3554: c = c - 'a' + 10; 3555: } 3556: else 3557: { 3558: c = c - 'A' + 10; 3559: } 3560: if (c >= largest_digit) 3561: largest_digit = c; 3562: numdigits++; 3563: 3564: for (count = 0; count < TOTAL_PARTS; count++) 3565: { 3566: parts[count] *= base; 3567: if (count) 3568: { 3569: parts[count] 3570: += (parts[count-1] >> HOST_BITS_PER_CHAR); 3571: parts[count-1] 3572: &= (1 << HOST_BITS_PER_CHAR) - 1; 3573: } 3574: else 3575: parts[0] += c; 3576: } 3577: 3578: /* If the extra highest-order part ever gets anything in it, 3579: the number is certainly too big. */ 3580: if (parts[TOTAL_PARTS - 1] != 0) 3581: overflow = 1; 3582: 3583: if (p >= token_buffer + maxtoken - 3) 3584: p = extend_token_buffer (p); 3585: *p++ = (c = getch ()); 3586: } 3587: } 3588: 3589: if (numdigits == 0) 3590: error ("numeric constant with no digits"); 3591: 3592: if (largest_digit >= base) 3593: error ("numeric constant contains digits beyond the radix"); 3594: 3595: /* Remove terminating char from the token buffer and delimit the string */ 3596: *--p = 0; 3597: 3598: if (floatflag != NOT_FLOAT) 3599: { 3600: tree type = double_type_node; 3601: char f_seen = 0; 3602: char l_seen = 0; 3603: int garbage_chars = 0; 3604: REAL_VALUE_TYPE value; 3605: jmp_buf handler; 3606: 3607: /* Read explicit exponent if any, and put it in tokenbuf. */ 3608: 3609: if ((c == 'e') || (c == 'E')) 3610: { 3611: if (p >= token_buffer + maxtoken - 3) 3612: p = extend_token_buffer (p); 3613: *p++ = c; 3614: c = getch (); 3615: if ((c == '+') || (c == '-')) 3616: { 3617: *p++ = c; 3618: c = getch (); 3619: } 3620: if (! isdigit (c)) 3621: error ("floating constant exponent has no digits"); 3622: while (isdigit (c)) 3623: { 3624: if (p >= token_buffer + maxtoken - 3) 3625: p = extend_token_buffer (p); 3626: *p++ = c; 3627: c = getch (); 3628: } 3629: } 3630: 3631: *p = 0; 3632: errno = 0; 3633: 3634: /* Convert string to a double, checking for overflow. */ 3635: if (setjmp (handler)) 3636: { 3637: error ("floating constant out of range"); 3638: value = dconst0; 3639: } 3640: else 3641: { 3642: set_float_handler (handler); 3643: /* The second argument, machine_mode, of REAL_VALUE_ATOF 3644: tells the desired precision of the binary result of 3645: decimal-to-binary conversion. */ 3646: 3647: /* Read the suffixes to choose a data type. */ 3648: switch (c) 3649: { 3650: case 'f': case 'F': 3651: type = float_type_node; 3652: value = REAL_VALUE_ATOF (token_buffer, TYPE_MODE (type)); 3653: garbage_chars = -1; 3654: break; 3655: 3656: case 'l': case 'L': 3657: type = long_double_type_node; 3658: value = REAL_VALUE_ATOF (token_buffer, TYPE_MODE (type)); 3659: garbage_chars = -1; 3660: break; 3661: 3662: default: 3663: value = REAL_VALUE_ATOF (token_buffer, TYPE_MODE (type)); 3664: } 3665: set_float_handler (NULL_PTR); 3666: } 3667: if (pedantic 3668: && (REAL_VALUE_ISINF (value) 3669: #ifdef ERANGE 3670: || (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT 3671: && errno == ERANGE 3672: /* ERANGE is also reported for underflow, so test the 3673: value to distinguish overflow from that. */ 3674: && (REAL_VALUES_LESS (dconst1, value) 3675: || REAL_VALUES_LESS (value, dconstm1))) 3676: #endif 3677: )) 3678: { 3679: pedwarn ("floating point number exceeds range of `%s'", 3680: IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)))); 3681: } 3682: /* Note: garbage_chars is -1 if first char is *not* garbage. */ 3683: while (isalnum (c)) 3684: { 3685: if (c == 'f' || c == 'F') 3686: { 3687: if (f_seen) 3688: error ("two `f's in floating constant"); 3689: f_seen = 1; 3690: } 3691: if (c == 'l' || c == 'L') 3692: { 3693: if (l_seen) 3694: error ("two `l's in floating constant"); 3695: l_seen = 1; 3696: } 3697: if (p >= token_buffer + maxtoken - 3) 3698: p = extend_token_buffer (p); 3699: *p++ = c; 3700: c = getch (); 3701: garbage_chars++; 3702: } 3703: 3704: if (garbage_chars > 0) 3705: error ("garbage at end of number"); 3706: 3707: /* Create a node with determined type and value. */ 3708: yylval.ttype = build_real (type, value); 3709: 3710: put_back (c); 3711: *p = 0; 3712: } 3713: else 3714: { 3715: tree type; 3716: HOST_WIDE_INT high, low; 3717: int spec_unsigned = 0; 3718: int spec_long = 0; 3719: int spec_long_long = 0; 3720: int bytes, warn; 3721: 3722: while (1) 3723: { 3724: if (c == 'u' || c == 'U') 3725: { 3726: if (spec_unsigned) 3727: error ("two `u's in integer constant"); 3728: spec_unsigned = 1; 3729: } 3730: else if (c == 'l' || c == 'L') 3731: { 3732: if (spec_long) 3733: { 3734: if (spec_long_long) 3735: error ("three `l's in integer constant"); 3736: else if (pedantic) 3737: pedwarn ("ANSI C++ forbids long long integer constants"); 3738: spec_long_long = 1; 3739: } 3740: spec_long = 1; 3741: } 3742: else 3743: { 3744: if (isalnum (c)) 3745: { 3746: error ("garbage at end of number"); 3747: while (isalnum (c)) 3748: { 3749: if (p >= token_buffer + maxtoken - 3) 3750: p = extend_token_buffer (p); 3751: *p++ = c; 3752: c = getch (); 3753: } 3754: } 3755: break; 3756: } 3757: if (p >= token_buffer + maxtoken - 3) 3758: p = extend_token_buffer (p); 3759: *p++ = c; 3760: c = getch (); 3761: } 3762: 3763: put_back (c); 3764: 3765: /* If the constant is not long long and it won't fit in an 3766: unsigned long, or if the constant is long long and won't fit 3767: in an unsigned long long, then warn that the constant is out 3768: of range. */ 3769: 3770: /* ??? This assumes that long long and long integer types are 3771: a multiple of 8 bits. This better than the original code 3772: though which assumed that long was exactly 32 bits and long 3773: long was exactly 64 bits. */ 3774: 3775: if (spec_long_long) 3776: bytes = TYPE_PRECISION (long_long_integer_type_node) / 8; 3777: else 3778: bytes = TYPE_PRECISION (long_integer_type_node) / 8; 3779: 3780: warn = overflow; 3781: for (i = bytes; i < TOTAL_PARTS; i++) 3782: if (parts[i]) 3783: warn = 1; 3784: if (warn) 3785: pedwarn ("integer constant out of range"); 3786: 3787: /* This is simplified by the fact that our constant 3788: is always positive. */ 3789: high = low = 0; 3790: 3791: for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR; i++) 3792: { 3793: high |= ((HOST_WIDE_INT) parts[i + (HOST_BITS_PER_WIDE_INT 3794: / HOST_BITS_PER_CHAR)] 3795: << (i * HOST_BITS_PER_CHAR)); 3796: low |= (HOST_WIDE_INT) parts[i] << (i * HOST_BITS_PER_CHAR); 3797: } 3798: 3799: 3800: yylval.ttype = build_int_2 (low, high); 3801: TREE_TYPE (yylval.ttype) = long_long_unsigned_type_node; 3802: 3803: #if 0 3804: /* Find the first allowable type that the value fits in. */ 3805: type = 0; 3806: for (i = 0; i < sizeof (type_sequence) / sizeof (type_sequence[0]); 3807: i++) 3808: if (!(spec_long && !type_sequence[i].long_flag) 3809: && !(spec_long_long && !type_sequence[i].long_long_flag) 3810: && !(spec_unsigned && !type_sequence[i].unsigned_flag) 3811: /* A hex or octal constant traditionally is unsigned. */ 3812: && !(base != 10 && flag_traditional 3813: && !type_sequence[i].unsigned_flag) 3814: /* A decimal constant can't be unsigned int 3815: unless explicitly specified. */ 3816: && !(base == 10 && !spec_unsigned 3817: && *type_sequence[i].node_var == unsigned_type_node)) 3818: if (int_fits_type_p (yylval.ttype, *type_sequence[i].node_var)) 3819: { 3820: type = *type_sequence[i].node_var; 3821: break; 3822: } 3823: if (flag_traditional && type == long_unsigned_type_node 3824: && !spec_unsigned) 3825: type = long_integer_type_node; 3826: 3827: if (type == 0) 3828: { 3829: type = long_long_integer_type_node; 3830: warning ("integer constant out of range"); 3831: } 3832: 3833: /* Warn about some cases where the type of a given constant 3834: changes from traditional C to ANSI C. */ 3835: if (warn_traditional) 3836: { 3837: tree other_type = 0; 3838: 3839: /* This computation is the same as the previous one 3840: except that flag_traditional is used backwards. */ 3841: for (i = 0; i < sizeof (type_sequence) / sizeof (type_sequence[0]); 3842: i++) 3843: if (!(spec_long && !type_sequence[i].long_flag) 3844: && !(spec_long_long && !type_sequence[i].long_long_flag) 3845: && !(spec_unsigned && !type_sequence[i].unsigned_flag) 3846: /* A hex or octal constant traditionally is unsigned. */ 3847: && !(base != 10 && !flag_traditional 3848: && !type_sequence[i].unsigned_flag) 3849: /* A decimal constant can't be unsigned int 3850: unless explicitly specified. */ 3851: && !(base == 10 && !spec_unsigned 3852: && *type_sequence[i].node_var == unsigned_type_node)) 3853: if (int_fits_type_p (yylval.ttype, *type_sequence[i].node_var)) 3854: { 3855: other_type = *type_sequence[i].node_var; 3856: break; 3857: } 3858: if (!flag_traditional && type == long_unsigned_type_node 3859: && !spec_unsigned) 3860: type = long_integer_type_node; 3861: 3862: if (other_type != 0 && other_type != type) 3863: { 3864: if (flag_traditional) 3865: warning ("type of integer constant would be different without -traditional"); 3866: else 3867: warning ("type of integer constant would be different with -traditional"); 3868: } 3869: } 3870: 3871: #else /* 1 */ 3872: if (!spec_long && !spec_unsigned 3873: && !(flag_traditional && base != 10) 3874: && int_fits_type_p (yylval.ttype, integer_type_node)) 3875: { 3876: #if 0 3877: if (warn_traditional && base != 10) 3878: warning ("small nondecimal constant becomes signed in ANSI C++"); 3879: #endif 3880: type = integer_type_node; 3881: } 3882: else if (!spec_long && (base != 10 || spec_unsigned) 3883: && int_fits_type_p (yylval.ttype, unsigned_type_node)) 3884: { 3885: /* Nondecimal constants try unsigned even in traditional C. */ 3886: type = unsigned_type_node; 3887: } 3888: 3889: else if (!spec_unsigned && !spec_long_long 3890: && int_fits_type_p (yylval.ttype, long_integer_type_node)) 3891: type = long_integer_type_node; 3892: 3893: else if (! spec_long_long 3894: && int_fits_type_p (yylval.ttype, 3895: long_unsigned_type_node)) 3896: { 3897: #if 0 3898: if (warn_traditional && !spec_unsigned) 3899: warning ("large integer constant becomes unsigned in ANSI C++"); 3900: #endif 3901: if (flag_traditional && !spec_unsigned) 3902: type = long_integer_type_node; 3903: else 3904: type = long_unsigned_type_node; 3905: } 3906: 3907: else if (! spec_unsigned 3908: /* Verify value does not overflow into sign bit. */ 3909: && TREE_INT_CST_HIGH (yylval.ttype) >= 0 3910: && int_fits_type_p (yylval.ttype, 3911: long_long_integer_type_node)) 3912: type = long_long_integer_type_node; 3913: 3914: else if (int_fits_type_p (yylval.ttype, 3915: long_long_unsigned_type_node)) 3916: { 3917: #if 0 3918: if (warn_traditional && !spec_unsigned) 3919: warning ("large nondecimal constant is unsigned in ANSI C++"); 3920: #endif 3921: 3922: if (flag_traditional && !spec_unsigned) 3923: type = long_long_integer_type_node; 3924: else 3925: type = long_long_unsigned_type_node; 3926: } 3927: 3928: else 3929: { 3930: type = long_long_integer_type_node; 3931: warning ("integer constant out of range"); 3932: 3933: if (base == 10 && ! spec_unsigned && TREE_UNSIGNED (type)) 3934: warning ("decimal integer constant is so large that it is unsigned"); 3935: } 3936: #endif 3937: 3938: TREE_TYPE (yylval.ttype) = type; 3939: *p = 0; 3940: } 3941: 3942: value = CONSTANT; break; 3943: } 3944: 3945: case '\'': 3946: char_constant: 3947: { 3948: register int result = 0; 3949: register int num_chars = 0; 3950: unsigned width = TYPE_PRECISION (char_type_node); 3951: int max_chars; 3952: 3953: if (wide_flag) 3954: { 3955: width = WCHAR_TYPE_SIZE; 3956: #ifdef MULTIBYTE_CHARS 3957: max_chars = MB_CUR_MAX; 3958: #else 3959: max_chars = 1; 3960: #endif 3961: } 3962: else 3963: max_chars = TYPE_PRECISION (integer_type_node) / width; 3964: 3965: while (1) 3966: { 3967: tryagain: 3968: 3969: c = getch (); 3970: 3971: if (c == '\'' || c == EOF) 3972: break; 3973: 3974: if (c == '\\') 3975: { 3976: int ignore = 0; 3977: c = readescape (&ignore); 3978: if (ignore) 3979: goto tryagain; 3980: if (width < HOST_BITS_PER_INT 3981: && (unsigned) c >= (1 << width)) 1.1.1.2 ! root 3982: warning ("escape sequence out of range for character"); 1.1 root 3983: #ifdef MAP_CHARACTER 3984: if (isprint (c)) 3985: c = MAP_CHARACTER (c); 3986: #endif 3987: } 3988: else if (c == '\n') 3989: { 3990: if (pedantic) 3991: pedwarn ("ANSI C++ forbids newline in character constant"); 3992: lineno++; 3993: } 3994: #ifdef MAP_CHARACTER 3995: else 3996: c = MAP_CHARACTER (c); 3997: #endif 3998: 3999: num_chars++; 4000: if (num_chars > maxtoken - 4) 4001: extend_token_buffer (token_buffer); 4002: 4003: token_buffer[num_chars] = c; 4004: 4005: /* Merge character into result; ignore excess chars. */ 4006: if (num_chars < max_chars + 1) 4007: { 4008: if (width < HOST_BITS_PER_INT) 4009: result = (result << width) | (c & ((1 << width) - 1)); 4010: else 4011: result = c; 4012: } 4013: } 4014: 4015: token_buffer[num_chars + 1] = '\''; 4016: token_buffer[num_chars + 2] = 0; 4017: 4018: if (c != '\'') 4019: error ("malformatted character constant"); 4020: else if (num_chars == 0) 4021: error ("empty character constant"); 4022: else if (num_chars > max_chars) 4023: { 4024: num_chars = max_chars; 4025: error ("character constant too long"); 4026: } 4027: else if (num_chars != 1 && ! flag_traditional) 4028: warning ("multi-character character constant"); 4029: 4030: /* If char type is signed, sign-extend the constant. */ 4031: if (! wide_flag) 4032: { 4033: int num_bits = num_chars * width; 4034: if (num_bits == 0) 4035: /* We already got an error; avoid invalid shift. */ 4036: yylval.ttype = build_int_2 (0, 0); 4037: else if (TREE_UNSIGNED (char_type_node) 4038: || ((result >> (num_bits - 1)) & 1) == 0) 4039: yylval.ttype 4040: = build_int_2 (result & ((unsigned HOST_WIDE_INT) ~0 4041: >> (HOST_BITS_PER_WIDE_INT - num_bits)), 4042: 0); 4043: else 4044: yylval.ttype 4045: = build_int_2 (result | ~((unsigned HOST_WIDE_INT) ~0 4046: >> (HOST_BITS_PER_WIDE_INT - num_bits)), 4047: -1); 4048: if (num_chars<=1) 4049: TREE_TYPE (yylval.ttype) = char_type_node; 4050: else 4051: TREE_TYPE (yylval.ttype) = integer_type_node; 4052: } 4053: else 4054: { 4055: #ifdef MULTIBYTE_CHARS 4056: /* Set the initial shift state and convert the next sequence. */ 4057: result = 0; 4058: /* In all locales L'\0' is zero and mbtowc will return zero, 4059: so don't use it. */ 4060: if (num_chars > 1 4061: || (num_chars == 1 && token_buffer[1] != '\0')) 4062: { 4063: wchar_t wc; 4064: (void) mbtowc (NULL, NULL, 0); 4065: if (mbtowc (& wc, token_buffer + 1, num_chars) == num_chars) 4066: result = wc; 4067: else 4068: warning ("Ignoring invalid multibyte character"); 4069: } 4070: #endif 4071: yylval.ttype = build_int_2 (result, 0); 4072: TREE_TYPE (yylval.ttype) = wchar_type_node; 4073: } 4074: 4075: value = CONSTANT; 4076: break; 4077: } 4078: 4079: case '"': 4080: string_constant: 4081: { 4082: register char *p; 4083: 4084: c = getch (); 4085: p = token_buffer + 1; 4086: 4087: while (c != '"' && c >= 0) 4088: { 4089: /* ignore_escape_flag is set for reading the filename in #line. */ 4090: if (!ignore_escape_flag && c == '\\') 4091: { 4092: int ignore = 0; 4093: c = readescape (&ignore); 4094: if (ignore) 4095: goto skipnewline; 4096: if (!wide_flag 4097: && TYPE_PRECISION (char_type_node) < HOST_BITS_PER_INT 4098: && c >= ((unsigned) 1 << TYPE_PRECISION (char_type_node))) 1.1.1.2 ! root 4099: warning ("escape sequence out of range for character"); 1.1 root 4100: } 4101: else if (c == '\n') 4102: { 4103: if (pedantic) 4104: pedwarn ("ANSI C++ forbids newline in string constant"); 4105: lineno++; 4106: } 4107: 4108: if (p == token_buffer + maxtoken) 4109: p = extend_token_buffer (p); 4110: *p++ = c; 4111: 4112: skipnewline: 4113: c = getch (); 4114: if (c == EOF) { 4115: error("Unterminated string"); 4116: break; 4117: } 4118: } 4119: *p = 0; 4120: 4121: /* We have read the entire constant. 4122: Construct a STRING_CST for the result. */ 4123: 4124: if (wide_flag) 4125: { 4126: /* If this is a L"..." wide-string, convert the multibyte string 4127: to a wide character string. */ 4128: char *widep = (char *) alloca ((p - token_buffer) * WCHAR_BYTES); 4129: int len; 4130: 4131: #ifdef MULTIBYTE_CHARS 4132: len = mbstowcs ((wchar_t *) widep, token_buffer + 1, p - token_buffer); 4133: if (len < 0 || len >= (p - token_buffer)) 4134: { 4135: warning ("Ignoring invalid multibyte string"); 4136: len = 0; 4137: } 4138: bzero (widep + (len * WCHAR_BYTES), WCHAR_BYTES); 4139: #else 4140: { 4141: union { long l; char c[sizeof (long)]; } u; 4142: int big_endian; 4143: char *wp, *cp; 4144: 4145: /* Determine whether host is little or big endian. */ 4146: u.l = 1; 4147: big_endian = u.c[sizeof (long) - 1]; 4148: wp = widep + (big_endian ? WCHAR_BYTES - 1 : 0); 4149: 4150: bzero (widep, (p - token_buffer) * WCHAR_BYTES); 4151: for (cp = token_buffer + 1; cp < p; cp++) 4152: *wp = *cp, wp += WCHAR_BYTES; 4153: len = p - token_buffer - 1; 4154: } 4155: #endif 4156: yylval.ttype = build_string ((len + 1) * WCHAR_BYTES, widep); 4157: TREE_TYPE (yylval.ttype) = wchar_array_type_node; 4158: } 4159: else 4160: { 4161: yylval.ttype = build_string (p - token_buffer, token_buffer + 1); 4162: TREE_TYPE (yylval.ttype) = char_array_type_node; 4163: } 4164: 4165: *p++ = '"'; 4166: *p = 0; 4167: 4168: value = STRING; break; 4169: } 4170: 4171: case '+': 4172: case '-': 4173: case '&': 4174: case '|': 4175: case '<': 4176: case '>': 4177: case '*': 4178: case '/': 4179: case '%': 4180: case '^': 4181: case '!': 4182: case '=': 4183: { 4184: register int c1; 4185: 4186: combine: 4187: 4188: switch (c) 4189: { 4190: case '+': 4191: yylval.code = PLUS_EXPR; break; 4192: case '-': 4193: yylval.code = MINUS_EXPR; break; 4194: case '&': 4195: yylval.code = BIT_AND_EXPR; break; 4196: case '|': 4197: yylval.code = BIT_IOR_EXPR; break; 4198: case '*': 4199: yylval.code = MULT_EXPR; break; 4200: case '/': 4201: yylval.code = TRUNC_DIV_EXPR; break; 4202: case '%': 4203: yylval.code = TRUNC_MOD_EXPR; break; 4204: case '^': 4205: yylval.code = BIT_XOR_EXPR; break; 4206: case LSHIFT: 4207: yylval.code = LSHIFT_EXPR; break; 4208: case RSHIFT: 4209: yylval.code = RSHIFT_EXPR; break; 4210: case '<': 4211: yylval.code = LT_EXPR; break; 4212: case '>': 4213: yylval.code = GT_EXPR; break; 4214: } 4215: 4216: token_buffer[1] = c1 = getch (); 4217: token_buffer[2] = 0; 4218: 4219: if (c1 == '=') 4220: { 4221: switch (c) 4222: { 4223: case '<': 4224: value = ARITHCOMPARE; yylval.code = LE_EXPR; goto done; 4225: case '>': 4226: value = ARITHCOMPARE; yylval.code = GE_EXPR; goto done; 4227: case '!': 4228: value = EQCOMPARE; yylval.code = NE_EXPR; goto done; 4229: case '=': 4230: value = EQCOMPARE; yylval.code = EQ_EXPR; goto done; 4231: } 4232: value = ASSIGN; goto done; 4233: } 4234: else if (c == c1) 4235: switch (c) 4236: { 4237: case '+': 4238: value = PLUSPLUS; goto done; 4239: case '-': 4240: value = MINUSMINUS; goto done; 4241: case '&': 4242: value = ANDAND; goto done; 4243: case '|': 4244: value = OROR; goto done; 4245: case '<': 4246: c = LSHIFT; 4247: goto combine; 4248: case '>': 4249: c = RSHIFT; 4250: goto combine; 4251: } 4252: else if ((c == '-') && (c1 == '>')) 4253: { 1.1.1.2 ! root 4254: nextchar = getch (); 1.1 root 4255: if (nextchar == '*') 4256: { 4257: nextchar = -1; 4258: value = POINTSAT_STAR; 4259: } 4260: else 4261: value = POINTSAT; 4262: goto done; 4263: } 4264: else if (c1 == '?' && (c == '<' || c == '>')) 4265: { 4266: token_buffer[3] = 0; 4267: 4268: c1 = getch (); 4269: yylval.code = (c == '<' ? MIN_EXPR : MAX_EXPR); 4270: if (c1 == '=') 4271: { 4272: /* <?= or >?= expression. */ 4273: token_buffer[2] = c1; 4274: value = ASSIGN; 4275: } 4276: else 4277: { 4278: value = MIN_MAX; 4279: nextchar = c1; 4280: } 1.1.1.2 ! root 4281: if (pedantic) 1.1 root 4282: pedwarn ("use of `operator %s' is not standard C++", 4283: token_buffer); 4284: goto done; 4285: } 1.1.1.2 ! root 4286: /* digraphs */ ! 4287: else if (c == '<' && c1 == '%') ! 4288: { value = '{'; goto done; } ! 4289: else if (c == '<' && c1 == ':') ! 4290: { value = '['; goto done; } ! 4291: else if (c == '%' && c1 == '>') ! 4292: { value = '}'; goto done; } ! 4293: else if (c == '%' && c1 == ':') ! 4294: { value = '#'; goto done; } 1.1 root 4295: 4296: nextchar = c1; 4297: token_buffer[1] = 0; 4298: 4299: value = c; 4300: goto done; 4301: } 4302: 4303: case ':': 4304: c = getch (); 4305: if (c == ':') 4306: { 4307: token_buffer[1] = ':'; 4308: token_buffer[2] = '\0'; 4309: value = SCOPE; 4310: yylval.itype = 1; 4311: } 1.1.1.2 ! root 4312: else if (c == '>') ! 4313: { ! 4314: value = ']'; ! 4315: goto done; ! 4316: } 1.1 root 4317: else 4318: { 4319: nextchar = c; 4320: value = ':'; 4321: } 4322: break; 4323: 4324: case 0: 4325: /* Don't make yyparse think this is eof. */ 4326: value = 1; 4327: break; 4328: 4329: case '(': 4330: /* try, weakly, to handle casts to pointers to functions. */ 4331: nextchar = skip_white_space (getch ()); 4332: if (nextchar == '*') 4333: { 4334: int next_c = skip_white_space (getch ()); 4335: if (next_c == ')') 4336: { 4337: nextchar = -1; 4338: yylval.ttype = build1 (INDIRECT_REF, 0, 0); 4339: value = PAREN_STAR_PAREN; 4340: } 4341: else 4342: { 4343: put_back (next_c); 4344: value = c; 4345: } 4346: } 4347: else if (nextchar == ')') 4348: { 4349: nextchar = -1; 4350: yylval.ttype = NULL_TREE; 4351: value = LEFT_RIGHT; 4352: } 4353: else value = c; 4354: break; 4355: 4356: default: 4357: value = c; 4358: } 4359: 4360: done: 4361: /* yylloc.last_line = lineno; */ 4362: #ifdef GATHER_STATISTICS 4363: token_count[value] += 1; 4364: #endif 4365: 4366: return value; 4367: } 4368: 4369: typedef enum 4370: { 4371: d_kind, t_kind, s_kind, r_kind, e_kind, c_kind, 4372: id_kind, op_id_kind, perm_list_kind, temp_list_kind, 4373: vec_kind, x_kind, lang_decl, lang_type, all_kinds 4374: } tree_node_kind; 4375: extern int tree_node_counts[]; 4376: extern int tree_node_sizes[]; 4377: extern char *tree_node_kind_names[]; 4378: 4379: /* Place to save freed lang_decls which were allocated on the 4380: permanent_obstack. @@ Not currently used. */ 4381: tree free_lang_decl_chain; 4382: 4383: tree 4384: build_lang_decl (code, name, type) 4385: enum tree_code code; 4386: tree name; 4387: tree type; 4388: { 4389: register tree t = build_decl (code, name, type); 4390: struct obstack *obstack = current_obstack; 4391: register int i = sizeof (struct lang_decl) / sizeof (int); 4392: register int *pi; 4393: 4394: if (! TREE_PERMANENT (t)) 4395: obstack = saveable_obstack; 4396: else 4397: /* Could be that saveable is permanent and current is not. */ 4398: obstack = &permanent_obstack; 4399: 4400: if (free_lang_decl_chain && obstack == &permanent_obstack) 4401: { 4402: pi = (int *)free_lang_decl_chain; 4403: free_lang_decl_chain = TREE_CHAIN (free_lang_decl_chain); 4404: } 4405: else 4406: pi = (int *) obstack_alloc (obstack, sizeof (struct lang_decl)); 4407: 4408: while (i > 0) 4409: pi[--i] = 0; 4410: 4411: DECL_LANG_SPECIFIC (t) = (struct lang_decl *) pi; 4412: LANG_DECL_PERMANENT ((struct lang_decl *) pi) 4413: = obstack == &permanent_obstack; 4414: my_friendly_assert (LANG_DECL_PERMANENT ((struct lang_decl *) pi) 4415: == TREE_PERMANENT (t), 234); 4416: DECL_MAIN_VARIANT (t) = t; 4417: if (current_lang_name == lang_name_cplusplus) 4418: { 4419: DECL_LANGUAGE (t) = lang_cplusplus; 4420: #if 0 4421: #ifndef NO_AUTO_OVERLOAD 4422: if (code == FUNCTION_DECL && name != 0 4423: && ! (IDENTIFIER_LENGTH (name) == 4 4424: && IDENTIFIER_POINTER (name)[0] == 'm' 4425: && strcmp (IDENTIFIER_POINTER (name), "main") == 0) 4426: && ! (IDENTIFIER_LENGTH (name) > 10 4427: && IDENTIFIER_POINTER (name)[0] == '_' 4428: && IDENTIFIER_POINTER (name)[1] == '_' 4429: && strncmp (IDENTIFIER_POINTER (name)+2, "builtin_", 8) == 0)) 4430: TREE_OVERLOADED (name) = 1; 4431: #endif 4432: #endif 4433: } 4434: else if (current_lang_name == lang_name_c) 4435: DECL_LANGUAGE (t) = lang_c; 4436: else my_friendly_abort (64); 4437: 4438: #if 0 /* not yet, should get fixed properly later */ 4439: if (code == TYPE_DECL) 4440: { 4441: tree id; 4442: id = get_identifier (build_overload_name (type, 1, 1)); 4443: DECL_ASSEMBLER_NAME (t) = id; 4444: } 4445: 4446: #endif 4447: #ifdef GATHER_STATISTICS 4448: tree_node_counts[(int)lang_decl] += 1; 4449: tree_node_sizes[(int)lang_decl] += sizeof(struct lang_decl); 4450: #endif 4451: 4452: return t; 4453: } 4454: 4455: tree 4456: build_lang_field_decl (code, name, type) 4457: enum tree_code code; 4458: tree name; 4459: tree type; 4460: { 4461: extern struct obstack *current_obstack, *saveable_obstack; 4462: register tree t = build_decl (code, name, type); 4463: struct obstack *obstack = current_obstack; 4464: register int i = sizeof (struct lang_decl_flags) / sizeof (int); 4465: register int *pi; 4466: #if 0 /* not yet, should get fixed properly later */ 4467: 4468: if (code == TYPE_DECL) 4469: { 4470: tree id; 4471: id = get_identifier (build_overload_name (type, 1, 1)); 4472: DECL_ASSEMBLER_NAME (t) = id; 4473: } 4474: #endif 4475: 4476: if (! TREE_PERMANENT (t)) 4477: obstack = saveable_obstack; 4478: else 4479: my_friendly_assert (obstack == &permanent_obstack, 235); 4480: 4481: pi = (int *) obstack_alloc (obstack, sizeof (struct lang_decl_flags)); 4482: while (i > 0) 4483: pi[--i] = 0; 4484: 4485: DECL_LANG_SPECIFIC (t) = (struct lang_decl *) pi; 4486: return t; 4487: } 4488: 4489: void 4490: copy_lang_decl (node) 4491: tree node; 4492: { 4493: int size; 4494: int *pi; 4495: 4496: if (TREE_CODE (node) == FIELD_DECL) 4497: size = sizeof (struct lang_decl_flags); 4498: else 4499: size = sizeof (struct lang_decl); 4500: pi = (int *)obstack_alloc (&permanent_obstack, size); 4501: bcopy ((char *)DECL_LANG_SPECIFIC (node), (char *)pi, size); 4502: DECL_LANG_SPECIFIC (node) = (struct lang_decl *)pi; 4503: } 4504: 4505: tree 4506: make_lang_type (code) 4507: enum tree_code code; 4508: { 4509: extern struct obstack *current_obstack, *saveable_obstack; 4510: register tree t = make_node (code); 4511: struct obstack *obstack = current_obstack; 4512: register int i = sizeof (struct lang_type) / sizeof (int); 4513: register int *pi; 4514: 4515: /* Set up some flags that give proper default behavior. */ 4516: IS_AGGR_TYPE (t) = 1; 4517: 4518: if (! TREE_PERMANENT (t)) 4519: obstack = saveable_obstack; 4520: else 4521: my_friendly_assert (obstack == &permanent_obstack, 236); 4522: 4523: pi = (int *) obstack_alloc (obstack, sizeof (struct lang_type)); 4524: while (i > 0) 4525: pi[--i] = 0; 4526: 4527: TYPE_LANG_SPECIFIC (t) = (struct lang_type *) pi; 4528: CLASSTYPE_AS_LIST (t) = build_tree_list (NULL_TREE, t); 4529: SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown); 4530: CLASSTYPE_INTERFACE_ONLY (t) = interface_only; 4531: CLASSTYPE_VBASE_SIZE (t) = integer_zero_node; 4532: TYPE_BINFO (t) = make_binfo (integer_zero_node, t, NULL_TREE, NULL_TREE, 4533: NULL_TREE); 4534: CLASSTYPE_BINFO_AS_LIST (t) = build_tree_list (NULL_TREE, TYPE_BINFO (t)); 4535: 4536: /* Make sure this is laid out, for ease of use later. 4537: In the presence of parse errors, the normal was of assuring 4538: this might not ever get executed, so we lay it out *immediately*. */ 4539: build_pointer_type (t); 4540: 4541: #ifdef GATHER_STATISTICS 4542: tree_node_counts[(int)lang_type] += 1; 4543: tree_node_sizes[(int)lang_type] += sizeof(struct lang_type); 4544: #endif 4545: 4546: return t; 4547: } 4548: 4549: void 4550: copy_decl_lang_specific (decl) 4551: tree decl; 4552: { 4553: extern struct obstack *current_obstack, *saveable_obstack; 4554: register int *old = (int *)DECL_LANG_SPECIFIC (decl); 4555: struct obstack *obstack = current_obstack; 4556: register int i = sizeof (struct lang_decl) / sizeof (int); 4557: register int *pi; 4558: 4559: if (! TREE_PERMANENT (decl)) 4560: obstack = saveable_obstack; 4561: else 4562: my_friendly_assert (obstack == &permanent_obstack, 237); 4563: 4564: pi = (int *) obstack_alloc (obstack, sizeof (struct lang_decl)); 4565: while (i-- > 0) 4566: pi[i] = old[i]; 4567: 4568: DECL_LANG_SPECIFIC (decl) = (struct lang_decl *) pi; 4569: 4570: #ifdef GATHER_STATISTICS 4571: tree_node_counts[(int)lang_decl] += 1; 4572: tree_node_sizes[(int)lang_decl] += sizeof(struct lang_decl); 4573: #endif 4574: } 4575: 4576: void 4577: dump_time_statistics () 4578: { 4579: register tree prev = 0, decl, next; 4580: int this_time = my_get_run_time (); 4581: TREE_INT_CST_LOW (IDENTIFIER_LOCAL_VALUE (this_filename_time)) 4582: += this_time - body_time; 4583: 4584: fprintf (stderr, "\n******\n"); 4585: print_time ("header files (total)", header_time); 4586: print_time ("main file (total)", this_time - body_time); 4587: fprintf (stderr, "ratio = %g : 1\n", 4588: (double)header_time / (double)(this_time - body_time)); 4589: fprintf (stderr, "\n******\n"); 4590: 4591: for (decl = filename_times; decl; decl = next) 4592: { 4593: next = IDENTIFIER_GLOBAL_VALUE (decl); 4594: IDENTIFIER_GLOBAL_VALUE (decl) = prev; 4595: prev = decl; 4596: } 4597: 4598: for (decl = prev; decl; decl = IDENTIFIER_GLOBAL_VALUE (decl)) 4599: print_time (IDENTIFIER_POINTER (decl), 4600: TREE_INT_CST_LOW (IDENTIFIER_LOCAL_VALUE (decl))); 4601: } 4602: 4603: void 4604: compiler_error (s, v, v2) 4605: char *s; 4606: HOST_WIDE_INT v, v2; /* @@also used as pointer */ 4607: { 4608: char buf[1024]; 4609: sprintf (buf, s, v, v2); 4610: error_with_file_and_line (input_filename, lineno, "%s (compiler error)", buf); 4611: } 4612: 4613: void 4614: compiler_error_with_decl (decl, s) 4615: tree decl; 4616: char *s; 4617: { 4618: char *name; 4619: count_error (0); 4620: 4621: report_error_function (0); 4622: 4623: if (TREE_CODE (decl) == PARM_DECL) 4624: fprintf (stderr, "%s:%d: ", 4625: DECL_SOURCE_FILE (DECL_CONTEXT (decl)), 4626: DECL_SOURCE_LINE (DECL_CONTEXT (decl))); 4627: else 4628: fprintf (stderr, "%s:%d: ", 4629: DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl)); 4630: 4631: name = lang_printable_name (decl); 4632: if (name) 4633: fprintf (stderr, s, name); 4634: else 4635: fprintf (stderr, s, "((anonymous))"); 4636: fprintf (stderr, " (compiler error)\n"); 4637: } 4638: 4639: void 4640: yyerror (string) 4641: char *string; 4642: { 4643: extern int end_of_file; 4644: char buf[200]; 4645: 4646: strcpy (buf, string); 4647: 4648: /* We can't print string and character constants well 4649: because the token_buffer contains the result of processing escapes. */ 4650: if (end_of_file) 4651: strcat (buf, input_redirected () 4652: ? " at end of saved text" 4653: : " at end of input"); 4654: else if (token_buffer[0] == 0) 4655: strcat (buf, " at null character"); 4656: else if (token_buffer[0] == '"') 4657: strcat (buf, " before string constant"); 4658: else if (token_buffer[0] == '\'') 4659: strcat (buf, " before character constant"); 4660: else if (token_buffer[0] < 040 || (unsigned char) token_buffer[0] >= 0177) 4661: sprintf (buf + strlen (buf), " before character 0%o", 4662: (unsigned char) token_buffer[0]); 4663: else 4664: strcat (buf, " before `%s'"); 4665: 4666: error (buf, token_buffer); 4667: } 1.1.1.2 ! root 4668: ! 4669: #ifdef HANDLE_SYSV_PRAGMA ! 4670: ! 4671: /* Handle a #pragma directive. INPUT is the current input stream, ! 4672: and C is a character to reread. Processes the entire input line ! 4673: and returns a character for the caller to reread: either \n or EOF. */ ! 4674: ! 4675: /* This function has to be in this file, in order to get at ! 4676: the token types. */ ! 4677: ! 4678: handle_sysv_pragma () ! 4679: { ! 4680: for (;;) ! 4681: { ! 4682: switch (yylex ()) ! 4683: { ! 4684: case IDENTIFIER: ! 4685: case TYPENAME: ! 4686: case STRING: ! 4687: case CONSTANT: ! 4688: handle_pragma_token ("ignored", yylval.ttype); ! 4689: break; ! 4690: case '(': ! 4691: handle_pragma_token ("(", NULL_TREE); ! 4692: break; ! 4693: case ')': ! 4694: handle_pragma_token (")", NULL_TREE); ! 4695: break; ! 4696: case ',': ! 4697: handle_pragma_token (",", NULL_TREE); ! 4698: break; ! 4699: case '=': ! 4700: handle_pragma_token ("=", NULL_TREE); ! 4701: break; ! 4702: case LEFT_RIGHT: ! 4703: handle_pragma_token ("(", NULL_TREE); ! 4704: handle_pragma_token (")", NULL_TREE); ! 4705: break; ! 4706: case END_OF_LINE: ! 4707: handle_pragma_token (NULL_PTR, NULL_TREE); ! 4708: return; ! 4709: default: ! 4710: handle_pragma_token (NULL_PTR, NULL_TREE); ! 4711: while (yylex () != END_OF_LINE) ! 4712: /* continue */; ! 4713: return; ! 4714: } ! 4715: } ! 4716: } ! 4717: #endif /* HANDLE_SYSV_PRAGMA */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.