From 0e5921e8a0f347a7de29c7347738db8de5769a88 Mon Sep 17 00:00:00 2001 From: Zack Weinberg Date: Thu, 7 Sep 2000 00:37:14 +0000 Subject: Integrated preprocessor. top level: * Makefile.in: Remove all references to c-parse.gperf, c-gperf.h, and c-parse.h. Remove -d from yacc command line generating c-parse.c. Update dependencies. * c-parse.gperf, c-gperf.h: Delete. * c-common.c: Don't define parse_options, cpp_token, yy_cur, yy_lim, or yy_get_token. Don't define get_directive_line if USE_CPPLIB. * c-common.h: Add multiple include guard. Define RID values for every keyword in C, C++, and Objective C. Put all the modifiers first. (struct c_fileinfo, get_fileinfo, dump_time_statistics): New. * c-decl.c (c_decode_option): Handle -lang-objc here. (print_lang_identifier): Handle C_IS_RESERVED_WORD case. (grokdeclarator): Adjust for new RID scheme. (extract_interface_info): New stub. * c-lang.c: Don't declare yy_cur or parse_options. (lang_init_options): Call cpp_init. Don't call cpp_options_init. (lang_init): Don't call check_newline if USE_CPPLIB. * c-lex.c: Don't include c-parse.h. Do include timevar.h. Elide lots of unnecessary code if USE_CPPLIB. Delete code rendered unnecessary by new architecture. Move routines not shared with C++ to c-parse.in. Maintain a local idea of the line number. Handle C++ as well as C. [USE_CPPLIB]: Declare and register callbacks for #ident and for entering/leaving files. (init_c_lex, c_lex): Are now the entry points to this file. (check_newline): Break out directive handling to process_directive. (read_ucs, is_extended_char, utf8_extend_token): Moved here from C++ front end. (readescape, parse_float): Overhaul. (lex_number, lex_string, lex_charconst): Break out of c_lex (n'ee yylex). (get_fileinfo, update_header_times, dump_one_header, dump_time_statistics): New and/or moved here from C++. Support per-file data needed by C++ and per-header timing statistics (C++ only, at the moment). * c-lex.h: Update prototypes. Add multiple include guard. * c-tree.h (struct lang_identifier): Add rid_code field. (C_IS_RESERVED_WORD, C_RID_CODE): New. * c-parse.in: Include c-pragma.h. Remove unnecesary calls to reinit_parse_for_function and/or position_after_white_space. (save_filename, save_lineno): Look ahead before saving. (label -> identifier ':'): Save file and line before shifting ':'. (reservedwords): No need to call get_identifier. (init_parse, finish_parse, yyerror, yylex, yyprint, make_pointer_declarator): Are now here for C/ObjC. (rid_to_yy): Conversion table from RID constants to Yacc codes. * c-pragma.c: Rewrite parsing logic to fit with cpplib's #pragma registry. Provide dummy implementation of that interface if !USE_CPPLIB. * c-pragma.h: Update to match. * flags.h: Add multiple include guard. (flag_detailed_statistics): Moved here from C++. * toplev.c: Define flag_detailed_statistics. * gcc.c (C specs): Use %(trad_capable_cpp) for -E|-M|-MM case #if USE_CPPLIB. * timevar.def (TV_CPP, TV_LEX): New. * timevar.h: Add multiple include guard. * objc/lang-specs.h: Use %(trad_capable_cpp) for -E|-M|-MM case #if USE_CPPLIB. * objc/objc-act.c: Don't mention yy_cur or parse_options. Initialize cpplib properly. Force lineno to 0 after first call to check_newline. Don't handle -lang-objc here. Move forget_protocol_qualifiers and remember_protocol_qualifiers here. cp: * Make-lang.in, Makefile.in: Remove all references to input.c, gxx.gperf, and hash.h. Add ../c-lex.o to C_OBJS. * gxx.gperf, hash.h, input.c: Delete. * lang-specs.h: Pass -lang-c++ to cc1plus so cpplib is initialized properly. * class.c (fixup_pending_inline): Take a tree, not a struct pending_inline *. All callers changed. (init_class_processing): Set RID_PUBLIC, RID_PRIVATE, RID_PROTECTED entries in ridpointers[] array here. * decl.c (duplicate_decls): Do not refer to struct pending_inline. (record_builtin_type, init_decl_processing): Use RID_MAX not CP_RID_MAX. (grokdeclarator): Use C_IS_RESERVED_WORD. * decl2.c (lang_decode_option): Ignore -lang-c++ for sake of cpplib. (grok_x_components): Do not inspect pending_inlines chain. * cp-tree.h (struct lang_identifier): Add rid_code entry. (C_IS_RESERVED_WORD, C_RID_CODE, C_RID_YYCODE): New. (flag_no_gnu_keywords, flag_operator_names, rid_to_yy): Declare. (DEFARG_LENGTH, struct pending_inline, TIME_IDENTIFIER_TIME, TIME_IDENTIFIER_FILEINFO): Kill. Update prototypes. * lex.h: Expunge cp_rid. Rewrite RIDBIT macros to use just a single 32-bit word. * parse.y: Call do_pending_inlines unconditionally. reinit_parse_for_method is now snarf_method. fn.defpen is no longer necessary. Remove unnecessary annotation on SCOPE. Do not refer to end_of_file or struct pending_inline. * semantics.c (begin_inline_definitions): Call do_pending_inlines unconditionally. * lex.c: Remove all code now shared with C front end. Initialize cpplib properly if USE_CPPLIB. Put reserved words into the get_identifier table. Rewrite pragma handling to work with the registry. Move code to save tokens for later processing to spew.c. * spew.c: Rewrite everything in terms of token streams instead of text. Move routines here from lex.c / input.c as appropriate. GC-mark trees hanging off the pending inlines chain. testsuite: * g++.old-deja/g++.benjamin/13478.C: Put meaningful tags on ERROR markers. * g++.old-deja/g++.brendan/crash8.C: Move ERROR marker up one line. * gcc.dg/c99-array-nonobj-1.c: Don't expect func[] cases to fail. * gcc.dg/wtr-label-1.c: Don't use unconstrained .* in error regexps. * gcc.dg/wtr-suffix-1.c: Correct error regexps. * gcc.dg/cpp/unc1.c, gcc.dg/cpp/unc2.c, gcc.dg/cpp/unc3.c: Preprocess only. * gcc.dg/cpp/unc4.c: Adjust line number in dg-error line. * gcc.dg/noncompile/const-ll-1.c: Generalize error regexp. From-SVN: r36216 --- gcc/ChangeLog | 166 +- gcc/Makefile.in | 30 +- gcc/c-common.c | 104 +- gcc/c-common.h | 123 +- gcc/c-decl.c | 89 +- gcc/c-gperf.h | 252 -- gcc/c-lang.c | 10 +- gcc/c-lex.c | 3469 +++++++++--------- gcc/c-lex.h | 12 +- gcc/c-parse.gperf | 105 - gcc/c-parse.in | 686 +++- gcc/c-pragma.c | 563 ++- gcc/c-pragma.h | 43 +- gcc/c-tree.h | 15 +- gcc/cp/ChangeLog | 427 ++- gcc/cp/Make-lang.in | 6 +- gcc/cp/Makefile.in | 14 +- gcc/cp/class.c | 21 +- gcc/cp/cp-tree.h | 78 +- gcc/cp/decl.c | 40 +- gcc/cp/decl2.c | 14 +- gcc/cp/gxx.gperf | 116 - gcc/cp/hash.h | 257 -- gcc/cp/input.c | 240 -- gcc/cp/lang-specs.h | 4 +- gcc/cp/lex.c | 4279 +++-------------------- gcc/cp/lex.h | 52 +- gcc/cp/parse.y | 45 +- gcc/cp/semantics.c | 3 +- gcc/cp/spew.c | 1311 ++++++- gcc/flags.h | 9 + gcc/gcc.c | 4 +- gcc/objc/Make-lang.in | 5 +- gcc/objc/lang-specs.h | 2 +- gcc/objc/objc-act.c | 51 +- gcc/testsuite/ChangeLog | 17 +- gcc/testsuite/g++.old-deja/g++.benjamin/13478.C | 4 +- gcc/testsuite/g++.old-deja/g++.brendan/crash8.C | 4 +- gcc/testsuite/gcc.dg/c99-array-nonobj-1.c | 4 +- gcc/testsuite/gcc.dg/cpp/unc1.c | 1 + gcc/testsuite/gcc.dg/cpp/unc2.c | 1 + gcc/testsuite/gcc.dg/cpp/unc3.c | 1 + gcc/testsuite/gcc.dg/cpp/unc4.c | 2 +- gcc/testsuite/gcc.dg/noncompile/const-ll-1.c | 2 +- gcc/testsuite/gcc.dg/wtr-label-1.c | 12 +- gcc/testsuite/gcc.dg/wtr-suffix-1.c | 14 +- gcc/timevar.def | 2 + gcc/timevar.h | 5 + gcc/toplev.c | 4 + 49 files changed, 5092 insertions(+), 7626 deletions(-) delete mode 100644 gcc/c-gperf.h delete mode 100644 gcc/c-parse.gperf delete mode 100644 gcc/cp/gxx.gperf delete mode 100644 gcc/cp/hash.h delete mode 100644 gcc/cp/input.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5f18e6de..0ac5556 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,81 @@ +2000-09-06 Zack Weinberg + + Integrated preprocessor. + + * Makefile.in: Remove all references to c-parse.gperf, + c-gperf.h, and c-parse.h. Remove -d from yacc command line + generating c-parse.c. Update dependencies. + * c-parse.gperf, c-gperf.h: Delete. + + * c-common.c: Don't define parse_options, cpp_token, yy_cur, + yy_lim, or yy_get_token. Don't define get_directive_line if + USE_CPPLIB. + * c-common.h: Add multiple include guard. Define RID values + for every keyword in C, C++, and Objective C. Put all the + modifiers first. + (struct c_fileinfo, get_fileinfo, dump_time_statistics): New. + * c-decl.c (c_decode_option): Handle -lang-objc here. + (print_lang_identifier): Handle C_IS_RESERVED_WORD case. + (grokdeclarator): Adjust for new RID scheme. + (extract_interface_info): New stub. + * c-lang.c: Don't declare yy_cur or parse_options. + (lang_init_options): Call cpp_init. Don't call + cpp_options_init. + (lang_init): Don't call check_newline if USE_CPPLIB. + + * c-lex.c: Don't include c-parse.h. Do include timevar.h. + Elide lots of unnecessary code if USE_CPPLIB. Delete code + rendered unnecessary by new architecture. Move routines not + shared with C++ to c-parse.in. Maintain a local idea of the + line number. Handle C++ as well as C. + [USE_CPPLIB]: Declare and register callbacks for #ident and + for entering/leaving files. + (init_c_lex, c_lex): Are now the entry points to this file. + (check_newline): Break out directive handling to + process_directive. + (read_ucs, is_extended_char, utf8_extend_token): Moved here + from C++ front end. + (readescape, parse_float): Overhaul. + (lex_number, lex_string, lex_charconst): Break out of c_lex + (n'ee yylex). + (get_fileinfo, update_header_times, dump_one_header, + dump_time_statistics): New and/or moved here from C++. + Support per-file data needed by C++ and per-header timing + statistics (C++ only, at the moment). + * c-lex.h: Update prototypes. Add multiple include guard. + * c-tree.h (struct lang_identifier): Add rid_code field. + (C_IS_RESERVED_WORD, C_RID_CODE): New. + + * c-parse.in: Include c-pragma.h. Remove unnecesary calls to + reinit_parse_for_function and/or position_after_white_space. + (save_filename, save_lineno): Look ahead before saving. + (label -> identifier ':'): Save file and line before shifting ':'. + (reservedwords): No need to call get_identifier. + (init_parse, finish_parse, yyerror, yylex, yyprint, + make_pointer_declarator): Are now here for C/ObjC. + (rid_to_yy): Conversion table from RID constants to Yacc codes. + + * c-pragma.c: Rewrite parsing logic to fit with cpplib's + #pragma registry. Provide dummy implementation of that + interface if !USE_CPPLIB. + * c-pragma.h: Update to match. + + * flags.h: Add multiple include guard. + (flag_detailed_statistics): Moved here from C++. + * toplev.c: Define flag_detailed_statistics. + + * gcc.c (C specs): Use %(trad_capable_cpp) for -E|-M|-MM case + #if USE_CPPLIB. + * timevar.def (TV_CPP, TV_LEX): New. + * timevar.h: Add multiple include guard. + + * objc/lang-specs.h: Use %(trad_capable_cpp) for -E|-M|-MM case + #if USE_CPPLIB. + * objc/objc-act.c: Don't mention yy_cur or parse_options. + Initialize cpplib properly. Force lineno to 0 after first + call to check_newline. Don't handle -lang-objc here. + Move forget_protocol_qualifiers and remember_protocol_qualifiers here. + 2000-09-06 David Edelsohn * rs6000.md: Correct function unit definitions for cr_logical and @@ -171,8 +249,8 @@ 2000-09-05 Bruce Korb - * fixinc/fixincl.c (load_file): always read header files - with sizes that are a multiple of the page size. + * fixinc/fixincl.c (load_file): always read header files + with sizes that are a multiple of the page size. & use libiberty's getpagesize for determining that. 2000-09-05 Alexandre Oliva @@ -202,7 +280,7 @@ Wed Jan 1 00:23:59 MET 1997 Jan Hubicka Wed Jan 1 00:17:32 MET 1997 Jan Hubicka - * i386.md (pushsi2, pushhi2, pophi2, swapsf, swapdf, + * i386.md (pushsi2, pushhi2, pophi2, swapsf, swapdf, umulsi3_highpart, smulsi3_highpart, testqi_ccno_1, xorqi_ext_1): Add '*' to insn pattern name. @@ -222,7 +300,7 @@ Wed Jan 1 00:17:32 MET 1997 Jan Hubicka 2000-09-03 Richard Earnshaw - * arm.c (final_prescan_insn): If the form of a jump insn isn't + * arm.c (final_prescan_insn): If the form of a jump insn isn't recognized, don't try to conditionally execute it. Sun Sep 3 13:10:56 2000 Denis Chertykov @@ -316,7 +394,7 @@ Sat Sep 2 13:58:23 2000 Marek Michalkiewicz (prepare_move_operands): Call emit_pic_move or emit_pic_const_move if appropriate. (output_far_jump): For PIC, use braf and output long offset. - (machine_dependent_reorg): + (machine_dependent_reorg): (sh_expand_prologue): Save and initialize the PIC register. (sh_expand_epilogue): Restore it. (initial_elimination_offset): Account for it. @@ -349,7 +427,7 @@ Sat Sep 2 13:58:23 2000 Marek Michalkiewicz * fix-header.c (write_rbrac): Add putc and getc to list of functions to protect against prior definition as a macro. - + 2000-09-01 Joseph S. Myers * c-common.h (enum c_tree_index): Add CTI_C_SIZE_TYPE. @@ -414,18 +492,18 @@ Fri Sep 1 10:59:47 2000 Richard Kenner 2000-09-01 Andrew Haley - * dwarf2out.c (stack_adjust_offset): New function. - (dwarf2out_stack_adjust): Break out stack adjust logic into - new stack_adjust_offset function. Look inside parallels and - sequences for stack adjustments. + * dwarf2out.c (stack_adjust_offset): New function. + (dwarf2out_stack_adjust): Break out stack adjust logic into + new stack_adjust_offset function. Look inside parallels and + sequences for stack adjustments. 2000-08-31 Jeff Law * arm.md: Use no_new_pseudos to determine when it is safe to create new pseudo registers. - * arm.c (legitimize_pic_address): Use no_new_pseudos to determine - when we can safely allocate new registers. + * arm.c (legitimize_pic_address): Use no_new_pseudos to determine + when we can safely allocate new registers. 2000-08-31 Geoffrey Keating @@ -441,7 +519,7 @@ Fri Sep 1 10:59:47 2000 Richard Kenner * toplev.c (rest_of_compilation): No CONCATs after RTL generation. 2000-08-22 Philipp Thomas - Masanobu Yuhara + Masanobu Yuhara * gmicro.h (TARGET_SWITCHES): Add descriptions and mark them for translation. @@ -496,7 +574,7 @@ Tue Aug 29 22:09:59 2000 Richard Kenner * c-common.c (declare_function_name): Use func_id_node, function_id_node, and pretty_function_id_node. Do not make - __func__ visible at file scope. + __func__ visible at file scope. * c-common.h (c_tree_index): Add CTI_FUNCTION_ID, CTI_PRETTY_FUNCTION_ID, and CTI_FUNC_ID. (function_id_node, pretty_function_id_node, func_id_node): New @@ -509,7 +587,7 @@ Tue Aug 29 22:09:59 2000 Richard Kenner * c-decl.c (pushdecl, implicit_decl_warning): Constify a char *. * c-pragma.h (struct weak_syms): Constify name and value members. - (add_weak): Constify arguments. + (add_weak): Constify arguments. * calls.c (special_function_p): Constify a char *. (expand_call): Remove variable which is initialized and then @@ -590,7 +668,7 @@ Tue Aug 29 22:29:58 2000 Denis Chertykov & Marek Michalkiew (output_movqi): New prototype. (output_movhi): New prototype. (call_insn_operand): Likewise. - (final_prescan_insn): Likewise. + (final_prescan_insn): Likewise. (avr_simplify_comparision_p): Likewise. (avr_normalize_condition): Likewise. (compare_eq_p): Likewise. @@ -800,7 +878,7 @@ Tue Aug 29 15:17:54 EDT 2000 John Wehle (john@feith.com) (gen_internal_sym, output_die_symbol, output_symbolic_ref): New fns. (output_die): Call output_die_symbol and AT_ref_external. (output_comdat_comp_unit): New fn, split out from... - (dwarf2out_finish): ...here. Also call add_sibling_attributes for + (dwarf2out_finish): ...here. Also call add_sibling_attributes for secondary CUs. (output_pubnames, output_aranges): Abort if we see entries from secondary CUs. @@ -928,9 +1006,9 @@ Fri Aug 25 12:52:49 EDT 2000 John Wehle (john@feith.com) (flow_loops_find): Call flow_loop_entry_edges_find. (flow_loop_dump): Dump entry_edges list. (flow_loops_free): Free entry_edges. - + 2000-08-26 Michael Hayes - + * loop.c (loop_dump_aux, debug_loop): New functions. (LOOP_BLOCK_NUM_1, LOOP_BLOCK_NUM, LOOP_INSN_UID): New macros. @@ -943,14 +1021,14 @@ Fri Aug 25 12:52:49 EDT 2000 John Wehle (john@feith.com) * toplev.c (rest_of_compilation): Add NULL callback function pointer to call to flow_loops_dump. - + 2000-08-26 Michael Hayes * loop.c (count_loop_regs_set): Replace start and end arguments with loop argument. All callers udated. - + 2000-08-26 Michael Hayes - + * loop.c (constant_high_bytes): Delete. 2000-08-26 Michael Hayes @@ -1000,7 +1078,7 @@ Fri 25-Aug-2000 08:03:27 BST Neil Booth * gcc/c-typeck.c (decl_constant_value): Don't check ITERATOR_P. (readonly_warning): Likewise. * gcc/tree.h (ITERATOR_BOUND_P): Don't mention it. - + 2000-08-24 Jim Wilson * c-common.c (decl_attributes, case A_ALIGN): Revert last change. @@ -1012,7 +1090,7 @@ Fri 25-Aug-2000 08:03:27 BST Neil Booth 2000-08-24 Zack Weinberg - * ggc-page.c (alloc_page): If HAVE_MMAP_ANYWHERE and we're + * ggc-page.c (alloc_page): If HAVE_MMAP_ANYWHERE and we're asked for one page, allocate GGC_QUIRE_SIZE of them and put the extras on the free list. (release_pages): Clean up. @@ -1032,7 +1110,7 @@ Fri 25-Aug-2000 08:03:27 BST Neil Booth (fr_register_operand, grfr_register_operand): New. (gr_nonimmediate_operand, grfr_nonimmediate_operand): New. (grfr_reg_or_8bit_operand): New. - (gr_reg_or_0_operand): Rename from reg_or_0_operand and + (gr_reg_or_0_operand): Rename from reg_or_0_operand and use gr_register_operand. (gr_reg_or_5bit_operand, gr_reg_or_6bit_operand): Likewise. (gr_reg_or_8bit_operand, gr_reg_or_8bit_adjusted_operand): Likewise. @@ -1059,7 +1137,7 @@ Fri 25-Aug-2000 08:03:27 BST Neil Booth * config/ia64/ia64.md (*): Use gr_register_operand and co. (mf): Indicate that we set memory as well as use it. (fetchadd_acq_si): Show memory being modified as well. - (fetchadd_acq_di, cmpxchg_acq_si, cmpxchg_acq_di): Likewise. + (fetchadd_acq_di, cmpxchg_acq_si, cmpxchg_acq_di): Likewise. (val_compare_and_swap_si, val_compare_and_swap_di): Remove. (lock_test_and_set_si, lock_test_and_set_di): Remove. (fetch_and_add_si, fetch_and_sub_si, fetch_and_or_si): Remove. @@ -1082,7 +1160,7 @@ Fri 25-Aug-2000 08:03:27 BST Neil Booth * dwarf2out.c (AT_flag, AT_int, AT_unsigned, AT_string, AT_ref, AT_loc, AT_addr, AT_lbl): Abort on unsuitable input. - (get_AT_low_pc, get_AT_hi_pc, get_AT_string, get_AT_flag, + (get_AT_low_pc, get_AT_hi_pc, get_AT_string, get_AT_flag, get_AT_unsigned, get_AT_ref): Don't call them if get_AT fails. 2000-08-24 Greg McGary @@ -1286,7 +1364,7 @@ Tue Aug 22 21:21:05 2000 J"orn Rennecke (THUMB_FUNCTION_START): New macro: Common code at the start of Thumb functions. (__divsi3, __udivsi3, __modsi3, __umodsi3): Use new macros. - + Tue Aug 22 20:34:52 2000 Kaz Kojima * config/sh/sh.md (cmpeqdi_t splitter): Fix a reverse testing. @@ -1327,7 +1405,7 @@ Tue Aug 22 20:34:52 2000 Kaz Kojima * Makefile.in (OBJS): Add dependence.o. * dependence.c: New file. - + 2000-08-22 Alexandre Oliva , John David Anglin * calls.c (check_sibcall_argument_overlap_1): Adjust for @@ -1459,10 +1537,10 @@ Tue Aug 22 02:31:26 2000 Richard Kenner * mips/linux.h (LINK_SPEC): Use %(endian_spec). * mips/mips.h: Change LINKER_ENDIAN_SPEC to ENDIAN_SPEC - and linker_endian_spec to endian_spec. + and linker_endian_spec to endian_spec. (ENDIAN_SPEC): Add %{EB} and %{EL}. (LINK_SPEC): Remove %{EB} and %{EL}. - (ASM_SPEC): Likewise. Use %(endian_spec). + (ASM_SPEC): Likewise. Use %(endian_spec). 2000-08-21 Joseph S. Myers @@ -1676,7 +1754,7 @@ Fri Aug 18 14:23:18 2000 Richard Kenner (fixup_match_1): Likewise. (fixup_match_1, combine_stack_adjustments_for_block): Add casts to avoid signed/unsigned warnings. - + * function.c (fixup_var_refs_1, case MEM): Update CODE after updating X. @@ -1869,7 +1947,7 @@ Tue Aug 15 17:33:05 2000 Richard Kenner expands. (arm_buneq, arm_bltgt, arm_buneq_reversed, arm_bltgt_reveresed): New patterns. - + Tue Aug 15 00:36:36 2000 Ovidiu Predescu * gthr-posix.h: Conditionally include ; include @@ -1939,7 +2017,7 @@ Tue Aug 15 00:36:36 2000 Ovidiu Predescu 2000-08-14 Kaveh R. Ghazi * cse.c (fold_rtx): Avoid empty body in an if-statement. - + * doloop.c (doloop_iterations_max, doloop_modify): Avoid using the `U' integer constant suffix. @@ -1977,7 +2055,7 @@ Tue Aug 15 00:36:36 2000 Ovidiu Predescu * configure.in: Accept *-*-linux* not just *-*-linux-gnu*. * fixinc/inclhack.def: Likewise. - * fixinc/mkfixinc.sh: Likewise. + * fixinc/mkfixinc.sh: Likewise. * configure: Regenerate. * fixinc/fixincl.x: Regenerate. * install.texi: Document equivalence of linux and linux-gnu. @@ -2067,7 +2145,7 @@ Mon Aug 14 18:51:44 2000 J"orn Rennecke (do_restore): Likewise. (gen_movdi_x, gen_fr_spill_x, gen_fr_restore_x): New. (ia64_expand_prologue, ia64_expand_epilogue): Use them. - (rtx_needs_barrier): Track actual bit manipulation for + (rtx_needs_barrier): Track actual bit manipulation for ar.unat moves, gr_spill, and gr_restore. (emit_insn_group_barriers): Special case gr_spill/gr_restore. (process_set): Don't handle varargs spills. @@ -2080,7 +2158,7 @@ Mon Aug 14 18:51:44 2000 J"orn Rennecke * config/ia64/ia64.h (PROMOTE_MODE): Only extend to SImode. 2000-08-11 Mark Elbrecht - + * gcc.texi (The Configuration File): Document COLLECT2_HOST_INITIALIZATION, GCC_DRIVER_HOST_INITIALIZATION, and UPDATE_PATH_HOST_CANONICALIZATION. @@ -2281,7 +2359,7 @@ Thu Aug 10 00:11:04 2000 Ovidiu Predescu 2000-08-08 David Edelsohn * rs6000.c (optimization_options): Decorate 'level' as - ATTRIBUTE_UNUSED. + ATTRIBUTE_UNUSED. (mask64_operand): Remove sign-extend thinko. (rldic_operand): New function. (load_multiple_operation): regno's are unsigned ints. @@ -2346,7 +2424,7 @@ Thu Aug 10 00:11:04 2000 Ovidiu Predescu (ia64_encode_section_info): Silence signed/unsigned warnings. (spill_offset, sp_offset, spill_offset_emitted): Remove. (tmp_reg, tmp_saved): Remove. - (process_set): Rewrite to expect complicated bits via + (process_set): Rewrite to expect complicated bits via REG_FRAME_RELATED_EXPR. (ia64_expand_fetch_and_op): Use emit_move_insn; be explicit in the use of ar.ccv; never set RTX_UNCHANGING_P. @@ -2436,7 +2514,7 @@ Thu Aug 10 00:11:04 2000 Ovidiu Predescu * mn10300.md: Use nonimmediate_operand instead of general_operand on output operands. - + * mn10300.h (PREFERRED_RELOAD_CLASS): Limit memory reloads. 2000-08-07 Alexandre Oliva @@ -2578,7 +2656,7 @@ Sun Aug 6 00:54:42 2000 Ovidiu Predescu * tree.c (tree_expr_nonnegative_p): Move to... * fold-const.c: ... here. Also handle BIND_EXPR and RTL_EXPR. - (rtl_expr_nonnegative_p): New. + (rtl_expr_nonnegative_p): New. * tree.h: Add prototype for rtl_expr_nonnegative_p. * real.h (CONST_DOUBLE_LOW, CONST_DOUBLE_HIGH, CONST_DOUBLE_MEM, @@ -2880,9 +2958,9 @@ Fri Aug 4 11:43:49 2000 John Wehle (john@feith.com) Fri Aug 4 06:53:46 2000 Clinton Popetz - * (mips_legitimate_address_p): Don't allow register+offset - if the offset is large and negative, and we are compiling - for 64 bit registers. + * (mips_legitimate_address_p): Don't allow register+offset + if the offset is large and negative, and we are compiling + for 64 bit registers. 2000-08-04 Herman A.J. ten Brugge diff --git a/gcc/Makefile.in b/gcc/Makefile.in index b07034f..baa7b9d 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -1080,13 +1080,12 @@ s-crt0: $(CRT0_S) $(MCRT0_S) $(GCC_PASSES) $(CONFIG_H) c-errors.o: c-errors.c $(CONFIG_H) system.h $(TREE_H) c-tree.h flags.h \ diagnostic.h -c-parse.o : $(srcdir)/c-parse.c $(CONFIG_H) $(TREE_H) c-lex.h $(GGC_H) \ - $(srcdir)/c-parse.h c-tree.h c-common.h input.h flags.h system.h \ - toplev.h output.h +c-parse.o : $(srcdir)/c-parse.c $(CONFIG_H) $(TREE_H) c-lex.h $(GGC_H) intl.h \ + c-tree.h c-common.h input.h flags.h system.h toplev.h output.h cpplib.h $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) -c $(srcdir)/c-parse.c -$(srcdir)/c-parse.h: $(srcdir)/c-parse.c + $(srcdir)/c-parse.c: $(srcdir)/c-parse.y - cd $(srcdir); $(BISON) $(BISONFLAGS) -d -o c-parse.c c-parse.y + cd $(srcdir); $(BISON) $(BISONFLAGS) -o c-parse.c c-parse.y $(srcdir)/c-parse.y: c-parse.in echo '/*WARNING: This file is automatically generated!*/' >tmp-c-parse.y sed -e "/^ifobjc$$/,/^end ifobjc$$/d" \ @@ -1094,13 +1093,6 @@ $(srcdir)/c-parse.y: c-parse.in $(srcdir)/c-parse.in >>tmp-c-parse.y $(SHELL) $(srcdir)/move-if-change tmp-c-parse.y $(srcdir)/c-parse.y -$(srcdir)/c-gperf.h: c-parse.gperf - gperf -L C -F ', 0, 0' -p -j1 -i 1 -g -o -t -G -N is_reserved_word \ - -k1,3,$$ $(srcdir)/c-parse.gperf >tmp-gperf.h || ( \ - echo "See $(website)/cvs.html#generated_files" >&2 ; \ - exit 1 ) - $(SHELL) $(srcdir)/move-if-change tmp-gperf.h $(srcdir)/c-gperf.h - c-decl.o : c-decl.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) c-tree.h \ c-common.h $(GGC_H) c-lex.h flags.h function.h output.h $(EXPR_H) \ toplev.h defaults.h intl.h @@ -1109,8 +1101,8 @@ c-typeck.o : c-typeck.c $(CONFIG_H) system.h $(TREE_H) c-tree.h c-common.h \ c-lang.o : c-lang.c $(CONFIG_H) system.h $(TREE_H) c-tree.h c-common.h \ $(GGC_H) c-lex.h toplev.h diagnostic.h output.h function.h c-lex.o : c-lex.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) c-lex.h c-tree.h \ - c-common.h $(srcdir)/c-parse.h $(srcdir)/c-gperf.h c-pragma.h input.h \ - intl.h flags.h toplev.h output.h mbchar.h $(GGC_H) + c-common.h c-pragma.h input.h intl.h flags.h toplev.h output.h \ + mbchar.h $(GGC_H) cpplib.h $(SPLAY_TREE_H) c-aux-info.o : c-aux-info.c $(CONFIG_H) system.h $(TREE_H) c-tree.h \ c-common.h flags.h toplev.h c-convert.o : c-convert.c $(CONFIG_H) system.h $(TREE_H) flags.h toplev.h @@ -1769,8 +1761,7 @@ intl.o: intl.c intl.h gansidecl.h Makefile $(top_builddir)/intl/libintl.a: intl.all # Make sure all the headers are there for xgettext to scan. -$(INTL_TARGETS): $(srcdir)/c-gperf.h \ - $(srcdir)/c-parse.c $(srcdir)/c-parse.h +$(INTL_TARGETS): $(srcdir)/c-parse.c intl.all intl.install intl.uninstall intl.distdir \ intl.mostlyclean intl.clean intl.distclean intl.maintainer-clean: @@ -2238,8 +2229,7 @@ maintainer-clean: @echo 'deletes files that may need special tools to rebuild.' $(MAKE) INTL_DISTCLEAN= INTL_CLEAN= INTL_MOSTLYCLEAN= \ intl.maintainer-clean lang.maintainer-clean distclean - -rm -f c-parse.y c-gperf.h - -rm -f c-parse.c c-parse.h c-parse.output TAGS + -rm -f c-parse.y c-parse.c c-parse.output TAGS -rm -f cpp.info* cpp.??s cpp.*aux -rm -f gcc.info* gcc.??s gcc.*aux # @@ -2681,7 +2671,7 @@ distdir-cvs: force # This target exists to do the initial work before the language specific # stuff gets done. -distdir-start: doc $(srcdir)/INSTALL $(srcdir)/c-parse.y $(srcdir)/c-gperf.h \ +distdir-start: doc $(srcdir)/INSTALL $(srcdir)/c-parse.y \ $(srcdir)/c-parse.c $(srcdir)/config.in $(srcdir)/version.c TAGS @case '$(USE_NLS)' in \ yes) ;; \ @@ -2760,7 +2750,7 @@ distdir: distdir-cvs distdir-start intl.distdir intl.distdir-fixup \ # creates a diff file between an older distribution and this one. # The -P option assumes this is GNU diff. diff: - diff -rc2P -x c-parse.y -x c-parse.c -x c-parse.h -x c-gperf.h \ + diff -rc2P -x c-parse.y -x c-parse.c \ -x TAGS -x INSTALL -x configure -x config.in \ -x "gcc.??" -x "gcc.??s" -x gcc.aux -x "gcc.info*" \ -x "cpp.??" -x "cpp.??s" -x cpp.aux -x "cpp.info*" \ diff --git a/gcc/c-common.c b/gcc/c-common.c index 9c65647..efb81a3 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -35,8 +35,6 @@ Boston, MA 02111-1307, USA. */ #if USE_CPPLIB #include "cpplib.h" cpp_reader parse_in; -cpp_options parse_options; -enum cpp_token cpp_token; #endif #undef WCHAR_TYPE_SIZE @@ -3518,105 +3516,7 @@ truthvalue_conversion (expr) return build_binary_op (NE_EXPR, expr, integer_zero_node, 1); } -#if USE_CPPLIB -/* Read the rest of a #-directive from input stream FINPUT. - In normal use, the directive name and the white space after it - have already been read, so they won't be included in the result. - We allow for the fact that the directive line may contain - a newline embedded within a character or string literal which forms - a part of the directive. - - The value is a string in a reusable buffer. It remains valid - only until the next time this function is called. */ -unsigned char *yy_cur, *yy_lim; - -#define GETC() (yy_cur < yy_lim ? *yy_cur++ : yy_get_token ()) -#define UNGETC(c) ((c) == EOF ? 0 : yy_cur--) - -int -yy_get_token () -{ - for (;;) - { - parse_in.limit = parse_in.token_buffer; - cpp_token = cpp_get_token (&parse_in); - if (cpp_token == CPP_EOF) - return -1; - yy_lim = CPP_PWRITTEN (&parse_in); - yy_cur = parse_in.token_buffer; - if (yy_cur < yy_lim) - return *yy_cur++; - } -} - -char * -get_directive_line () -{ - static char *directive_buffer = NULL; - static unsigned buffer_length = 0; - register char *p; - register char *buffer_limit; - register int looking_for = 0; - register int char_escaped = 0; - - if (buffer_length == 0) - { - directive_buffer = (char *)xmalloc (128); - buffer_length = 128; - } - - buffer_limit = &directive_buffer[buffer_length]; - - for (p = directive_buffer; ; ) - { - int c; - - /* Make buffer bigger if it is full. */ - if (p >= buffer_limit) - { - register unsigned bytes_used = (p - directive_buffer); - - buffer_length *= 2; - directive_buffer - = (char *)xrealloc (directive_buffer, buffer_length); - p = &directive_buffer[bytes_used]; - buffer_limit = &directive_buffer[buffer_length]; - } - - c = GETC (); - - /* Discard initial whitespace. */ - if ((c == ' ' || c == '\t') && p == directive_buffer) - continue; - - /* Detect the end of the directive. */ - if (c == '\n' && looking_for == 0) - { - UNGETC (c); - c = '\0'; - } - - *p++ = c; - - if (c == 0) - return directive_buffer; - - /* Handle string and character constant syntax. */ - if (looking_for) - { - if (looking_for == c && !char_escaped) - looking_for = 0; /* Found terminator... stop looking. */ - } - else - if (c == '\'' || c == '"') - looking_for = c; /* Don't stop buffering until we see another - another one of these (or an EOF). */ - - /* Handle backslash. */ - char_escaped = (c == '\\' && ! char_escaped); - } -} -#else +#if !USE_CPPLIB /* Read the rest of a #-directive from input stream FINPUT. In normal use, the directive name and the white space after it have already been read, so they won't be included in the result. @@ -3699,7 +3599,7 @@ get_directive_line (finput) char_escaped = (c == '\\' && ! char_escaped); } } -#endif /* !USE_CPPLIB */ +#endif /* USE_CPPLIB */ /* Make a variant type in the proper way for C/C++, propagating qualifiers down to the element type of an array. */ diff --git a/gcc/c-common.h b/gcc/c-common.h index 900b77c..7b4912c 100644 --- a/gcc/c-common.h +++ b/gcc/c-common.h @@ -19,6 +19,9 @@ along with GNU CC; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#ifndef GCC_C_COMMON_H +#define GCC_C_COMMON_H + /* Usage of TREE_LANG_FLAG_?: 0: COMPOUND_STMT_NO_SCOPE (in COMPOUND_STMT). TREE_NEGATED_INT (in INTEGER_CST). @@ -33,52 +36,72 @@ Boston, MA 02111-1307, USA. */ 4: SCOPE_PARTIAL_P (in SCOPE_STMT) */ -/* Reserved identifiers. */ +/* Reserved identifiers. This is the union of all the keywords for C, + C++, and Objective C. All the type modifiers have to be in one + block at the beginning, because they are used as mask bits. There + are 27 type modifiers; if we add many more we will have to redesign + the mask mechanism. */ enum rid { - RID_UNUSED, - RID_INT, - RID_CHAR, - RID_FLOAT, - RID_DOUBLE, - RID_VOID, - RID_UNUSED1, - - /* The first seven are in the order of most frequently used, - as emiprically determined. */ - RID_FIRST_MODIFIER, - RID_EXTERN = RID_FIRST_MODIFIER, - RID_CONST, - RID_LONG, - RID_TYPEDEF, - RID_UNSIGNED, - RID_SHORT, - RID_INLINE, - RID_AUTO, - RID_STATIC, - RID_REGISTER, - RID_SIGNED, - RID_RESTRICT, - RID_VOLATILE, - RID_BOUNDED, - RID_UNBOUNDED, - RID_NOALIAS, - RID_COMPLEX, - - RID_IN, - RID_OUT, - RID_INOUT, - RID_BYCOPY, - RID_BYREF, - RID_ONEWAY, - RID_ID, - - RID_MAX + /* Modifiers: */ + /* C, in empirical order of frequency. */ + RID_STATIC = 0, + RID_UNSIGNED, RID_LONG, RID_CONST, RID_EXTERN, + RID_REGISTER, RID_TYPEDEF, RID_SHORT, RID_INLINE, + RID_VOLATILE, RID_SIGNED, RID_AUTO, RID_RESTRICT, + + /* C extensions */ + RID_BOUNDED, RID_UNBOUNDED, RID_COMPLEX, + + /* C++ */ + RID_FRIEND, RID_VIRTUAL, RID_EXPLICIT, RID_EXPORT, RID_MUTABLE, + + /* ObjC */ + RID_IN, RID_OUT, RID_INOUT, RID_BYCOPY, RID_BYREF, RID_ONEWAY, + + /* C */ + RID_INT, RID_CHAR, RID_FLOAT, RID_DOUBLE, RID_VOID, + RID_ENUM, RID_STRUCT, RID_UNION, RID_IF, RID_ELSE, + RID_WHILE, RID_DO, RID_FOR, RID_SWITCH, RID_CASE, + RID_DEFAULT, RID_BREAK, RID_CONTINUE, RID_RETURN, RID_GOTO, + RID_SIZEOF, + + /* C extensions */ + RID_ASM, RID_TYPEOF, RID_ALIGNOF, RID_ATTRIBUTE, RID_VA_ARG, + RID_EXTENSION, RID_IMAGPART, RID_REALPART, RID_LABEL, RID_PTRBASE, + RID_PTREXTENT, RID_PTRVALUE, + + /* C++ */ + RID_BOOL, RID_WCHAR, RID_CLASS, + RID_PUBLIC, RID_PRIVATE, RID_PROTECTED, + RID_TEMPLATE, RID_NULL, RID_CATCH, + RID_DELETE, RID_FALSE, RID_NAMESPACE, + RID_NEW, RID_OPERATOR, RID_THIS, + RID_THROW, RID_TRUE, RID_TRY, + RID_TYPENAME, RID_TYPEID, RID_USING, + + /* casts */ + RID_CONSTCAST, RID_DYNCAST, RID_REINTCAST, RID_STATCAST, + + /* alternate spellings */ + RID_AND, RID_AND_EQ, RID_NOT, RID_NOT_EQ, + RID_OR, RID_OR_EQ, RID_XOR, RID_XOR_EQ, + RID_BITAND, RID_BITOR, RID_COMPL, + + /* Objective C */ + RID_ID, RID_AT_ENCODE, RID_AT_END, + RID_AT_CLASS, RID_AT_ALIAS, RID_AT_DEFS, + RID_AT_PRIVATE, RID_AT_PROTECTED, RID_AT_PUBLIC, + RID_AT_PROTOCOL, RID_AT_SELECTOR, RID_AT_INTERFACE, + RID_AT_IMPLEMENTATION, + + RID_MAX, + + RID_FIRST_MODIFIER = RID_STATIC, + RID_LAST_MODIFIER = RID_ONEWAY }; -#define NORID RID_UNUSED - /* The elements of `ridpointers' are identifier nodes for the reserved type names and storage classes. It is indexed by a RID_... value. */ extern tree *ridpointers; @@ -523,3 +546,21 @@ extern tree default_conversion PARAMS ((tree)); extern tree common_type PARAMS ((tree, tree)); extern tree expand_tree_builtin PARAMS ((tree, tree, tree)); + +/* Hook currently used only by the C++ front end to reset internal state + after entering or leaving a header file. */ +extern void extract_interface_info PARAMS ((void)); + +/* Information recorded about each file examined during compilation. */ + +struct c_fileinfo +{ + int time; /* Time spent in the file. */ + short interface_only; /* Flags - used only by C++ */ + short interface_unknown; +}; + +struct c_fileinfo *get_fileinfo PARAMS ((const char *)); +extern void dump_time_statistics PARAMS ((void)); + +#endif diff --git a/gcc/c-decl.c b/gcc/c-decl.c index a8cd0a3..af9428b 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -503,7 +503,9 @@ c_decode_option (argc, argv) strings_processed = 0; #endif /* ! USE_CPPLIB */ - if (!strcmp (p, "-ftraditional") || !strcmp (p, "-traditional")) + if (!strcmp (p, "-lang-objc")) + c_language = clk_objective_c; + else if (!strcmp (p, "-ftraditional") || !strcmp (p, "-traditional")) { flag_traditional = 1; flag_writable_strings = 1; @@ -845,6 +847,14 @@ print_lang_identifier (file, node, indent) print_node (file, "implicit", IDENTIFIER_IMPLICIT_DECL (node), indent + 4); print_node (file, "error locus", IDENTIFIER_ERROR_LOCUS (node), indent + 4); print_node (file, "limbo value", IDENTIFIER_LIMBO_VALUE (node), indent + 4); + if (C_IS_RESERVED_WORD (node)) + { + tree rid = ridpointers[C_RID_CODE (node)]; + indent_to (file, indent + 4); + fprintf (file, "rid "); + fprintf (file, HOST_PTR_PRINTF, (void *)rid); + fprintf (file, " \"%s\"", IDENTIFIER_POINTER (rid)); + } } /* Hook called at end of compilation to assume 1 elt @@ -2896,6 +2906,7 @@ lookup_name (name) tree name; { register tree val; + if (current_binding_level != global_binding_level && IDENTIFIER_LOCAL_VALUE (name)) val = IDENTIFIER_LOCAL_VALUE (name); @@ -3986,7 +3997,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized) for (spec = declspecs; spec; spec = TREE_CHAIN (spec)) { - register int i; register tree id = TREE_VALUE (spec); if (id == ridpointers[(int) RID_INT]) @@ -3994,29 +4004,29 @@ grokdeclarator (declarator, declspecs, decl_context, initialized) if (id == ridpointers[(int) RID_CHAR]) explicit_char = 1; - if (TREE_CODE (id) == IDENTIFIER_NODE) - for (i = (int) RID_FIRST_MODIFIER; i < (int) RID_MAX; i++) - { - if (ridpointers[i] == id) - { - if (i == (int) RID_LONG && specbits & (1 << i)) - { - if (longlong) - error ("`long long long' is too long for GCC"); - else - { - if (pedantic && !flag_isoc99 && ! in_system_header - && warn_long_long) - pedwarn ("ISO C89 does not support `long long'"); - longlong = 1; - } - } - else if (specbits & (1 << i)) - pedwarn ("duplicate `%s'", IDENTIFIER_POINTER (id)); - specbits |= 1 << i; - goto found; - } - } + if (TREE_CODE (id) == IDENTIFIER_NODE && C_IS_RESERVED_WORD (id)) + { + enum rid i = C_RID_CODE (id); + if (i <= RID_LAST_MODIFIER) + { + if (i == RID_LONG && specbits & (1< 1 && ! flag_isoc99) pedwarn ("duplicate `const'"); if (volatilep > 1 && ! flag_isoc99) @@ -6990,3 +7005,9 @@ set_current_function_name_declared (i) { abort (); } + +/* Dummy function in place of callback used by C++. */ +void +extract_interface_info () +{ +} diff --git a/gcc/c-gperf.h b/gcc/c-gperf.h deleted file mode 100644 index a864d2e..0000000 --- a/gcc/c-gperf.h +++ /dev/null @@ -1,252 +0,0 @@ -/* C code produced by gperf version 2.7.1 (19981006 egcs) */ -/* Command-line: gperf -L C -F , 0, 0 -p -j1 -i 1 -g -o -t -G -N is_reserved_word -k1,3,$ ../../gcc/c-parse.gperf */ -/* Command-line: gperf -L C -F ', 0, 0' -p -j1 -i 1 -g -o -t -N is_reserved_word -k1,3,$ c-parse.gperf */ -struct resword { const char *name; short token; enum rid rid; }; -#ifdef __GNUC__ -__inline -#endif -static unsigned int hash PARAMS ((const char *, unsigned int)); -#ifdef __GNUC__ -__inline -#endif -struct resword *is_reserved_word PARAMS ((const char *, unsigned int)); - -#define TOTAL_KEYWORDS 92 -#define MIN_WORD_LENGTH 2 -#define MAX_WORD_LENGTH 20 -#define MIN_HASH_VALUE 17 -#define MAX_HASH_VALUE 301 -/* maximum key range = 285, duplicates = 0 */ - -#ifdef __GNUC__ -__inline -#endif -static unsigned int -hash (str, len) - register const char *str; - register unsigned int len; -{ - static unsigned short asso_values[] = - { - 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, - 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, - 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, - 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, - 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, - 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, - 302, 302, 302, 302, 113, 302, 302, 302, 302, 302, - 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, - 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, - 302, 302, 302, 302, 302, 1, 302, 78, 52, 111, - 34, 9, 46, 59, 1, 20, 302, 1, 118, 17, - 18, 39, 58, 302, 7, 6, 33, 70, 21, 2, - 5, 1, 1, 302, 302, 302, 302, 302, 302, 302, - 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, - 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, - 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, - 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, - 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, - 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, - 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, - 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, - 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, - 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, - 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, - 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, - 302, 302, 302, 302, 302, 302 - }; - register int hval = len; - - switch (hval) - { - default: - case 3: - hval += asso_values[(unsigned char)str[2]]; - case 2: - case 1: - hval += asso_values[(unsigned char)str[0]]; - break; - } - return hval + asso_values[(unsigned char)str[len - 1]]; -} - -static struct resword wordlist[] = - { - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"__real__", REALPART, NORID}, - {"__signed__", TYPESPEC, RID_SIGNED}, - {"", 0, 0}, {"", 0, 0}, - {"__restrict__", TYPE_QUAL, RID_RESTRICT}, - {"", 0, 0}, {"", 0, 0}, - {"__extension__", EXTENSION, NORID}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"else", ELSE, NORID}, - {"", 0, 0}, - {"__imag__", IMAGPART, NORID}, - {"", 0, 0}, - {"__inline__", SCSPEC, RID_INLINE}, - {"switch", SWITCH, NORID}, - {"", 0, 0}, - {"__volatile__", TYPE_QUAL, RID_VOLATILE}, - {"while", WHILE, NORID}, - {"", 0, 0}, - {"__inline", SCSPEC, RID_INLINE}, - {"", 0, 0}, - {"in", TYPE_QUAL, RID_IN}, - {"__volatile", TYPE_QUAL, RID_VOLATILE}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"__typeof__", TYPEOF, NORID}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"__signed", TYPESPEC, RID_SIGNED}, - {"", 0, 0}, - {"__restrict", TYPE_QUAL, RID_RESTRICT}, - {"struct", STRUCT, NORID}, - {"", 0, 0}, - {"restrict", TYPE_QUAL, RID_RESTRICT}, - {"oneway", TYPE_QUAL, RID_ONEWAY}, - {"id", OBJECTNAME, RID_ID}, - {"", 0, 0}, {"", 0, 0}, - {"sizeof", SIZEOF, NORID}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"for", FOR, NORID}, - {"return", RETURN, NORID}, - {"__bounded__", TYPE_QUAL, RID_BOUNDED}, - {"extern", SCSPEC, RID_EXTERN}, - {"break", BREAK, NORID}, - {"if", IF, NORID}, - {"", 0, 0}, {"", 0, 0}, - {"__ptrbase__", PTR_BASE, NORID}, - {"__ptrvalue__", PTR_VALUE, NORID}, - {"__ptrextent__", PTR_EXTENT, NORID}, - {"", 0, 0}, - {"do", DO, NORID}, - {"", 0, 0}, - {"__ptrbase", PTR_BASE, NORID}, - {"__ptrvalue", PTR_VALUE, NORID}, - {"void", TYPESPEC, RID_VOID}, - {"", 0, 0}, - {"register", SCSPEC, RID_REGISTER}, - {"", 0, 0}, - {"short", TYPESPEC, RID_SHORT}, - {"", 0, 0}, - {"__unbounded__", TYPE_QUAL, RID_UNBOUNDED}, - {"__imag", IMAGPART, NORID}, - {"__asm__", ASM_KEYWORD, NORID}, - {"__typeof", TYPEOF, NORID}, - {"int", TYPESPEC, RID_INT}, - {"", 0, 0}, - {"__alignof__", ALIGNOF, NORID}, - {"", 0, 0}, - {"__attribute__", ATTRIBUTE, NORID}, - {"", 0, 0}, {"", 0, 0}, - {"__bounded", TYPE_QUAL, RID_BOUNDED}, - {"inout", TYPE_QUAL, RID_INOUT}, - {"", 0, 0}, - {"__attribute", ATTRIBUTE, NORID}, - {"enum", ENUM, NORID}, - {"__asm", ASM_KEYWORD, NORID}, - {"", 0, 0}, - {"__ptrextent", PTR_EXTENT, NORID}, - {"", 0, 0}, - {"signed", TYPESPEC, RID_SIGNED}, - {"", 0, 0}, {"", 0, 0}, - {"out", TYPE_QUAL, RID_OUT}, - {"", 0, 0}, - {"byref", TYPE_QUAL, RID_BYREF}, - {"", 0, 0}, {"", 0, 0}, - {"union", UNION, NORID}, - {"", 0, 0}, - {"asm", ASM_KEYWORD, NORID}, - {"__unbounded", TYPE_QUAL, RID_UNBOUNDED}, - {"", 0, 0}, - {"unsigned", TYPESPEC, RID_UNSIGNED}, - {"double", TYPESPEC, RID_DOUBLE}, - {"default", DEFAULT, NORID}, - {"", 0, 0}, - {"__const__", TYPE_QUAL, RID_CONST}, - {"float", TYPESPEC, RID_FLOAT}, - {"__complex__", TYPESPEC, RID_COMPLEX}, - {"", 0, 0}, - {"__complex", TYPESPEC, RID_COMPLEX}, - {"", 0, 0}, - {"__builtin_va_arg", VA_ARG, NORID}, - {"__label__", LABEL, NORID}, - {"case", CASE, NORID}, - {"", 0, 0}, - {"__real", REALPART, NORID}, - {"@defs", DEFS, NORID}, - {"__alignof", ALIGNOF, NORID}, - {"goto", GOTO, NORID}, - {"", 0, 0}, - {"@private", PRIVATE, NORID}, - {"@selector", SELECTOR, NORID}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"typeof", TYPEOF, NORID}, - {"typedef", SCSPEC, RID_TYPEDEF}, - {"", 0, 0}, - {"continue", CONTINUE, NORID}, - {"@encode", ENCODE, NORID}, - {"", 0, 0}, {"", 0, 0}, - {"@interface", INTERFACE, NORID}, - {"", 0, 0}, - {"__const", TYPE_QUAL, RID_CONST}, - {"inline", SCSPEC, RID_INLINE}, - {"auto", SCSPEC, RID_AUTO}, - {"", 0, 0}, - {"volatile", TYPE_QUAL, RID_VOLATILE}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"@implementation", IMPLEMENTATION, NORID}, - {"@protected", PROTECTED, NORID}, - {"", 0, 0}, {"", 0, 0}, - {"const", TYPE_QUAL, RID_CONST}, - {"", 0, 0}, - {"@end", END, NORID}, - {"bycopy", TYPE_QUAL, RID_BYCOPY}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"@compatibility_alias", ALIAS, NORID}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"", 0, 0}, {"", 0, 0}, - {"long", TYPESPEC, RID_LONG}, - {"char", TYPESPEC, RID_CHAR}, - {"static", SCSPEC, RID_STATIC}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"@class", CLASS, NORID}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"@protocol", PROTOCOL, NORID}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"@public", PUBLIC, NORID} - }; - -#ifdef __GNUC__ -__inline -#endif -struct resword * -is_reserved_word (str, len) - register const char *str; - register unsigned int len; -{ - if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) - { - register int key = hash (str, len); - - if (key <= MAX_HASH_VALUE && key >= 0) - { - register const char *s = wordlist[key].name; - - if (*str == *s && !strcmp (str + 1, s + 1)) - return &wordlist[key]; - } - } - return 0; -} diff --git a/gcc/c-lang.c b/gcc/c-lang.c index ab28b0d4..f8dd30b 100644 --- a/gcc/c-lang.c +++ b/gcc/c-lang.c @@ -37,9 +37,7 @@ static int c_tree_printer PARAMS ((output_buffer *)); #if USE_CPPLIB #include "cpplib.h" -extern char *yy_cur; extern cpp_reader parse_in; -extern cpp_options parse_options; #endif /* Each of the functions defined here @@ -57,9 +55,8 @@ void lang_init_options () { #if USE_CPPLIB + cpp_init (); cpp_reader_init (&parse_in); - parse_in.opts = &parse_options; - cpp_options_init (&parse_options); #endif /* Mark as "unspecified". */ flag_bounds_check = -1; @@ -86,10 +83,7 @@ lang_init () and put it in input_filename. */ #if !USE_CPPLIB ungetc (check_newline (), finput); -#else - check_newline (); - yy_cur--; -#endif +#endif save_lang_status = &push_c_function_context; restore_lang_status = &pop_c_function_context; diff --git a/gcc/c-lex.c b/gcc/c-lex.c index 867c7be..84ef094 100644 --- a/gcc/c-lex.c +++ b/gcc/c-lex.c @@ -29,12 +29,13 @@ Boston, MA 02111-1307, USA. */ #include "c-lex.h" #include "c-tree.h" #include "flags.h" -#include "c-parse.h" +#include "timevar.h" #include "c-pragma.h" #include "toplev.h" #include "intl.h" #include "ggc.h" #include "tm_p.h" +#include "splay-tree.h" /* MULTIBYTE_CHARS support only works for native compilers. ??? Ideally what we want is to model widechar support after @@ -51,35 +52,29 @@ Boston, MA 02111-1307, USA. */ #define GET_ENVIRONMENT(ENV_VALUE,ENV_NAME) ((ENV_VALUE) = getenv (ENV_NAME)) #endif -#if USE_CPPLIB #include "cpplib.h" + +#if USE_CPPLIB extern cpp_reader parse_in; -extern cpp_options parse_options; #else /* Stream for reading from the input file. */ FILE *finput; #endif -extern void yyprint PARAMS ((FILE *, int, YYSTYPE)); +/* Private idea of the line number. See discussion in c_lex(). */ +static int lex_lineno; + +/* We may keep statistics about how long which files took to compile. */ +static int header_time, body_time; +static splay_tree file_info_tree; /* Cause the `yydebug' variable to be defined. */ #define YYDEBUG 1 -#if USE_CPPLIB -extern unsigned char *yy_cur, *yy_lim; -extern enum cpp_token cpp_token; - -extern int yy_get_token (); - -#define GETC() (yy_cur < yy_lim ? *yy_cur++ : yy_get_token ()) -#define UNGETC(c) ((c) == EOF ? 0 : yy_cur--) - -#else /* ! USE_CPPLIB */ - -#define GETC() getch () -#define UNGETC(c) put_back (c) +#if !USE_CPPLIB -struct putback_buffer { +struct putback_buffer +{ unsigned char *buffer; int buffer_size; int index; @@ -117,11 +112,10 @@ put_back (ch) putback.buffer[++putback.index] = ch; } } -#endif /* ! USE_CPPLIB */ int linemode; -extern int yydebug; +#endif /* File used for outputting assembler code. */ extern FILE *asm_out_file; @@ -132,85 +126,69 @@ extern FILE *asm_out_file; /* Number of bytes in a wide character. */ #define WCHAR_BYTES (WCHAR_TYPE_SIZE / BITS_PER_UNIT) +#if !USE_CPPLIB static int maxtoken; /* Current nominal length of token buffer. */ -char *token_buffer; /* Pointer to token buffer. - Actual allocated length is maxtoken + 2. - This is not static because objc-parse.y uses it. */ +static char *token_buffer; /* Pointer to token buffer. + Actual allocated length is maxtoken + 2. */ +#endif -static int indent_level; /* Number of { minus number of }. */ +int indent_level; /* Number of { minus number of }. */ +int pending_lang_change; /* If we need to switch languages - C++ only */ +int c_header_level; /* depth in C headers - C++ only */ /* Nonzero tells yylex to ignore \ in string constants. */ static int ignore_escape_flag; -/* Nonzero if end-of-file has been seen on input. */ -static int end_of_file; +static const char *readescape PARAMS ((const char *, const char *, + unsigned int *)); +static const char *read_ucs PARAMS ((const char *, const char *, + unsigned int *, int)); +static void parse_float PARAMS ((PTR)); +static tree lex_number PARAMS ((const char *, unsigned int)); +static tree lex_string PARAMS ((const char *, unsigned int, int)); +static tree lex_charconst PARAMS ((const char *, unsigned int, int)); +static void update_header_times PARAMS ((const char *)); +static int dump_one_header PARAMS ((splay_tree_node, void *)); -#ifdef HANDLE_GENERIC_PRAGMAS -static int handle_generic_pragma PARAMS ((int)); -#endif /* HANDLE_GENERIC_PRAGMAS */ -static int whitespace_cr PARAMS ((int)); +#if !USE_CPPLIB static int skip_white_space PARAMS ((int)); static char *extend_token_buffer PARAMS ((const char *)); -static int readescape PARAMS ((int *)); -static void parse_float PARAMS ((PTR)); static void extend_token_buffer_to PARAMS ((int)); static int read_line_number PARAMS ((int *)); - -/* Do not insert generated code into the source, instead, include it. - This allows us to build gcc automatically even for targets that - need to add or modify the reserved keyword lists. */ -#include "c-gperf.h" - -/* Return something to represent absolute declarators containing a *. - TARGET is the absolute declarator that the * contains. - TYPE_QUALS is a list of modifiers such as const or volatile - to apply to the pointer type, represented as identifiers. - - We return an INDIRECT_REF whose "contents" are TARGET - and whose type is the modifier list. */ - -tree -make_pointer_declarator (type_quals, target) - tree type_quals, target; -{ - return build1 (INDIRECT_REF, type_quals, target); -} - -void -forget_protocol_qualifiers () -{ - int i, n = sizeof wordlist / sizeof (struct resword); - - for (i = 0; i < n; i++) - if ((int) wordlist[i].rid >= (int) RID_IN - && (int) wordlist[i].rid <= (int) RID_ONEWAY) - wordlist[i].name = ""; -} +static void process_directive PARAMS ((void)); +#else +static void cb_ident PARAMS ((cpp_reader *, const unsigned char *, + unsigned int)); +static void cb_enter_file PARAMS ((cpp_reader *)); +static void cb_leave_file PARAMS ((cpp_reader *)); +static void cb_rename_file PARAMS ((cpp_reader *)); +#endif -void -remember_protocol_qualifiers () -{ - int i, n = sizeof wordlist / sizeof (struct resword); - - for (i = 0; i < n; i++) - if (wordlist[i].rid == RID_IN) - wordlist[i].name = "in"; - else if (wordlist[i].rid == RID_OUT) - wordlist[i].name = "out"; - else if (wordlist[i].rid == RID_INOUT) - wordlist[i].name = "inout"; - else if (wordlist[i].rid == RID_BYCOPY) - wordlist[i].name = "bycopy"; - else if (wordlist[i].rid == RID_BYREF) - wordlist[i].name = "byref"; - else if (wordlist[i].rid == RID_ONEWAY) - wordlist[i].name = "oneway"; -} const char * -init_parse (filename) +init_c_lex (filename) const char *filename; { + struct c_fileinfo *toplevel; + + /* Set up filename timing. Must happen before cpp_start_read. */ + file_info_tree = splay_tree_new ((splay_tree_compare_fn)strcmp, + 0, + (splay_tree_delete_value_fn)free); + toplevel = get_fileinfo (""); + if (flag_detailed_statistics) + { + header_time = 0; + body_time = get_run_time (); + toplevel->time = body_time; + } + +#ifdef MULTIBYTE_CHARS + /* Change to the native locale for multibyte conversions. */ + setlocale (LC_CTYPE, ""); + GET_ENVIRONMENT (literal_codeset, "LANG"); +#endif + #if !USE_CPPLIB /* Open input file. */ if (filename == 0 || !strcmp (filename, "-")) @@ -227,194 +205,97 @@ init_parse (filename) setvbuf (finput, (char *) xmalloc (IO_BUFFER_SIZE), _IOFBF, IO_BUFFER_SIZE); #endif #else /* !USE_CPPLIB */ - parse_in.show_column = 1; - if (! cpp_start_read (&parse_in, filename)) + + parse_in.cb.ident = cb_ident; + parse_in.cb.enter_file = cb_enter_file; + parse_in.cb.leave_file = cb_leave_file; + parse_in.cb.rename_file = cb_rename_file; + + /* Make sure parse_in.digraphs matches flag_digraphs. */ + CPP_OPTION (&parse_in, digraphs) = flag_digraphs; + + if (! cpp_start_read (&parse_in, 0 /* no printer */, filename)) abort (); if (filename == 0 || !strcmp (filename, "-")) filename = "stdin"; - - /* cpp_start_read always puts at least one line directive into the - token buffer. We must arrange to read it out here. */ - yy_cur = parse_in.token_buffer; - yy_lim = CPP_PWRITTEN (&parse_in); - cpp_token = CPP_DIRECTIVE; #endif - add_c_tree_codes (); - - init_lex (); - init_pragma (); +#if !USE_CPPLIB + maxtoken = 40; + token_buffer = (char *) xmalloc (maxtoken + 2); +#endif + /* Start it at 0, because check_newline is called at the very beginning + and will increment it to 1. */ + lineno = lex_lineno = 0; return filename; } -void -finish_parse () +struct c_fileinfo * +get_fileinfo (name) + const char *name; { -#if USE_CPPLIB - cpp_finish (&parse_in); - errorcount += parse_in.errors; -#else - fclose (finput); -#endif + splay_tree_node n; + struct c_fileinfo *fi; + + n = splay_tree_lookup (file_info_tree, (splay_tree_key) name); + if (n) + return (struct c_fileinfo *) n->value; + + fi = (struct c_fileinfo *) xmalloc (sizeof (struct c_fileinfo)); + fi->time = 0; + fi->interface_only = 0; + fi->interface_unknown = 1; + splay_tree_insert (file_info_tree, (splay_tree_key) name, + (splay_tree_value) fi); + return fi; } -void -init_lex () +static void +update_header_times (name) + const char *name; { - /* Make identifier nodes long enough for the language-specific slots. */ - set_identifier_size (sizeof (struct lang_identifier)); - - /* Start it at 0, because check_newline is called at the very beginning - and will increment it to 1. */ - lineno = 0; - -#ifdef MULTIBYTE_CHARS - /* Change to the native locale for multibyte conversions. */ - setlocale (LC_CTYPE, ""); - GET_ENVIRONMENT (literal_codeset, "LANG"); -#endif - - maxtoken = 40; - token_buffer = (char *) xmalloc (maxtoken + 2); - - ridpointers = (tree *) xcalloc ((int) RID_MAX, sizeof (tree)); - ridpointers[(int) RID_INT] = get_identifier ("int"); - ridpointers[(int) RID_CHAR] = get_identifier ("char"); - ridpointers[(int) RID_VOID] = get_identifier ("void"); - ridpointers[(int) RID_FLOAT] = get_identifier ("float"); - ridpointers[(int) RID_DOUBLE] = get_identifier ("double"); - ridpointers[(int) RID_SHORT] = get_identifier ("short"); - ridpointers[(int) RID_LONG] = get_identifier ("long"); - ridpointers[(int) RID_UNSIGNED] = get_identifier ("unsigned"); - ridpointers[(int) RID_SIGNED] = get_identifier ("signed"); - ridpointers[(int) RID_INLINE] = get_identifier ("inline"); - ridpointers[(int) RID_CONST] = get_identifier ("const"); - ridpointers[(int) RID_RESTRICT] = get_identifier ("restrict"); - ridpointers[(int) RID_VOLATILE] = get_identifier ("volatile"); - ridpointers[(int) RID_BOUNDED] = get_identifier ("__bounded"); - ridpointers[(int) RID_UNBOUNDED] = get_identifier ("__unbounded"); - ridpointers[(int) RID_AUTO] = get_identifier ("auto"); - ridpointers[(int) RID_STATIC] = get_identifier ("static"); - ridpointers[(int) RID_EXTERN] = get_identifier ("extern"); - ridpointers[(int) RID_TYPEDEF] = get_identifier ("typedef"); - ridpointers[(int) RID_REGISTER] = get_identifier ("register"); - ridpointers[(int) RID_COMPLEX] = get_identifier ("complex"); - ridpointers[(int) RID_ID] = get_identifier ("id"); - ridpointers[(int) RID_IN] = get_identifier ("in"); - ridpointers[(int) RID_OUT] = get_identifier ("out"); - ridpointers[(int) RID_INOUT] = get_identifier ("inout"); - ridpointers[(int) RID_BYCOPY] = get_identifier ("bycopy"); - ridpointers[(int) RID_BYREF] = get_identifier ("byref"); - ridpointers[(int) RID_ONEWAY] = get_identifier ("oneway"); - forget_protocol_qualifiers(); - - /* Some options inhibit certain reserved words. - Clear those words out of the hash table so they won't be recognized. */ -#define UNSET_RESERVED_WORD(STRING) \ - do { struct resword *s = is_reserved_word (STRING, sizeof (STRING) - 1); \ - if (s) s->name = ""; } while (0) - - if (! doing_objc_thang) - UNSET_RESERVED_WORD ("id"); - - if (flag_traditional) - { - UNSET_RESERVED_WORD ("const"); - UNSET_RESERVED_WORD ("restrict"); - UNSET_RESERVED_WORD ("volatile"); - UNSET_RESERVED_WORD ("typeof"); - UNSET_RESERVED_WORD ("signed"); - UNSET_RESERVED_WORD ("inline"); - UNSET_RESERVED_WORD ("complex"); - } - else if (!flag_isoc99) - UNSET_RESERVED_WORD ("restrict"); - - if (flag_no_asm) + /* Changing files again. This means currently collected time + is charged against header time, and body time starts back at 0. */ + if (flag_detailed_statistics) { - UNSET_RESERVED_WORD ("asm"); - UNSET_RESERVED_WORD ("typeof"); - if (! flag_isoc99) - UNSET_RESERVED_WORD ("inline"); - UNSET_RESERVED_WORD ("complex"); + int this_time = get_run_time (); + struct c_fileinfo *file = get_fileinfo (name); + header_time += this_time - body_time; + file->time += this_time - body_time; + body_time = this_time; } } -void -reinit_parse_for_function () +static int +dump_one_header (n, dummy) + splay_tree_node n; + void *dummy ATTRIBUTE_UNUSED; { + print_time ((const char *) n->key, + ((struct c_fileinfo *) n->value)->time); + return 0; } - -/* Function used when yydebug is set, to print a token in more detail. */ void -yyprint (file, yychar, yylval) - FILE *file; - int yychar; - YYSTYPE yylval; +dump_time_statistics () { - tree t; - switch (yychar) - { - case IDENTIFIER: - case TYPENAME: - case OBJECTNAME: - t = yylval.ttype; - if (IDENTIFIER_POINTER (t)) - fprintf (file, " `%s'", IDENTIFIER_POINTER (t)); - break; - - case CONSTANT: - t = yylval.ttype; - if (TREE_CODE (t) == INTEGER_CST) - fprintf (file, -#if HOST_BITS_PER_WIDE_INT == 64 -#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT - " 0x%x%016x", -#else -#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG - " 0x%lx%016lx", -#else - " 0x%llx%016llx", -#endif -#endif -#else -#if HOST_BITS_PER_WIDE_INT != HOST_BITS_PER_INT - " 0x%lx%08lx", -#else - " 0x%x%08x", -#endif -#endif - TREE_INT_CST_HIGH (t), TREE_INT_CST_LOW (t)); - break; - } + struct c_fileinfo *file = get_fileinfo (input_filename); + int this_time = get_run_time (); + file->time += this_time - body_time; + + fprintf (stderr, "\n******\n"); + print_time ("header files (total)", header_time); + print_time ("main file (total)", this_time - body_time); + fprintf (stderr, "ratio = %g : 1\n", + (double)header_time / (double)(this_time - body_time)); + fprintf (stderr, "\n******\n"); + + splay_tree_foreach (file_info_tree, dump_one_header, 0); } - -/* Iff C is a carriage return, warn about it - if appropriate - - and return nonzero. */ - -static int -whitespace_cr (c) - int c; -{ - static int newline_warning = 0; - if (c == '\r') - { - /* ANSI C says the effects of a carriage return in a source file - are undefined. */ - if (pedantic && !newline_warning) - { - warning ("carriage return in source file"); - warning ("(we only warn about the first carriage return)"); - newline_warning = 1; - } - return 1; - } - return 0; -} +#if !USE_CPPLIB /* If C is not whitespace, return C. Otherwise skip whitespace and return first nonwhite char read. */ @@ -427,46 +308,29 @@ skip_white_space (c) { switch (c) { - /* We don't recognize comments here, because - cpp output can include / and * consecutively as operators. - Also, there's no need, since cpp removes all comments. */ + /* There is no need to process comments, backslash-newline, + or \r here. None can occur in the output of cpp. */ case '\n': if (linemode) { - UNGETC (c); + put_back (c); return EOF; } c = check_newline (); break; + /* Per C99, horizontal whitespace is just these four characters. */ case ' ': case '\t': case '\f': case '\v': - case '\b': -#if USE_CPPLIB - /* While processing a # directive we don't get CPP_HSPACE - tokens, so we also need to handle whitespace the normal way. */ - if (cpp_token == CPP_HSPACE) - c = yy_get_token (); - else -#endif - c = GETC(); - break; - - case '\r': - whitespace_cr (c); - c = GETC(); + c = getch (); break; case '\\': - c = GETC(); - if (c == '\n') - lineno++; - else - error ("stray '\\' in program"); - c = GETC(); + error ("stray '\\' in program"); + c = getch (); break; default: @@ -482,9 +346,9 @@ position_after_white_space () { register int c; - c = GETC(); + c = getch (); - UNGETC (skip_white_space (c)); + put_back (skip_white_space (c)); } /* Make the token buffer longer, preserving the data in it. @@ -511,183 +375,132 @@ extend_token_buffer (p) return token_buffer + offset; } -#if defined HANDLE_PRAGMA -/* Local versions of these macros, that can be passed as function pointers. */ -static int -pragma_getc () -{ - return GETC (); -} - -static void -pragma_ungetc (arg) - int arg; -{ - UNGETC (arg); -} -#endif static int read_line_number (num) int *num; { - register int token = yylex (); + tree value; + enum cpp_ttype token = c_lex (&value); - if (token == CONSTANT - && TREE_CODE (yylval.ttype) == INTEGER_CST) + if (token == CPP_NUMBER && TREE_CODE (value) == INTEGER_CST) { - *num = TREE_INT_CST_LOW (yylval.ttype); + *num = TREE_INT_CST_LOW (value); return 1; } else { - if (token != END_OF_LINE) + if (token != CPP_EOF) error ("invalid #-line"); return 0; } } - + /* At the beginning of a line, increment the line number and process any #-directive on this line. If the line is a #-directive, read the entire line and return a newline. - Otherwise, return the line's first non-whitespace character. - - Note that in the case of USE_CPPLIB, we get the whole line as one - CPP_DIRECTIVE token. */ + Otherwise, return the line's first non-whitespace character. */ int check_newline () { register int c; - register int token; - int saw_line; - enum { act_none, act_push, act_pop } action; - int old_lineno, action_number, l; - - restart: - /* Read first nonwhite char on the line. */ - -#ifdef USE_CPPLIB - c = GETC (); - /* In some cases where we're leaving an include file, we can get multiple - CPP_HSPACE tokens in a row, so we need to loop. */ - while (cpp_token == CPP_HSPACE) - c = yy_get_token (); -#else - do - c = GETC (); - while (c == ' ' || c == '\t'); -#endif - - lineno++; - if (c != '#') + /* Loop till we get a nonblank, non-directive line. */ + for (;;) { - /* Sequences of multiple newlines are very common; optimize them. */ - if (c == '\n') - goto restart; + /* Read first nonwhite char on the line. */ + do + c = getch (); + while (c == ' ' || c == '\t'); + + lex_lineno++; + if (c == '#') + { + process_directive (); + return '\n'; + } - /* If not #, return it so caller will use it. */ - return c; + else if (c != '\n') + break; } + return c; +} +static void +process_directive () +{ + enum cpp_ttype token; + tree value; + int saw_line; + enum { act_none, act_push, act_pop } action; + int action_number, l; + char *new_file; +#ifndef NO_IMPLICIT_EXTERN_C + int entering_c_header; +#endif + /* Don't read beyond this line. */ saw_line = 0; linemode = 1; -#if USE_CPPLIB - if (cpp_token == CPP_VSPACE) - { - /* Format is " ". - Only the line number is interesting, and even that - we can get more efficiently than scanning the line. */ - yy_cur = yy_lim - 1; - lineno = parse_in.lineno - 1; - goto skipline; - } -#endif + token = c_lex (&value); - token = yylex (); - - if (token == IDENTIFIER) + if (token == CPP_NAME) { /* If a letter follows, then if the word here is `line', skip it and ignore it; otherwise, ignore the line, with an error if the word isn't `pragma'. */ - const char *name = IDENTIFIER_POINTER (yylval.ttype); + const char *name = IDENTIFIER_POINTER (value); if (!strcmp (name, "pragma")) { - token = yylex (); - if (token != IDENTIFIER - || TREE_CODE (yylval.ttype) != IDENTIFIER_NODE) - goto skipline; + dispatch_pragma (); + goto skipline; +#if 0 #ifdef HANDLE_PRAGMA /* We invoke HANDLE_PRAGMA before HANDLE_GENERIC_PRAGMAS (if both are defined), in order to give the back end a chance to override the interpretation of SYSV style pragmas. */ - if (HANDLE_PRAGMA (pragma_getc, pragma_ungetc, - IDENTIFIER_POINTER (yylval.ttype))) + if (HANDLE_PRAGMA (getch, put_back, IDENTIFIER_POINTER (value))) goto skipline; #endif /* HANDLE_PRAGMA */ - -#ifdef HANDLE_GENERIC_PRAGMAS - if (handle_generic_pragma (token)) - goto skipline; -#endif /* HANDLE_GENERIC_PRAGMAS */ - - /* Issue a warning message if we have been asked to do so. - Ignoring unknown pragmas in system header file unless - an explcit -Wunknown-pragmas has been given. */ - if (warn_unknown_pragmas > 1 - || (warn_unknown_pragmas && ! in_system_header)) - warning ("ignoring pragma: %s", token_buffer); - - goto skipline; +#endif } else if (!strcmp (name, "define")) { - debug_define (lineno, GET_DIRECTIVE_LINE ()); + debug_define (lex_lineno, GET_DIRECTIVE_LINE ()); goto skipline; } else if (!strcmp (name, "undef")) { - debug_undef (lineno, GET_DIRECTIVE_LINE ()); + debug_undef (lex_lineno, GET_DIRECTIVE_LINE ()); goto skipline; } else if (!strcmp (name, "line")) { saw_line = 1; - token = yylex (); + token = c_lex (&value); goto linenum; } else if (!strcmp (name, "ident")) { - /* #ident. The pedantic warning is now in cpp. */ - - /* Here we have just seen `#ident '. - A string constant should follow. */ + /* #ident. We expect a string constant here. + The pedantic warning and syntax error are now in cpp. */ - token = yylex (); - if (token == END_OF_LINE) + token = c_lex (&value); + if (token != CPP_STRING || TREE_CODE (value) != STRING_CST) goto skipline; - if (token != STRING - || TREE_CODE (yylval.ttype) != STRING_CST) - { - error ("invalid #ident"); - goto skipline; - } +#ifdef ASM_OUTPUT_IDENT if (! flag_no_ident) { -#ifdef ASM_OUTPUT_IDENT - ASM_OUTPUT_IDENT (asm_out_file, - TREE_STRING_POINTER (yylval.ttype)); -#endif + ASM_OUTPUT_IDENT (asm_out_file, TREE_STRING_POINTER (value)); } +#endif /* Skip the rest of this line. */ goto skipline; @@ -699,15 +512,14 @@ check_newline () /* If the # is the only nonwhite char on the line, just ignore it. Check the new newline. */ - if (token == END_OF_LINE) + if (token == CPP_EOF) goto skipline; linenum: /* Here we have either `#line' or `# '. In either case, it should be a line number; a digit should follow. */ - if (token != CONSTANT - || TREE_CODE (yylval.ttype) != INTEGER_CST) + if (token != CPP_NUMBER || TREE_CODE (value) != INTEGER_CST) { error ("invalid #-line"); goto skipline; @@ -716,7 +528,7 @@ linenum: /* subtract one, because it is the following line that gets the specified number */ - l = TREE_INT_CST_LOW (yylval.ttype) - 1; + l = TREE_INT_CST_LOW (value) - 1; /* More follows: it must be a string constant (filename). It would be neat to use cpplib to quickly process the string, but @@ -732,32 +544,30 @@ linenum: } /* Read the string constant. */ - token = yylex (); + token = c_lex (&value); ignore_escape_flag = 0; - if (token == END_OF_LINE) + if (token == CPP_EOF) { /* No more: store the line number and check following line. */ - lineno = l; + lex_lineno = l; goto skipline; } - if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST) + if (token != CPP_STRING || TREE_CODE (value) != STRING_CST) { error ("invalid #line"); goto skipline; } - input_filename = TREE_STRING_POINTER (yylval.ttype); + new_file = TREE_STRING_POINTER (value); if (main_input_filename == 0) - main_input_filename = input_filename; + main_input_filename = new_file; - old_lineno = lineno; action = act_none; action_number = 0; - lineno = l; /* Each change of file name reinitializes whether we are now in a system header. */ @@ -789,113 +599,282 @@ linenum: in_system_header = 1; read_line_number (&action_number); } +#ifndef NO_IMPLICIT_EXTERN_C + if (action_number == 4) + { + /* `4' after file name means this is a C header file. */ + entering_c_header = 1; + read_line_number (&action_number); + } +#endif /* Do the actions implied by the preceding numbers. */ - if (action == act_push) { - /* Pushing to a new file. */ - struct file_stack *p - = (struct file_stack *) xmalloc (sizeof (struct file_stack)); - input_file_stack->line = old_lineno; - p->next = input_file_stack; - p->name = input_filename; - p->indent_level = indent_level; - input_file_stack = p; - input_file_stack_tick++; + lineno = lex_lineno; + push_srcloc (input_filename, 1); + input_file_stack->indent_level = indent_level; debug_start_source_file (input_filename); +#ifndef NO_IMPLICIT_EXTERN_C + if (c_header_level) + ++c_header_level; + else if (entering_c_header) + { + c_header_level = 1; + ++pending_lang_change; + } +#endif } else if (action == act_pop) { /* Popping out of a file. */ if (input_file_stack->next) { - struct file_stack *p = input_file_stack; - if (indent_level != p->indent_level) +#ifndef NO_IMPLICIT_EXTERN_C + if (c_header_level && --c_header_level == 0) + { + if (entering_c_header) + warning ("badly nested C headers from preprocessor"); + --pending_lang_change; + } +#endif +#if 0 + if (indent_level != input_file_stack->indent_level) { warning_with_file_and_line - (p->name, old_lineno, - "This file contains more `%c's than `%c's.", - indent_level > p->indent_level ? '{' : '}', - indent_level > p->indent_level ? '}' : '{'); + (input_filename, lex_lineno, + "This file contains more '%c's than '%c's.", + indent_level > input_file_stack->indent_level ? '{' : '}', + indent_level > input_file_stack->indent_level ? '}' : '{'); } - input_file_stack = p->next; - free (p); - input_file_stack_tick++; +#endif + pop_srcloc (); debug_end_source_file (input_file_stack->line); } else error ("#-lines for entering and leaving files don't match"); } - /* Now that we've pushed or popped the input stack, - update the name in the top element. */ - if (input_file_stack) - input_file_stack->name = input_filename; + update_header_times (new_file); + + input_filename = new_file; + lex_lineno = l; + + /* Hook for C++. */ + extract_interface_info (); /* skip the rest of this line. */ skipline: linemode = 0; - end_of_file = 0; - do - c = GETC(); - while (c != '\n' && c != EOF); - return c; + while (getch () != '\n'); } - -#ifdef HANDLE_GENERIC_PRAGMAS +#else /* USE_CPPLIB */ -/* Handle a #pragma directive. - TOKEN is the token we read after `#pragma'. Processes the entire input - line and return non-zero iff the pragma has been successfully parsed. */ +/* Not yet handled: #pragma, #define, #undef. + No need to deal with linemarkers under normal conditions. */ -/* This function has to be in this file, in order to get at - the token types. */ +static void +cb_ident (pfile, str, len) + cpp_reader *pfile ATTRIBUTE_UNUSED; + const unsigned char *str; + unsigned int len; +{ +#ifdef ASM_OUTPUT_IDENT + if (! flag_no_ident) + { + /* Convert escapes in the string. */ + tree value = lex_string ((const char *)str, len, 0); + ASM_OUTPUT_IDENT (asm_out_file, TREE_STRING_POINTER (value)); + } +#endif +} -static int -handle_generic_pragma (token) - register int token; +static void +cb_enter_file (pfile) + cpp_reader *pfile; { - for (;;) + cpp_buffer *ip = CPP_BUFFER (pfile); + /* Bleah, need a better interface to this. */ + const char *flags = cpp_syshdr_flags (pfile, ip); + + /* Mustn't stack the main buffer on the input stack. (Ick.) */ + if (ip->prev) + { + lex_lineno = lineno = ip->prev->lineno - 1; + push_srcloc (ggc_alloc_string (ip->nominal_fname, -1), 1); + input_file_stack->indent_level = indent_level; + debug_start_source_file (ip->nominal_fname); + } + else + lex_lineno = 1; + + update_header_times (ip->nominal_fname); + + /* Hook for C++. */ + extract_interface_info (); + + in_system_header = (flags[0] != 0); +#ifndef NO_IMPLICIT_EXTERN_C + if (c_header_level) + ++c_header_level; + else if (flags[2] != 0) + { + c_header_level = 1; + ++pending_lang_change; + } +#endif +} + +static void +cb_leave_file (pfile) + cpp_reader *pfile; +{ + /* Bleah, need a better interface to this. */ + const char *flags = cpp_syshdr_flags (pfile, CPP_BUFFER (pfile)); +#if 0 + if (indent_level != input_file_stack->indent_level) + { + warning_with_file_and_line + (input_filename, lex_lineno, + "This file contains more '%c's than '%c's.", + indent_level > input_file_stack->indent_level ? '{' : '}', + indent_level > input_file_stack->indent_level ? '}' : '{'); + } +#endif + /* We get called for the main buffer, but we mustn't pop it. */ + if (input_file_stack->next) + pop_srcloc (); + in_system_header = (flags[0] != 0); +#ifndef NO_IMPLICIT_EXTERN_C + if (c_header_level && --c_header_level == 0) + { + if (flags[2] != 0) + warning ("badly nested C headers from preprocessor"); + --pending_lang_change; + } +#endif + lex_lineno = CPP_BUFFER (pfile)->lineno; + debug_end_source_file (input_file_stack->line); + + update_header_times (input_file_stack->name); + /* Hook for C++. */ + extract_interface_info (); +} + +static void +cb_rename_file (pfile) + cpp_reader *pfile; +{ + cpp_buffer *ip = CPP_BUFFER (pfile); + /* Bleah, need a better interface to this. */ + const char *flags = cpp_syshdr_flags (pfile, ip); + input_filename = ggc_alloc_string (ip->nominal_fname, -1); + lex_lineno = ip->lineno; + in_system_header = (flags[0] != 0); + + update_header_times (ip->nominal_fname); + /* Hook for C++. */ + extract_interface_info (); +} +#endif /* USE_CPPLIB */ + +/* Parse a '\uNNNN' or '\UNNNNNNNN' sequence. + + [lex.charset]: The character designated by the universal-character-name + \UNNNNNNNN is that character whose character short name in ISO/IEC 10646 + is NNNNNNNN; the character designated by the universal-character-name + \uNNNN is that character whose character short name in ISO/IEC 10646 is + 0000NNNN. If the hexadecimal value for a universal character name is + less than 0x20 or in the range 0x7F-0x9F (inclusive), or if the + universal character name designates a character in the basic source + character set, then the program is ill-formed. + + We assume that wchar_t is Unicode, so we don't need to do any + mapping. Is this ever wrong? */ + +static const char * +read_ucs (p, limit, cptr, length) + const char *p; + const char *limit; + unsigned int *cptr; + int length; +{ + unsigned int code = 0; + int c; + + for (; length; --length) { - switch (token) + if (p >= limit) { - case IDENTIFIER: - case TYPENAME: - case STRING: - case CONSTANT: - handle_pragma_token (token_buffer, yylval.ttype); + error ("incomplete universal-character-name"); break; + } - case END_OF_LINE: - return handle_pragma_token (NULL_PTR, NULL_TREE); - - default: - handle_pragma_token (token_buffer, NULL); + c = *p++; + if (! ISXDIGIT (c)) + { + error ("non hex digit '%c' in universal-character-name", c); + p--; + break; } - token = yylex (); + code <<= 4; + if (c >= 'a' && c <= 'f') + code += c - 'a' + 10; + if (c >= 'A' && c <= 'F') + code += c - 'A' + 10; + if (c >= '0' && c <= '9') + code += c - '0'; } -} -#endif /* HANDLE_GENERIC_PRAGMAS */ - -#define ENDFILE -1 /* token that represents end-of-file */ +#ifdef TARGET_EBCDIC + sorry ("universal-character-name on EBCDIC target"); + *cptr = 0x3f; /* EBCDIC invalid character */ + return p; +#endif + + if (code > 0x9f && !(code & 0x80000000)) + /* True extended character, OK. */; + else if (code >= 0x20 && code < 0x7f) + { + /* ASCII printable character. The C character set consists of all of + these except $, @ and `. We use hex escapes so that this also + works with EBCDIC hosts. */ + if (code != 0x24 && code != 0x40 && code != 0x60) + error ("universal-character-name used for '%c'", code); + } + else + error ("invalid universal-character-name"); + + *cptr = code; + return p; +} -/* Read an escape sequence, returning its equivalent as a character, - or store 1 in *ignore_ptr if it is backslash-newline. */ +/* Read an escape sequence and write its character equivalent into *CPTR. + P is the input pointer, which is just after the backslash. LIMIT + is how much text we have. + Returns the updated input pointer. */ -static int -readescape (ignore_ptr) - int *ignore_ptr; +static const char * +readescape (p, limit, cptr) + const char *p; + const char *limit; + unsigned int *cptr; { - register int c = GETC(); - register int code; - register unsigned count; + unsigned int c, code, count; unsigned firstdig = 0; int nonnull; + if (p == limit) + { + /* cpp has already issued an error for this. */ + *cptr = 0; + return p; + } + + c = *p++; + switch (c) { case 'x': @@ -903,17 +882,20 @@ readescape (ignore_ptr) warning ("the meaning of `\\x' varies with -traditional"); if (flag_traditional) - return c; + { + *cptr = 'x'; + return p; + } code = 0; count = 0; nonnull = 0; - while (1) + while (p < limit) { - c = GETC(); + c = *p++; if (! ISXDIGIT (c)) { - UNGETC (c); + p--; break; } code *= 16; @@ -934,7 +916,8 @@ readescape (ignore_ptr) if (! nonnull) { warning ("\\x used with no following hex digits"); - return 'x'; + *cptr = 'x'; + return p; } else if (count == 0) /* Digits are all 0's. Ok. */ @@ -946,108 +929,390 @@ readescape (ignore_ptr) - (count - 1) * 4)) <= firstdig))) pedwarn ("hex escape out of range"); - return code; + *cptr = code; + return p; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': code = 0; - count = 0; - while ((c <= '7') && (c >= '0') && (count++ < 3)) + for (count = 0; count < 3; count++) { + if (c < '0' || c > '7') + { + p--; + break; + } code = (code * 8) + (c - '0'); - c = GETC(); + if (p == limit) + break; + c = *p++; } - UNGETC (c); - return code; - case '\\': case '\'': case '"': - return c; + if (count == 3) + p--; - case '\n': - lineno++; - *ignore_ptr = 1; - return 0; + *cptr = code; + return p; - case 'n': - return TARGET_NEWLINE; + case '\\': case '\'': case '"': case '?': + *cptr = c; + return p; - case 't': - return TARGET_TAB; + case 'n': *cptr = TARGET_NEWLINE; return p; + case 't': *cptr = TARGET_TAB; return p; + case 'r': *cptr = TARGET_CR; return p; + case 'f': *cptr = TARGET_FF; return p; + case 'b': *cptr = TARGET_BS; return p; + case 'v': *cptr = TARGET_VT; return p; + case 'a': + if (warn_traditional && !in_system_header) + warning ("the meaning of '\\a' varies with -traditional"); + *cptr = flag_traditional ? c : TARGET_BELL; + return p; - case 'r': - return TARGET_CR; + /* Warnings and support checks handled by read_ucs(). */ + case 'u': case 'U': + if (c_language != clk_cplusplus && !flag_isoc99) + break; - case 'f': - return TARGET_FF; - - case 'b': - return TARGET_BS; - - case 'a': if (warn_traditional && !in_system_header) - warning ("the meaning of `\\a' varies with -traditional"); - - if (flag_traditional) - return c; - return TARGET_BELL; - - case 'v': -#if 0 /* Vertical tab is present in common usage compilers. */ - if (flag_traditional) - return c; -#endif - return TARGET_VT; + warning ("the meaning of '\\%c' varies with -traditional", c); - case 'e': - case 'E': + return read_ucs (p, limit, cptr, c == 'u' ? 4 : 8); + + case 'e': case 'E': if (pedantic) - pedwarn ("non-ANSI-standard escape sequence, `\\%c'", c); - return TARGET_ESC; + pedwarn ("non-ISO-standard escape sequence, '\\%c'", c); + *cptr = TARGET_ESC; return p; - case '?': - return c; - - /* `\(', etc, are used at beginning of line to avoid confusing Emacs. */ - case '(': - case '{': - case '[': - /* `\%' is used to prevent SCCS from getting confused. */ - case '%': + /* '\(', etc, are used at beginning of line to avoid confusing Emacs. + '\%' is used to prevent SCCS from getting confused. */ + case '(': case '{': case '[': case '%': if (pedantic) - pedwarn ("unknown escape sequence `\\%c'", c); - return c; + pedwarn ("unknown escape sequence '\\%c'", c); + *cptr = c; + return p; } + if (ISGRAPH (c)) - pedwarn ("unknown escape sequence `\\%c'", c); + pedwarn ("unknown escape sequence '\\%c'", c); else - pedwarn ("unknown escape sequence: `\\' followed by char code 0x%x", c); - return c; + pedwarn ("unknown escape sequence: '\\' followed by char 0x%.2x", c); + + *cptr = c; + return p; } - -void -yyerror (msgid) - const char *msgid; + +#if 0 /* not yet */ +/* Returns nonzero if C is a universal-character-name. Give an error if it + is not one which may appear in an identifier, as per [extendid]. + + Note that extended character support in identifiers has not yet been + implemented. It is my personal opinion that this is not a desirable + feature. Portable code cannot count on support for more than the basic + identifier character set. */ + +static inline int +is_extended_char (c) + int c; +{ +#ifdef TARGET_EBCDIC + return 0; +#else + /* ASCII. */ + if (c < 0x7f) + return 0; + + /* None of the valid chars are outside the Basic Multilingual Plane (the + low 16 bits). */ + if (c > 0xffff) + { + error ("universal-character-name '\\U%08x' not valid in identifier", c); + return 1; + } + + /* Latin */ + if ((c >= 0x00c0 && c <= 0x00d6) + || (c >= 0x00d8 && c <= 0x00f6) + || (c >= 0x00f8 && c <= 0x01f5) + || (c >= 0x01fa && c <= 0x0217) + || (c >= 0x0250 && c <= 0x02a8) + || (c >= 0x1e00 && c <= 0x1e9a) + || (c >= 0x1ea0 && c <= 0x1ef9)) + return 1; + + /* Greek */ + if ((c == 0x0384) + || (c >= 0x0388 && c <= 0x038a) + || (c == 0x038c) + || (c >= 0x038e && c <= 0x03a1) + || (c >= 0x03a3 && c <= 0x03ce) + || (c >= 0x03d0 && c <= 0x03d6) + || (c == 0x03da) + || (c == 0x03dc) + || (c == 0x03de) + || (c == 0x03e0) + || (c >= 0x03e2 && c <= 0x03f3) + || (c >= 0x1f00 && c <= 0x1f15) + || (c >= 0x1f18 && c <= 0x1f1d) + || (c >= 0x1f20 && c <= 0x1f45) + || (c >= 0x1f48 && c <= 0x1f4d) + || (c >= 0x1f50 && c <= 0x1f57) + || (c == 0x1f59) + || (c == 0x1f5b) + || (c == 0x1f5d) + || (c >= 0x1f5f && c <= 0x1f7d) + || (c >= 0x1f80 && c <= 0x1fb4) + || (c >= 0x1fb6 && c <= 0x1fbc) + || (c >= 0x1fc2 && c <= 0x1fc4) + || (c >= 0x1fc6 && c <= 0x1fcc) + || (c >= 0x1fd0 && c <= 0x1fd3) + || (c >= 0x1fd6 && c <= 0x1fdb) + || (c >= 0x1fe0 && c <= 0x1fec) + || (c >= 0x1ff2 && c <= 0x1ff4) + || (c >= 0x1ff6 && c <= 0x1ffc)) + return 1; + + /* Cyrillic */ + if ((c >= 0x0401 && c <= 0x040d) + || (c >= 0x040f && c <= 0x044f) + || (c >= 0x0451 && c <= 0x045c) + || (c >= 0x045e && c <= 0x0481) + || (c >= 0x0490 && c <= 0x04c4) + || (c >= 0x04c7 && c <= 0x04c8) + || (c >= 0x04cb && c <= 0x04cc) + || (c >= 0x04d0 && c <= 0x04eb) + || (c >= 0x04ee && c <= 0x04f5) + || (c >= 0x04f8 && c <= 0x04f9)) + return 1; + + /* Armenian */ + if ((c >= 0x0531 && c <= 0x0556) + || (c >= 0x0561 && c <= 0x0587)) + return 1; + + /* Hebrew */ + if ((c >= 0x05d0 && c <= 0x05ea) + || (c >= 0x05f0 && c <= 0x05f4)) + return 1; + + /* Arabic */ + if ((c >= 0x0621 && c <= 0x063a) + || (c >= 0x0640 && c <= 0x0652) + || (c >= 0x0670 && c <= 0x06b7) + || (c >= 0x06ba && c <= 0x06be) + || (c >= 0x06c0 && c <= 0x06ce) + || (c >= 0x06e5 && c <= 0x06e7)) + return 1; + + /* Devanagari */ + if ((c >= 0x0905 && c <= 0x0939) + || (c >= 0x0958 && c <= 0x0962)) + return 1; + + /* Bengali */ + if ((c >= 0x0985 && c <= 0x098c) + || (c >= 0x098f && c <= 0x0990) + || (c >= 0x0993 && c <= 0x09a8) + || (c >= 0x09aa && c <= 0x09b0) + || (c == 0x09b2) + || (c >= 0x09b6 && c <= 0x09b9) + || (c >= 0x09dc && c <= 0x09dd) + || (c >= 0x09df && c <= 0x09e1) + || (c >= 0x09f0 && c <= 0x09f1)) + return 1; + + /* Gurmukhi */ + if ((c >= 0x0a05 && c <= 0x0a0a) + || (c >= 0x0a0f && c <= 0x0a10) + || (c >= 0x0a13 && c <= 0x0a28) + || (c >= 0x0a2a && c <= 0x0a30) + || (c >= 0x0a32 && c <= 0x0a33) + || (c >= 0x0a35 && c <= 0x0a36) + || (c >= 0x0a38 && c <= 0x0a39) + || (c >= 0x0a59 && c <= 0x0a5c) + || (c == 0x0a5e)) + return 1; + + /* Gujarati */ + if ((c >= 0x0a85 && c <= 0x0a8b) + || (c == 0x0a8d) + || (c >= 0x0a8f && c <= 0x0a91) + || (c >= 0x0a93 && c <= 0x0aa8) + || (c >= 0x0aaa && c <= 0x0ab0) + || (c >= 0x0ab2 && c <= 0x0ab3) + || (c >= 0x0ab5 && c <= 0x0ab9) + || (c == 0x0ae0)) + return 1; + + /* Oriya */ + if ((c >= 0x0b05 && c <= 0x0b0c) + || (c >= 0x0b0f && c <= 0x0b10) + || (c >= 0x0b13 && c <= 0x0b28) + || (c >= 0x0b2a && c <= 0x0b30) + || (c >= 0x0b32 && c <= 0x0b33) + || (c >= 0x0b36 && c <= 0x0b39) + || (c >= 0x0b5c && c <= 0x0b5d) + || (c >= 0x0b5f && c <= 0x0b61)) + return 1; + + /* Tamil */ + if ((c >= 0x0b85 && c <= 0x0b8a) + || (c >= 0x0b8e && c <= 0x0b90) + || (c >= 0x0b92 && c <= 0x0b95) + || (c >= 0x0b99 && c <= 0x0b9a) + || (c == 0x0b9c) + || (c >= 0x0b9e && c <= 0x0b9f) + || (c >= 0x0ba3 && c <= 0x0ba4) + || (c >= 0x0ba8 && c <= 0x0baa) + || (c >= 0x0bae && c <= 0x0bb5) + || (c >= 0x0bb7 && c <= 0x0bb9)) + return 1; + + /* Telugu */ + if ((c >= 0x0c05 && c <= 0x0c0c) + || (c >= 0x0c0e && c <= 0x0c10) + || (c >= 0x0c12 && c <= 0x0c28) + || (c >= 0x0c2a && c <= 0x0c33) + || (c >= 0x0c35 && c <= 0x0c39) + || (c >= 0x0c60 && c <= 0x0c61)) + return 1; + + /* Kannada */ + if ((c >= 0x0c85 && c <= 0x0c8c) + || (c >= 0x0c8e && c <= 0x0c90) + || (c >= 0x0c92 && c <= 0x0ca8) + || (c >= 0x0caa && c <= 0x0cb3) + || (c >= 0x0cb5 && c <= 0x0cb9) + || (c >= 0x0ce0 && c <= 0x0ce1)) + return 1; + + /* Malayalam */ + if ((c >= 0x0d05 && c <= 0x0d0c) + || (c >= 0x0d0e && c <= 0x0d10) + || (c >= 0x0d12 && c <= 0x0d28) + || (c >= 0x0d2a && c <= 0x0d39) + || (c >= 0x0d60 && c <= 0x0d61)) + return 1; + + /* Thai */ + if ((c >= 0x0e01 && c <= 0x0e30) + || (c >= 0x0e32 && c <= 0x0e33) + || (c >= 0x0e40 && c <= 0x0e46) + || (c >= 0x0e4f && c <= 0x0e5b)) + return 1; + + /* Lao */ + if ((c >= 0x0e81 && c <= 0x0e82) + || (c == 0x0e84) + || (c == 0x0e87) + || (c == 0x0e88) + || (c == 0x0e8a) + || (c == 0x0e0d) + || (c >= 0x0e94 && c <= 0x0e97) + || (c >= 0x0e99 && c <= 0x0e9f) + || (c >= 0x0ea1 && c <= 0x0ea3) + || (c == 0x0ea5) + || (c == 0x0ea7) + || (c == 0x0eaa) + || (c == 0x0eab) + || (c >= 0x0ead && c <= 0x0eb0) + || (c == 0x0eb2) + || (c == 0x0eb3) + || (c == 0x0ebd) + || (c >= 0x0ec0 && c <= 0x0ec4) + || (c == 0x0ec6)) + return 1; + + /* Georgian */ + if ((c >= 0x10a0 && c <= 0x10c5) + || (c >= 0x10d0 && c <= 0x10f6)) + return 1; + + /* Hiragana */ + if ((c >= 0x3041 && c <= 0x3094) + || (c >= 0x309b && c <= 0x309e)) + return 1; + + /* Katakana */ + if ((c >= 0x30a1 && c <= 0x30fe)) + return 1; + + /* Bopmofo */ + if ((c >= 0x3105 && c <= 0x312c)) + return 1; + + /* Hangul */ + if ((c >= 0x1100 && c <= 0x1159) + || (c >= 0x1161 && c <= 0x11a2) + || (c >= 0x11a8 && c <= 0x11f9)) + return 1; + + /* CJK Unified Ideographs */ + if ((c >= 0xf900 && c <= 0xfa2d) + || (c >= 0xfb1f && c <= 0xfb36) + || (c >= 0xfb38 && c <= 0xfb3c) + || (c == 0xfb3e) + || (c >= 0xfb40 && c <= 0xfb41) + || (c >= 0xfb42 && c <= 0xfb44) + || (c >= 0xfb46 && c <= 0xfbb1) + || (c >= 0xfbd3 && c <= 0xfd3f) + || (c >= 0xfd50 && c <= 0xfd8f) + || (c >= 0xfd92 && c <= 0xfdc7) + || (c >= 0xfdf0 && c <= 0xfdfb) + || (c >= 0xfe70 && c <= 0xfe72) + || (c == 0xfe74) + || (c >= 0xfe76 && c <= 0xfefc) + || (c >= 0xff21 && c <= 0xff3a) + || (c >= 0xff41 && c <= 0xff5a) + || (c >= 0xff66 && c <= 0xffbe) + || (c >= 0xffc2 && c <= 0xffc7) + || (c >= 0xffca && c <= 0xffcf) + || (c >= 0xffd2 && c <= 0xffd7) + || (c >= 0xffda && c <= 0xffdc) + || (c >= 0x4e00 && c <= 0x9fa5)) + return 1; + + error ("universal-character-name '\\u%04x' not valid in identifier", c); + return 1; +#endif +} + +/* Add the UTF-8 representation of C to the token_buffer. */ + +static void +utf8_extend_token (c) + int c; { - const char *string = _(msgid); - - /* We can't print string and character constants well - because the token_buffer contains the result of processing escapes. */ - if (end_of_file) - error ("%s at end of input", string); - else if (token_buffer[0] == 0) - error ("%s at null character", string); - else if (token_buffer[0] == '"') - error ("%s before string constant", string); - else if (token_buffer[0] == '\'') - error ("%s before character constant", string); - else if (!ISGRAPH(token_buffer[0])) - error ("%s before character 0%o", string, (unsigned char) token_buffer[0]); + int shift, mask; + + if (c <= 0x0000007f) + { + extend_token (c); + return; + } + else if (c <= 0x000007ff) + shift = 6, mask = 0xc0; + else if (c <= 0x0000ffff) + shift = 12, mask = 0xe0; + else if (c <= 0x001fffff) + shift = 18, mask = 0xf0; + else if (c <= 0x03ffffff) + shift = 24, mask = 0xf8; else - error ("%s before `%s'", string, token_buffer); + shift = 30, mask = 0xfc; + + extend_token (mask | (c >> shift)); + do + { + shift -= 6; + extend_token ((unsigned char) (0x80 | (c >> shift))); + } + while (shift); } +#endif #if 0 - struct try_type { tree *node_var; @@ -1070,15 +1335,14 @@ struct try_type type_sequence[] = struct pf_args { /* Input */ + const char *str; + int fflag; + int lflag; int base; - char * p; - /* I/O */ - int c; /* Output */ - int imag; - tree type; int conversion_errno; REAL_VALUE_TYPE value; + tree type; }; static void @@ -1086,154 +1350,137 @@ parse_float (data) PTR data; { struct pf_args * args = (struct pf_args *) data; - int fflag = 0, lflag = 0; - /* Copy token_buffer now, while it has just the number - and not the suffixes; once we add `f' or `i', - REAL_VALUE_ATOF may not work any more. */ - char *copy = (char *) alloca (args->p - token_buffer + 1); - bcopy (token_buffer, copy, args->p - token_buffer + 1); - args->imag = 0; + const char *typename; + args->conversion_errno = 0; args->type = double_type_node; - - while (1) - { - int lose = 0; - - /* Read the suffixes to choose a data type. */ - switch (args->c) - { - case 'f': case 'F': - if (fflag) - error ("more than one `f' in numeric constant"); - else if (warn_traditional && !in_system_header) - warning ("traditional C rejects the `%c' suffix", args->c); - fflag = 1; - break; - - case 'l': case 'L': - if (lflag) - error ("more than one `l' in numeric constant"); - else if (warn_traditional && !in_system_header) - warning ("traditional C rejects the `%c' suffix", args->c); - lflag = 1; - break; - - case 'i': case 'I': - if (args->imag) - error ("more than one `i' or `j' in numeric constant"); - else if (pedantic) - pedwarn ("ISO C forbids imaginary numeric constants"); - args->imag = 1; - break; - - default: - lose = 1; - } - - if (lose) - break; - - if (args->p >= token_buffer + maxtoken - 3) - args->p = extend_token_buffer (args->p); - *(args->p++) = args->c; - *(args->p) = 0; - args->c = GETC(); - } + typename = "double"; /* The second argument, machine_mode, of REAL_VALUE_ATOF tells the desired precision of the binary result of decimal-to-binary conversion. */ - if (fflag) + if (args->fflag) { - if (lflag) - error ("both `f' and `l' in floating constant"); + if (args->lflag) + error ("both 'f' and 'l' suffixes on floating constant"); args->type = float_type_node; - errno = 0; - if (args->base == 16) - args->value = REAL_VALUE_HTOF (copy, TYPE_MODE (args->type)); - else - args->value = REAL_VALUE_ATOF (copy, TYPE_MODE (args->type)); - args->conversion_errno = errno; - /* A diagnostic is required here by some ANSI C testsuites. - This is not pedwarn, because some people don't want - an error for this. */ - if (REAL_VALUE_ISINF (args->value) && pedantic) - warning ("floating point number exceeds range of `float'"); + typename = "float"; } - else if (lflag) + else if (args->lflag) { args->type = long_double_type_node; - errno = 0; - if (args->base == 16) - args->value = REAL_VALUE_HTOF (copy, TYPE_MODE (args->type)); - else - args->value = REAL_VALUE_ATOF (copy, TYPE_MODE (args->type)); - args->conversion_errno = errno; - if (REAL_VALUE_ISINF (args->value) && pedantic) - warning ("floating point number exceeds range of `long double'"); + typename = "long double"; } - else + else if (flag_single_precision_constant) { - errno = 0; - if (flag_single_precision_constant) - args->type = float_type_node; - if (args->base == 16) - args->value = REAL_VALUE_HTOF (copy, TYPE_MODE (args->type)); - else - args->value = REAL_VALUE_ATOF (copy, TYPE_MODE (args->type)); - args->conversion_errno = errno; - if (REAL_VALUE_ISINF (args->value) && pedantic) - warning ("floating point number exceeds range of `double'"); + args->type = float_type_node; + typename = "float"; } + + errno = 0; + if (args->base == 16) + args->value = REAL_VALUE_HTOF (args->str, TYPE_MODE (args->type)); + else + args->value = REAL_VALUE_ATOF (args->str, TYPE_MODE (args->type)); + + args->conversion_errno = errno; + /* A diagnostic is required here by some ISO C testsuites. + This is not pedwarn, because some people don't want + an error for this. */ + if (REAL_VALUE_ISINF (args->value) && pedantic) + warning ("floating point number exceeds range of '%s'", typename); } -/* Get the next character, staying within the current token if possible. - If we're lexing a token, we don't want to look beyond the end of the - token cpplib has prepared for us; otherwise, we end up reading in the - next token, which screws up feed_input. So just return a null - character. */ - -static inline int token_getch PARAMS ((void)); - -static inline int -token_getch () +int +c_lex (value) + tree *value; { #if USE_CPPLIB - if (yy_cur == yy_lim) - return '\0'; -#endif - return GETC (); -} + const cpp_token *tok; + enum cpp_ttype type; + + retry: + timevar_push (TV_CPP); + tok = cpp_get_token (&parse_in); + timevar_pop (TV_CPP); + + /* The C++ front end does horrible things with the current line + number. To ensure an accurate line number, we must reset it + every time we return a token. If we reset it from tok->line + every time, we'll get line numbers inside macros referring to the + macro definition; this is nice, but we don't want to change the + behavior until integrated mode is the only option. So we keep our + own idea of the line number, and reset it from tok->line at each + new line (which never happens inside a macro). */ + if (tok->flags & BOL) + lex_lineno = tok->line; + + *value = NULL_TREE; + lineno = lex_lineno; + type = tok->type; + switch (type) + { + case CPP_OPEN_BRACE: indent_level++; break; + case CPP_CLOSE_BRACE: indent_level--; break; + + /* Issue this error here, where we can get at tok->val.aux. */ + case CPP_OTHER: + if (ISGRAPH (tok->val.aux)) + error ("stray '%c' in program", tok->val.aux); + else + error ("stray '\\%#o' in program", tok->val.aux); + goto retry; + + case CPP_DEFINED: + type = CPP_NAME; + case CPP_NAME: + *value = get_identifier ((const char *)tok->val.node->name); + break; -static inline void token_put_back PARAMS ((int)); + case CPP_INT: + case CPP_FLOAT: + case CPP_NUMBER: + *value = lex_number ((const char *)tok->val.str.text, tok->val.str.len); + break; -static inline void -token_put_back (ch) - int ch; -{ -#if USE_CPPLIB - if (ch == '\0') - return; -#endif - UNGETC (ch); -} + case CPP_CHAR: + case CPP_WCHAR: + *value = lex_charconst ((const char *)tok->val.str.text, + tok->val.str.len, tok->type == CPP_WCHAR); + break; -/* Read a single token from the input stream, and assign it lexical - semantics. */ + case CPP_STRING: + case CPP_WSTRING: + case CPP_OSTRING: + *value = lex_string ((const char *)tok->val.str.text, + tok->val.str.len, tok->type == CPP_WSTRING); + break; -int -yylex () -{ - register int c; - register char *p; - register int value; + /* These tokens should not be visible outside cpplib. */ + case CPP_HEADER_NAME: + case CPP_COMMENT: + case CPP_MACRO_ARG: + case CPP_PLACEMARKER: + abort (); + + default: break; + } + + return type; + +#else + int c; + char *p; int wide_flag = 0; int objc_flag = 0; + int charconst = 0; + + *value = NULL_TREE; - c = GETC(); + retry: + c = getch (); /* Effectively do c = skip_white_space (c) but do it faster in the usual cases. */ @@ -1244,81 +1491,54 @@ yylex () case '\t': case '\f': case '\v': - case '\b': -#if USE_CPPLIB - if (cpp_token == CPP_HSPACE) - c = yy_get_token (); - else -#endif - c = GETC(); + c = getch (); break; - case '\r': - /* Call skip_white_space so we can warn if appropriate. */ - case '\n': - case '/': - case '\\': c = skip_white_space (c); default: goto found_nonwhite; } found_nonwhite: - token_buffer[0] = c; - token_buffer[1] = 0; - -/* yylloc.first_line = lineno; */ + lineno = lex_lineno; switch (c) { case EOF: - end_of_file = 1; - token_buffer[0] = 0; - if (linemode) - value = END_OF_LINE; - else - value = ENDFILE; - break; + return CPP_EOF; case 'L': -#if USE_CPPLIB - if (cpp_token == CPP_NAME) - goto letter; -#endif /* Capital L may start a wide-string or wide-character constant. */ { - register int c = token_getch(); - if (c == '\'') + register int c1 = getch(); + if (c1 == '\'') { wide_flag = 1; goto char_constant; } - if (c == '"') + if (c1 == '"') { wide_flag = 1; goto string_constant; } - token_put_back (c); + put_back (c1); } goto letter; case '@': if (!doing_objc_thang) - { - value = c; - break; - } + goto straychar; else { /* '@' may start a constant string object. */ - register int c = token_getch (); - if (c == '"') + register int c1 = getch (); + if (c1 == '"') { objc_flag = 1; goto string_constant; } - token_put_back (c); + put_back (c1); /* Fall through to treat '@' as the start of an identifier. */ } @@ -1337,1122 +1557,971 @@ yylex () case '_': case '$': letter: -#if USE_CPPLIB - if (cpp_token == CPP_NAME) - { - /* Note that one character has already been read from - yy_cur into token_buffer. Also, cpplib complains about - $ in identifiers, so we don't have to. */ - - int len = yy_lim - yy_cur + 1; - if (len >= maxtoken) - extend_token_buffer_to (len + 1); - memcpy (token_buffer + 1, yy_cur, len); - p = token_buffer + len; - yy_cur = yy_lim; - } - else -#endif + p = token_buffer; + while (ISALNUM (c) || c == '_' || c == '$' || c == '@') { - p = token_buffer; - while (ISALNUM (c) || c == '_' || c == '$' || c == '@') + /* Make sure this char really belongs in an identifier. */ + if (c == '$') { - /* Make sure this char really belongs in an identifier. */ - if (c == '$') - { - if (! dollars_in_ident) - error ("`$' in identifier"); - else if (pedantic) - pedwarn ("`$' in identifier"); - } - - if (p >= token_buffer + maxtoken) - p = extend_token_buffer (p); - - *p++ = c; - c = token_getch(); + if (! dollars_in_ident) + error ("'$' in identifier"); + else if (pedantic) + pedwarn ("'$' in identifier"); } - *p = 0; - token_put_back (c); - } - - value = IDENTIFIER; - yylval.itype = 0; - - /* Try to recognize a keyword. Uses minimum-perfect hash function */ - - { - register struct resword *ptr; - - if ((ptr = is_reserved_word (token_buffer, p - token_buffer))) - { - if (ptr->rid) - yylval.ttype = ridpointers[(int) ptr->rid]; - value = (int) ptr->token; - - /* Only return OBJECTNAME if it is a typedef. */ - if (doing_objc_thang && value == OBJECTNAME) - { - tree decl = lookup_name(yylval.ttype); - - if (decl == NULL_TREE - || TREE_CODE (decl) != TYPE_DECL) - value = IDENTIFIER; - } - - /* Even if we decided to recognize asm, still perhaps warn. */ - if (pedantic - && (value == ASM_KEYWORD || value == TYPEOF - || (ptr->rid == RID_INLINE && ! flag_isoc99)) - && token_buffer[0] != '_') - pedwarn ("ANSI does not permit the keyword `%s'", - token_buffer); - } - } - - /* If we did not find a keyword, look for an identifier - (or a typename). */ + if (p >= token_buffer + maxtoken) + p = extend_token_buffer (p); - if (value == IDENTIFIER) - { - tree decl; - - if (token_buffer[0] == '@') - error("invalid identifier `%s'", token_buffer); - - yylval.ttype = get_identifier (token_buffer); - decl = lookup_name (yylval.ttype); - - if (decl != 0 && TREE_CODE (decl) == TYPE_DECL) - value = TYPENAME; - /* A user-invisible read-only initialized variable - should be replaced by its value. - We handle only strings since that's the only case used in C. */ - else if (decl != 0 && TREE_CODE (decl) == VAR_DECL - && DECL_IGNORED_P (decl) - && TREE_READONLY (decl) - && DECL_INITIAL (decl) != 0 - && TREE_CODE (DECL_INITIAL (decl)) == STRING_CST) - { - tree stringval = DECL_INITIAL (decl); + *p++ = c; + c = getch(); + } - /* Copy the string value so that we won't clobber anything - if we put something in the TREE_CHAIN of this one. */ - yylval.ttype = build_string (TREE_STRING_LENGTH (stringval), - TREE_STRING_POINTER (stringval)); - value = STRING; - } - else if (doing_objc_thang) - { - tree objc_interface_decl = is_class_name (yylval.ttype); + put_back (c); - if (objc_interface_decl) - { - value = CLASSNAME; - yylval.ttype = objc_interface_decl; - } - } - } + if (p >= token_buffer + maxtoken) + p = extend_token_buffer (p); + *p = 0; - break; + *value = get_identifier (token_buffer); + return CPP_NAME; case '.': -#if USE_CPPLIB - if (yy_cur < yy_lim) -#endif { /* It's hard to preserve tokenization on '.' because it could be a symbol by itself, or it could be the start of a floating point number and cpp won't tell us. */ - register int c1 = token_getch (); - token_buffer[1] = c1; + int c1 = getch (); if (c1 == '.') { - c1 = token_getch (); - if (c1 == '.') - { - token_buffer[2] = c1; - token_buffer[3] = 0; - value = ELLIPSIS; - goto done; - } - error ("parse error at `..'"); + int c2 = getch (); + if (c2 == '.') + return CPP_ELLIPSIS; + + put_back (c2); + error ("parse error at '..'"); } + else if (c1 == '*' && c_language == clk_cplusplus) + return CPP_DOT_STAR; + + put_back (c1); if (ISDIGIT (c1)) - { - token_put_back (c1); - goto number; - } - token_put_back (c1); + goto number; } - value = '.'; - token_buffer[1] = 0; - break; - - case '0': case '1': - /* Optimize for most frequent case. */ - { - register int cond; + return CPP_DOT; -#if USE_CPPLIB - cond = (yy_cur == yy_lim); -#else - register int c1 = token_getch (); - token_put_back (c1); - cond = (! ISALNUM (c1) && c1 != '.'); -#endif - if (cond) - { - yylval.ttype = (c == '0') ? integer_zero_node : integer_one_node; - value = CONSTANT; - break; - } - /*FALLTHRU*/ - } - case '2': case '3': case '4': + case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': number: - { - int base = 10; - int count = 0; - int largest_digit = 0; - int numdigits = 0; - int overflow = 0; - - /* We actually store only HOST_BITS_PER_CHAR bits in each part. - The code below which fills the parts array assumes that a host - int is at least twice as wide as a host char, and that - HOST_BITS_PER_WIDE_INT is an even multiple of HOST_BITS_PER_CHAR. - Two HOST_WIDE_INTs is the largest int literal we can store. - In order to detect overflow below, the number of parts (TOTAL_PARTS) - must be exactly the number of parts needed to hold the bits - of two HOST_WIDE_INTs. */ -#define TOTAL_PARTS ((HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR) * 2) - unsigned int parts[TOTAL_PARTS]; + p = token_buffer; + /* Scan the next preprocessing number. All C numeric constants + are preprocessing numbers, but not all preprocessing numbers + are valid numeric constants. Preprocessing numbers fit the + regular expression \.?[0-9]([0-9a-zA-Z_.]|[eEpP][+-])* + See C99 section 6.4.8. */ + for (;;) + { + if (p >= token_buffer + maxtoken) + p = extend_token_buffer (p); - enum anon1 { NOT_FLOAT, AFTER_POINT, TOO_MANY_POINTS, AFTER_EXPON} - floatflag = NOT_FLOAT; + *p++ = c; + c = getch(); - for (count = 0; count < TOTAL_PARTS; count++) - parts[count] = 0; + if (c == '+' || c == '-') + { + int d = p[-1]; + if (d == 'e' || d == 'E' || d == 'p' || d == 'P') + continue; + } + if (ISALNUM (c) || c == '_' || c == '.') + continue; + break; + } + put_back (c); - p = token_buffer; - *p++ = c; + *value = lex_number (token_buffer, p - token_buffer); + return CPP_NUMBER; - if (c == '0') - { - *p++ = (c = token_getch()); - if ((c == 'x') || (c == 'X')) - { - base = 16; - *p++ = (c = token_getch()); - } - /* Leading 0 forces octal unless the 0 is the only digit. */ - else if (c >= '0' && c <= '9') - { - base = 8; - numdigits++; - } - else - numdigits++; - } + case '\'': + char_constant: + charconst = 1; - /* Read all the digits-and-decimal-points. */ + case '"': + string_constant: + { + int delimiter = charconst ? '\'' : '"'; +#ifdef MULTIBYTE_CHARS + int longest_char = local_mb_cur_max (); + (void) local_mbtowc (NULL_PTR, NULL_PTR, 0); +#endif + c = getch (); + p = token_buffer + 1; - while (c == '.' - || (ISALNUM (c) && c != 'l' && c != 'L' - && c != 'u' && c != 'U' - && c != 'i' && c != 'I' && c != 'j' && c != 'J' - && (floatflag == NOT_FLOAT - || ((base != 16) && (c != 'f') && (c != 'F')) - || base == 16))) + while (c != delimiter && c != EOF) { - if (c == '.') + if (p + 2 > token_buffer + maxtoken) + p = extend_token_buffer (p); + + /* ignore_escape_flag is set for reading the filename in #line. */ + if (!ignore_escape_flag && c == '\\') { - if (base == 16 && pedantic && !flag_isoc99) - pedwarn ("floating constant may not be in radix 16"); - if (floatflag == TOO_MANY_POINTS) - /* We have already emitted an error. Don't need another. */ - ; - else if (floatflag == AFTER_POINT || floatflag == AFTER_EXPON) - { - error ("malformed floating constant"); - floatflag = TOO_MANY_POINTS; - /* Avoid another error from atof by forcing all characters - from here on to be ignored. */ - p[-1] = '\0'; - } - else - floatflag = AFTER_POINT; - - if (base == 8) - base = 10; - *p++ = c = token_getch(); - /* Accept '.' as the start of a floating-point number - only when it is followed by a digit. */ - if (p == token_buffer + 2 && !ISDIGIT (c)) - abort (); + *p++ = c; + *p++ = getch (); /* escaped character */ + c = getch (); + continue; } else { - /* It is not a decimal point. - It should be a digit (perhaps a hex digit). */ - - if (ISDIGIT (c)) - { - c = c - '0'; - } - else if (base <= 10) - { - if (c == 'e' || c == 'E') - { - base = 10; - floatflag = AFTER_EXPON; - break; /* start of exponent */ - } - error ("nondigits in number and not hexadecimal"); - c = 0; - } - else if (base == 16 && (c == 'p' || c == 'P')) - { - floatflag = AFTER_EXPON; - break; /* start of exponent */ - } - else if (c >= 'a' && c <= 'f') - { - c = c - 'a' + 10; - } - else +#ifdef MULTIBYTE_CHARS + int i; + int char_len = -1; + for (i = 0; i < longest_char; ++i) { - c = c - 'A' + 10; - } - if (c >= largest_digit) - largest_digit = c; - numdigits++; + if (p + i >= token_buffer + maxtoken) + p = extend_token_buffer (p); + p[i] = c; - for (count = 0; count < TOTAL_PARTS; count++) - { - parts[count] *= base; - if (count) - { - parts[count] - += (parts[count-1] >> HOST_BITS_PER_CHAR); - parts[count-1] - &= (1 << HOST_BITS_PER_CHAR) - 1; - } - else - parts[0] += c; + char_len = local_mblen (p, i + 1); + if (char_len != -1) + break; + c = getch (); } - - /* If the highest-order part overflows (gets larger than - a host char will hold) then the whole number has - overflowed. Record this and truncate the highest-order - part. */ - if (parts[TOTAL_PARTS - 1] >> HOST_BITS_PER_CHAR) + if (char_len == -1) { - overflow = 1; - parts[TOTAL_PARTS - 1] &= (1 << HOST_BITS_PER_CHAR) - 1; + /* Replace all except the first byte. */ + put_back (c); + for (--i; i > 0; --i) + put_back (p[i]); + char_len = 1; } + /* mbtowc sometimes needs an extra char before accepting */ + else if (char_len <= i) + put_back (c); - if (p >= token_buffer + maxtoken - 3) - p = extend_token_buffer (p); - *p++ = (c = token_getch()); + p += char_len; +#else + *p++ = c; +#endif + c = getch (); } } + } - /* This can happen on input like `int i = 0x;' */ - if (numdigits == 0) - error ("numeric constant with no digits"); - - if (largest_digit >= base) - error ("numeric constant contains digits beyond the radix"); + if (charconst) + { + *value = lex_charconst (token_buffer + 1, p - (token_buffer + 1), + wide_flag); + return wide_flag ? CPP_WCHAR : CPP_CHAR; + } + else + { + *value = lex_string (token_buffer + 1, p - (token_buffer + 1), + wide_flag); + return wide_flag ? CPP_WSTRING : objc_flag ? CPP_OSTRING : CPP_STRING; + } - /* Remove terminating char from the token buffer and delimit the - string. */ - *--p = 0; + case '+': + case '-': + case '&': + case '|': + case ':': + case '<': + case '>': + case '*': + case '/': + case '%': + case '^': + case '!': + case '=': + { + int c1; + enum cpp_ttype type = CPP_EOF; - if (floatflag != NOT_FLOAT) + switch (c) { - tree type; - int imag, conversion_errno; - REAL_VALUE_TYPE value; - struct pf_args args; - - /* Read explicit exponent if any, and put it in tokenbuf. */ + case '+': type = CPP_PLUS; break; + case '-': type = CPP_MINUS; break; + case '&': type = CPP_AND; break; + case '|': type = CPP_OR; break; + case ':': type = CPP_COLON; break; + case '<': type = CPP_LESS; break; + case '>': type = CPP_GREATER; break; + case '*': type = CPP_MULT; break; + case '/': type = CPP_DIV; break; + case '%': type = CPP_MOD; break; + case '^': type = CPP_XOR; break; + case '!': type = CPP_NOT; break; + case '=': type = CPP_EQ; break; + } - if ((base == 10 && ((c == 'e') || (c == 'E'))) - || (base == 16 && (c == 'p' || c == 'P'))) - { - if (p >= token_buffer + maxtoken - 3) - p = extend_token_buffer (p); - *p++ = c; - c = token_getch(); - if ((c == '+') || (c == '-')) - { - *p++ = c; - c = token_getch(); - } - /* Exponent is decimal, even if string is a hex float. */ - if (! ISDIGIT (c)) - error ("floating constant exponent has no digits"); - while (ISDIGIT (c)) - { - if (p >= token_buffer + maxtoken - 3) - p = extend_token_buffer (p); - *p++ = c; - c = token_getch (); - } - } - if (base == 16 && floatflag != AFTER_EXPON) - error ("hexadecimal floating constant has no exponent"); + c1 = getch (); - *p = 0; + if (c1 == '=' && type < CPP_LAST_EQ) + return type + (CPP_EQ_EQ - CPP_EQ); + else if (c == c1) + switch (c) + { + case '+': return CPP_PLUS_PLUS; + case '-': return CPP_MINUS_MINUS; + case '&': return CPP_AND_AND; + case '|': return CPP_OR_OR; + case ':': + if (c_language == clk_cplusplus) + return CPP_SCOPE; + break; - /* Setup input for parse_float() */ - args.base = base; - args.p = p; - args.c = c; + case '<': type = CPP_LSHIFT; goto do_triad; + case '>': type = CPP_RSHIFT; goto do_triad; + } + else + switch (c) + { + case '-': + if (c1 == '>') + { + if (c_language == clk_cplusplus) + { + c1 = getch (); + if (c1 == '*') + return CPP_DEREF_STAR; + put_back (c1); + } + return CPP_DEREF; + } + break; - /* Convert string to a double, checking for overflow. */ - if (do_float_handler (parse_float, (PTR) &args)) - { - /* Receive output from parse_float() */ - value = args.value; - } - else - { - /* We got an exception from parse_float() */ - error ("floating constant out of range"); - value = dconst0; - } + case '>': + if (c1 == '?' && c_language == clk_cplusplus) + { type = CPP_MAX; goto do_triad; } + break; - /* Receive output from parse_float() */ - c = args.c; - imag = args.imag; - type = args.type; - conversion_errno = args.conversion_errno; - -#ifdef ERANGE - /* ERANGE is also reported for underflow, - so test the value to distinguish overflow from that. */ - if (conversion_errno == ERANGE && !flag_traditional && pedantic - && (REAL_VALUES_LESS (dconst1, value) - || REAL_VALUES_LESS (value, dconstm1))) - warning ("floating point number exceeds range of `double'"); -#endif + case '<': + if (c1 == ':' && flag_digraphs) + return CPP_OPEN_SQUARE; + if (c1 == '%' && flag_digraphs) + { indent_level++; return CPP_OPEN_BRACE; } + if (c1 == '?' && c_language == clk_cplusplus) + { type = CPP_MIN; goto do_triad; } + break; - /* If the result is not a number, assume it must have been - due to some error message above, so silently convert - it to a zero. */ - if (REAL_VALUE_ISNAN (value)) - value = dconst0; + case ':': + if (c1 == '>' && flag_digraphs) + return CPP_CLOSE_SQUARE; + break; + case '%': + if (c1 == '>' && flag_digraphs) + { indent_level--; return CPP_CLOSE_BRACE; } + break; + } - /* Create a node with determined type and value. */ - if (imag) - yylval.ttype = build_complex (NULL_TREE, - convert (type, integer_zero_node), - build_real (type, value)); - else - yylval.ttype = build_real (type, value); - } - else - { - tree traditional_type, ansi_type, type; - HOST_WIDE_INT high, low; - int spec_unsigned = 0; - int spec_long = 0; - int spec_long_long = 0; - int suffix_lu = 0; - int spec_imag = 0; - int warn = 0, i; - - traditional_type = ansi_type = type = NULL_TREE; - while (1) - { - if (c == 'u' || c == 'U') - { - if (spec_unsigned) - error ("two `u's in integer constant"); - else if (warn_traditional && !in_system_header) - warning ("traditional C rejects the `%c' suffix", c); - spec_unsigned = 1; - if (spec_long) - suffix_lu = 1; - } - else if (c == 'l' || c == 'L') - { - if (spec_long) - { - if (spec_long_long) - error ("three `l's in integer constant"); - else if (suffix_lu) - error ("`LUL' is not a valid integer suffix"); - else if (c != spec_long) - error ("`Ll' and `lL' are not valid integer suffixes"); - else if (pedantic && ! flag_isoc99 - && ! in_system_header && warn_long_long) - pedwarn ("ISO C89 forbids long long integer constants"); - spec_long_long = 1; - } - spec_long = c; - } - else if (c == 'i' || c == 'j' || c == 'I' || c == 'J') - { - if (spec_imag) - error ("more than one `i' or `j' in numeric constant"); - else if (pedantic) - pedwarn ("ISO C forbids imaginary numeric constants"); - spec_imag = 1; - } - else - break; - if (p >= token_buffer + maxtoken - 3) - p = extend_token_buffer (p); - *p++ = c; - c = token_getch(); - } + put_back (c1); + return type; - /* If the literal overflowed, pedwarn about it now. */ - if (overflow) - { - warn = 1; - pedwarn ("integer constant is too large for this configuration of the compiler - truncated to %d bits", HOST_BITS_PER_WIDE_INT * 2); - } + do_triad: + c1 = getch (); + if (c1 == '=') + type += (CPP_EQ_EQ - CPP_EQ); + else + put_back (c1); + return type; + } - /* This is simplified by the fact that our constant - is always positive. */ + case '~': return CPP_COMPL; + case '?': return CPP_QUERY; + case ',': return CPP_COMMA; + case '(': return CPP_OPEN_PAREN; + case ')': return CPP_CLOSE_PAREN; + case '[': return CPP_OPEN_SQUARE; + case ']': return CPP_CLOSE_SQUARE; + case '{': indent_level++; return CPP_OPEN_BRACE; + case '}': indent_level--; return CPP_CLOSE_BRACE; + case ';': return CPP_SEMICOLON; + + straychar: + default: + if (ISGRAPH (c)) + error ("stray '%c' in program", c); + else + error ("stray '\\%#o' in program", c); + goto retry; + } + /* NOTREACHED */ +#endif +} - high = low = 0; - for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR; i++) - { - high |= ((HOST_WIDE_INT) parts[i + (HOST_BITS_PER_WIDE_INT - / HOST_BITS_PER_CHAR)] - << (i * HOST_BITS_PER_CHAR)); - low |= (HOST_WIDE_INT) parts[i] << (i * HOST_BITS_PER_CHAR); - } +#define ERROR(msgid) do { error(msgid); goto syntax_error; } while(0) - yylval.ttype = build_int_2 (low, high); - TREE_TYPE (yylval.ttype) = long_long_unsigned_type_node; +static tree +lex_number (str, len) + const char *str; + unsigned int len; +{ + int base = 10; + int count = 0; + int largest_digit = 0; + int numdigits = 0; + int overflow = 0; + int c; + tree value; + const char *p; + enum anon1 { NOT_FLOAT = 0, AFTER_POINT, AFTER_EXPON } floatflag = NOT_FLOAT; + + /* We actually store only HOST_BITS_PER_CHAR bits in each part. + The code below which fills the parts array assumes that a host + int is at least twice as wide as a host char, and that + HOST_BITS_PER_WIDE_INT is an even multiple of HOST_BITS_PER_CHAR. + Two HOST_WIDE_INTs is the largest int literal we can store. + In order to detect overflow below, the number of parts (TOTAL_PARTS) + must be exactly the number of parts needed to hold the bits + of two HOST_WIDE_INTs. */ +#define TOTAL_PARTS ((HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR) * 2) + unsigned int parts[TOTAL_PARTS]; + + /* Optimize for most frequent case. */ + if (len == 1) + { + if (*str == '0') + return integer_zero_node; + else if (*str == '1') + return integer_one_node; + else + return build_int_2 (*str - '0', 0); + } - /* If warn_traditional, calculate both the ANSI type and the - traditional type, then see if they disagree. - Otherwise, calculate only the type for the dialect in use. */ - if (warn_traditional || flag_traditional) - { - /* Calculate the traditional type. */ - /* Traditionally, any constant is signed; - but if unsigned is specified explicitly, obey that. - Use the smallest size with the right number of bits, - except for one special case with decimal constants. */ - if (! spec_long && base != 10 - && int_fits_type_p (yylval.ttype, unsigned_type_node)) - traditional_type = (spec_unsigned ? unsigned_type_node - : integer_type_node); - /* A decimal constant must be long - if it does not fit in type int. - I think this is independent of whether - the constant is signed. */ - else if (! spec_long && base == 10 - && int_fits_type_p (yylval.ttype, integer_type_node)) - traditional_type = (spec_unsigned ? unsigned_type_node - : integer_type_node); - else if (! spec_long_long) - traditional_type = (spec_unsigned ? long_unsigned_type_node - : long_integer_type_node); - else if (int_fits_type_p (yylval.ttype, - spec_unsigned - ? long_long_unsigned_type_node - : long_long_integer_type_node)) - traditional_type = (spec_unsigned - ? long_long_unsigned_type_node - : long_long_integer_type_node); - else - traditional_type = (spec_unsigned - ? widest_unsigned_literal_type_node - : widest_integer_literal_type_node); - } - if (warn_traditional || ! flag_traditional) - { - /* Calculate the ANSI type. */ - if (! spec_long && ! spec_unsigned - && int_fits_type_p (yylval.ttype, integer_type_node)) - ansi_type = integer_type_node; - else if (! spec_long && (base != 10 || spec_unsigned) - && int_fits_type_p (yylval.ttype, unsigned_type_node)) - ansi_type = unsigned_type_node; - else if (! spec_unsigned && !spec_long_long - && int_fits_type_p (yylval.ttype, long_integer_type_node)) - ansi_type = long_integer_type_node; - else if (! spec_long_long - && int_fits_type_p (yylval.ttype, - long_unsigned_type_node)) - ansi_type = long_unsigned_type_node; - else if (! spec_unsigned - && int_fits_type_p (yylval.ttype, - long_long_integer_type_node)) - ansi_type = long_long_integer_type_node; - else if (int_fits_type_p (yylval.ttype, - long_long_unsigned_type_node)) - ansi_type = long_long_unsigned_type_node; - else if (! spec_unsigned - && int_fits_type_p (yylval.ttype, - widest_integer_literal_type_node)) - ansi_type = widest_integer_literal_type_node; - else - ansi_type = widest_unsigned_literal_type_node; - } + for (count = 0; count < TOTAL_PARTS; count++) + parts[count] = 0; - type = flag_traditional ? traditional_type : ansi_type; + /* len is known to be >1 at this point. */ + p = str; - /* We assume that constants specified in a non-decimal - base are bit patterns, and that the programmer really - meant what they wrote. */ - if (warn_traditional && !in_system_header && base == 10 - && traditional_type != ansi_type) - { - if (TYPE_PRECISION (traditional_type) - != TYPE_PRECISION (ansi_type)) - warning ("width of integer constant changes with -traditional"); - else if (TREE_UNSIGNED (traditional_type) - != TREE_UNSIGNED (ansi_type)) - warning ("integer constant is unsigned in ISO C, signed with -traditional"); - else - warning ("width of integer constant may change on other systems with -traditional"); - } + if (len > 2 && str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) + { + base = 16; + p = str + 2; + } + /* The ISDIGIT check is so we are not confused by a suffix on 0. */ + else if (str[0] == '0' && ISDIGIT (str[1])) + { + base = 8; + p = str + 1; + } - if (pedantic && !flag_traditional && !spec_long_long && !warn - && (TYPE_PRECISION (long_integer_type_node) - < TYPE_PRECISION (type))) - { - warn = 1; - pedwarn ("integer constant larger than the maximum value of an unsigned long int"); - } + do + { + c = *p++; - if (base == 10 && ! spec_unsigned && TREE_UNSIGNED (type)) - warning ("decimal constant is so large that it is unsigned"); + if (c == '.') + { + if (base == 16 && pedantic && !flag_isoc99) + pedwarn ("floating constant may not be in radix 16"); + else if (floatflag == AFTER_POINT) + ERROR ("too many decimal points in floating constant"); + else if (floatflag == AFTER_EXPON) + ERROR ("decimal point in exponent - impossible!"); + else + floatflag = AFTER_POINT; - if (spec_imag) - { - if (TYPE_PRECISION (type) - <= TYPE_PRECISION (integer_type_node)) - yylval.ttype - = build_complex (NULL_TREE, integer_zero_node, - convert (integer_type_node, - yylval.ttype)); - else - error ("complex integer constant is too wide for `complex int'"); - } - else if (flag_traditional && !int_fits_type_p (yylval.ttype, type)) - /* The traditional constant 0x80000000 is signed - but doesn't fit in the range of int. - This will change it to -0x80000000, which does fit. */ - { - TREE_TYPE (yylval.ttype) = unsigned_type (type); - yylval.ttype = convert (type, yylval.ttype); - TREE_OVERFLOW (yylval.ttype) - = TREE_CONSTANT_OVERFLOW (yylval.ttype) = 0; - } - else - TREE_TYPE (yylval.ttype) = type; + if (base == 8) + base = 10; + } + else if (c == '_') + /* Possible future extension: silently ignore _ in numbers, + permitting cosmetic grouping - e.g. 0x8000_0000 == 0x80000000 + but somewhat easier to read. Ada has this? */ + ERROR ("underscore in number"); + else + { + int n; + /* It is not a decimal point. + It should be a digit (perhaps a hex digit). */ + if (ISDIGIT (c)) + { + n = c - '0'; + } + else if (base <= 10 && (c == 'e' || c == 'E')) + { + base = 10; + floatflag = AFTER_EXPON; + break; + } + else if (base == 16 && (c == 'p' || c == 'P')) + { + floatflag = AFTER_EXPON; + break; /* start of exponent */ + } + else if (base == 16 && c >= 'a' && c <= 'f') + { + n = c - 'a' + 10; + } + else if (base == 16 && c >= 'A' && c <= 'F') + { + n = c - 'A' + 10; + } + else + { + p--; + break; /* start of suffix */ + } - /* If it's still an integer (not a complex), and it doesn't - fit in the type we choose for it, then pedwarn. */ + if (n >= largest_digit) + largest_digit = n; + numdigits++; - if (! warn - && TREE_CODE (TREE_TYPE (yylval.ttype)) == INTEGER_TYPE - && ! int_fits_type_p (yylval.ttype, TREE_TYPE (yylval.ttype))) - pedwarn ("integer constant is larger than the maximum value for its type"); - } + for (count = 0; count < TOTAL_PARTS; count++) + { + parts[count] *= base; + if (count) + { + parts[count] + += (parts[count-1] >> HOST_BITS_PER_CHAR); + parts[count-1] + &= (1 << HOST_BITS_PER_CHAR) - 1; + } + else + parts[0] += n; + } - token_put_back (c); - *p = 0; + /* If the highest-order part overflows (gets larger than + a host char will hold) then the whole number has + overflowed. Record this and truncate the highest-order + part. */ + if (parts[TOTAL_PARTS - 1] >> HOST_BITS_PER_CHAR) + { + overflow = 1; + parts[TOTAL_PARTS - 1] &= (1 << HOST_BITS_PER_CHAR) - 1; + } + } + } + while (p < str + len); - if (ISALNUM (c) || c == '.' || c == '_' || c == '$' - || (!flag_traditional && (c == '-' || c == '+') - && (p[-1] == 'e' || p[-1] == 'E'))) - error ("missing white space after number `%s'", token_buffer); + /* This can happen on input like `int i = 0x;' */ + if (numdigits == 0) + ERROR ("numeric constant with no digits"); - value = CONSTANT; break; - } + if (largest_digit >= base) + ERROR ("numeric constant contains digits beyond the radix"); - case '\'': - char_constant: - { - register int result = 0; - register int num_chars = 0; - int chars_seen = 0; - unsigned width = TYPE_PRECISION (char_type_node); - int max_chars; -#ifdef MULTIBYTE_CHARS - int longest_char = local_mb_cur_max (); - (void) local_mbtowc (NULL_PTR, NULL_PTR, 0); -#endif + if (floatflag != NOT_FLOAT) + { + tree type; + int imag, fflag, lflag, conversion_errno; + REAL_VALUE_TYPE real; + struct pf_args args; + char *copy; + + if (base == 16 && floatflag != AFTER_EXPON) + ERROR ("hexadecimal floating constant has no exponent"); + + /* Read explicit exponent if any, and put it in tokenbuf. */ + if ((base == 10 && ((c == 'e') || (c == 'E'))) + || (base == 16 && (c == 'p' || c == 'P'))) + { + if (p < str + len) + c = *p++; + if (p < str + len && (c == '+' || c == '-')) + c = *p++; + /* Exponent is decimal, even if string is a hex float. */ + if (! ISDIGIT (c)) + ERROR ("floating constant exponent has no digits"); + while (p < str + len && ISDIGIT (c)) + c = *p++; + if (! ISDIGIT (c)) + p--; + } - max_chars = TYPE_PRECISION (integer_type_node) / width; - if (wide_flag) - width = WCHAR_TYPE_SIZE; + /* Copy the float constant now; we don't want any suffixes in the + string passed to parse_float. */ + copy = alloca (p - str + 1); + memcpy (copy, str, p - str); + copy[p - str] = '\0'; - while (1) + /* Now parse suffixes. */ + fflag = lflag = imag = 0; + while (p < str + len) + switch (*p++) { - tryagain: - c = token_getch(); + case 'f': case 'F': + if (fflag) + ERROR ("more than one 'f' suffix on floating constant"); + else if (warn_traditional && !in_system_header) + warning ("traditional C rejects the 'f' suffix"); - if (c == '\'' || c == EOF) - break; + fflag = 1; + break; - ++chars_seen; - if (c == '\\') - { - int ignore = 0; - c = readescape (&ignore); - if (ignore) - goto tryagain; - if (width < HOST_BITS_PER_INT - && (unsigned) c >= ((unsigned)1 << width)) - pedwarn ("escape sequence out of range for character"); -#ifdef MAP_CHARACTER - if (ISPRINT (c)) - c = MAP_CHARACTER (c); -#endif - } - else if (c == '\n') - { - if (pedantic) - pedwarn ("ISO C forbids newline in character constant"); - lineno++; - } - else - { -#ifdef MULTIBYTE_CHARS - wchar_t wc; - int i; - int char_len = -1; - for (i = 1; i <= longest_char; ++i) - { - if (i > maxtoken - 4) - extend_token_buffer (token_buffer); + case 'l': case 'L': + if (lflag) + ERROR ("more than one 'l' suffix on floating constant"); + else if (warn_traditional && !in_system_header) + warning ("traditional C rejects the 'l' suffix"); - token_buffer[i] = c; - char_len = local_mbtowc (& wc, - token_buffer + 1, - i); - if (char_len != -1) - break; - c = token_getch (); - } - if (char_len > 1) - { - /* mbtowc sometimes needs an extra char before accepting */ - if (char_len < i) - token_put_back (c); - if (! wide_flag) - { - /* Merge character into result; ignore excess chars. */ - for (i = 1; i <= char_len; ++i) - { - if (i > max_chars) - break; - if (width < HOST_BITS_PER_INT) - result = (result << width) - | (token_buffer[i] - & ((1 << width) - 1)); - else - result = token_buffer[i]; - } - num_chars += char_len; - goto tryagain; - } - c = wc; - } - else - { - if (char_len == -1) - { - warning ("Ignoring invalid multibyte character"); - /* Replace all but the first byte. */ - for (--i; i > 1; --i) - token_put_back (token_buffer[i]); - wc = token_buffer[1]; - } -#ifdef MAP_CHARACTER - c = MAP_CHARACTER (wc); -#else - c = wc; -#endif - } -#else /* ! MULTIBYTE_CHARS */ -#ifdef MAP_CHARACTER - c = MAP_CHARACTER (c); -#endif -#endif /* ! MULTIBYTE_CHARS */ - } + lflag = 1; + break; - if (wide_flag) - { - if (chars_seen == 1) /* only keep the first one */ - result = c; - goto tryagain; - } + case 'i': case 'I': + case 'j': case 'J': + if (imag) + ERROR ("more than one 'i' or 'j' suffix on floating constant"); + else if (pedantic) + pedwarn ("ISO C forbids imaginary numeric constants"); + imag = 1; + break; - /* Merge character into result; ignore excess chars. */ - num_chars += (width / TYPE_PRECISION (char_type_node)); - if (num_chars < max_chars + 1) - { - if (width < HOST_BITS_PER_INT) - result = (result << width) | (c & ((1 << width) - 1)); - else - result = c; - } + default: + ERROR ("invalid suffix on floating constant"); } - if (c != '\'') - error ("malformed character constant"); - else if (chars_seen == 0) - error ("empty character constant"); - else if (num_chars > max_chars) - { - num_chars = max_chars; - error ("character constant too long"); - } - else if (chars_seen != 1 && ! flag_traditional && warn_multichar) - warning ("multi-character character constant"); + /* Setup input for parse_float() */ + args.str = copy; + args.fflag = fflag; + args.lflag = lflag; + args.base = base; - /* If char type is signed, sign-extend the constant. */ - if (! wide_flag) - { - int num_bits = num_chars * width; - if (num_bits == 0) - /* We already got an error; avoid invalid shift. */ - yylval.ttype = build_int_2 (0, 0); - else if (TREE_UNSIGNED (char_type_node) - || ((result >> (num_bits - 1)) & 1) == 0) - yylval.ttype - = build_int_2 (result & (~(unsigned HOST_WIDE_INT) 0 - >> (HOST_BITS_PER_WIDE_INT - num_bits)), - 0); - else - yylval.ttype - = build_int_2 (result | ~(~(unsigned HOST_WIDE_INT) 0 - >> (HOST_BITS_PER_WIDE_INT - num_bits)), - -1); - TREE_TYPE (yylval.ttype) = integer_type_node; - } - else - { - yylval.ttype = build_int_2 (result, 0); - TREE_TYPE (yylval.ttype) = wchar_type_node; - } - - value = CONSTANT; - break; - } + /* Convert string to a double, checking for overflow. */ + if (do_float_handler (parse_float, (PTR) &args)) + { + /* Receive output from parse_float() */ + real = args.value; + } + else + /* We got an exception from parse_float() */ + ERROR ("floating constant out of range"); - case '"': - string_constant: - { - unsigned width = wide_flag ? WCHAR_TYPE_SIZE - : TYPE_PRECISION (char_type_node); -#ifdef MULTIBYTE_CHARS - int longest_char = local_mb_cur_max (); - (void) local_mbtowc (NULL_PTR, NULL_PTR, 0); + /* Receive output from parse_float() */ + conversion_errno = args.conversion_errno; + type = args.type; + +#ifdef ERANGE + /* ERANGE is also reported for underflow, + so test the value to distinguish overflow from that. */ + if (conversion_errno == ERANGE && !flag_traditional && pedantic + && (REAL_VALUES_LESS (dconst1, real) + || REAL_VALUES_LESS (real, dconstm1))) + warning ("floating point number exceeds range of 'double'"); #endif - c = token_getch (); - p = token_buffer + 1; - while (c != '"' && c != EOF) - { - /* ignore_escape_flag is set for reading the filename in #line. */ - if (!ignore_escape_flag && c == '\\') - { - int ignore = 0; - c = readescape (&ignore); - if (ignore) - goto skipnewline; - if (width < HOST_BITS_PER_INT - && (unsigned) c >= ((unsigned)1 << width)) - pedwarn ("escape sequence out of range for character"); - } - else if (c == '\n') - { - if (pedantic) - pedwarn ("ISO C forbids newline in string constant"); - lineno++; - } - else - { -#ifdef MULTIBYTE_CHARS - wchar_t wc; - int i; - int char_len = -1; - for (i = 0; i < longest_char; ++i) - { - if (p + i >= token_buffer + maxtoken) - p = extend_token_buffer (p); - p[i] = c; + /* Create a node with determined type and value. */ + if (imag) + value = build_complex (NULL_TREE, convert (type, integer_zero_node), + build_real (type, real)); + else + value = build_real (type, real); + } + else + { + tree trad_type, ansi_type, type; + HOST_WIDE_INT high, low; + int spec_unsigned = 0; + int spec_long = 0; + int spec_long_long = 0; + int spec_imag = 0; + int suffix_lu = 0; + int warn = 0, i; + + trad_type = ansi_type = type = NULL_TREE; + while (p < str + len) + { + c = *p++; + switch (c) + { + case 'u': case 'U': + if (spec_unsigned) + error ("two 'u' suffixes on integer constant"); + else if (warn_traditional && !in_system_header) + warning ("traditional C rejects the 'u' suffix"); + + spec_unsigned = 1; + if (spec_long) + suffix_lu = 1; + break; - char_len = local_mbtowc (& wc, p, i + 1); - if (char_len != -1) - break; - c = token_getch (); - } - if (char_len == -1) - { - warning ("Ignoring invalid multibyte character"); - /* Replace all except the first byte. */ - token_put_back (c); - for (--i; i > 0; --i) - token_put_back (p[i]); - char_len = 1; - } - /* mbtowc sometimes needs an extra char before accepting */ - if (char_len <= i) - token_put_back (c); - if (! wide_flag) - { - p += (i + 1); - c = token_getch (); - continue; - } - c = wc; -#endif /* MULTIBYTE_CHARS */ - } + case 'l': case 'L': + if (spec_long) + { + if (spec_long_long) + error ("three 'l' suffixes on integer constant"); + else if (suffix_lu) + error ("'lul' is not a valid integer suffix"); + else if (c != spec_long) + error ("'Ll' and 'lL' are not valid integer suffixes"); + else if (pedantic && ! flag_isoc99 + && ! in_system_header && warn_long_long) + pedwarn ("ISO C89 forbids long long integer constants"); + spec_long_long = 1; + } + spec_long = c; + break; - /* Add this single character into the buffer either as a wchar_t - or as a single byte. */ - if (wide_flag) - { - unsigned width = TYPE_PRECISION (char_type_node); - unsigned bytemask = (1 << width) - 1; - int byte; + case 'i': case 'I': case 'j': case 'J': + if (spec_imag) + error ("more than one 'i' or 'j' suffix on integer constant"); + else if (pedantic) + pedwarn ("ISO C forbids imaginary numeric constants"); + spec_imag = 1; + break; - if (p + WCHAR_BYTES > token_buffer + maxtoken) - p = extend_token_buffer (p); + default: + ERROR ("invalid suffix on integer constant"); + } + } - for (byte = 0; byte < WCHAR_BYTES; ++byte) - { - int value; - if (byte >= (int) sizeof (c)) - value = 0; - else - value = (c >> (byte * width)) & bytemask; - if (BYTES_BIG_ENDIAN) - p[WCHAR_BYTES - byte - 1] = value; - else - p[byte] = value; - } - p += WCHAR_BYTES; - } - else - { - if (p >= token_buffer + maxtoken) - p = extend_token_buffer (p); - *p++ = c; - } + /* If the literal overflowed, pedwarn about it now. */ + if (overflow) + { + warn = 1; + pedwarn ("integer constant is too large for this configuration of the compiler - truncated to %d bits", HOST_BITS_PER_WIDE_INT * 2); + } - skipnewline: - c = token_getch (); - } + /* This is simplified by the fact that our constant + is always positive. */ - /* Terminate the string value, either with a single byte zero - or with a wide zero. */ - if (wide_flag) - { - if (p + WCHAR_BYTES > token_buffer + maxtoken) - p = extend_token_buffer (p); - bzero (p, WCHAR_BYTES); - p += WCHAR_BYTES; - } - else - { - if (p >= token_buffer + maxtoken) - p = extend_token_buffer (p); - *p++ = 0; - } + high = low = 0; - if (c == EOF) - error ("Unterminated string constant"); + for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR; i++) + { + high |= ((HOST_WIDE_INT) parts[i + (HOST_BITS_PER_WIDE_INT + / HOST_BITS_PER_CHAR)] + << (i * HOST_BITS_PER_CHAR)); + low |= (HOST_WIDE_INT) parts[i] << (i * HOST_BITS_PER_CHAR); + } - /* We have read the entire constant. - Construct a STRING_CST for the result. */ + value = build_int_2 (low, high); + TREE_TYPE (value) = long_long_unsigned_type_node; - yylval.ttype = build_string (p - (token_buffer + 1), token_buffer + 1); - if (wide_flag) - { - TREE_TYPE (yylval.ttype) = wchar_array_type_node; - value = STRING; - } - else if (objc_flag) - { - TREE_TYPE (yylval.ttype) = char_array_type_node; - value = OBJC_STRING; - } - else - { - TREE_TYPE (yylval.ttype) = char_array_type_node; - value = STRING; - } + /* If warn_traditional, calculate both the ISO type and the + traditional type, then see if they disagree. + Otherwise, calculate only the type for the dialect in use. */ + if (warn_traditional || flag_traditional) + { + /* Calculate the traditional type. */ + /* Traditionally, any constant is signed; but if unsigned is + specified explicitly, obey that. Use the smallest size + with the right number of bits, except for one special + case with decimal constants. */ + if (! spec_long && base != 10 + && int_fits_type_p (value, unsigned_type_node)) + trad_type = spec_unsigned ? unsigned_type_node : integer_type_node; + /* A decimal constant must be long if it does not fit in + type int. I think this is independent of whether the + constant is signed. */ + else if (! spec_long && base == 10 + && int_fits_type_p (value, integer_type_node)) + trad_type = spec_unsigned ? unsigned_type_node : integer_type_node; + else if (! spec_long_long) + trad_type = (spec_unsigned + ? long_unsigned_type_node + : long_integer_type_node); + else if (int_fits_type_p (value, + spec_unsigned + ? long_long_unsigned_type_node + : long_long_integer_type_node)) + trad_type = (spec_unsigned + ? long_long_unsigned_type_node + : long_long_integer_type_node); + else + trad_type = (spec_unsigned + ? widest_unsigned_literal_type_node + : widest_integer_literal_type_node); + } + if (warn_traditional || ! flag_traditional) + { + /* Calculate the ISO type. */ + if (! spec_long && ! spec_unsigned + && int_fits_type_p (value, integer_type_node)) + ansi_type = integer_type_node; + else if (! spec_long && (base != 10 || spec_unsigned) + && int_fits_type_p (value, unsigned_type_node)) + ansi_type = unsigned_type_node; + else if (! spec_unsigned && !spec_long_long + && int_fits_type_p (value, long_integer_type_node)) + ansi_type = long_integer_type_node; + else if (! spec_long_long + && int_fits_type_p (value, long_unsigned_type_node)) + ansi_type = long_unsigned_type_node; + else if (! spec_unsigned + && int_fits_type_p (value, long_long_integer_type_node)) + ansi_type = long_long_integer_type_node; + else if (int_fits_type_p (value, long_long_unsigned_type_node)) + ansi_type = long_long_unsigned_type_node; + else if (! spec_unsigned + && int_fits_type_p (value, widest_integer_literal_type_node)) + ansi_type = widest_integer_literal_type_node; + else + ansi_type = widest_unsigned_literal_type_node; + } - break; - } + type = flag_traditional ? trad_type : ansi_type; - case '+': - case '-': - case '&': - case '|': - case ':': - case '<': - case '>': - case '*': - case '/': - case '%': - case '^': - case '!': - case '=': - { - register int c1; + /* We assume that constants specified in a non-decimal + base are bit patterns, and that the programmer really + meant what they wrote. */ + if (warn_traditional && !in_system_header + && base == 10 && trad_type != ansi_type) + { + if (TYPE_PRECISION (trad_type) != TYPE_PRECISION (ansi_type)) + warning ("width of integer constant changes with -traditional"); + else if (TREE_UNSIGNED (trad_type) != TREE_UNSIGNED (ansi_type)) + warning ("integer constant is unsigned in ISO C, signed with -traditional"); + else + warning ("width of integer constant may change on other systems with -traditional"); + } - combine: + if (pedantic && !flag_traditional && !spec_long_long && !warn + && (TYPE_PRECISION (long_integer_type_node) < TYPE_PRECISION (type))) + { + warn = 1; + pedwarn ("integer constant larger than the maximum value of an unsigned long int"); + } - switch (c) - { - case '+': - yylval.code = PLUS_EXPR; break; - case '-': - yylval.code = MINUS_EXPR; break; - case '&': - yylval.code = BIT_AND_EXPR; break; - case '|': - yylval.code = BIT_IOR_EXPR; break; - case '*': - yylval.code = MULT_EXPR; break; - case '/': - yylval.code = TRUNC_DIV_EXPR; break; - case '%': - yylval.code = TRUNC_MOD_EXPR; break; - case '^': - yylval.code = BIT_XOR_EXPR; break; - case LSHIFT: - yylval.code = LSHIFT_EXPR; break; - case RSHIFT: - yylval.code = RSHIFT_EXPR; break; - case '<': - yylval.code = LT_EXPR; break; - case '>': - yylval.code = GT_EXPR; break; - } + if (base == 10 && ! spec_unsigned && TREE_UNSIGNED (type)) + warning ("decimal constant is so large that it is unsigned"); - token_buffer[1] = c1 = token_getch(); - token_buffer[2] = 0; + if (spec_imag) + { + if (TYPE_PRECISION (type) + <= TYPE_PRECISION (integer_type_node)) + value = build_complex (NULL_TREE, integer_zero_node, + convert (integer_type_node, value)); + else + ERROR ("complex integer constant is too wide for 'complex int'"); + } + else if (flag_traditional && !int_fits_type_p (value, type)) + /* The traditional constant 0x80000000 is signed + but doesn't fit in the range of int. + This will change it to -0x80000000, which does fit. */ + { + TREE_TYPE (value) = unsigned_type (type); + value = convert (type, value); + TREE_OVERFLOW (value) = TREE_CONSTANT_OVERFLOW (value) = 0; + } + else + TREE_TYPE (value) = type; - if (c1 == '=') - { - switch (c) - { - case '<': - value = ARITHCOMPARE; yylval.code = LE_EXPR; goto done; - case '>': - value = ARITHCOMPARE; yylval.code = GE_EXPR; goto done; - case '!': - value = EQCOMPARE; yylval.code = NE_EXPR; goto done; - case '=': - value = EQCOMPARE; yylval.code = EQ_EXPR; goto done; - } - value = ASSIGN; goto done; - } - else if (c == c1) - switch (c) - { - case '+': - value = PLUSPLUS; goto done; - case '-': - value = MINUSMINUS; goto done; - case '&': - value = ANDAND; goto done; - case '|': - value = OROR; goto done; - case '<': - c = LSHIFT; - goto combine; - case '>': - c = RSHIFT; - goto combine; - } - else - switch (c) - { - case '-': - if (c1 == '>') - { value = POINTSAT; goto done; } - break; + /* If it's still an integer (not a complex), and it doesn't + fit in the type we choose for it, then pedwarn. */ - /* digraphs */ - case ':': - if (c1 == '>' && flag_digraphs) - { value = ']'; goto done; } - break; - case '<': - if (flag_digraphs) - { - if (c1 == '%') - { value = '{'; indent_level++; goto done; } - if (c1 == ':') - { value = '['; goto done; } - } - break; - case '%': - if (c1 == '>' && flag_digraphs) - { value = '}'; indent_level--; goto done; } - break; - } + if (! warn + && TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE + && ! int_fits_type_p (value, TREE_TYPE (value))) + pedwarn ("integer constant is larger than the maximum value for its type"); + } - token_put_back (c1); - token_buffer[1] = 0; + if (p < str + len) + error ("missing white space after number '%.*s'", (int) (p - str), str); - if ((c == '<') || (c == '>')) - value = ARITHCOMPARE; - else value = c; - break; - } + return value; - case 0: - /* Don't make yyparse think this is eof. */ - value = 1; - break; + syntax_error: + return integer_zero_node; +} - case '{': - indent_level++; - value = c; - break; +static tree +lex_string (str, len, wide) + const char *str; + unsigned int len; + int wide; +{ + tree value; + char *buf = alloca ((len + 1) * (wide ? WCHAR_BYTES : 1)); + char *q = buf; + const char *p = str, *limit = str + len; + unsigned int c; + unsigned width = wide ? WCHAR_TYPE_SIZE + : TYPE_PRECISION (char_type_node); - case '}': - indent_level--; - value = c; - break; +#ifdef MULTIBYTE_CHARS + /* Reset multibyte conversion state. */ + (void) local_mbtowc (NULL_PTR, NULL_PTR, 0); +#endif - default: - value = c; + while (p < limit) + { +#ifdef MULTIBYTE_CHARS + wchar_t wc; + int char_len; + + char_len = local_mbtowc (&wc, p, limit - p); + if (char_len == -1) + { + warning ("Ignoring invalid multibyte character"); + char_len = 1; + c = *p++; + } + else + { + p += char_len; + c = wc; + } +#else + c = *p++; +#endif + + if (c == '\\' && !ignore_escape_flag) + { + p = readescape (p, limit, &c); + if (width < HOST_BITS_PER_INT + && (unsigned) c >= ((unsigned)1 << width)) + pedwarn ("escape sequence out of range for character"); + } + + /* Add this single character into the buffer either as a wchar_t + or as a single byte. */ + if (wide) + { + unsigned charwidth = TYPE_PRECISION (char_type_node); + unsigned bytemask = (1 << width) - 1; + int byte; + + for (byte = 0; byte < WCHAR_BYTES; ++byte) + { + int n; + if (byte >= (int) sizeof (c)) + n = 0; + else + n = (c >> (byte * charwidth)) & bytemask; + if (BYTES_BIG_ENDIAN) + q[WCHAR_BYTES - byte - 1] = n; + else + q[byte] = n; + } + q += WCHAR_BYTES; + } + else + { + *q++ = c; + } } -done: -/* yylloc.last_line = lineno; */ + /* Terminate the string value, either with a single byte zero + or with a wide zero. */ + if (wide) + { + memset (q, 0, WCHAR_BYTES); + q += WCHAR_BYTES; + } + else + { + *q++ = '\0'; + } + + value = build_string (q - buf, buf); + + if (wide) + TREE_TYPE (value) = wchar_array_type_node; + else + TREE_TYPE (value) = char_array_type_node; return value; } -/* Sets the value of the 'yydebug' variable to VALUE. - This is a function so we don't have to have YYDEBUG defined - in order to build the compiler. */ - -void -set_yydebug (value) - int value; +static tree +lex_charconst (str, len, wide) + const char *str; + unsigned int len; + int wide; { -#if YYDEBUG != 0 - yydebug = value; + const char *limit = str + len; + int result = 0; + int num_chars = 0; + int chars_seen = 0; + unsigned width = TYPE_PRECISION (char_type_node); + int max_chars; + unsigned int c; + tree value; + +#ifdef MULTIBYTE_CHARS + int longest_char = local_mb_cur_max (); + (void) local_mbtowc (NULL_PTR, NULL_PTR, 0); +#endif + + max_chars = TYPE_PRECISION (integer_type_node) / width; + if (wide) + width = WCHAR_TYPE_SIZE; + + while (str < limit) + { +#ifdef MULTIBYTE_CHARS + wchar_t wc; + int char_len; + + char_len = local_mbtowc (&wc, str, limit - str); + if (char_len == -1) + { + warning ("Ignoring invalid multibyte character"); + char_len = 1; + c = *str++; + } + else + { + p += char_len; + c = wc; + } #else - warning ("YYDEBUG not defined."); + c = *str++; +#endif + + ++chars_seen; + if (c == '\\') + { + str = readescape (str, limit, &c); + if (width < HOST_BITS_PER_INT + && (unsigned) c >= ((unsigned)1 << width)) + pedwarn ("escape sequence out of range for character"); + } +#ifdef MAP_CHARACTER + if (ISPRINT (c)) + c = MAP_CHARACTER (c); #endif + + /* Merge character into result; ignore excess chars. */ + num_chars += (width / TYPE_PRECISION (char_type_node)); + if (num_chars < max_chars + 1) + { + if (width < HOST_BITS_PER_INT) + result = (result << width) | (c & ((1 << width) - 1)); + else + result = c; + } + } + + if (chars_seen == 0) + error ("empty character constant"); + else if (num_chars > max_chars) + { + num_chars = max_chars; + error ("character constant too long"); + } + else if (chars_seen != 1 && ! flag_traditional && warn_multichar) + warning ("multi-character character constant"); + + /* If char type is signed, sign-extend the constant. */ + if (! wide) + { + int num_bits = num_chars * width; + if (num_bits == 0) + /* We already got an error; avoid invalid shift. */ + value = build_int_2 (0, 0); + else if (TREE_UNSIGNED (char_type_node) + || ((result >> (num_bits - 1)) & 1) == 0) + value = build_int_2 (result & (~(unsigned HOST_WIDE_INT) 0 + >> (HOST_BITS_PER_WIDE_INT - num_bits)), + 0); + else + value = build_int_2 (result | ~(~(unsigned HOST_WIDE_INT) 0 + >> (HOST_BITS_PER_WIDE_INT - num_bits)), + -1); + /* In C, a character constant has type 'int'; in C++, 'char'. */ + if (chars_seen <= 1 && c_language == clk_cplusplus) + TREE_TYPE (value) = char_type_node; + else + TREE_TYPE (value) = integer_type_node; + } + else + { + value = build_int_2 (result, 0); + TREE_TYPE (value) = wchar_type_node; + } + + return value; } diff --git a/gcc/c-lex.h b/gcc/c-lex.h index 224aa03..5247c38 100644 --- a/gcc/c-lex.h +++ b/gcc/c-lex.h @@ -18,16 +18,20 @@ along with GNU CC; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -extern char *token_buffer; /* Pointer to token buffer. */ +#ifndef _C_LEX_H +#define _C_LEX_H extern tree make_pointer_declarator PARAMS ((tree, tree)); -extern void reinit_parse_for_function PARAMS ((void)); extern void position_after_white_space PARAMS ((void)); extern int check_newline PARAMS ((void)); -extern int yylex PARAMS ((void)); -extern void yyerror PARAMS ((const char *)); +extern int c_lex PARAMS ((tree *)); +extern const char *init_c_lex PARAMS ((const char *)); extern void forget_protocol_qualifiers PARAMS ((void)); extern void remember_protocol_qualifiers PARAMS ((void)); extern tree is_class_name PARAMS ((tree)); + +extern int indent_level; + +#endif diff --git a/gcc/c-parse.gperf b/gcc/c-parse.gperf deleted file mode 100644 index 1f36392..0000000 --- a/gcc/c-parse.gperf +++ /dev/null @@ -1,105 +0,0 @@ -%{ -/* Command-line: gperf -L C -F ', 0, 0' -p -j1 -i 1 -g -o -t -N is_reserved_word -k1,3,$ c-parse.gperf */ -%} -struct resword { const char *name; short token; enum rid rid; }; -#ifdef __GNUC__ -__inline -#endif -static unsigned int hash PARAMS ((const char *, unsigned int)); -#ifdef __GNUC__ -__inline -#endif -struct resword *is_reserved_word PARAMS ((const char *, unsigned int)); -%% -@class, CLASS, NORID -@compatibility_alias, ALIAS, NORID -@defs, DEFS, NORID -@encode, ENCODE, NORID -@end, END, NORID -@implementation, IMPLEMENTATION, NORID -@interface, INTERFACE, NORID -@private, PRIVATE, NORID -@protected, PROTECTED, NORID -@protocol, PROTOCOL, NORID -@public, PUBLIC, NORID -@selector, SELECTOR, NORID -__alignof, ALIGNOF, NORID -__alignof__, ALIGNOF, NORID -__asm, ASM_KEYWORD, NORID -__asm__, ASM_KEYWORD, NORID -__attribute, ATTRIBUTE, NORID -__attribute__, ATTRIBUTE, NORID -__bounded, TYPE_QUAL, RID_BOUNDED -__bounded__, TYPE_QUAL, RID_BOUNDED -__builtin_va_arg, VA_ARG, NORID -__complex, TYPESPEC, RID_COMPLEX -__complex__, TYPESPEC, RID_COMPLEX -__const, TYPE_QUAL, RID_CONST -__const__, TYPE_QUAL, RID_CONST -__extension__, EXTENSION, NORID -__imag, IMAGPART, NORID -__imag__, IMAGPART, NORID -__inline, SCSPEC, RID_INLINE -__inline__, SCSPEC, RID_INLINE -__label__, LABEL, NORID -__ptrbase, PTR_BASE, NORID -__ptrbase__, PTR_BASE, NORID -__ptrextent, PTR_EXTENT, NORID -__ptrextent__, PTR_EXTENT, NORID -__ptrvalue, PTR_VALUE, NORID -__ptrvalue__, PTR_VALUE, NORID -__real, REALPART, NORID -__real__, REALPART, NORID -__restrict, TYPE_QUAL, RID_RESTRICT -__restrict__, TYPE_QUAL, RID_RESTRICT -__signed, TYPESPEC, RID_SIGNED -__signed__, TYPESPEC, RID_SIGNED -__typeof, TYPEOF, NORID -__typeof__, TYPEOF, NORID -__unbounded, TYPE_QUAL, RID_UNBOUNDED -__unbounded__, TYPE_QUAL, RID_UNBOUNDED -__volatile, TYPE_QUAL, RID_VOLATILE -__volatile__, TYPE_QUAL, RID_VOLATILE -asm, ASM_KEYWORD, NORID -auto, SCSPEC, RID_AUTO -break, BREAK, NORID -bycopy, TYPE_QUAL, RID_BYCOPY -byref, TYPE_QUAL, RID_BYREF -case, CASE, NORID -char, TYPESPEC, RID_CHAR -const, TYPE_QUAL, RID_CONST -continue, CONTINUE, NORID -default, DEFAULT, NORID -do, DO, NORID -double, TYPESPEC, RID_DOUBLE -else, ELSE, NORID -enum, ENUM, NORID -extern, SCSPEC, RID_EXTERN -float, TYPESPEC, RID_FLOAT -for, FOR, NORID -goto, GOTO, NORID -id, OBJECTNAME, RID_ID -if, IF, NORID -in, TYPE_QUAL, RID_IN -inout, TYPE_QUAL, RID_INOUT -inline, SCSPEC, RID_INLINE -int, TYPESPEC, RID_INT -long, TYPESPEC, RID_LONG -oneway, TYPE_QUAL, RID_ONEWAY -out, TYPE_QUAL, RID_OUT -register, SCSPEC, RID_REGISTER -restrict, TYPE_QUAL, RID_RESTRICT -return, RETURN, NORID -short, TYPESPEC, RID_SHORT -signed, TYPESPEC, RID_SIGNED -sizeof, SIZEOF, NORID -static, SCSPEC, RID_STATIC -struct, STRUCT, NORID -switch, SWITCH, NORID -typedef, SCSPEC, RID_TYPEDEF -typeof, TYPEOF, NORID -union, UNION, NORID -unsigned, TYPESPEC, RID_UNSIGNED -void, TYPESPEC, RID_VOID -volatile, TYPE_QUAL, RID_VOLATILE -while, WHILE, NORID diff --git a/gcc/c-parse.in b/gcc/c-parse.in index 588faeb..9d2001b 100644 --- a/gcc/c-parse.in +++ b/gcc/c-parse.in @@ -43,6 +43,7 @@ end ifc #include "input.h" #include "c-lex.h" #include "c-tree.h" +#include "c-pragma.h" #include "flags.h" #include "output.h" #include "toplev.h" @@ -117,9 +118,6 @@ end ifc %token REALPART IMAGPART VA_ARG %token PTR_VALUE PTR_BASE PTR_EXTENT -/* Used in c-lex.c for parsing pragmas. */ -%token END_OF_LINE - /* Add precedence rules to solve dangling else s/r conflict */ %nonassoc IF %nonassoc ELSE @@ -155,6 +153,8 @@ end ifc %type unop +%type ENUM STRUCT UNION IF ELSE WHILE DO FOR SWITCH CASE DEFAULT +%type BREAK CONTINUE RETURN GOTO ASM_KEYWORD SIZEOF TYPEOF ALIGNOF %type identifier IDENTIFIER TYPENAME CONSTANT expr nonnull_exprlist exprlist %type expr_no_commas cast_expr unary_expr primary string STRING @@ -254,7 +254,12 @@ end ifobjc /* Tell yyparse how to print a token's value, if yydebug is set. */ #define YYPRINT(FILE,YYCHAR,YYLVAL) yyprint(FILE,YYCHAR,YYLVAL) -extern void yyprint PARAMS ((FILE *, int, YYSTYPE)); + +static void yyprint PARAMS ((FILE *, int, YYSTYPE)); +static void yyerror PARAMS ((const char *)); +static inline int _yylex PARAMS ((void)); +static int yylex PARAMS ((void)); +static void init_reswords PARAMS ((void)); /* Add GC roots for variables local to this file. */ void @@ -351,7 +356,7 @@ fndef: { if (! start_function (current_declspecs, $3, prefix_attributes, NULL_TREE)) YYERROR1; - reinit_parse_for_function (); } + } old_style_parm_decls { store_parm_decls (); } compstmt_or_error @@ -367,7 +372,7 @@ fndef: { if (! start_function (current_declspecs, $3, prefix_attributes, NULL_TREE)) YYERROR1; - reinit_parse_for_function (); } + } old_style_parm_decls { store_parm_decls (); } compstmt_or_error @@ -383,7 +388,7 @@ fndef: { if (! start_function (NULL_TREE, $2, prefix_attributes, NULL_TREE)) YYERROR1; - reinit_parse_for_function (); } + } old_style_parm_decls { store_parm_decls (); } compstmt_or_error @@ -1178,7 +1183,7 @@ nested_function: pop_function_context (); YYERROR1; } - reinit_parse_for_function (); } + } old_style_parm_decls { store_parm_decls (); } /* This used to use compstmt_or_error. @@ -1204,7 +1209,7 @@ notype_nested_function: pop_function_context (); YYERROR1; } - reinit_parse_for_function (); } + } old_style_parm_decls { store_parm_decls (); } /* This used to use compstmt_or_error. @@ -1696,8 +1701,7 @@ if_prefix: compstmt_count); $$ = stmt_count; if_stmt_file = $-1; - if_stmt_line = $0; - position_after_white_space (); } + if_stmt_line = $0; } ; /* This is a subroutine of stmt. @@ -1710,18 +1714,24 @@ do_stmt_start: emit_line_note ($-1, $0); /* See comment in `while' alternative, above. */ emit_nop (); - expand_start_loop_continue_elsewhere (1); - position_after_white_space (); } + expand_start_loop_continue_elsewhere (1); } lineno_labeled_stmt WHILE { expand_loop_continue_here (); } ; +/* The forced readahead in here is because we might be at the end of a + line, and the line and file won't be bumped until yylex absorbs the + first token on the next line. */ save_filename: - { $$ = input_filename; } + { if (yychar == YYEMPTY) + yychar = YYLEX; + $$ = input_filename; } ; save_lineno: - { $$ = lineno; } + { if (yychar == YYEMPTY) + yychar = YYLEX; + $$ = lineno; } ; lineno_labeled_stmt: @@ -1768,8 +1778,7 @@ stmt: expand_expr_stmt ($1); } | simple_if ELSE { c_expand_start_else (); - $1 = stmt_count; - position_after_white_space (); } + $1 = stmt_count; } lineno_labeled_stmt { c_expand_end_cond (); if (extra_warnings && stmt_count == $1) @@ -1805,8 +1814,7 @@ stmt: expand_start_loop (1); emit_line_note (input_filename, lineno); expand_exit_loop_if_false (NULL_PTR, - truthvalue_conversion ($4)); - position_after_white_space (); } + truthvalue_conversion ($4)); } lineno_labeled_stmt { expand_end_loop (); } | do_stmt_start @@ -1845,8 +1853,7 @@ stmt: expand_exit_loop_if_false (NULL_PTR, truthvalue_conversion ($6)); $7 = lineno; - $8 = input_filename; - position_after_white_space (); } + $8 = input_filename; } lineno_labeled_stmt { /* Emit the increment expression, with a line number. */ emit_line_note ($8, $7); @@ -1857,8 +1864,7 @@ stmt: | SWITCH '(' expr ')' { stmt_count++; emit_line_note ($-1, $0); - c_expand_start_case ($3); - position_after_white_space (); } + c_expand_start_case ($3); } lineno_labeled_stmt { expand_end_case ($3); } | BREAK ';' @@ -1937,22 +1943,19 @@ label: CASE expr_no_commas ':' { tree case_label_tree = build_case_label ($2, NULL_TREE); stmt_count++; genrtl_case_label(CASE_LOW(case_label_tree), CASE_HIGH(case_label_tree)); - position_after_white_space (); } | CASE expr_no_commas ELLIPSIS expr_no_commas ':' { tree case_label_tree = build_case_label ($2, $4); stmt_count++; genrtl_case_label(CASE_LOW(case_label_tree), CASE_HIGH(case_label_tree)); - position_after_white_space (); } | DEFAULT ':' { tree case_label_tree = build_case_label (NULL_TREE, NULL_TREE); stmt_count++; genrtl_case_label(CASE_LOW(case_label_tree), CASE_HIGH(case_label_tree)); - position_after_white_space (); } - | identifier ':' save_filename save_lineno maybe_attribute - { tree label = define_label ($3, $4, $1); + | identifier save_filename save_lineno ':' maybe_attribute + { tree label = define_label ($2, $3, $1); stmt_count++; emit_nop (); if (label) @@ -1960,7 +1963,7 @@ label: CASE expr_no_commas ':' expand_label (label); decl_attributes (label, $5, NULL_TREE); } - position_after_white_space (); } + } ; /* Either a type-qualifier or nothing. First thing in an `asm' statement. */ @@ -2658,25 +2661,9 @@ selector: ; reservedwords: - ENUM { $$ = get_identifier (token_buffer); } - | STRUCT { $$ = get_identifier (token_buffer); } - | UNION { $$ = get_identifier (token_buffer); } - | IF { $$ = get_identifier (token_buffer); } - | ELSE { $$ = get_identifier (token_buffer); } - | WHILE { $$ = get_identifier (token_buffer); } - | DO { $$ = get_identifier (token_buffer); } - | FOR { $$ = get_identifier (token_buffer); } - | SWITCH { $$ = get_identifier (token_buffer); } - | CASE { $$ = get_identifier (token_buffer); } - | DEFAULT { $$ = get_identifier (token_buffer); } - | BREAK { $$ = get_identifier (token_buffer); } - | CONTINUE { $$ = get_identifier (token_buffer); } - | RETURN { $$ = get_identifier (token_buffer); } - | GOTO { $$ = get_identifier (token_buffer); } - | ASM_KEYWORD { $$ = get_identifier (token_buffer); } - | SIZEOF { $$ = get_identifier (token_buffer); } - | TYPEOF { $$ = get_identifier (token_buffer); } - | ALIGNOF { $$ = get_identifier (token_buffer); } + ENUM | STRUCT | UNION | IF | ELSE | WHILE | DO | FOR + | SWITCH | CASE | DEFAULT | BREAK | CONTINUE | RETURN + | GOTO | ASM_KEYWORD | SIZEOF | TYPEOF | ALIGNOF | TYPESPEC | TYPE_QUAL ; @@ -2807,3 +2794,606 @@ objcencodeexpr: end ifobjc %% + +/* yylex() is a thin wrapper around c_lex(), all it does is translate + cpplib.h's token codes into yacc's token codes. */ +#include "cpplib.h" +#include "intl.h" +#include "timevar.h" + +static enum cpp_ttype last_token; +#if USE_CPPLIB +extern cpp_reader parse_in; +#endif + +/* The reserved keyword table. */ +struct resword +{ + const char *word; + ENUM_BITFIELD(rid) rid : 16; + unsigned int disable : 16; +}; + +/* Disable mask. Keywords are disabled if (reswords[i].disable & mask) is + _true_. */ +#define D_TRAD 0x01 /* not in traditional C */ +#define D_C89 0x02 /* not in C89 */ +#define D_EXT 0x04 /* GCC extension */ +#define D_EXT89 0x08 /* GCC extension incorporated in C99 */ +#define D_OBJC 0x10 /* Objective C only */ +#define D_YES 0x20 /* always starts disabled */ + +static const struct resword reswords[] = +{ + { "__alignof", RID_ALIGNOF, 0 }, + { "__alignof__", RID_ALIGNOF, 0 }, + { "__asm", RID_ASM, 0 }, + { "__asm__", RID_ASM, 0 }, + { "__attribute", RID_ATTRIBUTE, 0 }, + { "__attribute__", RID_ATTRIBUTE, 0 }, + { "__bounded", RID_BOUNDED, 0 }, + { "__bounded__", RID_BOUNDED, 0 }, + { "__builtin_va_arg", RID_VA_ARG, 0 }, + { "__complex", RID_COMPLEX, 0 }, + { "__complex__", RID_COMPLEX, 0 }, + { "__const", RID_CONST, 0 }, + { "__const__", RID_CONST, 0 }, + { "__extension__", RID_EXTENSION, 0 }, + { "__imag", RID_IMAGPART, 0 }, + { "__imag__", RID_IMAGPART, 0 }, + { "__inline", RID_INLINE, 0 }, + { "__inline__", RID_INLINE, 0 }, + { "__label__", RID_LABEL, 0 }, + { "__ptrbase", RID_PTRBASE, 0 }, + { "__ptrbase__", RID_PTRBASE, 0 }, + { "__ptrextent", RID_PTREXTENT, 0 }, + { "__ptrextent__", RID_PTREXTENT, 0 }, + { "__ptrvalue", RID_PTRVALUE, 0 }, + { "__ptrvalue__", RID_PTRVALUE, 0 }, + { "__real", RID_REALPART, 0 }, + { "__real__", RID_REALPART, 0 }, + { "__restrict", RID_RESTRICT, 0 }, + { "__restrict__", RID_RESTRICT, 0 }, + { "__signed", RID_SIGNED, 0 }, + { "__signed__", RID_SIGNED, 0 }, + { "__typeof", RID_TYPEOF, 0 }, + { "__typeof__", RID_TYPEOF, 0 }, + { "__unbounded", RID_UNBOUNDED, 0 }, + { "__unbounded__", RID_UNBOUNDED, 0 }, + { "__volatile", RID_VOLATILE, 0 }, + { "__volatile__", RID_VOLATILE, 0 }, + { "asm", RID_ASM, D_EXT }, + { "auto", RID_AUTO, 0 }, + { "break", RID_BREAK, 0 }, + { "case", RID_CASE, 0 }, + { "char", RID_CHAR, 0 }, + { "const", RID_CONST, D_TRAD }, + { "continue", RID_CONTINUE, 0 }, + { "default", RID_DEFAULT, 0 }, + { "do", RID_DO, 0 }, + { "double", RID_DOUBLE, 0 }, + { "else", RID_ELSE, 0 }, + { "enum", RID_ENUM, 0 }, + { "extern", RID_EXTERN, 0 }, + { "float", RID_FLOAT, 0 }, + { "for", RID_FOR, 0 }, + { "goto", RID_GOTO, 0 }, + { "if", RID_IF, 0 }, + { "inline", RID_INLINE, D_TRAD|D_EXT89 }, + { "int", RID_INT, 0 }, + { "long", RID_LONG, 0 }, + { "register", RID_REGISTER, 0 }, + { "restrict", RID_RESTRICT, D_TRAD|D_C89 }, + { "return", RID_RETURN, 0 }, + { "short", RID_SHORT, 0 }, + { "signed", RID_SIGNED, D_TRAD }, + { "sizeof", RID_SIZEOF, 0 }, + { "static", RID_STATIC, 0 }, + { "struct", RID_STRUCT, 0 }, + { "switch", RID_SWITCH, 0 }, + { "typedef", RID_TYPEDEF, 0 }, + { "typeof", RID_TYPEOF, D_TRAD|D_EXT }, + { "union", RID_UNION, 0 }, + { "unsigned", RID_UNSIGNED, 0 }, + { "void", RID_VOID, 0 }, + { "volatile", RID_VOLATILE, D_TRAD }, + { "while", RID_WHILE, 0 }, +ifobjc + { "@class", RID_AT_CLASS, D_OBJC }, + { "@compatibility_alias", RID_AT_ALIAS, D_OBJC }, + { "@defs", RID_AT_DEFS, D_OBJC }, + { "@encode", RID_AT_ENCODE, D_OBJC }, + { "@end", RID_AT_END, D_OBJC }, + { "@implementation", RID_AT_IMPLEMENTATION, D_OBJC }, + { "@interface", RID_AT_INTERFACE, D_OBJC }, + { "@private", RID_AT_PRIVATE, D_OBJC }, + { "@protected", RID_AT_PROTECTED, D_OBJC }, + { "@protocol", RID_AT_PROTOCOL, D_OBJC }, + { "@public", RID_AT_PUBLIC, D_OBJC }, + { "@selector", RID_AT_SELECTOR, D_OBJC }, + { "id", RID_ID, D_OBJC }, + { "bycopy", RID_BYCOPY, D_OBJC|D_YES }, + { "byref", RID_BYREF, D_OBJC|D_YES }, + { "in", RID_IN, D_OBJC|D_YES }, + { "inout", RID_INOUT, D_OBJC|D_YES }, + { "oneway", RID_ONEWAY, D_OBJC|D_YES }, + { "out", RID_OUT, D_OBJC|D_YES }, +end ifobjc +}; +#define N_reswords (sizeof reswords / sizeof (struct resword)) + +/* Table mapping from RID_* constants to yacc token numbers. + Unfortunately we have to have entries for all the keywords in all + three languages. */ +static const short rid_to_yy[RID_MAX] = +{ + /* RID_STATIC */ SCSPEC, + /* RID_UNSIGNED */ TYPESPEC, + /* RID_LONG */ TYPESPEC, + /* RID_CONST */ TYPE_QUAL, + /* RID_EXTERN */ SCSPEC, + /* RID_REGISTER */ SCSPEC, + /* RID_TYPEDEF */ SCSPEC, + /* RID_SHORT */ TYPESPEC, + /* RID_INLINE */ SCSPEC, + /* RID_VOLATILE */ TYPE_QUAL, + /* RID_SIGNED */ TYPESPEC, + /* RID_AUTO */ SCSPEC, + /* RID_RESTRICT */ TYPE_QUAL, + + /* C extensions */ + /* RID_BOUNDED */ TYPE_QUAL, + /* RID_UNBOUNDED */ TYPE_QUAL, + /* RID_COMPLEX */ TYPESPEC, + + /* C++ */ + /* RID_FRIEND */ 0, + /* RID_VIRTUAL */ 0, + /* RID_EXPLICIT */ 0, + /* RID_EXPORT */ 0, + /* RID_MUTABLE */ 0, + + /* ObjC */ + /* RID_IN */ TYPE_QUAL, + /* RID_OUT */ TYPE_QUAL, + /* RID_INOUT */ TYPE_QUAL, + /* RID_BYCOPY */ TYPE_QUAL, + /* RID_BYREF */ TYPE_QUAL, + /* RID_ONEWAY */ TYPE_QUAL, + + /* C */ + /* RID_INT */ TYPESPEC, + /* RID_CHAR */ TYPESPEC, + /* RID_FLOAT */ TYPESPEC, + /* RID_DOUBLE */ TYPESPEC, + /* RID_VOID */ TYPESPEC, + /* RID_ENUM */ ENUM, + /* RID_STRUCT */ STRUCT, + /* RID_UNION */ UNION, + /* RID_IF */ IF, + /* RID_ELSE */ ELSE, + /* RID_WHILE */ WHILE, + /* RID_DO */ DO, + /* RID_FOR */ FOR, + /* RID_SWITCH */ SWITCH, + /* RID_CASE */ CASE, + /* RID_DEFAULT */ DEFAULT, + /* RID_BREAK */ BREAK, + /* RID_CONTINUE */ CONTINUE, + /* RID_RETURN */ RETURN, + /* RID_GOTO */ GOTO, + /* RID_SIZEOF */ SIZEOF, + + /* C extensions */ + /* RID_ASM */ ASM_KEYWORD, + /* RID_TYPEOF */ TYPEOF, + /* RID_ALIGNOF */ ALIGNOF, + /* RID_ATTRIBUTE */ ATTRIBUTE, + /* RID_VA_ARG */ VA_ARG, + /* RID_EXTENSION */ EXTENSION, + /* RID_IMAGPART */ IMAGPART, + /* RID_REALPART */ REALPART, + /* RID_LABEL */ LABEL, + /* RID_PTRBASE */ PTR_BASE, + /* RID_PTREXTENT */ PTR_EXTENT, + /* RID_PTRVALUE */ PTR_VALUE, + + /* C++ */ + /* RID_BOOL */ 0, + /* RID_WCHAR */ 0, + /* RID_CLASS */ 0, + /* RID_PUBLIC */ 0, + /* RID_PRIVATE */ 0, + /* RID_PROTECTED */ 0, + /* RID_TEMPLATE */ 0, + /* RID_NULL */ 0, + /* RID_CATCH */ 0, + /* RID_DELETE */ 0, + /* RID_FALSE */ 0, + /* RID_NAMESPACE */ 0, + /* RID_NEW */ 0, + /* RID_OPERATOR */ 0, + /* RID_THIS */ 0, + /* RID_THROW */ 0, + /* RID_TRUE */ 0, + /* RID_TRY */ 0, + /* RID_TYPENAME */ 0, + /* RID_TYPEID */ 0, + /* RID_USING */ 0, + + /* casts */ + /* RID_CONSTCAST */ 0, + /* RID_DYNCAST */ 0, + /* RID_REINTCAST */ 0, + /* RID_STATCAST */ 0, + + /* alternate spellings */ + /* RID_AND */ 0, + /* RID_AND_EQ */ 0, + /* RID_NOT */ 0, + /* RID_NOT_EQ */ 0, + /* RID_OR */ 0, + /* RID_OR_EQ */ 0, + /* RID_XOR */ 0, + /* RID_XOR_EQ */ 0, + /* RID_BITAND */ 0, + /* RID_BITOR */ 0, + /* RID_COMPL */ 0, + + /* Objective C */ + /* RID_ID */ OBJECTNAME, + /* RID_AT_ENCODE */ ENCODE, + /* RID_AT_END */ END, + /* RID_AT_CLASS */ CLASS, + /* RID_AT_ALIAS */ ALIAS, + /* RID_AT_DEFS */ DEFS, + /* RID_AT_PRIVATE */ PRIVATE, + /* RID_AT_PROTECTED */ PROTECTED, + /* RID_AT_PUBLIC */ PUBLIC, + /* RID_AT_PROTOCOL */ PROTOCOL, + /* RID_AT_SELECTOR */ SELECTOR, + /* RID_AT_INTERFACE */ INTERFACE, + /* RID_AT_IMPLEMENTATION */ IMPLEMENTATION +}; + +static void +init_reswords () +{ + unsigned int i; + tree id; + int mask = (D_YES + | (doing_objc_thang ? 0 : D_OBJC) + | (flag_isoc99 ? 0 : D_C89) + | (flag_traditional ? D_TRAD : 0) + | (flag_no_asm ? (flag_isoc99 ? D_EXT : D_EXT|D_EXT89) : 0)); + + /* It is not necessary to register ridpointers as a GC root, because + all the trees it points to are permanently interned in the + get_identifier hash anyway. */ + ridpointers = (tree *) xcalloc ((int) RID_MAX, sizeof (tree)); + for (i = 0; i < N_reswords; i++) + { + id = get_identifier (reswords[i].word); + C_RID_CODE (id) = reswords[i].rid; + ridpointers [(int) reswords[i].rid] = id; + if (! (reswords[i].disable & mask)) + C_IS_RESERVED_WORD (id) = 1; + } +} + +const char * +init_parse (filename) + const char *filename; +{ + add_c_tree_codes (); + + /* Make identifier nodes long enough for the language-specific slots. */ + set_identifier_size (sizeof (struct lang_identifier)); + + init_reswords (); + init_pragma (); + + return init_c_lex (filename); +} + +void +finish_parse () +{ +#if USE_CPPLIB + cpp_finish (&parse_in, 0 /* no printer */); + errorcount += parse_in.errors; +#else + fclose (finput); +#endif +} + +#if USE_CPPLIB +#define NAME(type) cpp_type2name (type) +#else +/* Bleah */ +#include "symcat.h" +#define OP(e, s) s, +#define TK(e, s) STRINGX(e), + +static const char *type2name[N_TTYPES] = { TTYPE_TABLE }; +#define NAME(type) type2name[type] +#endif + +static void +yyerror (msgid) + const char *msgid; +{ + const char *string = _(msgid); + + if (last_token == CPP_EOF) + error ("%s at end of input", string); + else if (last_token == CPP_CHAR || last_token == CPP_WCHAR) + { + unsigned int val = TREE_INT_CST_LOW (yylval.ttype); + const char *ell = (last_token == CPP_CHAR) ? "" : "L"; + if (val <= UCHAR_MAX && ISGRAPH (val)) + error ("%s before %s'%c'", string, ell, val); + else + error ("%s before %s'\\x%x'", string, ell, val); + } + else if (last_token == CPP_STRING + || last_token == CPP_WSTRING + || last_token == CPP_OSTRING) + error ("%s before string constant", string); + else if (last_token == CPP_NUMBER + || last_token == CPP_INT + || last_token == CPP_FLOAT) + error ("%s before numeric constant", string); + else if (last_token == CPP_NAME) + error ("%s before \"%s\"", string, IDENTIFIER_POINTER (yylval.ttype)); + else + error ("%s before '%s' token", string, NAME(last_token)); +} + +static inline int +_yylex () +{ + retry: + last_token = c_lex (&yylval.ttype); + + switch (last_token) + { + case CPP_EQ: return '='; + case CPP_NOT: return '!'; + case CPP_GREATER: yylval.code = GT_EXPR; return ARITHCOMPARE; + case CPP_LESS: yylval.code = LT_EXPR; return ARITHCOMPARE; + case CPP_PLUS: yylval.code = PLUS_EXPR; return '+'; + case CPP_MINUS: yylval.code = MINUS_EXPR; return '-'; + case CPP_MULT: yylval.code = MULT_EXPR; return '*'; + case CPP_DIV: yylval.code = TRUNC_DIV_EXPR; return '/'; + case CPP_MOD: yylval.code = TRUNC_MOD_EXPR; return '%'; + case CPP_AND: yylval.code = BIT_AND_EXPR; return '&'; + case CPP_OR: yylval.code = BIT_IOR_EXPR; return '|'; + case CPP_XOR: yylval.code = BIT_XOR_EXPR; return '^'; + case CPP_RSHIFT: yylval.code = RSHIFT_EXPR; return RSHIFT; + case CPP_LSHIFT: yylval.code = LSHIFT_EXPR; return LSHIFT; + + case CPP_COMPL: return '~'; + case CPP_AND_AND: return ANDAND; + case CPP_OR_OR: return OROR; + case CPP_QUERY: return '?'; + case CPP_COLON: return ':'; + case CPP_COMMA: return ','; + case CPP_OPEN_PAREN: return '('; + case CPP_CLOSE_PAREN: return ')'; + case CPP_EQ_EQ: yylval.code = EQ_EXPR; return EQCOMPARE; + case CPP_NOT_EQ: yylval.code = NE_EXPR; return EQCOMPARE; + case CPP_GREATER_EQ:yylval.code = GE_EXPR; return ARITHCOMPARE; + case CPP_LESS_EQ: yylval.code = LE_EXPR; return ARITHCOMPARE; + + case CPP_PLUS_EQ: yylval.code = PLUS_EXPR; return ASSIGN; + case CPP_MINUS_EQ: yylval.code = MINUS_EXPR; return ASSIGN; + case CPP_MULT_EQ: yylval.code = MULT_EXPR; return ASSIGN; + case CPP_DIV_EQ: yylval.code = TRUNC_DIV_EXPR; return ASSIGN; + case CPP_MOD_EQ: yylval.code = TRUNC_MOD_EXPR; return ASSIGN; + case CPP_AND_EQ: yylval.code = BIT_AND_EXPR; return ASSIGN; + case CPP_OR_EQ: yylval.code = BIT_IOR_EXPR; return ASSIGN; + case CPP_XOR_EQ: yylval.code = BIT_XOR_EXPR; return ASSIGN; + case CPP_RSHIFT_EQ: yylval.code = RSHIFT_EXPR; return ASSIGN; + case CPP_LSHIFT_EQ: yylval.code = LSHIFT_EXPR; return ASSIGN; + + case CPP_OPEN_SQUARE: return '['; + case CPP_CLOSE_SQUARE: return ']'; + case CPP_OPEN_BRACE: return '{'; + case CPP_CLOSE_BRACE: return '}'; + case CPP_SEMICOLON: return ';'; + case CPP_ELLIPSIS: return ELLIPSIS; + + case CPP_PLUS_PLUS: return PLUSPLUS; + case CPP_MINUS_MINUS: return MINUSMINUS; + case CPP_DEREF: return POINTSAT; + case CPP_DOT: return '.'; + + case CPP_EOF: +#if USE_CPPLIB + cpp_pop_buffer (&parse_in); + if (! CPP_BUFFER (&parse_in)) +#endif + return 0; + goto retry; + + case CPP_NAME: + if (C_IS_RESERVED_WORD (yylval.ttype)) + return rid_to_yy[C_RID_CODE (yylval.ttype)]; + + if (IDENTIFIER_POINTER (yylval.ttype)[0] == '@') + { + error ("invalid identifier `%s'", IDENTIFIER_POINTER (yylval.ttype)); + return IDENTIFIER; + } + + { + tree decl; + + decl = lookup_name (yylval.ttype); + + if (decl) + { + if (TREE_CODE (decl) == TYPE_DECL) + return TYPENAME; + /* A user-invisible read-only initialized variable + should be replaced by its value. + We handle only strings since that's the only case used in C. */ + else if (TREE_CODE (decl) == VAR_DECL + && DECL_IGNORED_P (decl) + && TREE_READONLY (decl) + && DECL_INITIAL (decl) != 0 + && TREE_CODE (DECL_INITIAL (decl)) == STRING_CST) + { + tree stringval = DECL_INITIAL (decl); + + /* Copy the string value so that we won't clobber anything + if we put something in the TREE_CHAIN of this one. */ + yylval.ttype = build_string (TREE_STRING_LENGTH (stringval), + TREE_STRING_POINTER (stringval)); + return STRING; + } + } + else if (doing_objc_thang) + { + tree objc_interface_decl = is_class_name (yylval.ttype); + + if (objc_interface_decl) + { + yylval.ttype = objc_interface_decl; + return CLASSNAME; + } + } + + return IDENTIFIER; + } + + case CPP_INT: + case CPP_FLOAT: + case CPP_NUMBER: + case CPP_CHAR: + case CPP_WCHAR: + return CONSTANT; + + case CPP_STRING: + case CPP_WSTRING: + return STRING; + + case CPP_OSTRING: + return OBJC_STRING; + + /* These tokens are C++ specific (and will not be generated + in C mode, but let's be cautious). */ + case CPP_SCOPE: + case CPP_DEREF_STAR: + case CPP_DOT_STAR: + case CPP_MIN_EQ: + case CPP_MAX_EQ: + case CPP_MIN: + case CPP_MAX: + /* These tokens should not survive translation phase 4. */ + case CPP_HASH: + case CPP_PASTE: + case CPP_BACKSLASH: + error ("syntax error before '%s' token", NAME(last_token)); + goto retry; + + default: + abort (); + } + + /* NOTREACHED */ +} + +static int +yylex() +{ + int r; + timevar_push (TV_LEX); + r = _yylex(); + timevar_pop (TV_LEX); + return r; +} + +/* Sets the value of the 'yydebug' variable to VALUE. + This is a function so we don't have to have YYDEBUG defined + in order to build the compiler. */ + +void +set_yydebug (value) + int value; +{ +#if YYDEBUG != 0 + yydebug = value; +#else + warning ("YYDEBUG not defined."); +#endif +} + +/* Function used when yydebug is set, to print a token in more detail. */ + +static void +yyprint (file, yychar, yyl) + FILE *file; + int yychar; + YYSTYPE yyl; +{ + tree t = yyl.ttype; + + fprintf (file, " [%s]", NAME(last_token)); + + switch (yychar) + { + case IDENTIFIER: + case TYPENAME: + case OBJECTNAME: + case TYPESPEC: + case TYPE_QUAL: + case SCSPEC: + if (IDENTIFIER_POINTER (t)) + fprintf (file, " `%s'", IDENTIFIER_POINTER (t)); + break; + + case CONSTANT: + fprintf (file, " %s", GET_MODE_NAME (TYPE_MODE (TREE_TYPE (t)))); + if (TREE_CODE (t) == INTEGER_CST) + fprintf (file, +#if HOST_BITS_PER_WIDE_INT == 64 +#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT + " 0x%x%016x", +#else +#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG + " 0x%lx%016lx", +#else + " 0x%llx%016llx", +#endif +#endif +#else +#if HOST_BITS_PER_WIDE_INT != HOST_BITS_PER_INT + " 0x%lx%08lx", +#else + " 0x%x%08x", +#endif +#endif + TREE_INT_CST_HIGH (t), TREE_INT_CST_LOW (t)); + break; + } +} + +/* This is not the ideal place to put these, but we have to get them out + of c-lex.c because cp/lex.c has its own versions. */ + +/* Return something to represent absolute declarators containing a *. + TARGET is the absolute declarator that the * contains. + TYPE_QUALS is a list of modifiers such as const or volatile + to apply to the pointer type, represented as identifiers. + + We return an INDIRECT_REF whose "contents" are TARGET + and whose type is the modifier list. */ + +tree +make_pointer_declarator (type_quals, target) + tree type_quals, target; +{ + return build1 (INDIRECT_REF, type_quals, target); +} diff --git a/gcc/c-pragma.c b/gcc/c-pragma.c index 3bb9a39..2d6bee8 100644 --- a/gcc/c-pragma.c +++ b/gcc/c-pragma.c @@ -28,9 +28,28 @@ Boston, MA 02111-1307, USA. */ #include "flags.h" #include "toplev.h" #include "ggc.h" +#include "c-lex.h" +#include "cpplib.h" #ifdef HANDLE_GENERIC_PRAGMAS +#if USE_CPPLIB +extern cpp_reader parse_in; +#else +struct pragma_entry; +static struct pragma_entry *pragmas; + +void cpp_register_pragma PARAMS ((cpp_reader *, const char *, const char *, + void (*) PARAMS ((cpp_reader *)) )); +void cpp_register_pragma_space PARAMS ((cpp_reader *, const char *)); +#endif + +#define BAD(msgid) do { warning (msgid); return; } while (0) +#define BAD2(msgid, arg) do { warning (msgid, arg); return; } while (0) + +#ifdef HANDLE_PRAGMA_PACK +static void handle_pragma_pack PARAMS ((cpp_reader *)); + #ifdef HANDLE_PRAGMA_PACK_PUSH_POP typedef struct align_stack { @@ -48,34 +67,19 @@ static struct align_stack * alignment_stack = NULL; happens, we restore the value to this, not to a value of 0 for maximum_field_alignment. Value is in bits. */ static int default_alignment; +#define SET_GLOBAL_ALIGNMENT(ALIGN) \ +(default_alignment = maximum_field_alignment = (ALIGN)) -static int push_alignment PARAMS ((int, tree)); -static int pop_alignment PARAMS ((tree)); -#ifdef HANDLE_PRAGMA_PACK_PUSH_POP +static void push_alignment PARAMS ((int, tree)); +static void pop_alignment PARAMS ((tree)); static void mark_align_stack PARAMS ((void *)); -#endif /* Push an alignment value onto the stack. */ -static int +static void push_alignment (alignment, id) int alignment; tree id; { - switch (alignment) - { - case 0: - case 1: - case 2: - case 4: - case 8: - case 16: - break; - default: - warning ("\ -Alignment must be a small power of two, not %d, in #pragma pack", - alignment); - return 0; - } if (alignment_stack == NULL || alignment_stack->alignment != alignment @@ -98,16 +102,14 @@ Alignment must be a small power of two, not %d, in #pragma pack", alignment_stack = entry; - maximum_field_alignment = alignment * BITS_PER_UNIT; + maximum_field_alignment = alignment; } else alignment_stack->num_pushes ++; - - return 1; } /* Undo a push of an alignment onto the stack. */ -static int +static void pop_alignment (id) tree id; { @@ -118,7 +120,7 @@ pop_alignment (id) warning ("\ #pragma pack (pop) encountered without matching #pragma pack (push, )" ); - return 0; + return; } /* If we got an identifier, strip away everything above the target @@ -145,320 +147,307 @@ pop_alignment (id) if (entry == NULL) maximum_field_alignment = default_alignment; else - maximum_field_alignment = entry->alignment * BITS_PER_UNIT; + maximum_field_alignment = entry->alignment; free (alignment_stack); alignment_stack = entry; } - - return 1; } -#endif /* HANDLE_PRAGMA_PACK_PUSH_POP */ - -/* Handle one token of a pragma directive. TOKEN is the current token, and - STRING is its printable form. Some front ends do not support generating - tokens, and will only pass in a STRING. Also some front ends will reuse - the buffer containing STRING, so it must be copied to a local buffer if - it needs to be preserved. - - If STRING is non-NULL, then the return value will be ignored, and there - will be futher calls to handle_pragma_token in order to handle the rest of - the line containing the #pragma directive. If STRING is NULL, the entire - line has now been presented to handle_pragma_token and the return value - should be zero if the pragma flawed in some way, or if the pragma was not - recognised, and non-zero if it was successfully handled. */ - -int -handle_pragma_token (string, token) - const char *string; - tree token; + +static void +mark_align_stack (p) + void *p; { - static enum pragma_state state = ps_start; - static enum pragma_state type; -#ifdef HANDLE_PRAGMA_WEAK - static char *name; - static char *value; -#endif -#if defined(HANDLE_PRAGMA_PACK) || defined(HANDLE_PRAGMA_PACK_PUSH_POP) - static unsigned int align; -#endif - static tree id; + align_stack *a = *(align_stack **) p; - /* If we have reached the end of the #pragma directive then - determine what value we should return. */ - - if (string == NULL) + while (a) { - int ret_val = 0; - - switch (type) - { - default: - abort (); - break; - - case ps_done: - /* The pragma was not recognised. */ - break; - -#ifdef HANDLE_PRAGMA_PACK - case ps_pack: - if (state == ps_right) - { - maximum_field_alignment = align * BITS_PER_UNIT; -#ifdef HANDLE_PRAGMA_PACK_PUSH_POP - default_alignment = maximum_field_alignment; -#endif - ret_val = 1; - } - else - warning ("malformed `#pragma pack'"); - break; -#endif /* HANDLE_PRAGMA_PACK */ - -#ifdef HANDLE_PRAGMA_PACK_PUSH_POP - case ps_push: - if (state == ps_right) - ret_val = push_alignment (align, id); - else - warning ("malformed '#pragma pack(push[,id],)'"); - break; - - case ps_pop: - if (state == ps_right) - ret_val = pop_alignment (id); - else - warning ("malformed '#pragma pack(pop[,id])'"); - break; + ggc_mark_tree (a->id); + a = a->prev; + } +} +#else /* not HANDLE_PRAGMA_PACK_PUSH_POP */ +#define SET_GLOBAL_ALIGNMENT(ALIGN) (maximum_field_alignment = (ALIGN)) +#define push_alignment(ID, N) \ + BAD("#pragma pack(push[, id], ) is not supported on this target") +#define pop_alignment(ID) \ + BAD("#pragma pack(pop[, id], ) is not supported on this target") #endif /* HANDLE_PRAGMA_PACK_PUSH_POP */ - -#ifdef HANDLE_PRAGMA_WEAK - case ps_weak: - if (HANDLE_PRAGMA_WEAK) - { - if (state == ps_name) - ret_val = add_weak (name, NULL); - else if (state == ps_value) - ret_val = add_weak (name, value); - else - warning ("malformed `#pragma weak'"); - } - else - ret_val = 1; /* Ignore the pragma. */ - break; -#endif /* HANDLE_PRAGMA_WEAK */ - - case ps_poison: - ret_val = 1; - break; - } - type = state = ps_start; - id = NULL_TREE; - - return ret_val; +/* #pragma pack () + #pragma pack (N) + + #pragma pack (push, N) + #pragma pack (push, ID, N) + #pragma pack (pop) + #pragma pack (pop, ID) */ +static void +handle_pragma_pack (dummy) + cpp_reader *dummy ATTRIBUTE_UNUSED; +{ + tree x, id = 0; + int align; + enum cpp_ttype token; + enum { set, reset, push, pop } action; + + if (c_lex (&x) != CPP_OPEN_PAREN) + BAD ("missing '(' after '#pragma pack' - ignored"); + + token = c_lex (&x); + if (token == CPP_CLOSE_PAREN) + action = reset; + else if (token == CPP_NUMBER) + { + align = TREE_INT_CST_LOW (x); + action = set; + } + else if (token == CPP_NAME) + { + if (!strcmp (IDENTIFIER_POINTER (x), "push")) + action = push; + else if (!strcmp (IDENTIFIER_POINTER (x), "pop")) + action = pop; + else + BAD2 ("unknown action '%s' for '#pragma pack' - ignored", + IDENTIFIER_POINTER (x)); } + else + BAD ("malformed '#pragma pack' - ignored"); - /* If we have been given a token, but it is not an identifier, - or a small constant, then something has gone wrong. */ - if (token) + token = c_lex (&x); + if ((action == set || action == reset) && token != CPP_CLOSE_PAREN) + BAD ("malformed '#pragma pack' - ignored"); + if ((action == push || action == pop) && token != CPP_COMMA) + BAD2 ("malformed '#pragma pack(%s[, id], )' - ignored", + action == push ? "push" : "pop"); + + if (action == push || action == pop) { - switch (TREE_CODE (token)) + token = c_lex (&x); + if (token == CPP_NAME) { - case IDENTIFIER_NODE: - break; - - case INTEGER_CST: - if (TREE_INT_CST_HIGH (token) != 0) - return 0; - break; - - default: - return 0; + id = x; + if (c_lex (&x) != CPP_COMMA) + BAD2 ("malformed '#pragma pack(%s[, id], )' - ignored", + action == push ? "push" : "pop"); + token = c_lex (&x); } + if (token == CPP_NUMBER) + align = TREE_INT_CST_LOW (x); + else + BAD2 ("malformed '#pragma pack(%s[, id], )' - ignored", + action == push ? "push" : "pop"); + + if (c_lex (&x) != CPP_CLOSE_PAREN) + BAD ("malformed '#pragma pack' - ignored"); } - - switch (state) + if (c_lex (&x) != CPP_EOF) + warning ("junk at end of '#pragma pack'"); + + switch (align) { - case ps_start: - type = state = ps_done; -#ifdef HANDLE_PRAGMA_PACK - if (strcmp (string, "pack") == 0) - type = state = ps_pack; -#endif -#ifdef HANDLE_PRAGMA_WEAK - if (strcmp (string, "weak") == 0) - type = state = ps_weak; -#endif - if (strcmp (string, "poison") == 0) - type = state = ps_poison; + case 0: + case 1: + case 2: + case 4: + case 8: + case 16: + align *= BITS_PER_UNIT; break; + default: + BAD2 ("alignment must be a small power of two, not %d", align); + } -#ifdef HANDLE_PRAGMA_WEAK - case ps_weak: - name = xstrdup (string); - state = ps_name; - break; - - case ps_name: - state = (strcmp (string, "=") ? ps_bad : ps_equals); - break; + switch (action) + { + case set: SET_GLOBAL_ALIGNMENT (align); break; + case reset: SET_GLOBAL_ALIGNMENT (0); break; + case push: push_alignment (align, id); break; + case pop: pop_alignment (id); break; + } +} +#endif /* HANDLE_PRAGMA_PACK */ - case ps_equals: - value = xstrdup (string); - state = ps_value; - break; +#ifdef HANDLE_PRAGMA_WEAK +static void handle_pragma_weak PARAMS ((cpp_reader *)); - case ps_value: - state = ps_bad; - break; -#endif /* HANDLE_PRAGMA_WEAK */ - -#ifdef HANDLE_PRAGMA_PACK - case ps_pack: - state = (strcmp (string, "(") ? ps_bad : ps_left); - break; +/* #pragma weak name [= value] */ +static void +handle_pragma_weak (dummy) + cpp_reader *dummy ATTRIBUTE_UNUSED; +{ + tree name, value, x; + enum cpp_ttype t; - case ps_left: + value = 0; - if (token == NULL_TREE) - { - /* #pragma pack () resets packing rules to their - defaults. */ - if (strcmp (string, ")") == 0) - { - align = 0; - state = ps_right; - } - else - state = ps_bad; - } - else if (TREE_CODE (token) == INTEGER_CST) - goto handle_align; + if (c_lex (&name) != CPP_NAME) + BAD ("malformed #pragma weak, ignored"); + t = c_lex (&x); + if (t == CPP_EQ) + { + if (c_lex (&value) != CPP_NAME) + BAD ("malformed #pragma weak, ignored"); + t = c_lex (&x); + } + if (t != CPP_EOF) + warning ("junk at end of #pragma weak"); -#ifdef HANDLE_PRAGMA_PACK_PUSH_POP - else if (TREE_CODE (token) == IDENTIFIER_NODE) - { - if (strcmp (string, "push") == 0) - type = state = ps_push; - else if (strcmp (string, "pop") == 0) - type = state = ps_pop; - else - state = ps_bad; - } + add_weak (IDENTIFIER_POINTER (name), value ? IDENTIFIER_POINTER (value) : 0); +} #endif - else - state = ps_bad; - break; - handle_align: - switch (tree_log2 (token)) - { - case 0: - case 1: - case 2: - case 3: - case 4: - state = ps_align; - align = 1 << tree_log2 (token); - break; - - default: - state = ps_bad; - break; - } - break; +#if !USE_CPPLIB +/* Glue version of cpplib's pragma registration and dispatch system. */ +struct pragma_entry +{ + struct pragma_entry *next; + const char *name; + size_t len; + int isnspace; + union { + void (*handler) PARAMS ((cpp_reader *)); + struct pragma_entry *space; + } u; +}; - case ps_align: - state = (strcmp (string, ")") ? ps_bad : ps_right); - break; +void +cpp_register_pragma_space (pfile, space) + cpp_reader *pfile ATTRIBUTE_UNUSED; + const char *space; +{ + struct pragma_entry *new; + const struct pragma_entry *p = pragmas; + size_t len = strlen (space); - case ps_right: - state = ps_bad; - break; -#endif /* HANDLE_PRAGMA_PACK */ + while (p) + { + if (p->isnspace && p->len == len && !memcmp (p->name, space, len)) + return; + p = p->next; + } -#ifdef HANDLE_PRAGMA_PACK_PUSH_POP - case ps_push: - state = (strcmp (string, ",") ? ps_bad : ps_pushcomma); - break; + new = (struct pragma_entry *) xmalloc (sizeof (struct pragma_entry)); + new->name = space; + new->len = len; + new->isnspace = 1; + new->u.space = 0; - case ps_pushid: - state = (strcmp (string, ",") ? ps_bad : ps_pushcomma2); - break; + new->next = pragmas; + pragmas = new; +} - case ps_pushcomma: - if (token && TREE_CODE (token) == IDENTIFIER_NODE) +void +cpp_register_pragma (pfile, space, name, handler) + cpp_reader *pfile ATTRIBUTE_UNUSED; + const char *space; + const char *name; + void (*handler) PARAMS ((cpp_reader *)); +{ + struct pragma_entry **x, *new; + size_t len; + + x = &pragmas; + if (space) + { + struct pragma_entry *p = pragmas; + len = strlen (space); + while (p) { - id = token; - state = ps_pushid; - break; + if (p->isnspace && p->len == len && !memcmp (p->name, space, len)) + { + x = &p->u.space; + goto found; + } + p = p->next; } + abort (); + } - /* else fall through */ - case ps_pushcomma2: - if (token && TREE_CODE (token) == INTEGER_CST) - goto handle_align; - else - state = ps_bad; - break; + found: + new = (struct pragma_entry *) xmalloc (sizeof (struct pragma_entry)); + new->name = name; + new->len = strlen (name); + new->isnspace = 0; + new->u.handler = handler; - case ps_pop: - if (strcmp (string, ",") == 0) - state = ps_popcomma; - else - state = (strcmp (string, ")") ? ps_bad : ps_right); - break; + new->next = *x; + *x = new; +} - case ps_popcomma: - if (token && TREE_CODE (token) == IDENTIFIER_NODE) - { - id = token; - state = ps_align; - } - else - state = ps_bad; - break; -#endif /* HANDLE_PRAGMA_PACK_PUSH_POP */ +/* Called from process_directive() for #pragma lines. */ +void +dispatch_pragma () +{ + enum cpp_ttype t; + tree x; + const struct pragma_entry *p; + const char *name; + size_t len; - case ps_poison: - if (token && TREE_CODE (token) != IDENTIFIER_NODE) - state = ps_bad; - break; + p = pragmas; - case ps_bad: - case ps_done: - break; + new_space: + t = c_lex (&x); + if (t == CPP_EOF) + return; - default: - abort (); + if (t != CPP_NAME) + { + warning ("malformed #pragma directive"); + return; } - return 1; -} -#endif /* HANDLE_GENERIC_PRAGMAS */ - -#ifdef HANDLE_PRAGMA_PACK_PUSH_POP -static void -mark_align_stack (p) - void *p; -{ - align_stack *a = *(align_stack **) p; - - while (a) + name = IDENTIFIER_POINTER (x); + len = IDENTIFIER_LENGTH (x); + while (p) { - ggc_mark_tree (a->id); - a = a->prev; + if (strlen (p->name) == len && !memcmp (p->name, name, len)) + { + if (p->isnspace) + { + p = p->u.space; + goto new_space; + } + else + { + (*p->u.handler) (0); + return; + } + } + p = p->next; } + + /* Issue a warning message if we have been asked to do so. Ignore + unknown pragmas in system header file unless an explcit + -Wunknown-pragmas has been given. */ + if (warn_unknown_pragmas > in_system_header) + warning ("ignoring pragma %s", name); } + #endif void init_pragma () { +#if !USE_CPPLIB + cpp_reader *pfile = 0; +#else + cpp_reader *pfile = &parse_in; +#endif + +#ifdef HANDLE_PRAGMA_PACK + cpp_register_pragma (pfile, 0, "pack", handle_pragma_pack); +#endif +#ifdef HANDLE_PRAGMA_WEAK + cpp_register_pragma (pfile, 0, "weak", handle_pragma_weak); +#endif + #ifdef HANDLE_PRAGMA_PACK_PUSH_POP ggc_add_root (&alignment_stack, 1, sizeof(alignment_stack), mark_align_stack); #endif } + +#endif /* HANDLE_GENERIC_PRAGMAS */ diff --git a/gcc/c-pragma.h b/gcc/c-pragma.h index 65b1cc4..50d0f57 100644 --- a/gcc/c-pragma.h +++ b/gcc/c-pragma.h @@ -61,41 +61,20 @@ extern int add_weak PARAMS ((const char *, const char *)); /* Define HANDLE_GENERIC_PRAGMAS if any kind of front-end pragma parsing is to be done. The code in GCC's generic C source files will only look for the definition of this constant. They will - ignore definitions of HANDLE_PRAGMA_PACK and so on. - With #pragma poison, this is always set. */ -#define HANDLE_GENERIC_PRAGMAS 1 - - -#ifdef HANDLE_GENERIC_PRAGMAS -enum pragma_state -{ - ps_start, - ps_done, -#ifdef HANDLE_PRAGMA_WEAK - ps_weak, - ps_name, - ps_equals, - ps_value, -#endif -#ifdef HANDLE_PRAGMA_PACK - ps_pack, - ps_left, - ps_align, - ps_right, + ignore definitions of HANDLE_PRAGMA_PACK and so on. */ +#if defined HANDLE_PRAGMA_PACK || defined HANDLE_PRAGMA_WEAK +#define HANDLE_GENERIC_PRAGMAS #endif -#ifdef HANDLE_PRAGMA_PACK_PUSH_POP - ps_push, ps_pushcomma, ps_pushid, ps_pushcomma2, - ps_pop, ps_popcomma, -#endif - ps_poison, - ps_bad -}; -/* Handle a C style pragma */ -extern int handle_pragma_token PARAMS ((const char *, tree)); +#ifdef HANDLE_GENERIC_PRAGMAS +extern void init_pragma PARAMS ((void)); -#endif /* HANDLE_GENERIC_PRAGMAS */ +# if !USE_CPPLIB +extern void dispatch_pragma PARAMS ((void)); +# endif -extern void init_pragma PARAMS ((void)); +#else +# define init_pragma() +#endif #endif /* _C_PRAGMA_H */ diff --git a/gcc/c-tree.h b/gcc/c-tree.h index af9a3b6..290ebe9 100644 --- a/gcc/c-tree.h +++ b/gcc/c-tree.h @@ -28,13 +28,18 @@ Boston, MA 02111-1307, USA. */ /* The limbo_value is used for block level extern declarations, which need to be type checked against subsequent extern declarations. They can't - be referenced after they fall out of scope, so they can't be global. */ + be referenced after they fall out of scope, so they can't be global. + + The rid_code field is used for keywords. It is in all + lang_identifier nodes, because some keywords are only special in a + particular context. */ struct lang_identifier { struct tree_identifier ignore; tree global_value, local_value, label_value, implicit_decl; tree error_locus, limbo_value; + enum rid rid_code; }; /* Macros for access to language-specific slots in an identifier. */ @@ -83,6 +88,14 @@ extern int pedantic; nonzero if the definition of the type has already started. */ #define C_TYPE_BEING_DEFINED(type) TYPE_LANG_FLAG_0 (type) +/* In an IDENTIFIER_NODE, nonzero if this identifier is actually a + keyword. C_RID_CODE (node) is then the RID_* value of the keyword, + and C_RID_YYCODE is the token number wanted by Yacc. */ + +#define C_IS_RESERVED_WORD(id) TREE_LANG_FLAG_0 (id) +#define C_RID_CODE(id) \ + (((struct lang_identifier *) (id))->rid_code) + /* In a RECORD_TYPE, a sorted array of the fields of the type. */ struct lang_type { diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 6dd4b94..4b28703 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,52 @@ +2000-09-06 Zack Weinberg + + Integrated preprocessor. + + * Make-lang.in, Makefile.in: Remove all references to input.c, + gxx.gperf, and hash.h. Add ../c-lex.o to C_OBJS. + * gxx.gperf, hash.h, input.c: Delete. + * lang-specs.h: Pass -lang-c++ to cc1plus so cpplib is + initialized properly. + + * class.c (fixup_pending_inline): Take a tree, not a + struct pending_inline *. All callers changed. + (init_class_processing): Set RID_PUBLIC, RID_PRIVATE, + RID_PROTECTED entries in ridpointers[] array here. + * decl.c (duplicate_decls): Do not refer to struct + pending_inline. + (record_builtin_type, init_decl_processing): Use RID_MAX not + CP_RID_MAX. + (grokdeclarator): Use C_IS_RESERVED_WORD. + * decl2.c (lang_decode_option): Ignore -lang-c++ for sake of + cpplib. + (grok_x_components): Do not inspect pending_inlines chain. + + * cp-tree.h (struct lang_identifier): Add rid_code entry. + (C_IS_RESERVED_WORD, C_RID_CODE, C_RID_YYCODE): New. + (flag_no_gnu_keywords, flag_operator_names, rid_to_yy): Declare. + (DEFARG_LENGTH, struct pending_inline, TIME_IDENTIFIER_TIME, + TIME_IDENTIFIER_FILEINFO): Kill. + Update prototypes. + * lex.h: Expunge cp_rid. Rewrite RIDBIT macros to use just a + single 32-bit word. + * parse.y: Call do_pending_inlines unconditionally. + reinit_parse_for_method is now snarf_method. fn.defpen is no + longer necessary. Remove unnecessary annotation on + SCOPE. Do not refer to end_of_file or struct pending_inline. + * semantics.c (begin_inline_definitions): Call + do_pending_inlines unconditionally. + + * lex.c: Remove all code now shared with C front end. + Initialize cpplib properly if USE_CPPLIB. Put reserved words + into the get_identifier table. Rewrite pragma handling to + work with the registry. Move code to save tokens for later + processing to spew.c. + + * spew.c: Rewrite everything in terms of token streams instead + of text. Move routines here from lex.c / input.c as + appropriate. GC-mark trees hanging off the pending inlines + chain. + 2000-09-06 Mark Mitchell * NEWS: Mention that the named return value extension has been @@ -110,7 +159,7 @@ (write_template_parm): Likewise. (write_template_template_parm): Check tree code instead of using TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO. - * method.c (build_overload_nested_name): Add + * method.c (build_overload_nested_name): Add BOUND_TEMPLATE_TEMPLATE_PARM. (process_overload_item): Split TEMPLATE_TEMPLATE_PARM case. * parse.y (bad_parm): Add BOUND_TEMPLATE_TEMPLATE_PARM. @@ -215,10 +264,10 @@ (write_component): Remove. (write_local_name): Add parameter. Use direct local entity to discriminator calculation. - (write_class_enum_type): Pass another argument to write_name. + (write_class_enum_type): Pass another argument to write_name. (write_template_template_arg): Likewise. (make_guard_variable): Likewise. - + 2000-08-27 Jason Merrill * decl.c (pushdecl): Matching decls for local externs are found in @@ -260,7 +309,7 @@ (cp_tree_printer, print_function_argument_list, print_declaration, print_expression, print_function_declaration, print_function_parameter, print_type, print_cv_qualifier): New - functions. + functions. (init_error): Initialize lang_printer. 2000-08-24 Jason Merrill @@ -292,18 +341,18 @@ (write_type): Adjust call to write_function_type. * pt.c (instantiate_template): Instantiate alternate entry points when instantiating the main function. - + 2000-08-23 Gabriel Dos Reis * error.c (cp_print_error_function): Don't use embedded '\n' in - output_printf. + output_printf. 2000-08-23 Gabriel Dos Reis * decl.c (init_decl_processing): Remove bogus initialization. * error.c (lang_print_error_function): Restore here. - (init_error): Initialize print_error_function. - + (init_error): Initialize print_error_function. + 2000-08-22 Theodore Papadopoulo * decl2.c (arg_assoc): Revert my 2000-08-11 change. @@ -339,10 +388,10 @@ (print_template_context): Likewise. (current_tinst_level): Make static to reflect Brendan Kehoe's change of 1995-04-13. - (push_tinst_level): Call print_instantiation_context. - + (push_tinst_level): Call print_instantiation_context. + 2000-08-21 Nix - + * lang-specs.h: Do not process -o or run the assembler if -fsyntax-only. @@ -374,12 +423,12 @@ * decl.c (member_function_or_else): Use cp_error ... %T. (grokdeclarator): Likewise. (start_method): Likewise. - * friend.c (make_friend_class): Use cp_pedwarn ... %T. + * friend.c (make_friend_class): Use cp_pedwarn ... %T. 2000-08-18 Nathan Sidwell * decl2.c (grokfield): Set CLASSTYPE_GOT_SEMICOLON on class - TYPE_DECLs. + TYPE_DECLs. 2000-08-18 Nathan Sidwell @@ -436,7 +485,7 @@ * class.c (instantiate_type): Reinstate local variable deleted in previous change. - + * cvt.c (cp_convert_to_pointer): Pass itf_complain, not itf_no_attributes. @@ -466,10 +515,10 @@ (cp_parse_init): Adjust. (structsp): Clear and restore current_aggr. (component_decl_list): Clear current_aggr. - + * error.c (dump_type, case TYPENAME_TYPE): Don't emit the aggregate tag on the typename's context. - + * pt.c (tsubst_friend_class): Return error_mark_node, if parms becomes NULL. (instantiate_class_template): Ignore error_mark_node friend types. @@ -477,7 +526,7 @@ 2000-08-14 Nathan Sidwell * cvt.c (warn_ref_binding): New static function, broken out of ... - (convert_to_reference): ... here. Use it. + (convert_to_reference): ... here. Use it. 2000-08-11 Kriang Lerdsuwanakij @@ -498,7 +547,7 @@ * cp-tree.h (resolve_scope_to_name): Remove unused prototype. (lookup_nested_tag): Likewise. - + * decl2.c (grokfield): Fix comment to reflect many types of _DECLs can be produced. @@ -528,12 +577,12 @@ * rtti.c (build_dynamic_cast_1): Set "C" linkage for new abi runtime. * cp/tinfo.cc (__dynamic_cast): Likewise. - * cp/inc/cxxabi.h (__dynamic_cast): Likewise. + * cp/inc/cxxabi.h (__dynamic_cast): Likewise. 2000-08-09 Nathan Sidwell * cvt.c (convert_to_pointer_force): Fix error message when - attempting to cast from ambiguous base. + attempting to cast from ambiguous base. 2000-08-08 Jason Merrill @@ -572,9 +621,9 @@ 2000-08-04 Zack Weinberg - * Make-lang.in (cc1plus): Depend on $(BACKEND), not stamp-objlist. - * Makefile.in: Add C_OBJS, BACKEND; delete OBJS, OBJDEPS. - (cc1plus): Link with $(BACKEND) and $(C_OBJS). + * Make-lang.in (cc1plus): Depend on $(BACKEND), not stamp-objlist. + * Makefile.in: Add C_OBJS, BACKEND; delete OBJS, OBJDEPS. + (cc1plus): Link with $(BACKEND) and $(C_OBJS). 2000-08-04 Mark Mitchell @@ -586,7 +635,7 @@ (clone_function_decl): Likewise. * decl2.c (check_classfn): Likewise. * semantics.c (finish_member_declaration): Likewise. - + 2000-08-04 Joseph S. Myers * decl.c (flag_isoc94): New variable. @@ -674,7 +723,7 @@ (binfo_for_vtable): Simplify. * tree.c (unshare_base_binfos): Clear BINFO_PRIMARY_BASE_OF. (make_binfo): Make it have 11 entries. - + 2000-07-30 Alex Samuel * mangle.c (DECL_TEMPLATE_ID_P): Remove. @@ -805,7 +854,7 @@ Wed Jul 26 15:05:51 CEST 2000 Marc Espie * decl2.c (finish_decl_parsing): Handle TEMPLATE_ID_EXPR. - * decl.c (pushdecl): Handle seeing an OVERLOAD in + * decl.c (pushdecl): Handle seeing an OVERLOAD in IDENTIFIER_NAMESPACE_VALUE. 2000-07-16 Mark Mitchell @@ -871,7 +920,7 @@ Wed Jul 26 15:05:51 CEST 2000 Marc Espie (initialize_inlined_parameters): Likewise. (declare_return_variable): Likewise. (expand_call_inline): Likewise. - + 2000-07-10 Jakub Jelinek * semantics.c (expand_body): Sync interface information @@ -881,10 +930,10 @@ Wed Jul 26 15:05:51 CEST 2000 Marc Espie * init.c (build_new_1): Bail early if the call to new fails. - * decl.c (compute_array_index_type): Check specifically for + * decl.c (compute_array_index_type): Check specifically for an INTEGER_CST, not just TREE_CONSTANT. - * decl.c (duplicate_decls): Don't call duplicate_decls on + * decl.c (duplicate_decls): Don't call duplicate_decls on the DECL_TEMPLATE_RESULT. (decls_match): Return 0 if the DECL_TEMPLATE_RESULTs have different codes. @@ -935,7 +984,7 @@ Wed Jul 26 15:05:51 CEST 2000 Marc Espie 2000-07-04 scott snyder Jason Merrill - * repo.c (repo_get_id): Handle the case where a class with virtual + * repo.c (repo_get_id): Handle the case where a class with virtual bases has a null TYPE_BINFO_VTABLE. 2000-07-04 Kevin Buhr @@ -988,7 +1037,7 @@ Wed Jul 26 15:05:51 CEST 2000 Marc Espie * semantics.c (lang_expand_stmt): Changed call to genrtl_compound_stmt to ignore return value. - + 2000-07-02 Mark Mitchell * mangle.c (canonicalize_for_substitution): Return the canonical @@ -1000,14 +1049,14 @@ Wed Jul 26 15:05:51 CEST 2000 Marc Espie 2000-07-01 Benjamin Chelf - * Make-lang.in (cc1plus$(exeext)): Added c-semantics.o. - + * Make-lang.in (cc1plus$(exeext)): Added c-semantics.o. + * Makefile.in (OBJS): Added ../c-semantics.o. (OBJDEPS): Likewise. - + * cp-tree.h (TREE_LANG_FLAG_?): Moved common documentation to ../c-common.h. - (struct stmt_tree): Added comment. + (struct stmt_tree): Added comment. (current_function_name_declared): Removed. (stmts_are_full_exprs_p): Likewise. (genrtl_do_pushlevel): Likewise. @@ -1032,10 +1081,10 @@ Wed Jul 26 15:05:51 CEST 2000 Marc Espie (push_cp_function_context): Likewise. * expect.c (expand_throw): Change reference to - stmts_are_full_exprs_p. + stmts_are_full_exprs_p. * init.c (build_aggr_init): Change reference to - stmts_are_full_exprs_p. + stmts_are_full_exprs_p. (build_vec_init): Likewise. * optimize.c (maybe_clone_body): Change reference to @@ -1069,7 +1118,7 @@ Wed Jul 26 15:05:51 CEST 2000 Marc Espie (genrtl_decl_cleanup): Likewise. (expand_cond): Likewise. (expand_stmt): Renamed to ... - (lang_expand_stmt): ... this. + (lang_expand_stmt): ... this. (lang_expand_expr_stmt): Initialize. (set_current_function_name_declared): Likewise. (stmts_are_full_exprs_p): Likewise. @@ -1089,7 +1138,7 @@ Wed Jul 26 15:05:51 CEST 2000 Marc Espie current_function_name_declared(). (setup_vtbl_ptr): Likewise. (genrtl_do_poplevel): Removed. - + 2000-06-30 Jason Merrill * init.c (init_init_processing): Go back to aligning like @@ -1143,7 +1192,7 @@ Wed Jul 26 15:05:51 CEST 2000 Marc Espie * parse.y: Move inclusion of lex.h. * parse.c: Regenerated. * spew.c: Move inclusion of lex.h. - + * cp-tree.h (struct language_function): Remove temp_name_counter. (temp_name_counter): Remove. (get_temp_name): Change prototype. @@ -1164,7 +1213,7 @@ Wed Jul 26 15:05:51 CEST 2000 Marc Espie (do_static_initialization): Replace sentry with guard throughout. (do_static_destruction): Likewise. * init.c (create_temporary_var): Add comment. - + 2000-06-28 Alex Samuel * mangle.c (find_substitution): Use same_type_p. @@ -1215,7 +1264,7 @@ Wed Jul 26 15:05:51 CEST 2000 Marc Espie (build_modify_expr): Likewise. (get_delta_difference): Likewise. (build_ptrmemfunc): Likewise. - + 2000-06-29 Nathan Sidwell * cp-tree.h (SET_DECL_ARTIFICIAL): Remove. @@ -1250,7 +1299,7 @@ Wed Jul 26 15:05:51 CEST 2000 Marc Espie * pt.c (tsubst, case TEMPLATE_TEMPLATE_PARM): Handle cv-qualified types correctly. - + 2000-06-27 Mark Mitchell * decl.c (grokfndecl): Set DECL_CONTEXT for static functions too. @@ -1283,7 +1332,7 @@ Wed Jul 26 15:05:51 CEST 2000 Marc Espie 2000-06-25 Theodore Papadopoulo - * search.c (lookup_member): Fix typo in comment. + * search.c (lookup_member): Fix typo in comment. 2000-06-24 Jason Merrill @@ -1394,7 +1443,7 @@ Wed Jul 26 15:05:51 CEST 2000 Marc Espie * decl.c (pushdecl): Also pull out one of the FUNCTION_DECLs from an old OVERLOAD when we're declaring a non-function. (pushdecl, destroy_local_var): Check for error_mark_node. - (warn_extern_redeclared_static): Also bail early if + (warn_extern_redeclared_static): Also bail early if we're a CONST_DECL. (push_overloaded_decl): Ignore an old error_mark_node. @@ -1411,7 +1460,7 @@ Wed Jul 26 15:05:51 CEST 2000 Marc Espie 2000-06-20 Jason Merrill - * pt.c (tsubst_decl, case TYPE_DECL): Fix test for TYPE_DECLs + * pt.c (tsubst_decl, case TYPE_DECL): Fix test for TYPE_DECLs for which we don't need to look for instantiations. 2000-06-21 Nathan Sidwell @@ -1447,7 +1496,7 @@ Wed Jul 26 15:05:51 CEST 2000 Marc Espie (build_x_compound_expr): Likewise. (check_return_expr): Likewise. * typeck2.c (add_exception_specifier): Likewise. - + * mangle.c (write_method_parms): Use direct comparison for end of parmlist. @@ -1514,7 +1563,7 @@ Wed Jul 26 15:05:51 CEST 2000 Marc Espie (genrtl_named_return_value): Likewise. (genrtl_begin_stmt_expr): Likewise. (genrtl_finish_stmt_expr): Likewise. - (finish_for_stmt): Removed first argument and generate rtl + (finish_for_stmt): Removed first argument and generate rtl specific code. (finish_switch_stmt): Likewise. (do_poplevel): Removed generate rtl specific code. @@ -1567,7 +1616,7 @@ Wed Jul 26 15:05:51 CEST 2000 Marc Espie (finish_named_return_value): Likewise. (begin_stmt_expr): Likewise. (finish_stmt_expr): Likewise. - + * decl.c (initialize_local_var): Changed call to finish_expr_stmt to call genrtl_expr_stmt when appropriate. @@ -1581,16 +1630,16 @@ Wed Jul 26 15:05:51 CEST 2000 Marc Espie genrtl_expr_stmt when appropriate. (build_vec_init): Likewise. - * parse.y (simple_stmt): Removed first argument from call to - finish_for_stmt. Removed first argument from call to + * parse.y (simple_stmt): Removed first argument from call to + finish_for_stmt. Removed first argument from call to finish_switch_stmt. * parse.c: Regenerated. - * pt.c (tsubst_expr): Removed first argument from call to - finish_for_stmt. Removed first argument from call to + * pt.c (tsubst_expr): Removed first argument from call to + finish_for_stmt. Removed first argument from call to finish_switch_stmt. - + 2000-06-16 Benjamin Chelf * cp-tree.h (enum cplus_tree_code): Changed __DUMMY to @@ -1599,9 +1648,9 @@ Wed Jul 26 15:05:51 CEST 2000 Marc Espie * lex.c (cplus_tree_code_type[]): Removed #include "c-common.def". (cplus_tree_code_length[]): Likewise. (cplus_tree_code_name[]): Likewise. - (init_parse): Added call to add_c_tree_codes. Changed + (init_parse): Added call to add_c_tree_codes. Changed LAST_AND_UNUSED_TREE_CODE to LAST_C_TREE_CODE. - + 2000-06-16 Mark Mitchell * cp-tree.h (finish_mem_initializers): Declare. @@ -1613,7 +1662,7 @@ Wed Jul 26 15:05:51 CEST 2000 Marc Espie the number of trees. (n_trees): Remove. (count_trees): Don't use it. - + 2000-06-15 Jason Merrill * tree.c (count_trees): New debugging function. @@ -1665,12 +1714,12 @@ Wed Jul 26 15:05:51 CEST 2000 Marc Espie * semantics.c (setup_vtbl_ptr): Don't use current_member_init_list and current_base_init_list. (begin_function_definition): Don't call reinit_parse_for_function. - + * dump.c (dequeue_and_dump): Use TREE_VEC_LENGTH with vectors. * error.c (dump_expr): Handle ADDR_EXPRs with REFERENCE_TYPE correctly. - + * cp-tree.h (DECL_PENDING_INLINE_P): Relax checking. 2000-06-14 Benjamin Chelf @@ -1722,11 +1771,11 @@ Wed Jul 26 15:05:51 CEST 2000 Marc Espie * Make-lang.in (CXX_SRCS): Added $(srcdir)/c-common.def. (cc1plus$(exeext)): Added $(srcdir)/c-common.def. - + * lex.c (cplus_tree_code_type[]): Added '#include "c-common.def"'. (cplus_tree_code_length[]): Added '#include "c-common.def"'. (cplus_tree_code_name[]): Added '#include "c-common.def"'. - + 2000-06-14 Mark Mitchell * cp-tree.h (BINFO_OVERRIDE_ALONG_VIRTUAL_PATH): New macro. @@ -1777,7 +1826,7 @@ Tue Jun 13 15:48:03 2000 Maciej W. Rozycki used to initialize the parameters more than once. 2000-06-11 Mark Mitchell - + * mangle.c (NESTED_TEMPLATE_MATCH): Fix typo in comment. (is_std_substitution): Don't check CLASSTYPE_USE_TEMPLATE here. (find_substitution): Only use the `Sa' substitution for @@ -1796,7 +1845,7 @@ Tue Jun 13 15:48:03 2000 Maciej W. Rozycki * class.c (build_vtable): Clarify comment. (build_ctor_vtbl_group): Pass the most derived type to build_vtable. - + 2000-06-11 Kaveh R. Ghazi * decl2.c (compare_options): Don't needlessly cast away const-ness. @@ -1872,7 +1921,7 @@ Tue Jun 13 15:48:03 2000 Maciej W. Rozycki * decl2.c: Remove #inclusion of diagnostic.h (lang_decode_option): Move diagnostic formatting options to - toplevel. + toplevel. * lang-options.h: Remove documentation for diagnostic options. @@ -1978,7 +2027,7 @@ Mon Jun 5 06:48:55 2000 Richard Kenner (grokvardecl): Call mangle_decl for new ABI. Only set mangled name for fully-instantiated templates. * decl2.c (grokclassfn): Use set_mangled_name_for_decl for - destructors with the new ABI. + destructors with the new ABI. (finish_static_data_member_decl): Use mangle_decl under the new ABI. (grokfield): Use mangle_type for new ABI. (grokoptypename): Use mangle_conv_op_for_type for new ABI. @@ -2014,7 +2063,7 @@ Mon Jun 5 06:48:55 2000 Richard Kenner (get_tinfo_decl): Call mangle_typeinfo_for_type for new ABI. (tinfo_base_init): Likewise. Mangle typeinfo string name with mangle_typeinfo_string_for_type. - + 2000-06-03 Mark Mitchell * cp-tree.h (TMPL_ARGS_LEVEL): Clarify comment. @@ -2049,7 +2098,7 @@ Mon Jun 5 06:48:55 2000 Richard Kenner (regenerate_decl_from_template): Tweak formatting. Use TMPL_ARGS_DEPTH for clarity. (set_mangled_name_for_template_decl): Use INNERMOST_ARGS. - + * dump.c (dequeue_and_dump): Dump information about thunks. 2000-06-01 Richard Henderson @@ -2094,7 +2143,7 @@ Wed May 31 14:09:00 2000 Richard Kenner (unsupported_options): New variable (compare_options): New function. (lang_decode_option): Use them. - + * decl.c (build_cp_library_fn): Set DECL_CONTEXT. * method.c (mangle_expression): Adjust test for legal expression @@ -2115,7 +2164,7 @@ Wed May 31 14:09:00 2000 Richard Kenner (build_new_method_call): Use DECL_NONSTATIC_MEMBER_FUNCTION_P. * ir.texi: Update thunk documentation. - + * call.c (joust): Fix handling of overloaded builtin operators. 2000-05-30 Zack Weinberg @@ -2126,7 +2175,7 @@ Wed May 31 14:09:00 2000 Richard Kenner in the user namespace. * lex.c (do_identifier): If the identifier's declaration has DECL_ANTICIPATED on, it has not yet been declared. But do not - replace it with an ordinary implicit declaration. + replace it with an ordinary implicit declaration. * tinfo2.cc: Include stdlib.h. @@ -2263,7 +2312,7 @@ Sat May 27 11:25:46 2000 Richard Kenner (mark_lang_function): Call it. (use_label): New fn, split out from... (make_label_decl): ...here. Don't call it. - (decl_jump_unsafe, check_previous_goto, check_previous_goto_1, + (decl_jump_unsafe, check_previous_goto, check_previous_goto_1, check_previous_gotos): New fns, split out from... (define_label): ...here. (check_switch_goto): New fn. @@ -2292,7 +2341,7 @@ Sat May 27 11:25:46 2000 Richard Kenner (ptm_initializer): ... here. (sythesize_tinfo_var): Adjust. Deal with pointer to member function. - (create_tinfo_types): Adjust. + (create_tinfo_types): Adjust. 2000-05-25 Mark Mitchell @@ -2343,7 +2392,7 @@ Sat May 27 11:25:46 2000 Richard Kenner (expand_indirect_vtbls_init): Remove. * semantics.c (setup_vtbl_ptr): Fix typos in comment. * tree.c (make_binfo): Make them bigger. - + 2000-05-25 Nathan Sidwell * inc/cxxabi.h (__pbase_type_info): Define, based on @@ -2388,7 +2437,7 @@ Sat May 27 11:25:46 2000 Richard Kenner values to indicate the kind of destruction to be done. (build_vbase_delete): Likewise. (build_vec_delete): Likewise. - + * init.c (sort_member_init): Fix typo in error message generation code. @@ -2443,7 +2492,7 @@ Mon May 15 11:46:29 2000 Donald Lindsay * ptree.c (print_lang_decl): Adjust. * typeck.c (build_component_ref): Don't check DECL_LANG_SPECIFIC before checking DECL_MUTABLE_P. - + * decl2.c (maybe_retrofit_in_chrg): Don't create in-charge parameters for template functions. * pt.c (tsubst_decl): Make sure we call maybe_retrofit_in_chrg for @@ -2474,7 +2523,7 @@ Mon May 15 11:46:29 2000 Donald Lindsay (tsubst_copy): Adjust use of IDENTIFIER_TYPENAME_P. * semantics.c (finish_member_declaration): Don't mark members of classes declared in an extern "C" region as extern "C". - + 2000-05-22 Martin v. Löwis * decl2.c (qualified_lookup_using_namespace): Look through @@ -2513,7 +2562,7 @@ Mon May 15 11:46:29 2000 Donald Lindsay (get_ctor_vtbl_name): New function. * search.c (dfs_walk_real): Use BINFO_N_BASETYPES. (init_vbase_pointers): Don't mess with the TREE_CHAIN of a binfo. - + * cp-tree.h (struct lang_type): Remove search_slot. (CLASSTYPE_SEARCH_SLOT): Remove. (emit_base_init): Change prototype. @@ -2598,7 +2647,7 @@ Mon May 15 11:46:29 2000 Donald Lindsay (find_vbase_instance): Use binfo_for_vbase. (binfo_for_vbase): New function. * typeck.c (get_delta_difference): Use binfo_for_vbase. - + 2000-05-17 Mark Mitchell * decl2.c (finish_anon_union): Generalize error messages to handle @@ -2611,7 +2660,7 @@ Mon May 15 11:46:29 2000 Donald Lindsay (expand_member_init): Record the result of name lookup for future reference. * typeck.c (build_component_ref): Fix formatting. - + Wed May 17 17:27:44 2000 Andrew Cagney * decl.c (pop_label): Replace warn_unused with warn_unused_label. @@ -2674,7 +2723,7 @@ Wed May 17 17:27:44 2000 Andrew Cagney (lang_init_options): Set default prefixing rules. * lang-options.h: Add -fdiagnostics-show-location=. - + * decl2.c: #include diagnostic.h. (lang_decode_option): Handle -fdiagnostics-show-location=. @@ -2741,7 +2790,7 @@ Wed May 17 17:27:44 2000 Andrew Cagney * rtti.c (ptmd_initializer): Set non-public, if class is incomplete. - + * inc/cxxabi.h (__dynamic_cast): Explicitly say extern "C++". (__cxa_vec_new, __cxa_vec_ctor, __cxa_vec_dtor, __cxa_vec_delete): Likewise. @@ -2806,7 +2855,7 @@ Wed May 17 17:27:44 2000 Andrew Cagney set DECL_DESTRUCTOR_P or DECL_CONSTRUCTOR_P on a thunk. * search.c (covariant_return_p): Remove THUNK_DECL handling. * ir.texi: Update. - + 2000-05-01 Jason Merrill * tree.c (walk_tree): Set lineno. @@ -2872,7 +2921,7 @@ Wed May 17 17:27:44 2000 Andrew Cagney DECL_RESULT. (expand_call_inline): Update the pending target_exprs stack. (optimize_function): Initialize the stack. - + * decl2.c (finish_file): Fix typo in comment. * method.c (emit_thunk): Don't try to return a `void' value. @@ -2920,7 +2969,7 @@ Wed May 17 17:27:44 2000 Andrew Cagney (build_reinterpret_cast): Likewise. (build_c_cast): Likewise. (convert_for_assignment): Likewise. - + 2000-04-26 Jason Merrill * decl.c (finish_function): Don't play games with DECL_INLINE. @@ -2983,7 +3032,7 @@ Wed May 17 17:27:44 2000 Andrew Cagney 2000-04-22 Gabriel Dos Reis * ir.texi: Document complex number representation. - + 2000-04-20 Nathan Sidwell * rtti.c (init_rtti_processing): Set tinfo_var_id in new-abi. @@ -2998,7 +3047,7 @@ Wed May 17 17:27:44 2000 Andrew Cagney New enumeration. * inc/typeinfo (type_info::before, type_info::operator==): Compare __name addresses. - + * tinfo2.cc: Remove new-abi builtins comment. 2000-04-20 Jason Merrill @@ -3070,7 +3119,7 @@ Mon Apr 17 17:11:16 2000 Mark P Mitchell * method.c (make_thunk): Tweak mangling for vcall offset thunks. Use int_size_in_bytes. (emit_thunk): Handle vcall offset thunks. - + Sat Apr 15 16:00:01 2000 Richard Kenner * decl2.c (parse_time, varconst_time): Delete declarations. @@ -3080,7 +3129,7 @@ Sat Apr 15 16:00:01 2000 Richard Kenner 2000-04-13 Nathan Sidwell * class.c (build_base_field): Reformat comment. - + * inc/cxxabi.h (stddef.h): Comment inclusion. (__base_class_info::__offset): Comment shift. @@ -3114,13 +3163,13 @@ Sat Apr 15 16:00:01 2000 Richard Kenner (build_delete): Use it. Simplify. * optimize.c (maybe_clone_body): Handle destructors. * search.c (lookup_field_queue_p): Use IDENTIFIER_CTOR_OR_DTOR_P. - + * exception.cc (cleanup_fn): New typedef. (CALL_CLEANUP): New macro. (cp_eh_info): Use them. (__cp_push_exception): Likewise. (__cp_pop_exception): Likewise. - + 2000-04-11 Mark Mitchell * cp-tree.h (cp_tree_index): Add CPTI_DTOR_IDENTIFIER. @@ -3173,7 +3222,7 @@ Sat Apr 15 16:00:01 2000 Richard Kenner * search.c (lookup_fnfields_1): Use CLASSTYPE_CONSTRUCTOR_SLOT, CLASSTYPE_DESTRUCTOR_SLOT, and CLASSTYPE_FIRST_CONVERSION_SLOT. * semantics.c (expand_body): Clone function bodies as necessary. - + * optimize.c (remap_decl): Avoid sharing structure for arrays whose size is only known at run-time. * tree.c (copy_tree_r): Don't copy PARM_DECLs. @@ -3200,7 +3249,7 @@ Sat Apr 15 16:00:01 2000 Richard Kenner * pt.c (instantiate_template): Remove goto. * tree.c (build_cplus_method_type): Remove mention of obstacks in comment. - + * cp-tre.h (finish_function): Change prototype. * decl.c (end_cleanup_fn): Adjust caller. (finish_function): Take only one parameter. @@ -3218,7 +3267,7 @@ Sat Apr 15 16:00:01 2000 Richard Kenner * lex.c (copy_decl): Define it. * pt.c (tsubst_decl): Likewise. * tree.c (copy_template_template_parm): Likewise. - + * cp-tree.h (lang_type): Remove has_nonpublic_ctor and has_nonpublic_assign_ref. (TYPE_HAS_NONPUBLIC_CTOR): Don't declare. @@ -3248,7 +3297,7 @@ Sat Apr 15 16:00:01 2000 Richard Kenner * decl.c (check_tag_decl): Notice extra fundamental types. Diagnose empty decls in classes, too. - * decl.c (grokdeclarator): Don't override an anonymous name if no + * decl.c (grokdeclarator): Don't override an anonymous name if no declarator was given. * cvt.c (convert_to_void): Call resolve_offset_ref. @@ -3282,7 +3331,7 @@ Sat Apr 15 16:00:01 2000 Richard Kenner specific catch checking. Fix void conversion check. (__pointer_to_member_type_info::__do_catch): Remove. (__pointer_to_member_type_info::__pointer_catch): Implement. - + 2000-04-10 Martin v. Löwis * lex.c (init_parse): Remove traces of classof and headof. @@ -3301,7 +3350,7 @@ Sat Apr 15 16:00:01 2000 Richard Kenner * pt.c (tsubst_decl): Likewise. * ptree.c (print_lang_decl): Don't print it. * typeck.c (mark_addressable): Don't use it. - + 2000-04-09 Nathan Sidwell * vec.cc: Include and . @@ -3363,8 +3412,8 @@ Sat Apr 15 16:00:01 2000 Richard Kenner __class_type_info::__dyncast_result): Move from inc/cxxabi.h. Adjust. (__class_type_info::find_public_src): Prepend __. Adjust. - (__class_type_info::do_find_public_src, - __si_class_type_info::do_find_public_src, + (__class_type_info::do_find_public_src, + __si_class_type_info::do_find_public_src, __vmi_class_type_info::do_find_public_src): Likewise. (__class_type_info::do_dyncast, __si_class_type_info::do_dyncast, @@ -3407,7 +3456,7 @@ Sat Apr 15 16:00:01 2000 Richard Kenner * typeck.c (build_static_cast): Use complete_ctor_identifier. (build_modify_expr): Likewise. * typeck2.c (build_functional_cast): Likewise. - + Under the new ABI, constructors don't return `this'. * cp-tree.h (warn_reorder): Declare. (special_function_kind): New enum. @@ -3432,7 +3481,7 @@ Sat Apr 15 16:00:01 2000 Richard Kenner of emit_base_init. * typeck.c (check_return_expr): Don't magically convert return statements into `return this' in constructors under the new ABI. - + * cp-tree.h (cp_tree_index): Add CPTI_BASE_CTOR_IDENTIFIER, CPTI_BASE_DTOR_IDENTIFIER, and CPTI_DELETING_DTOR_IDENTIFIER. (base_ctor_identifier): New macro. @@ -3453,7 +3502,7 @@ Sat Apr 15 16:00:01 2000 Richard Kenner (build_delete): Use CLASSTYPE_N_BASECLASSES. * search.c (init_search_processing): Don't initialize vptr_identifier. - + 2000-04-08 Kaveh R. Ghazi * typeck.c (build_binary_op): Call `tree_expr_nonnegative_p' to elide @@ -3471,7 +3520,7 @@ Sat Apr 15 16:00:01 2000 Richard Kenner (__vmi_class_type_info::do_find_public_src): Adjust. (__vmi_class_type_info::do_dyncast): Adjust. (__vmi_class_type_info::do_upcast): Adjust. - + 2000-04-07 Nathan Sidwell * tinfo.cc (convert_to_base): New function. @@ -3491,7 +3540,7 @@ Sat Apr 15 16:00:01 2000 Richard Kenner (DECL_SAVED_INLINE): Rename to ... (DECL_DEFERRED_FN): ... this. (in_function_p): Remove declaration. - (mark_inline_for_output): Rename to ... + (mark_inline_for_output): Rename to ... (defer_fn): ... this. * decl.c (finish_function): Adjust call to mark_inline_for_output. (in_function_p): Remove definition. @@ -3541,7 +3590,7 @@ Sat Apr 15 16:00:01 2000 Richard Kenner * Makefile.in (GGC_H): New variable. Use it throughout in place of ggc.h. - + * call.c: Don't include obstack.h. Include ggc.h. (obstack_chunk_alloc): Don't define. (obstack_chunk_free): Likewise. @@ -3655,7 +3704,7 @@ Wed Apr 5 15:12:18 MET DST 2000 Jan Hubicka (__vmi_class_type_info::do_find_public_src): Use it. (__vmi_class_type_info::do_dyncast): Likewise. (__vmi_class_type_info::do_upcast): Likewise. - + 2000-04-03 Zack Weinberg * lang-specs.h: Pass -fno-show-column to the preprocessor. @@ -3758,7 +3807,7 @@ Wed Apr 5 15:12:18 MET DST 2000 Jan Hubicka * tree.c (debug_binfo): Likewise. * tinfo.cc (__dynamic_cast): Look for vtable_prefix at appropriate negative offset. - + Sun Mar 26 20:15:26 2000 Richard Kenner * class.c (check_field_decl): Fix typo. @@ -3775,7 +3824,7 @@ Sun Mar 26 20:15:26 2000 Richard Kenner (resolve_overloaded_unification, more_specialized): Likewise. * semantics.c (finish_member_declaration): Likewise. * typeck.c (build_x_function_call): Likewise. - + 2000-03-26 Mark Mitchell * class.c (layout_empty_base): Handle empty bases with non-byte @@ -3784,7 +3833,7 @@ Sun Mar 26 20:15:26 2000 Richard Kenner (layout_virtual_bases): Likewise. * class.c (finish_struct_1): Fix typo in this change: - + Sat Mar 25 09:12:10 2000 Richard Kenner 2000-03-25 Mark Mitchell @@ -3793,7 +3842,7 @@ Sun Mar 26 20:15:26 2000 Richard Kenner keeping track of how many template classes have been seen. * dump.c (dequeue_and_dump): Dump DECL_TEMPLATE_RESULT. - + Sat Mar 25 09:12:10 2000 Richard Kenner * class.c (build_vbase_pointer_fields): layout_field now place_field. @@ -3815,11 +3864,11 @@ Sat Mar 25 09:12:10 2000 Richard Kenner * rtti.c (expand_class_desc): Use bitsize_one_node. * typeck.c (build_component_addr): Use byte_position and don't special case for zero offset. - + 2000-03-24 Nathan Sidwell * decl.c (vtype_decl_p): Use TYPE_POLYMORPHIC_P. - + * rtti.c (get_tinfo_decl): Set comdat linkage on new-abi tinfo object. (emit_tinfo_decl): Only emit polymorphic tinfo's when emitting @@ -3854,7 +3903,7 @@ Sat Mar 25 09:12:10 2000 Richard Kenner * search.c (lookup_field_1): Likewise. * tree.c (walk_tree, get_type_decl, cp_tree_equal, member_p): Likewise. * xref.c (classname): Likewise. - + 2000-03-22 Mark Mitchell * cp-tree.h (BINFO_FOR_VBASE): Adjust documentation. @@ -3883,7 +3932,7 @@ Sat Mar 25 09:12:10 2000 Richard Kenner (dfs_find_vbases): Adjust usage of BINFO_NEW_VTABLE_MARKED. (dfs_clear_vbase_slots): Likewise. (init_vbase_pointers): LIkewise. - + 2000-03-22 Jason Merrill * typeck.c (type_after_usual_arithmetic_conversions): Prefer a @@ -3893,7 +3942,7 @@ Sat Mar 25 09:12:10 2000 Richard Kenner * class.c (layout_virtual_bases): Adjust names in conditionally compiled code. - + * class.c (record_base_offsets): New function. (layout_conflict_p): Likewise. (layout_nonempty_base_or_field): Use it. @@ -3909,7 +3958,7 @@ Sat Mar 25 09:12:10 2000 Richard Kenner * cp-tree.h (CLASSTYPE_VBASECLASSES): Fix typo in comment. (fntype_p): Remove. * search.c (dfs_skip_nonprimary_vbases_unmarkedp): Fix typo in - comment. + comment. (dfs_skip_nonprimary_vbases_markedp): Likewise. * typeck.c (fntype_p): Remove. @@ -3995,7 +4044,7 @@ Sat Mar 25 09:12:10 2000 Richard Kenner * init.c (build_offset_ref): Handle the case of a templated member function. - + 2000-03-19 Martin v. Löwis * except.c (expand_exception_blocks): Clear catch_clauses_last. @@ -4016,7 +4065,7 @@ Sat Mar 25 09:12:10 2000 Richard Kenner when dereferencing them under the new ABI. * typeck.c (get_member_function_from_ptrfunc): Tweak calculation of pointers-to-members under the new ABI. - + * class.c (check_bitfield_decl): Remove restriction on really long bitfields. (layout_class_type): Implement new ABI handling of bitfields @@ -4057,7 +4106,7 @@ Fri Mar 17 08:09:14 2000 Richard Kenner host_integerp, and tree_low_cst. (pointer_int_sum): Use integer_zerop. (build_component_addr): Use bit_position. - + 2000-03-17 Nathan Sidwell * typeck.c (require_complete_type): Don't assume size_zero_node. @@ -4092,7 +4141,7 @@ Fri Mar 17 08:09:14 2000 Richard Kenner 2000-03-15 Nathan Sidwell * decl.c (cp_finish_decl): Remove obsolete comment. - + * typeck.c (build_ptrmemfunc1): Kill uninitialized warning. 2000-03-14 Mark Mitchell @@ -4176,7 +4225,7 @@ Fri Mar 17 08:09:14 2000 Richard Kenner (tsubst_decl): Fix typo in code contained in comment. (instantiate_template): Handle member template specializations. (most_general_template): Likewise. - + 2000-03-11 Gabriel Dos Reis * lex.c (whitespace_cr): Compress consecutive calls to warning(). @@ -4222,8 +4271,8 @@ Fri Mar 17 08:09:14 2000 Richard Kenner (nothrow_libfn_p): New fn. * decl.c (grokfndecl): Use it. * cp-tree.h: Declare it. - - * decl.c (push_overloaded_decl_1, auto_function, + + * decl.c (push_overloaded_decl_1, auto_function, define_function): Lose. (build_library_fn_1): New static fn. (builtin_function): Use it. @@ -4237,7 +4286,7 @@ Fri Mar 17 08:09:14 2000 Richard Kenner * except.c (init_exception_processing, call_eh_info, do_pop_exception, (expand_end_eh_spec, alloc_eh_object, expand_throw): Use above fns. * rtti.c (build_runtime_decl): Lose. - (throw_bad_cast, throw_bad_typeid, get_tinfo_decl, + (throw_bad_cast, throw_bad_typeid, get_tinfo_decl, build_dynamic_cast_1, expand_si_desc, expand_class_desc, expand_ptr_desc, expand_attr_desc, expand_generic_desc): Use above fns. @@ -4287,7 +4336,7 @@ Fri Mar 17 08:09:14 2000 Richard Kenner * typeck.c (convert_for_assignment): Don't look at array initializer. - * call.c (convert_like_real): Likewise. + * call.c (convert_like_real): Likewise. 2000-03-07 Jason Merrill @@ -4298,7 +4347,7 @@ Fri Mar 17 08:09:14 2000 Richard Kenner (utf8_extend_token): New fn, #if 0'd out. (real_yylex): Treat extended chars like letters. - * search.c (note_debug_info_needed): Walk the bases even if we + * search.c (note_debug_info_needed): Walk the bases even if we weren't deferring the type itself. 2000-03-07 Kaveh R. Ghazi @@ -4339,7 +4388,7 @@ Mon Mar 6 08:46:47 2000 Richard Kenner * pt.c (instantiate_decl): Clear TI_PENDING_TEMPLATE_FLAG a little later. - + * dump.c (dequeue_and_dump): Dump SCOPE_NO_CLEANUPS_P. 2000-03-05 Nathan Sidwell @@ -4347,7 +4396,7 @@ Mon Mar 6 08:46:47 2000 Richard Kenner * call.c (convert_like): Macrofy. (convert_like_with_context): New macro. (convert_like_real): Renamed from convert_like. Add calling - context parameters, for diagnostics. Add recursive flag. Call + context parameters, for diagnostics. Add recursive flag. Call dubious_conversion_warnings for outer conversion. (build_user_type_conversion): Use convert_like_with_context. (build_over_call): Likewise. Don't warn about dubious @@ -4358,7 +4407,7 @@ Mon Mar 6 08:46:47 2000 Richard Kenner (dubious_conversion_warnings): Prototype new function. * typeck.c (convert_arguments): Adjust convert_default_arg call. (dubious_conversion_warnings): New function, broken - out of convert_for_assignment. + out of convert_for_assignment. (convert_for_assignment): Adjust. 2000-03-03 Jason Merrill @@ -4369,7 +4418,7 @@ Mon Mar 6 08:46:47 2000 Richard Kenner * decl.c (finish_function): Don't mess with flag_keep_inline_functions. * decl2.c (finish_vtable_vardecl): Don't check decl_function_context. - * search.c (note_debug_info_needed, dfs_debug_mark, + * search.c (note_debug_info_needed, dfs_debug_mark, dfs_debug_unmarkedp): Uncomment. Adjust for new scheme. * decl2.c (finish_vtable_vardecl): Call note_debug_info_needed. @@ -4435,10 +4484,10 @@ Mon Mar 6 08:46:47 2000 Richard Kenner (build_cplus_array_test_1): Likewise. (cp_build_qualified_type_real): Likewise. * typeck.c (complete_type): Likewise. - + * g++spec.c (lang_specific_driver): Add -fnew-abi at the start of the command-line, not the end. - + 2000-03-01 Jason Merrill * pt.c (instantiate_decl): Clear TI_PENDING_TEMPLATE_FLAG. @@ -4552,19 +4601,19 @@ Sun Feb 27 16:40:33 2000 Richard Kenner * call.c (add_function_candidate): Add ctype parm; if non-zero, override the type of 'this' accordingly. (add_template_candidate, add_template_candidate_real): Add ctype parm. - (convert_class_to_reference, build_user_type_conversion_1, + (convert_class_to_reference, build_user_type_conversion_1, build_new_function_call, build_object_call, build_new_op, build_new_method_call): Pass ctype parm. * search.c (lookup_member): Put rval_binfo, not basetype_path, in the baselink. - * call.c (convert_class_to_reference, build_user_type_conversion_1, + * call.c (convert_class_to_reference, build_user_type_conversion_1, build_new_function_call, build_object_call, build_new_op, build_new_method_call, build_op_delete_call): Don't get basetype_path from a baselink. * typeck.c (build_component_ref): Likewise. * init.c (build_offset_ref): Likewise. - (resolve_offset_ref): Don't call enforce_access. + (resolve_offset_ref): Don't call enforce_access. Call build_scoped_ref. * typeck2.c (build_scoped_ref): Simplify. Do nothing if it would cause an error or if -pedantic. @@ -4590,7 +4639,7 @@ Sun Feb 27 16:40:33 2000 Richard Kenner EXPR_WITH_FILE_LOCATION. * lex.c (check_newline): Tweak filename/lineno setting. * semantics.c (begin_while_stmt): Fix typo in comment. - + Sat Feb 26 19:50:23 2000 Richard Kenner * lang-options.h (-fmessage-length=): Add missing option. @@ -4616,7 +4665,7 @@ Fri Feb 25 14:52:33 2000 Jim Wilson * parse.c: Regenerated. * Makefile.in (lex.o): Depend on input.h. (optimize.o): Likewise. - + 2000-02-24 Nathan Sidwell * decl.c (grokdeclarator): Diagnose qualifiers on non-member @@ -4639,7 +4688,7 @@ Fri Feb 25 14:52:33 2000 Jim Wilson (parse_float, real_yylex): Likewise. * parse.y (paren_expr_or_null, paren_cond_or_null): Likewise. (unary_expr, new_initializer, cast_expr, primary, primary_no_id, - new_type_id, maybe_label_decls, simple_stmt, + new_type_id, maybe_label_decls, simple_stmt, for.init.statement): Likewise. * pt.c (do_decl_instantiation, do_type_instantiation): Likewise. * semantics.c (finish_named_return_value): Likewise. @@ -4675,7 +4724,7 @@ Fri Feb 25 14:52:33 2000 Jim Wilson (expand_ptrmemfunc_cst): Likewise. (delta2_from_ptrmemfunc): Assert that we're not using the new ABI. (pfn_from_ptrmemfunc): Adjust for the new ABI. - + 2000-02-21 Gabriel Dos Reis * call.c (build_object_call): Compress consecutive calls to @@ -4684,7 +4733,7 @@ Fri Feb 25 14:52:33 2000 Jim Wilson (build_op_delete_call): Adjust message formatting. * class.c (check_bases): Compress consecutive calls to - cp_pedwarn. + cp_pedwarn. (finish_struct_anon): Say 'ISO C++'. * decl.c (start_decl): Same here. @@ -4694,7 +4743,7 @@ Fri Feb 25 14:52:33 2000 Jim Wilson (check_static_variable_definition): Likewise. Say 'ISO C++' (compute_array_index_type): Say 'ISO C++' (create_array_type_for_decl): Compress consecutive calls to - cp_error. + cp_error. (grokdeclarator): Say 'ISO C++' (grok_op_properties): Likewise. @@ -4705,7 +4754,7 @@ Fri Feb 25 14:52:33 2000 Jim Wilson * expr.c (do_case): Say 'ISO C++' * friend.c (do_friend): Compress consecutive calls to warning. - + 2000-02-20 Mark Mitchell * cp-tree.h (merge_primary_and_secondary_vtables_p): New macro. @@ -4729,12 +4778,12 @@ Fri Feb 25 14:52:33 2000 Jim Wilson (build_secondary_vtable): ... here. * pt.c (tsubst_decl): Fix formatting. - + Sat Feb 19 18:43:13 2000 Richard Kenner * class.c (build_primary_vtable, layout_vtable_decl): Likewise. (avoid_overlap, build_base_field): Likewise. - (build_base_field, build_base_fields, is_empty_class): + (build_base_field, build_base_fields, is_empty_class): Test DECL_SIZE with integer_zero. (layout_class_type): Set CLASSTYPE_SIZE_UNIT. * cp-tree.h (struct lang_type): New field size_unit. @@ -4754,12 +4803,12 @@ Sat Feb 19 18:43:13 2000 Richard Kenner functions. (build_vtbl_initializer): Adjust accordingly. (get_vtable_decl): Fix formatting. - + 2000-02-18 Jason Merrill * semantics.c (deferred_type_access_control): Walk the entire type_lookups list. - (save_type_access_control): Rename from + (save_type_access_control): Rename from initial_deferred_type_access_control. Just remember the value. (decl_type_access_control): New fn. (begin_function_definition): Use deferred_type_access_control, after @@ -4773,7 +4822,7 @@ Sat Feb 19 18:43:13 2000 Richard Kenner (notype_component_declarator): Likewise. * cp-tree.h: Adjust. - * decl.c (redeclaration_error_message): Allow redeclaration of + * decl.c (redeclaration_error_message): Allow redeclaration of namespace-scope decls. 2000-02-18 Martin von Loewis @@ -4867,7 +4916,7 @@ Sat Feb 19 18:43:13 2000 Richard Kenner (is_member_template): Use decl_function_context, not hack_decl_function_context. Use DECL_CONTEXT, not DECL_CLASS_CONTEXT. - (build_template_decl): Set DECL_VIRTUAL_CONTEXT, not + (build_template_decl): Set DECL_VIRTUAL_CONTEXT, not DECL_CLASS_CONTEXT. (check_default_tmpl_args): Use CP_DECL_CONTEXT, not DECL_REAL_CONTEXT. @@ -4895,7 +4944,7 @@ Sat Feb 19 18:43:13 2000 Richard Kenner * typeck.c (build_x_function_call): Use DECL_CONTEXT, not DECL_CLASS_CONTEXT. * typeck2.c (error_not_base_type): Likewise. - + 2000-02-15 Jason Merrill * decl.c (xref_tag): Don't SET_IDENTIFIER_NAMESPACE_VALUE. @@ -4964,7 +5013,7 @@ Sat Feb 19 18:43:13 2000 Richard Kenner (struct saved_scope): Add lookups field. (type_lookups): New macro. * parse.y (declmods): Now . - (parse_decl): Add lookups parm. Call + (parse_decl): Add lookups parm. Call initial_deferred_type_access_control. (lang_extdef): Clear type_lookups. (typed_declspecs, declmods, typespec): Set lookups field. @@ -5046,9 +5095,9 @@ Mon Jan 31 15:35:29 2000 Jim Wilson unreal chilren of virtual bases. (finish_struct_1): Don't use merge_overrides. Don't use dfs_fixup_vtable_deltas. - * tree.c (reverse_path): Return a TREE_LIST, not a chain of + * tree.c (reverse_path): Return a TREE_LIST, not a chain of BINFOs. - + 2000-01-31 Herman A.J. ten Brugge Jason Merrill @@ -5073,13 +5122,13 @@ Mon Jan 31 15:35:29 2000 Jim Wilson (type_info::is_pointer_p, type_info::is_function_p): Declare new virtual functions. (type_info::do_catch, type_info::do_upcast): Likewise. - + * tinfo.h (__base_class_info): Define new class. (__class_type_info): Likewise. (__si_class_type_info): Likewise. (__vmi_class_type_info): Likewise. (__dynamic_cast): Prototype. - + * tinfo.cc: Conditionalize old and new rtti mechanisms. (type_info::is_pointer_p): Define new function. (type_info::is_function_p): Likewise. @@ -5107,7 +5156,7 @@ Mon Jan 31 15:35:29 2000 Jim Wilson (__si_class_type_info::do_upcast): Likewise. (__vmi_class_type_info::do_upcast): Likewise. (__dynamic_cast): Likewise. - + * tinfo2.cc (__fundamental_type_info): Define new class. (__pointer_type_info): Likewise. (__reference_type_info): Likewise. @@ -5124,7 +5173,7 @@ Mon Jan 31 15:35:29 2000 Jim Wilson (__ptr_to_member_type_info::~__ptr_to_member_type_info): Likewise. (__pointer_type_info::do_catch): Define new function. (__ptr_to_member_type_info::do_catch): Define new function. - + (__throw_type_match_rtti_2): Use new ABI interface, if enabled. (__is_pointer): Likewise. @@ -5141,7 +5190,7 @@ Mon Jan 31 15:35:29 2000 Jim Wilson (override_one_vtable): Use build_secondary_vtable. (finish_struct_1): Use build_primary_vtable and build_secondary_vtable. - + 2000-01-28 Ulrich Drepper * cp/decl.c: Adjust variable names, comments, help strings. @@ -5177,9 +5226,9 @@ Mon Jan 31 15:35:29 2000 Jim Wilson and BF_FN. (modify_one_vtable): Simplify. (dfs_fixup_vtable_deltas): Likewise. - (override_one_vtable): Use BF_DELTA, BF_VCALL_INDEX, BF_FN. + (override_one_vtable): Use BF_DELTA, BF_VCALL_INDEX, BF_FN. * method.c (make_thunk): Handle vcall indices. - + 2000-01-28 Nathan Sidwell Compiler side new abi rtti (not enabled). @@ -5283,7 +5332,7 @@ Wed Jan 26 22:19:14 2000 J"orn Rennecke (dfs_finish_vtabls): Use layout_vtable_decl. (modify_one_vtables): Always duplicate vtables under the new ABI. (finish_struct_1): Use layout_vtable_decl. - + 2000-01-25 Kaveh R. Ghazi * decl.c (member_function_or_else): Change third arg from a format @@ -5294,7 +5343,7 @@ Wed Jan 26 22:19:14 2000 J"orn Rennecke * typeck.c (composite_pointer_type, c_sizeof, expr_sizeof, build_binary_op_nodefault, build_unary_op, build_reinterpret_cast, build_const_cast, get_delta_difference, check_return_expr): Avoid - ANSI string concatenation usage. + ANSI string concatenation usage. 2000-01-24 Mark Mitchell @@ -5414,7 +5463,7 @@ Wed Jan 26 22:19:14 2000 J"orn Rennecke * typeck.c (convert_arguments): Restore two-message error reporting. - + 2000-01-20 Nathan Sidwell Remap dynamic cast hint values to be consistent across ABIs. @@ -5425,7 +5474,7 @@ Wed Jan 26 22:19:14 2000 J"orn Rennecke * tinfo.cc (__si_type_info::do_dyncast): Remap BOFF meaning. (__class_type_info::do_dyncast): Likewise. (__class_type_info::do_find_public_subobj): Likewise. - * tinfo2.cc (__dynamic_cast): Remap BOFF parameter. + * tinfo2.cc (__dynamic_cast): Remap BOFF parameter. 2000-01-19 Gabriel Dos Reis @@ -5433,16 +5482,16 @@ Wed Jan 26 22:19:14 2000 J"orn Rennecke * typeck2.c (incomplete_type_error): Restore previous cp_error and cp_error_at call sequence. - + 2000-01-20 Brad Lucier * class.c (dump_class_hierarchy): Make format agree with argument; cast pointer to unsigned long and print with %lx. - + 2000-01-19 Gabriel Dos Reis * decl2.c (lang_decode_option): Set default line-wrap length to 72. - + * typeck.c (composite_pointer_type, common_type, comp_target_parms, c_sizeof, expr_sizeof, build_array_ref, build_function_call_real, convert_arguments, @@ -5450,7 +5499,7 @@ Wed Jan 26 22:19:14 2000 J"orn Rennecke build_unary_op, mark_addressable, build_compound_expr, build_static_cast, build_reinterpret_cast, build_const_cast, build_c_cast, build_modify_expr, get_delta_difference, - build_ptrmemfunc, check_return_expr): Replace 'ANSI C++' with + build_ptrmemfunc, check_return_expr): Replace 'ANSI C++' with 'ISO C++'. Fusion consecutive calls to diagnotic message routines into a single one. * typeck2.c (readonly_error, abstract_virtuals_error, @@ -5509,7 +5558,7 @@ Wed Jan 26 22:19:14 2000 J"orn Rennecke (finish_struct_1): Adjust call to modify_all_vtables. Add overridden functions from non-primary bases to the vtable. * tree.c (build_shared_int_cst): New function. - + * cp-tree.h (scratchalloc): Remove. (build_scratch_list): Likewise. * call.c (convert_class_to_reference): Replace build_scratch_list @@ -5543,7 +5592,7 @@ Wed Jan 26 22:19:14 2000 J"orn Rennecke * typeck.c (build_x_compound_expr): Likewise. (build_static_cast): Likewise. (build_modify_expr): Likewise. - + * cp-tree.h (DECL_VINDEX): Add documentation. * class.c (build_vtable_entry): Likewise. (start_vtable): Add comment. @@ -5556,7 +5605,7 @@ Wed Jan 26 22:19:14 2000 J"orn Rennecke (create_vtbl_ptr): Likewise. (layout_class_type): Likewise. (finish_struct_1): Likewise. Add comments. - + 2000-01-16 Mark Mitchell * class.c (finish_struct_1): Replace redundant code with @@ -5577,7 +5626,7 @@ Wed Jan 26 22:19:14 2000 J"orn Rennecke (build_vbase_offset_vtbl_entries): Simplify. (build_vbase_offset_vtbl_entries): Adjust. (build_vbase_pointer): Add ability to look up vbase offsets in - vtable. + vtable. (start_vtable): New function. (add_virtual_function): Use it. (determine_primary_base): Use TYPE_CONTAINS_VPTR_P. @@ -5606,14 +5655,14 @@ Wed Jan 26 22:19:14 2000 J"orn Rennecke * search.c (dfs_walk_real): Make it global. (dfs_debug_mark): Use TYPE_CONTAINS_VPTR_P. * tree.c (make_binfo): Don't clear BINFO_VPTR_FIELD. - + * tinfo.h (USItype): Make it signed under the new ABI. * tinfo.cc (convert_to_base): New function. Encapsulate base conversion logic here. (__class_type_info::do_upcast): Use it. (__class_type_info::do_dyncast): Likewise. (__class_type_info::do_find_public_subobj): Likewise. - + * init.c (construct_virtual_bases): Don't look up the addresses of virtual bases at run-time. @@ -5653,7 +5702,7 @@ Wed Jan 26 22:19:14 2000 J"orn Rennecke (dfs_vtable_path_unmarked_real_bases_queue_p): New function. (dfs_vtable_path_marked_real_bases_queue_p): New function. (dfs_vtable_path_unmark): Likewise. - + 2000-01-14 Mark Mitchell * optimize.c (copy_body_r): Clear the operand three of a @@ -5669,7 +5718,7 @@ Wed Jan 26 22:19:14 2000 J"orn Rennecke * pt.c (tsubst_friend_function): Improve comment. (instantiate_decl): Avoid crashing when a "nested" function is instantiated from the top level. - + * dump.c (dqeueue_and_dump): Dump DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION. @@ -5705,7 +5754,7 @@ Wed Jan 26 22:19:14 2000 J"orn Rennecke * parse.c: Regenerated. * pt.c (finish_member_template_decl): Likewise. * typeck.c (decay_conversion): Likewise. - + * cp-tree.h (dfs_skip_vbases): New function. (find_vbase_instance): Likewise. * class.c (determine_primary_base): Allow a nearly empty base to @@ -5732,16 +5781,16 @@ Wed Jan 26 22:19:14 2000 J"orn Rennecke (fixup_all_virtual_upcast_offsets): Likewise. (dfs_find_vbase_instances): New function. (find_vbase_instance): Likewise. - + 2000-01-11 Mumit Khan * lex.c (DIR_SEPARATOR): Delete macro. 2000-01-12 Gabriel Dos Reis - + * decl2.c (lang_decode_option): Handle automatic line wrapping option. - + 2000-01-11 Mark Mitchell * friend.c (do_friend): Don't resolve scopes when processing @@ -5766,7 +5815,7 @@ Wed Jan 26 22:19:14 2000 J"orn Rennecke (layout_basetypes): Don't call propagate_binfo_offsets. * search.c (dfs_get_vbase_types): Clone completely fresh binfos for the vbases. - + * class.c (build_base_field): New function, split out from ... (build_base_fields): ... here. Use it. Allocate primary bases first, under the new ABI. @@ -5774,7 +5823,7 @@ Wed Jan 26 22:19:14 2000 J"orn Rennecke (remove_base_field): New function, split out from ... (remove_base_fields): ... here. Adjust since primary bases come first under the new ABI. - + * cp-tree.h (expand_direct_vtbls_init): Remove declaration. (initialize_vtbl_ptrs): New function. (expand_indirect_vtbls_init): Change prototype. @@ -5786,11 +5835,11 @@ Wed Jan 26 22:19:14 2000 J"orn Rennecke * search.c (convert_pointer_to_vbase): Make it global. (expand_indirect_vtbls_init): Remove vtable initialization code. * semantics.c (setup_vtbl_ptr): Use initialize_vtbl_ptrs. - + * class.c (dfs_finish_vtbls): New function. (finish_vtbls): Use it. (dump_class_hierarchy): New function. - + * cp-tree.h (BINFO_PRIMARY_MARKED_P): Change definition. (BINFO_VBASE_PRIMARY_P): New macro. (BINFO_VIRTUALS): Add to documentation. @@ -5806,7 +5855,7 @@ Wed Jan 26 22:19:14 2000 J"orn Rennecke (dfs_marked_real_bases_queue_p): Likewise. (dfs_get_pure_virtuals): Simplify. (get_pure_virtuals): Likewise. - + 2000-01-10 Kaveh R. Ghazi * lex.c: Include tm_p.h. @@ -5820,7 +5869,7 @@ Wed Jan 26 22:19:14 2000 J"orn Rennecke * decl2.c (comdat_linkage): Don't set DECL_DEFER_OUTPUT. * pt.c (instantiate_decl): Defer comdat templates that might not be needed. - + * cp-tree.h (DECL_NEEDED_P): Also true if !DECL_COMDAT. * decl2.c (finish_vtable_vardecl): Don't check !DECL_COMDAT. (finish_file): Likewise. @@ -5859,7 +5908,7 @@ Wed Jan 26 22:19:14 2000 J"orn Rennecke or unshare_base_binfos for virtual bases here. * search.c (dfs_get_vbase_types): Do it here. (get_vbase_types): Adjust. - + 2000-01-02 Mark Mitchell * cp-tree.h (CLASSTYPE_VFIELDS): Move definition. @@ -5873,7 +5922,7 @@ Wed Jan 26 22:19:14 2000 J"orn Rennecke are no base classes. Call mark_primary_bases here. (modify_all_direct_vtables): Remove. (modify_all_indirect_vtables): Remove. - (dfs_modify_vtables_queue_p): New function. + (dfs_modify_vtables_queue_p): New function. (dfs_modify_vtables): New function. (modify_all_vtables): Use them. (build_base_fields): Build FIELD_DECLs for primary virtual base @@ -5920,7 +5969,7 @@ Wed Jan 26 22:19:14 2000 J"orn Rennecke * tree.c (CEIL): Remove. (propagate_binfo_offsets): Remove. (layout_basetypes): Remove. - + 2000-01-01 Mark Mitchell * cp-tree.h (CLASSTYPE_N_BASECLASSES): Use BINFO_N_BASETYPES. @@ -5935,7 +5984,7 @@ Wed Jan 26 22:19:14 2000 J"orn Rennecke (dfs_unmark_primary_bases): Likewise. (unmark_primary_bases): Likewise. (dfs_get_pure_virtuals): Likewise. - + 2000-01-01 Mark Mitchell * cp-tree.h (skip_rtti_stuff): Adjust prototype. @@ -5947,7 +5996,7 @@ Wed Jan 26 22:19:14 2000 J"orn Rennecke (get_pure_virtuals): Likewise. (expand_upcast_fixups): Likewise. * tree.c (debug_binfo): Likewise. - + * class.c (build_vtable): Don't return a value. Don't rebuild vtables for bases that have already been handled. (prepare_fresh_vtable): Don't rebuild vtables for bases that have diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in index 662ab32..5b08fd3 100644 --- a/gcc/cp/Make-lang.in +++ b/gcc/cp/Make-lang.in @@ -115,7 +115,7 @@ CXX_SRCS = $(srcdir)/cp/call.c $(srcdir)/cp/class.c $(srcdir)/cp/cp-tree.def \ $(srcdir)/cp/decl.h $(srcdir)/cp/decl2.c $(srcdir)/cp/dump.c \ $(srcdir)/cp/errfn.c $(srcdir)/cp/error.c $(srcdir)/cp/except.c \ $(srcdir)/cp/expr.c $(srcdir)/cp/friend.c $(srcdir)/cp/init.c \ - $(srcdir)/cp/input.c $(srcdir)/cp/lex.c $(srcdir)/cp/lex.h \ + $(srcdir)/cp/lex.c $(srcdir)/cp/lex.h \ $(srcdir)/cp/mangle.c $(srcdir)/cp/method.c $(srcdir)/cp/optimize.c \ $(srcdir)/cp/parse.y $(srcdir)/cp/pt.c $(srcdir)/cp/ptree.c \ $(srcdir)/cp/repo.c $(srcdir)/cp/rtti.c $(srcdir)/cp/search.c \ @@ -123,8 +123,8 @@ CXX_SRCS = $(srcdir)/cp/call.c $(srcdir)/cp/class.c $(srcdir)/cp/cp-tree.def \ $(srcdir)/cp/typeck.c $(srcdir)/cp/typeck2.c $(srcdir)/cp/xref.c cc1plus$(exeext): $(P) $(CXX_SRCS) $(LIBDEPS) $(BACKEND) c-common.o \ - c-pragma.o c-semantics.o $(srcdir)/cp/cp-tree.h $(srcdir)/cp/cp-tree.def \ - $(srcdir)/c-common.def $(srcdir)/cp/gxx.gperf $(srcdir)/cp/cfns.gperf hash.o \ + c-pragma.o c-semantics.o c-lex.o $(srcdir)/cp/cp-tree.h $(srcdir)/cp/cp-tree.def \ + $(srcdir)/c-common.def $(srcdir)/cp/cfns.gperf hash.o \ $(srcdir)/cp/operators.def cd cp; $(MAKE) $(LANG_FLAGS_TO_PASS) $(CXX_FLAGS_TO_PASS) ../cc1plus$(exeext) # diff --git a/gcc/cp/Makefile.in b/gcc/cp/Makefile.in index 025ae06..e73f6ad 100644 --- a/gcc/cp/Makefile.in +++ b/gcc/cp/Makefile.in @@ -172,7 +172,7 @@ INCLUDES = -I. -I.. -I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../config -I$(srcdir) # Lists of files for various purposes. # Shared with C front end: -C_OBJS = ../c-common.o ../c-pragma.o ../c-semantics.o +C_OBJS = ../c-common.o ../c-pragma.o ../c-semantics.o ../c-lex.o # Language-specific object files for g++ @@ -237,16 +237,6 @@ $(PARSE_H) $(PARSE_C) : $(srcdir)/parse.y # cp $(PARSE_C) y.tab.c # touch stamp-parse -# We used to try to protect people from having to rerun gperf. But, -# the C front-end already requires this if c-parse.gperf is changed, -# so we should be consistent. -$(srcdir)/hash.h: $(srcdir)/gxx.gperf - gperf -L C -F ', 0, 0' -p -j1 -g -o -t -N is_reserved_word \ - '-k1,4,7,$$' $(srcdir)/gxx.gperf >$(srcdir)/hash.h || ( \ - echo "Please update your 'gperf' from the GCC infrastructure" >&2 ; \ - echo " ftp://sourceware.cygnus.com/pub/egcs/infrastructure/gperf*" >&2 ; \ - exit 1 ) - $(srcdir)/cfns.h: $(srcdir)/cfns.gperf gperf -o -C -E -k '1-6,$$' -j1 -D -N 'libc_name_p' \ $(srcdir)/cfns.gperf > $(srcdir)/cfns.h @@ -254,7 +244,7 @@ $(srcdir)/cfns.h: $(srcdir)/cfns.gperf spew.o : spew.c $(CXX_TREE_H) $(PARSE_H) $(srcdir)/../flags.h \ lex.h $(srcdir)/../toplev.h lex.o : lex.c $(CXX_TREE_H) \ - $(PARSE_H) input.c $(srcdir)/../flags.h hash.h lex.h \ + $(PARSE_H) $(srcdir)/../flags.h lex.h \ $(srcdir)/../c-pragma.h $(srcdir)/../toplev.h \ $(srcdir)/../output.h $(srcdir)/../mbchar.h $(GGC_H) \ $(srcdir)/../input.h $(srcdir)/../diagnostic.h operators.def diff --git a/gcc/cp/class.c b/gcc/cp/class.c index de692db..0306df7 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -153,7 +153,7 @@ static void check_bases PARAMS ((tree, int *, int *, int *)); static void check_bases_and_members PARAMS ((tree, int *)); static tree create_vtable_ptr PARAMS ((tree, int *, int *, tree *, tree *)); static void layout_class_type PARAMS ((tree, int *, int *, tree *, tree *)); -static void fixup_pending_inline PARAMS ((struct pending_inline *)); +static void fixup_pending_inline PARAMS ((tree)); static void fixup_inline_methods PARAMS ((tree)); static void set_primary_base PARAMS ((tree, tree, int *)); static void propagate_binfo_offsets PARAMS ((tree, tree)); @@ -4449,15 +4449,12 @@ create_vtable_ptr (t, empty_p, vfuns_p, complete. */ static void -fixup_pending_inline (info) - struct pending_inline *info; +fixup_pending_inline (fn) + tree fn; { - if (info) + if (DECL_PENDING_INLINE_INFO (fn)) { - tree args; - tree fn = info->fndecl; - - args = DECL_ARGUMENTS (fn); + tree args = DECL_ARGUMENTS (fn); while (args) { DECL_CONTEXT (args) = fn; @@ -4487,13 +4484,13 @@ fixup_inline_methods (type) /* Do inline member functions. */ for (; method; method = TREE_CHAIN (method)) - fixup_pending_inline (DECL_PENDING_INLINE_INFO (method)); + fixup_pending_inline (method); /* Do friends. */ for (method = CLASSTYPE_INLINE_FRIENDS (type); method; method = TREE_CHAIN (method)) - fixup_pending_inline (DECL_PENDING_INLINE_INFO (TREE_VALUE (method))); + fixup_pending_inline (TREE_VALUE (method)); CLASSTYPE_INLINE_FRIENDS (type) = NULL_TREE; } @@ -5426,6 +5423,10 @@ init_class_processing () access_public_virtual_node = build_int_2 (4 | ak_public, 0); access_protected_virtual_node = build_int_2 (4 | ak_protected, 0); access_private_virtual_node = build_int_2 (4 | ak_private, 0); + + ridpointers[(int) RID_PUBLIC] = access_public_node; + ridpointers[(int) RID_PRIVATE] = access_private_node; + ridpointers[(int) RID_PROTECTED] = access_protected_node; } /* Set current scope to NAME. CODE tells us if this is a diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index f54891c..b32367b 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -32,6 +32,7 @@ Boston, MA 02111-1307, USA. */ /* Usage of TREE_LANG_FLAG_?: 0: BINFO_MARKED (BINFO nodes). + IDENTIFIER_MARKED (IDENTIFIER_NODEs) NEW_EXPR_USE_GLOBAL (in NEW_EXPR). DELETE_EXPR_USE_GLOBAL (in DELETE_EXPR). LOOKUP_EXPR_GLOBAL (in LOOKUP_EXPR). @@ -71,7 +72,7 @@ Boston, MA 02111-1307, USA. */ or FIELD_DECL). NEED_TEMPORARY_P (in REF_BIND, BASE_CONV) IDENTIFIER_TYPENAME_P (in IDENTIFIER_NODE) - 5: Unused. + 5: C_IS_RESERVED_WORD (in IDENTIFIER_NODE) 6: BINFO_ACCESS (in BINFO) Usage of TYPE_LANG_FLAG_?: @@ -282,8 +283,21 @@ struct lang_identifier tree class_value; tree class_template_info; struct lang_id2 *x; + enum rid rid_code; }; +/* In an IDENTIFIER_NODE, nonzero if this identifier is actually a + keyword. C_RID_CODE (node) is then the RID_* value of the keyword, + and C_RID_YYCODE is the token number wanted by Yacc. */ + +#define C_IS_RESERVED_WORD(id) TREE_LANG_FLAG_5 (id) +#define C_RID_CODE(id) \ + (((struct lang_identifier *) (id))->rid_code) + +extern const short rid_to_yy[RID_MAX]; +#define C_RID_YYCODE(id) \ + rid_to_yy[((struct lang_identifier *) (id))->rid_code] + #define LANG_IDENTIFIER_CAST(NODE) \ ((struct lang_identifier*)IDENTIFIER_NODE_CHECK (NODE)) @@ -468,15 +482,6 @@ struct tree_srcloc #define IDENTIFIER_CLASS_VALUE(NODE) \ (LANG_IDENTIFIER_CAST (NODE)->class_value) -/* The amount of time used by the file whose special "time identifier" - is NODE, represented as an INTEGER_CST. See get_time_identifier. */ -#define TIME_IDENTIFIER_TIME(NODE) IDENTIFIER_BINDING(NODE) - -/* For a "time identifier" this is a INTEGER_CST. The - TREE_INT_CST_LOW is 1 if the corresponding file is "interface only". - The TRE_INT_CST_HIGH is 1 if it is "interface unknown". */ -#define TIME_IDENTIFIER_FILEINFO(NODE) IDENTIFIER_CLASS_VALUE (NODE) - /* TREE_TYPE only indicates on local and class scope the current type. For namespace scope, the presence of a type in any namespace is indicated with global_type_node, and the real type behind must @@ -1039,6 +1044,14 @@ extern int flag_cond_mismatch; extern int flag_no_asm; +/* Nonzero means don't recognize any extended keywords. */ + +extern int flag_no_gnu_keywords; + +/* Nonzero means recognize the named operators from C++98. */ + +extern int flag_operator_names; + /* For cross referencing. */ extern int flag_gnu_xref; @@ -1896,6 +1909,8 @@ struct lang_decl_flags } u2; }; +struct unparsed_text; + struct lang_decl { struct lang_decl_flags decl_flags; @@ -1911,7 +1926,7 @@ struct lang_decl union { tree sorted_fields; - struct pending_inline *pending_inline_info; + struct unparsed_text *pending_inline_info; struct language_function *saved_language_function; } u; @@ -1925,8 +1940,6 @@ struct lang_decl } u2; }; -/* An un-parsed default argument looks like an identifier. */ -#define DEFARG_LENGTH(NODE) (DEFAULT_ARG_CHECK(NODE)->identifier.length) #define DEFARG_POINTER(NODE) (DEFAULT_ARG_CHECK(NODE)->identifier.pointer) /* Non-zero if NODE is a _DECL with TREE_READONLY set. */ @@ -3212,10 +3225,6 @@ extern int flag_labels_ok; /* Nonzero means allow Microsoft extensions without a pedwarn. */ extern int flag_ms_extensions; -/* Non-zero means to collect statistics which might be expensive - and to print them when we are done. */ -extern int flag_detailed_statistics; - /* Non-zero means warn in function declared in derived class has the same name as a virtual in the base class, but fails to match the type signature of any virtual function in the base class. */ @@ -3503,25 +3512,6 @@ extern varray_type local_classes; /* Things for handling inline functions. */ -struct pending_inline -{ - struct pending_inline *next; /* pointer to next in chain */ - int lineno; /* line number we got the text from */ - const char *filename; /* name of file we were processing */ - tree fndecl; /* FUNCTION_DECL that brought us here */ - int token; /* token we were scanning */ - int token_value; /* value of token we were scanning (YYSTYPE) */ - - char *buf; /* pointer to character stream */ - int len; /* length of stream */ - unsigned int can_free : 1; /* free this after we're done with it? */ - unsigned int deja_vu : 1; /* set iff we don't want to see it again. */ - unsigned int interface : 2; /* 0=interface 1=unknown 2=implementation */ -}; - -/* in method.c */ -extern struct pending_inline *pending_inlines; - /* Negative values means we know `this' to be of static type. */ extern int flag_this_is_variable; @@ -4148,41 +4138,33 @@ extern void set_quals_and_spec PARAMS ((tree, tree, tree)); extern void lang_init PARAMS ((void)); extern void lang_finish PARAMS ((void)); extern void print_parse_statistics PARAMS ((void)); -extern void extract_interface_info PARAMS ((void)); extern void do_pending_inlines PARAMS ((void)); -extern void process_next_inline PARAMS ((struct pending_inline *)); -extern struct pending_input *save_pending_input PARAMS ((void)); -extern void restore_pending_input PARAMS ((struct pending_input *)); +extern void process_next_inline PARAMS ((struct unparsed_text *)); + extern void yyungetc PARAMS ((int, int)); -extern void reinit_parse_for_method PARAMS ((int, tree)); -extern void reinit_parse_for_block PARAMS ((int, struct obstack *)); +extern void snarf_method PARAMS ((tree)); + extern void check_for_missing_semicolon PARAMS ((tree)); extern void note_got_semicolon PARAMS ((tree)); extern void note_list_got_semicolon PARAMS ((tree)); extern void do_pending_lang_change PARAMS ((void)); -extern int identifier_type PARAMS ((tree)); extern void see_typename PARAMS ((void)); extern tree do_identifier PARAMS ((tree, int, tree)); extern tree do_scoped_id PARAMS ((tree, int)); extern tree identifier_typedecl_value PARAMS ((tree)); -extern int real_yylex PARAMS ((void)); -extern int is_rid PARAMS ((tree)); extern tree build_lang_decl PARAMS ((enum tree_code, tree, tree)); extern void retrofit_lang_decl PARAMS ((tree)); extern tree copy_decl PARAMS ((tree)); extern void copy_lang_decl PARAMS ((tree)); extern tree cp_make_lang_type PARAMS ((enum tree_code)); extern tree make_aggr_type PARAMS ((enum tree_code)); -extern void dump_time_statistics PARAMS ((void)); extern void compiler_error PARAMS ((const char *, ...)) ATTRIBUTE_PRINTF_1; extern void yyerror PARAMS ((const char *)); extern void clear_inline_text_obstack PARAMS ((void)); extern void maybe_snarf_defarg PARAMS ((void)); -extern tree snarf_defarg PARAMS ((void)); extern void add_defarg_fn PARAMS ((tree)); extern void do_pending_defargs PARAMS ((void)); -extern int identifier_type PARAMS ((tree)); extern void yyhook PARAMS ((int)); extern int cp_type_qual_from_rid PARAMS ((tree)); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index b363266..03d8c6a 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -3464,7 +3464,7 @@ duplicate_decls (newdecl, olddecl) DECL_VIRTUAL_CONTEXT (newdecl) = DECL_VIRTUAL_CONTEXT (olddecl); if (DECL_CONTEXT (olddecl)) DECL_CONTEXT (newdecl) = DECL_CONTEXT (olddecl); - if (DECL_PENDING_INLINE_INFO (newdecl) == (struct pending_inline *)0) + if (DECL_PENDING_INLINE_INFO (newdecl) == 0) DECL_PENDING_INLINE_INFO (newdecl) = DECL_PENDING_INLINE_INFO (olddecl); DECL_STATIC_CONSTRUCTOR (newdecl) |= DECL_STATIC_CONSTRUCTOR (olddecl); DECL_STATIC_DESTRUCTOR (newdecl) |= DECL_STATIC_DESTRUCTOR (olddecl); @@ -6148,7 +6148,7 @@ end_only_namespace_names () } /* Push the declarations of builtin types into the namespace. - RID_INDEX, if < CP_RID_MAX is the index of the builtin type + RID_INDEX is the index of the builtin type in the array RID_POINTERS. NAME is the name used when looking up the builtin type. TYPE is the _TYPE node for the builtin type. */ @@ -6161,7 +6161,7 @@ record_builtin_type (rid_index, name, type) tree rname = NULL_TREE, tname = NULL_TREE; tree tdecl = NULL_TREE; - if ((int) rid_index < (int) CP_RID_MAX) + if ((int) rid_index < (int) RID_MAX) rname = ridpointers[(int) rid_index]; if (name) tname = get_identifier (name); @@ -6172,7 +6172,7 @@ record_builtin_type (rid_index, name, type) { tdecl = pushdecl (build_decl (TYPE_DECL, tname, type)); set_identifier_type_value (tname, NULL_TREE); - if ((int) rid_index < (int) CP_RID_MAX) + if ((int) rid_index < (int) RID_MAX) /* Built-in types live in the global namespace. */ SET_IDENTIFIER_GLOBAL_VALUE (tname, tdecl); } @@ -6215,7 +6215,7 @@ record_builtin_java_type (name, size) TYPE_PRECISION (type) = - size; layout_type (type); } - record_builtin_type (CP_RID_MAX, name, type); + record_builtin_type (RID_MAX, name, type); decl = TYPE_NAME (type); /* Suppress generate debug symbol entries for these types, @@ -6371,27 +6371,27 @@ init_decl_processing () record_builtin_type (RID_SIGNED, NULL_PTR, integer_type_node); record_builtin_type (RID_LONG, "long int", long_integer_type_node); record_builtin_type (RID_UNSIGNED, "unsigned int", unsigned_type_node); - record_builtin_type (CP_RID_MAX, "long unsigned int", + record_builtin_type (RID_MAX, "long unsigned int", long_unsigned_type_node); - record_builtin_type (CP_RID_MAX, "unsigned long", long_unsigned_type_node); - record_builtin_type (CP_RID_MAX, "long long int", + record_builtin_type (RID_MAX, "unsigned long", long_unsigned_type_node); + record_builtin_type (RID_MAX, "long long int", long_long_integer_type_node); - record_builtin_type (CP_RID_MAX, "long long unsigned int", + record_builtin_type (RID_MAX, "long long unsigned int", long_long_unsigned_type_node); - record_builtin_type (CP_RID_MAX, "long long unsigned", + record_builtin_type (RID_MAX, "long long unsigned", long_long_unsigned_type_node); record_builtin_type (RID_SHORT, "short int", short_integer_type_node); - record_builtin_type (CP_RID_MAX, "short unsigned int", + record_builtin_type (RID_MAX, "short unsigned int", short_unsigned_type_node); - record_builtin_type (CP_RID_MAX, "unsigned short", + record_builtin_type (RID_MAX, "unsigned short", short_unsigned_type_node); ptrdiff_type_node = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (PTRDIFF_TYPE))); /* Define both `signed char' and `unsigned char'. */ - record_builtin_type (CP_RID_MAX, "signed char", signed_char_type_node); - record_builtin_type (CP_RID_MAX, "unsigned char", unsigned_char_type_node); + record_builtin_type (RID_MAX, "signed char", signed_char_type_node); + record_builtin_type (RID_MAX, "unsigned char", unsigned_char_type_node); /* `unsigned long' is the standard type for sizeof. Note that stddef.h uses `unsigned long', @@ -6454,7 +6454,7 @@ init_decl_processing () signed_size_zero_node = build_int_2 (0, 0); record_builtin_type (RID_FLOAT, NULL_PTR, float_type_node); record_builtin_type (RID_DOUBLE, NULL_PTR, double_type_node); - record_builtin_type (CP_RID_MAX, "long double", long_double_type_node); + record_builtin_type (RID_MAX, "long double", long_double_type_node); pushdecl (build_decl (TYPE_DECL, get_identifier ("complex int"), complex_integer_type_node)); @@ -6481,7 +6481,7 @@ init_decl_processing () TYPE_QUAL_CONST)); empty_except_spec = build_tree_list (NULL_TREE, NULL_TREE); #if 0 - record_builtin_type (CP_RID_MAX, NULL_PTR, string_type_node); + record_builtin_type (RID_MAX, NULL_PTR, string_type_node); #endif /* Make a type to be the domain of a few array types @@ -6596,16 +6596,16 @@ init_decl_processing () vtable_entry_type = build_qualified_type (vtable_entry_type, TYPE_QUAL_CONST); } - record_builtin_type (CP_RID_MAX, VTBL_PTR_TYPE, vtable_entry_type); + record_builtin_type (RID_MAX, VTBL_PTR_TYPE, vtable_entry_type); vtbl_type_node = build_cplus_array_type (vtable_entry_type, NULL_TREE); layout_type (vtbl_type_node); vtbl_type_node = build_qualified_type (vtbl_type_node, TYPE_QUAL_CONST); - record_builtin_type (CP_RID_MAX, NULL_PTR, vtbl_type_node); + record_builtin_type (RID_MAX, NULL_PTR, vtbl_type_node); vtbl_ptr_type_node = build_pointer_type (vtable_entry_type); layout_type (vtbl_ptr_type_node); - record_builtin_type (CP_RID_MAX, NULL_PTR, vtbl_ptr_type_node); + record_builtin_type (RID_MAX, NULL_PTR, vtbl_ptr_type_node); std_node = build_decl (NAMESPACE_DECL, flag_honor_std @@ -9822,7 +9822,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) next = 0; - if (is_rid (dname)) + if (C_IS_RESERVED_WORD (dname)) { cp_error ("declarator-id missing; using reserved word `%D'", dname); diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 085e352..7bbd998 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -368,10 +368,6 @@ int flag_labels_ok; int flag_ms_extensions; -/* Non-zero means to collect statistics which might be expensive - and to print them when we are done. */ -int flag_detailed_statistics; - /* C++ specific flags. */ /* Zero means that `this' is a *const. This gives nice behavior in the 2.0 world. 1 gives 1.2-compatible behavior. 2 gives Spring behavior. @@ -601,6 +597,8 @@ lang_decode_option (argc, argv) if (!strcmp (p, "-ftraditional") || !strcmp (p, "-traditional")) /* ignore */; + else if (!strcmp (p, "-lang-c++")) + /* ignore - cpplib needs to see this */; else if (p[0] == '-' && p[1] == 'f') { /* Some kind of -f option. @@ -922,7 +920,6 @@ void grok_x_components (specs) tree specs; { - struct pending_inline **p; tree t; specs = strip_attrs (specs); @@ -937,13 +934,6 @@ grok_x_components (specs) fixup_anonymous_aggr (t); finish_member_declaration (build_decl (FIELD_DECL, NULL_TREE, t)); - - /* Ignore any inline function definitions in the anonymous union - since an anonymous union may not have function members. */ - p = &pending_inlines; - for (; *p; *p = (*p)->next) - if (DECL_CONTEXT ((*p)->fndecl) != t) - break; } /* Returns a PARM_DECL for a parameter of the indicated TYPE, with the diff --git a/gcc/cp/gxx.gperf b/gcc/cp/gxx.gperf deleted file mode 100644 index fab533d..0000000 --- a/gcc/cp/gxx.gperf +++ /dev/null @@ -1,116 +0,0 @@ -%{ -/* Command-line: gperf -L C -F ', 0, 0' -p -j1 -g -o -t -N is_reserved_word -k1,4,$,7 gplus.gperf */ -%} -struct resword { const char *name; short token; enum rid rid;}; -#ifdef __GNUC__ -__inline -#endif -static unsigned int hash PARAMS ((const char *, unsigned int)); -#ifdef __GNUC__ -__inline -#endif -struct resword *is_reserved_word PARAMS ((const char *, unsigned int)); -%% -__alignof, ALIGNOF, RID_UNUSED -__alignof__, ALIGNOF, RID_UNUSED -__asm, ASM_KEYWORD, RID_UNUSED -__asm__, ASM_KEYWORD, RID_UNUSED -__attribute, ATTRIBUTE, RID_UNUSED -__attribute__, ATTRIBUTE, RID_UNUSED -__builtin_va_arg, VA_ARG, RID_UNUSED -__complex, TYPESPEC, RID_COMPLEX -__complex__, TYPESPEC, RID_COMPLEX -__const, CV_QUALIFIER, RID_CONST -__const__, CV_QUALIFIER, RID_CONST -__extension__, EXTENSION, RID_UNUSED -__imag, IMAGPART, RID_UNUSED -__imag__, IMAGPART, RID_UNUSED -__inline, SCSPEC, RID_INLINE -__inline__, SCSPEC, RID_INLINE -__label__, LABEL, RID_UNUSED -__null, CONSTANT, RID_NULL -__real, REALPART, RID_UNUSED -__real__, REALPART, RID_UNUSED -__restrict, CV_QUALIFIER, RID_RESTRICT -__restrict__, CV_QUALIFIER, RID_RESTRICT -__signed, TYPESPEC, RID_SIGNED -__signed__, TYPESPEC, RID_SIGNED -__typeof, TYPEOF, RID_UNUSED -__typeof__, TYPEOF, RID_UNUSED -__volatile, CV_QUALIFIER, RID_VOLATILE -__volatile__, CV_QUALIFIER, RID_VOLATILE -__wchar_t, TYPESPEC, RID_WCHAR /* Unique to ANSI C++ */, -asm, ASM_KEYWORD, RID_UNUSED, -and, ANDAND, RID_UNUSED, -and_eq, ASSIGN, RID_UNUSED, -auto, SCSPEC, RID_AUTO, -bitand, '&', RID_UNUSED, -bitor, '|', RID_UNUSED, -bool, TYPESPEC, RID_BOOL, -break, BREAK, RID_UNUSED, -case, CASE, RID_UNUSED, -catch, CATCH, RID_UNUSED, -char, TYPESPEC, RID_CHAR, -class, AGGR, RID_CLASS, -compl, '~', RID_UNUSED, -const, CV_QUALIFIER, RID_CONST, -const_cast, CONST_CAST, RID_UNUSED, -continue, CONTINUE, RID_UNUSED, -default, DEFAULT, RID_UNUSED, -delete, DELETE, RID_UNUSED, -do, DO, RID_UNUSED, -double, TYPESPEC, RID_DOUBLE, -dynamic_cast, DYNAMIC_CAST, RID_UNUSED, -else, ELSE, RID_UNUSED, -enum, ENUM, RID_UNUSED, -explicit, SCSPEC, RID_EXPLICIT, -export, SCSPEC, RID_EXPORT, -extern, SCSPEC, RID_EXTERN, -false, CXX_FALSE, RID_UNUSED, -float, TYPESPEC, RID_FLOAT, -for, FOR, RID_UNUSED, -friend, SCSPEC, RID_FRIEND, -goto, GOTO, RID_UNUSED, -if, IF, RID_UNUSED, -inline, SCSPEC, RID_INLINE, -int, TYPESPEC, RID_INT, -long, TYPESPEC, RID_LONG, -mutable, SCSPEC, RID_MUTABLE, -namespace, NAMESPACE, RID_UNUSED, -new, NEW, RID_UNUSED, -not, '!', RID_UNUSED, -not_eq, EQCOMPARE, RID_UNUSED, -operator, OPERATOR, RID_UNUSED, -or, OROR, RID_UNUSED, -or_eq, ASSIGN, RID_UNUSED, -private, VISSPEC, RID_PRIVATE, -protected, VISSPEC, RID_PROTECTED, -public, VISSPEC, RID_PUBLIC, -register, SCSPEC, RID_REGISTER, -reinterpret_cast, REINTERPRET_CAST, RID_UNUSED, -return, RETURN_KEYWORD, RID_UNUSED, -short, TYPESPEC, RID_SHORT, -signed, TYPESPEC, RID_SIGNED, -sizeof, SIZEOF, RID_UNUSED, -static, SCSPEC, RID_STATIC, -static_cast, STATIC_CAST, RID_UNUSED, -struct, AGGR, RID_RECORD, -switch, SWITCH, RID_UNUSED, -template, TEMPLATE, RID_TEMPLATE, -this, THIS, RID_UNUSED, -throw, THROW, RID_UNUSED, -true, CXX_TRUE, RID_UNUSED, -try, TRY, RID_UNUSED, -typedef, SCSPEC, RID_TYPEDEF, -typename, TYPENAME_KEYWORD, RID_UNUSED, -typeid, TYPEID, RID_UNUSED, -typeof, TYPEOF, RID_UNUSED, -union, AGGR, RID_UNION, -unsigned, TYPESPEC, RID_UNSIGNED, -using, USING, RID_UNUSED, -virtual, SCSPEC, RID_VIRTUAL, -void, TYPESPEC, RID_VOID, -volatile, CV_QUALIFIER, RID_VOLATILE, -while, WHILE, RID_UNUSED, -xor, '^', RID_UNUSED, -xor_eq, ASSIGN, RID_UNUSED, diff --git a/gcc/cp/hash.h b/gcc/cp/hash.h deleted file mode 100644 index 8518d5b..0000000 --- a/gcc/cp/hash.h +++ /dev/null @@ -1,257 +0,0 @@ -/* C code produced by gperf version 2.7.1 (19981006 egcs) */ -/* Command-line: gperf -L C -F , 0, 0 -p -j1 -g -o -t -N is_reserved_word -k1,4,7,$ ../../../gcc/cp/gxx.gperf */ -/* Command-line: gperf -L C -F ', 0, 0' -p -j1 -g -o -t -N is_reserved_word -k1,4,$,7 gplus.gperf */ -struct resword { const char *name; short token; enum rid rid;}; -#ifdef __GNUC__ -__inline -#endif -static unsigned int hash PARAMS ((const char *, unsigned int)); -#ifdef __GNUC__ -__inline -#endif -struct resword *is_reserved_word PARAMS ((const char *, unsigned int)); - -#define TOTAL_KEYWORDS 103 -#define MIN_WORD_LENGTH 2 -#define MAX_WORD_LENGTH 16 -#define MIN_HASH_VALUE 4 -#define MAX_HASH_VALUE 274 -/* maximum key range = 271, duplicates = 0 */ - -#ifdef __GNUC__ -__inline -#endif -static unsigned int -hash (str, len) - register const char *str; - register unsigned int len; -{ - static unsigned short asso_values[] = - { - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 0, 275, 97, 1, 19, - 40, 0, 12, 68, 0, 74, 275, 0, 11, 67, - 27, 0, 70, 6, 96, 43, 6, 37, 3, 10, - 8, 104, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275 - }; - register int hval = len; - - switch (hval) - { - default: - case 7: - hval += asso_values[(unsigned char)str[6]]; - case 6: - case 5: - case 4: - hval += asso_values[(unsigned char)str[3]]; - case 3: - case 2: - case 1: - hval += asso_values[(unsigned char)str[0]]; - break; - } - return hval + asso_values[(unsigned char)str[len - 1]]; -} - -#ifdef __GNUC__ -__inline -#endif -struct resword * -is_reserved_word (str, len) - register const char *str; - register unsigned int len; -{ - static struct resword wordlist[] = - { - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"else", ELSE, RID_UNUSED,}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"__real__", REALPART, RID_UNUSED}, - {"", 0, 0}, - {"true", CXX_TRUE, RID_UNUSED,}, - {"or_eq", ASSIGN, RID_UNUSED,}, - {"export", SCSPEC, RID_EXPORT,}, - {"", 0, 0}, {"", 0, 0}, - {"__const__", CV_QUALIFIER, RID_CONST}, - {"__volatile", CV_QUALIFIER, RID_VOLATILE}, - {"__real", REALPART, RID_UNUSED}, - {"__volatile__", CV_QUALIFIER, RID_VOLATILE}, - {"__const", CV_QUALIFIER, RID_CONST}, - {"xor_eq", ASSIGN, RID_UNUSED,}, - {"throw", THROW, RID_UNUSED,}, - {"__complex__", TYPESPEC, RID_COMPLEX}, - {"case", CASE, RID_UNUSED,}, - {"typeof", TYPEOF, RID_UNUSED,}, - {"", 0, 0}, - {"while", WHILE, RID_UNUSED,}, - {"bool", TYPESPEC, RID_BOOL,}, - {"__complex", TYPESPEC, RID_COMPLEX}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"extern", SCSPEC, RID_EXTERN,}, - {"", 0, 0}, {"", 0, 0}, - {"not", '!', RID_UNUSED,}, - {"typedef", SCSPEC, RID_TYPEDEF,}, - {"virtual", SCSPEC, RID_VIRTUAL,}, - {"not_eq", EQCOMPARE, RID_UNUSED,}, - {"new", NEW, RID_UNUSED,}, - {"", 0, 0}, - {"do", DO, RID_UNUSED,}, - {"catch", CATCH, RID_UNUSED,}, - {"", 0, 0}, {"", 0, 0}, - {"delete", DELETE, RID_UNUSED,}, - {"double", TYPESPEC, RID_DOUBLE,}, - {"__extension__", EXTENSION, RID_UNUSED}, - {"__alignof__", ALIGNOF, RID_UNUSED}, - {"__asm__", ASM_KEYWORD, RID_UNUSED}, - {"", 0, 0}, - {"typeid", TYPEID, RID_UNUSED,}, - {"", 0, 0}, - {"__null", CONSTANT, RID_NULL}, - {"switch", SWITCH, RID_UNUSED,}, - {"", 0, 0}, {"", 0, 0}, - {"friend", SCSPEC, RID_FRIEND,}, - {"__alignof", ALIGNOF, RID_UNUSED}, - {"false", CXX_FALSE, RID_UNUSED,}, - {"sizeof", SIZEOF, RID_UNUSED,}, - {"__inline", SCSPEC, RID_INLINE}, - {"", 0, 0}, - {"__inline__", SCSPEC, RID_INLINE}, - {"", 0, 0}, - {"static_cast", STATIC_CAST, RID_UNUSED,}, - {"", 0, 0}, {"", 0, 0}, - {"union", AGGR, RID_UNION,}, - {"continue", CONTINUE, RID_UNUSED,}, - {"", 0, 0}, - {"goto", GOTO, RID_UNUSED,}, - {"const", CV_QUALIFIER, RID_CONST,}, - {"static", SCSPEC, RID_STATIC,}, - {"__imag__", IMAGPART, RID_UNUSED}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"private", VISSPEC, RID_PRIVATE,}, - {"typename", TYPENAME_KEYWORD, RID_UNUSED,}, - {"", 0, 0}, - {"int", TYPESPEC, RID_INT,}, - {"__signed__", TYPESPEC, RID_SIGNED}, - {"", 0, 0}, {"", 0, 0}, - {"void", TYPESPEC, RID_VOID,}, - {"if", IF, RID_UNUSED,}, - {"", 0, 0}, - {"template", TEMPLATE, RID_TEMPLATE,}, - {"__attribute", ATTRIBUTE, RID_UNUSED}, - {"struct", AGGR, RID_RECORD,}, - {"__attribute__", ATTRIBUTE, RID_UNUSED}, - {"", 0, 0}, {"", 0, 0}, - {"this", THIS, RID_UNUSED,}, - {"const_cast", CONST_CAST, RID_UNUSED,}, - {"or", OROR, RID_UNUSED,}, - {"explicit", SCSPEC, RID_EXPLICIT,}, - {"", 0, 0}, - {"auto", SCSPEC, RID_AUTO,}, - {"bitor", '|', RID_UNUSED,}, - {"break", BREAK, RID_UNUSED,}, - {"", 0, 0}, - {"compl", '~', RID_UNUSED,}, - {"public", VISSPEC, RID_PUBLIC,}, - {"xor", '^', RID_UNUSED,}, - {"__restrict__", CV_QUALIFIER, RID_RESTRICT}, - {"and_eq", ASSIGN, RID_UNUSED,}, - {"class", AGGR, RID_CLASS,}, - {"for", FOR, RID_UNUSED,}, - {"__restrict", CV_QUALIFIER, RID_RESTRICT}, - {"try", TRY, RID_UNUSED,}, - {"__typeof__", TYPEOF, RID_UNUSED}, - {"__asm", ASM_KEYWORD, RID_UNUSED}, - {"signed", TYPESPEC, RID_SIGNED,}, - {"__label__", LABEL, RID_UNUSED}, - {"", 0, 0}, - {"volatile", CV_QUALIFIER, RID_VOLATILE,}, - {"float", TYPESPEC, RID_FLOAT,}, - {"", 0, 0}, - {"__signed", TYPESPEC, RID_SIGNED}, - {"", 0, 0}, - {"__typeof", TYPEOF, RID_UNUSED}, - {"", 0, 0}, {"", 0, 0}, - {"__builtin_va_arg", VA_ARG, RID_UNUSED}, - {"", 0, 0}, {"", 0, 0}, - {"__wchar_t", TYPESPEC, RID_WCHAR /* Unique to ANSI C++ */,}, - {"protected", VISSPEC, RID_PROTECTED,}, - {"", 0, 0}, - {"namespace", NAMESPACE, RID_UNUSED,}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"using", USING, RID_UNUSED,}, - {"enum", ENUM, RID_UNUSED,}, - {"", 0, 0}, - {"and", ANDAND, RID_UNUSED,}, - {"__imag", IMAGPART, RID_UNUSED}, - {"", 0, 0}, {"", 0, 0}, - {"bitand", '&', RID_UNUSED,}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"short", TYPESPEC, RID_SHORT,}, - {"long", TYPESPEC, RID_LONG,}, - {"", 0, 0}, {"", 0, 0}, - {"inline", SCSPEC, RID_INLINE,}, - {"", 0, 0}, - {"default", DEFAULT, RID_UNUSED,}, - {"", 0, 0}, {"", 0, 0}, - {"unsigned", TYPESPEC, RID_UNSIGNED,}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"return", RETURN_KEYWORD, RID_UNUSED,}, - {"asm", ASM_KEYWORD, RID_UNUSED,}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"mutable", SCSPEC, RID_MUTABLE,}, - {"", 0, 0}, {"", 0, 0}, - {"dynamic_cast", DYNAMIC_CAST, RID_UNUSED,}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"operator", OPERATOR, RID_UNUSED,}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"char", TYPESPEC, RID_CHAR,}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"reinterpret_cast", REINTERPRET_CAST, RID_UNUSED,}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"register", SCSPEC, RID_REGISTER,} - }; - - if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) - { - register int key = hash (str, len); - - if (key <= MAX_HASH_VALUE && key >= 0) - { - register const char *s = wordlist[key].name; - - if (*str == *s && !strcmp (str + 1, s + 1)) - return &wordlist[key]; - } - } - return 0; -} diff --git a/gcc/cp/input.c b/gcc/cp/input.c deleted file mode 100644 index 431fed7..0000000 --- a/gcc/cp/input.c +++ /dev/null @@ -1,240 +0,0 @@ -/* Input handling for G++. - Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000 - Free Software Foundation, Inc. - Written by Ken Raeburn (raeburn@cygnus.com) while at Watchmaker Computing. - Enhanced by Michael Tiemann (tiemann@cygnus.com) to better support USE_CPPLIB - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* G++ needs to do enough saving and re-parsing of text that it is - necessary to abandon the simple FILE* model and use a mechanism where - we can pre-empt one input stream with another derived from saved text; - we may need to do this arbitrarily often, and cannot depend on having - the GNU library available, so FILE objects just don't cut it. - - This file is written as a separate module, but can be included by - lex.c for very minor efficiency gains (primarily in function - inlining). */ - -#include "system.h" - -#if !USE_CPPLIB -struct putback_buffer { - char *buffer; - int buffer_size; - int index; -}; - -static struct putback_buffer putback = {NULL, 0, -1}; -#endif - -struct input_source { - /* saved string */ - const char *str; - int length; - /* current position, when reading as input */ - int offset; - /* linked list maintenance */ - struct input_source *next; - /* values to restore after reading all of current string */ - struct pending_input *input; -#if !USE_CPPLIB - const char *filename; - int lineno; - struct putback_buffer putback; -#endif -}; - -static struct input_source *input, *free_inputs; - -#if USE_CPPLIB -extern unsigned char *yy_cur, *yy_lim; -extern int yy_get_token (); -#endif - -extern void feed_input PARAMS ((const char *, int, const char *, int)); -extern void put_input PARAMS ((int)); -extern void put_back PARAMS ((int)); -extern int getch PARAMS ((void)); -extern int input_redirected PARAMS ((void)); - -static inline struct input_source * allocate_input PARAMS ((void)); -static inline void free_input PARAMS ((struct input_source *)); -static inline void end_input PARAMS ((void)); - -static inline struct input_source * -allocate_input () -{ - struct input_source *inp; - if (free_inputs) - { - inp = free_inputs; - free_inputs = inp->next; - inp->next = 0; - return inp; - } - inp = (struct input_source *) xmalloc (sizeof (struct input_source)); - inp->next = 0; - return inp; -} - -static inline void -free_input (inp) - struct input_source *inp; -{ - inp->str = 0; - inp->length = 0; - inp->next = free_inputs; - free_inputs = inp; -} - -/* Some of these external functions are declared inline in case this file - is included in lex.c. */ - -inline -void -feed_input (str, len, file, line) - const char *str; - int len; - const char *file; - int line; -{ - struct input_source *inp = allocate_input (); - - /* This shouldn't be necessary. */ - while (len && !str[len-1]) - len--; - -#if USE_CPPLIB - if (yy_lim > yy_cur) - /* If we've started reading the next token, we're hosed. The - token_getch stuff is supposed to prevent this from happening. */ - my_friendly_abort (990710); - cpp_push_buffer (&parse_in, str, len); - CPP_BUFFER (&parse_in)->manual_pop = 1; - CPP_BUFFER (&parse_in)->nominal_fname - = CPP_BUFFER (&parse_in)->fname = file; - CPP_BUFFER (&parse_in)->lineno = parse_in.lineno = line; -#else - inp->str = str; - inp->length = len; - inp->offset = 0; - inp->putback = putback; - inp->filename = input_filename; - inp->lineno = lineno; - putback.buffer = NULL; - putback.buffer_size = 0; - putback.index = -1; -#endif - inp->next = input; - inp->input = save_pending_input (); - input = inp; - lineno = line; - input_filename = file; -} - -extern int end_of_file; - -static inline void -end_input () -{ - struct input_source *inp = input; - -#if USE_CPPLIB - cpp_pop_buffer (&parse_in); -#else - putback = inp->putback; - input_filename = inp->filename; - lineno = inp->lineno; -#endif - - end_of_file = 0; - input = inp->next; - /* Get interface/implementation back in sync. */ - extract_interface_info (); - restore_pending_input (inp->input); - free_input (inp); -} - -inline int -getch () -{ -#if USE_CPPLIB - return (yy_cur < yy_lim ? *yy_cur++ : yy_get_token ()); -#else - if (putback.index != -1) - { - int ch = putback.buffer[putback.index]; - --putback.index; - return ch; - } - if (input) - { - if (input->offset >= input->length) - { - my_friendly_assert (putback.index == -1, 223); - ++(input->offset); - if (input->offset - input->length < 64) - return EOF; - - /* We must be stuck in an error-handling rule; give up. */ - end_input (); - return getch (); - } - return (unsigned char)input->str[input->offset++]; - } - return getc (finput); -#endif -} - -inline -void -put_back (ch) - int ch; -{ -#if USE_CPPLIB - if (ch == EOF) - ; - else if (yy_cur[-1] != ch) - my_friendly_abort (990709); - else - yy_cur--; -#else - if (ch != EOF) - { - if (putback.index == putback.buffer_size - 1) - { - putback.buffer_size += 16; - putback.buffer = xrealloc (putback.buffer, putback.buffer_size); - } - my_friendly_assert (putback.buffer != NULL, 224); - putback.buffer[++putback.index] = ch; - } -#endif -} - -inline -int -input_redirected () -{ -#ifdef USE_CPPLIB - return CPP_BUFFER(&parse_in)->manual_pop; -#else - return input != 0; -#endif -} diff --git a/gcc/cp/lang-specs.h b/gcc/cp/lang-specs.h index 8f8c10d..a9c47d1 100644 --- a/gcc/cp/lang-specs.h +++ b/gcc/cp/lang-specs.h @@ -44,7 +44,7 @@ Boston, MA 02111-1307, USA. */ %{fnew-abi:-D__GXX_ABI_VERSION=100}\ %{ansi:-trigraphs -$ -D__STRICT_ANSI__} %(cpp_options)\ %{!M:%{!MM:%{!E:%{!pipe:%g.ii} |\n\ - cc1plus %{!pipe:%g.ii} %(cc1_options) %{+e*}\ + cc1plus -lang-c++ %{!pipe:%g.ii} %(cc1_options) %{+e*}\ %{!fsyntax-only:%{!S:-o %{|!pipe:%g.s} |\n\ as %(asm_options) %{!pipe:%g.s} %A }}}}}\n" #endif /* ! USE_CPPLIB */ @@ -52,6 +52,6 @@ Boston, MA 02111-1307, USA. */ {".ii", "@c++-cpp-output"}, {"@c++-cpp-output", "%{!M:%{!MM:%{!E:\ - cc1plus -fpreprocessed %i %(cc1_options) %{+e*}\ + cc1plus -lang-c++ -fpreprocessed %i %(cc1_options) %{+e*}\ %{!fsyntax-only:%{!S:-o %{|!pipe:%g.s} |\n\ as %(asm_options) %{!pipe:%g.s} %A }}}}}"}, diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c index 94679b4..1d6ca77 100644 --- a/gcc/cp/lex.c +++ b/gcc/cp/lex.c @@ -31,10 +31,11 @@ Boston, MA 02111-1307, USA. */ #include "input.h" #include "tree.h" #include "cp-tree.h" +#include "cpplib.h" +#include "c-lex.h" #include "lex.h" #include "parse.h" #include "flags.h" -#include "obstack.h" #include "c-pragma.h" #include "toplev.h" #include "output.h" @@ -48,98 +49,57 @@ Boston, MA 02111-1307, USA. */ #include #endif -#define obstack_chunk_alloc xmalloc -#define obstack_chunk_free free - extern void yyprint PARAMS ((FILE *, int, YYSTYPE)); -static tree get_time_identifier PARAMS ((const char *)); -static int check_newline PARAMS ((void)); -static int whitespace_cr PARAMS ((int)); -static int skip_white_space PARAMS ((int)); -static void finish_defarg PARAMS ((void)); static int interface_strcmp PARAMS ((const char *)); -static int readescape PARAMS ((int *)); -static char *extend_token_buffer PARAMS ((const char *)); -static void consume_string PARAMS ((struct obstack *, int)); -static void feed_defarg PARAMS ((tree, tree)); -static void store_pending_inline PARAMS ((tree, struct pending_inline *)); -static void reinit_parse_for_expr PARAMS ((struct obstack *)); static int *init_cpp_parse PARAMS ((void)); -static void cp_pragma_interface PARAMS ((const char *)); -static void cp_pragma_implementation PARAMS ((const char *)); -static int handle_cp_pragma PARAMS ((const char *)); -#ifdef HANDLE_GENERIC_PRAGMAS -static int handle_generic_pragma PARAMS ((int)); -#endif +static void init_reswords PARAMS ((void)); +static void init_cp_pragma PARAMS ((void)); +static void mark_impl_file_chain PARAMS ((PTR)); + +static tree parse_strconst_pragma PARAMS ((const char *, int)); +static void handle_pragma_vtable PARAMS ((cpp_reader *)); +static void handle_pragma_unit PARAMS ((cpp_reader *)); +static void handle_pragma_interface PARAMS ((cpp_reader *)); +static void handle_pragma_implementation PARAMS ((cpp_reader *)); + #ifdef GATHER_STATISTICS #ifdef REDUCE_LENGTH static int reduce_cmp PARAMS ((int *, int *)); static int token_cmp PARAMS ((int *, int *)); #endif #endif -static void begin_definition_of_inclass_inline PARAMS ((struct pending_inline*)); -static void parse_float PARAMS ((PTR)); static int is_global PARAMS ((tree)); -static void init_filename_times PARAMS ((void)); -static void extend_token_buffer_to PARAMS ((int)); -#ifdef HANDLE_PRAGMA -static int pragma_getc PARAMS ((void)); -static void pragma_ungetc PARAMS ((int)); -#endif -static int read_line_number PARAMS ((int *)); -static int token_getch PARAMS ((void)); -static void token_put_back PARAMS ((int)); -static void mark_impl_file_chain PARAMS ((void *)); -static int read_ucs PARAMS ((int)); -static int is_extended_char PARAMS ((int)); -static int is_extended_char_1 PARAMS ((int)); static void init_operators PARAMS ((void)); -/* This obstack is needed to hold text. It is not safe to use - TOKEN_BUFFER because `check_newline' calls `yylex'. */ -struct obstack inline_text_obstack; -char *inline_text_firstobj; - -/* Nonzero if parse output is being saved to an obstack for later parsing. */ -static int saving_parse_to_obstack = 0; +/* A constraint that can be tested at compile time. */ +#ifdef __STDC__ +#define CONSTRAINT(name, expr) extern int constraint_##name [(expr) ? 1 : -1] +#else +#define CONSTRAINT(name, expr) extern int constraint_/**/name [(expr) ? 1 : -1] +#endif -#if USE_CPPLIB #include "cpplib.h" +#if USE_CPPLIB extern cpp_reader parse_in; -extern cpp_options parse_options; -extern unsigned char *yy_cur, *yy_lim; -extern enum cpp_token cpp_token; #else FILE *finput; -#endif -int end_of_file; int linemode; +#endif /* Pending language change. Positive is push count, negative is pop count. */ int pending_lang_change = 0; -/* Wrap the current header file in extern "C". */ -static int c_header_level = 0; - -extern int first_token; -extern struct obstack token_obstack; - -/* ??? Don't really know where this goes yet. */ -#include "input.c" - - extern int yychar; /* the lookahead symbol */ extern YYSTYPE yylval; /* the semantic value of the */ /* lookahead symbol */ -#if 0 -YYLTYPE yylloc; /* location data for the lookahead */ - /* symbol */ -#endif - +/* These flags are used by c-lex.c. In C++, they're always off and on, + respectively. */ +int warn_traditional = 0; +int flag_digraphs = 1; /* the declaration found for the last IDENTIFIER token read in. yylex must look this up to detect typedefs, which get token type TYPENAME, @@ -147,24 +107,9 @@ YYLTYPE yylloc; /* location data for the lookahead */ used in a context which makes it a reference to a variable. */ tree lastiddecl; -/* We may keep statistics about how long which files took to compile. */ -static int header_time, body_time; -static tree filename_times; -static tree this_filename_time; - /* Array for holding counts of the numbers of tokens seen. */ extern int *token_count; -/* When we see a default argument in a method declaration, we snarf it as - text using snarf_defarg. When we get up to namespace scope, we then go - through and parse all of them using do_pending_defargs. Since yacc - parsers are not reentrant, we retain defargs state in these two - variables so that subsequent calls to do_pending_defargs can resume - where the previous call left off. */ - -static tree defarg_fns; -static tree defarg_parm; - /* Functions and data structures for #pragma interface. `#pragma implementation' means that the main file being compiled @@ -255,9 +200,6 @@ make_call_declarator (target, parms, cv_qualifiers, exception_specification) tree target, parms, cv_qualifiers, exception_specification; { target = build_parse_node (CALL_EXPR, target, - /* Both build_parse_node and - decl_tree_cons build on the - temp_decl_obstack. */ decl_tree_cons (parms, cv_qualifiers, NULL_TREE), /* The third operand is really RTL. We shouldn't put anything there. */ @@ -279,49 +221,6 @@ int interface_only; /* whether or not current file is only for int interface_unknown; /* whether or not we know this class to behave according to #pragma interface. */ -/* lexical analyzer */ - -#undef WCHAR_TYPE_SIZE -#define WCHAR_TYPE_SIZE TYPE_PRECISION (wchar_type_node) - -/* Number of bytes in a wide character. */ -#define WCHAR_BYTES (WCHAR_TYPE_SIZE / BITS_PER_UNIT) - -static int maxtoken; /* Current nominal length of token buffer. */ -char *token_buffer; /* Pointer to token buffer. - Actual allocated length is maxtoken + 2. */ - -static int indent_level; /* Number of { minus number of }. */ - -#include "hash.h" - - -/* Nonzero tells yylex to ignore \ in string constants. */ -static int ignore_escape_flag; - -static tree -get_time_identifier (name) - const char *name; -{ - tree time_identifier; - int len = strlen (name); - char *buf = (char *) alloca (len + 6); - strcpy (buf, "file "); - bcopy (name, buf+5, len); - buf[len+5] = '\0'; - time_identifier = get_identifier (buf); - if (TIME_IDENTIFIER_TIME (time_identifier) == NULL_TREE) - { - TIME_IDENTIFIER_TIME (time_identifier) = build_int_2 (0, 0); - TIME_IDENTIFIER_FILEINFO (time_identifier) - = build_int_2 (0, 1); - SET_IDENTIFIER_GLOBAL_VALUE (time_identifier, filename_times); - filename_times = time_identifier; - } - return time_identifier; -} - - /* Tree code classes. */ #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE, @@ -360,10 +259,8 @@ void lang_init_options () { #if USE_CPPLIB + cpp_init (); cpp_reader_init (&parse_in); - parse_in.opts = &parse_options; - cpp_options_init (&parse_options); - parse_options.cplusplus = 1; #endif /* Default exceptions on. */ @@ -385,10 +282,13 @@ lang_init () if (flag_bounds_check < 0) flag_bounds_check = flag_bounded_pointers; +#if !USE_CPPLIB /* the beginning of the file is a new line; check for # */ /* With luck, we discover the real source file's name from that and put it in input_filename. */ - put_back (check_newline ()); + ungetc (check_newline (), finput); +#endif + if (flag_gnu_xref) GNU_xref_begin (input_filename); init_repo (input_filename); } @@ -405,19 +305,6 @@ lang_identify () return "cplusplus"; } -static void -init_filename_times () -{ - this_filename_time = get_time_identifier (""); - if (flag_detailed_statistics) - { - header_time = 0; - body_time = get_run_time (); - TREE_INT_CST_LOW (TIME_IDENTIFIER_TIME (this_filename_time)) - = body_time; - } -} - static int * init_cpp_parse () { @@ -439,6 +326,11 @@ operator_name_info_t assignment_operator_name_info[(int) LAST_CPLUS_TREE_CODE]; /* Initialize data structures that keep track of operator names. */ +#define DEF_OPERATOR(NAME, C, NM, OM, AR, AP) \ + CONSTRAINT (C, sizeof "operator " + sizeof NAME <= 256); +#include "operators.def" +#undef DEF_OPERATOR + static void init_operators () { @@ -447,9 +339,6 @@ init_operators () struct operator_name_info_t *oni; #define DEF_OPERATOR(NAME, CODE, NEW_MANGLING, OLD_MANGLING, ARITY, ASSN_P) \ - my_friendly_assert ((strlen ("operator ") + strlen (NAME) + 1 \ - + ISALPHA (NAME[0]) <= 256), \ - 20000526); \ sprintf (buffer, ISALPHA (NAME[0]) ? "operator %s" : "operator%s", NAME); \ identifier = get_identifier (buffer); \ IDENTIFIER_OPNAME_P (identifier) = 1; \ @@ -507,57 +396,326 @@ init_operators () = "(round %=)"; } -const char * -init_parse (filename) - const char *filename; +/* The reserved keyword table. */ +struct resword { - extern int flag_no_gnu_keywords; - extern int flag_operator_names; + const char *word; + ENUM_BITFIELD(rid) rid : 16; + unsigned int disable : 16; +}; -#ifdef MULTIBYTE_CHARS - /* Change to the native locale for multibyte conversions. */ - setlocale (LC_CTYPE, ""); - literal_codeset = getenv ("LANG"); -#endif +/* Disable mask. Keywords are disabled if (reswords[i].disable & mask) is + _true_. */ +#define D_EXT 0x01 /* GCC extension */ +#define D_ASM 0x02 /* in C99, but has a switch to turn it off */ +#define D_OPNAME 0x04 /* operator names */ + +CONSTRAINT(ridbits_fit, RID_LAST_MODIFIER < sizeof(unsigned long) * CHAR_BIT); + +static const struct resword reswords[] = +{ + { "__alignof", RID_ALIGNOF, 0 }, + { "__alignof__", RID_ALIGNOF, 0 }, + { "__asm", RID_ASM, 0 }, + { "__asm__", RID_ASM, 0 }, + { "__attribute", RID_ATTRIBUTE, 0 }, + { "__attribute__", RID_ATTRIBUTE, 0 }, + { "__builtin_va_arg", RID_VA_ARG, 0 }, + { "__complex", RID_COMPLEX, 0 }, + { "__complex__", RID_COMPLEX, 0 }, + { "__const", RID_CONST, 0 }, + { "__const__", RID_CONST, 0 }, + { "__extension__", RID_EXTENSION, 0 }, + { "__imag", RID_IMAGPART, 0 }, + { "__imag__", RID_IMAGPART, 0 }, + { "__inline", RID_INLINE, 0 }, + { "__inline__", RID_INLINE, 0 }, + { "__label__", RID_LABEL, 0 }, + { "__null", RID_NULL, 0 }, + { "__real", RID_REALPART, 0 }, + { "__real__", RID_REALPART, 0 }, + { "__restrict", RID_RESTRICT, 0 }, + { "__restrict__", RID_RESTRICT, 0 }, + { "__signed", RID_SIGNED, 0 }, + { "__signed__", RID_SIGNED, 0 }, + { "__typeof", RID_TYPEOF, 0 }, + { "__typeof__", RID_TYPEOF, 0 }, + { "__volatile", RID_VOLATILE, 0 }, + { "__volatile__", RID_VOLATILE, 0 }, + { "__wchar_t", RID_WCHAR, 0 }, + { "asm", RID_ASM, D_ASM }, + { "and", RID_AND, D_OPNAME }, + { "and_eq", RID_AND_EQ, D_OPNAME }, + { "auto", RID_AUTO, 0 }, + { "bitand", RID_BITAND, D_OPNAME }, + { "bitor", RID_BITOR, D_OPNAME }, + { "bool", RID_BOOL, 0 }, + { "break", RID_BREAK, 0 }, + { "case", RID_CASE, 0 }, + { "catch", RID_CATCH, 0 }, + { "char", RID_CHAR, 0 }, + { "class", RID_CLASS, 0 }, + { "compl", RID_COMPL, D_OPNAME }, + { "const", RID_CONST, 0 }, + { "const_cast", RID_CONSTCAST, 0 }, + { "continue", RID_CONTINUE, 0 }, + { "default", RID_DEFAULT, 0 }, + { "delete", RID_DELETE, 0 }, + { "do", RID_DO, 0 }, + { "double", RID_DOUBLE, 0 }, + { "dynamic_cast", RID_DYNCAST, 0 }, + { "else", RID_ELSE, 0 }, + { "enum", RID_ENUM, 0 }, + { "explicit", RID_EXPLICIT, 0 }, + { "export", RID_EXPORT, 0 }, + { "extern", RID_EXTERN, 0 }, + { "false", RID_FALSE, 0 }, + { "float", RID_FLOAT, 0 }, + { "for", RID_FOR, 0 }, + { "friend", RID_FRIEND, 0 }, + { "goto", RID_GOTO, 0 }, + { "if", RID_IF, 0 }, + { "inline", RID_INLINE, 0 }, + { "int", RID_INT, 0 }, + { "long", RID_LONG, 0 }, + { "mutable", RID_MUTABLE, 0 }, + { "namespace", RID_NAMESPACE, 0 }, + { "new", RID_NEW, 0 }, + { "not", RID_NOT, D_OPNAME }, + { "not_eq", RID_NOT_EQ, D_OPNAME }, + { "operator", RID_OPERATOR, 0 }, + { "or", RID_OR, D_OPNAME }, + { "or_eq", RID_OR_EQ, D_OPNAME }, + { "private", RID_PRIVATE, 0 }, + { "protected", RID_PROTECTED, 0 }, + { "public", RID_PUBLIC, 0 }, + { "register", RID_REGISTER, 0 }, + { "reinterpret_cast", RID_REINTCAST, 0 }, + { "return", RID_RETURN, 0 }, + { "short", RID_SHORT, 0 }, + { "signed", RID_SIGNED, 0 }, + { "sizeof", RID_SIZEOF, 0 }, + { "static", RID_STATIC, 0 }, + { "static_cast", RID_STATCAST, 0 }, + { "struct", RID_STRUCT, 0 }, + { "switch", RID_SWITCH, 0 }, + { "template", RID_TEMPLATE, 0 }, + { "this", RID_THIS, 0 }, + { "throw", RID_THROW, 0 }, + { "true", RID_TRUE, 0 }, + { "try", RID_TRY, 0 }, + { "typedef", RID_TYPEDEF, 0 }, + { "typename", RID_TYPENAME, 0 }, + { "typeid", RID_TYPEID, 0 }, + { "typeof", RID_TYPEOF, D_ASM|D_EXT }, + { "union", RID_UNION, 0 }, + { "unsigned", RID_UNSIGNED, 0 }, + { "using", RID_USING, 0 }, + { "virtual", RID_VIRTUAL, 0 }, + { "void", RID_VOID, 0 }, + { "volatile", RID_VOLATILE, 0 }, + { "while", RID_WHILE, 0 }, + { "xor", RID_XOR, D_OPNAME }, + { "xor_eq", RID_XOR_EQ, D_OPNAME }, -#if !USE_CPPLIB - /* Open input file. */ - if (filename == 0 || !strcmp (filename, "-")) +}; +#define N_reswords (sizeof reswords / sizeof (struct resword)) + +/* Table mapping from RID_* constants to yacc token numbers. + Unfortunately we have to have entries for all the keywords in all + three languages. */ +const short rid_to_yy[RID_MAX] = +{ + /* RID_STATIC */ SCSPEC, + /* RID_UNSIGNED */ TYPESPEC, + /* RID_LONG */ TYPESPEC, + /* RID_CONST */ CV_QUALIFIER, + /* RID_EXTERN */ SCSPEC, + /* RID_REGISTER */ SCSPEC, + /* RID_TYPEDEF */ SCSPEC, + /* RID_SHORT */ TYPESPEC, + /* RID_INLINE */ SCSPEC, + /* RID_VOLATILE */ CV_QUALIFIER, + /* RID_SIGNED */ TYPESPEC, + /* RID_AUTO */ SCSPEC, + /* RID_RESTRICT */ CV_QUALIFIER, + + /* C extensions. Bounded pointers are not yet in C++ */ + /* RID_BOUNDED */ 0, + /* RID_UNBOUNDED */ 0, + /* RID_COMPLEX */ TYPESPEC, + + /* C++ */ + /* RID_FRIEND */ SCSPEC, + /* RID_VIRTUAL */ SCSPEC, + /* RID_EXPLICIT */ SCSPEC, + /* RID_EXPORT */ SCSPEC, + /* RID_MUTABLE */ SCSPEC, + + /* ObjC */ + /* RID_IN */ 0, + /* RID_OUT */ 0, + /* RID_INOUT */ 0, + /* RID_BYCOPY */ 0, + /* RID_BYREF */ 0, + /* RID_ONEWAY */ 0, + + /* C */ + /* RID_INT */ TYPESPEC, + /* RID_CHAR */ TYPESPEC, + /* RID_FLOAT */ TYPESPEC, + /* RID_DOUBLE */ TYPESPEC, + /* RID_VOID */ TYPESPEC, + /* RID_ENUM */ ENUM, + /* RID_STRUCT */ AGGR, + /* RID_UNION */ AGGR, + /* RID_IF */ IF, + /* RID_ELSE */ ELSE, + /* RID_WHILE */ WHILE, + /* RID_DO */ DO, + /* RID_FOR */ FOR, + /* RID_SWITCH */ SWITCH, + /* RID_CASE */ CASE, + /* RID_DEFAULT */ DEFAULT, + /* RID_BREAK */ BREAK, + /* RID_CONTINUE */ CONTINUE, + /* RID_RETURN */ RETURN_KEYWORD, + /* RID_GOTO */ GOTO, + /* RID_SIZEOF */ SIZEOF, + + /* C extensions */ + /* RID_ASM */ ASM_KEYWORD, + /* RID_TYPEOF */ TYPEOF, + /* RID_ALIGNOF */ ALIGNOF, + /* RID_ATTRIBUTE */ ATTRIBUTE, + /* RID_VA_ARG */ VA_ARG, + /* RID_EXTENSION */ EXTENSION, + /* RID_IMAGPART */ IMAGPART, + /* RID_REALPART */ REALPART, + /* RID_LABEL */ LABEL, + /* RID_PTRBASE */ 0, + /* RID_PTREXTENT */ 0, + /* RID_PTRVALUE */ 0, + + /* C++ */ + /* RID_BOOL */ TYPESPEC, + /* RID_WCHAR */ TYPESPEC, + /* RID_CLASS */ AGGR, + /* RID_PUBLIC */ VISSPEC, + /* RID_PRIVATE */ VISSPEC, + /* RID_PROTECTED */ VISSPEC, + /* RID_TEMPLATE */ TEMPLATE, + /* RID_NULL */ CONSTANT, + /* RID_CATCH */ CATCH, + /* RID_DELETE */ DELETE, + /* RID_FALSE */ CXX_FALSE, + /* RID_NAMESPACE */ NAMESPACE, + /* RID_NEW */ NEW, + /* RID_OPERATOR */ OPERATOR, + /* RID_THIS */ THIS, + /* RID_THROW */ THROW, + /* RID_TRUE */ CXX_TRUE, + /* RID_TRY */ TRY, + /* RID_TYPENAME */ TYPENAME_KEYWORD, + /* RID_TYPEID */ TYPEID, + /* RID_USING */ USING, + + /* casts */ + /* RID_CONSTCAST */ CONST_CAST, + /* RID_DYNCAST */ DYNAMIC_CAST, + /* RID_REINTCAST */ REINTERPRET_CAST, + /* RID_STATCAST */ STATIC_CAST, + + /* alternate spellings */ + /* RID_AND */ ANDAND, + /* RID_AND_EQ */ ASSIGN, + /* RID_NOT */ '!', + /* RID_NOT_EQ */ EQCOMPARE, + /* RID_OR */ OROR, + /* RID_OR_EQ */ ASSIGN, + /* RID_XOR */ '^', + /* RID_XOR_EQ */ ASSIGN, + /* RID_BITAND */ '&', + /* RID_BITOR */ '|', + /* RID_COMPL */ '~', + + /* Objective C */ + /* RID_ID */ 0, + /* RID_AT_ENCODE */ 0, + /* RID_AT_END */ 0, + /* RID_AT_CLASS */ 0, + /* RID_AT_ALIAS */ 0, + /* RID_AT_DEFS */ 0, + /* RID_AT_PRIVATE */ 0, + /* RID_AT_PROTECTED */ 0, + /* RID_AT_PUBLIC */ 0, + /* RID_AT_PROTOCOL */ 0, + /* RID_AT_SELECTOR */ 0, + /* RID_AT_INTERFACE */ 0, + /* RID_AT_IMPLEMENTATION */ 0 +}; + +static void +init_reswords () +{ + unsigned int i; + tree id; + int mask = ((flag_operator_names ? 0 : D_OPNAME) + | (flag_no_asm ? D_ASM : 0) + | (flag_no_gnu_keywords ? D_EXT : 0)); + + /* It is not necessary to register ridpointers as a GC root, because + all the trees it points to are permanently interned in the + get_identifier hash anyway. */ + ridpointers = (tree *) xcalloc ((int) RID_MAX, sizeof (tree)); + for (i = 0; i < N_reswords; i++) { - finput = stdin; - filename = "stdin"; + id = get_identifier (reswords[i].word); + C_RID_CODE (id) = reswords[i].rid; + ridpointers [(int) reswords[i].rid] = id; + if (! (reswords[i].disable & mask)) + C_IS_RESERVED_WORD (id) = 1; } - else - finput = fopen (filename, "r"); - if (finput == 0) - pfatal_with_name (filename); +} -#ifdef IO_BUFFER_SIZE - setvbuf (finput, (char *) xmalloc (IO_BUFFER_SIZE), _IOFBF, IO_BUFFER_SIZE); +static void +init_cp_pragma () +{ +#if USE_CPPLIB +#define pfile &parse_in +#else +#define pfile 0 #endif -#else /* !USE_CPPLIB */ - parse_in.show_column = 1; - if (! cpp_start_read (&parse_in, filename)) - abort (); + cpp_register_pragma (pfile, 0, "vtable", handle_pragma_vtable); + cpp_register_pragma (pfile, 0, "unit", handle_pragma_unit); - if (filename == 0 || !strcmp (filename, "-")) - filename = "stdin"; + cpp_register_pragma (pfile, 0, "interface", handle_pragma_interface); + cpp_register_pragma (pfile, 0, "implementation", + handle_pragma_implementation); - /* cpp_start_read always puts at least one line directive into the - token buffer. We must arrange to read it out here. */ - yy_cur = parse_in.token_buffer; - yy_lim = CPP_PWRITTEN (&parse_in); - cpp_token = CPP_DIRECTIVE; - -#endif /* !USE_CPPLIB */ - - /* Initialize the lookahead machinery. */ - init_spew (); + cpp_register_pragma_space (pfile, "GCC"); + cpp_register_pragma (pfile, "GCC", "interface", handle_pragma_interface); + cpp_register_pragma (pfile, "GCC", "implementation", + handle_pragma_implementation); +} +const char * +init_parse (filename) + const char *filename; +{ /* Make identifier nodes long enough for the language-specific slots. */ set_identifier_size (sizeof (struct lang_identifier)); decl_printable_name = lang_printable_name; + internal_filename = ggc_alloc_string (INTERNAL_FILENAME, + sizeof (INTERNAL_FILENAME)); + input_filename = internal_filename; + + init_reswords (); + init_pragma (); + init_cp_pragma (); + + init_spew (); init_tree (); init_cplus_expand (); @@ -576,53 +734,16 @@ init_parse (filename) init_operators (); init_method (); init_error (); - gcc_obstack_init (&inline_text_obstack); - inline_text_firstobj = (char *) obstack_alloc (&inline_text_obstack, 0); - - internal_filename = ggc_alloc_string (INTERNAL_FILENAME, - sizeof (INTERNAL_FILENAME)); - /* Start it at 0, because check_newline is called at the very beginning - and will increment it to 1. */ - lineno = 0; - input_filename = internal_filename; current_function_decl = NULL; - maxtoken = 40; - token_buffer = (char *) xmalloc (maxtoken + 2); - - my_friendly_assert ((int) CP_RID_MAX < 64, 20000630); - ridpointers = (tree *) xcalloc ((int) CP_RID_MAX, sizeof (tree)); - ridpointers[(int) RID_INT] = get_identifier ("int"); - ridpointers[(int) RID_BOOL] = get_identifier ("bool"); - ridpointers[(int) RID_CHAR] = get_identifier ("char"); - ridpointers[(int) RID_VOID] = get_identifier ("void"); - ridpointers[(int) RID_FLOAT] = get_identifier ("float"); - ridpointers[(int) RID_DOUBLE] = get_identifier ("double"); - ridpointers[(int) RID_SHORT] = get_identifier ("short"); - ridpointers[(int) RID_LONG] = get_identifier ("long"); - ridpointers[(int) RID_UNSIGNED] = get_identifier ("unsigned"); - ridpointers[(int) RID_SIGNED] = get_identifier ("signed"); - ridpointers[(int) RID_INLINE] = get_identifier ("inline"); - ridpointers[(int) RID_CONST] = get_identifier ("const"); - ridpointers[(int) RID_RESTRICT] = get_identifier ("__restrict"); - ridpointers[(int) RID_VOLATILE] = get_identifier ("volatile"); - ridpointers[(int) RID_AUTO] = get_identifier ("auto"); - ridpointers[(int) RID_STATIC] = get_identifier ("static"); - ridpointers[(int) RID_EXTERN] = get_identifier ("extern"); - ridpointers[(int) RID_TYPEDEF] = get_identifier ("typedef"); - ridpointers[(int) RID_REGISTER] = get_identifier ("register"); - ridpointers[(int) RID_COMPLEX] = get_identifier ("__complex"); - - /* C++ extensions. These are probably not correctly named. */ - ridpointers[(int) RID_WCHAR] = get_identifier ("__wchar_t"); class_type_node = build_int_2 (class_type, 0); TREE_TYPE (class_type_node) = class_type_node; ridpointers[(int) RID_CLASS] = class_type_node; record_type_node = build_int_2 (record_type, 0); TREE_TYPE (record_type_node) = record_type_node; - ridpointers[(int) RID_RECORD] = record_type_node; + ridpointers[(int) RID_STRUCT] = record_type_node; union_type_node = build_int_2 (union_type, 0); TREE_TYPE (union_type_node) = union_type_node; @@ -632,18 +753,6 @@ init_parse (filename) TREE_TYPE (enum_type_node) = enum_type_node; ridpointers[(int) RID_ENUM] = enum_type_node; - ridpointers[(int) RID_VIRTUAL] = get_identifier ("virtual"); - ridpointers[(int) RID_EXPLICIT] = get_identifier ("explicit"); - ridpointers[(int) RID_EXPORT] = get_identifier ("export"); - ridpointers[(int) RID_FRIEND] = get_identifier ("friend"); - - ridpointers[(int) RID_PUBLIC] = get_identifier ("public"); - ridpointers[(int) RID_PRIVATE] = get_identifier ("private"); - ridpointers[(int) RID_PROTECTED] = get_identifier ("protected"); - ridpointers[(int) RID_TEMPLATE] = get_identifier ("template"); - /* This is for ANSI C++. */ - ridpointers[(int) RID_MUTABLE] = get_identifier ("mutable"); - /* Create the built-in __null node. Note that we can't yet call for type_for_size here because integer_type_node and so forth are not set up. Therefore, we don't set the type of these nodes until @@ -651,61 +760,21 @@ init_parse (filename) null_node = build_int_2 (0, 0); ridpointers[RID_NULL] = null_node; - init_filename_times (); - - /* Some options inhibit certain reserved words. - Clear those words out of the hash table so they won't be recognized. */ -#define UNSET_RESERVED_WORD(STRING) \ - do { struct resword *s = is_reserved_word (STRING, sizeof (STRING) - 1); \ - if (s) s->name = ""; } while (0) - -#if 0 - /* let's parse things, and if they use it, then give them an error. */ - if (!flag_exceptions) - { - UNSET_RESERVED_WORD ("throw"); - UNSET_RESERVED_WORD ("try"); - UNSET_RESERVED_WORD ("catch"); - } -#endif - - if (flag_no_asm || flag_no_gnu_keywords) - UNSET_RESERVED_WORD ("typeof"); - if (! flag_operator_names) - { - /* These are new ANSI keywords that may break code. */ - UNSET_RESERVED_WORD ("and"); - UNSET_RESERVED_WORD ("and_eq"); - UNSET_RESERVED_WORD ("bitand"); - UNSET_RESERVED_WORD ("bitor"); - UNSET_RESERVED_WORD ("compl"); - UNSET_RESERVED_WORD ("not"); - UNSET_RESERVED_WORD ("not_eq"); - UNSET_RESERVED_WORD ("or"); - UNSET_RESERVED_WORD ("or_eq"); - UNSET_RESERVED_WORD ("xor"); - UNSET_RESERVED_WORD ("xor_eq"); - } - token_count = init_cpp_parse (); interface_unknown = 1; ggc_add_string_root (&internal_filename, 1); - ggc_add_tree_root (ridpointers, CP_RID_MAX); - ggc_add_tree_root (&defarg_fns, 1); - ggc_add_tree_root (&defarg_parm, 1); - ggc_add_tree_root (&this_filename_time, 1); - ggc_add_tree_root (&filename_times, 1); ggc_add_root (&impl_file_chain, 1, sizeof (impl_file_chain), mark_impl_file_chain); - return filename; + + return init_c_lex (filename); } void finish_parse () { #if USE_CPPLIB - cpp_finish (&parse_in); + cpp_finish (&parse_in, 0 /* no printer */); errorcount += parse_in.errors; #else fclose (finput); @@ -906,20 +975,23 @@ mark_impl_file_chain (arg) void extract_interface_info () { - tree fileinfo = 0; + struct c_fileinfo *finfo = 0; if (flag_alt_external_templates) { tree til = tinst_for_decl (); if (til) - fileinfo = get_time_identifier (TINST_FILE (til)); + finfo = get_fileinfo (TINST_FILE (til)); } - if (!fileinfo) - fileinfo = get_time_identifier (input_filename); - fileinfo = TIME_IDENTIFIER_FILEINFO (fileinfo); - interface_only = TREE_INT_CST_LOW (fileinfo); - interface_unknown = TREE_INT_CST_HIGH (fileinfo); + if (!finfo) + finfo = get_fileinfo (input_filename); + + interface_only = finfo->interface_only; + interface_unknown = finfo->interface_unknown; + + /* This happens to be a convenient place to put this. */ + if (flag_gnu_xref) GNU_xref_file (input_filename); } /* Return nonzero if S is not considered part of an @@ -963,12 +1035,124 @@ interface_strcmp (s) return 1; } +/* Heuristic to tell whether the user is missing a semicolon + after a struct or enum declaration. Emit an error message + if we know the user has blown it. */ + +void +check_for_missing_semicolon (type) + tree type; +{ + if (yychar < 0) + yychar = yylex (); + + if ((yychar > 255 + && yychar != SCSPEC + && yychar != IDENTIFIER + && yychar != TYPENAME + && yychar != CV_QUALIFIER + && yychar != SELFNAME) + || yychar == 0 /* EOF */) + { + if (ANON_AGGRNAME_P (TYPE_IDENTIFIER (type))) + error ("semicolon missing after %s declaration", + TREE_CODE (type) == ENUMERAL_TYPE ? "enum" : "struct"); + else + cp_error ("semicolon missing after declaration of `%T'", type); + shadow_tag (build_tree_list (0, type)); + } + /* Could probably also hack cases where class { ... } f (); appears. */ + clear_anon_tags (); +} + +void +note_got_semicolon (type) + tree type; +{ + if (!TYPE_P (type)) + my_friendly_abort (60); + if (CLASS_TYPE_P (type)) + CLASSTYPE_GOT_SEMICOLON (type) = 1; +} + +void +note_list_got_semicolon (declspecs) + tree declspecs; +{ + tree link; + + for (link = declspecs; link; link = TREE_CHAIN (link)) + { + tree type = TREE_VALUE (link); + if (TYPE_P (type)) + note_got_semicolon (type); + } + clear_anon_tags (); +} + + +/* Parse a #pragma whose sole argument is a string constant. + If OPT is true, the argument is optional. */ +static tree +parse_strconst_pragma (name, opt) + const char *name; + int opt; +{ + tree result, x; + enum cpp_ttype t; + + t = c_lex (&x); + if (t == CPP_STRING) + { + result = x; + if (c_lex (&x) != CPP_EOF) + warning ("junk at end of #pragma %s", name); + return result; + } + + if (t == CPP_EOF && opt) + return 0; + + error ("invalid #pragma %s", name); + return (tree)-1; +} + +static void +handle_pragma_vtable (dfile) + cpp_reader *dfile ATTRIBUTE_UNUSED; +{ + tree vtbl = parse_strconst_pragma ("vtable", 0); + + if (vtbl && vtbl != (tree)-1) + pending_vtables = tree_cons (NULL_TREE, + get_identifier (TREE_STRING_POINTER (vtbl)), + pending_vtables); +} + static void -cp_pragma_interface (main_filename) - const char *main_filename; +handle_pragma_unit (dfile) + cpp_reader *dfile ATTRIBUTE_UNUSED; { - tree fileinfo - = TIME_IDENTIFIER_FILEINFO (get_time_identifier (input_filename)); + /* Validate syntax, but don't do anything. */ + parse_strconst_pragma ("unit", 0); +} + +static void +handle_pragma_interface (dfile) + cpp_reader *dfile ATTRIBUTE_UNUSED; +{ + tree fname = parse_strconst_pragma ("interface", 1); + struct c_fileinfo *finfo; + const char *main_filename; + + if (fname == (tree)-1) + return; + else if (fname == 0) + main_filename = file_name_nondirectory (input_filename); + else + main_filename = TREE_STRING_POINTER (fname); + + finfo = get_fileinfo (input_filename); if (impl_file_chain == 0) { @@ -976,30 +1160,16 @@ cp_pragma_interface (main_filename) auto-implementing. */ if (main_input_filename == 0) main_input_filename = input_filename; - -#ifdef AUTO_IMPLEMENT - filename = file_name_nondirectory (main_input_filename); - fi = get_time_identifier (filename); - fi = TIME_IDENTIFIER_FILEINFO (fi); - TREE_INT_CST_LOW (fi) = 0; - TREE_INT_CST_HIGH (fi) = 1; - /* Get default. */ - impl_file_chain - = (struct impl_files *) xmalloc (sizeof (struct impl_files)); - impl_file_chain->filename = ggc_alloc_string (filename, -1); - impl_file_chain->next = 0; -#endif } interface_only = interface_strcmp (main_filename); #ifdef MULTIPLE_SYMBOL_SPACES if (! interface_only) +#endif interface_unknown = 0; -#else /* MULTIPLE_SYMBOL_SPACES */ - interface_unknown = 0; -#endif /* MULTIPLE_SYMBOL_SPACES */ - TREE_INT_CST_LOW (fileinfo) = interface_only; - TREE_INT_CST_HIGH (fileinfo) = interface_unknown; + + finfo->interface_only = interface_only; + finfo->interface_unknown = interface_unknown; } /* Note that we have seen a #pragma implementation for the key MAIN_FILENAME. @@ -1011,10 +1181,35 @@ cp_pragma_interface (main_filename) a matching #p interface for this to have any effect. */ static void -cp_pragma_implementation (main_filename) - const char *main_filename; +handle_pragma_implementation (dfile) + cpp_reader *dfile ATTRIBUTE_UNUSED; { + tree fname = parse_strconst_pragma ("implementation", 1); + const char *main_filename; struct impl_files *ifiles = impl_file_chain; + + if (fname == (tree)-1) + return; + + if (fname == 0) + { + if (main_input_filename) + main_filename = main_input_filename; + else + main_filename = input_filename; + main_filename = file_name_nondirectory (main_filename); + } + else + { + main_filename = TREE_STRING_POINTER (fname); +#if USE_CPPLIB + + if (cpp_included (&parse_in, main_filename)) + warning ("#pragma implementation for %s appears after file is included", + main_filename); +#endif + } + for (; ifiles; ifiles = ifiles->next) { if (! strcmp (ifiles->filename, main_filename)) @@ -1028,2047 +1223,57 @@ cp_pragma_implementation (main_filename) impl_file_chain = ifiles; } } - -/* Set up the state required to correctly handle the definition of the - inline function whose preparsed state has been saved in PI. */ -static void -begin_definition_of_inclass_inline (pi) - struct pending_inline* pi; +void +do_pending_lang_change () { - tree context; - - if (!pi->fndecl) - return; - - /* If this is an inline function in a local class, we must make sure - that we save all pertinent information about the function - surrounding the local class. */ - context = decl_function_context (pi->fndecl); - if (context) - push_function_context_to (context); - - feed_input (pi->buf, pi->len, pi->filename, pi->lineno); - yychar = PRE_PARSED_FUNCTION_DECL; - yylval.pi = pi; - /* Pass back a handle to the rest of the inline functions, so that they - can be processed later. */ - DECL_PENDING_INLINE_INFO (pi->fndecl) = 0; - DECL_PENDING_INLINE_P (pi->fndecl) = 0; - interface_unknown = pi->interface == 1; - interface_only = pi->interface == 0; + for (; pending_lang_change > 0; --pending_lang_change) + push_lang_context (lang_name_c); + for (; pending_lang_change < 0; ++pending_lang_change) + pop_lang_context (); } -/* Called from the top level: if there are any pending inlines to - do, set up to process them now. This function sets up the first function - to be parsed; after it has been, the rule for fndef in parse.y will - call process_next_inline to start working on the next one. */ +/* Return true if d is in a global scope. */ -void -do_pending_inlines () +static int +is_global (d) + tree d; { - struct pending_inline *t; - - /* Oops, we're still dealing with the last batch. */ - if (yychar == PRE_PARSED_FUNCTION_DECL) - return; + while (1) + switch (TREE_CODE (d)) + { + case ERROR_MARK: + return 1; - /* Reverse the pending inline functions, since - they were cons'd instead of appended. */ - { - struct pending_inline *prev = 0, *tail; - t = pending_inlines; - pending_inlines = 0; + case OVERLOAD: d = OVL_FUNCTION (d); continue; + case TREE_LIST: d = TREE_VALUE (d); continue; + default: + my_friendly_assert (DECL_P (d), 980629); - for (; t; t = tail) - { - tail = t->next; - t->next = prev; - t->deja_vu = 1; - prev = t; + return DECL_NAMESPACE_SCOPE_P (d); } - t = prev; - } - - if (t == 0) - return; - - /* Now start processing the first inline function. */ - begin_definition_of_inclass_inline (t); } -/* Called from the fndecl rule in the parser when the function just parsed - was declared using a PRE_PARSED_FUNCTION_DECL (i.e. came from - do_pending_inlines). */ - -void -process_next_inline (i) - struct pending_inline *i; +tree +do_identifier (token, parsing, args) + register tree token; + int parsing; + tree args; { - tree context; - context = decl_function_context (i->fndecl); - if (context) - pop_function_context_from (context); - i = i->next; - if (yychar == YYEMPTY) - yychar = yylex (); - if (yychar != END_OF_SAVED_INPUT) - { - error ("parse error at end of saved function text"); + register tree id; + int lexing = (parsing == 1); - /* restore_pending_input will abort unless yychar is either - END_OF_SAVED_INPUT or YYEMPTY; since we already know we're - hosed, feed back YYEMPTY. */ - } - yychar = YYEMPTY; - end_input (); - if (i) - begin_definition_of_inclass_inline (i); + if (! lexing || IDENTIFIER_OPNAME_P (token)) + id = lookup_name (token, 0); else - extract_interface_info (); -} + id = lastiddecl; -/* Since inline methods can refer to text which has not yet been seen, - we store the text of the method in a structure which is placed in the - DECL_PENDING_INLINE_INFO field of the FUNCTION_DECL. - After parsing the body of the class definition, the FUNCTION_DECL's are - scanned to see which ones have this field set. Those are then digested - one at a time. + /* Do Koenig lookup if appropriate (inside templates we build lookup + expressions instead). - This function's FUNCTION_DECL will have a bit set in its common so - that we know to watch out for it. */ - -static void -consume_string (this_obstack, matching_char) - register struct obstack *this_obstack; - int matching_char; -{ - register int c; - int starting_lineno; - -#if USE_CPPLIB - if (cpp_token == CPP_STRING) - { - /* The C preprocessor will warn about newlines in strings. */ - obstack_grow (this_obstack, yy_cur, (yy_lim - yy_cur)); - yy_cur = yy_lim; - lineno = parse_in.lineno; - return; - } -#endif - - starting_lineno = lineno; - do - { - c = getch (); - if (c == EOF) - { - int save_lineno = lineno; - lineno = starting_lineno; - if (matching_char == '"') - error ("end of file encountered inside string constant"); - else - error ("end of file encountered inside character constant"); - lineno = save_lineno; - return; - } - if (c == '\\') - { - obstack_1grow (this_obstack, c); - c = getch (); - obstack_1grow (this_obstack, c); - - /* Make sure we continue the loop */ - c = 0; - continue; - } - if (c == '\n') - { - if (pedantic) - pedwarn ("ISO C++ forbids newline in string constant"); - lineno++; - } - obstack_1grow (this_obstack, c); - } - while (c != matching_char); -} - -struct pending_input { - int yychar, eof; - YYSTYPE yylval; - struct obstack token_obstack; - int first_token; -}; - -struct pending_input * -save_pending_input () -{ - struct pending_input *p; - p = (struct pending_input *) xmalloc (sizeof (struct pending_input)); - p->yychar = yychar; - p->yylval = yylval; - p->eof = end_of_file; - yychar = YYEMPTY; - p->first_token = first_token; - p->token_obstack = token_obstack; - - first_token = 0; - gcc_obstack_init (&token_obstack); - end_of_file = 0; - return p; -} - -void -restore_pending_input (p) - struct pending_input *p; -{ - my_friendly_assert (yychar == YYEMPTY || yychar == END_OF_SAVED_INPUT, 230); - yychar = p->yychar; - yylval = p->yylval; - first_token = p->first_token; - obstack_free (&token_obstack, (char *) 0); - token_obstack = p->token_obstack; - end_of_file = p->eof; - free (p); -} - -/* Unget character CH from the input stream. - If RESCAN is non-zero, then we want to `see' this - character as the next input token. */ - -void -yyungetc (ch, rescan) - int ch; - int rescan; -{ - /* Unget a character from the input stream. */ - if (yychar == YYEMPTY || rescan == 0) - { - /* If we're putting back a brace, undo the change in indent_level - from the first time we saw it. */ - if (ch == '{') - indent_level--; - else if (ch == '}') - indent_level++; - - put_back (ch); - } - else - { - yychar = ch; - } -} - -void -clear_inline_text_obstack () -{ - obstack_free (&inline_text_obstack, inline_text_firstobj); -} - -/* This function stores away the text for an inline function that should - be processed later. It decides how much later, and may need to move - the info between obstacks; therefore, the caller should not refer to - the T parameter after calling this function. */ - -static void -store_pending_inline (decl, t) - tree decl; - struct pending_inline *t; -{ - t->fndecl = decl; - DECL_PENDING_INLINE_INFO (decl) = t; - DECL_PENDING_INLINE_P (decl) = 1; - - /* Because we use obstacks, we must process these in precise order. */ - t->next = pending_inlines; - pending_inlines = t; -} - -void -reinit_parse_for_method (yychar, decl) - int yychar; - tree decl; -{ - int len; - int starting_lineno = lineno; - const char *starting_filename = input_filename; - - reinit_parse_for_block (yychar, &inline_text_obstack); - - len = obstack_object_size (&inline_text_obstack); - if (decl == void_type_node - || (current_class_type && TYPE_REDEFINED (current_class_type))) - { - /* Happens when we get two declarations of the same - function in the same scope. */ - char *buf = obstack_finish (&inline_text_obstack); - obstack_free (&inline_text_obstack, buf); - return; - } - else - { - struct pending_inline *t; - char *buf = obstack_finish (&inline_text_obstack); - - t = (struct pending_inline *) obstack_alloc (&inline_text_obstack, - sizeof (struct pending_inline)); - t->lineno = starting_lineno; - t->filename = starting_filename; - t->token = YYEMPTY; - t->token_value = 0; - t->buf = buf; - t->len = len; - t->deja_vu = 0; -#if 0 - if (interface_unknown && processing_template_defn && flag_external_templates && ! DECL_IN_SYSTEM_HEADER (decl)) - warn_if_unknown_interface (decl); -#endif - t->interface = (interface_unknown ? 1 : (interface_only ? 0 : 2)); - store_pending_inline (decl, t); - } -} - -/* Consume a block -- actually, a method beginning - with `:' or `{' -- and save it away on the specified obstack. */ - -void -reinit_parse_for_block (pyychar, obstackp) - int pyychar; - struct obstack *obstackp; -{ - register int c; - int blev = 1; - int starting_lineno = lineno; - const char *starting_filename = input_filename; - int len; - int look_for_semicolon = 0; - int look_for_lbrac = 0; - - if (pyychar == '{') - { - obstack_1grow (obstackp, '{'); - /* We incremented indent_level in yylex; undo that. */ - indent_level--; - } - else if (pyychar == '=') - look_for_semicolon = 1; - else if (pyychar == ':') - { - obstack_1grow (obstackp, pyychar); - /* Add a space so we don't get confused by ': ::A(20)'. */ - obstack_1grow (obstackp, ' '); - look_for_lbrac = 1; - blev = 0; - } - else if (pyychar == RETURN_KEYWORD) - { - obstack_grow (obstackp, "return", 6); - look_for_lbrac = 1; - blev = 0; - } - else if (pyychar == TRY) - { - obstack_grow (obstackp, "try", 3); - look_for_lbrac = 1; - blev = 0; - } - else - { - yyerror ("parse error in method specification"); - obstack_1grow (obstackp, '{'); - } - - c = getch (); - - while (c != EOF) - { - int this_lineno = lineno; - - saving_parse_to_obstack = 1; - c = skip_white_space (c); - saving_parse_to_obstack = 0; - - /* Don't lose our cool if there are lots of comments. */ - if (lineno == this_lineno + 1) - obstack_1grow (obstackp, '\n'); - else if (lineno == this_lineno) - ; - else if (lineno - this_lineno < 10) - { - int i; - for (i = lineno - this_lineno; i > 0; i--) - obstack_1grow (obstackp, '\n'); - } - else - { - char buf[16]; - sprintf (buf, "\n# %d \"", lineno); - len = strlen (buf); - obstack_grow (obstackp, buf, len); - - len = strlen (input_filename); - obstack_grow (obstackp, input_filename, len); - obstack_1grow (obstackp, '\"'); - obstack_1grow (obstackp, '\n'); - } - - while (c > ' ') /* ASCII dependent... */ - { - obstack_1grow (obstackp, c); - if (c == '{') - { - look_for_lbrac = 0; - blev++; - } - else if (c == '}') - { - blev--; - if (blev == 0 && !look_for_semicolon) - { - if (pyychar == TRY) - { - if (peekyylex () == CATCH) - { - yylex (); - obstack_grow (obstackp, " catch ", 7); - look_for_lbrac = 1; - } - else - { - yychar = '{'; - goto done; - } - } - else - { - goto done; - } - } - } - else if (c == '\\') - { - /* Don't act on the next character...e.g, doing an escaped - double-quote. */ - c = getch (); - if (c == EOF) - { - error_with_file_and_line (starting_filename, - starting_lineno, - "end of file read inside definition"); - goto done; - } - obstack_1grow (obstackp, c); - } - else if (c == '\"') - consume_string (obstackp, c); - else if (c == '\'') - consume_string (obstackp, c); - else if (c == ';') - { - if (look_for_lbrac) - { - error ("function body for constructor missing"); - obstack_1grow (obstackp, '{'); - obstack_1grow (obstackp, '}'); - len += 2; - goto done; - } - else if (look_for_semicolon && blev == 0) - goto done; - } - c = getch (); - } - - if (c == EOF) - { - error_with_file_and_line (starting_filename, - starting_lineno, - "end of file read inside definition"); - goto done; - } - else if (c != '\n') - { - obstack_1grow (obstackp, c); - c = getch (); - } - } - done: - obstack_1grow (obstackp, '\0'); -} - -/* Consume a no-commas expression -- actually, a default argument -- and - save it away on the specified obstack. */ - -static void -reinit_parse_for_expr (obstackp) - struct obstack *obstackp; -{ - register int c; - int starting_lineno = lineno; - const char *starting_filename = input_filename; - int len; - int plev = 0; - - c = getch (); - - while (c != EOF) - { - int this_lineno = lineno; - - saving_parse_to_obstack = 1; - c = skip_white_space (c); - saving_parse_to_obstack = 0; - - /* Don't lose our cool if there are lots of comments. */ - if (lineno == this_lineno + 1) - obstack_1grow (obstackp, '\n'); - else if (lineno == this_lineno) - ; - else if (lineno - this_lineno < 10) - { - int i; - for (i = lineno - this_lineno; i > 0; --i) - obstack_1grow (obstackp, '\n'); - } - else - { - char buf[16]; - sprintf (buf, "\n# %d \"", lineno); - len = strlen (buf); - obstack_grow (obstackp, buf, len); - - len = strlen (input_filename); - obstack_grow (obstackp, input_filename, len); - obstack_1grow (obstackp, '\"'); - obstack_1grow (obstackp, '\n'); - } - - while (c > ' ') /* ASCII dependent... */ - { - if (plev <= 0 && (c == ')' || c == ',')) - { - put_back (c); - goto done; - } - obstack_1grow (obstackp, c); - if (c == '(' || c == '[') - ++plev; - else if (c == ']' || c == ')') - --plev; - else if (c == '\\') - { - /* Don't act on the next character...e.g, doing an escaped - double-quote. */ - c = getch (); - if (c == EOF) - { - error_with_file_and_line (starting_filename, - starting_lineno, - "end of file read inside definition"); - goto done; - } - obstack_1grow (obstackp, c); - } - else if (c == '\"') - consume_string (obstackp, c); - else if (c == '\'') - consume_string (obstackp, c); - c = getch (); - } - - if (c == EOF) - { - error_with_file_and_line (starting_filename, - starting_lineno, - "end of file read inside definition"); - goto done; - } - else if (c != '\n') - { - obstack_1grow (obstackp, c); - c = getch (); - } - } - done: - obstack_1grow (obstackp, '\0'); -} - -int do_snarf_defarg; - -/* Decide whether the default argument we are about to see should be - gobbled up as text for later parsing. */ - -void -maybe_snarf_defarg () -{ - if (current_class_type && TYPE_BEING_DEFINED (current_class_type)) - do_snarf_defarg = 1; -} - -tree -snarf_defarg () -{ - int len; - char *buf; - tree arg; - - reinit_parse_for_expr (&inline_text_obstack); - len = obstack_object_size (&inline_text_obstack); - buf = obstack_finish (&inline_text_obstack); - - arg = make_node (DEFAULT_ARG); - DEFARG_LENGTH (arg) = len - 1; - DEFARG_POINTER (arg) = buf; - - return arg; -} - -/* Called from grokfndecl to note a function decl with unparsed default - arguments for later processing. Also called from grokdeclarator - for function types with unparsed defargs; the call from grokfndecl - will always come second, so we can overwrite the entry from the type. */ - -void -add_defarg_fn (decl) - tree decl; -{ - if (TREE_CODE (decl) == FUNCTION_DECL) - TREE_VALUE (defarg_fns) = decl; - else - defarg_fns = tree_cons (current_class_type, decl, defarg_fns); -} - -/* Helper for do_pending_defargs. Starts the parsing of a default arg. */ - -static void -feed_defarg (f, p) - tree f, p; -{ - tree d = TREE_PURPOSE (p); - const char *file; - int line; - if (TREE_CODE (f) == FUNCTION_DECL) - { - line = DECL_SOURCE_LINE (f); - file = DECL_SOURCE_FILE (f); - } - else - { - line = lineno; - file = input_filename; - } - - feed_input (DEFARG_POINTER (d), DEFARG_LENGTH (d), file, line); - yychar = DEFARG_MARKER; - yylval.ttype = p; -} - -/* Helper for do_pending_defargs. Ends the parsing of a default arg. */ - -static void -finish_defarg () -{ - if (yychar == YYEMPTY) - yychar = yylex (); - if (yychar != END_OF_SAVED_INPUT) - { - error ("parse error at end of saved function text"); - - /* restore_pending_input will abort unless yychar is either - END_OF_SAVED_INPUT or YYEMPTY; since we already know we're - hosed, feed back YYEMPTY. */ - } - yychar = YYEMPTY; - end_input (); -} - -/* Main function for deferred parsing of default arguments. Called from - the parser. */ - -void -do_pending_defargs () -{ - if (defarg_parm) - finish_defarg (); - - for (; defarg_fns; defarg_fns = TREE_CHAIN (defarg_fns)) - { - tree defarg_fn = TREE_VALUE (defarg_fns); - if (defarg_parm == NULL_TREE) - { - push_nested_class (TREE_PURPOSE (defarg_fns), 1); - pushlevel (0); - if (TREE_CODE (defarg_fn) == FUNCTION_DECL) - maybe_begin_member_template_processing (defarg_fn); - - if (TREE_CODE (defarg_fn) == FUNCTION_DECL) - { -#if 0 - tree p; - for (p = DECL_ARGUMENTS (defarg_fn); p; p = TREE_CHAIN (p)) - pushdecl (copy_node (p)); -#endif - defarg_parm = TYPE_ARG_TYPES (TREE_TYPE (defarg_fn)); - } - else - defarg_parm = TYPE_ARG_TYPES (defarg_fn); - } - else - defarg_parm = TREE_CHAIN (defarg_parm); - - for (; defarg_parm; defarg_parm = TREE_CHAIN (defarg_parm)) - if (TREE_PURPOSE (defarg_parm) - && TREE_CODE (TREE_PURPOSE (defarg_parm)) == DEFAULT_ARG) - { - feed_defarg (defarg_fn, defarg_parm); - - /* Return to the parser, which will process this defarg - and call us again. */ - return; - } - - if (TREE_CODE (defarg_fn) == FUNCTION_DECL) - { - maybe_end_member_template_processing (); - check_default_args (defarg_fn); - } - - poplevel (0, 0, 0); - pop_nested_class (); - } -} - -/* Heuristic to tell whether the user is missing a semicolon - after a struct or enum declaration. Emit an error message - if we know the user has blown it. */ - -void -check_for_missing_semicolon (type) - tree type; -{ - if (yychar < 0) - yychar = yylex (); - - if ((yychar > 255 - && yychar != SCSPEC - && yychar != IDENTIFIER - && yychar != TYPENAME - && yychar != CV_QUALIFIER - && yychar != SELFNAME) - || end_of_file) - { - if (ANON_AGGRNAME_P (TYPE_IDENTIFIER (type))) - error ("semicolon missing after %s declaration", - TREE_CODE (type) == ENUMERAL_TYPE ? "enum" : "struct"); - else - cp_error ("semicolon missing after declaration of `%T'", type); - shadow_tag (build_tree_list (0, type)); - } - /* Could probably also hack cases where class { ... } f (); appears. */ - clear_anon_tags (); -} - -void -note_got_semicolon (type) - tree type; -{ - if (!TYPE_P (type)) - my_friendly_abort (60); - if (CLASS_TYPE_P (type)) - CLASSTYPE_GOT_SEMICOLON (type) = 1; -} - -void -note_list_got_semicolon (declspecs) - tree declspecs; -{ - tree link; - - for (link = declspecs; link; link = TREE_CHAIN (link)) - { - tree type = TREE_VALUE (link); - if (TYPE_P (type)) - note_got_semicolon (type); - } - clear_anon_tags (); -} - -/* Iff C is a carriage return, warn about it - if appropriate - - and return nonzero. */ -static int -whitespace_cr (c) - int c; -{ - static int newline_warning = 0; - - if (c == '\r') - { - /* ANSI C says the effects of a carriage return in a source file - are undefined. */ - if (pedantic && !newline_warning) - { - warning ("carriage return in source file (we only warn about the first carriage return)"); - newline_warning = 1; - } - return 1; - } - return 0; -} - -/* If C is not whitespace, return C. - Otherwise skip whitespace and return first nonwhite char read. */ - -static int -skip_white_space (c) - register int c; -{ - for (;;) - { - switch (c) - { - /* We don't recognize comments here, because - cpp output can include / and * consecutively as operators. - Also, there's no need, since cpp removes all comments. */ - - case '\n': - if (linemode) - { - put_back (c); - return EOF; - } - c = check_newline (); - break; - - case ' ': - case '\t': - case '\f': - case '\v': - case '\b': -#if USE_CPPLIB - /* While processing a # directive we don't get CPP_HSPACE - tokens, so we also need to handle whitespace the normal way. */ - if (cpp_token == CPP_HSPACE) - c = yy_get_token (); - else -#endif - c = getch (); - break; - - case '\r': - whitespace_cr (c); - c = getch (); - break; - - case '\\': - c = getch (); - if (c == '\n') - { - lineno++; - c = getch (); - } - else if (c == 'u') - c = read_ucs (4); - else if (c == 'U') - c = read_ucs (8); - else - error ("stray '\\' in program"); - break; - - default: - return (c); - } - } -} - -/* Make the token buffer longer, preserving the data in it. - P should point to just beyond the last valid character in the old buffer. - The value we return is a pointer to the new buffer - at a place corresponding to P. */ - -static void -extend_token_buffer_to (size) - int size; -{ - do - maxtoken = maxtoken * 2 + 10; - while (maxtoken < size); - token_buffer = (char *) xrealloc (token_buffer, maxtoken + 2); -} - -static char * -extend_token_buffer (p) - const char *p; -{ - int offset = p - token_buffer; - extend_token_buffer_to (offset); - return token_buffer + offset; -} - -#if defined HANDLE_PRAGMA -/* Local versions of these macros, that can be passed as function pointers. */ -static int -pragma_getc () -{ - return getch (); -} - -static void -pragma_ungetc (arg) - int arg; -{ - put_back (arg); -} -#endif - -static int -read_line_number (num) - int *num; -{ - register int token = real_yylex (); - - if (token == CONSTANT - && TREE_CODE (yylval.ttype) == INTEGER_CST) - { - *num = TREE_INT_CST_LOW (yylval.ttype); - return 1; - } - else - { - if (token != END_OF_LINE) - error ("invalid #-line"); - return 0; - } -} - -/* At the beginning of a line, increment the line number - and process any #-directive on this line. - If the line is a #-directive, read the entire line and return a newline. - Otherwise, return the line's first non-whitespace character. - - Note that in the case of USE_CPPLIB, we get the whole line as one - CPP_DIRECTIVE token. */ - -static int -check_newline () -{ - register int c; - register int token; - int saw_line; - enum { act_none, act_push, act_pop } action; - int action_number, l; - int entering_c_header; - char *new_file; - - restart: - /* Read first nonwhite char on the line. Do this before incrementing the - line number, in case we're at the end of saved text. */ - -#ifdef USE_CPPLIB - c = getch (); - /* In some cases where we're leaving an include file, we can get multiple - CPP_HSPACE tokens in a row, so we need to loop. */ - while (cpp_token == CPP_HSPACE) - c = yy_get_token (); -#else - do - c = getch (); - while (c == ' ' || c == '\t'); -#endif - - lineno++; - - if (c != '#') - { - /* Sequences of multiple newlines are very common; optimize them. */ - if (c == '\n') - goto restart; - - /* If not #, return it so caller will use it. */ - return c; - } - - /* Don't read beyond this line. */ - saw_line = 0; - linemode = 1; - -#if USE_CPPLIB - if (cpp_token == CPP_VSPACE) - { - /* Format is " ". - Only the line number is interesting, and even that - we can get more efficiently than scanning the line. */ - yy_cur = yy_lim - 1; - lineno = parse_in.lineno - 1; - goto skipline; - } -#endif - - token = real_yylex (); - - if (token == IDENTIFIER) - { - /* If a letter follows, then if the word here is `line', skip - it and ignore it; otherwise, ignore the line, with an error - if the word isn't `pragma'. */ - - const char *name = IDENTIFIER_POINTER (yylval.ttype); - - if (!strcmp (name, "pragma")) - { - token = real_yylex (); - if (token != IDENTIFIER - || TREE_CODE (yylval.ttype) != IDENTIFIER_NODE) - goto skipline; - - /* If this is 1, we handled it; if it's -1, it was one we - wanted but had something wrong with it. Only if it's - 0 was it not handled. */ - if (handle_cp_pragma (IDENTIFIER_POINTER (yylval.ttype))) - goto skipline; - -#ifdef HANDLE_PRAGMA - /* We invoke HANDLE_PRAGMA before HANDLE_GENERIC_PRAGMAS - (if both are defined), in order to give the back - end a chance to override the interpretation of - SYSV style pragmas. */ - if (HANDLE_PRAGMA (pragma_getc, pragma_ungetc, - IDENTIFIER_POINTER (yylval.ttype))) - goto skipline; -#endif /* HANDLE_PRAGMA */ - -#ifdef HANDLE_GENERIC_PRAGMAS - if (handle_generic_pragma (token)) - goto skipline; -#endif /* HANDLE_GENERIC_PRAGMAS */ - - /* Issue a warning message if we have been asked to do so. - Ignoring unknown pragmas in system header file unless - an explcit -Wunknown-pragmas has been given. */ - if (warn_unknown_pragmas > 1 - || (warn_unknown_pragmas && ! in_system_header)) - warning ("ignoring pragma: %s", token_buffer); - - goto skipline; - } - else if (!strcmp (name, "define")) - { - debug_define (lineno, GET_DIRECTIVE_LINE ()); - goto skipline; - } - else if (!strcmp (name, "undef")) - { - debug_undef (lineno, GET_DIRECTIVE_LINE ()); - goto skipline; - } - else if (!strcmp (name, "line")) - { - saw_line = 1; - token = real_yylex (); - goto linenum; - } - else if (!strcmp (name, "ident")) - { - /* #ident. The pedantic warning is now in cpp. */ - - /* Here we have just seen `#ident '. - A string constant should follow. */ - - token = real_yylex (); - if (token == END_OF_LINE) - goto skipline; - if (token != STRING - || TREE_CODE (yylval.ttype) != STRING_CST) - { - error ("invalid #ident"); - goto skipline; - } - - if (! flag_no_ident) - { -#ifdef ASM_OUTPUT_IDENT - ASM_OUTPUT_IDENT (asm_out_file, - TREE_STRING_POINTER (yylval.ttype)); -#endif - } - - /* Skip the rest of this line. */ - goto skipline; - } - - error ("undefined or invalid # directive `%s'", name); - goto skipline; - } - - /* If the # is the only nonwhite char on the line, - just ignore it. Check the new newline. */ - if (token == END_OF_LINE) - goto skipline; - -linenum: - /* Here we have either `#line' or `# '. - In either case, it should be a line number; a digit should follow. */ - - if (token != CONSTANT - || TREE_CODE (yylval.ttype) != INTEGER_CST) - { - error ("invalid #-line"); - goto skipline; - } - - /* subtract one, because it is the following line that - gets the specified number */ - - l = TREE_INT_CST_LOW (yylval.ttype) - 1; - - /* More follows: it must be a string constant (filename). - It would be neat to use cpplib to quickly process the string, but - (1) we don't have a handy tokenization of the string, and - (2) I don't know how well that would work in the presense - of filenames that contain wide characters. */ - - if (saw_line || saving_parse_to_obstack) - { - /* Don't treat \ as special if we are processing #line 1 "...". - If you want it to be treated specially, use # 1 "...". Also - ignore these if saving to an obstack for later parsing. */ - ignore_escape_flag = 1; - } - - /* Read the string constant. */ - token = real_yylex (); - - ignore_escape_flag = 0; - - if (token == END_OF_LINE) - { - /* No more: store the line number and check following line. */ - lineno = l; - goto skipline; - } - - if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST) - { - error ("invalid #line"); - goto skipline; - } - - /* Changing files again. This means currently collected time - is charged against header time, and body time starts back at 0. */ - if (flag_detailed_statistics) - { - int this_time = get_run_time (); - tree time_identifier = get_time_identifier (TREE_STRING_POINTER (yylval.ttype)); - header_time += this_time - body_time; - TREE_INT_CST_LOW (TIME_IDENTIFIER_TIME (this_filename_time)) - += this_time - body_time; - this_filename_time = time_identifier; - body_time = this_time; - } - - new_file = TREE_STRING_POINTER (yylval.ttype); - - GNU_xref_file (new_file); - - if (main_input_filename == 0) - { - struct impl_files *ifiles = impl_file_chain; - - if (ifiles) - { - while (ifiles->next) - ifiles = ifiles->next; - ifiles->filename = file_name_nondirectory (new_file); - } - - main_input_filename = new_file; - } - - action = act_none; - action_number = 0; - - /* Each change of file name - reinitializes whether we are now in a system header. */ - in_system_header = 0; - entering_c_header = 0; - - if (!read_line_number (&action_number) && input_file_stack) - { - input_file_stack->name = input_filename = new_file; - input_file_stack->line = lineno = l; - } - - /* `1' after file name means entering new file. - `2' after file name means just left a file. */ - - if (action_number == 1) - { - action = act_push; - read_line_number (&action_number); - } - else if (action_number == 2) - { - action = act_pop; - read_line_number (&action_number); - } - if (action_number == 3) - { - /* `3' after file name means this is a system header file. */ - in_system_header = 1; - read_line_number (&action_number); - } - if (action_number == 4) - { - /* `4' after file name means this is a C header file. */ - entering_c_header = 1; - read_line_number (&action_number); - } - - /* Do the actions implied by the preceding numbers. */ - - if (action == act_push) - { - /* Pushing to a new file. */ - push_srcloc (new_file, l); - input_file_stack->indent_level = indent_level; - debug_start_source_file (input_filename); - if (c_header_level) - ++c_header_level; - else if (entering_c_header) - { - c_header_level = 1; - ++pending_lang_change; - } - } - else if (action == act_pop) - { - /* Popping out of a file. */ - if (input_file_stack->next) - { - if (c_header_level && --c_header_level == 0) - { - if (entering_c_header) - warning ("badly nested C headers from preprocessor"); - --pending_lang_change; - } - - if (indent_level != input_file_stack->indent_level) - { - warning_with_file_and_line - (input_filename, lineno, - "This file contains more `%c's than `%c's.", - indent_level > input_file_stack->indent_level ? '{' : '}', - indent_level > input_file_stack->indent_level ? '}' : '{'); - } - - pop_srcloc (); - input_file_stack->name = new_file; - debug_end_source_file (input_file_stack->line); - } - else - error ("#-lines for entering and leaving files don't match"); - } - - input_filename = new_file; - lineno = l; - - extract_interface_info (); - - /* skip the rest of this line. */ - skipline: - linemode = 0; - end_of_file = 0; - - do - c = getch (); - while (c != '\n' && c != EOF); - return c; -} - -#ifdef HANDLE_GENERIC_PRAGMAS - -/* Handle a #pragma directive. - TOKEN is the token we read after `#pragma'. Processes the entire input - line and return non-zero iff the pragma has been successfully parsed. */ - -/* This function has to be in this file, in order to get at - the token types. */ - -static int -handle_generic_pragma (token) - register int token; -{ - for (;;) - { - switch (token) - { - case IDENTIFIER: - case TYPENAME: - case STRING: - case CONSTANT: - handle_pragma_token (token_buffer, yylval.ttype); - break; - - case LEFT_RIGHT: - handle_pragma_token ("(", NULL_TREE); - handle_pragma_token (")", NULL_TREE); - break; - - case END_OF_LINE: - return handle_pragma_token (NULL_PTR, NULL_TREE); - - default: - handle_pragma_token (token_buffer, NULL_TREE); - } - - token = real_yylex (); - } -} -#endif /* HANDLE_GENERIC_PRAGMAS */ - -static int -handle_cp_pragma (pname) - const char *pname; -{ - register int token; - - if (! strcmp (pname, "vtable")) - { - /* More follows: it must be a string constant (class name). */ - token = real_yylex (); - if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST) - { - error ("invalid #pragma vtable"); - return -1; - } - - pending_vtables - = tree_cons (NULL_TREE, - get_identifier (TREE_STRING_POINTER (yylval.ttype)), - pending_vtables); - token = real_yylex (); - if (token != END_OF_LINE) - warning ("trailing characters ignored"); - return 1; - } - else if (! strcmp (pname, "unit")) - { - /* More follows: it must be a string constant (unit name). */ - token = real_yylex (); - if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST) - { - error ("invalid #pragma unit"); - return -1; - } - token = real_yylex (); - if (token != END_OF_LINE) - warning ("trailing characters ignored"); - return 1; - } - else if (! strcmp (pname, "interface")) - { - const char *main_filename = input_filename; - - main_filename = file_name_nondirectory (main_filename); - - token = real_yylex (); - - if (token != END_OF_LINE) - { - if (token != STRING - || TREE_CODE (yylval.ttype) != STRING_CST) - { - error ("invalid `#pragma interface'"); - return -1; - } - main_filename = TREE_STRING_POINTER (yylval.ttype); - token = real_yylex (); - } - - if (token != END_OF_LINE) - warning ("garbage after `#pragma interface' ignored"); - - cp_pragma_interface (main_filename); - - return 1; - } - else if (! strcmp (pname, "implementation")) - { - const char *main_filename = main_input_filename ? main_input_filename : input_filename; - - main_filename = file_name_nondirectory (main_filename); - - token = real_yylex (); - - if (token != END_OF_LINE) - { - if (token != STRING - || TREE_CODE (yylval.ttype) != STRING_CST) - { - error ("invalid `#pragma implementation'"); - return -1; - } - main_filename = TREE_STRING_POINTER (yylval.ttype); - token = real_yylex (); - } - - if (token != END_OF_LINE) - warning ("garbage after `#pragma implementation' ignored"); - - cp_pragma_implementation (main_filename); - - return 1; - } - - return 0; -} - -void -do_pending_lang_change () -{ - for (; pending_lang_change > 0; --pending_lang_change) - push_lang_context (lang_name_c); - for (; pending_lang_change < 0; ++pending_lang_change) - pop_lang_context (); -} - -/* Parse a '\uNNNN' or '\UNNNNNNNN' sequence. - - [lex.charset]: The character designated by the universal-character-name - \UNNNNNNNN is that character whose character short name in ISO/IEC 10646 - is NNNNNNNN; the character designated by the universal-character-name - \uNNNN is that character whose character short name in ISO/IEC 10646 is - 0000NNNN. If the hexadecimal value for a universal character name is - less than 0x20 or in the range 0x7F-0x9F (inclusive), or if the - universal character name designates a character in the basic source - character set, then the program is ill-formed. - - We assume that wchar_t is Unicode, so we don't need to do any - mapping. Is this ever wrong? */ - -static int -read_ucs (length) - int length; -{ - unsigned int code = 0; - int c; - - for (; length; --length) - { - c = getch (); - if (! ISXDIGIT (c)) - { - error ("non hex digit '%c' in universal-character-name", c); - put_back (c); - break; - } - code <<= 4; - if (c >= 'a' && c <= 'f') - code += c - 'a' + 10; - if (c >= 'A' && c <= 'F') - code += c - 'A' + 10; - if (c >= '0' && c <= '9') - code += c - '0'; - } - -#ifdef TARGET_EBCDIC - sorry ("universal-character-name on EBCDIC target"); - return 0x3F; -#endif - - if (code > 0x9f && !(code & 0x80000000)) - /* True extended character, OK. */; - else if (code >= 0x20 && code < 0x7f) - { - /* ASCII printable character. The C character set consists of all of - these except $, @ and `. We use hex escapes so that this also - works with EBCDIC hosts. */ - if (code != 0x24 && code != 0x40 && code != 0x60) - error ("universal-character-name designates `%c', part of the basic source character set", code); - } - else - error ("invalid universal-character-name"); - return code; -} - -/* Returns nonzero if C is a universal-character-name. Give an error if it - is not one which may appear in an identifier, as per [extendid]. */ - -static inline int -is_extended_char (c) - int c; -{ -#ifdef TARGET_EBCDIC - return 0; -#else - /* ASCII. */ - if (c < 0x7f) - return 0; - - return is_extended_char_1 (c); -#endif -} - -static int -is_extended_char_1 (c) - int c; -{ - /* None of the valid chars are outside the Basic Multilingual Plane (the - low 16 bits). */ - if (c > 0xffff) - { - error ("universal-character-name `\\U%08x' not valid in identifier", c); - return 1; - } - - /* Latin */ - if ((c >= 0x00c0 && c <= 0x00d6) - || (c >= 0x00d8 && c <= 0x00f6) - || (c >= 0x00f8 && c <= 0x01f5) - || (c >= 0x01fa && c <= 0x0217) - || (c >= 0x0250 && c <= 0x02a8) - || (c >= 0x1e00 && c <= 0x1e9a) - || (c >= 0x1ea0 && c <= 0x1ef9)) - return 1; - - /* Greek */ - if ((c == 0x0384) - || (c >= 0x0388 && c <= 0x038a) - || (c == 0x038c) - || (c >= 0x038e && c <= 0x03a1) - || (c >= 0x03a3 && c <= 0x03ce) - || (c >= 0x03d0 && c <= 0x03d6) - || (c == 0x03da) - || (c == 0x03dc) - || (c == 0x03de) - || (c == 0x03e0) - || (c >= 0x03e2 && c <= 0x03f3) - || (c >= 0x1f00 && c <= 0x1f15) - || (c >= 0x1f18 && c <= 0x1f1d) - || (c >= 0x1f20 && c <= 0x1f45) - || (c >= 0x1f48 && c <= 0x1f4d) - || (c >= 0x1f50 && c <= 0x1f57) - || (c == 0x1f59) - || (c == 0x1f5b) - || (c == 0x1f5d) - || (c >= 0x1f5f && c <= 0x1f7d) - || (c >= 0x1f80 && c <= 0x1fb4) - || (c >= 0x1fb6 && c <= 0x1fbc) - || (c >= 0x1fc2 && c <= 0x1fc4) - || (c >= 0x1fc6 && c <= 0x1fcc) - || (c >= 0x1fd0 && c <= 0x1fd3) - || (c >= 0x1fd6 && c <= 0x1fdb) - || (c >= 0x1fe0 && c <= 0x1fec) - || (c >= 0x1ff2 && c <= 0x1ff4) - || (c >= 0x1ff6 && c <= 0x1ffc)) - return 1; - - /* Cyrillic */ - if ((c >= 0x0401 && c <= 0x040d) - || (c >= 0x040f && c <= 0x044f) - || (c >= 0x0451 && c <= 0x045c) - || (c >= 0x045e && c <= 0x0481) - || (c >= 0x0490 && c <= 0x04c4) - || (c >= 0x04c7 && c <= 0x04c8) - || (c >= 0x04cb && c <= 0x04cc) - || (c >= 0x04d0 && c <= 0x04eb) - || (c >= 0x04ee && c <= 0x04f5) - || (c >= 0x04f8 && c <= 0x04f9)) - return 1; - - /* Armenian */ - if ((c >= 0x0531 && c <= 0x0556) - || (c >= 0x0561 && c <= 0x0587)) - return 1; - - /* Hebrew */ - if ((c >= 0x05d0 && c <= 0x05ea) - || (c >= 0x05f0 && c <= 0x05f4)) - return 1; - - /* Arabic */ - if ((c >= 0x0621 && c <= 0x063a) - || (c >= 0x0640 && c <= 0x0652) - || (c >= 0x0670 && c <= 0x06b7) - || (c >= 0x06ba && c <= 0x06be) - || (c >= 0x06c0 && c <= 0x06ce) - || (c >= 0x06e5 && c <= 0x06e7)) - return 1; - - /* Devanagari */ - if ((c >= 0x0905 && c <= 0x0939) - || (c >= 0x0958 && c <= 0x0962)) - return 1; - - /* Bengali */ - if ((c >= 0x0985 && c <= 0x098c) - || (c >= 0x098f && c <= 0x0990) - || (c >= 0x0993 && c <= 0x09a8) - || (c >= 0x09aa && c <= 0x09b0) - || (c == 0x09b2) - || (c >= 0x09b6 && c <= 0x09b9) - || (c >= 0x09dc && c <= 0x09dd) - || (c >= 0x09df && c <= 0x09e1) - || (c >= 0x09f0 && c <= 0x09f1)) - return 1; - - /* Gurmukhi */ - if ((c >= 0x0a05 && c <= 0x0a0a) - || (c >= 0x0a0f && c <= 0x0a10) - || (c >= 0x0a13 && c <= 0x0a28) - || (c >= 0x0a2a && c <= 0x0a30) - || (c >= 0x0a32 && c <= 0x0a33) - || (c >= 0x0a35 && c <= 0x0a36) - || (c >= 0x0a38 && c <= 0x0a39) - || (c >= 0x0a59 && c <= 0x0a5c) - || (c == 0x0a5e)) - return 1; - - /* Gujarati */ - if ((c >= 0x0a85 && c <= 0x0a8b) - || (c == 0x0a8d) - || (c >= 0x0a8f && c <= 0x0a91) - || (c >= 0x0a93 && c <= 0x0aa8) - || (c >= 0x0aaa && c <= 0x0ab0) - || (c >= 0x0ab2 && c <= 0x0ab3) - || (c >= 0x0ab5 && c <= 0x0ab9) - || (c == 0x0ae0)) - return 1; - - /* Oriya */ - if ((c >= 0x0b05 && c <= 0x0b0c) - || (c >= 0x0b0f && c <= 0x0b10) - || (c >= 0x0b13 && c <= 0x0b28) - || (c >= 0x0b2a && c <= 0x0b30) - || (c >= 0x0b32 && c <= 0x0b33) - || (c >= 0x0b36 && c <= 0x0b39) - || (c >= 0x0b5c && c <= 0x0b5d) - || (c >= 0x0b5f && c <= 0x0b61)) - return 1; - - /* Tamil */ - if ((c >= 0x0b85 && c <= 0x0b8a) - || (c >= 0x0b8e && c <= 0x0b90) - || (c >= 0x0b92 && c <= 0x0b95) - || (c >= 0x0b99 && c <= 0x0b9a) - || (c == 0x0b9c) - || (c >= 0x0b9e && c <= 0x0b9f) - || (c >= 0x0ba3 && c <= 0x0ba4) - || (c >= 0x0ba8 && c <= 0x0baa) - || (c >= 0x0bae && c <= 0x0bb5) - || (c >= 0x0bb7 && c <= 0x0bb9)) - return 1; - - /* Telugu */ - if ((c >= 0x0c05 && c <= 0x0c0c) - || (c >= 0x0c0e && c <= 0x0c10) - || (c >= 0x0c12 && c <= 0x0c28) - || (c >= 0x0c2a && c <= 0x0c33) - || (c >= 0x0c35 && c <= 0x0c39) - || (c >= 0x0c60 && c <= 0x0c61)) - return 1; - - /* Kannada */ - if ((c >= 0x0c85 && c <= 0x0c8c) - || (c >= 0x0c8e && c <= 0x0c90) - || (c >= 0x0c92 && c <= 0x0ca8) - || (c >= 0x0caa && c <= 0x0cb3) - || (c >= 0x0cb5 && c <= 0x0cb9) - || (c >= 0x0ce0 && c <= 0x0ce1)) - return 1; - - /* Malayalam */ - if ((c >= 0x0d05 && c <= 0x0d0c) - || (c >= 0x0d0e && c <= 0x0d10) - || (c >= 0x0d12 && c <= 0x0d28) - || (c >= 0x0d2a && c <= 0x0d39) - || (c >= 0x0d60 && c <= 0x0d61)) - return 1; - - /* Thai */ - if ((c >= 0x0e01 && c <= 0x0e30) - || (c >= 0x0e32 && c <= 0x0e33) - || (c >= 0x0e40 && c <= 0x0e46) - || (c >= 0x0e4f && c <= 0x0e5b)) - return 1; - - /* Lao */ - if ((c >= 0x0e81 && c <= 0x0e82) - || (c == 0x0e84) - || (c == 0x0e87) - || (c == 0x0e88) - || (c == 0x0e8a) - || (c == 0x0e0d) - || (c >= 0x0e94 && c <= 0x0e97) - || (c >= 0x0e99 && c <= 0x0e9f) - || (c >= 0x0ea1 && c <= 0x0ea3) - || (c == 0x0ea5) - || (c == 0x0ea7) - || (c == 0x0eaa) - || (c == 0x0eab) - || (c >= 0x0ead && c <= 0x0eb0) - || (c == 0x0eb2) - || (c == 0x0eb3) - || (c == 0x0ebd) - || (c >= 0x0ec0 && c <= 0x0ec4) - || (c == 0x0ec6)) - return 1; - - /* Georgian */ - if ((c >= 0x10a0 && c <= 0x10c5) - || (c >= 0x10d0 && c <= 0x10f6)) - return 1; - - /* Hiragana */ - if ((c >= 0x3041 && c <= 0x3094) - || (c >= 0x309b && c <= 0x309e)) - return 1; - - /* Katakana */ - if ((c >= 0x30a1 && c <= 0x30fe)) - return 1; - - /* Bopmofo */ - if ((c >= 0x3105 && c <= 0x312c)) - return 1; - - /* Hangul */ - if ((c >= 0x1100 && c <= 0x1159) - || (c >= 0x1161 && c <= 0x11a2) - || (c >= 0x11a8 && c <= 0x11f9)) - return 1; - - /* CJK Unified Ideographs */ - if ((c >= 0xf900 && c <= 0xfa2d) - || (c >= 0xfb1f && c <= 0xfb36) - || (c >= 0xfb38 && c <= 0xfb3c) - || (c == 0xfb3e) - || (c >= 0xfb40 && c <= 0xfb41) - || (c >= 0xfb42 && c <= 0xfb44) - || (c >= 0xfb46 && c <= 0xfbb1) - || (c >= 0xfbd3 && c <= 0xfd3f) - || (c >= 0xfd50 && c <= 0xfd8f) - || (c >= 0xfd92 && c <= 0xfdc7) - || (c >= 0xfdf0 && c <= 0xfdfb) - || (c >= 0xfe70 && c <= 0xfe72) - || (c == 0xfe74) - || (c >= 0xfe76 && c <= 0xfefc) - || (c >= 0xff21 && c <= 0xff3a) - || (c >= 0xff41 && c <= 0xff5a) - || (c >= 0xff66 && c <= 0xffbe) - || (c >= 0xffc2 && c <= 0xffc7) - || (c >= 0xffca && c <= 0xffcf) - || (c >= 0xffd2 && c <= 0xffd7) - || (c >= 0xffda && c <= 0xffdc) - || (c >= 0x4e00 && c <= 0x9fa5)) - return 1; - - error ("universal-character-name `\\u%04x' not valid in identifier", c); - return 1; -} - -#if 0 -/* Add the UTF-8 representation of C to the token_buffer. */ - -static void -utf8_extend_token (c) - int c; -{ - int shift, mask; - - if (c <= 0x0000007f) - { - extend_token (c); - return; - } - else if (c <= 0x000007ff) - shift = 6, mask = 0xc0; - else if (c <= 0x0000ffff) - shift = 12, mask = 0xe0; - else if (c <= 0x001fffff) - shift = 18, mask = 0xf0; - else if (c <= 0x03ffffff) - shift = 24, mask = 0xf8; - else - shift = 30, mask = 0xfc; - - extend_token (mask | (c >> shift)); - do - { - shift -= 6; - extend_token ((unsigned char) (0x80 | (c >> shift))); - } - while (shift); -} -#endif - -#define ENDFILE -1 /* token that represents end-of-file */ - -/* Read an escape sequence, returning its equivalent as a character, - or store 1 in *ignore_ptr if it is backslash-newline. */ - -static int -readescape (ignore_ptr) - int *ignore_ptr; -{ - register int c = getch (); - register int code; - register unsigned count; - unsigned firstdig = 0; - int nonnull; - - switch (c) - { - case 'x': - code = 0; - count = 0; - nonnull = 0; - while (1) - { - c = getch (); - if (! ISXDIGIT (c)) - { - put_back (c); - break; - } - code *= 16; - if (c >= 'a' && c <= 'f') - code += c - 'a' + 10; - if (c >= 'A' && c <= 'F') - code += c - 'A' + 10; - if (c >= '0' && c <= '9') - code += c - '0'; - if (code != 0 || count != 0) - { - if (count == 0) - firstdig = code; - count++; - } - nonnull = 1; - } - if (! nonnull) - error ("\\x used with no following hex digits"); - else if (count == 0) - /* Digits are all 0's. Ok. */ - ; - else if ((count - 1) * 4 >= TYPE_PRECISION (integer_type_node) - || (count > 1 - && (((unsigned)1 - << (TYPE_PRECISION (integer_type_node) - - (count - 1) * 4)) - <= firstdig))) - pedwarn ("hex escape out of range"); - return code; - - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': - code = 0; - count = 0; - while ((c <= '7') && (c >= '0') && (count++ < 3)) - { - code = (code * 8) + (c - '0'); - c = getch (); - } - put_back (c); - return code; - - case 'U': - return read_ucs (8); - case 'u': - return read_ucs (4); - - case '\\': case '\'': case '"': - return c; - - case '\n': - lineno++; - *ignore_ptr = 1; - return 0; - - case 'n': - return TARGET_NEWLINE; - - case 't': - return TARGET_TAB; - - case 'r': - return TARGET_CR; - - case 'f': - return TARGET_FF; - - case 'b': - return TARGET_BS; - - case 'a': - return TARGET_BELL; - - case 'v': - return TARGET_VT; - - case 'e': - case 'E': - if (pedantic) - pedwarn ("non-ISO-standard escape sequence, `\\%c'", c); - return 033; - - case '?': - return c; - - /* `\(', etc, are used at beginning of line to avoid confusing Emacs. */ - case '(': - case '{': - case '[': - /* `\%' is used to prevent SCCS from getting confused. */ - case '%': - if (pedantic) - pedwarn ("unknown escape sequence `\\%c'", c); - return c; - } - if (ISGRAPH (c)) - pedwarn ("unknown escape sequence `\\%c'", c); - else - pedwarn ("unknown escape sequence: `\\' followed by char code 0x%x", c); - return c; -} - -void -yyerror (string) - const char *string; -{ - extern int end_of_file; - - /* We can't print string and character constants well - because the token_buffer contains the result of processing escapes. */ - if (end_of_file) - { - if (input_redirected ()) - error ("%s at end of saved text", string); - else - error ("%s at end of input", string); - } - else if (token_buffer[0] == 0) - error ("%s at null character", string); - else if (token_buffer[0] == '"') - error ("%s before string constant", string); - else if (token_buffer[0] == '\'') - error ("%s before character constant", string); - else if (!ISGRAPH ((unsigned char)token_buffer[0])) - error ("%s before character 0%o", string, (unsigned char) token_buffer[0]); - else - error ("%s before `%s'", string, token_buffer); -} - -/* Value is 1 (or 2) if we should try to make the next identifier look like - a typename (when it may be a local variable or a class variable). - Value is 0 if we treat this name in a default fashion. */ -int looking_for_typename; - -inline int -identifier_type (decl) - tree decl; -{ - tree t; - - if (TREE_CODE (decl) == TEMPLATE_DECL) - { - if (TREE_CODE (DECL_TEMPLATE_RESULT (decl)) == TYPE_DECL) - return PTYPENAME; - else if (looking_for_template) - return PFUNCNAME; - } - if (looking_for_template && really_overloaded_fn (decl)) - { - /* See through a baselink. */ - if (TREE_CODE (decl) == TREE_LIST) - decl = TREE_VALUE (decl); - - for (t = decl; t != NULL_TREE; t = OVL_CHAIN (t)) - if (DECL_FUNCTION_TEMPLATE_P (OVL_FUNCTION (t))) - return PFUNCNAME; - } - if (TREE_CODE (decl) == NAMESPACE_DECL) - return NSNAME; - if (TREE_CODE (decl) != TYPE_DECL) - return IDENTIFIER; - if (DECL_ARTIFICIAL (decl) && TREE_TYPE (decl) == current_class_type) - return SELFNAME; - - /* A constructor declarator for a template type will get here as an - implicit typename, a TYPENAME_TYPE with a type. */ - t = got_scope; - if (t && TREE_CODE (t) == TYPENAME_TYPE) - t = TREE_TYPE (t); - decl = TREE_TYPE (decl); - if (TREE_CODE (decl) == TYPENAME_TYPE) - decl = TREE_TYPE (decl); - if (t && t == decl) - return SELFNAME; - - return TYPENAME; -} - -void -see_typename () -{ - /* Only types expected, not even namespaces. */ - looking_for_typename = 2; - if (yychar < 0) - if ((yychar = yylex ()) < 0) yychar = 0; - looking_for_typename = 0; - if (yychar == IDENTIFIER) - { - lastiddecl = lookup_name (yylval.ttype, -2); - if (lastiddecl == 0) - { - if (flag_labels_ok) - lastiddecl = IDENTIFIER_LABEL_VALUE (yylval.ttype); - } - else - yychar = identifier_type (lastiddecl); - } -} - -/* Return true if d is in a global scope. */ - -static int -is_global (d) - tree d; -{ - while (1) - switch (TREE_CODE (d)) - { - case ERROR_MARK: - return 1; - - case OVERLOAD: d = OVL_FUNCTION (d); continue; - case TREE_LIST: d = TREE_VALUE (d); continue; - default: - my_friendly_assert (DECL_P (d), 980629); - - return DECL_NAMESPACE_SCOPE_P (d); - } -} - -tree -do_identifier (token, parsing, args) - register tree token; - int parsing; - tree args; -{ - register tree id; - int lexing = (parsing == 1); - - if (! lexing || IDENTIFIER_OPNAME_P (token)) - id = lookup_name (token, 0); - else - id = lastiddecl; - - /* Do Koenig lookup if appropriate (inside templates we build lookup - expressions instead). - - [basic.lookup.koenig]: If the ordinary unqualified lookup of the name - finds the declaration of a class member function, the associated - namespaces and classes are not considered. */ + [basic.lookup.koenig]: If the ordinary unqualified lookup of the name + finds the declaration of a class member function, the associated + namespaces and classes are not considered. */ if (args && !current_template_parms && (!id || is_global (id))) id = lookup_arg_dependent (token, id, args); @@ -3187,9 +1392,6 @@ do_identifier (token, parsing, args) local variables and then finding matching instantiations. */ if (current_template_parms && (is_overloaded_fn (id) - /* Some local VAR_DECLs (such as those for local variables - in member functions of local classes) are built on the - permanent obstack. */ || (TREE_CODE (id) == VAR_DECL && CP_DECL_CONTEXT (id) && TREE_CODE (CP_DECL_CONTEXT (id)) == FUNCTION_DECL) @@ -3295,1386 +1497,6 @@ identifier_typedecl_value (node) return NULL_TREE; } -struct pf_args -{ - /* Input */ - int base; - char * p; - /* I/O */ - int c; - /* Output */ - int imag; - tree type; - int conversion_errno; - REAL_VALUE_TYPE value; -}; - -static void -parse_float (data) - PTR data; -{ - struct pf_args * args = (struct pf_args *) data; - int fflag = 0, lflag = 0; - /* Copy token_buffer now, while it has just the number - and not the suffixes; once we add `f' or `i', - REAL_VALUE_ATOF may not work any more. */ - char *copy = (char *) alloca (args->p - token_buffer + 1); - bcopy (token_buffer, copy, args->p - token_buffer + 1); - args->imag = 0; - args->conversion_errno = 0; - args->type = double_type_node; - - while (1) - { - int lose = 0; - - /* Read the suffixes to choose a data type. */ - switch (args->c) - { - case 'f': case 'F': - if (fflag) - error ("more than one `f' in numeric constant"); - fflag = 1; - break; - - case 'l': case 'L': - if (lflag) - error ("more than one `l' in numeric constant"); - lflag = 1; - break; - - case 'i': case 'I': - if (args->imag) - error ("more than one `i' or `j' in numeric constant"); - else if (pedantic) - pedwarn ("ISO C++ forbids imaginary numeric constants"); - args->imag = 1; - break; - - default: - lose = 1; - } - - if (lose) - break; - - if (args->p >= token_buffer + maxtoken - 3) - args->p = extend_token_buffer (args->p); - *(args->p++) = args->c; - *(args->p) = 0; - args->c = getch (); - } - - /* The second argument, machine_mode, of REAL_VALUE_ATOF - tells the desired precision of the binary result - of decimal-to-binary conversion. */ - - if (fflag) - { - if (lflag) - error ("both `f' and `l' in floating constant"); - - args->type = float_type_node; - errno = 0; - if (args->base == 16) - args->value = REAL_VALUE_HTOF (copy, TYPE_MODE (args->type)); - else - args->value = REAL_VALUE_ATOF (copy, TYPE_MODE (args->type)); - args->conversion_errno = errno; - /* A diagnostic is required here by some ANSI C testsuites. - This is not pedwarn, because some people don't want - an error for this. */ - if (REAL_VALUE_ISINF (args->value) && pedantic) - warning ("floating point number exceeds range of `float'"); - } - else if (lflag) - { - args->type = long_double_type_node; - errno = 0; - if (args->base == 16) - args->value = REAL_VALUE_HTOF (copy, TYPE_MODE (args->type)); - else - args->value = REAL_VALUE_ATOF (copy, TYPE_MODE (args->type)); - args->conversion_errno = errno; - if (REAL_VALUE_ISINF (args->value) && pedantic) - warning ("floating point number exceeds range of `long double'"); - } - else - { - errno = 0; - if (args->base == 16) - args->value = REAL_VALUE_HTOF (copy, TYPE_MODE (args->type)); - else - args->value = REAL_VALUE_ATOF (copy, TYPE_MODE (args->type)); - args->conversion_errno = errno; - if (REAL_VALUE_ISINF (args->value) && pedantic) - warning ("floating point number exceeds range of `double'"); - } -} - -/* Get the next character, staying within the current token if possible. - If we're lexing a token, we don't want to look beyond the end of the - token cpplib has prepared for us; otherwise, we end up reading in the - next token, which screws up feed_input. So just return a null - character. */ - -static int -token_getch () -{ -#if USE_CPPLIB - if (yy_cur == yy_lim) - return '\0'; -#endif - return getch (); -} - -static void -token_put_back (ch) - int ch; -{ -#if USE_CPPLIB - if (ch == '\0') - return; -#endif - put_back (ch); -} - -/* Read a single token from the input stream, and assign it lexical - semantics. - - Note: We used to do token pasting here, to produce compound tokens like - LEFT_RIGHT and EXTERN_LANG_STRING. That's now handled in spew.c, along - with symbol table interaction and other context-sensitivity. */ - -int -real_yylex () -{ - register int c; - register char *p; - register int value; - int wide_flag = 0; - - c = getch (); - - /* Effectively do c = skip_white_space (c) - but do it faster in the usual cases. */ - while (1) - switch (c) - { - case ' ': - case '\t': - case '\f': - case '\v': - case '\b': -#if USE_CPPLIB - if (cpp_token == CPP_HSPACE) - c = yy_get_token (); - else -#endif - c = getch (); - break; - - case '\r': - /* Call skip_white_space so we can warn if appropriate. */ - - case '\n': - case '/': - case '\\': - c = skip_white_space (c); - default: - goto found_nonwhite; - } - found_nonwhite: - - token_buffer[0] = c; - token_buffer[1] = 0; - -/* yylloc.first_line = lineno; */ - - switch (c) - { - case EOF: - end_of_file = 1; - token_buffer[0] = 0; - if (linemode) - value = END_OF_LINE; - else if (input_redirected ()) - value = END_OF_SAVED_INPUT; - else - value = ENDFILE; - break; - - case 'L': -#if USE_CPPLIB - if (cpp_token == CPP_NAME) - goto letter; -#endif - /* Capital L may start a wide-string or wide-character constant. */ - { - register int c = token_getch (); - if (c == '\'') - { - wide_flag = 1; - goto char_constant; - } - if (c == '"') - { - wide_flag = 1; - goto string_constant; - } - token_put_back (c); - } - - case 'A': case 'B': case 'C': case 'D': case 'E': - case 'F': case 'G': case 'H': case 'I': case 'J': - case 'K': case 'M': case 'N': case 'O': - case 'P': case 'Q': case 'R': case 'S': case 'T': - case 'U': case 'V': case 'W': case 'X': case 'Y': - case 'Z': - case 'a': case 'b': case 'c': case 'd': case 'e': - case 'f': case 'g': case 'h': case 'i': case 'j': - case 'k': case 'l': case 'm': case 'n': case 'o': - case 'p': case 'q': case 'r': case 's': case 't': - case 'u': case 'v': case 'w': case 'x': case 'y': - case 'z': - case '_': - case '$': - letter: -#if USE_CPPLIB - if (cpp_token == CPP_NAME) - { - /* Note that one character has already been read from - yy_cur into token_buffer. Also, cpplib complains about - $ in identifiers, so we don't have to. */ - - int len = yy_lim - yy_cur + 1; - if (len >= maxtoken) - extend_token_buffer_to (len + 1); - memcpy (token_buffer + 1, yy_cur, len); - p = token_buffer + len; - yy_cur = yy_lim; - } - else -#endif - { - p = token_buffer; - while (1) - { - /* Make sure this char really belongs in an identifier. */ - if (ISALNUM (c) || c == '_') - /* OK */; - else if (c == '$') - { - if (! dollars_in_ident) - error ("`$' in identifier"); - else if (pedantic) - pedwarn ("`$' in identifier"); - } - /* FIXME we should use some sort of multibyte character - encoding. Locale-dependent? Always UTF-8? */ - else if (is_extended_char (c)) - { - sorry ("universal characters in identifiers"); - c = '_'; - } - else - break; - - if (p >= token_buffer + maxtoken) - p = extend_token_buffer (p); - - *p++ = c; - - idtryagain: - c = token_getch (); - - if (c == '\\') - { - int ignore = 0; - c = readescape (&ignore); - if (ignore) - goto idtryagain; - } - } - - *p = 0; - token_put_back (c); - } - - value = IDENTIFIER; - yylval.itype = 0; - - /* Try to recognize a keyword. Uses minimum-perfect hash function */ - - { - register struct resword *ptr; - - if ((ptr = is_reserved_word (token_buffer, p - token_buffer))) - { - if (ptr->rid) - { - if (ptr->token == VISSPEC) - { - switch (ptr->rid) - { - case RID_PUBLIC: - yylval.ttype = access_public_node; - break; - case RID_PRIVATE: - yylval.ttype = access_private_node; - break; - case RID_PROTECTED: - yylval.ttype = access_protected_node; - break; - default: - my_friendly_abort (63); - } - } - else - yylval.ttype = ridpointers[(int) ptr->rid]; - } - else switch (ptr->token) - { - case EQCOMPARE: - yylval.code = NE_EXPR; - token_buffer[0] = '!'; - token_buffer[1] = '='; - token_buffer[2] = 0; - break; - - case ASSIGN: - if (strcmp ("and_eq", token_buffer) == 0) - { - yylval.code = BIT_AND_EXPR; - token_buffer[0] = '&'; - } - else if (strcmp ("or_eq", token_buffer) == 0) - { - yylval.code = BIT_IOR_EXPR; - token_buffer[0] = '|'; - } - else if (strcmp ("xor_eq", token_buffer) == 0) - { - yylval.code = BIT_XOR_EXPR; - token_buffer[0] = '^'; - } - token_buffer[1] = '='; - token_buffer[2] = 0; - break; - - case '&': - yylval.code = BIT_AND_EXPR; - token_buffer[0] = '&'; - token_buffer[1] = 0; - break; - - case '|': - yylval.code = BIT_IOR_EXPR; - token_buffer[0] = '|'; - token_buffer[1] = 0; - break; - - case '^': - yylval.code = BIT_XOR_EXPR; - token_buffer[0] = '^'; - token_buffer[1] = 0; - break; - } - - value = (int) ptr->token; - } - } - - /* If we did not find a keyword, look for an identifier - (or a typename). */ - - if (value == IDENTIFIER || value == TYPESPEC) - GNU_xref_ref (current_function_decl, token_buffer); - - if (value == IDENTIFIER) - { - register tree tmp = get_identifier (token_buffer); - -#if !defined(VMS) && defined(JOINER) - /* Make sure that user does not collide with our internal - naming scheme. */ - if (JOINER == '$' - && (THIS_NAME_P (tmp) - || VPTR_NAME_P (tmp) - || DESTRUCTOR_NAME_P (tmp) - || VTABLE_NAME_P (tmp) - || TEMP_NAME_P (tmp) - || ANON_AGGRNAME_P (tmp) - || ANON_PARMNAME_P (tmp))) - warning ("identifier name `%s' conflicts with GNU C++ internal naming strategy", - token_buffer); -#endif - - yylval.ttype = tmp; - } - if (value == NEW && ! global_bindings_p ()) - { - value = NEW; - goto done; - } - break; - - case '.': -#if USE_CPPLIB - if (yy_cur < yy_lim) -#endif - { - /* It's hard to preserve tokenization on '.' because - it could be a symbol by itself, or it could be the - start of a floating point number and cpp won't tell us. */ - register int c1 = token_getch (); - token_buffer[1] = c1; - if (c1 == '*') - { - value = DOT_STAR; - token_buffer[2] = 0; - goto done; - } - if (c1 == '.') - { - c1 = token_getch (); - if (c1 == '.') - { - token_buffer[2] = c1; - token_buffer[3] = 0; - value = ELLIPSIS; - goto done; - } - error ("parse error at `..'"); - } - if (ISDIGIT (c1)) - { - token_put_back (c1); - goto number; - } - token_put_back (c1); - } - value = '.'; - token_buffer[1] = 0; - break; - - case '0': case '1': - /* Optimize for most frequent case. */ - { - register int cond; - -#if USE_CPPLIB - cond = (yy_cur == yy_lim); -#else - register int c1 = token_getch (); - token_put_back (c1); - cond = (! ISALNUM (c1) && c1 != '.'); -#endif - if (cond) - { - yylval.ttype = (c == '0') ? integer_zero_node : integer_one_node; - value = CONSTANT; - break; - } - /*FALLTHRU*/ - } - case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - number: - { - int base = 10; - int count = 0; - int largest_digit = 0; - int numdigits = 0; - int overflow = 0; - - /* We actually store only HOST_BITS_PER_CHAR bits in each part. - The code below which fills the parts array assumes that a host - int is at least twice as wide as a host char, and that - HOST_BITS_PER_WIDE_INT is an even multiple of HOST_BITS_PER_CHAR. - Two HOST_WIDE_INTs is the largest int literal we can store. - In order to detect overflow below, the number of parts (TOTAL_PARTS) - must be exactly the number of parts needed to hold the bits - of two HOST_WIDE_INTs. */ -#define TOTAL_PARTS ((HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR) * 2) - unsigned int parts[TOTAL_PARTS]; - - enum anon1 { NOT_FLOAT, AFTER_POINT, TOO_MANY_POINTS, AFTER_EXPON } - floatflag = NOT_FLOAT; - - for (count = 0; count < TOTAL_PARTS; count++) - parts[count] = 0; - - p = token_buffer; - *p++ = c; - - if (c == '0') - { - *p++ = (c = token_getch ()); - if ((c == 'x') || (c == 'X')) - { - base = 16; - *p++ = (c = token_getch ()); - } - /* Leading 0 forces octal unless the 0 is the only digit. */ - else if (c >= '0' && c <= '9') - { - base = 8; - numdigits++; - } - else - numdigits++; - } - - /* Read all the digits-and-decimal-points. */ - - while (c == '.' - || (ISALNUM (c) && c != 'l' && c != 'L' - && c != 'u' && c != 'U' - && c != 'i' && c != 'I' && c != 'j' && c != 'J' - && (floatflag == NOT_FLOAT - || ((base != 16) && (c != 'f') && (c != 'F')) - || base == 16))) - { - if (c == '.') - { - if (base == 16 && pedantic) - pedwarn ("floating constant may not be in radix 16"); - if (floatflag == TOO_MANY_POINTS) - /* We have already emitted an error. Don't need another. */ - ; - else if (floatflag == AFTER_POINT || floatflag == AFTER_EXPON) - { - error ("malformed floating constant"); - floatflag = TOO_MANY_POINTS; - /* Avoid another error from atof by forcing all characters - from here on to be ignored. */ - p[-1] = '\0'; - } - else - floatflag = AFTER_POINT; - - if (base == 8) - base = 10; - *p++ = c = token_getch (); - /* Accept '.' as the start of a floating-point number - only when it is followed by a digit. */ - if (p == token_buffer + 2 && !ISDIGIT (c)) - my_friendly_abort (990710); - } - else - { - /* It is not a decimal point. - It should be a digit (perhaps a hex digit). */ - - if (ISDIGIT (c)) - { - c = c - '0'; - } - else if (base <= 10) - { - if (c == 'e' || c == 'E') - { - base = 10; - floatflag = AFTER_EXPON; - break; /* start of exponent */ - } - error ("nondigits in number and not hexadecimal"); - c = 0; - } - else if (base == 16 && (c == 'p' || c == 'P')) - { - floatflag = AFTER_EXPON; - break; /* start of exponent */ - } - else if (c >= 'a') - { - c = c - 'a' + 10; - } - else - { - c = c - 'A' + 10; - } - if (c >= largest_digit) - largest_digit = c; - numdigits++; - - for (count = 0; count < TOTAL_PARTS; count++) - { - parts[count] *= base; - if (count) - { - parts[count] - += (parts[count-1] >> HOST_BITS_PER_CHAR); - parts[count-1] - &= (1 << HOST_BITS_PER_CHAR) - 1; - } - else - parts[0] += c; - } - - /* If the highest-order part overflows (gets larger than - a host char will hold) then the whole number has - overflowed. Record this and truncate the highest-order - part. */ - if (parts[TOTAL_PARTS - 1] >> HOST_BITS_PER_CHAR) - { - overflow = 1; - parts[TOTAL_PARTS - 1] &= (1 << HOST_BITS_PER_CHAR) - 1; - } - - if (p >= token_buffer + maxtoken - 3) - p = extend_token_buffer (p); - *p++ = (c = token_getch ()); - } - } - - /* This can happen on input like `int i = 0x;' */ - if (numdigits == 0) - error ("numeric constant with no digits"); - - if (largest_digit >= base) - error ("numeric constant contains digits beyond the radix"); - - /* Remove terminating char from the token buffer and delimit the - string. */ - *--p = 0; - - if (floatflag != NOT_FLOAT) - { - tree type; - int imag, conversion_errno; - REAL_VALUE_TYPE value; - struct pf_args args; - - /* Read explicit exponent if any, and put it in tokenbuf. */ - - if ((base == 10 && ((c == 'e') || (c == 'E'))) - || (base == 16 && (c == 'p' || c == 'P'))) - { - if (p >= token_buffer + maxtoken - 3) - p = extend_token_buffer (p); - *p++ = c; - c = token_getch (); - if ((c == '+') || (c == '-')) - { - *p++ = c; - c = token_getch (); - } - /* Exponent is decimal, even if string is a hex float. */ - if (! ISDIGIT (c)) - error ("floating constant exponent has no digits"); - while (ISDIGIT (c)) - { - if (p >= token_buffer + maxtoken - 3) - p = extend_token_buffer (p); - *p++ = c; - c = token_getch (); - } - } - if (base == 16 && floatflag != AFTER_EXPON) - error ("hexadecimal floating constant has no exponent"); - - *p = 0; - - /* Setup input for parse_float() */ - args.base = base; - args.p = p; - args.c = c; - - /* Convert string to a double, checking for overflow. */ - if (do_float_handler (parse_float, (PTR) &args)) - { - /* Receive output from parse_float() */ - value = args.value; - } - else - { - /* We got an exception from parse_float() */ - error ("floating constant out of range"); - value = dconst0; - } - - /* Receive output from parse_float() */ - c = args.c; - imag = args.imag; - type = args.type; - conversion_errno = args.conversion_errno; - -#ifdef ERANGE - /* ERANGE is also reported for underflow, - so test the value to distinguish overflow from that. */ - if (conversion_errno == ERANGE && pedantic - && (REAL_VALUES_LESS (dconst1, value) - || REAL_VALUES_LESS (value, dconstm1))) - warning ("floating point number exceeds range of `double'"); -#endif - - /* If the result is not a number, assume it must have been - due to some error message above, so silently convert - it to a zero. */ - if (REAL_VALUE_ISNAN (value)) - value = dconst0; - - /* Create a node with determined type and value. */ - if (imag) - yylval.ttype = build_complex (NULL_TREE, - convert (type, integer_zero_node), - build_real (type, value)); - else - yylval.ttype = build_real (type, value); - } - else - { - tree type; - HOST_WIDE_INT high, low; - int spec_unsigned = 0; - int spec_long = 0; - int spec_long_long = 0; - int spec_imag = 0; - int warn = 0; - int i; - - while (1) - { - if (c == 'u' || c == 'U') - { - if (spec_unsigned) - error ("two `u's in integer constant"); - spec_unsigned = 1; - } - else if (c == 'l' || c == 'L') - { - if (spec_long) - { - if (spec_long_long) - error ("three `l's in integer constant"); - else if (pedantic && ! in_system_header && warn_long_long) - pedwarn ("ISO C++ forbids long long integer constants"); - spec_long_long = 1; - } - spec_long = 1; - } - else if (c == 'i' || c == 'j' || c == 'I' || c == 'J') - { - if (spec_imag) - error ("more than one `i' or `j' in numeric constant"); - else if (pedantic) - pedwarn ("ISO C++ forbids imaginary numeric constants"); - spec_imag = 1; - } - else - break; - if (p >= token_buffer + maxtoken - 3) - p = extend_token_buffer (p); - *p++ = c; - c = token_getch (); - } - - /* If the literal overflowed, pedwarn about it now. */ - if (overflow) - { - warn = 1; - pedwarn ("integer constant is too large for this configuration of the compiler - truncated to %d bits", HOST_BITS_PER_WIDE_INT * 2); - } - - /* This is simplified by the fact that our constant - is always positive. */ - - high = low = 0; - - for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR; i++) - { - high |= ((HOST_WIDE_INT) parts[i + (HOST_BITS_PER_WIDE_INT - / HOST_BITS_PER_CHAR)] - << (i * HOST_BITS_PER_CHAR)); - low |= (HOST_WIDE_INT) parts[i] << (i * HOST_BITS_PER_CHAR); - } - - yylval.ttype = build_int_2 (low, high); - TREE_TYPE (yylval.ttype) = long_long_unsigned_type_node; - - /* Calculate the ANSI type. */ - if (! spec_long && ! spec_unsigned - && int_fits_type_p (yylval.ttype, integer_type_node)) - type = integer_type_node; - else if (! spec_long && (base != 10 || spec_unsigned) - && int_fits_type_p (yylval.ttype, unsigned_type_node)) - type = unsigned_type_node; - else if (! spec_unsigned && !spec_long_long - && int_fits_type_p (yylval.ttype, long_integer_type_node)) - type = long_integer_type_node; - else if (! spec_long_long - && int_fits_type_p (yylval.ttype, - long_unsigned_type_node)) - type = long_unsigned_type_node; - else if (! spec_unsigned - && int_fits_type_p (yylval.ttype, - long_long_integer_type_node)) - type = long_long_integer_type_node; - else if (int_fits_type_p (yylval.ttype, - long_long_unsigned_type_node)) - type = long_long_unsigned_type_node; - else if (! spec_unsigned - && int_fits_type_p (yylval.ttype, - widest_integer_literal_type_node)) - type = widest_integer_literal_type_node; - else - type = widest_unsigned_literal_type_node; - - if (pedantic && !spec_long_long && !warn - && (TYPE_PRECISION (long_integer_type_node) - < TYPE_PRECISION (type))) - { - warn = 1; - pedwarn ("integer constant larger than the maximum value of an unsigned long int"); - } - - if (base == 10 && ! spec_unsigned && TREE_UNSIGNED (type)) - warning ("decimal constant is so large that it is unsigned"); - - if (spec_imag) - { - if (TYPE_PRECISION (type) - <= TYPE_PRECISION (integer_type_node)) - yylval.ttype - = build_complex (NULL_TREE, integer_zero_node, - convert (integer_type_node, - yylval.ttype)); - else - error ("complex integer constant is too wide for `__complex int'"); - } - else - TREE_TYPE (yylval.ttype) = type; - - - /* If it's still an integer (not a complex), and it doesn't - fit in the type we choose for it, then pedwarn. */ - - if (! warn - && TREE_CODE (TREE_TYPE (yylval.ttype)) == INTEGER_TYPE - && ! int_fits_type_p (yylval.ttype, TREE_TYPE (yylval.ttype))) - pedwarn ("integer constant is larger than the maximum value for its type"); - } - - token_put_back (c); - *p = 0; - - if (ISALNUM (c) || c == '.' || c == '_' || c == '$' - || ((c == '-' || c == '+') - && (p[-1] == 'e' || p[-1] == 'E'))) - error ("missing white space after number `%s'", token_buffer); - - value = CONSTANT; break; - } - - case '\'': - char_constant: - { - register int result = 0; - register int num_chars = 0; - int chars_seen = 0; - unsigned width = TYPE_PRECISION (char_type_node); - int max_chars; -#ifdef MULTIBYTE_CHARS - int longest_char = local_mb_cur_max (); - local_mbtowc (NULL_PTR, NULL_PTR, 0); -#endif - - max_chars = TYPE_PRECISION (integer_type_node) / width; - if (wide_flag) - width = WCHAR_TYPE_SIZE; - - while (1) - { - tryagain: - c = token_getch (); - - if (c == '\'' || c == EOF) - break; - - ++chars_seen; - if (c == '\\') - { - int ignore = 0; - c = readescape (&ignore); - if (ignore) - goto tryagain; - if (width < HOST_BITS_PER_INT - && (unsigned) c >= ((unsigned)1 << width)) - pedwarn ("escape sequence out of range for character"); -#ifdef MAP_CHARACTER - if (ISPRINT (c)) - c = MAP_CHARACTER (c); -#endif - } - else if (c == '\n') - { - if (pedantic) - pedwarn ("ISO C++ forbids newline in character constant"); - lineno++; - } - else - { -#ifdef MULTIBYTE_CHARS - wchar_t wc; - int i; - int char_len = -1; - for (i = 1; i <= longest_char; ++i) - { - if (i > maxtoken - 4) - extend_token_buffer (token_buffer); - - token_buffer[i] = c; - char_len = local_mbtowc (& wc, - token_buffer + 1, - i); - if (char_len != -1) - break; - c = token_getch (); - } - if (char_len > 1) - { - /* mbtowc sometimes needs an extra char before accepting */ - if (char_len < i) - token_put_back (c); - if (! wide_flag) - { - /* Merge character into result; ignore excess chars. */ - for (i = 1; i <= char_len; ++i) - { - if (i > max_chars) - break; - if (width < HOST_BITS_PER_INT) - result = (result << width) - | (token_buffer[i] - & ((1 << width) - 1)); - else - result = token_buffer[i]; - } - num_chars += char_len; - goto tryagain; - } - c = wc; - } - else - { - if (char_len == -1) - { - warning ("Ignoring invalid multibyte character"); - /* Replace all but the first byte. */ - for (--i; i > 1; --i) - token_put_back (token_buffer[i]); - wc = token_buffer[1]; - } -#ifdef MAP_CHARACTER - c = MAP_CHARACTER (wc); -#else - c = wc; -#endif - } -#else /* ! MULTIBYTE_CHARS */ -#ifdef MAP_CHARACTER - c = MAP_CHARACTER (c); -#endif -#endif /* ! MULTIBYTE_CHARS */ - } - - if (wide_flag) - { - if (chars_seen == 1) /* only keep the first one */ - result = c; - goto tryagain; - } - - /* Merge character into result; ignore excess chars. */ - num_chars += (width / TYPE_PRECISION (char_type_node)); - if (num_chars < max_chars + 1) - { - if (width < HOST_BITS_PER_INT) - result = (result << width) | (c & ((1 << width) - 1)); - else - result = c; - } - } - - if (c != '\'') - error ("malformatted character constant"); - else if (chars_seen == 0) - error ("empty character constant"); - else if (num_chars > max_chars) - { - num_chars = max_chars; - error ("character constant too long"); - } - else if (chars_seen != 1 && warn_multichar) - warning ("multi-character character constant"); - - /* If char type is signed, sign-extend the constant. */ - if (! wide_flag) - { - int num_bits = num_chars * width; - if (num_bits == 0) - /* We already got an error; avoid invalid shift. */ - yylval.ttype = build_int_2 (0, 0); - else if (TREE_UNSIGNED (char_type_node) - || ((result >> (num_bits - 1)) & 1) == 0) - yylval.ttype - = build_int_2 (result & (~(unsigned HOST_WIDE_INT) 0 - >> (HOST_BITS_PER_WIDE_INT - num_bits)), - 0); - else - yylval.ttype - = build_int_2 (result | ~(~(unsigned HOST_WIDE_INT) 0 - >> (HOST_BITS_PER_WIDE_INT - num_bits)), - -1); - /* In C, a character constant has type 'int'; in C++, 'char'. */ - if (chars_seen <= 1) - TREE_TYPE (yylval.ttype) = char_type_node; - else - TREE_TYPE (yylval.ttype) = integer_type_node; - } - else - { - yylval.ttype = build_int_2 (result, 0); - TREE_TYPE (yylval.ttype) = wchar_type_node; - } - - value = CONSTANT; - break; - } - - case '"': - string_constant: - { - unsigned width = wide_flag ? WCHAR_TYPE_SIZE - : TYPE_PRECISION (char_type_node); -#ifdef MULTIBYTE_CHARS - int longest_char = local_mb_cur_max (); - local_mbtowc (NULL_PTR, NULL_PTR, 0); -#endif - - c = token_getch (); - p = token_buffer + 1; - - while (c != '"' && c != EOF) - { - /* ignore_escape_flag is set for reading the filename in #line. */ - if (!ignore_escape_flag && c == '\\') - { - int ignore = 0; - c = readescape (&ignore); - if (ignore) - goto skipnewline; - if (width < HOST_BITS_PER_INT - && (unsigned) c >= ((unsigned)1 << width)) - pedwarn ("escape sequence out of range for character"); - } - else if (c == '\n') - { - if (pedantic) - pedwarn ("ISO C++ forbids newline in string constant"); - lineno++; - } - else - { -#ifdef MULTIBYTE_CHARS - wchar_t wc; - int i; - int char_len = -1; - for (i = 0; i < longest_char; ++i) - { - if (p + i >= token_buffer + maxtoken) - p = extend_token_buffer (p); - p[i] = c; - - char_len = local_mbtowc (& wc, p, i + 1); - if (char_len != -1) - break; - c = token_getch (); - } - if (char_len == -1) - { - warning ("Ignoring invalid multibyte character"); - /* Replace all except the first byte. */ - token_put_back (c); - for (--i; i > 0; --i) - token_put_back (p[i]); - char_len = 1; - } - /* mbtowc sometimes needs an extra char before accepting */ - if (char_len <= i) - token_put_back (c); - if (! wide_flag) - { - p += (i + 1); - c = token_getch (); - continue; - } - c = wc; -#endif /* MULTIBYTE_CHARS */ - } - - /* Add this single character into the buffer either as a wchar_t - or as a single byte. */ - if (wide_flag) - { - unsigned width = TYPE_PRECISION (char_type_node); - unsigned bytemask = (1 << width) - 1; - int byte; - - if (p + WCHAR_BYTES > token_buffer + maxtoken) - p = extend_token_buffer (p); - - for (byte = 0; byte < WCHAR_BYTES; ++byte) - { - int value; - if (byte >= (int) sizeof (c)) - value = 0; - else - value = (c >> (byte * width)) & bytemask; - if (BYTES_BIG_ENDIAN) - p[WCHAR_BYTES - byte - 1] = value; - else - p[byte] = value; - } - p += WCHAR_BYTES; - } - else - { - if (p >= token_buffer + maxtoken) - p = extend_token_buffer (p); - *p++ = c; - } - - skipnewline: - c = token_getch (); - } - - /* Terminate the string value, either with a single byte zero - or with a wide zero. */ - if (wide_flag) - { - if (p + WCHAR_BYTES > token_buffer + maxtoken) - p = extend_token_buffer (p); - bzero (p, WCHAR_BYTES); - p += WCHAR_BYTES; - } - else - { - if (p >= token_buffer + maxtoken) - p = extend_token_buffer (p); - *p++ = 0; - } - - if (c == EOF) - error ("Unterminated string constant"); - - /* We have read the entire constant. - Construct a STRING_CST for the result. */ - - yylval.ttype = build_string (p - (token_buffer + 1), token_buffer + 1); - - if (wide_flag) - TREE_TYPE (yylval.ttype) = wchar_array_type_node; - else - TREE_TYPE (yylval.ttype) = char_array_type_node; - - value = STRING; break; - } - - case '+': - case '-': - case '&': - case '|': - case ':': - case '<': - case '>': - case '*': - case '/': - case '%': - case '^': - case '!': - case '=': - { - register int c1; - - combine: - - switch (c) - { - case '+': - yylval.code = PLUS_EXPR; break; - case '-': - yylval.code = MINUS_EXPR; break; - case '&': - yylval.code = BIT_AND_EXPR; break; - case '|': - yylval.code = BIT_IOR_EXPR; break; - case '*': - yylval.code = MULT_EXPR; break; - case '/': - yylval.code = TRUNC_DIV_EXPR; break; - case '%': - yylval.code = TRUNC_MOD_EXPR; break; - case '^': - yylval.code = BIT_XOR_EXPR; break; - case LSHIFT: - yylval.code = LSHIFT_EXPR; break; - case RSHIFT: - yylval.code = RSHIFT_EXPR; break; - case '<': - yylval.code = LT_EXPR; break; - case '>': - yylval.code = GT_EXPR; break; - } - - token_buffer[1] = c1 = token_getch (); - token_buffer[2] = 0; - - if (c1 == '=') - { - switch (c) - { - case '<': - value = ARITHCOMPARE; yylval.code = LE_EXPR; goto done; - case '>': - value = ARITHCOMPARE; yylval.code = GE_EXPR; goto done; - case '!': - value = EQCOMPARE; yylval.code = NE_EXPR; goto done; - case '=': - value = EQCOMPARE; yylval.code = EQ_EXPR; goto done; - } - value = ASSIGN; goto done; - } - else if (c == c1) - switch (c) - { - case '+': - value = PLUSPLUS; goto done; - case '-': - value = MINUSMINUS; goto done; - case '&': - value = ANDAND; goto done; - case '|': - value = OROR; goto done; - case '<': - c = LSHIFT; - goto combine; - case '>': - c = RSHIFT; - goto combine; - case ':': - value = SCOPE; - yylval.itype = 1; - goto done; - } - else if (c1 == '?' && (c == '<' || c == '>')) - { - token_buffer[3] = 0; - - c1 = token_getch (); - yylval.code = (c == '<' ? MIN_EXPR : MAX_EXPR); - if (c1 == '=') - { - /* ?= expression. */ - token_buffer[2] = c1; - value = ASSIGN; - } - else - { - value = MIN_MAX; - token_put_back (c1); - } - if (pedantic) - pedwarn ("use of `operator %s' is not standard C++", - token_buffer); - goto done; - } - else - switch (c) - { - case '-': - if (c1 == '>') - { - c1 = token_getch (); - if (c1 == '*') - value = POINTSAT_STAR; - else - { - token_put_back (c1); - value = POINTSAT; - } - goto done; - } - break; - - /* digraphs */ - case ':': - if (c1 == '>') - { value = ']'; goto done; } - break; - case '<': - if (c1 == '%') - { value = '{'; indent_level++; goto done; } - if (c1 == ':') - { value = '['; goto done; } - break; - case '%': - if (c1 == '>') - { value = '}'; indent_level--; goto done; } - break; - } - - token_put_back (c1); - token_buffer[1] = 0; - - /* Here the C frontend changes < and > to ARITHCOMPARE. We don't - do that because of templates. */ - - value = c; - break; - } - - case 0: - /* Don't make yyparse think this is eof. */ - value = 1; - break; - - case '{': - indent_level++; - value = c; - break; - - case '}': - indent_level--; - value = c; - break; - - default: - if (is_extended_char (c)) - goto letter; - value = c; - } - -done: -/* yylloc.last_line = lineno; */ -#ifdef GATHER_STATISTICS -#ifdef REDUCE_LENGTH - token_count[value] += 1; -#endif -#endif - - return value; -} - -int -is_rid (t) - tree t; -{ - return !!is_reserved_word (IDENTIFIER_POINTER (t), IDENTIFIER_LENGTH (t)); -} - #ifdef GATHER_STATISTICS /* The original for tree_node_kind is in the toplevel tree.c; changes there need to be brought into here, unless this were actually put into a header @@ -4839,33 +1661,6 @@ make_aggr_type (code) } void -dump_time_statistics () -{ - register tree prev = 0, decl, next; - int this_time = get_run_time (); - TREE_INT_CST_LOW (TIME_IDENTIFIER_TIME (this_filename_time)) - += this_time - body_time; - - fprintf (stderr, "\n******\n"); - print_time ("header files (total)", header_time); - print_time ("main file (total)", this_time - body_time); - fprintf (stderr, "ratio = %g : 1\n", - (double)header_time / (double)(this_time - body_time)); - fprintf (stderr, "\n******\n"); - - for (decl = filename_times; decl; decl = next) - { - next = IDENTIFIER_GLOBAL_VALUE (decl); - SET_IDENTIFIER_GLOBAL_VALUE (decl, prev); - prev = decl; - } - - for (decl = prev; decl; decl = IDENTIFIER_GLOBAL_VALUE (decl)) - print_time (IDENTIFIER_POINTER (decl), - TREE_INT_CST_LOW (TIME_IDENTIFIER_TIME (decl))); -} - -void compiler_error VPARAMS ((const char *msg, ...)) { #ifndef ANSI_PROTOTYPES @@ -4884,7 +1679,7 @@ compiler_error VPARAMS ((const char *msg, ...)) va_end (ap); error_with_file_and_line (input_filename, lineno, "%s (compiler error)", buf); } - + /* Return the type-qualifier corresponding to the identifier given by RID. */ diff --git a/gcc/cp/lex.h b/gcc/cp/lex.h index 7d00129..1439c18 100644 --- a/gcc/cp/lex.h +++ b/gcc/cp/lex.h @@ -21,35 +21,13 @@ can know your rights and responsibilities. It should be in a file named COPYING. Among other things, the copyright notice and this notice must be preserved on all copies. */ -enum cp_rid -{ - RID_FRIEND = RID_MAX, - RID_VIRTUAL, - RID_EXPLICIT, - RID_EXPORT, - RID_MUTABLE, - RID_LAST_MODIFIER = RID_MUTABLE, - - RID_BOOL, - RID_WCHAR, - - /* C++ extension */ - RID_CLASS, - RID_RECORD, - RID_UNION, - RID_ENUM, - RID_LONGLONG, - - RID_PUBLIC, - RID_PRIVATE, - RID_PROTECTED, - RID_EXCEPTION, - RID_TEMPLATE, - RID_NULL, - /* Before adding enough to get up to 64, the RIDBIT_* macros - will have to be changed a little. */ - CP_RID_MAX -}; +#ifndef _CP_LEX_H +#define _CP_LEX_H + +#if 0 +/* Formerly, the RID_* values used as mask bits did not fit into a + single 32-bit word. Now they do, but let's preserve the old logic + in case they ever stop fitting again. -zw, 8 Aug 2000 */ /* The type that can represent all values of RIDBIT. */ /* We assume that we can stick in at least 32 bits into this. */ @@ -73,6 +51,18 @@ typedef struct { unsigned long idata[2]; } (V).idata[1] = 0; \ } while (0) #define RIDBIT_ANY_SET(V) ((V).idata[0] || (V).idata[1]) +#else +typedef unsigned long RID_BIT_TYPE; /* assumed at least 32 bits */ +#define RIDBIT_OF(R) ((unsigned long)1 << (int) (R)) + +#define RIDBIT_SETP(N, V) ((V) & RIDBIT_OF (N)) +#define RIDBIT_NOTSETP(N, V) (! ((V) & RIDBIT_OF (N))) +#define RIDBIT_ANY_SET(V) (V) + +#define RIDBIT_SET(N, V) do { (V) |= RIDBIT_OF (N); } while (0) +#define RIDBIT_RESET(N, V) do { (V) &= ~RIDBIT_OF (N); } while (0) +#define RIDBIT_RESET_ALL(V) do { (V) = 0; } while (0) +#endif /* the declaration found for the last IDENTIFIER token read in. yylex must look this up to detect typedefs, which get token type TYPENAME, @@ -80,7 +70,9 @@ typedef struct { unsigned long idata[2]; } used in a context which makes it a reference to a variable. */ extern tree lastiddecl; +#if !USE_CPPLIB extern char *token_buffer; /* Pointer to token buffer. */ +#endif /* Back-door communication channel to the lexer. */ extern int looking_for_typename; @@ -97,3 +89,5 @@ extern int pending_lang_change; extern int yylex PARAMS ((void)); extern struct lang_decl *free_lang_decl_chain; + +#endif /* _CP_LEX_H */ diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y index eb6a01a..5c69e10 100644 --- a/gcc/cp/parse.y +++ b/gcc/cp/parse.y @@ -51,8 +51,6 @@ const char * const language_string = "GNU C++"; extern struct obstack permanent_obstack; -extern int end_of_file; - /* Like YYERROR but do call yyerror. */ #define YYERROR1 { yyerror ("syntax error"); YYERROR; } @@ -220,8 +218,8 @@ cp_parse_init () tree ttype; char *strtype; enum tree_code code; - flagged_type_tree ftype; - struct pending_inline *pi; + flagged_type_tree ftype; + struct unparsed_text *pi; } /* All identifiers that are not reserved words @@ -275,7 +273,7 @@ cp_parse_init () %token NAMESPACE TYPENAME_KEYWORD USING %token LEFT_RIGHT TEMPLATE %token TYPEID DYNAMIC_CAST STATIC_CAST REINTERPRET_CAST CONST_CAST -%token SCOPE +%token SCOPE /* Define the operator tokens and their precedences. The value is an integer because, if used, it is the tree code @@ -372,7 +370,6 @@ cp_parse_init () %token PRE_PARSED_FUNCTION_DECL %type component_constructor_declarator %type fn.def2 return_id constructor_declarator -%type fn.defpen %type ctor_initializer_opt function_try_block %type named_class_head_sans_basetype %type class_head named_class_head @@ -480,22 +477,20 @@ lang_extdef: extdef: fndef eat_saved_input - { if (pending_inlines) do_pending_inlines (); } + { do_pending_inlines (); } | datadef - { if (pending_inlines) do_pending_inlines (); } + { do_pending_inlines (); } | template_def - { if (pending_inlines) do_pending_inlines (); } + { do_pending_inlines (); } | asm_keyword '(' string ')' ';' { if (TREE_CHAIN ($3)) $3 = combine_strings ($3); assemble_asm ($3); } | extern_lang_string '{' extdefs_opt '}' { pop_lang_context (); } | extern_lang_string .hush_warning fndef .warning_ok eat_saved_input - { if (pending_inlines) do_pending_inlines (); - pop_lang_context (); } + { do_pending_inlines (); pop_lang_context (); } | extern_lang_string .hush_warning datadef .warning_ok - { if (pending_inlines) do_pending_inlines (); - pop_lang_context (); } + { do_pending_inlines (); pop_lang_context (); } | NAMESPACE identifier '{' { push_namespace ($2); } extdefs_opt '}' @@ -665,16 +660,16 @@ template_def: template_extdef: fndef eat_saved_input - { if (pending_inlines) do_pending_inlines (); } + { do_pending_inlines (); } | template_datadef - { if (pending_inlines) do_pending_inlines (); } + { do_pending_inlines (); } | template_def - { if (pending_inlines) do_pending_inlines (); } + { do_pending_inlines (); } | extern_lang_string .hush_warning fndef .warning_ok eat_saved_input - { if (pending_inlines) do_pending_inlines (); + { do_pending_inlines (); pop_lang_context (); } | extern_lang_string .hush_warning template_datadef .warning_ok - { if (pending_inlines) do_pending_inlines (); + { do_pending_inlines (); pop_lang_context (); } | extension template_extdef { pedantic = $1; } @@ -814,7 +809,7 @@ fn.def2: YYERROR1; if (yychar == YYEMPTY) yychar = YYLEX; - reinit_parse_for_method (yychar, $$); } + snarf_method ($$); } | component_constructor_declarator { $$ = parse_method ($1, NULL_TREE, NULL_TREE); goto rest_of_mdef; } @@ -2163,24 +2158,18 @@ initlist: { $$ = tree_cons ($3, $5, $$); } ; -fn.defpen: - PRE_PARSED_FUNCTION_DECL - { start_function (NULL_TREE, $1->fndecl, NULL_TREE, - (SF_DEFAULT | SF_PRE_PARSED - | SF_INCLASS_INLINE)); } - pending_inline: - fn.defpen maybe_return_init ctor_initializer_opt compstmt_or_error + PRE_PARSED_FUNCTION_DECL maybe_return_init ctor_initializer_opt compstmt_or_error { expand_body (finish_function ((int)$3 | 2)); process_next_inline ($1); } - | fn.defpen maybe_return_init function_try_block + | PRE_PARSED_FUNCTION_DECL maybe_return_init function_try_block { expand_body (finish_function ((int)$3 | 2)); process_next_inline ($1); } - | fn.defpen maybe_return_init error + | PRE_PARSED_FUNCTION_DECL maybe_return_init error { finish_function (2); process_next_inline ($1); } diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 6c9a5a6..8b1efab 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -2041,8 +2041,7 @@ finish_class_definition (t, attributes, semi, pop_scope_p) void begin_inline_definitions () { - if (pending_inlines - && current_scope () == current_function_decl) + if (current_scope () == current_function_decl) do_pending_inlines (); } diff --git a/gcc/cp/spew.c b/gcc/cp/spew.c index f152642..341f772 100644 --- a/gcc/cp/spew.c +++ b/gcc/cp/spew.c @@ -20,7 +20,6 @@ along with GNU CC; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - /* This file is the type analyzer for GNU C++. To debug it, define SPEW_DEBUG when compiling parse.c and spew.c. */ @@ -29,34 +28,121 @@ Boston, MA 02111-1307, USA. */ #include "input.h" #include "tree.h" #include "cp-tree.h" +#include "cpplib.h" +#include "c-lex.h" #include "lex.h" #include "parse.h" #include "flags.h" #include "obstack.h" #include "toplev.h" +#include "ggc.h" +#include "intl.h" +#include "timevar.h" + +#ifdef SPEW_DEBUG +#define SPEW_INLINE +#else +#define SPEW_INLINE inline +#endif + +#if USE_CPPLIB +extern cpp_reader parse_in; +#endif /* This takes a token stream that hasn't decided much about types and tries to figure out as much as it can, with excessive lookahead and backtracking. */ /* fifo of tokens recognized and available to parser. */ -struct token { +struct token +{ /* The values for YYCHAR will fit in a short. */ short yychar; - short end_of_file; + unsigned int lineno; YYSTYPE yylval; }; -static int do_aggr PARAMS ((void)); -static void scan_tokens PARAMS ((unsigned int)); +/* Since inline methods can refer to text which has not yet been seen, + we store the text of the method in a structure which is placed in the + DECL_PENDING_INLINE_INFO field of the FUNCTION_DECL. + After parsing the body of the class definition, the FUNCTION_DECL's are + scanned to see which ones have this field set. Those are then digested + one at a time. + + This function's FUNCTION_DECL will have a bit set in its common so + that we know to watch out for it. */ + +struct unparsed_text +{ + struct unparsed_text *next; /* process this one next */ + tree decl; /* associated declaration */ + const char *filename; /* name of file we were processing */ + int lineno; /* line number we got the text from */ + int interface; /* remembering interface_unknown and interface_only */ + + struct token *pos; /* current position, when rescanning */ + struct token *limit; /* end of saved text */ +}; + +/* Stack of state saved off when we return to an inline method or + default argument that has been stored for later parsing. */ +struct feed +{ + struct unparsed_text *input; + const char *filename; + int lineno; + int yychar; + YYSTYPE yylval; + int first_token; + struct obstack token_obstack; + struct feed *next; +}; + +static struct obstack feed_obstack; +static struct feed *feed; + +static SPEW_INLINE void do_aggr PARAMS ((void)); +static SPEW_INLINE int identifier_type PARAMS ((tree)); +static void scan_tokens PARAMS ((int)); +static void feed_defarg PARAMS ((tree)); +static void finish_defarg PARAMS ((void)); +static int read_token PARAMS ((struct token *)); + +static SPEW_INLINE int num_tokens PARAMS ((void)); +static SPEW_INLINE struct token *nth_token PARAMS ((int)); +static SPEW_INLINE int add_token PARAMS ((struct token *)); +static SPEW_INLINE int shift_token PARAMS ((void)); +static SPEW_INLINE void push_token PARAMS ((struct token *)); +static SPEW_INLINE void consume_token PARAMS ((void)); +static SPEW_INLINE int read_process_identifier PARAMS ((YYSTYPE *)); + +static SPEW_INLINE void feed_input PARAMS ((struct unparsed_text *)); +static SPEW_INLINE void end_input PARAMS ((void)); +static SPEW_INLINE void snarf_block PARAMS ((const char *, int)); +static tree snarf_defarg PARAMS ((void)); + +/* The list of inline functions being held off until we reach the end of + the current class declaration. */ +struct unparsed_text *pending_inlines; +struct unparsed_text *pending_inlines_tail; + +/* The list of previously-deferred inline functions currently being parsed. + This exists solely to be a GC root. */ +struct unparsed_text *processing_these_inlines; + +static void begin_parsing_inclass_inline PARAMS ((struct unparsed_text *)); +static void mark_pending_inlines PARAMS ((PTR)); #ifdef SPEW_DEBUG -static int num_tokens PARAMS ((void)); -static struct token *nth_token PARAMS ((int)); -static void add_token PARAMS ((struct token *)); -static void consume_token PARAMS ((void)); -static int debug_yychar PARAMS ((int)); +int spew_debug = 0; +static unsigned int yylex_ctr = 0; + +static void debug_yychar PARAMS ((int)); + +/* In parse.y: */ +extern char *debug_yytranslate PARAMS ((int)); #endif +static enum cpp_ttype last_token; /* From lex.c: */ /* the declaration found for the last IDENTIFIER token read in. @@ -67,31 +153,324 @@ extern tree lastiddecl; /* let our brains leak out here too */ extern int yychar; /* the lookahead symbol */ extern YYSTYPE yylval; /* the semantic value of the */ /* lookahead symbol */ -extern int end_of_file; - +/* The token fifo lives in this obstack. */ struct obstack token_obstack; int first_token; - -#ifdef SPEW_DEBUG -int spew_debug = 0; -static unsigned int yylex_ctr = 0; -static int debug_yychar (); -#endif -/* Initialize token_obstack. Called once, from init_parse. */ +/* Sometimes we need to save tokens for later parsing. If so, they are + stored on this obstack. */ +struct obstack inline_text_obstack; +char *inline_text_firstobj; + +/* When we see a default argument in a method declaration, we snarf it as + text using snarf_defarg. When we get up to namespace scope, we then go + through and parse all of them using do_pending_defargs. Since yacc + parsers are not reentrant, we retain defargs state in these two + variables so that subsequent calls to do_pending_defargs can resume + where the previous call left off. */ + +static tree defarg_fns; +static tree defarg_parm; + +/* Initialize obstacks. Called once, from init_parse. */ void init_spew () { + gcc_obstack_init (&inline_text_obstack); + inline_text_firstobj = (char *) obstack_alloc (&inline_text_obstack, 0); gcc_obstack_init (&token_obstack); + gcc_obstack_init (&feed_obstack); + ggc_add_tree_root (&defarg_fns, 1); + ggc_add_tree_root (&defarg_parm, 1); + + ggc_add_root (&pending_inlines, 1, sizeof (struct unparsed_text *), + mark_pending_inlines); + ggc_add_root (&processing_these_inlines, 1, sizeof (struct unparsed_text *), + mark_pending_inlines); } -#ifdef SPEW_DEBUG -/* Use functions for debugging... */ +void +clear_inline_text_obstack () +{ + obstack_free (&inline_text_obstack, inline_text_firstobj); +} -/* Return the number of tokens available on the fifo. */ +/* Subroutine of read_token. */ +static SPEW_INLINE int +read_process_identifier (pyylval) + YYSTYPE *pyylval; +{ + tree id = pyylval->ttype; + + if (C_IS_RESERVED_WORD (id)) + { + /* Possibly replace the IDENTIFIER_NODE with a magic cookie. + Can't put yylval.code numbers in ridpointers[]. Bleah. */ + switch (C_RID_CODE (id)) + { + case RID_BITAND: pyylval->code = BIT_AND_EXPR; return '&'; + case RID_AND_EQ: pyylval->code = BIT_AND_EXPR; return ASSIGN; + case RID_BITOR: pyylval->code = BIT_IOR_EXPR; return '|'; + case RID_OR_EQ: pyylval->code = BIT_IOR_EXPR; return ASSIGN; + case RID_XOR: pyylval->code = BIT_XOR_EXPR; return '^'; + case RID_XOR_EQ: pyylval->code = BIT_XOR_EXPR; return ASSIGN; + case RID_NOT_EQ: pyylval->code = NE_EXPR; return EQCOMPARE; + + default: + if (C_RID_YYCODE (id) == TYPESPEC) + GNU_xref_ref (current_function_decl, IDENTIFIER_POINTER (id)); + + pyylval->ttype = ridpointers[C_RID_CODE (id)]; + return C_RID_YYCODE (id); + } + } + + GNU_xref_ref (current_function_decl, IDENTIFIER_POINTER (id)); + + /* Make sure that user does not collide with our internal naming + scheme. This is not necessary if '.' is used to remove them from + the user's namespace, but is if '$' or double underscores are. */ + +#if !defined(JOINER) || JOINER == '$' + if (THIS_NAME_P (id) + || VPTR_NAME_P (id) + || DESTRUCTOR_NAME_P (id) + || VTABLE_NAME_P (id) + || TEMP_NAME_P (id) + || ANON_AGGRNAME_P (id) + || ANON_PARMNAME_P (id)) + warning ( +"identifier name `%s' conflicts with GNU C++ internal naming strategy", + IDENTIFIER_POINTER (id)); +#endif + return IDENTIFIER; +} + +/* Read the next token from the input file. The token is written into + T, and its type number is returned. */ static int +read_token (t) + struct token *t; +{ + retry: + + last_token = c_lex (&t->yylval.ttype); + + switch (last_token) + { +#define YYCHAR(yy) t->yychar = yy; break; +#define YYCODE(c) t->yylval.code = c; + + case CPP_EQ: YYCHAR('='); + case CPP_NOT: YYCHAR('!'); + case CPP_GREATER: YYCODE(GT_EXPR); YYCHAR('>'); + case CPP_LESS: YYCODE(LT_EXPR); YYCHAR('<'); + case CPP_PLUS: YYCODE(PLUS_EXPR); YYCHAR('+'); + case CPP_MINUS: YYCODE(MINUS_EXPR); YYCHAR('-'); + case CPP_MULT: YYCODE(MULT_EXPR); YYCHAR('*'); + case CPP_DIV: YYCODE(TRUNC_DIV_EXPR); YYCHAR('/'); + case CPP_MOD: YYCODE(TRUNC_MOD_EXPR); YYCHAR('%'); + case CPP_AND: YYCODE(BIT_AND_EXPR); YYCHAR('&'); + case CPP_OR: YYCODE(BIT_IOR_EXPR); YYCHAR('|'); + case CPP_XOR: YYCODE(BIT_XOR_EXPR); YYCHAR('^'); + case CPP_RSHIFT: YYCODE(RSHIFT_EXPR); YYCHAR(RSHIFT); + case CPP_LSHIFT: YYCODE(LSHIFT_EXPR); YYCHAR(LSHIFT); + + case CPP_COMPL: YYCHAR('~'); + case CPP_AND_AND: YYCHAR(ANDAND); + case CPP_OR_OR: YYCHAR(OROR); + case CPP_QUERY: YYCHAR('?'); + case CPP_COLON: YYCHAR(':'); + case CPP_COMMA: YYCHAR(','); + case CPP_OPEN_PAREN: YYCHAR('('); + case CPP_CLOSE_PAREN: YYCHAR(')'); + case CPP_EQ_EQ: YYCODE(EQ_EXPR); YYCHAR(EQCOMPARE); + case CPP_NOT_EQ: YYCODE(NE_EXPR); YYCHAR(EQCOMPARE); + case CPP_GREATER_EQ:YYCODE(GE_EXPR); YYCHAR(ARITHCOMPARE); + case CPP_LESS_EQ: YYCODE(LE_EXPR); YYCHAR(ARITHCOMPARE); + + case CPP_PLUS_EQ: YYCODE(PLUS_EXPR); YYCHAR(ASSIGN); + case CPP_MINUS_EQ: YYCODE(MINUS_EXPR); YYCHAR(ASSIGN); + case CPP_MULT_EQ: YYCODE(MULT_EXPR); YYCHAR(ASSIGN); + case CPP_DIV_EQ: YYCODE(TRUNC_DIV_EXPR); YYCHAR(ASSIGN); + case CPP_MOD_EQ: YYCODE(TRUNC_MOD_EXPR); YYCHAR(ASSIGN); + case CPP_AND_EQ: YYCODE(BIT_AND_EXPR); YYCHAR(ASSIGN); + case CPP_OR_EQ: YYCODE(BIT_IOR_EXPR); YYCHAR(ASSIGN); + case CPP_XOR_EQ: YYCODE(BIT_XOR_EXPR); YYCHAR(ASSIGN); + case CPP_RSHIFT_EQ: YYCODE(RSHIFT_EXPR); YYCHAR(ASSIGN); + case CPP_LSHIFT_EQ: YYCODE(LSHIFT_EXPR); YYCHAR(ASSIGN); + + case CPP_OPEN_SQUARE: YYCHAR('['); + case CPP_CLOSE_SQUARE: YYCHAR(']'); + case CPP_OPEN_BRACE: YYCHAR('{'); + case CPP_CLOSE_BRACE: YYCHAR('}'); + case CPP_SEMICOLON: YYCHAR(';'); + case CPP_ELLIPSIS: YYCHAR(ELLIPSIS); + + case CPP_PLUS_PLUS: YYCHAR(PLUSPLUS); + case CPP_MINUS_MINUS: YYCHAR(MINUSMINUS); + case CPP_DEREF: YYCHAR(POINTSAT); + case CPP_DOT: YYCHAR('.'); + + /* These tokens are C++ specific. */ + case CPP_SCOPE: YYCHAR(SCOPE); + case CPP_DEREF_STAR: YYCHAR(POINTSAT_STAR); + case CPP_DOT_STAR: YYCHAR(DOT_STAR); + case CPP_MIN_EQ: YYCODE(MIN_EXPR); YYCHAR(ASSIGN); + case CPP_MAX_EQ: YYCODE(MAX_EXPR); YYCHAR(ASSIGN); + case CPP_MIN: YYCODE(MIN_EXPR); YYCHAR(MIN_MAX); + case CPP_MAX: YYCODE(MAX_EXPR); YYCHAR(MIN_MAX); +#undef YYCHAR +#undef YYCODE + + case CPP_EOF: +#if USE_CPPLIB + cpp_pop_buffer (&parse_in); + if (CPP_BUFFER (&parse_in)) + goto retry; +#endif + t->yychar = 0; + break; + + case CPP_NAME: + t->yychar = read_process_identifier (&t->yylval); + break; + + case CPP_INT: + case CPP_FLOAT: + case CPP_NUMBER: + case CPP_CHAR: + case CPP_WCHAR: + t->yychar = CONSTANT; + break; + + case CPP_STRING: + case CPP_WSTRING: + t->yychar = STRING; + break; + + /* This token should not be generated in C++ mode. */ + case CPP_OSTRING: + + /* These tokens should not survive translation phase 4. */ + case CPP_HASH: + case CPP_PASTE: + error ("syntax error before '#' token"); + goto retry; + + case CPP_BACKSLASH: + error ("syntax error before '\\' token"); + goto retry; + + default: + abort (); + } + + t->lineno = lineno; + return t->yychar; +} + +static SPEW_INLINE void +feed_input (input) + struct unparsed_text *input; +{ + struct feed *f; +#if 0 + if (feed) + abort (); +#endif + + f = obstack_alloc (&feed_obstack, sizeof (struct feed)); + + /* The token list starts just after the struct unparsed_text in memory. */ + input->pos = (struct token *) (input + 1); + +#ifdef SPEW_DEBUG + if (spew_debug) + fprintf (stderr, "\tfeeding %s:%d [%d tokens]\n", + input->filename, input->lineno, input->limit - input->pos); +#endif + + f->input = input; + f->filename = input_filename; + f->lineno = lineno; + f->yychar = yychar; + f->yylval = yylval; + f->first_token = first_token; + f->token_obstack = token_obstack; + f->next = feed; + + input_filename = input->filename; + lineno = input->lineno; + yychar = YYEMPTY; + yylval.ttype = NULL_TREE; + first_token = 0; + gcc_obstack_init (&token_obstack); + feed = f; +} + +static SPEW_INLINE void +end_input () +{ + struct feed *f = feed; + + input_filename = f->filename; + lineno = f->lineno; + yychar = f->yychar; + yylval = f->yylval; + first_token = f->first_token; + obstack_free (&token_obstack, 0); + token_obstack = f->token_obstack; + feed = f->next; + + obstack_free (&feed_obstack, f); + +#ifdef SPEW_DEBUG + if (spew_debug) + fprintf (stderr, "\treturning to %s:%d\n", input_filename, lineno); +#endif +} + +/* GC callback to mark memory pointed to by the pending inline queue. */ +static void +mark_pending_inlines (pi) + PTR pi; +{ + struct unparsed_text *up = * (struct unparsed_text **)pi; + + while (up) + { + struct token *t = (struct token *) (up + 1); + struct token *l = up->limit; + + while (t < l) + { + /* Some of the possible values for yychar use yylval.code + instead of yylval.ttype. We only have to worry about + yychars that could have been returned by read_token. */ + switch (t->yychar) + { + case '+': case '-': case '*': case '/': + case '%': case '&': case '|': case '^': + case '>': case '<': case LSHIFT: case RSHIFT: + case ASSIGN: case MIN_MAX: case EQCOMPARE: case ARITHCOMPARE: + t++; + continue; + } + if (t->yylval.ttype) + ggc_mark_tree (t->yylval.ttype); + t++; + } + up = up->next; + } +} + +/* Token queue management. */ + +/* Return the number of tokens available on the fifo. */ +static SPEW_INLINE int num_tokens () { return (obstack_object_size (&token_obstack) / sizeof (struct token)) @@ -100,28 +479,51 @@ num_tokens () /* Fetch the token N down the line from the head of the fifo. */ -static struct token* +static SPEW_INLINE struct token* nth_token (n) int n; { +#ifdef ENABLE_CHECKING /* could just have this do slurp_ implicitly, but this way is easier to debug... */ - my_friendly_assert (n < num_tokens (), 298); + my_friendly_assert (n >= 0 && n < num_tokens (), 298); +#endif return ((struct token*)obstack_base (&token_obstack)) + n + first_token; } -/* Add a token to the token fifo. */ +static const struct token Teosi = { END_OF_SAVED_INPUT, 0 UNION_INIT_ZERO }; +static const struct token Tpad = { EMPTY, 0 UNION_INIT_ZERO }; -static void +/* Copy the next token into T and return its value. */ +static SPEW_INLINE int add_token (t) - struct token* t; + struct token *t; { - obstack_grow (&token_obstack, t, sizeof (struct token)); + if (!feed) + return read_token (t); + + if (feed->input->pos < feed->input->limit) + { + memcpy (t, feed->input->pos, sizeof (struct token)); + return (feed->input->pos++)->yychar; + } + + memcpy (t, &Teosi, sizeof (struct token)); + return END_OF_SAVED_INPUT; +} + +/* Shift the next token onto the fifo. */ +static SPEW_INLINE int +shift_token () +{ + size_t point = obstack_object_size (&token_obstack); + obstack_blank (&token_obstack, sizeof (struct token)); + return add_token ((struct token *) (obstack_base (&token_obstack) + point)); } /* Consume the next token out of the fifo. */ -static void +static SPEW_INLINE void consume_token () { if (num_tokens () == 1) @@ -133,139 +535,235 @@ consume_token () first_token++; } -#else -/* ...otherwise use macros. */ - -#define num_tokens() \ - ((obstack_object_size (&token_obstack) / sizeof (struct token)) - first_token) - -#define nth_token(N) \ - (((struct token*)obstack_base (&token_obstack))+(N)+first_token) - -#define add_token(T) obstack_grow (&token_obstack, (T), sizeof (struct token)) +/* Push a token at the head of the queue; it will be the next token read. */ +static SPEW_INLINE void +push_token (t) + struct token *t; +{ + if (first_token == 0) /* We hope this doesn't happen often. */ + { + size_t active = obstack_object_size (&token_obstack); + obstack_blank (&token_obstack, sizeof (struct token)); + if (active) + memmove (obstack_base (&token_obstack) + sizeof (struct token), + obstack_base (&token_obstack), active); + first_token++; + } + first_token--; + memcpy (nth_token (0), t, sizeof (struct token)); +} -#define consume_token() \ - (num_tokens () == 1 \ - ? (obstack_free (&token_obstack, obstack_base (&token_obstack)), \ - (first_token = 0)) \ - : first_token++) -#endif -/* Pull in enough tokens from real_yylex that the queue is N long beyond - the current token. */ +/* Pull in enough tokens that the queue is N long beyond the current + token. */ static void scan_tokens (n) - unsigned int n; + int n; { - unsigned int i; - struct token *tmp; + int i; + int num = num_tokens (); + int yychar; + + /* First, prune any empty tokens at the end. */ + i = num; + while (i > 0 && nth_token (i - 1)->yychar == EMPTY) + i--; + if (i < num) + { + obstack_blank (&token_obstack, -((num - i) * sizeof (struct token))); + num = i; + } - /* We cannot read past certain tokens, so make sure we don't. */ - i = num_tokens (); - if (i > n) + /* Now, if we already have enough tokens, return. */ + if (num > n) return; - while (i-- > 0) + + /* Never read past these characters: they might separate + the current input stream from one we save away later. */ + for (i = 0; i < num; i++) { - tmp = nth_token (i); - /* Never read past these characters: they might separate - the current input stream from one we save away later. */ - if (tmp->yychar == '{' || tmp->yychar == ':' || tmp->yychar == ';') + yychar = nth_token (i)->yychar; + if (yychar == '{' || yychar == ':' || yychar == ';') goto pad_tokens; } while (num_tokens () <= n) { - obstack_blank (&token_obstack, sizeof (struct token)); - tmp = ((struct token *)obstack_next_free (&token_obstack))-1; - tmp->yychar = real_yylex (); - tmp->end_of_file = end_of_file; - tmp->yylval = yylval; - end_of_file = 0; - if (tmp->yychar == '{' - || tmp->yychar == ':' - || tmp->yychar == ';') - { - pad_tokens: - while (num_tokens () <= n) - { - obstack_blank (&token_obstack, sizeof (struct token)); - tmp = ((struct token *)obstack_next_free (&token_obstack))-1; - tmp->yychar = EMPTY; - tmp->end_of_file = 0; - } - } + yychar = shift_token (); + if (yychar == '{' || yychar == ':' || yychar == ';') + goto pad_tokens; } + return; + + pad_tokens: + while (num_tokens () <= n) + obstack_grow (&token_obstack, &Tpad, sizeof (struct token)); } -/* from lex.c: */ -/* Value is 1 (or 2) if we should try to make the next identifier look like - a typename (when it may be a local variable or a class variable). - Value is 0 if we treat this name in a default fashion. */ -extern int looking_for_typename; +int looking_for_typename; int looking_for_template; -extern int do_snarf_defarg; + +static int after_friend; +static int after_new; +static int do_snarf_defarg; tree got_scope; tree got_object; -int -peekyylex () +static SPEW_INLINE int +identifier_type (decl) + tree decl; +{ + tree t; + + if (TREE_CODE (decl) == TEMPLATE_DECL) + { + if (TREE_CODE (DECL_TEMPLATE_RESULT (decl)) == TYPE_DECL) + return PTYPENAME; + else if (looking_for_template) + return PFUNCNAME; + } + if (looking_for_template && really_overloaded_fn (decl)) + { + /* See through a baselink. */ + if (TREE_CODE (decl) == TREE_LIST) + decl = TREE_VALUE (decl); + + for (t = decl; t != NULL_TREE; t = OVL_CHAIN (t)) + if (DECL_FUNCTION_TEMPLATE_P (OVL_FUNCTION (t))) + return PFUNCNAME; + } + if (TREE_CODE (decl) == NAMESPACE_DECL) + return NSNAME; + if (TREE_CODE (decl) != TYPE_DECL) + return IDENTIFIER; + if (DECL_ARTIFICIAL (decl) && TREE_TYPE (decl) == current_class_type) + return SELFNAME; + + /* A constructor declarator for a template type will get here as an + implicit typename, a TYPENAME_TYPE with a type. */ + t = got_scope; + if (t && TREE_CODE (t) == TYPENAME_TYPE) + t = TREE_TYPE (t); + decl = TREE_TYPE (decl); + if (TREE_CODE (decl) == TYPENAME_TYPE) + decl = TREE_TYPE (decl); + if (t && t == decl) + return SELFNAME; + + return TYPENAME; +} + +/* token[0] == AGGR (struct/union/enum) + Thus, token[1] is either a TYPENAME or a TYPENAME_DEFN. + If token[2] == '{' or ':' then it's TYPENAME_DEFN. + It's also a definition if it's a forward declaration (as in 'struct Foo;') + which we can tell if token[2] == ';' *and* token[-1] != FRIEND or NEW. */ + +static SPEW_INLINE void +do_aggr () { - scan_tokens (0); - return nth_token (0)->yychar; + int yc1, yc2; + + scan_tokens (2); + yc1 = nth_token (1)->yychar; + if (yc1 != TYPENAME && yc1 != IDENTIFIER && yc1 != PTYPENAME) + return; + yc2 = nth_token (2)->yychar; + if (yc2 == ';') + { + /* It's a forward declaration iff we were not preceded by + 'friend' or `new'. */ + if (after_friend || after_new) + return; + } + else if (yc2 != '{' && yc2 != ':') + return; + + switch (yc1) + { + case TYPENAME: + nth_token (1)->yychar = TYPENAME_DEFN; + break; + case PTYPENAME: + nth_token (1)->yychar = PTYPENAME_DEFN; + break; + case IDENTIFIER: + nth_token (1)->yychar = IDENTIFIER_DEFN; + break; + default: + my_friendly_abort (102); + } +} + +void +see_typename () +{ + /* Only types expected, not even namespaces. */ + looking_for_typename = 2; + if (yychar < 0) + if ((yychar = yylex ()) < 0) yychar = 0; + looking_for_typename = 0; + if (yychar == IDENTIFIER) + { + lastiddecl = lookup_name (yylval.ttype, -2); + if (lastiddecl == 0) + { + if (flag_labels_ok) + lastiddecl = IDENTIFIER_LABEL_VALUE (yylval.ttype); + } + else + yychar = identifier_type (lastiddecl); + } } int yylex () { - struct token tmp_token; + int yychr; tree trrr = NULL_TREE; int old_looking_for_typename = 0; + timevar_push (TV_LEX); + retry: #ifdef SPEW_DEBUG if (spew_debug) { yylex_ctr ++; - fprintf (stderr, "\t\t## %d ##", yylex_ctr); + fprintf (stderr, "\t\t## %d @%d ", yylex_ctr, lineno); } #endif if (do_snarf_defarg) { - my_friendly_assert (num_tokens () == 0, 2837); - tmp_token.yychar = DEFARG; - tmp_token.yylval.ttype = snarf_defarg (); - tmp_token.end_of_file = 0; do_snarf_defarg = 0; - add_token (&tmp_token); + yylval.ttype = snarf_defarg (); + yychar = DEFARG; + got_object = NULL_TREE; + timevar_pop (TV_LEX); + return DEFARG; } /* if we've got tokens, send them */ else if (num_tokens ()) - tmp_token= *nth_token (0); + yychr = nth_token (0)->yychar; else - { - /* if not, grab the next one and think about it */ - tmp_token.yychar = real_yylex (); - tmp_token.yylval = yylval; - tmp_token.end_of_file = end_of_file; - add_token (&tmp_token); - } + yychr = shift_token (); /* many tokens just need to be returned. At first glance, all we have to do is send them back up, but some of them are needed to figure out local context. */ - switch (tmp_token.yychar) + switch (yychr) { case EMPTY: /* This is a lexical no-op. */ - consume_token (); #ifdef SPEW_DEBUG if (spew_debug) - debug_yychar (tmp_token.yychar); + debug_yychar (yychr); #endif + consume_token (); goto retry; case '(': @@ -273,9 +771,8 @@ yylex () if (nth_token (1)->yychar == ')') { consume_token (); - tmp_token.yychar = LEFT_RIGHT; + yychr = LEFT_RIGHT; } - consume_token (); break; case IDENTIFIER: @@ -289,12 +786,12 @@ yylex () else if (nth_token (1)->yychar == '<') looking_for_template = 1; - trrr = lookup_name (tmp_token.yylval.ttype, -2); + trrr = lookup_name (nth_token (0)->yylval.ttype, -2); if (trrr) { - tmp_token.yychar = identifier_type (trrr); - switch (tmp_token.yychar) + yychr = identifier_type (trrr); + switch (yychr) { case TYPENAME: case SELFNAME: @@ -305,7 +802,7 @@ yylex () /* If this got special lookup, remember it. In these cases, we know it can't be a declarator-id. */ if (got_scope || got_object) - tmp_token.yylval.ttype = trrr; + nth_token (0)->yylval.ttype = trrr; break; case PFUNCNAME: @@ -326,7 +823,6 @@ yylex () case TYPENAME_DEFN: case PTYPENAME: case PTYPENAME_DEFN: - consume_token (); /* If we see a SCOPE next, restore the old value. Otherwise, we got what we want. */ looking_for_typename = old_looking_for_typename; @@ -334,142 +830,581 @@ yylex () break; case SCSPEC: - if (tmp_token.yylval.ttype == ridpointers[RID_EXTERN]) + if (nth_token (0)->yylval.ttype == ridpointers[RID_EXTERN]) { scan_tokens (1); if (nth_token (1)->yychar == STRING) { - tmp_token.yychar = EXTERN_LANG_STRING; - tmp_token.yylval.ttype = get_identifier + yychr = EXTERN_LANG_STRING; + nth_token (1)->yylval.ttype = get_identifier (TREE_STRING_POINTER (nth_token (1)->yylval.ttype)); consume_token (); } } /* If export, warn that it's unimplemented and go on. */ - else if (tmp_token.yylval.ttype == ridpointers[RID_EXPORT]) + else if (nth_token (0)->yylval.ttype == ridpointers[RID_EXPORT]) { warning ("keyword 'export' not implemented and will be ignored"); +#ifdef SPEW_DEBUG + if (spew_debug) + debug_yychar (yychr); +#endif consume_token (); goto retry; } - /* do_aggr needs to check if the previous token was `friend', - so just increment first_token instead of calling consume_token. */ - ++first_token; + /* do_aggr needs to know if the previous token was `friend'. */ + else if (nth_token (0)->yylval.ttype == ridpointers[RID_FRIEND]) + after_friend = 1; + break; case NEW: - /* do_aggr needs to check if the previous token was `new', - so just increment first_token instead of calling consume_token. */ - ++first_token; + /* do_aggr needs to know if the previous token was `new'. */ + after_new = 1; break; case TYPESPEC: + case '{': + case ':': + case ';': /* If this provides a type for us, then revert lexical state to standard state. */ looking_for_typename = 0; - consume_token (); break; case AGGR: - *nth_token (0) = tmp_token; do_aggr (); - /* fall through to output... */ + after_friend = after_new = 0; + break; + case ENUM: /* Set this again, in case we are rescanning. */ looking_for_typename = 2; - /* fall through... */ + break; + default: - consume_token (); + break; } /* class member lookup only applies to the first token after the object expression, except for explicit destructor calls. */ - if (tmp_token.yychar != '~') + if (yychr != '~') got_object = NULL_TREE; - /* Clear looking_for_typename if we got 'enum { ... };'. */ - if (tmp_token.yychar == '{' || tmp_token.yychar == ':' - || tmp_token.yychar == ';') - looking_for_typename = 0; + yychar = yychr; + yylval = nth_token (0)->yylval; + lineno = nth_token (0)->lineno; - yylval = tmp_token.yylval; - yychar = tmp_token.yychar; - end_of_file = tmp_token.end_of_file; #ifdef SPEW_DEBUG if (spew_debug) - debug_yychar (yychar); + debug_yychar (yychr); #endif + consume_token (); - return yychar; + timevar_pop (TV_LEX); + return yychr; } -/* token[0] == AGGR (struct/union/enum) - Thus, token[1] is either a TYPENAME or a TYPENAME_DEFN. - If token[2] == '{' or ':' then it's TYPENAME_DEFN. - It's also a definition if it's a forward declaration (as in 'struct Foo;') - which we can tell if token[2] == ';' *and* token[-1] != FRIEND or NEW. */ +/* Unget character CH from the input stream. + If RESCAN is non-zero, then we want to `see' this + character as the next input token. */ -static int -do_aggr () +void +yyungetc (ch, rescan) + int ch; + int rescan; { - int yc1, yc2; - - scan_tokens (2); - yc1 = nth_token (1)->yychar; - if (yc1 != TYPENAME && yc1 != IDENTIFIER && yc1 != PTYPENAME) - return 0; - yc2 = nth_token (2)->yychar; - if (yc2 == ';') + /* Unget a character from the input stream. */ + if (yychar == YYEMPTY || rescan == 0) { - /* It's a forward declaration iff we were not preceded by - 'friend' or `new'. */ - if (first_token > 0) + struct token fake; + + /* If we're putting back a brace, undo the change in indent_level + from the first time we saw it. */ + if (ch == '{') + indent_level--; + else if (ch == '}') + indent_level++; + + fake.yychar = ch; + fake.yylval.ttype = 0; + fake.lineno = lineno; + + push_token (&fake); + } + else + { + yychar = ch; + } +} + + +/* Set up the state required to correctly handle the definition of the + inline function whose preparsed state has been saved in PI. */ + +static void +begin_parsing_inclass_inline (pi) + struct unparsed_text *pi; +{ + tree context; + + /* Record that we are processing the chain of inlines starting at + PI in a special GC root. */ + processing_these_inlines = pi; + + ggc_collect (); + + /* If this is an inline function in a local class, we must make sure + that we save all pertinent information about the function + surrounding the local class. */ + context = decl_function_context (pi->decl); + if (context) + push_function_context_to (context); + + feed_input (pi); + interface_unknown = pi->interface == 1; + interface_only = pi->interface == 0; + DECL_PENDING_INLINE_P (pi->decl) = 0; + DECL_PENDING_INLINE_INFO (pi->decl) = 0; + + /* Pass back a handle to the rest of the inline functions, so that they + can be processed later. */ + yychar = PRE_PARSED_FUNCTION_DECL; + yylval.pi = pi; + + start_function (NULL_TREE, pi->decl, NULL_TREE, + (SF_DEFAULT | SF_PRE_PARSED | SF_INCLASS_INLINE)); +} + +/* Called from the top level: if there are any pending inlines to + do, set up to process them now. This function sets up the first function + to be parsed; after it has been, the rule for fndef in parse.y will + call process_next_inline to start working on the next one. */ + +void +do_pending_inlines () +{ + /* Oops, we're still dealing with the last batch. */ + if (yychar == PRE_PARSED_FUNCTION_DECL) + return; + + if (pending_inlines) + { + /* Clear the chain, so that any inlines nested inside the batch + we're to process now don't refer to this batch. See e.g. + g++.other/lookup6.C. */ + struct unparsed_text *first = pending_inlines; + pending_inlines = pending_inlines_tail = 0; + + begin_parsing_inclass_inline (first); + } +} + +/* Called from the fndecl rule in the parser when the function just parsed + was declared using a PRE_PARSED_FUNCTION_DECL (i.e. came from + do_pending_inlines). */ + +void +process_next_inline (i) + struct unparsed_text *i; +{ + tree decl = i->decl; + tree context = decl_function_context (decl); + + if (context) + pop_function_context_from (context); + if (yychar == YYEMPTY) + yychar = yylex (); + if (yychar != END_OF_SAVED_INPUT) + error ("parse error at end of saved function text"); + end_input (); + + i = i->next; + if (i) + begin_parsing_inclass_inline (i); + else + { + processing_these_inlines = 0; + extract_interface_info (); + } +} + + +/* Subroutine of snarf_method, deals with actual absorption of the block. */ + +static SPEW_INLINE void +snarf_block (starting_file, starting_line) + const char *starting_file; + int starting_line; +{ + int blev = 1; + int look_for_semicolon = 0; + int look_for_lbrac = 0; + int look_for_catch = 0; + int yyc; + struct token tmp; + size_t point; + + if (yychar == '{') + /* We incremented indent_level in yylex; undo that. */ + indent_level--; + else if (yychar == '=') + look_for_semicolon = 1; + else if (yychar == ':' || yychar == RETURN_KEYWORD || yychar == TRY) + { + if (yychar == TRY) + look_for_catch = 1; + look_for_lbrac = 1; + blev = 0; + } + else + yyerror ("parse error in method specification"); + + /* The current token is the first one to be recorded. */ + tmp.yychar = yychar; + tmp.yylval = yylval; + tmp.lineno = lineno; + obstack_grow (&inline_text_obstack, &tmp, sizeof (struct token)); + + for (;;) + { + point = obstack_object_size (&inline_text_obstack); + obstack_blank (&inline_text_obstack, sizeof (struct token)); + yyc = add_token ((struct token *) + (obstack_base (&inline_text_obstack) + point)); + + if (yyc == '{') + { + look_for_lbrac = 0; + blev++; + } + else if (yyc == '}') + { + blev--; + if (blev == 0 && !look_for_semicolon) + { + if (!look_for_catch) + break; + + if (add_token (&tmp) != CATCH) + { + push_token (&tmp); + break; + } + + look_for_lbrac = 1; + obstack_grow (&inline_text_obstack, &tmp, sizeof (struct token)); + } + } + else if (yyc == ';') { - if (nth_token (-1)->yychar == SCSPEC - && nth_token (-1)->yylval.ttype == ridpointers[(int) RID_FRIEND]) - return 0; - if (nth_token (-1)->yychar == NEW) - return 0; + if (look_for_lbrac) + { + error ("function body for constructor missing"); + /* fake a { } to avoid further errors */ + tmp.yylval.ttype = 0; + tmp.yychar = '{'; + obstack_grow (&inline_text_obstack, &tmp, sizeof (struct token)); + tmp.yychar = '}'; + obstack_grow (&inline_text_obstack, &tmp, sizeof (struct token)); + break; + } + else if (look_for_semicolon && blev == 0) + break; + } + else if (yyc == 0) + { + error_with_file_and_line (starting_file, starting_line, + "end of file read inside definition"); + break; } } - else if (yc2 != '{' && yc2 != ':') - return 0; +} - switch (yc1) +/* This function stores away the text for an inline function that should + be processed later (by do_pending_inlines). */ +void +snarf_method (decl) + tree decl; +{ + int starting_lineno = lineno; + const char *starting_filename = input_filename; + size_t len; + + struct unparsed_text *meth; + + /* Leave room for the header, then absorb the block. */ + obstack_blank (&inline_text_obstack, sizeof (struct unparsed_text)); + snarf_block (starting_filename, starting_lineno); + + len = obstack_object_size (&inline_text_obstack); + meth = (struct unparsed_text *) obstack_finish (&inline_text_obstack); + + /* Happens when we get two declarations of the same function in the + same scope. */ + if (decl == void_type_node + || (current_class_type && TYPE_REDEFINED (current_class_type))) { - case TYPENAME: - nth_token (1)->yychar = TYPENAME_DEFN; - break; - case PTYPENAME: - nth_token (1)->yychar = PTYPENAME_DEFN; - break; - case IDENTIFIER: - nth_token (1)->yychar = IDENTIFIER_DEFN; - break; - default: - my_friendly_abort (102); + obstack_free (&inline_text_obstack, (char *)meth); + return; } - return 0; -} + + meth->decl = decl; + meth->filename = starting_filename; + meth->lineno = starting_lineno; + meth->limit = (struct token *) ((char *)meth + len); + meth->interface = (interface_unknown ? 1 : (interface_only ? 0 : 2)); + meth->next = 0; + +#ifdef SPEW_DEBUG + if (spew_debug) + fprintf (stderr, "\tsaved method of %d tokens from %s:%d\n", + meth->limit - (struct token *) (meth + 1), + starting_filename, starting_lineno); +#endif + + DECL_PENDING_INLINE_INFO (decl) = meth; + DECL_PENDING_INLINE_P (decl) = 1; + + if (pending_inlines_tail) + pending_inlines_tail->next = meth; + else + pending_inlines = meth; + pending_inlines_tail = meth; +} + +/* Consume a no-commas expression - a default argument - and save it + on the inline_text_obstack. */ + +static tree +snarf_defarg () +{ + int starting_lineno = lineno; + const char *starting_filename = input_filename; + int yyc; + int plev = 0; + size_t point; + size_t len; + struct unparsed_text *buf; + tree arg; + + obstack_blank (&inline_text_obstack, sizeof (struct unparsed_text)); + + for (;;) + { + point = obstack_object_size (&inline_text_obstack); + obstack_blank (&inline_text_obstack, sizeof (struct token)); + yyc = add_token ((struct token *) + (obstack_base (&inline_text_obstack) + point)); + + if (plev <= 0 && (yyc == ')' || yyc == ',')) + break; + else if (yyc == '(' || yyc == '[') + ++plev; + else if (yyc == ']' || yyc == ')') + --plev; + else if (yyc == 0) + { + error_with_file_and_line (starting_filename, starting_lineno, + "end of file read inside default argument"); + goto done; + } + } + + /* Unget the last token. */ + push_token ((struct token *) (obstack_base (&inline_text_obstack) + point)); + /* This is the documented way to shrink a growing obstack block. */ + obstack_blank (&inline_text_obstack, - sizeof (struct token)); + + done: + len = obstack_object_size (&inline_text_obstack); + buf = (struct unparsed_text *) obstack_finish (&inline_text_obstack); + + buf->decl = 0; + buf->filename = starting_filename; + buf->lineno = starting_lineno; + buf->limit = (struct token *) ((char *)buf + len); + buf->next = 0; +#ifdef SPEW_DEBUG + if (spew_debug) + fprintf (stderr, "\tsaved defarg of %d tokens from %s:%d\n", + buf->limit - (struct token *) (buf + 1), + starting_filename, starting_lineno); +#endif + + arg = make_node (DEFAULT_ARG); + DEFARG_POINTER (arg) = (char *)buf; + + return arg; +} + +/* Decide whether the default argument we are about to see should be + gobbled up as text for later parsing. */ + +void +maybe_snarf_defarg () +{ + if (current_class_type && TYPE_BEING_DEFINED (current_class_type)) + do_snarf_defarg = 1; +} + +/* Called from grokfndecl to note a function decl with unparsed default + arguments for later processing. Also called from grokdeclarator + for function types with unparsed defargs; the call from grokfndecl + will always come second, so we can overwrite the entry from the type. */ + +void +add_defarg_fn (decl) + tree decl; +{ + if (TREE_CODE (decl) == FUNCTION_DECL) + TREE_VALUE (defarg_fns) = decl; + else + defarg_fns = tree_cons (current_class_type, decl, defarg_fns); +} + +/* Helper for do_pending_defargs. Starts the parsing of a default arg. */ + +static void +feed_defarg (p) + tree p; +{ + tree d = TREE_PURPOSE (p); + + feed_input ((struct unparsed_text *)DEFARG_POINTER (d)); + yychar = DEFARG_MARKER; + yylval.ttype = p; +} + +/* Helper for do_pending_defargs. Ends the parsing of a default arg. */ + +static void +finish_defarg () +{ + if (yychar == YYEMPTY) + yychar = yylex (); + if (yychar != END_OF_SAVED_INPUT) + error ("parse error at end of saved function text"); + + end_input (); +} + +/* Main function for deferred parsing of default arguments. Called from + the parser. */ + +void +do_pending_defargs () +{ + if (defarg_parm) + finish_defarg (); + + for (; defarg_fns; defarg_fns = TREE_CHAIN (defarg_fns)) + { + tree defarg_fn = TREE_VALUE (defarg_fns); + if (defarg_parm == NULL_TREE) + { + push_nested_class (TREE_PURPOSE (defarg_fns), 1); + pushlevel (0); + if (TREE_CODE (defarg_fn) == FUNCTION_DECL) + maybe_begin_member_template_processing (defarg_fn); + + if (TREE_CODE (defarg_fn) == FUNCTION_DECL) + defarg_parm = TYPE_ARG_TYPES (TREE_TYPE (defarg_fn)); + else + defarg_parm = TYPE_ARG_TYPES (defarg_fn); + } + else + defarg_parm = TREE_CHAIN (defarg_parm); + + for (; defarg_parm; defarg_parm = TREE_CHAIN (defarg_parm)) + if (TREE_PURPOSE (defarg_parm) + && TREE_CODE (TREE_PURPOSE (defarg_parm)) == DEFAULT_ARG) + { + feed_defarg (defarg_parm); + + /* Return to the parser, which will process this defarg + and call us again. */ + return; + } + + if (TREE_CODE (defarg_fn) == FUNCTION_DECL) + { + maybe_end_member_template_processing (); + check_default_args (defarg_fn); + } + + poplevel (0, 0, 0); + pop_nested_class (); + } +} + #ifdef SPEW_DEBUG /* debug_yychar takes a yychar (token number) value and prints its name. */ -static int +static void debug_yychar (yy) int yy; { - /* In parse.y: */ - extern char *debug_yytranslate (); - - int i; - - if (yy<256) { - fprintf (stderr, "<%d: %c >\n", yy, yy); - return 0; - } - fprintf (stderr, "<%d:%s>\n", yy, debug_yytranslate (yy)); - return 1; + if (yy<256) + fprintf (stderr, "->%d < %c >\n", lineno, yy); + else if (yy == IDENTIFIER || yy == TYPENAME) + { + const char *id; + if (TREE_CODE (yylval.ttype) == IDENTIFIER_NODE) + id = IDENTIFIER_POINTER (yylval.ttype); + else if (TREE_CODE_CLASS (TREE_CODE (yylval.ttype)) == 'd') + id = IDENTIFIER_POINTER (DECL_NAME (yylval.ttype)); + else + id = ""; + fprintf (stderr, "->%d <%s `%s'>\n", lineno, debug_yytranslate (yy), id); + } + else + fprintf (stderr, "->%d <%s>\n", lineno, debug_yytranslate (yy)); } #endif + +#if USE_CPPLIB +#define NAME(type) cpp_type2name (type) +#else +/* Bleah */ +#include "symcat.h" +#define OP(e, s) s, +#define TK(e, s) STRINGX(e), + +static const char *type2name[N_TTYPES] = { TTYPE_TABLE }; +#define NAME(type) type2name[type] +#endif + +void +yyerror (msgid) + const char *msgid; +{ + const char *string = _(msgid); + + if (last_token == CPP_EOF) + error ("%s at end of input", string); + else if (last_token == CPP_CHAR || last_token == CPP_WCHAR) + { + unsigned int val = TREE_INT_CST_LOW (yylval.ttype); + const char *ell = (last_token == CPP_CHAR) ? "" : "L"; + if (val <= UCHAR_MAX && ISGRAPH (val)) + error ("%s before %s'%c'", string, ell, val); + else + error ("%s before %s'\\x%x'", string, ell, val); + } + else if (last_token == CPP_STRING + || last_token == CPP_WSTRING + || last_token == CPP_OSTRING) + error ("%s before string constant", string); + else if (last_token == CPP_NUMBER + || last_token == CPP_INT + || last_token == CPP_FLOAT) + error ("%s before numeric constant", string); + else if (last_token == CPP_NAME + && TREE_CODE (yylval.ttype) == IDENTIFIER_NODE) + error ("%s before \"%s\"", string, IDENTIFIER_POINTER (yylval.ttype)); + else + error ("%s before '%s' token", string, NAME(last_token)); +} diff --git a/gcc/flags.h b/gcc/flags.h index 21f9237..59778c6 100644 --- a/gcc/flags.h +++ b/gcc/flags.h @@ -19,6 +19,9 @@ along with GNU CC; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#ifndef GCC_FLAGS_H +#define GCC_FLAGS_H + /* Name of the input .c file being compiled. */ extern const char *main_input_filename; @@ -590,3 +593,9 @@ extern int flag_no_ident; /* Nonzero means we should do dwarf2 duplicate elimination. */ extern int flag_eliminate_dwarf2_dups; + +/* Non-zero means to collect statistics which might be expensive + and to print them when we are done. */ +extern int flag_detailed_statistics; + +#endif /* GCC_FLAGS_H */ diff --git a/gcc/gcc.c b/gcc/gcc.c index 7281fd7..e87b143 100644 --- a/gcc/gcc.c +++ b/gcc/gcc.c @@ -567,7 +567,7 @@ static const char *cpp_options = %{fshort-wchar:-U__WCHAR_TYPE__ -D__WCHAR_TYPE__=short\\ unsigned\\ int}\ %{fshow-column} %{fno-show-column}\ %{fleading-underscore} %{fno-leading-underscore}\ - %{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*} %Z %i\ + %{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{U*} %{D*} %{i*} %Z %i\ %{E:%W{o*}}%{M:%W{o*}}%{MM:%W{o*}}"; static const char *cc1_options = @@ -693,7 +693,7 @@ static struct compiler default_compilers[] = {".c", "@c"}, {"@c", #if USE_CPPLIB - "%{E|M|MM:cpp0 -lang-c %{ansi:-std=c89} %(cpp_options)}\ + "%{E|M|MM:%(trad_capable_cpp) -lang-c %{ansi:-std=c89} %(cpp_options)}\ %{!E:%{!M:%{!MM:cc1 -lang-c %{ansi:-std=c89} %(cpp_options)\ %(cc1_options) %{!fsyntax-only:%{!S:-o %{|!pipe:%g.s} |\n\ as %(asm_options) %{!pipe:%g.s} %A }}}}}" diff --git a/gcc/objc/Make-lang.in b/gcc/objc/Make-lang.in index 41a29ef..7ece705 100644 --- a/gcc/objc/Make-lang.in +++ b/gcc/objc/Make-lang.in @@ -68,7 +68,7 @@ objc-parse.o : $(srcdir)/objc/objc-parse.c \ $(CONFIG_H) $(TREE_H) $(srcdir)/toplev.h $(srcdir)/ggc.h \ $(srcdir)/c-lex.h $(srcdir)/c-tree.h $(srcdir)/c-common.h \ $(srcdir)/input.h $(srcdir)/flags.h $(srcdir)/output.h \ - $(srcdir)/objc/objc-act.h system.h + $(srcdir)/objc/objc-act.h system.h cpplib.h $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) -I$(srcdir)/objc \ -c $(srcdir)/objc/objc-parse.c @@ -88,8 +88,7 @@ objc-act.o : $(srcdir)/objc/objc-act.c \ $(CONFIG_H) $(TREE_H) $(RTL_H) system.h \ $(srcdir)/c-tree.h $(srcdir)/c-common.h $(srcdir)/c-lex.h \ $(srcdir)/toplev.h $(srcdir)/flags.h $(srcdir)/objc/objc-act.h \ - $(srcdir)/input.h $(srcdir)/function.h $(srcdir)/output.h \ - $(srcdir)/c-parse.h + $(srcdir)/input.h $(srcdir)/function.h $(srcdir)/output.h $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) -I$(srcdir)/objc \ -c $(srcdir)/objc/objc-act.c diff --git a/gcc/objc/lang-specs.h b/gcc/objc/lang-specs.h index ccd91940..d6d50e0 100644 --- a/gcc/objc/lang-specs.h +++ b/gcc/objc/lang-specs.h @@ -24,7 +24,7 @@ Boston, MA 02111-1307, USA. */ {".m", "@objective-c"}, {"@objective-c", #if USE_CPPLIB - "%{E|M|MM:cpp0 -lang-objc %{ansi:-std=c89} %(cpp_options)}\ + "%{E|M|MM:%(trad_capable_cpp) -lang-objc %{ansi:-std=c89} %(cpp_options)}\ %{!E:%{!M:%{!MM:cc1obj -lang-objc %(cpp_options) %(cc1_options) %{gen-decls}\ %{!fsyntax-only:%{!S:-o %{|!pipe:%g.s} |\n\ as %(asm_options) %{!pipe:%g.s} %A }}}}}" diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c index fd358a9..ba5837a 100644 --- a/gcc/objc/objc-act.c +++ b/gcc/objc/objc-act.c @@ -56,7 +56,6 @@ Boston, MA 02111-1307, USA. */ #if USE_CPPLIB #include "cpplib.h" extern cpp_reader parse_in; -extern cpp_options parse_options; #endif /* This is the default way of generating a method name. */ @@ -137,7 +136,6 @@ char *util_firstobj; /* for encode_method_def */ #include "rtl.h" -#include "c-parse.h" #define OBJC_VERSION (flag_next_runtime ? 5 : 8) #define PROTOCOL_VERSION 2 @@ -693,17 +691,12 @@ generate_struct_by_value_array () exit (0); } -#if USE_CPPLIB -extern char *yy_cur; -#endif - void lang_init_options () { #if USE_CPPLIB + cpp_init (); cpp_reader_init (&parse_in); - parse_in.opts = &parse_options; - cpp_options_init (&parse_options); #endif } @@ -715,16 +708,11 @@ lang_init () With luck, we discover the real source file's name from that and put it in input_filename. */ ungetc (check_newline (), finput); -#else - check_newline (); - yy_cur--; -#endif - - /* The line number can be -1 if we had -g3 and the input file - had a directive specifying line 0. But we want predefined - functions to have a line number of 0, not -1. */ - if (lineno == -1) - lineno = 0; +#endif + /* Force the line number back to 0; check_newline will have + raised it to 1, which will make the builtin functions appear + not to be built in. */ + lineno = 0; /* If gen_declaration desired, open the output file. */ if (flag_gen_declaration) @@ -800,9 +788,7 @@ lang_decode_option (argc, argv) { const char *p = argv[0]; - if (!strcmp (p, "-lang-objc")) - c_language = clk_objective_c; - else if (!strcmp (p, "-gen-decls")) + if (!strcmp (p, "-gen-decls")) flag_gen_declaration = 1; else if (!strcmp (p, "-Wselector")) warn_selector = 1; @@ -8632,3 +8618,26 @@ lookup_objc_ivar (id) else return 0; } + +/* Parser callbacks. */ +void +forget_protocol_qualifiers () +{ + C_IS_RESERVED_WORD (ridpointers[(int) RID_IN]) = 0; + C_IS_RESERVED_WORD (ridpointers[(int) RID_OUT]) = 0; + C_IS_RESERVED_WORD (ridpointers[(int) RID_INOUT]) = 0; + C_IS_RESERVED_WORD (ridpointers[(int) RID_BYCOPY]) = 0; + C_IS_RESERVED_WORD (ridpointers[(int) RID_BYREF]) = 0; + C_IS_RESERVED_WORD (ridpointers[(int) RID_ONEWAY]) = 0; +} + +void +remember_protocol_qualifiers () +{ + C_IS_RESERVED_WORD (ridpointers[(int) RID_IN]) = 1; + C_IS_RESERVED_WORD (ridpointers[(int) RID_OUT]) = 1; + C_IS_RESERVED_WORD (ridpointers[(int) RID_INOUT]) = 1; + C_IS_RESERVED_WORD (ridpointers[(int) RID_BYCOPY]) = 1; + C_IS_RESERVED_WORD (ridpointers[(int) RID_BYREF]) = 1; + C_IS_RESERVED_WORD (ridpointers[(int) RID_ONEWAY]) = 1; +} diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 8a9cd10..17f824a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,16 @@ +2000-09-06 Zack Weinberg + + * g++.old-deja/g++.benjamin/13478.C: Put meaningful tags on + ERROR markers. + * g++.old-deja/g++.brendan/crash8.C: Move ERROR marker up one line. + * gcc.dg/c99-array-nonobj-1.c: Don't expect func[] cases to fail. + * gcc.dg/wtr-label-1.c: Don't use unconstrained .* in error regexps. + * gcc.dg/wtr-suffix-1.c: Correct error regexps. + * gcc.dg/cpp/unc1.c, gcc.dg/cpp/unc2.c, gcc.dg/cpp/unc3.c: + Preprocess only. + * gcc.dg/cpp/unc4.c: Adjust line number in dg-error line. + * gcc.dg/noncompile/const-ll-1.c: Generalize error regexp. + 2000-09-06 Nathan Sidwell * g++.old-deja/g++.pt/deduct2.C: New test. @@ -57,7 +70,7 @@ 2000-09-01 Nathan Sidwell - * g++.old-deja/g++.other/nested4.C: New test. + * g++.old-deja/g++.other/nested4.C: New test. 2000-09-01 Nathan Sidwell @@ -315,7 +328,7 @@ Sun Aug 6 11:41:51 2000 Ovidiu Predescu 2000-08-05 Zack Weinberg - * gcc.c-torture/execute/20000731-1.x: Delete. + * gcc.c-torture/execute/20000731-1.x: Delete. 2000-08-04 Zack Weinberg diff --git a/gcc/testsuite/g++.old-deja/g++.benjamin/13478.C b/gcc/testsuite/g++.old-deja/g++.benjamin/13478.C index c4dba9c..55a948d 100644 --- a/gcc/testsuite/g++.old-deja/g++.benjamin/13478.C +++ b/gcc/testsuite/g++.old-deja/g++.benjamin/13478.C @@ -26,8 +26,8 @@ const hand_table Agent::table_1[] = { {0, &Agent::table_2}, {first, &Agent::foo}, - {last, &(hand)Agent::foo} // ERROR - // ERROR - -}; // ERROR - // ERROR - + {last, &(hand)Agent::foo} // ERROR - no match +}; // ERROR - cannot convert diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/crash8.C b/gcc/testsuite/g++.old-deja/g++.brendan/crash8.C index 8990c46..4de66c6 100644 --- a/gcc/testsuite/g++.old-deja/g++.brendan/crash8.C +++ b/gcc/testsuite/g++.old-deja/g++.brendan/crash8.C @@ -1,8 +1,8 @@ // Build don't link: // GROUPS passed old-abort template -class Elvis -{// ERROR - in template.* +class Elvis // ERROR - in template.* +{ } ; template diff --git a/gcc/testsuite/gcc.dg/c99-array-nonobj-1.c b/gcc/testsuite/gcc.dg/c99-array-nonobj-1.c index 5fd79eb..12e26b4 100644 --- a/gcc/testsuite/gcc.dg/c99-array-nonobj-1.c +++ b/gcc/testsuite/gcc.dg/c99-array-nonobj-1.c @@ -21,7 +21,7 @@ void g (struct s []); /* { dg-bogus "warning" "warning in place of error" } */ /* { dg-error "array" "struct \[\] arg" { xfail *-*-* } 20 } */ extern func c[]; /* { dg-bogus "warning" "warning in place of error" } */ -/* { dg-error "array" "func \[\] var" { xfail *-*-* } 23 } */ +/* { dg-error "array" "func \[\] var" { target *-*-* } 23 } */ void h (func []); /* { dg-bogus "warning" "warning in place of error" } */ -/* { dg-error "array" "func \[\] arg" { xfail *-*-* } 26 } */ +/* { dg-error "array" "func \[\] arg" { target *-*-* } 26 } */ diff --git a/gcc/testsuite/gcc.dg/cpp/unc1.c b/gcc/testsuite/gcc.dg/cpp/unc1.c index 5059ae6..18c306f 100644 --- a/gcc/testsuite/gcc.dg/cpp/unc1.c +++ b/gcc/testsuite/gcc.dg/cpp/unc1.c @@ -1,4 +1,5 @@ /* Tests for un-terminated conditionals: 1. */ +/* { dg-do preprocess } */ #if 1 /* { dg-error "unterminated" "unterminated #if" } */ diff --git a/gcc/testsuite/gcc.dg/cpp/unc2.c b/gcc/testsuite/gcc.dg/cpp/unc2.c index d9e3959..976d2b1 100644 --- a/gcc/testsuite/gcc.dg/cpp/unc2.c +++ b/gcc/testsuite/gcc.dg/cpp/unc2.c @@ -1,4 +1,5 @@ /* Tests for unterminated conditionals: 2. */ +/* { dg-do preprocess } */ #ifdef __sparc__ /* { dg-error "unterminated" "unterminated if-elif-elif..." } */ sparc diff --git a/gcc/testsuite/gcc.dg/cpp/unc3.c b/gcc/testsuite/gcc.dg/cpp/unc3.c index 9a16bb3..d5f16f7 100644 --- a/gcc/testsuite/gcc.dg/cpp/unc3.c +++ b/gcc/testsuite/gcc.dg/cpp/unc3.c @@ -1,4 +1,5 @@ /* Tests for unterminated conditionals: 3. */ +/* { dg-do preprocess } */ #if 1 /* { dg-error "#else" "unterminated #else" } */ #else diff --git a/gcc/testsuite/gcc.dg/cpp/unc4.c b/gcc/testsuite/gcc.dg/cpp/unc4.c index c486281..84ea6e4 100644 --- a/gcc/testsuite/gcc.dg/cpp/unc4.c +++ b/gcc/testsuite/gcc.dg/cpp/unc4.c @@ -37,4 +37,4 @@ ignored /* dg.exp doesn't read the included files for tags, so we have to do them explicitly here. */ -/* { dg-error "#if" "unc1.c: unterminated #if" { target *-*-* } 3 } */ +/* { dg-error "#if" "unc1.c: unterminated #if" { target *-*-* } 4 } */ diff --git a/gcc/testsuite/gcc.dg/noncompile/const-ll-1.c b/gcc/testsuite/gcc.dg/noncompile/const-ll-1.c index e38dff2..cac3af6 100644 --- a/gcc/testsuite/gcc.dg/noncompile/const-ll-1.c +++ b/gcc/testsuite/gcc.dg/noncompile/const-ll-1.c @@ -20,5 +20,5 @@ */ -unsigned long long a = 1LUL; /* { dg-error "LUL" "error for LUL suffix" } */ +unsigned long long a = 1LUL; /* { dg-error "lul|LUL" "error for LUL suffix" } */ long long b = 1Ll; /* { dg-error "Ll" "error for Ll suffix" } */ diff --git a/gcc/testsuite/gcc.dg/wtr-label-1.c b/gcc/testsuite/gcc.dg/wtr-label-1.c index b8d494e..8c7d73a 100644 --- a/gcc/testsuite/gcc.dg/wtr-label-1.c +++ b/gcc/testsuite/gcc.dg/wtr-label-1.c @@ -18,12 +18,12 @@ testfunc1 (int foo6) foo1: foo2: foo3: - foo4: /* { dg-warning "traditional C lacks.*`foo4' conflicts" "label conflicts with identifier" } */ - foo5: /* { dg-warning "traditional C lacks.*`foo5' conflicts" "label conflicts with identifier" } */ - foo6: /* { dg-warning "traditional C lacks.*`foo6' conflicts" "label conflicts with identifier" } */ - foo7: /* { dg-warning "traditional C lacks.*`foo7' conflicts" "label conflicts with identifier" } */ - testfunc1: /* { dg-warning "traditional C lacks.*`testfunc1' conflicts" "label conflicts with identifier" } */ - a: /* { dg-warning "traditional C lacks.*`a' conflicts" "label conflicts with identifier" } */ + foo4: /* { dg-warning "traditional C lacks" "label conflicts with identifier" } */ + foo5: /* { dg-warning "traditional C lacks" "label conflicts with identifier" } */ + foo6: /* { dg-warning "traditional C lacks" "label conflicts with identifier" } */ + foo7: /* { dg-warning "traditional C lacks" "label conflicts with identifier" } */ + testfunc1: /* { dg-warning "traditional C lacks" "label conflicts with identifier" } */ + a: /* { dg-warning "traditional C lacks" "label conflicts with identifier" } */ i: j: } diff --git a/gcc/testsuite/gcc.dg/wtr-suffix-1.c b/gcc/testsuite/gcc.dg/wtr-suffix-1.c index 3a16378..056dbb7 100644 --- a/gcc/testsuite/gcc.dg/wtr-suffix-1.c +++ b/gcc/testsuite/gcc.dg/wtr-suffix-1.c @@ -12,14 +12,14 @@ testfunc (void) i = 1L; i = 1l; - i = 1U; /* { dg-warning "traditional C rejects the `U' suffix" "numeric constant suffix" } */ - i = 1u; /* { dg-warning "traditional C rejects the `u' suffix" "numeric constant suffix" } */ + i = 1U; /* { dg-warning "traditional C rejects the 'u' suffix" "numeric constant suffix" } */ + i = 1u; /* { dg-warning "traditional C rejects the 'u' suffix" "numeric constant suffix" } */ f = 1.0; - f = 1.0F; /* { dg-warning "traditional C rejects the `F' suffix" "numeric constant suffix" } */ - f = 1.0f; /* { dg-warning "traditional C rejects the `f' suffix" "numeric constant suffix" } */ - f = 1.0L; /* { dg-warning "traditional C rejects the `L' suffix" "numeric constant suffix" } */ - f = 1.0l; /* { dg-warning "traditional C rejects the `l' suffix" "numeric constant suffix" } */ - + f = 1.0F; /* { dg-warning "traditional C rejects the 'f' suffix" "numeric constant suffix" } */ + f = 1.0f; /* { dg-warning "traditional C rejects the 'f' suffix" "numeric constant suffix" } */ + f = 1.0L; /* { dg-warning "traditional C rejects the 'l' suffix" "numeric constant suffix" } */ + f = 1.0l; /* { dg-warning "traditional C rejects the 'l' suffix" "numeric constant suffix" } */ + #line 24 "sys-header.h" 3 /* We are in system headers now, no -Wtraditional warnings should issue. */ diff --git a/gcc/timevar.def b/gcc/timevar.def index 19a3bb2..8205caa 100644 --- a/gcc/timevar.def +++ b/gcc/timevar.def @@ -40,6 +40,8 @@ DEFTIMEVAR (TV_GC , "garbage collection") DEFTIMEVAR (TV_DUMP , "dump files") /* Timing in various stages of the compiler. */ +DEFTIMEVAR (TV_CPP , "preprocessing") +DEFTIMEVAR (TV_LEX , "lexical analysis") DEFTIMEVAR (TV_PARSE , "parser") DEFTIMEVAR (TV_EXPAND , "expand") DEFTIMEVAR (TV_VARCONST , "varconst") diff --git a/gcc/timevar.h b/gcc/timevar.h index c7fcfa7..e20a26e 100644 --- a/gcc/timevar.h +++ b/gcc/timevar.h @@ -19,6 +19,9 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#ifndef GCC_TIMEVAR_H +#define GCC_TIMEVAR_H + /* Timing variables are used to measure elapsed time in various portions of the compiler. Each measures elapsed user, system, and wall-clock time, as appropriate to and supported by the host @@ -84,3 +87,5 @@ extern void timevar_print PARAMS ((FILE *)); /* Provided for backward compatibility. */ extern long get_run_time PARAMS ((void)); extern void print_time PARAMS ((const char *, long)); + +#endif diff --git a/gcc/toplev.c b/gcc/toplev.c index d657d49..b590eee 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -477,6 +477,10 @@ int time_report = 0; int mem_report = 0; +/* Non-zero means to collect statistics which might be expensive + and to print them when we are done. */ +int flag_detailed_statistics = 0; + /* -f flags. */ -- cgit v1.1