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