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