Index: vendor/gcc/dist/contrib/gcc/ChangeLog =================================================================== --- vendor/gcc/dist/contrib/gcc/ChangeLog (revision 60966) +++ vendor/gcc/dist/contrib/gcc/ChangeLog (revision 60967) @@ -1,17393 +1,17450 @@ +Fri May 26 10:30:02 2000 Richard Earnshaw (rearnsha@arm.com) + + * arm.md (negdi2): Add clobber of condition code register. + +Wed May 24 00:25:45 2000 Alexandre Oliva + + 2000-05-22 Richard Henderson + * function.c (thread_prologue_and_epilogue_insns): Make sure + existing line number notes appear after the prologue. + +2000-05-16 Franz Sirl + + * sysv4.h (CPP_OS_LINUX_SPEC): Define __unix and __linux according + to given options. + +2000-05-14 Franz Sirl + + * rs6000/rs6000.md (nonlocal_goto_receiver): Add length attribute. + +Wed Apr 12 00:42:19 2000 Jeffrey A Law (law@cygnus.com) + + 2000-02-19 Richard Henderson + * c-typeck.c (add_pending_init): Don't abort for multiple + fields at the same offset. + (pending_init_member): Test the correct member. + + Wed Apr 12 00:44:31 2000 Jeffrey A Law (law@cygnus.com) + * config/i386/freebsd-elf.h (DEFAULT_VTABLE_THUNKS): Changed to 2. + + Tue Nov 9 17:14:40 1999 H.J. Lu + * invoke.texi (-fvtable-thunks): Document that Linux/GNU uses + version 2 as default. + + Tue Nov 9 10:16:55 1999 H.J. Lu + * alpha/linux-elf.h (DEFAULT_VTABLE_THUNKS): Changed to 2. + * arm/linux-elf.h: Likewise. + * rs6000/linux.h: Likewise. + * sparc/linux.h: Likewise. + + Mon Nov 8 14:41:34 1999 H.J. Lu + * config/linux.h (DEFAULT_VTABLE_THUNKS): Changed to 2. + + Sun May 2 08:49:27 1999 Martin von Löwis + * invoke.texi (-fvtable-thunks): Document numeric argument. + +2000-04-11 Alexandre Oliva + + * config/elfos.h (SELECT_SECTION): Decide whether to use a data or + const section to output a CONSTRUCTOR based on the same conditions + used for VAR_DECLs. + +Mon Apr 3 02:31:32 2000 Jeffrey A Law (law@cygnus.com) + + 2000-01-20 Michael Hayes + * unroll.c (loop_iterations): Don't abort if REG_USERVAR_P set + on iteration_var. + Wed Mar 22 13:11:54 2000 David Edelsohn * rs6000.c (reg_or_u_cint_operand): New function. (logical_operand): Handle 64-bit hosts. (logical_u_operand): New function. (non_logical_cint_operand): Handle 64-bit hosts. (non_logical_u_cint_operand): New function. (expand_block_move): Allow 8 DImode loads for PowerPC64. * rs6000.h (PREDICATE_CODES): Define new functions. * rs6000.md (iordi3, xordi3): Constant int must be unsigned 32-bits. (movdi_64): Bracket code intended for 64-bit hosts. Create CONST_DOUBLE for 32-bit values. * glimits.h (__LONG_MAX__): Recognize 64-bit AIX too. Wed Mar 22 13:11:54 2000 Gabriel Paubert * rs6000.md: Correct instructions length attributes and constraints on unsigned compare instructions. (*ne0): Disable for PowerPC64. Tue Mar 7 21:41:17 2000 Jeffrey A Law (law@cygnus.com) * cccp.c (handle_directive): Initialize backslash_newlines_p. Wed Jan 19 20:39:17 2000 Jim Wilson * fixinc/inclhack.tpl: Test for directory before trying to cd into it. * fixinc/fixincl.sh, fixinc/inclhack.sh: Regenerate. Tue Oct 12 09:45:19 1999 Jonathan Larmour * config/rs6000/eabi-ctors.c (__do_global_ctors): Run through __CTOR_LIST__ in opposite order, which is the correct order for sorted constructors. (__do_global_dtors): similarly for __DTOR_LIST__. 2000-01-05 Bernd Schmidt * reload1.c (choose_reload_regs): When disabling a reload, also set reload_spill_index to -1. Thu Nov 4 15:52:35 1999 Andrew Haley * reload1.c (reload_reg_free_for_value_p): Don't use a register that is in reload_reg_used. 2000-01-18 Clinton Popetz * loop.c (check_dbra_loop): When checking a loop for reversability, check the source of any stores to ensure they don't depend on an initial value. Sat Jan 8 12:12:46 2000 Nick Clifton * config/v850/v850.c (expand_epilogue): Interrupt functions no longer allocate extra stack for function calls. Fri Feb 18 13:32:32 2000 Martin von Loewis * gcc.texi (Bug Reporting): Refer to bugs.html. (Bug Lists): Likewise. * system.h (GCCBUGURL): New preprocessor define. (abort): Use it. * gcc.c (main): Likewise. Thu Feb 3 10:53:45 2000 Richard Henderson Wed Nov 3 10:10:58 1999 Richard Henderson * c-decl.c (duplicate_decls): Copy DECL_MODE too. Thu Jan 20 10:02:07 2000 Richard Henderson 2000-01-03 Anthony Green * config/i386/i386.md (builtin_setjmp_receiver): New pattern. Restore the pic register if required. Fri Jan 7 14:40:05 2000 Richard Henderson Thu Oct 28 18:06:50 1999 Richard Kenner * stmt.c (expand_value_return): Correctly convert VAL when promoting function return. Tue Jan 4 02:22:27 2000 Jeffrey A Law (law@cygnus.com) Mon Oct 18 18:50:51 1999 Andreas Schwab * config/m68k/m68k.h (INITIAL_FRAME_POINTER_OFFSET): Add one word if the pic register is used. Sat Sep 25 13:11:07 1999 Jeffrey A Law (law@cygnus.com) * cse.c: Update comments. (cse_insn): When converting a conditional/computed jump into an unconditional jump, always make sure a BARRIER immediately follows the converted jump. Do not delete unreachable code. (cse_basic_block): Do not delete unreachable code. * toplev.c (rest_of_compilation): Move call to delete_trivially_dead_insns after the conditional call to jump_optimize. Wed Dec 29 22:47:43 1999 Jeffrey A Law (law@cygnus.com) 1999-12-12 Stephen L Moshier * loop.c (load_mems): Don't hoist written floating point mem if -ffloat-store. * cppinit.c (is_idchar): Only use special initialization for gcc-2.8 and later versions of the compiler. Wed Oct 27 01:42:26 1999 Scott Christley * sparc.md (call): Don't bound structure return size to 0xfff. Mon Dec 27 07:32:59 1999 Jeffrey A Law (law@cygnus.com) Fri Sep 3 10:16:37 HST 1999 Glen Nakamura * cccp.c (rescan): Fixed obp pointer handling around call to check_expand subroutine. Thu Sep 16 00:46:35 1999 Geoff Keating * loop.c (basic_induction_var): A non-integer variable which is being set by a paradoxical subreg is probably not a biv. 1999-08-31 12:20 -0700 Zack Weinberg * loop.c (check_dbra_loop): Check bl->biv->add_val is a CONST_INT before using its INTVAL. Tue Nov 2 15:27:31 1999 Alexandre Oliva * configure.in (m68k-hp-hpux*, xm_alloca.h): The underscore should have been an hyphen, fixed. * configure: Rebuilt. Thu Dec 23 11:59:56 1999 Jeffrey A Law (law@cygnus.com) 1999-12-23 Martin v. Löwis * fold-const.c (operand_equal_p): Use memcmp to compare string constants. Suggested by D. J. Bernstein Thu Dec 16 02:26:11 1999 Jeffrey A Law (law@cygnus.com) * h8300.md (HImode preinc peephole): Fix typo. 1999-12-14 Bernd Schmidt * loop.c (check_dbra_loop): Can't reverse a biv that has maybe_multiple set. 1999-12-07 Martin v. Löwis * invoke.texi (C Dialect Options): Remove -flang-c9x, add -std documentation. Sun Oct 31 22:32:17 1999 Alexandre Oliva * config/i386/sol2gas.h: I had installed the wrong version of Sept 22's patch in the release branch. Fixed. * configure.in: Likewise. * configure: Rebuilt. Reported by Jason Beardsley Sun Oct 24 23:54:10 PDT 1999 Jeff Law (law@cygnus.com) * gcc-2.95.2 Released. Mon Oct 25 00:43:05 1999 Jeffrey A Law (law@cygnus.com) * loop.c (note_set_pseudo_multiple_uses_retval): New variable. (note_set_pseudo_multiple_uses): New function. (check_dbra_loop): Use not_set_pseudo_multiple_uses to determine if a pseudo set in the loop exit is used elsewhere. Wed Oct 20 10:46:41 1999 Richard Earnshaw (rearnsha@arm.com) * jump.c (jump_optimize_1): More accurately detect casesi insns. Wed Oct 20 22:57:58 1999 Jeffrey A Law (law@cygnus.com) * toplev.c (main): Do not turn on strict aliasing by default. * invoke.texi: Corresponding changes. * sparc.md (movsf_const_intreg): If splitting, length must be > 1. (movdf_const_intreg_sp64): Similarly. * local-alloc.c (update_equiv_regs): Check the correct insn for pre-existing REG_EQUIV notes. Tue Oct 19 02:03:00 1999 Jeffrey A Law (law@cygnus.com) Revert this change. Gavin's patch to operand_equal_p is a better fix. * fold-const.c (fold_range_test): Do not try to fold the range test if the rhs or lhs has side effects. Fri Sep 17 15:05:27 1999 Gavin Romig-Koch * fold-const.c (operand_equal_p): Pay attention to side effects. * reg-stack.c (stack_result): Aggregates are not returned in stack registers. Mon Oct 18 01:41:35 1999 Jeffrey A Law (law@cygnus.com) * combine.c (get_last_value): If the last set of a register is after subst_low_cuid, then we can not use it to determine the register's last value. Sat Oct 16 15:20:15 1999 Jeffrey A Law (law@cygnus.com) Sat Oct 16 00:07:01 1999 Richard Henderson * gcse.c (hash_expr_1): Add in MEM_ALIAS_SET. (expr_equiv_p): Reject memories with different alias sets. Wed Oct 13 01:46:14 1999 Jeffrey A Law (law@cygnus.com) Wed Oct 13 01:44:29 1999 Carol LePage * configure.in (sparc-hal-solaris2*): Fix xm_file, xm_defines, float_format and thread_file definitions. * configure: Rebuilt. Tue Oct 12 17:09:38 1999 David Edelsohn * collect2.c (main): Do preliminary link on AIX if rflag. Mon Oct 11 23:35:19 1999 Jeffrey A Law (law@cygnus.com) Fri Sep 3 09:14:32 1999 Marc Espie * tlink.c (scan_linker_output): Skip the initial underscore in a mangled name if appropriate. Fri Aug 27 19:19:43 CEST 1999 Marc Espie * config/openbsd.h (SET_ASM_OP): Define. Mon Oct 4 08:54:12 1999 Alexandre Oliva * cppinit.c (is_idchar initializer): Loosen tests to accept gcc 2.>6 and >2. Tue Jun 29 01:37:53 1999 Jeffrey A Law (law@cygnus.com) * pa.h (CPP_SPEC): Conditionally add -D__STDC_EXT__ to the cpp command line. Thu Sep 2 20:08:23 1999 J"orn Rennecke * regmove.c (fixup_match_1): Don't change an unchanging register. (stable_but_for_p): Renamed to: (stable_and_no_regs_but_for_p). Reject unchanging registers too. Changed all callers. Tue Aug 17 22:06:11 1999 Jan Hubicka * haifa-sched.c (insn_unit): Fix typo on out of range test. * sched.c (insn_unit): Likewise. Sun Oct 10 20:58:27 1999 David Edelsohn * rs6000.md (scc patterns): Disable most SImode variants if TARGET_POWERPC64. * rs6000.c (expand_block_move): Fix gen_movsi typos. Thu Oct 7 23:06:50 1999 Richard Henderson * rs6000.md (fix_truncdfsi2_internal+1): Emit a clobber before the fctiwz insn. Thu Oct 7 00:36:17 1999 Diego Novillo * config/rs6000/rs6000.c (secondary_reload_class): For TARGET_ELF make sure that HIGH instructions are copied into BASE_REGS. Thu Sep 30 05:40:34 1999 Richard Earnshaw * c-lang.c (finish_file case ndef ASM_OUTPUT_{CON,DE}STRUCTOR): Correctly build argument list to constructor and destructor functions. Wed Sep 22 17:55:31 1999 David Edelsohn * rs6000.c (expand_block_move): DImode loads and stores require word-aligned displacements. Increment address registers with adddi3 on 64-bit platform. Use TARGET_POWERPC64 not TARGET_64BIT. Wed Sep 22 07:07:44 1999 Alexandre Oliva * config/i386/sol2.h (PREFERRED_DEBUGGING_TYPE): Use stabs. (ASM_SPEC): Moved from sol2dbg.h. Added work-around for gas. * config/i386/sol2dbg.h: Removed. * config/i386/sol2gas.h: New file, to enable gas work-around. * configure.in: Use i386/sol2gas.h on Solaris/x86 --with-gas. Don't use sol2dbg.h. * configure: Rebuilt. Wed Sep 15 21:20:38 1999 Mark Mitchell * c-typeck.c (qualify_type): Merge qualifiers from both types. Wed Sep 15 10:07:27 1999 Scott Bambrough * config/arm/linux-elf.h: define NO_IMPLICIT_EXTERN_C Tue Sep 7 16:50:59 1999 David Edelsohn * rs6000.h (ASM_FILE_START): Specify complete filename, including path, in .file directive. Tue Sep 7 01:27:21 1999 Jeffrey A Law (law@cygnus.com) Thu Sep 2 00:06:43 1999 Jeffrey A Law (law@cygnus.com) * fold-const.c (fold_range_test): Do not try to fold the range test if the rhs or lhs has side effects. Sun Aug 29 03:27:23 1999 Scott Weikart * fix-header.c (main): Do not pass a null pointer to strcmp. Thu Aug 19 14:42:38 1999 Mike Stump Mark Mitchell * c-common.c (c_get_alias_set): Fix support for pointers and references. Fri Aug 27 01:03:48 1999 Jim Kingdon with much help from Jeffrey A Law and Richard Henderson * i386.md: In the 6 insns which call output_fix_trunc, earlyclobber operands[0]. Fri Aug 27 01:01:51 1999 Philip Blundell * jump.c (duplicate_loop_exit_test): Call reg_scan_update after creating new registers. Fri Aug 27 15:35:24 1999 Jeffrey A Law (law@cygnus.com) * cse.c (fold_rtx): Work around bug in Sun V5.0 compilers. * pa.c (emit_move_sequence): Do not stop on SUBREG_WORD of an operand. Tue Aug 31 11:51:06 1999 Jim Kingdon * i386.c (output_strlen_unroll): Don't write xops[7] label if it wasn't set. Fri Aug 27 09:36:17 1999 Andreas Schwab * function.c (assign_stack_temp_for_type): Fix change of Mar 5 for the fact that ALIGN is measured in bits, not bytes. Wed Aug 25 14:00:18 1999 Jason Merrill * c-common.c (combine_strings): Always set TREE_CONSTANT. Wed Aug 18 01:16:43 1999 David S. Miller * config/sparc/sparc.c (sparc_block_profiler): Fix typo in Aug 2 change. Mon Aug 16 01:29:24 PDT 1999 Jeff Law (law@cygnus.com) * gcc-2.95.1 Released. 1999-08-13 Michael Meissner * Makefile.in (GCC_FOR_TARGET): Move -B./ after the tooldir -B. Fri Aug 13 01:42:24 1999 Jeffrey A Law (law@cygnus.com) Tue Aug 3 00:03:41 1999 Kaveh R. Ghazi * fixincludes: Fix the return type of bsearch, char* -> void*. * fixinc/inclhack.def: Likewise. Fri Aug 13 01:29:57 1999 Alexandre Oliva * dwarfout.c (fundamental_type_code): Return FT_boolean for INTEGER_TYPE with precision==1, it's __java_boolean. 1999-08-11 Richard Earnshaw (rearnsha@arm.com) * emit-rtl.c (mark_reg_pointer): Don't increase the alignment of a register that is already known to be a pointer. 1999-08-11 Bruce Korb * fixinc/inclhack.tpl: Only install assert.h conditionally. * fixinc/inclhack.sh: Regenerated. * fixinc/fixincl.sh: Regenerated. Wed Aug 11 00:34:22 1999 Joe Buck * invoke.texi: s/GNU CC/GCC/ for consistency with gcc.texi. Fix documentation of -ansi flag to describe its C++ behavior. Remove bogus reference to GCC 2.9. Tue Aug 10 22:40:36 1999 Jeffrey A Law (law@cygnus.com) Thu Aug 5 22:27:15 1999 J"orn Rennecke * config/sh/lib1funcs.asm (___movstrSI0): Change or r0,r0,r0 to nop. (___mulsi3): Use '!' comment character. Sat Aug 7 00:06:30 1999 Jeffrey A Law (law@cygnus.com) * gcc.texi: Update bug reporting text. Tue Jul 20 17:07:54 1999 Richard Henderson * rs6000.h (struct rs6000_args): Add sysv_gregno. * rs6000.c (init_cumulative_args): Init sysv_gregno. (function_arg_boundary): Align DFmode. (function_arg_advance): Restructure for ABI_V4; use sysv_gregno to get fp reg and stack overflow correct. (function_arg): Likewise. (function_arg_pass_by_reference): True for TFmode for ABI_V4. (setup_incoming_varargs): Restructure for ABI_V4; use function_arg_advance to skip final named argument. (expand_builtin_saveregs): Properly unskip the last integer arg when doing varargs. Adjust overflow location calculation. * ginclude/va-ppc.h (struct __va_list_tag): Make gpr and fpr explicitly unsigned. (__VA_FP_REGSAVE): Use new OFS argument instead of AP->fpr directly. (__VA_GP_REGSAVE): Similarly. (__va_longlong_p): Delete. (__va_arg_type_violation): New declaration. (va_arg): Restructure. Flag promotion errors. Align double. TFmode passed by reference. * rs6000.md (movdi_32+1): Use GEN_INT after arithmetic in the HOST_BITS_PER_WIDE_INT > 32 case. 1999-08-6 Herman A.J. ten Brugge * reg-stack.c (change_stack) Fixed problem with negative array index. Fri Aug 6 20:41:08 1999 Jeffrey A Law (law@cygnus.com) Mon Jul 19 15:09:29 1999 David Edelsohn * rs6000.md (arithmetic, logical, and shift Rc combiner patterns): Disable patterns performing SImode comparisons with SImode values if TARGET_POWERPC64 and instruction does not sign-extend or does not mask to narrower than SImode, i.e. where bit 31 and bit 63 may differ for signed quantities. (indirect_jump): Add expander to choose RTL based on TARGET_64BIT. (tablejump): Patterns contingent on TARGET_64BIT not TARGET_POWERPC64. (decrement_and_branch_on_count): Add 64-bit variant. Thu Aug 5 02:40:42 1999 Jeffrey A Law (law@cygnus.com) * gcc.c: Update URLs and mail addresses. * gcc.texi: Likewise. Thu Aug 5 01:14:13 1999 Daniel Jacobowitz * rs6000.c (current_file_function_operand): Return zero for weak functions. (rs6000_encode_section_info): Do not set SYMBOL_REF_FLAG for weak symbols. * rs6000.h (ENCODE_SECTION_NIFO): Do not set SYMBOL_REF_FLAG for weak symbols. Thu Aug 5 00:56:30 1999 Geoffrey Keating * rs6000.c (rs6000_stack_info): For ABI_V4/ABI_SOLARIS -fpic, always allocate space in the stack frame for the PIC register. Thu Aug 5 00:20:47 1999 Jeffrey A Law (law@cygnus.com) * m68k.md (xordi3, anddi3): These patterns are not available on the coldfire. Wed Aug 4 23:39:20 1999 Mark Mitchell * real.c (GET_REAL): Don't violate ANSI/ISO aliasing rules. (PUT_REAL): Likewise. Wed Aug 4 02:15:32 1999 Richard Henderson * jump.c (delete_insn): Delete the addr_vec when deleting a tablejump. Wed Aug 4 01:08:44 1999 Jeffrey A Law (law@cygnus.com) * flow.c (delete_unreachable_blocks): Do not call merge_blocks or tidy_fallthru_edge if the last insn in the block is not an unconditional jump or a simple conditional jump. Tue Aug 3 03:51:20 1999 Jeffrey A Law (law@cygnus.com) * cse.c (cse_insn): Fix dumb thinko in last change. Mon Aug 2 23:45:45 1999 Hans-Peter Nilsson * dwarf2out.c (add_location_or_const_value_attribute): Correct test for sizes of passed and declared parameter types. Mon Aug 2 12:45:09 1999 Richard Henderson * alpha.c (override_options): Don't force ALPHA_TP_PROG for ev6. Mon Aug 2 01:34:22 1999 Jeffrey A Law (law@cygnus.com) * fix-header.c (main): When testing for CONTINUED, use string equality, not pointer equality. Mon Aug 2 01:27:24 1999 Dan Nicolaescu * sparc.c (sparc_block_profiler): Use the %g2 register, not %o0. Sun Aug 1 22:46:42 1999 Jeffrey A Law (law@cygnus.com) * cse.c (cse_insn): Fix loop which deletes insns after a jump that has become an unconditional jump. * m68k.c (output_function_prologue): Fix typo in CPU32 case. (output_function_epilogue): Similarly. Tue Jul 20 12:37:30 1999 Hans-Peter Nilsson * dwarf2out.c (output_abbrev_section): Terminate with a zero. Thu Jul 15 15:40:09 1999 Jim Wilson * tree.c (build_type_attribute_variant): Move current_obstack restore after build_qualified_type call. Fri Jun 4 03:20:40 1999 J"orn Rennecke * sh.c (fixup_addr_diff_vecs): Emit braf reference label. (braf_label_ref_operand): Delete. * sh.h (PREDICATE_CODES): Remove braf_label_ref_operand. * sh.md (casesi_jump_2): Operand1 is now the inside of a label_ref, and has no predicate. The patten has a predicate to guard against invalid substitutions. (dummy_jump): Delete. (casesi): Update use of casesi_jump_2. Thu Jul 31 12:34:45 1999 Joe Buck * gcc.texi: Use terms "GNU Compiler Collection" and "GCC". Also update copyright. Wed Jul 28 21:39:31 PDT 1999 Jeff Law (law@cygnus.com) * gcc-2.95 Released. * verison.c: No longer a prerelease. Wed Jul 28 13:49:03 1999 Jeffrey A Law (law@cygnus.com) * README: Update. Sun Jul 25 21:40:33 1999 Jeffrey A Law (law@cygnus.com) * gcc.texi: More changes related to list conversion. * invoke.texi: Likewise. Sat Jul 17 23:58:24 1999 David Edelsohn * rs6000.md (insv, extzv): Remove SImode dependence in named patterns. Explicitly generate DImode RTL if PowerPC64 and operand is DImode. (insvdi): Reverse start and size in instruction template. 1999-07-17 Alexandre Oliva * gcc.texi: Update e-mail addresses and URLs to gcc.gnu.org. Removed paragraph about compression of files and size limitation, duplicated in the FAQ. Use gcc-patches for posting patches. * gcc.c (main): Updated URL with bug reporting instructions to gcc.gnu.org. Removed e-mail address. * system.h (abort): Likewise. 1999-07-17 Kaveh R. Ghazi * Makefile.in (stmp-multilib-sub): Make the files extracted from $(LIBGCC1) writable. Fri Jul 16 01:39:57 1999 Jeffrey A Law (law@cygnus.com) * m68k.c (output_function_prologue): Fix computation of save mask when generating PIC code. 1999-07-12 Joseph S. Myers * invoke.texi: Typo fixes. Wed Jul 14 23:28:06 1999 Jeffrey A Law (law@cygnus.com) * emit-rtl.c (gen_realpart): Issue an error for cases GCC can not handle at this time instead of silently generating incorrect code. (gen_imagpart): Likewise. * reload.c (find_reloads): Emit a USE for a pseudo register without a hard register if we could not create an optional reload for the pseudo. Wed Jul 14 01:57:39 1999 Richard Henderson * regclass.c (scan_one_insn): Notice subregs that change the size of their operand. (record_reg_classes): Use that to obey CLASS_CANNOT_CHANGE_SIZE. Wed Jul 14 01:37:06 1999 Jeffrey A Law (law@cygnus.com) * configure.in (alpha*-*-*): Include alpha/t-ieee. * configure: Rebuilt. * alpha/t-ieee: New file. Tue Jul 13 10:44:14 1999 Jeffrey A Law (law@cygnus.com) Wed Jun 16 20:29:00 1999 J"orn Rennecke * cse.c (cse_insn): Don't put hard register source into tables for the last insn of a libcall. * rs6000.c (find_addr_reg): Do not select r0 as an address register. Tue Jul 13 00:46:18 1999 Philippe De Muyter * m68k/x-mot3300 (XCFLAGS): List of big files now includes `cse.o'. Mon Jul 12 23:39:08 1999 Jeffrey A Law (law@cygnus.com) * rs6000.md (movsf): Do not force easy FP constants into memory. Sun Jul 11 11:21:24 1999 Jason Merrill * toplev.c (main): Don't complain about saying -gdwarf. Fri Jul 9 03:51:52 1999 Jeffrey A Law (law@cygnus.com) * version.c: Drop "gcc-" prefix from version #. Thu Jul 8 19:15:51 1999 Jim Wilson * unroll.c (unroll_loops): Don't delete named CODE_LABEL or NOTE_INSN_DELETED_LABEL note. Thu Jul 8 14:18:46 1999 Richard Henderson * m68k.c (output_function_prologue): Add pic register to mask if live and flag_pic. (output_function_epilogue): Likewise. Thu Jul 8 10:28:25 1999 Craig Burley * invoke.texi (DEC Alpha Options): Put @end table at beginning of line, to avoid confusing texi2html. Wed Jul 7 02:00:04 1999 Franz Sirl * reload1.c (gen_reload): When synthesizing a 3 operand add sequence, improve test for when to reload OP1 into the reload register instead of OP0. Wed Jul 7 01:38:03 1999 Jim Wilson * unroll.c (unroll_loop): Don't delete NOTE_INSN_DELETED_LABEL notes. 1999-07-07 Manfred Hollstein * m88k/dguxbcs.h (CPP_SPEC): Add missing \ in multi-line string literal. Wed Jul 7 01:16:43 1999 Richard Henderson * ginclude/varargs.h (__builtin_va_alist_t): New typedef. (va_dcl): Use __builtin_va_alist_t. Wed Jul 7 01:13:31 1999 Jason Merrill * dwarf2out.c (gen_struct_or_union_type_die): Only remember types on the permanent_obstack. * dwarfout.c (output_type): Likewise. Fri Jul 2 03:05:13 1999 Jeffrey A Law (law@cygnus.com) * dwarfout.c (field_byte_offset): Correctly compute the object's byte offset for the first bit of a field which crosses an alignment boundary on a !BYTES_BIG_ENDIAN target. Fri Jul 2 01:36:36 1999 Robert Lipe * fixinc.svr4: Fix by deleting protos for htons and ntohs. Fri Jul 2 00:46:47 1999 Richard Henderson Jeff Law * ginclude/varargs.h (va_dcl): Use word_mode for type of __builtin_va_list. * except.c: Include intl.h. (expand_eh_return): Set current_function_cannot_inline. (save_eh_status, restore_eh_status): Twiddle eh_return_stub_label. * function.h (struct function): Add eh_return_stub_label. * flow.c (delete_unreachable_blocks): Don't merge across EH edges. * Makefile.in (except.o): Depend on intl.h. Fri Jul 2 00:04:23 1999 David Edelsohn * rs6000.md (movdf_hardfloat32): Handle PRE_INC and PRE_DEC the same as offsettable in cases 1 and 2. 1999-07-01 Mark Kettenis * config/i386/gnu.h (CPP_SPEC): Define __PIC__ and __pic__ if -fPIC or -fpic is specified. Wed Jun 30 23:56:01 1999 Jeffrey A Law (law@cygnus.com) * expr.c (emit_block_move): Use copy_to_mode_reg for !TARGET_MEM_FUNCTIONS case too. Tue Jun 29 01:37:53 1999 Jeffrey A Law (law@cygnus.com) * mips.md (leasi, leadi): New patterns. * expr.c (emit_block_move): Properly handle case where one of the block move arguments has a queued increment or decrement. (clear_storage): Similarly. Fix formatting goof. Mon Jun 28 05:32:09 1999 Jeffrey A Law (law@cygnus.com) * m68k.h (CONDITIONAL_REGISTER_USAGE): Define for !SUN_FPA case. Also make the PIC register call_used. * m68k.h (FINALIZE_PIC): Delete. * m68k.c (finalize_pic): Delete. * m68k.h (CONDITIONAL_REGISTER_USAGE): Make the PIC register fixed when -fpic/-fPIC. Mon Jun 28 05:16:35 1999 Richard Henderson * m68k.h (PREFERRED_RELOAD_CLASS): Don't force any FP const_doubles to memory. Mon Jun 28 04:07:27 1999 David Edelsohn * rs6000.c (output_toc): Always use hex values for floating-point constants. Store single-precision values in upper-half of TOC entry in 64-bit mode. * rs6000.md (floatsidf2, floatunssidf2): Add !TARGET_POWERPC64 to final constraints. (fix_truncdfsi2 splitter): Change pattern matching fctiwz. (fctiwz): Improve accuracy of RTL for pattern. * rs6000.c (print_operand, case 'L'): Use plus_constant_for_output. * expmed.c (expand_divmod): Ensure unsigned value fits in reg_note. Fri Jun 25 06:06:37 1999 Richard Henderson * alpha.h (MASK_SUPPORT_ARCH, MASK_CPU_EV5, MASK_CPU_EV6): Define such that MASK_SUPPORT_ARCH is not negative. Fri Jun 25 05:35:44 1999 Jeffrey A Law (law@cygnus.com) * loop.c (verify_dominator): Properly handle ADDR_VEC and ADDR_DIFF_VEC insns that appear inside loops. Thu Jun 24 22:54:05 1999 David Edelsohn Jeff Law * rs6000.md (movdf_hardfloat32): Revert previous patch. Handle LO_SUM the same as offsettable in cases 1 and 2. * rs6000.c (find_addr_reg): Revert previous patch. Thu Jun 24 22:43:12 1999 Philippe De Muyter * system.h (strstr): New external function declaration. * acconfig.h (NEED_DECLARATION_STRSTR): New define slot. * configure.in (GCC_NEED_DECLARATIONS): Check for strstr. * config.in, configure: Rebuilt. 1999-06-24 Tom Tromey * gcc.c (main): Read user-specified specs files after computing additional startfile_prefixes. 1999-06-24 Bruce Korb *fixinc/inclhack.def(end_else_label): combined else_label and endif_label and fixed the sed expression. *fixinc/{fixincl.x|inclhack.sh}: regen Tue Jun 22 01:58:18 1999 Jeffrey A Law (law@cygnus.com) * rs6000.md (movdf_hardfloat32): Use %X instead of always emitting 'x' when handling non-offsettable addresses Tue Jun 22 00:20:05 1999 Richard Earnshaw (rearnsha@arm.com) * final.c (shorten_branches): Don't try to split an insn that has been deleted. Mon Jun 21 23:32:17 1999 Jeffrey A Law (law@cygnus.com) Thu Jun 17 15:07 1999 Bruce Korb * fixincludes: ISCNTL patch Mon Jun 21 22:15:50 1999 Jeffrey A Law (law@cygnus.com) * rs6000.c (find_addr_reg): Handle LO_SUM addresses. Mon Jun 21 22:14:05 1999 David Edelsohn * rs6000.md (movdf_hardfloat32): Fix typo. Mon Jun 21 20:10:42 1999 Richard Henderson * collect2.c (main): Log frame table count. (GCC_OK_SYMBOL) [ECOFF]: Accept stGlobal. (scan_prog_file) [COFF]: Handle frame tables. * alpha/alpha.h (UNALIGNED_SHORT_ASM_OP): Define. (UNALIGNED_INT_ASM_OP, UNALIGNED_DOUBLE_INT_ASM_OP): Define. * alpha/elf.h: Undef them again. * alpha/vms.h: Remove their definitions. 1999-06-21 Jakub Jelinek * real.c (ereal_from_double): Fix for 64-bit big endian hosts. * emit-rtl.c (gen_lowpart_common): Add case for hosts where double fits in HOST_WIDE_INT and one uses union to access a long constant as double. Mon Jun 21 17:18:25 1999 Richard Henderson * sparc.c (sparc_override_options): Don't allow profiling for code models other than medlow. (sparc_function_profiler): New function from old FUNCTION_PROFILER macro. Use ASM_GENERATE_INTERNAL_LABEL and MCOUNT_FUNCTION. (sparc_function_block_profiler): Likewise. Use user_label_prefix. (sparc_block_profiler): Likewise. (sparc_function_block_profiler_exit): Likewise. * sparc.h (FUNCTION_PROFILER): Call new sparc.c function. (FUNCTION_BLOCK_PROFILER): Likewise. (BLOCK_PROFILER): Likewise. (FUNCTION_BLOCK_PROFILER_EXIT): Likewise. (MCOUNT_FUNCTION): New. * sparc/pbd.h (FUNCTION_PROFILER): Delete. (FUNCTION_BLOCK_PROFILER, BLOCK_PROFILER): Delete. * sparc/sun4o3.h (FUNCTION_PROFILER): Delete. (MCOUNT_FUNCTION): New. * sparc/sysv4.h (FUNCTION_BLOCK_PROFILER): Delete. (BLOCK_PROFILER): Delete. (MCOUNT_FUNCTION): New. Mon Jun 21 06:22:21 1999 Mark Elbrecht * i386/djgpp.h (LIB_SPEC): New. (STARTFILE_SPEC): New. * i386/xm-djgpp.h (NO_SYS_SIGLIST): Deleted. Now obsolete. Mon Jun 21 06:19:33 1999 Philippe De Muyter * fixinc/Makefile.in (gnu-regex.o): Do not define STDC_HEADERS in compiler flags. * system.h (WSTOPSIG): New macro. Mon Jun 21 05:33:15 1999 Mumit Khan * c-pragma.c (push_alignment): Don't ignore alignments greater than 4 bytes. (insert_pack_attributes): Take into account member natural alignment. * i386/winnt.c (exports_head): New static variable. (i386_pe_record_exported_symbol): New function. (i386_pe_asm_file_end): Use. * i386/cygwin.h (ASM_OUTPUT_COMMON): Record the exported symbols to be emitted at end of assembly. (ASM_DECLARE_OBJECT_NAME): Likewise. (ASM_DECLARE_FUNCTION_NAME): Likewise. * i386/uwin.h (CPP_SPEC): Use -idirafter instead -iprefix and -iwithprefix. Mon Jun 21 05:17:00 1999 David Edelsohn * rs6000.md (movdf_hardfloat32): Use worst case insn length attributes for cases 1 and 2. * rs6000.c (find_addr_reg): New function. * rs6000.h (find_addr_reg): Declare. (offsettable_addr_operand): Delete. * rs6000.md (movdf_hardfloat32): Handle non-offsettable loads from and stores to GPRs. Mon Jun 21 04:44:31 1999 Jeffrey A Law (law@cygnus.com) * sparc.h (LEGITIMIZE_RELOAD_ADDRESS): Fix paren error introduced in last change. Sun Jun 20 17:24:35 1999 Richard Henderson * haifa-sched.c (sched_analyze): Don't clear reg_last_uses on calls. Sat Jun 19 22:52:55 1999 Richard Henderson * haifa-sched.c (sched_analyze): Mark call-user regs as clobbered instead of set. Sat Jun 19 05:40:07 1999 Philip Blundell * arm.c (arm_reload_in_hi): Invert sense of test on BYTES_BIG_ENDIAN. Sat Jun 19 05:25:05 1999 Richard Earnshaw (rearnsha@arm.com) * arm.h (CONDITIONAL_REGISTER_USAGE): If flag_pic, never use PIC_OFFSET_TABLE_REGNUM for general alloaction. (INITIAL_ELIMINATION_OFFSET): Count the fact that the PIC register must be stacked if it is used for PIC accesses. * arm.c (use_return_insn): Handle PIC register specially. (output_return_instruction): Likewise. (output_func_{prologue,epilogue}): Likewise. (output_expand_prologue): Likewise. * arm.c (arm_override_options): Remove warning about PIC code not being supported. Fri Jun 18 15:44:18 1999 Richard Henderson * alpha.c (alpha_expand_block_move): Use get_insns rather than gen_sequence as argument to emit_no_conflict_block. Fri Jun 18 06:48:30 1999 Kaveh R. Ghazi * fixinc/inclhack.def (ioctl_fix_ctrl): Fix the definition of _*ISCTRL(). * fixinc/{fixincl.x,inclhack.sh}: regen Thu Jun 17 13:28:30 1999 David O'Brien * i386/freebsd-elf.h (LINK_SPEC): Fix typo. * i386/freebsd-elf.h (FUNCTION_PROFILER): labels are not needed and the reference to `mcount' was not correct for the ELF on FreeBSD. Thu Jun 17 02:54:30 1999 Jeffrey A Law (law@cygnus.com) * invoke.texi (ia32 options): Fix typo. * emit-rtl.c (operand_subword): Tighten checks for when it is safe to safe to extract a subword out of a REG. Wed Jun 16 10:33:02 1999 Jason Merrill * dwarfout.c (add_incomplete_type): New fn. (output_type): Call it. (retry_incomplete_types): New fn. (dwarfout_finish): Call it. From Eric Raskin : (output_type): Output types for bases. Tue Jun 15 01:55:20 1999 David O'Brien * i386/freebsd-elf.h (LINK_SPEC): clean up the linking library specifications and make it realistic. (LIB_SPEC): Likewise. Mon Jun 14 03:55:40 1999 Jeffrey A Law (law@cygnus.com) * configure.in (rs6000-ibm-aix4.3*, powerpc-ibm-aix4.3*): Do not require a sub-version #. * configure: Rebuilt. 1999-06-14 Robert Lipe (robertlipe@usa.net) * svr4.h (DWARF2_DEBUGGING_INFO): Check for redefinition. 1999-06-14 Andreas Jaeger * gcc.texi: Mention gcc 2.95 instead of egcs 1.00. Sun Jun 13 01:08:02 1999 Mark Mitchell * invoke.texi (node Option Summary): Add -fpermissive flag. Sat Jun 12 03:40:42 1999 Jeffrey A Law (law@cygnus.com) * sparc.h (LEGITIMIZE_RELOAD_ADDRESS): Do nothing with operands that require PIC code sequences. Fri Jun 11 03:17:51 1999 Jeffrey A Law (law@cygnus.com) * Makefile.in (libgcc2): Pass MAYBE_USE_COLLECT2 as an argument. * libgcc2.c (__CTOR_LIST, __DTOR_LIST); Do not provide initializers is some circumstances. * fixinc/inclhack.def (endif_label): Add additional selector for more bogus stuff after #endif statements. * fixinc/inclhack.sh, fixinc/fixincl.x: Rebuilt. Thu Jun 10 20:45:27 1999 Mumit Khan * i386/cygwin.h (SET_ASM_OP): Define. Thu Jun 10 20:37:57 1999 Mumit Khan * reg-stack.c (stack_reg_life_analysis): Find all the RETURN insns. Thu Jun 10 14:47:59 1999 Bruce Korb * fixinc/inclhack.def(sun_auth_proto): We do not know how to test for the presence of valid prototypes. Delete bypass expr. (ioctl_fix_ctrl): Correct the selection expression. * fixinc/inclhack.def(no_double_slash): fixed quoting rules * fixinc/inclhack.sh: regen * fixinc/fixincl.x: regen Thu Jun 10 01:22:59 1999 Jeffrey A Law (law@cygnus.com) * loop.c (strength_reduce): Disable biv->giv translations and giv recombination. For the release branch only. Wed Jun 9 15:57:57 1999 Franz Sirl * rs6000.md (movsi_got_internal_mem): Delete. * rs6000.h (CONDITIONAL_REGISTER_USAGE): Mark PIC_OFFSET_TABLE_REGNUM. (GOT_TOC_REGNUM): Delete. (PIC_OFFSET_TABLE_REGNUM): Define. (FINALIZE_PIC): Disable. * rs6000.c (rs6000_got_register): New code for fixed pic register. (rs6000_replace_regno): Delete. (rs6000_finalize_pic): Likewise. (output_prolog): Handle PIC_OFFSET_TABLE_REGNUM. Wed Jun 9 19:44:26 1999 J"orn Rennecke * loop.c (loop_insn_first_p): Don't compare LUIDs when P is a note; use <= for the compare; advance P while it is a NOTE. Wed Jun 9 13:12:24 1999 Jeffrey A Law (law@cygnus.com) * fixinc/inclhack.def (no_double_slash): Fix quoting for test. * fixinc/inclhack.sh, fixinc/fixincl.x, fixinc/fixincl.sh; Rebuilt. * varasm.c (remove_from_pending_weak_list): Verify t->name is non-NULL before passing it to strcmp. Wed Jun 9 23:01:17 1999 Michael Hayes * invoke.texi: Add C4x invocation docs. Wed Jun 9 22:42:49 1999 Michael Hayes * config/c4x/c4x.h (TARGET_EXPOSE_LDP, LEGITIMIZE_RELOAD_ADDRESS): Define new macros. * config/c4x/c4x.c (c4x_emit_move_sequence, src_operand): Use TARGET_EXPOSE_LDP. (c4x_legitimize_reload_address): New function. * config/c4x/c4x.md: Update docs. Wed Jun 9 06:50 1999 Bruce Korb * fixinc/inclhack.def(sun_auth_proto): bypass the patch if the typed arguments are not part of a comment (ioctl_fix_ctrl): Added a purpose comment * fixinc/fixincl.x: regenerate * fixinc/inclhack.sh: regenerate Wed Jun 9 04:14:48 1999 Jeffrey A Law (law@cygnus.com) * fixincludes: Avoid removing '.'. * fixinc/fixinc.svr4: Likewise. * fixinc/fixinc.winnt: Likewise. * fixinc/inclhack.tpl: Likewise. * fixinc/fixincl.sh, fixinc/inclhack.sh: Rebuilt. Wed Jun 9 03:55:34 1999 Jim Wilson * configure.in (rs6000-ibm-aix4.[12]*): Change rx6000 to rs6000. * configure: Regenerate. * configure.in (rs6000-ibm-aix4.[12]*): Delete use of aix41-gld.h. Add use of x-aix41-gld. 1999-06-09 Kaveh R. Ghazi * fixinc/inclhack.def (sun_catmacro): Escape parens in the select pattern. * fixinc/fixincl.x, fixinc/inclhack.sh: Rebuilt. Wed Jun 9 03:10:34 1999 Mumit Khan * c-pragma.c (handle_pragma_token): Handle `#pragma pack()' correctly. Tue Jun 8 05:47:48 1999 Richard Earnshaw (rearnsha@arm.com) * optabs.c (expand_cmplxdiv_wide): Use expand_abs to get the absolute values. Mon Jun 7 22:30:37 1999 Jeffrey A Law (law@cygnus.com) * fixinc/inclhack.def (bad_lval): Remove bogus selector. * fixinc/inclhack.sh, fixinc/fixincl.x, fixinc/fixincl.sh; Rebuilt. * fixinc/inclhack.def (avoid_bool): Also catch "typedef [unsigned] int bool". * fixinc/inclhack.sh, fixinc/fixincl.x, fixinc/fixincl.sh: Rebuilt. * m68k/x-hp3bsd44: Delete obsolete and incorrect file. * configure.in (m68k-hp-bsd4.4): No longer use x-hp3bsd44. * configure: Rebuilt. Mon Jun 7 22:05:03 1999 Mark Kettenis * config/i386/gnu.h: Include right after , such that we can override its definitions if necessary. (CPP_SPEC): New define. Support processor specific predefines via %(cpp_cpu). (CC1_SPEC): New define. Support processor specific compiler options via %(cc1_cpu). (STARTFILE_SPEC): New define. Use crt0.o instead of crt1.o for -static. 1999-06-07 Kaveh R. Ghazi * fixinc/inclhack.def (math_gcc_ifndefs): Insert whitespace between sed's -e flag, and the open-quote following it. * fixinc/fixincl.x, fixinc/fixincl.sh: Rebuilt. Mon Jun 7 20:34:20 1999 Robert Lipe Jeffrey A Law (law@cygnus.com) * varasm.c (assemble_start_function): Remove the function from the pending weak decls list when we define a function. (assemble_variable): Similarly for variables. (weak_finish): Ignore items on the list with a NULL name. (remove_from_ending_weak_list); New function to "remove" an item from the pending weak declarations list. Mon Jun 7 19:27:07 1999 Jerry Quinn * pa.md (fmpyfadd, fmpynfadd, fnegabs): New patterns. Sun Jun 6 11:58:34 1999 Jakub Jelinek * sparc.md (abstf2): This should be an expand. (split after abstf2_notv9): Fix mode. (abstf2_hq_v9): New pattern. (abstf2_v9): Only use when no hard quad. (absdf2_v9): Fix if target is not the same as source. (ashrsi3_extend, ashrsi3_extend2, lshrsi3_extend, lshrsi3_extend2): Add correct output constraints. Sat Jun 5 17:04:16 1999 Craig Burley From Dave Love to egcs-patches on 20 May 1999 17:38:38 +0100: * invoke.texi: Clarify text vis-a-vis Intel CPUs. Fri Jun 4 13:30:27 1999 Rainer Orth * alpha/osf.h (CPP_SUBTARGET_SPEC): Handle -threads. (LIB_SPEC): Likewise. Link with -lprof1_r for -g/-pg. 1999-06-04 Andreas Schwab * loop.c (check_dbra_loop): Fix change of Jan 19. Fri Jun 4 00:12:40 1999 Marc Espie * freebsd-elf.h (SWITCH_TAKES_ARG): Redefine, not define. (STARTFILE_SPEC): Define, override the svr4.h version. (ENDFILE_SPEC): Likewise. Thu Jun 3 23:58:55 1999 Jeffrey A Law (law@cygnus.com) * fixinc/inclhack.def (limits_ifndefs): Also apply to sys/limits.h * fixinc/fixincl.x: Regenerated. * fixinc/inclhack.sh: Regenerated. Thu Jun 3 07:48 1999 Bruce Korb * fixinc/inclhack.def(Io_Def_Quotes): corrected sed expression * fixinc/fixincl.x: regenerate * fixinc/inclhack.sh: regenerate Thu Jun 3 22:27:50 1999 Robert Lipe * i386/udk.h (LINK_SPEC): Correct linker search path for system libraries. Thu Jun 3 02:15:07 1999 Jason Merrill * dwarf2out.c (add_incomplete_type): New fn. (gen_struct_or_union_type_die): Call it. (retry_incomplete_types): New fn. (dwarf2out_finish): Call it. Thu Jun 3 01:19:03 1999 Jeffrey A Law (law@cygnus.com) * gcse.c (insert_insn_end_bb): Correct placement of insns when the current block starts with a CODE_LABEL and ends with a CALL and we can not find all the argument setup instructions for the CALL. Wed Jun 2 12:25:55 1999 Richard Henderson * alpha.c (override_options): Thinko in last patch. * alpha/osf.h (CPP_SUBTARGET_SPEC): Define. (LIB_SPEC): Recognize -pthread. Wed Jun 2 07:07 1999 Bruce Korb * fixinc/fixincl.c(global def): Add FD_SHELL_SCRIPT to mark fixes that need "file=xxx\n" prepended before invocation (start_fixer - new): starting the fixer process is complex enough to warrent its own routine. It prepends the "file=xxx\n" stuff. (process): uses the new routine; omit usage of putenv() * fixinc/fixincl.tpl: mark shell scripts with FD_SHELL_SCRIPT * fixinc/fixincl.x: regenerate Wed Jun 2 06:36:14 1999 Richard Earnshaw (rearnsha@arm.com) * arm.md (zero_extendqidi2): Don't allow operand1 to be a memory reference. Temporary work-around for problems with constant pool handling. Wed Jun 2 02:40:43 1999 Jeffrey A Law (law@cygnus.com) * README, configure.in, gcc.1, gcc.texi: Update name (egcs -> gcc) and version #s (1.1 -> 2.95) as needed. * README.g77: Kill way out of date file in the toplevel directory. Wed Jun 2 00:52:34 1999 David O'Brien * configure.in (i[34567]86-*-freebsdelf): Don't include linux.h, i386/freebsd-elf.h no longer requires it. Instead include svr4.h. * configure: Rebuilt. * i386/freebsd-elf.h (DEFAULT_VTABLE_THUNKS): Define. (ASM_COMMENT_START, ASM_APP_ON, ASM_APP_OFF, SET_ASM_OP): Likewise. (PREFERRED_DEBUGGING_TYPE, WCHAR_UNSIGNED): Likewise. (SWITCH_TAKES_ARG): Likewise. * i386/freebsd.h: Remove FREEBSD_NATIVE support. * config/t-freebsd: Moved from config/i386/ so it can used for all FreeBSD targets. Mon May 31 02:22:55 1999 Philippe De Muyter * m68k/x-mot3300 (XCFLAGS): Fixed to match stb.o, not f/stb.o. Wed Jun 2 00:08:34 1999 Robert Lipe * configure.in (i[34567]86-*-udk*): Install headers with cpio. * configure: Rebuilt. Wed Jun 2 00:49:00 EDT 1999 John Wehle (john@feith.com) * flow.c (mark_regs_live_at_end, insn_dead_p, mark_set_1, mark_used_regs): Only give FRAME_POINTER_REGNUM and HARD_FRAME_POINTER_REGNUM special treatment if reload hasn't run or the frame pointer is needed. * haifa-sched.c (attach_deaths): Likewise. * sched.c (attach_deaths): Likewise. Thu May 27 22:06:52 1999 Mark Mitchell * cccp.c (handle_directive): Handle backslash-newlines in quoted strings correctly. Mon May 31 22:42:02 1999 Jeffrey A Law (law@cygnus.com) * Remove this patch (from the branch only) Wed May 26 09:53:05 1999 Mark Mitchell * fold-const.c (fold): STRIP_NOPS when deciding whether or not something is a candidate for optimize_bit_field_compare. Mon May 31 15:23:23 1999 Richard Henderson * alpha.md (reload_*_help): New patterns and splitters. (reload_*): Use them. (mov[qh]i): Likewise. Mon May 31 09:36:11 1999 Cort Dougan * rs6000/linux.h (LINK_SPEC): Use emulation elf32ppclinux. Sat May 29 19:08:10 1999 Philip Blundell * config/arm/aout.h (ASM_OUTPUT_ALIGN): Only define if not already defined. * config/arm/elf.h (ASM_OUTPUT_ALIGN): Define. (MAX_OFILE_ALIGNMENT): Likewise. Mon May 31 00:45:14 1999 Jeffrey A Law (law@cygnus.com) * jump.c (jump_optimize_1): Only set CAN_REACH_END if calculate_can_reach_end returns nonzero. * Makefile.in (CFLAGS): Remove warning flags. (WARN_CFLAGS): Disable. * configure.in (native gas tests): Search for an assembler in the same manner that the installed compiler will. * configure: Rebuilt. * tm.texi (MD_EXEC_PREFIX): Note need to update configure.in too. * alias.c (find_base_term): Improve handling of addresses constructed from binary operations. Sun May 30 14:43:37 1999 Robert Lipe * fixincl.c: Replace local include scheme with #includes of gansidecl.h and system.h. * procopen.c: Likewise. * server.c: Likewise. Sun May 30 14:18:40 1999 Jeffrey A Law (law@cygnus.com) * function.h (cleanup_label, frame_offset): Declare. (tail_recursion_label, tail_recursion_reentry): Likewise. (arg_pointer_save_area, rtl_expr_chain): Likewise. * stmt.c (cleanup_label, frame_offset): Delete extern declarations. (tail_recursion_label, tail_recursion_reentry): Likewise. (arg_pointer_save_area, rtl_expr_chain): Likewise. Fri May 28 03:47:03 1999 Eric Raskin (ehr@listworks.com) * i386/t-dgux (EXTRA_PARTS): Add crti.o. (crti.o): Add build rule and dependencies. Fri May 28 03:07:10 1999 Franz Sirl * rs6000/sysv4.h (CC1_SPEC): Add support for -profile (LIB_LINUX_SPEC): Likewise. (LIB_LINUX_SPEC): Add support for -pthread (CPP_OS_LINUX_SPEC): Likewise. (CPP_SYSV_SPEC): Avoid redefinitions if both -fpic and -fPIC are specified * rs6000.c (output_mi_thunk): Enable full support again. Thu May 27 13:04:52 1999 H.J. Lu (hjl@gnu.org) * i386.c (output_fp_cc0_set): Don't check the JUMP_INSN code for conditional move. (notice_update_cc, output_float_compare): Enable TARGET_CMOVE support. (output_float_compare, output_fp_cc0_set): Fix the FLOAT comparison for IEEE math and CC_FCOMI. (put_jump_code): No IEEE if CC_FCOMI is set. 1999-05-27 Andreas Schwab * fold-const.c (fold_truthop): Make the field reference unsigned when converting a single bit compare. Thu May 27 03:07:13 1999 Philip Blundell Based on patch by Scott Bambrough and Pat Beirne: * config/arm/arm.c (making_const_table): New variable. * config/arm/arm.h (making_const_table): Declare. (OUTPUT_INT_ADDR_CONST): Mark symbols as position independent if appropriate. * config/arm/arm.md (consttable_4, consttable_8, consttable_end): Keep track of when we are building the constant table. Thu May 27 02:52:55 1999 Jeffrey A Law (law@cygnus.com) * varasm.c (STRIP_NAME_ENCODING): Remove default definition. * output.h (STRIP_NAME_ENCODING): Strip '*' like the old varasm version did. Thu May 27 02:40:48 1999 J"orn Rennecke * loop.c (strength_reduce): Don't do biv->giv conversion on constants. Thu May 27 02:09:27 1999 Jeffrey A Law (law@cygnus.com) * reload.c (push_reload): Do not call remove_address_replacements when presented with identical optional reloads. Wed May 26 14:18:05 1999 Richard Henderson * alpha.h (MASK_FIX, TARGET_FIX): New. (MASK_*): Reorganize constants. (CPP_AM_FIX_SPEC): New. (TARGET_SWITCHES): Add FIX. (EXTRA_SPECS): Likewise. (CPP_CPU_EV6_SPEC): Use FIX, not CIX. (SECONDARY_MEMORY_NEEDED): Likewise. (REGISTER_MOVE_COST): Likewise. * alpha.c (override_options): Add FIX support. Always use ALPHA_TP_PROG for ev6. * alpha.md (sqrt and mov[sd]i patterns): Use FIX, not CIX. * alpha/elf.h (ASM_FILE_START): Look at FIX too. * configure.in (target_cpu_default2) [ev6]: Use FIX, not CIX. Wed May 26 09:53:05 1999 Mark Mitchell * fold-const.c (fold): STRIP_NOPS when deciding whether or not something is a candidate for optimize_bit_field_compare. Wed May 26 03:54:33 1999 Melissa O'Neill * fixinc/fixincl.c: (WIFSIGNALED): Define if not already defined. (WTERMSIG, WIFEXITED, WEXITSTATUS, WIFSTOPPED, WSTOPSIG): Likewise. (S_IRUSR, S_IWUSR, S_IXUSR, S_IRGRP, S_IWGRP, S_IXGRP): Likewise. (S_IROTH, S_IWOTH, S_IXOTH, S_IRWXU, S_IRWXG, S_IRWXO): Likewise. Wed May 26 02:19:31 1999 Philip Blundell * arm.h (NEED_PLT_GOT): Fix mistake in last change. (GOT_PCREL): New macro. Define to 1 if not already defined. * arm/elf.h (GOT_PCREL): Define to 0. * arm.c (arm_finalize_pic): Take into account the setting of GOT_PCREL. Tue May 25 14:06:06 1999 Jeffrey A Law (law@cygnus.com) * output.h (STRIP_NAME_ENCODING): Provide default definition. * dwarf2out.c (ASM_NAME_TO_STRING): Use STRIP_NAME_ENCODING. * flow.c (mark_set_1): Do not record BLKmode stores as dead store elimination candidates. Mon May 24 14:34:31 1999 Jeffrey A Law (law@cygnus.com) * loop.c (strength_reduce): Do not clear NOT_EVERY_ITERATION at the last CODE_LABEL in a loop if we have previously passed a jump to the top of the loop. Mon May 24 01:02:58 1999 Mark Mitchell * stmt.c (expand_end_bindings): Ignore any elements of VARS that are not VAR_DECLs. Sun May 23 20:31:16 1999 Jeffrey A Law (law@cygnus.com) * loop.c (strength_reduce): Grow reg_single_usage as needed. Sun May 23 10:13:20 1999 David O'Brien * i386/freebsd-elf.h (LINK_SPEC): Change -static to -Bstatic. Also remove a useless comment. Sun May 23 10:05:23 1999 Jerry Quinn * pa.md (negdf2,negsf2): Use fneg instead of fsub on pa 2.0. Sat May 22 01:27:49 1999 Mark Mitchell * expr.h (lang_expand_constant): Guard with #ifdef TREE_CODE. Thu May 20 10:00:42 1999 Stephen L Moshier * Makefile.in (GCC_FOR_TARGET): Add -I$(build_tooldir)/include. Thu May 20 09:58:57 1999 Jan Hubicka * function.c (assign_stack_local): Align stack slot propertly. (assign_outer_stack_local): Likewise. Thu May 20 10:38:43 1999 Mark Mitchell * expr.h (lang_expand_constant): Declare. * toplev.c (lang_expand_constant): Define it. * varasm.c (output_constant): Use it. Thu May 20 11:28:53 1999 Kaveh R. Ghazi * optabs.c (expand_cmplxdiv_straight, expand_cmplxdiv_wide): Change function definitions to K&R style. Thu May 20 08:15:00 1999 Bruce Korb * fixinc/fixincl.c(main): we must not ignore SIGCLD now. Thu May 20 07:06:39 1999 Alexandre Oliva * fixinc/Makefile.in(gnu-regex.o): add $(INCLUDES) to compile options * fixinc/fixincl.c(wait_for_pid): K&R-ify arguments (several places): omit static initialization (process): use single fd, since only the read fd is used * fixinc/gnu-regex.c: define 'const' away, if not supported * fixinc/procopen.c(several places): omit static initialization * fixinc/server.c: define 'volitile' away, if not supported 1999-05-20 Andreas Schwab * config/dbxcoff.h (DBX_OUTPUT_MAIN_SOURCE_FILE_END): Use asm_fprintf and %L to generate the label name. * config/dbxelf.h (DBX_OUTPUT_MAIN_SOURCE_FILE_END): Likewise. (ASM_OUTPUT_SOURCE_LINE): Correct generation of internal labels. Thu May 20 01:40:55 1999 Jeffrey A Law (law@cygnus.com) * jump.c (can_reverse_comparison_p): Do not abort if the comparison insn for a conditional jump can not be found. Wed May 19 23:58:58 1999 Jeffrey A Law (law@cygnus.com) * mips.h (ENCODE_SECTION_INFO): Do not perform GP optimizations on variables in specific sections other than .sbss and .sdata. Tue May 18 11:20:48 1999 Mark Mitchell * stmt.c (expand_return): Call start_cleanup_deferral and end_cleanup_deferral around conditional code. Wed May 19 03:10:08 1999 Bruce Korb * fixinc/fixincl.tpl: Avoid depending on ANSI C features for filename lists. Utilizes new AutoGen function "krstr". * fixinc/fixincl.x: Rebuilt. Wed May 19 02:47:11 1999 Jan Hubicka (hubicka@freesoft.cz) * i386.c (output_float_compare): Avoid GNU-C extensions. Wed May 19 00:50:24 1999 Jeffrey A Law (law@cygnus.com) * version.c: Bump version to gcc-2.95 prerelease. Tue May 18 03:53:37 1999 Craig Burley Improve open-coding of complex divide: * flags.h: Declare new front-end-malleable flag. * toplev.c: Define new flag. * optabs.c (expand_cmplxdiv_straight): New function to do original open-coding. (expand_cmplxdiv_wide): New function to do new open-coding, from Toon Moene, with changes (call to emit_barrier, dropping of spurious `ok = 1;', plus the obvious `break;' -> `return 0;'). (expand_binop): A bit of spacing fixing, while at it. Use new functions instead of inlining the open-coding code. Tue May 18 00:51:46 1999 Krister Walfridsson * configure.in (arm*-*-netbsd*): Use collect2. (i[34567]86-*-netbsd*): Likewise. (m68k*-*-netbsd*): Likewise. (ns32k-*-netbsd*): Likewise. (sparc-*-netbsd*): Likewise. (vax-*-netbsd*): Likewise. * configure: Rebuilt. Tue May 18 00:21:34 1999 Zack Weinberg * cppspec.c: Insert -no-gcc into command line unless -gcc was given by user. * gcc.c (default_compilers): Define __GNUC__ and __GNUC_MINOR__ only if -no-gcc was not given. * objc/lang-specs.h: Likewise. * cpp.texi: Document -x and -std options; explain that -lang is no longer supported. Minor related corrections. Mon May 17 23:56:39 1999 Alexandre Oliva * Makefile.in (stmp-fixproto): Pass location of mkinstalldirs to fixproto. * fixproto: Avoid unportable constructs such as `basename' and `mkdir -p'. Use mkinstalldirs from the environment if `mkdir -p' fails. * fixinc/fixincl.c: Remove #error, it is not portable. Mon May 17 23:50:41 1999 Marc Espie * collect2.c (main): Fix typo in COLLECT2_HOST_INITIALIZATION. Mon May 17 19:45:41 1999 Rainer Orth * fixinc/fixincl.c (process): Wait for children from chain_open() to avoid creating zombies. * fixinc/inclhack.tpl: Removed no-op pipe. * fixinc/inclhack.sh fixinc/fixincl.sh: regenerate Mon May 17 07:23:34 1999 Mark Mitchell * tree.def (TYPE_NONCOPIED_PARTS): Revise documentation to match reality. * expr.c (init_noncopied_parts): Don't generate initializers for parts that don't need them. Mon May 17 02:56:35 PDT 1999 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. Sat Oct 31 05:08:34 CET 1998 Jan Hubicka (hubicka@freesoft.cz) * reg-stack.c: Do not emit pop insns after cc0 setter. (emit_pop_insn): Do not emit insn in case WHEN is NULL. (compare_for_stack_reg): Update REG_DEAD note and do not emit push insn. * i386.c: (output_float_compare): Handle new REG_DEAD notes. Mon May 17 01:57:37 1999 David Daney * i386/sol2.h (LINK_SPEC): Do not pass "-z text" to the linker if -mimpure-text. 1999-05-17 Andreas Schwab * m68k.c (standard_68881_constant_p): Don't accept -0.0 as valid 68881 constant. * fold-const.c (fold_truthop): When converting a one-bit comparison don't sign extend the constant. * cse.c (cse_insn): Copy SRC_CONST before putting it in the REG_EQUAL note. 1999-05-17 Mike Stump * rs6000/vxppc.h (CPP_SPEC): Fix support for vararg functions. Sat May 15 14:22:40 1999 Jeffrey A Law (law@cygnus.com) * fixinc/hackshell.tpl: Fix mis-applied patch. * fixinc/inclhack.sh: Regenerated. Thu May 13 21:05:55 1999 Mark Kettenis * fixinc/mkfixinc.sh: Add the Hurd (*-*-gnu*) to the list of targets that do not need any fixes. Sat May 15 14:12:38 1999 Michael Hayes * config/c4x/c4x.md (set_lo_sum+2): New splitter to load large const_ints. Sat May 15 14:09:08 1999 Michael Hayes * config/c4x/c4x.md (decrement_and_branch_on_count): Disabled. (doloop_begin, doloop_end): New patterns. (*rptb_init): Added extra operands. Fri May 14 21:31:36 1999 Michael Hayes * config/c4x/c4x.md (*umulqi3_highpart_clobber): Fix operand 2 constraints order. 1999-05-14 Ulrich Drepper * fixinc/fixinc.x86-linux-gnu (FD_ZERO): Fix operand numbers in asm input operands. Thu May 13 15:34:18 1999 David Edelsohn * rs6000.c (mask_constant): Delete. (mask_operand): Move mask_constant() body to here. * rs6000.h (mask_constant): Delete declaration. * rs6000.md (nabsdi2): Reverse subtraction in splitter. Thu May 13 02:25:01 1999 Jeffrey A Law (law@cygnus.com) * cpp.texi: Fix some typos. Thu May 13 01:49:55 1999 Graham Stott * loop.c (maybe_eliminate_biv): Check regno against max_reg_before_loop. * i386.c (memory_address_info): Correct the scale factor test. Thu May 13 01:31:19 1999 Nick Burrett * arm.md (nop): Backout Apr 27 change. Ensure REGISTER_PREFIX is applied to each register. * aof.h (ASM_FILE_START): Define register `r0'. 1999-05-12 20:22 -0400 Zack Weinberg * configure.in: Make --enable-cpp and --with-cpp-install-dir documented options. Enable the cpp driver by default. * configure: Rebuilt. Wed May 12 18:08:48 1999 David Edelsohn Richard Henderson * rs6000.c (print_operand) [w]: Calculate signed constant more clearly. (rs6000_allocate_stack_space): Print as hexadecimal value. * rs6000.h (CONST_OK_FOR_LETTER_P): 'L' checks for a signed, 16-bit shifted constant. Fix typo for 'P'. (EXTRA_CONSTARINT): 'T' checks for a 32-bit mask operand. * rs6000.md (movsi, addsi3_internal1, movdi, adddi3_internal1): Use 'L' for shifted constant. (anddi3_internal3): Fix typo. (32-bit mask patterns): Use 'T'. Wed May 12 07:30:31 1999 Bruce Korb * fixinc/fixincl.c(quoted_file_exists): new procedure to ensure that a file exists before trying to copy it into the destination (extract_quoted_files): use that routine. Wed May 12 07:27:31 1999 Craig Burley Allow front end (like g77's) to override maintenance of errno: * expr.c (expand_builtin): Bother with errno only if flag_errno_math. * flags.h: Declare flag_errno_math. * toplev.c: Define flag_errno_math. Tue May 11 23:55:49 1999 Jeffrey A Law (law@cygnus.com) * fixproto: Change "mkdir" calls to "mkdir -p" * fixinc/inclhack.def (io_def_quotes): Consistently allow multiple whitespace characters between the "define" and the name of the macro. * fixinc/fixincl.x, fixinc/inclhack.sh: Rebuilt. Tue May 11 20:46:37 1999 Richard Henderson * alpha.c (alpha_expand_block_move): Handle TImode registers used with ADDRESSOF. (alpha_expand_block_clear): Handle ADDRESSOF specially. 1999-05-11 Ulrich Drepper * fixinc/fixinc.x86-linux-gnu (FD_ZERO): Remove unneccessary memory output operand which irritates gcc. Tue May 11 11:45:16 1999 Dave Brolley * toplev.c (documented_lang_options): Add -MD, -MMD, -M and -MM for cpplib-enabled compilers. Tue May 11 11:34:56 1999 Vladimir Makarov * config/sparc/sparc.h (GO_IF_LEGITIMATE_ADDRESS): Add parentheses around &&. Mon May 10 13:51:24 1999 Nick Clifton * tm.texi (FUNCTION_ARG): Stack element of PARALLEL must come first. Tue May 11 01:32:01 1999 Jeffrey A Law (law@cygnus.com) * fixinc/inclhack.def (sun_auth_proto): Apply to all targets. (sysz_stdlib_for_sun): Similarly. * fixinc/fixincl.x, fixinc/inclhack.sh: Rebuilt. Mon May 10 20:34:10 1999 Jim Wilson * config/mips/elf.h (UNIQUE_SECTION_P): Undef. * config/mips/elf64.h (UNIQUE_SECTION_P): Undef. * config/mips/mips.h (UNIQUE_SECTION_P): Define to 0. 1999-05-10 18:21 -0400 Zack Weinberg * cppfiles.c (initialize_input_buffer): New function. (finclude): Call it, if pfile->input_buffer is NULL. Accept any character device as an input file. (read_and_prescan): Use pfile->input_buffer and pfile->input_speccase. * cppinit.c (cpp_cleanup): Free pfile->input_buffer and pfile->input_speccase. * cpplib.h (cpp_reader): Add input_buffer, input_speccase, and input_buffer_len members. Use memcpy in CPP_PUTS_Q. * cppmain.c: Buffer output in the token_buffer; throttle number of calls to fwrite; check for errors from fwrite. 1999-05-10 18:21 -0400 Zack Weinberg * cppspec.c: Treat two non-option arguments as input and output file. Three or more non-option args is an error. Clean up. * gcc.c (default_compilers): Pass -$ to the preprocessor. * objc/lang-specs.h: Likewise. Mon May 10 12:59:20 1999 Jeffrey A Law (law@cygnus.com) * optabs.c (emit_cmp_and_jump_insns): Handle the case where both operands to the comparison are constants. Mon May 10 07:28:10 1999 Bruce Korb * fixinc/inclhack.def(arm_norcroft_hint): check before fixing (no_double_slash): portability (math_exception): added reminder comment Mon May 10 01:28:10 1999 Craig Burley From Fri May 7 9:31:41 1999 Donn Terry (donn@interix.com): * varasm.c (mark_constant_pool): Add some transitive closure. Sun May 9 22:51:04 1999 Craig Burley Fix gcc.dg/990506-0.c: * c-typeck.c (require_complete_type): Handle ERROR_MARK input. Sun May 9 13:19:12 1999 Jeffrey A Law (law@cygnus.com) * gcse.c (cprop_insn): Do not try to simplify a simple jump. Sun May 9 11:12:19 1999 Philip Blundell * config/arm/arm.h (ASM_OUTPUT_MI_THUNK): Add (PLT) to branch if necessary. Reported by jim@federated.com. Sat May 8 23:05:35 1999 Jeffrey A Law (law@cygnus.com) * pa.h (PRINT_OPERAND_ADDRESS): Output "%r0", not "r0" for the base register in an absolute memory address. * pa.md (conditional moves): Avoid using immediate zero for register zero. Sat May 8 06:23:21 1999 Philip Blundell Based on patch by Scott Bambrough: * config/arm/arm.h (NEED_PLT_GOT): New macro. Set to 0 if not already defined. * config/arm/elf.h (NEED_PLT_GOT): Define to flag_pic. * config/arm/arm.md (call_symbol, call_value_symbol et al.): If NEED_PLT_GOT is true, add explicit "(PLT)" to generated branches. * config/arm/arm.c (output_func_epilogue, output_return_instruction): Likewise for calls to abort. Sat May 8 01:57:58 1999 Donn Terry (donn@interix.com) * calls.c (rtx_for_function_call): Extend function pointer being passed to chkr_check_exec_libfunc, if needed. Sat May 8 01:51:50 1999 David Edelsohn * ginclude/stdarg.h (__va_rounded_size): Use long type for rounding on AIX. * ginclude/varargs.h: Likewise. Sat May 8 01:47:20 1999 Andreas Schwab * invoke.texi: Remove duplicates in the description of -d letters. Fix use of @item vs. @itemx. Sat May 8 01:43:02 1999 Franz Sirl * rs6000.h (RS6000_VARARGS_OFFSET): Die die die. (CUMULATIVE_ARGS): Remove varargs_offset; update commentary. * rs6000.c (setup_incoming_varargs): Fix typo last change. (init_cumulative_args): Remove varargs_offset references. * rs6000/linux.h (NO_IMPLICIT_EXTERN_C): Define. (MD_EXEC_PREFIX, MD_STARTFILE_PREFIX): Undefine. Sat May 8 01:34:19 1999 Andreas Schwab * reload1.c (gen_mode_int): New function. (reload_cse_move2add): Use it to generate the new constants. Sat May 8 01:25:09 1999 Andreas Schwab * varasm.c (output_constant): Do nothing if -fsyntax-only. Fri May 7 19:10:15 1999 Vladimir Makarov * sparc.h (GO_IF_LEGITIMATE_ADDRESS): Prohibit REG+REG addressing for TFmode when there are no instructions which accept REG+REG instructions. Fri May 7 12:38:54 1999 Jim Wilson * mips/elf64.h (MAKE_DECL_ONE_ONLY, UNIQUE_SECTION_P): Define. * mips/mips.c (mips_select_rtx_section): When TARGET_MIPS16, use function_section instead of text_section. * mips/mips.h (ENCODE_SECTION_INFO): Add check for UNIQUE_SECTION_P in TARGET_MIPS16 STRING_CST handling. Fri May 7 09:54:11 1999 Nick Clifton Patch from: Nick Burrett * arm.c (arm_poke_function_name): New function to implement -mpoke-function-name. * aof.h (ASM_DECLARE_FUNCTION_NAME): Call it. * aout.h (ASM_DECLARE_FUNCTION_NAME): Likewise. * elf.h (ASM_DECLARE_FUNCTION_NAME): Likewise. * arm.h: Prototype it. (TARGET_SWITCHES): Add `no-poke-function-name'. Fri May 7 14:19:31 1999 Rainer Orth * fixinc/server.c (load_data): Cast text_size to long, adapt format. * fixinc/server.c (read_pipe_timeout): Declare volatile, modified in signal handler. (sig_handler): Add debug code. * fixinc/server.c (run_shell): Don't \-escape cd, it breaks the Ultrix V4.3 /bin/sh. * fixinc/server.c (def_args): Use static instead of STATIC to avoid redefinition error from linker iff DEBUG. * fixinc/hackshell.tpl: Don't strip trailing directory from DESTDIR - that is already done * fixinc/fixincl.c (run_compiles): fix memory leak Thu May 6 20:34:00 1999 Mark Mitchell * resource.c (mark_referenced_resources): Make volatil monotonically increasing. (mark_set_resources): Likewise. Thu May 6 20:02:33 1999 Fred Fish * rs6000/xm-beos.h (HAVE_VPRINTF): Don't redefine if already defined. (HAVE_PUTENV, HAVE_ATEXIT, HAVE_RENAME): Likewise. Wed May 5 20:28:32 1999 Jason Merrill * install.texi (Header Dirs): s/GPLUS/GPLUSPLUS/. Wed May 5 23:44:15 1999 J"orn Rennecke * unroll.c (copy_loop_body): Don't copy VTOP notes from copy_notes_from. Wed May 5 16:26:13 1999 Vladimir Makarov * function.c (purge_addressof_replacements): Rename into purge_bitfield_addressof_replacements. (purge_addressof_replacements): New variable. (purge_addressof_1): Add code for changing addressof in notes for field values which are extracted by usage MEM with narrower mode. (purge_addressof): Initialize purge_bitfield_addressof_replacements. Wed May 5 07:40:02 1999 Nick Clifton Patch from: Nick Burrett * config/arm/arm.h (ARM_MCOUNT_NAME): Define. (FUNCTION_PROFILER): Remove assembler dialect dependency and use ARM_MCOUNT_NAME. (TRAMPOLINE_TEMPLATE): Remove assembler dialect dependency. * config/arm/aof.h (ARM_MCOUNT_NAME): Define. 1999-05-05 09:58 -0400 Zack Weinberg * gcc.c (default_compilers): Fix brace nesting bug. * objc/lang-specs.h: Use %i, not %g.mi, for the input file when processing an .mi file. Tue May 4 13:17:55 1999 Mark Mitchell * resource.c (mark_set_resources): Handle UNSPEC_VOLATILE, ASM_INPUT, TRAP_IF, and ASM_OPERANDS just like in mark_referenced_resources. Mon May 3 22:38:41 1999 David Edelsohn * rs6000/aix43.h (SUBTARGET_OVERRIDE_OPTIONS): Change non-PowerPC and AIX64 combination to warning. Add warning for disabling PowerPC64 support when using 64-bit mode. (LIB_SPEC): Do not link with libg.a in 64-bit mode. (LINK_SPEC): Do not export libg.exp symbols in 64-bit mode. * rs6000/rs6000.h (MY_ISCOFF): Treat import/export files as valid XCOFF files. (read_only_data_section, private_data_section, read_only_private_data_section): Always align CSECTs to doubleword boundary regardless of mode. (TEXT_SECTION_ASM_OP): Align text CSECT on doubleword boundary in 64-bit mode. (DATA_SECTION_ASM_OP): Always align CSECT to doubleword boundary. (ASM_OUTPUT_LOCAL): Use rounded size in 64-bit mode to maintain doublword alignment. Mon May 3 14:45:23 1999 Jeffrey A Law (law@cygnus.com) * mn10200.md (btst insns): btst does not leave cc0 in a useable state for redundant tst eliminatino. * mn10300.md (btst insns): Likewise. Mon May 3 16:14:32 1999 Kaveh R. Ghazi * mips.h (Pmode): Revert Oct 14th change which added a cast. Sun May 2 14:02:21 1999 Mark Mitchell * tree.h (struct tree_decl): Add comdat_flag. (DECL_COMDAT): Define it. * toplev.c (wrapup_global_declarations): Don't output a DECL_COMDAT function just because it's public. Sun May 2 15:16:42 1999 Joseph S. Myers * pdp11.h (TARGET_SWITCHES): Fix error in previous change. (ASSEMBLER_DIALECT): Define. (CONDITIONAL_REGISTER_USAGE): Rename floating point registers if required for the UNIX assembler. (ASM_OUTPUT_INT): Remove. The compiler will synthesise it. (ASM_OUTPUT_ADDR_VEC_PROLOGUE): Remove. (ASM_OPEN_PAREN, ASM_CLOSE_PAREN): Change to "[" and "]". (TRAMPOLINE_TEMPLATE): Use ASM_OUTPUT_SHORT. * pdp11.c (output_addr_const_pdp11): Copy of output_addr_const adapted to output constants in octal. * pdp11.c, pdp11.h, pdp11.md: Use output_addr_const_pdp11 instead of output_addr_const. Output constants in octal. Use assembler dialect alternatives where DEC and UNIX assemblers use different instruction names. Sun May 2 01:15:06 PDT 1999 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. Fri Apr 30 13:55:43 1999 Richard Henderson * va-ppc.h (__va_start_common): Let __builtin_saveregs do the work. * rs6000.c (expand_builtin_saveregs): For V4, initialize a private va_list struct, and return a pointer to it. (setup_incoming_varargs): V4 save area based off virtual_stack_vars instead of frame_pointer. Thu Apr 29 23:02:22 1999 Mark Mitchell * emit-rtl.c (start_sequence): Expand comments. (start_sequence_for_rtl_expr): Likewise. (push_to_sequence): Likewise. (end_sequence): Likewise. * expr.c (inhibit_defer_pop): Likewise. * expr.h (inhibit_defer_pop): Likewise. (NO_DEFER_POP): Likewise. (OK_DEFER_POP): Likewise. Thu Apr 29 22:13:46 1999 Robert Lipe * configure.in (i?86-UnixWare7*-sysv): Set thread_file to 'posix' --enable-threads[={yes,pthreads,posix}] is passed as a command line parameter to configure. * config/i386/sysv5.h (LIB_SPEC): Add support for '-pthread'. (CPP_SPEC): Likewise. Thu Apr 29 17:23:59 1999 Richard Henderson * emit-rtl.c (operand_subword): Religiously mask and sign-extend from 32-bits to HOST_WIDE_INT. Thu Apr 29 15:58:52 1999 Robert Lipe * fixinc/regex.c, fixinc/regex.h: Removed. Replace with... * fixinc/gnu-regex.c, fixinc/gnu-regex.h: Imported from GDB 4.18. * fixinc/Makefile.in (OBJ, HDR): Handle name changes from above. (gnu-regex.o): Define REGEX_MALLOC to avoid memory leak. * fixinc/fixincl.c: new regex.h header name * Makefile.in: new regex.[ch] file names Thu Apr 29 12:53:33 1999 Richard Henderson * calls.c (emit_call_1): Pass rounded_stack_size to emit_call instead of the unrounded size. 1999-04-28 14:40 Bruce Korb * fixinc/mkfixinc.sh: Makesure the result shell script is writable Wed Apr 28 10:36:39 1999 Andreas Schwab * config/m68k/m68k.md (cmpsi+1): Use cmp.w when comparing a 16 bit constant with an address register. Wed Apr 28 00:14:41 PDT 1999 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. Tue Apr 27 19:50:25 EDT 1999 Andrew MacLeod * rtl.h (REG_EH_REGION): Update comment to indicate a value of -1 indicates no throw and no nonlocal gotos. * optabs.c (emit_libcall_block): Emit REG_EH_REGION with a value of -1 instead of 0 to indicate a nonlocal goto won't happen either. * flow.c (count_basic_blocks, find_basic_blocks_1): Ignore libcall blocks, look for REG_EH_REGION note exclusively. (make_edges): Check for REG_EH_REGION > 0 for specified handlers. Tue Apr 27 15:33:42 1999 David Edelsohn * rs6000.h (read_only_data_section, private_data_section, read_only_private_data_section, toc_section): Align CSECT on doubleword boundary for 64-bit target. (DATA_SECTION_ASM_OP): Likewise. * rs6000.c (rs6000_stack_info): Leaf procedure stack limit is 288. Tue Apr 27 20:19:47 1999 J"orn Rennecke * sh.md (insv): Use copy_addr_to_reg. * final.c (insn_lengths_max_uid): New variable. (init_insn_lengths, shorten_branches): Set it. (get_attr_lengths): Test insn uid against insn_lengths_max_uid. 1999-04-27 08:32 -0400 Zack Weinberg * expr.c (emit_move_insn_1): Abort if MODE argument is invalid. (compare): Punt if TREE_OPERAND (exp, 0) is an ERROR_MARK. Tue Apr 27 01:33:43 1999 Jeffrey A Law (law@cygnus.com) * Makefile.in (ORDINARY_FLAGS_TO_PASS): Renmaed from FLAGS_TO_PASS. Remove "CC". (FLAGS_TO_PASS): New variable. Tue Apr 27 00:36:44 1999 Nick Burrett * arm.md (nop): Output instruction using output_asm_insn to fix assembler dialect problems. Mon Apr 26 23:55:50 1999 Robert Lipe * Makefile.in (fixinc.sh): Fix dependencies. * fixinc/inclhack.def (avoid_bool): Enable match if typedefs are prepended by spaces. (sco5_stat_wrappers): New fix. Make sys/stat.h C++ safe. * fixinc/fixincl.sh, fixinc/fixincl.x, fixinc/inclhack.sh: Rebuilt. Mon Apr 26 23:28:54 1999 Mumit Khan Donn Terry * function.c (put_var_into_stack): Change ptr_mode to Pmode in setup for chkr_set_right_libfunc calls. (assign_params): Likewise. * expr.c (emit_push_insn): Change ptr_mode to Pmode in setup for chkr_copy_bitmap_libfunc and chkr_set_right_libfunc calls. (expand_assignment): Change ptr_mode to Pmode in setup for chkr_add_libfunc and chkr_copy_bitmap_libfunc. (store_expr): Change ptr_mode to Pmode in setup for chkr_add_libfunc and chkr_copy_bitmap_libfunc. (expand_expr): Change ptr_mode to Pmode in setup for chkr_check_addr_libfunc. (expand_builtin): Change ptr_mode to Pmode in setup for chkr_check_str_libfunc, chkr_copy_bitmap_libfunc and chkr_check_addr_libfunc. * calls.c (rtx_for_function_call): Change ptr_mode to Pmode in setup for chkr_check_exec_libfunc. (expand_call): Change ptr_mode to Pmode in setup for chkr_set_right_libfunc. (expand_call): Change ptr_mode to Pmode in setup for chkr_set_right_libfunc. (store_one_arg): Change ptr_mode to Pmode in setup for chkr_set_right_libfunc. * c-parse.in (absdcl1): Allow attributes in explicit typespecs. (%expect): Update. * c-parse.y: Regenerate. * c-parse.c: Likewise. * objc/objc-parse.c: Likewise. * objc/objc-parse.y: Likewise. Mon Apr 26 21:17:41 1999 Jason Merrill * c-pragma.c (push_alignment): Don't ignore alignments greater than 4 bytes. (handle_pragma_token): Likewise. * c-pragma.c: Support for #pragma pack (push, , ). (struct align_stack): Add id field. (push_alignment, pop_alignment): Take id parameter. (handle_pragma_token): Add necessary states. * c-pragma.h (enum pragma_state): Add necessary states. Tue Apr 27 13:58:23 1999 Michael Hayes * config/c4x/c4x.md (*cmpqf, *cmpqf_noov, *cmpqi_test, *cmpqi_test_noov): Remove ? modifier from constraints list. (*smulqi3_highpart_clobber, *umulqi3_highpart_clobber): Swap output strings to match new constraint ordering. 1999-04-26 19:16 -0400 Zack Weinberg * cpphash.c (dump_definition): New function. * cpphash.h: Prototype it. * cpplib.c (handle_directive): Don't output anything here. Streamline. (pass_thru_directive): Take a length, not a pointer to the end. All callers changed. (do_define): Handle -dD, -dN, -g3 entirely here. Streamline. (do_include): Handle -dI here. (do_ident): Correct to match cccp. (do_pragma): Copy the pragma through here. (do_assert, do_unassert): Tidy. * cppinit.c (cpp_finish): If -dM was specified, walk the macro hash table and call dump_definition on all the entries. * cppmain.c: cpp_finish may produce output. Mon Apr 26 15:27:33 1999 Mark Mitchell * toplev.c (compile_file): Move call to check_global_declarations after output_exception_table to restore behavior as it was before 1999-04-22 change. 1999-04-26 10:50 -0700 Bruce Korb * fixinc/fixincl.c: Improve the handling of child process exits * fixinc/server.[ch]: Export the interface for shutting down the server process * fixinc/inclhack.tpl: Remove unnecessary character quote * fixinc/fixincl.sh, fixinc/inclhack.sh: Regenerate Mon Apr 26 10:41:42 EDT 1999 Andrew MacLeod * alpha.md (builtin_setjmp_receiver): Use a label_ref instead of a code label. 1999-04-26 09:47 -0400 Zack Weinberg * rtl.texi: Document the rtl classes and their relation to formats. Mon Apr 26 01:02:38 1999 Richard Henderson * alpha.md (fix_trunc patterns): Use reg_no_subreg_operand on op0 for less work in reload. (movsf and movdf patterns): Put fp reg alternatives first. Mon Apr 26 01:55:56 1999 Marc Espie * configure.in (openbsd): Factorize xmake_file. (ix86 openbsd): Trim obsolete comment. (vax openbsd): Fix typo. * configure: Rebuilt. Mon Apr 26 01:30:59 1999 Donn Terry * expr.c (expand_assignment): Improve test for pointer type. Mon Apr 26 00:26:18 1999 Richard Henderson * alpha.c (print_operand_address): Account for the subreg word. Mon Apr 26 01:08:36 1999 Toshiyasu Morita (tm@netcom.com) * fold-const.c (make_range): Always initialize arg0 and arg1. (fold): Similarly for alt0 and alt1. * function.c (fixup_var_refs_insns): Initialize insn_list. (instantiate_virtual_regs_1): Initialize offset. * optabs.c (expand_binop): Initialize carry_in, carry_out, op0_xhigh and op1_xhigh. * stmt.c (expand_end_case): Initialize minval and maxval. Mon Apr 26 01:02:34 1999 Nathan Sidwell * toplev.c (report_error_function): Reorder file stack and function name printing. Ignore FILE parameter. Mon Apr 26 00:58:54 1999 Jerry Quinn * pa.h (architecture_type): New enum. (pa_arch_string, pa_arch): Declare. (MASK_PA_10, MASK_PA_20): New flags. (TARGET_SWITCHES): Add pa-risc-2-0. Update docs for PA1.0 codegen. (TARGET_OPTIONS): Add -march= option. * pa.c (pa_arch, pa_arch_string): Define. (override_options): Set them. * pa/pa-hpux10.h (ASM_FILE_START): Output LEVEL 2.0 asm directive for 2.0 architecture. * invoke.texi (Option Summary, HPPA Options): Document new architecture flags. * pa/pa-hpux.h, pa/pa-hpux10.h, pa/pa-hpux9.h, pa/pa-osf.h, pa.h, pa.c, pa.md, configure.in, configure: Replace TARGET_SNAKE by TARGET_PA_11 and MASK_SNAKE by MASK_PA_11. Mon Apr 26 00:28:25 1999 Theodore Papadopoulo * flags.h (inline_max_insns): Declare. * integrate.c (inline_max_insns): New variable. (function_cannot_inline_p): Use it. * toplev.c (main): Add the flag -finline-limit-n. (display_help): Document -finline-limit-n. * invoke.texi: Document -finline-limit-n Sun Apr 25 23:03:32 1999 Richard Henderson * stmt.c (expand_asm_operands): Reload in-out reg-only memory operands. Sun Apr 25 13:06:13 1999 Richard Henderson * function.c (assign_parms/STACK_BYTES): Revert last change, and that of 19 Nov. Sun Apr 25 12:30:50 1999 Richard Henderson * calls.c (emit_call_1): New arg rounded_stack_size; update callers. Update pending_stack_adjust based on this value. (compute_argument_block_size): Include pending_stack_adjust in PREFERRED_STACK_BOUNDARY alignment. * function.c (assign_parms): Don't round to PREFERRED_STACK_BOUNDARY. Sun Apr 25 14:38:10 EDT 1999 John Wehle (john@feith.com) * stupid.c (stupid_mark_refs): Generate a REG_UNUSED note for a register which is clobbered even if the register was used by an earlier instruction. * i386.md (fix_truncsfdi2, fix_truncdfdi2, fix_truncxfdi2): Don't bother with the gen_reg_RTX. (fix_truncsfsi2, fix_truncsfdi2, fix_truncdfsi2, fix_truncdfdi2, fix_truncxfsi2, fix_truncxfdi2): Update operand constraints and modes. * i386.c (output_fix_trunc): Use HImode register to avoid memory stalls. Call output_move_double instead of output_to_reg. (output_to_reg): Remove. * i386.h: Likewise. * i386.md (negsf2, negdf2, negxf2): Set the type attribute to fpop. Sat Apr 24 23:15:57 1999 Donn Terry (donn@interix.com) * alpha.md (call_value_nt): Correct subscripts. Sat Apr 24 20:49:20 1999 Richard Henderson * alpha.h (PRINT_OPERAND_ADDRESS): Break out to ... * alpha.c (print_operand_address): here. Handle subregs. Fri Apr 23 22:35:41 EDT 1999 John Wehle (john@feith.com) * acconfig.h (HAVE_GAS_FILDS_FISTS): Add. * configure.in: Check assembler instructions. * configure: Rebuild. * config.in: Likewise. * i386.md (floathisf2, floathidf2, floathixf2): New patterns. * i386.c (print_operand): Use the proper suffix for a 387 HImode operand. Abort if a 387 operand has an unsupported size. Fri Apr 23 16:57:40 1999 Richard Henderson * alpha.c (alpha_write_verstamp): Mark `file' unused. * alpha.h (FUNCTION_VALUE): Use gen_rtx_REG not gen_rtx. (LIBCALL_VALUE): Likewise. (GO_IF_LEGITIMATE_SIMPLE_ADDRESS): Handle normal subregs. Fri Apr 23 14:57:33 1999 Donn Terry * alpha32.h (INITIALIZE_TRAMPOLINE): Get offsets right. * alpha.c (alpha_initialize_trampoline): Add covert_memory_address calls as needed. Fri Apr 23 14:36:47 1999 Richard Henderson * alpha.c (alpha_expand_prologue): Don't negate frame size for use with subq. Fri Apr 23 09:43:18 1999 Nick Clifton * print-rtl.c (print_rtx): Display LABEL_NUSES for labels. Thu Apr 22 23:08:37 1999 Mark Mitchell * toplev.h (wrapup_global_declarations): Declare. (check_global_declarations): Likewise. * toplev.c (wrapup_global_declarations): New function, split out from ... (check_global_declarations): Likewise... (compile_file): Here. Thu Apr 22 22:34:41 1999 Richard Henderson * c-parse.in (expr_no_commas): Verify we've an expr before calling C_SET_EXP_ORIGINAL_CODE. Thu Apr 22 22:22:15 EDT 1999 John Wehle (john@feith.com) * toplev.c (rest_of_compilation): Always set current_function_uses_only_leaf_regs appropriately. Thu Apr 22 14:39:43 1999 Mumit Khan * i386/xm-cygwin.h (HAVE_BCOPY): Delete unneeded macro. (HAVE_BZERO): Likewise. (HAVE_BCMP): Likewise. (HAVE_RINDEX): Likewise. (HAVE_INDEX): Likewise. (DIR_SEPARATOR_2): Define. (GET_ENV_PATH_LIST): Turn path lists into POSIX. (PATH_SEPARATOR): Use ':'. 1999-04-22 Bruce Korb * configure.in: enable disabling of fast fixincludes * configure: regenerate 1999-04-21 14:55 -0400 Zack Weinberg * gen-protos.c: #undef abort after including system.h. Delete defns of fancy_abort and fatal. * fix-header.c: Delete defn of fancy_abort. Wed Apr 21 12:09:38 1999 Mumit Khan * cccp.c (simplify_filename): Always preserve leading double slash. Wed Apr 21 18:15:55 1999 Michael Hayes * config/c4x/c4x.md: Add new peepholes to remove redundant loads. Wed Apr 21 17:41:29 1999 Michael Hayes * config/c4x/c4x.md (binary patterns): Reorder alternatives so that two operand instructions are chosen before three operand instructions. Tue Apr 20 23:38:58 1999 Nathan Sidwell * objc/Make-lang.in (objc-parse.c): Put BISON parameters in correct order. * Makefile.in (c-parse.c): Put BISON parameters in correct order. Tue Apr 20 16:38:11 1999 Richard Henderson * alpha.md (nt_lda): New pattern. * alpha.c (alpha_expand_prologue): Use it for large frames under windows nt. Tue Apr 20 17:57:14 1999 Catherine Moore * config/arm/arm.md (movhi): Add check for odd offset. Tue Apr 20 13:14:58 EDT 1999 John Wehle (john@feith.com) * i386.c (output_move_double): Abort if a non-offsettable memory operand is encountered. Delete unused code. (find_addr_reg): Remove. Mon Apr 19 21:13:02 1999 Craig Burley * tree.def (BLOCK): Fix typo in comment. 1999-04-19 14:51 -0400 Zack Weinberg * cpplib.c (output_line_command): Drop CONDITIONAL argument. We can omit unnecessary line commands if file_change == same_file and pfile->lineno != 0. All callers changed. (cpp_get_token [case '\n']): Don't bump pfile->lineno if CPP_OPTIONS (pfile)->no_line_commands is set. * cpplib.h: Fix prototype of output_line_command. 1999-04-18 17:46 -0400 Zack Weinberg * cppfiles.c (find_position, read_and_prescan): Use `unsigned long' variables consistently to count line and column numbers. Sun Apr 18 15:50:33 EDT 1999 John Wehle (john@feith.com) * output.h (current_function_is_leaf, current_function_uses_only_leaf_regs): Declare. * function.c (current_function_is_leaf, current_function_uses_only_leaf_regs): Define. (init_function_start): Initialize current_function_is_leaf and current_function_uses_only_leaf_regs. * final.c (leaf_function): Don't define. (final_start_function): Replace uses of leaf_function with current_function_uses_only_leaf_regs. * toplev.c (rest_of_compilation): Set current_function_is_leaf prior to invoking local register allocation. (rest_of_compilation): Replace uses of leaf_function with current_function_uses_only_leaf_regs. * dbxout.c (dbxout_symbol, dbxout_parms): Likewise. * dwarf2out.c (add_location_or_const_vaule_attribute): Likewise. * dwarfout.c (add_location_or_const_value_attribute): Likewise. * sdbout.c (sdbout_symbol): Likewise. * sparc.h (FUNCTION_PROLOGUE, FUNCTION_EPILOGUE): Likewise. * sparc.c (eligible_for_epilogue_delay, output_return, sparc_return_peephole_ok): Likewise. * sparc.md (leaf_function attribute, untyped_return): Likewise. * i386.c (ix86_compute_frame_size): Don't align the stack for leaf functions which don't allocate any stack slots. * tm.texi: Update documentation. Sun Apr 18 02:15:09 PDT 1999 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. Sun Apr 18 00:08:45 1999 Richard Henderson * alpha.h (GO_IF_LEGITIMATE_SIMPLE_ADDRESS): Correct last change -- make sure FP_BASE_P registers are only used with an integer. Sat Apr 17 22:54:17 1999 Richard Henderson * alpha.h (REG_OK_FP_BASE_P): New macro. (GO_IF_LEGITIMATE_SIMPLE_ADDRESS): Use it. * alpha.md (adddi3+1): New insn to handle large constants off the soft frame pointer. (adddi3+2): Don't split soft frame pointer or arg pointer additions. Sun Apr 18 17:24:10 1999 Michael Hayes * config/c4x/c4x.c (legitimize_operands): Use rtx_cost to determine if it is worthwhile forcing a constant into a register. * config/c4x/c4x.h (CONST_COSTS): An integer value of 255 or 65535 used with a logical and or an integer value of 16 or 24 used with a right shift has zero cost on the C40. Sat Apr 17 21:30:11 1999 Bernd Schmidt * gcse.c (compute_local_properties): If setp is nonzero, clear TRANSP instead of setting it to all ones. Sat Apr 17 21:10:10 1999 Jan Hubicka * i386.c (i386_preferred_stack_boundary_string): New global variable. (i386_preferred_stack_boundary): New global variable. (override_functions): Set it. Tidy option setting code. * i386.h (TARGET_OPTIONS): New command line option. (i386_preferred_stack_boundary_string): Declare it. (i386_preferred_stack_boundary): Likewise. (PREFERRED_STACK_BOUNDARY): Use i386_preferred_stack_boundary. Sat Apr 17 19:22:38 1999 Jan Hubicka * i386.c (k6_cost): Take into account the decoding time. Sat Apr 17 19:13:22 1999 Donn Terry * i386.h (PRINT_OPERAND_PUNCT_VALID_P): Allow _. * i386.c (print_operand): New %_ operator. (load_pic_register): Proper number of leading _ in GOT literal. * i386.md (prologue_get_pc_and_set_got): Likewise. * i386/unix.h (ASM_OUTPUT_MI_THUNK): Likewise. Sat Apr 17 19:13:07 1999 Richard Henderson * alpha.c (alpha_expand_prologue): Use gen_adddi3 instead of emit_move_insn+plus_constant. For NT, don't use the stack probe loop pointer to allocate stack space. * alpha.md (adddi3): Always use lda to set the stack pointer. 1999-04-17 20:11 -0400 Zack Weinberg * c-aux-info.c, emit-rtl.c, explow.c, expmed.c, gcse.c, haifa-sched.c, optabs.c, reorg.c, resource.c, sched.c: Include toplev.h for real declaration of trim_filename. * Makefile.in: Update dependencies. Sat Apr 17 14:36:19 1999 Craig Burley * tree.c (chainon): Check for circularity only if ENABLE_CHECKING is defined. 1999-04-17 10:15 -0400 Zack Weinberg * cccp.c: Make fatal non-static. Sat Apr 17 23:47:24 1999 Michael Hayes * config/c4x/c4x.md (*andqi3_255_clobber,*andqi3_65535_clobber): New logical and patterns using C40 bit-field insert instructions. (*lshrqi3_24_clobber,*ashrqi3_24_clobber,*lshrqi3_16_clobber, *ashrqi3_16_clobber): New shift patterns using C40 bit-field insert instructions. 1999-04-16 22:44 -0400 Zack Weinberg * system.h: Always prototype abort. Prototype fatal. Define abort to call fatal, not fprintf/exit. Define a stub macro for trim_filename. * toplev.c: Define DIR_SEPARATOR. (trim_filename): New function. * toplev.h: Prototype trim_filename, and #undef system.h's stub. * gcc.c, genattr.c, genattrtab.c, gencodes.c, genconfig.c, genemit.c, genextract.c, genflags.c, genopinit.c, genoutput.c, genpeep.c, genrecog.c: Make fatal non-static. * gcov.c, gengenrtl.c, protoize.c: #undef abort after including system.h. * config/i386/dgux.h, config/m68k/xm-amix.h: Remove stale code relating to abort. Sat Apr 17 11:25:44 1999 Michael Hayes * config/c4x/c4x.md (mulqf3_clrqf_clobber, mulqi3_clrqi_clobber): New patterns to support parallel multiply and load of zero. Fri Apr 16 01:23:47 1999 Jason Merrill * tree.c (valid_machine_attribute): If we're modifying the FUNCTION_TYPE within a POINTER_TYPE and we don't get a decl, update the POINTER_TYPE. Fri Apr 16 00:19:31 1999 Jan Hubicka * i386.c (x86_adjust_cost): Move break statement to correct place. Thu Apr 15 23:17:33 1999 Jerry Quinn * pa.h (HAVE_PRE_INCREMENT, HAVE_POST_INCREMENT, HAVE_PRE_DECREMENT, HAVE_POST_DECREMENT): Fix pa_cpu value from 8000 to PROCESSOR_8000. Thu Apr 15 20:46:57 1999 Donn Terry (donn@interix.com) * expr.c (expand_assignment): Force pointers to proper mode if POINTERS_EXTEND_UNSIGNED is defined. * xm-alpha.h (alloca.h): Add Interix to list of special machines that don't like alloca.h, pending using autoconf results. * except.c (start_catch_hadler): Be sure rtime_address is Pmode if POINTERS_EXTEND_UNSIGNED. * except.c (expand_eh_return): Force pointers to proper mode if POINTERS_EXTEND_UNSIGNED. Thu Apr 15 23:13:35 1999 Michael Hayes * config/c4x/c4x.h: Tweaked comment formatting. * config/c4x/c4x.c: Likewise. Thu Apr 15 02:45:19 1999 Mumit Khan * aclocal.m4 (GCC_FUNC_MKDIR_TAKES_ONE_ARG): Define. * configure.in: Use. * configure: Rebuilt. * acconfig.h (MKDIR_TAKES_ONE_ARG): Add. * config.in: Rebuilt. * system.h: Use. Thu Apr 15 01:03:21 1999 Jan Hubicka Jeff Law * i386.md (QImode add pattern): Support lea instruction. (HImode add pattern): Likewise. * i386.md (ashlsi patterns): Call output_ashl instead of output_ashlsi3. (ashlqi): Use expander, separate LEA and SAL / ADD patterns; call output_ashl. (ashlhi): Likewise. * i386.h (output_ashl): Renamed from output_ashlsi3. * i386.c (output_ashl): Likewise; support HImode and QImode operands as well. * i386.md (notsi, nothi, xorsi, xorhi, and xorqi patterns): Call memory_address_displacement_length instead of memory_address_length. * i386.c (memory_address_info): Renamed from memory_address_length. Accept new argument DISP_LENGTH. All callers changed. If DISP_LENGTH, then return the displacement length. Else return length of the entire memory address. Handle MULT case correctly. * i386.h (memory_address_info): Update declaration. * i386.md (memory_bit_test): Fix paren error. Wed Apr 14 21:29:18 1999 Andrew Haley * flow.c: (make_edges): Always make edges from a basic block to its exception handlers, even if the block ends with a jump. 1999-04-14 23:26 -0400 Zack Weinberg * graph.c (node_data): Return void. Ignore result of print_rtl_single. Change caller to match. * integrate.c (subst_constants): Initialize op0_mode to an invalid mode, and abort before use if it's still invalid. (Can only happen if the RTX_CLASS, RTX_FORMAT tables are corrupted.) * objc/objc-act.c (get_objc_string_decl, build_selector_translation_table, generate_protocol_list, synth_id_with_class_suffix, build_keyword_selector, build_selector_expr, gen_declarator): Abort when the tree structure is corrupted. Wed Apr 14 19:57:49 1999 Jeffrey A Law (law@cygnus.com) * configure.in (alpha interix): Use symbolic names to set target_cpu_default. * configure: Rebuilt. * explow.c (allocate_dynamic_stack_space): Undo last change. Use convert_memory_address instead. Wed Apr 14 19:42:02 1999 Donn Terry (donn@interix.com) * alpha/lib1funcs.asm: New file. * alpha/t-interix (lib1funcs.asm): Add to build. * explow.c (allocate_dynamic_stack_space): Correctly convert TARGET to Pmode. Wed Apr 14 14:26:36 1999 John Wehle (john@feith.com) * i386.md (truncxfdf): Output the template supplied by output_move_double with the correct operands. * i386.md (extendsfdf, extendsfxf, extenddfxf): Use output_float_extend instead specifying '#' as the template. * i386.c (output_float_extend): Define. * i386.h (output_float_extend): Declare. Wed Apr 14 10:48:03 1999 Catherine Moore * config/mips/elf.h, config/mips/elf64.h (CTORS_SECTION_ASM_OP): Define. (DTORS_SECTION_ASM_OP): Define. (EXTRA_SECTIONS): Define. (INVOKE__main): Define. (NAME__MAIN): Define. (SYMBOL__MAIN): Define. (EXTRA_SECTIONS_FUNCTIONS): Define. (SECTION_FUNCTION_TEMPLATE): Define. (ASM_OUTPUT_CONSTRUCTOR): Define. (ASM_OUTPUT_DESTRUCTOR): Define. (CTOR_LIST_BEGIN): Define. (CTOR_LIST_END): Define. (DTOR_LIST_BEGIN): Define. (DTOR_LIST_END): Define. (LIB_SPEC): Define. (STARTFILE_SPEC): Define. (ENDFILE_SPEC): Define. * config/mips/linux.h: Undefine all of the above. * config/mips/rtems64.h: Likewise. * config/mips/t-r3900: Likewise. * config/mips/t-elf: New file. * config/mips/vxworks.h: New file. * configure.in (mips-wrs-vxworks): Use mips/vxworks.h. (mips*-*-*elf*): Use t-elf instead of t-ecoff. * configure: Regenerate. Wed Apr 14 09:59:38 1999 Richard Henderson * reload1.c (emit_reload_insns): Also find equivalent mems for subregs of pseudos. * alpha.c (aligned_memory_operand): Recognize the output of LEGITIMIZE_RELOAD_ADDRESS. Examine reg_equiv_memory_loc in the event of a pseudo. (unaligned_memory_operand): Likewise. Don't otherwise accept completely illegal addresses. (normal_memory_operand): Likewise. Handle subregs of pseudos. (get_aligned_mem): Revert previous change. Abort if we don't have a mem. During reload, call find_replacement on all illegal memories. (get_unaligned_address): Likewise. * alpha.h (SECONDARY_INPUT_RELOAD_CLASS): Use !aligned_memory_operand instead of unaligned_memory_operand. * alpha.md: Revert extra argument to get_aligned_mem. (reload_inqi): Use any_memory_operand in constraints. Abort if we're not given some sort of mem. (reload_inhi): Likewise. (reload_outqi, reload_outhi): Likewise. Wed Apr 14 09:39:20 1999 Richard Henderson * i386.md (neghi): Use the whole register when widening the op. 1999-04-14 12:37 -0400 Zack Weinberg * cpperror.c, cppexp.c, cpplib.c: Never call abort. * cpphash.c: Only call abort when we detect corruption of the malloc arena. * cppmain.c: Don't define fatal or fancy_abort. Wed Apr 14 09:19:39 1999 Jan Hubicka * i386.c (x86_adjust_cost): Agi stall takes 1 cycle on Pentium, fst requires value to be ready one extra cycle. Wed Apr 14 11:28:34 1999 Dave Brolley * config/i386/i386.c (memory_address_length): Add missing parenthesis. Wed Apr 14 13:59:27 1999 Martin von Loewis * extend.texi (Deprecated Features): New node. * invoke.texi (-Wdeprecated): Document. Wed Apr 14 00:18:22 1999 Jan Hubicka * i386.md (SImode logical compare): Avoid outputing non-pariable testw and testl on Pentium. (register and memory bit tests): Likewise. (setcc, normal and reversed conditional branches): Use shorter sequence for testing flags stored in EAX. * i386.md (xorsi3): Do not output NOT instrctions on Pentium. (xorqi3): Likewise. (xorhi3): Likewise. (notsi2): Likewise. (notqi2): Likewise. (nothi2): Likewise; do not output prefixed opcodes when possible. * i386.md (neghi2): Do not output prefixed opcode when possible. (ashlhi3): Likewise. Wed Apr 14 00:08:46 1999 Richard Henderson * i386.c (memory_address_length): New function. * i386.h (memory_address_length): Declare it. Tue Apr 13 22:52:04 1999 Donn Terry (donn@interix.com) Martin Heller (Ing.-Buero_Heller@t-online.de) * configure.in (interix Alpha): Add. (winnt Alpha): Use alpha32.h (interix i386): Parallel Alpha32. * configure: Rebuilt. * config/interix.h: Move common elements from i386-interix.h. * config/i386/i386-interix.h: Delete same. * config/alpha/alpha-interix.h: New file. * config/alpha/alpha32.h: New file, part fron win-nt.h. * config/alpha/win-nt.h: Deletions (-> alpha32.h). * config/alpha/interix.h: New file * config/alpha/alpha.md (interix): Comment. * config/alpha/xm-alpha-interix.h: New file. * config/alpha/t-interix: New file. * fixinc/mkfixinc.sh (interix/Alpha): Add. 1999-04-13 Mike Stump * i386/vxi386.h (CPP_CPU_SPEC): Define appropriately for vxworks. (CPP_PREDEFINES, LIB_SPEC, STARTFILE_SPEC, ENDFILE_SPEC): likewise. Tue Apr 13 21:01:36 1999 Jason Merrill * c-common.c (default_valid_lang_attribute): New fn. (valid_lang_attribute): New callback ptr. (decl_attributes): Call it. Move init_priority support into C++ frontend. Tue Apr 13 17:47:14 1999 John Wehle (john@feith.com) * i386.md (movdi): Add splitter. Wed Apr 14 10:04:27 1999 Michael Hayes * config/c4x/c4x.md (storeqf_int, storeqf_int_clobber, loadqf_int, loadqf_int_clobber): Add new patterns with corresponding splitters to handle moves of floating point values into and out of intager registers by using memory. * config/c4x/c4x.c (c4x_check_legit_addr): Disallow PRE_INC for modes other than QFmode and QImode. (mixed_subreg_operand): New function. (c4x_emit_move_sequence): If moving a floating point value into or out of an integer register, use the new patterns storeqf_int_clobber or loadqf_int_clobber. (reg_imm_operand, *_reg_operand): Call reg_operand instead of register_operand. (reg_operand, src_operand): Disallow operand if it satisifes mixed_subreg_operand. * config/c4x/c4x.h (mixed_subreg_operand): Add prototype. Tue Apr 13 14:49:13 1999 Jan Hubicka * i386.c (agi_dependent): Handle push operation more correctly. Tue Apr 13 14:45:17 1999 Jan Hubicka * i386.md (anddi3): Add % constraint. (iordi3, xordi3): Likewise. Tue Apr 13 14:29:58 1999 Jan Hubicka * i386.md (extendhisi2): Output mov instead of cw instruction for K6 to improve decoding bandwidth. * i386.md (extendhiqi2): Likewise. Tue Apr 13 14:26:31 1999 Jan Hubicka * i386.md (movsf_push): Handle memory to memory case too, new splitter. (movdf_push, movxf_push): Likewise. (movsf_push_memory, movdf_push_memory, movxf_push_memory): Remove. Tue Apr 13 14:14:06 1999 Jan Hubicka * i386.md: Do not output mov %0,reg on AMD K6. Tue Apr 13 12:14:07 1999 Dave Brolley * cppinit.c (cpp_start_read): Fix buffer overwrite. * Makefile.in (cppinit.o): Typo in dependencies. Tue Apr 13 05:04:59 1999 Richard Earnshaw (rearnsha@arm.com) * arm.h (function prototypes for arm.c): Ifdef these out if HAVE_CONFIG_H is not defined. Tue Apr 13 02:11:11 1999 Jeffrey A Law (law@cygnus.com) * pa.c: Avoid Using immediate zero for register zero. * pa.md: Likewise. * pa.c (print_operand, case 'f'): New case for FP register or 0.0. (print_operand, case 'r'): Use %r0 for zero value. * pa.md (move patterns, fcmp patterns): Use new %f output arg. * pa.c: Use a register name, not a raw immediate in branch, compare/clear, sub, subb, uaddcm and vshd instructions. * pa.md: Likewise. * pa.md, pa.h, ee.asm, ee_fp.asm, lib2funcs.asm: Likewise. * pa.c: Use a register name, not a raw immediate in "bv" instructions. * pa.md, pa.h, ee.asm, ee_fp.asm, lib2funcs.asm: Likewise. * pa.c: Remove space register specification in memory addresses, except where it is actually needed. * pa.md, pa.h, ee.asm, ee_fp.asm, lib2funcs.asm: Likewise. Mon Apr 12 23:34:35 1999 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. Mon Apr 12 14:58:30 1999 Jan Hubicka * reg-stack.c (check_stack_regs_mentioned): Remove variable SIZE. Mon Apr 12 19:15:17 1999 Daniel Jacobowitz * rs6000/sysv4.h (CPP_OS_LINUX_SPEC): Add missing backslash. Mon Apr 12 19:11:38 1999 Mumit Khan * i386/cygwin.h (SUBTARGET_SWITCHES): Add -mconsole; fix -mno-nop-fun-dllimport and minor doc fixes. (STARTFILE_SPEC): Cygwin DLLs don't have dllcrt0. (LINK_SPEC): Add -mconsole support. * i386/mingw32.h (LIB_SPEC): Make libraries consistent with Cygwin. (LINK_SPEC): Remove. Use Cygwin's version. (MATH_LIBRARY): Make it null. * i386/crtdll.h (MATH_LIBRARY): Likewise. Fri Apr 12 15:00:52 1999 Stan Cox * c-decl.c (c_decode_option, start_decl, start_function, finish_function) : Recognize -Wno-main so we can avoid warnings. 1999-04-12 Zack Weinberg * cpphash.c (collect_expansion, macroexpand, push_macro_expansion): Make the escape character in macro buffers '\r', not '@'. Remove code to protect literal occurences of the escape character; '\r' cannot appear in a macro buffer unless we put it there. * cpplib.c (skip_comment, copy_comment, cpp_skip_hspace, copy_rest_of_line, cpp_get_token, parse_string, parse_assertion): '\r' might be a backslash-newline marker, or it might be a macro escape marker, depending on CPP_BUFFER (pfile)->has_escapes. '@' is not a special character. * cpplib.h: Update commentary. Mon Apr 12 09:30:03 1999 Richard Earnshaw (rearnsha@arm.com) * arm.h (target_fp_name, structure_size_string, arm_cpu_select): Const-ify. * arm.c (target_fp_name, structure_size_string): Const-ify. * arm.md (reload_inhi, reload_outhi): Make the scratch DImode. * arm.c (arm_reload_in_hi): Handle cases when the input is still a pseudo, make use of scratch registers for reloading the address as appropriate. (arm_reload_outhi): Similarly for when the output is still a pseudo. * riscix.h (SUBTARGET_SWITCHES): Document. 1999-04-12 Bruce Korb * fixincludes: make fixincludes behave like the scripts in fixinc/ * Makefile.in( stmp-fixinc ): ensure the SHELL value is that of the make * fixincl/inclhack.tpl: the file name lists ought to be restricted to "*.h" anyway C++ files may be named .../[a-z]++/... also Adding copyright year and attribution to output * fixincl/inclhack.def: fixed broken expression Clarify a some comments * fixincl/fixincl.tpl: Clarify a some comments Remove dead template text Correct the counting of regular expressions Mon Apr 12 03:07:44 1999 Richard Henderson * alpha.c (aligned_memory_operand): Handle out of range stack slots. Take a new SCRATCH argument for the occasion. Update all callers. (get_unaligned_address): Abort on out of range stack slots. * alpha.md (adddi3 splitter): Check s_p_rtx not REGNO. (reload_inqi): Check for aligned mems before unaligned. (reload_inhi): Likewise. Mon Apr 12 03:11:30 1999 Jeffrey A Law (law@cygnus.com) * flow.c (flow_delete_insn): If we delete a CODE_LABEL, also remove it from the nonlocal_goto_handler_labels list. * jump.c (delete_insn): Likewise. (jump_optimize_1): Also recompute LABEL_NUSES when we are just marking labels. * rtl.h (remove_node_from_expr_list): Declare. * rtlanal.c (remove_node_from_expr_list): New function. Mon Apr 12 02:37:02 1999 Jan Hubicka * reg-stack.c: Update comment, include varray.h. (stack_regs_mentioned_data): New global variable. (check_stack_regs_mentioned): New function. (stack_regs_mentioned): New function. (reg_to_stack): Initialize and free stack_regs_mentioned_data, use stack_regs_mentioned. (record_asm_reg_life): Change insn type cache for changed insn. (record_reg_life): Do not change the insn mode. (emit_pop_insn): Likewise. (emit_swap_insn): Likewise. (move_for_stack_reg): Likewise. (stack_reg_life_analysis): Use stack_regs_mentioned. (emit_swap_insn): Likewise. (subst_stack_regs): Likewise. (convert_regs): Likewise. * jump.c (find_cross_jump): Use stack_regs_mentioned. * rtl.h (stack_regs_mentioned): Declare. Mon Apr 12 00:57:10 1999 Theodore Papadopoulo * integrate.c (INTEGRATE_THRESHOLD): Sync it with the comment. Sun Apr 11 10:24:18 1999 Mark Mitchell * rtl.h (rtx_def): Update documentation for jump and call. Sun Apr 11 07:43:44 1999 Kaveh R. Ghazi * jump.c (jump_optimize_1): Make the definition static to match the prototype. Sat Apr 10 22:51:53 1999 Jan Hubicka * flow.c (life_analysis): New parameter remove_dead_code. (life_analysis_1): Likewise. (propagate_block): Likewise; use it. * output.h: Update prototype. * toplev.c: Update calls to life_analysis. Sat Apr 10 22:12:12 1999 Jan Hubicka * recog.c (constrain_operands): Ignore unary operators when matching operands. Recognize '5'..'9' as well. Sat Apr 10 21:53:02 1999 Philipp Thomas (kthomas@gwdg.de) Richard Henderson * configure.in: Set target_cpu_default2 for target_alias k6. * i386.h (TARGET_SWITCHES): Remove no- entries. (CC1_CPU_SPEC): Likewise. (CPP_CPU_DEFAULT_SPEC): Streamline definition. Add K6 version. (CPP_K6_SPEC): New. (CPP_CPU_SPEC): Add K6 variant. (EXTRA_SPECS): Likewise. Fri Apr 9 11:29:17 1999 Richard Henderson * flow.c (merge_blocks_nomove): Rewrite to properly handle two blocks that vanish entirely during merging. Sat Apr 10 20:09:55 1999 John Wehle (john@feith.com) * i386.md (floatsisf2, floatdisf2, floatsidf2, floatdidf2, floatsixf2, floatdixf2, movsicc, movhicc, movsfcc, movdfcc, movxfcc, movdicc): Remove unused register constraints from the splitters. * i386.md (fixuns_truncsfsi2, fixuns_truncdfsi2, fixuns_truncxfsi2): Delete. * reg-stack.c (delete_insn_for_stacker): Ensure that the only side effects of a PARALLEL are clobbers. (subst_stack_regs): Handle subst_stack_regs_pat deleting a PARALLEL. * i386.md (extendsfdf2, extenddfxf2, extendsfxf2): Rewrite using a splitter. * i386.c (output_op_from_reg): Remove. * i386.h: Likewise. Sat Apr 10 13:09:18 1999 Nick Clifton * config/arm/arm.c (di_operand): Allow SUBREGs as well. (soft_df_operand): Allow SUBREGs as well. Sat Apr 10 06:14:31 1999 Jan Hubicka * extend.texi (Assembler Instructions with C Expression Operands): Document the i386 floating point operands. 1999-04-10 Mike Stump * configure.in (*-*-vxworks): Add vxWorks thread support for all vxWorks targets. * configure.in (thumb-wrs-xvworks): Add vxWorks support for thumb. * configure: Rebuilt. Sat Apr 10 06:04:50 1999 Donn Terry (donn@interix.com) * i386/t-interix: Use mostly system headers unchanged. Use system assert.h * fixinc/fixinc.interix: Ditto (make almost no-op). * config/x-interix.h (_ALL_SOURCE): add -D * config/x-interix.h (crti.o): Delete dependency. * config/xm-interix.h (ONLY_INT_FIELDS): Define only when bootstrapping. * i386/xm-i386-interix.h: New file. * i386/interix.h (ASM_OUTPUT_LIMITED_STRING): Fix warnings. * i386/i386-interix.h: Renamed from interix.h. * configure.in (interix): Use new files. * configure: Rebuilt. Sat Apr 10 05:25:28 1999 Daniel Jacobowitz * rs6000/sysv4.h (CPP_OS_LINUX_SPEC): Fix conditions for -Dunix and -Dlinux, and remove duplicate definition. Change -Asystem(linux) to -Asystem(posix). (CPP_OS_SOLARIS_SPEC): Fix conditions for -Dunix, -Dsun, -DSVR4, -D__EXTENSIONS__. * rs6000/linux.h (CPP_PREDEFINES): Remove -Dunix, -Dlinux, -Asystem(linux), and -Asystem(unix). Sat Apr 10 05:14:50 1999 Mark Elbrecht * i386/djgpp.h (SET_ASM_OP): Define. * cccp.c (DIR_SEPARATOR): Move to the top of the file. (is_dir_separator): New function. (simplify_filename): Use it. * collect2.c (find_a_file): Use HAVE_DOS_BASED_FILE_SYSTEM in place of the DIR_SEPARATOR test. Consider any file starting with a drivename to be absolute. If the absolute filename test fails and EXECUTABLE_SUFFIX is defined, append EXECUTABLE_SUFFIX to the file and try again. * cppinit.c (base_name): Use HAVE_DOS_BASED_FILE_SYSTEM in place of __MSDOS__ and _WIN32. * cppfiles.c (simplify_pathname): Likewise. * gcc.c (IS_DIR_SEPARATOR): Define new macro. Returns true if a character is a directory separator. (find_a_file): Use it. (convert_filename): Likewise. (process_command): Likewise. (do_spec_1): Likewise. (is_directory): Likewise. (main): Likewise. * prefix.c (IS_DIR_SEPARATOR): Define. Tests whether a character is a directory separator. (translate_name): Use it. (update_path): Change DIR_SEPARATOR_2 to DIR_SEPARATOR. Fix warning in block where '/' is changed to DIR_SEPARATOR. * i386/xm-djgpp.h (DIR_SEPARATOR): Set to '/'. (DIR_SEPARATOR_2): New macro. Set to '\'. (HAVE_DOS_BASED_FILESYS): Define. * i386/xm-mingw32.h: Updated copyright. Set DIR_SEPARATOR_2 to '/'. Define HAVE_DOS_BASED_FILE_SYSTEM. * i386/xm-os2.h: Likewise. * winnt/xm-winnt.h: Likewise. * i386/xm-dos.h: Likewise. Add copyright. 1999-04-10 Joseph S. Myers * pdp11.h (TARGET_SWITCHES): Add option to vary assembler syntax. (TARGET_DEFAULT): Possibly use UNIX syntax. (TARGET_UNIX_ASM, TARGET_UNIX_ASM_DEFAULT): New macros. (REGISTER_NAMES): Use "r5" instead of "fp". (ASM_OUTPUT_ALIGN): Use ".even" directive, and abort for any greater alignment. * 2bsd.h (TARGET_UNIX_ASM_DEFAULT): Default to UNIX assembler syntax for 2BSD. * pdp11.c (output_ascii): Use working syntax for ".byte". (print_operand_address): Use "*" instead of "@" when using UNIX assembler syntax. Sat Apr 10 03:50:12 1999 Jeffrey A Law (law@cygnus.com) * rtl.h (rebuild_jump_labels): Declare. * jump.c (jump_optimize_1): Renamed from jump_optimize. Make static. Add new argument MARK_LABELS_ONLY. Quit after mark_all_labels if requested. (jump_optimize, rebuild_jump_labels): New wrapper functions for jump_optimize_1. * toplev.c (rest_of_compilation): Use rebuild_jump_labels instead of running the entire jump optimizer. * rtl.h (local_alloc): Returns an integer now. * local-alloc.c (recorded_label_ref): New file scoped variable. (local_alloc): Initialize recorded_label_ref to zero. Return its value when local allocation has completed. (update_equiv_regs); If we create an equivalence for a LABEL_REF, set recorded_label_ref. * toplev.c (rest_of_compilation): Run the jump optimizer after register allocation and reloading if needed. Fri Apr 9 21:02:57 1999 Krister Walfridsson (cato@df.lth.se) * i386/gas.h (ASM_OUTPUT_MAX_SKIP_ALIGN): Fix typo. * i386/freebsd-elf.h (ASM_OUTPUT_MAX_SKIP_ALIGN): Likewise. 1999-04-09 Zack Weinberg * cpphash.c (special_symbol): When expanding __LINE__, use the top file buffer, not the top buffer. Fri Apr 9 13:41:04 1999 Jim Wilson * Makefile.in (check-g++, check-gcc, check-g77, check-objc): Add cd .. to TCL_LIBRARY command. Fri Apr 9 13:04:52 1999 Nick Clifton * config/arm/unknown-elf.h (SUBTARGET_CPU_DEFAULT): Only define if not already specified. Fri Apr 9 11:18:55 1999 Jason Merrill * c-common.c (decl_attributes, A_INIT_PRIORITY): Allow arrays of classes, too. Fri Apr 9 10:40:10 1999 Kaveh R. Ghazi * rs6000.c (rs6000_override_options, ptt, rs6000_file_start, rs6000_float_const, rs6000_replace_regno, debug_stack_info, rs6000_output_load_toc_table, output_prolog, output_epilog): Const-ify a char*. (output_mi_thunk): Likewise. Mark parameter `thunk_fndecl' with ATTRIBUTE_UNUSED. Hide unused variables `r0', `sp', `toc', `schain', `r12', `buf' and `labelno'. (output_ascii): Const-ify a char*. (rs6000_gen_section_name): Initialize variable `last_period'. (rs6000_adjust_priority): Mark parameter `insn' with ATTRIBUTE_UNUSED. (rs6000_trampoline_template, rs6000_dll_import_ref, rs6000_longcall_ref, rs6000_encode_section_info): Const-ify a char*. * rs6000.h (offsettable_mem_operand, optimization_options): Add prototypes. * rs6000.md (movdi, define_split): Cast a value to HOST_WIDE_INT when comparing against one. Thu Apr 8 19:20:18 1999 Jeffrey A Law (law@cygnus.com) * expr.c (expand_expr, case ARRAY_REF, COMPONENT_REF, BIT_FIELD_REF): Do not try to optimize a aggregate address which has VOIDmode. Mirrors March 23 change to expand_assignment. * flow.c (delete_unreachable_blocks): Do not require EDGE_FALLTHRU for an edge when tidying an edge which connects consecutive basic blocks. * flow.c (can_delete_label_p): Do not convert a label into a deleted label here. * cse.c (flush_hash_table): New function. (cse_insn): Flush the hash table when we encounter a volatile asm. (cse_basic_block): Use flush_hash_table instead of doing it inline. * reload1.c (reload_cse_regs_1): Flush known register values if we encounter a volatile asm. * loop.c (strength_reduce): Re-enable Joern's loop improvements. Thu Apr 8 09:37:40 1999 Nick Clifton * config/arm/arm.c (arm_print_operand): Undo previous change - always print large constants in decimal. Thu Apr 8 10:22:23 1999 Kaveh R. Ghazi * configure.in (host_xm_file, build_xm_file): Include hwint.h. Use case statements instead of "if test -a ... -a ... -a ..." * machmode.h: Don't define HOST_WIDE_INT, etc. Wrap use of HOST_WIDE_INT in #ifdef. * mips.h: Include hwint.h instead of providing definitions for HOST_WIDE_INT, etc. Wrap uses of HOST_WIDE_INT in #ifdef. Thu Apr 8 06:16:14 1999 John Wehle (john@feith.com) * i386.md (truncdfsf2, truncxfsf2, truncxfdf2): Rewrite using a splitter. Thu Apr 8 01:26:05 1999 Arg Haas (ahaas@neosoft.com) Jeffrey A Law (law@cygnus.com) * freebsd-elf.h (ASM_OUTPUT_MAX_SKIP_ALIGN): Avoid ambiguous else statement. * gas.h (ASM_OUTPUT_MAX_SKIP_ALIGN): Likewise. * linux.h (ASM_OUTPUT_MAX_SKIP_ALIGN): Likewise. * openbsd.h (ASM_OUTPUT_MAX_SKIP_ALIGN): Likewise. Wed Apr 7 22:40:19 1999 Jim Wilson * i960/i960.c (i960_function_prologue): Don't save static chain pointer. * i960/i960.h (STACK_CHAIN_REGNUM): Change from r3 to g12. (TRAMPOLINE_TEMPLATE): Likewise. (FRAME_POINTER_REQUIRED): Check current_function_has_nonlocal_goto. * i960/i960.md (nonlocal_goto): Rewrite. Tue Apr 6 17:49:49 1999 Philip Blundell * config/arm/lib1funcs.asm: Test for __ELF__ not __elf__. Wed Apr 7 14:07:34 1999 Jeffrey A Law (law@cygnus.com) * h8300.c (h8300_adjust_insn_length): Also avoid recognizing ADDR_VEC and ADDR_DIFF_VEC insns. * h8300.c (h8300_adjust_insn_length): Avoid trying to recognize USE, CLOBBER or SEQUENCE insns. * unroll.c (unroll_loop): For HAVE_cc0 machines, adjust copy_end_luid to account for the uncopied insn that sets cc0 at the end of the loop. * unroll.c (copy_loop_body): Always ensure at least two insns are in the copied loop. Wed Apr 7 14:52:18 1999 Catherine Moore * config/mips/elf.h (MAKE_DECL_ONE_ONLY): Define. (UNIQUE_SECTION_P): Define. 1999-04-07 Bruce Korb * fixinc/inclhack.tpl & fixincl.tpl: Remove dynamic content from generated files Wed Apr 7 13:16:22 1999 John Wehle (john@feith.com) * i386.c (output_move_memory): Remove. * i386.h: Likewise. * i386.md (movsi, movhi, movstricthi, movqi, movstrictqi, movsf, movdf, movxf, movdi): Check no_new_pseudos instead of (reload_in_progress | reload_completed). Wed Apr 7 03:16:45 1999 Richard Henderson * alpha.c (reg_no_subreg_operand): New function. * alpha.h (PREDICATE_CODES): Add it. * alpha.md (floatdi?f patterns): Use it for op1. * alpha.c (alpha_end_function): Don't flag weak functions. Wed Apr 7 02:11:55 1999 Richard Henderson * expr.c (expand_builtin) [BUILT_IN_RETURN_ADDRESS]: Use copy_to_mode_reg; don't force constants into a register. Tue Apr 6 22:55:25 1999 Richard Henderson * toplev.c (compile_file): Typo flow_dump -> flow2_dump. 1999-04-06 Joseph S. Myers * pdp11.c (simple_memory_operand): Add default case in switch. * pdp11.h (TARGET_SWITCHES): Add help strings. (NOTICE_UPDATE_CC): Don't include excess argument to format. (ASM_OUTPUT_DOUBLE_INT): Remove. Tue Apr 6 22:09:40 1999 Richard Henderson * expr.c (expand_builtin_setjmp): Put setjmp return label on nonlocal_goto_handler_labels for flow. Tue Apr 6 22:05:21 1999 Jan Hubicka Richard Henderson * flow.c (verify_flow_info): New function. (find_basic_blocks): Call it if ENABLE_CHECKING. (merge_blocks): Don't merge if there are non-deletable labels. * toplev.c (fatal_insn): Allow a printf-style arg list. * toplev.h (fatal_insn): Update prototype. Tue Apr 6 16:18:58 1999 Jan Hubicka * flow.c (split_edge) update correctly flow graph, disable EDGE_CRITICAL flag on the split edge, update NUSES for new label. Tue Apr 6 15:47:51 1999 Richard Henderson * emit-rtl.c (gen_rtx_CONST_DOUBLE): Use XWINT not XINT. Clear third and following slots, if they exist. Tue Apr 6 15:45:28 1999 Richard Henderson * flow.c (create_basic_block): Make sure the bb note is in the block. (can_delete_note_p): Rename from delete_note_p. (delete_insn_chain): Preserve undeleteable labels too. (tidy_fallthru_edge): Use next_real_insn instead of confusing inline code. 1999-04-06 Zack Weinberg * cppexp.c (parse_charconst): Initialize c. (cpp_parse_expr): Initialize rprio. * cppfiles.c (merge_include_chains): Initialize prev. (finclude): Set fp->line_base to fp->buf before returning. * cpphash.c (macroexpand): Initialize token. * cppspec.c (lang_specific_driver): Change suff to const char *const *. 1999-04-06 Zack Weinberg * cppinit.c (install_predefs): Delete function. (cpp_start_read): Don't call install_predefs. (cpp_handle_option): Remove case 'u' and all refs to opts->inhibit_predefs. (print_help): Don't mention -undef. (initialize_builtins): Define __HAVE_BUILTIN_SETJMP__, to match cccp. * cpplib.h (struct cpp_options): Remove inhibit_predefs member. * cccp.c (predefs): Delete variable. (main): Remove case 'u' in argument parse loop, 'inhibit_predefs' variable, and the code block that would process CPP_PREDEFINES. (initialize_builtins): Don't define __OBJC__, the driver will do that. * gcc.c (default_compilers): Remove -undef from all specs that invoke a C preprocessor. * ch/lang-specs.h: Likewise. * cp/lang-specs.h: Likewise. * f/lang-specs.h: Likewise. * objc/lang-specs.h: Likewise. Mon Apr 5 11:55:31 1999 Donn Terry (donn@interix.com) * Makefile.in (SUBDIR_FLAGS_TO_PASS): Fix misapplied patch. Mon Apr 5 11:51:38 1999 Jeffrey A Law (law@cygnus.com) * m68k.md (movdf): Hide GPR sources & destinations from regclass. Mon Apr 5 09:54:42 1999 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. Mon Apr 5 05:55:15 1999 Bruce Korb * fixincl.tpl: Separate "-e" from its argument, a la the Sat Apr 3 17:05:13 1999 fix. * genfixes: Ensure that the server shell is _NOT_ csh. Mon Apr 5 03:52:30 1999 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. Mon Apr 5 04:47:14 1999 Jeffrey A Law (law@cygnus.com) * i386.c (x86_double_with_add): Turn off for Pentium and PPro. (small_shift_operand, output_ashlsi3): New functions. * i386.h (small_shift_operand, output_ashlsi3): Declare. * i386.md (ashlsi3): Simplify ahlsi3 patterns. Remove splitters that are no longer needed. Sun Apr 4 04:05:04 1999 Jeffrey A Law (law@cygnus.com) * stmt.c (expand_loop_end): When copying the loop exit test, do not walk into a nested loop. Sun Apr 4 00:14:54 1999 Jeffrey A Law (law@cygnus.com) * fixinc/hackshell.tpl: Skip links to directories, to avoid removing them. * fixinc/inclhack.tpl: Likewise. * fixinc/fixinc.sh, fixinc/fixincl.x, fixinc/inclhack.sh: Rebuilt. Sat Apr 3 23:46:13 1999 David Edelsohn * rs6000.md (addsi3, iorsi3, xorsi3, adddi3, iordi3, xordi3, movsi_got, movsi, movsf): Use no_new_pseudos. * rs6000.c (rs6000_got_register): Likewise. (offsettable_mem_opereand): Use || not |. Sat Apr 3 22:02:56 1999 Jeffrey A Law (law@cygnus.com) * acconfig.h (ENABLE_CHECKING): Remove redundant #undef. * config.in: Rebuilt. Sat Apr 3 16:22:59 1999 Toshiyasu Morita (tm@netcom.com) * gcc.texi: Add info on regmove pass. * regmove.c (fixup_match_1): Consistently evaluate HAVE_POST_INCREMENT and HAVE_POST_DECREMENT. Sat Apr 3 19:21:05 1999 Alexandre Oliva * configure.in (DEFAULT_LINKER, DEFAULT_ASSEMBLER): Use grep instead of test and sed to check whether they're GNU programs. * configure: Rebuilt. Sat Apr 3 17:57:35 1999 Alexandre Oliva * Makefile.in (install-headers-tar, install-headers-cpio): Avoid problems with CDPATH. Reported by Ralf Canis Sat Apr 3 13:50:16 1999 Jeffrey A Law (law@cygnus.com) * fixinc.x86-linux-gnu: Deleted. Sat Apr 3 17:05:13 1999 Alexandre Oliva * inclhack.tpl: Insert spaces between `sed -e' and '...'. Reported by Kaveh R. Ghazi * fixinc/fixincl.sh, fixinc/fixincl.x, fixinc/inclhack.sh: Regen. Sat Apr 3 14:54:46 1999 Craig Burley * tree.def (BLOCK): Fix typo in comment. Sat Apr 3 00:53:29 1999 John Wehle (john@feith.com) * i386.md (floatsisf2, floatdisf2, floatsidf2, floatdidf2, floatsixf2, floatdixf2): Rewrite using a splitter. Fri Apr 2 17:36:10 1999 Nick Clifton * config/arm/arm.c (arm_print_operand): Print large constants in hex rather than decimal. Fri Apr 2 17:23:58 1999 Nick Clifton * print-rtl.c (print_rtx): Use both HOST_WIDE_INT_PRINT_DEC and HOST_WIDE_INT_PRINT_HEX to display constants. 1999-04-02 Zack Weinberg * config/i386/i386.h: Document all TARGET_SWITCHES or add explicit null initializer. * config/i386/cygwin.h: Document all SUBTARGET_SWITCHES. * config/i386/dgux.h: Likewise. * config/i386/osf1elf.h: Likewise. * config/i386/win32.h: Likewise. * config/i386/osfrose.h: Likewise. Drop obsolete -mno-ident option. Fri Apr 2 17:49:44 1999 Toshiyasu Morita * regmove.c (fixup_match_1): Remove now useless if (0). Sat Apr 3 11:37:20 1999 Michael Hayes * tm.texi (USE_LOAD_POST_DECREMENT, USE_LOAD_PRE_DECREMENT, USE_STORE_POST_DECREMENT, USE_STORE_PRE_DECREMENT): Document. (USE_LOAD_POST_INCREMENT, USE_LOAD_PRE_INCREMENT, USE_STORE_POST_INCREMENT, USE_STORE_PRE_INCREMENT): Fix documentation. * rtl.h (USE_LOAD_POST_DECREMENT, USE_LOAD_PRE_DECREMENT, USE_STORE_POST_DECREMENT, USE_STORE_PRE_DECREMENT, USE_LOAD_POST_INCREMENT, USE_LOAD_PRE_INCREMENT, USE_STORE_POST_INCREMENT, USE_STORE_PRE_INCREMENT): Provide default definition. * expr.c (USE_LOAD_POST_INCREMENT, USE_LOAD_PRE_INCREMENT, USE_STORE_POST_INCREMENT, USE_STORE_PRE_INCREMENT): Delete default definition. Fri Apr 2 16:03:05 1999 Jeffrey A Law (law@cygnus.com) * fixinc.dgux, fixinc.interix, fixinc.irix, fixinc.ptx: Deleted. * fixinc.sco, fixinc.svr4, fixinc.winnt, fixinc.wrap: Likewise. Fri Apr 2 15:46:25 1999 Donn Terry (donn@interix.com) * configure.in: Set and substitute quoted_cc_set_by_configure. * configure: Rebuilt. * Makefile.in (SUBDIR_FLAGS_TO_PASS): Fix quoting problem with ``. Fri Apr 2 14:35:45 1999 Stan Cox * config/i386/cygwin.h (CPP_SPEC): Use mingw_include_path instead of a hardcoded path for -mno-cygwin. (mingw_include_path): New. 1999-04-02 Joseph S. Myers * pdp11.c: Include "recog.h". (output_function_prologue): Remove unused variables `nregs', `i', `offset'. (output_function_epilogue): Remove unused variables `may_call_alloca', `nregs', `regno', `adjust_fp'. (output_ascii): Mark as returning void. (print_operand_address: Likewise. (simple_memory_operand): Remove unused variables `plus0', `plus1', `offset'. * pdp11.h: Declare functions `arith_operand', `const_immediate_operand', `expand_shift_operand', `legitimate_address_p', `notice_update_cc_on_set', `output_ascii', `output_function_epilogue', `output_function_prologue', `print_operand_address', `register_move_cost', `simple_memory_operand'. (HARD_REGNO_MODE_OK): Parenthesize `REGNO' arg. (REGNO_REG_CLASS): Likewise. * pdp11.md: Add explicit `int' to `static count' (in two places). (addhi3): Add explicit braces to avoid ambiguous else. (addqi3): Likewise. (ashlhi3): Likewise. Fri Apr 2 14:17:10 1999 Jerry James * gcc/invoke.texi: Add documentation for additional supported MIPS CPU types, options -mips16 and -mentry, and ABI and ISA defaults. Fri Apr 2 14:12:06 1999 John Wehle (john@feith.com) * i386.md: Delete floating point compare, add, subtract, multiply, and divide patterns which allowed integer operands. * i386.c (output_387_binary_op): Delete unused code. (output_float_compare): Likewise. Fri Apr 2 11:53:37 1999 John Wehle (john@feith.com) * i386.md (movsf+1, movdf+1, movxf+1): Update constraints so that SECONDARY_MEMORY_RELOAD is used. Remove dead code. 1999-04-02 Bruce Korb * fixinc/mkfixinc.sh: Added support for x86-interix. * fixinc/fixinc.interix: Fixincludes script, slight changes from ./fixinc.interix. Untested (needs interix box). * fixinc/inclhack.def: Complete the change to the 'fixinc.tmp' file. Fixed regex for finding C++ headers. * fixincl.x, fixincl.sh, inclhack.sh: Regenerate. Fri Apr 2 11:36:12 1999 Jan Hubicka (hubicka@paru.cas.cz) * i386.c (print_operand_address, case REG): Do not use ESI addressing mode for the K6. * i386.c (print_operand_address, case MULT): Use more efficient encoding (mult (reg) (const_int 2)). Thu Apr 1 17:01:50 1999 Richard Henderson Move over patch from Bernd Schmidt from GC branch: * emit-rtl.c (gen_rtx_CONST_DOUBLE): New function. (gen_rtx): Call it. Tidy cases. * rtl.h (gen_rtx_CONST_DOUBLE): Prototype it. * gengenrtl.c: Add commentary. (special_rtx): Also match CONST_DOUBLE. (gencode): Emit call to memset instead of bzero. Fri Apr 2 12:58:26 1999 Michael Hayes * config/c4x/c4x.md (ashlhi3, lshrhi3, ashrhi3): Force operand 1 into a register if shift count not constant. (ashlhi3_reg, lshrhi3_reg, ashrhi3_reg): Ensure that operand 1 is a register. Fri Apr 2 12:19:17 1999 Michael Hayes * config/c4x/c4x.md (*db): Enable pattern if TARGET_LOOP_UNSIGNED is non-zero. (movstrqi_small, movstrqi_large, *cmpstrqi): Add + modifier to address register constraints. (*movhi_clobber+1): Modify splitter pattern to handle destination register that is used in the source address. (*xorhi3_clobber): Replace AND with XOR in call to legitimize_operands. Fri Apr 2 12:16:15 1999 Michael Hayes * config/c4x/c4x.h: Added more comments. Fri Apr 2 11:58:22 1999 Michael Hayes * config/c4x/c4x.c (c4x_emit_move_sequence): Force invalid QImode constants into memory if we get called directly from gen_move_insn rather than emit_move_insn. (c4x_legitimize_address): Fix up LABEL_REF addresses. Thu Apr 1 12:04:05 1999 Jim Wilson * expr.c (store_field): When check direct_store, assume all complex modes can be directly stored. 1999-04-01 Bruce Korb * fixinc/genfixes: New shell script that runs autogen to create the generated files. 1999-04-01 Manfred Hollstein * Makefile.in (cppmain$(exeext)): Depend on intl.o. Link in intl.o. Thu Apr 1 03:48:34 1999 H.J. Lu (hjl@gnu.org) * i386.c (output_fp_conditional_move): Abort for LT, LE, GE, and GT signed integer comparisons. * i386.c (output_int_conditional_move): Use "enum rtx_code" for code type. * i386.c (notice_update_cc): No need to check the INT mode for conditional moves since FLOAT conditional moves don't affect cc0. Thu Apr 1 02:17:18 1999 Jeffrey A Law (law@cygnus.com) * fixinc/inclhack.def (zzz_ki_syscalls, zzz_time): Fix trigger string to only match on hpux11. * fixinc/fixincl.x, fixinc/inclhack.sh, fixinc/fixinc.sh: Rebuilt. Thu Apr 1 01:09:27 1999 Alexandre Oliva * fixinc/hackshell.tpl: Complete transition to fixinc.tmp. * fixinc/inclhack.sh: Rebuilt. * fixinc/inclhack.def: Fix typos in c_asm.h fix. * fixinc/fixincl.x, fixinc/inclhack.sh, fixinc/fixinc.sh: Rebuilt. Wed Mar 31 17:20:11 1999 Jeffrey A Law (law@cygnus.com) * toplev.c (rest_of_compilation): Allow dbr_schedule to write to the dump file too. Wed Mar 31 12:32:43 1999 Richard Henderson * flow.c (find_basic_blocks): New argument `do_cleanup'. Conditionally call delete_unreachable_blocks. (free_basic_block_vars): Zero ENTRY/EXIT data. (allocate_for_life_analysis): Kill. Split into... (allocate_bb_life_data, allocate_reg_life_data): ... new functions. (life_analysis_1): Update. * gcse.c (gcse_main): Update find_basic_blocks call. * toplev.c (rest_of_compilation): Likewise. * stupid.c (stupid_life_analysis): Update life data calls. * rtl.h, output.h: Update prototypes. Wed Mar 31 12:10:00 1999 Bruce Korb * inclhack.def (several): Added spaces in tests to ensure correct shell syntax. Added c_asm.h fix from fixincludes. Also corrected the corrected fix to C++ comments :-} * inclhack.tpl: Changed method of traversing symlink trees so that file name matching will work correctly. * fixincl.c, hackshell.tpl: Fallout from above. * fixincl.x, inclhack.sh, fixincl.sh: Rebuilt. Tue Mar 30 10:43:49 1999 Philip Blundell * config/arm/aout.h (DBX_DEBUGGING_INFO): Avoid redefinition if dbxelf.h was previously included. (CPP_APCS_PC_DEFAULT_SPEC): No need to undefine. * config/arm/linux-elf.h (FP_DEFAULT): Correctly override the definition from arm.h. Wed Mar 31 10:33:37 1999 Kaveh R. Ghazi * Makefile.in (c-gperf.h): Generate using gperf language 'C', not 'KR-C', so gperf uses the `const' keyword on strings. * c-parse.gperf (resword): Const-ify a char*. Wed Mar 31 01:49:31 1999 Ian Lance Taylor * t-rtems (LIMITS_H_TEST, LIBGCC2_INCLUDES): Define. Wed Mar 31 00:50:48 1999 Jeffrey A Law (law@cygnus.com) * system.h (STDERR_FILENO): Fix typo. * inclhack.def (bool): Also fix bogus bool in curses_colr/curses.h. * fixincl.x, inclhack.sh, fixincl.sh: Rebuilt. Tue Mar 30 20:51:40 1999 Mark Mitchell * alias.c (alias_set_compare): Remove. (record_alias_subset): Use splay_tree_compare_ints instead of alias_set_compare. (init_alias_once): Likewise. * cse.c: Include splay-tree.h. (reg_qty): Remove. (reg_tick): Likewise. (reg_table): Likewise. (cse_reg_info): New structure. (cse_reg_info_free_list): New variable. (cse_reg_info_tree): Likewise. (cached_regno): Likewise. (cached_cse_reg_info): Likewise. (all_minus_one): Remove. (consec_ints): Likewise. (GET_CSE_REG_INFO): New macro. (REG_TICK): Likewise. Use throughout instead of reg_tick. (REG_IN_TABLE): Likewise. Use throughout instead of reg_in_table. (REG_QTY): Likewise. Use throughout instead of reg_qty. (get_cse_reg_info): New function. (free_cse_reg_info): Likewise. (new_basic_block): Reinitialize cse_reg_info_tree instead of reg_tick, all_minus_one, and consec_ints. * Makefile.in (cse.o): Depend on splay-tree.h Tue Mar 30 13:19:36 1999 Jason Merrill * libgcc2.c (throw_helper): Just return the SP offset, rather than a whole udata. Include args_size in the offset. (__throw, __rethrow): Adjust. Tue Mar 30 11:39:27 1999 Craig Burley * extend.texi (Extended Asm): Delete spurious `b' before `@end example', which was confusing texi2html. Tue Mar 30 00:26:34 1999 Jason Merrill * dwarf2out.c (output_line_info): Don't emit redundant info. Do start a new row if the file changes and the line # doesn't. Mon Mar 29 15:48:39 1999 Jason Merrill * invoke.texi (Invoking G++, C++ Dialect Options): Update. Mon Mar 29 15:05:39 1999 Richard Henderson * except.c (start_dynamic_handler): Force jmp_buf address to and operand before moving to memory. Mon Mar 29 15:11:10 1999 Craig Burley * invoke.texi (Code Gen Options): Attempt to clarify -fcheck-memory-usage. Minor edits to -fprefix-function-name. Mon Mar 29 20:52:47 1999 J"orn Rennecke * loop.c (maybe_eliminate_biv): For libcalls that set a giv, skip to end of libcall. Mon Mar 29 20:35:49 1999 J"orn Rennecke * sh.md (mulsi3): Tag an extra REG_EQUAL note to the middle insn. Mon Mar 29 11:50:34 1999 Jerry Quinn * pa.h (HAVE_PRE_INCREMENT): Disable when optimizing for a PA8000 class machine. (HAVE_PRE_DECREMENT, HAVE_POST_INCREMENT): Likewise. (HAVE_POST_DECREMENT): Likewise. Mon Mar 29 08:24:43 1999 Bruce Korb * fixinc/mkfixinc.sh: Fix portability problems with old shells. * fixinc/README: Updated for release announcement Sun Mar 28 20:26:55 1999 Kaveh R. Ghazi * recog.h (insn_outfun, insn_operand_predicate): Add prototype arguments. * rtl.h (note_stores): Likewise. * rtlanal.c (note_stores): Likewise. Sun Mar 28 15:34:28 1999 Richard Henderson * varasm.c (output_constant_pool): Always mark the constant pool. Sun Mar 28 16:09:01 1999 Jerry Quinn * pa.md (pa7100LCshiftmem, pa7100LCalu): Change simultaneity. Use shift/mem ops in pa7100LCalu. * pa.c (pa_adjust_cost): Don't do cost adjustments on pa8000. (pa_reorg): Don't call pa_combine_instructions on pa8000. Sun Mar 28 15:27:26 1999 Jeffrey A Law (law@cygnus.com) * reload1.c (reload): Remove accidental code duplication. Sun Mar 28 12:22:12 1999 Robert Lipe (robertlipe@usa.net) * i386/sysv5.h: New file to describe UnixWare7/SVR5. * configure.in (i?86-UnixWare7*-sysv): Use it. * i386/udk.h: Use sysv5.h. Now uses Dwarf-2. Sun Mar 28 01:15:04 1999 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. Sun Mar 28 00:44:27 1999 Jeffrey A Law (law@cygnus.com) * sdbout.c (sdbout_symbol): Do not call build_pointer_type, build one on the fly and do not cache the result. * gcc.cps, cpp.cps: Delete unwanted files. Sat Mar 27 23:37:40 1999 John Wehle (john@feith.com) * i386.md (movdicc+3, movdicc+4): Rewrite using split_di. * i386.c (output_int_conditional_move): Delete unused code. Sat Mar 27 21:17:36 1999 David Edelsohn * rs6000/{aix41.h,aix43.h} (ASM_CPU_SPEC): Add 604e. Sat Mar 27 16:13:50 1999 Jeffrey A Law (law@cygnus.com) * flow.c (mark_used_regs): Improve handling of ASMs. 1999-03-26 Zack Weinberg * Makefile.in (xcpp, cppspec.o): New targets. (CPP_INSTALL_NAME): New macro. (install-cpp): Install xcpp. Use CPP_INSTALL_NAME. (all.build, start.encap): Build xcpp. * cppspec.c: New file, implements argument filtering for a user-visible C preprocessor. * cpp.sh: Removed. Fri Mar 26 20:41:46 1999 Jim Wilson * Makefile.in (stmp-fixinc): Use tooldir instead of gcc_tooldir. Fri Mar 26 16:02:37 1999 Nick Clifton * configure.in (arm-*-vxworks*): Just include arm/vxarm.h. * configure: Regenerate. * config/arm/vxarm.h: Define SUBTARGET_CPU_DEFAULT before including arm/coff.h 1999-02-16 Scott Bambrough * configure.in (arm*-*-linux-gnu*): Set thread_file to 'posix' if --enable-threads[={yes,pthreads,posix}] is passed as a command line parameter to configure. * configure: Regenerate. * gcc/config/arm/t-linux (TARGET_LIBGCC2_CFLAGS): Include -fPIC. Fri Mar 26 19:42:19 1999 J"orn Rennecke * loop.c (combine_givs): Fix index into can_combine when doing benefit adjustment for remaining givs when having combined a giv. Fri Mar 26 11:38:01 1999 Nick Clifton * config/arm/t-arm-elf (EXTRA_MULTILIB_PARTS): Define. Fri Mar 26 10:48:27 1999 Nick Clifton * config/arm/linux-elf.h: Include dbxelf.h Fri Mar 26 10:43:47 1999 Nick Clifton * config/svr4.h: Include new header file dbxelf.h. (DBX_DEBUGGING_INFO): Remove definition. (DBX_USE_BINCL): Remove definition. (DBX_BLOCKS_FUNCTION_RELATIVE): Remove definition. (ASM_IDENTIFY_GCC): Remove definition. (ASM_IDENTIFY_GCC_AFTER_SOURCE): Remove definition. (ASM_OUTPUT_SOURCE_LINE): Remove definition. (DBX_FUNCTION_FIRST): Remove definition. (DBX_OUTPUT_MAIN_SOURCE_FILE_END): Remove definition. * config/elfos.h: Include new header file dbxelf.h. (DBX_DEBUGGING_INFO): Remove definition. (DBX_BLOCKS_FUNCTION_RELATIVE): Remove definition. (ASM_IDENTIFY_GCC): Remove definition. (ASM_IDENTIFY_GCC_AFTER_SOURCE): Remove definition. (ASM_OUTPUT_SOURCE_LINE): Remove definition. (DBX_FUNCTION_FIRST): Remove definition. * config/dbxelf.h: New header file. (DBX_DEBUGGING_INFO): Define. (DBX_BLOCKS_FUNCTION_RELATIVE): Define. (DBX_FUNCTION_FIRST): Define. (DBX_USE_BINCL): Define. (DBX_CONTIN_LENGTH): Define. (ASM_IDENTIFY_GCC): Define. (ASM_IDENTIFY_GCC_AFTER_SOURCE): Define. (ASM_OUTPUT_SOURCE_LINE): Define. (DBX_OUTPUT_MAIN_SOURCE_FILE_END): Define. Fri Mar 26 01:59:15 1999 "Charles M. Hannum" * fold-const.c (fold_truthop): Optimize bitfield references with different masks as long as their size and bit position are the same. * fold-const.c (fold_truthop): Build a type for both the lhs and rhs and use it appropriately. * fold-const.c (fold_truthop): Mask the lhs and rhs after merging adjacent bitfield references. * fold-const.c (fold_truthop): Verify that the lhs and rhs are in the same bit position when optimizing bitfield references which have the same mask. Thu Mar 25 22:53:27 1999 Martin von Löwis * gcc.texi (Copy Assignment): New node. 1999-03-25 Zack Weinberg * gcc.c: Compile unconditionally all code formerly dependent on #ifdef LANG_SPECIFIC_DRIVER. * gccspec.c: New file with stub lang_specific_driver, lang_specific_pre_link. * Makefile.in: Link gccspec.o into xgcc. Add rule to compile Thu Mar 25 21:08:02 1999 Jason Merrill * gcc.texi (Temporaries): Update. Thu Mar 25 16:53:53 1999 Richard Henderson * combine.c (distribute_notes): Place REG_LABEL also where REG_EQUAL indicates. Thu Mar 25 12:46:37 1999 Jim Wilson * a29k/a29k.h (TARGET_SWITCHES): Add doc strings. * i960/i960.h (TARGET_SWITCHES): Add doc strings. * invoke.texi (a29k): Add documentation for -mno-multm option. Thu Mar 25 14:04:54 1999 Andrew MacLeod * rtl.texi (RTX_FRAME_RELATED_P): Add documentation. * rtl.h (struct rtx_def): Update comment for frame_related field. (set_unique_reg_note): Declare prototype. * dwarf2out.c (dwarf2out_frame_debug_expr): Split out from 'dwarf2out_frame_debug' to handle only expressions, and process component parts of a PARALLEL expression. (dwarf2out_frame_debug): Process insns only, and call new function 'dwarf2out_frame_debug_expr' for patterns. * emit-rtl.c (set_unique_reg_note): New function to add a reg note, but if there is an existing one, delete it first. * expmed.c (expand_mult, expand_divmod): Use set_unique_reg_note. * optabs.c (add_equal_note, expand_binop): Use set_unique_reg_note. (emit_no_conflict_block, emit_libcall_block): Use set_unique_reg_note. (expand_fix): Use set_unique_reg_note. Thu Mar 25 11:47:49 1999 Art Haas * tlink.c (symbol_hash_newfunc): Remove redundant call to hash_newfunc. (file_hash_newfunc, demangled_hash_newfunc): Likewise. Thu Mar 25 10:05:56 1999 Richard Henderson * i386.h (PREFERRED_STACK_BOUNDARY): Set to 128. 1999-03-25 Philip Blundell Based on patch from Jim Studt : * config/arm/linux-elf.h (STARTFILE_SPEC, ENDFILE_SPEC): Copy definitions from config/linux.h. (DBX_BLOCKS_FUNCTION_RELATIVE): Define to 1. Thu Mar 25 02:12:42 1999 Finn Hakansson * loop.c (strength_reduce): Correct a comment. * rtl.h (MEM_COPY_ATTRIBUTES): Remove unnecessary ending backslash. Thu Mar 25 02:02:13 1999 Axel Thimm * Makefile.in (RANLIB_TEST): Improve test. Thu Mar 25 01:15:33 1999 Donn Terry * combine.c (force_to_mode, case PLUS): Use sign extended mask when masking the low bits out of a constant. Tue Mar 23 15:45:25 1999 Richard Earnshaw (rearnsha@arm.com) Jeff Law * fold-const.c (make_range): If orig_type is unset, set it as soon as we know the type. Remove now unnecessary set of orig_type for conversions. Wed Mar 24 23:27:25 1999 Mark Elbrecht Jeff Law * system.h (STDIN_FILENO): Provide default definition if one is not provided by the system header files. (STDOUT_FILENO, STDERR_FILENO): Likewise. * i386/xm-djgpp.h (COLLECT2_HOST_INITIALIZATION): New macro. * collect2.c (main): Use it. (pexecute_pid): New variable. Holds return value from call to pexecute. (collect2_execute): Rework to use pexecute instead of fork. (collect2_wait): Use pwait() instead of wait(). * i386/djgpp.h: Fix typo. Wed Mar 24 23:24:30 1999 Jeffrey A Law (law@cygnus.com) * fixinc/mkfixinc.sh: Recognize cygwin* instead of only cygwin32. Wed Mar 24 15:44:12 1999 Nick Clifton * config/m32r/m32r.c (init_idents): Accept both NAME and __NAME__ versions of attribute names and values. (m32r_valid_machine_decl_attribute): Likewise. (m32r_encode_section_info): Likewise. Wed Mar 24 21:42:15 1999 J"orn Rennecke * reload1.c (choose_reload_regs): If output-reloading for a simple move insn, try to inherit an equivalence for the input. 1999-02-24 Mike Stump * arm/aout.h (DBX_OUTPUT_MAIN_SOURCE_FILENAME): Fix quoting. 1999-03-24 Jim Blandy * libgcc2.c (__CTOR_LIST__, __DTOR_LIST__): Initialize on all platforms. Wed Mar 24 01:35:01 1999 Geoff Keating * fold-const.c (fold): Recognize a rotate by an unsigned amount. Tue Mar 23 23:32:14 1999 Jeffrey A Law (law@cygnus.com) * pa.md (rotlsi3): New expander. Synthesize a variable rotate left using a variable rotate right. Provide anonymous pattern for rotate left by a constant value. * expr.c (expand_assignment): Do not try to optimize a aggregate address which has VOIDmode. Tue Mar 23 22:51:48 1999 Mumit Khan Donn Terry * protoize.c (abspath): Preserve multiple leading slashes for _WIN32 and Interix. 1999-01-23 Mike Stump * arm/vxarm.h: Split out vxWorks support into separate headerfile and vxify. * arm/arm.c (cpu_defaults): Allow arm710 as default. * configure.in: Split out vxWorks support for Arm. * configure: Rebuilt. Tue Mar 23 11:20:03 1999 Per Bothner * tree.c (first_rtl_op, has_cleanups): Handle GOTO_SUBROUTINE_EXPR. Tue Mar 23 09:00:39 1999 Nick Clifton * config/arm/riscix1.h (SUBTARGET_SWITCHES): Add doc string. * config/arm/riscix1-1.h (SUBTARGET_SWITCHES): Add doc string. Tue Mar 23 07:50:20 1999 Mark Mitchell * function.c: Include hash.h. (insns_for_mem_entry): New struct. (put_reg_into_stack): Take an optional hash-table mapping MEMs to the INSNs that use them. (fixup_var_refs): Likewise. (put_addressof_into_stack): Likewise. (purge_addressof_1): Likewise. Keep the hash-table up to date if we add new instructions. (fixup_var_refs_insns): Use it to avoid searching the entire instruction chain. (insns_for_mem_newfunc): New function. (insns_for_mem_comp): Likewise. (insns_for_mem_walk): Likewise. (compute_insns_for_mem): Likewise. (pop_function_context_from): Pass NULL for the hash-table. (put_var_into_stack): Likewise. (gen_mem_addressof): Likewise. (flush_addressof): Likewise. (purge_addressof): Call compute_insns_for_mem to pre-compute the hash table. * Makefile.in (OBJS): Include hash.o. (function.o): Depend on hash.h. Tue Mar 23 00:39:14 1999 Jeffrey A Law (law@cygnus.com) * i386/openbsd.h (TARGET_DEFAULT): Use symbolic names instead of numbers. * i386/netbsd.h, i386/freebsd.h: Likewise. * crtstuff.c: Use ANSI function definitions. Fix minor whitespace problems. * i386/openbsd.h (TARGET_DEFAULT): Define. * configure.in: Do not set TARGET_CPU_DEFAULT for x86 OpenBSD configurations. * configure: Rebuilt. Tue Mar 23 00:39:10 1999 John Wehle (john@feith.com) * i386/freebsd.h (TARGET_DEFAULT): Define instead of TARGET_CPU_DEFAULT. * i386/netbsd.h (TARGET_DEFAULT): Likewise. Mon Mar 22 23:52:01 1999 Mumit Khan Donn Terry * sdbout.c (syms.h): Don't include on Interix. * toplev.c (main): No sbrk on Interix. * configure.in: Add i386-pc-interix support. * configure: Regenerate. * fixinc.interix: New file. * config/interix.h: New file. * config/x-interix: New file. * config/xm-interix.h: New file. * i386/interix.h: New file. * i386/interix.c: New file. * i386/t-interix: New file. Mon Mar 22 23:41:49 1999 Jeffrey A Law (law@cygnus.com) * i386.h (PREFERRED_STACK_BOUNDARY): Define. Mon Mar 22 23:41:31 1999 John Wehle (john@feith.com) * i386.c (ix86_compute_frame_size): New function. (ix86_prologue, ix86_epilogue): Use it. * i386.h (INITIAL_ELIMINATION_OFFSET): Likewise. * reload1.c: Provide default for PREFERRED_STACK_BOUNDARY. Mon Mar 22 18:06:59 1999 Jim Wilson * mips/mips.h (TARGET_SWITCHES, TARGET_OPTIONS): Add option doc strings. * mips/abi64.h (SUBTARGET_TARGET_OPTIONS): Likewise. Mon Mar 22 16:18:27 1999 Nick Clifton * config/arm/elf.h (VALID_MACHINE_DECL_ATTRIBUTE): Do not bother passing ATTRIBUTES to arm_valid_machine_decl_attribute. * config/arm/coff.h (VALID_MACHINE_DECL_ATTRIBUTE): Do not bother passing ATTRIBUTES to arm_valid_machine_decl_attribute. * config/arm/arm.h (DEFAULT_RTX_COSTS): Do not bother passing OUTER_CODE to arm_rtx_costs - it is not used. (arm_compare_fp): Delete declaration. (FINAL_PRESCAN_INSN): Do not bother passing OPVEC or NOPERANDS to arm_final_prescan_insn - they are not used. (const_ok_for_op): Remove prototype. (arm_rtx_costs): Fix prototype. (arm_valid_machine_decl_attribute): Fix prototype. (final_prescan_insn): Fix prototype. * config/arm/arm.md: Remove references to arm_compare_fp. * config/arm/arm.c (arm_compare_fp): Delete. (const_ok_for_op): Make function static. Add prototype. Remove mode parameter - it is unused. (arm_rtx_costs): Remove outer_code parameter. (reload_memory_operand): Declare mode parameter unused. (power_of_two_operand): Declare mode parameter unused. (equality_operator): Declare mode parameter unused. (load_multiple_operation): Declare mode parameter unused. (store_multiple_operation): Declare mode parameter unused. (multi_register_push): Declare mode parameter unused. (arm_valid_machine_decl_attribute): Remove attributes parameter - it is unused. (select_dominance_cc_mode): Remove op parameter - it is unused. (gen_compare_reg): Remove fp parameter - it is unused. (final_prescan_insn): Remove opvec and noperands parameters - they are unused. Mon Mar 22 14:35:28 1999 Nick Clifton * tm.texi (MD_SCHED_INIT): Add missing closing parenthesis. Mon Mar 22 22:24:30 1999 J"orn Rennecke * reload1.c (reload_as_needed): Set reload_is_output_reload / reload_has_output_reload for auto_inc expressions that could be reloaded. Call forget_old_reloads for REG_INC notes. Mon Mar 22 21:51:57 1999 J"orn Rennecke * cse.c (cse_insn): Don't change the result register of a libcall. Mon Mar 22 21:08:59 1999 J"orn Rennecke * rtl.h (shallow_copy_rtx): Declare. * rtl.c (shallow_copy_rtx): New function. * reload.c (find_reloads_toplev): Use shallow_copy_rtx instead of copy_rtx. Mon Mar 22 10:44:33 1999 Vladimir Makarov * config/h8300/h8300.md (adjust_length): New attribute. (modhi3+1, andsi3+1, iorsi3+1, extzv+1, extzv+2): Change insn default value of attribute "adjust_length" onto "no". * config/h8300/h8300.c (h8300_adjust_insn_length): Adjust length only if the attribute "adjust_length" value is "yes". Use 0 if the shift is negative. * final.c (shorten_branches): Check insn length after its adjusting. Sun Mar 21 17:33:48 1999 Jeffrey A Law (law@cygnus.com) * i860.h (TARGET_SWITCHES): Add documentation for default case. * i860/paragon.h (TARGET_SWITCHES): Add documentation for default case. * i370.h (TARGET_SWITCHES): Add documentation for default case. * fx80.h (TARGET_SWITCHES): Add documentation for default case. * elxsi.h (TARGET_SWITCHES): Add documentation for default case. * clipper.h (TARGET_SWITCHES): Add documentation for default case. * 1750a.h (TARGET_SWITCHES): Add documentation for default case. * pa.h (TARGET_SWITCHES): Add documentation for default case. (TARGET_OPTIONS): Likewise for default case. * mn10300.h (TARGET_SWITCHES): Add documentation for default case. * h8300.h (TARGET_SWITCHES): Add documentation for default case. * gcse.c (dump_hash_table): Fix whitespace in declaration. (compute_transpout): Renamed from pre_compute_transpout. (compute_pre_*): Deleted. (pre_expr_reaches_here_p): New argument, CHECK_PRE_COMP. All callers changed. (insert_insn_end_bb): Renamed from pre_insert_insn. (pre_*): Delete unused variables. Only leave local properties and global redundant/optimal computation points. (alloc_pre_mem, free_pre_mem): Corresponding changes. (compute_pre_data): Simplify and call pre_lcm to run the lazy code motion dataflow analysis. (pre_insert, pre_insert_copies, pre_delete): Revamp to use LCM based redundant and optimal computation points. * basic-block.h (pre_lcm, pre_rev_lcm): Declare. * toplev.c (main): A debug option without a level defaults to level 2. Sun Mar 21 12:13:01 1999 Nick Clifton * flow.c (can_delete_label_p): Do not allow user specified labels to be deleted. * dwarf2out.c (gen_label_die): Generate addresses for deleted (programmer specified) labels. * dwarfout.c (output_label_die): Generate addresses for deleted (programmer specified) labels. 1999-03-21 Manfred Hollstein * Makefile.in (xgcc$(exeext)): Add intl.o to list of files to be linked with. Sun Mar 21 01:15:03 1999 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. Sat Mar 20 22:26:23 1999 Kaveh R. Ghazi * sparc.h (TARGET_SWITCHES): Add null description to default case. Sat Mar 20 21:46:06 1999 Kaveh R. Ghazi * c-lex.c (yylex): Remove unused variable `bytes'. * flow.c (print_rtl_with_bb): Cast the return value of alloca. * function.c (assign_parms): Wrap variable `varargs_setup' in macro SETUP_INCOMING_VARARGS. (thread_prologue_and_epilogue_insns): Mark parameter `f' with ATTRIBUTE_UNUSED. * local-alloc.c (no_equiv): Likewise for parameter `store'. * sched.c (schedule_insns): Remove unused variables `insn' and `next'. * tlink.c (symbol_hash_newfunc, symbol_hash_lookup, file_hash_newfunc, file_hash_lookup, demangled_hash_newfunc, demangled_hash_lookup, symbol_push, symbol_pop, file_push, file_pop, tlink_init, tlink_execute, frob_extension, obstack_fgets, tfgets, pfgets, freadsym, read_repo_file, maybe_tweak, recompile_files, read_repo_files, demangle_new_symbols, scan_linker_output): Add static prototype. (symbol_hash_newfunc, file_hash_newfunc, demangled_hash_newfunc): Make the third argument a `hash_table_key'. * toplev.c (debug_start_source_file): Mark parameter `filename' with ATTRIBUTE_UNUSED. Sun Mar 21 02:28:21 1999 Andreas Schwab * tm.texi (Varargs): Don't split argument of @item across lines. * invoke.texi: Fix use of @item vs @itemx. Sun Mar 21 09:59:54 1999 Michael Hayes * config/c4x/c4x.h (TARGET_SWITCHES): Add null description to default case. Sat Mar 20 23:33:54 1999 Michael Hayes * loop.c (check_dbra_loop): Fix debug message. Sat Mar 20 15:54:35 1999 Michael Hayes * config/c4x/c4x.md (decrement_and_branch_on_count): Emit rptb_end pattern instead of decrement_and_branch_until_zero pattern. Sat Mar 20 11:39:58 1999 Michael Hayes * config/c4x/c4x.h (TARGET_SWITCHES): Add documentation. * config/c4x/c4x.h (TARGET_OPTIONS): Add documentation. Fri Mar 19 23:26:29 1999 Martin von Löwis * expr.c (expand_expr): Handle ERROR_MARK much earlier. Fri Mar 19 15:28:38 1999 Kaveh R. Ghazi * cccp.c (create_definition): Cast to U_CHAR* when assigning to one. * cppfiles.c (read_and_prescan): Likewise. Start a #define in column 0. * cpplib.c (cpp_define): Cast to U_CHAR* when assigning to one. (cpp_push_buffer): Likewise for cpp_buffer*. (do_include): Change the type of `fbeg' and `fend' to unsigned char*. (do_endif): Cast to char* when assigning to one. (do_assert): Likewise. (do_unassert): Likewise. (cpp_read_check_assertion): Change the type of `name' to U_CHAR*. Don't do unnecessary cast to char* anymore. * genrecog.c (make_insn_sequence): Cast to char** when assigning to one. Cast the first argument of bzero to PTR. * loop.c (strength_reduce): Remove unused variable `note'. * reload1.c (new_insn_chain): Cast to struct insn_chain* when assigning to one. * rtl.c (copy_rtx): Use memcpy instead of bcopy. Fri Mar 19 11:19:31 1999 Kaveh R. Ghazi * calls.c (initialize_argument_information): Mark parameters `num_actuals' and `n_named_args' with ATTRIBUTE_UNUSED. * dbxout.c (dbxout_start_new_source_file): Likewise for parameter `filename'. (dbxout_finish): Likewise for parameters `file' and `filename'. (dbxout_prepare_symbol): Likewise for parameter `decl'. (dbxout_begin_function): Likewise. * explow.c (hard_function_value): Likewise for parameter `func'. * function.c (locate_and_pad_parm): Likewise for parameter `fndecl'. * expmed.c (expand_divmod): Omit unused argument to `expand_abs'. * expr.c (expand_expr): Likewise. * expr.h (expand_abs): Delete unused argument from prototype. * optabs.c (expand_abs): Remove unused parameter `unsignedp'. * sdbout.c (sdbout_init): Mark parameter `syms' with ATTRIBUTE_UNUSED. (sdbout_end_block): Likewise for parameter `n'. * toplev.c (debug_define): Likewise for parameters `lineno' and `buffer'. (debug_undef): Likewise. * varasm.c (named_section): Likewise for parameter 'reloc'. (assemble_external): Likewise for parameter `decl'. (assemble_alias): Likewise for parameter `target'. Fri Mar 19 01:54:30 1999 Theodore Papadopoulo * toplev.c (read_integral_parameter): Constify. Better control of error messages. (main): Use read_integral_parameter to set optimize, id_clash_len, larger_than_size, and the debugging level. * toplev.h (read_integral_parameter): Update prototype. Fri Mar 19 01:42:05 1999 Zack Weinberg * system.h: Use putc_unlocked, fputc_unlocked, and fputs_unlocked only if putc_unlocked has a prototype already. Prototype fputs_unlocked if necessary. * configure.in: Check for prototypes of putc_unlocked and fputs_unlocked. * acconfig.h: Updated. * config.in, configure: Rebuilt. Fri Mar 19 02:45:12 1999 Alexandre Oliva * Makefile.in (INTL_TARGETS): New macro. ($(INTL_TARGETS)): Depend on generated sources; drop dependencies on cp/parse.c and objc/objc-parse.c. ($(srcdir)/cp/parse.c): Move to cp/Make-lang.in. * objc/Make-lang.in ($(INTL_TARGETS)): Depend on objc/objc-parse.c. Thu Mar 18 22:28:53 1999 Jeffrey A Law (law@cygnus.com) * i860.h (TARGET_SWITCHES): Add documentation. * i860/paragon.h (TARGET_SWITCHES): Add documentation. * i370.h (TARGET_SWITCHES): Add documentation. * fx80.h (TARGET_SWITCHES): Add documentation. * elxsi.h (TARGET_SWITCHES): Add documentation. * clipper.h (TARGET_SWITCHES): Add documentation. * 1750a.h (TARGET_SWITCHES): Add documentation. * pa.h (TARGET_SWITCHES): Add documentation. (TARGET_OPTIONS): Likewise. * mn10300.h (TARGET_SWITCHES): Add documentation. * h8300.h (TARGET_SWITCHES): Add documentation. Thu Mar 18 15:58:26 1999 Nick Clifton * loop.c (strength_reduce): Do not perform pseudo replacements if the loop contains volatile memory references. Thu Mar 18 19:09:50 1999 J"orn Rennecke * reload.c (find_reloads_toplev): When processing X recursively, don't alter it destructively except by filling in constants. Thu Mar 18 10:14:18 1999 Kaveh R. Ghazi * cccp.c (default_include): Initialize structure members. (pass_thru_directive): Change the type of 'keyword_length' to int. (main): Cast `bindtextdomain' and `textdomain' to (void). * collect2.c (main): Likewise. * cppmain.c (main): Likewise. * gcc.c (main): Likewise. * gcov.c (main): Likewise. * protoize.c (main): Likewise. * toplev.c (main): Likewise. 1999-03-18 Gavin Romig-Koch * config/mips/mips.c (mips_explicit_type_size_string): Correct its type. Thu Mar 18 01:24:25 1999 Jeffrey A Law (law@cygnus.com) * configure.in: Use "exit 1", not "exit (1)". * configure: Rebuilt. Wed Mar 17 23:17:42 1999 Mark Kettenis * config/t-gnu (SYSTEM_HEADER_DIR): New variable. Set to `/include' in order to find the system's limits.h. Wed Mar 17 23:00:18 1999 Robert Lipe * fixinc/fixincl.c: Include auto-host.h instead of config.h. * fixinc/procopen.c: Likewise. * fixinc/regex.c: Likewise. * fixinc/server.c: Likewise. Wed Mar 17 22:46:13 1999 Mark Elbrecht Jeff Law * pa.md: Add real PA8000 scheduling information. * pa.h (processor_type): Add PROCESSOR_8000 symbol. (ISSUE_RATE): Revamp, including PA8000 support. * pa.c (override_options): Add 8000 as -mschedule= option. Do not call strcmp if pa_cpu_string is null. * pa.md (attr cpu): Add 8000. * invoke.texi: Add documentation for PA8000 scheduling. Wed Mar 17 18:20:24 1999 David S. Miller * config/sparc/sparc.h (TARGET_SWITCHES, TARGET_OPTIONS): Add descriptions. * config/sparc/sp64-elf.h (SUBTARGET_SWITCHES): Likewise. * config/sparc/splet.h (SUBTARGET_SWITCHES): Likewise. Wed Mar 17 14:51:19 1999 Richard Henderson * flow.c (compute_immediate_dominators): New function. * basic-block.h (compute_immediate_dominators): Declare it. * alpha.h (HARD_REGNO_MODE_OK): Allow only 4 and 8 byte unit modes in FP regs. (MODES_TIEABLE_P): Define asymmetricly wrt modes illegal in FP regs. Wed Mar 17 14:41:41 1999 Nick Clifton * config/arm/aout.h (ASM_GENERATE_INTERNAL_LABEL): Fix compile time warning. * config/arm/arm.md: Fix various compile time warnings. * config/arm/arm.h: Fix various compile time warnings. Add function prototypes. * config/arm/arm.c: Fix various compile time warnings. (arm_override_options): Reorganize to separate tuning from targetting. (bit_count): New function: Return a count of the number of bits set in a word. Wed Mar 17 21:29:12 1999 J"orn Rennecke * reload1.c (eliminate_regs): Don't keep REG_DEAD notes around for things that were eliminated. Wed Mar 17 12:16:26 1999 Richard Henderson * function.c (fixup_var_refs_1): First try moving the expression directly into a register. Don't separate cc0 setter and user. Wed Mar 17 11:20:29 1999 Dave Brolley * cppfiles.c (PIPE_BUF): #define PIPE_BUF if not defined already. Wed Mar 17 09:25:06 1999 Kaveh R. Ghazi * c-lex.c: Don't include setjmp.h. (parse_float): New static function. (pf_args): New struct. (yylex): Use them in call to `do_float_handler'. 1999-03-16 Andreas Schwab * cexp.y (yyerror): Call verror to get a useful error message. * cexp.c: Rebuilt. * .gdbinit: Move command to put breakpoint at abort to end of file so that gdb does not bail out early. Tue Mar 16 15:30:19 1999 Nick Clifton * rtl.h: Rename prototype for free_bb_memory to free_bb_mem. Tue Mar 16 23:40:09 1999 J"orn Rennecke * sh.md (movsi_i): Move t/r alternative after r/rI alternative. Tue Mar 16 13:44:50 1999 Jim Wilson * mn10200/mn10200.md (addsi3, subsi3, ashlsi3, lshrsi3, ashrsi3): Delete emit_library_call_value declaration. 1999-03-16 Zack Weinberg * cppfiles.c (read_and_prescan): Map backslash-newline to '\r' (which cannot otherwise appear in the processed buffer) and move it out of tokens that it appears in the middle of. Improve performance. (find_position): New function. * cpplib.c: \r (one character) indicates backslash newline, not \\\n (two characters). It cannot appear in the middle of a token. Call CPP_BUMP_LINE (pfile) whenever parsing moves past \n or \r. Increment pfile->lineno whenever a \n is placed into token_buffer. Only one mark can exist at a time, and CPP_BUMP_LINE must not be used while it is active. It is automatically cleared by cpp_pop_buffer and parse_goto_mark. \r is not in is_hor_space or is_space. (NEWLINE_FIX, NEWLINE_FIX1, adjust_position, update_position, count_newlines, parse_move_mark): Removed. (parse_string, copy_comment): New functions. (parse_name): Returns void. (parse_set_mark, parse_clear_mark, parse_goto_mark): Take only one argument, a cpp_reader *. Change for new marking scheme. (skip_comment): Handle CHILL line comments too. Second argument is now first character of comment marker; all callers changed. Issue error for unterminated block comment here. (cpp_skip_hspace): Recognize CHILL comments. (copy_rest_of_line): Likewise. Call skip_comment and parse_string directly, don't go through cpp_get_token. Emit "/**/" for block comments if -traditional (create_definition needs this). (do_define): Don't play with put_out_comments. (cpp_push_buffer): Initialize ->mark to -1. (cpp_buf_line_and_col): Just read out the values in the buffer structure. (output_line_command): Use cpp_buf_line_and_col. Fix formatting. Remove stale code. (cpp_get_token): Break out string parsing code to parse_string. Use skip_comment for CHILL comments too. Use copy_comment for put_out_comments instead of dinking with marks. Remove stale code. Don't call output_line_command unless it's necessary. * cpplib.h (parse_marker): Removed. (struct cpp_buffer): Line_base is now a unsigned char *; add `mark' [long], remove `marks' [struct parse_marker *]. (parse_set_mark, parse_clear_mark, parse_goto_mark): Update prototypes. (CPP_BUMP_LINE, CPP_BUMP_BUFFER_LINE): New macros. * cppinit.c (is_hor_space, is_space): '\r' is not considered whitespace. * cppexp.c (cpp_parse_expression): Use cpp_skip_hspace, not SKIP_WHITE_SPACE. * cpphash.c (macarg): Disable line commands while expanding. Tue Mar 16 11:30:19 1999 Gavin Romig-Koch * c-lex.c (yylex) : Remove warning for integer literals being larger than the largest target int. Add warning for integer literal being larger than than its chosen type. Tue Mar 16 10:53:17 1999 Gavin Romig-Koch * invoke.texi: Add -mlong32 documentation. * config/mips/mips.h (mips_explicit_type_size_string): New. (TARGET_SWITCHES): Add 'long32'. (TARGET_OPTIONS): Add 'explicit-type-size'. (CC1_SPECS): Set -mexplicit-type-size. (LONG_MAX_SPEC): Change a use of 'no-long64' to 'long32'. * config/mips/abi64.h (LONG_MAX_SPEC): Same. Add 'mabi=32'. * config/mips/mips.c (mips_explicit_type_size_string): New. (override_options): Use it. * config/mips/osfrose.h (CC1_SPECS): Set -mexplicit-type-size. * config/mips/mips.h (SUBTARGET_CPP_SIZE_SPEC): Pointer size now depends on both size longs and size of GP registers. Tue Mar 16 10:22:22 1999 Gavin Romig-Koch * config/mips/iris.h (CTORS_SECTION_ASM_OP,DTORS_SECTION_ASM_OP, dtors_section): Use Pmode == DImode rather than TARGET_LONG64. * config/mips/mips.c (override_options): Allow -mlong64 and -mint64 with -mips2 or less. * config/mips/mips.h (MASK_LONG64): Fix comment. (POINTER_SIZE): Use Pmode == DImode rather than TARGET_LONG64. (Pmode): Make Pmode the smaller of longs or gp registers. * invoke.texi: Note the new size for pointers. Mon Mar 15 22:45:25 1999 David Edelsohn * rs6000.h (ASM_OUTPUT_{DOUBLE,FLOAT}): Always generate IEEE 754 bit-pattern directly. (ASM_OUTPUT_REG_{PUSH,POP}): Delete. * rs6000.c (first_reg_to_save): If profiling and context needed, allocate a reg to save static chain for all ABIs. For AIX profiling, calculate parameter registers to save based on need. (output_function_profiler): Save and restore static chain around profile call for all ABIs. 1999-03-15 Zack Weinberg * cppinit.c: Instead of one pending list, keep separate lists for each category of pending option: -D/-U, -A, -include, -imacros. Move the four partial include-path lists into the pending block. Use head and tail pointers so we don't ever have to reverse the lists. (cpp_start_read): Break out blocks of code to their own functions: install_predefs and initialize_dependency_output. Use path_include for C_INCLUDE_PATH and friends as well as CPATH. Remove include_defaults gunk. Warn about the combination of -lang-chill and -trigraphs. Optimize string bashing. Walk each pending list once, deallocating as we go. (append_include_chain): Brought over from cppfiles.c. Mark dirs as system include dirs if and only if appending to system include path. If opts->verbose, print a notice when a dir is dropped from the include path because it doesn't exist. Fix memory leak: this function is not supposed to copy its DIR argument. (nreverse_pending, push_pending): Removed. (APPEND): New macro for adding to pending lists. (path_include): Can now add to any partial include path. (base_name): Bring over from cccp.c. (cpp_options_init): Allocate the pending block. (cpp_handle_option): Add --version. Exit after --help. Fix formatting. Order -ifoo options by frequency of usage. (install_predefs): New function, simplified version of code that was in cpp_start_read. (initialize_dependency_output): Likewise. Understand OBJECT_SUFFIX. * cppfiles.c (simplify_pathname): Export. (merge_include_chains): Don't nreverse the lists. If opts->verbose, print a notice when a duplicate dir is detected and dropped from the include path. (finclude): Fix excessive cleverness in setting fp->system_header_p. (actual_directory): Set x->sysp from CPP_BUFFER (pfile)->system_header_p so that one system header may include another with "". (deps_output): Fix double adjustment of deps_size which would cause all dependencies after the first two lines to be lost. * cpplib.c (cpp_unassert): New function. * cpplib.h: Lay out struct cpp_pending here. Adjust prototypes. Add include_prefix_len to struct cpp_options. Mon Mar 15 16:01:52 1999 Jim Wilson * config/misp/mips.h (REGISTER_MOVE_COST): Make the cost of moving from HI/LO/HILO/MD into general registers the same as for one of moving general registers to HI/LO/HILO/MD. Mon Mar 15 12:39:38 1999 Nick Clifton * config/m32r/m32r.c (init_idents): New function. Initialize static tree nodes for m32r specific attribute identifiers. Remove leading and trailing double underscores from the attribute names. (m32r_valid_machine_decl_attribute): Call init_idents. (m32r_encode_section_info): Call init_idents. Mon Mar 15 10:20:20 1999 Mark Mitchell * reload.c (find_reloads): Add a REG_LABEL note if we substitute a LABEL_REF for something else. Mon Mar 15 08:24:17 1999 Kaveh R. Ghazi * fold-const.c (exact_real_inverse): Move variable `float_error' into the scope where it is used. (const_binop_1): New static function. (cb_args): New struct. (const_binop): Use them in call to `do_float_handler'. (fold_convert_1): New static function. (fc_args): New struct. (fold_convert): Use them in call to `do_float_handler'. Mon Mar 15 22:50:18 1999 Michael Hayes * rtlanal.c (auto_inc_p): New function. * rtl.h (auto_inc_p): Prototype it. * reload1.c (add_auto_inc_notes): New function. (reload): Strip REG_INC notes and call add_auto_inc_notes for each insn to restore them correctly. 1999-03-15 Manfred Hollstein * fixinc/Makefile.in (procopen.o): List the actual dependencies. Sun Mar 14 16:22:10 1999 Kaveh R. Ghazi * cse.c (check_fold_consts): New static function. (cfc_args): New struct. (simplify_relational_operation): Use them in call to `do_float_handler'. * toplev.c (do_float_handler): New function to wrap calls to setjmp/set_float_handler. * toplev.h (do_float_handler): Add extern prototype. * tree.c (build_real_from_int_cst_1): New static function. (brfic_args): New struct. (build_real_from_int_cst): Use them in call to `do_float_handler'. Sun Mar 14 01:15:06 1999 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. Sat Mar 13 17:37:18 1999 Richard Henderson * haifa-sched.c (sched_analyze_1): Only clear reg_last_uses on a SET. Sat Mar 13 11:36:16 1999 Richard Earnshaw (rearnsha@arm.com) * arm.c (arm_split_constant): Don't try to force a constant to memory after arm_reorg has run. (after_arm_reorg): New static variable. (arm_reorg): Set it. (output_func_epilogue): Clear it. Fri Mar 12 20:26:32 1999 David Edelsohn * configure.in ({rs6000,powerpc}-ibm-aix*): Set float_format to none. * configure: Rebuilt. Fri Mar 12 20:45:30 1999 J"orn Rennecke * unroll.c (loop_iterations): Don't return a final value for EQ comparison loops. Fri Mar 12 12:35:01 1999 Jim Wilson * reload1.c (calculate_needs_all_insns): When ignore equivalence setting insn, clear need_elim, need_reload, and need_operand_change. Fri Mar 12 07:54:43 1999 Bruce Korb * fixinc/fixinc.*: Some changes from the fixincl-branch were not applied (??!!). Corrected. * fixinc/Makefile.in: Same thing. Fri Mar 12 00:51:43 1999 Jeffrey A Law (law@cygnus.com) * expr.c (expand_expr): Allow a CALL_EXPR with a mode wider than MAX_INTEGER_COMPUTATION_MODE. Thu Mar 11 14:00:58 1999 Richard Henderson * alpha.h (HARD_REGNO_MODE_OK): Disallow QI/HImode in fp regs. (MODES_TIEABLE_P): Update. * alpha.md (ev5_e0): Conflict loads and stores. Thu Mar 11 13:55:52 1999 Richard Henderson * machmode.h (smallest_mode_for_size): Prototype. * stor-layout.c (smallest_mode_for_size): Remove static. Thu Mar 11 21:25:59 1999 J"orn Rennecke * loop.c (strength_reduce): Don't do biv increment -> DEST_REG giv conversion if we don't know the lifetime. Thu Mar 11 20:37:59 1999 J"orn Rennecke * reload.1c (delete_address_reloads_1): Check for reloads of CURRENT_INSN even if it sets DST. Thu Mar 11 10:29:50 1999 Jason Merrill * dwarf2out.c (add_AT_lbl_offset): Rename from add_AT_section_offset. (print_die, size_of_die, value_format, output_die): Adjust. Thu Mar 11 10:27:42 1999 Robert Lipe * dwarf2out.c (TEXT_SECTION_LABEL, DEBUG_LINE_SECTION_LABEL, DEBUG_INFO_SECTION_LABEL, ABBREV_SECTION_LABEL, text_section_label, debug_line_section_label, debug_info_section_label, abbrev_section_label): New. (output_compilation_unit_header): Emit label associated with section instead of section name itself. (out_pubnames, output_aranges, output_line_info, dwarf2out_finish): Likewise. (dwarf2out_init): Build internal label names for sections from static labels. Thu Mar 11 17:28:32 1999 J"orn Rennecke * sh.md (mulsi3): End mul.l sequence with a no-op move. Thu Mar 11 08:52:02 1999 Bruce Korb * Makefile.in: Activated fixinc/mkfixinc.sh. * configure.in: Activated fixinc/mkfixinc.sh. Thu Mar 11 01:38:02 1999 Mumit Khan * cppfiles.c (INO_T_EQ): Handle UWIN. * c-common.c (decl_attributes): Flag unrecognized attribute functions as warnings instead of as errors. Support for i386-pc-uwin. * i386/uwin.h: New file. * i386/xm-uwin.h: New file. * i386/t-uwin: New file. * i386/uwin.asm: New file. * configure.in (i[3456]86-*-uwin*): Define. Add Workaround for vfork bug when hosted on uwin. * configure: Regenerate. * cccp.c (INO_T_EQ): Undefine. UWIN has inodes. (absolute_filename): UWIN uses POSIX pathnames only. * libgcc2.c (getpagesize): Do not define for UWIN. (mprotect): Likewise. * protoize.c (dirent.h): Conditionally include. (fputc): Prototype only if it's not a macro. Wed Mar 10 02:49:04 1999 Jason Merrill * configure.in: Remove init_priority stuff. 1999-03-11 Colin Smith * sdbout.c (plain_type_1): Make boolean types work better with sdb. Thu Mar 11 00:20:52 1999 Alexandre Oliva * gcc.texi: Update bug reporting instructions to match current ezmlm list reality. Wed Mar 10 23:11:19 1999 Kaveh R. Ghazi * gcc.c (print_file_name, print_prog_name, spec_machine, read_specs, set_spec, lookup_compiler, build_search_list, putenv_from_prefixes, find_a_file, record_temp_file, delete_if_ordinary, handle_braces, do_spec, do_spec_1, find_file, is_directory, validate_switches, used_arg, default_arg, pfatal_with_name, perror_with_name, pfatal_pexecute, fatal, error, notice, add_preprocessor_option, add_assembler_option, add_linker_option, process_command, execute, unused_prefix_warnings, clear_args, fatal_error, lang_specific_driver, user_specs, compiler, link_command_spec, option_map, translate_options, make_temp_file, temp_name, programname, path_prefix, machine_suffix, just_machine_suffix, gcc_exec_prefix, standard_exec_prefix, standard_exec_prefix_1, md_exec_prefix, md_startfile_prefix, md_startfile_prefix_1, standard_startfile_prefix, standard_startfile_prefix_1, standard_startfile_prefix_2, tooldir_base_prefix, tooldir_prefix, multilib_dir, temp_filename, temp_file, command, switchstr, infile, outfiles, input_filename, input_basename, input_suffix, check_live_switch, main): Qualify a char* with the `const' keyword. Wed Mar 10 20:28:29 1999 Jeffrey A Law (law@cygnus.com) * lcm.c: New file. * Makefile.in (OBJS): Add lcm.o. (lcm.o): Add dependencies. * gcse.c (compute_pre_local_properties): Delete. (compute_pre_data): Use compute_local_properties instead of compute_pre_local_properties. * gcse.c: More comments, whitespace and similar fixes. (dump_cuid_table, maybe_set_rd_gen, dump_cprop_data): Delete. (dump_pre_data, compute_cprop_local_properties): Likewise. (one_classic_gcse_pass): Lose unused argument. All callers changed. (compute_hash_table, compute_expr_hash_table): Likewise. (compute_set_hash_table, one_pre_gcse_pass, mark_call): Likewise. (cprop_insn, cprop, one_cprop_pass): Add new argument ALTER_JUMPS. All callers changed. Only alter jumps if ALTER_JUMPS is nonzero. Lose unused argument. (gcse_main): Always run a cprop pass after finishing global cse. (compute_local_properties): New function. (hash_scan_pat, hash_scan_insn): No longer call maybe_set_rd_gen. (compute_cprop_data): Use compute_local_properties. * gcse.c: Update various comments. (current_function_calls_longjmp): Delete declaration. * gcse.c (run_jump_opt_after_gcse): New variable. (gcse_main): Returns an integer. (hash_scan_set): Record initializations from CONST_DOUBLEs too. (try_replace_reg): Update some comments. (cprop_insn): Allow propagation into some JUMP_INSNs too. * rtl.h (gcse_main): Update prototype. * toplev.c (rest_of_compilation): If gcse_main returns nonzero, then run a jump optimization pass. * jump.c (delete_barrier_successors): Delete nop jumps too. Wed Mar 10 19:04:31 1999 J"orn Rennecke * sh.c (fp_arith_reg_operand): Actually test if reg is suitable for FP arithmetic. Changed caller. * sh.md (subsf3, subsf_i): Use fp_arith_reg_operand. Wed Mar 10 18:56:31 1999 J"orn Rennecke * reload1.c (choose_reload_regs): When inheriting from the frame pointer, don't clobber it. Wed Mar 10 08:01:52 1999 Bruce Korb * fixinc/fixinc.*: Resync-ed with the files in this directory. * fixinc/mkfixinc.sh: The machine case elements were out-of-order. (the ix86-*-linux-gnu* entry needed to be earlier). Wed Mar 10 00:01:24 1999 J"orn Rennecke * reload1.c (reload_combine_note_store): Fix calculation of number of affected registers. Tue Mar 9 15:48:15 1999 Richard Henderson * flow.c (tidy_fallthru_edge): Be more careful finding the last BARRIER of a list. Delete the cc0 setter as well as a cond jump. Tue Mar 9 15:26:02 1999 Hans-Peter Nilsson * i386.md (ashlsi3 splitter): Fix typo in last change. Tue Mar 9 11:35:20 1999 Richard Henderson * reg-stack.c (stack_reg_life_analysis): Use returnjump_p instead of an explicit test for RETURN. Tue Mar 9 09:33:16 1999 Kaveh R. Ghazi * Makefile.in (toplev.o): Depend on $(BASIC_BLOCK_H). * toplev.c: Include basic-block.h. Tue Mar 9 02:08:17 1999 Jeffrey A Law (law@cygnus.com) * calls.c (load_register_parameters): New function. (expand_call): Use it. * calls.c (expand_call): Slightly reorganize code. * calls.c (compute_argument_addresses): New function. (rtx_for_function_call): New function. (expand_call): Use them. * i386.md (zero_extendhisi2): Split into an expander and anonymous pattern. Add new anonymous pattern for use when optimizing for size or for the PPro. (zero_extendqihi2, zero_extendqisi2): Likewise. Mon Mar 8 23:43:47 1999 Richard Henderson * haifa-sched.c (sched_analyze_1): Fix last change -- add clobber dependencies to sets in the non-hard-reg case too. Mon Mar 8 18:55:21 1999 Marc Espie * config/openbsd.h (HANDLE_SYSV_PRAGMA): Define. Mon Mar 8 16:04:44 1999 Jim Wilson * local-alloc.c (combine_regs): Don't combine if we have a hard reg for which CLASS_LIKELY_SPILLED_P is true. * unroll.c (loop_iterations): Only call loop_find_equiv_value if we have a REG or SUBREG. Mon Mar 8 15:27:42 1999 Jeffrey A Law (law@cygnus.com) * i386.md (ashlsi3): Revise comments. Provide new anonymous pattern for Pentium and PPro/PII. Reverse constraints in generic ashlsi3 anonymous pattern. * calls.c (initialize_argument_info): Accept a pointer to CUMULATIVE_ARGS. (expand_call): Pass the address of CUMULATIVE_ARGS. * rs6000/xm-sysv4.h (HOST_BITS_PER_LONGLONG): Remove #if 0. * mn10300.h (CASE_DROPS_THROUGH): Delete. * mn10200.h (CASE_DROPS_THROUGH): Delete. * h8300.h (CASE_DROPS_THROUGH): Delete. * flow.c (merge_blocks_nomove): For HAVE_cc0 targets, make sure to also delete the cc0 setter when deleting a conditional branch to the next block. Mon Mar 8 18:47:11 1999 J"orn Rennecke * regmove.c (copy_src_to_dest): New argument max_old_uid. Mon Mar 8 08:23:00 1999 Bruce Korb * ChangeLog: Merged entries from fixincl-branch. Sun Mar 7 11:48:56 1999 Richard Henderson * haifa-sched.c (ENCODE_BLOCKAGE): Don't shift unit too far. (print_exp): Special case addition of a constant. (print_value) [CONST_INT]: Use HOST_WIDE_INT_PRINT_HEX. Sun Mar 7 11:21:02 1999 Richard Henderson * haifa-sched.c (reg_last_clobbers): New. (reg_pending_clobbers, bb_reg_last_clobbers): New. (compute_block_backward_dependences): Allocate memory for them. (schedule_region): Likewise. (sched_analyze_1): Clobbers don't interfere with one another. They do interfere with sets ... (sched_analyze_2): ... and uses. (sched_analyze): Likewise. (sched_analyze_insn): Update reg_last_clobbers appropriately. Sun Mar 7 08:30:37 1999 Kaveh R. Ghazi * gmon-sol2.c: Include config.h and system.h. Don't redundantly include system header files. (sccsid): Remove. (moncontrol, monstartup, _mcleanup, internal_mcount): Prototype. (_mcleanup): Add the `const' keyword to a char*. (internal_mcount): Declare `etext' as a char[] not a function. Cast `etext' to char* when calling `monstartup'. * sparc.c (frame_base_name, save_regs, restore_regs, build_big_number, sparc_cmodel_string, sparc_align_loops_string, sparc_align_jumps_string, sparc_align_funcs_string, code_model, cpu_default, cpu_table, output_function_prologue, output_function_epilogue, output_return, sparc_flat_output_function_prologue, ultra_code_names, sparc_flat_output_function_epilogue): Constify a char*. (hypersparc_adjust_cost): Add a default case in a switch. * sparc.h (sparc_cmodel_string, OVERRIDE_OPTIONS, sparc_cpu_select, sparc_align_loops_string, sparc_align_jumps_string, sparc_align_funcs_string, output_return): Constify a char*. * sparc.md (movdi): Change the comparison of HOST_BITS_PER_WIDE_INT so that we check "== 32", instead of "!= 64". Cast a value to HOST_WIDE_INT when comparing against one. Hide the declaration for variable `chain'. Sun Mar 7 08:05:27 1999 Kaveh R. Ghazi * system.h (const, inline): Move the stage2 handling of these keywords-as-macros from here... * gansidecl.h (const, inline): ...to here. Sun Mar 7 02:44:15 1999 Richard Henderson * recog.c (push_operand, pop_operand): VOIDmode needn't match modes. Sun Mar 7 01:58:47 1999 Richard Henderson * cse.c (canon_hash): Never reject hard regs in CCmode. Sun Mar 7 01:15:04 1999 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. Sat Mar 6 17:18:44 1999 Richard Earnshaw (rearnsha@arm.com) Richard Henderson * flow.c (make_edges): Handle casesi that jump to default branch. If CASE_DROPS_THROUGH, force fallthru to block after casesi. Sat Mar 6 07:49:23 1999 Kaveh R. Ghazi * c-aux-info.c (data_type, affix_data_type, gen_decl, gen_formal_list_for_type, gen_formal_list_for_func_def, gen_type): Qualify a char* with the `const' keyword. * c-common.c (declare_hidden_char_array, add_attribute, if_elt, declare_function_name, decl_attributes, format_char_info, check_format_info, binary_op_error): Likewise. * cexp.y (yyerror, error, pedwarn, warning, token): Likewise. * gcse.c (dump_hash_table): Likewise. * integrate.c (function_cannot_inline_p): Likewise. * optabs.c: Include insn-config.h earlier. (init_libfuncs, init_integral_libfuncs, init_floating_libfuncs): Qualify a char* with the `const' keyword. * real.c (asctoe24, asctoe53, asctoe64, asctoe113, asctoe, asctoeg, mtherr, ereal_atof): Likewise. * real.h (ereal_atof): Likewise. * sbitmap.c (dump_sbitmap_vector): Likewise. * sbitmap.h (dump_sbitmap_vector): Likewise. * stmt.c (nesting, n_occurrences, expand_start_case): Likewise. * toplev.c (rest_of_compilation): Likewise. * tree.h (function_cannot_inline_p, expand_start_case): Likewise. Fri Mar 5 23:16:42 1999 David Edelsohn * rs6000.h (ASM_OUTPUT_REG_{PUSH,POP}): Add 64-bit support and do not overwrite AIX link register save area. Fri Mar 5 23:08:01 1999 J"orn Rennecke * reload.c (find_reloads_subreg_address): Actually create the USE for the register, not the new memory location. Fri Mar 5 21:41:07 1999 J"orn Rennecke * reload1.c (emit_reload_insns): If pseudo that can't be replaced with its equivalent constant, fall back to reload_in. Fri Mar 5 13:20:39 1999 Richard Henderson * Makefile.in: Delete .flow2 debugging files. Fri Mar 5 11:36:11 1999 Nick Clifton * config/arm/arm.c (arm_override_options): Change default target cpu selection so that enabling TARGET_APCS_32 does not override default target CPU. Fri Mar 5 19:26:23 1999 J"orn Rennecke * sh.h (SLOW_BYTE_ACCESS): Define to 1. (BOOL_TYPE_SIZE): Define. Fri Mar 5 02:14:54 1999 John Wehle (john@feith.com) * function.c (assign_stack_temp_for_type): Abort if mode == Blkmode and align is less than BIGGEST_ALIGNMENT / BITS_PER_UNIT. (assign_stack_temp_for_type): Round the size parameter passed to assign_stack_local instead of size itself. Thu Mar 4 15:00:35 1999 Richard Henderson * flow.c (delete_unreachable_blocks): Mark blocks as they are put on to the worklist, not as they are taken off. Thu Mar 4 00:05:44 1999 Jeffrey A Law (law@cygnus.com) * function.c (current_function_has_computed_jump): Remove duplicate definition. Wed Mar 3 19:09:11 1999 Jim Wilson * m68k/m68020-elf.h (INIT_SECTION_ASM_OP, FINI_SECTION_ASM_OP): Undef. (STARTFILE_SPEC, ENDFILE_SPEC): Define to empty string. * sparc/elf.h (MULDI3_LIBCALL, DIVDI3_LIBCALL, UDIVDI3_LIBCALL, MODDI3_LIBCALL, UMODDI3_LIBCALL, STDC_0_IN_SYSTEM_HEADERS): Undef. (INIT_SUBTARGET_OPTABS): Define to empty. Wed Mar 3 00:00:37 1999 J"orn Rennecke * sh.c (force_into): New function. (expand_block_move): Use it. Tue Mar 2 10:39:43 1999 Nick Clifton * cccp.c (struct default_include): Add 'included' field. (main): Set 'included' field when a default include directory is added to the chain. If -v is specified list all default include directories which do not get appended to the chain. Tue Mar 2 09:24:10 1999 Nick Clifton * configure.in (gxx_include_dir): Rename to gcc_gxx_include_dir in order to prevent it being overridden by a top level Makefile. (gcc_tooldir): If $exec_prefix != $prefix then use the difference between the two as the basis for gcc_tooldir. * configure: Rebuild. * Makefile.in: Rename gxx_include_dir to gcc_gxx_include_dir. Tue Mar 2 16:45:31 1999 J"orn Rennecke * unroll.c (copy_loop_body): Don't make extra copies of NOTE_INSN_LOOP_CONT notes. Tue Mar 2 07:44:56 1999 Mark Mitchell * tree.c (save_tree_status): Don't treat functions with no context as nested. Tue Mar 2 09:37:05 1999 Robert Lipe * Makefile.in (MAKEINFO): Use makeinfo built from sibling tree when available. Tue Mar 2 10:12:48 1999 Kaveh R. Ghazi * alpha.c (alpha_cpu_name, alpha_cpu_string, alpha_tp_string, alpha_fprm_string, alpha_fptm_string, alpha_mlat_string, current_function_file): Add the `const' keyword. (normal_memory_operand): Mark parameter `mode' with ATTRIBUTE_UNUSED. (alpha_expand_unaligned_load): Add a default case to a switch. * alpha.h (alpha_cpu_string, alpha_fprm_string, alpha_fptm_string, alpha_tp_string, alpha_mlat_string): Add the `const' keyword. (normal_memory_operand): Add prototype. * alpha.md: Cast an expression to `unsigned HOST_WIDE_INT' when comparing against one. Tue Mar 2 10:00:21 1999 Kaveh R. Ghazi * mips.c (abort_with_insn): Make function static, add a prototype, constify 2nd parameter and mark with ATTRIBUTE_NORETURN. (current_function_file, mips_cpu_string, mips_isa_string, mips_abi_string, mips_no_mips16_string, mips_entry_string, mips_move_1word, mips_move_2words, output_block_move, load_store, override_options, make_temp_file, mips16_fp_args): Qualify a char* with the `const' keyword. * mips.h (current_function_file, mips_cpu_string, mips_isa_string, mips_abi_string, mips_entry_string, mips_no_mips16_string, mips_move_1word, mips_move_2words, output_block_move): Likewise. (abort_with_insn): Remove extern prototype. * mips.md: Qualify a char* with the `const' keyword. Remove many unused variables named `label'. Tue Mar 2 01:27:52 1999 H.J. Lu (hjl@gnu.org) * Makefile.in (cpp_install_dir, INSTALL_CPP, UNINSTALL_CPP): New variables. (install-cpp, uninstall-cpp): New targets. (install-normal): Depend on $(INSTALL_CPP). (uninstall): Depend on $(UNINSTALL_CPP). * configure.in (cpp_install_dir): New, substitute. (tmake_file): Added t-install-cpp for --enable-cpp. * configure: Rebuilt. * cpp.sh: New cpp script. * config/t-install-cpp: New target fragment. Tue Mar 2 01:40:01 1999 Franz Sirl Jeffrey A Law (law@cygnus.com) * cse.c (fold_rtx): Update comments for (const (minus (label) (label))) case. (cse_insn): Avoid creating a bogus REG_EQUAL note for (const (minus (label) (label))) (record_jump_cond): Fix mismatched paren in comment. Tue Mar 2 01:07:12 1999 Dan Nicolaescu * final.c (end_final): There are 11 words in the "main header" structure, not 10. Tue Mar 2 00:09:18 1999 Marc Espie * extend.texi: Reference __extension__ in the index. Mon Mar 1 19:09:32 1999 Jim Wilson * Makefile.in (CROSS_FLOAT_H): Delete. (FLOAT_H): Use float_h_file. (rest.cross, stmp-int-hdrs): Delete gfloat.h dependency. (gfloat.h): Delete. (stmp-int-hdrs): Use FLOAT_H instead of gfloat.h. (mostlyclean): Delete gloat.h reference. (install-cross-rest, install-float-h-cross, stmp-headers): Update comments. * configure.in (sparcv9-*-solaris2*): Set float_format to none. (sparc-*-solaris2*): Set float_format to none for 2.5 and higher. (float_h_file): Set from float_format. Substitute into Makefile.in. (float_format): No longer substitute into Makefile.in. * cross-make (FLOAT_H): Delete. * config/mips/t-cross64 (FLOAT_H): Delete. * configure: Rebuilt. Mon Mar 1 16:36:18 1999 Jeffrey A Law (law@cygnus.com) * mips.md (div_trap_normal, div_trap_mips16): Require the dependent insn to be an INSN before looking at its pattern. Mon Mar 1 15:03:51 1999 Jim Wilson * config/m68k/lb1sf68.asm (udivsi3): Change jmi to jcs. Fix comments. * config/m68k/m68k.h (LEGITIMATE_INDEX_REG_P): Reject SIGN_EXTEND of HImode reg when TARGET_5200. Mon Mar 1 21:44:30 1999 J"orn Rennecke From Toshiyasu Morita: * sh.h (CACHE_LOG): SH2 has cache, too. Mon Mar 1 14:23:36 1999 Catherine Moore * toplev.c (compile_file): Disable -ffunction-sections and debugging warning if the object format is elf. Mon Mar 1 11:46:25 1999 Vladimir N. Makarov * config/h8300/h8300.c (print_operand): Use 16 bit addressing when the data in 8-bit area and can not be addressed by 8-bit. Sun Feb 28 16:40:00 1999 Richard Henderson * flow.c (create_basic_block): Disregard integrated bb notes. Sun Feb 28 15:57:06 1999 Richard Henderson * sparc.md (blockage, nonlocal_goto_receiver): Set length to 0. Sun Feb 28 14:47:53 1999 Arturo Montes * config/i386/t-sco5gas (crti.o): New target. Sun Feb 28 15:10:17 1999 David Edelsohn * rs6000.md (elf_high, movsi_got, *movsi_got_internal, *movsi_got_internal_mem, GOT splitter, movdf_hardfloat32, movdf_softfloat32, movdf_hardfloat64, movdf_softfloat64, load_multiple, allocate_stack, call_indirect_aix32, call_indirect_aix64, call_value_indirect_aix32, call_value_indirect_aix64, call_indirect_nt, call_value_indirect_nt): Use gpc_reg_operand instead of register_operand. Sun Feb 28 15:10:17 1999 Michael Meissner * rs6000.md (one_cmplsi2, andsi3, iorsi3, xorsi3, *eqvsi3, *andcsi3, *iorcsi3, *nandsi3, *norsi3): Add alternatives to use CR other than cr0. * rs6000.c (and{,64}_operand): If the user did -ffixed-cr0, don't allow andi. or andis. which always set cr0. Sun Feb 28 01:15:04 1999 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. Sun Feb 28 02:00:38 1999 Jeffrey A Law (law@cygnus.com) * invoke.texi: Update information for PA scheduling. Sat Feb 27 23:21:47 1999 Jerry Quinn Mike Stump * pa.c (override_options): Change default to 7100LC. * pa.h (REG_ALLOC_ORDER): Change order to allocate left half of float regs before right half of float regs. Sat Feb 27 22:48:38 1999 H.J. Lu (hjl@gnu.org) Jeffrey A Law (law@cygnus.com) * frame.h: Update some comments. * defaults.h (TARGET_ATTRIBUTE_WEAK): Define. * crtstuff.c (__register_frame_info, __deregister_frame_info): Declare using TARGET_WEAK_ATTRIBUTE. (__do_global_dtors_aux): Check if __deregister_frame_info is zero before calling it. (__do_global_dtors): Likewise. (frame_dummy): Check if __register_frame_info is zero before calling it. (__frame_dummy): Likewise. Sat Feb 27 19:18:24 1999 Jeffrey A Law (law@cygnus.com) * SERVICE: Update from the FSF. Sat Feb 27 14:31:22 1999 Arturo Montes * config/i386/t-sco5 (crti.o): New target. * config/i386/sco5.h (STARTFILE_SPEC): Include crti.o when linking -shared. * configure.in (i[34567]86-*-sco3.2v5*): Add crti.o. Sat Feb 27 01:12:40 1999 Jeffrey A Law (law@cygnus.com) * md.texi (prologue,epilogue): Document named patterns. Fri Feb 26 19:31:25 1999 Dave Love * md.texi, invoke.texi: Fix unterminated @xrefs. Fri Feb 26 15:33:45 1999 Richard Henderson * genattrtab.c (simplify_knowing): Fix uninitialized read in Feb 21 change. * genextract.c (main): Clear recog_operands before extracting. Fri Feb 26 02:24:57 1999 Jeffrey A Law (law@cygnus.com) * c-pragma.c (add_weak); Delete. Moved into... * varasm.c (add_weak): New external function. (declare_weak): If HANDLE_PRAGMA_WEAK, then add the function to the list of weak functions. * c-pragma (add_weak): Declare. Thu Feb 25 23:43:59 1999 Richard Henderson Flow rewrite to use basic block structures and edge lists: * basic-block.h (x_basic_block_head, x_basic_block_end): Kill. (basic_block_computed_jump_target, basic_block_live_at_start): Kill. (struct edge_def): New. (struct basic_block_def): New. (basic_block_info): New. (BLOCK_HEAD, BLOCK_END): Update. (ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR): New. (uid_block_number): Kill. (basic_block_for_insn, BLOCK_FOR_INSN): New. (BLOCK_NUM): Update. * flow.c (XNMALLOC): Kill. (max_uid_for_flow): Kill. (uid_block_number): Kill. (uid_volatile): Turn into a bitmap. (SET_INSN_VOLATILE): New. (basic_block_info): New. (entry_exit_blocks): New. (x_basic_block_head, x_basic_block_end): Kill. (basic_block_computed_jump_target, basic_block_live_at_start): Kill. (flow_int_list_blocks, basic_block_succ, basic_block_pred): Kill. (basic_block_loop_depth): Kill. (basic_block_for_insn): New. (find_basic_blocks): Split out initial block counting into count_basic_blocks. Call functions split out of find_basic_blocks_1. (count_basic_blocks): New. (find_basic_blocks_1): Split out edge recognition, unreachable block deletion. (create_basic_block): New. (compute_bb_for_insn): New. (clear_edges): New. (free_bb_memory): Kill. (add_edge, add_edge_to_label): Kill. (mark_label_ref): Kill. (make_edges): Rewrite to use edge lists. (make_edge, make_label_edge): New. (mark_critical_edges): New. (split_edge, insert_insn_on_edge): New. (commit_one_edge_insertion, commit_edge_insertions): New. (delete_unreachable_blocks): Rewrite to use edge lists. Split out EH region manipulation into delete_eh_regions. Call tidy_fallthru_edge and merge_blocks. (delete_eh_regions): New. (delete_note_p): New. (delete_insn_chain): New. (delete_block): Split out code into delete_insn_chain and tidy_fallthru_edge. Update edge lists. (expunge_block): New. (flow_delete_insn): New? (can_delete_label_p): New? (merge_blocks_nomove, merge_blocks): New. (tidy_fallthru_edge): New. (calculate_loop_depth): New. (life_analysis): Allocate and free uid_volatile. (free_basic_block_vars): Update for new structures. (record_volatile_insns): Use SET_INSN_VOLATILE. (mark_regs_live_at_end): Tidy EXIT_IGNORE_STACK usage. (mark_used_regs): Likewise. (life_analysis_1): Use bb global_live_at_start, global_live_at_end, local_set regsets. Use bb->aux to store new_live_at_end. Begin life propagation from EXIT_BLOCK rather than last block. Clear regs_ever_live after mark_regs_live_at_end. (allocate_for_life_analysis): Update for new structures. (propagate_block): Split out loop depth calculation to calculate_loop_depth. (regno_uninitialized): Use bb->global_live_at_start. (regno_clobbered_at_setjmp): Likewise. (dump_bb_data): Likewise. (find_auto_inc): Use BLOCK_FOR_INSN instead of BLOCK_NUM. (dump_flow_info): Update for new structures. (dump_edge_info): New. (print_rtl_with_bb): Update for new structures. (compute_preds_succs): Do no work -- convert edge lists. (set_block_for_insn): From corpse of old set_block_num. (set_block_num): Call it. * rtl.c (note_insn_name): Add NOTE_INSN_BASIC_BLOCK. * rtl.h (rtunion_def): Add bb entry. (NOTE_BASIC_BLOCK): New. (NOTE_INSN_BASIC_BLOCK): New. * varray.h (varray_data_tag): Add bb entry. (VARRAY_BB_INIT, VARRAY_BB): New. * emit-rtl.c (emit_label_before): New. * except.c (expand_rethrow): Delete insns following the call to rethrow. Put the REG_EH_RETHROW on the call. * jump.c (returnjump_p, returnjump_p_1): New. * expr.h (nonlocal_goto_handler_labels): New declaration. * function.c (nonlocal_goto_handler_labels): Define it. (push_function_context_to): Save it. (pop_function_context_from): Restore it. (init_function_start): Clear it. (nonlocal_label_rtx_list): Kill. * function.h (struct function): Add storage space for it. * stmt.c (expand_nl_handler_label): Return the new label. (expand_nl_goto_receivers): Collect a list of them in nonlocal_goto_handler_labels. * Makefile.in (print-rtl.o): Depend on basic-block.h. (flow.o): Depend on insn-flags.h. * function.c (thread_prologue_and_epilogue_insns): Do not half-heartedly update bb structures. * toplev.c: Add flow2 dump as -dw. (rest_of_compilation): Finish .greg before flow2. * graph.c (draw_edge): Handle class 3. (print_rtl_graph_with_bb): Make abnormal edges red class 2, change non-fall-thru but adjacent to green class 3. Update to use new structures. * print-rtl.c (print_rtx): Handle NOTE_INSN_BASIC_BLOCK. * reg-stack.c (BLOCK_NUM): Convert to function. Abort if block_number is -1. (reg_to_stack): Initialize block_num to -1. * combine.c (set_nonzero_bits_and_sign_copies): Update reference to basic_block_live_at_start to bb->global_live_at_start. (try_combine): Likewise. (reg_dead_at_p): Likewise. * global.c (global_conflicts): Likewise. Handle stack regs on all abnormal edges, not just computed jumps. (mark_elimination): Update reference to basic_block_live_at_start. (build_insn_chain): Likewise. * haifa-sched.c (haifa_edge): Rename from edge for conflict. (is_cfg_nonregular): Look at nonlocal_goto_handler_labels instead of nonlocal_label_rtx_list. (check_live_1): Update reference to basic_block_live_at_start. (update_live_1): Likewise. (find_pre_sched_live): Likewise. (find_post_sched_live): Likewise. * local-alloc.c (update_equiv_regs): Likewise. (block_alloc): Likewise. * reload1.c (reload, reload_combine): Likewise. * regmove.c (mark_flags_life_zones): Likewise. * resource.c (mark_target_live_regs): Likewise. * sched.c (schedule_block): Likewise. * regclass.c (regset_release_memory): Don't free basic_block_live_at_start. * unroll.c (copy_loop_body): Don't duplicate NOTE_INSN_BASIC_BLOCK. Thu Feb 25 21:32:34 1999 Jason Merrill * fixinc.wrap: Also handle struct queue in sys/stream.h. * fixinc.svr4: Likewise. * dwarf2out.c (scope_die_for): Set scope_die to comp_unit_die rather than asserting it. Thu Feb 25 23:33:06 1999 Kaveh R. Ghazi * cppexp.c (left_shift, right_shift, parse_charconst, COMPARE, cpp_parse_expr): Replace uses of long/HOST_BITS_PER_LONG with HOST_WIDEST_INT/HOST_BITS_PER_WIDEST_INT. * Makefile.in (cppmain.o, cpplib.o, cpphash.o, cppalloc.o, cpperror.o, cppexp.o, cppfiles.o, cppinit.o, fix-header.o, scan-decls.o): Don't depend on machmode.h. * cppexp.c: Don't define CHAR_BIT or HOST_BITS_PER_WIDE_INT anymore. Replace all instances of HOST_WIDE_INT with HOST_WIDEST_INT. * cppfiles.c: Likewise. * cpplib.c: Likewise. * cpplib.h: Likewise. Also don't include machmode.h anymore. Thu Feb 25 18:46:26 1999 Richard Henderson * gcc.c (default_compilers): Define __FAST_MATH__ when appropriate. * objc/lang-specs.h: Likewise. Thu Feb 25 16:19:43 1999 Jeffrey A Law (law@cygnus.com) * pa.md (call patterns): Lose unused argument to output_call. * print-rtl.c (print_rtl): Print /j and /c for the jump/call flags. 1999-02-25 Zack Weinberg * cpphash.c (install): Rename to cpp_install, add cpp_reader* first argument. All callers changed. (hashtab): Removed. (cpp_lookup, cpp_install): Change all refs to hashtab to pfile->hashtab. (cpp_hash_cleanup): Removed. * cpphash.h: Adjust prototypes. * cpplib.h (struct cpp_reader): Add hashtab pointer. * cppinit.c (cpp_reader_init): Also allocate space for the hashtab. (cpp_cleanup): Delete all macros and free the hashtab. Thu Feb 25 21:52:54 1999 J"orn Rennecke * sh.h (PASS_IN_REG_P): For TARGET_HITACHI, don't pass structures in registers. * expr.h (PRETEND_OUTGOING_VARARGS_NAMED): Provide default definition. * function.c (assign_parms): Honour PRETEND_OUTGOING_VARARGS_NAMED. * calls.c (expand_call): Likewise. * sh.c (sh_expand_prologue): For TARGET_HITACHI, don't push varargs / stdarg arguments. * sh.h (CPP_SPEC): Add -D__HITACHI__ for -mhitachi. (FUNCTION_ARG): For TARGET_HITACHI, don't pass unnamed arguments in registers. (PRETEND_OUTGOING_VARARGS_NAMED): Define. * va-sh.h (entire file): If __HITACHI__ is defined, use sh[123] flavor varargs. Thu Feb 25 14:32:40 1999 Kaveh R. Ghazi * cse.c (dump_class): Revert last change and make the prototype extern. Thu Feb 25 19:13:42 1999 J"orn Rennecke * rtl.h (insn_first_p): Don't declare. * rtlanal.c (insn_first_p): Delete. * loop.c (loop_insn_first_p): Faster implementation. Thu Feb 25 10:44:35 1999 Richard Earnshaw (rearnsha@arm.com) * arm.h (TARGET_SWITCHES): Delete deprecated switches -m[236]. (TARGET_3, TARGET_6): Delete. (ARM_FLAG_ARM[36]): Delete. (CPP_CPU_ARCH_SPEC): No need to handle -m[236] any more. (CC1_SPEC): Don't expand -m[236] into new equivalents. (CPP_APCS_PC_SPEC): No need to handle -m[236] any more. * arm.c (arm_override_options): Delete warnings about deprecated options -m[236]. * arm.c (arm_finalize_pic): Build the label into the special pic adjustment insn instead of issuing it separately. * arm.md (pic_add_dot_plus_eight): Rework to contain the label that is needed. * arm.md (*zeroextractqi_compare0_scratch): Delete. (*ne_zeroextractsi): New pattern. Thu Feb 25 18:40:06 1999 J"orn Rennecke * stmt.c (expand_end_loop): Grok code emitted by expand_exit_loop_if_false. Thu Feb 25 10:17:32 1999 Nick Clifton * config/arm/arm.c (return_in_memory): Float fields in unions force a return in memory. (load_multiple_sequence): Add comment explaining why two LDR instructions can be better than an LDMIA instruction. * config/arm/arm.h (TARGET_SHORT_BY_BYTES): Add comment describing the real meaning of this option. (FIXED_REGISTERS): Default r10 to not-fixed. (CALL_USED_REGISTERS): Default r10 to not-call-used. (SUBTARGET_CONDITIONAL_REGISTER_USAGE): If not defined, define as empty. (CONDITIONAL_REGISTER_USAGE): Fix r10 if TARGET_APCS_STACK is true. Invoke SUBTARGET_CONDITIONAL_REGISTER_USAGE after performing other checks. * config/arm/arm.md (zero_extendhisi2): Undo previous change. (extendhisi2): Undo previous change. Also add comments describing why TARGET_SHORT_BY_BYTES can be ignored for armv4(t) architectures. * config/arm/riscix.h (SUBTARGET_CONDITIONAL_REGISTER_USAGE): Define to fix r10. * config/arm/riscix1-1.h (SUBTARGET_CONDITIONAL_REGISTER_USAGE): Define to fix r10. Thu Feb 25 12:09:04 1999 Kaveh R. Ghazi * cse.c (dump_class): Make the function definition static to match the prototype. Wed Feb 24 17:47:28 1999 Jim Wilson * dbxout.c (gstab.h): Use if CROSS_COMPILE. * dwarf2out.c (add_location_or_const_value_attribute): Add big endian correction for parms passed in regs but living on the stack. Wed Feb 24 14:03:54 1999 Jeffrey A Law (law@cygnus.com) * calls.c (initialize_argument_information): New function extracted from expand_call. (expand_call): Use initialize_argument_information. Remove variables which are no longer used due to cleanups. * calls.c (compute_argument_block_size): New function, extracted from expand_calls. (expand_calls): Use compute_argument_block_size. Delete original_args_size, use unadjusted_args_size instead. * calls.c (precompute_arguments): New function, extracted from expand_call. (expand_call): Use precompute_arguments. * calls.c (finalize_must_preallocate): New function, extracted from expand_call. (expand_call): Use finalize_must_preallocate. * calls.c (store_one_arg): Mark "variable_size" as possibly unused. * regclass.c (record_reg_classes, case 'p'): Set classes appropriately. An alternative always fails if it needs a pseudo and no suitable register class can be found. Wed Feb 24 19:47:56 1999 J"orn Rennecke * loop.h (loop_insn_first_p): Declare. * loop.c (loop_insn_first_p): No longer static. * unroll.c (iteration_info): Fix comparison to reg_iv_type->num_elements. Before accessing reg_biv_class, check index against max_reg_before_loop. Fix and enable code for giv iterators. (loop_iterations): Compare with reg_iv_type->num_elements instead of with max_reg_before_loop. Wed Feb 24 19:17:11 1999 J"orn Rennecke * unroll.c (unroll_loop): Avoid out-of-bounds index for local_regno. Wed Feb 24 11:26:41 1999 Vladimir N. Makarov * config/sparc/sparc.h (CONDITIONAL_REGISTER_USAGE): Don't use PIC_OFFSET_TABLE_REGNUM for register allocation when -fPIC. Tue Feb 23 16:24:19 1999 Marc Lehmann * config/i386/i386.md: Fix typo. Mon Feb 22 19:36:33 1999 Andrew Cagney * config/mips/mips.c (mips_debugger_offset): When TARGET_MIPS16 && frame_pointer_needed adjust frame size. (function_prologue): Don't MIPS16 .mask GPOFFSET. Already adjusted in .frame pseudo-op. Frm Jim Wilson : * mips.c (function_prologue): Adjust frame size in .frame pseudo-op when TARGET_MIPS16 && frame_pointer_needed. 1999-02-22 Nick Clifton * config/arm/arm.h: Add TARGET_CPU_strongarm1100. Add -mno-sched command line switch to disable scheduling of instructions into the function's prologue. (enum processor_type): Remove. (TARGET_OPTIONS): Add "fpe=" option to match documentation. (struct arm_cpu_select): Replace 'set_tune_p' and 'set_arch_p' fields with 'processors' field. (CONDITIONAL_REGISTER_USAGE): Allow r10 to be used if stack checking is not enabled. (RETURN_IN_MEMORY): Always call arm_return_in_memory. * config/arm/arm.c (arm_cpu): Remove. (tune_flags): Remove. (arm_is_strong): New variable: true iff the target processor is a StrongARM. (arm_is_6_or_7): New variable: true iff the target processor is an ARM6 or and ARM7. (arm_select): Fields reorganised. (struct processors): processor_type field removed. (all_procs): Remove. (all_cores): New array: Definitions of all known ARM cpu cores. (all_architectures): New array: Definitions of all known ARM architectures. (streq): New macro. (FL_SCHED): New processor flag: processor required load scheduling. (FL_STRONG): New processor flag: processor is a StrongARM. (arm_override_options): Reorganized to make code clearer. (use_return_insn): Test for "not (TARGET_APCS and frame_pointer_needed)". (arm_return_in_memory): Improve handling of structures. * config/arm/arm.md: Remove "cpu" attribute. Replace with "is_strongarm" and "is_arm_6_or_7" attributes. (zero_extendhisi2): Check for TARGET_SHORT_BY_BYTES before arm_arch4. (extendhisi2): Check for TARGET_SHORT_BY_BYTES before arm_arch4. * invoke.texi (ARM Options): Document -mtune= and -mfp= options. 1999-02-22 Philip Blundell * config/arm/linux-gas.h (INITIALIZE_TRAMPOLINE): Replace default definition with one including cache synchronization. (CLEAR_INSN_CACHE): Correct syscall number and enable definition. Move definition of inhibit_libc to... * config/arm/xm-linux.h: ... here. * config/arm/t-linux: Disable multilib configurations since the only effect for most people is to cause builds to fail. * config/arm/elf.h (ASM_FILE_START): Add .file directive. (ASM_SPEC): Translate -mapcs-float to -mfloat for the assembler. * config/arm/linux-elf.h (DEFAULT_VTABLE_THUNKS): Define. (HANDLE_SYSV_PRAGMA): Likewise. (LIB_SPEC): Copy definition from generic Linux files. (LIBGCC_SPEC): Include -lfloat if -msoft-float was given. (FP_DEFAULT): Set to SOFT3 on 32-bit targets. (DWARF2_DEBUGGING_INFO): Define. (PREFERRED_DEBUGGING_TYPE): Define as DBX_DEBUG. Mon Feb 22 16:54:18 1999 Andrew MacLeod * loop.c (libcall_other_regs): Make extern. * rtl.h (find_last_value): Add parameter to prototype. (libcall_other_reg): Add extern declaration. * rtlanal.c (find_last_value): Add another parameter to allow a definition using a hardware register to be found as well. Mon Feb 22 13:33:47 1999 Mark Mitchell * cse.c (dump_class): New function. (invalidate_memory): Fix typo in comment. * function.c (temp_slot): Add an alias set field. (assign_stack_temp): Only reuse slots if they will have the same alias set as before. (combine_temp_slots): Don't combine if -fstrict-aliasing; that's unsafe. * rtl.c (copy_rtx): Copy all the flags (in particular, MEM_SCALAR_P). Mon Feb 22 14:13:23 1999 Vladimir N. Makarov * configure.in (i[34567]86-*-linux-gnu*, i[34567]86-*-linux-gnulibc1, i[34567]86-*-linux-gnuaout*, i[34567]86-*-linux-gnuoldld*): Use fixinc.x86-linux-gnu as fixincludes. * configure: Rebuilt. * fixinc.x86-linux-gnu: New script for fixing asm-statements bug on x86 linux. * fixinc/fixinc.x86-linux-gnu: Copy of the previous one. * fixinc/mkfixinc.sh (i[34567]86-*-linux-gnu*, i[34567]86-*-linux-gnulibc1, i[34567]86-*-linux-gnuaout*, i[34567]86-*-linux-gnuoldld*): Use fixinc.x86-linux-gnu as fixincludes. Mon Feb 22 08:55:05 1999 Ovidiu Predescu * objc/objc-act.c (encode_type): Temporary revert to the old behavior of encoding types as the new one seems to break the encoding of bitfields. Mon Feb 22 11:40:44 1999 Craig Burley Sat Feb 20 09:59:36 1999 Craig Burley * Makefile.in (all.internal, all.cross): Depend on `doc' target, to ensure docs get made before installation. Decrease spurious warnings from -fsyntax-only: * stmt.c (expand_expr_stmt): Expand expr even when -fsyntax-only. Mon Feb 22 10:55:00 1999 Gavin Romig-Koch * c-lex.c (yylex): Replace warning about integer constants being larger than long-longs, with a warning about integer constants being larger than the largest target integer. Mon Feb 22 08:35:38 1999 Craig Burley Fix -fsyntax-only ICEs: * varasm.c (assemble_zeros, assemble_variable, output_constant_def): Do nothing when -fsyntax-only. Fri Feb 19 18:18:56 1999 Don Bowman * configure.in (mips*-*-vxworks*): Enable gthreads vxworks support. * configure: Rebuilt. Sun Feb 21 20:34:44 1999 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. Sun Feb 21 20:35:10 1999 Jeffrey A Law (law@cygnus.com) * config/aoutos.h (ASM_OUTPUT_CONSTRUCTOR): Delete. (ASM_OUTPUT_DESTRUCTOR, ASM_OUTPUT_GC_ENTRY): Likewise. * tm.texi: Update docs for constructors and destructors. Sun Feb 21 17:11:18 1999 Richard Henderson * genattrtab.c (check_attr_value): Allow negative const_int if negative_ok. Accept integral arithmetic operators. Accept direct references to other attributes. Accept symbol_ref in non-constant attributes. (max_attr_value): Add new argument `unknownp'. Update all callers. (or_attr_value): Likewise. (simplify_knowing): Don't optimize if max_attr_value unknown. (write_length_unit_log): Likewise with or_attr_value. (find_and_mark_used_attributes): Don't fallthru case. (write_attr_set): Pass thru all non-cond expressions. (write_attr_value): Handle symbol_ref, attr, and arithmetic. Sun Feb 21 13:16:44 1999 Michael Hayes * regmove.c (discover_flags_reg): Use word_mode instead of SImode. Sun Feb 21 13:15:40 1999 Richard Henderson * regmove.c (discover_flags_reg): Remove cc0 code. (mark_flags_life_zones) [HAVE_cc0]: Force use of cc0; bail if a potential flags register was identified. Sat Feb 20 16:16:07 1998 Franz Sirl * rs6000.md (scc plus ltu): Fix typo in last change. Sat Feb 20 09:08:44 1999 Richard Earnshaw (rearnsha@arm.com) * xm-arm.h (HOST_BITS_PER_LONGLONG): Define. Fri Feb 19 23:02:02 1999 Richard Henderson * regmove.c (discover_flags_reg): New function. (flags_set_1, mark_flags_life_zones): New functions. (regmove_optimize): Call them. (fixup_match_1): Use insn modes rather than sets_cc0_p. Fri Feb 19 22:47:01 1999 J"orn Rennecke * rtlanal.c (insn_first_p): Fix return value for insn == reference. * loop.c (strength_reduce, check_final_value, check_dbra_loop): Use loop_insn_first_p. Fri Feb 19 15:49:26 1999 Michael Meissner David Edelsohn * rs6000.md (scc plus eq): Fix output template. (scc plus ltu): Fix output template and collapse variants correcting early clobbers. (scc plus geu): Fix output template. (scc plus gt): Fix output template. (scc plus gtu): Fix output template and collapse variants. Fri Feb 19 15:43:59 1999 Kaveh R. Ghazi * cppinit.c (print_help): Remove unescaped newline in string. Fri Feb 19 19:55:06 1999 J"orn Rennecke * loop.c (strength_reduce): Check for intervening jumps when converting biv increment to giv. Thu Feb 18 16:36:58 1999 Per Bothner * tree.def (TRY_FINALLY_EXPR, GOTO_SUBROUTINE_EXPR): New tree nodes, * expr.c (expand_expr): Support new tree nodes. Fri Feb 19 10:17:56 1999 Andreas Schwab * config/m68k/m68k.c (m68k_align_loops_string, m68k_align_jumps_string, m68k_align_funcs_string): Add const. * config/m68k/m68k.h (m68k_align_loops_string, m68k_align_jumps_string, m68k_align_funcs_string): Likewise. Thu Feb 18 23:28:35 1999 Kaveh R. Ghazi * bitmap.c (bitmap_print): Qualify a char* with the `const' keyword. * bitmap.h (bitmap_print): Likewise. * c-decl.c (builtin_function, grokdeclarator, grokfield): Likewise. * c-lang.c (build_objc_string): Likewise. * c-lex.c (yyerror, extend_token_buffer): Likewise. Don't include limits.h or ctype.h. Remove unused variable `p'. * c-lex.h (yyerror): Qualify a char* with the `const' keyword. * c-pragma.c (handle_pragma_token): Likewise. * c-pragma.h (handle_pragma_token): Likewise. * c-tree.h (build_objc_string, builtin_function, grokfield, build_indirect_ref, lvalue_or_else, readonly_warning, error_init, pedwarn_init): Likewise. * c-typeck.c (convert_for_assignment, warn_for_assignment, push_string, warning_init, incomplete_type_error, build_indirect_ref, lvalue_or_else, readonly_warning, build_c_cast, spelling, push_member_name, print_spelling, error_init, pedwarn_init, start_init): Likewise. * objc/objc-act.c (build_objc_string): Likewise. * print-tree.c (print_node_brief, print_node): Likewise. * tree.h (lvalue_or_else, print_node, print_node_brief): Likewise. Thu Feb 18 20:44:21 1999 David Edelsohn * regclass.c (record_reg_classes): Correctly handle 'p' constraint. Thu Feb 18 19:59:37 1999 Marc Espie * configure.in :Handle OpenBSD platforms. * configure: Rebuilt. * config/openbsd.h: New file. * config/xm-openbsd.h: New file. * config/t-openbsd: New file. * config/t-openbsd-thread: New file. Thu Feb 18 18:47:09 1999 Jeffrey A Law (law@cygnus.com) * function.c (assign_stack_temp_for_type): Round SIZE before calling assign_stack_local for BLKmode slots. Fri Feb 19 01:45:06 1999 J"orn Rennecke * loop.c (strength_reduce): For derived givs, replace the giv this was derived from with its new_reg. (recombine_givs): Don't set new_reg for derived giv. And don't print it, print SUM instead. Thu Feb 18 15:52:49 1999 Jim Wilson * m68kelf.h (ASM_RETURN_CASE_JUMP): Add 5200 support. 1999-02-18 Zack Weinberg * cpplib.c: Kill define of STDC_VALUE. Don't include output.h or prefix.h. Change CPP_IS_MACRO_BUFFER to not refer to macro_cleanup. (GET_ENV_PATH_LIST, PATH_SEPARATOR, STANDARD_INCLUDE_DIR, predefs, SIZE_TYPE, PTRDIFF_TYPE, WCHAR_TYPE, CPP_WCHAR_TYPE, USER_LABEL_PREFIX, REGISTER_PREFIX, struct cpp_pending, version_string, struct default_include, include_defaults_array, path_include, cpp_options_init, dump_special_to_buffer, initialize_builtins, cpp_start_read, cpp_reader_init, nreverse_pending, push_pending, print_help, cpp_handle_option, cpp_handle_options, cpp_finish, cpp_cleanup): Move to cppinit.c. (macro_cleanup, struct arglist, collect_expansion, create_definition, compare_defs, comp_def_part, ARG_BASE, struct argdata, macarg, change_newlines, timestamp, monthnames, special_symbol, unsafe_chars, macroexpand, push_macro_expansion): Move to cpphash.c. (quote_string, check_macro_name, cpp_expand_to_buffer, output_line_command, cpp_undef): Export. (null_underflow, null_cleanup, handle_directive): Make static. * cpplib.h: Prototype now-exported functions. Adjust decls of syntax tables so we can include cpplib.h in cppinit.c. * cpphash.h: Prototype all functions exported by cpphash.c. * cppinit.c: Make syntax tables initialized data if possible (uses GCC designated-initializer extension). * cppexp.c: Make cpp_lex static. * Makefile.in: Move -D switches for the various include dirs from cpplib.o rule to cppinit.o rule. Adjust dependencies. Thu Feb 18 13:15:56 1999 Marc Espie * alpha/openbsd.h: New file. * alpha/xm-openbsd.h: New file. * sparc/openbsd.h: New file. * sparc/xm-openbsd.h: New file. * m68k/openbsd.h: New file. * m68k/xm-openbsd.h: New file. * i386/openbsd.h: New file, originally from netbsd. * i386/xm-openbsd.h: New file. 1999-02-17 Zack Weinberg * Makefile.in: Correct dependencies for cpplib object files. Wed Feb 17 14:04:18 1999 Michael Meissner * rs6000.md ({add,sub}si3 `.'): Add alternatives to use CR other than cr0. Wed Feb 17 16:59:28 1999 J"orn Rennecke * loop.c (strength_reduce): Don't move giv insn for biv turned giv below scan_start. Wed Feb 17 10:56:24 1999 Kaveh R. Ghazi * tree.c (tree_node_kind_names, print_obstack_name, get_identifier, maybe_get_identifier, build_string, build_expr_wfl, is_attribute_p, lookup_attribute, print_obstack_statistics, get_file_function_name_long, tree_check, tree_class_check, expr_check): Qualify a char* with the `const' keyword. * tree.h (get_identifier, maybe_get_identifier, build_string, build_expr_wfl, is_attribute_p, lookup_attribute, print_obstack_statistics, print_obstack_name, tree_check, tree_class_check, expr_check): Likewise. Tue Feb 16 21:29:38 1999 Jeffrey A Law (law@cygnus.com) * i386/freebsd-elf.h, i386/gas.h, i386/linux.h: Fix minor spacing errors. * calls.c (store_one_arg): Mark any slots used for the argument as in-use immediately after we're done saving any slots which will be overwritten by this argument. Tue Feb 16 21:02:07 1999 Anton Hartl * rs6000.md (call_value): Fix typo. Wed Feb 17 01:29:07 1999 J"orn Rennecke * loop.c (strength_reduce): Calculate maybe_dead before calling recombine_givs. Wed Feb 17 00:43:12 1999 J"orn Rennecke * loop.c (strength_reduce): Dump biv increment -> giv conversions. Tue Feb 16 15:31:39 1999 Ovidiu Predescu * objc/objc-act.c (encode_type): Encode the type instead of encoding the mode of the type (patch from Richard Frith-Macdonald ). Tue Feb 16 10:53:51 1999 Richard Earnshaw (rearnsha@arm.com) * config/arm/arm.md (*zeroextractqi_compare0_scratch): Re-add load instruction killed in previous change. Simplify mask generation. (*zeroextractsi_compare0_scratch): Simplify mask generation. Tue Feb 16 09:52:26 1999 Nick Clifton * config/arm/arm.md (zeroextractqi_compare0_scratch): Ensure that bitfield does not overflow a byte boundary. Tue Feb 16 01:37:33 1999 Charles G Waldman * c-common.c (shorten_compare): Get the min/max value from the underlying type of an enumeration, not the enumerated type itself. Mon Feb 15 23:04:48 1999 Jeffrey A Law (law@cygnus.com) * jump.c: Include insn-attr.h. (delete_computation): If reload has completed and insn scheduling after reload is enabled, then do not depend on REG_DEAD notes. * Makefile.in (jump.o): Depend on insn-attr.h. Mon Feb 15 16:57:38 1999 Richard Henderson * i386.md (addsi3): Allow lea for any constant_p. 1999-02-15 Zack Weinberg * toplev.c (documented_lang_options): Remove -fident and -fnoident, which are now handled by the language independent option parser. 1999-02-15 Zack Weinberg * c-common.c (UNGETC [USE_CPPLIB=1]): Do nothing if c is EOF. * c-lex.c: Likewise. * cpplib.c (cpp_push_buffer, cpp_pop_buffer): Use a linked list in malloced memory for the buffer stack. (cpp_get_token): Don't pop the last buffer off the stack. Calls after CPP_EOF has been returned produce CPP_EOF with no state change. (cpp_finish): Pop last buffer here. (do_line): Don't free ip->last_nominal_fname if it is equal to ip->fname. (special_symbol): If a T_CONST is the empty string, push a single `@ ' escape instead. (macroexpand): Special symbol buffers have escapes too. * cpplib.h (struct cpp_buffer): Remove unused fields, add prev buffer pointer. (struct cpp_reader): Remove buffer_stack. Add buffer_stack_depth. (CPP_PREV_BUFFER, CPP_NULL_BUFFER): Buffer stack is now a linked list. Mon Feb 15 14:44:53 1999 Kaveh R. Ghazi * cccp.c: Don't define HOST_WIDE_INT. Replace all occurrences of WIDE_INT with WIDEST_INT. * cexp.y: Likewise. Don't define unsigned_HOST_WIDE_INT, CHAR_BIT or HOST_BITS_PER_WIDE_INT. Replace occurrences of PRINTF_PROTO_1() style with PVPROTO() ATTRIBUTE_PRINTF_1 style macros. Replace occurrences of "unsigned_HOST" with "unsigned HOST". Provide a definition of variable `c89' when compiling a test binary and set it. * system.h: Don't define the PRINTF_PROTO_* macros. Mon Feb 15 11:33:51 1999 Jeffrey A Law (law@cygnus.com) * loop.c (mark_loop_jump): Handle LO_SUM. If we encounter something we do not understand, mark the loop and containing loops as invalid. Mon Feb 15 00:40:45 1999 J"orn Rennecke * alias.c (init_alias_analysis): Avoid self-referential value when setting reg_known_value from REG_EQUAL notes. Sun Feb 14 23:12:10 1999 Richard Henderson * i386.c (legitimate_address_p): Verify modes of base and index. Sun Feb 14 23:01:28 1999 Richard Henderson * i386.c (legitimate_pic_address_disp_p): Remove static. * i386.h (LEGITIMATE_PIC_OPERAND_P): Use it instead of open-coding cases. Sun Feb 14 21:03:28 1999 Jeffrey A Law (law@cygnus.com) * except.c (start_catch_handler): Use emit_cmp_and_jump_insns. * explow.c (probe_stack_range): Likewise. * expmed.c (do_cmp_and_jump): Likewise. * expr.c (store_expr, expand_expr, expand_builtin): Likewise. (do_tablejump): Likewise. * stmt.c (expand_expr_stmt, expand_end_case): Likewise. (do_jump_if_equal, emit_case_nodes): Likewise. * optabs.c (emit_cmp_and_jump_insns): Clarify comments. If UNSIGNEDP, then convert comparison to an unsigned code before emitting the jump. (expand_float, expand_fix): Use emit_cmp_and_jump_insns. Sun Feb 14 02:24:15 1999 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. Sun Feb 14 01:15:04 1999 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. Sun Feb 14 00:45:50 1999 Jeffrey A Law (law@cygnus.com) * loop.c: Disable recent loop changes. Temporary as Joern continues to fix problems. Sat Feb 13 23:29:42 1999 Richard Henderson * loop.c (combine_givs_used_by_other): Delete. (combine_givs_benefit_from): Delete. (combine_givs): Deny combination of givs only used once. Simplify code with the death of combine_givs_benefit_from. Sun Feb 14 11:24:05 1999 Michael Hayes * loop.c (scan_loop): Call reg_in_basic_block_p before loop_reg_used_before_p. Sat Feb 13 05:32:00 1999 Richard Earnshaw (rearnsha@arm.com) * arm.md: Use gen_rtx_FOO instead of gen_rtx (FOO, ...). * arm.h: Likewise. * arm.c: Likewise. * arm.h (TARGET_OPTIONS): Reformat for clarity. (GO_IF_LEGITIMATE_ADDRESS): When generating PIC, references to symbols in the constant pool aren't valid. (LEGITIMATE_PIC_OPERAND_P): Likewise. * arm.c: Include "system.h", not stdio.h and string.h. Fri Feb 12 13:06:28 1999 Jim Wilson * stmt.c (expand_return): Return if optimize_tail_recursion succeeded. (optimize_tail_recursion): Change return type from void to int. Add return statements. * tree.h (optimize_tail_recursion): Change prototype to match. Fri Feb 12 21:09:51 1999 J"orn Rennecke * reload.c (find_reloads_subreg_address): New function, broken out of find_reloads_toplev. (find_reloads_toplev, find_reloads_address_1): Use it. Fri Feb 12 13:20:52 1999 Jeffrey A Law (law@cygnus.com) * h8300.md (zero_extendhisi2 H8/300 variant): Correctly handle extending a CONST_INT. * h8300.md (peephole for combining memrefs): Delete incorrect peephole. Fri Feb 12 18:29:11 1999 J"orn Rennecke * loop.c (loop_insn_first_p, biv_elimination_giv_has_0_offset): New functions. (maybe_eliminate_biv_1): Use biv_elimination_giv_has_0_offset. Fri Feb 12 16:56:10 1999 J"orn Rennecke * loop.c (load_mems): Don't guess how to do a load / store, use emit_move_insn. Fri Feb 12 09:24:26 1999 Kaveh R. Ghazi * system.h: Provide a definition for HOST_WIDEST_INT, etc. Fri Feb 12 23:37:26 1999 Michael Hayes * config/c4x/c4x.c (c4x_address_cost): Revert 9 Feb change. Fri Feb 12 00:51:26 1999 Jeffrey A Law (law@cygnus.com) * reload.c (find_reloads_address_1): Fix handling of an autoincremented pseudo which is homed in the stack. * mips.c (save_restore_insns): Fix loop to save/restore FP registers. (compute_frame_size): Change loop over FP regs to be consistent with the loop in save_restore_insns. Thu Feb 11 17:38:40 1999 Jim Wilson * i960/i960.h (OVERRIDE_OPTIONS): Warn if -mlong-double-64 is used. (LONG_DOUBLE_TYPE_SIZE): Undef then unconditionally define to 96. Thu Feb 11 15:11:35 1999 Jeffrey A Law (law@cygnus.com) * mn10200.md (bset); Re-enable. Thu Feb 11 15:20:49 1999 J"orn Rennecke * sh.md (is_sfunc): New attribute. * sh.h (INSN_SETS_ARE_DELAYED, INSN_REFERENCES_ARE_DELAYED): Use it. Thu Feb 11 01:06:49 1999 Nathan Sidwell * fold-const.c (range_binop): Take account of the bounded nature of fixed length arithmetic when comparing unbounded ranges. Thu Feb 11 00:08:17 1999 John Wehle (john@feith.com) * function.c (assign_stack_temp_for_type): Clear best_p when an exact match is found. * i386.h (LOCAL_ALIGNMENT): Define. * function.c (assign_stack_local, assign_outer_stack_local): Use it. (assign_stack_temp_for_type): New function based on assign_stack_temp. (assign_stack_temp): Call it. (assign_temp): Use assign_stack_temp_for_type, not assign_stack_temp. * stmt.c: Use assign_temp, not assign_stack_temp. * tm.texi: Document LOCAL_ALIGNMENT. Wed Feb 10 23:28:28 1999 Jeffrey A Law (law@cygnus.com) * reorg.c: Finish deleting half-deleted comment. Wed Feb 10 17:12:21 1999 Jim Wilson * emit-rtl.c (operand_subword): Sign extend REAL_VALUE_TO_TARGET_SINGLE result. * final.c (split_double): Sign extend REAL_VALUE_TO_TARGET_DOUBLE result. * real.c (endian): Delete sign extension code. * config/m32r/m32r.md (movsf_insn+1): REAL_VALUE_TO_TARGET_SINGLE call replaced with operand_subword call. Wed Feb 10 15:16:39 1999 Richard Henderson * alpha.md (cmov compound patterns): Delete. Jump can now create the correct constructs in the first place. Wed Feb 10 11:03:22 1999 Richard Henderson * configure.in (alphaev6*): Fix typo in target_cpu_default2. Wed Feb 10 13:59:18 1999 Dave Brolley * mbchar.c (local_mb_cur_max): Handle the case where MB_CUR_MAX is 0. Wed Feb 10 10:35:05 1999 Jim Wilson * tmp-emsgids.c: Delete. Wed Feb 10 09:57:08 1999 Mark Mitchell * rtlanal.c (for_each_rtx): Fix declaration to conform to GNU coding standards. Wed Feb 10 10:09:41 1999 Jeffrey A Law (law@cygnus.com) * mn10200.md (bset, bclr): Operand 0 is a read/write operand. * reload1.c (reload_combine_note_store): Second argument is no longer unused/ignored. Handle multi-register hard regs. (move2add_note_store): Simplify. Wed Feb 10 10:05:23 1999 Mumit Khan * collect2.c (collect_execute): Remove cygwin-specific code. Tue Feb 9 17:27:29 1999 Nathan Sidwell * system.h (_, N_): Remove dummy i18n macros. * protoize.c: Move inclusion of intl.h to after system.h. * cexp.y: Include intl.h. * cexp.c: Rebuilt. Tue Feb 9 16:52:22 1999 Mumit Khan * i386/cygwin.h (SUBTARGET_OVERRIDE_OPTIONS): New macro to ignore fpic/fPIC for windows32 targets. * i386/xm-cygwin.h (GET_ENV_PATH_LIST): Replace '\\' in windows32 paths with '/'. * i386/mingw32.h (CPP_SPEC): Define. (CPP_PREDEFINES): Add MINGW32 version id. * i386/crtdll.h (CPP_PREDEFINES): Likewise. * Makefile.in (collect2$(exeext)): Delete redundant dependency and add missing exeext to target. * gcc.c (convert_filename): Handle null filename argument. Wed Feb 10 15:46:10 1999 Michael Hayes * config/c4x/c4x.md (*movhf_noclobber, *movhi_noclobber): Use m constraint instead of QT. 1999-02-09 Brendan Kehoe * cpplib.c (special_symbol): Move IP to be declared in function scope, rather than individual case statements. 1999-02-09 Zack Weinberg * cppfiles.c (finclude): Handle pipes properly under old BSD derivatives. 1999-02-09 Melissa O'Neill * system.h: Provide fallback definitions for S_ISCHR, S_ISSOCK, S_ISFIFO, O_NONBLOCK, and O_NOCTTY. 1999-02-09 Zack Weinberg * cpplib.c (do_define): Allow redefining __STDC__ with -D. 1999-02-09 Jim Blandy * configure.in: For PowerPC configurations, accept "401", "ec603e", "740", and "750" as valid arguments to --with-cpu. * configure: Rebuilt. Tue Feb 9 00:00:14 1999 Mark Kettenis * configure.in (i[34567]86-*gnu*): Set float_format to i386. * configure: Rebuilt. Mon Feb 8 22:38:24 1999 Jeffrey A Law (law@cygnus.com) * rs6000.md: Revert "alternate use of crs if cr0 not available" patches from 01-22-1999, 01-24-1999, 01-26-1999, and 02-08-1999. Mon Feb 8 21:36:44 1999 Richard Henderson * output.h (current_function_has_computed_jump): Rename from current_function_addresses_labels. * function.h (struct function): Likewise for addresses_labels member. * rtl.h (FUNCTION_FLAGS_HAS_COMPUTED_JUMP): Likewise. * function.c (current_function_has_computed_jump): Likewise. Update all references. * integrate.c (function_cannot_inline_p): Test current_function_has_computed_jump instead of addresses_labels. (initialize_for_inline): Likewise save. (output_inline_function): Likewise restore. * expr.c (expand_expr): Don't reference addresses_labels variables. * stmt.c (expand_computed_goto): Set has_computed_jump. 1999-02-08 Michael Meissner This is being installed only to get it into the repository to help with the revert, resubmit & review process for the massive rs6000.md changes. * rs6000.md (andsi3_internal1 splitter): Don't split if using the rlwinm instruction. (anddi3_internal1): Likewise. (andsi3_internal{2,3}): Correct some insn lengths. (anddi3*): Restore missing TARGET_POWERPC64, and don't emit old mnemonics. Mon Feb 8 21:31:06 1999 Richard Henderson * loop.c (reg_single_usage): New file-scope variable ... (scan_loop): ... moved out of here. Always initialize. Test loop_has_call instead of reg_single_usage not zero. Free reg_single_usage after strength reduction. (count_loop_regs_set): Assume single_usage non-zero. (combine_givs_used_by_other): Test reg_single_usage. (load_mems_and_recount_loop_regs_set): Remove reg_single_usage as a parameter. Assume non-zero. 1999-02-08 Zack Weinberg * cpplib.c (special_symbol): Rewrite. Don't copy things multiple times. Handle __STDC__ specially. T_CONST indicates a constant /string/. Don't handle T_*_TYPE and T_SPEC_DEFINED. Use cpp_buf_line_and_col instead of adjust_position. Determine the file buffer only if needed. (initialize_builtins): Handle __SIZE_TYPE__, __PTRDIFF_TYPE__, __WCHAR_TYPE__, __USER_LABEL_PREFIX__, and __REGISTER_PREFIX__ with T_CONST special hashtab entries. Don't provide __OBJC__; the driver does that. Provide __STDC_VERSION__, using T_CONST. Use T_STDC for __STDC__. Give install the length of all symbols defined. (eval_if_expression): Drop code to insert and remove the "defined" special symbol. * cpplib.h: Remove SELF_DIR_DUMMY (no longer used). Remove T_*_TYPE and T_SPEC_DEFINED from enum node_type; add T_STDC. * cpphash.c (install): Drop the `ivalue' parameter. Constify the `value' parameter. All callers changed. * cpphash.h (install): Change prototype to match. (union hashval): Remove `ival' member. * cppexp.c (cpp_lex): Handle `defined' here. Mon Feb 8 17:29:42 1999 Jeffrey A Law (law@cygnus.com) * pa.h (EXTRA_CONSTRAINT): Fix comment. Mon Feb 8 18:57:45 1999 Vladimir N. Makarov * c-typeck.c (check_init_type_bitfields): Use nonincremental initialization of unions whose first member is a bitfield. Remove unnecessary code for checking the declaration mode after DECL_C_BIT_FIELD. * varasm.c (output_constructor): Additional comment about the constructor of bitfield union initialization. Tue Feb 9 11:55:04 1999 Michael Hayes * config/c4x/c4x.md (*movhi_stik): New pattern. (movhi): Allow some immediate constants to be directly stored in memory. Tue Feb 9 11:34:15 1999 Michael Hayes * config/c4x/c4x.md (all call patterns): Add constraints "Ur". (call, call_value): Force address into a register if not valid for a call instruction. (load_immed_address): Emit a USE of the SYMBOL_REF that is forced into memory. * config/c4x/c4x.c (c4x_print_operand): Fix 'C' and 'U' modifiers. Tue Feb 9 11:08:41 1999 Michael Hayes * config/c4x/c4x.c (call_address_operand, symbolic_address_operand): Rename from call_operand and symbolic_operand respectively. All callers changed. * config/c4x/c4x.md (call_address_operand, symbolic_address_operand): Likewise. * config/c4x/c4x.h (call_address_operand, symbolic_address_operand): Likewise. (PREDICATE_CODES): Allow CONST, LABEL_REF for call_address_operand. Tue Feb 9 10:52:27 1999 Michael Hayes * config/c4x/c4x.c (c4x_legitimize_address): Don't generate a LO_SUM address for HImode or HFmode but instead force address into a register so that it is offsettable. (c4x_emit_move_sequence): Handle LO_SUM immediate address. Tue Feb 9 10:46:42 1999 Michael Hayes * config/c4x/c4x.c (c4x_address_cost): Return cost of 1 for REG+REG addressing if strength reduction enabled. Tue Feb 9 10:10:31 1999 Michael Hayes * config/c4x/t-c4x (LIBGCC2_CFLAGS): Delete. (TARGET_LIBGCC2_CFLAGS): Define. 1999-02-08 Nick Clifton * config/v850/v850.md: Replace \\n\\t with \\; * config/v850/v850.md: Enforce TARGET_LONG_CALLS option. * config/v850/v850.c (construct_restore_jr, construct_save_jarl): Enforce TARGET_LONG_CALLS option. Mon Feb 8 11:43:07 1999 Donn Terry * real.c (PUT_REAL) [XFmode]: Zero the balance of the structure. Mon Feb 8 11:37:24 1999 Marc Espie (espie@cvs.openbsd.org) * m88k/t-luna-gas: Remove bash dependency. Mon Feb 8 11:34:44 1999 Graham * collect2.c (xrealloc): Fix typo in last change. Mon Feb 8 09:13:38 1999 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. Sun Feb 7 22:18:42 1999 Robert Lipe * tree.h (TYPE_CHECK): Make it clear to the preprocessor that we do not want macro replacement within a character constant. (TYPE_CHECK1): Likewise. Sun Feb 7 15:37:10 1999 Jason Merrill * tree.h (DECL_P): New macro. Sun Feb 7 01:15:04 1999 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. Sat Feb 6 18:14:46 1999 Jeffrey A Law (law@cygnus.com) * mn10300.md (reload_insi): Do not earlyclobber the output operand. * README.g77, gcc.c, gcc.texi: Update email addresses. * invoke.texi system.h: Likewise. Sat Feb 6 11:04:08 1999 Jim Wilson * unroll.c (find_splittable_givs): After express_from, call replace_rtx to convert dest_reg to new_reg. Sat Feb 6 10:31:35 1999 Jeffrey A Law (law@cygnus.com) * reload1.c (reload_combine_note_store): Be more careful with STRICT_LOW_PART, ZERO_EXTRACT and SIGN_EXTRACT. (move2add_note_store): Likewise. Sat Feb 6 10:18:01 1999 Kaveh R. Ghazi * cppfiles.c (read_and_prescan): Cast the result of `xrealloc' to U_CHAR* when assigning to one. Ensure the values of a ?: operator have the same type. * cppinit.c (initialize_char_syntax): Use K&R function definition. Sat Feb 6 11:17:03 1999 Richard Earnshaw Support for ARM9 * config/arm/arm.c (all_procs): Add arm9 and arm9tdmi. * config/arm/arm.h ((TARGET_CPU_arm9, TARGET_CPUD_arm9tdmi): Define. (TARGET_CPU_DEFAULT): Rework to support ARM9. (CPP_CPU_ARCH_SPEC): Likewise. (enum processor_type): Likewise. * config/arm/arm.md (attr cpu): Add arm9. General scheduling changes * config/arm/arm.c (MAX_INSNS_SKIPPED): Delete. (max_insns_skipped): New variable. (arm_override_options): If generating hard floating point code for the FPA, emit code for version 3. When optimizing for space, don't synthesize constants. Reword several flags based on the requested processor and optimization level. (use_return_insn): New argument iscond, all callers changed. Don't use a return insn if it will be conditional and that would be expensive; eg on StrongARM. (arm_adjust_cost): Anti- and output- dependencies normally have no cost. (load_multiple_sequence): Newer ARMs don't benefit from ldm if the sequence is short. (final_prescan_insn): Use max_insns_skipped instead of MAX_INSNS_SKIPPED. Note whether we will make a return instruction conditional, and aviod this if it would be expensive. * config/arm/arm.md (scheduling attributes and function units): Rewrite to better describe ARM8, 9 and StrongARM. * config/arm/arm.md (*movhi_insn_littleend): Make op0 predicate s_register_operand. (*ifcompare_plus_move): Use arm_rhs_operand in place of arm_rhsm_operand. Rework constraints. (*if_plus_move): Likewise. (*ifcompare_move_plus): Likewise. (*if_move_plus): Likewise. (*ifcompre_arith_move): Likewise. (*if_arith_move): Likewise. (*ifcompare_move_arith): Likewise. (*if_move_arith): Likewise. * config/arm/xm-netbsd.h: Don't include arm/xm-arm.h. 1999-02-05 Michael Meissner * loop.c (check_dbra_loop): A store using an address giv for which we have no life information is not reversible. Fri Feb 5 17:08:01 1999 Dave Brolley * function.c (fixup_var_refs): Scan catch_clauses too. Fri Feb 5 11:49:49 1999 Benjamin Kosnik * c-common.c (decl_attributes): Fix reserved space for init_priority. * tree.h (MAX_RESERVED_INIT_PRIORITY): New macro. Fri Feb 5 12:37:05 1999 Jeffrey A Law (law@cygnus.com) * loop.c (strength_reduce): Clear not_every_iteration when passing the NOTE_INSN_LOOP_CONT note. * haifa-sched.c (add_dependence): Do not add a dependency on a note. Fri Feb 5 10:55:43 1999 Nick Clifton * recog.c (split_block_insns): Only call update_flow_info if instruction scheduling is enabled. 1999-02-05 Zack Weinberg * Makefile.in (gen-protos): Use libcpp.a like everyone else. Fri Feb 5 07:09:29 1999 J"orn Rennecke * loop.c (first_loop_store_insn): New file-scope variable. (prescan_loop): Set it. (check_dbra_loop): Check if a store depends on a register that is set after the store. Fri Feb 5 06:55:15 1999 J"orn Rennecke * unroll.c (entire file): Remove tabs / spaces at end of lines. Replace spaces with tabs where appropriate. Thu Feb 4 15:12:41 1999 J"orn Rennecke * loop.c (scan_loop): New argument loop_cont. Changed caller. (strength_reduce): New argument loop_cont. Changed caller. Before clearing not_every_iteration after a label, check if we are not already past LOOP_CONT. 1999-02-04 Zack Weinberg * cpperror.c (cpp_print_containing_files): Fix formatting bug induced by merge. 1999-02-04 Zack Weinberg * cpplib.c (initialize_char_syntax): Move to cppinit.c. (cpp_define): Remove redundant syntax checks. (make_assertion): Rename cpp_assert, remove redundant syntax checks, export. (cpp_options_init): Don't init things to zero twice. (cpp_expand_to_buffer): Use memcpy, not a char-by-char loop. (do_include): Kill excessively verbose #import warning that snuck back in in the gcc2 merge. (convert_string): Removed. (do_line): Rewrite with simple last-name-used cache instead of private hashtable. (cpp_start_read): Call initialize_char_syntax here, not... (cpp_reader_init): ...here. (cpp_handle_options): Support the -std switch. * cpplib.h (cpp_buffer): Add last_nominal_fname member. (cpp_options): Add c9x flag. Declare all the is_* tables and trigraph table here, as const. Prototype cpp_assert and initialize_char_syntax. * cppinit.c: New file. * cppfiles.c (read_and_prescan): Optimize. * Makefile.in (LIBCPP_OBJS): Add cppinit.o. Thu Feb 4 10:46:30 1999 Gavin Romig-Koch * config/mips/mips.md ([u]divmodsi4,[u]divmoddi4,[u]divsi3,[u]divdi3, [u]modsi3,[u]moddi3) : Don't copy the "zero" argument to a register before calling gen_div_trap. Wed Feb 3 21:56:27 1999 Jeffrey A Law (law@cygnus.com) * configure.in (hppa1.1-*-*, hppa2*-*): Use symbolic value rather than numeric value for target_cpu_default.. * configure: Rebuilt. Wed Feb 3 21:55:56 1999 Marc Espie * Makefile.in (xgcc$(exeext)): Remove choose-temp, pexecute and mkstemp. Get them from libiberty. (COLLECT2_OBJS): Similarly for choose-temp, cplus-dem and mkstemp. (PROTO_OBJS): Similarly for choose-temp, getopt, getopt1 and pexecute. (cplus-dem.o, pexecute.o, choose-temp.o): Remove build rules. (mkstemp.o, getopt1.o, getopt.o): Likewise. * pa-gas.h (TARGET_DEFAULT): Use symbolic values rather than numeric values. * pa-hpux.h (LINK_SPEC): Likewise. * pa-hpux10.h (LINK_SPEC): Likewise. * pa-hpux9.h (LINK_SPEC): Likewise. * pa-osf.h (LINK_SPEC): Likewise. * pa-pro.h (TARGET_DEFAULT): Likewise. * pa1.h (TARGET_DEFAULT): Likewise. * pa.h (MASK_*): New defines. (TARGET_*): Use symbolic values rather than numeric values. (TARGET_SWITCHES): Likewise. (TARGET_DEFAULT): Likewise. (CPP_SPEC): Likewise. Wed Feb 3 21:07:38 1999 Bernd Schmidt * reload1.c (reload_cse_regs_1): Undo Jan 16 patch. * reload.c (find_reusable_reload): New function, broken out of push_reload. Add code to verify that none of the involved outputs are subject to earlyclobbers. (push_reload): Break out new function find_reusable_reload. Delete "register" keyword for IN, OUT args. Wed Feb 3 15:51:04 1999 Gavin Romig-Koch * config/mips/mips.c (true_reg_or_0_operand) : New function. * config/mips/mips.h (PREDICATE_CODES): Add true_reg_or_0_operand. * config/mips/mips.md (div_trap,div_trap_normal,div_trap_mips16): Use true_reg_or_0_operand for div_trap. Wed Feb 3 20:44:59 1999 J"orn Rennecke * loop.h (express_from): Declare. (struct induction): Replace derived flag with derived_from pointer. * loop.c (strength_reduce, record_giv, recombine_givs): Likewise. (express_from): No longer static. * unroll.c (find_splittable_givs): Replace derived with derived_from. When processing an address giv with which another giv has been combined that has also been derived from a third giv, handle like having combined with the third giv. Set splittable_regs_updates appropriately for derived givs. Wed Feb 3 15:26:58 1999 Gavin Romig-Koch * config/mips/mips.md (div_trap_mips16): Remove nop's after branches. Wed Feb 3 11:56:23 1999 Jeffrey A Law (law@cygnus.com) * pa.c (insn_sets_and_refs_are_delayed): New function. * pa.h (INSN_SETS_ARE_DELAYED): Use it. (INSN_REFERENCES_ARE_DELAYED): Likewise. Wed Feb 3 06:24:49 1999 Richard Earnshaw (rearnsha@arm.com) * config/arm/t-arm-elf (LIBGCC2_CFLAGS): Delete. * config/arm/t-linux (LIBGCC2_CFLAGS): Delete. (TARGET_LIBGCC2_CFLAGS): Define. (LIBGCC2_DEBUG_CFLAGS): Define. * config/arm/t-netbsd: Likewise. * config/arm/t-semi: Likewise. * config/arm/t-semiaof: Likewise. * config/arm/t-riscix: Likewise. Wed Feb 3 10:59:07 1999 Andreas Schwab * config/m68k/m68k.c (print_operand_address): When printing a SYMBOL_REF that ends in `.' put parentheses around it. Tue Feb 2 23:38:35 1999 David O'Brien * i386/freebsd*.h now allows '$' in label names and does not use the PCC struct return method. Tue Feb 2 22:38:23 1999 Jim Wilson * Makefile.in: Change all uses of AR to AR_FOR_TARGET. Change all uses of HOST_AR to AR. Likewise for AR_FLAGS, RANLIB, and RANLIB_TEST. (RANLIB_TEST): Test to see if ranlib exists. Only test absolute file names if host == target. (HOST_AR, HOST_AR_FLAGS, HOST_RANLIB, HOST_RANLIB_TEST): Delete. (AR_FLAGS_FOR_TARGET): Renamed from AR_FOR_TARGET_FLAGS. (AR, AR_FLAGS, OLDAR, OLDAR_FLAGS, RANLIB, RANLIB_TEST): Delete rules setting them to *_FOR_TARGET. * cross-make (AR, AR_FLAGS, OLDAR, OLDAR_FLAGS, RANLIB, RANLIB_TEST): Delete. Tue Feb 2 22:38:19 1999 Theodore Papadopoulo * toplev.h (read_integral_parameter): Declare. * toplev.c (read_integral_parameter): New function. Fri Jan 29 21:00:56 1999 Bob Manson * resource.c, resource.h: New files. * Makefile.in (OBJS): Add it. * haifa-sched.c (regno_use_in): Moved to rtlanal.c. (split_block_insns): Moved to recog.c. (update_flow_info): Make public. * rtl.h: Declare them. * reorg.c: Moved the functions dealing with computing resource usage to resource.c. * sched.c (regno_use_in): Moved to rtlanal.c. (update_flow_info): Make public. (schedule_insns): Use split_block_insns. * recog.c (split_block_insns): New function. Tue Feb 2 22:03:26 1999 David Edelsohn * rs6000/linux.h (LINK_START_DEFAULT_SPEC): Delete, unused. (LINK_OS_DEFAULT_SPEC): Delete, unused. Tue Feb 2 20:29:34 1999 Catherine Moore * configure.in (arm-*-oabi): Support. * configure: Regenerate. * config/arm/unknown-elf-oabi.h: New file. Tue Feb 2 19:43:59 1999 Jeffrey A Law (law@cygnus.com) * i386.md (ashlsi3): Turn into a define_expand an anonymous pattern. Make the anonymous pattern match when ! optimize_size. (ashlsi3 size optimizer): New pattern. * intl/Makefile.in (uninstall): Add missing "; \". Tue Feb 2 18:21:23 1999 Stan Cox * sparc.h (TARGET_CPU_sparc86x): Added. TARGET_CPU_sparclite86x synonym. Tue Feb 2 20:24:11 1999 J"orn Rennecke * loop.c (loop_optimize): Fix value max_uid_for_loop is reset to after find_and_verify_loops call. Tue Feb 2 19:48:29 1999 J"orn Rennecke * (recombine_givs): Don't use a giv that's likely to be dead to derive others. * loop.c (recombine_givs): Fix test for lifetime overlaps / loop wrap around when deriving givs. Mon Feb 1 20:00:40 1999 Richard Henderson * recog.c (check_asm_operands): Treat indeterminate operand ok results as success. Try harder to resolve a matching constraint. * stmt.c (expand_asm_operands): Recognize when an output operand's constraint does not allow memory. Treat indeterminate operand ok results as failure. Try harder to resolve a matching constraint. Mon Feb 1 15:00:02 1999 Ken Raeburn Use varrays for constant-equivalence data: * varray.h (struct const_equiv_data): New type. (union varray_data_tag): New element const_equiv. (VARRAY_CONST_EQUIV_INIT, VARRAY_CONST_EQUIV): New macros. (VARRAY_SIZE): New macro, returns number of elements. * integrate.h: Include varray.h. (struct inline_remap): Replace const_equiv_map, const_age_map and const_equiv_map_size with a const_equiv_varray element. (MAYBE_EXTEND_CONST_EQUIV_VARRAY): New macro; grows varray if needed. (SET_CONST_EQUIV_DATA): New macro; sets rtx and age fields simultaneously, growing the varray if needed. * integrate.c (global_const_equiv_map, global_const_equiv_map_size): Deleted, replaced by.... (global_const_equiv_varray): New variable. (expand_inline_function): References changed. * integrate.h: Update declarations. * integrate.c (process_reg_parm, expand_inline_function, copy_rtx_and_substitute, try_constants, subst_constants, mark_stores): Use varray allocation and accessor macros, new integrate.h macros, and global_const_equiv_varray. Don't conditionalize non-NULL stores on array size; instead, expand the array as needed. * unroll.c (unroll_loop): Likewise. * unroll.c (unroll_loop): Initialize const_equiv_varray element to zero. After allocating varray, always exit through bottom of function, where it can be deallocated if needed. Don't explicitly reallocate const_equiv_map storage; instead, just ensure the varray has been initialized, and update the global reference. Mon Feb 1 09:40:25 1999 Kaveh R. Ghazi * system.h (inline, const): Handle these for stage2 (and later) gcc. * dwarf2out.c (inline): Don't define. * dwarfout.c (inline): Likewise. Sun Jan 31 22:04:37 1999 Richard Henderson * loop.c (recombine_givs): Dump recombination and derivation data. Sun Jan 31 20:34:29 1999 Zack Weinberg * flags.h: Declare flag_no_ident. * toplev.c: Define flag_no_ident. Process -f(no-)ident here. * c-tree.h: Don't declare flag_no_ident. * c-decl.c: Don't define flag_no_ident. Don't process -f(no-)ident switches here. * config/elfos.h (ASM_FILE_END): Output final .ident directive only if !flag_no_ident. * config/ptx4.h: Likewise. * config/svr4.h: Likewise. * config/alpha/elf.h: Likewise. * config/arm/linux-elf.h: Likewise. * config/i386/sco5.h: Likewise. * config/i860/fx2800.h: Likewise. * config/mips/gnu.h: Likewise. * config/i386/osfrose.h: Likewise. * gcc.c (C specs): Map -Qn to -fno-ident. * objc/lang-specs.h: Likewise. Mon Feb 1 10:52:07 1999 Michael Hayes * configure.in: Don't remove loop.o and unroll.o when enable-haifa is selected. * configure: Rebuilt. Sun Jan 31 13:22:02 1999 John Wehle (john@feith.com) * i386.md (movsicc, movhicc, movsfcc, movdfcc, movxfcc, movdicc): Delete unconstrained alternatives. * i386.c (output_fp_conditional_move, output_int_conditional_move): Delete unused case. Sun Jan 31 01:15:04 1999 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. Sun Jan 31 00:52:37 1999 Richard Henderson * alpha.md (mov patterns): Emit the assembler aliases mov and fmov instead of bis and cpys. Combine alternatives where possible. Sat Jan 30 23:14:13 1999 Kaveh R. Ghazi * gcov.c (fnotice): Add missing FILE* parameter. (function_summary): Fix format specifiers in calls to `fnotice'. (output_data): Likewise. * toplev.c (fnotice): Constify char* parameter. * toplev.h (fnotice): Add prototype. Wrap prototype with BUFSIZ to protect FILE* usage. Sun Jan 31 15:33:09 1999 Michael Hayes * config/c4x/c4x.h (RTX_COSTS): Explicitly define c4x costs. Sat Jan 30 08:27:23 1999 Jeffrey A Law (law@cygnus.com) * combine.c (distribute_notes): Handle REG_EH_REGION notes. * alias.c (fixed_scalar_and_varying_struct_p): Add "static" to function definition. (aliases_everything_p, write_dependence_p):Likewise. * install.texi: Fix merge lossages. * cccp.c (main): Only call setlocale (LC_MESSAGES, ...) if LC_MESSAGES is defined. * collect2.c (main): Likewise. * cppmain.c (main): Likewise. * gcc.c (main): Likewise. * gcov.c (main): Likewise. * protoize.c (main): Likewise. * toplev.c (main): Likewise. * pa.md (parallel shift and shiftadd): Mark output of shift as an earlyclobber. * loop.c: Disable recent loop changes. Temporary as Joern continues to fix problems. Sat Jan 30 03:24:37 1999 J"orn Rennecke * loop.c (strength_reduce): Size reg_map according to reg_iv_type. Fri Jan 29 18:26:07 1999 Dave Brolley * emit-rtl.c (remove_insn): New function. * rtl.h (remove_insn): Add prototype. * function.c (reposition_prologue_and_epilogue_notes): Call remove_insn. Fri Jan 29 22:34:41 1999 J"orn Rennecke * loop.c (recombine_givs): Don't try to derive givs that have combined. Fri Jan 29 15:00:39 1999 Kaveh R. Ghazi * toplev.c (notice, fnotice): Check ANSI_PROTOTYPES, not __STDC__, when declaring arguments and calling va_arg() to initialize them. * collect2.c (notice): Likewise. * loop.c (find_life_end): Use PROTO() macro in the prototype. Fri Jan 29 14:36:11 1999 Kaveh R. Ghazi * collect2.c (error): Fix typo in declaration. * cpperror.c (cpp_message): Likewise. * cpplib.c (cpp_warning): Likewise. * cpplib.h (cpp_notice): Use PVPROTO not VPROTO, also add ATTRIBUTE_PRINTF_1. * toplev.c (error): Fix typo in declaration. Fri Jan 29 15:44:13 1999 J"orn Rennecke * loop.c (strength_reduce): Fix HAVE_cc0 handling when scanning forward from cont dominator. Fri Jan 29 07:10:27 1999 Kaveh R. Ghazi * cccp.c (eprint_string): Constify a char*. (notice): Likewise. Use PVPROTO not VPROTO, add ATTRIBUTE_PRINTF_1. (vnotice): Constify a char*. (error): Likewise. Use PVPROTO not VPROTO, add ATTRIBUTE_PRINTF_1. (verror): Constify a char*. (warning): Likewise. Use PVPROTO not VPROTO, add ATTRIBUTE_PRINTF_1. (vwarning): Constify a char*. (error_with_line): Likewise. Use PVPROTO not VPROTO, add ATTRIBUTE_PRINTF_2. (verror_with_line): Constify a char*. (vwarning_with_line): Likewise. (warning_with_line): Likewise. Use PVPROTO not VPROTO, add ATTRIBUTE_PRINTF_2. (pedwarn): Constify a char*. Use PVPROTO not VPROTO, add ATTRIBUTE_PRINTF_1. (pedwarn_with_line): Likewise with ATTRIBUTE_PRINTF_2. (pedwarn_with_file_and_line): Likewise with ATTRIBUTE_PRINTF_4. Also correct typo in parameter name declaration. (make_assertion): Constify a char*. (quote_string_for_make): Likewise. (deps_output): Likewise. (fatal): Likewise. Use PVPROTO not VPROTO, add ATTRIBUTE_PRINTF_1. Use ATTRIBUTE_NORETURN not an explicit "__attribute__ ((noreturn))". (fancy_abort): Likewise for ATTRIBUTE_NORETURN. (pfatal_with_name): Likewise. (pipe_closed): Likewise. (memory_full): Likewise. Fri Jan 29 00:14:55 1999 J"orn Rennecke * loop.c (strength_reduce): Grow set_in_loop / n_times_set / may_not_optimize to proper size when converting biv increments into givs. If necessary, reallocate reg_iv_type / reg_iv_info before calling recombine_givs. Thu Jan 28 23:24:08 1999 J"orn Rennecke * loop.c (recombine_givs): New parameter unroll_p. If set, don't generate complex adds. Changed caller. Don't generate adds that cost more than the original one. (strength_reduce): Warning fixes. Thu Jan 28 09:41:11 1999 Jeffrey A Law (law@cygnus.com) * configure.in (hppa1.0-hp-hpux10*): Use t-pa. * configure: Rebuilt. Wed Jan 27 23:39:53 1999 J"orn Rennecke * rtl.h (insn_first_p, no_jumps_between_p): Declare. * rtlanal.c (insn_first_p, no_jumps_between_p): New function. * loop.h (varray.h): Include. (struct induction): Change combined_with to unsigned. New members derived, ix and last_use. (reg_iv_type, reg_iv_info): Now varray_type. All references changed. (REG_IV_TYPE, REG_IV_INFO): Define. (first_increment_giv, last_increment_giv): Declare. * loop.c (loop_number_loop_cont): New static variable. (loop_number_cont_dominator): Likewise. (reg_iv_type, reg_iv_info): Now varray_type. (first_increment_giv, last_increment_giv): New variables. (compute_luids, verify_dominator, find_life_end): New functions. (cmp_recombine_givs_stats, recombine_givs): Likewise. (loop_optimize): Allocate loop_number_loop_cont and loop_number_cont_dominator. Use compute_luids. (find_and_verify_loops): Initialize loop_number_loop_cont and loop_number_cont_dominator. (strength_reduce): Try to find bivs that can be expressed as givs of another biv, and to convert biv increments into givs. Call recombine_givs. Handle derived givs. (record_biv): New argument location. All callers changed. (record_giv): Initialize derived and last_use fields. (basic_induction_var): New argument location. All callers changed. (combine_givs): Don't combine a DEST_REG giv with a DEST_ADDR giv. Increment combined_with instead of setting to 1. * unroll.c (derived_regs): New static variable. (unroll_loop): Initialize it. Allocate local_regno according to max_reg_num. (copy_loop_body): Cope with derived givs. (find_splittable_givs): Check for Givs made from biv increments. Set derived_regs for givs. * Makefile.in (stmt.o, loop.o, unroll.o): Depend on loop.h . Wed Jan 27 19:31:36 1999 J"orn Rennecke * function.c (purge_addressof_1): Handle case when a register has been used in a wider mode. 1999-01-27 Bruce Korb * fixinc/fixincl.c, fixinc/server.[ch]: Removed the last of the capitalized variable and proc names. * fixinc/server.c: Removed the process open code. * fixinc/procopen.c: New file containing the proc open code. * fixinc/inclhack.tpl: Added code to bypass a readability test when a file is not present. A problem on some systems. * fixinc/inclhack.sh, fixinc/fixincl.sh: Regenerated. Wed Jan 27 11:58:18 1999 Dave Brolley * cpplib.h (cpp_notice): Add prototype. Wed Jan 27 02:20:48 1999 Jeffrey A Law (law@cygnus.com) * Merge gcc2 snapshot 19980929. * cccp.c (PRINTF_PROTO): Remove. (PRINTF_PROTO_{1,2,3,4}: Likewise. * cexp.y: Likewise. * system.h: Add PRINTF_PROTO and PRINTF_PROTO_{1,2,3,4}. * fix-header.c (cpp_file_lin_for_message): Delete. In libcpp. (cpp_print_containing_files, v_cpp_message, cpp_message): Likewise. (cpp_fatal, cpp-Pfatal_with_name): Likewise. * gen-protos.c (hashf): Delete in cpphash.o. * gen-protos.c (hashf): Delete in cpphash.o. * expr.c: Do not merge SAVE_STACKAREA_MODE changes. * expmed.c: Likewise. * rs6000.md: Likewise. * rs6000.c, rs6000.md: Do not merge formatting changes yet. Wed Jan 27 01:13:42 1999 Richard Henderson * rs6000.c (input_operand): Don't expect CONST around CONSTANT_P_RTX. * rs6000.md (movsi, movdi): Likewise. Tue Jan 26 13:31:38 1999 Jim Wilson * function.c (expand_function_end): Pass arg_pointer_save_area to validize_mem before using it. Emit code into a sequence. Tue Jan 26 13:41:38 1999 David Edelsohn * rs6000.md (doz + set cr and or + set cr patterns): Add missing '#' to split patterns. Correct indentation of some new patterns. 1999-01-26 Zack Weinberg * cppfiles.c (safe_read): Deleted. (read_and_prescan): New function, replaces safe_read, converts and/or warns about trigraphs, silently converts odd line terminators (\r, \n\r, \r\n). Warns about no newline at EOF. (finclude): Use read_and_prescan; turn off nonblocking mode on the input descriptor; remove file-size-examination and no-newline-at-EOF gunk which is longer necessary; be more careful about checking that we've been handed a legitimate file to read (only real files, pipes, and ttys are acceptable). * cpplib.h (cpp_options): Rename no_trigraphs flag to `trigraphs' and invert its sense. (trigraph_table): Declare. (cpp_warning_with_line): Prototype. * cpplib.c: Remove all references to trigraph_pcp. Define trigraph_table; initialize it in initialize_char_syntax. Open files in nonblocking mode. s/no_trigraphs/trigraphs/ throughout, and invert sense. Put cpp_warning_with_line back in and export it. Tue Jan 26 23:21:49 1999 Michael Hayes * config/c4x/c4x.h (COUNTER_REGS): New register class. * config/c4x/c4x.md (*rptb_init): Change constraints. (rptb_end): Emit alternate looping instructions if RC register not allocated for loop counter. (decrement_and_branch_on_count): Allow other registers for loop counter. 1999-01-25 Zack Weinberg * cppexp.c (struct arglist): Removed. (parse_number): Use HOST_WIDE_INT for the accumulator. Allow two `l' suffixes unless C89. Clean up. Make static. (parse_charconst): New function broken out of cpp_lex. Code cleaned up drastically. Don't use a token_buffer. (token_buffer): Removed. (cpp_lex): Don't call parse_number on a constant string. Use parse_charconst. (cpp_parse_expr): Properly handle an ERROR op returned by cpp_lex. 1999-01-25 Zack Weinberg * cpplib.c: Don't include signal.h, sys/times.h, or sys/resource.h. Don't declare localtime. (macroexpand): Handle special symbols here. (push_macro_expansion): Chop off the trailing '@ ' if possible here. (cpp_get_token): Don't do either of the above two things here. Move `string' label just after case '"' so that wide strings don't crash the preprocessor. Sun Jan 24 20:13:45 1999 David Edelsohn * rs6000.md (left shift + set cr patterns): Add missing '#' to split patterns. (move register + set cr pattern): Likewise. (movdi, !TARGET_POWERPC64 splitters): Add back in Jan. 15th patch, inadvertently deleted. Sun Jan 24 08:07:59 1999 Jeffrey A Law (law@cygnus.com) * stmt.c (stmt_loop_nest_empty): New function. * tree.h (stmt_loop_nest_empty): Declare it. * rtl.def (CALL_PLACEHOLDER): New rtx code. Sun Jan 24 21:24:43 1999 Michael Hayes * config/c4x/c4x.c (c4x_emit_move_sequence, c4x_encode_section_info): New functions. (c4x_check_legit_addr): Remove USE and PLUS, allow LO_SUM, and disable SYMBOL_REF, LABEL_REF, and CONST cases. (c4x_legitimize_address): Penalize SYMBOL_REF, LABEL_REF, and CONST cases. Add LO_SUM. (c4x_print_operand): Modified 'C' and 'R' cases for calls. Added 'U' case. Remove dependence on SYMBOL_REF_FLAG. (c4x_print_operand_address): Handle LO_SUM. (c4x_scan_for_ldp): Delete. Hooray! (c4x_process_after_reload): Remove call to c4x_scan_for_ldp. Split all insns. (c4x_immed_int_constant): Renamed from c4x_int_constant. All callers changed. (c4x_immed_float_constant): Renamed from c4x_float_constant. All callers changed. (c4x_T_constraint): Allow LO_SUM, disable SYMBOL_REF, LABEL_REF, and CONST. (c4x_U_constraint, symbolic_operand): New functions. (src_operand): Allow 'I' constants in HImode. Allow LO_SUM, disable SYMBOL_REF, LABEL_REF, and CONST. (lsrc_operand, tsrc_operand): Call src_operand instead of general_operand. (c4x_operand_subword): Update comments. * config/c4x/c4x.c (TARGET_LOAD_ADDRESS): New macro. (LEGITIMATE_CONSTANT_P): Allow SYMBOL_REF, LABEL_REF, CONST, plus HIGH and LO_SUM for the C40. (ENCODE_SECTION_INFO): Define macro. (symbolic_operand, c4x_U_constraint, c4x_emit_move_sequence): New prototypes. (PREDICATE_CODES): Add symbolic_operand. * config/c4x/c4x.md (movqi, movgqf, movhi, movhi): Call c4x_emit_move_sequence. (floatunsqiqf2, fixuns_truncqfqi2): Rework emitted RTL to avoid symbol references. (all patterns with g constraint): Replace 'g' constraint with 'rIm'. (set_high): Renamed from set_high_use. (set_lo_sum): Renamed from set_ior_lo_use. (all call patterns): Make MEM explicit in call address operands. Modified output templates to use 'U' modifier. Sun Jan 24 01:15:05 1999 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. Sat Jan 23 22:34:57 1999 Kaveh R. Ghazi * final.c (bb_str): Qualify a char* with the keyword `const'. (add_bb_string, final_scan_insn, output_asm_insn): Likewise. * fix-header.c (read_scan_file): Likewise. * genoutput.c (output_epilogue, process_template): Likewise. * local-alloc.c (requires_inout, block_alloc): Likewise. * output.h (output_asm_insn, assemble_string): Likewise. * recog.c (recog_constraints, check_asm_operands, decode_asm_operands, extract_insn, preprocess_constraints, constrain_operands): Likewise. * recog.h (operand_alternative, recog_constraints, insn_template, insn_outfun, insn_operand_constraint, insn_name): Likewise. * regclass.c (record_reg_classes, scan_one_insn): Likewise. * regmove.c (find_matches): Likewise. * reload.c (alternative_allows_memconst): Likewise. * reload1.c (constraint_accepts_reg_p, reload_cse_simplify_operands): Likewise. * rtl.h (decode_asm_operands): Likewise. * scan.h (fn_decl): Likewise. * varasm.c (assemble_string): Likewise. Sat Jan 23 01:37:36 1999 Jeffrey A Law (law@cygnus.com) * configure.in (gcc_tooldir): Handle case where exec_prefix has not been explicitly set. * configure: Rebuilt. * fold-const.c (lshift_double): Mark 'prec' arguments as possibly unused. * bitmap.h (bitmap_head_def): Make indx field unsigned. * configure.in (gcc_tooldir): When not making a relative gcc_tooldir, use $exec_prefix/$target_alias for gcc_tooldir. * configure: Rebuilt. Fri Jan 22 11:48:56 1999 Richard Henderson * cppp.c (xrealloc): Fix typo last change. * cppalloc.c, gcc.c, genattr.c, genattrtab.c, gencodes.c: Likewise. * genconfig.c, genemit.c, genextract.c, genflags.c: Likewise. * genopinit.c, genoutput.c, genpeep.c, genrecog.c: Likewise. 1999-01-22 Michael Meissner * rs6000.h (CR0_REGNO_P): New macro to test if cr0. (CR_REGNO_NOT_CR0_P): New macro to test if cr, but not cr0. (PREDICATE_CODES): Add cc_reg_not_cr0_operand. (cc_reg_not_cr0_operand): Add declaration. * rs6000.c (cc_reg_not_cr0_operand): Return true if register is a pseudo register, or a control register that is not CR0. * rs6000.md (all combiner patterns building . instructions): For all `.' instructions that do something and set cr0, add an alternative that does the operation, and then sets a different flag, in order to avoid using the costly mcrf instruction and also allow cr0 to be clobbered in asm statements. Also fix a few patterns that used the wrong register. * rs6000.h (rs6000_cpu_select): Make string, names be const char *. (rs6000_debug_name): Make const char *, not char *. * sysv4.h (rs6000_{abi,sdata}_name): Make const char *. * rs6000.c (rs6000_{debug,abi,sdata}_name): Make const char *. (rs6000_select): Use const char * in casts. Fri Jan 22 07:43:01 1999 Jeffrey A Law (law@cygnus.com) * Makefile.in (gcc_tooldir): Move before first reference. Let autoconf substitute in a value. * configure.in (gcc_tooldir): Only use a relative path to the tool directory if $exec_prefix == $prefix. * configure: Rebuilt. * Makefile.in (tooldir): Replace with gcc_tooldir. Thu Jan 21 23:21:57 1999 Jeffrey A Law (law@cygnus.com) * m68k.md (ashldi_const): Disable for !TARGET_5200. Fix indentation. (ashldi3 expander): Similarly. Update comments. (ashrdi_const, lshrdi_const): Fix indentation. (ashrdi3, lshrdi3): Fix indentation. Update comments. Thu Jan 21 21:53:36 1999 Richard Henderson * emit-rtl.c (try_split): Don't try to split non-instructions. Thu Jan 21 23:47:30 1999 Andrew MacLeod * expr.c (emit_push_insn): Fix dumb typo. Thu Jan 21 20:24:02 1999 Richard Henderson * rs6000.h (LEGITIMIZE_RELOAD_ADDRESS): Recognize and accept transformations that we have performed earlier. * alpha.h (LEGITIMIZE_RELOAD_ADDRESS): Likewise. * alpha.md (prologue_stack_probe_loop): Don't do our own label handling, call gen_label_rtx instead. Thu Jan 21 17:45:18 1999 Richard Henderson * configure.in ({rs6000|powerpc}-ibm-aix4.[12]*): Add missing `then'. * cccp.c (xrealloc): Call malloc given a NULL old pointer. * collect2.c, cppalloc.c, gcc.c, genattr.c, genattrtab.c: Likewise. * gencodes.c, genconfig.c, genemit.c, genextract.c: Likewise. * genflags.c, genopinit.c, genoutput.c, genpeep.c: Likewise. * genrecog.c, mips-tfile.c, protoize.c: Likewise. Thu Jan 21 19:44:55 1999 Michael Meissner * configure.in ({rs6000|powerpc}-ibm-aix4.[12]*): If --with-gnu-ld, use x-aix41-gld instead of x-aix41 to suppress adding -Wl,-bbigtoc to BOOT_LDFLAGS. * configure: Regenerate. * config/rs6000/x-aix41-gld: New file, don't set BOOT_LDFLAGS. Thu Jan 21 15:48:03 1999 Dave Brolley * cppexp.c (cpp_lex): Allocate token_buffer dynamically. Thu Jan 21 14:18:04 1999 Andrew MacLeod * expr.c (MOVE_BY_PIECES_P): Define condition for deciding to use move_by_pieces. (MOVE_MAX_PIECES): Define maximum number of bytes to move at once. (USE_LOAD_POST_INCREMENT, USE_LOAD_PRE_DECREMENT): Define defaults. (USE_STORE_POST_INCREMENT, USE_STORE_PRE_DECREMENT): Define defaults. (move_by_pieces): Use new macros. (emit_block_move): Use new macros. (clear_by_pieces): Use new macros. (clear_storage): Use new macros. (emit_push_insn): Use new macros. (expand_expr): Use new macros. * config/sh/sh.h (USE_LOAD_POST_INCREMENT, USE_LOAD_PRE_DECREMENT): Define. (USE_STORE_POST_INCREMENT, USE_STORE_PRE_DECREMENT): Define. (MOVE_BY_PIECES_P): Define based on alignment and TARGET_SMALLCODE. (MOVE_MAX_PIECES): Move 8 bytes on SH4. * tm.texi(MOVE_BY_PIECES_P, MOVE_MAX_PIECES, USE_LOAD_POST_INCREMENT, USE_LOAD_PRE_DECREMENT, USE_STORE_POST_INCREMENT, USE_STORE_PRE_DECREMENT): Describe new macros. Thu Jan 21 14:13:31 1999 Vladimir N. Makarov * varasm.c (output_constant_pool): Use floor_log2 instead of exact_log2 for ASM_OUTPUT_ALIGN. * stor-layout.c (layout_type): Do machine-dependent extra alignment. * emit-rtl.c (operand_subword): Handle case when a subword outside the operand. * tm.texi (ROUND_TYPE_{SIZE,ALIGN}): More accurate descriptions of the macros. Thu Jan 21 01:59:30 1999 Richard Henderson * cse.c (fold_rtx): Revert 29 Dec change. (cse_insn): Revert 12 Jan change. * expr.c (expand_builtin): Don't emit CONST around CONSTANT_P_RTX. * regclass.c (reg_scan_mark_refs): Revert 29 Dec change. * rtl.def: Likewise. * rtl.h (CONSTANT_P): Likewise. * expr.c (emit_move_insn): Never try to flush CONSTANT_P_RTX to memory. * recog.c (immediate_operand): Accept CONSTANT_P_RTX. * alpha.c (input_operand): Likewise. * c4x.c (const_operand): Likewise. * explow.c (allocate_dynamic_stack_space): Use register_operand instead of arith_operand, which does not exist. * 1750a.h: Fix comment closure. * a29k.c (a29k_set_memflags): Fix typo in 19 Jan change. * arc.md (one_cmplsi2_set_cc_insn): Fix set mode mismatch. * arm.h (TARGET_SWITCHES): Fix typo. * i370.md (anon mult and div patterns): Fix set mode mismatch. * i860.c (output_delayed_branch): Fix operands to constrain_operands. (output_delay_insn): Likewise. * m88k.md (anon rotate insns): Fix set mode mismatch. (anon BLKmode moves): Commonize and fix set mode mismatches. * ns32k.md (udivmoddi[shq]i4_internal): Fix mode mismatch. * romp.md (movdf): Fix typo. Thu Jan 21 00:29:35 1999 Nathan Sidwell * Makefile.in (install-common): Remove extraneous chmod for gcov install. Wed Jan 20 18:15:08 1999 Dave Brolley * function.c (assign_parms): Save and restore setting of TREE_USED (parm). Wed Jan 20 12:51:42 1999 Mark Mitchell * arm.md: Use MEM_COPY_ATTRIBUTES where appropriate throughout. Pass MEM_SCALAR_P to arm_gen_store_multiple where appropriate. Tue Jan 19 21:20:52 1999 Richard Henderson * recog.c (pop_operand): New function. * recog.h (pop_operand): Declare it. * genrecog.c (preds): Define it. * expr.c (do_jump_for_compare): Handle conditional branch expanders emitting multiple jump instructions. * jump.c (condjump_label): New function. * rtl.h (condjump_label): Declare it. Tue Jan 19 21:08:20 1999 Richard Henderson * expr.c (emit_move_insn_1): Revert 17 Dec change. Don't emit clobber during or after reload. Tue Jan 19 16:56:03 1999 Richard Henderson * genoutput.c (name_for_index): New function. (scan_operands, validate_insn_alternatives): Use it. * genrecog.c (insn_name_ptr_size): New variable. (make_insn_sequence): Fill in insn_name_ptr. (merge_trees): Use it. Tue Jan 19 16:37:36 1999 Richard Henderson * i386/isc.h (TARGET_DEFAULT): Define symbolicly. * i386/isccoff.h, i386/next.h, i386/sco.h, i386/sco5.h: Likewise. * i386/scodbx.h, i386/sequent.h, i386.unix.h: Likewise. Tue Jan 19 15:00:10 1999 Jeffrey A Law (law@cygnus.com) * loop.c (NUM_STORES): Delete. (loop_store_mems): Turn into an EXPR_LIST of MEMs. (prescan_loop): Properly initialize loop_mems_idx. (note_addr_stored): Simplify using list structure instead of fixed sized array. (invariant_p, check_dbra_loop, load_mems): Similarly. * flow.c (invalidate_from_autoinc): New function. (mark_set_1, mark_used_regs): Use it. * Makefile.in (protoize.o, unprotoize.o): Depend on Makefile. 1999-01-19 Vladimir N. Makarov * invoke.texi (-mlong-double-64): New option description. 1999-01-19 Jim Wilson * libgcc2.c: Change all uses of LONG_DOUBLE_TYPE_SIZE to LIBGCC2_LONG_DOUBLE_TYPE_SIZE. (LIBGCC2_LONG_DOUBLE_TYPE_SIZE): New. Set to LONG_DOUBLE_TYPE_SIZE if not defined. * i960/i960.h (MULTILIB_DEFAULTS): Define to mnumerics. (CPP_SPECS): Add -mlong-double-64 support. (TARGET_FLAG_LONG_DOUBLE_64, TARGET_LONG_DOUBLE_64): New. (TARGET_SWITCHES): Add -mlong-double-64 support. (LONG_DOUBLE_TYPE_SIZE): Likewise. (LIBGCC2_LONG_DOUBLE_TYPE_SIZE): Define. * i960/vx960-coff.h (MULTILIB_DEFAULTS): Define to msoft-float. (CPP_SPECS): Add -mlong-double-64 support. * i960/t-960bare (MULTILIB_OPTIONS): Add mlong-double-64. (MULTILIB_DIRNAMES): Add ld64. * i960/t-vxworks960 (MULTILIB_OPTIONS, MULTILIB_DIRNAMES): Likewise. Tue Jan 19 11:54:04 1999 Jason Merrill * calls.c (expand_call): Strip a TARGET_EXPR if we're passing by invisible reference. Tue Jan 19 14:51:36 1999 David Edelsohn * rs6000.c (offsettable_addr_operand): Delete. (offsettable_mem_operand): New function. * rs6000.h (PREDICATE_CODES): Reflect function change. (RS6000_SAVE_TOC): Represent address as MEM. * win-nt.h (RS6000_SAVE_TOC): Same. * rs6000.md (indirect calls): Change offsettable address parameter to offsettable memory parameter. Tue Jan 19 10:24:53 1999 Mark Mitchell * rtl.h (rtx_def): Update documentation. (MEM_IN_STRUCT_P): Likewise. (MEM_SCALAR_P): New macro. (MEM_COPY_ATTRIBUTES): Likewise. (MEM_SET_IN_STRUCT_P): Likewise. * rtl.texi (MEM_SCALAR_P): Document. * alias.c (canon_rtx): Use MEM_COPY_ATTRIBUTES. (fixed_scalar_and_varying_struct_p): New function. Use MEM_SCALAR_P rather than !MEM_IN_STRUCT_P. (aliases_everything_p): Likewise. (true_dependence): Use them. (write_dependence_p): New function, containing code common to anti_dependence and output_dependence. (anti_dependence): Use it. (output_dependence): Likewise. * calls.c (save_fixed_argument_area): Don't clear MEM_IN_STRUCT_P. (expand_call): Use MEM_SET_IN_STRUCT_P. (emit_library_call): Don't clear MEM_IN_STRUCT_P. (emit_library_call_value): Likewise. (store_one_arg): Use MEM_SET_IN_STRUCT_P. * combine.c (simplify_rtx): Use MEM_COPY_ATTRIBUTES. (make_extraction): Likewise. (simplify_shift_const): Likewise. (gen_lowpart_for_combine): Likewise. * cse.c (gen_lowpart_if_possible): Use MEM_COPY_ATTRIBUTES. * emit-rtl.c (operand_subword): Likewise. (change_address): Likewise. * explow.c (stabilize): Use MEM_COPY_ATTRIBUTES. * expr.c (protect_from_queue): Use MEM_COPY_ATTRIBUTES. (emit_group_store): Use MEM_SET_IN_STRUCT_P. (copy_blkmode_from_reg): Likewise. (store_field): Likewise. (expand_expr): Remove bogus guesswork setting MEM_IN_STRUCT_P heuristically. Use MEM_SET_IN_STRUCT_P. (get_memory_rtx): Likewise. * final.c (alter_subreg): Use MEM_COPY_ATTRIBUTES. * function.c (assign_stack_temp): Clear MEM_SCALAR_P and MEM_ALIAS_SET on newly returned MEMs. (assign_temp): Use MEM_SET_IN_STRUCT_P. (put_reg_into_stack): Likewise. (fixup_var_refs1): Use MEM_COPY_ATTRIBUTES. (gen_mem_addressof): Use MEM_SET_IN_STRUCT_P. (assign_parms): Likewise. (expand_function): Likewise. * integrate.c (expand_inline_function): Likewise. (copy_rtx_and_substitute): Use MEM_COPY_ATTRIBUTES. * loop.c (note_addr_stored): Remove check on MEM_IN_STRUCT_P. * optabs.c (gen_move_insn): Use MEM_COPY_ATTRIBUTES. * print-rtl.c (print_rtx): Print /f for frame_related. * recog.c (validate_replace_rtx_1): Use MEM_COPY_ATTRIBUTES. * reload1.c (reload): Copy MEM_SCALAR_P as well. * stmt.c (expand_decl): Use MEM_SET_IN_STRUCT_P. (expand_anon_union_decl): Use MEM_COPY_ATTRIBUTES. * varasm.c (make_decl_rtl): Use MEM_SET_IN_STRUCT_P. (output_constant_def): Likewise. * a29k.c (a29k_set_memflags_1): Take scalar_p. Set MEM_SCALAR_P. (a29k_set_memflags): Use it. * alpha.c (get_aligned_mem): Use MEM_COPY_ATTRIBUTES. * c4x.c (c4x_scan_for_ld): Likewise. * h8300.c (fix_bit_operand): Likewise. * m88k.c (legitimize_address): Likewise. (block_move_loop): Likewise. (block_move_no_loop): Likewise. (block_move_sequence): Likewise. (m88k_builtin_saveregs): Use MEM_SET_IN_STRUCT_P. * mips/abi64.h (SETUP_INCOMING_VARARGS): Likewise. * rs6000.c (expand_block_move_insn): Use MEM_COPY_ATTRIBUTES. * sh.c (sh_builtin_saveregs): Use MEM_SET_IN_STRUCT_P. * arm.h (arm_gen_load_multiple): Take scalar_p. (arm_store_load_multiple): Likewise. * arm.c (arm_gen_load_multiple): Likewise. (arm_gen_store_multiple): Likewise. (arm_gen_movstrqi): Treat MEM_SCALAR_P like MEM_IN_STRUCT_P. Tue Jan 19 12:30:37 1999 Andrew MacLeod * optabs.c (emit_libcall_block): Add a REG_EH_REGION reg note to all calls within a libcall block to indicate no throws are possible. * flow.c (find_basic_blocks, find_basic_blocks_1): Don't look for libcall blocks. Don't add edges to exception handlers if we see a REG_EH_REGION note with a value of 0. (make_edges): Override active_eh_region vector if the call has a note indicating the call does not throw. 1999-01-19 Vladimir N. Makarov * config/rs6000/sysv4.h (CC1_SPEC): Fix correct numbers of {}. Tue Jan 19 06:26:30 1999 Jeffrey A Law (law@cygnus.com) * Makefile.in (cccp.o, cpplib.o): Depend on Makefile. Mon Jan 18 09:56:41 1999 Jason Merrill * invoke.texi (C++ Dialect Options): Document -fno-rtti. 1999-01-18 Vladimir N. Makarov * invoke.texi (-mcpu=740, -mcpu=750): New options. (-m(no-)multiple, -m(no-)string): Describe cases for PPC740 & PPC750. 1999-01-18 Michael Meissner * rs6000.h ({ASM,CPP}_CPU_SPEC): Add support for all machines supported with -mcpu=xxx. (processor_type): Add PROCESSOR_PPC750. (ADJUST_PRIORITY): Call rs6000_adjust_priority. (RTX_COSTS): Supply costs for 750 multiply/divide operations. (rs6000_adjust_priority): Add declaration. * rs6000.c (rs6000_override_options): -mcpu={750,740} now sets the processor type as 750, not 603. Allow -mmultiple and -mstring on little endian 750 systems. (rs6000_adjust_priority): Stub for now. (get_issue_rate): The PowerPC 750 can issue 2 instructions/cycle. * rs6000.md (function/cpu attributes): Add initial ppc750 support. * sysv4.h (STRICT_ALIGNMENT): Don't force strict alignment if little endian. (CC1_SPEC): Pass -mstrict-align if little endian, and not overridden. (CC1_ENDIAN_{LITTLE,BIG,DEFAULT}_SPEC): Endian specific configs. (SUBTARGET_EXTRA_SPECS): Add cc1 endian specs. * {sysv4,eabi}le.h (CC1_ENDIAN_DEFAULT_SPEC): Override, default is little endian. * t-ppcgas (MULTILIB_*): Delete obsolete Solaris multilibs. Mon Jan 18 12:03:08 1999 Gavin Romig-Koch * config/mips/mips.md (div_trap): Split div_trap_mips16 from div_trap. (div_trap_normal,div_trap_mips16): Correct the length attributes. Mon Jan 18 11:48:28 1999 Kaveh R. Ghazi * cpplib.c (special_symbol): Qualify a char* with the `const' keyword. Instead of writing to const char *buf directly, use a non-const variable `wbuf' to allocate and write a string, then set buf = wbuf. * cppulp.c (user_label_prefix): Qualify a char* with the `const' keyword. * dyn-string.c (dyn_string_append): Likewise. * dyn-string.h (dyn_string_append): Likewise. * final.c (end_final, output_operand_lossage, asm_fprintf): Likewise. * output.h (end_final, output_operand_lossage, asm_fprintf, named_section, decode_reg_name, make_decl_rtl, user_label_prefix): Likewise. * profile.c (init_branch_prob): Likewise. * toplev.c (set_target_switch, vmessage, v_message_with_file_and_line, v_message_with_decl, v_error_with_file_and_line, v_error_with_decl, v_error_for_asm, verror, vfatal, v_warning_with_file_and_line, v_warning_with_decl, v_warning_for_asm, vwarning, vpedwarn, v_pedwarn_with_decl, v_pedwarn_with_file_and_line, vsorry, v_really_sorry, open_dump_file, dump_rtl, clean_dump_file, print_version, print_single_switch, print_switch_values, dump_base_name, debug_args, lang_independent_options, user_label_prefix, documented_lang_options, target_switches, target_options, print_time, pfatal_with_name, fatal_io_error, fatal_insn, default_print_error_function, print_error_function, report_error_function, error_with_file_and_line, error_with_decl, error_for_asm, error, fatal, warning_with_file_and_line, warning_with_decl, warning_for_asm, warning, pedwarn, pedwarn_with_decl, pedwarn_with_file_and_line, sorry, really_sorry, botch, output_quoted_string, output_file_directive, open_dump_file, rest_of_decl_compilation, display_help, main): Likewise. * toplev.h (print_time, fatal, fatal_io_error, pfatal_with_name, fatal_insn, warning, error, pedwarn, pedwarn_with_file_and_line, warning_with_file_and_line, error_with_file_and_line, sorry, really_sorry, default_print_error_function, report_error_function, rest_of_decl_compilation, pedwarn_with_decl, warning_with_decl, error_with_decl, error_for_asm, warning_for_asm, output_quoted_string, output_file_directive, botch): Likewise. * tree.h (make_decl_rtl): Likewise. * varasm.c (strip_reg_name, named_section, decode_reg_name, make_decl_rtl): Likewise. Mon Jan 18 11:35:49 1999 Gavin Romig-Koch * Makefile.in (TCL_LIBRARY): Use 'cd' to find the library directory logically rather than physically. Mon Jan 18 09:05:37 1999 Kaveh R. Ghazi * loop.c (insert_bct): Hide the definition of variables `increment_direction', `compare_direction', `add_iteration' and `loop_var_mode'. * recog.c (mode_dependent_address_p): Mark parameter `addr' with ATTRIBUTE_UNUSED. Mark label `win' with ATTRIBUTE_UNUSED_LABEL. (mode_independent_operand): Mark label `lose' with ATTRIBUTE_UNUSED_LABEL. * regclass.c (n_occurrences): Remove prototype and definition. * reload.c (find_reloads_address_1): Mark variable `tem' with ATTRIBUTE_UNUSED. * reload1.c (reload): Cast the first two arguments of `bcopy' to PTR. * sbitmap.c (sbitmap_copy): Likewise. * scan-decls.c (scan_decls): Hide label `handle_comma'. * toplev.c (output_lang_identify): Mark prototype with ATTRIBUTE_UNUSED. * tree.c (make_node): Cast the first argument of `bzero' to PTR. (make_tree_vec): Likewise. (build1): Likewise. * varasm.c (assemble_static_space): Mark variable `tem' with ATTRIBUTE_UNUSED. Mon Jan 18 04:28:36 1999 Nathan Sidwell * Makefile.in (GCOV_INSTALL_NAME): New macro. (install-common): Use it. (uninstall): Use it. (uninstall): Use correct names for protoize and unprotoize. Mon Jan 18 03:52:56 1999 Christian Bruel Jeffrey A Law (law@cygnus.com) * flow.c (last_mem_set): Delete variable. References removed. (mem_set_list): New variable. (life_analysis): Initialize and finalize alias analysis. (propagate_block); Initialize mem_set_list. Clear for CALL_INSNs. (insn_dead_p): For a store to memory, search the entire mem_set_list for a match. (mark_set_1): Kill entries on the mem_set_list for aliased writes or changes to their addresses. Add new entries to the mem_set_list for memory writes writes. (mark_used_regs): Kill entries on the mem_set_list which may be referenced by a load operation. Mon Jan 18 01:01:02 1999 Jeffrey A Law (law@cygnus.com) * alias.c (base_alias_check): Add missing return for differing symbols case. Mon Jan 18 00:36:13 1999 Rainer Orth * mips-tdump.c (print_file_desc): Handle unknown filenames and missing local symbols. Sun Jan 17 21:04:31 1999 Richard Henderson * jump.c (rtx_renumbered_equal_p): Special case CODE_LABEL. * system.h (bcopy): Implement with memmove not memcpy. Sun Jan 17 19:23:20 1999 Jeffrey A Law (law@cygnus.com) * Makefile.in (cppulp.o): Add dependencies. * i386.md (integer conditional moves): Add missing earlyclobbers. * regmove.c (optimize_reg_copy_1): Undo Aug 18 change. Update REG_N_CALLS_CROSSED and REG_LIVE_LENGH if and only if we change where a register is live. Sun Jan 17 03:20:47 1999 H.J. Lu (hjl@gnu.org) * reg-stack.c (subst_stack_regs_pat): Abort if the destination of a FP conditional move is not on the FP register stack. Sun Jan 17 01:15:04 1999 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. Sat Jan 16 23:40:33 1999 Jeffrey A Law (law@cygnus.com) * reload1.c (reload_cse_regs_1): Do not call reload_cse_simplify_operands for an insn with asm operands. * cccp.c (print_help): Fix typos. * cpplib.c (print_help): Fix typos. * toplev.c (f_optiosn): Fix typos. (documented_lang_options): Fix typos. Sat Jan 16 21:48:17 1999 Marc Espie (Marc.Espie@openbsd.org) * gcc.c (do_spec_1): Fix obvious typo. Sat Jan 16 19:31:07 1999 Kaveh R. Ghazi * c-decl.c (duplicate_decls): If `warn_traditional', warn when a non-static function declaration follows a static one. * invoke.texi (-Wtraditional): Document the extra check now done by this flag. Sat Jan 16 15:13:46 1999 Jeffrey A Law (law@cygnus.com) * pa.md (shadd): Create shadd insns, even if the result of the shift is needed without the addition. Sat Jan 16 10:48:16 1999 J"orn Rennecke * sh.md (movdf, movsf): Temporary workaround for no_new_pseudos lossage. Fri Jan 15 23:44:37 1999 Richard Henderson * sparc.c (sparc_issue): Add hypersparc/sparclite86x entries. Fri Jan 15 22:30:04 1999 David Edelsohn * rs6000.h (CONST_OK_FOR_LETTER_P): Do not assume 32-bit CONST_INT. * rs6000.c (u_short_cint_operand, add_operand, logical_operand, non_add_cint_operand, non_logical_cint_operand): Likewise. (get_issue_rate): Add CPU_PPC604E case. * rs6000.md (movdi, !TARGET_POWERPC64 splitters): Handle 64-bit hosts. Fri Jan 15 18:42:12 1999 Richard Henderson * expr.c (queued_subexp_p): Make public. * expr.h (queued_subexp_p): Declare it. * recog.c (asm_operand_ok): New function. (check_asm_operands): Use it. After reload, use constrain_operands instead. * recog.h (asm_operand_ok): Declare it. * stmt.c (expand_asm_operands): Use it to try harder to make asms initially satisfy their constraints. Fri Jan 15 17:43:59 1999 Jeffrey A. Law * sparc.h (LEGITIMIZE_RELOAD_ADDRESS): Do not create (mem (lo_sum (...)) for TFmode unless TARGET_V9. Sat Jan 16 12:47:15 1999 Michael Hayes * config/c4x/c4x.md (not_repeat_reg): Allow ldp instruction in delay slot of RPTBD. Sat Jan 16 12:26:40 1999 Michael Hayes * config/c4x/libgcc.S (___divhi3, ___modhi3): Fix long long divide and modulo sign problem. Fri Jan 15 11:02:31 1999 Michael Hayes * unroll.c (loop_iterations): Return 0 if the last loop insn is not a jump insn or if the loop has multiple back edges. 1999-01-15 Manfred Hollstein * configure.in (fixinc_defs): Do not define for m[68]8k-motorola-sysv{,3}; it's working properly now. Remove comment saying "see m68k-motorola-sysv as an example". * configure: Regenerate using autoconf. * fixinc/fixincl.c (main): Do not ignore SIGCHLD. Thu Jan 14 22:38:41 1999 Jeffrey A Law (law@cygnus.com) * unroll.c (find_splittable_givs): For a DEST_ADDR giv, do not share a register with another DEST_ADDR giv if the address is not valid. * pa.c (hppa_expand_epilogue): Save and restore the static chain around the call to mcount. * h8300.h (ASM_OUTPUT_LABELREF): Use asm_fprintf, not fprintf. * stmt.c (expand_end_case): Use emit_cmp_and_jump_insns to avoid generating non-canonical rtl. 1999-01-14 Vladimir N. Makarov * config/i960/i960.c (i960_output_move_double_zero, i960_output_move_quad_zero): New functions for moving zeros. (i960_output_move_double, i960_output_move_quad): Additional code for situation when moving unaligned register group. * config/i960/i960.h (i960_output_move_double_zero, i960_output_move_quad_zero): The function definitions. * config/i960/i960.md (movdi+1, movti+1): Usage of the functions. 1999-01-13 Vladimir N. Makarov * config/i960/i960.c (i960_function_prologue): New code (optimal solution) for saving global registers in local registers. (form_reg_groups, reg_group_compare, split_reg_group): New functions used by the code. (reg_group): New structure definition for the new code. 1999-01-13 Manfred Hollstein * fixinc/fixincl.c (create_file): Pass file creation mask as third parameter to "open". Use O_TRUNC flag to open instead of explicitly unlink'ing the file. (process): and forget about the "chmod" stuff. Wed Jan 13 20:12:37 1999 Richard Henderson * integrate.c (expand_inline_function): Recognize (mem (addressof)) and substitute. Copy the return value from there into a new pseudo. Wed Jan 13 16:47:00 1999 Catherine Moore * config/arm.c (output_func_epilogue): Check TARGET_ABORT_NORETURN before generating a call to abort for volatile functions. * config/arm.h (ARM_FLAG_ABORT_NORETURN): Define. (TARGET_ABORT_NORETURN): Define. (abort-on-noreturn): New option. Thu Jan 14 13:52:42 1999 Michael Hayes * config/c4x/c4x.md (in_annul_slot_3): Correctly allow unarycc and binarycc operations in 3rd annulled delay slot! Wed Jan 13 16:16:44 1999 Catherine Moore * config/arm.c (output_func_epilogue): Check TARGET_ABORT_NORETURN before generating a call to abort for volatile functions. * config/arm.h (ARM_FLAG_ABORT_NORETURN): Define. (TARGET_ABORT_NORETURN): Define. (abort-on-noreturn): New option. Wed Jan 13 13:30:08 1999 Kaveh R. Ghazi * cccp.c (xstrdup): Renamed from `savestring'. All callers changed. Remove prototype which we get from libiberty.h. * collect2.c (xstrdup): Likewise. * genextract.c (xstrdup): Likewise for `copystr'. (mybzero): Remove it and use `memset' instead. * genoutput.c (mybcopy, mybzero): Remove these. All callers changed to use `memcpy' and `memset' instead. * genrecog.c (xstrdup): Renamed from `copystr'. All callers changed. Remove prototype. (mybcopy, mybzero): Remove these and use memcpy/memset. Wed Jan 13 00:59:04 1999 Jeffrey A Law (law@cygnus.com) * mips.h (LOAD_EXTEND_OP): Correct for SImode and CCmode moves when generating code for TARGET_64BIT. Tue Jan 12 14:05:37 1999 David Edelsohn * rs6000.c (print_operand, cases 'm' and 'M'): Do not depend on HOST_WIDE_INT word-size. (rs6000_stack_info): Remove redundant alignment of fpmem. Tue Jan 12 14:05:37 1999 Richard Henderson * rs6000.c (short_cint_operand): Remove CONSTANT_P_RTX handling. (u_short_cint_operand, reg_or_cint_operand, logical_operand): Likewise. (input_operand): Adjust CONSTANT_P_RTX handling. * rs6000.h (PREDICATE_CODES): Remove CONSTANT_P_RTX references. * rs6000.md (movsi): Adjust CONSTANT_P_RTX handling. (movhi, movqi): Remove CONSTANT_P_RTX handling. (movdi): Adjust CONSTANT_P_RTX handling. 1999-01-12 Manfred Hollstein * configure: Regenerate using autoconf. * fixinc/Makefile.in (INCLUDES): Add -I$(srcdir)/../../include. * fixinc/fixincl.c (SIGCHLD): Use SIGCLD on (very) old systems. (process): "fchmod" isn't available on all systems, use "chmod" instead. * fixinc/server.c: Add #include . (STDIN_FILENO): Add default definition if no include file defines it already. (STDOUT_FILENO): Likewise. Tue Jan 12 10:23:24 1999 Stan Cox * mips.md (call_value_internal3c): New pattern for -mips16 -mlong-calls. 1999-01-12 Manfred Hollstein * m68k/mot3300.h (ADD_MISSING_POSIX, ADD_MISSING_XOPEN): Define to ensure all prototypes necessary for building libio will be available. * m68k/xm-mot3300.h (ADD_MISSING_POSIX, ADD_MISSING_XOPEN): Remove definitions here as they are not host specific. * m88k/sysv3.h, m88k/xm-sysv3.h: Likewise. Tue Jan 12 02:53:46 1999 Richard Henderson * cse.c (cse_insn): Never prefer (const (constant_p_rtx)). Tue Jan 12 02:36:10 1999 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. Tue Jan 12 01:30:19 1999 Richard Henderson * rtl.c (rtx_alloc): Use memset instead of inline loop. * recog.h (recog_op_alt): Declare extern. Tue Jan 12 00:23:31 1999 Richard Henderson * function.c (purge_addressof_1): If the note accesses a mem+addressof in a wider mode than any replacement, adjust the cached replacement. Cache trivial substitutions as well. Tue Jan 12 00:06:00 1999 Richard Henderson * Makefile.in (OBJECTS): Add sbitmap.o. (BASIC_BLOCK_H): Add sbitmap.h. * basic-block.h: Move simple bitmap code to sbitmap.h. * flow.c: Move simple bitmap code to sbitmap.c. * sbitmap.h, sbitmap.c: New files. Mon Jan 11 23:51:50 1999 Richard Henderson * alpha.h (TARGET_SWITCHES): Document switches. (TARGET_OPTIONS): Likewise. * alpha/elf.h (ASM_FINISH_DECLARE_OBJECT): Use HOST_WIDE_INT_PRINT_DEC. Mon Jan 11 22:54:14 1999 Richard Henderson * tree.c (new_alias_set): Return zero if !flag_strict_aliasing. Mon Jan 11 22:36:01 1999 Richard Henderson * basic-block.h (basic_block_head): Rename to x_basic_block_head. (basic_block_end): Rename to x_basic_block_end. (BLOCK_HEAD, BLOCK_END): Update. * caller-save.c: Change basic_block_head/end references to BLOCK_HEAD/END. * combine.c, flow.c, function.c, gcse.c, global.c: Likewise. * graph.c, haifa-sched.c, local-alloc.c, regclass.c: Likewise. * regmove.c, reload1.c, reorg.c, sched.c: Likewise. Sat Jan 9 23:54:09 1999 Kaveh R. Ghazi * gcc.c (xstrerror): Renamed from my_strerror. All callers changed. Remove prototype since we get that from libiberty.h. * protoize.c (xstrerror): Likewise. Sat Jan 9 23:22:04 1999 Kaveh R. Ghazi * gcc.c (read_specs): Ensure format specifiers match their arguments. Sat Jan 9 20:04:24 1999 Richard Henderson * tree.c (copy_node): Oops. That would be copy not zero in that last change. Sun Jan 10 15:35:41 1999 Michael Hayes * config/c4x/c4x.c: Include system.h. (c4x_caller_save_map): Disable caller save for RC. (c4x_optimization_options): Disable scheduling before reload. (valid_parallel_load_store) : Define return type as int. Remove unused variable regs. * config/c4x/c4x.h (REGISTER_MOVE_COST): Make independent of register class. * config/c4x/c4x.md (rotlqi3, rotrqi3): Fix up emitted RTL to handle rotations. (*db, decrement_and_branch_until_zero): Fix up constraints to keep reload happy. Sat Jan 9 18:35:29 1999 Richard Henderson * tree.c (make_node): Call bzero instead of inline clear. (copy_node, make_tree_vec, build1): Likewise. (get_identifier): Call strlen instead of inline count. (maybe_get_identifier): Likewise. Sun Jan 10 14:04:51 1999 Michael Hayes * config/c4x/c4x.md (in_annul_slot_3): Allow unarycc and binarycc operations in 3rd annulled delay slot. (*lshrqi3_const_set): Disallow c constraint for operand0. (modhi3+1, modhi3+2): Set attribute type to multi. * config/c4x/c4x.c (c4x_S_constraint): Removed space in middle of != operator. Sat Jan 9 11:44:55 1999 Kaveh R. Ghazi * gansidecl.h: Allow attribute unused on labels only when we are version 2.93 or higher. Not all versions of 2.92 have this feature. * version.c: Bump minor number to 93. Fri Jan 8 10:51:13 1999 Andreas Schwab * config/m68k/m68k.h: Declare output_function_epilogue. * recog.h: Declare next_insn_tests_no_inequality. Fri Jan 8 01:43:53 1999 Jeffrey A Law (law@cygnus.com) * stmt.c (optimize_tail_recursion): New function, extracted from ... (expand_return): Use optimize_tail_recursion. * tree.h (optimize_tail_recursion): Declare. * toplev.c (compile_file): Move call to output_func_start_profiler to after the loop to emit deferred functions. Thu Jan 7 19:52:53 1999 Gerald Pfeifer * system.h (abort): Supply more detailed information on how to report an Internal Compiler Error. Thu Jan 7 09:25:58 1999 Bruce Korb (korb@datadesign.com) * fixinc/fixincl.c (*): More decapitalization of variables plus some explanatory comments. * fixinc/Makefile.in fixinc/mkfixinc.sh: When the fixincl program does not work for a certain system, we substitute a shell script. Added user commentary when this happens. Thu Jan 7 11:26:17 1999 Mark Mitchell * calls.c (store_unaligned_arguments_into_pseudos): Use xmalloc to allocate memory that will live beyond this function. (expand_call): Free it here. Thu Jan 7 03:08:17 1999 Richard Henderson * sparc.h (PREFERRED_RELOAD_CLASS): Select GENERAL_REGS for integer data not destined for fp regs. (LEGITIMIZE_RELOAD_ADDRESS): New. Thu Jan 7 03:03:42 1999 Stan Cox Richard Henderson Support for Hypersparc and Sparclite86x: * sparc.h (TARGET_CPU_hypersparc, TARGET_CPU_sparclite86x): New. (CPP_CPU32_DEFAULT_SPEC): Fix up for the new targets. (ASM_CPU32_DEFAULT_SPEC): Likewise. (TARGET_CPU_DEFAULT): Likewise. (enum processor_type): Likewise. (CPP_ENDIAN_SPEC): Handle little endian data. (LIBGCC2_WORDS_BIG_ENDIAN): Likewise. (ADJUST_COST): Call sparc_adjust_cost. * sparc.c (sparc_override_options): Fix up for the new targets. (supersparc_adjust_cost): Make static. (hypersparc_adjust_cost): New. (ultrasparc_adjust_cost): Make static. (sparc_adjust_cost): New. * sparc.md (attr cpu): Add hypersparc and sparclite86x. (function_unit): Add hypersparc scheduling rules. * configure.in (with_cpu handler): Recognize hypersparc. Thu Jan 7 23:54:05 1999 Michael Hayes * config/c4x/c4x.c: Added space after negation operator. * config/c4x/c4x.h: Likewise. * config/c4x/c4x.md: Likewise. Thu Jan 7 23:39:27 1999 Michael Hayes * config/c4x/c4x.c (c4x_preferred_reload_class): Always return class. Thu Jan 7 00:29:25 1999 Bernd Schmidt * combine.c (num_sign_bit_copies): In NEG, MULT, DIV and MOD cases, when a test can't be performed due to limited width of HOST_BITS_PER_WIDE_INT, use the more conservative approximation. Fix UDIV case for cases where the first operand has the highest bit set. Thu Jan 7 00:01:38 1999 Lutz Vieweg * pa.h (reg_class): Add FPUPPER_REGS. (REG_CLASS_NAMES): Similarly. (REG_CLASS_CONTENTS): Similarly. (REGNO_REG_CLASS): Handle FPUPPER_REGS. (FP_REG_CLASS_P): Likewise. (REG_CLASS_FROM_LETTER): Similarly. (CLASS_MAX_NREGS): Similarly. 1999-01-06 Brendan Kehoe * fixincludes: For HP/UX 10.20, also look in curses_colr/curses.h for a typedef of bool. Make sure to have a copy of the file is in place before we look to fix it. Fix typo in variable name to FILE. Wed Jan 6 07:51:05 1999 Richard Henderson * expr.c (expand_builtin) [case BUILT_IN_CONSTANT_P]: Use value_mode for the return mode. Wed Jan 6 17:55:19 1999 Robert Lipe * configure.in: New flag --with-dwarf2. If set, enables DWARF-2 debugging as default. * config/tm-dwarf2.h: New file. Wed Jan 6 16:08:54 1999 Jeffrey A Law (law@cygnus.com) * h8300.h (ASM_OUTPUT_LABELREF): Define. * pa.h (DONT_RECORD_EQUIVALENCE): Kill. * local-alloc.c (update_equiv_regs): Corresponding changes. * tm.texi (DONT_RECORD_EQUIVALENCE): Kill. * calls.c (special_function_p): Push alloca test inside the large conditional which excludes functions not at file scope or not extern. * calls.c (special_function_p): New function broken out of expand_call. (precompute_register_parameters): Likewise. (store_one_arg): Likewise. (store_unaligned_argumetns_into_pseudos): Likewise. (save_fixed_argument_area): Likewise. (restore_fixed_argument_area): Likewise. (expand_call): Corresponding changes. Thu Jan 7 00:12:24 1999 Michael Hayes * config/c4x/c4x.md (addqi3): If the destination operand is a hard register other than an extended precision register, emit addqi3_noclobber. (*addqi3_noclobber_reload): New pattern added so that reload will recognize a store of a pseudo, equivalent to the sum of the frame pointer and a constant, as an add insn. 1999-01-06 Manfred Hollstein * fixinc/fixincl.c: Re-indent according to the GNU standards. fixinc/server.c: Likewise. fixinc/server.h: Likewise. Wed Jan 6 10:43:29 1999 Andreas Schwab * config/m68k/m68k.c (const_uint32_operand): Remove CONSTANT_P_RTX handling. (const_sint32_operand): Likewise. Wed Jan 6 09:44:51 1999 Kaveh R. Ghazi * toplev.h: In addition to checking _JBLEN, also check if `setjmp' is a macro when deciding if we can use `jmp_buf' in prototypes. Wed Jan 6 03:18:53 1999 Mark Elbrecht * configure.in (pc-msdosdjgpp): Set x_make to x-go32. * configure: Rebuilt. * i386/xm-go32.h: Define LIBSTDCXX. * i386/x-go32: New. * i386/go32.h (MD_EXEC_PREFIX): Define. (FILE_NAME_ABSOLUTE_P): Define. (LINK_COMMAND_SPEC): Define. Wed Jan 6 02:23:36 1999 "Charles M. Hannum" * expr.c (store_expr): If the lhs is a memory location pointed to be a postincremented (or postdecremented) pointer, always force the rhs to be evaluated into a pseudo. Wed Jan 6 00:54:21 1999 Geoff Keating * real.c (mtherr): Print more reasonable warning messages. Tue Jan 5 21:57:42 1999 Kaveh R. Ghazi * Makefile.in (gcc.o, prefix.o, cccp.o, cpplib.o): Depend on prefix.h. * cccp.c: Include prefix.h, don't prototype prefix.c functions. (new_include_prefix): Constify char* parameters. * cppfiles.c (read_name_map): Likewise. (append_include_chain): Likewise. Also, use a writable char* copy of parameter `dir' which we then modify, rather than using the parameter itself to store the new writable string. (remap_filename): Constify some variables. Also, use a writable char* to store an allocated string which we will be modifying. * cpplib.c: Include prefix.h, don't prototype prefix.c functions. (cpp_start_read): Constify variable `str'. * cpplib.h (append_include_chain): Constify a char* parameter. * gcc.c Include prefix.h, don't prototype prefix.c functions. (add_prefix, save_string): Constify char* parameters. (fatal, error): Add ATTRIBUTE_PRINTF_1 to prototypes. * prefix.c: Include prefix.h. (get_key_value, translate_name, save_string, update_path, set_std_prefix): Constify various char* parameters and variables. (save_string): Use xmalloc, not malloc. (translate_name): Use a writable temporary variable to create and modify a string before setting it to a const char*. * prefix.h: New file to prototype functions exported from prefix.c. Tue Jan 5 08:52:18 1999 Bruce Korb (korb@datadesign.com) * fixinc/fixincl.c (various): Added debug code so Manfred can trace the processing. * fixinc/inclhack.def (sys/utsname.h): Provide forward declaration of struct utsname on Ultrix V4.[35]. * fixinc/{fixincl.x|fixincl.sh|inclhack.sh} : Regenerated. Mon Jan 4 15:37:30 1999 Zack Weinberg * cpplib.c (skip_if_group): Split out the logic that handles directive recognition to its own function. Don't use parse markers; use a bare pointer into the buffer. Use copy/skip_rest_of_line instead of doing it by hand. Remove `return on any directive' mode which was never used, and take only one argument. (consider_directive_while_skipping): New function, subroutine of skip_if_group. Logic streamlined a bit. (conditional_skip, do_elif, do_else): Call skip_if_group with only one argument. Mon Jan 4 15:27:30 1999 Zack Weinberg * cpplib.c (do_undef): EOF immediately after '#undef FOO' is not an error. Mon Jan 4 11:55:51 1999 Jason Merrill * extend.texi (Bound member functions): Document. Mon Jan 4 11:01:48 1999 Kaveh R. Ghazi * mips-tdump.c (st_to_string, sc_to_string, glevel_to_string, lang_to_string, type_to_string): Make return type const char*. (print_symbol): Apply `const' keyword to a char*. (print_file_desc): Cast structure member `crfd' to ulong when comparing against one. * mips-tfile.c (pfatal_with_name): Apply `const' keyword to char*. (fatal, error): Add ATTRIBUTE_PRINTF_1 to prototypes. (progname, input_name): Apply `const' keyword to a char*. Don't redundantly include sys/stat.h. (alloc_info): Apply `const' keyword to a char*. (st_to_string, sc_to_string): Likewise. (hash_string): Cast variable `hash_string' to a symint_t when comparing against one. (add_string): Cast PAGE_USIZE to Ptrdiff_t when comparing against one. Likewise cast it to long when comparing against one. (add_local_symbol): Apply `const' keyword to a char*. (add_ext_symbol): Likewise. (add_unknown_tag): Likewise. (add_procedure): Cast a printf-style field width to an int. (add_file): Cast PAGE_USIZE to long when comparing against one. (parse_begin): Cast a printf-style field width to an int. (parse_bend): Likewise. (parse_def): Likewise. (parse_end): Likewise. (mark_stabs): Mark parameter `start' with ATTRIBUTE_UNUSED. (parse_stabs_common): Fix format specifier. (parse_input): Change type of variable `i' to Size_t. (write_object): Fix arguments to match format specifiers. Cast variable `num_write' to long when comparing against one. (read_seek): Cast variable `sys_read' to symint_t when comparing against one. Fix arguments to match format specifiers. Cast variable `size' to long when comparing against one. (copy_object): Cast result of `sizeof' to int when comparing against one. Fix arguments to match format specifiers. Cast variable `ifd' to long when comparing against a signed value. Likewise, likewise. Mon Jan 4 10:30:33 1999 Kaveh R. Ghazi * c-common.c (decl_attributes): Allow applying attribute `unused' on a LABEL_DECL. * c-parse.in (label): Parse attributes after a label, and call `decl_attributes' to handle them. * gansidecl.h (ATTRIBUTE_UNUSED_LABEL): Define. * genrecog.c (OUTPUT_LABEL, write_tree_1, write_tree): When generating labels, mark them with ATTRIBUTE_UNUSED_LABEL. * invoke.texi: Note that labels can be marked `unused'. Sun Jan 3 23:32:18 1999 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. Sun Jan 3 23:00:42 1999 Jeffrey A Law (law@cygnus.com) * optabs.c (emit_cmp_and_jump_insns): Use CONSTANT_P canonicalizing RTL for a compare/jump sequence. Sun Jan 3 22:58:15 1999 Michael Hayes * optabs.c (emit_cmp_insn): Abort if asked to emit non-canonical RTL for a target with HAVE_cc0 defined. (emit_cmp_and_jump_insns): New function. * expr.h (emit_cmp_and_jump_insns): Prototype it. * loop.c (check_dbra_loop): Use it to replace calls to emit_cmp_insn and emit_jump_insn and to canonicalize the comparison if necessary. * unroll.c (unroll_loop): Likewise. Sun Jan 3 21:01:04 1999 Rainer Orth * fixincludes (sys/utsname.h): Provide forward declaration of struct utsname on Ultrix V4.[35]. * mips.md (div_trap): Use local labels instead of dot-relative branches. Sun Jan 3 20:40:34 1999 Jeffrey A Law (law@cygnus.com) * pa.md (branch, negated branch): Handle (const_int 0) as first source operand. * pa.c (output_cbranch): Likewise. Sun Jan 3 03:20:38 1999 David Edelsohn * rs6000.c (rs6000_stack_info): Undo spurious part of last change. 1999-01-01 Manfred Hollstein * extend.texi (__builtin_constant_p): Add missing @smallexample. Fri Jan 1 11:48:20 1999 Jeffrey A Law (law@cygnus.com) * i386.md (doubleword shifts): Fix dumb mistakes in previous change. Wed Dec 30 23:38:55 1998 Jeffrey A Law (law@cygnus.com) * m68k.md (adddi_dilshr32): Allow all operands to be registers too. (adddi_dishl32): Similarly. * cse.c (invalidate_skipped_block): Call invalidate_from_clobbers for each insn in the skipped block. * reload1.c (reload_as_needed): Verify that the insn satisfies its constraints after replacing a register address with an autoincrement address for reload inheritance purposes. * i386.md (doubleword shifts): Avoid namespace pollution. Wed Dec 30 23:00:28 1998 David O'Brien * configure.in (FreeBSD ELF): Needs special crt files. Wed Dec 30 22:50:13 1998 Geoffrey Noer * i386/xm-cygwin.h: Change DIR_SEPARATOR to forward slash. 1998-12-30 Andreas Schwab * loop.c (check_dbra_loop): While reversing the loop, if the comparison value has a VOID mode use the mode of the other operand to compute the mask. Wed Dec 30 22:24:00 1998 Michael Meissner * rs6000.md ({save,restore}_stack_function): Take 2 operands to avoid warnings in compiling explow.c. (patch from Ken Raeburn, raeburn@cygnus.com) * rs6000.c (rs6000_stack_info): Force 8-byte alignment of fpmem_offset. Compute total size after that, and then rs6000_fpmem_offset using both values. Mon Dec 28 19:26:32 1998 Gerald Pfeifer * gcc.texi (Non-bugs): ``Empty'' loops will be optimized away in the future; indeed that already happens in some cases. Tue Dec 29 11:58:53 1998 Richard Henderson * sparc.c (input_operand): Recognize (const (constant_p_rtx)). (arith_operand): Remove constant_p_rtx handling. (const64_operand, const64_high_operand): Likewise. (arith11_operand, arith10_operand, arith_double_operand): Likewise. (arith11_double_operand, arith10_double_operand, small_int): Likewise. (small_int_or_double, uns_small_int, zero_operand): Likewise. * sparc.h (PREDICATE_CODES): Likewise. * rtl.h (CONSTANT_P): Remove CONSTANT_P_RTX. Tue Dec 29 11:32:54 1998 Richard Kenner * rtl.def (CONSTANT_P_RTX): Clarify commentary. * expr.c (expand_builtin, case BUILT_IN_CONSTANT_P): Rework to consider constant CONSTRUCTOR constant and to defer some cases to cse. * cse.c (fold_rtx, case CONST): Add handling for CONSTANT_P_RTX. * regclass.c (reg_scan_mark_refs, case CONST): Likewise. Tue Dec 29 11:30:10 1998 Richard Henderson * expr.c (init_expr_once): Kill can_handle_constant_p recognition. * cse.c (fold_rtx, case 'x'): Remove standalone CONSTANT_P_RTX code. * alpha.c (reg_or_6bit_operand): Remove CONSTANT_P_RTX handling. (reg_or_8bit_operand, cint8_operand, add_operand): Likewise. (sext_add_operand, and_operand, or_operand): Likewise. (reg_or_cint_operand, some_operand, input_operand): Likewise. * alpha.h (PREDICATE_CODES): Likewise. Sat Dec 26 23:26:26 1998 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. Sat Dec 26 09:17:04 1998 Jeffrey A Law (law@cygnus.com) * gengenrtl.c (gencode): Always use bzero to clear memory instead of dangerous casts and stores. * Makefile.in (compare, gnucompare): Add missing else true clauses. Fri Dec 25 23:00:56 1998 Jeffrey A Law (law@cygnus.com) * alpha.md (builtin_longjmp): Add missing "DONE". Thu Dec 24 10:39:57 1998 Stan Cox * gcc.c (execute): Enable -pipe with win32. Wed Dec 23 10:27:44 1998 Nick Clifton * config/arm/t-arm-elf: Add multiplib option for leading underscores. * config/arm/thumb.h (ASM_OUTPUT_LABELREF): Use variable 'user_label_prefix' rather than macro USER_LABEL_PREFIX. (thumb_shiftable_const): Use macro 'BASE_REG_CLASS' rather than variable 'reload_address_base_reg_class'. [Note this change is unrelated to the others in this patch]. * config/arm/unknown-elf.h (USER_LABEL_PREFIX): Default to no leading underscore. Wed Dec 23 09:51:32 1998 Kaveh R. Ghazi * alias.c (record_alias_subset): Remove ignored `&'. (init_alias_once): Likewise. * c-lex.c (UNGETC): Cast first argument of comma expression to void. * config/mips/mips.c (mips_asm_file_end): Cast the result of fwrite to `int' when comparing against one. * config/mips/mips.h (CAN_ELIMINATE): Add parens around && within ||. (INITIAL_ELIMINATION_OFFSET): Add braces to avoid ambiguous `else'. * cse.c (rehash_using_reg): Change type of variable `i' to unsigned int. * dwarf2out.c (initial_return_save): Cast -1 to unsigned before assigning it to one. * except.c (duplicate_eh_handlers): Remove unused variable `tmp'. * final.c (final_scan_insn): Likewise for variable `i'. (output_asm_insn): Cast a char to unsigned char when used as an array index. * gcse.c (compute_pre_ppinout): Cast -1 to SBITMAP_ELT_TYPE when assigning it to one. * loop.c (strength_reduce): Remove unused variables `count' and `temp'. * recog.c (preprocess_constraints): Cast a char to unsigned char when used as an array index. * regmove.c (find_matches): Likewise. * reload1.c (calculate_needs): Add default case in switch. (eliminate_regs_in_insn): Initialize variable `offset'. (set_offsets_for_label): Change type of variable `i' to unsigned. (reload_as_needed): Wrap variable `i' in macro check on AUTO_INC_DEC || INSN_CLOBBERS_REGNO_P. * scan-decls.c (scan_decls): Mark parameters `argc' and `argv' with ATTRIBUTE_UNUSED. Cast variable `start_written' to size_t when comparing against one. * stor-layout.c (layout_decl): Cast maximum_field_alignment to unsigned when comparing against one. Likewise for GET_MODE_ALIGNMENT(). (layout_record): Cast record_align to int when comparing against a signed value. (layout_type): Cast TYPE_ALIGN() to int when comparing against a signed value. * tree.c (get_identifier): Cast variable `len' to unsigned when comparing against one. (maybe_get_identifier): Likewise Wed Dec 23 00:10:01 1998 Jeffrey A Law (law@cygnus.com) * toplev.c (rest_of_compilation): Do not set reload_completed. * reload1.c (reload): Set reload_completed before calling cleanup_subreg_operands. Tue Dec 22 23:58:31 1998 Richard Henderson * reload1.c (emit_reload_insns): Check `set' not null before use. Tue Dec 22 15:15:45 1998 Nick Clifton * rtlanal.c (multiple_sets): Change type of 'found' from 'rtx' to 'int'. Tue Dec 22 13:55:44 1998 Theodore Papadopoulo * halfpic.c (half_pic_encode): Delete redundant code. Tue Dec 22 13:02:22 1998 Michael Meissner * toplev.c (main): Delete handling of -dM as a preprocessor option. Mon Dec 21 17:39:38 1998 Michael Meissner * toplev.c (main): Don't emit any warnings when using -dD, -dM, or -dI, which are handled by the preprocessor. Sun Dec 20 16:13:44 1998 John F. Carr * configure.in: Handle Digital UNIX 5.x the same as 4.x. * i386/sol2.h: Define LOCAL_LABEL_PREFIX as ".". Sun Dec 20 07:39:52 1998 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. Sat Dec 19 22:24:22 1998 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. Sat Dec 19 21:41:32 1998 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. Sat Dec 19 09:52:27 1998 Kaveh R. Ghazi * genattr.c (fatal): Qualify a char* with the `const' keyword. * genattrtab.c (fatal, attr_printf, attr_string, write_attr_set, write_unit_name, write_eligible_delay, expand_units, make_length_attrs, write_attr_case, find_attr, make_internal_attr): Likewise. * gencheck.c (tree_codes): Likewise. * gencodes.c (fatal): Likewise. * genconfig.c (fatal): Likewise. * genemit.c (fatal): Likewise. * genextract.c (fatal, walk_rtx, copystr): Likewise. * genflags.c (fatal): Likewise. * genopinit.c (fatal, optabs, gen_insn): Likewise. * genoutput.c (fatal, error, predicates): Likewise. * genpeep.c (fatal): Likewise. * genrecog.c (fatal, decision, pred_table, add_to_sequence, write_tree_1, write_tree, change_state, copystr, indents): Likewise. Thu Dec 17 18:21:49 1998 Rainer Orth * configure.in (with-fast-fixincludes): Fix whitespace. * configure: Rebuilt. * fixincludes (c_asm.h): Wrap Digital UNIX V4.0B DEC C specific asm() etc. function declarations in __DECC. Thu Dec 17 13:57:23 1998 Nick Clifton * expr.c (emit_move_insn_1): Only emit a clobber if the target is a pseudo register. Thu Dec 17 13:50:29 1998 Nick Clifton * gcse.c: Include expr.h in order to get the prototype for get_condition() which is used in delete_null_pointer_checks(). Thu Dec 17 15:58:26 1998 Kaveh R. Ghazi * hwint.h: New file to consolidate HOST_WIDE_INT (etc) macros. Thu Dec 17 12:31:12 1998 Jim Wilson * Makefile.in (INTERNAL_CFLAGS): Add SCHED_CFLAGS. (ALL_CFLAGS): Delete SCHED_CFLAGS. 1998-12-17 Vladimir N. Makarov * config/i60/i960.md (extendqihi2): Fix typo (usage ',' instead of ';'). 1998-12-17 Michael Tiemann * i960.md (extend*, zero_extend*): Don't generate rtl that looks like (subreg:SI (reg:SI N) 0), because it's wrong, and it hides optimizations from the combiner. Thu Dec 17 08:27:03 1998 J"orn Rennecke * loop.c (combine_givs_used_by_other): Don't depend on n_times_set. Wed Dec 16 17:30:35 1998 Nick Clifton * toplev.c (main): Disable optimize_size if a specific optimization level is requested. Always set optimization level to 2 if -Os is specified. Wed Dec 16 16:33:04 1998 Dave Brolley * objc/lang-specs.h: Pass -MD, -MMD and -MG to cc1obj if configured with cpplib. * cpplib.c (cpp_start_read): If in_fname is not initialized, try to initialize it using fname. 1998-12-16 Zack Weinberg * cpplib.c (do_include): Treat #include_next in the primary source file as #include plus warning. Treat #include_next in a file included by absolute path as an error. fp == CPP_NULL_BUFFER is a fatal inconsistency. Wed Dec 16 12:28:54 1998 Kaveh R. Ghazi * cccp.c: Don't define MIN/MAX anymore. * cpplib.c: Likewise. * machmode.h: Likewise. * system.h: Provide definitions for MIN/MAX. Tue Dec 15 23:47:42 1998 Zack Weinberg * fix-header.c: Don't define xstrdup here. Wed Dec 16 05:11:04 1998 J"orn Rennecke * loop.c (consec_sets_giv): New argument last_consec_insn. (strength_reduce): Provide / use it. Wed Dec 16 17:24:07 1998 Michael Hayes * loop.h (loop_info): New field 'vtop'. * loop.c (check_dbra_loop): Use loop_info->vtop rather than scanning loop for vtop. * unroll.c (subtract_reg_term, find_common_reg_term): New functions. (loop_iterations): Use them to determine if loop has a constant number of iterations. Set loop_info->vtop. Don't subtract common reg term from initial_value and final_value if have a do-while loop. Tue Dec 15 13:49:55 1998 Jeffrey A Law (law@cygnus.com) * mn10200.md (addsi3 expander): Use "nonmemory_operand" for operand 2. * mn10300.md (bset, bclr): Operand 0 is a read/write operand. * mn10200.md (abssf2, negsf2): New expanders. * mn10300.md (absdf2, abssf2, negdf2, negsf2): New expanders. Tue Dec 15 11:55:30 1998 Nick Clifton * integrate.c (copy_rtx_and_substitute): If a SUBREG is replaced by a CONCAT whose components do not have the same mode as the original SUBREG, use a new SUBREG to restore the mode. * emit-rtl.c (subreg_realpart_p): Cope with subregs containing multiword complex values. 1998-12-15 Zack Weinberg * cppalloc.c: Add xstrdup here. * cpplib.h: Remove savestring prototype. * cpplib.c: Remove savestring function. s/savestring/xstrdup/ throughout. * cppfiles.c: s/savestring/xstrdup/ throughout. 1998-12-15 Zack Weinberg * cpplib.c: Make all directive handlers read their own arguments. (struct directive): Remove last two arguments from FUNC member prototype. Remove `command_reads_line' member entirely. (directive_table): Remove initializations of command_reads_line flag. Pretty-print. (eval_if_expression, do_define, do_line, do_include, do_undef, do_error, do_pragma, do_ident, do_if, do_xifdef, do_else, do_elif, do_sccs, do_assert, do_unassert, do_warning): Take only two args. (cpp_define): Call do_define with two args and the text to define stuffed into a buffer. (make_assertion): Call do_assert with two args. (handle_directive): Call do_line with two args. Call kt->func with two args. Remove command_reads_line processing. (do_define, do_undef, do_error, do_warning, do_pragma, do_sccs): Read the rest of the line here. (do_ident): Gobble rest of line, as cccp does. (cpp_undef): New function. (cpp_start_read): Call cpp_undef instead of do_undef. 1998-12-15 Zack Weinberg * cpphash.h (union hash_value): Remove `keydef' member, add a `struct hashnode *aschain' member for #assert. * cpplib.c (struct tokenlist_list, struct assertion_hashnode): Delete structure definitions. (assertion_install, assertion_lookup, delete_assertion, check_assertion, compare_token_lists, reverse_token_list, read_token_list, free_token_list): Delete functions. (parse_assertion): New function. (cpp_cleanup): Don't destroy the assertion_hashtable. (do_assert): Gut and rewrite. #assert foo (bar) places entries for `#foo' and `#foo(bar)' in the macro hash table, type T_ASSERT. The value union's `aschain' member is used to chain all answers for a given predicate together. (do_unassert): Also rewritten. Take an un-asserted answer off the chain from its predicate and call delete_macro on the hashnode, or walk a predicate chain calling delete_macro on all the entries. (cpp_read_check_assertion): Simply call parse_assertion to get the canonical assertion name, and look that up in the hash table. * cpplib.h (ASSERTION_HASHNODE,ASSERTION_HASHSIZE,assertion_hashtab): Removed. * cpphash.c (install): Use bcopy instead of an explicit loop to copy the macro name. * cppexp.c (cpp_lex): Convert the result of cpp_read_check_assertion to a `struct operation' directly; don't go through parse_number. Tue Dec 15 18:27:39 1998 J"orn Rennecke * loop.h (struct induction): Delete times_used member. * loop.c (n_times_set): Rename to set_in_loop. Changed all users. (n_times_used): Rename to n_times_set. Changed all users. (scan_loop): Free reg_single_usage before strength reduction. (record_giv, combine_givs): Remove handling of times_used member. (combine_givs_used_once): Rename to: (combine_givs_used_by_other) . Changed all callers. Tue Dec 15 01:45:26 1998 Jason Merrill * dwarf2out.c (gen_struct_or_union_type_die): Check AGGREGATE_TYPE_P instead of TREE_CODE_CLASS == 't'. (gen_type_die): Likewise. (scope_die_for): Ignore FUNCTION_TYPE "scopes". Mon Dec 14 16:23:27 1998 Jim Wilson * real.c (endian): Disable last change unless HOST_BITS_PER_WIDE_INT is greater than 32. Mon Dec 14 17:13:36 1998 Andrew MacLeod * output.h (force_data_section): New prototype. * varasm.c (force_data_section): New function to force the data section, regardless of what in_section thinks. * dwarf2out.c (output_call_frame_info): Call force_data_section since varasm may not realize we've changes sections. Mon Dec 14 14:09:34 1998 Nick Clifton * reload1.c (reload): Delete REG_RETVAL and REG_LIBCALL notes after completing reload. * rtl.texi: Document that REG_RETVAL and REG_LIBCALL are deleted after reload. Mon Dec 14 01:39:28 1998 Jeffrey A Law (law@cygnus.com) * rtl.h (multiple_sets): Fix prototype. * rtlanal.c (multiple_sets): Fix return type. Sun Dec 13 12:43:58 1998 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. Sun Dec 13 01:05:22 1998 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. 1998-12-13 Manfred Hollstein * protoize.c (fputs): Wrap extern declaration in #ifndef fputs. Sun Dec 13 00:24:14 1998 J"orn Rennecke * rtl.h (recompute_reg_usage): Add second argument. * flow.c (recompute_reg_usage): Likewise. * toplev.c (rest_of_compilation): Supply second argument to recompute_reg_usage. * reload1.c (compute_use_by_pseudos): Allow reg_renumber[regno] < 0 after reload. Sat Dec 12 23:39:10 1998 Jeffrey A Law (law@cygnus.com) * m68k/t-m68kelf (MULTILIB_OPTIONS): Add mcpu32. (MULTILIB_MATCHES): -m68332 now uses mcpu32 libraries, not m68000. (MULTILIB_EXCEPTIONS): Don't build 68881 libraries for m68000, mcpu32 or m5200. * i386/next.h (ASM_OUTPUT_ALIGN): Use 0x90 for fill character. * rtlanal.c (multiple_sets): New function. * rtl.h (multiple_sets): Declare it. * local-alloc.c (wipe_dead_reg): Use it. * global.c (global_conflicts): Likewise. Sat Dec 12 22:13:02 1998 Mark Mitchell * global.c (record_conflicts): Don't use an array of shorts to store an array of ints. (global_conflicts): Likewise. Sat Dec 12 16:49:24 1998 Richard Henderson * alpha.c (alpha_expand_block_move): mode_for_size expects bits, not bytes. Infer extra alignment from addressof. 1998-12-11 Michael Meissner * rs6000/sysv4.h (ASM_OUTPUT_ALIGNED_LOCAL): Put small data in the .sbss section, not .sdata. 1998-12-11 Manfred Hollstein * cccp.c: Do not #include here; this is already done by "system.h". * collect2.c: Likewise. * cpplib.h: Likewise. * gcc.c: Likewise. * gcov.c: Likewise. * getpwd.c: Likewise. * protoize.c: Likewise. * toplev.c: Likewise. * cpplib.h (HOST_WIDE_INT): Get definition from "machmode.h" and don't try to define it here. * Makefile.in (cppmain.o): Depend on machmode.h. (cpplib.o): Likewise. (cpperror.o): Likewise. (cppexp.o): Likewise. (cppfiles.o): Likewise. (cpphash.o): Likewise. (cppalloc.o): Likewise. (fix-header.o): Likewise. (scan-decls.o): Likewise. Fri Dec 11 11:02:49 1998 Stan Cox * sh.c (print_operand): Lookup interrupt_handler attribute instead of relying on static variable. * (calc_live_regs): Likewise. * (sh_pragma_insert_attributes): Create interrupt_handler attribute if a pragma was specified. * (sh_valid_machine_decl_attribute): Don't set static flag. * sh.h (PRAGMA_INSERT_ATTRIBUTES): New. Fri Dec 11 12:56:07 1998 J"orn Rennecke * reload1.c (reload_combine): Use BASIC_BLOCK_LIVE_AT_START to determine if a register is live at a jump destination. Everything is dead at a BARRIER. Thu Dec 10 16:02:06 1998 Jim Wilson * cse.c (simplify_unary_operation): Sign-extend constants when they have the most significant bit set for the target. * real.c (endian): Sign-extend 32 bit output values on a 64 bit host. * m32r/m32r.c (m32r_expand_prologue): Store pretend_size in HOST_WIDE_INT temporary before negating it. * m32r/m32r.md (movsi_insn+1): Use ~0xffff instead of 0xffff0000. Thu Dec 10 15:05:59 1998 Dave Brolley * objc/objc-act.c (lang_init_options): Enclose cpplib related code in #if USE_CPPLIB. Thu Dec 10 13:39:46 1998 Kaveh R. Ghazi * collect2.h: New header file for prototypes. * Makefile.in (collect2.o, tlink.o): Depend on collect2.h. * collect2.c: Include collect2.h. * tlink.c: Likewise. Wed Dec 9 23:55:11 1998 Jeffrey A Law (law@cygnus.com) * flow.c: Update some comments. Wed Dec 9 15:29:26 1998 Dave Brolley * objc/objc-act.c (cpp_initialized): Removed. (lang_init_options): Initialize cpplib. (lang_decode_option): Move initialization of cpplib to lang_init_options. * c-lang.c (parse_options,parse_in): Added. (lang_init_options): Initialized cpplib here. * c-decl.c (parse_options,cpp_initialized): Removed. (c_decode_option): Move initialization of cpplib to lang_init_options. Wed Dec 9 19:36:57 1998 J"orn Rennecke * reload1.c (reload_combine, reload_combine_note_store): Make STORE_RUID always valid. (reload_combine): Check if BASE is clobbered too early. Wed Dec 9 09:53:58 1998 Nick Clifton * reload.c (find_reloads): Display the insn that cannot be reloaded. Wed Dec 9 12:15:26 1998 Dave Brolley * cccp.c (create_definition): Fix end of buffer logic. Wed Dec 9 10:15:45 1998 Kaveh R. Ghazi * except.c (duplicate_eh_handlers, rethrow_symbol_map): Function pointer parameters changed to use the PARAMS() macro. Wed Dec 9 09:12:40 1998 Andrew MacLeod * except.h (struct handler_info): Add handler_number field. * except.c (gen_exception_label): EH labels no longer need to be on the permanent obstack. (get_new_handler): Set the label number field. (output_exception_table_entry): Regenerate handler label reference from the label number field. (init_eh): Remove a blank line. * integrate.c (get_label_from_map): Labels no longer need to be on the permanent obstack. Tue Dec 8 22:04:33 1998 Jim Wilson * i960/i960.h (CONST_COSTS, case CONST_INT): Accept power2_operand only when OUTER_CODE is SET. Tue Dec 8 22:47:15 1998 J"orn Rennecke * loop.c (strength_reduce): If scan_start points to the loop exit test, be wary of subversive use of gotos inside expression statements. Don't set maybe_multiple for a backward jump that does not include the label under consideration into its range. * unroll.c (biv_total_increment): Make use of maybe_multiple field. Tue Dec 8 22:33:18 1998 J"orn Rennecke * explow.c (plus_constant_wide): Don't immediately return with result of recursive call. Tue Dec 8 15:32:56 1998 Andrew MacLeod * eh-common.h (struct eh_context): Add table_index for rethrows. * rtl.h (enum reg_note): Add REG_EH_REGION and REG_EH_RETHROW reg notes. (SYMBOL_REF_NEED_ADJUST): New flag indicating symbol needs to be processed when inlined or unrolled (ie duplicated in some way). * rtl.c (reg_note_name): Add strings for new reg_note enums. * expr.h (rethrow_libfunc): New library decl. * optabs.c (rethrow_libfunc): Initialize. * except.h (struct eh_entry): Add new field 'rethrow_label'. (new_eh_region_entry): No longer exported from except.c. (duplicate_handlers): Renamed to duplicate_eh_handlers and different prototype. (rethrow_symbol_map, rethrow_used): New exported functions. (eh_region_from_symbol): New exported function. * except.c (create_rethrow_ref): New function to create a single SYMBOL_REF for a rethrow region. (push_eh_entry): Initialize a rethrow ref. (func_eh_entry): Add a rethrow_label field. (new_eh_region_entry): Make static, and initialize the rethrow entry. (duplicate_eh_handlers): Create a new region, and remap labels/symbols. (eh_region_from_symbol): Find an EH region based on its rethrow symbol. (rethrow_symbol_map): Given a label map, maps a rethrow symbol for a region into an appropriate new symbol. (rethrow_used): Indicate whether a rethrow symbol has been referenced. (expand_eh_region_end): Don't issue jump around code for new-exceptions. (end_catch_handler): Emit a barrier for new-exceptions since control can never drop through the end of a catch block. (expand_end_all_catch): new-exceptions never fall through a catch block. (expand_rethrow): Use __rethrow routine for new exceptions. (output_exception_table_entry): Generate rethrow labels, if needed. (output_exception_table): Generate start and end rethrow labels. (init_eh): Create rethrow symbols for beginning and end of table. (scan_region): Don't eliminate EH regions which are the targets of rethrows. * flow.c (make_edges): Add different edges for rethrow calls, identified by having the REG_EH_RETHROW reg label. (delete_unreachable_blocks): Don't delete regions markers which are the target of a rethrow. * integrate.c (save_for_inline_eh_labelmap): New callback routine to allow save_for_inline_copying to call duplicate_eh_handlers. (save_for_inline_copying): Call duplicate_eh_handlers instead of exposing internal details of exception regions. (copy_for_inline): Check if SYMBOL_REFs need adjustment. (expand_inline_function_eh_labelmap): New callback routine to allow expand_inline_function to call duplicate_eh_handlers. (expand_inline_function): Call duplicate_eh_handlers instead of exposing internal details of exception regions. (copy_rtx_and_substitute): Adjust SYMBOL_REFS if SYMBOL_REF_NEED_ADJUST flag is set. * libgcc2.c (find_exception_handler): Generalize to enable it to pick up processing where it left off last time for a rethrow. (__unwinding_cleanup): New function. debug hook which is called before unwinding when __throw finds there is nothing but cleanups left. (throw_helper): Common parts of __throw extracted out for reuse. (__throw): Common parts moved to throw_helper. (__rethrow): New function for performing rethrows. Tue Dec 8 13:11:04 1998 Jeffrey A Law (law@cygnus.com) * reload1.c (current_function_decl): Tweak declaration. Tue Dec 8 10:23:52 1998 Richard Henderson * c-decl.c (flag_isoc9x): Default off. (c_decode_option): Kill -std=gnu, add -std=gnu89 and -std=gnu9x. * cccp.c (print_help, main): Likewise. * gcc.c (default_compilers): Update for -std=gnu*. Tue Dec 8 01:14:46 1998 Jeffrey A Law (law@cygnus.com) * Makefile.in (DEMANGLE_H): Change location to shared demangle.h. * demangle.h: Deleted. * reload1.c (current_function_decl): Declare. Tue Dec 8 11:58:51 1998 Kaveh R. Ghazi * cpplib.c (convert_string): Use `0x00ff', not `0x00ffU'. Tue Dec 8 09:28:36 1998 Kaveh R. Ghazi * dbxout.c: If USG is defined use gstab.h, even if HAVE_STAB_H is set. 1998-12-08 Ulrich Drepper * configure.in: Test for availability of putc_unlocked, fputc_unlocked, and fputs_unlocked. * configure: Rebuilt. * system.h: If the *_unlocked functions are available use them instead of the locked counterparts by defining macros. * config.in: Regenerated. Tue Dec 8 00:34:05 1998 Mike Stump * i386/bsd.h (ASM_FILE_START): Don't use dump_base_name, it is wrong and should only be used for dump related things, not debugging information, instead main_input_filename should be used. Also, reuse output_file_directive if possible. * i386/aix386ng.h (ASM_FILE_START): Likewise. * i386/isc.h (ASM_FILE_START): Likewise. * i386/win-nt.h (ASM_FILE_START): Likewise. * i386/sun386.h (ASM_FILE_START): Likewise. Mon Dec 7 23:56:28 1998 Robert Lipe * configure.in (mips*-*-linux*): Handle big and little endian systems. * configure: Rebuilt. Mon Dec 7 23:14:51 1998 Mike Stump * emit-rtl.c: Fix typo. Mon Dec 7 23:07:38 1998 Nathan Sidwell * reload1.c (eliminate_regs): Don't do anything, if we're not generating code. Mon Dec 7 15:27:09 1998 DJ Delorie * mips/mips.h (ENCODE_SECTION_INFO): Handle TARGET_EMBEDDED_DATA. Add comment. * mips/mips.c (mips_select_section): Add comment. Mon Dec 7 17:55:06 1998 Mike Stump * cccp.c (ignore_escape_flag): Add support for \ as `natural' characters in file names in #line to be consistent with #include handling. We support escape processing in the # 1 "..." version of the command. See also support in cp/lex.c. (handle_directive): Likewise. (do_line): Likewise. 1998-12-07 Zack Weinberg * cpplib.c (initialize_char_syntax): Use ISALPHA and ISALNUM so it'll work on non-ASCII platforms. Always consider $ an identifier character. Take no arguments. (cpp_reader_init): Call initialize_char_syntax with no arguments. (cpp_start_read): Don't call initialize_char_syntax again. Clear is_idchar['$'] and is_idstart['$'] if not opts->dollars_in_ident. * cpplib.h (struct cpp_reader): Replace void *data element by cpp_options *opts. Rearrange elements to make gdb printout less annoying (put buffer stack at end). (CPP_OPTIONS): Get rid of now-unnecessary cast. * cppmain.c: s/data/opts/ when initializing cpp_reader structure. * c-decl.c: Likewise. * objc/objc-act.c: Likewise. * fix-header.c: Likewise. 1998-12-07 Zack Weinberg * cpplib.h (struct cpp_buffer): Replace dir and dlen members with a struct file_name_list pointer. (struct cpp_reader): Add pointer to chain of `actual directory' include searchpath entries. (struct file_name_list): Add *alloc pointer for the sake of the actual-directory chain. Move definition of HOST_WIDE_INT here. (cpp_parse_escape): Change prototype to match changes in cppexp.c. * cppfiles.c (actual_directory): New function. (finclude): Use it to initialize the buffer's actual_dir entry. (find_include_file): We don't need to fix up max_include_len here. * cpplib.c (do_include): Don't allocate a file_name_list on the fly for current directory "" includes, use the one that's been preallocated in pfile->buffer->actual_dir. Hoist out duplicate code from the search_start selection logic. (cpp_reader_init): Initialize pfile->actual_dirs. Remove definition of HOST_WIDE_INT. Change calls to cpp_parse_escape to match changes in cppexp.c (note hardcoded MASK, which is safe since this is the source character set). * cppexp.c: Bring over changes to cpp_parse_escape from cccp.c to handle wide character constants in #if directives. The function now returns a HOST_WIDE_INT, and takes a third argument which is a binary mask for all legal values (0x00ff for 8-bit `char', 0xffff for 16-bit `wchar_t', etc.) Define MAX_CHAR_TYPE_MASK and MAX_WCHAR_TYPE_MASK. Change callers of cpp_parse_escape to match. [Fixes c-torture/execute/widechar-1.c] Mon Dec 7 15:38:25 1998 Dave Brolley * gcc.c (default_compilers): Fix typo in USE_CPPLIB spec for cc1. Mon Dec 7 15:38:25 1998 Kaveh R. Ghazi * c-aux-info.c (concat): Wrap function definition in !USE_CPPLIB. * cppalloc.c: Move function `xcalloc' from cpplib.c to here. * cpplib.c: Move function `xcalloc' from here to cppalloc.c. Mon Dec 7 11:30:49 1998 Nick Clifton * final.c (output_asm_name): Use tabs to separate comments from assembly text. Include instruction lengths (if defined) in output. Mon Dec 7 10:53:38 1998 Michael Hayes * loop.c (check_dbra_loop): Fix initial_value and initial_equiv_value in the loop_info structure. Mon Dec 7 11:04:40 1998 Catherine Moore * configure.in (arm*-*-ecos-elf): New target. * configure: Regenerated. * config/arm/elf.h (ASM_WEAKEN_LABEL): Define. * config/arm/ecos-elf.h: New file. * config/arm/unknown-elf.h (TARGET_VERSION): Check for redefinition. Mon Dec 7 16:15:51 1998 J"orn Rennecke * sh.c (output_far_jump): Emit braf only for TARGET_SH2. Sun Dec 6 04:19:45 1998 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. Sun Dec 6 05:16:16 1998 Michael Hayes * loop.c (check_dbra_loop): New argument loop_info. Update fields as needed. Sun Dec 6 03:40:13 1998 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. Sun Dec 6 07:49:29 1998 Alexandre Oliva * gcc.texi (Bug Reporting): 40Kb is a soft limit, larger compressed reports are ok and preferred over URLs. Sun Dec 6 07:45:33 1998 Alexandre Oliva * invoke.texi (Warning Options): Soften the tone of -pedantic. Sun Dec 6 00:20:44 1998 H.J. Lu (hjl@gnu.org) * print-rtl.c (print_rtx): Add prototype. * unroll.c (iteration_info): Make it static. Sun Dec 6 01:19:46 1998 Richard Henderson * alias.c (memrefs_conflict_p): A second ANDed address disables the aligned address optimization. Sat Dec 5 18:48:25 1998 Richard Henderson * alpha.c (alpha_emit_set_const_1): Fix parenthesis error in -c << n case. Sat Dec 5 15:14:52 1998 Jason Merrill * i960.h (BOOL_TYPE_SIZE): Define. Sun Dec 6 00:28:16 1998 Michael Hayes * config/c4x/c4x.c (valid_parallel_load_store): Flog functionality from old valid_parallel_operands_4. (valid_parallel_operands_4): Check that operands for 4 operand parallel insns are valid, excluding load/store insns. * config/c4x/c4x.h (valid_parallel_load_store): Add prototype. * config/c4x/c4x.md (*movqf_parallel, *movqi_parallel): Use valid_parallel_load_store instead of valid_parallel_operands_4. (*absqf2_movqf_clobber, *floatqiqf2_movqf_clobber, *negqf2_movqf_clobber, *absqi2_movqi_clobber, *fixqfqi2_movqi_clobber, *negqi2_movqi_clobber, *notqi_movqi_clobber): Use valid_parallel_operands_4. (*subqf3_movqf_clobber, *ashlqi3_movqi_clobber, *ashrqi3_movqi_clobber, *lshrqi3_movqi_clobber, *subqi3_movqi_clobber): Use valid_parallel_operands_5. Sat Dec 5 23:52:01 1998 Michael Hayes * config/c4x/c4x.c (iteration_info): Delete extern. Fri Dec 4 20:15:57 1998 Bernd Schmidt * tm.texi (SMALL_REGISTER_CLASSES): Make description match reality. * final.c (cleanup_subreg_operands): Delete some unused code. * recog.h (MAX_RECOG_ALTERNATIVES): New macro. (struct insn_alternative): New structure definition. (recog_op_alt): Declare variable. (preprocess_constraints): Declare function. * recog.c (recog_op_alt): New variable. (extract_insn): Verify number of alternatives is in range. (preprocess_constraints): New function. * reg-stack.c: Include recog.h. (constrain_asm_operands): Delete. (get_asm_operand_lengths): Delete. (get_asm_operand_n_inputs): New function. (record_asm_reg_life): Delete OPERANDS, CONSTRAINTS, N_INPUTS and N_OUTPUTS args. All callers changed. Compute number of inputs and outputs here by calling get_asm_operand_n_inputs. Instead of constrain_asm_operands, call extract_insn, constrain_operands and preprocess_constraints. Use information computed by these functions throughout. (record_reg_life): Delete code that is unused due to changes in record_asm_reg_life. (subst_asm_stack_regs): Delete OPERANDS, OPERAND_LOC, CONSTRAINTS, N_INPUTS and N_OUTPUTS args. All callers changed. Similar changes as in record_asm_reg_life. (subst_stack_regs): Move n_operands declaration into the if statement where it's used. Delete code that is unused due to changes in subst_asm_stack_regs. * stmt.c (expand_asm_operands): Verify number of alternatives is in range. * Makefile.in (reg-stack.o): Depend on recog.h. Fri Dec 4 02:23:24 1998 Jeffrey A Law (law@cygnus.com) * except.c (set_exception_version_code): Argument is an "int". Fri Dec 4 01:29:28 1998 Jeffrey A Law (law@cygnus.com) * configure.in (hppa2*-*-*): Handle like hppa1.1-*-* for now. * configure: Rebuilt. Fri Dec 4 01:29:28 1998 Robert Lipe * configure.in (mipsel-*-linux*): New target. * mips/linux.h: New file, based on other Linux targets. Thu Dec 3 11:19:50 1998 Mike Stump * gthr-vxworks.h (__ehdtor): Fix memory leak. The delete hook runs in the context of the deleter, not the deletee, so we must use taskVarGet to find the correct memory to free. (__gthread_key_create): Initialize the task variable subsystem so that the task variable is still active when the delete hook is run. 1998-12-03 Joseph S. Myers * pdp11.h: Use optimize_size for space optimizations. * pdp11.c: Likewise. * pdp11.md: Likewise. * pdp11.h (TARGET_40_PLUS): Fix typo. Thu Dec 3 11:48:32 1998 Jeffrey A Law (law@cygnus.com) * local-alloc.c (block_alloc): Slightly retune heuristic to widen qty lifetimes. Thu Dec 3 22:30:18 1998 Michael Hayes * alias.c (addr_side_effect_eval): New function. (memrefs_conflict_p): Use it. * rtl.h (addr_side_effect_eval): Prototype it. 1998-12-02 Joseph S. Myers * pdp11.md (extendsfdf2): Fix mode mismatch in SET. Wed Dec 2 11:23:07 1998 Jim Wilson * reload.c (find_reloads): When force const to memory, put result in substed_operand not *recog_operand_loc. 1998-12-02 Ulrich Drepper * c-lex.c: Fix indentation from last patch. Remove trailing whitespace. * real.c: Likewise. Wed Dec 2 10:11:12 1998 Jeffrey A Law (law@cygnus.com) * flow.c (delete_block): Call set_last_insn after we have reset NEXT_INSN (kept_tail). Wed Dec 2 00:47:31 1998 Jeffrey A Law (law@cygnus.com) * mips.md (trap_if): Use "$0" for the value zero. Tue Dec 1 20:49:49 1998 Ulrich Drepper Stephen L Moshier Richard Henderson * c-common.c (declare_function_name): Declare predefined variable `__func__'. * c-decl.c (flag_isoc9x): Set to 1 by default. (c_decode_option): Handle -std= option. Remove -flang-isoc9x. (grokdeclarator): Always emit warning about implicit int for ISO C 9x. * c-parse.in: Allow constructors in ISO C 9x. Rewrite designator list handling. Allow [*] parameters. Don't warn about comma at end of enum definition for ISO C 9x. * cccp.c (c9x): New variable. (rest_extension): New variable. (print_help): Document new -std= option. (main): Recognize -std= option. Set c9x appropriately. (create_definition): Recognize ISO C 9x vararg macros. * gcc.c (default_compilers): Adjust specs for -std options. (option_map): Add --std. (display_help): Document -std. * toplev.c (documented_lang_options): Add -std and remove -flang-isoc9x. * c-lex.c (yylex): Recognize hex FP constants and call REAL_VALUE_ATOF or REAL_VALUE_HTOF based on base of the constants. * fold-const.c (real_hex_to_f): New function. Replacement function for hex FP conversion if REAL_ARITHMETIC is not defined. * real.c (asctoeg): Add handling of hex FP constants. * real.h: Define REAL_VALUE_HTOF if necessary using ereal_atof or real_hex_to_f. Tue Dec 1 16:45:49 1998 Stan Cox * mips.md (divmodsi4*, divmoddi4*, udivmodsi4*, udivmoddi4): Add -mcheck-range-division/-mcheck-zero-division checking. Avoid as macro expansion. Use hi/lo as destination register. (div_trap): New. (divsi3*, divdi3*, modsi3*, moddi3*, udivsi3*, udivdi3*, umodsi3*, umoddi3*): Add -mcheck-range-division/-mcheck-zero-division checking. Avoid as macro expansion. Use hi/lo as destination register. * mips.h (MASK_CHECK_RANGE_DIV): New. (MASK_NO_CHECK_ZERO_DIV): New. (ELIMINABLE_REGS): Added GP_REG_FIRST + 31. (CAN_ELIMINATE, INITIAL_ELIMINATION_OFFSET): Allow for getting return address for leaf functions out of r31 to support builtin_return_address. Tue Dec 1 15:03:30 1998 Herman A.J. ten Brugge * jump.c (jump_optimize): Call regs_set_between_p with PREV_INSN(x), NEXT_INSN(x) to check insn x. Tue Dec 1 15:20:44 1998 Jeffrey A Law (law@cygnus.com) * flow.c (delete_block): Call set_last_insn if we end up deleting the last insn in the rtl chain. * reload1.c (reload): Do not set reload_completed or split insns here. Instead... * toplev.c (rest_of_compilation): Set reload_completed after reload returns. Split insns after reload_cse has run. Tue Dec 1 11:55:04 1998 Richard Henderson * final.c (final_scan_insn): Abort if block_depth falls below 0. Tue Dec 1 10:23:16 1998 Nick Clifton * config/arm/t-arm-elf (LIBGCC2_CFLAGS): Define inhibit_libc. Tue Dec 1 10:22:18 1998 Nick Clifton * config/arm/unknown-elf.h (ASM_OUTPUT_DWARF2_ADDR_CONST): Remove use of user-label_prefix. Tue Dec 1 17:58:26 1998 J"orn Rennecke * reload1.c (emit_reload_insns): Clear spill_reg_store when doing a new non-inherited reload from the same pseudo. * local-alloc.c (function_invariant_p): New function. (update_equiv_regs): Use function_invariant_p instead of CONSTANT_P to decide if an equivalence should be recorded. * reload1.c (num_eliminable_invariants): New static variable. (reload): Set it. Use function_invariant_p instead of CONSTANT_P to decide if an equivalence should be recorded. Unshare PLUS. (calculate_needs_all_insns): Skip insns that only set an equivalence. Take num_eliminable_invariants into account when deciding if register elimination should be done. (reload_as_needed): Take num_eliminable_invariants into account when deciding if register elimination should be done. (eliminate_regs): Handle non-constant reg_equiv_constant. * rtl.h (function_invariant_p): Declare. Mon Nov 30 02:00:08 1998 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. Mon Nov 30 00:42:59 1998 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. Sun Nov 29 22:59:40 1998 Jason Merrill * except.c (add_new_handler): Complain about additional handlers after one that catches everything. Sat Nov 28 10:56:32 1998 Jeffrey A Law (law@cygnus.com) * configure.in (alpha*-*-netbsd): Fix typo. * configure: Rebuilt. Fri Nov 27 12:28:56 1998 Kaveh R. Ghazi * system.h: Include libiberty.h. * c-aux-info.c: Remove prototypes for concat/concat3. Change function `concat' from fixed parameters to variable parameters, as is done in libiberty. All callers of concat/concat3 changed to use the new `concat' with variable args. * cccp.c: Remove things made redundant by libiberty.h and/or conform to libiberty standards. * cexp.y: Likewise. * collect2.c: Likewise. * config/1750a/1750a.h: Likewise. * cppalloc.c: Likewise. * cppexp.c: Likewise. * cppfiles.c: Likewise. * cpphash.c: Likewise. * cpplib.c: Likewise. * dyn-string.c: Likewise. * fix-header.c: Likewise. * gcc.c: Likewise. * gcov.c: Likewise. * genattr.c: Likewise. * genattrtab.c: Likewise. * gencheck.c: Likewise. * gencodes.c: Likewise. * genconfig.c: Likewise. * genemit.c: Likewise. * genextract.c: Likewise. * genflags.c: Likewise. * gengenrtl.c: Likewise. * genopinit.c: Likewise. * genoutput.c: Likewise. * genpeep.c: Likewise. * genrecog.c: Likewise. * getpwd.c: Likewise. * halfpic.c: Likewise. * hash.c: Likewise. * mips-tdump.c: Likewise. Wrap malloc/realloc/calloc prototypes in NEED_DECLARATION_* macros. * mips-tfile.c: Remove things made redundant by libiberty.h and/or conform to libiberty standards. (fatal): Fix const-ification of variable `format' in !ANSI_PROTOTYPES case. * prefix.c: Remove things made redundant by libiberty.h and/or conform to libiberty standards. * print-rtl.c: Rename variable `spaces' to `xspaces' to avoid conflicting with function `spaces' from libiberty. * profile.c: Remove things made redundant by libiberty.h and/or conform to libiberty standards. * protoize.c: Likewise. * rtl.h: Likewise. * scan.h: Likewise. * tlink.c: Likewise. * toplev.c: Likewise. * toplev.h: Likewise. * tree.h: Likewise. Thu Nov 26 08:38:06 1998 Kaveh R. Ghazi * cppfiles.c (simplify_pathname): Un-ANSI-fy function definition. Thu Nov 26 23:45:37 1998 Michael Hayes * README.C4X: Updated URLs. * config/c4x/c4x.c (c4x_address_conflict): Fix typo. (valid_parallel_operands_5): Remove unused variable. Thu Nov 26 23:40:03 1998 Michael Hayes * config/c4x/c4x.h (TARGET_DEFAULT): Fix typo. 1998-11-26 Manfred Hollstein * Makefile.in (CONFIG_LANGUAGES): New macro taking all languages which can be configured. (LANGUAGES): Use $(CONFIG_LANGUAGES) instead of @all_languages@ (Makefile): Pass actual LANGUAGES through the environment when re-configuring. (cstamp-h): Likewise. (config.status): Likewise. * configure.in (enable_languages): Add new configuration parameter "--enable-languages=lang1,lang2,...". (${srcdir}/*/config-lang.in): Change handling to configure only those directories, that the user might have enabled; default to "all" existing languages. * configure: Regenerate. Thu Nov 26 00:19:19 1998 Richard Henderson * rtlanal.c (regs_set_between_p): New function. * rtl.h (regs_set_between_p): Prototype it. * jump.c (jump_optimize): Use it instead of modified_between_p in the Sep 2 change. Wed Nov 25 23:32:02 1998 Ian Dall Matthias Pfaller * invoke.texi (Option Summary, NS32K Options): Add description of NS32K specific options. * ns32k.md (tstdf, cmpdf, movdf, truncdfsf2, fixdfqi2, fixdfhi2, fixdfsi2, fixunsdfqi2, fixunsdfhi2, fixunsdfsi2, fix_truncdfqi2, fix_truncdfhi2, fix_truncdfsi2, adddf3, subdf3, muldf3, divdf3, negdf2, absdf2): Use l instead of f since the double class and float class are no longer the same. (cmpsi, truncsiqi2, truncsihi2, addsi3, subsi3, mulsi3, umulsidi3, divsi3, modsi3, andsi3, iorsi3, xorsi3, negsi2, one_cmplsi2, ashlsi3, ashlhi3, ashlqi3, rotlsi3, rotlhi3, rotlqi3, abssi2,...): Use "g" instead of "rmn" since LEGITIMATE_PIC_OPERAND has been fixed. (cmpsi, cmphi, cmpqi): Use general_operand instead of non_immediate_operand. Removes erroneous assumption that can't compare constants. (movsf, movsi, movhi, movqi,...): New register numbering scheme. (movsi, addsi3): Use NS32K_DISPLACEMENT_P instead of hard coded constants. (movstrsi, movstrsi1, movstrsi2): Completely new block move scheme. (...): Patterns to exploit multiply-add instructions. (udivmodsi4, udivmodsi_internal4, udivmodhi4, udivmoddihi4_internal, udivmodqi4, udivmoddiqi4_internal): New patterns to exploit extended divide insns. (udivsi3, udivhi3, udivqi3): Remove since superseded by udivmodsi etc patterns. * ns32k.h (FUNCTION_VALUE, LIBCALL_VALUE): Use f0 for complex float return values as well as simple scalar floats. (TARGET_32381, TARGET_MULT_ADD, TARGET_SWITCHES): Support new flag to denote 32381 fpu. (OVERRIDE_OPTIONS): 32381 is a strict superset of 32081. (CONDITIONAL_REGISTER_USAGE): Disable extra 32381 registers if not compiling for 32381. (FIRST_PSEUDO_REGISTER, FIXED_REGISTERS, CALL_USED_REGISTERS, REGISTER_NAMES, ADDITIONAL_REGISTER_NAMES, OUTPUT_REGISTER_NAMES, REG_ALLOC_ORDER, DBX_REGISTER_NUMBER, R0_REGNUM, F0_REGNUM, L1_REGNUM, STACK_POINTER_REGNUM, FRAME_POINTER_REGNUM, LONG_FP_REGS_P, ARG_POINTER_REGNUM, reg_class, REG_CLASS_NAMES, REG_CLASS_CONTENTS, SUBSET_P,REGNO_REG_CLASS, REG_CLASS_FROM_LETTER, FUNCTION_PROLOGUE, FUNCTION_EPILOGUE, REGNO_OK_FOR_INDEX_P, FP_REG_P, REG_OK_FOR_INDEX_P, REG_OK_FOR_BASE_P, MEM_REG): New register scheme to include 32381 fpu registers and special register classes for new 32381 instructions dotf and polyf. (MODES_TIEABLE_P): Allow all integer modes, notably DI and SI, to be tieable. (INCOMING_RETURN_ADDR_RTX, RETURN_ADDR_RTX, INCOMING_FRAME_SP_OFFSET): New macros in case DWARF support is required. (SMALL_REGISTER_CLASSES): Make dependent on -mmult-add option. (MOVE_RATIO): Set to zero because of smart movstrsi implementation. (REGISTER_MOVE_COST): Move code to register_move_cost function for ease of coding and debugging. (CLASS_LIKELY_SPILLED_P): Under new register scheme class LONG_FLOAT_REGO is likely spilled but not caught by default definition. (CONSTANT_ADDRESS_P, CONSTANT_ADDRESS_NO_LABEL_P): Use macro instead of hard coded numbers in range check. (ASM_OUTPUT_LABELREF_AS_INT): Delete since unused. (...): Add prototypes for functions in ns32k.c but disable because of problems when ns32k.h is included in machine independent files. * ns32k.c: Include "system.h", "tree.h", "expr.h", "flags.h". (ns32k_reg_class_contents, regcass_map, ns32k_out_reg_names, hard_regno_mode_ok, secondary_reload_class, print_operand, print_operand_address): New register scheme to include 32381 fpu registers and special register classes for new 32381 instructions dotf and polyf. (gen_indexed_expr): Make static to keep namespace clean. (check_reg): Remove since never called. (move_tail, expand_block_move): Helper functions for "movstrsi" block move insn. (register_move_cost): Helper function for REGISTER_MOVE_COST macro. Increase cost of moves which go via memory. * netbsd.h (TARGET_DEFAULT): Set (new) 32381 fpu flag. (CPP_PREDEFINES): No longer predefine "unix". * ns32k.md (movsi, movsi, adddi3, subdi3, subsi3, subhi3, subqi3,...): Remove erroneous %$. print_operand() can work out from the rtx is an immediate prefix is required. * ns32k.h (RETURN_POPS_ARGS, VALID_MACHINE_DECL_ATTRIBUTE, VALID_MACHINE_TYPE_ATTRIBUTE, COMP_TYPE_ATTRIBUTES, SET_DEFAULT_TYPE_ATTRIBUTES): Support for -mrtd calling convention. (LEGITIMATE_PIC_OPERAND_P, SYMBOLIC_CONST): Correct handling of pic operands. * ns32k.c (symbolic_reference_mentioned_p, print_operand): Correct handling of pic operands. (ns32k_valid_decl_attribute_p, ns32k_valid_type_attribute_p, ns32k_comp_type_attributes, ns32k_return_pops_args): Support for -mrtd calling convention. Wed Nov 25 23:42:20 1998 Tom Tromey * gcc.c (option_map): Recognize --output-class-directory. Thu Nov 26 18:26:21 1998 Michael Hayes * loop.h (precondition_loop_p): Added new mode argument. * unroll.c (precondition_loop_p): Likewise. (approx_final_value): Function deleted and subsumed into loop_iterations. (loop_find_equiv_value): New function. (loop_iterations): Use loop_find_equiv_value to find increments too large to be immediate constants. Also use it to find terms common to initial and final iteration values that can be removed. Thu Nov 26 18:05:04 1998 Michael Hayes * loop.h (struct loop_info): Define new structure. (precondition_loop_p): Added prototype. (unroll_loop): Added new argument loop_info to prototype. (final_biv_value, final_giv_value): Added new argument n_iterations to prototype. * loop.c (strength_reduce): Declare new structure loop_iteration_info and new pointer loop_info. (loop_n_iterations): Replace global variable by element in loop_info structure. (check_final_value): New argument n_iterations. (insert_bct): New argument loop_info. (loop_unroll_factor): Replace global array by element in loop_info structure. (loop_optimize): Remove code to allocate and initialize loop_unroll_factor_array. * unroll.c (precondition_loop_p): No longer static since used by branch on count optimization. (precondition_loop_p, unroll_loop): New argument loop_info. (final_biv_value, final_giv_value, find_splittable_regs): New argument n_iterations. (loop_iteration_var, loop_initial_value, loop_increment, loop_final_value, loop_comparison_code, loop_unroll_factor): Replaced global variables by loop_info structure. (loop_unroll_factor): Replace global array by element in loop_info structure. Thu Nov 26 17:49:29 1998 Michael Hayes * loop.c (check_dbra_loop): Update JUMP_LABEL field of jump insn when loop reversed. * unroll.c (precondition_loop_p): Return loop_initial_value for initial_value instead of loop_iteration_var. Thu Nov 26 17:15:38 1998 Michael Hayes * config/c4x/c4x.md: Fix minor formatting problems. Update docs. (*b, *b_rev, *b_noov, *b_noov_rev, *db, decrement_and_branch_until_zero, rptb_end): Use c4x_output_cbranch to output the instruction sequences. (rpts): Delete. (rptb_top): Provide alternatives to use any register or memory for loop counter. (rptb_end): Emit use of operands rather than assigning them explicitly to the RS and RE registers. Thu Nov 26 16:37:59 1998 Michael Hayes * config/c4x/c4x.c (c4x_modified_between_p, c4x_mem_set_p, c4x_mem_set_p, c4x_mem_modified_between_p, c4x_insn_moveable_p, c4x_parallel_pack, c4x_parallel_find, c4x_update_info_reg, c4x_update_info_regs, c4x_copy_insn_after, c4x_copy_insns_after, c4x_merge_notes, c4x_parallel_process, c4x_combine_parallel_independent, c4x_combine_parallel_dependent, c4x_combine_parallel): Delete. Thu Nov 26 15:16:05 1998 Michael Hayes * config/c4x/c4x.c (c4x_override_options): For compatibility with old target options clear flag_branch_on_count_reg if -mno-rptb specified and set flag_argument_alias is -mno-aliases specified. (c4x_output_cbranch): Handle a sequence of insns rather than a single insn. (c4x_rptb_insert): Do not emit a RPTB insn if the RC register has not been allocated as the loop counter. (c4x_address_conflict): Do not allow two volatile memory references. (valid_parallel_operands_4, valid_parallel_operands_5, valid_parallel_operands_6): Reject pattern if the register destination of the first set is used as part of an address in the second set. Thu Nov 26 14:56:32 1998 Michael Hayes * config/c4x/c4x.h (TARGET_DEFAULT): Add PARALEL_MPY_FLAG. (TARGET_SMALL_REG_CLASS): Set to 0 so that SMALL_REGISTER_CLASSES is no longer enabled if PARALLEL_MPY_FLAG set. (HARD_REGNO_CALL_CLOBBERED): Add parentheses to remove ambiguity. (REG_CLASS_CONTENTS): Add braces around initializers. (HAVE_MULTIPLE_PACK): Define. (ASM_OUTPUT_BYTE_FLOAT): Use %lf format specifier with REAL_VALUE_TO_DECIMAL. (ASM_OUTPUT_SHORT_FLOAT): Use %lf format specifier with REAL_VALUE_TO_DECIMAL. (ar0_reg_operand): Add prototype. (ar0_mem_operand): Likewise. (ar1_reg_operand): Likewise. (ar1_mem_operand): Likewise. (ar2_reg_operand): Likewise. (ar2_mem_operand): Likewise. (ar3_reg_operand): Likewise. (ar3_mem_operand): Likewise. (ar4_reg_operand): Likewise. (ar4_mem_operand): Likewise. (ar5_reg_operand): Likewise. (ar5_mem_operand): Likewise. (ar6_reg_operand): Likewise. (ar6_mem_operand): Likewise. (ar7_reg_operand): Likewise. (ar7_mem_operand): Likewise. (ir0_reg_operand): Likewise. (ir0_mem_operand): Likewise. (ir1_reg_operand): Likewise. (ir1_mem_operand): Likewise. (group1_reg_operand): Likewise. (group1_mem_operand): Likewise. (ir1_reg_operand): Likewise. (arx_reg_operand): Likewise. (not_rc_reg): Likewise. (not_modify_reg): Likewise. (c4x_group1_reg_operand): Remove prototype. (c4x_group1_mem_operand): Likewise. (c4x_arx_reg_operand): Likewise. Wed Nov 25 19:02:55 1998 (Stephen L Moshier) * emit-rtl.c (gen_lowpart_common): Remove earlier change. * real.c (make_nan): Make SIGN arg actually specify the sign bit. Thu Nov 26 14:12:05 1998 Michael Hayes * config/c4x/c4x.md (addqi3): Emit addqi3_noclobber pattern during reload. Wed Nov 25 22:05:28 1998 J"orn Rennecke * config/sh/lib1funcs.asm (___udivsi3_i4): Don't switch to sz == 1 unless FMOVD_WORKS is defined. Wed Nov 25 20:11:04 1998 J"orn Rennecke * regclass.c (init_reg_sets): Move code that calculates tables dependent on reg_class_contents from here... (init_reg_sets_1): To here. Wed Nov 25 14:54:46 1998 Zack Weinberg * cpplib.h: Delete struct import_file. Add ihash element to struct cpp_buffer. Delete dont_repeat_files and import_hash_table elements from cpp_reader; change all_include_files to a hash table. Delete all foobar_include / last_foobar_include elements from struct cpp_options; put back four such: quote_include, bracket_include, system_include, after_include. Redo struct file_name_list completely. Add new structure type include_hash. Add prototypes for merge_include_chains and include_hash. Change prototypes for finclude, find_include_file, and append_include_chain to match changes below. * cppfiles.c (simplify_pathname, include_hash, remap_filename, merge_include_chains): New functions. (add_import, lookup_import, open_include_file): Removed. (INO_T_EQ): Define this (copied from cccp.c). (hack_vms_include_specification): Remove all calls and #if 0 out the definition. It was being called incorrectly and at the wrong times. Until a VMSie can look at this, it's better to not pretend to support it. (append_include_chain): Change calling convention; now takes only one directory at a time, and sets up the data structure itself. (redundant_include_p): Rewritten - this is now used for all include redundancy, whether by #ifndef, #import, or #pragma once. Looks up things in the include hash table. (file_cleanup): Decrement pfile->system_include_depth here if it's >0. (find_include_file): Calling convention changed; now passes around a struct include_hash instead of 3 separate parameters. Guts ripped out and replaced with new include_hash mechanism. (finclude): Calling convention changed as for find_include_file. Error exits pulled out-of-line. Reformat. (safe_read): Return a long, not an int. (deps_output): Don't recurse. * cpplib.c (is_system_include): Deleted. (path_include): Fix up call to append_include_chain. (do_include): Fix up calls to find_include_file and finclude. Clean up dependency output a bit. Shorten obnoxiously lengthy #import warning message. Don't decrement pfile->system_include_depth here. (do_pragma): Understand the include_hash structure. Reformat. (do_endif): Correct handling of control macros. Understand the include_hash. (cpp_start_read): Fix up calls to finclude. Call merge_include_chains. (cpp_handle_option): Fix up calls to append_include_chain. Understand the four partial include chains. (cpp_finish): Add debugging code (#if 0-ed out) for the include_hash. (cpp_cleanup): Free the include_hash, not the import hash and the all_include and dont_repeat lists which no longer exist. Wed Nov 25 11:26:19 1998 Jeffrey A Law (law@cygnus.com) * toplev.c (no_new_pseudos): Define. (rest_of_compilation): Set no_new_pseudos as needed. * emit-rtl.c (gen_reg_rtx): Abort if we try to create a new pseudo if no_new_pseudos is set. * rtl.h (no_new_pseudos): Declare it. * reload1.c (reload): Update comments. * md.texi: Corresponding changes. Wed Nov 25 11:26:17 1998 Bernd Schmidt * reload1.c (reg_used_in_insn): Renamed from reg_used_by_pseudo. (choose_reload_regs): Rename it here as well. When computing it, also merge in used hardregs. 1998-11-25 Zack Weinberg * gcc.c: Split out Objective-C specs to... * objc/lang-specs.h: here. (New file.) Make the specs cpplib aware. * c-lex.c (init_parse): Always initialize the filename global. * objc/objc-act.c (lang_init): Always call check_newline at beginning of file. Wed Nov 25 00:48:29 1998 Graham * reload1.c (reload): Remove unused variable. (reload_reg_free_for_value_p): Add missing parameter definition. * jump.c (jump_optimize): Remove unused variable. Wed Nov 25 00:07:11 1998 Jeffrey A Law (law@cygnus.com) * Makefile.in (graph.o): Depend on $(RTL_H), not rtl.h. * cse.c (fold_rtx): Make autoincrement addressing mode tests be runtime selectable. * expr.c (move_by_pieces): Similarly. (move_by_pieces_1, clear_by_pieces, clear_by_pieces_1): Similarly. * flow.c (find_auto_inc): Similarly. (try_pre_increment): Similarly. * loop.c (strength_reduce): Similarly. * regclass.c (auto_inc_dec_reg_p): Similarly. * regmove.c (try_auto_increment): Similarly. (fixup_match_1): Similarly. * rtl.h (HAVE_PRE_INCREMENT): Define if not already defined. (HAVE_PRE_DECREMENT): Similarly. (HAVE_POST_INCREMENT, HAVE_POST_DECREMENT): Similarly. * Corresponding changes to all target header files. * tm.texi: Update docs for autoinc addressing modes. Tue Nov 24 20:24:59 1998 Jim Wilson * configure.in (m68020-*-elf*, m68k-*-elf*): New targets. * configure: Rebuild. * config/elfos.h: New file. * config/m68k/m68020-elf.h, config/m68k/m68kelf.h, config/m68k/t-m68kelf: New file. Tue Nov 24 13:40:06 1998 Jeffrey A Law (law@cygnus.com) * Makefile.in (HOST_AR): Define. (HOST_AR_FLAGS, HOST_RANLIB, HOST_RANLIB_TEST): Similarly. (libcpp.a): Use the host tools explicitly. (STAGESTUFF): Add libcpp.a. Tue Nov 24 09:33:49 1998 Nick Clifton * config/m32r/m32r.md (movstrsi_internal): Describe changes made to source and destination registers. Mon Nov 23 20:28:02 1998 Mike Stump * libgcc2.c (top_elt): Remove top_elt, it isn't thread safe. The strategy we now use is to pre allocate the top_elt along with the EH context so that each thread has its own top_elt. This is necessary as the dynamic cleanup chain is used on the top element of the stack and each thread MUST have its own. (eh_context_static): Likewise. (new_eh_context): Likewise. (__sjthrow): Likewise. Mon Nov 23 20:25:03 1998 Jason Merrill * i386/linux.h (ASM_OUTPUT_MAX_SKIP_ALIGN): Wrap in do...while. * i386.md (prologue_get_pc): Remove unused variable. Mon Nov 23 17:05:40 1998 Geoffrey Noer * i386/xm-cygwin.h: Rename cygwin_ path funcs back to cygwin32_. Mon Nov 23 16:40:00 1998 Ulrich Drepper * Makefile.in (OBJS): Add graph.o. (graph.o): New dependency list. * flags.h: Declare dump_for_graph and define graph_dump_types type. * print-rtl.c (dump_for_graph): Define new variable. (print_rtx): Rewrite to allow use in graph dumping functions. * toplev.c: Declare print_rtl_graph_with_bb, clean_graph_dump_file, finish_graph_dump_file. Define graph_dump_format. (compile_file): If graph dumping is enabled also clear these files. Finish graph dump files. (rest_of_compilation): Also dump graph information if enabled. (main): Recognize -dv to enabled VCG based graph dumping. * graph.c: New file. Graph dumping functions. Mon Nov 23 16:39:04 1998 Richard Henderson * configure.in: Look for . * system.h: Include it before substitute S_ISREG definitions. Mon Nov 23 17:40:37 1998 Gavin Romig-Koch * config/mips/abi.h: Use ABI_O64, duplicating ABI_32 usage. * config/mips/iris6.h: Same. * config/mips/mips.md: Same. * config/mips/mips.c: Same; also add "-mabi=o64" option. * config/mips/mips.h: Same; also define ABI_O64. Mon Nov 23 17:02:27 1998 Kaveh R. Ghazi * configure.in: Use AC_PREREQ(2.12.1). Mon Nov 23 10:16:38 1998 Melissa O'Neill * cccp.c (S_ISREG, S_ISDIR): Delete defines. * cpplib.c, gcc.c: Likewise. * system.h (S_ISREG, S_ISDIR): Define if not already defined. Mon Nov 23 09:53:44 1998 Richard Henderson * local-alloc.c (local_alloc): Use malloc not alloca for reg_qty, reg_offset, ref_next_in_qty. Mon Nov 23 16:46:46 1998 J"orn Rennecke * caller-save.c (insert_one_insn): Initialize the live_before and live_after register sets. Add SH4 support: * config/sh/lib1funcs.asm (___movstr_i4_even, ___movstr_i4_odd): Define. (___movstrSI12_i4, ___sdivsi3_i4, ___udivsi3_i4): Define. * sh.c (reg_class_from_letter, regno_reg_class): Add DF_REGS. (fp_reg_names, assembler_dialect): New variables. (print_operand_address): Handle SUBREGs. (print_operand): Added 'o' case. Don't use adj_offsettable_operand on PRE_DEC / POST_INC. Name of FP registers depends on mode. (expand_block_move): Emit different code for SH4 hardware. (prepare_scc_operands): Use emit_sf_insn / emit_df_insn as appropriate. (from_compare): Likewise. (add_constant): New argument last_value. Changed all callers. (find_barrier): Don't try HImode load for FPUL_REG. (machine_dependent_reorg): Likewise. (sfunc_uses_reg): A CLOBBER cannot be the address register use. (gen_far_branch): Emit a barrier after the new jump. (barrier_align): Don't trust instruction lengths before fixing up pcloads. (machine_dependent_reorg): Add support for FIRST_XD_REG .. LAST_XD_REG. Use auto-inc addressing for fp registers if doubles need to be loaded in two steps. Set sh_flag_remove_dead_before_cse. (push): Support for TARGET_FMOVD. Use gen_push_fpul for fpul. (pop): Support for TARGET_FMOVD. Use gen_pop_fpul for fpul. (calc_live_regs): Support for TARGET_FMOVD. Don't save FPSCR. Support for FIRST_XD_REG .. LAST_XD_REG. (sh_expand_prologue): Support for FIRST_XD_REG .. LAST_XD_REG. (sh_expand_epilogue): Likewise. (sh_builtin_saveregs): Use DFmode moves for fp regs on SH4. (initial_elimination_offset): Take TARGET_ALIGN_DOUBLE into account. (arith_reg_operand): FPUL_REG is OK for SH4. (fp_arith_reg_operand, fp_extended_operand): New functions. (tertiary_reload_operand, fpscr_operand): Likewise. (commutative_float_operator, noncommutative_float_operator): Likewise. (binary_float_operator, get_fpscr_rtx, emit_sf_insn): Likewise. (emit_df_insn, expand_sf_unop, expand_sf_binop): Likewise. (expand_df_unop, expand_df_binop, expand_fp_branch): Likewise. (emit_fpscr_use, mark_use, remove_dead_before_cse): Likewise. * sh.h (CPP_SPEC): Add support for -m4, m4-single, m4-single-only. (CONDITIONAL_REGISTER_USAGE): Likewise. (HARD_SH4_BIT, FPU_SINGLE_BIT, SH4_BIT, FMOVD_BIT): Define. (TARGET_CACHE32, TARGET_SUPERSCALAR, TARGET_HARWARD): Define. (TARGET_HARD_SH4, TARGET_FPU_SINGLE, TARGET_SH4, TARGET_FMOVD): Define. (target_flag): Add -m4, m4-single, m4-single-only, -mfmovd. (OPTIMIZATION_OPTIONS): If optimizing, set flag_omit_frame_pointer to -1 and sh_flag_remove_dead_before_cse to 1. (ASSEMBLER_DIALECT): Define to assembler_dialect. (assembler_dialect, fp_reg_names): Declare. (OVERRIDE_OPTIONS): Add code for TARGET_SH4. Hide names of registers that are not accessible. (CACHE_LOG): Take TARGET_CACHE32 into account. (LOOP_ALIGN): Take TARGET_HARWARD into account. (FIRST_XD_REG, LAST_XD_REG, FPSCR_REG): Define. (FIRST_PSEUDO_REGISTER: Now 49. (FIXED_REGISTERS, CALL_USED_REGISTERS): Include values for registers. (HARD_REGNO_NREGS): Special treatment of FIRST_XD_REG .. LAST_XD_REG. (HARD_REGNO_MODE_OK): Update. (enum reg_class): Add DF_REGS and FPSCR_REGS. (REG_CLASS_NAMES, REG_CLASS_CONTENTS, REG_ALLOC_ORDER): Likewise. (SECONDARY_OUTPUT_RELOAD_CLASS, SECONDARY_INPUT_RELOAD_CLASS): Update. (CLASS_CANNOT_CHANGE_SIZE, DEBUG_REGISTER_NAMES): Define. (NPARM_REGS): Eight floating point parameter registers on SH4. (BASE_RETURN_VALUE_REG): SH4 also passes double values in floating point registers. (GET_SH_ARG_CLASS): Likewise. Complex float types are also returned in float registers. (BASE_ARG_REG): Complex float types are also passes in float registers. (FUNCTION_VALUE): Change mode like PROMOTE_MODE does. (LIBCALL_VALUE): Remove trailing semicolon. (ROUND_REG): Round when double precision value is passed in floating point register(s). (FUNCTION_ARG_ADVANCE): No change wanted for SH4 when things are passed on the stack. (FUNCTION_ARG): Little endian adjustment for SH4 SFmode. (FUNCTION_ARG_PARTIAL_NREGS): Zero for SH4. (TRAMPOLINE_ALIGNMENT): Take TARGET_HARWARD into account. (INITIALIZE_TRAMPOLINE): Emit ic_invalidate_line for TARGET_HARWARD. (MODE_DISP_OK_8): Not for SH4 DFmode. (GO_IF_LEGITIMATE_ADDRESS): No base reg + index reg for SH4 DFmode. Allow indexed addressing for PSImode after reload. (LEGITIMIZE_ADDRESS): Not for SH4 DFmode. (LEGITIMIZE_RELOAD_ADDRESS): Handle SH3E SFmode. Don't change SH4 DFmode nor PSImode RELOAD_FOR_INPUT_ADDRESS. (DOUBLE_TYPE_SIZE): 64 for SH4. (RTX_COSTS): Add PLUS case. Increase cost of ASHIFT, ASHIFTRT, LSHIFTRT case. (REGISTER_MOVE_COST): Add handling of R0_REGS, FPUL_REGS, T_REGS, MAC_REGS, PR_REGS, DF_REGS. (REGISTER_NAMES): Use fp_reg_names. (enum processor_type): Add PROCESSOR_SH4. (sh_flag_remove_dead_before_cse): Declare. (rtx_equal_function_value_matters, fpscr_rtx, get_fpscr_rtx): Declare. (PREDICATE_CODES): Add binary_float_operator, commutative_float_operator, fp_arith_reg_operand, fp_extended_operand, fpscr_operand, noncommutative_float_operator. (ADJUST_COST): Use different scale for TARGET_SUPERSCALAR. (SH_DYNAMIC_SHIFT_COST): Cheaper for SH4. * sh.md (attribute cpu): Add value sh4. (attrbutes fmovd, issues): Define. (attribute type): Add values dfp_arith, dfp_cmp, dfp_conv, dfdiv. (function units memory, int, mpy, fp): Make dependent on issue rate. (function units issue, single_issue, load_si, load): Define. (function units load_store, fdiv, gp_fpul): Define. (attribute hit_stack): Provide proper default. (use_sfunc_addr+1, udivsi3): Predicated on ! TARGET_SH4. (udivsi3_i4, udivsi3_i4_single, divsi3_i4, divsi3_i4_single): New insns. (udivsi3, divsi3): Emit special patterns for SH4 hardware, (mulsi3_call): Now uses match_operand for function address. (mulsi3): Also emit code for SH1 case. Wrap result in REG_LIBCALL / REG_RETVAL notes. (push, pop, push_e, pop_e): Now define_expands. (push_fpul, push_4, pop_fpul, pop_4, ic_invalidate_line): New expanders. (movsi_ie): Added y/i alternative. (ic_invalidate_line_i, movdf_i4): New insns. (movdf_i4+[123], reload_outdf+[12345], movsi_y+[12]): New splitters. (reload_indf, reload_outdf, reload_outsf, reload_insi): New expanders. (movdf): Add special code for SH4. (movsf_ie, movsf_ie+1, reload_insf, calli): Make use of fpscr visible. (call_valuei, calli, call_value): Likewise. (movsf): Emit no-op move. (mov_nop, movsi_y): New insns. (blt, sge): Generalize to handle DFmode. (return predicate): Call emit_fpscr_use and remove_dead_before_cse. (block_move_real, block_lump_real): Predicate on ! TARGET_HARD_SH4. (block_move_real_i4, block_lump_real_i4, fpu_switch): New insns. (fpu_switch0, fpu_switch1, movpsi): New expanders. (fpu_switch+[12], fix_truncsfsi2_i4_2+1): New splitters. (toggle_sz): New insn. (addsf3, subsf3, mulsf3, divsf3): Now define_expands. (addsf3_i, subsf3_i, mulsf3_i4, mulsf3_ie, divsf3_i): New insns. (macsf3): Make use of fpscr visible. Disable for SH4. (floatsisf2): Make use of fpscr visible. (floatsisf2_i4): New insn. (floatsisf2_ie, fixsfsi, cmpgtsf_t, cmpeqsf_t): Disable for SH4. (ieee_ccmpeqsf_t): Likewise. (fix_truncsfsi2): Emit different code for SH4. (fix_truncsfsi2_i4, fix_truncsfsi2_i4_2, cmpgtsf_t_i4): New insns. (cmpeqsf_t_i4, ieee_ccmpeqsf_t_4): New insns. (negsf2, sqrtsf2, abssf2): Now expanders. (adddf3, subdf3i, muldf2, divdf3, floatsidf2): New expanders. (negsf2_i, sqrtsf2_i, abssf2_i, adddf3_i, subdf3_i): New insns. (muldf3_i, divdf3_i, floatsidf2_i, fix_truncdfsi2_i): New insns. (fix_truncdfsi2, cmpdf, negdf2, sqrtdf2, absdf2): New expanders. (fix_truncdfsi2_i4, cmpgtdf_t, cmpeqdf_t, ieee_ccmpeqdf_t): New insns. (fix_truncdfsi2_i4_2+1): New splitters. (negdf2_i, sqrtdf2_i, absdf2_i, extendsfdf2_i4): New insns. (extendsfdf2, truncdfsf2): New expanders. (truncdfsf2_i4): New insn. * t-sh (LIB1ASMFUNCS): Add _movstr_i4, _sdivsi3_i4, _udivsi3_i4. (MULTILIB_OPTIONS): Add m4-single-only/m4-single/m4. * float-sh.h: When testing for __SH3E__, also test for __SH4_SINGLE_ONLY__ . * va-sh.h (__va_freg): Define to float. (__va_greg, __fa_freg, __gnuc_va_list, va_start): Define for __SH4_SINGLE_ONLY__ like for __SH3E__ . (__PASS_AS_FLOAT, __TARGET_SH4_P): Likewise. (__PASS_AS_FLOAT): Use different definition for __SH4__ and __SH4_SINGLE__. (TARGET_SH4_P): Define. (va_arg): Use it. * sh.md (movdf_k, movsf_i): Tweak the condition so that init_expr_once is satisfied about the existence of load / store insns. * sh.md (movsi_i, movsi_ie, movsi_i_lowpart, movsf_i, movsf_ie): Change m constraint in source operand to mr / mf. * va-sh.h (__va_arg_sh1): Use __asm instead of asm. * (__VA_REEF): Define. (__va_arg_sh1): Use it. * va-sh.h (va_start, va_arg, va_copy): Add parentheses. Sun Nov 22 21:34:02 1998 Jeffrey A Law (law@cygnus.com) * i386/dgux.c (struct option): Add new "description field". * m88k/m88k.c (struct option): Likewise. Sun Nov 22 16:07:57 1998 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. Sun Nov 22 13:40:02 1998 Bernd Schmidt * regmove.c (regmove_profitable_p): Use return value of find_matches properly. Sun Nov 22 02:47:37 1998 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. Sat Nov 21 22:12:09 1998 Jeffrey A Law (law@cygnus.com) * reload1.c (eliminate_regs): Do not lose if eliminate_regs is called without reload having been called earlier. * v850.c (ep_memory_operand): Offsets < 0 are not valid for EP addressing modes. (v850_reorg): Similarly. * loop.c (check_dbra_loop): Avoid using gen_add2_insn. Sat Nov 21 02:18:38 1998 J"orn Rennecke * loop.c (move_movables): Start of libcall might be new loop start. Fri Nov 20 12:14:16 1998 Kaveh R. Ghazi * hash.c (hash_table_init_n): Wrap prototype arguments in PARAMS(). Fri Nov 20 08:34:00 1998 Bernd Schmidt * function.c (nonlocal_goto_handler_slots): Renamed from nonlocal_goto_handler_slot; now an EXPR_LIST chain. (push_function_context_to): Adjust for this change. (pop_function_context_from): Likewise. (init_function_start): Likewise. (expand_function_end): Likewise. * function.h (struct function): Likewise. * calls.c (expand_call): Likewise. * explow.c (allocate_dynamic_stack_space): Likewise. * expr.h (nonlocal_goto_handler_slots): Rename its declaration. * stmt.c (declare_nonlocal_label): Make a new handler slot for each label. (expand_goto): When doing a nonlocal goto, find corresponding handler slot for it. Don't put the label address in the static chain register. (expand_end_bindings): Break out nonlocal goto handling code into three new functions. (expand_nl_handler_label, expand_nl_goto_receiver, expand_nl_goto_receivers): New static functions, broken out of expand_end_bindings and adapted to create one handler per nonlocal label. * function.c (delete_handlers): Delete insn if it references any of the nonlocal goto handler slots. * i960.md (nonlocal_goto): Comment out code that modifies static_chain_rtx. * sparc.md (nonlocal_goto): Likewise. (goto_handler_and_restore_v9): Comment out. (goto_handler_and_restore_v9_sp64): Comment out. Thu Nov 19 23:44:38 1998 Bernd Schmidt * expr.c (STACK_BYTES): Delete unused macro. * calls.c: Provide default for PREFERRED_STACK_BOUNDARY. (STACK_BYTES): Use PREFERRED_STACK_BOUNDARY, not STACK_BOUNDARY. (expand_call): Likewise. (emit_library_call): Likewise. (emit_library_call_value): Likewise. * function.c: Provide default for PREFERRED_STACK_BOUNDARY. (STACK_BYTES): Use PREFERRED_STACK_BOUNDARY, not STACK_BOUNDARY. * explow.c: Provide default for PREFERRED_STACK_BOUNDARY. (round_push): Use PREFERRED_STACK_BOUNDARY, not STACK_BOUNDARY. (allocate_dynamic_stack_space): Likewise. * tm.texi (PREFERRED_STACK_BOUNDARY): Document new macro. (STACK_BOUNDARY): Update description to reflect the new situation. Thu Nov 19 22:20:51 1998 Jeffrey A Law (law@cygnus.com) * reorg.c (relax_delay_slots): When optimizing for code size, if a return with a filled delay slot is followed by a return with an unfilled delay slot, delete the first return and reemit the insn that was previously in its delay slot. * i860.c (single_insn_src_p): Add missing parens. * ginclude/math-3300.h: Likewise. Thu Nov 19 20:55:59 1998 H.J. Lu (hjl@gnu.org) * regclass.c (init_reg_sets_1): Add prototype. (init_reg_modes): Likewise. 1998-11-19 Zack Weinberg * c-common.c: Change warning messages to say `comparison is always true' or `comparison is always false' instead of the confusing `is always 0', `is always 1'. Thu Nov 19 19:05:49 1998 Per Bothner * print-tree.c (print_node): After printing BLOCK or BIND_EXPR, break instead of return (which loses closing '>'). Thu Nov 19 19:34:13 1998 Jeffrey A Law (law@cygnus.com) * i386.h (LEGITIMATE_CONSTANT_P): Reject CONST_DOUBLEs that are not standard 387 constants. * i386.md (jump): Explicitly set "memory" attribute. (indirect_jump, prologue_set_stack_ptr): Likewise. (prologue_get_pc_and_set_got, pop): Likewise. (allocate_stack_worder, blockage, return_internal): Likewise. (return_pop_internal, nop): Likewise. (epilogue_set_stack_ptr, leave): Likewise. Thu Nov 19 15:42:54 1998 Nick Clifton * config/arm/coff.h: Set USER_LABEL_PREFIX to "_". Thu Nov 19 23:20:59 1998 J"orn Rennecke * reload1.c (reload_reg_free_for_value_p): Early auto_inc reloads don't conflict with outputs. Thu Nov 19 12:58:55 1998 Kaveh R. Ghazi * configure.in: Don't do AC_CHECK_HEADERS(wait.h sys/wait.h). Instead call AC_HEADER_SYS_WAIT. * collect2.c: Don't provide defaults for sys/wait.h macros. * gcc.c: Likewise. * protoize.c: Likewise. Also, don't include sys/wait.h. * system.h: Include sys/wait.h and provide macro defaults. 1998-11-19 Andreas Schwab * Makefile.in (mandir): Set to @mandir@. (man1dir): New variable to hold the former value of $(mandir). Replace all uses of $(mandir) by $(man1dir). Wed Nov 18 16:31:28 1998 Jim Wilson * reload.c (find_reloads_address_part): If have a CONST_INT, create a new one before passing it to force_const_mem. * reload.c (find_reloads_toplev): Pass &x instead of NULL_PTR in find_reloads_address call. Wed Nov 18 22:13:00 1998 J"orn Rennecke * expr.c (store_expr): Don't generate load-store pair if TEMP is identical (according to ==) with TARGET. Tue Nov 17 22:25:16 1998 J"orn Rennecke * reload1.c (reload_reg_free_for_value_p): When considered reload has an output, matching inputs are not sufficient to avoid conflict. Tue Nov 17 11:51:16 1998 Mark Mitchell * hash.h (hash_table_key): New type. (hash_entry): Change `string' field to generic `key'. (hash_table): Add `comp' and `hash' functions. (hash_table_init): Take them as input. (hash_table_init_n): Likewise. (hash_lookup): Modify for generic keys. (hash_newfunc): Likewise. (hash_traverse): Likewise. (string_hash): New function. (string_compare): Likewise. (string_copy): Likewise. * hash.c (hash_table_init_n): Modify for generic keys. (hash_table_init): Likewise. (hash_lookup): Likewise. (hash_newfunc): Likewise. (hash_traverse): Likewise. (string_hash): Split out from hash_lookup. (string_compare): New function. (string_copy): Split out from hash_lookup. * tlink.c (symbol_hash_newfunc): Modify for new interfaces to hash tables. (symbol_hash_lookup): Likewise. (file_hash_newfunc): Likewise. (file_hash_lookup): Likewise. (demangled_hash_newfunc): Likewise. (demangled_hash_lookup): Likewise. (tlink_int): Likewise. (read_repo_file): Likewise. (recompile_files): Likewise. (demangle_new_symbols): Likewise. (scan_linker_output): Likewise. Tue Nov 17 17:13:53 1998 J"orn Rennecke * flow.c (insn_dead_p): New argument NOTES. Changed all callers. Mon Nov 16 17:56:07 1998 David Edelsohn * rs6000.c (output_mi_thunk): Improve test for local branch. Mon Nov 16 17:56:07 1998 Franz Sirl * rs6000.c (output_mi_thunk): Correct test for aggregate values. Mon Nov 16 21:02:52 1998 J"orn Rennecke * reload1.c (reload_reg_free_before_p): Delete. Changed all callers to use reload_reg_free_for_value_p instead. (reload_reg_free_for_value_p): Handle more reload types. A RELOAD_FOR_INPUT doesn't conflict with its RELOAD_FOR_INPUT_ADDRESS / RELOAD_FOR_INPADDR_ADDRESS. Add special case for OUT == const0_rtx. Added ignore_address_reloads argument. Changed all callers. Mon Nov 16 02:22:29 1998 Jason Merrill * toplev.c (compile_file): Don't pedwarn about undefined static functions just because we passed -Wunused. Mon Nov 16 04:41:41 1998 J"orn Rennecke * function.c (purge_addressof_1): Unshare rtl created by store_bit_field. Mon Nov 16 04:23:06 1998 J"orn Rennecke * regmove.c (regmove_optimize): Don't do anything but optimize_reg_copy[123] when flag_regmove is not set. Sat Nov 14 15:05:07 1998 Richard Henderson * alpha.md (addsi3, subsi3): Revise 5 Nov change to store DImode value in paradoxical SImode result, rather than truncating midpoint. Fri Nov 13 22:19:23 1998 Richard Henderson * alpha.c (reg_not_elim_operand): New. * alpha.h (PREDICATE_CODES): Add it. * alpha.md (s48addq, s48subq patterns): Use it as the predicate for the multiplicand. Fri Nov 13 22:50:37 1998 David Edelsohn * rs6000.md (movsf): Remove explicit secondary-reload-like functionality. Only truncate SFmode store if in FPR. (movsf splitters): Combine const_double splitters. (movsf_hardfloat): Add GPR support. Fri Nov 13 11:02:11 1998 Stan Cox * splet.h (SUBTARGET_OVERRIDE_OPTIONS): New to deprecate -mlive-g0 and -mbroken-saverestore. * t-splet (MULTILIB_OPTIONS): Likewise. * sparc.c (sparc_flat_compute_frame_size): Correctly calc args_size in a leaf function. Clarify total_size/extra_size relationship. Thu Nov 12 19:20:57 1998 Geoffrey Noer * i386/cygwin32.asm: Delete. * i386/cygwin.asm: New file, renamed from cygwin32.asm. * i386/cygwin32.h: Delete. * i386/cygwin.h: New file, renamed from cygwin32.h. * i386/t-cygwin32: Delete. * i386/t-cygwin: New file, renamed from t-cygwin32. Include cygwin.asm instead of cygwin32.asm. Remove "32" from comment. * i386/x-cygwin32: Delete. * i386/x-cygwin: New file, renamed from x-cygwin32. * i386/xm-cygwin32: Delete. * i386/xm-cygwin: New file, renamed from xm-cygwin32. Use newly renamed cygwin_ funcs for path translations. * i386/win32.h: Define __CYGWIN__ when -mcygwin given. * i386/winnt.c: Remove "32" from comment about cygwin. * i386/mingw32.h: Fix references to cygwin32.h in light of above. * rs6000/cygwin32.h: Delete. * rs6000/cygwin.h: New file, renamed from cygwin32.h. Add -D__CYGWIN__ to CPP_PREDEFINES. * rs6000/x-cygwin32: Delete. * rs6000/x-cygwin: New file, renamed from x-cygwin32. * rs6000/xm-cygwin32: Delete. * rs6000/xm-cygwin: New file, renamed from xm-cygwin32. * configure.in: Check for cygwin* instead of cygwin32. Account for the rename of cygwin-related config files to lose the "32"s. * configure: Regenerate. * cccp.c, collect2.c, gcc.c, getpwd.c, libgcc2.c, protoize.c, toplev.c: Change all refs to __CYGWIN32__ to __CYGWIN__. Wed Nov 11 12:25:19 1998 Tom Tromey * Makefile.in (JAVAGC): New macro. * configure: Rebuilt. * configure.in: Recognize --enable-java-gc argument. Subst `JAVAGC' variable. Thu Nov 12 03:32:16 1998 J"orn Rennecke Handle equivalences that have been obscured by gcse: * reload1.c (reload): Handle equivalences set up in multiple places. * local-alloc.c (reg_equiv_init_insns): New variable. (no_equiv): New function. (update_equiv_regs): Handle equivalences set up in multiple places. Don't ignore an insn just because its destination is likely to be spilled. Wed Nov 11 13:46:13 1998 Jim Wilson * except.c (expand_eh_return): Readd force_operand call lost in Sept 15 change. Tue Nov 10 17:04:11 1998 David Edelsohn * rs6000.h (LEGITIMIZE_ADDRESS): Add missing goto on last case. 1998-11-09 Andreas Schwab * dbxout.c: Check HAVE_STAB_H instead of HAVE_STABS_H. Mon Nov 9 20:15:19 1998 Bernd Schmidt * regmove.c (regmove_optimize): Fix error in last change. Mon Nov 9 16:37:52 1998 Andrew Cagney * mips.c (function_prologue): When TARGET_MIPS16, adjust the register offset in the .mask pseudo to compensate for frame pointer adjustments. (mips16_fp_args, build_mips16_call_stub): For little endian, do not word swap arguments moved to/from FP registers. * mips16.S (DFREVCMP): Reverse arguments to OPCODE. Mon Nov 9 09:47:06 1998 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. Mon Nov 9 02:14:14 1998 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. Mon Nov 9 03:06:24 1998 Jeffrey A Law (law@cygnus.com) * reload1.c (delete_output_reload_insn): If a pseudo is set multiple times, then it can not be completely replaced. Mon Nov 9 00:39:02 1998 Richard Henderson * alpha.md (call, call_value) [OSF]: Correct alt 3 insn length. Sun Nov 8 17:50:30 1998 Kaveh R. Ghazi * gansidecl.h: Prepend a "G" to the macro wrapping this file (to distinguish it from the macro wrapping ansidecl.h.) Include libiberty's ansidecl.h. Remove all redundant definitions. Define the PROTO() style macros in terms of the PARAMS() ones. * calls.c (emit_library_call): Switch on ANSI_PROTOTYPES, not __STDC__, when deciding whether to use ANSI variable args. (emit_library_call_value): Likewise. * cccp.c (error): Likewise. (warning): Likewise. (error_with_line): Likewise. (warning_with_line): Likewise. (pedwarn): Likewise. (pedwarn_with_line): Likewise. (pedwarn_with_file_and_line): Likewise. (fatal): Likewise. * cexp.y (error): Likewise. (pedwarn): Likewise. (warning): Likewise. * collect2.c (fatal_perror): Likewise. (fatal): Likewise. (error): Likewise. * combine.c (gen_rtx_combine): Likewise. * cpperror.c (cpp_message): Likewise. (cpp_fatal): Likewise. * cpplib.c (cpp_error): Likewise. (cpp_warning): Likewise. (cpp_pedwarn): Likewise. (cpp_error_with_line): Likewise. (cpp_warning_with_line): Likewise. (cpp_pedwarn_with_line): Likewise. (cpp_pedwarn_with_file_and_line): Likewise. * cpplib.h: Don't define PARAMS() macro. * demangle.h: Likewise. * doprint.c (checkit): Switch on ANSI_PROTOTYPES, not __STDC__, when deciding whether to use ANSI variable args. * emit-rtl.c (gen_rtx): Likewise. (gen_rtvec): Likewise. * final.c (asm_fprintf): Likewise. * fix-header.c (cpp_message): Likewise. (fatal): Likewise. (cpp_fatal): Likewise. * gcc.c (concat): Likewise. (fatal): Likewise. (error): Likewise. * genattr.c (fatal): Likewise. * genattrtab.c (attr_rtx): Likewise. (attr_printf): Likewise. (fatal): Likewise. * gencodes.c (fatal): Likewise. * genconfig.c (fatal): Likewise. * genemit.c (fatal): Likewise. * genextract.c (fatal): Likewise. * genflags.c (fatal): Likewise. * genopinit.c (fatal): Likewise. * genoutput.c (fatal): Likewise. (error): Likewise. * genpeep.c (fatal): Likewise. * genrecog.c (fatal): Likewise. * halfpic.h: Switch on ANSI_PROTOTYPES, not __STDC__, when deciding whether to declare `tree_node' and `rtx_def'. * hash.h: Don't define stuff we get from gansidecl.h. * mips-tfile.c: Likewise. Define __proto() in terms of PARAMS(). (fatal): Switch on ANSI_PROTOTYPES, not __STDC__, when deciding whether to use ANSI variable args. (error): Likewise. * prefix.c (concat): Likewise. * scan.h: Likewise. * system.h: Likewise. * toplev.c (error_with_file_and_line): Likewise. (error_with_decl): Likewise. (error_for_asm): Likewise. (error): Likewise. (fatal): Likewise. (warning_with_file_and_line): Likewise. (warning_with_decl): Likewise. (warning_for_asm): Likewise. (warning): Likewise. (pedwarn): Likewise. (pedwarn_with_decl): Likewise. (pedwarn_with_file_and_line): Likewise. (sorry): Likewise. (really_sorry): Likewise. * toplev.h: Switch on ANSI_PROTOTYPES, not __STDC__, when deciding whether to declare `tree_node' and `rtx_def'. * tree.c (build): Switch on ANSI_PROTOTYPES, not __STDC__, when deciding whether to use ANSI variable args. (build_nt): Likewise. (build_parse_node): Likewise. Sun Nov 8 13:10:55 1998 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. Sat Nov 7 23:34:01 1998 Kaveh R. Ghazi * Makefile.in (libcpp.a): Check RANLIB_TEST before runing RANLIB. Sat Nov 7 22:26:19 1998 David Edelsohn * collect2.c (main, case 'b'): Use else if. Sat Nov 7 15:35:25 1998 Kaveh R. Ghazi * configure.in (host_xm_file, build_xm_file, xm_file, tm_file): Arrange to include gansidecl.h in {ht}config.h & tm.h just before the config/ directory headers. (tm_file_list, host_xm_file_list, build_xm_file_list): Handle gansidecl.h in the list of dependencies. * Makefile.in (RTL_BASE_H): Don't depend on gansidecl.h. (TREE_H, DEMANGLE_H, RECOG_H, REGS_H, libgcc2.a, stmp-multilib, mbchar.o, collect2.o, pexecute.o, vfprintf.o, splay-tree.o, gcc.o, gencheck.o, choose-temp.o, mkstemp.o, mkstemp.o, prefix.o, dyn-string.o, cexp.o, cccp.o, cppmain.o, cpplib.o, cpperror.o, cppexp.o, cppfiles.o, cpphash.o, cppalloc.o, scan-decls.o): Likewise. * cccp.c: Don't include gansidecl.h. * cexp.y: Likewise. * collect2.c: Likewise. * config/c4x/c4x.c: Likewise. * config/v850/v850.h: Likewise. * cppalloc.c: Likewise. * cpperror.c: Likewise. * cppexp.c: Likewise. * cppfiles.c: Likewise. * cpphash.c: Likewise. * cpplib.c: Likewise. * cppmain.c: Likewise. * cppulp.c: Likewise. * demangle.h: Likewise. * doprint.c: Likewise. * dyn-string.c: Likewise. * eh-common.h: Likewise. * fix-header.c: Likewise. * frame.c: Likewise. * gcc.c: Likewise. * gcov.c: Likewise. * gen-protos.c: Likewise. * gencheck.c: Likewise. * halfpic.h: Likewise. * hash.c: Likewise. * machmode.h: Likewise. * mbchar.c: Likewise. * prefix.c: Likewise. * protoize.c: Likewise. * recog.h: Likewise. * rtl.h: Likewise. * scan-decls.c: Likewise. * tree.h: Likewise. * varray.h: Likewise. Sat Nov 7 11:37:53 1998 Richard Henderson * i386.md (call_value_pop): If we're not popping anything, defer to call_value. (call_pop): Likewise defer to call. Sat Nov 7 02:49:56 1998 Richard Henderson * function.c (purge_addressof): Clear purge_addressof_replacements only after processing the whole function. Sat Nov 7 00:54:55 1998 Jeffrey A Law (law@cygnus.com) * reload1.c (reload): If we can not perform a particular elimination when we thought we could earlier, then we must always iterate through the loop at least one more time. Fri Nov 6 19:37:33 1998 Richard Henderson * alpha.c (add_operand): Simplify the CONST_INT match. (sext_add_operand): Correct typo in comparison by using CONST_OK_FOR_LETTER_P. * alpha.md (s?addq): Use sext_add_operand to allow the negative constant alternatives to be generated. (mulsi3, muldi3, umuldi3_highpart): Loosen constraints to allow small constants, since the hw instructions do. Fri Nov 6 20:15:19 1998 Bernd Schmidt * reload1.c (emit_reload_insns): When rewriting the SET_DEST of a previous insn to store directly into our reload register, make sure that if the source of the previous insn is a reload register, its spill_reg_store and spill_reg_stored_to values are cleared. Fri Nov 6 16:35:10 1998 David Edelsohn * rs6000.md (floatunssidf2_internal splitter): Use base register operand, not hard-coded SP. Fri Nov 6 04:07:53 1998 David S. Miller * jump.c (calculate_can_reach_end): Fix thinko. Fri Nov 6 00:16:04 1998 Jeffrey A Law (law@cygnus.com) * reorg.c (fill_simple_delay_slots): Fix typo. * romp.h (LEGITIMIZE_ADDRESS): Fix typo. Fri Nov 6 00:10:00 1998 Jan Hubicka (hubicka@freesoft.cz) * i386.md (extendsidi2): Use # in the output template. (extendsidi splitters): New splitters. Thu Nov 5 11:13:27 1998 Nick Clifton * configure.in: Use unknown-elf.h as tm_file for arm-elf configurations. * configure: Regenerate. Thu Nov 5 07:59:05 1998 David S. Miller * jump.c (init_label_info, delete_barrier_successors, mark_all_labels, delete_unreferenced_labels, delete_noop_moves, calculate_can_reach_end): New functions broken out of jump_optimize. (jump_optimize): Use them. Thu Nov 5 07:57:45 1998 Andrew MacLeod * except.c (expand_fixup_region_end): Make sure outer context labels are not issued in an inner context during cleanups. Thu Nov 5 04:03:06 1998 Richard Henderson * alpha.md (addsi3, subsi3): No new temporaries once cse is no longer expected. Thu Nov 5 03:29:19 1998 Richard Henderson * alpha.md (addsi3, subsi3): Expand to a DImode temporary so as to expose this midpoint to CSE. Thu Nov 5 03:42:54 1998 David S. Miller * config/sparc/sparc.md (movdf_const_intreg_sp64): Enable again. Thu Nov 5 10:53:01 1998 Andreas Schwab * configure.in: Bring over gcc2 change of Nov 19 1997. Wed Nov 4 23:43:08 1998 Graham * toplev.c (output_lang_identify): Make definition dependent on ASM_IDENTIFY_LANGUAGE. * print-rtl.c (spaces): Make static. Wed Nov 4 22:16:36 1998 Hans-Peter Nilsson * extend.texi: Clarify proper uses for register clobbers in asms. Wed Nov 4 22:16:36 1998 Bernd Schmidt * recog.h (enum op_type): Define. (constrain_operands): Adjust prototype. (recog_op_type): Declare new variable. * recog.c (recog_op_type): New variable. (insn_invalid_p): Allow modifying an asm statement after reload. (extract_insn): Set up recog_op_type. (constrain_operands): Lose INSN_CODE_NUM arg. All callers changed. Don't compute operand types, use recog_op_type. Use the information computed by extract_insn instead of the previous method of finding it by insn code number. * caller-save.c (init_caller_save): Use extract_insn, not insn_extract. * reorg.c (fill_slots_from_thread): Likewise. * reload1.c (reload_as_needed): Likewise. (gen_reload): Likewise. (inc_for_reload): Likewise. (reload_cse_simplify_operands): Likewise. Use the information computed by extract_insn instead of the previous method of finding it by insn code number. * genattrtab.c (write_attr_case): Generate call to extract_insn, not insn_extract. * final.c (final_scan_insn): Use extract_insn, not insn_extract. (cleanup_operand_subregs): Use extract_insn, not insn_extract. Use the information computed by extract_insn instead of the previous method of finding it by insn code number. * regmove.c (find_matches): Likewise. Change meaning of the return value to be nonzero if the optimization can be performed, zero if not. All callers changed. Shorten some variable names to fix formatting problems. (regmove_optimize): Shorten some variable names to fix formatting problems. Use the information computed by extract_insn instead of the previous method of finding it by insn code number. * regclass.c (scan_one_insn): Likewise. (record_reg_classes): Don't compute operand types, use recog_op_type. * reload.c (find_reloads): Lose CONSTRAINTS1 variable; use recog_constraints instead. Wed Nov 4 21:37:46 1998 Jeffrey A Law (law@cygnus.com) * rtl.h (flow2_completed): Declare. * flow.c (flow2_completed): Definition. * toplev.c (rest_of_compilation): Set and clear flow2_completed as necessary. Wed Nov 4 19:15:37 1998 Melissa O'Neill * Makefile.in (libcpp.a): Ranlib libcpp.a. * cppulp.c (user_label_prefix): Initialize. Wed Nov 4 19:07:08 1998 John Wehle (john@feith.com) * flow.c (mark_regs_live_at_end): Mark the stack pointer as live at a RETURN if current_function_sp_is_unchanging is set. Wed Nov 4 18:16:29 1998 Herman A.J. ten Brugge * emit-rtl.c (try_split): Fixed error in Oct 10 patch. Wed Nov 4 15:11:15 1998 Geoffrey Noer * i386/cygwin32.h (MASK_WIN32, MASK_CYGWIN, MASK_WINDOWS, MASK_DLL, TARGET_WIN32, TARGET_CYGWIN, TARGET_WINDOWS, TARGET_DLL): New. (SUBTARGET_SWITCHES): Add -mno-cygwin, -mcygwin, and -mdll options. (CPP_PREDEFINES): Don't define __CYGWIN32__ here. (STARTFILE_SPEC): Handle -mdll, -mno-cygwin options. (CPP_SPEC): Handle -mno-cygwin option. Define __CYWIN__ in addition to __CYGWIN32__. (LIB_SPEC): Handle -mno-cygwin option. (LINK_SPEC): Handle -mdll. Wed Nov 4 22:56:14 1998 J"orn Rennecke * reload.c (find_reloads): Fix test for usage by other reload to handle secondary reloads properly. Wed Nov 4 17:25:10 1998 Kaveh R. Ghazi * reload1.c (ELIMINABLE_REGS, NUM_ELIMINABLE_REGS): Introduce an intermediate structure which has exactly the members provided by ELIMINABLE_REGS. Define NUM_ELIMINABLE_REGS in terms of the static intermediate structure. (init_elim_table): Xmalloc() `reg_eliminate', and initialize it from the intermediate structure. Do the same analogous fix in the case where ELIMINABLE_REGS is not defined. Tue Nov 3 20:50:03 1998 Jeffrey A Law (law@cygnus.com) * pa.h (SELECT_SECTION): Fix thinko. Tue Nov 3 17:51:36 1998 Jim Wilson * dwarf2out.c (output_call_frame_info): Comments on last change. Tue Nov 3 07:51:43 1998 Richard Earnshaw (rearnsha@arm.com) * arm.c (add_constant): When taking the address of an item in the pool, get the mode of the item addressed. * arm.c (final_prescan_insn case INSN): If an insn doesn't contain a SET or a PARALLEL, don't consider it for conditional execution. Restore ABI compatibility for NetBSD. * arm/netbsd.h (DEFAULT_PCC_STRUCT_RETURN): Override setting in arm.h. (RETURN_IN_MEMORY): Likewise. Mon Nov 2 11:46:17 1998 Doug Evans * m32r/m32r.c (m32r_expand_block_move): Fix byte count computations. (m32r_output_block_move): Rewrite bytes < 4 handling. Mon Nov 2 10:10:35 1998 Kaveh R. Ghazi * configure.in: Call AC_FUNC_VFORK. * collect2.c: Define VFORK_STRING as a printable string for error messages (either "vfork" or "fork".) If HAVE_VFORK_H is defined, include vfork.h. If VMS is defined, define vfork() appropriately. Remove vfork check on USG, we're using autoconf. (collect_execute): Pass VFORK_STRING to fatal_perror instead of checking locally what string to pass. (scan_prog_file): Likewise. (scan_libraries): Likewise. * gcc.c: Remove vfork check on USG, we're using autoconf. Besides, no calls to vfork/fork occur in this file. * protoize.c: Likewise. Mon Nov 2 07:52:28 1998 Alexandre Oliva * configure.in (DEFAULT_LINKER): Renamed from LD. (DEFAULT_ASSEMBLER): Renamed from AS; reverted Schwab's patch. (gcc_cv_as): Try $DEFAULT_ASSEMBLER before $AS. * configure: Rebuilt. Mon Nov 2 01:48:10 1998 Alexandre Oliva * BUGS: Fix the regexp for `more' to find the appropriate node. Reported by Joerg Pietschmann * BUGS: Added link to the WWW FAQ. Sun Nov 1 18:27:15 1998 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. Sun Nov 1 11:04:32 1998 Jeffrey A Law (law@cygnus.com) * From Christian Gafton: * i386/linux.h (CPP_PREDEFINES): Add -D__i386__. * sparc/linux.h (CPP_PREDEFINES): Add -D__sparc__. * sparc/linux64.h (CPP_PREDEFINES): Add -D__sparc__. Sat Oct 31 21:42:39 1998 Mark Mitchell * c-common.c (c_get_alias_set): Allow all type-punning through unions. Don't get confused about the type of a bit-field, despite the antics of build_modify_expr. Sat Oct 31 22:35:29 1998 Jean-Pierre Radley * fixinc.sco: Parameterize #include_next values. * fixinc/fixinc.sco: Likewise. Sat Oct 31 20:39:35 1998 Jeffrey A Law (law@cygnus.com) * toplev.c (rest_of_compilation): No longer set reload_completed. * reload1.c (reload): Set it here. Perform instruction splitting after reload has completed if we will be running the scheduler again. Sat Oct 31 12:30:02 1998 Jeffrey A Law (law@cygnus.com) * jump.c (jump_optimize): Initialize mappings from INSN_UID to EH region if exceptions are enabled and we're performing cross jump optimizations. (find_cross_jump): Exit loop if the insns are in different EH regions. Sat Oct 31 10:02:48 1998 Mark Mitchell * dwarf2out.c (output_call_frame_info): Use ASM_OUTPUT_DWARF_DELTA4 for the CIE offset to match frame.c. Sat Oct 31 10:23:14 1998 Kaveh R. Ghazi Reinstall Apr 24th fix, lost during May 6th gcc2 merge: * c-common.c (check_format_info): Don't check for the 'x' format character twice, instead check for 'x' and 'X' Fri Oct 30 14:50:25 1998 Jeffrey A Law (law@cygnus.com) * configure.in (assembler features): Also make gas is configured if we find it in the source tree. Fri Oct 30 13:23:20 1998 Richard Henderson * i386.c (i386_comp_type_attributes): Compare whether the attributes are defined, not their tree nodes. Fri Oct 30 11:39:47 1998 Alexandre Oliva * configure.in (gxx_include_dir): Bitten by autoconf quoting characters. :-( * configure: Rebuilt. Fri Oct 30 10:43:29 1998 Andreas Schwab * configure.in: Ignore non-absolute value in $AS. Fri Oct 30 00:54:25 1998 Peter Jakubek * m68k.h (INDIRECTABLE_1_ADDRESS_P): Fix thinko. Fri Oct 30 00:42:34 1998 Mark Elbrecht * configure.in (msdosdjgpp): Set exeext and target_alias. Thu Oct 29 23:55:43 1998 Bernd Schmidt * flow.c (XNMALLOC): New macro. (flow_int_list_blocks, basic_block_succ, basic_block_pred): New static variables. (add_edge, add_edge_to_label): New static functions. (free_bb_memory): New function. (flow_delete_insn): Delete function. (basic_block_drops_in): Delete variable. (find_basic_blocks): Allocate and initialize basic_block_head, basic_block_succ. Don't allocate basic_block_drops_in. Call free_bb_memory at the beginning. (find_basic_blocks_1): Don't do multiple passes. Delete code to compute basic_block_drops_in. After calling make_edges, mark blocks reached by current block live. Update test for unreachable live blocks. (mark_label_ref): Delete args X, CHECKDUP. Add PRED arg. All callers changed. Simplify to call add_edge_to_label when a LABEL_REF is found. (make_edges): Simplify to call add_edge_to_label instead of mark_label_ref most of the time. Compute here whether control drops into the next block. (delete_unreachable_blocks): Return void. All callers changed. Delete unreachable blocks in reverse order. After deleting all unreachable blocks, renumber the remaining ones and update n_basic_blocks. (delete_block): Speed up deletion a bit. Don't set basic_block_drops_in for deleted blocks. (free_basic_block_vars): Don't free basic_block_drops_in. (life_analysis_1): Update to use new edge representation. (dump_flow_info): Delete code to print basic block info; call dump_bb_data instead. (compute_preds_succs): Delete code to recompute basic_block_drops_in and uid_block_number. Simply copy the previously computed cfg. (dump_bb_data): New arg LIVE_INFO. All callers changed. Print register lifetime information if LIVE_INFO is nonzero. * basic-block.h (dump_bb_data): Adjust prototype. * gcse.c (gcse_main): Update call to dump_bb_data. * rtl.h (free_bb_memory): Declare. * toplev.c (rest_of_compilation): Call free_bb_memory. * reload1.c (struct elim_table): Delete MAX_OFFSET member. (update_eliminable_offsets): Don't compute it. (set_initial_elim_offsets): Don't initialize it. Break out some code into set_initial_label_offsets so the rest of this function can be called from reload_as_needed. Assume that INITIAL_FRAME_POINTER_OFFSET is defined when ELIMINABLE_REGS isn't. (set_initial_label_offsets): New function, broken out of set_initial_elim_offsets. (set_offsets_for_label): New function, broken out of set_label_offsets and reload_as_needed. (reload): Call the two new functions. (reload_as_needed): Call set_initial_elim_offsets instead of duplicating the code. Likewise for set_offsets_for_label. * reload1.c (choose_reload_regs): Fix typo in Oct 17 change. (emit_reload_insns): Ensure that when we set reg_reloaded_valid for any hard reg, reg_reloaded_dead contains valid data. Thu Oct 29 22:30:54 1998 Marcus Meissner * i386.c (i386_comp_type_attributes): Return nonzero for mismatched "stdcall" and "cdecl" attributes. Thu Oct 29 19:05:17 1998 Jim Wilson * sched.c (update_flow_info): Add code to ! found_orig_dest case to handle deleted no-op moves of hard registers. * haifa-sched.c (update_flow_info): Likewise. Thu Oct 29 18:07:47 1998 Jeffrey A Law (law@cygnus.com) * mips.md (reload_{in,out}{si,di}): Emit a USE of HILO at the end of the sequences to reload the HILO register which do not actually reference HILO. Thu Oct 29 12:39:35 1998 Jim Wilson * c-common.c (c_get_alias_set): Handle ARRAY_REF of union field. Thu Oct 29 14:10:22 1998 Andrew MacLeod * except.c (emit_eh_context): Make the EH context register stay alive at -O0 so stupid.c doesn't get confused. 1998-10-29 Herman A.J. ten Brugge * emit-rtl.c (try_split): Do not try to split a BARRIER. Thu Oct 29 01:33:54 1998 Jan Hubicka Jeffrey A Law (law@cygnus.com) * i386.md: Change ix86_cpu == PROCESSOR_PENTIUM to TARGET_PENTIUM. (zero_extendsidi2): Use # in output template and handle completely by splits. (zero_extend splitters): New define_splits. (ashiftrt_32): New pattern. Wed Oct 28 22:58:35 1998 Jason Merrill * tree.c (append_random_chars): New fn. (get_file_function_name_long): Use it. Wed Oct 28 22:27:05 1998 Richard Henderson * Makefile.in (cc1): Put C_OBJS, and thence @extra_c_objs@ last. (LIBCPP_OBJS): New. Add cppulp.o. (cppmain, fix-header): Depend on and use libcpp.a. * configure.in (extra_c_objs, extra_cxx_objs): Use libcpp.a instead of the individual object files. * objc/Make-lang.in (cc1obj): Put OBJC_OBJS, and thence @extra_c_objs@, last. * cccp.c (user_label_prefix): New. (main): Set it off -f*leading-underscore. (special_symbol): Use it. * cpplib.c (special_symbol): Likewise. (cpp_handle_option): Handle -f*leading-underscore. * cppulp.c: New file. * output.h (user_label_prefix): Declare it. * dwarf2out.c (ASM_NAME_TO_STRING): Prepend user_label_prefix. * toplev.c (f_options, main): Handle -f*leading-underscore. * defaults.h (ASM_OUTPUT_LABELREF): Use asm_fprintf instead of referencing USER_LABEL_PREFIX directly. * config/nextstep.h (ASM_OUTPUT_LABELREF): Likewise. * m32r/m32r.h (ASM_OUTPUT_LABELREF): Likewise. * final.c (asm_fprintf): Use user_label_prefix instead. * arm/thumb.c (thumb_print_operand): Likewise. * gcc.c (default_compilers): Pass -f*leading-underscore on to cpp wherever appropriate. Wed Oct 28 23:09:25 1998 Robert Lipe * sco5.h (SUBTARGET_SWITCHES): Add documentation for OpenServer- specific compiler switches. Wed Oct 28 21:05:53 1998 Jeffrey A Law (law@cygnus.com) * Makefile.in (c-common.o): Depend on c-pragma.h. Use $(RTL_H) instead of rtl.h. Wed Oct 28 20:52:47 1998 Kaveh R. Ghazi * gcc.c (EXTRA_SPECS, extra_specs): Introduce an intermediate structure which has exactly the members provided by EXTRA_SPECS. Xmalloc() the real `extra_specs', and initialize it from this intermediate structure. * alpha.h (EXTRA_SPECS): Revert change for missing initializers. * mips.h (EXTRA_SPECS): Likewise. * sparc.h (EXTRA_SPECS): Likewise. Wed Oct 28 16:46:07 1998 Andreas Schwab * function.c (purge_addressof_1): Instead of aborting when a bitfield insertion as a replacement for (MEM (ADDRESSOF)) does not work just put the ADDRESSOF on stack. Otherwise remember all such successful replacements, so that exactly the same replacements can be made on the REG_NOTEs. Remove the special case for CALL insns again. (purge_addressof_replacements): New variable. (purge_addressof): Clear it at end. 1998-10-28 Zack Weinberg * c-lang.c: Declare extern char *yy_cur if USE_CPPLIB. (lang_init): Call check_newline always. * c-lex.c (init_parse) [USE_CPPLIB=1]: After calling cpp_start_read, set yy_cur and yy_lim to read from parse_in.token_buffer, so that we'll see the first #line directive. * cpplib.c (cpp_start_read): finclude the main input file before processing -include/-imacros. Process -imacros and -include separately, and handle -include by stacking a buffer for the file in question as if it'd been #included. * toplev.c (documented_lang_options): Recognize -H when USE_CPPLIB is on. 1998-10-28 Zack Weinberg * cpplib.c: Merge do_once into do_pragma. Break file handling code out of do_include. Move append_include_chain, deps_output, file_cleanup, redundant_include_p, import_hash, lookup_import, add_import, read_filename_string, read_name_map, open_include_file, finclude, safe_read to cppfiles.c. Move prototypes for deps_output, append_include_chain, finclude to cpplib.h. Move definition of struct file_name_list there also. * cppfiles.c: New file. Contains all the above functions broken out of cpplib.c; also hack_vms_include_specification from cccp.c and find_include_file, a new function broken out of do_include. * Makefile.in (cppmain): Depend on cppfiles.o. (fix-header): Likewise. (cppfiles.o): New target. * configure.in (--enable-c-cpplib): Add cppfiles.o to extra_c_objs. Add ../cppfiles.o to extra_cxx_objs. Wed Oct 28 14:06:49 1998 Jim Wilson * dwarfout.c (dwarfout_file_scope_decl): If DECL_CONTEXT, don't abort if pending_types is non-zero. (dwarfout_finish): Verify pending_types is zero before finishing. Wed Oct 28 10:29:09 1998 Nick Clifton * expr.c (convert_move): Use shifts to perform the move if a suitable extend pattern cannot be found. Code written by Richard Henderson . Wed Oct 28 03:59:29 1998 Bernd Schmidt * regclass.c (renumber, regno_allocated): New static variables, moved out of allocate_reg_info. (allocate_reg_info): Move these two variables outside the function. Move code to free memory into new function free_reg_info. (free_reg_info): New function, broken out of allocate_reg_info. * toplev.c (compile_file): Call free_reg_info, not allocate_reg_info. * rtl.h (allocate_reg_info): Don't declare. (free_reg_info): Declare. * final.c (cleanup_subreg_operands): ASM_INPUTs need no treatment. Wed Oct 28 02:38:12 1998 Jason Merrill * toplev.c (compile_file): Temporarily revert last change. Wed Oct 28 00:00:35 1998 Jason Merrill * c-typeck.c (convert_for_assignment): Parenthesize. 1998-10-28 Andreas Schwab * reload1.c (delete_output_reload): Avoid ambigous else. Wed Oct 28 00:10:35 1998 Jeffrey A Law (law@cygnus.com) * toplev.c (compile_file): Call allocate_reg_info to free register table memory. * rtl.h (allocate_reg_info): Declare. * PROJECTS: Remove entry for local spilling. * final.c (cleanup_subreg_operands): New function. (final_scan_insn): Use it. (alter_subreg): Clear the "used" field when we turn a SUBREG into a REG. * reload1.c (reload): Delete CLOBBER insns and also cleanup SUBREG operands when reload has finished. * reload.h (cleanup_subreg_operands): Declare.. * flow.c (life_analysis_1): No longer delete CLOBBER insns after reload. Handled in reload itself. Tue Oct 27 23:32:34 1998 Bernd Schmidt * reload1.c (verify_initial_offsets): New function. (reload): Call it after reload_as_needed. Also verify that the frame size stays constant during reload_as_needed. * i386.h (CONST_DOUBLE_OK_FOR_LETTER_P): Undo Jul 26 change. * reload.h (struct insn_chain): Add need_operand_change element. * reload1.c (new_insn_chain): Clear it. (calculate_needs_all_insns): Set it; don't overload need_reload. (reload_as_needed): Use it. * reload.c (find_reloads_address): Use BASE_REG_CLASS instead of reload_address_base_reg_class throughout. Similar for INDEX_REG_CLASS and reload_address_index_reg_class. (find_reloads_address_1): Likewise. * reload.h (reload_address_base_reg_class, reload_address_index_reg_class): Don't declare. * reload1.c (reg_old_renumber, pseudo_previous_regs, pseudo_forbidden_regs, bad_spill_regs_global): New static variables. (used_spill_regs): Now static. (reload_address_base_reg_class, reload_address_index_reg_class, regs_explicitly_used, counted_for_groups, counted_for_nongroups, basic_block_needs, max_needs, group_size, group_mode, max_groups, max_nongroups, max_needs_insn, max_groups_insn, max_nongroups_insn, forbidden_regs): Deleted variables. (init_reload): Delete code to compute base/index reg classes. (reload): Delete variable J. Delete code to manage basic_block_needs. Don't compute regs_explicitly_used. Allocate, initialize and free reg_old_renumber, pseudo_forbidden_regs, pseudo_previous_regs. Initialize bad_spill_regs_global. Don't call order_regs_for_reload here. Don't initialize spill_reg_order and n_spills. Don't forbid explicitly used regs to be used for spill regs. Change main loop to infinite loop, with explicit break statements. Make SOMETHING_CHANGED variable local to that loop. Don't initialize max_needs, max_groups, max_nongroups, max_needs_insn, max_groups_insn, max_nongroups_insn, group_size, group_mode. Make sure spilled_pseudos is cleared before calling spill_hard_reg or new_spill_reg. Don't call dump_needs. Delete code to reset potential_reload_regs. Delete code to terminate loop conditional on the global needs variables showing no further needs. (calculate_needs_all_insns): Return void. All callers changed. Initialize something_needs_elimination here, not in reload. Delete avoid_return_reg kludge. (calculate_needs): Lose AVOID_RETURN_REG and GLOBAL args, return void. All callers changed. Initialize the group_mode and group_size elements of the arg CHAIN. Delete code to manage basic_block_needs. Operate on elements of CHAIN instead of global variables. Delete avoid_return_reg kludge. (find_tworeg_group): Lose GLOBAL arg, take CHAIN arg, return void. All callers changed. Operate on elements of CHAIN instead of global variables. Delete special SMALL_REGISTER_CLASSES code. Delete spill_failure code; now in new_spill_reg. (find_group): Lose GLOBAL arg, take CHAIN arg, return void. All callers changed. Operate on elements of CHAIN instead of global variables. (maybe_mark_pseudo_spilled): New static function. (find_reload_regs): Lose GLOBAL arg, take CHAIN arg, return void. All callers changed. Operate on elements of CHAIN instead of global variables. Call order_regs_for_reload here, not in reload. Initialize spill_reg_order and n_spills. Simplify test whether an asm insn is involved. Delete spill_failure code; now in new_spill_reg. Call maybe_mark_pseudo_spilled for everything marked as live in CHAIN. Merge CHAIN's used_spill_regs into the global variable used_spill_regs. (dump_needs): Take CHAIN arg. No longer static, to prevent the compiler from optimizing this function (now unused) away. Operate on elements of CHAIN instead of global variables. (possible_group_p): Lose MAX_GROUPS arg, take CHAIN arg. All callers changed. Operate on elements of CHAIN instead of global variables. (count_possible_groups): Lose GROUP_SIZE, GROUP_MODE, MAX_GROUPS args, take CHAIN arg. All callers changed. Operate on elements of CHAIN instead of global variables. (new_spill_reg): Lose MAX_NEEDS, MAX_NONGROUPS, GLOBAL args, take CHAIN, NONGROUP args. Return void. All callers changed. Verify caller isn't trying to spill a pseudo. Simplify test for illegal reg, just use bad_spill_regs. Generate better error messages. Operate on elements of CHAIN instead of global variables. Mark spilled register in CHAIN's used_spill_regs element. Don't call spill_hard_reg. (spill_hard_reg): Lose GLOBAL arg, return void. All callers changed. Mark spilled hard regs in bad_spill_regs_global. Mark affected pseudos in spilled_pseudos, but don't spill them. (ior_hard_reg_set): New static function. (finish_spills): Return int. All callers changed. Compute spill_reg_order, n_spills and spill_regs here. Also update regs_ever_live for regs used as spills. For every pseudo in spilled_pseudos, spill it and mark the previous hard reg it had in pseudo_previous_regs. Compute which hard regs are used as spills in insns during which it is live, and retry global register allocation. Update all life information in the reload_insn_chain not to include pseudos without hard regs. Call alter_reg for all affected speudos. (scan_paradoxical_subregs): Disable SMALL_REGISTER_CLASSES special case, it's not clear what it's supposed to do. (hard_reg_use_compare): Take bad_spill_regs into account. (pseudos_counted): New static variable. (count_pseudo): New static function. (order_regs_for_reload): Take CHAIN arg. All callers changed. Initialize bad_spill_regs from bad_spill_regs_global, then merge any hard registers explicitly used across the current insn into the set. Compute hard_reg_n_uses taking only pseudos live across this insn into account. Tweak sorting of potential_reload_regs. (compare_spill_regs): Delete function. (reload_as_needed): Don't sort the spill_regs array, it's computed in proper order in finish_spills. Delete avoid_return_reg kludge. Delete code to manage basic_block_needs. (allocate_reload_reg): Minor speed/readability tweaks. Operate on elements of CHAIN instead of global variables. (choose_reload_regs): Lose AVOID_RETURN_REG arg. All callers changed. Delete avoid_return_reg kludge. Initialize reload_reg_used from CHAIN's used_spill_regs element. Delete unused label FAIL. (reload_combine): Replace reload_address_index_reg_class with INDEX_REGS. Don't use used_spill_regs to determine information about lifetime of hard regs. Tue Oct 27 13:15:02 1998 Nick Clifton * toplev.c (display_help): Ignore empty target specific options, and if -W is also specified on the command line then display undocumented options. * config/arm/arm.c: Updated with changes in devo sources. * config/arm/arm.h: Updated with changes in devo sources. * config/arm/lib1funcs.asm: Updated with changes in devo sources. * config/arm/lib1thumb.asm: Add ELF support. Tue Oct 27 16:11:43 1998 David Edelsohn * collect2.c (aix64_flag): New variable. (main, case 'b'): Parse it. (GCC_CHECK_HDR): Object magic number must match mode. (scan_prog_file): Only check for shared object if valid header. Print debugging if header/mode mismatch. Tue Oct 27 10:15:02 1998 Nick Clifton Added support for arm-elf-linux configuration, submitted by Philip Blundell , and integrated this with the arm-elf code developed by Catherine Moore . The following files are affected: * configure.in: Add arm-*-linux-gnu, armv2-*-linux and arm-*-elf targets. * configure: Regenerated. * config/arm/aout.h: Add default definitions of REGISTER_PREFIX, USER_LABEL_PREFIX and LOCAL_LABEL_PREFIX. Make other macro definitions conditional on their not having been already defined. * config/arm/lin1funcs.asm: Add ELF only macros to generate .size and .type directives, and add "(PLT)" qualification to function calls. * config/arm/linux.h: Deleted. This file is now superseded by either linux-elf.h or linux-aout.h. * config/arm/linux-gas.h: Define `inhibit_libc' if cross-compiling. (CLEAR_INSN_CACHE): New macro, currently disabled (awaiting kernel support). Move definitions from old linux.h file here. * config/arm/elf.h: New file. Generic ARM/ELF support. * config/arm/linux-aout.h: New file. Support for Linux with a.out. * config/arm/linux-elf.h: New file. Support for Linux with ELF. * config/arm/linux-elf26.h: New file. Support for Linux with ELF using the 26bit APCS. * config/arm/unknown-elf.h: New file. Support for OS'es other than Linux with ELF. * config/arm/t-arm-elf: New file. makefile fragment for arm-elf builds. * config/arm/coff.h: Include aout.h for basic assembler macros. Add support for -mstructure_size_boundary= command line option. * config/arm/arm.h: Add support for -mstructure_size_boundary= command line option. Make macro definitions conditional on their not having been already defined. * config/arm/arm.c: Add support for -mstructure_size_boundary= command line option. Tue Oct 27 08:56:46 1998 Andrew MacLeod * dwarfout.c (ASM_OUTPUT_DWARF_STRING_NEWLINE): ASM_OUTPUT_DWARF_STRING has been changed to not include a newline. Use this macro instead. (output_enumeral_list, const_value_attribute, name_attribute, comp_dir_attribute, prototyped_attribute, producer_attribute, inline_attribute, pure_or_virtual_attribute, output_inheritance_die, dwarfout_file_scope_decl, generate_new_sfname_entry, generate_macinfo_entry, dwarfout_init, dwarfout_finish): Use ASM_OUTPUT_DWARF_STRING_NEWLINE macro. Mon Oct 26 13:35:02 1998 Richard Henderson * combine.c (subst): Process the inputs to a parallel asm_operands only once. Mon Oct 26 13:32:31 1998 Richard Henderson * stmt.c (expand_asm_operands): Accept `=' or `+' at any position. Mon Oct 26 12:53:14 1998 Jeffrey A Law (law@cygnus.com) * tm.texi (ASM_OUTPUT_MAX_SKIP_ALIGN): Document. Mon Oct 26 00:36:58 1998 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. Sun Oct 25 23:36:52 1998 Jason Merrill * stmt.c (expand_fixup): Set fixup->before_jump to a NOTE_INSN_DELETED instead of a NOTE_INSN_BLOCK_BEG. Sun Oct 25 15:49:57 1998 Kaveh R. Ghazi * Makefile.in (recog.o): Depend on toplev.h. (insn-emit.o): Depend on recog.h. (insn-peep.o): Depend on recog.h and insn-config.h. * combine.c (simplify_set): Remove unused variable `scratches'. * final.c (final_scan_insn): Wrap declaration of variables `vlen' and `idx' in macro conditional controlling their use. * genemit.c (main): Make the generated output file include recog.h. Don't have it declare `insn_operand_constraint', since we get it from recog.h. * genpeep.c (main): Make the generated output file include insn-config.h and recog.h. * recog.c: Include toplev.h. (extract_insn): Remove unused variable `p'. * regclass.c (fix_register): Add missing braces around initializer for `what_option'. (allocate_reg_info): Move variable `i' into the scope where it is used. Change its type to `size_t'. Sun Oct 25 13:10:15 1998 Bernd Schmidt * reload.c (push_reload): When merging reloads, make sure that reload_in_reg and reload_in are from the same reload in all cases. Sun Oct 25 12:07:00 1998 Mumit Khan * i386/crtdll.h (CPP_PREDEFINES): Fix typo. * i386/mingw32.h (CPP_PREDEFINES): Likewise. Fri Oct 23 23:42:03 1998 David Edelsohn * loop.c (loop_has_tablejump): New variable. (prescan_loop): Scan for it. (insert_bct): Replace explicit scan with use of it. * regclass.c (regclass): Restore loop variable j. (record_reg_classes): Deterine op_types modifiers and initialize classes[i] before matching constraints. Handle matching constraints 5-9. Fri Oct 23 13:55:48 1998 Jim Wilson * m32r/m32r.c (gen_split_move_double): Call alter_subreg. Delete subreg support. Fri Oct 23 16:19:24 1998 Kaveh R. Ghazi * mips.h (EXTRA_SPECS): Add missing initializers. Fri Oct 23 16:08:39 1998 Kaveh R. Ghazi * sparc.h (EXTRA_SPECS): Add missing initializers. (sparc_defer_case_vector): Provide a prototype. * svr4.h (ASM_OUTPUT_ASCII): Cast STRING_LIMIT to (long) when comparing it to the result of a pointer subtraction. Fri Oct 23 15:34:14 1998 Kaveh R. Ghazi * alpha.c (override_options): Use ISDIGIT(), not isdigit(). Cast the argument to (unsigned char). * alpha.h (EXTRA_SPECS): Add missing initializers. (ASM_GENERATE_INTERNAL_LABEL): Ensure the argument matches the format specifier. Fri Oct 23 13:12:35 1998 Jeffrey A Law (law@cygnus.com) * flow.c (life_analysis_1): Enable "rescan" code after reload. (propagate_block): Delete dead code after reload. * sched.c (update_flow_info): Revert Oct 19, 1998 change. Brings back Oct 15, 1998 change. * haifa-sched.c (update_flow_info): Likewise. * flow.c (life_analysis_1): Delete CLOBBER insns after reload. * mn10200.md (truncated shift): Accept constant inputs too. Fri Oct 23 04:06:57 1998 Richard Earnshaw (rearnsha@arm.com) * machmode.h (mode_mask_array): No longer const. * rtl.c (init_rtl): Fully initialize it if EXTRA_CC_MODES defined. Fri Oct 23 11:19:06 1998 Martin v. Löwis * frame.c: Somewhat explain `FDE'. Suggested by Brendan Kehoe Fri Oct 23 00:56:11 1998 Jason Merrill * expr.c (pending_chain): Move up. (save_expr_status): Do save pending_chain. (restore_expr_status): And restore it. * function.h (struct function): Add pending_chain. 1998-10-23 Herman A.J. ten Brugge * reorg.c (relax_delay_slots): Fixed test for mostly_true_jump. The did not match the code. Fri Oct 23 00:07:01 1998 Bernd Schmidt * regclass.c (regclass): Break out some code into new function scan_one_insn, and into regclass_init. (init_cost): New static variable, moved out of regclass. (regclass_init): Initialize it here, not in . (scan_one_insn): New static function, broken out of regclass. * recog.c (apply_change_group): Break out some code into new function insn_invalid_p. (insn_invalid_p): New static fn, broken out of apply_change_group. Thu Oct 22 22:34:42 1998 Jim Wilson * reload1.c (reload_as_needed): When rewrite POST_INC, verify reg_reloaded_contents matches incremented pseudo. * v850/v850.c (v850_reorg): Call alter_subreg. Delete subreg support. Fri Oct 23 11:11:56 1998 Michael Hayes * rtl.def (POST_MODIFY, PRE_MODIFY): New generalized operators for addressing modes with side effects. These are currently placeholders for the C4x target. Thu Oct 22 16:46:35 1998 Bernd Schmidt * loop.c (express_from): Make sure that when generating a PLUS of a PLUS, any constant expression appears on the outermost PLUS. Thu Oct 22 15:46:23 1998 Per Bothner (bothner@cygnus.com) * Makefile.in (distdir-cvs, distdir-start): Clean up so it works if "$(srcdir)" != ".". Wed Oct 21 19:23:59 1998 Jim Wilson * expmed.c (store_bit_field): If need to add a SUBREG, then remove existing SUBREG if we can, otherwise abort. Wed Oct 21 09:58:51 1998 Mark Mitchell * c-common.c (c_apply_type_quals_to_decl): Don't crash when `restrict' is applied to a non-pointer variable. Wed Oct 21 09:18:58 1998 Mark Mitchell * invoke.texi: Document -flang-isoc9x. * Makefile.in (OBJS): Add splay-tree.o. (c-common.o): Depend on rtl.h. (splay-tree.o): List dependencies and provide build rule. * rtl.h (record_alias_subset): New function. * alias.c: Include splay-tree.h. (alias_set_entry): New type. (CHECK_ALIAS_SETS_FOR_CONSISTENCY): Remove. (DIFFERENT_ALIAS_SETS_P): Use mem_in_disjoint_alias_sets_p. (mems_in_disjoin_alias_sets_p): New function. (alias_set_compare): Likewise. (insert_subset_children): Likewise. (get_alias_set_entry): Likewise. * tree.h (TYPE_RESTRICT): New macro. (TYPE_UNQUALIFIED): New manifest constant. (TYPE_QUAL_CONST): Likewise. (TYPE_QUAL_VOLATILE): Likewise. (TYPE_QUAL_RESTRICT): Likewise. (tree_type): Add restrict_flag. Reduce count of free bits. (DECL_POINTER_ALIAS_SET): New macro. (DECL_POINTER_ALIAS_SET_KNOWN_P): Likewise. (tree_decl): Add pointer_alias_set. (build_qualified_type): New function. (build_type_variant): Define in terms of build_qualified_type. * tree.c (set_type_quals): New function. (make_node): Initialize DECL_POINTER_ALIAS_SET. (build_type_attribute_variant): Use build_qualified_type and set_type_quals. (build_type_variant): Rename, and modify, to become... (build_qualified_type): New function. (build_complex_type): Use set_type_quals. * c-tree.h (C_TYPE_OBJECT_P): New macro. (C_TYPE_FUNCTION_P): Likewise. (C_TYPE_INCOMPLETE_P): Likewise. (C_TYPE_OBJECT_OR_INCOMPLETE_P): Likewise. (c_apply_type_quals_to_decl): New function. (c_build_qualified_type): New function. (c_build_type_variant): Define in terms of c_build_qualified_type. (flag_isoc9x): Declare. * c-typeck.c (qualify_type): Use c_build_qualified_type. (common_type): Change to use TYPE_QUALS. (comptypes): Likewise. (convert_for_assignment): Likewise. * c-aux-info.c (gen_type): Likewise. Deal with `restrict'. * c-decl.c (flag_isoc9x): Define. (c_decode_option): Handle -flang-isoc9x. (grokdeclarator): Update to handle restrict. Use TYPE_QUALS, c_build_qualified_type, etc. Use c_apply_type_quals_to_decl. * c-lex.c (init_lex): Deal with restrict. (init_lex): Don't treat restrict as a reserved word in -traditional mode, or without -flang-isoc9x. * c-lex.h (rid): Add RID_RESTRICT. * c-parse.gperf (restrict, __restrict, __restrict__): Make equivalent to RID_RESTRICT. * c-parse.in (TYPE_QUAL): Update comment. * c-common.c: Include rtl.h. (c_find_base_decl): New function. (c_build_type_variant): Rename, and modify, to become ... (c_build_qualified_type): New function. (c_apply_type_quals_to_decl): Likewise. (c_get_alias_set): For INDIRECT_REFs, check to see if we can find a particular alias set for the reference. * toplev.c (documented_lang_options): Add -flang-isoc9x. Wed Oct 21 09:15:06 1998 Nick Clifton * config/arm/arm.h (TARGET_SWITCHES): Document arm specific command line switches. Tue Oct 20 10:04:51 1998 Graham * reload.c (loc_mentioned_in_p): Add missing braces to bind else to correct if. Mon Oct 19 16:34:05 1998 Tom Tromey * gcc.c (option_map): Added --classpath and --CLASSPATH. Tue Oct 20 10:59:02 1998 Gavin Romig-Koch * regclass.c (fix_register): Add error message. * invoke.texi (-fcall-used-REG,-fcall-saved-REG): Note the new error message. Tue Oct 20 10:12:17 1998 Kaveh R. Ghazi * c-decl.c (warn_missing_noreturn): New global variable. (c_decode_option): Check for new flags -W{no-}missing-noreturn. (finish_function): Implement missing noreturn warning. * c-tree.h (warn_missing_noreturn): Declare extern. * invoke.texi: Document new flags. * toplev.c (documented_lang_options): Add description. Tue Oct 20 22:16:11 1998 Michael Hayes * config/c4x/c4x.c (c4x_parallel_process): Disable until BCT loop optimization stable for the C4x. (c4x_rptb_info_t, c4x_dump, c4x_rptb_in_range, c4x_rptb_unjumped_loop, c4x_rptb_find_comp_and_jump, c4x_rptb_loop_info_get, c4x_rptb_emit_init, c4x_rptb_process): Deleted (superseded by BCT loop optimization). (c4x_address_conflict): Be more paranoid when packing a volatile memref in a parallel load/store. Tue Oct 20 21:56:05 1998 Michael Hayes * config/c4x/c4x.md (repeat_block_top, repeat_block_end, repeat_block_filler): Deleted. (*ashlqi3_set, *ashrqi3_const_set, *ashrqi3_nonconst_clobber): Condition code not set if destination register from 'c' class. (*subbqi3_carry_clobber): Fix typo. 1998-10-18 Herman A.J. ten Brugge * reorg.c (steal_delay_list_from_target): Check for insns that modify the condition codes and effect the direction of the jump in the sequence. Sat Oct 17 13:09:09 1998 Graham * function.c (purge_addressof_1): Replace call to emit_insns_before() with emit_insn_before(). Mon Oct 19 19:34:03 1998 Mike Stump * libgcc2.c (__pure_virtual): Call __terminate instead of _exit. Mon Oct 19 13:26:24 1998 Bernd Schmidt * jump.c (sets_cc0_p): Compile only if HAVE_cc0. Mon Oct 19 11:40:56 1998 Jeffrey A Law (law@cygnus.com) * gcse.c (compute_hash_table): Correctly identify hard regs which are clobbered across calls. * loop.c (scan_loop): Be more selective about what invariants are moved out of a loop. Mon Oct 19 10:46:58 1998 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. Mon Oct 19 11:40:56 1998 Jeffrey A Law (law@cygnus.com) * libgcc2.c (eh_context_static): Do not call malloc to allocate the static eh_context structure. Mon Oct 19 10:45:40 1998 Bernd Schmidt * combine.c (recog_for_combine): Lose PADDED_SCRATCHES arg. All callers changed. (try_combine): Don't update max_scratch. * flow.c (max_scratch, num_scratch): Delete variables. (life_analysis_1): Don't initialize max_scratch. (propagate_block): Don't update max_scratch. (mark_set_1): Don't increment num_scratch. * regs.h (max_scratch): Delete declaration. Mon Oct 19 10:28:15 1998 Jeffrey A Law (law@cygnus.com) * reload1.c (reload_reg_free_before_p): Hack. Return 0 if EQUIV is nonzero. This is temporary! * sched.c (update_flow_info): Handle death notes made invalid by instruction splitting. Partially reverts Oct 15, 1998 patch. * haifa-sched.c (update_flow_info): Likewise. Sun Oct 18 17:31:26 1998 Jeffrey A Law (law@cygnus.com) * function.c (uninitialized_vars_warning): Do not warn for a VAR_DECL if it has a nonzero DECL_INITIAL. Sat Oct 17 23:18:08 1998 Kaveh R. Ghazi * Makefile.in (flow.o): Depend on recog.h. * cpplib.h (directive_table): Add missing initializiers. (finclude): Change type of variable `bsize' to size_t. * cse.c (rtx_cost): Mark parameter `outer_code' with ATTRIBUTE_UNUSED. * dwarfout.h (dwarfout_label): Wrap prototype in macro RTX_CODE. * fix-header.c (lookup_std_proto): Cast the result of `strlen' to `int' when comparing against one. (cpp_file_line_for_message): Mark parameter `pfile' with ATTRIBUTE_UNUSED. (cpp_fatal): Mark parameter `pfile' with ATTRIBUTE_UNUSED. * flow.c: Include recog.h. (sbitmap_copy): Cast arguments 1 & 2 of `bcopy' to (PTR). * function.c (thread_prologue_and_epilogue_insns): Mark parameter `f' with ATTRIBUTE_UNUSED. (reposition_prologue_and_epilogue_notes): Likewise. * genopinit.c (gen_insn): Cast argument of ctype functions to `unsigned char'. * haifa-sched.c: Include recog.h. (blockage_range): Cast result of UNIT_BLOCKED macro to (int) when comparing against one. * libgcc2.a (__throw): Revert ATTRIBUTE_UNUSED change for now. * mips-tfile.c (parse_end): Cast the argument of ctype function to `unsigned char'. (parse_ent): Likewise. (parse_input): Likewise. * optabs.c (init_libfuncs): Likewise. * protoize.c (find_rightmost_formals_list): Likewise. * recog.h (const_double_operand): Fix typo in prototype. * tlink.c (scan_linker_output): Cast the argument of ctype function to `unsigned char'. * toplev.c (check_lang_option): Cast the result of `strlen' to `int' when comparing against one. Sat Oct 17 13:09:09 1998 Graham * gcse.c (dump_cuid_table): Correct typo. Sat Oct 17 11:02:47 1998 Nick Clifton * toplev.c (display_help): Prepend '-m' to target specific options. (check_lang_option): Ignore text after end of first word of a language specific option. Sat Oct 17 02:26:03 1998 Bernd Schmidt * reload1.c (reg_used_by_pseudo): New static variable. (choose_reload_regs): Initialize it. Use it instead of testing spill_reg_order to determine whether a pseudo is live in a hard register across the current insn. Fix a typo in a reference to reload_reg_rtx. * flow.c (propagate_block): Replace code that computes and uses regs_sometimes_live with simpler code that just walks the set of currently live registers. * Makefile.in (insn-extract.o): Fix dependencies. * genextract.c (main): Generate includes for insn-config.h and recog.h. Delete generation of declarations which are now in recog.h. * genrecog.c (main): Delete generation of definitions which are now in recog.c. * local-alloc.c (block_alloc): Use extract_insn and the variables it sets up instead of looking up values by insn_code. * recog.c (recog_operand, recog_operand_loc, recog_dup_loc, recog_dup_num): Define here instead of generating the definition in genrecog.c. (recog_n_operands, recog_n_dups, recog_n_alternatives, recog_operand_mode, recog_constraints, recog_operand_address_p): New variables. (extract_insn): New function. * recog.h (extract_insn): Declare function. (which_alternative, recog_n_operands, recog_n_dups, recog_n_alternatives, recog_operand_mode, recog_constraints, recog_operand_address_p): Declare variables. * regclass.c (n_occurrences): New static function. * reload.c (n_occurrences): Delete function. (find_reloads): Use extract_insn. * reload.h (n_occurrences): Delete declaration. Sat Oct 17 01:17:51 1998 Jeffrey A Law (law@cygnus.com) * reload1.c (reload_as_needed): Fix test for when to call update_eliminable_offsets. Fri Oct 16 20:40:50 1998 J"orn Rennecke Fix consistency problems with reg_equiv_{mem,address}; Improve reload inheritance; * reload.c (reload_out_reg): New variable. (loc_mentioned_in_p, remove_address_replacements): New functions. (remove_replacements): Deleted. (push_reload): Set reload_out_reg[i]. When merging, also set reload_{in,out}_reg[i], and remove duplicate address reloads. (combine_reloads): Copy reload_out_reg[i]. (find_reloads): Do make_memloc substitution also when reg_equiv_memory_loc[regno] and num_not_at_initial_offset are both nonzero. Include *recog_operand_loc in commutativity operand changes. Generate optional output reloads. Delete reference to n_memlocs. Don't set *recog_operand_loc before processing operands. Call make_memloc in reg_equiv_address code. Set *recog_operand_loc only after processing operands, and only if replace is true. Return a value. When changing address reload types for operands that didn't get reloaded, use RELOAD_FOR_OPADDR_ADDRESS for RELOAD_FOR_INPADDR_ADDRESS / RELOAD_FOR_OUTADDR_ADDRESS reloads. Don't emit USEs for pseudo SUBREGs when not replacing. (find_reloads_address): Do make_memloc substitution also when reg_equiv_memory_loc[regno] and num_not_at_initial_offset are both nonzero. (find_reloads_toplev): Likewise. Call make_memloc in reg_equiv_address code. (debug_reload_to_stream): Add code to output reload_out_reg. (make_memloc): Delete local variable i, ifdefed out code, and references to memlocs and n_memlocs. (memlocs, n_memlocs): Delete. (push_secondary_reload): Clear reload_out_reg. (find_reloads_address_1): Provide memrefloc argument to all calls to find_reloads_address. In AUTO_INC code, handle non-directly addressable equivalences properly. * reload.h (reload_out_reg, num_not_at_initial_offset): Declare. (find_reloads): Add return type. (remove_address_replacements, deallocate_reload_reg): Declare. * reload1.c (num_not_at_initial_offset): No longer static. (delete_address_reloads, delete_address_reloads_1): Likewise. (deallocate_reload_reg): New function. (spill_reg_stored_to): New array. (eliminate_regs): Don't substitute from reg_equiv_memory_loc. (eliminate_regs_in_insn): Move assignments of previous_offset and max_offset fields, and recalculation of num_not_at_initial_offset into new static function: (update_eliminable_offsets) . (reload_as_needed): Call update_eliminable_offsets after calling find_reloads. Call forget_old_reloads_1 with contents of reloaded auto_inc expressions if the actual addressing can't be changed to match the auto_inc. (choose_reload_regs): For inheritance, replace reload_reg_free_before_p test with reload_reg_used_at_all test, and remove stand-alone reload_reg_used_at_all test. Use reload_out_reg to determine which reload regs have output reloads. Treat reload_override_in more similar to inherited reloads. Handle (subreg (reg... for inheritance. For flag_expensive_optimizations, add an extra pass to remove unnecessary reloads from known working inheritance. Delete obsolete code for pseudos replaced with MEMs. Handle inheritance from auto_inc expressions. (emit_reload_insns): If reload_in is a MEM, set OLD to reload_in_reg[j]. Don't reload directly from oldequiv; if it's a pseudo with a stack slot, use reload_in[j]. Check that reload_in_reg[j] is a MEM before replacing reload_in from reg_reloaded_contents. Include non-spill registers in reload inheritance processing. Also try to use reload_out_reg to set spill_reg_store / reg_last_reload_reg. In code to set new_spill_reg_store, use single_set to find out if there is a single set. Add code that allows to delete optional output reloads. Add code to allow deletion of output reloads that use no spill reg. At the end, set reload_override_in to oldequiv. Also call delete_output_reload if reload_out_reg is equal to old in oldequiv code. Add code to call delete_output_reload for stores with no matching load. Set / use spill_reg_stored_to. Handle case where secondary output reload uses a temporary, but actual store isn't found. When looking for a store of a value not loaded in order to call delete_output_reload, count_occurrences should return 0 for no loads; but discount inherited input reloadill_reg_stored_to. Do checks for extra uses of REG. Changed all callers. Use delete_address_reloads. (reload): Take return value of find_reloads into account. If a no-op set needs more than one reload, delete it. (reload_reg_free_before_p): RELOAD_FOR_INPUT can ignore RELOAD_FOR_INPUT_ADDRESS / RELOAD_FOR_INPADDR_ADDRESS for the same operand. (clear_reload_reg_in_use): Check for other reloads that keep a register in use. (reload_reg_free_for_value_p): Handle RELOAD_FOR_OPERAND_ADDRESS / RELOAD_FOR_OPADDR_ADDR. Take into account when an address address reload is only needed for the address reload we are considering. (count_occurrences): Use rtx_equal_p for MEMs. (inc_for_reload): Return instruction that stores into RELOADREG. New argument two, IN, and rtx. Changed all callers. (calculate_needs_all_insns, reload_as_needed): Don't clear after_call for a CLOBBER. Keep track of how many hard registers need to be copied from after_call, and don't clear after_call before we have seen that much copies, or we see a different instruction. Fri Oct 16 10:58:23 1998 Jeffrey A Law (law@cygnus.com) * flow.c (find_basic_blocks_1): Do not delete unreachable blocks after reload has completed. Fri Oct 16 17:26:10 1998 Dave Brolley * cpplib.c (cpp_get_token): Replace whitespace that occurs between a macro name and the next token with a single blank if that whitespace is in a macro buffer and the next token is not '('. Fri Oct 16 15:44:02 1998 Dave Brolley * cccp.c (rescan): Handle multibyte characters ending in backslash. (rescan): Likewise. (skip_if_group): Likewise. (skip_to_end_of_comment): Likewise. (macarg1): Likewise. (discard_comments): Likewise. (change_newlines): Likewise. Fri Oct 16 15:26:24 1998 Dave Brolley * c-lex.c (yylex): Fix unaligned access of wchar_t. Fri Oct 16 10:47:53 1998 Nick Clifton * config/arm/arm.h (TARGET_SWITCHES): Add --help documentation. (TARGET_OPTIONS): Add --help documentation. Fri Oct 16 11:49:01 1998 Kaveh R. Ghazi * rtl.h (sets_cc0_p): Revert Oct 14 ATTRIBUTE_NORETURN change. Fri Oct 16 07:08:46 1998 Bruce Korb * fixinc/* Moved in from ../contrib directory in preparation for integrating it into the normal build process. In particular, fixinc/Makefile.in must be config-ed into the build directory as fixinc/Makefile. Proposed patches to ./Makefile.in and ./configure.in will be "in the mail" momentarily. Fri Oct 16 08:13:46 1998 David S. Miller * cse.c (cse_basic_block): Fixup hash flushing loop so we do not accidently walk into the free list. Comment how that can happen. (invalidate): Fix indentation. Thu Oct 15 23:53:29 1998 Bernd Schmidt Jeffrey A Law (law@cygnus.com) * flow.c (life_analysis_1): Do not clobber regs_ever_live after reload. Never perform rescans of the insn chain after reload. (propagate_block): Do not delete insn or create new autoinc addressing modes after reload. * jump.c (jump_optimize): Unconditionally use the code that was previously conditional on PRESERVE_DEATH_INFO_REGNO_P. * reload1.c (reload): When reloading is finished, delete all REG_DEAD and REG_UNUSED notes. (emit_reload_insns): Delete all code that was conditional on PRESERVE_DEATH_INFO_REGNO_P. (no_longer_dead_regs): Delete variable. (reload_cse_delete_death_notes): Delete function. (reload_cse_no_longer_dead): Delete function. (reload_cse_regs_1): Delete all code to handle deletion of death notes. (reload_cse_noop_set_p): Likewise. (reload_cse_simplify_set): Likewise. (reload_cse_simplify_operands): Likewise. (reload_cse_move2add): Likewise. * reorg.c (used_spill_regs): Delete declaration. (max_label_num_after_reload): Delete declaration. (find_dead_or_set_registers): Don't assume that spill regs are dead at a CODE_LABEL. * rtlanal.c (dead_or_set_regno_p): Death notes are always accurate, even after reload. * sched.c (sched_analyze_insn): Likewise. (update_flow_info): Likewise. * haifa-sched.c (sched_analyze_insn): Likewise. (update_flow_info): Likewise. * tm.texi (PRESERVE_DEATH_INFO_REGNO_P): Delete documentation. * toplev.c (max_label_num_after_reload): Delete variable. (rest_of_compilation): Don't set max_label_num_after_reload. Call life_analysis after reload_cse_regs if optimizing. * config/gmicro/gmicro.h: Delete comment referring to PRESERVE_DEATH_INFO_REGNO_P. * config/i386/i386.h: Likewise. * config/m88k/m88k.h: Likewise. * config/m32r/m32r.h (PRESERVE_DEATH_INFO_REGNO_P): Delete definition. * config/sh/sh.h: Likewise. Thu Oct 15 19:48:41 1998 David Edelsohn * loop.c (strength_reduce): Restore marking bct_p as ATTRIBUTE_UNUSED. * rs6000.c (optimization_options): Change #ifdef HAIFA to HAVE_decrement_and_branch_on_count. (small_data_operand): Remove TARGET_ELF condition for marking parameters ATTRIBUTE_UNUSED. Thu Oct 15 11:45:51 1998 Robert Lipe * config/i386/sco5.h (MAX_OFILE_ALIGNMENT): Define. (SELECT_SECTION): Resync with svr4.h. Thu Oct 15 12:42:13 1998 David Edelsohn * loop.c (strength_reduce): Undo Oct 14 change marking bct_p ATTRIBUTE_UNUSED. Thu Oct 15 00:57:55 1998 Robert Lipe * c-pragma.c (handle_pragma_token): Test for null tree before dereferencing TREE_CODE. Thu Oct 15 17:36:48 1998 Michael Hayes * config/c4x/c4x.c: Convert to use GEN_INT. (c4x_parallel_process): Rework to handle new repeat loop structure. * config/c4x/c4x.md: Convert to use GEN_INT. (rptb_end): Convert to use GE test. Replace uses with clobbers. (decrement_and_branch_on_count): Likewise. * config/c4x/c4x.h (REPEAT_BLOCK_PROCESS): Deleted hook now that loop.c has the desired functionality. (rc_reg_operand): New prototype. * config/c4x/t-c4x: Can now build all front ends. Wed Oct 14 23:27:08 1998 Didier FORT (didier.fort@fedex.com) * fixincludes: Fix up rpc/{clnt,svr,xdr}.h for SunOS. Wed Oct 14 22:13:28 1998 Joel Sherrill (joel@OARcorp.com) * Makefile.in (stmp-fixinc): Do not install assert.h if not desired. * config/t-rtems: Do not install assert.h -- use newlib's. Wed Oct 14 21:57:08 1998 J"orn Rennecke * combine.c (combine_instructions): When finished, call init_recog. * regmove.c (optimize_reg_copy_3): Reject volatile MEMs. Wed Oct 14 16:10:22 1998 Per Bothner * toplev.c: If flag_syntax_only, don't open or write assembler file. Wed Oct 14 13:26:05 1998 Kaveh R. Ghazi * cppalloc.c (memory_full): Mark function prototype with ATTRIBUTE_NORETURN. * demangle.h (collect_exit): Likewise. * fix-header.c (v_fatal, fatal): Likewise. * gcc.c (pfatal_with_name, pfatal_pexecute, fatal, fancy_abort): Likewise. * gcov.c (print_usage): Likewise. * genattr.c (fatal, fancy_abort): Likewise. * genattrtab.c (fatal, fancy_abort): Likewise. * gencodes.c (fatal, fancy_abort): Likewise. * genconfig.c (fatal, fancy_abort): Likewise. * genemit.c (fatal, fancy_abort): Likewise. * genextract.c (fatal, fancy_abort): Likewise. * genflags.c (fatal, fancy_abort): Likewise. * genopinit.c (fatal, fancy_abort): Likewise. * genoutput.c (fatal, fancy_abort): Likewise. * genpeep.c (fatal, fancy_abort): Likewise. * genrecog.c (fatal, fancy_abort): Likewise. * libgcc2.c (__eprintf, __default_terminate, __sjthrow, __sjpopnthrow, __throw): Likewise. * objc/objc-act.c (objc_fatal): Likewise. * protoize.c (usage, aux_info_corrupted, declare_source_confusing): Likewise. * rtl.c (dump_and_abort): Likewise. * rtl.h (sets_cc0_p): Likewise. * toplev.c (float_signal, pipe_closed): Likewise. 1998-10-14 Andreas Schwab * dwarf2out.c (expand_builtin_dwarf_reg_size): Look at all ranges when generating the decision tree for the general case. * config/m68k/m68k.h (HARD_REGNO_MODE_OK): Don't accept modes wider that 12 bytes in fpu regs or wider than 8 byte in fpa regs. Wed Oct 14 11:14:02 1998 Kaveh R. Ghazi * Makefile.in (sched.o): Depend on recog.h. * alias.c (REG_BASE_VALUE): Cast the result of REGNO() macro to (unsigned) when comparing against one. (find_base_value): Likewise. (record_base_value): Cast variable `regno' to (unsigned) when comparing against one. Cast the result of REGNO() macro to (unsigned) when comparing against one. (memrefs_conflict_p): Change type of variables `r_x' and `r_y' to unsigned. (init_alias_analysis): Add unsigned variable `ui'. Use it as loop variable where an unsigned index is needed. * caller-save.c (init_caller_save): Cast `-1' to (enum insn_code) before comparing against one. * collect2.c: Add prototypes for functions `error', `fatal' and `fatal_perror'. Make these functions take variable arguments instead of faking it with a fixed number of args. (write_c_file_stat): Cast the argument of ctype macro to (unsigned char). * combine.c (can_combine_p): Mark parameter `pred' with ATTRIBUTE_UNUSED. (find_split_point): Cast variable `src' to (unsigned HOST_WIDE_INT) when comparing against one. (simplify_rtx): Cast 1 to (unsigned HOST_WIDE_INT) in shift. (simplify_logical): Likewise. (force_to_mode): Cast result of INTVAL() macro to (unsigned HOST_WIDE_INT) when comparing against one. Cast 1 to (unsigned HOST_WIDE_INT) in shift. (simplify_and_const_int): Cast result of INTVAL() macro to `unsigned HOST_WIDE_INT' when comparing against one. (merge_outer_ops): Cast variable const0 to `unsigned HOST_WIDE_INT' when comparing against the result of GET_MODE_MASK() macro. (simplify_comparison): Likewise for variable `c0'. Cast variable `const_op' to `unsigned HOST_WIDE_INT' when comparing against one. Cast `1' to `unsigned HOST_WIDE_INT' in shift. Cast the result of `GET_MODE_MASK()/2' to `HOST_WIDE_INT' when comparing against one. Cast `1' to `unsigned HOST_WIDE_INT' in shift. Cast result of INTVAL() macro to `unsigned HOST_WIDE_INT' when comparing against one. (distribute_notes): Wrap variable `cc0_setter' in macro `HAVE_cc0'. config/mips/mips.c (gen_int_relational): Cast result of INTVAL() macro to `unsigned HOST_WIDE_INT' when comparing against one. (output_block_move): Cast `sizeof' expression to (int) when comparing against one. (function_arg): Cast BITS_PER_WORD to `unsigned' when comparing against one. (save_restore_insns): Cast `base_offset' to `long' to match format specifier in fprintf. * config/mips/mips.h (Pmode): Cast the result of `Pmode' macro to `enum machine_mode'. * flow.c (life_analysis_1): Remove unused variable `insn'. * gcc.c (translate_options): Move variables `j' and `k' into the scope in which they are used. Change their types to `size_t'. (set_spec): Cast the argument of ctype macro to `unsigned char'. (read_specs): Likewise. (process_command): Cast `sizeof' to (int) when comparing against one. (do_spec_1): Cast the argument of ctype macro to `unsigned char'. (handle_braces): Cast both sides of `==' expression to `long' to ensure sign matching. (main): Cast variable `i' to `int' when comparing against one. * gcov-io.h (__fetch_long): Change type of parameter `bytes' from int to size_t. Cast variable `i' to size_t when comparing against one. * genattrtab.c (convert_set_attr_alternative): Remove unused parameter `insn_code'. All callers changed. (convert_set_attr): Likewise. * genrecog.c (add_to_sequence): Cast result of XVECLEN() macro to size_t when comparing against one. Likewise for variable `len'. * global.c (global_alloc): Cast variable `max_regno' to size_t when comparing against one. Likewise for variable `max_allocno'. * jump.c (sets_cc0_p): Mark parameter `x' with ATTRIBUTE_UNUSED. * local-alloc.c (validate_equiv_mem_from_store): Mark parameter `set' with ATTRIBUTE_UNUSED. (find_free_reg): Cast `sizeof' expression to (int) when comparing against one. * loop.c (count_loop_regs_set): Remove unused variable `dest'. (strength_reduce): Mark parameter `bct_p' with ATTRIBUTE_UNUSED. (get_condition): Cast variable `const_val' to `unsigned HOST_WIDE_INT' when comparing against one. Cast unsigned expression to HOST_WIDE_INT when comparing against one. (insert_loop_mem): Mark parameter `data' with ATTRIBUTE_UNUSED. (load_mems_and_recount_loop_regs_set): Cast variable `nregs' to `unsigned' when comparing against one. * protoize.c (is_id_char): Change type of parameter `ch' to unsigned char. (munge_compile_params): Cast argument of ctype macro to (const unsigned char). (process_aux_info_file): Cast variable `aux_info_size' to int when comparing against one. (forward_to_next_token_char): Cast argument of ctype macro to `const unsigned char'. (edit_formals_lists): Likewise. (find_rightmost_formals_list): Likewise. (add_local_decl): Likewise. (add_global_decls): Likewise. (edit_fn_definition): Likewise. (do_cleaning): Likewise. (scan_for_missed_items): Likewise. (edit_file): Cast variable `orig_size' to (int) when comparing against one. (main): Cast argument of ctype macro to `const unsigned char'. * recog.c (const_int_operand): Mark parameter `mode' with ATTRIBUTE_UNUSED. * regclass.c (record_reg_classes): Change type of variable `c' to `unsigned char'. Cast `char' array index to `unsigned char'. * reload.c (push_secondary_reload): Cast argument to REG_CLASS_FROM_LETTER() macro to `unsigned char'. * reload1.c (calculate_needs): Cast `char' array index to `unsigned char'. (set_label_offsets): Change type of variable `i' to unsigned int. Cast result of XVECLEN() macro to unsigned when comparing against one. (mark_not_eliminable): Change type of variable `i' to unsigned. (order_regs_for_reload): Likewise. Cast `max_regno' to unsigned when comparing against one. (reload_as_needed): Cast macro NUM_ELIMINABLE_REGS to (int) when comparing against one. (choose_reload_regs): Hide unused label `fail'. (reload_cse_simplify_operands): Cast `char' array index to `unsigned char'. (reload_combine_note_store): Mark parameter `set' with ATTRIBUTE_UNUSED. Cast UNITS_PER_WORD to unsigned when comparing against one. (reload_cse_move2add): Remove unused variable `src2'. * sched.c: Include recog.h. (sched_note_set): Remove unused parameter `b'. All callers changed. (split_hard_reg_notes): Likewise for parameter `orig_insn'. (blockage_range): Cast result of UNIT_BLOCKED() macro to (int) when comparing against one. * stupid.c (stupid_find_reg): Mark parameter `changes_size' with ATTRIBUTE_UNUSED. Cast `sizeof' expression to (int) when comparing against one. * unroll.c (precondition_loop_p): Remove unused parameter `loop_end'. All callers changed. Tue Oct 13 22:12:11 1998 Bernd Schmidt * reload1.c (maybe_fix_stack_asms): New static function. (reload): Call it. * reload.h (compute_use_by_pseudos): Declare. * reload1.c (spilled_pseudos, insns_need_reload): New variables. (something_needs_reloads): Delete variable. (finish_spills): New function. (compute_use_by_pseudos): New function. (delete_caller_save_insns): Lose argument FIRST. All callers changed. Use the reload_insn_chain instead of walking the rtl directly. (reload): Allocate and free spilled_pseudos. Ensure that all calls of spill_hard_reg are followed by a call to finish_spills. Use the insns_need_reload list instead of something_needs_reloads to find out if reload_as_needed must be called. Clear unused_insn_chains at the end. (calculate_needs_all_insns): Lose FIRST parameter. All callers changed. Delete code to keep track of current basic block. Walk reload_insn_chain instead of the rtl structure. Build the insns_need_reload chain. Remember which insns need reloading/elimination by setting the appropriate fields in struct insn_chain, not by putting modes on the insn. (calculate_needs): Lose THIS_BLOCK arg. Accept arg CHAIN instead of arg INSN. All callers changed. Delete declaration of struct needs. Don't set something_needs_reloads. Record insn needs in the CHAIN argument. (spill_hard_reg): Record the affected pseudos in spilled_pseudos. (reload_as_needed): Lose FIRST arg. All callers changed. Walk the reload_insn_chain instead of the rtx structure. Delete code to keep track of current basic block. Rename one of the NEXT variables to OLD_NEXT. (allocate_reload_reg): Accept arg CHAIN instead of arg INSN. All callers changed. (choose_reload_regs): Likewise. (emit_reload_insns): Replace INSN and BB args with arg CHAIN. All callers changed. * caller-save.c (MOVE_MAX_WORDS): New macro. Use it throughout instead of (MOVE_MAX / UNITS_PER_WORD) computation. (hard_regs_live, hard_regs_need_restore): Delete variables. (n_regs_saved): Now static. (referenced_regs, this_insn_sets): New variables. (setup_save_areas): Restructure the code a bit. (restore_referenced_regs): Delete function. (mark_referenced_regs): New function, similar to the old restore_referenced_regs, but mark registers in referenced_regs. (clear_reg_live): Delete function. (mark_set_regs): Renamed from set_reg_live. All callers changed. Only mark registers in this_insn_sets. (save_call_clobbered_regs): Rework this function to walk the reload_insn_chain instead of using the list of instructions directly. Delete code to keep track of register lives, compute live regs on the fly from information in the chain. Instead of calling restore_referenced_regs, use mark_referenced_regs, then walk the set it computes and call insert_restore as appropriate. (insert_restore): Lose INSN and BLOCK args. Add CHAIN arg. All callers changed. Restructure the code a bit. Test hard_regs_saved instead of hard_regs_need_restore. (insert_save): Lose INSN and BLOCK args. Add CHAIN and TO_SAVE args. All callers changed. Restructure the code a bit. Use TO_SAVE to determine which regs to save instead of more complicated test. (insert_one_arg): Lose INSN and BLOCK args. Add CHAIN arg. All callers changed. Create a new insn_chain structure for the new insn and place it into the chain. * rtl.texi: Update documentation to reflect that reload no longer puts modes on the insns. 1998-10-14 Andreas Schwab * function.c (purge_addressof_1): Force the first argument of a CALL insn to memory. Wed Oct 14 00:38:40 1998 Jeffrey A Law (law@cygnus.com) * rtl.h: Delete duplicate prototypes. Add some missing prototypes. * rtlanal.c (for_each_rtx): Formatting tweak. 1998-10-13 Herman A.J. ten Brugge * real.c (emdnorm and etoasc): Disable round to even for c4x target to be compatible with TI compiler. * Makefile.in (USER_H): Add va-c4x.h to definition. Tue Oct 13 23:03:37 1998 Richard Henderson * function.c (purge_addressof_1): Fix typo in inequality: do bitfield optimization for equal mode sizes. * expmed.c (store_bit_field): Don't take subregs of subregs in the movstrict case. Tidy a potential problem in the multi-word case. (extract_bit_field): Likewise. Tue Oct 13 22:12:11 1998 Bernd Schmidt * flow.c (find_basic_blocks): Emit NOPs after normal calls in this function. Compute max_uid_for_flow by calling get_max_uid after the scan. (find_basic_blocks_1): Don't emit NOPs here. Tue Oct 13 22:05:49 1998 Richard Henderson * alias.c (base_alias_check): Accept new args for the modes of the two references. Use them to determine if an AND can overlap. Update all callers. (memrefs_conflict_p): Assume sizes are aligned, and uses them to determine if an AND can overlap. Tue Oct 13 17:51:04 1998 Jim Wilson * config/m68k/m68k.h (HARD_REGNO_MODE_OK): For FP regs, add REGNO >= 16 check. Add comment to document problems with TARGET_SUN_FPA version of this macro. * config/m68k/m68k.md (movxf+1): Support 'r'/'r' moves. Tue Oct 13 17:46:18 1998 Kaveh R. Ghazi * Makefile.in (gencheck.o): Depend on gansidecl.h. * c-common.c (print_char_table): Add missing initializers. (scan_char_table): Likewise. (time_char_table): Likewise. * c-decl.c (c_decode_option): Mark parameter `argc' with ATTRIBUTE_UNUSED. (declare_parm_level): Mark parameter `definition_flag' with ATTRIBUTE_UNUSED. * c-lex.c (readescape): Use `(unsigned)1' in shift. (yylex): Likewise. Cast `sizeof' to an (int) when comparing against one. * calls.c (store_one_arg): Remove unused parameter `fndecl'. All callers changed. (emit_call_1): Mark parameters `fndecl' and `funtype' with ATTRIBUTE_UNUSED. (expand_call): Cast result of MIN() to (unsigned int) when comparing against an unsigned value. * cccp.c (pcfinclude): Remove unused parameter `limit'. All callers changed. (make_definition): Remove unused parameter `op'. All callers changed. (create_definition): Cast REST_EXTENSION_LENGTH to (long) when comparing against the result of pointer arithmetic. * config/mips/mips.h (FUNCTION_ARG_BOUNDARY): Cast to (unsigned) when comparing against one. * dwarf2out.c (dwarf2out_frame_debug): Cast REGNO() and HARD_FRAME_POINTER_REGNUM to (unsigned) when comparing against one. (output_die): Move variable `i' into the scope in which it is used. Change its type to `unsigned'. (output_die): Cast the result of `strlen' to (int) when passing it to ASM_OUTPUT_ASCII(). (output_pubnames): Likewise. (output_line_info): Likewise. * emit-rtl.c (global_rtl): Add missing initializers. * explow.c (promote_mode): Mark parameter `for_call' with ATTRIBUTE_UNUSED. * expmed.c (expand_shift): Cast the result of GET_MODE_BITSIZE to `unsigned HOST_WIDE_INT' when comparing against one. (synth_mult): Change type of variable `cost' to int. (emit_store_flag): Use `(unsigned HOST_WIDE_INT) 1' in shift. * expr.c (copy_blkmode_from_reg): Cast BITS_PER_WORD to (unsigned) when comparing against one. (get_inner_reference): Change variable `alignment' to unsigned. (expand_expr): Cast the result of GET_MODE_ALIGNMENT to (unsigned int) when comparing against one. (expand_builtin_setjmp): Change type of variable `i' to size_t. * fold-const.c (div_and_round_double): Cast BASE to (HOST_WIDE_INT) when comparing against one. * gencheck.c: Include gansidecl.h. (main): Mark parameter `argv' with ATTRIBUTE_UNUSED. * optabs.c (gen_cond_trap): Mark parameters `code', `op2' and `tcode' with ATTRIBUTE_UNUSED. * real.c (edivm): Cast constant value to (unsigned long) in expression compared against an unsigned value. * stmt.c (expand_return): Cast BITS_PER_WORD to (unsigned) when comparing against one. (expand_end_case): Cast CASE_VALUES_THRESHOLD to (unsigned int) when comparing against one. * stor-layout.c (mode_for_size): Cast MAX_FIXED_MODE_SIZE to (unsigned int) when comparing against one. Likewise for GET_MODE_BITSIZE. (smallest_mode_for_size): Likewise. (save_storage_status): Mark parameter `p' with ATTRIBUTE_UNUSED. (restore_storage_status): Likewise. * toplev.c (debug_args): Add missing initializer. (f_options): Spelling correction. Add missing initializers. (documented_lang_options): Likewise. (debug_end_source_file): Mark parameter `lineno' with ATTRIBUTE_UNUSED. * tree.c (valid_machine_attribute): Mark parameters `attr_args', `decl' and `type' with ATTRIBUTE_UNUSED. * varasm.c (decode_reg_name): Cast `sizeof' expression to (int) when comparing against one. (assemble_variable): Mark parameter `top_level' with ATTRIBUTE_UNUSED. (assemble_external_libcall): Mark parameter `fun' with ATTRIBUTE_UNUSED. (output_constant_pool): Mark parameters `fnname' and `fndecl' with ATTRIBUTE_UNUSED. Tue Oct 13 12:51:04 1998 Nick Clifton * config/v850/lib1funcs.asm (_udivsi3): Add .type declaration. Replace use of r5 with use of r19. * config/v850/v850.h (LINK_POINTER_REGNUM): Define. * config/v850/v850.c (compute_register_save_size): Allow for the fact that helper functions save all registers, not just those used by the function. Replace constant 31 with macro LINK_POINTER_REGNUM. * config/v850/v850.md: Use 'indirect_operand' rather than 'memory_operand' for bit test/set/clear patterns. Tue Oct 13 11:49:14 1998 Jason Merrill * mips/iris6.h (ASM_OUTPUT_WEAK_ALIAS): Call ASM_GLOBALIZE_LABEL. * varasm.c (assemble_start_function et al): Don't call ASM_GLOBALIZE_LABEL for weak symbols. Tue Oct 13 11:37:45 1998 Nick Clifton * cse.c (equiv_constant): Check for NULL return from gen_lowpart_if_possible(). Tue Oct 13 11:24:51 1998 Jeffrey A Law (law@cygnus.com) * mn10200.md (addsi3, subsi3, negsi2): Only allow register operands. * collect2.c (main): Pass -EL/-EB through to the compiler. 1998-10-12 Herman A.J. ten Brugge * expr.c (push_block): Handle targets where the stack grows to higher addresses, but args grow to lower addresses and ACCUMULATE_OUTGOING_ARGS is not defined. Tue Oct 13 08:00:52 1998 Catherine Moore * config/v850/v850.c (print_operand): Extend meaning of 'c' operands to support .vtinherit. Tue Oct 13 21:38:35 1998 Michael Hayes * config/c4x/c4x.c: Convert to gen_rtx_FOO. Added ATTRIBUTE_UNUSED to unused function arguments. (rc_reg_operand): New predicate. (c4x_rptb_insert): New function. (c4x_rptb_nop_p): Recognize modified rptb_top pattern. (c4x_optimization_options): New function. * config/c4x/c4x.md: Convert to gen_rtx_FOO. (decrement_and_branch_on_count): New pattern. (rptb_top): Modified pattern to work with BCT optimization. * config/c4x/c4x.h (RC_REG): New register class. (rc_reg_operand): Define prototype. (IS_RC_REG): New macro. (IS_RC_OR_PSEUDO_REG): New macro. (IS_RC_OR_PSEUDO_REGNO): New macro. (OPTIMIZATION_OPTIONS): Define. Mon Oct 12 19:57:34 1998 Jason Merrill * collect2.c (extract_init_priority): No priority is 65535. Mon Oct 12 12:10:37 1998 Alexandre Oliva * Makefile.in (build_tooldir): New variable, same as old $(tooldir), but without depending on $(libdir)/$(unlibsubdir). (GCC_FOR_TARGET): Add -B$(build_tooldir)/bin/. (bootstrap, bootstrap2, bootstrap3, bootstrap4): Likewise. * configure.in (gxx_include_dir): Set default based on unlibsubdir. * Makefile.in (tooldir): Likewise. (cccp.o, cpplib.o): Use unlibsubdir implicitly through gxx_include_dir, includedir and tooldir. (protoize.o, unprotoize.o): Likewise. Mon Oct 12 10:50:44 1998 Nick Clifton * config/arm/arm.md: Replace (reg 24) with (reg:CC 24). * config/arm/thumb.c (thumb_override_options): Add warning about PIC code not being supported just yet. Sun Oct 11 16:49:15 1998 John Wehle (john@feith.com) * flow.c: Update comment. (notice_stack_pointer_modification): New static function. (record_volatile_insns): Use it. (mark_regs_live_at_end): Mark the stack pointer as alive at the end of the function if current_function_sp_is_unchanging is set. (life_analysis_1): Set current_function_sp_is_unchanging. * function.c: Define it. (init_function_start): Initialize it. * output.h: Declare it. * reorg.c (fill_simple_delay_slots, dbr_schedule): Mark the stack pointer as alive at the end of the function if current_function_sp_is_unchanging is set. * i386.c (ix86_epilogue): Optimize the restoring of the stack pointer. Mon Oct 12 01:22:53 1998 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. Sun Oct 11 23:04:30 1998 Robert Lipe * c-pragma.c (handle_pragma_token): If passed a token instead of a tree, use that as the pack value. Sun Oct 11 14:21:14 1998 Mark Mitchell * flow.c (find_basic_blocks_1): Fix prototype. Sun Oct 11 05:03:41 1998 Ken Raeburn * tree.h (DECL_NO_CHECK_MEMORY_USAGE): New macros. (struct tree_decl): New fields no_check_memory_usage. * c-common.c (enum attrs): Add A_NO_CHECK_MEMORY_USAGE. (init_attributes): Register it as a new attribute. (decl_attributes): Set flags on functions given that attribute. * c-decl.c (duplicate_decls): Merge new attribute. * expr.h (current_function_check_memory_usage): Declare new var. * calls.c, expr.c, function.c, stmt.c, alpha.c, clipper.c, m88k.c, pa.c, sparc.c: Replace uses of flag_check_memory_usage with current_function_check_memory_usage. * function.h: Add field to struct function. * function.c (current_function_check_memory_usage): Define it. (push_function_context_to, pop_function_context_from): Save and restore it. (expand_function_start): Set it, based on global flag and function attribute. * expr.c (expand_expr, case VAR_DECL): In memory-checking code, do check non-automatic variables, to permit detection of writes to read-only locations in embedded systems without memory management. * calls.c (store_one_arg): Use ARGS_SIZE_RTX to get size of argument when emitting chkr_set_right_libfunc call, even if the argument is BLKmode or variable-sized; don't abort. * optabs.c (init_optabs): Create Checker and __cyg_profile_* symbols in Pmode, not VOIDmode. Sun Oct 11 01:03:05 1998 Zack Weinberg * cppexp.c: When forcing unsigned comparisons, cast both sides of the operation. * cpphash.h: Move static declaration of hashtab[]... * cpphash.c: ...here. * cpplib.c: Cast difference of two pointers to size_t before comparing it to size_t. Cast signed to unsigned before comparing to size_t. (FIXME: struct argdata should use unsigned buffer sizes.) * cpplib.h (struct cpp_reader): Declare token_buffer_size as unsigned int. (CPP_WRITTEN): Cast return value to size_t. (CPP_RESERVE): Parenthesize N for evaluation order, cast to size_t before comparison. Sun Oct 11 00:15:29 1998 Jeffrey A Law (law@cygnus.com) * flow.c (find_basic_blocks): Delete "live_reachable_p" argument. (find_basic_blocks_1): Similarly. * output.h (find_basic_blocks): Fix prototype. * gcse.c, toplev.c: Don't pass "live_reachable_p" argument to find_basic_blocks anymore. Sat Oct 10 22:00:34 1998 Richard Henderson * basic-block.h (EXECUTE_IF_SET_IN_SBITMAP): New macro. (sbitmap_free, sbitmap_vector_free): New macros. * output.h (rtl_dump_file): Declare. Sat Oct 10 17:01:42 1998 Jeffrey A Law (law@cygnus.com) * regmove.c (optimize_reg_copy_3): Honor TRULY_NOOP_TRUNCATION. Fri Oct 9 22:08:05 1998 Kaveh R. Ghazi * fp-bit.c (SFtype): Don't implicitly use int in declaration. (DFtype): Likewise. (_fpdiv_parts): Remove unused parameter `tmp', all callers changed. (divide): Remove unused variable `tmp'. (si_to_float): Cast numeric constant to (SItype) before comparing it against one. Fri Oct 9 16:03:19 1998 Graham * flow.c (print_rtl_with_bb): Changed type of in_bb_p to match use. * gcc.c (add_preprocessor_option): Correct typo when allocating memory, sizeof() argument had one too many `*'. (add_assembler_option): Likewise. (add_linker_option): Likewise. * gcov.c (output_data): Likewise. * local-alloc.c (memref_used_between_p): Likewise. (update_equiv_regs): Likewise. * loop.c (strength_reduce): Likewise. * reg-stack.c (record_asm_reg_life): Likewise. (subst_asm_stack_reg): Likewise. * reorg.c (dbr_schedule): Likewise. Fri Oct 9 15:57:51 1998 Bernd Schmidt * flow.c (life_analysis_1): Break out some functions. (find_basic_blocks_1): Likewise. Also move some variables out and make them static. Rename NONLOCAL_LABEL_LIST arg to NONLOCAL_LABELS and initialize new static var nonlocal_label_list with it. (active_eh_region, nested_eh_region, label_value_list, nonlocal_label_list): New static variables. (make_edges, delete_unreachable_blocks, delete_block): New static functions, broken out of find_basic_blocks_1. (record_volatile_insns, mark_regs_live_at_end, set_noop_p, noop_move_p): New static functions, broken out of life_analysis_1. Fri Oct 9 15:49:29 1998 Richard Henderson * expmed.c (store_bit_field): Pun non-integral str_rtx modes. Take extra care for op0 now possibly being a subreg. (extract_bit_field): Likewise. * function.c (purge_addressof_1): Revert Oct 4 change. Drop the reg to memory if there is no equal sized integral mode. * stor-layout.c (int_mode_for_mode): New function. * machmode.h: Prototype it. Fri Oct 9 14:26:44 1998 Jeffrey A Law (law@cygnus.com) * global.c (build_insn_chain): Verify no real insns exist past the end of the last basic block, then exit the loop. Fri Oct 9 11:44:47 1998 David Edelsohn * loop.c (insert_bct): Ensure loop_iteration_var non-zero before use. Thu Oct 8 21:59:47 1998 Dave Brolley * emit-rtl.c (init_emit_once): Call INIT_EXPANDERS. Thu Oct 8 22:03:45 1998 David Edelsohn * rs6000.h (RTX_COSTS): Add PROCESSOR_PPC604e cases. Thu Oct 8 17:00:18 1998 Richard Henderson * flow.c (find_basic_blocks): Correctly determine when a call is within an exception region. Thu Oct 8 17:15:04 1998 Jeffrey A Law (law@cygnus.com) * toplev.c (output_file_directive): Use DIR_SEPARATOR, not '/'. * cpplib.h: Protect from multiple inclusions. * cpplib.c: Fix minor formatting problems. * i386/xm-cygwin32.h: Only define POSIX if it is not already defined. * jump.c (jump_optimize): Revert accidental patch. * Makefile.in (cpplib.o): Use unlibsubdir. Thu Oct 8 12:50:47 1998 Jim Wilson * loop.c (get_condition): Allow combine when either compare is VOIDmode. Thu Oct 8 11:31:01 1998 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. Thu Oct 8 12:21:14 1998 Richard Frith-Macdonald * c-lex.c (remember_protocol_qualifiers): Handle RID_BYREF. (init_lex): Initialize ridpointers[RID_BYREF]. * c-lex.h (enum rid): Add RID_BYREF. * c-parse.gperf: Add RID_BYREF as a type qualifier. * objc/objc-act.c (is_objc_type_qualifiers): Handle RID_BYREF. (encode_type_qualifiers): Similarly. * c-gperf.h: Rebuilt. Thu Oct 8 05:56:00 1998 Jeffrey A Law (law@cygnus.com) * c-common.c (type_for_mode): Only return TItype nodes when HOST_BITS_PER_WIDE_INT is >= 64 bits. * c-decl.c (intTI_type_node, unsigned_intTI_type_node): Only declare when HOST_BITS_PER_WIDE_INT is >= 64 bits. (init_decl_processing): Only create TItype nodes when HOST_BITS_PER_WIDE_INT is >= 64 bits. * c-tree.h (intTI_type_node, unsigned_intTI_type_node): Only declare when HOST_BITS_PER_WIDE_INT is >= 64 bits. Thu Oct 8 05:05:34 1998 Bernd Schmidt * stmt.c (n_occurrences): New static function. (expand_asm_operands): Verify that all constrains match in the number of alternatives. Verify that '+' or '=' are at the beginning of an output constraint. Don't allow '&' for input operands. Verify that '%' isn't written for the last operand. * reload.c (find_reloads): Abort if an asm is found with invalid constraints; all possible problems ought to be checked for earlier. Thu Oct 8 04:26:20 1998 Michael Hayes * flags.h (flag_branch_on_count_reg): Always declare. * toplev.c (flag_branch_on_count_reg): Likewise. * toplev.c: Fix typos. * real.c (c4xtoe): Remove unused variables. Add some missing parens. (toc4x): Similarly. Thu Oct 8 01:25:22 1998 Richard Henderson * flow.c (find_basic_blocks): Calc upper bound for extra nops in max_uids_for_flow. (find_basic_blocks_1): Add a nop to the end of a basic block when a trailing call insn does not have abnormal control flow. * gcse.c (pre_transpout): New variable. (alloc_pre_mem, free_pre_mem, dump_pre_data): Bookkeeping for it. (compute_pre_transpout): Calculate it. (compute_pre_ppinout): Use it to eliminate impossible placements due to abnormal control flow through calls. (compute_pre_data): Call compute_pre_transpout. Wed Oct 7 21:40:24 1998 David S. Miller * config/sparc/sol2-sld-64.h (ASM_CPU_SPEC): Fix typo. Wed Oct 7 21:19:46 1998 Ken Raeburn * config/mips/mips.md (tablejump_internal3, tablejump_internal4 and matching define_insns): Tack on a `use' of the table label, so flow analysis will recognize a tablejump. Wed Oct 7 17:33:39 1998 Richard Henderson * gcse.c (pre_insert_insn): Tweek to notice that calls do not always end basic blocks for abnormal edge reasons. Wed Oct 7 14:40:43 1998 Nick Clifton * config/i386/i386.h: Remove definition of HANDLE_PRAGMA_PACK_PUSH_POP. * config/i386/go32.h: Add definition of HANDLE_PRAGMA_PACK_PUSH_POP. * config/i386/win32.h: Add definition of HANDLE_PRAGMA_PACK_PUSH_POP. * config/i386/cygwin32.h: Add definition of HANDLE_PRAGMA_PACK_PUSH_POP. * c-pragma.c (insert_pack_attributes): Do not insert attributes unless #pragma pack(push,) is in effect. Wed Oct 7 12:10:46 1998 Jim Wilson * expr.c (emit_group_store): Handle a PARALLEL destination. Wed Oct 7 10:07:29 1998 Richard Henderson * gcse.c (pre_insert_insn): When a call ends a bb, insert the new insns before the argument regs are loaded. Wed Oct 7 12:55:26 1998 Kaveh R. Ghazi * Makefile.in (c-gperf.h): Add -L KR-C -F ', 0, 0' flags to gperf. (c-parse.gperf): Update comments describing invocation flags. (c-gperf.h): Regenerate using gperf 2.7.1 (19981006 egcs). 1998-10-07 Manfred Hollstein * reload1.c (reload): Call free before clobbering the memory locations or constants pointers. Wed Oct 7 02:05:20 1998 David S. Miller * config/sparc/sol2-sld-64.h (TRANSFER_FROM_TRAMPOLINE): Rework for efficiency by checking whether we need to modify the current stack permission at all. (ASM_OUTPUT_CONSTRUCTOR, ASM_OUTPUT_DESTRUCTOR): Define. * config/sparc/sparc.c (sparc_initialize_trampoline): Emit __enable_execute_stack libcall here too if TRANSFER_FROM_TRAMPOLINE is defined. * config/sparc/sparc.h: Set TARGET_ARCH32 to a constant if IN_LIBGCC2. Wed Oct 7 02:27:52 1998 Jeffrey A Law (law@cygnus.com) * Makefile.in (DRIVER_DEFINES): Remove last change. Wed Oct 7 01:08:43 1998 Bernd Schmidt * jump.c (duplicate_loop_exit_test): Strip REG_WAS_0 notes off all insns we're going to copy. * regclass.c (reg_scan_mark_refs): Don't test X for NULL_RTX. * loop.c (count_one_set): Add prototype. * caller-save.c (restore_referenced_regs): Lose mode argument. (insert_save): Lose mode argument. (insert_restore): Lose mode argument. (insert_one_insn): Lose mode argument. (save_call_clobbered_regs): Lose mode argument. (setup_save_areas): Take no argument and return void. All callers changed. Don't verify validity of memory addresses. * reload.h (setup_save_ares): Adjust prototype. (save_call_clobbered_regs): Likewise. * reload1.c (delete_caller_save_insns): New function. (caller_save_spill_class): Delete variable. (caller_save_group_size): Delete variable. (reload): Call setup_save_areas and save_call_clobbered_regs in the main loop, before calling calculate_needs_all_insns. Don't call save_call_clobbered_regs after the loop. Call delete_caller_save_insns at the end of an iteration if something changed. Delete code to manage caller_save_spill_class. Emit the final note before setting reload_first_uid. Simplify test that determines whether reload_as_needed gets run. (calculate_needs): Delete code to manage caller_save_spill_class. Tue Oct 6 15:42:27 1998 Richard Henderson * collect2.c (main): Initialize ld_file_name. Tue Oct 6 15:45:15 1998 Catherine Moore * config/sparc/sysv4.h (ASM_OUTPUT_SECTION_NAME): Don't check for flag_function_sections. Tue Oct 6 20:02:31 1998 J"orn Rennecke * cse.c (insert_regs): Fix bug in Sep 24 change. Tue Oct 6 17:00:42 1998 J"orn Rennecke * flags.h (flag_dump_unnumbered): Declare. * toplev.c (flag_dump_unnumbered): Don't declare. * print-rtl.c (flags.h): Include. (print_rtl_single): Add return value. * rtl.h (print_rtl_single): Update declaration. * flow.c (flag_dump_unnumbered): Don't declare. (print_rtl_with_bb): Use return value of print_rtl_single. Tue Oct 6 01:36:00 1998 Bernd Schmidt * loop.c (count_one_set): New static function, broken out of count_loop_regs_set. (count_loop_regs_set): Call it. * global.c (mark_reg_store): Handle clobbers here by not calling set_preference. (mark_reg_clobber): Just call mark_reg_store after ensuring SETTER is in fact a clobber. * integrate.c (process_reg_param): New function, broken out of expand_inline_function. (expand_inline_function): Call it. * i386.md (addsidi3_1): Delete unused variable temp. (addsidi3_2): Likewise. (clstrstrsi): Delete unused variable addr1. * rtl.h: Don't declare any functions also declared in recog.h. * Makefile.in (stupid.o): Update dependencies. (global.o): Likewise. * global.c: Include reload.h. (reg_becomes_live): New function. (reg_dies): New function. (build_insn_chain): New function. (global_alloc): Call build_insn_chain before calling reload. * reload.h (struct needs): New structure definition. (struct insn_chain): Likewise. (reload_insn_chain): Declare variable. (new_insn_chain): Declare function. * reload1.c (reload_startobj): New variable. (reload_insn_chain): New variable. (unused_insn_chains): New variable. (new_insn_chain): New function. (init_reload): Initialize reload_startobj, not reload_firstobj. (reload): Initialize reload_firstobj. Before returning, free everything on the reload_obstack. * stupid.c: Include insn-config.h, reload.h and basic-block.h. (reg_where_dead_chain, reg_where_born_exact, reg_where_born_clobber, current_chain): New variables. (reg_where_born): Delete variable. (REG_WHERE_BORN): New macro. (find_clobbered_regs): New function. (stupid_life_analysis): Don't allocate/free reg_where_born. Allocate and free reg_where_born_exact, reg_where_born_clobber, reg_where_dead_chain. Use REG_WHERE_BORN instead of reg_where_born. While processing the insns, build the reload_insn_chain with information about register lifetimes. (stupid_reg_compare): Use REG_WHERE_BORN instead of reg_where_born. (stupid_mark_refs): Replace arg INSN with arg CHAIN. All callers changed. Compute and information about birth and death of pseudo registers in reg_where_dead_chain, reg_where_born_exact and reg_where_born_clobber. Delete code to set elements of reg_where_born. Mon Oct 5 22:34:30 1998 Alexandre Petit-Bianco * tree.def (GOTO_EXPR): Modified documentation. * expr.c (expand_expr): Expand GOTO_EXPR into a goto or a computed goto. Mon Oct 5 22:43:36 1998 David Edelsohn * unroll.c (loop_iteration_var, loop_initial_value, loop_increment loop_final_value, loop_comparison_code): No longer static. (unroll_loop): Delete loop_start_value update. * loop.h (loop_iteration_var, loop_initial_value, loop_increment, loop_final_value, loop_comparison_code): Extern. (loop_start_value): Delete extern. * loop.c (loop_can_insert_bct, loop_increment, loop_start_value, loop_comparison_value, loop_comparison_code): Delete. (loop_optimize): Remove initialization for deleted variables. (strength_reduce): Delete analyze_loop_iterations call. Only call insert_bct if flag_branch_count_on_reg set. (analyze_loop_iterations): Delete. (insert_bct): Remove iteration count calculation. Move checks for viable BCT optimization to here. Obtain iteration count from loop_iterations and correct for unrolling. Check for enough iteration to be beneficial. Comment out runtime iteration count case. (insert_bct): Print iteration count in dump file. Remove loop_var_mode and use word_mode directly. * rs6000.h (processor_type): Add PROCESSOR_PPC604e. * rs6000.c (rs6000_override_options): Use it. (optimization_options): Enable use of flag_branch_on_count_reg. * rs6000.md (define_function_unit): Describe 604e. 1998-10-05 Herman A.J. ten Brugge * loop.c (move_movables): Corrected threshold calculation for moved_once registers. Mon Oct 5 21:18:45 1998 Bernd Schmidt * loop.c (combine_givs_p): Fix test for identical givs. Mon Oct 5 10:11:28 1998 Nick Clifton * dwarf2out.c (gen_subprogram_die): If errorcount nonzero, don't call abort if the function is already defined. Mon Oct 5 10:02:36 1998 Jeffrey A Law (law@cygnus.com) * combine.c (simplify_rtx): Do not replace TRUNCATE with a SUBREG if truncation is not a no-op. Mon Oct 5 09:02:04 1998 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. Mon Oct 5 08:19:55 1998 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. Mon Oct 5 01:07:23 1998 Torbjorn Granlund * expmed.c (expand_divmod): Don't widen for computing remainder if we seem to have a divmod pattern for needed mode. Mon Oct 5 01:01:42 1998 Zack Weinberg * cpplib.c (macroexpand): Correct off-by-one error in handling of escapes. Sun Oct 4 23:58:30 1998 Richard Henderson * combine.c (expand_field_assignment): Don't do bitwise operations on MODE_FLOAT; pun to MODE_INT if possible. Sun Oct 4 18:33:24 1998 Jason Merrill scott snyder * tlink.c (scan_linker_output): Recognize errors from irix 6.2 linker. Recognize mangled names in quotes. Sun Oct 4 02:58:20 1998 Jakub Jelinek * config/sparc/sparc.md (ashldi3+1): Name it ashldi3_sp64. (ashlsi3_const1, ashldi3_const1): New combiner patterns. (ashrsi3_extend, ashrsi3_extend2): New combiner patterns. (lshrsi3_extend, lshrsi3_extend2): Likewise. Sun Oct 4 00:23:00 1998 David S. Miller * function.c (purge_addressof_1): If trying to take a sub-word integral piece of a floating point mode, put it on the stack. Sat Oct 3 19:01:03 1998 Richard Henderson * alpha/linux.h (CPP_PREDEFINES): Define __alpha__ for imake. Sat Oct 3 14:42:19 1998 Jason Merrill * PROJECTS: Remove template friends. * collect2.c (sort_ids): Remove unused variable. * tm.texi (MATH_LIBRARY): Document. (NEED_MATH_LIBRARY): Remove. * varasm.c (assemble_start_function, assemble_variable, weak_finish, assemble_alias): Do ASM_GLOBALIZE_LABEL for weak symbols, too. Sat Oct 3 16:14:44 1998 John Carr * dwarf2out.c (expand_builtin_dwarf_reg_size): Initialize last_end to 0x7fffffff. Fri Oct 2 19:14:20 1998 David S. Miller * function.c (purge_addressof_1): Do not perform endianness corrections on bitpos, who we call will do it for us. Fri Oct 2 11:52:35 1998 Jeffrey A Law (law@cygnus.com) * h8300.c (WORD_REG_USED): Fix typo. (initial_offset): Use WORD_REG_USED. * h8300.c (handle_pragma): Fix typo. Fri Oct 2 10:51:35 1998 Bernd Schmidt * caller-save.c (insert_save_restore): Break this function up into new functions insert_restore, insert_save and insert_one_insn. All callers changed. (insert_restore): New function, mostly broken out of insert_save_restore. (insert_save): Likewise. (insert_one_insn): Likewise. (restore_referenced_regs): New argument BLOCK. All callers changed. (save_call_clobbered_regs): Don't keep track of basic block boundaries in this function, do it in insert_one_insn instead. * reload1.c (reload): Break out some more pieces into separate functions. (dump_needs): New function, broken out of reload. (set_initial_elim_offsets): Likewise. (init_elim_table): Likewise. (update_eliminables): Likewise. * global.c (global_alloc): Delete code to manage the scratch_list. * local-alloc.c (qty_scratch_rtx): Delete. (scratch_block): Delete. (scratch_list): Delete. (scratch_list_length): Delete. (scratch_index): Delete. (alloc_qty_for_scratch): Delete. (local-alloc): Update initialization of max_qty. Delete code to manage the scratch list. Delete code to allocate/initialize qty_scratch_rtx. (block_alloc): Don't allocate quantities for scratches. Delete code to manage the scratch list. * regs.h (scratch_list): Delete declaration. (scratch_block): Delete declaration. (scratch_list_length): Delete declaration. * reload1.c (reload): Delete code to manage the scratch list. (spill_hard_reg): Likewise. (mark_scratch_live): Delete. * recog.c (alter_subreg): Delete declaration. 1998-10-02 Andreas Jaeger * Makefile.in (cccp.o): Fix typo in last patch. Fri Oct 2 16:13:12 1998 J"orn Rennecke * t-sh (LIB1ASMFUNCS): Add _set_fpscr . * config/sh/lib1funcs.asm (___set_fpscr): Add. Fri Oct 2 02:01:59 1998 Jeffrey A Law (law@cygnus.com) * regclass.c (reg_scan_mark_refs): Return immediately if passed a NULL_RTX as an argument. * Makefile.in (unlibsubdir): Define. (DRIVER_DEFINES): Use unlibsubdir. (cccp.o, cpplib.o, protoize.o, unprotoize.o): Similarly. (stmp-fixinc): Similarly. Thu Oct 1 19:58:30 1998 Bernd Schmidt * regmove.c (regmove_optimize): Add variable old_max_uid. At the end of the function, update basic_block_end. Thu Oct 1 17:58:25 1998 David S. Miller * dwarf2out.c (expand_builtin_dwarf_reg_size): Use FIRST_PSEUDO_REGISTER as upper bound for last_end, not an arbitrary constant. Thu Oct 1 17:57:14 1998 Nick Clifton * config/arm/arm.c: Improve interworking support. Thu Oct 1 18:43:35 1998 J"orn Rennecke * reload1.c (choose_reload_regs): Fix test if reload_reg_rtx[r] was copied from reload_out[r] . Thu Oct 1 19:20:09 1998 John Carr * dwarf2out.c (expand_builtin_dwarf_reg_size): Fix to work with more than three size ranges. * flow.c (sbitmap_copy): Use bcopy to copy bitmap. * rtl.c (mode_name): Add a null string at the end of the array. (mode_wider_mode): Change type to unsigned char. (mode_mask_array): New variable. (init_rtl): Update for mode_wider_mode type change. * rtl.h (mode_wider_mode): Change type to unsigned char. (mode_mask_array): Declare. (GET_MODE_MASK): Use mode_mask_array. Thu Oct 1 15:56:01 1998 Gavin Romig-Koch * calls.c (expand_call) : Encapsulate code into copy_blkmode_from_reg. * expr.c (copy_blkmode_from_reg): New function. * expr.h (copy_blkmode_from_reg): New function. * integrate.c (function_cannot_inline_p): We can inline these now. (expand_inline_function): Use copy_blkmode_from_reg if needed. Avoid creating BLKmode REGs. (copy_rtx_and_substitute): Don't try to SUBREG a BLKmode object. Thu Oct 1 10:42:27 1998 Nick Clifton * config/v850/v850.c: Add function prototypes. Add support for v850 special data areas. * config/v850/v850.h: Add support for v850 special data areas. * c-pragma.c: Add support for HANDLE_PRAGMA_PACK and HANDLE_PRAGMA_PACK_PUSH_POP. (push_alignment): New function: Cache an alignment requested by a #pragma pack(push,). (pop_alignment): New function: Pop an alignment from the alignment stack. (insert_pack_attributes): New function: Generate __packed__ and __aligned__ attributes for new decls whilst a #pragma pack is in effect. (add_weak): New function: Cache a #pragma weak directive. (handle_pragma_token): Document calling conventions. Add support for #pragma pack(push,) and #pragma pack (pop). * c-pragma.h: If HANDLE_SYSV_PRAGMA or HANDLE_PRAGMA_PACK_PUSH_POP are defined enable HANDLE_PRAGMA_PACK. Move 'struct weak_syms' here (from varasm.c). Add pragma states for push and pop pragmas. * c-common.c (decl_attributes): Call PRAGMA_INSERT_ATTRIBUTES if it is defined. * c-lex.c: Replace occurances of HANDLE_SYSV_PRAGMA with HANDLE_GENERIC_PRAGMAS. * varasm.c: Move definition of 'struct weak_syms' into c-pragma.h. (handle_pragma_weak): Deleted. * config/i386/i386.h: Define HANDLE_PRAGMA_PACK_PUSH_POP. * config/winnt/win-nt.h: Define HANDLE_PRAGMA_PACK_PUSH_POP. * c-decl.c (start_function): Add invocation of SET_DEFAULT_DECL_ATTRIBUTES, if defined. * tm.texi: Remove description of non-existent macro SET_DEFAULT_SECTION_NAME. (HANDLE_SYSV_PRAGMA): Document. (HANDLE_PRAGMA_PACK_PUSH_POP): Document. Wed Sep 30 22:27:53 1998 Robert Lipe * config.sub: Recognize i[34567]86-pc-udk as new target. * configure.in: Likewise. * config/i386/t-udk: New file. * config/i386/udk.h: New file. Wed Sep 30 19:33:07 1998 Jeffrey A Law (law@cygnus.com) * reorg.c (check_annul_list_true_false): Remove unused variables. (steal_delay_list_from_target): Add missing "used_annul" variable. (try_merge_delay_insns): Close out half formed comment. Wed Sep 30 19:13:20 1998 Zack Weinberg * cpplib.c (macroexpand): If arg->raw_before or arg->raw_after, remove any no-reexpansion escape at the beginning of the pasted token. Correct handling of whitespace markers and no-reexpand markers at the end if arg->raw_after. * toplev.c (documented_lang_options): Recognize -include, -imacros, -iwithprefix, -iwithprefixbefore. * cpplib.c (cpp_start_read): Process -imacros and -include switches at the same time and in command-line order, after initializing the dependency-output code. Emit properly nested #line directives for them. Emit a #line for the main file before processing these switches, and don't do it again afterward. Wed Sep 30 18:03:22 1998 Richard Henderson * function.c (purge_addressof_1): Use bitfield manipulation routines to handle mem mode < reg mode. Wed Sep 30 18:43:32 1998 Herman ten Brugge * reorg.c (try_merge_delay_insns): Account for resources referenced in each instruction in INSN's delay list before trying to eliminate useless instructions. Similarly when looking at a trial insn's delay slots. * reorg.c (check_annul_list_true_false): New function. (steal_delay_list_from_{target,fallthrough}): Call it and also refine tests for when we may annul if already filled a slot. (fill_slots_from_thread): Likewise. (delete_from_delay_slot): Return newly-created thread. (try_merge_delay_isns): Use its new return value. Wed Sep 30 18:29:26 1998 Jeffrey A Law (law@cygnus.com) * loop.c (check_dbra_loop): Use a vanilla loop reversal if the biv is used to compute a giv or as some other non-counting use. Wed Sep 30 18:19:27 1998 Michael Hayes * regs.h (HARD_REGNO_CALL_PART_CLOBBERED): New macro. * local-alloc.c (find_free_reg): Use it. * global.c (find_reg): Likewise. * tm.texi: Document HARD_REGNO_CALL_PART_CLOBBERED. * regs.h (HARD_REGNO_CALLER_SAVE_MODE): New macro. * caller-save.c (init_caller_save): Use it. * tm.texi: Document HARD_REGNO_CALLER_SAVE_MODE. Wed Sep 30 12:57:30 1998 Zack Weinberg * configure.in: Add --enable-cpplib option which uses cpplib for cpp, but doesn't link cpplib into cc1. Make help text capitalization consistent. * configure: Rebuilt. Wed Sep 30 10:09:39 1998 Mark Mitchell * function.c (gen_mem_addressof): If the address REG is REG_USERVAR_P make the new REG be so also. * loop.c (scan_loop): Apply DeMorgan's laws and add documentation in an attempt to clarify slightly. Wed Sep 30 09:57:40 1998 Jeffrey A Law (law@cygnus.com) * expr.c (expand_expr): Handle COMPONENT_REF, BIT_FIELD_REF ARRAY_REF and INDIRECT_REF in code to check MAX_INTEGER_COMPUTATION_MODE. Wed Sep 30 10:13:39 1998 Catherine Moore * toplev.c: Fix last patch. Tue Sep 29 20:03:18 1998 Jim Wilson * loop.c (get_condition): Fix typo in May 9 change. Tue Sep 29 11:11:38 1998 Andrew MacLeod * invoke.texi (-fexceptions): Merge 2 different descriptions. Mon Sep 28 22:08:52 1998 Kaveh R. Ghazi * toplev.c (documented_lang_options): Spelling corrections. Mon Sep 28 19:41:24 1998 Alexandre Oliva * configure.in: New flags --with-ld and --with-as, equivalent to setting LD and AS environment variables. Test whether specified arguments are GNU commands, and report them with checking messages. Use the specified AS for configure tests too. * configure: Likewise. * acconfig.h: Add DEFAULT_ASSEMBLER and DEFAULT_LINKER. * config.in: Likewise. * gcc.c (find_a_file): When looking for `as' and `ld', return the DEFAULT program if it exists. * collect2.c (main): Use DEFAULT_LINKER if it exists. * gcc.c (find_a_file): The test for existence of a full pathname was reversed. Mon Sep 28 17:34:35 1998 Michael Meissner * rs6000.h (ASM_OUTPUT_MI_THUNK): Only define on ELF systems. * rs6000.c (output_mi_thunk): Always use a raw jump for now. Mon Sep 28 14:24:03 1998 Mark Mitchell * tree.h (TYPE_BINFO): Document. Mon Sep 28 12:55:49 1998 Stan Cox * i386-coff.h (dbxcoff.h): Added. Mon Sep 28 12:51:00 1998 Catherine Moore * toplev.c: Fix bad patch around flag_data_sections. Mon Sep 28 10:32:28 1998 Nick Clifton * reload1.c (reload): Use reload_address_index_reg_class and reload_address_base_reg_class when setting caller_save_spill_class. (Patch generated by Jim Wilson: wilson@cygnus.com). Mon Sep 28 07:43:34 1998 Mark Mitchell * c-common.c (c_get_alias_set): Tighten slightly for FUNCTION_TYPEs and ARRAY_TYPEs. Tidy up. Improve support for type-punning. * expr.c (store_field): Add alias_set parameter. Set the MEM_ALIAS_SET accordingly, if the target is a MEM. (expand_assignment): Use it. (store_constructor_field): Pass 0. (expand_expr): Likewise. Mon Sep 28 07:54:03 1998 Catherine Moore * flags.h: Add flag_data_sections. * toplev.c: Add option -fdata-sections. Add flag_data_sections. (compile_file): Error if flag_data_sections not supported. * varasm.c (assemble_variable): Handle flag_data_sections. * config/svr4.h: Modify prefixes for UNIQUE_SECTION_NAME. * config/mips/elf.h: Likewise. * config/mips/elf64.h: Likewise. * invoke.texi: Describe -fdata-sections. Mon Sep 28 04:15:44 1998 Craig Burley * invoke.texi (-ffloat-store): Clarify that this option does not affect intermediate results -- only variables. Mon Sep 28 04:11:35 1998 Jeffrey A Law (law@cygnus.com) * cpp.texi: Update for Fortran usage from Craig. Fri Sep 25 22:09:47 1998 David Edelsohn * rs6000.c (function_arg_boundary): Revert accidental change on September 18. Fri Sep 25 20:30:00 1998 Michael Meissner * rs6000.h (ASM_OUTPUT_MI_THUNK): Declare, call output_mi_thunk. (output_mi_thunk): Declare. * rs6000.c (output_mi_thunk): Function to create thunks for MI. (output_function_profiler): Use r12 for temp, instead of r11 so that we preserve the static chain register. Fri Sep 25 14:18:33 1998 Jim Wilson * sdbout.c (sdbout_one_type): Don't look at TYPE_BINFO field of enums. Fri Sep 25 19:30:19 1998 J"orn Rennecke * sh.c (gen_shl_sext): Fix case 5. Fri Sep 25 17:35:23 1998 J"orn Rennecke * reload1.c (reload_combine): Re-add line that got accidentally lost. Fri Sep 25 10:43:47 1998 Kaveh R. Ghazi * cccp.c (pedwarn_with_file_and_line): For !__STDC__ case, avoid accessing variables until they are initialized via va_arg(). Thu Sep 24 22:12:16 1998 David S. Miller * reload1.c (reload_combine): Initialize set before using. Thu Sep 24 18:53:20 1998 Jason Merrill * sdbout.c (sdbout_field_types): Don't emit the types of fields we won't be emitting. Thu Sep 24 17:05:30 1998 Nick Clifton * config/arm/arm.md (insv): Add comment. In CONST_INT case, and operand3 with mask before using it. Patch provided by Jim Wilson. Thu Sep 24 15:08:08 1998 Jakub Jelinek * config/sparc/sparc.c (function_value): Perform the equivalent of PROMOTE_MODE for ARCH64. (eligible_for_epilogue_delay): Allow DImode operations in delay slot of a return for ARCH64. Thu Sep 24 22:17:54 1998 J"orn Rennecke * sh.md (sqrtsf2): Fix mode of sqrt. Thu Sep 24 21:48:51 1998 J"orn Rennecke * reload1.c (choose_reload_regs): Also try inheritance when reload_in is a stack slot of a pseudo, even if we already got a reload reg. Thu Sep 24 21:22:39 1998 J"orn Rennecke * reload1.c (reload_cse_regs_1): Renamed from reload_cse_regs. (reload_cse_regs): New function body: call reload_cse_regs_1, reload_combine, reload_cse_move2add. When doing expensive_optimizations, call reload_cse_regs_1 a second time after reload_cse_move2add. (reload_combine, reload_combine_note_store): New functions. (reload_combine_note_use): New function. (reload_cse_move2add, move2add_note_store): New functions. Thu Sep 24 18:48:43 1998 J"orn Rennecke * reload.c (find_reloads): In code to promote RELOAD_FOR_X_ADDR_ADDR reloads to RELOAD_FOR_X_ADDRESS reloads, test for reload sharing. Properly keep track of first RELOAD_FOR_X_ADDRESS also for more than 3 such reloads. If there is not more than one RELOAD_FOR_X_ADDRESS, don't change RELOAD_FOR_X_ADDR_ADDR reload. Thu Sep 24 17:45:55 1998 J"orn Rennecke * expr.c (store_constructor): When initializing a field that is smaller than a word, at the start of a word, try to widen it to a full word. * cse.c (cse_insn): When we are about to change a register, remove any invalid references to it. (remove_invalid_subreg_refs): New function. (mention_regs): Special treatment for SUBREGs. (insert_regs): Don't strip SUBREG for call to mention_regs. Check if reg_tick needs to be bumped up before that call. (lookup_as_function): Try to match known word_mode constants when looking for a norrower constant. (canon_hash): Special treatment for SUBREGs. Thu Sep 24 01:35:34 1998 David S. Miller * config/sparc/sol2-sld-64.h (TRANSFER_FROM_TRAMPOLINE): Define. * config/sparc/sparc.c (sparc64_initialize_trampoline): If that is defined, emit libcall to __enable_execute_stack. Also fix opcodes and offsets in actual stack trampoline code so they match the commentary and actually work. Thu Sep 24 01:19:02 1998 Jakub Jelinek * configure.in (sparcv9-*-solaris): Use t-sol2 and t-sol2-64 for tmake_file. (sparc64-*-linux): Use t-linux and sparc/t-linux64 for tmake_file. Set extra_parts to needed crt objects. * configure: Rebuilt. * config/sparc/linux64.h (SPARC_BI_ARCH): Define. (TARGET_DEFAULT): Set if default is v9 or ultra. (STARTFILE_SPEC32, STARTFILE_SPEC64): New macros. (STARTFILE_SPEC): Set to those upon SPARC_BI_ARCH. (ENDFILE_SPEC32, ENDFILE_SPEC64, ENDFILE_SPEC): Likewise. (SUBTARGET_EXTRA_SPECS, LINK_ARCH32_SPEC, LINK_ARCH64_SPEC, LINK_SPEC, LINK_ARCH_SPEC): Likewise. (TARGET_VERSION): Define. (MULTILIB_DEFAULT): Define. * config/sparc/sparc.h (CPP_CPU_DEFAULT_SPEC): Rearrange so that mixed 32/64 bit compilers based upon SPARC_BI_ARCH work. (CPP_CPU64_DEFAULT_SPEC, CPP_CPU32_DEFAULT_SEC): Define appropriately. (TARGET_SWITCHES): Allow ptr32/ptr64 options once more. * config/sparc/sparc.c (sparc_override_options): If arch and pointer size disagree, emit diagnostic and fix it up. If SPARC_BI_ARCH and TARGET_ARCH32, set cmodel to CM_32. Turn off V8PLUS in 64-bit mode. * config/sparc/t-linux64: New file. * config/sparc/t-sol2-64: New file. * config/sparc/t-sol2: Adjust build rules to use MULTILIB_CFLAGS. * config/sparc/sol2-sld-64.h (SPARC_BI_ARCH): Define. (ASM_CPU32_DEFAULT_SPEC, ASM_CPU64_DEFAULT_SPEC, CPP_CPU32_DEFAULT_SPEC, CPP_CPU64_DEFAULT_SPEC): Define. (ASM_SPEC, CPP_CPU_SPEC): Set appropriately based upon those. (STARTFILE_SPEC32, STARTFILE_SPEC32, STARTFILE_ARCH_SPEC): Define. (STARTFILE_SPEC): Set appropriately based upon those. (CPP_CPU_DEFAULT_SPEC, ASM_CPU_DEFAULT_SPEC): Set based upon disposition of DEFAULT_ARCH32_P. (LINK_ARCH32_SPEC, LINK_ARCH64_SPEC): Define. (LINK_ARCH_SPEC, LINK_ARCH_DEFAULT_SPEC): Set based upon those. (CC1_SPEC, MULTILIB_DEFAULTS): Set based upon DEFAULT_ARCH32_P. (MD_STARTFILE_PREFIX): Set correctly based upon SPARC_BI_ARCH. * config/sparc/xm-sysv4-64.h (HOST_BITS_PER_LONG): Only set on arch64/v9. * config/sparc/xm-sp64.h (HOST_BITS_PER_LONG): Likewise. Wed Sep 23 22:32:31 1998 Mark Mitchell * rtl.h (init_virtual_regs): New function. * emit-rtl.c (init_virtual_regs): Define. (insn_emit): Use it. * integrate.c (save_for_inline_copying): Likewise. Wed Sep 23 16:22:01 1998 Nick Clifton * config/arm/thumb.h: The following patches were made by Jim Wilson: (enum reg_class): Add NONARG_LO_REGS support. (REG_CLASS_NAMES, REG_CLASS_CONTENTS, REGNO_REG_CLASS, PREFERRED_RELOAD_CLASS, SECONDARY_RELOAD_CLASS): Likewise. (GO_IF_LEGITIMATE_ADDRESS): Disable REG+REG addresses before reload completes. Re-enable HImode REG+OFFSET addresses. (LEGITIMIZE_RELOAD_ADDRESS): Define. * expmed.c (extract_bit_field): Add comment from Jim Wilson. Wed Sep 23 13:26:02 1998 Richard Henderson * alpha.c (get_aligned_mem): Revert Sep 20 change. (alpha_set_memflags, alpha_set_memflags_1): Likewise. (alpha_align_insns): Properly calculate initial offset wrt max_align. Wed Sep 23 10:45:44 1998 Richard Earnshaw (rearnsha@arm.com) * arm.c (find_barrier): Revert change of Apr 23. Handle table jumps as a single entity, taking into account the size of the table. Tue Sep 22 15:13:34 1998 Alexandre Petit-Bianco * tree.def (SWITCH_EXPR): New tree node definition. Mon Sep 21 23:40:38 1998 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. Mon Sep 21 22:31:14 1998 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. Mon Sep 21 22:48:09 1998 Jeffrey A Law (law@cygnus.com) * configure.in: Recognize i[34567]86-*-openbsd* and handle it like NetBSD. Mon Sep 21 22:05:28 1998 Jeffrey A Law (law@cygnus.com) * Revert this patch. * reload.c (find_reloads): Do not replace a pseudo with (MEM (reg_equiv_addr)) in the initializing insn for the pseudo. Mon Sep 21 20:19:41 1998 John Carr * final.c (final_scan_insn): Disable tracking CC across branches. Mon Sep 21 17:15:26 1998 Andrew MacLeod * expr.h (eh_rtime_match_libfunc): New extern declaration. * optabs.c (init_optabs): Set eh_rtime_match_libfunc. * except.c (start_catch_handler): Use eh_rtime_match_libfunc. * libgcc2.c (__eh_rtime_match): Always return 0 if the matcher is NULL. Only include if inhibit_libc is not defined. Mon Sep 21 14:10:51 1998 Jason Merrill * toplev.c (rest_of_compilation): Skip compiling anything with DECL_EXTERNAL set, not just if it has DECL_INLINE as well. Mon Sep 21 13:51:05 1998 Jim Wilson * flow.c (find_basic_blocks): Delete check for in_libcall_block when prev_code is a CALL_INSN. Change check for REG_RETVAL note to use in_libcall_block. (find_basic_blocks_1): Delete check for in_libcall_block when prev_code is a CALL_INSN. If CALL_INSN and in_libcall_block, then change code to INSN. Mon Sep 21 14:02:23 1998 Robert Lipe * i386.h (TARGET_SWITCHES): Improve doc for align-double. Fix typo in no-fancy-math-387 description. Mon Sep 21 09:27:18 1998 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. Mon Sep 21 09:24:49 1998 Stan Cox * i386-coff.h (DBX_DEBUGGING_INFO): Added. Mon Sep 21 09:14:49 1998 Robert Lipe * i386.h (TARGET_SWITCHES): Add description fields for flags documented in install.texi. (TARGET_OPTIONS): Likewise. Mon Sep 21 01:39:03 1998 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. Mon Sep 21 01:53:05 1998 Felix Lee * c-lex.c (init_lex): Use getenv ("LANG"), not GET_ENVIRONMENT (). * cccp.c (main): Likewise. * cccp.c, collect2.c, cpplib.c, gcc.c, config/i386/xm-cygwin32.h: Rename GET_ENVIRONMENT to GET_ENV_PATH_LIST, and fix some macro-use bugs. Mon Sep 21 00:52:12 1998 Per Bothner * Makefile.in (LIBS): Link in libiberty.a. * c-common.c, gcc.c, toplev.c: Replace (some) bcopy calls by memcpy. Sun Sep 20 23:28:11 1998 Richard Henderson * reload1.c (emit_reload_insns): Accept a new arg for the bb. Use it to update bb boundaries. Update caller. * function.c (reposition_prologue_and_epilogue_notes): Update bb boundaries wrt the moved note. Sun Sep 20 20:57:02 1998 Robert Lipe * configure.in (i*86-*-sysv5*): Use fixinc.svr4 to patch byteorder problems. * configure: Regenerate. Sun Sep 20 19:01:51 1998 Richard Henderson * alpha.c (alpha_sr_alias_set): New variable. (override_options): Set it. (alpha_expand_prologue, alpha_expand_epilogue): Use it. (mode_mask_operand): Fix signed-unsigned comparison warning. (alpha_expand_block_move): Likewise. (print_operand): Likewise. (get_aligned_mem): Use change_address. (alpha_set_memflags, alpha_set_memflags_1): Set the alias set. (alphaev4_insn_pipe, alphaev4_next_group): New functions. (alphaev4_next_nop, alphaev5_next_nop): New functions. (alpha_align_insns): Remade from old alphaev5_align_insns to handle multiple processors. (alpha_reorg): Call alpha_align_insns for both ev4 and ev5. * output.h (label_to_alignment): Prototype. * tree.c (new_alias_set): New function. * tree.h (new_alias_set): Declare it. * c-common.c (c_get_alias_set): Use it. Sun Sep 20 12:35:55 1998 Richard Henderson * fold-const.c (fold): Yet another COND_EXPR bug: when folding to an ABS expr, convert an unsigned input to signed. Sun Sep 20 12:14:45 1998 Jeffrey A Law (law@cygnus.com) * fold-const.c (fold): Fix another type in COND_EXPR handling code. 1998-09-20 Michael Hayes * configure.in: Add support for c4x targets. * configure: Rebuilt. Sun Sep 20 00:00:51 1998 Richard Henderson * combine.c (distribute_notes): If an insn is a cc0 user, only delete it if we can also delete the cc0 setter. Sun Sep 20 00:22:23 1998 Michael Tiemann * fold-const.c (fold): Fix typo in COND_EXPR handling code. (invert_truthvalue): Enable truthvalue inversion for floating-point operands if -ffast-math. Sat Sep 19 23:58:07 1998 Melissa O'Neill * configure.in: Disable collect2 for nextstep. Instead use crtbegin/crtend. * configure: Rebuilt. * config/nextstep.h (STARTFILE_SPEC): Add crtbegin. (ENDFILE_SPEC): Define. (OBJECT_FORMAT_MACHO): Define. (EH_FRAME_SECTION_ASM_OP): Define. * crtstuff.c: Handle MACHO. Sun Sep 20 00:24:24 1998 Robert Lipe * config/i386/sco5.h (TARGET_MEM_FUNCTIONS): Define. 1998-09-19 Torbjorn Granlund * fp-bit.c (pack_d): Do not clear SIGN when fraction is 0. (_fpadd_parts): Get sign right for 0. 1998-09-19 Michael Hayes * ginclude/varargs.h: Add support for C4x target. * ginclude/stdargs.h: Likewise. Sat Sep 19 12:05:09 1998 Richard Henderson * alpha.c (alpha_return_addr): SET should be VOIDmode. (alpha_emit_set_long_const): Rewrite to be callable from reload and 32-bit hosts. (alpha_expand_epilogue): Update for alpha_emit_set_long_const. * alpha.md (movdi): Likewise. Sat Sep 19 07:33:36 1998 Richard Earnshaw (rearnsha@arm.com) * arm.c (add_constant): New parameter address_only, change caller. Set it non-zero if taking the address of an item in the pool. (arm_reorg): Handle cases where we need the address of an item in the pool. * arm.c (bad_signed_byte_operand): Check both arms of a sum in a memory address. * arm.md (splits for *extendqihi_insn and *extendqisi_insn): Handle memory addresses that are not in standard canonical form. Sat Sep 19 01:00:32 1998 Michael Hayes (mph@elec.canterbury.ac.nz) * README.C4X: New file with information about the c4x ports. * ginclude/va-c4x.h: New file for c4x varargs support. * config/c4x: New directory with c4x port files. Fri Sep 18 22:52:05 1998 Jeffrey A Law (law@cygnus.com) * reload.c (find_reloads): Do not replace a pseudo with (MEM (reg_equiv_addr)) in the initializing insn for the pseudo. Fri Sep 18 23:50:56 1998 David Edelsohn * toplev.c (rest_of_compilation): Set bct_p on second call to loop_optimize. * loop.c (loop_optimize, scan_loop, strength_reduce): New argument bct_p. (strength_reduce): Only call analyze_loop_iterations and insert_bct if bct_p set. (check_dbra_loop): Fix typo. (insert_bct): Use word_mode instead of SImode. (instrument_loop_bct): Likewise. Do not delete iteration count condition code generation insn. Initialize iteration count before loop start. * rtl.h (loop_optimize): Update prototype. * ginclude/va-ppc.h (va_arg): longlong types in overflow area are not doubleword aligned. * rs6000.c (optimization_options): New function. (secondary_reload_class): Only call true_regnum for PSEUDO_REGs. * rs6000.h (OPTIMIZATION_OPTIONS): Define. (REG_ALLOC_ORDER): Allocate highest numbered condition regsiters first; cr1 can be used for FP record condition insns. Fri Sep 18 09:44:55 1998 Nick Clifton * config/m32r/m32r.h (m32r_block_immediate_operand): Add to PREDICATE_CODES. * config/m32r/m32r.md: Add "movstrsi" and "movstrsi_internal" patterns. * config/m32r/m32r.c (m32r_print_operand): Add 's' and 'p' operators. (block_move_call): New function: Call a library routine to copy a block of memory. (m32r_expand_block_move): New function: Expand a "movstrsi" pattern into a sequence of insns. (m32r_output_block_move): New function: Expand a "movstrsi_internal" pattern into a sequence of assembler opcodes. (m32r_block_immediate_operand): New function: Return true if the RTL is an integer constant, less than or equal to MAX_MOVE_BYTES. Thu Sep 17 16:42:16 1998 Andrew MacLeod * except.c (start_catch_handler): Issue 'fatal' instead of 'error' and re-align some code. * libgcc2.c (__eh_rtime_match): fprintf a runtime error. Use . Thu Sep 17 12:24:33 1998 J"orn Rennecke * regmove.c (copy_src_to_dest): Check that modes match. Wed Sep 16 22:10:42 1998 Robert Lipe * config/i386/sco5.h (SUPPORTS_WEAK): True only if targeting ELF. Wed Sep 16 15:24:54 1998 Richard Henderson * i386.h (PREFERRED_RELOAD_CLASS): Respect an existing class narrower than FLOAT_REGS. Wed Sep 16 17:51:00 1998 Alexandre Oliva * cpplib.c: Removed OLD_GPLUSPLUS_INCLUDE_DIR. * cccp.c: Likewise. * Makefile.in (old_gxx_include_dir): Removed. Wed Sep 16 12:29:22 1998 Nick Clifton * config/sh/sh.h: Update definition of HANDLE_PRAGMA to match new specification. * config/sh/sh.c (handle_pragma): Rename to sh_handle_pragma(). (sh_handle_pragma): Change function arguments to match new specification for HANDLE_PRAGMA. Wed Sep 16 12:43:19 1998 Kaveh R. Ghazi * gen-protos.c (parse_fn_proto): Cast argument of ISALNUM to `unsigned char'. (main): Mark parameter `argc' with ATTRIBUTE_UNUSED. When generating output, initialize missing struct member to zero. Wed Sep 16 14:47:43 1998 J"orn Rennecke * regmove.c (copy_src_to_dest): Don't copy if that requires (a) new register(s). Wed Sep 16 01:29:12 1998 Bernd Schmidt * global.c (reg_allocno): Now static. * reload1.c (reg_allocno): Delete declaration. (order_regs_for_reload): Take no arguments. Don't treat regs allocated by global differently than those allocated by local-alloc. Wed Sep 16 01:09:01 1998 Kamil Iskra * m68k/m68k.c (output_function_prologue): Reverse NO_ADDSUB_Q condition, fix format strings. (output_function_epilogue): Likewise. * m68k/m68k.c: Don't include directly. Wed Sep 16 00:30:56 1998 Geoff Keating * gcse.c: New definition NEVER_SET for reg_first_set, reg_last_set, mem_first_set, mem_last_set; because 0 can be a CUID. (oprs_unchanged_p): Use new definition. (record_last_reg_set_info): Likewise. (record_last_mem_set_info): Likewise. (compute_hash_table): Likewise. Tue Sep 15 22:59:52 1998 Jeffrey A Law (law@cygnus.com) * rs6000.c (output_epilogue): Handle Chill. * mn10200.h (ASM_OUTPUT_DWARF2_ADDR_CONST): Define. * mn10300.h (ASM_OUTPUT_DWARF2_ADDR_CONST): Define. * combine.c (make_extraction): If no mode is specified for an operand of insv, extv, or extzv, default it to word_mode. (simplify_comparison): Similarly. * expmed.c (store_bit_field): Similarly. (extract_bit_field): Similarly. * function.c (fixup_var_regs_1): Similarly. * recog.c (validate_replace_rtx_1): Similarly. * mips.md (extv, extzv, insv expanders): Default modes for most operands. Handle TARGET_64BIT. (movdi_uld, movdi_usd): New patterns. * pa.c (emit_move_sequence): Do not replace a pseudo with its equivalent memory location unless we have been provided a scratch register. Similarly do not call find_replacement unless a scratch register has been provided. Tue Sep 15 19:23:01 1998 Bernd Schmidt * i386.h (PREFERRED_RELOAD_CLASS): For standard 387 constants, return FLOAT_REGS. Tue Sep 15 19:09:06 1998 Richard Henderson * tree.h (BUILT_IN_CALLER_RETURN_ADDRESS): Unused. Kill. (BUILT_IN_FP, BUILT_IN_SP, BUILT_IN_SET_RETURN_ADDR_REG): Kill. (BUILT_IN_EH_STUB_OLD, BUILT_IN_EH_STUB, BUILT_IN_SET_EH_REGS): Kill. (BUILT_IN_EH_RETURN, BUILT_IN_DWARF_CFA): New. * c-decl.c (init_decl_processing): Update accordingly. * expr.c (expand_builtin): Likewise. * rtl.h (global_rtl): Add cfa entry. (virtual_cfa_rtx, VIRTUAL_CFA_REGNUM): New. (LAST_VIRTUAL_REGISTER): Update. * emit-rtl.c (global_rtl): Add cfa entry. (init_emit): Initialize it. * function.c (cfa_offset): New. (instantiate_virtual_regs): Initialize it. (instantiate_virtual_regs_1): Instantiate virtual_cfa_rtx. (expand_function_end): Call expand_eh_return. * tm.texi (ARG_POINTER_CFA_OFFSET): New. * except.c (current_function_eh_stub_label): Kill. (current_function_eh_old_stub_label): Likwise; update all references. (expand_builtin_set_return_addr_reg): Kill. (expand_builtin_eh_stub_old, expand_builtin_eh_stub): Kill. (expand_builtin_set_eh_regs): Kill. (eh_regs): Produce a third reg for the actual handler address. (eh_return_context, eh_return_stack_adjust): New. (eh_return_handler, eh_return_stub_label): New. (init_eh_for_function): Initialize them. (expand_builtin_eh_return, expand_eh_return): New. * except.h: Update prototypes. * flow.c (find_basic_blocks_1): Update references to the stub label. * function.h (struct function): Kill stub label elements. * libgcc2.c (in_reg_window): For REG_SAVED_REG, check that the register number is one that would be in the previous window. Provide a dummy definition for non-windowed targets. (get_reg_addr): New function. (get_reg, put_reg, copy_reg): Use it. (__throw): Rely on in_reg_window, not INCOMING_REGNO. Kill stub generating code and use __builtin_eh_return. Use __builtin_dwarf_cfa. * alpha.c (alpha_eh_epilogue_sp_ofs): New. (alpha_init_expanders): Initialize it. (alpha_expand_epilogue): Use it. * alpha.h: Declare it. * alpha.md (eh_epilogue): New. * m68h.h (ARG_POINTER_CFA_OFFSET): New. * sparc.h (ARG_POINTER_CFA_OFFSET): New. Tue Sep 15 19:31:58 1998 Michael Meissner * i960.h (CONST_COSTS): Fix thinko. Test flag, not the constant flag bit mask. Tue Sep 15 14:10:54 1998 Andrew MacLeod * except.h (struct eh_entry): Add false_label field. (end_catch_handler): Add prototype. * except.c (push_eh_entry): Set false_label field to NULL_RTX. (start_catch_handler): When using old style exceptions, issue runtime typematch code before continuing with the handler. (end_catch_handler): New function, generates label after handler if needed by older style exceptions. (expand_start_all_catch): No need to check for new style exceptions. (output_exception_table_entry): Only output the first handler label for old style exceptions. * libgcc2.c (__eh_rtime_match): New routine to lump runtime matching mechanism into one function, if a runtime matcher is provided. Tue Sep 15 13:53:59 1998 Andrew MacLeod * config/i960/i960.h (SLOW_BYTE_ACCESS): Change definition to 1. Tue Sep 15 09:59:01 1998 Mark Mitchell * integrate.c (copy_decl_list): Fix typo. Tue Sep 15 04:18:52 1998 David S. Miller * config/sparc/sparc.md (movdf_const_intreg_sp32): Fix length attribute. Mon Sep 14 14:02:53 1998 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. Mon Sep 14 10:33:56 1998 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. Mon Sep 14 09:51:05 1998 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. Sun Sep 13 22:10:18 1998 David S. Miller * invoke.texi (C Dialect Options): Put back missing @end itemize. Mon Sep 14 02:33:46 1998 Alexandre Oliva * configure.in: Remove usage of `!' to negate the result of a command; some common shells do not support it. Sun Sep 13 19:17:35 1998 David S. Miller * configure.in: In sparc9-sol2 config, use 'if test' not brackets. * configure: Rebuilt. * config/sparc/sol2-sld-64.h (SPARC_DEFAULT_CMODEL): Change to CM_MEDANY. (CPP_CPU_SPEC): Do not define _LP64, header files do this. (CPP_CPU_DEFAULT_SPEC): Likewise. * config/sparc/sol2.h (INIT_SUBTARGET_OPTABS): Get the names right for arch64 libfuncs. * config/sparc/sparc.md (goto_handler_and_restore): Allow any mode for operand zero. Sun Sep 13 09:11:59 1998 Kaveh R. Ghazi * acconfig.h (NEED_DECLARATION_STRSIGNAL): Provide a stub. * collect2.c: Don't declare `sys_siglist' here. (my_strsignal): Prototype and define new function. Use it in place of `sys_siglist' hacks. * mips_tfile.c: Likewise. * configure.in (AC_CHECK_FUNCS): Check for strsignal. (GCC_NEED_DECLARATIONS): Likewise. * system.h (strsignal): Prototype it, if necessary. (sys_siglist): Declare it, if necessary. Sun Sep 13 04:37:28 1998 David S. Miller * loop.c (move_movables): While removing insn sequences, preserve the next pointer of the most recently deleted insn when we skip over a NOTE. Sun Sep 13 08:13:39 1998 Ben Elliston * objc/config-lang.in: Do not output the name of the selected thread file when building the front-end. The Makefile for the runtime library will do this. * objc/Make-lang.in: Do not build the runtime library or install the Objective C header files. The Makefile for the runtime library will do this. * objc/Makefile.in (all.indirect): Only build the front-end. (compiler): Rename to `frontend'. (obj-runtime): Remove target. (copy-headers): Likewise. (clean): No need to remove `libobjc.a' any longer. Sat Sep 12 11:37:19 1998 Michael Meissner * rs6000.h ({ASM,CPP}_CPU_SPEC): Add support for all machines supported with -mcpu=xxx. Fri Sep 11 23:55:54 1998 David S. Miller * flow.c (mark_set_1): Recognize multi-register structure return values in CALL insns. (mark_used_regs): Likewise. (count_reg_sets_1): Likewise. (count_reg_references): Likewise. * rtlanal.c (note_stores): Likewise. (reg_overlap_mentioned_p): Likewise. * haifa-sched.c (check_live_1): Likewise. (update_live_1): Likewise. (sched_analyze_1): Likewise. (sched_note_set): Likewise. (birthing_insn_p): Likewise. (attach_deaths): Likewise. * config/sparc/sparc.md (movdf_const_intreg_sp64): Disable. Fri Sep 11 22:57:55 1998 Eric Dumazet * config/i386/sco5.h (ASM_WEAKEN_LABEL): Defined as in svr4.h. Thu Sep 10 22:02:04 1998 David S. Miller * glimits.h (__LONG_MAX__): Recognize __sparcv9 too. Thu Sep 10 21:19:10 1998 Jakub Jelinek * configure.in: Add check for GAS subsection -1 support. * acconfig.h (HAVE_GAS_SUBSECTION_ORDERING): Add. * configure config.in: Rebuilt. * config/sparc/sparc.h (CASE_VECTOR_MODE): For V9 flag_pic, use SImode is subsection -1 works, else use DImode. (ASM_OUTPUT_ADDR_VEC_START, ASM_OUTPUT_ADDR_VEC_END): Define if subsection -1 works. * config/sparc/sparc.c (sparc_output_addr_vec, sparc_output_addr_diff_vec): Use them if defined. Thu Sep 10 10:46:01 1998 Mark Mitchell * tree.h (DECL_ORIGIN): New macro. * integrate.c (copy_and_set_decl_abstract_origin): New function. (copy_decl_list): Use it. (integrate_parm_decls): Likewise. (integrate_decl_tree): Likewise. * dwarf2out.c (decl_ultimate_origin): Simplify. * dwarfout.c (decl_ultimate_origin): Likewise. * c-decl.c (duplicate_decls): Use DECL_ORIGIN. (pushdecl): Likewise. Thu Sep 10 08:01:31 1998 Anthony Green * config/rs6000/rs6000.c (output_epilog): Add Java support. Thu Sep 10 14:48:59 1998 Martin von Löwis * invoke.texi (C++ Dialect Options): Document -fhonor-std. Thu Sep 10 01:38:05 1998 Jeffrey A Law (law@cygnus.com) * reg-stack.c (straighten_stack): Do nothing if the virtual stack is empty or has a single entry. * toplev.c (rest_of_compilation): Open up the dump file for reg-stack before calling reg_to_stack. Thu Sep 10 00:03:34 1998 Richard Henderson * alpha.c (alphaev5_insn_pipe): Abort on default case. (alphaev5_next_group): Swallow CLOBBERs and USEs. * c-tree.h (warn_long_long): Declare it. Wed Sep 9 23:31:36 1998 (Stephen L Moshier) * emit-rtl.c (gen_lowpart_common): Disable optimization of initialized float-int union if the value is a NaN. Wed Sep 9 23:00:48 1998 Nathan Sidwell * c-lex.c (real_yylex): Don't warn about long long constants if we're allowing long long Wed Sep 9 21:58:41 1998 Bernd Schmidt * except.h (current_function_eh_stub_label): Declare. (current_function_eh_old_stub_label): Declare. * function.h (struct function): New members eh_stub_label and eh_old_stub_label. * except.c (current_function_eh_stub_label): New variable. (current_function_eh_old_stub_label): New variable. (init_eh_for_function): Clear them. (save_eh_status): Save them. (restore_eh_status): Restore them. (expand_builtin_eh_stub): Set current_function_eh_stub_label. (expand_builtin_eh_stub_old): Set current_function_eh_old_stub_label. * flow.c (find_basic_blocks_1): When handling a REG_LABEL note, don't make an edge from the block that contains it to the block starting with the label if this label is one of the eh stub labels. If eh stub labels exist, show they are reachable from the last block in the function. * reload1.c (reload): Break out several subroutines and make some variables global. (calculate_needs_all_insns): New function, broken out of reload. (calculate_needs): Likewise. (find_reload_regs): Likewise. (find_group): Likewise. (find_tworeg_group): Likewise. (something_needs_reloads): New global variable, formerly in reload. (something_needs_elimination): Likewise. (caller_save_spill_class): Likewise. (caller_save_group_size): Likewise. (max_needs): Likewise. (group_size): Likewise. (max_groups): Likewise. (max_nongroups): Likewise. (group_mode): Likewise. (max_needs_insn): Likewise. (max_groups_insn): Likewise. (max_nongroups_insn): Likewise. (failure): Likewise. * print-rtl.c (print_rtx): For MEMs, print MEM_ALIAS_SET. Wed Sep 9 13:14:41 1998 Richard Henderson * loop.c (load_mems): Copy rtx for output mem. Wed Sep 9 15:16:58 1998 Gavin Romig-Koch * mips/abi64.h (LONG_MAX_SPEC): Don't set LONG_MAX for mips1 or mips2 either. Wed Sep 9 12:31:35 1998 Jeffrey A Law (law@cygnus.com) * pa.c (pa_reorg): New marking scheme for jumps inside switch tables. (pa_adjust_insn_length): Update to work with new marking scheme for jumps inside switch tables. * pa.md (switch_jump): Remove pattern. (jump): Handle jumps inside jump tables. * Makefile.in (profile.o): Depend on insn-config.h Wed Sep 9 09:36:51 1998 Jim Wilson * iris6.h (DWARF2_UNWIND_INFO): Undef. Wed Sep 9 01:32:01 1998 David S. Miller Add preliminary native sparcv9 Solaris support. * configure.in: Recognize sparv9-*-solaris2* * configure: Rebuilt. * config.sub: Recognize sparcv9 just like sparc64. * config/sparc/sol2-c1.asm config/sparc/sol2-ci.asm config/sparc/sol2-cn.asm: Macroize so it can be shared between 32-bit and 64-bit Solaris systems. * config/sparc/t-sol2: Assemble those with cpp. * config/sparc/sparc.h (TARGET_CPU_sparcv9): New alias for v9. (*TF*_LIBCALL): If ARCH64 use V9 names. * config/sparc/{xm-sysv4-64,sol2-sld-64}.h: New files. Wed Sep 9 01:07:30 1998 Jakub Jelinek * config/sparc/sparc.h (TARGET_CM_MEDMID): Fix documentation. (CASE_VECTOR_MODE): Set to SImode even if PTR64, when MEDLOW and not doing pic. (ASM_OUTPUT_ADDR_{VEC,DIFF}_ELT): Check CASE_VECTOR_MODE not Pmode. * config/sparc/sparc.md (tablejump): Likewise, and sign extend op0 to Pmode if CASE_VECTOR_MODE is something else. Wed Sep 9 00:10:31 1998 Jeffrey A Law (law@cygnus.com) * prefix.c (update_path): Correctly handle cases where PATH is a substring of the builtin prefix, but specifies a different directory location. Tue Sep 8 23:46:04 1998 Hans-Peter Nilsson * expr.c: Corrected comment about what MOVE_RATIO does. * config/alpha/alpha.h: Likewise. * config/1750a/1750a.h: Likewise. * config/clipper/clipper.h: Likewise. * config/i386/i386.h: Likewise. Tue Sep 8 22:56:12 1998 Jeffrey A Law (law@cygnus.com) * configure.in (m68k-next-nextstep3*): Use collect2. Similarly for x86 NeXT configurations. * configure: Rebuilt. Tue Sep 8 01:38:57 1998 Nathan Sidwell * configure.in: Don't assume srcdir is .../gcc. * configure: Rebuilt. Sat Sep 5 16:34:34 1998 John Wehle (john@feith.com) * global.c: Update comments. (global_alloc): Assign allocation-numbers even for registers allocated by local_alloc in case they are later spilled and retry_global_alloc is called. (mark_reg_store, mark_reg_clobber, mark_reg_conflicts, mark_reg_death): Always record a conflict with a pseudo register even if it has been assigned to a hard register. (dump_conflicts): Don't list pseudo registers already assigned to a hard register as needing to be allocated, but do list their conflicts. * local-alloc.c: Update comment. Mon Sep 7 23:38:01 1998 Jeffrey A Law (law@cygnus.com) * configure.in: Check for bogus GCC_EXEC_PREFIX and LIBRARY_PATH. * configure: Rebuilt. Mon Sep 7 22:41:46 1998 Michael Meissner * rs6000.c (rs6000_override_options): Fix name for ec603e, to add missing 'c'. * t-ppccomm (MULTILIB_MATCHES_FLOAT): Add support for -mcpu=xxx for all targets that set -msoft-float. Mon Sep 7 23:30:07 1998 Kaveh R. Ghazi * toplev.c (print_switch_values): Make static to match prototype. Mon Sep 7 19:13:59 1998 Jeffrey A Law (law@cygnus.com) * configure.in: If we are unable to find the "gnatbind" program, then do not configure the ada subdir. * configure: Rebuilt. Sun Sep 6 14:03:58 1998 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. Sun Sep 6 13:28:07 1998 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. Sun Sep 6 08:54:14 1998 Kaveh R. Ghazi * Makefile.in (toplev.o): Depend on $(EXPR_H). (insn-extract.o, insn-attrtab.o): Depend on toplev.h. * gansidecl.h: Define ATTRIBUTE_NORETURN. * genattrtab.c: Have insn-attrtab.c include toplev.h. * genextract.c: Have insn-extract.c include toplev.h. * rtl.h: Don't prototype `fatal_insn_not_found' and `fatal_insn'. * toplev.c: Include expr.h. (really_sorry, fancy_abort): Remove prototypes. (set_target_switch): Add argument in prototype. (vfatal): Mark prototype with ATTRIBUTE_NORETURN. (v_really_sorry): Likewise. (print_version, print_single_switch, print_switch_values): Make static and add prototype arguments. (decl_printable_name): Add prototype arguments. (lang_expand_expr_t): New typedef. (lang_expand_expr): Declare as a lang_expand_expr_t. (incomplete_decl_finalize_hook): Add prototype argument. (decl_name): Mark variable `verbosity' with ATTRIBUTE_UNUSED. (botch): Likewise for variable `s'. (rest_of_type_compilation): Mark variables `type' and `toplev' with ATTRIBUTE_UNUSED if none of DBX_DEBUGGING_INFO, XCOFF_DEBUGGING_INFO or SDB_DEBUGGING_INFO are defined. (display_help): Make variable `i' an `unsigned long'. (main): Remove unused parameter `envp'. Cast assignment to `lang_expand_expr' to a `lang_expand_expr_t'. Cast -1 when comparing it with a `size_t'. * toplev.h (fatal, fatal_io_error, pfatal_with_name): Mark prototype with ATTRIBUTE_NORETURN. (fatal_insn_not_found, fatal_insn, really_sorry, push_float_handler, pop_float_handler): Add prototypes. (fancy_abort): Mark prototype with ATTRIBUTE_NORETURN. (do_abort, botch): Add prototypes. Sat Sep 6 12:05:18 1998 John Carr * final.c (final): If a label is reached only from a single jump, call NOTICE_UPDATE_CC on the jump and its predecessor before emitting the insn after the label. * i386.h: Add AMD K6 support. Change TARGET_* macros to use table lookup. (INITIALIZE_TRAMPOLINE): Improve trampoline code. (ADJUST_COST): Change definition to call function in i386.c. (ISSUE_RATE): Define as 2 for anything newer than an 80486. * i386.c: Add AMD K6 support. Add constants for feature tests used by TARGET_* macros. (split_di): If before reload, call gen_lowpart and gen_highpart. (x86_adjust_cost): New function. (put_jump_code): New function. (print_operand): New codes 'D' and 'd'. * i386.md: New insn types. New insn attribute "memory". Redefine scheduling parameters to use new types and add AMD K6 support. Explicitly set type of most insns. (move insns): K6 prefers movl $0,reg to xorl reg,reg. Pentium Pro and K6 prefer movl $1,reg to incl reg. (adddi3, subdi3): Set cc_status. (DImode shift patterns): Change label counters from HOST_WIDE_INT to int; x86 can't have more than 2^31 DImode shifts per file. (setcc): Combine all setcc patterns. Allow writing memory. Combine all jump patterns using match_operator. (*bzero): Name pattern. Emit multiple stos instructions when that is faster than rep stos. (xordi3, anddi3, iordi3): Simplify DImode logical patterns and add define_split. Sun Sep 6 11:17:20 1998 Dave Love * config/m68k/x-next (BOOT_LDFLAGS): Define suitably for f771 linking. Sat Sep 5 22:05:25 1998 Richard Henderson * alpha.c (alpha_ra_ever_killed): Inspect the topmost sequence, not whatever we're generating now. * alpha.c (set_frame_related_p, FRP): New. (alpha_expand_prologue): Mark frame related insns. (alpha_expand_epilogue): Likewise, but with a null FRP. * alpha.h (INCOMING_RETURN_ADDR_RTX): New. * alpha.md (exception_receiver): New. * alpha/crtbegin.asm (.eh_frame): New beginning. (__do_frame_setup, __do_frame_takedown): New. * alpha/crtend.asm (.eh_frame): New ending. * alpha/elf.h (DWARF2_DEBUGGING_INFO): Define. (ASM_SPEC): Don't emit both dwarf2 and mdebug. (ASM_FILE_START): Don't emit .file for dwarf2. * rtl.h (enum reg_note): Add REG_FRAME_RELATED_EXPR. * rtl.c (reg_note_name): Likewise. * rtl.texi (REG_NOTES): Likewise. * dwarf2out.c (dwarf2out_frame_debug): Use it. Recognize a store without an offset. Sat Sep 5 14:47:17 1998 Richard Henderson * i386.h (PREFERRED_RELOAD_CLASS): Standard fp constants load to TOS. * i386.md (movsf, movdf, movxf): Validate memory address returned from force_const_mem. Kill useless REG_EQUAL setting code. Sat Sep 5 14:23:31 1998 Torbjorn Granlund * m68k.md (zero_extendsidi2): Fix typo. Sat Sep 5 13:40:24 1998 Krister Walfridsson * configure.in: Removed references to the removed file. * config/xm-netbsd.h: Use ${cpu_type}/xm-netbsd.h for arm*-*-netbsd* and ns32k-*-netbsd*. * config/i386/xm-netbsd.h: Removed unnecessary file. * config/m68k/xm-netbsd.h: Likewise. * config/sparc/xm-netbsd.h: Likewise. * config/mips/xm-netbsd.h: Likewise. Sat Aug 29 13:32:58 1998 Mumit Khan * i386/cygwin32.h (BIGGEST_ALIGNMENT): Define. (PCC_BITFIELD_TYPE_MATTERS): Define to be 0. * i386/cygwin32.h (ASM_OUTPUT_SECTION_NAME): Don't check for for exact section attributions. * i386/mingw32.h (CPP_PREDEFINES): Add __MSVCRT__ for msvc runtime. * i386/crtdll.h (CPP_PREDEFINES): Define. Sat Sep 5 03:23:05 1998 Jeffrey A Law (law@cygnus.com) * m68k.md (5200 movqi): Do not allow byte sized memory references using address regs. * m68k.c (output_move_qimode): Do not use byte sized operations on address registers. * Makefile.in (pexecute.o): Use pexecute.c from libiberty. Provide explicit rules for building. Similarly for alloca, vfprintf, choose-temp and mkstemp, getopt, getopt1, and obstack. (INCLUDES): Add $(srcdir)/../include. * pexecute.c, alloca.c, vfprintf.c, choose-temp.c, mkstemp.c: Delete. * getopt.h, getopt.c getopt1.c, obstack.c, obstack.h: Likewise. Fri Sep 4 11:57:50 1998 Tom Tromey * gcc.c (do_spec_1): [case 'o'] Account for lang_specific_extra_outfiles. (main): Correctly clear all slots in outfiles for lang_specific_extra_outfiles. Set input_file_number before calling lang_specific_pre_link. Fri Sep 4 10:37:07 1998 Jim Wilson * loop.c (load_mems): Fix JUMP_LABEL field after for_each_rtx call. Fri Sep 4 02:01:05 1998 David S. Miller * config/sparc/sparc.c (output_double_int): In all V9 symbolic cases, use xword. (sparc_output_deferred_case_vectors): If no work to do, return. Fix thinko in Sept 1 change. 1998-09-03 SL Baur * Makefile.in: Add semicolon in BISON definition for portability. Thu Sep 3 13:34:41 1998 Toon Moene * config/nextstep.c (handle_pragma): Correct name of third argument. Tue Sep 1 11:30:33 1998 Nick Clifton * config/m32r/m32r.md: Change (reg:CC 17) to (reg:SI 17). * config/m32r/m32r.h: Make register 17 be fixed. * config/m32r/m32r.c: Use SImode for cc operations. Thu Sep 3 18:17:34 1998 Benjamin Kosnik * invoke.texi (Warning Options): Add -Wnon-template-friend documentation. Thu Sep 3 18:16:16 1998 Michael Meissner * rs6000.c (rs6000_override_options): Add -mcpu={401,e603e}. Thu Sep 3 18:05:16 1998 David Edelsohn * rs6000.md (movsf): Disable explicit secondary-reload-like functionality if TARGET_POWERPC64. (movdf): Remove TARGET_POWERPC64 explicit secondary-reload-like functionality. Thu Sep 3 11:41:40 1998 Robert Lipe * fixinc.sco: Borrow code to wrap 'bool' typedefs from tinfo.h and term.h from fixinc.wrap. Thu Sep 3 09:47:31 1998 Kaveh R. Ghazi * aclocal.m4 (GCC_HEADER_STRING): New macro to detect if it is safe to include both string.h and strings.h together. (GCC_NEED_DECLARATION): Test STRING_WITH_STRINGS when deciding which headers to search for function declarations. Continue to prefer string.h over strings.h when both are not acceptable. * acconfig.h (STRING_WITH_STRINGS): Add stub. * configure.in: Call GCC_HEADER_STRING. * system.h: Test STRING_WITH_STRINGS when deciding which headers to include. Continue to prefer string.h over strings.h when both are not acceptable. Wed Sep 2 23:56:29 1998 David S. Miller * config/sparc/sparc.c (output_double_int): If V9 and MEDLOW, do not assume top 32-bits of symbolic addresses are zero if flag_pic. Thu Sep 3 00:23:21 1998 Richard Henderson * ginclude/va-alpha.h: Protect entire second portion of the file against double inclusion. Thu Sep 3 00:37:55 1998 Ovidiu Predescu Added support for the Boehm's garbage collector. * configure.in: Handle --enable-objc-gc. * configure: Rebuilt. * Makefile.in (CHECK_TARGETS): Add check-objc. (check-objc): New rule. * objc/Make-lang.in: Build a different Objective-C library that runs with the Boehm's collector. * objc/encoding.c (objc_round_acc_size_for_types): New function. * objc/encoding.c: Correctly compute the size of compound types in the presence of bitfields. Skip the variable name of the type if any. Added support for long long. * objc/encoding.h (_C_GCINVISIBLE): New specifier. (_F_GCINVISIBLE): New mask. * objc/gc.c: New file. Compute the type memory mask associated with a class based on the runtime information. * objc/misc.c: Added the hooks that use the Boehm's collector allocation functions. * objc/objc-act.c (build_class_template): Generate a new class member (gc_object_type) to hold the class' type memory mask. (build_shared_structure_initializer): Initialize the new member to NULL. (encode_complete_bitfield): New function. Generate the new encoding. (encode_field_decl): Generate the new encoding only for the GNU runtime. * objc/objc-api.h (_C_LNG_LNG, _C_ULNG_LNG): New specifiers for the long long types. (class_get_gc_object_type): New function to mark a pointer instance variable as a weak pointer. * objc/objc-features.texi: New file. * objc/objc.h (gc_object_type): New class member. * objc/objects.c (class_create_instance): Create a typed memory object when compiled with Boehm's collector support. * objc/sendmsg.c (__objc_init_install_dtable): Call __objc_send_initialize instead of setting the initialize flag. (__objc_send_initialize): Call __objc_generate_gc_type_description to generate the class type memory mask. Rewrite the code that sends the +initialize so that it is called only once (bug report and fix from Ronald Pijnacker ). * testsuite/objc: New testsuite for Objective-C type encoding. * testsuite/lib/objc-torture.exp: New file. * testsuite/lib/objc.exp: New file. Wed Sep 2 14:47:36 1998 Jim Wilson * jump.c (jump_optimize): In if/then/else transformations, add another call to modified_between_p for the jump insn. Wed Sep 2 14:16:49 1998 Jeffrey A Law (law@cygnus.com) * fix-header.c (symlink): Treat like readlink. Wed Sep 2 19:30:06 1998 J"orn Rennecke * dwarfout.c (fundamental_type_code): Encode 32 bit floats/doubles as FT_float. Wed Sep 2 10:06:07 1998 Nick Clifton * config/nextstep.h: Update HANDLE_PRAGMA macro. * config/h8300/h8300.h: Update HANDLE_PRAGMA macro. * config/i960/i960.h: Update HANDLE_PRAGMA macro. * config/nextstep.c (handle_pragma): Take three arguments, as per the new HANDLE_PRAGMA macro specification. * config/h8300/h8300.c (handle_pragma): Take three arguments, as per the new HANDLE_PRAGMA macro specification. * config/i960/i960.c (process_pragma): Take three arguments, as per the new HANDLE_PRAGMA macro specification. Wed Sep 2 09:25:29 1998 Nick Clifton * c-lex.c (check_newline): Call HANDLE_PRAGMA before HANDLE_SYSV_PRAGMA if both are defined. Generate warning messages if unknown pragmas are encountered. (handle_sysv_pragma): Interpret return code from handle_pragma_token (). Return success/failure indication rather than next unprocessed character. (pragma_getc): New function: retrieves characters from the input stream. Defined when HANDLE_PRAGMA is enabled. (pragma_ungetc): New function: replaces characters back into the input stream. Defined when HANDLE_PRAGMA is enabled. * c-pragma.c (handle_pragma_token): Return success/failure status of the parse. * c-pragma.h: Change prototype of handle_pragma_token(). * varasm.c (handle_pragma_weak): Only create this function if HANDLE_PRAGMA_WEAK is defined. * c-common,c (decl_attributes): If defined call the expression contained within the INSERT_ATTRIBUTES macro before adding attributes to a decl. * tm.texi (HANDLE_PRAGMA): Document the new version of HANDLE_PRAGMA, which takes three arguments. (INSERT_ATTRIBUTES): Document this new macro. * LANGUAGES: Document the new version of HANDLE_PRAGMA and the new INSERT_ATTRIBUTES macro. Wed Sep 2 02:03:23 1998 David S. Miller * config/sparc/sparc.md (movdf): Only generate special RTL for LABEL_REFs when PIC. (move_label_di): Remove. (movdi_pic_label_ref, movdi_high_pic_label_ref, movdi_lo_sum_pic_label_ref): New patterns for 64-bit label references when PIC. * config/sparc/sparc.h (ASM_OUTPUT_ADDR_VEC_ELT, ASM_OUTPUT_ADDR_DIFF_ELT): Don't do anything special for MEDLOW, output an .xword for all 64-bit cases. Tue Sep 1 15:55:17 1998 David S. Miller * config/sparc/sparc.c (finalize_pic): Don't output arbitrary alignment, use FUNCTION_BOUNDARY instead. (sparc_output_deferred_case_vectors): Likewise. Mon Aug 31 17:25:41 1998 David S. Miller * config/sparc/sparc.md (movsf_const_intreg): Kill warning. (movtf_insn_sp64, movtf_no_e_insn_sp64): Reorder alternatives. Mon Aug 31 13:57:55 1998 Richard Henderson * alpha/va_list.h: New file. * alpha/x-alpha (EXTRA_HEADERS): New. Add va_list.h. Mon Aug 31 14:55:02 1998 Jeffrey A Law (law@cygnus.com) * NEWS: Add SCO Openserver and Unixware 7 notes. * NEWS: Fix typos. Mon Aug 31 15:42:18 1998 Dave Brolley * varasm.c (compare_constant_1): Handle RANGE_EXPR. (record_constant_1): Handle RANGE_EXPR. Mon Aug 31 10:54:03 1998 Richard Henderson * print-rtl.c (print_rtx): NOTE_INSN_LIVE has an rtx not a bitmap. * haifa-sched.c (sched_analyze): Handle NOTE_INSN_RANGE_START and NOTE_INSN_RANGE_END specially. (reemit_notes): Likewise. Mon Aug 31 10:18:52 1998 Kaveh R. Ghazi * sparc.c (TMASK, UMASK): Use `(unsigned)1' not `1U'. (ultrasparc_sched_init): Remove unneeded &. Mon Aug 31 10:47:16 1998 Andreas Schwab * config/m68k/m68k.h (TARGET_SWITCHES): Don't remove MASK_68040 for m68020-60, to prevent the use of fintrz. Sun Aug 30 22:17:20 1998 Mark Mitchell * configure.in: If the native compiler is GCC use $(WARN_CFLAGS) even in stage1. * Makefile.in: Likewise. * configure: Regenerated. Sun Aug 30 22:15:41 1998 H.J. Lu (hjl@gnu.org) * configure.in (gxx_include_dir): Changed to '${prefix}/include/g++'-${libstdcxx_interface}. * configure: Rebuilt. Sun Aug 30 20:19:43 1998 Hans-Peter Nilsson * expr.c (expand_expr): Change ">" to ">=" making MOVE_RATIO use consistent. * tm.texi (Costs): Say MOVE_RATIO is number of mem-mem move *sequences* *below* which scalar moves will be used. Sun Aug 30 17:18:43 1998 Jeffrey A Law (law@cygnus.com) * collect2.c (mktemp): Delete unused declaration. * config/xm-netbsd.h: Remove unnecessary file. * config/*/xm-netbsd.h: Do not include the generic xm-netbsd.h file anymore, it is not needed. Sun Aug 30 16:05:45 1998 Mark Mitchell * convert.c (convert_to_integer): Issue an error on conversions to incomplete types. Sun Aug 30 16:47:20 1998 Martin von Lvwis * Makefile.in: Add lang_tree_files and gencheck.h. * configure.in: Generate them. * gencheck.c: Include gencheck.h. Sat Aug 29 21:38:24 1998 David S. Miller * config/sparc/sparc.md (pic_lo_sum_di, pic_sethi_di): Rename to movdi_lo_sum_pic and movdi_high_pic and make visible. * config/sparc/sparc.c (legitimize_pic_address): For -fPIC, emit these when Pmode is not SImode. * config/sparc/linux64.h (SPARC_DEFAULT_CMODEL): Make CM_MEDLOW. Sat Aug 29 14:59:32 1998 Mumit Khan * i386/cygwin32.h (ASM_OUTPUT_SECTION_NAME): Don't emit .linkonce directive after the first time. Sat Aug 29 12:39:56 1998 Jeffrey A Law (law@cygnus.com) * m68k.md (beq0_di): Generate correct (and more efficient) code when the clobbered operand overlaps with an input. (bne0_di): Similarly. * Makefile.in (INSTALL): Remove "--no-header" argument. * NEWS: Various updates. Fri Aug 28 19:00:44 1998 David S. Miller * config/sparc/sparc.c (arith_operand, const64_operand, const64_high_operand, arith_double_4096_operand): Mark mode as unused. (create_simple_focus_bits): Remove unused arg highest_bit_set, all callers changed. (sparc_emit_set_const64): Remove unused variable i. (sparc_splitdi_legitimate): Likewise for addr_part. (ultra_code_from_mask): Likewise for mask. (ultra_cmove_results_ready_p): Fixup entry modulo calc. and reverse return values so it matches usage and comments. (ultra_flush_pipeline): Likewise. (ultra_fpmode_conflict_exists): Likewise, remove unused variable this_type, and allow loads and stores of differing FP modes as they do not create a conflict. (ultra_find_type): Initialize fpmode to SFmode, fix parenthesization thinkos in large conditional. (ultrasparc_sched_init): Mark dump and sched_verbose as unused. Init free_slot_mask after ultra_cur_hist is reset, not before. (ultrasparc_rescan_pipeline_state): Remove unused variable ucode. (ultrasparc_sched_reorder): Don't bzero current pipeline state, use ultra_flush_pipeline instead, then re-init group pointer. Fix statement with no effect. If no progress made in, and no instructions scheduled at all, advance to new pipeline cycle else we get into an endless loop. (ultrasparc_adjust_cost): Remove previous arg. * config/sparc/sparc.h (ADJUST_COST): Update to reflect that. Fri Aug 28 13:52:35 1998 Jim Wilson * sparc.md (DImode, DFmode, TFmode splits): Delete self_reference code. Use reg_overlap_mentioned_p to detect when source and destination overlap. (negtf2_notv9+1): Use DFmode instead of SFmode in last two operands. 1998-08-28 Brendan Kehoe * loop.c (check_dbra_loop): Pass COMPARISON_VALUE, not COMPARISON_VAL, into invariant_p. Fri Aug 28 15:13:25 1998 J"orn Rennecke * regmove.c (regclass_compatible_p): New function. (regmove_optimize): Use it. Use NREGS parameter instead of calling max_reg_num. (fixup_match_1): Don't use code = MINUS when later tieing with a hard register is likely. Fri Aug 28 14:54:07 1998 J"orn Rennecke * loop.c (check_dbra_loop): Fix calculation of FINAL_VALUE when COMPARISON_VAL was normalized. Thu Aug 27 20:10:46 1998 Jeffrey A Law (law@cygnus.com) * loop.c (check_dbra_loop): The loop ending comparison value must be an invariant or we can not reverse the loop. * loop.c (scan_loop): Count down from max_reg_num - 1 to FIRST_PSEUDO_REGISTER to avoid calling max_reg_num each iteration of the loop. (load_mems_and_recount_loop_regs_set): Likewise. * i386.c (print_operand): Remove obsolete 'c' docs. Wed Aug 26 17:13:37 1998 Tom Tromey * gthr.h: Document __GTHREAD_MUTEX_INIT_FUNCTION. * frame.c (init_object_mutex): New function. (init_object_mutex_once): Likewise. (find_fde): Call it. (__register_frame_info): Likewise. (__register_frame_info_table): Likewise. (__deregister_frame_info): Likewise. Thu Aug 27 15:14:18 1998 Jeffrey A Law (law@cygnus.com) * haifa-sched.c (sched_analyze_insn): Fix thinko in last change. Thu Aug 27 16:34:51 1998 J"orn Rennecke * loop.c (check_dbra_loop): Enable code for reversal of some loops without a known constant loop end. Wed Aug 26 18:38:15 1998 Richard Henderson * haifa-sched.c (last_clock_var): New. (schedule_block): Initialize it. (schedule_insn): Use it to fill insn modes with issue information. * alpha.c (alpha_handle_trap_shadows): Remove do-nothing exit. Tag trapb and next insn with TImode. (alphaev5_insn_pipe, alphaev5_next_group, alphaev5_align_insns): New. (alpha_reorg): Add conditional for alpha_handle_trap_shadows. Invoke alphaev5_align_insns as appropriate. * alpha.h (LABEL_ALIGN_AFTER_BARRIER): Was ALIGN_LABEL_AFTER_BARRIER. (MD_SCHED_VARIABLE_ISSUE): New. * alpha.md (attr type): Add multi. (define_asm_attributes): New. (prologue_stack_probe_loop, builtin_setjmp_receiver): Set type multi. (arg_home): Likewise. (fnop, unop, realign): New. Wed Aug 26 15:55:41 1998 Jim Wilson * iris5.h (PREFERRED_DEBUGGING_TYPE): Undef. * iris5gas.h (PREFERRED_DEBUGGING_TYPE): Define. * configure.in (powerpc-ibm-aix4.[12]*): Change from 4.[12].*. (rs6000-ibm-aix4.[12]*): Likewise. * configure: Regenerate. Wed Aug 26 09:30:59 1998 Nick Clifton * config/arm/thumb.c (thumb_exit): Do not move a4 into lr if it already contains the return address. Wed Aug 26 12:57:09 1998 Jeffrey A Law (law@cygnus.com) * calls.c (expand_call): Use bitfield instructions to extract/deposit word sized hunks when loading unaligned args into registers. * haifa-sched.c (sched_analyze_insn): Only create scheduling barriers for LOOP, EH and SETJMP notes on the loop_notes list. * mn10300.h (RTX_COSTS): Handle UDIV and UMOD too. Wed Aug 26 16:35:37 1998 J"orn Rennecke * loop.c (check_dbra_loop): Add some code that would allow reversal of some loops without a known constant loop end if it were enabled. Wed Aug 26 11:08:44 1998 Gavin Romig-Koch * mips.md (lshrsi3_internal2+2): Fix type-o. Wed Aug 26 10:53:03 1998 Kaveh R. Ghazi * system.h: Include stdarg.h/varargs.h, make sure they are ordered correctly with regards to stdio.h. * calls.c: Remove stdarg.h/varargs.h. * cccp.c: Likewise. * cexp.y: Likewise. * combine.c: Likewise. * cpperror.c: Likewise. * cpplib.c: Likewise. * cpplib.h: Likewise. * doprint.c: Likewise. * emit-rtl.c: Likewise. * final.c: Likewise. * fix-header.c: Likewise. * gcc.c: Likewise. * genattr.c: Likewise. * genattrtab.c: Likewise. * gencodes.c: Likewise. * genconfig.c: Likewise. * genemit.c: Likewise. * genextract.c: Likewise. * genflags.c: Likewise. * genopinit.c: Likewise. * genoutput.c: Likewise. * genpeep.c: Likewise. * genrecog.c: Likewise. * mips-tfile.c: Likewise. * prefix.c: Likewise. * protoize.c: Likewise. * regmove.c: Likewise. * toplev.c: Likewise. * tree.c: Likewise. Wed Aug 26 05:09:27 1998 Jakub Jelinek * config/sparc/sparc.c (sparc_override_options): If not TARGET_FPU, turn off TARGET_VIS. * config/sparc/sparc.h (TARGET_SWITCHES): Add no-vis. (LEGITIMATE_CONSTANT_P): Allow SF/DF mode zero when TARGET_VIS. * config/sparc/sparc.md (movsi_insn): Use fzeros not fzero. (movdi_insn_sp64): Add VIS fzero alternative. (clear_sf, clear_df): New VIS patterns. (movsf, movdf expanders): Allow fp_zero_operand flat out when TARGET_VIS. (one_cmpldi2_sp64): Provide new fnot1 VIS alternative. Tue Aug 25 10:57:41 1998 Mark Mitchell * loop.c (n_times_set, n_times_used, may_not_optimize, reg_single_usage): Convert to varrays. All uses changed. (insert_loop_mem): Return a value. (scan_loop): Tweak AVOID_CC_MODE_COPIES code. (load_mems_and_recount_loop_regs_set): Likewise. Grow the arrays, if necessary. Tue Aug 25 23:57:12 1998 Jeffrey A Law (law@cygnus.com) * From Alexandre: * configure.in: Do not set thread_file to "irix" since no such support exists yet. * sparc.md (float abs/neg splits): Check reload_completed before calling alter_subreg. Tue Aug 25 19:17:59 1998 David S. Miller * config/sparc/sparc.c (sparc_absnegfloat_split_legitimate): New function. * config/sparc/sparc.h: Declare it. * config/sparc/sparc.md (float abs/neg splits): Use it. (all other splits): Handle SUBREGs properly where necessary. (unnamed (1< * config/v850/v850.c (movsi_source_operand): Treat CONSTANT_P_RTX as an ordinary operand. Tue Aug 25 12:54:57 1998 Jason Merrill * tree.c (valid_machine_attribute): Don't apply attributes to both decl and type. Tue Aug 25 12:23:20 1998 Richard Henderson * reload.c (operands_match_p): Handle rtvecs. * i386.c (legitimate_pic_address_disp_p): New. (legitimate_address_p): Use it. (legitimize_pic_address): Use unspecs to represent @GOT and @GOTOFF. Handle constant pool symbols just like statics. (emit_pic_move): Use Pmode not SImode for clarity. (output_pic_addr_const) [SYMBOL_REF]: Remove @GOT and @GOTOFF hacks. [UNSPEC]: New, handling what we killed above. [PLUS]: Detect and abort on invalid symbol arithmetic. * i386.h (CONSTANT_ADDRESS_P): Remove HIGH. Tue Aug 25 12:02:23 1998 Mark Mitchell * alias.c: Include output.h. (DIFFERENT_ALIAS_SETS_P): Don't treat alias sets as different if we're in a varargs function. * Makefile.in (alias.o): Depend on output.h Tue Aug 25 19:20:12 1998 J"orn Rennecke * sh.h (GIV_SORT_CRITERION): Delete. Tue Aug 25 13:19:46 1998 Dave Brolley * regclass.c (regclass): Use xmalloc/free instead of alloca. * stupid.c (stupid_life_analysis): Likewise. * reload1.c (reload): Likewise. Tue Aug 25 05:48:18 1998 Jakub Jelinek * config/sparc/sparc.c (arith_4096_operand, arith_add_operand, arith_double_4096_operand, arith_double_add_operand): New predicates. * config/sparc/sparc.h (PREDICATE_CODES): Add them, declare them. * config/sparc/sparc.md (adddi3, addsi3, subdi3, subsi3): Use them to transform add/sub 4096 into add/sub -4096. Mon Aug 24 23:31:03 1998 David S. Miller * loop.c (scan_loop): Allocate some slop to handle pseudos generated by move_movables. (load_mems_and_recount_loop_regs_set): Honor AVOID_CC_MODE_COPIES here too. Mon Aug 24 19:45:40 1998 Jim Wilson * tree.def (DECL_RESULT): Correct documentation. Tue Aug 25 01:15:27 1998 J"orn Rennecke * reload1.c (reload_reg_free_before_p): New argument EQUIV; Changed all callers. Abort for RELOAD_FOR_INSN. RELOAD_FOR_OUTADDR_ADDR: conflicts will all RELOAD_FOR_OUTPUT reloads. * reload1.c (reload_cse_regs_1): When deleting a no-op move that loads the function result, substitute with a USE. Mon Aug 24 15:20:19 1998 David Edelsohn * rs6000.h (GO_IF_LEGITIMATE_ADDRESS): Use TARGET_POWERPC64 when testing LEGITIMATE_INDEXED_ADDRESS_P DFmode and DImode. (LEGITIMIZE_ADDRESS): Use TARGET_POWERPC64 for INDEXED fixup. * rs6000.c (print_operand, case 'L'): Add UNITS_PER_WORD, not 4. (print_operand, cases 'O' and 'T'): Fix typos in lossage strings. * rs6000.md (fix_truncdfsi2_store): Remove %w from non-CONST_INT operand. (movdf_softfloat32, movdf_hardfloat64, movdf_softfloat64): Change 'o' to 'm' for GPR variant constraints. Mon Aug 24 10:25:46 1998 Jeffrey A Law (law@cygnus.com) * loop.c (scan_loop): Honor AVOID_CC_MODE_COPIES. * h8300.h (STRIP_NAME_ENCODING): Fix typo. * sparc.md (TFmode splits): Use reg_overlap_mentioned_p to detect when the source and destination overlap. * stmt.c (emit_case_nodes): Change rtx_function to rtx_fn to avoid clash with global type. Mon Aug 24 00:53:53 1998 Jason Merrill * fixinc.irix: Add curses.h handling from fixinc.wrap. * c-common.c (combine_strings): Also set TREE_READONLY. Change warn_write_strings to flag_const_strings. * c-decl.c, c-tree.h: Likewise. Sun Aug 23 18:39:11 1998 David S. Miller * config/sparc/sparc.c (sparc_emit_set_const32): If outputting a CONST_INT, not a symbolic reference, don't use a HIGH/LO_SUM sequence, use SET/IOR instead so CSE can see it. * config/sparc/sparc.md (movhi_const64_special, movsi_const64_special): New patterns necessitated by that change. (movhi_high): Remove. (movhi_lo_sum): Change to match an IOR. (movdf_insn_sp32): Test TARGET_V9 not TARGET_ARCH64. (movdf_insn_v9only): New pattern for when V9 but not ARCH64. (movdf_insn_sp64): Test both TARGET_V9 and TARGET_ARCH64. (movdf splits): Allow when not V9 or when not ARCH64 and integer registers are involved. (snesi_zero_extend split): Remove reload_completed test. (unnamed plus and minus zero_extend sidi splits): Add it. Sun Aug 23 11:56:08 1998 Mark Mitchell * extend.texi: Remove description of extension to explicit instantiation that is now endorsed by standard C++. Sun Aug 23 09:39:09 1998 David S. Miller * config/arc/arc.c (arc_initialize_pic): Remove. * config/arc/arc.h (INITIALIZE_PIC): Similarly, this routine does nothing on any platform and is invoked by no-one, it does not even appear in the documentation. * config/sparc/sparc.h (INITIALIZE_PIC): Likewise. * config/sparc/sparc.c (initialize_pic): Likewise. (find_addr_reg): Remove this as well, no longer referenced after my rewrite. Sun Aug 23 00:17:14 1998 Jeffrey A Law (law@cygnus.com) * recog.c (validate_replace_rtx_group): New function. * recog.h (validate_replace_rtx_group): Declare it. * regmove.c (optimize_reg_copy_3): If any substitution fails, then undo the entire group of substitutions. Sat Aug 22 23:31:00 1998 Klaus-Georg Adams (Klaus-Georg.Adams@chemie.uni-karlsruhe.de) * loop.c (load_mems): Fix initializers. Fri Aug 21 23:07:46 1998 David S. Miller * config/sparc/sparc.md (TFmode splits): Handle destination registers being referenced in the address correctly. * expmed.c (make_tree) [CONST_INT]: Sign extend even if TREE_UNSIGNED, when bitsize of type's mode is larger than HOST_BITS_PER_WIDE_INT. Fri Aug 21 19:31:31 1998 Alexandre Petit-Bianco * tree.def (LABELED_BLOCK_EXPR, EXIT_BLOCK_EXPR): New tree nodes. * tree.h (LABELED_BLOCK_LABEL, LABELED_BLOCK_BODY, EXIT_BLOCK_LABELED_BLOCK, EXIT_BLOCK_RETURN, LOOP_EXPR_BODY): New macros. * expr.c (expand_expr): Handle LABELED_BLOCK_EXPR and EXIT_BLOCK_EXPR. Thu Aug 20 19:43:44 1998 Jeffrey A Law (law@cygnus.com) * h8300.c (h8300_encode_label): Use '&' for tiny data items. * h8300.h (TINY_DATA_NAME_P): Likewise. (STRIP_NAME_ENCODING): Handle '&'. * mn10200.h (REG_OK_FOR_INDEX_P): Do not check the mode of the register (it could be accessed via an outer SUBREG). (REG_OK_FOR_BASE_P): Likewise. (GO_IF_LEGITIMATE_ADDRESS): Consistently use REGNO_OK_FOR_BASE_P. * remove.c (optimize_reg_copy_3): Abort instead of silently generating bogus rtl. * jump.c (rtx_renumbered_equal_p): Do not consider PLUS commutative. Thu Aug 20 17:35:20 1998 David S. Miller * config/sparc/sparc.md (movtf_insn_sp32): All memory operands must be offsettable so the splits can be made. Thu Aug 20 13:56:53 1998 Michael Meissner * config/i386/winnt.c: Include system.h, not stdio.h to get sys/param.h pulled in before rtl.h in case the system defines MIN and MAX. Thu Aug 20 13:44:20 1998 David Edelsohn * rs6000.md (movqi, movhi): Add CONSTANT_P_RTX. Thu Aug 20 13:15:11 1998 Dave Brolley * stor-layout.c (layout_type): Compute TYPE_SIZE_UNIT correctly for arrays of bits. * cpplib.c (cpp_define): Handle macros with parameters. Wed Aug 19 21:33:19 1998 David Edelsohn * rs6000.c (rs6000_output_load_toc_table): Use ld for 64-bit. (output_toc): Use single TOC slot or llong minimal-toc for DFmode and DImode 64-bit. Use llong for minimal-toc SFmode and SYMBOL_REF / LABEL_REF 64-bit. (output_function_profiler): Use llong for profiler label and ld to load 64-bit label address. Wed Aug 19 17:52:27 1998 Nick Clifton (nickc@cygnus.com) * config/arm/thumb.md (extendqisi2_insn): Cope with REG + OFFSET addressing. Wed Aug 19 14:13:31 1998 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. Wed Aug 19 13:10:30 1998 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. Wed Aug 19 13:06:47 1998 Jason Merrill * collect2.c (extract_init_priority): Use atoi instead of strtoul. Wed Aug 19 13:51:35 1998 Hans-Peter Nilsson * tm.texi (Misc): Fix typo "teh". * tm.texi (PIC): Fix typo "PPIC". * tm.texi (Caller Saves): Say that DEFAULT_CALLER_SAVES has no effect when -O2 and higher. * invoke.texi (Optimize Options): Likewise for -fcaller-saves. 1998-08-19 Michael Hayes * regclass.c: Changed register set documentation to be consistent with GCC behavior. * final.c (final_start_function): Removed redundant test for call_fixed_regs. Wed Aug 19 13:28:41 1998 Mark Mitchell * rtl.h (rtx_function): New type. (for_each_rtx): New function. * rtlanal.c (for_each_rtx): Define it. * recog.c (change_t): New type. (change_objects, change_old_codes, change_locs, change_olds): Replace with ... (changes): New variable. (validate_change): Dynamically allocate room for more changes, if necessary. Uses changes array instead of change_objects, etc. (apply_change_group): Use changes array instead of change_objects, etc. * loop.c (loop_mem_info): New type. (loop_mems): New variable. (loop_mems_idx): Likewise. (looop_mems_allocated): Likewise. (scan_loop): Remove nregs parameter. (next_insn_in_loop): New function. (load_mems_and_recount_loop_regs_set): Likewise. (load_mems): Likewise. (insert_loop_mem): Likewise. (replace_loop_mem): Likewise. (replace_label): Likewise. (INSN_IN_RANGE_P): New macro. (loop_optimize): Don't pass max_reg_num() to scan_loop. (scan_loop): Remove nregs parameter, compute it after any new registers are created by load_mems. Use INSN_IN_RANGE_P and next_insn_in_loop rather than expanding them inline. Call load_mems to load memory into pseudos, if appropriate. (prescan_loop): Figure out whether or not there are jumps from the loop to targets other than the label immediately following the loop. Call insert_loop_mem to notice all the MEMs used in the loop, if it could be safe to pull MEMs into REGs for the duration of the loop. (strength_reduce): Use next_insn_in_loop. Tweak comments. Wed Aug 19 08:29:44 1998 Richard Earnshaw (rearnsha@arm.com) * arm.c (arm_override_options): Remove lie about ignoring PIC flag. Wed Aug 19 07:08:15 1998 David S. Miller * config/sparc/sparc.c (finalize_pic): Check for the correct nonlocal_goto_receiver UNSPEC number. * config/sparc/sparc.md (nonlocal_goto_receiver): Add comment making note of this dependency existing in sparc.c. (negtf2_notv9 split): Give NEG SFmode. (negsf2): Fix insn output string. Tue Aug 18 12:40:27 1998 Richard Henderson * c-common.c (decl_attributes): Issue an error if the argument to alias is not a string. Tue Aug 18 10:33:30 1998 Jeffrey A Law (law@cygnus.com) * haifa-sched.c (sched_analyze): Put all JUMP_INSNs on the last pending memory flush list. * combine.c (can_combine_p): Allow combining insns with REG_RETVAL notes. (try_combine): Allow combining insns with REG_LIBCALL notes. * expr.c (emit_block_move): Do not call memcpy as a libcall instead build up a CALL_EXPR and call it like any other function. (clear_storage): Similarly for memset. * regmove.c (fixup_match_2): Do not call reg_overlap_mentioned_p on notes. * Makefile.in (cplus-dem.o): Provide explicit rules for building cplus-dem.o. * regmove.c (optimize_reg_copy_1): Update REG_N_CALLS_CROSSED and REG_LIVE_LENGTH as successful substitutions are made. Tue Aug 18 07:15:27 1998 Kaveh R. Ghazi * config/sparc/sparc.c (ultra_find_type): Add empty semicolon statement after end of loop label. Tue Aug 18 07:13:27 1998 David S. Miller * config/sparc/sparc.c (ultra_types_avail): New variable. (ultra_build_types_avail): New function to record mask of insn types in ready list at this cycle. (ultrasparc_sched_reorder): Call it. (ultra_find_type): Use it to quicken the search. Also simplif dependency check, don't use rtx_equal_p because we know exactly what we are looking for. Tue Aug 18 03:20:53 1998 Richard Earnshaw (rearnsha@arm.com) * arm.h (SECONDARY_INPUT_RELOAD_CLASS): Return NO_REGS if compiling for architecture v4. Mon Aug 17 21:26:38 1998 David S. Miller * config/sparc/sparc.md (sltu, sgeu): Don't FAIL, call gen_compare_reg. (movsf_const_intreg, movsf_const_high, movsf_const_lo, movdf_const_intreg and helper splits): New patterns to move float constants into integer registers. (negtf2, negdf2, abstf2, absdf2): Rework using new patterns and splits. Mon Aug 17 11:46:19 1998 Jeffrey A Law (law@cygnus.com) * From Graham * tree.c (build_index_type): Copy TYPE_SIZE_UNIT from sizetype to itype. * c-decl.c (finish_enum): Copy TYPE_SIZ_UNIT from enumtype to tem. * rs6000.c (secondary_reload_class): For TARGET_ELF, indicate that a BASE_REGS register is needed as an intermediate when copying a symbolic value into any register class other than BASE_REGS. * expr.c (move_by_pieces): No longer static. Remove prototype. * rtl.h (move_by_pieces): Add extern prototype. * mips.c (expand_block_move): Handle aligned straight line copy by calling move_by_pieces. * expr.c (expand_expr): Allow assignments from TImode PARM_DECLs and VAR_DECLs. Mon Aug 17 10:28:52 1998 Mark Mitchell * stmt.c (expand_end_loop): Tidy. Allow unconditional jumps out of the loop to be treated as part of the exit test. Mon Aug 17 10:06:11 1998 Kaveh R. Ghazi Jeff Law * Makefile.in (cplus-dep.o): Use cplus-dem.c from libiberty. * cplus-dem.c: Delete. * Makefile.in (fold-const.o): Depend on $(RTL_H). * fold-const.c: Include rtl.h to get the prototype for `set_identifier_local_value'. * loop.c (express_from_1): Remove unused variable `tmp'. (combine_givs): Cast the first argument of bzero to char *. * toplev.c (display_help): Remove unused variable `looking_for_start'. * c-decl.c (init_decl_processing): Remove unneeded &. * alpha.h (alpha_initialize_trampoline): Provide prototype. * except.c (set_exception_lang_code, set_exception_version_code): Change parameter from `short' to `int' to avoid using a gcc extension. * except.h (set_exception_lang_code, set_exception_version_code): Likewise for prototypes. * flow.c (count_reg_references): Remove unused variables `regno' and `i'. * gcse.c (hash_scan_insn): Declare parameter `in_libcall_block'. * prefix.c (translate_name): Cast the result of `alloca'. * varray.h (VARRAY_FREE): Reimplement as a `do-while(0)' statement. Mon Aug 17 09:23:42 1998 Andreas Schwab * config/m68k/m68k.c: Include "system.h" instead of . Include "toplev.h". (valid_dbcc_comparison_p): Mark mode argument as unused. (symbolic_operand): Likewise. (legitimize_pic_address): Likewise. (const_uint32_operand): Likewise. (const_sint32_operand): Likewise. * sched.c [!INSN_SCHEDULING]: Define only dummy function schedule_insns and comment out rest of file. * m68k.c (output_move_simode_const): Use subl to move a zero into an address register. (output_move_[hq]imode): Likewise. Mon Aug 17 09:15:47 1998 Jeffrey A Law (law@cygnus.com) * toplev.c (main): Enable -fstrict-aliasing for -O2 and above. * invoke.texi: Corresponding changes. Mon Aug 17 02:03:55 1998 Richard Henderson * regclass.c (allocate_reg_info): Respect MIN when clearing data. Sun Aug 16 17:37:06 1998 David S. Miller * config/sparc/sparc.c (ultra_code_from_mask, ultra_cmove_results_ready_p, ultra_fpmode_conflict_exists, ultra_find_type, ultra_schedule_insn, ultra_flush_pipeline, ultrasparc_sched_init, ultrasparc_variable_issue, ultra_rescan_pipeline_state, ultrasparc_sched_reorder): New functions to describe UltraSPARC pipeline exactly to Haifa. (ultrasparc_adjust_cost): Indicate IMUL type insns have zero cost, as there is nothing the scheduler can do about it. Indicate that REG_DEP_OUTPUT's collide. Fixup formatting. * config/sparc/sparc.h (RTX_COSTS): Fixup integer multiply and divide costs on Ultra for DImode. (MD_SCHED_INIT, MD_SCHED_REORDER, MD_SCHED_VARIABLE_ISSUE): Define. * config/sparc/sparc.md (ieu_unnamed function unit): Rename to ieuN and add call_no_delay_slot to type list. (cti function unit): New unit for branches on UltraSPARC. (subx/addx insns): Set type to misc. (sidi zero/sign extension insns on arch64): Set type to shift. (sign_extendhidi2_insn): Set type to sload. Sun Aug 16 13:52:00 1998 David Edelsohn * rs6000.c (rs6000_stack_info): Use if == 0 for sizes. (output_epilog): Use if != 0 for offset. (rs6000_fatal_bad_address): Prepare for Intl. * rs6000.h (rs6000_fatal_bad_address): Declare. * rs6000.md (movsfcc, movdfcc): Use else if. (elf_high): Use {liu|lis}. (elf_low): Use {cal|la}. Remove %a template from old mnemonics. (movsi): Use rs6000_fatal_bad_address. Sun Aug 16 01:53:21 1998 Richard Henderson * reload.c (find_equiv_reg): Reject equivalences separated by a volatile instruction. Sun Aug 16 00:21:44 1998 Franz Sirl * rs6000/linux.h (CPP_OS_DEFAULT_SPEC): Define. Sat Aug 15 20:51:35 1998 Richard Henderson * alpha.md (movsicc): Fix mode mismatch. Sat Aug 15 20:22:33 1998 H.J. Lu (hjl@gnu.org) * config/alpha/alpha.h (ASM_OUTPUT_MI_THUNK): Handle aggregated return type. * config/alpha/win-nt.h (ASM_OUTPUT_MI_THUNK): Likewise. Sat Aug 15 08:39:49 1998 David S. Miller * config/sparc/sparc.md (movsi_lo_sum_pic_label_reg): Remove write-only modifier from operand 1 constraint. Sat Aug 15 06:28:19 1998 David S. Miller * config/sparc/sparc.c (sparc_emit_set_const64_quick1): If emitting a XOR of -1 at the end, emit a NOT instead for combine's sake. (sparc_emit_set_const64): Likewise, also when computing trailing bits do not negate low_bits and make fast_int an int. Fri Aug 14 21:07:03 1998 Jeffrey A Law (law@cygnus.com) * loop.c (add_label_notes): Do not ignore references to labels before dispatch tables. Mirrors Apr 8 change to mark_jump_label. * gcse.c (add_label_notes): Similarly. * pa.h (ASM_OUTPUT_MI_THUNK): Strip name encoding. * m68k.md (adddi_dilshr32): One of the operands must be a register. (adddi_dishl32): Similarly. Fri Aug 14 14:12:59 1998 Jason Merrill * i386.h (MODES_TIEABLE_P): Reorganize to shut up warnings. * alias.c (memrefs_conflict_p): Add braces to shut up warnings. * cse.c (cse_basic_block): Add parens to shut up warnings. Fri Aug 14 12:58:21 1998 David S. Miller * config/sparc/sparc.c (sparc_emit_set_const64_quick2, sparc_emit_set_const64_longway, const64_is_2insns, create_simple_focus_bits, sparc_emit_set_const64): Fix more bugs in 64-bit constant formation. * config/sparc/sparc.md (snesi_zero_extend split): Generate rtl for addx not subx. (define_insn movdi_const64_special): Make available even when HOST_BITS_PER_WIDE_INT is not 64. (movdi_lo_sum_sp64_cint, movdi_high_sp64_cint): Remove. (losum_di_medlow, sethm, setlo): Make op2 symbolic_operand. (cmp_siqi_trunc_set, cmp_diqi_trunc_set): Encapsulate both instances of operand 1 inside a QI subreg. (xordi3_sp64_dbl): Remove '%' constraint for op1. (one_cmpldi2_sp64): Fix output string. (one_cmplsi2_not_liveg0): Rewrite to remove unneeded extra alternative case. (unnamed arch64 ashift DI): Truncate shift count if greater than 63, not 31. Fri Aug 14 21:52:53 1998 J"orn Rennecke * expr.c (store_expr): Don't optimize away load-store pair when either source or destination have a side effect. Fri Aug 14 16:50:10 1998 John Carr * genrecog.c (add_to_sequence): Fatal error if the modes of the operands of SET are incompatible. * alpha.md: Fix max and min patterns so modes of SET operands match. Fri Aug 14 12:22:55 1998 Ian Lance Taylor * configure.in: Avoid [[ by using test and changequote. * configure: Rebuild. Fri Aug 14 01:22:31 1998 David S. Miller * rtl.def (CONSTANT_P_RTX): Fix typo in string name. * config/sparc/sparc.md (seqdi_special_trunc, snedi_special_trunc, seqsi_special_extend, snesi_special_extend, snesi_zero_extend and split, snedi_zero_trunc and split, seqsi_zero_extend and split, seqdi_zero_trunc and split, pic_lo_sum_di, pic_sethi_di, movdi_cc_sp64_trunc, movdi_cc_reg_sp64_trunc, addx_extend_sp32 and split, addx_extend_sp64, subx_extend_sp64, subx_extend and split): Fix mismatching modes in SET operands. (conditional move patterns): Fix formatting. (unnamed subx arch64 pattern): Remove duplicate insn. Fri Aug 14 00:34:34 1998 David S. Miller * config/sparc/sparc.c (const64_operand, const64_high_operand): Get it right when HOST_BITS_PER_WIDE_INT is not 64. (input_operand): Fixup test for what we accept for constant integers. (sparc_emit_set_const32, sparc_emit_set_symbolic_const64): Give set VOIDmode. (safe_constDI): Remove. (sparc_emit_set_safe_HIGH64, gen_safe_SET64, gen_safe_OR64, gen_safe_XOR64): New functions. (sparc_emit_set_const64_quick1, sparc_emit_set_const64_quick2, sparc_emit_set_const64_longway, sparc_emit_set_const64): Use them. * config/sparc/sparc.md (define_insn xordi3_sp64_dbl): Only make available when HOST_BITS_PER_WIDE_INT is not 64. (define_insn movdi_sp64_dbl, movdi_const64_special): Likewise and move before movdi_insn_sp64 pattern. (define_insn movdi_lo_sum_sp64_dbl, movdi_high_sp64_dbl): Remove. (define_insn sethi_di_medlow, seth44, setm44, sethh): Use symbolic_operand as predicate for second operand. (DImode minus split on arch32, negsi2 expander, one_cmplsi2 expander): Give set VOIDmode. Fri Aug 14 01:45:06 1998 Mumit Khan * i386/cygwin32 (DEFAULT_PCC_STRUCT_RETURN): Define. Fri Aug 14 01:40:21 1998 Geoffrey Keating * rs6000/linux.h (LINK_SPEC): Pass -G args to the linker. Fri Aug 14 01:23:23 1998 Richard Earnshaw (rearnsha@arm.com) * arm/netbsd.h (TARGET_DEFAULT): Default includes software floating point. (CPP_FLOAT_DEFAULT_SPEC): Re-define accordingly. Fri Aug 14 01:19:08 1998 Robert Lipe * install.texi: Various SCO OpenServer tweaks. Thu Aug 13 20:14:40 1998 Jim Wilson * reload1.c (eliminate_regs_in_insn): Handle another case when eliminating the frame pointer to the hard frame pointer. Add missing ep->to_rtx check to one existing case. * mips/mips.md (movhi_internal2+2): Fix typo mem:SI -> mem:HI. Thu Aug 13 17:08:11 1998 Jason Merrill * tree.h: De-conditionalize init_priority code. * mips.h (NM_FLAGS): Change from -Bp to -Bn. * collect2.c (NM_FLAGS): Change from -p to -n. * configure.in: Turn on collect2 for mipstx39-elf. Handle use_collect2=no properly. * c-common.c: De-conditionalize init_priority code. * collect2.c (extract_init_priority, sort_ids): New fns. (main): Call sort_ids. Move sequence_number to file scope. * configure.in: Handle --enable-init-priority. * c-common.c (attrs): Add A_INIT_PRIORITY. (init_attributes, decl_attributes): Likewise. * tree.h (DEFAULT_INIT_PRIORITY, MAX_INIT_PRIORITY): New macros. * tree.c (get_file_function_name_long): Split out... (get_file_function_name): ...from here. Thu Aug 13 16:09:53 1998 Martin von Loewis * expr.c (safe_from_p): Change code to ERROR_MARK only when not accessing nodes. Thu Aug 13 15:24:48 1998 Jason Merrill * toplev.c (display_help): Add braces to shut up warnings. * tree.c (simple_cst_equal): Likewise. * fold-const.c (non_lvalue): Don't deal with null pointer constants here. (fold, case COMPOUND_EXPR): Wrap a constant 0 in a NOP_EXPR. * c-typeck.c (initializer_constant_valid_p): Allow conversion of 0 of any size to a pointer. Thu Aug 13 12:53:13 1998 Jim Wilson * i386/winnt.c (i386_pe_asm_file_end): Check TREE_SYMBOL_REFERENCED. Wed Aug 12 17:25:18 1998 Jeffrey A Law (law@cygnus.com) * mn10300.c (REG_SAVE_BYTES): Only reserve space for registers which will be saved. * mn10300.md (prologue insn): Only save registers which need saving. (epilogue insn): Similarly. * mn10300.c, mn10300.h, mn10300.md: Remove "global zero register" optimizations. Wed Aug 12 12:39:16 1998 Gavin Romig-Koch * mips/mips.h (ENCODE_SECTION_INFO): Set SYMBOL_REF_FLAG for VAR_DECL's in gp addressable sections. Tue Aug 11 23:02:31 1998 John Carr * sparc.c: Change return to ; return; in functions returning void. * sparc.md: Add empty semicolon statement after final label in move expanders. Tue Aug 11 22:42:01 1998 David S. Miller * config/sparc/sparc.md (define_insn addx_extend): Rename to addx_extend_sp64, only allow when TARGET_ARCH64. (define_insn addx_extend_sp32 and split): Version that works when not TARGET_ARCH64. (define_insn subx_extend): Likewise. (define_split adddi3 and subdi3 with zero extension): Fixup and correct bugs when not TARGET_ARCH64. Tue Aug 11 16:04:34 1998 John Carr * except.c (set_exception_lang_code, set_exception_version_code): Use prototype-style definition if __STDC__, to match declaration in except.h. * genemit.c: Change FAIL and DONE macros not to use loops. Tue Aug 11 12:27:03 1998 Jim Wilson * dwarf2out.c (ASM_OUTPUT_DWARF_ADDR_CONST): Use ASM_OUTPUT_DWARF2_ADDR_CONST if defined. * mips/mips.md (reload_outsi): Use M16_REG_P when TARGET_MIPS16. Tue Aug 11 18:12:53 1998 Dave Love * README.g77: Update from Craig. Tue Aug 11 04:46:01 1998 David S. Miller * config/sparc/sparc.c (sparc_emit_set_const32): INTVAL is of type HOST_WIDE_INT. (safe_constDI sparc_emit_set_const64_quick1, sparc_emit_set_const64_quick2, sparc_emit_set_const64_longway, analyze_64bit_constant, const64_is_2insns, create_simple_focus_bits): Fix some bugs when compiled on real 64-bit hosts. (function_arg_record_value_3, function_arg_record_value_2, function_arg_record_value): Add fully prototyped forward decls. * config/sparc/sparc.md (define_insn cmpsi_insn_sp32): Rename back to cmpsi_insn and use on both 64 and 32 bit targets. (define_insn cmpsi_insn_sp64): Remove. (define_expand zero_extendsidi2): Allow for 32-bit target too. (define_insn zero_extendsidi2_insn): Rename to zero_extendsidi2_insn_sp64. (define_insn zero_extendsidi2_insn_sp32): New pattern and associated forced split for it. * config/sparc/sparc.c (const64_operand, const64_high_operand): New predicates. * config/sparc/sparc.h: Declare them. (PREDICATE_CODES): Add them. * config/sparc/sparc.md (movdi_lo_sum_sp64_dbl, movdi_high_sp64_dbl, xordi3_sp64_dbl): Use them. Mon Aug 10 22:57:24 1998 John Carr * config/sparc/sparc.md (define_insn jump): Output ba,pt not b,pt in v9 case as the latter makes the Solaris assembler crash. Mon Aug 10 22:39:09 1998 David S. Miller * config/sparc/sparc.c (input_operand): Do not accept a LO_SUM MEM for TFmode when !v9. We require offsettable memory addresses. * config/sparc/sparc.h (ALTER_HARD_SUBREG): Handle TFmode to DFmode register number conversions. * config/sparc/sparc.md (define_split DFmode moves): If register is a SUBREG do alter_subreg on it before using. (define_expand movtf): Fixup comment about alignment on v9. (define_split TFmode moves): Don't use gen_{high,low}part, create explicit SUBREGs instead. Mon Aug 10 19:02:55 1998 John Carr * Makefile.in (mbchar.o): Depend on mbchar.c. Mon Aug 10 04:28:13 1998 David S. Miller Richard Henderson Rewrite Sparc backend for better code generation and improved sparc64 support. * config/sparc/sp64-elf.h: Set JUMP_TABLES_IN_TEXT_SECTION to zero. * config/sparc/sysv4.h: Likewise. * config/sparc/sparc.c (v8plus_regcmp_p, sparc_operand, move_operand, v8plus_regcmp_op, emit_move_sequence, singlemove_string, doublemove_string, mem_aligned_8, output_move_double, output_move_quad, output_fp_move_double, move_quad_direction, output_fp_move_quad, output_scc_insn): Remove. (small_int_or_double): New predicate. (gen_compare_reg): Remove TARGET_V8PLUS cmpdi_v8plus emission. (legitimize_pic_address): Emit movsi_{high,lo_sum}_pic instead of old pic_{sethi,lo_sum}_si patterns. (mem_min_alignment): New generic function to replace mem_aligned_8, which uses REGNO_POINTER_ALIGN information when available and can test for arbitrary alignments. All callers changed. (save_regs, restore_regs, build_big_number, output_function_prologue, output_cbranch, output_return, sparc_flat_save_restore, sparc_flat_output_function_prologue, sparc_flat_output_function_epilogue): Prettify insn output. (output_function_epilogue): Likewise and add code to output deferred case vectors. (output_v9branch): Likewise, add new arg INSN and use it to tack on branch prediction settings. All callers changed. (print_operand): Likewise and output %l44 for LO_SUMs when TARGET_CM_MEDMID. (sparc_splitdi_legitimate): New function to make sure DImode splits can be run properly when !arch64. (sparc_initialize_trampoline, sparc64_initialize_trampoline): Reformat example code in comments. (set_extends): Remove UNSPEC/v8plus_clear_high case. (sparc_addr_diff_list, sparc_addr_list): New statics to keep track of deferred case vectors we need to output. (sparc_defer_case_vector): Record a case vector. (sparc_output_addr_vec, sparc_output_addr_diff_vec, sparc_output_deferred_case_vectors): New functions to output them. (sparc_emit_set_const32): New function to form 32-bit constants in registers when that requires more than one instruction. (safe_constDI, sparc_emit_set_const64_quick1, sparc_emit_set_const64_quick2, sparc_emit_set_const64_longway, analyze_64bit_constant, const64_is_2insns, create_simple_focus_bits, sparc_emit_set_const64): New functions which do the same for 64-bit constants when arch64. (sparc_emit_set_symbolic_const64): New function to emit address loading for all code models on v9. * config/sparc/sparc.h (CONDITIONAL_REGISTER_USAGE): Do not make %g1 fixed when arch64, unfix %g0 when TARGET_LIVE_G0. (ALTER_HARD_SUBREG): Fix thinko, return REGNO + 1 not 1. (SECONDARY_INPUT_RELOAD_CLASS, SECONDARY_OUTPUT_RELOAD_CLASS): Fix inaccuracies in comments, add symbolic and text_segment operands when TARGET_CM_MEDANY and TARGET_CM_EMBMEDANY respectively. Use GENERAL_REGS in these cases as a temp REG is needed to load these addresses into a register properly. (EXTRA_CONSTRAINT): Document more accurately, remove Q case as it is no longer used. (GO_IF_LEGITIMATE_ADDRESS): Allow TFmode for LO_SUM on v9 since fp quads are guaranteed to have 16-byte alignment. (LEGITIMIZE_ADDRESS): For SYMBOL_REF, CONST, and LABEL_REF use copy_to_suggested_reg instead of explicit LO_SUM and HIGH. (ASM_OUTPUT_ADDR_VEC, ASM_OUTPUT_ADDR_DIFF_VEC): New macros for deferred case vector implementation. (ASM_OUTPUT_ADDR_VEC_ELT): Use fputc to output newline. (ASM_OUTPUT_ADDR_DIFF_ELT): Parenthesize LABEL in macro calls. Generate "internal label - label" instead of "label - 1b". (PRINT_OPERAND_ADDRESS): For LO_SUM use %l44 on TARGET_CM_MEDMID. (PREDICATE_CODES): Remove sparc_operand, move_operand, v8plus_regcmp_op. Add small_int_or_double, input_operand, and zero_operand. (doublemove_string, output_block_move, output_fp_move_double, output_fp_move_quad, output_move_double, output_move_quad, output_scc_insn, singlemove_string, mem_aligned_8, move_operand, sparc_operand, v8plus_regcmp_op, v8plus_regcmp_p): Remove externs. (sparc_emit_set_const32, sparc_emit_set_const64, sparc_emit_set_symbolic_const64, input_operand, zero_operand, mem_min_alignment, small_int_or_double): Add externs. * config/sparc/sparc.md: Document the many uses of UNSPEC and UNSPEC_VOLATILE in this backend. (define_function_unit ieu): Rename to ieu_unnamed. Add move and unary to types which execute in it. (define_function_unit ieu_shift): Rename to ieu0. (define_function_unit ieu1): New, executes compare, call, and uncond_branch type insns. (define_function_units for type fdivs, fdivd, fsqrt): These execute in the fpu multiply unit not the adder on UltraSparc. (define_expand cmpdi): Disallow TARGET_V8PLUS. (define_insn cmpsi_insn): Rename to cmpsi_insn_sp32. (define_insn cmpsi_insn_sp64): New, same as sp32 variant except it allows the arith_double_operand predicate and rHI constraint when TARGET_ARCH64. (define_insn cmpdi_sp64, cmpsf_fpe, cmpdf_fpe, cmptf_fpe, cmpsf_fp, cmpdf_fp, cmptf_fp, sltu_insn, neg_sltu_insn, neg_sltu_minux_x, neg_sltu_plus_x, sgeu_insn, neg_sgeu_insn, sltu_plus_x, sltu_plus_x, sltu_plus_x_plus_y, x_minus_sltu, sgeu_plus_x, x_minus_sgeu, movqi_cc_sp64, movhi_cc_sp64, movsi_cc_sp64, movdi_cc_sp64, movsf_cc_sp64, movdf_cc_sp64, movtf_cc_sp64, movqi_cc_reg_sp64, movhi_cc_reg_sp64, movsi_cc_reg_sp64, movdi_cc_reg_sp64, movsf_cc_reg_sp64, movdf_cc_reg_sp64, movtf_cc_reg_sp64, zero_extendhisi2_insn, cmp_siqi_trunc, cmp_siqi_trunc_set, sign_extendhisi2_insn, sign_extendqihi2_insn, sign_extendqisi2_insn, sign_extendqidi2_insn, sign_extendhidi2_insn, extendsfdf2, extendsftf2, extenddftf2, truncdfsf2, trunctfsf2, trunctfdf2, floatsisf2, floatsidf2, floatsitf2, floatdisf2, floatdidf2, floatditf2, fix_truncsfsi2, fix_truncdfsi2, fix_trunctfsi2, fix_truncsfdi2, fix_truncdfdi2, fix_trunctfdi2, adddi3_sp64, addsi3, cmp_ccx_plus, cmp_cc_plus_set, subdi_sp64, subsi3, cmp_minus_ccx, cmp_minus_ccx_set, mulsi3, muldi3, muldi3_v8plus, cmp_mul_set, mulsidi3, mulsidi3_v8plus, const_mulsidi3_v8plus, mulsidi3_sp32, const_mulsidi3, smulsi3_highpart_v8plus, unnamed subreg mult, const_smulsi3_highpart_v8plus, smulsi3_highpart_sp32, const_smulsi3_highpart, umulsidi3_v8plus, umulsidi3_sp32, const_umulsidi3, const_umulsidi3_v8plus, umulsi3_highpart_v8plus, const_umulsi3_highpart_v8plus, umulsi3_highpart_sp32, const_umulsi3_highpart, divsi3, divdi3, cmp_sdiv_cc_set, udivsi3, udivdi3, cmp_udiv_cc_set, smacsi, smacdi, umacdi, anddi3_sp64, andsi3, and_not_di_sp64, and_not_si, iordi3_sp64, iorsi3, or_not_di_sp64, or_not_si, xordi3_sp64, xorsi3, xor_not_di_sp64, xor_not_si, cmp_cc_arith_op, cmp_ccx_arith_op, cmp_cc_arith_op_set, cmp_ccx_arith_op_set, cmp_ccx_xor_not, cmp_cc_xor_not_set, cmp_ccx_xor_not_set, cmp_cc_arith_op_not, cmp_ccx_arith_op_not, cmp_cc_arith_op_not_set, cmp_ccx_arith_op_not_set, negdi2_sp64, cmp_cc_neg, cmp_ccx_neg, cmp_cc_set_neg, cmp_ccx_set_neg, one_cmpldi2_sp64, cmp_cc_not, cmp_ccx_not, cmp_cc_set_not, cmp_ccx_set_not, addtf3, adddf3, addsf3, subtf3, subdf3, subsf3, multf3, muldf3, mulsf3, muldf3_extend, multf3_extend, divtf3, divdf3, divsf3, negtf2, negdf2, negsf2, abstf2, absdf2, abssf2, sqrttf2, sqrtdf2, sqrtsf2, ashlsi3, ashldi3, unnamed DI ashift, cmp_cc_ashift_1, cmp_cc_set_ashift_1, ashrsi3, ashrdi3, unnamed DI ashiftrt, ashrdi3_v8plus, lshrsi3, lshrdi3, unnamed DI lshiftrt, lshrdi3_v8plus, tablejump_sp32, tablejump_sp64, call_address_sp32, call_symbolic_sp32, call_address_sp64, call_symbolic_sp64, call_address_struct_value_sp32, call_symbolic_struct_value_sp32, call_address_untyped_struct_value_sp32, call_symbolic_untyped_struct_value_sp32, call_value_address_sp32, call_value_symbolic_sp32, call_value_address_sp64, call_value_symbolic_sp64, branch_sp32, branch_sp64, flush_register_windows, goto_handler_and_restore, goto_handler_and_restore_v9, goto_handler_and_restore_v9_sp64, flush, all ldd/std peepholes, return_qi, return_hi, return_si, return_addsi, return_di, return_adddi, return_sf, all call+jump peepholes, trap, unnamed trap insns): Prettify output strings. (define_insn anddi3_sp32, and_not_di_sp32, iordi3_sp32, or_not_di_sp32, xordi3_sp32, xor_not_di_sp32, one_cmpldi2): Likewise and force + implement splits for integer cases. (define_insn return_sf_no_fpu): Likewise and allow to match when no-fpu because of our subreg SFmode splits. (define_insn zero_extendqihi2, zero_extendqisi2_insn, zero_extendqidi2_insn, zero_extendhidi2_insn, zero_extendsidi2_insn, sign_extendsidi2_insn): Likewise and use input_operand for second operand. (cmp_minus_cc, cmp_minus_cc_set): Likewise and use reg_or_0_operand for operand 2 so new splits can use it. (cmp_zero_extendqisi2, cmp_zero_extendqisi2_set, cmp_cc_plus, cmp_cc_xor_not): Likewise and don't forget to check TARGET_LIVE_G0 too. (cmp_zero_extract, cmp_zero_extract_sp64): Likewise and allow CONST_DOUBLEs for operand 2. (define_insn move_label_di): Likewise and label distance optimization because it no longer works with new deferred case vector scheme. To be revisited. (define_insn x_minus_y_minus_sltu, x_minus_sltu_plus_y): Likewise and allow reg_or_0_operand and J constraint for second operand. (define_insn jump): Set branch predict taken on V9. (define_insn tablejump): Emit LABEL_REF + PLUS memory address for new deferred case vector scheme. (define_insn pic_tablejump_32, pic_tablejump_64): Remove. (define_insn negdi2_sp32): Force + implement splits. (define_insn negsi2, one_cmplsi2): Rename to negsi2_not_liveg0 and one_cmplsi2_not_liveg0 respectively, and create expander of original names which emit special rtl for TARGET_LIVE_G0. (define_insn cmpdi_v8plus, scc_si, scc_di): Remove. (define_insn seq, sne, slt, sge, sle, sltu, sgeu): Don't do gen_compare_reg, FAIL instead. (define_insn sgtu, sleu): Likewise and check gen_s*() return values when trying to reverse condition codes, if they FAIL then do likewise. (define_insn snesi_zero, neg_snesi_zero, snesi_zero_extend, snedi_zero, neg_snedi_zero, snedi_zero_trunc, seqsi_zero, neg_seqsi_zero, seqsi_zero_extend, seqdi_zero, neg_seqdi_zero, seqdi_zero_trunc, x_plus_i_ne_0, x_minus_i_ne_0, x_plus_i_eq_0, x_minus_i_eq_0): Add new splits to perform these multi-insn cases, set output string to # to indicate they are mandatory splits. (define_insn pic_lo_sum_si, pic_sethi_si, pic_lo_sum_di, pic_sethi_di, move_pic_label_si): Remove. (define_insn movsi_low_sum, movsi_high, movsi_lo_sum_pic, movsi_high_pic, movsi_pic_label_reg): New patterns to take their place. (define_expand movsi_pic_label_ref, define_insn movsi_high_pic_label_ref, movsi_lo_sum_pic_label_ref): New expander and insns to handle PIC label references and deferred case vectors. (define_insn get_pc_via_rdpc): Comment out as it is no longer used. (define_expand movqi, movhi, movsi, movdi, movsf, movdf, movtf): Rewrite to not use emit_move_sequence, make use of new constant formation code, and new splits for all multi-insn cases. (define_insn movqi_insn): Remove sethi case, it can never happen. Use reg_or_zero_operand instead of const0_rtx explicit test, use input_operand instead of move_operand for source, and use general_operand now for dest. (define_insn movhi_insn): Similar but leave sethi case. (define_insn lo_sum_qi, store_qi, store_hi): Remove. (define_insn sethi_hi lo_sum_hi): Rename to movhi_high and movhi_lo_sum respectively, prettify output string. (define_insn movsi_zero_liveg0): New pattern to put zero into a register when needed on TARGET_LIVE_G0. (define_insn movsi_insn): Use general_operand and input_operand for dest and src respectively. Simplify applicability test. Prettify output strings, and add clr alternative for J constraint. (define_insn movdi_sp32_v9, movdi_sp32, define_splits for deprecated std and reg-reg DI moves): Remove and... (define_insn movdi_insn_sp32, movdi_insn_sp64): Replace with new implementation which uses forced splits for all non-single insn cases. (define_split DI move cases on !arch64): New splits to handle all situations of 64-bit double register DImode on 32bit, and unaligned registers and memory addresses for all subtargets. (define_insn movsf_const_insn, movdf_const_insn, store_sf): Remove. (define_insn movsf_insn, movsf_no_f_insn): Use general_operand and input_operand for dest and src respectively, prettify output strings. (define_insn movdf_insn, movdf_no_e_insn, store_df, movtf_const_insn, movtf_insn, movtf_no_e_insn, store_tf): Remove and... (define_insn movdf_insn_sp32, movdf_no_e_insn_sp32, movdf_insn_sp64, movdf_no_e_insn_sp64, movtf_insn, movtf_no_e_insn_sp32, movtf_insn_hq_sp64, movtf_insn_sp64, movtf_no_e_insn_sp64): Replace with new implementation which uses forced splits for all non-single insn cases. (define_split DF move cases): New splits in similar vein to DI move counterparts. (define_insn sethi_di_medlow, sethi_di_medium_pic, sethi_di_embmedany_data, sethi_di_embmedany_text, sethi_di_sp64, movdi_sp64_insn): Remove old v9 code model and constant loading support insns and.. (define_insn pic_lo_sum_di, pic_sethi_di, sethi_di_medlow_embmedany_pic, sethi_di_medlow, losum_di_medlow, seth44, setm44, setl44, sethh, setlm, sethm, setlo, embmedany_sethi, embmedany_losum, embmedany_brsum, embmedany_textuhi, embmedany_texthi, embmedany_textulo, embmedany_textlo, movdi_lo_sum_sp64_cint, movdi_lo_sum_sp64_dbl, movdi_high_sp64_cint, movdi_high_sp64_dbl): Replace with new scheme, using unspecs, secondary reloads, and one to one sparc insn to rtl insn mapping for better scheduling and code gen. (define_expand reload_indi, reload_outdi): Reload helpers for MEDANY and EMBMEDANY symbol address loading cases which require a temporary register. (define_expand movsicc): Remove v8plus_regcmp cases. (define_insn movdi_cc_sp64_trunc, movdi_cc_reg_sp64_trunc, cmp_zero_extendqidi2, cmp_zero_extendqidi2_set, cmp_qidi_trunc, cmp_diqi_trunc_set): New patterns used by some of the new scc splits on arch64. (define_insn xordi3_sp64_dbl): New pattern used for constant formation when crossing from 32-bit targets. (define_insn movsi_cc_reg_v8plus, v8plus_clear_high, and helper split): Remove. (define_insn addx, subx): Make visible and prettify. (define_insn adddi3_insn_sp32): Likewise and force split. (define_insn addx_extend, subx_extend, unnamed): New patterns for 64bit scc split usage. (define_insn unnamed plusDI zero_extend, unnamed minusDI zero_extend, subdi3): Force and implement splits. * final.c (final_scan_insn): Don't output labels if target specifies ASM_OUTPUT_ADDR_{DIFF}_VEC. Do these macro operations instead. * reorg.c (dbr_schedule): When taking on BR_PRED notes at the end, don't forget to walk inside SEQUENCESs too as these are what the delay slot scheduler will create. Mon Aug 10 01:21:01 1998 Richard Henderson * alpha.md (extxl+1,+2): New patterns to work around combine lossage. Sat Aug 8 19:20:22 1998 Gary Thomas (gdt@linuxppc.org) * rs6000.c (rs6000_allocate_stack_space): Fix typo which caused bad assembly code to be generated. Sat Aug 8 18:53:28 1998 Jeffrey A Law (law@cygnus.com) * netbsd.h: Fix typo. Mon Aug 3 00:06:42 1998 Robert Lipe * config.sub: Fix typo. Sun Aug 2 22:39:08 1998 Hans-Peter Nilsson * invoke.texi (Environment Variables): Typo: Change "ascpects" into "aspects". (Running Protoize): Typo: Change "ther" into "other". Sun Aug 2 00:42:50 1998 Jeffrey A Law (law@cygnus.com) * i386/netbsd.h: Undo previous change to DWARF2_UNWIND_INFO. * m68k/netbsd.h: Likewise. * ns32k/netbsd.h: Likewise. * sparc/netbsd.h: Likewise. Sat Aug 1 17:59:30 1998 Richard Henderson * ginclude/va-alpha.h (va_list): Use a typedef, not a define. * ginclude/va-clipper.h (va_list): Likewise. Fri Jul 31 20:22:02 1998 Michael Meissner * rs6000.c (rs6000_override_options): If big endian and -Os, use load/store multiple instructions unless user overrides. Fri Jul 31 17:08:59 1998 Jeffrey A Law (law@cygnus.com) * ns32k/netbsd.h: Fix typo. Fri Jul 31 10:23:55 1998 Doug Evans * m32r/m32r.h (ASM_OUTPUT_SOURCE_LINE): Always output line number labels with .debugsym if no parallel insns. Thu Jul 30 19:15:53 1998 Richard Henderson * alpha.md (fp cmp): Replicate patterns for ALPHA_TP_INSN. (fcmov): Remove ALPHA_TP_INSN patterns -- fcmov doesn't trap. Thu Jul 30 19:50:15 1998 David Edelsohn * rs6000/x-aix43 (AR_FOR_TARGET_FLAGS): Delete. (AR_FOR_TARGET): Define. Thu Jul 30 12:29:12 1998 Mark Mitchell * dyn-string.h: New file. * dyn-string.c: Likewise. * Makefile.in (OBJS): Add dyn-string.o. (dwarf2out.o): Add dyn-string.h dependency. (dyn-string.o): List dependencies. * dwarf2out.c: Include dyn-string.h. (ASM_NAME_TO_STRING): Use dyn_string_append, rather than strcpy. (addr_const_to_string): Take a dyn_string_t, not a char* as a prototype. Use dyn_string_append rather than strcat, throughout. (addr_to_string): Use dyn_string_t. Thu Jul 30 13:08:07 1998 Ken Raeburn Function entry/exit profiling instrumentation: * expr.h (profile_function_entry_libfunc, profile_function_exit_libfunc): Declare new variables. * optabs.c: Define them here. (init_optabs): Initialize them. * tree.h (struct tree_decl): New flag no_instrument_function_entry_exit. (DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT): New accessor macro. * c-decl.c (duplicate_decls): Merge it. * c-common.c (enum attrs): New value A_NO_INSTRUMENT_FUNCTION. (init_attributes): Use it for "no_instrument_function". (decl_attributes): Handle it, for functions that have not yet been compiled. Set decl flag. * flags.h (flag_instrument_function_entry_exit): Declare new variable. * toplev.c (flag_instrument_function_entry_exit): Define it here. (f_options): New option "instrument-functions". * function.h (struct function): New field instrument_entry_exit. * function.c (current_function_instrument_entry_exit): New variable. (push_function_context_to, pop_function_context_from): Save and restore. (expand_function_start): Set current_ variable, maybe emit return label and entry profile call. (expand_function_end): Maybe emit exit profile call. Thu Jul 30 00:58:34 1998 Jeffrey A Law (law@cygnus.com) * i386.md (movqi): When optimizing a load of (const_int 1) into a NON_QI_REG_P, pretend the register is SImode. Wed Jul 29 23:49:23 1998 Todd Vierling * configure.in: Use xm-netbsd.h as the NetBSD xm file (not xm-siglist). Accept arm32 as arm, m68k4k as m68k, mipsle as mips-dec, and any manufacturer id for ns32k. * configure: Regenerated. * config/netbsd.h: When using ASM_WEAKEN_LABEL, make it global too. * config/t-netbsd: Don't compile libgcc1-test as the fns are in libc. * config/i386/netbsd.h: Undefine DWARF2_UNWIND_INFO, not define as 0. * config/m68k/netbsd.h: Same. * config/ns32k/netbsd.h: Same. * config/sparc/netbsd.h: Same. Wed Jul 29 22:39:21 1998 Jeffrey A Law (law@cygnus.com) * unroll.c (unroll_loop): Do not abort for an UNROLL_MODULO or UNROLL_COMPLETELY loop that starts with a jump to its exit code. Wed Jul 29 22:18:14 1998 David Edelsohn * rs6000/rs6000.md (absdi2 define_split): Swap operands of MINUS. * rs6000/rs6000.c (mask64_operand): Use HOST_BITS_PER_WIDE_INT. (print_operand, case 'B'): Don't fall through. (print_operand, case 'S'): Correct mask begin/end computation. Use HOST_BITS_PER_WIDE_INT. * rs6000/rs6000.h (CPP_PREDEFINES): Define _LONG_LONG. (CONDITIONAL_REGISTER_USAGE): GPR13 fixed if TARGET_64BIT. * rs6000/aix41.h (CPP_PREDEFINES): Same. * rs6000/aix43.h (CPP_PREDEFINES): Same. Wed Jul 29 11:47:10 1998 Nick Clifton * config/arm/thumb.md (extendqisi2_insn): Remove earlyclobber constraint from second alternative. Tue Jul 28 23:29:04 1998 Jason Merrill * configure.in: Fix --without/--disable cases for local-prefix, gxx-include-dir and checking. Tue Jul 28 22:01:23 1998 David S. Miller * configure.in (enable_haifa): Set by default for sparc64 too. configure: Rebuilt. Tue Jul 28 23:29:04 1998 Jason Merrill * i386/cygwin32.h (VALID_MACHINE_TYPE_ATTRIBUTE): New macro. * i386/winnt.c (associated_type): New fn. (i386_pe_valid_type_attribute_p): New fn. (i386_pe_check_vtable_importexport): Remove. (i386_pe_dllexport_p): Use associated_type. (i386_pe_dllimport_p): Likewise. From Antonio M. O. Neto : * i386.c (i386_valid_type_attribute_p): Also accept attributes for METHOD_TYPEs. Tue Jul 28 23:17:39 1998 Peter Gerwinski * tree.c (build_range_type): Copy TYPE_SIZE_UNIT. Tue Jul 28 22:31:12 1998 Craig Burley * gcc.c: Fix commentary describing %g, %u, %U, and %O. * gcc.c (do_spec_1): Fix handling of %g%O and %U%O to prevent them from generating a new base name for each occurrence of a specific suffix. 1998-07-28 Vladimir N. Makarov * cse.c (cse_insn): Enable substitution inside libcall only for REG, SUBREG, MEM. * rtlanal.c (replace_rtx): Prohibit replaces in CONST_DOUBLE. * cplus-dem.c (type_kind_t): New type. (demangle_template_value_parm): Add type_kind_t parameter. Rely on this parameter, rather than demangling the type again. (demangle_integral_value): Pass tk_integral. (demangle_template_: Pass the value returned from do_type. (do_type): Return a type_kind_t. Pass tk_integral to demangle_template_value_parm for array bounds. (demangle_fund_type): Likewise. Mon Jul 27 00:54:41 1998 Jason Merrill * tree.c (simple_cst_equal, case CONSTRUCTOR): OK if the elts are identical. Mon Jul 27 22:18:36 1998 Jeffrey A Law (law@cygnus.com) * pa.c (move_operand): Accept CONSTANT_P_RTX. Mon Jul 27 17:18:52 1998 Dave Brolley * stor-layout.c (layout_type): Handle arrays of bits, for Chill. * expr.c (get_inner_reference): Handle zero-based, unsigned, array index conversion. Mon Jul 27 14:51:33 1998 Jeffrey A Law (law@cygnus.com) * mn10300.h (DEBUGGER_AUTO_OFFSET): Define. (DEBUGGER_ARG_OFFSET): Likewise. * mn10300.md (movsf): Remove last change. Not needed. Mon Jul 27 14:22:36 1998 Dave Brolley * c-lex.c (yylex): Fix boundary conditions in character literal and string literal loops. Mon Jul 27 11:43:54 1998 Stan Cox * longlong.h (count_leading_zeros): Sparclite scan instruction was being invoked incorrectly. * i386.c (ix86_prologue): Added SUBTARGET_PROLOGUE invocation. * i386/cygwin32.h (STARTFILE_SPEC, LIB_SPEC, SUBTARGET_PROLOGUE): Add -pg support. * i386/win32.h: New file. Hybrid mingw32.h/cygwin32.h configuration. * configure.in: Added i[34567]86-*-win32. * config.sub: Likewise. * configure: Rebuilt. Sun Jul 26 01:11:12 1998 H.J. Lu (hjl@gnu.org) * i386.h (CONST_DOUBLE_OK_FOR_LETTER_P): Return 0 when eliminating the frame pointer and compiling PIC code and reload has not completed. * i386.c (output_to_reg): Add code to emulate non-popping DImode case. Sun Jul 26 01:01:32 1998 Jeffrey A Law (law@cygnus.com) * regmove.c (regmove_optimize): Fix typo initializing regmove_bb_head. Sat Jul 25 23:29:23 1998 Gerald Pfeifer * Makefile.in (install-info): Only try to update the info directory file if it exists in the first place. Fri Jul 24 18:58:37 1998 Klaus Espenlaub * rs6000.h (ASM_OUTPUT_CONSTRUCTOR, ASM_OUTPUT_DESTRUCTOR): Delete. Fri Jul 24 14:20:26 1998 Jeffrey A Law (law@cygnus.com) * mn10300.md (movqi, movhi, movsi, movsf): Correctly handle CONST_DOUBLE source. Fri Jul 24 11:17:04 1998 Nick Clifton * config/arm/thumb.c (thumb_print_operand): Decode %_ in asm strings as the insertion of USER_LABEL_PREFIX. * config/arm/thumb.h (PRINT_OPERAND_PUNCT_VALID_P): Accept _ as a valid code. * config/arm/thumb.md: Use %_ as a prefix to gcc library function calls. Thu Jul 23 18:53:20 1998 Jim Wilson * dbxout.c (dbxout_range_type): Only call dbxout_type_index for already defined type. Thu Jul 23 13:49:41 1998 Jeffrey A Law (law@cygnus.com) * expr.c (check_max_integer_computation_mode): Allow conversions of constant integers to MAX_INTEGER_COMPUTATION_MODE. (expand_expr): Likewise. Thu Jul 23 11:12:06 1998 Alexandre Petit-Bianco * expr.c (expand_expr): Expand RETURN_EXPR. Thu Jul 23 11:00:29 1998 Jim Wilson * dwarf2out.c (dwarf2out_finish): Call stripattributes on TEXT_SECTION. Wed Jul 22 19:10:00 1998 Catherine Moore * dwarf2out.c (output_aranges): Call stripattributes for TEXT_SECTION references. (output_line_info): Likewise. Wed Jul 22 14:08:54 1998 David S. Miller * profile.c (branch_prob): Call allocate_reg_info after outputting profile rtl in instrument_arcs. Wed Jul 22 12:47:49 1998 Jim Wilson * fixinc.irix (math.h): Install wrapper instead of copying. Wed Jul 22 12:37:14 1998 Alexandre Petit-Bianco * tree.def (EXPR_WITH_FILE_LOCATION): Defined as an 'e' expression so WFL are expanded correctly when contained in a COMPOUND_EXPR. * tree.h (EXPR_WFL_EMIT_LINE_NOTE): Change macro not to use lang_flag_0. Added documentation in the flag table. Tue Jul 21 23:28:35 1998 Klaus Kaempf * cccp.c (do_include): Fix vax c style include handling. Tue Jul 21 13:28:19 1998 Jason Merrill * cplus-dem.c (do_type): Use demangle_template_value_parm for arrays. Sun Jul 12 01:27:05 1998 Jason Merrill * fold-const.c (non_lvalue): Don't deal with null pointer constants here. (fold, case COMPOUND_EXPR): Wrap a constant 0 in a NOP_EXPR. Tue Jul 21 15:49:31 1998 David Edelsohn * rs6000.h (PREDICATE_CODES): Add CONSTANT_P_RTX. * rs6000.md (movsi, movdi): Add CONSTANT_P_RTX. * rs6000.c (short_cint_operand): Add CONSTANT_P_RTX. (u_short_cint_operand): Same. (reg_or_cint_operand): Same. (logical_operand): Same. (input_operand): Same. (reg_or_short_operand): Use u_short_cint_operand. Tue Jul 21 08:56:42 1998 Richard Henderson * alpha.md (fix_truncdfsi2, fix_truncsfsi2): Remove the define_expands, but keep the insns and splits. Adjust so when the ultimate destination is memory, use cvtql. Tue Jul 21 08:55:09 1998 Richard Henderson * flow.c (regno_uninitialized): Fixed regs are never uninitialized. Tue Jul 21 00:31:01 1998 Jeffrey A Law (law@cygnus.com) * gcc.c (do_spec): Call "error" not "warning". * configure.in: Fix minor problems with gas feature detection code. * configure: Rebuilt. * gcc.c (do_spec): Issue a warning for '%[]' usage. * Undo this change. * gcc.c: Delete %[spec] support. (do_spec_1, case '('): Likewise. (do_spec_1, case '['): Call error. Mon Jul 20 22:34:17 1998 Richard Henderson * alpha.h (CPP_SPEC): Tidy. Hook to cpp_cpu and cpp_subtarget. (CPP_SUBTARGET_SPEC): Default to empty string. (CPP_AM_*, CPP_IM_*, CPP_CPU_*, CPP_CPU_SPEC): New. (EXTRA_SPECS, SUBTARGET_EXTRA_SPECS): New. * alpha/elf.h (LD_SPEC): Use %(elf_dynamic_linker). * alpha/linux-elf.h (SUBTARGET_EXTRA_SPECS): New. (LIB_SPEC): Tidy. * alpha/linux.h (CPP_PREDEFINES): Tidy. * alpha/netbsd-elf.h (SUBTARGET_EXTRA_SPECS): New. * alpha/netbsd.h (CPP_PREDEFINES): Tidy. * alpha/osf.h (CPP_PREDEFINES): Remove bits subsumed by CPP_CPU_SPEC. * alpha/win-nt.h (CPP_PREDEFINES): Likewise. * alpha/vsf.h (CPP_PREDEFINES): Likewise. (CPP_SUBTARGET_SPEC): New. Do this instead of overriding CPP_SPEC. * alpha/vxworks.h: Likewise. Mon Jul 20 22:51:57 1998 Ken Raeburn * mips.md (reload_outsi): Added missing REGNO call. (smulsi3_highpart, umulsi3_highpart): Provide prototype for function pointer. (mul_acc_di, mul_acc_64bit_di): Don't use match_op_dup, use another match_operator and compare the codes. * mips.h (MASK_DEBUG_E, MASK_DEBUG_I): Set to zero. * MIPS multiply pattern fixes: * mips.h (enum reg_class, REG_CLASS_NAMES, REG_CLASS_CONTENTS): Add union classes for HI, LO, or HILO plus general registers. (GENERATE_MADD): Deleted. * mips.md (mulsi3_mult3): Don't disparage output-LO alternative. Add TARGET_MAD to condition. (mulsi3): Test HAVE_mulsi3_mult3, not specific flags. (mul_acc_si): Expand GENERATE_MADD here; it's the only use. Use "*d" for accumulator, to give preference to LO initially but not during reload. Mon Jul 20 16:16:38 1998 Dave Brolley * configure.in (enable_c_mbchar): New configure option. (extra_cpp_objs): Always available now. * cexp.y (mbchar.h): #include it. (yylex): Handle Multibyte characters in character literals. * cccp.c (mbchar.h): #include it. (main): Set character set based on LANG environment variable. (rescan): Handle multibyte characters in comments. (skip_if_group): See above. (validate_else): See above. (skip_to_end_of_comment): See above. (macarg1): See above. (discard_comments): See above. (rescan): Handle multibyte characters in string and character literals. (collect_expansion): See above. (skip_quoted_string): See above. (macroexpand): See above. (macarg1): See above. (discard_comments): See above. (change_newlines): See above. * c-lex.c (mbchar.h): #include it. (GET_ENVIRONMENT): New macro. (init_lex): Set character set based on LANG environment variable. (yylex): Handle multibyte characters in character literals. (yylex): Handle multibyte characters in string literals. * Makefile.in (mbchar.o): New target. (cccp$(exeext)): @extra_cpp_objs@ is always available. (cppmain$(exeext)): @extra_cpp_objs@ is always available. * mbchar.[ch]: New files for multibyte character handling. Mon Jul 20 01:11:11 1998 David S. Miller * jump.c (jump_optimize): When simplifying noop moves and PUSH_ROUNDING, fix thinko so we use same criterion for identifying the PUSHes to rewrite in second loop as we did in the first. Sun Jul 19 08:23:53 1998 Kaveh R. Ghazi * cplus-dem.c (demangle_nested_args): Make function definition static to match the prototype. Fri Jul 17 14:58:44 1998 Richard Henderson * alloca.c: Respect USE_C_ALLOCA. * gencheck.c (xmalloc): Ignore __GNUC__ for definition. * gengenrtl.c (xmalloc): Likewise. Fri Jul 17 14:18:14 1998 Richard Henderson * loop.h (struct induction): Add no_const_addval. * loop.c (the_movables, reg_address_cost): New variables. (init_loop): Init reg_address_cost. (loop_optimize): Call end_alias_analysis. (scan_loop): Init the_movables. (record_giv): Init induction->no_const_addval. (basic_induction_var) [PLUS]: Use rtx_equal_p instead of ==. [REG]: Rearrange loop search test to catch more cases. (general_induction_var): Return success not benefit; take an extra argument for that. Change all callers. (simplify_giv_expr) [PLUS]: Always combine invariants. Use sge_plus. [MULT]: Use rtx_equal_p instead of ==. Combine simple invariants. [default]: Search the_movables for additional combinations. (sge_plus_constant, sge_plus): New functions. (express_from_1): New function. (express_from): Always define. Rewrite using express_from_1. (combine_givs_p): Handle more cases. Ignore address cost. (cmp_combine_givs_stats): New function. (combine_givs_used_once, combine_givs_benefit_from): New functions. (combine_givs): Rewrite to do best-fit combination. * fold-const.c (operand_equal_p): Handle RTL_EXPR. (fold): Do a complete (A*C)+(B*C) association check. Fri Jul 17 11:21:55 1998 Jim Wilson * function.c (fixup_var_refs_insns): Handle CLOBBER of a CONCAT. Fri Jul 17 11:48:55 1998 Jeffrey A Law (law@cygnus.com) * mn10300.c (MODES_TIEABLE_P): Fix typo. Fri Jul 17 03:26:12 1998 Rihcard Earnshaw (rearnsha@arm.com) * tree.c (valid_machine_attribute): Only create a new type variant if there is a decl to use it. Thu Jul 16 14:48:04 1998 Nick Clifton * gcc.c (do_spec_1): Cope with %g/%u/%U options which do not have a suffix. Fri Jul 17 03:24:40 1998 Hans-Peter Nilsson * extend.texi (Explicit Reg Vars): Typo: change "may deleted" into "may be deleted" Thu Jul 16 14:48:47 1998 Jeffrey A Law (law@cygnus.com) * mn10300.c (count_tst_insns): New arg oreg_countp. Callers changed. Simplify tests for clearing an address register. (expand_prologue): Corresponding changes. * mn10300.md (movXX patterns): Make sure the destination is an ADDRESS_REG when substituting "zero_areg" for (const_int 0). (logical patterns): Split into expanders + patterns. (zero and sign extension patterns): Similarly. (shift patterns): Similarly. Thu Jul 16 01:17:44 1998 Richard Henderson * loop.c (emit_iv_add_mult): Scan the entire insn list generated for the sequence, recording base values. Wed Jul 15 10:49:55 1998 Richard Henderson * i386.h (CPP_CPU_SPEC): Remove -Asystem(unix). Tue Jul 14 14:15:30 1998 Nick Clifton * gcc.c: Remove ANSI-C ism from --help code. * toplev.c: Support --help with USE_CPPLIB. Tue Jul 14 14:46:08 1998 Jeffrey A Law (law@cygnus.com) * configure.in: Rework gas feature code to work with symlink based source trees. * extend.texi: Clarify some issues related to local variables assigned to explicit registers. * mn10300.md (mulsi): Turn into expander + pattern. * mn10300.md (movsi, movsf, movdi, movdf): Remove "x" from I -> a alternative. Tue Jul 14 07:41:59 1998 Richard Earnshaw (rearnsha@arm.com) * arm/tcoff.h (USER_LABEL_PREFIX): Make it empty to match coff.h. Tue Jul 14 03:02:44 1998 Jeffrey A Law (law@cygnus.com) * version.c: Bump again to distinguish mainline tree from the egcs-1.1 branch. See ChangeLog.0 for earlier changes. Local Variables: add-log-time-format: current-time-string End: Index: vendor/gcc/dist/contrib/gcc/c-typeck.c =================================================================== --- vendor/gcc/dist/contrib/gcc/c-typeck.c (revision 60966) +++ vendor/gcc/dist/contrib/gcc/c-typeck.c (revision 60967) @@ -1,6948 +1,6947 @@ /* Build expressions with type checking for C compiler. Copyright (C) 1987, 88, 91-97, 1998 Free Software Foundation, Inc. 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. */ /* This file is part of the C front end. It contains routines to build C expressions given their operands, including computing the types of the result, C-specific error checks, and some optimization. There are also routines to build RETURN_STMT nodes and CASE_STMT nodes, and to process initializations in declarations (since they work like a strange sort of assignment). */ #include "config.h" #include "system.h" #include "tree.h" #include "c-tree.h" #include "flags.h" #include "output.h" #include "rtl.h" #include "expr.h" #include "toplev.h" #include "intl.h" /* Nonzero if we've already printed a "missing braces around initializer" message within this initializer. */ static int missing_braces_mentioned; static tree qualify_type PROTO((tree, tree)); static int comp_target_types PROTO((tree, tree)); static int function_types_compatible_p PROTO((tree, tree)); static int type_lists_compatible_p PROTO((tree, tree)); static int self_promoting_type_p PROTO((tree)); static tree decl_constant_value PROTO((tree)); static tree lookup_field PROTO((tree, tree, tree *)); static tree convert_arguments PROTO((tree, tree, tree, tree)); static tree pointer_int_sum PROTO((enum tree_code, tree, tree)); static tree pointer_diff PROTO((tree, tree)); static tree unary_complex_lvalue PROTO((enum tree_code, tree)); static void pedantic_lvalue_warning PROTO((enum tree_code)); static tree internal_build_compound_expr PROTO((tree, int)); static tree convert_for_assignment PROTO((tree, tree, const char *, tree, tree, int)); static void warn_for_assignment PROTO((const char *, const char *, tree, int)); static tree valid_compound_expr_initializer PROTO((tree, tree)); static void push_string PROTO((const char *)); static void push_member_name PROTO((tree)); static void push_array_bounds PROTO((int)); static int spelling_length PROTO((void)); static char *print_spelling PROTO((char *)); static void warning_init PROTO((const char *)); static tree digest_init PROTO((tree, tree, int, int)); static void check_init_type_bitfields PROTO((tree)); static void output_init_element PROTO((tree, tree, tree, int)); static void output_pending_init_elements PROTO((int)); static void add_pending_init PROTO((tree, tree)); static int pending_init_member PROTO((tree)); /* Do `exp = require_complete_type (exp);' to make sure exp does not have an incomplete type. (That includes void types.) */ tree require_complete_type (value) tree value; { tree type = TREE_TYPE (value); if (TREE_CODE (value) == ERROR_MARK) return error_mark_node; /* First, detect a valid value with a complete type. */ if (TYPE_SIZE (type) != 0 && type != void_type_node) return value; incomplete_type_error (value, type); return error_mark_node; } /* Print an error message for invalid use of an incomplete type. VALUE is the expression that was used (or 0 if that isn't known) and TYPE is the type that was invalid. */ void incomplete_type_error (value, type) tree value; tree type; { const char *type_code_string; /* Avoid duplicate error message. */ if (TREE_CODE (type) == ERROR_MARK) return; if (value != 0 && (TREE_CODE (value) == VAR_DECL || TREE_CODE (value) == PARM_DECL)) error ("`%s' has an incomplete type", IDENTIFIER_POINTER (DECL_NAME (value))); else { retry: /* We must print an error message. Be clever about what it says. */ switch (TREE_CODE (type)) { case RECORD_TYPE: type_code_string = "struct"; break; case UNION_TYPE: type_code_string = "union"; break; case ENUMERAL_TYPE: type_code_string = "enum"; break; case VOID_TYPE: error ("invalid use of void expression"); return; case ARRAY_TYPE: if (TYPE_DOMAIN (type)) { type = TREE_TYPE (type); goto retry; } error ("invalid use of array with unspecified bounds"); return; default: abort (); } if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE) error ("invalid use of undefined type `%s %s'", type_code_string, IDENTIFIER_POINTER (TYPE_NAME (type))); else /* If this type has a typedef-name, the TYPE_NAME is a TYPE_DECL. */ error ("invalid use of incomplete typedef `%s'", IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)))); } } /* Return a variant of TYPE which has all the type qualifiers of LIKE as well as those of TYPE. */ static tree qualify_type (type, like) tree type, like; { return c_build_qualified_type (type, TYPE_QUALS (type) | TYPE_QUALS (like)); } /* Return the common type of two types. We assume that comptypes has already been done and returned 1; if that isn't so, this may crash. In particular, we assume that qualifiers match. This is the type for the result of most arithmetic operations if the operands have the given two types. */ tree common_type (t1, t2) tree t1, t2; { register enum tree_code code1; register enum tree_code code2; tree attributes; /* Save time if the two types are the same. */ if (t1 == t2) return t1; /* If one type is nonsense, use the other. */ if (t1 == error_mark_node) return t2; if (t2 == error_mark_node) return t1; /* Merge the attributes. */ attributes = merge_machine_type_attributes (t1, t2); /* Treat an enum type as the unsigned integer type of the same width. */ if (TREE_CODE (t1) == ENUMERAL_TYPE) t1 = type_for_size (TYPE_PRECISION (t1), 1); if (TREE_CODE (t2) == ENUMERAL_TYPE) t2 = type_for_size (TYPE_PRECISION (t2), 1); code1 = TREE_CODE (t1); code2 = TREE_CODE (t2); /* If one type is complex, form the common type of the non-complex components, then make that complex. Use T1 or T2 if it is the required type. */ if (code1 == COMPLEX_TYPE || code2 == COMPLEX_TYPE) { tree subtype1 = code1 == COMPLEX_TYPE ? TREE_TYPE (t1) : t1; tree subtype2 = code2 == COMPLEX_TYPE ? TREE_TYPE (t2) : t2; tree subtype = common_type (subtype1, subtype2); if (code1 == COMPLEX_TYPE && TREE_TYPE (t1) == subtype) return build_type_attribute_variant (t1, attributes); else if (code2 == COMPLEX_TYPE && TREE_TYPE (t2) == subtype) return build_type_attribute_variant (t2, attributes); else return build_type_attribute_variant (build_complex_type (subtype), attributes); } switch (code1) { case INTEGER_TYPE: case REAL_TYPE: /* If only one is real, use it as the result. */ if (code1 == REAL_TYPE && code2 != REAL_TYPE) return build_type_attribute_variant (t1, attributes); if (code2 == REAL_TYPE && code1 != REAL_TYPE) return build_type_attribute_variant (t2, attributes); /* Both real or both integers; use the one with greater precision. */ if (TYPE_PRECISION (t1) > TYPE_PRECISION (t2)) return build_type_attribute_variant (t1, attributes); else if (TYPE_PRECISION (t2) > TYPE_PRECISION (t1)) return build_type_attribute_variant (t2, attributes); /* Same precision. Prefer longs to ints even when same size. */ if (TYPE_MAIN_VARIANT (t1) == long_unsigned_type_node || TYPE_MAIN_VARIANT (t2) == long_unsigned_type_node) return build_type_attribute_variant (long_unsigned_type_node, attributes); if (TYPE_MAIN_VARIANT (t1) == long_integer_type_node || TYPE_MAIN_VARIANT (t2) == long_integer_type_node) { /* But preserve unsignedness from the other type, since long cannot hold all the values of an unsigned int. */ if (TREE_UNSIGNED (t1) || TREE_UNSIGNED (t2)) t1 = long_unsigned_type_node; else t1 = long_integer_type_node; return build_type_attribute_variant (t1, attributes); } /* Likewise, prefer long double to double even if same size. */ if (TYPE_MAIN_VARIANT (t1) == long_double_type_node || TYPE_MAIN_VARIANT (t2) == long_double_type_node) return build_type_attribute_variant (long_double_type_node, attributes); /* Otherwise prefer the unsigned one. */ if (TREE_UNSIGNED (t1)) return build_type_attribute_variant (t1, attributes); else return build_type_attribute_variant (t2, attributes); case POINTER_TYPE: /* For two pointers, do this recursively on the target type, and combine the qualifiers of the two types' targets. */ /* This code was turned off; I don't know why. But ANSI C specifies doing this with the qualifiers. So I turned it on again. */ { tree pointed_to_1 = TREE_TYPE (t1); tree pointed_to_2 = TREE_TYPE (t2); tree target = common_type (TYPE_MAIN_VARIANT (pointed_to_1), TYPE_MAIN_VARIANT (pointed_to_2)); t1 = build_pointer_type (c_build_qualified_type (target, TYPE_QUALS (pointed_to_1) | TYPE_QUALS (pointed_to_2))); return build_type_attribute_variant (t1, attributes); } #if 0 t1 = build_pointer_type (common_type (TREE_TYPE (t1), TREE_TYPE (t2))); return build_type_attribute_variant (t1, attributes); #endif case ARRAY_TYPE: { tree elt = common_type (TREE_TYPE (t1), TREE_TYPE (t2)); /* Save space: see if the result is identical to one of the args. */ if (elt == TREE_TYPE (t1) && TYPE_DOMAIN (t1)) return build_type_attribute_variant (t1, attributes); if (elt == TREE_TYPE (t2) && TYPE_DOMAIN (t2)) return build_type_attribute_variant (t2, attributes); /* Merge the element types, and have a size if either arg has one. */ t1 = build_array_type (elt, TYPE_DOMAIN (TYPE_DOMAIN (t1) ? t1 : t2)); return build_type_attribute_variant (t1, attributes); } case FUNCTION_TYPE: /* Function types: prefer the one that specified arg types. If both do, merge the arg types. Also merge the return types. */ { tree valtype = common_type (TREE_TYPE (t1), TREE_TYPE (t2)); tree p1 = TYPE_ARG_TYPES (t1); tree p2 = TYPE_ARG_TYPES (t2); int len; tree newargs, n; int i; /* Save space: see if the result is identical to one of the args. */ if (valtype == TREE_TYPE (t1) && ! TYPE_ARG_TYPES (t2)) return build_type_attribute_variant (t1, attributes); if (valtype == TREE_TYPE (t2) && ! TYPE_ARG_TYPES (t1)) return build_type_attribute_variant (t2, attributes); /* Simple way if one arg fails to specify argument types. */ if (TYPE_ARG_TYPES (t1) == 0) { t1 = build_function_type (valtype, TYPE_ARG_TYPES (t2)); return build_type_attribute_variant (t1, attributes); } if (TYPE_ARG_TYPES (t2) == 0) { t1 = build_function_type (valtype, TYPE_ARG_TYPES (t1)); return build_type_attribute_variant (t1, attributes); } /* If both args specify argument types, we must merge the two lists, argument by argument. */ len = list_length (p1); newargs = 0; for (i = 0; i < len; i++) newargs = tree_cons (NULL_TREE, NULL_TREE, newargs); n = newargs; for (; p1; p1 = TREE_CHAIN (p1), p2 = TREE_CHAIN (p2), n = TREE_CHAIN (n)) { /* A null type means arg type is not specified. Take whatever the other function type has. */ if (TREE_VALUE (p1) == 0) { TREE_VALUE (n) = TREE_VALUE (p2); goto parm_done; } if (TREE_VALUE (p2) == 0) { TREE_VALUE (n) = TREE_VALUE (p1); goto parm_done; } /* Given wait (union {union wait *u; int *i} *) and wait (union wait *), prefer union wait * as type of parm. */ if (TREE_CODE (TREE_VALUE (p1)) == UNION_TYPE && TREE_VALUE (p1) != TREE_VALUE (p2)) { tree memb; for (memb = TYPE_FIELDS (TREE_VALUE (p1)); memb; memb = TREE_CHAIN (memb)) if (comptypes (TREE_TYPE (memb), TREE_VALUE (p2))) { TREE_VALUE (n) = TREE_VALUE (p2); if (pedantic) pedwarn ("function types not truly compatible in ANSI C"); goto parm_done; } } if (TREE_CODE (TREE_VALUE (p2)) == UNION_TYPE && TREE_VALUE (p2) != TREE_VALUE (p1)) { tree memb; for (memb = TYPE_FIELDS (TREE_VALUE (p2)); memb; memb = TREE_CHAIN (memb)) if (comptypes (TREE_TYPE (memb), TREE_VALUE (p1))) { TREE_VALUE (n) = TREE_VALUE (p1); if (pedantic) pedwarn ("function types not truly compatible in ANSI C"); goto parm_done; } } TREE_VALUE (n) = common_type (TREE_VALUE (p1), TREE_VALUE (p2)); parm_done: ; } t1 = build_function_type (valtype, newargs); /* ... falls through ... */ } default: return build_type_attribute_variant (t1, attributes); } } /* Return 1 if TYPE1 and TYPE2 are compatible types for assignment or various other operations. Return 2 if they are compatible but a warning may be needed if you use them together. */ int comptypes (type1, type2) tree type1, type2; { register tree t1 = type1; register tree t2 = type2; int attrval, val; /* Suppress errors caused by previously reported errors. */ if (t1 == t2 || !t1 || !t2 || TREE_CODE (t1) == ERROR_MARK || TREE_CODE (t2) == ERROR_MARK) return 1; /* Treat an enum type as the integer type of the same width and signedness. */ if (TREE_CODE (t1) == ENUMERAL_TYPE) t1 = type_for_size (TYPE_PRECISION (t1), TREE_UNSIGNED (t1)); if (TREE_CODE (t2) == ENUMERAL_TYPE) t2 = type_for_size (TYPE_PRECISION (t2), TREE_UNSIGNED (t2)); if (t1 == t2) return 1; /* Different classes of types can't be compatible. */ if (TREE_CODE (t1) != TREE_CODE (t2)) return 0; /* Qualifiers must match. */ if (TYPE_QUALS (t1) != TYPE_QUALS (t2)) return 0; /* Allow for two different type nodes which have essentially the same definition. Note that we already checked for equality of the type qualifiers (just above). */ if (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2)) return 1; #ifndef COMP_TYPE_ATTRIBUTES #define COMP_TYPE_ATTRIBUTES(t1,t2) 1 #endif /* 1 if no need for warning yet, 2 if warning cause has been seen. */ if (! (attrval = COMP_TYPE_ATTRIBUTES (t1, t2))) return 0; /* 1 if no need for warning yet, 2 if warning cause has been seen. */ val = 0; switch (TREE_CODE (t1)) { case POINTER_TYPE: val = (TREE_TYPE (t1) == TREE_TYPE (t2) ? 1 : comptypes (TREE_TYPE (t1), TREE_TYPE (t2))); break; case FUNCTION_TYPE: val = function_types_compatible_p (t1, t2); break; case ARRAY_TYPE: { tree d1 = TYPE_DOMAIN (t1); tree d2 = TYPE_DOMAIN (t2); val = 1; /* Target types must match incl. qualifiers. */ if (TREE_TYPE (t1) != TREE_TYPE (t2) && 0 == (val = comptypes (TREE_TYPE (t1), TREE_TYPE (t2)))) return 0; /* Sizes must match unless one is missing or variable. */ if (d1 == 0 || d2 == 0 || d1 == d2 || TREE_CODE (TYPE_MIN_VALUE (d1)) != INTEGER_CST || TREE_CODE (TYPE_MIN_VALUE (d2)) != INTEGER_CST || TREE_CODE (TYPE_MAX_VALUE (d1)) != INTEGER_CST || TREE_CODE (TYPE_MAX_VALUE (d2)) != INTEGER_CST) break; if (! ((TREE_INT_CST_LOW (TYPE_MIN_VALUE (d1)) == TREE_INT_CST_LOW (TYPE_MIN_VALUE (d2))) && (TREE_INT_CST_HIGH (TYPE_MIN_VALUE (d1)) == TREE_INT_CST_HIGH (TYPE_MIN_VALUE (d2))) && (TREE_INT_CST_LOW (TYPE_MAX_VALUE (d1)) == TREE_INT_CST_LOW (TYPE_MAX_VALUE (d2))) && (TREE_INT_CST_HIGH (TYPE_MAX_VALUE (d1)) == TREE_INT_CST_HIGH (TYPE_MAX_VALUE (d2))))) val = 0; break; } case RECORD_TYPE: if (maybe_objc_comptypes (t1, t2, 0) == 1) val = 1; break; default: break; } return attrval == 2 && val == 1 ? 2 : val; } /* Return 1 if TTL and TTR are pointers to types that are equivalent, ignoring their qualifiers. */ static int comp_target_types (ttl, ttr) tree ttl, ttr; { int val; /* Give maybe_objc_comptypes a crack at letting these types through. */ if ((val = maybe_objc_comptypes (ttl, ttr, 1)) >= 0) return val; val = comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (ttl)), TYPE_MAIN_VARIANT (TREE_TYPE (ttr))); if (val == 2 && pedantic) pedwarn ("types are not quite compatible"); return val; } /* Subroutines of `comptypes'. */ /* Return 1 if two function types F1 and F2 are compatible. If either type specifies no argument types, the other must specify a fixed number of self-promoting arg types. Otherwise, if one type specifies only the number of arguments, the other must specify that number of self-promoting arg types. Otherwise, the argument types must match. */ static int function_types_compatible_p (f1, f2) tree f1, f2; { tree args1, args2; /* 1 if no need for warning yet, 2 if warning cause has been seen. */ int val = 1; int val1; if (!(TREE_TYPE (f1) == TREE_TYPE (f2) || (val = comptypes (TREE_TYPE (f1), TREE_TYPE (f2))))) return 0; args1 = TYPE_ARG_TYPES (f1); args2 = TYPE_ARG_TYPES (f2); /* An unspecified parmlist matches any specified parmlist whose argument types don't need default promotions. */ if (args1 == 0) { if (!self_promoting_args_p (args2)) return 0; /* If one of these types comes from a non-prototype fn definition, compare that with the other type's arglist. If they don't match, ask for a warning (but no error). */ if (TYPE_ACTUAL_ARG_TYPES (f1) && 1 != type_lists_compatible_p (args2, TYPE_ACTUAL_ARG_TYPES (f1))) val = 2; return val; } if (args2 == 0) { if (!self_promoting_args_p (args1)) return 0; if (TYPE_ACTUAL_ARG_TYPES (f2) && 1 != type_lists_compatible_p (args1, TYPE_ACTUAL_ARG_TYPES (f2))) val = 2; return val; } /* Both types have argument lists: compare them and propagate results. */ val1 = type_lists_compatible_p (args1, args2); return val1 != 1 ? val1 : val; } /* Check two lists of types for compatibility, returning 0 for incompatible, 1 for compatible, or 2 for compatible with warning. */ static int type_lists_compatible_p (args1, args2) tree args1, args2; { /* 1 if no need for warning yet, 2 if warning cause has been seen. */ int val = 1; int newval = 0; while (1) { if (args1 == 0 && args2 == 0) return val; /* If one list is shorter than the other, they fail to match. */ if (args1 == 0 || args2 == 0) return 0; /* A null pointer instead of a type means there is supposed to be an argument but nothing is specified about what type it has. So match anything that self-promotes. */ if (TREE_VALUE (args1) == 0) { if (! self_promoting_type_p (TREE_VALUE (args2))) return 0; } else if (TREE_VALUE (args2) == 0) { if (! self_promoting_type_p (TREE_VALUE (args1))) return 0; } else if (! (newval = comptypes (TREE_VALUE (args1), TREE_VALUE (args2)))) { /* Allow wait (union {union wait *u; int *i} *) and wait (union wait *) to be compatible. */ if (TREE_CODE (TREE_VALUE (args1)) == UNION_TYPE && (TYPE_NAME (TREE_VALUE (args1)) == 0 || TYPE_TRANSPARENT_UNION (TREE_VALUE (args1))) && TREE_CODE (TYPE_SIZE (TREE_VALUE (args1))) == INTEGER_CST && tree_int_cst_equal (TYPE_SIZE (TREE_VALUE (args1)), TYPE_SIZE (TREE_VALUE (args2)))) { tree memb; for (memb = TYPE_FIELDS (TREE_VALUE (args1)); memb; memb = TREE_CHAIN (memb)) if (comptypes (TREE_TYPE (memb), TREE_VALUE (args2))) break; if (memb == 0) return 0; } else if (TREE_CODE (TREE_VALUE (args2)) == UNION_TYPE && (TYPE_NAME (TREE_VALUE (args2)) == 0 || TYPE_TRANSPARENT_UNION (TREE_VALUE (args2))) && TREE_CODE (TYPE_SIZE (TREE_VALUE (args2))) == INTEGER_CST && tree_int_cst_equal (TYPE_SIZE (TREE_VALUE (args2)), TYPE_SIZE (TREE_VALUE (args1)))) { tree memb; for (memb = TYPE_FIELDS (TREE_VALUE (args2)); memb; memb = TREE_CHAIN (memb)) if (comptypes (TREE_TYPE (memb), TREE_VALUE (args1))) break; if (memb == 0) return 0; } else return 0; } /* comptypes said ok, but record if it said to warn. */ if (newval > val) val = newval; args1 = TREE_CHAIN (args1); args2 = TREE_CHAIN (args2); } } /* Return 1 if PARMS specifies a fixed number of parameters and none of their types is affected by default promotions. */ int self_promoting_args_p (parms) tree parms; { register tree t; for (t = parms; t; t = TREE_CHAIN (t)) { register tree type = TREE_VALUE (t); if (TREE_CHAIN (t) == 0 && type != void_type_node) return 0; if (type == 0) return 0; if (TYPE_MAIN_VARIANT (type) == float_type_node) return 0; if (C_PROMOTING_INTEGER_TYPE_P (type)) return 0; } return 1; } /* Return 1 if TYPE is not affected by default promotions. */ static int self_promoting_type_p (type) tree type; { if (TYPE_MAIN_VARIANT (type) == float_type_node) return 0; if (C_PROMOTING_INTEGER_TYPE_P (type)) return 0; return 1; } /* Return an unsigned type the same as TYPE in other respects. */ tree unsigned_type (type) tree type; { tree type1 = TYPE_MAIN_VARIANT (type); if (type1 == signed_char_type_node || type1 == char_type_node) return unsigned_char_type_node; if (type1 == integer_type_node) return unsigned_type_node; if (type1 == short_integer_type_node) return short_unsigned_type_node; if (type1 == long_integer_type_node) return long_unsigned_type_node; if (type1 == long_long_integer_type_node) return long_long_unsigned_type_node; if (type1 == intDI_type_node) return unsigned_intDI_type_node; if (type1 == intSI_type_node) return unsigned_intSI_type_node; if (type1 == intHI_type_node) return unsigned_intHI_type_node; if (type1 == intQI_type_node) return unsigned_intQI_type_node; return signed_or_unsigned_type (1, type); } /* Return a signed type the same as TYPE in other respects. */ tree signed_type (type) tree type; { tree type1 = TYPE_MAIN_VARIANT (type); if (type1 == unsigned_char_type_node || type1 == char_type_node) return signed_char_type_node; if (type1 == unsigned_type_node) return integer_type_node; if (type1 == short_unsigned_type_node) return short_integer_type_node; if (type1 == long_unsigned_type_node) return long_integer_type_node; if (type1 == long_long_unsigned_type_node) return long_long_integer_type_node; if (type1 == unsigned_intDI_type_node) return intDI_type_node; if (type1 == unsigned_intSI_type_node) return intSI_type_node; if (type1 == unsigned_intHI_type_node) return intHI_type_node; if (type1 == unsigned_intQI_type_node) return intQI_type_node; return signed_or_unsigned_type (0, type); } /* Return a type the same as TYPE except unsigned or signed according to UNSIGNEDP. */ tree signed_or_unsigned_type (unsignedp, type) int unsignedp; tree type; { if ((! INTEGRAL_TYPE_P (type) && ! POINTER_TYPE_P (type)) || TREE_UNSIGNED (type) == unsignedp) return type; if (TYPE_PRECISION (type) == TYPE_PRECISION (signed_char_type_node)) return unsignedp ? unsigned_char_type_node : signed_char_type_node; if (TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node)) return unsignedp ? unsigned_type_node : integer_type_node; if (TYPE_PRECISION (type) == TYPE_PRECISION (short_integer_type_node)) return unsignedp ? short_unsigned_type_node : short_integer_type_node; if (TYPE_PRECISION (type) == TYPE_PRECISION (long_integer_type_node)) return unsignedp ? long_unsigned_type_node : long_integer_type_node; if (TYPE_PRECISION (type) == TYPE_PRECISION (long_long_integer_type_node)) return (unsignedp ? long_long_unsigned_type_node : long_long_integer_type_node); return type; } /* Compute the value of the `sizeof' operator. */ tree c_sizeof (type) tree type; { enum tree_code code = TREE_CODE (type); tree t; if (code == FUNCTION_TYPE) { if (pedantic || warn_pointer_arith) pedwarn ("sizeof applied to a function type"); return size_int (1); } if (code == VOID_TYPE) { if (pedantic || warn_pointer_arith) pedwarn ("sizeof applied to a void type"); return size_int (1); } if (code == ERROR_MARK) return size_int (1); if (TYPE_SIZE (type) == 0) { error ("sizeof applied to an incomplete type"); return size_int (0); } /* Convert in case a char is more than one unit. */ t = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type), size_int (TYPE_PRECISION (char_type_node))); t = convert (sizetype, t); /* size_binop does not put the constant in range, so do it now. */ if (TREE_CODE (t) == INTEGER_CST && force_fit_type (t, 0)) TREE_CONSTANT_OVERFLOW (t) = TREE_OVERFLOW (t) = 1; return t; } tree c_sizeof_nowarn (type) tree type; { enum tree_code code = TREE_CODE (type); tree t; if (code == FUNCTION_TYPE || code == VOID_TYPE || code == ERROR_MARK) return size_int (1); if (TYPE_SIZE (type) == 0) return size_int (0); /* Convert in case a char is more than one unit. */ t = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type), size_int (TYPE_PRECISION (char_type_node))); t = convert (sizetype, t); force_fit_type (t, 0); return t; } /* Compute the size to increment a pointer by. */ tree c_size_in_bytes (type) tree type; { enum tree_code code = TREE_CODE (type); tree t; if (code == FUNCTION_TYPE) return size_int (1); if (code == VOID_TYPE) return size_int (1); if (code == ERROR_MARK) return size_int (1); if (TYPE_SIZE (type) == 0) { error ("arithmetic on pointer to an incomplete type"); return size_int (1); } /* Convert in case a char is more than one unit. */ t = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type), size_int (BITS_PER_UNIT)); t = convert (sizetype, t); force_fit_type (t, 0); return t; } /* Implement the __alignof keyword: Return the minimum required alignment of TYPE, measured in bytes. */ tree c_alignof (type) tree type; { enum tree_code code = TREE_CODE (type); if (code == FUNCTION_TYPE) return size_int (FUNCTION_BOUNDARY / BITS_PER_UNIT); if (code == VOID_TYPE || code == ERROR_MARK) return size_int (1); return size_int (TYPE_ALIGN (type) / BITS_PER_UNIT); } /* Implement the __alignof keyword: Return the minimum required alignment of EXPR, measured in bytes. For VAR_DECL's and FIELD_DECL's return DECL_ALIGN (which can be set from an "aligned" __attribute__ specification). */ tree c_alignof_expr (expr) tree expr; { if (TREE_CODE (expr) == VAR_DECL) return size_int (DECL_ALIGN (expr) / BITS_PER_UNIT); if (TREE_CODE (expr) == COMPONENT_REF && DECL_C_BIT_FIELD (TREE_OPERAND (expr, 1))) { error ("`__alignof' applied to a bit-field"); return size_int (1); } else if (TREE_CODE (expr) == COMPONENT_REF && TREE_CODE (TREE_OPERAND (expr, 1)) == FIELD_DECL) return size_int (DECL_ALIGN (TREE_OPERAND (expr, 1)) / BITS_PER_UNIT); if (TREE_CODE (expr) == INDIRECT_REF) { tree t = TREE_OPERAND (expr, 0); tree best = t; int bestalign = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (t))); while (TREE_CODE (t) == NOP_EXPR && TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) == POINTER_TYPE) { int thisalign; t = TREE_OPERAND (t, 0); thisalign = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (t))); if (thisalign > bestalign) best = t, bestalign = thisalign; } return c_alignof (TREE_TYPE (TREE_TYPE (best))); } else return c_alignof (TREE_TYPE (expr)); } /* Return either DECL or its known constant value (if it has one). */ static tree decl_constant_value (decl) tree decl; { if (/* Don't change a variable array bound or initial value to a constant in a place where a variable is invalid. */ current_function_decl != 0 && ! pedantic && ! TREE_THIS_VOLATILE (decl) && TREE_READONLY (decl) && ! ITERATOR_P (decl) && DECL_INITIAL (decl) != 0 && TREE_CODE (DECL_INITIAL (decl)) != ERROR_MARK /* This is invalid if initial value is not constant. If it has either a function call, a memory reference, or a variable, then re-evaluating it could give different results. */ && TREE_CONSTANT (DECL_INITIAL (decl)) /* Check for cases where this is sub-optimal, even though valid. */ && TREE_CODE (DECL_INITIAL (decl)) != CONSTRUCTOR && DECL_MODE (decl) != BLKmode) return DECL_INITIAL (decl); return decl; } /* Perform default promotions for C data used in expressions. Arrays and functions are converted to pointers; enumeral types or short or char, to int. In addition, manifest constants symbols are replaced by their values. */ tree default_conversion (exp) tree exp; { register tree type = TREE_TYPE (exp); register enum tree_code code = TREE_CODE (type); /* Constants can be used directly unless they're not loadable. */ if (TREE_CODE (exp) == CONST_DECL) exp = DECL_INITIAL (exp); /* Replace a nonvolatile const static variable with its value unless it is an array, in which case we must be sure that taking the address of the array produces consistent results. */ else if (optimize && TREE_CODE (exp) == VAR_DECL && code != ARRAY_TYPE) { exp = decl_constant_value (exp); type = TREE_TYPE (exp); } /* Strip NON_LVALUE_EXPRs and no-op conversions, since we aren't using as an lvalue. */ /* Do not use STRIP_NOPS here! It will remove conversions from pointer to integer and cause infinite recursion. */ while (TREE_CODE (exp) == NON_LVALUE_EXPR || (TREE_CODE (exp) == NOP_EXPR && TREE_TYPE (TREE_OPERAND (exp, 0)) == TREE_TYPE (exp))) exp = TREE_OPERAND (exp, 0); /* Normally convert enums to int, but convert wide enums to something wider. */ if (code == ENUMERAL_TYPE) { type = type_for_size (MAX (TYPE_PRECISION (type), TYPE_PRECISION (integer_type_node)), ((flag_traditional || (TYPE_PRECISION (type) >= TYPE_PRECISION (integer_type_node))) && TREE_UNSIGNED (type))); return convert (type, exp); } if (TREE_CODE (exp) == COMPONENT_REF && DECL_C_BIT_FIELD (TREE_OPERAND (exp, 1))) { tree width = DECL_SIZE (TREE_OPERAND (exp, 1)); HOST_WIDE_INT low = TREE_INT_CST_LOW (width); /* If it's thinner than an int, promote it like a C_PROMOTING_INTEGER_TYPE_P, otherwise leave it alone. */ if (low < TYPE_PRECISION (integer_type_node)) { if (flag_traditional && TREE_UNSIGNED (type)) return convert (unsigned_type_node, exp); else return convert (integer_type_node, exp); } } if (C_PROMOTING_INTEGER_TYPE_P (type)) { /* Traditionally, unsignedness is preserved in default promotions. Also preserve unsignedness if not really getting any wider. */ if (TREE_UNSIGNED (type) && (flag_traditional || TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node))) return convert (unsigned_type_node, exp); return convert (integer_type_node, exp); } if (flag_traditional && !flag_allow_single_precision && TYPE_MAIN_VARIANT (type) == float_type_node) return convert (double_type_node, exp); if (code == VOID_TYPE) { error ("void value not ignored as it ought to be"); return error_mark_node; } if (code == FUNCTION_TYPE) { return build_unary_op (ADDR_EXPR, exp, 0); } if (code == ARRAY_TYPE) { register tree adr; tree restype = TREE_TYPE (type); tree ptrtype; int constp = 0; int volatilep = 0; if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'r' || TREE_CODE_CLASS (TREE_CODE (exp)) == 'd') { constp = TREE_READONLY (exp); volatilep = TREE_THIS_VOLATILE (exp); } if (TYPE_QUALS (type) || constp || volatilep) restype = c_build_qualified_type (restype, TYPE_QUALS (type) | (constp * TYPE_QUAL_CONST) | (volatilep * TYPE_QUAL_VOLATILE)); if (TREE_CODE (exp) == INDIRECT_REF) return convert (TYPE_POINTER_TO (restype), TREE_OPERAND (exp, 0)); if (TREE_CODE (exp) == COMPOUND_EXPR) { tree op1 = default_conversion (TREE_OPERAND (exp, 1)); return build (COMPOUND_EXPR, TREE_TYPE (op1), TREE_OPERAND (exp, 0), op1); } if (! lvalue_p (exp) && ! (TREE_CODE (exp) == CONSTRUCTOR && TREE_STATIC (exp))) { error ("invalid use of non-lvalue array"); return error_mark_node; } ptrtype = build_pointer_type (restype); if (TREE_CODE (exp) == VAR_DECL) { /* ??? This is not really quite correct in that the type of the operand of ADDR_EXPR is not the target type of the type of the ADDR_EXPR itself. Question is, can this lossage be avoided? */ adr = build1 (ADDR_EXPR, ptrtype, exp); if (mark_addressable (exp) == 0) return error_mark_node; TREE_CONSTANT (adr) = staticp (exp); TREE_SIDE_EFFECTS (adr) = 0; /* Default would be, same as EXP. */ return adr; } /* This way is better for a COMPONENT_REF since it can simplify the offset for a component. */ adr = build_unary_op (ADDR_EXPR, exp, 1); return convert (ptrtype, adr); } return exp; } /* Look up component name in the structure type definition. If this component name is found indirectly within an anonymous union, store in *INDIRECT the component which directly contains that anonymous union. Otherwise, set *INDIRECT to 0. */ static tree lookup_field (type, component, indirect) tree type, component; tree *indirect; { tree field; /* If TYPE_LANG_SPECIFIC is set, then it is a sorted array of pointers to the field elements. Use a binary search on this array to quickly find the element. Otherwise, do a linear search. TYPE_LANG_SPECIFIC will always be set for structures which have many elements. */ if (TYPE_LANG_SPECIFIC (type)) { int bot, top, half; tree *field_array = &TYPE_LANG_SPECIFIC (type)->elts[0]; field = TYPE_FIELDS (type); bot = 0; top = TYPE_LANG_SPECIFIC (type)->len; while (top - bot > 1) { half = (top - bot + 1) >> 1; field = field_array[bot+half]; if (DECL_NAME (field) == NULL_TREE) { /* Step through all anon unions in linear fashion. */ while (DECL_NAME (field_array[bot]) == NULL_TREE) { tree anon = 0, junk; field = field_array[bot++]; if (TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE || TREE_CODE (TREE_TYPE (field)) == UNION_TYPE) anon = lookup_field (TREE_TYPE (field), component, &junk); if (anon != NULL_TREE) { *indirect = field; return anon; } } /* Entire record is only anon unions. */ if (bot > top) return NULL_TREE; /* Restart the binary search, with new lower bound. */ continue; } if (DECL_NAME (field) == component) break; if (DECL_NAME (field) < component) bot += half; else top = bot + half; } if (DECL_NAME (field_array[bot]) == component) field = field_array[bot]; else if (DECL_NAME (field) != component) field = 0; } else { for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) { if (DECL_NAME (field) == NULL_TREE) { tree junk; tree anon = 0; if (TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE || TREE_CODE (TREE_TYPE (field)) == UNION_TYPE) anon = lookup_field (TREE_TYPE (field), component, &junk); if (anon != NULL_TREE) { *indirect = field; return anon; } } if (DECL_NAME (field) == component) break; } } *indirect = NULL_TREE; return field; } /* Make an expression to refer to the COMPONENT field of structure or union value DATUM. COMPONENT is an IDENTIFIER_NODE. */ tree build_component_ref (datum, component) tree datum, component; { register tree type = TREE_TYPE (datum); register enum tree_code code = TREE_CODE (type); register tree field = NULL; register tree ref; /* If DATUM is a COMPOUND_EXPR or COND_EXPR, move our reference inside it unless we are not to support things not strictly ANSI. */ switch (TREE_CODE (datum)) { case COMPOUND_EXPR: { tree value = build_component_ref (TREE_OPERAND (datum, 1), component); return build (COMPOUND_EXPR, TREE_TYPE (value), TREE_OPERAND (datum, 0), value); } case COND_EXPR: return build_conditional_expr (TREE_OPERAND (datum, 0), build_component_ref (TREE_OPERAND (datum, 1), component), build_component_ref (TREE_OPERAND (datum, 2), component)); default: break; } /* See if there is a field or component with name COMPONENT. */ if (code == RECORD_TYPE || code == UNION_TYPE) { tree indirect = 0; if (TYPE_SIZE (type) == 0) { incomplete_type_error (NULL_TREE, type); return error_mark_node; } field = lookup_field (type, component, &indirect); if (!field) { error (code == RECORD_TYPE ? "structure has no member named `%s'" : "union has no member named `%s'", IDENTIFIER_POINTER (component)); return error_mark_node; } if (TREE_TYPE (field) == error_mark_node) return error_mark_node; /* If FIELD was found buried within an anonymous union, make one COMPONENT_REF to get that anonymous union, then fall thru to make a second COMPONENT_REF to get FIELD. */ if (indirect != 0) { ref = build (COMPONENT_REF, TREE_TYPE (indirect), datum, indirect); if (TREE_READONLY (datum) || TREE_READONLY (indirect)) TREE_READONLY (ref) = 1; if (TREE_THIS_VOLATILE (datum) || TREE_THIS_VOLATILE (indirect)) TREE_THIS_VOLATILE (ref) = 1; datum = ref; } ref = build (COMPONENT_REF, TREE_TYPE (field), datum, field); if (TREE_READONLY (datum) || TREE_READONLY (field)) TREE_READONLY (ref) = 1; if (TREE_THIS_VOLATILE (datum) || TREE_THIS_VOLATILE (field)) TREE_THIS_VOLATILE (ref) = 1; return ref; } else if (code != ERROR_MARK) error ("request for member `%s' in something not a structure or union", IDENTIFIER_POINTER (component)); return error_mark_node; } /* Given an expression PTR for a pointer, return an expression for the value pointed to. ERRORSTRING is the name of the operator to appear in error messages. */ tree build_indirect_ref (ptr, errorstring) tree ptr; const char *errorstring; { register tree pointer = default_conversion (ptr); register tree type = TREE_TYPE (pointer); if (TREE_CODE (type) == POINTER_TYPE) { if (TREE_CODE (pointer) == ADDR_EXPR && !flag_volatile && (TREE_TYPE (TREE_OPERAND (pointer, 0)) == TREE_TYPE (type))) return TREE_OPERAND (pointer, 0); else { tree t = TREE_TYPE (type); register tree ref = build1 (INDIRECT_REF, TYPE_MAIN_VARIANT (t), pointer); if (TYPE_SIZE (t) == 0 && TREE_CODE (t) != ARRAY_TYPE) { error ("dereferencing pointer to incomplete type"); return error_mark_node; } if (TREE_CODE (t) == VOID_TYPE && skip_evaluation == 0) warning ("dereferencing `void *' pointer"); /* We *must* set TREE_READONLY when dereferencing a pointer to const, so that we get the proper error message if the result is used to assign to. Also, &* is supposed to be a no-op. And ANSI C seems to specify that the type of the result should be the const type. */ /* A de-reference of a pointer to const is not a const. It is valid to change it via some other pointer. */ TREE_READONLY (ref) = TYPE_READONLY (t); TREE_SIDE_EFFECTS (ref) = TYPE_VOLATILE (t) || TREE_SIDE_EFFECTS (pointer) || flag_volatile; TREE_THIS_VOLATILE (ref) = TYPE_VOLATILE (t); return ref; } } else if (TREE_CODE (pointer) != ERROR_MARK) error ("invalid type argument of `%s'", errorstring); return error_mark_node; } /* This handles expressions of the form "a[i]", which denotes an array reference. This is logically equivalent in C to *(a+i), but we may do it differently. If A is a variable or a member, we generate a primitive ARRAY_REF. This avoids forcing the array out of registers, and can work on arrays that are not lvalues (for example, members of structures returned by functions). */ tree build_array_ref (array, index) tree array, index; { if (index == 0) { error ("subscript missing in array reference"); return error_mark_node; } if (TREE_TYPE (array) == error_mark_node || TREE_TYPE (index) == error_mark_node) return error_mark_node; if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE && TREE_CODE (array) != INDIRECT_REF) { tree rval, type; /* Subscripting with type char is likely to lose on a machine where chars are signed. So warn on any machine, but optionally. Don't warn for unsigned char since that type is safe. Don't warn for signed char because anyone who uses that must have done so deliberately. */ if (warn_char_subscripts && TYPE_MAIN_VARIANT (TREE_TYPE (index)) == char_type_node) warning ("array subscript has type `char'"); /* Apply default promotions *after* noticing character types. */ index = default_conversion (index); /* Require integer *after* promotion, for sake of enums. */ if (TREE_CODE (TREE_TYPE (index)) != INTEGER_TYPE) { error ("array subscript is not an integer"); return error_mark_node; } /* An array that is indexed by a non-constant cannot be stored in a register; we must be able to do address arithmetic on its address. Likewise an array of elements of variable size. */ if (TREE_CODE (index) != INTEGER_CST || (TYPE_SIZE (TREE_TYPE (TREE_TYPE (array))) != 0 && TREE_CODE (TYPE_SIZE (TREE_TYPE (TREE_TYPE (array)))) != INTEGER_CST)) { if (mark_addressable (array) == 0) return error_mark_node; } /* An array that is indexed by a constant value which is not within the array bounds cannot be stored in a register either; because we would get a crash in store_bit_field/extract_bit_field when trying to access a non-existent part of the register. */ if (TREE_CODE (index) == INTEGER_CST && TYPE_VALUES (TREE_TYPE (array)) && ! int_fits_type_p (index, TYPE_VALUES (TREE_TYPE (array)))) { if (mark_addressable (array) == 0) return error_mark_node; } if (pedantic && !lvalue_p (array)) { if (DECL_REGISTER (array)) pedwarn ("ANSI C forbids subscripting `register' array"); else pedwarn ("ANSI C forbids subscripting non-lvalue array"); } if (pedantic) { tree foo = array; while (TREE_CODE (foo) == COMPONENT_REF) foo = TREE_OPERAND (foo, 0); if (TREE_CODE (foo) == VAR_DECL && DECL_REGISTER (foo)) pedwarn ("ANSI C forbids subscripting non-lvalue array"); } type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (array))); rval = build (ARRAY_REF, type, array, index); /* Array ref is const/volatile if the array elements are or if the array is. */ TREE_READONLY (rval) |= (TYPE_READONLY (TREE_TYPE (TREE_TYPE (array))) | TREE_READONLY (array)); TREE_SIDE_EFFECTS (rval) |= (TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (array))) | TREE_SIDE_EFFECTS (array)); TREE_THIS_VOLATILE (rval) |= (TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (array))) /* This was added by rms on 16 Nov 91. It fixes vol struct foo *a; a->elts[1] in an inline function. Hope it doesn't break something else. */ | TREE_THIS_VOLATILE (array)); return require_complete_type (fold (rval)); } { tree ar = default_conversion (array); tree ind = default_conversion (index); /* Do the same warning check as above, but only on the part that's syntactically the index and only if it is also semantically the index. */ if (warn_char_subscripts && TREE_CODE (TREE_TYPE (index)) == INTEGER_TYPE && TYPE_MAIN_VARIANT (TREE_TYPE (index)) == char_type_node) warning ("subscript has type `char'"); /* Put the integer in IND to simplify error checking. */ if (TREE_CODE (TREE_TYPE (ar)) == INTEGER_TYPE) { tree temp = ar; ar = ind; ind = temp; } if (ar == error_mark_node) return ar; if (TREE_CODE (TREE_TYPE (ar)) != POINTER_TYPE || TREE_CODE (TREE_TYPE (TREE_TYPE (ar))) == FUNCTION_TYPE) { error ("subscripted value is neither array nor pointer"); return error_mark_node; } if (TREE_CODE (TREE_TYPE (ind)) != INTEGER_TYPE) { error ("array subscript is not an integer"); return error_mark_node; } return build_indirect_ref (build_binary_op (PLUS_EXPR, ar, ind, 0), "array indexing"); } } /* Build a function call to function FUNCTION with parameters PARAMS. PARAMS is a list--a chain of TREE_LIST nodes--in which the TREE_VALUE of each node is a parameter-expression. FUNCTION's data type may be a function type or a pointer-to-function. */ tree build_function_call (function, params) tree function, params; { register tree fntype, fundecl = 0; register tree coerced_params; tree name = NULL_TREE, assembler_name = NULL_TREE; /* Strip NON_LVALUE_EXPRs, etc., since we aren't using as an lvalue. */ STRIP_TYPE_NOPS (function); /* Convert anything with function type to a pointer-to-function. */ if (TREE_CODE (function) == FUNCTION_DECL) { name = DECL_NAME (function); assembler_name = DECL_ASSEMBLER_NAME (function); /* Differs from default_conversion by not setting TREE_ADDRESSABLE (because calling an inline function does not mean the function needs to be separately compiled). */ fntype = build_type_variant (TREE_TYPE (function), TREE_READONLY (function), TREE_THIS_VOLATILE (function)); fundecl = function; function = build1 (ADDR_EXPR, build_pointer_type (fntype), function); } else function = default_conversion (function); fntype = TREE_TYPE (function); if (TREE_CODE (fntype) == ERROR_MARK) return error_mark_node; if (!(TREE_CODE (fntype) == POINTER_TYPE && TREE_CODE (TREE_TYPE (fntype)) == FUNCTION_TYPE)) { error ("called object is not a function"); return error_mark_node; } /* fntype now gets the type of function pointed to. */ fntype = TREE_TYPE (fntype); /* Convert the parameters to the types declared in the function prototype, or apply default promotions. */ coerced_params = convert_arguments (TYPE_ARG_TYPES (fntype), params, name, fundecl); /* Check for errors in format strings. */ if (warn_format && (name || assembler_name)) check_function_format (name, assembler_name, coerced_params); /* Recognize certain built-in functions so we can make tree-codes other than CALL_EXPR. We do this when it enables fold-const.c to do something useful. */ if (TREE_CODE (function) == ADDR_EXPR && TREE_CODE (TREE_OPERAND (function, 0)) == FUNCTION_DECL && DECL_BUILT_IN (TREE_OPERAND (function, 0))) switch (DECL_FUNCTION_CODE (TREE_OPERAND (function, 0))) { case BUILT_IN_ABS: case BUILT_IN_LABS: case BUILT_IN_FABS: if (coerced_params == 0) return integer_zero_node; return build_unary_op (ABS_EXPR, TREE_VALUE (coerced_params), 0); default: break; } { register tree result = build (CALL_EXPR, TREE_TYPE (fntype), function, coerced_params, NULL_TREE); TREE_SIDE_EFFECTS (result) = 1; if (TREE_TYPE (result) == void_type_node) return result; return require_complete_type (result); } } /* Convert the argument expressions in the list VALUES to the types in the list TYPELIST. The result is a list of converted argument expressions. If TYPELIST is exhausted, or when an element has NULL as its type, perform the default conversions. PARMLIST is the chain of parm decls for the function being called. It may be 0, if that info is not available. It is used only for generating error messages. NAME is an IDENTIFIER_NODE or 0. It is used only for error messages. This is also where warnings about wrong number of args are generated. Both VALUES and the returned value are chains of TREE_LIST nodes with the elements of the list in the TREE_VALUE slots of those nodes. */ static tree convert_arguments (typelist, values, name, fundecl) tree typelist, values, name, fundecl; { register tree typetail, valtail; register tree result = NULL; int parmnum; /* Scan the given expressions and types, producing individual converted arguments and pushing them on RESULT in reverse order. */ for (valtail = values, typetail = typelist, parmnum = 0; valtail; valtail = TREE_CHAIN (valtail), parmnum++) { register tree type = typetail ? TREE_VALUE (typetail) : 0; register tree val = TREE_VALUE (valtail); if (type == void_type_node) { if (name) error ("too many arguments to function `%s'", IDENTIFIER_POINTER (name)); else error ("too many arguments to function"); break; } /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue. */ /* Do not use STRIP_NOPS here! We do not want an enumerator with value 0 to convert automatically to a pointer. */ if (TREE_CODE (val) == NON_LVALUE_EXPR) val = TREE_OPERAND (val, 0); if (TREE_CODE (TREE_TYPE (val)) == ARRAY_TYPE || TREE_CODE (TREE_TYPE (val)) == FUNCTION_TYPE) val = default_conversion (val); val = require_complete_type (val); if (type != 0) { /* Formal parm type is specified by a function prototype. */ tree parmval; if (TYPE_SIZE (type) == 0) { error ("type of formal parameter %d is incomplete", parmnum + 1); parmval = val; } else { /* Optionally warn about conversions that differ from the default conversions. */ if (warn_conversion) { int formal_prec = TYPE_PRECISION (type); if (INTEGRAL_TYPE_P (type) && TREE_CODE (TREE_TYPE (val)) == REAL_TYPE) warn_for_assignment ("%s as integer rather than floating due to prototype", (char *) 0, name, parmnum + 1); else if (TREE_CODE (type) == COMPLEX_TYPE && TREE_CODE (TREE_TYPE (val)) == REAL_TYPE) warn_for_assignment ("%s as complex rather than floating due to prototype", (char *) 0, name, parmnum + 1); else if (TREE_CODE (type) == REAL_TYPE && INTEGRAL_TYPE_P (TREE_TYPE (val))) warn_for_assignment ("%s as floating rather than integer due to prototype", (char *) 0, name, parmnum + 1); else if (TREE_CODE (type) == REAL_TYPE && TREE_CODE (TREE_TYPE (val)) == COMPLEX_TYPE) warn_for_assignment ("%s as floating rather than complex due to prototype", (char *) 0, name, parmnum + 1); /* ??? At some point, messages should be written about conversions between complex types, but that's too messy to do now. */ else if (TREE_CODE (type) == REAL_TYPE && TREE_CODE (TREE_TYPE (val)) == REAL_TYPE) { /* Warn if any argument is passed as `float', since without a prototype it would be `double'. */ if (formal_prec == TYPE_PRECISION (float_type_node)) warn_for_assignment ("%s as `float' rather than `double' due to prototype", (char *) 0, name, parmnum + 1); } /* Detect integer changing in width or signedness. */ else if (INTEGRAL_TYPE_P (type) && INTEGRAL_TYPE_P (TREE_TYPE (val))) { tree would_have_been = default_conversion (val); tree type1 = TREE_TYPE (would_have_been); if (TREE_CODE (type) == ENUMERAL_TYPE && type == TREE_TYPE (val)) /* No warning if function asks for enum and the actual arg is that enum type. */ ; else if (formal_prec != TYPE_PRECISION (type1)) warn_for_assignment ("%s with different width due to prototype", (char *) 0, name, parmnum + 1); else if (TREE_UNSIGNED (type) == TREE_UNSIGNED (type1)) ; /* Don't complain if the formal parameter type is an enum, because we can't tell now whether the value was an enum--even the same enum. */ else if (TREE_CODE (type) == ENUMERAL_TYPE) ; else if (TREE_CODE (val) == INTEGER_CST && int_fits_type_p (val, type)) /* Change in signedness doesn't matter if a constant value is unaffected. */ ; /* Likewise for a constant in a NOP_EXPR. */ else if (TREE_CODE (val) == NOP_EXPR && TREE_CODE (TREE_OPERAND (val, 0)) == INTEGER_CST && int_fits_type_p (TREE_OPERAND (val, 0), type)) ; #if 0 /* We never get such tree structure here. */ else if (TREE_CODE (TREE_TYPE (val)) == ENUMERAL_TYPE && int_fits_type_p (TYPE_MIN_VALUE (TREE_TYPE (val)), type) && int_fits_type_p (TYPE_MAX_VALUE (TREE_TYPE (val)), type)) /* Change in signedness doesn't matter if an enum value is unaffected. */ ; #endif /* If the value is extended from a narrower unsigned type, it doesn't matter whether we pass it as signed or unsigned; the value certainly is the same either way. */ else if (TYPE_PRECISION (TREE_TYPE (val)) < TYPE_PRECISION (type) && TREE_UNSIGNED (TREE_TYPE (val))) ; else if (TREE_UNSIGNED (type)) warn_for_assignment ("%s as unsigned due to prototype", (char *) 0, name, parmnum + 1); else warn_for_assignment ("%s as signed due to prototype", (char *) 0, name, parmnum + 1); } } parmval = convert_for_assignment (type, val, (char *) 0, /* arg passing */ fundecl, name, parmnum + 1); #ifdef PROMOTE_PROTOTYPES if ((TREE_CODE (type) == INTEGER_TYPE || TREE_CODE (type) == ENUMERAL_TYPE) && (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))) parmval = default_conversion (parmval); #endif } result = tree_cons (NULL_TREE, parmval, result); } else if (TREE_CODE (TREE_TYPE (val)) == REAL_TYPE && (TYPE_PRECISION (TREE_TYPE (val)) < TYPE_PRECISION (double_type_node))) /* Convert `float' to `double'. */ result = tree_cons (NULL_TREE, convert (double_type_node, val), result); else /* Convert `short' and `char' to full-size `int'. */ result = tree_cons (NULL_TREE, default_conversion (val), result); if (typetail) typetail = TREE_CHAIN (typetail); } if (typetail != 0 && TREE_VALUE (typetail) != void_type_node) { if (name) error ("too few arguments to function `%s'", IDENTIFIER_POINTER (name)); else error ("too few arguments to function"); } return nreverse (result); } /* This is the entry point used by the parser for binary operators in the input. In addition to constructing the expression, we check for operands that were written with other binary operators in a way that is likely to confuse the user. */ tree parser_build_binary_op (code, arg1, arg2) enum tree_code code; tree arg1, arg2; { tree result = build_binary_op (code, arg1, arg2, 1); char class; char class1 = TREE_CODE_CLASS (TREE_CODE (arg1)); char class2 = TREE_CODE_CLASS (TREE_CODE (arg2)); enum tree_code code1 = ERROR_MARK; enum tree_code code2 = ERROR_MARK; if (class1 == 'e' || class1 == '1' || class1 == '2' || class1 == '<') code1 = C_EXP_ORIGINAL_CODE (arg1); if (class2 == 'e' || class2 == '1' || class2 == '2' || class2 == '<') code2 = C_EXP_ORIGINAL_CODE (arg2); /* Check for cases such as x+y< TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op1, 0))) && TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op1, 0)))) { final_type = result_type; op1 = TREE_OPERAND (op1, 0); result_type = TREE_TYPE (op1); } if (TREE_CODE (op1) == INTEGER_CST && TREE_CODE (op0) == NOP_EXPR && TYPE_PRECISION (type0) > TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op0, 0))) && TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op0, 0)))) { final_type = result_type; op0 = TREE_OPERAND (op0, 0); result_type = TREE_TYPE (op0); } break; case TRUNC_MOD_EXPR: case FLOOR_MOD_EXPR: if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE) { /* Although it would be tempting to shorten always here, that loses on some targets, since the modulo instruction is undefined if the quotient can't be represented in the computation mode. We shorten only if unsigned or if dividing by something we know != -1. */ shorten = (TREE_UNSIGNED (TREE_TYPE (orig_op0)) || (TREE_CODE (op1) == INTEGER_CST && (TREE_INT_CST_LOW (op1) != -1 || TREE_INT_CST_HIGH (op1) != -1))); common = 1; } break; case TRUTH_ANDIF_EXPR: case TRUTH_ORIF_EXPR: case TRUTH_AND_EXPR: case TRUTH_OR_EXPR: case TRUTH_XOR_EXPR: if ((code0 == INTEGER_TYPE || code0 == POINTER_TYPE || code0 == REAL_TYPE || code0 == COMPLEX_TYPE) && (code1 == INTEGER_TYPE || code1 == POINTER_TYPE || code1 == REAL_TYPE || code1 == COMPLEX_TYPE)) { /* Result of these operations is always an int, but that does not mean the operands should be converted to ints! */ result_type = integer_type_node; op0 = truthvalue_conversion (op0); op1 = truthvalue_conversion (op1); converted = 1; } break; /* Shift operations: result has same type as first operand; always convert second operand to int. Also set SHORT_SHIFT if shifting rightward. */ case RSHIFT_EXPR: if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE) { if (TREE_CODE (op1) == INTEGER_CST && skip_evaluation == 0) { if (tree_int_cst_sgn (op1) < 0) warning ("right shift count is negative"); else { if (TREE_INT_CST_LOW (op1) | TREE_INT_CST_HIGH (op1)) short_shift = 1; if (TREE_INT_CST_HIGH (op1) != 0 || ((unsigned HOST_WIDE_INT) TREE_INT_CST_LOW (op1) >= TYPE_PRECISION (type0))) warning ("right shift count >= width of type"); } } /* Use the type of the value to be shifted. This is what most traditional C compilers do. */ result_type = type0; /* Unless traditional, convert the shift-count to an integer, regardless of size of value being shifted. */ if (! flag_traditional) { if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node) op1 = convert (integer_type_node, op1); /* Avoid converting op1 to result_type later. */ converted = 1; } } break; case LSHIFT_EXPR: if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE) { if (TREE_CODE (op1) == INTEGER_CST && skip_evaluation == 0) { if (tree_int_cst_sgn (op1) < 0) warning ("left shift count is negative"); else if (TREE_INT_CST_HIGH (op1) != 0 || ((unsigned HOST_WIDE_INT) TREE_INT_CST_LOW (op1) >= TYPE_PRECISION (type0))) warning ("left shift count >= width of type"); } /* Use the type of the value to be shifted. This is what most traditional C compilers do. */ result_type = type0; /* Unless traditional, convert the shift-count to an integer, regardless of size of value being shifted. */ if (! flag_traditional) { if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node) op1 = convert (integer_type_node, op1); /* Avoid converting op1 to result_type later. */ converted = 1; } } break; case RROTATE_EXPR: case LROTATE_EXPR: if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE) { if (TREE_CODE (op1) == INTEGER_CST && skip_evaluation == 0) { if (tree_int_cst_sgn (op1) < 0) warning ("shift count is negative"); else if (TREE_INT_CST_HIGH (op1) != 0 || ((unsigned HOST_WIDE_INT) TREE_INT_CST_LOW (op1) >= TYPE_PRECISION (type0))) warning ("shift count >= width of type"); } /* Use the type of the value to be shifted. This is what most traditional C compilers do. */ result_type = type0; /* Unless traditional, convert the shift-count to an integer, regardless of size of value being shifted. */ if (! flag_traditional) { if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node) op1 = convert (integer_type_node, op1); /* Avoid converting op1 to result_type later. */ converted = 1; } } break; case EQ_EXPR: case NE_EXPR: /* Result of comparison is always int, but don't convert the args to int! */ build_type = integer_type_node; if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE || code0 == COMPLEX_TYPE) && (code1 == INTEGER_TYPE || code1 == REAL_TYPE || code1 == COMPLEX_TYPE)) short_compare = 1; else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE) { register tree tt0 = TREE_TYPE (type0); register tree tt1 = TREE_TYPE (type1); /* Anything compares with void *. void * compares with anything. Otherwise, the targets must be compatible and both must be object or both incomplete. */ if (comp_target_types (type0, type1)) result_type = common_type (type0, type1); else if (TYPE_MAIN_VARIANT (tt0) == void_type_node) { /* op0 != orig_op0 detects the case of something whose value is 0 but which isn't a valid null ptr const. */ if (pedantic && (!integer_zerop (op0) || op0 != orig_op0) && TREE_CODE (tt1) == FUNCTION_TYPE) pedwarn ("ANSI C forbids comparison of `void *' with function pointer"); } else if (TYPE_MAIN_VARIANT (tt1) == void_type_node) { if (pedantic && (!integer_zerop (op1) || op1 != orig_op1) && TREE_CODE (tt0) == FUNCTION_TYPE) pedwarn ("ANSI C forbids comparison of `void *' with function pointer"); } else pedwarn ("comparison of distinct pointer types lacks a cast"); if (result_type == NULL_TREE) result_type = ptr_type_node; } else if (code0 == POINTER_TYPE && TREE_CODE (op1) == INTEGER_CST && integer_zerop (op1)) result_type = type0; else if (code1 == POINTER_TYPE && TREE_CODE (op0) == INTEGER_CST && integer_zerop (op0)) result_type = type1; else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE) { result_type = type0; if (! flag_traditional) pedwarn ("comparison between pointer and integer"); } else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE) { result_type = type1; if (! flag_traditional) pedwarn ("comparison between pointer and integer"); } break; case MAX_EXPR: case MIN_EXPR: if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE) && (code1 == INTEGER_TYPE || code1 == REAL_TYPE)) shorten = 1; else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE) { if (comp_target_types (type0, type1)) { result_type = common_type (type0, type1); if (pedantic && TREE_CODE (TREE_TYPE (type0)) == FUNCTION_TYPE) pedwarn ("ANSI C forbids ordered comparisons of pointers to functions"); } else { result_type = ptr_type_node; pedwarn ("comparison of distinct pointer types lacks a cast"); } } break; case LE_EXPR: case GE_EXPR: case LT_EXPR: case GT_EXPR: build_type = integer_type_node; if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE) && (code1 == INTEGER_TYPE || code1 == REAL_TYPE)) short_compare = 1; else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE) { if (comp_target_types (type0, type1)) { result_type = common_type (type0, type1); if ((TYPE_SIZE (TREE_TYPE (type0)) != 0) != (TYPE_SIZE (TREE_TYPE (type1)) != 0)) pedwarn ("comparison of complete and incomplete pointers"); else if (pedantic && TREE_CODE (TREE_TYPE (type0)) == FUNCTION_TYPE) pedwarn ("ANSI C forbids ordered comparisons of pointers to functions"); } else { result_type = ptr_type_node; pedwarn ("comparison of distinct pointer types lacks a cast"); } } else if (code0 == POINTER_TYPE && TREE_CODE (op1) == INTEGER_CST && integer_zerop (op1)) { result_type = type0; if (pedantic || extra_warnings) pedwarn ("ordered comparison of pointer with integer zero"); } else if (code1 == POINTER_TYPE && TREE_CODE (op0) == INTEGER_CST && integer_zerop (op0)) { result_type = type1; if (pedantic) pedwarn ("ordered comparison of pointer with integer zero"); } else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE) { result_type = type0; if (! flag_traditional) pedwarn ("comparison between pointer and integer"); } else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE) { result_type = type1; if (! flag_traditional) pedwarn ("comparison between pointer and integer"); } break; default: break; } if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE || code0 == COMPLEX_TYPE) && (code1 == INTEGER_TYPE || code1 == REAL_TYPE || code1 == COMPLEX_TYPE)) { int none_complex = (code0 != COMPLEX_TYPE && code1 != COMPLEX_TYPE); if (shorten || common || short_compare) result_type = common_type (type0, type1); /* For certain operations (which identify themselves by shorten != 0) if both args were extended from the same smaller type, do the arithmetic in that type and then extend. shorten !=0 and !=1 indicates a bitwise operation. For them, this optimization is safe only if both args are zero-extended or both are sign-extended. Otherwise, we might change the result. Eg, (short)-1 | (unsigned short)-1 is (int)-1 but calculated in (unsigned short) it would be (unsigned short)-1. */ if (shorten && none_complex) { int unsigned0, unsigned1; tree arg0 = get_narrower (op0, &unsigned0); tree arg1 = get_narrower (op1, &unsigned1); /* UNS is 1 if the operation to be done is an unsigned one. */ int uns = TREE_UNSIGNED (result_type); tree type; final_type = result_type; /* Handle the case that OP0 (or OP1) does not *contain* a conversion but it *requires* conversion to FINAL_TYPE. */ if ((TYPE_PRECISION (TREE_TYPE (op0)) == TYPE_PRECISION (TREE_TYPE (arg0))) && TREE_TYPE (op0) != final_type) unsigned0 = TREE_UNSIGNED (TREE_TYPE (op0)); if ((TYPE_PRECISION (TREE_TYPE (op1)) == TYPE_PRECISION (TREE_TYPE (arg1))) && TREE_TYPE (op1) != final_type) unsigned1 = TREE_UNSIGNED (TREE_TYPE (op1)); /* Now UNSIGNED0 is 1 if ARG0 zero-extends to FINAL_TYPE. */ /* For bitwise operations, signedness of nominal type does not matter. Consider only how operands were extended. */ if (shorten == -1) uns = unsigned0; /* Note that in all three cases below we refrain from optimizing an unsigned operation on sign-extended args. That would not be valid. */ /* Both args variable: if both extended in same way from same width, do it in that width. Do it unsigned if args were zero-extended. */ if ((TYPE_PRECISION (TREE_TYPE (arg0)) < TYPE_PRECISION (result_type)) && (TYPE_PRECISION (TREE_TYPE (arg1)) == TYPE_PRECISION (TREE_TYPE (arg0))) && unsigned0 == unsigned1 && (unsigned0 || !uns)) result_type = signed_or_unsigned_type (unsigned0, common_type (TREE_TYPE (arg0), TREE_TYPE (arg1))); else if (TREE_CODE (arg0) == INTEGER_CST && (unsigned1 || !uns) && (TYPE_PRECISION (TREE_TYPE (arg1)) < TYPE_PRECISION (result_type)) && (type = signed_or_unsigned_type (unsigned1, TREE_TYPE (arg1)), int_fits_type_p (arg0, type))) result_type = type; else if (TREE_CODE (arg1) == INTEGER_CST && (unsigned0 || !uns) && (TYPE_PRECISION (TREE_TYPE (arg0)) < TYPE_PRECISION (result_type)) && (type = signed_or_unsigned_type (unsigned0, TREE_TYPE (arg0)), int_fits_type_p (arg1, type))) result_type = type; } /* Shifts can be shortened if shifting right. */ if (short_shift) { int unsigned_arg; tree arg0 = get_narrower (op0, &unsigned_arg); final_type = result_type; if (arg0 == op0 && final_type == TREE_TYPE (op0)) unsigned_arg = TREE_UNSIGNED (TREE_TYPE (op0)); if (TYPE_PRECISION (TREE_TYPE (arg0)) < TYPE_PRECISION (result_type) /* We can shorten only if the shift count is less than the number of bits in the smaller type size. */ && TREE_INT_CST_HIGH (op1) == 0 && TYPE_PRECISION (TREE_TYPE (arg0)) > TREE_INT_CST_LOW (op1) /* If arg is sign-extended and then unsigned-shifted, we can simulate this with a signed shift in arg's type only if the extended result is at least twice as wide as the arg. Otherwise, the shift could use up all the ones made by sign-extension and bring in zeros. We can't optimize that case at all, but in most machines it never happens because available widths are 2**N. */ && (!TREE_UNSIGNED (final_type) || unsigned_arg || 2 * TYPE_PRECISION (TREE_TYPE (arg0)) <= TYPE_PRECISION (result_type))) { /* Do an unsigned shift if the operand was zero-extended. */ result_type = signed_or_unsigned_type (unsigned_arg, TREE_TYPE (arg0)); /* Convert value-to-be-shifted to that type. */ if (TREE_TYPE (op0) != result_type) op0 = convert (result_type, op0); converted = 1; } } /* Comparison operations are shortened too but differently. They identify themselves by setting short_compare = 1. */ if (short_compare) { /* Don't write &op0, etc., because that would prevent op0 from being kept in a register. Instead, make copies of the our local variables and pass the copies by reference, then copy them back afterward. */ tree xop0 = op0, xop1 = op1, xresult_type = result_type; enum tree_code xresultcode = resultcode; tree val = shorten_compare (&xop0, &xop1, &xresult_type, &xresultcode); if (val != 0) return val; op0 = xop0, op1 = xop1; converted = 1; resultcode = xresultcode; if ((warn_sign_compare < 0 ? extra_warnings : warn_sign_compare != 0) && skip_evaluation == 0) { int op0_signed = ! TREE_UNSIGNED (TREE_TYPE (orig_op0)); int op1_signed = ! TREE_UNSIGNED (TREE_TYPE (orig_op1)); int unsignedp0, unsignedp1; tree primop0 = get_narrower (op0, &unsignedp0); tree primop1 = get_narrower (op1, &unsignedp1); /* Avoid spurious warnings for comparison with enumerators. */ xop0 = orig_op0; xop1 = orig_op1; STRIP_TYPE_NOPS (xop0); STRIP_TYPE_NOPS (xop1); /* Give warnings for comparisons between signed and unsigned quantities that may fail. */ /* Do the checking based on the original operand trees, so that casts will be considered, but default promotions won't be. */ /* Do not warn if the comparison is being done in a signed type, since the signed type will only be chosen if it can represent all the values of the unsigned type. */ if (! TREE_UNSIGNED (result_type)) /* OK */; /* Do not warn if both operands are unsigned. */ else if (op0_signed == op1_signed) /* OK */; /* Do not warn if the signed quantity is an unsuffixed integer literal (or some static constant expression involving such literals) and it is non-negative. */ else if ((op0_signed && TREE_CODE (xop0) == INTEGER_CST && tree_int_cst_sgn (xop0) >= 0) || (op1_signed && TREE_CODE (xop1) == INTEGER_CST && tree_int_cst_sgn (xop1) >= 0)) /* OK */; /* Do not warn if the comparison is an equality operation, the unsigned quantity is an integral constant and it does not use the most significant bit of result_type. */ else if ((resultcode == EQ_EXPR || resultcode == NE_EXPR) && ((op0_signed && TREE_CODE (xop1) == INTEGER_CST && int_fits_type_p (xop1, signed_type (result_type))) || (op1_signed && TREE_CODE (xop0) == INTEGER_CST && int_fits_type_p (xop0, signed_type (result_type))))) /* OK */; else warning ("comparison between signed and unsigned"); /* Warn if two unsigned values are being compared in a size larger than their original size, and one (and only one) is the result of a `~' operator. This comparison will always fail. Also warn if one operand is a constant, and the constant does not have all bits set that are set in the ~ operand when it is extended. */ if ((TREE_CODE (primop0) == BIT_NOT_EXPR) != (TREE_CODE (primop1) == BIT_NOT_EXPR)) { if (TREE_CODE (primop0) == BIT_NOT_EXPR) primop0 = get_narrower (TREE_OPERAND (primop0, 0), &unsignedp0); else primop1 = get_narrower (TREE_OPERAND (primop1, 0), &unsignedp1); if (TREE_CODE (primop0) == INTEGER_CST || TREE_CODE (primop1) == INTEGER_CST) { tree primop; long constant, mask; int unsignedp, bits; if (TREE_CODE (primop0) == INTEGER_CST) { primop = primop1; unsignedp = unsignedp1; constant = TREE_INT_CST_LOW (primop0); } else { primop = primop0; unsignedp = unsignedp0; constant = TREE_INT_CST_LOW (primop1); } bits = TYPE_PRECISION (TREE_TYPE (primop)); if (bits < TYPE_PRECISION (result_type) && bits < HOST_BITS_PER_LONG && unsignedp) { mask = (~0L) << bits; if ((mask & constant) != mask) warning ("comparison of promoted ~unsigned with constant"); } } else if (unsignedp0 && unsignedp1 && (TYPE_PRECISION (TREE_TYPE (primop0)) < TYPE_PRECISION (result_type)) && (TYPE_PRECISION (TREE_TYPE (primop1)) < TYPE_PRECISION (result_type))) warning ("comparison of promoted ~unsigned with unsigned"); } } } } /* At this point, RESULT_TYPE must be nonzero to avoid an error message. If CONVERTED is zero, both args will be converted to type RESULT_TYPE. Then the expression will be built. It will be given type FINAL_TYPE if that is nonzero; otherwise, it will be given type RESULT_TYPE. */ if (!result_type) { binary_op_error (code); return error_mark_node; } if (! converted) { if (TREE_TYPE (op0) != result_type) op0 = convert (result_type, op0); if (TREE_TYPE (op1) != result_type) op1 = convert (result_type, op1); } if (build_type == NULL_TREE) build_type = result_type; { register tree result = build (resultcode, build_type, op0, op1); register tree folded; folded = fold (result); if (folded == result) TREE_CONSTANT (folded) = TREE_CONSTANT (op0) & TREE_CONSTANT (op1); if (final_type != 0) return convert (final_type, folded); return folded; } } /* Return a tree for the sum or difference (RESULTCODE says which) of pointer PTROP and integer INTOP. */ static tree pointer_int_sum (resultcode, ptrop, intop) enum tree_code resultcode; register tree ptrop, intop; { tree size_exp; register tree result; register tree folded; /* The result is a pointer of the same type that is being added. */ register tree result_type = TREE_TYPE (ptrop); if (TREE_CODE (TREE_TYPE (result_type)) == VOID_TYPE) { if (pedantic || warn_pointer_arith) pedwarn ("pointer of type `void *' used in arithmetic"); size_exp = integer_one_node; } else if (TREE_CODE (TREE_TYPE (result_type)) == FUNCTION_TYPE) { if (pedantic || warn_pointer_arith) pedwarn ("pointer to a function used in arithmetic"); size_exp = integer_one_node; } else size_exp = c_size_in_bytes (TREE_TYPE (result_type)); /* If what we are about to multiply by the size of the elements contains a constant term, apply distributive law and multiply that constant term separately. This helps produce common subexpressions. */ if ((TREE_CODE (intop) == PLUS_EXPR || TREE_CODE (intop) == MINUS_EXPR) && ! TREE_CONSTANT (intop) && TREE_CONSTANT (TREE_OPERAND (intop, 1)) && TREE_CONSTANT (size_exp) /* If the constant comes from pointer subtraction, skip this optimization--it would cause an error. */ && TREE_CODE (TREE_TYPE (TREE_OPERAND (intop, 0))) == INTEGER_TYPE /* If the constant is unsigned, and smaller than the pointer size, then we must skip this optimization. This is because it could cause an overflow error if the constant is negative but INTOP is not. */ && (! TREE_UNSIGNED (TREE_TYPE (intop)) || (TYPE_PRECISION (TREE_TYPE (intop)) == TYPE_PRECISION (TREE_TYPE (ptrop))))) { enum tree_code subcode = resultcode; tree int_type = TREE_TYPE (intop); if (TREE_CODE (intop) == MINUS_EXPR) subcode = (subcode == PLUS_EXPR ? MINUS_EXPR : PLUS_EXPR); /* Convert both subexpression types to the type of intop, because weird cases involving pointer arithmetic can result in a sum or difference with different type args. */ ptrop = build_binary_op (subcode, ptrop, convert (int_type, TREE_OPERAND (intop, 1)), 1); intop = convert (int_type, TREE_OPERAND (intop, 0)); } /* Convert the integer argument to a type the same size as sizetype so the multiply won't overflow spuriously. */ if (TYPE_PRECISION (TREE_TYPE (intop)) != TYPE_PRECISION (sizetype) || TREE_UNSIGNED (TREE_TYPE (intop)) != TREE_UNSIGNED (sizetype)) intop = convert (type_for_size (TYPE_PRECISION (sizetype), TREE_UNSIGNED (sizetype)), intop); /* Replace the integer argument with a suitable product by the object size. Do this multiplication as signed, then convert to the appropriate pointer type (actually unsigned integral). */ intop = convert (result_type, build_binary_op (MULT_EXPR, intop, convert (TREE_TYPE (intop), size_exp), 1)); /* Create the sum or difference. */ result = build (resultcode, result_type, ptrop, intop); folded = fold (result); if (folded == result) TREE_CONSTANT (folded) = TREE_CONSTANT (ptrop) & TREE_CONSTANT (intop); return folded; } /* Return a tree for the difference of pointers OP0 and OP1. The resulting tree has type int. */ static tree pointer_diff (op0, op1) register tree op0, op1; { register tree result, folded; tree restype = ptrdiff_type_node; tree target_type = TREE_TYPE (TREE_TYPE (op0)); if (pedantic || warn_pointer_arith) { if (TREE_CODE (target_type) == VOID_TYPE) pedwarn ("pointer of type `void *' used in subtraction"); if (TREE_CODE (target_type) == FUNCTION_TYPE) pedwarn ("pointer to a function used in subtraction"); } /* First do the subtraction as integers; then drop through to build the divide operator. Do not do default conversions on the minus operator in case restype is a short type. */ op0 = build_binary_op (MINUS_EXPR, convert (restype, op0), convert (restype, op1), 0); /* This generates an error if op1 is pointer to incomplete type. */ if (TYPE_SIZE (TREE_TYPE (TREE_TYPE (op1))) == 0) error ("arithmetic on pointer to an incomplete type"); /* This generates an error if op0 is pointer to incomplete type. */ op1 = c_size_in_bytes (target_type); /* Divide by the size, in easiest possible way. */ result = build (EXACT_DIV_EXPR, restype, op0, convert (restype, op1)); folded = fold (result); if (folded == result) TREE_CONSTANT (folded) = TREE_CONSTANT (op0) & TREE_CONSTANT (op1); return folded; } /* Construct and perhaps optimize a tree representation for a unary operation. CODE, a tree_code, specifies the operation and XARG is the operand. NOCONVERT nonzero suppresses the default promotions (such as from short to int). */ tree build_unary_op (code, xarg, noconvert) enum tree_code code; tree xarg; int noconvert; { /* No default_conversion here. It causes trouble for ADDR_EXPR. */ register tree arg = xarg; register tree argtype = 0; register enum tree_code typecode = TREE_CODE (TREE_TYPE (arg)); tree val; if (typecode == ERROR_MARK) return error_mark_node; if (typecode == ENUMERAL_TYPE) typecode = INTEGER_TYPE; switch (code) { case CONVERT_EXPR: /* This is used for unary plus, because a CONVERT_EXPR is enough to prevent anybody from looking inside for associativity, but won't generate any code. */ if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE || typecode == COMPLEX_TYPE)) { error ("wrong type argument to unary plus"); return error_mark_node; } else if (!noconvert) arg = default_conversion (arg); break; case NEGATE_EXPR: if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE || typecode == COMPLEX_TYPE)) { error ("wrong type argument to unary minus"); return error_mark_node; } else if (!noconvert) arg = default_conversion (arg); break; case BIT_NOT_EXPR: if (typecode == COMPLEX_TYPE) { code = CONJ_EXPR; if (!noconvert) arg = default_conversion (arg); } else if (typecode != INTEGER_TYPE) { error ("wrong type argument to bit-complement"); return error_mark_node; } else if (!noconvert) arg = default_conversion (arg); break; case ABS_EXPR: if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE || typecode == COMPLEX_TYPE)) { error ("wrong type argument to abs"); return error_mark_node; } else if (!noconvert) arg = default_conversion (arg); break; case CONJ_EXPR: /* Conjugating a real value is a no-op, but allow it anyway. */ if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE || typecode == COMPLEX_TYPE)) { error ("wrong type argument to conjugation"); return error_mark_node; } else if (!noconvert) arg = default_conversion (arg); break; case TRUTH_NOT_EXPR: if (typecode != INTEGER_TYPE && typecode != REAL_TYPE && typecode != POINTER_TYPE && typecode != COMPLEX_TYPE /* These will convert to a pointer. */ && typecode != ARRAY_TYPE && typecode != FUNCTION_TYPE) { error ("wrong type argument to unary exclamation mark"); return error_mark_node; } arg = truthvalue_conversion (arg); return invert_truthvalue (arg); case NOP_EXPR: break; case REALPART_EXPR: if (TREE_CODE (arg) == COMPLEX_CST) return TREE_REALPART (arg); else if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE) return fold (build1 (REALPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg)); else return arg; case IMAGPART_EXPR: if (TREE_CODE (arg) == COMPLEX_CST) return TREE_IMAGPART (arg); else if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE) return fold (build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg)); else return convert (TREE_TYPE (arg), integer_zero_node); case PREINCREMENT_EXPR: case POSTINCREMENT_EXPR: case PREDECREMENT_EXPR: case POSTDECREMENT_EXPR: /* Handle complex lvalues (when permitted) by reduction to simpler cases. */ val = unary_complex_lvalue (code, arg); if (val != 0) return val; /* Increment or decrement the real part of the value, and don't change the imaginary part. */ if (typecode == COMPLEX_TYPE) { tree real, imag; arg = stabilize_reference (arg); real = build_unary_op (REALPART_EXPR, arg, 1); imag = build_unary_op (IMAGPART_EXPR, arg, 1); return build (COMPLEX_EXPR, TREE_TYPE (arg), build_unary_op (code, real, 1), imag); } /* Report invalid types. */ if (typecode != POINTER_TYPE && typecode != INTEGER_TYPE && typecode != REAL_TYPE) { error (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR ? "wrong type argument to increment" : "wrong type argument to decrement"); return error_mark_node; } { register tree inc; tree result_type = TREE_TYPE (arg); arg = get_unwidened (arg, 0); argtype = TREE_TYPE (arg); /* Compute the increment. */ if (typecode == POINTER_TYPE) { /* If pointer target is an undefined struct, we just cannot know how to do the arithmetic. */ if (TYPE_SIZE (TREE_TYPE (result_type)) == 0) error (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR ? "increment of pointer to unknown structure" : "decrement of pointer to unknown structure"); else if ((pedantic || warn_pointer_arith) && (TREE_CODE (TREE_TYPE (result_type)) == FUNCTION_TYPE || TREE_CODE (TREE_TYPE (result_type)) == VOID_TYPE)) pedwarn (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR ? "wrong type argument to increment" : "wrong type argument to decrement"); inc = c_size_in_bytes (TREE_TYPE (result_type)); } else inc = integer_one_node; inc = convert (argtype, inc); /* Handle incrementing a cast-expression. */ while (1) switch (TREE_CODE (arg)) { case NOP_EXPR: case CONVERT_EXPR: case FLOAT_EXPR: case FIX_TRUNC_EXPR: case FIX_FLOOR_EXPR: case FIX_ROUND_EXPR: case FIX_CEIL_EXPR: pedantic_lvalue_warning (CONVERT_EXPR); /* If the real type has the same machine representation as the type it is cast to, we can make better output by adding directly to the inside of the cast. */ if ((TREE_CODE (TREE_TYPE (arg)) == TREE_CODE (TREE_TYPE (TREE_OPERAND (arg, 0)))) && (TYPE_MODE (TREE_TYPE (arg)) == TYPE_MODE (TREE_TYPE (TREE_OPERAND (arg, 0))))) arg = TREE_OPERAND (arg, 0); else { tree incremented, modify, value; arg = stabilize_reference (arg); if (code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR) value = arg; else value = save_expr (arg); incremented = build (((code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR) ? PLUS_EXPR : MINUS_EXPR), argtype, value, inc); TREE_SIDE_EFFECTS (incremented) = 1; modify = build_modify_expr (arg, NOP_EXPR, incremented); value = build (COMPOUND_EXPR, TREE_TYPE (arg), modify, value); TREE_USED (value) = 1; return value; } break; default: goto give_up; } give_up: /* Complain about anything else that is not a true lvalue. */ if (!lvalue_or_else (arg, ((code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR) ? "invalid lvalue in increment" : "invalid lvalue in decrement"))) return error_mark_node; /* Report a read-only lvalue. */ if (TREE_READONLY (arg)) readonly_warning (arg, ((code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR) ? "increment" : "decrement")); val = build (code, TREE_TYPE (arg), arg, inc); TREE_SIDE_EFFECTS (val) = 1; val = convert (result_type, val); if (TREE_CODE (val) != code) TREE_NO_UNUSED_WARNING (val) = 1; return val; } case ADDR_EXPR: /* Note that this operation never does default_conversion regardless of NOCONVERT. */ /* Let &* cancel out to simplify resulting code. */ if (TREE_CODE (arg) == INDIRECT_REF) { /* Don't let this be an lvalue. */ if (lvalue_p (TREE_OPERAND (arg, 0))) return non_lvalue (TREE_OPERAND (arg, 0)); return TREE_OPERAND (arg, 0); } /* For &x[y], return x+y */ if (TREE_CODE (arg) == ARRAY_REF) { if (mark_addressable (TREE_OPERAND (arg, 0)) == 0) return error_mark_node; return build_binary_op (PLUS_EXPR, TREE_OPERAND (arg, 0), TREE_OPERAND (arg, 1), 1); } /* Handle complex lvalues (when permitted) by reduction to simpler cases. */ val = unary_complex_lvalue (code, arg); if (val != 0) return val; #if 0 /* Turned off because inconsistent; float f; *&(int)f = 3.4 stores in int format whereas (int)f = 3.4 stores in float format. */ /* Address of a cast is just a cast of the address of the operand of the cast. */ switch (TREE_CODE (arg)) { case NOP_EXPR: case CONVERT_EXPR: case FLOAT_EXPR: case FIX_TRUNC_EXPR: case FIX_FLOOR_EXPR: case FIX_ROUND_EXPR: case FIX_CEIL_EXPR: if (pedantic) pedwarn ("ANSI C forbids the address of a cast expression"); return convert (build_pointer_type (TREE_TYPE (arg)), build_unary_op (ADDR_EXPR, TREE_OPERAND (arg, 0), 0)); } #endif /* Allow the address of a constructor if all the elements are constant. */ if (TREE_CODE (arg) == CONSTRUCTOR && TREE_CONSTANT (arg)) ; /* Anything not already handled and not a true memory reference is an error. */ else if (typecode != FUNCTION_TYPE && !lvalue_or_else (arg, "invalid lvalue in unary `&'")) return error_mark_node; /* Ordinary case; arg is a COMPONENT_REF or a decl. */ argtype = TREE_TYPE (arg); /* If the lvalue is const or volatile, merge that into the type to which the address will point. Note that you can't get a restricted pointer by taking the address of something, so we only have to deal with `const' and `volatile' here. */ if (TREE_CODE_CLASS (TREE_CODE (arg)) == 'd' || TREE_CODE_CLASS (TREE_CODE (arg)) == 'r') { if (TREE_READONLY (arg) || TREE_THIS_VOLATILE (arg)) argtype = c_build_type_variant (argtype, TREE_READONLY (arg), TREE_THIS_VOLATILE (arg)); } argtype = build_pointer_type (argtype); if (mark_addressable (arg) == 0) return error_mark_node; { tree addr; if (TREE_CODE (arg) == COMPONENT_REF) { tree field = TREE_OPERAND (arg, 1); addr = build_unary_op (ADDR_EXPR, TREE_OPERAND (arg, 0), 0); if (DECL_C_BIT_FIELD (field)) { error ("attempt to take address of bit-field structure member `%s'", IDENTIFIER_POINTER (DECL_NAME (field))); return error_mark_node; } addr = convert (argtype, addr); if (! integer_zerop (DECL_FIELD_BITPOS (field))) { tree offset = size_binop (EASY_DIV_EXPR, DECL_FIELD_BITPOS (field), size_int (BITS_PER_UNIT)); int flag = TREE_CONSTANT (addr); addr = fold (build (PLUS_EXPR, argtype, addr, convert (argtype, offset))); TREE_CONSTANT (addr) = flag; } } else addr = build1 (code, argtype, arg); /* Address of a static or external variable or file-scope function counts as a constant. */ if (staticp (arg) && ! (TREE_CODE (arg) == FUNCTION_DECL && DECL_CONTEXT (arg) != 0)) TREE_CONSTANT (addr) = 1; return addr; } default: break; } if (argtype == 0) argtype = TREE_TYPE (arg); return fold (build1 (code, argtype, arg)); } #if 0 /* If CONVERSIONS is a conversion expression or a nested sequence of such, convert ARG with the same conversions in the same order and return the result. */ static tree convert_sequence (conversions, arg) tree conversions; tree arg; { switch (TREE_CODE (conversions)) { case NOP_EXPR: case CONVERT_EXPR: case FLOAT_EXPR: case FIX_TRUNC_EXPR: case FIX_FLOOR_EXPR: case FIX_ROUND_EXPR: case FIX_CEIL_EXPR: return convert (TREE_TYPE (conversions), convert_sequence (TREE_OPERAND (conversions, 0), arg)); default: return arg; } } #endif /* 0 */ /* Return nonzero if REF is an lvalue valid for this language. Lvalues can be assigned, unless their type has TYPE_READONLY. Lvalues can have their address taken, unless they have DECL_REGISTER. */ int lvalue_p (ref) tree ref; { register enum tree_code code = TREE_CODE (ref); switch (code) { case REALPART_EXPR: case IMAGPART_EXPR: case COMPONENT_REF: return lvalue_p (TREE_OPERAND (ref, 0)); case STRING_CST: return 1; case INDIRECT_REF: case ARRAY_REF: case VAR_DECL: case PARM_DECL: case RESULT_DECL: case ERROR_MARK: return (TREE_CODE (TREE_TYPE (ref)) != FUNCTION_TYPE && TREE_CODE (TREE_TYPE (ref)) != METHOD_TYPE); case BIND_EXPR: case RTL_EXPR: return TREE_CODE (TREE_TYPE (ref)) == ARRAY_TYPE; default: return 0; } } /* Return nonzero if REF is an lvalue valid for this language; otherwise, print an error message and return zero. */ int lvalue_or_else (ref, msgid) tree ref; const char *msgid; { int win = lvalue_p (ref); if (! win) error (msgid); return win; } /* Apply unary lvalue-demanding operator CODE to the expression ARG for certain kinds of expressions which are not really lvalues but which we can accept as lvalues. If ARG is not a kind of expression we can handle, return zero. */ static tree unary_complex_lvalue (code, arg) enum tree_code code; tree arg; { /* Handle (a, b) used as an "lvalue". */ if (TREE_CODE (arg) == COMPOUND_EXPR) { tree real_result = build_unary_op (code, TREE_OPERAND (arg, 1), 0); /* If this returns a function type, it isn't really being used as an lvalue, so don't issue a warning about it. */ if (TREE_CODE (TREE_TYPE (arg)) != FUNCTION_TYPE) pedantic_lvalue_warning (COMPOUND_EXPR); return build (COMPOUND_EXPR, TREE_TYPE (real_result), TREE_OPERAND (arg, 0), real_result); } /* Handle (a ? b : c) used as an "lvalue". */ if (TREE_CODE (arg) == COND_EXPR) { pedantic_lvalue_warning (COND_EXPR); if (TREE_CODE (TREE_TYPE (arg)) != FUNCTION_TYPE) pedantic_lvalue_warning (COMPOUND_EXPR); return (build_conditional_expr (TREE_OPERAND (arg, 0), build_unary_op (code, TREE_OPERAND (arg, 1), 0), build_unary_op (code, TREE_OPERAND (arg, 2), 0))); } return 0; } /* If pedantic, warn about improper lvalue. CODE is either COND_EXPR COMPOUND_EXPR, or CONVERT_EXPR (for casts). */ static void pedantic_lvalue_warning (code) enum tree_code code; { if (pedantic) pedwarn (code == COND_EXPR ? "ANSI C forbids use of conditional expressions as lvalues" : code == COMPOUND_EXPR ? "ANSI C forbids use of compound expressions as lvalues" : "ANSI C forbids use of cast expressions as lvalues"); } /* Warn about storing in something that is `const'. */ void readonly_warning (arg, msgid) tree arg; const char *msgid; { /* Forbid assignments to iterators. */ if (TREE_CODE (arg) == VAR_DECL && ITERATOR_P (arg)) pedwarn ("%s of iterator `%s'", _(msgid), IDENTIFIER_POINTER (DECL_NAME (arg))); if (TREE_CODE (arg) == COMPONENT_REF) { if (TYPE_READONLY (TREE_TYPE (TREE_OPERAND (arg, 0)))) readonly_warning (TREE_OPERAND (arg, 0), msgid); else pedwarn ("%s of read-only member `%s'", _(msgid), IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND (arg, 1)))); } else if (TREE_CODE (arg) == VAR_DECL) pedwarn ("%s of read-only variable `%s'", _(msgid), IDENTIFIER_POINTER (DECL_NAME (arg))); else pedwarn ("%s of read-only location", _(msgid)); } /* Mark EXP saying that we need to be able to take the address of it; it should not be allocated in a register. Value is 1 if successful. */ int mark_addressable (exp) tree exp; { register tree x = exp; while (1) switch (TREE_CODE (x)) { case COMPONENT_REF: if (DECL_C_BIT_FIELD (TREE_OPERAND (x, 1))) { error ("cannot take address of bitfield `%s'", IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND (x, 1)))); return 0; } /* ... fall through ... */ case ADDR_EXPR: case ARRAY_REF: case REALPART_EXPR: case IMAGPART_EXPR: x = TREE_OPERAND (x, 0); break; case CONSTRUCTOR: TREE_ADDRESSABLE (x) = 1; return 1; case VAR_DECL: case CONST_DECL: case PARM_DECL: case RESULT_DECL: if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x) && DECL_NONLOCAL (x)) { if (TREE_PUBLIC (x)) { error ("global register variable `%s' used in nested function", IDENTIFIER_POINTER (DECL_NAME (x))); return 0; } pedwarn ("register variable `%s' used in nested function", IDENTIFIER_POINTER (DECL_NAME (x))); } else if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x)) { if (TREE_PUBLIC (x)) { error ("address of global register variable `%s' requested", IDENTIFIER_POINTER (DECL_NAME (x))); return 0; } /* If we are making this addressable due to its having volatile components, give a different error message. Also handle the case of an unnamed parameter by not trying to give the name. */ else if (C_TYPE_FIELDS_VOLATILE (TREE_TYPE (x))) { error ("cannot put object with volatile field into register"); return 0; } pedwarn ("address of register variable `%s' requested", IDENTIFIER_POINTER (DECL_NAME (x))); } put_var_into_stack (x); /* drops in */ case FUNCTION_DECL: TREE_ADDRESSABLE (x) = 1; #if 0 /* poplevel deals with this now. */ if (DECL_CONTEXT (x) == 0) TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (x)) = 1; #endif default: return 1; } } /* Build and return a conditional expression IFEXP ? OP1 : OP2. */ tree build_conditional_expr (ifexp, op1, op2) tree ifexp, op1, op2; { register tree type1; register tree type2; register enum tree_code code1; register enum tree_code code2; register tree result_type = NULL; tree orig_op1 = op1, orig_op2 = op2; ifexp = truthvalue_conversion (default_conversion (ifexp)); #if 0 /* Produces wrong result if within sizeof. */ /* Don't promote the operands separately if they promote the same way. Return the unpromoted type and let the combined value get promoted if necessary. */ if (TREE_TYPE (op1) == TREE_TYPE (op2) && TREE_CODE (TREE_TYPE (op1)) != ARRAY_TYPE && TREE_CODE (TREE_TYPE (op1)) != ENUMERAL_TYPE && TREE_CODE (TREE_TYPE (op1)) != FUNCTION_TYPE) { if (TREE_CODE (ifexp) == INTEGER_CST) return pedantic_non_lvalue (integer_zerop (ifexp) ? op2 : op1); return fold (build (COND_EXPR, TREE_TYPE (op1), ifexp, op1, op2)); } #endif /* Promote both alternatives. */ if (TREE_CODE (TREE_TYPE (op1)) != VOID_TYPE) op1 = default_conversion (op1); if (TREE_CODE (TREE_TYPE (op2)) != VOID_TYPE) op2 = default_conversion (op2); if (TREE_CODE (ifexp) == ERROR_MARK || TREE_CODE (TREE_TYPE (op1)) == ERROR_MARK || TREE_CODE (TREE_TYPE (op2)) == ERROR_MARK) return error_mark_node; type1 = TREE_TYPE (op1); code1 = TREE_CODE (type1); type2 = TREE_TYPE (op2); code2 = TREE_CODE (type2); /* Quickly detect the usual case where op1 and op2 have the same type after promotion. */ if (TYPE_MAIN_VARIANT (type1) == TYPE_MAIN_VARIANT (type2)) { if (type1 == type2) result_type = type1; else result_type = TYPE_MAIN_VARIANT (type1); } else if ((code1 == INTEGER_TYPE || code1 == REAL_TYPE) && (code2 == INTEGER_TYPE || code2 == REAL_TYPE)) { result_type = common_type (type1, type2); } else if (code1 == VOID_TYPE || code2 == VOID_TYPE) { if (pedantic && (code1 != VOID_TYPE || code2 != VOID_TYPE)) pedwarn ("ANSI C forbids conditional expr with only one void side"); result_type = void_type_node; } else if (code1 == POINTER_TYPE && code2 == POINTER_TYPE) { if (comp_target_types (type1, type2)) result_type = common_type (type1, type2); else if (integer_zerop (op1) && TREE_TYPE (type1) == void_type_node && TREE_CODE (orig_op1) != NOP_EXPR) result_type = qualify_type (type2, type1); else if (integer_zerop (op2) && TREE_TYPE (type2) == void_type_node && TREE_CODE (orig_op2) != NOP_EXPR) result_type = qualify_type (type1, type2); else if (TYPE_MAIN_VARIANT (TREE_TYPE (type1)) == void_type_node) { if (pedantic && TREE_CODE (TREE_TYPE (type2)) == FUNCTION_TYPE) pedwarn ("ANSI C forbids conditional expr between `void *' and function pointer"); result_type = qualify_type (type1, type2); } else if (TYPE_MAIN_VARIANT (TREE_TYPE (type2)) == void_type_node) { if (pedantic && TREE_CODE (TREE_TYPE (type1)) == FUNCTION_TYPE) pedwarn ("ANSI C forbids conditional expr between `void *' and function pointer"); result_type = qualify_type (type2, type1); } else { pedwarn ("pointer type mismatch in conditional expression"); result_type = build_pointer_type (void_type_node); } } else if (code1 == POINTER_TYPE && code2 == INTEGER_TYPE) { if (! integer_zerop (op2)) pedwarn ("pointer/integer type mismatch in conditional expression"); else { op2 = null_pointer_node; #if 0 /* The spec seems to say this is permitted. */ if (pedantic && TREE_CODE (type1) == FUNCTION_TYPE) pedwarn ("ANSI C forbids conditional expr between 0 and function pointer"); #endif } result_type = type1; } else if (code2 == POINTER_TYPE && code1 == INTEGER_TYPE) { if (!integer_zerop (op1)) pedwarn ("pointer/integer type mismatch in conditional expression"); else { op1 = null_pointer_node; #if 0 /* The spec seems to say this is permitted. */ if (pedantic && TREE_CODE (type2) == FUNCTION_TYPE) pedwarn ("ANSI C forbids conditional expr between 0 and function pointer"); #endif } result_type = type2; } if (!result_type) { if (flag_cond_mismatch) result_type = void_type_node; else { error ("type mismatch in conditional expression"); return error_mark_node; } } /* Merge const and volatile flags of the incoming types. */ result_type = build_type_variant (result_type, TREE_READONLY (op1) || TREE_READONLY (op2), TREE_THIS_VOLATILE (op1) || TREE_THIS_VOLATILE (op2)); if (result_type != TREE_TYPE (op1)) op1 = convert_and_check (result_type, op1); if (result_type != TREE_TYPE (op2)) op2 = convert_and_check (result_type, op2); #if 0 if (code1 == RECORD_TYPE || code1 == UNION_TYPE) { result_type = TREE_TYPE (op1); if (TREE_CONSTANT (ifexp)) return pedantic_non_lvalue (integer_zerop (ifexp) ? op2 : op1); if (TYPE_MODE (result_type) == BLKmode) { register tree tempvar = build_decl (VAR_DECL, NULL_TREE, result_type); register tree xop1 = build_modify_expr (tempvar, op1); register tree xop2 = build_modify_expr (tempvar, op2); register tree result = fold (build (COND_EXPR, result_type, ifexp, xop1, xop2)); layout_decl (tempvar, TYPE_ALIGN (result_type)); /* No way to handle variable-sized objects here. I fear that the entire handling of BLKmode conditional exprs needs to be redone. */ if (TREE_CODE (DECL_SIZE (tempvar)) != INTEGER_CST) abort (); DECL_RTL (tempvar) = assign_stack_local (DECL_MODE (tempvar), (TREE_INT_CST_LOW (DECL_SIZE (tempvar)) + BITS_PER_UNIT - 1) / BITS_PER_UNIT, 0); TREE_SIDE_EFFECTS (result) = TREE_SIDE_EFFECTS (ifexp) | TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2); return build (COMPOUND_EXPR, result_type, result, tempvar); } } #endif /* 0 */ if (TREE_CODE (ifexp) == INTEGER_CST) return pedantic_non_lvalue (integer_zerop (ifexp) ? op2 : op1); return fold (build (COND_EXPR, result_type, ifexp, op1, op2)); } /* Given a list of expressions, return a compound expression that performs them all and returns the value of the last of them. */ tree build_compound_expr (list) tree list; { return internal_build_compound_expr (list, TRUE); } static tree internal_build_compound_expr (list, first_p) tree list; int first_p; { register tree rest; if (TREE_CHAIN (list) == 0) { #if 0 /* If something inside inhibited lvalueness, we should not override. */ /* Consider (x, y+0), which is not an lvalue since y+0 is not. */ /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue. */ if (TREE_CODE (list) == NON_LVALUE_EXPR) list = TREE_OPERAND (list, 0); #endif /* Don't let (0, 0) be null pointer constant. */ if (!first_p && integer_zerop (TREE_VALUE (list))) return non_lvalue (TREE_VALUE (list)); return TREE_VALUE (list); } if (TREE_CHAIN (list) != 0 && TREE_CHAIN (TREE_CHAIN (list)) == 0) { /* Convert arrays to pointers when there really is a comma operator. */ if (TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (list)))) == ARRAY_TYPE) TREE_VALUE (TREE_CHAIN (list)) = default_conversion (TREE_VALUE (TREE_CHAIN (list))); } rest = internal_build_compound_expr (TREE_CHAIN (list), FALSE); if (! TREE_SIDE_EFFECTS (TREE_VALUE (list))) { /* The left-hand operand of a comma expression is like an expression statement: with -W or -Wunused, we should warn if it doesn't have any side-effects, unless it was explicitly cast to (void). */ if ((extra_warnings || warn_unused) && ! (TREE_CODE (TREE_VALUE (list)) == CONVERT_EXPR && TREE_TYPE (TREE_VALUE (list)) == void_type_node)) warning ("left-hand operand of comma expression has no effect"); /* When pedantic, a compound expression can be neither an lvalue nor an integer constant expression. */ if (! pedantic) return rest; } /* With -Wunused, we should also warn if the left-hand operand does have side-effects, but computes a value which is not used. For example, in `foo() + bar(), baz()' the result of the `+' operator is not used, so we should issue a warning. */ else if (warn_unused) warn_if_unused_value (TREE_VALUE (list)); return build (COMPOUND_EXPR, TREE_TYPE (rest), TREE_VALUE (list), rest); } /* Build an expression representing a cast to type TYPE of expression EXPR. */ tree build_c_cast (type, expr) register tree type; tree expr; { register tree value = expr; if (type == error_mark_node || expr == error_mark_node) return error_mark_node; type = TYPE_MAIN_VARIANT (type); #if 0 /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue. */ if (TREE_CODE (value) == NON_LVALUE_EXPR) value = TREE_OPERAND (value, 0); #endif if (TREE_CODE (type) == ARRAY_TYPE) { error ("cast specifies array type"); return error_mark_node; } if (TREE_CODE (type) == FUNCTION_TYPE) { error ("cast specifies function type"); return error_mark_node; } if (type == TREE_TYPE (value)) { if (pedantic) { if (TREE_CODE (type) == RECORD_TYPE || TREE_CODE (type) == UNION_TYPE) pedwarn ("ANSI C forbids casting nonscalar to the same type"); } } else if (TREE_CODE (type) == UNION_TYPE) { tree field; if (TREE_CODE (TREE_TYPE (value)) == ARRAY_TYPE || TREE_CODE (TREE_TYPE (value)) == FUNCTION_TYPE) value = default_conversion (value); for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (field)), TYPE_MAIN_VARIANT (TREE_TYPE (value)))) break; if (field) { const char *name; tree t; if (pedantic) pedwarn ("ANSI C forbids casts to union type"); if (TYPE_NAME (type) != 0) { if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE) name = IDENTIFIER_POINTER (TYPE_NAME (type)); else name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))); } else name = ""; t = digest_init (type, build (CONSTRUCTOR, type, NULL_TREE, build_tree_list (field, value)), 0, 0); TREE_CONSTANT (t) = TREE_CONSTANT (value); return t; } error ("cast to union type from type not present in union"); return error_mark_node; } else { tree otype, ovalue; /* If casting to void, avoid the error that would come from default_conversion in the case of a non-lvalue array. */ if (type == void_type_node) return build1 (CONVERT_EXPR, type, value); /* Convert functions and arrays to pointers, but don't convert any other types. */ if (TREE_CODE (TREE_TYPE (value)) == FUNCTION_TYPE || TREE_CODE (TREE_TYPE (value)) == ARRAY_TYPE) value = default_conversion (value); otype = TREE_TYPE (value); /* Optionally warn about potentially worrisome casts. */ if (warn_cast_qual && TREE_CODE (type) == POINTER_TYPE && TREE_CODE (otype) == POINTER_TYPE) { /* Go to the innermost object being pointed to. */ tree in_type = type; tree in_otype = otype; while (TREE_CODE (in_type) == POINTER_TYPE) in_type = TREE_TYPE (in_type); while (TREE_CODE (in_otype) == POINTER_TYPE) in_otype = TREE_TYPE (in_otype); if (TYPE_QUALS (in_otype) & ~TYPE_QUALS (in_type)) /* There are qualifiers present in IN_OTYPE that are not present in IN_TYPE. */ pedwarn ("cast discards qualifiers from pointer target type"); } /* Warn about possible alignment problems. */ if (STRICT_ALIGNMENT && warn_cast_align && TREE_CODE (type) == POINTER_TYPE && TREE_CODE (otype) == POINTER_TYPE && TREE_CODE (TREE_TYPE (otype)) != VOID_TYPE && TREE_CODE (TREE_TYPE (otype)) != FUNCTION_TYPE /* Don't warn about opaque types, where the actual alignment restriction is unknown. */ && !((TREE_CODE (TREE_TYPE (otype)) == UNION_TYPE || TREE_CODE (TREE_TYPE (otype)) == RECORD_TYPE) && TYPE_MODE (TREE_TYPE (otype)) == VOIDmode) && TYPE_ALIGN (TREE_TYPE (type)) > TYPE_ALIGN (TREE_TYPE (otype))) warning ("cast increases required alignment of target type"); if (TREE_CODE (type) == INTEGER_TYPE && TREE_CODE (otype) == POINTER_TYPE && TYPE_PRECISION (type) != TYPE_PRECISION (otype) && !TREE_CONSTANT (value)) warning ("cast from pointer to integer of different size"); if (warn_bad_function_cast && TREE_CODE (value) == CALL_EXPR && TREE_CODE (type) != TREE_CODE (otype)) warning ("cast does not match function type"); if (TREE_CODE (type) == POINTER_TYPE && TREE_CODE (otype) == INTEGER_TYPE && TYPE_PRECISION (type) != TYPE_PRECISION (otype) #if 0 /* Don't warn about converting 0 to pointer, provided the 0 was explicit--not cast or made by folding. */ && !(TREE_CODE (value) == INTEGER_CST && integer_zerop (value)) #endif /* Don't warn about converting any constant. */ && !TREE_CONSTANT (value)) warning ("cast to pointer from integer of different size"); ovalue = value; value = convert (type, value); /* Ignore any integer overflow caused by the cast. */ if (TREE_CODE (value) == INTEGER_CST) { TREE_OVERFLOW (value) = TREE_OVERFLOW (ovalue); TREE_CONSTANT_OVERFLOW (value) = TREE_CONSTANT_OVERFLOW (ovalue); } } /* Pedantically, don't ley (void *) (FOO *) 0 be a null pointer constant. */ if (pedantic && TREE_CODE (value) == INTEGER_CST && TREE_CODE (expr) == INTEGER_CST && TREE_CODE (TREE_TYPE (expr)) != INTEGER_TYPE) value = non_lvalue (value); /* If pedantic, don't let a cast be an lvalue. */ if (value == expr && pedantic) value = non_lvalue (value); return value; } /* Build an assignment expression of lvalue LHS from value RHS. MODIFYCODE is the code for a binary operator that we use to combine the old value of LHS with RHS to get the new value. Or else MODIFYCODE is NOP_EXPR meaning do a simple assignment. */ tree build_modify_expr (lhs, modifycode, rhs) tree lhs, rhs; enum tree_code modifycode; { register tree result; tree newrhs; tree lhstype = TREE_TYPE (lhs); tree olhstype = lhstype; /* Types that aren't fully specified cannot be used in assignments. */ lhs = require_complete_type (lhs); /* Avoid duplicate error messages from operands that had errors. */ if (TREE_CODE (lhs) == ERROR_MARK || TREE_CODE (rhs) == ERROR_MARK) return error_mark_node; /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue. */ /* Do not use STRIP_NOPS here. We do not want an enumerator whose value is 0 to count as a null pointer constant. */ if (TREE_CODE (rhs) == NON_LVALUE_EXPR) rhs = TREE_OPERAND (rhs, 0); newrhs = rhs; /* Handle control structure constructs used as "lvalues". */ switch (TREE_CODE (lhs)) { /* Handle (a, b) used as an "lvalue". */ case COMPOUND_EXPR: pedantic_lvalue_warning (COMPOUND_EXPR); newrhs = build_modify_expr (TREE_OPERAND (lhs, 1), modifycode, rhs); if (TREE_CODE (newrhs) == ERROR_MARK) return error_mark_node; return build (COMPOUND_EXPR, lhstype, TREE_OPERAND (lhs, 0), newrhs); /* Handle (a ? b : c) used as an "lvalue". */ case COND_EXPR: pedantic_lvalue_warning (COND_EXPR); rhs = save_expr (rhs); { /* Produce (a ? (b = rhs) : (c = rhs)) except that the RHS goes through a save-expr so the code to compute it is only emitted once. */ tree cond = build_conditional_expr (TREE_OPERAND (lhs, 0), build_modify_expr (TREE_OPERAND (lhs, 1), modifycode, rhs), build_modify_expr (TREE_OPERAND (lhs, 2), modifycode, rhs)); if (TREE_CODE (cond) == ERROR_MARK) return cond; /* Make sure the code to compute the rhs comes out before the split. */ return build (COMPOUND_EXPR, TREE_TYPE (lhs), /* But cast it to void to avoid an "unused" error. */ convert (void_type_node, rhs), cond); } default: break; } /* If a binary op has been requested, combine the old LHS value with the RHS producing the value we should actually store into the LHS. */ if (modifycode != NOP_EXPR) { lhs = stabilize_reference (lhs); newrhs = build_binary_op (modifycode, lhs, rhs, 1); } /* Handle a cast used as an "lvalue". We have already performed any binary operator using the value as cast. Now convert the result to the cast type of the lhs, and then true type of the lhs and store it there; then convert result back to the cast type to be the value of the assignment. */ switch (TREE_CODE (lhs)) { case NOP_EXPR: case CONVERT_EXPR: case FLOAT_EXPR: case FIX_TRUNC_EXPR: case FIX_FLOOR_EXPR: case FIX_ROUND_EXPR: case FIX_CEIL_EXPR: if (TREE_CODE (TREE_TYPE (newrhs)) == ARRAY_TYPE || TREE_CODE (TREE_TYPE (newrhs)) == FUNCTION_TYPE) newrhs = default_conversion (newrhs); { tree inner_lhs = TREE_OPERAND (lhs, 0); tree result; result = build_modify_expr (inner_lhs, NOP_EXPR, convert (TREE_TYPE (inner_lhs), convert (lhstype, newrhs))); if (TREE_CODE (result) == ERROR_MARK) return result; pedantic_lvalue_warning (CONVERT_EXPR); return convert (TREE_TYPE (lhs), result); } default: break; } /* Now we have handled acceptable kinds of LHS that are not truly lvalues. Reject anything strange now. */ if (!lvalue_or_else (lhs, "invalid lvalue in assignment")) return error_mark_node; /* Warn about storing in something that is `const'. */ if (TREE_READONLY (lhs) || TYPE_READONLY (lhstype) || ((TREE_CODE (lhstype) == RECORD_TYPE || TREE_CODE (lhstype) == UNION_TYPE) && C_TYPE_FIELDS_READONLY (lhstype))) readonly_warning (lhs, "assignment"); /* If storing into a structure or union member, it has probably been given type `int'. Compute the type that would go with the actual amount of storage the member occupies. */ if (TREE_CODE (lhs) == COMPONENT_REF && (TREE_CODE (lhstype) == INTEGER_TYPE || TREE_CODE (lhstype) == REAL_TYPE || TREE_CODE (lhstype) == ENUMERAL_TYPE)) lhstype = TREE_TYPE (get_unwidened (lhs, 0)); /* If storing in a field that is in actuality a short or narrower than one, we must store in the field in its actual type. */ if (lhstype != TREE_TYPE (lhs)) { lhs = copy_node (lhs); TREE_TYPE (lhs) = lhstype; } /* Convert new value to destination type. */ newrhs = convert_for_assignment (lhstype, newrhs, _("assignment"), NULL_TREE, NULL_TREE, 0); if (TREE_CODE (newrhs) == ERROR_MARK) return error_mark_node; result = build (MODIFY_EXPR, lhstype, lhs, newrhs); TREE_SIDE_EFFECTS (result) = 1; /* If we got the LHS in a different type for storing in, convert the result back to the nominal type of LHS so that the value we return always has the same type as the LHS argument. */ if (olhstype == TREE_TYPE (result)) return result; return convert_for_assignment (olhstype, result, _("assignment"), NULL_TREE, NULL_TREE, 0); } /* Convert value RHS to type TYPE as preparation for an assignment to an lvalue of type TYPE. The real work of conversion is done by `convert'. The purpose of this function is to generate error messages for assignments that are not allowed in C. ERRTYPE is a string to use in error messages: "assignment", "return", etc. If it is null, this is parameter passing for a function call (and different error messages are output). FUNNAME is the name of the function being called, as an IDENTIFIER_NODE, or null. PARMNUM is the number of the argument, for printing in error messages. */ static tree convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum) tree type, rhs; const char *errtype; tree fundecl, funname; int parmnum; { register enum tree_code codel = TREE_CODE (type); register tree rhstype; register enum tree_code coder; /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue. */ /* Do not use STRIP_NOPS here. We do not want an enumerator whose value is 0 to count as a null pointer constant. */ if (TREE_CODE (rhs) == NON_LVALUE_EXPR) rhs = TREE_OPERAND (rhs, 0); if (TREE_CODE (TREE_TYPE (rhs)) == ARRAY_TYPE || TREE_CODE (TREE_TYPE (rhs)) == FUNCTION_TYPE) rhs = default_conversion (rhs); else if (optimize && TREE_CODE (rhs) == VAR_DECL) rhs = decl_constant_value (rhs); rhstype = TREE_TYPE (rhs); coder = TREE_CODE (rhstype); if (coder == ERROR_MARK) return error_mark_node; if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (rhstype)) { overflow_warning (rhs); /* Check for Objective-C protocols. This will issue a warning if there are protocol violations. No need to use the return value. */ maybe_objc_comptypes (type, rhstype, 0); return rhs; } if (coder == VOID_TYPE) { error ("void value not ignored as it ought to be"); return error_mark_node; } /* Arithmetic types all interconvert, and enum is treated like int. */ if ((codel == INTEGER_TYPE || codel == REAL_TYPE || codel == ENUMERAL_TYPE || codel == COMPLEX_TYPE) && (coder == INTEGER_TYPE || coder == REAL_TYPE || coder == ENUMERAL_TYPE || coder == COMPLEX_TYPE)) return convert_and_check (type, rhs); /* Conversion to a transparent union from its member types. This applies only to function arguments. */ else if (codel == UNION_TYPE && TYPE_TRANSPARENT_UNION (type) && ! errtype) { tree memb_types; tree marginal_memb_type = 0; for (memb_types = TYPE_FIELDS (type); memb_types; memb_types = TREE_CHAIN (memb_types)) { tree memb_type = TREE_TYPE (memb_types); if (comptypes (TYPE_MAIN_VARIANT (memb_type), TYPE_MAIN_VARIANT (rhstype))) break; if (TREE_CODE (memb_type) != POINTER_TYPE) continue; if (coder == POINTER_TYPE) { register tree ttl = TREE_TYPE (memb_type); register tree ttr = TREE_TYPE (rhstype); /* Any non-function converts to a [const][volatile] void * and vice versa; otherwise, targets must be the same. Meanwhile, the lhs target must have all the qualifiers of the rhs. */ if (TYPE_MAIN_VARIANT (ttl) == void_type_node || TYPE_MAIN_VARIANT (ttr) == void_type_node || comp_target_types (memb_type, rhstype)) { /* If this type won't generate any warnings, use it. */ if (TYPE_QUALS (ttl) == TYPE_QUALS (ttr) || ((TREE_CODE (ttr) == FUNCTION_TYPE && TREE_CODE (ttl) == FUNCTION_TYPE) ? ((TYPE_QUALS (ttl) | TYPE_QUALS (ttr)) == TYPE_QUALS (ttr)) : ((TYPE_QUALS (ttl) | TYPE_QUALS (ttr)) == TYPE_QUALS (ttl)))) break; /* Keep looking for a better type, but remember this one. */ if (! marginal_memb_type) marginal_memb_type = memb_type; } } /* Can convert integer zero to any pointer type. */ if (integer_zerop (rhs) || (TREE_CODE (rhs) == NOP_EXPR && integer_zerop (TREE_OPERAND (rhs, 0)))) { rhs = null_pointer_node; break; } } if (memb_types || marginal_memb_type) { if (! memb_types) { /* We have only a marginally acceptable member type; it needs a warning. */ register tree ttl = TREE_TYPE (marginal_memb_type); register tree ttr = TREE_TYPE (rhstype); /* Const and volatile mean something different for function types, so the usual warnings are not appropriate. */ if (TREE_CODE (ttr) == FUNCTION_TYPE && TREE_CODE (ttl) == FUNCTION_TYPE) { /* Because const and volatile on functions are restrictions that say the function will not do certain things, it is okay to use a const or volatile function where an ordinary one is wanted, but not vice-versa. */ if (TYPE_QUALS (ttl) & ~TYPE_QUALS (ttr)) warn_for_assignment ("%s makes qualified function pointer from unqualified", errtype, funname, parmnum); } else if (TYPE_QUALS (ttr) & ~TYPE_QUALS (ttl)) warn_for_assignment ("%s discards qualifiers from pointer target type", errtype, funname, parmnum); } if (pedantic && ! DECL_IN_SYSTEM_HEADER (fundecl)) pedwarn ("ANSI C prohibits argument conversion to union type"); return build1 (NOP_EXPR, type, rhs); } } /* Conversions among pointers */ else if (codel == POINTER_TYPE && coder == POINTER_TYPE) { register tree ttl = TREE_TYPE (type); register tree ttr = TREE_TYPE (rhstype); /* Any non-function converts to a [const][volatile] void * and vice versa; otherwise, targets must be the same. Meanwhile, the lhs target must have all the qualifiers of the rhs. */ if (TYPE_MAIN_VARIANT (ttl) == void_type_node || TYPE_MAIN_VARIANT (ttr) == void_type_node || comp_target_types (type, rhstype) || (unsigned_type (TYPE_MAIN_VARIANT (ttl)) == unsigned_type (TYPE_MAIN_VARIANT (ttr)))) { if (pedantic && ((TYPE_MAIN_VARIANT (ttl) == void_type_node && TREE_CODE (ttr) == FUNCTION_TYPE) || (TYPE_MAIN_VARIANT (ttr) == void_type_node /* Check TREE_CODE to catch cases like (void *) (char *) 0 which are not ANSI null ptr constants. */ && (!integer_zerop (rhs) || TREE_CODE (rhs) == NOP_EXPR) && TREE_CODE (ttl) == FUNCTION_TYPE))) warn_for_assignment ("ANSI forbids %s between function pointer and `void *'", errtype, funname, parmnum); /* Const and volatile mean something different for function types, so the usual warnings are not appropriate. */ else if (TREE_CODE (ttr) != FUNCTION_TYPE && TREE_CODE (ttl) != FUNCTION_TYPE) { if (TYPE_QUALS (ttr) & ~TYPE_QUALS (ttl)) warn_for_assignment ("%s discards qualifiers from pointer target type", errtype, funname, parmnum); /* If this is not a case of ignoring a mismatch in signedness, no warning. */ else if (TYPE_MAIN_VARIANT (ttl) == void_type_node || TYPE_MAIN_VARIANT (ttr) == void_type_node || comp_target_types (type, rhstype)) ; /* If there is a mismatch, do warn. */ else if (pedantic) warn_for_assignment ("pointer targets in %s differ in signedness", errtype, funname, parmnum); } else if (TREE_CODE (ttl) == FUNCTION_TYPE && TREE_CODE (ttr) == FUNCTION_TYPE) { /* Because const and volatile on functions are restrictions that say the function will not do certain things, it is okay to use a const or volatile function where an ordinary one is wanted, but not vice-versa. */ if (TYPE_QUALS (ttl) & ~TYPE_QUALS (ttr)) warn_for_assignment ("%s makes qualified function pointer from unqualified", errtype, funname, parmnum); } } else warn_for_assignment ("%s from incompatible pointer type", errtype, funname, parmnum); return convert (type, rhs); } else if (codel == POINTER_TYPE && coder == INTEGER_TYPE) { /* An explicit constant 0 can convert to a pointer, or one that results from arithmetic, even including a cast to integer type. */ if (! (TREE_CODE (rhs) == INTEGER_CST && integer_zerop (rhs)) && ! (TREE_CODE (rhs) == NOP_EXPR && TREE_CODE (TREE_TYPE (rhs)) == INTEGER_TYPE && TREE_CODE (TREE_OPERAND (rhs, 0)) == INTEGER_CST && integer_zerop (TREE_OPERAND (rhs, 0)))) { warn_for_assignment ("%s makes pointer from integer without a cast", errtype, funname, parmnum); return convert (type, rhs); } return null_pointer_node; } else if (codel == INTEGER_TYPE && coder == POINTER_TYPE) { warn_for_assignment ("%s makes integer from pointer without a cast", errtype, funname, parmnum); return convert (type, rhs); } if (!errtype) { if (funname) { tree selector = maybe_building_objc_message_expr (); if (selector && parmnum > 2) error ("incompatible type for argument %d of `%s'", parmnum - 2, IDENTIFIER_POINTER (selector)); else error ("incompatible type for argument %d of `%s'", parmnum, IDENTIFIER_POINTER (funname)); } else error ("incompatible type for argument %d of indirect function call", parmnum); } else error ("incompatible types in %s", errtype); return error_mark_node; } /* Print a warning using MSGID. It gets OPNAME as its one parameter. If OPNAME is null, it is replaced by "passing arg ARGNUM of `FUNCTION'". FUNCTION and ARGNUM are handled specially if we are building an Objective-C selector. */ static void warn_for_assignment (msgid, opname, function, argnum) const char *msgid; const char *opname; tree function; int argnum; { if (opname == 0) { tree selector = maybe_building_objc_message_expr (); char * new_opname; if (selector && argnum > 2) { function = selector; argnum -= 2; } if (function) { /* Function name is known; supply it. */ const char *argstring = _("passing arg %d of `%s'"); new_opname = (char *) alloca (IDENTIFIER_LENGTH (function) + strlen (argstring) + 1 + 25 /*%d*/ + 1); sprintf (new_opname, argstring, argnum, IDENTIFIER_POINTER (function)); } else { /* Function name unknown (call through ptr); just give arg number.*/ const char *argnofun = _("passing arg %d of pointer to function"); new_opname = (char *) alloca (strlen (argnofun) + 1 + 25 /*%d*/ + 1); sprintf (new_opname, argnofun, argnum); } opname = new_opname; } pedwarn (msgid, opname); } /* Return nonzero if VALUE is a valid constant-valued expression for use in initializing a static variable; one that can be an element of a "constant" initializer. Return null_pointer_node if the value is absolute; if it is relocatable, return the variable that determines the relocation. We assume that VALUE has been folded as much as possible; therefore, we do not need to check for such things as arithmetic-combinations of integers. */ tree initializer_constant_valid_p (value, endtype) tree value; tree endtype; { switch (TREE_CODE (value)) { case CONSTRUCTOR: if ((TREE_CODE (TREE_TYPE (value)) == UNION_TYPE || TREE_CODE (TREE_TYPE (value)) == RECORD_TYPE) && TREE_CONSTANT (value) && CONSTRUCTOR_ELTS (value)) return initializer_constant_valid_p (TREE_VALUE (CONSTRUCTOR_ELTS (value)), endtype); return TREE_STATIC (value) ? null_pointer_node : 0; case INTEGER_CST: case REAL_CST: case STRING_CST: case COMPLEX_CST: return null_pointer_node; case ADDR_EXPR: return TREE_OPERAND (value, 0); case NON_LVALUE_EXPR: return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype); case CONVERT_EXPR: case NOP_EXPR: /* Allow conversions between pointer types. */ if (TREE_CODE (TREE_TYPE (value)) == POINTER_TYPE && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == POINTER_TYPE) return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype); /* Allow conversions between real types. */ if (TREE_CODE (TREE_TYPE (value)) == REAL_TYPE && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == REAL_TYPE) return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype); /* Allow length-preserving conversions between integer types. */ if (TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == INTEGER_TYPE && (TYPE_PRECISION (TREE_TYPE (value)) == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (value, 0))))) return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype); /* Allow conversions between other integer types only if explicit value. */ if (TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == INTEGER_TYPE) { tree inner = initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype); if (inner == null_pointer_node) return null_pointer_node; return 0; } /* Allow (int) &foo provided int is as wide as a pointer. */ if (TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == POINTER_TYPE && (TYPE_PRECISION (TREE_TYPE (value)) >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (value, 0))))) return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype); /* Likewise conversions from int to pointers, but also allow conversions from 0. */ if (TREE_CODE (TREE_TYPE (value)) == POINTER_TYPE && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == INTEGER_TYPE) { if (integer_zerop (TREE_OPERAND (value, 0))) return null_pointer_node; else if (TYPE_PRECISION (TREE_TYPE (value)) <= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (value, 0)))) return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype); } /* Allow conversions to union types if the value inside is okay. */ if (TREE_CODE (TREE_TYPE (value)) == UNION_TYPE) return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype); return 0; case PLUS_EXPR: if (TREE_CODE (endtype) == INTEGER_TYPE && TYPE_PRECISION (endtype) < POINTER_SIZE) return 0; { tree valid0 = initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype); tree valid1 = initializer_constant_valid_p (TREE_OPERAND (value, 1), endtype); /* If either term is absolute, use the other terms relocation. */ if (valid0 == null_pointer_node) return valid1; if (valid1 == null_pointer_node) return valid0; return 0; } case MINUS_EXPR: if (TREE_CODE (endtype) == INTEGER_TYPE && TYPE_PRECISION (endtype) < POINTER_SIZE) return 0; { tree valid0 = initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype); tree valid1 = initializer_constant_valid_p (TREE_OPERAND (value, 1), endtype); /* Win if second argument is absolute. */ if (valid1 == null_pointer_node) return valid0; /* Win if both arguments have the same relocation. Then the value is absolute. */ if (valid0 == valid1) return null_pointer_node; return 0; } default: return 0; } } /* If VALUE is a compound expr all of whose expressions are constant, then return its value. Otherwise, return error_mark_node. This is for handling COMPOUND_EXPRs as initializer elements which is allowed with a warning when -pedantic is specified. */ static tree valid_compound_expr_initializer (value, endtype) tree value; tree endtype; { if (TREE_CODE (value) == COMPOUND_EXPR) { if (valid_compound_expr_initializer (TREE_OPERAND (value, 0), endtype) == error_mark_node) return error_mark_node; return valid_compound_expr_initializer (TREE_OPERAND (value, 1), endtype); } else if (! TREE_CONSTANT (value) && ! initializer_constant_valid_p (value, endtype)) return error_mark_node; else return value; } /* Perform appropriate conversions on the initial value of a variable, store it in the declaration DECL, and print any error messages that are appropriate. If the init is invalid, store an ERROR_MARK. */ void store_init_value (decl, init) tree decl, init; { register tree value, type; /* If variable's type was invalidly declared, just ignore it. */ type = TREE_TYPE (decl); if (TREE_CODE (type) == ERROR_MARK) return; /* Digest the specified initializer into an expression. */ value = digest_init (type, init, TREE_STATIC (decl), TREE_STATIC (decl) || pedantic); /* Store the expression if valid; else report error. */ #if 0 /* Note that this is the only place we can detect the error in a case such as struct foo bar = (struct foo) { x, y }; where there is one initial value which is a constructor expression. */ if (value == error_mark_node) ; else if (TREE_STATIC (decl) && ! TREE_CONSTANT (value)) { error ("initializer for static variable is not constant"); value = error_mark_node; } else if (TREE_STATIC (decl) && initializer_constant_valid_p (value, TREE_TYPE (value)) == 0) { error ("initializer for static variable uses complicated arithmetic"); value = error_mark_node; } else { if (pedantic && TREE_CODE (value) == CONSTRUCTOR) { if (! TREE_CONSTANT (value)) pedwarn ("aggregate initializer is not constant"); else if (! TREE_STATIC (value)) pedwarn ("aggregate initializer uses complicated arithmetic"); } } #endif DECL_INITIAL (decl) = value; /* ANSI wants warnings about out-of-range constant initializers. */ STRIP_TYPE_NOPS (value); constant_expression_warning (value); } /* Methods for storing and printing names for error messages. */ /* Implement a spelling stack that allows components of a name to be pushed and popped. Each element on the stack is this structure. */ struct spelling { int kind; union { int i; const char *s; } u; }; #define SPELLING_STRING 1 #define SPELLING_MEMBER 2 #define SPELLING_BOUNDS 3 static struct spelling *spelling; /* Next stack element (unused). */ static struct spelling *spelling_base; /* Spelling stack base. */ static int spelling_size; /* Size of the spelling stack. */ /* Macros to save and restore the spelling stack around push_... functions. Alternative to SAVE_SPELLING_STACK. */ #define SPELLING_DEPTH() (spelling - spelling_base) #define RESTORE_SPELLING_DEPTH(depth) (spelling = spelling_base + depth) /* Save and restore the spelling stack around arbitrary C code. */ #define SAVE_SPELLING_DEPTH(code) \ { \ int __depth = SPELLING_DEPTH (); \ code; \ RESTORE_SPELLING_DEPTH (__depth); \ } /* Push an element on the spelling stack with type KIND and assign VALUE to MEMBER. */ #define PUSH_SPELLING(KIND, VALUE, MEMBER) \ { \ int depth = SPELLING_DEPTH (); \ \ if (depth >= spelling_size) \ { \ spelling_size += 10; \ if (spelling_base == 0) \ spelling_base \ = (struct spelling *) xmalloc (spelling_size * sizeof (struct spelling)); \ else \ spelling_base \ = (struct spelling *) xrealloc (spelling_base, \ spelling_size * sizeof (struct spelling)); \ RESTORE_SPELLING_DEPTH (depth); \ } \ \ spelling->kind = (KIND); \ spelling->MEMBER = (VALUE); \ spelling++; \ } /* Push STRING on the stack. Printed literally. */ static void push_string (string) const char *string; { PUSH_SPELLING (SPELLING_STRING, string, u.s); } /* Push a member name on the stack. Printed as '.' STRING. */ static void push_member_name (decl) tree decl; { const char *string = DECL_NAME (decl) ? IDENTIFIER_POINTER (DECL_NAME (decl)) : ""; PUSH_SPELLING (SPELLING_MEMBER, string, u.s); } /* Push an array bounds on the stack. Printed as [BOUNDS]. */ static void push_array_bounds (bounds) int bounds; { PUSH_SPELLING (SPELLING_BOUNDS, bounds, u.i); } /* Compute the maximum size in bytes of the printed spelling. */ static int spelling_length () { register int size = 0; register struct spelling *p; for (p = spelling_base; p < spelling; p++) { if (p->kind == SPELLING_BOUNDS) size += 25; else size += strlen (p->u.s) + 1; } return size; } /* Print the spelling to BUFFER and return it. */ static char * print_spelling (buffer) register char *buffer; { register char *d = buffer; register struct spelling *p; for (p = spelling_base; p < spelling; p++) if (p->kind == SPELLING_BOUNDS) { sprintf (d, "[%d]", p->u.i); d += strlen (d); } else { register const char *s; if (p->kind == SPELLING_MEMBER) *d++ = '.'; for (s = p->u.s; (*d = *s++); d++) ; } *d++ = '\0'; return buffer; } /* Issue an error message for a bad initializer component. MSGID identifies the message. The component name is taken from the spelling stack. */ void error_init (msgid) const char *msgid; { char *ofwhat; error (msgid); ofwhat = print_spelling ((char *) alloca (spelling_length () + 1)); if (*ofwhat) error ("(near initialization for `%s')", ofwhat); } /* Issue a pedantic warning for a bad initializer component. MSGID identifies the message. The component name is taken from the spelling stack. */ void pedwarn_init (msgid) const char *msgid; { char *ofwhat; pedwarn (msgid); ofwhat = print_spelling ((char *) alloca (spelling_length () + 1)); if (*ofwhat) pedwarn ("(near initialization for `%s')", ofwhat); } /* Issue a warning for a bad initializer component. MSGID identifies the message. The component name is taken from the spelling stack. */ static void warning_init (msgid) const char *msgid; { char *ofwhat; warning (msgid); ofwhat = print_spelling ((char *) alloca (spelling_length () + 1)); if (*ofwhat) warning ("(near initialization for `%s')", ofwhat); } /* Digest the parser output INIT as an initializer for type TYPE. Return a C expression of type TYPE to represent the initial value. The arguments REQUIRE_CONSTANT and CONSTRUCTOR_CONSTANT request errors if non-constant initializers or elements are seen. CONSTRUCTOR_CONSTANT applies only to elements of constructors. */ static tree digest_init (type, init, require_constant, constructor_constant) tree type, init; int require_constant, constructor_constant; { enum tree_code code = TREE_CODE (type); tree inside_init = init; if (init == error_mark_node) return init; /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue. */ /* Do not use STRIP_NOPS here. We do not want an enumerator whose value is 0 to count as a null pointer constant. */ if (TREE_CODE (init) == NON_LVALUE_EXPR) inside_init = TREE_OPERAND (init, 0); /* Initialization of an array of chars from a string constant optionally enclosed in braces. */ if (code == ARRAY_TYPE) { tree typ1 = TYPE_MAIN_VARIANT (TREE_TYPE (type)); if ((typ1 == char_type_node || typ1 == signed_char_type_node || typ1 == unsigned_char_type_node || typ1 == unsigned_wchar_type_node || typ1 == signed_wchar_type_node) && ((inside_init && TREE_CODE (inside_init) == STRING_CST))) { if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)), TYPE_MAIN_VARIANT (type))) return inside_init; if ((TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (inside_init))) != char_type_node) && TYPE_PRECISION (typ1) == TYPE_PRECISION (char_type_node)) { error_init ("char-array initialized from wide string"); return error_mark_node; } if ((TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (inside_init))) == char_type_node) && TYPE_PRECISION (typ1) != TYPE_PRECISION (char_type_node)) { error_init ("int-array initialized from non-wide string"); return error_mark_node; } TREE_TYPE (inside_init) = type; if (TYPE_DOMAIN (type) != 0 && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST) { register int size = TREE_INT_CST_LOW (TYPE_SIZE (type)); size = (size + BITS_PER_UNIT - 1) / BITS_PER_UNIT; /* Subtract 1 (or sizeof (wchar_t)) because it's ok to ignore the terminating null char that is counted in the length of the constant. */ if (size < TREE_STRING_LENGTH (inside_init) - (TYPE_PRECISION (typ1) != TYPE_PRECISION (char_type_node) ? TYPE_PRECISION (wchar_type_node) / BITS_PER_UNIT : 1)) pedwarn_init ("initializer-string for array of chars is too long"); } return inside_init; } } /* Any type can be initialized from an expression of the same type, optionally with braces. */ if (inside_init && TREE_TYPE (inside_init) != 0 && (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)), TYPE_MAIN_VARIANT (type)) || (code == ARRAY_TYPE && comptypes (TREE_TYPE (inside_init), type)) || (code == POINTER_TYPE && (TREE_CODE (TREE_TYPE (inside_init)) == ARRAY_TYPE || TREE_CODE (TREE_TYPE (inside_init)) == FUNCTION_TYPE) && comptypes (TREE_TYPE (TREE_TYPE (inside_init)), TREE_TYPE (type))))) { if (code == POINTER_TYPE && (TREE_CODE (TREE_TYPE (inside_init)) == ARRAY_TYPE || TREE_CODE (TREE_TYPE (inside_init)) == FUNCTION_TYPE)) inside_init = default_conversion (inside_init); else if (code == ARRAY_TYPE && TREE_CODE (inside_init) != STRING_CST && TREE_CODE (inside_init) != CONSTRUCTOR) { error_init ("array initialized from non-constant array expression"); return error_mark_node; } if (optimize && TREE_CODE (inside_init) == VAR_DECL) inside_init = decl_constant_value (inside_init); /* Compound expressions can only occur here if -pedantic or -pedantic-errors is specified. In the later case, we always want an error. In the former case, we simply want a warning. */ if (require_constant && pedantic && TREE_CODE (inside_init) == COMPOUND_EXPR) { inside_init = valid_compound_expr_initializer (inside_init, TREE_TYPE (inside_init)); if (inside_init == error_mark_node) error_init ("initializer element is not constant"); else pedwarn_init ("initializer element is not constant"); if (flag_pedantic_errors) inside_init = error_mark_node; } else if (require_constant && ! TREE_CONSTANT (inside_init)) { error_init ("initializer element is not constant"); inside_init = error_mark_node; } else if (require_constant && initializer_constant_valid_p (inside_init, TREE_TYPE (inside_init)) == 0) { error_init ("initializer element is not computable at load time"); inside_init = error_mark_node; } return inside_init; } /* Handle scalar types, including conversions. */ if (code == INTEGER_TYPE || code == REAL_TYPE || code == POINTER_TYPE || code == ENUMERAL_TYPE || code == COMPLEX_TYPE) { /* Note that convert_for_assignment calls default_conversion for arrays and functions. We must not call it in the case where inside_init is a null pointer constant. */ inside_init = convert_for_assignment (type, init, _("initialization"), NULL_TREE, NULL_TREE, 0); if (require_constant && ! TREE_CONSTANT (inside_init)) { error_init ("initializer element is not constant"); inside_init = error_mark_node; } else if (require_constant && initializer_constant_valid_p (inside_init, TREE_TYPE (inside_init)) == 0) { error_init ("initializer element is not computable at load time"); inside_init = error_mark_node; } return inside_init; } /* Come here only for records and arrays. */ if (TYPE_SIZE (type) && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST) { error_init ("variable-sized object may not be initialized"); return error_mark_node; } /* Traditionally, you can write struct foo x = 0; and it initializes the first element of x to 0. */ if (flag_traditional) { tree top = 0, prev = 0, otype = type; while (TREE_CODE (type) == RECORD_TYPE || TREE_CODE (type) == ARRAY_TYPE || TREE_CODE (type) == QUAL_UNION_TYPE || TREE_CODE (type) == UNION_TYPE) { tree temp = build (CONSTRUCTOR, type, NULL_TREE, NULL_TREE); if (prev == 0) top = temp; else TREE_OPERAND (prev, 1) = build_tree_list (NULL_TREE, temp); prev = temp; if (TREE_CODE (type) == ARRAY_TYPE) type = TREE_TYPE (type); else if (TYPE_FIELDS (type)) type = TREE_TYPE (TYPE_FIELDS (type)); else { error_init ("invalid initializer"); return error_mark_node; } } if (otype != type) { TREE_OPERAND (prev, 1) = build_tree_list (NULL_TREE, digest_init (type, init, require_constant, constructor_constant)); return top; } else return error_mark_node; } error_init ("invalid initializer"); return error_mark_node; } /* Handle initializers that use braces. */ /* Type of object we are accumulating a constructor for. This type is always a RECORD_TYPE, UNION_TYPE or ARRAY_TYPE. */ static tree constructor_type; /* For a RECORD_TYPE or UNION_TYPE, this is the chain of fields left to fill. */ static tree constructor_fields; /* For an ARRAY_TYPE, this is the specified index at which to store the next element we get. This is a special INTEGER_CST node that we modify in place. */ static tree constructor_index; /* For an ARRAY_TYPE, this is the end index of the range to initialize with the next element, or NULL in the ordinary case where the element is used just once. */ static tree constructor_range_end; /* For an ARRAY_TYPE, this is the maximum index. */ static tree constructor_max_index; /* For a RECORD_TYPE, this is the first field not yet written out. */ static tree constructor_unfilled_fields; /* For an ARRAY_TYPE, this is the index of the first element not yet written out. This is a special INTEGER_CST node that we modify in place. */ static tree constructor_unfilled_index; /* In a RECORD_TYPE, the byte index of the next consecutive field. This is so we can generate gaps between fields, when appropriate. This is a special INTEGER_CST node that we modify in place. */ static tree constructor_bit_index; /* If we are saving up the elements rather than allocating them, this is the list of elements so far (in reverse order, most recent first). */ static tree constructor_elements; /* 1 if so far this constructor's elements are all compile-time constants. */ static int constructor_constant; /* 1 if so far this constructor's elements are all valid address constants. */ static int constructor_simple; /* 1 if this constructor is erroneous so far. */ static int constructor_erroneous; /* 1 if have called defer_addressed_constants. */ static int constructor_subconstants_deferred; /* Structure for managing pending initializer elements, organized as an AVL tree. */ struct init_node { struct init_node *left, *right; struct init_node *parent; int balance; tree purpose; tree value; }; /* Tree of pending elements at this constructor level. These are elements encountered out of order which belong at places we haven't reached yet in actually writing the output. */ static struct init_node *constructor_pending_elts; /* The SPELLING_DEPTH of this constructor. */ static int constructor_depth; /* 0 if implicitly pushing constructor levels is allowed. */ int constructor_no_implicit = 0; /* 0 for C; 1 for some other languages. */ static int require_constant_value; static int require_constant_elements; /* 1 if it is ok to output this constructor as we read it. 0 means must accumulate a CONSTRUCTOR expression. */ static int constructor_incremental; /* DECL node for which an initializer is being read. 0 means we are reading a constructor expression such as (struct foo) {...}. */ static tree constructor_decl; /* start_init saves the ASMSPEC arg here for really_start_incremental_init. */ static char *constructor_asmspec; /* Nonzero if this is an initializer for a top-level decl. */ static int constructor_top_level; /* This stack has a level for each implicit or explicit level of structuring in the initializer, including the outermost one. It saves the values of most of the variables above. */ struct constructor_stack { struct constructor_stack *next; tree type; tree fields; tree index; tree range_end; tree max_index; tree unfilled_index; tree unfilled_fields; tree bit_index; tree elements; int offset; struct init_node *pending_elts; int depth; /* If nonzero, this value should replace the entire constructor at this level. */ tree replacement_value; char constant; char simple; char implicit; char incremental; char erroneous; char outer; }; struct constructor_stack *constructor_stack; /* This stack records separate initializers that are nested. Nested initializers can't happen in ANSI C, but GNU C allows them in cases like { ... (struct foo) { ... } ... }. */ struct initializer_stack { struct initializer_stack *next; tree decl; char *asmspec; struct constructor_stack *constructor_stack; tree elements; struct spelling *spelling; struct spelling *spelling_base; int spelling_size; char top_level; char incremental; char require_constant_value; char require_constant_elements; char deferred; }; struct initializer_stack *initializer_stack; /* Prepare to parse and output the initializer for variable DECL. */ void start_init (decl, asmspec_tree, top_level) tree decl; tree asmspec_tree; int top_level; { const char *locus; struct initializer_stack *p = (struct initializer_stack *) xmalloc (sizeof (struct initializer_stack)); char *asmspec = 0; if (asmspec_tree) asmspec = TREE_STRING_POINTER (asmspec_tree); p->decl = constructor_decl; p->asmspec = constructor_asmspec; p->incremental = constructor_incremental; p->require_constant_value = require_constant_value; p->require_constant_elements = require_constant_elements; p->constructor_stack = constructor_stack; p->elements = constructor_elements; p->spelling = spelling; p->spelling_base = spelling_base; p->spelling_size = spelling_size; p->deferred = constructor_subconstants_deferred; p->top_level = constructor_top_level; p->next = initializer_stack; initializer_stack = p; constructor_decl = decl; constructor_incremental = top_level; constructor_asmspec = asmspec; constructor_subconstants_deferred = 0; constructor_top_level = top_level; if (decl != 0) { require_constant_value = TREE_STATIC (decl); require_constant_elements = ((TREE_STATIC (decl) || pedantic) /* For a scalar, you can always use any value to initialize, even within braces. */ && (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE || TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE || TREE_CODE (TREE_TYPE (decl)) == UNION_TYPE || TREE_CODE (TREE_TYPE (decl)) == QUAL_UNION_TYPE)); locus = IDENTIFIER_POINTER (DECL_NAME (decl)); constructor_incremental |= TREE_STATIC (decl); } else { require_constant_value = 0; require_constant_elements = 0; locus = "(anonymous)"; } constructor_stack = 0; missing_braces_mentioned = 0; spelling_base = 0; spelling_size = 0; RESTORE_SPELLING_DEPTH (0); if (locus) push_string (locus); } void finish_init () { struct initializer_stack *p = initializer_stack; /* Output subconstants (string constants, usually) that were referenced within this initializer and saved up. Must do this if and only if we called defer_addressed_constants. */ if (constructor_subconstants_deferred) output_deferred_addressed_constants (); /* Free the whole constructor stack of this initializer. */ while (constructor_stack) { struct constructor_stack *q = constructor_stack; constructor_stack = q->next; free (q); } /* Pop back to the data of the outer initializer (if any). */ constructor_decl = p->decl; constructor_asmspec = p->asmspec; constructor_incremental = p->incremental; require_constant_value = p->require_constant_value; require_constant_elements = p->require_constant_elements; constructor_stack = p->constructor_stack; constructor_elements = p->elements; spelling = p->spelling; spelling_base = p->spelling_base; spelling_size = p->spelling_size; constructor_subconstants_deferred = p->deferred; constructor_top_level = p->top_level; initializer_stack = p->next; free (p); } /* Call here when we see the initializer is surrounded by braces. This is instead of a call to push_init_level; it is matched by a call to pop_init_level. TYPE is the type to initialize, for a constructor expression. For an initializer for a decl, TYPE is zero. */ void really_start_incremental_init (type) tree type; { struct constructor_stack *p = (struct constructor_stack *) xmalloc (sizeof (struct constructor_stack)); if (type == 0) type = TREE_TYPE (constructor_decl); /* Turn off constructor_incremental if type is a struct with bitfields. Do this before the first push, so that the corrected value is available in finish_init. */ check_init_type_bitfields (type); p->type = constructor_type; p->fields = constructor_fields; p->index = constructor_index; p->range_end = constructor_range_end; p->max_index = constructor_max_index; p->unfilled_index = constructor_unfilled_index; p->unfilled_fields = constructor_unfilled_fields; p->bit_index = constructor_bit_index; p->elements = constructor_elements; p->constant = constructor_constant; p->simple = constructor_simple; p->erroneous = constructor_erroneous; p->pending_elts = constructor_pending_elts; p->depth = constructor_depth; p->replacement_value = 0; p->implicit = 0; p->incremental = constructor_incremental; p->outer = 0; p->next = 0; constructor_stack = p; constructor_constant = 1; constructor_simple = 1; constructor_depth = SPELLING_DEPTH (); constructor_elements = 0; constructor_pending_elts = 0; constructor_type = type; if (TREE_CODE (constructor_type) == RECORD_TYPE || TREE_CODE (constructor_type) == UNION_TYPE) { constructor_fields = TYPE_FIELDS (constructor_type); /* Skip any nameless bit fields at the beginning. */ while (constructor_fields != 0 && DECL_C_BIT_FIELD (constructor_fields) && DECL_NAME (constructor_fields) == 0) constructor_fields = TREE_CHAIN (constructor_fields); constructor_unfilled_fields = constructor_fields; constructor_bit_index = copy_node (integer_zero_node); TREE_TYPE (constructor_bit_index) = sbitsizetype; } else if (TREE_CODE (constructor_type) == ARRAY_TYPE) { constructor_range_end = 0; if (TYPE_DOMAIN (constructor_type)) { constructor_max_index = TYPE_MAX_VALUE (TYPE_DOMAIN (constructor_type)); constructor_index = copy_node (TYPE_MIN_VALUE (TYPE_DOMAIN (constructor_type))); } else constructor_index = copy_node (integer_zero_node); constructor_unfilled_index = copy_node (constructor_index); } else { /* Handle the case of int x = {5}; */ constructor_fields = constructor_type; constructor_unfilled_fields = constructor_type; } if (constructor_incremental) { int momentary = suspend_momentary (); push_obstacks_nochange (); if (TREE_PERMANENT (constructor_decl)) end_temporary_allocation (); make_decl_rtl (constructor_decl, constructor_asmspec, constructor_top_level); assemble_variable (constructor_decl, constructor_top_level, 0, 1); pop_obstacks (); resume_momentary (momentary); } if (constructor_incremental) { defer_addressed_constants (); constructor_subconstants_deferred = 1; } } /* Push down into a subobject, for initialization. If this is for an explicit set of braces, IMPLICIT is 0. If it is because the next element belongs at a lower level, IMPLICIT is 1. */ void push_init_level (implicit) int implicit; { struct constructor_stack *p; /* If we've exhausted any levels that didn't have braces, pop them now. */ while (constructor_stack->implicit) { if ((TREE_CODE (constructor_type) == RECORD_TYPE || TREE_CODE (constructor_type) == UNION_TYPE) && constructor_fields == 0) process_init_element (pop_init_level (1)); else if (TREE_CODE (constructor_type) == ARRAY_TYPE && tree_int_cst_lt (constructor_max_index, constructor_index)) process_init_element (pop_init_level (1)); else break; } /* Structure elements may require alignment. Do this now if necessary for the subaggregate, and if it comes next in sequence. Don't do this for subaggregates that will go on the pending list. */ if (constructor_incremental && constructor_type != 0 && TREE_CODE (constructor_type) == RECORD_TYPE && constructor_fields && constructor_fields == constructor_unfilled_fields) { /* Advance to offset of this element. */ if (! tree_int_cst_equal (constructor_bit_index, DECL_FIELD_BITPOS (constructor_fields))) { /* By using unsigned arithmetic, the result will be correct even in case of overflows, if BITS_PER_UNIT is a power of two. */ unsigned next = (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (constructor_fields)) / (unsigned)BITS_PER_UNIT); unsigned here = (TREE_INT_CST_LOW (constructor_bit_index) / (unsigned)BITS_PER_UNIT); assemble_zeros ((next - here) * (unsigned)BITS_PER_UNIT / (unsigned)BITS_PER_UNIT); } /* Indicate that we have now filled the structure up to the current field. */ constructor_unfilled_fields = constructor_fields; } p = (struct constructor_stack *) xmalloc (sizeof (struct constructor_stack)); p->type = constructor_type; p->fields = constructor_fields; p->index = constructor_index; p->range_end = constructor_range_end; p->max_index = constructor_max_index; p->unfilled_index = constructor_unfilled_index; p->unfilled_fields = constructor_unfilled_fields; p->bit_index = constructor_bit_index; p->elements = constructor_elements; p->constant = constructor_constant; p->simple = constructor_simple; p->erroneous = constructor_erroneous; p->pending_elts = constructor_pending_elts; p->depth = constructor_depth; p->replacement_value = 0; p->implicit = implicit; p->incremental = constructor_incremental; p->outer = 0; p->next = constructor_stack; constructor_stack = p; constructor_constant = 1; constructor_simple = 1; constructor_depth = SPELLING_DEPTH (); constructor_elements = 0; constructor_pending_elts = 0; /* Don't die if an entire brace-pair level is superfluous in the containing level. */ if (constructor_type == 0) ; else if (TREE_CODE (constructor_type) == RECORD_TYPE || TREE_CODE (constructor_type) == UNION_TYPE) { /* Don't die if there are extra init elts at the end. */ if (constructor_fields == 0) constructor_type = 0; else { constructor_type = TREE_TYPE (constructor_fields); push_member_name (constructor_fields); constructor_depth++; if (constructor_fields != constructor_unfilled_fields) constructor_incremental = 0; } } else if (TREE_CODE (constructor_type) == ARRAY_TYPE) { constructor_type = TREE_TYPE (constructor_type); push_array_bounds (TREE_INT_CST_LOW (constructor_index)); constructor_depth++; if (! tree_int_cst_equal (constructor_index, constructor_unfilled_index) || constructor_range_end != 0) constructor_incremental = 0; } if (constructor_type == 0) { error_init ("extra brace group at end of initializer"); constructor_fields = 0; constructor_unfilled_fields = 0; return; } /* Turn off constructor_incremental if type is a struct with bitfields. */ check_init_type_bitfields (constructor_type); if (implicit && warn_missing_braces && !missing_braces_mentioned) { missing_braces_mentioned = 1; warning_init ("missing braces around initializer"); } if (TREE_CODE (constructor_type) == RECORD_TYPE || TREE_CODE (constructor_type) == UNION_TYPE) { constructor_fields = TYPE_FIELDS (constructor_type); /* Skip any nameless bit fields at the beginning. */ while (constructor_fields != 0 && DECL_C_BIT_FIELD (constructor_fields) && DECL_NAME (constructor_fields) == 0) constructor_fields = TREE_CHAIN (constructor_fields); constructor_unfilled_fields = constructor_fields; constructor_bit_index = copy_node (integer_zero_node); TREE_TYPE (constructor_bit_index) = sbitsizetype; } else if (TREE_CODE (constructor_type) == ARRAY_TYPE) { constructor_range_end = 0; if (TYPE_DOMAIN (constructor_type)) { constructor_max_index = TYPE_MAX_VALUE (TYPE_DOMAIN (constructor_type)); constructor_index = copy_node (TYPE_MIN_VALUE (TYPE_DOMAIN (constructor_type))); } else constructor_index = copy_node (integer_zero_node); constructor_unfilled_index = copy_node (constructor_index); } else { warning_init ("braces around scalar initializer"); constructor_fields = constructor_type; constructor_unfilled_fields = constructor_type; } } /* Don't read a struct incrementally if it has any bitfields, because the incremental reading code doesn't know how to handle bitfields yet. */ static void check_init_type_bitfields (type) tree type; { if (TREE_CODE (type) == RECORD_TYPE) { tree tail; for (tail = TYPE_FIELDS (type); tail; tail = TREE_CHAIN (tail)) { if (DECL_C_BIT_FIELD (tail)) { constructor_incremental = 0; break; } check_init_type_bitfields (TREE_TYPE (tail)); } } else if (TREE_CODE (type) == UNION_TYPE) { tree tail = TYPE_FIELDS (type); if (tail && DECL_C_BIT_FIELD (tail)) /* We also use the nonincremental algorithm for initiliazation of unions whose first member is a bitfield, becuase the incremental algorithm has no code for dealing with bitfields. */ constructor_incremental = 0; } else if (TREE_CODE (type) == ARRAY_TYPE) check_init_type_bitfields (TREE_TYPE (type)); } /* At the end of an implicit or explicit brace level, finish up that level of constructor. If we were outputting the elements as they are read, return 0 from inner levels (process_init_element ignores that), but return error_mark_node from the outermost level (that's what we want to put in DECL_INITIAL). Otherwise, return a CONSTRUCTOR expression. */ tree pop_init_level (implicit) int implicit; { struct constructor_stack *p; int size = 0; tree constructor = 0; if (implicit == 0) { /* When we come to an explicit close brace, pop any inner levels that didn't have explicit braces. */ while (constructor_stack->implicit) process_init_element (pop_init_level (1)); } p = constructor_stack; if (constructor_type != 0) size = int_size_in_bytes (constructor_type); /* Warn when some struct elements are implicitly initialized to zero. */ if (extra_warnings && constructor_type && TREE_CODE (constructor_type) == RECORD_TYPE && constructor_unfilled_fields) { push_member_name (constructor_unfilled_fields); warning_init ("missing initializer"); RESTORE_SPELLING_DEPTH (constructor_depth); } /* Now output all pending elements. */ output_pending_init_elements (1); #if 0 /* c-parse.in warns about {}. */ /* In ANSI, each brace level must have at least one element. */ if (! implicit && pedantic && (TREE_CODE (constructor_type) == ARRAY_TYPE ? integer_zerop (constructor_unfilled_index) : constructor_unfilled_fields == TYPE_FIELDS (constructor_type))) pedwarn_init ("empty braces in initializer"); #endif /* Pad out the end of the structure. */ if (p->replacement_value) { /* If this closes a superfluous brace pair, just pass out the element between them. */ constructor = p->replacement_value; /* If this is the top level thing within the initializer, and it's for a variable, then since we already called assemble_variable, we must output the value now. */ if (p->next == 0 && constructor_decl != 0 && constructor_incremental) { constructor = digest_init (constructor_type, constructor, require_constant_value, require_constant_elements); /* If initializing an array of unknown size, determine the size now. */ if (TREE_CODE (constructor_type) == ARRAY_TYPE && TYPE_DOMAIN (constructor_type) == 0) { int failure; int momentary_p; push_obstacks_nochange (); if (TREE_PERMANENT (constructor_type)) end_temporary_allocation (); momentary_p = suspend_momentary (); /* We shouldn't have an incomplete array type within some other type. */ if (constructor_stack->next) abort (); failure = complete_array_type (constructor_type, constructor, 0); if (failure) abort (); size = int_size_in_bytes (constructor_type); resume_momentary (momentary_p); pop_obstacks (); } output_constant (constructor, size); } } else if (constructor_type == 0) ; else if (TREE_CODE (constructor_type) != RECORD_TYPE && TREE_CODE (constructor_type) != UNION_TYPE && TREE_CODE (constructor_type) != ARRAY_TYPE && ! constructor_incremental) { /* A nonincremental scalar initializer--just return the element, after verifying there is just one. */ if (constructor_elements == 0) { error_init ("empty scalar initializer"); constructor = error_mark_node; } else if (TREE_CHAIN (constructor_elements) != 0) { error_init ("extra elements in scalar initializer"); constructor = TREE_VALUE (constructor_elements); } else constructor = TREE_VALUE (constructor_elements); } else if (! constructor_incremental) { if (constructor_erroneous) constructor = error_mark_node; else { int momentary = suspend_momentary (); constructor = build (CONSTRUCTOR, constructor_type, NULL_TREE, nreverse (constructor_elements)); if (constructor_constant) TREE_CONSTANT (constructor) = 1; if (constructor_constant && constructor_simple) TREE_STATIC (constructor) = 1; resume_momentary (momentary); } } else { tree filled; int momentary = suspend_momentary (); if (TREE_CODE (constructor_type) == RECORD_TYPE || TREE_CODE (constructor_type) == UNION_TYPE) { /* Find the offset of the end of that field. */ filled = size_binop (CEIL_DIV_EXPR, constructor_bit_index, size_int (BITS_PER_UNIT)); } else if (TREE_CODE (constructor_type) == ARRAY_TYPE) { /* If initializing an array of unknown size, determine the size now. */ if (TREE_CODE (constructor_type) == ARRAY_TYPE && TYPE_DOMAIN (constructor_type) == 0) { tree maxindex = size_binop (MINUS_EXPR, constructor_unfilled_index, integer_one_node); push_obstacks_nochange (); if (TREE_PERMANENT (constructor_type)) end_temporary_allocation (); maxindex = copy_node (maxindex); TYPE_DOMAIN (constructor_type) = build_index_type (maxindex); TREE_TYPE (maxindex) = TYPE_DOMAIN (constructor_type); /* TYPE_MAX_VALUE is always one less than the number of elements in the array, because we start counting at zero. Therefore, warn only if the value is less than zero. */ if (pedantic && (tree_int_cst_sgn (TYPE_MAX_VALUE (TYPE_DOMAIN (constructor_type))) < 0)) error_with_decl (constructor_decl, "zero or negative array size `%s'"); layout_type (constructor_type); size = int_size_in_bytes (constructor_type); pop_obstacks (); } filled = size_binop (MULT_EXPR, constructor_unfilled_index, size_in_bytes (TREE_TYPE (constructor_type))); } else filled = 0; if (filled != 0) assemble_zeros (size - TREE_INT_CST_LOW (filled)); resume_momentary (momentary); } constructor_type = p->type; constructor_fields = p->fields; constructor_index = p->index; constructor_range_end = p->range_end; constructor_max_index = p->max_index; constructor_unfilled_index = p->unfilled_index; constructor_unfilled_fields = p->unfilled_fields; constructor_bit_index = p->bit_index; constructor_elements = p->elements; constructor_constant = p->constant; constructor_simple = p->simple; constructor_erroneous = p->erroneous; constructor_pending_elts = p->pending_elts; constructor_depth = p->depth; constructor_incremental = p->incremental; RESTORE_SPELLING_DEPTH (constructor_depth); constructor_stack = p->next; free (p); if (constructor == 0) { if (constructor_stack == 0) return error_mark_node; return NULL_TREE; } return constructor; } /* Within an array initializer, specify the next index to be initialized. FIRST is that index. If LAST is nonzero, then initialize a range of indices, running from FIRST through LAST. */ void set_init_index (first, last) tree first, last; { while ((TREE_CODE (first) == NOP_EXPR || TREE_CODE (first) == CONVERT_EXPR || TREE_CODE (first) == NON_LVALUE_EXPR) && (TYPE_MODE (TREE_TYPE (first)) == TYPE_MODE (TREE_TYPE (TREE_OPERAND (first, 0))))) (first) = TREE_OPERAND (first, 0); if (last) while ((TREE_CODE (last) == NOP_EXPR || TREE_CODE (last) == CONVERT_EXPR || TREE_CODE (last) == NON_LVALUE_EXPR) && (TYPE_MODE (TREE_TYPE (last)) == TYPE_MODE (TREE_TYPE (TREE_OPERAND (last, 0))))) (last) = TREE_OPERAND (last, 0); if (TREE_CODE (first) != INTEGER_CST) error_init ("nonconstant array index in initializer"); else if (last != 0 && TREE_CODE (last) != INTEGER_CST) error_init ("nonconstant array index in initializer"); else if (! constructor_unfilled_index) error_init ("array index in non-array initializer"); else if (tree_int_cst_lt (first, constructor_unfilled_index)) error_init ("duplicate array index in initializer"); else { TREE_INT_CST_LOW (constructor_index) = TREE_INT_CST_LOW (first); TREE_INT_CST_HIGH (constructor_index) = TREE_INT_CST_HIGH (first); if (last != 0 && tree_int_cst_lt (last, first)) error_init ("empty index range in initializer"); else { if (pedantic) pedwarn ("ANSI C forbids specifying element to initialize"); constructor_range_end = last; } } } /* Within a struct initializer, specify the next field to be initialized. */ void set_init_label (fieldname) tree fieldname; { tree tail; int passed = 0; /* Don't die if an entire brace-pair level is superfluous in the containing level. */ if (constructor_type == 0) return; for (tail = TYPE_FIELDS (constructor_type); tail; tail = TREE_CHAIN (tail)) { if (tail == constructor_unfilled_fields) passed = 1; if (DECL_NAME (tail) == fieldname) break; } if (tail == 0) error ("unknown field `%s' specified in initializer", IDENTIFIER_POINTER (fieldname)); else if (!passed) error ("field `%s' already initialized", IDENTIFIER_POINTER (fieldname)); else { constructor_fields = tail; if (pedantic) pedwarn ("ANSI C forbids specifying structure member to initialize"); } } /* Add a new initializer to the tree of pending initializers. PURPOSE indentifies the initializer, either array index or field in a structure. VALUE is the value of that index or field. */ static void add_pending_init (purpose, value) tree purpose, value; { struct init_node *p, **q, *r; q = &constructor_pending_elts; p = 0; if (TREE_CODE (constructor_type) == ARRAY_TYPE) { while (*q != 0) { p = *q; if (tree_int_cst_lt (purpose, p->purpose)) q = &p->left; - else if (tree_int_cst_lt (p->purpose, purpose)) + else if (p->purpose != purpose) q = &p->right; else abort (); } } else { while (*q != NULL) { p = *q; if (tree_int_cst_lt (DECL_FIELD_BITPOS (purpose), DECL_FIELD_BITPOS (p->purpose))) q = &p->left; - else if (tree_int_cst_lt (DECL_FIELD_BITPOS (p->purpose), - DECL_FIELD_BITPOS (purpose))) + else if (p->purpose != purpose) q = &p->right; else abort (); } } r = (struct init_node *) oballoc (sizeof (struct init_node)); r->purpose = purpose; r->value = value; *q = r; r->parent = p; r->left = 0; r->right = 0; r->balance = 0; while (p) { struct init_node *s; if (r == p->left) { if (p->balance == 0) p->balance = -1; else if (p->balance < 0) { if (r->balance < 0) { /* L rotation. */ p->left = r->right; if (p->left) p->left->parent = p; r->right = p; p->balance = 0; r->balance = 0; s = p->parent; p->parent = r; r->parent = s; if (s) { if (s->left == p) s->left = r; else s->right = r; } else constructor_pending_elts = r; } else { /* LR rotation. */ struct init_node *t = r->right; r->right = t->left; if (r->right) r->right->parent = r; t->left = r; p->left = t->right; if (p->left) p->left->parent = p; t->right = p; p->balance = t->balance < 0; r->balance = -(t->balance > 0); t->balance = 0; s = p->parent; p->parent = t; r->parent = t; t->parent = s; if (s) { if (s->left == p) s->left = t; else s->right = t; } else constructor_pending_elts = t; } break; } else { /* p->balance == +1; growth of left side balances the node. */ p->balance = 0; break; } } else /* r == p->right */ { if (p->balance == 0) /* Growth propagation from right side. */ p->balance++; else if (p->balance > 0) { if (r->balance > 0) { /* R rotation. */ p->right = r->left; if (p->right) p->right->parent = p; r->left = p; p->balance = 0; r->balance = 0; s = p->parent; p->parent = r; r->parent = s; if (s) { if (s->left == p) s->left = r; else s->right = r; } else constructor_pending_elts = r; } else /* r->balance == -1 */ { /* RL rotation */ struct init_node *t = r->left; r->left = t->right; if (r->left) r->left->parent = r; t->right = r; p->right = t->left; if (p->right) p->right->parent = p; t->left = p; r->balance = (t->balance < 0); p->balance = -(t->balance > 0); t->balance = 0; s = p->parent; p->parent = t; r->parent = t; t->parent = s; if (s) { if (s->left == p) s->left = t; else s->right = t; } else constructor_pending_elts = t; } break; } else { /* p->balance == -1; growth of right side balances the node. */ p->balance = 0; break; } } r = p; p = p->parent; } } /* Return nonzero if FIELD is equal to the index of a pending initializer. */ static int pending_init_member (field) tree field; { struct init_node *p; p = constructor_pending_elts; if (TREE_CODE (constructor_type) == ARRAY_TYPE) { while (p) { - if (tree_int_cst_equal (field, p->purpose)) + if (field == p->purpose) return 1; else if (tree_int_cst_lt (field, p->purpose)) p = p->left; else p = p->right; } } else { while (p) { if (field == p->purpose) return 1; else if (tree_int_cst_lt (DECL_FIELD_BITPOS (field), DECL_FIELD_BITPOS (p->purpose))) p = p->left; else p = p->right; } } return 0; } /* "Output" the next constructor element. At top level, really output it to assembler code now. Otherwise, collect it in a list from which we will make a CONSTRUCTOR. TYPE is the data type that the containing data type wants here. FIELD is the field (a FIELD_DECL) or the index that this element fills. PENDING if non-nil means output pending elements that belong right after this element. (PENDING is normally 1; it is 0 while outputting pending elements, to avoid recursion.) */ static void output_init_element (value, type, field, pending) tree value, type, field; int pending; { int duplicate = 0; if (TREE_CODE (TREE_TYPE (value)) == FUNCTION_TYPE || (TREE_CODE (TREE_TYPE (value)) == ARRAY_TYPE && !(TREE_CODE (value) == STRING_CST && TREE_CODE (type) == ARRAY_TYPE && TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE) && !comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (value)), TYPE_MAIN_VARIANT (type)))) value = default_conversion (value); if (value == error_mark_node) constructor_erroneous = 1; else if (!TREE_CONSTANT (value)) constructor_constant = 0; else if (initializer_constant_valid_p (value, TREE_TYPE (value)) == 0 || ((TREE_CODE (constructor_type) == RECORD_TYPE || TREE_CODE (constructor_type) == UNION_TYPE) && DECL_C_BIT_FIELD (field) && TREE_CODE (value) != INTEGER_CST)) constructor_simple = 0; if (require_constant_value && ! TREE_CONSTANT (value)) { error_init ("initializer element is not constant"); value = error_mark_node; } else if (require_constant_elements && initializer_constant_valid_p (value, TREE_TYPE (value)) == 0) { error_init ("initializer element is not computable at load time"); value = error_mark_node; } /* If this element duplicates one on constructor_pending_elts, print a message and ignore it. Don't do this when we're processing elements taken off constructor_pending_elts, because we'd always get spurious errors. */ if (pending) { if (TREE_CODE (constructor_type) == RECORD_TYPE || TREE_CODE (constructor_type) == UNION_TYPE || TREE_CODE (constructor_type) == ARRAY_TYPE) { if (pending_init_member (field)) { error_init ("duplicate initializer"); duplicate = 1; } } } /* If this element doesn't come next in sequence, put it on constructor_pending_elts. */ if (TREE_CODE (constructor_type) == ARRAY_TYPE && !tree_int_cst_equal (field, constructor_unfilled_index)) { if (! duplicate) /* The copy_node is needed in case field is actually constructor_index, which is modified in place. */ add_pending_init (copy_node (field), digest_init (type, value, require_constant_value, require_constant_elements)); } else if (TREE_CODE (constructor_type) == RECORD_TYPE && field != constructor_unfilled_fields) { /* We do this for records but not for unions. In a union, no matter which field is specified, it can be initialized right away since it starts at the beginning of the union. */ if (!duplicate) add_pending_init (field, digest_init (type, value, require_constant_value, require_constant_elements)); } else { /* Otherwise, output this element either to constructor_elements or to the assembler file. */ if (!duplicate) { if (! constructor_incremental) { if (field && TREE_CODE (field) == INTEGER_CST) field = copy_node (field); constructor_elements = tree_cons (field, digest_init (type, value, require_constant_value, require_constant_elements), constructor_elements); } else { /* Structure elements may require alignment. Do this, if necessary. */ if (TREE_CODE (constructor_type) == RECORD_TYPE) { /* Advance to offset of this element. */ if (! tree_int_cst_equal (constructor_bit_index, DECL_FIELD_BITPOS (field))) { /* By using unsigned arithmetic, the result will be correct even in case of overflows, if BITS_PER_UNIT is a power of two. */ unsigned next = (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field)) / (unsigned)BITS_PER_UNIT); unsigned here = (TREE_INT_CST_LOW (constructor_bit_index) / (unsigned)BITS_PER_UNIT); assemble_zeros ((next - here) * (unsigned)BITS_PER_UNIT / (unsigned)BITS_PER_UNIT); } } output_constant (digest_init (type, value, require_constant_value, require_constant_elements), int_size_in_bytes (type)); /* For a record or union, keep track of end position of last field. */ if (TREE_CODE (constructor_type) == RECORD_TYPE || TREE_CODE (constructor_type) == UNION_TYPE) { tree temp = size_binop (PLUS_EXPR, DECL_FIELD_BITPOS (field), DECL_SIZE (field)); TREE_INT_CST_LOW (constructor_bit_index) = TREE_INT_CST_LOW (temp); TREE_INT_CST_HIGH (constructor_bit_index) = TREE_INT_CST_HIGH (temp); } } } /* Advance the variable that indicates sequential elements output. */ if (TREE_CODE (constructor_type) == ARRAY_TYPE) { tree tem = size_binop (PLUS_EXPR, constructor_unfilled_index, integer_one_node); TREE_INT_CST_LOW (constructor_unfilled_index) = TREE_INT_CST_LOW (tem); TREE_INT_CST_HIGH (constructor_unfilled_index) = TREE_INT_CST_HIGH (tem); } else if (TREE_CODE (constructor_type) == RECORD_TYPE) constructor_unfilled_fields = TREE_CHAIN (constructor_unfilled_fields); else if (TREE_CODE (constructor_type) == UNION_TYPE) constructor_unfilled_fields = 0; /* Now output any pending elements which have become next. */ if (pending) output_pending_init_elements (0); } } /* Output any pending elements which have become next. As we output elements, constructor_unfilled_{fields,index} advances, which may cause other elements to become next; if so, they too are output. If ALL is 0, we return when there are no more pending elements to output now. If ALL is 1, we output space as necessary so that we can output all the pending elements. */ static void output_pending_init_elements (all) int all; { struct init_node *elt = constructor_pending_elts; tree next; retry: /* Look thru the whole pending tree. If we find an element that should be output now, output it. Otherwise, set NEXT to the element that comes first among those still pending. */ next = 0; while (elt) { if (TREE_CODE (constructor_type) == ARRAY_TYPE) { if (tree_int_cst_equal (elt->purpose, constructor_unfilled_index)) output_init_element (elt->value, TREE_TYPE (constructor_type), constructor_unfilled_index, 0); else if (tree_int_cst_lt (constructor_unfilled_index, elt->purpose)) { /* Advance to the next smaller node. */ if (elt->left) elt = elt->left; else { /* We have reached the smallest node bigger than the current unfilled index. Fill the space first. */ next = elt->purpose; break; } } else { /* Advance to the next bigger node. */ if (elt->right) elt = elt->right; else { /* We have reached the biggest node in a subtree. Find the parent of it, which is the next bigger node. */ while (elt->parent && elt->parent->right == elt) elt = elt->parent; elt = elt->parent; if (elt && tree_int_cst_lt (constructor_unfilled_index, elt->purpose)) { next = elt->purpose; break; } } } } else if (TREE_CODE (constructor_type) == RECORD_TYPE || TREE_CODE (constructor_type) == UNION_TYPE) { /* If the current record is complete we are done. */ if (constructor_unfilled_fields == 0) break; if (elt->purpose == constructor_unfilled_fields) { output_init_element (elt->value, TREE_TYPE (constructor_unfilled_fields), constructor_unfilled_fields, 0); } else if (tree_int_cst_lt (DECL_FIELD_BITPOS (constructor_unfilled_fields), DECL_FIELD_BITPOS (elt->purpose))) { /* Advance to the next smaller node. */ if (elt->left) elt = elt->left; else { /* We have reached the smallest node bigger than the current unfilled field. Fill the space first. */ next = elt->purpose; break; } } else { /* Advance to the next bigger node. */ if (elt->right) elt = elt->right; else { /* We have reached the biggest node in a subtree. Find the parent of it, which is the next bigger node. */ while (elt->parent && elt->parent->right == elt) elt = elt->parent; elt = elt->parent; if (elt && tree_int_cst_lt (DECL_FIELD_BITPOS (constructor_unfilled_fields), DECL_FIELD_BITPOS (elt->purpose))) { next = elt->purpose; break; } } } } } /* Ordinarily return, but not if we want to output all and there are elements left. */ if (! (all && next != 0)) return; /* Generate space up to the position of NEXT. */ if (constructor_incremental) { tree filled; tree nextpos_tree = size_int (0); if (TREE_CODE (constructor_type) == RECORD_TYPE || TREE_CODE (constructor_type) == UNION_TYPE) { tree tail; /* Find the last field written out, if any. */ for (tail = TYPE_FIELDS (constructor_type); tail; tail = TREE_CHAIN (tail)) if (TREE_CHAIN (tail) == constructor_unfilled_fields) break; if (tail) /* Find the offset of the end of that field. */ filled = size_binop (CEIL_DIV_EXPR, size_binop (PLUS_EXPR, DECL_FIELD_BITPOS (tail), DECL_SIZE (tail)), size_int (BITS_PER_UNIT)); else filled = size_int (0); nextpos_tree = size_binop (CEIL_DIV_EXPR, DECL_FIELD_BITPOS (next), size_int (BITS_PER_UNIT)); TREE_INT_CST_HIGH (constructor_bit_index) = TREE_INT_CST_HIGH (DECL_FIELD_BITPOS (next)); TREE_INT_CST_LOW (constructor_bit_index) = TREE_INT_CST_LOW (DECL_FIELD_BITPOS (next)); constructor_unfilled_fields = next; } else if (TREE_CODE (constructor_type) == ARRAY_TYPE) { filled = size_binop (MULT_EXPR, constructor_unfilled_index, size_in_bytes (TREE_TYPE (constructor_type))); nextpos_tree = size_binop (MULT_EXPR, next, size_in_bytes (TREE_TYPE (constructor_type))); TREE_INT_CST_LOW (constructor_unfilled_index) = TREE_INT_CST_LOW (next); TREE_INT_CST_HIGH (constructor_unfilled_index) = TREE_INT_CST_HIGH (next); } else filled = 0; if (filled) { int nextpos = TREE_INT_CST_LOW (nextpos_tree); assemble_zeros (nextpos - TREE_INT_CST_LOW (filled)); } } else { /* If it's not incremental, just skip over the gap, so that after jumping to retry we will output the next successive element. */ if (TREE_CODE (constructor_type) == RECORD_TYPE || TREE_CODE (constructor_type) == UNION_TYPE) constructor_unfilled_fields = next; else if (TREE_CODE (constructor_type) == ARRAY_TYPE) { TREE_INT_CST_LOW (constructor_unfilled_index) = TREE_INT_CST_LOW (next); TREE_INT_CST_HIGH (constructor_unfilled_index) = TREE_INT_CST_HIGH (next); } } /* ELT now points to the node in the pending tree with the next initializer to output. */ goto retry; } /* Add one non-braced element to the current constructor level. This adjusts the current position within the constructor's type. This may also start or terminate implicit levels to handle a partly-braced initializer. Once this has found the correct level for the new element, it calls output_init_element. Note: if we are incrementally outputting this constructor, this function may be called with a null argument representing a sub-constructor that was already incrementally output. When that happens, we output nothing, but we do the bookkeeping to skip past that element of the current constructor. */ void process_init_element (value) tree value; { tree orig_value = value; int string_flag = value != 0 && TREE_CODE (value) == STRING_CST; /* Handle superfluous braces around string cst as in char x[] = {"foo"}; */ if (string_flag && constructor_type && TREE_CODE (constructor_type) == ARRAY_TYPE && TREE_CODE (TREE_TYPE (constructor_type)) == INTEGER_TYPE && integer_zerop (constructor_unfilled_index)) { constructor_stack->replacement_value = value; return; } if (constructor_stack->replacement_value != 0) { error_init ("excess elements in struct initializer"); return; } /* Ignore elements of a brace group if it is entirely superfluous and has already been diagnosed. */ if (constructor_type == 0) return; /* If we've exhausted any levels that didn't have braces, pop them now. */ while (constructor_stack->implicit) { if ((TREE_CODE (constructor_type) == RECORD_TYPE || TREE_CODE (constructor_type) == UNION_TYPE) && constructor_fields == 0) process_init_element (pop_init_level (1)); else if (TREE_CODE (constructor_type) == ARRAY_TYPE && (constructor_max_index == 0 || tree_int_cst_lt (constructor_max_index, constructor_index))) process_init_element (pop_init_level (1)); else break; } while (1) { if (TREE_CODE (constructor_type) == RECORD_TYPE) { tree fieldtype; enum tree_code fieldcode; if (constructor_fields == 0) { pedwarn_init ("excess elements in struct initializer"); break; } fieldtype = TREE_TYPE (constructor_fields); if (fieldtype != error_mark_node) fieldtype = TYPE_MAIN_VARIANT (fieldtype); fieldcode = TREE_CODE (fieldtype); /* Accept a string constant to initialize a subarray. */ if (value != 0 && fieldcode == ARRAY_TYPE && TREE_CODE (TREE_TYPE (fieldtype)) == INTEGER_TYPE && string_flag) value = orig_value; /* Otherwise, if we have come to a subaggregate, and we don't have an element of its type, push into it. */ else if (value != 0 && !constructor_no_implicit && value != error_mark_node && TYPE_MAIN_VARIANT (TREE_TYPE (value)) != fieldtype && (fieldcode == RECORD_TYPE || fieldcode == ARRAY_TYPE || fieldcode == UNION_TYPE)) { push_init_level (1); continue; } if (value) { push_member_name (constructor_fields); output_init_element (value, fieldtype, constructor_fields, 1); RESTORE_SPELLING_DEPTH (constructor_depth); } else /* Do the bookkeeping for an element that was directly output as a constructor. */ { /* For a record, keep track of end position of last field. */ tree temp = size_binop (PLUS_EXPR, DECL_FIELD_BITPOS (constructor_fields), DECL_SIZE (constructor_fields)); TREE_INT_CST_LOW (constructor_bit_index) = TREE_INT_CST_LOW (temp); TREE_INT_CST_HIGH (constructor_bit_index) = TREE_INT_CST_HIGH (temp); constructor_unfilled_fields = TREE_CHAIN (constructor_fields); } constructor_fields = TREE_CHAIN (constructor_fields); /* Skip any nameless bit fields at the beginning. */ while (constructor_fields != 0 && DECL_C_BIT_FIELD (constructor_fields) && DECL_NAME (constructor_fields) == 0) constructor_fields = TREE_CHAIN (constructor_fields); break; } if (TREE_CODE (constructor_type) == UNION_TYPE) { tree fieldtype; enum tree_code fieldcode; if (constructor_fields == 0) { pedwarn_init ("excess elements in union initializer"); break; } fieldtype = TREE_TYPE (constructor_fields); if (fieldtype != error_mark_node) fieldtype = TYPE_MAIN_VARIANT (fieldtype); fieldcode = TREE_CODE (fieldtype); /* Accept a string constant to initialize a subarray. */ if (value != 0 && fieldcode == ARRAY_TYPE && TREE_CODE (TREE_TYPE (fieldtype)) == INTEGER_TYPE && string_flag) value = orig_value; /* Otherwise, if we have come to a subaggregate, and we don't have an element of its type, push into it. */ else if (value != 0 && !constructor_no_implicit && value != error_mark_node && TYPE_MAIN_VARIANT (TREE_TYPE (value)) != fieldtype && (fieldcode == RECORD_TYPE || fieldcode == ARRAY_TYPE || fieldcode == UNION_TYPE)) { push_init_level (1); continue; } if (value) { push_member_name (constructor_fields); output_init_element (value, fieldtype, constructor_fields, 1); RESTORE_SPELLING_DEPTH (constructor_depth); } else /* Do the bookkeeping for an element that was directly output as a constructor. */ { TREE_INT_CST_LOW (constructor_bit_index) = TREE_INT_CST_LOW (DECL_SIZE (constructor_fields)); TREE_INT_CST_HIGH (constructor_bit_index) = TREE_INT_CST_HIGH (DECL_SIZE (constructor_fields)); constructor_unfilled_fields = TREE_CHAIN (constructor_fields); } constructor_fields = 0; break; } if (TREE_CODE (constructor_type) == ARRAY_TYPE) { tree elttype = TYPE_MAIN_VARIANT (TREE_TYPE (constructor_type)); enum tree_code eltcode = TREE_CODE (elttype); /* Accept a string constant to initialize a subarray. */ if (value != 0 && eltcode == ARRAY_TYPE && TREE_CODE (TREE_TYPE (elttype)) == INTEGER_TYPE && string_flag) value = orig_value; /* Otherwise, if we have come to a subaggregate, and we don't have an element of its type, push into it. */ else if (value != 0 && !constructor_no_implicit && value != error_mark_node && TYPE_MAIN_VARIANT (TREE_TYPE (value)) != elttype && (eltcode == RECORD_TYPE || eltcode == ARRAY_TYPE || eltcode == UNION_TYPE)) { push_init_level (1); continue; } if (constructor_max_index != 0 && tree_int_cst_lt (constructor_max_index, constructor_index)) { pedwarn_init ("excess elements in array initializer"); break; } /* In the case of [LO .. HI] = VALUE, only evaluate VALUE once. */ if (constructor_range_end) { if (constructor_max_index != 0 && tree_int_cst_lt (constructor_max_index, constructor_range_end)) { pedwarn_init ("excess elements in array initializer"); TREE_INT_CST_HIGH (constructor_range_end) = TREE_INT_CST_HIGH (constructor_max_index); TREE_INT_CST_LOW (constructor_range_end) = TREE_INT_CST_LOW (constructor_max_index); } value = save_expr (value); } /* Now output the actual element. Ordinarily, output once. If there is a range, repeat it till we advance past the range. */ do { tree tem; if (value) { push_array_bounds (TREE_INT_CST_LOW (constructor_index)); output_init_element (value, elttype, constructor_index, 1); RESTORE_SPELLING_DEPTH (constructor_depth); } tem = size_binop (PLUS_EXPR, constructor_index, integer_one_node); TREE_INT_CST_LOW (constructor_index) = TREE_INT_CST_LOW (tem); TREE_INT_CST_HIGH (constructor_index) = TREE_INT_CST_HIGH (tem); if (!value) /* If we are doing the bookkeeping for an element that was directly output as a constructor, we must update constructor_unfilled_index. */ { TREE_INT_CST_LOW (constructor_unfilled_index) = TREE_INT_CST_LOW (constructor_index); TREE_INT_CST_HIGH (constructor_unfilled_index) = TREE_INT_CST_HIGH (constructor_index); } } while (! (constructor_range_end == 0 || tree_int_cst_lt (constructor_range_end, constructor_index))); break; } /* Handle the sole element allowed in a braced initializer for a scalar variable. */ if (constructor_fields == 0) { pedwarn_init ("excess elements in scalar initializer"); break; } if (value) output_init_element (value, constructor_type, NULL_TREE, 1); constructor_fields = 0; break; } /* If the (lexically) previous elments are not now saved, we can discard the storage for them. */ if (constructor_incremental && constructor_pending_elts == 0 && value != 0 && constructor_stack == 0) clear_momentary (); } /* Expand an ASM statement with operands, handling output operands that are not variables or INDIRECT_REFS by transforming such cases into cases that expand_asm_operands can handle. Arguments are same as for expand_asm_operands. */ void c_expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line) tree string, outputs, inputs, clobbers; int vol; char *filename; int line; { int noutputs = list_length (outputs); register int i; /* o[I] is the place that output number I should be written. */ register tree *o = (tree *) alloca (noutputs * sizeof (tree)); register tree tail; if (TREE_CODE (string) == ADDR_EXPR) string = TREE_OPERAND (string, 0); if (TREE_CODE (string) != STRING_CST) { error ("asm template is not a string constant"); return; } /* Record the contents of OUTPUTS before it is modified. */ for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++) o[i] = TREE_VALUE (tail); /* Perform default conversions on array and function inputs. */ /* Don't do this for other types-- it would screw up operands expected to be in memory. */ for (i = 0, tail = inputs; tail; tail = TREE_CHAIN (tail), i++) if (TREE_CODE (TREE_TYPE (TREE_VALUE (tail))) == ARRAY_TYPE || TREE_CODE (TREE_TYPE (TREE_VALUE (tail))) == FUNCTION_TYPE) TREE_VALUE (tail) = default_conversion (TREE_VALUE (tail)); /* Generate the ASM_OPERANDS insn; store into the TREE_VALUEs of OUTPUTS some trees for where the values were actually stored. */ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line); /* Copy all the intermediate outputs into the specified outputs. */ for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++) { if (o[i] != TREE_VALUE (tail)) { expand_expr (build_modify_expr (o[i], NOP_EXPR, TREE_VALUE (tail)), NULL_RTX, VOIDmode, EXPAND_NORMAL); free_temp_slots (); } /* Detect modification of read-only values. (Otherwise done by build_modify_expr.) */ else { tree type = TREE_TYPE (o[i]); if (TREE_READONLY (o[i]) || TYPE_READONLY (type) || ((TREE_CODE (type) == RECORD_TYPE || TREE_CODE (type) == UNION_TYPE) && C_TYPE_FIELDS_READONLY (type))) readonly_warning (o[i], "modification by `asm'"); } } /* Those MODIFY_EXPRs could do autoincrements. */ emit_queue (); } /* Expand a C `return' statement. RETVAL is the expression for what to return, or a null pointer for `return;' with no value. */ void c_expand_return (retval) tree retval; { tree valtype = TREE_TYPE (TREE_TYPE (current_function_decl)); if (TREE_THIS_VOLATILE (current_function_decl)) warning ("function declared `noreturn' has a `return' statement"); if (!retval) { current_function_returns_null = 1; if (warn_return_type && valtype != 0 && TREE_CODE (valtype) != VOID_TYPE) warning ("`return' with no value, in function returning non-void"); expand_null_return (); } else if (valtype == 0 || TREE_CODE (valtype) == VOID_TYPE) { current_function_returns_null = 1; if (pedantic || TREE_CODE (TREE_TYPE (retval)) != VOID_TYPE) pedwarn ("`return' with a value, in function returning void"); expand_return (retval); } else { tree t = convert_for_assignment (valtype, retval, _("return"), NULL_TREE, NULL_TREE, 0); tree res = DECL_RESULT (current_function_decl); tree inner; if (t == error_mark_node) return; inner = t = convert (TREE_TYPE (res), t); /* Strip any conversions, additions, and subtractions, and see if we are returning the address of a local variable. Warn if so. */ while (1) { switch (TREE_CODE (inner)) { case NOP_EXPR: case NON_LVALUE_EXPR: case CONVERT_EXPR: case PLUS_EXPR: inner = TREE_OPERAND (inner, 0); continue; case MINUS_EXPR: /* If the second operand of the MINUS_EXPR has a pointer type (or is converted from it), this may be valid, so don't give a warning. */ { tree op1 = TREE_OPERAND (inner, 1); while (! POINTER_TYPE_P (TREE_TYPE (op1)) && (TREE_CODE (op1) == NOP_EXPR || TREE_CODE (op1) == NON_LVALUE_EXPR || TREE_CODE (op1) == CONVERT_EXPR)) op1 = TREE_OPERAND (op1, 0); if (POINTER_TYPE_P (TREE_TYPE (op1))) break; inner = TREE_OPERAND (inner, 0); continue; } case ADDR_EXPR: inner = TREE_OPERAND (inner, 0); while (TREE_CODE_CLASS (TREE_CODE (inner)) == 'r') inner = TREE_OPERAND (inner, 0); if (TREE_CODE (inner) == VAR_DECL && ! DECL_EXTERNAL (inner) && ! TREE_STATIC (inner) && DECL_CONTEXT (inner) == current_function_decl) warning ("function returns address of local variable"); break; default: break; } break; } t = build (MODIFY_EXPR, TREE_TYPE (res), res, t); TREE_SIDE_EFFECTS (t) = 1; expand_return (t); current_function_returns_value = 1; } } /* Start a C switch statement, testing expression EXP. Return EXP if it is valid, an error node otherwise. */ tree c_expand_start_case (exp) tree exp; { register enum tree_code code = TREE_CODE (TREE_TYPE (exp)); tree type = TREE_TYPE (exp); if (code != INTEGER_TYPE && code != ENUMERAL_TYPE && code != ERROR_MARK) { error ("switch quantity not an integer"); exp = error_mark_node; } else { tree index; type = TYPE_MAIN_VARIANT (TREE_TYPE (exp)); if (warn_traditional && (type == long_integer_type_node || type == long_unsigned_type_node)) pedwarn ("`long' switch expression not converted to `int' in ANSI C"); exp = default_conversion (exp); type = TREE_TYPE (exp); index = get_unwidened (exp, NULL_TREE); /* We can't strip a conversion from a signed type to an unsigned, because if we did, int_fits_type_p would do the wrong thing when checking case values for being in range, and it's too hard to do the right thing. */ if (TREE_UNSIGNED (TREE_TYPE (exp)) == TREE_UNSIGNED (TREE_TYPE (index))) exp = index; } expand_start_case (1, exp, type, "switch statement"); return exp; } Index: vendor/gcc/dist/contrib/gcc/config/alpha/linux-elf.h =================================================================== --- vendor/gcc/dist/contrib/gcc/config/alpha/linux-elf.h (revision 60966) +++ vendor/gcc/dist/contrib/gcc/config/alpha/linux-elf.h (revision 60967) @@ -1,48 +1,48 @@ /* Definitions of target machine for GNU compiler for Alpha Linux-based GNU systems using ELF. Copyright (C) 1996, 1997 Free Software Foundation, Inc. Contributed by Richard Henderson. 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. */ #undef TARGET_VERSION #define TARGET_VERSION fprintf (stderr, " (Alpha GNU/Linux for ELF)"); #undef SUBTARGET_EXTRA_SPECS #define SUBTARGET_EXTRA_SPECS \ { "elf_dynamic_linker", ELF_DYNAMIC_LINKER }, #undef SUB_CPP_PREDEFINES #define SUB_CPP_PREDEFINES "-D__ELF__" #ifdef USE_GNULIBC_1 #define ELF_DYNAMIC_LINKER "/lib/ld.so.1" #else #define ELF_DYNAMIC_LINKER "/lib/ld-linux.so.2" #endif #ifndef USE_GNULIBC_1 #undef DEFAULT_VTABLE_THUNKS -#define DEFAULT_VTABLE_THUNKS 1 +#define DEFAULT_VTABLE_THUNKS 2 #endif #ifndef USE_GNULIBC_1 #undef LIB_SPEC #define LIB_SPEC \ "%{shared:-lc}%{!shared:%{pthread:-lpthread }%{profile:-lc_p}%{!profile:-lc}} " #endif Index: vendor/gcc/dist/contrib/gcc/config/elfos.h =================================================================== --- vendor/gcc/dist/contrib/gcc/config/elfos.h (revision 60966) +++ vendor/gcc/dist/contrib/gcc/config/elfos.h (revision 60967) @@ -1,704 +1,705 @@ /* elfos.h -- operating system specific defines to be used when targeting GCC for some generic ELF system - Copyright (C) 1991, 1994, 1995, 1999 Free Software Foundation, Inc. + Copyright (C) 1991, 1994, 1995, 1999, 2000 Free Software Foundation, Inc. Based on svr4.h contributed by Ron Guilmette (rfg@netcom.com). 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. */ /* For the sake of libgcc2.c, indicate target supports atexit. */ #define HAVE_ATEXIT #undef ENDFILE_SPEC #define ENDFILE_SPEC "crtend.o%s" #undef STARTFILE_SPEC #define STARTFILE_SPEC "%{!shared: \ %{!symbolic: \ %{pg:gcrt0.o%s}%{!pg:%{p:mcrt0.o%s}%{!p:crt0.o%s}}}}\ crtbegin.o%s" /* Attach a special .ident directive to the end of the file to identify the version of GCC which compiled this code. The format of the .ident string is patterned after the ones produced by native svr4 C compilers. */ #define IDENT_ASM_OP ".ident" #define ASM_FILE_END(FILE) \ do { \ if (!flag_no_ident) \ fprintf ((FILE), "\t%s\t\"GCC: (GNU) %s\"\n", \ IDENT_ASM_OP, version_string); \ } while (0) /* Output #ident as a .ident. */ #define ASM_OUTPUT_IDENT(FILE, NAME) \ fprintf (FILE, "\t%s\t\"%s\"\n", IDENT_ASM_OP, NAME); /* Use periods rather than dollar signs in special g++ assembler names. */ #define NO_DOLLAR_IN_LABEL /* Writing `int' for a bitfield forces int alignment for the structure. */ #define PCC_BITFIELD_TYPE_MATTERS 1 /* Implicit library calls should use memcpy, not bcopy, etc. */ #define TARGET_MEM_FUNCTIONS /* Handle #pragma weak and #pragma pack. */ #define HANDLE_SYSV_PRAGMA /* System V Release 4 uses DWARF debugging info. */ #define DWARF_DEBUGGING_INFO /* All ELF targets can support DWARF-2. */ #define DWARF2_DEBUGGING_INFO /* Also allow them to support STABS debugging. */ #include "dbxelf.h" /* The GNU tools operate better with stabs. Since we don't have any native tools to be compatible with, default to stabs. */ #ifndef PREFERRED_DEBUGGING_TYPE #define PREFERRED_DEBUGGING_TYPE DBX_DEBUG #endif #undef ASM_BYTE_OP #define ASM_BYTE_OP ".byte" #undef SET_ASM_OP #define SET_ASM_OP ".set" /* This is how to begin an assembly language file. Most svr4 assemblers want at least a .file directive to come first, and some want to see a .version directive come right after that. Here we just establish a default which generates only the .file directive. If you need a .version directive for any specific target, you should override this definition in the target-specific file which includes this one. */ #undef ASM_FILE_START #define ASM_FILE_START(FILE) \ output_file_directive ((FILE), main_input_filename) /* This is how to allocate empty space in some section. The .zero pseudo-op is used for this on most svr4 assemblers. */ #define SKIP_ASM_OP ".zero" #undef ASM_OUTPUT_SKIP #define ASM_OUTPUT_SKIP(FILE,SIZE) \ fprintf (FILE, "\t%s\t%u\n", SKIP_ASM_OP, (SIZE)) /* This is how to output a reference to a user-level label named NAME. `assemble_name' uses this. For System V Release 4 the convention is *not* to prepend a leading underscore onto user-level symbol names. */ #undef ASM_OUTPUT_LABELREF #define ASM_OUTPUT_LABELREF(FILE,NAME) fprintf (FILE, "%s", NAME) /* This is how to output an internal numbered label where PREFIX is the class of label and NUM is the number within the class. For most svr4 systems, the convention is that any symbol which begins with a period is not put into the linker symbol table by the assembler. */ #undef ASM_OUTPUT_INTERNAL_LABEL #define ASM_OUTPUT_INTERNAL_LABEL(FILE, PREFIX, NUM) \ do { \ fprintf (FILE, ".%s%d:\n", PREFIX, NUM); \ } while (0) /* This is how to store into the string LABEL the symbol_ref name of an internal numbered label where PREFIX is the class of label and NUM is the number within the class. This is suitable for output with `assemble_name'. For most svr4 systems, the convention is that any symbol which begins with a period is not put into the linker symbol table by the assembler. */ #undef ASM_GENERATE_INTERNAL_LABEL #define ASM_GENERATE_INTERNAL_LABEL(LABEL, PREFIX, NUM) \ do { \ sprintf (LABEL, "*.%s%d", PREFIX, NUM); \ } while (0) /* Output the label which precedes a jumptable. Note that for all svr4 systems where we actually generate jumptables (which is to say every svr4 target except i386, where we use casesi instead) we put the jump- tables into the .rodata section and since other stuff could have been put into the .rodata section prior to any given jumptable, we have to make sure that the location counter for the .rodata section gets pro- perly re-aligned prior to the actual beginning of the jump table. */ #define ALIGN_ASM_OP ".align" #ifndef ASM_OUTPUT_BEFORE_CASE_LABEL #define ASM_OUTPUT_BEFORE_CASE_LABEL(FILE,PREFIX,NUM,TABLE) \ ASM_OUTPUT_ALIGN ((FILE), 2); #endif #undef ASM_OUTPUT_CASE_LABEL #define ASM_OUTPUT_CASE_LABEL(FILE,PREFIX,NUM,JUMPTABLE) \ do { \ ASM_OUTPUT_BEFORE_CASE_LABEL (FILE, PREFIX, NUM, JUMPTABLE) \ ASM_OUTPUT_INTERNAL_LABEL (FILE, PREFIX, NUM); \ } while (0) /* The standard SVR4 assembler seems to require that certain builtin library routines (e.g. .udiv) be explicitly declared as .globl in each assembly file where they are referenced. */ #define ASM_OUTPUT_EXTERNAL_LIBCALL(FILE, FUN) \ ASM_GLOBALIZE_LABEL (FILE, XSTR (FUN, 0)) /* This says how to output assembler code to declare an uninitialized external linkage data object. Under SVR4, the linker seems to want the alignment of data objects to depend on their types. We do exactly that here. */ #define COMMON_ASM_OP ".comm" #undef ASM_OUTPUT_ALIGNED_COMMON #define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN) \ do { \ fprintf ((FILE), "\t%s\t", COMMON_ASM_OP); \ assemble_name ((FILE), (NAME)); \ fprintf ((FILE), ",%u,%u\n", (SIZE), (ALIGN) / BITS_PER_UNIT); \ } while (0) /* This says how to output assembler code to declare an uninitialized internal linkage data object. Under SVR4, the linker seems to want the alignment of data objects to depend on their types. We do exactly that here. */ #define LOCAL_ASM_OP ".local" #undef ASM_OUTPUT_ALIGNED_LOCAL #define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \ do { \ fprintf ((FILE), "\t%s\t", LOCAL_ASM_OP); \ assemble_name ((FILE), (NAME)); \ fprintf ((FILE), "\n"); \ ASM_OUTPUT_ALIGNED_COMMON (FILE, NAME, SIZE, ALIGN); \ } while (0) /* This is the pseudo-op used to generate a 32-bit word of data with a specific value in some section. This is the same for all known svr4 assemblers. */ #define INT_ASM_OP ".long" /* This is the pseudo-op used to generate a contiguous sequence of byte values from a double-quoted string WITHOUT HAVING A TERMINATING NUL AUTOMATICALLY APPENDED. This is the same for most svr4 assemblers. */ #undef ASCII_DATA_ASM_OP #define ASCII_DATA_ASM_OP ".ascii" /* Support const sections and the ctors and dtors sections for g++. Note that there appears to be two different ways to support const sections at the moment. You can either #define the symbol READONLY_DATA_SECTION (giving it some code which switches to the readonly data section) or else you can #define the symbols EXTRA_SECTIONS, EXTRA_SECTION_FUNCTIONS, SELECT_SECTION, and SELECT_RTX_SECTION. We do both here just to be on the safe side. */ #define USE_CONST_SECTION 1 #define CONST_SECTION_ASM_OP ".section\t.rodata" /* Define the pseudo-ops used to switch to the .ctors and .dtors sections. Note that we want to give these sections the SHF_WRITE attribute because these sections will actually contain data (i.e. tables of addresses of functions in the current root executable or shared library file) and, in the case of a shared library, the relocatable addresses will have to be properly resolved/relocated (and then written into) by the dynamic linker when it actually attaches the given shared library to the executing process. (Note that on SVR4, you may wish to use the `-z text' option to the ELF linker, when building a shared library, as an additional check that you are doing everything right. But if you do use the `-z text' option when building a shared library, you will get errors unless the .ctors and .dtors sections are marked as writable via the SHF_WRITE attribute.) */ #define CTORS_SECTION_ASM_OP ".section\t.ctors,\"aw\"" #define DTORS_SECTION_ASM_OP ".section\t.dtors,\"aw\"" /* On svr4, we *do* have support for the .init and .fini sections, and we can put stuff in there to be executed before and after `main'. We let crtstuff.c and other files know this by defining the following symbols. The definitions say how to change sections to the .init and .fini sections. This is the same for all known svr4 assemblers. */ #define INIT_SECTION_ASM_OP ".section\t.init" #define FINI_SECTION_ASM_OP ".section\t.fini" /* A default list of other sections which we might be "in" at any given time. For targets that use additional sections (e.g. .tdesc) you should override this definition in the target-specific file which includes this file. */ #undef EXTRA_SECTIONS #define EXTRA_SECTIONS in_const, in_ctors, in_dtors /* A default list of extra section function definitions. For targets that use additional sections (e.g. .tdesc) you should override this definition in the target-specific file which includes this file. */ #undef EXTRA_SECTION_FUNCTIONS #define EXTRA_SECTION_FUNCTIONS \ CONST_SECTION_FUNCTION \ CTORS_SECTION_FUNCTION \ DTORS_SECTION_FUNCTION #define READONLY_DATA_SECTION() const_section () extern void text_section (); #define CONST_SECTION_FUNCTION \ void \ const_section () \ { \ if (!USE_CONST_SECTION) \ text_section(); \ else if (in_section != in_const) \ { \ fprintf (asm_out_file, "%s\n", CONST_SECTION_ASM_OP); \ in_section = in_const; \ } \ } #define CTORS_SECTION_FUNCTION \ void \ ctors_section () \ { \ if (in_section != in_ctors) \ { \ fprintf (asm_out_file, "%s\n", CTORS_SECTION_ASM_OP); \ in_section = in_ctors; \ } \ } #define DTORS_SECTION_FUNCTION \ void \ dtors_section () \ { \ if (in_section != in_dtors) \ { \ fprintf (asm_out_file, "%s\n", DTORS_SECTION_ASM_OP); \ in_section = in_dtors; \ } \ } /* Switch into a generic section. This is currently only used to support section attributes. */ #define ASM_OUTPUT_SECTION_NAME(FILE, DECL, NAME, RELOC) \ do { \ static struct section_info \ { \ struct section_info *next; \ char *name; \ enum sect_enum {SECT_RW, SECT_RO, SECT_EXEC} type; \ } *sections; \ struct section_info *s; \ char *mode; \ enum sect_enum type; \ \ for (s = sections; s; s = s->next) \ if (!strcmp (NAME, s->name)) \ break; \ \ if (DECL && TREE_CODE (DECL) == FUNCTION_DECL) \ type = SECT_EXEC, mode = "ax"; \ else if (DECL && DECL_READONLY_SECTION (DECL, RELOC)) \ type = SECT_RO, mode = "a"; \ else \ type = SECT_RW, mode = "aw"; \ \ if (s == 0) \ { \ s = (struct section_info *) xmalloc (sizeof (struct section_info)); \ s->name = xmalloc ((strlen (NAME) + 1) * sizeof (*NAME)); \ strcpy (s->name, NAME); \ s->type = type; \ s->next = sections; \ sections = s; \ fprintf (FILE, ".section\t%s,\"%s\",@progbits\n", NAME, mode); \ } \ else \ { \ if (DECL && s->type != type) \ error_with_decl (DECL, "%s causes a section type conflict"); \ \ fprintf (FILE, ".section\t%s\n", NAME); \ } \ } while (0) #define MAKE_DECL_ONE_ONLY(DECL) (DECL_WEAK (DECL) = 1) #define UNIQUE_SECTION_P(DECL) (DECL_ONE_ONLY (DECL)) #define UNIQUE_SECTION(DECL,RELOC) \ do { \ int len; \ char *name, *string, *prefix; \ \ name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (DECL)); \ \ if (! DECL_ONE_ONLY (DECL)) \ { \ if (TREE_CODE (DECL) == FUNCTION_DECL) \ prefix = ".text."; \ else if (DECL_READONLY_SECTION (DECL, RELOC)) \ prefix = ".rodata."; \ else \ prefix = ".data."; \ } \ else if (TREE_CODE (DECL) == FUNCTION_DECL) \ prefix = ".gnu.linkonce.t."; \ else if (DECL_READONLY_SECTION (DECL, RELOC)) \ prefix = ".gnu.linkonce.r."; \ else \ prefix = ".gnu.linkonce.d."; \ \ len = strlen (name) + strlen (prefix); \ string = alloca (len + 1); \ sprintf (string, "%s%s", prefix, name); \ \ DECL_SECTION_NAME (DECL) = build_string (len, string); \ } while (0) /* A C statement (sans semicolon) to output an element in the table of global constructors. */ #define ASM_OUTPUT_CONSTRUCTOR(FILE,NAME) \ do { \ ctors_section (); \ fprintf (FILE, "\t%s\t ", INT_ASM_OP); \ assemble_name (FILE, NAME); \ fprintf (FILE, "\n"); \ } while (0) /* A C statement (sans semicolon) to output an element in the table of global destructors. */ #define ASM_OUTPUT_DESTRUCTOR(FILE,NAME) \ do { \ dtors_section (); \ fprintf (FILE, "\t%s\t ", INT_ASM_OP); \ assemble_name (FILE, NAME); \ fprintf (FILE, "\n"); \ } while (0) /* A C statement or statements to switch to the appropriate section for output of DECL. DECL is either a `VAR_DECL' node or a constant of some sort. RELOC indicates whether forming the initial value of DECL requires link-time relocations. */ #define SELECT_SECTION(DECL,RELOC) \ { \ if (TREE_CODE (DECL) == STRING_CST) \ { \ if (! flag_writable_strings) \ const_section (); \ else \ data_section (); \ } \ - else if (TREE_CODE (DECL) == VAR_DECL) \ + else if (TREE_CODE (DECL) == VAR_DECL \ + || TREE_CODE (DECL) == CONSTRUCTOR) \ { \ if ((flag_pic && RELOC) \ || !TREE_READONLY (DECL) || TREE_SIDE_EFFECTS (DECL) \ || !DECL_INITIAL (DECL) \ || (DECL_INITIAL (DECL) != error_mark_node \ && !TREE_CONSTANT (DECL_INITIAL (DECL)))) \ data_section (); \ else \ const_section (); \ } \ else \ const_section (); \ } /* A C statement or statements to switch to the appropriate section for output of RTX in mode MODE. RTX is some kind of constant in RTL. The argument MODE is redundant except in the case of a `const_int' rtx. Currently, these always go into the const section. */ #undef SELECT_RTX_SECTION #define SELECT_RTX_SECTION(MODE,RTX) const_section() /* Define the strings used for the special svr4 .type and .size directives. These strings generally do not vary from one system running svr4 to another, but if a given system (e.g. m88k running svr) needs to use different pseudo-op names for these, they may be overridden in the file which includes this one. */ #define TYPE_ASM_OP ".type" #define SIZE_ASM_OP ".size" /* This is how we tell the assembler that a symbol is weak. */ #define ASM_WEAKEN_LABEL(FILE,NAME) \ do { fputs ("\t.weak\t", FILE); assemble_name (FILE, NAME); \ fputc ('\n', FILE); } while (0) /* The following macro defines the format used to output the second operand of the .type assembler directive. Different svr4 assemblers expect various different forms for this operand. The one given here is just a default. You may need to override it in your machine- specific tm.h file (depending upon the particulars of your assembler). */ #define TYPE_OPERAND_FMT "@%s" /* Write the extra assembler code needed to declare a function's result. Most svr4 assemblers don't require any special declaration of the result value, but there are exceptions. */ #ifndef ASM_DECLARE_RESULT #define ASM_DECLARE_RESULT(FILE, RESULT) #endif /* These macros generate the special .type and .size directives which are used to set the corresponding fields of the linker symbol table entries in an ELF object file under SVR4. These macros also output the starting labels for the relevant functions/objects. */ /* Write the extra assembler code needed to declare a function properly. Some svr4 assemblers need to also have something extra said about the function's return value. We allow for that here. */ #define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \ do { \ fprintf (FILE, "\t%s\t ", TYPE_ASM_OP); \ assemble_name (FILE, NAME); \ putc (',', FILE); \ fprintf (FILE, TYPE_OPERAND_FMT, "function"); \ putc ('\n', FILE); \ ASM_DECLARE_RESULT (FILE, DECL_RESULT (DECL)); \ ASM_OUTPUT_LABEL(FILE, NAME); \ } while (0) /* Write the extra assembler code needed to declare an object properly. */ #define ASM_DECLARE_OBJECT_NAME(FILE, NAME, DECL) \ do { \ fprintf (FILE, "\t%s\t ", TYPE_ASM_OP); \ assemble_name (FILE, NAME); \ putc (',', FILE); \ fprintf (FILE, TYPE_OPERAND_FMT, "object"); \ putc ('\n', FILE); \ size_directive_output = 0; \ if (!flag_inhibit_size_directive && DECL_SIZE (DECL)) \ { \ size_directive_output = 1; \ fprintf (FILE, "\t%s\t ", SIZE_ASM_OP); \ assemble_name (FILE, NAME); \ fprintf (FILE, ",%d\n", int_size_in_bytes (TREE_TYPE (DECL))); \ } \ ASM_OUTPUT_LABEL(FILE, NAME); \ } while (0) /* Output the size directive for a decl in rest_of_decl_compilation in the case where we did not do so before the initializer. Once we find the error_mark_node, we know that the value of size_directive_output was set by ASM_DECLARE_OBJECT_NAME when it was run for the same decl. */ #define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP_LEVEL, AT_END) \ do { \ char *name = XSTR (XEXP (DECL_RTL (DECL), 0), 0); \ if (!flag_inhibit_size_directive && DECL_SIZE (DECL) \ && ! AT_END && TOP_LEVEL \ && DECL_INITIAL (DECL) == error_mark_node \ && !size_directive_output) \ { \ size_directive_output = 1; \ fprintf (FILE, "\t%s\t ", SIZE_ASM_OP); \ assemble_name (FILE, name); \ fprintf (FILE, ",%d\n", int_size_in_bytes (TREE_TYPE (DECL))); \ } \ } while (0) /* This is how to declare the size of a function. */ #define ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL) \ do { \ if (!flag_inhibit_size_directive) \ { \ char label[256]; \ static int labelno; \ labelno++; \ ASM_GENERATE_INTERNAL_LABEL (label, "Lfe", labelno); \ ASM_OUTPUT_INTERNAL_LABEL (FILE, "Lfe", labelno); \ fprintf (FILE, "\t%s\t ", SIZE_ASM_OP); \ assemble_name (FILE, (FNAME)); \ fprintf (FILE, ","); \ assemble_name (FILE, label); \ fprintf (FILE, "-"); \ assemble_name (FILE, (FNAME)); \ putc ('\n', FILE); \ } \ } while (0) /* A table of bytes codes used by the ASM_OUTPUT_ASCII and ASM_OUTPUT_LIMITED_STRING macros. Each byte in the table corresponds to a particular byte value [0..255]. For any given byte value, if the value in the corresponding table position is zero, the given character can be output directly. If the table value is 1, the byte must be output as a \ooo octal escape. If the tables value is anything else, then the byte value should be output as a \ followed by the value in the table. Note that we can use standard UN*X escape sequences for many control characters, but we don't use \a to represent BEL because some svr4 assemblers (e.g. on the i386) don't know about that. Also, we don't use \v since some versions of gas, such as 2.2 did not accept it. */ #define ESCAPES \ "\1\1\1\1\1\1\1\1btn\1fr\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\ \0\0\"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\\\0\0\0\ \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\ \1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\ \1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\ \1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\ \1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1" /* Some svr4 assemblers have a limit on the number of characters which can appear in the operand of a .string directive. If your assembler has such a limitation, you should define STRING_LIMIT to reflect that limit. Note that at least some svr4 assemblers have a limit on the actual number of bytes in the double-quoted string, and that they count each character in an escape sequence as one byte. Thus, an escape sequence like \377 would count as four bytes. If your target assembler doesn't support the .string directive, you should define this to zero. */ #define STRING_LIMIT ((unsigned) 256) #define STRING_ASM_OP ".string" /* The routine used to output NUL terminated strings. We use a special version of this for most svr4 targets because doing so makes the generated assembly code more compact (and thus faster to assemble) as well as more readable, especially for targets like the i386 (where the only alternative is to output character sequences as comma separated lists of numbers). */ #define ASM_OUTPUT_LIMITED_STRING(FILE, STR) \ do \ { \ register unsigned char *_limited_str = (unsigned char *) (STR); \ register unsigned ch; \ fprintf ((FILE), "\t%s\t\"", STRING_ASM_OP); \ for (; ch = *_limited_str; _limited_str++) \ { \ register int escape; \ switch (escape = ESCAPES[ch]) \ { \ case 0: \ putc (ch, (FILE)); \ break; \ case 1: \ fprintf ((FILE), "\\%03o", ch); \ break; \ default: \ putc ('\\', (FILE)); \ putc (escape, (FILE)); \ break; \ } \ } \ fprintf ((FILE), "\"\n"); \ } \ while (0) /* The routine used to output sequences of byte values. We use a special version of this for most svr4 targets because doing so makes the generated assembly code more compact (and thus faster to assemble) as well as more readable. Note that if we find subparts of the character sequence which end with NUL (and which are shorter than STRING_LIMIT) we output those using ASM_OUTPUT_LIMITED_STRING. */ #undef ASM_OUTPUT_ASCII #define ASM_OUTPUT_ASCII(FILE, STR, LENGTH) \ do \ { \ register unsigned char *_ascii_bytes = (unsigned char *) (STR); \ register unsigned char *limit = _ascii_bytes + (LENGTH); \ register unsigned bytes_in_chunk = 0; \ for (; _ascii_bytes < limit; _ascii_bytes++) \ { \ register unsigned char *p; \ if (bytes_in_chunk >= 60) \ { \ fprintf ((FILE), "\"\n"); \ bytes_in_chunk = 0; \ } \ for (p = _ascii_bytes; p < limit && *p != '\0'; p++) \ continue; \ if (p < limit && (p - _ascii_bytes) <= STRING_LIMIT) \ { \ if (bytes_in_chunk > 0) \ { \ fprintf ((FILE), "\"\n"); \ bytes_in_chunk = 0; \ } \ ASM_OUTPUT_LIMITED_STRING ((FILE), _ascii_bytes); \ _ascii_bytes = p; \ } \ else \ { \ register int escape; \ register unsigned ch; \ if (bytes_in_chunk == 0) \ fprintf ((FILE), "\t%s\t\"", ASCII_DATA_ASM_OP); \ switch (escape = ESCAPES[ch = *_ascii_bytes]) \ { \ case 0: \ putc (ch, (FILE)); \ bytes_in_chunk++; \ break; \ case 1: \ fprintf ((FILE), "\\%03o", ch); \ bytes_in_chunk += 4; \ break; \ default: \ putc ('\\', (FILE)); \ putc (escape, (FILE)); \ bytes_in_chunk += 2; \ break; \ } \ } \ } \ if (bytes_in_chunk > 0) \ fprintf ((FILE), "\"\n"); \ } \ while (0) /* All SVR4 targets use the ELF object file format. */ #define OBJECT_FORMAT_ELF Index: vendor/gcc/dist/contrib/gcc/config/i386/freebsd.h =================================================================== --- vendor/gcc/dist/contrib/gcc/config/i386/freebsd.h (revision 60966) +++ vendor/gcc/dist/contrib/gcc/config/i386/freebsd.h (revision 60967) @@ -1,257 +1,257 @@ /* Definitions for Intel 386 running FreeBSD with ELF format Copyright (C) 1996 Free Software Foundation, Inc. Contributed by Eric Youngdale. Modified for stabs-in-ELF by H.J. Lu. Adapted from GNU/Linux version by John Polstra. Continued development by David O'Brien 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. */ #undef TARGET_VERSION #define TARGET_VERSION fprintf (stderr, " (i386 FreeBSD/ELF)"); /* The svr4 ABI for the i386 says that records and unions are returned in memory. */ /* On FreeBSD, we do not. */ #undef DEFAULT_PCC_STRUCT_RETURN #define DEFAULT_PCC_STRUCT_RETURN 0 /* This gets defined in tm.h->linux.h->svr4.h, and keeps us from using libraries compiled with the native cc, so undef it. */ #undef NO_DOLLAR_IN_LABEL /* Use more efficient ``thunks'' to implement C++ vtables. */ #undef DEFAULT_VTABLE_THUNKS -#define DEFAULT_VTABLE_THUNKS 1 +#define DEFAULT_VTABLE_THUNKS 2 /* Override the default comment-starter of "/". */ #undef ASM_COMMENT_START #define ASM_COMMENT_START "#" #undef ASM_APP_ON #define ASM_APP_ON "#APP\n" #undef ASM_APP_OFF #define ASM_APP_OFF "#NO_APP\n" #undef SET_ASM_OP #define SET_ASM_OP ".set" /* This is how to output an element of a case-vector that is relative. This is only used for PIC code. See comments by the `casesi' insn in i386.md for an explanation of the expression this outputs. */ #undef ASM_OUTPUT_ADDR_DIFF_ELT #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \ fprintf (FILE, "\t.long _GLOBAL_OFFSET_TABLE_+[.-%s%d]\n", LPREFIX, VALUE) /* Indicate that jump tables go in the text section. This is necessary when compiling PIC code. */ #define JUMP_TABLES_IN_TEXT_SECTION (flag_pic) /* Use stabs instead of DWARF debug format. */ #undef PREFERRED_DEBUGGING_TYPE #define PREFERRED_DEBUGGING_TYPE DBX_DEBUG /* Copy this from the svr4 specifications... */ /* Define the register numbers to be used in Dwarf debugging information. The SVR4 reference port C compiler uses the following register numbers in its Dwarf output code: 0 for %eax (gnu regno = 0) 1 for %ecx (gnu regno = 2) 2 for %edx (gnu regno = 1) 3 for %ebx (gnu regno = 3) 4 for %esp (gnu regno = 7) 5 for %ebp (gnu regno = 6) 6 for %esi (gnu regno = 4) 7 for %edi (gnu regno = 5) The following three DWARF register numbers are never generated by the SVR4 C compiler or by the GNU compilers, but SDB on x86/svr4 believes these numbers have these meanings. 8 for %eip (no gnu equivalent) 9 for %eflags (no gnu equivalent) 10 for %trapno (no gnu equivalent) It is not at all clear how we should number the FP stack registers for the x86 architecture. If the version of SDB on x86/svr4 were a bit less brain dead with respect to floating-point then we would have a precedent to follow with respect to DWARF register numbers for x86 FP registers, but the SDB on x86/svr4 is so completely broken with respect to FP registers that it is hardly worth thinking of it as something to strive for compatibility with. The version of x86/svr4 SDB I have at the moment does (partially) seem to believe that DWARF register number 11 is associated with the x86 register %st(0), but that's about all. Higher DWARF register numbers don't seem to be associated with anything in particular, and even for DWARF regno 11, SDB only seems to under- stand that it should say that a variable lives in %st(0) (when asked via an `=' command) if we said it was in DWARF regno 11, but SDB still prints garbage when asked for the value of the variable in question (via a `/' command). (Also note that the labels SDB prints for various FP stack regs when doing an `x' command are all wrong.) Note that these problems generally don't affect the native SVR4 C compiler because it doesn't allow the use of -O with -g and because when it is *not* optimizing, it allocates a memory location for each floating-point variable, and the memory location is what gets described in the DWARF AT_location attribute for the variable in question. Regardless of the severe mental illness of the x86/svr4 SDB, we do something sensible here and we use the following DWARF register numbers. Note that these are all stack-top-relative numbers. 11 for %st(0) (gnu regno = 8) 12 for %st(1) (gnu regno = 9) 13 for %st(2) (gnu regno = 10) 14 for %st(3) (gnu regno = 11) 15 for %st(4) (gnu regno = 12) 16 for %st(5) (gnu regno = 13) 17 for %st(6) (gnu regno = 14) 18 for %st(7) (gnu regno = 15) */ #undef DBX_REGISTER_NUMBER #define DBX_REGISTER_NUMBER(n) \ ((n) == 0 ? 0 \ : (n) == 1 ? 2 \ : (n) == 2 ? 1 \ : (n) == 3 ? 3 \ : (n) == 4 ? 6 \ : (n) == 5 ? 7 \ : (n) == 6 ? 5 \ : (n) == 7 ? 4 \ : ((n) >= FIRST_STACK_REG && (n) <= LAST_STACK_REG) ? (n)+3 \ : (-1)) /* Tell final.c that we don't need a label passed to mcount. */ #undef FUNCTION_PROFILER #define FUNCTION_PROFILER(FILE, LABELNO) \ { \ if (flag_pic) \ fprintf (FILE, "\tcall *.mcount@GOT(%%ebx)\n"); \ else \ fprintf (FILE, "\tcall .mcount\n"); \ } #undef SIZE_TYPE #define SIZE_TYPE "unsigned int" #undef PTRDIFF_TYPE #define PTRDIFF_TYPE "int" #undef WCHAR_TYPE #define WCHAR_TYPE "int" #undef WCHAR_UNSIGNED #define WCHAR_UNSIGNED 0 #undef WCHAR_TYPE_SIZE #define WCHAR_TYPE_SIZE BITS_PER_WORD #undef CPP_PREDEFINES #define CPP_PREDEFINES "-Di386 -Dunix -D__ELF__ -D__FreeBSD__ -Asystem(unix) -Asystem(FreeBSD) -Acpu(i386) -Amachine(i386)" #undef CPP_SPEC #define CPP_SPEC "%(cpp_cpu) %{fPIC:-D__PIC__ -D__pic__} %{fpic:-D__PIC__ -D__pic__} %{posix:-D_POSIX_SOURCE}" /* This defines which switch letters take arguments. On FreeBSD, most of the normal cases (defined in gcc.c) apply, and we also have -h* and -z* options (for the linker) (comming from svr4). We also have -R (alias --rpath), no -z, --soname (-h), --assert etc. */ #undef SWITCH_TAKES_ARG #define SWITCH_TAKES_ARG(CHAR) \ (DEFAULT_SWITCH_TAKES_ARG (CHAR) \ || (CHAR) == 'h' \ || (CHAR) == 'z' \ || (CHAR) == 'R') /* Provide a STARTFILE_SPEC appropriate for FreeBSD. Here we add the magical crtbegin.o file (see crtstuff.c) which provides part of the support for getting C++ file-scope static object constructed before entering `main'. */ #undef STARTFILE_SPEC #define STARTFILE_SPEC \ "%{!shared: \ %{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} \ %{!p:%{profile:gcrt1.o%s} \ %{!profile:crt1.o%s}}}} \ crti.o%s %{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}" /* Provide a ENDFILE_SPEC appropriate for FreeBSD. Here we tack on the magical crtend.o file (see crtstuff.c) which provides part of the support for getting C++ file-scope static object constructed before entering `main', followed by a normal "finalizer" file, `crtn.o'. */ #undef ENDFILE_SPEC #define ENDFILE_SPEC \ "%{!shared:crtend.o%s} %{shared:crtendS.o%s} crtn.o%s" /* Provide a LIB_SPEC appropriate for FreeBSD. Just select the appropriate libc, depending on whether we're doing profiling or need threads support. (simular to the default, except no -lg, and no -p. */ #undef LIB_SPEC #define LIB_SPEC "%{!shared: \ %{!pg:%{!pthread:%{!kthread:-lc} \ %{kthread:-lpthread -lc}} \ %{pthread:-lc_r}} \ %{pg:%{!pthread:%{!kthread:-lc_p} \ %{kthread:-lpthread_p -lc_p}} \ %{pthread:-lc_r_p}}}" /* Provide a LINK_SPEC appropriate for FreeBSD. Here we provide support for the special GCC options -static and -shared, which allow us to link things in one of these three modes by applying the appropriate combinations of options at link-time. We like to support here for as many of the other GNU linker options as possible. But I don't have the time to search for those flags. I am sure how to add support for -soname shared_object_name. H.J. I took out %{v:%{!V:-V}}. It is too much :-(. They can use -Wl,-V. When the -shared link option is used a final link is not being done. */ #undef LINK_SPEC #define LINK_SPEC "-m elf_i386 \ %{Wl,*:%*} \ %{v:-V} \ %{assert*} %{R*} %{rpath*} %{defsym*} \ %{shared:-Bshareable %{h*} %{soname*}} \ %{!shared: \ %{!static: \ %{rdynamic:-export-dynamic} \ %{!dynamic-linker:-dynamic-linker /usr/libexec/ld-elf.so.1}} \ %{static:-Bstatic}} \ %{symbolic:-Bsymbolic}" /* A C statement to output to the stdio stream FILE an assembler command to advance the location counter to a multiple of 1< 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. */ #undef TARGET_VERSION #define TARGET_VERSION fprintf (stderr, " (i386 FreeBSD/ELF)"); /* The svr4 ABI for the i386 says that records and unions are returned in memory. */ /* On FreeBSD, we do not. */ #undef DEFAULT_PCC_STRUCT_RETURN #define DEFAULT_PCC_STRUCT_RETURN 0 /* This gets defined in tm.h->linux.h->svr4.h, and keeps us from using libraries compiled with the native cc, so undef it. */ #undef NO_DOLLAR_IN_LABEL /* Use more efficient ``thunks'' to implement C++ vtables. */ #undef DEFAULT_VTABLE_THUNKS -#define DEFAULT_VTABLE_THUNKS 1 +#define DEFAULT_VTABLE_THUNKS 2 /* Override the default comment-starter of "/". */ #undef ASM_COMMENT_START #define ASM_COMMENT_START "#" #undef ASM_APP_ON #define ASM_APP_ON "#APP\n" #undef ASM_APP_OFF #define ASM_APP_OFF "#NO_APP\n" #undef SET_ASM_OP #define SET_ASM_OP ".set" /* This is how to output an element of a case-vector that is relative. This is only used for PIC code. See comments by the `casesi' insn in i386.md for an explanation of the expression this outputs. */ #undef ASM_OUTPUT_ADDR_DIFF_ELT #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \ fprintf (FILE, "\t.long _GLOBAL_OFFSET_TABLE_+[.-%s%d]\n", LPREFIX, VALUE) /* Indicate that jump tables go in the text section. This is necessary when compiling PIC code. */ #define JUMP_TABLES_IN_TEXT_SECTION (flag_pic) /* Use stabs instead of DWARF debug format. */ #undef PREFERRED_DEBUGGING_TYPE #define PREFERRED_DEBUGGING_TYPE DBX_DEBUG /* Copy this from the svr4 specifications... */ /* Define the register numbers to be used in Dwarf debugging information. The SVR4 reference port C compiler uses the following register numbers in its Dwarf output code: 0 for %eax (gnu regno = 0) 1 for %ecx (gnu regno = 2) 2 for %edx (gnu regno = 1) 3 for %ebx (gnu regno = 3) 4 for %esp (gnu regno = 7) 5 for %ebp (gnu regno = 6) 6 for %esi (gnu regno = 4) 7 for %edi (gnu regno = 5) The following three DWARF register numbers are never generated by the SVR4 C compiler or by the GNU compilers, but SDB on x86/svr4 believes these numbers have these meanings. 8 for %eip (no gnu equivalent) 9 for %eflags (no gnu equivalent) 10 for %trapno (no gnu equivalent) It is not at all clear how we should number the FP stack registers for the x86 architecture. If the version of SDB on x86/svr4 were a bit less brain dead with respect to floating-point then we would have a precedent to follow with respect to DWARF register numbers for x86 FP registers, but the SDB on x86/svr4 is so completely broken with respect to FP registers that it is hardly worth thinking of it as something to strive for compatibility with. The version of x86/svr4 SDB I have at the moment does (partially) seem to believe that DWARF register number 11 is associated with the x86 register %st(0), but that's about all. Higher DWARF register numbers don't seem to be associated with anything in particular, and even for DWARF regno 11, SDB only seems to under- stand that it should say that a variable lives in %st(0) (when asked via an `=' command) if we said it was in DWARF regno 11, but SDB still prints garbage when asked for the value of the variable in question (via a `/' command). (Also note that the labels SDB prints for various FP stack regs when doing an `x' command are all wrong.) Note that these problems generally don't affect the native SVR4 C compiler because it doesn't allow the use of -O with -g and because when it is *not* optimizing, it allocates a memory location for each floating-point variable, and the memory location is what gets described in the DWARF AT_location attribute for the variable in question. Regardless of the severe mental illness of the x86/svr4 SDB, we do something sensible here and we use the following DWARF register numbers. Note that these are all stack-top-relative numbers. 11 for %st(0) (gnu regno = 8) 12 for %st(1) (gnu regno = 9) 13 for %st(2) (gnu regno = 10) 14 for %st(3) (gnu regno = 11) 15 for %st(4) (gnu regno = 12) 16 for %st(5) (gnu regno = 13) 17 for %st(6) (gnu regno = 14) 18 for %st(7) (gnu regno = 15) */ #undef DBX_REGISTER_NUMBER #define DBX_REGISTER_NUMBER(n) \ ((n) == 0 ? 0 \ : (n) == 1 ? 2 \ : (n) == 2 ? 1 \ : (n) == 3 ? 3 \ : (n) == 4 ? 6 \ : (n) == 5 ? 7 \ : (n) == 6 ? 5 \ : (n) == 7 ? 4 \ : ((n) >= FIRST_STACK_REG && (n) <= LAST_STACK_REG) ? (n)+3 \ : (-1)) /* Tell final.c that we don't need a label passed to mcount. */ #undef FUNCTION_PROFILER #define FUNCTION_PROFILER(FILE, LABELNO) \ { \ if (flag_pic) \ fprintf (FILE, "\tcall *.mcount@GOT(%%ebx)\n"); \ else \ fprintf (FILE, "\tcall .mcount\n"); \ } #undef SIZE_TYPE #define SIZE_TYPE "unsigned int" #undef PTRDIFF_TYPE #define PTRDIFF_TYPE "int" #undef WCHAR_TYPE #define WCHAR_TYPE "int" #undef WCHAR_UNSIGNED #define WCHAR_UNSIGNED 0 #undef WCHAR_TYPE_SIZE #define WCHAR_TYPE_SIZE BITS_PER_WORD #undef CPP_PREDEFINES #define CPP_PREDEFINES "-Di386 -Dunix -D__ELF__ -D__FreeBSD__ -Asystem(unix) -Asystem(FreeBSD) -Acpu(i386) -Amachine(i386)" #undef CPP_SPEC #define CPP_SPEC "%(cpp_cpu) %{fPIC:-D__PIC__ -D__pic__} %{fpic:-D__PIC__ -D__pic__} %{posix:-D_POSIX_SOURCE}" /* This defines which switch letters take arguments. On FreeBSD, most of the normal cases (defined in gcc.c) apply, and we also have -h* and -z* options (for the linker) (comming from svr4). We also have -R (alias --rpath), no -z, --soname (-h), --assert etc. */ #undef SWITCH_TAKES_ARG #define SWITCH_TAKES_ARG(CHAR) \ (DEFAULT_SWITCH_TAKES_ARG (CHAR) \ || (CHAR) == 'h' \ || (CHAR) == 'z' \ || (CHAR) == 'R') /* Provide a STARTFILE_SPEC appropriate for FreeBSD. Here we add the magical crtbegin.o file (see crtstuff.c) which provides part of the support for getting C++ file-scope static object constructed before entering `main'. */ #undef STARTFILE_SPEC #define STARTFILE_SPEC \ "%{!shared: \ %{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} \ %{!p:%{profile:gcrt1.o%s} \ %{!profile:crt1.o%s}}}} \ crti.o%s %{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}" /* Provide a ENDFILE_SPEC appropriate for FreeBSD. Here we tack on the magical crtend.o file (see crtstuff.c) which provides part of the support for getting C++ file-scope static object constructed before entering `main', followed by a normal "finalizer" file, `crtn.o'. */ #undef ENDFILE_SPEC #define ENDFILE_SPEC \ "%{!shared:crtend.o%s} %{shared:crtendS.o%s} crtn.o%s" /* Provide a LIB_SPEC appropriate for FreeBSD. Just select the appropriate libc, depending on whether we're doing profiling or need threads support. (simular to the default, except no -lg, and no -p. */ #undef LIB_SPEC #define LIB_SPEC "%{!shared: \ %{!pg:%{!pthread:%{!kthread:-lc} \ %{kthread:-lpthread -lc}} \ %{pthread:-lc_r}} \ %{pg:%{!pthread:%{!kthread:-lc_p} \ %{kthread:-lpthread_p -lc_p}} \ %{pthread:-lc_r_p}}}" /* Provide a LINK_SPEC appropriate for FreeBSD. Here we provide support for the special GCC options -static and -shared, which allow us to link things in one of these three modes by applying the appropriate combinations of options at link-time. We like to support here for as many of the other GNU linker options as possible. But I don't have the time to search for those flags. I am sure how to add support for -soname shared_object_name. H.J. I took out %{v:%{!V:-V}}. It is too much :-(. They can use -Wl,-V. When the -shared link option is used a final link is not being done. */ #undef LINK_SPEC #define LINK_SPEC "-m elf_i386 \ %{Wl,*:%*} \ %{v:-V} \ %{assert*} %{R*} %{rpath*} %{defsym*} \ %{shared:-Bshareable %{h*} %{soname*}} \ %{!shared: \ %{!static: \ %{rdynamic:-export-dynamic} \ %{!dynamic-linker:-dynamic-linker /usr/libexec/ld-elf.so.1}} \ %{static:-Bstatic}} \ %{symbolic:-Bsymbolic}" /* A C statement to output to the stdio stream FILE an assembler command to advance the location counter to a multiple of 1< #undef MD_EXEC_PREFIX #undef MD_STARTFILE_PREFIX /* Output at beginning of assembler file. */ /* The .file command should always begin the output. */ #undef ASM_FILE_START #define ASM_FILE_START(FILE) \ do { \ output_file_directive (FILE, main_input_filename); \ fprintf (FILE, "\t.version\t\"01.01\"\n"); \ } while (0) /* Provide a STARTFILE_SPEC appropriate for GNU/Linux. Here we add the GNU/Linux magical crtbegin.o file (see crtstuff.c) which provides part of the support for getting C++ file-scope static object constructed before entering `main'. */ #undef STARTFILE_SPEC #define STARTFILE_SPEC \ "%{!shared: \ %{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} %{!p:crt1.o%s}}}\ crti.o%s %{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}" /* Provide a ENDFILE_SPEC appropriate for GNU/Linux. Here we tack on the GNU/Linux magical crtend.o file (see crtstuff.c) which provides part of the support for getting C++ file-scope static object constructed before entering `main', followed by a normal GNU/Linux "finalizer" file, `crtn.o'. */ #undef ENDFILE_SPEC #define ENDFILE_SPEC \ "%{!shared:crtend.o%s} %{shared:crtendS.o%s} crtn.o%s" /* This is for -profile to use -lc_p instead of -lc. */ #undef CC1_SPEC #define CC1_SPEC "%{profile:-p} \ %{sun4:} %{target:} \ %{mcypress:-mcpu=cypress} \ %{msparclite:-mcpu=sparclite} %{mf930:-mcpu=f930} %{mf934:-mcpu=f934} \ %{mv8:-mcpu=v8} %{msupersparc:-mcpu=supersparc} \ " #undef TARGET_VERSION #define TARGET_VERSION fprintf (stderr, " (sparc GNU/Linux with ELF)"); #undef SIZE_TYPE #define SIZE_TYPE "unsigned int" #undef PTRDIFF_TYPE #define PTRDIFF_TYPE "int" #undef WCHAR_TYPE #define WCHAR_TYPE "long int" #undef WCHAR_TYPE_SIZE #define WCHAR_TYPE_SIZE BITS_PER_WORD #undef CPP_PREDEFINES #define CPP_PREDEFINES "-D__ELF__ -Dunix -D__sparc__ -Dlinux -Asystem(unix) -Asystem(posix)" #undef CPP_SUBTARGET_SPEC #ifdef USE_GNULIBC_1 #define CPP_SUBTARGET_SPEC \ "%{fPIC:-D__PIC__ -D__pic__} %{fpic:-D__PIC__ -D__pic__} %{posix:-D_POSIX_SOURCE}" #else #define CPP_SUBTARGET_SPEC \ "%{fPIC:-D__PIC__ -D__pic__} %{fpic:-D__PIC__ -D__pic__} %{posix:-D_POSIX_SOURCE} %{pthread:-D_REENTRANT}" #endif #undef LIB_SPEC /* We no longer link with libc_p.a or libg.a by default. If you want to profile or debug the GNU/Linux C library, please add -lc_p or -ggdb to LDFLAGS at the link time, respectively. */ #if 1 #ifdef USE_GNULIBC_1 #define LIB_SPEC \ "%{!shared: %{p:-lgmon} %{pg:-lgmon} %{profile:-lgmon -lc_p} \ %{!profile:%{!ggdb:-lc} %{ggdb:-lg}}}" #else #define LIB_SPEC \ "%{shared: -lc} \ %{!shared: %{mieee-fp:-lieee} %{pthread:-lpthread} \ %{profile:-lc_p} %{!profile: -lc}}" #endif #else #define LIB_SPEC \ "%{!shared: \ %{mieee-fp:-lieee} %{p:-lgmon -lc_p} %{pg:-lgmon -lc_p} \ %{!p:%{!pg:%{!g*:-lc} %{g*:-lg}}}}" #endif /* Provide a LINK_SPEC appropriate for GNU/Linux. Here we provide support for the special GCC options -static and -shared, which allow us to link things in one of these three modes by applying the appropriate combinations of options at link-time. We like to support here for as many of the other GNU linker options as possible. But I don't have the time to search for those flags. I am sure how to add support for -soname shared_object_name. H.J. I took out %{v:%{!V:-V}}. It is too much :-(. They can use -Wl,-V. When the -shared link option is used a final link is not being done. */ /* If ELF is the default format, we should not use /lib/elf. */ #undef LINK_SPEC #ifdef USE_GNULIBC_1 #ifndef LINUX_DEFAULT_ELF #define LINK_SPEC "-m elf32_sparc -Y P,/usr/lib %{shared:-shared} \ %{!shared: \ %{!ibcs: \ %{!static: \ %{rdynamic:-export-dynamic} \ %{!dynamic-linker:-dynamic-linker /lib/elf/ld-linux.so.1} \ %{!rpath:-rpath /lib/elf/}} %{static:-static}}}" #else #define LINK_SPEC "-m elf32_sparc -Y P,/usr/lib %{shared:-shared} \ %{!shared: \ %{!ibcs: \ %{!static: \ %{rdynamic:-export-dynamic} \ %{!dynamic-linker:-dynamic-linker /lib/ld-linux.so.1}} \ %{static:-static}}}" #endif #else #define LINK_SPEC "-m elf32_sparc -Y P,/usr/lib %{shared:-shared} \ %{!shared: \ %{!ibcs: \ %{!static: \ %{rdynamic:-export-dynamic} \ %{!dynamic-linker:-dynamic-linker /lib/ld-linux.so.2}} \ %{static:-static}}}" #endif /* The sun bundled assembler doesn't accept -Yd, (and neither does gas). It's safe to pass -s always, even if -g is not used. */ #undef ASM_SPEC #define ASM_SPEC \ "%{V} %{v:%{!V:-V}} %{!Qn:-Qy} %{n} %{T} %{Ym,*} %{Wa,*:%*} -s %{fpic:-K PIC} %{fPIC:-K PIC}" /* Same as sparc.h */ #undef DBX_REGISTER_NUMBER #define DBX_REGISTER_NUMBER(REGNO) (REGNO) /* We use stabs-in-elf for debugging, because that is what the native toolchain uses. XXX */ #undef PREFERRED_DEBUGGING_TYPE #define PREFERRED_DEBUGGING_TYPE DBX_DEBUG #undef ASM_OUTPUT_ALIGNED_LOCAL #define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \ do { \ fputs ("\t.local\t", (FILE)); \ assemble_name ((FILE), (NAME)); \ putc ('\n', (FILE)); \ ASM_OUTPUT_ALIGNED_COMMON (FILE, NAME, SIZE, ALIGN); \ } while (0) #undef COMMON_ASM_OP #define COMMON_ASM_OP "\t.common" /* This is how to output a definition of an internal numbered label where PREFIX is the class of label and NUM is the number within the class. */ #undef ASM_OUTPUT_INTERNAL_LABEL #define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \ fprintf (FILE, ".L%s%d:\n", PREFIX, NUM) /* This is how to output a reference to an internal numbered label where PREFIX is the class of label and NUM is the number within the class. */ #undef ASM_OUTPUT_INTERNAL_LABELREF #define ASM_OUTPUT_INTERNAL_LABELREF(FILE,PREFIX,NUM) \ fprintf (FILE, ".L%s%d", PREFIX, NUM) /* This is how to store into the string LABEL the symbol_ref name of an internal numbered label where PREFIX is the class of label and NUM is the number within the class. This is suitable for output with `assemble_name'. */ #undef ASM_GENERATE_INTERNAL_LABEL #define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM) \ sprintf (LABEL, "*.L%s%d", PREFIX, NUM) #if 0 /* Define for support of TFmode long double and REAL_ARITHMETIC. Sparc ABI says that long double is 4 words. GNU/Linux does not support long double yet. */ #define LONG_DOUBLE_TYPE_SIZE 128 #endif /* Override MACHINE_STATE_{SAVE,RESTORE} because we have special traps available which can get and set the condition codes reliably. */ #undef MACHINE_STATE_SAVE #define MACHINE_STATE_SAVE(ID) \ unsigned long int ms_flags, ms_saveret; \ asm volatile("ta 0x20\n\t" \ "mov %%g1, %0\n\t" \ "mov %%g2, %1\n\t" \ : "=r" (ms_flags), "=r" (ms_saveret)); #undef MACHINE_STATE_RESTORE #define MACHINE_STATE_RESTORE(ID) \ asm volatile("mov %0, %%g1\n\t" \ "mov %1, %%g2\n\t" \ "ta 0x21\n\t" \ : /* no outputs */ \ : "r" (ms_flags), "r" (ms_saveret)); Index: vendor/gcc/dist/contrib/gcc/cp/ChangeLog =================================================================== --- vendor/gcc/dist/contrib/gcc/cp/ChangeLog (revision 60966) +++ vendor/gcc/dist/contrib/gcc/cp/ChangeLog (revision 60967) @@ -1,16093 +1,16207 @@ +2000-03-08 Nathan Sidwell + + * exception.cc (__cp_pop_exception): Cleanup the original object. + +1999-11-13 Jason Merrill + + * rtti.c (get_tinfo_fn_unused): Split out from get_tinfo_fn. + * class.c (set_rtti_entry): Use it. + +Wed Apr 12 00:45:49 2000 Jeffrey A Law (law@cygnus.com) + + 2000-02-03 + * call.c (add_function_candidate): Do not add vlist ctor into + candidates in compatibility mode. + (build_user_type_conversion_1): Add LOOKUP_HAS_VLIST when adding + vlist. + (convert_like): Likewise. + (build_over_call): Skip vlist only if it is mentioned in flags. + (build_new_method_call): Do not add vlist in compatibility mode, + except for dtors. + * cp-tree.h (flag_vtable_thunks): Has now four possible values. + (DECL_VLIST_CTOR_WRAPPER_P, DECL_VLIST_CTOR_WRAPPED): New macros. + (in_charge_identifier): Declare external. + * decl.c (xref_basetypes): Check for vtable_thunks >=2. + (finish_dtor): Use bit 2 of in_chrg. + (finish_function): Do not finish vlist ctor wrappers. + * decl2.c (flag_vtable_thunks_compat): New variable. + (lang_decode_option): Set it accordingly. + (maybe_retrofit_in_chrg): Call make_vlist_ctor_wrapper. + * init.c (build_base_dtor_call): Pass 4 in in_chrg. + (no_vlist_base_init): New function. + (expand_default_init): Do not pass vlist in compatibility mode. + Try to call old base ctor if new one was not generated. + (build_new_1): Do not pass vlist in compatibility mode. + * method.c (get_id_2): Do not put _Vlist into dtor name in + compatibility mode. + (make_vlist_ctor_wrapper, emit_vlist_ctor_wrapper): New functions. + (synthesize_method): Call emit_vlist_ctor_wrapper. + * pt.c (instantiate_class_template): Check for vtable_thunks >=2. + + Sat Nov 13 15:48:59 1999 H.J. Lu + * init.c (finish_dtor): Call mark_all_temps_used () before + declaring vlist. + + Tue Nov 9 15:01:57 1999 H.J. Lu + * init.c (construct_virtual_bases): Update. + (expand_cleanup_for_base): Update. + + Tue Nov 9 08:25:04 1999 H.J. Lu + * init.c (construct_virtual_bases): Update. + (expand_cleanup_for_base): Take vlist parameter. + (emit_base_init): Pass vlist to expand_cleanup_for_base. + (construct_virtual_bases): Likewise. + + 1999-05-02 Martin von Löwis + * class.c (prepare_ctor_vtable, finish_one_ctor_vtable, + prepend_ctor_vfields_for_vbase, finish_ctor_vtables_for_vbases, + finish_ctor_vtables_1, prepend_vbase_vfields, + finish_ctor_vtables): New functions. + (finish_struct_1): Call finish_ctor_vtables. + * cp-tree.h (TYPE_USES_PVBASES): New macro. + (constructor_for_vbase_attr): Widen to two bits. + (CONSTRUCTOR_FOR_VBASE, CONSTRUCTOR_FOR_PVBASE, + DESTRUCTOR_FOR_PVBASE): New macros. + (DECL_CONSTRUCTOR_FOR_VBASE_P): Adopt to new enumeration. + (DECL_CONSTRUCTOR_FOR_VBASE): New macro. + (DECL_CONSTRUCTOR_FOR_PVBASE_P, DECL_DESTRUCTOR_FOR_PVBASE_P): New + macros. + (vlist_identifier, vlist_type_node, vlist_zero_node): Declare. + (VCTABLE_NAME, VLIST_NAME_FORMAT, VLIST_NAME, VLIST1_NAME, + VLIST_TYPE_NAME): New macros. + (LOOKUP_HAS_VLIST): New macro. + (build_base_dtor_call, init_vlist): Declare. + (build_destructor_name): Add int argument. + * decl.c (vlist_identifier, vlist_type_node, vlist_zero_node): + Define. + (init_decl_processing): Initialize them. + (grokdeclarator): Handle vlist argument. + (copy_args_p): Likewise. + (grok_ctor_properties): Don't try to skip initial int for + templates. Skip vlist if available. + (xref_basetypes): Set TYPE_USES_PVBASES. + (finish_dtor, finish_ctor): New functions, moved out of ... + (finish_function): ... here. + * decl2.c (lang_decode_option): Set flag_vtable_thunks explicitly. + (maybe_retrofit_in_chrg): Retrofit __vlist parameter. + (grokclassfn): Pass pvbase flag into mangled name. + * init.c (build_base_dtor_call): New function. + (build_partial_cleanup_for): Call it. + (pvbasecount, init_vlist, ): New functions. + (emit_base_init): Process vlist argument. + (expand_aggr_vbase_init_1): Likewise. + (expand_aggr_vbase_init): Likewise. + (expand_default_init): Likewise. + (build_new_1): Pass null vlist argument. + (build_delete): Likewise. Call build_base_dtor_call. + * method.c (process_overload_item): Mangle _Vlist specially. + (build_base_path, get_vlist_vtable_id): New functions. + (build_destructor_name): Potentially mangle _Vlist into it. + (do_build_copy_constructor): Skip vlist argument. + (synthesize_method): Likewise. + * pt.c (has_pvbases_p): New function. + (instantiate_class_template): Call it. + (tsubst_decl): Retrofit before mangling. Pass pvbase_p to + destructor mangling. + * search.c (expand_direct_vtbls_init_thunks): New function. + (expand_indirect_vtbls_init_thunks): New function. + (expand_indirect_vtbls_init): Call it. + * call.c (add_function_candidate): Process vlist argument. + (build_user_type_conversion_1): Add vlist argument. + (convert_like): Likewise. + (build_over_call): Likewise. + (build_new_method_call): Likewise. + 2000-02-18 Martin von Loewis * typeck2.c (my_friendly_abort): Use GCCBUGURL. 1999-11-01 Jason Merrill * decl2.c (maybe_make_one_only): Always make things comdat on ELF targets, too. Sun Oct 24 23:54:10 PDT 1999 Jeff Law (law@cygnus.com) * gcc-2.95.2 Released. 1999-09-06 Mark Mitchell * pt.c (tsubst): Back out 1999-08-06 patch. Use fold and decl_constant_value to simplify array bounds. 1999-08-19 Jason Merrill * cp-tree.h: Declare flag_use_repository. * pt.c (do_decl_instantiation): Don't complain about duplicate instantiation with -frepo. (do_type_instantiation): Likewise. 1999-08-14 Jason Merrill * decl2.c (lookup_arg_dependent): Note that we've already checked the current namespace. Mon Aug 16 01:29:24 PDT 1999 Jeff Law (law@cygnus.com) * gcc-2.95.1 Released. 1999-08-12 Mark Mitchell * decl2.c (lang_decode_option): Deprecate signatures. 1999-08-11 Martin v. Loewis * lex.c (do_identifier): If we find a hidden type after a global was selected already, continue using the global. 1999-08-10 Martin v. Loewis * decl2.c (set_decl_namespace): Do not complain about non-matching decls if processing a template. 1999-08-09 Jason Merrill * parse.y (function_try_block): Call end_protect_partials before expand_start_all_catch. 1999-08-06 Jason Merrill * pt.c (maybe_get_template_decl_from_type_decl): Make sure that we're looking at a class. * decl.c (lookup_name_real): Set the complain flag if we're looking for a namespace member. * decl.c (pushdecl): Only give an error for shadowing a parm from *this* function. * decl2.c (build_expr_from_tree, case METHOD_CALL_EXPR): Only build_expr_from_tree on the args of a TEMPLATE_ID_EXPR. * class.c (mark_overriders): Fix order of args to overrides. (warn_hidden): Likewise. Fix for having virtual and non-virtual functions with the same name. * cp-tree.h (DECL_VIRTUAL_CONTEXT): New macro. * typeck.c (expand_ptrmemfunc_cst): Calculate delta correctly for virtual functions and MI. Simplify. * typeck.c (c_expand_return): Downgrade pedwarn about returning NULL from op new to warning. * decl2.c (reparse_absdcl_as_casts): Don't warn about old-style casts in system headers or extern "C" blocks. * pt.c (do_decl_instantiation): Downgrade duplicate instantiation errors to pedwarn. * error.c (dump_type_real): Handle TREE_LIST again. * typeck.c (comp_target_parms): Don't complain about converting from () to (...) if !flag_strict_prototype. * class.c (instantiate_type): Downgrade errors for object-dependent memfn refs to pedwarn. 1999-08-06 Alexandre Oliva * pt.c (tsubst): Use build_index_type to build in-template array index type. Fixes g++.oliva/dwarf1.C. * decl.c (grokdeclarator): Likewise, just for consistency, as it doesn't seem to trigger the bug without it. Thu Aug 5 02:40:42 1999 Jeffrey A Law (law@cygnus.com) * typeck2.c: Update URLs and mail addresses. 1999-08-03 Mumit Khan * decl.c (start_decl): Set attributes before duplicate_decls call. Wed Jul 28 21:39:31 PDT 1999 Jeff Law (law@cygnus.com) * gcc-2.95 Released. Sun Jul 25 15:24:21 1999 Jeffrey A Law (law@cygnus.com) * g++FAQ.texi: Deleted per Joe Buck's request. * Makefile.in: Corresponding changes. Sat Jul 17 23:50:47 1999 Jeffrey A Law (law@cygnus.com) * Makefile.in (INTERFACE): Bump to 2. 1999-07-17 Alexandre Oliva * typeck2.c (my_friendly_abort): Updated URL with bug reporting instructions to gcc.gnu.org. Removed e-mail address. 1999-07-15 Mark Mitchell * pt.c (check_default_tmpl_args): Handle friends defined in the class just like member functions defined in the class. Thu Jul 15 01:26:49 1999 H.J. Lu * decl.c (duplicate_decls): Relax restriction for exception checks on duplicate symbols. 1999-07-07 Jason Merrill * decl.c (grokdeclarator): Update the names of all variants when de-anonymizing. Wed Jul 7 01:26:47 1999 Alexandre Oliva * decl2.c (mark_vtable_entries): Fix check for rtti offset. 1999-06-26 Richard Henderson * decl.c (cp_finish_decl): Fix typo in cp_warning_at call. 1999-06-21 Mark Mitchell * init.c (expand_aggr_vbase_init): Rename to construct_virtual_bases. Conditionalize construction here, rather than ... (emit_base_init): Here. 1999-06-19 Mark Mitchell * semantics.c (finish_asm_statement): Apply decay conversions to input operands. * decl.c (expand_static_init): When building an anonymous function for use with atexit, compute its body before and after entering the function. 1999-06-18 Mark Mitchell * init.c (expand_aggr_vbase_init): Add flag parameter. (build_partial_cleanup_for): Remove, inlining into .. (expand_cleanup_for_base): ... here. Take flag parameter. (emit_base_init): Pass the in_chrg parameter to emit_aggr_vbase_init. (emit_aggr_vbase_init): Pass it to expand_cleanup_for_base. 1999-06-16 Mark Mitchell * decl2.c (import_export_decl): Use same_type_p, rather than relying on pointer-equality for types. * method.c (do_build_copy_constructor): Simplify. * call.c (build_method_call): Remove bogus code for two-argument delete. * init.c (build_new_1): Expand on comment, and remove dead code. * init.c (expand_cleanup_for_base): New function, split out from ... (emit_base_init): Here. (expand_aggr_vbase_init): Use it. 1999-06-15 Mark Mitchell * cp-tree.h (class_cache_firstobj): Declare. (maybe_push_cache_obstack): Rename to push_cache_obstack. * class.c (permanent_obstack): Remove declaration. (class_cache_firstobj): Make it global. (add_method): Don't use permanent_obstack directly. (pushclass): Only free the class_cache_obstack if we know how far back to free it. (maybe_push_cache_obstack): Rename to push_cache_obstack. * decl.c: Remove dead comment. (saved_scope): Add class_cache_firstobj. (push_to_top_level): Save it. (pop_from_top_level): Restore it. (push_class_level_binding): Use push_cache_obstack, not maybe_push_cache_obstack. * search.c (push_class_decls): Likewise. 1999-06-14 Nathan Sidwell * call.c (build_new_op): Remove REF_BIND from all operands. 1999-06-07 Mark Mitchell * search.c (convert_pointer_to_single_level): Reimplement without using get_binfo. 1999-06-06 Mark Mitchell * method.c (is_back_referenceable_type): Back-reference bools when not squangling. 1999-06-04 Jason Merrill * semantics.c (finish_if_stmt_cond): Copy cond to permanent_obstack. (finish_while_stmt_cond, finish_do_stmt, finish_for_cond): Likewise. 1999-05-30 Mark Mitchell * lex.c (make_lang_type): Create TYPE_BINFO for TEMPLATE_TYPE_PARMs just like for non-template types. 1999-05-28 Nathan Sidwell * decl.c (complete_array_type): Allocate off same obstack. Fix DO_DEFAULT comment to match reality. 1999-05-22 Mark Mitchell * tree.c (mapcar): Handle NON_LVALUE_EXPR. 1999-05-21 Mark Mitchell * typeck.c (build_ptrmemfunc): Handle PTRMEM_CSTs carefully to reveal optimization opportunities. 1999-05-20 Mark Mitchell * decl.c (grokdeclarator): Don't treat [] as indicating a zero-sized array in a typedef. * call.c (build_object_call): Don't look at DECL_NAME for a type. (pt.c): Or CP_TYPE_QUALS for an ERROR_MARK. (typeck.c): Or TYPE_MAIN_VARIANT for a type. 1999-05-20 Jason Merrill * tree.c (lvalue_p_1): A NOP_EXPR can be an lvalue. (build_cplus_new): Make sure that what we return is of the right type. 1999-05-20 Mark Mitchell * cp-tree.h (make_ptrmem_cst): New function. * expr.c (cplus_expand_constant): Split out from ... (cplus_expand_expr): Here. Use cplus_expand_constant. (init_cplus_expand): Set lang_expand_constant. * pt.c (convert_nontype_argument): Use make_ptrmem_cst. * tree.c (make_ptrmem_cst): Define. * typeck.c (unary_complex_lvalue): Use make_ptrmem_cst. * typeck2.c (initializer_constant_valid_p): Use make_ptrmem_cst. 1999-05-19 Mark Mitchell * decl2.c (start_static_storage_duration_function): Fix comment. (finish_file): Create static storage duration functions lazily. Wed May 19 02:50:53 1999 Arvind Sankar * gxxint.texi: Fix typo. 1999-05-18 Jason Merrill * call.c (joust): Compare the types of the conv ops, not the target types of the conversions. Tue May 18 00:21:34 1999 Zack Weinberg * lang-specs.h: Define __GNUC__ and __GNUC_MINOR__ only if -no-gcc was not given. 1999-05-17 Mark Mitchell * cp-tree.def (TEMPLATE_ID_EXPR): Update documentation. * decl.c (grokfndecl): Don't allow inline declarations of friend template specializations, or friend template specializations with default arguments. * pt.c (tsubst): Handle substitution into array types that does not yield a fixed upper bound, even when not processing a template. (tsubst_copy): Deal with the fact that the second operand to a TEMPLATE_ID_EXPR may be NULL_TREE, a TREE_LIST, or a TREE_VEC. * search.c (marked_pushdecls_p): Don't descend into TEMPLATE_TYPE_PARMs and the like. (unmarked_pushdecls_p): Likewise. * call.c (build_over_call): Don't throw away initializations/copies of empty classes; use MODIFY_EXPR and INIT_EXPR as for non-empty classes. * class.c (finish_struct_1): Put the padding byte for an empty class on the TYPE_NONCOPIED_PARTS list for the class. 1999-05-16 Mark Mitchell * decl2.c (build_expr_from_tree): Handle COMPONENT_REFs that indicate a reference to a field that is a qualified name. 1999-05-16 Jason Merrill * decl2.c (finish_objects): Don't use .?tors.* if we don't have ASM_OUTPUT_CONSTRUCTOR. * friend.c (do_friend): Add attrlist arg. Remove support for getting a non-decl as 'decl'. * decl.c (grokfndecl): Remove attrlist arg. Don't set attrs or rtl. (grokdeclarator): Adjust. * cp-tree.h: Adjust. 1999-05-16 Mark Mitchell * cp-tree.h (permanent_p): New function. * init.c (build_new_1): Use mapcar, not copy_node, to copy a possibly complex tree node. * tree.c (mapcar): Adjust comments, and follow coding standards in conditional. (permanent_p): New function. 1999-05-13 Per Bothner * class.c (push_lang_context): Turn off DECL_IGNORED_P for primitive Java types, if we actually see `extern "Java"'. 1999-05-10 18:21 -0400 Zack Weinberg * lang-specs.h: Pass -$ to the preprocessor. 1999-05-10 Jason Merrill * init.c (build_offset_ref): Wrap baselinks in OFFSET_REF, too. Don't bother wrapping an OFFSET_TYPE around unknown_type_node. (resolve_offset_ref): Don't handle a raw baselink. * cvt.c (build_expr_type_conversion): Likewise. * typeck.c (decay_conversion, build_c_cast, convert_for_assignment, convert_for_initialization): Likewise. * class.c (instantiate_type): Handle seeing a baselink under an OFFSET_REF. * error.c (dump_expr): Likewise. * pt.c (for_each_template_parm): Likewise. (resolve_overloaded_unification): Likewise. * tree.c (is_overloaded_fn, really_overloaded_fn): Likewise. * typeck.c (expr_sizeof): Also complain about other permutations of overloaded functions. 1999-05-07 Jason Merrill * init.c (resolve_offset_ref): Don't return a raw method. Use BASELINK_P. * typeck.c (decay_conversion): Don't handle a raw method. Resolve all OFFSET_REFs. (get_member_function_from_ptrfunc): 0 is a valid vtable index. (build_binary_op_nodefault): Handle resolving overloaded fns. Use same_type_p for pmf bits. Don't use build_binary_op to compare raw pointers to methods. (convert_for_assignment): Check for OFFSET_REF, not OFFSET_TYPE, to decide when to call resolve_offset_ref. (build_c_cast, convert_for_initialization): Likewise. * cvt.c (build_expr_type_conversion): Likewise. 1999-05-06 Nathan Sidwell * call.c (build_new_method_call): Use TYPE_MAIN_VARIANT of class. 1999-05-05 Mark Mitchell * decl2.c (start_objects): Don't let static constructors and destructors get inlined. * parse.y (nested_name_specifier): Make sure ordinary types are complete, just like template types. * parse.c: Regenerated. * pt.c (check_explicit_specialization): Improve error messages. 1999-05-04 Martin von Löwis * typeck.c (string_conv_p): Use same_type_p to check whether we try to convert between char and wchar_t. 1999-05-03 Mark Mitchell * search.c (lookup_field_r): Set the TREE_TYPE of an ambiguous lookup to error_mark_node here. (lookup_member): Revise documentation. Add comments. Don't set the TREE_TYPE to error_mark_node here, and don't build up an extra TREE_LIST for ambiguous lookups. (setup_class_bindings): Adjust accordingly. (push_class_decls): Revise out-of-date comments. * typeck.c (build_const_cast): Tighten checks for legality. 1999-05-02 Martin von Löwis * init.c (build_member_call): Lookup names coming from namespace-scoped LOOKUP_EXPR. 1999-05-03 Jim Blandy * gxxint.texi: Add documentation for 'I'. 1999-05-02 Martin von Löwis * tinfo.cc (operator==): Qualify type_info with std::. 1999-05-02 Mark Mitchell * cp-tree.h (lang_decl_flags): Remove comdat. Updated dummy. (DECL_COMDAT): Remove definition. 1999-05-01 Mark Mitchell * decl.c (wrapup_globals_for_namespace): Fix thinko in previous change. 1999-04-30 Mark Mitchell * class.c (build_vtable): Use build_lang_decl when building vtables, not just build_decl. (prepare_fresh_vtable): Likewise. * decl.c (wrapup_globals_for_namespace): Mark vtables as DECL_EXTERNAL when calling wrapup_global_declarations. * decl2.c (priority_info_s): Add initializations_p and destructions_p members. (finish_vtable_vardecl): Use TREE_SYMBOL_REFERENCED, not TREE_USED, when deciding what vtables to write out. (ssdf_decls): New variable. (ssdf_decls_used): Likewise. (start_static_storage_duration_function): Deal with being called multiple times. Avoid inlining this function. (generate_inits_for_priority): Deal with reuse of priority map. (get_priority_info): Clear initializations_p and destructions_p. (do_static_initialization): Tweak comment. (do_static_destruction): Likewise. Fix condition on sentries for destruction. (generate_ctor_or_dtor_function): Call all of the static storage duration functions. (generate_ctor_or_dtor_function_for_priority): Check initializations_p and destructions_p to see what priorities need initialization functions. (finish_file): Rework to generate multiple static storage duration functions, rather than just one. * typeck.c (build_const_cast): Tweak last change to handle templates correctly. * typeck.c (build_const_cast): Disallow use of const_cast to anything but a pointer or reference type. 1999-04-30 Nathan Sidwell * decl.c (cp_finish_decl): Don't permit arrays of abstract or signature type. 1999-04-29 Mark Mitchell * decl2.c (do_static_destruction): Remove obsolete FIXME comment. (finish_file): Indent comments properly. 1999-04-29 Richard Henderson * decl2.c (do_static_initialization): Call do_pending_stack_adjust. (do_static_destruction): Likewise. 1999-04-29 Nathan Sidwell * cp-tree.h (TYPE_NOTHROW_P): New macro. * decl2.c (delete_sanity): Warn on deleting void *. * init.c (build_new_1): Use TYPE_NOTHROW_P. * typeck.c (c_expand_return): cp_pedwarn on returning NULL from throwing operator new. 1999-04-28 Nathan Sidwell * cp-tree.h (build_component_addr): Remove prototype. * typeck.c (build_component_addr): Make static. Remove MSG argument. (build_component_addr): Remove MSG parameter, clean up comment. (build_x_function_call): Use cp_error. (build_unary_op): Adjust call of build_component_addr. 1999-04-28 Mark Mitchell * pt.c (tsubst_friend_class): Check for NULL. Wed Apr 28 11:42:22 1999 Andreas Schwab * search.c (binfo_for_vtable): Initialize bfvi.var. 1999-04-27 Nathan Sidwell * rtti.c (build_x_typeid): Check rtti is enabled. 1999-04-26 Mark Mitchell * search.c (is_subobject_of_p): Make sure we're looking at the right baseclasses. 1999-04-26 Marc Espie * Make-lang.in (cplib2.ready): Don't depend on phony targets. 1999-04-23 Mark Mitchell * decl2.c (finish_file): Tweak handling of extern inlines so that they are not unnecessarily put out. * search.c (is_subobject_of_p): Handle TEMPLATE_TYPE_PARMs and such as base classes. 1999-04-22 Brendan Kehoe * tree.c (build_exception_variant): Fix typo: use the chain of U, not trying V, while cycling through U. 1999-04-22 Mark Mitchell * cp-tree.h (lang_decl_flags): Remove returns_first_arg and preserves_first_arg. Enlarge dummy accordingly. (DECL_TINFO_FN_P): New macro. (SET_DECL_TINFO_FN_P): Likeiwse. (DECL_RETURNS_FIRST_ARG): Remove. (DECL_PRESERVES_THIS): Likewise. (DECL_INIT_PRIORITY): New macro. (finish_struct_1): Change prototype. (cat_namespace_levels): Remove prototype. (vtable_decl_p): New prototype. (vtype_decl_p): Likewise. (sigtable_decl_p): Likewise. (walk_globals_pred): New typedef. (walk_globals_fn): Likewise. (walk_globals): New prototype. (walk_namespaces_fn): New typedef. (walk_namespaces): New prototype. (wrapup_globals_for_namespace): Likewise. (walk_vtables): Remove prototype. (walk_sigtables): Likewise. (instantiate_pending_templates): New prototype. * class.c (finish_struct_1): Don't return a value. * decl.h (pending_statics): Remove declaration. * decl.c (walk_namespaces_r): New function. (walk_globals_r): Likewise. (vtable_decl_p): Likewise. (vtype_decl_p): Likewise. (sigtable_decl_p): Likewise. (walk_namespaces): Likewise. (walk_globals_data): New type. (walk_globals): New function. (wrapup_globals_for_namespace): Likewise. (expand_static_init): Remove assertion. Remove redundancy in conditional. Don't put static data members in static_aggregates Tidy. (finish_function): Remove redundancy in conditional. Don't set DECL_RETURNS_FIRST_ARG. (cat_namespace_levels): Remove. * decl2.c: Include splay-tree.h and varray.h. (priority_info_s): New structure. (finish_vtable_vardecl): Change prototype. Adjust for new calling conventions. (prune_vtable_vardecl): Likewise. (finish_sigtable_vardecl): Likewise. (setup_initp): Remove. (do_dtors): Remove. (do_ctors): Remove. (start_static_storage_duration_function): New function. (generate_inits_for_priority): Likewise. (finish_static_storage_duration_function): Likewise. (get_priority_info): Likewise. (do_static_initialization): Likewise. (do_static_destruction): Likewise. (do_static_initialization_and_destruction): Likewise. (generate_ctor_or_dtor_function): Likewise. (generate_ctor_and_dtor_functions_for_priority): Likewise. (pending_statics): Make it a varray. (pending_statics_used): New variable. (saved_inlines): Make it a varray. (saved_inlines_used): New variable. (finish_static_data_member): Change method of updating pending_statics. (mark_inline_for_output): Remove #if 0'd code. Change method of updating saved_inlines. (walk_vtables): Remove. (walk_sigtables): Likewise. (import_export_decl): Use DECL_TINFO_FN_P. (pending_templates): Remove declaration. (maybe_templates): Likewise. (static_aggregates_initp): Likewise. (setup_initp): Likewise. (finish_objects): Simplify. (INITIALIZE_P_IDENTIFIER): New macro. (PRIORITY_IDENTIFIER): New macro. (SSDF_IDENTIFIER): New macro. (initialize_p_decl): New variable. (priority_decl): Likewise. (ssdf_decl): Likewise. (priority_info_map): Likewise. (finish_file): Recode output of static intializers and other file-scope finalization tasks. * error.c (OB_END_TEMPLATE_ID): New macro. (dump_type_real): Use it. (dump_decl): Likewise. (dump_function_name): Likewise. * lex.c (set_typedecl_interface_info): Adjust for new walk_globals interface. (check_newline): Use walk_globals, not walk_vtables. * pt.c (pending_tempalte_expansions): Remove. (set_vardecl_interface_info): Likewise. (pending_templates): Make static. (maybe_templates): Likewise. (instantiate_class_template): Adjust call to finish_struct_1. (instantiate_pending_templates): New function. * rtti.c (get_tinfo_fn): Use SET_DECL_TINFO_FN_P. * tree.c (static_aggregates_initp): Remove. (cp_valid_lang_attribute): Don't use it; use DECL_INIT_PRIORITY instead. * Makefile.in (decl2.o): Depend on varray.h and splay-tree.h. * gxx.gperf (RETURN): Rename to RETURN_KEYWORD to avoid clashes with the RTL code RETURN. * hash.h: Regenerated. * lex.c (reinit_parse_for_block): Use RETURN_KEYWORD. * parse.y: Replace RETURN with RETURN_KEYWORD throughout. * parse.c: Regenerated. * pt.c: Include varray.h. Include rtl.h since varray.h requires it. (inline_parm_levels): New variable. (inline_parm_levels_used): Likewise. (maybe_begin_member_template_processing): Update them. (maybe_end_member_template_processing): Use them, rather than guessing how many levels to pop. * decl.c (make_typename_type): Tighten error-checking. 1999-04-20 Mark Mitchell * cp-tree.h (build_binary_op): Remove unneeded parameter. * class.c (build_vrable_entry_ref): Adjust call to build_binary_op. * decl.c (expand_static_init): Likewise. (grokdeclarator): Likewise. (finish_function): Likewise. * decl2.c (delete_sanity): Likewise. (do_dtors): Likewise. (do_ctors): Likewise. * error.c (dump_type_suffix): Likewise. * expr.c (cplus_expand_expr): Likewise. * init.c (resolve_offset_ref): Likewise. (build_new): Likewise. (build_new_1): Likewise. (build_vec_delete_1): Likewise. (expand_vec_init_catch_clause): Likewise. (build_delete): Likewise. * pt.c (tsubst): Likewise. * rtti.c (synthesize_tinfo_fn): Likewise. * search.c (expand_upcast_fixups): Likewise. (expand_direct_vtbls_init): Likewise. * typeck.c (get_member_function_from_ptrfunc): Likewise. (build_binary_op_nodefault): Likewise. (point_int_sum): Likewise. (pointer_diff): Likewise. (build_unary_op): Likewise. (build_modify_expr): Likewise. (get_delta_difference): Likewise. (build_ptrmemfunc): Likewise. (expand_ptrmemfunc_cst): Likewise. 1999-04-20 Jason Merrill * decl.c (grokfndecl): Always call cplus_decl_attributes. * decl2.c (grokfield): Pass attrlist to grokdeclarator. 1999-04-19 Mark Mitchell * cp-tree.h (finish_static_data_member_decl): New function. * decl2.c (finish_static_data_member_decl): Split out from ... (grokfield): Here. * pt.c (instantiate_class_template): Use it here instead of trying to fake it. (tsubst_decl): Don't set DECL_ASSEMBLER_NAME; finish_static_data_member_decl will do that. Explicit set DECL_EXTERNAL to match non-template processing. 1999-04-18 Mark Mitchell * cp-tree.h (finish_class_definition): Add parameter. * parse.y (structsp): Use it. Don't call pop_scope here. * parse.c: Regenerated. * semantics.c (finish_class_definition): Pop it here. 1999-04-17 Mark Mitchell * decl.c (xref_tag): Revise handling of nested template declarations. * pt.c (check_explicit_specialization): Tweak handling of friend templates in template classes. (tsubst_friend_class): Handle friend declarations for nested member template classes. 1999-04-16 Mark Mitchell * class.c (finish_struct): Remove unused variable. (pushclass): Likewise. (invalidate_class_lookup_cache): Likewise. * cp-tree.def (TYPENAME_TYPE): Improve documentation. * decl.c (build_typename_type): Make sure TYPENAME_TYPE_FULLNAME doesn't get obliterated. (make_typename_type): Handle template classes correctly. * cp-tree.h (TREE_NONLOCAL_FLAG): Remove. (storetags): Declare. * class.c (finish_struct): Don't use TREE_NONLOCAL_FLAG. (pushclass): Likewise. Use storetags to install tag declarations, not pushtag. (invalidate_class_lookup_cache): Don't use TREE_NONLOCAL_FLAG. * decl.c (storetags): Make it global. (push_class_binding): Set INHERITED_VALUE_BINDING_P for an implicit typename declaration. (pushtag): Tidy. Don't use TREE_NONLOCAL_FLAG. * method.c (hack_identifier): Likewise. * search.c (lookup_member): Likewise. * decl.c (warn_about_implicit_typename_lookup): New function. (lookup_name_real): Use it. Rework handling of implicit typename extension. 1999-04-15 Mark Mitchell * cp-tree.h (lookup_nested_field): Remove. * class.c (push_nested_class): Handle UNION_TYPEs. (pop_nested_class): Likewise. * decl.c (lookup_name_real): Don't call lookup_nested_field. (start_decl): Use push_nested_class, not just pushclass. (cp_finish_decl): Use pop_nested_class, not just popclass. * search.c (lookup_nested_field): Remove. * cp-tree.h (lang_type): Add documentation. * decl2.c (handle_class_head): Create template declarations here, as appropriate. * parse.y (class_head): Return whether or not we entered a new scope, as well as the type named. (named_class_head): Likewise. (named_complex_class_head_sans_basetype): Likewise. (structsp): Adjust accordingly. Pop scope when required. * parse.c: Regenerated. * pt.c (check_default_tmpl_args): Robustify. (redeclare_class_template): Likewise. (instantiate_class_template): An instantiation of an anonymous union is itself an anonymous union. * semantics.c (begin_class_definition): Don't create template declarations here. 1999-04-15 Jason Merrill * parse.y (after_type_declarator_intern): New nonterminal. (after_type_declarator): Use it. (direct_after_type_declarator): Likewise. Move above nonnested_type to fix reduce/reduce conflict resolution. (declmods): Reducing from just 'attributes' has EMPTY precedence. * Makefile.in (CONFLICTS): Update. * decl.c (define_label): Downgrade error for jumping over a non-POD decl to pedwarn. 1999-04-14 Mark Mitchell * cp-tree.h (popclass): Change declaration. (pop_nested_class): Likewise. (poplevel_class): Remove declaration. * call.c (convert_default_argument): Pass no arguments to popclass. * class.c (finish_struct_1): Likewise. (finish_struct): Likewise. (popclass): Remove argument. Simplify code accordingly. (pop_nested_class): Likewise. * decl.c (poplevel_class): Declare it here, and make it static. (poplevel): Handle class scopes. (poplevel_class): Don't take an rgument. Simplify. (pop_everything): Pass no arguments to pop_nested_class. (cp_finish_decl): Pass no arguments to popclass. (grokdeclarator): Pass no arguments to pop_nested_class. (finish_function): Likewise. * decl2.c (grokfield): Likewise. (pop_scope): Pass no arguments to popclass. * lex.c (do_pending_defargs): Pass no arguments to pop_nested_class. * pt.c (instantiate_class_template): Move call to pushclass, and document. Pass no arguments to popclass. (regenerate_decl_from_template): Likewise. 1999-04-14 Jason Merrill * typeck.c (build_unary_op): Handle taking the address of a unique bound non-static member function. 1999-04-13 Martin von Loewis * lang-options.h (-Wdeprecated): New flag. * decl2.c (warn_deprecated): New flag. (lang_decode_option): Deprecated this-is-variable, external-templates, alt-external-templates. Support -Wdeprecated. * errfn.c (cp_deprecated): New function. 1999-04-13 Jason Merrill * decl2.c (setup_initp): Compare DECL_ASSEMBLER_NAME instead of the decls themselves. * pt.c (tsubst_function_type): Copy attributes over. * tree.c (cp_valid_lang_attribute): New fn. Handle init_priority and com_interface. * cp-tree.h: Add prototype. * decl.c (init_decl_processing): Set valid_lang_attribute. 1999-04-13 Mark Mitchell * class.c (finish_struct_1): Look at the const-ness of the field's type, not the TREE_READONLY-ness of the declaration. * method.c (synthesize_method): Likewise. * pt.c (tsubst_decl): Call c_apply_type_quals_to_decl when creating new declarations. 1999-04-13 Mike Stump * decl2.c (import_export_decl): Because vtables always reference virtual functions, even if they are inlined, don't allow -fno-implement-inlines to not emit them, instead, emit them with the vtable. * decl.c (start_function): Likewise. 1999-04-12 Jason Merrill * cp-tree.h (struct lang_type): Add com_interface. (CLASSTYPE_COM_INTERFACE): New macro. * class.c (set_rtti_entry): COM interface classes have no RTTI entries in their vtables; adjust. (add_virtual_function, finish_base_struct, skip_rtti_stuff, modify_one_vtable, fixup_vtable_deltas1, override_one_vtable, finish_struct_1): Likewise. * decl2.c (mark_vtable_entries): Likewise. * rtti.c (build_headof, get_tinfo_fn_dynamic): Likewise. * search.c (get_abstract_virtuals_1, get_abstract_virtuals, expand_upcast_fixups): Likewise. * tree.c (debug_binfo): Likewise. * cp-tree.h (COMPARE_NO_ATTRIBUTES): New macro. * typeck.c (comptypes): If we get it, ignore attributes. * class.c (instantiate_type): Use BASELINK_P. Change complain parameter to flags; 2 means ignore attributes. * call.c (build_op_delete_call): Pass it. * decl.c (xref_tag): Only complain once about using a typedef-name with 'struct'. Downgrade to pedwarn. * decl.c (grokdeclarator): Allow [] syntax for zero-length array. * parse.y (absdcl_intern): New nonterminal. (absdcl, direct_abstract_declarator): Use it. * pt.c (lookup_template_class): Look through implict typename. 1999-04-11 Mark Mitchell * friend.c (add_friend): Deal gracefully with error_mark_node. * method.c (build_overload_value): Handle pointers-to-members as template parameters. * decl.c (push_binding): Fix typo in comment. 1999-04-10 Mark Mitchell * error.c (dump_type_real): If a typename is a template-id, put out the template arguments. (dump_expr): Handle TEMPLATE_ID_EXPR. * pt.c (lookup_template_class): Now that full arguments are available everywhere, remove code that tried to guess them. 1999-04-09 Mark Mitchell * decl.c (make_typename_type): Complain if we don't find a type when trying to make a typename type for a non-template type. 1999-04-09 Jason Merrill * decl.c (start_decl): Pass attributes to grokdeclarator. (grokdeclarator): Handle attributes on constructor-syntax initializers. 1999-04-08 Mark Mitchell * error.c (dump_expr): Don't crash on INDIRECT_REFs whose operands don't have types. * search.c (template_self_reference_p): Tweak. 1999-04-07 Mark Mitchell * init.c (build_offset_ref): Don't build yet another weird data structure to describe overloaded functions. 1999-04-06 Mark Mitchell * cp-tree.h (BASELINK_P): New macro. (SET_BASELINK_P): Likewise. * init.c (build_member_call): Remove needless assignment in if statement. * search.c (lookup_field_r): Fix handling when we are looking specifically for a type; these are not hidden by functions and variables. (lookup_member): Use SET_BASELINK_P. * tree.c (is_overloaded_fn): Use BASELINK_P. (really_overloaed_fn): Likewise. (get_first_fn): Likewise. 1999-04-05 Mark Mitchell * decl.c (lookup_name_current_level): Tweak, and improve documentation. * class.c (maybe_fixup_vptrs): Remove declaration. (build_class_init_list): Likewise. * decl.c (pushdecl_class_level): Call check_template_shadow here ... (push_class_level_binding): ... not here. * search.c (dfs_push_type_decls): Only avoid template-self-reference TYPE_DECLs if they are from base classes. 1999-04-04 Mark Mitchell * pt.c (check_template_shadow): Don't treat OVERLOADs as _DECL nodes. Tidy. 1999-04-03 Jason Merrill * class.c (maybe_fixup_vptrs, build_class_init_list): Lose. (finish_struct_1): Don't call build_class_init_list. 1999-04-02 Mark Mitchell * tinfo.h (__class_type_info): Fix illegal declaration. * cp-tree.def (TEMPLATE_ID_EXPR): Update comment. * cp-tree.h (INHERITED_VALUE_BINDING_P): New macro. (IDENTIFIER_CLASS_VALUE): Improve documentation. (is_properly_derived_from): Declare. (invalidate_class_lookup_cache): Likewise. (maybe_maybe_note_name_used_in_class): Likewise. (note_name_declared_in_class): Likewise. (push_using_decl): Remove duplicate declaration. (id_in_current_class): Remove declaration. (push_class_binding): Change prototype. (clear_identitifer_class_values): Declare. * call.c (is_properly_derived_from): Make it global. (build_new_function_call): Be careful about updating candidates. (build_new_method_call): Handle COMPONENT_REFs. Don't crash when asked to make illegal calls. * class.c: Include splay-tree.h. (class_stack_node): Add names_used slot. (check_member_decl_is_same_in_complete_scope): Remove. (add_method): Fix comment. Push the declaration into class scope. (finish_struct_1): When popping the class, pop the bindings too. Remove check for data member/function member conflict. (finish_struct): Remove calls to check_member_decl_is_same_in_complete_scope. Change calls to popclass. (pushclass): Clear names_used in the class stack entry. Use invalidate_class_lookup_cache to remove cached entries, rather than magic values with popclass. Clear IDENTIFIER_CLASS_VALUE before entering a new class. Remove dead code. Don't mess with current_function_decl when pushing declarations. (invalidate_class_lookup_cache): New function, split out from ... (popclass): Here. Clean up names_used on our way out. (instantiate_type): Adjust. (build_self_reference): Don't push the declaration here. (maybe_note_name_used_in_class): New function. (note_name_declared_in_class): Likewise. * decl.c (add_binding): Change prototype. (find_class_binding_level): New function. (innermost_nonclass_level): Likewise. (current_binding_level): Update documentation. (inner_binding_level): Remove. Replace with current_binding_level throughout. (push_binding_level): Remove special handling of class_binding_level. (pop_binding_level): Likewise. Use find_class_binding_level. (suspend_binding_level): Likewise. (global_bindings_p): Use innermost_nonclass_level. (toplevel_bindings_p): Likewise. (namespace_bindings_p): Likewise. (pseudo_global_level_p): Likewise. (push_binding): Clear INHERITED_VALUE_BINDING_P. (add_binding): Check for illegal multiple declarations. Return a value indicating whether or not the new binding was legal. (push_local_binding): Skip over class binding levels. Check return value from add_binding. (push_class_binding): Set INHERITED_VALUE_BINDING_P. Call note_name_declared_in_class. (pushlevel_class): Remove "fake out the rest of the compiler" code. (poplevel_class): Reset IDENTIFIER_CLASS_VALUEs. (clear_identifier_class_values): New function. (pop_from_top_level): Use it. (pop_everything): Tweak. (maybe_process_template_type_declaration): Don't push the declaration for the template here. (pushtag): Don't push tag declarations into class scope here. (pushdecl): Apply DeMorgan's law for readability. (pushdecl_class_level): Remove special-case code for TYPE_BEING_DEFINED. Handle OVERLOADs and anonymous unions. (push_class_level_bindng): Deal with inherited bindings. (lookup_name_real): Remove special-case code for TYPE_BEING_DEFINED, and some implicit typename magic. (grokdeclarator): Handle COMPONENT_REF for a template function. (build_enumerator): Don't call pushdecl_class_level here. (id_in_current_class): Remove. * decl2.c (grokfield): Don't call pushdecl_class_level or check_template_shadow. * errfn.c (cp_file_of): Don't declare. (cp_line_of): Likewise. * error.c (dump_decl): Handle an OVERLOAD. (cp_file_of): Likewise. (cp_line_of): Likewise. * init.c (build_member_call): Handle a COMPONENT_REF. * lex.c (do_identifier): Call maybe_note_name_used_in_class, not pushdecl_class_level. * method.c (hack_identifier): Build COMPONENT_REFs for references to member templates as well as member functions. Remove dead code. * parse.y (left_curly): Remove. (nonnested_type): Call maybe_note_name_used_in_class, not pushdecl_class_level. * parse.c: Regenerated. (nested_name_specifier_1): Likewise. * pt.c (check_explicit_specialization): Adjust, for robustness. (check_template_shadow): Handle OVERLOADs. (build_template_decl): Set DECL_CONSTRUCTOR_P on the TEMPLATE_DECL, if appropriate. * search.c (envelope_add_decl): Remove. (dfs_pushdecls): Likewise. (dfs_compress_decls): Likewise. (dfs_push_decls): New function. (dfs_push_type_decls): Likewise. (setup_class_bindings): Likewise. (template_self_reference_p): Likewise. (lookup_field_r): Use it. (looup_member): Remove old comment. Deal with ambiguity. (push_class_decls): Use dfs_push_decls and dfs_push_type_decls, and remove envelope processing. * semantics.c (begin_class_definition): Let pushclass push declarations for base classes. (finish_member_declaration): Push declarations into class scope. * typeck.c (build_component_ref): Just put an OVERLOAD into the COMPONENT_REF, not a TREE_LIST of an OVERLOAD. (build_x_function_call): Deal with OVERLOAD. Handle template-ids. * Makefile.in (class.o): Depend on splay-tree.h. Wed Mar 31 11:30:43 1999 Nathan Sidwell * cvt.c (convert_pointer_to_real): Use same_type_p. * typeck.c (comp_target_types): Use same_type_p. 1999-03-31 Jason Merrill * semantics.c (begin_inline_definitions, finish_inline_definitions): Rename from finish_default_args and begin_inline_definitions, respectively, to something that isn't a total lie. :) * parse.y (structsp): Adjust. * tree.c (hash_tree_cons): Remove obsolete via_* parms. (list_hash_lookup): Likewise. (hash_tree_chain): Adjust. * pt.c (tsubst): Adjust. (tsubst_arg_types): Use plain hash_tree_cons. * cp-tree.h (hash_tree_cons_simple): Lose. * parse.y (declmods, nonempty_cv_qualifiers): Use hash_tree_cons. Wed Mar 31 10:48:29 1999 Kaveh R. Ghazi * Makefile.in (hash.h): Generate using gperf language 'C', not 'KR-C', so gperf uses the `const' keyword on strings. * gxx.gperf (resword): Const-ify a char*. 1999-03-30 Jason Merrill * cp-tree.h (IDENTIFIER_AS_DESC, IDENTIFIER_AS_LIST, CLASSTYPE_BASELINK_VEC, CLASSTYPE_N_SUPERCLASSES, CLASSTYPE_N_BASECLASSES, CLASSTYPE_MAX_DEPTH, CLASSTYPE_BASE_INIT_LIST, CLASSTYPE_AS_LIST, CLASSTYPE_ID_AS_LIST, CLASSTYPE_BINFO_AS_LIST): Remove cruft. * class.c, lex.c, parse.y, ptree.c, search.c, semantics.c, tree.c: Adjust. 1999-03-29 Jason Merrill * decl2.c (lang_decode_option): Remove -Wsign-promo from -Wall. 1999-03-28 Jason Merrill * pt.c (fn_type_unification): Ignore 'this' parm from conversion ops. 1999-03-27 Mark Mitchell * cp-tree.h (add_friend): Declare. (add_friends): Likewise. * friend.c (add_friend): Make it global. Don't add to DECL_BEFRIENDING_CLASSES if the befriending class is a template. (add_friends): Make it global. (make_friend_class): Don't add to DECL_BEFRIENDING_CLASSES if the befriending class is a template. * parse.y (component_decl_1): Fix typo in comment. * parse.c: Regenerated. * pt.c (instantiate_class_template): Use add_friend and add_friends rather that duplicating some of their functionality here. 1999-03-27 Jason Merrill * call.c (build_field_call): Unify 'this' and non-'this' cases. * typeck.c (build_indirect_ref): Check for 'this' sooner. Fri Mar 26 10:20:34 1999 Kaveh R. Ghazi * call.c (op_error): Const-ify a char*. (add_candidate, source_type, add_warning): Add static prototype. (print_z_candidates): Const-ify a char*. * class.c (resolve_address_of_overloaded_function, fixed_type_or_null, build_vtable_entry_ref): Add static prototype. (get_vtable_name, finish_struct_1): Const-ify a char*. * cvt.c (convert_to_reference): Likewise. * decl.c (redeclaration_error_message, record_builtin_type, record_unknown_type, member_function_or_else, bad_specifiers): Likewise. (find_binding, select_decl, unqualified_namespace_lookup, lookup_flags, qualify_lookup, record_builtin_java_type, tag_name): Add static prototype. (warn_extern_redeclared_static, duplicate_decls, pushdecl, implicitly_declare, record_builtin_java_type, define_function, grok_op_properties, tag_name): Const-ify a char*. * cp-tree.h (FORMAT_VBASE_NAME): Allow parameter `BUF' to be const. (define_function, finish_builtin_type): Const-ify a char*. (cp_error, cp_error_at, cp_warning, cp_warning_at, cp_pedwarn, cp_pedwarn_at, cp_compiler_error, cp_sprintf): Add prototype args. (file_name_nondirectory): Const-ify a char*. (init_filename_times): Don't prototype. (compiler_error): Prototype. (yyerror, init_repo): Const-ify a char*. (build_srcloc): Don't prototype. (build_x_indirect_ref, build_indirect_ref, build_component_addr): Const-ify a char*. (warn_for_assignment): Don't prototype. (convert_for_initialization, readonly_error, check_for_new_type, GNU_xref_begin, GNU_xref_file, GNU_xref_ref, GNU_xref_call): Const-ify a char*. * decl2.c (acceptable_java_type, output_vtable_inherit, setup_initp, start_objects, finish_objects, do_dtors, do_ctors, merge_functions, decl_namespace, validate_nonmember_using_decl, do_nonmember_using_decl): Add static prototype. (lang_f_options): Const-ify a char*. (finish_builtin_type): Likewise. (add_function, arg_assoc_namespace, arg_assoc_class): Add static prototype. * errfn.c: Include cp-tree.h. (cp_thing): Add static prototype. (compiler_error): Don't protoptype. (cp_compiler_error): Cast `compiler_error' to `errorfn' before passing it to `cp_thing'. * error.c (interesting_scope_p): Add static prototype. * except.c (build_eh_type_type, build_eh_type_type_ref): Const-ify a char*. * init.c (compiler_error): Don't prototype. (member_init_ok_or_else): Const-ify a char*. (build_java_class_ref): Add static prototype. * lex.c (compiler_error): Don't prototype. (get_time_identifier, interface_strcmp, extend_token_buffer, handle_cp_pragma): Const-ify a char*. (is_global, init_filename_times): Add static prototype. (file_name_nondirectory, cplus_tree_code_name): Const-ify a char*. (compiler_error): Change from fixed args to variable args. (yyerror): Const-ify a char*. * parse.y (cond_stmt_keyword): Const-ify a char*. (parse_decl): Add static prototype. * pt.c (template_args_equal, print_template_context): Likewise. (print_candidates, check_default_tmpl_args): Const-ify a char*. (instantiate_class_template): Likewise. * repo.c (get_base_filename, open_repo_file, init_repo): Likewise. * rtti.c (call_void_fn, expand_generic_desc, expand_si_desc, expand_class_desc, expand_ptr_desc, expand_attr_desc): Likewise. * search.c (lookup_field_info, lookup_member): Likewise. (lookup_member): Cast the first argument of `bzero' to a PTR. * sig.c (compiler_error): Don't prototype. (build_signature_pointer_or_reference_nam): Const-ify a char*. (get_sigtable_name, build_member_function_pointer): Likewise. * tree.c (compiler_error): Don't prototype. (no_linkage_helper, build_srcloc): Add static prototype. (build_vbase_pointer_fields): Const-ify a char*. (__eprintf): Don't unnecessarily handle `const' when !__STDC__. * typeck.c (compiler_error): Don't prototype. (convert_for_assignment): Const-ify a char*. (comp_cv_target_types): Add static prototype. (build_x_indirect_ref, build_indirect_ref, convert_arguments, build_component_addr, build_unary_op, convert_for_initialization): Const-ify a char*. * typeck2.c (ack): Add static prototype and change from fixed args to variable args. (readonly_error, check_for_new_type): Const-ify a char*. * xref.c (_XREF_FILE, find_file, filename, fctname, declname, fixname, open_xref_file, classname, GNU_xref_begin): Likewise. (GNU_xref_file): Likewise. Also use `xmalloc' instead of `malloc'. (GNU_xref_end_scope, GNU_xref_ref, GNU_xref_decl, GNU_xref_call, gen_assign, GNU_xref_member): Const-ify a char*. 1999-03-25 Martin von Löwis * gxxint.texi: Remove old discussion on copying virtual bases. 1999-03-25 Zack Weinberg * Make-lang.in: Remove all references to g++.o/g++.c. Link g++ from gcc.o. 1999-03-25 Jason Merrill * decl2.c (comdat_linkage): Treat vtables like functions. 1999-03-25 Mark Mitchell * pt.c (tsubst_decl): tsubst into DECL_BEFRIENDING_CLASSES. 1999-03-25 Nathan Sidwell * decl.c (init_decl_processing): Add `signed' type as a synonym for `int'. 1999-03-25 Jason Merrill * typeck.c (common_type): Handle cv-qual unification for pointers to members. * decl.c (unqualified_namespace_lookup): Return error_mark_node on error. (lookup_name_real): Set LOOKUP_COMPLAIN when *not* parsing. * lex.c (do_identifier): If we got error_mark_node, call lookup_name again. 1999-03-24 Martin von Löwis * class.c (finish_struct_1): Always reset TYPE_FIELDS for empty classes. 1999-03-24 Jason Merrill * decl.c (lookup_name_real): Do nested field lookup regardless of TYPE_BEING_DEFINED. 1999-03-24 Mark Mitchell * cp-tree.h (lang_type): Remove has_assignment and has_real_assignment. Add befriending_classes. (TYPE_HAS_ASSIGNMENT): Remove. (TYPE_HAS_REAL_ASSIGNMENT): Likewise. (CLASSTYPE_BEFRIENDING_CLASSES): New macro. (lang_decl): Document. (DECL_BEFRIENDING_CLASSES): New macro. (FRIEND_NAME): Move declaration to more obvious location. (FRIEND_DECLS): Likewise. * class.c (finish_struct_1): Don't use TYPE_HAS_REAL_ASSIGNMENT. * decl.c (duplicate_decls): Copy DECL_BEFRIENDING_CLASSES. (fixup_anonymous_union): Don't use TYPE_HAS_ASSIGNMENT. (grok_op_properties): Likewise. * friend.c (is_friend): Use FRIEND_NAME and FRIEND_DECLS. (add_friend): Likewise. Don't do weird things with assignment operators. Update DECL_BEFRIENDING_CLASSES. (add_friends): Don't do weird things with assignment operators. (make_friend_class): Likewise. Update CLASSTYPE_BEFRIENDING_CLASSES. * pt.c (instantiate_class_template): Don't set TYPE_HAS_ASSIGNMENT. (tsubst_copy): Substitute the TREE_TYPE for more unary expressions. * ptree.c (print_lang_type): Don't look at TYPE_HAS_ASSIGNMENT. * search.c (protected_accessible_p): New function. (friend_accessible_p): Likewise. (accessible_p): Use them. 1999-03-23 Mark Mitchell * pt.c (convert_nontype_argument): Don't create things that aren't PTRMEM_CSTs when applying a qualification conversion to a PTRMEM_CST. 1999-03-23 Mark Mitchell * Makefile.in (OBJS): Don't mention hash.o. (OBJDEPS): Likewise. 1999-03-23 Jason Merrill * decl2.c (finish_file): Set at_eof to 2 after expanding ctors. * decl.c (expand_static_init): Make sure we don't add any after then. * decl.c (cp_finish_decl): Move intelligence about handling DECL_COMDAT for variables from here... * decl2.c (comdat_linkage): ...to here. (maybe_make_one_only): Tweak. (import_export_decl): Call comdat_linkage for variables, too. (finish_file): Handle template statics properly. 1999-03-22 Mark Mitchell * cp-tree.h (TYPE_PTRMEMFUNC_P): Use TYPE_PTRMEMFUNC_FLAG. Document internals of pointer-to-member-functions. (DELTA2_FROM_PTRMEMFUNC): Make it call delta2_from_ptrmemfunc. (PFN_FROM_PTRMEMFUNC): Likewise. (build_type_conversion): Remove unused parameter. (build_ptrmemfunc1): Declare. (expand_ptrmemfunc_cst): New function. (delta2_from_ptrmemfunc): Likewise. (pfn_from_ptrmemfunc): Likewise. * cvt.c (cp_convert_to_pointer): Remove unused parameter to build_type_conversion. Use TYPE_PTRMEM_P for readability. (convert_to_reference): Remove unused parameter to build_type_conversion. (ocp_convert): Likewise. (build_user_type_conversion): Likewise. * error.c (dump_expr): Handle NULL pointer-to-member functions. * expr.c (cplus_expand_expr): Handle PTRMEM_CSTs for functions. * method.c (build_overload_value): Don't go splitting CONSTRUCTORs open when handling pointer-to-member functions. * pt.c (convert_nontype_argument): Clean up error messages. Be more stringent with pointers-to-members. * typeck.c (build_ptrmemfunc1): Don't declare. Make it global. (build_unary_op): Tidy ever-so-slightly. (build_conditional_expr): Remove extra parameter to build_type_conversion. (build_ptrmemfunc): Build PTRMEM_CSTs if we know what function we're using. (expand_ptrmemfunc_cst): Define. (delta2_from_ptrmemfunc): Likewise. (pfn_from_ptrmemfunc): Likewise. 1999-03-19 Mark Mitchell * init.c (build_member_call): Handle template-id expressions correctly. * typeck.c (build_x_function_call): Likewise. 1999-03-19 Chip Salzenberg * friend.c (make_friend_class): Avoid core dump when not-yet-defined friend type lacks TYPE_LANG_SPECIFIC(). 1999-03-18 Jason Merrill * decl.c (start_function): Suppress normal linkage heuristics for #pragma interface under MULTIPLE_SYMBOL_SPACES. 1999-03-19 Alexandre Oliva * Make-lang.in: ($(INTL_TARGETS)): Depend on cp/parse.c. ($(srcdir)/cp/parse.c): Moved from ../Makefile.in. 1999-03-17 Martin von Löwis * parse.y (named_complex_class_head_sans_basetype): Do not push a scope for error_mark_node. (maybe_base_class_list): Likewise. * decl.c (start_decl): Check for error_mark_node as a type. Detected by g++.brendan/array-refs.C. (start_decl_1): Likewise. Detected by g++.bugs/900322_01.C. (maybe_build_cleanup_1): Likewise. Detected by g++.jason/incomplete1.C. * tree.c (build_dummy_object): Use void_zero_node instead of the error_mark_node. (is_dummy_object): Check for such a node. Detected by g++.bob/inherit1.C 1999-03-16 Jason Merrill * method.c (old_backref_index): Split out... (flush_repeats): From here. Rename back from try_old_backref. (build_mangled_name): Put back some old-style repeat handling. Mon Mar 15 21:57:16 1999 Kaveh R. Ghazi * lex.c: Don't include setjmp.h. (parse_float): New static function. (pf_args): New struct. (real_yylex): Use them in call to `do_float_handler'. 1999-03-15 Mark Mitchell * decl.c (xref_basetypes): Set CLASSTYPE_VBASECLASSES here. * tree.c (layout_basetypes): Not here. * search.c (dfs_search): Remove; no longer used. 1999-03-12 Mark Mitchell * decl2.c (validate_nonmember_using_decl): Issue sensible error-messages on bogus qualifiers. 1999-03-14 Jason Merrill * call.c (add_function_candidate): Fix uninitialized variable. * Makefile.in (search.o): Add dependency on varray.h. 1999-03-13 Jason Merrill * decl.c (duplicate_decls): Use same_type_p. * method.c (try_old_backref): Renamed from flush_repeats. Use same_type_p. Don't try to handle repeats. Return success. (is_back_referenceable_type): Return 0 if TYPE_FOR_JAVA. Support calls from old-style code, too. (check_ktype): Use same_type_p. (check_btype): Use same_type_p. Don't pull out TYPE_MAIN_VARIANT. (build_qualified_name): Simplify logic. (process_overload_item): Strip typedefs and quals at the top. (build_mangled_name_for_type_with_Gcode): Remove call to type_canonical_variant. (build_mangled_name): Likewise. Remove support for old-style repeats, which have been disabled since 2.7.2. Don't mess with TREE_USED. (build_decl_overload_real): Don't mess with TREE_USED. 1999-03-13 Nathan Sidwell * error.c (cp_printers): Add 'F' escape character. (dump_type_real): Remove TREE_LIST (fnargs) printing. Functionality moved to dump_parameters. (dump_type_suffix): Use dump_parameters and dump_exception_spec. (dump_function_decl): Extend meaning of V parameter. Use dump_parameters and dump_exception_spec. (dump_parameters): New static function. (dump_exception_spec): New static function. (fndecl_as_string): Change argument semantics. Use dump_function_decl directly. * sig.c (build_signature_table_constructor): Use cp_error. 1999-03-13 Martin von Löwis * semantics.c (finish_switch_cond): Handle error cases gracefully. Detected by g++.law/enum5.C. * typeck.c (build_modify_expr): Check for errors after resolving offsets. Detected by g++.brendan/static1.C. * decl.c (complete_array_type): Ignore initial_value if it is an error. Detected by g++.benjamin/17930.C. * typeck2.c (process_init_constructor): Return error if one argument is in error. Detected by g++.benjamin/13478.C. 1999-03-12 Martin von Löwis * decl.c (select_decl): Allow class templates when we need types. * decl2.c (ambiguous_decl): Likewise. 1999-03-12 Mark Mitchell * lex.c (do_identifier): Correct call to enforce_access. * search.c (accessible_p): Tweak comment. 1999-03-10 Mark Mitchell * semantics.c (begin_class_definition): Call build_self_reference. (finish_member_declaration): Set DECL_CONTEXT for TYPE_DECLs. * search.c (assert_canonical_unmarked): Fix typo in prototype. * search.c (dfs_canonical_queue): New function. (dfs_assert_unmarked_p): Likewise. (assert_canonical_unmarked): Likewise. (access_in_type): Use it. (accessible_p): Likewise. Walk the whole tree when umarking. * sig.c (build_signature_table_constructor): Use accessible_p instead of compute_access. 1999-03-09 Jason Merrill * call.c (add_builtin_candidates): Handle overloaded conversion ops. 1999-03-09 Mark Mitchell * cp-tree.h (flag_access_control): Declare. (TREE_VIA_PPUBLIC): Document. (DECL_NONSTATIC_MEMBER_P): New macro. (enforce_access): Return an indication of whether or not access was permitted. (build_self_reference): Change prototype. (compute_access): Replace with ... (accessible_p): New function. (dfs_walk): Change prototype. (dfs_unmark): Likewise. (markedp): Likewise. * call.c (enforce_access): Use accessible_p. * class.c (build_self_reference): Insert the declaration into the list of members for this type, and make it public. * decl.c (xref_basetypes): Avoid ill-timed recursion. * init.c (build_offset_ref): Use lookup_member, not three separate name-lookups. Call enforce_access rather than checking for illegal accesses here. (resolve_offset_ref): Likewise. * lex.c (do_identifier): Likewise. * method.c (hack_identifier): Likewise. * parse.y (self_reference): Remove. (opt_component_decl_list): Don't use it. * parse.c: Regenerated. * pt.c (print_candidates): Generalize to handle lists of overloaded functions. (instantiate_class_template): Don't rely on TREE_VIA_PRIVATE; it's not set. (get_template_base): Use new calling convention for dfs_walk. * search.c: Include varray.h. Add prototypes. (dfs_walk): Accept a data pointer to pass to the work functions. All callers changed. All work functions changed. (breadth_first_search): Rename to bfs_walk, and make consistent with dfs_walk. (dfs_walk_real): New function. (canonical_binfo): New function. (context_for_name_lookup): Likewise. (shared_marked_p): Likewise. (shared_unmarked_p): Likewise. (lokup_field_queue_p): Likewise. (lookup_field_r): Generalize to handle both functions and fields. (lookup_field): Just call lookup_member. (lookup_fnfields): Likewise. (lookup_member): Move body of lookup_field here and generalize. (dfs_accessible_queue_p): Likewise. (dfs_accessible_p): Likewise. (dfs_access_in_type): Likewise. (access_in_type): Likewise. (compute_access): Remove, and replace with ... (accessible_p): New function. (vbase_types): Remove. (vbase_decl_ptr_intermediate): Likewise. (vbase_decl_ptr): Likewise. (vbase_init_result): Likewise. (closed_envelopes): Likewise. (bvtable): Likewise. 1999-03-09 Jason Merrill * call.c (add_function_candidate): Check for proper number of args before checking the validity of those args. 1999-03-06 Jason Merrill * cp-tree.h (struct lang_type): Add anon_union field. (ANON_UNION_TYPE_P): Use it instead of examining type. (SET_ANON_UNION_TYPE_P): New macro. * decl.c (check_tag_decl): Use it. * search.c (compute_access): Handle non-type contexts earlier, and handle NULL_TREE. * tree.c (build_exception_variant): Use copy_to_permanent. * decl2.c (setup_initp): Give statics with no priority the default priority here. (do_dtors, do_ctors, finish_file): Remove special handling of non-prioritized statics. 1999-03-05 Mark Mitchell * cp-tree.h (ANON_UNION_TYPE_P): Robustify. * decl.c (make_typename_type): Don't issue an error if an immediate lookup fails; it migt be resolved later. * friend.c (is_friend): Add comment. * search.c (breadth_first_search): Add POSTFN and DATA parameters. Tidy. All callers changed. (lookup_field_queue_p): New function. (lookup_field_r): Likewise. (lookup_field_post): Likewise. (lookup_field): Use them, via breadth_first_search, instead of duplicating logic. (compute_access): Robustify. (lookup_fnfield_info): New structure. 1999-03-05 Jason Merrill * pt.c (tsubst, case ARRAY_REF): Use tsubst_expr again. 1999-03-03 Jason Merrill * class.c, decl2.c, method.c, pt.c: Add 'static' to make SunOS 4 cc happy. * decl2.c (import_export_class): Also return if CLASSTYPE_INTERFACE_ONLY is set. 1999-03-03 Martin von Löwis * decl.c (push_overloaded_decl): Only overwrite the old binding if there was one. * decl2.c (do_local_using_decl): Fix loop termination. 1999-03-02 Mark Mitchell * cp-tree.h (determine_specialization): Don't declare. * pt.c (determine_specialization): Make it static. Eliminate complain parameter. Note that decl is always non-NULL now, and simplify accordingly. * decl.c (maybe_push_to_top_level): Always call push_cp_function_context. (pop_from_top_level): Always call pop_cp_function_context. 1999-02-26 Nathan Sidwell * typeck.c (complete_type_or_else): Add VALUE arg, for helpful diagnostics. * cp-tree.h (complete_type_or_else): Added VALUE parameter. * init.c (build_new_1): Extra arg to complete_type_or_else. (build_delete): Likewise. * typeck.c (require_complete_type): Likewise. (pointer_int_sum): Likewise. (pointer_diff): Likewise. (build_component_ref): Likewise. * typeck2.c (incomplete_type_error): Always use cp_error. Show declaration of undefined type, if appropriate. Deal with UNKNOWN_TYPE nodes. * typeck.c (require_complete_type): Use TYPE_SIZE as size_zero_node to mean incomplete type. (require_complete_type_in_void): New function. (build_compound_expr): Call complete_type_in_void for LHS. (build_c_cast): Call complete_type_in_void for void cast. * cvt.c (ocp_convert): Call complete_type_in_void for void cast. * decl.c (cplus_expand_expr_stmt): Void expression checks moved to require_complete_type_in_void. Call it. * cp-tree.h (require_complete_type_in_void): Prototype new function. * typeck.c (convert_arguments): Use alternative format for function decls. Don't require_complete_type here. Simplify diagnostic printing. (convert_for_initialization): Don't require_complete_type on RHS yet. * call.c (convert_arg_to_ellipsis): Call require_complete_type. * call.c (build_over_call): Cope with qualified void return type. * semantics.c (finish_call_expr): Likewise. * typeck.c (build_function_call_real): Likewise. (c_expand_return): Likewise. * decl2.c (reparse_absdcl_as_expr): Cope with qualified void type. * call.c (print_z_candidates): Use alternate print format, to be consistent with (pt.c) print_candidates. * method.c (hack_identifier): List candidate members. * search.c (lookup_field): Build ambiguous list, and show it, if ambiguous. 1999-02-26 Mark Mitchell * typeck.c (decay_conversion): Don't confuse constant array variables with their initializers. * decl.c (duplicate_decls): Copy DECL_TEMPLATE_INSTANTIATED when merging decls. * pt.c (regenerate_decl_from_template): Tweak for clarity. (instantiate_decl): Mark a decl instantiated before regenerating it to avoid recursion. * tree.c (mapcar): Don't call decl_constant_value unless we know something is TREE_READONLY_DECL_P. * class.c (check_for_override): Don't stop checking when we find the first overridden function. Delete #if 0'd code. * search.c (get_matching_virtual): Likewise. 1999-02-25 Richard Henderson * lang-specs.h: Define __FAST_MATH__ when appropriate. 1999-02-24 Mike Stump * typeck.c (convert_for_assignment): Allow boolean integral constant expressions to convert to null pointer. 1999-02-24 Martin von Loewis * decl.c (lookup_namespace_name): Resolve namespace aliases. * class.c (push_nested_class): Allow namespaces. * decl2.c (set_decl_namespace): Add friendp parameter. * decl.c (grokfndecl): Pass it. (grokvardecl): Likewise. * cp-tree.h: Change declaration. 1999-02-24 Jason Merrill * pt.c (tsubst): Allow an array of explicit size zero. 1999-02-23 Jason Merrill * errfn.c: Change varargs code to look like toplev.c. * method.c (process_modifiers): Don't prepend 'U' for char or wchar_t. 1999-02-20 Craig Burley * Make-lang.in (cplib2.ready): Don't consider updating cplib2 stuff if the current directory isn't writable, as it won't work (such as during a `make install'). Sun Feb 21 20:38:00 1999 H.J. Lu (hjl@gnu.org) * decl2.c (start_objects): Make file scope constructors and destructors local to the file if ASM_OUTPUT_CONSTRUCTOR and ASM_OUTPUT_DESTRUCTOR are defined. 1999-02-19 Mark Mitchell * cp-tree.h (CLASSTYPE_METHOD_VEC): Adjust comment. (fn_type_unification): Adjust prototype. (lookup_fnfields_1): Declare. * call.c (add_template_candidate_real): Adjust call to fn_type_unification. * class.c (add_method): Don't allow duplicate declarations of constructors or destructors. (resolve_address_of_overloaded_function): Remove unused variable. Adjust call to fn_type_unification. * decl.c (grokfndecl): Be more robust in the face of illegal specializations. * decl2.c (check_classfn): Remove hokey handling of member templates. * pt.c (determine_specialization): Improve comments. Adjust to handle template argument deduction as per the standard. (check_explicit_specialization): Fix comment spacing. Handle type-conversion operators correctly. Improve error-recovery. (fn_type_unification): Remove EXTRA_FN_ARG parameter. (get_bindings_real): Simplify handling of static members. * search.c (lookup_fnfields_1): Make it have external linkage. * typeck.c (compparms): Fix comment. (build_unary_op): Don't try to figure out which template specialization is being referred to when when the address-of operator is used with a template function. Thu Feb 18 23:40:01 1999 Kaveh R. Ghazi * cp-tree.h (lvalue_or_else): Qualify a char* with the `const' keyword to match an analogous change at the top level. * tree.c (lvalue_or_else): Likewise. 1999-02-17 Mark Mitchell * decl.c (xref_basetypes): Comment. * pt.c (instantiate_class_template): Use xref_basetypes. 1999-02-16 Mark Mitchell * cp-tree.h (tsubst): Change prototype. (tsubst_expr): Likewise. (tsubst_copy): Likewise. (type_unification): Remove prototype. * call.c (convert_default_arg): Adjust call to tsubst_expr. * class.c (resolve_address_of_overloaded_function): Just use fn_type_unification. * decl.c (grokdeclarator): Adjust call to tsubst. * method.c (build_template_parm_names): Likewise. * pt.c (GTB_VIA_VIRTUAL): New macro. (GTB_IGNORE_TYPE): Likewise. (resolve_overloaded_unification): Add `complain' parameter. (try_one_overload): Likewise. (tsubst_template_arg_vector): Likewise. (tsubst_template_parms): Likewise. (tsubst_aggr_type): Likewise. (tsubst_arg_types): Likewise. (tsubst_call_declarator_parms): Likewise. (unify): Remove explicit_mask. (type_unification_real): Likewise. (get_template_base_recursive): Likewise. (coerce_template_template_parms): Provide prototype. (tsubst_function_type): Likewise. (try_class_unification): New function. All callers changed to use new complain parameter. (get_template_base): Use try_class_unification. (unify): Adjust handling of classes derived from template types. (fn_type_unification): Substitute explicit arguments before unification. 1999-02-16 Kriang Lerdsuwanakij * decl.c (pushdecl): Remove dead code. 1999-02-16 Jason Merrill * decl2.c (finish_objects): Fix code I missed in previous change. 1999-02-13 Jason Merrill * decl.c (grokfndecl): Return NULL_TREE instead of error_mark_node. (grokdeclarator): Don't expect error_mark_node from grokfndecl. * pt.c (maybe_process_partial_specialization): Complain about 'template <>' on non-specialization. 1999-02-10 Jason Merrill * decl.c (grokdeclarator): Catch wierd declarators. * decl2.c (finish_file): Don't abort because of namespace parsing failure. (check_decl_namespace): Remove. 1999-02-09 Mark Mitchell * cp-tree.h (get_template_base): Don't declare. (dfs_walk): Declare. (dfs_unmark): Likewise. (markedp): Likewise. * pt.c (unify): Remove duplicate declaration. Pass tparms and targs to get_template_base. (get_template_base_recursive): Move here from search.c. Check to see that the base found can be instantiated to form the desired type. (get_template_base): Likewise. (get_class_bindings): Simplify. * search.c (get_template_base_recursive): Move to pt.c. (get_template_base): Likewise. (markedp): Make it global. (dfs_walk): Likewise. (dfs_unmark): Likewise. 1999-02-07 Jason Merrill * pt.c (maybe_process_partial_specialization): Complain about specialization in wrong namespace. * tree.c (decl_namespace_context): New fn. 1999-02-06 Kriang Lerdsuwanakij * decl2.c (arg_assoc_type): Handle TEMPLATE_TEMPLATE_PARM. * pt.c (coerce_template_template_parms): Handle nested template template parameters. Sat Feb 6 18:08:40 1999 Jeffrey A Law (law@cygnus.com) * typeck2.c: Update email addresses. 1999-02-04 Kriang Lerdsuwanakij * pt.c (unify): Call coerce_template_parms with the COMPLAIN flag turned off. 1999-02-04 Jason Merrill * lex.c (retrofit_lang_decl): Split out... (build_lang_decl): From here. * decl.c (pushdecl): Call it for functions generated by the middle end that don't have DECL_LANG_SPECIFIC. * cp-tree.h: Declare it. * decl2.c: Remove flag_init_priority. Always enable initp stuff. (start_objects, finish_objects): Only use special init_priority code if the user specified a priority. (do_ctors, do_dtors): Use DEFAULT_INIT_PRIORITY for the non-initp objects. Wed Feb 3 22:50:17 1999 Marc Espie * Make-lang.in (GXX_OBJS): Remove choose-temp.o, pexecute.o and mkstemp.o. Get them from libiberty now. (DEMANGLER_PROG): Simlarly, remove getopt.o getopt1.o. Tue Feb 2 22:38:48 1999 Theodore Papadopoulo * decl2.c (lang_decode_option): Use read_integral_parameter. 1999-02-01 Mark Mitchell * pt.c (tsubst, case TYPENAME_TYPE): Check TYPE_BEING_DEFINED before calling complete_type_or_else. Mon Feb 1 09:49:52 1999 Kaveh R. Ghazi * input.c (inline): Don't define, its handled by system.h. Sun Jan 31 20:34:29 1999 Zack Weinberg * decl2.c: Don't define flag_no_ident here. Don't process -f(no-)ident here. * cp-tree.h: Don't declare flag_no_ident here. * lang-specs.h: Map -Qn to -fno-ident. 1999-01-28 Jason Merrill * cp-tree.h (struct tree_binding): Replace scope field with a union. (BINDING_SCOPE): Adjust. * decl.c (BINDING_LEVEL): Adjust. 1999-01-26 Jason Merrill * pt.c (instantiate_class_template): Set up the DECL_INITIAL of member constants. * init.c (expand_member_init): Pull out TYPE_MAIN_VARIANT in a ctor initializer. * tree.c (equal_functions): Fix name in prototype. * decl.c (push_local_binding): Add FLAGS argument. (pushdecl, push_overloaded_decl): Pass it. * decl2.c (do_local_using_decl): Likewise. * cp-tree.h: Adjust prototype. * decl.c (poplevel): Fix logic. * decl.c (push_local_binding): Also wrap used decls in a TREE_LIST. (poplevel): Handle that. Fix logic for removing TREE_LISTs. (cat_namespace_levels): Don't loop forever. 1999-01-25 Richard Henderson * typeck.c (build_reinterpret_cast): Fix typo in duplicated test. 1999-01-25 Jason Merrill * class.c (resolve_address_of_overloaded_function): Mark the chosen function used. * call.c (build_call): Make sure that a function coming in has been marked used already. * decl.c (expand_static_init): Call mark_used instead of assemble_external. * except.c (call_eh_info, do_pop_exception, expand_end_eh_spec, alloc_eh_object, expand_throw): Likewise. * init.c (build_builtin_delete_call): Likewise. * rtti.c (call_void_fn, get_tinfo_fn, build_dynamic_cast_1, expand_si_desc, expand_class_desc, expand_ptr_desc, expand_attr_desc, expand_generic_desc): Likewise. 1999-01-25 Martin von Löwis * tree.c (equal_functions): New function. (ovl_member): Call it. 1999-01-24 Jason Merrill * cvt.c (cp_convert_to_pointer): Fix conversion of 0 to pmf. 1999-01-25 Martin von Loewis * decl.c (decls_match): Return 1 if old and new are identical. (push_overloaded_decl): Set OVL_USED when PUSH_USING. 1999-01-24 Jason Merrill * decl.c (start_function): Make member functions one_only on windows. * decl2.c (import_export_decl): Likewise. * decl.c (grokdeclarator): Don't complain about implicit int in a system header. Change same-name field check to not complain in a system header instead of within extern "C". 1999-01-21 Mark Mitchell * cp-tree.h (PUSH_GLOBAL): New macro. (PUSH_LOCAL): Likewise. (PUSH_USING): Likewise. (namespace_bindings_p): Declare. (push_overloaded_decl): Likewise. * decl.c (push_overloaded_decl): Don't make it static. Check for illegal declarations after using declarations here. (namespace_bindings_p): Likewise. (duplicate_decls): Don't consider declarations from different namespaces to be the same. (pushdecl): Use symbolic PUSH_ constants in calls to push_overloaded_decl. (push_overloaded_decl_1): Likewise. * decl2.c (validate_nonmember_using_decl): Tweak `std' handling. (do_nonmember_using_decl): Check for illegal using declarations after ordinary declarations here. (do_local_using_decl): Call pushdecl to insert declarations. 1999-01-21 Jason Merrill * decl.c (grokdeclarator): Fix lang_c -> lang_name_c typo. 1999-01-21 Mark Mitchell * tree.c (build_cplus_array_type_1): Don't call build_array_type for types involving template parameters. * cp-tree.h (PARM_DECL_EXPR): Delete. (convert_default_arg): Change prototype. (check_default_argument): Declare. (search_tree): Likewise. * call.c (convert_default_arg): Take the function to which the default argument belongs as a parameter, and do any necessary instantiation here, instead of ... (build_over_call): Here. * decl.c (local_variable_p): New function. (check_default_argument): Likewise, split out and tidied from ... (grokparms): Here. * error.c (dump_expr): Don't set PARM_DECL_EXPR. * pt.c (tsubst_call_declarator_parms): New function. (for_each_template_parm): Handle ARRAY_REFs. Do the obvious thing with CALL_EXPRs, rather than trying to be clever. (tsubst): Use tsubst_call_declarator_parms. * tree.c (search_tree): Don't make it static. * typeck.c (convert_arguments): Use new interface to convert_default_arg. 1999-01-20 Mark Mitchell * error.c (dump_function_decl): Don't print the argument types for a function when the verbosity level is negative. * call.c (build_over_call): Check format attributes at call-time. * pt.c (tsubst_copy): Fix comment. (unify): Don't allow unification with variable-sized arrays. * semantics.c (finish_stmt_expr): When processing a template make the BIND_EXPR long-lived. 1999-01-19 Jason Merrill * decl2.c (finish_vtable_vardecl): Make vtables comdat here. (import_export_vtable): Not here. 1999-01-18 Jason Merrill * typeck.c (build_component_ref): Wrap an OVERLOAD around a unique non-static member function. 1999-01-18 Nathan Sidwell * class.c (instantiate_type): Only diagnose illegal address of member function if complaining. * decl.c (lookup_name_real): Remove duplicate code. 1999-01-18 Jason Merrill * tree.c (copy_template_template_parm): Use permanent_obstack. 1999-01-18 Kriang Lerdsuwanakij * pt.c (unify): Remove restrictions on deduction of argument of template template parameters. 1999-01-18 Nathan Sidwell * rtti.c (build_dynamic_cast_1): Resolve OFFSET_REF exprs. * class.c (resolve_address_of_overloaded_function): Show list of all candidates, when none of them match. 1999-01-18 Chip Salzenberg * typeck.c (comp_ptr_ttypes_reinterpret): Per ANSI, tighten up definition of 'casting away const' in reinterpret_cast<>. 1999-01-18 Graham * cvt.c: Add include for decl.h, remove extern for static_aggregates which is now provided by decl.h. * Makefile.in (cvt.o): Add dependency for decl.h and missing dependencies for convert.h and flags.h. 1999-01-18 Nathan Sidwell * decl2.c (do_dtors): Set current location to that of the decl, for sensible diagnostics and debugging. (check_classfn): Issue `incomplete type' error, if class is not defined. 1999-01-16 Jason Merrill * cp-tree.h: Add prototype for bound_pmf_p. 1999-01-16 Jason Merrill Manfred Hollstein * decl.c (grokdeclarator): Don't make 'main(){}' an error with only -Wreturn-type. 1999-01-16 Nathan Sidwell * cp-tree.h (struct lang_type): Added has_mutable flag. (CLASSTYPE_HAS_MUTABLE): New macro to access it. (TYPE_HAS_MUTABLE_P): New macro to read it. (cp_has_mutable_p): Prototype for new function. * class.c (finish_struct_1): Set has_mutable from members. * decl.c (cp_finish_decl): Clear decl's TREE_READONLY flag, if it contains a mutable. * typeck.c (cp_has_mutable_p): New function. 1999-01-15 Mark Mitchell * pt.c (process_template_parm): Ignore top-level qualifiers on non-type parameters. * decl.c (start_function): Use current_function_parms in the call to require_complete_type_for_parms, not the probably empty DECL_ARGUMENTS. 1999-01-14 Jason Merrill * semantics.c (finish_asm_stmt): Don't warn about redundant volatile. * decl2.c (import_export_class): MULTIPLE_SYMBOL_SPACES only means that we don't suppress the other copies. * lex.c (handle_cp_pragma): Likewise. 1999-01-13 Mark Mitchell * decl.c (grokdeclarator): Undo 1998-12-14 change. * tree.c (build_cplus_array_type_1): Likewise. * pt.c (instantiate_class_template): Remove misleading comment. (tsubst_aggr_type): Substitute if there are template parameters, regardless of whether or not they use template arguments. (unify): Likewise, but for unification. 1999-01-12 Richard Henderson * cp-tree.h (flag_permissive): Declare extern. 1999-01-06 Mark Mitchell * cp-tree.h (IDENTIFIER_TYPENAME_P): Use OPERATOR_TYPENAME_FORMAT here. (lang_type): Add is_partial_instantiation. Decrease width of dummy. (PARTIAL_INSTANTIATION_P): New macro. (OPERATOR_TYPENAME_P): Remove. * decl.c (unary_op_p): Use IDENTIFIER_TYPENAME_P, not OPERATOR_TYPENAME_P. (grok_op_properties): Likewise. * friend.c (do_friend): Handle friends that are member functions correctly. * lex.c (init_parse): Use OPERATOR_TYPENAME_FORMAT. * pt.c (instantiate_class_template): Rework for clarity. Avoid leaving TYPE_BEING_DEFINED set in obscure cases. Don't do any more partial instantiation than is absolutely necessary for implicit typename. Set PARTIAL_INSTANTIATION_P. (tsubst_decl): Use IDENTIFIER_TYPENAME_P. * semantics.c (begin_class_definition): Handle partial specializations of a type that was previously partially instantiated. Wed Jan 6 03:18:53 1999 Mark Elbrecht * Make-lang.in (g++.o): Depend on prefix.h. 1999-01-04 Jason Merrill * tree.c (bound_pmf_p): New fn. * typeck.c (build_c_cast): Use it. * decl.c (grok_op_properties): Use same_type_p. Tue Dec 22 15:09:25 1998 Kaveh R. Ghazi * Makefile.in (cvt.o): Depend on toplev.h. * cp-tree.h (check_template_shadow, pod_type_p): Add prototypes. * cvt.c: Include toplev.h. * except.c (get_eh_caught, get_eh_handlers): Hide prototypes and definitions. * init.c (expand_vec_init): Initialize variable `itype'. * lex.c (yyerror): Cast the argument passed to a ctype function to an unsigned char. * method.c (build_mangled_C9x_name): Wrap prototype and definition in "HOST_BITS_PER_WIDE_INT >= 64". * typeck.c (build_binary_op): Mark parameter `convert_p' with ATTRIBUTE_UNUSED. 1998-12-22 Mark Mitchell * cp-tree.h (TYPE_RAISES_EXCEPTIONS): Improve documentation. * tree.c (build_exception_variant): Don't crash on empty throw specs. 1998-12-18 DJ Delorie * cvt.c (convert_to_reference): Check for both error_mark_node and NULL_NODE after call to convert_for_initialization. 1998-12-17 Jason Merrill * error.c (interesting_scope_p): New fn. (dump_simple_decl): Use it. (dump_expr, case CONSTRUCTOR): Force a & for a PMF. (dump_expr, case OFFSET_REF): Print ->* if appropriate. 1998-12-16 Mark Mitchell * class.c (resolve_address_of_overloaded_function): Do conversion to correct type here, rather than ... (instantiate_type): Here. * cp-tree.h (DECL_TEMPLATE_PARM_P): New macro. (DECL_TEMPLATE_TEMPLATE_PARM_P): Use it. (decl_template_parm_p): Remove. * decl.c (pushdecl): Don't set DECL_CONTEXT for a template parameter. * lex.c (do_identifier): Use DECL_TEMPLATE_PARM_P. * pt.c (push_inline_template_parms_recursive): Set it. (decl_template_parm_p): Remove. (check_template_shadow): Use DECL_TEMPLATE_PARM_P. (process_template_parm): Set it. Wed Dec 16 16:33:58 1998 Dave Brolley * lang-specs.h (default_compilers): Pass -MD, -MMD and -MG to cc1plus if configured with cpplib. 1998-12-15 Mark Mitchell * decl.c (poplevel): Make sure ns_binding is initialized. * decl.c (finish_function): Undo inadvertent change in previous patch. 1998-12-14 Mark Mitchell * class.c (pushclass): Tweak handling of class-level bindings. (resolve_address_of_overloaded_function): Update pointer-to-member handling. (instantiate_type): Likewise. * cvt.c (cp_convert_to_pointer): Likewise. * decl.c (pop_binding): Take the DECL to pop, not just the name. Deal with `struct stat' hack. (binding_level): Add to documentation. (push_binding): Clear BINDING_TYPE. (add_binding): New function. (push_local_binding): Use it. (push_class_binding): Likewise. (poplevel): Adjust calls to pop_binding. (poplevel_class): Likewise. (pushdecl): Adjust handling of TYPE_DECLs; add bindings for hidden declarations to current binding level. (push_class_level_binding): Likewise. (push_overloaded_decl): Adjust handling of OVERLOADs in local bindings. (lookup_namespace_name): Don't crash when confronted with a TEMPLATE_DECL. (lookup_name_real): Do `struct stat' hack in local binding contexts. (build_ptrmemfunc_type): Adjust documentation. (grokdeclarator): Don't avoid building real array types when processing templates unless really necessary. (finish_method): Adjust calls to pop_binding. * decl2.c (reparse_absdcl_as_expr): Recursively call ourselves, not reparse_decl_as_expr. (build_expr_from_tree): Deal with a template-id as the function to call in a METHOD_CALL_EXPR. * pt.c (convert_nontype_argument): Tweak pointer-to-member handling. (maybe_adjust_types_For_deduction): Don't do peculiar things with METHOD_TYPEs here. (resolve_overloaded_unification): Handle COMPONENT_REFs. Build pointer-to-member types where necessary. * tree.c (build_cplus_array_type_1): Don't avoid building real array types when processing templates unless really necessary. (build_exception_variant): Compare the exception lists correctly. 1998-12-13 Mark Mitchell * cp-tree.def (CPLUS_BINDING): Update documentation. * cp-tree.h (LOCAL_BINDING_P): New macro. (lang_identifier): Rename local_value to bindings. (tree_binding): Make `scope' of type `void*', not `tree'. (BINDING_SCOPE): Update documentation. (IDENTIFIER_LOCAL_VALUE): Remove. (IDENTIFIER_CLASS_VALUE): Document. (IDENTIFIER_BINDING): New macro. (IDENTIFIER_VALUE): Likewise. (TIME_IDENTIFIER_TIME): Likewise. (TIME_IDENTIFIER_FILEINFO): Likewise. (IMPLICIT_TYPENAME_P): Likewise. (set_identifier_local_value): Remove. (push_local_binding): New function. (push_class_binding): Likewise. * class.c (pushclass): Update comments; use push_class_binding. * decl.c (set_identifier_local_value_with_scope): Remove. (set_identifier_local_value): Likewise. (push_binding): New function. (pop_binding): Likewise. (binding_level): Update documentation. Remove shadowed. (BINDING_LEVEL): New macro. (free_binding_nodes): New variable. (poplevel): Adjust for new name-lookup scheme. Don't mess up BLOCK_VARs when doing for-scope extension. Remove effectively dead code. (pushlevel_class): Tweak formatting. (poplevel_class): Adjust for new name-lookup scheme. (print_binding_level): Likewise. (store_bindings): Likewise. (pushdecl): Likewise. (pushdecl_class_level): Likewise. (push_class_level_binding): Likewise. (push_overloaded_decl): Update comments. Adjust for new name-lookup scheme. (lookup_name_real): Likewise. (lookup_name_current_level): Likewise. (cp_finish_decl): Likewise. (require_complete_types_for_parms): Likewise. Remove misleading #if 0'd code. (grok_parms): Likewise. Don't call require_complete_types_for_parms here. (grok_ctor_properties): Don't treat templates as copy constructors. (grop_op_properties): Or as assignment operators. (start_function): Document. Adjust for new name-lookup scheme. (finish_function): Likewise. * decl2.c (do_local_using_decl): Use push_local_binding. * lex.c (begin_definition_of_inclass_inline): New function, split out from ... (do_pending_inlines): Here, and ... (process_next_inline): Here. (get_time_identifier): Use TIME_IDENTIFIER_* macros. (init_filename_times): Likewise. (extract_interface_info): Likewise. (ste_typedecl_interface_info): Likewise. (check_newline): Likewise. (dump_time_statistics): Likewise. (handle_cp_pragma): Likewise. (do_identifier): Adjust for new name-lookup scheme. * parse.y (function_try_block): Return ctor_initializer_opt value. (fndef): Use it. (fn.defpen): Pass appropriate values to start_function. (pending_inline): Use functor_try_block value, and pass appropriate values to finish_function. * pt.c (is_member_template): Update documentation; remove handling of FUNCTION_DECLs. As per name, this function should deal only in TEMPLATE_DECLs. (decl_template_parm_p): Change name of olddecl parameter to decl. (check_template_shadow): Adjust for new name-lookup scheme. (lookup_template_class): Likewise. (tsubst_decl): Tweak so as not to confuse member templates with copy constructors and assignment operators. (unify): Handle UNION_TYPEs. * ptree.c (print_lang_identifier): Adjust for new name-lookup scheme. (lang_print_xnode): Adjust for new name-lookup scheme. * typeck.c (mark_addressable): Likewise. (c_expand_return): Likewise. 1998-12-08 Jason Merrill * decl.c (grokdeclarator): Allow field with same name as class in extern "C". * decl.c (lookup_name_real): Don't limit field lookup to types. * class.c (check_member_decl_is_same_in_complete_scope): No error if icv and x are the same. * lex.c (do_identifier): Tweak error message. 1998-12-10 Mark Mitchell * decl.c (start_enum): Use push_obstacks, not end_temporary_allocation. (finish_enum): Call pop_obstacks. 1998-12-10 Mark Mitchell * class.c (instantiate_type): Return error_mark_node rather than junk. 1998-12-09 Mark Mitchell * cp-tree.h (most_specialized_instantiation): New function. (print_candidates): Likewise. * class.c (validate_lhs): Remove. (resolve_address_of_overloaded_function): New function, split out and then substantially reworked, from ... (instantiate_type): Use it. Simplify. * cvt.c (convert_to_reference): Complain when caller has indicated that's the right thing to do. Don't crash if instantiate_type fails. * pt.c: Substitute `parameters' for `paramters' throughout. (print_candidates): Don't make it static. (most_specialized_instantiation): Split out from ... (most_specialized): Here. Wed Dec 9 15:33:01 1998 Dave Brolley * lex.c (lang_init_options): Initialize cpplib. * decl2.c (parse_options,cpp_initialized): Removed. (lang_decode_option): Move initialization of cpplib to lang_init_options. 1998-12-09 Mark Mitchell * decl.c (grokdeclarator): Update the name of the TEMPLATE_DECL, as well as the TYPE_DECL, when a typedef name is assigned to a previously anonymous type. 1998-12-08 Andrew MacLeod * cp/except.c (call_eh_info): Use __start_cp_handler instead of __cp_eh_info for getting the eh info pointer. Add table_index to field list. (push_eh_cleanup): Don't increment 'handlers' data field. (process_start_catch_block): Don't set the 'caught' field. * cp/exception.cc (CP_EH_INFO): New macro for getting the exception info pointer within library routines. (__cp_eh_info): Use CP_EH_INFO. (__start_cp_handler): Get exception info pointer, set caught field, and increment the handlers field. Avoids this being done by handlers. (__uncatch_exception, __check_eh_spec): Use CP_EH_INFO macro. (uncaught_exception): Use CP_EH_INFO macro. Tue Dec 8 10:48:21 1998 Jeffrey A Law (law@cygnus.com) * Make-lang.in (cxxmain.o): Depend on $(DEMANGLE_H), not demangle.h Mon Dec 7 17:56:06 1998 Mike Stump * lex.c (check_newline): Add support for \ as `natural' characters in file names in #line to be consistent with #include handling. We support escape processing in the # 1 "..." version of the command. See also support in cp/lex.c. 1998-12-07 Zack Weinberg * cp/decl2.c: s/data/opts/ when initializing cpp_reader structure. 1998-12-07 Jason Merrill * decl.c (build_typename_type): Set DECL_ARTIFICIAL. * error.c (dump_simple_decl): Also print namespace context. (dump_function_decl): Likewise. * decl2.c (ambiguous_decl): Don't print old value if it's error_mark_node. * decl.c (lookup_name_real): Fix handling of local types shadowed by a non-type decl. Remove obsolete code. * cp-tree.h (DECL_FUNCTION_SCOPE_P): New macro. * lang-options.h: Add -fpermissive. * decl2.c: Likewise. * cp-tree.h: Add flag_permissive. * decl.c (init_decl_processing): If neither -fpermissive or -pedantic were specified, set flag_pedantic_errors. * call.c (build_over_call): Turn dropped qualifier messages back into pedwarns. * cvt.c (convert_to_reference): Likewise. * typeck.c (convert_for_assignment): Likewise. 1998-12-05 Jason Merrill * decl2.c (coerce_new_type): Use same_type_p. (coerce_delete_type): Likewise. * call.c (check_dtor_name): Return 1, not error_mark_node. 1998-12-04 Jason Merrill * lex.c (handle_cp_pragma): Disable #pragma interface/implementation if MULTIPLE_SYMBOL_SPACES. * pt.c (check_template_shadow): New fn. * decl2.c (grokfield): Use it. * decl.c (pushdecl): Likewise. (pushdecl_class_level): Likewise. (start_method): Likewise. (xref_tag): Don't try to use 't' if we're defining. * call.c (check_dtor_name): Just return an error_mark_node. * pt.c (lookup_template_class): Complain about using non-template here. * parse.y (apparent_template_type): Not here. * pt.c (check_explicit_specialization): Complain about specialization with C linkage. * lang-options.h: Add -f{no-,}implicit-inline-templates. * pt.c (convert_nontype_argument): Don't assume that any integer argument is intended to be a constant-expression. 1998-12-03 Mark Mitchell * class.c (handle_using_decl): Fix comment. Don't lookup constructors in base classes. (validate_lhs): Fix typo in comment. * search.c (lookup_field_1): Don't return a USING_DECL. * cp-tree.h (DECL_ACCESS): Improve documentation. * decl.c (expand_static_init): Don't set the initialization-done flag until the initialization is done. 1998-12-02 Mark Mitchell * decl2.c (validate_nonmember_using_decl): Complain about using declarations for class members. 1998-11-29 Jason Merrill * typeck2.c (process_init_constructor): Use same_type_p. * decl.c (check_tag_decl): Don't warn about null decl inside a class. * pt.c (unify, case OFFSET_TYPE): Pass down 'strict' rather than UNIFY_ALLOW_NONE. (convert_nontype_argument): Use TYPE_PTRMEMFUNC_FN_TYPE. (resolve_overloaded_unification): Strip baselinks. Fri Nov 27 13:07:23 1998 Kaveh R. Ghazi * g++spec.c: Don't prototype xmalloc. 1998-11-25 Jason Merrill * except.c (expand_throw): Use TYPE_PTR_P to check for pointers. * decl.c (check_tag_decl): Do complain about null friend decl at file scope. 1998-11-25 Andreas Schwab * lex.c (make_lang_type): Clear the whole struct lang_type, not only the first multiple of sizeof (int). 1998-11-24 Jason Merrill * decl.c (start_decl): An explicit specialization of a static data member is only a definition if it has an initializer. * except.c (expand_throw): Use cp_finish_decl for the throw temp. * cvt.c (build_up_reference): Pass DIRECT_BIND down into cp_finish_decl. * init.c (expand_default_init): Check for DIRECT_BIND instead of DECL_ARTIFICIAL. * call.c (build_over_call): Use build_decl. * except.c (expand_throw): Just use convert, not build_reinterpret_cast. * lex.c (handle_generic_pragma): Use token_buffer. * decl.c (check_tag_decl): Don't complain about null friend decl. 1998-11-24 Dave Pitts * Make-lang.in (DEMANGLER_PROG): Move the output arguments to the first position. * lex.c (check_newline): Use ISALPHA. (readescape): Use ISGRAPH. (yyerror): Use ISGRAPH. 1998-11-24 Nathan Sidwell * search.c (get_abstract_virtuals): Do not use initial CLASSTYPE_ABSTRACT_VIRTUALS. * typeck2.c (abstract_virtuals_error): Show location of abstract declaration. * call.c (build_new_method_call): Use CLASSTYPE_ABSTRACT_VIRTUAL, rather than recalculate. * class.c (finish_struct_bits): Don't bother working out whether get_abstract_virtuals will do anything, just do it. 1998-11-24 Graham * typeck.c (build_component_ref): Remove unused statement. 1998-11-24 Jason Merrill * class.c (add_method): Catch invalid overloads. * class.c (add_method): Build up OVERLOADs properly for conversion ops. * search.c (lookup_conversions): Handle getting real OVERLOADs. (add_conversions): Likewise. Revert last change. * call.c (add_conv_candidate): Pass totype to add_candidate instead of fn. Don't add a new candidate if the last one was for the same type. (print_z_candidates): Handle getting a type as a function. (joust): If we got two conversion candidates to the same type, just pick one. (build_object_call): Lose 'templates'. (build_user_type_conversion_1): Handle getting real OVERLOADs. 1998-11-23 Jason Merrill * typeck2.c (process_init_constructor): If there are elements that don't have initializers and they need to have constructors run, supply them with initializers. * class.c (finish_struct_1): A class with a 0-width bitfield is still empty. 1998-11-23 Mark Mitchell * pt.c (instantiate_class_template): Don't try to figure out what specialization to use for a partial instantiation. Correct typos in a couple of comments. Avoid calling uses_template_parms multiple times. 1998-11-23 Benjamin Kosnik * method.c (process_overload_item): Add call to build_mangled_C9x_name for intTI_type_nodes. (build_mangled_C9x_name): Add prototype, define. * decl.c (init_decl_processing): Add names for TImode_type_node. 1998-11-23 Jason Merrill * parse.y (named_class_head): Update CLASSTYPE_DECLARED_CLASS. * class.c (finish_struct_1): Set things up for 0-width bitfields like we do for others. * decl.c (check_tag_decl): New fn. (shadow_tag): Split out from here. * decl2.c (grok_x_components): Call it. 1998-11-22 Jason Merrill * decl.c: Lose warn_about_return_type. (grokdeclarator): Always complain about implicit int, except for `main () { ... }'. * decl.c (tag_name): New fn. (xref_tag): Complain about using typedef-name after class-key. * init.c (expand_vec_init): Also keep going if from_array. * tree.c (is_overloaded_fn): Also handle the output of build_offset_ref. * decl.c (grokdeclarator): Use constructor_name when comparing field name against enclosing class. * class.c (finish_struct_anon): Likewise. 1998-11-22 Mark Mitchell * decl.c (poplevel): Remove code to handle KEEP == 2. (finish_function): Don't confuse BLOCK-order when processing a destructor. 1998-11-21 Jason Merrill * decl.c (require_complete_types_for_parms): Call layout_decl after we've completed the type. 1998-11-21 Martin von Löwis * decl2.c (validate_nonmember_using_decl): Allow using templates from the global namespace. 1998-11-21 Jason Merrill Handle specifying template args to member function templates. * tree.c (build_overload): Always create an OVERLOAD for a template. * search.c (add_conversions): Handle finding an OVERLOAD. * decl2.c (check_classfn): Likewise. * lex.c (identifier_type): See through a baselink. * parse.y (do_id): Don't call do_identifier if we got a baselink. * class.c (instantiate_type, case TREE_LIST): Recurse. * decl.c (grokdeclarator): Allow a boolean constant for array bounds, odd as that sounds. * pt.c (unify): Be more strict about non-type parms, except for array bounds. (UNIFY_ALLOW_INTEGER): New macro. 1998-11-19 Manfred Hollstein * Make-lang.in (mandir): Replace all uses of $(mandir) by $(man1dir). 1998-11-19 Jason Merrill * semantics.c (begin_class_definition): Call maybe_process_partial_specialization before push_template_decl. Don't call push_template_decl for a specialization. * search.c (lookup_field): Do return a member template class. * decl2.c (handle_class_head): Handle member template classes. * decl.c (grokdeclarator): A parm type need not be complete. * pt.c (convert_nontype_argument): Fix thinko. 1998-11-18 Mark Mitchell * cp-tree.h (PTRMEM_CST_CLASS): Fix typo. (global_delete_fndecl): New variable. * decl.c (global_delete_fndecl): Define it. (init_decl_processing): Set it. * init.c (build_builtin_delete_call): Use it. * tree.c (mapcar): Recursively call mapcar for the type of EXPR nodes. 1998-11-18 Jason Merrill * decl.c (cplus_expand_expr_stmt): Always complain about unresolved type. * tree.c (lvalue_p_1): An INDIRECT_REF to a function is an lvalue. * call.c (build_object_call): Also support references to functions. * typeck.c (convert_for_initialization): Don't decay a function if the target is a reference to function. * search.c (add_conversions): Get all the overloads from a class. * decl.c (grok_ctor_properties): Complain about any constructor that will take a single arg of the class type by value. * typeck2.c (build_functional_cast): Can't create objects of abstract classes this way. * cvt.c (ocp_convert): Likewise. * decl.c (grokfndecl): Member functions of local classes are not public. 1998-11-18 Mark Mitchell * Make-lang.in (cc1plus): Add dependency on hash.o. 1998-11-18 Jason Merrill * search.c (get_abstract_virtuals): Complain about virtuals with no final overrider. * typeck2.c (abstract_virtuals_error): Remove handling for virtuals with no final overrider. * class.c (override_one_vtable): Don't set DECL_ABSTRACT_VIRTUAL_P on virtuals with no final overrider. * lex.c (reinit_parse_for_block): Add a space after the initial ':'. * class.c (finish_struct_1): Don't remove zero-width bit-fields until after layout_type. * friend.c (do_friend): Don't set_mangled_name_for_decl. * class.c (finish_struct_anon): Complain about non-fields. * decl2.c (build_anon_union_vars): Likewise. * decl.c (grokdeclarator): Normal data members can't have the same name as the class, either. * class.c (finish_struct_anon): Neither can members of an anonymous union. 1998-11-17 Mark Mitchell * cp-tree.h (TYPE_ALIAS_SET): Document language-dependent uses. (TYPE_BINFO): Likewise. (IS_AGGR_TYPE): Tweak. (SET_IS_AGGR_TYPE): New macro. (CLASS_TYPE_P): Tweak. (lang_type): Group mark bitfields together. Remove linenum. (CLASSTYPE_SOURCE_LINE): Remove macro. (CLASSTYPE_MARKED_N): New macro. (SET_CLASSTYPE_MARKED_N): Likewise. (CLEAR_CLASSTYPE_MARKED_N): Likewise. (CLASS_TYPE_MARKED_*): Use them. (SET_CLASSTYPE_MARKED_*): Likewise. (CLEAR_CLASSTYPE_MARKED_*): Likewise. (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO): Likewise. (TYPE_TEMPLATE_INFO): Handle TEMPLATE_TEMPLATE_PARMs as well. (TYPENAME_TYPE_FULLNAME): Use TYPE_BINFO rather than CLASSTYPE_SIZE. * class.c (class_cache_obstack): New variable. (class_cache_firstobj): Likewise. (finish_struct): Don't set CLASSTYPE_SOURCE_LINE. (pushclass): Free the cache, when appropriate. (popclass): Tidy. (maybe_push_cache_obstack): Use class_cache_obstack. * decl.c (include hash.h). (typename_hash): New function. (typename_compare): Likewise. (build_typename_type): Check the hash table to avoid creating duplicates. (build_ptrmemfunc_type): Use SET_IS_AGGR_TYPE. (grokdeclarator): Use CLASS_TYPE_P. (xref_basetypes): Likewise. (start_function): Likewise. Don't put current_class_ref on the permanent obstack. * error.c (dump_type_real): Use TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO and TYPE_TI_ARGS. * lex.c (note_got_semicolon): Use CLASS_TYPE_P. (make_lang_type): Don't create TYPE_LANG_SPECIFIC and associated fields for types other than class types. Do clear TYPE_ALIAS_SET for types other than class types, though. * method.c (build_overload_identifier): Use CLASS_TYPE_P and TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO. * pt.c (process_template_parm): Don't set CLASSTYPE_GOT_SEMICOLON. (lookup_template_class): Use TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO. Coerce arguments on the momentary obstack. (for_each_template_parm): Use TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO. (instantiate_class_template): Calculate template arguments on the momentary obstack. Tidy. (tsubst_template_arg_vector): Use make_temp_vec. (tsubst_aggr_type): Put template arguments on the momentary obstack. (tsubst_decl): Likewise. (tsubst): Copy the array bounds index to the permanent obstack before building index types. Use new macros. (unify): Use new macros. (do_type_instantiation): Likewise. * search.c (lookup_fnfields_1): Use new macros. (dfs_pushdecls): Build envelopes on the cache obstack. (dfs_compress_decls): Use new macros. (push_class_decls): Build on the cache obstack. * semantics.c (finish_typeof): Don't set CLASSTYPE_GOT_SEMICOLON. * sign.c (build_signature_pointer_or_reference_type): Use SET_IS_AGGR_TYPE. * tree.c (make_binfo): Check CLASS_TYPE_P. (copy_template_template_parm): Adjust. (make_temp_vec): Use push_expression_obstack. * typeck.c (complete_type): Use new macros. (comptypes): Likewise. 1998-11-17 Jason Merrill * pt.c (tsubst): Add diagnostics for invalid array, reference and pointer to member types. 1998-11-16 Jason Merrill * typeck2.c (my_friendly_abort): Don't fatal twice in a row. * typeck.c (c_expand_start_case): Use build_expr_type_conversion. Simplify. * parse.y (structsp): Fix cut-and-paste error. * init.c (build_new): Complain about non-integral size. * parse.y (unary_expr): Complain about defining types in sizeof. * typeck.c (expr_sizeof): Complain about sizeof an overloaded fn. * rtti.c (build_x_typeid): Complain about typeid without including . (get_typeid): Likewise. Complain about typeid of incomplete type. (get_tinfo_fn_dynamic): Likewise. (get_typeid_1): Not static anymore. * except.c (build_eh_type_type): Use get_typeid_1. * rtti.c (build_dynamic_cast_1): Give errors for dynamic_cast to ambiguous or private bases. Fix warning for reference cast. 1998-11-16 Mark Mitchell * cp-tree.h (DECL_TEMPLATE_INSTANTIATED): New macro. * decl.c (duplicate_decls): Remove special-case code to deal with template friends, and just do the obvious thing. * pt.c (register_specialization): Tweak for clarity, and also to clear DECL_INITIAL for an instantiation before it is merged with a specialization. (check_explicit_specialization): Fix indentation. (tsubst_friend_function): Handle both definitions in friend declaration and outside friend declarations. (tsubst_decl): Don't clear DECL_INITIAL for an instantiation. (regenerate_decl_from_template): Tweak accordingly. (instantiate_decl): Likewise. 1998-11-16 Jason Merrill * decl.c (cplus_expand_expr_stmt): Promote warning about naked member function reference to error. * cvt.c (ocp_convert): Complain about converting an overloaded function to void. * init.c (build_offset_ref): Just return a lone static member function. * decl.c (cp_finish_decl): Only complain about real CONSTRUCTORs, not internal ones. * typeck.c (build_binary_op_nodefault): Improve error handling. * decl.c (grokfndecl): Complain about making 'main' a template. * typeck.c (string_conv_p): Don't convert from wchar_t[] to char*. * call.c (build_method_call): Handle a BIT_NOT_EXPR around a TYPE_DECL in a template. 1998-11-15 Jason Merrill * typeck2.c (my_friendly_abort): Add URL in the other case, too. * decl.c (struct cp_function): Add named_label_uses. (push_cp_function_context): Save it. (pop_cp_function_context): Restore it. (define_label): Also complain about jumping into the scope of non-POD objects that don't have constructors. * tree.c (pod_type_p): New fn. * pt.c (instantiate_class_template): Clear TYPE_BEING_DEFINED sooner. * rtti.c (synthesize_tinfo_fn): Call import_export_decl here. (get_tinfo_fn): Not here. * repo.c (repo_get_id): Abort if we get called for an incomplete type. 1998-11-13 Mark Mitchell * except.c (expand_throw): Make sure first argument to __cp_push_exception is of type `void*' to avoid spurious error messages. 1998-11-11 Jason Merrill * pt.c (try_one_overload): Take orig_targs again. Only check for mismatches against them; we don't care what a previous call found. (resolve_overloaded_unification): Adjust. * search.c (lookup_field): Don't return anything for a non-type field from a dependent type. * decl.c (grokdeclarator): Resolve SCOPE_REFs of the current class in an array declarator. (start_decl): Push into the class before looking for the field. 1998-11-08 Mark Mitchell * method.c (build_overload_value): Handle REFERENCE_TYPE. 1998-11-08 Martin von Löwis * decl.c (grokdeclarator): Allow namespace-scoped members if they are friends. 1998-11-08 Jason Merrill * pt.c (tsubst_decl): Don't mess with the global value of an un-mangled DECL_ASSEMBLER_NAME. 1998-11-03 Christopher Faylor * decl.c (init_decl_processing): Remove CYGWIN conditional since CYGWIN is now able to deal with trapping signals. Sat Nov 7 15:48:02 1998 Kaveh R. Ghazi * cp-tree.h: Don't include gansidecl.h. * exception.cc: Include gansidecl.h (since we don't include config.h) * g++spec.c: Don't include gansidecl.h. 1998-11-06 Mark Mitchell * cp-tree.h (lang_decl_flags): Add defined_in_class. Decrease size of dummy. (DECL_DEFINED_IN_CLASS_P): New macro. (TEMPLATE_PARMS_FOR_INLINE): Document. (check_static_variable_definition): New function. * decl.c (cp_finish_decl): Set DECL_DEFINED_IN_CLASS_P, if appropriate. (check_static_variable_definition): Split out from ... (grokdeclarator): Here. * pt.c (check_default_tmpl_args): New function, split out from ... (push_template_decl_real): Here. (instantiate_template): Fix comment. 1998-11-04 Mark Mitchell * cp-tree.h (CP_TYPE_CONST_P): Make {0,1}-valued. (CP_TYPE_VOLATILE_P): Likewise. (CP_TYPE_RESTRICT_P): Likewise. 1998-11-03 Mark Mitchell * pt.c (tsubst): Use build_index_type, not build_index_2_type. 1998-11-02 Jason Merrill * class.c (instantiate_type): Be more helpful. * decl2.c (import_export_decl): Call import_export_class. * cp-tree.h (EMPTY_CONSTRUCTOR_P): Check !TREE_HAS_CONSTRUCTOR. * decl2.c (build_expr_from_tree): Propagate TREE_HAS_CONSTRUCTOR. * pt.c (tsubst_copy): Likewise. 1998-11-02 Mark Mitchell * init.c (expand_vec_init): Fix off-by-one error. 1998-11-02 Alexandre Oliva * parse.y (apparent_template_type): New type. (named_complex_class_head_sans_basetype): Use it. * Makefile.in (CONFLICTS): One new conflict. * parse.c: Regenerated. 1998-11-01 Mark Mitchell * cp-tree.h (COMPARE_STRICT): New macro. (COMPARE_BASE): Likewise. (COMPARE_RELAXED): Likewise. (COMPARE_REDECLARATION): Likewise. (same_type_p): Likewise. (same_or_base_type_p): Likewise. * call.c (standard_conversion): Use them, in place of comptypes with numeric arguments. (reference_binding): Likewise. (convert_like): Likewise. (build_over_call): Likewise. (is_subseq): Likewise. (is_properly_derived_from): Likewise. (compare_ics): Likewise. (joust): Likewise. * class.c (delete_duplicate_fields_1): Likewise. (resolves_to_fixed_type_p): Likewise. (instantiate_type): Likewise. Remove #if 0'd code. * decl.c (decls_match): Likewise. Use COMPARE_REDECLARATION here. (pushdecl): Likewise. (lookup_name_real): Likewise. (grokdeclarator): Likewise. Check for illegal array declarations. (grokparms): Likewise. (grok_op_properties): Likewise. * decl2.c (check_classfn): Likewise. * friend.c (is_friend): Likewise. (make_friend_class): Likewise. * init.c (expand_aggr_init): Likewise. (expand_vec_init): Likewise. * pt.c (is_member_template_class): Remove declaration. (is_specialization_of): Use COMPARE_* and new macros. (comp_template_parms): Likewise. (convert_nontype_argument): Likewise. (coerce_template_template_parms): Likewise. (template_args_equal): Likewise. (lookup_template_class): Likewise. (type_unification_real): Likewise. (unify): Likewise. (get_bindings_real): Likewise. * search.c (covariant_return_p): Likewise. (get_matching_virtual): Likewise. * sig.c (match_method_types): Likewise. * tree.c (vec_binfo_member): Likewise. (cp_tree_equal): Likewise. * typeck.c (common_type): Likewise. (comp_array_types): Likewise. Get issues involving unknown array bounds right. (comptypes): Update comments. Use new flags. (comp_target_types): Use new macros. (compparms): Likewise. (comp_target_parms): Likewise. (string_conv_p): Likewise. (build_component_ref): Likewise. (build_indirect_ref): Likewise. (build_conditional_expr): Likewise. (build_static_cast): Likewise. (build_reinterpret_cast): Likewise. (build_const_cast): Likewise. (build_modify_expr): Likewise. (convert_for_assignment): Likewise. (comp_ptr_ttypes_real): Likewise. (ptr_reasonably_similar): Likewise. (comp_ptr_ttypes_const): Likewise. 1998-10-31 Jason Merrill * rtti.c (build_dynamic_cast_1): Fix cut-and-paste error. 1998-10-30 Mark Mitchell * decl2.c (delete_sanity): Pass integer_zero_node, not integer_two_node, to build_vec_delete. * init.c (build_array_eh_cleanup): Remove. (expand_vec_init_try_block): New function. (expand_vec_init_catch_clause): Likewise. (build_vec_delete_1): Don't deal with case that auto_delete_vec might be integer_two_node anymore. (expand_vec_init): Rework for initialization-correctness and exception-correctness. * typeck2.c (process_init_constructor): Make mutual exclusivity of cases more obvious. 1998-10-29 Jason Merrill * decl.c (lookup_name_real): OK, only warn if not lexing. Simplify suggested fix. * cp-tree.h (IDENTIFIER_MARKED): New macro. * search.c (lookup_conversions): Use breadth_first_search. (add_conversions): Avoid adding two conversions to the same type. (breadth_first_search): Work with base binfos, rather than binfos and base indices. (get_virtual_destructor): Adjust. (tree_has_any_destructor_p): Adjust. (get_matching_virtual): Adjust. * pt.c (push_template_decl_real): Generalize check for incorrect number of template parms. (is_member_template_class): #if 0. 1998-10-29 Richard Henderson * Makefile.in (cc1plus): Put CXX_OBJS, and thence @extra_cxx_objs@, last. 1998-10-28 Zack Weinberg * lex.c: Call check_newline from lang_init always. After calling cpp_start_read, set yy_cur and yy_lim to read from the cpplib token buffer. 1998-10-28 Jason Merrill * class.c (instantiate_type): Don't consider templates for a normal match. * class.c (finish_struct_1): Don't complain about non-copy assignment ops in union members. * class.c (build_vtable): Don't pass at_eof to import_export_vtable. (prepare_fresh_vtable): Likewise. (finish_struct_1): Don't call import_export_class. * decl2.c (finish_vtable_vardecl): Do import/export stuff. (finish_prevtable_vardecl): Lose. (finish_file): Don't call it. * pt.c (instantiate_class_template): Likewise. * cp-tree.h: Remove it. * init.c (build_delete): Reset TYPE_HAS_DESTRUCTOR here. * decl.c (finish_function): Not here. (start_function): Do set DECL_INITIAL. * pt.c (push_template_decl_real): Complain about default template args for enclosing classes. * call.c (add_function_candidate): Treat conversion functions as coming from the argument's class. * cp-tree.h (DECL_CONV_FN_P): New fn. (DECL_DESTRUCTOR_P): Also check DECL_LANGUAGE. * class.c (add_method): Use DECL_CONV_FN_P. * decl2.c (check_classfn): Likewise. * error.c (dump_function_name): Likewise. (dump_function_decl): Likewise. * pt.c (fn_type_unification): Likewise. * search.c (add_conversions): Likewise. 1998-10-27 Jason Merrill * lex.c (do_identifier): Also generate LOOKUP_EXPR for RESULT_DECL. * method.c (hack_identifier): Also check for using RESULT_DECL from outer context. 1998-10-27 Mark Mitchell * decl.c (grokdeclarator): Use type_quals, rather than constp, consistently. 1998-10-27 Jason Merrill * call.c (standard_conversion): instantiate_type here. (reference_binding): And here. (implicit_conversion): Not here. (build_op_delete_call): No need to cons up an OVERLOAD. * cvt.c (cp_convert_to_pointer): instantiate_type here. (convert_to_reference): And here. * decl.c (grok_reference_init): Not here. (grokparms): Or here. * typeck2.c (digest_init): Or here. * typeck.c (decay_conversion): Take the address of overloaded functions, too. (require_instantiated_type): Lose. (convert_arguments): Don't handle unknown types here. (build_c_cast): Likewise. (build_binary_op): Gut. (build_conditional_expr): Don't require_instantiated_type. (build_modify_expr): Likewise. (build_static_cast): Don't instantiate_type. (build_reinterpret_cast): Likewise. (build_const_cast): Likewise. (convert_for_initialization): Likewise. (build_ptrmemfunc): Use type_unknown_p. (convert_for_assignment): Also do default_conversion on overloaded functions. Hand them off to ocp_convert. 1998-10-26 Mark Mitchell * error.c (dump_decl): Deal with TEMPLATE_DECLs that are VAR_DECLs. Handle vtables whose DECL_CONTEXT is not a type. * class.c (finish_struct_1): Use build_cplus_array_type to build array types. * decl.c (init_decl_processing): Likewise. * except.c (expand_end_eh_spec): Likewise. * search.c (expand_upcast_fixups): Simplify very slightly. 1998-10-26 Jason Merrill * decl.c (grokdeclarator): Complain about a variable using constructor syntax coming back null from start_decl. * friend.c (make_friend_class): Complain about trying to make a non-class type a friend. * decl.c (grokfndecl): Set DECL_INITIAL for a defn here. (start_function): Not here. 1998-10-26 Brendan Kehoe * decl.c (grokdeclarator): Disallow `explicit' in a friend declaration. 1998-10-26 Jason Merrill * typeck2.c (process_init_constructor): Only skip anonymous fields if they are bitfields. * cp-tree.def (TYPEOF_TYPE): New code. * error.c (dump_type_real): Handle it. * pt.c (tsubst): Likewise. * tree.c (search_tree): Likewise. * semantics.c (finish_typeof): New fn. * parse.y (typespec): Use it. * cp-tree.h: Declare it. 1998-10-26 Manfred Hollstein * cp-tree.h (FORMAT_VBASE_NAME): Make definition unconditional. 1998-10-26 Jason Merrill * typeck.c (convert_arguments): Don't handle pmf references specially. * init.c (build_member_call): Don't try to convert to the base type if it's ambiguous or pedantic. * typeck2.c (check_for_new_type): Only depend on pedantic for C-style casts. 1998-10-25 Mark Mitchell * decl.c (grokdeclarator): Set DECL_NONCONVERTING_P for all non-converting constructors. 1998-10-24 Martin von Löwis * gxxint.texi: Correct documentation for n, N, Q, and B. 1998-10-23 Martin von Löwis * parse.y (condition): Convert VAR_DECL from reference to indirect reference. 1998-10-23 Andrew MacLeod * exception.cc (__cp_pop_exception): Free the original exception value, not the potentially coerced one. 1998-10-23 Mark Mitchell * Makefile.in (hash.h): Run gperf when necessary. * cp-tree.h (CP_TYPE_READONLY): Remove. (CP_TYPE_VOLATILE): Likewise. (CP_TYPE_QUALS): New macro. (CP_TYPE_CONST_P): Likewise. (CP_TYPE_VOLATILE_P): Likewise. (CP_TYPE_RESTRICT_P): Likewise. (CP_TYPE_CONST_NON_VOLATILE_P): Likewise. (cp_build_type_variant): Rename to ... (cp_build_qualified_type): New function. (c_apply_type_quals_to_decl): Declare. (SIGNATURE_POINTER_NAME_FORMAT): Modify to allow `restrict'. (SIGNATURE_REFERENCE_NAME_FORMAT): Likewise. (cp_type_qual_from_rid): New function. (compparms): Remove unused parameter. All callers changed. (cp_type_quals): New function. (at_least_as_qualified_p): Likewise. (more_qualified_p): Likewise. * call.c (standard_conversion): Replace calls to cp_build_type_variant with cp_build_qualified_type. Use CP_TYPE_QUALS to get qualifiers and at_least_as_qualified_p to compare them. Use CP_TYPE_* macros to check qualifiers. (reference_binding): Likewise. (implicit_conversion): Likewise. (add_builtin_candidates): Likewise. (build_over_call): Likewise. * class.c (overrides): Compare all qualifiers, not just `const', on method declarations. * cvt.c (convert_to_reference): More CP_TYPE_QUALS conversion, etc. (convert_pointer_to_real): Likewise. (type_promotes_to): Likewise. * decl.c (check_for_uninitialized_const_var): New function. (init_decl_processing): More CP_TYPE_QUALS conversion, etc. (cp_finish_decl): Use check_for_uninitialized_const_var. (grokdeclarator): More CP_TYPE_QUALS conversion, etc. Update to handle `restrict'. (grok_ctor_properties): Likewise. (grok_op_properties): Likewise. (start_function): Likewise. (rever_static_member_fn): Likewise. * decl2.c (grok_method_quals): Likewise. (grokfield): Likewise. * error.c (dump_readonly_or_volatile): Rename to ... (dump_qualifiers): New function. Handle `restrict'. (dump_type_real): Use it. (dump_aggr_type): Likewise. (dump_type_prefix): Likewise. (dump_type_suffix): Likewise. (dump_function_decl): Likewise. (cv_as_string): Likewise. * gxx.gperf: Add __restrict and __restrict__. * gxxint.texi: Document `u' as used for `__restrict', and a few other previously undocumented codes. * hash.h: Regenerated. * init.c (expand_aggr_init): More CP_TYPE_QUALS conversion, etc. (build_member_call): Likewise. (build_new_1): Likewise. * lex.c (init_parse): Add entry for RID_RESTRICT. (cons_up_default_function): More CP_TYPE_QUALS conversion, etc. (cp_type_qual_from_rid): Define. * lex.h (enum rid): Add RID_RESTRICT. * method.c (process_modifiers): Deal with `restrict'. * parse.y (primary): More CP_TYPE_QUALS conversion, etc. * parse.c: Regenerated. * pt.c (convert_nontype_argument): More CP_TYPE_QUALS conversion, etc. (tsubst_aggr_type): Likewise. (tsubst): Likewise. (check_cv_quals_for_unify): Likewise. (unify): Likewise. * rtti.c (init_rtti_processing): Likewise. (build_headof): Likewise. (get_tinfo_var): Likewise. (buidl_dynamic_cast_1): Likewise. Fix `volatile' handling. (expand_class_desc): Likewise. (expand_attr_desc): Likewise. (synthesize_tinfo_fn): Likewise. * search.c (covariant_return_p): Likewise. Fix `volatile' handling. (get_matching_virtual): Likewise. (expand_upcast_fixups): Likewise. * sig.c (build_signature_pointer_or_reference_name): Take type_quals, not constp and volatilep. (build_signature_pointer_or_reference_type): Likewise. (match_method_types): More CP_TYPE_QUALS conversion, etc. (build_signature_pointer_constructor): Likewise. (build_signature_method_call): Likewise. * tree.c (build_cplus_array_type): Likewise. (cp_build_type_variant): Rename to ... (cp_build_qualified_type): New function. Deal with `__restrict'. (canonical_type_variant): More CP_TYPE_QUALS conversion, etc. (build_exception_variant): Likewise. (mapcar): Likewise. * typeck.c (qualif_type): Likewise. (common_type): Likewise. (comptypes): Likewise. (comp_cv_target_types): Likewise. (at_least_as_qualified_p): Define. (more_qualified_p): Likewise. (comp_cv_qualification): More CP_TYPE_QUALS conversion, etc. (compparms): Likewise. (inline_conversion): Likewise. (string_conv_p): Likewise. (build_component_ref): Likewise. (build_indirect_ref): Likewise. (build_array_ref): Likewise. (build_unary_op): Likewise. (build_conditional_expr): Likewise. (build_static_cast): Likewise. (build_c_cast): Likewise. (build_modify_expr): Likewise. (convert_For_assignment): Likewise. (comp_ptr_ttypes_real): Likewise. (cp_type_quals): New function. 1998-10-23 Jason Merrill * cp-tree.h (CP_TYPE_READONLY): New macro to handle arrays. (CP_TYPE_VOLATILE): Likewise. * decl.c (grokdeclarator): Use them. * tree.c (canonical_type_variant): Likewise. 1998-10-22 Martin von Löwis * parse.y (named_class_head): Push into class while parsing the base class list. * decl2.c (push_scope, pop_scope): New functions. * cp-tree.h: Declare them. * init.c (build_new_1): Delay cleanup until end of full expression. 1998-10-21 Jason Merrill * typeck.c (build_component_ref): Use of a type here is an error. 1998-10-19 Jason Merrill Revamp references to member functions. * method.c (hack_identifier): Call build_component_ref for a reference to a member function. * typeck.c (build_component_ref): Only return a single function if it's static. Otherwise, return a COMPONENT_REF. (build_x_function_call): Handle a COMPONENT_REF. (build_unary_op): Handle all unknown-type things. * decl2.c (arg_assoc): Handle COMPONENT_REF. * class.c (instantiate_type): Complain if the function we get is a nonstatic member function. Remove code for finding "compatible" functions. * pt.c (tsubst_copy): Handle NOP_EXPR. * tree.c (build_dummy_object): New fn. (maybe_dummy_object): New fn. (is_dummy_object): New fn. * cp-tree.h: Declare them. * cvt.c (cp_convert_to_pointer): Use maybe_dummy_object. * error.c (dump_expr, case OFFSET_REF): Use is_dummy_object. * init.c (build_member_call): Use maybe_dummy_object and is_dummy_object. (build_offset_ref): Use maybe_dummy_object. (resolve_offset_ref): Use is_dummy_object. * typeck.c (build_x_function_call): Call build_dummy_object. (unary_complex_lvalue): Call is_dummy_object. * typeck.c (build_component_addr): Make sure field is a field. * call.c (build_new_op): Delete obsolete code. * pt.c (tsubst, TEMPLATE*PARM*): Abort if we don't have any args. 1998-10-18 Martin von Löwis * decl2.c (validate_nonmember_using_decl): Fix using-directives of std if std is ignored. 1998-10-18 Jason Merrill * decl.c (grokvardecl): Fix thinko. * decl.c (grokdeclarator): Embedded attrs bind to the right, not the left. * parse.y (fn.def2): Fix 'attrs' format. 1998-10-18 Alastair J. Houghton * Makefile.in (CONFLICTS): Update. * parse.y (expr_or_declarator_intern): New rule. (expr_or_declarator, direct_notype_declarator, primary, functional_cast): Use it. (notype_declarator_intern): New rule. (notype_declarator, complex_notype_declarator): Use it. 1998-10-17 Jason Merrill * decl.c (grokfndecl): Set DECL_CONTEXT to namespace if appropriate. (grokvardecl): Likewise. Sat Oct 17 23:27:20 1998 Kaveh R. Ghazi * class.c (make_method_vec): Cast 1st argument of `bzero' to (PTR). (add_method): Likewise for arguments 1 & 2 of `bcopy'. * decl.c (signal_catch): Mark with ATTRIBUTE_NORETURN. * pt.c (process_partial_specialization): Cast 1st argument of `bzero' to (PTR). * tree.c (build_base_fields): Cast `base_align' to (int) when comparing against one. 1998-10-16 Mark Mitchell * decl.c (lookup_name_real): Handle template parameters for member templates where said parameters have the same name as the surrounding class. * decl.c (expand_static_init): Build cleanups before entering the anonymous function used to do them to avoid access-checking confusion. * decl.c (grokfndecl): Add back call to cplus_decl_attributes accidentally removed by previous change, and make DECL_RTL here. * class.c (add_method): Don't make DECL_RTL here. * pt.c (for_each_template_parm): Don't examine uninstantiated default arguments. 1998-10-16 Dave Brolley * lex.c (real_yylex): Fix unaligned access of wchar_t. 1998-10-16 Mark Mitchell * class.c (add_method): Fix documentation to reflect previous changes. Check for duplicate method declarations here. * decl.c (decls_match): Handle FUNCTION_DECL vs TEMPLATE_DECL correctly; such things never match. (grokfndecl): Don't look for duplicate methods here. * decl2.c (check_classfn): Don't assume names are mangled. Don't add bogus member function declarations to a class before the class type is complete. (grokfield): Reformat error message. * method.c (set_mangled_name_for_decl): Don't mangle names while processing_template_decl. 1998-10-16 Jason Merrill * typeck.c (build_indirect_ref): Complain about a pointer to data member, too. * typeck2.c (build_m_component_ref): Don't indirect a pointer to data member. * init.c (resolve_offset_ref): Don't undo the above. * cp-tree.h (DECL_C_BIT_FIELD, SET_DECL_C_BIT_FIELD): New macros. (struct lang_decl_flags): Add `bitfield'. * class.c (finish_struct_1): Use DECL_C_BIT_FIELD instead of DECL_BIT_FIELD. * decl2.c (grokbitfield, grok_alignof): Likewise. * init.c (build_offset_ref): Likewise. * typeck.c (build_component_addr, expr_sizeof): Likewise. * cvt.c (build_up_reference): Don't crash if taking the address returns error_mark_node. * decl.c (grokfndecl): Also check ctype when checking for ::main(). 1998-10-15 Jason Merrill * decl.c (grokfndecl): ::main and __builtin_* get C linkage. Do mangling here. (grokdeclarator): Instead of here. * friend.c (do_friend): Lose special handling of ::main and __builtin_*. * cp-tree.h (DECL_MAIN_P): Check for C linkage. * spew.c (yylex): Clear looking_for_typename if we got 'enum { ... };'. 1998-10-15 Mark Mitchell * class.c (maybe_warn_about_overly_private_class): Improve error messages for class with only private constructors. * cp-tree.def (TYPENAME_TYPE): Add to documentation. * cp-tree.h (TYPENAME_TYPE_FULLNAME): Document. (build_typename_type): New function. * decl.c (build_typename_type): Broken out from ... (make_typename_type): Use it. * search.c (lookup_field): Likewise. 1998-10-14 Benjamin Kosnik * pt.c (convert_nontype_argument): Check against type_referred_to. * decl.c (grokvardecl): Check for declarator name before building DECL_ASSEMBLER_NAME. 1998-10-14 Mark Mitchell * pt.c (lookup_template_class): Add comment. (instantiate_class_template): Don't mark the _TYPE node for member class templates as an instantiation. 1998-10-14 Jason Merrill * decl.c (grokfndecl): Fix my thinko. 1998-10-13 Jason Merrill * tinfo2.cc (fast_compare): Remove. (before): Just use strcmp. * tinfo.cc (operator==): Just use strcmp. 1998-10-13 Klaus-Georg Adams * decl.c (grokfndecl): Don't check for linkage in `extern "C"' declarations. 1998-10-13 Mark Mitchell * cp-tree.h (specializations_of_same_template_p): Remove. * search.c (get_template_base): Don't use it. (get_template_base_recursive): Likewise. * pt.c (specializations_of_same_template_p): Remove. (unify): Don't use it. (lookup_template_class): Find the correct parent when setting CLASSTYPE_TI_TEMPLATE. 1998-10-12 Jason Merrill * tinfo.cc (operator==): Always compare names. 1998-10-12 Herman ten Brugge * decl.c (start_function): Fix cut-and-paste error. 1998-10-12 Jason Merrill * inc/typeinfo: Add #pragma interface. (operator!=): Just call operator==. * tinfo.cc: Add #pragma implementation. (operator==): Move from inc/typeinfo and tinfo2.cc. Check __COMMON_UNRELIABLE instead of _WIN32. * typeck2.c (my_friendly_abort): Add URL. 1998-10-12 Alastair J. Houghton * decl.c (start_method): Added extra parameter for attributes. * cp-tree.h (start_method): Update prototype. * parse.y (fn.def2): Update start_method parameter list. 1998-10-11 Mark Mitchell * cp-tree.h (specializations_of_same_template_p): Declare. * pt.c (specializations_of_same_template_p): New function. (unify): Use it. * search.c (get_template_base): Use it. (get_template_base_recursive): Likewise. 1998-10-10 Manfred Hollstein * decl2.c (start_objects): Add new variable `joiner' and initialize it properly. 1998-10-09 Mark Mitchell * search.c (expand_upcast_fixups): Tweak to match 1998-10-07 change to vtable types. * cvt.c (ocp_convert): Avoid infinite recursion caused by 1998-10-03 change. 1998-10-08 Jason Merrill * pt.c (resolve_overloaded_unification): New fn. (try_one_overload): Likewise. (unify): Don't fail on unknown type. (type_unification_real): Likewise. Use resolve_overloaded_unification to handle an overloaded argument. (template_args_equal): Split out... (comp_template_args): From here. (determine_specialization): Also allow a template with more parms than were explicitly specified. * cp-tree.h: Add template_args_equal. * call.c (resolve_args): Remove TEMPLATE_ID_EXPR code. Thu Oct 8 15:58:30 1998 Anthony Green * semantics.c (finish_asm_stmt): Revert my 1998-09-28 change. Thu Oct 8 06:00:19 1998 Jeffrey A Law (law@cygnus.com) * typeck.c (unsigned_type): Only return TItype nodes when HOST_BITS_PER_WIDE_INT is >= 64 bits. (signed_type): Likewise. * decl.c (intTI_type_node, unsigned_intTI_type_node): Only declare when HOST_BITS_PER_WIDE_INT is >= 64 bits. (init_decl_processing): Only create TItype nodes when HOST_BITS_PER_WIDE_INT is >= 64 bits. * cp-tree.h (intTI_type_node, unsigned_intTI_type_node): Only declare when HOST_BITS_PER_WIDE_INT is >= 64 bits. Wed Oct 7 12:32:44 1998 Kaveh R. Ghazi * Makefile.in (hash.h): Add -L KR-C -F ', 0, 0' flags to gperf. (gxx.gperf): Update comments describing invocation flags. (hash.h): Regenerate using gperf 2.7.1 (19981006 egcs). 1998-10-07 Mark Mitchell * class.c (finish_struct_1): Add commentary on previous change. * cp-tree.h (vtbl_ptr_type_node): New variable. * class.c (build_vtbl_ref): Don't indirect through the vptr; it's already of the right type. (finish_struct_1): Make the vptr be of type vtbl_ptr_type_node. Simplify code to grow vtable. * decl.c (vtbl_ptr_type_node): Define. (init_decl_processing): Initialize it. 1998-10-06 Mark Mitchell * cp-tree.def (PTRMEM_CST): New tree node. * cp-tree.h (ptrmem_cst): New type. (lang_type): Remove local_typedecls. (dummy): Increase to 12 bits from 11. (CLASSTYPE_LOCAL_TYPEDECLS): Remove. (PTRMEM_CST_CLASS): New macro. (PTRMEM_CST_MEMBER): Likewise. (current_access_specifier): New variable. (current_class_type): Remove duplicate declaration. (finish_struct): Change prototype. (unreverse_member_declarations): New function. (pushdecl_class_level): Change prototype. (grok_enum_decls): Remove. (fixup_anonymous_union): New function. (grok_x_components): Change prototype. (tsubst_chain): Remove. (finish_member_template_decl): Likewise. (check_explicit_specialization): Fix indentation. (finish_class_definition): Change prototype. (finish_member_class_template): Likewise. (finish_member_declaration): New function. (check_multiple_declarators): Likewise. * class.c (class_stack_node_t): New type. (current_class_base): Remove. (current_class_stack): Change type. (current_access_specifier): New variable. (grow_method): Remove. (check_member_decl_is_same_in_complete_scope): Break out from finish_struct. (make_method_vec): New function. (free_method_vec): Likewise. (add_implicitly_declared_members): Break out from finish_struct_1. (free_method_vecs): New variable. (add_method): Rework for direct use from parser. (handle_using_decl): Watch for NULL_TREE while iterating through CLASSTYPE_METHOD_VEC. (finish_struct_methods): Don't build CLASSTYPE_METHOD_VEC here; just do some error-checking. (warn_hidden): Change iteration through CLASSTYPE_METHOD_VEC. (finish_struct_1): Simplify. Use add_implicitly_declared_members. (finish_struct): Change prototype. Simplify; fields and methods are already set up at this point. (init_class_processing): Set up current_class_stack. (pushclass): Save current_access_specifier. (popclass): Restore it. (currently_open_class): Simplify. (build_self_reference): Remove use of CLASSTYPE_LOCAL_TYPEDECLS. * decl.c (saved_scope): Add access_specifier. (maybe_push_to_top_level): Save it. (pop_from_top_level): Restore it. (maybe_process_template_type_declaration): Use finish_member_declaration. (pushtag): Likewise. (pushdecl_class_level): Don't return a value. (fixup_anonymous_union): Break out from grok_x_components. (shadow_tag): Use it. (xref_tag): Complain about using an elaborated type specifier to reference a template type parameter or typedef name. (xref_basetypes): Don't set CLASSTYPE_LOCAL_TYPEDECLS. (current_local_enum): Remove. (build_enumerator): Call finish_member_declaration. (grok_enum_decls): Remove. * decl2.c (grok_x_components): Simplify. (check_classfn): Change iteration through CLASSTYPE_METHOD_VEC. (grokfield): Don't set CLASSTYPE_LOCAL_TYPEDECLS. (merge_functions): Add to comment. (arg_assoc_type): Prototype. (arg_assoc): Pass as many arguments as there are parameters. * error.c (dump_expr): Handle PTRMEM_CST. Improve handling of OFFSET_REF. * expr.c (cpls_expand_expr): Remove dead code. Handle PTRMEM_CST. * friend.c (do_friend): Lookup friends when in nested classes. Change comments. * init.c (build_offset_ref): Do lookup even for classes that are only partially defined. (decl_constant_value): Remove dead code. * method.c (build_overload_value): Remove hack where by TYPE was not a TYPE. Handle PTRMEM_CST. (build_template_parm_names): Don't pass a PARM_DECL where a TYPE should go. * parse.y (components, notype_components, component_decl, component_decl_1, component_declarator, component_declarator0): Now all are itype rather than ttype. Rework to add members to classes on the fly. (typesqpecqual_reserved): Use check_multiple_declarators. (structsp): Update class to finish_class_definition. (do_xref_defn): Unsplit into named_class_head. (access_specifier): Set current_access_specifier. * pt.c (set_current_access_from_decl): New function. (finish_member_template_decl): Don't take the parameters. (comp_template_args): Make more robust. (lookup_template_class): Don't use current_local_enum. (for_each_template_parm): Handle PTRMEM_CST. (instantiate_class_template): Use set_current_access_from_decl, finish_member_declaration and unreverse_member_declarations. Set lineno/input_filename before generating implicit member functions. (type_unification_real): Don't assume back-unification happens only for the last argument. (regenerate_decl_from_template): Call pushclass a bit earlier. (tsubst_chain): Remove. (tsubst_enum): Use set_current_access_from_decl. (set_mangled_name_for_template_decl): Fix indentation. * search.c (lookup_fnfields_1): Change iteration through CLASSTYPE_METHOD_VEC. (dfs_pushdecls): Likewise. (dfs_compress_decls): Likewise. (add_conversions): Likewise. * semantics.c (finish_class_definition): Don't take components. Change call to finish_struct. (finish_member_declaration): New function. (finish_member_class_template): Don't take template parameters. Change call to grok_x_components. Call finish_member_template_decl. (check_multiple_declarators): New function. * sig.c (append_signature_fields): Work from the TYPE_METHODS, not a passed in fieldlist. * tree.c (search_tree): Handle PTRMEM_CST. (mapcar): Likewise. * typeck.c (unary_complex_lvalue): Build PTRMEM_CSTs, not INTEGER_CSTs, for pointer-to-data members. * call.c (resolve_args): Resolve template specializations, if possible. Tue Oct 6 07:57:26 1998 Kaveh R. Ghazi * Makefile.in (spew.o): Depend on toplev.h. * call.c (compare_ics): Initialize variables `deref_from_type2', `deref_to_type1' and `deref_to_type2'. * except.c (get_eh_type): Hide prototype and definition. (process_start_catch_block_old): Remove unused static prototype. * pt.c (tsubst_decl): Initialize variable `argvec'. * spew.c: Include toplev.h. 1998-10-05 Jason Merrill * pt.c (instantiate_decl): Do save and restore file position. 1998-10-05 Martin von Löwis * method.c (build_decl_overload_real): Clear numeric_output_need_bar after __. 1998-10-05 Nathan Sidwell * call.c (build_new_method_call): Issue 'incomplete type' error, if class is not defined. 1998-10-05 Kaveh R. Ghazi * call.c (build_object_call): Move declaration of variable `fn' into the scope where it is used. Don't access variable `fn' when it is uninitialized, instead use `fns'. 1998-10-04 Theodore Papadopoulo * errfn.c (cp_thing): Print buf as a string not as a printf format to avoid problems with the operator%. Consequently, `%%' sequences in format are copied as `%' in buf. 1998-10-04 Jason Merrill * pt.c (pop_tinst_level): Call extract_interface_info. (instantiate_decl): Don't save and restore file position. * decl.c (cp_finish_decl): Make statics in extern inlines and templates common, if possible and the target doesn't support weak symbols. * decl.c (grokdeclarator): Remove redundant calls to build_type_variant and some duplicated code. * sig.c (build_signature_reference_type): Only take the type parm. (build_signature_pointer_type): Likewise. * tree.c (build_cplus_method_type): Adjust. * cp-tree.h: Update. 1998-10-04 Mark Mitchell * call.c (build_over_call): Make pedwarns about dropped qualifiers into full-fledged errors. * cvt.c (convert_to_reference): Likewise. * typeck.c (convert_for_assignment): Likewise. * search.c (expand_upcast_vtables): In addition to unsetting TREE_READONLY, remove top-level const type qualifier. 1998-10-03 Mark Mitchell * class.c (current_class_ptr, current_class_ref): Clarify documentation. * cvt.c (ocp_convert): Don't expect fold to remove all trivial NOP type conversions. * decl.c (decls_match): Use comptypes directly; ignore qualifiers on the DECL. (duplicate_decls): Remove qualifier checks on DECL. (grokdeclarator): Make the type built up include top-level qualifiers. * decl2.c (do_dtors): Fix spelling error. * error.c (dump_simple_decl): Don't look at qualifiers on the decl when printing type information. * init.c (build_new_1): Add documentation. Deal with the fact that type of allocated memory now contains qualifiers. * lex.c (is_global): Improve error-recovery. * sig.c (build_member_function_pointer): Don't cast away const on fields of sigtable_entry_type. * tree.c (lvalue_type): Don't look at top-level qualifiers on expressions. * typeck.c (decay_conversion): Likewise. (build_component_ref): Make sure the type of the COMPONENT_REF contains top-level qualifiers, as appropriate. Improve error-handling. (build_indirect_ref): Simplify. Don't strip top-level qualifiers. (build_array_ref): Likewise. (build_unary_op): Improve error-recovery. (unary_complex_lvalue): Make taking the address a bound member function an error, not a sorry. (build_conditional_expr): Look at the type qualifiers, not the qualifiers on the expression itself. 1998-10-03 Jason Merrill * decl2.c (merge_functions): Remove duplicates. * decl2.c: Add -f{no-,}implicit-inline-templates. (import_export_decl): Check it. * decl.c (lookup_name_real): Template parms also take precedence over implicit typename. Only warn if yylex. * typeck.c (build_conditional_expr): Only fold if ifexp is an INTEGER_CST. * decl2.c (finish_vtable_vardecl): Check DECL_INTERFACE_KNOWN instead of linkage. 1998-10-01 Jason Merrill * cp-tree.h (FORMAT_VBASE_NAME): New macro. * class.c (build_vbase_pointer): Use it. * rtti.c (expand_class_desc): Likewise. * tree.c (build_vbase_pointer_fields): Likewise. Thu Oct 1 10:43:45 1998 Nick Clifton * decl.c (start_decl): Add invocation of SET_DEFAULT_DECL_ATTRIBUTES, if defined. (start_function): Add invocation of SET_DEFAULT_DECL_ATTRIBUTES, if defined. * lex.c: Replace occurrences of HANDLE_SYSV_PRAGMA with HANDLE_GENERIC_PRAGMAS. 1998-09-28 Anthony Green * semantics.c (finish_asm_stmt): Always permit volatile asms. 1998-09-28 Mark Mitchell * decl.c (grokdeclarator): Tighten checks for invalid destructors. Improve error-messages and error-recovery. * decl2.c (check_classfn): Don't assume that mangled destructor names contain type information. 1998-09-25 Jason Merrill * search.c (get_base_distance): Remove assert. * decl2.c (build_anon_union_vars): Don't process a field with no name. (finish_anon_union): Also complain about local anon unions with no members. 1998-09-25 Martin von Löwis * decl.c (lookup_namespace_name): If the name is a namespace, return it immediately. Fri Sep 25 11:45:38 1998 Kaveh R. Ghazi * cp-tree.h (define_case_label): Remove unused parameter. (check_java_method): Likewise. (grokclassfn): Likewise. (expand_aggr_init): Likewise. (build_x_delete): Likewise. (maybe_end_member_template_processing): Likewise. (unshare_base_binfos): Add prototype. (string_conv_p): Likewise. (my_friendly_abort): Mark with ATTRIBUTE_NORETURN. * cvt.c (build_up_reference): Remove unused parameter `checkconst', all callers changed. (build_type_conversion): Mark parameter `code' with ATTRIBUTE_UNUSED. (build_expr_type_conversion): Initialize variable `conv'. * decl.c (push_namespace): Initialize variable `d'. (define_case_label): Remove unused parameter `decl', all callers changed. * decl2.c (lang_decode_option): If !USE_CPPLIB, mark parameter `argc' with ATTRIBUTE_UNUSED. (grokclassfn): Remove unused parameter `cname', all callers changed. (check_java_method): Likewise for parameter `ctype'. (copy_assignment_arg_p): Mark parameter `virtualp' with ATTRIBUTE_UNUSED. (finish_prevtable_vardecl): Likewise for parameter `prev'. * expr.c (extract_init): Likewise for parameters `decl' and `init'. * init.c (expand_aggr_init_1): Remove unused parameter `alias_this', all callers changed. (expand_aggr_init): Likewise. (expand_default_init): Likewise. (build_new_1): Initialize variable `susp'. (build_x_delete): Remove unused parameter `type', all callers changed. * lex.c (set_typedecl_interface_info): Mark parameter `prev' with ATTRIBUTE_UNUSED. (readescape): Use (unsigned) value in shift. (real_yylex): Likewise. Likewise. Also cast `sizeof' to int when comparing to a signed quantity. * pt.c (maybe_end_member_template_processing): Remove unused parameter `decl', all callers changed. (check_explicit_specialization): Add braces around empty body in an else-statement. (current_template_args): Initialize variable `args'. (lookup_template_class): Likewise for variable `prev_local_enum'. (tsubst_decl): Likewise for variable `r'. (set_mangled_name_for_template_decl): Initialize variable `context'. * spew.c (scan_tokens): Change type of parameter `n' to unsigned. Likewise for variable `i'. (yylex): Initialize variable `trrr'. * typeck.c (compparms): Mark variable `strict' with ATTRIBUTE_UNUSED. * xref.c (simplify_type): Cast argument of ctype function to `unsigned char'. 1998-09-24 Mark Mitchell * cp-tree.h (language_lvalue_valid): Remove. * decl.c (grokdeclarator): Don't disallow references to functions. * tree.c (lvalue_p_1): New function, combining duplicated code from ... (lvalue_p): Use it. (real_lvalue_p): Likewise. * typeck.c (language_lvalue_valid): Remove. (build_modify_expr): Treat FUNCTION_TYPEs as readonly, even though they don't have TREE_READONLY set. * typeck2.c (readonly_error): Add case for FUNCTION_DECLs. 1998-09-24 Benjamin Kosnik * spew.c (yylex): Give diagnostic. * hash.h (is_reserved_word): Add export. * gxx.gperf: Likewise. * lex.h (rid): Add RID_EXPORT. * lex.c (init_parse): Likewise. Tue Sep 22 21:01:19 1998 Gerald Pfeifer * friend.c (do_friend): Make warning a full sentence. 1998-09-22 Mark Mitchell * parse.y (component_decl_list): Improve error-recovery. 1998-09-22 Benjamin Kosnik * decl.c (make_typename_type): Move error to point where name variable can be used by dump_type. 1998-09-22 Mark Mitchell * decl.c (grokfndecl): Improve error-recovery. * decl2.c (grokfield): Likewise. * pt.c (finish_member_template_decl): Likewise. 1998-09-20 Martin von Löwis * method.c (hack_identifier): Finding multiple members is always an error. 1998-09-21 Per Bothner * Make-lang.in (c++-filt): Link libiberty.a after cxxmain.o. Mon Sep 21 01:53:05 1998 Felix Lee * lex.c (init_lex): Use getenv ("LANG"), not GET_ENVIRONMENT (). 1998-09-20 Mark Mitchell * class.c (maybe_warn_about_overly_private_class): Reformat. 1998-09-17 Andrew MacLeod * exception.cc (__cplus_type_matcher): Realign some code. 1998-09-16 Mark Mitchell * Make-lang.in (tinfo.o): Use CXXFLAGS when compiling. (tinfo2.o): Likewise. (exception.o): Likewise. (new.o): Likewise. (opnew.o): Likewise. (opnewnt.o): Likewise. (opvnew.o): Likewise. (opvnewnt.o): Likewise. (opdel.o): Likewise. (opdelnt.o): Likewise. (opvdel.o): Likewise. (opvdelnt.o): Likewise. 1998-09-16 Richard Henderson * decl.c (init_decl_processing): Kill __builtin_fp and __builtin_sp. 1998-09-15 Alexandre Oliva * call.c (build_field_call): Handle static data members too. * typeck.c (comptypes): When comparing pointer types, check whether referred types match even in strictest modes. 1998-09-15 Mark Mitchell * cp-tree.h: Revert previous change. (finish_struct_methods): Remove declaration. * class.c: Revert previous change. (maybe_warn_about_overly_private_class): New function. (finish_struct_methods): Declare here, and make static. Remove unnecessary parameters. Tidy slightly. Use maybe_warn_about_overly_private_class. (finish_struct_1): Adjust. Remove check for private constructors, now done elsewhere. (finish_struct): Adjust. 1998-09-15 Andrew MacLeod * except.c (expand_start_catch_block): No need to check for new exception model. (process_start_catch_block_old): Deleted. (process_start_catch_block): Add call to start_decl_1(). (expand_end_catch_block): Add call to end_catch_handler(). * exception.cc (__cplus_type_matcher): Only check the exception language if there is an exception table. 1998-09-15 Andrew MacLeod * search.c (expand_indirect_vtbls_init): Mark temporary stack slots as used to prevent conflicts with virtual function tables. 1998-09-14 Mark Mitchell * cp-tree.h (lang_type): Add has_non_private_static_mem_fn. (CLASSTYPE_HAS_NON_PRIVATE_STATIC_MEM_FN): New macro, to access it. * class.c (maybe_class_too_private_p): New function. (finish_struct_methods): Use it. (finish_struct_1): Likewise. (finish_struct): Set CLASSTYPE_HAS_NON_PRIVATE_STATIC_MEM_FN if appropriate. * pt.c (check_specialization_scope): Fix spelling error. (check_explicit_specialization): Remove code to handle explicit specializations in class scope; they are now correctly diagnosed as errors. 1998-09-10 Mark Mitchell * decl.c (pushdecl): Don't copy types if the DECL_ABSTRACT_ORIGIN of the new decl matches the TYPE_NAME of the type. 1998-09-09 Kriang Lerdsuwanakij * class.c (get_enclosing_class): New function. (is_base_of_enclosing_class): Likewise. * cp-tree.h (get_enclosing_class): Declare. (is_base_of_enclosing_class): Likewise. * pt.c (coerce_template_parms): Use them. 1998-09-09 Jason Merrill * g++spec.c (lang_specific_driver): Check whether MATH_LIBRARY is null to decide whether to use it. * error.c (dump_type_real): Handle NAMESPACE_DECL. * parse.y (base_class.1): Avoid crash on error. 1998-09-08 Martin von Löwis * decl.c (make_typename_type): If context is a namespace, the code is in error. 1998-09-08 Mumit Khan * parse.y (nomods_initdcl0): Set up the parser stack correctly. 1998-09-08 Mark Mitchell * cp-tree.h (anonymous_namespace_name): Declare. * decl.c: Define it. (push_namespace): Use anonymous_namespace_name, rather than local static anon_name. * error.c (dump_decl): If a namespace is named anonymous_namespace_name, call it {anonymous}. * decl.c (grokparms): Distinguish between references and pointers in error message. 1998-09-08 Richard Henderson Mark Mitchell * pt.c (process_partial_specialization): Consistently allocate and zero tpd.parms based on ntparms. Use tpd2.parms, not tpd.parms, where appropriate. Sun Sep 6 00:00:51 1998 Jeffrey A Law (law@cygnus.com) * Makefile.in (INCLUDES): Update after recent toplevel gcc reorganizations. 1998-09-05 Mark Mitchell * cp-tree.h (TI_PENDING_SPECIALIZATION_FLAG): Remove. * class.c (finish_struct): Remove hackery to deal with explicit specializations in class scope. * decl.c (grokfndecl): Improve error-recovery. * decl2.c (grokfield): Likewise. * pt.c (check_specialization_scope): New function. (begin_specialization): Call it. (process_partial_specialization): New function, split out from push_template_decl. Check partial specializations more stringently. (push_template_decl): Call it. (check_explicit_specialization): Don't attempt to handle explicit specializations in class scope. (template_parm_data): Document. Add current_arg and arg_uses_template_parms. (mark_template_parm): Set it. (tsubst_arg_types): Remove unused variable. * semantics.c (begin_class_definition): Tweak. 1998-09-04 Mark Mitchell * inc/typeinfo (type_info::type_info(const char*)): Make `explicit'. * cp-tree.h (hash_tree_cons_simple): New macro. * pt.c (tsubst_arg_types): New function. Use hash_tree_cons. (coerce_template_parms): Use make_temp_vec, instead of make_tree_vec. Document this behavior. (lookup_template_class): Likewise. (tsubst, cases METHOD_TYPE, FUNCTION_TYPE): Use tsubst_arg_types. Remove dead code (and add assertion to check its deadness). Fix bug w.r.t. exception specifications. 1998-09-03 Jason Merrill * decl2.c (import_export_vtable): Always make artificials comdat. (import_export_decl): Likewise. * pt.c (mark_decl_instantiated): Likewise. 1998-09-03 Mark Mitchell * cp-tree.h (finish_globally_qualified_member_call_expr): Rename to ... (finish_qualified_call_expr). * semantics.c: Likewise. * parse.y (primary): Use it. * method.c (hack_identifier): Remove redundant code. * init.c (resolve_offset_ref): Call convert_from_reference to handle members of reference type. Improve error recovery. 1998-09-03 Benjamin Kosnik * cp-tree.h: Declare warn_nontemplate_friend. * decl2.c (lang_decode_option): Set. * lang-options.h: Add -Wnon-template-friend. * friend.c (do_friend): Use to toggle non-template function warning. 1998-09-03 Mark Mitchell * decl.c (finish_enum): Don't resolve CONST_DECLs to their corresponding INTEGER_CSTs when processing_template_decl. * pt.c (tsubst_enum): Tweak accordingly. 1998-09-03 Benjamin Kosnik * decl.c (pushdecl_class_level): Add warning here. (pushdecl): Tweak. 1998-09-02 Jason Merrill * cvt.c (convert_pointer_to_real): Tidy. * search.c (get_base_distance_recursive): Simplify. (get_base_distance): Likewise. * pt.c (unify): Only special-case INTEGER_TYPE if it uses template parms. Wed Sep 02 09:25:29 1998 Nick Clifton * lex.c (check_newline): Call HANDLE_PRAGMA before HANDLE_SYSV_PRAGMA if both are defined. Generate warning messages if unknown pragmas are encountered. (handle_sysv_pragma): Interpret return code from handle_pragma_token (). Return success/failure indication rather than next unprocessed character. (pragma_getc): New function: retrieves characters from the input stream. Defined when HANDLE_PRAGMA is defined. (pragma_ungetc): New function: replaces characters back into the input stream. Defined when HANDLE_PRAGMA is defined. 1998-09-01 Jason Merrill * decl2.c (output_vtable_inherit): Use %cDIGIT in the operands. * class.c (build_vtable_entry_ref): Likewise. 1998-09-01 Mark Mitchell * cp-tree.h (DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION): New macro. * decl2.c (import_export_decl): Likewise. * pt.c (instantiate_decl): Use it. 1998-09-01 Jason Merrill * decl.c (lookup_name_real): Also do implicit typename thing for artificial TYPE_DECLs. * search.c (lookup_field): Likewise. (lookup_fnfields, lookup_field): Adjust for implicit typename kludge. * semantics.c (begin_constructor_declarator): Use enter_scope_of. (enter_scope_of): Extract type from implicit typename. (begin_class_definition): Likewise. * lex.c (identifier_type): Handle implicit typename when checking for SELFNAME. * cp-tree.h: Declare flag_strict_prototype. * lex.c (do_scoped_id, do_identifier): Don't implicitly_declare if -fstrict-prototype. * decl.c (init_decl_processing): If -f{no,-}strict-prototype wasn't specified, set it to the value of pedantic. 1998-09-01 Mark Mitchell * decl2.c (arg_assoc): Handle template-id expressions as arguments. 1998-08-31 Mark Mitchell * decl.c (finish_enum): Handle member enums of classes declared in template functions. * decl2.c (grok_x_components): Strip attributes before calling groktypename. 1998-08-31 Jason Merrill * cp-tree.h, decl2.c: Remove support for -fall-virtual, -fenum-int-equivalence and -fno-nonnull-objects. * class.c (check_for_override): Remove support for -fall-virtual. (finish_struct_1): Likewise. * call.c (build_new_op): Remove support for -fenum-int-equivalence. * typeck.c (build_binary_op_nodefault): Likewise. * cvt.c (ocp_convert): Likewise. * call.c (build_vfield_ref): Remove support for -fno-nonnull-objects. * class.c (build_vbase_path): Likewise. Sun Aug 30 22:16:31 1998 H.J. Lu (hjl@gnu.org) * Makefile.in (INTERFACE): New, set to 1. 1998-08-30 Mark Mitchell * error.c (dump_decl): Use CP_DECL_CONTEXT, not DECL_CONTEXT, when comparing with global_namespace. (dump_aggr_type): Likewise. * decl.c (grokfndecl): Issue error on declaration of friend templates with explicit template arguments. * pt.c (convert_template_argument): New function, split out from... (coerce_template_parms): Here. (tsubst): Attempt better error-recovery. 1998-08-28 Benjamin Kosnik * pt.c (decl_template_parm_p): Add checks for TEMPLATE_TEMPLATE_PARM. 1998-08-28 Mark Mitchell * lex.c (do_identifier): Fix thinko in previous change. 1998-08-28 Jason Merrill * search.c (dfs_search, binfo_for_vtable, dfs_bfv_helper): New fns. * decl2.c (output_vtable_inherit): Call binfo_for_vtable. 1998-08-28 Richard Henderson Add support for discarding unused virtual functions. * lang-options.h: Add -fvtable-gc. * cp-tree.h: Add flag_vtable_gc. * decl2.c (output_vtable_inherit): New fn. (finish_vtable_vardecl): Call it. * class.c (build_vtable_entry_ref): New fn. (build_vtbl_ref): Call it. 1998-08-28 Mark Mitchell * cp-tree.h (build_enumerator): Take the enumeration type as a parameter. * decl.c (finish_enum): Don't set the TREE_TYPE for the enumeration constant values if we're processing_template_decls. Don't set the type for the CONST_DECLs either; that's done in build_enumerator. (build_enumerator): Take the enumeration type as a parameter. * lex.c (do_identifier): Don't resolve enumeration constants while processing template declarations, even if they happen to be TEMPLATE_PARM_INDEXs. * parse.y (current_enum_type): New variable. (primary): Don't allow statement-expression in local classes just as we don't in global classes. (structsp): Use current_enum_type. (enum_list): Likewise. * pt.c (tsubst_enum): Don't check for NOP_EXPRs introduced by finish_enum; they no longer occur. * cp-tree.h (finish_base_specifier): New function. * parse.y (base_class): Use it. * semantics.c (finish_base_specifier): Define it. * parse.y (structsp): Warn on use of typename outside of template declarations. 1998-08-27 Jason Merrill * lex.c (handle_cp_pragma): Remove #pragma vtable. * lang-options.h: Remove +e options. * decl2.c (lang_decode_option): Likewise. (import_export_vtable): Don't check write_virtuals. (finish_vtable_vardecl, finish_file): Likewise. * search.c (dfs_debug_mark): Likewise. * semantics.c (begin_class_definition): Likewise. * class.c (build_vtable, finish_vtbls, finish_struct_1): Likewise. * call.c (build_over_call): Check flag_elide_constructors. * decl2.c: flag_elide_constructors defaults to 1. * typeck.c (convert_arguments): Remove return_loc parm. (build_function_call_real): Adjust. * search.c: Tear out all mi_matrix and memoize code. (lookup_field, lookup_fnfields): Use scratch_tree_cons. * lang-options.h: Remove documentation for -fhandle-exceptions, -fmemoize-lookups and -fsave-memoized. * cp-tree.h: Lose mi_matrix and memoize support. * decl2.c: Ignore -fmemoize-lookups and -fsave-memoized. * class.c: Lose struct class_level. (pushclass, popclass): Lose memoize support. * init.c (build_offset_ref): Likewise. Never change BINFO_INHERITANCE_CHAIN. * init.c (emit_base_init): Change modification of BINFO_INHERITANCE_CHAIN to an assert. * search.c (get_base_distance_recursive): Likewise. (get_base_distance): Likewise. (lookup_member): Likewise. (convert_pointer_to_single_level): Likewise. (lookup_field): Likewise. Lose setting TREE_VIA_* on TREE_LISTs. (lookup_fnfields): Likewise. * tree.c (propagate_binfo_offsets): Don't call unshare_base_binfos. (unshare_base_binfos): Don't call propagate_binfo_offsets. (layout_basetypes): Call propagate_binfo_offsets instead of unshare_base_binfos. * decl.c (xref_basetypes): Call unshare_base_binfos. * pt.c (instantiate_class_template): Likewise. * tree.c (reverse_path): Remove 'copy' parm; always make a temporary copy. * class.c (build_vbase_path): Just call it. * search.c (compute_access): Likewise. Don't re-reverse. 1998-08-27 Mark Mitchell * class.c (build_vbase_path): Use reverse_path. (finish_base_struct): Move warnings for inaccessible bases to layout_basetypes. (modify_one_vtable): Remove check of TREE_USED (binfo). (fixup_vtable_deltas1): Likewise. * cp-tree.h (BINFO_INHERITANCE_CHAIN): Document here. (xref_tag): Remove binfos parameter. (make_binfo): Remove chain parameter. (reverse_path): Add copy parameter. * decl.c (init_decl_processing): Change calls to xref_tag. (xref_tag): Remove binfos parameter. (xref_basetypes): Change calls to make_binfo. * decl2.c (grok_x_components): Change calls to xref_tag. (handle_class_head): Likewise. * friend.c (do_friend): Likewise. * lex.c (make_lang_type): Change calls to make_binfo. * parse.y (structsp): Change calls to xref_tag. (named_complex_class_head_sans_basetype): Likewise. (named_class_head): Likewise. * rtti.c (init_rtti_processing): Likewise. * search.c (compute_access): Change calls to reverse_path. (dfs_get_vbase_types): Change calls to make_binfo. (get_vbase_types): Remove dead code. * tree.c (unshare_base_binfos): Change calls to make_binfo. (layout_basetypes): Warn here about inaccessible bases. (make_binfo): Remove chain parameter. (reverse_path): Add copy parameter. 1998-08-27 Jason Merrill * class.c: #if 0 complete_type_p. * init.c (build_java_class_ref, build_new_1): Remove unused locals. * method.c (process_overload_item): Likewise. * typeck.c (comp_target_types): Likewise. Stop sharing binfos for indirect virtual bases. * tree.c (propagate_binfo_offsets): Unshare vbases, too. (layout_basetypes): Likewise. (unshare_base_binfos): Copy vbases, too. * cp-tree.h (BINFO_VIA_PUBLIC, BINFO_BASEINIT_MARKED, BINFO_VBASE_INIT_MARKED): Remove obsolete macros. (BINFO_PUSHDECLS_MARKED, SET_BINFO_PUSHDECLS_MARKED, CLEAR_BINFO_PUSHDECLS_MARKED): New macros. * search.c (lookup_field, lookup_fnfields, lookup_member): Remove reference to BINFO_VIA_PUBLIC. (marked_pushdecls_p, unmarked_pushdecls_p): New fns. (push_class_decls): Use them. (dfs_pushdecls): Use SET_BINFO_PUSHDECLS_MARKED. (dfs_compress_decls): Use CLEAR_BINFO_PUSHDECLS_MARKED. 1998-08-27 Mark Mitchell * decl.c (build_enumerator): Set DECL_CONTEXT for the CONST_DECLs. 1998-08-26 Mark Mitchell * cp-tree.h (finish_enum): Change prototype. * decl.c (finish_enum): Use TYPE_VALUES, rather than taking a VALUES parameter. Don't try to compute mins/maxs if processing_template_decl. * parse.y (structsp): Use new calling sequence for finish_enum. * pt.c (tsubst_enum): Likewise. Take the new type as input. (lookup_template_class): Remove unused variables. Tweak. Register enums on instantiation list before substituting enumeration constants. (tsubst_decl): Remove unused variables. (regenerate_decl_from_template): Likewise. * decl.c (duplicate_decls): Don't obliterate the DECL_TEMPLATE_INFO for a template if we're not replacing it with anything. * lex.c (do_identifier): Fix typo in comment. Wed Aug 26 10:54:51 1998 Kaveh R. Ghazi * errfn.c: Remove stdarg.h/varargs.h. * tree.c: Likewise. 1998-08-25 Brendan Kehoe * pt.c (tsubst_copy): Only do typename overloading on an IDENTIFIER_NODE that happens to look like a typename if it actually has a type for us to use. 1998-08-25 Jason Merrill * typeck.c (comp_cv_target_types): Split out... (comp_target_types): From here. Don't allow cv-qual changes under a pointer if nptrs == 0. Fix OFFSET_TYPE handling. (build_ptrmemfunc): Pass 1 to nptrs. * cvt.c (perform_qualification_conversions): Use comp_ptr_ttypes. 1998-08-25 Mark Mitchell * search.c (dependent_base_p): Don't compare a binfo to current_class_type; use the TREE_TYPE of the binfo instead. * cp-tree.h (CLASS_TYPE_P): Revise definition. 1998-08-25 Jason Merrill * decl.c (duplicate_decls): Don't complain about different exceptions from an internal decl even if pedantic. * typeck.c (convert_for_assignment): Converting from pm of vbase to derived is an error, not a sorry. * call.c (build_over_call): Use convert_pointer_to_real for 'this'. * class.c (fixed_type_or_null): Rename from resolves_to_fixed_type_p. Return the dynamic type of the expression, if fixed, or null. (resolves_to_fixed_type_p): Use it. Return 0 if the dynamic type does not match the static type. (build_vbase_path): Rename 'alias_this' to 'nonnull'. Use resolves_to_fixed_type_p again. 1998-08-24 Mark Mitchell * pt.c (tsubst_decl): Move special case code for dealing with tricky friend templates here from ... (regenerate_decl_from_template): Here. 1998-08-24 Jason Merrill * decl.c (start_decl): Remove redundant linkage check. 1998-08-24 Gavin Romig-Koch * typeck.c (c_expand_return): Handle the case that valtype is wider than the functions return type. 1998-08-24 Mark Mitchell * cp-tree.h (CLASS_TYPE_P): New macro. * decl.c (grokdeclarator): Use it instead of IS_AGGR_TYPE. * pt.c (process_template_parm): Undo previous change. 1998-08-24 Benjamin Kosnik * cp-tree.h: Declare. * pt.c (decl_template_parm_p): New function. * decl.c (pushdecl): Check decls for redeclaring template parms. (xref_tag): Make redeclaration an error, print decl. * decl2.c (grokfield): Check field_decls for redeclaration as well. 1998-08-24 Jason Merrill * parse.y (primary): Fix up the type of string constants. 1998-08-24 Mark Mitchell * typeck.c (convert_for_initialization): Move check for odd uses of NULL to avoid duplicate warnings. 1998-08-24 Jason Merrill * tree.c (lvalue_type): Fix for arrays. * typeck.c (string_conv_p): New fn. (convert_for_assignment): Use it. (build_unary_op): Use lvalue_type. * call.c (standard_conversion, convert_like): Use string_conv_p. (add_function_candidate): Use lvalue_type. * cvt.c (convert_to_reference): Likewise. * decl2.c (lang_decode_option): Ignore -traditional. * decl.c (init_decl_processing): flag_writable_strings inhibits flag_const_strings. 1998-08-24 Andrew MacLeod * lang-options.h (lang_options): Add fconst-strings to the list of valid options. * decl2.c (lang_f_options, lang_decode_option): Likewise. 1998-08-24 Nathan Sidwell * lex.c (real_yylex): Don't warn about long long constants if we're allowing long long. 1998-08-24 Martin von Löwis * decl.c (pushdecl): Use IDENTIFIER_NAMESPACE_VALUE instead of accessing bindings directly. * search.c (my_tree_cons): Reimplement. * lang-specs.h: Remove __HONOR_STD. * inc/exception, inc/new, inc/new.h, inc/typeinfo: Likewise. 1998-08-23 Mark Mitchell * decl.c (grokdeclarator): Complain about in-class initialization of aggregates and/or references. * pt.c (process_template_parm): Clear IS_AGGR_TYPE for TEMPLATE_TYPE_PARMs. * decl2.c (grok_array_decl): Add comment. (mark_used): Don't instantiate an explicit instantiation. * friend.c (make_friend_class): Remove bogus comment. Fix check for partial specializations. * pt.c (check_explicit_specialization): Don't SET_DECL_EXPLICIT_INSTANTIATION here. (mark_decl_instantiated): Or here. (do_decl_instantiation): Do it here, instead. Add checks for duplicate explicit instantiations, etc. Tidy. (do_type_instantiation): Likewise. (instantiate_decl): Improve comments. Complain about explicit instantiations where no definition is available. * cp-tree.h (ansi_null_node): Remove. * call.c (build_over_call): Warn about converting NULL to an arithmetic type. * cvt.c (build_expr_type_conversion): Likewise. Use null_ptr_cst_p instead of expanding it inline. * decl.c (ansi_null_node): Remove. (init_decl_processing): Make null_node always have integral type. * except.c (build_throw): Warn about converting NULL to an arithmetic type. * lex.c (init_parse): Remove handling of ansi_null_node. * pt.c (type_unification_real): Don't convert NULL to void* type. * typeck.c (build_binary_op_nodefault): Fix NULL warnings. (convert_for_assignment): Warn about converting NULL to an arithmetic type. (convert_for_initialization): Likewise. 1998-08-20 Jason Merrill * tree.c (search_tree, no_linkage_helper, no_linkage_check): New fn. * pt.c (coerce_template_parms): Use no_linkage_check. * decl.c (grokvardecl): Likewise. (grokfndecl): Likewise. Members of anonymous types have no linkage. * method.c (process_overload_item): Remove useless code. 1998-08-20 Per Bothner Handle new'ing of Java classes. * init.c (build_class_classref): New function. (build_new_1): If type is TYPE_FOR_JAVA: Call _Jv_AllocObject; constructor does not return this; don't need to exception-protect. * pt.c (lookup_template_class): Copy TYPE_FOR_JAVA flag. * decl2.c (acceptable_java_type): Handle template-derived types. 1998-08-20 Per Bothner * decl2.c (import_export_vtable): Suppress vtables for Java classes. 1998-08-20 Mark Mitchell * decl.c (duplicate_decls): Always merge the old and new patterns for templates, regardless of whether or not the new one has DECL_INITIAL. Don't throw away specializations. Merge DECL_SAVED_TREE. * pt.c (tsubst_decl): Use the right pattern when calculating the complete args for a new template instance. (do_decl_instantiation): Fix typo in comment. (regenerate_decl_from_template): Deal with tricky friend template case. (instantiate_decl): Likewise. Thu Aug 20 09:09:45 1998 Jeffrey A Law (law@cygnus.com) * init.c (build_builtin_delete_call): Add missing assemble_external call. 1998-08-20 Jason Merrill * parse.y (notype_unqualified_id): Also accept ~A. 1998-08-19 Mark Mitchell * typeck.c (build_binary_op_nodefault): Warn on use of NULL in arithmetic. * except.c (build_throw): Warn when NULL is thrown, even with -ansi. Use ansi_null_node, rather than integer_zero_node, in the thrown expression. * cp-tree.h (ansi_null_node): New variable. * decl.c (ansi_null_node): New variable. (init_decl_processing): Initialize its type. * lex.c (init_parse): Initialize its value. Use ansi_null_node for null_node in non-ANSI mode. * typeck.c (build_binary_op_nodefault): Use ansi_null_node in place of null_node to avoid spurious errors. 1998-08-17 Mark Mitchell * cp-tree.h (enter_scope_of): New function. * parse.y (complex_direct_notype_declarator): Use it. * semantics.c (enter_scope_of): New function. 1998-08-17 Jason Merrill * decl.c (grokparms): No, here. * decl.c (grokdeclarator): Catch parm with pointer to array of unknown bound here... * method.c (process_overload_item): ...not here. * gxxint.texi: Remove obsolete documentation of overloading code. * decl.c (finish_enum): Also set TYPE_SIZE_UNIT. * class.c (finish_struct_bits): Likewise. * tree.c (lvalue_type): Fix for arrays. * typeck.c (build_unary_op): Use lvalue_type. * call.c (add_function_candidate): Likewise. * cvt.c (convert_to_reference): Likewise. * decl2.c (lang_decode_option): Ignore -traditional. * init.c (build_offset_ref): Don't mess with error_mark_node. * lex.c (do_scoped_id): Use cp_error. * rtti.c (get_tinfo_fn): Don't mess with the context for now. 1998-08-17 Benjamin Kosnik * decl.c (grokdeclarator): Allow anonymous types to be cv-qualified. Mon Aug 17 10:40:18 1998 Jeffrey A Law (law@cygnus.com) * cp-tree.h (set_identifier_local_value): Provide prototype. * decl2.c (do_namespace_alias): Remove unused variables `binding' and `old'. Fri Aug 14 16:42:27 1998 Nick Clifton * Makefile.in: Rename BBISON to BISON so that it can be properly inherited from the parent makefile. 1998-08-13 Jason Merrill * lang-options.h: Add -finit-priority. * decl2.c: Likewise. Check flag_init_priority instead of USE_INIT_PRIORITY. * decl2.c (setup_initp): New fn. (start_objects, finish_objects, do_ctors): Handle init_priority. (do_dtors, finish_file): Likewise. 1998-08-13 Jason Merrill * pt.c (tsubst_copy): Hush warning. * rtti.c (get_tinfo_fn): Also set DECL_IGNORED_P. 1998-08-12 Mark Mitchell * pt.c (print_template_context): Don't abort when instantiating a synthesized method. * decl.c (grokdeclarator): Issue errors on namespace qualified declarators in parameter lists or in class scope. 1998-08-09 Mark Mitchell * pt.c (check_explicit_specialization): Don't abort on bogus explicit instantiations. 1998-08-07 Mark Mitchell * typeck.c (require_complete_type): Use complete_type_or_else. (complete_type_or_else): Always return NULL_TREE on failure, as documented. * pt.c (tsubst_aggr_type): Prototype. (tsubst_decl): New function, split out from tsubst. Set input_filename and lineno as appropriate. (pop_tinst_level): Restore the file and line number saved in push_tinst_level. (instantiate_class_template): Set input_filename and lineno as appropriate. (tsubst): Move _DECL processing to tsubst_decl. Make sure the context for a TYPENAME_TYPE is complete. * decl2.c (grokbitfield): Issue errors on bitfields declared with function type. (do_dtors): As in do_ctors, pretend to be a member of the same class as a static data member while generating a call to its destructor. * cvt.c (cp_convert_to_pointer): Handle NULL pointer conversions, even in complex virtual base class hierarchies. 1998-08-06 Mark Mitchell * cp-tree.h (ENUM_TEMPLATE_INFO): New macro. (TYPE_TEMPLATE_INFO): Likewise. (SET_TYPE_TEMPLATE_INFO): Likewise. (ENUM_TI_TEMPLATE): Likewise. (ENUM_TI_ARGS): Likewise. (lookup_nested_type_by_name): Remove. * decl.c (maybe_process_template_type_declaration): Handle enums. (start_enum): Don't check for primary-template enum declarations here. (finish_enum): Clean up, document. Make sure template enum constants get the correct type. (build_enumerator): Copy initializers for template enumerations, too. (grok_enum_decls): Document. * lex.c (do_identifier): Document use of LOOKUP_EXPR a bit better. Build LOOKUP_EXPRs for local variables, even if they are TREE_PERMANENT. * pt.c (tsubst_enum): Remove field_chain parameter. (template_class_depth): Include the depth of surrounding function contexts. (push_template_decl): Check for primary-template enum declarations here. Deal with enumeration templates. (lookup_template_class): Likewise. (for_each_template_parm): Likewise. (instantiate_class_template): Don't call tsubst_enum directly, call tsubst instead, to instantiate enums. Deal with all field_chain issues here, not in tsubst_enum. (lookup_nested_type_by_name): Remove. (tsubst_aggr_type): Revise handling of enumeration types. (tsubst): Likewise. (tsubst_copy): Likewise. (tsubst_expr): Call tsubst, not tsubst_enum for TAG_DEFNs. 1998-08-04 Mark Mitchell * decl.c (pushtag): Don't mangle the name of a TYPE_DECL if it uses template parameters. * method.c (build_template_parm_names): Use the full set of template arguments for tsubst'ing. (build_overload_identifier): Pass the full set of template arguments to build_template_parm_names, not just the innermost_args. * pt.c (TMPL_ARGS_DEPTH): Define using TMPL_ARGS_HAVE_MULTIPLE_LEVELS, for clarity. (NUM_TMPL_ARGS): New macro. (add_outermost_template_args): Deal with the case where the outer args will be completely discarded. (coerce_template_parms): Use the full set of template arguments for tsubst'ing. Simplify. Add some asserts. Improve error messages. (lookup_template_class): Pass the full set of template arguments to coerce_template_parms. (tsubst): Add assertion. (do_type_instantiation): Don't instantiate member template classes. * init.c (build_offset_ref): Deal with a TEMPLATE_ID_EXPR whose name is a LOOKUP_EXPR, rather than an IDENTIFIER_NODE. 1998-08-03 Jason Merrill * method.c (set_mangled_name_for_decl): Change return type to void. * decl.c (lookup_name_real): A namespace-level decl takes priority over implicit typename. Avoid doing the same lookup twice. * search.c (dependent_base_p): New fn. (dfs_pushdecls, dfs_compress_decls): Use it. * typeck.c (get_member_function_from_ptrfunc): Don't try to handle virtual functions if the type doesn't have any. 1998-08-03 Mark Mitchell * decl2.c (grokfield): Don't mangle the name of a TYPE_DECL if it uses template parameters. 1998-08-02 Mark Mitchell * cp-tree.def (LOOKUP_EXPR): Document. Remove second argument. * cp-tree.h (DECL_TI_TEMPLATE): Improve documentation. * lex.c (do_identifier): Don't use a second argument, or a type, when building LOOKUP_EXPRs. (do_identifier): Likewise. (do_scoped_id): Likewise. * method.c (hack_identifier): Improve error message. * pt.c (lookup_template_function): Don't needlessly call copy_to_permanent or build_min. (tsubst_copy): Remove #if 0'd code. tsubst into LOOKUP_EXPRs if necessary. (do_decl_instantiation): Improve error message. * tree.c (mapcar, case LOOKUP_EXPR): Don't be sorry; make a copy. (build_min): Copy the type to the permanent obstack, too. 1998-08-01 Jason Merrill * init.c (init_init_processing): Remove BI* handling. (build_builtin_call): Remove. (build_builtin_delete_call): New fn. (build_delete): Use it. 1998-07-31 Mark Mitchell * cp-tree.h (PROCESSING_REAL_TEMPLATE_DECL_P): New macro. (maybe_check_template_type): New function. * decl.c (maybe_process_template_type_declaration): New function, split out from pushtag Call maybe_check_template_type. (pushtag): Use it. Use PROCESSING_REAL_TEMPLATE_DECL_P. (xref_tag): Use PROCESSING_REAL_TEMPLATE_DECL_P. * friend.c (do_friend): Use PROCESSING_REAL_TEMPLATE_DECL_P. * pt.c (template_class_depth_real): Generalization of ... (template_class_depth): Use it. (register_specialization): Use duplicate_decls for duplicate declarations of specializations. (maybe_check_template_type): New function. (push_template_decl_real): Fix comment. (convert_nontype_argument): Likewise. (lookup_template_class): Likewise. Avoid an infinite loop on erroneous code. (tsubst_friend_function): Fix comment. (tsubst, case FUNCTION_DECL): Deal with a DECL_TI_TEMPLATE that is an IDENTIFIER_NODE. * semantics.c (begin_function_definition): Use reset_specialization to note that template headers don't apply directly to declarations after the opening curly for a function. 1998-07-29 Jason Merrill * decl.c (push_overloaded_decl): Use current_namespace instead of DECL_CONTEXT (decl) to determine where we go. * decl.c (lookup_name_real): Fix typo. 1998-07-28 Mark Mitchell * friend.c (is_friend): Be lenient with member functions to deal with nested friends. 1998-07-28 Jason Merrill * class.c (finish_struct_1): Convert integer_zero_node to ssizetype before passing it to set_rtti_entry. * typeck2.c (initializer_constant_valid_p): Allow conversion of 0 of any size to a pointer. 1998-07-27 Mark Mitchell * cp-tree.h (TI_USES_TEMPLATE_PARMS): Remove. (build_template_decl_overload): Remove. (set_mangled_name_for_decl): New function. (innermost_args): Remove is_spec parameter. (most_specialized, most_specialized_class): Remove declarations. (lookup_template_class): Add entering_scope parameter. (maybe_process_partial_specialization): New function. (finish_template_decl): Likewise. (finish_template_type): Likewise. * class.c (finish_struct): Clean up processing of member template specializations. * decl.c (pushtag): Fix formatting. (lookup_tag): Improve handling of pseudo-global levels. (make_typename_type): Adjust call to lookup_template_class. (shadow_tag): Use maybe_process_partial_specialization. (xref_tag): Improve handling of member friends. (start_function): Call push_nested_class before push_template_decl. Don't call push_template_decl for specializations. * decl2.c (grok_x_components): Don't call xref_tag for template instantiations. Handle UNION_TYPEs like RECORD_TYPEs. (grokclassfn): Use set_mangled_name_for_decl. (arg_assoc_class): Adjust call to innermost_args. (mark_used): Don't call instantiate_decl for a TEMPLATE_DECL. * error.c (dump_function_name): Improve printing of template function names. * friend.c (is_friend): Don't compare types of decls to determine friendship, unless flag_guiding_decls. (make_friend_class): Partial specializations cannot be friends. (do_friend): Use set_mangled_name_for_decl. Call push_template_decl_real instead of push_template_decl. * method.c (build_decl_overload_real): Remove prototype. Give it external linkage. (build_overload_identififer): Adjust call to innermost_args. (build_template_decl_overload): Remove. (set_mangled_name_for_decl): New function. * parse.y (.finish_template_type): New non-terminal. (template_def): Use finish_template_decl. Use template_extdef instead of extdef. (template_extdef, template_datadef): New non-terminals, containing only those rules for things which can be templates. (datadef): Tidy. (template_type, self_template_type): Use .finish_template_type. (named_class_head): Use maybe_process_partial_specialization. * pt.c (mangle_class_name_for_template): Remove context parameter. (get_class_bindings): Remove outer_args parameter. (complete_template_args): Remove. (add_outermost_template_args): New function. (register_specialization): Return the specialization. (unregister_specialization): New function. (tsubst_template_parms): Likewise. (most_specialized, most_specialized_class): Prototype here as static. (original_template): Rename to most_general_template. (tsubst_template_parms): New function. (set_mangled_name_for_template_decl): Likewise. (TMPL_ARGS_DEPTH): New macro. (TMPL_ARGS_HAVE_MULTIPLE_LEVELS): Adjust. (TMPL_ARGS_LEVEL): New macro. (SET_TMPL_ARGS_LEVEL): Likewise. (TMPL_ARG): Likewise. (SET_TMPL_ARG): Likewise. (TMPL_ARGS_DEPTH): Likewise. (finish_member_template_decl): Use finish_template_decl. (maybe_process_partial_specialization): New function, split out from tsubst. (inline_needs_template_parms): Use TMPL_PARMS_DEPTH. (maybe_begin_member_template_processing): Use new macros. (is_member_template): Likewise. (is_member_template_class): Likewise. (add_to_template_args): Likewise. Deal with multiple levels of args. (maybe_process_partial_specialization): New function. (retrieve_specialization): Add consistency check. (determine_specialization): Return full argument list. (check_explicit_specialization): Tweak friend handling. Use full argument lists. Simplify. (current_template_args): Use new macros. (push_template_decl_real): Change ill-named mainargs to specargs. Check that a partial specialization actually specializes at least one parameter. Improve friend handling. Modify for full template arguments. (classtype_mangled_name): Don't mangle the names of specializations. (lookup_template_class): Add entering_scope parameter. Use it to avoid finding a template type when an instantiation is required. Simplify. Use full template arguments. (tsubst_friend_function): Use unregister_specialization. Use new macros. Use full template arguments. (tsubst_friend_class): Substitute, using tsubst_template_parms, into the template parameters before passing them to redeclare_class_template. (instantiate_class_template): Simplify. Use full template arguments. Adjust calls to get_class_bindings. Use SET_IDENTIFIER_TYPE_VALUE where needed. Improve friend handling. (innermost_args): Use new macros. (tsubst_aggr_type): New function, split out from tsubst. (tsubst): Use tsubst_aggr_type, tsubst_template_parms, new calling conventions for lookup_template_class. Refine handling of partial instantiations. Remove calls to complete_template_args. Simplify. Add consistency checks. Use set_mangled_name_for_decl and set_mangled_name_for_template_decl. (tsubst_copy): Use tsubst_aggr_type. (instantiate_template): Use full template arguments. (more_specialized): Improve formatting. (more_specialized_class): Adjust calls to get_class_bindings. (get_bindings_real): Don't call complete_template_args. (most_specialized): Don't overwrite input; create a new list. (most_specialized_class): Use most_general_template. (regenerate_decl_from_template): Use unregister_specialization. Use full template arguments. (instantiate_decl): Use full template arguments. (set_mangled_name_for_template_decl): New function. * semantics.c (begin_class_definition): Use maybe_process_partial_specialization. (finish_member_class_template): New function. (finish_template_decl): Likewise. (finish_template_type): Likewise. (typeck.c): Don't crash after issuing a compiler_error. * Makefile.in (CONFLICTS): Adjust; we removed a s/r conflict. 1998-07-27 Jason Merrill * typeck2.c (build_functional_cast): Handle default-initialization. * call.c (build_over_call): Pass 1 to popclass. * parse.y (direct_notype_declarator): Add precedence declaration to notype_unqualified_id case. * Makefile.in (EXPECT): Adjust. * tree.c (ovl_member): Fix for single function in OVL. 1998-07-27 Dave Brolley * c-lex.c (yylex): Fix boundary conditions in character literal and string literal loops. 1998-07-24 Jason Merrill * decl.c (lookup_name_real): OK, do return the from_obj value unless got_object depends on template parms. * parse.y (nested_name_specifier_1): Pull out the TYPE_MAIN_VARIANT. * pt.c (coerce_template_parms): Also complain about local enums. * cp-tree.h: Add prototype for set_identifier_local_value. * decl.c (set_identifier_local_value_with_scope): Make static, prototype. * search.c (covariant_return_p): Likewise. * except.c (build_terminate_handler, alloc_eh_object): Likewise. * call.c (build_method_call): Only pull out the type of a destructor if it's a template type parm. * decl.c (lookup_name_real): Never return the from_obj value. 1998-07-23 Jason Merrill * except.c (process_start_catch_block_old): Call start_decl_1 for catch parm. * decl.c (start_decl_1): Avoid duplicate error. * init.c (expand_default_init): Only perform the initialization if it will do something. 1998-07-23 H.J. Lu (hjl@gnu.org) * parse.y (base_class): Check for invalid base class. 1998-07-23 Jason Merrill * decl2.c (import_export_template): Fold in... (import_export_class): ...to here. Handle dllimport/export. * class.c (build_vtable): Pass at_eof to import_export_vtable. (prepare_fresh_vtable): Likewise. * decl2.c (import_export_class): Split out... (finish_prevtable_vardecl): From here. * class.c (finish_struct_1): Call import_export_class if at_eof. * decl.c (start_function): #if 0 mysterious code I wrote and have forgotten why. * rtti.c (get_tinfo_fn): If this is for a class type, set DECL_CONTEXT. 1998-07-22 Jason Merrill * inc/exception: Change terminate and unexpected to (). * parse.y (named_class_head_sans_basetype_defn): A named_class_head_sans_basetype followed by '{' or ':' is a defn. 1998-07-21 Jason Merrill * tree.c (canonical_type_variant): New fn to handle arrays. * cp-tree.h (CANONICAL_TYPE_VARIANT): Remove. * pt.c (unify, default case): Also fold arg. Fix array bounds case. * method.c (process_overload_item): Use build_overload_value for arrays. 1998-07-20 Dave Brolley * lex.c (mbchar.h): #include it. (GET_ENVIRONMENT): New macro. (init_parse): Set character set based on LANG environment variable. (real_yylex): Handle multibyte characters in character literals. (real_yylex): Handle multibyte characters in string literals. 1998-07-19 Jason Merrill * lex.c (do_identifier): Look for class value even if we don't have a global value. Do implicit declaration if parsing is 2. * semantics.c (finish_call_expr): Pass 2 if we're doing Koenig lookup. 1998-07-19 Mark Mitchell * decl.c (pushtag): Revert previous change. * pt.c (lookup_template_class): Don't put out debugging information for types that use template parameters. * decl.c (pushtag): Don't put out debugging information for compiler-generated typedefs. * error.c (dump_type_real): Don't crash when presented with intQI_type_node or the like. * semantics.c (finish_translation_unit): Fix spelling error in comment. 1998-07-17 Jason Merrill * decl.c (lookup_name_real): Pull out single function here. (select_decl): Not here. (unqualified_namespace_lookup): Use CP_DECL_CONTEXT. * decl.c (qualify_lookup): Tweak again. * pt.c (lookup_template_class): Don't mess with the context of the instantiation. * decl2.c (current_decl_namespace): Remove special handling for templates. * pt.c (tsubst, case FUNCTION_DECL): Fix getting complete args for a member template specialization. * tree.c (ovl_member): Use decls_match to compare functions. * decl.c (decls_match): Check the context of a function. * parse.y (primary): Use notype_unqualified_id instead of IDENTIFIER in Koenig lookup support rules. * semantics.c (finish_call_expr): Handle the new cases. * typeck.c (build_x_function_call): Handle overloaded methods. * decl.c (grokvardecl): Don't call build_static_name for extern "C". 1998-07-16 Mark Mitchell * semantics.c (finish_object_call_expr): Revert previous change. * call.c (build_new_method_call): Likewise. Instead, convert TYPE_DECLs to IDENTIFIERs here, in the presence of templates. 1998-07-16 Jason Merrill * decl.c (qualify_lookup): Handle templates. * decl2.c (do_using_directive): Don't pass ancestor. * decl.c (push_using_directive): Calculate ancestor. * decl2.c (do_nonmember_using_decl): Allow for type shadowing. * decl.c (pushdecl): Move type shadowing handling from here... (duplicate_decls): ...to here. * decl.c (set_identifier_local_value_with_scope): New fn. (pushdecl): Use it. (set_identifier_local_value, lookup_type_current_level): New fns. * decl2.c (do_local_using_decl): Handle types and binding level stuff properly. * init.c (build_offset_ref): Don't call mark_used on an OVERLOAD. * decl.c (select_decl): Extract a lone function from an OVERLOAD. (lookup_namespace_name): Likewise. * typeck.c (build_unary_op): Not here anymore. * decl2.c (do_class_using_decl): Make sure we get an identifier. * class.c (handle_using_decl): Ignore TYPE_DECLs. * decl.c (qualify_lookup): New fn. (lookup_name_real): Use it. 1998-07-16 Martin v. Loewis * decl2.c (add_using_namespace): When directly using a namespace that was indirect before, promote it. * cp-tree.h (LOOKUP_PREFER_TYPES, LOOKUP_PREFER_NAMESPACES, LOOKUP_PREFER_BOTH, LOOKUP_NAMESPACES_ONLY, LOOKUP_TYPES_ONLY, LOOKUP_QUALIFIERS_ONLY, LOOKUP_TEMPLATES_EXPECTED): New macros. * decl.c (select_decl): Replace two flag parameters by one. (unqualified_namespace_lookup): Likewise, pass flag. (lookup_flags): New function. (lookup_name_real): Compute flags, pass them. (lookup_namespace_name): Call with zero-flag. * decl2.c (ambiguous_decl): Add flag parameter, complain only according to flags. (lookup_using_namespace, qualified_lookup_using_namespace): Add flag parameter, pass them through. * lex.c (do_scoped_id): Call with zero-flag. 1998-07-16 Jason Merrill * typeck.c (convert_for_assignment): Use comptypes. 1998-07-16 Mark Mitchell * semantics.c (finish_object_call_expr): Move test for the function called being a TYPE_DECL to ... * call.c (build_new_method_call): Here. 1998-07-15 Jason Merrill * decl2.c (arg_assoc_class): Also look at template arguments, if any. (arg_assoc): Handle error_mark_node and multiple levels of TREE_LIST. * lex.c (looking_for_typename): Don't initialize. * decl2.c (ambiguous_decl): Clarify error message. * decl.c (push_using_directive): Iterate over namespaces used indirectly. 1998-07-15 Martin v. Löwis * decl2.c (add_using_namespace): Iterate over namespaces used indirectly. * decl.c (lookup_name_real): Accept namespace aliases as locals. (cat_namespace_levels): Ignore aliases. (duplicate_decls): Ignore duplicate aliases. * decl2.c (do_namespace_alias): Process block level namespace aliases. Store alias with pushdecl. Remove odr errors. * parse.y (namespace_alias): New non-terminal. (extdef): Use it. 1998-07-15 Jason Merrill * decl2.c (arg_assoc_type): Handle METHOD_TYPE like FUNCTION_TYPE. Handle TEMPLATE_TYPE_PARM. (arg_assoc): Rewrite. * pt.c (complete_template_args): Don't look at the context unless we have to. * method.c (build_decl_overload_real): Fix namespace handling. * typeck.c (build_unary_op): Extract a lone function from an OVERLOAD. * call.c (build_scoped_method_call): Handle getting a namespace for basetype in a destructor call. (check_dtor_name): Handle enums. * parse.y (using_directive): New nonterminal. (extdef, simple_stmt): Use it. 1998-07-14 Martin von Löwis * decl2.c (add_function): Move error message ... (arg_assoc_namespace): ... from here. 1998-07-14 Jason Merrill * parse.y (namespace_qualifier): Fix multiple level handling. * decl2.c (namespace_ancestor): Use CP_DECL_CONTEXT. (arg_assoc): Don't skip the first argument of a function. Tue Jul 14 20:09:22 1998 Jeffrey A Law (law@cygnus.com) * search.c (my_tree_cons): Clean up. 1998-07-14 Jason Merrill * call.c (joust): Don't warn about "confusing" conversions to the same type. 1998-07-14 Martin von Löwis * class.c (push_nested_class): Complain about namespaces. * decl.c (start_decl): Enter the object's namespace. (cp_finish_decl): Leave it. (grokdeclarator): Likewise. * decl2.c (check_decl_namespace): New function. (finish_file): Call it. * parse.y (complex_direct_notype_declarator): Set complexity of namespace-qualified ids to -1, enter the namespace. * method.c (build_template_decl_overload): Expect _DECL as first parameter. Put context temporarily into current_namespace. * pt.c (check_explicit_specialization): Change caller. (tsubst): Likewise. * init.c (build_offset_ref): Call mark_used and convert_from_reference for namespace members. Mon Jul 13 23:25:28 1998 Martin von Löwis * search.c (my_tree_cons): The bitfield is at index 2. Mon Jul 13 17:21:01 1998 Nick Clifton * lang-options.h: Format changed to work with new --help support in gcc/toplev.c 1998-07-12 Martin von Löwis * decl2.c (build_expr_from_tree): Change calls of do_identifier. Do Koenig lookup in CALL_EXPR. (arg_assoc): Handle error_mark. * lex.c (is_global): New function. (do_identifier): Expect arguments for Koenig lookup. * parse.y (primary): Add rules for calls of unqualified function calls. (do_id): Change call of do_identifier. * pt.c (finish_stmt_expr): Likewise. * semantics.c (finish_id_expr): Likewise. (finish_call_expr): Add integer parameter to indicate argument-dependent lookup. * decl.c (struct binding_level): New field using_directives. (push_using_decl): Not sorry anymore. (push_using_directive): New function. (lookup_tag): Use CP_DECL_CONTEXT to iterate. (unqualified_namespace_lookup): New function, code from ... (lookup_name_real): ... here. * decl2.c (lookup_using_namespace): Pass using list instead of initial scope. (validate_nonmember_using_decl): New function. (do_nonmember_using_decl): New function. (do_toplevel_using_decl): Use them. (do_local_using_decl): New function. (do_using_directive): Support block-level directives. * parse.y (simple_stmt): Support using declarations and directives. (namespace_qualifier, namespace_using_decl): New non-terminals. * xref.c (classname): New function. (GNU_xref_hier): Change class and base parameters to tree. * decl.c (xref_baseypes): Change caller. * friend.c (make_friend_class): Likewise. 1998-07-12 Kriang Lerdsuwanakij * typeck.c (comptypes, case TEMPLATE_TEMPLATE_PARM): Add parameter comparison. * pt.c (for_each_template_parm, case TEMPLATE_DECL): If it is a template template parameter, record its use. (for_each_template_parm, case TEMPLATE_TEMPLATE_PARM): Traverse its template arguments if exists. * pt.c (coerce_template_template_parms): New function equivalent to coerce_template_parms when IS_TMPL_PARM is true. (coerce_template_parms): Use it. Remove the IS_TMPL_PARM parameter, all callers changed. (coerce_template_parms): Access ARGLIST properly when creating a new vector. Only accept implicit TYPE_DECL as valid argument for a template template parameter when it is a base class of current_class_type. Don't display error message when COMPLAIN is false. 1998-07-12 Klaus Kaempf (kkaempf@progis.de) * repo.c (get_base_filename): Use file_name_nondirectory. (open_repo_file): Likewise. * cp-tree.h (file_name_nondirectory): Add prototype. 1998-07-12 Jason Merrill * friend.c (do_friend): Pull the identifier out of declarator. Use cp_error and friends. * decl2.c (qualified_lookup_using_namespace): Fix call to purpose_member. * decl.c (lookup_name_real): Don't call complete_type on a namespace. (grokvardecl): Use DECL_CLASS_SCOPE_P. * cvt.c (convert_pointer_to_real): Check for error_mark_node sooner. * class.c (warn_hidden): Fix for OVERLOAD. From grahams@rcp.co.uk: * cp-tree.h (DEFARG_NODE_CHECK): New macro. (DEFARG_LENGTH, DEFARG_POINTER): Use it. Sun Jul 12 01:20:57 1998 Jeffrey A Law (law@cygnus.com) * g++.1 (-traditional): Remove duplicated documentation. 1998-07-11 Mark Mitchell * method.c (flush_repeats): Add nrepeats parameter. (issue_nrepeats): Likewise. (is_back_referenceable_type): New function. Don't back-reference TEMPLATE_TYPE_PARMs as well as simple types like integers. (build_mangled_name_for_type): Likewise. (build_mangled_name_for_type_with_Gcode): Likewise. (lasttype): Remove. (nrepeats): Likewise. (Nrepeats): Likewise. (start_squangling): Don't clear the variables removed above. (end_squangling): Likewise. (flush_repeats): Tidy. Use nrepeats parameter rather than Nrepeats global. (issue_nrepeats): Likewise, but with nrepeats global. Use is_backreferenceable_type. (build_overload_nested_name): Tidy. Add comment. Use build_mangled_name_for_type. (build_underscore_int): Comment. (build_overload_scope_ref): Use build_mangled_name_for_type. (build_overload_int): Likewise. (build_template_template_parm_names): Tidy. (build_template_parm_names): Use build_mangled_name_for_type. (build_overload_identifier): Add comments. (build_mangled_name_for_type_with_Gcode): Split out from build_mangled_name. (build_mangled_name_for_type): Use it. (build_mangled_name): Rework to use build_mangled_name_for_type and to not use global nrepeats/Nrepeats. Tidy. (process_modifiers): Tidy. (check_btype): Use is_backreferenceable_type. Add comment. Rename `node' to `type'. (process_overload_item): Set numeric_output_need_bar here. Use build_mangled_name_for_type. Tidy. (build_decl_overload_real): Tidy. Don't use Nrepeats. Use build_mangled_name_for_type. * pt.c (push_template_decl_real): Don't look at DECL_TEMPLATE_INFO for TYPE_DECLs. 1998-07-08 Vladimir N. Makarov * cp-tree.h (warn_long_long): Define. * decl.c (grokdeclarator): Add flag `warn_long_long' as guard for warning "ANSI C++ does not support `long long'". * decl2.c (warn_long_long): Define. (lang_decode_option): Parse -Wlong-long, -Wno-long-long options. 1998-07-07 Jason Merrill * decl.c (xref_tag): Handle attributes between 'class' and name. * parse.y (aggr): Likewise. * semantics.c (finish_class_definition): Likewise. * Makefile.in (EXPECTED): Adjust. * cp-tree.h: Declare flag_optional_diags and warn_multichar. * decl2.c: Define them. (lang_decode_option): Handle them. * lang-options.h: Add -foptional-diags. * class.c (finish_struct): Don't complain about multiple meanings of name if -fno-optional-diags. * decl.c (pushdecl_class_level): Likewise. * lex.c (real_yylex): Check warn_multichar. 1998-07-06 Jason Merrill * decl.c (lookup_tag): Use CP_DECL_CONTEXT. * tree.c (make_binfo): Fix length. 1998-06-30 Benjamin Kosnik * decl2.c (lang_decode_option): Remove warn_template_debugging. * lang-options.h: Likewise. Mon Jun 29 20:17:40 1998 Kaveh R. Ghazi * except.c (build_eh_type_type_ref): Remove unused variable `susp'. (process_start_catch_block): Likewise for variables `false_label_rtx', `call_rtx' and `return_value_rtx'. 1998-06-29 Brendan Kehoe * tree.c (build_srcloc): Make sure we allocate this node on the permanent obstack. Sat Jun 27 23:34:18 1998 Fred Fish * g++spec.c (NEED_MATH_LIBRARY): Define to 1 if not already defined. (lang_specific_driver): Initialize need_math with NEED_MATH_LIBRARY. (lang_specific_driver): Only add -lm automatically if need_math is nonzero. Sat Jun 27 12:22:56 1998 Jeffrey A Law (law@cygnus.com) * Make-lang.in (g++): Depend on mkstemp.o. Link in mkstemp.o Sat Jun 27 07:36:09 1998 Kaveh R. Ghazi * Makefile.in (EXPR_H): New dependency variable. (decl2.o): Depend on $(EXPR_H). (typeck.o): Likewise. (init.o): Likewise. (expr.o): Likewise. 1998-06-25 Benjamin Kosnik * decl.c (start_enum): Put local enums on permanent_obstack. 1998-06-25 Mark Mitchell * cp-tree.h (c_get_alias_set): Declare. * decl.c (init_decl_processing): Set lang_get_alias_set. 1998-06-25 Andrew MacLeod * cp-tree.h (mark_all_runtime_matches): Add function prototype. * except.c (mark_all_runtime_matches): Set TREE_SYMBOL_REFERENCED flag for all function decls which are in the exception table. * exception.cc (__cplus_type_matcher): Check for CATCH_ALL_TYPE match. * decl2.c (finish_file): Call mark_all_runtime_matches to make sure code is emitted for any referenced rtti function. 1998-06-25 Dave Brolley * lang-specs.h: Use new | syntax to eliminate string concatenation. 1998-06-25 Jason Merrill * cp-tree.h (CP_DECL_CONTEXT): New macro. * decl2.c (is_namespace_ancestor, lookup_using_namespace): Use it. * method.c (build_overload_nested_name): Likewise. * sig.c (build_signature_pointer_or_reference_type): Don't set DECL_CONTEXT. 1998-06-24 Martin v. Löwis Set DECL_CONTEXT for globals to NULL_TREE instead of global_namespace. * cp-tree.h (FROB_CONTEXT): New macro. (DECL_MAIN_P): ::main should have a DECL_CONTEXT of NULL_TREE. * decl.c (namespace_binding): Replace NULL_TREE with global_namespace. (set_namespace_binding, pop_namespace, lookup_name_real): Likewise. * decl2.c (is_namespace_ancestor, lookup_using_namespace): Likewise. * decl.c (pushtag): Use FROB_CONTEXT. (pushdecl, make_typename_type, define_function, grokdeclarator): Likewise. * decl2.c (set_decl_namespace, do_namespace_alias): Likewise. * pt.c (push_template_decl_real, lookup_template_class, tsubst): Likewise. * decl2.c (decl_namespace): Return global_namespace if no context. * method.c (build_overload_nested_name): Expect null as context. * pt.c (mangle_class_name_for_template): Do nothing for null contexts. (lookup_template_class): Allow for null id_context. 1998-06-25 Richard Henderson * method.c (emit_thunk): Set current_function_is_thunk for the ASM_OUTPUT_MI_THUNK case as well. 1998-06-23 Andrew MacLeod * exception.cc (__cplus_type_matcher): Get a match_info pointer instead of an exception table entry as a parameter. 1998-06-23 Andrew MacLeod * parse.y (function_try_block): Don't call start_catch_handler. * except.c (call_eh_info): Remove coerced field from declaration. (build_eh_type_type_ref): New function to create an address of a rtti function for the new style exception tables. (expand_start_catch_block): Split function, this contains the common part. (process_start_catch_block_old): New function to perform the rest of expand_start_catch_block under old style exceptions. (process_start_catch_block_old): New function to perform the rest of expand_start_catch_block under new style exceptions. (expand_end_catch_block): Only pop the false label off the stack under the old style of exceptions. * semantics.c (finish_try_block): Don't call start_catch_handler. * exception.cc (struct cp_eh_info): Add original_value field. (__cplus_type_matcher): Perform type matching on the original exception value, and if we have a match, set the current value. (__cp_push_exception): Set the original exception value. 1998-06-23 Jason Merrill * call.c (joust): Fix confusing conversion warning. * call.c (build_op_delete_call): Add placement parm. Check LOOKUP_SPECULATIVELY. * cp-tree.h, decl2.c, init.c: Adjust. * decl.c (finish_function): Use it. * pt.c (tsubst): Diagnose creating void fields or variables. Mon Jun 22 08:50:26 1998 Kaveh R. Ghazi * call.c (build_scoped_method_call): Remove unused variable `tmp'. * cp-tree.h (check_dtor_name): Add prototype. * init.c (expand_member_init): Remove unused variables `ptr_type_node', `parm' and `rval'. * ptree.c (print_lang_type): Use HOST_WIDE_INT_PRINT_DEC specifier in call to fprintf. (lang_print_xnode): Likewise. * typeck2.c (enum_name_string): Cast argument to sprintf to long and use %ld specifier. * xref.c (GNU_xref_end_scope): Use HOST_WIDE_INT_PRINT_DEC specifier in call to fprintf. (GNU_xref_member): Cast argument to sprintf to int. Fri Jun 19 23:22:42 1998 Bruno Haible * typeck2.c (pop_init_level): Warn about implicit zero initialization of struct members. Thu Jun 18 09:32:32 1998 Kaveh R. Ghazi * cp-tree.h: Prototype function `check_java_method'. 1998-06-17 Jason Merrill * class.c (finish_struct): Make conflicting use of id a pedwarn. * decl.c (pushdecl_class_level): Likewise. 1998-06-17 Mark Mitchell * pt.c (convert_nontype_argument): Issue an error when presented with an integer (real) constant that cannot be simplified to an INT_CST (REAL_CST). * cp-tree.h (c_get_alias_set): Remove declaration added in 1998-06-13 change that should never have been checked in. 1998-06-17 Jason Merrill * typeck.c (build_binary_op_nodefault): Change % in format strings to %%. * decl.c (grokvardecl): Don't build_static_name for decls that aren't at namespace scope. * init.c (perform_member_init): Catch default-initialization of references. 1998-06-17 Mark Mitchell * errfn.c (cp_thing): Handle the `%%' formatting sequence. 1998-06-17 Jason Merrill * method.c (hack_identifier): Complain about getting a namespace or class template. * typeck.c (decay_conversion): Remove check for namespaces. * typeck2.c (incomplete_type_error): Likewise. * parse.y (template_arg): Add PTYPENAME expansion. 1998-06-16 Andrew MacLeod * decl.c (grokvardecl): Don't build external assembler names for TYPENAMEs in other namespaces as there is no declarator. * error.c (cp_file_of, cp_line_of): Don't extract file or line number info from DECL_CONTEXT if it is NULL. 1998-06-16 Jason Merrill * call.c (check_dtor_name): Split out. (build_scoped_method_call): Use it. (build_method_call): Use it. * init.c (build_offset_ref): Use it. * typeck.c (build_static_cast): Fix handling of pointers to members. * decl.c (finish_function): Just return nothing from a constructor. * typeck.c (c_expand_return): Complain about returning a void expression from a destructor. 1998-06-13 Mark Mitchell * class.c (alter_access): Accept a BINFO explaining how to get from the entity whose accessed is being altered to the type doing the altering. (handle_using_decl): New function containing code split out from ... (finish_struct_1): Here. * cp-tree.h (complete_type_or_else): Declare. * init.c (build_new_1, build_delete): Use it. * typeck.c (require_complete_type): Use complete_type, rather than expanding it inline. (complete_type_or_else): New function. (build_component_ref): Use it. (pointer_int_sum): Make sure the type pointed to is complete. (pointer_diff): Likewise. * pt.c (for_each_template_parm): Traverse the TYPE_CONTEXT for types. * search.c (get_matching_virtual): Note that member templates cannot override virtual functions. 1998-06-12 Brendan Kehoe * pt.c (check_explicit_specialization): If DECLARATOR turned into an error_mark_node from lookup_template_function, return the same. (determine_specialization): Also make sure TEMPLATE_ID isn't an error_mark_node, before we try to read its operands. * decl.c (grokdeclarator): If we got an error_mark_node from check_explicit_specialization, just return it right back. 1998-06-12 Mark Mitchell * class.c (instantiate_type): Don't treat template-ids that don't specify any template arguments as equivalent to ordinary identifiers. Use OFFSET_REF instead of SCOPE_REF to refer to pointer-to-members for member templates. Tidy slightly. * cp-tree.def (TEMPLATE_ID_EXPR): Revise documentation. * init.c (build_offset_ref): Handle template-ids like ordinary identifiers, for the most part, but store a TEMPLATE_ID_EXPR in the offset part of the OFFSET_REF. * typeck.c (build_unary_op): Change check for unknown types to look for OFFSET_REFs, not SCOPE_REFs. 1998-06-11 Mark Mitchell * pt.c (is_member_template_class): New function. (push_template_decl_real): Use it. 1998-06-11 Benjamin Kosnik * friend.c (do_friend): Add support for nested classes using member functions of the enclosing class as friends. 1998-06-10 Mark Mitchell * call.c (convert_default_arg): Make global, not static. (convert_arg_for_ellipsis): Split out from ... (build_over_call): Here. * cp-tree.h (convert_default_arg); Declare. (convert_arg_to_ellipsis): Likewise. (do_member_init): Remove. * init.c (do_member_init): Remove; this code is dead. (expand_member_init): Remove much of this code; it is dead. * typeck.c (convert_arguments): Use convert_default_arg and convert_arg_for_ellipsis, rather than duplicating here. * call.c (convert_like): Don't fail silently if build_user_type_conversion fails. Always return error_mark_node for failure. 1998-06-10 Jason Merrill * search.c (covariant_return_p): Complain about ambiguous base. * typeck.c (build_component_ref): Diagnose ref to nested type. 1998-06-10 Brendan Kehoe * decl.c (grokparms): Check that INIT isn't an error_mark_node before giving error about invalid type for default arg. 1998-06-10 Jason Merrill * call.c (build_method_call): Fix thinko. 1998-06-10 Dave Brolley * decl2.c (lang_decode_option): New argc/argv interface. * cp-tree.h (lang_decode_option): New argc/argv interface. * lang-specs.h (default_compilers): Only call cpp if -E, -M or -MM is specified for cpplib-enabled compilers. * lex.c (lang_init): Don't check_newline for cpplib. (init_parse): Don't initialize cpplib here. 1998-06-10 Brendan Kehoe * typeck.c (build_component_ref): Make sure FIELD has a lang_specific piece before checking DECL_MUTABLE_P. 1998-06-10 John Carr * tree.c (debug_binfo): Make printf format match arguments. * error.c (OB_PUTI): Make printf format match arguments. 1998-06-10 Jason Merrill * init.c (perform_member_init): Handle default-initialization. * except.c (build_throw): Handle throwing NULL. * typeck.c (build_x_function_call): Use resolve_offset_ref. * search.c (compute_access): Only strip an anonymous union for a FIELD_DECL. * call.c (add_builtin_candidates): Tweak. * cvt.c (build_expr_type_conversion): Restore code for conversion from class types. * decl2.c (delete_sanity): Use it. Clean up. * typeck.c (comp_ptr_ttypes_real): Fix cv-qual comparisons. 1998-06-10 Branko Cibej * typeck.c (c_expand_return): Don't warn about void expressions on return statements in functions returning void. 1998-06-09 Mark Mitchell * pt.c (fn_type_unification): Revise documentation. Tidy. (type_unification): Likewise. 1998-06-09 Andrew MacLeod * semantics.c (finish_try_block): Rename expand_start_catch, and delete expand_end_catch. * parse.y (function_try_block): Rename expand_start_catch, and delete expand_end_catch. * except.c (expand_end_eh_spec): Rename expand_start_catch, and delete expand_end_catch. 1998-06-09 Jason Merrill * search.c (lookup_member): New fn. * class.c (finish_struct_1): Use it. * decl.c (lookup_name_real): Use it. Mon Jun 8 20:45:52 1998 Kaveh R. Ghazi * Makefile.in (decl2.o): Depend on dwarf2out.h and dwarfout.h. * cp-tree.h: Add prototype for `maybe_print_template_context' and `maybe_make_one_only'. * decl.c (auto_function): Remove unused variable `decl'. * decl2.c: Include dwarf2out.h and dwarfout.h. * lex.c: Remove redundant declarations of `set_float_handler' and `asm_out_file'. 1998-06-08 Andrew MacLeod * except.c (init_exception_processing): Remove NEW_EH_MODEL compile time flag. Call __cp_eh_info instead of __cp_exception_info. * exception.cc (struct cp_eh_info): Remove NEW_EH_MODEL flag. (__cp_exception_info): Return offset into cp_eh_info structure to match what use to be the start of this structure. (__cp_eh_info): New function to return a pointer to cp_eh_info struct. (__cplus_type_matcher, __cp_push_exception): Remove NEW_EH_MODEL compile time flag. (__uncatch_exception, __check_eh_spec, std::uncaught_exception): Call __cp_eh_info instead of __cp_exception_info. 1998-06-08 Jason Merrill * decl.c (cp_finish_decl): Disable inlining of extern inlines with static variables. 1998-06-08 Mark Mitchell * init.c (build_offset_ref): Correct previous change to use build, not build_min. 1998-06-07 Mark Mitchell * class.c (instantiate_type): Handle pointer-to-members where the member is a template. * init.c (build_offset_ref): Likewise. * typeck.c (build_unary_op): Likewise. 1998-06-07 Richard Henderson * lex.c (lang_init_options): New function. (lang_init): Remove flag_exceptions == 2 hack. 1998-06-05 Jason Merrill * search.c (envelope_add_decl): Tweak for implicit typename. * call.c (joust): Also warn about confusing conversion op/constructor overload resolution. * spew.c (yylex): Also return the TYPE_DECL if got_object. Don't clear got_object after '~'. * call.c (build_scoped_method_call): Tweak destructor handling. (build_method_call): Likewise. * pt.c (tsubst_copy, case METHOD_CALL_EXPR): Don't mess with TYPE_MAIN_VARIANT for destructors. * semantics.c (finish_object_call_expr): Complain about calling a TYPE_DECL. 1998-06-05 Per Bothner * g++spec.c (lang_specific_pre_link, lang_specific_extra_ofiles): Define - update needed by gcc.c change. 1998-06-05 Jason Merrill * error.c (cp_printers): Use 'o' instead of '_' for the null entry. 1998-06-05 Martin v. Loewis * cp-tree.h (DECL_NAMESPACE_ALIAS, ORIGINAL_NAMESPACE): Declare. * decl.c (lookup_name_real): Add namespaces_only parameter. If set, return only NAMESPACE_DECLs. (select_decl): Likewise. (identifier_type_value): Give additional parameter. (lookup_name_nonclass): Likewise. (lookup_name): Likewise. (find_binding): Skip namespace aliases. (binding_for_name): Likewise. (push_namespace): Check for namespace aliases. (lookup_name_namespace_only): New function. (begin_only_namespace_names, end_only_namespace_names): New functions. * decl2.c (set_decl_namespace): Skip namespace aliases. (do_using_directive): Likewise. (do_namespace_alias): Produce namespace aliases, fix alias redeclaration. * error.c (dump_decl): Support SCOPE_REF. * parse.y (extdef): Wrap lookup with namespace_only for namespace aliases and using declarations. 1998-06-04 Jason Merrill * tree.c (really_overloaded_fn): Only see through one TREE_LIST. * error.c (dump_expr): Clean up NEW_EXPR case. 1998-06-04 Martin von Löwis Suggested by Brendan Kehoe * decl2.c (do_toplevel_using_decl): When decl is a TYPE_DECL, treat it as using ::decl. * decl2.c (arg_assoc_type): Process unknown_type_node and OFFSET_TYPE. * tree.c (mapcar): Support NEW_EXPR. * error.c (dump_expr): Support NEW_EXPR. 1998-06-03 Jason Merrill * method.c (make_thunk): Use overload machinery to make name. * search.c (covariant_return_p): New fn. (get_matching_virtual): Use it. * init.c (build_new_1): Fix check for void. 1998-06-01 Per Bothner * cp-tree.h (TYPE_FOR_JAVA): New macro. * decl.c, cp-tree.h (java_byte_type_node, java_short_type_node, java_int_type_node, java_long_type_node, java_float_type_node, java_double_type_node, java_char_type_node, java_boolean_type_node): New "primitive" types, with predefined names __java_byte etc. (record_builtin_java_type): New function. (init_decl_processing): Make Java types with record_builtin_java_type. (pushtag, grokdeclarator): Set TYPE_FOR_JAVA if in extern "JAVA". (xref_baseypes): If base class was TYPE_FOR_JAVA, so is this class. (grokfndecl): Call check_java_method for Java classes. * method.c (is_java_type): Removed. Replaced with TYPE_FOR_JAVA. (process_overload_item): Match types against specific java_XX_type_node types, rather than using is_java_type. * class.c (finish_struct_1): Don't add default copy constructor or operator= if TYPE_FOR_JAVA. (pop_lang_conext): Restore strict_prototyp proper if Java. * decl2.c (acceptable_java_type, check_java_method): New functions. * pt.c (instantiate_class_template): Copy TYPE_FOR_JAVA from pattern. (tsubst): Move common statement after if statement. * typeck.c (comptypes): If strict, TYPE_FOR_JAVA must match. 1998-06-01 Jason Merrill * pt.c (for_each_template_parm): Use first_rtl_op. * tree.c (build_cplus_array_type_1): Also check index_type for template parms. 1998-05-31 Jason Merrill * pt.c (tsubst): Always copy BINFO_BASETYPES. 1998-05-29 scott snyder * tree.c (layout_basetypes): If we change TYPE_SIZE, change TYPE_SIZE_UNIT too. 1998-05-29 Mark Mitchell * decl.c (grokdeclarator): Don't complain about in-class initialization of static consts if we don't really know the type of the variable. 1998-05-29 Jason Merrill * cp-tree.h (DECL_DESTRUCTOR_P): New macro. * method.c (build_destructor_name): New fn. * decl2.c (maybe_retrofit_in_chrg): Split out... (grokclassfn): From here. Reorganize. * decl.c (grok_ctor_properties): Make sure ctors for types with vbases have the in_chrg parm. * pt.c (instantiate_class_template): Update TYPE_USES_VIRTUAL_BASECLASSES from tsubsted bases. Don't call grok_*_properties. (tsubst): Call grok_ctor_properties and maybe_retrofit_in_chrg. 1998-05-28 Mark Mitchell * pt.c (instantiate_decl): Make test for whether or not static variables should be instantiated early match its comment. 1998-05-28 Jason Merrill * decl.c (start_decl): Always pedwarn about vacuously redeclaring a member. (start_function): Call check_default_args. * decl2.c (grokfield): Don't call check_default_args. (check_default_args): Use cp_error_at. * lex.c (do_pending_defargs): Call check_default_args. 1998-05-27 Brendan Kehoe * call.c (build_method_call): Make sure get_type_value returns something before we try to use its TYPE_MAIN_VARIANT. (build_scoped_method_call): Likewise. 1998-05-27 Jason Merrill * typeck2.c (digest_init): Complain about getting a TREE_LIST to initialize an array. * search.c (expand_upcast_fixups): Don't set DECL_CONTEXT and DECL_VIRTUAL_P. * friend.c (do_friend): Clarify template warning. 1998-05-27 Mark Mitchell * decl.c (shadow_label): Don't treat decls as identifiers. (maybe_push_to_top_level): Clear shadowed_labels. * pt.c (instantiate_decl): Reset lineno and filename after calling regenerate_decl_from_template. * decl.c (grokdeclarator): Don't try to use TYPE_OBSTACK on an error_mark_node. 1998-05-27 Kevin Buhr * parse.y (base_class): Use is_aggr_type, not IS_AGGR_TYPE. 1998-05-26 Kriang Lerdsuwanakij * pt.c (process_template_parm): Accept TYPENAME_TYPE nodes. (convert_nontype_argument): Handle cases when nontype template parameters become classes after substitution. 1998-05-26 Mark Mitchell * friend.c (is_friend): Use comptypes, rather than == to compare types. Modify for new representation of template friends. (make_friend_class): Likewise. * pt.c (tsubst_friend_class): Undo 1998-05-21 change. Tweak. (instantiate_class_template): Deal with template friends. * decl.c (store_parm_decls): Remove redundant call to expand_main_function. 1998-05-26 Benjamin Kosnik * decl.c (start_decl): Check for DECL_LANG_SPECIFIC before DECL_USE_TEMPLATE. 1998-05-26 Per Bothner * language_as_string: Handle lang_java. 1998-05-26 Jason Merrill * decl.c (pushdecl): Don't copy the type_decl. 1998-05-26 Martin v. Löwis * class.c (pushclass): Always store TYPE_MAIN_VARIANT in current_class_type. * decl.c (grokdeclarator): Put typedefs on the type's obstack. * parse.y (complex_direct_notype_declarator): Use $1 to access scope of notype_qualified_id. 1998-05-26 Dave Brolley * lex.c (parse_options,yy_cur,yy_lim): Add for cpplib. (init_parse): Initialize cpplib interface. * Makefile.in (CXX_OBJS): Make sure dependencies never end with an empty continuation. 1998-05-26 Mark Mitchell * decl.c (pushtag): Avoid crashing on erroneous input. 1998-05-25 Martin v. Löwis * decl.c (push_namespace): Only produce one unique name for anonymous namespaces. (get_unique_name): Remove. 1998-05-25 Mark Mitchell * call.c (tourney): Don't do any extra comparisons. * decl2.c (build_anon_union_vars): Don't crash on empty sub-unions. * cp-tree.h (processing_template_parmlist): Declare. * decl.c (pushtag): Don't call push_template_decl when we shouldn't. * pt.c (processing_template_parmlist): New variable. (TMPL_ARGS_HAVE_MULTIPLE_LEVELS): New macro. (complete_template_args): Use it. (add_to_template_args): Likewise. (innermost_args): Likewise. (tsubst): Likewise. (begin_template_parm_list): Use processing_template_parmlist. (end_template_parm_list): Likewise. * cp-tree.h (ANON_UNION_TYPE_P): New macro. * decl.c (grokdeclarator): Use it. * decl2.c (grok_x_components): Likewise. * init.c (initializing_context): Likewise. * method.c (do_build_copy_constructor): Likewise. (do_build_assign_ref): Likewise. * search.c (compute_access): Likewise. * typeck.c (build_component_ref): Likewise. * decl.c (grokdeclarator): Don't give a cv-qualified version of an unnamed type a typedef name "for linkage purposes". * pt.c (lookup_template_class): Don't look at IDENTIFIER_CLASS_VALUE when there's no current_class_type. * method.c (build_overload_int): Handle error cases gracefully. * pt.c (instantiate_decl): Handle static member variables correctly. * pt.c (tsubst): Use the tsubst'd type when producing new TEMPLATE_PARM_INDEX nodes. 1998-05-24 Mark Mitchell * tree.c (cp_tree_equal): Handle pointers to member functions. * call.c (maybe_handle_implicit_object): Handle QUAL_CONVs. Make sure the type of the REF_BIND is a reference type. (maybe_handle_ref_bind, compare_ics): Rename reference_type to target_type for clarity. * parse.y (xcond): Move call to condition_conversion ... * semantics.c (finish_for_cond): Here. * parse.c: Regenerated. 1998-05-24 Jason Merrill * decl.c (push_namespace): Namespaces have type void. * typeck2.c (incomplete_type_error): Complain about namespace used as expression. * typeck.c (decay_conversion): Likewise. 1998-05-24 Martin von Löwis * error.c (dump_expr): Support namespaces. 1998-05-23 Jason Merrill * cp-tree.def: Add SRCLOC. * cp-tree.h: Add struct tree_srcloc and accessor macros. * tree.c (build_srcloc, build_srcloc_here): New fns. * pt.c (add_pending_template): Use build_srcloc_here. (push_tinst_level): Update last_template_error_tick before erroring. (instantiate_decl): Restore lineno and input_filename before calling add_pending_template. * decl2.c (finish_file): Set up lineno and input_filename for pending templates. 1998-05-22 Jason Merrill * decl.c (lang_print_error_function): New fn. (init_decl_processing): Set print_error_function to use it. * errfn.c (cp_thing): Don't call maybe_print_template_context here. * call.c (maybe_handle_ref_bind): Propagate ICS_USER_FLAG and ICS_BAD_FLAG. * cvt.c (ocp_convert): Don't set LOOKUP_NO_CONVERSION for copy-initialization. * class.c (build_vtable_entry): Use int_fits_type_p. (build_vtable): Pass a signed offset to build_vtable_entry. (prepare_fresh_vtable, modify_one_vtable, fixup_vtable_deltas1, set_rtti_entry): Likewise. 1998-05-22 Per Bothner * cp-tree.h: Add comments documenting which LANG_FLAGS are used. (C_TYPE_VARIABLE_SIZE, C_DECL_VARIABLE_SIZE): Removed, not used. 1998-05-22 Jason Merrill * pt.c (print_template_context): Use fprintf instead of cp_error. * pt.c (determine_specialization): Just return an error_mark_node. Also print the decl we want in error messages. If we complain, return error_mark_node. (tsubst_friend_function): Set lineno and input_filename so error messages will be useful. (instantiate_template): Just return an error_mark_node. (check_explicit_specialization): Don't mess with a returned error_mark_node. * pt.c (print_template_context): Add new argument. (maybe_print_template_context): New fn. (push_tinst_level): Increment tinst_level_tick. (pop_tinst_level): Likewise. * errfn.c (cp_thing): Call maybe_print_template_context. Use xrealloc instead of xmalloc. * typeck.c (build_unary_op, CONVERT_EXPR): Propagate TREE_CONSTANT. 1998-05-21 Jason Merrill * pt.c (tsubst_friend_class): Don't call redeclare_class_template if the template we looked up is the same as the one we already have. Thu May 21 11:54:44 1998 Dave Brolley * lex.c: (handle_sysv_pragma): FILE* parameter not used. (cpp_reader,parse_in): Add for cpplib. (check_newline): Call handle_sysv_pragma with new interface. (check_newline): Call GET_DIRECTIVE_LINE, not get_directive_line. * input.c: (yy_cur,yy_lim,yy_get_token,GETC): Add for cpplib. (sub_getch): Call GETC for cpplib. * cp-tree.h: (get_directive_line): Different prototype for cpplib. (GET_DIRECTIVE_LINE): Macro wrapper for get_directive_line. * Makefile.in (CXX_OBJS): Add @extra_cxx_objs@ for cpplib. 1998-05-21 Jason Merrill * decl2.c (maybe_make_one_only): New fn. (import_export_vtable): Use it. (import_export_decl): Likewise. * pt.c (mark_decl_instantiated): Likewise. 1998-05-21 Mark Mitchell * decl2.c (find_representative_member): Rename to ... (build_anon_union_vars): New function. (finish_anon_union): Fix stupidity of previous change. 1998-05-20 Jason Merrill * decl.c (grokfndecl): Handle definition of specialization in friend declaration. * error.c (dump_decl): Fix LOOKUP_EXPR handling. 1998-05-20 Mark Mitchell * class.c (delete_duplicate_fields_1): Use DECL_DECLARES_TYPE_P to look for type declarations. (finish_struct): Deal with templates on the CLASSTYPE_TAGS list. * cp-tree.h (DECL_DECLARES_TYPE_P): New macro. (finish_member_class_template): Declare. * decl.c (pushtag): Put member class templates on the CLASSTYPE_TAGS list, just as for ordinary member classes. (pushdecl_class_level): Use DECL_DECLARES_TYPE_P. (lookup_tag): Look for IDENTIFIER_CLASS_VALUEs, just as with IDENTIFIER_NAMESPACE_VALUEs. * parse.y (component_decl): Move code to ... * semantics.c (finish_member_class_template): New function. Don't put member class templates on the list of components for a class. * parse.c: Regenerated. * pt.c (classtype_mangled_name): Don't try DECL_CONTEXT on types. In fact, don't use DECL_CONTEXT at all here. 1998-05-20 Martin von Loewis * decl.c (record_unknown_type): New function. (init_decl_processing): Call it for the unknown and global type nodes. 1998-05-20 Mark Mitchell * decl2.c (find_representative_member): New function. (finish_anon_union): Use it. * cp-tree.h (MAIN_NAME_P): New macro. (DECL_MAIN_P): Likwise. * decl.c (pushdecl): Avoid crashing on redefinitions of `main'. (grokfndecl): Use the new macros. (grokdeclarator): Likewise. (start_function): Likewise. (store_parm_decls): Likewise. (finsh_function): Likewise. * friend.c (do_friend): Likewise. * typeck.c (build_function_call_real): Likewise. (build_unary_op): Likewise. Wed May 20 02:16:01 1998 Jason Merrill * decl2.c (start_objects, finish_objects, do_dtors, do_ctors): Split out from... (finish_file): ...here. Tue May 19 20:36:23 1998 Jason Merrill * tree.c (is_overloaded_fn): Don't abort on placeholders from push_class_decls. Tue May 19 15:16:22 1998 Brendan Kehoe * class.c (is_empty_class): Return 0 if TYPE is an error_mark_node. * error.c (dump_expr): Handle an ARROW_EXPR. Tue May 19 15:13:39 1998 Mark Mitchell * decl.c (saveable_obstack): Declare. (pushdecl): Copy TYPE_DECLs to the same obstack as the type they declare, if necessary. Tue May 19 14:50:27 1998 Mark Mitchell * call.c (compare_qual): Remove. (is_subseq): Tweak. (is_properly_derived_from): New function. (maybe_handle_ref_bind): Likewise. (maybe_handle_implicit_object): Likewise. (compare_ics): Modify substantially to bring into conformance with the standard. * cp-tree.h (TYPE_PTRMEMFUNC_OBJECT_TYPE): New macro. (comp_cv_qualification): Declare. (comp_cv_qual_signature): Likewise. * typeck.c (comp_cv_qualification): Likewise. (comp_cv_qual_signature): Likewise. Tue May 19 10:05:02 1998 Kaveh R. Ghazi * Makefile.in (parse.o): Depend on toplev.h. * class.c (typecode_p): Remove prototype and definition. * cp-tree.h (currently_open_class, is_empty_class, member_p): Add prototype. * decl.c (push_overloaded_decl_top_level): Remove prototype and definition. * errfn.c (cp_error): Cast function pointer `error' to (errorfn *) in call to `cp_thing'. (cp_warning): Likewise for function pointer `warning'. * except.c (do_function_call): Remove prototype and definition. (call_eh_info): Wrap variable `t1' in macro NEW_EH_MODEL. * method.c (is_java_type): Add prototype and make it static. * parse.y: Include toplev.h. * pt.c (type_unification): Remove unused variable `arg'. (instantiate_decl): Likewise for `save_ti'. * tree.c (propagate_binfo_offsets): Likewise for `base_binfos'. Tue May 19 02:43:25 1998 Jason Merrill * init.c (build_member_call): Handle template_ids. * parse.y (primary): Add global_scope template_id. Mon May 18 23:22:52 1998 Jason Merrill * decl2.c (get_sentry): Use end_temporary_allocation. Don't declare permanent_obstack. Mon May 18 12:28:44 1998 Mark Mitchell * parse.y (.finish_new_placement): New non-terminal. (unary_expr, new_type_id): Use it. * parse.c: Regenerated. Mon May 18 12:20:27 1998 Brendan Kehoe * pt.c (redeclare_class_template): Say where the original definition of the template-parameter's default argument appeared. Mon May 18 03:00:57 1998 Jason Merrill * call.c (build_over_call): Tweak empty class handling. * decl.c (make_typename_type): Use currently_open_class. * class.c (instantiate_type): Don't abort on TREE_NONLOCAL_FLAG. Mon May 18 01:43:01 1998 Martin v. Loewis * decl.c (lookup_name_real): Don't look at IDENTIFIER_LOCAL_VALUE for a type unless it is one. * class.c (finish_struct_1): Use OVL_CURRENT in error message. Mon May 18 01:24:08 1998 Jeffrey A Law (law@cygnus.com) * Makefile.in (program_transform_name, objdir): Define. * Makefile.in (BISON): Use bison from the build tree if it exists. (FLEX): Likewise. Sun May 17 14:52:08 1998 Martin v. Loewis * typeck.c (type_unknown_p): Return true for TREE_LIST also. * call.c (build_method_call): Use TYPE_MAIN_VARIANT on typedefs. Sun May 17 14:51:41 1998 Jason Merrill * call.c (build_scoped_method_call): Likewise. Sun May 17 13:53:48 1998 Mark Mitchell * init.c (build_new_1): Call suspend_momentary around the creation of values that must be saved for exception handling. * parse.y (.build_new_placement): New non-terminal. (unary_expr, new_placement): Use it. * parse.c: Regenerated. Sun May 17 12:32:08 1998 Jason Merrill * decl.c (duplicate_decls): Use CANONICAL_TYPE_VARIANT to compare old and new types. * pt.c (tsubst): Make sure that BINFO_TYPE of new binfos is the canonical type. * call.c (build_over_call): Don't use IS_SIGNATURE on a namespace. Fri May 15 20:28:00 1998 Jason Merrill * decl.c (start_decl): Revert problem change. * Makefile.in (CONFLICTS): Fix. Fri May 15 15:34:02 1998 Benjamin Kosnik * decl.c (duplicate_decls): Clean up, add DECL_DATA_AREA bits. Fri May 15 00:46:05 1998 Jason Merrill * class.c (finish_struct_1): Use BINFO_SIZE. * decl.c (start_decl): Use 'tem'. Thu May 14 16:30:47 1998 Andrew MacLeod * exception.cc: Include eh-common.h. (struct cp_eh_info): Add eh_info struct with NEW_EH_MODEL. (__cplus_type_matcher): First stab at new C++ runtime type matcher. (__cp_push_exception): Initialize eh_info struct as well. * except.c: Remove local structs and include eh-common.h. (init_exception_processing): Set language and version codes. (call_eh_info): Add presence of eh_info to runtime description of struct cp_eh_info. (expand_end_eh_spec): Call start_catch_block() and end_catch_block(). * semantics.c (finish_try_block): Call start_catch_block() and end_catch_block(). * parse.y (function_try_block): Call start_catch_block() and end_catch_block(). Thu May 14 12:27:34 1998 Brendan Kehoe * typeck.c (original_type): New function. (common_type): Use it to get the DECL_ORIGINAL_TYPE for T1 and T2, to see if they're actually the same. * cp-tree.h (original_type): Declare. Wed May 13 12:54:30 1998 Kaveh R. Ghazi * Makefile.in (lex.o): Depend on output.h. * call.c (add_function_candidate): Remove unused variable `cand'. (add_conv_candidate): Likewise. (build_builtin_candidate): Likewise. * cp-tree.h: Add prototype for `types_overlap_p'. * decl.c (signal_catch): Mark parameter `sig' with ATTRIBUTE_UNUSED. * decl2.c (merge_functions): Remove unused variables `tmp' and `tempn'. * error.c (expr_as_string): Mark parameter `v' with ATTRIBUTE_UNUSED. (code_as_string): Likewise. (language_as_string): Likewise. (parm_as_string): Likewise. (op_as_string): Likewise. (assop_as_string): Likewise. (cv_as_string): Likewise. * lex.c: Include output.h. * pt.c (type_unification): Cast first argument of `bzero' to a char*. * search.c (dfs_no_overlap_yet): Mark parameter `t' with ATTRIBUTE_UNUSED. * tinfo.cc (__class_type_info::dcast): Change the type of variable `i' from int to size_t. * typeck.c (language_lvalue_valid): Mark parameter `exp' with ATTRIBUTE_UNUSED. Tue May 12 21:37:49 1998 Jason Merrill * error.c (dump_simple_decl): Use DECL_CLASS_SCOPE_P and/or DECL_NAMESPACE_SCOPE_P. (lang_decl_name): Likewise. * pt.c (tsubst_friend_function, tsubst): Likewise. * decl.c (pushdecl, redeclaration_error_message, start_decl, cp_finish_decl, start_function): Likewise. * class.c (finish_struct_1): Likewise. * call.c (build_over_call): Likewise. (compare_ics): Use DERIVED_FROM_P. Tue May 12 07:24:18 1998 Mark Mitchell * cp-tree.h (CANONICAL_TYPE_VARIANT): New macro. * method.c (build_mangled_name): Use it. (build_decl_overload_real): Likewise. * error.c (dump_simple_decl): New function, broken out from ... (dump_decl): Use it. Mon May 11 11:38:07 1998 Mark Mitchell * ptree.c (lang_print_xnode): Add missing `break'. * pt.c (tsubst): Remove duplicate check for IDENTIFIER_NODE. * call.c (add_template_candidate): Adjust for changes to fn_type_unification. (add_template_candidate_real): Likewise. (add_template_conv_candidate): Likewise. (build_user_type_conversion_1): Likewise. (build_new_function_call): Likewise. (build_object_call): Likewise. (build_new_op): Likewise. (build_new_method_call): Likewise. * class.c (instantiate_type): Likewise. * cp-tree.h (unification_kind_t): New type. (fn_type_unification): Adjust prototype. (type_unificaiton): Likewise. * pt.c (UNIFY_ALLOW_NONE): New macro. (UNIFY_ALLOW_MORE_CV_QUAL): Likewise. (UNIFY_ALLOW_LESS_CV_QUAL): Likewise. (UNIFY_ALLOW_DERIVED): Likewise. (unify): Change prototype. (maybe_adjust_types_for_deduction): New function. (check_cv_quals_for_unify): Likewise. (determine_specialization): Adjust. (fn_type_unification): Likewise. (type_unification): Likewise. (type_unification_real): Likewise. Use maybe_adjust_types_for_deduction. Fix mishandling of back-unification of template functions passed as arguments. Pass appropriate combination of UNIFY_ALLOW_* to unify. (unify): Remove unused NTPARMS parameter. Use check_cv_quals_for_unify. Remove bogus code that allowed too-generous unification in order to adhere more closely to standard. (get_bindings_real): Adjust. (get_class_bindings): Likewise. * method.c (build_overload_identifier): Only use the innermost template arguments when mangling. * pt.c (tsubst_template_argument_vector): New function. (complete_template_args): Deal with the situation where the extra_args contain more than one level of arguments. (lookup_template_class): Deal with member template classes, which may have more than one level of arguments. (tsubst): Don't tsbust into the TREE_TYPE of an IDENTIFIER_NODE. Improve handling of member template classes. Use DECL_PRIMARY_TEMPLATE instead of inline expansion. Use tsubst_template_argument_vector where appropriate. (regenerate_decl_from_template): Break out from ... (instantiate_decl): Here. * lex.c (yyprint): Remove TYPENAME_ELLIPSIS. * parse.h: Regenerated. * parse.c: Really regenerated. * cp-tree.h (finish_unary_op_expr): New function. (finish_id_expr): Likewise. (begin_new_placement): Likewise. (finish_new_placement): Likewise. (finish_declarator): Likewise. (finish_translation_unit): Likewise. (finish_parmlist): Likewise. (begin_class_definition): Likewise. (finish_class_definition): Likewise. (finish_default_args): Likewise. (finish_inline_definitions): Likewise. * parse.y (GCC_ASM_KEYWORD): Remove. (TYPENAME_ELLIPSIS): Likewise. * parse.c: Regenerated. Use new functions in semantics.c in the actions for many rules. * gxx.gperf (GCC_ASM_KEYWORD): Just use ASM_KEYWORD. * hash.h: Regenerated. * semantics.c (finish_expr_stmt): Allow NULL expr. (finish_unary_op_expr): New function, containing code previously in parse.y. (finish_id_expr): Likewise. (begin_new_placement): Likewise. (finish_new_placement): Likewise. (finish_declarator): Likewise. (finish_translation_unit): Likewise. (finish_parmlist): Likewise. (begin_class_definition): Likewise. (finish_class_definition): Likewise. (finish_default_args): Likewise. (finish_inline_definitions): Likewise. Sun May 10 23:43:13 1998 Mark Mitchell * typeck.c (build_c_cast): Don't decay arrays and functions to pointer type when converting to a class type. Sun May 10 22:53:56 1998 Jason Merrill * cp-tree.h (DECL_NAMESPACE_SCOPE_P): New macro. (DECL_CLASS_SCOPE_P): Likewise. Sun May 10 22:48:22 1998 H.J. Lu (hjl@gnu.org) * class.c (finish_struct_1): Use OVL_CURRENT on TREE_VEC_ELT. * decl2.c (constructor_name_full): Likewise. Sun May 10 22:48:12 1998 Mike Stump * tree.c (mapcar): Add OVERLOAD support. * init.c (resolve_offset_ref): We must use basetype_path before we destroy it with a call to convert_pointer_to. Sat May 9 14:44:37 1998 Jason Merrill * class.c (currently_open_class): New fn. * decl.c (lookup_name_real): Use it. * search.c (lookup_field): Likewise. Fri May 8 23:32:42 1998 Martin von Loewis * cp-tree.def (OVERLOAD): New node. * cp-tree.h (BINDING_TYPE, SET_IDENTIFIER_GLOBAL_VALUE, SET_IDENTIFIER_NAMESPACE_VALUE): Define. (NAMESPACE_BINDING): Remove. (IDENTIFIER_GLOBAL_VALUE, IDENTIFIER_NAMESPACE_VALUE): Use namespace_binding. (OVL_FUNCTION, OVL_CHAIN, OVL_CURRENT, OVL_NEXT, OVL_USED): Define. (tree_overload): New struct. (IDENTIFIER_TYPE_VALUE): Use identifier_type_value. (REAL_IDENTIFIER_TYPE_VALUE): Define. (IDENTIFIER_HAS_TYPE_VALUE): Use IDENTIFIER_TYPE_VALUE. (lang_decl_flags): Remove in_namespace. (lang_decl): Remove chain. (DECL_CHAIN, DECL_NAMESPACE): Remove. (flag_honor_std): Declare extern. (identifier_type_value, pushdecl_namespace_level, push_using_decl, namespace_binding, set_namespace_binding, lookup_function_nonclass, cat_namespace_levels, set_decl_namespace, lookup_arg_dependent, binding_init, ovl_cons, scratch_ovl_cons, ovl_member, build_overload): Declare. (decl_list_length, get_namespace_id, current_namespace_id, overloaded_globals_p): Remove. (lookup_using_namespace, qualified_lookup_using_namespace): Change return type. (push_scratch_obstack): New macro. * call.c (add_function_candidate): Special-case type of OVERLOAD node. (build_user_conversions_1): Iterate using OVL_NEXT for ctors, convs, fns. (build_new_function_call): Iterate using OVL_CHAIN. Print DECL_NAME in when reporting ambiguities. (build_object_call): Iterate using OVL_NEXT for fns, convs. (build_new_op): Call lookup_function_nonclass. Iterate using OVL_NEXT. (build_op_delete_call): Change detection of members. Do not wrap TREE_LIST around fields and single global functions. (build_over_call): Don't push a class level if the context is a namespace. (build_new_method_call): Iterate using OVL_NEXT. * class.c (add_method): Chain overloaded members using build_overload. Remove copying of method. (grow_method): When iterating through the obstack, expect OVERLOAD nodes. Chain overload members. (finish_struct_methods): Chain overload members. Unpack OVERLOAD nodes in call to get_baselinks. (duplicate_tag_error): Expect OVERLOAD nodes when unchaining. (finish_struct_1): Iterate over ctor using OVL_NEXT. Handle fdecls that are OVERLOAD nodes. (validate_lhs): New function. (instantiate_type): Do not copy OVERLOAD nodes. Remove dead code. Use DECL_NAME in error messages. Split code between global and member function processing. * decl.c (global_type_node): New static variable. (in_std): New global. (struct binding_level): New field usings. (resume_binding_level): Assert that we are not in a class. (toplevel_bindings_p): Just check for namespace_p or pseudo_global. (resume_level): Remove. (find_binding): New function. (binding_for_name): Call it. (namespace_binding, set_namespace_binding): New functions. (push_namespace): Associate binding level with new namespace, resume_binding_level for existing namespace. Remove old code. Fake std by counting. (store_bindings): Use REAL_IDENTIFIER_TYPE_VALUE. (maybe_push_to_top_level): Save current namespace. (pop_from_top_level): Restore saved namespace. (pop_namespace): Call suspend_binding_level. Remove old code. (cat_namespace_levels): New function. (set_identifier_type_value_with_scope): For namespace bindings, set BINDING_TYPE, and use global_type_node. Use REAL_IDENTIFIER_TYPE_VALUE otherwise. (identifier_type_value): New function. (pushtag): If no context, use current_namespace. (duplicate_decls): Don't process DECL_CHAIN. (pushdecl): Set DECL_CONTEXT to current_namespace, if it is not already set. Never reset it to NULL_TREE. Lookup global variables in their namespace. Push overloaded templates if they are on namespace level. (pushdecl_namespace_level): New function. (pushdecl_top_level): Implement using pushdecl_namespace_level. (pushdecl_using_decl): New function. (overloaded_globals_p): Remove. (push_overloaded_decl): Create OVERLOAD nodes, and iterate through them. Use namespace_binding and set_namespace_value. (redeclaration_error_message): Complain if the declarations come from different namespaces. (lookup_tag): On namespace level, look in the BINDING_TYPE. (lookup_namespace_name): Pass tree_bindings from stack. Remove old code. (select_decl): New function. (lookup_name_real): Call it for qualified and unqualified lookup. Pass tree_bindings from the stack. If prefer_type is 1, also accept namespaces. (lookup_function_nonclass): New function. (init_decl_processing): Set the binding level of the global namespace to global_binding_level. Build a proper type list for __builtin_apply. Initialize std_node to "fake std" if flag_honor_std is set. Initialize global_type_node. Allocated bad_alloc in namespace std if flag_honor_std. (define_function): Set the DECL_CONTEXT to the current_namespace. (start_decl): A namespace is not considered as a context here. If the DECL_CONTEXT is a namespace, push the decl. (cp_finish_decl): Check for namespaces used as initializers. (grokfndecl): Add namespace parameter. Remove processing of DECL_CHAIN. (grokvardecl): Add namespace parameter. (grokdeclarator): Process SCOPEs that are namespaces. For mangling, temporarily set the DECL_CONTEXT on anonymous structs. (start_function): Check for contexts that are namespaces. Set context for declarations that have not been pushed. (store_parm_decls): Check for ::main only. (finish_function): Likewise. (start_method): Check for contexts that are namespaces. (start_method): Remove DECL_CHAIN processing. * decl2.c (flag_honor_std): Declare. (lang_decode_option): Set it if -fhonor-std or -fnew-abi is given. (decl_namespace_list): New static global. (grok_x_components): Ignore namespaces as type contexts. (check_classfn): Expect OVERLOAD nodes. (grokfield): Remove DECL_CHAIN processing. (finish_file): Call cat_namespace_levels. (merge_functions): New function. (ambiguous_decl): Rewrite. (lookup_using_namespace): Produce tree_bindings. (qualified_lookup_using_namespace): Likewise. (set_decl_namespace, decl_namespace, current_decl_namespace, push_decl_namespace, pop_decl_namespace): New functions. (arg_lookup): New struct. (add_function, arg_assoc_namespace, arg_assoc_class, arg_assoc_type, arg_assoc_args, arg_assoc, lookup_arg_dependent): New functions. (get_namespace_id, current_namespace_id): Remove. (do_toplevel_using_decl): Rewrite. (do_class_using_decl): Complain about namespace qualifiers. (do_using_directive): Sorry if not on namespace level. Complain about unknown namespaces. * error.c (dump_aggr_type): Check for namespace contexts. * except.c (init_exception_processing): Push terminate into std. * friend.c (is_friend): A namespace is not a context, here. * init.c (expand_member_init): Remove DECL_CHAIN processing. (build_offset_ref): Process OVERLOAD nodes. * lang-specs.h (__HONOR_STD): Define if -fnew-abi or -fhonor-std. * lex.c (identifier_type): Loop using OVL_CHAIN. (see_typename): Set looking_for_typename to 2. (real_yylex): Likewise. (do_identifier): Expect OVERLOAD nodes instead of TREE_LISTs. (do_scoped_id): Expect OVERLOAD nodes. Change calling convention for qualified_lookup_using_namespace. (build_lang_decl): Don't set in_namespace anymore. * method.c (typevec_size): New global. (build_overload_nested_name): Return if global_namespace. Otherwise, always expect a declaration context. (build_qualified_name): Likewise. Make sure we don't write beyond typevec_size. (build_decl_overload_real): Likewise. Allocate one extra slot for the namespace. (hack_identifier): Mark code dead. Process OVERLOAD and NAMESPACE_DECL nodes. * parse.y (program): Pop namespaces until in global namespace. (extdef): In a using-declaration, don't discard the identifier if there is no declaration. (left_curly): Ignore type contexts which are namespaces. (typename_sub2): Use IDENTIFIER_TYPE_VALUE to retrieve the type used as scope. * pt.c (template_class_depth): Expect types to be namespaces. (determine_specialization): Simplify by expecting OVERLOAD nodes. (push_template_decl): Push into namespace level. Reset ctx if it is a namespace. Set DECL_CONTEXT to current_namespace if not set already. Ignore real contexts that are namespaces. (mangle_class_name_for_template): Skip global_namespace. Mangle other namespaces as declarations. (lookup_template_function): Set type of OVERLOAD nodes to unknown. (lookup_template_class): Push into namespace of context. If the context is a namespace, set it to global_namespace. Use id_context for mangling. (for_each_template_parm): Handle OVERLOAD and NAMESPACE_DECL nodes. (tsubst_friend_function): Ignore namespace contexts. Push into namespace level. (tsubst): Handle NAMESPACE_DECL nodes. Remove DECL_CHAIN processing. (type_unification_real): Recognize OVERLOAD instead of TREE_LIST nodes. * ptree.c (print_lang_identifier): Print bindings. (lang_print_xnode): Print OVERLOAD nodes. * rtti.c (init_rtti_processing): Push type_info into std. * search.c (lookup_fnfields_here): Expect OVERLOAD nodes. (lookup_fnfields_1, get_virtuals_named_this, get_matching_virtual, dfs_debug_mark, dfs_pushdecls, dfs_compress_decls, add_conversions, lookup_fnfields_here): Likewise. Process all nodes, instead of going through TREE_CHAIN. * sig.c (build_signature_pointer_or_reference_type): Set context to global_namespace. (build_signature_table_constructor): Expect OVERLOAD nodes. * spew.c (yylex): Save old setting of looking_for_typename. * tree.c (decl_list_length): Remove. (binding_init): New function. (count_functions): Rewrite. (is_overloaded_fn): Expect OVERLOAD nodes. (really_overloaded_fn, get_first_fn, lvalue_type): Likewise. (ovl_cons, scratch_ovl_cons, build_overload, build_overload_after, ovl_member): New functions. * typeck.c (require_complete_type): Expect OVERLOAD nodes. (type_unknown_p): Likewise. (require_instantiated_type): Likewise. (build_component_ref): Declare code dead. (build_x_function_call): Create and expect OVERLOAD nodes. (build_function_call_real): Check for ::main only. (build_unary_op): Likewise. Expect OVERLOAD nodes. (convert_for_assignment): Check for TREE_LIST before accessing TREE_VALUE. * decl.c (duplicate_decls): Check for namespace bindings instead of global bindings. (pushdecl, push_overloaded_decl, lookup_tag, lookup_name_real, lookup_name_current_level, start_decl, xref_tag, finish_enum): Likewise. * init.c (build_offset_ref): Likewise. * search.c (lookup_field): Likewise. (lookup_fnfields): Likewise. (dfs_debug_mark): Likewise. * decl.c (poplevel): Use SET_IDENTIFIER_TYPE_VALUE. (poplevel_class, pop_from_top_level): Likewise. * decl2.c (finish_method): Likewise. * class.c (build_vtable): Use SET_IDENTIFIER_GLOBAL_VALUE. * decl.c (record_builtin_type): Likewise. (init_decl_processing, grokfndecl): Likewise. * lex.c (get_time_identifier, do_identifier, do_scoped_id): Likewise. (make_lang_type): Likewise. * parse.y (make_thunk): Likewise. * pt.c (tsubst): Likewise. * tree.c (debug_binfo): Likewise. * exception.cc, new.cc, new1.cc, new2.cc, tinfo.cc, tinfo.h, tinfo2.cc, inc/new.h: Add std qualifications. * inc/new: Wrap with namespace std if __HONOR_STD. * inc/typeinfo: Likewise. Fri May 8 00:43:50 1998 Jason Merrill * call.c (build_user_type_conversion_1): Handle second_conv properly for templates. Thu May 7 17:09:25 1998 Andrew MacLeod * method.c (build_decl_overload_real): Set TREE_USED flag to zero for build_type_variants nodes as well. Wed May 6 19:27:09 1998 Jason Merrill * pt.c (tsubst): Don't tsubst the type of an IDENTIFIER_NODE. Wed May 6 16:49:48 1998 Jim Wilson * Makefile.in (call.o, class.o, decl.o, decl2.o, errfn.o, error.o, except.o, expr.o, friend.o, init.o, lex.o, method.o, pt.o, repo.o, rtti.o, search.o, semantics.o, sig.o, tree.o, typeck.o, typeck2.o, xref.o): Add toplev.h dependencies. Wed May 6 16:44:58 1998 Jeffrey A Law (law@cygnus.com) * errfn.c (cp_error, cp_warning): Remove declarations for error and warning respectively. Wed May 6 14:28:18 1998 Kaveh R. Ghazi * error.c: Convert to using ctype macros defined in system.h. * method.c: Likewise. * xref.c: Likewise. * lex.c: Likewise. Also remove redundant system header stuff. Wed May 6 06:36:41 1998 Robert Lipe * call.c, class.c, decl.c, decl2.c, errfn.c, error.c, except.c, expr.c, friend.c, init.c, lex.c, method.c, pt.c, repo.c, rtti.c, search.c, semantics.c, sig.c, tree.c, typeck.c, typeck2.c, xref.c: Add include of toplev.h. Wed May 6 02:33:39 1998 Jason Merrill * tree.c (perm_manip): Also regenerate the RTL of an extern. (copy_to_permanent): Use end_temporary_allocation. Tue May 5 23:54:04 1998 Jason Merrill * init.c (expand_vec_init): The initialization of each array element is a full-expression. Tue May 5 18:24:13 1998 Andrew MacLeod * method.c (build_mangled_name): Add a call to build_type_variant to get the right type. Tue May 5 01:25:03 1998 Jason Merrill * Makefile.in: Add .SUFFIXES. * cp-tree.def: Remove NAMESPACE_DECL. Sun May 3 01:32:14 1998 Jason Merrill * call.c (build_over_call): Do evaluate arg even if it has empty class type. * decl.c (start_function): Don't push a member function. Thu Apr 30 18:59:23 1998 Jim Wilson * Makefile.in (g++FAQ.info): Put -o option before input file. Thu Apr 30 13:05:33 1998 Andrew MacLeod * gxxint.texi: Add info for squangling codes K and B. Tue Apr 28 13:22:01 1998 Mark Mitchell * semantics.c (begin_stmt_expr): Avoid duplicating the effect of the expression in templates. (finish_stmt_expr): Likewise. 1998-04-28 Brendan Kehoe * decl2.c (ambiguous_decl): Fix NAME parm to be a tree, not int. Mon Apr 27 13:58:10 1998 Mark Mitchell * decl.c (maybe_push_to_top_level): Always clear current_template_parms and processing_template_decl. (pushtag): Remove check of current_class_type and some comments, since maybe_push_to_top_level no longer creates confusion. Sun Apr 26 12:10:18 1998 Mark Mitchell * cp-tree.h (CLASSTYPE_IS_TEMPLATE): New macro. (DECL_CLASS_TEMPLATE_P): Likewise. (DECL_PRIMARY_TEMPLATE): Likewise. (PRIMARY_TEMPLATE_P): Use it. (push_template_decl_real): New function. (redeclare_class_template): Take new template parameters as input. (is_specialization_of): New function. (comp_template_args): Declare. * decl.c (pushtag): Handle friend template classes. (xref_tag): Likewise. Use new calling convention for redeclare_class_template. * decl2.c (grok_x_components): Handle friend templates. * friend.c (is_friend): Use is_specialization_of where appropriate. Deal with friend class templates. (make_friend_class): Let a class template be friends with itself. * pt.c (comp_template_args): Remove declaration. (tsubst_friend_class): New function. (push_template_decl_real): New function. (push_template_decl): Use it. (redeclare_class_template): Adjust for new calling convention. (comp_template_args): Give it external linkage. (instantiate_class_type): Use tsubst_friend_class to deal with friend templates. * typeck.c (comptypes): Use comp_template_args, rather than expanding it inline. * parse.y (component_decl): Handle a nested template type like other component type declarations. * pt.c (check_explicit_specialization): Handle overloaded constructors correctly. * pt.c (mabybe_get_template_decl_from_type_decl): New function. (lookup_template_class): Use it. Thu Apr 23 21:19:06 1998 Jason Merrill * cp-tree.def: Add WRAPPER. USER_CONV now only has two ops. * cp-tree.h: Add WRAPPER support. * call.c (add_candidate): Split out from add_*_candidate fns. (build_over_call): Take the candidate instead of function and args. Enforce access control here. Emit overload warnings here. (add_warning): New fn. (joust): Add WARN parm. If not set, call add_warning instead of printing a warning. Re-enable some warnings. (tourney): Pass it. (convert_like): Adjust. (build_new_op): Adjust. (build_new_function_call): Adjust. (build_user_type_conversion_1): Adjust. (USER_CONV_FN): Adjust. * tree.c (build_expr_wrapper, build_expr_ptr_wrapper, build_int_wrapper): New fns. Thu Apr 23 18:27:53 1998 Mark P. Mitchell * pt.c (unify): Fix typo in previous change. Thu Apr 23 09:32:58 1998 Jason Merrill * error.c (dump_type_real): Declare canonical_name. * typeck.c (comp_target_types): Fix PMFs. Wed Apr 22 13:24:48 1998 Mark Mitchell * class.c (finish_struct): Set TREE_PRIVATE and TREE_PROTECTED for the DECL_RESULTs of a member TEMPLATE_DECL, not just the TEMPLATE_DECL. * pt.c (tsubst): Decrease the template-level of TEMPLATE_TEMPLATE_PARMS. Likewise for the DECL_INITIAL of a TEMPLATE_PARM_INDEX. (template_decl_level): New function. (unify): Make sure to record unifications for template parameters, even when the parameters exactly match the arguments. Combine duplicated code for TEMPLATE_TEMPLATE_PARMs and TEMPLATE_TYPE_PARMS. Don't try to unify template parameters that aren't from the level we're currently working on. Tue Apr 21 22:00:04 1998 Mark Mitchell * errfn.c (cp_thing): Use xrealloc, not xmalloc, to copy memory. * decl2.c (check_member_template): Set DECL_IGNORED for member class templates, too. * decl2.c (grokfield): Remangle the name of a member TYPE_DECL. Tue Apr 21 18:59:11 1998 Benjamin Kosnik * decl.c (duplicate_decls): Only check DECL_FRIEND_P if function. Tue Apr 21 14:22:00 1998 Jeffrey A Law (law@cygnus.com) * cp-tree.h (intTI_type_node, unsigned_intTI_type_node): Declare. * decl.c (intTI_type_node, unsigned_intTI_type_node): Define. (init_decl_processing): Handle TI types. * typeck.c (unsigned_type, signed_type): Handle TI types. Sat Apr 18 15:25:21 1998 Jim Wilson * g++spec.c (lang_specific_driver): New argument in_added_libraries. New local added_libraries. Increment count when add library to arglist. Fri Apr 17 21:25:00 1998 Mark Mitchell * cp-tree.h (type_as_string_real): New function. * pt.c (mangle_class_name_for_template): Use it. * error.c (dump_aggr_type): Change prototype. (dump_type_prefix): Likewise. (dump_type_suffix): Likewise. (dump_type_real): Convert from dump_type. If desired, the "canonica" name of a typedef, i.e., the name of the underlying type, can be printed. (dump_type): Call dump_type_real. Fri Apr 17 14:30:45 1998 Jason Merrill * decl2.c (lang_decode_option): -fnew-abi implies -fvtable-thunks. * typeck.c (comp_target_types): Tweak pedantic case. (comp_target_parms): Tweak pedantic case. Clean up somewhat. Return -1 or 1 instead of 1 or 2. (compparms): Remove STRICT handling. (convert_for_assignment): Fix handling of pmfs. Fri Apr 17 14:04:16 1998 Mark Mitchell * typeck.c (comp_target_types): Handle references like pointers. (comp_target_parms): Note that return code from comp_target_types can be negative to indicate failure. Fri Apr 17 09:10:52 1998 Andreas Schwab * Make-lang.in (c++.all.build): Don't depend on $(DEMANGLER_PROG), which requires a working target compiler to build. Fri Apr 17 08:57:35 1998 Jeffrey A Law (law@cygnus.com) * tree.c (avoid_overlap): Add prototype. * spew.c (num_tokens): Add prototype. (nth_noken, add_token, consume_token, debug_yychar): Likewise. * search.c (dfs_check_overlap): Add prototype. (dfs_no_overlap_yet): Likewise. * pt.c (original_template): Add prototype. (inline_needs_template_parms): Likewise. (push_inline_template_parms_recursive): Likewise. (retrieve_specialization, register_specialization): Likewise. (print_candidates, reduce_template_parm_level): Likewise. (build_template_decl, mark_template_parm): Likewise. (tsubst_friend_function, get_bindings_real): Likewise. * method.c (start_squangling): Add prototype. (end_squangling, check_ktype, issue_ktype): Likewise. (build_overloaded_scope_ref, check_btype): Likewise. (build_mangled_template_parm_index): Likewise. * lex.c (init_cpp_parse): Add prototype. (handle_cp_pragma, handle_sysv_pragma): Likewise. (reduce_cmp, token_cmp): Likewise. * except.c (call_eh_info): Add prototype. (push_eh_info, get_eh_info, get_eh_value, get_eh_type): Likewise. (get_eh_caught, get_eh_handlers, do_pop_exception): Likewise. * decl2.c (is_namespace_ancestor): Add prototype. (namespace_ancestor, add_using_namespace): Likewise. (ambiguous_decl): Likewise. * decl.c (indent): Add prototype. * call.c (add_template_candidate_real): Add prototype. Fri Apr 17 01:57:12 1998 Jason Merrill * decl2.c (build_expr_from_tree): Just return a PMF. Fri Apr 17 00:45:12 1998 Mark Mitchell * typeck2.c (process_init_constructor): Don't strip cv-qualifiers when doing initializations. * pt.c (unify): Use comptypes to compare type args. Fri Apr 17 00:24:22 1998 Jason Merrill * decl.c (duplicate_decls): Fix check for when it's safe to free the new decl. * pt.c (mangle_class_name_for_template): Don't pass a typedef type to type_as_string. Thu Apr 16 17:47:30 1998 Jeffrey A Law (law@cygnus.com) * pt.c (build_template_parm_index): Add prototype. * search.c (my_tree_cons): Don't clear words outside the newly allocated node. Wed Apr 15 15:34:44 1998 Dave Brolley * lex.c (init_parse): Now returns char* containing the filename. Wed Apr 15 13:20:06 1998 John Carr Jeff Law * errfn.c: Rework to avoid problems when HOST_WIDE_INT is longer than a pointer. Sun Apr 12 22:31:19 1998 Richard Kenner * cvt.c (cp_convert_to_pointer): Use TYPE_PRECISION. Fri Apr 10 12:16:49 1998 Benjamin Kosnik * decl.c (duplicate_decls): Don't warn for redundant decls if friend: let add_friend take care of it. Thu Apr 9 02:40:48 1998 Jason Merrill * sig.c (build_signature_pointer_constructor): Don't set TREE_HAS_CONSTRUCTOR for a signature pointer. * cvt.c (ocp_convert): Don't force a temporary for internal structs. * init.c (resolve_offset_ref): Warn about implicit & on pmfs here, too. * typeck.c (build_unary_op): Only allow taking the address of a real constructor. * typeck2.c (digest_init): Simplify. (store_init_value): Don't pedwarn about using { } for pmfs. Thu Apr 9 22:16:57 1998 Per Bothner * cp-tree.h (start_decl): Update prototype. * decl.c (start_decl): Like the C version, new parameters for the attributes. Call cplus_decl_attributes here, (pushdecl): Like C version, do build_type_copy if TYPE_DECL, (grokdeclarator): Pass NULL for new start_decl arguments. * pt.c (tsubst_expr): Likewise. * parse.y: Merge cplus_decl_attribute calls into start_decl calls. * typeck.c (common_type): Check TYPE_MAIN_VARIANT. * lex.c (build_lang_decl): Add lang_name_java. * class.c (push_lang_context): Add lang_name_java. * method.c (build_mangled_name): Check for is_java_type. Thu Apr 9 22:16:57 1998 Benjamin Kosnik * decl.c (grokdeclarator): Check TYPE_MAIN_VARIANT. * call.c (build_scoped_method_call): Check for TREE_CODE for VOID_TYPE instead of type == void_type_node. (build_method_call): Likewise. * decl.c (lookup_name_real): Likewise. (grokdeclarator): Likewise. (start_decl): Likewise. (grokparms): Likewise. (start_function): Likewise. (finish_function): Likewise. (start_method): Likewise. Thu Apr 9 00:18:44 1998 Dave Brolley (brolley@cygnus.com) * lex.c (finput): New variable. (init_cpp_parse): Renamed from init_parse. (init_parse): Handle !USE_CPPLIB. Call init_cpp_parse when finished. (finish_parse): New function. * cp-tree.h (init_lex, init_parse): Remove declarations. Mon Apr 6 02:25:05 1998 Jason Merrill * call.c (build_call): Still evaluate the actual argument. * class.c (is_empty_class): Update for -fnew-abi. * decl2.c: -fnew-abi implies -fsquangle. * method.c (do_build_assign_ref): Don't do anything to copy an empty class. (do_build_copy_constructor): Likewise. * call.c (build_over_call): Likewise. Sat Apr 4 18:43:58 1998 Jason Merrill * tree.c (avoid_overlap): Return a value. Sat Apr 4 12:52:35 1998 Jeffrey A Law (law@cygnus.com) * method.c (check_btype): Add missing argument to xrealloc. (check_ktype): Likewise. Fri Apr 3 02:22:59 1998 Jason Merrill Implement empty base optimization. * class.c (finish_struct_1): Add vbase fields earlier. Set CLASSTYPE_SIZE of an empty base to 0. Types with bases can be empty. * search.c (dfs_check_overlap, dfs_no_overlap_yet): New fns. (types_overlap_p): New fn. * tree.c (avoid_overlap): New fn. (build_base_fields): Use it to avoid overlapping empty bases. * cp-tree.h, decl2.c, lang-options.h: Add -fnew-abi. * decl.c (cplus_expand_expr_stmt): Strip unused INDIRECT_REFs. Re-implement allocation of base class subobjects. * tree.c (unshare_base_binfos): New fn. (layout_basetypes): Use it. Now handles offsets of both virtual and non-virtual bases, after layout_type. (layout_vbasetypes): Remove. (build_base_fields): Generate FIELD_DECLs for each non-virtual base. (build_vbase_pointer_fields): Split out from old layout_basetypes. * class.c (finish_base_struct): Lose offset handling code. Move nonvdtor warning here. Don't mess with t_binfo anymore. (finish_struct_1): Don't mess with t_binfo anymore. Use fns above. * cp-tree.h: Adjust. Thu Apr 2 14:25:13 1998 Jason Merrill * cp-tree.h: Lose CLASSTYPE_VBASE_SIZE, some unused stuff. * decl.c, decl2.c, pt.c, ptree.c, lex.c: Likewise. * class.c (duplicate_tag_error): Likewise. (finish_struct_1): Set CLASSTYPE_SIZE, CLASSTYPE_MODE, CLASSTYPE_ALIGN. * tree.c (layout_vbasetypes): Update from layout_record, remove var_size support, use CLASSTYPE_SIZE instead of CLASSTYPE_VBASE_SIZE. (layout_basetypes): Likewise. Wed Apr 1 18:22:25 1998 Jeffrey A Law (law@cygnus.com) * class.c, Make sure system.h is included just after config.h. Delete lingering stdio and errno references too. * decl.c, errfn.c, parse.y, ptree.c search.c, xref.c: Likewise. Wed Apr 1 15:38:36 1998 Jason Merrill * friend.c (is_friend): Fix access control for local classes. * class.c (is_empty_class): New fn. * call.c (build_call): Don't pass empty class objects to a function. Wed Apr 1 14:58:35 1998 Mark Mitchell * call.c (build_over_call): Do name resolution for default arguments of function templates in the scope of the templates. Tue Mar 31 13:43:57 1998 Jeffrey A Law (law@cygnus.com) * call.c: Include system.h. Remove includes, declarations and defines provided by system.h. * class.c, cvt.c, decl.c, decl2.c, errfn.c error.c: Likewise. * except.c, expr.c friend.c, g++spec.c, init.c, input.c: Likewise. * lex.c, parse.y, pt.c, ptree.c repo.c rtti.c, search.c: Likewise. * semantics.c, sig.c, spew.c, tree.c, typeck.c: Likewise. * typeck2.c, xref.c: Likewise. * Makefile.in: Dependencies updated as appropriate. * Make-lang.in: Likewise. Mon Mar 30 12:15:00 1998 Mark Mitchell * pt.c (fn_type_unification): Allow incomplete unification without an immediate error message. Mon Mar 30 08:55:42 1998 Jason Merrill * tree.c (member_p): New fn. * decl2.c (finish_file): Only set DECL_STATIC_FUNCTION_P for initializing class members. * cp-tree.def (TEMPLATE_PARM_INDEX): Class 'x'. * ptree.c (lang_print_xnode): Handle TEMPLATE_PARM_INDEX. * call.c (build_method_call): Handle non-scoped destructors, too. * pt.c (tsubst_copy): Likewise. * pt.c (print_template_context): Split out... (push_tinst_level): ...from here. * friend.c (is_friend): Don't pass a type to decl_function_context. * typeck.c (convert_for_initialization): Always hand off conversions to class type. Sun Mar 29 20:01:59 1998 Jason Merrill * friend.c (is_friend): Local classes have the same access as the enclosing function. Sun Mar 29 00:47:32 1998 Jeffrey A Law (law@cygnus.com) * typeck.c (expand_target_expr): Delete dead function. * search.c: Put various prototypes inside #ifdef MI_MATRIX. * repo.c (save_string): Delete dead function. * method.c (thunk_printable_name): Delete dead function. * lex.c (yynextch): Delete dead function. * expr.c (tree_extract_aggr_init): #if 0 out. * except.c (do_unwind): Delete dead function. (easy_expand_asm): Likewise. * cvt.c (build_conversion_type_1): Delete dead function. * cp-tree.h (push_expression_obstack): Declare. * call.c (source_type): #if 0 out. * class.c (alter_access): Remove unused label. Add braces around empty else clause. * lex.c (yyprint): Fix argument to printf. Sat Mar 28 17:43:52 1998 Mark Mitchell * pt.c (tsubst): Clear TREE_USED for new FUNCTION_DECLs. * pt.c (instantiate_class_template): Make sure template arguments are permanent. * init.c (resolve_offset_ref): Don't go looking around in template types. * semantics.c: Add routines to handle expressions, and some declaration processing. * parse.y: Use them. (current_class_depth): Move declaration to cp-tree.h. * parse.c: Regenerated. * cp-tree.h: Use them. (current_class_depth): Declare. * pt.c (tsubst_copy): Use begin_stmt_expr and finish_stmt_expr. Fri Mar 27 20:23:18 1998 Mark Mitchell * error.c (dump_decl): Be a bit more explicit with template type arguments, when verbose. Fri Mar 27 18:16:40 1998 Jason Merrill * inc/exception: Reorder closing braces. Fri Mar 27 13:22:18 1998 Mark Mitchell * pt.c (redeclare_class_template): New function. * cp_tree.h (redeclare_class_template): Declare it. * decl.c (xref_tag): Use it. Thu Mar 26 11:16:30 1998 Jason Merrill * call.c (build_over_call): Check IS_AGGR_TYPE, not TYPE_LANG_SPECIFIC. * typeck.c (convert_arguments): Likewise. * decl.c (grokdeclarator): Remove const and volatile from type after setting constp and volatilep. * class.c (finish_struct_1): Don't warn about bool bitfield larger than one bit. Thu Mar 26 10:25:52 1998 Mark Mitchell * pt.c (convert_nontype_argument): STRIP_NOPS where appropriate. Thu Mar 26 10:24:05 1998 Mark Mitchell * call.c (build_object_call): Complain about ambiguous operator(), rather that crashing. (build_new_op): Likewise. (build_op_delete_call): Likewise. Thu Mar 26 10:23:24 1998 Mark Mitchell * cvt.c (perform_qualification_conversions): Use comp_target_types instead of comp_ptr_ttypes. Wed Mar 25 16:10:50 1998 Mark Mitchell * cp-tree.h (enforce_access): Declare. * call.c (enforce_access): Make it extern, not static. * class.c (alter_access): Use enforce_access; modify code for ISO compliance, rather than ARM rules. Wed Mar 25 12:10:45 1998 Kriang Lerdsuwanakij * cp-tree.h: Fix typo. Wed Mar 25 02:01:02 1998 Jason Merrill * expr.c (cplus_expand_expr): Only do PCC_STATIC_STRUCT_RETURN thing if (aggregate_value_p (type)). * decl2.c (constructor_name_full): Handle TYPENAME_TYPE. Tue Mar 24 16:12:01 1998 Mark Mitchell * tree.c (mapcar): When dealing with a DECL, use it's constant value, if any. * pt.c (lookup_template_class): Don't mangle the names of template classes whose arguments are unknown. * pt.c (tsubst_expr): Handle GOTO_STMT correctly. Tue Mar 24 12:21:55 1998 Benjamin Kosnik * decl.c (init_decl_processing): Set TYPE_PRECISON for bools to 1. Tue Mar 24 12:21:48 1998 Jim Wilson * decl.c (init_decl_processing): Initialize TYPE_MAX_VALUE for boolean_type_node to 1. Tue Mar 24 10:23:47 1998 Mark Mitchell * error.c (dump_expr): Remove unused variable `l'. * pt.c (for_each_template_parm): New function, created by converting uses_template_parms. (tree_fn_t): New typedef. (uses_template_parms): Use it. (mark_template_parm): New function. (push_template_decl): Check that the argument list of a partial specialization uses all the template parameters. * Make-lang.in (c++filt): Don't delete cxxmain.c after we're done with it; we might want it for debugging. * cp-tree.h (type_unification): Change interface. * class.c (finish_struct_1): Skip nested template types, just like ordinary nested types. (instantiate_type): Use new interface to type_unification. * lex.c (init_lex): Add __sz as opname for sizeof. * method.c (build_overload_scope_ref): New function. (build_overload_int): Handle complex expressions. Set numeric_output_need_bar if necessary. (build_overload_value): Handle non-PARM_DECL nodes; this routine is now used by build_overload_int. Remove some assignments to numeric_output_need_bar. Use build_overload_scope_ref. (build_qualified_name): Note that some template mangled names end with digits, and set numeric_output_need_bar appropriately. Use build_underscore_int. * pt.c (unify): Change interface. (type_unification_real): Likewise. (determine_specialization): Use new interfaces. (tsubst): Deal gracefully with situations in which the argument vector is not fully filled. (fn_type_unification): Use new interfaces. (type_unification): Likewise. Remove NOP_EXPR hack. (type_unification_real): Likewise. (unify): Likewise. Deal with unification of complex expressions. Mon Mar 23 12:24:37 1998 Jason Merrill * pt.c (complete_template_args): Initialize skip properly. * decl.c (make_typename_type): Revert. (make_implicit_typename): Remove. (lookup_name_real): Don't call it. Call lookup_field if we see a TYPE_DECL from a template base. * search.c (lookup_field): Do implicit typename stuff. Sun Mar 22 00:50:42 1998 Nick Clifton Geoff Noer * Makefile.in: Various fixes for building cygwin32 native toolchains. * Make-lang.in: Likewise. Fri Mar 20 18:07:39 1998 Kriang Lerdsuwanakij * pt.c (tsubst, TEMPLATE_TEMPLATE_PARM): Simplify. Fri Mar 20 10:42:07 1998 Jason Merrill * decl.c (make_implicit_typename): Rewrite removed code. (make_typename_type): Call it if the type we look up comes from a base that uses template parms. * pt.c (complete_template_args): Rewrite. (tsubst, FUNCTION_DECL): Use it. Fri Mar 20 08:12:43 1998 H.J. Lu (hjl@gnu.org) * semantics.c (finish_asm_stmt): Fix combine strings. Call c_expand_asm_operands () if output_operands, input_operands or clobbers is not NULL_TREE. Fri Mar 20 00:10:19 1998 Kriang Lerdsuwanakij * pt.c (complete_template_args): New function. (get_bindings): Deal with specializations of function templates with return type containing parameters from outer class templates. (tsubst, TEMPLATE_TEMPLATE_PARM): When reducing parameter level, substitute arguments and compose a new type. Thu Mar 19 19:01:48 1998 Mark Mitchell * pt.c (tsubst): Clear DECL_PENDING_INLINE_INFO for new FUNCTION_DECLs. Thu Mar 19 11:51:58 1998 Jason Merrill * decl.c (make_implicit_typename): Lose useless code. * call.c (standard_conversion): Handle A* -> const A* properly. * pt.c (get_bindings_real): Rename from get_bindings. Add check_rettype parm. (get_bindings): Pass 1. (get_bindings_overload): Pass 0. Wed Mar 19 09:08:12 1998 Mark Mitchell * pt.c (check_explicit_specialization): When reverting a static member function, also remove the `this' parameter from last_function_parms. Thu Mar 19 02:27:48 1998 Jason Merrill * pt.c (tsubst_copy, CONST_DECL): Don't bother tsubsting a function context. * decl.c (store_bindings): Use free_binding_vecs. (pop_from_top_level): Likewise. Wed Mar 18 12:41:43 1998 Jason Merrill * decl.c (make_implicit_typename): Only change the type of a TYPENAME_TYPE. Wed Mar 18 10:09:51 1998 Mark Mitchell * semantics.c: New file, containing routines to perform the semantic phase of parsing. * parse.y: Use it. * pt.c (tsubst_expr): Likewise. * cp-tree.h: Declare the various functions in semantics.c. Provide macros to access _STMT tree nodes. * cp-tree.def: Add ASM_STMT tree node. * Makefile.in, Make-lang.in: Add dependencies on and for semantics.c. Wed Mar 18 00:24:10 1998 Jason Merrill * pt.c (push_template_decl): Only check primary templates. * pt.c (check_explicit_specialization): Complain about default args in explicit specialization. * parse.y (nomods_initdcl0): Also call cp_finish_decl for a constructor_declarator. Tue Mar 17 14:44:54 1998 Mark Mitchell * typeck2.c (build_x_arrow): Don't crash when an aggregate type has no overloaded operator ->. * call.c (build_field_call): Don't crash when presented with a field that is actually a nested type. * decl.c (pushtag): Deal with friend class injection in local classes. * call.c (build_object_call): Don't crash if OBJ is a pointer-to-member-function. Tue Mar 17 11:40:26 1998 Jason Merrill * pt.c (push_template_decl): Complain about template with C linkage, anonymous template class. Mon Mar 16 12:10:39 1998 Jason Merrill * class.c (pushclass): Only use the mi_matrix stuff #ifdef MI_MATRIX. * search.c: Likewise. * lex.c (do_pending_defargs): Only call maybe_{begin,end}_member_template_processing for FUNCTION_DECLs. * parse.y (initdcl0_innards): Move maybeasm back into initdcl0 et al. Mon Mar 16 10:47:22 1998 Mark Mitchell * parse.y: Deal with CONSTRUCTORS in new_initializers. Mon Mar 16 10:54:21 1998 Mark Mitchell * pt.c (tsubst_copy): Deal with BIND_EXPR in a way that more closely mimics the behavior in parse.y. (tsubst_expr): Return the resulting BLOCK when making a tsubst'ing into a compound statement. Sun Mar 15 02:07:26 1998 Jason Merrill * cp-tree.h (TEMPLATE_PARMS_FOR_INLINE): New macro. * pt.c (inline_needs_template_parms): New fn. (original_template): New fn. (push_inline_template_parms_recursive): New fn. (maybe_begin_member_template_processing): Use them. (maybe_end_member_template_processing): Likewise. (is_member_or_friend_template): Rename to is_member_template. Member functions of local classes are never member templates. Sun Mar 15 01:14:22 1998 Kriang Lerdsuwanakij * lex.c (do_identifier): Handle TEMPLATE_DECL that was added in the class scope to catch redefinition error. * pt.c (reduce_template_parm_level): Also copy the DECL_TEMPLATE_PARMS field. Sun Mar 15 10:54:08 1998 Mark Mitchell * pt.c (tsubst): Clear TYPE_REFERENCE_TO when creating a reduced-level template type parameter. Sun Mar 15 12:26:02 1998 Manfred Hollstein * cp-tree.h (struct lang_decl_flags): Add needs_final_overrider. (DECL_NEEDS_FINAL_OVERRIDER_P): New macro. * class.c (override_one_vtable): Set DECL_NEEDS_FINAL_OVERRIDER_P. * decl.c (duplicate_decls): Propagate it. * typeck2.c (abstract_virtuals_error): Use two loops to emit abstract virtual functions and virtual functions which need a final overrider separately. Thu Mar 12 09:39:40 1998 Manfred Hollstein * lang-specs.h: Properly put brackets around array elements in initializer. * typeck.c (build_binary_op_nodefault): Correctly place parens around && and || in expression. Thu Mar 12 09:26:04 1998 Manfred Hollstein * call.c (default_parm_conversions): Remove prototype definition. (build_method_call): Remove unused variable result. * cvt.c (ocp_convert): Remove unused variable conversion. * decl2.c (ambiguous_decl): Add explicit parameter definition for name. * except.c (do_unwind): #if 0 definition of unused variables fcall and next_pc. * expr.c (extract_scalar_init): #if 0 prototype and function definition. * init.c (expand_aggr_init_1): Remove unused variable init_type. (build_new_1): Remove unused variable t. * pt.c (instantiate_class_template): Remove unused variable newtag; cast called function return value to void. (do_decl_instantiation): Remove unused variables name and fn. * tree.c (get_type_decl): Add default return to shut up compiler from complaining control reaches end of non-void function. * typeck.c (build_x_conditional_expr): Remove unused variable rval. Thu Mar 12 09:12:15 1998 Manfred Hollstein * call.c (default_parm_conversions): Remove prototype definition. (build_method_call): Remove unused variable result. (build_over_call): Add default case in enumeration switch. Thu Mar 12 08:39:13 1998 Manfred Hollstein * decl2.c (lang_decode_option): Change j's type to size_t. * tree.c (layout_vbasetypes): record_align and desired_align are of type unsigned int; const_size and nonvirtual_const_size likewise. Wed Mar 11 07:25:20 1998 Mark Mitchell * parse.y (new_initializer): Make sure all initializers are lists. Tue Mar 10 07:32:36 1998 Mark Mitchell * decl2.c (import_export_decl): Mark tinfo functions for cv-qualified versions of class types as DECL_NOT_REALLY_EXTERN. Fri Mar 6 23:27:35 1998 Jeffrey A Law (law@cygnus.com) * method.c: Fix typo. Fri Mar 6 10:06:59 1998 Kaveh R. Ghazi * method.c: Include "system.h" to get stdlib.h, stdio.h, ctype.h, string.h, etc. (issue_nrepeats): Add default case in enumeration switch. (check_btype): Likewise. (process_overload_item): Likewise. * Makefile.in (method.o): Depend on system.h. Wed Mar 4 22:26:53 1998 Andreas Schwab * lex.c (do_scoped_id): Fix parenthesizing. Wed Mar 4 12:11:53 1998 Michael Tiemann * rtti.c (get_tinfo_fn_dynamic): If this function is called an FLAG_RTTI is unset, initialize type info machinery and continue with FLAG_RTTI enabled. (get_typeid): Likewise. Wed Mar 4 11:47:55 1998 Jason Merrill * typeck.c (unary_complex_lvalue): &D::i has type B::* if i comes from B. Wed Mar 4 11:28:08 1998 Mark Mitchell * pt.c (finish_member_template_decl): Deal more gracefully with invalid declarations. Tue Mar 3 01:38:17 1998 Jason Merrill * cvt.c, decl.c, decl2.c, init.c, rtti.c, typeck.c, typeck2.c, cp-tree.h: Clean up more old overloading code, old RTTI code, and some formatting quirks. * call.c, class.c, cp-tree.h, cvt.c, decl.c, init.c, lex.c, method.c, pt.c, ptree.c, typeck.c: Remove support for -fno-ansi-overloading and overloading METHOD_CALL_EXPR. * class.h: Remove. * Makefile.in: Adjust. * pt.c (unify): Don't allow reduced cv-quals when strict. * call.c, class.c, pt.c, cp-tree.h: Remove nsubsts parm from *type_unification* and unify. Mon Mar 2 12:11:06 1998 Jason Merrill * parse.y (explicit_template_type): Remove TEMPLATE keyword. (nested_name_specifier): And add it before this use. (typename_sub0): And this use. Also add use without the keyword. (typename_sub1): Likewise. * pt.c (instantiate_class_template): Don't actually instantiate anything if our type uses template parms. Mon Mar 2 11:04:59 1998 Jim Wilson * decl.c (start_function): Don't call temporary_allocation for a nested function. Sun Mar 1 21:06:37 1998 Jason Merrill * pt.c (instantiate_class_template): Don't mess with friends if our type uses template parms. Sat Feb 28 12:06:44 1998 Jason Merrill * parse.y (nested_name_specifier): Use explicit_template_type. (typename_sub): Allow a template_type, an explicit_template_type, or an implicit template type at the end. * lex.c (yyprint): Handle a PTYPENAME being a TEMPLATE_DECL. * decl.c (make_typename_type): Handle template-id where the name is a TEMPLATE_DECL. * call.c (build_scoped_method_call): Handle member template destructor call. * pt.c (tsubst_copy, METHOD_CALL_EXPR): Don't assume a member destructor is represented by the type. * cp-tree.h (TYPENAME_TYPE_FULLNAME): New macro. * parse.y (nested_name_specifier): Add 'template' case. (explicit_template_type): New rule. (typename_sub): Use it. * decl.c (make_typename_type): Handle getting a template-id for NAME. * pt.c (tsubst): Likewise. Fri Feb 27 11:17:50 1998 Jason Merrill * pt.c (add_to_template_args): Fix thinko. (instantiate_class_template): Call it later. * pt.c (get_class_bindings): Add outer_args parm. (most_specialized_class): Likewise. (instantiate_class_template): Pass it. (more_specialized_class): Likewise. (lookup_template_class): Get context from template if none was specified. (finish_member_template_decl): Don't do anything with a partial specialization. * decl2.c (check_member_template): Use IS_AGGR_TYPE instead of AGGREGATE_TYPE_P. * class.c (finish_struct): Member class templates have already been checked for name clashes. * decl.c (pushdecl_with_scope): Handle pushing at class level. Fri Feb 27 02:25:16 1998 Jason Merrill * pt.c (tsubst, TEMPLATE_DECL): Support member class templates. (tsubst, *_PARM): Support multiple levels of template classes. (instantiate_class_template): Look up the pattern from the original template. (lookup_template_class): Handle getting a template for d1. (push_template_decl): Correct setting of 'primary'. (reduce_template_parm_level): Add 'levels' parm. (finish_member_template_decl): Support member class templates. (template_class_depth): Handle multiple levels. * parse.y (component_decl_1, fn.def2): Remove member template case. (component_decl): Add member template cases. * decl2.c (check_member_template): We now handle member template classes. * decl.c (pushtag): Handle member templates. * method.c (do_inline_function_hair): Don't touch IDENTIFIER_GLOBAL_VALUE. * init.c (build_offset_ref): If name isn't an identifier, just return it. * spew.c (yylex): Handle PTYPENAME like TYPENAME. * typeck.c (get_delta_difference): Do adjust for conversions to and from virtual base. Wed Feb 25 09:51:29 1998 Jason Merrill * typeck.c (get_delta_difference): Give hard error for conversion from virtual base. * cp-tree.h: Tweak formatting. Wed Feb 25 00:35:33 1998 Jason Merrill * decl.c (push_namespace): Handle redeclaration error. * cp-tree.h (IDENTIFIER_NAMESPACE_VALUE): New macro. (IDENTIFIER_NAMESPACE_BINDINGS): New macro. (NAMESPACE_BINDING): New macro. (IDENTIFIER_GLOBAL_VALUE): Use NAMESPACE_BINDING. * *.c: Use them. * pt.c (push_template_decl): Use innermost_args. * decl.c (get_unique_name): Tweak from earlier in the name. Tue Feb 24 22:15:04 1998 Martin von Loewis * cp-tree.def: Add CPLUS_BINDING node. * cp-tree.h (tree_binding): New struct. (BINDING_SCOPE, BINDING_VALUE): New macros. (current_namespace, global_namespace): Declare extern. (struct lang_decl_flags): New field in_namespace. (DECL_NAMESPACE_USING, DECL_NAMESPACE_USERS): New macros. (DECL_NAMESPACE, SET_DECL_NAMESPACE): New macros. (TREE_INDIRECT_USING): New macro. * decl2.c (current_namespace, global_namespace): Declare. The value is a NAMESPACE_DECL now, not a TREE_LIST. (is_namespace_ancestor, namespace_ancestor): New static functions. (add_using_namespace, ambiguous_decl): Likewise. (lookup_using_namespace): New support function for lookup_name. (qualified_lookup_using_namespace): New support function for do_scoped_id and lookup_namespace_name. (get_namespace_id): Mark as obsolete. (current_namespace_id): Likewise. (do_namespace_alias): Implement. (do_using_directive): Implement as call to add_using_namespace. * decl.c (binding_for_name): New function. (push_namespace, pop_namespace): Implement. (push_decl): Don't install a FUNCTION_DECL in the global branch. (lookup_namespace_name): Implement using qualified lookup. (lookup_name_real): For global scoping, lookup in global_namespace. For namespace scoping, lookup in given namespace. For unscoped lookup, iterate over namespace, considering using directives. (init_decl_processing): Initialize global_namespace. (grokvardecl): Build assembler name as static name for globals. (grokdeclarator): Remove old namespace mangling. (xref_tag): When installing a global binding for the tag, make sure we have an identifier. * method.c (build_overload_nested_name): Mangle namespaces. (build_qualified_name): Likewise. (build_decl_overload_real): Likewise. * lex.c (build_lang_decl): Set namespace for new declaration to current_namespace. (do_scoped_id): Find global names in global or current namespace, or using qualified namespace lookup, depending on context. * init.c (build_member_call): When scope is namespace, use build_x_function_call instead. (build_offset_ref): When scope is namespace, collapse processing to lookup_namespace_name instead. * error.c (dump_decl): Support NAMESPACE_DECL. * decl.c (pushdecl): Bind globals to current namespace. (push_overloaded_decl): Likewise. (lookup_tag): Likewise. (lookup_name_current_level): Likewise. (xref_tag): Likewise. (start_function): Likewise. * lex.c (do_identifier): Likewise. (identifier_typedecl_value): Likewise. (real_yylex): Likewise. * method.c (do_inline_function_hair): Likewise. * parse.y (unscoped): Likewise. * pt.c (check_explicit_specialization): Likewise. (lookup_template_class): Likewise. * rtti.c (call_void_fn): Likewise. * sig.c (build_sigtable): Likewise. * ptree.c (lang_print_xnode): New function. Tue Feb 24 01:40:24 1998 Jason Merrill * pt.c (instantiate_class_template): Don't instantiate if pedantic and the args use template parms. * pt.c (push_tinst_level): If the instantiation uses template parms, fail silently. * decl.c (xref_basetypes): Do call complete_type for basetypes that involve template parameters. Tue Feb 24 00:36:43 1998 Jason Merrill * typeck2.c (process_init_constructor): Fix labeled init check. Mon Feb 23 05:08:55 1998 Jason Merrill * pt.c, call.c, decl.c, method.c, cp-tree.h: Remove unused NARGS argument to tsubst and friends. * pt.c (tsubst, FUNCTION_DECL): Tidy. * typeck.c (build_x_function_call): Handle static member function templates like non-templates. Handle friend templates like normal function templates. * pt.c (tsubst, *_PARM): Don't use orig_level. (get_bindings): Don't call add_to_template_args. (instantiate_template): Likewise. (tsubst, FUNCTION_DECL): Call add_to_template_args as appropriate. * ptree.c (print_lang_type): Print index/level for template parms. Mon Feb 23 02:52:29 1998 Mark Mitchell * Make-lang.in (cc1plus): Note that cc1plus depends on cp/cp-tree.h and cp/cp-tree.def. * cp-tree.def (TEMPLATE_CONST_PARM): Remove. (TEMPLATE_PARM_INDEX): New tree code, used to indicate a position in a template parameter list. * cp-tree.h (template_parm_index): New structure, used as the tree structure for a TEMPLATE_PARM_INDEX. (TEMPLATE_PARM_IDX): New macro. (TEMPLATE_PARM_LEVEL): Likewise. (TEMPLATE_PARM_DESCENDANTS): Likewise. (TEMPLATE_PARM_ORIG_LEVEL): Likewise. (TEMPLATE_PARM_DECL): Likewise. (TEMPLATE_TYPE_PARM_INDEX): Likewise. (TEMPLATE_TYPE_ORIG_LEVEL): Likewise. (TEMPLATE_TYPE_DECL): Likewise. (TEMPLATE_CONST_IDX): Remove. (TEMPLATE_CONST_LEVEL): Likewise. (TEMPLATE_CONST_SET_INFO): Likewise. (TEMPLATE_TYPE_SET_INFO): Likewise. (TEMPLATE_TYPE_IDX): Redefine in terms of TEMPLATE_PARM_INDEX node. (TEMPLATE_TYPE_LEVEL): Likewise. * decl.c (decls_match): Call comp_template_parms, rather than expanding it inline. (duplicate_decls): If two template declarations are being merged, then their TEMPLATE_INFOs should be merged as well. (grokfndecl): Save template-id information when declaring a friend with explicit template arguments. Pass arguments to check_explicit_specialization via correct convention; at some point check_explicit_specialization changed, but these call-sites did not. (grokdeclarator): Tidy up slightly. * decl2.c (check_classfn): Tidy up slightly. Don't assume that two template functions with the same DECL_ASSEMBLER_NAME the same, since the names are not yet mangled. * error.c (dump_decl): Use TEMPLATE_PARM_INDEX instead of TEMPLATE_CONST_PARM. (dump_expr): Likewise. Use the TEMPLATE_PARM_DECL to get at the decl for a non-type parameter, rather than printing `'. * friend.c (is_friend): Handle TEMPLATE_DECL friends. (do_friend): Deal with template friends. * lex.c (do_pending_inlines): Call maybe_begin_member_template_processing, rather than conditionally calling begin_member_template_processing. (process_next_inline): Likewise. Call maybe_end_member_template_processing, rather than conditionally calling end_member_template_processing. (do_pending_defargs): Likewise. (do_identifier): Use TEMPLATE_PARM_INDEX instead of TEMPLATE_CONST_PARM. * method.c (build_mangled_template_parm_index): New function. (build_overload_value): Use it. (build_overload_name): Likewise. * pt.c (finish_member_template_decl): Allow friend declarations. (template_class_depth): New function. (is_member_template): Rename, and modify, to become... (is_member_or_friend_template): New function. (end_member_template_processing): Rename, and modify, to become... (maybe_end_member_template_processing). (build_template_parm_index): New function. (reduce_template_parm_level): New function. (process_template_parm): Modify to use build_template_parm_index. (push_template_decl): Deal with friend templates. (uses_template_parms): Use TEMPLATE_PARM_INDEX instead of TEMPLATE_CONST_PARM. (tsubst_friend_function): New function. (instantiate_class_template): Generate the DECL_FRIENDLIST for a new instantiation by using tsubst_friend_function rather than just tsubst. (tsubst): Don't tsubst into a type which is a TEMPLATE_DECL. Use TEMPLATE_PARM_INDEX instead of TEMPLATE_CONST_PARM, and the appropriate new macros. Use reduce_template_parm_level to generate lower-level template parameters. Handle tsubst'ing into TEMPLATE_DECLS that declare TEMPLATE_TEMPLATE_PARMS. Don't forget to tsubst the DECL_CONTEXT and DECL_CLASS_CONTEXT of newly created templates. Similarly for the template parameters for a new template. (tsubst_copy): Tidy up slightly. Use TEMPLATE_PARM_INDEX instead of TEMPLATE_CONST_PARM. Handle TYPE_DECLs by tsubsting into them. (unify): Use TEMPLATE_PARM_INDEX instead of TEMPLATE_CONST_PARM. (get_bindings): Call add_to_template_args if necessary. (instantiate_decl): Handle instantiations of friend templates. * search.c (lookup_field_1): Don't treat the TYPE_FIELDS of a TEMPLATE_TYPE_PARM as a list of fields; it's not! * spew.c (yylex): Do a little manual constant propagation to clarify the code. Sun Feb 22 19:53:29 1998 Jeffrey A Law (law@cygnus.com) * error.c: Include sys/types.h. Thu Feb 19 14:49:09 1998 Jeffrey A Law (law@cygnus.com) * method.c (build_mangled_name): Start CPP directives in column zero. Thu Feb 19 10:36:48 1998 Jason Merrill * typeck2.c (process_init_constructor): Sorry about non-trivial labeled initializers. * parse.y (initlist): Re-enable labeled initializers. Thu Feb 19 10:15:55 1998 Kriang Lerdsuwanakij * pt.c (coerce_template_parms): Add a new parameter, is_tmpl_parm, all callers changed. Rely on the new parameter instead of arg being a TREE_LIST when determine whether we are working inside template template parameter. Clean up is_type test. Thu Feb 19 10:04:12 1998 Jason Merrill * cvt.c (cp_convert_to_pointer): Preserve TREE_CONSTANT. * typeck2.c (initializer_constant_valid_p): Allow conversions between pointers and references. 1998-02-19 Brendan Kehoe * typeck.c (build_unary_op): Only warn about incr/decr a pointer if pedantic || warn_pointer_arith. Thu Feb 19 09:37:21 1998 Kriang Lerdsuwanakij * pt.c (unify): Handle TEMPLATE_DECL. 1998-02-18 Brendan Kehoe * cp-tree.h (strip_attrs): Remove decl. 1998-02-18 Doug Evans * decl.c (duplicate_decls): Call merge_machine_decl_attributes. Update olddecl's attributes too. (strip_attrs): Remove function. * typeck.c (common_type): Call merge_machine_type_attributes. Tue Feb 17 14:07:52 1998 Mark Mitchell * parse.y (initdcl0_innards): New grammar symbol. (nomods_initdecls, nomods_initdcl0): Change type from itype to none, since the resulting value is never used. (parse_decl): New function. (datadef): Remove redundant actions. (initdcl0, notype_initdcl0, nomods_initdcl0): Use initdcl0_innards. * parse.c: Regenerated. Tue Feb 17 11:54:16 1998 Jason Merrill * parse.y (simple_stmt): Use getdecls() to check for decl. Sat Feb 14 11:50:51 1998 Manfred Hollstein * Make-lang.in (DEMANGLER_INSTALL_NAME, DEMANGLER_CROSS_NAME): New macros. (c++.install-common): Install c++filt properly as native or as cross variant. (c++.uninstall): Add c++filt. Fri Feb 13 14:55:37 1998 Jason Merrill * call.c (standard_conversion): Fix multi-level ptr conversions. Fri Feb 13 14:06:22 1998 Mike Stump * init.c (build_new): Propagate error_mark_node up. Fri Feb 13 13:24:32 1998 Jason Merrill * parse.y (simple_stmt): If the condition isn't a declaration, start the controlled block after the test. Fri Feb 13 02:26:10 1998 Andreas Schwab * call.c (build_over_call): Convert builtin abs, labs and fabs to tree-codes. * decl.c (init_decl_processing): Re-enable abs, labs and fabs as builtins. Fri Feb 13 01:36:42 1998 Jason Merrill * call.c (standard_conversion): A BASE_CONV replaces an RVALUE_CONV. Fri Feb 13 00:21:59 1998 Jason Merrill * cp-tree.h: Add access_protected_virtual_node. * class.c (init_class_processing): Initialize it. * decl.c (xref_basetypes): Use it. * parse.y (base_class_access_list): Likewise. * Make-lang.in (DEMANGLER_PROG): Add $(exeext). (c++.install-common): Install c++filt. Thu Feb 12 12:46:51 1998 Benjamin Kosnik * decl.c (shadow_tag): Give error for typedef-ing built-in types. Wed Feb 11 23:28:05 1998 Mark Mitchell * call.c (reference_binding): Use comptypes when comparing TYPE_MAIN_VARIANTS to handle non-canonical array/index types. Wed Feb 11 16:42:04 1998 Mark Mitchell * tree.c (is_overloaded_fn): Use really_overloaded_fn. (really_overloaded_fn): Move check here from is_overloaded_fn. (get_first_fn): Use really_overloaded_fn and is_overloaded_fn. Wed Feb 11 15:54:18 1998 Mark Mitchell * typeck.c (build_ptrmemfunc): Type-check pointer-to-member conversions. Mon Feb 9 22:23:31 1998 Mark Mitchell * cp-tree.h (push_template_decl): Return the decl passed in, or an equivalent duplicate. * decl.c (pushtag): Use the return value from push_template_decl. (duplicate_decls): When duplicating a template declaration, merge the DECL_TEMPLATE_RESULTs as well. (make_implicit_typename): Don't try to dive into typename types to find a context for making a new implicit typename. (start_decl): Use the return value from push_template_decl. (grokdeclarator): Complain about declarations list `const operator int'. Since we don't correctly handle in-class initializations of non-static data members, complain about this (now illegal) practice. Issue an error for initializations of non-const statics since that is illegal as well, and since we don't handle that case correctly either. (start_function): Use the return value from push_template_decl. (start_method): Likewise. * decl2.c (grokfield): Likewise. Since the change to grokdeclarator ensures that all initialized fields are in fact static, remove a redundant test for TREE_PUBLIC. * parse.y (initlist): Disable labeled initializers since they do not work as per the documentation, and since they do not use the same syntax as the C front end. * pt.c (push_template_decl): Return the decl passed in, or an equivalent duplicate. (lookup_template_class): When searching in a nested context, use the right arguments. (uses_template_parms): Handle the DECL_INITIAL for a CONST_DECL. * typeck.c (build_component_ref): Assign the correct type to the result of build_vfn_ref. Tue Feb 10 23:56:46 1998 Jason Merrill * pt.c (convert_nontype_argument): Fix typo. (check_explicit_specialization): Allow old-style specialization of class template members. Tue Feb 10 20:36:52 1998 Jason Merrill Manfred Hollstein * decl.c (grokdeclarator): Use DECL_USE_TEMPLATE instead when deciding to override DECL_ASSEMBLER_NAME. Tue Feb 10 15:30:55 1998 Andrew MacLeod * decl2.c (lang_f_options): Add -fsquangle to option processing list. * cp-tree.h (flag_do_squangling): Add declaration. * lang-options.h: Add -fsquangle and -fno-squangle. * method.c: Add macros and static variables for squangling. (build_overload_name): Rename to build_mangled_name, add logic for B compression, and split into process_modifiers and process_overload_item. (process_modifiers): New function, to handle constant, reference, and pointer types. (process_overload_item): New function, handles issue of type codes. (build_overload_name): New function, start squangling and call build_mangled_name. (ALLOCATE_TYPEVEC, DEALLOCATE_TYPEVEC): Remove macro and expand inline. (start_squangling): New function to initialize squangling structs. (end_squangling): New function to destroy squangling structs. (nrepeats): Rename variable to Nrepeats. (issue_nrepeats): New function for issuing 'n' type repeats. (check_ktype): New function to check for type K name compression. (build_overload_nested_name): Add a check for K name compression. (build_qualified_name): Add a check for K name compression and don't use DECL_ASSEMBLER_NAME when squangling is on. (check_btype): New function, checks for B type compression. (build_static_name, build_decl_overload_real): Initiate squangling. (build_typename_overload, build_overload_with_type): Initiate squangling Sun Feb 8 23:47:38 1998 scott snyder * method.c (make_thunk): Avoid name buffer overflow. Sat Feb 7 16:48:54 1998 Jason Merrill * pt.c (instantiate_decl): Call cp_finish_decl for vars even if we don't define them yet. * parse.y (nomods_initdcl0): Add constructor_declarator case. Fri Feb 6 21:32:25 1998 Richard Kenner * config-lang.in (diff_excludes): Use basename only. Thu Feb 5 19:10:40 1998 Jason Merrill * tinfo2.cc: Add tinfo for signed char. Thu Feb 5 14:38:23 1998 Mike Stump * search.c (compute_access): Handle protected constructors in derived classes as accessible. Wed Feb 4 01:26:49 1998 Jason Merrill * expr.c (cplus_expand_expr, PCC_STATIC_STRUCT_RETURN code): Call convert_from_reference sooner. Tue Feb 3 23:50:52 1998 Mark Mitchell * cvt.c (ocp_convert): Obtain the constant values from constant decls even if the destination type is the same as the type of the decl. * decl2.c (finish_file): Make sure that static inlines with definitions are not marked DECL_EXTERNAL before returning. Tue Feb 3 22:43:42 1998 Jason Merrill * decl.c: Lose arg_looking_for_template. (lookup_name_real): Likewise. * parse.y: Lose processing_template_arg, template_arg1. (primary): Likewise. * spew.c (yylex): Set lastiddecl for PTYPENAMEs, too. Tue Feb 3 22:04:01 1998 Kriang Lerdsuwanakij * error.c (dump_decl): Fix type of default arguments for template template parameters and nontype template parameters. * parse.y (template_parm): Handle invalid default template template arguments here. * parse.y (template_parm): Use template_arg instead of PTYPENAME for default template template argument. * pt.c (coerce_template_parms): Merge default template argument codes. Can treat RECORD_TYPE as template name if it is implicitly created. Fix argument index in error message. * typeck.c (comptypes): Merge template argument comparison codes in TEMPLATE_TEMPLATE_PARM and RECORD_TYPE. Tue Jan 6 01:42:44 1998 Mumit Khan * lex.c (file_name_nondirectory): Also check for '/'. Mon Feb 2 11:24:22 1998 Mark Mitchell * parse.y (primary): Deal with statement-expressions in templates. * pt.c (tsubst_copy): Handle BIND_EXPR. * tree.c (mapcar): Likewise. * call.c (add_template_candidate_real): Pass extra parameter to fn_type_unification. * cp-tree.h (fn_type_unification): Add parameter. * pt.c (fn_type_unification): Add additional parameter to deal with static member functions. (get_bindings): Deal with static member functions. * cp-tree.h (DECL_NONSTATIC_MEMBER_FUNCTION_P): New macro. (revert_static_member_fn): Declare. * decl.c (revert_static_member_fn): Remove declaration. Change linkage from internal to external. (cp_finish_decl): Deal with virtual functions in classes local to template functions. * decl2.c (finish_file): Don't forget to emit increment/decrement expressions in initializers for file-scope variables. * parse.y (typename_sub2): If the typename doesn't names a template, rather than a type, issue an error message. * pt.c (check_explicit_specialization): Handle specializations of static member functions. (coerce_template_parms): Handle offset references to lists of member functions. * search.c (note_debug_info_needed): Don't crash when handed a type which is being defined. * typeck.c (complete_type): Don't crash when handed NULL_TREE; that can happen with some illegal code. Mon Feb 2 00:57:38 1998 Kaveh R. Ghazi * call.c (user_harshness): Initialize `code' to 0. (build_method_call): Initialize `candidates', `cp' and `len' to 0. (null_ptr_cst_p): Add parentheses around && within ||. (standard_conversion): Likewise. (z_candidate): Likewise. (build_user_type_conversion_1): Initialize `args' to NULL_TREE. (build_object_call): Likewise for `mem_args'. (build_new_op): Likewise for `mem_arglist'. Add `return' from default case in enumeration switch. * class.c (build_vtable_entry): Add explicit braces to avoid ambiguous `else'. (build_class_init_list): Likewise. (finish_struct_1): Initialize `width' to 0. (instantiate_type): Initialize `name' to NULL_TREE. Add explicit braces to avoid ambiguous `else'. * cvt.c (convert_to_aggr): Add explicit braces to avoid ambiguous `else'. * decl.c (grok_reference_init): Eliminate unused parameter, all callers changed. (record_builtin_type): Initialize `tdecl' to NULL_TREE. (init_decl_processing): Initialize `vb_off_identifier' to NULL_TREE. (cp_finish_decl): Initialize `ttype' to NULL_TREE. (grokdeclarator): Add parentheses around && within ||. Add explicit braces to avoid ambiguous `else'. (grokparms): Initialize `type' to NULL_TREE. (xref_tag): Remove unused label `just_return'. (finish_enum): Initialize `minnode' and `maxnode' to NULL_TREE. (finish_function): Initialize `cond' and `thenclause' to NULL_TREE. (hack_incomplete_structures): Add parentheses around assignment used as truth value. * decl2.c (coerce_delete_type): Hide definition of `e3'. * error.c: Include . (dump_expr): Change the type of `i' to size_t. Remove unused label `error'. * except.c (init_exception_processing): Remove unused variable `d'. (expand_throw): Likewise for `label'. * friend.c (add_friends): Add explicit braces to avoid ambiguous `else'. * init.c (sort_member_init): Initialize `last_field' to NULL_TREE. (sort_base_init): Likewise for `binfo'. (expand_member_init): Likewise for `rval'. (build_member_call): Add parentheses around assignment used as truth value. (build_offset_ref): Add explicit braces to avoid ambiguous `else'. (build_new): Initialize `nelts' to NULL_TREE. Initialize `old_immediate_size_expand' to 0. (build_new_1): Initialize `nelts' and `alloc_node' to NULL_TREE. (build_vec_delete_1): Remove unused variable `block'. (expand_vec_init): Initialize `itype' to NULL_TREE. * lex.c: Include if we don't have . Protect declaration of `index' and `rindex' with autoconf macros. (reinit_parse_for_expr): Remove unused variables `look_for_semicolon' and `look_for_lbrac'. (cons_up_default_function): Initialize `args' to NULL_TREE. (readescape): Initialize `firstdig' to 0. (real_yylex): Add parentheses around assignment used as truth value. * method.c: Include if we don't have . Protect declaration of `index' with autoconf macro. * parse.y (primary): Add explicit braces to avoid ambiguous `else'. Initialize `type' to NULL_TREE. (structsp): Remove unused variable `id'. * pt.c (coerce_template_parms): Add explicit braces to avoid ambiguous `else'. (lookup_template_class): Initialize `template' to NULL_TREE. (instantiate_class_template): Remove unused variable `name' and `e'. (tsubst): Likewise for `i'. Initialize `last' to NULL_TREE. (do_poplevel): Initialize `saved_warn_unused' to 0. (type_unification): Remove unused varable `parm'. (unify): Likewise for `j'. * repo.c (init_repo): Add parentheses around assignment used as truth value. (finish_repo): Remove unused varable `p'. * search.c (get_binfo): Initialize `type' to NULL_TREE. (get_base_distance): Likewise. (lookup_field): Initialize `rval_binfo_h', `type', `basetype_path' and `new_v' to NULL_TREE. (lookup_fnfields): Likewise for `rval_binfo_h'. (breadth_first_search): Add parentheses around assignment used as truth value. (get_template_base): Initialize `type' to NULL_TREE. * sig.c (append_signature_fields): Initialize `last_mfptr' to NULL_TREE. (build_signature_table_constructor): Likewise for `last_rhs_field', `pfn' and `vt_off'. (build_sigtable): Likewise for `init'. * tree.c (break_out_calls): Initialize `t2' to NULL_TREE. (propagate_binfo_offsets): Likewise for `delta'. (hash_tree_cons): Initialize hashcode to 0. (can_free): Likewise for `size'. (cp_tree_equal): Add explicit braces to avoid ambiguous `else'. * typeck.c (convert_sequence): Hide prototype. (common_type): Add explicit braces to avoid ambiguous `else'. (comp_target_types): Likewise. (build_x_function_call): Initialize `ctypeptr' to NULL_TREE. (build_function_call_real): Add explicit braces to avoid ambiguous `else'. (convert_arguments): Initialize `called_thing' to 0. (convert_for_initialization): Initialize `savew' and `savee' to 0. * typeck2.c (incomplete_type_error): Initialize `errmsg' to 0. (digest_init): Initialize `old_tail_contents' to NULL_TREE. (build_x_arrow): Likewise for `last_rval'. * xref.c (GNU_xref_decl): Initialize `cls' to 0. Sun Feb 1 12:45:34 1998 J"orn Rennecke * decl.c (init_decl_processing): Use set_sizetype. * decl2.c (sizetype): Don't declare. * typeck.c (c_sizeof): Convert result of *_DIV_EXPR to sizetype. (c_sizeof_nowarn, build_binary_op_nodefault): Likewise. (build_component_addr, unary_complex_lvalue): Likewise. * rtti.c (expand_class_desc): Likewise. * class.c (get_vfield_offset): Likewise. Thu Jan 29 10:39:30 1998 Mark Mitchell * pt.c (convert_nontype_argument): Move check for is_overloaded_fn early to avoid bogus error. Handle overloaded function names provided as template arguments correctly. (coerce_template_parms): Don't mishandle overloaded functions when dealing with template template parameters. (lookup_template_class): Issue an error message, rather than crashing, when the TYPE_DECL provided is not a template type. Wed Jan 28 23:14:44 1998 Jason Merrill * class.c (instantiate_type): Don't just return a known type if it's wrong. Wed Jan 28 11:04:07 1998 Mark Mitchell * class.c (instantiate_type): Remove handling of FUNCTION_DECL since that code could never be reached. * error.c (dump_decl): Avoid aborting in the midst of printing an error message about an illegal template declaration. * parse.y (structsp): Print an error message, rather than crashing, when a class-head does not name a class. * pt.c (convert_nontype_argument): Allow REAL_TYPE and COMPLEX_TYPE template arguments as a g++ extension. * cp-tree.def (ALIGNOF_EXPR): New tree code. * decl2.c (grok_alignof): If processing_template_decl, just store the expression. * typeck.c (c_alignof): Likewise. * decl2.c (build_expr_from_tree): Handle ALIGNOF_EXPR. * error.c (dump_expr): Likewise. * pt.c (tsubst_copy): Likewise. * tree.c (cp_tree_equal): Likewise. * pt.c (uses_template_parms): Correctly determine whether or not a SIZEOF_EXPR/ALIGNOF_EXPR uses template parameters so that constant folding can be done. * cp-tree.h (grok_enum_decls): Remove type parameter. * decl.c (grok_enum_decls): Likewise. * decl2.c (grok_x_components): Call grok_enum_decls unconditionally, since it will do nothing if there is no current_local_enum. Use the new calling sequence. * pt.c (tsubst_enum): Use the new calling sequence for grok_enum_decls. * decl.c (start_function): Make member functions of local classes in extern inline functions have comdat linkage here... (grokdeclarator): Rather than here. Wed Jan 28 10:55:47 1998 Jason Merrill * pt.c (convert_nontype_argument): Use decl_constant_value. Tue Jan 27 16:42:21 1998 Mark Mitchell * call.c (add_template_candidate_real): New function. (add_template_candidate): Use it. (add_template_conv_candidate): Likewise. (joust): Pass extra argument to more_specialized. * class.c (instantiate_type): Handle a single FUNCTION_DECL. (is_local_class): Remove. (finish_struct): Check TI_PENDING_SPECIALIZATION_FLAG. * cp-tree.h (is_local_class): Remove. (perform_array_to_pointer_conversion): Likewise. (finish_member_template_decl): Add. (check_explicit_specialization): Return a tree, not an int. (more_specialized): Take additional argument. (get_bindings): Likewise. (TI_PENDING_SPECIALIZATION_FLAG): New macro. * cvt.c (perform_qualification_conversions): Use comp_ptr_ttypes. (perform_array_to_pointer_conversion): Remove. * decl.c (saved_scope): Add processing_specialization, processing_explicit_instantiation fields. (maybe_push_to_top_level): Save them. (pop_from_top_level): Restore them. (grokfndecl): Use new return value from check_explicit_specialization. (start_decl): Don't check flag_guiding_decls before pushing decls. (cp_finish_decl): Remove previous (bogus) change. (grok_declarator): Use decl_function_context rather than is_local_class. * decl2.c (finish_file): Pass extra argument to get_bindings. (build_expr_from_tree): Let build_x_component_ref check validity of arguments rather than doing it here. * lex.c (cons_up_default_function): Remove code fooling with processing_specialization, processing_explicit_instantiation flags, as that is now done in {maybe_push_top,pop_from}_top_level. * method.c (build_overload_identifier): Mangle local classes in template functions correctly. * parse.y (finish_member_template_decl): Move to pt.c. * pt.c (finish_member_template_decl): Moved here from parse.y. (print_candidates): New function. (determine_specialization): Change interface. Properly look for most specialized versions of template candidates. (check_explicit_specialization): Fully process explicit instantiations. (push_template_decl): Avoid looking at CLASSTYPE fields in FUNCTION_DECLS. (determine_overloaded_function): Remove. (convert_nontype_argument): Change name from convert_nontype_parameter. Use determine_overloaded_function instead of instantiate_type. (mangle_class_name_for_template): Handle type contexts as well as function contexts. (classtype_mangled_name): Likewise. (lookup_template_class): Likewise. (tsubst): Likewise. (more_specialized): Take explict template arguments as a parameter. (most_specialized): Likewise. (get_bindings): Likewise. Check that return types match before proclaiming a function a match. (do_decl_instantiation): Remove code searching for function to instantiate; that is now done in check_explicit_specialization. (add_maybe_template): Pass extra argument to get_bindings. * tree.c (really_overloaded_fn): Use is_overloaded_fn to simplify implementation. * typeck.c (build_component_ref): Check for invalid arguments. Tue Jan 27 01:44:02 1998 Jason Merrill * expr.c (cplus_expand_expr, AGGR_INIT_EXPR): Don't check that return_target and call_target are equivalent. * pt.c (type_unification_real): Just accept function parms that don't use any template parms. Sun Jan 25 03:30:00 1998 Jason Merrill * decl.c (cp_finish_decl): When bailing on a comdat variable, also unset DECL_NOT_REALLY_EXTERN. * parse.y (typename_sub*): Fix std::. Sat Jan 24 12:13:54 1998 Jason Merrill * error.c (dump_decl): Fix type default template args. (dump_type): Hand TEMPLATE_DECL off to dump_decl. Fri Jan 23 18:34:37 1998 Mumit Khan * lex.c (DIR_SEPARATOR): Define to be '/' if not already defined. (file_name_nondirectory): Use. Wed Jan 21 10:29:57 1998 Kriang Lerdsuwanakij * pt.c (coerce_template_parms): Don't access elements of ARGLIST that are not really present. Substitute default arguments in template template arguments. Correctly convert TEMPLATE_DECL to TEMPLATE_TEMPLATE_PARM. (comp_template_args): TEMPLATE_DECL and TEMPLATE_TEMPLATE_PARM are no longer treated specially here. * parse.y (template_template_parm): Fix copy error. * decl.c (grokdeclarator): Warn about missing `typename' for nested type created from template template parameters. * parse.y (bad_parm): Likewise * class.c (finish_struct): Handle TEMPLATE_TEMPLATE_PARM. (push_nested_class): Likewise. * cp-tree.def (TEMPLATE_TEMPLATE_PARM): New tree code. * cp-tree.h (DECL_TEMPLATE_TEMPLATE_PARM_P): New macro. (copy_template_template_parm): Declare. * decl.c (arg_looking_for_template): New variable. (lookup_name_real): Handle TEMPLATE_TEMPLATE_PARM. Try to return TEMPLATE_DECL or TEMPLATE_TEMPLATE_PARM node if arg_looking_for_template is nonzero. (pushdecl): Handle TEMPLATE_TEMPLATE_PARM. (grok_op_properties, xref_tag, xref_basetypes): Likewise. (grokdeclarator): Handle TEMPLATE_DECL. * decl2.c (constructor_name_full): Handle TEMPLATE_TEMPLATE_PARM. * error.c (dump_type): Add TEMPLATE_DECL and TEMPLATE_TEMPLATE_PARM. (dump_type_prefix, dump_type_suffix): Handle TEMPLATE_TEMPLATE_PARM. (dump_decl): Handle unnamed template type parameters. Handle template template parameters. (dump_function_name): Handle template template parameters. * init.c (is_aggr_typedef, is_aggr_type, get_aggr_from_typedef): Handle TEMPLATE_TEMPLATE_PARM. * method.c (build_template_template_parm_names): New function. (build_template_parm_names): Handle TEMPLATE_DECL. (build_overload_nested_name, build_overload_name): Handle TEMPLATE_TEMPLATE_PARM. * parse.y (maybe_identifier): New nonterminal. (template_type_parm): Use it. (template_template_parm, template_arg1): New nonterminal. (template_parm): Add template_template_parm rules. (template_arg): Set processing_template_arg. (template_arg1): Rules moved from template_arg. (primary, nonnested_type): Set arg_looking_for_template if we are processing template arguments. * pt.c (begin_member_template_processing): Handle TEMPLATE_DECL. (process_template_parm): Handle template template parameters. (coerce_template_parms, comp_template_args): Likewise. (mangle_class_name_for_template, lookup_template_class): Likewise. (uses_template_parms): Handle TEMPLATE_DECL and TEMPLATE_TEMPLATE_PARM. (current_template_args): Handle TEMPLATE_DECL. (tsubst, tsubst_copy, unify): Handle TEMPLATE_TEMPLATE_PARM. * search.c (dfs_walk, dfs_record_inheritance): Handle TEMPLATE_TEMPLATE_PARM. * tree.c (copy_template_template_parm): New function. (mapcar): Handle TEMPLATE_TEMPLATE_PARM. * typeck.c (comptypes): Handle TEMPLATE_TEMPLATE_PARM. Mon Jan 19 22:40:03 1998 Mark Mitchell * decl.c (start_decl): Don't allow duplicate definitions of static data members. * call.c (build_user_type_conversion_1): Handle user-defined template conversion operators correctly. * decl2.c (build_expr_from_tree): Issue an error message if the object in a COMPONENT_REF is a TEMPLATE_DECL. * typeck.c (incomplete_type_error): Handle TEMPLATE_TYPE_PARMs. * class.c (is_local_class): New function. * cp-tree.h (is_local_class): Declare it. (last_tree): Likewise. (begin_tree): Likewise. (end_tree): Likewise. (lookup_template_class): Change prototype. * decl.c (cp_finish_decl): Check for NULL where necessary. Consider FUNCTION_DECLS to declare objects with top-level binding, when calling make_decl_rtl. (grokdeclarator): Give members of local classes internal linkage. (start_function): Remove declaration of last_tree. (finish_function): Set flag_keep_inline_functions around call to rest_of_compilation if we are processing a member function in a local class. (start_method): Call push_template_decl for member functions of local classes in template functions. * decl2.c (import_export_decl): Don't give external linkage to instantiations of templates with internal linkage. * parse.y (last_tree): Remove declaration. (template_type): Pass extra parameter to lookup_template_class. (self_template_type): Likewise. (structsp): Move call to reset_specialization into left_curly. (left_curly): Call reset_specialization, and begin_tree. * pt.c (saved_trees): New variable. (mangle_class_name_for_template): Change prototype. Use additional function context to name local classes in templates correctly. (classtype_mangled_name): Pass the context. (push_template_decl): Handle local classes and templates, and member functions for such classes. (convert_nontype_parameter): Fix handling of pointer-to-member constants. (lookup_template_class): Handle local classes in templates. (tsubst): Likewise. Don't assume that template instantiations have external linkage; pay attention to the template declaration. (mark_decl_instantiated): Likewise. (begin_tree): New function. (end_tree): Likewise. * decl.c (xref_basetypes): Don't call complete_type for basetypes that involve template parameters; that can lead to infinite recursion unnecessarily. * pt.c (register_specialization): Do not register specializations that aren't ready to be registered yet. (check_explicit_specialization): Handle explicit specialization of constructors and destructors. (build_template_decl): New function. (push_template_delc): Handle out-of-class specializations of member templates. * pt.c (check_explicit_specialization): Set up the template information before registering the specialization. (coerce_template_parms): Fix thinko. (tsubst): Handle specializations of member templates correctly. * class.c (finish_struct_methods): Remove calls to check_explicit_specialization from here. (finish_struct): And insert them here. * cp-tree.h (perform_qualification_conversions): New function. (perform_array_to_pointer_conversion): Likewise. (begin_explicit_instantiation): Likewise. (end_explicit_instantiation): Likewise. (determine_specialization): Renamed from determine_explicit_specialization. (comp_template_parms): New function. (processing_explicit_instantiation): New variable. * cvt.c (perform_qualification_conversions): New function. (perform_array_to_pointer_conversion): Likewise. * decl.c (duplicate_decls): Don't consider template functions alike unless they have the same parameters. Refine handling of instantiation/specialization mismatches. (start_decl): Don't call pushdecl for template specializations, since they don't affect overloading. (start_function): Likewise. (grokfndecl): Call check_explicit_specialization a little later. Don't call duplicate_decls for memberm template specializations. (grokdeclarator): Don't update template_count for classes that are themselves specializations. Remove use of `2' as parameter to grokfndecl since that value isn't used. * lex.c (cons_up_default_function): Save and restore processing_explicit_instantiation around calls to grokfield. * parse.y (finish_member_template_decl): New function. (component_decl_1): Use it. (fn.def2): Likewise. (template_arg_list_opt): New nonterminal. (template_type): Use it. (self_template_type): Likewise. (template_id): Likewise. (object_template_id): Likewise. (notype_template_declarator): Likwise. (begin_explicit_instantiation): Likewise. (end_explicit_instantiation): Likewise. (explicit_instantiation): Use them. * pt.c (coerce_template_parms): Add parameters. (processing_explicit_instantiation): New variable. (convert_nontype_parameter): New function. (determine_overloaded_function): Likewise. (begin_explicit_instantiation): Likewise. (end_explicit_instantiation): Likewise. (retrieve_specialization): Likewise. (register_specialization): Likewise. (processing_explicit_specialization): Removed. (determine_specialization): Handle specializations of member functions of template class instantiations. (check_explicit_specialization): Refine to conform to standard. (comp_template_parms): New function. (coerce_template_parms): Call convert_nontype_parameter. (tsubst): Refine handling of member templates. Use register_specialization. (instantiate_template): Use retrieve_specialization. (do_decl_instantiation): Likewise. (instantiate_decl): Likewise. (type_unification): Improve handling of explict template arguments. * tree.c (mapcar): Return error_mark_node, rather than aborting, on VAR_DECLS, FUNCTION_DECLS, and CONST_DECLS. * typeck.c (build_unary_op): Call determine_specialization, rather than determine_explicit_specialization. Mon Jan 19 13:18:51 1998 Jason Merrill * cvt.c (build_up_reference): A TARGET_EXPR has side effects. Fri Jan 16 11:40:50 1998 Bruno Haible * error.c (dump_decl): For enum tags, output the tag, not its value. 1998-01-13 Brendan Kehoe * decl.c (init_decl_processing): Only call init_rtti_processing FLAG_RTTI is set. Mon Jan 12 01:35:18 1998 Jason Merrill * init.c (build_new_1): Split out from build_new. (build_new): Just return a NEW_EXPR. * expr.c (cplus_expand_expr): Handle NEW_EXPR. * decl2.c (get_temp_regvar): Tweak. * cp-tree.h (TREE_CALLS_NEW): Comment out. * class.c (resolves_to_fixed_type_p): Remove use. * method.c (build_opfncall): Likewise. * call.c (build_new_op): Likewise. Wed Jan 7 23:47:13 1998 Jason Merrill * exception.cc (__eh_alloc, __eh_free): New fns. (__cp_push_exception, __cp_pop_exception): Use them. (__uncatch_exception): Call terminate here if no exception. * except.c (build_terminate_handler): New fn. (expand_start_catch_block): Use it. (expand_exception_blocks): Likewise. (alloc_eh_object): New fn. (expand_throw): Use it. Protect exception init with terminate. * typeck.c (build_modify_expr): Remove code that ignores trivial methods. Mon Dec 22 11:36:27 1997 Kaveh R. Ghazi * call.c (add_builtin_candidate): Add default case in enumeration switch. (build_new_op): Likewise. (convert_like): Likewise. * cvt.c (build_expr_type_conversion): Likewise. * tree.c (real_lvalue_p): Likewise. (lvalue_p): Likewise. (cp_tree_equal): Likewise. * typeck.c (comptypes): Likewise. (build_component_ref): Likewise. (build_function_call_real): Likewise. (build_binary_op_nodefault): Likewise. (build_unary_op): Likewise. (build_modify_expr): Likewise. * typeck2.c (initializer_constant_valid_p): Likewise. Sun Dec 21 15:59:00 1997 Nick Clifton * decl2.c (lang_decode_option): Add support for -Wunknown-pragmas. Thu Dec 18 14:51:50 1997 Mark Mitchell * pt.c (coerce_template_parms): Make sure to digest_init if possible. * decl.c (duplicate_decls): Make the newdecl virtual if the olddecl was, just as is done with other attributes of olddecl. Thu Dec 18 14:43:19 1997 Jason Merrill * typeck.c (unary_complex_lvalue): Ignore op0 when taking the address of an OFFSET_REF. * cp-tree.def: Add AGGR_INIT_EXPR. * error.c, tree.c, typeck.c: Replace uses of NEW_EXPR with AGGR_INIT_EXPR where appropriate. * expr.c (cplus_expand_expr): Likewise. Simplify. * decl2.c (finish_file): Remove call to register_exception_table. Wed Dec 17 17:08:52 1997 Benjamin Kosnik * pt.c (instantiate_class_template): Don't do injection when processing_template_decl is true, as pollutes current_binding_level for base classes. Wed Dec 17 21:17:39 1997 Peter Schmid * pt.c (maybe_fold_nontype_arg): Add prototype. Tue Dec 16 10:31:20 1997 Jason Merrill * tree.c (mapcar): Handle TRY_CATCH_EXPR et al. * error.c (dump_expr): Likewise. Mon Dec 15 12:22:04 1997 Jason Merrill * typeck.c (build_function_call_real): Remove "inline called before definition" pedwarn. * pt.c (coerce_template_parms): Use maybe_fold_nontype_arg. Sun Dec 14 22:34:20 1997 Jason Merrill * cvt.c (cp_convert_to_pointer): Fix base conversion of pm's. * pt.c (type_unification_real): Change __null to type void* with a warning. Sun Dec 14 20:38:35 1997 Mark Mitchell * call.c (implicit_conversion): Don't call build_user_type_conversion_1 with a NULL expr, since it will crash. * pt.c (unify): Don't try to unify array bounds if either array is unbounded. Fri Dec 12 16:09:14 1997 Jason Merrill * errfn.c (cp_pedwarn, cp_pedwarn_at, cp_error_at, cp_warning_at): Replace extern decls with casts. * decl.c (expand_start_early_try_stmts): Don't mess with a sequence. Update last_parm_cleanup_insn. (store_after_parms): Remove. * cp-tree.h: Adjust. Thu Dec 11 22:18:37 1997 Jason Merrill * decl2.c (comdat_linkage): Also set DECL_COMDAT. (finish_file): Check DECL_COMDAT instead of weak|one_only. (import_export_vtable): Use make_decl_one_only instead of comdat_linkage for win32 tweak. (import_export_decl): Likewise. * pt.c (mark_decl_instantiated): Likewise. * decl2.c (finish_file): Lose handling of templates in pending_statics. Thu Dec 11 21:12:09 1997 Jason Merrill * decl2.c (finish_file): Lose call to expand_builtin_throw. * except.c (expand_builtin_throw): Remove. * cp-tree.h: Remove ptr_ptr_type_node. * decl.c: Likewise. Thu Dec 11 20:43:33 1997 Teemu Torma * decl.c (ptr_ptr_type_node): Define. (init_decl_processing): Initialize it. * cp-tree.h: Declare it. * exception.cc (__cp_exception_info): Use __get_eh_info. (__cp_push_exception): Likewise. (__cp_pop_exception): Likewise. From Scott Snyder : * except.c (expand_builtin_throw): Use get_saved_pc_ref instead of saved_pc. (init_exception_processing): Removed saved_pc initialization. Wed Dec 10 11:04:45 1997 Jason Merrill * pt.c (instantiate_decl): Defer all templates but inline functions. Mon Dec 8 23:17:13 1997 Jason Merrill * init.c (expand_vec_init): Don't fold a list of parameters. * decl.c (copy_args_p): Handle copy elision for types with virtual bases. * call.c (build_over_call): Likewise. Sun Dec 7 22:38:12 1997 Mark Mitchell * pt.c (lookup_template_function): Copy the template arguments, not just the list containing them, to the permanent obstack. Sun Dec 7 15:53:06 1997 Jason Merrill * except.c (expand_start_catch_block): suspend_momentary for the terminate handler. * error.c (dump_decl): Handle LOOKUP_EXPR. Sun Dec 7 15:45:07 1997 Mark Mitchell * rtti.c (build_dynamic_cast): Copy the cast-to type to the permanent obstack if we are processing a template decl. * typeck.c (build_static_cast): Likewise. (build_const_cast): Likewise. (build_reinterpret_cast): Likewise. * pt.c (coerce_template_parms): Coerce some expressions, even when processing_template_decl. Sun Dec 7 01:46:33 1997 Bruno Haible * typeck.c (build_binary_op_nodefault, pointer_diff): Symmetric handling of pointer difference expressions. * typeck.c (comp_target_types): Comparison of function/method types is independent of nptrs. Sun Dec 7 01:40:27 1997 Mark Mitchell * pt.c (tsubst): Avoid creating pointer to reference and reference to reference types. Sat Dec 6 01:29:37 1997 Jason Merrill * parse.y (do_id): New nonterminal. (template_id): Use it. Fri Dec 5 01:17:34 1997 Jason Merrill * parse.y (template_id): do_identifier for PFUNCNAMEs, too. * spew.c (yylex): Don't do_identifier here. * decl2.c (build_expr_from_tree): Revert last change. * decl2.c (build_expr_from_tree): Expand the name for a method call. * parse.y (object_template_id): Don't try to take the DECL_NAME. Wed Dec 3 20:02:39 1997 Jason Merrill * init.c (build_new): Use a TARGET_EXPR instead of SAVE_EXPR for alloc_expr. * call.c (build_op_delete_call): Adjust. * except.c (expand_end_catch_block): Lose rethrow region. (expand_start_catch_block): Likewise. (expand_end_catch_block): Don't expand_leftover_cleanups. Wed Dec 3 13:24:04 1997 Benjamin Kosnik * pt.c (tsubst): Remove tree_cons call (places redundant info into DECL_TEMPLATE_INSTANTIATION). Wed Dec 3 11:44:52 1997 Jason Merrill * tree.c (is_overloaded_fn): Handle getting a fn template. (really_overloaded_fn): Likewise. * error.c (dump_decl): Handle TEMPLATE_ID_EXPRs better. * pt.c (check_explicit_specialization): Tweak. (determine_explicit_specialization): Tweak. * tree.c, cp-tree.h (get_target_expr): New fn. Wed Dec 3 08:47:27 1997 Paul Eggert * pt.c (check_explicit_specialization): Fix misspelling in diagnostic: `preceeded'. * typeck.c (get_delta_difference): Fix misspelling in diagnostic: `conversiona'. 1997-12-02 Mark Mitchell * pt.c (determine_explicit_specialization): Avoid an internal error for bad specializations. * method.c (build_overload_value): Handle SCOPE_REF. Tue Dec 2 19:18:50 1997 Mike Stump * class.c (prepare_fresh_vtable): Enable even more complex MI vtable names. Tue Dec 2 01:37:19 1997 Jason Merrill * exception.cc (__check_eh_spec): Optimize a bit. * exception.cc (__cp_pop_exception): Lose handler arg. * except.c (do_pop_exception): Likewise. (push_eh_cleanup): Let the cleanup mechanism supply the handler. (expand_end_catch_block): Likewise. Fri Nov 28 01:58:14 1997 Jason Merrill * pt.c (check_explicit_specialization): Complain about using a template-id for a non-specialization. Fri Nov 28 12:35:19 1997 Scott Christley * repo.c: Prototype rindex only if needed. * xref.c: Likewise. Fri Nov 28 01:56:35 1997 Bruno Haible * error.c (dump_decl): Handle TEMPLATE_ID_EXPR. Thu Nov 27 00:59:46 1997 Jason Merrill * typeck.c (build_const_cast): Handle references here instead of handing off to convert_to_reference. * except.c: Lose Unexpected, SetTerminate, SetUnexpected, TerminateFunctionCall. (init_exception_processing): Likewise. Terminate et al are now the fns, not ADDR_EXPRs. (various): Lose redundant assemble_external calls. (do_unwind): s/BuiltinReturnAddress/builtin_return_address_fndecl/. * cp-tree.h (struct lang_decl_flags): Add comdat. (DECL_COMDAT): New macro. * decl.c (duplicate_decls): Propagate it. (cp_finish_decl): Handle it. * decl2.c (import_export_decl): Just set DECL_COMDAT on VAR_DECLs. * class.c: Remove static pending_hard_virtuals. (add_virtual_function): Take pointers to pending_virtuals and pending_hard_virtuals. (finish_struct_1): Pass them. Declare pending_hard_virtuals. Wed Nov 26 20:28:49 1997 Jason Merrill * decl2.c (import_export_vtable): If we support one_only but not weak symbols, mark instantiated template vtables one_only. (import_export_decl): Likewise for tinfo functions. (finish_vtable_vardecl): Also write out vtables from explicitly instantiated template classes. * pt.c (mark_class_instantiated): Revert last change. * except.c (expand_throw): Call mark_used on the destructor. Wed Nov 26 15:13:48 1997 Jeffrey A Law (law@cygnus.com) * lex.c (lang_init): Enable flag_exceptions by default if no command line switch was specified. 1997-11-26 Mark Mitchell * pt.c (unify): Handle `void' template parameters in specializations. Wed Nov 26 01:11:24 1997 Jason Merrill * rtti.c (build_dynamic_cast): Handle template case here. (build_dynamic_cast_1): Not here. * typeck2.c (digest_init): Make copies where appropriate. * decl2.c (delete_sanity): resolve_offset_ref. * except.c: Call terminate without caching so many bits. * except.c (expand_start_catch_block): Fix catching a reference to pointer. Tue Nov 25 11:28:21 1997 Jason Merrill * init.c (build_new): Copy size to the saveable obstack. * init.c (build_new): Stick a CLEANUP_POINT_EXPR inside the TRY_CATCH_EXPR for now. Mon Nov 24 12:15:55 1997 Jason Merrill * typeck.c (mark_addressable): Don't assume a FUNCTION_DECL has DECL_LANG_SPECIFIC. * exception.cc (struct cp_eh_info): Add handlers field. (__cp_push_exception): Initialize it. (__cp_pop_exception): Decrement it. Don't pop unless it's 0. (__throw_bad_exception): Remove. * except.c (call_eh_info): Add handlers field. (get_eh_handlers): New fn. (push_eh_cleanup): Increment handlers. Fri Nov 21 12:22:07 1997 Jason Merrill * except.c (expand_start_eh_spec): Use the try/catch code. (expand_end_eh_spec): Likewise. Call __check_eh_spec instead of doing everything inline. (init_exception_processing): throw_type_match now takes const void pointers. * exception.cc (__check_eh_spec): New fn. * inc/exception: Neither terminate nor unexpected return. * decl.c: Make const_ptr_type_node public. * tinfo2.cc (__throw_type_match_rtti): Take the typeinfos constly. * except.c (expand_start_catch_block): We only need the rethrow region for non-sjlj exceptions. (expand_end_catch_block): Likewise. Use outer_context_label_stack. Thu Nov 20 14:40:17 1997 Jason Merrill * Make-lang.in (CXX_LIB2FUNCS): Add new op new and op delete objs. (various.o): Likewise. * inc/new: Add placement deletes. Add throw specs for default new. * new.cc (set_new_handler): Move here from libgcc2. * new1.cc (new (nothrow)): Catch a bad_alloc thrown from the handler. (new): Move from libgcc2. Throw bad_alloc. * new2.cc: Move the rest of the op news and op deletes from libgcc2. * decl.c (init_decl_processing): Update exception specs on new and delete. * method.c (build_decl_overload_real): Don't mess with global placement delete. * init.c (build_new): Check for null throw spec, not nothrow_t. * decl.c (duplicate_decls): Don't complain about different exceptions from an internal declaration. * call.c (build_op_delete_call): Fix check for member fns again. * decl2.c (import_export_decl): Interface hackery affects virtual synthesized methods. Wed Nov 19 18:24:14 1997 Jason Merrill * decl.c (start_decl): Don't just complain about a mismatched scope, fix it. * decl.c (make_implicit_typename): Handle case where t is not actually from context. * tree.c (get_type_decl): Lose identifier case. * spew.c (yylex): Lose useless call to identifier_typedecl_value. * parse.y (nonnested_type): Just use lookup_name. (complex_type_name): Just use IDENTIFIER_GLOBAL_VALUE. Wed Nov 19 11:45:07 1997 Michael Tiemann * error.c (dump_function_name): Test DECL_LANG_SPECIFIC in case T was built in C language context (for example, by output_func_start_profiler). Wed Nov 19 10:39:27 1997 Jason Merrill * decl.c (make_implicit_typename): New fn. (lookup_name_real): Use it. Use current_class_type as the context. Mon Nov 17 23:42:03 1997 Bruno Haible * pt.c (do_poplevel): Don't prohibit jumps into this contour. Mon Nov 17 02:01:28 1997 Jason Merrill * friend.c (do_friend): Warn about non-template friends in templates. * call.c (build_op_delete_call): Fix handling of inherited delete. * search.c (dfs_record_inheritance): Ignore template type parms. Sat Nov 15 00:30:51 1997 Jason Merrill * call.c (build_new_op): Fix copy error. (build_op_new_call): New fn. (build_op_delete_call): New fn. * cp-tree.h: Declare them. * init.c (build_new): Use them. Support placement delete. (build_x_delete): Use build_op_delete_call. (build_delete): Likewise. * decl2.c (delete_sanity): Likewise. (coerce_delete_type): Don't complain about placement delete. Thu Nov 13 01:52:36 1997 Jason Merrill * call.c (build_new_function_call): Remove unused 'obj' parm. * cp-tree.h, typeck.c: Adjust. * init.c (build_new): Make the cleanup last longer. (expand_vec_init): Call do_pending_stack_adjust. Wed Nov 12 11:04:33 1997 Jason Merrill * pt.c (do_type_instantiation): Fix typo. (mark_class_instantiated): If we support one_only but not weak symbols, don't mark this as known. * init.c (build_new): Handle vec delete in EH cleanup. Wed Nov 12 08:11:55 1997 Benjamin Kosnik * call.c (build_method_call): Call complete_type before checking for destructor. Sun Nov 9 01:29:55 1997 Jim Wilson (wilson@cygnus.com) * decl.c (add_block_current_level): Delete. * init.c (build_vec_delete_1): Delete build_block and add_block_current_level calls. Wed Nov 12 00:48:16 1997 Jason Merrill * init.c (build_new): Handle freeing allocated memory when the constructor throws. * call.c (build_new_method_call): Fix flags arg. * pt.c (do_type_instantiation): Don't try to instantiate member templates. (mark_decl_instantiated): If we support one_only but not weak symbols, mark this one_only. * decl2.c (import_export_vtable): Don't defer handling of vtables if MULTIPLE_SYMBOL_SPACES. Tue Nov 11 12:02:12 1997 Jason Merrill * except.c (expand_end_catch_block): Lose call to __sjpopnthrow. Tue Nov 11 02:53:44 1997 Jason Merrill * except.c (do_pop_exception): Return a value. Mon Nov 10 20:25:31 1997 Jason Merrill * call.c (build_new_method_call): Handle getting a TEMPLATE_ID_EXPR around a TEMPLATE_DECL. Don't look for a field if we got template parms. * typeck.c (build_x_function_call): Remember the TEMPLATE_ID_EXPR, not just the args. * decl2.c (build_expr_from_tree): Tweak last change. * pt.c (tsubst_copy): Use get_first_fn instead of TREE_VALUE. (maybe_fold_nontype_arg): Split out from tsubst_copy. * tree.c (get_first_fn): Just return a TEMPLATE_ID_EXPR. Mon Nov 10 20:08:38 1997 Kriang Lerdsuwanakij * pt.c (tsubst_copy): Handle explicit template arguments in function calls. * typeck.c (build_x_function_call): Likewise. * decl2.c (build_expr_from_tree): Lookup function name if it hasn't been done. * pt.c (tsubst): Instantiate template functions properly when template parameter does not appear in function arguments and return type. (comp_template_args): Handle member templates required by tsubst. Mon Nov 10 20:08:38 1997 Jason Merrill * decl.c (grokdeclarator): Tweak conditions for pedwarn in previous change. Mon Nov 10 20:08:29 1997 Bruno Haible * pt.c (coerce_template_parms): Tweak error message. * decl.c (grokdeclarator): If -Wreturn-type, warn everytime a return type defaults to `int', even if there are storage-class specifiers. Mon Nov 10 03:04:20 1997 Jason Merrill Complete nested exception support. * except.c (do_pop_exception): Split out... (push_eh_cleanup): From here. Handle the EH region by hand. (expand_start_catch_block): Add a new level for the catch parm. Move the rethrow region outside the two cleanup regions. Protect the initializer for the catch parm with terminate. (expand_end_catch_block): Likewise. End the region for the eh_cleanup. * exception.cc (__cp_pop_exception): Now takes two parms. Handle popping off the middle of the stack. * tree.c (lvalue_p, real_lvalue_p): Handle TRY_CATCH_EXPR, WITH_CLEANUP_EXPR, and UNSAVE_EXPR. (build_cplus_new): Only wrap CALL_EXPRs. * init.c (expand_default_init): Handle a TRY_CATCH_EXPR around the constructor call. Sun Nov 9 18:00:26 1997 Richard Kenner * Make-lang.in (c++.distdir): Make inc subdirectory. Fri Nov 7 11:57:28 1997 Jason Merrill * decl2.c (finish_file): Put back some code. Thu Nov 6 11:28:14 1997 Jason Merrill * decl2.c (finish_file): Remove redundant code. * method.c (emit_thunk): Don't let the backend defer generic thunks. Wed Nov 5 23:52:50 1997 Jason Merrill * except.c (call_eh_info): Split out... (push_eh_info): From here. (expand_builtin_throw): Use it. (expand_start_catch_block): Move region start back. Tue Nov 4 13:45:10 1997 Doug Evans * lex.c (MULTIBYTE_CHARS): #undef if cross compiling. (real_yylex): Record wide strings using target endianness, not host. 1997-11-03 Brendan Kehoe * repo.c (rindex): Add decl unconditionally. (get_base_filename, open_repo_file): Don't cast rindex. * xref.c (rindex): Add decl unconditionally. (index): Remove unused decl. (open_xref_file): Don't cast rindex. Sun Nov 2 15:04:12 1997 Jason Merrill * class.c (build_vbase_path): Propagate the result type properly. 1997-11-01 Brendan Kehoe * except.c (expand_builtin_throw) [!DWARF2_UNWIND_INFO]: Replace remaining use of saved_throw_type with a call to get_eh_type. 1997-10-31 Brendan Kehoe * lex.c (FILE_NAME_NONDIRECTORY): Delete macro. (file_name_nondirectory): New function, doing the same as the macro. (set_typedecl_interface_info): Use it instead of the macro. (check_newline): Likewise. (handle_cp_pragma): Likewise. * repo.c (get_base_filename): Cast result of rindex to char*. (open_repo_file): Likewise. * xref.c (open_xref_file): Likewise. * error.c (dump_char): Make its arg int, not char. * except.c (push_eh_info): Pass the number of fields - 1 down, not the exact number of fields. Fri Oct 31 01:47:57 1997 Jason Merrill Support for nested exceptions. * tinfo2.cc (__is_pointer): New fn. * exception.cc (struct cp_eh_info): Define. (__cp_exception_info, __uncatch_exception): New fns. (__cp_push_exception, __cp_pop_exception): New fns. * except.c: Lose saved_throw_{type,value,cleanup,in_catch}. Lose empty_fndecl. (init_exception_processing): Likewise. __eh_pc is now external. (push_eh_info): New fn. (get_eh_{info,value,type,caught}): New fns. (push_eh_cleanup): Just call __cp_pop_exception. (expand_start_catch_block): Use push_eh_info. Start the eh region sooner. (expand_end_eh_spec): Use push_eh_info. (expand_throw): Call __cp_push_exception to set up the exception info. Just pass the destructor or 0 as the cleanup. Call __uncatch_exception when we rethrow. (expand_builtin_throw): Don't refer to empty_fndecl. Thu Oct 23 02:01:30 1997 Jason Merrill * pt.c (instantiate_decl): SET_DECL_IMPLICIT_INSTANTIATION on new decl. 1997-10-22 Brendan Kehoe * method.c (build_template_parm_names, build_decl_overload_real): Add static to definitions. * pt.c (add_to_template_args, note_template_header, processing_explicit_specialization, type_unification_real): Likewise. ({determine,check}_explicit_specialization): Use a single string for error messages. Mon Oct 20 12:06:34 1997 Jason Merrill * except.c (expand_exception_blocks): Call do_pending_stack_adjust. (expand_end_catch_block): Likewise. (expand_end_eh_spec): Likewise. Mon Oct 20 11:44:20 1997 Mark Mitchell * decl.c (duplicate_decls): Handle template specializations correctly. * error.c (dump_function_name): Fix printing of specializations of member functions that are not member templates. * cp-tree.h (processing_specialization): Make global. * pt.c (processing_specialization): Likewise. * lex.c (cons_up_default_function): Save and restore processing_specialization to avoid confusion. Mon Oct 20 10:52:22 1997 Jason Merrill * decl.c (init_decl_processing): Give null_node unknown* type. * typeck.c (comp_target_types): Handle UNKNOWN_TYPE. (common_type): Likewise. * error.c (args_as_string): Recognize null_node. Sun Oct 19 09:13:01 1997 Richard Kenner * typeck.c (rationalize_conditional_expr): Handle {MIN,MAX}_EXPR. (unary_complex_lvalue): Call it for {MIN,MAX}_EXPR. * decl.c (init_decl_processing): Call using_eh_for_cleanups. * Make-lang.in (g++): Include prefix.o. Thu Oct 16 15:31:09 1997 Judy Goldberg * pt.c (determine_explicit_specialization): Initialize "dummy" to keep Purify quiet. Thu Oct 16 00:14:48 1997 Jason Merrill * method.c (build_overload_value): Handle TEMPLATE_CONST_PARMs here. (build_overload_int): Not here. Wed Oct 15 00:35:28 1997 Mike Stump * class.c (build_type_pathname): Remove. (prepare_fresh_vtable): Fix problem with complex MI vtable names. 1997-10-14 Brendan Kehoe * parse.y (unary_expr): Give a pedwarn if someone tries to use the &&label GNU extension. Tue Oct 14 12:01:00 1997 Mark Mitchell * decl.c (pushtag): Unset DECL_ASSEMBLER_NAME before setting it, so as to avoid incorrect manglings. * method.c (build_decl_overload_real): Don't mangle return types for constructors. Tue Oct 14 11:46:14 1997 Jason Merrill * cp-tree.h (scratchalloc, build_scratch_list, make_scratch_vec, scratch_tree_cons): Define as macros for now. * call.c, class.c, cvt.c, decl.c, decl2.c, except.c, expr.c, init.c, lex.c, method.c, parse.y, pt.c, rtti.c, search.c, tree.c, typeck.c, typeck2.c: Use them and the expression_obstack variants. Mon Oct 13 17:41:26 1997 Benjamin Kosnik * decl.c (store_return_init): Allow classes with explicit ctors to be used with the named return values extension. Fri Oct 10 12:21:11 1997 Jason Merrill * pt.c (instantiate_decl): Fix previous change. Thu Oct 9 12:08:21 1997 Jason Merrill * pt.c (tsubst): Fix thinko. (instantiate_decl): Really use the original template. * call.c (build_new_method_call): Use simple constructor_name for error messages. Wed Oct 8 22:44:42 1997 Jeffrey A Law * method.c (build_underscore_int): Don't use ANSI specific features. Wed Oct 8 00:18:22 1997 Jason Merrill * decl2.c (finish_prevtable_vardecl): Check DECL_REALLY_EXTERN for our key method; it might have been inlined by -O3. Tue Oct 7 23:00:12 1997 Mark Mitchell * decl.c (make_typename_type): Do not try to call lookup_field for non-aggregate types. Tue Oct 7 22:52:10 1997 Jason Merrill * typeck.c (build_reinterpret_cast): Tweak. Tue Oct 7 22:45:31 1997 Alexandre Oliva * typeck.c (build_reinterpret_cast): Converting a void pointer to function pointer with a reinterpret_cast produces a warning if -pedantic is issued. Tue Oct 7 22:43:43 1997 Bruno Haible * typeck.c (c_expand_return): Don't warn about returning a reference-type variable as a reference. Tue Oct 7 21:11:22 1997 Jason Merrill * method.c (build_static_name): Fix typo. 1997-10-07 Brendan Kehoe * decl.c (duplicate_decls): Make sure DECL_LANG_SPECIFIC is set on OLDDECL before we try to do DECL_USE_TEMPLATE. Tue Oct 7 00:48:36 1997 Jason Merrill * decl.c (duplicate_decls): Don't warn about template instances. * typeck.c (mark_addressable): Lose ancient code that unsets DECL_EXTERNAL. * pt.c (do_decl_instantiation): Lose support for instantiating non-templates. * call.c (build_new_function_call): Fix handling of null explicit template args. (build_new_method_call): Likewise. Mon Oct 6 23:44:34 1997 Mark Mitchell * method.c (build_underscore_int): Fix typo. 1997-10-06 Brendan Kehoe * tree.c (print_lang_statistics): #if 0 call to print_inline_obstack_statistics until its definition is checked in. Mon Oct 6 09:27:29 1997 Jason Merrill * decl2.c (finish_file): Move dump_tree_statistics to end. * pt.c (instantiate_decl): Look for the original template. (tsubst): Set DECL_IMPLICIT_INSTANTIATION on partial instantiations of member templates. Wed Oct 1 08:41:38 1997 Jason Merrill * Makefile.in (g++FAQ.*): New rules. (CONFLICTS): Update. * g++FAQ.texi: Moved from libg++. * parse.y (PFUNCNAME): Only specify the type once. 1997-10-01 Brendan Kehoe * lex.c (real_yylex): Clean up the code to fully behave the way the c-lex.c parser does for complex and real numbers. Tue Sep 30 08:51:36 1997 Jason Merrill * method.c (build_decl_overload_real): Reformat. Tue Sep 30 00:18:26 1997 Jason Merrill * method.c (synthesize_method): If at_eof, determine our linkage. 1997-09-29 Paul Eggert * lex.c (real_yylex): Treat `$' just like `_', except issue a diagnostic if !dollars_in_ident or if pedantic. * lang-specs.h (@c++): -ansi no longer implies -$. * decl2.c (lang_decode_option): -traditional and -ansi now do not mess with dollars_in_ident. Mon Sep 29 19:57:51 1997 H.J. Lu * Makefile.in (parse.o, decl.o): Also depend on $(srcdir)/../except.h $(srcdir)/../output.h. (decl2.o): Also depend on $(srcdir)/../expr.h ../insn-codes.h $(srcdir)/../except.h $(srcdir)/../output.h. (typeck.o, init.o): Also depend on $(srcdir)/../expr.h ../insn-codes.h. * call.c, cp-tree.h, decl.c, tree.c: Finish prototyping. * expr.c (cplus_expand_expr): Make it static. * decl2.c, init.c, typeck.c: Include "expr.h". (expand_expr): Use proper values when calling the function. Mon Sep 29 11:05:54 1997 Alexandre Oliva * lang-options.h: New -Wold-style-cast flag. * cp-tree.h (warn_old_style_cast): New variable. * decl2.c (warn_old_style_cast): Likewise. (lang_decode_option): Support -Wold-style-cast. (reparse_absdcl_as_casts): Produce old-style-cast warning. Mon Sep 29 09:20:53 1997 Benjamin Kosnik * decl.c (cp_finish_decl): Allow expand_aggr_init to set TREE_USED, reset value based on already_used. * init.c (expand_member_init): Revert change. Mon Sep 29 08:57:53 1997 Jason Merrill * cp-tree.h, decl.c, decl2.c, pt.c: Lose DECL_C_STATIC and DECL_PUBLIC. Don't pretend statics are public. * decl2.c (lang_decode_option): Add missing ;. Sat Sep 27 16:22:48 1997 Jason Merrill * friend.c (do_friend): Disable injection for all template-derived decls. * decl2.c (lang_decode_option): Handle -fguiding-decls. * parse.y (notype_template_declarator): New nonterminal. (direct_notype_declarator): Use it. (complex_direct_notype_declarator): Likewise. (object_template_id): Accept any kind of identifier after TEMPLATE. (notype_qualified_id): Don't add template declarators here. Sat Sep 27 16:21:58 1997 Mark Mitchell * call.c (add_template_candidate): Add explicit_targs parameter. (build_scoped_method_call): Use it. (build_overload_call_real): Likewise. (build_user_type_conversion_1): Likewise. (build_new_function_call): Likewise. (build_object_call): Likewise. (build_new_op): Likewise. (build_new_method_call): Likewise. (build_new_function_call): Handle TEMPLATE_ID_EXPR. (build_new_method_call): Likewise. * class.c (finish_struct_methods): Add specialization pass to determine which methods were specializing which other methods. (instantiate_type): Handle TEMPLATE_ID_EXPR. * cp-tree.def (TEMPLATE_ID_EXPR): New tree code. * cp-tree.h (name_mangling_version): New variable. (flag_guiding_decls): Likewise. (build_template_decl_overload): New function. (begin_specialization): Likewise. (reset_specialization): Likewise. (end_specialization): Likewise. (determine_explicit_specialization): Likewise. (check_explicit_specialization): Likewise. (lookup_template_function): Likewise. (fn_type_unification): Add explicit_targs parameter. (type_unification): Likewise. * decl.c (duplicate_decls): Add smarts for explicit specializations. (grokdeclarator): Handle TEMPLATE_ID_EXPR, and function specializations. (grokfndecl): Call check_explicit_specialization. * decl2.c (lang_decode_option): Handle -fname-mangling-version. (build_expr_from_tree): Handle TEMPLATE_ID_EXPR. (check_classfn): Handle specializations. * error.c (dump_function_name): Print specialization arguments. * friend.c (do_friend): Don't call pushdecl for template instantiations. * init.c (build_member_call): Handle TEMPLATE_ID_EXPR. * lang-options.h: Add -fname-mangling-version, -fguiding-decls, and -fno-guiding-decls. * lex.c (identifier_type): Return PFUNCNAME for template function names. * method.c (build_decl_overload_real): New function. (build_template_parm_names): New function. (build_overload_identifier): Use it. (build_underscore_int): New function. (build_overload_int): Use it. Add levels for template parameters. (build_overload_name): Likewise. Also, handle TYPENAME_TYPEs. (build_overload_nested_names): Handle template type parameters. (build_template_decl_overload): New function. * parse.y (YYSTYPE): New ntype member. (nested_name_specifier): Use it. (nested_name_specifier_1): Likewise. (PFUNCNAME): New token. (template_id, object_template_id): New non-terminals. (template_parm_list): Note specializations. (template_def): Likewise. (structsp): Likewise. (fn.def2): Handle member template specializations. (component_decl_1): Likewise. (direct_notype_declarator): Handle template-ids. (component_decl_1): Likewise. (direct_notype_declarator): Handle template-ids. (primary): Handle TEMPLATE_ID_EXPR, and template-ids. * pt.c (processing_specializations): New variable. (template_header_count): Likewise. (type_unification_real): New function. (processing_explicit_specialization): Likewise. (note_template_header): Likewise. (is_member_template): Handle specializations. (end_template_decl): Call reset_specialization. (push_template_decl): Handle member template specializations. (tsubst): Likewise. (tsubst_copy): Handle TEMPLATE_ID_EXPR. (instantiate_template): Handle specializations. (instantiate_decl): Likewise. (fn_type_unification): Handle explicit_targs. (type_unification): Likewise. Allow incomplete unification without an error message, if allow_incomplete. (get_bindings): Use new calling sequence for fn_type_unification. * spew.c (yylex): Handle PFUNCNAME. * tree.c (is_overloaded_fn): Handle TEMPLATE_ID_EXPR. (really_overloaded_fn): Likewise. (get_first_fn): Handle function templates. * typeck.c (build_x_function_call): Use really_overloaded_fn. Handle TEMPLATE_ID_EXPR. (build_x_unary_op): Likewise. (build_unary_op): Likewise. (mark_addressable): Templates whose address is taken are marked as used. 1997-09-25 Andreas Schwab * decl.c (init_decl_processing): Declare __builtin_constant_p as accepting any kind of type, not only int. Fri Sep 26 00:22:56 1997 Jason Merrill * search.c (get_matching_virtual): Notice virtual bases when sorrying about covariant returns. * parse.y (member_init): Also imply typename here. Remove ancient extension for initializing base members. Thu Sep 25 11:11:13 1997 Jason Merrill Handle multi-level typenames and implicit typename in base list. * parse.y (typename_sub{,[0-2]}): New rules. (structsp, rule TYPENAME_KEYWORD): Use typename_sub. (nonnested_type): New rule. (complete_type_name): Use it. (base_class.1): Use typename_sub and nonnested_type. (nested_name_specifier): Don't elide std:: here. * decl.c (make_typename_type): Handle getting a type for NAME. (lookup_name_real): Turn std:: into :: here. Rvalue conversions were removed in London. * call.c (is_subseq): Don't consider lvalue transformations. (build_conv): LVALUE_CONV and RVALUE_CONV get IDENTITY_RANK. (joust): Re-enable ?: kludge. 1997-09-22 Brendan Kehoe * decl.c (start_function): Up warning of no return type to be a pedwarn. Mon Sep 22 14:15:34 1997 Benjamin Kosnik * init.c (expand_member_init): Don't set TREE_USED. * decl.c (cp_finish_decl): Mark decls used if type has TREE_USED set,don't clear TREE_USED wholesale. Sat Sep 20 15:31:00 1997 Jason Merrill * call.c (build_over_call): Do require_complete_type before build_cplus_new. Thu Sep 18 16:47:52 1997 Jason Merrill * search.c (lookup_field): Call complete_type in all cases. * decl.c (finish_function): Just warn about flowing off the end. Wed Sep 17 10:31:25 1997 Jason Merrill * decl.c (grokparms): Don't bash a permanent list node if we're in a function. 1997-09-17 Brendan Kehoe * Makefile.in (CONFLICTS): Fix s/r conflict count to 18. Tue Sep 16 14:06:56 1997 Jason Merrill * call.c (build_new_op): Give better error for syntactically correct, but semantically invalid, use of undeclared template. * call.c (compare_qual): Handle pmfs. * decl.c (store_parm_decls): last_parm_cleanup_insn is the insn after the exception spec. Mon Sep 15 11:52:13 1997 Jason Merrill * call.c (null_ptr_cst_p): Integer type, not integral type. * call.c (joust): Disable warnings until they can be moved to the right place. Fri Sep 12 16:11:13 1997 Per Bothner * Makefile.in, config-lang.in: Convert to autoconf. Thu Sep 11 17:14:55 1997 Jason Merrill * decl.c (lookup_name_real): Add implicit 'typename' to types from base classes. * pt.c (most_specialized_class): Fix typo. (tsubst): Move constant folding to TREE_VEC case. Thu Sep 11 10:08:45 1997 Mark Mitchell * pt.c (do_poplevel): Don't warn about unused local variables while processing_template_decl since we don't always know whether or not they will need constructing/destructing. * pt.c (uses_template_parms): Check the values of an enumeration type to make sure they don't depend on template parms. * decl.c (make_typename_type): Don't lookup the field if the context uses template parms, even if we're not processing_template_decl at the moment. * pt.c (coerce_template_parms): Avoid looking at the TYPE_LANG_DECL portion of a typename type, since there won't be one. (tsubst): Do constant folding as necessary to make sure that arguments passed to lookup_template_class really are constants. Wed Sep 10 11:21:55 1997 Jason Merrill * except.c (expand_builtin_throw): #ifndef DWARF2_UNWIND_INFO. * decl2.c (finish_file): Only register exception tables if we need to. * decl.c (init_decl_processing): Add __builtin_[fs]p. Tue Sep 9 19:49:38 1997 Jason Merrill * pt.c (unify): Just return 0 for a TYPENAME_TYPE. Tue Sep 9 17:57:25 1997 Mark Mitchell * error.c (dump_decl): Avoid crashing when presented with a uninitialized constant, as can occur with a template parameter. (dump_expr): Make sure that there are enough levels of current_template_parms before we start diving through them. 1997-09-09 Brendan Kehoe * typeck.c (build_indirect_ref): Heed FLAG_VOLATILE similar to c-typeck.c. Tue Sep 9 09:36:39 1997 Benjamin Kosnik * except.c (expand_throw): Call build_delete for all exception types, not just objects with destructors. Mon Sep 8 02:33:20 1997 Jody Goldberg * decl.c (current_local_enum): Remove static. * pt.c (tsubst_enum): Save and restore value of current_local_enum in case template is expanded in enum decl. (instantiate_class_template): Use new tsubst_enum signature. (tsubst_expr): Likewise. Mon Sep 8 01:21:43 1997 Mark Mitchell * pt.c (begin_member_template_processing): Take a function as argument, not a set of template arguments. Use the template parameters, rather than the arguments. Handle non-type parameters correctly. Push a binding level for the parameters so that multiple member templates using the same parameter names can be declared. (end_member_template_processing): Pop the binding level. (push_template_decl): Mark member templates as static when appropriate. * lex.c (do_pending_inlines): Pass the function, not its template arguments, to begin_member_template_processing. (process_next_inline): Likewise. (do_pending_defargs): Likewise. * error.c (dump_expr): Obtain the correct declaration for a TEMPLATE_CONST_PARM. * call.c (add_template_conv_candidate): New function. (build_object_call): Handle member templates, as done in the other build_ functions. Sat Sep 6 10:20:27 1997 Mark Mitchell * decl.c (replace_defag): Undo previous change. * lex.c (do_pending_defargs): Deal with member templates. * pt.c (is_member_template): Avoid crashing when passed a non-function argument. Fri Sep 5 17:27:38 1997 Jason Merrill * class.c (grow_method): Remove check for redeclaration. Fri Sep 5 01:37:17 1997 Mark Mitchell * cp-tree.h (INNERMOST_TEMPLATE_PARMS): New macro. (DECL_INNERMOST_TEMPLATE_PARMS): Likewise. (PRIMARY_TEMPLATE_P): Use it. * call.c (build_overload_call_real): Use it. * class.c (instantiate_type): Likewise. * decl.c (decls_match): Likewise. * method.c (build_overload_identifier): Likewise. * pt.c (push_template_decl): Likewise. (classtype_mangled_name): Likewise. (lookup_template_class): Likewise. * cp-tree.h (DECL_NTPARMS): Change name from DECL_NT_PARMS to DECL_NTPARMS to conform to usage elsewhere. * call.c (add_template_candidate): Likewise. * class.c (instantiate_type): Likewise. * pt.c (instantiate_template): Likewise. (get_bindings): Likewise. * class.c (grow_method): Use DECL_FUNCTION_TEMPLATE_P instead of is_member_template. * pt.c (unify): Undo changes to allow multiple levels of template parameters. (type_unification): Likewise. (fn_type_unification): Likewise. (get_class_bindings): Likewise. * cp-tree.h (Likewise). * decl.c (replace_defarg): Check that the type of the default parameter does not invlove a template type before complaining about the initialization. * error.c (dump_expr): Deal with template constant parameters in member templates correctly. * pt.c (is_member_template): Deal with class specializations correctly. (tsubst): Handle "partial instantiation" of member templates correctly. Wed Sep 3 12:30:24 1997 Mark Mitchell * pt.c (type_unification): Change calling sequence to allow for multiple levels of template parameters. (tsubst_expr): Likewise. (tsubst): Likewise. (tsubst_copy): Likewise. (instantiate_template): Likewise. (unify): Likewise. * call.c (build_overload_call_real): Use it. (add_builtin_candidate): Use it. (build_new_method_call): Use it. * class.c (instantiate_type): Use it. * decl.c (grokdeclarator): Use it. * decl2.c (finish_file): Use it. * method.c (build_overload_identifier): Use it. * call.c (add_template_candidate): Add additional parameter for the function return type. Call fn_type_unification istead of type_unification. (build_user_type_conversion_1): Handle member templates. (build_new_function_call): Likewise. (build_new_op): Likewise. (build_new_method_call): Likewise. * class.c (grow_method): Don't give an error message indicating that two member templates with the same name are ambiguous. (finish_struct): Treat member template functions just like member functions. * cp-tree.h (check_member_template): Add declaration. (begin_member_template_processing): Likewise. (end_member_template_processing): Likewise. (fn_type_unification): Likewise. (is_member_template): Likewise. (tsubst): Change prototype. (tsubst_expr): Likewise. (tsubst_copy): Likewise. (instantiate_template): Likewise. (get_bindings): Likewise. * decl.c (decls_match): Handle multiple levels of template parameters. (pushdecl): Handle template type params just like other type declarations. (push_class_level_binding): Return immediately if the class_binding_level is NULL. (grokfndecl): If check_classfn() returns a member_template, use the result of the template, not the template itself. * decl2.c (check_member_template): New function. Check to see that the entity declared to be a member template can be one. (check_classfn): Allow redeclaration of member template functions with different types; the new functions can be specializations or explicit instantiations. * error.c (dump_decl): Handle multiple levels of template parameters. (dump_function_decl): Update to handle function templates. * lex.c (do_pending_inlines): Set up template parameter context for member templates. (process_next_inline): Likewise. * method.c (build_overload_identifier): Adjust for multiple levels of template parameters. * parse.y (fn.def2): Add member templates. (component_decl_1): Likewise. * pt.c (begin_member_template_processing): New function. (end_member_template_processing): Likewise. (is_member_template): Likewise. (fn_type_unification): Likewise. (current_template_parms): Return a vector of all the template parms, not just the innermost level of parms. (push_template_decl): Deal with the possibility of member templates. (lookup_template_class): Likewise. (uses_template_parms): Likewise. (tsubst): Modify processing to TEMPLATE_TYPE_PARM and TEMPLATE_CONST_PARM to deal with multiple levels of template arguments. Add processing of TEMPLATE_DECL to produce new TEMPLATE_DECLs from old ones. (do_decl_instantiation): Handle member templates. * search.c (lookup_fnfields_1): Handle member template conversion operators. * tree.c (cp_tree_equal): Check the levels, as well as the indices, of TEMPLATE_CONST_PARMs. * typeck.c (comptypes): Check the levels, as well as the indices, fo TEMPLATE_TYPE_PARMs. (build_x_function_call): Treat member templates like member functions. Wed Sep 3 11:09:25 1997 Jason Merrill * typeck.c (c_expand_return): Always convert_for_initialization before checking for returning a pointer to local. * pt.c (type_unification): If strict and the function parm doesn't use template parms, just compare types. Wed Sep 3 10:35:49 1997 Klaus Espenlaub * method.c (build_overloaded_value): Replace direct call to the floating point emulator with REAL_VALUE_TO_DECIMAL macro. Wed Sep 3 00:02:53 1997 Jason Merrill * typeck.c (convert_arguments): Don't arbitrarily choose the first of a set of overloaded functions. Tue Sep 2 12:09:13 1997 Jason Merrill * lex.c (real_yylex): Don't elide __FUNCTION__. * method.c (build_overload_value): Add in_template parm. (build_overload_int): Likewise. (build_overload_identifier): Pass it. * decl.c (duplicate_decls): Don't bash a previous template definition with a redeclaration. * pt.c (unify): float doesn't match double. * pt.c (do_type_instantiation): Handle getting a _TYPE or a TYPE_DECL. Handle getting non-template types. * parse.y (explicit_instantiation): Use typespec instead of aggr template_type. Tue Sep 2 10:27:08 1997 Richard Henderson * typeck.c (build_ptrmemfunc1): Clean up ptr->int cast warnings. Mon Sep 1 13:19:04 1997 Eugene Mamchits * call.c (add_builtin_candidate): Add missing TREE_TYPE. (compare_ics): Likewise. Mon Sep 1 13:19:04 1997 Jason Merrill * call.c (joust): Warn about choosing one conversion op over another because of 'this' argument when the other return type is better. (source_type): New fn. * call.c (build_new_op): Strip leading REF_BIND from first operand to builtin operator. * decl2.c (mark_vtable_entries): Mark abort_fndecl as used when we use its RTL. Thu Aug 28 09:45:23 1997 Jason Merrill * call.c (null_ptr_cst_p): Remove support for (void*)0. Wed Aug 27 02:03:34 1997 Jeffrey A Law * typeck.c (expand_target_expr): Make definition match declaration. * class.c (get_basefndecls): Make definition match declaration. Mon Aug 25 14:30:02 1997 Jason Merrill * input.c (sub_getch): Eventually give up and release the input file. * decl.c (cp_finish_decl): If #p i/i, put inline statics in the right place. * call.c (joust): Tweak message. Sat Aug 23 18:02:59 1997 Mark Mitchell * error.c (type_as_string): Put const/volatile on template type parameters where appropriate. Sat Aug 23 17:47:22 1997 Jeffrey A Law * call.c (strictly_better): Make arguments unsigned ints. Thu Aug 21 18:48:44 1997 Jason Merrill * lex.c (real_yylex): Refer to __complex instead of complex. Thu Aug 21 22:25:46 1997 J"orn Rennecke * lex.c (real_yylex): Don't use getc directly. Wed Aug 20 17:25:08 1997 Jason Merrill * call.c (is_subseq): Don't try to be clever. Wed Aug 20 03:13:36 1997 H.J. Lu (hjl@gnu.ai.mit.edu) * parse.y, pt.c: Include "except.h". * call.c, class.c, class.h, cp-tree.h, cvt.c, decl.c, decl2.c, error.c, except.c, expr.c, friend.c, g++spec.c, init.c, input.c, lex.c, lex.h, method.c, parse.y, pt.c, repo.c, rtti.c, search.c, sig.c, spew.c, tree.c, typeck.c, typeck2.c, xref.c: Finish prototyping. Wed Aug 20 01:34:40 1997 Jason Merrill * decl2.c (mark_vtable_entries): Instead of replacing pure virtuals with a reference to __pure_virtual, copy the decl and change the RTL. Tue Aug 19 02:26:07 1997 Jason Merrill * pt.c (lookup_nested_type_by_name): Handle typedef wierdness. * typeck2.c (my_friendly_abort): Report bugs to egcs-bugs@cygnus.com. * pt.c (instantiate_class_template): Call repo_template_used before finish_prevtable_vardecl. * call.c (is_subseq): New fn. (compare_ics): Use it. * repo.c (finish_repo): Don't crash on no args. * parse.y (named_complex_class_head_sans_basetype): Handle explicit global scope. * decl2.c (handle_class_head): New fn. * pt.c (unify): Add CONST_DECL case. Thu Aug 14 10:05:13 1997 Brendan Kehoe * rtti.c (permanent_obstack): Fix decl to not be a pointer. * cp-tree.h (report_type_mismatch): Add prototype. * call.c (build_overload_call_real): Remove erroneous fourth argument to report_type_mismatch. (build_user_type_conversion_1): Remove erroneous second arg to tourney. (build_new_function_call): Likewise. (build_object_call): Likewise. (build_new_op): Likewise. (build_new_method_call): Likewise. Wed Aug 13 19:19:25 1997 Jason Merrill * error.c (dump_decl): Don't bother processing a function with no DECL_LANG_SPECIFIC. * method.c (emit_thunk): Call init_function_start in the macro case. Wed Aug 13 10:46:19 1997 H.J. Lu (hjl@gnu.ai.mit.edu) * decl2.c (DEFAULT_VTABLE_THUNKS): Define to be 0 if not defined and used to set flag_vtable_thunks. Tue Aug 12 20:13:57 1997 Jason Merrill * parse.y: Don't clear the inlines from their obstack until they've all been processed. * decl.c (duplicate_decls): Don't complain about exception specification mismatch if flag_exceptions is off. Mon Aug 11 15:01:56 1997 Marc Lehmann * Make-lang.in (c++.distclean): Remove g++.c on make distclean. Sun Aug 10 12:06:09 1997 Paul Eggert * cp-tree.h: Replace STDIO_PROTO with PROTO in include files. * cvt.c, error.c, except.c, expr.c, friend.c, init.c, rtti.c: Include before include files that formerly used STDIO_PROTO. * decl.c, g++spec.c, lex.c, method.c, repo.c: Include "config.h" first, as per autoconf manual. Fri Aug 8 11:47:48 1997 Jason Merrill * decl.c (duplicate_decls): Tweak wording. * lex.c (do_pending_defargs): Don't die if we see a default arg that isn't a DEFAULT_ARG. * error.c (dump_expr): Handle DEFAULT_ARG. * decl2.c (lang_decode_option): Handle -fhandle-exceptions. * lang-options.h: Add -fhandle-exceptions. * class.c (build_vtable): Vtables are artificial. (prepare_fresh_vtable): Likewise. Wed Aug 6 11:02:36 1997 Jason Merrill * cvt.c (ocp_convert): After converting to the target type, set LOOKUP_NO_CONVERSION. * call.c (joust): Warn about potentially confusing promotion rules with -Wsign-promo. * cp-tree.h, lang-options.h, decl2.c: Support -Wsign-promo. Tue Aug 5 15:15:07 1997 Michael Meissner * exception.cc: Declare __terminate_func with noreturn attribute. Fri Aug 1 03:18:15 1997 Jason Merrill * parse.y: Break out eat_saved_input, handle errors. (function_try_block): Use compstmt instead of compstmt_or_error. Thu Jul 31 17:14:04 1997 Jason Merrill * tree.c (build_cplus_new): Don't set TREE_ADDRESSABLE. Fri Jul 4 01:45:16 1997 Andreas Schwab * Make-lang.in (cplib2.txt, cplib2.ready): Instead of checking for existence of cc1plus check whether $(LANGUAGES) contains C++. Wed Jul 30 13:04:21 1997 Andreas Schwab * method.c (do_build_copy_constructor): When copying an anonymous union member loop around to handle nested anonymous unions. Use the offset of the member relative to the outer structure, not the union. Tue Jul 29 21:17:29 1997 Jason Merrill * call.c (resolve_args): New fn. (build_new_function_call): Use it. (build_object_call): Likewise. (build_new_method_call): Likewise. Mon Jul 28 16:02:36 1997 Jason Merrill * call.c (build_over_call): tsubst all default parms from templates. Wed Jul 23 13:36:25 1997 Jason Merrill * decl.c (struct cp_function): Add static_labelno. (push_cp_function_context): Save it. (pop_cp_function_context): Restore it. Tue Jul 22 14:43:29 1997 Jason Merrill * typeck.c (build_component_ref_1): Convert from reference. Tue Jul 22 11:06:23 1997 Brendan Kehoe * parse.y (current_declspecs, prefix_attributes): Initialize to NULL_TREE. * parse.y (initdcl0): Make sure CURRENT_DECLSPECS is non-nil before we try to force it to be a TREE_LIST. (decl): Make sure $1.t is non-nil. Sun Jul 20 11:53:07 1997 Jason Merrill * pt.c (uses_template_parms): Handle template first-parse codes. * decl.c (cp_finish_decl): Only warn about user-defined statics. Fri Jul 18 17:56:08 1997 Jason Merrill * pt.c (unify): Handle BOOLEAN_TYPE. * cp-tree.h: Lose PARM_DEFAULT_FROM_TEMPLATE. * pt.c (tsubst): Don't set it. * call.c (build_over_call): Use uses_template_parms. Thu Jul 17 18:06:30 1997 Jason Merrill * method.c (build_overload_nested_name): Use static_labelno instead of var_labelno. (build_qualified_name): New fn. (build_overload_name): Split out from here. (build_static_name): Use build_qualified_name. * decl.c (cp_finish_decl): Statics in extern inline functions have comdat linkage. (start_function): Initialize static_labelno. Thu Jul 17 11:20:17 1997 Benjamin Kosnik * class.c (finish_struct_methods): Add check of warn_ctor_dtor_privacy before "all member functions in class [] are private". Wed Jul 16 23:47:08 1997 Jason Merrill * lex.c (do_scoped_id): convert_from_reference. * init.c (build_offset_ref): Likewise. Wed Jul 16 12:34:29 1997 Benjamin Kosnik * error.c (dump_expr): Check TREE_OPERAND before dump_expr_list. Mon Jul 14 03:23:46 1997 Jason Merrill * typeck.c (get_member_function_from_ptrfunc): Promote index before saving it. Sun Jul 13 00:11:52 1997 Jason Merrill * tree.c (layout_basetypes): Move non-virtual destructor warning. * decl.c (xref_basetypes): Remove non-virtual destructor warning. Sat Jul 12 12:47:12 1997 Jason Merrill * decl.c (grokdeclarator): Call add_defarg_fn for the function type, too. * lex.c (add_defarg_fn): Adjust. (do_pending_defargs): Adjust. Don't skip the first parm. Fri Jul 11 01:39:50 1997 Jason Merrill * decl.c (build_enumerator): Global enumerators are also readonly. * rtti.c (build_dynamic_cast_1): Renamed from build_dynamic_cast. (build_dynamic_cast): Call it and convert_from_reference. * lex.c (add_defarg_fn): New fn. (snarf_defarg): Don't add to defarg_types. (do_pending_defargs): Lose defarg_types. All fns we process now have defargs. * decl.c (grokfndecl): Call add_defarg_fn. * Makefile.in (CONFLICTS): Expect 18 s/r conflicts. * cp-tree.def: Add DEFAULT_ARG. * spew.c (yylex): Call snarf_defarg as appropriate. * parse.y: New tokens DEFARG and DEFARG_MARKER. (defarg_again, pending_defargs, defarg, defarg1): New rules. (structsp): Use pending_defargs. (parms, full_parm): Use defarg. * lex.c (init_lex): Initialize inline_text_firstobj. (do_pending_inlines): Never pass the obstack to feed_input. (process_next_inline): Call end_input instead of restore_pending_input. (clear_inline_text_obstack, reinit_parse_for_expr, do_pending_defargs, finish_defarg, feed_defarg, snarf_defarg, maybe_snarf_defarg): New fns. * input.c (end_input): New fn. (sub_getch): At the end of some fed input, just keep returning EOF until someone calls end_input. Remove 'obstack' field from struct input_source. * decl.c (grokparms): Handle DEFAULT_ARG. (replace_defarg): New fn. * cp-tree.h (DEFARG_LENGTH, DEFARG_POINTER): New macros. Wed Jul 9 13:44:12 1997 Jason Merrill * call.c (implicit_conversion): If nothing else works, try binding an rvalue to a reference. Wed Jul 9 13:04:38 1997 Geoffrey Noer * decl.c (init_decl_processing): Fix Jun 30 patch -- move ifndef for Cygwin32 to include SIGSEGV. Thu Jul 3 01:44:05 1997 Jason Merrill * class.c (finish_struct_1): Only complain about pointers without copy stuff if there are any constructors. * rtti.c (build_dynamic_cast): Call complete_type on the types. * decl.c (grokfndecl): If the function we chose doesn't actually match, die. * decl2.c (grokclassfn): Don't specify 'const int' for the artificial destructor parm. * pt.c (type_unification): If we are called recursively, nothing decays. Mon Jun 30 17:53:21 1997 Geoffrey Noer * decl.c (init_decl_processing): Stop trying to catch signals other than SIGABRT since the Cygwin32 library doesn't support them correctly yet. This fixes a situation in which g++ causes a hang on SIGSEGVs and other such signals in our Win32-hosted tools. Mon Jun 30 14:50:01 1997 Jason Merrill * tree.c (mapcar, case CALL_EXPR): Handle all the parse node data. Fri Jun 27 15:18:49 1997 Jason Merrill * typeck2.c (store_init_value): Always return the value if our type needs constructing. * method.c (hack_identifier): Convert class statics from reference, too. Thu Jun 26 11:44:46 1997 Jason Merrill * Make-lang.in (cplib2.ready): Add $(LANGUAGES) dependency. Thu Jun 19 16:49:28 1997 Mike Stump * typeck.c (c_expand_return): Make sure we clean up temporaries at the end of return x; Thu Jun 19 12:28:43 1997 Brendan Kehoe * lex.c (check_for_missing_semicolon): Also check for CV_QUALIFIER. Tue Jun 17 18:35:57 1997 Mike Stump * except.c (expand_builtin_throw): Add support -fno-sjlj-exceptions -fPIC exception handling on the SPARC. Mon Jun 16 01:24:37 1997 Jason Merrill * repo.c (extract_string): Null-terminate. * cp-tree.h (TI_SPEC_INFO): New macro. (CLASSTYPE_TI_SPEC_INFO): New macro. * pt.c (push_template_decl): Correctly determine # of template parms for partial specs. * call.c (compare_ics): Really fix 'this' conversions. * pt.c (do_decl_instantiation): Don't crash on explicit inst of non-template fn. * pt.c (push_template_decl): Complain about mismatch in # of template parms between a class template and a member template. Sun Jun 15 02:38:20 1997 Jason Merrill * method.c (synthesize_method): You can't call function_cannot_inline_p after finish_function. * decl.c (finish_function): Turn on flag_inline_functions and turn off DECL_INLINE before handing a synthesized method to the backend. Thu Jun 12 17:35:28 1997 Jason Merrill * method.c (synthesize_method): Remove July 30 change to never set DECL_INLINE if at_eof. Thu Jun 12 15:25:08 1997 Mike Stump * xref.c (GNU_xref_member): Ensure that the node has a decl_lang_specific part before checking DECL_FRIEND_P. Thu Jun 12 12:36:05 1997 Jason Merrill * pt.c (instantiate_class_template): Diagnose non-class types used as bases. Wed Jun 11 17:33:40 1997 Jason Merrill * typeck.c (build_conditional_expr): Use convert_for_initialization instead of convert_and_check. Wed Jun 11 12:31:33 1997 Brendan Kehoe * parse.y (typespec): Don't pedwarn for typeof. Tue Jun 10 00:22:09 1997 Jason Merrill * repo.c (finish_repo): Only check changes if we would write a repo file. * call.c (compare_ics): Fix handling of 'this' conversions. * pt.c (do_decl_instantiation): Support static data too. Rename from do_function_instantiation. * cp-tree.h: Adjust. * parse.y: Adjust. * repo.c (extract_string): New fn. (get_base_filename): Use it. (init_repo): Compare old args with current args. Mon Jun 9 14:25:30 1997 Mike Stump * Makefile.in, Make-lang.in: Protect C-ls with a comment character, idea from Paul Eggert . Mon Jun 9 01:52:03 1997 Jason Merrill * typeck.c (c_expand_return): Be more persistent in looking for returned temps. * cvt.c (build_up_reference): Use NOP_EXPR for switching from pointer to reference. * class.c (build_vbase_path): Don't do anything if PATH has no steps. Sun Jun 8 03:07:05 1997 Jason Merrill * init.c (build_member_call, build_offset_ref): Use do_scoped_id instead of do_identifier. * cvt.c (convert): Remove bogosity. Sat Jun 7 20:50:17 1997 Brendan Kehoe * cvt.c (build_up_reference): Do checks of ARGTYPE and TARGET_TYPE before trying to use get_binfo. Fri Jun 6 17:36:39 1997 Jason Merrill * cvt.c (build_up_reference): Call get_binfo to get access control. * decl2.c (import_export_decl): If we don't support weaks, leave statics undefined. Fri Jun 6 15:55:49 1997 Mike Stump * except.c (expand_builtin_throw): Add support for machines that cannot access globals after throw's epilogue when -fno-sjlj-exceptions is used. Thu Jun 5 16:28:43 1997 Jason Merrill * parse.y: 'std::' becomes '::'. * lex.c (real_yylex): Remove 'namespace' warning. * init.c (build_member_call): Ignore 'std::'. (build_offset_ref): Likewise. * decl2.c (do_using_directive): Ignore 'using namespace std;'. (do_toplevel_using_decl): Ignore 'using std::whatever'. * decl.c (push_namespace): Just sorry. (pop_namespace): Nop. (init_decl_processing): Declare std namespace. Tue Jun 3 18:08:23 1997 Jason Merrill * search.c (push_class_decls): A name which ambiguously refers to several instantiations of the same template just refers to the template. Tue Jun 3 12:30:40 1997 Benjamin Kosnik * decl.c (build_enumerator): Fix problem with unsigned long enumerated values being smashed to ints, causing overflow when computing next enumerated value (for enum values around MAX_VAL). Mon Jun 2 17:40:56 1997 Jason Merrill * typeck.c (build_component_ref): Only call mark_used on a decl. Thu May 29 15:54:17 1997 Brendan Kehoe * typeck.c (build_c_cast): Make the check for a ptr to function more specific before possible default_conversion call. Thu May 29 13:02:06 1997 Mike Stump * except.c (expand_exception_blocks): Simplify and fix and make sure we don't end a region in a sequence, as expand_end_bindings doesn't like it. Wed May 28 17:08:03 1997 Mike Stump * except.c (init_exception_processing): Mark terminate as not returning so that the optimizer can optimize better. Tue May 27 19:49:19 1997 Mike Stump * cvt.c (convert): Don't do any extra work, if we can avoid it easily. Tue May 27 18:21:47 1997 Mike Stump * *.[chy]: Change cp_convert to ocp_convert, change convert to cp_convert. convert is now reserved for the backend, and doesn't have the semantics a frontend person should ever want. Fri May 23 10:58:31 1997 Jason Merrill * lang-specs.h: Define __EXCEPTIONS if exceptions are enabled. Lose -traditional support. Thu May 22 15:41:28 1997 Jason Merrill * rtti.c (get_tinfo_var): Use TYPE_PRECISION (sizetype). * parse.y (self_reference): Do it for templates, too. * class.c (pushclass): Don't overload_template_name; the alias generated by build_self_reference serves the same purpose. * tree.c (list_hash): Make static, take more args. (list_hash_lookup): Likewise. (list_hash_add): Make static. (list_hash_canon): Lose. (hash_tree_cons): Only build a new node if one isn't already in the hashtable. (hash_tree_chain): Use hash_tree_cons. * cp-tree.h: Adjust. * decl.c (grokfndecl): Just check IDENTIFIER_GLOBAL_VALUE instead of calling lookup_name. Wed May 21 18:24:19 1997 Jason Merrill * pt.c (instantiate_class_template): TYPE_VALUES for an enum doesn't refer to the CONST_DECLs. Tue May 20 21:09:32 1997 Bob Manson * rtti.c (get_tinfo_var): Either INT_TYPE_SIZE or 32, whichever is bigger. (expand_class_desc): Convert the last argument to a sizetype. Tue May 20 13:55:57 1997 Brendan Kehoe * gxx.gperf (__complex, __complex__, __imag, __imag__, __real, __real__): Add reswords. * hash.h: Regenerate. * lex.h (rid): Add RID_COMPLEX. (RID_LAST_MODIFIER): Set to RID_COMPLEX. * lex.c (init_lex): Add building of RID_COMPLEX. (real_yylex): General cleanup in line with what c-lex.c also has, sans the cruft for traditional; add handling of SPEC_IMAG, complex types, and imaginary numeric constants. * parse.y (REALPART, IMAGPART): Add tokens. (unary_expr): Add REALPART and IMAGPART rules. * cp-tree.h (complex_{integer,float,double,long}_type_node): Declare. * decl.c (complex_{integer,float,double,long}_type_node): Define types. (init_decl_processing): Set up the types. (grokdeclarator): Add handling of RID_COMPLEX. Set and use DEFAULTED_INT instead of EXPLICIT_INT when we default to int type. * call.c (build_new_op): Add REALPART_EXPR and IMAGPART_EXPR cases. * cvt.c (cp_convert): Handle COMPLEX_TYPE. * error.c (dump_type_prefix, dump_type, dump_type_suffix): Add COMPLEX_TYPE case. * method.c (build_overload_name): Add handling of the different COMPLEX_TYPEs, prefixing them with `J'. * pt.c (process_template_parm): Don't let them use a COMPLEX_TYPE as a template parm. (uses_template_parms, tsubst, unify): Add COMPLEX_TYPE case. * tree.c (lvalue_p): Add REALPART_EXPR and IMAGPART_EXPR cases. (mapcar): Handle COMPLEX_CST. * typeck.c (build_binary_op_nodefault): Handle COMPLEX_TYPE. (common_type): Add code for complex types. (build_unary_op): Add REALPART_EXPR and IMAGPART_EXPR cases. (convert_for_assignment): Likewise. (mark_addressable): Add REALPART_EXPR and IMAGPART_EXPR cases. Mon May 19 12:26:27 1997 Jason Merrill * pt.c (tsubst): Don't pass the MINUS_EXPR for an array domain to tsubst_expr, as it might try to do overload resolution. Sat May 17 10:48:31 1997 Jason Merrill * pt.c (instantiate_class_template): Oops. Fri May 16 14:23:57 1997 Jason Merrill * cp-tree.def: Add TAG_DEFN. * pt.c (tsubst_enum): New fn. (instantiate_class_template): Use it. (tsubst_expr): Support TAG_DEFN. (tsubst): Support local enums. (tsubst_copy): Likewise. * decl.c (finish_enum): Likewise. (start_enum): If this is a local enum, switch to permanent_obstack. Wed May 14 19:08:28 1997 Mike Stump * decl.c (store_parm_decls): Set last_parm_cleanup_insn here. (finish_function): Put the base init code for constructors just after the parm cleanup insns. (struct cp_function): Add last_parm_cleanup_insn. (push_cp_function_context): Likewise. (pop_cp_function_context): Likewise. Tue May 13 15:51:20 1997 Jason Merrill * pt.c (tsubst_copy): Handle BIT_NOT_EXPR. Wed May 7 11:17:59 1997 Brendan Kehoe * method.c (emit_thunk) [ASM_OUTPUT_MI_THUNK]: Build up the RTL for THUNK_FNDECL before we switch to temporary allocation. Mon May 5 14:46:53 1997 Jason Merrill * call.c (build_new_op): Handle null arg2 for ?:. Thu May 1 18:26:37 1997 Mike Stump * except.c (expand_exception_blocks): Ensure that we flow through the end of the exception region for the exception specification. Move exception region for the exception specification in, so that it doesn't protect the parm cleanup. Remove some obsolete code. * decl.c (store_parm_decls): Likewise. (finish_function): Likewise. Tue Apr 29 15:38:54 1997 Jason Merrill * init.c (build_new): Fix nothrow handling. Tue Apr 29 14:29:50 1997 Brendan Kehoe * init.c (emit_base_init): Don't warn about the initialization list for an artificial member. Fri Apr 25 17:47:59 1997 Brendan Kehoe * expr.c (do_case): Handle !START case for the error msg. Fri Apr 25 11:55:23 1997 Jason Merrill * decl2.c, lang-options.h: New option -Weffc++. * class.c, decl.c, init.c, typeck.c: Move Effective C++ warnings to -Weffc++. * decl2.c (finish_prevtable_vardecl): Change NO_LINKAGE_HEURISTICS to MULTIPLE_SYMBOL_SPACES. Wed Apr 23 18:06:50 1997 Jason Merrill * method.c (emit_thunk, generic case): Set current_function_is_thunk. * method.c (emit_thunk, macro case): Set up DECL_RESULT. * typeck.c (c_expand_return): Don't complain about returning void to void in an artificial function. * method.c (make_thunk): Change settings of READONLY/VOLATILE, don't set DECL_RESULT, set DECL_ARTIFICIAL. (emit_thunk, generic code): Also set up DECL_LANG_SPECIFIC. Wed Apr 23 14:43:06 1997 Mike Stump * init.c (init_decl_processing): Add support for setjmp/longjmp based exception handling. * except.c (init_exception_processing): Likewise. (expand_end_catch_block): Likewise. (expand_exception_blocks): Likewise. (expand_throw): Likewise. * exception.cc (__default_terminate): Likewise. * init.c (perform_member_init): Use new method of expr level cleanups, instead of cleanups_this_call and friends. (emit_base_init): Likewise. (expand_aggr_vbase_init_1): Likewise. (expand_vec_init): Likewise. * decl.c (cp_finish_decl): Likewise. (expand_static_init): Likewise. (store_parm_decls): Likewise. (cplus_expand_expr_stmt): Likewise. * decl2.c (finish_file): Likewise. * Make-lang.in (exception.o): Ok to compile with -O now. * decl.c (maybe_build_cleanup_1): We no longer have to unsave, as we know it will be done later by the backend. * decl2.c (lang_f_options): Remove support for short temps. * lang-options.h: Likewise. Wed Apr 23 04:12:06 1997 Jason Merrill * tree.c (varargs_function_p): New fn. * method.c (emit_thunk): Replace broken generic code with code to generate a heavyweight thunk function. Tue Apr 22 02:45:18 1997 Jason Merrill * pt.c (process_template_parm): pedwarn about floating-point parms. * decl.c (grokdeclarator): inline no longer implies static. * spew.c (yylex): Always return the TYPE_DECL if we got a scope. Mon Apr 21 15:42:27 1997 Jason Merrill * class.c (check_for_override): The signature of an overriding function is not changed. * call.c (build_over_call): Move setting of conv into the loop. Note: this change, along with the related changes of the 18th thru the 20th of April, fix an infinite loop problem in conversions. Sun Apr 20 16:24:29 1997 Jason Merrill * call.c (build_user_type_conversion_1): Really ignore rvalue conversions when looking for a REFERENCE_TYPE. * cvt.c (build_up_reference): Eviscerate, use build_unary_op. * cp-tree.h (TREE_REFERENCE_EXPR): #if 0. * typeck.c (decay_conversion): Don't set TREE_REFERENCE_EXPR. (build_unary_op): Likewise. * call.c (build_over_call): See through a CONVERT_EXPR around the ADDR_EXPR for on a temporary. * typeck.c (c_expand_return): See through a CONVERT_EXPR around the ADDR_EXPR for a local variable. Fri Apr 18 12:11:33 1997 Jason Merrill * call.c (build_user_type_conversion_1): If we're trying to convert to a REFERENCE_TYPE, only consider lvalue conversions. (build_new_function_call): Print candidates. (implicit_conversion): Try a temp binding if the lvalue conv is BAD. (reference_binding): Binding a temporary of a reference-related type is BAD. Thu Apr 17 14:37:22 1997 Brendan Kehoe * inc/typeinfo (type_info::before): Add cv-qualifier-seq. * tinfo2.cc (type_info::before): Likewise. Mon Apr 14 12:38:17 1997 Jason Merrill * call.c (implicit_conversion): Oops. Fri Apr 11 02:18:30 1997 Jason Merrill * call.c (implicit_conversion): Try to find a reference conversion before binding a const reference to a temporary. Wed Apr 2 12:51:36 1997 Mike Stump * exception.cc (__default_unexpected): Call terminate by default, so that if the user overrides terminate, the correct function will be called. Wed Mar 19 14:14:45 1997 Mike Stump * parse.y (left_curly): Avoid trying to use any fields of error_mark_node, as there aren't any. Thu Mar 13 16:33:22 1997 Jason Merrill * lex.c (do_identifier): Avoid breaking on overloaded methods as default arguments. Wed Mar 12 13:55:10 1997 Hans-Peter Nilsson * call.c (add_template_candidate): Initialize the variable "dummy". Mon Mar 10 15:13:14 1997 Brendan Kehoe * decl.c (start_decl): Make sure TYPE isn't an error_mark_node before we try to use TYPE_SIZE and TREE_CONSTANT on it. Fri Mar 7 13:19:36 1997 Brendan Kehoe * cp-tree.h (comp_ptr_ttypes, more_specialized): Add decl. (debug_binfo): Delete decl, not needed. * tree.c (fnaddr_from_vtable_entry, function_arg_chain, promotes_to_aggr_type): Delete fns. * cp-tree.h (FNADDR_FROM_VTABLE_ENTRY, SET_FNADDR_FROM_VTABLE_ENTRY, FUNCTION_ARG_CHAIN, PROMOTES_TO_AGGR_TYPE): Delete alternates to #if 1. * decl.c (pending_invalid_xref{,_file,_line}): Delete unused vars. * friend.c (is_friend_type): Delete fn. * cp-tree.h (is_friend_type): Delete decl. * decl.c (original_result_rtx, double_ftype_double, double_ftype_double_double, int_ftype_int, long_ftype_long, float_ftype_float, ldouble_ftype_ldouble, last_dtor_insn): Make static. * typeck.c (original_result_rtx, warn_synth): Delete extern decls. * decl.c (push_overloaded_decl{,_top_level}): Make static, adding fwd decls. * cp-tree.h (push_overloaded_decl{,_top_level}): Delete decls. * decl.c (pushdecl_nonclass_level): #if 0, unused. * cp-tree.h (pushdecl_nonclass_level): #if 0 decl. * lex.c (reinit_lang_specific): #if 0, unused. * cp-tree.h (reinit_lang_specific): #if 0 decl. * decl.c (revert_static_member_fn): Make static, adding fwd decl. * cp-tree.h (revert_static_member_fn): Delete decl. * class.c (root_lang_context_p): Delete fn. * cp-tree.h (root_lang_context_p): Delete decl. * decl.c (set_current_level_tags_transparency): #if 0, unused. * cp-tree.h (set_current_level_tags_transparency): #if 0 decl. * lex.c (set_vardecl_interface_info): Make static. * cp-tree.h (set_vardecl_interface_info): Delete decl. * call.c (find_scoped_type): Make static. * cp-tree.h (find_scoped_type): Delete decl. * search.c (convert_pointer_to_vbase): Make static. * cp-tree.h (convert_pointer_to_vbase): Delete decl. * decl.c (const_ptr_type_node): Likewise. * cp-tree.h (const_ptr_type_node): Delete decl. * typeck.c (common_base_type): Make static. * cp-tree.h (common_base_types): Delete erroneous decl. * pt.c (classtype_mangled_name): Make static. * cp-tree.h (classtype_mangled_name): Delete decl. * lex.c (check_newline): Make static. * cp-tree.h (check_newline): Delete decl. * typeck.c (build_x_array_ref): Delete fn, same idea as grok_array_decl. * cp-tree.h (build_x_array_ref): Delete decl. * lex.c (copy_decl_lang_specific): Delete fn, same idea as copy_lang_decl. * cp-tree.h (copy_decl_lang_specific): #if 0 decl. * class.c (build_vtable_entry): Make static. * cp-tree.h (build_vtable_entry): Delete decl. * class.c (build_vbase_pointer): Make static. * cp-tree.h (build_vbase_pointer): Delete decl. * sig.c (build_sptr_ref): Add forward decl and make static. * cp-tree.h (build_sptr_ref): Delete decl. * call.c (build_new_method_call): Add forward decl and make static. * cp-tree.h (build_new_method_call): Delete decl. * call.c (build_object_call): Make static. * class.c (check_for_override, complete_type_p, mark_overriders): Likewise. * decl.c (cp_function_chain): Likewise. * lex.c (set_typedecl_interface_info, reinit_parse_for_block): Likewise. * pt.c (comp_template_args, get_class_bindings, push_tinst_level): Likewise. * tree.c (build_cplus_array_type_1): Likewise. * typeck.c (comp_ptr_ttypes_{const,real,reinterpret}): Likewise. (comp_target_parms): Likewise. * init.c (build_builtin_call): Make static. * cp-tree.h (build_builtin_call): Delete decl. * typeck.c (binary_op_error): Delete decl. * cp-tree.h (binary_op_error): Likewise. Thu Mar 6 16:13:52 1997 Brendan Kehoe * call.c (build_method_call): Compare against error_mark_node directly, rather than the ERROR_MARK tree code. * cvt.c (cp_convert): Likewise. * decl.c (print_binding_level): Likewise. (duplicate_decls): Likewise. (grokdeclarator): Likewise. (grokdeclarator): Likewise. * init.c (expand_aggr_init_1): Likewise. (decl_constant_value): Likewise. * method.c (build_opfncall): Likewise. (hack_identifier): Likewise. * typeck.c (build_modify_expr): Likewise. * typeck.c (build_c_cast): Don't decl TYPE as register tree. Sun Mar 2 02:54:36 1997 Bruno Haible * pt.c (unify): Strip NOP_EXPR wrappers before unifying integer values. * pt.c (coerce_template_parms): Add new error message. * method.c (build_overload_value): Implement name mangling for floating-point template arguments. * method.c (build_overload_int, icat, dicat): Fix mangling of template arguments whose absolute value doesn't fit in a signed word. Mon Mar 3 12:14:54 1997 Brendan Kehoe * friend.c: New file; put all of the friend stuff in here. * init.c: Instead of here. * Makefile.in (CXX_OBJS): Add friend.o. (friend.o): Add dependencies. * Make-lang.in (CXX_SRCS): Add $(srcdir)/cp/friend.c. Sun Mar 2 11:04:43 1997 Jason Merrill * call.c (build_scoped_method_call): Complain if the scope isn't a base. Wed Feb 26 11:31:06 1997 Jason Merrill * parse.y (left_curly): Don't crash on erroneous type. * init.c (build_delete): Fix type of ref. Tue Feb 25 12:41:48 1997 Jason Merrill * search.c (get_vbase_1): Renamed from get_vbase. (get_vbase): Wrapper, now non-static. (convert_pointer_to_vbase): Now static. * call.c (build_scoped_method_call): Accept a binfo for BASETYPE. * init.c (build_delete): Pass one. (build_partial_cleanup_for): Use build_scoped_method_call. * decl.c (finish_function): Pass a binfo. Mon Feb 24 15:00:12 1997 Jason Merrill * call.c (build_over_call): Only synthesize non-trivial copy ctors. * typeck.c (build_c_cast): Lose other reference to flag. * call.c (build_field_call): Don't look for [cd]tor_identifier. * decl2.c (delete_sanity): Remove meaningless use of LOOKUP_HAS_IN_CHARGE. * decl.c (finish_function): Use build_scoped_method_call instead of build_delete for running vbase dtors. * init.c (build_delete): Call overload resolution code instead of duplicating it badly. Thu Feb 20 15:12:15 1997 Jason Merrill * call.c (build_over_call): Call mark_used before trying to elide the call. * decl.c (implicitly_declare): Don't set DECL_ARTIFICIAL. Wed Feb 19 11:18:53 1997 Brendan Kehoe * typeck.c (build_modify_expr): Always pedwarn for a cast to non-reference used as an lvalue. Wed Feb 19 10:35:37 1997 Jason Merrill * cvt.c (cp_convert_to_pointer): Convert from 0 to a pmf properly. Tue Feb 18 15:40:57 1997 Jason Merrill * parse.y (handler): Fix template typo. Sun Feb 16 02:12:28 1997 Jason Merrill * error.c (lang_decl_name): New fn. * tree.c (lang_printable_name): Use it. Fri Feb 14 16:57:05 1997 Mike Stump * g++spec.c: Include config.h so that we can catch bzero #defines from the config file. Tue Feb 11 13:50:48 1997 Mike Stump * new1.cc: Include a declaration for malloc, to avoid warning, and avoid lossing on systems that require one (ones that define malloc in xm.h). Mon Feb 10 22:51:13 1997 Bruno Haible * decl2.c (max_tinst_depth): New variable. (lang_decode_option): Parse "-ftemplate-depth-NN" command line option. * pt.c (max_tinst_depth): Variable moved. * lang-options.h: Declare "-ftemplate-depth-NN" command line option as legal. Fri Feb 7 15:43:34 1997 Jason Merrill * decl.c (xref_basetypes): Allow a base class that depends on template parms to be incomplete. * decl2.c (build_expr_from_tree): Support typeid(type). * rtti.c (get_typeid): Support templates. (expand_si_desc, expand_class_desc): Fix string length. (expand_ptr_desc, expand_attr_desc, expand_generic_desc): Likewise. Tue Feb 4 11:28:24 1997 Jason Merrill * pt.c (unify, case TEMPLATE_CONST_PARM): Use cp_tree_equal. * pt.c (tsubst): Put it back for -fno-ansi-overloading. Mon Feb 3 18:41:12 1997 Jason Merrill * pt.c (tsubst, case FUNCTION_DECL): Lose obsolete code that smashes together template and non-template decls of the same signature. Thu Jan 30 19:18:00 1997 Jason Merrill * pt.c (tsubst): Don't recurse for the type of a TYPENAME_TYPE. Wed Jan 29 11:40:35 1997 Brendan Kehoe * decl.c (duplicate_decls): Next route, pedwarn about different exceptions if -pedantic *or* olddecl !DECL_IN_SYSTEM_HEADER. Tue Jan 28 20:43:29 1997 Brendan Kehoe * cp-tree.h (HAS_DEFAULT_IMPLEMENTATION): Delete macro. (struct lang_type): Delete has_default_implementation member. Increase dummy to 21. * decl.c (start_method): Delete usage. * cp-tree.h (build_call, null_ptr_cst_p, in_function_p, store_after_parms, start_decl_1, auto_function): Add decls. (get_arglist_len_in_bytes, declare_implicit_exception, have_exceptions_p, make_type_decl, typedecl_for_tag, store_in_parms, pop_implicit_try_blocks, push_exception_cleanup, build_component_type_expr, cplus_exception_name, {make,clear}_anon_parm_name, dont_see_typename): Removed decls. * call.c (build_this): Make static. (is_complete): Likewise. (implicit_conversion): Likewise. (reference_binding): Likewise. (standard_conversion): Likewise. (strip_top_quals): Likewise. (non_reference): Likewise. (build_conv): Likewise. (user_harshness): Likewise. (rank_for_ideal): Likewise. * decl.c (start_decl_1): Delete forward decl. (push_decl_level): Make static. (resume_binding_level): Make static. (namespace_bindings_p): Make static. (declare_namespace_level): Make static. (lookup_name_real): Make static. (duplicate_decls): Make static. Take register off NEWDECL and OLDDECL parm decls. * decl2.c (get_sentry): Make static. (temp_name_p): Delete fn. * except.c (auto_function): Delete decl. * lex.c (handle_{cp,sysv}_pragma): Make static. (handle_sysv_pragma) [HANDLE_SYSV_PRAGMA]: Add forward decl. * method.c (do_build_{copy_constructor,assign_ref}): Make static. * pt.c (tsubst_expr_values): Make static. * rtti.c (combine_strings): Delete decl. Tue Jan 28 16:40:40 1997 Jason Merrill * pt.c (push_template_decl): Handle getting a typedef. * call.c (build_new_function_call): Complain about void arg. Tue Jan 28 15:25:09 1997 Brendan Kehoe * decl.c (duplicate_decls): Give pedwarn of different exceptions if -pedantic, instead of olddecl !DECL_IN_SYSTEM_HEADER. Mon Jan 27 19:21:29 1997 Mike Stump * except.c (expand_throw): Don't expand the cleanup tree here, since we are not going to write the rtl out. Fixes problem with -g -O on SPARC. Mon Jan 27 16:24:35 1997 Sean McNeil * Make-lang.in: Add $(exeext) as necessary. Mon Jan 27 13:20:39 1997 Mike Stump * parse.y (handler_seq): Must have at least one catch clause. Sat Jan 25 12:00:05 1997 Jason Merrill * call.c (add_builtin_candidate): Restore ?: hack. * decl.c (grok_op_properties): More warnings. Sat Jan 25 08:50:03 1997 Brendan Kehoe * decl.c (duplicate_decls): On second thought, do it as a pedwarn still but only if !DECL_IN_SYSTEM_HEADER (olddecl). * decl.c (duplicate_decls): Scale back to a warning, and only do 'em if -pedantic. Fri Jan 24 17:52:54 1997 Mike Stump * decl.c (duplicate_decls): pedwarn mismatched exception specifications. Thu Jan 23 18:18:54 1997 Mike Stump * call.c (build_new_method_call): Don't display the invisible argument for controlling virtual bases. Thu Jan 23 16:48:10 1997 Mike Stump * new: Add nothrow new and delete, bad_alloc and throw specifications for delete. * decl.c (init_decl_processing): Add throw specification for delete. * new.cc (nothrow): Define. * lex.c (real_yylex): Removing warning that throw and friends are keywords. * new1.cc (operator new (size_t sz, const nothrow_t&)): Define. * new2.cc (operator new[] (size_t sz, const nothrow_t&): Define. * Make-lang.in: Add new{1,2}.{cc,o}. Thu Jan 23 16:39:06 1997 Jason Merrill * lex.c (cons_up_default_function): Fix return type of synth op=. * init.c (emit_base_init): Add warnings for uninitialized members and bases. * decl.c (xref_basetypes): Add warning for non-polymorphic type with destructor used as base type. * decl.c (grok_op_properties): Add warning for op= returning void. * typeck.c (c_expand_return): Add warning for op= returning anything other than *this. * class.c (finish_struct_1): Add warning for class with pointers but not copy ctor or copy op=. * cp-tree.h (TI_PENDING_TEMPLATE_FLAG): New macro. * pt.c (add_pending_template): Use it instead of LANG_FLAG_0. (instantiate_template): If -fexternal-templates, add this instantiation to pending_templates. * decl2.c (copy_assignment_arg_p): Disable old hack to support Booch components. Tue Jan 21 18:32:04 1997 Mike Stump * cvt.c (cp_convert): pedwarn enum to pointer conversions. Mon Jan 20 17:59:51 1997 Jason Merrill * call.c (standard_conversion): Handle getting references. Tack on RVALUE_CONV here. Do it for non-class types, too. (reference_binding): Pass references to standard_conversion. (implicit_conversion): Likewise. (add_builtin_candidate): Disable one ?: kludge. (convert_like): Handle RVALUE_CONVs for non-class types. (joust): Disable the other ?: kludge. Mon Jan 20 14:53:13 1997 Brendan Kehoe * decl.c (init_decl_processing): Add code to build up common function types beforehand, to avoid creation then removal of things already in the hash table. Mon Jan 20 14:43:49 1997 Jason Merrill * decl.c (finish_function): Also zero out DECL_INCOMING_RTL for the arguments. * error.c (dump_expr, TEMPLATE_CONST_PARM): Don't require current_template_parms. Fri Jan 17 10:25:42 1997 Jason Merrill * search.c (lookup_field): Don't return a function, check want_type. Thu Jan 16 18:14:35 1997 Brendan Kehoe * init.c (build_new): Make sure PLACEMENT has a type. Thu Jan 16 17:40:28 1997 Jason Merrill * init.c (build_new): Support new (nothrow). Wed Jan 15 12:38:14 1997 Jason Merrill * pt.c (instantiate_decl): Also do push_to_top_level before setting up DECL_INITIAL. * cp-tree.h (PARM_DEFAULT_FROM_TEMPLATE): New macro. * pt.c (tsubst): Defer instantiation of default args. * call.c (build_over_call): Until here. Wed Jan 15 10:08:10 1997 Brendan Kehoe * search.c (lookup_field): Make sure we have an IDENTIFIER_CLASS_VALUE before we try to return it. Thu Jan 9 07:19:01 1997 Brendan Kehoe * call.c (build_method_call): Delete unused var PARM. (build_overload_call_real): Likewise. (build_object_call): Delete unused var P. (build_new_op): Likewise. * decl.c (builtin_type_tdescs_{arr, len, max}): #if 0 out static var definitions, which are never used. (shadow_tag): Delete unused var FN. * expr.c (cplus_expand_expr): Delete unused var ORIGINAL_TARGET. * init.c (build_new): Delete unused var ALLOC_TEMP. * method.c (hack_identifier): Delete unused var CONTEXT. (do_build_copy_constructor): Delete unused var NAME. (synthesize_method): Delete unused var BASE. * pt.c (lookup_template_class): Delete unused var CODE_TYPE_NODE. * rtti.c (build_headof): Delete unused var VPTR. (get_typeid): Delete unused var T. * typeck.c (build_conditional_expr): Delete unused vars ORIG_OP1 and ORIG_OP2. (build_ptrmemfunc): Delete unused vars U and NINDEX. * typeck2.c (build_functional_cast): Delete unused var BINFO. Wed Jan 8 13:09:54 1997 Jason Merrill * search.c (lookup_field): Use IDENTIFIER_CLASS_VALUE to look up things in a type being defined. * decl.c (finish_enum): Reverse the values so that they are in the correct order. * pt.c (instantiate_class_template): Don't initialize BINFO_BASETYPES until the vector is filled out. (unify): Don't abort on conflicting bindings, just fail. (instantiate_decl): Do push_tinst_level before any tsubsting. * method.c (build_overload_value): Handle getting a TEMPLATE_CONST_PARM for a pointer. Tue Jan 7 14:00:58 1997 Jason Merrill * init.c (expand_member_init): Don't give 'not a base' error for templates. * pt.c (instantiate_decl): Call import_export_decl later. * pt.c (instantiate_class_template): Return a value. * parse.y (extension): New rule for __extension__. (extdef, unary_expr, decl, component_decl): Use it. Tue Jan 7 09:20:28 1997 Mike Stump * class.c (base_binfo): Remove unused base_has_virtual member. (finish_base_struct): Likewise. (finish_struct_1): Likewise. Tue Dec 31 20:25:50 1996 Mike Stump * search.c (expand_upcast_fixups): Fix bogus code generation problem where the generated code uses the wrong index into the runtime built vtable on the stack. Old code could clobber random stack values. Tue Dec 31 15:16:56 1996 Mike Stump * init.c (perform_member_init): Make sure the partial EH cleanups live on the function_obstack. Fri Dec 27 10:31:40 1996 Paul Eggert * Make-lang.in (g++spec.o): Don't use $< with an explicit target; this isn't portable to some versions of `make' (e.g. Solaris 2.5.1). Tue Dec 24 10:24:03 1996 Jeffrey A Law * decl.c (grokvardecl): Avoid ANSI style initialization. Sun Dec 22 04:22:06 1996 Jason Merrill * pt.c (tsubst): Tweak arg types for a FUNCTION_TYPE. Fri Dec 20 17:09:25 1996 Jason Merrill * pt.c (instantiate_class_template): Call grok_{ctor,op}_properties. Fri Dec 20 12:17:12 1996 Brendan Kehoe * g++spec.c (lang_specific_driver): Put missing hyphen in front of arguments we compare against. Start the count of I at 1, not 0, since argv[0] is still the command. Thu Dec 19 11:53:57 1996 Stan Shebs * lang-specs.h: Accept .cp as an C++ extension. Mon Dec 16 22:43:31 1996 Brendan Kehoe * cp-tree.h (ptr_reasonably_similar): Add decl. Thu Dec 12 15:00:35 1996 Brendan Kehoe * decl.c (grokvardecl): Change SPECBITS parm to be the SPECBITS_IN pointer. New local SPECBITS with the parm's value. (grokdeclarator): Pass &specbits down. * parse.y (expr_no_commas): Make sure $$ is not an error_mark_node before we try to do C_SET_EXP_ORIGINAL_CODE on it. * search.c (envelope_add_decl): Check that the CLASSTYPE_CID of CONTEXT is not 0 before we try to use TYPE_DERIVES_FROM. * decl.c (cplus_expand_expr_stmt): Only expand the expr if EXP is not an error_mark_node. Sat Dec 7 17:20:22 1996 Jason Merrill * cp-tree.h (TYPE_MAIN_DECL): Use TYPE_STUB_DECL. * *.c: Use TYPE_MAIN_DECL instead of TYPE_NAME where appropriate. Fri Dec 6 14:40:09 1996 Jason Merrill * decl.c (grokdeclarator): When giving an anonymous struct a name, replace TYPE_NAME instead of TYPE_IDENTIFIER (so TYPE_STUB_DECL is not affected). * typeck2.c (build_m_component_ref): If component is a pointer to data member, resolve the OFFSET_REF now. * call.c (convert_like): Don't go into infinite recursion. * pt.c (coerce_template_parms): Use tsubst_expr for non-type args. * class.c (finish_struct_1): Set DECL_ARTIFICIAL on the vptr. * tree.c (layout_basetypes): And on the vbase ptr. Thu Dec 5 02:11:28 1996 Jason Merrill * decl.c (BOOL_TYPE_SIZE): Define in terms of POINTER_SIZE or CHAR_TYPE_SIZE so bool is always the same size as another type. * decl.c (pushtag): Set DECL_IGNORED_P for DWARF, too. Tue Dec 3 23:18:37 1996 Jason Merrill * decl2.c (grok_x_components): Remove synthesized methods from TYPE_METHODS of an anonymous union, complain about member functions. * decl.c (shadow_tag): Wipe out memory of synthesized methods in anonymous unions. (finish_function): Just clear the DECL_RTL of our arguments. Fri Nov 29 21:54:17 1996 Jason Merrill * decl2.c (finish_file): Emit DWARF debugging info for static data members. * pt.c (tsubst): If t is a stub decl, return the stub decl for type. Wed Nov 27 14:47:15 1996 Bob Manson * typeck.c (build_component_ref): Don't die if COMPONENT isn't a IDENTIFIER_NODE. Wed Nov 27 16:05:19 1996 Michael Meissner * Make-lang.in (g++-cross$(exeext)): Fix typo. Wed Nov 27 08:14:00 1996 Brendan Kehoe Make the g++ driver now be a standalone program, rather than one that tries to run the gcc driver after munging up the options. * Make-lang.in (g++.c, g++spec.o): New rules. (g++.o): New rule, based on gcc.o with -DLANG_SPECIFIC_DRIVER added. (g++$(exeext)): New rule, based on xgcc rule. (g++-cross$(exeext)): Now just copies g++$(exeext) over. * g++spec.c: New file. * g++.c: Removed file. Tue Nov 26 19:01:09 1996 Mike Stump * cvt.c (build_up_reference): Arrange for any temporary values that have been keep in registers until now to be put into memory. Mon Nov 25 15:16:41 1996 Kaveh R. Ghazi * Make-lang.in (c++.stage[1234]): Depend upon stage[1-4]-start, so that make -j3 bootstrap works better. Sun Nov 24 02:09:39 1996 Jason Merrill * decl.c (pushtag): Do pushdecl for anon tags. Thu Nov 21 16:30:24 1996 Jason Merrill * typeck.c (c_expand_return): Fix logic. (unary_complex_lvalue): Avoid unused warning on address of INIT_EXPR. Wed Nov 20 18:47:31 1996 Bob Manson * g++.c (main): Make sure arglist has a final NULL entry. Add PEXECUTE_LAST to the flags passed to pexecute, as otherwise stdin/stdout of the invoked program are redirected to nowheresville. Tue Nov 19 16:12:44 1996 Jason Merrill * decl.c (implicitly_declare): Set DECL_ARTIFICIAL. Tue Nov 19 15:48:19 1996 Mike Stump * init.c (resolve_offset_ref): Handle obj.vfn better. * typeck.c (build_component_ref): Set TREE_TYPE on result from build_vfn_ref. Tue Nov 19 13:14:33 1996 Mike Stump * typeck.c (convert_for_assignment): Also handle anachronistic implicit conversions from (::*)() to cv void*. * cvt.c (cp_convert_to_pointer): Likewise. Mon Nov 18 17:05:26 1996 Jason Merrill * lex.c (handle_cp_pragma): Fix bogus warning. Mon Nov 18 16:10:43 1996 Mike Stump * cvt.c (cp_convert_to_pointer): Avoid thinking a POINTER_TYPE (METHOD_TYPE) is a TYPE_PTRMEMFUNC_P. Thu Nov 14 23:18:17 1996 Jason Merrill * class.c (finish_struct_1): Support DWARF2_DEBUG. * search.c (dfs_debug_mark): Likewise. * decl2.c (finish_vtable_vardecl): Likewise. * decl.c (pushtag, finish_enum): Likewise. * lex.c (check_newline): Use debug_* instead of calling *out functions directly. Thu Nov 14 15:21:46 1996 Brendan Kehoe * Make-lang.in (cplib2.ready): Add else clause to avoid problems on some picky hosts. Wed Nov 13 12:32:07 1996 Jason Merrill * class.c (finish_struct_1): A class has a non-trivial copy constructor if it has virtual functions. * cvt.c (cp_convert): Always call a constructor. * call.c (reference_binding): Still tack on a REF_BIND for bad conversions. (build_user_type_conversion_1): Propagate ICS_BAD_FLAG. * typeck.c (convert_arguments): Pass LOOKUP_ONLYCONVERTING. (c_expand_return): Likewise. * typeck2.c (digest_init): Likewise for { }. * init.c (expand_aggr_init_1): Keep the CONSTRUCTOR handling. * cvt.c (cp_convert): Handle failure better. Wed Nov 13 11:51:20 1996 Brendan Kehoe * g++.c (main): Also set PEXECUTE_SEARCH, to make the invocation of GCC be path-relative. Wed Nov 13 11:27:16 1996 Michael Meissner * Make-lang.in (g++-cross): G++-cross doesn't need version.o, but it does need choose-temp.o and pexecute.o. Wed Nov 13 07:53:38 1996 Brendan Kehoe * g++.c (error) [!HAVE_VPRINTF]: Put error back for the only time that we still use it. (P_tmpdir, R_OK, W_OK, X_OK) [__MSDOS__]: Delete unnecessary macros. Wed Nov 13 02:00:26 1996 Jason Merrill * init.c (expand_default_init): Avoid calling constructors to initialize reference temps. * cvt.c (convert_to_reference): Fix. Tue Nov 12 19:10:07 1996 Jason Merrill * cvt.c (cp_convert): Simplify for flag_ansi_overloading. (convert_to_reference): Likewise. * typeck.c (convert_for_initialization): Likewise. * init.c (expand_default_init): Likewise. (expand_aggr_init_1): Likewise. * cp-tree.h (CONV_NONCONVERTING): Lose. * typeck.c (build_c_cast): Lose allow_nonconverting parm. * *.c: Adjust. * call.c (build_user_type_conversion_1): Assume LOOKUP_ONLYCONVERTING. Tue Nov 12 16:29:04 1996 Brendan Kehoe * pt.c (tsubst_expr): Reverse args to expand_start_catch_block. Tue Nov 12 15:26:17 1996 Jason Merrill * init.c (expand_aggr_init_1): Don't crash on non-constructor TARGET_EXPR. Tue Nov 12 14:00:50 1996 Brendan Kehoe * g++.c: Include gansidecl.h. (VPROTO, PVPROTO, VA_START): Delete. (choose_temp_base_try, choose_temp_base, perror_exec, run_dos) [__MSDOS__]: Delete fns. (pfatal_with_name): Delete fn. (temp_filename): Declare like in gcc.c. (pexecute, pwait, choose_temp_base): Declare from gcc.c. (error_count, signal_count): Define. (error): Delete both definitions. (PEXECUTE_{FIRST,LAST,SEARCH,VERBOSE}): Define from gcc.c. (pfatal_pexecute): Add fn from gcc.c. (main): Rename local VERBOSE var to VERBOSE_FLAG. Rewrite the code to use the pexecute stuff also used by gcc.c. (MIN_FATAL_STATUS): Define. * Make-lang.in (g++): Add dependency on and linking with choose-temp.o and pexecute.o. * cp-tree.h: Include gansidecl.h. (STDIO_PROTO): Delete #undef/#define. * cvt.c (NULL): Delete #undef/#define. * expr.c (NULL): Likewise. * init.c (NULL): Likewise. * rtti.c (NULL): Likewise. * xref.c (NULL): Likewise. * cp-tree.h (build_user_type_conversion): Add prototype. * call.c (build_user_type_conversion): Delete prototype. Correct decl of FLAGS arg to be an int. * cvt.c (build_user_type_conversion): Likewise. Tue Nov 12 12:16:20 1996 Jason Merrill * cp-tree.def: Add TRY_BLOCK and HANDLER. * except.c (expand_start_catch_block): Support templates. * parse.y (try_block, handler_seq): Likewise. * pt.c (tsubst_expr): Support TRY_BLOCK and HANDLER. Mon Nov 11 13:57:31 1996 Jason Merrill * pt.c (current_template_args): New fn. (push_template_decl): Use it. * decl.c (grokdeclarator): Use it. * decl2.c (build_expr_from_tree): Dereference ref vars. * decl.c (grokdeclarator): Generalize handling of TYPENAME_TYPEs in the decl-specifier-seq. * decl.c (grok_op_properties): Don't force the type of a conversion op to be complete. Don't warn about converting to the same type for template instantiations. * decl2.c (finish_file): Don't call instantiate_decl on synthesized methods. Mon Nov 11 13:20:34 1996 Bob Manson * typeck.c (get_delta_difference): Remove previous bogusness. Don't give errors if force is set. Fri Nov 8 17:38:44 1996 Jason Merrill * decl2.c (finish_file): Don't emit debug info. * decl.c (pushdecl): Lose obsolete code. (grokdeclarator): Still do the long long thing after complaining. * search.c (note_debug_info_needed): Don't do anything if we're in a template. * method.c (synthesize_method): For non-local classes, push_to_top_level first. Fri Nov 8 11:52:28 1996 Bob Manson * typeck.c (get_delta_difference): Add no_error parameter. (build_ptrmemfunc): Call get_delta_difference with no_error set; we don't want error messages when converting unrelated pointer-to-member functions. Thu Nov 7 11:16:24 1996 Mike Stump * error.c (dump_expr): Improve the wording on error messages that involve pointer to member functions. Tue Nov 5 17:12:05 1996 Mike Stump * cvt.c (cp_convert_to_pointer): Move code for conversions from (::*)() to void* or (*)() up a bit, so that we can convert from METHOD_TYPEs as well. Tue Nov 5 14:54:17 1996 Jason Merrill * rtti.c (get_tinfo_fn): Make sure 'type' is permanent. There are no 'member' types. (get_tinfo_fn_dynamic): Diagnose typeid of overloaded fn. (build_x_typeid): Handle errors. Mon Nov 4 17:43:12 1996 Mike Stump * typeck.c (convert_for_assignment): Handle anachronistic implicit conversions from (::*)() to void* or (*)(). * cvt.c (cp_convert_to_pointer): Likewise. (cp_convert_to_pointer_force): Remove cp_convert_to_pointer conversions from here. * decl2.c (lang_decode_option): Add -W{no-,}pmf-conversions. * lang-options.h: Likewise. * decl2.c (warn_pmf2ptr): Define. * cp-tree.h: Declare it. * typeck2.c (digest_init): Allow pmfs down into convert_for_initialization. Sun Nov 3 09:43:00 1996 Jason Merrill * typeck.c (c_expand_return): Fix for returning overloaded fn. Fri Nov 1 08:53:17 1996 Jason Merrill * cp-tree.h (DIRECT_BIND): Change from INDIRECT_BIND. * decl.c (grok_reference_init): Pass DIRECT_BIND. * cvt.c (build_up_reference): Don't mark 'this' addressable. Use DIRECT_BIND. * call.c (convert_like): Don't pass INDIRECT_BIND. * typeck.c (convert_arguments): Likewise. * typeck.c (mark_addressable): Allow &this if flag_this_is_variable. Thu Oct 31 17:08:49 1996 Jason Merrill * typeck.c (mark_addressable): Support TARGET_EXPR, unify with similar code in build_up_ref. * cvt.c (build_up_reference): Drastically simplify. Mon Oct 28 12:45:05 1996 Jeffrey A Law * typeck.c (signed_or_unsigned_type): If the given type already as the correct signedness, then just return it. * typeck.c ({un,}signed_type): If can't do anything, call signed_or_unsigned_type. Thu Oct 24 14:21:59 1996 Bob Manson * decl2.c (copy_assignment_arg_p): Don't buy the farm if current_class_type is NULL. Wed Oct 23 00:43:10 1996 Jason Merrill * class.c (finish_struct_1): Avoid empty structs by adding a field so layout_type gets the mode right. * typeck.c (c_expand_return): Drastically simplify. Mon Oct 21 22:34:02 1996 Jason Merrill * typeck.c (decay_conversion): Handle overloaded methods. Fri Oct 18 16:03:48 1996 Jason Merrill * call.c (build_over_call): A TARGET_EXPR has side-effects. Thu Oct 17 11:31:59 1996 Mike Stump * cvt.c (convert_to_pointer_force): Add code to support pointer to member function to pointer to function conversions. * init.c (resolve_offset_ref): Add code to allow faked up objects, ignoring them if they are not used, and giving an error, if they are needed. * typeck.c (get_member_function_from_ptrfunc): Fold e1 to improve code, and so that we can give an error, if we needed an object, and one was not provided. (build_c_cast): Don't call default_conversion when we want to convert to pointer to function from a METHOD_TYPE. Mon Oct 14 00:28:51 1996 Jason Merrill * Make-lang.in (cplib2.ready): Fix logic. * decl.c (shadow_tag): Only complain about non-artificial function members. * class.c (finish_struct_1): Add synthesized methods to TYPE_METHODS. Fri Oct 11 16:12:40 1996 Jason Merrill * expr.c (cplus_expand_expr): Pre-tweak call_target like expand_inline_function would. * pt.c (mark_decl_instantiated): If extern_p, call mark_inline_for_output. Thu Oct 10 15:58:08 1996 Mike Stump * typeck.c (unary_complex_lvalue): Add code to handle intermediate pmd conversions. * typeck.c (get_delta_difference): Fix wording, as we can be used for pointer to data members. Tue Oct 8 12:43:51 1996 Bob Manson * pt.c (tsubst): If the function decl isn't a member of this template, return a copy of the decl (including copying the lang-specific part) so we don't hose ourselves later. Thu Oct 3 16:24:28 1996 Jason Merrill * class.c (finish_struct): Remove DWARF-specific tag handling. * decl.c (pushtag): Likewise. (finish_function): Always clear DECL_ARGUMENTS on function decls with no saved RTX. * decl2.c (finish_file): Emit DWARF debugging info for static data members. Wed Oct 2 21:58:01 1996 Bob Manson * decl.c (duplicate_decls): Make sure the old DECL_LANG_SPECIFIC isn't the same as the new one before we whack it. Mon Sep 30 13:38:24 1996 Jason Merrill * class.c, cp-tree.h, cvt.c, decl.c, decl2.c, gxx.gperf, hash.h, lex.c, method.c, parse.y, typeck.c, typeck2.c: Remove warn_traditional and warn_strict_prototypes; remove ancient 'overload' code; remove references to flag_traditional. Mon Sep 30 12:58:40 1996 Mike Stump * input.c (sub_getch): Handle 8-bit characters in string literals. Sun Sep 29 03:12:01 1996 Jason Merrill * tree.c (mapcar): Handle CONSTRUCTORs. (copy_to_permanent): Handle expression_obstack properly. * Make-lang.in (cplib2.txt): Also depend on the headers. * rtti.c (get_tinfo_var): Don't assume that POINTER_SIZE == INT_TYPE_SIZE. (expand_class_desc): Use USItype for offset field. * tinfo.h (struct __class_type_info): Likewise. * method.c (build_overload_int): TYPE_PRECISION should be applied to types. Sat Sep 28 14:44:50 1996 Jason Merrill * call.c (build_new_op): A COND_EXPR involving void must be a builtin. Fri Sep 27 16:40:30 1996 Jason Merrill * typeck.c (build_x_component_ref): New fn. (build_object_ref): Use it. * parse.y (primary): Use it. * decl2.c (build_expr_from_tree): Use it. * cp-tree.h: Declare it. * decl.c (start_decl): Variable-sized arrays cannot be initialized. * error.c (dump_type_suffix): Handle variable arrays. Fri Sep 27 13:14:05 1996 Brendan Kehoe * Make-lang.in (exception.o): Put back compiling it with -fPIC. Fri Sep 27 03:00:09 1996 Jason Merrill * decl.c (lookup_name_real): Don't try to look up anything in a TYPENAME_TYPE. * tinfo2.cc (__throw_type_match_rtti): Oops. Thu Sep 26 22:11:05 1996 Brendan Kehoe * Make-lang.in (exception.o): Use -fno-PIC for now. Thu Sep 26 10:59:00 1996 Jason Merrill * rtti.c (build_dynamic_cast): Pass tinfo fns rather than calling them. (get_tinfo_fn_dynamic): Extracted from build_typeid. * tinfo2.cc (__dynamic_cast): Adjust. * rtti.c (build_typeid): Use resolves_to_fixed_type_p. (build_x_typeid): Likewise. * parse.y: Call build_x_typeid instead of build_typeid. * cp-tree.def: Add TYPEID_EXPR. * pt.c (tsubst_copy): Handle typeid. * decl2.c (build_expr_from_tree): Likewise. * rtti.c (build_x_typeid): Throw bad_typeid from here. (build_typeid): Not here. * cp-tree.h: Declare build_x_typeid. Wed Sep 25 17:26:16 1996 Jason Merrill * call.c (convert_like): Pull out constant values. * tree.c (mapcar): Use build_cplus_array_type, not build_array_type. Wed Sep 25 17:28:53 1996 Michael Meissner * decl.c (init_decl_processing): Create short int types before creating size_t in case a machine description needs to use unsigned short for size_t. Tue Sep 24 18:18:44 1996 Jason Merrill * Make-lang.in (exception.o): Turn off pic. * tinfo2.cc (__throw_type_match_rtti): Fix cv-variants of the same type, multi-level ptr conversions. * rtti.c (call_void_fn): Renamed and genericized from throw_bad_cast. (throw_bad_cast): Use it. (throw_bad_typeid): New fn. (build_typeid): Throw bad_typeid as needed. Use build_call. (synthesize_tinfo_fn): Handle functions and arrays before checking for cv-quals. * Remove .h from standard C++ headers, add new.h, move into inc subdirectory. * exception*: Remove pointer from object, constructors. Add default exception::what that uses type_info::name. Add __throw_bad_typeid. * init.c (build_new): Don't add a cookie to new (void *) T[2]. Mon Sep 23 15:21:53 1996 Jason Merrill * Make-lang.in: Building C++ code depends on cc1plus. Mon Sep 23 12:38:40 1996 Brendan Kehoe * decl.c (struct saved_scope): Declare PROCESSING_TEMPLATE_DECL as a HOST_WIDE_INT, not a tree. Mon Sep 23 12:36:02 1996 Jason Merrill * exception.cc: Don't include . * Make-lang.in (c++.clean): Remove cplib2.*. Mon Sep 23 09:42:19 1996 Doug Evans * parse.y (component_decl_1, component_costructor_declarator case): Pass attributes/prefix_attributes in tree list. Mon Sep 23 01:18:50 1996 Jason Merrill * tinfo{,2}.cc: #include instead of . Sun Sep 22 05:31:22 1996 Jason Merrill * lex.c (do_identifier): Don't do deferred lookup in a template header. * typeck2.c (store_init_value): Oops. * new.{h,cc}, exception.{h,cc}, typeinfo.h, tinfo{2.cc,.cc,.h}: New files for C++ lang-support library. * Make-lang.in (CXX_EXTRA_HEADERS): Define. (CXX_LIB2FUNCS): Define. And rules for building the C++ lang-support code. * config-lang.in (headers): Define. (lib2funcs): Define. Sat Sep 21 19:17:28 1996 Jason Merrill * decl2.c (build_expr_from_tree): If CONSTRUCTOR has a type, call digest_init. * pt.c (tsubst_copy): Compute type for CONSTRUCTOR. * typeck2.c (store_init_value): Check for initializing pmf with { } here. (process_init_constructor): Not here. Thu Sep 19 16:41:07 1996 Jason Merrill * pt.c (begin_template_parm_list): Increment processing_template_decl here. (end_template_parm_list): Not here. (process_template_parm): No need to add 1 to it now. * *.c: Use processing_template_decl instead of current_template_parms to check for being in a template. * pt.c (uses_template_parms): Handle SCOPE_REF. Fix CONSTRUCTOR. (tsubst_copy): Handle CONSTRUCTOR. (instantiate_decl): Set up context properly for variables. * decl2.c (build_expr_from_tree): Handle CONSTRUCTOR. * class.c (finish_struct): Reverse CLASSTYPE_TAGS. Wed Sep 18 13:30:20 1996 Brendan Kehoe * lex.c (enum tree_node_kind) [GATHER_STATISTICS]: Put the enum back. Wed Sep 18 04:24:07 1996 Jason Merrill * method.c (make_thunk): Call comdat_linkage before setting the TREE_CODE. * decl2.c (comdat_linkage): Use make_decl_one_only. (import_export_decl): Likewise. * decl.c (init_decl_processing): Check supports_one_only instead of SUPPORTS_WEAK. Sat Sep 14 08:34:41 1996 Jason Merrill * decl2.c (grokfield): Tighten checking for access decls. * decl.c (make_typename_type): Resolve references to current_class_type. Set CLASSTYPE_GOT_SEMICOLON. (lookup_name_real): Types that depend on a template parameter get an implicit 'typename' unless they're in the current scope. (start_decl_1): We don't care about incomplete types that depend on a template parm. (grokdeclarator): Resolve 'typename's in the type specifier that refer to members of the current scope. * call.c (build_over_call): Remove 'inline called before definition' diagnostic. (build_method_call): Likewise. * decl.c (duplicate_decls): Downgrade 'used before declared inline' to a warning, only with -Winline. Fri Sep 13 17:31:40 1996 Stan Shebs * mpw-make.sed: Fix include paths, add @DASH_C_FLAG@ to compile. Wed Sep 11 22:38:13 1996 Gerald Baumgartner * call.c (build_method_call): When calling a signature default implementation, as in other cases, let instance_ptr simply be instance. Wed Sep 11 22:14:44 1996 Mike Stump * parse.y (simple_stmt): Cleanup and use do_poplevel (). Wed Sep 11 22:10:48 1996 Mike Stump * except.c (expand_start_catch_block): Add a pushlevel so that -g works on hppa and SPARC. Wed Sep 11 10:18:06 1996 Brendan Kehoe * typeck.c (build_indirect_ref): Catch PTR being an error_mark_node. Mon Sep 9 19:51:14 1996 Gerald Baumgartner * call.c (build_over_call): Check first whether DECL_CONTEXT exists before testing whether it's a signature. Sun Sep 8 16:06:57 1996 Gerald Baumgartner * call.c (build_new_method_call): Don't complain about signature pointers and references not being an aggr type. (build_this): If a signature pointer or reference was passed in, just return it. (build_new_method_call): If instance is a signature pointer, set basetype to the signature type of instance. * sig.c (build_signature_method_call): Deleted basetype and instance parameters, they can be found as the DECL_CONTEXT of function and as the first argument passed in. * cp-tree.h: Changed declaration of build_signature_method_call. * call.c (build_method_call): Deleted first two arguments in call of build_signature_method_call. (build_over_call): Added call to build_signature_method_call. Thu Sep 5 16:51:28 1996 Jason Merrill * typeck.c (build_c_cast): Don't tack a non_lvalue_expr onto a target_expr. Thu Sep 5 10:05:38 1996 Brendan Kehoe * cvt.c (convert_to_reference): Use %#T, not %#D, for error. Wed Sep 4 17:16:09 1996 Bob Manson * except.c (expand_start_try_stmts): Move to except.c in the backend. (expand_end_try_stmts): Remove. * init.c (perform_member_init): Use add_partial_entry () instead of directly manipulating lists. (emit_base_init): Likewise. Wed Sep 4 12:14:36 1996 Mike Stump * except.c (expand_exception_blocks): Always make sure USE and CLOBBER insns that came at the end still do, the backend relies upon this. Wed Sep 4 07:44:48 1996 Jason Merrill * call.c (build_over_call): We can only use a TARGET_EXPR of the right type. Tue Sep 3 19:26:05 1996 Jason Merrill * cvt.c (convert_to_reference): Revert last change, don't complain about temp without target decl. Tue Sep 3 10:22:56 1996 Mike Stump * decl.c (grokdeclarator): Don't core dump when void() is given. Tue Sep 3 02:38:56 1996 Jason Merrill * decl.c (copy_args_p): Don't crash. Fri Aug 30 14:26:57 1996 Mike Stump * pt.c (tsubst): And support template args inside the exception specification. * pt.c (tsubst): Add support for exception specifications in template functions. Fri Aug 30 10:01:55 1996 Mike Stump * cp-tree.def (DECL_STMT): Eliminate the throw spec field, only 3 fields now. * cp-tree.h (start_decl): Eliminate the throw spec parameter. (start_function): Likewise. (start_method): Likewise. (grokfield): Likewise. (make_call_declarator): Add throw spec parameter. (set_quals_and_spec): Add routine. * lex.c (set_quals_and_spec): Likewise. * decl.h (grokdeclarator): Eliminate the throw spec parameter. * decl.c (shadow_tag): Eliminate the throw spec parameter to grokdeclarator. (groktypename): Likewise. (start_decl): Eliminate the throw spec parameter. Eliminate the throw spec parameter to grokdeclarator. Eliminate the throw spec field in DECL_STMT. (cp_finish_decl): Eliminate the throw spec field in DECL_STMT. (grokfndecl): Remove useless set of raises. (grokdeclarator): Eliminate the throw spec parameter. Eliminate the throw spec parameter to start_decl. Pull the throw spec out of the call declarator. (grokparms): Eliminate the throw spec parameter to grokdeclarator. (start_function): Eliminate the throw spec parameter. Eliminate the throw spec parameter to grokdeclarator. (start_method): Likewise. * decl2.c (grokfield): Likewise. (grokbitfield): Eliminate the throw spec parameter to grokdeclarator. (grokoptypename): Likewise. (finish_file): Eliminate the throw spec parameter to start_function. Add throw spec to make_call_declarator. * except.c (init_exception_processing): Add throw spec to make_call_declarator. Eliminate the throw spec parameter to start_decl. (expand_start_catch_block): Eliminate the throw spec parameter to grokdeclarator. (expand_builtin_throw): Add throw spec to make_call_declarator. Eliminate the throw spec parameter to start_function. (start_anon_func): Likewise. * lex.c (make_call_declarator): Add throw spec parameter. (set_quals_and_spec): New routine. (cons_up_default_function): Add throw spec to make_call_declarator. Eliminate the throw spec parameter to grokfield. * method.c (synthesize_method): Eliminate the throw spec parameter to start_function. * pt.c (process_template_parm): Eliminate the throw spec parameter to grokdeclarator. (tsubst): Add throw spec to make_call_declarator. (tsubst_expr): Eliminate the throw spec parameter to start_decl. (do_function_instantiation): Eliminate the throw spec parameter to grokdeclarator. Eliminate the throw spec parameter to start_function. * rtti.c (synthesize_tinfo_fn): Eliminate the throw spec parameter to start_function. * parse.y (datadef): Remove non-winning optimization. (decl): Likewise. (fndef): Remove ambiguous error productions uncovered by grammar fixing. (constructor_declarator): Add exception_specification_opt here. (component_constructor_declarator): Likewise. (direct_after_type_declarator): Likewise. (complex_direct_notype_declarator): Likewise. (direct_abstract_declarator): Likewise. (fn.def1): Remove exception_specification_opt. (fn.def2): Likewise. (condition): Likewise. (initdcl0): Likewise. (initdcl): Likewise. (notype_initdcl0): Likewise. (nomods_initdcl0): Likewise. (component_decl_1): Likewise. (component_declarator): Likewise. (after_type_component_declarator0): Likewise. (after_type_component_declarator): Likewise. (notype_component_declarator): Likewise. Wed Aug 28 01:40:30 1996 Jason Merrill * call.c (build_over_call): Also use an INIT_EXPR when initializing anything from an rvalue. * call.c (build_over_call): Call stabilize_reference when building an INIT_EXPR instead of calling the copy ctor. * call.c (joust): Extend the previous change to all comparisons. * decl2.c, method.c, lex.c: Use MAKE_DECL_ONE_ONLY and NO_LINKAGE_HEURISTICS. * decl2.c (finish_file): Emit any statics that weren't already. * typeck.c (build_static_cast): Implement. * tree.c (build_cplus_new): Handle getting a TARGET_EXPR. * decl.c (grokparms): Use can_convert_arg instead of implicit_conversion directly. (copy_args_p): New fn. * cvt.c (convert_to_reference): Don't complain about temp with static_cast. (build_up_reference): Handle TARGET_EXPRs. * call.c (build_over_call): Elide unnecessary temps. (can_convert*): Use new overloading code. Tue Aug 27 13:12:21 1996 Jason Merrill * call.c: Move TYPE_PTR*_MACROS ... * cp-tree.h: To here. * typeck.c (build_reinterpret_cast): Implement. * call.c (add_builtin_candidate): Use TYPE_PTROB_P instead of ptr_complete_ob. (joust): If we're comparing a function to a builtin and the worst conversion for the builtin is worse than the worst conversion for the function, take the function. * typeck.c (build_const_cast): Implement. (comp_ptr_ttypes_const): Like comp_ptr_ttypes, for const_cast. (comp_ptr_ttypes_reinterpret): Like cpt, for reinterpret_cast. Tue Aug 27 13:14:58 1996 Bob Manson * rtti.c (build_dynamic_cast): Don't try to dereference exprtype too early. Make sure we explode if exprtype turns out to be a NULL_TREE when it shouldn't be. Tue Aug 27 10:56:21 1996 Mike Stump * cp-tree.h: New routine make_call_declarator. * lex.c (make_call_declarator): Define it. * except.c (init_exception_processing): Use it. (expand_builtin_throw): Likewise. (start_anon_func): Likewise. * decl2.c (finish_file): Likewise. * lex.c (cons_up_default_function): Likewise. * parse.y: Likewise. * pt.c (tsubst): Likewise. Mon Aug 26 17:40:03 1996 Mike Stump * decl2.c (groktypefield): Remove unused code. Mon Aug 26 17:00:33 1996 Mike Stump * gxx.gperf: Change TYPE_QUAL into CV_QUALIFIER. * parse.y: Likewise. Change maybe_type_qual into maybe_cv_qualifier. Change type_quals into cv_qualifiers. Change nonempty_type_quals into nonempty_cv_qualifiers. * hash.h: Rebuild. * lex.c (make_pointer_declarator): Change type_quals into cv_qualifiers. (make_reference_declarator): Likewise. Thu Aug 22 01:09:22 1996 Jason Merrill * decl.c (start_function): Only check interface_* for templates with flag_alt_external_templates. * call.c (build_new_op): Check for comparison of different enum types. (build_over_call): Fix arg # output. * typeck.c (build_component_ref): Handle pre-found TYPE_DECL. Wed Aug 21 00:13:15 1996 Jason Merrill * call.c (build_new_op): Check for erroneous args. * call.c (build_new_method_call): Add missing args to cp_error. * tree.c (error_type): Don't print reference-to-array. * typeck.c (convert_for_assignment): Don't say contravariance for removing const. Tue Aug 20 13:23:00 1996 Jason Merrill * call.c (build_over_call): Diagnose bad convs for `this'. * lex.c (cons_up_default_function): Set DECL_ARTIFICIAL on _ctor_arg. * call.c (convert_like): Handle bad convs. (build_over_call): Handle bad convs better. * decl2.c: -fansi-overloading is now the default. * call.c (build_new_method_call): Check for erroneous args. * pt.c (instantiate_class_template): Propagate TYPE_USES_MULTIPLE_INHERITANCE. Tue Aug 20 13:09:57 1996 Mike Stump * call.c (enforce_access): Add static to routine. Sun Aug 18 14:35:54 1996 Jason Merrill * call.c (build_user_type_conversion_1): Fix bad handling. (compare_ics): Likewise. Sat Aug 17 21:54:11 1996 Jason Merrill * call.c (standard_conversion): Oops. Sat Aug 17 16:28:11 1996 Geoffrey Noer * g++.c: Update test for win32 (&& ! cygwin32). Sat Aug 17 03:45:31 1996 Jason Merrill * typeck.c (comp_ptr_ttypes_real): Handle OFFSET_TYPEs properly. (ptr_reasonably_similar): New fn. * call.c (BAD_RANK): New rank. (ICS_BAD_FLAG): New macro. (standard_conversion): Handle almost-right pointer conversions. (reference_binding): Handle bad rvalue bindings. (add_*_candidate): Stuff. (build_over_call): Pass bad conversions to convert_for_initialization. (compare_ics): Handle bad convs. (joust): Likewise. Fri Aug 16 15:02:19 1996 Bob Manson * init.c (expand_vec_init): Use ptrdiff_type_node instead of integer_type_node when computing pointer offsets. Fri Aug 16 01:28:32 1996 Jason Merrill * tree.c (lvalue_type): New fn. (error_type): New fn. * call.c (op_error): Use error_type. (add_conv_candidate): Use lvalue_type. (add_builtin_candidates): Likewise. * error.c (args_as_string): Use error_type. Thu Aug 15 17:27:13 1996 Jason Merrill * pt.c (instantiate_decl): Evaluate DECL_INITIAL of a VAR_DECL here. (tsubst): Not here. * decl.c (init_decl_processing): With -ansi, __null's type is the signed integral type with the same number of bits as a pointer. Introduce a new variable null_node for it. * cp-tree.h: Adjust. * call.c (null_ptr_cst_p): Adjust. Thu Aug 15 17:09:54 1996 Mike Stump * except.c (do_unwind): Mark %i7 as used on the SPARC so we can optimize. Thu Aug 15 01:36:49 1996 Jason Merrill * decl2.c (import_export_decl): Ignore #pragma interface for tinfo fns of classes without virtual functions. * call.c (add_function_candidate): Handle `this' specially. (compare_ics): Likewise. Tue Aug 13 12:16:10 1996 Jason Merrill * typeck.c (build_conditional_expr): Fix handling of __null. * decl2.c (comdat_linkage): New fn. (import_export_vtable): Use it. (import_export_decl): Use it. * method.c (make_thunk): Use it. Mon Aug 12 00:09:18 1996 Jason Merrill * pt.c (end_template_decl): If we don't actually have parms, return. * parse.y (template_header): Accept 'template <>'. * errfn.c: Allow 5 args. Sun Aug 11 15:20:58 1996 Jason Merrill * tree.c (make_temp_vec): New fn. * pt.c (push_template_decl): Handle partial specs. (instantiate_class_template): Likewise. (more_specialized): Use get_bindings. (more_specialized_class): New fn. (get_class_bindings): New fn. (most_specialized_class): New fn. (do_function_instantiation): List candidates for ambiguous case. * decl.c (duplicate_decls): Lose reference to DECL_TEMPLATE_MEMBERS. (shadow_tag): Call push_template_decl for partial specializations. * parse.y: Likewise. * cp-tree.h (DECL_TEMPLATE_SPECIALIZATIONS): Replaces DECL_TEMPLATE_MEMBERS. * call.c (print_z_candidates): Reduce duplication. Fri Aug 9 14:36:08 1996 Jason Merrill * decl2.c (lang_decode_option): Allow -fansi-overloading. Thu Aug 8 17:04:18 1996 Jason Merrill * pt.c (get_bindings): New fn. (most_specialized): Likewise. (do_function_instantiation): Use them. (add_maybe_template): New fn. * cp-tree.h (DECL_MAYBE_TEMPLATE): New macro. * call.c (build_new_op): Handle guiding decls. (build_new_function_call): Likewise. * decl2.c (finish_file): Likewise. * decl2.c (mark_used): Do synthesis here. * call.c (build_method_call): Not here. (build_over_call): Or here. * typeck.c (build_function_call_real): Or here. * tree.c (bot_manip): Call mark_used on functions used in default args. Thu Aug 8 17:48:16 1996 Michael Meissner * decl2.c (import_export_vtable): Delete code that disabled vtable heuristic on systems with ASM_OUTPUT_EXTERNAL. Wed Aug 7 12:44:11 1996 Jason Merrill * typeck.c (build_x_function_call): Handle static call context better. * decl.c (finish_function): Set the DECL_CONTEXT of the result to the function, not its outer block. * call.c (build_field_call): Pass fields on to build_opfncall regardless of TYPE_OVERLOADS_CALL_EXPR. (build_method_call): Pass on to build_new_method_call sooner. * typeck.c (build_ptrmemfunc): Just return what instantiate_type gives us. * class.c (instantiate_type): Don't put a POINTER_TYPE to METHOD_TYPE on an expression. Also make a copy of rhs instead of modifying it. Tue Aug 6 12:58:46 1996 Jason Merrill * call.c (compare_ics): Handle qual_conv after lvalue_conv. (add_builtin_candidate): Don't take enums for ++. (build_new_method_call): Handle non-aggregates and field calls. Move new overloading code from... * cvt.c: Here. * decl.c (grokparms): Don't check default args in templates. Mon Aug 5 17:17:06 1996 Jason Merrill * cvt.c (build_new_op): Fix args to build_unary_op. (add_builtin_candidates): Don't call type_promotes_to on float. * decl.c (grokparms): Check the type of the default arg. * cvt.c (build_new_op): Pass non-overloaded cases on rather than returning NULL_TREE. * typeck.c (build_x_binary_op): Avoid doing extra work. (build_x_unary_op): Likewise. (build_x_conditional_expr): Likewise. * cvt.c (build_over_call): Return. (add_builtin_candidate): Fix MEMBER_REF. (build_new_op): Likewise. Mon Aug 5 17:07:47 1996 Mike Stump * method.c (build_overload_name): Put bug fix into code but leave disabled for now so we can be bug compatible with older releases that do repeats incorrectly. In the future, we can enable it. Mon Aug 5 13:46:28 1996 Jason Merrill * cvt.c (convert_like): Don't call build_cplus_new twice. * call.c, cp-tree.h, cvt.c, decl2.c, init.c, method.c, pt.c, typeck.c: Control new overloading code with -fansi-overloading. Sun Aug 4 15:29:11 1996 Jason Merrill * cvt.c (build_over_call): Call build_cplus_new. * call.c (build_method_call): Likewise. * typeck.c (build_function_call_real): Likewise. (build_conditional_expr): If both operands are TARGET_EXPRs, wrap the COND_EXPR in a TARGET_EXPR so they use the same slot. * cvt.c (build_up_reference): Propagate INDIRECT_BIND to recursive calls. * typeck.c (complete_type): Propagate TYPE_NEEDS_{CONSTRUCTING,DESTRUCTOR}. Sat Aug 3 14:05:07 1996 Jason Merrill * cvt.c (joust): More ?: kludging. Sigh. (build_over_call): Don't try to synthesize global fns. * search.c (lookup_conversions): Use binfo marking. Sat Aug 3 12:33:42 1996 Bob Manson * search.c (build_mi_matrix): Use the correct value of cid when determining the new mi_size. Sat Aug 3 01:27:41 1996 Jason Merrill * cvt.c (add_builtin_candidates): Do consider type conversion ops for the first parms of += et al. (strip_top_quals): New fn. (reference_binding): Use it instead of TYPE_MAIN_VARIANT. (implicit_conversion): Likewise. (add_builtin_candidates): Be careful about arrays. (build_new_method_call): Handle vtable optimization. Fri Aug 2 01:26:59 1996 Jason Merrill * cp-tree.h (LOOKUP_NO_TEMP_BIND): New flag. * cvt.c (reference_binding): Use it. (implicit_conversion): Use it. (add_builtin_candidate, COND_EXPR): Use it. * cvt.c (build_new_function_call): Check for error args. * typeck.c (comptypes): Just check DERIVED_FROM_P, not UNIQUELY. * gxx.gperf: Add __null. * hash.h: Regenerate. * lex.h: Add RID_NULL. * lex.c (init_lex): Create null_pointer_node here, stick it in RID_NULL. * decl.c (init_decl_processing): Still set its type here. * cvt.c (cp_convert_to_pointer): Don't produce null_pointer_node. (convert_to_pointer_force): Likewise. (null_ptr_cst_p): Check for null_pointer_node; only accept (void*)0 if (! pedantic). * call.c (convert_harshness): Use null_ptr_cst_p. * typeck.c (convert_for_assignment): Likewise. Don't produce null_pointer_node. * error.c (args_as_string): Handle lists of actual args, too. * cvt.c (null_ptr_cst): Support (void*)0 for now. (build_user_type_conversion_1): Improve diagnostics. (build_new_function_call): Likewise. (build_object_call): Likewise. (build_new_method_call): Likewise. Move call before def diagnostic... (build_over_call): Here. * cvt.c (build_new_method_call): Don't complain about no match if LOOKUP_SPECULATIVELY. (build_over_call): Fix 'this' for virtual fn. (build_new_method_call): Add diagnostic. Thu Aug 1 16:45:09 1996 Jason Merrill * cvt.c (add_function_candidate): Expect 'this' and 'in_chrg' for constructors to be passed in. (build_over_call): Likewise. (build_user_type_conversion_1): Pass them in. (convert_like): Likewise. (build_object_call): Handle overloaded conversions. (build_over_call): Pass the right args to build_vfn_ref. (standard_conversion): Fix pmf convs. (joust): Handle comparing statics and non-statics. (build_new_method_call): New fn. * call.c (build_method_call): Call it if NEW_OVER. Thu Aug 1 16:06:14 1996 Mike Stump * lex.c (do_identifier): Don't use %O on IDENTIFIER_OPNAME_Ps, use %D instead. Thu Aug 1 15:24:02 1996 Mike Stump * except.c (expand_throw): Use maybe_build_cleanup_and_delete instead of just maybe_build_cleanup so that we deallocate the thrown object. Thu Aug 1 15:18:00 1996 Brendan Kehoe * decl2.c (finish_prevtable_vardecl): Make non-static for pt.c's use. * cp-tree.h (finish_prevtable_vardecl): Add decl. Thu Aug 1 11:53:51 1996 Bob Manson * pt.c (instantiate_class_template): Call complete_type. Also, if we're at the end of the file and we just instantiated a template class with a vtable, call finish_prevtable_vardecl. * error.c (dump_decl): Don't explode (or explode more gracefully as appropriate) if the object being dumped has a null type. (dump_expr): Likewise. * search.c (build_mi_matrix): Ensure that mi_size is large enough, by counting the number of nodes that we'll need before allocating the array. (lookup_fnfields): Fix comment. (breadth_first_search): Fix comment. Wed Jul 31 09:57:05 1996 Jason Merrill * pt.c (instantiate_class_template): Propagate TYPE_PACKED and TYPE_ALIGN. * class.c (finish_struct): Call cplus_decl_attributes here. (finish_struct_1): Not here. * cp-tree.h: Adjust. * pt.c (type_unification): New parameter STRICT. (unify): If STRICT, don't allow cv addition or base deduction. * call.c, class.c, cvt.c, cp-tree.h: Adjust. Tue Jul 30 13:06:13 1996 Jason Merrill * search.c (get_template_base{_recursive}): New fns. * pt.c (more_specialized): New fn. (do_function_instantiation): Use it. (unify): Handle base deduction. * cvt.c (joust): Use more_specialized. Don't arbitrarily choose between non-builtin candidates. (build_over_call): Call require_complete_type. * decl.c (start_function): Statics are static even in a #pragma interface file. * decl2.c (import_export_vtable): Disable vtable heuristic on systems with ASM_OUTPUT_EXTERNAL. * cvt.c (compare_ics): Fix comparison of PMEM_CONV and BASE_CONV. (standard_conversion): No std conv to enum type. * cvt.c (standard_conversion): Fix order of args to DERIVED_FROM_P for ptm's. * cvt.c (reference_binding): Bind directly to a base subobject of a class rvalue. * cvt.c (build_new_op): Enforce access control. Tue Jul 30 09:22:53 1996 Bob Manson * typeck2.c (process_init_constructor): When scanning the union for a named field, skip things that aren't FIELD_DECLs. * method.c (synthesize_method): Don't scan fndecl's rtl if we're at the end of the file; just assume the function can't be inlined. Mon Jul 29 15:48:30 1996 Jason Merrill * cvt.c (build_builtin_candidate): Stick a dummy conversion in if it failed. * cvt.c (build_user_type_conversion_1): Handle overloaded conversion ops. * cvt.c (add_builtin_candidates): Don't consider type conversion operators for the first parameter of operator=. Mon Jul 29 15:33:55 1996 Bob Manson * typeck.c (complete_type): Only call layout_type if we're not expanding a template. Mon Jul 29 14:40:38 1996 Jason Merrill * cvt.c (compare_ics): Oops. * cvt.c (op_error): Oops. * cp-tree.def: Add RVALUE_CONV, rename EXACT_CONV to IDENTITY_CONV. * cvt.c: Add IDENTITY_RANK before others. Use real_lvalue_p. (build_conv): Use them. (implicit_conversion): Use them. (convert_like): Handle them. (build_new_op): Handle builtin COND_EXPR again. (add_builtin_candidates): Strip cv-quals. Fix oops. Include enums in lists of types for COND_EXPR. (add_builtin_candidate): Add enum candidates for COND_EXPR. Mon Jul 29 12:05:40 1996 Bob Manson * typeck.c (build_modify_expr): Always attempt to build a call to the assignment operator, even if we're using a default one. (convert_for_initialization): Call complete_type. Mon Jul 29 11:25:08 1996 Jason Merrill * cvt.c (reference_binding): A REF_BIND gets the reference type. (implicit_conversion): Likewise. (convert_like): Likewise. (compare_ics): Likewise. (compare_qual): Likewise. (print_z_candidates): Handle no candidates. (build_new_op): Don't handle builtin COND_EXPR for now. Sat Jul 27 11:27:47 1996 Stan Shebs * cvt.c (build_builtin_candidate): Init local var in an ANSI way. Fri Jul 26 01:07:22 1996 Jason Merrill * cvt.c (joust): If the candidates are the same, arbitrarily pick one. * cvt.c (build_builtin_candidate): Oops. (build_new_op): Oops. * method.c (build_opfncall): Pass COND_EXPR on. * cvt.c (build_builtin_candidate): Reorganize, support COND_EXPR. (add_builtin_candidate{,s}): Likewise. (add_builtin_candidates): Likewise. (print_z_candidates, op_error, build_new_op): Likewise. (type_decays_to): New fn. * lex.c (init_lex): Just say ?: for COND_EXPR. Thu Jul 25 09:33:33 1996 Jason Merrill * typeck.c (complete_type): Call layout_type rather than building a new array type. * cvt.c (add_builtin_candidate): Pointer arithmetic candidates only use ptrdiff_t. Wed Jul 24 12:45:08 1996 Jason Merrill * cvt.c: Always compile the new overloading code (but don't use it). (implicit_conversion): Add a BASE_CONV when converting to the same class type. (convert_like): Handle BASE_CONV. Tue Jul 23 12:46:30 1996 Jason Merrill * cvt.c (build_new_op): Support {MAX,MIN}_EXPR. (add_builtin_candidate): Likewise. NEW_OVER changes: * typeck.c (build_x_function_call): Try an operator function whenever we call an object of class type. * method.c (build_opfncall): Pass CALL_EXPRs through. * cvt.c (implicit_conversion): Do const-ref case first. (add_conv_candidate, build_object_call, op_error): New fns. (ptr_complete_ob, TYPE_PTROB_P): void is not an object type. ({add,build}_builtin_candidate{,s}, print_z_candidates): Display builtin candidates. (build_new_op): Handle CALL_EXPR. Don't try to decay void. Fall back on preincrement handling. Use op_error. Handle warn_synth. (convert_like): Pass INDIRECT_BIND. Don't try to do anything with an error_mark_node. (build_over_call): Handle PROMOTE_PROTOTYPES and ellipsis promotions properly. Mon Jul 22 16:21:55 1996 Bob Manson * pt.c (tsubst_expr): Handle CONTINUE_STMT. Mon Jul 22 15:38:58 1996 Mike Stump * typeck.c (build_component_ref_1): Use build_component_ref instead of open coding it here. Mon Jul 22 12:18:54 1996 Jason Merrill * g++.c (main): Don't link with -lg++. NEW_OVER changes: * cvt.c (convert_to_reference): Don't use convert_from_reference on result of build_type_conversion. (cp_convert): Only call build_method_call for ctors if build_type_conversion failed. (ptr_complete_ob): New function. (TYPE_PTR{,OB,MEM}_P): New macros. ({add,build}_builtin_candidate{,s}): New functions. (print_z_candidates): Handle builtins. (build_user_type_conversion_1): Don't use conversion fns for converting to a base type. (build_user_type_conversion_1): Set ICS_USER_FLAG on AMBIG_CONVs. (build_user_type_conversion): Use convert_from_reference. (build_new_op): New function. (build_over_call): Fix handling of methods. (compare_ics): Handle AMBIG_CONV properly. * typeck2.c: Increment abort count. * method.c (build_opfncall): Forward most requests to build_new_op. * cp-tree.h (IS_OVERLOAD_TYPE): Tweak. Fri Jul 19 17:59:29 1996 Brendan Kehoe * error.c (dump_expr, case CONSTRUCTOR, case CAST_EXPR): Take out invalid second argument to dump_expr_list. Fri Jul 19 14:04:05 1996 Mike Stump * decl.c (lookup_name_real): Make sure we do obj->X::i correctly. Thu Jul 18 14:48:23 1996 Bob Manson * decl2.c (import_export_vtable): ASM_OUTPUT_EXTERNAL, not ASSEMBLE_EXTERNAL. Mon Jul 15 17:48:43 1996 Mike Stump * typeck2.c (process_init_constructor): New pedwarn for using { } to initialize a pointer to member function. * typeck.c (build_ptrmemfunc1): Avoid use of digest_init so that we can avoid the new error. Mon Jul 15 15:42:03 1996 Mike Stump * typeck.c (build_ptrmemfunc1): New function to hide details of pointer to member functions better. Mon Jul 15 14:23:02 1996 Mike Stump * init.c (resolve_offset_ref): Resolve OFFSET_REFs that are methods into the actual method, as we know the implied object is not used. Mon Jul 15 13:08:29 1996 Brendan Kehoe * parse.y (maybecomma_warn): Only emit the pedwarn if we're not inside a system header. Fri Jul 12 16:30:05 1996 Bob Manson * call.c (build_method_call): Call complete_type on the instance type. Thu Jul 11 17:16:40 1996 Mike Stump * typeck.c (build_component_ref): Always build up an OFFSET_REF for obj_ptr->func so that we can know which object to use in a method call. Wed Jul 10 19:36:37 1996 Mike Stump * typeck.c (build_ptrmemfunc): Remove sorry, now we can cast around things. Also improve maintainability. Wed Jul 10 18:20:11 1996 Bob Manson * decl.c (grokdeclarator): Check for overflow when evaluating an array dimension. Wed Jul 10 17:26:19 1996 Jason Merrill * cvt.c (cp_convert): Don't check for ambiguity with constructor if NEW_OVER. * typeck.c (build_x_function_call): Pass function overload questions to new overloading code if NEW_OVER. * init.c (expand_aggr_init_1): Only check for type conversion ops if we're doing copy-initialization (i.e. LOOKUP_ONLYCONVERTING). Don't check for ambiguity with constructor if NEW_OVER. * cvt.c (convert_to_reference): Dereference the result of a type conversion operator. (build_conv): Propagate ICS_USER_FLAG. (implicit_conversion): Call instantiate_type. Pass LOOKUP_ONLYCONVERTING instead of LOOKUP_NORMAL. (add_function_candidate): Fix cv-quals on argtype. (print_z_candidates): New function. (build_new_function_call): Call it. (build_user_type_conversion_1): If LOOKUP_ONLYCONVERTING, don't consider non-converting constructors. Call print_z_candidates. Return an AMBIG_CONV for an ambiguous conversion. (build_user_type_conversion): Handle AMBIG_CONV. (convert_like): Fix test for building TARGET_EXPR. Call instantiate_type. Handle AMBIG_CONV and LVALUE_CONV. (build_over_call): Handle 0 args and ellipsis. * cp-tree.def: Add AMBIG_CONV. Tue Jul 9 17:48:48 1996 Mike Stump * decl.c (lookup_name_real): If we find mem in obj when parsing `obj->mem', make sure we return the right value. Tue Jul 9 16:11:28 1996 Bob Manson * search.c (get_base_distance): Call complete_type. Tue Jul 9 12:46:34 1996 Mike Stump * decl.c (store_bindings): Make static. Mon Jul 8 16:42:31 1996 Jason Merrill * init.c (expand_aggr_init_1): Don't check type conversions if NEW_OVER. * cvt.c (z_candidate): Put back template field. (add_function_candidate): Set it. (add_template_candidate): Likewise. (joust): Use it. (compare_qual): Handle references and pointers to members. (compare_ics): Handle reference bindings. * decl.c (duplicate_decls): Propagate DECL_ONE_ONLY. Mon Jul 8 16:18:56 1996 Bob Manson * call.c (compute_conversion_costs): Call complete_type. * tree.c (vec_binfo_member): Use comptypes instead of comparing pointers, so we can handle template parameters. Fri Jul 5 16:51:53 1996 Bob Manson * cvt.c (cp_convert_to_pointer): We have to call complete_type here; let's make it explicit instead of a side effect of an error check. Wed Jul 3 16:29:51 1996 Jason Merrill * cvt.c (z_candidate): Remove template field. (reference_binding): Handle binding to temporary. (implicit_conversion): Likewise. (add_function_candidate): Handle artificial constructor parms. Handle functions with too few parms. (add_template_candidate): New function. (build_user_type_conversion_1): Handle constructors. (convert_like): Likewise. (build_over_call): Likewise. (build_new_function_call): Support templates. (compare_ics): Fix reference, inheritance handling. Mon Jul 1 22:58:18 1996 Bob Manson * decl.c: Add signed_size_zero_node. (init_decl_processing): Build it. * class.c (prepare_fresh_vtable): Use it instead of size_zero_node when we're trying to make a negative delta. Mon Jul 1 17:56:19 1996 Brendan Kehoe Stop doing this damn index==strchr variable name confusion. * class.c (add_virtual_function): Change local var INDEX to be named IDX. (add_method): Likewise. * lex.c (print_parse_statistics): Likewise. * search.c (make_memoized_table_entry): Likewise. (lookup_fnfields_here): Likewise. (lookup_field): Likewise. (lookup_fnfields): Likewise. (get_baselinks): Likewise. * sig.c (build_signature_table_constructor): Likewise. (build_signature_method_call): Likewise. * typeck.c (build_x_array_ref): Change INDEX parm to be named IDX. (get_member_function_from_ptrfunc): Likewise. (build_ptrmemfunc): Change local var INDEX to be IDX. (c_expand_start_case): Likewise. Sat Jun 29 14:05:46 1996 Jason Merrill * cvt.c (cp_convert_to_pointer): Move user-defined type conversion handling to before extraction of TYPE_PTRMEMFUNC_FN_TYPE. (convert_to_reference): Use build_type_conversion to convert to the reference type directly. (standard_conversion): Fix void* case, non-conversions. (reference_binding): Fix expr == 0 case, non-conversions. (convert_like): Support REF_BIND. (compare_qual): Split out from compare_ics. (compare_ics): Use it, handle icses with only a qual_conv. * init.c (expand_vec_init): Don't crash if decl is NULL. Fri Jun 28 11:52:51 1996 Stan Shebs * mpw-config.in: New file, configury for Mac MPW. * mpw-make.sed: New file, makefile editing for MPW. Thu Jun 27 15:18:30 1996 Jason Merrill * pt.c (instantiate_class_template): Call repo_template_used. * search.c (lookup_conversions): Only lookup conversions in complete types. Thu Jun 27 12:59:53 1996 Brendan Kehoe * cp-tree.def: Renamed from tree.def, to avoid confusion with gcc's tree.def. * cp-tree.h, lex.c: Include cp-tree.def. * Makefile.in (CXX_TREE_H): Reference cp-tree.def. Wed Jun 26 18:29:47 1996 Bob Manson * init.c (build_vec_delete_1): Call complete_type. Mon Jun 24 17:17:32 1996 Mike Stump * except.c (start_anon_func): Make sure anonymous functions are never external. Fri Jun 21 15:10:58 1996 Jason Merrill * decl.c (finish_function): If function_depth > 1, set nested. * decl2.c (grokbitfield): Revert Bob's change. * class.c (finish_struct_1): Fix handling of named bitfield widths. Thu Jun 20 23:35:38 1996 Jason Merrill * pt.c (add_pending_template): Handle types. (lookup_template_class): With -fexternal-templates, just add the class to pending_templates instead of instantiating it now. * decl2.c (finish_file): Handle types in pending_templates. Thu Jun 20 14:08:40 1996 Bob Manson * decl2.c (grokbitfield): Handle constant decls appropriately. Give an appropriate error message now instead of spewing core later. Thu Jun 20 13:01:51 1996 Jason Merrill * decl2.c: Don't turn on thunks by default for now. Wed Jun 19 11:37:04 1996 Jason Merrill * typeck.c (complete_type): Handle error_mark_node. (common_type, OFFSET_TYPE): Handle template_type_parms. Tue Jun 18 10:02:15 1996 Jason Merrill * pt.c (instantiate_decl): If at_eof, call import_export_decl regardless of DECL_INLINE. * typeck.c (mark_addressable): Set TREE_ADDRESSABLE on CONSTRUCTORs. * class.c (finish_struct_bits): Copy TYPE_SIZE. * rtti.c (build_dynamic_cast): Support templates. * tree.def: Support DYNAMIC_CAST_EXPR. * pt.c (tsubst_copy): Likewise. * decl2.c (build_expr_from_tree): Likewise. Mon Jun 17 15:23:36 1996 Jason Merrill * typeck.c (build_static_cast): Support templates. (build_const_cast): Likewise. * tree.def: Support CONST/STATIC_CAST_EXPR. * pt.c (tsubst_copy): Likewise. * decl2.c (build_expr_from_tree): Likewise. Sun Jun 16 12:33:57 1996 Jason Merrill * decl2.c (finish_vtable_vardecl): Don't trust TREE_SYMBOL_REFERENCED for vtables of local classes. Fri Jun 14 18:13:36 1996 Jason Merrill * pt.c (tsubst_copy): Handle operator T. Wed Jun 12 17:52:40 1996 Brendan Kehoe * init.c (build_delete): Move creation of PARMS inside test of TYPE_HAS_DESTRUCTOR, since it's never used outside of that block. Tue Jun 11 15:09:18 1996 Bob Manson * typeck.c (build_conditional_expr): Don't assume that the arguments to ?: are always pointers or records. Tue Jun 11 13:56:23 1996 Jason Merrill * decl2.c (import_export_decl): Still emit static/weak/comdat copies of inline template functions with -fno-implicit-templates. Tue Jun 11 11:42:13 1996 Bob Manson * init.c (build_delete): Determine the complete basetype path to the destructor we're calling. Fri Jun 7 15:30:10 1996 Bob Manson * decl.c (build_enumerator): Always copy the INTEGER_CST used to initialize the enum, because we really and truly don't know where it came from. (start_enum): Don't copy integer_zero_node because build_enumerator will do it. Fri Jun 7 11:11:09 1996 Jason Merrill * decl.c (finish_function): Do access control on base destructors. * pt.c (tsubst, case FUNCTION_DECL): Set up IDENTIFIER_GLOBAL_VALUE for member functions so pushdecl doesn't hose us. Fri Jun 7 10:37:33 1996 Mike Stump * cvt.c (build_up_reference): If we have already extended the lifetime of the temporary, don't try it again. * typeck.c (c_expand_return): Don't try and convert the return value twice when we want a reference, once is enough. Tue Jun 4 15:41:45 1996 Jason Merrill * pt.c (tsubst_expr, case DECL_STMT): Don't pass LOOKUP_ONLYCONVERTING at all for now. * search.c (add_conversions): Put the conversion function in TREE_VALUE, the basetype in TREE_PURPOSE. * cvt.c (build_type_conversion): Adjust. * cvt.c (build_expr_type_conversion): Adjust. * call.c (user_harshness): Adjust. Mon Jun 3 15:30:52 1996 Jason Merrill * method.c (emit_thunk): Pretend this is a FUNCTION_DECL for the backend's benefit. Mon Jun 10 18:58:19 1996 Mike Stump * except.c (expand_start_catch_block): Add a dummy region, if we get an error, so that we can avoid core dumping later. Fri May 31 14:56:13 1996 Mike Stump * cp-tree.h (OFFSET_REF): Remove. * tree.def (CP_OFFSET_REF): Rename to OFFSET_REF. * expr.c (cplus_expand_expr): Cleanup callers of expand_expr. * init.c (expand_aggr_init_1): Likewise. (build_new): Likewise. * typeck.c (expand_target_expr): Likewise. Fri May 31 14:22:08 1996 Jason Merrill * typeck.c (build_modify_expr): Don't use TREE_VALUE on a TARGET_EXPR. Wed May 29 17:04:33 1996 Mike Stump * cvt.c (build_up_reference): Redo how and when temporaries are created. * decl.c (grok_reference_init): Don't try and be smart about running cleanups. Wed May 29 16:02:08 1996 Mike Stump * cvt.c (build_up_reference): Add NULL_TREE to all calls to build (TARGET_EXPR...), now that it has 4 arguments. * tree.c (build_cplus_new): Likewise. Thu May 23 16:40:30 1996 Jason Merrill * error.c (dump_expr, case CAST_EXPR): Handle T() properly. * pt.c (instantiate_decl): Don't call push/pop_cp_function_context. * decl.c (struct saved_scope): Remove named_labels, {base,member}_init_list. (maybe_push_to_top_level): Don't set them. Call push_cp_function_context if appropriate. (pop_from_top_level): Likewise. * method.c (do_build_assign_ref): Remove obsolete check of TYPE_HAS_ASSIGN_REF (basetype). * decl.c (grokfndecl): Diagnose user definition of implicitly-declared methods. Thu May 23 12:13:08 1996 Bob Manson * method.c (do_build_copy_constructor): Add code to give meaningful error messages instead of crashing. (do_build_assign_ref): Don't synthesize assignment operators for classes containing reference or const members. * class.c (struct base_info): Remove cant_synth_copy_ctor and cant_synth_asn_ref. (finish_base_struct): Remove the code that tries to conditionalize synthesis of copy constructors & assignment operators based on access permissions. Instead, let it fail when it tries to synthesize the copy constructor. This will give meaningful error messages instead of silently generating code to perform a bitcopy. Wed May 22 11:45:19 1996 Bob Manson * lex.c (real_yylex): Remove old-n-crufty #if 0 code for determining types for constant values. * decl.c (struct named_label_list): Use instead of stuffing random items into a TREE_LIST node. (named_label_uses): Use the new struct. (poplevel): Likewise. (lookup_label): Likewise. (define_label): Add an error message to tell the user the line where the goto is located in addition to the destination of the goto. (init_decl_processing): Use NULL instead of NULL_TREE to initialize named_label_uses. (finish_function): Likewise. (start_decl): Complain about defining a static data member in a different type from which it was declared. Wed May 22 09:33:23 1996 Jason Merrill * cvt.c (build_expr_type_conversion): Adjust. Tue May 21 11:21:56 1996 Jason Merrill * call.c (build_method_call): Always convert 'this' to the appropriate type. * search.c (add_conversions): Put the conversion function in TREE_VALUE, the type in TREE_PURPOSE. * cvt.c (build_type_conversion): Adjust. * call.c (user_harshness): Adjust. * method.c (emit_thunk): Call temporary_allocation and permanent_allocation around the ASM_OUTPUT_MI_THUNK case, too. * tree.c (build_cplus_array_type): Handle tweaking of TYPE_MAIN_VARIANT here. * typeck.c (common_type): Not here. * typeck.c (complete_type): Only try to complete an array type if it has a domain. Mon May 20 14:55:59 1996 Jason Merrill * decl.c (grokvardecl): Call complete_type. (grokdeclarator): Call complete_type for PARM_DECLs. Fri May 17 16:41:17 1996 Jason Merrill * pt.c (instantiate_class_template): Re-set CLASSTYPE_GOT_SEMICOLON after calling finish_struct_1. Fri May 17 14:56:55 1996 Mike Stump * cp-tree.h (cp_expand_decl_cleanup): Remove, the backend is now smart enough to do it right. * tree.c (cp_expand_decl_cleanup): Likewise. * decl.c (cp_finish_decl): Use expand_decl_cleanup instead of cp_expand_decl_cleanup. (store_parm_decls): Likewise. (hack_incomplete_structures): Likewise. * except.c (push_eh_cleanup): Likewise. Fri May 17 13:13:51 1996 Mike Stump * expr.c (expand_expr, cond UNSAVE_EXPR): Move from the C++ frontend to the backend where it belongs. * tree.c (unsave_expr): Likewise. (unsave_expr_now): Likewise. * tree.def (UNSAVE_EXPR): Likewise. * cp-tree.h (unsave_expr): Likewise. (unsave_expr_now): Likewise. Fri May 17 11:02:41 1996 Mike Stump * init.c (emit_base_init): Make sure the partial EH cleanups live on the function_obstack. Thu May 16 15:29:33 1996 Bob Manson * expr.c (do_case): Don't try to dereference null TREE_TYPEs when checking for pointer types. Thu May 16 13:38:58 1996 Jason Merrill * pt.c (instantiate_class_template): Remove obsolete check for access declarations. Thu May 16 13:34:15 1996 Mike Stump * call.c (build_overload_call): Simplify calls to build_overload_call by removing last parameter. (build_method_call): Likewise. * cp-tree.h: Likewise. * method.c (build_opfncall): Likewise. * typeck.c (build_x_function_call): Likewise. Thu May 16 13:15:43 1996 Mike Stump * call.c (default_parm_conversions): Factor out common code. (build_method_call): Use it. (build_overload_call_real): Use it. Wed May 15 14:46:14 1996 Mike Stump * call.c (build_method_call): Allow implicit & on METHOD_TYPEs, but pedwarn as the code is bogus. * typeck.c (decay_conversion): Likewise. (build_function_call_real): Use build_addr_func instead of default_conversion. Don't allow pointer-to-method functions down here. (build_unary_op): Use real pointer-to-member functions instead of fake ones. (build_ptrmemfunc): Use build_addr_func instead of build_unary_op. (convert_for_assignment): Removed some obsolete code. * decl2.c (reparse_absdcl_as_expr): Pass current_class_ref to build_x_function_call instead of current_class_ptr. Only call digest_init once on an initializer, we do this just checking TREE_TYPE. (build_expr_from_tree): Pass current_class_ref to build_x_function_call instead of current_class_ptr. * init.c (build_member_call): Likewise. * pase.y: Likewise. * error.c (dump_expr): Handle OFFSET_REFs better. * pt.c (unify): Handle pointer-to-member functions better. * decl.c (finish_function): Clear out current_class_ref just like we do for current_class_ptr. * typeck.c (get_delta_difference): Handle virtual bases better. Tue May 14 16:37:37 1996 Jason Merrill * sig.c (build_signature_table_constructor): Use the delta for the original basetype for this virtual function with thunks. (build_signature_method_call): We still need to adjust 'this' with thunks. Tue May 14 16:27:25 1996 Mike Stump * call.c (build_addr_func): New routine. Used to get the `real' address of a function or a method. Needed to avoid getting a pointer-to-member function. (build_call): New routine to build CALL_EXPRs. (build_method_call): Use it. * cvt.c (convert_to_aggr): Likewise. * typeck.c (build_function_call_real): Likewise. * sig.c (build_signature_table_constructor): Use build_addr_func. * cp-tree.h (build_call, build_addr_func): Declare them. Tue May 14 12:47:47 1996 Mike Stump * cp-tree.h (LOOKUP_AGGR): Remove, unused. * parse.y: Remove uses of LOOKUP_AGGR. Tue May 14 12:07:51 1996 Mike Stump * *.[chy]: Rename current_class_decl to current_class_ptr, and C_C_D to current_class_ref. Mon May 13 16:55:23 1996 Jason Merrill * call.c (convert_harshness): Tighten up pointer conversions. Sat May 11 04:33:50 1996 Doug Evans * decl2.c (finish_vtable_vardecl): Surround DECL_ONE_ONLY with ifdef. (finish_file): Likewise. Fri May 10 11:09:57 1996 Jason Merrill * cvt.c (convert_fn_ptr): We don't use thunks for pmfs. * method.c (emit_thunk): Set flag_omit_frame_pointer in default code. Thu May 9 18:18:30 1996 Jason Merrill * decl2.c: Turn on thunks by default where supported. Tue May 7 20:39:57 1996 Mike Stump * cp-tree.h (build_overload_call_maybe): Removed. * call.c (build_overload_call_real): Invert meaning of last arg to be require_complete. (build_overload_call): Likewise. * typeck.c (build_x_function_call): Use build_overload_call_real instead of build_overload_call_maybe. Mon May 6 01:23:32 1996 Jason Merrill * decl2.c (finish_file): Don't try to emit functions that haven't been compiled. Fri May 3 09:30:13 1996 Jason Merrill * decl2.c (finish_vtable_vardecl): Oops. * decl.c (maybe_push_to_top_level): Do save previous_class_*. Also store the bindings from previous_class_values. (pop_from_top_level): Restore them. Thu May 2 21:56:49 1996 Jason Merrill * decl2.c (finish_vtable_vardecl): Only write out vtable if its symbol has been referenced. (finish_file): Re-join synthesis/vtable loop with inline emission loop, disable inlining when an inline is output. Thu May 2 17:20:02 1996 Mike Stump * except.c (init_exception_processing): Setup saved_in_catch. (push_eh_cleanup): Reset __eh_in_catch. (expand_start_catch_block): Set __eh_in_catch. Thu May 2 16:21:17 1996 Mike Stump * except.c (push_eh_cleanup): Add tracking for whether or not we have an active exception object. (expand_builtin_throw): Use it to make sure a rethrow without an exception object is caught. Thu May 2 11:26:41 1996 Jason Merrill * decl.c (maybe_push_to_top_level): Clear out class-level bindings cache. Wed May 1 11:26:52 1996 Jason Merrill * decl2.c (finish_file): Also use sentries for vars with DECL_ONE_ONLY or DECL_WEAK set (should any such happen to be created). * lex.c (handle_cp_pragma): Disable #pragma interface/implementation if SUPPORTS_ONE_ONLY > 1. Tue Apr 30 11:25:46 1996 Jason Merrill * method.c (emit_thunk): Wrap default case in temporary/permanent_allocation. * method.c (make_thunk): Use DECL_ONE_ONLY. (emit_thunk): Call assemble_end_function. Mon Apr 29 15:38:29 1996 Jason Merrill * decl2.c (import_export_vtable): Use DECL_ONE_ONLY. (import_export_decl): Likewise. (finish_prevtable_vardecl): Disable vtable hack if SUPPORTS_ONE_ONLY > 1. Mon Apr 29 14:32:47 1996 Mike Stump * typeck.c (build_modify_expr): PREINCREMENT_EXPR and PREDECREMENT_EXPRs take two arguments, not one. Mon Apr 29 00:27:53 1996 Jason Merrill * class.c (build_vtable_entry): Don't build thunks for abstract virtuals. * lex.c (real_yylex): Fix handling of __PRETTY_FUNCTION__ like C frontend. Sat Apr 27 16:45:35 1996 Jason Merrill * class.c (set_rtti_entry): Use size_zero_node. (build_vtable): Likewise. Sat Apr 27 14:48:57 1996 Jason Merrill * class.c (finish_struct_1): Pass size_zero_node to set_rtti_entry. (prepare_fresh_vtable): Likewise. Fri Apr 26 13:14:14 1996 Jason Merrill * method.c (emit_thunk): Call mark_used on the target function. * call.c (build_method_call): Don't warn about pending templates. Thu Apr 25 14:55:44 1996 Jason Merrill * decl2.c (finish_file): Fix list walking logic. * typeck2.c (check_for_new_type): Only warn if -pedantic. Wed Apr 24 15:41:15 1996 Bob Manson * class.c (finish_struct_1): Remove old code for dont_allow_type_definitions. * cp-tree.h: Likewise. * spew.c: Make sure cp-tree.h is included before parse.h, so the definition of flagged_type_tree is found before it is used. * lex.c: Likewise. * parse.y: Added the ftype member to the type union, and changed a number of rules to use it instead of ttype. Added calls to check_for_new_type() as appropriate. * typeck2.c (check_for_new_type): New function for checking if a newly defined type appears in the specified tree. * cp-tree.h: Add new type flagged_type_tree. Add a prototype for check_for_new_type(). Wed Apr 24 00:36:21 1996 Jason Merrill * decl2.c (finish_file): Only use a sentry if the decl is public. * pt.c (tsubst_expr, DECL_STMT): If we don't have an initializer, don't pass LOOKUP_ONLYCONVERTING. Tue Apr 23 17:18:47 1996 Bob Manson * typeck.c (common_type): Fix the ARRAY_TYPE case so it properly keeps track of const and volatile type modifiers. Tue Apr 23 10:52:56 1996 Jason Merrill * tree.c (cp_tree_equal): C++ version of simple_cst_equal. * pt.c (comp_template_args): Use it. * rtti.c (get_tinfo_fn, build_dynamic_cast, expand_*_desc): Call assemble_external for artificial function decls. * decl.c (cp_finish_decl): Oops. Mon Apr 22 17:28:27 1996 Jason Merrill * decl2.c (import_export_decl): Put static data member templates into common storage, or make them weak, depending on whether they are dynamically or statically initialized. (get_sentry): New function. (finish_file): Do import_export_decl for static data members before building the init/fini functions. Don't init/fini a variable that's EXTERNAL. Use a sentry for variables in common. Fix mismatching push/pop_temp_slots. * decl.c (cp_finish_decl): If DECL_NOT_REALLY_EXTERN, do the expand_static_init thang. * method.c (get_id_2): New function. Mon Apr 22 15:32:45 1996 Bob Manson * parse.y (empty_parms): Make sure we use C++-style prototypes when we're declaring member functions. Sun Apr 21 10:08:22 1996 Jason Merrill * Makefile.in (CONFLICTS): 16 s/r conflicts. * parse.y (self_template_type): New nonterminal. Thu Apr 18 08:56:54 1996 Jason Merrill * decl.c (make_typename_type): Handle getting a TYPE_DECL for a name. * parse.y (base_class.1): Allow 'typename foo::bar'. * lex.c (check_newline): Remove #pragma code that plays with the input stream, since we now deal with tokens. Clear nextchar when we're done. (handle_cp_pragma): Use real_yylex. (handle_sysv_pragma): Don't do skipline here. Only call real_yylex in one place. * lex.c (check_for_missing_semicolon): Handle SELFNAME. * lex.c (handle_cp_pragma): Fix "#pragma implementation". Wed Apr 17 16:51:33 1996 Jason Merrill * parse.y: New token SELFNAME for potential constructor. * spew.c (yylex): Handle it. * lex.c (identifier_type): Produce it. * parse.y (complete_type_name): In :: case, don't push class binding. (complex_type_name): Likewise. Wed Apr 17 15:02:40 1996 Mike Stump * typeck.c (build_reinterpret_cast): Handle pointer to member functions. Wed Apr 17 12:28:26 1996 Brendan Kehoe * lex.c (handle_cp_pragma): New function, with decl, doing the cc1plus pragmas. (check_newline): Put the vtable/unit/implementation/interface pragma code into handle_cp_pragma, replacing it with a call. (handle_sysv_pragma): Give int return type, and take FINPUT and TOKEN args. Get the next token after handling the pragma token. Wed Apr 17 10:28:34 1996 Jason Merrill * cvt.c (cp_convert_to_pointer): Avoid doing base analysis on pmfs. (convert_to_pointer_force): Likewise. * init.c (build_new): Fix array new without -fcheck-new. Tue Apr 16 13:44:58 1996 Jason Merrill * cp-tree.h, call.c, class.c, decl.c, parse.y, pt.c, rtti.c, tree.c: Lose TYPE_NESTED_NAME. * parse.y (nested_name_specifier_1): Don't treat non-identifiers as identifiers. * tree.def: Add VEC_INIT_EXPR. * expr.c (cplus_expand_expr): Handle it. * init.c (build_new): Use it instead of the RTL_EXPR nastiness and the extra file-scope symbol nastiness. Mon Apr 15 16:21:29 1996 Jason Merrill * method.c (make_thunk): Thunks are static. (emit_thunk): Use ASM_OUTPUT_MI_THUNK if it's defined. * decl2.c (mark_vtable_entries): Emit thunks as needed. (finish_file): Don't emit them here. Sun Apr 14 11:34:39 1996 Jason Merrill * rtti.c (build_dynamic_cast): Handle null pointers. (ifnonnull): New function. Fri Apr 12 09:08:27 1996 Bob Manson * call.c (build_method_call): Remember the original basetype we were called with. Give an error message instead of trying (incorrectly) to call a non-static member function through a non-inherited class. * search.c (expand_upcast_fixups): Mark the new fixup as DECL_ARTIFICIAL. Thu Apr 11 03:57:09 1996 Jason Merrill * init.c (build_new): Use a TARGET_EXPR for alloc_expr. * class.c (set_rtti_entry): Fix for thunks. * decl2.c (import_export_decl): Still emit typeinfo fns for cv-variants of builtin types. * rtti.c (expand_class_desc): Set up base_info_type_node here. (init_rtti_processing): Instead of here. Wed Apr 10 14:17:13 1996 Jason Merrill * rtti.c (init_rtti_processing): Do init regardless of -frtti. (build_typeid): Only complain about taking dynamic typeid without -frtti. * decl2.c: flag_rtti defaults to 1. * rtti.c (get_tinfo_var): The general class case is now smaller. (init_rtti_processing): Pack the latter three fields of base_info into 32 bits. Wed Apr 10 13:50:14 1996 Mike Stump * init.c (expand_member_init): Don't dump if name is NULL_TREE. Wed Apr 10 12:56:02 1996 Mike Stump * search.c (make_memoized_table_entry): Undefer the pop, if necessary. (push_memoized_context): Split out code to undefer pop_type_level to (clear_memoized_cache): here. (pop_memoized_context): We can only handle one layer of deferral of pop_type_level so clear the cache, if there was a previous level. Tue Apr 9 23:06:09 1996 Jason Merrill * rtti.c (init_rtti_processing): Build up base_info_type_node. (expand_class_desc): Use one pointer to an array of base_info structs, passed using a CONSTRUCTOR. Tue Apr 9 14:20:57 1996 Mike Stump * class.c (build_vbase_path): Remove block extern for flag_assume_nonnull_objects here. (build_vfn_ref): Split out functionality into build_vtbl_ref. (build_vtbl_ref): New routine. (build_vtable): Set up rtti info here. (add_virtual_function): Note in CLASSTYPE_RTTI the best place where we can get the rtti pointers from to avoid having to search around for a place. (finish_base_struct): Likewise. (finish_struct_1): Likewise. Never create totally new vtables with totally new vtable pointers for rtti. Disable code to layout vtable pointers better until we want to break binary compatibility. * rtti.c (build_headof_sub): New routine to convert down to a sub-object that has an rtti pointer in the vtable. (build_headof): Use it. Also, use build_vtbl_ref now to be more maintainable. (build_dynamic_cast): Make sure we have saved it, if we need to. * search.c (dfs_init_vbase_pointers): Disable code that deals with a more efficient vtable layout, enable later. * call.c (flag_assume_nonnull_objects): Moved declaration to * cp-tree.h: here. Declare build_vtbl_ref. * pt.c (instantiate_class_template): Use NULL_TREE instead of 0 in function calls that want a tree. Tue Apr 9 12:10:26 1996 Jason Merrill * rtti.c (build_dynamic_cast): Handle downcasting to X* given other X subobjects in the most derived type. Ack. * rtti.c (build_dynamic_cast): No need to strip cv-quals here, get_typeid will do it for us. (get_typeid_1): Break out call-building for expand_*_desc to use. (get_typeid): Call it. (expand_*_desc): Likewise. * decl.c (init_decl_processing): Don't set TYPE_BUILT_IN on char * and void *. (init_decl_processing): Lose builtin_type_tdescs lossage. * decl2.c (finish_vtable_vardecl): Remove obsolete code. Mon Apr 8 17:23:23 1996 Bob Manson * pt.c (tsubst): When calling set_nested_typename, use TYPE_NESTED_NAME (current_class_type) instead of current_class_name. * decl.c (pushdecl): Likewise. (pushdecl_class_level): Likewise. (grokdeclarator): Use NULL_TREE instead of 0 in the call to set_nested_typename. Sun Apr 7 10:44:31 1996 Jason Merrill * rtti.c (synthesize_tinfo_fn): Handle arrays. * cp-tree.h (DECL_REALLY_EXTERN): New macro. Sat Apr 6 13:56:27 1996 Jason Merrill * rtti.c (throw_bad_cast): Use entry point __throw_bad_cast. (init_rtti_processing): Lose bad_cast_type. (build_dynamic_cast): Use throw_bad_cast. * rtti.c (synthesize_tinfo_fn): Handle enums and pmfs. * decl2.c (finish_file): Don't synthesize artificial functions that are external and not inline. * rtti.c (get_tinfo_fn): If at_eof, call import_export_decl. * decl2.c (finish_file): Handle having new inlines added to saved_inlines by synthesis. * rtti.c (get_bad_cast_node): Don't require . Fri Apr 5 17:02:09 1996 Jason Merrill RTTI rewrite to initialize nodes as needed, not require that users #include , complete functionality and reduce wasted space. * rtti.c (init_rtti_processing): New fn. (build_typeid): The vtable entry is now a function. (get_tinfo_var): New fn. (get_tinfo_fn): Likewise. (get_typeid): Use it. (build_dynamic_cast): Declare and use entry point __dynamic_cast. (build_*_desc): Rename to expand_*_desc and rewrite to use entry points __rtti_*. (add_uninstantiated_desc, get_def_to_follow, build_t_desc): Lose. (synthesize_tinfo_fn): New fn. * method.c (build_t_desc_overload): Lose. (build_overload_with_type): More generic. * decl.c (init_decl_processing): Call init_rtti_processing. * class.c (set_rtti_entry): Use get_tinfo_fn. * decl2.c (mark_vtable_entries): Mark the rtti function. (finish_prevtable_vardecl): Don't build_t_desc. (import_export_decl): Handle tinfo functions. (finish_file): Likewise. * typeck.c (inline_conversion): New fn. (build_function_call_real): Use it. * cp-tree.h: Add decls. * method.c (hack_identifier): Also convert component_refs from references. * lex.c (cons_up_default_function): Use the type, not the name, in declspecs. * decl2.c (import_export_vtable): Fix weak vtables. Fri Apr 5 13:30:17 1996 Bob Manson * search.c (get_base_distance_recursive): Fix access checks for protected bases. Fri Apr 5 11:02:06 1996 Brendan Kehoe * call.c (unary_complex_lvalue): Delete unneeded decl, it's in cp-tree.h. (convert_harshness): Add prototypes wrapped by PROTO. * decl2.c (grok_function_init): Likewise. (do_toplevel_using_decl): Change to void return type. * class.c (build_vtable_entry): Remove decl of make_thunk. (merge_overrides): Fix order of arg definitions. (finish_vtbls): Likewise. (fixup_vtable_deltas): Likewise. (modify_all_direct_vtables): Likewise. (modify_all_indirect_vtables): Likewise. * search.c (get_base_distance_recursive): Likewise. (get_abstract_virtuals_1): Likewise. (fixup_virtual_upcast_offsets): Likewise. (lookup_fnfields_1): Add prototypes wrapped by PROTO. * init.c (perform_member_init): Fix order of arg definitions. (expand_aggr_init_1): Add prototypes wrapped by PROTO. * cp-tree.h (make_thunk): Add decl. (overload_template_name, push_template_decl): Add decls. (do_toplevel_using_decl): Change to void return type. (vec_binfo_member): Add decl. Thu Apr 4 13:33:10 1996 Brendan Kehoe * typeck.c (mark_addressable, convert_for_assignment, convert_for_initialization, pointer_int_sum, pointer_diff, unary_complex_lvalue): Add prototypes wrapped by PROTO. (convert_sequence): #if 0 fn decl, since definition also is. Thu Apr 4 11:00:53 1996 Mike Stump * rtti.c (build_dynamic_cast): Make sure we strip qualifiers on cast to pointer types for type searching. Wed Apr 3 17:10:57 1996 Brendan Kehoe * typeck.c (get_delta_difference): Use cp_error, not error, in the case where BINFO == 0. Wed Apr 3 12:01:02 1996 Mike Stump * call.c (build_method_call): Fix wording of error messages so constructors come out right. Tue Apr 2 16:06:59 1996 Bob Manson * decl.c (push_overloaded_decl): Don't warn about hidden constructors when both the type and the function are declared in a system header file. Mon Apr 1 09:03:13 1996 Bob Manson * class.c (finish_struct_1): Propagate the TYPE_PACKED flag for the type to the type's fields. Sat Mar 30 12:14:33 1996 Brendan Kehoe * parse.y (complex_parmlist, ELLIPSES): Take out ARM-based warning. Fri Mar 29 15:51:36 1996 Bob Manson * class.c (base_info, finish_base_struct): Replace needs_virtual_dtor with base_has_virtual. (finish_struct_1): Remove the old code that tried to make default destructors virtual. Use base_has_virtual when checking if we need to add a vtable entry for the rtti code. Fri Mar 29 14:02:36 1996 Jason Merrill * pt.c (push_template_decl): Complain about template decl with inappropriate declaration. Fri Mar 29 12:15:35 1996 Bob Manson * typeck.c (build_x_unary_op): Remove bogus check for taking the address of a member function. Fri Mar 29 11:56:02 1996 Jason Merrill * parse.y (constructor_declarator): Only push the class if we are not already in the class. Fri Mar 29 09:41:02 1996 Jeffrey A. Law * method.c (emit_thunk): Remove current_call_is_indirect nonsense. Add additional argument to INIT_CUMULATIVE_ARGS. Thu Mar 28 16:41:39 1996 Jason Merrill * decl.c (shadow_tag): Fix error about anon union with methods. * parse.y (self_reference): Only generate a self-reference if this is a non-template class. (opt.component_decl_list): Only use it if it was generated. * parse.y (component_decl_1): Use constructor_declarator. (fn.def2): Likewise. (notype_component_declarator0): Likewise. Thu Mar 28 15:11:35 1996 Bob Manson * typeck.c (build_x_unary_op): Add checks for taking the address of a TARGET_EXPR or of a member function, and give appropriate warnings. Thu Mar 28 14:49:26 1996 Jason Merrill * pt.c (process_template_parm): Allow template type parms to be used as types for template const parms. Wed Mar 27 15:51:19 1996 Mike Stump * init.c (expand_vec_init): Ensure the eh cleanups are on the function_obstack. Wed Mar 27 10:14:30 1996 Jason Merrill * decl.c (lookup_name_real): Be even more picky about the ambiguous lookup warning. (grokdeclarator): Tweak SCOPE_REF constructor declarators here. * parse.y (constructor_declarator): Rather than here. * parse.y (constructor_declarator): New nonterminal. (fn.def1): Use it. (explicit_instantiation): Likewise. Tue Mar 26 13:41:33 1996 Jason Merrill Add implicit declaration of class name at class scope. * decl.c (lookup_name_real): Restrict pedwarn about ambiguous lookup. * parse.y (self_reference): New nonterminal. (opt.component_decl_list): Use it. (fn.def1): Add nested_name_specifier type_name cases. * class.c (build_self_reference): New function. (finish_struct): Handle access_default later, move self-reference decl to the end. * pt.c (lookup_template_class): Handle getting a TYPE_DECL. * cp-tree.h: Adjust. * pt.c (do_function_instantiation): Separate handling of member functions and non-member functions properly. Mon Mar 25 14:23:22 1996 Jason Merrill * pt.c (process_template_parm): Improve error for 'volatile class K'. * class.c (finish_struct_1): Check the right slot for destructors. * decl.c (start_enum): Complain about enum templates. Mon Mar 25 13:25:31 1996 Mike Stump * init.c (resolve_offset_ref): Offset pointers to member data by one. * typeck.c (unary_complex_lvalue): Likewise. Mon Mar 25 13:30:42 1996 Bob Manson * typeck.c (c_expand_return): Check for a returned local array name, similar to the check for an ADDR_EXPR. Mon Mar 25 13:07:19 1996 Jason Merrill * decl.c (cp_finish_decl): Don't build cleanups for static variables here. Fri Mar 22 17:57:55 1996 Mike Stump * typeck.c (build_modify_expr): Fix error messages to be more accurate. * cp-tree.h (assop_as_string): Parallel to op_as_string, but for assignment operators. * error.c (assop_as_string): Likewise. Add support for `%Q' for assignment operators. Fri Mar 22 13:48:29 1996 Jason Merrill * decl.c (grokdeclarator): Call bad_specifiers for typedefs. Also give an error if initialized. pedwarn about nested type with the same name as its enclosing class. * pt.c (tsubst, case TYPE_DECL): Set DECL_CONTEXT. * typeck.c (require_complete_type): Be sure to instantiate the MAIN_VARIANT of the type. * decl2.c (finish_file): Instantiate pending templates before processing static constructors and destructors. * pt.c (instantiate_decl): Don't instantiate functions at toplevel unless at_eof. Fri Mar 22 09:30:17 1996 Bob Manson * decl2.c (delete_sanity): If error_mark_node is passed in as an expression, quit while we're ahead. * decl.c (grokdeclarator): Give an error message if `friend' is combined with any storage class specifiers. Wed Mar 20 14:51:55 1996 Jason Merrill * parse.y (named_complex_class_head_sans_basetype): Don't crash on definition of nonexistent nested type. * error.c (dump_decl, case TYPE_DECL): Fix decision for whether or not to say 'typedef'. Wed Mar 20 00:11:47 1996 Brendan Kehoe * cp-tree.h (struct lang_type): Make search_slot a tree, not a char*. * search.c (dfs_walk, dfs_init_vbase_pointers, expand_upcast_fixups): Remove cast of CLASSTYPE_SEARCH_SLOT. (dfs_find_vbases): Remove cast for CLASSTYPE_SEARCH_SLOT init. Tue Mar 19 17:56:03 1996 Jason Merrill * except.c (build_throw): Support minimal parse. * pt.c (tsubst_copy): Support THROW_EXPR. * decl2.c (build_expr_from_tree): Likewise. * pt.c (mangle_class_name_for_template): Always allocate scratch_firstobj. Tue Mar 19 16:34:31 1996 Bob Manson * cvt.c (cp_convert_to_pointer): Give an appropriate error when trying to cast from an incomplete type. Tue Mar 19 16:00:33 1996 Jason Merrill * pt.c (instantiate_class_template): Don't bother setting up CLASSTYPE_TAGS explicitly, as the nested types will add themselves. Tue Mar 19 15:48:43 1996 Bob Manson * decl.c (shadow_tag): Remove old error check for usage of an enum without a previous declaration. (xref_tag): Add error message about usage of enums without a previous declaration. Tue Mar 19 09:21:35 1996 Jason Merrill * lex.c (do_identifier): Only do name consistency check if we're parsing. * pt.c (push_template_decl): Don't crash if we get a member defn that doesn't match. * decl.c (xref_tag_from_type): New function to do an xref without always having to figure out code_type_node. * cp-tree.h: Declare it. * pt.c (instantiate_class_template): Use it for friend classes. (lookup_template_class): Use it. * typeck2.c (build_functional_cast): Pull out a single parm before passing it to build_c_cast. Tue Mar 19 09:07:15 1996 Bob Manson * expr.c (do_case): Give an error message if a pointer is given as a case value. Mon Mar 18 21:57:54 1996 Jason Merrill * typeck.c (build_c_cast): Don't pull single TEMPLATE_DECL out of an overload list. * lex.c (cons_up_default_function): Really, now, interface hackery does not apply to synthesized methods. Mon Mar 18 18:20:57 1996 Mike Stump * call.c (build_method_call): Ctors and dtors now have special names with respect to lookups. * class.c (add_method): Likewise. (grow_method): Likewise. (finish_struct_methods): Likewise. (warn_hidden): Likewise. (finish_struct_1): Likewise. * cvt.c (convert_to_reference): Likewise. (convert_to_aggr): Likewise. (cp_convert): Likewise. * decl2.c (check_classfn): Likewise. * init.c (expand_member_init): Likewise. (expand_default_init): Likewise. (expand_aggr_init_1): Likewise. (build_offset_ref): Likewise. (build_new): Likewise. (build_delete): Likewise. * lex.c (do_inline_function_hair): Likewise. * search.c (lookup_field_1): Likewise. (lookup_fnfields_here): Likewise. (lookup_field): Likewise. (lookup_fnfields): Likewise. (get_virtual_destructor): Likewise. (dfs_debug_mark): Likewise. (dfs_pushdecls): Likewise. (dfs_compress_decls): Likewise. * tree.c (layout_basetypes): Likewise. * typeck.c (build_component_ref): Likewise. (build_x_function_call): Likewise. (build_modify_expr): Likewise. (convert_for_initialization): Likewise. (build_functional_cast): Likewise. * cp-tree.h (CLASSTYPE_FIRST_CONVERSION): Likewise. (CTOR_NAME): New. (DTOR_NAME): New. * decl.c (ctor_identifier): New. (dtor_identifier): New. (init_decl_processing): Set them. Mon Mar 18 18:00:51 1996 Mike Stump * typeck.c (build_component_ref): Don't get confused by fields whose context has no type name, like pointer to member functions. Mon Mar 18 13:19:03 1996 Jason Merrill * decl.c (grokdeclarator): Handle typedef without declarator. * pt.c (tsubst): Handle SCOPE_REF in declarator. * parse.y (bad_parm): Catch another case of missing `typename'. * lex.c (yyprint): Handle TYPE_DECLs. * decl.c (start_function): Don't try to be clever. * lex.c: Lose compiler_error_with_decl. * typeck2.c: Lose error_with_aggr_type. (incomplete_type_error): Use cp_* instead of old functions. (readonly_error): Likewise. * typeck.c (convert_arguments): Likewise. * search.c (lookup_nested_field): Likewise. * method.c (make_thunk): Likewise. * decl.c (grokparms): Likewise. * cp-tree.h: Update. * tree.c (min_tree_cons): Call copy_to_permanent for the purpose and value. Mon Mar 18 11:25:52 1996 Bob Manson * method.c (build_opfncall): When deleting a pointer to an array, build a new pointer to the tree past any ARRAY_TYPE nodes. Mon Mar 18 10:11:46 1996 Brendan Kehoe * decl.c (lookup_name_real): Initialize local var TYPE to NULL_TREE. Fri Mar 15 11:03:57 1996 Jason Merrill * pt.c (instantiate_decl): Only call import_export_decl if at_eof and ! DECL_INLINE. * decl.c (finish_function): Don't set nested based on hack_decl_function_context. * parse.y (function_try_block): Check for nested function. (pending_inlines): Likewise. * decl2.c (build_expr_from_tree): If a unary op already has a type, just return it. * decl2.c (finish_prevtable_vardecl): Use ADJUST_VTABLE_LINKAGE. * decl2.c (walk_vtables): vardecl_fn returns int; return 1 if it does. (finish_file): Check the return value of walk_vtables. (finish_prevtable_vardecl): Return int. (finish_vtable_vardecl): Likewise. (prune_vtable_vardecl): Likewise. * lex.c (set_vardecl_interface_info): Likewise. * cp-tree.h: Adjust return types. * class.c (delete_duplicate_fields_1): Don't complain about duplicate nested types if they're the same type. (finish_struct): Remove check for duplicate. * decl2.c (grokfield): Don't check for typedef of anonymous type. Thu Mar 14 10:00:19 1996 Jason Merrill * cp-tree.h: Lose SIGNATURE_GROKKING_TYPEDEF. * decl.c (grokdeclarator): Lose special handling of class-level typedef. Lose SIGNATURE_GROKKING_TYPEDEF. Set SIGNATURE_HAS_OPAQUE_TYPEDECLS later. * cvt.c (convert_pointer_to_real): Retain cv-quals in conversion. * pt.c (tsubst_copy): Strip cv-quals from destructor name types. * search.c (compute_access): Fix handling of anonymous union members. * class.c (finish_struct_anon): Propagate TREE_{PRIVATE,PROTECTED} from anonymous unions to their members. * typeck.c (build_x_function_call): For static member functions, hand off to build_member_call. Wed Mar 13 14:03:34 1996 Jason Merrill * typeck.c (build_component_ref): Handle OFFSET_REFs. * init.c (expand_vec_init): Fix init == 0 case. Tue Mar 12 14:36:02 1996 Jason Merrill * init.c (build_new): pedwarn about init and array new. (expand_vec_init): Handle lists, use convert_for_initialization. * typeck.c (convert_for_initialization): Pass LOOKUP_NO_CONVERSION when converting to an aggregate type. * cvt.c (cp_convert): Pass it through. * typeck.c (build_conditional_expr): Handle user-defined conversions to slightly different types. * decl.c (grokdeclarator): Force an array type in a parm to be permanent. * decl2.c (do_using_directive): Sorry. (do_namespace_alias): Likewise. * lex.c (real_yylex): Warn about using the `namespace' keyword. Sun Mar 10 22:26:09 1996 Jason Merrill * parse.y (datadef): Move call to note_list_got_semicolon up. Fri Mar 8 11:47:26 1996 Mike Stump * tree.c (unsave_expr): Don't unsave, UNSAVE_EXPRs. Fri Mar 8 11:29:06 1996 Mike Stump * decl.c (cp_finish_decl): The exception regions have to be nested, not overlapping. We start the exception region for a decl, after it has been fully built, and all temporaries for it have been cleaned up. Thu Mar 7 17:46:06 1996 Mike Stump * tree.c (vec_binfo_member): Don't core dump if we have no bases. Thu Mar 7 14:11:49 1996 Jason Merrill * tree.def: Add RETURN_INIT. * pt.c (instantiate_decl): Handle RETURN_INIT. * decl.c (store_return_init): Handle minimal_parse_mode. * tree.c (cp_build_type_variant): Just return an error_mark_node. * decl.c (make_typename_type): Don't try to get the file and line of an identifier. * typeck.c (comptypes): Handle TYPENAME_TYPE. Wed Mar 6 18:47:50 1996 Per Bothner * decl.c (poplevel): Make sure we clear out and restore old local non-VAR_DECL values by default when they go out of scope. Wed Mar 6 09:57:36 1996 Jason Merrill * method.c (build_overload_value): Use DECL_ASSEMBLER_NAME in referring to addresses of variables and functions. * error.c (dump_expr): Support SIZEOF_EXPR. * init.c (do_friend): Use the return value of check_classfn. * typeck.c (convert_arguments): Call complete_type. * method.c (hack_identifier): After giving an error, set value to error_mark_node. Tue Mar 5 16:00:15 1996 Jason Merrill * tree.c (hack_decl_function_context): Kludge around DECL_CONTEXT lossage for local classes. * cp-tree.h: Declare it. * decl.c (lookup_name_real): Evil, painful hack for local classes. (grokfndecl): Set DECL_CLASS_CONTEXT and DECL_NO_STATIC_CHAIN here. Use hack_decl_function_context. (grokdeclarator): Don't set DECL_NO_STATIC_CHAIN here. (start_function): Use hack_decl_function_context. (finish_function): Likewise. * method.c (synthesize_method): Likewise. * lex.c (process_next_inline): Likewise. (do_pending_inlines): Likewise. * decl2.c (finish_file): Unset DECL_STATIC_FUNCTION_P when we're done with it. Mon Mar 4 22:38:39 1996 Gerald Baumgartner * sig.c (build_signature_pointer_or_reference_type): Align signature pointers/references on 8-byte boundaries so they can be grabbed 2 words at a time on a Sparc. Tue Mar 5 10:21:01 1996 Jason Merrill * method.c (hack_identifier): Requiring a static chain is now a hard error. * decl.c (grokdeclarator): Set DECL_NO_STATIC_CHAIN on nested functions. Mon Mar 4 20:03:33 1996 Jason Merrill * init.c (build_offset_ref): Call complete_type. * decl.c (pop_from_top_level): Always pop previous_class_type. * parse.y: Handle multiple decls in a for-init-statement. * pt.c (tsubst_expr): Likewise. * pt.c (tsubst): Use tsubst_expr for the second operand of an ARRAY_REF. * decl.c (maybe_push_to_top_level): Don't save previous_class_type. (poplevel_class): Set it here. (pop_from_top_level): Pop it here if we're returning to class scope. * class.c (pushclass): Don't set it here. * decl.c (maybe_push_to_top_level): Save current_template_parms, and clear it if !pseudo. (pop_from_top_level): Restore it. * decl2.c (finish_file): Push the dummy each time we walk the list of vtables. * error.c (dump_expr): Support LOOKUP_EXPR and actually do something for CAST_EXPR. Mon Feb 19 14:49:18 1996 Rusty Russell * cvt.c (cp_convert): Warn about implicit conversion of the address of a function to bool, as it is always true. Fri Feb 23 23:06:01 1996 Rusty Russell * typeck.c (c_expand_return): Fix warning for local externs returned. Mon Mar 4 15:03:11 1996 Jason Merrill * tree.c (mapcar): Propagate const and volatile properly. * typeck.c (complete_type): Be sure to instantiate the MAIN_VARIANT of the type. * method.c (synthesize_method): Class interface hackery does not apply to synthesized methods. Mon Mar 4 14:05:23 1996 Jason Merrill * pt.c (comp_template_args): Use comptypes rather than just checking for TEMPLATE_TYPE_PARM equivalence. * typeck.c (build_x_function_call): Call complete_type before checking TYPE_OVERLOADS_CALL_EXPR. Mon Mar 4 18:48:30 1996 Manfred Hollstein * g++.c (main): Check also for new define ALT_LIBM. Fri Mar 1 13:09:33 1996 Jason Merrill * pt.c (instantiate_class_template): If we don't have a pattern yet, that's OK. (coerce_template_parms): If we see a local class, bail. * decl.c (grok_reference_init): Make sure there's a type before checking its code. * pt.c (do_function_instantiation): Avoid crashing on invalid decls. (push_template_decl): Likewise. * parse.y (named_class_head): Set CLASSTYPE_TEMPLATE_SPECIALIZATION here if we have basetypes. * decl.c (xref_tag): Diagnose redeclaration of template type-parameter name. * error.c (dump_type): Handle anonymous template type parms. * pt.c (instantiate_template): Use TYPE_MAIN_DECL instead of TYPE_STUB_DECL. (coerce_template_parms): Likewise. Thu Feb 29 16:26:01 1996 Mike Stump * class.c (instantiate_type, case {ARRAY,INDIRECT}_REF, case ADDR_EXPR): Don't modify rhs if a subinstantiation fails. Thu Feb 29 08:20:25 1996 Jason Merrill * pt.c (instantiate_template): Take the MAIN_VARIANT of the type before trying to get its STUB_DECL. (coerce_template_parms): Likewise. * parse.y (template_type_parm): If they didn't use 'class', pretend they did after giving an error. * pt.c (coerce_template_parms): Diagnose use of local class. * decl.c (grok_reference_init): Use instantiate_type. * error.c (dump_expr): Handle TEMPLATE_DECLs. * parse.y (named_class_head): Diagnose mismatching types and tags. * decl.c (pushdecl): Type decls and class templates clash with artificial type decls, not hide them. * decl.c (redeclaration_error_message): Diagnose redefinition of templates properly. (duplicate_decls): Diagnose disallowed overloads for template functions, too. * decl.c (start_decl): Call complete_type before checking for a destructor. * pt.c (tsubst): Use tsubst_expr on the elts of a VEC. * decl.c (xref_tag): A TEMPLATE_TYPE_PARM is a match. Wed Feb 28 09:28:44 1996 Jason Merrill * decl.c (grok_op_properties): Don't check for operator++(int) in a template. * tree.c (perm_manip): Return a copy of variable and function decls with external linkage. * tree.def: Change some of the min tree codes to type "1". * pt.c (uses_template_parms): Handle 'e's, return 1 for LOOKUP_EXPRs. * method.c (build_overload_int): Emit something arbitrary for anything but an INTEGER_CST if we're in a template. * decl.c (cp_finish_decl): Call complete_type before deciding whether or not to lay out the decl. * lex.c (do_identifier): Check for DECL_INITIAL before using it. Tue Feb 27 16:35:32 1996 Jason Merrill * typeck2.c (build_x_arrow): Call complete_type. * pt.c (add_pending_template): Broken out. (lookup_template_class): If -fexternal-templates, call it for all the methods of implemented types. (instantiate_class_template): Instead of instantiating them here. (instantiate_decl): Handle -fexternal-templates earlier. Tue Feb 27 15:51:32 1996 Brendan Kehoe * search.c, lex.c, decl.c, class.c, cp-tree.h: Don't wrap the memoized lookup stuff inside GATHER_STATISTICS. Tue Feb 27 10:38:08 1996 Jason Merrill * decl.c (start_decl): Complain about array of incomplete type here. (grokdeclarator): Not here. * parse.y (template_parm): Expand full_parm inline so we can set the rule's precedence. * pt.c (tsubst_expr): If we're in a template, just do tsubst_copy. (tsubst): tsubst_expr the DECL_INITIAL of FIELD_DECLs. * decl2.c (grokbitfield): Don't check for integer constant here. * class.c (finish_struct_1): Check here. * decl.c (define_label): Make the min decl go on permanent_obstack. * pt.c (unify): Don't handle CONST_DECLs. (uses_template_parms): Don't check DECL_INITIAL on a CONST_DECL. (tsubst_copy): Likewise. * lex.c (do_identifier): Do pull the DECL_INITIAL out of a CONST_DECL for a template parm. Mon Feb 26 12:48:18 1996 Jason Merrill * decl.c (grokdeclarator): Complain about array of incomplete type here. (start_decl_1): Not here. * pt.c (tsubst): Handle pointer-to-function declarators. * method.c (hack_identifier): If pedantic, diagnose local class methods that require a static chain. * decl.c (grok_op_properties): No longer static. * cp-tree.h: Declare it. * pt.c (tsubst): Call it for operators. Use tsubst_copy for TREE_VECs. * parse.y (template_arg): The expr has precedence like '>'. Fri Feb 23 14:51:52 1996 Jason Merrill * pt.c (coerce_template_parms): Don't coerce an expression using template parms. (uses_template_parms): Also check DECL_INITIAL in CONST_DECLs. (tsubst): Don't use build_index_2_type if the max_value uses template parms. * method.c (build_overload_int): Emit something arbitrary for an expression using template parms. * parse.y (template_close_bracket): New non-terminal to catch use of '>>' instead of '> >' in template class names. (template_type): Use it. * Makefile.in (CONFLICTS): Causes one more r/r conflict. * tree.def: Add CAST_EXPR. * typeck2.c (build_functional_cast): Use CAST_EXPR instead of CONVERT_EXPR for minimal_parse_mode. * typeck.c (build_c_cast): Likewise. * pt.c (tsubst_copy): Likewise. * decl2.c (build_expr_from_tree): Likewise. * error.c (dump_expr): Likewise. Fri Feb 23 10:36:46 1996 Brendan Kehoe * except.c (SetTerminate, SetUnexpected): Put back global vars. (init_exception_processing): Put back decl/init of set_unexpected_fndecl and set_terminate_fndecl, needed to get the fns from libstdc++. * decl.c (struct binding_level): Delete ACCEPT_ANY bitfield. (declare_uninstantiated_type_level, uninstantiated_type_level_p): Delete unused fns. * cp-tree.h (declare_uninstantiated_type_level, uninstantiated_type_level_p): Delete prototypes. Thu Feb 22 19:36:15 1996 Jason Merrill * pt.c (tsubst_expr): Add default return. Thu Feb 22 16:47:24 1996 Brendan Kehoe * error.c (fndecl_as_string): Delete unused arg CNAME. * sig.c (build_signature_table_constructor, build_signature_method_call): Fix calls. * class.c (the_null_vtable_entry): Delete var definition. (init_class_processing): Delete tree the_null_vtable_entry init. * decl.c (no_print_{functions, builtins}): Declare as static. (__tp_desc_type_node): #if 0 var definition. (init_type_desc): #if 0 init of __tp_desc_type_node. (vb_off_identifier): Move var decl into init_decl_processing. (current_function_assigns_this): Declare as static. (int_ftype_ptr_ptr_int, void_ftype_ptr_int_int): Delete var decls. (init_decl_processing): Delete init of void_ftype_ptr_ptr_int. Move decls of string_ftype_ptr_ptr and int_ftype_string_string here. * decl2.c (delete_sanity): Delete definition/mod of local var ELT_SIZE. * init.c (BI_header_type, BI_header_size): Declare as static. * pt.c (template_classes): Delete unused var. (add_pending_template): Delete decl for non-existent fn. (lookup_template_class): Delete vars CODE and TAG_CODE. (instantiate_template): Delete unused var TARGS. * cp-tree.h (vb_off_identifier, current_function_assigns_this): Delete decls. (__tp_desc_type_node): #if 0 var decl. (fndecl_as_string): Fix prototype. Thu Feb 22 15:56:19 1996 Jason Merrill * tree.def: Add GOTO_STMT. * pt.c (tsubst_expr): Support goto and labels. * decl.c (define_label): Support minimal parsing. * parse.y (simple_stmt): Likewise. Thu Feb 22 15:30:12 1996 Brendan Kehoe * xref.c (GNU_xref_member): Only define/set var I if XREF_SHORT_MEMBER_NAMES is defined, to match when it's actually used. (GNU_xref_end_scope): Delete unused fifth arg TRNS. (GNU_xref_end): Fix call. * decl.c (poplevel, poplevel_class, finish_method): Fix calls. * cp-tree.h (GNU_xref_end_scope): Fix prototype. * tree.c (build_exception_variant): Delete unused vars I, A, T, T2, and CNAME. (layout_vbasetypes): Delete unused var NONVIRTUAL_VAR_SIZE. (mapcar): Delete unused var CODE. (build_cplus_new): Delete unused arg WITH_CLEANUP_P. (break_out_cleanups): Fix call. (bot_manip): Likewise. * call.c (build_method_call): Likewise. * cvt.c (build_up_reference, convert_to_reference, cp_convert): Likewise. * typeck.c (unary_complex_lvalue, build_modify_expr, convert_for_initialization): Likewise. * typeck2.c (build_functional_cast): Likewise. * cp-tree.h (build_cplus_new): Fix prototype. * repo.c (open_repo_file): Delete unused var Q. (repo_compile_flags, repo_template_declared, repo_template_defined, repo_class_defined, repo_inline_used, repo_vtable_used, repo_tinfo_used): #if 0 unused fns. (repo_get_id, repo_vtable_used): Declare as static. * cp-tree.h (mark_{decl,class}_instantiated, finish_repo): Add prototypes. Thu Feb 22 14:53:35 1996 Jason Merrill * parse.y (pending_inlines): Add function_try_block case. * pt.c (unify): Fix for template const parms. Thu Feb 22 13:24:15 1996 Brendan Kehoe * lex.c (extract_interface_info): Delete forward decl. (default_copy_constructor_body, default_assign_ref_body): Delete decls for non-existent functions. (synth_firstobj, inline_text_firstobjs): Delete unused vars. (init_lex): Delete setting them. (cons_up_default_function): Delete unused vars FUNC_BUF, FUNC_LEN, and COMPLEX. Delete code setting COMPLEX. Delete old #if 0'd synth code. (toplevel, expression_obstack): Delete unused extern decls. (tree_node_kind): Delete unused enum. (tree_node_counts, tree_node_sizes): Wrap with #ifdef GATHER_STATISTICS. (tree_node_kind_names): Delete unused extern decl. (synth_obstack): Delete unused var. (init_lex): Don't set it. (init_parse): Add decl before use. (reduce_count): Only define #ifdef GATHER_STATISTICS && REDUCE_LENGTH. (current_unit_{name, language}): Delete unused vars. (check_newline): Don't bother setting them, just accept the #pragma. * cp-tree.h (init_repo, peek_yylex): Add prototypes. (current_unit_{name, language}): Delete decls. * search.c: Wrap all of the memoized functions, macros, and variables inside #ifdef GATHER_STATISTICS. (lookup_field, lookup_fnfields): Likewise. (init_search_processing): Likewise. (reinit_search_statistics): Wrap whole function. * lex.c (reinit_lang_specific): Wrap call to reinit_search_statistics. * decl.c (finish_function): Only call pop_memoized_context if GATHER_STATISTICS is defined. (start_function): Likewise for push_memoized_context. * class.c (pushclass, popclass): Likewise. * cp-tree.h (CLASSTYPE_MTABLE_ENTRY): Move definition from here... * search.c (CLASSTYPE_MTABLE_ENTRY): ... to here. * cvt.c (cp_convert): Delete unused local var FORM. * cp-tree.h (can_convert, can_convert_arg, real_lvalue_p): Add prototypes. Thu Feb 22 13:19:44 1996 Jason Merrill * pt.c (do_poplevel): Oops; really return what we get from poplevel this time. Thu Feb 22 11:41:44 1996 Brendan Kehoe * cp-tree.h (is_aggr_type): Add prototype. * cp-tree.h ({push,pop}_cp_function_context): Add decls. * method.c ({push,pop}_cp_function_context): Delete decls. * except.c (start_eh_unwinder, end_eh_unwinder): Declare as void. (SetUnexpected, SetTerminate): Delete unused vars. (init_exception_processing): Don't set SetUnexpected or SetTerminate. Don't set SET_UNEXPECTED_FNDECL or SET_TERMINATE_FNDECL. (output_exception_table_entry): Delete unused array LABEL. (expand_internal_throw): Delete unused var PARAMS. (expand_start_catch_block): Delete unused var CLEANUP. (emit_exception_table): Delete unused var EH_NODE_DECL. (expand_builtin_throw): Delete unused vars UNWIND_AND_THROW and GOTO_UNWIND_AND_THROW. Don't set them. (end_eh_unwinder): Add top decl. (pop_rtl_from_perm): Delete unused decl of PERMANENT_OBSTACK. (exception_section, push_rtl_perm, do_function_call, lang_interim_eh, push_eh_cleanup, eh_outer_context, expand_end_eh_spec, end_eh_unwinder): Declare as static. (saved_pc, saved_throw_type, saved_throw_value, saved_cleanup, throw_used): Likewise. * cp-tree.h (expand_end_eh_spec): Delete prototype. * search.c (dfs_mark, dfs_mark_vtable_path, dfs_unmark_vtable_path, dfs_mark_new_vtable, dfs_unmark_new_vtable, dfs_clear_search_slot, dfs_search_slot_nonempty_p, bfs_markedp, bfs_unmarkedp, bfs_marked_vtable_pathp, bfs_unmarked_vtable_pathp, bfs_marked_new_vtablep, bfs_unmarked_new_vtablep): #if 0 unused functions. (n_fields_searched, n_calls_lookup_field, n_calls_lookup_field_1, n_calls_lookup_fnfields, n_calls_lookup_fnfields_1, n_calls_get_base_type, n_outer_fields_searched, n_contexts_saved): Only define #ifdef GATHER_STATISTICS. (reinit_search_statistics): Only init some vars if GATHER_STATISTICS is defined. (vbase_decl): Delete var definition. (init_search): Delete old decl. (init_vbase_pointers): Delete building of VBASE_DECL, since it's never actually used. (expand_indirect_vtbls_init): Delete init of VBASE_DECL. (get_base_distance_recursive): Delete unused fourth arg BASETYPE_PATH. Fix call . (get_base_distance): Fix call. (push_class_decls): Delete unused var ID. (make_memoized_table_entry): Declare as static. (breadth_first_search): Declare as static. (tree_has_any_destructor_p): Declare as static. (pop_class_decls): Delete unused arg pop_class_decls. * class.c (popclass): Fix call to pop_class_decls. * cp-tree.h (make_memoized_table_entry, breadth_first_search, tree_has_any_destructor_p): Delete prototypes. * rtti.c (build_ptmf_desc): Delete unused arg TYPE. (build_t_desc): Fix call. Delete unused vars ELEMS and TT. (build_dynamic_cast): Delete unused local vars TMP1 and RETVAL. (build_user_desc): Delete unused var T. (build_class_desc): Delete unused vars T and OFF. (build_t_desc): Delete unused var NAME_STRING. (build_headof): Make static. (get_bad_cast_node): Likewise. (get_def_to_follow): Likewise. * cp-tree.h (init_type_desc): Add prototype. (build_headof): Remove prototype. Thu Feb 22 00:54:22 1996 Jason Merrill * pt.c (tsubst): Only look for matching decls at file scope for non-member functions. * call.c (build_scoped_method_call): Handle scoped destructor calls in templates. * decl.c (*_top_level): Also save previous_class_values. * pt.c (tsubst_expr): Support do {} while loops. * parse.y (simple_stmt): Likewise. * tree.def: Likewise. * method.c (build_overload_identifier): For a class nested in a template class, don't mangle in the template parms from our context. * lex.c, cp-tree.h: Remove support for template instantiations in the pending_inlines code. * pt.c: Remove dead functions and unused arguments. (uses_template_parms): TYPENAME_TYPEs always use template parms. * parse.y: Stop passing anything to end_template_decl. * tree.c (print_lang_statistics): Only print tinst info #ifdef GATHER_STATISTICS. Wed Feb 21 16:57:33 1996 Brendan Kehoe * init.c (expand_recursive_init{,_1}): Delete decls. (sort_member_init): Delete unused var INIT. (emit_base_init): Delete unused var X. (build_offset_ref): Delete unused var CNAME. (sort_member_init): Delete unused var FIELDS_TO_UNMARK. (emit_base_init): Delete unused local var BASE. Delete extern decl of IN_CHARGE_IDENTIFIER. (build_delete): Delete unused local var VIRTUAL_SIZE. * init.c (build_vec_delete): Delete unused third arg ELT_SIZE. (build_delete): Fix call. * decl2.c (delete_sanity): Likewise. * cp-tree.h (build_vec_delete): Update prototype. * typeck.c (common_base_type): Delete unused var TMP. (build_binary_op): Delete local var ARGS_SAVE. (build_array_ref): Delete unused var ITYPE. (c_expand_return): Delete unused var USE_TEMP. * typeck.c (compexcepttypes): Delete unused arg STRICT. (comptypes): Fix calls. * decl.c (duplicate_decls): Likewise. * cp-tree.h (compexcepttypes): Delete extra arg. * decl2.c (check_classfn): Delete unused second arg CNAME. * decl.c (start_decl, grokfndecl): Fix calls. * init.c (do_friend): Likewise. * cp-tree.h (check_classfn): Update prototype. * cp-tree.h (signature_error, import_export_vtable, append_signature_fields, id_in_current_class, mark_used, copy_assignment_arg_p): Add decls. * decl2.c (mark_used): Delete decl. * class.c (n_*): Wrap with #ifdef GATHER_STATISTICS. * class.c (get_vtable_entry): Disable unused function. (doing_hard_virtuals): Delete unused static global var. (finish_struct_1): Don't init DOING_HARD_VIRTUALS. (prepare_fresh_vtable): Delete unused vars PATH and RESULT. (overrides): Delete unused vars RETTYPE and BASE_RETTYPE. (modify_one_vtable): Delete unused var OLD_RTTI. (finish_struct_anon): Delete unused vars OFFSET and X. (finish_struct_bits): Delete unused var METHOD_VEC. (get_basefndecls): Delete unused var PURPOSE. Delete unused for-scope local variable METHODS. * call.c (user_harshness): Delete unused/unneeded arg PARM. (ideal_candidate): Delete unused args BASETYPE and PARMS. (build_method_call): Delete unused args passed into ideal_candidate. (build_overload_call_real): Likewise. Delete unused var OVERLOAD_NAME. * cp-tree.h (synthesize_method): Add decl. * decl.c (note_level_for_for): Give void return type. (pushdecl_nonclass_level): Likewise. (finish_function): Delete unused vars VFIELDS and ALLOCATED_THIS. (poplevel): Delete unused var IMPLICIT_TRY_BLOCK. (suspend_binding_level): Delete unused var LEVEL. (duplicate_decls): Delete unused var CTYPE. (duplicate_decls): Delete unused var PREVIOUS_C_DECL. (init_decl_processing): Delete unused vars FLOAT_ENDLINK and PTR_ENDLINK. (grokdeclarator): Delete unused var C. (grokdeclarator): Delete unused var SIZE_VARIES. (grokparms): Delete unused var SAW_VOID. (start_function): Delete unused var OLDDECL. (cplus_expand_expr_stmt): Delete unused var REMOVE_IMPLICIT_IMMEDIATELY. * cp-tree.h (pushdecl_nonclass_level): Fix prototype. * Makefile.in (CONFLICTS): Update to 12 shift/reduce. Wed Feb 21 00:06:17 1996 Jason Merrill * tree.c (build_min): Set TREE_COMPLEXITY to lineno. (build_min_nt): Likewise. * pt.c (do_pushlevel): Emit line note. (do_poplevel): Return what we get from poplevel. (tsubst_expr): Set lineno from TREE_COMPLEXITY in stmt nodes. * parse.y: Use do_pushlevel and do_poplevel. * cp-tree.h: Declare do_poplevel. * cp-tree.h: Declare at_eof. * decl.c (cp_finish_decl): Pass it to rest_of_decl_compilation. * decl2.c (import_export_decl): Renamed from import_export_inline. (finish_file): Call it to do interface handling for statics. * pt.c (tsubst_copy): Call mark_used on variables and functions used here. * decl2.c (finish_file): Don't emit statics we can't generate. * pt.c (instantiate_decl): Don't set interface on instantiations we can't generate. * cp-tree.h (struct tinst_level): Change 'classname' to 'decl'. * tree.c (print_lang_statistics): Print max template depth. * pt.c (push_tinst_level): Dump entire instantiation context. (instantiate_class_template): Use it and pop_tinst_level. (instantiate_decl): Likewise. * call.c class.c cp-tree.h decl.c decl2.c error.c lex.c method.c pt.c ptree.c tree.def: Remove all traces of UNINSTANTIATED_P_TYPE. Tue Feb 20 18:21:51 1996 Jason Merrill * call.c class.c cp-tree.h cvt.c decl.c decl2.c error.c expr.c init.c lex.c method.c parse.y pt.c repo.c search.c spew.c tree.c tree.def typeck.c typeck2.c xref.c: Massive, systemic changes for the new template implementation. Tue Feb 20 17:14:29 1996 Brendan Kehoe * decl2.c (check_cp_case_value): Use STRIP_TYPE_NOPS. Thu Feb 15 18:44:42 1996 Mike Stump * decl.c (cp_finish_decl): Delay emitting the debug information for a typedef that has been installed as the canonical typedef, if the type has not yet been defined. Thu Feb 15 09:39:08 1996 Jason Merrill * decl2.c (grokfield): Still call pop_nested_class for access decls. Wed Feb 14 17:30:04 1996 Brendan Kehoe * decl.c (lookup_label): Call label_rtx. * decl.c (make_binding_level): New function. (pushlevel, pushlevel_class): Call it instead of explicit duplicate calls to xmalloc. * decl.c (init_decl_processing): Delete useless build_pointer_type call. * decl.c (float_ftype_float, ldouble_ftype_ldouble): Add definitions. (sizet_ftype_string): Delete variable. (init_decl_processing): Add built-in functions fabsf, fabsl, sqrtf, sqrtl, sinf, sin, sinl, cosf, cos, cosl. New local variable strlen_ftype, used for strlen. Wed Feb 14 16:21:25 1996 Jason Merrill * decl.c (push_to_top_level): Start from current_binding_level again for now; the stl hacks depend on g++ being broken in this way, and it'll be fixed in the template rewrite. * tree.def: Add USING_DECL. * decl2.c (do_class_using_decl): Implement. (grokfield): Pass access decls off to do_class_using_decl instead of grokdeclarator. * error.c (dump_decl): Handle USING_DECLs. * decl.c (grokdeclarator): Remove code for handling access decls. * class.c (finish_struct_1): Adjust accordingly, treat using-decls as access decls for now. (finish_struct): Don't check USING_DECLs for other uses of the name. * search.c (get_matching_virtual): Use cp_error_at. Wed Feb 14 10:36:58 1996 Brendan Kehoe * typeck.c (comptypes): Default COMP_TYPE_ATTRIBUTES to 1, to match c-typeck.c. (self_promoting_args_p): Move the check that TYPE is non-nil before trying to look at its main variant. (unsigned_type, signed_type): Add checking of DI/SI/HI/QI nodes. * cp-tree.h (DECL_WAITING_FRIENDS, SET_DECL_WAITING_FRIENDS): Delete macros. * init.c (xref_friend, embrace_waiting_friends): Delete functions. (do_friend): Delete call to xref_friend. * class.c (finish_struct_1): Delete call to embrace_waiting_friends. * typeck.c (convert_sequence): #if 0 unused function. * cp-tree.h (DECL_IN_MEMORY_P): New macro w/ the check that used to be in decl_in_memory_p. (decl_in_memory_p): Delete decl. * expr.c (decl_in_memory_p): Delete fn. * typeck.c (mark_addressable): Use DECL_IN_MEMORY_P. * decl.c (cp_finish_decl): Use DECL_IN_MEMORY_P. Tue Feb 13 12:51:21 1996 Jason Merrill * class.c (finish_struct_1): Check for a pure-specifier on a non-virtual function here. * decl2.c (grok_function_init): Don't check whether the function is virtual here. (grokfield): Don't call check_for_override here. * decl.c (push_to_top_level): Start from inner_binding_level, check class_shadowed in class levels. Mon Feb 12 17:46:59 1996 Mike Stump * decl.c (resume_level): Ignore things that don't have names, instead of core dumping. Mon Feb 12 15:47:44 1996 Brendan Kehoe * decl2.c (grokfield): Set DECL_VINDEX properly for FUNCTION_DECLs. Sat Feb 10 17:59:45 1996 Jason Merrill * class.c (finish_struct_1): Set DECL_VINDEX properly on a synthesized dtor. * parse.y (complete_type_name): Bind global_scope earlier. (complex_type_name): Likewise. (qualified_type_name): Remove. Thu Feb 8 15:15:14 1996 Jason Merrill * decl.c (grokfndecl): Move code that looks for virtuals in base classes... * class.c (check_for_override): ... to a new function. (finish_struct_1): Call it. * cp-tree.h: Declare warn_sign_compare. * typeck.c (build_binary_op_nodefault): Check warn_sign_compare rather than extra_warnings to decide whether to warn about comparison of signed and unsigned. * decl2.c (lang_decode_option): Handle warn_sign_compare. -Wall implies -Wsign-compare. -Wall doesn't imply -W. Wed Feb 7 15:27:57 1996 Mike Stump * typeck.c (build_component_ref): Fix to handle anon unions in base classes as well. Wed Feb 7 14:29:12 1996 Brendan Kehoe * class.c (resolves_to_fixed_type_p): Delete code dealing with a WITH_CLEANUP_EXPR, since we don't generate them any more. * cvt.c (build_up_reference): Likewise. * decl.c (grok_reference_init): Likewise. (cp_finish_decl): Likewise. * error.c (dump_expr): Likewise. * tree.c (real_lvalue_p): Likewise. (lvalue_p): Likewise. (build_cplus_new): Likewise. (unsave_expr_now): Likewise. * typeck.c (unary_complex_lvalue, build_modify_expr, c_expand_return): Likewise. Tue Feb 6 13:39:22 1996 Brendan Kehoe Make the C++ front-end pay attention to attributes for structures. * class.c (finish_struct): New argument ATTRIBUTES, passed down into finish_struct_1. (finish_struct_1): New argument ATTRIBUTES; call cplus_decl_attributes. Take out old round_up_size use and setting the DECL_ALIGN possibly using it. Take out setting of TYPE_ALIGN to round_up_size, which can override what the attribute set. * cp-tree.h (finish_struct): Update prototype. * parse.y (template_instantiate_once): Pass a NULL_TREE for the attributes to finish_struct. (structsp): For a CLASS decl, add maybe_attribute to rule and pass that value down into finish_struct. * Makefile.in (CONFLICTS): Switch to 7 shift/reduce conflicts. Tue Feb 6 13:12:15 1996 Per Bothner * decl.c (poplevel): Re-word dead for local handling. (pushdecl): Remove useless DECL_DEAD_FOR_LOCAL test. (cp_finish_decl): If is_for_scope, check for duplicates so we can disable is_for_scope. Otherwise, preserve_temp_slots. * lex.c (do_identifier): Use global binding in preference of dead for local variable. Mon Feb 5 17:46:46 1996 Mike Stump * init.c (initializing_context): Handle anon union changes, the context where fields of anon unions can be initialized now has to be found by walking up the TYPE_CONTEXT chain. Fri Feb 2 14:54:04 1996 Doug Evans * decl.c (start_decl): #ifdef out code to set DECL_COMMON if ASM_OUTPUT{,_ALIGNED}_BSS is defined. (obscure_complex_init): If bss is supported, always set DECL_INITIAL to error_mark_node. Thu Feb 1 16:19:56 1996 Brendan Kehoe * init.c (is_friend): Make sure there's a context before we see if it's an aggr type. Thu Feb 1 15:44:53 1996 Mike Stump * init.c (is_friend): Classes are not friendly with nested classes. Thu Feb 1 15:27:37 1996 Doug Evans * lex.c (check_newline): Pass last character read to HANDLE_PRAGMA, and record its result. Thu Feb 1 09:27:01 1996 Mike Stump * class.c (finish_struct_anon): Switch around code to not move anon union elements around, nor mess up their contexts, nor offsets, instead we now build up the right number of COMPONENT_REFs for all the anon unions that may be present at build_component_ref time. * typeck.c (lookup_anon_field): New routine to handle field lookup on fields without names. We find them, based upon their unique type instead. * typeck.c (build_component_ref): Allow FIELD_DECL components. Handle finding components in anonymous unions, and ensure that a COMPONENT_REF is built for each level as necessary. Tue Jan 30 18:18:23 1996 Mike Stump * cvt.c (build_up_reference): Make the INDIRECT_BIND case come after code that ensures that copy ctors are used if appropriate. Tue Jan 30 17:35:14 1996 Brendan Kehoe * init.c (build_vec_delete): Only give an error if base isn't an error_mark_node. Mon Jan 29 17:09:06 1996 Mike Stump * spew.c (do_aggr): `new struct S;' isn't a forward declaration. (yylex): If we see `new', keep slurping. Thu Jan 25 18:31:36 1996 Mike Stump * class.c (finish_struct_1): Move code for handling anon unions... (finish_struct_anon): to here. Fixup so that we do the offset calculations right, and so that the fields are physically moved to the containers's chain. Thu Jan 25 18:27:37 1996 Brendan Kehoe * decl.c (grokdeclarator): Avoid trying to get an operand off an identifier node. Wed Jan 24 11:25:30 1996 Jim Wilson * typeck.c (pointer_int_sum): Use TYPE_PRECISION (sizetype) not POINTER_SIZE to agree with expr.c. Thu Jan 25 13:01:23 1996 Mike Stump * search.c (lookup_field): Don't report ambiguities if protect is 0, instead return NULL_TREE. Wed Jan 24 13:01:26 1996 Mike Stump * class.c (finish_struct_1): Call warn_hidden if we want warnings about overloaded virtual functions. (warn_hidden): New routine to warn of virtual functions that are hidden by other virtual functions, that are not overridden. (get_basefndecls): New routine, used by warn_hidden. (mark_overriders): New routine, used by warn_hidden. * search.c (get_matching_virtual): Remove old warning that just isn't very useful. Tue Jan 23 12:26:10 1996 Brendan Kehoe * decl.c (output_builtin_tdesc_entries): #if 0 the function definition. * typeck.c (null_ptr_cst_p): Delete unused fn. (build_function_call_maybe): Delete unused fn. * expr.c (extract_init): #if 0 the code after unconditional return 0 for now. Delete old cadillac code. * edsel.c: Remove file. * Make-lang.in (CXX_SRCS): Take edsel.c off the list. * Makefile.in (CXX_OBJS): Delete edsel.o. (edsel.o): Delete rule. * cp-tree.h (flag_cadillac): Delete var decl. * lang-options.h: Delete "-fcadillac" and "-fno-cadillac". * decl2.c (flag_cadillac): Delete var definition. (lang_decode_option): Delete handling of -fcadillac and -fno-cadillac. (grokfield): Delete code depending on flag_cadillac. (finish_anon_union): Likewise. * class.c (finish_struct_1): Likewise. (pushclass): Likewise. (popclass): Likewise. (push_lang_context): Likewise. (pop_lang_context): Likewise. * decl.c (init_decl_processing): Likewise. (start_decl): Likewise. (cp_finish_decl): Likewise. (xref_tag): Likewise. (finish_enum): Likewise. (start_function): Likewise. (finish_function): Likewise. (finish_stmt): Likewise. * lex.c (lang_init): Likewise. (check_newline): Likewise. * lex.c (do_pending_inlines): Delete synthesized method kludge. Delete defunct, ancient garbage collection implementation. * rtti.c: New file with the RTTI stuff from gc.c. * gc.c: Removed file (moved the remaining stuff into rtti.c). * Makefile.in (CXX_OBJS): Replace gc.o with rtti.o. (rtti.o): New rule, replacing gc.o. * Make-lang.in (CXX_SRCS): Replace gc.c with rtti.c. * cp-tree.h: Delete gc-related fn decls. (DECL_GC_OFFSET): Delete macro. (flag_gc): Delete extern decl. * decl.c (current_function_obstack_index): Delete var decl. (current_function_obstack_usage): Delete var decl. (start_function): Delete clearing of current_function_obstack_index and current_function_obstack_usage. (init_decl_processing): Delete code relying on -fgc. Delete call to init_gc_processing. (cp_finish_decl): Delete calls to build_static_gc_entry and type_needs_gc_entry. Delete gc code setting DECL_GC_OFFSET. (store_parm_decls): Delete -fgc calls to cp_expand_decl_cleanup and to expand_expr of a __gc_main call. (maybe_gc_cleanup): Delete var decl. (finish_function): Delete call to expand_gc_prologue_and_epilogue. * decl2.c (flag_gc): Delete var decl. (lang_f_options): Delete offering of -fgc. (lang_decode_option): Delete -fgc and -fno-gc handling. (get_temp_regvar): Delete gc code. * init.c (build_new): Delete gc code. * lex.c (init_lex): Delete checking of flag_gc. * typeck.c (convert_arguments): Delete gc code. (build_component_addr): Delete -fgc warning. (build_modify_expr): Delete gc code. * decl2.c (build_push_scope): Delete fn. * cp-tree.h (build_push_scope): Delete decl. * search.c (clear_search_slots): Delete fn. * cp-tree.h (clear_search_slots): Delete decl. * search.c (tree_needs_constructor_p): Delete fn. * cp-tree.h (tree_needs_constructor_p): Delete decl. * tree.c (id_cmp): Delete fn. * tree.c (set_fnaddr_from_vtable_entry): Delete fn. * cp-tree.h (set_fnaddr_from_vtable_entry): Delete decl. * tree.c (decl_value_member): Delete fn. * cp-tree.h (decl_value_member): Delete decl. * tree.c (list_hash_lookup_or_cons): Delete fn. * cp-tree.h (list_hash_lookup_or_cons): Delete decl. * method.c (cplus_exception_name): Delete fn. (EXCEPTION_NAME_{PREFIX, LENGTH}): Delete macros. * spew.c (shift_tokens): Delete fn. Mon Jan 22 17:49:33 1996 Jason Merrill * except.c (init_exception_processing): Pass 1 to needs_pop in calls to cp_finish_decl. * parse.y: Likewise. Mon Jan 22 17:34:29 1996 Brendan Kehoe * tree.c (build_cplus_staticfn_type): Delete function definition; never used. * cp-tree.h (build_cplus_staticfn_type): Delete decl. * tree.c (virtual_member): Delete function definition; never used. * cp-tree.h (virtual_member): Delete decl. Fri Jan 19 18:03:14 1996 Mike Stump * typeck.c (build_component_ref): Handle getting vbase pointers out of complex multiple inheritance better. Fri Jan 19 16:27:40 1996 Mike Stump * typeck.c (build_object_ref): Make sure we use the real type, not any reference type. Fri Jan 19 16:01:47 1996 Mike Stump * tree.c (build_exception_variant): Don't create new types if we don't have to, also build new types on the right obstack. Fri Jan 19 14:09:44 1996 Jason Merrill * decl.c (store_bindings): Split out from push_to_top_level. (push_to_top_level): Call it for b->type_shadowed on class binding levels. Fri Jan 19 13:53:14 1996 Mike Stump * search.c (expand_upcast_fixups): Fix so that offsets stored in vbase_offsets are always right. Fixes a problem where virtual base upcasting and downcasting could be wrong during conversions on this during virtual function dispatch at ctor/dtor time when dynamic vtable fixups for deltas are needed. This only sounds easier than it is. :-) (fixup_virtual_upcast_offsets): Change to reflect new calling convention for expand_upcast_fixups. Fri Jan 19 12:23:08 1996 Brendan Kehoe * decl2.c (grokbitfield): Strip the NOPs from WIDTH before we check that it's usable as the bitfield width. Wed Jan 17 21:22:40 1996 Brendan Kehoe * decl2.c (grokfield): Call cplus_decl_attributes with the attrlist. Pass a null tree to grokdeclarator for its ATTRLIST arg, since it's only ever used for functions in it. Wed Jan 17 12:10:38 1996 Jason Merrill * parse.y (qualified_type_name): Use the TYPE_DECL, not the type. (nested_type): Likewise. (nested_name_specifier): Use lastiddecl. * decl.c (grokdeclarator): Adjust accordingly. * init.c (expand_member_init): Likewise. * parse.y (base_class): Likewise. * typeck2.c (build_functional_cast): Likewise. * typeck2.c (build_functional_cast): Fill in name after we've checked for non-aggr type. Wed Jan 17 10:18:01 1996 Mike Stump * decl2.c (warn_pointer_arith): Default to on. Tue Jan 16 12:45:38 1996 Jason Merrill * lex.c (is_rid): New function. * decl.c (grokdeclarator): Diagnose reserved words used as declarator-ids. Tue Jan 16 11:39:40 1996 Jason Merrill * tree.c (get_decl_list): Don't lose cv-quals. * decl.c (grokdeclarator): Fix SCOPE_REF handling and diagnose typespecs used as declarator-ids. Tue Jan 16 11:09:42 1996 Mike Stump * decl.c (poplevel): When poping a level, don't give a warning for any subblocks that already exist. Tue Jan 16 00:25:33 1996 Jason Merrill * typeck.c (build_object_ref): Finish what I started. * parse.y (qualified_type_name): Don't check TYPE_BUILT_IN. * decl2.c (constructor_name_full): Handle TEMPLATE_TYPE_PARMs. * decl.c (grokdeclarator): Also accept TEMPLATE_TYPE_PARM as a scope. Mon Jan 15 16:19:32 1996 Jason Merrill * decl.c (xref_tag): Handle passing a type in directly. * parse.y (qualified_type_name): Pull out the type. (nested_type): Likewise. Take types directly instead of as identifiers. * call.c (build_scoped_method_call): Take types directly instead of as identifiers. * decl.c (xref_basetypes): Likewise. * init.c (expand_member_init): Likewise. (build_member_call): Likewise. (build_offset_ref): Likewise. * typeck2.c (build_scoped_ref): Likewise, remove bogus code. * method.c (do_build_assign_ref): Likewise. * decl.c (grokdeclarator): Handle a type appearing as the declarator-id for constructors. * method.c (do_build_copy_constructor): current_base_init_list now uses the types directly, not their names. * init.c (sort_base_init): Likewise. (expand_member_init): Likewise. * init.c (is_aggr_type): New function, like is_aggr_typedef. Mon Jan 15 08:45:01 1996 Jeffrey A Law * tree.c (layout_basetypes): Call build_lang_field_decl instead of build_lang_decl if first arg is a FIELD_DECL. Thu Jan 11 14:55:07 1996 Brendan Kehoe * decl.c (cp_finish_decl): Only clear TREE_USED if DECL_NAME is non-empty. * except.c (expand_start_catch_block): Set TREE_USED to avoid warnings about the catch handler. Mon Jan 8 17:35:12 1996 Jason Merrill * typeck.c (build_modify_expr): Use a COMPOUND_EXPR instead of expand_target_expr. Thu Jan 4 12:30:32 1996 Brendan Kehoe Fix access control to use trees rather than integers. * class.c (access_{default, public, protected, private, default_virtual, public_virtual, private_virtual}_node): Add definitions. (init_class_processing): Do creation of those nodes. * cp-tree.h (access_type): Delete enum decl. (access_{default, public, protected, private, default_virtual, public_virtual, private_virtual}_node): Add decls. (compute_access): Change return type. * search.c (compute_access): Have tree return type, instead of enum. (lookup_field): Declare THIS_V and NEW_V to be tree nodes. * lex.c (real_yylex): Use yylval.ttype for giving the value of the access_* node for each of RID_{PUBLIC, PRIVATE, PROTECTED}. * parse.y (VISSPEC): Make ttype rather than itype. (base_class_access_list): Likewise. * *.[cy]: Change all refs of `access_public' to `access_public_node', etc. * call.c (build_method_call): Make ACCESS be a tree. * class.c (alter_access, finish_struct_1, filter_struct): Likewise. * cvt.c (convert_to_aggr): Likewise. * init.c (build_offset_ref, resolve_offset_ref, build_delete): Likewise. * method.c (hack_identifier): Likewise. * typeck.c (build_component_ref_1, build_component_ref): ): Likewise. Thu Jan 4 11:02:20 1996 Mike Stump * typeck.c (pointer_int_sum, pointer_diff): Make code agree with C frontend, and make it more consistent with respect to warn_pointer_arith. Tue Jan 2 00:13:38 1996 Rusty Russell * decl.c (pushdecl): Check for duplicate parameter names. Wed Jan 3 09:25:48 1996 Mike Stump * decl.c (expand_static_init): Call assemble_external for atexit. Wed Jan 3 07:55:19 1996 Mike Stump * except.c (do_unwind): Remove some generated dead code. (eh_outer_context): New routine, factor out some common code from expand_builtin_throw and end_eh_unwinder. Add code to do return address masking for the PA. (expand_builtin_throw): Use eh_outer_context instead of open coding it here. (end_eh_unwinder): Likewise. Tue Jan 2 17:00:56 1996 Mike Stump * except.c (expand_throw): Call assemble_external for __empty, if we use it. Thu Dec 28 11:13:15 1995 Mike Stump * except.c (expand_builtin_throw): Use RETURN_ADDR_OFFSET instead of NORMAL_RETURN_ADDR_OFFSET. (end_eh_unwinder): Likewise. Wed Dec 27 22:18:16 1995 Mike Stump * gc.c (build_dynamic_cast): Make sure we don't cast away const when dealing with references, and make sure we handle dynamic casting to a cv qualified reference. Thu Dec 21 23:50:35 1995 Mike Stump * except.c (struct eh_context): New structure top hold eh context information. (push_eh_context): New routine. (pop_eh_context): Likewise. * decl.c (push_cp_function_context): Use them. (pop_cp_function_context): Likewise. Wed Dec 20 12:42:51 1995 Jason Merrill * decl2.c (finish_file): Also prune uninteresting functions in the inline emission loop. Wed Dec 20 02:32:07 1995 Jeffrey A Law * sig.c (build_signature_table_constructor): Mark functions in the signature as referenced. Tue Dec 19 22:36:56 1995 Jason Merrill * decl2.c (finish_file): Do all the vtable/synthesis stuff before the inline emission stuff. Mon Dec 18 15:51:33 1995 Jason Merrill * cp-tree.h, decl2.c (flag_weak): New flag to control the use of weak symbols. * lang-options.h: Add -f{no-,}weak. * decl.c (init_decl_processing): If the target does not support weak symbols, don't use them. * decl2.c, pt.c: s/SUPPORTS_WEAK/flag_weak/. Sun Dec 17 21:13:23 1995 Rusty Russell * init.c (expand_member_init): warning for base init after members. Fri Dec 15 15:32:18 1995 Jason Merrill * cvt.c (build_expr_type_conversion): Don't convert to a reference type. Thu Dec 14 16:05:58 1995 Mike Stump * method.c (report_type_mismatch): Improve wording for volatile mismatches. Thu Dec 14 14:16:26 1995 Mike Stump * init.c (expand_aggr_init_1): Use expand_aggr_init_1 instead of expand_assignment, as the later doesn't handle things that have copy constructors well. The compiler would do bitwise copying, instead of ctor calling in some cases. Wed Dec 13 17:05:54 1995 Paul Eggert * g++.c (my_strerror): Return "cannot access" if errno is 0. (pfatal_with_name, perror_exec): Don't assume that the returned value from my_strerror contains no '%'s. (concat): Remove. (sys_nerror): Declare only if HAVE_STRERROR is not defined. Wed Dec 13 16:22:38 1995 Jason Merrill Lose CLASSTYPE_METHODS/DECL_NEXT_METHOD chain; make TYPE_METHODS/TREE_CHAIN mean what they used to. * decl2.c (constructor_name_full): Refer to CLASSTYPE_METHOD_VEC instead of TYPE_METHODS. * decl.c (duplicate_decls): Lose references to DECL_NEXT_METHOD. * tree.c (tree_copy_lang_decl_for_deferred_output): Likewise. * cp-tree.h (CLASSTYPE_METHODS): Lose. (CLASSTYPE_METHOD_VEC): Point to lang_spec->methods instead of TYPE_METHODS. (struct lang_decl): Lose next_method field. (DECL_NEXT_METHOD): Lose. * class.c (finish_struct_methods): Don't mess with TYPE_METHODS. (finish_struct): Just use TYPE_METHODS; we don't need fn_fields anymore. (finish_struct_methods): Don't mess with the TREE_CHAINs in fn_fields. * search.c (add_conversions): Don't use TREE_CHAIN to traverse method vector. * call.c (build_method_call): Synthesize here even when not inlining. * typeck.c (build_function_call_real): Likewise. Wed Dec 13 15:02:39 1995 Ian Lance Taylor * cp/lex.c (check_newline): If DBX_DEBUGGING_INFO and write_symbols == DBX_DEBUG, call dbxout_start_new_source_file and dbxout_resume_previous_source_file when appropriate. Tue Dec 12 20:38:55 1995 Mike Stump * except.c (start_anon_func): Push to the top level. (end_anon_func): Pop from the top level. Mon Dec 11 18:56:14 1995 Mike Stump * cp-tree.h (build_cleanup): New routine to build cleanups. * decl.c (expand_static_init): Use build_cleanup to build a cleanup call at ctor time and use atexit to run it later. * decl2.c (build_cleanup): New routine, taken from finish_file. (finish_file): Use build_cleanup instead, and don't put function local statics in global dtor list. Wed Dec 6 14:34:29 1995 Mike Stump * except.c (expand_throw): Ensure that we have cleanups, if we try and expand cleanups. Wed Dec 6 11:48:21 1995 Mike Stump * except.c (expand_throw): Add logic to manage dynamic cleanups for the EH object. (expand_end_catch_block): Use the magic of expand_goto, instead of emit_jump so that we get the cleanup for any catch clause parameter and the cleanup for the exception object. Update to reflect label changes. (push_eh_cleanup): New routine to register a cleanup for an exception object. (empty_fndecl): Used to default cleanup actions to nothing. (init_exception_processing): Setup empty_fndecl. Setup saved_cleanup. (expand_start_catch_block): Update to reflect label changes. Call push_eh_object to register the cleanup for the EH object. (start_anon_func): New routine to start building lambda expressions from trees. (end_anon_func): New routine to end them. (struct labelNode): Change so that we can use tree labels, or rtx labels. (saved_cleanup): Object to check for dynamic cleanups for the exception handling object. (push_label_entry): Change so that we can use tree labels, or rtx labels. (pop_label_entry): Likewise. (top_label_entry): Likewise. (expand_start_all_catch): Use tree label instead of rtx label, so that we can get the magic of expand_goto. (expand_end_all_catch): Update to reflect label changes. * class.c (build_vfn_ref): Remove building_cleanup logic, as we now use UNSAVE_EXPRs. * typeck.c (get_member_function_from_ptrfunc): Remove remnants of building_cleanup logic, as we now use UNSAVE_EXPRs. * cp-tree.h (unsave_expr): Declare it. * decl.c (building_cleanup): Remove. (maybe_build_cleanup): Remove building_cleanup logic, and use UNSAVE_EXPR instead. Sun Dec 3 01:34:58 1995 Mike Stump * gc.c (build_t_desc): Update error message to say . Thu Nov 30 12:30:05 1995 Brendan Kehoe * decl.c (pushdecl): Only warn about shadowing a local variable if warn_shadow is true. Sun Nov 26 16:06:55 1995 Rusty Russell * typeck.c (build_binary_op_nodefault): Added warning about comparisons between different enum types with -Wall, unless -fenum-int-equiv set. Wed Nov 22 15:44:02 1995 Mike Stump * class.c (finish_struct_1): Skip down to the inner type in multidimensional arrays. Ensures ctors will be made for types that need constructing. Wed Nov 22 14:19:22 1995 Mike Stump * decl.c (last_dtor_insn): New to track the last compiler generated insn in a dtor. (store_parm_decls): Set it. (finish_function): Use it to see if the dtor is empty. Avoid doing vtable setup all the time, if we can. (struct cp_function): Add last_dtor_insn. (push_cp_function_context): Save it. (pop_cp_function_context): Restore it. Wed Nov 22 11:52:19 1995 Paul Russell * typeck.c (build_unary_op): Set TREE_NO_UNUSED_WARNING to avoid warnings. Tue Nov 21 17:15:23 1995 Mike Stump * typeck.c (expand_target_expr): Make sure targets get put into the current temp_slot_level, so that the free_temp_slots call will reuse them. Tue Nov 21 13:32:03 1995 Mike Stump * class.c (finish_struct_1): Delay delta fixups for virtual bases until after we have done the hard virtuals, to avoid a bogus `every virtual function must have a unique final overrider' for virtual functions that are only overridden by hard virtuals. Thu Nov 9 13:35:30 1995 Jason Merrill * pt.c (do_function_instantiation): Don't try to find a file-scope template for a member function. Tue Nov 14 06:20:35 1995 Mike Stump * g++.c (main): Add handling of -nodefaultlibs. Mon Nov 13 15:45:34 1995 Mike Stump * cp-tree.h (INDIRECT_BIND): Add a way for the frontend to distinguish between direct bindings of reference variables, and indirect bindings of reference variables. * cvt.c (build_up_reference): Use it. * typeck.c (convert_arguments): Use it to indicate this is an indirect binding. * decl.c (cp_finish_decl): Ensure that we reuse stack slots as fast as they are unused. (expand_static_init): Likewise. (cplus_expand_expr_stmt): Likewise. * decl2.c (finish_file): Likewise. * init.c (perform_member_init): Likewise. (emit_base_init): Likewise. (expand_aggr_vbase_init_1): Likewise. Fri Nov 10 09:18:09 1995 Brendan Kehoe * decl.c (push_namespace): Rewrite to use build_lang_decl, so we get a DECL_LANG_SPECIFIC node. * cp-tree.h (lang_decl_flags): Add new member `level'. (NAMESPACE_LEVEL): Don't use decl.arguments, instead use the decl_flags level member. Mon Nov 6 18:36:13 1995 Brendan Kehoe * call.c (build_method_call): Make sure instance has a TYPE_LANG_SPECIFIC node before we dive into it. Sat Nov 4 20:01:52 1995 Jason Molenda * method.c (make_thunk): Use TREE_SET_CODE to set thunk's tree code. Thu Nov 2 17:56:57 1995 Mike Stump * decl.c (duplicate_decls): When smashing decls, smash staticness in the usual way. Thu Nov 2 16:44:02 1995 Mike Stump * decl.c (poplevel): Handle the merging of subblocks of cleanups when finishing blocks that have already been created (usually due to the fixup goto code). Fixes bad debugging information. Wed Nov 1 12:33:53 1995 Jason Merrill * method.c (hack_identifier): Don't abort when we get a TREE_LIST that's not a list of overloaded functions. Wed Nov 1 11:38:58 1995 Brendan Kehoe * decl2.c (mark_vtable_entries): Check DECL_LANG_SPECIFIC on fn before trying to use DECL_ABSTRACT_VIRTUAL_P. Tue Oct 31 11:56:55 1995 Jason Merrill * decl2.c (mark_used): New function for hooking into setting of TREE_USED on decls. * call.c (build_method_call): Use it. * class.c (instantiate_type): Likewise. * init.c (build_offset_ref): Likewise. Don't call assemble_external for all like-named functions. * method.c (hack_identifier): Likewise. (emit_thunk): Don't call assemble_external. (make_thunk): Create thunk as a FUNCTION_DECL so that it gets the right mode and ENCODE_SECTION_INFO works. * parse.y: Use mark_used. Pass operator names to do_identifier. * lex.c (do_identifier): Handle operator names. * decl2.c (grokclassfn): Tweak __in_chrg attributes. Thu Oct 26 16:45:58 1995 Brendan Kehoe * errfn.c: Include stdio.h. (cp_sprintf): Take out decl of sprintf, and cast sprintf to errorfn*. Wed Oct 25 18:58:41 1995 Mike Stump * typeck2.c (digest_init): Always convert initializers to the right type. Wed Oct 25 13:25:24 1995 Mike Stump * init.c (member_init_ok_or_else): Don't allow member initializers for indirect members, as it is invalid. Wed Oct 25 11:35:28 1995 Brendan Kehoe * decl.c (grokdeclarator): Don't allow `friend signed ()'. Fri Oct 20 10:30:59 1995 Mike Stump * parse.y (for.init.statement): Catch compound statements inside for initializations, if we're being pedantic. Fri Oct 20 10:03:42 1995 Mike Stump * decl.c (lookup_tag): Return NULL_TREE if we don't find what we are looking for. Thu Oct 19 14:26:10 1995 Mike Stump * error.c (dump_expr): Don't core dump when a boolean expression is used as a default argument. Thu Oct 19 10:36:30 1995 Jason Merrill * class.c (finish_struct_bits): Check aggregate_value_p instead of RETURN_IN_MEMORY. Wed Oct 18 18:12:32 1995 Jason Merrill * class.c (finish_struct_bits): Also set TREE_ADDRESSABLE on a BLKmode type that would otherwise be returned in registers. Mon Oct 16 12:32:19 1995 Brendan Kehoe * g++.c (WITHLIBC): New macro. (main): Declare saw_libc. Use WITHLIBC if `-lc' was used; set saw_libc and pass it at the end if it was set. Wed Oct 11 16:30:34 1995 Brendan Kehoe * parse.y (fn.def1): Call split_specs_attrs in declmods notype_declarator case. Index: vendor/gcc/dist/contrib/gcc/cp/call.c =================================================================== --- vendor/gcc/dist/contrib/gcc/cp/call.c (revision 60966) +++ vendor/gcc/dist/contrib/gcc/cp/call.c (revision 60967) @@ -1,4513 +1,4558 @@ /* Functions related to invoking methods and overloaded functions. Copyright (C) 1987, 92-97, 1998, 1999 Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@cygnus.com) and modified by Brendan Kehoe (brendan@cygnus.com). 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. */ /* High-level class interface. */ #include "config.h" #include "system.h" #include "tree.h" #include "cp-tree.h" #include "output.h" #include "flags.h" #include "rtl.h" #include "toplev.h" #include "obstack.h" #define obstack_chunk_alloc xmalloc #define obstack_chunk_free free extern int inhibit_warnings; extern tree ctor_label, dtor_label; static tree build_new_method_call PROTO((tree, tree, tree, tree, int)); static tree build_field_call PROTO((tree, tree, tree, tree)); static tree find_scoped_type PROTO((tree, tree, tree)); static struct z_candidate * tourney PROTO((struct z_candidate *)); static int joust PROTO((struct z_candidate *, struct z_candidate *, int)); static int compare_ics PROTO((tree, tree)); static tree build_over_call PROTO((struct z_candidate *, tree, int)); static tree convert_like PROTO((tree, tree)); static void op_error PROTO((enum tree_code, enum tree_code, tree, tree, tree, const char *)); static tree build_object_call PROTO((tree, tree)); static tree resolve_args PROTO((tree)); static struct z_candidate * build_user_type_conversion_1 PROTO ((tree, tree, int)); static void print_z_candidates PROTO((struct z_candidate *)); static tree build_this PROTO((tree)); static struct z_candidate * splice_viable PROTO((struct z_candidate *)); static int any_viable PROTO((struct z_candidate *)); static struct z_candidate * add_template_candidate PROTO((struct z_candidate *, tree, tree, tree, tree, int, unification_kind_t)); static struct z_candidate * add_template_candidate_real PROTO((struct z_candidate *, tree, tree, tree, tree, int, tree, unification_kind_t)); static struct z_candidate * add_template_conv_candidate PROTO((struct z_candidate *, tree, tree, tree, tree)); static struct z_candidate * add_builtin_candidates PROTO((struct z_candidate *, enum tree_code, enum tree_code, tree, tree *, int)); static struct z_candidate * add_builtin_candidate PROTO((struct z_candidate *, enum tree_code, enum tree_code, tree, tree, tree, tree *, tree *, int)); static int is_complete PROTO((tree)); static struct z_candidate * build_builtin_candidate PROTO((struct z_candidate *, tree, tree, tree, tree *, tree *, int)); static struct z_candidate * add_conv_candidate PROTO((struct z_candidate *, tree, tree, tree)); static struct z_candidate * add_function_candidate PROTO((struct z_candidate *, tree, tree, int)); static tree implicit_conversion PROTO((tree, tree, tree, int)); static tree standard_conversion PROTO((tree, tree, tree)); static tree reference_binding PROTO((tree, tree, tree, int)); static tree strip_top_quals PROTO((tree)); static tree non_reference PROTO((tree)); static tree build_conv PROTO((enum tree_code, tree, tree)); static int is_subseq PROTO((tree, tree)); static int maybe_handle_ref_bind PROTO((tree*, tree*)); static void maybe_handle_implicit_object PROTO((tree*)); static struct z_candidate * add_candidate PROTO((struct z_candidate *, tree, tree, int)); static tree source_type PROTO((tree)); static void add_warning PROTO((struct z_candidate *, struct z_candidate *)); tree build_vfield_ref (datum, type) tree datum, type; { tree rval; if (datum == error_mark_node) return error_mark_node; if (TREE_CODE (TREE_TYPE (datum)) == REFERENCE_TYPE) datum = convert_from_reference (datum); if (! TYPE_USES_COMPLEX_INHERITANCE (type)) rval = build (COMPONENT_REF, TREE_TYPE (CLASSTYPE_VFIELD (type)), datum, CLASSTYPE_VFIELD (type)); else rval = build_component_ref (datum, DECL_NAME (CLASSTYPE_VFIELD (type)), NULL_TREE, 0); return rval; } /* Build a call to a member of an object. I.e., one that overloads operator ()(), or is a pointer-to-function or pointer-to-method. */ static tree build_field_call (basetype_path, instance_ptr, name, parms) tree basetype_path, instance_ptr, name, parms; { tree field, instance; if (name == ctor_identifier || name == dtor_identifier) return NULL_TREE; /* Speed up the common case. */ if (instance_ptr == current_class_ptr && IDENTIFIER_CLASS_VALUE (name) == NULL_TREE) return NULL_TREE; field = lookup_field (basetype_path, name, 1, 0); if (field == error_mark_node || field == NULL_TREE) return field; if (TREE_CODE (field) == FIELD_DECL || TREE_CODE (field) == VAR_DECL) { /* If it's a field, try overloading operator (), or calling if the field is a pointer-to-function. */ instance = build_indirect_ref (instance_ptr, NULL_PTR); instance = build_component_ref_1 (instance, field, 0); if (instance == error_mark_node) return error_mark_node; if (IS_AGGR_TYPE (TREE_TYPE (instance))) return build_opfncall (CALL_EXPR, LOOKUP_NORMAL, instance, parms, NULL_TREE); else if (TREE_CODE (TREE_TYPE (instance)) == POINTER_TYPE) { if (TREE_CODE (TREE_TYPE (TREE_TYPE (instance))) == FUNCTION_TYPE) return build_function_call (instance, parms); else if (TREE_CODE (TREE_TYPE (TREE_TYPE (instance))) == METHOD_TYPE) return build_function_call (instance, expr_tree_cons (NULL_TREE, instance_ptr, parms)); } } return NULL_TREE; } static tree find_scoped_type (type, inner_name, inner_types) tree type, inner_name, inner_types; { tree tags = CLASSTYPE_TAGS (type); while (tags) { /* The TREE_PURPOSE of an enum tag (which becomes a member of the enclosing class) is set to the name for the enum type. So, if inner_name is `bar', and we strike `baz' for `enum bar { baz }', then this test will be true. */ if (TREE_PURPOSE (tags) == inner_name) { if (inner_types == NULL_TREE) return TYPE_MAIN_DECL (TREE_VALUE (tags)); return resolve_scope_to_name (TREE_VALUE (tags), inner_types); } tags = TREE_CHAIN (tags); } /* Look for a TYPE_DECL. */ for (tags = TYPE_FIELDS (type); tags; tags = TREE_CHAIN (tags)) if (TREE_CODE (tags) == TYPE_DECL && DECL_NAME (tags) == inner_name) { /* Code by raeburn. */ if (inner_types == NULL_TREE) return tags; return resolve_scope_to_name (TREE_TYPE (tags), inner_types); } return NULL_TREE; } /* Resolve an expression NAME1::NAME2::...::NAMEn to the name that names the above nested type. INNER_TYPES is a chain of nested type names (held together by SCOPE_REFs); OUTER_TYPE is the type we know to enclose INNER_TYPES. Returns NULL_TREE if there is an error. */ tree resolve_scope_to_name (outer_type, inner_stuff) tree outer_type, inner_stuff; { register tree tmp; tree inner_name, inner_type; if (outer_type == NULL_TREE && current_class_type != NULL_TREE) { /* We first try to look for a nesting in our current class context, then try any enclosing classes. */ tree type = current_class_type; while (type && (TREE_CODE (type) == RECORD_TYPE || TREE_CODE (type) == UNION_TYPE)) { tree rval = resolve_scope_to_name (type, inner_stuff); if (rval != NULL_TREE) return rval; type = DECL_CONTEXT (TYPE_MAIN_DECL (type)); } } if (TREE_CODE (inner_stuff) == SCOPE_REF) { inner_name = TREE_OPERAND (inner_stuff, 0); inner_type = TREE_OPERAND (inner_stuff, 1); } else { inner_name = inner_stuff; inner_type = NULL_TREE; } if (outer_type == NULL_TREE) { tree x; /* If we have something that's already a type by itself, use that. */ if (IDENTIFIER_HAS_TYPE_VALUE (inner_name)) { if (inner_type) return resolve_scope_to_name (IDENTIFIER_TYPE_VALUE (inner_name), inner_type); return inner_name; } x = lookup_name (inner_name, 0); if (x && TREE_CODE (x) == NAMESPACE_DECL) { x = lookup_namespace_name (x, inner_type); return x; } return NULL_TREE; } if (! IS_AGGR_TYPE (outer_type)) return NULL_TREE; /* Look for member classes or enums. */ tmp = find_scoped_type (outer_type, inner_name, inner_type); /* If it's not a type in this class, then go down into the base classes and search there. */ if (! tmp && TYPE_BINFO (outer_type)) { tree binfos = TYPE_BINFO_BASETYPES (outer_type); int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0; for (i = 0; i < n_baselinks; i++) { tree base_binfo = TREE_VEC_ELT (binfos, i); tmp = resolve_scope_to_name (BINFO_TYPE (base_binfo), inner_stuff); if (tmp) return tmp; } tmp = NULL_TREE; } return tmp; } /* Returns nonzero iff the destructor name specified in NAME (a BIT_NOT_EXPR) matches BASETYPE. The operand of NAME can take many forms... */ int check_dtor_name (basetype, name) tree basetype, name; { name = TREE_OPERAND (name, 0); /* Just accept something we've already complained about. */ if (name == error_mark_node) return 1; if (TREE_CODE (name) == TYPE_DECL) name = TREE_TYPE (name); else if (TREE_CODE_CLASS (TREE_CODE (name)) == 't') /* OK */; else if (TREE_CODE (name) == IDENTIFIER_NODE) { if ((IS_AGGR_TYPE (basetype) && name == constructor_name (basetype)) || (TREE_CODE (basetype) == ENUMERAL_TYPE && name == TYPE_IDENTIFIER (basetype))) name = basetype; else name = get_type_value (name); } else my_friendly_abort (980605); if (name && TYPE_MAIN_VARIANT (basetype) == TYPE_MAIN_VARIANT (name)) return 1; return 0; } /* Build a method call of the form `EXP->SCOPES::NAME (PARMS)'. This is how virtual function calls are avoided. */ tree build_scoped_method_call (exp, basetype, name, parms) tree exp, basetype, name, parms; { /* Because this syntactic form does not allow a pointer to a base class to be `stolen', we need not protect the derived->base conversion that happens here. @@ But we do have to check access privileges later. */ tree binfo, decl; tree type = TREE_TYPE (exp); if (type == error_mark_node || basetype == error_mark_node) return error_mark_node; if (processing_template_decl) { if (TREE_CODE (name) == BIT_NOT_EXPR && TREE_CODE (TREE_OPERAND (name, 0)) == IDENTIFIER_NODE) { tree type = get_aggr_from_typedef (TREE_OPERAND (name, 0), 0); if (type) name = build_min_nt (BIT_NOT_EXPR, type); } name = build_min_nt (SCOPE_REF, basetype, name); return build_min_nt (METHOD_CALL_EXPR, name, exp, parms, NULL_TREE); } if (TREE_CODE (type) == REFERENCE_TYPE) type = TREE_TYPE (type); if (TREE_CODE (basetype) == TREE_VEC) { binfo = basetype; basetype = BINFO_TYPE (binfo); } else binfo = NULL_TREE; /* Check the destructor call syntax. */ if (TREE_CODE (name) == BIT_NOT_EXPR) { /* We can get here if someone writes their destructor call like `obj.NS::~T()'; this isn't really a scoped method call, so hand it off. */ if (TREE_CODE (basetype) == NAMESPACE_DECL) return build_method_call (exp, name, parms, NULL_TREE, LOOKUP_NORMAL); if (! check_dtor_name (basetype, name)) cp_error ("qualified type `%T' does not match destructor name `~%T'", basetype, TREE_OPERAND (name, 0)); /* Destructors can be "called" for simple types; see 5.2.4 and 12.4 Note that explicit ~int is caught in the parser; this deals with typedefs and template parms. */ if (! IS_AGGR_TYPE (basetype)) { if (TYPE_MAIN_VARIANT (type) != TYPE_MAIN_VARIANT (basetype)) cp_error ("type of `%E' does not match destructor type `%T' (type was `%T')", exp, basetype, type); return cp_convert (void_type_node, exp); } } if (! is_aggr_type (basetype, 1)) return error_mark_node; if (! IS_AGGR_TYPE (type)) { cp_error ("base object `%E' of scoped method call is of non-aggregate type `%T'", exp, type); return error_mark_node; } if (! binfo) { binfo = get_binfo (basetype, type, 1); if (binfo == error_mark_node) return error_mark_node; if (! binfo) error_not_base_type (basetype, type); } if (binfo) { if (TREE_CODE (exp) == INDIRECT_REF) decl = build_indirect_ref (convert_pointer_to_real (binfo, build_unary_op (ADDR_EXPR, exp, 0)), NULL_PTR); else decl = build_scoped_ref (exp, basetype); /* Call to a destructor. */ if (TREE_CODE (name) == BIT_NOT_EXPR) { if (! TYPE_HAS_DESTRUCTOR (TREE_TYPE (decl))) return cp_convert (void_type_node, exp); return build_delete (TREE_TYPE (decl), decl, integer_two_node, LOOKUP_NORMAL|LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR, 0); } /* Call to a method. */ return build_method_call (decl, name, parms, binfo, LOOKUP_NORMAL|LOOKUP_NONVIRTUAL); } return error_mark_node; } /* We want the address of a function or method. We avoid creating a pointer-to-member function. */ tree build_addr_func (function) tree function; { tree type = TREE_TYPE (function); /* We have to do these by hand to avoid real pointer to member functions. */ if (TREE_CODE (type) == METHOD_TYPE) { tree addr; type = build_pointer_type (type); if (mark_addressable (function) == 0) return error_mark_node; addr = build1 (ADDR_EXPR, type, function); /* Address of a static or external variable or function counts as a constant */ if (staticp (function)) TREE_CONSTANT (addr) = 1; function = addr; } else function = default_conversion (function); return function; } /* Build a CALL_EXPR, we can handle FUNCTION_TYPEs, METHOD_TYPEs, or POINTER_TYPE to those. Note, pointer to member function types (TYPE_PTRMEMFUNC_P) must be handled by our callers. */ tree build_call (function, result_type, parms) tree function, result_type, parms; { int is_constructor = 0; tree tmp; tree decl; function = build_addr_func (function); if (TYPE_PTRMEMFUNC_P (TREE_TYPE (function))) { sorry ("unable to call pointer to member function here"); return error_mark_node; } if (TREE_CODE (function) == ADDR_EXPR && TREE_CODE (TREE_OPERAND (function, 0)) == FUNCTION_DECL) decl = TREE_OPERAND (function, 0); else decl = NULL_TREE; if (decl && DECL_CONSTRUCTOR_P (decl)) is_constructor = 1; if (decl) my_friendly_assert (TREE_USED (decl), 990125); /* Don't pass empty class objects by value. This is useful for tags in STL, which are used to control overload resolution. We don't need to handle other cases of copying empty classes. */ if (! decl || ! DECL_BUILT_IN (decl)) for (tmp = parms; tmp; tmp = TREE_CHAIN (tmp)) if (is_empty_class (TREE_TYPE (TREE_VALUE (tmp))) && ! TREE_ADDRESSABLE (TREE_TYPE (TREE_VALUE (tmp)))) { tree t = make_node (RTL_EXPR); TREE_TYPE (t) = TREE_TYPE (TREE_VALUE (tmp)); RTL_EXPR_RTL (t) = const0_rtx; RTL_EXPR_SEQUENCE (t) = NULL_RTX; TREE_VALUE (tmp) = build (COMPOUND_EXPR, TREE_TYPE (t), TREE_VALUE (tmp), t); } function = build_nt (CALL_EXPR, function, parms, NULL_TREE); TREE_HAS_CONSTRUCTOR (function) = is_constructor; TREE_TYPE (function) = result_type; TREE_SIDE_EFFECTS (function) = 1; return function; } /* Build something of the form ptr->method (args) or object.method (args). This can also build calls to constructors, and find friends. Member functions always take their class variable as a pointer. INSTANCE is a class instance. NAME is the name of the method desired, usually an IDENTIFIER_NODE. PARMS help to figure out what that NAME really refers to. BASETYPE_PATH, if non-NULL, contains a chain from the type of INSTANCE down to the real instance type to use for access checking. We need this information to get protected accesses correct. This parameter is used by build_member_call. FLAGS is the logical disjunction of zero or more LOOKUP_ flags. See cp-tree.h for more info. If this is all OK, calls build_function_call with the resolved member function. This function must also handle being called to perform initialization, promotion/coercion of arguments, and instantiation of default parameters. Note that NAME may refer to an instance variable name. If `operator()()' is defined for the type of that field, then we return that result. */ tree build_method_call (instance, name, parms, basetype_path, flags) tree instance, name, parms, basetype_path; int flags; { tree basetype, instance_ptr; #ifdef GATHER_STATISTICS n_build_method_call++; #endif if (instance == error_mark_node || name == error_mark_node || parms == error_mark_node || (instance != NULL_TREE && TREE_TYPE (instance) == error_mark_node)) return error_mark_node; if (processing_template_decl) { /* We need to process template parm names here so that tsubst catches them properly. Other type names can wait. */ if (TREE_CODE (name) == BIT_NOT_EXPR) { tree type = NULL_TREE; if (TREE_CODE (TREE_OPERAND (name, 0)) == IDENTIFIER_NODE) type = get_aggr_from_typedef (TREE_OPERAND (name, 0), 0); else if (TREE_CODE (TREE_OPERAND (name, 0)) == TYPE_DECL) type = TREE_TYPE (TREE_OPERAND (name, 0)); if (type && TREE_CODE (type) == TEMPLATE_TYPE_PARM) name = build_min_nt (BIT_NOT_EXPR, type); } return build_min_nt (METHOD_CALL_EXPR, name, instance, parms, NULL_TREE); } if (TREE_CODE (name) == BIT_NOT_EXPR) { if (parms) error ("destructors take no parameters"); basetype = TREE_TYPE (instance); if (TREE_CODE (basetype) == REFERENCE_TYPE) basetype = TREE_TYPE (basetype); if (! check_dtor_name (basetype, name)) cp_error ("destructor name `~%T' does not match type `%T' of expression", TREE_OPERAND (name, 0), basetype); if (! TYPE_HAS_DESTRUCTOR (complete_type (basetype))) return cp_convert (void_type_node, instance); instance = default_conversion (instance); instance_ptr = build_unary_op (ADDR_EXPR, instance, 0); return build_delete (build_pointer_type (basetype), instance_ptr, integer_two_node, LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 0); } return build_new_method_call (instance, name, parms, basetype_path, flags); } /* New overloading code. */ struct z_candidate { tree fn; tree convs; tree second_conv; int viable; tree basetype_path; tree template; tree warnings; struct z_candidate *next; }; #define IDENTITY_RANK 0 #define EXACT_RANK 1 #define PROMO_RANK 2 #define STD_RANK 3 #define PBOOL_RANK 4 #define USER_RANK 5 #define ELLIPSIS_RANK 6 #define BAD_RANK 7 #define ICS_RANK(NODE) \ (ICS_BAD_FLAG (NODE) ? BAD_RANK \ : ICS_ELLIPSIS_FLAG (NODE) ? ELLIPSIS_RANK \ : ICS_USER_FLAG (NODE) ? USER_RANK \ : ICS_STD_RANK (NODE)) #define ICS_STD_RANK(NODE) TREE_COMPLEXITY (NODE) #define ICS_USER_FLAG(NODE) TREE_LANG_FLAG_0 (NODE) #define ICS_ELLIPSIS_FLAG(NODE) TREE_LANG_FLAG_1 (NODE) #define ICS_THIS_FLAG(NODE) TREE_LANG_FLAG_2 (NODE) #define ICS_BAD_FLAG(NODE) TREE_LANG_FLAG_3 (NODE) #define USER_CONV_CAND(NODE) \ ((struct z_candidate *)WRAPPER_PTR (TREE_OPERAND (NODE, 1))) #define USER_CONV_FN(NODE) (USER_CONV_CAND (NODE)->fn) int null_ptr_cst_p (t) tree t; { if (t == null_node || (integer_zerop (t) && TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE)) return 1; return 0; } static tree build_conv (code, type, from) enum tree_code code; tree type, from; { tree t = build1 (code, type, from); int rank = ICS_STD_RANK (from); switch (code) { case PTR_CONV: case PMEM_CONV: case BASE_CONV: case STD_CONV: if (rank < STD_RANK) rank = STD_RANK; break; case QUAL_CONV: if (rank < EXACT_RANK) rank = EXACT_RANK; default: break; } ICS_STD_RANK (t) = rank; ICS_USER_FLAG (t) = ICS_USER_FLAG (from); ICS_BAD_FLAG (t) = ICS_BAD_FLAG (from); return t; } static tree non_reference (t) tree t; { if (TREE_CODE (t) == REFERENCE_TYPE) t = TREE_TYPE (t); return t; } static tree strip_top_quals (t) tree t; { if (TREE_CODE (t) == ARRAY_TYPE) return t; return TYPE_MAIN_VARIANT (t); } /* Returns the standard conversion path (see [conv]) from type FROM to type TO, if any. For proper handling of null pointer constants, you must also pass the expression EXPR to convert from. */ static tree standard_conversion (to, from, expr) tree to, from, expr; { enum tree_code fcode, tcode; tree conv; int fromref = 0; if (TREE_CODE (to) == REFERENCE_TYPE) to = TREE_TYPE (to); if (TREE_CODE (from) == REFERENCE_TYPE) { fromref = 1; from = TREE_TYPE (from); } to = strip_top_quals (to); from = strip_top_quals (from); if ((TYPE_PTRFN_P (to) || TYPE_PTRMEMFUNC_P (to)) && expr && type_unknown_p (expr)) { expr = instantiate_type (to, expr, 0); if (expr == error_mark_node) return NULL_TREE; from = TREE_TYPE (expr); } fcode = TREE_CODE (from); tcode = TREE_CODE (to); conv = build1 (IDENTITY_CONV, from, expr); if (fcode == FUNCTION_TYPE) { from = build_pointer_type (from); fcode = TREE_CODE (from); conv = build_conv (LVALUE_CONV, from, conv); } else if (fcode == ARRAY_TYPE) { from = build_pointer_type (TREE_TYPE (from)); fcode = TREE_CODE (from); conv = build_conv (LVALUE_CONV, from, conv); } else if (fromref || (expr && real_lvalue_p (expr))) conv = build_conv (RVALUE_CONV, from, conv); if (from == to) return conv; if ((tcode == POINTER_TYPE || TYPE_PTRMEMFUNC_P (to)) && expr && null_ptr_cst_p (expr)) { conv = build_conv (STD_CONV, to, conv); } else if (tcode == POINTER_TYPE && fcode == POINTER_TYPE) { enum tree_code ufcode = TREE_CODE (TREE_TYPE (from)); enum tree_code utcode = TREE_CODE (TREE_TYPE (to)); if (same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (from)), TYPE_MAIN_VARIANT (TREE_TYPE (to)))) ; else if (utcode == VOID_TYPE && ufcode != OFFSET_TYPE && ufcode != FUNCTION_TYPE) { from = build_pointer_type (cp_build_qualified_type (void_type_node, CP_TYPE_QUALS (TREE_TYPE (from)))); conv = build_conv (PTR_CONV, from, conv); } else if (ufcode == OFFSET_TYPE && utcode == OFFSET_TYPE) { tree fbase = TYPE_OFFSET_BASETYPE (TREE_TYPE (from)); tree tbase = TYPE_OFFSET_BASETYPE (TREE_TYPE (to)); if (DERIVED_FROM_P (fbase, tbase) && (same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (from))), TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (to)))))) { from = build_offset_type (tbase, TREE_TYPE (TREE_TYPE (from))); from = build_pointer_type (from); conv = build_conv (PMEM_CONV, from, conv); } } else if (IS_AGGR_TYPE (TREE_TYPE (from)) && IS_AGGR_TYPE (TREE_TYPE (to))) { if (DERIVED_FROM_P (TREE_TYPE (to), TREE_TYPE (from))) { from = cp_build_qualified_type (TREE_TYPE (to), CP_TYPE_QUALS (TREE_TYPE (from))); from = build_pointer_type (from); conv = build_conv (PTR_CONV, from, conv); } } if (same_type_p (from, to)) /* OK */; else if (comp_ptr_ttypes (TREE_TYPE (to), TREE_TYPE (from))) conv = build_conv (QUAL_CONV, to, conv); else if (expr && string_conv_p (to, expr, 0)) /* converting from string constant to char *. */ conv = build_conv (QUAL_CONV, to, conv); else if (ptr_reasonably_similar (TREE_TYPE (to), TREE_TYPE (from))) { conv = build_conv (PTR_CONV, to, conv); ICS_BAD_FLAG (conv) = 1; } else return 0; from = to; } else if (TYPE_PTRMEMFUNC_P (to) && TYPE_PTRMEMFUNC_P (from)) { tree fromfn = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (from)); tree tofn = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (to)); tree fbase = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fromfn))); tree tbase = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (tofn))); if (! DERIVED_FROM_P (fbase, tbase) || ! same_type_p (TREE_TYPE (fromfn), TREE_TYPE (tofn)) || ! compparms (TREE_CHAIN (TYPE_ARG_TYPES (fromfn)), TREE_CHAIN (TYPE_ARG_TYPES (tofn))) || CP_TYPE_QUALS (fbase) != CP_TYPE_QUALS (tbase)) return 0; from = cp_build_qualified_type (tbase, CP_TYPE_QUALS (fbase)); from = build_cplus_method_type (from, TREE_TYPE (fromfn), TREE_CHAIN (TYPE_ARG_TYPES (fromfn))); from = build_ptrmemfunc_type (build_pointer_type (from)); conv = build_conv (PMEM_CONV, from, conv); } else if (tcode == BOOLEAN_TYPE) { if (! (INTEGRAL_CODE_P (fcode) || fcode == REAL_TYPE || fcode == POINTER_TYPE || TYPE_PTRMEMFUNC_P (from))) return 0; conv = build_conv (STD_CONV, to, conv); if (fcode == POINTER_TYPE || (TYPE_PTRMEMFUNC_P (from) && ICS_STD_RANK (conv) < PBOOL_RANK)) ICS_STD_RANK (conv) = PBOOL_RANK; } /* We don't check for ENUMERAL_TYPE here because there are no standard conversions to enum type. */ else if (tcode == INTEGER_TYPE || tcode == BOOLEAN_TYPE || tcode == REAL_TYPE) { if (! (INTEGRAL_CODE_P (fcode) || fcode == REAL_TYPE)) return 0; conv = build_conv (STD_CONV, to, conv); /* Give this a better rank if it's a promotion. */ if (to == type_promotes_to (from) && ICS_STD_RANK (TREE_OPERAND (conv, 0)) <= PROMO_RANK) ICS_STD_RANK (conv) = PROMO_RANK; } else if (IS_AGGR_TYPE (to) && IS_AGGR_TYPE (from) && DERIVED_FROM_P (to, from)) { if (TREE_CODE (conv) == RVALUE_CONV) conv = TREE_OPERAND (conv, 0); conv = build_conv (BASE_CONV, to, conv); } else return 0; return conv; } /* Returns the conversion path from type FROM to reference type TO for purposes of reference binding. For lvalue binding, either pass a reference type to FROM or an lvalue expression to EXPR. Currently does not distinguish in the generated trees between binding to an lvalue and a temporary. Should it? */ static tree reference_binding (rto, rfrom, expr, flags) tree rto, rfrom, expr; int flags; { tree conv; int lvalue = 1; tree to = TREE_TYPE (rto); tree from = rfrom; int related; if (TREE_CODE (to) == FUNCTION_TYPE && expr && type_unknown_p (expr)) { expr = instantiate_type (to, expr, 0); if (expr == error_mark_node) return NULL_TREE; from = TREE_TYPE (expr); } if (TREE_CODE (from) == REFERENCE_TYPE) from = TREE_TYPE (from); else if (! expr || ! real_lvalue_p (expr)) lvalue = 0; related = (same_type_p (TYPE_MAIN_VARIANT (to), TYPE_MAIN_VARIANT (from)) || (IS_AGGR_TYPE (to) && IS_AGGR_TYPE (from) && DERIVED_FROM_P (to, from))); if (lvalue && related && at_least_as_qualified_p (to, from)) { conv = build1 (IDENTITY_CONV, from, expr); if (same_type_p (TYPE_MAIN_VARIANT (to), TYPE_MAIN_VARIANT (from))) conv = build_conv (REF_BIND, rto, conv); else { conv = build_conv (REF_BIND, rto, conv); ICS_STD_RANK (conv) = STD_RANK; } } else conv = NULL_TREE; if (! conv) { conv = standard_conversion (to, rfrom, expr); if (conv) { conv = build_conv (REF_BIND, rto, conv); /* Bind directly to a base subobject of a class rvalue. Do it after building the conversion for proper handling of ICS_RANK. */ if (TREE_CODE (TREE_OPERAND (conv, 0)) == BASE_CONV) TREE_OPERAND (conv, 0) = TREE_OPERAND (TREE_OPERAND (conv, 0), 0); } if (conv && ((! (CP_TYPE_CONST_NON_VOLATILE_P (to) && (flags & LOOKUP_NO_TEMP_BIND) == 0)) /* If T1 is reference-related to T2, cv1 must be the same cv-qualification as, or greater cv-qualification than, cv2; otherwise, the program is ill-formed. */ || (related && !at_least_as_qualified_p (to, from)))) ICS_BAD_FLAG (conv) = 1; } return conv; } /* Returns the implicit conversion sequence (see [over.ics]) from type FROM to type TO. The optional expression EXPR may affect the conversion. FLAGS are the usual overloading flags. Only LOOKUP_NO_CONVERSION is significant. */ static tree implicit_conversion (to, from, expr, flags) tree to, from, expr; int flags; { tree conv; struct z_candidate *cand; if (TREE_CODE (to) == REFERENCE_TYPE) conv = reference_binding (to, from, expr, flags); else conv = standard_conversion (to, from, expr); if (conv) ; else if (expr != NULL_TREE && (IS_AGGR_TYPE (non_reference (from)) || IS_AGGR_TYPE (non_reference (to))) && (flags & LOOKUP_NO_CONVERSION) == 0) { cand = build_user_type_conversion_1 (to, expr, LOOKUP_ONLYCONVERTING); if (cand) conv = cand->second_conv; if ((! conv || ICS_BAD_FLAG (conv)) && TREE_CODE (to) == REFERENCE_TYPE && (flags & LOOKUP_NO_TEMP_BIND) == 0) { cand = build_user_type_conversion_1 (TYPE_MAIN_VARIANT (TREE_TYPE (to)), expr, LOOKUP_ONLYCONVERTING); if (cand) { if (!CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (to))) ICS_BAD_FLAG (cand->second_conv) = 1; if (!conv || (ICS_BAD_FLAG (conv) > ICS_BAD_FLAG (cand->second_conv))) conv = build_conv (REF_BIND, to, cand->second_conv); } } } return conv; } /* Add a new entry to the list of candidates. Used by the add_*_candidate functions. */ static struct z_candidate * add_candidate (candidates, fn, convs, viable) struct z_candidate *candidates; tree fn, convs; int viable; { struct z_candidate *cand = (struct z_candidate *) scratchalloc (sizeof (struct z_candidate)); cand->fn = fn; cand->convs = convs; cand->second_conv = NULL_TREE; cand->viable = viable; cand->basetype_path = NULL_TREE; cand->template = NULL_TREE; cand->warnings = NULL_TREE; cand->next = candidates; return cand; } /* Create an overload candidate for the function or method FN called with the argument list ARGLIST and add it to CANDIDATES. FLAGS is passed on to implicit_conversion. */ static struct z_candidate * add_function_candidate (candidates, fn, arglist, flags) struct z_candidate *candidates; tree fn, arglist; int flags; { tree parmlist = TYPE_ARG_TYPES (TREE_TYPE (fn)); int i, len; tree convs; tree parmnode, argnode; int viable = 1; - /* The `this' and `in_chrg' arguments to constructors are not considered - in overload resolution. */ + /* The `this', `in_chrg', and `vlist' arguments to constructors are + not considered in overload resolution. */ if (DECL_CONSTRUCTOR_P (fn)) { parmlist = TREE_CHAIN (parmlist); arglist = TREE_CHAIN (arglist); if (TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (fn))) { parmlist = TREE_CHAIN (parmlist); arglist = TREE_CHAIN (arglist); } + if ((flags & LOOKUP_HAS_VLIST) + && DECL_CONSTRUCTOR_FOR_PVBASE_P (fn)) + { + parmlist = TREE_CHAIN (parmlist); + arglist = TREE_CHAIN (arglist); + } + else if (!(flags & LOOKUP_HAS_VLIST) + && !DECL_CONSTRUCTOR_FOR_PVBASE_P (fn)) + /* Ok */; + else + { + /* The ctor expects a vlist and the arguments don't have + one, or vice versa, so fn is not even a candidate, since + the corresponding ctor would be the candidate. */ + return candidates; + } } len = list_length (arglist); convs = make_scratch_vec (len); /* 13.3.2 - Viable functions [over.match.viable] First, to be a viable function, a candidate function shall have enough parameters to agree in number with the arguments in the list. We need to check this first; otherwise, checking the ICSes might cause us to produce an ill-formed template instantiation. */ parmnode = parmlist; for (i = 0; i < len; ++i) { if (parmnode == NULL_TREE || parmnode == void_list_node) break; parmnode = TREE_CHAIN (parmnode); } if (i < len && parmnode) viable = 0; /* Make sure there are default args for the rest of the parms. */ else for (; parmnode && parmnode != void_list_node; parmnode = TREE_CHAIN (parmnode)) if (! TREE_PURPOSE (parmnode)) { viable = 0; break; } if (! viable) goto out; /* Second, for F to be a viable function, there shall exist for each argument an implicit conversion sequence that converts that argument to the corresponding parameter of F. */ parmnode = parmlist; argnode = arglist; for (i = 0; i < len; ++i) { tree arg = TREE_VALUE (argnode); tree argtype = lvalue_type (arg); tree t; if (parmnode == void_list_node) break; if (parmnode) { tree parmtype = TREE_VALUE (parmnode); /* [over.match.funcs] For conversion functions, the function is considered to be a member of the class of the implicit object argument for the purpose of defining the type of the implicit object parameter. Since build_over_call ignores the ICS for the `this' parameter, we can just change the parm type. */ if (DECL_CONV_FN_P (fn) && i == 0) { parmtype = build_qualified_type (TREE_TYPE (argtype), TYPE_QUALS (TREE_TYPE (parmtype))); parmtype = build_pointer_type (parmtype); } t = implicit_conversion (parmtype, argtype, arg, flags); } else { t = build1 (IDENTITY_CONV, argtype, arg); ICS_ELLIPSIS_FLAG (t) = 1; } if (i == 0 && t && TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE && ! DECL_CONSTRUCTOR_P (fn)) ICS_THIS_FLAG (t) = 1; TREE_VEC_ELT (convs, i) = t; if (! t) { viable = 0; break; } if (ICS_BAD_FLAG (t)) viable = -1; if (parmnode) parmnode = TREE_CHAIN (parmnode); argnode = TREE_CHAIN (argnode); } out: return add_candidate (candidates, fn, convs, viable); } /* Create an overload candidate for the conversion function FN which will be invoked for expression OBJ, producing a pointer-to-function which will in turn be called with the argument list ARGLIST, and add it to CANDIDATES. FLAGS is passed on to implicit_conversion. Actually, we don't really care about FN; we care about the type it converts to. There may be multiple conversion functions that will convert to that type, and we rely on build_user_type_conversion_1 to choose the best one; so when we create our candidate, we record the type instead of the function. */ static struct z_candidate * add_conv_candidate (candidates, fn, obj, arglist) struct z_candidate *candidates; tree fn, obj, arglist; { tree totype = TREE_TYPE (TREE_TYPE (fn)); tree parmlist = TYPE_ARG_TYPES (TREE_TYPE (totype)); int i, len = list_length (arglist) + 1; tree convs = make_scratch_vec (len); tree parmnode = parmlist; tree argnode = arglist; int viable = 1; int flags = LOOKUP_NORMAL; /* Don't bother looking up the same type twice. */ if (candidates && candidates->fn == totype) return candidates; for (i = 0; i < len; ++i) { tree arg = i == 0 ? obj : TREE_VALUE (argnode); tree argtype = lvalue_type (arg); tree t; if (i == 0) t = implicit_conversion (totype, argtype, arg, flags); else if (parmnode == void_list_node) break; else if (parmnode) t = implicit_conversion (TREE_VALUE (parmnode), argtype, arg, flags); else { t = build1 (IDENTITY_CONV, argtype, arg); ICS_ELLIPSIS_FLAG (t) = 1; } TREE_VEC_ELT (convs, i) = t; if (! t) break; if (ICS_BAD_FLAG (t)) viable = -1; if (i == 0) continue; if (parmnode) parmnode = TREE_CHAIN (parmnode); argnode = TREE_CHAIN (argnode); } if (i < len) viable = 0; for (; parmnode && parmnode != void_list_node; parmnode = TREE_CHAIN (parmnode)) if (! TREE_PURPOSE (parmnode)) { viable = 0; break; } return add_candidate (candidates, totype, convs, viable); } static struct z_candidate * build_builtin_candidate (candidates, fnname, type1, type2, args, argtypes, flags) struct z_candidate *candidates; tree fnname, type1, type2, *args, *argtypes; int flags; { tree t, convs; int viable = 1, i; tree types[2]; types[0] = type1; types[1] = type2; convs = make_scratch_vec (args[2] ? 3 : (args[1] ? 2 : 1)); for (i = 0; i < 2; ++i) { if (! args[i]) break; t = implicit_conversion (types[i], argtypes[i], args[i], flags); if (! t) { viable = 0; /* We need something for printing the candidate. */ t = build1 (IDENTITY_CONV, types[i], NULL_TREE); } else if (ICS_BAD_FLAG (t)) viable = 0; TREE_VEC_ELT (convs, i) = t; } /* For COND_EXPR we rearranged the arguments; undo that now. */ if (args[2]) { TREE_VEC_ELT (convs, 2) = TREE_VEC_ELT (convs, 1); TREE_VEC_ELT (convs, 1) = TREE_VEC_ELT (convs, 0); t = implicit_conversion (boolean_type_node, argtypes[2], args[2], flags); if (t) TREE_VEC_ELT (convs, 0) = t; else viable = 0; } return add_candidate (candidates, fnname, convs, viable); } static int is_complete (t) tree t; { return TYPE_SIZE (complete_type (t)) != NULL_TREE; } /* Create any builtin operator overload candidates for the operator in question given the converted operand types TYPE1 and TYPE2. The other args are passed through from add_builtin_candidates to build_builtin_candidate. */ static struct z_candidate * add_builtin_candidate (candidates, code, code2, fnname, type1, type2, args, argtypes, flags) struct z_candidate *candidates; enum tree_code code, code2; tree fnname, type1, type2, *args, *argtypes; int flags; { switch (code) { case POSTINCREMENT_EXPR: case POSTDECREMENT_EXPR: args[1] = integer_zero_node; type2 = integer_type_node; break; default: break; } switch (code) { /* 4 For every pair T, VQ), where T is an arithmetic or enumeration type, and VQ is either volatile or empty, there exist candidate operator functions of the form VQ T& operator++(VQ T&); T operator++(VQ T&, int); 5 For every pair T, VQ), where T is an enumeration type or an arithmetic type other than bool, and VQ is either volatile or empty, there exist candidate operator functions of the form VQ T& operator--(VQ T&); T operator--(VQ T&, int); 6 For every pair T, VQ), where T is a cv-qualified or cv-unqualified complete object type, and VQ is either volatile or empty, there exist candidate operator functions of the form T*VQ& operator++(T*VQ&); T*VQ& operator--(T*VQ&); T* operator++(T*VQ&, int); T* operator--(T*VQ&, int); */ case POSTDECREMENT_EXPR: case PREDECREMENT_EXPR: if (TREE_CODE (type1) == BOOLEAN_TYPE) return candidates; case POSTINCREMENT_EXPR: case PREINCREMENT_EXPR: if ((ARITHMETIC_TYPE_P (type1) && TREE_CODE (type1) != ENUMERAL_TYPE) || TYPE_PTROB_P (type1)) { type1 = build_reference_type (type1); break; } return candidates; /* 7 For every cv-qualified or cv-unqualified complete object type T, there exist candidate operator functions of the form T& operator*(T*); 8 For every function type T, there exist candidate operator functions of the form T& operator*(T*); */ case INDIRECT_REF: if (TREE_CODE (type1) == POINTER_TYPE && (TYPE_PTROB_P (type1) || TREE_CODE (TREE_TYPE (type1)) == FUNCTION_TYPE)) break; return candidates; /* 9 For every type T, there exist candidate operator functions of the form T* operator+(T*); 10For every promoted arithmetic type T, there exist candidate operator functions of the form T operator+(T); T operator-(T); */ case CONVERT_EXPR: /* unary + */ if (TREE_CODE (type1) == POINTER_TYPE && TREE_CODE (TREE_TYPE (type1)) != OFFSET_TYPE) break; case NEGATE_EXPR: if (ARITHMETIC_TYPE_P (type1)) break; return candidates; /* 11For every promoted integral type T, there exist candidate operator functions of the form T operator~(T); */ case BIT_NOT_EXPR: if (INTEGRAL_TYPE_P (type1)) break; return candidates; /* 12For every quintuple C1, C2, T, CV1, CV2), where C2 is a class type, C1 is the same type as C2 or is a derived class of C2, T is a complete object type or a function type, and CV1 and CV2 are cv-qualifier-seqs, there exist candidate operator functions of the form CV12 T& operator->*(CV1 C1*, CV2 T C2::*); where CV12 is the union of CV1 and CV2. */ case MEMBER_REF: if (TREE_CODE (type1) == POINTER_TYPE && (TYPE_PTRMEMFUNC_P (type2) || TYPE_PTRMEM_P (type2))) { tree c1 = TREE_TYPE (type1); tree c2 = (TYPE_PTRMEMFUNC_P (type2) ? TYPE_METHOD_BASETYPE (TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (type2))) : TYPE_OFFSET_BASETYPE (TREE_TYPE (type2))); if (IS_AGGR_TYPE (c1) && DERIVED_FROM_P (c2, c1) && (TYPE_PTRMEMFUNC_P (type2) || is_complete (TREE_TYPE (TREE_TYPE (type2))))) break; } return candidates; /* 13For every pair of promoted arithmetic types L and R, there exist can- didate operator functions of the form LR operator*(L, R); LR operator/(L, R); LR operator+(L, R); LR operator-(L, R); bool operator<(L, R); bool operator>(L, R); bool operator<=(L, R); bool operator>=(L, R); bool operator==(L, R); bool operator!=(L, R); where LR is the result of the usual arithmetic conversions between types L and R. 14For every pair of types T and I, where T is a cv-qualified or cv- unqualified complete object type and I is a promoted integral type, there exist candidate operator functions of the form T* operator+(T*, I); T& operator[](T*, I); T* operator-(T*, I); T* operator+(I, T*); T& operator[](I, T*); 15For every T, where T is a pointer to complete object type, there exist candidate operator functions of the form112) ptrdiff_t operator-(T, T); 16For every pointer type T, there exist candidate operator functions of the form bool operator<(T, T); bool operator>(T, T); bool operator<=(T, T); bool operator>=(T, T); bool operator==(T, T); bool operator!=(T, T); 17For every pointer to member type T, there exist candidate operator functions of the form bool operator==(T, T); bool operator!=(T, T); */ case MINUS_EXPR: if (TYPE_PTROB_P (type1) && TYPE_PTROB_P (type2)) break; if (TYPE_PTROB_P (type1) && INTEGRAL_TYPE_P (type2)) { type2 = ptrdiff_type_node; break; } case MULT_EXPR: case TRUNC_DIV_EXPR: if (ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2)) break; return candidates; case EQ_EXPR: case NE_EXPR: if ((TYPE_PTRMEMFUNC_P (type1) && TYPE_PTRMEMFUNC_P (type2)) || (TYPE_PTRMEM_P (type1) && TYPE_PTRMEM_P (type2))) break; if ((TYPE_PTRMEMFUNC_P (type1) || TYPE_PTRMEM_P (type1)) && null_ptr_cst_p (args[1])) { type2 = type1; break; } if ((TYPE_PTRMEMFUNC_P (type2) || TYPE_PTRMEM_P (type2)) && null_ptr_cst_p (args[0])) { type1 = type2; break; } case LT_EXPR: case GT_EXPR: case LE_EXPR: case GE_EXPR: case MAX_EXPR: case MIN_EXPR: if ((ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2)) || (TYPE_PTR_P (type1) && TYPE_PTR_P (type2))) break; if (TYPE_PTR_P (type1) && null_ptr_cst_p (args[1])) { type2 = type1; break; } if (null_ptr_cst_p (args[0]) && TYPE_PTR_P (type2)) { type1 = type2; break; } return candidates; case PLUS_EXPR: if (ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2)) break; case ARRAY_REF: if (INTEGRAL_TYPE_P (type1) && TYPE_PTROB_P (type2)) { type1 = ptrdiff_type_node; break; } if (TYPE_PTROB_P (type1) && INTEGRAL_TYPE_P (type2)) { type2 = ptrdiff_type_node; break; } return candidates; /* 18For every pair of promoted integral types L and R, there exist candi- date operator functions of the form LR operator%(L, R); LR operator&(L, R); LR operator^(L, R); LR operator|(L, R); L operator<<(L, R); L operator>>(L, R); where LR is the result of the usual arithmetic conversions between types L and R. */ case TRUNC_MOD_EXPR: case BIT_AND_EXPR: case BIT_IOR_EXPR: case BIT_XOR_EXPR: case LSHIFT_EXPR: case RSHIFT_EXPR: if (INTEGRAL_TYPE_P (type1) && INTEGRAL_TYPE_P (type2)) break; return candidates; /* 19For every triple L, VQ, R), where L is an arithmetic or enumeration type, VQ is either volatile or empty, and R is a promoted arithmetic type, there exist candidate operator functions of the form VQ L& operator=(VQ L&, R); VQ L& operator*=(VQ L&, R); VQ L& operator/=(VQ L&, R); VQ L& operator+=(VQ L&, R); VQ L& operator-=(VQ L&, R); 20For every pair T, VQ), where T is any type and VQ is either volatile or empty, there exist candidate operator functions of the form T*VQ& operator=(T*VQ&, T*); 21For every pair T, VQ), where T is a pointer to member type and VQ is either volatile or empty, there exist candidate operator functions of the form VQ T& operator=(VQ T&, T); 22For every triple T, VQ, I), where T is a cv-qualified or cv- unqualified complete object type, VQ is either volatile or empty, and I is a promoted integral type, there exist candidate operator func- tions of the form T*VQ& operator+=(T*VQ&, I); T*VQ& operator-=(T*VQ&, I); 23For every triple L, VQ, R), where L is an integral or enumeration type, VQ is either volatile or empty, and R is a promoted integral type, there exist candidate operator functions of the form VQ L& operator%=(VQ L&, R); VQ L& operator<<=(VQ L&, R); VQ L& operator>>=(VQ L&, R); VQ L& operator&=(VQ L&, R); VQ L& operator^=(VQ L&, R); VQ L& operator|=(VQ L&, R); */ case MODIFY_EXPR: switch (code2) { case PLUS_EXPR: case MINUS_EXPR: if (TYPE_PTROB_P (type1) && INTEGRAL_TYPE_P (type2)) { type2 = ptrdiff_type_node; break; } case MULT_EXPR: case TRUNC_DIV_EXPR: if (ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2)) break; return candidates; case TRUNC_MOD_EXPR: case BIT_AND_EXPR: case BIT_IOR_EXPR: case BIT_XOR_EXPR: case LSHIFT_EXPR: case RSHIFT_EXPR: if (INTEGRAL_TYPE_P (type1) && INTEGRAL_TYPE_P (type2)) break; return candidates; case NOP_EXPR: if (ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2)) break; if ((TYPE_PTRMEMFUNC_P (type1) && TYPE_PTRMEMFUNC_P (type2)) || (TYPE_PTR_P (type1) && TYPE_PTR_P (type2)) || (TYPE_PTRMEM_P (type1) && TYPE_PTRMEM_P (type2)) || ((TYPE_PTRMEMFUNC_P (type1) || TREE_CODE (type1) == POINTER_TYPE) && null_ptr_cst_p (args[1]))) { type2 = type1; break; } return candidates; default: my_friendly_abort (367); } type1 = build_reference_type (type1); break; case COND_EXPR: /* Kludge around broken overloading rules whereby bool ? const char& : enum is ambiguous (between int and const char&). */ flags |= LOOKUP_NO_TEMP_BIND; /* Extension: Support ?: of enumeral type. Hopefully this will not be an extension for long. */ if (TREE_CODE (type1) == ENUMERAL_TYPE && type1 == type2) break; else if (TREE_CODE (type1) == ENUMERAL_TYPE || TREE_CODE (type2) == ENUMERAL_TYPE) return candidates; if (ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2)) break; if (TREE_CODE (type1) == TREE_CODE (type2) && (TREE_CODE (type1) == REFERENCE_TYPE || TREE_CODE (type1) == POINTER_TYPE || TYPE_PTRMEMFUNC_P (type1) || IS_AGGR_TYPE (type1))) break; if (TREE_CODE (type1) == REFERENCE_TYPE || TREE_CODE (type2) == REFERENCE_TYPE) return candidates; if (((TYPE_PTRMEMFUNC_P (type1) || TREE_CODE (type1) == POINTER_TYPE) && null_ptr_cst_p (args[1])) || IS_AGGR_TYPE (type1)) { type2 = type1; break; } if (((TYPE_PTRMEMFUNC_P (type2) || TREE_CODE (type2) == POINTER_TYPE) && null_ptr_cst_p (args[0])) || IS_AGGR_TYPE (type2)) { type1 = type2; break; } return candidates; default: my_friendly_abort (367); } /* If we're dealing with two pointer types, we need candidates for both of them. */ if (type2 && type1 != type2 && TREE_CODE (type1) == TREE_CODE (type2) && (TREE_CODE (type1) == REFERENCE_TYPE || (TREE_CODE (type1) == POINTER_TYPE && TYPE_PTRMEM_P (type1) == TYPE_PTRMEM_P (type2)) || TYPE_PTRMEMFUNC_P (type1) || IS_AGGR_TYPE (type1))) { candidates = build_builtin_candidate (candidates, fnname, type1, type1, args, argtypes, flags); return build_builtin_candidate (candidates, fnname, type2, type2, args, argtypes, flags); } return build_builtin_candidate (candidates, fnname, type1, type2, args, argtypes, flags); } tree type_decays_to (type) tree type; { if (TREE_CODE (type) == ARRAY_TYPE) return build_pointer_type (TREE_TYPE (type)); if (TREE_CODE (type) == FUNCTION_TYPE) return build_pointer_type (type); return type; } /* There are three conditions of builtin candidates: 1) bool-taking candidates. These are the same regardless of the input. 2) pointer-pair taking candidates. These are generated for each type one of the input types converts to. 3) arithmetic candidates. According to the WP, we should generate all of these, but I'm trying not to... */ static struct z_candidate * add_builtin_candidates (candidates, code, code2, fnname, args, flags) struct z_candidate *candidates; enum tree_code code, code2; tree fnname, *args; int flags; { int ref1, i; tree type, argtypes[3], types[2]; for (i = 0; i < 3; ++i) { if (args[i]) argtypes[i] = lvalue_type (args[i]); else argtypes[i] = NULL_TREE; } switch (code) { /* 4 For every pair T, VQ), where T is an arithmetic or enumeration type, and VQ is either volatile or empty, there exist candidate operator functions of the form VQ T& operator++(VQ T&); */ case POSTINCREMENT_EXPR: case PREINCREMENT_EXPR: case POSTDECREMENT_EXPR: case PREDECREMENT_EXPR: case MODIFY_EXPR: ref1 = 1; break; /* 24There also exist candidate operator functions of the form bool operator!(bool); bool operator&&(bool, bool); bool operator||(bool, bool); */ case TRUTH_NOT_EXPR: return build_builtin_candidate (candidates, fnname, boolean_type_node, NULL_TREE, args, argtypes, flags); case TRUTH_ORIF_EXPR: case TRUTH_ANDIF_EXPR: return build_builtin_candidate (candidates, fnname, boolean_type_node, boolean_type_node, args, argtypes, flags); case ADDR_EXPR: case COMPOUND_EXPR: case COMPONENT_REF: return candidates; default: ref1 = 0; } types[0] = types[1] = NULL_TREE; for (i = 0; i < 2; ++i) { if (! args[i]) ; else if (IS_AGGR_TYPE (argtypes[i])) { tree convs; if (i == 0 && code == MODIFY_EXPR && code2 == NOP_EXPR) return candidates; convs = lookup_conversions (argtypes[i]); if (code == COND_EXPR) { if (real_lvalue_p (args[i])) types[i] = scratch_tree_cons (NULL_TREE, build_reference_type (argtypes[i]), types[i]); types[i] = scratch_tree_cons (NULL_TREE, TYPE_MAIN_VARIANT (argtypes[i]), types[i]); } else if (! convs) return candidates; for (; convs; convs = TREE_CHAIN (convs)) { type = TREE_TYPE (TREE_TYPE (OVL_CURRENT (TREE_VALUE (convs)))); if (i == 0 && ref1 && (TREE_CODE (type) != REFERENCE_TYPE || CP_TYPE_CONST_P (TREE_TYPE (type)))) continue; if (code == COND_EXPR && TREE_CODE (type) == REFERENCE_TYPE) types[i] = scratch_tree_cons (NULL_TREE, type, types[i]); type = non_reference (type); if (i != 0 || ! ref1) { type = TYPE_MAIN_VARIANT (type_decays_to (type)); if (code == COND_EXPR && TREE_CODE (type) == ENUMERAL_TYPE) types[i] = scratch_tree_cons (NULL_TREE, type, types[i]); if (INTEGRAL_TYPE_P (type)) type = type_promotes_to (type); } if (! value_member (type, types[i])) types[i] = scratch_tree_cons (NULL_TREE, type, types[i]); } } else { if (code == COND_EXPR && real_lvalue_p (args[i])) types[i] = scratch_tree_cons (NULL_TREE, build_reference_type (argtypes[i]), types[i]); type = non_reference (argtypes[i]); if (i != 0 || ! ref1) { type = TYPE_MAIN_VARIANT (type_decays_to (type)); if (code == COND_EXPR && TREE_CODE (type) == ENUMERAL_TYPE) types[i] = scratch_tree_cons (NULL_TREE, type, types[i]); if (INTEGRAL_TYPE_P (type)) type = type_promotes_to (type); } types[i] = scratch_tree_cons (NULL_TREE, type, types[i]); } } for (; types[0]; types[0] = TREE_CHAIN (types[0])) { if (types[1]) for (type = types[1]; type; type = TREE_CHAIN (type)) candidates = add_builtin_candidate (candidates, code, code2, fnname, TREE_VALUE (types[0]), TREE_VALUE (type), args, argtypes, flags); else candidates = add_builtin_candidate (candidates, code, code2, fnname, TREE_VALUE (types[0]), NULL_TREE, args, argtypes, flags); } return candidates; } /* If TMPL can be successfully instantiated as indicated by EXPLICIT_TARGS and ARGLIST, adds the instantiation to CANDIDATES. TMPL is the template. EXPLICIT_TARGS are any explicit template arguments. ARGLIST is the arguments provided at the call-site. The RETURN_TYPE is the desired type for conversion operators. If OBJ is NULL_TREE, FLAGS are as for add_function_candidate. If an OBJ is supplied, FLAGS are ignored, and OBJ is as for add_conv_candidate. */ static struct z_candidate* add_template_candidate_real (candidates, tmpl, explicit_targs, arglist, return_type, flags, obj, strict) struct z_candidate *candidates; tree tmpl, explicit_targs, arglist, return_type; int flags; tree obj; unification_kind_t strict; { int ntparms = DECL_NTPARMS (tmpl); tree targs = make_scratch_vec (ntparms); struct z_candidate *cand; int i; tree fn; i = fn_type_unification (tmpl, explicit_targs, targs, arglist, return_type, strict); if (i != 0) return candidates; fn = instantiate_template (tmpl, targs); if (fn == error_mark_node) return candidates; if (obj != NULL_TREE) /* Aha, this is a conversion function. */ cand = add_conv_candidate (candidates, fn, obj, arglist); else cand = add_function_candidate (candidates, fn, arglist, flags); if (DECL_TI_TEMPLATE (fn) != tmpl) /* This situation can occur if a member template of a template class is specialized. Then, instantiate_template might return an instantiation of the specialization, in which case the DECL_TI_TEMPLATE field will point at the original specialization. For example: template struct S { template void f(U); template <> void f(int) {}; }; S sd; sd.f(3); Here, TMPL will be template S::f(U). And, instantiate template will give us the specialization template <> S::f(int). But, the DECL_TI_TEMPLATE field for this will point at template template <> S::f(int), so that we can find the definition. For the purposes of overload resolution, however, we want the original TMPL. */ cand->template = tree_cons (tmpl, targs, NULL_TREE); else cand->template = DECL_TEMPLATE_INFO (fn); return cand; } static struct z_candidate * add_template_candidate (candidates, tmpl, explicit_targs, arglist, return_type, flags, strict) struct z_candidate *candidates; tree tmpl, explicit_targs, arglist, return_type; int flags; unification_kind_t strict; { return add_template_candidate_real (candidates, tmpl, explicit_targs, arglist, return_type, flags, NULL_TREE, strict); } static struct z_candidate * add_template_conv_candidate (candidates, tmpl, obj, arglist, return_type) struct z_candidate *candidates; tree tmpl, obj, arglist, return_type; { return add_template_candidate_real (candidates, tmpl, NULL_TREE, arglist, return_type, 0, obj, DEDUCE_CONV); } static int any_viable (cands) struct z_candidate *cands; { for (; cands; cands = cands->next) if (pedantic ? cands->viable == 1 : cands->viable) return 1; return 0; } static struct z_candidate * splice_viable (cands) struct z_candidate *cands; { struct z_candidate **p = &cands; for (; *p; ) { if (pedantic ? (*p)->viable == 1 : (*p)->viable) p = &((*p)->next); else *p = (*p)->next; } return cands; } static tree build_this (obj) tree obj; { /* Fix this to work on non-lvalues. */ if (IS_SIGNATURE_POINTER (TREE_TYPE (obj)) || IS_SIGNATURE_REFERENCE (TREE_TYPE (obj))) return obj; else return build_unary_op (ADDR_EXPR, obj, 0); } static void print_z_candidates (candidates) struct z_candidate *candidates; { const char *str = "candidates are:"; for (; candidates; candidates = candidates->next) { if (TREE_CODE (candidates->fn) == IDENTIFIER_NODE) { if (candidates->fn == ansi_opname [COND_EXPR]) cp_error ("%s %D(%T, %T, %T) ", str, candidates->fn, TREE_TYPE (TREE_VEC_ELT (candidates->convs, 0)), TREE_TYPE (TREE_VEC_ELT (candidates->convs, 1)), TREE_TYPE (TREE_VEC_ELT (candidates->convs, 2))); else if (TREE_VEC_LENGTH (candidates->convs) == 2) cp_error ("%s %D(%T, %T) ", str, candidates->fn, TREE_TYPE (TREE_VEC_ELT (candidates->convs, 0)), TREE_TYPE (TREE_VEC_ELT (candidates->convs, 1))); else cp_error ("%s %D(%T) ", str, candidates->fn, TREE_TYPE (TREE_VEC_ELT (candidates->convs, 0))); } else if (TYPE_P (candidates->fn)) cp_error ("%s %T ", str, candidates->fn); else cp_error_at ("%s %+#D%s", str, candidates->fn, candidates->viable == -1 ? " " : ""); str = " "; } } /* Returns the best overload candidate to perform the requested conversion. This function is used for three the overloading situations described in [over.match.copy], [over.match.conv], and [over.match.ref]. If TOTYPE is a REFERENCE_TYPE, we're trying to find an lvalue binding as per [dcl.init.ref], so we ignore temporary bindings. */ static struct z_candidate * build_user_type_conversion_1 (totype, expr, flags) tree totype, expr; int flags; { struct z_candidate *candidates, *cand; tree fromtype = TREE_TYPE (expr); tree ctors = NULL_TREE, convs = NULL_TREE, *p; tree args = NULL_TREE; tree templates = NULL_TREE; if (IS_AGGR_TYPE (totype)) ctors = lookup_fnfields (TYPE_BINFO (totype), ctor_identifier, 0); if (IS_AGGR_TYPE (fromtype) && (! IS_AGGR_TYPE (totype) || ! DERIVED_FROM_P (totype, fromtype))) convs = lookup_conversions (fromtype); candidates = 0; flags |= LOOKUP_NO_CONVERSION; if (ctors) { tree t = build_int_2 (0, 0); TREE_TYPE (t) = build_pointer_type (totype); args = build_scratch_list (NULL_TREE, expr); + if (TYPE_USES_PVBASES (totype) && !flag_vtable_thunks_compat) + { + args = scratch_tree_cons (NULL_TREE, vlist_zero_node, args); + flags |= LOOKUP_HAS_VLIST; + } if (TYPE_USES_VIRTUAL_BASECLASSES (totype)) args = scratch_tree_cons (NULL_TREE, integer_one_node, args); args = scratch_tree_cons (NULL_TREE, t, args); ctors = TREE_VALUE (ctors); } for (; ctors; ctors = OVL_NEXT (ctors)) { tree ctor = OVL_CURRENT (ctors); if (DECL_NONCONVERTING_P (ctor)) continue; if (TREE_CODE (ctor) == TEMPLATE_DECL) { templates = scratch_tree_cons (NULL_TREE, ctor, templates); candidates = add_template_candidate (candidates, ctor, NULL_TREE, args, NULL_TREE, flags, DEDUCE_CALL); } else candidates = add_function_candidate (candidates, ctor, args, flags); if (candidates) { candidates->second_conv = build1 (IDENTITY_CONV, totype, NULL_TREE); candidates->basetype_path = TYPE_BINFO (totype); } } if (convs) args = build_scratch_list (NULL_TREE, build_this (expr)); for (; convs; convs = TREE_CHAIN (convs)) { tree fns = TREE_VALUE (convs); int convflags = LOOKUP_NO_CONVERSION; tree ics; /* If we are called to convert to a reference type, we are trying to find an lvalue binding, so don't even consider temporaries. If we don't find an lvalue binding, the caller will try again to look for a temporary binding. */ if (TREE_CODE (totype) == REFERENCE_TYPE) convflags |= LOOKUP_NO_TEMP_BIND; if (TREE_CODE (OVL_CURRENT (fns)) != TEMPLATE_DECL) ics = implicit_conversion (totype, TREE_TYPE (TREE_TYPE (OVL_CURRENT (fns))), 0, convflags); else /* We can't compute this yet. */ ics = error_mark_node; if (TREE_CODE (totype) == REFERENCE_TYPE && ics && ICS_BAD_FLAG (ics)) /* ignore the near match. */; else if (ics) for (; fns; fns = OVL_NEXT (fns)) { tree fn = OVL_CURRENT (fns); struct z_candidate *old_candidates = candidates; if (TREE_CODE (fn) == TEMPLATE_DECL) { templates = scratch_tree_cons (NULL_TREE, fn, templates); candidates = add_template_candidate (candidates, fn, NULL_TREE, args, totype, flags, DEDUCE_CONV); } else candidates = add_function_candidate (candidates, fn, args, flags); if (candidates != old_candidates) { if (TREE_CODE (fn) == TEMPLATE_DECL) ics = implicit_conversion (totype, TREE_TYPE (TREE_TYPE (candidates->fn)), 0, convflags); candidates->second_conv = ics; candidates->basetype_path = TREE_PURPOSE (convs); if (ics == NULL_TREE) candidates->viable = 0; else if (candidates->viable == 1 && ICS_BAD_FLAG (ics)) candidates->viable = -1; } } } if (! any_viable (candidates)) { #if 0 if (flags & LOOKUP_COMPLAIN) { if (candidates && ! candidates->next) /* say why this one won't work or try to be loose */; else cp_error ("no viable candidates"); } #endif return 0; } candidates = splice_viable (candidates); cand = tourney (candidates); if (cand == 0) { if (flags & LOOKUP_COMPLAIN) { cp_error ("conversion from `%T' to `%T' is ambiguous", fromtype, totype); print_z_candidates (candidates); } cand = candidates; /* any one will do */ cand->second_conv = build1 (AMBIG_CONV, totype, expr); ICS_USER_FLAG (cand->second_conv) = 1; ICS_BAD_FLAG (cand->second_conv) = 1; return cand; } for (p = &(cand->second_conv); TREE_CODE (*p) != IDENTITY_CONV; ) p = &(TREE_OPERAND (*p, 0)); /* Pedantically, normal function declarations are never considered to refer to template instantiations, so we only do this with -fguiding-decls. */ if (flag_guiding_decls && templates && ! cand->template && !DECL_INITIAL (cand->fn) && TREE_CODE (TREE_TYPE (cand->fn)) != METHOD_TYPE) add_maybe_template (cand->fn, templates); *p = build (USER_CONV, (DECL_CONSTRUCTOR_P (cand->fn) ? totype : non_reference (TREE_TYPE (TREE_TYPE (cand->fn)))), expr, build_expr_ptr_wrapper (cand)); ICS_USER_FLAG (cand->second_conv) = 1; if (cand->viable == -1) ICS_BAD_FLAG (cand->second_conv) = 1; return cand; } tree build_user_type_conversion (totype, expr, flags) tree totype, expr; int flags; { struct z_candidate *cand = build_user_type_conversion_1 (totype, expr, flags); if (cand) { if (TREE_CODE (cand->second_conv) == AMBIG_CONV) return error_mark_node; return convert_from_reference (convert_like (cand->second_conv, expr)); } return NULL_TREE; } /* Do any initial processing on the arguments to a function call. */ static tree resolve_args (args) tree args; { tree t; for (t = args; t; t = TREE_CHAIN (t)) { if (TREE_VALUE (t) == error_mark_node) return error_mark_node; else if (TREE_CODE (TREE_TYPE (TREE_VALUE (t))) == VOID_TYPE) { error ("invalid use of void expression"); return error_mark_node; } else if (TREE_CODE (TREE_VALUE (t)) == OFFSET_REF) TREE_VALUE (t) = resolve_offset_ref (TREE_VALUE (t)); } return args; } tree build_new_function_call (fn, args) tree fn, args; { struct z_candidate *candidates = 0, *cand; tree explicit_targs = NULL_TREE; int template_only = 0; if (TREE_CODE (fn) == TEMPLATE_ID_EXPR) { explicit_targs = TREE_OPERAND (fn, 1); fn = TREE_OPERAND (fn, 0); template_only = 1; } if (really_overloaded_fn (fn)) { tree t1; tree templates = NULL_TREE; args = resolve_args (args); if (args == error_mark_node) return error_mark_node; for (t1 = fn; t1; t1 = OVL_CHAIN (t1)) { tree t = OVL_FUNCTION (t1); struct z_candidate *old_candidates = candidates; if (TREE_CODE (t) == TEMPLATE_DECL) { templates = scratch_tree_cons (NULL_TREE, t, templates); candidates = add_template_candidate (candidates, t, explicit_targs, args, NULL_TREE, LOOKUP_NORMAL, DEDUCE_CALL); } else if (! template_only) candidates = add_function_candidate (candidates, t, args, LOOKUP_NORMAL); if (candidates != old_candidates) candidates->basetype_path = DECL_REAL_CONTEXT (t); } if (! any_viable (candidates)) { if (candidates && ! candidates->next) return build_function_call (candidates->fn, args); cp_error ("no matching function for call to `%D (%A)'", DECL_NAME (OVL_FUNCTION (fn)), args); if (candidates) print_z_candidates (candidates); return error_mark_node; } candidates = splice_viable (candidates); cand = tourney (candidates); if (cand == 0) { cp_error ("call of overloaded `%D (%A)' is ambiguous", DECL_NAME (OVL_FUNCTION (fn)), args); print_z_candidates (candidates); return error_mark_node; } /* Pedantically, normal function declarations are never considered to refer to template instantiations, so we only do this with -fguiding-decls. */ if (flag_guiding_decls && templates && ! cand->template && ! DECL_INITIAL (cand->fn)) add_maybe_template (cand->fn, templates); return build_over_call (cand, args, LOOKUP_NORMAL); } /* This is not really overloaded. */ fn = OVL_CURRENT (fn); return build_function_call (fn, args); } static tree build_object_call (obj, args) tree obj, args; { struct z_candidate *candidates = 0, *cand; tree fns, convs, mem_args = NULL_TREE; tree type = TREE_TYPE (obj); if (TYPE_PTRMEMFUNC_P (type)) { /* It's no good looking for an overloaded operator() on a pointer-to-member-function. */ cp_error ("pointer-to-member function %E cannot be called", obj); cp_error ("without an object; consider using .* or ->*"); return error_mark_node; } fns = lookup_fnfields (TYPE_BINFO (type), ansi_opname [CALL_EXPR], 1); if (fns == error_mark_node) return error_mark_node; args = resolve_args (args); if (args == error_mark_node) return error_mark_node; if (fns) { tree base = TREE_PURPOSE (fns); mem_args = scratch_tree_cons (NULL_TREE, build_this (obj), args); for (fns = TREE_VALUE (fns); fns; fns = OVL_NEXT (fns)) { tree fn = OVL_CURRENT (fns); if (TREE_CODE (fn) == TEMPLATE_DECL) { candidates = add_template_candidate (candidates, fn, NULL_TREE, mem_args, NULL_TREE, LOOKUP_NORMAL, DEDUCE_CALL); } else candidates = add_function_candidate (candidates, fn, mem_args, LOOKUP_NORMAL); if (candidates) candidates->basetype_path = base; } } convs = lookup_conversions (type); for (; convs; convs = TREE_CHAIN (convs)) { tree fns = TREE_VALUE (convs); tree totype = TREE_TYPE (TREE_TYPE (OVL_CURRENT (fns))); if ((TREE_CODE (totype) == POINTER_TYPE || TREE_CODE (totype) == REFERENCE_TYPE) && TREE_CODE (TREE_TYPE (totype)) == FUNCTION_TYPE) for (; fns; fns = OVL_NEXT (fns)) { tree fn = OVL_CURRENT (fns); if (TREE_CODE (fn) == TEMPLATE_DECL) { candidates = add_template_conv_candidate (candidates, fn, obj, args, totype); } else candidates = add_conv_candidate (candidates, fn, obj, args); if (candidates) candidates->basetype_path = TREE_PURPOSE (convs); } } if (! any_viable (candidates)) { cp_error ("no match for call to `(%T) (%A)'", TREE_TYPE (obj), args); print_z_candidates (candidates); return error_mark_node; } candidates = splice_viable (candidates); cand = tourney (candidates); if (cand == 0) { cp_error ("call of `(%T) (%A)' is ambiguous", TREE_TYPE (obj), args); print_z_candidates (candidates); return error_mark_node; } /* Since cand->fn will be a type, not a function, for a conversion function, we must be careful not to unconditionally look at DECL_NAME here. */ if (TREE_CODE (cand->fn) == FUNCTION_DECL && DECL_NAME (cand->fn) == ansi_opname [CALL_EXPR]) return build_over_call (cand, mem_args, LOOKUP_NORMAL); obj = convert_like (TREE_VEC_ELT (cand->convs, 0), obj); /* FIXME */ return build_function_call (obj, args); } static void op_error (code, code2, arg1, arg2, arg3, problem) enum tree_code code, code2; tree arg1, arg2, arg3; const char *problem; { const char * opname = (code == MODIFY_EXPR ? assignop_tab [code2] : opname_tab [code]); switch (code) { case COND_EXPR: cp_error ("%s for `%T ? %T : %T'", problem, error_type (arg1), error_type (arg2), error_type (arg3)); break; case POSTINCREMENT_EXPR: case POSTDECREMENT_EXPR: cp_error ("%s for `%T%s'", problem, error_type (arg1), opname); break; case ARRAY_REF: cp_error ("%s for `%T[%T]'", problem, error_type (arg1), error_type (arg2)); break; default: if (arg2) cp_error ("%s for `%T %s %T'", problem, error_type (arg1), opname, error_type (arg2)); else cp_error ("%s for `%s%T'", problem, opname, error_type (arg1)); } } tree build_new_op (code, flags, arg1, arg2, arg3) enum tree_code code; int flags; tree arg1, arg2, arg3; { struct z_candidate *candidates = 0, *cand; tree fns, mem_arglist = NULL_TREE, arglist, fnname; enum tree_code code2 = NOP_EXPR; tree templates = NULL_TREE; tree conv; if (arg1 == error_mark_node || arg2 == error_mark_node || arg3 == error_mark_node) return error_mark_node; /* This can happen if a template takes all non-type parameters, e.g. undeclared_template<1, 5, 72>a; */ if (code == LT_EXPR && TREE_CODE (arg1) == TEMPLATE_DECL) { cp_error ("`%D' must be declared before use", arg1); return error_mark_node; } if (code == MODIFY_EXPR) { code2 = TREE_CODE (arg3); arg3 = NULL_TREE; fnname = ansi_assopname[code2]; } else fnname = ansi_opname[code]; switch (code) { case NEW_EXPR: case VEC_NEW_EXPR: case VEC_DELETE_EXPR: case DELETE_EXPR: /* Use build_op_new_call and build_op_delete_call instead. */ my_friendly_abort (981018); case CALL_EXPR: return build_object_call (arg1, arg2); default: break; } /* The comma operator can have void args. */ if (TREE_CODE (arg1) == OFFSET_REF) arg1 = resolve_offset_ref (arg1); if (arg2 && TREE_CODE (arg2) == OFFSET_REF) arg2 = resolve_offset_ref (arg2); if (arg3 && TREE_CODE (arg3) == OFFSET_REF) arg3 = resolve_offset_ref (arg3); if (code == COND_EXPR) { if (arg2 == NULL_TREE || TREE_CODE (TREE_TYPE (arg2)) == VOID_TYPE || TREE_CODE (TREE_TYPE (arg3)) == VOID_TYPE || (! IS_OVERLOAD_TYPE (TREE_TYPE (arg2)) && ! IS_OVERLOAD_TYPE (TREE_TYPE (arg3)))) goto builtin; } else if (! IS_OVERLOAD_TYPE (TREE_TYPE (arg1)) && (! arg2 || ! IS_OVERLOAD_TYPE (TREE_TYPE (arg2)))) goto builtin; if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR) arg2 = integer_zero_node; if (arg2 && arg3) arglist = scratch_tree_cons (NULL_TREE, arg1, scratch_tree_cons (NULL_TREE, arg2, build_scratch_list (NULL_TREE, arg3))); else if (arg2) arglist = scratch_tree_cons (NULL_TREE, arg1, build_scratch_list (NULL_TREE, arg2)); else arglist = build_scratch_list (NULL_TREE, arg1); fns = lookup_function_nonclass (fnname, arglist); if (fns && TREE_CODE (fns) == TREE_LIST) fns = TREE_VALUE (fns); for (; fns; fns = OVL_NEXT (fns)) { tree fn = OVL_CURRENT (fns); if (TREE_CODE (fn) == TEMPLATE_DECL) { templates = scratch_tree_cons (NULL_TREE, fn, templates); candidates = add_template_candidate (candidates, fn, NULL_TREE, arglist, TREE_TYPE (fnname), flags, DEDUCE_CALL); } else candidates = add_function_candidate (candidates, fn, arglist, flags); } if (IS_AGGR_TYPE (TREE_TYPE (arg1))) { fns = lookup_fnfields (TYPE_BINFO (TREE_TYPE (arg1)), fnname, 1); if (fns == error_mark_node) return fns; } else fns = NULL_TREE; if (fns) { tree basetype = TREE_PURPOSE (fns); mem_arglist = scratch_tree_cons (NULL_TREE, build_this (arg1), TREE_CHAIN (arglist)); for (fns = TREE_VALUE (fns); fns; fns = OVL_NEXT (fns)) { tree fn = OVL_CURRENT (fns); tree this_arglist; if (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE) this_arglist = mem_arglist; else this_arglist = arglist; if (TREE_CODE (fn) == TEMPLATE_DECL) { /* A member template. */ templates = scratch_tree_cons (NULL_TREE, fn, templates); candidates = add_template_candidate (candidates, fn, NULL_TREE, this_arglist, TREE_TYPE (fnname), flags, DEDUCE_CALL); } else candidates = add_function_candidate (candidates, fn, this_arglist, flags); if (candidates) candidates->basetype_path = basetype; } } { tree args[3]; /* Rearrange the arguments for ?: so that add_builtin_candidate only has to know about two args; a builtin candidate will always have a first parameter of type bool. We'll handle that in build_builtin_candidate. */ if (code == COND_EXPR) { args[0] = arg2; args[1] = arg3; args[2] = arg1; } else { args[0] = arg1; args[1] = arg2; args[2] = NULL_TREE; } candidates = add_builtin_candidates (candidates, code, code2, fnname, args, flags); } if (! any_viable (candidates)) { switch (code) { case POSTINCREMENT_EXPR: case POSTDECREMENT_EXPR: /* Look for an `operator++ (int)'. If they didn't have one, then we fall back to the old way of doing things. */ if (flags & LOOKUP_COMPLAIN) cp_pedwarn ("no `%D (int)' declared for postfix `%s', trying prefix operator instead", fnname, opname_tab [code]); if (code == POSTINCREMENT_EXPR) code = PREINCREMENT_EXPR; else code = PREDECREMENT_EXPR; return build_new_op (code, flags, arg1, NULL_TREE, NULL_TREE); /* The caller will deal with these. */ case ADDR_EXPR: case COMPOUND_EXPR: case COMPONENT_REF: return NULL_TREE; default: break; } if (flags & LOOKUP_COMPLAIN) { op_error (code, code2, arg1, arg2, arg3, "no match"); print_z_candidates (candidates); } return error_mark_node; } candidates = splice_viable (candidates); cand = tourney (candidates); if (cand == 0) { if (flags & LOOKUP_COMPLAIN) { op_error (code, code2, arg1, arg2, arg3, "ambiguous overload"); print_z_candidates (candidates); } return error_mark_node; } if (TREE_CODE (cand->fn) == FUNCTION_DECL) { extern int warn_synth; if (warn_synth && fnname == ansi_opname[MODIFY_EXPR] && DECL_ARTIFICIAL (cand->fn) && candidates->next && ! candidates->next->next) { cp_warning ("using synthesized `%#D' for copy assignment", cand->fn); cp_warning_at (" where cfront would use `%#D'", cand == candidates ? candidates->next->fn : candidates->fn); } /* Pedantically, normal function declarations are never considered to refer to template instantiations, so we only do this with -fguiding-decls. */ if (flag_guiding_decls && templates && ! cand->template && ! DECL_INITIAL (cand->fn) && TREE_CODE (TREE_TYPE (cand->fn)) != METHOD_TYPE) add_maybe_template (cand->fn, templates); return build_over_call (cand, TREE_CODE (TREE_TYPE (cand->fn)) == METHOD_TYPE ? mem_arglist : arglist, LOOKUP_NORMAL); } /* Check for comparison of different enum types. */ switch (code) { case GT_EXPR: case LT_EXPR: case GE_EXPR: case LE_EXPR: case EQ_EXPR: case NE_EXPR: if (TREE_CODE (TREE_TYPE (arg1)) == ENUMERAL_TYPE && TREE_CODE (TREE_TYPE (arg2)) == ENUMERAL_TYPE && (TYPE_MAIN_VARIANT (TREE_TYPE (arg1)) != TYPE_MAIN_VARIANT (TREE_TYPE (arg2)))) { cp_warning ("comparison between `%#T' and `%#T'", TREE_TYPE (arg1), TREE_TYPE (arg2)); } break; default: break; } /* We need to strip any leading REF_BIND so that bitfields don't cause errors. This should not remove any important conversions, because builtins don't apply to class objects directly. */ conv = TREE_VEC_ELT (cand->convs, 0); if (TREE_CODE (conv) == REF_BIND) conv = TREE_OPERAND (conv, 0); arg1 = convert_like (conv, arg1); if (arg2) { conv = TREE_VEC_ELT (cand->convs, 1); if (TREE_CODE (conv) == REF_BIND) conv = TREE_OPERAND (conv, 0); arg2 = convert_like (conv, arg2); } if (arg3) { conv = TREE_VEC_ELT (cand->convs, 2); if (TREE_CODE (conv) == REF_BIND) conv = TREE_OPERAND (conv, 0); arg3 = convert_like (conv, arg3); } builtin: switch (code) { case MODIFY_EXPR: return build_modify_expr (arg1, code2, arg2); case INDIRECT_REF: return build_indirect_ref (arg1, "unary *"); case PLUS_EXPR: case MINUS_EXPR: case MULT_EXPR: case TRUNC_DIV_EXPR: case GT_EXPR: case LT_EXPR: case GE_EXPR: case LE_EXPR: case EQ_EXPR: case NE_EXPR: case MAX_EXPR: case MIN_EXPR: case LSHIFT_EXPR: case RSHIFT_EXPR: case TRUNC_MOD_EXPR: case BIT_AND_EXPR: case BIT_IOR_EXPR: case BIT_XOR_EXPR: case TRUTH_ANDIF_EXPR: case TRUTH_ORIF_EXPR: return build_binary_op_nodefault (code, arg1, arg2, code); case CONVERT_EXPR: case NEGATE_EXPR: case BIT_NOT_EXPR: case TRUTH_NOT_EXPR: case PREINCREMENT_EXPR: case POSTINCREMENT_EXPR: case PREDECREMENT_EXPR: case POSTDECREMENT_EXPR: case REALPART_EXPR: case IMAGPART_EXPR: return build_unary_op (code, arg1, candidates != 0); case ARRAY_REF: return build_array_ref (arg1, arg2); case COND_EXPR: return build_conditional_expr (arg1, arg2, arg3); case MEMBER_REF: return build_m_component_ref (build_indirect_ref (arg1, NULL_PTR), arg2); /* The caller will deal with these. */ case ADDR_EXPR: case COMPONENT_REF: case COMPOUND_EXPR: return NULL_TREE; default: my_friendly_abort (367); return NULL_TREE; } } /* Build up a call to operator new. This has to be handled differently from other operators in the way lookup is handled; first members are considered, then globals. CODE is either NEW_EXPR or VEC_NEW_EXPR. TYPE is the type to be created. ARGS are any new-placement args. FLAGS are the usual overloading flags. */ tree build_op_new_call (code, type, args, flags) enum tree_code code; tree type, args; int flags; { tree fnname = ansi_opname[code]; if (IS_AGGR_TYPE (type) && ! (flags & LOOKUP_GLOBAL) && (TYPE_GETS_NEW (type) & (1 << (code == VEC_NEW_EXPR)))) { return build_method_call (build_dummy_object (type), fnname, args, NULL_TREE, flags); } else return build_new_function_call (lookup_function_nonclass (fnname, args), args); } /* Build a call to operator delete. This has to be handled very specially, because the restrictions on what signatures match are different from all other call instances. For a normal delete, only a delete taking (void *) or (void *, size_t) is accepted. For a placement delete, only an exact match with the placement new is accepted. CODE is either DELETE_EXPR or VEC_DELETE_EXPR. ADDR is the pointer to be deleted. For placement delete, it is also used to determine what the corresponding new looked like. SIZE is the size of the memory block to be deleted. FLAGS are the usual overloading flags. PLACEMENT is the corresponding placement new call, or 0. */ tree build_op_delete_call (code, addr, size, flags, placement) enum tree_code code; tree addr, size, placement; int flags; { tree fn, fns, fnname, fntype, argtypes, args, type; if (addr == error_mark_node) return error_mark_node; type = TREE_TYPE (TREE_TYPE (addr)); fnname = ansi_opname[code]; if (IS_AGGR_TYPE (type) && ! (flags & LOOKUP_GLOBAL)) /* In [class.free] If the result of the lookup is ambiguous or inaccessible, or if the lookup selects a placement deallocation function, the program is ill-formed. Therefore, we ask lookup_fnfields to complain ambout ambiguity. */ { fns = lookup_fnfields (TYPE_BINFO (type), fnname, 1); if (fns == error_mark_node) return error_mark_node; } else fns = NULL_TREE; if (fns == NULL_TREE) fns = lookup_name_nonclass (fnname); if (placement) { /* placement is a CALL_EXPR around an ADDR_EXPR around a function. */ /* Extract the function. */ argtypes = TREE_OPERAND (TREE_OPERAND (placement, 0), 0); /* Then the second parm type. */ argtypes = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (argtypes))); /* Also the second argument. */ args = TREE_CHAIN (TREE_OPERAND (placement, 1)); } else { /* First try it without the size argument. */ argtypes = void_list_node; args = NULL_TREE; } argtypes = tree_cons (NULL_TREE, ptr_type_node, argtypes); fntype = build_function_type (void_type_node, argtypes); /* Strip const and volatile from addr. */ if (type != TYPE_MAIN_VARIANT (type)) addr = cp_convert (build_pointer_type (TYPE_MAIN_VARIANT (type)), addr); fn = instantiate_type (fntype, fns, 2); if (fn != error_mark_node) { if (TREE_CODE (fns) == TREE_LIST) /* Member functions. */ enforce_access (TREE_PURPOSE (fns), fn); return build_function_call (fn, expr_tree_cons (NULL_TREE, addr, args)); } /* If we are doing placement delete we do nothing if we don't find a matching op delete. */ if (placement) return NULL_TREE; /* Normal delete; now try to find a match including the size argument. */ argtypes = tree_cons (NULL_TREE, ptr_type_node, tree_cons (NULL_TREE, sizetype, void_list_node)); fntype = build_function_type (void_type_node, argtypes); fn = instantiate_type (fntype, fns, 2); if (fn != error_mark_node) { if (BASELINK_P (fns)) /* Member functions. */ enforce_access (TREE_PURPOSE (fns), fn); return build_function_call (fn, expr_tree_cons (NULL_TREE, addr, build_expr_list (NULL_TREE, size))); } /* finish_function passes LOOKUP_SPECULATIVELY if we're in a destructor, in which case the error should be deferred until someone actually tries to delete one of these. */ if (flags & LOOKUP_SPECULATIVELY) return NULL_TREE; cp_error ("no suitable operator delete for `%T'", type); return error_mark_node; } /* If the current scope isn't allowed to access DECL along BASETYPE_PATH, give an error. The most derived class in BASETYPE_PATH is the one used to qualify DECL. */ int enforce_access (basetype_path, decl) tree basetype_path; tree decl; { int accessible; accessible = accessible_p (basetype_path, decl); if (!accessible) { if (TREE_PRIVATE (decl)) cp_error_at ("`%+#D' is private", decl); else if (TREE_PROTECTED (decl)) cp_error_at ("`%+#D' is protected", decl); else cp_error_at ("`%+#D' is inaccessible", decl); cp_error ("within this context"); return 0; } return 1; } /* Perform the conversions in CONVS on the expression EXPR. */ static tree convert_like (convs, expr) tree convs, expr; { if (ICS_BAD_FLAG (convs) && TREE_CODE (convs) != USER_CONV && TREE_CODE (convs) != AMBIG_CONV) { tree t = convs; for (; t; t = TREE_OPERAND (t, 0)) { if (TREE_CODE (t) == USER_CONV) { expr = convert_like (t, expr); break; } else if (TREE_CODE (t) == AMBIG_CONV) return convert_like (t, expr); else if (TREE_CODE (t) == IDENTITY_CONV) break; } return convert_for_initialization (NULL_TREE, TREE_TYPE (convs), expr, LOOKUP_NORMAL, "conversion", NULL_TREE, 0); } switch (TREE_CODE (convs)) { case USER_CONV: { struct z_candidate *cand = WRAPPER_PTR (TREE_OPERAND (convs, 1)); tree fn = cand->fn; tree args; + int flags = LOOKUP_NORMAL; if (DECL_CONSTRUCTOR_P (fn)) { tree t = build_int_2 (0, 0); TREE_TYPE (t) = build_pointer_type (DECL_CONTEXT (fn)); args = build_scratch_list (NULL_TREE, expr); + if (TYPE_USES_PVBASES (DECL_CONTEXT (fn)) + && !flag_vtable_thunks_compat) + { + args = scratch_tree_cons (NULL_TREE, vlist_zero_node, args); + flags != LOOKUP_HAS_VLIST; + } if (TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (fn))) args = scratch_tree_cons (NULL_TREE, integer_one_node, args); args = scratch_tree_cons (NULL_TREE, t, args); } else args = build_this (expr); - expr = build_over_call (cand, args, LOOKUP_NORMAL); + expr = build_over_call (cand, args, flags); /* If this is a constructor or a function returning an aggr type, we need to build up a TARGET_EXPR. */ if (DECL_CONSTRUCTOR_P (fn)) expr = build_cplus_new (TREE_TYPE (convs), expr); return expr; } case IDENTITY_CONV: if (type_unknown_p (expr)) expr = instantiate_type (TREE_TYPE (convs), expr, 1); if (TREE_READONLY_DECL_P (expr)) expr = decl_constant_value (expr); return expr; case AMBIG_CONV: /* Call build_user_type_conversion again for the error. */ return build_user_type_conversion (TREE_TYPE (convs), TREE_OPERAND (convs, 0), LOOKUP_NORMAL); default: break; }; expr = convert_like (TREE_OPERAND (convs, 0), expr); if (expr == error_mark_node) return error_mark_node; switch (TREE_CODE (convs)) { case RVALUE_CONV: if (! IS_AGGR_TYPE (TREE_TYPE (convs))) return expr; /* else fall through */ case BASE_CONV: { tree cvt_expr = build_user_type_conversion (TREE_TYPE (convs), expr, LOOKUP_NORMAL); if (!cvt_expr) { /* This can occur if, for example, the EXPR has incomplete type. We can't check for that before attempting the conversion because the type might be an incomplete array type, which is OK if some constructor for the destination type takes a pointer argument. */ if (TYPE_SIZE (TREE_TYPE (expr)) == 0) { if (same_type_p (TREE_TYPE (expr), TREE_TYPE (convs))) incomplete_type_error (expr, TREE_TYPE (expr)); else cp_error ("could not convert `%E' (with incomplete type `%T') to `%T'", expr, TREE_TYPE (expr), TREE_TYPE (convs)); } else cp_error ("could not convert `%E' to `%T'", expr, TREE_TYPE (convs)); return error_mark_node; } return cvt_expr; } case REF_BIND: return convert_to_reference (TREE_TYPE (convs), expr, CONV_IMPLICIT, LOOKUP_NORMAL|LOOKUP_NO_CONVERSION, error_mark_node); case LVALUE_CONV: return decay_conversion (expr); case QUAL_CONV: /* Warn about deprecated conversion if appropriate. */ string_conv_p (TREE_TYPE (convs), expr, 1); break; default: break; } return ocp_convert (TREE_TYPE (convs), expr, CONV_IMPLICIT, LOOKUP_NORMAL|LOOKUP_NO_CONVERSION); } /* ARG is being passed to a varargs function. Perform any conversions required. Return the converted value. */ tree convert_arg_to_ellipsis (arg) tree arg; { if (TREE_CODE (TREE_TYPE (arg)) == REAL_TYPE && (TYPE_PRECISION (TREE_TYPE (arg)) < TYPE_PRECISION (double_type_node))) /* Convert `float' to `double'. */ arg = cp_convert (double_type_node, arg); else if (IS_AGGR_TYPE (TREE_TYPE (arg)) && ! TYPE_HAS_TRIVIAL_INIT_REF (TREE_TYPE (arg))) cp_warning ("cannot pass objects of type `%T' through `...'", TREE_TYPE (arg)); else /* Convert `short' and `char' to full-size `int'. */ arg = default_conversion (arg); arg = require_complete_type (arg); return arg; } /* ARG is a default argument expression being passed to a parameter of the indicated TYPE, which is a parameter to FN. Do any required conversions. Return the converted value. */ tree convert_default_arg (type, arg, fn) tree type; tree arg; tree fn; { if (fn && DECL_TEMPLATE_INFO (fn)) { /* This default argument came from a template. Instantiate the default argument here, not in tsubst. In the case of something like: template struct S { static T t(); void f(T = t()); }; we must be careful to do name lookup in the scope of S, rather than in the current class. */ if (DECL_CLASS_SCOPE_P (fn)) pushclass (DECL_REAL_CONTEXT (fn), 2); arg = tsubst_expr (arg, DECL_TI_ARGS (fn), /*complain=*/1, NULL_TREE); if (DECL_CLASS_SCOPE_P (fn)) popclass (); /* Make sure the default argument is reasonable. */ arg = check_default_argument (type, arg); } arg = break_out_target_exprs (arg); if (TREE_CODE (arg) == CONSTRUCTOR) { arg = digest_init (type, arg, 0); arg = convert_for_initialization (0, type, arg, LOOKUP_NORMAL, "default argument", 0, 0); } else { /* This could get clobbered by the following call. */ if (TREE_HAS_CONSTRUCTOR (arg)) arg = copy_node (arg); arg = convert_for_initialization (0, type, arg, LOOKUP_NORMAL, "default argument", 0, 0); #ifdef PROMOTE_PROTOTYPES if ((TREE_CODE (type) == INTEGER_TYPE || TREE_CODE (type) == ENUMERAL_TYPE) && (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))) arg = default_conversion (arg); #endif } return arg; } static tree build_over_call (cand, args, flags) struct z_candidate *cand; tree args; int flags; { tree fn = cand->fn; tree convs = cand->convs; tree converted_args = NULL_TREE; tree parm = TYPE_ARG_TYPES (TREE_TYPE (fn)); tree conv, arg, val; int i = 0; int is_method = 0; /* Give any warnings we noticed during overload resolution. */ if (cand->warnings) for (val = cand->warnings; val; val = TREE_CHAIN (val)) joust (cand, WRAPPER_PTR (TREE_VALUE (val)), 1); if (DECL_FUNCTION_MEMBER_P (fn)) enforce_access (cand->basetype_path, fn); if (args && TREE_CODE (args) != TREE_LIST) args = build_scratch_list (NULL_TREE, args); arg = args; /* The implicit parameters to a constructor are not considered by overload resolution, and must be of the proper type. */ if (DECL_CONSTRUCTOR_P (fn)) { converted_args = expr_tree_cons (NULL_TREE, TREE_VALUE (arg), converted_args); arg = TREE_CHAIN (arg); parm = TREE_CHAIN (parm); if (TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (fn))) { converted_args = expr_tree_cons (NULL_TREE, TREE_VALUE (arg), converted_args); arg = TREE_CHAIN (arg); parm = TREE_CHAIN (parm); } + if (flags & LOOKUP_HAS_VLIST) + { + converted_args = expr_tree_cons + (NULL_TREE, TREE_VALUE (arg), converted_args); + arg = TREE_CHAIN (arg); + parm = TREE_CHAIN (parm); + } } /* Bypass access control for 'this' parameter. */ else if (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE) { tree parmtype = TREE_VALUE (parm); tree argtype = TREE_TYPE (TREE_VALUE (arg)); tree t; if (ICS_BAD_FLAG (TREE_VEC_ELT (convs, i))) cp_pedwarn ("passing `%T' as `this' argument of `%#D' discards qualifiers", TREE_TYPE (argtype), fn); /* [class.mfct.nonstatic]: If a nonstatic member function of a class X is called for an object that is not of type X, or of a type derived from X, the behavior is undefined. So we can assume that anything passed as 'this' is non-null, and optimize accordingly. */ if (TREE_CODE (parmtype) == POINTER_TYPE) t = convert_pointer_to_real (TREE_TYPE (parmtype), TREE_VALUE (arg)); else /* This happens with signatures. */ t = convert_force (parmtype, TREE_VALUE (arg), CONV_C_CAST); converted_args = expr_tree_cons (NULL_TREE, t, converted_args); parm = TREE_CHAIN (parm); arg = TREE_CHAIN (arg); ++i; is_method = 1; } for (; arg && parm; parm = TREE_CHAIN (parm), arg = TREE_CHAIN (arg), ++i) { tree type = TREE_VALUE (parm); conv = TREE_VEC_ELT (convs, i); if (ICS_BAD_FLAG (conv)) { tree t = conv; val = TREE_VALUE (arg); for (; t; t = TREE_OPERAND (t, 0)) { if (TREE_CODE (t) == USER_CONV || TREE_CODE (t) == AMBIG_CONV) { val = convert_like (t, val); break; } else if (TREE_CODE (t) == IDENTITY_CONV) break; } val = convert_for_initialization (NULL_TREE, type, val, LOOKUP_NORMAL, "argument passing", fn, i - is_method); } else { /* Issue warnings about peculiar, but legal, uses of NULL. */ if (ARITHMETIC_TYPE_P (TREE_VALUE (parm)) && TREE_VALUE (arg) == null_node) cp_warning ("converting NULL to non-pointer type"); val = convert_like (conv, TREE_VALUE (arg)); } #ifdef PROMOTE_PROTOTYPES if ((TREE_CODE (type) == INTEGER_TYPE || TREE_CODE (type) == ENUMERAL_TYPE) && (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))) val = default_conversion (val); #endif converted_args = expr_tree_cons (NULL_TREE, val, converted_args); } /* Default arguments */ for (; parm && parm != void_list_node; parm = TREE_CHAIN (parm)) converted_args = expr_tree_cons (NULL_TREE, convert_default_arg (TREE_VALUE (parm), TREE_PURPOSE (parm), fn), converted_args); /* Ellipsis */ for (; arg; arg = TREE_CHAIN (arg)) converted_args = expr_tree_cons (NULL_TREE, convert_arg_to_ellipsis (TREE_VALUE (arg)), converted_args); converted_args = nreverse (converted_args); if (warn_format && (DECL_NAME (fn) || DECL_ASSEMBLER_NAME (fn))) check_function_format (DECL_NAME (fn), DECL_ASSEMBLER_NAME (fn), converted_args); /* Avoid actually calling copy constructors and copy assignment operators, if possible. */ if (! flag_elide_constructors) /* Do things the hard way. */; else if (DECL_CONSTRUCTOR_P (fn) && TREE_VEC_LENGTH (convs) == 1 && copy_args_p (fn)) { tree targ; arg = TREE_CHAIN (converted_args); if (TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (fn))) arg = TREE_CHAIN (arg); + if (flags & LOOKUP_HAS_VLIST) + arg = TREE_CHAIN (arg); arg = TREE_VALUE (arg); /* Pull out the real argument, disregarding const-correctness. */ targ = arg; while (TREE_CODE (targ) == NOP_EXPR || TREE_CODE (targ) == NON_LVALUE_EXPR || TREE_CODE (targ) == CONVERT_EXPR) targ = TREE_OPERAND (targ, 0); if (TREE_CODE (targ) == ADDR_EXPR) { targ = TREE_OPERAND (targ, 0); if (!same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (arg))), TYPE_MAIN_VARIANT (TREE_TYPE (targ)))) targ = NULL_TREE; } else targ = NULL_TREE; if (targ) arg = targ; else arg = build_indirect_ref (arg, 0); /* [class.copy]: the copy constructor is implicitly defined even if the implementation elided its use. */ if (TYPE_HAS_COMPLEX_INIT_REF (DECL_CONTEXT (fn))) mark_used (fn); /* If we're creating a temp and we already have one, don't create a new one. If we're not creating a temp but we get one, use INIT_EXPR to collapse the temp into our target. Otherwise, if the ctor is trivial, do a bitwise copy with a simple TARGET_EXPR for a temp or an INIT_EXPR otherwise. */ if (integer_zerop (TREE_VALUE (args))) { if (! real_lvalue_p (arg)) return arg; else if (TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn))) { val = build_decl (VAR_DECL, NULL_TREE, DECL_CONTEXT (fn)); val = build (TARGET_EXPR, DECL_CONTEXT (fn), val, arg, 0, 0); TREE_SIDE_EFFECTS (val) = 1; return val; } } else if (! real_lvalue_p (arg) || TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn))) { tree address; tree to = stabilize_reference (build_indirect_ref (TREE_VALUE (args), 0)); /* If we're initializing an empty class, then we actually have to use a MODIFY_EXPR rather than an INIT_EXPR. The reason is that the dummy padding member in the target may not actually be allocated if TO is a base class subobject. Since we've set TYPE_NONCOPIED_PARTS on the padding, a MODIFY_EXPR will preserve its value, which is the right thing to do if it's not really padding at all. It's not safe to just throw away the ARG if we're looking at an empty class because the ARG might contain a TARGET_EXPR which wants to be bound to TO. If it is not, expand_expr will assign a dummy slot for the TARGET_EXPR, and we will call a destructor for it, which is wrong, because we will also destroy TO, but will never have constructed it. */ val = build (is_empty_class (DECL_CLASS_CONTEXT (fn)) ? MODIFY_EXPR : INIT_EXPR, DECL_CONTEXT (fn), to, arg); TREE_SIDE_EFFECTS (val) = 1; address = build_unary_op (ADDR_EXPR, val, 0); /* Avoid a warning about this expression, if the address is never used. */ TREE_USED (address) = 1; return address; } } else if (DECL_NAME (fn) == ansi_opname[MODIFY_EXPR] && copy_args_p (fn) && TYPE_HAS_TRIVIAL_ASSIGN_REF (DECL_CLASS_CONTEXT (fn))) { tree to = stabilize_reference (build_indirect_ref (TREE_VALUE (converted_args), 0)); arg = build_indirect_ref (TREE_VALUE (TREE_CHAIN (converted_args)), 0); val = build (MODIFY_EXPR, TREE_TYPE (to), to, arg); TREE_SIDE_EFFECTS (val) = 1; return val; } mark_used (fn); if (DECL_CLASS_SCOPE_P (fn) && IS_SIGNATURE (DECL_CONTEXT (fn))) return build_signature_method_call (fn, converted_args); else if (DECL_VINDEX (fn) && (flags & LOOKUP_NONVIRTUAL) == 0) { tree t, *p = &TREE_VALUE (converted_args); tree binfo = get_binfo (DECL_CONTEXT (fn), TREE_TYPE (TREE_TYPE (*p)), 0); *p = convert_pointer_to_real (binfo, *p); if (TREE_SIDE_EFFECTS (*p)) *p = save_expr (*p); t = build_pointer_type (TREE_TYPE (fn)); fn = build_vfn_ref (p, build_indirect_ref (*p, 0), DECL_VINDEX (fn)); TREE_TYPE (fn) = t; } else if (DECL_INLINE (fn)) fn = inline_conversion (fn); else fn = build_addr_func (fn); /* Recognize certain built-in functions so we can make tree-codes other than CALL_EXPR. We do this when it enables fold-const.c to do something useful. */ if (TREE_CODE (fn) == ADDR_EXPR && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL && DECL_BUILT_IN (TREE_OPERAND (fn, 0))) switch (DECL_FUNCTION_CODE (TREE_OPERAND (fn, 0))) { case BUILT_IN_ABS: case BUILT_IN_LABS: case BUILT_IN_FABS: if (converted_args == 0) return integer_zero_node; return build_unary_op (ABS_EXPR, TREE_VALUE (converted_args), 0); default: break; } fn = build_call (fn, TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))), converted_args); if (TREE_CODE (TREE_TYPE (fn)) == VOID_TYPE) return fn; fn = require_complete_type (fn); if (IS_AGGR_TYPE (TREE_TYPE (fn))) fn = build_cplus_new (TREE_TYPE (fn), fn); return convert_from_reference (fn); } static tree build_new_method_call (instance, name, args, basetype_path, flags) tree instance, name, args, basetype_path; int flags; { struct z_candidate *candidates = 0, *cand; tree explicit_targs = NULL_TREE; tree basetype, mem_args = NULL_TREE, fns, instance_ptr; tree pretty_name; tree user_args = args; tree templates = NULL_TREE; int template_only = 0; if (TREE_CODE (name) == TEMPLATE_ID_EXPR) { explicit_targs = TREE_OPERAND (name, 1); name = TREE_OPERAND (name, 0); if (TREE_CODE_CLASS (TREE_CODE (name)) == 'd') name = DECL_NAME (name); else { if (TREE_CODE (name) == COMPONENT_REF) name = TREE_OPERAND (name, 1); if (TREE_CODE (name) == OVERLOAD) name = DECL_NAME (OVL_CURRENT (name)); } template_only = 1; } /* If there is an extra argument for controlling virtual bases, remove it for error reporting. */ if (flags & LOOKUP_HAS_IN_CHARGE) user_args = TREE_CHAIN (args); + if (flags & LOOKUP_HAS_VLIST) + user_args = TREE_CHAIN (user_args); args = resolve_args (args); if (args == error_mark_node) return error_mark_node; if (instance == NULL_TREE) basetype = BINFO_TYPE (basetype_path); else { if (TREE_CODE (instance) == OFFSET_REF) instance = resolve_offset_ref (instance); if (TREE_CODE (TREE_TYPE (instance)) == REFERENCE_TYPE) instance = convert_from_reference (instance); basetype = TYPE_MAIN_VARIANT (TREE_TYPE (instance)); /* XXX this should be handled before we get here. */ if (! IS_AGGR_TYPE (basetype) && ! (TYPE_LANG_SPECIFIC (basetype) && (IS_SIGNATURE_POINTER (basetype) || IS_SIGNATURE_REFERENCE (basetype)))) { if ((flags & LOOKUP_COMPLAIN) && basetype != error_mark_node) cp_error ("request for member `%D' in `%E', which is of non-aggregate type `%T'", name, instance, basetype); return error_mark_node; } /* If `instance' is a signature pointer/reference and `name' is not a constructor, we are calling a signature member function. In that case set the `basetype' to the signature type. */ if ((IS_SIGNATURE_POINTER (basetype) || IS_SIGNATURE_REFERENCE (basetype)) && TYPE_IDENTIFIER (basetype) != name) basetype = SIGNATURE_TYPE (basetype); } if (basetype_path == NULL_TREE) basetype_path = TYPE_BINFO (basetype); if (instance) { instance_ptr = build_this (instance); if (! template_only) { /* XXX this should be handled before we get here. */ fns = build_field_call (basetype_path, instance_ptr, name, args); if (fns) return fns; } } else { instance_ptr = build_int_2 (0, 0); TREE_TYPE (instance_ptr) = build_pointer_type (basetype); } pretty_name = (name == ctor_identifier ? constructor_name (basetype) : name); fns = lookup_fnfields (basetype_path, name, 1); if (fns == error_mark_node) return error_mark_node; if (fns) { tree fn = TREE_VALUE (fns); if (name == ctor_identifier && TYPE_USES_VIRTUAL_BASECLASSES (basetype) && ! (flags & LOOKUP_HAS_IN_CHARGE)) { + if (TYPE_USES_PVBASES(basetype) + && (!flag_vtable_thunks_compat || (name == dtor_identifier))) + { + args = scratch_tree_cons (NULL_TREE, vlist_zero_node, args); + flags |= LOOKUP_HAS_VLIST; + } flags |= LOOKUP_HAS_IN_CHARGE; args = scratch_tree_cons (NULL_TREE, integer_one_node, args); } mem_args = scratch_tree_cons (NULL_TREE, instance_ptr, args); for (; fn; fn = OVL_NEXT (fn)) { tree t = OVL_CURRENT (fn); tree this_arglist; /* We can end up here for copy-init of same or base class. */ if (name == ctor_identifier && (flags & LOOKUP_ONLYCONVERTING) && DECL_NONCONVERTING_P (t)) continue; if (TREE_CODE (TREE_TYPE (t)) == METHOD_TYPE) this_arglist = mem_args; else this_arglist = args; if (TREE_CODE (t) == TEMPLATE_DECL) { /* A member template. */ templates = scratch_tree_cons (NULL_TREE, t, templates); candidates = add_template_candidate (candidates, t, explicit_targs, this_arglist, TREE_TYPE (name), flags, DEDUCE_CALL); } else if (! template_only) candidates = add_function_candidate (candidates, t, this_arglist, flags); if (candidates) candidates->basetype_path = TREE_PURPOSE (fns); } } if (! any_viable (candidates)) { /* XXX will LOOKUP_SPECULATIVELY be needed when this is done? */ if (flags & LOOKUP_SPECULATIVELY) return NULL_TREE; if (TYPE_SIZE (basetype) == 0) incomplete_type_error (instance_ptr, basetype); else cp_error ("no matching function for call to `%T::%D (%A)%V'", basetype, pretty_name, user_args, TREE_TYPE (TREE_TYPE (instance_ptr))); print_z_candidates (candidates); return error_mark_node; } candidates = splice_viable (candidates); cand = tourney (candidates); if (cand == 0) { cp_error ("call of overloaded `%D(%A)' is ambiguous", pretty_name, user_args); print_z_candidates (candidates); return error_mark_node; } if (DECL_ABSTRACT_VIRTUAL_P (cand->fn) && instance == current_class_ref && DECL_CONSTRUCTOR_P (current_function_decl) && ! (flags & LOOKUP_NONVIRTUAL) && value_member (cand->fn, CLASSTYPE_ABSTRACT_VIRTUALS (basetype))) cp_error ("abstract virtual `%#D' called from constructor", cand->fn); if (TREE_CODE (TREE_TYPE (cand->fn)) == METHOD_TYPE && is_dummy_object (instance_ptr)) { cp_error ("cannot call member function `%D' without object", cand->fn); return error_mark_node; } if (DECL_VINDEX (cand->fn) && ! (flags & LOOKUP_NONVIRTUAL) && ((instance == current_class_ref && (dtor_label || ctor_label)) || resolves_to_fixed_type_p (instance, 0))) flags |= LOOKUP_NONVIRTUAL; /* Pedantically, normal function declarations are never considered to refer to template instantiations, so we only do this with -fguiding-decls. */ if (flag_guiding_decls && templates && ! cand->template && ! DECL_INITIAL (cand->fn)) add_maybe_template (cand->fn, templates); return build_over_call (cand, TREE_CODE (TREE_TYPE (cand->fn)) == METHOD_TYPE ? mem_args : args, flags); } /* Returns non-zero iff standard conversion sequence ICS1 is a proper subsequence of ICS2. */ static int is_subseq (ics1, ics2) tree ics1, ics2; { /* We can assume that a conversion of the same code between the same types indicates a subsequence since we only get here if the types we are converting from are the same. */ while (TREE_CODE (ics1) == RVALUE_CONV || TREE_CODE (ics1) == LVALUE_CONV) ics1 = TREE_OPERAND (ics1, 0); while (1) { while (TREE_CODE (ics2) == RVALUE_CONV || TREE_CODE (ics2) == LVALUE_CONV) ics2 = TREE_OPERAND (ics2, 0); if (TREE_CODE (ics2) == USER_CONV || TREE_CODE (ics2) == AMBIG_CONV || TREE_CODE (ics2) == IDENTITY_CONV) /* At this point, ICS1 cannot be a proper subsequence of ICS2. We can get a USER_CONV when we are comparing the second standard conversion sequence of two user conversion sequences. */ return 0; ics2 = TREE_OPERAND (ics2, 0); if (TREE_CODE (ics2) == TREE_CODE (ics1) && same_type_p (TREE_TYPE (ics2), TREE_TYPE (ics1)) && same_type_p (TREE_TYPE (TREE_OPERAND (ics2, 0)), TREE_TYPE (TREE_OPERAND (ics1, 0)))) return 1; } } /* Returns non-zero iff DERIVED is derived from BASE. The inputs may be any _TYPE nodes. */ int is_properly_derived_from (derived, base) tree derived; tree base; { if (!IS_AGGR_TYPE_CODE (TREE_CODE (derived)) || !IS_AGGR_TYPE_CODE (TREE_CODE (base))) return 0; /* We only allow proper derivation here. The DERIVED_FROM_P macro considers every class derived from itself. */ return (!same_type_p (TYPE_MAIN_VARIANT (derived), TYPE_MAIN_VARIANT (base)) && DERIVED_FROM_P (base, derived)); } /* We build the ICS for an implicit object parameter as a pointer conversion sequence. However, such a sequence should be compared as if it were a reference conversion sequence. If ICS is the implicit conversion sequence for an implicit object parameter, modify it accordingly. */ static void maybe_handle_implicit_object (ics) tree* ics; { if (ICS_THIS_FLAG (*ics)) { /* [over.match.funcs] For non-static member functions, the type of the implicit object parameter is "reference to cv X" where X is the class of which the function is a member and cv is the cv-qualification on the member function declaration. */ tree t = *ics; if (TREE_CODE (t) == QUAL_CONV) t = TREE_OPERAND (t, 0); if (TREE_CODE (t) == PTR_CONV) t = TREE_OPERAND (t, 0); t = build1 (IDENTITY_CONV, TREE_TYPE (TREE_TYPE (t)), NULL_TREE); t = build_conv (REF_BIND, build_reference_type (TREE_TYPE (TREE_TYPE (*ics))), t); ICS_STD_RANK (t) = ICS_STD_RANK (*ics); *ics = t; } } /* If ICS is a REF_BIND, modify it appropriately, set TARGET_TYPE to the type the reference originally referred to, and return 1. Otherwise, return 0. */ static int maybe_handle_ref_bind (ics, target_type) tree* ics; tree* target_type; { if (TREE_CODE (*ics) == REF_BIND) { /* [over.ics.rank] When a parameter of reference type binds directly (_dcl.init.ref_) to an argument expression, the implicit conversion sequence is the identity conversion, unless the argument expression has a type that is a derived class of the parameter type, in which case the implicit conversion sequence is a derived-to-base Conversion. If the parameter binds directly to the result of applying a conversion function to the argument expression, the implicit conversion sequence is a user-defined conversion sequence (_over.ics.user_), with the second standard conversion sequence either an identity conversion or, if the conversion function returns an entity of a type that is a derived class of the parameter type, a derived-to-base Conversion. When a parameter of reference type is not bound directly to an argument expression, the conversion sequence is the one required to convert the argument expression to the underlying type of the reference according to _over.best.ics_. Conceptually, this conversion sequence corresponds to copy-initializing a temporary of the underlying type with the argument expression. Any difference in top-level cv-qualification is subsumed by the initialization itself and does not constitute a conversion. */ tree old_ics = *ics; *target_type = TREE_TYPE (TREE_TYPE (*ics)); *ics = TREE_OPERAND (*ics, 0); if (TREE_CODE (*ics) == IDENTITY_CONV && is_properly_derived_from (TREE_TYPE (*ics), *target_type)) *ics = build_conv (BASE_CONV, *target_type, *ics); ICS_USER_FLAG (*ics) = ICS_USER_FLAG (old_ics); ICS_BAD_FLAG (*ics) = ICS_BAD_FLAG (old_ics); return 1; } return 0; } /* Compare two implicit conversion sequences according to the rules set out in [over.ics.rank]. Return values: 1: ics1 is better than ics2 -1: ics2 is better than ics1 0: ics1 and ics2 are indistinguishable */ static int compare_ics (ics1, ics2) tree ics1, ics2; { tree from_type1; tree from_type2; tree to_type1; tree to_type2; tree deref_from_type1 = NULL_TREE; tree deref_from_type2 = NULL_TREE; tree deref_to_type1 = NULL_TREE; tree deref_to_type2 = NULL_TREE; /* REF_BINDING is non-zero if the result of the conversion sequence is a reference type. In that case TARGET_TYPE is the type referred to by the reference. */ int ref_binding1; int ref_binding2; tree target_type1; tree target_type2; /* Handle implicit object parameters. */ maybe_handle_implicit_object (&ics1); maybe_handle_implicit_object (&ics2); /* Handle reference parameters. */ ref_binding1 = maybe_handle_ref_bind (&ics1, &target_type1); ref_binding2 = maybe_handle_ref_bind (&ics2, &target_type2); /* [over.ics.rank] When comparing the basic forms of implicit conversion sequences (as defined in _over.best.ics_) --a standard conversion sequence (_over.ics.scs_) is a better conversion sequence than a user-defined conversion sequence or an ellipsis conversion sequence, and --a user-defined conversion sequence (_over.ics.user_) is a better conversion sequence than an ellipsis conversion sequence (_over.ics.ellipsis_). */ if (ICS_RANK (ics1) > ICS_RANK (ics2)) return -1; else if (ICS_RANK (ics1) < ICS_RANK (ics2)) return 1; if (ICS_RANK (ics1) == BAD_RANK) { /* Both ICS are bad. We try to make a decision based on what would have happenned if they'd been good. */ if (ICS_USER_FLAG (ics1) > ICS_USER_FLAG (ics2) || ICS_STD_RANK (ics1) > ICS_STD_RANK (ics2)) return -1; else if (ICS_USER_FLAG (ics1) < ICS_USER_FLAG (ics2) || ICS_STD_RANK (ics1) < ICS_STD_RANK (ics2)) return 1; /* We couldn't make up our minds; try to figure it out below. */ } if (ICS_ELLIPSIS_FLAG (ics1)) /* Both conversions are ellipsis conversions. */ return 0; /* User-defined conversion sequence U1 is a better conversion sequence than another user-defined conversion sequence U2 if they contain the same user-defined conversion operator or constructor and if the sec- ond standard conversion sequence of U1 is better than the second standard conversion sequence of U2. */ if (ICS_USER_FLAG (ics1)) { tree t1, t2; for (t1 = ics1; TREE_CODE (t1) != USER_CONV; t1 = TREE_OPERAND (t1, 0)) if (TREE_CODE (t1) == AMBIG_CONV) return 0; for (t2 = ics2; TREE_CODE (t2) != USER_CONV; t2 = TREE_OPERAND (t2, 0)) if (TREE_CODE (t2) == AMBIG_CONV) return 0; if (USER_CONV_FN (t1) != USER_CONV_FN (t2)) return 0; /* We can just fall through here, after setting up FROM_TYPE1 and FROM_TYPE2. */ from_type1 = TREE_TYPE (t1); from_type2 = TREE_TYPE (t2); } else { /* We're dealing with two standard conversion sequences. [over.ics.rank] Standard conversion sequence S1 is a better conversion sequence than standard conversion sequence S2 if --S1 is a proper subsequence of S2 (comparing the conversion sequences in the canonical form defined by _over.ics.scs_, excluding any Lvalue Transformation; the identity conversion sequence is considered to be a subsequence of any non-identity conversion sequence */ from_type1 = ics1; while (TREE_CODE (from_type1) != IDENTITY_CONV) from_type1 = TREE_OPERAND (from_type1, 0); from_type1 = TREE_TYPE (from_type1); from_type2 = ics2; while (TREE_CODE (from_type2) != IDENTITY_CONV) from_type2 = TREE_OPERAND (from_type2, 0); from_type2 = TREE_TYPE (from_type2); } if (same_type_p (from_type1, from_type2)) { if (is_subseq (ics1, ics2)) return 1; if (is_subseq (ics2, ics1)) return -1; } /* Otherwise, one sequence cannot be a subsequence of the other; they don't start with the same type. This can happen when comparing the second standard conversion sequence in two user-defined conversion sequences. */ /* [over.ics.rank] Or, if not that, --the rank of S1 is better than the rank of S2 (by the rules defined below): Standard conversion sequences are ordered by their ranks: an Exact Match is a better conversion than a Promotion, which is a better conversion than a Conversion. Two conversion sequences with the same rank are indistinguishable unless one of the following rules applies: --A conversion that is not a conversion of a pointer, or pointer to member, to bool is better than another conversion that is such a conversion. The ICS_STD_RANK automatically handles the pointer-to-bool rule, so that we do not have to check it explicitly. */ if (ICS_STD_RANK (ics1) < ICS_STD_RANK (ics2)) return 1; else if (ICS_STD_RANK (ics2) < ICS_STD_RANK (ics1)) return -1; to_type1 = TREE_TYPE (ics1); to_type2 = TREE_TYPE (ics2); if (TYPE_PTR_P (from_type1) && TYPE_PTR_P (from_type2) && TYPE_PTR_P (to_type1) && TYPE_PTR_P (to_type2)) { deref_from_type1 = TREE_TYPE (from_type1); deref_from_type2 = TREE_TYPE (from_type2); deref_to_type1 = TREE_TYPE (to_type1); deref_to_type2 = TREE_TYPE (to_type2); } /* The rules for pointers to members A::* are just like the rules for pointers A*, except opposite: if B is derived from A then A::* converts to B::*, not vice versa. For that reason, we switch the from_ and to_ variables here. */ else if (TYPE_PTRMEM_P (from_type1) && TYPE_PTRMEM_P (from_type2) && TYPE_PTRMEM_P (to_type1) && TYPE_PTRMEM_P (to_type2)) { deref_to_type1 = TYPE_OFFSET_BASETYPE (TREE_TYPE (from_type1)); deref_to_type2 = TYPE_OFFSET_BASETYPE (TREE_TYPE (from_type2)); deref_from_type1 = TYPE_OFFSET_BASETYPE (TREE_TYPE (to_type1)); deref_from_type2 = TYPE_OFFSET_BASETYPE (TREE_TYPE (to_type2)); } else if (TYPE_PTRMEMFUNC_P (from_type1) && TYPE_PTRMEMFUNC_P (from_type2) && TYPE_PTRMEMFUNC_P (to_type1) && TYPE_PTRMEMFUNC_P (to_type2)) { deref_to_type1 = TYPE_PTRMEMFUNC_OBJECT_TYPE (from_type1); deref_to_type2 = TYPE_PTRMEMFUNC_OBJECT_TYPE (from_type2); deref_from_type1 = TYPE_PTRMEMFUNC_OBJECT_TYPE (to_type1); deref_from_type2 = TYPE_PTRMEMFUNC_OBJECT_TYPE (to_type2); } if (deref_from_type1 != NULL_TREE && IS_AGGR_TYPE_CODE (TREE_CODE (deref_from_type1)) && IS_AGGR_TYPE_CODE (TREE_CODE (deref_from_type2))) { /* This was one of the pointer or pointer-like conversions. [over.ics.rank] --If class B is derived directly or indirectly from class A, conversion of B* to A* is better than conversion of B* to void*, and conversion of A* to void* is better than conversion of B* to void*. */ if (TREE_CODE (deref_to_type1) == VOID_TYPE && TREE_CODE (deref_to_type2) == VOID_TYPE) { if (is_properly_derived_from (deref_from_type1, deref_from_type2)) return -1; else if (is_properly_derived_from (deref_from_type2, deref_from_type1)) return 1; } else if (TREE_CODE (deref_to_type1) == VOID_TYPE || TREE_CODE (deref_to_type2) == VOID_TYPE) { if (same_type_p (deref_from_type1, deref_from_type2)) { if (TREE_CODE (deref_to_type2) == VOID_TYPE) { if (is_properly_derived_from (deref_from_type1, deref_to_type1)) return 1; } /* We know that DEREF_TO_TYPE1 is `void' here. */ else if (is_properly_derived_from (deref_from_type1, deref_to_type2)) return -1; } } else if (IS_AGGR_TYPE_CODE (TREE_CODE (deref_to_type1)) && IS_AGGR_TYPE_CODE (TREE_CODE (deref_to_type2))) { /* [over.ics.rank] --If class B is derived directly or indirectly from class A and class C is derived directly or indirectly from B, --conversion of C* to B* is better than conversion of C* to A*, --conversion of B* to A* is better than conversion of C* to A* */ if (same_type_p (deref_from_type1, deref_from_type2)) { if (is_properly_derived_from (deref_to_type1, deref_to_type2)) return 1; else if (is_properly_derived_from (deref_to_type2, deref_to_type1)) return -1; } else if (same_type_p (deref_to_type1, deref_to_type2)) { if (is_properly_derived_from (deref_from_type2, deref_from_type1)) return 1; else if (is_properly_derived_from (deref_from_type1, deref_from_type2)) return -1; } } } else if (IS_AGGR_TYPE_CODE (TREE_CODE (from_type1)) && same_type_p (from_type1, from_type2)) { /* [over.ics.rank] --binding of an expression of type C to a reference of type B& is better than binding an expression of type C to a reference of type A& --conversion of C to B is better than conversion of C to A, */ if (is_properly_derived_from (from_type1, to_type1) && is_properly_derived_from (from_type1, to_type2)) { if (is_properly_derived_from (to_type1, to_type2)) return 1; else if (is_properly_derived_from (to_type2, to_type1)) return -1; } } else if (IS_AGGR_TYPE_CODE (TREE_CODE (to_type1)) && same_type_p (to_type1, to_type2)) { /* [over.ics.rank] --binding of an expression of type B to a reference of type A& is better than binding an expression of type C to a reference of type A&, --onversion of B to A is better than conversion of C to A */ if (is_properly_derived_from (from_type1, to_type1) && is_properly_derived_from (from_type2, to_type1)) { if (is_properly_derived_from (from_type2, from_type1)) return 1; else if (is_properly_derived_from (from_type1, from_type2)) return -1; } } /* [over.ics.rank] --S1 and S2 differ only in their qualification conversion and yield similar types T1 and T2 (_conv.qual_), respectively, and the cv- qualification signature of type T1 is a proper subset of the cv- qualification signature of type T2 */ if (TREE_CODE (ics1) == QUAL_CONV && TREE_CODE (ics2) == QUAL_CONV && same_type_p (from_type1, from_type2)) return comp_cv_qual_signature (to_type1, to_type2); /* [over.ics.rank] --S1 and S2 are reference bindings (_dcl.init.ref_), and the types to which the references refer are the same type except for top-level cv-qualifiers, and the type to which the reference initialized by S2 refers is more cv-qualified than the type to which the reference initialized by S1 refers */ if (ref_binding1 && ref_binding2 && same_type_p (TYPE_MAIN_VARIANT (to_type1), TYPE_MAIN_VARIANT (to_type2))) return comp_cv_qualification (target_type2, target_type1); /* Neither conversion sequence is better than the other. */ return 0; } /* The source type for this standard conversion sequence. */ static tree source_type (t) tree t; { for (;; t = TREE_OPERAND (t, 0)) { if (TREE_CODE (t) == USER_CONV || TREE_CODE (t) == AMBIG_CONV || TREE_CODE (t) == IDENTITY_CONV) return TREE_TYPE (t); } my_friendly_abort (1823); } /* Note a warning about preferring WINNER to LOSER. We do this by storing a pointer to LOSER and re-running joust to produce the warning if WINNER is actually used. */ static void add_warning (winner, loser) struct z_candidate *winner, *loser; { winner->warnings = expr_tree_cons (NULL_PTR, build_expr_ptr_wrapper (loser), winner->warnings); } /* Compare two candidates for overloading as described in [over.match.best]. Return values: 1: cand1 is better than cand2 -1: cand2 is better than cand1 0: cand1 and cand2 are indistinguishable */ static int joust (cand1, cand2, warn) struct z_candidate *cand1, *cand2; int warn; { int winner = 0; int i, off1 = 0, off2 = 0, len; /* Candidates that involve bad conversions are always worse than those that don't. */ if (cand1->viable > cand2->viable) return 1; if (cand1->viable < cand2->viable) return -1; /* If we have two pseudo-candidates for conversions to the same type, arbitrarily pick one. */ if (TYPE_P (cand1->fn) && cand1->fn == cand2->fn) return 1; /* a viable function F1 is defined to be a better function than another viable function F2 if for all arguments i, ICSi(F1) is not a worse conversion sequence than ICSi(F2), and then */ /* for some argument j, ICSj(F1) is a better conversion sequence than ICSj(F2) */ /* For comparing static and non-static member functions, we ignore the implicit object parameter of the non-static function. The WP says to pretend that the static function has an object parm, but that won't work with operator overloading. */ len = TREE_VEC_LENGTH (cand1->convs); if (len != TREE_VEC_LENGTH (cand2->convs)) { if (DECL_STATIC_FUNCTION_P (cand1->fn) && ! DECL_STATIC_FUNCTION_P (cand2->fn)) off2 = 1; else if (! DECL_STATIC_FUNCTION_P (cand1->fn) && DECL_STATIC_FUNCTION_P (cand2->fn)) { off1 = 1; --len; } else my_friendly_abort (42); } for (i = 0; i < len; ++i) { tree t1 = TREE_VEC_ELT (cand1->convs, i+off1); tree t2 = TREE_VEC_ELT (cand2->convs, i+off2); int comp = compare_ics (t1, t2); if (comp != 0) { if (warn_sign_promo && ICS_RANK (t1) + ICS_RANK (t2) == STD_RANK + PROMO_RANK && TREE_CODE (t1) == STD_CONV && TREE_CODE (t2) == STD_CONV && TREE_CODE (TREE_TYPE (t1)) == INTEGER_TYPE && TREE_CODE (TREE_TYPE (t2)) == INTEGER_TYPE && (TYPE_PRECISION (TREE_TYPE (t1)) == TYPE_PRECISION (TREE_TYPE (t2))) && (TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (t1, 0))) || (TREE_CODE (TREE_TYPE (TREE_OPERAND (t1, 0))) == ENUMERAL_TYPE))) { tree type = TREE_TYPE (TREE_OPERAND (t1, 0)); tree type1, type2; struct z_candidate *w, *l; if (comp > 0) type1 = TREE_TYPE (t1), type2 = TREE_TYPE (t2), w = cand1, l = cand2; else type1 = TREE_TYPE (t2), type2 = TREE_TYPE (t1), w = cand2, l = cand1; if (warn) { cp_warning ("passing `%T' chooses `%T' over `%T'", type, type1, type2); cp_warning (" in call to `%D'", w->fn); } else add_warning (w, l); } if (winner && comp != winner) { winner = 0; goto tweak; } winner = comp; } } /* warn about confusing overload resolution for user-defined conversions, either between a constructor and a conversion op, or between two conversion ops. */ if (winner && cand1->second_conv && ((DECL_CONSTRUCTOR_P (cand1->fn) != DECL_CONSTRUCTOR_P (cand2->fn)) /* Don't warn if the two conv ops convert to the same type... */ || (! DECL_CONSTRUCTOR_P (cand1->fn) && ! same_type_p (TREE_TYPE (TREE_TYPE (cand1->fn)), TREE_TYPE (TREE_TYPE (cand2->fn)))))) { int comp = compare_ics (cand1->second_conv, cand2->second_conv); if (comp != winner) { struct z_candidate *w, *l; if (winner == 1) w = cand1, l = cand2; else w = cand2, l = cand1; if (warn) { tree source = source_type (TREE_VEC_ELT (w->convs, 0)); if (! DECL_CONSTRUCTOR_P (w->fn)) source = TREE_TYPE (source); cp_warning ("choosing `%D' over `%D'", w->fn, l->fn); cp_warning (" for conversion from `%T' to `%T'", source, TREE_TYPE (w->second_conv)); cp_warning (" because conversion sequence for the argument is better"); } else add_warning (w, l); } } if (winner) return winner; /* or, if not that, F1 is a non-template function and F2 is a template function */ if (! cand1->template && cand2->template) return 1; else if (cand1->template && ! cand2->template) return -1; else if (cand1->template && cand2->template) winner = more_specialized (TI_TEMPLATE (cand1->template), TI_TEMPLATE (cand2->template), NULL_TREE); /* or, if not that, the context is an initialization by user-defined conversion (see _dcl.init_ and _over.match.user_) and the standard conversion sequence from the return type of F1 to the destination type (i.e., the type of the entity being initialized) is a better conversion sequence than the standard conversion sequence from the return type of F2 to the destination type. */ if (! winner && cand1->second_conv) winner = compare_ics (cand1->second_conv, cand2->second_conv); /* If the built-in candidates are the same, arbitrarily pick one. */ if (! winner && cand1->fn == cand2->fn && TREE_CODE (cand1->fn) == IDENTIFIER_NODE) { for (i = 0; i < len; ++i) if (!same_type_p (TREE_TYPE (TREE_VEC_ELT (cand1->convs, i)), TREE_TYPE (TREE_VEC_ELT (cand2->convs, i)))) break; if (i == TREE_VEC_LENGTH (cand1->convs)) return 1; /* Kludge around broken overloading rules whereby Integer a, b; test ? a : b; is ambiguous, since there's a builtin that takes references and another that takes values. */ if (cand1->fn == ansi_opname[COND_EXPR]) { tree c1 = TREE_VEC_ELT (cand1->convs, 1); tree c2 = TREE_VEC_ELT (cand2->convs, 1); tree t1 = strip_top_quals (non_reference (TREE_TYPE (c1))); tree t2 = strip_top_quals (non_reference (TREE_TYPE (c2))); if (same_type_p (t1, t2)) { if (TREE_CODE (c1) == REF_BIND && TREE_CODE (c2) != REF_BIND) return 1; if (TREE_CODE (c1) != REF_BIND && TREE_CODE (c2) == REF_BIND) return -1; } } } tweak: /* Extension: If the worst conversion for one candidate is worse than the worst conversion for the other, take the first. */ if (! winner && ! pedantic) { int rank1 = IDENTITY_RANK, rank2 = IDENTITY_RANK; for (i = 0; i < len; ++i) { if (ICS_RANK (TREE_VEC_ELT (cand1->convs, i+off1)) > rank1) rank1 = ICS_RANK (TREE_VEC_ELT (cand1->convs, i+off1)); if (ICS_RANK (TREE_VEC_ELT (cand2->convs, i+off2)) > rank2) rank2 = ICS_RANK (TREE_VEC_ELT (cand2->convs, i+off2)); } if (rank1 < rank2) return 1; if (rank1 > rank2) return -1; } return winner; } /* Given a list of candidates for overloading, find the best one, if any. This algorithm has a worst case of O(2n) (winner is last), and a best case of O(n/2) (totally ambiguous); much better than a sorting algorithm. */ static struct z_candidate * tourney (candidates) struct z_candidate *candidates; { struct z_candidate *champ = candidates, *challenger; int fate; int champ_compared_to_predecessor = 0; /* Walk through the list once, comparing each current champ to the next candidate, knocking out a candidate or two with each comparison. */ for (challenger = champ->next; challenger; ) { fate = joust (champ, challenger, 0); if (fate == 1) challenger = challenger->next; else { if (fate == 0) { champ = challenger->next; if (champ == 0) return 0; champ_compared_to_predecessor = 0; } else { champ = challenger; champ_compared_to_predecessor = 1; } challenger = champ->next; } } /* Make sure the champ is better than all the candidates it hasn't yet been compared to. */ for (challenger = candidates; challenger != champ && !(champ_compared_to_predecessor && challenger->next == champ); challenger = challenger->next) { fate = joust (champ, challenger, 0); if (fate != 1) return 0; } return champ; } int can_convert (to, from) tree to, from; { tree t = implicit_conversion (to, from, NULL_TREE, LOOKUP_NORMAL); return (t && ! ICS_BAD_FLAG (t)); } int can_convert_arg (to, from, arg) tree to, from, arg; { tree t = implicit_conversion (to, from, arg, LOOKUP_NORMAL); return (t && ! ICS_BAD_FLAG (t)); } Index: vendor/gcc/dist/contrib/gcc/cp/class.c =================================================================== --- vendor/gcc/dist/contrib/gcc/cp/class.c (revision 60966) +++ vendor/gcc/dist/contrib/gcc/cp/class.c (revision 60967) @@ -1,5401 +1,5753 @@ /* Functions related to building classes and their related objects. Copyright (C) 1987, 92-97, 1998, 1999 Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@cygnus.com) 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. */ /* High-level class interface. */ #include "config.h" #include "system.h" #include "tree.h" #include "cp-tree.h" #include "flags.h" #include "rtl.h" #include "output.h" #include "toplev.h" #include "splay-tree.h" #include "obstack.h" #define obstack_chunk_alloc xmalloc #define obstack_chunk_free free /* This is how we tell when two virtual member functions are really the same. */ #define SAME_FN(FN1DECL, FN2DECL) (DECL_ASSEMBLER_NAME (FN1DECL) == DECL_ASSEMBLER_NAME (FN2DECL)) extern void set_class_shadows PROTO ((tree)); /* The number of nested classes being processed. If we are not in the scope of any class, this is zero. */ int current_class_depth; /* In order to deal with nested classes, we keep a stack of classes. The topmost entry is the innermost class, and is the entry at index CURRENT_CLASS_DEPTH */ typedef struct class_stack_node { /* The name of the class. */ tree name; /* The _TYPE node for the class. */ tree type; /* The access specifier pending for new declarations in the scope of this class. */ tree access; /* If were defining TYPE, the names used in this class. */ splay_tree names_used; }* class_stack_node_t; /* The stack itself. This is an dynamically resized array. The number of elements allocated is CURRENT_CLASS_STACK_SIZE. */ static int current_class_stack_size; static class_stack_node_t current_class_stack; /* When we're processing a member function, current_class_ptr is the PARM_DECL for the `this' pointer. The current_class_ref is an expression for `*this'. */ tree current_class_ptr, current_class_ref; /* The following two can be derived from the previous one */ tree current_class_name; /* IDENTIFIER_NODE: name of current class */ tree current_class_type; /* _TYPE: the type of the current class */ tree current_access_specifier; tree previous_class_type; /* _TYPE: the previous type that was a class */ tree previous_class_values; /* TREE_LIST: copy of the class_shadowed list when leaving an outermost class scope. */ /* The obstack on which the cached class declarations are kept. */ static struct obstack class_cache_obstack; /* The first object allocated on that obstack. We can use obstack_free with tis value to free the entire obstack. */ char *class_cache_firstobj; struct base_info; static tree get_vfield_name PROTO((tree)); static void finish_struct_anon PROTO((tree)); static tree build_vbase_pointer PROTO((tree, tree)); static tree build_vtable_entry PROTO((tree, tree)); static tree get_vtable_name PROTO((tree)); static tree get_derived_offset PROTO((tree, tree)); static tree get_basefndecls PROTO((tree, tree)); static void set_rtti_entry PROTO((tree, tree, tree)); static tree build_vtable PROTO((tree, tree)); static void prepare_fresh_vtable PROTO((tree, tree)); +static tree prepare_ctor_vtable PROTO((tree, tree, tree)); static void fixup_vtable_deltas1 PROTO((tree, tree)); static void fixup_vtable_deltas PROTO((tree, int, tree)); +static tree finish_one_ctor_vtable PROTO((tree, tree, tree, tree)); +static tree prepend_ctor_vfields_for_vbase PROTO((tree, tree, tree, tree, int, tree)); +static tree finish_ctor_vtables_for_vbases PROTO((tree, tree, tree)); +static tree finish_ctor_vtables_1 PROTO((tree, tree)); +static tree prepend_vbase_vfields PROTO((tree, int, tree)); +static void finish_ctor_vtables PROTO((tree)); static void finish_vtbls PROTO((tree, int, tree)); static void modify_vtable_entry PROTO((tree, tree, tree)); static tree get_vtable_entry_n PROTO((tree, unsigned HOST_WIDE_INT)); static void add_virtual_function PROTO((tree *, tree *, int *, tree, tree)); static tree delete_duplicate_fields_1 PROTO((tree, tree)); static void delete_duplicate_fields PROTO((tree)); static void finish_struct_bits PROTO((tree, int)); static int alter_access PROTO((tree, tree, tree, tree)); static void handle_using_decl PROTO((tree, tree, tree, tree)); static int overrides PROTO((tree, tree)); static int strictly_overrides PROTO((tree, tree)); static void merge_overrides PROTO((tree, tree, int, tree)); static void override_one_vtable PROTO((tree, tree, tree)); static void mark_overriders PROTO((tree, tree)); static void check_for_override PROTO((tree, tree)); static tree get_class_offset_1 PROTO((tree, tree, tree, tree, tree)); static tree get_class_offset PROTO((tree, tree, tree, tree)); static void modify_one_vtable PROTO((tree, tree, tree, tree)); static void modify_all_vtables PROTO((tree, tree, tree)); static void modify_all_direct_vtables PROTO((tree, int, tree, tree, tree)); static void modify_all_indirect_vtables PROTO((tree, int, int, tree, tree, tree)); static int finish_base_struct PROTO((tree, struct base_info *)); static void finish_struct_methods PROTO((tree)); static void maybe_warn_about_overly_private_class PROTO ((tree)); static tree make_method_vec PROTO((int)); static void free_method_vec PROTO((tree)); static tree add_implicitly_declared_members PROTO((tree, int, int, int)); static tree fixed_type_or_null PROTO((tree, int *)); static tree resolve_address_of_overloaded_function PROTO((tree, tree, int, int, tree)); static void build_vtable_entry_ref PROTO((tree, tree, tree)); /* Way of stacking language names. */ tree *current_lang_base, *current_lang_stack; int current_lang_stacksize; /* Names of languages we recognize. */ tree lang_name_c, lang_name_cplusplus, lang_name_java; tree current_lang_name; /* When layout out an aggregate type, the size of the basetypes (virtual and non-virtual) is passed to layout_record via this node. */ static tree base_layout_decl; /* Constants used for access control. */ tree access_default_node; /* 0 */ tree access_public_node; /* 1 */ tree access_protected_node; /* 2 */ tree access_private_node; /* 3 */ tree access_default_virtual_node; /* 4 */ tree access_public_virtual_node; /* 5 */ tree access_protected_virtual_node; /* 6 */ tree access_private_virtual_node; /* 7 */ /* Variables shared between class.c and call.c. */ #ifdef GATHER_STATISTICS int n_vtables = 0; int n_vtable_entries = 0; int n_vtable_searches = 0; int n_vtable_elems = 0; int n_convert_harshness = 0; int n_compute_conversion_costs = 0; int n_build_method_call = 0; int n_inner_fields_searched = 0; #endif /* Virtual baseclass things. */ static tree build_vbase_pointer (exp, type) tree exp, type; { char *name; FORMAT_VBASE_NAME (name, type); return build_component_ref (exp, get_identifier (name), NULL_TREE, 0); } #if 0 /* Is the type of the EXPR, the complete type of the object? If we are going to be wrong, we must be conservative, and return 0. */ static int complete_type_p (expr) tree expr; { tree type = TYPE_MAIN_VARIANT (TREE_TYPE (expr)); while (1) { switch (TREE_CODE (expr)) { case SAVE_EXPR: case INDIRECT_REF: case ADDR_EXPR: case NOP_EXPR: case CONVERT_EXPR: expr = TREE_OPERAND (expr, 0); continue; case CALL_EXPR: if (! TREE_HAS_CONSTRUCTOR (expr)) break; /* fall through... */ case VAR_DECL: case FIELD_DECL: if (TREE_CODE (TREE_TYPE (expr)) == ARRAY_TYPE && IS_AGGR_TYPE (TREE_TYPE (TREE_TYPE (expr))) && TYPE_MAIN_VARIANT (TREE_TYPE (expr)) == type) return 1; /* fall through... */ case TARGET_EXPR: case PARM_DECL: if (IS_AGGR_TYPE (TREE_TYPE (expr)) && TYPE_MAIN_VARIANT (TREE_TYPE (expr)) == type) return 1; /* fall through... */ case PLUS_EXPR: default: break; } break; } return 0; } #endif /* Build multi-level access to EXPR using hierarchy path PATH. CODE is PLUS_EXPR if we are going with the grain, and MINUS_EXPR if we are not (in which case, we cannot traverse virtual baseclass links). TYPE is the type we want this path to have on exit. NONNULL is non-zero if we know (for any reason) that EXPR is not, in fact, zero. */ tree build_vbase_path (code, type, expr, path, nonnull) enum tree_code code; tree type, expr, path; int nonnull; { register int changed = 0; tree last = NULL_TREE, last_virtual = NULL_TREE; int fixed_type_p; tree null_expr = 0, nonnull_expr; tree basetype; tree offset = integer_zero_node; if (BINFO_INHERITANCE_CHAIN (path) == NULL_TREE) return build1 (NOP_EXPR, type, expr); /* If -fthis-is-variable, we might have set nonnull incorrectly. We don't care enough to get this right, so just clear it. */ if (flag_this_is_variable > 0) nonnull = 0; /* We could do better if we had additional logic to convert back to the unconverted type (the static type of the complete object), and then convert back to the type we want. Until that is done, we only optimize if the complete type is the same type as expr has. */ fixed_type_p = resolves_to_fixed_type_p (expr, &nonnull); if (!fixed_type_p && TREE_SIDE_EFFECTS (expr)) expr = save_expr (expr); nonnull_expr = expr; if (BINFO_INHERITANCE_CHAIN (path)) path = reverse_path (path); basetype = BINFO_TYPE (path); while (path) { if (TREE_VIA_VIRTUAL (path)) { last_virtual = BINFO_TYPE (path); if (code == PLUS_EXPR) { changed = ! fixed_type_p; if (changed) { tree ind; /* We already check for ambiguous things in the caller, just find a path. */ if (last) { tree binfo = get_binfo (last, TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (nonnull_expr))), 0); nonnull_expr = convert_pointer_to_real (binfo, nonnull_expr); } ind = build_indirect_ref (nonnull_expr, NULL_PTR); nonnull_expr = build_vbase_pointer (ind, last_virtual); if (nonnull == 0 && TREE_CODE (type) == POINTER_TYPE && null_expr == NULL_TREE) { null_expr = build1 (NOP_EXPR, build_pointer_type (last_virtual), integer_zero_node); expr = build (COND_EXPR, build_pointer_type (last_virtual), build (EQ_EXPR, boolean_type_node, expr, integer_zero_node), null_expr, nonnull_expr); } } /* else we'll figure out the offset below. */ /* Happens in the case of parse errors. */ if (nonnull_expr == error_mark_node) return error_mark_node; } else { cp_error ("cannot cast up from virtual baseclass `%T'", last_virtual); return error_mark_node; } } last = path; path = BINFO_INHERITANCE_CHAIN (path); } /* LAST is now the last basetype assoc on the path. */ /* A pointer to a virtual base member of a non-null object is non-null. Therefore, we only need to test for zeroness once. Make EXPR the canonical expression to deal with here. */ if (null_expr) { TREE_OPERAND (expr, 2) = nonnull_expr; TREE_TYPE (expr) = TREE_TYPE (TREE_OPERAND (expr, 1)) = TREE_TYPE (nonnull_expr); } else expr = nonnull_expr; /* If we go through any virtual base pointers, make sure that casts to BASETYPE from the last virtual base class use the right value for BASETYPE. */ if (changed) { tree intype = TREE_TYPE (TREE_TYPE (expr)); if (TYPE_MAIN_VARIANT (intype) != BINFO_TYPE (last)) { tree binfo = get_binfo (last, TYPE_MAIN_VARIANT (intype), 0); offset = BINFO_OFFSET (binfo); } } else { if (last_virtual) { offset = BINFO_OFFSET (binfo_member (last_virtual, CLASSTYPE_VBASECLASSES (basetype))); offset = size_binop (PLUS_EXPR, offset, BINFO_OFFSET (last)); } else offset = BINFO_OFFSET (last); } if (TREE_INT_CST_LOW (offset)) { /* Bash types to make the backend happy. */ offset = cp_convert (type, offset); #if 0 /* This shouldn't be necessary. (mrs) */ expr = build1 (NOP_EXPR, type, expr); #endif /* If expr might be 0, we need to preserve that zeroness. */ if (nonnull == 0) { if (null_expr) TREE_TYPE (null_expr) = type; else null_expr = build1 (NOP_EXPR, type, integer_zero_node); if (TREE_SIDE_EFFECTS (expr)) expr = save_expr (expr); return build (COND_EXPR, type, build (EQ_EXPR, boolean_type_node, expr, integer_zero_node), null_expr, build (code, type, expr, offset)); } else return build (code, type, expr, offset); } /* Cannot change the TREE_TYPE of a NOP_EXPR here, since it may be used multiple times in initialization of multiple inheritance. */ if (null_expr) { TREE_TYPE (expr) = type; return expr; } else return build1 (NOP_EXPR, type, expr); } /* Virtual function things. */ /* Build an entry in the virtual function table. DELTA is the offset for the `this' pointer. PFN is an ADDR_EXPR containing a pointer to the virtual function. Note that the index (DELTA2) in the virtual function table is always 0. */ static tree build_vtable_entry (delta, pfn) tree delta, pfn; { if (flag_vtable_thunks) { HOST_WIDE_INT idelta = TREE_INT_CST_LOW (delta); if (idelta && ! DECL_ABSTRACT_VIRTUAL_P (TREE_OPERAND (pfn, 0))) { pfn = build1 (ADDR_EXPR, vtable_entry_type, make_thunk (pfn, idelta)); TREE_READONLY (pfn) = 1; TREE_CONSTANT (pfn) = 1; } #ifdef GATHER_STATISTICS n_vtable_entries += 1; #endif return pfn; } else { extern int flag_huge_objects; tree elems = expr_tree_cons (NULL_TREE, delta, expr_tree_cons (NULL_TREE, integer_zero_node, build_expr_list (NULL_TREE, pfn))); tree entry = build (CONSTRUCTOR, vtable_entry_type, NULL_TREE, elems); /* DELTA used to be constructed by `size_int' and/or size_binop, which caused overflow problems when it was negative. That should be fixed now. */ if (! int_fits_type_p (delta, delta_type_node)) { if (flag_huge_objects) sorry ("object size exceeds built-in limit for virtual function table implementation"); else sorry ("object size exceeds normal limit for virtual function table implementation, recompile all source and use -fhuge-objects"); } TREE_CONSTANT (entry) = 1; TREE_STATIC (entry) = 1; TREE_READONLY (entry) = 1; #ifdef GATHER_STATISTICS n_vtable_entries += 1; #endif return entry; } } /* We want to give the assembler the vtable identifier as well as the offset to the function pointer. So we generate __asm__ __volatile__ (".vtable_entry %c0, %c1" : : "s"(&class_vtable), "i"((long)&vtbl[idx].pfn - (long)&vtbl[0])); */ static void build_vtable_entry_ref (basetype, vtbl, idx) tree basetype, vtbl, idx; { static char asm_stmt[] = ".vtable_entry %c0, %c1"; tree s, i, i2; s = build_unary_op (ADDR_EXPR, TYPE_BINFO_VTABLE (basetype), 0); s = build_tree_list (build_string (1, "s"), s); i = build_array_ref (vtbl, idx); if (!flag_vtable_thunks) i = build_component_ref (i, pfn_identifier, vtable_entry_type, 0); i = build_c_cast (ptrdiff_type_node, build_unary_op (ADDR_EXPR, i, 0)); i2 = build_array_ref (vtbl, build_int_2(0,0)); i2 = build_c_cast (ptrdiff_type_node, build_unary_op (ADDR_EXPR, i2, 0)); i = build_binary_op (MINUS_EXPR, i, i2); i = build_tree_list (build_string (1, "i"), i); expand_asm_operands (build_string (sizeof(asm_stmt)-1, asm_stmt), NULL_TREE, chainon (s, i), NULL_TREE, 1, NULL, 0); } /* Given an object INSTANCE, return an expression which yields the virtual function vtable element corresponding to INDEX. There are many special cases for INSTANCE which we take care of here, mainly to avoid creating extra tree nodes when we don't have to. */ tree build_vtbl_ref (instance, idx) tree instance, idx; { tree vtbl, aref; tree basetype = TREE_TYPE (instance); if (TREE_CODE (basetype) == REFERENCE_TYPE) basetype = TREE_TYPE (basetype); if (instance == current_class_ref) vtbl = build_vfield_ref (instance, basetype); else { if (optimize) { /* Try to figure out what a reference refers to, and access its virtual function table directly. */ tree ref = NULL_TREE; if (TREE_CODE (instance) == INDIRECT_REF && TREE_CODE (TREE_TYPE (TREE_OPERAND (instance, 0))) == REFERENCE_TYPE) ref = TREE_OPERAND (instance, 0); else if (TREE_CODE (TREE_TYPE (instance)) == REFERENCE_TYPE) ref = instance; if (ref && TREE_CODE (ref) == VAR_DECL && DECL_INITIAL (ref)) { tree init = DECL_INITIAL (ref); while (TREE_CODE (init) == NOP_EXPR || TREE_CODE (init) == NON_LVALUE_EXPR) init = TREE_OPERAND (init, 0); if (TREE_CODE (init) == ADDR_EXPR) { init = TREE_OPERAND (init, 0); if (IS_AGGR_TYPE (TREE_TYPE (init)) && (TREE_CODE (init) == PARM_DECL || TREE_CODE (init) == VAR_DECL)) instance = init; } } } if (IS_AGGR_TYPE (TREE_TYPE (instance)) && (TREE_CODE (instance) == RESULT_DECL || TREE_CODE (instance) == PARM_DECL || TREE_CODE (instance) == VAR_DECL)) vtbl = TYPE_BINFO_VTABLE (basetype); else vtbl = build_vfield_ref (instance, basetype); } assemble_external (vtbl); if (flag_vtable_gc) build_vtable_entry_ref (basetype, vtbl, idx); aref = build_array_ref (vtbl, idx); return aref; } /* Given an object INSTANCE, return an expression which yields the virtual function corresponding to INDEX. There are many special cases for INSTANCE which we take care of here, mainly to avoid creating extra tree nodes when we don't have to. */ tree build_vfn_ref (ptr_to_instptr, instance, idx) tree *ptr_to_instptr, instance; tree idx; { tree aref = build_vtbl_ref (instance, idx); /* When using thunks, there is no extra delta, and we get the pfn directly. */ if (flag_vtable_thunks) return aref; if (ptr_to_instptr) { /* Save the intermediate result in a SAVE_EXPR so we don't have to compute each component of the virtual function pointer twice. */ if (TREE_CODE (aref) == INDIRECT_REF) TREE_OPERAND (aref, 0) = save_expr (TREE_OPERAND (aref, 0)); *ptr_to_instptr = build (PLUS_EXPR, TREE_TYPE (*ptr_to_instptr), *ptr_to_instptr, cp_convert (ptrdiff_type_node, build_component_ref (aref, delta_identifier, NULL_TREE, 0))); } return build_component_ref (aref, pfn_identifier, NULL_TREE, 0); } /* Return the name of the virtual function table (as an IDENTIFIER_NODE) for the given TYPE. */ static tree get_vtable_name (type) tree type; { tree type_id = build_typename_overload (type); char *buf = (char *) alloca (strlen (VTABLE_NAME_FORMAT) + IDENTIFIER_LENGTH (type_id) + 2); const char *ptr = IDENTIFIER_POINTER (type_id); int i; for (i = 0; ptr[i] == OPERATOR_TYPENAME_FORMAT[i]; i++) ; #if 0 /* We don't take off the numbers; prepare_fresh_vtable uses the DECL_ASSEMBLER_NAME for the type, which includes the number in `3foo'. If we were to pull them off here, we'd end up with something like `_vt.foo.3bar', instead of a uniform definition. */ while (ptr[i] >= '0' && ptr[i] <= '9') i += 1; #endif sprintf (buf, VTABLE_NAME_FORMAT, ptr+i); return get_identifier (buf); } /* Return the offset to the main vtable for a given base BINFO. */ tree get_vfield_offset (binfo) tree binfo; { tree tmp = size_binop (FLOOR_DIV_EXPR, DECL_FIELD_BITPOS (CLASSTYPE_VFIELD (BINFO_TYPE (binfo))), size_int (BITS_PER_UNIT)); tmp = convert (sizetype, tmp); return size_binop (PLUS_EXPR, tmp, BINFO_OFFSET (binfo)); } /* Get the offset to the start of the original binfo that we derived this binfo from. If we find TYPE first, return the offset only that far. The shortened search is useful because the this pointer on method calling is expected to point to a DECL_CONTEXT (fndecl) object, and not a baseclass of it. */ static tree get_derived_offset (binfo, type) tree binfo, type; { tree offset1 = get_vfield_offset (TYPE_BINFO (BINFO_TYPE (binfo))); tree offset2; int i; while (BINFO_BASETYPES (binfo) && (i=CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo))) != -1) { tree binfos = BINFO_BASETYPES (binfo); if (BINFO_TYPE (binfo) == type) break; binfo = TREE_VEC_ELT (binfos, i); } offset2 = get_vfield_offset (TYPE_BINFO (BINFO_TYPE (binfo))); return size_binop (MINUS_EXPR, offset1, offset2); } /* Update the rtti info for this class. */ static void set_rtti_entry (virtuals, offset, type) tree virtuals, offset, type; { tree vfn; if (CLASSTYPE_COM_INTERFACE (type)) return; if (flag_rtti) - vfn = build1 (ADDR_EXPR, vfunc_ptr_type_node, get_tinfo_fn (type)); + vfn = build1 (ADDR_EXPR, vfunc_ptr_type_node, get_tinfo_fn_unused (type)); else vfn = build1 (NOP_EXPR, vfunc_ptr_type_node, size_zero_node); TREE_CONSTANT (vfn) = 1; if (! flag_vtable_thunks) TREE_VALUE (virtuals) = build_vtable_entry (offset, vfn); else { tree voff = build1 (NOP_EXPR, vfunc_ptr_type_node, offset); TREE_CONSTANT (voff) = 1; TREE_VALUE (virtuals) = build_vtable_entry (integer_zero_node, voff); /* The second slot is for the tdesc pointer when thunks are used. */ TREE_VALUE (TREE_CHAIN (virtuals)) = build_vtable_entry (integer_zero_node, vfn); } } /* Build a virtual function for type TYPE. If BINFO is non-NULL, build the vtable starting with the initial approximation that it is the same as the one which is the head of the association list. */ static tree build_vtable (binfo, type) tree binfo, type; { tree name = get_vtable_name (type); tree virtuals, decl; if (binfo) { tree offset; virtuals = copy_list (BINFO_VIRTUALS (binfo)); decl = build_lang_decl (VAR_DECL, name, TREE_TYPE (BINFO_VTABLE (binfo))); /* Now do rtti stuff. */ offset = get_derived_offset (TYPE_BINFO (type), NULL_TREE); offset = ssize_binop (MINUS_EXPR, integer_zero_node, offset); set_rtti_entry (virtuals, offset, type); } else { virtuals = NULL_TREE; decl = build_lang_decl (VAR_DECL, name, void_type_node); } #ifdef GATHER_STATISTICS n_vtables += 1; n_vtable_elems += list_length (virtuals); #endif /* Set TREE_PUBLIC and TREE_EXTERN as appropriate. */ import_export_vtable (decl, type, 0); decl = pushdecl_top_level (decl); SET_IDENTIFIER_GLOBAL_VALUE (name, decl); /* Initialize the association list for this type, based on our first approximation. */ TYPE_BINFO_VTABLE (type) = decl; TYPE_BINFO_VIRTUALS (type) = virtuals; DECL_ARTIFICIAL (decl) = 1; TREE_STATIC (decl) = 1; #ifndef WRITABLE_VTABLES /* Make them READONLY by default. (mrs) */ TREE_READONLY (decl) = 1; #endif /* At one time the vtable info was grabbed 2 words at a time. This fails on sparc unless you have 8-byte alignment. (tiemann) */ DECL_ALIGN (decl) = MAX (TYPE_ALIGN (double_type_node), DECL_ALIGN (decl)); DECL_VIRTUAL_P (decl) = 1; DECL_CONTEXT (decl) = type; binfo = TYPE_BINFO (type); SET_BINFO_NEW_VTABLE_MARKED (binfo); return decl; } extern tree signed_size_zero_node; /* Give TYPE a new virtual function table which is initialized with a skeleton-copy of its original initialization. The only entry that changes is the `delta' entry, so we can really share a lot of structure. FOR_TYPE is the derived type which caused this table to be needed. BINFO is the type association which provided TYPE for FOR_TYPE. The order in which vtables are built (by calling this function) for an object must remain the same, otherwise a binary incompatibility can result. */ static void prepare_fresh_vtable (binfo, for_type) tree binfo, for_type; { tree basetype; tree orig_decl = BINFO_VTABLE (binfo); tree name; tree new_decl; tree offset; tree path = binfo; char *buf, *buf2; char joiner = '_'; int i; #ifdef JOINER joiner = JOINER; #endif basetype = TYPE_MAIN_VARIANT (BINFO_TYPE (binfo)); buf2 = TYPE_ASSEMBLER_NAME_STRING (basetype); i = TYPE_ASSEMBLER_NAME_LENGTH (basetype) + 1; /* We know that the vtable that we are going to create doesn't exist yet in the global namespace, and when we finish, it will be pushed into the global namespace. In complex MI hierarchies, we have to loop while the name we are thinking of adding is globally defined, adding more name components to the vtable name as we loop, until the name is unique. This is because in complex MI cases, we might have the same base more than once. This means that the order in which this function is called for vtables must remain the same, otherwise binary compatibility can be compromised. */ while (1) { char *buf1 = (char *) alloca (TYPE_ASSEMBLER_NAME_LENGTH (for_type) + 1 + i); char *new_buf2; sprintf (buf1, "%s%c%s", TYPE_ASSEMBLER_NAME_STRING (for_type), joiner, buf2); buf = (char *) alloca (strlen (VTABLE_NAME_FORMAT) + strlen (buf1) + 1); sprintf (buf, VTABLE_NAME_FORMAT, buf1); name = get_identifier (buf); /* If this name doesn't clash, then we can use it, otherwise we add more to the name until it is unique. */ if (! IDENTIFIER_GLOBAL_VALUE (name)) break; /* Set values for next loop through, if the name isn't unique. */ path = BINFO_INHERITANCE_CHAIN (path); /* We better not run out of stuff to make it unique. */ my_friendly_assert (path != NULL_TREE, 368); basetype = TYPE_MAIN_VARIANT (BINFO_TYPE (path)); if (for_type == basetype) { /* If we run out of basetypes in the path, we have already found created a vtable with that name before, we now resort to tacking on _%d to distinguish them. */ int j = 2; i = TYPE_ASSEMBLER_NAME_LENGTH (basetype) + 1 + i + 1 + 3; buf1 = (char *) alloca (i); do { sprintf (buf1, "%s%c%s%c%d", TYPE_ASSEMBLER_NAME_STRING (basetype), joiner, buf2, joiner, j); buf = (char *) alloca (strlen (VTABLE_NAME_FORMAT) + strlen (buf1) + 1); sprintf (buf, VTABLE_NAME_FORMAT, buf1); name = get_identifier (buf); /* If this name doesn't clash, then we can use it, otherwise we add something different to the name until it is unique. */ } while (++j <= 999 && IDENTIFIER_GLOBAL_VALUE (name)); /* Hey, they really like MI don't they? Increase the 3 above to 6, and the 999 to 999999. :-) */ my_friendly_assert (j <= 999, 369); break; } i = TYPE_ASSEMBLER_NAME_LENGTH (basetype) + 1 + i; new_buf2 = (char *) alloca (i); sprintf (new_buf2, "%s%c%s", TYPE_ASSEMBLER_NAME_STRING (basetype), joiner, buf2); buf2 = new_buf2; } new_decl = build_lang_decl (VAR_DECL, name, TREE_TYPE (orig_decl)); /* Remember which class this vtable is really for. */ DECL_CONTEXT (new_decl) = for_type; DECL_ARTIFICIAL (new_decl) = 1; TREE_STATIC (new_decl) = 1; BINFO_VTABLE (binfo) = pushdecl_top_level (new_decl); DECL_VIRTUAL_P (new_decl) = 1; #ifndef WRITABLE_VTABLES /* Make them READONLY by default. (mrs) */ TREE_READONLY (new_decl) = 1; #endif DECL_ALIGN (new_decl) = DECL_ALIGN (orig_decl); /* Make fresh virtual list, so we can smash it later. */ BINFO_VIRTUALS (binfo) = copy_list (BINFO_VIRTUALS (binfo)); if (TREE_VIA_VIRTUAL (binfo)) { tree binfo1 = binfo_member (BINFO_TYPE (binfo), CLASSTYPE_VBASECLASSES (for_type)); /* XXX - This should never happen, if it does, the caller should ensure that the binfo is from for_type's binfos, not from any base type's. We can remove all this code after a while. */ if (binfo1 != binfo) warning ("internal inconsistency: binfo offset error for rtti"); offset = BINFO_OFFSET (binfo1); } else offset = BINFO_OFFSET (binfo); set_rtti_entry (BINFO_VIRTUALS (binfo), ssize_binop (MINUS_EXPR, integer_zero_node, offset), for_type); #ifdef GATHER_STATISTICS n_vtables += 1; n_vtable_elems += list_length (BINFO_VIRTUALS (binfo)); #endif /* Set TREE_PUBLIC and TREE_EXTERN as appropriate. */ import_export_vtable (new_decl, for_type, 0); if (TREE_VIA_VIRTUAL (binfo)) my_friendly_assert (binfo == binfo_member (BINFO_TYPE (binfo), CLASSTYPE_VBASECLASSES (current_class_type)), 170); SET_BINFO_NEW_VTABLE_MARKED (binfo); } +/* Return a new vtable for use in initialization of the BASE subobject + of COMPLETE_TYPE. The vtable there goes into the vfield of the + VBASEBASE virtual subobject. */ + +static tree +prepare_ctor_vtable (complete_type, base, vbasebase) + tree complete_type, base, vbasebase; +{ + tree orig_decl = BINFO_VTABLE (vbasebase); + tree name = get_vlist_vtable_id (base, vbasebase); + tree new_decl; + + new_decl = build_lang_decl (VAR_DECL, name, TREE_TYPE (orig_decl)); + /* Remember which class this vtable is really for. */ + DECL_CONTEXT (new_decl) = complete_type; + + DECL_ARTIFICIAL (new_decl) = 1; + TREE_STATIC (new_decl) = 1; + new_decl = pushdecl_top_level (new_decl); + DECL_VIRTUAL_P (new_decl) = 1; +#ifndef WRITABLE_VTABLES + /* Make them READONLY by default. (mrs) */ + TREE_READONLY (new_decl) = 1; +#endif + DECL_ALIGN (new_decl) = DECL_ALIGN (orig_decl); + +#ifdef GATHER_STATISTICS + n_vtables += 1; + n_vtable_elems += list_length (BINFO_VIRTUALS (binfo)); +#endif + + /* Set TREE_PUBLIC and TREE_EXTERN as appropriate. */ + import_export_vtable (new_decl, complete_type, 0); + + return new_decl; +} + #if 0 /* Access the virtual function table entry that logically contains BASE_FNDECL. VIRTUALS is the virtual function table's initializer. We can run off the end, when dealing with virtual destructors in MI situations, return NULL_TREE in that case. */ static tree get_vtable_entry (virtuals, base_fndecl) tree virtuals, base_fndecl; { unsigned HOST_WIDE_INT n = (HOST_BITS_PER_WIDE_INT >= BITS_PER_WORD ? (TREE_INT_CST_LOW (DECL_VINDEX (base_fndecl)) & (((unsigned HOST_WIDE_INT)1<<(BITS_PER_WORD-1))-1)) : TREE_INT_CST_LOW (DECL_VINDEX (base_fndecl))); #ifdef GATHER_STATISTICS n_vtable_searches += n; #endif while (n > 0 && virtuals) { --n; virtuals = TREE_CHAIN (virtuals); } return virtuals; } #endif /* Put new entry ENTRY into virtual function table initializer VIRTUALS. Also update DECL_VINDEX (FNDECL). */ static void modify_vtable_entry (old_entry_in_list, new_entry, fndecl) tree old_entry_in_list, new_entry, fndecl; { tree base_fndecl = TREE_OPERAND (FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (old_entry_in_list)), 0); #ifdef NOTQUITE cp_warning ("replaced %D with %D", DECL_ASSEMBLER_NAME (base_fndecl), DECL_ASSEMBLER_NAME (fndecl)); #endif TREE_VALUE (old_entry_in_list) = new_entry; /* Now assign virtual dispatch information, if unset. */ /* We can dispatch this, through any overridden base function. */ if (TREE_CODE (DECL_VINDEX (fndecl)) != INTEGER_CST) { DECL_VINDEX (fndecl) = DECL_VINDEX (base_fndecl); DECL_CONTEXT (fndecl) = DECL_CONTEXT (base_fndecl); } } /* Access the virtual function table entry N. VIRTUALS is the virtual function table's initializer. */ static tree get_vtable_entry_n (virtuals, n) tree virtuals; unsigned HOST_WIDE_INT n; { while (n > 0) { --n; virtuals = TREE_CHAIN (virtuals); } return virtuals; } /* Add a virtual function to all the appropriate vtables for the class T. DECL_VINDEX(X) should be error_mark_node, if we want to allocate a new slot in our table. If it is error_mark_node, we know that no other function from another vtable is overridden by X. HAS_VIRTUAL keeps track of how many virtuals there are in our main vtable for the type, and we build upon the PENDING_VIRTUALS list and return it. */ static void add_virtual_function (pv, phv, has_virtual, fndecl, t) tree *pv, *phv; int *has_virtual; tree fndecl; tree t; /* Structure type. */ { tree pending_virtuals = *pv; tree pending_hard_virtuals = *phv; /* FUNCTION_TYPEs and OFFSET_TYPEs no longer freely convert to void *. Make such a conversion here. */ tree vfn = build1 (ADDR_EXPR, vfunc_ptr_type_node, fndecl); TREE_CONSTANT (vfn) = 1; #ifndef DUMB_USER if (current_class_type == 0) cp_warning ("internal problem, current_class_type is zero when adding `%D', please report", fndecl); if (current_class_type && t != current_class_type) cp_warning ("internal problem, current_class_type differs when adding `%D', please report", fndecl); #endif /* If the virtual function is a redefinition of a prior one, figure out in which base class the new definition goes, and if necessary, make a fresh virtual function table to hold that entry. */ if (DECL_VINDEX (fndecl) == error_mark_node) { tree entry; /* We remember that this was the base sub-object for rtti. */ CLASSTYPE_RTTI (t) = t; /* If we are using thunks, use two slots at the front, one for the offset pointer, one for the tdesc pointer. For ARM-style vtables, use the same slot for both. */ if (*has_virtual == 0 && ! CLASSTYPE_COM_INTERFACE (t)) { if (flag_vtable_thunks) *has_virtual = 2; else *has_virtual = 1; } /* Build a new INT_CST for this DECL_VINDEX. */ { static tree index_table[256]; tree idx; /* We skip a slot for the offset/tdesc entry. */ int i = (*has_virtual)++; if (i >= 256 || index_table[i] == 0) { idx = build_int_2 (i, 0); if (i < 256) index_table[i] = idx; } else idx = index_table[i]; /* Now assign virtual dispatch information. */ DECL_VINDEX (fndecl) = idx; DECL_CONTEXT (fndecl) = t; } entry = build_vtable_entry (integer_zero_node, vfn); pending_virtuals = tree_cons (DECL_VINDEX (fndecl), entry, pending_virtuals); } /* Might already be INTEGER_CST if declared twice in class. We will give error later or we've already given it. */ else if (TREE_CODE (DECL_VINDEX (fndecl)) != INTEGER_CST) { /* Need an entry in some other virtual function table. Deal with this after we have laid out our virtual base classes. */ pending_hard_virtuals = temp_tree_cons (fndecl, vfn, pending_hard_virtuals); } *pv = pending_virtuals; *phv = pending_hard_virtuals; } /* Obstack on which to build the vector of class methods. */ struct obstack class_obstack; extern struct obstack *current_obstack; /* These are method vectors that were too small for the number of methods in some class, and so were abandoned. */ static tree free_method_vecs; /* Returns a method vector with enough room for N methods. N should be a power of two. */ static tree make_method_vec (n) int n; { tree new_vec; tree* t; for (t = &free_method_vecs; *t; t = &(TREE_CHAIN (*t))) /* Note that we don't use >= n here because we don't want to allocate a very large vector where it isn't needed. */ if (TREE_VEC_LENGTH (*t) == n) { new_vec = *t; *t = TREE_CHAIN (new_vec); TREE_CHAIN (new_vec) = NULL_TREE; bzero ((PTR) &TREE_VEC_ELT (new_vec, 0), n * sizeof (tree)); return new_vec; } new_vec = make_tree_vec (n); return new_vec; } /* Free the method vector VEC. */ static void free_method_vec (vec) tree vec; { TREE_CHAIN (vec) = free_method_vecs; free_method_vecs = vec; } /* Add method METHOD to class TYPE. If non-NULL, FIELDS is the entry in the METHOD_VEC vector entry of the class type where the method should be added. */ void add_method (type, fields, method) tree type, *fields, method; { push_obstacks_nochange (); end_temporary_allocation (); /* Setting the DECL_CONTEXT and DECL_CLASS_CONTEXT here is probably redundant. */ DECL_CONTEXT (method) = type; DECL_CLASS_CONTEXT (method) = type; if (fields && *fields) *fields = build_overload (method, *fields); else { int len; int slot; tree method_vec; if (!CLASSTYPE_METHOD_VEC (type)) /* Make a new method vector. We start with 8 entries. We must allocate at least two (for constructors and destructors), and we're going to end up with an assignment operator at some point as well. We could use a TREE_LIST for now, and convert it to a TREE_VEC in finish_struct, but we would probably waste more memory making the links in the list than we would by over-allocating the size of the vector here. Furthermore, we would complicate all the code that expects this to be a vector. We keep a free list of vectors that we outgrew so that we don't really waste any memory. */ CLASSTYPE_METHOD_VEC (type) = make_method_vec (8); method_vec = CLASSTYPE_METHOD_VEC (type); len = TREE_VEC_LENGTH (method_vec); if (DECL_NAME (method) == constructor_name (type)) /* A new constructor or destructor. Constructors go in slot 0; destructors go in slot 1. */ slot = DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (method)) ? 1 : 0; else { /* See if we already have an entry with this name. */ for (slot = 2; slot < len; ++slot) if (!TREE_VEC_ELT (method_vec, slot) || (DECL_NAME (OVL_CURRENT (TREE_VEC_ELT (method_vec, slot))) == DECL_NAME (method))) break; if (slot == len) { /* We need a bigger method vector. */ tree new_vec = make_method_vec (2 * len); bcopy ((PTR) &TREE_VEC_ELT (method_vec, 0), (PTR) &TREE_VEC_ELT (new_vec, 0), len * sizeof (tree)); free_method_vec (method_vec); len = 2 * len; method_vec = CLASSTYPE_METHOD_VEC (type) = new_vec; } if (DECL_CONV_FN_P (method) && !TREE_VEC_ELT (method_vec, slot)) { /* Type conversion operators have to come before ordinary methods; add_conversions depends on this to speed up looking for conversion operators. So, if necessary, we slide some of the vector elements up. In theory, this makes this algorithm O(N^2) but we don't expect many conversion operators. */ for (slot = 2; slot < len; ++slot) { tree fn = TREE_VEC_ELT (method_vec, slot); if (!fn) /* There are no more entries in the vector, so we can insert the new conversion operator here. */ break; if (!DECL_CONV_FN_P (OVL_CURRENT (fn))) /* We can insert the new function right at the SLOTth position. */ break; } if (!TREE_VEC_ELT (method_vec, slot)) /* There is nothing in the Ith slot, so we can avoid moving anything. */ ; else { /* We know the last slot in the vector is empty because we know that at this point there's room for a new function. */ bcopy ((PTR) &TREE_VEC_ELT (method_vec, slot), (PTR) &TREE_VEC_ELT (method_vec, slot + 1), (len - slot - 1) * sizeof (tree)); TREE_VEC_ELT (method_vec, slot) = NULL_TREE; } } } if (template_class_depth (type)) /* TYPE is a template class. Don't issue any errors now; wait until instantiation time to complain. */ ; else { tree fns; /* Check to see if we've already got this method. */ for (fns = TREE_VEC_ELT (method_vec, slot); fns; fns = OVL_NEXT (fns)) { tree fn = OVL_CURRENT (fns); if (TREE_CODE (fn) != TREE_CODE (method)) continue; if (TREE_CODE (method) != TEMPLATE_DECL) { /* [over.load] Member function declarations with the same name and the same parameter types cannot be overloaded if any of them is a static member function declaration. */ if (DECL_STATIC_FUNCTION_P (fn) != DECL_STATIC_FUNCTION_P (method)) { tree parms1 = TYPE_ARG_TYPES (TREE_TYPE (fn)); tree parms2 = TYPE_ARG_TYPES (TREE_TYPE (method)); if (! DECL_STATIC_FUNCTION_P (fn)) parms1 = TREE_CHAIN (parms1); else parms2 = TREE_CHAIN (parms2); if (compparms (parms1, parms2)) cp_error ("`%#D' and `%#D' cannot be overloaded", fn, method); } /* Since this is an ordinary function in a non-template class, it's mangled name can be used as a unique identifier. This technique is only an optimization; we would get the same results if we just used decls_match here. */ if (DECL_ASSEMBLER_NAME (fn) != DECL_ASSEMBLER_NAME (method)) continue; } else if (!decls_match (fn, method)) continue; /* There has already been a declaration of this method or member template. */ cp_error_at ("`%D' has already been declared in `%T'", method, type); /* We don't call duplicate_decls here to merge the declarations because that will confuse things if the methods have inline definitions. In particular, we will crash while processing the definitions. */ return; } } /* Actually insert the new method. */ TREE_VEC_ELT (method_vec, slot) = build_overload (method, TREE_VEC_ELT (method_vec, slot)); /* Add the new binding. */ if (!DECL_CONSTRUCTOR_P (method) && !DECL_DESTRUCTOR_P (method)) push_class_level_binding (DECL_NAME (method), TREE_VEC_ELT (method_vec, slot)); } pop_obstacks (); } /* Subroutines of finish_struct. */ /* Look through the list of fields for this struct, deleting duplicates as we go. This must be recursive to handle anonymous unions. FIELD is the field which may not appear anywhere in FIELDS. FIELD_PTR, if non-null, is the starting point at which chained deletions may take place. The value returned is the first acceptable entry found in FIELDS. Note that anonymous fields which are not of UNION_TYPE are not duplicates, they are just anonymous fields. This happens when we have unnamed bitfields, for example. */ static tree delete_duplicate_fields_1 (field, fields) tree field, fields; { tree x; tree prev = 0; if (DECL_NAME (field) == 0) { if (TREE_CODE (TREE_TYPE (field)) != UNION_TYPE) return fields; for (x = TYPE_FIELDS (TREE_TYPE (field)); x; x = TREE_CHAIN (x)) fields = delete_duplicate_fields_1 (x, fields); return fields; } else { for (x = fields; x; prev = x, x = TREE_CHAIN (x)) { if (DECL_NAME (x) == 0) { if (TREE_CODE (TREE_TYPE (x)) != UNION_TYPE) continue; TYPE_FIELDS (TREE_TYPE (x)) = delete_duplicate_fields_1 (field, TYPE_FIELDS (TREE_TYPE (x))); if (TYPE_FIELDS (TREE_TYPE (x)) == 0) { if (prev == 0) fields = TREE_CHAIN (fields); else TREE_CHAIN (prev) = TREE_CHAIN (x); } } else { if (DECL_NAME (field) == DECL_NAME (x)) { if (TREE_CODE (field) == CONST_DECL && TREE_CODE (x) == CONST_DECL) cp_error_at ("duplicate enum value `%D'", x); else if (TREE_CODE (field) == CONST_DECL || TREE_CODE (x) == CONST_DECL) cp_error_at ("duplicate field `%D' (as enum and non-enum)", x); else if (DECL_DECLARES_TYPE_P (field) && DECL_DECLARES_TYPE_P (x)) { if (same_type_p (TREE_TYPE (field), TREE_TYPE (x))) continue; cp_error_at ("duplicate nested type `%D'", x); } else if (DECL_DECLARES_TYPE_P (field) || DECL_DECLARES_TYPE_P (x)) { /* Hide tag decls. */ if ((TREE_CODE (field) == TYPE_DECL && DECL_ARTIFICIAL (field)) || (TREE_CODE (x) == TYPE_DECL && DECL_ARTIFICIAL (x))) continue; cp_error_at ("duplicate field `%D' (as type and non-type)", x); } else cp_error_at ("duplicate member `%D'", x); if (prev == 0) fields = TREE_CHAIN (fields); else TREE_CHAIN (prev) = TREE_CHAIN (x); } } } } return fields; } static void delete_duplicate_fields (fields) tree fields; { tree x; for (x = fields; x && TREE_CHAIN (x); x = TREE_CHAIN (x)) TREE_CHAIN (x) = delete_duplicate_fields_1 (x, TREE_CHAIN (x)); } /* Change the access of FDECL to ACCESS in T. The access to FDECL is along the path given by BINFO. Return 1 if change was legit, otherwise return 0. */ static int alter_access (t, binfo, fdecl, access) tree t; tree binfo; tree fdecl; tree access; { tree elem = purpose_member (t, DECL_ACCESS (fdecl)); if (elem) { if (TREE_VALUE (elem) != access) { if (TREE_CODE (TREE_TYPE (fdecl)) == FUNCTION_DECL) cp_error_at ("conflicting access specifications for method `%D', ignored", TREE_TYPE (fdecl)); else error ("conflicting access specifications for field `%s', ignored", IDENTIFIER_POINTER (DECL_NAME (fdecl))); } else { /* They're changing the access to the same thing they changed it to before. That's OK. */ ; } } else { enforce_access (binfo, fdecl); DECL_ACCESS (fdecl) = tree_cons (t, access, DECL_ACCESS (fdecl)); return 1; } return 0; } /* Process the USING_DECL, which is a member of T. The METHOD_VEC, if non-NULL, is the methods of T. The FIELDS are the fields of T. */ static void handle_using_decl (using_decl, t, method_vec, fields) tree using_decl; tree t; tree method_vec; tree fields; { tree ctype = DECL_INITIAL (using_decl); tree name = DECL_NAME (using_decl); tree access = TREE_PRIVATE (using_decl) ? access_private_node : TREE_PROTECTED (using_decl) ? access_protected_node : access_public_node; tree fdecl, binfo; tree flist = NULL_TREE; tree tmp; int i; int n_methods; binfo = binfo_or_else (ctype, t); if (! binfo) return; if (name == constructor_name (ctype) || name == constructor_name_full (ctype)) { cp_error_at ("using-declaration for constructor", using_decl); return; } fdecl = lookup_member (binfo, name, 0, 0); if (!fdecl) { cp_error_at ("no members matching `%D' in `%#T'", using_decl, ctype); return; } /* Functions are represented as TREE_LIST, with the purpose being the type and the value the functions. Other members come as themselves. */ if (TREE_CODE (fdecl) == TREE_LIST) /* Ignore base type this came from. */ fdecl = TREE_VALUE (fdecl); if (TREE_CODE (fdecl) == OVERLOAD) { /* We later iterate over all functions. */ flist = fdecl; fdecl = OVL_FUNCTION (flist); } name = DECL_NAME (fdecl); n_methods = method_vec ? TREE_VEC_LENGTH (method_vec) : 0; for (i = 2; i < n_methods && TREE_VEC_ELT (method_vec, i); i++) if (DECL_NAME (OVL_CURRENT (TREE_VEC_ELT (method_vec, i))) == name) { cp_error ("cannot adjust access to `%#D' in `%#T'", fdecl, t); cp_error_at (" because of local method `%#D' with same name", OVL_CURRENT (TREE_VEC_ELT (method_vec, i))); return; } if (! DECL_LANG_SPECIFIC (fdecl)) /* We don't currently handle DECL_ACCESS for TYPE_DECLs; just return. */ return; for (tmp = fields; tmp; tmp = TREE_CHAIN (tmp)) if (DECL_NAME (tmp) == name) { cp_error ("cannot adjust access to `%#D' in `%#T'", fdecl, t); cp_error_at (" because of local field `%#D' with same name", tmp); return; } /* Make type T see field decl FDECL with access ACCESS.*/ if (flist) { while (flist) { if (alter_access (t, binfo, OVL_FUNCTION (flist), access) == 0) return; flist = OVL_CHAIN (flist); } } else alter_access (t, binfo, fdecl, access); } struct base_info { int has_virtual; int max_has_virtual; tree vfield; tree vfields; tree rtti; char cant_have_default_ctor; char cant_have_const_ctor; char no_const_asn_ref; }; /* Record information about type T derived from its base classes. Store most of that information in T itself, and place the remaining information in the struct BASE_INFO. Propagate basetype offsets throughout the lattice. Note that the lattice topped by T is really a pair: it's a DAG that gives the structure of the derivation hierarchy, and it's a list of the virtual baseclasses that appear anywhere in the DAG. When a vbase type appears in the DAG, it's offset is 0, and it's children start their offsets from that point. When a vbase type appears in the list, its offset is the offset it has in the hierarchy, and its children's offsets include that offset in theirs. Returns the index of the first base class to have virtual functions, or -1 if no such base class. */ static int finish_base_struct (t, b) tree t; struct base_info *b; { tree binfos = TYPE_BINFO_BASETYPES (t); int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0; int first_vfn_base_index = -1; bzero ((char *) b, sizeof (struct base_info)); for (i = 0; i < n_baseclasses; i++) { tree base_binfo = TREE_VEC_ELT (binfos, i); tree basetype = BINFO_TYPE (base_binfo); /* Effective C++ rule 14. We only need to check TYPE_VIRTUAL_P here because the case of virtual functions but non-virtual dtor is handled in finish_struct_1. */ if (warn_ecpp && ! TYPE_VIRTUAL_P (basetype) && TYPE_HAS_DESTRUCTOR (basetype)) cp_warning ("base class `%#T' has a non-virtual destructor", basetype); /* If the type of basetype is incomplete, then we already complained about that fact (and we should have fixed it up as well). */ if (TYPE_SIZE (basetype) == 0) { int j; /* The base type is of incomplete type. It is probably best to pretend that it does not exist. */ if (i == n_baseclasses-1) TREE_VEC_ELT (binfos, i) = NULL_TREE; TREE_VEC_LENGTH (binfos) -= 1; n_baseclasses -= 1; for (j = i; j+1 < n_baseclasses; j++) TREE_VEC_ELT (binfos, j) = TREE_VEC_ELT (binfos, j+1); } if (! TYPE_HAS_CONST_INIT_REF (basetype)) b->cant_have_const_ctor = 1; if (TYPE_HAS_CONSTRUCTOR (basetype) && ! TYPE_HAS_DEFAULT_CONSTRUCTOR (basetype)) { b->cant_have_default_ctor = 1; if (! TYPE_HAS_CONSTRUCTOR (t)) { cp_pedwarn ("base `%T' with only non-default constructor", basetype); cp_pedwarn ("in class without a constructor"); } } if (TYPE_HAS_ASSIGN_REF (basetype) && !TYPE_HAS_CONST_ASSIGN_REF (basetype)) b->no_const_asn_ref = 1; TYPE_NEEDS_CONSTRUCTING (t) |= TYPE_NEEDS_CONSTRUCTING (basetype); TYPE_NEEDS_DESTRUCTOR (t) |= TYPE_NEEDS_DESTRUCTOR (basetype); TYPE_HAS_COMPLEX_ASSIGN_REF (t) |= TYPE_HAS_COMPLEX_ASSIGN_REF (basetype); TYPE_HAS_COMPLEX_INIT_REF (t) |= TYPE_HAS_COMPLEX_INIT_REF (basetype); TYPE_OVERLOADS_CALL_EXPR (t) |= TYPE_OVERLOADS_CALL_EXPR (basetype); TYPE_OVERLOADS_ARRAY_REF (t) |= TYPE_OVERLOADS_ARRAY_REF (basetype); TYPE_OVERLOADS_ARROW (t) |= TYPE_OVERLOADS_ARROW (basetype); if (CLASSTYPE_COM_INTERFACE (basetype)) { CLASSTYPE_COM_INTERFACE (t) = 1; if (i > 0) cp_error ("COM interface type `%T' must be the leftmost base class", basetype); } else if (CLASSTYPE_COM_INTERFACE (t)) { cp_error ("COM interface type `%T' with non-COM base class `%T'", t, basetype); CLASSTYPE_COM_INTERFACE (t) = 0; } if (TYPE_VIRTUAL_P (basetype)) { /* Ensure that this is set from at least a virtual base class. */ if (b->rtti == NULL_TREE) b->rtti = CLASSTYPE_RTTI (basetype); /* Don't borrow virtuals from virtual baseclasses. */ if (TREE_VIA_VIRTUAL (base_binfo)) continue; if (first_vfn_base_index < 0) { tree vfields; first_vfn_base_index = i; /* Update these two, now that we know what vtable we are going to extend. This is so that we can add virtual functions, and override them properly. */ TYPE_BINFO_VTABLE (t) = TYPE_BINFO_VTABLE (basetype); TYPE_BINFO_VIRTUALS (t) = TYPE_BINFO_VIRTUALS (basetype); b->has_virtual = CLASSTYPE_VSIZE (basetype); b->vfield = CLASSTYPE_VFIELD (basetype); b->vfields = copy_list (CLASSTYPE_VFIELDS (basetype)); vfields = b->vfields; while (vfields) { if (VF_BINFO_VALUE (vfields) == NULL_TREE || ! TREE_VIA_VIRTUAL (VF_BINFO_VALUE (vfields))) { tree value = VF_BASETYPE_VALUE (vfields); if (DECL_NAME (CLASSTYPE_VFIELD (value)) == DECL_NAME (CLASSTYPE_VFIELD (basetype))) VF_NORMAL_VALUE (b->vfields) = basetype; else VF_NORMAL_VALUE (b->vfields) = VF_NORMAL_VALUE (vfields); } vfields = TREE_CHAIN (vfields); } CLASSTYPE_VFIELD (t) = b->vfield; } else { /* Only add unique vfields, and flatten them out as we go. */ tree vfields = CLASSTYPE_VFIELDS (basetype); while (vfields) { if (VF_BINFO_VALUE (vfields) == NULL_TREE || ! TREE_VIA_VIRTUAL (VF_BINFO_VALUE (vfields))) { tree value = VF_BASETYPE_VALUE (vfields); b->vfields = tree_cons (base_binfo, value, b->vfields); if (DECL_NAME (CLASSTYPE_VFIELD (value)) == DECL_NAME (CLASSTYPE_VFIELD (basetype))) VF_NORMAL_VALUE (b->vfields) = basetype; else VF_NORMAL_VALUE (b->vfields) = VF_NORMAL_VALUE (vfields); } vfields = TREE_CHAIN (vfields); } if (b->has_virtual == 0) { first_vfn_base_index = i; /* Update these two, now that we know what vtable we are going to extend. This is so that we can add virtual functions, and override them properly. */ TYPE_BINFO_VTABLE (t) = TYPE_BINFO_VTABLE (basetype); TYPE_BINFO_VIRTUALS (t) = TYPE_BINFO_VIRTUALS (basetype); b->has_virtual = CLASSTYPE_VSIZE (basetype); b->vfield = CLASSTYPE_VFIELD (basetype); CLASSTYPE_VFIELD (t) = b->vfield; /* When we install the first one, set the VF_NORMAL_VALUE to be the current class, as this it is the most derived class. Hopefully, this is not set to something else later. (mrs) */ vfields = b->vfields; while (vfields) { if (DECL_NAME (CLASSTYPE_VFIELD (t)) == DECL_NAME (CLASSTYPE_VFIELD (basetype))) { VF_NORMAL_VALUE (vfields) = t; /* There should only be one of them! And it should always be found, if we get into here. (mrs) */ break; } vfields = TREE_CHAIN (vfields); } } } } } { tree vfields; /* Find the base class with the largest number of virtual functions. */ for (vfields = b->vfields; vfields; vfields = TREE_CHAIN (vfields)) { if (CLASSTYPE_VSIZE (VF_BASETYPE_VALUE (vfields)) > b->max_has_virtual) b->max_has_virtual = CLASSTYPE_VSIZE (VF_BASETYPE_VALUE (vfields)); if (VF_DERIVED_VALUE (vfields) && CLASSTYPE_VSIZE (VF_DERIVED_VALUE (vfields)) > b->max_has_virtual) b->max_has_virtual = CLASSTYPE_VSIZE (VF_DERIVED_VALUE (vfields)); } } if (b->vfield == 0) /* If all virtual functions come only from virtual baseclasses. */ return -1; /* Update the rtti base if we have a non-virtual base class version of it. */ b->rtti = CLASSTYPE_RTTI (BINFO_TYPE (TREE_VEC_ELT (binfos, first_vfn_base_index))); return first_vfn_base_index; } /* Set memoizing fields and bits of T (and its variants) for later use. MAX_HAS_VIRTUAL is the largest size of any T's virtual function tables. */ static void finish_struct_bits (t, max_has_virtual) tree t; int max_has_virtual; { int i, n_baseclasses = CLASSTYPE_N_BASECLASSES (t); /* Fix up variants (if any). */ tree variants = TYPE_NEXT_VARIANT (t); while (variants) { /* These fields are in the _TYPE part of the node, not in the TYPE_LANG_SPECIFIC component, so they are not shared. */ TYPE_HAS_CONSTRUCTOR (variants) = TYPE_HAS_CONSTRUCTOR (t); TYPE_HAS_DESTRUCTOR (variants) = TYPE_HAS_DESTRUCTOR (t); TYPE_NEEDS_CONSTRUCTING (variants) = TYPE_NEEDS_CONSTRUCTING (t); TYPE_NEEDS_DESTRUCTOR (variants) = TYPE_NEEDS_DESTRUCTOR (t); TYPE_USES_COMPLEX_INHERITANCE (variants) = TYPE_USES_COMPLEX_INHERITANCE (t); TYPE_VIRTUAL_P (variants) = TYPE_VIRTUAL_P (t); TYPE_USES_VIRTUAL_BASECLASSES (variants) = TYPE_USES_VIRTUAL_BASECLASSES (t); + TYPE_USES_PVBASES (variants) = TYPE_USES_PVBASES (t); /* Copy whatever these are holding today. */ TYPE_MIN_VALUE (variants) = TYPE_MIN_VALUE (t); TYPE_MAX_VALUE (variants) = TYPE_MAX_VALUE (t); TYPE_FIELDS (variants) = TYPE_FIELDS (t); TYPE_SIZE (variants) = TYPE_SIZE (t); TYPE_SIZE_UNIT (variants) = TYPE_SIZE_UNIT (t); variants = TYPE_NEXT_VARIANT (variants); } if (n_baseclasses && max_has_virtual) { /* For a class w/o baseclasses, `finish_struct' has set CLASS_TYPE_ABSTRACT_VIRTUALS correctly (by definition). Similarly for a class who's base classes do not have vtables. When neither of these is true, we might have removed abstract virtuals (by providing a definition), added some (by declaring new ones), or redeclared ones from a base class. We need to recalculate what's really an abstract virtual at this point (by looking in the vtables). */ CLASSTYPE_ABSTRACT_VIRTUALS (t) = get_abstract_virtuals (t); } if (n_baseclasses) { /* Notice whether this class has type conversion functions defined. */ tree binfo = TYPE_BINFO (t); tree binfos = BINFO_BASETYPES (binfo); tree basetype; for (i = n_baseclasses-1; i >= 0; i--) { basetype = BINFO_TYPE (TREE_VEC_ELT (binfos, i)); TYPE_HAS_CONVERSION (t) |= TYPE_HAS_CONVERSION (basetype); } } /* If this type has a copy constructor, force its mode to be BLKmode, and force its TREE_ADDRESSABLE bit to be nonzero. This will cause it to be passed by invisible reference and prevent it from being returned in a register. Also do this if the class has BLKmode but can still be returned in registers, since function_cannot_inline_p won't let us inline functions returning such a type. This affects the HP-PA. */ if (! TYPE_HAS_TRIVIAL_INIT_REF (t) || (TYPE_MODE (t) == BLKmode && ! aggregate_value_p (t) && CLASSTYPE_NON_AGGREGATE (t))) { tree variants; DECL_MODE (TYPE_MAIN_DECL (t)) = BLKmode; for (variants = t; variants; variants = TYPE_NEXT_VARIANT (variants)) { TYPE_MODE (variants) = BLKmode; TREE_ADDRESSABLE (variants) = 1; } } } /* Issue warnings about T having private constructors, but no friends, and so forth. HAS_NONPRIVATE_METHOD is nonzero if T has any non-private methods or static members. HAS_NONPRIVATE_STATIC_FN is nonzero if T has any non-private static member functions. */ static void maybe_warn_about_overly_private_class (t) tree t; { int has_member_fn = 0; int has_nonprivate_method = 0; tree fn; if (!warn_ctor_dtor_privacy /* If the class has friends, those entities might create and access instances, so we should not warn. */ || (CLASSTYPE_FRIEND_CLASSES (t) || DECL_FRIENDLIST (TYPE_MAIN_DECL (t))) /* We will have warned when the template was declared; there's no need to warn on every instantiation. */ || CLASSTYPE_TEMPLATE_INSTANTIATION (t)) /* There's no reason to even consider warning about this class. */ return; /* We only issue one warning, if more than one applies, because otherwise, on code like: class A { // Oops - forgot `public:' A(); A(const A&); ~A(); }; we warn several times about essentially the same problem. */ /* Check to see if all (non-constructor, non-destructor) member functions are private. (Since there are no friends or non-private statics, we can't ever call any of the private member functions.) */ for (fn = TYPE_METHODS (t); fn; fn = TREE_CHAIN (fn)) /* We're not interested in compiler-generated methods; they don't provide any way to call private members. */ if (!DECL_ARTIFICIAL (fn)) { if (!TREE_PRIVATE (fn)) { if (DECL_STATIC_FUNCTION_P (fn)) /* A non-private static member function is just like a friend; it can create and invoke private member functions, and be accessed without a class instance. */ return; has_nonprivate_method = 1; break; } else if (!DECL_CONSTRUCTOR_P (fn) && !DECL_DESTRUCTOR_P (fn)) has_member_fn = 1; } if (!has_nonprivate_method && has_member_fn) { /* There are no non-private methods, and there's at least one private member function that isn't a constructor or destructor. (If all the private members are constructors/destructors we want to use the code below that issues error messages specifically referring to constructors/destructors.) */ int i; tree binfos = BINFO_BASETYPES (TYPE_BINFO (t)); for (i = 0; i < CLASSTYPE_N_BASECLASSES (t); i++) if (TREE_VIA_PUBLIC (TREE_VEC_ELT (binfos, i)) || TREE_VIA_PROTECTED (TREE_VEC_ELT (binfos, i))) { has_nonprivate_method = 1; break; } if (!has_nonprivate_method) { cp_warning ("all member functions in class `%T' are private", t); return; } } /* Even if some of the member functions are non-private, the class won't be useful for much if all the constructors or destructors are private: such an object can never be created or destroyed. */ if (TYPE_HAS_DESTRUCTOR (t)) { tree dtor = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (t), 1); if (TREE_PRIVATE (dtor)) { cp_warning ("`%#T' only defines a private destructor and has no friends", t); return; } } if (TYPE_HAS_CONSTRUCTOR (t)) { int nonprivate_ctor = 0; /* If a non-template class does not define a copy constructor, one is defined for it, enabling it to avoid this warning. For a template class, this does not happen, and so we would normally get a warning on: template class C { private: C(); }; To avoid this asymmetry, we check TYPE_HAS_INIT_REF. All complete non-template or fully instantiated classes have this flag set. */ if (!TYPE_HAS_INIT_REF (t)) nonprivate_ctor = 1; else for (fn = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (t), 0); fn; fn = OVL_NEXT (fn)) { tree ctor = OVL_CURRENT (fn); /* Ideally, we wouldn't count copy constructors (or, in fact, any constructor that takes an argument of the class type as a parameter) because such things cannot be used to construct an instance of the class unless you already have one. But, for now at least, we're more generous. */ if (! TREE_PRIVATE (ctor)) { nonprivate_ctor = 1; break; } } if (nonprivate_ctor == 0) { cp_warning ("`%#T' only defines private constructors and has no friends", t); return; } } } /* Warn about duplicate methods in fn_fields. Also compact method lists so that lookup can be made faster. Data Structure: List of method lists. The outer list is a TREE_LIST, whose TREE_PURPOSE field is the field name and the TREE_VALUE is the DECL_CHAIN of the FUNCTION_DECLs. TREE_CHAIN links the entire list of methods for TYPE_METHODS. Friends are chained in the same way as member functions (? TREE_CHAIN or DECL_CHAIN), but they live in the TREE_TYPE field of the outer list. That allows them to be quickly deleted, and requires no extra storage. If there are any constructors/destructors, they are moved to the front of the list. This makes pushclass more efficient. We also link each field which has shares a name with its baseclass to the head of the list of fields for that base class. This allows us to reduce search time in places like `build_method_call' to consider only reasonably likely functions. */ static void finish_struct_methods (t) tree t; { tree fn_fields; tree method_vec = CLASSTYPE_METHOD_VEC (t); tree ctor_name = constructor_name (t); /* First fill in entry 0 with the constructors, entry 1 with destructors, and the next few with type conversion operators (if any). */ for (fn_fields = TYPE_METHODS (t); fn_fields; fn_fields = TREE_CHAIN (fn_fields)) { tree fn_name = DECL_NAME (fn_fields); /* Clear out this flag. @@ Doug may figure out how to break @@ this with nested classes and friends. */ DECL_IN_AGGR_P (fn_fields) = 0; /* Note here that a copy ctor is private, so we don't dare generate a default copy constructor for a class that has a member of this type without making sure they have access to it. */ if (fn_name == ctor_name) { tree parmtypes = FUNCTION_ARG_CHAIN (fn_fields); tree parmtype = parmtypes ? TREE_VALUE (parmtypes) : void_type_node; if (TREE_CODE (parmtype) == REFERENCE_TYPE && TYPE_MAIN_VARIANT (TREE_TYPE (parmtype)) == t) { if (TREE_CHAIN (parmtypes) == NULL_TREE || TREE_CHAIN (parmtypes) == void_list_node || TREE_PURPOSE (TREE_CHAIN (parmtypes))) { if (TREE_PROTECTED (fn_fields)) TYPE_HAS_NONPUBLIC_CTOR (t) = 1; else if (TREE_PRIVATE (fn_fields)) TYPE_HAS_NONPUBLIC_CTOR (t) = 2; } } } else if (fn_name == ansi_opname[(int) MODIFY_EXPR]) { tree parmtype = TREE_VALUE (FUNCTION_ARG_CHAIN (fn_fields)); if (copy_assignment_arg_p (parmtype, DECL_VIRTUAL_P (fn_fields))) { if (TREE_PROTECTED (fn_fields)) TYPE_HAS_NONPUBLIC_ASSIGN_REF (t) = 1; else if (TREE_PRIVATE (fn_fields)) TYPE_HAS_NONPUBLIC_ASSIGN_REF (t) = 2; } } } if (TYPE_HAS_DESTRUCTOR (t) && !TREE_VEC_ELT (method_vec, 1)) /* We thought there was a destructor, but there wasn't. Some parse errors cause this anomalous situation. */ TYPE_HAS_DESTRUCTOR (t) = 0; /* Issue warnings about private constructors and such. If there are no methods, then some public defaults are generated. */ maybe_warn_about_overly_private_class (t); } /* Emit error when a duplicate definition of a type is seen. Patch up. */ void duplicate_tag_error (t) tree t; { cp_error ("redefinition of `%#T'", t); cp_error_at ("previous definition here", t); /* Pretend we haven't defined this type. */ /* All of the component_decl's were TREE_CHAINed together in the parser. finish_struct_methods walks these chains and assembles all methods with the same base name into DECL_CHAINs. Now we don't need the parser chains anymore, so we unravel them. */ /* This used to be in finish_struct, but it turns out that the TREE_CHAIN is used by dbxout_type_methods and perhaps some other things... */ if (CLASSTYPE_METHOD_VEC (t)) { tree method_vec = CLASSTYPE_METHOD_VEC (t); int i, len = TREE_VEC_LENGTH (method_vec); for (i = 0; i < len; i++) { tree unchain = TREE_VEC_ELT (method_vec, i); while (unchain != NULL_TREE) { TREE_CHAIN (OVL_CURRENT (unchain)) = NULL_TREE; unchain = OVL_NEXT (unchain); } } } if (TYPE_LANG_SPECIFIC (t)) { tree binfo = TYPE_BINFO (t); int interface_only = CLASSTYPE_INTERFACE_ONLY (t); int interface_unknown = CLASSTYPE_INTERFACE_UNKNOWN (t); bzero ((char *) TYPE_LANG_SPECIFIC (t), sizeof (struct lang_type)); BINFO_BASETYPES(binfo) = NULL_TREE; TYPE_BINFO (t) = binfo; CLASSTYPE_INTERFACE_ONLY (t) = interface_only; SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown); TYPE_REDEFINED (t) = 1; } TYPE_SIZE (t) = NULL_TREE; TYPE_MODE (t) = VOIDmode; TYPE_FIELDS (t) = NULL_TREE; TYPE_METHODS (t) = NULL_TREE; TYPE_VFIELD (t) = NULL_TREE; TYPE_CONTEXT (t) = NULL_TREE; } /* finish up all new vtables. */ static void finish_vtbls (binfo, do_self, t) tree binfo; int do_self; tree t; { tree binfos = BINFO_BASETYPES (binfo); int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0; /* Should we use something besides CLASSTYPE_VFIELDS? */ if (do_self && CLASSTYPE_VFIELDS (BINFO_TYPE (binfo))) { if (BINFO_NEW_VTABLE_MARKED (binfo)) { tree decl, context; decl = BINFO_VTABLE (binfo); context = DECL_CONTEXT (decl); DECL_CONTEXT (decl) = 0; if (DECL_INITIAL (decl) != BINFO_VIRTUALS (binfo)) DECL_INITIAL (decl) = build_nt (CONSTRUCTOR, NULL_TREE, BINFO_VIRTUALS (binfo)); cp_finish_decl (decl, DECL_INITIAL (decl), NULL_TREE, 0, 0); DECL_CONTEXT (decl) = context; } CLEAR_BINFO_NEW_VTABLE_MARKED (binfo); } for (i = 0; i < n_baselinks; i++) { tree base_binfo = TREE_VEC_ELT (binfos, i); int is_not_base_vtable = i != CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo)); if (TREE_VIA_VIRTUAL (base_binfo)) { base_binfo = binfo_member (BINFO_TYPE (base_binfo), CLASSTYPE_VBASECLASSES (t)); } finish_vtbls (base_binfo, is_not_base_vtable, t); } } /* True if we should override the given BASE_FNDECL with the given FNDECL. */ static int overrides (fndecl, base_fndecl) tree fndecl, base_fndecl; { /* Destructors have special names. */ if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (base_fndecl)) && DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (fndecl))) return 1; if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (base_fndecl)) || DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (fndecl))) return 0; if (DECL_NAME (fndecl) == DECL_NAME (base_fndecl)) { tree types, base_types; #if 0 retypes = TREE_TYPE (TREE_TYPE (fndecl)); base_retypes = TREE_TYPE (TREE_TYPE (base_fndecl)); #endif types = TYPE_ARG_TYPES (TREE_TYPE (fndecl)); base_types = TYPE_ARG_TYPES (TREE_TYPE (base_fndecl)); if ((TYPE_QUALS (TREE_TYPE (TREE_VALUE (base_types))) == TYPE_QUALS (TREE_TYPE (TREE_VALUE (types)))) && compparms (TREE_CHAIN (base_types), TREE_CHAIN (types))) return 1; } return 0; } static tree get_class_offset_1 (parent, binfo, context, t, fndecl) tree parent, binfo, context, t, fndecl; { tree binfos = BINFO_BASETYPES (binfo); int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0; tree rval = NULL_TREE; if (binfo == parent) return error_mark_node; for (i = 0; i < n_baselinks; i++) { tree base_binfo = TREE_VEC_ELT (binfos, i); tree nrval; if (TREE_VIA_VIRTUAL (base_binfo)) base_binfo = binfo_member (BINFO_TYPE (base_binfo), CLASSTYPE_VBASECLASSES (t)); nrval = get_class_offset_1 (parent, base_binfo, context, t, fndecl); /* See if we have a new value */ if (nrval && (nrval != error_mark_node || rval==0)) { /* Only compare if we have two offsets */ if (rval && rval != error_mark_node && ! tree_int_cst_equal (nrval, rval)) { /* Only give error if the two offsets are different */ error ("every virtual function must have a unique final overrider"); cp_error (" found two (or more) `%T' class subobjects in `%T'", context, t); cp_error (" with virtual `%D' from virtual base class", fndecl); return rval; } rval = nrval; } if (rval && BINFO_TYPE (binfo) == context) { my_friendly_assert (rval == error_mark_node || tree_int_cst_equal (rval, BINFO_OFFSET (binfo)), 999); rval = BINFO_OFFSET (binfo); } } return rval; } /* Get the offset to the CONTEXT subobject that is related to the given BINFO. */ static tree get_class_offset (context, t, binfo, fndecl) tree context, t, binfo, fndecl; { tree first_binfo = binfo; tree offset; int i; if (context == t) return integer_zero_node; if (BINFO_TYPE (binfo) == context) return BINFO_OFFSET (binfo); /* Check less derived binfos first. */ while (BINFO_BASETYPES (binfo) && (i=CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo))) != -1) { tree binfos = BINFO_BASETYPES (binfo); binfo = TREE_VEC_ELT (binfos, i); if (BINFO_TYPE (binfo) == context) return BINFO_OFFSET (binfo); } /* Ok, not found in the less derived binfos, now check the more derived binfos. */ offset = get_class_offset_1 (first_binfo, TYPE_BINFO (t), context, t, fndecl); if (offset==0 || TREE_CODE (offset) != INTEGER_CST) my_friendly_abort (999); /* we have to find it. */ return offset; } /* Skip RTTI information at the front of the virtual list. */ unsigned HOST_WIDE_INT skip_rtti_stuff (virtuals, t) tree *virtuals, t; { int n; if (CLASSTYPE_COM_INTERFACE (t)) return 0; n = 0; if (*virtuals) { /* We always reserve a slot for the offset/tdesc entry. */ ++n; *virtuals = TREE_CHAIN (*virtuals); } if (flag_vtable_thunks && *virtuals) { /* The second slot is reserved for the tdesc pointer when thunks are used. */ ++n; *virtuals = TREE_CHAIN (*virtuals); } return n; } static void modify_one_vtable (binfo, t, fndecl, pfn) tree binfo, t, fndecl, pfn; { tree virtuals = BINFO_VIRTUALS (binfo); unsigned HOST_WIDE_INT n; /* update rtti entry */ if (flag_rtti) { if (binfo == TYPE_BINFO (t)) { if (! BINFO_NEW_VTABLE_MARKED (binfo)) build_vtable (TYPE_BINFO (DECL_CONTEXT (CLASSTYPE_VFIELD (t))), t); } else { if (! BINFO_NEW_VTABLE_MARKED (binfo)) prepare_fresh_vtable (binfo, t); } } if (fndecl == NULL_TREE) return; n = skip_rtti_stuff (&virtuals, t); while (virtuals) { tree current_fndecl = TREE_VALUE (virtuals); current_fndecl = FNADDR_FROM_VTABLE_ENTRY (current_fndecl); current_fndecl = TREE_OPERAND (current_fndecl, 0); if (current_fndecl && overrides (fndecl, current_fndecl)) { tree base_offset, offset; tree context = DECL_CLASS_CONTEXT (fndecl); tree vfield = CLASSTYPE_VFIELD (t); tree this_offset; offset = get_class_offset (context, t, binfo, fndecl); /* Find the right offset for the this pointer based on the base class we just found. We have to take into consideration the virtual base class pointers that we stick in before the virtual function table pointer. Also, we want just the delta between the most base class that we derived this vfield from and us. */ base_offset = size_binop (PLUS_EXPR, get_derived_offset (binfo, DECL_CONTEXT (current_fndecl)), BINFO_OFFSET (binfo)); this_offset = ssize_binop (MINUS_EXPR, offset, base_offset); if (binfo == TYPE_BINFO (t)) { /* In this case, it is *type*'s vtable we are modifying. We start with the approximation that it's vtable is that of the immediate base class. */ if (! BINFO_NEW_VTABLE_MARKED (binfo)) build_vtable (TYPE_BINFO (DECL_CONTEXT (vfield)), t); } else { /* This is our very own copy of `basetype' to play with. Later, we will fill in all the virtual functions that override the virtual functions in these base classes which are not defined by the current type. */ if (! BINFO_NEW_VTABLE_MARKED (binfo)) prepare_fresh_vtable (binfo, t); } #ifdef NOTQUITE cp_warning ("in %D", DECL_NAME (BINFO_VTABLE (binfo))); #endif modify_vtable_entry (get_vtable_entry_n (BINFO_VIRTUALS (binfo), n), build_vtable_entry (this_offset, pfn), fndecl); } ++n; virtuals = TREE_CHAIN (virtuals); } } /* These are the ones that are not through virtual base classes. */ static void modify_all_direct_vtables (binfo, do_self, t, fndecl, pfn) tree binfo; int do_self; tree t, fndecl, pfn; { tree binfos = BINFO_BASETYPES (binfo); int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0; /* Should we use something besides CLASSTYPE_VFIELDS? */ if (do_self && CLASSTYPE_VFIELDS (BINFO_TYPE (binfo))) { modify_one_vtable (binfo, t, fndecl, pfn); } for (i = 0; i < n_baselinks; i++) { tree base_binfo = TREE_VEC_ELT (binfos, i); int is_not_base_vtable = i != CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo)); if (! TREE_VIA_VIRTUAL (base_binfo)) modify_all_direct_vtables (base_binfo, is_not_base_vtable, t, fndecl, pfn); } } /* Fixup all the delta entries in this one vtable that need updating. */ static void fixup_vtable_deltas1 (binfo, t) tree binfo, t; { tree virtuals = BINFO_VIRTUALS (binfo); unsigned HOST_WIDE_INT n; n = skip_rtti_stuff (&virtuals, t); while (virtuals) { tree fndecl = TREE_VALUE (virtuals); tree pfn = FNADDR_FROM_VTABLE_ENTRY (fndecl); tree delta = DELTA_FROM_VTABLE_ENTRY (fndecl); fndecl = TREE_OPERAND (pfn, 0); if (fndecl) { tree base_offset, offset; tree context = DECL_CLASS_CONTEXT (fndecl); tree vfield = CLASSTYPE_VFIELD (t); tree this_offset; offset = get_class_offset (context, t, binfo, fndecl); /* Find the right offset for the this pointer based on the base class we just found. We have to take into consideration the virtual base class pointers that we stick in before the virtual function table pointer. Also, we want just the delta between the most base class that we derived this vfield from and us. */ base_offset = size_binop (PLUS_EXPR, get_derived_offset (binfo, DECL_CONTEXT (fndecl)), BINFO_OFFSET (binfo)); this_offset = ssize_binop (MINUS_EXPR, offset, base_offset); if (! tree_int_cst_equal (this_offset, delta)) { /* Make sure we can modify the derived association with immunity. */ if (binfo == TYPE_BINFO (t)) { /* In this case, it is *type*'s vtable we are modifying. We start with the approximation that it's vtable is that of the immediate base class. */ if (! BINFO_NEW_VTABLE_MARKED (binfo)) build_vtable (TYPE_BINFO (DECL_CONTEXT (vfield)), t); } else { /* This is our very own copy of `basetype' to play with. Later, we will fill in all the virtual functions that override the virtual functions in these base classes which are not defined by the current type. */ if (! BINFO_NEW_VTABLE_MARKED (binfo)) prepare_fresh_vtable (binfo, t); } modify_vtable_entry (get_vtable_entry_n (BINFO_VIRTUALS (binfo), n), build_vtable_entry (this_offset, pfn), fndecl); } } ++n; virtuals = TREE_CHAIN (virtuals); } } /* Fixup all the delta entries in all the direct vtables that need updating. This happens when we have non-overridden virtual functions from a virtual base class, that are at a different offset, in the new hierarchy, because the layout of the virtual bases has changed. */ static void fixup_vtable_deltas (binfo, init_self, t) tree binfo; int init_self; tree t; { tree binfos = BINFO_BASETYPES (binfo); int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0; for (i = 0; i < n_baselinks; i++) { tree base_binfo = TREE_VEC_ELT (binfos, i); int is_not_base_vtable = i != CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo)); if (! TREE_VIA_VIRTUAL (base_binfo)) fixup_vtable_deltas (base_binfo, is_not_base_vtable, t); } /* Should we use something besides CLASSTYPE_VFIELDS? */ if (init_self && CLASSTYPE_VFIELDS (BINFO_TYPE (binfo))) { fixup_vtable_deltas1 (binfo, t); } } /* These are the ones that are through virtual base classes. */ static void modify_all_indirect_vtables (binfo, do_self, via_virtual, t, fndecl, pfn) tree binfo; int do_self, via_virtual; tree t, fndecl, pfn; { tree binfos = BINFO_BASETYPES (binfo); int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0; /* Should we use something besides CLASSTYPE_VFIELDS? */ if (do_self && via_virtual && CLASSTYPE_VFIELDS (BINFO_TYPE (binfo))) { modify_one_vtable (binfo, t, fndecl, pfn); } for (i = 0; i < n_baselinks; i++) { tree base_binfo = TREE_VEC_ELT (binfos, i); int is_not_base_vtable = i != CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo)); if (TREE_VIA_VIRTUAL (base_binfo)) { via_virtual = 1; base_binfo = binfo_member (BINFO_TYPE (base_binfo), CLASSTYPE_VBASECLASSES (t)); } modify_all_indirect_vtables (base_binfo, is_not_base_vtable, via_virtual, t, fndecl, pfn); } } static void modify_all_vtables (t, fndecl, vfn) tree t, fndecl, vfn; { /* Do these first, so that we will make use of any non-virtual class's vtable, over a virtual classes vtable. */ modify_all_direct_vtables (TYPE_BINFO (t), 1, t, fndecl, vfn); if (TYPE_USES_VIRTUAL_BASECLASSES (t)) modify_all_indirect_vtables (TYPE_BINFO (t), 1, 0, t, fndecl, vfn); } /* Here, we already know that they match in every respect. All we have to check is where they had their declarations. */ static int strictly_overrides (fndecl1, fndecl2) tree fndecl1, fndecl2; { int distance = get_base_distance (DECL_CLASS_CONTEXT (fndecl2), DECL_CLASS_CONTEXT (fndecl1), 0, (tree *)0); if (distance == -2 || distance > 0) return 1; return 0; } /* Merge overrides for one vtable. If we want to merge in same function, we are fine. else if one has a DECL_CLASS_CONTEXT that is a parent of the other, than choose the more derived one else potentially ill-formed (see 10.3 [class.virtual]) we have to check later to see if there was an override in this class. If there was ok, if not then it is ill-formed. (mrs) We take special care to reuse a vtable, if we can. */ static void override_one_vtable (binfo, old, t) tree binfo, old, t; { tree virtuals = BINFO_VIRTUALS (binfo); tree old_virtuals = BINFO_VIRTUALS (old); enum { REUSE_NEW, REUSE_OLD, UNDECIDED, NEITHER } choose = UNDECIDED; /* If we have already committed to modifying it, then don't try and reuse another vtable. */ if (BINFO_NEW_VTABLE_MARKED (binfo)) choose = NEITHER; skip_rtti_stuff (&virtuals, t); skip_rtti_stuff (&old_virtuals, t); while (virtuals) { tree fndecl = TREE_VALUE (virtuals); tree old_fndecl = TREE_VALUE (old_virtuals); fndecl = FNADDR_FROM_VTABLE_ENTRY (fndecl); old_fndecl = FNADDR_FROM_VTABLE_ENTRY (old_fndecl); fndecl = TREE_OPERAND (fndecl, 0); old_fndecl = TREE_OPERAND (old_fndecl, 0); /* First check to see if they are the same. */ if (DECL_ASSEMBLER_NAME (fndecl) == DECL_ASSEMBLER_NAME (old_fndecl)) { /* No need to do anything. */ } else if (strictly_overrides (fndecl, old_fndecl)) { if (choose == UNDECIDED) choose = REUSE_NEW; else if (choose == REUSE_OLD) { choose = NEITHER; if (! BINFO_NEW_VTABLE_MARKED (binfo)) { prepare_fresh_vtable (binfo, t); override_one_vtable (binfo, old, t); return; } } } else if (strictly_overrides (old_fndecl, fndecl)) { if (choose == UNDECIDED) choose = REUSE_OLD; else if (choose == REUSE_NEW) { choose = NEITHER; if (! BINFO_NEW_VTABLE_MARKED (binfo)) { prepare_fresh_vtable (binfo, t); override_one_vtable (binfo, old, t); return; } TREE_VALUE (virtuals) = TREE_VALUE (old_virtuals); } else if (choose == NEITHER) { TREE_VALUE (virtuals) = TREE_VALUE (old_virtuals); } } else { choose = NEITHER; if (! BINFO_NEW_VTABLE_MARKED (binfo)) { prepare_fresh_vtable (binfo, t); override_one_vtable (binfo, old, t); return; } { /* This MUST be overridden, or the class is ill-formed. */ tree fndecl = TREE_OPERAND (FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (virtuals)), 0); tree vfn; fndecl = copy_node (fndecl); copy_lang_decl (fndecl); DECL_NEEDS_FINAL_OVERRIDER_P (fndecl) = 1; /* Make sure we search for it later. */ if (! CLASSTYPE_ABSTRACT_VIRTUALS (t)) CLASSTYPE_ABSTRACT_VIRTUALS (t) = error_mark_node; vfn = build1 (ADDR_EXPR, vfunc_ptr_type_node, fndecl); TREE_CONSTANT (vfn) = 1; /* We can use integer_zero_node, as we will core dump if this is used anyway. */ TREE_VALUE (virtuals) = build_vtable_entry (integer_zero_node, vfn); } } virtuals = TREE_CHAIN (virtuals); old_virtuals = TREE_CHAIN (old_virtuals); } /* Let's reuse the old vtable. */ if (choose == REUSE_OLD) { BINFO_VTABLE (binfo) = BINFO_VTABLE (old); BINFO_VIRTUALS (binfo) = BINFO_VIRTUALS (old); } } /* Merge in overrides for virtual bases. BINFO is the hierarchy we want to modify, and OLD has the potential overrides. */ static void merge_overrides (binfo, old, do_self, t) tree binfo, old; int do_self; tree t; { tree binfos = BINFO_BASETYPES (binfo); tree old_binfos = BINFO_BASETYPES (old); int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0; /* Should we use something besides CLASSTYPE_VFIELDS? */ if (do_self && CLASSTYPE_VFIELDS (BINFO_TYPE (binfo))) { override_one_vtable (binfo, old, t); } for (i = 0; i < n_baselinks; i++) { tree base_binfo = TREE_VEC_ELT (binfos, i); tree old_base_binfo = TREE_VEC_ELT (old_binfos, i); int is_not_base_vtable = i != CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo)); if (! TREE_VIA_VIRTUAL (base_binfo)) merge_overrides (base_binfo, old_base_binfo, is_not_base_vtable, t); } } /* Get the base virtual function declarations in T that are either overridden or hidden by FNDECL as a list. We set TREE_PURPOSE with the overrider/hider. */ static tree get_basefndecls (fndecl, t) tree fndecl, t; { tree methods = TYPE_METHODS (t); tree base_fndecls = NULL_TREE; tree binfos = BINFO_BASETYPES (TYPE_BINFO (t)); int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0; while (methods) { if (TREE_CODE (methods) == FUNCTION_DECL && DECL_VINDEX (methods) != NULL_TREE && DECL_NAME (fndecl) == DECL_NAME (methods)) base_fndecls = temp_tree_cons (fndecl, methods, base_fndecls); methods = TREE_CHAIN (methods); } if (base_fndecls) return base_fndecls; for (i = 0; i < n_baseclasses; i++) { tree base_binfo = TREE_VEC_ELT (binfos, i); tree basetype = BINFO_TYPE (base_binfo); base_fndecls = chainon (get_basefndecls (fndecl, basetype), base_fndecls); } return base_fndecls; } /* Mark the functions that have been hidden with their overriders. Since we start out with all functions already marked with a hider, no need to mark functions that are just hidden. Subroutine of warn_hidden. */ static void mark_overriders (fndecl, base_fndecls) tree fndecl, base_fndecls; { for (; base_fndecls; base_fndecls = TREE_CHAIN (base_fndecls)) { if (overrides (fndecl, TREE_VALUE (base_fndecls))) TREE_PURPOSE (base_fndecls) = fndecl; } } /* If this declaration supersedes the declaration of a method declared virtual in the base class, then mark this field as being virtual as well. */ static void check_for_override (decl, ctype) tree decl, ctype; { tree binfos = BINFO_BASETYPES (TYPE_BINFO (ctype)); int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0; int virtualp = DECL_VIRTUAL_P (decl); int found_overriden_fn = 0; for (i = 0; i < n_baselinks; i++) { tree base_binfo = TREE_VEC_ELT (binfos, i); if (TYPE_VIRTUAL_P (BINFO_TYPE (base_binfo))) { tree tmp = get_matching_virtual (base_binfo, decl, DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (decl))); if (tmp && !found_overriden_fn) { /* If this function overrides some virtual in some base class, then the function itself is also necessarily virtual, even if the user didn't explicitly say so. */ DECL_VIRTUAL_P (decl) = 1; /* The TMP we really want is the one from the deepest baseclass on this path, taking care not to duplicate if we have already found it (via another path to its virtual baseclass. */ if (TREE_CODE (TREE_TYPE (decl)) == FUNCTION_TYPE) { cp_error_at ("method `%D' may not be declared static", decl); cp_error_at ("(since `%D' declared virtual in base class.)", tmp); break; } virtualp = 1; DECL_VINDEX (decl) = tree_cons (NULL_TREE, tmp, DECL_VINDEX (decl)); /* We now know that DECL overrides something, which is all that is important. But, we must continue to iterate through all the base-classes in order to allow get_matching_virtual to check for various illegal overrides. */ found_overriden_fn = 1; } } } if (virtualp) { if (DECL_VINDEX (decl) == NULL_TREE) DECL_VINDEX (decl) = error_mark_node; IDENTIFIER_VIRTUAL_P (DECL_NAME (decl)) = 1; } } /* Warn about hidden virtual functions that are not overridden in t. We know that constructors and destructors don't apply. */ void warn_hidden (t) tree t; { tree method_vec = CLASSTYPE_METHOD_VEC (t); int n_methods = method_vec ? TREE_VEC_LENGTH (method_vec) : 0; int i; /* We go through each separately named virtual function. */ for (i = 2; i < n_methods && TREE_VEC_ELT (method_vec, i); ++i) { tree fns = TREE_VEC_ELT (method_vec, i); tree fndecl; tree base_fndecls = NULL_TREE; tree binfos = BINFO_BASETYPES (TYPE_BINFO (t)); int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0; /* First see if we have any virtual functions in this batch. */ for (; fns; fns = OVL_NEXT (fns)) { fndecl = OVL_CURRENT (fns); if (DECL_VINDEX (fndecl)) break; } if (fns == NULL_TREE) continue; /* First we get a list of all possible functions that might be hidden from each base class. */ for (i = 0; i < n_baseclasses; i++) { tree base_binfo = TREE_VEC_ELT (binfos, i); tree basetype = BINFO_TYPE (base_binfo); base_fndecls = chainon (get_basefndecls (fndecl, basetype), base_fndecls); } fns = OVL_NEXT (fns); /* ...then mark up all the base functions with overriders, preferring overriders to hiders. */ if (base_fndecls) for (; fns; fns = OVL_NEXT (fns)) { fndecl = OVL_CURRENT (fns); if (DECL_VINDEX (fndecl)) mark_overriders (fndecl, base_fndecls); } /* Now give a warning for all base functions without overriders, as they are hidden. */ for (; base_fndecls; base_fndecls = TREE_CHAIN (base_fndecls)) { if (! overrides (TREE_PURPOSE (base_fndecls), TREE_VALUE (base_fndecls))) { /* Here we know it is a hider, and no overrider exists. */ cp_warning_at ("`%D' was hidden", TREE_VALUE (base_fndecls)); cp_warning_at (" by `%D'", TREE_PURPOSE (base_fndecls)); } } } } +/* Generate one vtable for use in constructors or destructors of BASE + subobjects of COMPLETE_TYPE objects. The vtable belongs to the + vfield of the VBASEVASE subobject of the VBASE virtual base of + COMPLETE_TYPE (and BASE). */ + +static tree +finish_one_ctor_vtable (complete_type, base, vbase, vbasebase) + tree complete_type, base, vbase, vbasebase; +{ + tree virtuals; + tree newtable; + tree newvirtuals; + tree offset; + tree newvbase = binfo_member (BINFO_TYPE (vbase), + CLASSTYPE_VBASECLASSES (complete_type)); + + newtable = prepare_ctor_vtable (complete_type, base, vbasebase); + newvirtuals = copy_list (BINFO_VIRTUALS (vbasebase)); + + virtuals = newvirtuals; + /* Change the offset entry. First, delta between base an vbase. */ + offset = ssize_binop (MINUS_EXPR, BINFO_OFFSET (newvbase), + BINFO_OFFSET (base)); + /* Add delta between vbase and vbasebase. */ + offset = ssize_binop (PLUS_EXPR, offset, BINFO_OFFSET (vbasebase)); + offset = ssize_binop (MINUS_EXPR, offset, BINFO_OFFSET (vbase)); + /* Finally, negate. */ + offset = ssize_binop (MINUS_EXPR, integer_zero_node, offset); + offset = build1 (NOP_EXPR, vfunc_ptr_type_node, offset); + TREE_CONSTANT (offset) = 1; + TREE_VALUE (virtuals) = build_vtable_entry (integer_zero_node, offset); + virtuals = TREE_CHAIN (virtuals); + + /* Skip the typeinfo function. */ + virtuals = TREE_CHAIN (virtuals); + + /* Iterate over all methods of this virtual base. */ + for (; virtuals; virtuals = TREE_CHAIN (virtuals)) + { + tree fndecl = TREE_VALUE (virtuals); + tree pfn = FNADDR_FROM_VTABLE_ENTRY (fndecl); + fndecl = TREE_OPERAND (pfn, 0); + if (fndecl) + { + tree delta, newdelta, binfo_context; + tree context = DECL_CLASS_CONTEXT (fndecl); + + /* If this method is implemented in a base of the vbase, the + thunk we have is correct. */ + if (DERIVED_FROM_P (context, vbase)) + continue; + + binfo_context = binfo_value (context, base); + if (TREE_VIA_VIRTUAL (binfo_context)) + binfo_context = binfo_member + (context, CLASSTYPE_VBASECLASSES (complete_type)); + /* This is the delta from a complete C to a B subobject, or + more generally to the base subobject that implements the + virtual function for B. BASE already has the offset to + the complete type. */ + delta = BINFO_OFFSET (binfo_context); + /* This is the delta from the A to the complete C. */ + newdelta = BINFO_OFFSET (newvbase); + /* This is the delta from the A to the B subobject. */ + newdelta = size_binop (MINUS_EXPR, newdelta, delta); + newdelta = ssize_binop (MINUS_EXPR, integer_zero_node, + newdelta); + + modify_vtable_entry (virtuals, + build_vtable_entry (newdelta, pfn), + fndecl); + } + } + DECL_INITIAL (newtable) = build_nt (CONSTRUCTOR, NULL_TREE, + newvirtuals); + DECL_CONTEXT (newtable) = NULL_TREE; + cp_finish_decl (newtable, DECL_INITIAL (newtable), NULL_TREE, 0, 0); + DECL_CONTEXT (newtable) = complete_type; + return newtable; +} + +/* Add all vtables into LIST for the VBASEBASE subobject and its bases + of VBASE virtual BASE of COMPLETE_TYPE for use in BASE + constructors. DO_SELF indicates whether this is the VBASEBASE that + has 'primary' vfield. Return the new LIST. */ + +static tree +prepend_ctor_vfields_for_vbase (complete_type, base, vbase, vbasebase, + do_self, list) + tree complete_type, base, vbase, vbasebase; + int do_self; + tree list; +{ + int i; + tree vtbl; + tree bases = BINFO_BASETYPES (vbasebase); + int vfp = CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (vbasebase)); + + if (do_self && CLASSTYPE_VFIELDS (BINFO_TYPE (vbasebase))) + { + vtbl = finish_one_ctor_vtable (complete_type, base, vbase, vbasebase); + vtbl = build1 (ADDR_EXPR, vtbl_ptr_type_node, vtbl); + TREE_READONLY (vtbl) = 1; + TREE_CONSTANT (vtbl) = 1; + list = tree_cons (NULL_TREE, vtbl, list); + } + + if (!bases) + return list; + + for (i = 0; i < TREE_VEC_LENGTH (bases); i++) + { + tree vbasebase = TREE_VEC_ELT (bases, i); + if (TREE_VIA_VIRTUAL (vbasebase)) + continue; + list = prepend_ctor_vfields_for_vbase + (complete_type, base, vbase, vbasebase, (i != vfp), list); + } + + return list; +} + +/* Iterate over all virtual bases of the BASE subobject of + COMPLETE_TYPE. This list is given in VBASES. Return the list of + vtables generated in the process. */ + +static tree +finish_ctor_vtables_for_vbases (vbases, base, complete_type) + tree vbases, base, complete_type; +{ + tree result = NULL_TREE; + + for (; vbases; vbases = TREE_CHAIN (vbases)) + result = prepend_ctor_vfields_for_vbase + (complete_type, base, vbases, vbases, 1, result); + return result; +} + +/* Generate special vtables for virtual bases for use inside base + class ctors and dtors. Inside this function, we assume the + following scenario: + class A{virtual void foo();}; + class B:virtual A{int member1;} + class C:B{int member2;} + + BINFO is a base subject (e.g. B) of COMPLETE_TYPE. Returns the list + of virtual tables. */ + +static tree +finish_ctor_vtables_1 (binfo, complete_type) + tree binfo; + tree complete_type; +{ + int i; + tree binfos; + tree result = NULL_TREE; + + binfos = BINFO_BASETYPES (binfo); + if (!binfos) + return result; + + /* Iterate over all bases (i.e. B). */ + for (i = 0; i < TREE_VEC_LENGTH (binfos); i++) + { + tree base = TREE_VEC_ELT (binfos, i); + tree vbases = CLASSTYPE_VBASECLASSES (BINFO_TYPE (base)); + if (!vbases) + /* This base class does not have virtual bases. */ + continue; + if (TREE_VIA_VIRTUAL (base)) + /* A virtual base class is initialized on in the most-derived + constructor. */ + continue; + if (!TYPE_USES_PVBASES (BINFO_TYPE (base))) + /* Class has no polymorphic vbases. */ + continue; + /* Prepend vtable list for base class. */ + result = chainon (finish_ctor_vtables_1 (base, complete_type), + result); + /* Prepend our own vtable list. */ + result = chainon + (finish_ctor_vtables_for_vbases (vbases, base, complete_type), + result); + } + return result; +} + +/* Add the vtables of a virtual base BINFO in front of LIST, returning + the new list. DO_SELF indicates whether we have to return the + vtable of a vfield borrowed in a derived class. */ + +static tree +prepend_vbase_vfields (binfo, do_self, list) + tree binfo; + int do_self; + tree list; +{ + int i; + tree vtbl; + tree bases = BINFO_BASETYPES (binfo); + int vfp = CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo)); + + if (do_self && CLASSTYPE_VFIELDS (BINFO_TYPE (binfo))) + { + vtbl = BINFO_VTABLE (binfo); + vtbl = build1 (ADDR_EXPR, vtbl_ptr_type_node, vtbl); + TREE_READONLY (vtbl) = 1; + TREE_CONSTANT (vtbl) = 1; + list = tree_cons (NULL_TREE, vtbl, list); + } + + if (!bases) + return list; + + for (i = 0; i < TREE_VEC_LENGTH (bases); i++) + { + tree base = TREE_VEC_ELT (bases, i); + if (TREE_VIA_VIRTUAL (base)) + continue; + list = prepend_vbase_vfields (base, (i != vfp), list); + } + + return list; +} + +/* Wrapper around finish_ctor_vtables_1. Compute the vtable list for + type T. */ + +static void +finish_ctor_vtables (t) + tree t; +{ + tree veclist = NULL_TREE; + tree decl, type; + char *name; + tree vbase; + int len; + + /* This is only good for vtable thunks. */ + my_friendly_assert (flag_vtable_thunks, 990307); + + /* Start with the list of most-derived vtables. */ + + for (vbase = CLASSTYPE_VBASECLASSES (t); vbase; + vbase = TREE_CHAIN (vbase)) + veclist = prepend_vbase_vfields (vbase, 1, veclist); + + /* Compute the list of vtables for the bases. */ + veclist = chainon (veclist, finish_ctor_vtables_1 (TYPE_BINFO (t), t)); + + /* Finally, we initialize the virtual bases first. */ + for (vbase = CLASSTYPE_VBASECLASSES (t); vbase; + vbase = TREE_CHAIN (vbase)) + { + tree vbases = CLASSTYPE_VBASECLASSES (BINFO_TYPE (vbase)); + if (!vbases) + continue; + veclist = chainon (veclist, + finish_ctor_vtables_for_vbases (vbases, vbase, t)); + veclist = chainon (veclist, + finish_ctor_vtables_1 (vbase, t)); + } + + veclist = nreverse (veclist); + + /* Generate the name for the vtable list. */ + name = alloca (strlen (VLIST_NAME_FORMAT) + + TYPE_ASSEMBLER_NAME_LENGTH (t) + 2); + sprintf (name, VLIST_NAME_FORMAT, TYPE_ASSEMBLER_NAME_STRING (t)); + + /* Build the type of the list. */ + len = list_length (veclist) - 1; + if (len < 0) + /* If this class has virtual bases without virtual methods, make a + single zero-entry in the array. This avoids zero-sized objects. */ + len++; + type = build_cplus_array_type (vtbl_ptr_type_node, + build_index_type (size_int (len))); + + + /* Produce a new decl holding the list. */ + decl = build_lang_decl (VAR_DECL, get_identifier (name), type); + TREE_STATIC (decl) = 1; + TREE_READONLY (decl) = 1; + decl = pushdecl_top_level (decl); + import_export_vtable (decl, t, 0); + DECL_INITIAL (decl) = build_nt (CONSTRUCTOR, NULL_TREE, veclist); + + DECL_ARTIFICIAL (decl) = 1; + /* This tells finish_file et.al. that this is related to virtual + tables. There is currently no way to distinguish between vtables + and vlists, other than the name of the decl. */ + DECL_VIRTUAL_P (decl) = 1; + + /* Output the array. */ + cp_finish_decl (decl, DECL_INITIAL (decl), NULL_TREE, 0, 0); + + /* Set the class context after finishing, so that finish thinks this + is an unrelated global, and then finish_vtable_vardecl knows what + class this is related to. */ + DECL_CONTEXT (decl) = t; +} + /* Check for things that are invalid. There are probably plenty of other things we should check for also. */ static void finish_struct_anon (t) tree t; { tree field; for (field = TYPE_FIELDS (t); field; field = TREE_CHAIN (field)) { if (TREE_STATIC (field)) continue; if (TREE_CODE (field) != FIELD_DECL) continue; if (DECL_NAME (field) == NULL_TREE && TREE_CODE (TREE_TYPE (field)) == UNION_TYPE) { tree* uelt = &TYPE_FIELDS (TREE_TYPE (field)); for (; *uelt; uelt = &TREE_CHAIN (*uelt)) { if (DECL_ARTIFICIAL (*uelt)) continue; if (DECL_NAME (*uelt) == constructor_name (t)) cp_pedwarn_at ("ANSI C++ forbids member `%D' with same name as enclosing class", *uelt); if (TREE_CODE (*uelt) != FIELD_DECL) { cp_pedwarn_at ("`%#D' invalid; an anonymous union can only have non-static data members", *uelt); continue; } if (TREE_PRIVATE (*uelt)) cp_pedwarn_at ("private member `%#D' in anonymous union", *uelt); else if (TREE_PROTECTED (*uelt)) cp_pedwarn_at ("protected member `%#D' in anonymous union", *uelt); TREE_PRIVATE (*uelt) = TREE_PRIVATE (field); TREE_PROTECTED (*uelt) = TREE_PROTECTED (field); } } } } extern int interface_only, interface_unknown; /* Create default constructors, assignment operators, and so forth for the type indicated by T, if they are needed. CANT_HAVE_DEFAULT_CTOR, CANT_HAVE_CONST_CTOR, and CANT_HAVE_ASSIGNMENT are nonzero if, for whatever reason, the class cannot have a default constructor, copy constructor taking a const reference argument, or an assignment operator, respectively. If a virtual destructor is created, its DECL is returned; otherwise the return value is NULL_TREE. */ static tree add_implicitly_declared_members (t, cant_have_default_ctor, cant_have_const_cctor, cant_have_assignment) tree t; int cant_have_default_ctor; int cant_have_const_cctor; int cant_have_assignment; { tree default_fn; tree implicit_fns = NULL_TREE; tree name = TYPE_IDENTIFIER (t); tree virtual_dtor = NULL_TREE; tree *f; /* Destructor. */ if (TYPE_NEEDS_DESTRUCTOR (t) && !TYPE_HAS_DESTRUCTOR (t) && !IS_SIGNATURE (t)) { default_fn = cons_up_default_function (t, name, 0); check_for_override (default_fn, t); /* If we couldn't make it work, then pretend we didn't need it. */ if (default_fn == void_type_node) TYPE_NEEDS_DESTRUCTOR (t) = 0; else { TREE_CHAIN (default_fn) = implicit_fns; implicit_fns = default_fn; if (DECL_VINDEX (default_fn)) virtual_dtor = default_fn; } } TYPE_NEEDS_DESTRUCTOR (t) |= TYPE_HAS_DESTRUCTOR (t); /* Default constructor. */ if (! TYPE_HAS_CONSTRUCTOR (t) && ! cant_have_default_ctor && ! IS_SIGNATURE (t)) { default_fn = cons_up_default_function (t, name, 2); TREE_CHAIN (default_fn) = implicit_fns; implicit_fns = default_fn; } /* Copy constructor. */ if (! TYPE_HAS_INIT_REF (t) && ! IS_SIGNATURE (t) && ! TYPE_FOR_JAVA (t)) { /* ARM 12.18: You get either X(X&) or X(const X&), but not both. --Chip */ default_fn = cons_up_default_function (t, name, 3 + cant_have_const_cctor); TREE_CHAIN (default_fn) = implicit_fns; implicit_fns = default_fn; } /* Assignment operator. */ if (! TYPE_HAS_ASSIGN_REF (t) && ! IS_SIGNATURE (t) && ! TYPE_FOR_JAVA (t)) { default_fn = cons_up_default_function (t, name, 5 + cant_have_assignment); TREE_CHAIN (default_fn) = implicit_fns; implicit_fns = default_fn; } /* Now, hook all of the new functions on to TYPE_METHODS, and add them to the CLASSTYPE_METHOD_VEC. */ for (f = &implicit_fns; *f; f = &TREE_CHAIN (*f)) add_method (t, 0, *f); *f = TYPE_METHODS (t); TYPE_METHODS (t) = implicit_fns; return virtual_dtor; } /* Create a RECORD_TYPE or UNION_TYPE node for a C struct or union declaration (or C++ class declaration). For C++, we must handle the building of derived classes. Also, C++ allows static class members. The way that this is handled is to keep the field name where it is (as the DECL_NAME of the field), and place the overloaded decl in the DECL_FIELD_BITPOS of the field. layout_record and layout_union will know about this. More C++ hair: inline functions have text in their DECL_PENDING_INLINE_INFO nodes which must somehow be parsed into meaningful tree structure. After the struct has been laid out, set things up so that this can happen. And still more: virtual functions. In the case of single inheritance, when a new virtual function is seen which redefines a virtual function from the base class, the new virtual function is placed into the virtual function table at exactly the same address that it had in the base class. When this is extended to multiple inheritance, the same thing happens, except that multiple virtual function tables must be maintained. The first virtual function table is treated in exactly the same way as in the case of single inheritance. Additional virtual function tables have different DELTAs, which tell how to adjust `this' to point to the right thing. ATTRIBUTES is the set of decl attributes to be applied, if any. */ void finish_struct_1 (t, warn_anon) tree t; int warn_anon; { int old; enum tree_code code = TREE_CODE (t); tree fields = TYPE_FIELDS (t); tree x, last_x, method_vec; int has_virtual; int max_has_virtual; tree pending_virtuals = NULL_TREE; tree pending_hard_virtuals = NULL_TREE; tree abstract_virtuals = NULL_TREE; tree vfield; tree vfields; tree virtual_dtor; int cant_have_default_ctor; int cant_have_const_ctor; int no_const_asn_ref; int has_mutable = 0; /* The index of the first base class which has virtual functions. Only applied to non-virtual baseclasses. */ int first_vfn_base_index; int n_baseclasses; int any_default_members = 0; int const_sans_init = 0; int ref_sans_init = 0; tree access_decls = NULL_TREE; int aggregate = 1; int empty = 1; int has_pointers = 0; tree inline_friends; if (warn_anon && code != UNION_TYPE && ANON_AGGRNAME_P (TYPE_IDENTIFIER (t))) pedwarn ("anonymous class type not used to declare any objects"); if (TYPE_SIZE (t)) { if (IS_AGGR_TYPE (t)) cp_error ("redefinition of `%#T'", t); else my_friendly_abort (172); popclass (); return; } GNU_xref_decl (current_function_decl, t); /* If this type was previously laid out as a forward reference, make sure we lay it out again. */ TYPE_SIZE (t) = NULL_TREE; CLASSTYPE_GOT_SEMICOLON (t) = 0; #if 0 /* This is in general too late to do this. I moved the main case up to left_curly, what else needs to move? */ if (! IS_SIGNATURE (t)) { my_friendly_assert (CLASSTYPE_INTERFACE_ONLY (t) == interface_only, 999); my_friendly_assert (CLASSTYPE_INTERFACE_KNOWN (t) == ! interface_unknown, 999); } #endif old = suspend_momentary (); /* Install struct as DECL_FIELD_CONTEXT of each field decl. Also process specified field sizes. Set DECL_FIELD_SIZE to the specified size, or 0 if none specified. The specified size is found in the DECL_INITIAL. Store 0 there, except for ": 0" fields (so we can find them and delete them, below). */ if (TYPE_BINFO_BASETYPES (t)) n_baseclasses = TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (t)); else n_baseclasses = 0; if (n_baseclasses > 0) { struct base_info base_info; first_vfn_base_index = finish_base_struct (t, &base_info); /* Remember where we got our vfield from. */ CLASSTYPE_VFIELD_PARENT (t) = first_vfn_base_index; has_virtual = base_info.has_virtual; max_has_virtual = base_info.max_has_virtual; vfield = base_info.vfield; vfields = base_info.vfields; CLASSTYPE_RTTI (t) = base_info.rtti; cant_have_default_ctor = base_info.cant_have_default_ctor; cant_have_const_ctor = base_info.cant_have_const_ctor; no_const_asn_ref = base_info.no_const_asn_ref; aggregate = 0; } else { first_vfn_base_index = -1; has_virtual = 0; max_has_virtual = has_virtual; vfield = NULL_TREE; vfields = NULL_TREE; CLASSTYPE_RTTI (t) = NULL_TREE; cant_have_default_ctor = 0; cant_have_const_ctor = 0; no_const_asn_ref = 0; } #if 0 /* Both of these should be done before now. */ if (write_virtuals == 3 && CLASSTYPE_INTERFACE_KNOWN (t) && ! IS_SIGNATURE (t)) { my_friendly_assert (CLASSTYPE_INTERFACE_ONLY (t) == interface_only, 999); my_friendly_assert (CLASSTYPE_VTABLE_NEEDS_WRITING (t) == ! interface_only, 999); } #endif /* The three of these are approximations which may later be modified. Needed at this point to make add_virtual_function and modify_vtable_entries work. */ CLASSTYPE_VFIELDS (t) = vfields; CLASSTYPE_VFIELD (t) = vfield; for (x = TYPE_METHODS (t); x; x = TREE_CHAIN (x)) { GNU_xref_member (current_class_name, x); /* If this was an evil function, don't keep it in class. */ if (IDENTIFIER_ERROR_LOCUS (DECL_ASSEMBLER_NAME (x))) continue; /* Do both of these, even though they're in the same union; if the insn `r' member and the size `i' member are different sizes, as on the alpha, the larger of the two will end up with garbage in it. */ DECL_SAVED_INSNS (x) = NULL_RTX; DECL_FIELD_SIZE (x) = 0; check_for_override (x, t); if (DECL_ABSTRACT_VIRTUAL_P (x) && ! DECL_VINDEX (x)) cp_error_at ("initializer specified for non-virtual method `%D'", x); /* The name of the field is the original field name Save this in auxiliary field for later overloading. */ if (DECL_VINDEX (x)) { add_virtual_function (&pending_virtuals, &pending_hard_virtuals, &has_virtual, x, t); if (DECL_ABSTRACT_VIRTUAL_P (x)) abstract_virtuals = tree_cons (NULL_TREE, x, abstract_virtuals); #if 0 /* XXX Why did I comment this out? (jason) */ else TREE_USED (x) = 1; #endif } } if (n_baseclasses) fields = chainon (build_vbase_pointer_fields (t), fields); last_x = NULL_TREE; for (x = fields; x; x = TREE_CHAIN (x)) { GNU_xref_member (current_class_name, x); if (TREE_CODE (x) == FIELD_DECL) { DECL_PACKED (x) |= TYPE_PACKED (t); if (DECL_C_BIT_FIELD (x) && integer_zerop (DECL_INITIAL (x))) /* A zero-width bitfield doesn't do the trick. */; else empty = 0; } if (TREE_CODE (x) == USING_DECL) { /* Save access declarations for later. */ if (last_x) TREE_CHAIN (last_x) = TREE_CHAIN (x); else fields = TREE_CHAIN (x); access_decls = scratch_tree_cons (NULL_TREE, x, access_decls); continue; } last_x = x; if (TREE_CODE (x) == TYPE_DECL || TREE_CODE (x) == TEMPLATE_DECL) continue; /* If we've gotten this far, it's a data member, possibly static, or an enumerator. */ DECL_FIELD_CONTEXT (x) = t; /* ``A local class cannot have static data members.'' ARM 9.4 */ if (current_function_decl && TREE_STATIC (x)) cp_error_at ("field `%D' in local class cannot be static", x); /* Perform error checking that did not get done in grokdeclarator. */ if (TREE_CODE (TREE_TYPE (x)) == FUNCTION_TYPE) { cp_error_at ("field `%D' invalidly declared function type", x); TREE_TYPE (x) = build_pointer_type (TREE_TYPE (x)); } else if (TREE_CODE (TREE_TYPE (x)) == METHOD_TYPE) { cp_error_at ("field `%D' invalidly declared method type", x); TREE_TYPE (x) = build_pointer_type (TREE_TYPE (x)); } else if (TREE_CODE (TREE_TYPE (x)) == OFFSET_TYPE) { cp_error_at ("field `%D' invalidly declared offset type", x); TREE_TYPE (x) = build_pointer_type (TREE_TYPE (x)); } #if 0 if (DECL_NAME (x) == constructor_name (t)) cant_have_default_ctor = 1; #endif if (TREE_TYPE (x) == error_mark_node) continue; DECL_SAVED_INSNS (x) = NULL_RTX; DECL_FIELD_SIZE (x) = 0; /* When this goes into scope, it will be a non-local reference. */ DECL_NONLOCAL (x) = 1; if (TREE_CODE (x) == CONST_DECL) continue; if (TREE_CODE (x) == VAR_DECL) { if (TREE_CODE (t) == UNION_TYPE) /* Unions cannot have static members. */ cp_error_at ("field `%D' declared static in union", x); continue; } /* Now it can only be a FIELD_DECL. */ if (TREE_PRIVATE (x) || TREE_PROTECTED (x)) aggregate = 0; /* If this is of reference type, check if it needs an init. Also do a little ANSI jig if necessary. */ if (TREE_CODE (TREE_TYPE (x)) == REFERENCE_TYPE) { if (DECL_INITIAL (x) == NULL_TREE) ref_sans_init = 1; /* ARM $12.6.2: [A member initializer list] (or, for an aggregate, initialization by a brace-enclosed list) is the only way to initialize nonstatic const and reference members. */ cant_have_default_ctor = 1; TYPE_HAS_COMPLEX_ASSIGN_REF (t) = 1; if (! TYPE_HAS_CONSTRUCTOR (t) && extra_warnings) { if (DECL_NAME (x)) cp_warning_at ("non-static reference `%#D' in class without a constructor", x); else cp_warning_at ("non-static reference in class without a constructor", x); } } if (TREE_CODE (TREE_TYPE (x)) == POINTER_TYPE) has_pointers = 1; if (DECL_MUTABLE_P (x) || TYPE_HAS_MUTABLE_P (TREE_TYPE (x))) has_mutable = 1; /* If any field is const, the structure type is pseudo-const. */ if (CP_TYPE_CONST_P (TREE_TYPE (x))) { C_TYPE_FIELDS_READONLY (t) = 1; if (DECL_INITIAL (x) == NULL_TREE) const_sans_init = 1; /* ARM $12.6.2: [A member initializer list] (or, for an aggregate, initialization by a brace-enclosed list) is the only way to initialize nonstatic const and reference members. */ cant_have_default_ctor = 1; TYPE_HAS_COMPLEX_ASSIGN_REF (t) = 1; if (! TYPE_HAS_CONSTRUCTOR (t) && !IS_SIGNATURE (t) && extra_warnings) { if (DECL_NAME (x)) cp_warning_at ("non-static const member `%#D' in class without a constructor", x); else cp_warning_at ("non-static const member in class without a constructor", x); } } else { /* A field that is pseudo-const makes the structure likewise. */ tree t1 = TREE_TYPE (x); while (TREE_CODE (t1) == ARRAY_TYPE) t1 = TREE_TYPE (t1); if (IS_AGGR_TYPE (t1)) { if (C_TYPE_FIELDS_READONLY (t1)) C_TYPE_FIELDS_READONLY (t) = 1; if (CLASSTYPE_READONLY_FIELDS_NEED_INIT (t1)) const_sans_init = 1; } } /* We set DECL_C_BIT_FIELD in grokbitfield. If the type and width are valid, we'll also set DECL_BIT_FIELD. */ if (DECL_C_BIT_FIELD (x)) { /* Invalid bit-field size done by grokfield. */ /* Detect invalid bit-field type. */ if (DECL_INITIAL (x) && ! INTEGRAL_TYPE_P (TREE_TYPE (x))) { cp_error_at ("bit-field `%#D' with non-integral type", x); DECL_INITIAL (x) = NULL; } /* Detect and ignore out of range field width. */ if (DECL_INITIAL (x)) { tree w = DECL_INITIAL (x); register int width = 0; /* Avoid the non_lvalue wrapper added by fold for PLUS_EXPRs. */ STRIP_NOPS (w); /* detect invalid field size. */ if (TREE_CODE (w) == CONST_DECL) w = DECL_INITIAL (w); else if (TREE_READONLY_DECL_P (w)) w = decl_constant_value (w); if (TREE_CODE (w) != INTEGER_CST) { cp_error_at ("bit-field `%D' width not an integer constant", x); DECL_INITIAL (x) = NULL_TREE; } else if (width = TREE_INT_CST_LOW (w), width < 0) { DECL_INITIAL (x) = NULL; cp_error_at ("negative width in bit-field `%D'", x); } else if (width == 0 && DECL_NAME (x) != 0) { DECL_INITIAL (x) = NULL; cp_error_at ("zero width for bit-field `%D'", x); } else if (width > TYPE_PRECISION (long_long_unsigned_type_node)) { /* The backend will dump if you try to use something too big; avoid that. */ DECL_INITIAL (x) = NULL; sorry ("bit-fields larger than %d bits", TYPE_PRECISION (long_long_unsigned_type_node)); cp_error_at (" in declaration of `%D'", x); } else if (width > TYPE_PRECISION (TREE_TYPE (x)) && TREE_CODE (TREE_TYPE (x)) != ENUMERAL_TYPE && TREE_CODE (TREE_TYPE (x)) != BOOLEAN_TYPE) { cp_warning_at ("width of `%D' exceeds its type", x); } else if (TREE_CODE (TREE_TYPE (x)) == ENUMERAL_TYPE && ((min_precision (TYPE_MIN_VALUE (TREE_TYPE (x)), TREE_UNSIGNED (TREE_TYPE (x))) > width) || (min_precision (TYPE_MAX_VALUE (TREE_TYPE (x)), TREE_UNSIGNED (TREE_TYPE (x))) > width))) { cp_warning_at ("`%D' is too small to hold all values of `%#T'", x, TREE_TYPE (x)); } if (DECL_INITIAL (x)) { DECL_INITIAL (x) = NULL_TREE; DECL_FIELD_SIZE (x) = width; DECL_BIT_FIELD (x) = 1; if (width == 0) { #ifdef EMPTY_FIELD_BOUNDARY DECL_ALIGN (x) = MAX (DECL_ALIGN (x), EMPTY_FIELD_BOUNDARY); #endif #ifdef PCC_BITFIELD_TYPE_MATTERS if (PCC_BITFIELD_TYPE_MATTERS) DECL_ALIGN (x) = MAX (DECL_ALIGN (x), TYPE_ALIGN (TREE_TYPE (x))); #endif } } } else /* Non-bit-fields are aligned for their type. */ DECL_ALIGN (x) = MAX (DECL_ALIGN (x), TYPE_ALIGN (TREE_TYPE (x))); } else { tree type = TREE_TYPE (x); while (TREE_CODE (type) == ARRAY_TYPE) type = TREE_TYPE (type); if (TYPE_LANG_SPECIFIC (type) && ! ANON_UNION_P (x) && ! TYPE_PTRMEMFUNC_P (type)) { /* Never let anything with uninheritable virtuals make it through without complaint. */ if (CLASSTYPE_ABSTRACT_VIRTUALS (type)) abstract_virtuals_error (x, type); /* Don't let signatures make it through either. */ if (IS_SIGNATURE (type)) signature_error (x, type); if (code == UNION_TYPE) { const char *fie = NULL; if (TYPE_NEEDS_CONSTRUCTING (type)) fie = "constructor"; else if (TYPE_NEEDS_DESTRUCTOR (type)) fie = "destructor"; else if (TYPE_HAS_COMPLEX_ASSIGN_REF (type)) fie = "copy assignment operator"; if (fie) cp_error_at ("member `%#D' with %s not allowed in union", x, fie); } else { TYPE_NEEDS_CONSTRUCTING (t) |= TYPE_NEEDS_CONSTRUCTING (type); TYPE_NEEDS_DESTRUCTOR (t) |= TYPE_NEEDS_DESTRUCTOR (type); TYPE_HAS_COMPLEX_ASSIGN_REF (t) |= TYPE_HAS_COMPLEX_ASSIGN_REF (type); TYPE_HAS_COMPLEX_INIT_REF (t) |= TYPE_HAS_COMPLEX_INIT_REF (type); } if (!TYPE_HAS_CONST_INIT_REF (type)) cant_have_const_ctor = 1; if (!TYPE_HAS_CONST_ASSIGN_REF (type)) no_const_asn_ref = 1; if (TYPE_HAS_CONSTRUCTOR (type) && ! TYPE_HAS_DEFAULT_CONSTRUCTOR (type)) { cant_have_default_ctor = 1; #if 0 /* This is wrong for aggregates. */ if (! TYPE_HAS_CONSTRUCTOR (t)) { if (DECL_NAME (x)) cp_pedwarn_at ("member `%#D' with only non-default constructor", x); else cp_pedwarn_at ("member with only non-default constructor", x); cp_pedwarn_at ("in class without a constructor", x); } #endif } } if (DECL_INITIAL (x) != NULL_TREE) { /* `build_class_init_list' does not recognize non-FIELD_DECLs. */ if (code == UNION_TYPE && any_default_members != 0) cp_error_at ("multiple fields in union `%T' initialized"); any_default_members = 1; } } } /* If this type has any constant members which did not come with their own initialization, mark that fact here. It is not an error here, since such types can be saved either by their constructors, or by fortuitous initialization. */ CLASSTYPE_READONLY_FIELDS_NEED_INIT (t) = const_sans_init; CLASSTYPE_REF_FIELDS_NEED_INIT (t) = ref_sans_init; CLASSTYPE_ABSTRACT_VIRTUALS (t) = abstract_virtuals; CLASSTYPE_HAS_MUTABLE (t) = has_mutable; /* Effective C++ rule 11. */ if (has_pointers && warn_ecpp && TYPE_HAS_CONSTRUCTOR (t) && ! (TYPE_HAS_INIT_REF (t) && TYPE_HAS_ASSIGN_REF (t))) { cp_warning ("`%#T' has pointer data members", t); if (! TYPE_HAS_INIT_REF (t)) { cp_warning (" but does not override `%T(const %T&)'", t, t); if (! TYPE_HAS_ASSIGN_REF (t)) cp_warning (" or `operator=(const %T&)'", t); } else if (! TYPE_HAS_ASSIGN_REF (t)) cp_warning (" but does not override `operator=(const %T&)'", t); } /* Do some bookkeeping that will guide the generation of implicitly declared member functions. */ TYPE_HAS_COMPLEX_INIT_REF (t) |= (TYPE_HAS_INIT_REF (t) || TYPE_USES_VIRTUAL_BASECLASSES (t) || has_virtual || any_default_members); TYPE_NEEDS_CONSTRUCTING (t) |= (TYPE_HAS_CONSTRUCTOR (t) || TYPE_USES_VIRTUAL_BASECLASSES (t) || has_virtual || any_default_members); if (! IS_SIGNATURE (t)) CLASSTYPE_NON_AGGREGATE (t) = ! aggregate || has_virtual || TYPE_HAS_CONSTRUCTOR (t); TYPE_HAS_REAL_ASSIGN_REF (t) |= TYPE_HAS_ASSIGN_REF (t); TYPE_HAS_COMPLEX_ASSIGN_REF (t) |= TYPE_HAS_ASSIGN_REF (t) || TYPE_USES_VIRTUAL_BASECLASSES (t); /* Synthesize any needed methods. Note that methods will be synthesized for anonymous unions; grok_x_components undoes that. */ virtual_dtor = add_implicitly_declared_members (t, cant_have_default_ctor, cant_have_const_ctor, no_const_asn_ref); if (virtual_dtor) add_virtual_function (&pending_virtuals, &pending_hard_virtuals, &has_virtual, virtual_dtor, t); if (TYPE_METHODS (t)) { finish_struct_methods (t); method_vec = CLASSTYPE_METHOD_VEC (t); } else { method_vec = 0; /* Just in case these got accidentally filled in by syntax errors. */ TYPE_HAS_CONSTRUCTOR (t) = 0; TYPE_HAS_DESTRUCTOR (t) = 0; } for (access_decls = nreverse (access_decls); access_decls; access_decls = TREE_CHAIN (access_decls)) handle_using_decl (TREE_VALUE (access_decls), t, method_vec, fields); if (vfield == NULL_TREE && has_virtual) { /* We build this decl with vtbl_ptr_type_node, which is a `vtable_entry_type*'. It might seem more precise to use `vtable_entry_type (*)[N]' where N is the number of firtual functions. However, that would require the vtable pointer in base classes to have a different type than the vtable pointer in derived classes. We could make that happen, but that still wouldn't solve all the problems. In particular, the type-based alias analysis code would decide that assignments to the base class vtable pointer can't alias assignments to the derived class vtable pointer, since they have different types. Thus, in an derived class destructor, where the base class constructor was inlined, we could generate bad code for setting up the vtable pointer. Therefore, we use one type for all vtable pointers. We still use a type-correct type; it's just doesn't indicate the array bounds. That's better than using `void*' or some such; it's cleaner, and it let's the alias analysis code know that these stores cannot alias stores to void*! */ vfield = build_lang_field_decl (FIELD_DECL, get_vfield_name (t), vtbl_ptr_type_node); /* If you change any of the below, take a look at all the other VFIELD_BASEs and VTABLE_BASEs in the code, and change them too. */ DECL_ASSEMBLER_NAME (vfield) = get_identifier (VFIELD_BASE); CLASSTYPE_VFIELD (t) = vfield; DECL_VIRTUAL_P (vfield) = 1; DECL_ARTIFICIAL (vfield) = 1; DECL_FIELD_CONTEXT (vfield) = t; DECL_CLASS_CONTEXT (vfield) = t; DECL_FCONTEXT (vfield) = t; DECL_SAVED_INSNS (vfield) = NULL_RTX; DECL_FIELD_SIZE (vfield) = 0; DECL_ALIGN (vfield) = TYPE_ALIGN (ptr_type_node); #if 0 /* This is more efficient, but breaks binary compatibility, turn it on sometime when we don't care. If we turn it on, we also have to enable the code in dfs_init_vbase_pointers. */ /* vfield is always first entry in structure. */ TREE_CHAIN (vfield) = fields; fields = vfield; #else if (last_x) { my_friendly_assert (TREE_CHAIN (last_x) == NULL_TREE, 175); TREE_CHAIN (last_x) = vfield; last_x = vfield; } else fields = vfield; #endif empty = 0; vfields = chainon (vfields, build_tree_list (NULL_TREE, t)); } /* Now DECL_INITIAL is null on all members except for zero-width bit-fields. C++: maybe we will support default field initialization some day... */ /* Delete all duplicate fields from the fields */ delete_duplicate_fields (fields); /* Now we have the nearly final fieldlist for the data fields. Record it, then lay out the structure or union (including the fields). */ TYPE_FIELDS (t) = fields; if (n_baseclasses) { last_x = build_base_fields (t); /* If all our bases are empty, we can be empty too. */ for (x = last_x; empty && x; x = TREE_CHAIN (x)) if (DECL_SIZE (x) != integer_zero_node) empty = 0; } /* CLASSTYPE_INLINE_FRIENDS is really TYPE_NONCOPIED_PARTS. Thus, we have to save this before we start modifying TYPE_NONCOPIED_PARTS. */ inline_friends = CLASSTYPE_INLINE_FRIENDS (t); CLASSTYPE_INLINE_FRIENDS (t) = NULL_TREE; if (empty) { /* C++: do not let empty structures exist. */ tree decl = build_lang_field_decl (FIELD_DECL, NULL_TREE, char_type_node); TREE_CHAIN (decl) = fields; TYPE_FIELDS (t) = decl; TYPE_NONCOPIED_PARTS (t) = tree_cons (NULL_TREE, decl, TYPE_NONCOPIED_PARTS (t)); TREE_STATIC (TYPE_NONCOPIED_PARTS (t)) = 1; } if (n_baseclasses) TYPE_FIELDS (t) = chainon (last_x, TYPE_FIELDS (t)); layout_type (t); /* Remember the size and alignment of the class before adding the virtual bases. */ if (empty && flag_new_abi) CLASSTYPE_SIZE (t) = integer_zero_node; else if (flag_new_abi && TYPE_HAS_COMPLEX_INIT_REF (t) && TYPE_HAS_COMPLEX_ASSIGN_REF (t)) CLASSTYPE_SIZE (t) = TYPE_BINFO_SIZE (t); else CLASSTYPE_SIZE (t) = TYPE_SIZE (t); CLASSTYPE_ALIGN (t) = TYPE_ALIGN (t); finish_struct_anon (t); /* Set the TYPE_DECL for this type to contain the right value for DECL_OFFSET, so that we can use it as part of a COMPONENT_REF for multiple inheritance. */ layout_decl (TYPE_MAIN_DECL (t), 0); /* Now fix up any virtual base class types that we left lying around. We must get these done before we try to lay out the virtual function table. */ pending_hard_virtuals = nreverse (pending_hard_virtuals); if (n_baseclasses) /* layout_basetypes will remove the base subobject fields. */ max_has_virtual = layout_basetypes (t, max_has_virtual); if (empty) TYPE_FIELDS (t) = fields; my_friendly_assert (TYPE_FIELDS (t) == fields, 981117); /* Delete all zero-width bit-fields from the front of the fieldlist */ while (fields && DECL_C_BIT_FIELD (fields) && DECL_INITIAL (fields)) fields = TREE_CHAIN (fields); /* Delete all such fields from the rest of the fields. */ for (x = fields; x;) { if (TREE_CHAIN (x) && DECL_C_BIT_FIELD (TREE_CHAIN (x)) && DECL_INITIAL (TREE_CHAIN (x))) TREE_CHAIN (x) = TREE_CHAIN (TREE_CHAIN (x)); else x = TREE_CHAIN (x); } TYPE_FIELDS (t) = fields; if (TYPE_USES_VIRTUAL_BASECLASSES (t)) { tree vbases; vbases = CLASSTYPE_VBASECLASSES (t); { /* Now fixup overrides of all functions in vtables from all direct or indirect virtual base classes. */ tree binfos = BINFO_BASETYPES (TYPE_BINFO (t)); int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0; for (i = 0; i < n_baseclasses; i++) { tree base_binfo = TREE_VEC_ELT (binfos, i); tree basetype = BINFO_TYPE (base_binfo); tree vbases; vbases = CLASSTYPE_VBASECLASSES (basetype); while (vbases) { merge_overrides (binfo_member (BINFO_TYPE (vbases), CLASSTYPE_VBASECLASSES (t)), vbases, 1, t); vbases = TREE_CHAIN (vbases); } } } } /* Set up the DECL_FIELD_BITPOS of the vfield if we need to, as we might need to know it for setting up the offsets in the vtable (or in thunks) below. */ if (vfield != NULL_TREE && DECL_FIELD_CONTEXT (vfield) != t) { tree binfo = get_binfo (DECL_FIELD_CONTEXT (vfield), t, 0); tree offset = BINFO_OFFSET (binfo); vfield = copy_node (vfield); copy_lang_decl (vfield); if (! integer_zerop (offset)) offset = size_binop (MULT_EXPR, offset, size_int (BITS_PER_UNIT)); DECL_FIELD_CONTEXT (vfield) = t; DECL_CLASS_CONTEXT (vfield) = t; DECL_FIELD_BITPOS (vfield) = size_binop (PLUS_EXPR, offset, DECL_FIELD_BITPOS (vfield)); CLASSTYPE_VFIELD (t) = vfield; } #ifdef NOTQUITE cp_warning ("Doing hard virtuals for %T...", t); #endif if (has_virtual > max_has_virtual) max_has_virtual = has_virtual; if (max_has_virtual > 0) TYPE_VIRTUAL_P (t) = 1; if (flag_rtti && TYPE_VIRTUAL_P (t) && !pending_hard_virtuals) modify_all_vtables (t, NULL_TREE, NULL_TREE); while (pending_hard_virtuals) { modify_all_vtables (t, TREE_PURPOSE (pending_hard_virtuals), TREE_VALUE (pending_hard_virtuals)); pending_hard_virtuals = TREE_CHAIN (pending_hard_virtuals); } if (TYPE_USES_VIRTUAL_BASECLASSES (t)) { tree vbases; /* Now fixup any virtual function entries from virtual bases that have different deltas. This has to come after we do the pending hard virtuals, as we might have a function that comes from multiple virtual base instances that is only overridden by a hard virtual above. */ vbases = CLASSTYPE_VBASECLASSES (t); while (vbases) { /* We might be able to shorten the amount of work we do by only doing this for vtables that come from virtual bases that have differing offsets, but don't want to miss any entries. */ fixup_vtable_deltas (vbases, 1, t); vbases = TREE_CHAIN (vbases); } } /* Under our model of GC, every C++ class gets its own virtual function table, at least virtually. */ if (pending_virtuals) { pending_virtuals = nreverse (pending_virtuals); /* We must enter these virtuals into the table. */ if (first_vfn_base_index < 0) { if (! CLASSTYPE_COM_INTERFACE (t)) { /* The second slot is for the tdesc pointer when thunks are used. */ if (flag_vtable_thunks) pending_virtuals = tree_cons (NULL_TREE, NULL_TREE, pending_virtuals); /* The first slot is for the rtti offset. */ pending_virtuals = tree_cons (NULL_TREE, NULL_TREE, pending_virtuals); set_rtti_entry (pending_virtuals, convert (ssizetype, integer_zero_node), t); } build_vtable (NULL_TREE, t); } else { /* Here we know enough to change the type of our virtual function table, but we will wait until later this function. */ if (! BINFO_NEW_VTABLE_MARKED (TYPE_BINFO (t))) build_vtable (TREE_VEC_ELT (TYPE_BINFO_BASETYPES (t), first_vfn_base_index), t); } /* If this type has basetypes with constructors, then those constructors might clobber the virtual function table. But they don't if the derived class shares the exact vtable of the base class. */ CLASSTYPE_NEEDS_VIRTUAL_REINIT (t) = 1; } else if (first_vfn_base_index >= 0) { tree binfo = TREE_VEC_ELT (TYPE_BINFO_BASETYPES (t), first_vfn_base_index); /* This class contributes nothing new to the virtual function table. However, it may have declared functions which went into the virtual function table "inherited" from the base class. If so, we grab a copy of those updated functions, and pretend they are ours. */ /* See if we should steal the virtual info from base class. */ if (TYPE_BINFO_VTABLE (t) == NULL_TREE) TYPE_BINFO_VTABLE (t) = BINFO_VTABLE (binfo); if (TYPE_BINFO_VIRTUALS (t) == NULL_TREE) TYPE_BINFO_VIRTUALS (t) = BINFO_VIRTUALS (binfo); if (TYPE_BINFO_VTABLE (t) != BINFO_VTABLE (binfo)) CLASSTYPE_NEEDS_VIRTUAL_REINIT (t) = 1; } if (max_has_virtual || first_vfn_base_index >= 0) { CLASSTYPE_VSIZE (t) = has_virtual; if (first_vfn_base_index >= 0) { if (pending_virtuals) TYPE_BINFO_VIRTUALS (t) = chainon (TYPE_BINFO_VIRTUALS (t), pending_virtuals); } else if (has_virtual) { TYPE_BINFO_VIRTUALS (t) = pending_virtuals; DECL_VIRTUAL_P (TYPE_BINFO_VTABLE (t)) = 1; } } /* Now lay out the virtual function table. */ if (has_virtual) { /* Use size_int so values are memoized in common cases. */ tree itype = build_index_type (size_int (has_virtual)); tree atype = build_cplus_array_type (vtable_entry_type, itype); layout_type (atype); CLASSTYPE_VFIELD (t) = vfield; /* We may have to grow the vtable. */ if (TREE_TYPE (TYPE_BINFO_VTABLE (t)) != atype) { TREE_TYPE (TYPE_BINFO_VTABLE (t)) = atype; DECL_SIZE (TYPE_BINFO_VTABLE (t)) = 0; layout_decl (TYPE_BINFO_VTABLE (t), 0); /* At one time the vtable info was grabbed 2 words at a time. This fails on sparc unless you have 8-byte alignment. (tiemann) */ DECL_ALIGN (TYPE_BINFO_VTABLE (t)) = MAX (TYPE_ALIGN (double_type_node), DECL_ALIGN (TYPE_BINFO_VTABLE (t))); } } else if (first_vfn_base_index >= 0) CLASSTYPE_VFIELD (t) = vfield; CLASSTYPE_VFIELDS (t) = vfields; finish_struct_bits (t, max_has_virtual); /* Complete the rtl for any static member objects of the type we're working on. */ for (x = fields; x; x = TREE_CHAIN (x)) { if (TREE_CODE (x) == VAR_DECL && TREE_STATIC (x) && TREE_TYPE (x) == t) { DECL_MODE (x) = TYPE_MODE (t); make_decl_rtl (x, NULL, 0); } } if (TYPE_HAS_CONSTRUCTOR (t)) { tree vfields = CLASSTYPE_VFIELDS (t); while (vfields) { /* Mark the fact that constructor for T could affect anybody inheriting from T who wants to initialize vtables for VFIELDS's type. */ if (VF_DERIVED_VALUE (vfields)) TREE_ADDRESSABLE (vfields) = 1; vfields = TREE_CHAIN (vfields); } } /* Write out inline function definitions. */ do_inline_function_hair (t, inline_friends); if (CLASSTYPE_VSIZE (t) != 0) { #if 0 /* This is now done above. */ if (DECL_FIELD_CONTEXT (vfield) != t) { tree binfo = get_binfo (DECL_FIELD_CONTEXT (vfield), t, 0); tree offset = BINFO_OFFSET (binfo); vfield = copy_node (vfield); copy_lang_decl (vfield); if (! integer_zerop (offset)) offset = size_binop (MULT_EXPR, offset, size_int (BITS_PER_UNIT)); DECL_FIELD_CONTEXT (vfield) = t; DECL_CLASS_CONTEXT (vfield) = t; DECL_FIELD_BITPOS (vfield) = size_binop (PLUS_EXPR, offset, DECL_FIELD_BITPOS (vfield)); CLASSTYPE_VFIELD (t) = vfield; } #endif /* In addition to this one, all the other vfields should be listed. */ /* Before that can be done, we have to have FIELD_DECLs for them, and a place to find them. */ TYPE_NONCOPIED_PARTS (t) = tree_cons (default_conversion (TYPE_BINFO_VTABLE (t)), vfield, TYPE_NONCOPIED_PARTS (t)); if (warn_nonvdtor && TYPE_HAS_DESTRUCTOR (t) && DECL_VINDEX (TREE_VEC_ELT (method_vec, 1)) == NULL_TREE) cp_warning ("`%#T' has virtual functions but non-virtual destructor", t); } /* Make the rtl for any new vtables we have created, and unmark the base types we marked. */ finish_vtbls (TYPE_BINFO (t), 1, t); + /* If we use thunks, and have virtual bases, we might need to emit + additional vtables. */ + if (flag_vtable_thunks && TYPE_USES_PVBASES (t)) + finish_ctor_vtables (t); hack_incomplete_structures (t); #if 0 if (TYPE_NAME (t) && TYPE_IDENTIFIER (t)) undo_template_name_overload (TYPE_IDENTIFIER (t), 1); #endif resume_momentary (old); if (warn_overloaded_virtual) warn_hidden (t); #if 0 /* This has to be done after we have sorted out what to do with the enclosing type. */ if (write_symbols != DWARF_DEBUG) { /* Be smarter about nested classes here. If a type is nested, only output it if we would output the enclosing type. */ if (DECL_CLASS_SCOPE_P (TYPE_MAIN_DECL (t))) DECL_IGNORED_P (TYPE_MAIN_DECL (t)) = TREE_ASM_WRITTEN (TYPE_MAIN_DECL (t)); } #endif if (write_symbols != DWARF_DEBUG && write_symbols != DWARF2_DEBUG) { /* If the type has methods, we want to think about cutting down the amount of symbol table stuff we output. The value stored in the TYPE_DECL's DECL_IGNORED_P slot is a first approximation. For example, if a member function is seen and we decide to write out that member function, then we can change the value of the DECL_IGNORED_P slot, and the type will be output when that member function's debug info is written out. We can't do this with DWARF, which does not support name references between translation units. */ if (CLASSTYPE_METHOD_VEC (t)) { /* Don't output full info about any type which does not have its implementation defined here. */ if (CLASSTYPE_INTERFACE_ONLY (t)) TYPE_DECL_SUPPRESS_DEBUG (TYPE_MAIN_DECL (t)) = 1; #if 0 /* XXX do something about this. */ else if (CLASSTYPE_INTERFACE_UNKNOWN (t)) /* Only a first approximation! */ TYPE_DECL_SUPPRESS_DEBUG (TYPE_MAIN_DECL (t)) = 1; #endif } else if (CLASSTYPE_INTERFACE_ONLY (t)) TYPE_DECL_SUPPRESS_DEBUG (TYPE_MAIN_DECL (t)) = 1; } /* Finish debugging output for this type. */ rest_of_type_compilation (t, toplevel_bindings_p ()); return; } /* When T was built up, the member declarations were added in reverse order. Rearrange them to declaration order. */ void unreverse_member_declarations (t) tree t; { tree next; tree prev; tree x; /* The TYPE_FIELDS, TYPE_METHODS, and CLASSTYPE_TAGS are all in reverse order. Put them in declaration order now. */ TYPE_METHODS (t) = nreverse (TYPE_METHODS (t)); CLASSTYPE_TAGS (t) = nreverse (CLASSTYPE_TAGS (t)); /* Actually, for the TYPE_FIELDS, only the non TYPE_DECLs are in reverse order, so we can't just use nreverse. */ prev = NULL_TREE; for (x = TYPE_FIELDS (t); x && TREE_CODE (x) != TYPE_DECL; x = next) { next = TREE_CHAIN (x); TREE_CHAIN (x) = prev; prev = x; } if (prev) { TREE_CHAIN (TYPE_FIELDS (t)) = x; if (prev) TYPE_FIELDS (t) = prev; } } tree finish_struct (t, attributes, warn_anon) tree t, attributes; int warn_anon; { tree name = TYPE_NAME (t); if (TREE_CODE (name) == TYPE_DECL) { extern int lineno; DECL_SOURCE_FILE (name) = input_filename; /* For TYPE_DECL that are not typedefs (those marked with a line number of zero, we don't want to mark them as real typedefs. If this fails one needs to make sure real typedefs have a previous line number, even if it is wrong, that way the below will fill in the right line number. (mrs) */ if (DECL_SOURCE_LINE (name)) DECL_SOURCE_LINE (name) = lineno; name = DECL_NAME (name); } /* Append the fields we need for constructing signature tables. */ if (IS_SIGNATURE (t)) append_signature_fields (t); /* Now that we've got all the field declarations, reverse everything as necessary. */ unreverse_member_declarations (t); cplus_decl_attributes (t, attributes, NULL_TREE); if (processing_template_decl) { tree d = getdecls (); for (; d; d = TREE_CHAIN (d)) { /* If this is the decl for the class or one of the template parms, we've seen all the injected decls. */ if ((TREE_CODE (d) == TYPE_DECL && (TREE_TYPE (d) == t || TREE_CODE (TREE_TYPE (d)) == TEMPLATE_TYPE_PARM || TREE_CODE (TREE_TYPE (d)) == TEMPLATE_TEMPLATE_PARM)) || TREE_CODE (d) == CONST_DECL) break; /* Don't inject cache decls. */ else if (IDENTIFIER_TEMPLATE (DECL_NAME (d))) continue; DECL_TEMPLATE_INJECT (CLASSTYPE_TI_TEMPLATE (t)) = tree_cons (NULL_TREE, d, DECL_TEMPLATE_INJECT (CLASSTYPE_TI_TEMPLATE (t))); } finish_struct_methods (t); TYPE_SIZE (t) = integer_zero_node; } else finish_struct_1 (t, warn_anon); TYPE_BEING_DEFINED (t) = 0; if (current_class_type) popclass (); else error ("trying to finish struct, but kicked out due to previous parse errors."); return t; } /* Return the dynamic type of INSTANCE, if known. Used to determine whether the virtual function table is needed or not. *NONNULL is set iff INSTANCE can be known to be nonnull, regardless of our knowledge of its type. */ static tree fixed_type_or_null (instance, nonnull) tree instance; int *nonnull; { switch (TREE_CODE (instance)) { case INDIRECT_REF: /* Check that we are not going through a cast of some sort. */ if (TREE_TYPE (instance) == TREE_TYPE (TREE_TYPE (TREE_OPERAND (instance, 0)))) instance = TREE_OPERAND (instance, 0); /* fall through... */ case CALL_EXPR: /* This is a call to a constructor, hence it's never zero. */ if (TREE_HAS_CONSTRUCTOR (instance)) { if (nonnull) *nonnull = 1; return TREE_TYPE (instance); } return NULL_TREE; case SAVE_EXPR: /* This is a call to a constructor, hence it's never zero. */ if (TREE_HAS_CONSTRUCTOR (instance)) { if (nonnull) *nonnull = 1; return TREE_TYPE (instance); } return fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull); case RTL_EXPR: return NULL_TREE; case PLUS_EXPR: case MINUS_EXPR: if (TREE_CODE (TREE_OPERAND (instance, 1)) == INTEGER_CST) /* Propagate nonnull. */ fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull); if (TREE_CODE (TREE_OPERAND (instance, 0)) == ADDR_EXPR) return fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull); return NULL_TREE; case NOP_EXPR: case CONVERT_EXPR: return fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull); case ADDR_EXPR: if (nonnull) *nonnull = 1; return fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull); case COMPONENT_REF: return fixed_type_or_null (TREE_OPERAND (instance, 1), nonnull); case VAR_DECL: case FIELD_DECL: if (TREE_CODE (TREE_TYPE (instance)) == ARRAY_TYPE && IS_AGGR_TYPE (TREE_TYPE (TREE_TYPE (instance)))) { if (nonnull) *nonnull = 1; return TREE_TYPE (TREE_TYPE (instance)); } /* fall through... */ case TARGET_EXPR: case PARM_DECL: if (IS_AGGR_TYPE (TREE_TYPE (instance))) { if (nonnull) *nonnull = 1; return TREE_TYPE (instance); } else if (nonnull) { if (instance == current_class_ptr && flag_this_is_variable <= 0) { /* Normally, 'this' must be non-null. */ if (flag_this_is_variable == 0) *nonnull = 1; /* <0 means we're in a constructor and we know our type. */ if (flag_this_is_variable < 0) return TREE_TYPE (TREE_TYPE (instance)); } else if (TREE_CODE (TREE_TYPE (instance)) == REFERENCE_TYPE) /* Reference variables should be references to objects. */ *nonnull = 1; } return NULL_TREE; default: return NULL_TREE; } } /* Return non-zero if the dynamic type of INSTANCE is known, and equivalent to the static type. We also handle the case where INSTANCE is really a pointer. Used to determine whether the virtual function table is needed or not. *NONNULL is set iff INSTANCE can be known to be nonnull, regardless of our knowledge of its type. */ int resolves_to_fixed_type_p (instance, nonnull) tree instance; int *nonnull; { tree t = TREE_TYPE (instance); tree fixed = fixed_type_or_null (instance, nonnull); if (fixed == NULL_TREE) return 0; if (POINTER_TYPE_P (t)) t = TREE_TYPE (t); return same_type_p (TYPE_MAIN_VARIANT (t), TYPE_MAIN_VARIANT (fixed)); } void init_class_processing () { current_class_depth = 0; current_class_stack_size = 10; current_class_stack = (class_stack_node_t) xmalloc (current_class_stack_size * sizeof (struct class_stack_node)); current_lang_stacksize = 10; current_lang_base = (tree *)xmalloc(current_lang_stacksize * sizeof (tree)); current_lang_stack = current_lang_base; access_default_node = build_int_2 (0, 0); access_public_node = build_int_2 (1, 0); access_protected_node = build_int_2 (2, 0); access_private_node = build_int_2 (3, 0); access_default_virtual_node = build_int_2 (4, 0); access_public_virtual_node = build_int_2 (5, 0); access_protected_virtual_node = build_int_2 (6, 0); access_private_virtual_node = build_int_2 (7, 0); /* Keep these values lying around. */ base_layout_decl = build_lang_field_decl (FIELD_DECL, NULL_TREE, error_mark_node); TREE_TYPE (base_layout_decl) = make_node (RECORD_TYPE); gcc_obstack_init (&class_obstack); } /* Set current scope to NAME. CODE tells us if this is a STRUCT, UNION, or ENUM environment. NAME may end up being NULL_TREE if this is an anonymous or late-bound struct (as in "struct { ... } foo;") */ /* Set global variables CURRENT_CLASS_NAME and CURRENT_CLASS_TYPE to appropriate values, found by looking up the type definition of NAME (as a CODE). If MODIFY is 1, we set IDENTIFIER_CLASS_VALUE's of names which can be seen locally to the class. They are shadowed by any subsequent local declaration (including parameter names). If MODIFY is 2, we set IDENTIFIER_CLASS_VALUE's of names which have static meaning (i.e., static members, static member functions, enum declarations, etc). If MODIFY is 3, we set IDENTIFIER_CLASS_VALUE of names which can be seen locally to the class (as in 1), but know that we are doing this for declaration purposes (i.e. friend foo::bar (int)). So that we may avoid calls to lookup_name, we cache the _TYPE nodes of local TYPE_DECLs in the TREE_TYPE field of the name. For multiple inheritance, we perform a two-pass depth-first search of the type lattice. The first pass performs a pre-order search, marking types after the type has had its fields installed in the appropriate IDENTIFIER_CLASS_VALUE slot. The second pass merely unmarks the marked types. If a field or member function name appears in an ambiguous way, the IDENTIFIER_CLASS_VALUE of that name becomes `error_mark_node'. */ void pushclass (type, modify) tree type; int modify; { type = TYPE_MAIN_VARIANT (type); /* Make sure there is enough room for the new entry on the stack. */ if (current_class_depth + 1 >= current_class_stack_size) { current_class_stack_size *= 2; current_class_stack = (class_stack_node_t) xrealloc (current_class_stack, current_class_stack_size * sizeof (struct class_stack_node)); } /* Insert a new entry on the class stack. */ current_class_stack[current_class_depth].name = current_class_name; current_class_stack[current_class_depth].type = current_class_type; current_class_stack[current_class_depth].access = current_access_specifier; current_class_stack[current_class_depth].names_used = 0; current_class_depth++; /* Now set up the new type. */ current_class_name = TYPE_NAME (type); if (TREE_CODE (current_class_name) == TYPE_DECL) current_class_name = DECL_NAME (current_class_name); current_class_type = type; /* By default, things in classes are private, while things in structures or unions are public. */ current_access_specifier = (CLASSTYPE_DECLARED_CLASS (type) ? access_private_node : access_public_node); if (previous_class_type != NULL_TREE && (type != previous_class_type || TYPE_SIZE (previous_class_type) == NULL_TREE) && current_class_depth == 1) { /* Forcibly remove any old class remnants. */ invalidate_class_lookup_cache (); /* Now, free the obstack on which we cached all the values. */ if (class_cache_firstobj) obstack_free (&class_cache_obstack, class_cache_firstobj); class_cache_firstobj = (char*) obstack_finish (&class_cache_obstack); } /* If we're about to enter a nested class, clear IDENTIFIER_CLASS_VALUE for the enclosing classes. */ if (modify && current_class_depth > 1) clear_identifier_class_values (); pushlevel_class (); #if 0 if (CLASSTYPE_TEMPLATE_INFO (type)) overload_template_name (type); #endif if (modify) { if (type != previous_class_type || current_class_depth > 1) push_class_decls (type); else { tree item; /* We are re-entering the same class we just left, so we don't have to search the whole inheritance matrix to find all the decls to bind again. Instead, we install the cached class_shadowed list, and walk through it binding names and setting up IDENTIFIER_TYPE_VALUEs. */ set_class_shadows (previous_class_values); for (item = previous_class_values; item; item = TREE_CHAIN (item)) { tree id = TREE_PURPOSE (item); tree decl = TREE_TYPE (item); push_class_binding (id, decl); if (TREE_CODE (decl) == TYPE_DECL) set_identifier_type_value (id, TREE_TYPE (decl)); } unuse_fields (type); } storetags (CLASSTYPE_TAGS (type)); } } /* When we exit a toplevel class scope, we save the IDENTIFIER_CLASS_VALUEs so that we can restore them quickly if we reenter the class. Here, we've entered some other class, so we must invalidate our cache. */ void invalidate_class_lookup_cache () { tree t; /* This code can be seen as a cache miss. When we've cached a class' scope's bindings and we can't use them, we need to reset them. This is it! */ for (t = previous_class_values; t; t = TREE_CHAIN (t)) IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (t)) = NULL_TREE; previous_class_type = NULL_TREE; } /* Get out of the current class scope. If we were in a class scope previously, that is the one popped to. */ void popclass () { poplevel (1, 0, 0); /* Since poplevel_class does the popping of class decls nowadays, this really only frees the obstack used for these decls. */ pop_class_decls (); current_class_depth--; current_class_name = current_class_stack[current_class_depth].name; current_class_type = current_class_stack[current_class_depth].type; current_access_specifier = current_class_stack[current_class_depth].access; if (current_class_stack[current_class_depth].names_used) splay_tree_delete (current_class_stack[current_class_depth].names_used); } /* Returns 1 if current_class_type is either T or a nested type of T. */ int currently_open_class (t) tree t; { int i; if (t == current_class_type) return 1; for (i = 0; i < current_class_depth; ++i) if (current_class_stack [i].type == t) return 1; return 0; } /* When entering a class scope, all enclosing class scopes' names with static meaning (static variables, static functions, types and enumerators) have to be visible. This recursive function calls pushclass for all enclosing class contexts until global or a local scope is reached. TYPE is the enclosed class and MODIFY is equivalent with the pushclass formal of the same name. */ void push_nested_class (type, modify) tree type; int modify; { tree context; /* A namespace might be passed in error cases, like A::B:C. */ if (type == NULL_TREE || type == error_mark_node || ! IS_AGGR_TYPE (type) || TREE_CODE (type) == NAMESPACE_DECL || TREE_CODE (type) == TEMPLATE_TYPE_PARM || TREE_CODE (type) == TEMPLATE_TEMPLATE_PARM) return; context = DECL_CONTEXT (TYPE_MAIN_DECL (type)); if (context && CLASS_TYPE_P (context)) push_nested_class (context, 2); pushclass (type, modify); } /* Undoes a push_nested_class call. MODIFY is passed on to popclass. */ void pop_nested_class () { tree context = DECL_CONTEXT (TYPE_MAIN_DECL (current_class_type)); popclass (); if (context && CLASS_TYPE_P (context)) pop_nested_class (); } /* Set global variables CURRENT_LANG_NAME to appropriate value so that behavior of name-mangling machinery is correct. */ void push_lang_context (name) tree name; { *current_lang_stack++ = current_lang_name; if (current_lang_stack >= current_lang_base + current_lang_stacksize) { current_lang_base = (tree *)xrealloc (current_lang_base, sizeof (tree) * (current_lang_stacksize + 10)); current_lang_stack = current_lang_base + current_lang_stacksize; current_lang_stacksize += 10; } if (name == lang_name_cplusplus) { strict_prototype = strict_prototypes_lang_cplusplus; current_lang_name = name; } else if (name == lang_name_java) { strict_prototype = strict_prototypes_lang_cplusplus; current_lang_name = name; /* DECL_IGNORED_P is initially set for these types, to avoid clutter. (See record_builtin_java_type in decl.c.) However, that causes incorrect debug entries if these types are actually used. So we re-enable debug output after extern "Java". */ DECL_IGNORED_P (java_byte_type_node) = 0; DECL_IGNORED_P (java_short_type_node) = 0; DECL_IGNORED_P (java_int_type_node) = 0; DECL_IGNORED_P (java_long_type_node) = 0; DECL_IGNORED_P (java_float_type_node) = 0; DECL_IGNORED_P (java_double_type_node) = 0; DECL_IGNORED_P (java_char_type_node) = 0; DECL_IGNORED_P (java_boolean_type_node) = 0; } else if (name == lang_name_c) { strict_prototype = strict_prototypes_lang_c; current_lang_name = name; } else error ("language string `\"%s\"' not recognized", IDENTIFIER_POINTER (name)); } /* Get out of the current language scope. */ void pop_lang_context () { current_lang_name = *--current_lang_stack; if (current_lang_name == lang_name_cplusplus || current_lang_name == lang_name_java) strict_prototype = strict_prototypes_lang_cplusplus; else if (current_lang_name == lang_name_c) strict_prototype = strict_prototypes_lang_c; } /* Type instantiation routines. */ /* Given an OVERLOAD and a TARGET_TYPE, return the function that matches the TARGET_TYPE. If there is no satisfactory match, return error_mark_node, and issue an error message if COMPLAIN is non-zero. If TEMPLATE_ONLY, the name of the overloaded function was a template-id, and EXPLICIT_TARGS are the explicitly provided template arguments. */ static tree resolve_address_of_overloaded_function (target_type, overload, complain, template_only, explicit_targs) tree target_type; tree overload; int complain; int template_only; tree explicit_targs; { /* Here's what the standard says: [over.over] If the name is a function template, template argument deduction is done, and if the argument deduction succeeds, the deduced arguments are used to generate a single template function, which is added to the set of overloaded functions considered. Non-member functions and static member functions match targets of type "pointer-to-function" or "reference-to-function." Nonstatic member functions match targets of type "pointer-to-member function;" the function type of the pointer to member is used to select the member function from the set of overloaded member functions. If a nonstatic member function is selected, the reference to the overloaded function name is required to have the form of a pointer to member as described in 5.3.1. If more than one function is selected, any template functions in the set are eliminated if the set also contains a non-template function, and any given template function is eliminated if the set contains a second template function that is more specialized than the first according to the partial ordering rules 14.5.5.2. After such eliminations, if any, there shall remain exactly one selected function. */ int is_ptrmem = 0; int is_reference = 0; /* We store the matches in a TREE_LIST rooted here. The functions are the TREE_PURPOSE, not the TREE_VALUE, in this list, for easy interoperability with most_specialized_instantiation. */ tree matches = NULL_TREE; tree fn; /* By the time we get here, we should be seeing only real pointer-to-member types, not the internal POINTER_TYPE to METHOD_TYPE representation. */ my_friendly_assert (!(TREE_CODE (target_type) == POINTER_TYPE && (TREE_CODE (TREE_TYPE (target_type)) == METHOD_TYPE)), 0); /* Check that the TARGET_TYPE is reasonable. */ if (TYPE_PTRFN_P (target_type)) /* This is OK. */ ; else if (TYPE_PTRMEMFUNC_P (target_type)) /* This is OK, too. */ is_ptrmem = 1; else if (TREE_CODE (target_type) == FUNCTION_TYPE) { /* This is OK, too. This comes from a conversion to reference type. */ target_type = build_reference_type (target_type); is_reference = 1; } else { if (complain) cp_error("cannot resolve overloaded function `%D' based on conversion to type `%T'", DECL_NAME (OVL_FUNCTION (overload)), target_type); return error_mark_node; } /* If we can find a non-template function that matches, we can just use it. There's no point in generating template instantiations if we're just going to throw them out anyhow. But, of course, we can only do this when we don't *need* a template function. */ if (!template_only) { tree fns; for (fns = overload; fns; fns = OVL_CHAIN (fns)) { tree fn = OVL_FUNCTION (fns); tree fntype; if (TREE_CODE (fn) == TEMPLATE_DECL) /* We're not looking for templates just yet. */ continue; if ((TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE) != is_ptrmem) /* We're looking for a non-static member, and this isn't one, or vice versa. */ continue; /* See if there's a match. */ fntype = TREE_TYPE (fn); if (is_ptrmem) fntype = build_ptrmemfunc_type (build_pointer_type (fntype)); else if (!is_reference) fntype = build_pointer_type (fntype); if (can_convert_arg (target_type, fntype, fn)) matches = scratch_tree_cons (fn, NULL_TREE, matches); } } /* Now, if we've already got a match (or matches), there's no need to proceed to the template functions. But, if we don't have a match we need to look at them, too. */ if (!matches) { tree target_fn_type; tree target_arg_types; tree fns; if (is_ptrmem) target_fn_type = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (target_type)); else target_fn_type = TREE_TYPE (target_type); target_arg_types = TYPE_ARG_TYPES (target_fn_type); for (fns = overload; fns; fns = OVL_CHAIN (fns)) { tree fn = OVL_FUNCTION (fns); tree instantiation; tree instantiation_type; tree targs; if (TREE_CODE (fn) != TEMPLATE_DECL) /* We're only looking for templates. */ continue; if ((TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE) != is_ptrmem) /* We're not looking for a non-static member, and this is one, or vice versa. */ continue; /* Try to do argument deduction. */ targs = make_scratch_vec (DECL_NTPARMS (fn)); if (fn_type_unification (fn, explicit_targs, targs, target_arg_types, NULL_TREE, DEDUCE_EXACT) != 0) /* Argument deduction failed. */ continue; /* Instantiate the template. */ instantiation = instantiate_template (fn, targs); if (instantiation == error_mark_node) /* Instantiation failed. */ continue; /* See if there's a match. */ instantiation_type = TREE_TYPE (instantiation); if (is_ptrmem) instantiation_type = build_ptrmemfunc_type (build_pointer_type (instantiation_type)); else if (!is_reference) instantiation_type = build_pointer_type (instantiation_type); if (can_convert_arg (target_type, instantiation_type, instantiation)) matches = scratch_tree_cons (instantiation, fn, matches); } /* Now, remove all but the most specialized of the matches. */ if (matches) { tree match = most_specialized_instantiation (matches, explicit_targs); if (match != error_mark_node) matches = scratch_tree_cons (match, NULL_TREE, NULL_TREE); } } /* Now we should have exactly one function in MATCHES. */ if (matches == NULL_TREE) { /* There were *no* matches. */ if (complain) { cp_error ("no matches converting function `%D' to type `%#T'", DECL_NAME (OVL_FUNCTION (overload)), target_type); /* print_candidates expects a chain with the functions in TREE_VALUE slots, so we cons one up here (we're losing anyway, so why be clever?). */ for (; overload; overload = OVL_NEXT (overload)) matches = scratch_tree_cons (NULL_TREE, OVL_CURRENT (overload), matches); print_candidates (matches); } return error_mark_node; } else if (TREE_CHAIN (matches)) { /* There were too many matches. */ if (complain) { tree match; cp_error ("converting overloaded function `%D' to type `%#T' is ambiguous", DECL_NAME (OVL_FUNCTION (overload)), target_type); /* Since print_candidates expects the functions in the TREE_VALUE slot, we flip them here. */ for (match = matches; match; match = TREE_CHAIN (match)) TREE_VALUE (match) = TREE_PURPOSE (match); print_candidates (matches); } return error_mark_node; } /* Good, exactly one match. Now, convert it to the correct type. */ fn = TREE_PURPOSE (matches); mark_used (fn); if (TYPE_PTRFN_P (target_type) || TYPE_PTRMEMFUNC_P (target_type)) return build_unary_op (ADDR_EXPR, fn, 0); else { /* The target must be a REFERENCE_TYPE. Above, build_unary_op will mark the function as addressed, but here we must do it explicitly. */ mark_addressable (fn); return fn; } } /* This function will instantiate the type of the expression given in RHS to match the type of LHSTYPE. If errors exist, then return error_mark_node. We only complain is COMPLAIN is set. If we are not complaining, never modify rhs, as overload resolution wants to try many possible instantiations, in hopes that at least one will work. FLAGS is a bitmask, as we see at the top of the function. For non-recursive calls, LHSTYPE should be a function, pointer to function, or a pointer to member function. */ tree instantiate_type (lhstype, rhs, flags) tree lhstype, rhs; int flags; { int complain = (flags & 1); int strict = (flags & 2) ? COMPARE_NO_ATTRIBUTES : COMPARE_STRICT; if (TREE_CODE (lhstype) == UNKNOWN_TYPE) { if (complain) error ("not enough type information"); return error_mark_node; } if (TREE_TYPE (rhs) != NULL_TREE && ! (type_unknown_p (rhs))) { if (comptypes (lhstype, TREE_TYPE (rhs), strict)) return rhs; if (complain) cp_error ("argument of type `%T' does not match `%T'", TREE_TYPE (rhs), lhstype); return error_mark_node; } /* We don't overwrite rhs if it is an overloaded function. Copying it would destroy the tree link. */ if (TREE_CODE (rhs) != OVERLOAD) rhs = copy_node (rhs); /* This should really only be used when attempting to distinguish what sort of a pointer to function we have. For now, any arithmetic operation which is not supported on pointers is rejected as an error. */ switch (TREE_CODE (rhs)) { case TYPE_EXPR: case CONVERT_EXPR: case SAVE_EXPR: case CONSTRUCTOR: case BUFFER_REF: my_friendly_abort (177); return error_mark_node; case INDIRECT_REF: case ARRAY_REF: { tree new_rhs; new_rhs = instantiate_type (build_pointer_type (lhstype), TREE_OPERAND (rhs, 0), flags); if (new_rhs == error_mark_node) return error_mark_node; TREE_TYPE (rhs) = lhstype; TREE_OPERAND (rhs, 0) = new_rhs; return rhs; } case NOP_EXPR: rhs = copy_node (TREE_OPERAND (rhs, 0)); TREE_TYPE (rhs) = unknown_type_node; return instantiate_type (lhstype, rhs, flags); case COMPONENT_REF: { tree field = TREE_OPERAND (rhs, 1); tree r; r = instantiate_type (lhstype, field, flags); if (r != error_mark_node && TYPE_PTRMEMFUNC_P (lhstype)) { if (complain) { tree t = TYPE_PTRMEMFUNC_OBJECT_TYPE (lhstype); if (TREE_CODE (field) == OVERLOAD) field = OVL_FUNCTION (field); if (TREE_CODE (field) == FUNCTION_DECL) { cp_pedwarn ("object-dependent reference `%E' can only be used in a call", DECL_NAME (field)); cp_pedwarn (" to form a pointer to member function, say `&%T::%E'", t, DECL_NAME (field)); } else cp_pedwarn ("object-dependent reference can only be used in a call"); } return r; } return r; } case OFFSET_REF: rhs = TREE_OPERAND (rhs, 1); if (BASELINK_P (rhs)) return instantiate_type (lhstype, TREE_VALUE (rhs), flags); /* This can happen if we are forming a pointer-to-member for a member template. */ my_friendly_assert (TREE_CODE (rhs) == TEMPLATE_ID_EXPR, 0); /* Fall through. */ case TEMPLATE_ID_EXPR: return resolve_address_of_overloaded_function (lhstype, TREE_OPERAND (rhs, 0), complain, /*template_only=*/1, TREE_OPERAND (rhs, 1)); case OVERLOAD: return resolve_address_of_overloaded_function (lhstype, rhs, complain, /*template_only=*/0, /*explicit_targs=*/NULL_TREE); case TREE_LIST: /* Now we should have a baselink. */ my_friendly_assert (BASELINK_P (rhs), 990412); return instantiate_type (lhstype, TREE_VALUE (rhs), flags); case CALL_EXPR: /* This is too hard for now. */ my_friendly_abort (183); return error_mark_node; case PLUS_EXPR: case MINUS_EXPR: case COMPOUND_EXPR: TREE_OPERAND (rhs, 0) = instantiate_type (lhstype, TREE_OPERAND (rhs, 0), flags); if (TREE_OPERAND (rhs, 0) == error_mark_node) return error_mark_node; TREE_OPERAND (rhs, 1) = instantiate_type (lhstype, TREE_OPERAND (rhs, 1), flags); if (TREE_OPERAND (rhs, 1) == error_mark_node) return error_mark_node; TREE_TYPE (rhs) = lhstype; return rhs; case MULT_EXPR: case TRUNC_DIV_EXPR: case FLOOR_DIV_EXPR: case CEIL_DIV_EXPR: case ROUND_DIV_EXPR: case RDIV_EXPR: case TRUNC_MOD_EXPR: case FLOOR_MOD_EXPR: case CEIL_MOD_EXPR: case ROUND_MOD_EXPR: case FIX_ROUND_EXPR: case FIX_FLOOR_EXPR: case FIX_CEIL_EXPR: case FIX_TRUNC_EXPR: case FLOAT_EXPR: case NEGATE_EXPR: case ABS_EXPR: case MAX_EXPR: case MIN_EXPR: case FFS_EXPR: case BIT_AND_EXPR: case BIT_IOR_EXPR: case BIT_XOR_EXPR: case LSHIFT_EXPR: case RSHIFT_EXPR: case LROTATE_EXPR: case RROTATE_EXPR: case PREINCREMENT_EXPR: case PREDECREMENT_EXPR: case POSTINCREMENT_EXPR: case POSTDECREMENT_EXPR: if (complain) error ("invalid operation on uninstantiated type"); return error_mark_node; case TRUTH_AND_EXPR: case TRUTH_OR_EXPR: case TRUTH_XOR_EXPR: case LT_EXPR: case LE_EXPR: case GT_EXPR: case GE_EXPR: case EQ_EXPR: case NE_EXPR: case TRUTH_ANDIF_EXPR: case TRUTH_ORIF_EXPR: case TRUTH_NOT_EXPR: if (complain) error ("not enough type information"); return error_mark_node; case COND_EXPR: if (type_unknown_p (TREE_OPERAND (rhs, 0))) { if (complain) error ("not enough type information"); return error_mark_node; } TREE_OPERAND (rhs, 1) = instantiate_type (lhstype, TREE_OPERAND (rhs, 1), flags); if (TREE_OPERAND (rhs, 1) == error_mark_node) return error_mark_node; TREE_OPERAND (rhs, 2) = instantiate_type (lhstype, TREE_OPERAND (rhs, 2), flags); if (TREE_OPERAND (rhs, 2) == error_mark_node) return error_mark_node; TREE_TYPE (rhs) = lhstype; return rhs; case MODIFY_EXPR: TREE_OPERAND (rhs, 1) = instantiate_type (lhstype, TREE_OPERAND (rhs, 1), flags); if (TREE_OPERAND (rhs, 1) == error_mark_node) return error_mark_node; TREE_TYPE (rhs) = lhstype; return rhs; case ADDR_EXPR: return instantiate_type (lhstype, TREE_OPERAND (rhs, 0), flags); case ENTRY_VALUE_EXPR: my_friendly_abort (184); return error_mark_node; case ERROR_MARK: return error_mark_node; default: my_friendly_abort (185); return error_mark_node; } } /* Return the name of the virtual function pointer field (as an IDENTIFIER_NODE) for the given TYPE. Note that this may have to look back through base types to find the ultimate field name. (For single inheritance, these could all be the same name. Who knows for multiple inheritance). */ static tree get_vfield_name (type) tree type; { tree binfo = TYPE_BINFO (type); char *buf; while (BINFO_BASETYPES (binfo) && TYPE_VIRTUAL_P (BINFO_TYPE (BINFO_BASETYPE (binfo, 0))) && ! TREE_VIA_VIRTUAL (BINFO_BASETYPE (binfo, 0))) binfo = BINFO_BASETYPE (binfo, 0); type = BINFO_TYPE (binfo); buf = (char *) alloca (sizeof (VFIELD_NAME_FORMAT) + TYPE_NAME_LENGTH (type) + 2); sprintf (buf, VFIELD_NAME_FORMAT, TYPE_NAME_STRING (type)); return get_identifier (buf); } void print_class_statistics () { #ifdef GATHER_STATISTICS fprintf (stderr, "convert_harshness = %d\n", n_convert_harshness); fprintf (stderr, "compute_conversion_costs = %d\n", n_compute_conversion_costs); fprintf (stderr, "build_method_call = %d (inner = %d)\n", n_build_method_call, n_inner_fields_searched); if (n_vtables) { fprintf (stderr, "vtables = %d; vtable searches = %d\n", n_vtables, n_vtable_searches); fprintf (stderr, "vtable entries = %d; vtable elems = %d\n", n_vtable_entries, n_vtable_elems); } #endif } /* Push an obstack which is sufficiently long-lived to hold such class decls that may be cached in the previous_class_values list. The effect is undone by pop_obstacks. */ void push_cache_obstack () { static int cache_obstack_initialized; if (!cache_obstack_initialized) { gcc_obstack_init (&class_cache_obstack); class_cache_firstobj = (char*) obstack_finish (&class_cache_obstack); cache_obstack_initialized = 1; } push_obstacks_nochange (); current_obstack = &class_cache_obstack; } /* Build a dummy reference to ourselves so Derived::Base (and A::A) works, according to [class]: The class-name is also inserted into the scope of the class itself. For purposes of access checking, the inserted class name is treated as if it were a public member name. */ void build_self_reference () { tree name = constructor_name (current_class_type); tree value = build_lang_decl (TYPE_DECL, name, current_class_type); tree saved_cas; DECL_NONLOCAL (value) = 1; DECL_CONTEXT (value) = current_class_type; DECL_CLASS_CONTEXT (value) = current_class_type; DECL_ARTIFICIAL (value) = 1; saved_cas = current_access_specifier; current_access_specifier = access_public_node; finish_member_declaration (value); current_access_specifier = saved_cas; } /* Returns 1 if TYPE contains only padding bytes. */ int is_empty_class (type) tree type; { tree t; if (type == error_mark_node) return 0; if (! IS_AGGR_TYPE (type)) return 0; if (flag_new_abi) return CLASSTYPE_SIZE (type) == integer_zero_node; if (TYPE_BINFO_BASETYPES (type)) return 0; t = TYPE_FIELDS (type); while (t && TREE_CODE (t) != FIELD_DECL) t = TREE_CHAIN (t); return (t == NULL_TREE); } /* Find the enclosing class of the given NODE. NODE can be a *_DECL or a *_TYPE node. NODE can also be a local class. */ tree get_enclosing_class (type) tree type; { tree node = type; while (node && TREE_CODE (node) != NAMESPACE_DECL) { switch (TREE_CODE_CLASS (TREE_CODE (node))) { case 'd': node = DECL_CONTEXT (node); break; case 't': if (node != type) return node; node = TYPE_CONTEXT (node); break; default: my_friendly_abort (0); } } return NULL_TREE; } /* Return 1 if TYPE or one of its enclosing classes is derived from BASE. */ int is_base_of_enclosing_class (base, type) tree base, type; { while (type) { if (get_binfo (base, type, 0)) return 1; type = get_enclosing_class (type); } return 0; } /* Note that NAME was looked up while the current class was being defined and that the result of that lookup was DECL. */ void maybe_note_name_used_in_class (name, decl) tree name; tree decl; { splay_tree names_used; /* If we're not defining a class, there's nothing to do. */ if (!current_class_type || !TYPE_BEING_DEFINED (current_class_type)) return; /* If there's already a binding for this NAME, then we don't have anything to worry about. */ if (IDENTIFIER_CLASS_VALUE (name)) return; if (!current_class_stack[current_class_depth - 1].names_used) current_class_stack[current_class_depth - 1].names_used = splay_tree_new (splay_tree_compare_pointers, 0, 0); names_used = current_class_stack[current_class_depth - 1].names_used; splay_tree_insert (names_used, (splay_tree_key) name, (splay_tree_value) decl); } /* Note that NAME was declared (as DECL) in the current class. Check to see that the declaration is legal. */ void note_name_declared_in_class (name, decl) tree name; tree decl; { splay_tree names_used; splay_tree_node n; /* Look to see if we ever used this name. */ names_used = current_class_stack[current_class_depth - 1].names_used; if (!names_used) return; n = splay_tree_lookup (names_used, (splay_tree_key) name); if (n) { /* [basic.scope.class] A name N used in a class S shall refer to the same declaration in its context and when re-evaluated in the completed scope of S. */ cp_error ("declaration of `%#D'", decl); cp_error_at ("changes meaning of `%s' from `%+#D'", IDENTIFIER_POINTER (DECL_NAME (decl)), (tree) n->value); } } Index: vendor/gcc/dist/contrib/gcc/cp/cp-tree.h =================================================================== --- vendor/gcc/dist/contrib/gcc/cp/cp-tree.h (revision 60966) +++ vendor/gcc/dist/contrib/gcc/cp/cp-tree.h (revision 60967) @@ -1,3524 +1,3574 @@ /* Definitions for C++ parsing and type checking. Copyright (C) 1987, 92-97, 1998, 1999 Free Software Foundation, Inc. Hacked by Michael Tiemann (tiemann@cygnus.com) 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. */ #ifndef _CP_TREE_H #define _CP_TREE_H /* Usage of TREE_LANG_FLAG_?: 0: BINFO_MARKED (BINFO nodes). COMPOUND_STMT_NO_SCOPE (in COMPOUND_STMT). NEW_EXPR_USE_GLOBAL (in NEW_EXPR). DELETE_EXPR_USE_GLOBAL (in DELETE_EXPR). LOOKUP_EXPR_GLOBAL (in LOOKUP_EXPR). TREE_NEGATED_INT (in INTEGER_CST). TREE_INDIRECT_USING (in NAMESPACE_DECL). IDENTIFIER_MARKED (used by search routines). LOCAL_BINDING_P (in CPLUS_BINDING) 1: IDENTIFIER_VIRTUAL_P. TI_PENDING_TEMPLATE_FLAG. TEMPLATE_PARMS_FOR_INLINE. DELETE_EXPR_USE_VEC (in DELETE_EXPR). (TREE_CALLS_NEW) (in _EXPR or _REF) (commented-out). TYPE_USES_COMPLEX_INHERITANCE (in _TYPE). C_DECLARED_LABEL_FLAG. INHERITED_VALUE_BINDING_P (in CPLUS_BINDING) BASELINK_P (in TREE_LIST) 2: IDENTIFIER_OPNAME_P. BINFO_VBASE_MARKED. BINFO_FIELDS_MARKED. TYPE_VIRTUAL_P. 3: TYPE_USES_VIRTUAL_BASECLASSES (in a class TYPE). BINFO_VTABLE_PATH_MARKED. BINFO_PUSHDECLS_MARKED. (TREE_REFERENCE_EXPR) (in NON_LVALUE_EXPR) (commented-out). 4: BINFO_NEW_VTABLE_MARKED. TREE_HAS_CONSTRUCTOR (in INDIRECT_REF, SAVE_EXPR, CONSTRUCTOR, or FIELD_DECL). - 5: Not used. + 5: TYPE_USES_PVBASES (in a class TYPE). 6: Not used. Usage of TYPE_LANG_FLAG_?: 0: C_TYPE_FIELDS_READONLY (in RECORD_TYPE or UNION_TYPE). 1: TYPE_HAS_CONSTRUCTOR. 2: TYPE_HAS_DESTRUCTOR. 3: TYPE_FOR_JAVA. 4: TYPE_NEEDS_DESTRUCTOR. 5: IS_AGGR_TYPE. 6: TYPE_BUILT_IN. Usage of DECL_LANG_FLAG_?: 0: DECL_ERROR_REPORTED (in VAR_DECL). DECL_TEMPLATE_PARM_P (in CONST_DECL, TYPE_DECL, or TEMPLATE_DECL) 1: C_TYPEDEF_EXPLICITLY_SIGNED (in TYPE_DECL). DECL_TEMPLATE_INSTANTIATED (in a VAR_DECL or a FUNCTION_DECL) 2: DECL_THIS_EXTERN (in VAR_DECL or FUNCTION_DECL). 3: DECL_IN_AGGR_P. 4: DECL_MAYBE_TEMPLATE. 5: DECL_INTERFACE_KNOWN. 6: DECL_THIS_STATIC (in VAR_DECL or FUNCTION_DECL). 7: DECL_DEAD_FOR_LOCAL (in VAR_DECL). Usage of language-independent fields in a language-dependent manner: TYPE_ALIAS_SET This field is used by TYPENAME_TYPEs, TEMPLATE_TYPE_PARMs, and so forth as a substitute for the mark bits provided in `lang_type'. At present, only the six low-order bits are used. TYPE_BINFO For an ENUMERAL_TYPE, this is ENUM_TEMPLATE_INFO. For a TYPENAME_TYPE, this is TYPENAME_TYPE_FULLNAME. For a TEMPLATE_TEMPLATE_PARM, this is TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO. DECL_SAVED_INSNS/DECL_FIELD_SIZE For a static VAR_DECL, this is DECL_INIT_PRIORITY. */ /* Language-dependent contents of an identifier. */ struct lang_identifier { struct tree_identifier ignore; tree namespace_bindings; tree bindings; tree class_value; tree class_template_info; struct lang_id2 *x; }; struct lang_id2 { tree label_value, implicit_decl; tree error_locus; }; typedef struct { tree t; int new_type_flag; } flagged_type_tree; typedef struct { char common[sizeof (struct tree_common)]; struct rtx_def *rtl; /* Unused, but required to match up with what the middle-end expects. */ HOST_WIDE_INT index; HOST_WIDE_INT level; HOST_WIDE_INT orig_level; tree decl; } template_parm_index; typedef struct ptrmem_cst { char common[sizeof (struct tree_common)]; tree member; }* ptrmem_cst_t; /* Nonzero if this binding is for a local scope, as opposed to a class or namespace scope. */ #define LOCAL_BINDING_P(NODE) TREE_LANG_FLAG_0(NODE) /* Nonzero if BINDING_VALUE is from a base class of the class which is currently being defined. */ #define INHERITED_VALUE_BINDING_P(NODE) TREE_LANG_FLAG_1(NODE) /* For a binding between a name and an entity at a non-local scope, defines the scope where the binding is declared. (Either a class _TYPE node, or a NAMESPACE_DECL.) This macro should be used only for namespace-level bindings; on the IDENTIFIER_BINDING list BINDING_LEVEL is used instead. */ #define BINDING_SCOPE(NODE) (((struct tree_binding*)NODE)->scope.scope) /* This is the declaration bound to the name. Possible values: variable, overloaded function, namespace, template, enumerator. */ #define BINDING_VALUE(NODE) (((struct tree_binding*)NODE)->value) /* If name is bound to a type, this is the type (struct, union, enum). */ #define BINDING_TYPE(NODE) TREE_TYPE(NODE) #define IDENTIFIER_GLOBAL_VALUE(NODE) \ namespace_binding (NODE, global_namespace) #define SET_IDENTIFIER_GLOBAL_VALUE(NODE, VAL) \ set_namespace_binding (NODE, global_namespace, VAL) #define IDENTIFIER_NAMESPACE_VALUE(NODE) \ namespace_binding (NODE, current_namespace) #define SET_IDENTIFIER_NAMESPACE_VALUE(NODE, VAL) \ set_namespace_binding (NODE, current_namespace, VAL) struct tree_binding { char common[sizeof (struct tree_common)]; union { tree scope; struct binding_level *level; } scope; tree value; }; /* The overloaded FUNCTION_DECL. */ #define OVL_FUNCTION(NODE) (((struct tree_overload*)NODE)->function) #define OVL_CHAIN(NODE) TREE_CHAIN(NODE) /* Polymorphic access to FUNCTION and CHAIN. */ #define OVL_CURRENT(NODE) \ ((TREE_CODE(NODE)==OVERLOAD) ? OVL_FUNCTION(NODE) : NODE) #define OVL_NEXT(NODE) \ ((TREE_CODE(NODE)==OVERLOAD) ? TREE_CHAIN(NODE) : NULL_TREE) /* If set, this was imported in a using declaration. This is not to confuse with being used somewhere, which is not important for this node. */ #define OVL_USED(NODE) TREE_USED(NODE) struct tree_overload { char common[sizeof (struct tree_common)]; tree function; }; /* A `baselink' is a TREE_LIST whose TREE_PURPOSE is a BINFO indicating a particular base class, and whose TREE_VALUE is a (possibly overloaded) function from that base class. */ #define BASELINK_P(NODE) \ (TREE_CODE ((NODE)) == TREE_LIST && TREE_LANG_FLAG_1 ((NODE))) #define SET_BASELINK_P(NODE) \ (TREE_LANG_FLAG_1 ((NODE)) = 1) #define WRAPPER_PTR(NODE) (((struct tree_wrapper*)NODE)->u.ptr) #define WRAPPER_INT(NODE) (((struct tree_wrapper*)NODE)->u.i) struct tree_wrapper { char common[sizeof (struct tree_common)]; union { void *ptr; int i; } u; }; #define SRCLOC_FILE(NODE) (((struct tree_srcloc*)NODE)->filename) #define SRCLOC_LINE(NODE) (((struct tree_srcloc*)NODE)->linenum) struct tree_srcloc { char common[sizeof (struct tree_common)]; char *filename; int linenum; }; /* To identify to the debug emitters if it should pay attention to the flag `-Wtemplate-debugging'. */ #define HAVE_TEMPLATES 1 /* Macros for access to language-specific slots in an identifier. */ #define IDENTIFIER_NAMESPACE_BINDINGS(NODE) \ (((struct lang_identifier *)(NODE))->namespace_bindings) #define IDENTIFIER_TEMPLATE(NODE) \ (((struct lang_identifier *)(NODE))->class_template_info) /* The IDENTIFIER_BINDING is the innermost CPLUS_BINDING for the identifier. It's TREE_CHAIN is the next outermost binding. Each BINDING_VALUE is a DECL for the associated declaration. Thus, name lookup consists simply of pulling off the node at the front of the list (modulo oddities for looking up the names of types, and such.) You can use BINDING_SCOPE or BINDING_LEVEL to determine the scope that bound the name. */ #define IDENTIFIER_BINDING(NODE) \ (((struct lang_identifier*) (NODE))->bindings) /* The IDENTIFIER_VALUE is the value of the IDENTIFIER_BINDING, or NULL_TREE if there is no binding. */ #define IDENTIFIER_VALUE(NODE) \ (IDENTIFIER_BINDING (NODE) \ ? BINDING_VALUE (IDENTIFIER_BINDING (NODE)) \ : NULL_TREE) /* If IDENTIFIER_CLASS_VALUE is set, then NODE is bound in the current class, and IDENTIFIER_CLASS_VALUE is the value binding. This is just a pointer to the BINDING_VALUE of one of the bindings in the IDENTIFIER_BINDINGs list, so any time that this is non-NULL so is IDENTIFIER_BINDING. */ #define IDENTIFIER_CLASS_VALUE(NODE) \ (((struct lang_identifier *) (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 be found through lookup. */ #define IDENTIFIER_TYPE_VALUE(NODE) (identifier_type_value(NODE)) #define REAL_IDENTIFIER_TYPE_VALUE(NODE) (TREE_TYPE (NODE)) #define SET_IDENTIFIER_TYPE_VALUE(NODE,TYPE) (TREE_TYPE (NODE) = TYPE) #define IDENTIFIER_HAS_TYPE_VALUE(NODE) (IDENTIFIER_TYPE_VALUE (NODE) ? 1 : 0) #define LANG_ID_FIELD(NAME,NODE) \ (((struct lang_identifier *)(NODE))->x \ ? ((struct lang_identifier *)(NODE))->x->NAME : 0) #define SET_LANG_ID(NODE,VALUE,NAME) \ (((struct lang_identifier *)(NODE))->x == 0 \ ? ((struct lang_identifier *)(NODE))->x \ = (struct lang_id2 *)perm_calloc (1, sizeof (struct lang_id2)) : 0, \ ((struct lang_identifier *)(NODE))->x->NAME = (VALUE)) #define IDENTIFIER_LABEL_VALUE(NODE) LANG_ID_FIELD(label_value, NODE) #define SET_IDENTIFIER_LABEL_VALUE(NODE,VALUE) \ SET_LANG_ID(NODE, VALUE, label_value) #define IDENTIFIER_IMPLICIT_DECL(NODE) LANG_ID_FIELD(implicit_decl, NODE) #define SET_IDENTIFIER_IMPLICIT_DECL(NODE,VALUE) \ SET_LANG_ID(NODE, VALUE, implicit_decl) #define IDENTIFIER_ERROR_LOCUS(NODE) LANG_ID_FIELD(error_locus, NODE) #define SET_IDENTIFIER_ERROR_LOCUS(NODE,VALUE) \ SET_LANG_ID(NODE, VALUE, error_locus) #define IDENTIFIER_VIRTUAL_P(NODE) TREE_LANG_FLAG_1(NODE) /* Nonzero if this identifier is the prefix for a mangled C++ operator name. */ #define IDENTIFIER_OPNAME_P(NODE) TREE_LANG_FLAG_2(NODE) /* Nonzero if this identifier is the name of a type-conversion operator. */ #define IDENTIFIER_TYPENAME_P(NODE) \ (! strncmp (IDENTIFIER_POINTER (NODE), \ OPERATOR_TYPENAME_FORMAT, \ strlen (OPERATOR_TYPENAME_FORMAT))) /* Nonzero means reject anything that ANSI standard C forbids. */ extern int pedantic; /* In a RECORD_TYPE or UNION_TYPE, nonzero if any component is read-only. */ #define C_TYPE_FIELDS_READONLY(type) TYPE_LANG_FLAG_0 (type) /* Record in each node resulting from a binary operator what operator was specified for it. */ #define C_EXP_ORIGINAL_CODE(exp) ((enum tree_code) TREE_COMPLEXITY (exp)) /* Store a value in that field. */ #define C_SET_EXP_ORIGINAL_CODE(exp, code) \ (TREE_COMPLEXITY (exp) = (int)(code)) /* If non-zero, a VAR_DECL whose cleanup will cause a throw to the next exception handler. */ extern tree exception_throw_decl; extern tree double_type_node, long_double_type_node, float_type_node; extern tree char_type_node, unsigned_char_type_node, signed_char_type_node; extern tree ptrdiff_type_node; extern tree short_integer_type_node, short_unsigned_type_node; extern tree long_integer_type_node, long_unsigned_type_node; extern tree long_long_integer_type_node, long_long_unsigned_type_node; extern tree unsigned_type_node; extern tree string_type_node, char_array_type_node, int_array_type_node; extern tree wchar_array_type_node; extern tree wchar_type_node, signed_wchar_type_node, unsigned_wchar_type_node; extern tree complex_integer_type_node; extern tree complex_float_type_node; extern tree complex_double_type_node; extern tree complex_long_double_type_node; extern tree intQI_type_node, unsigned_intQI_type_node; extern tree intHI_type_node, unsigned_intHI_type_node; extern tree intSI_type_node, unsigned_intSI_type_node; extern tree intDI_type_node, unsigned_intDI_type_node; #if HOST_BITS_PER_WIDE_INT >= 64 extern tree intTI_type_node, unsigned_intTI_type_node; #endif extern tree java_byte_type_node; extern tree java_short_type_node; extern tree java_int_type_node; extern tree java_long_type_node; extern tree java_float_type_node; extern tree java_double_type_node; extern tree java_char_type_node; extern tree java_boolean_type_node; extern int current_function_returns_value; extern int current_function_returns_null; extern tree current_function_return_value; extern tree current_namespace; extern tree global_namespace; extern tree ridpointers[]; extern tree ansi_opname[]; extern tree ansi_assopname[]; /* Nonzero means `$' can be in an identifier. */ extern int dollars_in_ident; /* Nonzero means allow type mismatches in conditional expressions; just make their values `void'. */ extern int flag_cond_mismatch; /* Nonzero means don't recognize the keyword `asm'. */ extern int flag_no_asm; /* For cross referencing. */ extern int flag_gnu_xref; /* For environments where you can use GNU binutils (as, ld in particular). */ extern int flag_gnu_binutils; /* Nonzero means warn about implicit declarations. */ extern int warn_implicit; /* Nonzero means warn about usage of long long when `-pedantic'. */ extern int warn_long_long; /* Nonzero means warn when all ctors or dtors are private, and the class has no friends. */ extern int warn_ctor_dtor_privacy; /* Nonzero means warn about function definitions that default the return type or that use a null return and have a return-type other than void. */ extern int warn_return_type; /* Nonzero means give string constants the type `const char *', as mandated by the standard. */ extern int flag_const_strings; /* Nonzero means warn about deprecated conversion from string constant to `char *'. */ extern int warn_write_strings; /* Nonzero means warn about sizeof(function) or addition/subtraction of function pointers. */ extern int warn_pointer_arith; /* Nonzero means warn about suggesting putting in ()'s. */ extern int warn_parentheses; /* Nonzero means warn about multiple (redundant) decls for the same single variable or function. */ extern int warn_redundant_decls; /* Warn if initializer is not completely bracketed. */ extern int warn_missing_braces; /* Warn about comparison of signed and unsigned values. */ extern int warn_sign_compare; /* Warn about a subscript that has type char. */ extern int warn_char_subscripts; /* Nonzero means warn about pointer casts that can drop a type qualifier from the pointer target type. */ extern int warn_cast_qual; /* Warn about *printf or *scanf format/argument anomalies. */ extern int warn_format; /* Nonzero means warn about non virtual destructors in classes that have virtual functions. */ extern int warn_nonvdtor; /* Non-zero means warn when we convert a pointer to member function into a pointer to (void or function). */ extern int warn_pmf2ptr; /* Nonzero means warn about violation of some Effective C++ style rules. */ extern int warn_ecpp; /* Nonzero means warn where overload resolution chooses a promotion from unsigned to signed over a conversion to an unsigned of the same size. */ extern int warn_sign_promo; /* Non-zero means warn when a function is declared extern and later inline. */ extern int warn_extern_inline; /* Non-zero means warn when an old-style cast is used. */ extern int warn_old_style_cast; /* Nonzero means to treat bitfields as unsigned unless they say `signed'. */ extern int flag_signed_bitfields; /* 3 means write out only virtuals function tables `defined' in this implementation file. 2 means write out only specific virtual function tables and give them (C) public access. 1 means write out virtual function tables and give them (C) public access. 0 means write out virtual function tables and give them (C) static access (default). -1 means declare virtual function tables extern. */ extern int write_virtuals; /* True for more efficient but incompatible (not fully tested) vtable implementation (using thunks). - 0 is old behavior; 1 is new behavior. */ -extern int flag_vtable_thunks; + 0 is old behavior; 1 is new behavior; 3 adds vlist arguments; + 2 is 3 plus backwards-compatibility to 1. */ +extern int flag_vtable_thunks, flag_vtable_thunks_compat; /* INTERFACE_ONLY nonzero means that we are in an "interface" section of the compiler. INTERFACE_UNKNOWN nonzero means we cannot trust the value of INTERFACE_ONLY. If INTERFACE_UNKNOWN is zero and INTERFACE_ONLY is zero, it means that we are responsible for exporting definitions that others might need. */ extern int interface_only, interface_unknown; /* Nonzero means we should attempt to elide constructors when possible. */ extern int flag_elide_constructors; /* Nonzero means enable obscure ANSI features and disable GNU extensions that might cause ANSI-compliant code to be miscompiled. */ extern int flag_ansi; /* Nonzero means recognize and handle signature language constructs. */ extern int flag_handle_signatures; /* Nonzero means that member functions defined in class scope are inline by default. */ extern int flag_default_inline; /* The name-mangling scheme to use. Versions of gcc before 2.8 use version 0. */ extern int name_mangling_version; /* Nonzero means that guiding declarations are allowed. */ extern int flag_guiding_decls; /* Nonzero if squashed mangling is to be performed. This uses the B and K codes to reference previously seen class types and class qualifiers. */ extern int flag_do_squangling; /* Nonzero means generate separate instantiation control files and juggle them at link time. */ extern int flag_use_repository; /* Nonzero if we want to issue diagnostics that the standard says are not required. */ extern int flag_optional_diags; /* Nonzero means do not consider empty argument prototype to mean function takes no arguments. */ extern int flag_strict_prototype; /* Nonzero means output .vtable_{entry,inherit} for use in doing vtable gc. */ extern int flag_vtable_gc; /* Nonzero means make the default pedwarns warnings instead of errors. The value of this flag is ignored if -pedantic is specified. */ extern int flag_permissive; /* Nonzero if we want to obey access control semantics. */ extern int flag_access_control; /* C++ language-specific tree codes. */ #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) SYM, enum cplus_tree_code { __DUMMY = LAST_AND_UNUSED_TREE_CODE, #include "cp-tree.def" LAST_CPLUS_TREE_CODE }; #undef DEFTREECODE enum languages { lang_c, lang_cplusplus, lang_java }; /* Macros to make error reporting functions' lives easier. */ #define TYPE_IDENTIFIER(NODE) (DECL_NAME (TYPE_NAME (NODE))) #define TYPE_NAME_STRING(NODE) (IDENTIFIER_POINTER (TYPE_IDENTIFIER (NODE))) #define TYPE_NAME_LENGTH(NODE) (IDENTIFIER_LENGTH (TYPE_IDENTIFIER (NODE))) #define TYPE_ASSEMBLER_NAME_STRING(NODE) (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (TYPE_NAME (NODE)))) #define TYPE_ASSEMBLER_NAME_LENGTH(NODE) (IDENTIFIER_LENGTH (DECL_ASSEMBLER_NAME (TYPE_NAME (NODE)))) /* The _DECL for this _TYPE. */ #define TYPE_MAIN_DECL(NODE) (TYPE_STUB_DECL (TYPE_MAIN_VARIANT (NODE))) /* Nonzero if T is a class (or struct or union) type. Also nonzero for template type parameters and typename types. Despite its name, this macro has nothing to do with the definition of aggregate given in the standard. Think of this macro as MAYBE_CLASS_TYPE_P. */ #define IS_AGGR_TYPE(t) \ (TREE_CODE (t) == TEMPLATE_TYPE_PARM \ || TREE_CODE (t) == TYPENAME_TYPE \ || TREE_CODE (t) == TYPEOF_TYPE \ || TYPE_LANG_FLAG_5 (t)) /* Set IS_AGGR_TYPE for T to VAL. T must be a class, struct, or union type. */ #define SET_IS_AGGR_TYPE(T, VAL) \ (TYPE_LANG_FLAG_5 (T) = (VAL)) /* Nonzero if T is a class type. Zero for template type parameters, typename types, and so forth. */ #define CLASS_TYPE_P(t) \ (IS_AGGR_TYPE_CODE (TREE_CODE (t)) && IS_AGGR_TYPE (t)) #define IS_AGGR_TYPE_CODE(t) (t == RECORD_TYPE || t == UNION_TYPE) #define IS_AGGR_TYPE_2(TYPE1,TYPE2) \ (TREE_CODE (TYPE1) == TREE_CODE (TYPE2) \ && IS_AGGR_TYPE (TYPE1)&IS_AGGR_TYPE (TYPE2)) #define IS_OVERLOAD_TYPE(t) \ (IS_AGGR_TYPE (t) || TREE_CODE (t) == ENUMERAL_TYPE) /* In a *_TYPE, nonzero means a built-in type. */ #define TYPE_BUILT_IN(NODE) TYPE_LANG_FLAG_6(NODE) /* True if this a "Java" type, defined in 'extern "Java"'. */ #define TYPE_FOR_JAVA(NODE) TYPE_LANG_FLAG_3(NODE) /* The type qualifiers for this type, including the qualifiers on the elements for an array type. */ #define CP_TYPE_QUALS(NODE) \ ((TREE_CODE (NODE) != ARRAY_TYPE) \ ? TYPE_QUALS (NODE) : cp_type_quals (NODE)) /* Nonzero if this type is const-qualified. */ #define CP_TYPE_CONST_P(NODE) \ ((CP_TYPE_QUALS (NODE) & TYPE_QUAL_CONST) != 0) /* Nonzero if this type is volatile-qualified. */ #define CP_TYPE_VOLATILE_P(NODE) \ ((CP_TYPE_QUALS (NODE) & TYPE_QUAL_VOLATILE) != 0) /* Nonzero if this type is restrict-qualified. */ #define CP_TYPE_RESTRICT_P(NODE) \ ((CP_TYPE_QUALS (NODE) & TYPE_QUAL_RESTRICT) != 0) /* Nonzero if this type is const-qualified, but not volatile-qualified. Other qualifiers are ignored. This macro is used to test whether or not it is OK to bind an rvalue to a reference. */ #define CP_TYPE_CONST_NON_VOLATILE_P(NODE) \ ((CP_TYPE_QUALS (NODE) & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE)) \ == TYPE_QUAL_CONST) #define DELTA_FROM_VTABLE_ENTRY(ENTRY) \ (!flag_vtable_thunks ? \ TREE_VALUE (CONSTRUCTOR_ELTS (ENTRY)) \ : TREE_CODE (TREE_OPERAND ((ENTRY), 0)) != THUNK_DECL ? integer_zero_node \ : build_int_2 (THUNK_DELTA (TREE_OPERAND ((ENTRY), 0)), 0)) /* Virtual function addresses can be gotten from a virtual function table entry using this macro. */ #define FNADDR_FROM_VTABLE_ENTRY(ENTRY) \ (!flag_vtable_thunks ? \ TREE_VALUE (TREE_CHAIN (TREE_CHAIN (CONSTRUCTOR_ELTS (ENTRY)))) \ : TREE_CODE (TREE_OPERAND ((ENTRY), 0)) != THUNK_DECL ? (ENTRY) \ : DECL_INITIAL (TREE_OPERAND ((ENTRY), 0))) #define SET_FNADDR_FROM_VTABLE_ENTRY(ENTRY,VALUE) \ (TREE_VALUE (TREE_CHAIN (TREE_CHAIN (CONSTRUCTOR_ELTS (ENTRY)))) = (VALUE)) #define FUNCTION_ARG_CHAIN(NODE) (TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (NODE)))) #define PROMOTES_TO_AGGR_TYPE(NODE,CODE) \ (((CODE) == TREE_CODE (NODE) \ && IS_AGGR_TYPE (TREE_TYPE (NODE))) \ || IS_AGGR_TYPE (NODE)) /* Nonzero iff TYPE is uniquely derived from PARENT. Under MI, PARENT can be an ambiguous base class of TYPE, and this macro will be false. */ #define UNIQUELY_DERIVED_FROM_P(PARENT, TYPE) (get_base_distance (PARENT, TYPE, 0, (tree *)0) >= 0) #define ACCESSIBLY_DERIVED_FROM_P(PARENT, TYPE) (get_base_distance (PARENT, TYPE, -1, (tree *)0) >= 0) #define ACCESSIBLY_UNIQUELY_DERIVED_P(PARENT, TYPE) (get_base_distance (PARENT, TYPE, 1, (tree *)0) >= 0) #define DERIVED_FROM_P(PARENT, TYPE) (get_base_distance (PARENT, TYPE, 0, (tree *)0) != -1) /* This structure provides additional information above and beyond what is provide in the ordinary tree_type. In the past, we used it for the types of class types, template parameters types, typename types, and so forth. However, there can be many (tens to hundreds of thousands) of template parameter types in a compilation, and there's no need for this additional information in that case. Therefore, we now use this data structure only for class types. In the past, it was thought that there would be relatively few class types. However, in the presence of heavy use of templates, many (i.e., thousands) of classes can easily be generated. Therefore, we should endeavor to keep the size of this structure to a minimum. */ struct lang_type { struct { unsigned has_type_conversion : 1; unsigned has_init_ref : 1; unsigned has_default_ctor : 1; unsigned uses_multiple_inheritance : 1; unsigned const_needs_init : 1; unsigned ref_needs_init : 1; unsigned has_const_assign_ref : 1; unsigned anon_union : 1; unsigned has_nonpublic_ctor : 2; unsigned has_nonpublic_assign_ref : 2; unsigned vtable_needs_writing : 1; unsigned has_assign_ref : 1; unsigned gets_new : 2; unsigned gets_delete : 2; unsigned has_call_overloaded : 1; unsigned has_array_ref_overloaded : 1; unsigned has_arrow_overloaded : 1; unsigned interface_only : 1; unsigned interface_unknown : 1; unsigned needs_virtual_reinit : 1; unsigned marks: 6; unsigned vec_delete_takes_size : 1; unsigned declared_class : 1; unsigned being_defined : 1; unsigned redefined : 1; unsigned debug_requested : 1; unsigned use_template : 2; unsigned got_semicolon : 1; unsigned ptrmemfunc_flag : 1; unsigned is_signature : 1; unsigned is_signature_pointer : 1; unsigned is_signature_reference : 1; unsigned has_opaque_typedecls : 1; unsigned sigtable_has_been_generated : 1; unsigned was_anonymous : 1; unsigned has_real_assign_ref : 1; unsigned has_const_init_ref : 1; unsigned has_complex_init_ref : 1; unsigned has_complex_assign_ref : 1; unsigned has_abstract_assign_ref : 1; unsigned non_aggregate : 1; unsigned is_partial_instantiation : 1; unsigned has_mutable : 1; unsigned com_interface : 1; /* When adding a flag here, consider whether or not it ought to apply to a template instance if it applies to the template. If so, make sure to copy it in instantiate_class_template! */ /* The MIPS compiler gets it wrong if this struct also does not fill out to a multiple of 4 bytes. Add a member `dummy' with new bits if you go over the edge. */ unsigned dummy : 10; } type_flags; int vsize; int vfield_parent; union tree_node *vfields; union tree_node *vbases; union tree_node *tags; union tree_node *search_slot; unsigned char align; /* Room for another three unsigned chars. */ union tree_node *size; union tree_node *abstract_virtuals; union tree_node *friend_classes; union tree_node *rtti; union tree_node *methods; union tree_node *signature; union tree_node *signature_pointer_to; union tree_node *signature_reference_to; union tree_node *template_info; tree befriending_classes; }; /* Indicates whether or not (and how) a template was expanded for this class. 0=no information yet/non-template class 1=implicit template instantiation 2=explicit template specialization 3=explicit template instantiation */ #define CLASSTYPE_USE_TEMPLATE(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.use_template) /* Fields used for storing information before the class is defined. After the class is defined, these fields hold other information. */ /* List of friends which were defined inline in this class definition. */ #define CLASSTYPE_INLINE_FRIENDS(NODE) (TYPE_NONCOPIED_PARTS (NODE)) /* Nonzero for _CLASSTYPE means that operator new and delete are defined, respectively. */ #define TYPE_GETS_NEW(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.gets_new) #define TYPE_GETS_DELETE(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.gets_delete) #define TYPE_GETS_REG_DELETE(NODE) (TYPE_GETS_DELETE (NODE) & 1) /* Nonzero for _CLASSTYPE means that operator vec delete is defined and takes the optional size_t argument. */ #define TYPE_VEC_DELETE_TAKES_SIZE(NODE) \ (TYPE_LANG_SPECIFIC(NODE)->type_flags.vec_delete_takes_size) #define TYPE_VEC_NEW_USES_COOKIE(NODE) \ (TYPE_NEEDS_DESTRUCTOR (NODE) \ || (TYPE_LANG_SPECIFIC (NODE) && TYPE_VEC_DELETE_TAKES_SIZE (NODE))) /* Nonzero means that this _CLASSTYPE node defines ways of converting itself to other types. */ #define TYPE_HAS_CONVERSION(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_type_conversion) /* Nonzero means that this _CLASSTYPE node overloads operator=(X&). */ #define TYPE_HAS_ASSIGN_REF(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_assign_ref) #define TYPE_HAS_CONST_ASSIGN_REF(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_const_assign_ref) /* Nonzero means that this _CLASSTYPE node has an X(X&) constructor. */ #define TYPE_HAS_INIT_REF(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_init_ref) #define TYPE_HAS_CONST_INIT_REF(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_const_init_ref) /* Nonzero means that this type is being defined. I.e., the left brace starting the definition of this type has been seen. */ #define TYPE_BEING_DEFINED(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.being_defined) /* Nonzero means that this type has been redefined. In this case, if convenient, don't reprocess any methods that appear in its redefinition. */ #define TYPE_REDEFINED(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.redefined) /* Nonzero means that this type is a signature. */ # define IS_SIGNATURE(NODE) (TYPE_LANG_SPECIFIC(NODE)?TYPE_LANG_SPECIFIC(NODE)->type_flags.is_signature:0) # define SET_SIGNATURE(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.is_signature=1) # define CLEAR_SIGNATURE(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.is_signature=0) /* Nonzero means that this type is a signature pointer type. */ # define IS_SIGNATURE_POINTER(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.is_signature_pointer) /* Nonzero means that this type is a signature reference type. */ # define IS_SIGNATURE_REFERENCE(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.is_signature_reference) /* Nonzero means that this signature contains opaque type declarations. */ #define SIGNATURE_HAS_OPAQUE_TYPEDECLS(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_opaque_typedecls) /* Nonzero means that a signature table has been generated for this signature. */ #define SIGTABLE_HAS_BEEN_GENERATED(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.sigtable_has_been_generated) /* If NODE is a class, this is the signature type that contains NODE's signature after it has been computed using sigof(). */ #define CLASSTYPE_SIGNATURE(NODE) (TYPE_LANG_SPECIFIC(NODE)->signature) /* If NODE is a signature pointer or signature reference, this is the signature type the pointer/reference points to. */ #define SIGNATURE_TYPE(NODE) (TYPE_LANG_SPECIFIC(NODE)->signature) /* If NODE is a signature, this is a vector of all methods defined in the signature or in its base types together with their default implementations. */ #define SIGNATURE_METHOD_VEC(NODE) (TYPE_LANG_SPECIFIC(NODE)->signature) /* If NODE is a signature, this is the _TYPE node that contains NODE's signature pointer type. */ #define SIGNATURE_POINTER_TO(NODE) (TYPE_LANG_SPECIFIC(NODE)->signature_pointer_to) /* If NODE is a signature, this is the _TYPE node that contains NODE's signature reference type. */ #define SIGNATURE_REFERENCE_TO(NODE) (TYPE_LANG_SPECIFIC(NODE)->signature_reference_to) /* The is the basetype that contains NODE's rtti. */ #define CLASSTYPE_RTTI(NODE) (TYPE_LANG_SPECIFIC(NODE)->rtti) /* Nonzero means that this _CLASSTYPE node overloads operator(). */ #define TYPE_OVERLOADS_CALL_EXPR(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_call_overloaded) /* Nonzero means that this _CLASSTYPE node overloads operator[]. */ #define TYPE_OVERLOADS_ARRAY_REF(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_array_ref_overloaded) /* Nonzero means that this _CLASSTYPE node overloads operator->. */ #define TYPE_OVERLOADS_ARROW(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_arrow_overloaded) /* Nonzero means that this _CLASSTYPE (or one of its ancestors) uses multiple inheritance. If this is 0 for the root of a type hierarchy, then we can use more efficient search techniques. */ #define TYPE_USES_MULTIPLE_INHERITANCE(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.uses_multiple_inheritance) /* Nonzero means that this _CLASSTYPE (or one of its ancestors) uses virtual base classes. If this is 0 for the root of a type hierarchy, then we can use more efficient search techniques. */ #define TYPE_USES_VIRTUAL_BASECLASSES(NODE) (TREE_LANG_FLAG_3(NODE)) +/* Nonzero means that this _CLASSTYPE uses polymorphic virtual bases. + This flag is set only when we use vtable thunks. */ +#define TYPE_USES_PVBASES(NODE) (TREE_LANG_FLAG_5(NODE)) + /* Vector member functions defined in this class. Each element is either a FUNCTION_DECL, a TEMPLATE_DECL, or an OVERLOAD. All functions with the same name end up in the same slot. The first two elements are for constructors, and destructors, respectively. These are followed by ordinary member functions. There may be empty entries at the end of the vector. */ #define CLASSTYPE_METHOD_VEC(NODE) (TYPE_LANG_SPECIFIC(NODE)->methods) /* The first type conversion operator in the class (the others can be searched with TREE_CHAIN), or the first non-constructor function if there are no type conversion operators. */ #define CLASSTYPE_FIRST_CONVERSION(NODE) \ TREE_VEC_LENGTH (CLASSTYPE_METHOD_VEC (NODE)) > 2 \ ? TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (NODE), 2) \ : NULL_TREE; /* Mark bits for depth-first and breath-first searches. */ /* Get the value of the Nth mark bit. */ #define CLASSTYPE_MARKED_N(NODE, N) \ (((CLASS_TYPE_P (NODE) ? TYPE_LANG_SPECIFIC (NODE)->type_flags.marks \ : TYPE_ALIAS_SET (NODE)) & (1 << N)) != 0) /* Set the Nth mark bit. */ #define SET_CLASSTYPE_MARKED_N(NODE, N) \ (CLASS_TYPE_P (NODE) \ ? (TYPE_LANG_SPECIFIC (NODE)->type_flags.marks |= (1 << (N))) \ : (TYPE_ALIAS_SET (NODE) |= (1 << (N)))) /* Clear the Nth mark bit. */ #define CLEAR_CLASSTYPE_MARKED_N(NODE, N) \ (CLASS_TYPE_P (NODE) \ ? (TYPE_LANG_SPECIFIC (NODE)->type_flags.marks &= ~(1 << (N))) \ : (TYPE_ALIAS_SET (NODE) &= ~(1 << (N)))) /* Get the value of the mark bits. */ #define CLASSTYPE_MARKED(NODE) CLASSTYPE_MARKED_N(NODE, 0) #define CLASSTYPE_MARKED2(NODE) CLASSTYPE_MARKED_N(NODE, 1) #define CLASSTYPE_MARKED3(NODE) CLASSTYPE_MARKED_N(NODE, 2) #define CLASSTYPE_MARKED4(NODE) CLASSTYPE_MARKED_N(NODE, 3) #define CLASSTYPE_MARKED5(NODE) CLASSTYPE_MARKED_N(NODE, 4) #define CLASSTYPE_MARKED6(NODE) CLASSTYPE_MARKED_N(NODE, 5) /* Macros to modify the above flags */ #define SET_CLASSTYPE_MARKED(NODE) SET_CLASSTYPE_MARKED_N(NODE, 0) #define CLEAR_CLASSTYPE_MARKED(NODE) CLEAR_CLASSTYPE_MARKED_N(NODE, 0) #define SET_CLASSTYPE_MARKED2(NODE) SET_CLASSTYPE_MARKED_N(NODE, 1) #define CLEAR_CLASSTYPE_MARKED2(NODE) CLEAR_CLASSTYPE_MARKED_N(NODE, 1) #define SET_CLASSTYPE_MARKED3(NODE) SET_CLASSTYPE_MARKED_N(NODE, 2) #define CLEAR_CLASSTYPE_MARKED3(NODE) CLEAR_CLASSTYPE_MARKED_N(NODE, 2) #define SET_CLASSTYPE_MARKED4(NODE) SET_CLASSTYPE_MARKED_N(NODE, 3) #define CLEAR_CLASSTYPE_MARKED4(NODE) CLEAR_CLASSTYPE_MARKED_N(NODE, 3) #define SET_CLASSTYPE_MARKED5(NODE) SET_CLASSTYPE_MARKED_N(NODE, 4) #define CLEAR_CLASSTYPE_MARKED5(NODE) CLEAR_CLASSTYPE_MARKED_N(NODE, 4) #define SET_CLASSTYPE_MARKED6(NODE) SET_CLASSTYPE_MARKED_N(NODE, 5) #define CLEAR_CLASSTYPE_MARKED6(NODE) CLEAR_CLASSTYPE_MARKED_N(NODE, 5) /* A list of the nested tag-types (class, struct, union, or enum) found within this class. The TREE_PURPOSE of each node is the name of the type; the TREE_VALUE is the type itself. This list includes nested member class templates. */ #define CLASSTYPE_TAGS(NODE) (TYPE_LANG_SPECIFIC(NODE)->tags) /* If this class has any bases, this is the number of the base class from which our VFIELD is based, -1 otherwise. If this class has no base classes, this is not used. In D : B1, B2, PARENT would be 0, if D's vtable came from B1, 1, if D's vtable came from B2. */ #define CLASSTYPE_VFIELD_PARENT(NODE) (TYPE_LANG_SPECIFIC(NODE)->vfield_parent) /* Remove when done merging. */ #define CLASSTYPE_VFIELD(NODE) TYPE_VFIELD(NODE) /* The number of virtual functions defined for this _CLASSTYPE node. */ #define CLASSTYPE_VSIZE(NODE) (TYPE_LANG_SPECIFIC(NODE)->vsize) -/* The virtual base classes that this type uses. */ +/* The list of binfos of virtual base classes that this type uses. */ #define CLASSTYPE_VBASECLASSES(NODE) (TYPE_LANG_SPECIFIC(NODE)->vbases) /* The virtual function pointer fields that this type contains. */ #define CLASSTYPE_VFIELDS(NODE) (TYPE_LANG_SPECIFIC(NODE)->vfields) /* Number of baseclasses defined for this type. 0 means no base classes. */ #define CLASSTYPE_N_BASECLASSES(NODE) \ (TYPE_BINFO_BASETYPES (NODE) ? TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES(NODE)) : 0) /* Used for keeping search-specific information. Any search routine which uses this must define what exactly this slot is used for. */ #define CLASSTYPE_SEARCH_SLOT(NODE) (TYPE_LANG_SPECIFIC(NODE)->search_slot) /* These are the size, mode and alignment of the type without its virtual base classes, for when we use this type as a base itself. */ #define CLASSTYPE_SIZE(NODE) (TYPE_LANG_SPECIFIC(NODE)->size) #define CLASSTYPE_ALIGN(NODE) (TYPE_LANG_SPECIFIC(NODE)->align) /* A cons list of virtual functions which cannot be inherited by derived classes. When deriving from this type, the derived class must provide its own definition for each of these functions. */ #define CLASSTYPE_ABSTRACT_VIRTUALS(NODE) (TYPE_LANG_SPECIFIC(NODE)->abstract_virtuals) /* Nonzero means that this aggr type has been `closed' by a semicolon. */ #define CLASSTYPE_GOT_SEMICOLON(NODE) (TYPE_LANG_SPECIFIC (NODE)->type_flags.got_semicolon) /* Nonzero means that the main virtual function table pointer needs to be set because base constructors have placed the wrong value there. If this is zero, it means that they placed the right value there, and there is no need to change it. */ #define CLASSTYPE_NEEDS_VIRTUAL_REINIT(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.needs_virtual_reinit) /* Nonzero means that if this type has virtual functions, that the virtual function table will be written out. */ #define CLASSTYPE_VTABLE_NEEDS_WRITING(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.vtable_needs_writing) /* Nonzero means that this type has an X() constructor. */ #define TYPE_HAS_DEFAULT_CONSTRUCTOR(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_default_ctor) /* Nonzero means the type declared a ctor as private or protected. We use this to make sure we don't try to generate a copy ctor for a class that has a member of type NODE. */ #define TYPE_HAS_NONPUBLIC_CTOR(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_nonpublic_ctor) /* Ditto, for operator=. */ #define TYPE_HAS_NONPUBLIC_ASSIGN_REF(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_nonpublic_assign_ref) /* Nonzero means that this type contains a mutable member */ #define CLASSTYPE_HAS_MUTABLE(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_mutable) #define TYPE_HAS_MUTABLE_P(NODE) (cp_has_mutable_p (NODE)) /* Nonzero means that this type is meant for communication via COM. */ #define CLASSTYPE_COM_INTERFACE(NODE) \ (TYPE_LANG_SPECIFIC(NODE)->type_flags.com_interface) /* A list of class types of which this type is a friend. The TREE_VALUE is normally a TYPE, but will be a TEMPLATE_DECL in the case of a template friend. */ #define CLASSTYPE_FRIEND_CLASSES(NODE) (TYPE_LANG_SPECIFIC(NODE)->friend_classes) /* A list of the classes which grant friendship to this class. */ #define CLASSTYPE_BEFRIENDING_CLASSES(NODE) \ (TYPE_LANG_SPECIFIC (NODE)->befriending_classes) /* Say whether this node was declared as a "class" or a "struct". */ #define CLASSTYPE_DECLARED_CLASS(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.declared_class) /* Nonzero if this class has const members which have no specified initialization. */ #define CLASSTYPE_READONLY_FIELDS_NEED_INIT(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.const_needs_init) /* Nonzero if this class has ref members which have no specified initialization. */ #define CLASSTYPE_REF_FIELDS_NEED_INIT(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.ref_needs_init) /* Nonzero if this class is included from a header file which employs `#pragma interface', and it is not included in its implementation file. */ #define CLASSTYPE_INTERFACE_ONLY(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.interface_only) /* Same as above, but for classes whose purpose we do not know. */ #define CLASSTYPE_INTERFACE_UNKNOWN(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.interface_unknown) #define CLASSTYPE_INTERFACE_KNOWN(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.interface_unknown == 0) #define SET_CLASSTYPE_INTERFACE_UNKNOWN_X(NODE,X) (TYPE_LANG_SPECIFIC(NODE)->type_flags.interface_unknown = !!(X)) #define SET_CLASSTYPE_INTERFACE_UNKNOWN(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.interface_unknown = 1) #define SET_CLASSTYPE_INTERFACE_KNOWN(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.interface_unknown = 0) /* Nonzero if a _DECL node requires us to output debug info for this class. */ #define CLASSTYPE_DEBUG_REQUESTED(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.debug_requested) /* Additional macros for inheritance information. */ /* The BINFO_INHERITANCE_CHAIN is used opposite to the description in gcc/tree.h. In particular if D is derived from B then the BINFO for B (in D) will have a BINFO_INHERITANCE_CHAIN pointing to D. In tree.h, this pointer is described as pointing in other direction. There is a different BINFO for each path to a virtual base; BINFOs for virtual bases are not shared. In addition, shared versions of each of the virtual class BINFOs are stored in CLASSTYPE_VBASECLASSES. We use TREE_VIA_PROTECTED and TREE_VIA_PUBLIC, but private inheritance is indicated by the absence of the other two flags, not by TREE_VIAR_PRIVATE, which is unused. The TREE_CHAIN is for scratch space in search.c. */ /* Nonzero means marked by DFS or BFS search, including searches by `get_binfo' and `get_base_distance'. */ #define BINFO_MARKED(NODE) (TREE_VIA_VIRTUAL(NODE)?CLASSTYPE_MARKED(BINFO_TYPE(NODE)):TREE_LANG_FLAG_0(NODE)) /* Macros needed because of C compilers that don't allow conditional expressions to be lvalues. Grr! */ #define SET_BINFO_MARKED(NODE) (TREE_VIA_VIRTUAL(NODE)?SET_CLASSTYPE_MARKED(BINFO_TYPE(NODE)):(TREE_LANG_FLAG_0(NODE)=1)) #define CLEAR_BINFO_MARKED(NODE) (TREE_VIA_VIRTUAL(NODE)?CLEAR_CLASSTYPE_MARKED(BINFO_TYPE(NODE)):(TREE_LANG_FLAG_0(NODE)=0)) /* Nonzero means marked in search through virtual inheritance hierarchy. */ #define BINFO_VBASE_MARKED(NODE) CLASSTYPE_MARKED2 (BINFO_TYPE (NODE)) /* Modifier macros */ #define SET_BINFO_VBASE_MARKED(NODE) SET_CLASSTYPE_MARKED2 (BINFO_TYPE (NODE)) #define CLEAR_BINFO_VBASE_MARKED(NODE) CLEAR_CLASSTYPE_MARKED2 (BINFO_TYPE (NODE)) /* Nonzero means marked in search for members or member functions. */ #define BINFO_FIELDS_MARKED(NODE) \ (TREE_VIA_VIRTUAL(NODE)?CLASSTYPE_MARKED2 (BINFO_TYPE (NODE)):TREE_LANG_FLAG_2(NODE)) #define SET_BINFO_FIELDS_MARKED(NODE) (TREE_VIA_VIRTUAL(NODE)?SET_CLASSTYPE_MARKED2(BINFO_TYPE(NODE)):(TREE_LANG_FLAG_2(NODE)=1)) #define CLEAR_BINFO_FIELDS_MARKED(NODE) (TREE_VIA_VIRTUAL(NODE)?CLEAR_CLASSTYPE_MARKED2(BINFO_TYPE(NODE)):(TREE_LANG_FLAG_2(NODE)=0)) /* Nonzero means that this class is on a path leading to a new vtable. */ #define BINFO_VTABLE_PATH_MARKED(NODE) \ (TREE_VIA_VIRTUAL(NODE)?CLASSTYPE_MARKED3(BINFO_TYPE(NODE)):TREE_LANG_FLAG_3(NODE)) #define SET_BINFO_VTABLE_PATH_MARKED(NODE) (TREE_VIA_VIRTUAL(NODE)?SET_CLASSTYPE_MARKED3(BINFO_TYPE(NODE)):(TREE_LANG_FLAG_3(NODE)=1)) #define CLEAR_BINFO_VTABLE_PATH_MARKED(NODE) (TREE_VIA_VIRTUAL(NODE)?CLEAR_CLASSTYPE_MARKED3(BINFO_TYPE(NODE)):(TREE_LANG_FLAG_3(NODE)=0)) /* Nonzero means that this class has a new vtable. */ #define BINFO_NEW_VTABLE_MARKED(NODE) \ (TREE_VIA_VIRTUAL(NODE)?CLASSTYPE_MARKED4(BINFO_TYPE(NODE)):TREE_LANG_FLAG_4(NODE)) #define SET_BINFO_NEW_VTABLE_MARKED(NODE) (TREE_VIA_VIRTUAL(NODE)?SET_CLASSTYPE_MARKED4(BINFO_TYPE(NODE)):(TREE_LANG_FLAG_4(NODE)=1)) #define CLEAR_BINFO_NEW_VTABLE_MARKED(NODE) (TREE_VIA_VIRTUAL(NODE)?CLEAR_CLASSTYPE_MARKED4(BINFO_TYPE(NODE)):(TREE_LANG_FLAG_4(NODE)=0)) /* Nonzero means this class has done dfs_pushdecls. */ #define BINFO_PUSHDECLS_MARKED(NODE) BINFO_VTABLE_PATH_MARKED (NODE) #define SET_BINFO_PUSHDECLS_MARKED(NODE) SET_BINFO_VTABLE_PATH_MARKED (NODE) #define CLEAR_BINFO_PUSHDECLS_MARKED(NODE) CLEAR_BINFO_VTABLE_PATH_MARKED (NODE) /* Used by various search routines. */ #define IDENTIFIER_MARKED(NODE) TREE_LANG_FLAG_0 (NODE) /* Accessor macros for the vfield slots in structures. */ /* Get the assoc info that caused this vfield to exist. */ #define VF_BINFO_VALUE(NODE) TREE_PURPOSE (NODE) /* Get that same information as a _TYPE. */ #define VF_BASETYPE_VALUE(NODE) TREE_VALUE (NODE) /* Get the value of the top-most type dominating the non-`normal' vfields. */ #define VF_DERIVED_VALUE(NODE) (VF_BINFO_VALUE (NODE) ? BINFO_TYPE (VF_BINFO_VALUE (NODE)) : NULL_TREE) /* Get the value of the top-most type that's `normal' for the vfield. */ #define VF_NORMAL_VALUE(NODE) TREE_TYPE (NODE) /* Nonzero for TREE_LIST node means that this list of things is a list of parameters, as opposed to a list of expressions. */ #define TREE_PARMLIST(NODE) ((NODE)->common.unsigned_flag) /* overloaded! */ /* For FUNCTION_TYPE or METHOD_TYPE, a list of the exceptions that this type can raise. Each TREE_VALUE is a _TYPE. The TREE_VALUE will be NULL_TREE to indicate a throw specification of `(...)', or, equivalently, no throw specification. */ #define TYPE_RAISES_EXCEPTIONS(NODE) TYPE_NONCOPIED_PARTS (NODE) /* For FUNCTION_TYPE or METHOD_TYPE, return 1 iff it is declared `throw()'. */ #define TYPE_NOTHROW_P(NODE) \ (TYPE_RAISES_EXCEPTIONS (NODE) \ && TREE_VALUE (TYPE_RAISES_EXCEPTIONS (NODE)) == NULL_TREE) /* The binding level associated with the namespace. */ #define NAMESPACE_LEVEL(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.level) /* If a DECL has DECL_LANG_SPECIFIC, it is either a lang_decl_flags or a lang_decl (which has lang_decl_flags as its initial prefix). A FUNCTION_DECL, NAMESPACE_DECL, TYPE_DECL, or USING_DECL may have a full lang_decl. A FIELD_DECL, or a static data member VAR_DECL, will have only lang_decl_flags. Thus, one should only access the members of lang_decl that are not in lang_decl_flags for DECLs that are not FIELD_DECLs or VAR_DECLs. */ struct lang_decl_flags { #ifdef ONLY_INT_FIELDS int language : 8; #else enum languages language : 8; #endif unsigned operator_attr : 1; unsigned constructor_attr : 1; unsigned friend_attr : 1; unsigned static_function : 1; unsigned const_memfunc : 1; unsigned volatile_memfunc : 1; - unsigned abstract_virtual : 1; unsigned permanent_attr : 1 ; - unsigned constructor_for_vbase_attr : 1; + unsigned mutable_flag : 1; unsigned is_default_implementation : 1; unsigned saved_inline : 1; unsigned use_template : 2; - unsigned nonconverting : 1; unsigned declared_inline : 1; unsigned not_really_extern : 1; unsigned needs_final_overrider : 1; unsigned bitfield : 1; unsigned defined_in_class : 1; - unsigned dummy : 4; + unsigned constructor_for_vbase_attr : 2; + unsigned dummy : 3; tree access; tree context; tree memfunc_pointer_to; tree template_info; struct binding_level *level; }; struct lang_decl { struct lang_decl_flags decl_flags; tree main_decl_variant; tree befriending_classes; struct pending_inline *pending_inline_info; }; /* Non-zero if NODE is a _DECL with TREE_READONLY set. */ #define TREE_READONLY_DECL_P(NODE) \ (TREE_READONLY (NODE) && TREE_CODE_CLASS (TREE_CODE (NODE)) == 'd') /* Non-zero iff DECL is memory-based. The DECL_RTL of certain const variables might be a CONST_INT, or a REG in some cases. We cannot use `memory_operand' as a test here because on most RISC machines, a variable's address is not, by itself, a legitimate address. */ #define DECL_IN_MEMORY_P(NODE) \ (DECL_RTL (NODE) != NULL_RTX && GET_CODE (DECL_RTL (NODE)) == MEM) /* For FUNCTION_DECLs: return the language in which this decl was declared. */ #define DECL_LANGUAGE(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.language) /* For FUNCTION_DECLs: nonzero means that this function is a constructor. */ #define DECL_CONSTRUCTOR_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.constructor_attr) /* There ought to be a better way to find out whether or not something is a destructor. */ #define DECL_DESTRUCTOR_P(NODE) \ (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (NODE)) \ && DECL_LANGUAGE (NODE) == lang_cplusplus) #define DECL_CONV_FN_P(NODE) \ (IDENTIFIER_TYPENAME_P (DECL_NAME (NODE)) && TREE_TYPE (DECL_NAME (NODE))) -/* For FUNCTION_DECLs: nonzero means that this function is a constructor +#define CONSTRUCTOR_FOR_VBASE 1 +#define CONSTRUCTOR_FOR_PVBASE 2 +#define DESTRUCTOR_FOR_PVBASE 3 + +/* For FUNCTION_DECLs: nonzero means that this function is a con/destructor for an object with virtual baseclasses. */ -#define DECL_CONSTRUCTOR_FOR_VBASE_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.constructor_for_vbase_attr) +#define DECL_CONSTRUCTOR_FOR_VBASE(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.constructor_for_vbase_attr) +/* Nonzero means that this function is a constructor for an object + with virtual baseclasses. */ +#define DECL_CONSTRUCTOR_FOR_VBASE_P(NODE) \ + (DECL_CONSTRUCTOR_FOR_VBASE (NODE) == CONSTRUCTOR_FOR_VBASE) + +/* Nonzero means that this function is a constructor for an object + with virtual baseclasses which have virtual functions. */ +#define DECL_CONSTRUCTOR_FOR_PVBASE_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.constructor_for_vbase_attr == CONSTRUCTOR_FOR_PVBASE) + +/* Nonzero means that this function is a destructor for an object + with virtual baseclasses which have virtual functions. */ +#define DECL_DESTRUCTOR_FOR_PVBASE_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.constructor_for_vbase_attr == DESTRUCTOR_FOR_PVBASE) + +/* Nonzero means that this function is a wrapper around a PVBASE ctor. */ +#define DECL_VLIST_CTOR_WRAPPER_P(NODE) \ + (DECL_CONSTRUCTOR_FOR_VBASE_P (NODE) && DECL_VLIST_CTOR_WRAPPED (NODE)\ + && TREE_CODE (DECL_VLIST_CTOR_WRAPPED (NODE)) == FUNCTION_DECL \ + && DECL_CONSTRUCTOR_FOR_PVBASE_P (DECL_VLIST_CTOR_WRAPPED (NODE))) + +/* Refers to original function that NODE wraps. */ +#define DECL_VLIST_CTOR_WRAPPED(NODE) DECL_MEMFUNC_POINTER_TO (NODE) + /* Non-zero for a FUNCTION_DECL that declares a type-info function. */ #define DECL_TINFO_FN_P(NODE) \ (TREE_CODE (NODE) == FUNCTION_DECL \ && DECL_ARTIFICIAL (NODE) \ && DECL_LANG_SPECIFIC(NODE)->decl_flags.mutable_flag) /* Mark NODE as a type-info function. */ #define SET_DECL_TINFO_FN_P(NODE) \ (DECL_LANG_SPECIFIC((NODE))->decl_flags.mutable_flag = 1) /* For FUNCTION_DECLs: nonzero means that this function is a default implementation of a signature method. */ #define IS_DEFAULT_IMPLEMENTATION(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.is_default_implementation) /* Nonzero for _DECL means that this decl appears in (or will appear in) as a member in a RECORD_TYPE or UNION_TYPE node. It is also for detecting circularity in case members are multiply defined. In the case of a VAR_DECL, it is also used to determine how program storage should be allocated. */ #define DECL_IN_AGGR_P(NODE) (DECL_LANG_FLAG_3(NODE)) /* Nonzero if the DECL was defined in the class definition itself, rather than outside the class. */ #define DECL_DEFINED_IN_CLASS_P(DECL) \ (DECL_LANG_SPECIFIC (DECL)->decl_flags.defined_in_class) /* Nonzero for FUNCTION_DECL means that this decl is just a friend declaration, and should not be added to the list of member functions for this class. */ #define DECL_FRIEND_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.friend_attr) /* A TREE_LIST of the types which have befriended this FUNCTION_DECL. */ #define DECL_BEFRIENDING_CLASSES(NODE) \ (DECL_LANG_SPECIFIC(NODE)->befriending_classes) /* Nonzero for FUNCTION_DECL means that this decl is a static member function. */ #define DECL_STATIC_FUNCTION_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.static_function) /* Nonzero for a class member means that it is shared between all objects of that class. */ #define SHARED_MEMBER_P(NODE) \ (TREE_CODE (NODE) == VAR_DECL || TREE_CODE (NODE) == TYPE_DECL \ || TREE_CODE (NODE) == CONST_DECL) /* Nonzero for FUNCTION_DECL means that this decl is a non-static member function. */ #define DECL_NONSTATIC_MEMBER_FUNCTION_P(NODE) \ (TREE_CODE (TREE_TYPE (NODE)) == METHOD_TYPE) /* Nonzero for FUNCTION_DECL means that this decl is a member function (static or non-static). */ #define DECL_FUNCTION_MEMBER_P(NODE) \ (DECL_NONSTATIC_MEMBER_FUNCTION_P (NODE) || DECL_STATIC_FUNCTION_P (NODE)) /* Nonzero for FUNCTION_DECL means that this member function has `this' as const X *const. */ #define DECL_CONST_MEMFUNC_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.const_memfunc) /* Nonzero for FUNCTION_DECL means that this member function has `this' as volatile X *const. */ #define DECL_VOLATILE_MEMFUNC_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.volatile_memfunc) /* Nonzero for a DECL means that this member is a non-static member. */ #define DECL_NONSTATIC_MEMBER_P(NODE) \ ((TREE_CODE (NODE) == FUNCTION_DECL \ && DECL_NONSTATIC_MEMBER_FUNCTION_P (NODE)) \ || TREE_CODE (NODE) == FIELD_DECL) /* Nonzero for _DECL means that this member object type is mutable. */ #define DECL_MUTABLE_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.mutable_flag) /* Nonzero for _DECL means that this constructor is a non-converting constructor. */ #define DECL_NONCONVERTING_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.nonconverting) /* Nonzero for FUNCTION_DECL means that this member function exists as part of an abstract class's interface. */ #define DECL_ABSTRACT_VIRTUAL_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.abstract_virtual) /* Nonzero for FUNCTION_DECL means that this member function must be overridden by derived classes. */ #define DECL_NEEDS_FINAL_OVERRIDER_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.needs_final_overrider) /* Nonzero if allocated on permanent_obstack. */ #define LANG_DECL_PERMANENT(LANGDECL) ((LANGDECL)->decl_flags.permanent_attr) /* The _TYPE context in which this _DECL appears. This field holds the class where a virtual function instance is actually defined, and the lexical scope of a friend function defined in a class body. */ #define DECL_CLASS_CONTEXT(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.context) #define DECL_REAL_CONTEXT(NODE) \ ((TREE_CODE (NODE) == FUNCTION_DECL && DECL_FUNCTION_MEMBER_P (NODE)) \ ? DECL_CLASS_CONTEXT (NODE) : CP_DECL_CONTEXT (NODE)) /* NULL_TREE in DECL_CONTEXT represents the global namespace. */ #define CP_DECL_CONTEXT(NODE) \ (DECL_CONTEXT (NODE) ? DECL_CONTEXT (NODE) : global_namespace) #define FROB_CONTEXT(NODE) ((NODE) == global_namespace ? NULL_TREE : (NODE)) /* For a virtual function, the base where we find its vtable entry. For a non-virtual function, the base where it is defined. */ #define DECL_VIRTUAL_CONTEXT(NODE) DECL_CONTEXT (NODE) /* 1 iff NODE has namespace scope, including the global namespace. */ #define DECL_NAMESPACE_SCOPE_P(NODE) \ (DECL_CONTEXT (NODE) == NULL_TREE \ || TREE_CODE (DECL_CONTEXT (NODE)) == NAMESPACE_DECL) /* 1 iff NODE is a class member. */ #define DECL_CLASS_SCOPE_P(NODE) \ (DECL_CONTEXT (NODE) \ && TREE_CODE_CLASS (TREE_CODE (DECL_CONTEXT (NODE))) == 't') /* 1 iff NODE is function-local. */ #define DECL_FUNCTION_SCOPE_P(NODE) \ (DECL_CONTEXT (NODE) \ && TREE_CODE (DECL_CONTEXT (NODE)) == FUNCTION_DECL) /* For a NAMESPACE_DECL: the list of using namespace directives The PURPOSE is the used namespace, the value is the namespace that is the common ancestor. */ #define DECL_NAMESPACE_USING(NODE) DECL_VINDEX(NODE) /* In a NAMESPACE_DECL, the DECL_INITIAL is used to record all users of a namespace, to record the transitive closure of using namespace. */ #define DECL_NAMESPACE_USERS(NODE) DECL_INITIAL (NODE) /* In a NAMESPACE_DECL, points to the original namespace if this is a namespace alias. */ #define DECL_NAMESPACE_ALIAS(NODE) DECL_ABSTRACT_ORIGIN (NODE) #define ORIGINAL_NAMESPACE(NODE) \ (DECL_NAMESPACE_ALIAS (NODE) ? DECL_NAMESPACE_ALIAS (NODE) : (NODE)) /* In a non-local VAR_DECL with static storage duration, this is the initialization priority. If this value is zero, the NODE will be initialized at the DEFAULT_INIT_PRIORITY. */ #define DECL_INIT_PRIORITY(NODE) (DECL_FIELD_SIZE ((NODE))) /* In a TREE_LIST concatenating using directives, indicate indirekt directives */ #define TREE_INDIRECT_USING(NODE) ((NODE)->common.lang_flag_0) /* In a VAR_DECL for a variable declared in a for statement, this is the shadowed (local) variable. */ #define DECL_SHADOWED_FOR_VAR(NODE) DECL_RESULT(NODE) /* Points back to the decl which caused this lang_decl to be allocated. */ #define DECL_MAIN_VARIANT(NODE) (DECL_LANG_SPECIFIC(NODE)->main_decl_variant) /* For a FUNCTION_DECL: if this function was declared inline inside of a class declaration, this is where the text for the function is squirreled away. */ #define DECL_PENDING_INLINE_INFO(NODE) (DECL_LANG_SPECIFIC(NODE)->pending_inline_info) /* True if on the saved_inlines (see decl2.c) list. */ #define DECL_SAVED_INLINE(DECL) \ (DECL_LANG_SPECIFIC(DECL)->decl_flags.saved_inline) /* For a FUNCTION_DECL: if this function was declared inside a signature declaration, this is the corresponding member function pointer that was created for it. */ #define DECL_MEMFUNC_POINTER_TO(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.memfunc_pointer_to) /* For a FIELD_DECL: this points to the signature member function from which this signature member function pointer was created. */ #define DECL_MEMFUNC_POINTING_TO(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.memfunc_pointer_to) /* For a VAR_DECL or FUNCTION_DECL: template-specific information. */ #define DECL_TEMPLATE_INFO(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.template_info) /* Template information for a RECORD_TYPE or UNION_TYPE. */ #define CLASSTYPE_TEMPLATE_INFO(NODE) (TYPE_LANG_SPECIFIC(NODE)->template_info) /* Template information for an ENUMERAL_TYPE. Although an enumeration may not be a primary template, it may be declared within the scope of a primary template and the enumeration constants may depend on non-type template parameters. */ #define ENUM_TEMPLATE_INFO(NODE) (TYPE_BINFO (NODE)) /* Template information for a template template parameter. */ #define TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO(NODE) (TYPE_BINFO (NODE)) /* Template information for an ENUMERAL_, RECORD_, or UNION_TYPE. */ #define TYPE_TEMPLATE_INFO(NODE) \ (TREE_CODE (NODE) == ENUMERAL_TYPE \ ? ENUM_TEMPLATE_INFO (NODE) : \ (TREE_CODE (NODE) == TEMPLATE_TEMPLATE_PARM \ ? TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (NODE) \ : CLASSTYPE_TEMPLATE_INFO (NODE))) /* Set the template information for an ENUMERAL_, RECORD_, or UNION_TYPE to VAL. */ #define SET_TYPE_TEMPLATE_INFO(NODE, VAL) \ (TREE_CODE (NODE) == ENUMERAL_TYPE \ ? (ENUM_TEMPLATE_INFO (NODE) = VAL) \ : (CLASSTYPE_TEMPLATE_INFO (NODE) = VAL)) #define TI_TEMPLATE(NODE) (TREE_PURPOSE (NODE)) #define TI_ARGS(NODE) (TREE_VALUE (NODE)) #define TI_SPEC_INFO(NODE) (TREE_CHAIN (NODE)) #define TI_PENDING_TEMPLATE_FLAG(NODE) TREE_LANG_FLAG_1 (NODE) /* The TEMPLATE_DECL instantiated or specialized by NODE. This TEMPLATE_DECL will be the immediate parent, not the most general template. For example, in: template struct S { template void f(U); } the FUNCTION_DECL for S::f will have, as its DECL_TI_TEMPLATE, `template S::f'. As a special case, for a member friend template of a template class, this value will not be a TEMPLATE_DECL, but rather a LOOKUP_EXPR or IDENTIFIER_NODE indicating the name of the template and any explicit template arguments provided. For example, in: template struct S { friend void f(int, double); } the DECL_TI_TEMPLATE will be a LOOKUP_EXPR for `f' and the DECL_TI_ARGS will be {int}. */ #define DECL_TI_TEMPLATE(NODE) TI_TEMPLATE (DECL_TEMPLATE_INFO (NODE)) /* The template arguments used to obtain this decl from the most general form of DECL_TI_TEMPLATE. For the example given for DECL_TI_TEMPLATE, the DECL_TI_ARGS will be {int, double}. These are always the full set of arguments required to instantiate this declaration from the most general template specialized here. */ #define DECL_TI_ARGS(NODE) TI_ARGS (DECL_TEMPLATE_INFO (NODE)) #define CLASSTYPE_TI_TEMPLATE(NODE) TI_TEMPLATE (CLASSTYPE_TEMPLATE_INFO (NODE)) #define CLASSTYPE_TI_ARGS(NODE) TI_ARGS (CLASSTYPE_TEMPLATE_INFO (NODE)) #define CLASSTYPE_TI_SPEC_INFO(NODE) TI_SPEC_INFO (CLASSTYPE_TEMPLATE_INFO (NODE)) #define ENUM_TI_TEMPLATE(NODE) \ TI_TEMPLATE (ENUM_TEMPLATE_INFO (NODE)) #define ENUM_TI_ARGS(NODE) \ TI_ARGS (ENUM_TEMPLATE_INFO (NODE)) /* Like DECL_TI_TEMPLATE, but for an ENUMERAL_, RECORD_, or UNION_TYPE. */ #define TYPE_TI_TEMPLATE(NODE) \ (TI_TEMPLATE (TYPE_TEMPLATE_INFO (NODE))) /* Like DECL_TI_ARGS, , but for an ENUMERAL_, RECORD_, or UNION_TYPE. */ #define TYPE_TI_ARGS(NODE) \ (TI_ARGS (TYPE_TEMPLATE_INFO (NODE))) #define INNERMOST_TEMPLATE_PARMS(NODE) TREE_VALUE(NODE) /* Nonzero if the NODE corresponds to the template parameters for a member template, whose inline definition is being processed after the class definition is complete. */ #define TEMPLATE_PARMS_FOR_INLINE(NODE) TREE_LANG_FLAG_1 (NODE) #define DECL_SAVED_TREE(NODE) DECL_MEMFUNC_POINTER_TO (NODE) #define COMPOUND_STMT_NO_SCOPE(NODE) TREE_LANG_FLAG_0 (NODE) #define NEW_EXPR_USE_GLOBAL(NODE) TREE_LANG_FLAG_0 (NODE) #define DELETE_EXPR_USE_GLOBAL(NODE) TREE_LANG_FLAG_0 (NODE) #define DELETE_EXPR_USE_VEC(NODE) TREE_LANG_FLAG_1 (NODE) #define LOOKUP_EXPR_GLOBAL(NODE) TREE_LANG_FLAG_0 (NODE) /* The TYPE_MAIN_DECL for a class template type is a TYPE_DECL, not a TEMPLATE_DECL. This macro determines whether or not a given class type is really a template type, as opposed to an instantiation or specialization of one. */ #define CLASSTYPE_IS_TEMPLATE(NODE) \ (CLASSTYPE_TEMPLATE_INFO (NODE) \ && !CLASSTYPE_USE_TEMPLATE (NODE) \ && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (NODE))) /* The name used by the user to name the typename type. Typically, this is an IDENTIFIER_NODE, and the same as the DECL_NAME on the corresponding TYPE_DECL. However, this may also be a TEMPLATE_ID_EXPR if we had something like `typename X::Y'. */ #define TYPENAME_TYPE_FULLNAME(NODE) TYPE_BINFO (NODE) /* Nonzero if NODE is an implicit typename. */ #define IMPLICIT_TYPENAME_P(NODE) \ (TREE_CODE (NODE) == TYPENAME_TYPE && TREE_TYPE (NODE)) /* Nonzero in INTEGER_CST means that this int is negative by dint of using a twos-complement negated operand. */ #define TREE_NEGATED_INT(NODE) (TREE_LANG_FLAG_0 (NODE)) #if 0 /* UNUSED */ /* Nonzero in any kind of _EXPR or _REF node means that it is a call to a storage allocation routine. If, later, alternate storage is found to hold the object, this call can be ignored. */ #define TREE_CALLS_NEW(NODE) (TREE_LANG_FLAG_1 (NODE)) #endif /* Nonzero in any kind of _TYPE that uses multiple inheritance or virtual baseclasses. */ #define TYPE_USES_COMPLEX_INHERITANCE(NODE) (TREE_LANG_FLAG_1 (NODE)) #if 0 /* UNUSED */ /* Nonzero in IDENTIFIER_NODE means that this name is not the name the user gave; it's a DECL_NESTED_TYPENAME. Someone may want to set this on mangled function names, too, but it isn't currently. */ #define TREE_MANGLED(NODE) (FOO) #endif #if 0 /* UNUSED */ /* Nonzero in IDENTIFIER_NODE means that this name is overloaded, and should be looked up in a non-standard way. */ #define DECL_OVERLOADED(NODE) (FOO) #endif /* Nonzero if this (non-TYPE)_DECL has its virtual attribute set. For a FUNCTION_DECL, this is when the function is a virtual function. For a VAR_DECL, this is when the variable is a virtual function table. For a FIELD_DECL, when the field is the field for the virtual function table. For an IDENTIFIER_NODE, nonzero if any function with this name has been declared virtual. For a _TYPE if it uses virtual functions (or is derived from one that does). */ #define TYPE_VIRTUAL_P(NODE) (TREE_LANG_FLAG_2 (NODE)) extern int flag_new_for_scope; /* This flag is true of a local VAR_DECL if it was declared in a for statement, but we are no longer in the scope of the for. */ #define DECL_DEAD_FOR_LOCAL(NODE) DECL_LANG_FLAG_7 (NODE) /* This flag is set on a VAR_DECL that is a DECL_DEAD_FOR_LOCAL if we already emitted a warning about using it. */ #define DECL_ERROR_REPORTED(NODE) DECL_LANG_FLAG_0 (NODE) /* This _DECL represents a compiler-generated entity. */ #define SET_DECL_ARTIFICIAL(NODE) (DECL_ARTIFICIAL (NODE) = 1) /* Record whether a typedef for type `int' was actually `signed int'. */ #define C_TYPEDEF_EXPLICITLY_SIGNED(exp) DECL_LANG_FLAG_1 ((exp)) /* In a FIELD_DECL, nonzero if the decl was originally a bitfield. */ #define DECL_C_BIT_FIELD(NODE) \ (DECL_LANG_SPECIFIC (NODE) && DECL_LANG_SPECIFIC (NODE)->decl_flags.bitfield) #define SET_DECL_C_BIT_FIELD(NODE) \ (DECL_LANG_SPECIFIC (NODE)->decl_flags.bitfield = 1) /* Nonzero if the type T promotes to itself. ANSI C states explicitly the list of types that promote; in particular, short promotes to int even if they have the same width. */ #define C_PROMOTING_INTEGER_TYPE_P(t) \ (TREE_CODE ((t)) == INTEGER_TYPE \ && (TYPE_MAIN_VARIANT (t) == char_type_node \ || TYPE_MAIN_VARIANT (t) == signed_char_type_node \ || TYPE_MAIN_VARIANT (t) == unsigned_char_type_node \ || TYPE_MAIN_VARIANT (t) == short_integer_type_node \ || TYPE_MAIN_VARIANT (t) == short_unsigned_type_node)) #define INTEGRAL_CODE_P(CODE) \ (CODE == INTEGER_TYPE || CODE == ENUMERAL_TYPE || CODE == BOOLEAN_TYPE) #define ARITHMETIC_TYPE_P(TYPE) (INTEGRAL_TYPE_P (TYPE) || FLOAT_TYPE_P (TYPE)) /* Mark which labels are explicitly declared. These may be shadowed, and may be referenced from nested functions. */ #define C_DECLARED_LABEL_FLAG(label) TREE_LANG_FLAG_1 (label) /* Nonzero for _TYPE means that the _TYPE defines at least one constructor. */ #define TYPE_HAS_CONSTRUCTOR(NODE) (TYPE_LANG_FLAG_1(NODE)) /* When appearing in an INDIRECT_REF, it means that the tree structure underneath is actually a call to a constructor. This is needed when the constructor must initialize local storage (which can be automatically destroyed), rather than allowing it to allocate space from the heap. When appearing in a SAVE_EXPR, it means that underneath is a call to a constructor. When appearing in a CONSTRUCTOR, it means that it was a GNU C constructor expression. When appearing in a FIELD_DECL, it means that this field has been duly initialized in its constructor. */ #define TREE_HAS_CONSTRUCTOR(NODE) (TREE_LANG_FLAG_4(NODE)) #define EMPTY_CONSTRUCTOR_P(NODE) (TREE_CODE (NODE) == CONSTRUCTOR \ && CONSTRUCTOR_ELTS (NODE) == NULL_TREE \ && ! TREE_HAS_CONSTRUCTOR (NODE)) #if 0 /* Indicates that a NON_LVALUE_EXPR came from a C++ reference. Used to generate more helpful error message in case somebody tries to take its address. */ #define TREE_REFERENCE_EXPR(NODE) (TREE_LANG_FLAG_3(NODE)) #endif /* Nonzero for _TYPE means that the _TYPE defines a destructor. */ #define TYPE_HAS_DESTRUCTOR(NODE) (TYPE_LANG_FLAG_2(NODE)) #if 0 /* Nonzero for _TYPE node means that creating an object of this type will involve a call to a constructor. This can apply to objects of ARRAY_TYPE if the type of the elements needs a constructor. */ #define TYPE_NEEDS_CONSTRUCTING(NODE) ... defined in ../tree.h ... #endif /* Nonzero means that an object of this type can not be initialized using an initializer list. */ #define CLASSTYPE_NON_AGGREGATE(NODE) \ (TYPE_LANG_SPECIFIC (NODE)->type_flags.non_aggregate) #define TYPE_NON_AGGREGATE_CLASS(NODE) \ (IS_AGGR_TYPE (NODE) && CLASSTYPE_NON_AGGREGATE (NODE)) /* Nonzero if there is a user-defined X::op=(x&) for this class. */ #define TYPE_HAS_REAL_ASSIGN_REF(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_real_assign_ref) #define TYPE_HAS_COMPLEX_ASSIGN_REF(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_complex_assign_ref) #define TYPE_HAS_ABSTRACT_ASSIGN_REF(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_abstract_assign_ref) #define TYPE_HAS_COMPLEX_INIT_REF(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_complex_init_ref) /* Nonzero for _TYPE node means that destroying an object of this type will involve a call to a destructor. This can apply to objects of ARRAY_TYPE is the type of the elements needs a destructor. */ #define TYPE_NEEDS_DESTRUCTOR(NODE) (TYPE_LANG_FLAG_4(NODE)) /* Nonzero for class type means that initialization of this type can use a bitwise copy. */ #define TYPE_HAS_TRIVIAL_INIT_REF(NODE) \ (TYPE_HAS_INIT_REF (NODE) && ! TYPE_HAS_COMPLEX_INIT_REF (NODE)) /* Nonzero for class type means that assignment of this type can use a bitwise copy. */ #define TYPE_HAS_TRIVIAL_ASSIGN_REF(NODE) \ (TYPE_HAS_ASSIGN_REF (NODE) && ! TYPE_HAS_COMPLEX_ASSIGN_REF (NODE)) #define TYPE_PTRMEM_P(NODE) \ (TREE_CODE (NODE) == POINTER_TYPE \ && TREE_CODE (TREE_TYPE (NODE)) == OFFSET_TYPE) #define TYPE_PTR_P(NODE) \ (TREE_CODE (NODE) == POINTER_TYPE \ && TREE_CODE (TREE_TYPE (NODE)) != OFFSET_TYPE) #define TYPE_PTROB_P(NODE) \ (TYPE_PTR_P (NODE) && TREE_CODE (TREE_TYPE (NODE)) != FUNCTION_TYPE \ && TREE_CODE (TREE_TYPE (NODE)) != VOID_TYPE) #define TYPE_PTROBV_P(NODE) \ (TYPE_PTR_P (NODE) && TREE_CODE (TREE_TYPE (NODE)) != FUNCTION_TYPE) #define TYPE_PTRFN_P(NODE) \ (TREE_CODE (NODE) == POINTER_TYPE \ && TREE_CODE (TREE_TYPE (NODE)) == FUNCTION_TYPE) /* Nonzero for _TYPE node means that this type is a pointer to member function type. */ #define TYPE_PTRMEMFUNC_P(NODE) \ (TREE_CODE(NODE) == RECORD_TYPE && TYPE_PTRMEMFUNC_FLAG (NODE)) #define TYPE_PTRMEMFUNC_FLAG(NODE) \ (TYPE_LANG_SPECIFIC(NODE)->type_flags.ptrmemfunc_flag) /* A pointer-to-function member type looks like: struct { short __delta; short __index; union { P __pfn; short __delta2; } __pfn_or_delta2; }; where P is a POINTER_TYPE to a METHOD_TYPE appropriate for the pointer to member. The fields are used as follows: If __INDEX is -1, then the function to call is non-virtual, and is located at the address given by __PFN. If __INDEX is zero, then this a NULL pointer-to-member. Otherwise, the function to call is virtual. Then, __DELTA2 gives the offset from an instance of the object to the virtual function table, and __INDEX - 1 is the index into the vtable to use to find the function. The value to use for the THIS parameter is the address of the object plus __DELTA. For example, given: struct B1 { int i; }; struct B2 { double d; void f(); }; struct S : public B1, B2 {}; the pointer-to-member for `&S::f' looks like: { 4, -1, { &f__2B2 } }; The `4' means that given an `S*' you have to add 4 bytes to get to the address of the `B2*'. Then, the -1 indicates that this is a non-virtual function. Of course, `&f__2B2' is the name of that function. (Of course, the exactl values may differ depending on the mangling scheme, sizes of types, and such.). */ /* Get the POINTER_TYPE to the METHOD_TYPE associated with this pointer to member function. TYPE_PTRMEMFUNC_P _must_ be true, before using this macro. */ #define TYPE_PTRMEMFUNC_FN_TYPE(NODE) (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (NODE))))))) /* Returns `A' for a type like `int (A::*)(double)' */ #define TYPE_PTRMEMFUNC_OBJECT_TYPE(NODE) \ TYPE_METHOD_BASETYPE (TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (NODE))) /* These are use to manipulate the canonical RECORD_TYPE from the hashed POINTER_TYPE, and can only be used on the POINTER_TYPE. */ #define TYPE_GET_PTRMEMFUNC_TYPE(NODE) ((tree)TYPE_LANG_SPECIFIC(NODE)) #define TYPE_SET_PTRMEMFUNC_TYPE(NODE, VALUE) (TYPE_LANG_SPECIFIC(NODE) = ((struct lang_type *)(void*)(VALUE))) /* These are to get the delta2 and pfn fields from a TYPE_PTRMEMFUNC_P. */ #define DELTA2_FROM_PTRMEMFUNC(NODE) delta2_from_ptrmemfunc ((NODE)) #define PFN_FROM_PTRMEMFUNC(NODE) pfn_from_ptrmemfunc ((NODE)) /* For a pointer-to-member constant `X::Y' this is the RECORD_TYPE for `X'. */ #define PTRMEM_CST_CLASS(NODE) \ (TYPE_PTRMEM_P (TREE_TYPE (NODE)) \ ? TYPE_OFFSET_BASETYPE (TREE_TYPE (TREE_TYPE (NODE))) \ : TYPE_PTRMEMFUNC_OBJECT_TYPE (TREE_TYPE (NODE))) /* For a pointer-to-member constant `X::Y' this is the _DECL for `Y'. */ #define PTRMEM_CST_MEMBER(NODE) (((ptrmem_cst_t) NODE)->member) /* Nonzero for VAR_DECL and FUNCTION_DECL node means that `extern' was specified in its declaration. */ #define DECL_THIS_EXTERN(NODE) (DECL_LANG_FLAG_2(NODE)) /* Nonzero for VAR_DECL and FUNCTION_DECL node means that `static' was specified in its declaration. */ #define DECL_THIS_STATIC(NODE) (DECL_LANG_FLAG_6(NODE)) /* Nonzero in FUNCTION_DECL means it is really an operator. Just used to communicate formatting information to dbxout.c. */ #define DECL_OPERATOR(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.operator_attr) #define ANON_UNION_P(NODE) (DECL_NAME (NODE) == 0) /* Nonzero if TYPE is an anonymous union type. We have to use a flag for this because "A union for which objects or pointers are declared is not an anonymous union" [class.union]. */ #define ANON_UNION_TYPE_P(NODE) \ (TYPE_LANG_SPECIFIC (NODE) \ && TYPE_LANG_SPECIFIC (NODE)->type_flags.anon_union) #define SET_ANON_UNION_TYPE_P(NODE) \ (TYPE_LANG_SPECIFIC (NODE)->type_flags.anon_union = 1) #define UNKNOWN_TYPE LANG_TYPE /* Define fields and accessors for nodes representing declared names. */ #if 0 /* C++: A derived class may be able to directly use the virtual function table of a base class. When it does so, it may still have a decl node used to access the virtual function table (so that variables of this type can initialize their virtual function table pointers by name). When such thievery is committed, know exactly which base class's virtual function table is the one being stolen. This effectively computes the transitive closure. */ #define DECL_VPARENT(NODE) ((NODE)->decl.arguments) #endif #define TYPE_WAS_ANONYMOUS(NODE) (TYPE_LANG_SPECIFIC (NODE)->type_flags.was_anonymous) /* C++: all of these are overloaded! These apply only to TYPE_DECLs. */ /* The format of each node in the DECL_FRIENDLIST is as follows: The TREE_PURPOSE will be the name of a function, i.e., an IDENTIFIER_NODE. The TREE_VALUE will be itself a TREE_LIST, the list of functions with that name which are friends. The TREE_PURPOSE of each node in this sublist will be error_mark_node, if the function was declared a friend individually, in which case the TREE_VALUE will be the function_decl. If, however, all functions with a given name in a class were declared to be friends, the TREE_PUROSE will be the class type, and the TREE_VALUE will be NULL_TREE. */ #define DECL_FRIENDLIST(NODE) (DECL_INITIAL (NODE)) #define FRIEND_NAME(LIST) (TREE_PURPOSE (LIST)) #define FRIEND_DECLS(LIST) (TREE_VALUE (LIST)) /* The DECL_ACCESS, if non-NULL, is a TREE_LIST. The TREE_PURPOSE of each node is a type; the TREE_VALUE is the access granted for this DECL in that type. The DECL_ACCESS is set by access declarations. For example, if a member that would normally be public in a derived class is made protected, then the derived class and the protected_access_node will appear in the DECL_ACCESS for the node. */ #define DECL_ACCESS(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.access) /* C++: all of these are overloaded! These apply to PARM_DECLs and VAR_DECLs. */ #define DECL_REFERENCE_SLOT(NODE) ((tree)(NODE)->decl.arguments) #define SET_DECL_REFERENCE_SLOT(NODE,VAL) ((NODE)->decl.arguments=VAL) /* Accessor macros for C++ template decl nodes. */ /* The DECL_TEMPLATE_PARMS are a list. The TREE_PURPOSE of each node is a INT_CST whose TREE_INT_CST_HIGH indicates the level of the template parameters, with 1 being the outermost set of template parameters. The TREE_VALUE is a vector, whose elements are the template parameters at each level. Each element in the vector is a TREE_LIST, whose TREE_VALUE is a PARM_DECL (if the parameter is a non-type parameter), or a TYPE_DECL (if the parameter is a type parameter). The TREE_PURPOSE is the default value, if any. The TEMPLATE_PARM_INDEX for the parameter is avilable as the DECL_INITIAL (for a PARM_DECL) or as the TREE_TYPE (for a TYPE_DECL). */ #define DECL_TEMPLATE_PARMS(NODE) DECL_ARGUMENTS(NODE) #define DECL_INNERMOST_TEMPLATE_PARMS(NODE) \ INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (NODE)) #define DECL_NTPARMS(NODE) \ TREE_VEC_LENGTH (DECL_INNERMOST_TEMPLATE_PARMS (NODE)) /* For function, method, class-data templates. */ #define DECL_TEMPLATE_RESULT(NODE) DECL_RESULT(NODE) /* For a static member variable template, the DECL_TEMPLATE_INSTANTIATIONS list contains the explicitly and implicitly generated instantiations of the variable. There are no partial instantiations of static member variables, so all of these will be full instantiations. For a class template the DECL_TEMPLATE_INSTANTIATIONS lists holds all instantiations and specializations of the class type, including partial instantiations and partial specializations. In both cases, the TREE_PURPOSE of each node contains the arguments used; the TREE_VALUE contains the generated variable. The template arguments are always complete. For example, given: template struct S1 { template struct S2 {}; template struct S2 {}; }; the record for the partial specialization will contain, as its argument list, { {T}, {U*} }, and will be on the DECL_TEMPLATE_INSTANTIATIONS list for `template template struct S1::S2'. This list is not used for function templates. */ #define DECL_TEMPLATE_INSTANTIATIONS(NODE) DECL_VINDEX(NODE) /* For a function template, the DECL_TEMPLATE_SPECIALIZATIONS lists contains all instantiations and specializations of the function, including partial instantiations. For a partial instantiation which is a specialization, this list holds only full specializations of the template that are instantiations of the partial instantiation. For example, given: template struct S { template void f(U); template <> void f(T); }; the `S::f(int)' function will appear on the DECL_TEMPLATE_SPECIALIZATIONS list for both `template template void S::f(U)' and `template void S::f(T)'. In the latter case, however, it will have only the innermost set of arguments (T, in this case). The DECL_TI_TEMPLATE for the function declaration will point at the specialization, not the fully general template. For a class template, this list contains the partial specializations of this template. (Full specializations are not recorded on this list.) The TREE_PURPOSE holds the innermost arguments used in the partial specialization (e.g., for `template struct S' this will be `T*'.) The TREE_VALUE holds the innermost template parameters for the specialization (e.g., `T' in the example above.) The TREE_TYPE is the _TYPE node for the partial specialization. This list is not used for static variable templates. */ #define DECL_TEMPLATE_SPECIALIZATIONS(NODE) DECL_SIZE(NODE) #define DECL_TEMPLATE_INJECT(NODE) DECL_INITIAL(NODE) /* Nonzero for a DECL which is actually a template parameter. */ #define DECL_TEMPLATE_PARM_P(NODE) \ DECL_LANG_FLAG_0 (NODE) #define DECL_TEMPLATE_TEMPLATE_PARM_P(NODE) \ (TREE_CODE (NODE) == TEMPLATE_DECL && DECL_TEMPLATE_PARM_P (NODE)) #define DECL_FUNCTION_TEMPLATE_P(NODE) \ (TREE_CODE (NODE) == TEMPLATE_DECL \ && TREE_CODE (DECL_TEMPLATE_RESULT (NODE)) == FUNCTION_DECL) /* Nonzero for a DECL that represents a template class. */ #define DECL_CLASS_TEMPLATE_P(NODE) \ (TREE_CODE (NODE) == TEMPLATE_DECL \ && TREE_CODE (DECL_TEMPLATE_RESULT (NODE)) == TYPE_DECL \ && !DECL_TEMPLATE_TEMPLATE_PARM_P (NODE)) /* Nonzero if NODE which declares a type. */ #define DECL_DECLARES_TYPE_P(NODE) \ (TREE_CODE (NODE) == TYPE_DECL || DECL_CLASS_TEMPLATE_P (NODE)) /* A `primary' template is one that has its own template header. A member function of a class template is a template, but not primary. A member template is primary. Friend templates are primary, too. */ /* Returns the primary template corresponding to these parameters. */ #define DECL_PRIMARY_TEMPLATE(NODE) \ (TREE_TYPE (DECL_INNERMOST_TEMPLATE_PARMS (NODE))) /* Returns non-zero if NODE is a primary template. */ #define PRIMARY_TEMPLATE_P(NODE) (DECL_PRIMARY_TEMPLATE (NODE) == NODE) #define CLASSTYPE_TEMPLATE_LEVEL(NODE) \ (TREE_INT_CST_HIGH (TREE_PURPOSE (CLASSTYPE_TI_TEMPLATE (NODE)))) /* Indicates whether or not (and how) a template was expanded for this FUNCTION_DECL or VAR_DECL. 0=normal declaration, e.g. int min (int, int); 1=implicit template instantiation 2=explicit template specialization, e.g. int min (int, int); 3=explicit template instantiation, e.g. template int min (int, int); */ #define DECL_USE_TEMPLATE(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.use_template) #define DECL_TEMPLATE_INSTANTIATION(NODE) (DECL_USE_TEMPLATE (NODE) & 1) #define CLASSTYPE_TEMPLATE_INSTANTIATION(NODE) \ (CLASSTYPE_USE_TEMPLATE (NODE) & 1) #define DECL_TEMPLATE_SPECIALIZATION(NODE) (DECL_USE_TEMPLATE (NODE) == 2) #define SET_DECL_TEMPLATE_SPECIALIZATION(NODE) (DECL_USE_TEMPLATE (NODE) = 2) #define CLASSTYPE_TEMPLATE_SPECIALIZATION(NODE) \ (CLASSTYPE_USE_TEMPLATE (NODE) == 2) #define SET_CLASSTYPE_TEMPLATE_SPECIALIZATION(NODE) \ (CLASSTYPE_USE_TEMPLATE (NODE) = 2) #define DECL_IMPLICIT_INSTANTIATION(NODE) (DECL_USE_TEMPLATE (NODE) == 1) #define SET_DECL_IMPLICIT_INSTANTIATION(NODE) (DECL_USE_TEMPLATE (NODE) = 1) #define CLASSTYPE_IMPLICIT_INSTANTIATION(NODE) \ (CLASSTYPE_USE_TEMPLATE(NODE) == 1) #define SET_CLASSTYPE_IMPLICIT_INSTANTIATION(NODE) \ (CLASSTYPE_USE_TEMPLATE(NODE) = 1) #define DECL_EXPLICIT_INSTANTIATION(NODE) (DECL_USE_TEMPLATE (NODE) == 3) #define SET_DECL_EXPLICIT_INSTANTIATION(NODE) (DECL_USE_TEMPLATE (NODE) = 3) #define CLASSTYPE_EXPLICIT_INSTANTIATION(NODE) \ (CLASSTYPE_USE_TEMPLATE(NODE) == 3) #define SET_CLASSTYPE_EXPLICIT_INSTANTIATION(NODE) \ (CLASSTYPE_USE_TEMPLATE(NODE) = 3) /* Non-zero if DECL is a friend function which is an instantiation from the point of view of the compiler, but not from the point of view of the language. For example given: template struct S { friend void f(T) {}; }; the declaration of `void f(int)' generated when S is instantiated will not be a DECL_TEMPLATE_INSTANTIATION, but will be a DECL_FRIEND_PSUEDO_TEMPLATE_INSTANTIATION. */ #define DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION(DECL) \ (DECL_TEMPLATE_INFO (DECL) && !DECL_USE_TEMPLATE (DECL)) /* Non-zero if TYPE is a partial instantiation of a template class, i.e., an instantiation whose instantiation arguments involve template types. */ #define PARTIAL_INSTANTIATION_P(TYPE) \ (TYPE_LANG_SPECIFIC (TYPE)->type_flags.is_partial_instantiation) /* Non-zero iff we are currently processing a declaration for an entity with its own template parameter list, and which is not a full specialization. */ #define PROCESSING_REAL_TEMPLATE_DECL_P() \ (processing_template_decl > template_class_depth (current_class_type)) /* This function may be a guiding decl for a template. */ #define DECL_MAYBE_TEMPLATE(NODE) DECL_LANG_FLAG_4 (NODE) /* Nonzero if this VAR_DECL or FUNCTION_DECL has already been instantiated, i.e. its definition has been generated from the pattern given in the the template. */ #define DECL_TEMPLATE_INSTANTIATED(NODE) DECL_LANG_FLAG_1(NODE) /* We know what we're doing with this decl now. */ #define DECL_INTERFACE_KNOWN(NODE) DECL_LANG_FLAG_5 (NODE) /* This function was declared inline. This flag controls the linkage semantics of 'inline'; whether or not the function is inlined is controlled by DECL_INLINE. */ #define DECL_THIS_INLINE(NODE) \ (DECL_LANG_SPECIFIC (NODE)->decl_flags.declared_inline) /* DECL_EXTERNAL must be set on a decl until the decl is actually emitted, so that assemble_external will work properly. So we have this flag to tell us whether the decl is really not external. */ #define DECL_NOT_REALLY_EXTERN(NODE) \ (DECL_LANG_SPECIFIC (NODE)->decl_flags.not_really_extern) #define DECL_REALLY_EXTERN(NODE) \ (DECL_EXTERNAL (NODE) && ! DECL_NOT_REALLY_EXTERN (NODE)) #define THUNK_DELTA(DECL) ((DECL)->decl.frame_size.i) /* ...and for unexpanded-parameterized-type nodes. */ #define UPT_TEMPLATE(NODE) TREE_PURPOSE(TYPE_VALUES(NODE)) #define UPT_PARMS(NODE) TREE_VALUE(TYPE_VALUES(NODE)) /* An un-parsed default argument looks like an identifier. */ #define DEFARG_NODE_CHECK(t) TREE_CHECK(t, DEFAULT_ARG) #define DEFARG_LENGTH(NODE) (DEFARG_NODE_CHECK(NODE)->identifier.length) #define DEFARG_POINTER(NODE) (DEFARG_NODE_CHECK(NODE)->identifier.pointer) #define builtin_function(NAME, TYPE, CODE, LIBNAME) \ define_function (NAME, TYPE, CODE, (void (*) PROTO((tree)))pushdecl, LIBNAME) /* These macros provide convenient access to the various _STMT nodes created when parsing template declarations. */ #define IF_COND(NODE) TREE_OPERAND (NODE, 0) #define THEN_CLAUSE(NODE) TREE_OPERAND (NODE, 1) #define ELSE_CLAUSE(NODE) TREE_OPERAND (NODE, 2) #define WHILE_COND(NODE) TREE_OPERAND (NODE, 0) #define WHILE_BODY(NODE) TREE_OPERAND (NODE, 1) #define DO_COND(NODE) TREE_OPERAND (NODE, 0) #define DO_BODY(NODE) TREE_OPERAND (NODE, 1) #define RETURN_EXPR(NODE) TREE_OPERAND (NODE, 0) #define EXPR_STMT_EXPR(NODE) TREE_OPERAND (NODE, 0) #define FOR_INIT_STMT(NODE) TREE_OPERAND (NODE, 0) #define FOR_COND(NODE) TREE_OPERAND (NODE, 1) #define FOR_EXPR(NODE) TREE_OPERAND (NODE, 2) #define FOR_BODY(NODE) TREE_OPERAND (NODE, 3) #define SWITCH_COND(NODE) TREE_OPERAND (NODE, 0) #define SWITCH_BODY(NODE) TREE_OPERAND (NODE, 1) #define CASE_LOW(NODE) TREE_OPERAND (NODE, 0) #define CASE_HIGH(NODE) TREE_OPERAND (NODE, 1) #define GOTO_DESTINATION(NODE) TREE_OPERAND (NODE, 0) #define TRY_STMTS(NODE) TREE_OPERAND (NODE, 0) #define TRY_HANDLERS(NODE) TREE_OPERAND (NODE, 1) #define HANDLER_PARMS(NODE) TREE_OPERAND (NODE, 0) #define HANDLER_BODY(NODE) TREE_OPERAND (NODE, 1) #define COMPOUND_BODY(NODE) TREE_OPERAND (NODE, 0) #define ASM_CV_QUAL(NODE) TREE_OPERAND (NODE, 0) #define ASM_STRING(NODE) TREE_OPERAND (NODE, 1) #define ASM_OUTPUTS(NODE) TREE_OPERAND (NODE, 2) #define ASM_INPUTS(NODE) TREE_OPERAND (NODE, 3) #define ASM_CLOBBERS(NODE) TREE_OPERAND (NODE, 4) /* An enumeration of the kind of tags that C++ accepts. */ enum tag_types { record_type, class_type, union_type, enum_type, signature_type }; /* Zero means prototype weakly, as in ANSI C (no args means nothing). Each language context defines how this variable should be set. */ extern int strict_prototype; extern int strict_prototypes_lang_c, strict_prototypes_lang_cplusplus; /* Non-zero means that if a label exists, and no other identifier applies, use the value of the label. */ extern int flag_labels_ok; /* 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. */ extern int warn_overloaded_virtual; /* Nonzero means warn about use of multicharacter literals. */ extern int warn_multichar; /* Non-zero means warn if a non-templatized friend function is declared in a templatized class. This behavior is warned about with flag_guiding_decls in do_friend. */ extern int warn_nontemplate_friend; /* in c-common.c */ extern void declare_function_name PROTO((void)); extern void decl_attributes PROTO((tree, tree, tree)); extern void init_function_format_info PROTO((void)); extern void record_function_format PROTO((tree, tree, int, int, int)); extern void check_function_format PROTO((tree, tree, tree)); /* Print an error message for invalid operands to arith operation CODE. NOP_EXPR is used as a special case (see truthvalue_conversion). */ extern void binary_op_error PROTO((enum tree_code)); extern tree cp_build_qualified_type PROTO((tree, int)); extern tree canonical_type_variant PROTO((tree)); extern void c_expand_expr_stmt PROTO((tree)); /* Validate the expression after `case' and apply default promotions. */ extern tree check_case_value PROTO((tree)); /* Concatenate a list of STRING_CST nodes into one STRING_CST. */ extern tree combine_strings PROTO((tree)); extern void constant_expression_warning PROTO((tree)); extern tree convert_and_check PROTO((tree, tree)); extern void overflow_warning PROTO((tree)); extern void unsigned_conversion_warning PROTO((tree, tree)); extern void c_apply_type_quals_to_decl PROTO((int, tree)); /* Read the rest of the current #-directive line. */ #if USE_CPPLIB extern char *get_directive_line PROTO((void)); #define GET_DIRECTIVE_LINE() get_directive_line () #else extern char *get_directive_line PROTO((FILE *)); #define GET_DIRECTIVE_LINE() get_directive_line (finput) #endif /* Subroutine of build_binary_op, used for comparison operations. See if the operands have both been converted from subword integer types and, if so, perhaps change them both back to their original type. */ extern tree shorten_compare PROTO((tree *, tree *, tree *, enum tree_code *)); /* Prepare expr to be an argument of a TRUTH_NOT_EXPR, or validate its data type for an `if' or `while' statement or ?..: exp. */ extern tree truthvalue_conversion PROTO((tree)); extern tree type_for_mode PROTO((enum machine_mode, int)); extern tree type_for_size PROTO((unsigned, int)); extern int c_get_alias_set PROTO((tree)); /* in decl{2}.c */ extern tree void_list_node; extern tree void_zero_node; extern tree default_function_type; extern tree vtable_entry_type; extern tree sigtable_entry_type; extern tree __t_desc_type_node; #if 0 extern tree __tp_desc_type_node; #endif extern tree __access_mode_type_node; extern tree __bltn_desc_type_node, __user_desc_type_node; extern tree __class_desc_type_node, __attr_desc_type_node; extern tree __ptr_desc_type_node, __func_desc_type_node; extern tree __ptmf_desc_type_node, __ptmd_desc_type_node; extern tree type_info_type_node; extern tree class_star_type_node; extern tree this_identifier; extern tree ctor_identifier, dtor_identifier; extern tree pfn_identifier; extern tree index_identifier; extern tree delta_identifier; extern tree delta2_identifier; extern tree pfn_or_delta2_identifier; extern tree tag_identifier; extern tree vt_off_identifier; +extern tree in_charge_identifier; /* A node that is a list (length 1) of error_mark_nodes. */ extern tree error_mark_list; extern tree ptr_type_node; extern tree class_type_node, record_type_node, union_type_node, enum_type_node; extern tree unknown_type_node; extern tree opaque_type_node, signature_type_node; +extern tree vlist_identifier, vlist_type_node, vlist_zero_node; + /* Node for "pointer to (virtual) function". This may be distinct from ptr_type_node so gdb can distinguish them. */ #define vfunc_ptr_type_node \ (flag_vtable_thunks ? vtable_entry_type : ptr_type_node) /* The type of a vtbl, i.e., an array of vtable entries. */ extern tree vtbl_type_node; /* The type of a class vtbl pointer, i.e., a pointer to a vtable entry. */ extern tree vtbl_ptr_type_node; extern tree delta_type_node; extern tree std_node; extern tree long_long_integer_type_node, long_long_unsigned_type_node; /* For building calls to `delete'. */ extern tree integer_two_node, integer_three_node; extern tree boolean_type_node, boolean_true_node, boolean_false_node; extern tree null_node; extern tree anonymous_namespace_name; /* The FUNCTION_DECL for the default `::operator delete'. */ extern tree global_delete_fndecl; /* in pt.c */ /* These values are used for the `STRICT' parameter to type_unfication and fn_type_unification. Their meanings are described with the documentation for fn_type_unification. */ typedef enum unification_kind_t { DEDUCE_CALL, DEDUCE_CONV, DEDUCE_EXACT } unification_kind_t; extern tree current_template_parms; extern HOST_WIDE_INT processing_template_decl; extern tree last_tree; /* The template currently being instantiated, and where the instantiation was triggered. */ struct tinst_level { tree decl; int line; char *file; struct tinst_level *next; }; extern int minimal_parse_mode; extern void maybe_print_template_context PROTO ((void)); /* in class.c */ /* When parsing a class definition, the access specifier most recently given by the user, or, if no access specifier was given, the default value appropriate for the kind of class (i.e., struct, class, or union). */ extern tree current_access_specifier; extern tree current_class_name; extern tree current_class_type; extern tree current_class_ptr; extern tree previous_class_type; extern tree current_class_ref; extern int current_class_depth; extern tree current_lang_name; extern tree lang_name_cplusplus, lang_name_c, lang_name_java; /* The low-water mark on the class-cache obstack. */ extern char *class_cache_firstobj; /* Points to the name of that function. May not be the DECL_NAME of CURRENT_FUNCTION_DECL due to overloading */ extern tree original_function_name; /* in init.c */ extern tree global_base_init_list; extern tree current_base_init_list, current_member_init_list; extern int current_function_just_assigned_this; extern int current_function_parms_stored; /* Here's where we control how name mangling takes place. */ #define OPERATOR_ASSIGN_FORMAT "__a%s" #define OPERATOR_FORMAT "__%s" #define OPERATOR_TYPENAME_FORMAT "__op" /* Cannot use '$' up front, because this confuses gdb (names beginning with '$' are gdb-local identifiers). Note that all forms in which the '$' is significant are long enough for direct indexing (meaning that if we know there is a '$' at a particular location, we can index into the string at any other location that provides distinguishing characters). */ /* Define NO_DOLLAR_IN_LABEL in your favorite tm file if your assembler doesn't allow '$' in symbol names. */ #ifndef NO_DOLLAR_IN_LABEL #define JOINER '$' #define VPTR_NAME "$v" #define THROW_NAME "$eh_throw" #define DESTRUCTOR_DECL_PREFIX "_$_" #define AUTO_VTABLE_NAME "__vtbl$me__" #define AUTO_TEMP_NAME "_$tmp_" #define AUTO_TEMP_FORMAT "_$tmp_%d" #define VTABLE_BASE "$vb" #define VTABLE_NAME_FORMAT (flag_vtable_thunks ? "__vt_%s" : "_vt$%s") +#define VCTABLE_NAME "__vc$" +#define VLIST_NAME_FORMAT "__vl$%s" #define VFIELD_BASE "$vf" #define VFIELD_NAME "_vptr$" #define VFIELD_NAME_FORMAT "_vptr$%s" #define VBASE_NAME "_vb$" #define VBASE_NAME_FORMAT "_vb$%s" #define STATIC_NAME_FORMAT "_%s$%s" #define ANON_AGGRNAME_FORMAT "$_%d" #else /* NO_DOLLAR_IN_LABEL */ #ifndef NO_DOT_IN_LABEL #define JOINER '.' #define VPTR_NAME ".v" #define THROW_NAME ".eh_throw" #define DESTRUCTOR_DECL_PREFIX "_._" #define AUTO_VTABLE_NAME "__vtbl.me__" #define AUTO_TEMP_NAME "_.tmp_" #define AUTO_TEMP_FORMAT "_.tmp_%d" #define VTABLE_BASE ".vb" #define VTABLE_NAME_FORMAT (flag_vtable_thunks ? "__vt_%s" : "_vt.%s") +#define VCTABLE_NAME "__vc." +#define VLIST_NAME_FORMAT "__vl.%s" #define VFIELD_BASE ".vf" #define VFIELD_NAME "_vptr." #define VFIELD_NAME_FORMAT "_vptr.%s" #define VBASE_NAME "_vb." #define VBASE_NAME_FORMAT "_vb.%s" #define STATIC_NAME_FORMAT "_%s.%s" #define ANON_AGGRNAME_FORMAT "._%d" #else /* NO_DOT_IN_LABEL */ #define VPTR_NAME "__vptr" #define VPTR_NAME_P(ID_NODE) \ (!strncmp (IDENTIFIER_POINTER (ID_NODE), VPTR_NAME, sizeof (VPTR_NAME) - 1)) #define THROW_NAME "__eh_throw" #define DESTRUCTOR_DECL_PREFIX "__destr_" #define DESTRUCTOR_NAME_P(ID_NODE) \ (!strncmp (IDENTIFIER_POINTER (ID_NODE), DESTRUCTOR_DECL_PREFIX, \ sizeof (DESTRUCTOR_DECL_PREFIX) - 1)) #define IN_CHARGE_NAME "__in_chrg" #define AUTO_VTABLE_NAME "__vtbl_me__" #define AUTO_TEMP_NAME "__tmp_" #define TEMP_NAME_P(ID_NODE) \ (!strncmp (IDENTIFIER_POINTER (ID_NODE), AUTO_TEMP_NAME, \ sizeof (AUTO_TEMP_NAME) - 1)) #define AUTO_TEMP_FORMAT "__tmp_%d" #define VTABLE_BASE "__vtb" #define VTABLE_NAME "__vt_" #define VTABLE_NAME_FORMAT (flag_vtable_thunks ? "__vt_%s" : "_vt_%s") #define VTABLE_NAME_P(ID_NODE) \ (!strncmp (IDENTIFIER_POINTER (ID_NODE), VTABLE_NAME, \ sizeof (VTABLE_NAME) - 1)) +#define VCTABLE_NAME "__vc_" +#define VLIST_NAME_FORMAT "__vl_%s" #define VFIELD_BASE "__vfb" #define VFIELD_NAME "__vptr_" #define VFIELD_NAME_P(ID_NODE) \ (!strncmp (IDENTIFIER_POINTER (ID_NODE), VFIELD_NAME, \ sizeof (VFIELD_NAME) - 1)) #define VFIELD_NAME_FORMAT "_vptr_%s" #define VBASE_NAME "__vb_" #define VBASE_NAME_P(ID_NODE) \ (!strncmp (IDENTIFIER_POINTER (ID_NODE), VBASE_NAME, \ sizeof (VBASE_NAME) - 1)) #define VBASE_NAME_FORMAT "__vb_%s" #define STATIC_NAME_FORMAT "__static_%s_%s" #define ANON_AGGRNAME_PREFIX "__anon_" #define ANON_AGGRNAME_P(ID_NODE) \ (!strncmp (IDENTIFIER_POINTER (ID_NODE), ANON_AGGRNAME_PREFIX, \ sizeof (ANON_AGGRNAME_PREFIX) - 1)) #define ANON_AGGRNAME_FORMAT "__anon_%d" #define ANON_PARMNAME_FORMAT "__%d" #define ANON_PARMNAME_P(ID_NODE) (IDENTIFIER_POINTER (ID_NODE)[0] == '_' \ && IDENTIFIER_POINTER (ID_NODE)[1] == '_' \ && IDENTIFIER_POINTER (ID_NODE)[2] <= '9') #endif /* NO_DOT_IN_LABEL */ #endif /* NO_DOLLAR_IN_LABEL */ #define THIS_NAME "this" #define DESTRUCTOR_NAME_FORMAT "~%s" #define FILE_FUNCTION_PREFIX_LEN 9 #define CTOR_NAME "__ct" #define DTOR_NAME "__dt" #define IN_CHARGE_NAME "__in_chrg" +#define VLIST_NAME "__vlist" +#define VLIST1_NAME "__vlist1" +#define VLIST_TYPE_NAME "6_Vlist" #define VTBL_PTR_TYPE "__vtbl_ptr_type" #define VTABLE_DELTA_NAME "__delta" #define VTABLE_INDEX_NAME "__index" #define VTABLE_PFN_NAME "__pfn" #define VTABLE_DELTA2_NAME "__delta2" #define SIGNATURE_FIELD_NAME "__s_" #define SIGNATURE_FIELD_NAME_FORMAT "__s_%s" #define SIGNATURE_OPTR_NAME "__optr" #define SIGNATURE_SPTR_NAME "__sptr" #define SIGNATURE_POINTER_NAME "__sp_" #define SIGNATURE_POINTER_NAME_FORMAT "__%s%s%ssp_%s" #define SIGNATURE_REFERENCE_NAME "__sr_" #define SIGNATURE_REFERENCE_NAME_FORMAT "__%s%s%ssr_%s" #define SIGTABLE_PTR_TYPE "__sigtbl_ptr_type" #define SIGTABLE_NAME_FORMAT "__st_%s_%s" #define SIGTABLE_NAME_FORMAT_LONG "__st_%s_%s_%d" #define SIGTABLE_TAG_NAME "__tag" #define SIGTABLE_VB_OFF_NAME "__vb_off" #define SIGTABLE_VT_OFF_NAME "__vt_off" #define EXCEPTION_CLEANUP_NAME "exception cleanup" #define THIS_NAME_P(ID_NODE) (strcmp(IDENTIFIER_POINTER (ID_NODE), "this") == 0) #if !defined(NO_DOLLAR_IN_LABEL) || !defined(NO_DOT_IN_LABEL) #define VPTR_NAME_P(ID_NODE) (IDENTIFIER_POINTER (ID_NODE)[0] == JOINER \ && IDENTIFIER_POINTER (ID_NODE)[1] == 'v') #define DESTRUCTOR_NAME_P(ID_NODE) (IDENTIFIER_POINTER (ID_NODE)[1] == JOINER \ && IDENTIFIER_POINTER (ID_NODE)[2] == '_') #define VTABLE_NAME_P(ID_NODE) (IDENTIFIER_POINTER (ID_NODE)[1] == 'v' \ && IDENTIFIER_POINTER (ID_NODE)[2] == 't' \ && IDENTIFIER_POINTER (ID_NODE)[3] == JOINER) #define VBASE_NAME_P(ID_NODE) (IDENTIFIER_POINTER (ID_NODE)[1] == 'v' \ && IDENTIFIER_POINTER (ID_NODE)[2] == 'b' \ && IDENTIFIER_POINTER (ID_NODE)[3] == JOINER) #define TEMP_NAME_P(ID_NODE) (!strncmp (IDENTIFIER_POINTER (ID_NODE), AUTO_TEMP_NAME, sizeof (AUTO_TEMP_NAME)-1)) #define VFIELD_NAME_P(ID_NODE) (!strncmp (IDENTIFIER_POINTER (ID_NODE), VFIELD_NAME, sizeof(VFIELD_NAME)-1)) /* For anonymous aggregate types, we need some sort of name to hold on to. In practice, this should not appear, but it should not be harmful if it does. */ #define ANON_AGGRNAME_P(ID_NODE) (IDENTIFIER_POINTER (ID_NODE)[0] == JOINER \ && IDENTIFIER_POINTER (ID_NODE)[1] == '_') #define ANON_PARMNAME_FORMAT "_%d" #define ANON_PARMNAME_P(ID_NODE) (IDENTIFIER_POINTER (ID_NODE)[0] == '_' \ && IDENTIFIER_POINTER (ID_NODE)[1] <= '9') #endif /* !defined(NO_DOLLAR_IN_LABEL) || !defined(NO_DOT_IN_LABEL) */ /* Store the vbase pointer field name for type TYPE into pointer BUF. */ #define FORMAT_VBASE_NAME(BUF,TYPE) do { \ char *wbuf = (char *) alloca (TYPE_ASSEMBLER_NAME_LENGTH (TYPE) \ + sizeof (VBASE_NAME) + 1); \ sprintf (wbuf, VBASE_NAME_FORMAT, TYPE_ASSEMBLER_NAME_STRING (TYPE)); \ (BUF) = wbuf; \ } while (0) /* Returns non-zero iff ID_NODE is an IDENTIFIER_NODE whose name is `main'. */ #define MAIN_NAME_P(ID_NODE) \ (strcmp (IDENTIFIER_POINTER (ID_NODE), "main") == 0) /* Returns non-zero iff NODE is a declaration for the global function `main'. */ #define DECL_MAIN_P(NODE) \ (TREE_CODE (NODE) == FUNCTION_DECL \ && DECL_LANGUAGE (NODE) == lang_c \ && DECL_NAME (NODE) != NULL_TREE \ && MAIN_NAME_P (DECL_NAME (NODE))) /* Define the sets of attributes that member functions and baseclasses can have. These are sensible combinations of {public,private,protected} cross {virtual,non-virtual}. */ /* in class.c. */ extern tree access_default_node; /* 0 */ extern tree access_public_node; /* 1 */ extern tree access_protected_node; /* 2 */ extern tree access_private_node; /* 3 */ extern tree access_default_virtual_node; /* 4 */ extern tree access_public_virtual_node; /* 5 */ extern tree access_protected_virtual_node; /* 6 */ extern tree access_private_virtual_node; /* 7 */ /* 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 */ 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; /* Positive values means that we cannot make optimizing assumptions about `this'. Negative values means we know `this' to be of static type. */ extern int flag_this_is_variable; /* Nonzero means generate 'rtti' that give run-time type information. */ extern int flag_rtti; /* Nonzero means do emit exported implementations of functions even if they can be inlined. */ extern int flag_implement_inlines; /* Nonzero means templates obey #pragma interface and implementation. */ extern int flag_external_templates; /* Nonzero means templates are emitted where they are instantiated. */ extern int flag_alt_external_templates; /* Nonzero means implicit template instantiations are emitted. */ extern int flag_implicit_templates; /* Nonzero if we want to emit defined symbols with common-like linkage as weak symbols where possible, in order to conform to C++ semantics. Otherwise, emit them as local symbols. */ extern int flag_weak; /* Nonzero to enable experimental ABI changes. */ extern int flag_new_abi; /* Nonzero to not ignore namespace std. */ extern int flag_honor_std; /* Nonzero if we're done parsing and into end-of-file activities. */ extern int at_eof; enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, OP_FLAG, TYPENAME_FLAG }; /* The following two can be derived from the previous one */ extern tree current_class_name; /* IDENTIFIER_NODE: name of current class */ /* Some macros for char-based bitfields. */ #define B_SET(a,x) (a[x>>3] |= (1 << (x&7))) #define B_CLR(a,x) (a[x>>3] &= ~(1 << (x&7))) #define B_TST(a,x) (a[x>>3] & (1 << (x&7))) /* These are uses as bits in flags passed to build_method_call to control its error reporting behavior. LOOKUP_PROTECT means flag access violations. LOOKUP_COMPLAIN mean complain if no suitable member function matching the arguments is found. LOOKUP_NORMAL is just a combination of these two. LOOKUP_NONVIRTUAL means make a direct call to the member function found LOOKUP_GLOBAL means search through the space of overloaded functions, as well as the space of member functions. LOOKUP_HAS_IN_CHARGE means that the "in charge" variable is already in the parameter list. + LOOKUP_HAS_VLIST means that the "vlist" variable is already in + the parameter list. LOOKUP_ONLYCONVERTING means that non-conversion constructors are not tried. DIRECT_BIND means that if a temporary is created, it should be created so that it lives as long as the current variable bindings; otherwise it only lives until the end of the complete-expression. LOOKUP_SPECULATIVELY means return NULL_TREE if we cannot find what we are after. Note, LOOKUP_COMPLAIN is checked and error messages printed before LOOKUP_SPECULATIVELY is checked. LOOKUP_NO_CONVERSION means that user-defined conversions are not permitted. Built-in conversions are permitted. LOOKUP_DESTRUCTOR means explicit call to destructor. LOOKUP_NO_TEMP_BIND means temporaries will not be bound to references. These are used in global lookup to support elaborated types and qualifiers. LOOKUP_PREFER_TYPES means not to accept objects, and possibly namespaces. LOOKUP_PREFER_NAMESPACES means not to accept objects, and possibly types. LOOKUP_PREFER_BOTH means class-or-namespace-name. LOOKUP_TEMPLATES_EXPECTED means that class templates also count as types. */ #define LOOKUP_PROTECT (1) #define LOOKUP_COMPLAIN (2) #define LOOKUP_NORMAL (3) /* #define LOOKUP_UNUSED (4) */ #define LOOKUP_NONVIRTUAL (8) #define LOOKUP_GLOBAL (16) #define LOOKUP_HAS_IN_CHARGE (32) #define LOOKUP_SPECULATIVELY (64) #define LOOKUP_ONLYCONVERTING (128) #define DIRECT_BIND (256) #define LOOKUP_NO_CONVERSION (512) #define LOOKUP_DESTRUCTOR (512) #define LOOKUP_NO_TEMP_BIND (1024) #define LOOKUP_PREFER_TYPES (2048) #define LOOKUP_PREFER_NAMESPACES (4096) #define LOOKUP_PREFER_BOTH (6144) #define LOOKUP_TEMPLATES_EXPECTED (8192) +#define LOOKUP_HAS_VLIST (16384) #define LOOKUP_NAMESPACES_ONLY(f) \ (((f) & LOOKUP_PREFER_NAMESPACES) && !((f) & LOOKUP_PREFER_TYPES)) #define LOOKUP_TYPES_ONLY(f) \ (!((f) & LOOKUP_PREFER_NAMESPACES) && ((f) & LOOKUP_PREFER_TYPES)) #define LOOKUP_QUALIFIERS_ONLY(f) ((f) & LOOKUP_PREFER_BOTH) /* These flags are used by the conversion code. CONV_IMPLICIT : Perform implicit conversions (standard and user-defined). CONV_STATIC : Perform the explicit conversions for static_cast. CONV_CONST : Perform the explicit conversions for const_cast. CONV_REINTERPRET: Perform the explicit conversions for reinterpret_cast. CONV_PRIVATE : Perform upcasts to private bases. CONV_FORCE_TEMP : Require a new temporary when converting to the same aggregate type. */ #define CONV_IMPLICIT 1 #define CONV_STATIC 2 #define CONV_CONST 4 #define CONV_REINTERPRET 8 #define CONV_PRIVATE 16 /* #define CONV_NONCONVERTING 32 */ #define CONV_FORCE_TEMP 64 #define CONV_STATIC_CAST (CONV_IMPLICIT | CONV_STATIC | CONV_FORCE_TEMP) #define CONV_OLD_CONVERT (CONV_IMPLICIT | CONV_STATIC | CONV_CONST \ | CONV_REINTERPRET) #define CONV_C_CAST (CONV_IMPLICIT | CONV_STATIC | CONV_CONST \ | CONV_REINTERPRET | CONV_PRIVATE | CONV_FORCE_TEMP) /* Used by build_expr_type_conversion to indicate which types are acceptable as arguments to the expression under consideration. */ #define WANT_INT 1 /* integer types, including bool */ #define WANT_FLOAT 2 /* floating point types */ #define WANT_ENUM 4 /* enumerated types */ #define WANT_POINTER 8 /* pointer types */ #define WANT_NULL 16 /* null pointer constant */ #define WANT_ARITH (WANT_INT | WANT_FLOAT) /* Used with comptypes, and related functions, to guide type comparison. */ #define COMPARE_STRICT 0 /* Just check if the types are the same. */ #define COMPARE_BASE 1 /* Check to see if the second type is derived from the first, or if both are pointers (or references) and the types pointed to by the second type is derived from the pointed to by the first. */ #define COMPARE_RELAXED 2 /* Like COMPARE_DERIVED, but in reverse. Also treat enmeration types as the same as integer types of the same width. */ #define COMPARE_REDECLARATION 4 /* The comparsion is being done when another declaration of an existing entity is seen. */ #define COMPARE_NO_ATTRIBUTES 8 /* The comparison should ignore extra-linguistic type attributes. */ /* Used with push_overloaded_decl. */ #define PUSH_GLOBAL 0 /* Push the DECL into namespace scope, regardless of the current scope. */ #define PUSH_LOCAL 1 /* Push the DECL into the current scope. */ #define PUSH_USING 2 /* We are pushing this DECL as the result of a using declaration. */ /* Returns nonzero iff TYPE1 and TYPE2 are the same type, in the usual sense of `same'. */ #define same_type_p(type1, type2) \ comptypes ((type1), (type2), COMPARE_STRICT) /* Returns nonzero iff TYPE1 and TYPE2 are the same type, or if TYPE2 is derived from TYPE1, or if TYPE2 is a pointer (reference) to a class derived from the type pointed to (referred to) by TYPE1. */ #define same_or_base_type_p(type1, type2) \ comptypes ((type1), (type2), COMPARE_BASE) /* These macros are used to access a TEMPLATE_PARM_INDEX. */ #define TEMPLATE_PARM_IDX(NODE) (((template_parm_index*) NODE)->index) #define TEMPLATE_PARM_LEVEL(NODE) (((template_parm_index*) NODE)->level) #define TEMPLATE_PARM_DESCENDANTS(NODE) (TREE_CHAIN (NODE)) #define TEMPLATE_PARM_ORIG_LEVEL(NODE) (((template_parm_index*) NODE)->orig_level) #define TEMPLATE_PARM_DECL(NODE) (((template_parm_index*) NODE)->decl) /* These macros are for accessing the fields of TEMPLATE_TYPE_PARM and TEMPLATE_TEMPLATE_PARM nodes. */ #define TEMPLATE_TYPE_PARM_INDEX(NODE) (TYPE_FIELDS (NODE)) #define TEMPLATE_TYPE_IDX(NODE) \ (TEMPLATE_PARM_IDX (TEMPLATE_TYPE_PARM_INDEX (NODE))) #define TEMPLATE_TYPE_LEVEL(NODE) \ (TEMPLATE_PARM_LEVEL (TEMPLATE_TYPE_PARM_INDEX (NODE))) #define TEMPLATE_TYPE_ORIG_LEVEL(NODE) \ (TEMPLATE_PARM_ORIG_LEVEL (TEMPLATE_TYPE_PARM_INDEX (NODE))) #define TEMPLATE_TYPE_DECL(NODE) \ (TEMPLATE_PARM_DECL (TEMPLATE_TYPE_PARM_INDEX (NODE))) /* in lex.c */ /* Indexed by TREE_CODE, these tables give C-looking names to operators represented by TREE_CODES. For example, opname_tab[(int) MINUS_EXPR] == "-". */ extern char **opname_tab, **assignop_tab; /* in call.c */ extern int check_dtor_name PROTO((tree, tree)); extern int get_arglist_len_in_bytes PROTO((tree)); extern tree build_vfield_ref PROTO((tree, tree)); extern tree resolve_scope_to_name PROTO((tree, tree)); extern tree build_scoped_method_call PROTO((tree, tree, tree, tree)); extern tree build_addr_func PROTO((tree)); extern tree build_call PROTO((tree, tree, tree)); extern tree build_method_call PROTO((tree, tree, tree, tree, int)); extern int null_ptr_cst_p PROTO((tree)); extern tree type_decays_to PROTO((tree)); extern tree build_user_type_conversion PROTO((tree, tree, int)); extern tree build_new_function_call PROTO((tree, tree)); extern tree build_new_op PROTO((enum tree_code, int, tree, tree, tree)); extern tree build_op_new_call PROTO((enum tree_code, tree, tree, int)); extern tree build_op_delete_call PROTO((enum tree_code, tree, tree, int, tree)); extern int can_convert PROTO((tree, tree)); extern int can_convert_arg PROTO((tree, tree, tree)); extern int enforce_access PROTO((tree, tree)); extern tree convert_default_arg PROTO((tree, tree, tree)); extern tree convert_arg_to_ellipsis PROTO((tree)); extern int is_properly_derived_from PROTO((tree, tree)); /* in class.c */ extern tree build_vbase_path PROTO((enum tree_code, tree, tree, tree, int)); extern tree build_vtbl_ref PROTO((tree, tree)); extern tree build_vfn_ref PROTO((tree *, tree, tree)); extern void add_method PROTO((tree, tree *, tree)); extern int currently_open_class PROTO((tree)); extern tree get_vfield_offset PROTO((tree)); extern void duplicate_tag_error PROTO((tree)); extern tree finish_struct PROTO((tree, tree, int)); extern void finish_struct_1 PROTO((tree, int)); extern int resolves_to_fixed_type_p PROTO((tree, int *)); extern void init_class_processing PROTO((void)); extern int is_empty_class PROTO((tree)); extern void pushclass PROTO((tree, int)); extern void popclass PROTO((void)); extern void push_nested_class PROTO((tree, int)); extern void pop_nested_class PROTO((void)); extern void push_lang_context PROTO((tree)); extern void pop_lang_context PROTO((void)); extern tree instantiate_type PROTO((tree, tree, int)); extern void print_class_statistics PROTO((void)); extern void push_cache_obstack PROTO((void)); extern unsigned HOST_WIDE_INT skip_rtti_stuff PROTO((tree *, tree)); extern void build_self_reference PROTO((void)); extern void warn_hidden PROTO((tree)); extern tree get_enclosing_class PROTO((tree)); int is_base_of_enclosing_class PROTO((tree, tree)); extern void unreverse_member_declarations PROTO((tree)); extern void invalidate_class_lookup_cache PROTO((void)); extern void maybe_note_name_used_in_class PROTO((tree, tree)); extern void note_name_declared_in_class PROTO((tree, tree)); /* in cvt.c */ extern tree convert_to_reference PROTO((tree, tree, int, int, tree)); extern tree convert_from_reference PROTO((tree)); extern tree convert_pointer_to_real PROTO((tree, tree)); extern tree convert_pointer_to PROTO((tree, tree)); extern tree ocp_convert PROTO((tree, tree, int, int)); extern tree cp_convert PROTO((tree, tree)); extern tree convert PROTO((tree, tree)); extern tree convert_force PROTO((tree, tree, int)); extern tree build_type_conversion PROTO((tree, tree, int)); extern tree build_expr_type_conversion PROTO((int, tree, int)); extern tree type_promotes_to PROTO((tree)); extern tree perform_qualification_conversions PROTO((tree, tree)); /* decl.c */ /* resume_binding_level */ extern void set_identifier_local_value PROTO((tree, tree)); extern int global_bindings_p PROTO((void)); extern int toplevel_bindings_p PROTO((void)); extern int namespace_bindings_p PROTO((void)); extern void keep_next_level PROTO((void)); extern int kept_level_p PROTO((void)); extern void declare_parm_level PROTO((void)); extern void declare_pseudo_global_level PROTO((void)); extern int pseudo_global_level_p PROTO((void)); extern void set_class_shadows PROTO((tree)); extern void pushlevel PROTO((int)); extern void note_level_for_for PROTO((void)); extern void pushlevel_temporary PROTO((int)); extern tree poplevel PROTO((int, int, int)); extern void resume_level PROTO((struct binding_level *)); extern void delete_block PROTO((tree)); extern void insert_block PROTO((tree)); extern void add_block_current_level PROTO((tree)); extern void set_block PROTO((tree)); extern void pushlevel_class PROTO((void)); extern void print_binding_stack PROTO((void)); extern void print_binding_level PROTO((struct binding_level *)); extern void push_namespace PROTO((tree)); extern void pop_namespace PROTO((void)); extern void maybe_push_to_top_level PROTO((int)); extern void push_to_top_level PROTO((void)); extern void pop_from_top_level PROTO((void)); extern tree identifier_type_value PROTO((tree)); extern void set_identifier_type_value PROTO((tree, tree)); extern void pop_everything PROTO((void)); extern void pushtag PROTO((tree, tree, int)); extern tree make_anon_name PROTO((void)); extern void clear_anon_tags PROTO((void)); extern int decls_match PROTO((tree, tree)); extern int duplicate_decls PROTO((tree, tree)); extern tree pushdecl PROTO((tree)); extern tree pushdecl_top_level PROTO((tree)); extern void pushdecl_class_level PROTO((tree)); #if 0 extern void pushdecl_nonclass_level PROTO((tree)); #endif extern tree pushdecl_namespace_level PROTO((tree)); extern tree push_using_decl PROTO((tree, tree)); extern tree push_using_directive PROTO((tree)); extern void push_class_level_binding PROTO((tree, tree)); extern tree implicitly_declare PROTO((tree)); extern tree lookup_label PROTO((tree)); extern tree shadow_label PROTO((tree)); extern tree define_label PROTO((char *, int, tree)); extern void push_switch PROTO((void)); extern void pop_switch PROTO((void)); extern void define_case_label PROTO((void)); extern tree getdecls PROTO((void)); extern tree gettags PROTO((void)); #if 0 extern void set_current_level_tags_transparency PROTO((int)); #endif extern tree binding_for_name PROTO((tree, tree)); extern tree namespace_binding PROTO((tree, tree)); extern void set_namespace_binding PROTO((tree, tree, tree)); extern tree lookup_namespace_name PROTO((tree, tree)); extern tree build_typename_type PROTO((tree, tree, tree, tree)); extern tree make_typename_type PROTO((tree, tree)); extern tree lookup_name_nonclass PROTO((tree)); extern tree lookup_function_nonclass PROTO((tree, tree)); extern tree lookup_name PROTO((tree, int)); extern tree lookup_name_current_level PROTO((tree)); extern tree lookup_type_current_level PROTO((tree)); extern tree lookup_name_namespace_only PROTO((tree)); extern void begin_only_namespace_names PROTO((void)); extern void end_only_namespace_names PROTO((void)); extern tree namespace_ancestor PROTO((tree, tree)); extern int lookup_using_namespace PROTO((tree,tree,tree,tree,int)); extern int qualified_lookup_using_namespace PROTO((tree,tree,tree,int)); extern tree auto_function PROTO((tree, tree, enum built_in_function)); extern void init_decl_processing PROTO((void)); extern int init_type_desc PROTO((void)); extern tree define_function PROTO((const char *, tree, enum built_in_function, void (*) (tree), const char *)); extern tree check_tag_decl PROTO((tree)); extern void shadow_tag PROTO((tree)); extern tree groktypename PROTO((tree)); extern tree start_decl PROTO((tree, tree, int, tree, tree)); extern void start_decl_1 PROTO((tree)); extern void cp_finish_decl PROTO((tree, tree, tree, int, int)); extern void finish_decl PROTO((tree, tree, tree)); extern void expand_static_init PROTO((tree, tree)); extern int complete_array_type PROTO((tree, tree, int)); extern tree build_ptrmemfunc_type PROTO((tree)); /* the grokdeclarator prototype is in decl.h */ extern int parmlist_is_exprlist PROTO((tree)); extern int copy_args_p PROTO((tree)); extern int grok_ctor_properties PROTO((tree, tree)); extern void grok_op_properties PROTO((tree, int, int)); extern tree xref_tag PROTO((tree, tree, int)); extern tree xref_tag_from_type PROTO((tree, tree, int)); extern void xref_basetypes PROTO((tree, tree, tree, tree)); extern tree start_enum PROTO((tree)); extern tree finish_enum PROTO((tree)); extern tree build_enumerator PROTO((tree, tree, tree)); extern int start_function PROTO((tree, tree, tree, int)); extern void expand_start_early_try_stmts PROTO((void)); extern void store_parm_decls PROTO((void)); extern void store_return_init PROTO((tree, tree)); extern void finish_function PROTO((int, int, int)); extern tree start_method PROTO((tree, tree, tree)); extern tree finish_method PROTO((tree)); extern void hack_incomplete_structures PROTO((tree)); extern tree maybe_build_cleanup_and_delete PROTO((tree)); extern tree maybe_build_cleanup PROTO((tree)); extern void cplus_expand_expr_stmt PROTO((tree)); extern void finish_stmt PROTO((void)); extern void push_cp_function_context PROTO((tree)); extern void pop_cp_function_context PROTO((tree)); extern int in_function_p PROTO((void)); extern void replace_defarg PROTO((tree, tree)); extern void print_other_binding_stack PROTO((struct binding_level *)); extern void revert_static_member_fn PROTO((tree*, tree*, tree*)); extern void fixup_anonymous_union PROTO((tree)); extern int check_static_variable_definition PROTO((tree, tree)); extern void push_local_binding PROTO((tree, tree, int)); extern int push_class_binding PROTO((tree, tree)); extern tree check_default_argument PROTO((tree, tree)); extern tree push_overloaded_decl PROTO((tree, int)); extern void clear_identifier_class_values PROTO((void)); extern void storetags PROTO((tree)); extern int vtable_decl_p PROTO((tree, void *)); extern int vtype_decl_p PROTO((tree, void *)); extern int sigtable_decl_p PROTO((tree, void *)); typedef int (*walk_globals_pred) PROTO((tree, void *)); typedef int (*walk_globals_fn) PROTO((tree *, void *)); extern int walk_globals PROTO((walk_globals_pred, walk_globals_fn, void *)); typedef int (*walk_namespaces_fn) PROTO((tree, void *)); extern int walk_namespaces PROTO((walk_namespaces_fn, void *)); extern int wrapup_globals_for_namespace PROTO((tree, void *)); /* in decl2.c */ extern int check_java_method PROTO((tree)); extern int lang_decode_option PROTO((int, char **)); extern tree grok_method_quals PROTO((tree, tree, tree)); extern void warn_if_unknown_interface PROTO((tree)); extern void grok_x_components PROTO((tree)); extern void maybe_retrofit_in_chrg PROTO((tree)); extern void maybe_make_one_only PROTO((tree)); extern void grokclassfn PROTO((tree, tree, enum overload_flags, tree)); extern tree grok_alignof PROTO((tree)); extern tree grok_array_decl PROTO((tree, tree)); extern tree delete_sanity PROTO((tree, tree, int, int)); extern tree check_classfn PROTO((tree, tree)); extern void check_member_template PROTO((tree)); extern tree grokfield PROTO((tree, tree, tree, tree, tree)); extern tree grokbitfield PROTO((tree, tree, tree)); extern tree groktypefield PROTO((tree, tree)); extern tree grokoptypename PROTO((tree, tree)); extern int copy_assignment_arg_p PROTO((tree, int)); extern void cplus_decl_attributes PROTO((tree, tree, tree)); extern tree constructor_name_full PROTO((tree)); extern tree constructor_name PROTO((tree)); extern void setup_vtbl_ptr PROTO((void)); extern void mark_inline_for_output PROTO((tree)); extern void clear_temp_name PROTO((void)); extern tree get_temp_name PROTO((tree, int)); extern tree get_temp_regvar PROTO((tree, tree)); extern void finish_anon_union PROTO((tree)); extern tree finish_table PROTO((tree, tree, tree, int)); extern void finish_builtin_type PROTO((tree, const char *, tree *, int, tree)); extern tree coerce_new_type PROTO((tree)); extern tree coerce_delete_type PROTO((tree)); extern void comdat_linkage PROTO((tree)); extern void import_export_class PROTO((tree)); extern void import_export_vtable PROTO((tree, tree, int)); extern void import_export_decl PROTO((tree)); extern tree build_cleanup PROTO((tree)); extern void finish_file PROTO((void)); extern tree reparse_absdcl_as_expr PROTO((tree, tree)); extern tree reparse_absdcl_as_casts PROTO((tree, tree)); extern tree build_expr_from_tree PROTO((tree)); extern tree reparse_decl_as_expr PROTO((tree, tree)); extern tree finish_decl_parsing PROTO((tree)); extern tree check_cp_case_value PROTO((tree)); extern void set_decl_namespace PROTO((tree, tree, int)); extern tree current_decl_namespace PROTO((void)); extern void push_decl_namespace PROTO((tree)); extern void pop_decl_namespace PROTO((void)); extern void push_scope PROTO((tree)); extern void pop_scope PROTO((tree)); extern void do_namespace_alias PROTO((tree, tree)); extern void do_toplevel_using_decl PROTO((tree)); extern void do_local_using_decl PROTO((tree)); extern tree do_class_using_decl PROTO((tree)); extern void do_using_directive PROTO((tree)); extern void check_default_args PROTO((tree)); extern void mark_used PROTO((tree)); extern tree handle_class_head PROTO((tree, tree, tree)); extern tree lookup_arg_dependent PROTO((tree, tree, tree)); extern void finish_static_data_member_decl PROTO((tree, tree, tree, int, int)); /* in errfn.c */ /* The cp_* functions aren't suitable for ATTRIBUTE_PRINTF. */ extern void cp_error PVPROTO((const char *, ...)); extern void cp_error_at PVPROTO((const char *, ...)); extern void cp_warning PVPROTO((const char *, ...)); extern void cp_warning_at PVPROTO((const char *, ...)); extern void cp_pedwarn PVPROTO((const char *, ...)); extern void cp_pedwarn_at PVPROTO((const char *, ...)); extern void cp_compiler_error PVPROTO((const char *, ...)); extern void cp_sprintf PVPROTO((const char *, ...)); extern void cp_deprecated PROTO((const char*)); /* in error.c */ extern void init_error PROTO((void)); extern char *fndecl_as_string PROTO((tree, int)); extern char *type_as_string PROTO((tree, int)); extern char *type_as_string_real PROTO((tree, int, int)); extern char *args_as_string PROTO((tree, int)); extern char *decl_as_string PROTO((tree, int)); extern char *expr_as_string PROTO((tree, int)); extern char *code_as_string PROTO((enum tree_code, int)); extern char *language_as_string PROTO((enum languages, int)); extern char *parm_as_string PROTO((int, int)); extern char *op_as_string PROTO((enum tree_code, int)); extern char *assop_as_string PROTO((enum tree_code, int)); extern char *cv_as_string PROTO((tree, int)); extern char *lang_decl_name PROTO((tree, int)); extern char *cp_file_of PROTO((tree)); extern int cp_line_of PROTO((tree)); /* in except.c */ extern void init_exception_processing PROTO((void)); extern void expand_start_catch_block PROTO((tree, tree)); extern void expand_end_catch_block PROTO((void)); extern void expand_builtin_throw PROTO((void)); extern void expand_start_eh_spec PROTO((void)); extern void expand_exception_blocks PROTO((void)); extern tree start_anon_func PROTO((void)); extern void end_anon_func PROTO((void)); extern void expand_throw PROTO((tree)); extern tree build_throw PROTO((tree)); extern void mark_all_runtime_matches PROTO((void)); /* in expr.c */ extern void init_cplus_expand PROTO((void)); extern void fixup_result_decl PROTO((tree, struct rtx_def *)); extern int extract_init PROTO((tree, tree)); extern void do_case PROTO((tree, tree)); /* friend.c */ extern int is_friend PROTO((tree, tree)); extern void make_friend_class PROTO((tree, tree)); extern void add_friend PROTO((tree, tree)); extern void add_friends PROTO((tree, tree, tree)); extern tree do_friend PROTO((tree, tree, tree, tree, tree, enum overload_flags, tree, int)); /* in init.c */ extern void init_init_processing PROTO((void)); extern void expand_direct_vtbls_init PROTO((tree, tree, int, int, tree)); extern void emit_base_init PROTO((tree, int)); extern void check_base_init PROTO((tree)); extern void expand_member_init PROTO((tree, tree, tree)); extern void expand_aggr_init PROTO((tree, tree, int)); extern int is_aggr_typedef PROTO((tree, int)); extern int is_aggr_type PROTO((tree, int)); extern tree get_aggr_from_typedef PROTO((tree, int)); extern tree get_type_value PROTO((tree)); extern tree build_member_call PROTO((tree, tree, tree)); extern tree build_offset_ref PROTO((tree, tree)); extern tree resolve_offset_ref PROTO((tree)); extern tree decl_constant_value PROTO((tree)); extern tree build_new PROTO((tree, tree, tree, int)); extern tree build_new_1 PROTO((tree)); extern tree expand_vec_init PROTO((tree, tree, tree, tree, int)); extern tree build_x_delete PROTO((tree, int, tree)); extern tree build_delete PROTO((tree, tree, tree, int, int)); extern tree build_vbase_delete PROTO((tree, tree)); extern tree build_vec_delete PROTO((tree, tree, tree, tree, int)); +extern tree build_base_dtor_call PROTO((tree, tree, tree)); +extern void init_vlist PROTO((tree)); /* in input.c */ /* in lex.c */ extern char *file_name_nondirectory PROTO((const char *)); extern tree make_pointer_declarator PROTO((tree, tree)); extern tree make_reference_declarator PROTO((tree, tree)); extern tree make_call_declarator PROTO((tree, tree, tree, tree)); extern void set_quals_and_spec PROTO((tree, tree, tree)); extern char *operator_name_string PROTO((tree)); extern void lang_init PROTO((void)); extern void lang_finish PROTO((void)); #if 0 extern void reinit_lang_specific PROTO((void)); #endif extern void reinit_parse_for_function PROTO((void)); extern void print_parse_statistics PROTO((void)); extern void extract_interface_info PROTO((void)); extern void do_pending_inlines PROTO((void)); extern void process_next_inline PROTO((tree)); extern struct pending_input *save_pending_input PROTO((void)); extern void restore_pending_input PROTO((struct pending_input *)); extern void yyungetc PROTO((int, int)); extern void reinit_parse_for_method PROTO((int, tree)); extern void reinit_parse_for_block PROTO((int, struct obstack *)); extern tree cons_up_default_function PROTO((tree, tree, int)); extern void check_for_missing_semicolon PROTO((tree)); extern void note_got_semicolon PROTO((tree)); extern void note_list_got_semicolon PROTO((tree)); extern void do_pending_lang_change PROTO((void)); extern int identifier_type PROTO((tree)); extern void see_typename PROTO((void)); extern tree do_identifier PROTO((tree, int, tree)); extern tree do_scoped_id PROTO((tree, int)); extern tree identifier_typedecl_value PROTO((tree)); extern int real_yylex PROTO((void)); extern int is_rid PROTO((tree)); extern tree build_lang_decl PROTO((enum tree_code, tree, tree)); extern void retrofit_lang_decl PROTO((tree)); extern tree build_lang_field_decl PROTO((enum tree_code, tree, tree)); extern void copy_lang_decl PROTO((tree)); extern tree make_lang_type PROTO((enum tree_code)); extern void dump_time_statistics PROTO((void)); extern void compiler_error PVPROTO((const char *, ...)) ATTRIBUTE_PRINTF_1; extern void yyerror PROTO((const char *)); extern void clear_inline_text_obstack PROTO((void)); extern void maybe_snarf_defarg PROTO((void)); extern tree snarf_defarg PROTO((void)); extern void add_defarg_fn PROTO((tree)); extern void do_pending_defargs PROTO((void)); extern int identifier_type PROTO((tree)); extern void yyhook PROTO((int)); extern int cp_type_qual_from_rid PROTO((tree)); /* in method.c */ extern void init_method PROTO((void)); extern void do_inline_function_hair PROTO((tree, tree)); extern char *build_overload_name PROTO((tree, int, int)); extern tree build_static_name PROTO((tree, tree)); extern tree build_decl_overload PROTO((tree, tree, int)); extern tree build_decl_overload_real PROTO((tree, tree, tree, tree, tree, int)); extern void set_mangled_name_for_decl PROTO((tree)); extern tree build_typename_overload PROTO((tree)); extern tree build_overload_with_type PROTO((tree, tree)); -extern tree build_destructor_name PROTO((tree)); +extern tree build_destructor_name PROTO((tree, int)); extern tree build_opfncall PROTO((enum tree_code, int, tree, tree, tree)); extern tree hack_identifier PROTO((tree, tree)); extern tree make_thunk PROTO((tree, int)); extern void emit_thunk PROTO((tree)); extern void synthesize_method PROTO((tree)); extern tree get_id_2 PROTO((char *, tree)); +extern tree get_vlist_vtable_id PROTO((tree, tree)); + /* in pt.c */ extern void check_template_shadow PROTO ((tree)); extern tree innermost_args PROTO ((tree)); extern tree tsubst PROTO ((tree, tree, int, tree)); extern tree tsubst_expr PROTO ((tree, tree, int, tree)); extern tree tsubst_copy PROTO ((tree, tree, int, tree)); extern void maybe_begin_member_template_processing PROTO((tree)); extern void maybe_end_member_template_processing PROTO((void)); extern tree finish_member_template_decl PROTO((tree)); extern void begin_template_parm_list PROTO((void)); extern void begin_specialization PROTO((void)); extern void reset_specialization PROTO((void)); extern void end_specialization PROTO((void)); extern void begin_explicit_instantiation PROTO((void)); extern void end_explicit_instantiation PROTO((void)); extern tree check_explicit_specialization PROTO((tree, tree, int, int)); extern tree process_template_parm PROTO((tree, tree)); extern tree end_template_parm_list PROTO((tree)); extern void end_template_decl PROTO((void)); extern tree current_template_args PROTO((void)); extern tree push_template_decl PROTO((tree)); extern tree push_template_decl_real PROTO((tree, int)); extern void redeclare_class_template PROTO((tree, tree)); extern tree lookup_template_class PROTO((tree, tree, tree, tree, int)); extern tree lookup_template_function PROTO((tree, tree)); extern int uses_template_parms PROTO((tree)); extern tree instantiate_class_template PROTO((tree)); extern tree instantiate_template PROTO((tree, tree)); extern void overload_template_name PROTO((tree)); extern int fn_type_unification PROTO((tree, tree, tree, tree, tree, unification_kind_t)); struct tinst_level *tinst_for_decl PROTO((void)); extern void mark_decl_instantiated PROTO((tree, int)); extern int more_specialized PROTO((tree, tree, tree)); extern void mark_class_instantiated PROTO((tree, int)); extern void do_decl_instantiation PROTO((tree, tree, tree)); extern void do_type_instantiation PROTO((tree, tree)); extern tree instantiate_decl PROTO((tree)); extern tree do_poplevel PROTO((void)); extern tree get_bindings PROTO((tree, tree, tree)); /* CONT ... */ extern void add_tree PROTO((tree)); extern void begin_tree PROTO((void)); extern void end_tree PROTO((void)); extern void add_maybe_template PROTO((tree, tree)); extern void pop_tinst_level PROTO((void)); extern int more_specialized_class PROTO((tree, tree)); extern void do_pushlevel PROTO((void)); extern int is_member_template PROTO((tree)); extern int template_parms_equal PROTO((tree, tree)); extern int comp_template_parms PROTO((tree, tree)); extern int template_class_depth PROTO((tree)); extern int is_specialization_of PROTO((tree, tree)); extern int comp_template_args PROTO((tree, tree)); extern void maybe_process_partial_specialization PROTO((tree)); extern void maybe_check_template_type PROTO((tree)); extern tree most_specialized_instantiation PROTO((tree, tree)); extern void print_candidates PROTO((tree)); extern int instantiate_pending_templates PROTO((void)); extern int processing_specialization; extern int processing_explicit_instantiation; extern int processing_template_parmlist; /* in repo.c */ extern void repo_template_used PROTO((tree)); extern void repo_template_instantiated PROTO((tree, int)); extern void init_repo PROTO((const char *)); extern void finish_repo PROTO((void)); /* in rtti.c */ extern void init_rtti_processing PROTO((void)); extern tree get_tinfo_fn_dynamic PROTO((tree)); extern tree build_typeid PROTO((tree)); extern tree build_x_typeid PROTO((tree)); extern tree get_tinfo_fn PROTO((tree)); +extern tree get_tinfo_fn_unused PROTO((tree)); extern tree get_typeid PROTO((tree)); extern tree get_typeid_1 PROTO((tree)); extern tree build_dynamic_cast PROTO((tree, tree)); extern void synthesize_tinfo_fn PROTO((tree)); /* in search.c */ extern int types_overlap_p PROTO((tree, tree)); extern tree get_vbase PROTO((tree, tree)); extern tree get_binfo PROTO((tree, tree, int)); extern int get_base_distance PROTO((tree, tree, int, tree *)); extern int accessible_p PROTO((tree, tree)); extern tree lookup_field PROTO((tree, tree, int, int)); extern int lookup_fnfields_1 PROTO((tree, tree)); extern tree lookup_fnfields PROTO((tree, tree, int)); extern tree lookup_member PROTO((tree, tree, int, int)); extern tree lookup_nested_tag PROTO((tree, tree)); extern tree get_matching_virtual PROTO((tree, tree, int)); extern tree get_abstract_virtuals PROTO((tree)); extern tree init_vbase_pointers PROTO((tree, tree)); extern void expand_indirect_vtbls_init PROTO((tree, tree, tree)); extern void clear_search_slots PROTO((tree)); extern tree get_vbase_types PROTO((tree)); extern void note_debug_info_needed PROTO((tree)); extern void push_class_decls PROTO((tree)); extern void pop_class_decls PROTO((void)); extern void unuse_fields PROTO((tree)); extern void print_search_statistics PROTO((void)); extern void init_search_processing PROTO((void)); extern void reinit_search_statistics PROTO((void)); extern tree current_scope PROTO((void)); extern tree lookup_conversions PROTO((tree)); extern tree binfo_for_vtable PROTO((tree)); extern tree dfs_walk PROTO((tree, tree (*)(tree, void *), tree (*) (tree, void *), void *)); extern tree dfs_unmark PROTO((tree, void *)); extern tree markedp PROTO((tree, void *)); /* in semantics.c */ extern void finish_expr_stmt PROTO((tree)); extern tree begin_if_stmt PROTO((void)); extern void finish_if_stmt_cond PROTO((tree, tree)); extern tree finish_then_clause PROTO((tree)); extern void begin_else_clause PROTO((void)); extern void finish_else_clause PROTO((tree)); extern void finish_if_stmt PROTO((void)); extern tree begin_while_stmt PROTO((void)); extern void finish_while_stmt_cond PROTO((tree, tree)); extern void finish_while_stmt PROTO((tree)); extern tree begin_do_stmt PROTO((void)); extern void finish_do_body PROTO((tree)); extern void finish_do_stmt PROTO((tree, tree)); extern void finish_return_stmt PROTO((tree)); extern tree begin_for_stmt PROTO((void)); extern void finish_for_init_stmt PROTO((tree)); extern void finish_for_cond PROTO((tree, tree)); extern void finish_for_expr PROTO((tree, tree)); extern void finish_for_stmt PROTO((tree, tree)); extern void finish_break_stmt PROTO((void)); extern void finish_continue_stmt PROTO((void)); extern void begin_switch_stmt PROTO((void)); extern tree finish_switch_cond PROTO((tree)); extern void finish_switch_stmt PROTO((tree, tree)); extern void finish_case_label PROTO((tree, tree)); extern void finish_goto_stmt PROTO((tree)); extern tree begin_try_block PROTO((void)); extern void finish_try_block PROTO((tree)); extern void finish_handler_sequence PROTO((tree)); extern tree begin_handler PROTO((void)); extern void finish_handler_parms PROTO((tree)); extern void finish_handler PROTO((tree)); extern tree begin_compound_stmt PROTO((int)); extern tree finish_compound_stmt PROTO((int, tree)); extern void finish_asm_stmt PROTO((tree, tree, tree, tree, tree)); extern tree finish_parenthesized_expr PROTO((tree)); extern tree begin_stmt_expr PROTO((void)); extern tree finish_stmt_expr PROTO((tree, tree)); extern tree finish_call_expr PROTO((tree, tree, int)); extern tree finish_increment_expr PROTO((tree, enum tree_code)); extern tree finish_this_expr PROTO((void)); extern tree finish_object_call_expr PROTO((tree, tree, tree)); extern tree finish_qualified_object_call_expr PROTO((tree, tree, tree)); extern tree finish_pseudo_destructor_call_expr PROTO((tree, tree, tree)); extern tree finish_qualified_call_expr PROTO ((tree, tree)); extern tree finish_label_address_expr PROTO((tree)); extern tree finish_unary_op_expr PROTO((enum tree_code, tree)); extern tree finish_id_expr PROTO((tree)); extern int begin_new_placement PROTO((void)); extern tree finish_new_placement PROTO((tree, int)); extern int begin_function_definition PROTO((tree, tree)); extern tree begin_constructor_declarator PROTO((tree, tree)); extern tree finish_declarator PROTO((tree, tree, tree, tree, int)); extern void finish_translation_unit PROTO((void)); extern tree finish_template_type_parm PROTO((tree, tree)); extern tree finish_template_template_parm PROTO((tree, tree)); extern tree finish_parmlist PROTO((tree, int)); extern tree begin_class_definition PROTO((tree)); extern tree finish_class_definition PROTO((tree, tree, int, int)); extern void finish_default_args PROTO((void)); extern void begin_inline_definitions PROTO((void)); extern void finish_inline_definitions PROTO((void)); extern tree finish_member_class_template PROTO((tree)); extern void finish_template_decl PROTO((tree)); extern tree finish_template_type PROTO((tree, tree, int)); extern void enter_scope_of PROTO((tree)); extern tree finish_base_specifier PROTO((tree, tree, int)); extern void finish_member_declaration PROTO((tree)); extern void check_multiple_declarators PROTO((void)); extern tree finish_typeof PROTO((tree)); /* in sig.c */ extern tree build_signature_pointer_type PROTO((tree)); extern tree build_signature_reference_type PROTO((tree)); extern tree build_signature_pointer_constructor PROTO((tree, tree)); extern tree build_signature_method_call PROTO((tree, tree)); extern tree build_optr_ref PROTO((tree)); extern void append_signature_fields PROTO((tree)); /* in spew.c */ extern void init_spew PROTO((void)); extern int peekyylex PROTO((void)); extern int yylex PROTO((void)); extern tree arbitrate_lookup PROTO((tree, tree, tree)); /* in tree.c */ extern int pod_type_p PROTO((tree)); extern void unshare_base_binfos PROTO((tree)); extern int member_p PROTO((tree)); extern int real_lvalue_p PROTO((tree)); extern tree build_min PVPROTO((enum tree_code, tree, ...)); extern tree build_min_nt PVPROTO((enum tree_code, ...)); extern tree min_tree_cons PROTO((tree, tree, tree)); extern int lvalue_p PROTO((tree)); extern int lvalue_or_else PROTO((tree, const char *)); extern tree build_cplus_new PROTO((tree, tree)); extern tree get_target_expr PROTO((tree)); extern tree break_out_cleanups PROTO((tree)); extern tree break_out_calls PROTO((tree)); extern tree build_cplus_method_type PROTO((tree, tree, tree)); extern tree build_cplus_staticfn_type PROTO((tree, tree, tree)); extern tree build_cplus_array_type PROTO((tree, tree)); extern int layout_basetypes PROTO((tree, int)); extern tree build_vbase_pointer_fields PROTO((tree)); extern tree build_base_fields PROTO((tree)); extern tree hash_tree_cons PROTO((tree, tree, tree)); extern tree hash_tree_chain PROTO((tree, tree)); extern tree hash_chainon PROTO((tree, tree)); extern tree make_binfo PROTO((tree, tree, tree, tree)); extern tree binfo_value PROTO((tree, tree)); extern tree reverse_path PROTO((tree)); extern int count_functions PROTO((tree)); extern int is_overloaded_fn PROTO((tree)); extern tree get_first_fn PROTO((tree)); extern tree binding_init PROTO((struct tree_binding*)); extern int bound_pmf_p PROTO((tree)); extern tree ovl_cons PROTO((tree, tree)); extern tree scratch_ovl_cons PROTO((tree, tree)); extern int ovl_member PROTO((tree, tree)); extern tree build_overload PROTO((tree, tree)); extern tree fnaddr_from_vtable_entry PROTO((tree)); extern tree function_arg_chain PROTO((tree)); extern int promotes_to_aggr_type PROTO((tree, enum tree_code)); extern int is_aggr_type_2 PROTO((tree, tree)); extern char *lang_printable_name PROTO((tree, int)); extern tree build_exception_variant PROTO((tree, tree)); extern tree copy_template_template_parm PROTO((tree)); extern tree copy_to_permanent PROTO((tree)); extern tree permanent_p PROTO((tree)); extern void print_lang_statistics PROTO((void)); extern void __eprintf PROTO((const char *, const char *, unsigned, const char *)); extern tree array_type_nelts_total PROTO((tree)); extern tree array_type_nelts_top PROTO((tree)); extern tree break_out_target_exprs PROTO((tree)); extern tree get_type_decl PROTO((tree)); extern tree vec_binfo_member PROTO((tree, tree)); extern tree hack_decl_function_context PROTO((tree)); extern tree decl_namespace_context PROTO((tree)); extern tree lvalue_type PROTO((tree)); extern tree error_type PROTO((tree)); extern tree make_temp_vec PROTO((int)); extern tree build_ptr_wrapper PROTO((void *)); extern tree build_expr_ptr_wrapper PROTO((void *)); extern tree build_int_wrapper PROTO((int)); extern tree build_srcloc_here PROTO((void)); extern int varargs_function_p PROTO((tree)); extern int really_overloaded_fn PROTO((tree)); extern int cp_tree_equal PROTO((tree, tree)); extern int can_free PROTO((struct obstack *, tree)); extern tree mapcar PROTO((tree, tree (*) (tree))); extern tree no_linkage_check PROTO((tree)); extern void debug_binfo PROTO((tree)); extern void push_expression_obstack PROTO((void)); extern tree build_dummy_object PROTO((tree)); extern tree maybe_dummy_object PROTO((tree, tree *)); extern int is_dummy_object PROTO((tree)); extern tree search_tree PROTO((tree, tree (*)(tree))); extern int cp_valid_lang_attribute PROTO((tree, tree, tree, tree)); extern tree make_ptrmem_cst PROTO((tree, tree)); #define scratchalloc expralloc #define scratch_tree_cons expr_tree_cons #define build_scratch_list build_expr_list #define make_scratch_vec make_temp_vec #define push_scratch_obstack push_expression_obstack /* in typeck.c */ extern int string_conv_p PROTO((tree, tree, int)); extern tree condition_conversion PROTO((tree)); extern tree target_type PROTO((tree)); extern tree require_complete_type PROTO((tree)); extern tree require_complete_type_in_void PROTO((tree)); extern tree complete_type PROTO((tree)); extern tree complete_type_or_else PROTO((tree, tree)); extern int type_unknown_p PROTO((tree)); extern int fntype_p PROTO((tree)); extern tree commonparms PROTO((tree, tree)); extern tree original_type PROTO((tree)); extern tree common_type PROTO((tree, tree)); extern int compexcepttypes PROTO((tree, tree)); extern int comptypes PROTO((tree, tree, int)); extern int comp_target_types PROTO((tree, tree, int)); extern int compparms PROTO((tree, tree)); extern int comp_target_types PROTO((tree, tree, int)); extern int comp_cv_qualification PROTO((tree, tree)); extern int comp_cv_qual_signature PROTO((tree, tree)); extern int self_promoting_args_p PROTO((tree)); extern tree unsigned_type PROTO((tree)); extern tree signed_type PROTO((tree)); extern tree signed_or_unsigned_type PROTO((int, tree)); extern tree expr_sizeof PROTO((tree)); extern tree c_sizeof PROTO((tree)); extern tree c_sizeof_nowarn PROTO((tree)); extern tree c_alignof PROTO((tree)); extern tree inline_conversion PROTO((tree)); extern tree decay_conversion PROTO((tree)); extern tree default_conversion PROTO((tree)); extern tree build_object_ref PROTO((tree, tree, tree)); extern tree build_component_ref_1 PROTO((tree, tree, int)); extern tree build_component_ref PROTO((tree, tree, tree, int)); extern tree build_x_component_ref PROTO((tree, tree, tree, int)); extern tree build_x_indirect_ref PROTO((tree, const char *)); extern tree build_indirect_ref PROTO((tree, const char *)); extern tree build_array_ref PROTO((tree, tree)); extern tree build_x_function_call PROTO((tree, tree, tree)); extern tree get_member_function_from_ptrfunc PROTO((tree *, tree)); extern tree build_function_call_real PROTO((tree, tree, int, int)); extern tree build_function_call PROTO((tree, tree)); extern tree build_function_call_maybe PROTO((tree, tree)); extern tree convert_arguments PROTO((tree, tree, tree, int)); extern tree build_x_binary_op PROTO((enum tree_code, tree, tree)); extern tree build_binary_op PROTO((enum tree_code, tree, tree)); extern tree build_binary_op_nodefault PROTO((enum tree_code, tree, tree, enum tree_code)); extern tree build_x_unary_op PROTO((enum tree_code, tree)); extern tree build_unary_op PROTO((enum tree_code, tree, int)); extern tree unary_complex_lvalue PROTO((enum tree_code, tree)); extern int mark_addressable PROTO((tree)); extern tree build_x_conditional_expr PROTO((tree, tree, tree)); extern tree build_conditional_expr PROTO((tree, tree, tree)); extern tree build_x_compound_expr PROTO((tree)); extern tree build_compound_expr PROTO((tree)); extern tree build_static_cast PROTO((tree, tree)); extern tree build_reinterpret_cast PROTO((tree, tree)); extern tree build_const_cast PROTO((tree, tree)); extern tree build_c_cast PROTO((tree, tree)); extern tree build_x_modify_expr PROTO((tree, enum tree_code, tree)); extern tree build_modify_expr PROTO((tree, enum tree_code, tree)); extern tree convert_for_initialization PROTO((tree, tree, tree, int, const char *, tree, int)); extern void c_expand_asm_operands PROTO((tree, tree, tree, tree, int, char *, int)); extern void c_expand_return PROTO((tree)); extern tree c_expand_start_case PROTO((tree)); extern int comp_ptr_ttypes PROTO((tree, tree)); extern int ptr_reasonably_similar PROTO((tree, tree)); extern tree build_ptrmemfunc PROTO((tree, tree, int)); extern int cp_type_quals PROTO((tree)); extern int cp_has_mutable_p PROTO((tree)); extern int at_least_as_qualified_p PROTO((tree, tree)); extern int more_qualified_p PROTO((tree, tree)); extern tree build_ptrmemfunc1 PROTO((tree, tree, tree, tree, tree)); extern void expand_ptrmemfunc_cst PROTO((tree, tree *, tree *, tree *, tree *)); extern tree delta2_from_ptrmemfunc PROTO((tree)); extern tree pfn_from_ptrmemfunc PROTO((tree)); /* in typeck2.c */ extern tree error_not_base_type PROTO((tree, tree)); extern tree binfo_or_else PROTO((tree, tree)); extern void readonly_error PROTO((tree, const char *, int)); extern void abstract_virtuals_error PROTO((tree, tree)); extern void signature_error PROTO((tree, tree)); extern void incomplete_type_error PROTO((tree, tree)); extern void my_friendly_abort PROTO((int)) ATTRIBUTE_NORETURN; extern void my_friendly_assert PROTO((int, int)); extern tree store_init_value PROTO((tree, tree)); extern tree digest_init PROTO((tree, tree, tree *)); extern tree build_scoped_ref PROTO((tree, tree)); extern tree build_x_arrow PROTO((tree)); extern tree build_m_component_ref PROTO((tree, tree)); extern tree build_functional_cast PROTO((tree, tree)); extern char *enum_name_string PROTO((tree, tree)); extern void report_case_error PROTO((int, tree, tree, tree)); extern void check_for_new_type PROTO((const char *, flagged_type_tree)); extern tree initializer_constant_valid_p PROTO((tree, tree)); /* in xref.c */ extern void GNU_xref_begin PROTO((const char *)); extern void GNU_xref_end PROTO((int)); extern void GNU_xref_file PROTO((const char *)); extern void GNU_xref_start_scope PROTO((HOST_WIDE_INT)); extern void GNU_xref_end_scope PROTO((HOST_WIDE_INT, HOST_WIDE_INT, int, int)); extern void GNU_xref_ref PROTO((tree, const char *)); extern void GNU_xref_decl PROTO((tree, tree)); extern void GNU_xref_call PROTO((tree, const char *)); extern void GNU_xref_function PROTO((tree, tree)); extern void GNU_xref_assign PROTO((tree)); extern void GNU_xref_hier PROTO((tree, tree, int, int, int)); extern void GNU_xref_member PROTO((tree, tree)); /* -- end of C++ */ #endif /* not _CP_TREE_H */ Index: vendor/gcc/dist/contrib/gcc/cp/decl.c =================================================================== --- vendor/gcc/dist/contrib/gcc/cp/decl.c (revision 60966) +++ vendor/gcc/dist/contrib/gcc/cp/decl.c (revision 60967) @@ -1,15041 +1,15160 @@ /* Process declarations and variables for C compiler. Copyright (C) 1988, 92-98, 1999 Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@cygnus.com) 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. */ /* Process declarations and symbol lookup for C front end. Also constructs types; the standard scalar types at initialization, and structure, union, array and enum types when they are declared. */ /* ??? not all decl nodes are given the most useful possible line numbers. For example, the CONST_DECLs for enum values. */ #include "config.h" #include "system.h" #include "tree.h" #include "rtl.h" #include "flags.h" #include "cp-tree.h" #include "decl.h" #include "lex.h" #include #include "obstack.h" #include "defaults.h" #include "output.h" #include "except.h" #include "toplev.h" #include "../hash.h" #define obstack_chunk_alloc xmalloc #define obstack_chunk_free free extern tree builtin_return_address_fndecl; extern struct obstack permanent_obstack; extern struct obstack* saveable_obstack; extern int current_class_depth; extern tree static_ctors, static_dtors; extern int static_labelno; extern tree current_namespace; extern tree global_namespace; extern void (*print_error_function) PROTO((char *)); extern int (*valid_lang_attribute) PROTO ((tree, tree, tree, tree)); /* Obstack used for remembering local class declarations (like enums and static (const) members. */ #include "stack.h" struct obstack decl_obstack; static struct stack_level *decl_stack; #ifndef CHAR_TYPE_SIZE #define CHAR_TYPE_SIZE BITS_PER_UNIT #endif #ifndef SHORT_TYPE_SIZE #define SHORT_TYPE_SIZE (BITS_PER_UNIT * MIN ((UNITS_PER_WORD + 1) / 2, 2)) #endif #ifndef INT_TYPE_SIZE #define INT_TYPE_SIZE BITS_PER_WORD #endif #ifndef LONG_TYPE_SIZE #define LONG_TYPE_SIZE BITS_PER_WORD #endif #ifndef LONG_LONG_TYPE_SIZE #define LONG_LONG_TYPE_SIZE (BITS_PER_WORD * 2) #endif #ifndef WCHAR_UNSIGNED #define WCHAR_UNSIGNED 0 #endif #ifndef FLOAT_TYPE_SIZE #define FLOAT_TYPE_SIZE BITS_PER_WORD #endif #ifndef DOUBLE_TYPE_SIZE #define DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2) #endif #ifndef LONG_DOUBLE_TYPE_SIZE #define LONG_DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2) #endif #ifndef BOOL_TYPE_SIZE #ifdef SLOW_BYTE_ACCESS #define BOOL_TYPE_SIZE ((SLOW_BYTE_ACCESS) ? (POINTER_SIZE) : (CHAR_TYPE_SIZE)) #else #define BOOL_TYPE_SIZE CHAR_TYPE_SIZE #endif #endif /* We let tm.h override the types used here, to handle trivial differences such as the choice of unsigned int or long unsigned int for size_t. When machines start needing nontrivial differences in the size type, it would be best to do something here to figure out automatically from other information what type to use. */ #ifndef SIZE_TYPE #define SIZE_TYPE "long unsigned int" #endif #ifndef PTRDIFF_TYPE #define PTRDIFF_TYPE "long int" #endif #ifndef WCHAR_TYPE #define WCHAR_TYPE "int" #endif static tree grokparms PROTO((tree, int)); static tree lookup_nested_type PROTO((tree, tree)); static const char *redeclaration_error_message PROTO((tree, tree)); static struct stack_level *push_decl_level PROTO((struct stack_level *, struct obstack *)); static void push_binding_level PROTO((struct binding_level *, int, int)); static void pop_binding_level PROTO((void)); static void suspend_binding_level PROTO((void)); static void resume_binding_level PROTO((struct binding_level *)); static struct binding_level *make_binding_level PROTO((void)); static void declare_namespace_level PROTO((void)); static void signal_catch PROTO((int)) ATTRIBUTE_NORETURN; static void storedecls PROTO((tree)); static void require_complete_types_for_parms PROTO((tree)); static void push_overloaded_decl_1 PROTO((tree)); static int ambi_op_p PROTO((tree)); static int unary_op_p PROTO((tree)); static tree store_bindings PROTO((tree, tree)); static tree lookup_tag_reverse PROTO((tree, tree)); static tree obscure_complex_init PROTO((tree, tree)); static tree maybe_build_cleanup_1 PROTO((tree, tree)); static tree lookup_name_real PROTO((tree, int, int, int)); static void warn_extern_redeclared_static PROTO((tree, tree)); static void grok_reference_init PROTO((tree, tree, tree)); static tree grokfndecl PROTO((tree, tree, tree, tree, int, enum overload_flags, tree, tree, int, int, int, int, int, int, tree)); static tree grokvardecl PROTO((tree, tree, RID_BIT_TYPE *, int, int, tree)); static tree lookup_tag PROTO((enum tree_code, tree, struct binding_level *, int)); static void set_identifier_type_value_with_scope PROTO((tree, tree, struct binding_level *)); static void record_builtin_type PROTO((enum rid, const char *, tree)); static void record_unknown_type PROTO((tree, const char *)); static int member_function_or_else PROTO((tree, tree, const char *)); static void bad_specifiers PROTO((tree, const char *, int, int, int, int, int)); static void lang_print_error_function PROTO((char *)); static tree maybe_process_template_type_declaration PROTO((tree, int, struct binding_level*)); static void check_for_uninitialized_const_var PROTO((tree)); static unsigned long typename_hash PROTO((hash_table_key)); static boolean typename_compare PROTO((hash_table_key, hash_table_key)); static void push_binding PROTO((tree, tree, struct binding_level*)); static int add_binding PROTO((tree, tree)); static void pop_binding PROTO((tree, tree)); static tree local_variable_p PROTO((tree)); static tree find_binding PROTO((tree, tree)); static tree select_decl PROTO((tree, int)); static tree unqualified_namespace_lookup PROTO((tree, int)); static int lookup_flags PROTO((int, int)); static tree qualify_lookup PROTO((tree, int)); static tree record_builtin_java_type PROTO((const char *, int)); static const char *tag_name PROTO((enum tag_types code)); static void find_class_binding_level PROTO((void)); static struct binding_level *innermost_nonclass_level PROTO((void)); +static void finish_dtor PROTO((void)); +static void finish_ctor PROTO((int)); static tree poplevel_class PROTO((void)); static void warn_about_implicit_typename_lookup PROTO((tree, tree)); static int walk_namespaces_r PROTO((tree, walk_namespaces_fn, void *)); static int walk_globals_r PROTO((tree, void *)); #if defined (DEBUG_CP_BINDING_LEVELS) static void indent PROTO((void)); #endif /* A node which has tree code ERROR_MARK, and whose type is itself. All erroneous expressions are replaced with this node. All functions that accept nodes as arguments should avoid generating error messages if this node is one of the arguments, since it is undesirable to get multiple error messages from one error in the input. */ tree error_mark_node; /* Erroneous argument lists can use this *IFF* they do not modify it. */ tree error_mark_list; /* INTEGER_TYPE and REAL_TYPE nodes for the standard data types */ tree short_integer_type_node; tree integer_type_node; tree long_integer_type_node; tree long_long_integer_type_node; tree short_unsigned_type_node; tree unsigned_type_node; tree long_unsigned_type_node; tree long_long_unsigned_type_node; tree ptrdiff_type_node; tree unsigned_char_type_node; tree signed_char_type_node; tree char_type_node; tree wchar_type_node; tree signed_wchar_type_node; tree unsigned_wchar_type_node; tree wchar_decl_node; tree float_type_node; tree double_type_node; tree long_double_type_node; tree complex_integer_type_node; tree complex_float_type_node; tree complex_double_type_node; tree complex_long_double_type_node; tree intQI_type_node; tree intHI_type_node; tree intSI_type_node; tree intDI_type_node; #if HOST_BITS_PER_WIDE_INT >= 64 tree intTI_type_node; #endif tree unsigned_intQI_type_node; tree unsigned_intHI_type_node; tree unsigned_intSI_type_node; tree unsigned_intDI_type_node; #if HOST_BITS_PER_WIDE_INT >= 64 tree unsigned_intTI_type_node; #endif tree java_byte_type_node; tree java_short_type_node; tree java_int_type_node; tree java_long_type_node; tree java_float_type_node; tree java_double_type_node; tree java_char_type_node; tree java_boolean_type_node; /* A VOID_TYPE node, and the same, packaged in a TREE_LIST. */ tree void_type_node, void_list_node; tree void_zero_node; /* Nodes for types `void *' and `const void *'. */ tree ptr_type_node; tree const_ptr_type_node; /* Nodes for types `char *' and `const char *'. */ tree string_type_node, const_string_type_node; /* Type `char[256]' or something like it. Used when an array of char is needed and the size is irrelevant. */ tree char_array_type_node; /* Type `int[256]' or something like it. Used when an array of int needed and the size is irrelevant. */ tree int_array_type_node; /* Type `wchar_t[256]' or something like it. Used when a wide string literal is created. */ tree wchar_array_type_node; /* The bool data type, and constants */ tree boolean_type_node, boolean_true_node, boolean_false_node; /* Type `int ()' -- used for implicit declaration of functions. */ tree default_function_type; /* Function types `double (double)' and `double (double, double)', etc. */ static tree double_ftype_double, double_ftype_double_double; static tree int_ftype_int, long_ftype_long; static tree float_ftype_float; static tree ldouble_ftype_ldouble; /* Function type `int (const void *, const void *, size_t)' */ static tree int_ftype_cptr_cptr_sizet; /* C++ extensions */ tree vtable_entry_type; tree delta_type_node; #if 0 /* Old rtti stuff. */ tree __baselist_desc_type_node; tree __i_desc_type_node, __m_desc_type_node; tree __t_desc_array_type, __i_desc_array_type, __m_desc_array_type; #endif tree __t_desc_type_node; #if 0 tree __tp_desc_type_node; #endif tree __access_mode_type_node; tree __bltn_desc_type_node, __user_desc_type_node, __class_desc_type_node; tree __ptr_desc_type_node, __attr_desc_type_node, __func_desc_type_node; tree __ptmf_desc_type_node, __ptmd_desc_type_node; #if 0 /* Not needed yet? May be needed one day? */ tree __bltn_desc_array_type, __user_desc_array_type, __class_desc_array_type; tree __ptr_desc_array_type, __attr_dec_array_type, __func_desc_array_type; tree __ptmf_desc_array_type, __ptmd_desc_array_type; #endif +/* This is the identifier __vlist. */ +tree vlist_identifier; + +/* This is the type _Vlist = vtable_entry_type**. */ +tree vlist_type_node; + +/* A null pointer of type _Vlist. */ +tree vlist_zero_node; + /* Indicates that there is a type value in some namespace, although that is not necessarily in scope at the moment. */ static tree global_type_node; tree class_star_type_node; tree class_type_node, record_type_node, union_type_node, enum_type_node; tree unknown_type_node; tree opaque_type_node, signature_type_node; tree sigtable_entry_type; /* Array type `vtable_entry_type[]' */ tree vtbl_type_node; tree vtbl_ptr_type_node; /* namespace std */ tree std_node; int in_std = 0; /* Expect only namespace names now. */ static int only_namespace_names; /* In a destructor, the point at which all derived class destroying has been done, just before any base class destroying will be done. */ tree dtor_label; /* In a destructor, the last insn emitted after the start of the function and the parms. */ static rtx last_dtor_insn; /* In a constructor, the last insn emitted after the start of the function and the parms, the exception specification and any function-try-block. The constructor initializers are emitted after this insn. */ static rtx last_parm_cleanup_insn; /* In a constructor, the point at which we are ready to return the pointer to the initialized object. */ tree ctor_label; /* A FUNCTION_DECL which can call `abort'. Not necessarily the one that the user will declare, but sufficient to be called by routines that want to abort the program. */ tree abort_fndecl; /* A FUNCTION_DECL for the default `::operator delete'. */ tree global_delete_fndecl; extern rtx cleanup_label, return_label; /* If original DECL_RESULT of current function was a register, but due to being an addressable named return value, would up on the stack, this variable holds the named return value's original location. */ static rtx original_result_rtx; /* Sequence of insns which represents base initialization. */ tree base_init_expr; /* C++: Keep these around to reduce calls to `get_identifier'. Identifiers for `this' in member functions and the auto-delete parameter for destructors. */ tree this_identifier, in_charge_identifier; tree ctor_identifier, dtor_identifier; /* Used in pointer to member functions, in vtables, and in sigtables. */ tree pfn_identifier, index_identifier, delta_identifier, delta2_identifier; tree pfn_or_delta2_identifier, tag_identifier; tree vt_off_identifier; struct named_label_list { struct binding_level *binding_level; tree names_in_scope; tree label_decl; char *filename_o_goto; int lineno_o_goto; struct named_label_list *next; }; /* A list (chain of TREE_LIST nodes) of named label uses. The TREE_PURPOSE field is the list of variables defined in the label's scope defined at the point of use. The TREE_VALUE field is the LABEL_DECL used. The TREE_TYPE field holds `current_binding_level' at the point of the label's use. BWAHAHAAHAHahhahahahaah. No, no, no, said the little chicken. Look at the pretty struct named_label_list. See the pretty struct with the pretty named fields that describe what they do. See the pretty lack of gratuitous casts. Notice the code got a lot cleaner. Used only for jumps to as-yet undefined labels, since jumps to defined labels can have their validity checked by stmt.c. */ static struct named_label_list *named_label_uses = NULL; /* A list of objects which have constructors or destructors which reside in the global scope. The decl is stored in the TREE_VALUE slot and the initializer is stored in the TREE_PURPOSE slot. */ tree static_aggregates; /* -- end of C++ */ /* Two expressions that are constants with value zero. The first is of type `int', the second of type `void *'. */ tree integer_zero_node; tree null_pointer_node; /* The value for __null (NULL), namely, a zero of an integer type with the same number of bits as a pointer. */ tree null_node; /* A node for the integer constants 1, 2, and 3. */ tree integer_one_node, integer_two_node, integer_three_node; /* While defining an enum type, this is 1 plus the last enumerator constant value. */ static tree enum_next_value; /* Nonzero means that there was overflow computing enum_next_value. */ static int enum_overflow; /* Parsing a function declarator leaves a list of parameter names or a chain or parameter decls here. */ tree last_function_parms; /* Parsing a function declarator leaves here a chain of structure and enum types declared in the parmlist. */ static tree last_function_parm_tags; /* After parsing the declarator that starts a function definition, `start_function' puts here the list of parameter names or chain of decls. `store_parm_decls' finds it here. */ static tree current_function_parms; /* Similar, for last_function_parm_tags. */ static tree current_function_parm_tags; /* A list (chain of TREE_LIST nodes) of all LABEL_DECLs in the function that have names. Here so we can clear out their names' definitions at the end of the function. */ static tree named_labels; /* A list of LABEL_DECLs from outer contexts that are currently shadowed. */ static tree shadowed_labels; /* The FUNCTION_DECL for the function currently being compiled, or 0 if between functions. */ tree current_function_decl; /* Set to 0 at beginning of a function definition, set to 1 if a return statement that specifies a return value is seen. */ int current_function_returns_value; /* Set to 0 at beginning of a function definition, set to 1 if a return statement with no argument is seen. */ int current_function_returns_null; /* Set to 0 at beginning of a function definition, and whenever a label (case or named) is defined. Set to value of expression returned from function when that value can be transformed into a named return value. */ tree current_function_return_value; /* Nonzero means give `double' the same size as `float'. */ extern int flag_short_double; /* Nonzero means don't recognize any builtin functions. */ extern int flag_no_builtin; /* Nonzero means don't recognize the non-ANSI builtin functions. -ansi sets this. */ extern int flag_no_nonansi_builtin; /* Nonzero means enable obscure ANSI features and disable GNU extensions that might cause ANSI-compliant code to be miscompiled. */ extern int flag_ansi; /* Nonzero if we want to support huge (> 2^(sizeof(short)*8-1) bytes) objects. */ extern int flag_huge_objects; /* Nonzero if we want to conserve space in the .o files. We do this by putting uninitialized data and runtime initialized data into .common instead of .data at the expense of not flagging multiple definitions. */ extern int flag_conserve_space; /* Pointers to the base and current top of the language name stack. */ extern tree *current_lang_base, *current_lang_stack; /* C and C++ flags are in decl2.c. */ /* Set to 0 at beginning of a constructor, set to 1 if that function does an allocation before referencing its instance variable. */ static int current_function_assigns_this; int current_function_just_assigned_this; /* Set to 0 at beginning of a function. Set non-zero when store_parm_decls is called. Don't call store_parm_decls if this flag is non-zero! */ int current_function_parms_stored; /* Flag used when debugging spew.c */ extern int spew_debug; /* This is a copy of the class_shadowed list of the previous class binding contour when at global scope. It's used to reset IDENTIFIER_CLASS_VALUEs when entering another class scope (i.e. a cache miss). */ extern tree previous_class_values; /* A expression of value 0 with the same precision as a sizetype node, but signed. */ tree signed_size_zero_node; /* The name of the anonymous namespace, throughout this translation unit. */ tree anonymous_namespace_name; /* Allocate a level of searching. */ static struct stack_level * push_decl_level (stack, obstack) struct stack_level *stack; struct obstack *obstack; { struct stack_level tem; tem.prev = stack; return push_stack_level (obstack, (char *)&tem, sizeof (tem)); } /* For each binding contour we allocate a binding_level structure which records the names defined in that contour. Contours include: 0) the global one 1) one for each function definition, where internal declarations of the parameters appear. 2) one for each compound statement, to record its declarations. The current meaning of a name can be found by searching the levels from the current one out to the global one. Off to the side, may be the class_binding_level. This exists only to catch class-local declarations. It is otherwise nonexistent. Also there may be binding levels that catch cleanups that must be run when exceptions occur. Thus, to see whether a name is bound in the current scope, it is not enough to look in the CURRENT_BINDING_LEVEL. You should use lookup_name_current_level instead. */ /* Note that the information in the `names' component of the global contour is duplicated in the IDENTIFIER_GLOBAL_VALUEs of all identifiers. */ struct binding_level { /* A chain of _DECL nodes for all variables, constants, functions, and typedef types. These are in the reverse of the order supplied. There may be OVERLOADs on this list, too, but they are wrapped in TREE_LISTs; the TREE_VALUE is the OVERLOAD. */ tree names; /* A list of structure, union and enum definitions, for looking up tag names. It is a chain of TREE_LIST nodes, each of whose TREE_PURPOSE is a name, or NULL_TREE; and whose TREE_VALUE is a RECORD_TYPE, UNION_TYPE, or ENUMERAL_TYPE node. C++: the TREE_VALUE nodes can be simple types for component_bindings. */ tree tags; /* A list of USING_DECL nodes. */ tree usings; /* A list of used namespaces. PURPOSE is the namespace, VALUE the common ancestor with this binding_level's namespace. */ tree using_directives; /* If this binding level is the binding level for a class, then class_shadowed is a TREE_LIST. The TREE_PURPOSE of each node is the name of an entity bound in the class; the TREE_VALUE is the IDENTIFIER_CLASS_VALUE before we entered the class. Thus, when leaving class scope, we can restore the IDENTIFIER_CLASS_VALUE by walking this list. The TREE_TYPE is the DECL bound by this name in the class. */ tree class_shadowed; /* Similar to class_shadowed, but for IDENTIFIER_TYPE_VALUE, and is used for all binding levels. */ tree type_shadowed; /* For each level (except not the global one), a chain of BLOCK nodes for all the levels that were entered and exited one level down. */ tree blocks; /* The BLOCK node for this level, if one has been preallocated. If 0, the BLOCK is allocated (if needed) when the level is popped. */ tree this_block; /* The binding level which this one is contained in (inherits from). */ struct binding_level *level_chain; /* List of decls in `names' that have incomplete structure or union types. */ tree incomplete; /* List of VAR_DECLS saved from a previous for statement. These would be dead in ANSI-conforming code, but might be referenced in ARM-era code. These are stored in a TREE_LIST; the TREE_VALUE is the actual declaration. */ tree dead_vars_from_for; /* 1 for the level that holds the parameters of a function. 2 for the level that holds a class declaration. 3 for levels that hold parameter declarations. */ unsigned parm_flag : 4; /* 1 means make a BLOCK for this level regardless of all else. 2 for temporary binding contours created by the compiler. */ unsigned keep : 3; /* Nonzero if this level "doesn't exist" for tags. */ unsigned tag_transparent : 1; /* Nonzero if this level can safely have additional cleanup-needing variables added to it. */ unsigned more_cleanups_ok : 1; unsigned have_cleanups : 1; /* Nonzero if this level is for storing the decls for template parameters and generic decls; these decls will be discarded and replaced with a TEMPLATE_DECL. */ unsigned pseudo_global : 1; /* This is set for a namespace binding level. */ unsigned namespace_p : 1; /* True if this level is that of a for-statement where we need to worry about ambiguous (ARM or ANSI) scope rules. */ unsigned is_for_scope : 1; /* Two bits left for this word. */ #if defined(DEBUG_CP_BINDING_LEVELS) /* Binding depth at which this level began. */ unsigned binding_depth; #endif /* defined(DEBUG_CP_BINDING_LEVELS) */ }; #define NULL_BINDING_LEVEL ((struct binding_level *) NULL) /* The binding level currently in effect. */ static struct binding_level *current_binding_level; /* The binding level of the current class, if any. */ static struct binding_level *class_binding_level; /* A chain of binding_level structures awaiting reuse. */ static struct binding_level *free_binding_level; /* The outermost binding level, for names of file scope. This is created when the compiler is started and exists through the entire run. */ static struct binding_level *global_binding_level; /* Binding level structures are initialized by copying this one. */ static struct binding_level clear_binding_level; /* Nonzero means unconditionally make a BLOCK for the next level pushed. */ static int keep_next_level_flag; #if defined(DEBUG_CP_BINDING_LEVELS) static int binding_depth = 0; static int is_class_level = 0; static void indent () { register unsigned i; for (i = 0; i < binding_depth*2; i++) putc (' ', stderr); } #endif /* defined(DEBUG_CP_BINDING_LEVELS) */ static tree pushdecl_with_scope PROTO((tree, struct binding_level *)); static void push_binding_level (newlevel, tag_transparent, keep) struct binding_level *newlevel; int tag_transparent, keep; { /* Add this level to the front of the chain (stack) of levels that are active. */ *newlevel = clear_binding_level; newlevel->level_chain = current_binding_level; current_binding_level = newlevel; newlevel->tag_transparent = tag_transparent; newlevel->more_cleanups_ok = 1; newlevel->keep = keep; #if defined(DEBUG_CP_BINDING_LEVELS) newlevel->binding_depth = binding_depth; indent (); fprintf (stderr, "push %s level 0x%08x line %d\n", (is_class_level) ? "class" : "block", newlevel, lineno); is_class_level = 0; binding_depth++; #endif /* defined(DEBUG_CP_BINDING_LEVELS) */ } /* Find the innermost enclosing class scope, and reset CLASS_BINDING_LEVEL appropriately. */ static void find_class_binding_level () { struct binding_level *level = current_binding_level; while (level && level->parm_flag != 2) level = level->level_chain; if (level && level->parm_flag == 2) class_binding_level = level; else class_binding_level = 0; } static void pop_binding_level () { if (global_binding_level) { /* Cannot pop a level, if there are none left to pop. */ if (current_binding_level == global_binding_level) my_friendly_abort (123); } /* Pop the current level, and free the structure for reuse. */ #if defined(DEBUG_CP_BINDING_LEVELS) binding_depth--; indent (); fprintf (stderr, "pop %s level 0x%08x line %d\n", (is_class_level) ? "class" : "block", current_binding_level, lineno); if (is_class_level != (current_binding_level == class_binding_level)) { indent (); fprintf (stderr, "XXX is_class_level != (current_binding_level == class_binding_level)\n"); } is_class_level = 0; #endif /* defined(DEBUG_CP_BINDING_LEVELS) */ { register struct binding_level *level = current_binding_level; current_binding_level = current_binding_level->level_chain; level->level_chain = free_binding_level; #if 0 /* defined(DEBUG_CP_BINDING_LEVELS) */ if (level->binding_depth != binding_depth) abort (); #endif /* defined(DEBUG_CP_BINDING_LEVELS) */ free_binding_level = level; find_class_binding_level (); } } static void suspend_binding_level () { if (class_binding_level) current_binding_level = class_binding_level; if (global_binding_level) { /* Cannot suspend a level, if there are none left to suspend. */ if (current_binding_level == global_binding_level) my_friendly_abort (123); } /* Suspend the current level. */ #if defined(DEBUG_CP_BINDING_LEVELS) binding_depth--; indent (); fprintf (stderr, "suspend %s level 0x%08x line %d\n", (is_class_level) ? "class" : "block", current_binding_level, lineno); if (is_class_level != (current_binding_level == class_binding_level)) { indent (); fprintf (stderr, "XXX is_class_level != (current_binding_level == class_binding_level)\n"); } is_class_level = 0; #endif /* defined(DEBUG_CP_BINDING_LEVELS) */ current_binding_level = current_binding_level->level_chain; find_class_binding_level (); } static void resume_binding_level (b) struct binding_level *b; { /* Resuming binding levels is meant only for namespaces, and those cannot nest into classes. */ my_friendly_assert(!class_binding_level, 386); /* Also, resuming a non-directly nested namespace is a no-no. */ my_friendly_assert(b->level_chain == current_binding_level, 386); current_binding_level = b; #if defined(DEBUG_CP_BINDING_LEVELS) b->binding_depth = binding_depth; indent (); fprintf (stderr, "resume %s level 0x%08x line %d\n", (is_class_level) ? "class" : "block", b, lineno); is_class_level = 0; binding_depth++; #endif /* defined(DEBUG_CP_BINDING_LEVELS) */ } /* Create a new `struct binding_level'. */ static struct binding_level * make_binding_level () { /* NOSTRICT */ return (struct binding_level *) xmalloc (sizeof (struct binding_level)); } /* Nonzero if we are currently in the global binding level. */ int global_bindings_p () { return current_binding_level == global_binding_level; } /* Return the innermost binding level that is not for a class scope. */ static struct binding_level * innermost_nonclass_level () { struct binding_level *b; b = current_binding_level; while (b->parm_flag == 2) b = b->level_chain; return b; } /* Nonzero if we are currently in a toplevel binding level. This means either the global binding level or a namespace in a toplevel binding level. Since there are no non-toplevel namespace levels, this really means any namespace or pseudo-global level. We also include a class whose context is toplevel. */ int toplevel_bindings_p () { struct binding_level *b = innermost_nonclass_level (); return b->namespace_p || b->pseudo_global; } /* Nonzero if this is a namespace scope, or if we are defining a class which is itself at namespace scope, or whose enclosing class is such a class, etc. */ int namespace_bindings_p () { struct binding_level *b = innermost_nonclass_level (); return b->namespace_p; } void keep_next_level () { keep_next_level_flag = 1; } /* Nonzero if the current level needs to have a BLOCK made. */ int kept_level_p () { return (current_binding_level->blocks != NULL_TREE || current_binding_level->keep || current_binding_level->names != NULL_TREE || (current_binding_level->tags != NULL_TREE && !current_binding_level->tag_transparent)); } /* Identify this binding level as a level of parameters. */ void declare_parm_level () { current_binding_level->parm_flag = 1; } void declare_pseudo_global_level () { current_binding_level->pseudo_global = 1; } static void declare_namespace_level () { current_binding_level->namespace_p = 1; } int pseudo_global_level_p () { struct binding_level *b = innermost_nonclass_level (); return b->pseudo_global; } void set_class_shadows (shadows) tree shadows; { class_binding_level->class_shadowed = shadows; } /* Enter a new binding level. If TAG_TRANSPARENT is nonzero, do so only for the name space of variables, not for that of tags. */ void pushlevel (tag_transparent) int tag_transparent; { register struct binding_level *newlevel = NULL_BINDING_LEVEL; /* If this is the top level of a function, just make sure that NAMED_LABELS is 0. They should have been set to 0 at the end of the previous function. */ if (current_binding_level == global_binding_level) my_friendly_assert (named_labels == NULL_TREE, 134); /* Reuse or create a struct for this binding level. */ #if defined(DEBUG_CP_BINDING_LEVELS) if (0) #else /* !defined(DEBUG_CP_BINDING_LEVELS) */ if (free_binding_level) #endif /* !defined(DEBUG_CP_BINDING_LEVELS) */ { newlevel = free_binding_level; free_binding_level = free_binding_level->level_chain; } else { newlevel = make_binding_level (); } push_binding_level (newlevel, tag_transparent, keep_next_level_flag); GNU_xref_start_scope ((HOST_WIDE_INT) newlevel); keep_next_level_flag = 0; } void note_level_for_for () { current_binding_level->is_for_scope = 1; } void pushlevel_temporary (tag_transparent) int tag_transparent; { pushlevel (tag_transparent); current_binding_level->keep = 2; clear_last_expr (); /* Note we don't call push_momentary() here. Otherwise, it would cause cleanups to be allocated on the momentary obstack, and they will be overwritten by the next statement. */ expand_start_bindings (0); } /* For a binding between a name and an entity at a block scope, this is the `struct binding_level' for the block. */ #define BINDING_LEVEL(NODE) \ (((struct tree_binding*)NODE)->scope.level) /* These are currently unused, but permanent, CPLUS_BINDING nodes. They are kept here because they are allocated from the permanent obstack and cannot be easily freed. */ static tree free_binding_nodes; /* Make DECL the innermost binding for ID. The LEVEL is the binding level at which this declaration is being bound. */ static void push_binding (id, decl, level) tree id; tree decl; struct binding_level* level; { tree binding; if (!free_binding_nodes) { /* There are no free nodes, so we must build one here. */ push_obstacks_nochange (); end_temporary_allocation (); binding = make_node (CPLUS_BINDING); pop_obstacks (); } else { /* There are nodes on the free list. Grab the first one. */ binding = free_binding_nodes; /* And update the free list. */ free_binding_nodes = TREE_CHAIN (free_binding_nodes); } /* Now, fill in the binding information. */ BINDING_VALUE (binding) = decl; BINDING_TYPE (binding) = NULL_TREE; BINDING_LEVEL (binding) = level; INHERITED_VALUE_BINDING_P (binding) = 0; LOCAL_BINDING_P (binding) = (level != class_binding_level); /* And put it on the front of the list of bindings for ID. */ TREE_CHAIN (binding) = IDENTIFIER_BINDING (id); IDENTIFIER_BINDING (id) = binding; } /* ID is already bound in the current scope. But, DECL is an additional binding for ID in the same scope. This is the `struct stat' hack whereby a non-typedef class-name or enum-name can be bound at the same level as some other kind of entity. It's the responsibility of the caller to check that inserting this name is legal here. Returns nonzero if the new binding was successful. */ static int add_binding (id, decl) tree id; tree decl; { tree binding = IDENTIFIER_BINDING (id); int ok = 1; if (TREE_CODE (decl) == TYPE_DECL && DECL_ARTIFICIAL (decl)) /* The new name is the type name. */ BINDING_TYPE (binding) = decl; else if (!BINDING_VALUE (binding)) /* This situation arises when push_class_level_binding moves an inherited type-binding out of the way to make room for a new value binding. */ BINDING_VALUE (binding) = decl; else if (TREE_CODE (BINDING_VALUE (binding)) == TYPE_DECL && DECL_ARTIFICIAL (BINDING_VALUE (binding))) { /* The old binding was a type name. It was placed in BINDING_VALUE because it was thought, at the point it was declared, to be the only entity with such a name. Move the type name into the type slot; it is now hidden by the new binding. */ BINDING_TYPE (binding) = BINDING_VALUE (binding); BINDING_VALUE (binding) = decl; INHERITED_VALUE_BINDING_P (binding) = 0; } else { cp_error ("declaration of `%#D'", decl); cp_error_at ("conflicts with previous declaration `%#D'", BINDING_VALUE (binding)); ok = 0; } return ok; } /* Bind DECL to ID in the current_binding_level. If PUSH_USING is set in FLAGS, we know that DECL doesn't really belong to this binding level, that it got here through a using-declaration. */ void push_local_binding (id, decl, flags) tree id; tree decl; int flags; { struct binding_level *b; /* Skip over any local classes. This makes sense if we call push_local_binding with a friend decl of a local class. */ b = current_binding_level; while (b->parm_flag == 2) b = b->level_chain; if (lookup_name_current_level (id)) { /* Supplement the existing binding. */ if (!add_binding (id, decl)) /* It didn't work. Something else must be bound at this level. Do not add DECL to the list of things to pop later. */ return; } else /* Create a new binding. */ push_binding (id, decl, b); if (TREE_CODE (decl) == OVERLOAD || (flags & PUSH_USING)) /* We must put the OVERLOAD into a TREE_LIST since the TREE_CHAIN of an OVERLOAD is already used. Similarly for decls that got here through a using-declaration. */ decl = build_tree_list (NULL_TREE, decl); /* And put DECL on the list of things declared by the current binding level. */ TREE_CHAIN (decl) = b->names; b->names = decl; } /* Bind DECL to ID in the class_binding_level. Returns nonzero if the binding was successful. */ int push_class_binding (id, decl) tree id; tree decl; { int result = 1; tree binding = IDENTIFIER_BINDING (id); tree context; /* Note that we declared this value so that we can issue an error if this an illegal redeclaration of a name already used for some other purpose. */ note_name_declared_in_class (id, decl); if (binding && BINDING_LEVEL (binding) == class_binding_level) /* Supplement the existing binding. */ result = add_binding (id, decl); else /* Create a new binding. */ push_binding (id, decl, class_binding_level); /* Update the IDENTIFIER_CLASS_VALUE for this ID to be the class-level declaration. Note that we do not use DECL here because of the possibility of the `struct stat' hack; if DECL is a class-name or enum-name we might prefer a field-name, or some such. */ IDENTIFIER_CLASS_VALUE (id) = BINDING_VALUE (IDENTIFIER_BINDING (id)); /* If this is a binding from a base class, mark it as such. */ binding = IDENTIFIER_BINDING (id); if (BINDING_VALUE (binding) == decl && TREE_CODE (decl) != TREE_LIST) { /* Any implicit typename must be from a base-class. The context for an implicit typename declaration is always the derived class in which the lookup was done, so the checks based on the context of DECL below will not trigger. */ if (TREE_CODE (decl) == TYPE_DECL && IMPLICIT_TYPENAME_P (TREE_TYPE (decl))) INHERITED_VALUE_BINDING_P (binding) = 1; else { if (TREE_CODE (decl) == OVERLOAD) context = DECL_REAL_CONTEXT (OVL_CURRENT (decl)); else { my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (decl)) == 'd', 0); context = DECL_REAL_CONTEXT (decl); } if (is_properly_derived_from (current_class_type, context)) INHERITED_VALUE_BINDING_P (binding) = 1; else INHERITED_VALUE_BINDING_P (binding) = 0; } } else if (BINDING_VALUE (binding) == decl) /* We only encounter a TREE_LIST when push_class_decls detects an ambiguity. Such an ambiguity can be overridden by a definition in this class. */ INHERITED_VALUE_BINDING_P (binding) = 1; return result; } /* Remove the binding for DECL which should be the innermost binding for ID. */ static void pop_binding (id, decl) tree id; tree decl; { tree binding; if (id == NULL_TREE) /* It's easiest to write the loops that call this function without checking whether or not the entities involved have names. We get here for such an entity. */ return; /* Get the innermost binding for ID. */ binding = IDENTIFIER_BINDING (id); /* The name should be bound. */ my_friendly_assert (binding != NULL_TREE, 0); /* The DECL will be either the ordinary binding or the type binding for this identifier. Remove that binding. */ if (BINDING_VALUE (binding) == decl) BINDING_VALUE (binding) = NULL_TREE; else if (BINDING_TYPE (binding) == decl) BINDING_TYPE (binding) = NULL_TREE; else my_friendly_abort (0); if (!BINDING_VALUE (binding) && !BINDING_TYPE (binding)) { /* We're completely done with the innermost binding for this identifier. Unhook it from the list of bindings. */ IDENTIFIER_BINDING (id) = TREE_CHAIN (binding); /* And place it on the free list. */ TREE_CHAIN (binding) = free_binding_nodes; free_binding_nodes = binding; } } /* Exit a binding level. Pop the level off, and restore the state of the identifier-decl mappings that were in effect when this level was entered. If KEEP == 1, this level had explicit declarations, so and create a "block" (a BLOCK node) for the level to record its declarations and subblocks for symbol table output. If FUNCTIONBODY is nonzero, this level is the body of a function, so create a block as if KEEP were set and also clear out all label names. If REVERSE is nonzero, reverse the order of decls before putting them into the BLOCK. */ tree poplevel (keep, reverse, functionbody) int keep; int reverse; int functionbody; { register tree link; /* The chain of decls was accumulated in reverse order. Put it into forward order, just for cleanliness. */ tree decls; int tmp = functionbody; int real_functionbody = current_binding_level->keep == 2 ? ((functionbody = 0), tmp) : functionbody; tree tags = functionbody >= 0 ? current_binding_level->tags : 0; tree subblocks = functionbody >= 0 ? current_binding_level->blocks : 0; tree block = NULL_TREE; tree decl; int block_previously_created; int leaving_for_scope; if (current_binding_level->parm_flag == 2) return poplevel_class (); my_friendly_assert (!current_binding_level->class_shadowed, 19990414); /* We used to use KEEP == 2 to indicate that the new block should go at the beginning of the list of blocks at this binding level, rather than the end. This hack is no longer used. */ my_friendly_assert (keep == 0 || keep == 1, 0); GNU_xref_end_scope ((HOST_WIDE_INT) current_binding_level, (HOST_WIDE_INT) current_binding_level->level_chain, current_binding_level->parm_flag, current_binding_level->keep); if (current_binding_level->keep == 1) keep = 1; /* Get the decls in the order they were written. Usually current_binding_level->names is in reverse order. But parameter decls were previously put in forward order. */ if (reverse) current_binding_level->names = decls = nreverse (current_binding_level->names); else decls = current_binding_level->names; /* Output any nested inline functions within this block if they weren't already output. */ for (decl = decls; decl; decl = TREE_CHAIN (decl)) if (TREE_CODE (decl) == FUNCTION_DECL && ! TREE_ASM_WRITTEN (decl) && DECL_INITIAL (decl) != NULL_TREE && TREE_ADDRESSABLE (decl) && decl_function_context (decl) == current_function_decl) { /* If this decl was copied from a file-scope decl on account of a block-scope extern decl, propagate TREE_ADDRESSABLE to the file-scope decl. */ if (DECL_ABSTRACT_ORIGIN (decl) != NULL_TREE) TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (decl)) = 1; else { push_function_context (); output_inline_function (decl); pop_function_context (); } } /* If there were any declarations or structure tags in that level, or if this level is a function body, create a BLOCK to record them for the life of this function. */ block = NULL_TREE; block_previously_created = (current_binding_level->this_block != NULL_TREE); if (block_previously_created) block = current_binding_level->this_block; else if (keep == 1 || functionbody) block = make_node (BLOCK); if (block != NULL_TREE) { if (block_previously_created) { if (decls || tags || subblocks) { if (BLOCK_VARS (block) || BLOCK_TYPE_TAGS (block)) warning ("internal compiler error: debugging info corrupted"); BLOCK_VARS (block) = decls; BLOCK_TYPE_TAGS (block) = tags; /* We can have previous subblocks and new subblocks when doing fixup_gotos with complex cleanups. We chain the new subblocks onto the end of any pre-existing subblocks. */ BLOCK_SUBBLOCKS (block) = chainon (BLOCK_SUBBLOCKS (block), subblocks); } /* If we created the block earlier on, and we are just diddling it now, then it already should have a proper BLOCK_END_NOTE value associated with it. */ } else { BLOCK_VARS (block) = decls; BLOCK_TYPE_TAGS (block) = tags; BLOCK_SUBBLOCKS (block) = subblocks; /* Otherwise, for a new block, install a new BLOCK_END_NOTE value. */ remember_end_note (block); } } /* In each subblock, record that this is its superior. */ if (keep >= 0) for (link = subblocks; link; link = TREE_CHAIN (link)) BLOCK_SUPERCONTEXT (link) = block; /* We still support the old for-scope rules, whereby the variables in a for-init statement were in scope after the for-statement ended. We only use the new rules in flag_new_for_scope is nonzero. */ leaving_for_scope = current_binding_level->is_for_scope && flag_new_for_scope == 1; /* Remove declarations for all the DECLs in this level. */ for (link = decls; link; link = TREE_CHAIN (link)) { if (leaving_for_scope && TREE_CODE (link) == VAR_DECL) { tree outer_binding = TREE_CHAIN (IDENTIFIER_BINDING (DECL_NAME (link))); tree ns_binding; if (!outer_binding) ns_binding = IDENTIFIER_NAMESPACE_VALUE (DECL_NAME (link)); else ns_binding = NULL_TREE; if (outer_binding && (BINDING_LEVEL (outer_binding) == current_binding_level->level_chain)) /* We have something like: int i; for (int i; ;); and we are leaving the `for' scope. There's no reason to keep the binding of the inner `i' in this case. */ pop_binding (DECL_NAME (link), link); else if ((outer_binding && (TREE_CODE (BINDING_VALUE (outer_binding)) == TYPE_DECL)) || (ns_binding && TREE_CODE (ns_binding) == TYPE_DECL)) /* Here, we have something like: typedef int I; void f () { for (int I; ;); } We must pop the for-scope binding so we know what's a type and what isn't. */ pop_binding (DECL_NAME (link), link); else { /* Mark this VAR_DECL as dead so that we can tell we left it there only for backward compatibility. */ DECL_DEAD_FOR_LOCAL (link) = 1; /* Keep track of what should of have happenned when we popped the binding. */ if (outer_binding && BINDING_VALUE (outer_binding)) DECL_SHADOWED_FOR_VAR (link) = BINDING_VALUE (outer_binding); /* Add it to the list of dead variables in the next outermost binding to that we can remove these when we leave that binding. */ current_binding_level->level_chain->dead_vars_from_for = tree_cons (NULL_TREE, link, current_binding_level->level_chain-> dead_vars_from_for); /* Although we don't pop the CPLUS_BINDING, we do clear its BINDING_LEVEL since the level is going away now. */ BINDING_LEVEL (IDENTIFIER_BINDING (DECL_NAME (link))) = 0; } } else { /* Remove the binding. */ decl = link; if (TREE_CODE (decl) == TREE_LIST) decl = TREE_VALUE (decl); if (TREE_CODE_CLASS (TREE_CODE (decl)) == 'd') pop_binding (DECL_NAME (decl), decl); else if (TREE_CODE (decl) == OVERLOAD) pop_binding (DECL_NAME (OVL_FUNCTION (decl)), decl); else my_friendly_abort (0); } } /* Remove declarations for any `for' variables from inner scopes that we kept around. */ for (link = current_binding_level->dead_vars_from_for; link; link = TREE_CHAIN (link)) pop_binding (DECL_NAME (TREE_VALUE (link)), TREE_VALUE (link)); /* Restore the IDENTIFIER_TYPE_VALUEs. */ for (link = current_binding_level->type_shadowed; link; link = TREE_CHAIN (link)) SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (link), TREE_VALUE (link)); /* There may be OVERLOADs (wrapped in TREE_LISTs) on the BLOCK_VARs list if a `using' declaration put them there. The debugging back-ends won't understand OVERLOAD, so we remove them here. Because the BLOCK_VARS are (temporarily) shared with CURRENT_BINDING_LEVEL->NAMES we must do this fixup after we have popped all the bindings. */ if (block) { tree* d; for (d = &BLOCK_VARS (block); *d; ) { if (TREE_CODE (*d) == TREE_LIST) *d = TREE_CHAIN (*d); else d = &TREE_CHAIN (*d); } } /* If the level being exited is the top level of a function, check over all the labels. */ if (functionbody) { /* If this is the top level block of a function, the vars are the function's parameters. Don't leave them in the BLOCK because they are found in the FUNCTION_DECL instead. */ BLOCK_VARS (block) = 0; /* Clear out the definitions of all label names, since their scopes end here. */ for (link = named_labels; link; link = TREE_CHAIN (link)) { register tree label = TREE_VALUE (link); if (DECL_INITIAL (label) == NULL_TREE) { cp_error_at ("label `%D' used but not defined", label); /* Avoid crashing later. */ define_label (input_filename, 1, DECL_NAME (label)); } else if (warn_unused && !TREE_USED (label)) cp_warning_at ("label `%D' defined but not used", label); SET_IDENTIFIER_LABEL_VALUE (DECL_NAME (label), NULL_TREE); /* Put the labels into the "variables" of the top-level block, so debugger can see them. */ TREE_CHAIN (label) = BLOCK_VARS (block); BLOCK_VARS (block) = label; } named_labels = NULL_TREE; } /* Any uses of undefined labels now operate under constraints of next binding contour. */ { struct binding_level *level_chain; level_chain = current_binding_level->level_chain; if (level_chain) { struct named_label_list *labels; for (labels = named_label_uses; labels; labels = labels->next) if (labels->binding_level == current_binding_level) { labels->binding_level = level_chain; labels->names_in_scope = level_chain->names; } } } tmp = current_binding_level->keep; pop_binding_level (); if (functionbody) DECL_INITIAL (current_function_decl) = block; else if (block) { if (!block_previously_created) current_binding_level->blocks = chainon (current_binding_level->blocks, block); } /* If we did not make a block for the level just exited, any blocks made for inner levels (since they cannot be recorded as subblocks in that level) must be carried forward so they will later become subblocks of something else. */ else if (subblocks) current_binding_level->blocks = chainon (current_binding_level->blocks, subblocks); /* Take care of compiler's internal binding structures. */ if (tmp == 2) { expand_end_bindings (getdecls (), keep, 1); /* Each and every BLOCK node created here in `poplevel' is important (e.g. for proper debugging information) so if we created one earlier, mark it as "used". */ if (block) TREE_USED (block) = 1; block = poplevel (keep, reverse, real_functionbody); } /* Each and every BLOCK node created here in `poplevel' is important (e.g. for proper debugging information) so if we created one earlier, mark it as "used". */ if (block) TREE_USED (block) = 1; return block; } /* Delete the node BLOCK from the current binding level. This is used for the block inside a stmt expr ({...}) so that the block can be reinserted where appropriate. */ void delete_block (block) tree block; { tree t; if (current_binding_level->blocks == block) current_binding_level->blocks = TREE_CHAIN (block); for (t = current_binding_level->blocks; t;) { if (TREE_CHAIN (t) == block) TREE_CHAIN (t) = TREE_CHAIN (block); else t = TREE_CHAIN (t); } TREE_CHAIN (block) = NULL_TREE; /* Clear TREE_USED which is always set by poplevel. The flag is set again if insert_block is called. */ TREE_USED (block) = 0; } /* Insert BLOCK at the end of the list of subblocks of the current binding level. This is used when a BIND_EXPR is expanded, to handle the BLOCK node inside the BIND_EXPR. */ void insert_block (block) tree block; { TREE_USED (block) = 1; current_binding_level->blocks = chainon (current_binding_level->blocks, block); } /* Set the BLOCK node for the innermost scope (the one we are currently in). */ void set_block (block) register tree block; { current_binding_level->this_block = block; } /* Do a pushlevel for class declarations. */ void pushlevel_class () { register struct binding_level *newlevel; /* Reuse or create a struct for this binding level. */ #if defined(DEBUG_CP_BINDING_LEVELS) if (0) #else /* !defined(DEBUG_CP_BINDING_LEVELS) */ if (free_binding_level) #endif /* !defined(DEBUG_CP_BINDING_LEVELS) */ { newlevel = free_binding_level; free_binding_level = free_binding_level->level_chain; } else newlevel = make_binding_level (); #if defined(DEBUG_CP_BINDING_LEVELS) is_class_level = 1; #endif /* defined(DEBUG_CP_BINDING_LEVELS) */ push_binding_level (newlevel, 0, 0); decl_stack = push_decl_level (decl_stack, &decl_obstack); class_binding_level = current_binding_level; class_binding_level->parm_flag = 2; } /* ...and a poplevel for class declarations. */ static tree poplevel_class () { register struct binding_level *level = class_binding_level; tree shadowed; my_friendly_assert (level != 0, 354); decl_stack = pop_stack_level (decl_stack); /* If we're leaving a toplevel class, don't bother to do the setting of IDENTIFIER_CLASS_VALUE to NULL_TREE, since first of all this slot shouldn't even be used when current_class_type isn't set, and second, if we don't touch it here, we're able to use the cache effect if the next time we're entering a class scope, it is the same class. */ if (current_class_depth != 1) { struct binding_level* b; /* Clear out our IDENTIFIER_CLASS_VALUEs. */ for (shadowed = level->class_shadowed; shadowed; shadowed = TREE_CHAIN (shadowed)) IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (shadowed)) = NULL_TREE; /* Find the next enclosing class, and recreate IDENTIFIER_CLASS_VALUEs appropriate for that class. */ b = level->level_chain; while (b && b->parm_flag != 2) b = b->level_chain; if (b) for (shadowed = b->class_shadowed; shadowed; shadowed = TREE_CHAIN (shadowed)) { tree t; t = IDENTIFIER_BINDING (TREE_PURPOSE (shadowed)); while (t && BINDING_LEVEL (t) != b) t = TREE_CHAIN (t); if (t) IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (shadowed)) = BINDING_VALUE (t); } } else /* Remember to save what IDENTIFIER's were bound in this scope so we can recover from cache misses. */ { previous_class_type = current_class_type; previous_class_values = class_binding_level->class_shadowed; } for (shadowed = level->type_shadowed; shadowed; shadowed = TREE_CHAIN (shadowed)) SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (shadowed), TREE_VALUE (shadowed)); /* Remove the bindings for all of the class-level declarations. */ for (shadowed = level->class_shadowed; shadowed; shadowed = TREE_CHAIN (shadowed)) pop_binding (TREE_PURPOSE (shadowed), TREE_TYPE (shadowed)); GNU_xref_end_scope ((HOST_WIDE_INT) class_binding_level, (HOST_WIDE_INT) class_binding_level->level_chain, class_binding_level->parm_flag, class_binding_level->keep); /* Now, pop out of the binding level which we created up in the `pushlevel_class' routine. */ #if defined(DEBUG_CP_BINDING_LEVELS) is_class_level = 1; #endif /* defined(DEBUG_CP_BINDING_LEVELS) */ pop_binding_level (); return NULL_TREE; } /* We are entering the scope of a class. Clear IDENTIFIER_CLASS_VALUE for any names in enclosing classes. */ void clear_identifier_class_values () { tree t; if (!class_binding_level) return; for (t = class_binding_level->class_shadowed; t; t = TREE_CHAIN (t)) IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (t)) = NULL_TREE; } /* Returns non-zero if T is a virtual function table. */ int vtable_decl_p (t, data) tree t; void *data ATTRIBUTE_UNUSED; { return (TREE_CODE (t) == VAR_DECL && DECL_VIRTUAL_P (t)); } /* Returns non-zero if T is a TYPE_DECL for a type with virtual functions. */ int vtype_decl_p (t, data) tree t; void *data ATTRIBUTE_UNUSED; { return (TREE_CODE (t) == TYPE_DECL && TREE_TYPE (t) != error_mark_node && TYPE_LANG_SPECIFIC (TREE_TYPE (t)) && CLASSTYPE_VSIZE (TREE_TYPE (t))); } /* Returns non-zero if T is a signature table. */ int sigtable_decl_p (t, data) tree t; void *data ATTRIBUTE_UNUSED; { return (TREE_CODE (t) == VAR_DECL && TREE_TYPE (t) != error_mark_node && IS_SIGNATURE (TREE_TYPE (t))); } /* Walk all the namespaces contained NAMESPACE, including NAMESPACE itself, calling F for each. The DATA is passed to F as well. */ static int walk_namespaces_r (namespace, f, data) tree namespace; walk_namespaces_fn f; void *data; { tree current; int result = 0; result |= (*f) (namespace, data); for (current = NAMESPACE_LEVEL (namespace)->names; current; current = TREE_CHAIN (current)) { if (TREE_CODE (current) != NAMESPACE_DECL || DECL_NAMESPACE_ALIAS (current)) continue; if (!DECL_LANG_SPECIFIC (current)) { /* Hmm. std. */ my_friendly_assert (current == std_node, 393); continue; } /* We found a namespace. */ result |= walk_namespaces_r (current, f, data); } return result; } /* Walk all the namespaces, calling F for each. The DATA is passed to F as well. */ int walk_namespaces (f, data) walk_namespaces_fn f; void *data; { return walk_namespaces_r (global_namespace, f, data); } struct walk_globals_data { walk_globals_pred p; walk_globals_fn f; void *data; }; /* Walk the global declarations in NAMESPACE. Whenever one is found for which P returns non-zero, call F with its address. If any call to F returns a non-zero value, return a non-zero value. */ static int walk_globals_r (namespace, data) tree namespace; void *data; { struct walk_globals_data* wgd = (struct walk_globals_data *) data; walk_globals_pred p = wgd->p; walk_globals_fn f = wgd->f; void *d = wgd->data; tree *t; int result = 0; t = &NAMESPACE_LEVEL (namespace)->names; while (*t) { tree glbl = *t; if ((*p) (glbl, d)) result |= (*f) (t, d); /* If F changed *T, then *T still points at the next item to examine. */ if (*t == glbl) t = &TREE_CHAIN (*t); } return result; } /* Walk the global declarations. Whenever one is found for which P returns non-zero, call F with its address. If any call to F returns a non-zero value, return a non-zero value. */ int walk_globals (p, f, data) walk_globals_pred p; walk_globals_fn f; void *data; { struct walk_globals_data wgd; wgd.p = p; wgd.f = f; wgd.data = data; return walk_namespaces (walk_globals_r, &wgd); } /* Call wrapup_globals_declarations for the globals in NAMESPACE. If DATA is non-NULL, this is the last time we will call wrapup_global_declarations for this NAMESPACE. */ int wrapup_globals_for_namespace (namespace, data) tree namespace; void *data; { tree globals = NAMESPACE_LEVEL (namespace)->names; int len = list_length (globals); tree *vec = (tree *) alloca (sizeof (tree) * len); int i; int result; tree decl; int last_time = (data != 0); if (last_time && namespace == global_namespace) /* Let compile_file handle the global namespace. */ return 0; /* Process the decls in reverse order--earliest first. Put them into VEC from back to front, then take out from front. */ for (i = 0, decl = globals; i < len; i++, decl = TREE_CHAIN (decl)) vec[len - i - 1] = decl; if (last_time) { check_global_declarations (vec, len); return 0; } /* Temporarily mark vtables as external. That prevents wrapup_global_declarations from writing them out; we must process them ourselves in finish_vtable_vardecl. */ for (i = 0; i < len; ++i) if (vtable_decl_p (vec[i], /*data=*/0) && !DECL_EXTERNAL (vec[i])) { DECL_NOT_REALLY_EXTERN (vec[i]) = 1; DECL_EXTERNAL (vec[i]) = 1; } /* Write out any globals that need to be output. */ result = wrapup_global_declarations (vec, len); /* Undo the hack to DECL_EXTERNAL above. */ for (i = 0; i < len; ++i) if (vtable_decl_p (vec[i], /*data=*/0) && DECL_NOT_REALLY_EXTERN (vec[i])) { DECL_NOT_REALLY_EXTERN (vec[i]) = 0; DECL_EXTERNAL (vec[i]) = 0; } return result; } /* For debugging. */ static int no_print_functions = 0; static int no_print_builtins = 0; void print_binding_level (lvl) struct binding_level *lvl; { tree t; int i = 0, len; fprintf (stderr, " blocks="); fprintf (stderr, HOST_PTR_PRINTF, lvl->blocks); fprintf (stderr, " n_incomplete=%d parm_flag=%d keep=%d", list_length (lvl->incomplete), lvl->parm_flag, lvl->keep); if (lvl->tag_transparent) fprintf (stderr, " tag-transparent"); if (lvl->more_cleanups_ok) fprintf (stderr, " more-cleanups-ok"); if (lvl->have_cleanups) fprintf (stderr, " have-cleanups"); fprintf (stderr, "\n"); if (lvl->names) { fprintf (stderr, " names:\t"); /* We can probably fit 3 names to a line? */ for (t = lvl->names; t; t = TREE_CHAIN (t)) { if (no_print_functions && (TREE_CODE (t) == FUNCTION_DECL)) continue; if (no_print_builtins && (TREE_CODE (t) == TYPE_DECL) && (!strcmp (DECL_SOURCE_FILE (t),""))) continue; /* Function decls tend to have longer names. */ if (TREE_CODE (t) == FUNCTION_DECL) len = 3; else len = 2; i += len; if (i > 6) { fprintf (stderr, "\n\t"); i = len; } print_node_brief (stderr, "", t, 0); if (t == error_mark_node) break; } if (i) fprintf (stderr, "\n"); } if (lvl->tags) { fprintf (stderr, " tags:\t"); i = 0; for (t = lvl->tags; t; t = TREE_CHAIN (t)) { if (TREE_PURPOSE (t) == NULL_TREE) len = 3; else if (TREE_PURPOSE (t) == TYPE_IDENTIFIER (TREE_VALUE (t))) len = 2; else len = 4; i += len; if (i > 5) { fprintf (stderr, "\n\t"); i = len; } if (TREE_PURPOSE (t) == NULL_TREE) { print_node_brief (stderr, ""); } else if (TREE_PURPOSE (t) == TYPE_IDENTIFIER (TREE_VALUE (t))) print_node_brief (stderr, "", TREE_VALUE (t), 0); else { print_node_brief (stderr, ""); } } if (i) fprintf (stderr, "\n"); } if (lvl->class_shadowed) { fprintf (stderr, " class-shadowed:"); for (t = lvl->class_shadowed; t; t = TREE_CHAIN (t)) { fprintf (stderr, " %s ", IDENTIFIER_POINTER (TREE_PURPOSE (t))); } fprintf (stderr, "\n"); } if (lvl->type_shadowed) { fprintf (stderr, " type-shadowed:"); for (t = lvl->type_shadowed; t; t = TREE_CHAIN (t)) { fprintf (stderr, " %s ", IDENTIFIER_POINTER (TREE_PURPOSE (t))); } fprintf (stderr, "\n"); } } void print_other_binding_stack (stack) struct binding_level *stack; { struct binding_level *level; for (level = stack; level != global_binding_level; level = level->level_chain) { fprintf (stderr, "binding level "); fprintf (stderr, HOST_PTR_PRINTF, level); fprintf (stderr, "\n"); print_binding_level (level); } } void print_binding_stack () { struct binding_level *b; fprintf (stderr, "current_binding_level="); fprintf (stderr, HOST_PTR_PRINTF, current_binding_level); fprintf (stderr, "\nclass_binding_level="); fprintf (stderr, HOST_PTR_PRINTF, class_binding_level); fprintf (stderr, "\nglobal_binding_level="); fprintf (stderr, HOST_PTR_PRINTF, global_binding_level); fprintf (stderr, "\n"); if (class_binding_level) { for (b = class_binding_level; b; b = b->level_chain) if (b == current_binding_level) break; if (b) b = class_binding_level; else b = current_binding_level; } else b = current_binding_level; print_other_binding_stack (b); fprintf (stderr, "global:\n"); print_binding_level (global_binding_level); } /* Namespace binding access routines: The namespace_bindings field of the identifier is polymorphic, with three possible values: NULL_TREE, a list of CPLUS_BINDINGS, or any other tree_node indicating the BINDING_VALUE of global_namespace. */ /* Check whether the a binding for the name to scope is known. Assumes that the bindings of the name are already a list of bindings. Returns the binding found, or NULL_TREE. */ static tree find_binding (name, scope) tree name; tree scope; { tree iter, prev = NULL_TREE; scope = ORIGINAL_NAMESPACE (scope); for (iter = IDENTIFIER_NAMESPACE_BINDINGS (name); iter; iter = TREE_CHAIN (iter)) { my_friendly_assert (TREE_CODE (iter) == CPLUS_BINDING, 374); if (BINDING_SCOPE (iter) == scope) { /* Move binding found to the fron of the list, so subsequent lookups will find it faster. */ if (prev) { TREE_CHAIN (prev) = TREE_CHAIN (iter); TREE_CHAIN (iter) = IDENTIFIER_NAMESPACE_BINDINGS (name); IDENTIFIER_NAMESPACE_BINDINGS (name) = iter; } return iter; } prev = iter; } return NULL_TREE; } /* Always returns a binding for name in scope. If the namespace_bindings is not a list, convert it to one first. If no binding is found, make a new one. */ tree binding_for_name (name, scope) tree name; tree scope; { tree b = IDENTIFIER_NAMESPACE_BINDINGS (name); tree result; scope = ORIGINAL_NAMESPACE (scope); if (b && TREE_CODE (b) != CPLUS_BINDING) { /* Get rid of optimization for global scope. */ IDENTIFIER_NAMESPACE_BINDINGS (name) = NULL_TREE; BINDING_VALUE (binding_for_name (name, global_namespace)) = b; b = IDENTIFIER_NAMESPACE_BINDINGS (name); } if (b && (result = find_binding (name, scope))) return result; /* Not found, make a new permanent one. */ push_obstacks (&permanent_obstack, &permanent_obstack); result = make_node (CPLUS_BINDING); TREE_CHAIN (result) = b; IDENTIFIER_NAMESPACE_BINDINGS (name) = result; BINDING_SCOPE (result) = scope; BINDING_TYPE (result) = NULL_TREE; BINDING_VALUE (result) = NULL_TREE; pop_obstacks (); return result; } /* Return the binding value for name in scope, considering that namespace_binding may or may not be a list of CPLUS_BINDINGS. */ tree namespace_binding (name, scope) tree name; tree scope; { tree b = IDENTIFIER_NAMESPACE_BINDINGS (name); if (b == NULL_TREE) return NULL_TREE; if (scope == NULL_TREE) scope = global_namespace; if (TREE_CODE (b) != CPLUS_BINDING) return (scope == global_namespace) ? b : NULL_TREE; name = find_binding (name,scope); if (name == NULL_TREE) return name; return BINDING_VALUE (name); } /* Set the binding value for name in scope. If modifying the binding of global_namespace is attempted, try to optimize it. */ void set_namespace_binding (name, scope, val) tree name; tree scope; tree val; { tree b; if (scope == NULL_TREE) scope = global_namespace; if (scope == global_namespace) { b = IDENTIFIER_NAMESPACE_BINDINGS (name); if (b == NULL_TREE || TREE_CODE (b) != CPLUS_BINDING) { IDENTIFIER_NAMESPACE_BINDINGS (name) = val; return; } } b = binding_for_name (name, scope); BINDING_VALUE (b) = val; } /* Push into the scope of the NAME namespace. If NAME is NULL_TREE, then we select a name that is unique to this compilation unit. */ void push_namespace (name) tree name; { tree d = NULL_TREE; int need_new = 1; int implicit_use = 0; int global = 0; if (!global_namespace) { /* This must be ::. */ my_friendly_assert (name == get_identifier ("::"), 377); global = 1; } else if (!name) { /* The name of anonymous namespace is unique for the translation unit. */ if (!anonymous_namespace_name) anonymous_namespace_name = get_file_function_name ('N'); name = anonymous_namespace_name; d = IDENTIFIER_NAMESPACE_VALUE (name); if (d) /* Reopening anonymous namespace. */ need_new = 0; implicit_use = 1; } else if (current_namespace == global_namespace && name == DECL_NAME (std_node)) { in_std++; return; } else { /* Check whether this is an extended namespace definition. */ d = IDENTIFIER_NAMESPACE_VALUE (name); if (d != NULL_TREE && TREE_CODE (d) == NAMESPACE_DECL) { need_new = 0; if (DECL_NAMESPACE_ALIAS (d)) { cp_error ("namespace alias `%D' not allowed here, assuming `%D'", d, DECL_NAMESPACE_ALIAS (d)); d = DECL_NAMESPACE_ALIAS (d); } } } if (need_new) { /* Make a new namespace, binding the name to it. */ d = build_lang_decl (NAMESPACE_DECL, name, void_type_node); /* The global namespace is not pushed, and the global binding level is set elsewhere. */ if (!global) { d = pushdecl (d); pushlevel (0); declare_namespace_level (); NAMESPACE_LEVEL (d) = current_binding_level; } } else resume_binding_level (NAMESPACE_LEVEL (d)); if (implicit_use) do_using_directive (d); /* Enter the name space. */ current_namespace = d; } /* Pop from the scope of the current namespace. */ void pop_namespace () { if (current_namespace == global_namespace) { my_friendly_assert (in_std>0, 980421); in_std--; return; } current_namespace = CP_DECL_CONTEXT (current_namespace); /* The binding level is not popped, as it might be re-opened later. */ suspend_binding_level (); } /* Subroutines for reverting temporarily to top-level for instantiation of templates and such. We actually need to clear out the class- and local-value slots of all identifiers, so that only the global values are at all visible. Simply setting current_binding_level to the global scope isn't enough, because more binding levels may be pushed. */ struct saved_scope { struct binding_level *old_binding_level; tree old_bindings; tree old_namespace; struct saved_scope *prev; tree class_name, class_type; tree access_specifier; tree function_decl; struct binding_level *class_bindings; tree *lang_base, *lang_stack, lang_name; int lang_stacksize; int minimal_parse_mode; tree last_function_parms; tree template_parms; HOST_WIDE_INT processing_template_decl; tree previous_class_type, previous_class_values; int processing_specialization; int processing_explicit_instantiation; char *class_cache_firstobj; }; static struct saved_scope *current_saved_scope; /* A chain of the binding vecs created by store_bindings. We create a whole bunch of these during compilation, on permanent_obstack, so we can't just throw them away. */ static tree free_binding_vecs; static tree store_bindings (names, old_bindings) tree names, old_bindings; { tree t; for (t = names; t; t = TREE_CHAIN (t)) { tree binding, t1, id; if (TREE_CODE (t) == TREE_LIST) id = TREE_PURPOSE (t); else id = DECL_NAME (t); if (!id /* Note that we may have an IDENTIFIER_CLASS_VALUE even when we have no IDENTIFIER_BINDING if we have left the class scope, but cached the class-level declarations. */ || !(IDENTIFIER_BINDING (id) || IDENTIFIER_CLASS_VALUE (id))) continue; for (t1 = old_bindings; t1; t1 = TREE_CHAIN (t1)) if (TREE_VEC_ELT (t1, 0) == id) goto skip_it; if (free_binding_vecs) { binding = free_binding_vecs; free_binding_vecs = TREE_CHAIN (free_binding_vecs); } else binding = make_tree_vec (4); if (id) { my_friendly_assert (TREE_CODE (id) == IDENTIFIER_NODE, 135); TREE_VEC_ELT (binding, 0) = id; TREE_VEC_ELT (binding, 1) = REAL_IDENTIFIER_TYPE_VALUE (id); TREE_VEC_ELT (binding, 2) = IDENTIFIER_BINDING (id); TREE_VEC_ELT (binding, 3) = IDENTIFIER_CLASS_VALUE (id); IDENTIFIER_BINDING (id) = NULL_TREE; IDENTIFIER_CLASS_VALUE (id) = NULL_TREE; } TREE_CHAIN (binding) = old_bindings; old_bindings = binding; skip_it: ; } return old_bindings; } void maybe_push_to_top_level (pseudo) int pseudo; { extern int current_lang_stacksize; struct saved_scope *s = (struct saved_scope *) xmalloc (sizeof (struct saved_scope)); struct binding_level *b = current_binding_level; tree old_bindings = NULL_TREE; push_cp_function_context (NULL_TREE); if (previous_class_type) old_bindings = store_bindings (previous_class_values, old_bindings); /* Have to include global_binding_level, because class-level decls aren't listed anywhere useful. */ for (; b; b = b->level_chain) { tree t; /* Template IDs are inserted into the global level. If they were inserted into namespace level, finish_file wouldn't find them when doing pending instantiations. Therefore, don't stop at namespace level, but continue until :: . */ if (b == global_binding_level || (pseudo && b->pseudo_global)) break; old_bindings = store_bindings (b->names, old_bindings); /* We also need to check class_shadowed to save class-level type bindings, since pushclass doesn't fill in b->names. */ if (b->parm_flag == 2) old_bindings = store_bindings (b->class_shadowed, old_bindings); /* Unwind type-value slots back to top level. */ for (t = b->type_shadowed; t; t = TREE_CHAIN (t)) SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (t), TREE_VALUE (t)); } s->old_binding_level = current_binding_level; current_binding_level = b; s->old_namespace = current_namespace; s->class_name = current_class_name; s->class_type = current_class_type; s->access_specifier = current_access_specifier; s->function_decl = current_function_decl; s->class_bindings = class_binding_level; s->lang_stack = current_lang_stack; s->lang_base = current_lang_base; s->lang_stacksize = current_lang_stacksize; s->lang_name = current_lang_name; s->minimal_parse_mode = minimal_parse_mode; s->last_function_parms = last_function_parms; s->template_parms = current_template_parms; s->processing_template_decl = processing_template_decl; s->previous_class_type = previous_class_type; s->previous_class_values = previous_class_values; s->class_cache_firstobj = class_cache_firstobj; s->processing_specialization = processing_specialization; s->processing_explicit_instantiation = processing_explicit_instantiation; current_class_name = current_class_type = NULL_TREE; current_function_decl = NULL_TREE; class_binding_level = (struct binding_level *)0; current_lang_stacksize = 10; current_lang_stack = current_lang_base = (tree *) xmalloc (current_lang_stacksize * sizeof (tree)); current_lang_name = lang_name_cplusplus; strict_prototype = strict_prototypes_lang_cplusplus; named_labels = NULL_TREE; shadowed_labels = NULL_TREE; minimal_parse_mode = 0; previous_class_type = previous_class_values = NULL_TREE; class_cache_firstobj = 0; processing_specialization = 0; processing_explicit_instantiation = 0; current_template_parms = NULL_TREE; processing_template_decl = 0; current_namespace = global_namespace; s->prev = current_saved_scope; s->old_bindings = old_bindings; current_saved_scope = s; push_obstacks (&permanent_obstack, &permanent_obstack); } void push_to_top_level () { maybe_push_to_top_level (0); } void pop_from_top_level () { extern int current_lang_stacksize; struct saved_scope *s = current_saved_scope; tree t; /* Clear out class-level bindings cache. */ if (previous_class_type) invalidate_class_lookup_cache (); pop_obstacks (); current_binding_level = s->old_binding_level; current_saved_scope = s->prev; for (t = s->old_bindings; t; ) { tree save = t; tree id = TREE_VEC_ELT (t, 0); if (id) { SET_IDENTIFIER_TYPE_VALUE (id, TREE_VEC_ELT (t, 1)); IDENTIFIER_BINDING (id) = TREE_VEC_ELT (t, 2); IDENTIFIER_CLASS_VALUE (id) = TREE_VEC_ELT (t, 3); } t = TREE_CHAIN (t); TREE_CHAIN (save) = free_binding_vecs; free_binding_vecs = save; } current_namespace = s->old_namespace; current_class_name = s->class_name; current_class_type = s->class_type; current_access_specifier = s->access_specifier; current_function_decl = s->function_decl; class_binding_level = s->class_bindings; free (current_lang_base); current_lang_base = s->lang_base; current_lang_stack = s->lang_stack; current_lang_name = s->lang_name; current_lang_stacksize = s->lang_stacksize; if (current_lang_name == lang_name_cplusplus) strict_prototype = strict_prototypes_lang_cplusplus; else if (current_lang_name == lang_name_c) strict_prototype = strict_prototypes_lang_c; minimal_parse_mode = s->minimal_parse_mode; last_function_parms = s->last_function_parms; current_template_parms = s->template_parms; processing_template_decl = s->processing_template_decl; previous_class_type = s->previous_class_type; previous_class_values = s->previous_class_values; processing_specialization = s->processing_specialization; processing_explicit_instantiation = s->processing_explicit_instantiation; class_cache_firstobj = s->class_cache_firstobj; free (s); pop_cp_function_context (NULL_TREE); } /* Push a definition of struct, union or enum tag "name". into binding_level "b". "type" should be the type node, We assume that the tag "name" is not already defined. Note that the definition may really be just a forward reference. In that case, the TYPE_SIZE will be a NULL_TREE. C++ gratuitously puts all these tags in the name space. */ /* When setting the IDENTIFIER_TYPE_VALUE field of an identifier ID, record the shadowed value for this binding contour. TYPE is the type that ID maps to. */ static void set_identifier_type_value_with_scope (id, type, b) tree id; tree type; struct binding_level *b; { if (!b->namespace_p) { /* Shadow the marker, not the real thing, so that the marker gets restored later. */ tree old_type_value = REAL_IDENTIFIER_TYPE_VALUE (id); b->type_shadowed = tree_cons (id, old_type_value, b->type_shadowed); } else { tree binding = binding_for_name (id, current_namespace); BINDING_TYPE (binding) = type; /* Store marker instead of real type. */ type = global_type_node; } SET_IDENTIFIER_TYPE_VALUE (id, type); } /* As set_identifier_type_value_with_scope, but using current_binding_level. */ void set_identifier_type_value (id, type) tree id; tree type; { set_identifier_type_value_with_scope (id, type, current_binding_level); } /* Return the type associated with id. */ tree identifier_type_value (id) tree id; { /* There is no type with that name, anywhere. */ if (REAL_IDENTIFIER_TYPE_VALUE (id) == NULL_TREE) return NULL_TREE; /* This is not the type marker, but the real thing. */ if (REAL_IDENTIFIER_TYPE_VALUE (id) != global_type_node) return REAL_IDENTIFIER_TYPE_VALUE (id); /* Have to search for it. It must be on the global level, now. Ask lookup_name not to return non-types. */ id = lookup_name_real (id, 2, 1, 0); if (id) return TREE_TYPE (id); return NULL_TREE; } /* Pop off extraneous binding levels left over due to syntax errors. We don't pop past namespaces, as they might be valid. */ void pop_everything () { #ifdef DEBUG_CP_BINDING_LEVELS fprintf (stderr, "XXX entering pop_everything ()\n"); #endif while (!toplevel_bindings_p ()) { if (current_binding_level->parm_flag == 2) pop_nested_class (); else poplevel (0, 0, 0); } #ifdef DEBUG_CP_BINDING_LEVELS fprintf (stderr, "XXX leaving pop_everything ()\n"); #endif } /* The type TYPE is being declared. If it is a class template, or a specialization of a class template, do any processing required and perform error-checking. If IS_FRIEND is non-zero, this TYPE is being declared a friend. B is the binding level at which this TYPE should be bound. Returns the TYPE_DECL for TYPE, which may have been altered by this processing. */ static tree maybe_process_template_type_declaration (type, globalize, b) tree type; int globalize; struct binding_level* b; { tree decl = TYPE_NAME (type); if (processing_template_parmlist) /* You can't declare a new template type in a template parameter list. But, you can declare a non-template type: template struct S; is a forward-declaration of `A'. */ ; else { maybe_check_template_type (type); my_friendly_assert (IS_AGGR_TYPE (type) || TREE_CODE (type) == ENUMERAL_TYPE, 0); if (/* If !GLOBALIZE then we are looking at a definition. It may not be a primary template. (For example, in: template struct S1 { class S2 {}; } we have to push_template_decl for S2.) */ (processing_template_decl && !globalize) /* If we are declaring a friend template class, we will have GLOBALIZE set, since something like: template struct S1 { template friend class S2; }; declares S2 to be at global scope. */ || PROCESSING_REAL_TEMPLATE_DECL_P ()) { /* This may change after the call to push_template_decl_real, but we want the original value. */ tree name = DECL_NAME (decl); decl = push_template_decl_real (decl, globalize); /* If the current binding level is the binding level for the template parameters (see the comment in begin_template_parm_list) and the enclosing level is a class scope, and we're not looking at a friend, push the declaration of the member class into the class scope. In the friend case, push_template_decl will already have put the friend into global scope, if appropriate. */ if (TREE_CODE (type) != ENUMERAL_TYPE && !globalize && b->pseudo_global && b->level_chain->parm_flag == 2) { finish_member_declaration (CLASSTYPE_TI_TEMPLATE (type)); /* Put this tag on the list of tags for the class, since that won't happen below because B is not the class binding level, but is instead the pseudo-global level. */ b->level_chain->tags = saveable_tree_cons (name, type, b->level_chain->tags); if (TYPE_SIZE (current_class_type) == NULL_TREE) CLASSTYPE_TAGS (current_class_type) = b->level_chain->tags; } } } return decl; } /* Push a tag name NAME for struct/class/union/enum type TYPE. Normally put it into the inner-most non-tag-transparent scope, but if GLOBALIZE is true, put it in the inner-most non-class scope. The latter is needed for implicit declarations. */ void pushtag (name, type, globalize) tree name, type; int globalize; { register struct binding_level *b; b = current_binding_level; while (b->tag_transparent || (globalize && b->parm_flag == 2)) b = b->level_chain; if (toplevel_bindings_p ()) b->tags = perm_tree_cons (name, type, b->tags); else b->tags = saveable_tree_cons (name, type, b->tags); if (name) { /* Do C++ gratuitous typedefing. */ if (IDENTIFIER_TYPE_VALUE (name) != type) { register tree d = NULL_TREE; int newdecl = 0, in_class = 0; tree context; tree c_decl = NULL_TREE; context = type ? TYPE_CONTEXT (type) : NULL_TREE; if (! context) { tree cs = current_scope (); if (! globalize) context = cs; else if (cs != NULL_TREE && TREE_CODE_CLASS (TREE_CODE (cs)) == 't') /* When declaring a friend class of a local class, we want to inject the newly named class into the scope containing the local class, not the namespace scope. */ context = hack_decl_function_context (get_type_decl (cs)); } if (context) c_decl = TREE_CODE (context) == FUNCTION_DECL ? context : TYPE_MAIN_DECL (context); if (!context) context = current_namespace; if ((b->pseudo_global && b->level_chain->parm_flag == 2) || b->parm_flag == 2) in_class = 1; else d = lookup_nested_type (type, c_decl); if (d == NULL_TREE) { newdecl = 1; d = build_decl (TYPE_DECL, name, type); if (current_lang_name == lang_name_java) TYPE_FOR_JAVA (type) = 1; SET_DECL_ARTIFICIAL (d); if (! in_class) set_identifier_type_value_with_scope (name, type, b); } else d = TYPE_MAIN_DECL (d); TYPE_NAME (type) = d; DECL_CONTEXT (d) = FROB_CONTEXT (context); d = maybe_process_template_type_declaration (type, globalize, b); if (b->parm_flag == 2) { if (newdecl && !PROCESSING_REAL_TEMPLATE_DECL_P ()) /* Put this TYPE_DECL on the TYPE_FIELDS list for the class. But if it's a member template class, we want the TEMPLATE_DECL, not the TYPE_DECL, so this is done later. */ finish_member_declaration (d); else pushdecl_class_level (d); } else d = pushdecl_with_scope (d, b); if (newdecl) { if (ANON_AGGRNAME_P (name)) DECL_IGNORED_P (d) = 1; TYPE_CONTEXT (type) = DECL_CONTEXT (d); DECL_ASSEMBLER_NAME (d) = DECL_NAME (d); if (!uses_template_parms (type)) DECL_ASSEMBLER_NAME (d) = get_identifier (build_overload_name (type, 1, 1)); } } if (b->parm_flag == 2) { if (TYPE_SIZE (current_class_type) == NULL_TREE) CLASSTYPE_TAGS (current_class_type) = b->tags; } } if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL) /* Use the canonical TYPE_DECL for this node. */ TYPE_STUB_DECL (type) = TYPE_NAME (type); else { /* Create a fake NULL-named TYPE_DECL node whose TREE_TYPE will be the tagged type we just added to the current binding level. This fake NULL-named TYPE_DECL node helps dwarfout.c to know when it needs to output a representation of a tagged type, and it also gives us a convenient place to record the "scope start" address for the tagged type. */ tree d = build_decl (TYPE_DECL, NULL_TREE, type); TYPE_STUB_DECL (type) = pushdecl_with_scope (d, b); } } /* Counter used to create anonymous type names. */ static int anon_cnt = 0; /* Return an IDENTIFIER which can be used as a name for anonymous structs and unions. */ tree make_anon_name () { char buf[32]; sprintf (buf, ANON_AGGRNAME_FORMAT, anon_cnt++); return get_identifier (buf); } /* Clear the TREE_PURPOSE slot of tags which have anonymous typenames. This keeps dbxout from getting confused. */ void clear_anon_tags () { register struct binding_level *b; register tree tags; static int last_cnt = 0; /* Fast out if no new anon names were declared. */ if (last_cnt == anon_cnt) return; b = current_binding_level; while (b->tag_transparent) b = b->level_chain; tags = b->tags; while (tags) { /* A NULL purpose means we have already processed all tags from here to the end of the list. */ if (TREE_PURPOSE (tags) == NULL_TREE) break; if (ANON_AGGRNAME_P (TREE_PURPOSE (tags))) TREE_PURPOSE (tags) = NULL_TREE; tags = TREE_CHAIN (tags); } last_cnt = anon_cnt; } /* Subroutine of duplicate_decls: return truthvalue of whether or not types of these decls match. For C++, we must compare the parameter list so that `int' can match `int&' in a parameter position, but `int&' is not confused with `const int&'. */ int decls_match (newdecl, olddecl) tree newdecl, olddecl; { int types_match; if (newdecl == olddecl) return 1; if (TREE_CODE (newdecl) != TREE_CODE (olddecl)) /* If the two DECLs are not even the same kind of thing, we're not interested in their types. */ return 0; if (TREE_CODE (newdecl) == FUNCTION_DECL) { tree f1 = TREE_TYPE (newdecl); tree f2 = TREE_TYPE (olddecl); tree p1 = TYPE_ARG_TYPES (f1); tree p2 = TYPE_ARG_TYPES (f2); if (DECL_REAL_CONTEXT (newdecl) != DECL_REAL_CONTEXT (olddecl) && ! (DECL_LANGUAGE (newdecl) == lang_c && DECL_LANGUAGE (olddecl) == lang_c)) return 0; /* When we parse a static member function definition, we put together a FUNCTION_DECL which thinks its type is METHOD_TYPE. Change that to FUNCTION_TYPE, and proceed. */ if (TREE_CODE (f1) == METHOD_TYPE && DECL_STATIC_FUNCTION_P (olddecl)) revert_static_member_fn (&newdecl, &f1, &p1); else if (TREE_CODE (f2) == METHOD_TYPE && DECL_STATIC_FUNCTION_P (newdecl)) revert_static_member_fn (&olddecl, &f2, &p2); /* Here we must take care of the case where new default parameters are specified. Also, warn if an old declaration becomes ambiguous because default parameters may cause the two to be ambiguous. */ if (TREE_CODE (f1) != TREE_CODE (f2)) { if (TREE_CODE (f1) == OFFSET_TYPE) cp_compiler_error ("`%D' redeclared as member function", newdecl); else cp_compiler_error ("`%D' redeclared as non-member function", newdecl); return 0; } if (same_type_p (TREE_TYPE (f1), TREE_TYPE (f2))) { if (! strict_prototypes_lang_c && DECL_LANGUAGE (olddecl) == lang_c && p2 == NULL_TREE) { types_match = self_promoting_args_p (p1); if (p1 == void_list_node) TREE_TYPE (newdecl) = TREE_TYPE (olddecl); } else if (!strict_prototypes_lang_c && DECL_LANGUAGE (olddecl)==lang_c && DECL_LANGUAGE (newdecl) == lang_c && p1 == NULL_TREE) { types_match = self_promoting_args_p (p2); TREE_TYPE (newdecl) = TREE_TYPE (olddecl); } else types_match = compparms (p1, p2); } else types_match = 0; } else if (TREE_CODE (newdecl) == TEMPLATE_DECL) { if (!comp_template_parms (DECL_TEMPLATE_PARMS (newdecl), DECL_TEMPLATE_PARMS (olddecl))) return 0; if (TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) == TYPE_DECL) types_match = 1; else types_match = decls_match (DECL_TEMPLATE_RESULT (olddecl), DECL_TEMPLATE_RESULT (newdecl)); } else { if (TREE_TYPE (newdecl) == error_mark_node) types_match = TREE_TYPE (olddecl) == error_mark_node; else if (TREE_TYPE (olddecl) == NULL_TREE) types_match = TREE_TYPE (newdecl) == NULL_TREE; else if (TREE_TYPE (newdecl) == NULL_TREE) types_match = 0; else types_match = comptypes (TREE_TYPE (newdecl), TREE_TYPE (olddecl), COMPARE_REDECLARATION); } return types_match; } /* If NEWDECL is `static' and an `extern' was seen previously, warn about it. (OLDDECL may be NULL_TREE; NAME contains information about previous usage as an `extern'.) Note that this does not apply to the C++ case of declaring a variable `extern const' and then later `const'. Don't complain about built-in functions, since they are beyond the user's control. */ static void warn_extern_redeclared_static (newdecl, olddecl) tree newdecl, olddecl; { tree name; static const char *explicit_extern_static_warning = "`%D' was declared `extern' and later `static'"; static const char *implicit_extern_static_warning = "`%D' was declared implicitly `extern' and later `static'"; if (TREE_CODE (newdecl) == TYPE_DECL) return; name = DECL_ASSEMBLER_NAME (newdecl); if (TREE_PUBLIC (name) && DECL_THIS_STATIC (newdecl)) { /* It's okay to redeclare an ANSI built-in function as static, or to declare a non-ANSI built-in function as anything. */ if (! (TREE_CODE (newdecl) == FUNCTION_DECL && olddecl != NULL_TREE && TREE_CODE (olddecl) == FUNCTION_DECL && (DECL_BUILT_IN (olddecl) || DECL_BUILT_IN_NONANSI (olddecl)))) { cp_pedwarn (IDENTIFIER_IMPLICIT_DECL (name) ? implicit_extern_static_warning : explicit_extern_static_warning, newdecl); if (olddecl != NULL_TREE) cp_pedwarn_at ("previous declaration of `%D'", olddecl); } } } /* Handle when a new declaration NEWDECL has the same name as an old one OLDDECL in the same binding contour. Prints an error message if appropriate. If safely possible, alter OLDDECL to look like NEWDECL, and return 1. Otherwise, return 0. */ int duplicate_decls (newdecl, olddecl) tree newdecl, olddecl; { extern struct obstack permanent_obstack; unsigned olddecl_uid = DECL_UID (olddecl); int olddecl_friend = 0, types_match = 0; int new_defines_function = 0; if (newdecl == olddecl) return 1; types_match = decls_match (newdecl, olddecl); /* If either the type of the new decl or the type of the old decl is an error_mark_node, then that implies that we have already issued an error (earlier) for some bogus type specification, and in that case, it is rather pointless to harass the user with yet more error message about the same declaration, so just pretend the types match here. */ if (TREE_TYPE (newdecl) == error_mark_node || TREE_TYPE (olddecl) == error_mark_node) types_match = 1; /* Check for redeclaration and other discrepancies. */ if (TREE_CODE (olddecl) == FUNCTION_DECL && DECL_ARTIFICIAL (olddecl) && (DECL_BUILT_IN (olddecl) || DECL_BUILT_IN_NONANSI (olddecl))) { /* If you declare a built-in or predefined function name as static, the old definition is overridden, but optionally warn this was a bad choice of name. Ditto for overloads. */ if (! TREE_PUBLIC (newdecl) || (TREE_CODE (newdecl) == FUNCTION_DECL && DECL_LANGUAGE (newdecl) != DECL_LANGUAGE (olddecl))) { if (warn_shadow) cp_warning ("shadowing %s function `%#D'", DECL_BUILT_IN (olddecl) ? "built-in" : "library", olddecl); /* Discard the old built-in function. */ return 0; } else if (! types_match) { if (TREE_CODE (newdecl) != FUNCTION_DECL) { /* If the built-in is not ansi, then programs can override it even globally without an error. */ if (! DECL_BUILT_IN (olddecl)) cp_warning ("library function `%#D' redeclared as non-function `%#D'", olddecl, newdecl); else { cp_error ("declaration of `%#D'", newdecl); cp_error ("conflicts with built-in declaration `%#D'", olddecl); } return 0; } cp_warning ("declaration of `%#D'", newdecl); cp_warning ("conflicts with built-in declaration `%#D'", olddecl); } } else if (TREE_CODE (olddecl) != TREE_CODE (newdecl)) { if ((TREE_CODE (olddecl) == TYPE_DECL && DECL_ARTIFICIAL (olddecl) && TREE_CODE (newdecl) != TYPE_DECL && ! (TREE_CODE (newdecl) == TEMPLATE_DECL && TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) == TYPE_DECL)) || (TREE_CODE (newdecl) == TYPE_DECL && DECL_ARTIFICIAL (newdecl) && TREE_CODE (olddecl) != TYPE_DECL && ! (TREE_CODE (olddecl) == TEMPLATE_DECL && (TREE_CODE (DECL_TEMPLATE_RESULT (olddecl)) == TYPE_DECL)))) { /* We do nothing special here, because C++ does such nasty things with TYPE_DECLs. Instead, just let the TYPE_DECL get shadowed, and know that if we need to find a TYPE_DECL for a given name, we can look in the IDENTIFIER_TYPE_VALUE slot of the identifier. */ return 0; } if ((TREE_CODE (newdecl) == FUNCTION_DECL && DECL_FUNCTION_TEMPLATE_P (olddecl)) || (TREE_CODE (olddecl) == FUNCTION_DECL && DECL_FUNCTION_TEMPLATE_P (newdecl))) return 0; cp_error ("`%#D' redeclared as different kind of symbol", newdecl); if (TREE_CODE (olddecl) == TREE_LIST) olddecl = TREE_VALUE (olddecl); cp_error_at ("previous declaration of `%#D'", olddecl); /* New decl is completely inconsistent with the old one => tell caller to replace the old one. */ return 0; } else if (!types_match) { if (DECL_REAL_CONTEXT (newdecl) != DECL_REAL_CONTEXT (olddecl)) /* These are certainly not duplicate declarations; they're from different scopes. */ return 0; if (TREE_CODE (newdecl) == TEMPLATE_DECL) { /* The name of a class template may not be declared to refer to any other template, class, function, object, namespace, value, or type in the same scope. */ if (TREE_CODE (DECL_TEMPLATE_RESULT (olddecl)) == TYPE_DECL || TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) == TYPE_DECL) { cp_error ("declaration of template `%#D'", newdecl); cp_error_at ("conflicts with previous declaration `%#D'", olddecl); } else if (TREE_CODE (DECL_TEMPLATE_RESULT (olddecl)) == FUNCTION_DECL && TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) == FUNCTION_DECL && compparms (TYPE_ARG_TYPES (TREE_TYPE (DECL_TEMPLATE_RESULT (olddecl))), TYPE_ARG_TYPES (TREE_TYPE (DECL_TEMPLATE_RESULT (newdecl)))) && comp_template_parms (DECL_TEMPLATE_PARMS (newdecl), DECL_TEMPLATE_PARMS (olddecl))) { cp_error ("new declaration `%#D'", newdecl); cp_error_at ("ambiguates old declaration `%#D'", olddecl); } return 0; } if (TREE_CODE (newdecl) == FUNCTION_DECL) { if (DECL_LANGUAGE (newdecl) == lang_c && DECL_LANGUAGE (olddecl) == lang_c) { cp_error ("declaration of C function `%#D' conflicts with", newdecl); cp_error_at ("previous declaration `%#D' here", olddecl); } else if (compparms (TYPE_ARG_TYPES (TREE_TYPE (newdecl)), TYPE_ARG_TYPES (TREE_TYPE (olddecl)))) { cp_error ("new declaration `%#D'", newdecl); cp_error_at ("ambiguates old declaration `%#D'", olddecl); } else return 0; } /* Already complained about this, so don't do so again. */ else if (current_class_type == NULL_TREE || IDENTIFIER_ERROR_LOCUS (DECL_ASSEMBLER_NAME (newdecl)) != current_class_type) { cp_error ("conflicting types for `%#D'", newdecl); cp_error_at ("previous declaration as `%#D'", olddecl); } } else if (TREE_CODE (newdecl) == FUNCTION_DECL && ((DECL_TEMPLATE_SPECIALIZATION (olddecl) && (!DECL_TEMPLATE_INFO (newdecl) || (DECL_TI_TEMPLATE (newdecl) != DECL_TI_TEMPLATE (olddecl)))) || (DECL_TEMPLATE_SPECIALIZATION (newdecl) && (!DECL_TEMPLATE_INFO (olddecl) || (DECL_TI_TEMPLATE (olddecl) != DECL_TI_TEMPLATE (newdecl)))))) /* It's OK to have a template specialization and a non-template with the same type, or to have specializations of two different templates with the same type. Note that if one is a specialization, and the other is an instantiation of the same template, that we do not exit at this point. That situation can occur if we instantiate a template class, and then specialize one of its methods. This situation is legal, but the declarations must be merged in the usual way. */ return 0; else if (TREE_CODE (newdecl) == FUNCTION_DECL && ((DECL_TEMPLATE_INSTANTIATION (olddecl) && !DECL_USE_TEMPLATE (newdecl)) || (DECL_TEMPLATE_INSTANTIATION (newdecl) && !DECL_USE_TEMPLATE (olddecl)))) /* One of the declarations is a template instantiation, and the other is not a template at all. That's OK. */ return 0; else if (TREE_CODE (newdecl) == NAMESPACE_DECL && DECL_NAMESPACE_ALIAS (newdecl) && DECL_NAMESPACE_ALIAS (newdecl) == DECL_NAMESPACE_ALIAS (olddecl)) /* Redeclaration of namespace alias, ignore it. */ return 1; else { const char *errmsg = redeclaration_error_message (newdecl, olddecl); if (errmsg) { cp_error (errmsg, newdecl); if (DECL_NAME (olddecl) != NULL_TREE) cp_error_at ((DECL_INITIAL (olddecl) && namespace_bindings_p ()) ? "`%#D' previously defined here" : "`%#D' previously declared here", olddecl); } else if (TREE_CODE (olddecl) == FUNCTION_DECL && DECL_INITIAL (olddecl) != NULL_TREE && TYPE_ARG_TYPES (TREE_TYPE (olddecl)) == NULL_TREE && TYPE_ARG_TYPES (TREE_TYPE (newdecl)) != NULL_TREE) { /* Prototype decl follows defn w/o prototype. */ cp_warning_at ("prototype for `%#D'", newdecl); cp_warning_at ("follows non-prototype definition here", olddecl); } else if (TREE_CODE (olddecl) == FUNCTION_DECL && DECL_LANGUAGE (newdecl) != DECL_LANGUAGE (olddecl)) { /* extern "C" int foo (); int foo () { bar (); } is OK. */ if (current_lang_stack == current_lang_base) DECL_LANGUAGE (newdecl) = DECL_LANGUAGE (olddecl); else { cp_error_at ("previous declaration of `%#D' with %L linkage", olddecl, DECL_LANGUAGE (olddecl)); cp_error ("conflicts with new declaration with %L linkage", DECL_LANGUAGE (newdecl)); } } if (DECL_LANG_SPECIFIC (olddecl) && DECL_USE_TEMPLATE (olddecl)) ; else if (TREE_CODE (olddecl) == FUNCTION_DECL) { tree t1 = TYPE_ARG_TYPES (TREE_TYPE (olddecl)); tree t2 = TYPE_ARG_TYPES (TREE_TYPE (newdecl)); int i = 1; if (TREE_CODE (TREE_TYPE (newdecl)) == METHOD_TYPE) t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2); for (; t1 && t1 != void_list_node; t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2), i++) if (TREE_PURPOSE (t1) && TREE_PURPOSE (t2)) { if (1 == simple_cst_equal (TREE_PURPOSE (t1), TREE_PURPOSE (t2))) { if (pedantic) { cp_pedwarn ("default argument given for parameter %d of `%#D'", i, newdecl); cp_pedwarn_at ("after previous specification in `%#D'", olddecl); } } else { cp_error ("default argument given for parameter %d of `%#D'", i, newdecl); cp_error_at ("after previous specification in `%#D'", olddecl); } } if (DECL_THIS_INLINE (newdecl) && ! DECL_THIS_INLINE (olddecl) && TREE_ADDRESSABLE (olddecl) && warn_inline) { cp_warning ("`%#D' was used before it was declared inline", newdecl); cp_warning_at ("previous non-inline declaration here", olddecl); } } } /* If new decl is `static' and an `extern' was seen previously, warn about it. */ warn_extern_redeclared_static (newdecl, olddecl); /* We have committed to returning 1 at this point. */ if (TREE_CODE (newdecl) == FUNCTION_DECL) { /* Now that functions must hold information normally held by field decls, there is extra work to do so that declaration information does not get destroyed during definition. */ if (DECL_VINDEX (olddecl)) DECL_VINDEX (newdecl) = DECL_VINDEX (olddecl); if (DECL_CONTEXT (olddecl)) DECL_CONTEXT (newdecl) = DECL_CONTEXT (olddecl); if (DECL_CLASS_CONTEXT (olddecl)) DECL_CLASS_CONTEXT (newdecl) = DECL_CLASS_CONTEXT (olddecl); if (DECL_PENDING_INLINE_INFO (newdecl) == (struct pending_inline *)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); DECL_ABSTRACT_VIRTUAL_P (newdecl) |= DECL_ABSTRACT_VIRTUAL_P (olddecl); DECL_VIRTUAL_P (newdecl) |= DECL_VIRTUAL_P (olddecl); DECL_NEEDS_FINAL_OVERRIDER_P (newdecl) |= DECL_NEEDS_FINAL_OVERRIDER_P (olddecl); new_defines_function = DECL_INITIAL (newdecl) != NULL_TREE; /* Optionally warn about more than one declaration for the same name, but don't warn about a function declaration followed by a definition. */ if (warn_redundant_decls && ! DECL_ARTIFICIAL (olddecl) && !(new_defines_function && DECL_INITIAL (olddecl) == NULL_TREE) /* Don't warn about extern decl followed by definition. */ && !(DECL_EXTERNAL (olddecl) && ! DECL_EXTERNAL (newdecl)) /* Don't warn about friends, let add_friend take care of it. */ && ! DECL_FRIEND_P (newdecl)) { cp_warning ("redundant redeclaration of `%D' in same scope", newdecl); cp_warning_at ("previous declaration of `%D'", olddecl); } } /* Deal with C++: must preserve virtual function table size. */ if (TREE_CODE (olddecl) == TYPE_DECL) { register tree newtype = TREE_TYPE (newdecl); register tree oldtype = TREE_TYPE (olddecl); if (newtype != error_mark_node && oldtype != error_mark_node && TYPE_LANG_SPECIFIC (newtype) && TYPE_LANG_SPECIFIC (oldtype)) { CLASSTYPE_VSIZE (newtype) = CLASSTYPE_VSIZE (oldtype); CLASSTYPE_FRIEND_CLASSES (newtype) = CLASSTYPE_FRIEND_CLASSES (oldtype); } } /* Copy all the DECL_... slots specified in the new decl except for any that we copy here from the old type. */ DECL_MACHINE_ATTRIBUTES (newdecl) = merge_machine_decl_attributes (olddecl, newdecl); if (TREE_CODE (newdecl) == TEMPLATE_DECL) { if (! duplicate_decls (DECL_TEMPLATE_RESULT (newdecl), DECL_TEMPLATE_RESULT (olddecl))) cp_error ("invalid redeclaration of %D", newdecl); TREE_TYPE (olddecl) = TREE_TYPE (DECL_TEMPLATE_RESULT (olddecl)); DECL_TEMPLATE_SPECIALIZATIONS (olddecl) = chainon (DECL_TEMPLATE_SPECIALIZATIONS (olddecl), DECL_TEMPLATE_SPECIALIZATIONS (newdecl)); return 1; } if (types_match) { /* Automatically handles default parameters. */ tree oldtype = TREE_TYPE (olddecl); tree newtype; /* Make sure we put the new type in the same obstack as the old one. */ if (oldtype) push_obstacks (TYPE_OBSTACK (oldtype), TYPE_OBSTACK (oldtype)); else { push_obstacks_nochange (); end_temporary_allocation (); } /* Merge the data types specified in the two decls. */ newtype = common_type (TREE_TYPE (newdecl), TREE_TYPE (olddecl)); if (TREE_CODE (newdecl) == VAR_DECL) DECL_THIS_EXTERN (newdecl) |= DECL_THIS_EXTERN (olddecl); /* Do this after calling `common_type' so that default parameters don't confuse us. */ else if (TREE_CODE (newdecl) == FUNCTION_DECL && (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (newdecl)) != TYPE_RAISES_EXCEPTIONS (TREE_TYPE (olddecl)))) { TREE_TYPE (newdecl) = build_exception_variant (newtype, TYPE_RAISES_EXCEPTIONS (TREE_TYPE (newdecl))); TREE_TYPE (olddecl) = build_exception_variant (newtype, TYPE_RAISES_EXCEPTIONS (oldtype)); if ((pedantic || (! DECL_IN_SYSTEM_HEADER (olddecl) && ! DECL_IN_SYSTEM_HEADER (newdecl))) && DECL_SOURCE_LINE (olddecl) != 0 && flag_exceptions && ! compexcepttypes (TREE_TYPE (newdecl), TREE_TYPE (olddecl))) { cp_pedwarn ("declaration of `%D' throws different exceptions", newdecl); cp_pedwarn_at ("previous declaration here", olddecl); } } TREE_TYPE (newdecl) = TREE_TYPE (olddecl) = newtype; /* Lay the type out, unless already done. */ if (! same_type_p (newtype, oldtype) && TREE_TYPE (newdecl) != error_mark_node && !(processing_template_decl && uses_template_parms (newdecl))) layout_type (TREE_TYPE (newdecl)); if ((TREE_CODE (newdecl) == VAR_DECL || TREE_CODE (newdecl) == PARM_DECL || TREE_CODE (newdecl) == RESULT_DECL || TREE_CODE (newdecl) == FIELD_DECL || TREE_CODE (newdecl) == TYPE_DECL) && !(processing_template_decl && uses_template_parms (newdecl))) layout_decl (newdecl, 0); /* Merge the type qualifiers. */ if (TREE_READONLY (newdecl)) TREE_READONLY (olddecl) = 1; if (TREE_THIS_VOLATILE (newdecl)) TREE_THIS_VOLATILE (olddecl) = 1; /* Merge the initialization information. */ if (DECL_INITIAL (newdecl) == NULL_TREE && DECL_INITIAL (olddecl) != NULL_TREE) { DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl); DECL_SOURCE_FILE (newdecl) = DECL_SOURCE_FILE (olddecl); DECL_SOURCE_LINE (newdecl) = DECL_SOURCE_LINE (olddecl); if (DECL_LANG_SPECIFIC (newdecl) && DECL_LANG_SPECIFIC (olddecl)) DECL_SAVED_TREE (newdecl) = DECL_SAVED_TREE (olddecl); } /* Merge the section attribute. We want to issue an error if the sections conflict but that must be done later in decl_attributes since we are called before attributes are assigned. */ if (DECL_SECTION_NAME (newdecl) == NULL_TREE) DECL_SECTION_NAME (newdecl) = DECL_SECTION_NAME (olddecl); /* Keep the old rtl since we can safely use it, unless it's the call to abort() used for abstract virtuals. */ if ((DECL_LANG_SPECIFIC (olddecl) && !DECL_ABSTRACT_VIRTUAL_P (olddecl)) || DECL_RTL (olddecl) != DECL_RTL (abort_fndecl)) DECL_RTL (newdecl) = DECL_RTL (olddecl); pop_obstacks (); } /* If cannot merge, then use the new type and qualifiers, and don't preserve the old rtl. */ else { /* Clean out any memory we had of the old declaration. */ tree oldstatic = value_member (olddecl, static_aggregates); if (oldstatic) TREE_VALUE (oldstatic) = error_mark_node; TREE_TYPE (olddecl) = TREE_TYPE (newdecl); TREE_READONLY (olddecl) = TREE_READONLY (newdecl); TREE_THIS_VOLATILE (olddecl) = TREE_THIS_VOLATILE (newdecl); TREE_SIDE_EFFECTS (olddecl) = TREE_SIDE_EFFECTS (newdecl); } /* Merge the storage class information. */ DECL_WEAK (newdecl) |= DECL_WEAK (olddecl); DECL_ONE_ONLY (newdecl) |= DECL_ONE_ONLY (olddecl); TREE_PUBLIC (newdecl) = TREE_PUBLIC (olddecl); TREE_STATIC (olddecl) = TREE_STATIC (newdecl) |= TREE_STATIC (olddecl); if (! DECL_EXTERNAL (olddecl)) DECL_EXTERNAL (newdecl) = 0; if (DECL_LANG_SPECIFIC (newdecl) && DECL_LANG_SPECIFIC (olddecl)) { DECL_INTERFACE_KNOWN (newdecl) |= DECL_INTERFACE_KNOWN (olddecl); DECL_NOT_REALLY_EXTERN (newdecl) |= DECL_NOT_REALLY_EXTERN (olddecl); DECL_COMDAT (newdecl) |= DECL_COMDAT (olddecl); DECL_TEMPLATE_INSTANTIATED (newdecl) |= DECL_TEMPLATE_INSTANTIATED (olddecl); /* Don't really know how much of the language-specific values we should copy from old to new. */ DECL_IN_AGGR_P (newdecl) = DECL_IN_AGGR_P (olddecl); DECL_ACCESS (newdecl) = DECL_ACCESS (olddecl); DECL_NONCONVERTING_P (newdecl) = DECL_NONCONVERTING_P (olddecl); DECL_TEMPLATE_INFO (newdecl) = DECL_TEMPLATE_INFO (olddecl); olddecl_friend = DECL_FRIEND_P (olddecl); /* Only functions have DECL_BEFRIENDING_CLASSES. */ if (TREE_CODE (newdecl) == FUNCTION_DECL || DECL_FUNCTION_TEMPLATE_P (newdecl)) DECL_BEFRIENDING_CLASSES (newdecl) = chainon (DECL_BEFRIENDING_CLASSES (newdecl), DECL_BEFRIENDING_CLASSES (olddecl)); } if (TREE_CODE (newdecl) == FUNCTION_DECL) { if (DECL_TEMPLATE_INSTANTIATION (olddecl) && !DECL_TEMPLATE_INSTANTIATION (newdecl)) { /* If newdecl is not a specialization, then it is not a template-related function at all. And that means that we shoud have exited above, returning 0. */ my_friendly_assert (DECL_TEMPLATE_SPECIALIZATION (newdecl), 0); if (TREE_USED (olddecl)) /* From [temp.expl.spec]: If a template, a member template or the member of a class template is explicitly specialized then that specialization shall be declared before the first use of that specialization that would cause an implicit instantiation to take place, in every translation unit in which such a use occurs. */ cp_error ("explicit specialization of %D after first use", olddecl); SET_DECL_TEMPLATE_SPECIALIZATION (olddecl); } DECL_THIS_INLINE (newdecl) |= DECL_THIS_INLINE (olddecl); /* If either decl says `inline', this fn is inline, unless its definition was passed already. */ if (DECL_INLINE (newdecl) && DECL_INITIAL (olddecl) == NULL_TREE) DECL_INLINE (olddecl) = 1; DECL_INLINE (newdecl) = DECL_INLINE (olddecl); if (! types_match) { DECL_LANGUAGE (olddecl) = DECL_LANGUAGE (newdecl); DECL_ASSEMBLER_NAME (olddecl) = DECL_ASSEMBLER_NAME (newdecl); DECL_RTL (olddecl) = DECL_RTL (newdecl); } if (! types_match || new_defines_function) { /* These need to be copied so that the names are available. */ DECL_ARGUMENTS (olddecl) = DECL_ARGUMENTS (newdecl); DECL_RESULT (olddecl) = DECL_RESULT (newdecl); } if (new_defines_function) /* If defining a function declared with other language linkage, use the previously declared language linkage. */ DECL_LANGUAGE (newdecl) = DECL_LANGUAGE (olddecl); else { /* If redeclaring a builtin function, and not a definition, it stays built in. */ if (DECL_BUILT_IN (olddecl)) { DECL_BUILT_IN (newdecl) = 1; DECL_FUNCTION_CODE (newdecl) = DECL_FUNCTION_CODE (olddecl); /* If we're keeping the built-in definition, keep the rtl, regardless of declaration matches. */ DECL_RTL (newdecl) = DECL_RTL (olddecl); } else DECL_FRAME_SIZE (newdecl) = DECL_FRAME_SIZE (olddecl); DECL_RESULT (newdecl) = DECL_RESULT (olddecl); if ((DECL_SAVED_INSNS (newdecl) = DECL_SAVED_INSNS (olddecl))) /* Previously saved insns go together with the function's previous definition. */ DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl); /* Don't clear out the arguments if we're redefining a function. */ if (DECL_ARGUMENTS (olddecl)) DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl); } if (DECL_LANG_SPECIFIC (olddecl)) DECL_MAIN_VARIANT (newdecl) = DECL_MAIN_VARIANT (olddecl); } if (TREE_CODE (newdecl) == NAMESPACE_DECL) { NAMESPACE_LEVEL (newdecl) = NAMESPACE_LEVEL (olddecl); } /* Now preserve various other info from the definition. */ TREE_ADDRESSABLE (newdecl) = TREE_ADDRESSABLE (olddecl); TREE_ASM_WRITTEN (newdecl) = TREE_ASM_WRITTEN (olddecl); DECL_COMMON (newdecl) = DECL_COMMON (olddecl); DECL_ASSEMBLER_NAME (newdecl) = DECL_ASSEMBLER_NAME (olddecl); if (TREE_CODE (newdecl) == FUNCTION_DECL) { int function_size; struct lang_decl *ol = DECL_LANG_SPECIFIC (olddecl); struct lang_decl *nl = DECL_LANG_SPECIFIC (newdecl); function_size = sizeof (struct tree_decl); bcopy ((char *) newdecl + sizeof (struct tree_common), (char *) olddecl + sizeof (struct tree_common), function_size - sizeof (struct tree_common)); /* Can we safely free the storage used by newdecl? */ #define ROUND(x) ((x + obstack_alignment_mask (&permanent_obstack)) \ & ~ obstack_alignment_mask (&permanent_obstack)) if (DECL_TEMPLATE_INSTANTIATION (newdecl)) { /* If newdecl is a template instantiation, it is possible that the following sequence of events has occurred: o A friend function was declared in a class template. The class template was instantiated. o The instantiation of the friend declaration was recorded on the instantiation list, and is newdecl. o Later, however, instantiate_class_template called pushdecl on the newdecl to perform name injection. But, pushdecl in turn called duplicate_decls when it discovered that another declaration of a global function with the same name already existed. o Here, in duplicate_decls, we decided to clobber newdecl. If we're going to do that, we'd better make sure that olddecl, and not newdecl, is on the list of instantiations so that if we try to do the instantiation again we won't get the clobbered declaration. */ tree tmpl = DECL_TI_TEMPLATE (newdecl); tree decls = DECL_TEMPLATE_SPECIALIZATIONS (tmpl); for (; decls; decls = TREE_CHAIN (decls)) if (TREE_VALUE (decls) == newdecl) TREE_VALUE (decls) = olddecl; } if (((char *)newdecl + ROUND (function_size) == (char *)nl && ((char *)newdecl + ROUND (function_size) + ROUND (sizeof (struct lang_decl)) == obstack_next_free (&permanent_obstack))) || ((char *)newdecl + ROUND (function_size) == obstack_next_free (&permanent_obstack))) { DECL_MAIN_VARIANT (newdecl) = olddecl; DECL_LANG_SPECIFIC (olddecl) = ol; bcopy ((char *)nl, (char *)ol, sizeof (struct lang_decl)); obstack_free (&permanent_obstack, newdecl); } else if (LANG_DECL_PERMANENT (ol) && ol != nl) { if (DECL_MAIN_VARIANT (olddecl) == olddecl) { /* Save these lang_decls that would otherwise be lost. */ extern tree free_lang_decl_chain; tree free_lang_decl = (tree) ol; if (DECL_LANG_SPECIFIC (olddecl) == ol) abort (); TREE_CHAIN (free_lang_decl) = free_lang_decl_chain; free_lang_decl_chain = free_lang_decl; } else { /* Storage leak. */; } } } else { bcopy ((char *) newdecl + sizeof (struct tree_common), (char *) olddecl + sizeof (struct tree_common), sizeof (struct tree_decl) - sizeof (struct tree_common) + tree_code_length [(int)TREE_CODE (newdecl)] * sizeof (char *)); } DECL_UID (olddecl) = olddecl_uid; if (olddecl_friend) DECL_FRIEND_P (olddecl) = 1; /* NEWDECL contains the merged attribute lists. Update OLDDECL to be the same. */ DECL_MACHINE_ATTRIBUTES (olddecl) = DECL_MACHINE_ATTRIBUTES (newdecl); return 1; } /* Record a decl-node X as belonging to the current lexical scope. Check for errors (such as an incompatible declaration for the same name already seen in the same scope). Returns either X or an old decl for the same name. If an old decl is returned, it may have been smashed to agree with what X says. */ tree pushdecl (x) tree x; { register tree t; register tree name = DECL_ASSEMBLER_NAME (x); int need_new_binding = 1; if (DECL_TEMPLATE_PARM_P (x)) /* Template parameters have no context; they are not X::T even when declared within a class or namespace. */ ; else { if (current_function_decl && x != current_function_decl /* A local declaration for a function doesn't constitute nesting. */ && (TREE_CODE (x) != FUNCTION_DECL || DECL_INITIAL (x)) /* Don't change DECL_CONTEXT of virtual methods. */ && (TREE_CODE (x) != FUNCTION_DECL || !DECL_VIRTUAL_P (x)) && !DECL_CONTEXT (x)) DECL_CONTEXT (x) = current_function_decl; if (!DECL_CONTEXT (x)) DECL_CONTEXT (x) = FROB_CONTEXT (current_namespace); } /* Type are looked up using the DECL_NAME, as that is what the rest of the compiler wants to use. */ if (TREE_CODE (x) == TYPE_DECL || TREE_CODE (x) == VAR_DECL || TREE_CODE (x) == NAMESPACE_DECL) name = DECL_NAME (x); if (name) { #if 0 /* Not needed...see below. */ char *file; int line; #endif if (TREE_CODE (name) == TEMPLATE_ID_EXPR) name = TREE_OPERAND (name, 0); /* Namespace-scoped variables are not found in the current level. */ if (TREE_CODE (x) == VAR_DECL && DECL_NAMESPACE_SCOPE_P (x)) t = namespace_binding (name, DECL_CONTEXT (x)); else t = lookup_name_current_level (name); if (t == error_mark_node) { /* error_mark_node is 0 for a while during initialization! */ t = NULL_TREE; cp_error_at ("`%#D' used prior to declaration", x); } else if (t != NULL_TREE) { #if 0 /* This is turned off until I have time to do it right (bpk). */ /* With the code below that uses it... */ file = DECL_SOURCE_FILE (t); line = DECL_SOURCE_LINE (t); #endif if (TREE_CODE (t) == PARM_DECL) { if (DECL_CONTEXT (t) == NULL_TREE) fatal ("parse errors have confused me too much"); /* Check for duplicate params. */ if (duplicate_decls (x, t)) return t; } else if (((TREE_CODE (x) == FUNCTION_DECL && DECL_LANGUAGE (x) == lang_c) || DECL_FUNCTION_TEMPLATE_P (x)) && is_overloaded_fn (t)) /* Don't do anything just yet. */; else if (t == wchar_decl_node) { if (pedantic && ! DECL_IN_SYSTEM_HEADER (x)) cp_pedwarn ("redeclaration of wchar_t as `%T'", TREE_TYPE (x)); /* Throw away the redeclaration. */ return t; } else if (TREE_CODE (t) != TREE_CODE (x)) { if (duplicate_decls (x, t)) return t; } else if (duplicate_decls (x, t)) { #if 0 /* This is turned off until I have time to do it right (bpk). */ /* Also warn if they did a prototype with `static' on it, but then later left the `static' off. */ if (! TREE_PUBLIC (name) && TREE_PUBLIC (x)) { if (DECL_LANG_SPECIFIC (t) && DECL_FRIEND_P (t)) return t; if (extra_warnings) { cp_warning ("`static' missing from declaration of `%D'", t); warning_with_file_and_line (file, line, "previous declaration of `%s'", decl_as_string (t, 0)); } /* Now fix things so it'll do what they expect. */ if (current_function_decl) TREE_PUBLIC (current_function_decl) = 0; } /* Due to interference in memory reclamation (X may be obstack-deallocated at this point), we must guard against one really special case. [jason: This should be handled by start_function] */ if (current_function_decl == x) current_function_decl = t; #endif if (TREE_CODE (t) == TYPE_DECL) SET_IDENTIFIER_TYPE_VALUE (name, TREE_TYPE (t)); else if (TREE_CODE (t) == FUNCTION_DECL) check_default_args (t); return t; } else if (DECL_MAIN_P (x)) { /* A redeclaration of main, but not a duplicate of the previous one. [basic.start.main] This function shall not be overloaded. */ cp_error_at ("invalid redeclaration of `%D'", t); cp_error ("as `%D'", x); /* We don't try to push this declaration since that causes a crash. */ return x; } } check_template_shadow (x); /* If this is a function conjured up by the backend, massage it so it looks friendly. */ if (TREE_CODE (x) == FUNCTION_DECL && ! DECL_LANG_SPECIFIC (x)) { retrofit_lang_decl (x); DECL_LANGUAGE (x) = lang_c; } if (TREE_CODE (x) == FUNCTION_DECL && ! DECL_FUNCTION_MEMBER_P (x)) { t = push_overloaded_decl (x, PUSH_LOCAL); if (t != x || DECL_LANGUAGE (x) == lang_c) return t; if (!namespace_bindings_p ()) /* We do not need to create a binding for this name; push_overloaded_decl will have already done so if necessary. */ need_new_binding = 0; } else if (DECL_FUNCTION_TEMPLATE_P (x) && DECL_NAMESPACE_SCOPE_P (x)) return push_overloaded_decl (x, PUSH_GLOBAL); /* If declaring a type as a typedef, copy the type (unless we're at line 0), and install this TYPE_DECL as the new type's typedef name. See the extensive comment in ../c-decl.c (pushdecl). */ if (TREE_CODE (x) == TYPE_DECL) { tree type = TREE_TYPE (x); if (DECL_SOURCE_LINE (x) == 0) { if (TYPE_NAME (type) == 0) TYPE_NAME (type) = x; } else if (type != error_mark_node && TYPE_NAME (type) != x /* We don't want to copy the type when all we're doing is making a TYPE_DECL for the purposes of inlining. */ && (!TYPE_NAME (type) || TYPE_NAME (type) != DECL_ABSTRACT_ORIGIN (x))) { push_obstacks (TYPE_OBSTACK (type), TYPE_OBSTACK (type)); DECL_ORIGINAL_TYPE (x) = type; type = build_type_copy (type); TYPE_STUB_DECL (type) = TYPE_STUB_DECL (DECL_ORIGINAL_TYPE (x)); TYPE_NAME (type) = x; TREE_TYPE (x) = type; pop_obstacks (); } if (type != error_mark_node && TYPE_NAME (type) && TYPE_IDENTIFIER (type)) set_identifier_type_value_with_scope (DECL_NAME (x), type, current_binding_level); } /* Multiple external decls of the same identifier ought to match. We get warnings about inline functions where they are defined. We get warnings about other functions from push_overloaded_decl. Avoid duplicate warnings where they are used. */ if (TREE_PUBLIC (x) && TREE_CODE (x) != FUNCTION_DECL) { tree decl; if (IDENTIFIER_NAMESPACE_VALUE (name) != NULL_TREE && (DECL_EXTERNAL (IDENTIFIER_NAMESPACE_VALUE (name)) || TREE_PUBLIC (IDENTIFIER_NAMESPACE_VALUE (name)))) decl = IDENTIFIER_NAMESPACE_VALUE (name); else decl = NULL_TREE; if (decl /* If different sort of thing, we already gave an error. */ && TREE_CODE (decl) == TREE_CODE (x) && !same_type_p (TREE_TYPE (x), TREE_TYPE (decl))) { cp_pedwarn ("type mismatch with previous external decl", x); cp_pedwarn_at ("previous external decl of `%#D'", decl); } } /* This name is new in its binding level. Install the new declaration and return it. */ if (namespace_bindings_p ()) { /* Install a global value. */ /* If the first global decl has external linkage, warn if we later see static one. */ if (IDENTIFIER_GLOBAL_VALUE (name) == NULL_TREE && TREE_PUBLIC (x)) TREE_PUBLIC (name) = 1; if (!(TREE_CODE (x) == TYPE_DECL && DECL_ARTIFICIAL (x) && t != NULL_TREE)) { if (TREE_CODE (x) == FUNCTION_DECL) my_friendly_assert ((IDENTIFIER_GLOBAL_VALUE (name) == NULL_TREE) || (IDENTIFIER_GLOBAL_VALUE (name) == x), 378); SET_IDENTIFIER_NAMESPACE_VALUE (name, x); } /* Don't forget if the function was used via an implicit decl. */ if (IDENTIFIER_IMPLICIT_DECL (name) && TREE_USED (IDENTIFIER_IMPLICIT_DECL (name))) TREE_USED (x) = 1; /* Don't forget if its address was taken in that way. */ if (IDENTIFIER_IMPLICIT_DECL (name) && TREE_ADDRESSABLE (IDENTIFIER_IMPLICIT_DECL (name))) TREE_ADDRESSABLE (x) = 1; /* Warn about mismatches against previous implicit decl. */ if (IDENTIFIER_IMPLICIT_DECL (name) != NULL_TREE /* If this real decl matches the implicit, don't complain. */ && ! (TREE_CODE (x) == FUNCTION_DECL && TREE_TYPE (TREE_TYPE (x)) == integer_type_node)) cp_warning ("`%D' was previously implicitly declared to return `int'", x); /* If new decl is `static' and an `extern' was seen previously, warn about it. */ if (x != NULL_TREE && t != NULL_TREE && decls_match (x, t)) warn_extern_redeclared_static (x, t); } else { /* Here to install a non-global value. */ tree oldlocal = IDENTIFIER_VALUE (name); tree oldglobal = IDENTIFIER_NAMESPACE_VALUE (name); if (need_new_binding) { push_local_binding (name, x, 0); /* Because push_local_binding will hook X on to the current_binding_level's name list, we don't want to do that again below. */ need_new_binding = 0; } /* If this is a TYPE_DECL, push it into the type value slot. */ if (TREE_CODE (x) == TYPE_DECL) set_identifier_type_value_with_scope (name, TREE_TYPE (x), current_binding_level); /* Clear out any TYPE_DECL shadowed by a namespace so that we won't think this is a type. The C struct hack doesn't go through namespaces. */ if (TREE_CODE (x) == NAMESPACE_DECL) set_identifier_type_value_with_scope (name, NULL_TREE, current_binding_level); /* If this is an extern function declaration, see if we have a global definition or declaration for the function. */ if (oldlocal == NULL_TREE && DECL_EXTERNAL (x) && oldglobal != NULL_TREE && TREE_CODE (x) == FUNCTION_DECL && TREE_CODE (oldglobal) == FUNCTION_DECL) { /* We have one. Their types must agree. */ if (decls_match (x, oldglobal)) /* OK */; else { cp_warning ("extern declaration of `%#D' doesn't match", x); cp_warning_at ("global declaration `%#D'", oldglobal); } } /* If we have a local external declaration, and no file-scope declaration has yet been seen, then if we later have a file-scope decl it must not be static. */ if (oldlocal == NULL_TREE && oldglobal == NULL_TREE && DECL_EXTERNAL (x) && TREE_PUBLIC (x)) TREE_PUBLIC (name) = 1; if (DECL_FROM_INLINE (x)) /* Inline decls shadow nothing. */; /* Warn if shadowing an argument at the top level of the body. */ else if (oldlocal != NULL_TREE && !DECL_EXTERNAL (x) && TREE_CODE (oldlocal) == PARM_DECL /* Don't complain if it's from an enclosing function. */ && DECL_CONTEXT (oldlocal) == current_function_decl && TREE_CODE (x) != PARM_DECL) { /* Go to where the parms should be and see if we find them there. */ struct binding_level *b = current_binding_level->level_chain; if (cleanup_label) b = b->level_chain; /* ARM $8.3 */ if (b->parm_flag == 1) cp_error ("declaration of `%#D' shadows a parameter", name); } else if (warn_shadow && oldlocal != NULL_TREE && current_binding_level->is_for_scope && !DECL_DEAD_FOR_LOCAL (oldlocal)) { warning ("variable `%s' shadows local", IDENTIFIER_POINTER (name)); cp_warning_at (" this is the shadowed declaration", oldlocal); } /* Maybe warn if shadowing something else. */ else if (warn_shadow && !DECL_EXTERNAL (x) /* No shadow warnings for internally generated vars. */ && ! DECL_ARTIFICIAL (x) /* No shadow warnings for vars made for inlining. */ && ! DECL_FROM_INLINE (x)) { const char *warnstring = NULL; if (oldlocal != NULL_TREE && TREE_CODE (oldlocal) == PARM_DECL) warnstring = "declaration of `%s' shadows a parameter"; else if (IDENTIFIER_CLASS_VALUE (name) != NULL_TREE && current_class_ptr && !TREE_STATIC (name)) warnstring = "declaration of `%s' shadows a member of `this'"; else if (oldlocal != NULL_TREE) warnstring = "declaration of `%s' shadows previous local"; else if (oldglobal != NULL_TREE) /* XXX shadow warnings in outer-more namespaces */ warnstring = "declaration of `%s' shadows global declaration"; if (warnstring) warning (warnstring, IDENTIFIER_POINTER (name)); } } if (TREE_CODE (x) == FUNCTION_DECL) check_default_args (x); /* Keep count of variables in this level with incomplete type. */ if (TREE_CODE (x) == VAR_DECL && TREE_TYPE (x) != error_mark_node && ((TYPE_SIZE (TREE_TYPE (x)) == NULL_TREE && PROMOTES_TO_AGGR_TYPE (TREE_TYPE (x), ARRAY_TYPE)) /* RTTI TD entries are created while defining the type_info. */ || (TYPE_LANG_SPECIFIC (TREE_TYPE (x)) && TYPE_BEING_DEFINED (TREE_TYPE (x))))) current_binding_level->incomplete = tree_cons (NULL_TREE, x, current_binding_level->incomplete); } if (need_new_binding) { /* Put decls on list in reverse order. We will reverse them later if necessary. */ TREE_CHAIN (x) = current_binding_level->names; current_binding_level->names = x; if (current_binding_level == global_binding_level && !TREE_PERMANENT (x)) my_friendly_abort (124); } return x; } /* Same as pushdecl, but define X in binding-level LEVEL. We rely on the caller to set DECL_CONTEXT properly. */ static tree pushdecl_with_scope (x, level) tree x; struct binding_level *level; { register struct binding_level *b; tree function_decl = current_function_decl; current_function_decl = NULL_TREE; if (level->parm_flag == 2) { b = class_binding_level; class_binding_level = level; pushdecl_class_level (x); class_binding_level = b; } else { b = current_binding_level; current_binding_level = level; x = pushdecl (x); current_binding_level = b; } current_function_decl = function_decl; return x; } /* Like pushdecl, only it places X in the current namespace, if appropriate. */ tree pushdecl_namespace_level (x) tree x; { register struct binding_level *b = current_binding_level; register tree t; t = pushdecl_with_scope (x, NAMESPACE_LEVEL (current_namespace)); /* Now, the type_shadowed stack may screw us. Munge it so it does what we want. */ if (TREE_CODE (x) == TYPE_DECL) { tree name = DECL_NAME (x); tree newval; tree *ptr = (tree *)0; for (; b != global_binding_level; b = b->level_chain) { tree shadowed = b->type_shadowed; for (; shadowed; shadowed = TREE_CHAIN (shadowed)) if (TREE_PURPOSE (shadowed) == name) { ptr = &TREE_VALUE (shadowed); /* Can't break out of the loop here because sometimes a binding level will have duplicate bindings for PT names. It's gross, but I haven't time to fix it. */ } } newval = TREE_TYPE (x); if (ptr == (tree *)0) { /* @@ This shouldn't be needed. My test case "zstring.cc" trips up here if this is changed to an assertion. --KR */ SET_IDENTIFIER_TYPE_VALUE (name, newval); } else { *ptr = newval; } } return t; } /* Like pushdecl, only it places X in GLOBAL_BINDING_LEVEL, if appropriate. */ tree pushdecl_top_level (x) tree x; { tree cur_namespace = current_namespace; current_namespace = global_namespace; x = pushdecl_namespace_level (x); current_namespace = cur_namespace; return x; } /* Make the declaration of X appear in CLASS scope. */ void pushdecl_class_level (x) tree x; { /* Don't use DECL_ASSEMBLER_NAME here! Everything that looks in class scope looks for the pre-mangled name. */ register tree name; if (TREE_CODE (x) == OVERLOAD) x = OVL_CURRENT (x); name = DECL_NAME (x); if (name) { push_class_level_binding (name, x); if (TREE_CODE (x) == TYPE_DECL) set_identifier_type_value (name, TREE_TYPE (x)); } else if (ANON_UNION_TYPE_P (TREE_TYPE (x))) { tree f; for (f = TYPE_FIELDS (TREE_TYPE (x)); f; f = TREE_CHAIN (f)) pushdecl_class_level (f); } } #if 0 /* This function is used to push the mangled decls for nested types into the appropriate scope. Previously pushdecl_top_level was used, but that is incorrect for members of local classes. */ void pushdecl_nonclass_level (x) tree x; { struct binding_level *b = current_binding_level; my_friendly_assert (b->parm_flag != 2, 180); #if 0 /* Get out of template binding levels */ while (b->pseudo_global) b = b->level_chain; #endif pushdecl_with_scope (x, b); } #endif /* Make the declaration(s) of X appear in CLASS scope under the name NAME. */ void push_class_level_binding (name, x) tree name; tree x; { tree binding; /* The class_binding_level will be NULL if x is a template parameter name in a member template. */ if (!class_binding_level) return; /* Make sure that this new member does not have the same name as a template parameter. */ if (TYPE_BEING_DEFINED (current_class_type)) check_template_shadow (x); /* If this declaration shadows a declaration from an enclosing class, then we will need to restore IDENTIFIER_CLASS_VALUE when we leave this class. Record the shadowed declaration here. */ binding = IDENTIFIER_BINDING (name); if (binding && ((TREE_CODE (x) == OVERLOAD && BINDING_VALUE (binding) && is_overloaded_fn (BINDING_VALUE (binding))) || INHERITED_VALUE_BINDING_P (binding))) { tree shadow; tree old_decl; /* If the old binding was from a base class, and was for a tag name, slide it over to make room for the new binding. The old binding is still visible if explicitly qualified with a class-key. */ if (INHERITED_VALUE_BINDING_P (binding) && BINDING_VALUE (binding) && TREE_CODE (BINDING_VALUE (binding)) == TYPE_DECL && DECL_ARTIFICIAL (BINDING_VALUE (binding)) && !(TREE_CODE (x) == TYPE_DECL && DECL_ARTIFICIAL (x))) { old_decl = BINDING_TYPE (binding); BINDING_TYPE (binding) = BINDING_VALUE (binding); BINDING_VALUE (binding) = NULL_TREE; INHERITED_VALUE_BINDING_P (binding) = 0; } else old_decl = BINDING_VALUE (binding); /* There was already a binding for X containing fewer functions than are named in X. Find the previous declaration of X on the class-shadowed list, and update it. */ for (shadow = class_binding_level->class_shadowed; shadow; shadow = TREE_CHAIN (shadow)) if (TREE_PURPOSE (shadow) == name && TREE_TYPE (shadow) == old_decl) { BINDING_VALUE (binding) = x; INHERITED_VALUE_BINDING_P (binding) = 0; TREE_TYPE (shadow) = x; return; } } /* If we didn't replace an existing binding, put the binding on the stack of bindings for the identifier, and update IDENTIFIER_CLASS_VALUE. */ if (push_class_binding (name, x)) { push_cache_obstack (); class_binding_level->class_shadowed = tree_cons (name, IDENTIFIER_CLASS_VALUE (name), class_binding_level->class_shadowed); pop_obstacks (); /* Record the value we are binding NAME to so that we can know what to pop later. */ TREE_TYPE (class_binding_level->class_shadowed) = x; } } /* Insert another USING_DECL into the current binding level, returning this declaration. If this is a redeclaration, do nothing and return NULL_TREE. */ tree push_using_decl (scope, name) tree scope; tree name; { tree decl; my_friendly_assert (TREE_CODE (scope) == NAMESPACE_DECL, 383); my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 384); for (decl = current_binding_level->usings; decl; decl = TREE_CHAIN (decl)) if (DECL_INITIAL (decl) == scope && DECL_NAME (decl) == name) break; if (decl) return NULL_TREE; decl = build_lang_decl (USING_DECL, name, void_type_node); DECL_INITIAL (decl) = scope; TREE_CHAIN (decl) = current_binding_level->usings; current_binding_level->usings = decl; return decl; } /* Add namespace to using_directives. Return NULL_TREE if nothing was changed (i.e. there was already a directive), or the fresh TREE_LIST otherwise. */ tree push_using_directive (used) tree used; { tree ud = current_binding_level->using_directives; tree iter, ancestor; /* Check if we already have this. */ if (purpose_member (used, ud) != NULL_TREE) return NULL_TREE; /* Recursively add all namespaces used. */ for (iter = DECL_NAMESPACE_USING (used); iter; iter = TREE_CHAIN (iter)) push_using_directive (TREE_PURPOSE (iter)); ancestor = namespace_ancestor (current_decl_namespace (), used); ud = current_binding_level->using_directives; ud = perm_tree_cons (used, ancestor, ud); current_binding_level->using_directives = ud; return ud; } /* DECL is a FUNCTION_DECL for a non-member function, which may have other definitions already in place. We get around this by making the value of the identifier point to a list of all the things that want to be referenced by that name. It is then up to the users of that name to decide what to do with that list. DECL may also be a TEMPLATE_DECL, with a FUNCTION_DECL in its DECL_RESULT slot. It is dealt with the same way. FLAGS is a bitwise-or of the following values: PUSH_LOCAL: Bind DECL in the current scope, rather than at namespace scope. PUSH_USING: DECL is being pushed as the result of a using declaration. The value returned may be a previous declaration if we guessed wrong about what language DECL should belong to (C or C++). Otherwise, it's always DECL (and never something that's not a _DECL). */ tree push_overloaded_decl (decl, flags) tree decl; int flags; { tree name = DECL_NAME (decl); tree old; tree new_binding; int doing_global = (namespace_bindings_p () || !(flags & PUSH_LOCAL)); if (doing_global) { old = namespace_binding (name, DECL_CONTEXT (decl)); if (old && TREE_CODE (old) == FUNCTION_DECL && DECL_ARTIFICIAL (old) && (DECL_BUILT_IN (old) || DECL_BUILT_IN_NONANSI (old))) { if (duplicate_decls (decl, old)) return old; old = NULL_TREE; } } else old = lookup_name_current_level (name); if (old) { if (TREE_CODE (old) == TYPE_DECL && DECL_ARTIFICIAL (old)) { tree t = TREE_TYPE (old); if (IS_AGGR_TYPE (t) && warn_shadow && (! DECL_IN_SYSTEM_HEADER (decl) || ! DECL_IN_SYSTEM_HEADER (old))) cp_warning ("`%#D' hides constructor for `%#T'", decl, t); old = NULL_TREE; } else if (is_overloaded_fn (old)) { tree tmp; for (tmp = old; tmp; tmp = OVL_NEXT (tmp)) { tree fn = OVL_CURRENT (tmp); if (TREE_CODE (tmp) == OVERLOAD && OVL_USED (tmp) && !(flags & PUSH_USING) && compparms (TYPE_ARG_TYPES (TREE_TYPE (fn)), TYPE_ARG_TYPES (TREE_TYPE (decl)))) cp_error ("`%#D' conflicts with previous using declaration `%#D'", decl, fn); if (duplicate_decls (decl, fn)) return fn; } } else { cp_error_at ("previous non-function declaration `%#D'", old); cp_error ("conflicts with function declaration `%#D'", decl); return decl; } } if (old || TREE_CODE (decl) == TEMPLATE_DECL) { if (old && TREE_CODE (old) != OVERLOAD) new_binding = ovl_cons (decl, ovl_cons (old, NULL_TREE)); else new_binding = ovl_cons (decl, old); if (flags & PUSH_USING) OVL_USED (new_binding) = 1; } else /* NAME is not ambiguous. */ new_binding = decl; if (doing_global) set_namespace_binding (name, current_namespace, new_binding); else { /* We only create an OVERLOAD if there was a previous binding at this level, or if decl is a template. In the former case, we need to remove the old binding and replace it with the new binding. We must also run through the NAMES on the binding level where the name was bound to update the chain. */ if (TREE_CODE (new_binding) == OVERLOAD && old) { tree *d; for (d = &BINDING_LEVEL (IDENTIFIER_BINDING (name))->names; *d; d = &TREE_CHAIN (*d)) if (*d == old || (TREE_CODE (*d) == TREE_LIST && TREE_VALUE (*d) == old)) { if (TREE_CODE (*d) == TREE_LIST) /* Just replace the old binding with the new. */ TREE_VALUE (*d) = new_binding; else /* Build a TREE_LIST to wrap the OVERLOAD. */ *d = build_tree_list (NULL_TREE, new_binding); /* And update the CPLUS_BINDING node. */ BINDING_VALUE (IDENTIFIER_BINDING (name)) = new_binding; return decl; } /* We should always find a previous binding in this case. */ my_friendly_abort (0); } /* Install the new binding. */ push_local_binding (name, new_binding, flags); } return decl; } /* Generate an implicit declaration for identifier FUNCTIONID as a function of type int (). Print a warning if appropriate. */ tree implicitly_declare (functionid) tree functionid; { register tree decl; int temp = allocation_temporary_p (); push_obstacks_nochange (); /* Save the decl permanently so we can warn if definition follows. In ANSI C, warn_implicit is usually false, so the saves little space. But in C++, it's usually true, hence the extra code. */ if (temp && (! warn_implicit || toplevel_bindings_p ())) end_temporary_allocation (); /* We used to reuse an old implicit decl here, but this loses with inline functions because it can clobber the saved decl chains. */ decl = build_lang_decl (FUNCTION_DECL, functionid, default_function_type); DECL_EXTERNAL (decl) = 1; TREE_PUBLIC (decl) = 1; /* ANSI standard says implicit declarations are in the innermost block. So we record the decl in the standard fashion. */ pushdecl (decl); rest_of_decl_compilation (decl, NULL_PTR, 0, 0); if (warn_implicit /* Only one warning per identifier. */ && IDENTIFIER_IMPLICIT_DECL (functionid) == NULL_TREE) { cp_pedwarn ("implicit declaration of function `%#D'", decl); } SET_IDENTIFIER_IMPLICIT_DECL (functionid, decl); pop_obstacks (); return decl; } /* Return zero if the declaration NEWDECL is valid when the declaration OLDDECL (assumed to be for the same name) has already been seen. Otherwise return an error message format string with a %s where the identifier should go. */ static const char * redeclaration_error_message (newdecl, olddecl) tree newdecl, olddecl; { if (TREE_CODE (newdecl) == TYPE_DECL) { /* Because C++ can put things into name space for free, constructs like "typedef struct foo { ... } foo" would look like an erroneous redeclaration. */ if (same_type_p (TREE_TYPE (newdecl), TREE_TYPE (olddecl))) return 0; else return "redefinition of `%#D'"; } else if (TREE_CODE (newdecl) == FUNCTION_DECL) { /* If this is a pure function, its olddecl will actually be the original initialization to `0' (which we force to call abort()). Don't complain about redefinition in this case. */ if (DECL_LANG_SPECIFIC (olddecl) && DECL_ABSTRACT_VIRTUAL_P (olddecl)) return 0; /* If both functions come from different namespaces, this is not a redeclaration - this is a conflict with a used function. */ if (DECL_NAMESPACE_SCOPE_P (olddecl) && DECL_CONTEXT (olddecl) != DECL_CONTEXT (newdecl)) return "`%D' conflicts with used function"; /* We'll complain about linkage mismatches in warn_extern_redeclared_static. */ /* Defining the same name twice is no good. */ if (DECL_INITIAL (olddecl) != NULL_TREE && DECL_INITIAL (newdecl) != NULL_TREE) { if (DECL_NAME (olddecl) == NULL_TREE) return "`%#D' not declared in class"; else return "redefinition of `%#D'"; } return 0; } else if (TREE_CODE (newdecl) == TEMPLATE_DECL) { if ((TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) == FUNCTION_DECL && DECL_INITIAL (DECL_TEMPLATE_RESULT (newdecl)) && DECL_INITIAL (DECL_TEMPLATE_RESULT (olddecl))) || (TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) == TYPE_DECL && TYPE_SIZE (TREE_TYPE (newdecl)) && TYPE_SIZE (TREE_TYPE (olddecl)))) return "redefinition of `%#D'"; return 0; } else if (toplevel_bindings_p ()) { /* Objects declared at top level: */ /* If at least one is a reference, it's ok. */ if (DECL_EXTERNAL (newdecl) || DECL_EXTERNAL (olddecl)) return 0; /* Reject two definitions. */ return "redefinition of `%#D'"; } else { /* Objects declared with block scope: */ /* Reject two definitions, and reject a definition together with an external reference. */ if (!(DECL_EXTERNAL (newdecl) && DECL_EXTERNAL (olddecl))) return "redeclaration of `%#D'"; return 0; } } /* Get the LABEL_DECL corresponding to identifier ID as a label. Create one if none exists so far for the current function. This function is called for both label definitions and label references. */ tree lookup_label (id) tree id; { register tree decl = IDENTIFIER_LABEL_VALUE (id); if (current_function_decl == NULL_TREE) { error ("label `%s' referenced outside of any function", IDENTIFIER_POINTER (id)); return NULL_TREE; } if ((decl == NULL_TREE || DECL_SOURCE_LINE (decl) == 0) && (named_label_uses == NULL || named_label_uses->names_in_scope != current_binding_level->names || named_label_uses->label_decl != decl)) { struct named_label_list *new_ent; new_ent = (struct named_label_list*)oballoc (sizeof (struct named_label_list)); new_ent->label_decl = decl; new_ent->names_in_scope = current_binding_level->names; new_ent->binding_level = current_binding_level; new_ent->lineno_o_goto = lineno; new_ent->filename_o_goto = input_filename; new_ent->next = named_label_uses; named_label_uses = new_ent; } /* Use a label already defined or ref'd with this name. */ if (decl != NULL_TREE) { /* But not if it is inherited and wasn't declared to be inheritable. */ if (DECL_CONTEXT (decl) != current_function_decl && ! C_DECLARED_LABEL_FLAG (decl)) return shadow_label (id); return decl; } decl = build_decl (LABEL_DECL, id, void_type_node); /* Make sure every label has an rtx. */ label_rtx (decl); /* A label not explicitly declared must be local to where it's ref'd. */ DECL_CONTEXT (decl) = current_function_decl; DECL_MODE (decl) = VOIDmode; /* Say where one reference is to the label, for the sake of the error if it is not defined. */ DECL_SOURCE_LINE (decl) = lineno; DECL_SOURCE_FILE (decl) = input_filename; SET_IDENTIFIER_LABEL_VALUE (id, decl); named_labels = tree_cons (NULL_TREE, decl, named_labels); named_label_uses->label_decl = decl; return decl; } /* Make a label named NAME in the current function, shadowing silently any that may be inherited from containing functions or containing scopes. Note that valid use, if the label being shadowed comes from another scope in the same function, requires calling declare_nonlocal_label right away. */ tree shadow_label (name) tree name; { register tree decl = IDENTIFIER_LABEL_VALUE (name); if (decl != NULL_TREE) { shadowed_labels = tree_cons (NULL_TREE, decl, shadowed_labels); SET_IDENTIFIER_LABEL_VALUE (name, NULL_TREE); } return lookup_label (name); } /* Define a label, specifying the location in the source file. Return the LABEL_DECL node for the label, if the definition is valid. Otherwise return 0. */ tree define_label (filename, line, name) char *filename; int line; tree name; { tree decl; if (minimal_parse_mode) { push_obstacks (&permanent_obstack, &permanent_obstack); decl = build_decl (LABEL_DECL, name, void_type_node); pop_obstacks (); DECL_SOURCE_LINE (decl) = line; DECL_SOURCE_FILE (decl) = filename; add_tree (decl); return decl; } decl = lookup_label (name); /* After labels, make any new cleanups go into their own new (temporary) binding contour. */ current_binding_level->more_cleanups_ok = 0; /* If label with this name is known from an outer context, shadow it. */ if (decl != NULL_TREE && DECL_CONTEXT (decl) != current_function_decl) { shadowed_labels = tree_cons (NULL_TREE, decl, shadowed_labels); SET_IDENTIFIER_LABEL_VALUE (name, NULL_TREE); decl = lookup_label (name); } if (name == get_identifier ("wchar_t")) cp_pedwarn ("label named wchar_t"); if (DECL_INITIAL (decl) != NULL_TREE) { cp_error ("duplicate label `%D'", decl); return 0; } else { struct named_label_list *uses, *prev; int identified = 0; /* Mark label as having been defined. */ DECL_INITIAL (decl) = error_mark_node; /* Say where in the source. */ DECL_SOURCE_FILE (decl) = filename; DECL_SOURCE_LINE (decl) = line; prev = NULL; uses = named_label_uses; while (uses != NULL) if (uses->label_decl == decl) { struct binding_level *b = current_binding_level; while (b) { tree new_decls = b->names; tree old_decls = (b == uses->binding_level) ? uses->names_in_scope : NULL_TREE; while (new_decls != old_decls) { if (TREE_CODE (new_decls) == VAR_DECL /* Don't complain about crossing initialization of internal entities. They can't be accessed, and they should be cleaned up by the time we get to the label. */ && ! DECL_ARTIFICIAL (new_decls) && !(DECL_INITIAL (new_decls) == NULL_TREE && pod_type_p (TREE_TYPE (new_decls)))) { /* This is really only important if we're crossing an initialization. The POD stuff is just pedantry; why should it matter if the class contains a field of pointer to member type? */ int problem = (DECL_INITIAL (new_decls) || (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (new_decls)))); if (! identified) { if (problem) { cp_error ("jump to label `%D'", decl); error_with_file_and_line (uses->filename_o_goto, uses->lineno_o_goto, " from here"); } else { cp_pedwarn ("jump to label `%D'", decl); pedwarn_with_file_and_line (uses->filename_o_goto, uses->lineno_o_goto, " from here"); } identified = 1; } if (problem) cp_error_at (" crosses initialization of `%#D'", new_decls); else cp_pedwarn_at (" enters scope of non-POD `%#D'", new_decls); } new_decls = TREE_CHAIN (new_decls); } if (b == uses->binding_level) break; b = b->level_chain; } if (prev != NULL) prev->next = uses->next; else named_label_uses = uses->next; uses = uses->next; } else { prev = uses; uses = uses->next; } current_function_return_value = NULL_TREE; return decl; } } struct cp_switch { struct binding_level *level; struct cp_switch *next; }; static struct cp_switch *switch_stack; void push_switch () { struct cp_switch *p = (struct cp_switch *) oballoc (sizeof (struct cp_switch)); p->level = current_binding_level; p->next = switch_stack; switch_stack = p; } void pop_switch () { switch_stack = switch_stack->next; } /* Same, but for CASE labels. If DECL is NULL_TREE, it's the default. */ /* XXX Note decl is never actually used. (bpk) */ void define_case_label () { tree cleanup = last_cleanup_this_contour (); struct binding_level *b = current_binding_level; int identified = 0; if (cleanup) { static int explained = 0; cp_warning_at ("destructor needed for `%#D'", TREE_PURPOSE (cleanup)); warning ("where case label appears here"); if (!explained) { warning ("(enclose actions of previous case statements requiring"); warning ("destructors in their own binding contours.)"); explained = 1; } } for (; b && b != switch_stack->level; b = b->level_chain) { tree new_decls = b->names; for (; new_decls; new_decls = TREE_CHAIN (new_decls)) { if (TREE_CODE (new_decls) == VAR_DECL /* Don't complain about crossing initialization of internal entities. They can't be accessed, and they should be cleaned up by the time we get to the label. */ && ! DECL_ARTIFICIAL (new_decls) && ((DECL_INITIAL (new_decls) != NULL_TREE && DECL_INITIAL (new_decls) != error_mark_node) || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (new_decls)))) { if (! identified) error ("jump to case label"); identified = 1; cp_error_at (" crosses initialization of `%#D'", new_decls); } } } /* After labels, make any new cleanups go into their own new (temporary) binding contour. */ current_binding_level->more_cleanups_ok = 0; current_function_return_value = NULL_TREE; } /* Return the list of declarations of the current level. Note that this list is in reverse order unless/until you nreverse it; and when you do nreverse it, you must store the result back using `storedecls' or you will lose. */ tree getdecls () { return current_binding_level->names; } /* Return the list of type-tags (for structs, etc) of the current level. */ tree gettags () { return current_binding_level->tags; } /* Store the list of declarations of the current level. This is done for the parameter declarations of a function being defined, after they are modified in the light of any missing parameters. */ static void storedecls (decls) tree decls; { current_binding_level->names = decls; } /* Similarly, store the list of tags of the current level. */ void storetags (tags) tree tags; { current_binding_level->tags = tags; } /* Given NAME, an IDENTIFIER_NODE, return the structure (or union or enum) definition for that name. Searches binding levels from BINDING_LEVEL up to the global level. If THISLEVEL_ONLY is nonzero, searches only the specified context (but skips any tag-transparent contexts to find one that is meaningful for tags). FORM says which kind of type the caller wants; it is RECORD_TYPE or UNION_TYPE or ENUMERAL_TYPE. If the wrong kind of type is found, and it's not a template, an error is reported. */ static tree lookup_tag (form, name, binding_level, thislevel_only) enum tree_code form; tree name; struct binding_level *binding_level; int thislevel_only; { register struct binding_level *level; /* Non-zero if, we should look past a pseudo-global level, even if THISLEVEL_ONLY. */ int allow_pseudo_global = 1; for (level = binding_level; level; level = level->level_chain) { register tree tail; if (ANON_AGGRNAME_P (name)) for (tail = level->tags; tail; tail = TREE_CHAIN (tail)) { /* There's no need for error checking here, because anon names are unique throughout the compilation. */ if (TYPE_IDENTIFIER (TREE_VALUE (tail)) == name) return TREE_VALUE (tail); } else if (level->namespace_p) /* Do namespace lookup. */ for (tail = current_namespace; 1; tail = CP_DECL_CONTEXT (tail)) { tree old = binding_for_name (name, tail); /* If we just skipped past a pseudo global level, even though THISLEVEL_ONLY, and we find a template class declaration, then we use the _TYPE node for the template. See the example below. */ if (thislevel_only && !allow_pseudo_global && old && BINDING_VALUE (old) && DECL_CLASS_TEMPLATE_P (BINDING_VALUE (old))) old = TREE_TYPE (BINDING_VALUE (old)); else old = BINDING_TYPE (old); /* If it has an original type, it is a typedef, and we should not return it. */ if (old && DECL_ORIGINAL_TYPE (TYPE_NAME (old))) old = NULL_TREE; if (old && TREE_CODE (old) != form && !(form != ENUMERAL_TYPE && TREE_CODE (old) == TEMPLATE_DECL)) { cp_error ("`%#D' redeclared as %C", old, form); return NULL_TREE; } if (old) return old; if (thislevel_only || tail == global_namespace) return NULL_TREE; } else for (tail = level->tags; tail; tail = TREE_CHAIN (tail)) { if (TREE_PURPOSE (tail) == name) { enum tree_code code = TREE_CODE (TREE_VALUE (tail)); /* Should tighten this up; it'll probably permit UNION_TYPE and a struct template, for example. */ if (code != form && !(form != ENUMERAL_TYPE && code == TEMPLATE_DECL)) { /* Definition isn't the kind we were looking for. */ cp_error ("`%#D' redeclared as %C", TREE_VALUE (tail), form); return NULL_TREE; } return TREE_VALUE (tail); } } if (thislevel_only && ! level->tag_transparent) { if (level->pseudo_global && allow_pseudo_global) { /* We must deal with cases like this: template struct S; template struct S {}; When looking up `S', for the second declaration, we would like to find the first declaration. But, we are in the pseudo-global level created for the template parameters, rather than the (surrounding) namespace level. Thus, we keep going one more level, even though THISLEVEL_ONLY is non-zero. */ allow_pseudo_global = 0; continue; } else return NULL_TREE; } if (current_class_type && level->level_chain->namespace_p) { /* Try looking in this class's tags before heading into global binding level. */ tree context = current_class_type; while (context) { switch (TREE_CODE_CLASS (TREE_CODE (context))) { tree these_tags; case 't': these_tags = CLASSTYPE_TAGS (context); if (ANON_AGGRNAME_P (name)) while (these_tags) { if (TYPE_IDENTIFIER (TREE_VALUE (these_tags)) == name) return TREE_VALUE (tail); these_tags = TREE_CHAIN (these_tags); } else while (these_tags) { if (TREE_PURPOSE (these_tags) == name) { if (TREE_CODE (TREE_VALUE (these_tags)) != form) { cp_error ("`%#D' redeclared as %C in class scope", TREE_VALUE (tail), form); return NULL_TREE; } return TREE_VALUE (tail); } these_tags = TREE_CHAIN (these_tags); } /* If this type is not yet complete, then don't look at its context. */ if (TYPE_SIZE (context) == NULL_TREE) goto no_context; /* Go to next enclosing type, if any. */ context = DECL_CONTEXT (TYPE_MAIN_DECL (context)); break; case 'd': context = DECL_CONTEXT (context); break; default: my_friendly_abort (10); } continue; no_context: break; } } } return NULL_TREE; } #if 0 void set_current_level_tags_transparency (tags_transparent) int tags_transparent; { current_binding_level->tag_transparent = tags_transparent; } #endif /* Given a type, find the tag that was defined for it and return the tag name. Otherwise return 0. However, the value can never be 0 in the cases in which this is used. C++: If NAME is non-zero, this is the new name to install. This is done when replacing anonymous tags with real tag names. */ static tree lookup_tag_reverse (type, name) tree type; tree name; { register struct binding_level *level; for (level = current_binding_level; level; level = level->level_chain) { register tree tail; for (tail = level->tags; tail; tail = TREE_CHAIN (tail)) { if (TREE_VALUE (tail) == type) { if (name) TREE_PURPOSE (tail) = name; return TREE_PURPOSE (tail); } } } return NULL_TREE; } /* Lookup TYPE in CONTEXT (a chain of nested types or a FUNCTION_DECL). Return the type value, or NULL_TREE if not found. */ static tree lookup_nested_type (type, context) tree type; tree context; { if (context == NULL_TREE) return NULL_TREE; while (context) { switch (TREE_CODE (context)) { case TYPE_DECL: { tree ctype = TREE_TYPE (context); tree match = value_member (type, CLASSTYPE_TAGS (ctype)); if (match) return TREE_VALUE (match); context = DECL_CONTEXT (context); /* When we have a nested class whose member functions have local types (e.g., a set of enums), we'll arrive here with the DECL_CONTEXT as the actual RECORD_TYPE node for the enclosing class. Instead, we want to make sure we come back in here with the TYPE_DECL, not the RECORD_TYPE. */ if (context && TREE_CODE (context) == RECORD_TYPE) context = TREE_CHAIN (context); } break; case FUNCTION_DECL: if (TYPE_NAME (type) && TYPE_IDENTIFIER (type)) return lookup_name (TYPE_IDENTIFIER (type), 1); return NULL_TREE; default: my_friendly_abort (12); } } return NULL_TREE; } /* Look up NAME in the NAMESPACE. */ tree lookup_namespace_name (namespace, name) tree namespace, name; { struct tree_binding _b; tree val; my_friendly_assert (TREE_CODE (namespace) == NAMESPACE_DECL, 370); if (TREE_CODE (name) == NAMESPACE_DECL) /* This happens for A::B when B is a namespace. */ return name; else if (TREE_CODE (name) == TEMPLATE_DECL) { /* This happens for A::B where B is a template, and there are no template arguments. */ cp_error ("invalid use of `%D'", name); return error_mark_node; } namespace = ORIGINAL_NAMESPACE (namespace); my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 373); val = binding_init (&_b); if (!qualified_lookup_using_namespace (name, namespace, val, 0)) return error_mark_node; if (BINDING_VALUE (val)) { val = BINDING_VALUE (val); /* If we have a single function from a using decl, pull it out. */ if (TREE_CODE (val) == OVERLOAD && ! really_overloaded_fn (val)) val = OVL_FUNCTION (val); return val; } cp_error ("`%D' undeclared in namespace `%D'", name, namespace); return error_mark_node; } /* Hash a TYPENAME_TYPE. K is really of type `tree'. */ static unsigned long typename_hash (k) hash_table_key k; { unsigned long hash; tree t; t = (tree) k; hash = (((unsigned long) TYPE_CONTEXT (t)) ^ ((unsigned long) DECL_NAME (TYPE_NAME (t)))); return hash; } /* Compare two TYPENAME_TYPEs. K1 and K2 are really of type `tree'. */ static boolean typename_compare (k1, k2) hash_table_key k1; hash_table_key k2; { tree t1; tree t2; tree d1; tree d2; t1 = (tree) k1; t2 = (tree) k2; d1 = TYPE_NAME (t1); d2 = TYPE_NAME (t2); return (DECL_NAME (d1) == DECL_NAME (d2) && same_type_p (TYPE_CONTEXT (t1), TYPE_CONTEXT (t2)) && ((TREE_TYPE (t1) != NULL_TREE) == (TREE_TYPE (t2) != NULL_TREE)) && same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)) && TYPENAME_TYPE_FULLNAME (t1) == TYPENAME_TYPE_FULLNAME (t2)); } /* Build a TYPENAME_TYPE. If the type is `typename T::t', CONTEXT is the type of `T', NAME is the IDENTIFIER_NODE for `t'. If BASE_TYPE is non-NULL, this type is being created by the implicit typename extension, and BASE_TYPE is a type named `t' in some base class of `T' which depends on template parameters. Returns the new TYPENAME_TYPE. */ tree build_typename_type (context, name, fullname, base_type) tree context; tree name; tree fullname; tree base_type; { tree t; tree d; struct hash_entry* e; static struct hash_table ht; push_obstacks (&permanent_obstack, &permanent_obstack); if (!ht.table && !hash_table_init (&ht, &hash_newfunc, &typename_hash, &typename_compare)) fatal ("virtual memory exhausted"); /* The FULLNAME needs to exist for the life of the hash table, i.e., for the entire compilation. */ if (!TREE_PERMANENT (fullname)) fullname = copy_to_permanent (fullname); /* Build the TYPENAME_TYPE. */ t = make_lang_type (TYPENAME_TYPE); TYPE_CONTEXT (t) = FROB_CONTEXT (context); TYPENAME_TYPE_FULLNAME (t) = fullname; TREE_TYPE (t) = base_type; /* Build the corresponding TYPE_DECL. */ d = build_decl (TYPE_DECL, name, t); TYPE_NAME (TREE_TYPE (d)) = d; TYPE_STUB_DECL (TREE_TYPE (d)) = d; DECL_CONTEXT (d) = FROB_CONTEXT (context); DECL_ARTIFICIAL (d) = 1; /* See if we already have this type. */ e = hash_lookup (&ht, t, /*create=*/false, /*copy=*/0); if (e) { /* This will free not only TREE_TYPE, but the lang-specific data and the TYPE_DECL as well. */ obstack_free (&permanent_obstack, t); t = (tree) e->key; } else /* Insert the type into the table. */ hash_lookup (&ht, t, /*create=*/true, /*copy=*/0); pop_obstacks (); return t; } tree make_typename_type (context, name) tree context, name; { tree t; tree fullname; if (TREE_CODE_CLASS (TREE_CODE (name)) == 't') { if (!(TYPE_LANG_SPECIFIC (name) && (CLASSTYPE_IS_TEMPLATE (name) || CLASSTYPE_USE_TEMPLATE (name)))) name = TYPE_IDENTIFIER (name); else /* Create a TEMPLATE_ID_EXPR for the type. */ name = build_nt (TEMPLATE_ID_EXPR, CLASSTYPE_TI_TEMPLATE (name), CLASSTYPE_TI_ARGS (name)); } else if (TREE_CODE (name) == TYPE_DECL) name = DECL_NAME (name); fullname = name; if (TREE_CODE (name) == TEMPLATE_ID_EXPR) { name = TREE_OPERAND (name, 0); if (TREE_CODE (name) == TEMPLATE_DECL) name = TREE_OPERAND (fullname, 0) = DECL_NAME (name); } if (TREE_CODE (name) != IDENTIFIER_NODE) my_friendly_abort (2000); if (TREE_CODE (context) == NAMESPACE_DECL) { /* We can get here from typename_sub0 in the explicit_template_type expansion. Just fail. */ cp_error ("no class template named `%#T' in `%#T'", name, context); return error_mark_node; } if (! uses_template_parms (context) || currently_open_class (context)) { if (TREE_CODE (fullname) == TEMPLATE_ID_EXPR) { tree tmpl = NULL_TREE; if (IS_AGGR_TYPE (context)) tmpl = lookup_field (context, name, 0, 0); if (!tmpl || !DECL_CLASS_TEMPLATE_P (tmpl)) { cp_error ("no class template named `%#T' in `%#T'", name, context); return error_mark_node; } return lookup_template_class (tmpl, TREE_OPERAND (fullname, 1), NULL_TREE, context, /*entering_scope=*/0); } else { if (IS_AGGR_TYPE (context)) t = lookup_field (context, name, 0, 1); else { cp_error ("no type named `%#T' in `%#T'", name, context); return error_mark_node; } if (t) return TREE_TYPE (t); } } /* If the CONTEXT is not a template type, then either the field is there now or its never going to be. */ if (!uses_template_parms (context) && !t) { cp_error ("no type named `%#T' in `%#T'", name, context); return error_mark_node; } return build_typename_type (context, name, fullname, NULL_TREE); } /* Select the right _DECL from multiple choices. */ static tree select_decl (binding, flags) tree binding; int flags; { tree val; val = BINDING_VALUE (binding); if (LOOKUP_NAMESPACES_ONLY (flags)) { /* We are not interested in types. */ if (val && TREE_CODE (val) == NAMESPACE_DECL) return val; return NULL_TREE; } /* If we could have a type and we have nothing or we need a type and have none. */ if (BINDING_TYPE (binding) && (!val || ((flags & LOOKUP_PREFER_TYPES) && TREE_CODE (val) != TYPE_DECL))) val = TYPE_STUB_DECL (BINDING_TYPE (binding)); /* Don't return non-types if we really prefer types. */ else if (val && LOOKUP_TYPES_ONLY (flags) && TREE_CODE (val) != TYPE_DECL && (TREE_CODE (val) != TEMPLATE_DECL || !DECL_CLASS_TEMPLATE_P (val))) val = NULL_TREE; return val; } /* Unscoped lookup of a global, iterate over namespaces, considering using namespace statements. */ static tree unqualified_namespace_lookup (name, flags) tree name; int flags; { struct tree_binding _binding; tree b = binding_init (&_binding); tree initial = current_decl_namespace(); tree scope = initial; tree siter; struct binding_level *level; tree val = NULL_TREE; while (!val) { val = binding_for_name (name, scope); /* Initialize binding for this context. */ BINDING_VALUE (b) = BINDING_VALUE (val); BINDING_TYPE (b) = BINDING_TYPE (val); /* Add all _DECLs seen through local using-directives. */ for (level = current_binding_level; !level->namespace_p; level = level->level_chain) if (!lookup_using_namespace (name, b, level->using_directives, scope, flags)) /* Give up because of error. */ return error_mark_node; /* Add all _DECLs seen through global using-directives. */ /* XXX local and global using lists should work equally. */ siter = initial; while (1) { if (!lookup_using_namespace (name, b, DECL_NAMESPACE_USING (siter), scope, flags)) /* Give up because of error. */ return error_mark_node; if (siter == scope) break; siter = CP_DECL_CONTEXT (siter); } val = select_decl (b, flags); if (scope == global_namespace) break; scope = CP_DECL_CONTEXT (scope); } return val; } /* Combine prefer_type and namespaces_only into flags. */ static int lookup_flags (prefer_type, namespaces_only) int prefer_type, namespaces_only; { if (namespaces_only) return LOOKUP_PREFER_NAMESPACES; if (prefer_type > 1) return LOOKUP_PREFER_TYPES; if (prefer_type > 0) return LOOKUP_PREFER_BOTH; return 0; } /* Given a lookup that returned VAL, use FLAGS to decide if we want to ignore it or not. Subroutine of lookup_name_real. */ static tree qualify_lookup (val, flags) tree val; int flags; { if (val == NULL_TREE) return val; if ((flags & LOOKUP_PREFER_NAMESPACES) && TREE_CODE (val) == NAMESPACE_DECL) return val; if ((flags & LOOKUP_PREFER_TYPES) && (TREE_CODE (val) == TYPE_DECL || ((flags & LOOKUP_TEMPLATES_EXPECTED) && DECL_CLASS_TEMPLATE_P (val)))) return val; if (flags & (LOOKUP_PREFER_NAMESPACES | LOOKUP_PREFER_TYPES)) return NULL_TREE; return val; } /* Any other BINDING overrides an implicit TYPENAME. Warn about that. */ static void warn_about_implicit_typename_lookup (typename, binding) tree typename; tree binding; { tree subtype = TREE_TYPE (TREE_TYPE (typename)); tree name = DECL_NAME (typename); if (! (TREE_CODE (binding) == TEMPLATE_DECL && CLASSTYPE_TEMPLATE_INFO (subtype) && CLASSTYPE_TI_TEMPLATE (subtype) == binding) && ! (TREE_CODE (binding) == TYPE_DECL && same_type_p (TREE_TYPE (binding), subtype))) { cp_warning ("lookup of `%D' finds `%#D'", name, binding); cp_warning (" instead of `%D' from dependent base class", typename); cp_warning (" (use `typename %T::%D' if that's what you meant)", constructor_name (current_class_type), name); } } /* Look up NAME in the current binding level and its superiors in the namespace of variables, functions and typedefs. Return a ..._DECL node of some kind representing its definition if there is only one such declaration, or return a TREE_LIST with all the overloaded definitions if there are many, or return 0 if it is undefined. If PREFER_TYPE is > 0, we prefer TYPE_DECLs or namespaces. If PREFER_TYPE is > 1, we reject non-type decls (e.g. namespaces). If PREFER_TYPE is -2, we're being called from yylex(). (UGLY) Otherwise we prefer non-TYPE_DECLs. If NONCLASS is non-zero, we don't look for the NAME in class scope, using IDENTIFIER_CLASS_VALUE. */ static tree lookup_name_real (name, prefer_type, nonclass, namespaces_only) tree name; int prefer_type, nonclass, namespaces_only; { tree t; tree val = NULL_TREE; int yylex = 0; tree from_obj = NULL_TREE; int flags; int val_is_implicit_typename = 0; /* Hack: copy flag set by parser, if set. */ if (only_namespace_names) namespaces_only = 1; if (prefer_type == -2) { extern int looking_for_typename; tree type = NULL_TREE; yylex = 1; prefer_type = looking_for_typename; flags = lookup_flags (prefer_type, namespaces_only); /* If the next thing is '<', class templates are types. */ if (looking_for_template) flags |= LOOKUP_TEMPLATES_EXPECTED; /* std:: becomes :: for now. */ if (got_scope == std_node) got_scope = void_type_node; if (got_scope) type = got_scope; else if (got_object != error_mark_node) type = got_object; if (type) { if (type == error_mark_node) return error_mark_node; if (TREE_CODE (type) == TYPENAME_TYPE && TREE_TYPE (type)) type = TREE_TYPE (type); if (TYPE_P (type)) type = complete_type (type); if (TREE_CODE (type) == VOID_TYPE) type = global_namespace; if (TREE_CODE (type) == NAMESPACE_DECL) { struct tree_binding b; val = binding_init (&b); flags |= LOOKUP_COMPLAIN; if (!qualified_lookup_using_namespace (name, type, val, flags)) return NULL_TREE; val = select_decl (val, flags); } else if (! IS_AGGR_TYPE (type) || TREE_CODE (type) == TEMPLATE_TYPE_PARM || TREE_CODE (type) == TEMPLATE_TEMPLATE_PARM || TREE_CODE (type) == TYPENAME_TYPE) /* Someone else will give an error about this if needed. */ val = NULL_TREE; else if (type == current_class_type) val = IDENTIFIER_CLASS_VALUE (name); else val = lookup_member (type, name, 0, prefer_type); } else val = NULL_TREE; if (got_scope) goto done; else if (got_object && val) from_obj = val; } else { flags = lookup_flags (prefer_type, namespaces_only); /* If we're not parsing, we need to complain. */ flags |= LOOKUP_COMPLAIN; } /* First, look in non-namespace scopes. */ for (t = IDENTIFIER_BINDING (name); t; t = TREE_CHAIN (t)) { tree binding; if (!LOCAL_BINDING_P (t) && nonclass) /* We're not looking for class-scoped bindings, so keep going. */ continue; /* If this is the kind of thing we're looking for, we're done. */ if (qualify_lookup (BINDING_VALUE (t), flags)) binding = BINDING_VALUE (t); else if ((flags & LOOKUP_PREFER_TYPES) && qualify_lookup (BINDING_TYPE (t), flags)) binding = BINDING_TYPE (t); else binding = NULL_TREE; if (binding && (!val || !(TREE_CODE (binding) == TYPE_DECL && IMPLICIT_TYPENAME_P (TREE_TYPE (binding))))) { if (val_is_implicit_typename && !yylex) warn_about_implicit_typename_lookup (val, binding); val = binding; val_is_implicit_typename = (TREE_CODE (val) == TYPE_DECL && IMPLICIT_TYPENAME_P (TREE_TYPE (val))); if (!val_is_implicit_typename) break; } } /* Now lookup in namespace scopes. */ if (!val || val_is_implicit_typename) { t = unqualified_namespace_lookup (name, flags); if (t) { if (val_is_implicit_typename && !yylex) warn_about_implicit_typename_lookup (val, t); val = t; } } done: if (val) { /* This should only warn about types used in qualified-ids. */ if (from_obj && from_obj != val) { if (looking_for_typename && TREE_CODE (from_obj) == TYPE_DECL && TREE_CODE (val) == TYPE_DECL && TREE_TYPE (from_obj) != TREE_TYPE (val)) { cp_pedwarn ("lookup of `%D' in the scope of `%#T' (`%#T')", name, got_object, TREE_TYPE (from_obj)); cp_pedwarn (" does not match lookup in the current scope (`%#T')", TREE_TYPE (val)); } /* We don't change val to from_obj if got_object depends on template parms because that breaks implicit typename for destructor calls. */ if (! uses_template_parms (got_object)) val = from_obj; } /* If we have a single function from a using decl, pull it out. */ if (TREE_CODE (val) == OVERLOAD && ! really_overloaded_fn (val)) val = OVL_FUNCTION (val); } else if (from_obj) val = from_obj; return val; } tree lookup_name_nonclass (name) tree name; { return lookup_name_real (name, 0, 1, 0); } tree lookup_function_nonclass (name, args) tree name; tree args; { return lookup_arg_dependent (name, lookup_name_nonclass (name), args); } tree lookup_name_namespace_only (name) tree name; { /* type-or-namespace, nonclass, namespace_only */ return lookup_name_real (name, 1, 1, 1); } tree lookup_name (name, prefer_type) tree name; int prefer_type; { return lookup_name_real (name, prefer_type, 0, 0); } /* Similar to `lookup_name' but look only in the innermost non-class binding level. */ tree lookup_name_current_level (name) tree name; { struct binding_level *b; tree t = NULL_TREE; b = current_binding_level; while (b->parm_flag == 2) b = b->level_chain; if (b->namespace_p) { t = IDENTIFIER_NAMESPACE_VALUE (name); /* extern "C" function() */ if (t != NULL_TREE && TREE_CODE (t) == TREE_LIST) t = TREE_VALUE (t); } else if (IDENTIFIER_BINDING (name) && LOCAL_BINDING_P (IDENTIFIER_BINDING (name))) { while (1) { if (BINDING_LEVEL (IDENTIFIER_BINDING (name)) == b) return IDENTIFIER_VALUE (name); if (b->keep == 2) b = b->level_chain; else break; } } return t; } /* Like lookup_name_current_level, but for types. */ tree lookup_type_current_level (name) tree name; { register tree t = NULL_TREE; my_friendly_assert (! current_binding_level->namespace_p, 980716); if (REAL_IDENTIFIER_TYPE_VALUE (name) != NULL_TREE && REAL_IDENTIFIER_TYPE_VALUE (name) != global_type_node) { struct binding_level *b = current_binding_level; while (1) { if (purpose_member (name, b->type_shadowed)) return REAL_IDENTIFIER_TYPE_VALUE (name); if (b->keep == 2) b = b->level_chain; else break; } } return t; } void begin_only_namespace_names () { only_namespace_names = 1; } void end_only_namespace_names () { only_namespace_names = 0; } /* Arrange for the user to get a source line number, even when the compiler is going down in flames, so that she at least has a chance of working around problems in the compiler. We used to call error(), but that let the segmentation fault continue through; now, it's much more passive by asking them to send the maintainers mail about the problem. */ static void signal_catch (sig) int sig ATTRIBUTE_UNUSED; { signal (SIGSEGV, SIG_DFL); #ifdef SIGIOT signal (SIGIOT, SIG_DFL); #endif #ifdef SIGILL signal (SIGILL, SIG_DFL); #endif #ifdef SIGABRT signal (SIGABRT, SIG_DFL); #endif #ifdef SIGBUS signal (SIGBUS, SIG_DFL); #endif my_friendly_abort (0); } #if 0 /* Unused -- brendan 970107 */ /* Array for holding types considered "built-in". These types are output in the module in which `main' is defined. */ static tree *builtin_type_tdescs_arr; static int builtin_type_tdescs_len, builtin_type_tdescs_max; #endif /* Push the declarations of builtin types into the namespace. RID_INDEX, if < RID_MAX 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. */ static void record_builtin_type (rid_index, name, type) enum rid rid_index; const char *name; tree type; { tree rname = NULL_TREE, tname = NULL_TREE; tree tdecl = NULL_TREE; if ((int) rid_index < (int) RID_MAX) rname = ridpointers[(int) rid_index]; if (name) tname = get_identifier (name); TYPE_BUILT_IN (type) = 1; if (tname) { tdecl = pushdecl (build_decl (TYPE_DECL, tname, type)); set_identifier_type_value (tname, NULL_TREE); if ((int) rid_index < (int) RID_MAX) /* Built-in types live in the global namespace. */ SET_IDENTIFIER_GLOBAL_VALUE (tname, tdecl); } if (rname != NULL_TREE) { if (tname != NULL_TREE) { set_identifier_type_value (rname, NULL_TREE); SET_IDENTIFIER_GLOBAL_VALUE (rname, tdecl); } else { tdecl = pushdecl (build_decl (TYPE_DECL, rname, type)); set_identifier_type_value (rname, NULL_TREE); } } } /* Record one of the standard Java types. * Declare it as having the given NAME. * If SIZE > 0, it is the size of one of the integral types; * otherwise it is the negative of the size of one of the other types. */ static tree record_builtin_java_type (name, size) const char *name; int size; { tree type, decl; if (size > 0) type = make_signed_type (size); else if (size > -32) { /* "__java_char" or ""__java_boolean". */ type = make_unsigned_type (-size); /*if (size == -1) TREE_SET_CODE (type, BOOLEAN_TYPE);*/ } else { /* "__java_float" or ""__java_double". */ type = make_node (REAL_TYPE); TYPE_PRECISION (type) = - size; layout_type (type); } record_builtin_type (RID_MAX, name, type); decl = TYPE_NAME (type); /* Suppress generate debug symbol entries for these types, since for normal C++ they are just clutter. However, push_lang_context undoes this if extern "Java" is seen. */ DECL_IGNORED_P (decl) = 1; TYPE_FOR_JAVA (type) = 1; return type; } /* Push a type into the namespace so that the back-ends ignore it. */ static void record_unknown_type (type, name) tree type; const char *name; { tree decl = pushdecl (build_decl (TYPE_DECL, get_identifier (name), type)); /* Make sure the "unknown type" typedecl gets ignored for debug info. */ DECL_IGNORED_P (decl) = 1; TYPE_DECL_SUPPRESS_DEBUG (decl) = 1; TYPE_SIZE (type) = TYPE_SIZE (void_type_node); TYPE_ALIGN (type) = 1; TYPE_MODE (type) = TYPE_MODE (void_type_node); } /* Push overloaded decl, in global scope, with one argument so it can be used as a callback from define_function. */ static void push_overloaded_decl_1 (x) tree x; { push_overloaded_decl (x, PUSH_GLOBAL); } #ifdef __GNUC__ __inline #endif tree auto_function (name, type, code) tree name, type; enum built_in_function code; { return define_function (IDENTIFIER_POINTER (name), type, code, push_overloaded_decl_1, IDENTIFIER_POINTER (build_decl_overload (name, TYPE_ARG_TYPES (type), 0))); } /* Create the predefined scalar types of C, and some nodes representing standard constants (0, 1, (void *)0). Initialize the global binding level. Make definitions for built-in primitive functions. */ void init_decl_processing () { register tree endlink, int_endlink, double_endlink, unsigned_endlink; tree fields[20]; /* Data type of memcpy. */ tree memcpy_ftype, strlen_ftype; int wchar_type_size; tree temp; tree array_domain_type; tree vb_off_identifier = NULL_TREE; /* Function type `char *(char *, char *)' and similar ones */ tree string_ftype_ptr_ptr, int_ftype_string_string; tree sizetype_endlink; tree ptr_ftype, ptr_ftype_unsigned, ptr_ftype_sizetype; tree void_ftype, void_ftype_int, void_ftype_ptr; /* Have to make these distinct before we try using them. */ lang_name_cplusplus = get_identifier ("C++"); lang_name_c = get_identifier ("C"); lang_name_java = get_identifier ("Java"); /* Enter the global namespace. */ my_friendly_assert (global_namespace == NULL_TREE, 375); my_friendly_assert (current_lang_name == NULL_TREE, 375); current_lang_name = lang_name_cplusplus; push_namespace (get_identifier ("::")); global_namespace = current_namespace; current_lang_name = NULL_TREE; if (flag_strict_prototype == 2) flag_strict_prototype = pedantic; if (! flag_permissive && ! pedantic) flag_pedantic_errors = 1; strict_prototypes_lang_c = flag_strict_prototype; /* Initially, C. */ current_lang_name = lang_name_c; current_function_decl = NULL_TREE; named_labels = NULL_TREE; named_label_uses = NULL; current_binding_level = NULL_BINDING_LEVEL; free_binding_level = NULL_BINDING_LEVEL; /* Because most segmentation signals can be traced back into user code, catch them and at least give the user a chance of working around compiler bugs. */ signal (SIGSEGV, signal_catch); /* We will also catch aborts in the back-end through signal_catch and give the user a chance to see where the error might be, and to defeat aborts in the back-end when there have been errors previously in their code. */ #ifdef SIGIOT signal (SIGIOT, signal_catch); #endif #ifdef SIGILL signal (SIGILL, signal_catch); #endif #ifdef SIGABRT signal (SIGABRT, signal_catch); #endif #ifdef SIGBUS signal (SIGBUS, signal_catch); #endif gcc_obstack_init (&decl_obstack); /* Must lay these out before anything else gets laid out. */ error_mark_node = make_node (ERROR_MARK); TREE_PERMANENT (error_mark_node) = 1; TREE_TYPE (error_mark_node) = error_mark_node; error_mark_list = build_tree_list (error_mark_node, error_mark_node); TREE_TYPE (error_mark_list) = error_mark_node; /* Make the binding_level structure for global names. */ pushlevel (0); global_binding_level = current_binding_level; /* The global level is the namespace level of ::. */ NAMESPACE_LEVEL (global_namespace) = global_binding_level; declare_namespace_level (); this_identifier = get_identifier (THIS_NAME); in_charge_identifier = get_identifier (IN_CHARGE_NAME); + vlist_identifier = get_identifier (VLIST_NAME); ctor_identifier = get_identifier (CTOR_NAME); dtor_identifier = get_identifier (DTOR_NAME); pfn_identifier = get_identifier (VTABLE_PFN_NAME); index_identifier = get_identifier (VTABLE_INDEX_NAME); delta_identifier = get_identifier (VTABLE_DELTA_NAME); delta2_identifier = get_identifier (VTABLE_DELTA2_NAME); pfn_or_delta2_identifier = get_identifier ("__pfn_or_delta2"); if (flag_handle_signatures) { tag_identifier = get_identifier (SIGTABLE_TAG_NAME); vb_off_identifier = get_identifier (SIGTABLE_VB_OFF_NAME); vt_off_identifier = get_identifier (SIGTABLE_VT_OFF_NAME); } /* Define `int' and `char' first so that dbx will output them first. */ integer_type_node = make_signed_type (INT_TYPE_SIZE); record_builtin_type (RID_INT, NULL_PTR, integer_type_node); /* Define `char', which is like either `signed char' or `unsigned char' but not the same as either. */ char_type_node = (flag_signed_char ? make_signed_type (CHAR_TYPE_SIZE) : make_unsigned_type (CHAR_TYPE_SIZE)); record_builtin_type (RID_CHAR, "char", char_type_node); /* `signed' is the same as `int' */ record_builtin_type (RID_SIGNED, NULL_PTR, integer_type_node); long_integer_type_node = make_signed_type (LONG_TYPE_SIZE); record_builtin_type (RID_LONG, "long int", long_integer_type_node); unsigned_type_node = make_unsigned_type (INT_TYPE_SIZE); record_builtin_type (RID_UNSIGNED, "unsigned int", unsigned_type_node); long_unsigned_type_node = make_unsigned_type (LONG_TYPE_SIZE); record_builtin_type (RID_MAX, "long unsigned int", long_unsigned_type_node); record_builtin_type (RID_MAX, "unsigned long", long_unsigned_type_node); long_long_integer_type_node = make_signed_type (LONG_LONG_TYPE_SIZE); record_builtin_type (RID_MAX, "long long int", long_long_integer_type_node); long_long_unsigned_type_node = make_unsigned_type (LONG_LONG_TYPE_SIZE); record_builtin_type (RID_MAX, "long long unsigned int", long_long_unsigned_type_node); record_builtin_type (RID_MAX, "long long unsigned", long_long_unsigned_type_node); short_integer_type_node = make_signed_type (SHORT_TYPE_SIZE); record_builtin_type (RID_SHORT, "short int", short_integer_type_node); short_unsigned_type_node = make_unsigned_type (SHORT_TYPE_SIZE); record_builtin_type (RID_MAX, "short unsigned int", short_unsigned_type_node); record_builtin_type (RID_MAX, "unsigned short", short_unsigned_type_node); /* `unsigned long' is the standard type for sizeof. Note that stddef.h uses `unsigned long', and this must agree, even if long and int are the same size. */ set_sizetype (TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (SIZE_TYPE)))); ptrdiff_type_node = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (PTRDIFF_TYPE))); /* Define both `signed char' and `unsigned char'. */ signed_char_type_node = make_signed_type (CHAR_TYPE_SIZE); record_builtin_type (RID_MAX, "signed char", signed_char_type_node); unsigned_char_type_node = make_unsigned_type (CHAR_TYPE_SIZE); record_builtin_type (RID_MAX, "unsigned char", unsigned_char_type_node); /* These are types that type_for_size and type_for_mode use. */ intQI_type_node = make_signed_type (GET_MODE_BITSIZE (QImode)); pushdecl (build_decl (TYPE_DECL, NULL_TREE, intQI_type_node)); intHI_type_node = make_signed_type (GET_MODE_BITSIZE (HImode)); pushdecl (build_decl (TYPE_DECL, NULL_TREE, intHI_type_node)); intSI_type_node = make_signed_type (GET_MODE_BITSIZE (SImode)); pushdecl (build_decl (TYPE_DECL, NULL_TREE, intSI_type_node)); intDI_type_node = make_signed_type (GET_MODE_BITSIZE (DImode)); pushdecl (build_decl (TYPE_DECL, NULL_TREE, intDI_type_node)); #if HOST_BITS_PER_WIDE_INT >= 64 intTI_type_node = make_signed_type (GET_MODE_BITSIZE (TImode)); pushdecl (build_decl (TYPE_DECL, get_identifier ("__int128_t"), intTI_type_node)); #endif unsigned_intQI_type_node = make_unsigned_type (GET_MODE_BITSIZE (QImode)); pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intQI_type_node)); unsigned_intHI_type_node = make_unsigned_type (GET_MODE_BITSIZE (HImode)); pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intHI_type_node)); unsigned_intSI_type_node = make_unsigned_type (GET_MODE_BITSIZE (SImode)); pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intSI_type_node)); unsigned_intDI_type_node = make_unsigned_type (GET_MODE_BITSIZE (DImode)); pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intDI_type_node)); #if HOST_BITS_PER_WIDE_INT >= 64 unsigned_intTI_type_node = make_unsigned_type (GET_MODE_BITSIZE (TImode)); pushdecl (build_decl (TYPE_DECL, get_identifier ("__uint128_t"), unsigned_intTI_type_node)); #endif float_type_node = make_node (REAL_TYPE); TYPE_PRECISION (float_type_node) = FLOAT_TYPE_SIZE; record_builtin_type (RID_FLOAT, NULL_PTR, float_type_node); layout_type (float_type_node); double_type_node = make_node (REAL_TYPE); if (flag_short_double) TYPE_PRECISION (double_type_node) = FLOAT_TYPE_SIZE; else TYPE_PRECISION (double_type_node) = DOUBLE_TYPE_SIZE; record_builtin_type (RID_DOUBLE, NULL_PTR, double_type_node); layout_type (double_type_node); long_double_type_node = make_node (REAL_TYPE); TYPE_PRECISION (long_double_type_node) = LONG_DOUBLE_TYPE_SIZE; record_builtin_type (RID_MAX, "long double", long_double_type_node); layout_type (long_double_type_node); complex_integer_type_node = make_node (COMPLEX_TYPE); pushdecl (build_decl (TYPE_DECL, get_identifier ("complex int"), complex_integer_type_node)); TREE_TYPE (complex_integer_type_node) = integer_type_node; layout_type (complex_integer_type_node); complex_float_type_node = make_node (COMPLEX_TYPE); pushdecl (build_decl (TYPE_DECL, get_identifier ("complex float"), complex_float_type_node)); TREE_TYPE (complex_float_type_node) = float_type_node; layout_type (complex_float_type_node); complex_double_type_node = make_node (COMPLEX_TYPE); pushdecl (build_decl (TYPE_DECL, get_identifier ("complex double"), complex_double_type_node)); TREE_TYPE (complex_double_type_node) = double_type_node; layout_type (complex_double_type_node); complex_long_double_type_node = make_node (COMPLEX_TYPE); pushdecl (build_decl (TYPE_DECL, get_identifier ("complex long double"), complex_long_double_type_node)); TREE_TYPE (complex_long_double_type_node) = long_double_type_node; layout_type (complex_long_double_type_node); java_byte_type_node = record_builtin_java_type ("__java_byte", 8); java_short_type_node = record_builtin_java_type ("__java_short", 16); java_int_type_node = record_builtin_java_type ("__java_int", 32); java_long_type_node = record_builtin_java_type ("__java_long", 64); java_float_type_node = record_builtin_java_type ("__java_float", -32); java_double_type_node = record_builtin_java_type ("__java_double", -64); java_char_type_node = record_builtin_java_type ("__java_char", -16); java_boolean_type_node = record_builtin_java_type ("__java_boolean", -1); integer_zero_node = build_int_2 (0, 0); TREE_TYPE (integer_zero_node) = integer_type_node; integer_one_node = build_int_2 (1, 0); TREE_TYPE (integer_one_node) = integer_type_node; integer_two_node = build_int_2 (2, 0); TREE_TYPE (integer_two_node) = integer_type_node; integer_three_node = build_int_2 (3, 0); TREE_TYPE (integer_three_node) = integer_type_node; boolean_type_node = make_unsigned_type (BOOL_TYPE_SIZE); TREE_SET_CODE (boolean_type_node, BOOLEAN_TYPE); TYPE_MAX_VALUE (boolean_type_node) = build_int_2 (1, 0); TREE_TYPE (TYPE_MAX_VALUE (boolean_type_node)) = boolean_type_node; TYPE_PRECISION (boolean_type_node) = 1; record_builtin_type (RID_BOOL, "bool", boolean_type_node); boolean_false_node = build_int_2 (0, 0); TREE_TYPE (boolean_false_node) = boolean_type_node; boolean_true_node = build_int_2 (1, 0); TREE_TYPE (boolean_true_node) = boolean_type_node; /* These are needed by stor-layout.c. */ size_zero_node = size_int (0); size_one_node = size_int (1); signed_size_zero_node = build_int_2 (0, 0); TREE_TYPE (signed_size_zero_node) = make_signed_type (TYPE_PRECISION (sizetype)); void_type_node = make_node (VOID_TYPE); record_builtin_type (RID_VOID, NULL_PTR, void_type_node); layout_type (void_type_node); /* Uses integer_zero_node. */ void_list_node = build_tree_list (NULL_TREE, void_type_node); TREE_PARMLIST (void_list_node) = 1; null_pointer_node = build_int_2 (0, 0); TREE_TYPE (null_pointer_node) = build_pointer_type (void_type_node); layout_type (TREE_TYPE (null_pointer_node)); /* Used for expressions that do nothing, but are not errors. */ void_zero_node = build_int_2 (0, 0); TREE_TYPE (void_zero_node) = void_type_node; string_type_node = build_pointer_type (char_type_node); const_string_type_node = build_pointer_type (build_qualified_type (char_type_node, TYPE_QUAL_CONST)); #if 0 record_builtin_type (RID_MAX, NULL_PTR, string_type_node); #endif /* Make a type to be the domain of a few array types whose domains don't really matter. 200 is small enough that it always fits in size_t and large enough that it can hold most function names for the initializations of __FUNCTION__ and __PRETTY_FUNCTION__. */ array_domain_type = build_index_type (build_int_2 (200, 0)); /* Make a type for arrays of characters. With luck nothing will ever really depend on the length of this array type. */ char_array_type_node = build_array_type (char_type_node, array_domain_type); /* Likewise for arrays of ints. */ int_array_type_node = build_array_type (integer_type_node, array_domain_type); /* This is just some anonymous class type. Nobody should ever need to look inside this envelope. */ class_star_type_node = build_pointer_type (make_lang_type (RECORD_TYPE)); default_function_type = build_function_type (integer_type_node, NULL_TREE); ptr_type_node = build_pointer_type (void_type_node); const_ptr_type_node = build_pointer_type (build_qualified_type (void_type_node, TYPE_QUAL_CONST)); #if 0 record_builtin_type (RID_MAX, NULL_PTR, ptr_type_node); #endif + endlink = void_list_node; int_endlink = tree_cons (NULL_TREE, integer_type_node, endlink); double_endlink = tree_cons (NULL_TREE, double_type_node, endlink); unsigned_endlink = tree_cons (NULL_TREE, unsigned_type_node, endlink); ptr_ftype = build_function_type (ptr_type_node, NULL_TREE); ptr_ftype_unsigned = build_function_type (ptr_type_node, unsigned_endlink); sizetype_endlink = tree_cons (NULL_TREE, sizetype, endlink); /* We realloc here because sizetype could be int or unsigned. S'ok. */ ptr_ftype_sizetype = build_function_type (ptr_type_node, sizetype_endlink); void_ftype = build_function_type (void_type_node, endlink); void_ftype_int = build_function_type (void_type_node, int_endlink); void_ftype_ptr = build_function_type (void_type_node, tree_cons (NULL_TREE, ptr_type_node, endlink)); void_ftype_ptr = build_exception_variant (void_ftype_ptr, tree_cons (NULL_TREE, NULL_TREE, NULL_TREE)); float_ftype_float = build_function_type (float_type_node, tree_cons (NULL_TREE, float_type_node, endlink)); double_ftype_double = build_function_type (double_type_node, double_endlink); ldouble_ftype_ldouble = build_function_type (long_double_type_node, tree_cons (NULL_TREE, long_double_type_node, endlink)); double_ftype_double_double = build_function_type (double_type_node, tree_cons (NULL_TREE, double_type_node, double_endlink)); int_ftype_int = build_function_type (integer_type_node, int_endlink); long_ftype_long = build_function_type (long_integer_type_node, tree_cons (NULL_TREE, long_integer_type_node, endlink)); int_ftype_cptr_cptr_sizet = build_function_type (integer_type_node, tree_cons (NULL_TREE, const_ptr_type_node, tree_cons (NULL_TREE, const_ptr_type_node, tree_cons (NULL_TREE, sizetype, endlink)))); string_ftype_ptr_ptr /* strcpy prototype */ = build_function_type (string_type_node, tree_cons (NULL_TREE, string_type_node, tree_cons (NULL_TREE, const_string_type_node, endlink))); int_ftype_string_string /* strcmp prototype */ = build_function_type (integer_type_node, tree_cons (NULL_TREE, const_string_type_node, tree_cons (NULL_TREE, const_string_type_node, endlink))); strlen_ftype /* strlen prototype */ = build_function_type (sizetype, tree_cons (NULL_TREE, const_string_type_node, endlink)); memcpy_ftype /* memcpy prototype */ = build_function_type (ptr_type_node, tree_cons (NULL_TREE, ptr_type_node, tree_cons (NULL_TREE, const_ptr_type_node, sizetype_endlink))); if (flag_huge_objects) delta_type_node = long_integer_type_node; else delta_type_node = short_integer_type_node; builtin_function ("__builtin_constant_p", default_function_type, BUILT_IN_CONSTANT_P, NULL_PTR); builtin_return_address_fndecl = builtin_function ("__builtin_return_address", ptr_ftype_unsigned, BUILT_IN_RETURN_ADDRESS, NULL_PTR); builtin_function ("__builtin_frame_address", ptr_ftype_unsigned, BUILT_IN_FRAME_ADDRESS, NULL_PTR); builtin_function ("__builtin_alloca", ptr_ftype_sizetype, BUILT_IN_ALLOCA, "alloca"); builtin_function ("__builtin_ffs", int_ftype_int, BUILT_IN_FFS, NULL_PTR); /* Define alloca, ffs as builtins. Declare _exit just to mark it as volatile. */ if (! flag_no_builtin && !flag_no_nonansi_builtin) { temp = builtin_function ("alloca", ptr_ftype_sizetype, BUILT_IN_ALLOCA, NULL_PTR); /* Suppress error if redefined as a non-function. */ DECL_BUILT_IN_NONANSI (temp) = 1; temp = builtin_function ("ffs", int_ftype_int, BUILT_IN_FFS, NULL_PTR); /* Suppress error if redefined as a non-function. */ DECL_BUILT_IN_NONANSI (temp) = 1; temp = builtin_function ("_exit", void_ftype_int, NOT_BUILT_IN, NULL_PTR); TREE_THIS_VOLATILE (temp) = 1; TREE_SIDE_EFFECTS (temp) = 1; /* Suppress error if redefined as a non-function. */ DECL_BUILT_IN_NONANSI (temp) = 1; } builtin_function ("__builtin_abs", int_ftype_int, BUILT_IN_ABS, NULL_PTR); builtin_function ("__builtin_fabsf", float_ftype_float, BUILT_IN_FABS, NULL_PTR); builtin_function ("__builtin_fabs", double_ftype_double, BUILT_IN_FABS, NULL_PTR); builtin_function ("__builtin_fabsl", ldouble_ftype_ldouble, BUILT_IN_FABS, NULL_PTR); builtin_function ("__builtin_labs", long_ftype_long, BUILT_IN_LABS, NULL_PTR); builtin_function ("__builtin_saveregs", ptr_ftype, BUILT_IN_SAVEREGS, NULL_PTR); builtin_function ("__builtin_classify_type", default_function_type, BUILT_IN_CLASSIFY_TYPE, NULL_PTR); builtin_function ("__builtin_next_arg", ptr_ftype, BUILT_IN_NEXT_ARG, NULL_PTR); builtin_function ("__builtin_args_info", int_ftype_int, BUILT_IN_ARGS_INFO, NULL_PTR); builtin_function ("__builtin_setjmp", build_function_type (integer_type_node, tree_cons (NULL_TREE, ptr_type_node, endlink)), BUILT_IN_SETJMP, NULL_PTR); builtin_function ("__builtin_longjmp", build_function_type (integer_type_node, tree_cons (NULL_TREE, ptr_type_node, tree_cons (NULL_TREE, integer_type_node, endlink))), BUILT_IN_LONGJMP, NULL_PTR); /* Untyped call and return. */ builtin_function ("__builtin_apply_args", ptr_ftype, BUILT_IN_APPLY_ARGS, NULL_PTR); temp = tree_cons (NULL_TREE, build_pointer_type (build_function_type (void_type_node, NULL_TREE)), tree_cons (NULL_TREE, ptr_ftype_sizetype, NULL_TREE)); builtin_function ("__builtin_apply", build_function_type (ptr_type_node, temp), BUILT_IN_APPLY, NULL_PTR); builtin_function ("__builtin_return", void_ftype_ptr, BUILT_IN_RETURN, NULL_PTR); /* Currently under experimentation. */ builtin_function ("__builtin_memcpy", memcpy_ftype, BUILT_IN_MEMCPY, "memcpy"); builtin_function ("__builtin_memcmp", int_ftype_cptr_cptr_sizet, BUILT_IN_MEMCMP, "memcmp"); builtin_function ("__builtin_strcmp", int_ftype_string_string, BUILT_IN_STRCMP, "strcmp"); builtin_function ("__builtin_strcpy", string_ftype_ptr_ptr, BUILT_IN_STRCPY, "strcpy"); builtin_function ("__builtin_strlen", strlen_ftype, BUILT_IN_STRLEN, "strlen"); builtin_function ("__builtin_sqrtf", float_ftype_float, BUILT_IN_FSQRT, "sqrtf"); builtin_function ("__builtin_fsqrt", double_ftype_double, BUILT_IN_FSQRT, NULL_PTR); builtin_function ("__builtin_sqrtl", ldouble_ftype_ldouble, BUILT_IN_FSQRT, "sqrtl"); builtin_function ("__builtin_sinf", float_ftype_float, BUILT_IN_SIN, "sinf"); builtin_function ("__builtin_sin", double_ftype_double, BUILT_IN_SIN, "sin"); builtin_function ("__builtin_sinl", ldouble_ftype_ldouble, BUILT_IN_SIN, "sinl"); builtin_function ("__builtin_cosf", float_ftype_float, BUILT_IN_COS, "cosf"); builtin_function ("__builtin_cos", double_ftype_double, BUILT_IN_COS, "cos"); builtin_function ("__builtin_cosl", ldouble_ftype_ldouble, BUILT_IN_COS, "cosl"); if (!flag_no_builtin) { builtin_function ("abs", int_ftype_int, BUILT_IN_ABS, NULL_PTR); builtin_function ("fabs", double_ftype_double, BUILT_IN_FABS, NULL_PTR); builtin_function ("labs", long_ftype_long, BUILT_IN_LABS, NULL_PTR); builtin_function ("fabsf", float_ftype_float, BUILT_IN_FABS, NULL_PTR); builtin_function ("fabsl", ldouble_ftype_ldouble, BUILT_IN_FABS, NULL_PTR); builtin_function ("memcpy", memcpy_ftype, BUILT_IN_MEMCPY, NULL_PTR); builtin_function ("memcmp", int_ftype_cptr_cptr_sizet, BUILT_IN_MEMCMP, NULL_PTR); builtin_function ("strcmp", int_ftype_string_string, BUILT_IN_STRCMP, NULL_PTR); builtin_function ("strcpy", string_ftype_ptr_ptr, BUILT_IN_STRCPY, NULL_PTR); builtin_function ("strlen", strlen_ftype, BUILT_IN_STRLEN, NULL_PTR); builtin_function ("sqrtf", float_ftype_float, BUILT_IN_FSQRT, NULL_PTR); builtin_function ("sqrt", double_ftype_double, BUILT_IN_FSQRT, NULL_PTR); builtin_function ("sqrtl", ldouble_ftype_ldouble, BUILT_IN_FSQRT, NULL_PTR); builtin_function ("sinf", float_ftype_float, BUILT_IN_SIN, NULL_PTR); builtin_function ("sin", double_ftype_double, BUILT_IN_SIN, NULL_PTR); builtin_function ("sinl", ldouble_ftype_ldouble, BUILT_IN_SIN, NULL_PTR); builtin_function ("cosf", float_ftype_float, BUILT_IN_COS, NULL_PTR); builtin_function ("cos", double_ftype_double, BUILT_IN_COS, NULL_PTR); builtin_function ("cosl", ldouble_ftype_ldouble, BUILT_IN_COS, NULL_PTR); /* Declare these functions volatile to avoid spurious "control drops through" warnings. */ temp = builtin_function ("abort", void_ftype, NOT_BUILT_IN, NULL_PTR); TREE_THIS_VOLATILE (temp) = 1; TREE_SIDE_EFFECTS (temp) = 1; /* Well, these are actually ANSI, but we can't set DECL_BUILT_IN on them... */ DECL_BUILT_IN_NONANSI (temp) = 1; temp = builtin_function ("exit", void_ftype_int, NOT_BUILT_IN, NULL_PTR); TREE_THIS_VOLATILE (temp) = 1; TREE_SIDE_EFFECTS (temp) = 1; DECL_BUILT_IN_NONANSI (temp) = 1; } #if 0 /* Support for these has not been written in either expand_builtin or build_function_call. */ builtin_function ("__builtin_div", default_ftype, BUILT_IN_DIV, NULL_PTR); builtin_function ("__builtin_ldiv", default_ftype, BUILT_IN_LDIV, NULL_PTR); builtin_function ("__builtin_ffloor", double_ftype_double, BUILT_IN_FFLOOR, NULL_PTR); builtin_function ("__builtin_fceil", double_ftype_double, BUILT_IN_FCEIL, NULL_PTR); builtin_function ("__builtin_fmod", double_ftype_double_double, BUILT_IN_FMOD, NULL_PTR); builtin_function ("__builtin_frem", double_ftype_double_double, BUILT_IN_FREM, NULL_PTR); builtin_function ("__builtin_memset", ptr_ftype_ptr_int_int, BUILT_IN_MEMSET, NULL_PTR); builtin_function ("__builtin_getexp", double_ftype_double, BUILT_IN_GETEXP, NULL_PTR); builtin_function ("__builtin_getman", double_ftype_double, BUILT_IN_GETMAN, NULL_PTR); #endif /* C++ extensions */ unknown_type_node = make_node (UNKNOWN_TYPE); record_unknown_type (unknown_type_node, "unknown type"); /* Indirecting an UNKNOWN_TYPE node yields an UNKNOWN_TYPE node. */ TREE_TYPE (unknown_type_node) = unknown_type_node; TREE_TYPE (null_node) = type_for_size (POINTER_SIZE, 0); /* Looking up TYPE_POINTER_TO and TYPE_REFERENCE_TO yield the same result. */ TYPE_POINTER_TO (unknown_type_node) = unknown_type_node; TYPE_REFERENCE_TO (unknown_type_node) = unknown_type_node; /* This is for handling opaque types in signatures. */ opaque_type_node = copy_node (ptr_type_node); TYPE_MAIN_VARIANT (opaque_type_node) = opaque_type_node; record_builtin_type (RID_MAX, 0, opaque_type_node); /* This is special for C++ so functions can be overloaded. */ wchar_type_node = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (WCHAR_TYPE))); wchar_type_size = TYPE_PRECISION (wchar_type_node); signed_wchar_type_node = make_signed_type (wchar_type_size); unsigned_wchar_type_node = make_unsigned_type (wchar_type_size); wchar_type_node = TREE_UNSIGNED (wchar_type_node) ? unsigned_wchar_type_node : signed_wchar_type_node; record_builtin_type (RID_WCHAR, "__wchar_t", wchar_type_node); /* Artificial declaration of wchar_t -- can be bashed */ wchar_decl_node = build_decl (TYPE_DECL, get_identifier ("wchar_t"), wchar_type_node); pushdecl (wchar_decl_node); /* This is for wide string constants. */ wchar_array_type_node = build_array_type (wchar_type_node, array_domain_type); if (flag_vtable_thunks) { /* Make sure we get a unique function type, so we can give its pointer type a name. (This wins for gdb.) */ tree vfunc_type = make_node (FUNCTION_TYPE); TREE_TYPE (vfunc_type) = integer_type_node; TYPE_ARG_TYPES (vfunc_type) = NULL_TREE; layout_type (vfunc_type); vtable_entry_type = build_pointer_type (vfunc_type); } else { vtable_entry_type = make_lang_type (RECORD_TYPE); fields[0] = build_lang_field_decl (FIELD_DECL, delta_identifier, delta_type_node); fields[1] = build_lang_field_decl (FIELD_DECL, index_identifier, delta_type_node); fields[2] = build_lang_field_decl (FIELD_DECL, pfn_identifier, ptr_type_node); finish_builtin_type (vtable_entry_type, VTBL_PTR_TYPE, fields, 2, double_type_node); /* Make this part of an invisible union. */ fields[3] = copy_node (fields[2]); TREE_TYPE (fields[3]) = delta_type_node; DECL_NAME (fields[3]) = delta2_identifier; DECL_MODE (fields[3]) = TYPE_MODE (delta_type_node); DECL_SIZE (fields[3]) = TYPE_SIZE (delta_type_node); TREE_UNSIGNED (fields[3]) = 0; TREE_CHAIN (fields[2]) = fields[3]; vtable_entry_type = build_qualified_type (vtable_entry_type, TYPE_QUAL_CONST); } 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 (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 (RID_MAX, NULL_PTR, vtbl_ptr_type_node); + if (flag_vtable_thunks) + { + /* We need vlists only when using thunks; otherwise leave them + as NULL_TREE. That way, it doesn't get into the way of the + mangling. */ + vlist_type_node = build_pointer_type (vtbl_ptr_type_node); + vlist_zero_node = build_int_2 (0, 0); + TREE_TYPE (vlist_zero_node) = vlist_type_node; + } + /* Simplify life by making a "sigtable_entry_type". Give its fields names so that the debugger can use them. */ if (flag_handle_signatures) { sigtable_entry_type = make_lang_type (RECORD_TYPE); fields[0] = build_lang_field_decl (FIELD_DECL, tag_identifier, delta_type_node); fields[1] = build_lang_field_decl (FIELD_DECL, vb_off_identifier, delta_type_node); fields[2] = build_lang_field_decl (FIELD_DECL, delta_identifier, delta_type_node); fields[3] = build_lang_field_decl (FIELD_DECL, index_identifier, delta_type_node); fields[4] = build_lang_field_decl (FIELD_DECL, pfn_identifier, ptr_type_node); /* Set the alignment to the max of the alignment of ptr_type_node and delta_type_node. Double alignment wastes a word on the Sparc. */ finish_builtin_type (sigtable_entry_type, SIGTABLE_PTR_TYPE, fields, 4, (TYPE_ALIGN (ptr_type_node) > TYPE_ALIGN (delta_type_node)) ? ptr_type_node : delta_type_node); /* Make this part of an invisible union. */ fields[5] = copy_node (fields[4]); TREE_TYPE (fields[5]) = delta_type_node; DECL_NAME (fields[5]) = vt_off_identifier; DECL_MODE (fields[5]) = TYPE_MODE (delta_type_node); DECL_SIZE (fields[5]) = TYPE_SIZE (delta_type_node); TREE_UNSIGNED (fields[5]) = 0; TREE_CHAIN (fields[4]) = fields[5]; sigtable_entry_type = build_qualified_type (sigtable_entry_type, TYPE_QUAL_CONST); record_builtin_type (RID_MAX, SIGTABLE_PTR_TYPE, sigtable_entry_type); } std_node = build_decl (NAMESPACE_DECL, get_identifier (flag_honor_std ? "fake std":"std"), void_type_node); pushdecl (std_node); global_type_node = make_node (LANG_TYPE); record_unknown_type (global_type_node, "global type"); /* Now, C++. */ current_lang_name = lang_name_cplusplus; { tree bad_alloc_type_node, newtype, deltype; if (flag_honor_std) push_namespace (get_identifier ("std")); bad_alloc_type_node = xref_tag (class_type_node, get_identifier ("bad_alloc"), 1); if (flag_honor_std) pop_namespace (); newtype = build_exception_variant (ptr_ftype_sizetype, build_tree_list (NULL_TREE, bad_alloc_type_node)); deltype = build_exception_variant (void_ftype_ptr, build_tree_list (NULL_TREE, NULL_TREE)); auto_function (ansi_opname[(int) NEW_EXPR], newtype, NOT_BUILT_IN); auto_function (ansi_opname[(int) VEC_NEW_EXPR], newtype, NOT_BUILT_IN); global_delete_fndecl = auto_function (ansi_opname[(int) DELETE_EXPR], deltype, NOT_BUILT_IN); auto_function (ansi_opname[(int) VEC_DELETE_EXPR], deltype, NOT_BUILT_IN); } abort_fndecl = define_function ("__pure_virtual", void_ftype, NOT_BUILT_IN, 0, 0); /* Perform other language dependent initializations. */ init_class_processing (); init_init_processing (); init_search_processing (); if (flag_rtti) init_rtti_processing (); if (flag_exceptions) init_exception_processing (); if (flag_no_inline) { flag_inline_functions = 0; } if (! supports_one_only ()) flag_weak = 0; /* Create the global bindings for __FUNCTION__ and __PRETTY_FUNCTION__. */ declare_function_name (); /* Prepare to check format strings against argument lists. */ init_function_format_info (); /* Show we use EH for cleanups. */ using_eh_for_cleanups (); print_error_function = lang_print_error_function; lang_get_alias_set = &c_get_alias_set; valid_lang_attribute = cp_valid_lang_attribute; /* Maintain consistency. Perhaps we should just complain if they say -fwritable-strings? */ if (flag_writable_strings) flag_const_strings = 0; } /* Function to print any language-specific context for an error message. */ static void lang_print_error_function (file) char *file; { default_print_error_function (file); maybe_print_template_context (); } /* Make a definition for a builtin function named NAME and whose data type is TYPE. TYPE should be a function type with argument types. FUNCTION_CODE tells later passes how to compile calls to this function. See tree.h for its possible values. If LIBRARY_NAME is nonzero, use that for DECL_ASSEMBLER_NAME, the name to be called if we can't opencode the function. */ tree define_function (name, type, function_code, pfn, library_name) const char *name; tree type; enum built_in_function function_code; void (*pfn) PROTO((tree)); const char *library_name; { tree decl = build_lang_decl (FUNCTION_DECL, get_identifier (name), type); DECL_EXTERNAL (decl) = 1; TREE_PUBLIC (decl) = 1; DECL_ARTIFICIAL (decl) = 1; my_friendly_assert (DECL_CONTEXT (decl) == NULL_TREE, 392); DECL_CONTEXT (decl) = FROB_CONTEXT (current_namespace); /* Since `pushdecl' relies on DECL_ASSEMBLER_NAME instead of DECL_NAME, we cannot change DECL_ASSEMBLER_NAME until we have installed this function in the namespace. */ if (pfn) (*pfn) (decl); if (library_name) DECL_ASSEMBLER_NAME (decl) = get_identifier (library_name); make_function_rtl (decl); if (function_code != NOT_BUILT_IN) { DECL_BUILT_IN (decl) = 1; DECL_FUNCTION_CODE (decl) = function_code; } return decl; } /* When we call finish_struct for an anonymous union, we create default copy constructors and such. But, an anonymous union shouldn't have such things; this function undoes the damage to the anonymous union type T. (The reason that we create the synthesized methods is that we don't distinguish `union { int i; }' from `typedef union { int i; } U'. The first is an anonymous union; the second is just an ordinary union type.) */ void fixup_anonymous_union (t) tree t; { tree *q; /* Wipe out memory of synthesized methods */ TYPE_HAS_CONSTRUCTOR (t) = 0; TYPE_HAS_DEFAULT_CONSTRUCTOR (t) = 0; TYPE_HAS_INIT_REF (t) = 0; TYPE_HAS_CONST_INIT_REF (t) = 0; TYPE_HAS_ASSIGN_REF (t) = 0; TYPE_HAS_CONST_ASSIGN_REF (t) = 0; /* Splice the implicitly generated functions out of the TYPE_METHODS list. */ q = &TYPE_METHODS (t); while (*q) { if (DECL_ARTIFICIAL (*q)) *q = TREE_CHAIN (*q); else q = &TREE_CHAIN (*q); } /* ANSI C++ June 5 1992 WP 9.5.3. Anonymous unions may not have function members. */ if (TYPE_METHODS (t)) error ("an anonymous union cannot have function members"); } /* Make sure that a declaration with no declarator is well-formed, i.e. just defines a tagged type or anonymous union. Returns the type defined, if any. */ tree check_tag_decl (declspecs) tree declspecs; { int found_type = 0; tree ob_modifier = NULL_TREE; register tree link; register tree t = NULL_TREE; for (link = declspecs; link; link = TREE_CHAIN (link)) { register tree value = TREE_VALUE (link); if (TYPE_P (value)) { ++found_type; if (IS_AGGR_TYPE (value) || TREE_CODE (value) == ENUMERAL_TYPE) { my_friendly_assert (TYPE_MAIN_DECL (value) != NULL_TREE, 261); t = value; } } else if (value == ridpointers[(int) RID_FRIEND]) { if (current_class_type == NULL_TREE || current_scope () != current_class_type) ob_modifier = value; } else if (value == ridpointers[(int) RID_STATIC] || value == ridpointers[(int) RID_EXTERN] || value == ridpointers[(int) RID_AUTO] || value == ridpointers[(int) RID_REGISTER] || value == ridpointers[(int) RID_INLINE] || value == ridpointers[(int) RID_VIRTUAL] || value == ridpointers[(int) RID_CONST] || value == ridpointers[(int) RID_VOLATILE] || value == ridpointers[(int) RID_EXPLICIT]) ob_modifier = value; } if (found_type > 1) error ("multiple types in one declaration"); /* Inside a class, we might be in a friend or access declaration. Until we have a good way of detecting the latter, don't warn. */ if (t == NULL_TREE && ! current_class_type) pedwarn ("declaration does not declare anything"); /* Check for an anonymous union. We're careful accessing TYPE_IDENTIFIER because some built-in types, like pointer-to-member types, do not have TYPE_NAME. */ else if (t && TREE_CODE (t) == UNION_TYPE && TYPE_NAME (t) && ANON_AGGRNAME_P (TYPE_IDENTIFIER (t))) { /* Anonymous unions are objects, so they can have specifiers. */; SET_ANON_UNION_TYPE_P (t); } else if (ob_modifier) { if (ob_modifier == ridpointers[(int) RID_INLINE] || ob_modifier == ridpointers[(int) RID_VIRTUAL]) cp_error ("`%D' can only be specified for functions", ob_modifier); else if (ob_modifier == ridpointers[(int) RID_FRIEND]) cp_error ("`%D' can only be specified inside a class", ob_modifier); else if (ob_modifier == ridpointers[(int) RID_EXPLICIT]) cp_error ("`%D' can only be specified for constructors", ob_modifier); else cp_error ("`%D' can only be specified for objects and functions", ob_modifier); } return t; } /* Called when a declaration is seen that contains no names to declare. If its type is a reference to a structure, union or enum inherited from a containing scope, shadow that tag name for the current scope with a forward reference. If its type defines a new named structure or union or defines an enum, it is valid but we need not do anything here. Otherwise, it is an error. C++: may have to grok the declspecs to learn about static, complain for anonymous unions. */ void shadow_tag (declspecs) tree declspecs; { tree t = check_tag_decl (declspecs); if (t) maybe_process_partial_specialization (t); /* This is where the variables in an anonymous union are declared. An anonymous union declaration looks like: union { ... } ; because there is no declarator after the union, the parser sends that declaration here. */ if (t && ANON_UNION_TYPE_P (t)) { fixup_anonymous_union (t); if (TYPE_FIELDS (t)) { tree decl = grokdeclarator (NULL_TREE, declspecs, NORMAL, 0, NULL_TREE); finish_anon_union (decl); } } } /* Decode a "typename", such as "int **", returning a ..._TYPE node. */ tree groktypename (typename) tree typename; { if (TREE_CODE (typename) != TREE_LIST) return typename; return grokdeclarator (TREE_VALUE (typename), TREE_PURPOSE (typename), TYPENAME, 0, NULL_TREE); } /* Decode a declarator in an ordinary declaration or data definition. This is called as soon as the type information and variable name have been parsed, before parsing the initializer if any. Here we create the ..._DECL node, fill in its type, and put it on the list of decls for the current context. The ..._DECL node is returned as the value. Exception: for arrays where the length is not specified, the type is left null, to be filled in by `cp_finish_decl'. Function definitions do not come here; they go to start_function instead. However, external and forward declarations of functions do go through here. Structure field declarations are done by grokfield and not through here. */ /* Set this to zero to debug not using the temporary obstack to parse initializers. */ int debug_temp_inits = 1; tree start_decl (declarator, declspecs, initialized, attributes, prefix_attributes) tree declarator, declspecs; int initialized; tree attributes, prefix_attributes; { register tree decl; register tree type, tem; tree context; extern int have_extern_spec; extern int used_extern_spec; tree attrlist; #if 0 /* See code below that used this. */ int init_written = initialized; #endif /* This should only be done once on the top most decl. */ if (have_extern_spec && !used_extern_spec) { declspecs = decl_tree_cons (NULL_TREE, get_identifier ("extern"), declspecs); used_extern_spec = 1; } if (attributes || prefix_attributes) attrlist = build_scratch_list (attributes, prefix_attributes); else attrlist = NULL_TREE; decl = grokdeclarator (declarator, declspecs, NORMAL, initialized, attrlist); if (decl == NULL_TREE || TREE_CODE (decl) == VOID_TYPE) return NULL_TREE; type = TREE_TYPE (decl); if (type == error_mark_node) return NULL_TREE; /* Don't lose if destructors must be executed at file-level. */ if (! processing_template_decl && TREE_STATIC (decl) && TYPE_NEEDS_DESTRUCTOR (complete_type (type)) && !TREE_PERMANENT (decl)) { push_obstacks (&permanent_obstack, &permanent_obstack); decl = copy_node (decl); if (TREE_CODE (type) == ARRAY_TYPE) { tree itype = TYPE_DOMAIN (type); if (itype && ! TREE_PERMANENT (itype)) { itype = build_index_type (copy_to_permanent (TYPE_MAX_VALUE (itype))); type = build_cplus_array_type (TREE_TYPE (type), itype); TREE_TYPE (decl) = type; } } pop_obstacks (); } context = (TREE_CODE (decl) == FUNCTION_DECL && DECL_VIRTUAL_P (decl)) ? DECL_CLASS_CONTEXT (decl) : DECL_CONTEXT (decl); if (initialized && context && TREE_CODE (context) == NAMESPACE_DECL && context != current_namespace && TREE_CODE (decl) == VAR_DECL) { /* When parsing the initializer, lookup should use the object's namespace. */ push_decl_namespace (context); } /* We are only interested in class contexts, later. */ if (context && TREE_CODE (context) == NAMESPACE_DECL) context = NULL_TREE; if (initialized) /* Is it valid for this decl to have an initializer at all? If not, set INITIALIZED to zero, which will indirectly tell `cp_finish_decl' to ignore the initializer once it is parsed. */ switch (TREE_CODE (decl)) { case TYPE_DECL: /* typedef foo = bar means give foo the same type as bar. We haven't parsed bar yet, so `cp_finish_decl' will fix that up. Any other case of an initialization in a TYPE_DECL is an error. */ if (pedantic || list_length (declspecs) > 1) { cp_error ("typedef `%D' is initialized", decl); initialized = 0; } break; case FUNCTION_DECL: cp_error ("function `%#D' is initialized like a variable", decl); initialized = 0; break; default: if (! processing_template_decl) { if (type != error_mark_node) { if (TYPE_SIZE (type) != NULL_TREE && ! TREE_CONSTANT (TYPE_SIZE (type))) { cp_error ("variable-sized object `%D' may not be initialized", decl); initialized = 0; } if (TREE_CODE (type) == ARRAY_TYPE && TYPE_SIZE (complete_type (TREE_TYPE (type))) == NULL_TREE) { cp_error ("elements of array `%#D' have incomplete type", decl); initialized = 0; } } } } if (initialized) { if (! toplevel_bindings_p () && DECL_EXTERNAL (decl)) cp_warning ("declaration of `%#D' has `extern' and is initialized", decl); DECL_EXTERNAL (decl) = 0; if (toplevel_bindings_p ()) TREE_STATIC (decl) = 1; /* Tell `pushdecl' this is an initialized decl even though we don't yet have the initializer expression. Also tell `cp_finish_decl' it may store the real initializer. */ DECL_INITIAL (decl) = error_mark_node; } #ifdef SET_DEFAULT_DECL_ATTRIBUTES SET_DEFAULT_DECL_ATTRIBUTES (decl, attributes); #endif /* Set attributes here so if duplicate decl, will have proper attributes. */ cplus_decl_attributes (decl, attributes, prefix_attributes); if (context && TYPE_SIZE (complete_type (context)) != NULL_TREE) { push_nested_class (context, 2); if (TREE_CODE (decl) == VAR_DECL) { tree field = lookup_field (context, DECL_NAME (decl), 0, 0); if (field == NULL_TREE || TREE_CODE (field) != VAR_DECL) cp_error ("`%#D' is not a static member of `%#T'", decl, context); else { if (DECL_CONTEXT (field) != context) { cp_pedwarn ("ANSI C++ does not permit `%T::%D' to be defined as `%T::%D'", DECL_CONTEXT (field), DECL_NAME (decl), context, DECL_NAME (decl)); DECL_CONTEXT (decl) = DECL_CONTEXT (field); } /* Static data member are tricky; an in-class initialization still doesn't provide a definition, so the in-class declaration will have DECL_EXTERNAL set, but will have an initialization. Thus, duplicate_decls won't warn about this situation, and so we check here. */ if (DECL_INITIAL (decl) && DECL_INITIAL (field)) cp_error ("duplicate initialization of %D", decl); if (duplicate_decls (decl, field)) decl = field; } } else { tree field = check_classfn (context, decl); if (field && duplicate_decls (decl, field)) decl = field; } /* cp_finish_decl sets DECL_EXTERNAL if DECL_IN_AGGR_P is set. */ DECL_IN_AGGR_P (decl) = 0; if ((DECL_LANG_SPECIFIC (decl) && DECL_USE_TEMPLATE (decl)) || CLASSTYPE_USE_TEMPLATE (context)) { SET_DECL_TEMPLATE_SPECIALIZATION (decl); /* [temp.expl.spec] An explicit specialization of a static data member of a template is a definition if the declaration includes an initializer; otherwise, it is a declaration. We check for processing_specialization so this only applies to the new specialization syntax. */ if (DECL_INITIAL (decl) == NULL_TREE && processing_specialization) DECL_EXTERNAL (decl) = 1; } if (DECL_EXTERNAL (decl) && ! DECL_TEMPLATE_SPECIALIZATION (decl)) cp_pedwarn ("declaration of `%#D' outside of class is not definition", decl); } /* Add this decl to the current binding level, but not if it comes from another scope, e.g. a static member variable. TEM may equal DECL or it may be a previous decl of the same name. */ if ((TREE_CODE (decl) != PARM_DECL && DECL_CONTEXT (decl) != NULL_TREE /* Definitions of namespace members outside their namespace are possible. */ && TREE_CODE (DECL_CONTEXT (decl)) != NAMESPACE_DECL) || (TREE_CODE (decl) == TEMPLATE_DECL && !namespace_bindings_p ()) || TREE_CODE (type) == LANG_TYPE /* The declaration of template specializations does not affect the functions available for overload resolution, so we do not call pushdecl. */ || (TREE_CODE (decl) == FUNCTION_DECL && DECL_TEMPLATE_SPECIALIZATION (decl))) tem = decl; else tem = pushdecl (decl); if (processing_template_decl) { if (! current_function_decl) tem = push_template_decl (tem); else if (minimal_parse_mode) DECL_VINDEX (tem) = build_min_nt (DECL_STMT, copy_to_permanent (declarator), copy_to_permanent (declspecs), NULL_TREE); } #if ! defined (ASM_OUTPUT_BSS) && ! defined (ASM_OUTPUT_ALIGNED_BSS) /* Tell the back-end to use or not use .common as appropriate. If we say -fconserve-space, we want this to save .data space, at the expense of wrong semantics. If we say -fno-conserve-space, we want this to produce errors about redefs; to do this we force variables into the data segment. */ DECL_COMMON (tem) = flag_conserve_space || ! TREE_PUBLIC (tem); #endif if (! processing_template_decl) start_decl_1 (tem); /* Corresponding pop_obstacks is done in `cp_finish_decl'. */ push_obstacks_nochange (); #if 0 /* We have no way of knowing whether the initializer will need to be evaluated at run-time or not until we've parsed it, so let's just put it in the permanent obstack. (jason) */ if (init_written && ! (TREE_CODE (tem) == PARM_DECL || (TREE_READONLY (tem) && (TREE_CODE (tem) == VAR_DECL || TREE_CODE (tem) == FIELD_DECL)))) { /* When parsing and digesting the initializer, use temporary storage. Do this even if we will ignore the value. */ if (toplevel_bindings_p () && debug_temp_inits) { if (processing_template_decl || TYPE_NEEDS_CONSTRUCTING (type) || TREE_CODE (type) == REFERENCE_TYPE) /* In this case, the initializer must lay down in permanent storage, since it will be saved until `finish_file' is run. */ ; else temporary_allocation (); } } #endif return tem; } void start_decl_1 (decl) tree decl; { tree type = TREE_TYPE (decl); int initialized = (DECL_INITIAL (decl) != NULL_TREE); if (type == error_mark_node) return; /* If this type of object needs a cleanup, and control may jump past it, make a new binding level so that it is cleaned up only when it is initialized first. */ if (TYPE_NEEDS_DESTRUCTOR (type) && current_binding_level->more_cleanups_ok == 0) pushlevel_temporary (1); if (initialized) /* Is it valid for this decl to have an initializer at all? If not, set INITIALIZED to zero, which will indirectly tell `cp_finish_decl' to ignore the initializer once it is parsed. */ { /* Don't allow initializations for incomplete types except for arrays which might be completed by the initialization. */ if (TYPE_SIZE (complete_type (type)) != NULL_TREE) ; /* A complete type is ok. */ else if (TREE_CODE (type) != ARRAY_TYPE) { cp_error ("variable `%#D' has initializer but incomplete type", decl); initialized = 0; type = TREE_TYPE (decl) = error_mark_node; } else if (TYPE_SIZE (complete_type (TREE_TYPE (type))) == NULL_TREE) { if (DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl)) cp_error ("elements of array `%#D' have incomplete type", decl); /* else we already gave an error in start_decl. */ initialized = 0; } } if (!initialized && TREE_CODE (decl) != TYPE_DECL && TREE_CODE (decl) != TEMPLATE_DECL && IS_AGGR_TYPE (type) && ! DECL_EXTERNAL (decl)) { if ((! processing_template_decl || ! uses_template_parms (type)) && TYPE_SIZE (complete_type (type)) == NULL_TREE) { cp_error ("aggregate `%#D' has incomplete type and cannot be initialized", decl); /* Change the type so that assemble_variable will give DECL an rtl we can live with: (mem (const_int 0)). */ type = TREE_TYPE (decl) = error_mark_node; } else { /* If any base type in the hierarchy of TYPE needs a constructor, then we set initialized to 1. This way any nodes which are created for the purposes of initializing this aggregate will live as long as it does. This is necessary for global aggregates which do not have their initializers processed until the end of the file. */ initialized = TYPE_NEEDS_CONSTRUCTING (type); } } #if 0 /* We don't do this yet for GNU C++. */ /* For a local variable, define the RTL now. */ if (! toplevel_bindings_p () /* But not if this is a duplicate decl and we preserved the rtl from the previous one (which may or may not happen). */ && DECL_RTL (tem) == NULL_RTX) { if (TYPE_SIZE (TREE_TYPE (tem)) != NULL_TREE) expand_decl (tem); else if (TREE_CODE (TREE_TYPE (tem)) == ARRAY_TYPE && DECL_INITIAL (tem) != NULL_TREE) expand_decl (tem); } #endif if (! initialized) DECL_INITIAL (decl) = NULL_TREE; } /* Handle initialization of references. These three arguments are from `cp_finish_decl', and have the same meaning here that they do there. Quotes on semantics can be found in ARM 8.4.3. */ static void grok_reference_init (decl, type, init) tree decl, type, init; { tree tmp; if (init == NULL_TREE) { if ((DECL_LANG_SPECIFIC (decl) == 0 || DECL_IN_AGGR_P (decl) == 0) && ! DECL_THIS_EXTERN (decl)) { cp_error ("`%D' declared as reference but not initialized", decl); if (TREE_CODE (decl) == VAR_DECL) SET_DECL_REFERENCE_SLOT (decl, error_mark_node); } return; } if (init == error_mark_node) return; if (TREE_CODE (type) == REFERENCE_TYPE && TREE_CODE (init) == CONSTRUCTOR) { cp_error ("ANSI C++ forbids use of initializer list to initialize reference `%D'", decl); return; } if (TREE_CODE (init) == TREE_LIST) init = build_compound_expr (init); if (TREE_CODE (TREE_TYPE (init)) == REFERENCE_TYPE) init = convert_from_reference (init); if (TREE_CODE (TREE_TYPE (type)) != ARRAY_TYPE && TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE) { /* Note: default conversion is only called in very special cases. */ init = default_conversion (init); } tmp = convert_to_reference (type, init, CONV_IMPLICIT, LOOKUP_SPECULATIVELY|LOOKUP_NORMAL|DIRECT_BIND, decl); if (tmp == error_mark_node) goto fail; else if (tmp != NULL_TREE) { init = tmp; DECL_INITIAL (decl) = save_expr (init); } else { cp_error ("cannot initialize `%T' from `%T'", type, TREE_TYPE (init)); goto fail; } /* ?? Can this be optimized in some cases to hand back the DECL_INITIAL slot?? */ if (TYPE_SIZE (TREE_TYPE (type))) { init = convert_from_reference (decl); if (TREE_PERMANENT (decl)) init = copy_to_permanent (init); SET_DECL_REFERENCE_SLOT (decl, init); } if (TREE_STATIC (decl) && ! TREE_CONSTANT (DECL_INITIAL (decl))) { expand_static_init (decl, DECL_INITIAL (decl)); DECL_INITIAL (decl) = NULL_TREE; } return; fail: if (TREE_CODE (decl) == VAR_DECL) SET_DECL_REFERENCE_SLOT (decl, error_mark_node); return; } /* Fill in DECL_INITIAL with some magical value to prevent expand_decl from mucking with forces it does not comprehend (i.e. initialization with a constructor). If we are at global scope and won't go into COMMON, fill it in with a dummy CONSTRUCTOR to force the variable into .data; otherwise we can use error_mark_node. */ static tree obscure_complex_init (decl, init) tree decl, init; { if (! flag_no_inline && TREE_STATIC (decl)) { if (extract_init (decl, init)) return NULL_TREE; } #if ! defined (ASM_OUTPUT_BSS) && ! defined (ASM_OUTPUT_ALIGNED_BSS) if (toplevel_bindings_p () && ! DECL_COMMON (decl)) DECL_INITIAL (decl) = build (CONSTRUCTOR, TREE_TYPE (decl), NULL_TREE, NULL_TREE); else #endif DECL_INITIAL (decl) = error_mark_node; return init; } /* Issue an error message if DECL is an uninitialized const variable. */ static void check_for_uninitialized_const_var (decl) tree decl; { tree type = TREE_TYPE (decl); /* ``Unless explicitly declared extern, a const object does not have external linkage and must be initialized. ($8.4; $12.1)'' ARM 7.1.6 */ if (TREE_CODE (decl) == VAR_DECL && TREE_CODE (type) != REFERENCE_TYPE && CP_TYPE_CONST_P (type) && !TYPE_NEEDS_CONSTRUCTING (type) && !DECL_INITIAL (decl)) cp_error ("uninitialized const `%D'", decl); } /* Finish processing of a declaration; install its line number and initial value. If the length of an array type is not known before, it must be determined now, from the initial value, or it is an error. Call `pop_obstacks' iff NEED_POP is nonzero. For C++, `cp_finish_decl' must be fairly evasive: it must keep initializers for aggregates that have constructors alive on the permanent obstack, so that the global initializing functions can be written at the end. INIT0 holds the value of an initializer that should be allowed to escape the normal rules. FLAGS is LOOKUP_ONLYCONVERTING is the = init syntax was used, else 0 if the (init) syntax was used. For functions that take default parameters, DECL points to its "maximal" instantiation. `cp_finish_decl' must then also declared its subsequently lower and lower forms of instantiation, checking for ambiguity as it goes. This can be sped up later. */ void cp_finish_decl (decl, init, asmspec_tree, need_pop, flags) tree decl, init; tree asmspec_tree; int need_pop; int flags; { register tree type; tree cleanup = NULL_TREE, ttype = NULL_TREE; int was_incomplete; int temporary = allocation_temporary_p (); char *asmspec = NULL; int was_readonly = 0; int already_used = 0; tree core_type; /* If this is 0, then we did not change obstacks. */ if (! decl) { if (init) error ("assignment (not initialization) in declaration"); return; } /* If a name was specified, get the string. */ if (asmspec_tree) asmspec = TREE_STRING_POINTER (asmspec_tree); if (init && TREE_CODE (init) == NAMESPACE_DECL) { cp_error ("Cannot initialize `%D' to namespace `%D'", decl, init); init = NULL_TREE; } if (current_class_type && DECL_REAL_CONTEXT (decl) == current_class_type && TYPE_BEING_DEFINED (current_class_type) && (DECL_INITIAL (decl) || init)) DECL_DEFINED_IN_CLASS_P (decl) = 1; if (TREE_CODE (decl) == VAR_DECL && DECL_CONTEXT (decl) && TREE_CODE (DECL_CONTEXT (decl)) == NAMESPACE_DECL && DECL_CONTEXT (decl) != current_namespace && init) { /* Leave the namespace of the object. */ pop_decl_namespace (); } /* If the type of the thing we are declaring either has a constructor, or has a virtual function table pointer, AND its initialization was accepted by `start_decl', then we stayed on the permanent obstack through the declaration, otherwise, changed obstacks as GCC would. */ type = TREE_TYPE (decl); if (type == error_mark_node) { if (toplevel_bindings_p () && temporary) end_temporary_allocation (); return; } if (TYPE_HAS_MUTABLE_P (type)) TREE_READONLY (decl) = 0; if (processing_template_decl) { if (init && DECL_INITIAL (decl)) DECL_INITIAL (decl) = init; if (minimal_parse_mode && ! DECL_ARTIFICIAL (decl)) { tree stmt = DECL_VINDEX (decl); /* If the decl is declaring a member of a local class (in a template function), the DECL_VINDEX will either be NULL, or it will be an actual virtual function index, not a DECL_STMT. */ if (stmt != NULL_TREE && TREE_CODE (stmt) == DECL_STMT) { DECL_VINDEX (decl) = NULL_TREE; TREE_OPERAND (stmt, 2) = copy_to_permanent (init); add_tree (stmt); } } goto finish_end0; } /* Take care of TYPE_DECLs up front. */ if (TREE_CODE (decl) == TYPE_DECL) { if (init && DECL_INITIAL (decl)) { /* typedef foo = bar; store the type of bar as the type of foo. */ TREE_TYPE (decl) = type = TREE_TYPE (init); DECL_INITIAL (decl) = init = NULL_TREE; } if (type != error_mark_node && IS_AGGR_TYPE (type) && DECL_NAME (decl)) { if (TREE_TYPE (DECL_NAME (decl)) && TREE_TYPE (decl) != type) cp_warning ("shadowing previous type declaration of `%#D'", decl); set_identifier_type_value (DECL_NAME (decl), type); CLASSTYPE_GOT_SEMICOLON (type) = 1; } GNU_xref_decl (current_function_decl, decl); /* If we have installed this as the canonical typedef for this type, and that type has not been defined yet, delay emitting the debug information for it, as we will emit it later. */ if (TYPE_MAIN_DECL (TREE_TYPE (decl)) == decl && TYPE_SIZE (TREE_TYPE (decl)) == NULL_TREE) TYPE_DECL_SUPPRESS_DEBUG (decl) = 1; rest_of_decl_compilation (decl, NULL_PTR, DECL_CONTEXT (decl) == NULL_TREE, at_eof); goto finish_end; } if (TREE_CODE (decl) != FUNCTION_DECL) { ttype = target_type (type); } if (! DECL_EXTERNAL (decl) && TREE_READONLY (decl) && TYPE_NEEDS_CONSTRUCTING (type)) { /* Currently, GNU C++ puts constants in text space, making them impossible to initialize. In the future, one would hope for an operating system which understood the difference between initialization and the running of a program. */ was_readonly = 1; TREE_READONLY (decl) = 0; } if (TREE_CODE (decl) == FIELD_DECL) { if (init && init != error_mark_node) my_friendly_assert (TREE_PERMANENT (init), 147); if (asmspec) { /* This must override the asm specifier which was placed by grokclassfn. Lay this out fresh. */ DECL_RTL (TREE_TYPE (decl)) = NULL_RTX; DECL_ASSEMBLER_NAME (decl) = get_identifier (asmspec); make_decl_rtl (decl, asmspec, 0); } } /* If `start_decl' didn't like having an initialization, ignore it now. */ else if (init != NULL_TREE && DECL_INITIAL (decl) == NULL_TREE) init = NULL_TREE; else if (DECL_EXTERNAL (decl)) ; else if (TREE_CODE (type) == REFERENCE_TYPE || (TYPE_LANG_SPECIFIC (type) && IS_SIGNATURE_REFERENCE (type))) { if (TREE_STATIC (decl)) make_decl_rtl (decl, NULL_PTR, toplevel_bindings_p () || pseudo_global_level_p ()); grok_reference_init (decl, type, init); init = NULL_TREE; } GNU_xref_decl (current_function_decl, decl); core_type = type; while (TREE_CODE (core_type) == ARRAY_TYPE) core_type = TREE_TYPE (core_type); if (TREE_CODE (decl) == FIELD_DECL) ; else if (TREE_CODE (decl) == CONST_DECL) { my_friendly_assert (TREE_CODE (decl) != REFERENCE_TYPE, 148); DECL_INITIAL (decl) = init; /* This will keep us from needing to worry about our obstacks. */ my_friendly_assert (init != NULL_TREE, 149); init = NULL_TREE; } else if (init) { if (TYPE_HAS_CONSTRUCTOR (type) || TYPE_NEEDS_CONSTRUCTING (type)) { if (TREE_CODE (type) == ARRAY_TYPE) init = digest_init (type, init, (tree *) 0); else if (TREE_CODE (init) == CONSTRUCTOR && TREE_HAS_CONSTRUCTOR (init)) { if (TYPE_NON_AGGREGATE_CLASS (type)) { cp_error ("`%D' must be initialized by constructor, not by `{...}'", decl); init = error_mark_node; } else goto dont_use_constructor; } } else { dont_use_constructor: if (TREE_CODE (init) != TREE_VEC) init = store_init_value (decl, init); } if (init) /* We must hide the initializer so that expand_decl won't try to do something it does not understand. */ init = obscure_complex_init (decl, init); } else if (DECL_EXTERNAL (decl)) ; else if (TREE_CODE_CLASS (TREE_CODE (type)) == 't' && (IS_AGGR_TYPE (type) || TYPE_NEEDS_CONSTRUCTING (type))) { if (! TYPE_NEEDS_CONSTRUCTING (core_type)) { if (CLASSTYPE_READONLY_FIELDS_NEED_INIT (core_type)) cp_error ("structure `%D' with uninitialized const members", decl); if (CLASSTYPE_REF_FIELDS_NEED_INIT (core_type)) cp_error ("structure `%D' with uninitialized reference members", decl); } check_for_uninitialized_const_var (decl); if (TYPE_SIZE (type) != NULL_TREE && TYPE_NEEDS_CONSTRUCTING (type)) init = obscure_complex_init (decl, NULL_TREE); } else check_for_uninitialized_const_var (decl); /* For top-level declaration, the initial value was read in the temporary obstack. MAXINDEX, rtl, etc. to be made below must go in the permanent obstack; but don't discard the temporary data yet. */ if (toplevel_bindings_p () && temporary) end_temporary_allocation (); /* Deduce size of array from initialization, if not already known. */ if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type) == NULL_TREE && TREE_CODE (decl) != TYPE_DECL) { int do_default = (TREE_STATIC (decl) /* Even if pedantic, an external linkage array may have incomplete type at first. */ ? pedantic && ! DECL_EXTERNAL (decl) : !DECL_EXTERNAL (decl)); tree initializer = init ? init : DECL_INITIAL (decl); int failure = complete_array_type (type, initializer, do_default); if (failure == 1) cp_error ("initializer fails to determine size of `%D'", decl); if (failure == 2) { if (do_default) cp_error ("array size missing in `%D'", decl); /* If a `static' var's size isn't known, make it extern as well as static, so it does not get allocated. If it's not `static', then don't mark it extern; finish_incomplete_decl will give it a default size and it will get allocated. */ else if (!pedantic && TREE_STATIC (decl) && !TREE_PUBLIC (decl)) DECL_EXTERNAL (decl) = 1; } if (pedantic && TYPE_DOMAIN (type) != NULL_TREE && tree_int_cst_lt (TYPE_MAX_VALUE (TYPE_DOMAIN (type)), integer_zero_node)) cp_error ("zero-size array `%D'", decl); layout_decl (decl, 0); } if (TREE_CODE (decl) == VAR_DECL) { if (DECL_SIZE (decl) == NULL_TREE && TYPE_SIZE (complete_type (TREE_TYPE (decl))) != NULL_TREE) layout_decl (decl, 0); if (TREE_STATIC (decl) && DECL_SIZE (decl) == NULL_TREE) { /* A static variable with an incomplete type: that is an error if it is initialized. Otherwise, let it through, but if it is not `extern' then it may cause an error message later. */ if (DECL_INITIAL (decl) != NULL_TREE) cp_error ("storage size of `%D' isn't known", decl); init = NULL_TREE; } else if (!DECL_EXTERNAL (decl) && DECL_SIZE (decl) == NULL_TREE) { /* An automatic variable with an incomplete type: that is an error. Don't talk about array types here, since we took care of that message in grokdeclarator. */ cp_error ("storage size of `%D' isn't known", decl); TREE_TYPE (decl) = error_mark_node; } else if (!DECL_EXTERNAL (decl) && IS_AGGR_TYPE (ttype)) /* Let debugger know it should output info for this type. */ note_debug_info_needed (ttype); if (TREE_STATIC (decl) && DECL_CLASS_SCOPE_P (decl)) note_debug_info_needed (DECL_CONTEXT (decl)); if ((DECL_EXTERNAL (decl) || TREE_STATIC (decl)) && DECL_SIZE (decl) != NULL_TREE && ! TREE_CONSTANT (DECL_SIZE (decl))) { if (TREE_CODE (DECL_SIZE (decl)) == INTEGER_CST) constant_expression_warning (DECL_SIZE (decl)); else cp_error ("storage size of `%D' isn't constant", decl); } if (! DECL_EXTERNAL (decl) && TYPE_NEEDS_DESTRUCTOR (type) /* Cleanups for static variables are handled by `finish_file'. */ && ! TREE_STATIC (decl)) { int yes = suspend_momentary (); cleanup = maybe_build_cleanup (decl); resume_momentary (yes); } } /* PARM_DECLs get cleanups, too. */ else if (TREE_CODE (decl) == PARM_DECL && TYPE_NEEDS_DESTRUCTOR (type)) { if (temporary) end_temporary_allocation (); cleanup = maybe_build_cleanup (decl); if (temporary) resume_temporary_allocation (); } /* Output the assembler code and/or RTL code for variables and functions, unless the type is an undefined structure or union. If not, it will get done when the type is completed. */ was_incomplete = (DECL_SIZE (decl) == NULL_TREE); if (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == FUNCTION_DECL || TREE_CODE (decl) == RESULT_DECL) { /* ??? FIXME: What about nested classes? */ int toplev = toplevel_bindings_p () || pseudo_global_level_p (); int was_temp = (TREE_STATIC (decl) && TYPE_NEEDS_DESTRUCTOR (type) && allocation_temporary_p ()); if (was_temp) end_temporary_allocation (); /* Static data in a function with comdat linkage also has comdat linkage. */ if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl) /* Don't mess with __FUNCTION__. */ && ! TREE_ASM_WRITTEN (decl) && current_function_decl && DECL_CONTEXT (decl) == current_function_decl && (DECL_THIS_INLINE (current_function_decl) || DECL_TEMPLATE_INSTANTIATION (current_function_decl)) && TREE_PUBLIC (current_function_decl)) { /* Rather than try to get this right with inlining, we suppress inlining of such functions. */ current_function_cannot_inline = "function with static variable cannot be inline"; /* If flag_weak, we don't need to mess with this, as we can just make the function weak, and let it refer to its unique local copy. This works because we don't allow the function to be inlined. */ if (! flag_weak) { if (DECL_INTERFACE_KNOWN (current_function_decl)) { TREE_PUBLIC (decl) = 1; DECL_EXTERNAL (decl) = DECL_EXTERNAL (current_function_decl); } else if (DECL_INITIAL (decl) == NULL_TREE || DECL_INITIAL (decl) == error_mark_node) { TREE_PUBLIC (decl) = 1; DECL_COMMON (decl) = 1; } /* else we lose. We can only do this if we can use common, which we can't if it has been initialized. */ if (TREE_PUBLIC (decl)) DECL_ASSEMBLER_NAME (decl) = build_static_name (current_function_decl, DECL_NAME (decl)); else if (! DECL_ARTIFICIAL (decl)) { cp_warning_at ("sorry: semantics of inline function static data `%#D' are wrong (you'll wind up with multiple copies)", decl); cp_warning_at (" you can work around this by removing the initializer", decl); } } } else if (TREE_CODE (decl) == VAR_DECL && DECL_LANG_SPECIFIC (decl) && DECL_COMDAT (decl)) /* Set it up again; we might have set DECL_INITIAL since the last time. */ comdat_linkage (decl); if (TREE_CODE (decl) == VAR_DECL && DECL_VIRTUAL_P (decl)) make_decl_rtl (decl, NULL_PTR, toplev); else if (TREE_CODE (decl) == VAR_DECL && TREE_READONLY (decl) && DECL_INITIAL (decl) != NULL_TREE && DECL_INITIAL (decl) != error_mark_node && ! EMPTY_CONSTRUCTOR_P (DECL_INITIAL (decl))) { DECL_INITIAL (decl) = save_expr (DECL_INITIAL (decl)); if (asmspec) DECL_ASSEMBLER_NAME (decl) = get_identifier (asmspec); if (! toplev && TREE_STATIC (decl) && ! TREE_SIDE_EFFECTS (decl) && ! TREE_PUBLIC (decl) && ! DECL_EXTERNAL (decl) && ! TYPE_NEEDS_DESTRUCTOR (type) && DECL_MODE (decl) != BLKmode) { /* If this variable is really a constant, then fill its DECL_RTL slot with something which won't take up storage. If something later should take its address, we can always give it legitimate RTL at that time. */ DECL_RTL (decl) = gen_reg_rtx (DECL_MODE (decl)); store_expr (DECL_INITIAL (decl), DECL_RTL (decl), 0); TREE_ASM_WRITTEN (decl) = 1; } else if (toplev && ! TREE_PUBLIC (decl)) { /* If this is a static const, change its apparent linkage if it belongs to a #pragma interface. */ if (!interface_unknown) { TREE_PUBLIC (decl) = 1; DECL_EXTERNAL (decl) = interface_only; } make_decl_rtl (decl, asmspec, toplev); } else rest_of_decl_compilation (decl, asmspec, toplev, at_eof); } else if (TREE_CODE (decl) == VAR_DECL && DECL_LANG_SPECIFIC (decl) && DECL_IN_AGGR_P (decl)) { if (TREE_STATIC (decl)) { if (init == NULL_TREE #ifdef DEFAULT_STATIC_DEFS /* If this code is dead, then users must explicitly declare static member variables outside the class def'n as well. */ && TYPE_NEEDS_CONSTRUCTING (type) #endif ) { DECL_EXTERNAL (decl) = 1; make_decl_rtl (decl, asmspec, 1); } else rest_of_decl_compilation (decl, asmspec, toplev, at_eof); } else /* Just a constant field. Should not need any rtl. */ goto finish_end0; } else rest_of_decl_compilation (decl, asmspec, toplev, at_eof); if (was_temp) resume_temporary_allocation (); if (type != error_mark_node && TYPE_LANG_SPECIFIC (core_type) && CLASSTYPE_ABSTRACT_VIRTUALS (core_type)) abstract_virtuals_error (decl, core_type); else if ((TREE_CODE (type) == FUNCTION_TYPE || TREE_CODE (type) == METHOD_TYPE) && TYPE_LANG_SPECIFIC (TREE_TYPE (type)) && CLASSTYPE_ABSTRACT_VIRTUALS (TREE_TYPE (type))) abstract_virtuals_error (decl, TREE_TYPE (type)); if (TYPE_LANG_SPECIFIC (core_type) && IS_SIGNATURE (core_type)) signature_error (decl, core_type); else if ((TREE_CODE (type) == FUNCTION_TYPE || TREE_CODE (type) == METHOD_TYPE) && TYPE_LANG_SPECIFIC (TREE_TYPE (type)) && IS_SIGNATURE (TREE_TYPE (type))) signature_error (decl, TREE_TYPE (type)); if (TREE_CODE (decl) == FUNCTION_DECL) ; else if (DECL_EXTERNAL (decl) && ! (DECL_LANG_SPECIFIC (decl) && DECL_NOT_REALLY_EXTERN (decl))) { if (init) DECL_INITIAL (decl) = init; } else if (TREE_STATIC (decl) && type != error_mark_node) { /* Cleanups for static variables are handled by `finish_file'. */ if (TYPE_NEEDS_CONSTRUCTING (type) || init != NULL_TREE || TYPE_NEEDS_DESTRUCTOR (type)) expand_static_init (decl, init); } else if (! toplev) { /* This is a declared decl which must live until the end of the binding contour. It may need a cleanup. */ /* Recompute the RTL of a local array now if it used to be an incomplete type. */ if (was_incomplete && ! TREE_STATIC (decl)) { /* If we used it already as memory, it must stay in memory. */ TREE_ADDRESSABLE (decl) = TREE_USED (decl); /* If it's still incomplete now, no init will save it. */ if (DECL_SIZE (decl) == NULL_TREE) DECL_INITIAL (decl) = NULL_TREE; expand_decl (decl); } else if (! TREE_ASM_WRITTEN (decl) && (TYPE_SIZE (type) != NULL_TREE || TREE_CODE (type) == ARRAY_TYPE)) { /* Do this here, because we did not expand this decl's rtl in start_decl. */ if (DECL_RTL (decl) == NULL_RTX) expand_decl (decl); else if (cleanup) { /* XXX: Why don't we use decl here? */ /* Ans: Because it was already expanded? */ if (! expand_decl_cleanup (NULL_TREE, cleanup)) cp_error ("parser lost in parsing declaration of `%D'", decl); /* Cleanup used up here. */ cleanup = NULL_TREE; } } if (current_binding_level->is_for_scope) { struct binding_level *outer = current_binding_level->level_chain; /* Check to see if the same name is already bound at the outer level, either because it was directly declared, or because a dead for-decl got preserved. In either case, the code would not have been valid under the ARM scope rules, so clear is_for_scope for the current_binding_level. Otherwise, we need to preserve the temp slot for decl to last into the outer binding level. */ tree outer_binding = TREE_CHAIN (IDENTIFIER_BINDING (DECL_NAME (decl))); if (outer_binding && BINDING_LEVEL (outer_binding) == outer && (TREE_CODE (BINDING_VALUE (outer_binding)) == VAR_DECL) && DECL_DEAD_FOR_LOCAL (BINDING_VALUE (outer_binding))) { BINDING_VALUE (outer_binding) = DECL_SHADOWED_FOR_VAR (BINDING_VALUE (outer_binding)); current_binding_level->is_for_scope = 0; } else if (DECL_IN_MEMORY_P (decl)) preserve_temp_slots (DECL_RTL (decl)); } expand_start_target_temps (); if (DECL_SIZE (decl) && type != error_mark_node) { /* Compute and store the initial value. */ expand_decl_init (decl); already_used = TREE_USED (decl) || TREE_USED (type); if (init || TYPE_NEEDS_CONSTRUCTING (type)) { emit_line_note (DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl)); expand_aggr_init (decl, init, flags); } /* Set this to 0 so we can tell whether an aggregate which was initialized was ever used. Don't do this if it has a destructor, so we don't complain about the 'resource allocation is initialization' idiom. */ /* Now set attribute((unused)) on types so decls of that type will be marked used. (see TREE_USED, above.) This avoids the warning problems this particular code tried to work around. */ if (TYPE_NEEDS_CONSTRUCTING (type) && ! already_used && cleanup == NULL_TREE && DECL_NAME (decl)) TREE_USED (decl) = 0; if (already_used) TREE_USED (decl) = 1; } /* Cleanup any temporaries needed for the initial value. */ expand_end_target_temps (); if (DECL_SIZE (decl) && type != error_mark_node) { /* Store the cleanup, if there was one. */ if (cleanup) { if (! expand_decl_cleanup (decl, cleanup)) cp_error ("parser lost in parsing declaration of `%D'", decl); } } } finish_end0: /* Undo call to `pushclass' that was done in `start_decl' due to initialization of qualified member variable. I.e., Foo::x = 10; */ { tree context = DECL_REAL_CONTEXT (decl); if (context && TREE_CODE_CLASS (TREE_CODE (context)) == 't' && (TREE_CODE (decl) == VAR_DECL /* We also have a pushclass done that we need to undo here if we're at top level and declare a method. */ || TREE_CODE (decl) == FUNCTION_DECL) /* If size hasn't been set, we're still defining it, and therefore inside the class body; don't pop the binding level.. */ && TYPE_SIZE (context) != NULL_TREE && context == current_class_type) pop_nested_class (); } } finish_end: /* If requested, warn about definitions of large data objects. */ if (warn_larger_than && ! processing_template_decl && (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL) && !DECL_EXTERNAL (decl)) { register tree decl_size = DECL_SIZE (decl); if (decl_size && TREE_CODE (decl_size) == INTEGER_CST) { unsigned units = TREE_INT_CST_LOW (decl_size) / BITS_PER_UNIT; if (units > larger_than_size) warning_with_decl (decl, "size of `%s' is %u bytes", units); } } if (need_pop) { /* Resume permanent allocation, if not within a function. */ /* The corresponding push_obstacks_nochange is in start_decl, start_method, groktypename, and in grokfield. */ pop_obstacks (); } if (was_readonly) TREE_READONLY (decl) = 1; } /* This is here for a midend callback from c-common.c */ void finish_decl (decl, init, asmspec_tree) tree decl, init; tree asmspec_tree; { cp_finish_decl (decl, init, asmspec_tree, 1, 0); } void expand_static_init (decl, init) tree decl; tree init; { tree oldstatic = value_member (decl, static_aggregates); if (oldstatic) { if (TREE_PURPOSE (oldstatic) && init != NULL_TREE) cp_error ("multiple initializations given for `%D'", decl); } else if (! toplevel_bindings_p ()) { /* Emit code to perform this initialization but once. */ tree temp; /* Remember this information until end of file. */ push_obstacks (&permanent_obstack, &permanent_obstack); /* Emit code to perform this initialization but once. This code looks like: static int temp = 0; if (!temp) { // Do initialization. temp = 1; // Register variable for destruction at end of program. } Note that the `temp' variable is only set to 1 *after* the initialization is complete. This ensures that an exception, thrown during the construction, will cause the variable to reinitialized when we pass through this code again, as per: [stmt.dcl] If the initialization exits by throwing an exception, the initialization is not complete, so it will be tried again the next time control enters the declaration. In theory, this process should be thread-safe, too; multiple threads should not be able to initialize the variable more than once. We don't yet attempt to ensure thread-safety. */ temp = get_temp_name (integer_type_node, 1); rest_of_decl_compilation (temp, NULL_PTR, 0, 0); /* Begin the conditional initialization. */ expand_start_cond (build_binary_op (EQ_EXPR, temp, integer_zero_node), 0); expand_start_target_temps (); /* Do the initialization itself. */ if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)) || (init && TREE_CODE (init) == TREE_LIST)) { expand_aggr_init (decl, init, 0); do_pending_stack_adjust (); } else if (init) expand_assignment (decl, init, 0, 0); /* Set TEMP to 1. */ expand_assignment (temp, integer_one_node, 0, 0); /* Cleanup any temporaries needed for the initial value. If destroying one of the temporaries causes an exception to be thrown, then the object itself has still been fully constructed. */ expand_end_target_temps (); /* Use atexit to register a function for destroying this static variable. */ if (TYPE_NEEDS_DESTRUCTOR (TREE_TYPE (decl))) { tree cleanup, fcall; static tree Atexit = 0; int saved_flag_access_control; if (Atexit == 0) { tree atexit_fndecl, PFV, pfvlist; /* Remember this information until end of file. */ push_obstacks (&permanent_obstack, &permanent_obstack); PFV = build_pointer_type (build_function_type (void_type_node, void_list_node)); pfvlist = tree_cons (NULL_TREE, PFV, void_list_node); push_lang_context (lang_name_c); atexit_fndecl = builtin_function ("atexit", build_function_type (void_type_node, pfvlist), NOT_BUILT_IN, NULL_PTR); mark_used (atexit_fndecl); Atexit = default_conversion (atexit_fndecl); pop_lang_context (); pop_obstacks (); } /* Call build_cleanup before we enter the anonymous function so that any access checks will be done relative to the current scope, rather than the scope of the anonymous function. */ build_cleanup (decl); /* Now start the function. */ cleanup = start_anon_func (); /* Now, recompute the cleanup. It may contain SAVE_EXPRs that refer to the original function, rather than the anonymous one. That will make the back-end think that nested functions are in use, which causes confusion. */ saved_flag_access_control = flag_access_control; flag_access_control = 0; fcall = build_cleanup (decl); flag_access_control = saved_flag_access_control; /* Finish off the function. */ expand_expr_stmt (fcall); end_anon_func (); /* Call atexit with the cleanup function. */ mark_addressable (cleanup); cleanup = build_unary_op (ADDR_EXPR, cleanup, 0); fcall = build_function_call (Atexit, expr_tree_cons (NULL_TREE, cleanup, NULL_TREE)); expand_expr_stmt (fcall); } expand_end_cond (); /* Resume old (possibly temporary) allocation. */ pop_obstacks (); } else { /* This code takes into account memory allocation policy of `start_decl'. Namely, if TYPE_NEEDS_CONSTRUCTING does not hold for this object, then we must make permanent the storage currently in the temporary obstack. */ if (!TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))) preserve_initializer (); static_aggregates = perm_tree_cons (init, decl, static_aggregates); } } /* Make TYPE a complete type based on INITIAL_VALUE. Return 0 if successful, 1 if INITIAL_VALUE can't be deciphered, 2 if there was no information (in which case assume 0 if DO_DEFAULT). */ int complete_array_type (type, initial_value, do_default) tree type, initial_value; int do_default; { register tree maxindex = NULL_TREE; int value = 0; /* Allocate on the same obstack as TYPE. */ push_obstacks (TYPE_OBSTACK (type), TYPE_OBSTACK (type)); if (initial_value) { /* Note MAXINDEX is really the maximum index, one less than the size. */ if (TREE_CODE (initial_value) == STRING_CST) { int eltsize = int_size_in_bytes (TREE_TYPE (TREE_TYPE (initial_value))); maxindex = build_int_2 ((TREE_STRING_LENGTH (initial_value) / eltsize) - 1, 0); } else if (TREE_CODE (initial_value) == CONSTRUCTOR) { tree elts = CONSTRUCTOR_ELTS (initial_value); maxindex = size_binop (MINUS_EXPR, integer_zero_node, size_one_node); for (; elts; elts = TREE_CHAIN (elts)) { if (TREE_PURPOSE (elts)) maxindex = TREE_PURPOSE (elts); else maxindex = size_binop (PLUS_EXPR, maxindex, size_one_node); } maxindex = copy_node (maxindex); } else { /* Make an error message unless that happened already. */ if (initial_value != error_mark_node) value = 1; else initial_value = NULL_TREE; /* Prevent further error messages. */ maxindex = build_int_2 (0, 0); } } if (!maxindex) { if (do_default) maxindex = build_int_2 (0, 0); value = 2; } if (maxindex) { tree itype; tree domain; domain = build_index_type (maxindex); TYPE_DOMAIN (type) = domain; if (! TREE_TYPE (maxindex)) TREE_TYPE (maxindex) = domain; if (initial_value) itype = TREE_TYPE (initial_value); else itype = NULL; if (itype && !TYPE_DOMAIN (itype)) TYPE_DOMAIN (itype) = domain; /* The type of the main variant should never be used for arrays of different sizes. It should only ever be completed with the size of the array. */ if (! TYPE_DOMAIN (TYPE_MAIN_VARIANT (type))) TYPE_DOMAIN (TYPE_MAIN_VARIANT (type)) = domain; } pop_obstacks(); /* Lay out the type now that we can get the real answer. */ layout_type (type); return value; } /* Return zero if something is declared to be a member of type CTYPE when in the context of CUR_TYPE. STRING is the error message to print in that case. Otherwise, quietly return 1. */ static int member_function_or_else (ctype, cur_type, string) tree ctype, cur_type; const char *string; { if (ctype && ctype != cur_type) { error (string, TYPE_NAME_STRING (ctype)); return 0; } return 1; } /* Subroutine of `grokdeclarator'. */ /* Generate errors possibly applicable for a given set of specifiers. This is for ARM $7.1.2. */ static void bad_specifiers (object, type, virtualp, quals, inlinep, friendp, raises) tree object; const char *type; int virtualp, quals, friendp, raises, inlinep; { if (virtualp) cp_error ("`%D' declared as a `virtual' %s", object, type); if (inlinep) cp_error ("`%D' declared as an `inline' %s", object, type); if (quals) cp_error ("`const' and `volatile' function specifiers on `%D' invalid in %s declaration", object, type); if (friendp) cp_error_at ("invalid friend declaration", object); if (raises) cp_error_at ("invalid exception specifications", object); } /* CTYPE is class type, or null if non-class. TYPE is type this FUNCTION_DECL should have, either FUNCTION_TYPE or METHOD_TYPE. DECLARATOR is the function's name. VIRTUALP is truthvalue of whether the function is virtual or not. FLAGS are to be passed through to `grokclassfn'. QUALS are qualifiers indicating whether the function is `const' or `volatile'. RAISES is a list of exceptions that this function can raise. CHECK is 1 if we must find this method in CTYPE, 0 if we should not look, and -1 if we should not call `grokclassfn' at all. Returns `NULL_TREE' if something goes wrong, after issuing applicable error messages. */ static tree grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals, raises, check, friendp, publicp, inlinep, funcdef_flag, template_count, in_namespace) tree ctype, type; tree declarator; tree orig_declarator; int virtualp; enum overload_flags flags; tree quals, raises; int check, friendp, publicp, inlinep, funcdef_flag, template_count; tree in_namespace; { tree cname, decl; int staticp = ctype && TREE_CODE (type) == FUNCTION_TYPE; int has_default_arg = 0; tree t; if (ctype) cname = TREE_CODE (TYPE_NAME (ctype)) == TYPE_DECL ? TYPE_IDENTIFIER (ctype) : TYPE_NAME (ctype); else cname = NULL_TREE; if (raises) { type = build_exception_variant (type, raises); } decl = build_lang_decl (FUNCTION_DECL, declarator, type); /* Propagate volatile out from type to decl. */ if (TYPE_VOLATILE (type)) TREE_THIS_VOLATILE (decl) = 1; /* If this decl has namespace scope, set that up. */ if (in_namespace) set_decl_namespace (decl, in_namespace, friendp); else if (publicp && ! ctype) DECL_CONTEXT (decl) = FROB_CONTEXT (current_namespace); /* `main' and builtins have implicit 'C' linkage. */ if ((MAIN_NAME_P (declarator) || (IDENTIFIER_LENGTH (declarator) > 10 && IDENTIFIER_POINTER (declarator)[0] == '_' && IDENTIFIER_POINTER (declarator)[1] == '_' && strncmp (IDENTIFIER_POINTER (declarator)+2, "builtin_", 8) == 0)) && current_lang_name == lang_name_cplusplus && ctype == NULL_TREE /* NULL_TREE means global namespace. */ && DECL_CONTEXT (decl) == NULL_TREE) DECL_LANGUAGE (decl) = lang_c; /* Should probably propagate const out from type to decl I bet (mrs). */ if (staticp) { DECL_STATIC_FUNCTION_P (decl) = 1; DECL_CONTEXT (decl) = ctype; } if (ctype) DECL_CLASS_CONTEXT (decl) = ctype; if (ctype == NULL_TREE && DECL_MAIN_P (decl)) { if (processing_template_decl) error ("cannot declare `main' to be a template"); if (inlinep) error ("cannot declare `main' to be inline"); else if (! publicp) error ("cannot declare `main' to be static"); inlinep = 0; publicp = 1; } /* Members of anonymous types and local classes have no linkage; make them internal. */ if (ctype && (ANON_AGGRNAME_P (TYPE_IDENTIFIER (ctype)) || hack_decl_function_context (TYPE_MAIN_DECL (ctype)))) publicp = 0; if (publicp) { /* [basic.link]: A name with no linkage (notably, the name of a class or enumeration declared in a local scope) shall not be used to declare an entity with linkage. Only check this for public decls for now. */ t = no_linkage_check (TREE_TYPE (decl)); if (t) { if (ANON_AGGRNAME_P (TYPE_IDENTIFIER (t))) { if (DECL_LANGUAGE (decl) == lang_c) /* Allow this; it's pretty common in C. */; else cp_pedwarn ("non-local function `%#D' uses anonymous type", decl); } else cp_pedwarn ("non-local function `%#D' uses local type `%T'", decl, t); } } TREE_PUBLIC (decl) = publicp; if (! publicp) { DECL_INTERFACE_KNOWN (decl) = 1; DECL_NOT_REALLY_EXTERN (decl) = 1; } if (inlinep) DECL_THIS_INLINE (decl) = DECL_INLINE (decl) = 1; DECL_EXTERNAL (decl) = 1; if (quals != NULL_TREE && TREE_CODE (type) == FUNCTION_TYPE) { cp_error ("%smember function `%D' cannot have `%T' method qualifier", (ctype ? "static " : "non-"), decl, TREE_VALUE (quals)); quals = NULL_TREE; } if (IDENTIFIER_OPNAME_P (DECL_NAME (decl))) grok_op_properties (decl, virtualp, check < 0); if (ctype && hack_decl_function_context (decl)) DECL_NO_STATIC_CHAIN (decl) = 1; for (t = TYPE_ARG_TYPES (TREE_TYPE (decl)); t; t = TREE_CHAIN (t)) if (TREE_PURPOSE (t) && TREE_CODE (TREE_PURPOSE (t)) == DEFAULT_ARG) { has_default_arg = 1; break; } if (friendp && TREE_CODE (orig_declarator) == TEMPLATE_ID_EXPR) { if (funcdef_flag) cp_error ("defining explicit specialization `%D' in friend declaration", orig_declarator); else { if (PROCESSING_REAL_TEMPLATE_DECL_P ()) { /* Something like `template friend void f()'. */ cp_error ("template-id `%D' in declaration of primary template", orig_declarator); return NULL_TREE; } /* A friend declaration of the form friend void f<>(). Record the information in the TEMPLATE_ID_EXPR. */ SET_DECL_IMPLICIT_INSTANTIATION (decl); DECL_TEMPLATE_INFO (decl) = perm_tree_cons (TREE_OPERAND (orig_declarator, 0), TREE_OPERAND (orig_declarator, 1), NULL_TREE); if (has_default_arg) { cp_error ("default arguments are not allowed in declaration of friend template specialization `%D'", decl); return NULL_TREE; } if (inlinep) { cp_error ("`inline' is not allowed in declaration of friend template specialization `%D'", decl); return NULL_TREE; } } } if (has_default_arg) add_defarg_fn (decl); /* Plain overloading: will not be grok'd by grokclassfn. */ if (! ctype && ! processing_template_decl && DECL_LANGUAGE (decl) != lang_c && (! DECL_USE_TEMPLATE (decl) || name_mangling_version < 1)) set_mangled_name_for_decl (decl); if (funcdef_flag) /* Make the init_value nonzero so pushdecl knows this is not tentative. error_mark_node is replaced later with the BLOCK. */ DECL_INITIAL (decl) = error_mark_node; /* Caller will do the rest of this. */ if (check < 0) return decl; if (check && funcdef_flag) DECL_INITIAL (decl) = error_mark_node; if (flags == NO_SPECIAL && ctype && constructor_name (cname) == declarator) { tree tmp; /* Just handle constructors here. We could do this inside the following if stmt, but I think that the code is more legible by breaking this case out. See comments below for what each of the following calls is supposed to do. */ DECL_CONSTRUCTOR_P (decl) = 1; grokclassfn (ctype, decl, flags, quals); decl = check_explicit_specialization (orig_declarator, decl, template_count, 2 * (funcdef_flag != 0) + 4 * (friendp != 0)); if (decl == error_mark_node) return NULL_TREE; if ((! TYPE_FOR_JAVA (ctype) || check_java_method (decl)) && check) { tmp = check_classfn (ctype, decl); if (tmp && TREE_CODE (tmp) == TEMPLATE_DECL) tmp = DECL_TEMPLATE_RESULT(tmp); if (tmp && DECL_ARTIFICIAL (tmp)) cp_error ("definition of implicitly-declared `%D'", tmp); if (tmp && duplicate_decls (decl, tmp)) return tmp; } if (! grok_ctor_properties (ctype, decl)) return NULL_TREE; } else { tree tmp; /* Function gets the ugly name, field gets the nice one. This call may change the type of the function (because of default parameters)! */ if (ctype != NULL_TREE) grokclassfn (ctype, decl, flags, quals); decl = check_explicit_specialization (orig_declarator, decl, template_count, 2 * (funcdef_flag != 0) + 4 * (friendp != 0)); if (decl == error_mark_node) return NULL_TREE; if (ctype != NULL_TREE && (! TYPE_FOR_JAVA (ctype) || check_java_method (decl)) && check) { tmp = check_classfn (ctype, decl); if (tmp && TREE_CODE (tmp) == TEMPLATE_DECL) tmp = DECL_TEMPLATE_RESULT (tmp); if (tmp && DECL_STATIC_FUNCTION_P (tmp) && TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE) { /* Remove the `this' parm added by grokclassfn. XXX Isn't this done in start_function, too? */ revert_static_member_fn (&decl, NULL, NULL); last_function_parms = TREE_CHAIN (last_function_parms); } if (tmp && DECL_ARTIFICIAL (tmp)) cp_error ("definition of implicitly-declared `%D'", tmp); if (tmp) { /* Attempt to merge the declarations. This can fail, in the case of some illegal specialization declarations. */ if (!duplicate_decls (decl, tmp)) cp_error ("no `%#D' member function declared in class `%T'", decl, ctype); return tmp; } } if (ctype == NULL_TREE || check) return decl; if (virtualp) { DECL_VIRTUAL_P (decl) = 1; if (DECL_VINDEX (decl) == NULL_TREE) DECL_VINDEX (decl) = error_mark_node; IDENTIFIER_VIRTUAL_P (DECL_NAME (decl)) = 1; } } return decl; } static tree grokvardecl (type, declarator, specbits_in, initialized, constp, in_namespace) tree type; tree declarator; RID_BIT_TYPE *specbits_in; int initialized; int constp; tree in_namespace; { tree decl; RID_BIT_TYPE specbits; specbits = *specbits_in; if (TREE_CODE (type) == OFFSET_TYPE) { /* If you declare a static member so that it can be initialized, the code will reach here. */ tree basetype = TYPE_OFFSET_BASETYPE (type); type = TREE_TYPE (type); decl = build_lang_field_decl (VAR_DECL, declarator, type); DECL_CONTEXT (decl) = basetype; DECL_CLASS_CONTEXT (decl) = basetype; DECL_ASSEMBLER_NAME (decl) = build_static_name (basetype, declarator); } else { tree context; if (in_namespace) context = in_namespace; else if (namespace_bindings_p () || RIDBIT_SETP (RID_EXTERN, specbits)) context = current_namespace; else context = NULL_TREE; decl = build_decl (VAR_DECL, declarator, complete_type (type)); if (context) set_decl_namespace (decl, context, 0); context = DECL_CONTEXT (decl); if (declarator && context && current_lang_name != lang_name_c) DECL_ASSEMBLER_NAME (decl) = build_static_name (context, declarator); } if (in_namespace) set_decl_namespace (decl, in_namespace, 0); if (RIDBIT_SETP (RID_EXTERN, specbits)) { DECL_THIS_EXTERN (decl) = 1; DECL_EXTERNAL (decl) = !initialized; } /* In class context, static means one per class, public access, and static storage. */ if (DECL_CLASS_SCOPE_P (decl)) { TREE_PUBLIC (decl) = 1; TREE_STATIC (decl) = 1; DECL_EXTERNAL (decl) = 0; } /* At top level, either `static' or no s.c. makes a definition (perhaps tentative), and absence of `static' makes it public. */ else if (toplevel_bindings_p ()) { TREE_PUBLIC (decl) = (RIDBIT_NOTSETP (RID_STATIC, specbits) && (DECL_THIS_EXTERN (decl) || ! constp)); TREE_STATIC (decl) = ! DECL_EXTERNAL (decl); } /* Not at top level, only `static' makes a static definition. */ else { TREE_STATIC (decl) = !! RIDBIT_SETP (RID_STATIC, specbits); TREE_PUBLIC (decl) = DECL_EXTERNAL (decl); } if (TREE_PUBLIC (decl)) { /* [basic.link]: A name with no linkage (notably, the name of a class or enumeration declared in a local scope) shall not be used to declare an entity with linkage. Only check this for public decls for now. */ tree t = no_linkage_check (TREE_TYPE (decl)); if (t) { if (ANON_AGGRNAME_P (TYPE_IDENTIFIER (t))) /* Ignore for now; `enum { foo } e' is pretty common. */; else cp_pedwarn ("non-local variable `%#D' uses local type `%T'", decl, t); } } return decl; } /* Create and return a canonical pointer to member function type, for TYPE, which is a POINTER_TYPE to a METHOD_TYPE. */ tree build_ptrmemfunc_type (type) tree type; { tree fields[4]; tree t; tree u; /* If a canonical type already exists for this type, use it. We use this method instead of type_hash_canon, because it only does a simple equality check on the list of field members. */ if ((t = TYPE_GET_PTRMEMFUNC_TYPE (type))) return t; push_obstacks (TYPE_OBSTACK (type), TYPE_OBSTACK (type)); u = make_lang_type (UNION_TYPE); SET_IS_AGGR_TYPE (u, 0); fields[0] = build_lang_field_decl (FIELD_DECL, pfn_identifier, type); fields[1] = build_lang_field_decl (FIELD_DECL, delta2_identifier, delta_type_node); finish_builtin_type (u, "__ptrmemfunc_type", fields, 1, ptr_type_node); TYPE_NAME (u) = NULL_TREE; t = make_lang_type (RECORD_TYPE); /* Let the front-end know this is a pointer to member function... */ TYPE_PTRMEMFUNC_FLAG (t) = 1; /* ... and not really an aggregate. */ SET_IS_AGGR_TYPE (t, 0); fields[0] = build_lang_field_decl (FIELD_DECL, delta_identifier, delta_type_node); fields[1] = build_lang_field_decl (FIELD_DECL, index_identifier, delta_type_node); fields[2] = build_lang_field_decl (FIELD_DECL, pfn_or_delta2_identifier, u); finish_builtin_type (t, "__ptrmemfunc_type", fields, 2, ptr_type_node); pop_obstacks (); /* Zap out the name so that the back-end will give us the debugging information for this anonymous RECORD_TYPE. */ TYPE_NAME (t) = NULL_TREE; TYPE_SET_PTRMEMFUNC_TYPE (type, t); /* Seems to be wanted. */ CLASSTYPE_GOT_SEMICOLON (t) = 1; return t; } /* DECL is a VAR_DECL defined in-class, whose TYPE is also given. Check to see that the definition is valid. Issue appropriate error messages. Return 1 if the definition is particularly bad, or 0 otherwise. */ int check_static_variable_definition (decl, type) tree decl; tree type; { /* Motion 10 at San Diego: If a static const integral data member is initialized with an integral constant expression, the initializer may appear either in the declaration (within the class), or in the definition, but not both. If it appears in the class, the member is a member constant. The file-scope definition is always required. */ if (CLASS_TYPE_P (type) || TREE_CODE (type) == REFERENCE_TYPE) { cp_error ("in-class initialization of static data member of non-integral type `%T'", type); /* If we just return the declaration, crashes will sometimes occur. We therefore return void_type_node, as if this was a friend declaration, to cause callers to completely ignore this declaration. */ return 1; } else if (!CP_TYPE_CONST_P (type)) cp_error ("ANSI C++ forbids in-class initialization of non-const static member `%D'", decl); else if (pedantic && !INTEGRAL_TYPE_P (type)) cp_pedwarn ("ANSI C++ forbids initialization of member constant `%D' of non-integral type `%T'", decl, type); return 0; } /* Given declspecs and a declarator, determine the name and type of the object declared and construct a ..._DECL node for it. (In one case we can return a ..._TYPE node instead. For invalid input we sometimes return 0.) DECLSPECS is a chain of tree_list nodes whose value fields are the storage classes and type specifiers. DECL_CONTEXT says which syntactic context this declaration is in: NORMAL for most contexts. Make a VAR_DECL or FUNCTION_DECL or TYPE_DECL. FUNCDEF for a function definition. Like NORMAL but a few different error messages in each case. Return value may be zero meaning this definition is too screwy to try to parse. MEMFUNCDEF for a function definition. Like FUNCDEF but prepares to handle member functions (which have FIELD context). Return value may be zero meaning this definition is too screwy to try to parse. PARM for a parameter declaration (either within a function prototype or before a function body). Make a PARM_DECL, or return void_type_node. CATCHPARM for a parameter declaration before a catch clause. TYPENAME if for a typename (in a cast or sizeof). Don't make a DECL node; just return the ..._TYPE node. FIELD for a struct or union field; make a FIELD_DECL. BITFIELD for a field with specified width. INITIALIZED is 1 if the decl has an initializer. ATTRLIST is a TREE_LIST node with prefix attributes in TREE_VALUE and normal attributes in TREE_PURPOSE, or NULL_TREE. In the TYPENAME case, DECLARATOR is really an absolute declarator. It may also be so in the PARM case, for a prototype where the argument type is specified but not the name. This function is where the complicated C meanings of `static' and `extern' are interpreted. For C++, if there is any monkey business to do, the function which calls this one must do it, i.e., prepending instance variables, renaming overloaded function names, etc. Note that for this C++, it is an error to define a method within a class which does not belong to that class. Except in the case where SCOPE_REFs are implicitly known (such as methods within a class being redundantly qualified), declarations which involve SCOPE_REFs are returned as SCOPE_REFs (class_name::decl_name). The caller must also deal with this. If a constructor or destructor is seen, and the context is FIELD, then the type gains the attribute TREE_HAS_x. If such a declaration is erroneous, NULL_TREE is returned. QUALS is used only for FUNCDEF and MEMFUNCDEF cases. For a member function, these are the qualifiers to give to the `this' pointer. May return void_type_node if the declarator turned out to be a friend. See grokfield for details. */ enum return_types { return_normal, return_ctor, return_dtor, return_conversion }; tree grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) tree declspecs; tree declarator; enum decl_context decl_context; int initialized; tree attrlist; { RID_BIT_TYPE specbits; int nclasses = 0; tree spec; tree type = NULL_TREE; int longlong = 0; int constp; int restrictp; int volatilep; int type_quals; int virtualp, explicitp, friendp, inlinep, staticp; int explicit_int = 0; int explicit_char = 0; int defaulted_int = 0; int opaque_typedef = 0; tree typedef_decl = NULL_TREE; char *name; tree typedef_type = NULL_TREE; int funcdef_flag = 0; enum tree_code innermost_code = ERROR_MARK; int bitfield = 0; #if 0 /* See the code below that used this. */ tree decl_machine_attr = NULL_TREE; #endif /* Set this to error_mark_node for FIELD_DECLs we could not handle properly. All FIELD_DECLs we build here have `init' put into their DECL_INITIAL. */ tree init = NULL_TREE; /* Keep track of what sort of function is being processed so that we can warn about default return values, or explicit return values which do not match prescribed defaults. */ enum return_types return_type = return_normal; tree dname = NULL_TREE; tree ctype = current_class_type; tree ctor_return_type = NULL_TREE; enum overload_flags flags = NO_SPECIAL; tree quals = NULL_TREE; tree raises = NULL_TREE; int template_count = 0; tree in_namespace = NULL_TREE; tree inner_attrs; int ignore_attrs; RIDBIT_RESET_ALL (specbits); if (decl_context == FUNCDEF) funcdef_flag = 1, decl_context = NORMAL; else if (decl_context == MEMFUNCDEF) funcdef_flag = -1, decl_context = FIELD; else if (decl_context == BITFIELD) bitfield = 1, decl_context = FIELD; /* Look inside a declarator for the name being declared and get it as a string, for an error message. */ { tree *next = &declarator; register tree decl; name = NULL; while (next && *next) { decl = *next; switch (TREE_CODE (decl)) { case TREE_LIST: /* For attributes. */ next = &TREE_VALUE (decl); break; case COND_EXPR: ctype = NULL_TREE; next = &TREE_OPERAND (decl, 0); break; case BIT_NOT_EXPR: /* For C++ destructors! */ { tree name = TREE_OPERAND (decl, 0); tree rename = NULL_TREE; my_friendly_assert (flags == NO_SPECIAL, 152); flags = DTOR_FLAG; return_type = return_dtor; if (TREE_CODE (name) == TYPE_DECL) TREE_OPERAND (decl, 0) = name = constructor_name (name); my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 153); if (ctype == NULL_TREE) { if (current_class_type == NULL_TREE) { error ("destructors must be member functions"); flags = NO_SPECIAL; } else { tree t = constructor_name (current_class_name); if (t != name) rename = t; } } else { tree t = constructor_name (ctype); if (t != name) rename = t; } if (rename) { cp_error ("destructor `%T' must match class name `%T'", name, rename); TREE_OPERAND (decl, 0) = rename; } next = &name; } break; case ADDR_EXPR: /* C++ reference declaration */ /* Fall through. */ case ARRAY_REF: case INDIRECT_REF: ctype = NULL_TREE; innermost_code = TREE_CODE (decl); next = &TREE_OPERAND (decl, 0); break; case CALL_EXPR: if (parmlist_is_exprlist (TREE_OPERAND (decl, 1))) { /* This is actually a variable declaration using constructor syntax. We need to call start_decl and cp_finish_decl so we can get the variable initialized... */ tree attributes, prefix_attributes; *next = TREE_OPERAND (decl, 0); init = TREE_OPERAND (decl, 1); if (attrlist) { attributes = TREE_PURPOSE (attrlist); prefix_attributes = TREE_VALUE (attrlist); } else { attributes = NULL_TREE; prefix_attributes = NULL_TREE; } decl = start_decl (declarator, declspecs, 1, attributes, prefix_attributes); if (decl) { /* Look for __unused__ attribute */ if (TREE_USED (TREE_TYPE (decl))) TREE_USED (decl) = 1; finish_decl (decl, init, NULL_TREE); } else cp_error ("invalid declarator"); return 0; } innermost_code = TREE_CODE (decl); if (decl_context == FIELD && ctype == NULL_TREE) ctype = current_class_type; if (ctype && TREE_OPERAND (decl, 0) && (TREE_CODE (TREE_OPERAND (decl, 0)) == TYPE_DECL && ((DECL_NAME (TREE_OPERAND (decl, 0)) == constructor_name_full (ctype)) || (DECL_NAME (TREE_OPERAND (decl, 0)) == constructor_name (ctype))))) TREE_OPERAND (decl, 0) = constructor_name (ctype); next = &TREE_OPERAND (decl, 0); decl = *next; if (ctype != NULL_TREE && decl != NULL_TREE && flags != DTOR_FLAG && decl == constructor_name (ctype)) { return_type = return_ctor; ctor_return_type = ctype; } ctype = NULL_TREE; break; case TEMPLATE_ID_EXPR: { tree fns = TREE_OPERAND (decl, 0); if (TREE_CODE (fns) == LOOKUP_EXPR) fns = TREE_OPERAND (fns, 0); dname = fns; if (TREE_CODE (dname) == COMPONENT_REF) dname = TREE_OPERAND (dname, 1); if (TREE_CODE (dname) != IDENTIFIER_NODE) { my_friendly_assert (is_overloaded_fn (dname), 19990331); dname = DECL_NAME (get_first_fn (dname)); } } /* Fall through. */ case IDENTIFIER_NODE: if (TREE_CODE (decl) == IDENTIFIER_NODE) dname = decl; next = 0; if (is_rid (dname)) { cp_error ("declarator-id missing; using reserved word `%D'", dname); name = IDENTIFIER_POINTER (dname); } if (! IDENTIFIER_OPNAME_P (dname) /* GNU/Linux headers use '__op'. Arrgh. */ || (IDENTIFIER_TYPENAME_P (dname) && ! TREE_TYPE (dname))) name = IDENTIFIER_POINTER (dname); else { if (IDENTIFIER_TYPENAME_P (dname)) { my_friendly_assert (flags == NO_SPECIAL, 154); flags = TYPENAME_FLAG; ctor_return_type = TREE_TYPE (dname); return_type = return_conversion; } name = operator_name_string (dname); } break; /* C++ extension */ case SCOPE_REF: { /* Perform error checking, and decide on a ctype. */ tree cname = TREE_OPERAND (decl, 0); if (cname == NULL_TREE) ctype = NULL_TREE; else if (TREE_CODE (cname) == NAMESPACE_DECL) { ctype = NULL_TREE; in_namespace = TREE_OPERAND (decl, 0); TREE_OPERAND (decl, 0) = NULL_TREE; } else if (! is_aggr_type (cname, 1)) TREE_OPERAND (decl, 0) = NULL_TREE; /* Must test TREE_OPERAND (decl, 1), in case user gives us `typedef (class::memfunc)(int); memfunc *memfuncptr;' */ else if (TREE_OPERAND (decl, 1) && TREE_CODE (TREE_OPERAND (decl, 1)) == INDIRECT_REF) ctype = cname; else if (TREE_CODE (cname) == TEMPLATE_TYPE_PARM || TREE_CODE (cname) == TEMPLATE_TEMPLATE_PARM) { cp_error ("`%T::%D' is not a valid declarator", cname, TREE_OPERAND (decl, 1)); cp_error (" perhaps you want `typename %T::%D' to make it a type", cname, TREE_OPERAND (decl, 1)); return void_type_node; } else if (ctype == NULL_TREE) ctype = cname; else if (TREE_COMPLEXITY (decl) == current_class_depth) TREE_OPERAND (decl, 0) = ctype; else { if (! UNIQUELY_DERIVED_FROM_P (cname, ctype)) { cp_error ("type `%T' is not derived from type `%T'", cname, ctype); TREE_OPERAND (decl, 0) = NULL_TREE; } else ctype = cname; } if (ctype && TREE_CODE (TREE_OPERAND (decl, 1)) == TYPE_DECL && ((DECL_NAME (TREE_OPERAND (decl, 1)) == constructor_name_full (ctype)) || (DECL_NAME (TREE_OPERAND (decl, 1)) == constructor_name (ctype)))) TREE_OPERAND (decl, 1) = constructor_name (ctype); next = &TREE_OPERAND (decl, 1); decl = *next; if (ctype) { if (TREE_CODE (decl) == IDENTIFIER_NODE && constructor_name (ctype) == decl) { return_type = return_ctor; ctor_return_type = ctype; } else if (TREE_CODE (decl) == BIT_NOT_EXPR && TREE_CODE (TREE_OPERAND (decl, 0)) == IDENTIFIER_NODE && (constructor_name (ctype) == TREE_OPERAND (decl, 0) || constructor_name_full (ctype) == TREE_OPERAND (decl, 0))) { return_type = return_dtor; ctor_return_type = ctype; flags = DTOR_FLAG; TREE_OPERAND (decl, 0) = constructor_name (ctype); next = &TREE_OPERAND (decl, 0); } } } break; case ERROR_MARK: next = 0; break; case TYPE_DECL: /* Parse error puts this typespec where a declarator should go. */ cp_error ("`%T' specified as declarator-id", DECL_NAME (decl)); if (TREE_TYPE (decl) == current_class_type) cp_error (" perhaps you want `%T' for a constructor", current_class_name); dname = DECL_NAME (decl); name = IDENTIFIER_POINTER (dname); /* Avoid giving two errors for this. */ IDENTIFIER_CLASS_VALUE (dname) = NULL_TREE; declspecs = temp_tree_cons (NULL_TREE, integer_type_node, declspecs); *next = dname; next = 0; break; default: cp_compiler_error ("`%D' as declarator", decl); return 0; /* We used to do a 155 abort here. */ } } if (name == NULL) name = "type name"; } /* A function definition's declarator must have the form of a function declarator. */ if (funcdef_flag && innermost_code != CALL_EXPR) return 0; if (((dname && IDENTIFIER_OPNAME_P (dname)) || flags == TYPENAME_FLAG) && innermost_code != CALL_EXPR && ! (ctype && declspecs == NULL_TREE)) { cp_error ("declaration of `%D' as non-function", dname); return void_type_node; } /* Anything declared one level down from the top level must be one of the parameters of a function (because the body is at least two levels down). */ /* This heuristic cannot be applied to C++ nodes! Fixed, however, by not allowing C++ class definitions to specify their parameters with xdecls (must be spec.d in the parmlist). Since we now wait to push a class scope until we are sure that we are in a legitimate method context, we must set oldcname explicitly (since current_class_name is not yet alive). We also want to avoid calling this a PARM if it is in a namespace. */ if (decl_context == NORMAL && ! namespace_bindings_p () && ! pseudo_global_level_p ()) { struct binding_level *b = current_binding_level; current_binding_level = b->level_chain; if (current_binding_level != 0 && toplevel_bindings_p ()) decl_context = PARM; current_binding_level = b; } /* Look through the decl specs and record which ones appear. Some typespecs are defined as built-in typenames. Others, the ones that are modifiers of other types, are represented by bits in SPECBITS: set the bits for the modifiers that appear. Storage class keywords are also in SPECBITS. If there is a typedef name or a type, store the type in TYPE. This includes builtin typedefs such as `int'. Set EXPLICIT_INT if the type is `int' or `char' and did not come from a user typedef. Set LONGLONG if `long' is mentioned twice. For C++, constructors and destructors have their own fast treatment. */ for (spec = declspecs; spec; spec = TREE_CHAIN (spec)) { register int i; register tree id; /* Certain parse errors slip through. For example, `int class;' is not caught by the parser. Try weakly to recover here. */ if (TREE_CODE (spec) != TREE_LIST) return 0; id = TREE_VALUE (spec); if (TREE_CODE (id) == IDENTIFIER_NODE) { if (id == ridpointers[(int) RID_INT] || id == ridpointers[(int) RID_CHAR] || id == ridpointers[(int) RID_BOOL] || id == ridpointers[(int) RID_WCHAR]) { if (type) { if (id == ridpointers[(int) RID_BOOL]) error ("`bool' is now a keyword"); else cp_error ("extraneous `%T' ignored", id); } else { if (id == ridpointers[(int) RID_INT]) explicit_int = 1; else if (id == ridpointers[(int) RID_CHAR]) explicit_char = 1; type = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (id)); } goto found; } /* C++ aggregate types. */ if (IDENTIFIER_HAS_TYPE_VALUE (id)) { if (type) cp_error ("multiple declarations `%T' and `%T'", type, id); else type = IDENTIFIER_TYPE_VALUE (id); goto found; } for (i = (int) RID_FIRST_MODIFIER; i <= (int) RID_LAST_MODIFIER; i++) { if (ridpointers[i] == id) { if (i == (int) RID_LONG && RIDBIT_SETP (i, specbits)) { if (pedantic && ! in_system_header && warn_long_long) pedwarn ("ANSI C++ does not support `long long'"); if (longlong) error ("`long long long' is too long for GCC"); else longlong = 1; } else if (RIDBIT_SETP (i, specbits)) pedwarn ("duplicate `%s'", IDENTIFIER_POINTER (id)); RIDBIT_SET (i, specbits); goto found; } } } /* C++ aggregate types. */ else if (TREE_CODE (id) == TYPE_DECL || TREE_CODE (id) == TEMPLATE_DECL) { if (type) cp_error ("multiple declarations `%T' and `%T'", type, TREE_TYPE (id)); else { type = TREE_TYPE (id); TREE_VALUE (spec) = type; } goto found; } if (type) error ("two or more data types in declaration of `%s'", name); else if (TREE_CODE (id) == IDENTIFIER_NODE) { register tree t = lookup_name (id, 1); if (!t || TREE_CODE (t) != TYPE_DECL) error ("`%s' fails to be a typedef or built in type", IDENTIFIER_POINTER (id)); else { type = TREE_TYPE (t); #if 0 /* See the code below that used this. */ decl_machine_attr = DECL_MACHINE_ATTRIBUTES (id); #endif typedef_decl = t; } } else if (id != error_mark_node) /* Can't change CLASS nodes into RECORD nodes here! */ type = id; found: ; } typedef_type = type; /* No type at all: default to `int', and set DEFAULTED_INT because it was not a user-defined typedef. Except when we have a `typedef' inside a signature, in which case the type defaults to `unknown type' and is instantiated when assigning to a signature pointer or ref. */ if (type == NULL_TREE && (RIDBIT_SETP (RID_SIGNED, specbits) || RIDBIT_SETP (RID_UNSIGNED, specbits) || RIDBIT_SETP (RID_LONG, specbits) || RIDBIT_SETP (RID_SHORT, specbits))) { /* These imply 'int'. */ type = integer_type_node; defaulted_int = 1; } if (type == NULL_TREE) { explicit_int = -1; if (return_type == return_dtor) type = void_type_node; else if (return_type == return_ctor) type = build_pointer_type (ctor_return_type); else if (return_type == return_conversion) type = ctor_return_type; else if (current_class_type && IS_SIGNATURE (current_class_type) && RIDBIT_SETP (RID_TYPEDEF, specbits) && (decl_context == FIELD || decl_context == NORMAL)) { explicit_int = 0; opaque_typedef = 1; type = copy_node (opaque_type_node); } else { /* We handle `main' specially here, because 'main () { }' is so common. With no options, it is allowed. With -Wreturn-type, it is a warning. It is only an error with -pedantic-errors. */ int is_main = (funcdef_flag && MAIN_NAME_P (dname) && ctype == NULL_TREE && in_namespace == NULL_TREE && current_namespace == global_namespace); if (in_system_header) /* Allow it, sigh. */; else if (pedantic || ! is_main) cp_pedwarn ("ANSI C++ forbids declaration `%D' with no type", dname); else if (warn_return_type) cp_warning ("ANSI C++ forbids declaration `%D' with no type", dname); type = integer_type_node; } } else if (return_type == return_dtor) { error ("return type specification for destructor invalid"); type = void_type_node; } else if (return_type == return_ctor) { error ("return type specification for constructor invalid"); type = build_pointer_type (ctor_return_type); } else if (return_type == return_conversion) { if (!same_type_p (type, ctor_return_type)) cp_error ("operator `%T' declared to return `%T'", ctor_return_type, type); else cp_pedwarn ("return type specified for `operator %T'", ctor_return_type); type = ctor_return_type; } ctype = NULL_TREE; /* Now process the modifiers that were specified and check for invalid combinations. */ /* Long double is a special combination. */ if (RIDBIT_SETP (RID_LONG, specbits) && TYPE_MAIN_VARIANT (type) == double_type_node) { RIDBIT_RESET (RID_LONG, specbits); type = build_qualified_type (long_double_type_node, CP_TYPE_QUALS (type)); } /* Check all other uses of type modifiers. */ if (RIDBIT_SETP (RID_UNSIGNED, specbits) || RIDBIT_SETP (RID_SIGNED, specbits) || RIDBIT_SETP (RID_LONG, specbits) || RIDBIT_SETP (RID_SHORT, specbits)) { int ok = 0; if (TREE_CODE (type) == REAL_TYPE) error ("short, signed or unsigned invalid for `%s'", name); else if (TREE_CODE (type) != INTEGER_TYPE) error ("long, short, signed or unsigned invalid for `%s'", name); else if (RIDBIT_SETP (RID_LONG, specbits) && RIDBIT_SETP (RID_SHORT, specbits)) error ("long and short specified together for `%s'", name); else if ((RIDBIT_SETP (RID_LONG, specbits) || RIDBIT_SETP (RID_SHORT, specbits)) && explicit_char) error ("long or short specified with char for `%s'", name); else if ((RIDBIT_SETP (RID_LONG, specbits) || RIDBIT_SETP (RID_SHORT, specbits)) && TREE_CODE (type) == REAL_TYPE) error ("long or short specified with floating type for `%s'", name); else if (RIDBIT_SETP (RID_SIGNED, specbits) && RIDBIT_SETP (RID_UNSIGNED, specbits)) error ("signed and unsigned given together for `%s'", name); else { ok = 1; if (!explicit_int && !defaulted_int && !explicit_char && pedantic) { pedwarn ("long, short, signed or unsigned used invalidly for `%s'", name); if (flag_pedantic_errors) ok = 0; } } /* Discard the type modifiers if they are invalid. */ if (! ok) { RIDBIT_RESET (RID_UNSIGNED, specbits); RIDBIT_RESET (RID_SIGNED, specbits); RIDBIT_RESET (RID_LONG, specbits); RIDBIT_RESET (RID_SHORT, specbits); longlong = 0; } } if (RIDBIT_SETP (RID_COMPLEX, specbits) && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE) { error ("complex invalid for `%s'", name); RIDBIT_RESET (RID_COMPLEX, specbits); } /* Decide whether an integer type is signed or not. Optionally treat bitfields as signed by default. */ if (RIDBIT_SETP (RID_UNSIGNED, specbits) || (bitfield && ! flag_signed_bitfields && (explicit_int || defaulted_int || explicit_char /* A typedef for plain `int' without `signed' can be controlled just like plain `int'. */ || ! (typedef_decl != NULL_TREE && C_TYPEDEF_EXPLICITLY_SIGNED (typedef_decl))) && TREE_CODE (type) != ENUMERAL_TYPE && RIDBIT_NOTSETP (RID_SIGNED, specbits))) { if (longlong) type = long_long_unsigned_type_node; else if (RIDBIT_SETP (RID_LONG, specbits)) type = long_unsigned_type_node; else if (RIDBIT_SETP (RID_SHORT, specbits)) type = short_unsigned_type_node; else if (type == char_type_node) type = unsigned_char_type_node; else if (typedef_decl) type = unsigned_type (type); else type = unsigned_type_node; } else if (RIDBIT_SETP (RID_SIGNED, specbits) && type == char_type_node) type = signed_char_type_node; else if (longlong) type = long_long_integer_type_node; else if (RIDBIT_SETP (RID_LONG, specbits)) type = long_integer_type_node; else if (RIDBIT_SETP (RID_SHORT, specbits)) type = short_integer_type_node; if (RIDBIT_SETP (RID_COMPLEX, specbits)) { /* If we just have "complex", it is equivalent to "complex double", but if any modifiers at all are specified it is the complex form of TYPE. E.g, "complex short" is "complex short int". */ if (defaulted_int && ! longlong && ! (RIDBIT_SETP (RID_LONG, specbits) || RIDBIT_SETP (RID_SHORT, specbits) || RIDBIT_SETP (RID_SIGNED, specbits) || RIDBIT_SETP (RID_UNSIGNED, specbits))) type = complex_double_type_node; else if (type == integer_type_node) type = complex_integer_type_node; else if (type == float_type_node) type = complex_float_type_node; else if (type == double_type_node) type = complex_double_type_node; else if (type == long_double_type_node) type = complex_long_double_type_node; else type = build_complex_type (type); } if (return_type == return_conversion && (RIDBIT_SETP (RID_CONST, specbits) || RIDBIT_SETP (RID_VOLATILE, specbits) || RIDBIT_SETP (RID_RESTRICT, specbits))) cp_error ("qualifiers are not allowed on declaration of `operator %T'", ctor_return_type); /* Set CONSTP if this declaration is `const', whether by explicit specification or via a typedef. Likewise for VOLATILEP. */ constp = !! RIDBIT_SETP (RID_CONST, specbits) + CP_TYPE_CONST_P (type); restrictp = !! RIDBIT_SETP (RID_RESTRICT, specbits) + CP_TYPE_RESTRICT_P (type); volatilep = !! RIDBIT_SETP (RID_VOLATILE, specbits) + CP_TYPE_VOLATILE_P (type); type_quals = ((constp ? TYPE_QUAL_CONST : 0) | (restrictp ? TYPE_QUAL_RESTRICT : 0) | (volatilep ? TYPE_QUAL_VOLATILE : 0)); type = cp_build_qualified_type (type, type_quals); staticp = 0; inlinep = !! RIDBIT_SETP (RID_INLINE, specbits); virtualp = RIDBIT_SETP (RID_VIRTUAL, specbits); RIDBIT_RESET (RID_VIRTUAL, specbits); explicitp = RIDBIT_SETP (RID_EXPLICIT, specbits) != 0; RIDBIT_RESET (RID_EXPLICIT, specbits); if (RIDBIT_SETP (RID_STATIC, specbits)) staticp = 1 + (decl_context == FIELD); if (virtualp && staticp == 2) { cp_error ("member `%D' cannot be declared both virtual and static", dname); staticp = 0; } friendp = RIDBIT_SETP (RID_FRIEND, specbits); RIDBIT_RESET (RID_FRIEND, specbits); /* $7.1.2, Function specifiers */ if (friendp && explicitp) error ("only declarations of constructors can be `explicit'"); if (RIDBIT_SETP (RID_MUTABLE, specbits)) { if (decl_context == PARM) { error ("non-member `%s' cannot be declared `mutable'", name); RIDBIT_RESET (RID_MUTABLE, specbits); } else if (friendp || decl_context == TYPENAME) { error ("non-object member `%s' cannot be declared `mutable'", name); RIDBIT_RESET (RID_MUTABLE, specbits); } } /* Warn if two storage classes are given. Default to `auto'. */ if (RIDBIT_ANY_SET (specbits)) { if (RIDBIT_SETP (RID_STATIC, specbits)) nclasses++; if (RIDBIT_SETP (RID_EXTERN, specbits)) nclasses++; if (decl_context == PARM && nclasses > 0) error ("storage class specifiers invalid in parameter declarations"); if (RIDBIT_SETP (RID_TYPEDEF, specbits)) { if (decl_context == PARM) error ("typedef declaration invalid in parameter declaration"); nclasses++; } if (RIDBIT_SETP (RID_AUTO, specbits)) nclasses++; if (RIDBIT_SETP (RID_REGISTER, specbits)) nclasses++; } /* Give error if `virtual' is used outside of class declaration. */ if (virtualp && (current_class_name == NULL_TREE || decl_context != FIELD)) { error ("virtual outside class declaration"); virtualp = 0; } if (current_class_name == NULL_TREE && RIDBIT_SETP (RID_MUTABLE, specbits)) { error ("only members can be declared mutable"); RIDBIT_RESET (RID_MUTABLE, specbits); } /* Static anonymous unions are dealt with here. */ if (staticp && decl_context == TYPENAME && TREE_CODE (declspecs) == TREE_LIST && ANON_UNION_TYPE_P (TREE_VALUE (declspecs))) decl_context = FIELD; /* Give error if `const,' `volatile,' `inline,' `friend,' or `virtual' is used in a signature member function declaration. */ if (decl_context == FIELD && IS_SIGNATURE (current_class_type) && RIDBIT_NOTSETP (RID_TYPEDEF, specbits)) { if (type_quals != TYPE_UNQUALIFIED) { error ("type qualifiers specified for signature member function `%s'", name); type_quals = TYPE_UNQUALIFIED; } if (inlinep) { error ("`inline' specified for signature member function `%s'", name); /* Later, we'll make signature member functions inline. */ inlinep = 0; } if (friendp) { error ("`friend' declaration in signature definition"); friendp = 0; } if (virtualp) { error ("`virtual' specified for signature member function `%s'", name); /* Later, we'll make signature member functions virtual. */ virtualp = 0; } } /* Warn about storage classes that are invalid for certain kinds of declarations (parameters, typenames, etc.). */ if (nclasses > 1) error ("multiple storage classes in declaration of `%s'", name); else if (decl_context != NORMAL && nclasses > 0) { if ((decl_context == PARM || decl_context == CATCHPARM) && (RIDBIT_SETP (RID_REGISTER, specbits) || RIDBIT_SETP (RID_AUTO, specbits))) ; else if (RIDBIT_SETP (RID_TYPEDEF, specbits)) ; else if (decl_context == FIELD && ! IS_SIGNATURE (current_class_type) /* C++ allows static class elements */ && RIDBIT_SETP (RID_STATIC, specbits)) /* C++ also allows inlines and signed and unsigned elements, but in those cases we don't come in here. */ ; else { if (decl_context == FIELD) { tree tmp = NULL_TREE; register int op = 0; if (declarator) { /* Avoid trying to get an operand off an identifier node. */ if (TREE_CODE (declarator) == IDENTIFIER_NODE) tmp = declarator; else tmp = TREE_OPERAND (declarator, 0); op = IDENTIFIER_OPNAME_P (tmp); } error ("storage class specified for %s `%s'", IS_SIGNATURE (current_class_type) ? (op ? "signature member operator" : "signature member function") : (op ? "member operator" : "field"), op ? operator_name_string (tmp) : name); } else error (((decl_context == PARM || decl_context == CATCHPARM) ? "storage class specified for parameter `%s'" : "storage class specified for typename"), name); RIDBIT_RESET (RID_REGISTER, specbits); RIDBIT_RESET (RID_AUTO, specbits); RIDBIT_RESET (RID_EXTERN, specbits); if (decl_context == FIELD && IS_SIGNATURE (current_class_type)) { RIDBIT_RESET (RID_STATIC, specbits); staticp = 0; } } } else if (RIDBIT_SETP (RID_EXTERN, specbits) && initialized && !funcdef_flag) { if (toplevel_bindings_p ()) { /* It's common practice (and completely valid) to have a const be initialized and declared extern. */ if (!(type_quals & TYPE_QUAL_CONST)) warning ("`%s' initialized and declared `extern'", name); } else error ("`%s' has both `extern' and initializer", name); } else if (RIDBIT_SETP (RID_EXTERN, specbits) && funcdef_flag && ! toplevel_bindings_p ()) error ("nested function `%s' declared `extern'", name); else if (toplevel_bindings_p ()) { if (RIDBIT_SETP (RID_AUTO, specbits)) error ("top-level declaration of `%s' specifies `auto'", name); } if (nclasses > 0 && friendp) error ("storage class specifiers invalid in friend function declarations"); /* Now figure out the structure of the declarator proper. Descend through it, creating more complex types, until we reach the declared identifier (or NULL_TREE, in an absolute declarator). */ inner_attrs = NULL_TREE; ignore_attrs = 0; while (declarator && TREE_CODE (declarator) != IDENTIFIER_NODE && TREE_CODE (declarator) != TEMPLATE_ID_EXPR) { /* Each level of DECLARATOR is either an ARRAY_REF (for ...[..]), an INDIRECT_REF (for *...), a CALL_EXPR (for ...(...)), an identifier (for the name being declared) or a null pointer (for the place in an absolute declarator where the name was omitted). For the last two cases, we have just exited the loop. For C++ it could also be a SCOPE_REF (for class :: ...). In this case, we have converted sensible names to types, and those are the values we use to qualify the member name. an ADDR_EXPR (for &...), a BIT_NOT_EXPR (for destructors) At this point, TYPE is the type of elements of an array, or for a function to return, or for a pointer to point to. After this sequence of ifs, TYPE is the type of the array or function or pointer, and DECLARATOR has had its outermost layer removed. */ if (type == error_mark_node) { if (TREE_CODE (declarator) == SCOPE_REF) declarator = TREE_OPERAND (declarator, 1); else declarator = TREE_OPERAND (declarator, 0); continue; } if (quals != NULL_TREE && (declarator == NULL_TREE || TREE_CODE (declarator) != SCOPE_REF)) { if (ctype == NULL_TREE && TREE_CODE (type) == METHOD_TYPE) ctype = TYPE_METHOD_BASETYPE (type); if (ctype != NULL_TREE) { tree dummy = build_decl (TYPE_DECL, NULL_TREE, type); ctype = grok_method_quals (ctype, dummy, quals); type = TREE_TYPE (dummy); quals = NULL_TREE; } } /* See the comment for the TREE_LIST case, below. */ if (ignore_attrs) ignore_attrs = 0; else if (inner_attrs) { decl_attributes (type, inner_attrs, NULL_TREE); inner_attrs = NULL_TREE; } switch (TREE_CODE (declarator)) { case TREE_LIST: { /* We encode a declarator with embedded attributes using a TREE_LIST. The attributes apply to the declarator directly inside them, so we have to skip an iteration before applying them to the type. If the declarator just inside is the declarator-id, we apply the attrs to the decl itself. */ inner_attrs = TREE_PURPOSE (declarator); ignore_attrs = 1; declarator = TREE_VALUE (declarator); } break; case ARRAY_REF: { register tree itype = NULL_TREE; register tree size = TREE_OPERAND (declarator, 1); /* The index is a signed object `sizetype' bits wide. */ tree index_type = signed_type (sizetype); declarator = TREE_OPERAND (declarator, 0); /* Check for some types that there cannot be arrays of. */ if (TREE_CODE (type) == VOID_TYPE) { cp_error ("declaration of `%D' as array of voids", dname); type = error_mark_node; } if (TREE_CODE (type) == FUNCTION_TYPE) { cp_error ("declaration of `%D' as array of functions", dname); type = error_mark_node; } /* ARM $8.4.3: Since you can't have a pointer to a reference, you can't have arrays of references. If we allowed them, then we'd be saying x[i] is valid for an array x, but then you'd have to ask: what does `*(x + i)' mean? */ if (TREE_CODE (type) == REFERENCE_TYPE) { if (decl_context == TYPENAME) cp_error ("cannot make arrays of references"); else cp_error ("declaration of `%D' as array of references", dname); type = error_mark_node; } if (TREE_CODE (type) == OFFSET_TYPE) { cp_error ("declaration of `%D' as array of data members", dname); type = error_mark_node; } if (TREE_CODE (type) == METHOD_TYPE) { cp_error ("declaration of `%D' as array of function members", dname); type = error_mark_node; } if (size == error_mark_node) type = error_mark_node; else if (TREE_CODE (type) == ARRAY_TYPE && !TYPE_DOMAIN (type)) { /* [dcl.array] the constant expressions that specify the bounds of the arrays can be omitted only for the first member of the sequence. */ cp_error ("declaration of `%D' as multidimensional array", dname); cp_error ("must have bounds for all dimensions except the first"); type = error_mark_node; } if (type == error_mark_node) continue; /* VC++ spells a zero-sized array with []. */ if (size == NULL_TREE && decl_context == FIELD && ! staticp && ! RIDBIT_SETP (RID_TYPEDEF, specbits)) size = integer_zero_node; if (size) { /* Must suspend_momentary here because the index type may need to live until the end of the function. For example, it is used in the declaration of a variable which requires destructing at the end of the function; then build_vec_delete will need this value. */ int yes = suspend_momentary (); /* Might be a cast. */ if (TREE_CODE (size) == NOP_EXPR && TREE_TYPE (size) == TREE_TYPE (TREE_OPERAND (size, 0))) size = TREE_OPERAND (size, 0); /* If this involves a template parameter, it will be a constant at instantiation time, but we don't know what the value is yet. Even if no template parameters are involved, we may an expression that is not a constant; we don't even simplify `1 + 2' when processing a template. */ if (processing_template_decl) { /* Resolve a qualified reference to an enumerator or static const data member of ours. */ if (TREE_CODE (size) == SCOPE_REF && TREE_OPERAND (size, 0) == current_class_type) { tree t = lookup_field (current_class_type, TREE_OPERAND (size, 1), 0, 0); if (t) size = t; } itype = build_index_type (build_min (MINUS_EXPR, sizetype, size, integer_one_node)); goto dont_grok_size; } if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE && TREE_CODE (TREE_TYPE (size)) != ENUMERAL_TYPE && TREE_CODE (TREE_TYPE (size)) != BOOLEAN_TYPE) { cp_error ("size of array `%D' has non-integer type", dname); size = integer_one_node; } if (TREE_READONLY_DECL_P (size)) size = decl_constant_value (size); if (pedantic && integer_zerop (size)) cp_pedwarn ("ANSI C++ forbids zero-size array `%D'", dname); if (TREE_CONSTANT (size)) { int old_flag_pedantic_errors = flag_pedantic_errors; int old_pedantic = pedantic; pedantic = flag_pedantic_errors = 1; /* Always give overflow errors on array subscripts. */ constant_expression_warning (size); pedantic = old_pedantic; flag_pedantic_errors = old_flag_pedantic_errors; if (INT_CST_LT (size, integer_zero_node)) { cp_error ("size of array `%D' is negative", dname); size = integer_one_node; } } else { if (pedantic) { if (dname) cp_pedwarn ("ANSI C++ forbids variable-size array `%D'", dname); else cp_pedwarn ("ANSI C++ forbids variable-size array"); } } itype = fold (build_binary_op (MINUS_EXPR, cp_convert (index_type, size), cp_convert (index_type, integer_one_node))); if (! TREE_CONSTANT (itype)) itype = variable_size (itype); else if (TREE_OVERFLOW (itype)) { error ("overflow in array dimension"); TREE_OVERFLOW (itype) = 0; } /* If we're a parm, we need to have a permanent type so mangling checks for re-use will work right. If both the element and index types are permanent, the array type will be, too. */ if (decl_context == PARM && allocation_temporary_p () && TREE_PERMANENT (type)) { push_obstacks (&permanent_obstack, &permanent_obstack); itype = build_index_type (itype); pop_obstacks (); } else itype = build_index_type (itype); dont_grok_size: resume_momentary (yes); } type = build_cplus_array_type (type, itype); ctype = NULL_TREE; } break; case CALL_EXPR: { tree arg_types; int funcdecl_p; tree inner_parms = TREE_OPERAND (declarator, 1); tree inner_decl = TREE_OPERAND (declarator, 0); /* Declaring a function type. Make sure we have a valid type for the function to return. */ /* We now know that the TYPE_QUALS don't apply to the decl, but to its return type. */ type_quals = TYPE_UNQUALIFIED; /* Warn about some types functions can't return. */ if (TREE_CODE (type) == FUNCTION_TYPE) { error ("`%s' declared as function returning a function", name); type = integer_type_node; } if (TREE_CODE (type) == ARRAY_TYPE) { error ("`%s' declared as function returning an array", name); type = integer_type_node; } if (inner_decl && TREE_CODE (inner_decl) == SCOPE_REF) inner_decl = TREE_OPERAND (inner_decl, 1); if (inner_decl && TREE_CODE (inner_decl) == TEMPLATE_ID_EXPR) inner_decl = dname; /* Pick up type qualifiers which should be applied to `this'. */ quals = TREE_OPERAND (declarator, 2); /* Pick up the exception specifications. */ raises = TREE_TYPE (declarator); /* Say it's a definition only for the CALL_EXPR closest to the identifier. */ funcdecl_p = inner_decl && (TREE_CODE (inner_decl) == IDENTIFIER_NODE || TREE_CODE (inner_decl) == TEMPLATE_ID_EXPR || TREE_CODE (inner_decl) == BIT_NOT_EXPR); if (ctype == NULL_TREE && decl_context == FIELD && funcdecl_p && (friendp == 0 || dname == current_class_name)) ctype = current_class_type; if (ctype && return_type == return_conversion) TYPE_HAS_CONVERSION (ctype) = 1; if (ctype && constructor_name (ctype) == dname) { /* We are within a class's scope. If our declarator name is the same as the class name, and we are defining a function, then it is a constructor/destructor, and therefore returns a void type. */ if (flags == DTOR_FLAG) { /* ANSI C++ June 5 1992 WP 12.4.1. A destructor may not be declared const or volatile. A destructor may not be static. */ if (staticp == 2) error ("destructor cannot be static member function"); if (quals) { cp_error ("destructors may not be `%s'", IDENTIFIER_POINTER (TREE_VALUE (quals))); quals = NULL_TREE; } if (decl_context == FIELD) { if (! member_function_or_else (ctype, current_class_type, "destructor for alien class `%s' cannot be a member")) return void_type_node; } } else /* It's a constructor. */ { if (explicitp == 1) explicitp = 2; /* ANSI C++ June 5 1992 WP 12.1.2. A constructor may not be declared const or volatile. A constructor may not be virtual. A constructor may not be static. */ if (staticp == 2) error ("constructor cannot be static member function"); if (virtualp) { pedwarn ("constructors cannot be declared virtual"); virtualp = 0; } if (quals) { cp_error ("constructors may not be `%s'", IDENTIFIER_POINTER (TREE_VALUE (quals))); quals = NULL_TREE; } { RID_BIT_TYPE tmp_bits; bcopy ((void*)&specbits, (void*)&tmp_bits, sizeof (RID_BIT_TYPE)); RIDBIT_RESET (RID_INLINE, tmp_bits); RIDBIT_RESET (RID_STATIC, tmp_bits); if (RIDBIT_ANY_SET (tmp_bits)) error ("return value type specifier for constructor ignored"); } type = build_pointer_type (ctype); if (decl_context == FIELD && IS_SIGNATURE (current_class_type)) { error ("constructor not allowed in signature"); return void_type_node; } else if (decl_context == FIELD) { if (! member_function_or_else (ctype, current_class_type, "constructor for alien class `%s' cannot be member")) return void_type_node; TYPE_HAS_CONSTRUCTOR (ctype) = 1; if (return_type != return_ctor) return NULL_TREE; } } if (decl_context == FIELD) staticp = 0; } else if (friendp) { if (initialized) error ("can't initialize friend function `%s'", name); if (virtualp) { /* Cannot be both friend and virtual. */ error ("virtual functions cannot be friends"); RIDBIT_RESET (RID_FRIEND, specbits); friendp = 0; } if (decl_context == NORMAL) error ("friend declaration not in class definition"); if (current_function_decl && funcdef_flag) cp_error ("can't define friend function `%s' in a local class definition", name); } /* Construct the function type and go to the next inner layer of declarator. */ declarator = TREE_OPERAND (declarator, 0); /* FIXME: This is where default args should be fully processed. */ arg_types = grokparms (inner_parms, funcdecl_p ? funcdef_flag : 0); if (declarator && flags == DTOR_FLAG) { /* A destructor declared in the body of a class will be represented as a BIT_NOT_EXPR. But, we just want the underlying IDENTIFIER. */ if (TREE_CODE (declarator) == BIT_NOT_EXPR) declarator = TREE_OPERAND (declarator, 0); if (strict_prototype == 0 && arg_types == NULL_TREE) arg_types = void_list_node; else if (arg_types == NULL_TREE || arg_types != void_list_node) { cp_error ("destructors may not have parameters"); arg_types = void_list_node; last_function_parms = NULL_TREE; } } /* ANSI says that `const int foo ();' does not make the function foo const. */ type = build_function_type (type, arg_types); { tree t; for (t = arg_types; t; t = TREE_CHAIN (t)) if (TREE_PURPOSE (t) && TREE_CODE (TREE_PURPOSE (t)) == DEFAULT_ARG) { add_defarg_fn (type); break; } } } break; case ADDR_EXPR: case INDIRECT_REF: /* Filter out pointers-to-references and references-to-references. We can get these if a TYPE_DECL is used. */ if (TREE_CODE (type) == REFERENCE_TYPE) { error ("cannot declare %s to references", TREE_CODE (declarator) == ADDR_EXPR ? "references" : "pointers"); declarator = TREE_OPERAND (declarator, 0); continue; } if (TREE_CODE (type) == OFFSET_TYPE && (TREE_CODE (TREE_TYPE (type)) == VOID_TYPE || TREE_CODE (TREE_TYPE (type)) == REFERENCE_TYPE)) { cp_error ("cannot declare pointer to `%#T' member", TREE_TYPE (type)); type = TREE_TYPE (type); } /* Merge any constancy or volatility into the target type for the pointer. */ /* We now know that the TYPE_QUALS don't apply to the decl, but to the target of the pointer. */ type_quals = TYPE_UNQUALIFIED; if (IS_SIGNATURE (type)) { if (TREE_CODE (declarator) == ADDR_EXPR) { if (CLASSTYPE_METHOD_VEC (type) == NULL_TREE && TYPE_SIZE (type)) cp_warning ("empty signature `%T' used in signature reference declaration", type); #if 0 type = build_signature_reference_type (type); #else sorry ("signature reference"); return NULL_TREE; #endif } else { if (CLASSTYPE_METHOD_VEC (type) == NULL_TREE && TYPE_SIZE (type)) cp_warning ("empty signature `%T' used in signature pointer declaration", type); type = build_signature_pointer_type (type); } } else if (TREE_CODE (declarator) == ADDR_EXPR) { if (TREE_CODE (type) == VOID_TYPE) error ("invalid type: `void &'"); else type = build_reference_type (type); } else if (TREE_CODE (type) == METHOD_TYPE) type = build_ptrmemfunc_type (build_pointer_type (type)); else type = build_pointer_type (type); /* Process a list of type modifier keywords (such as const or volatile) that were given inside the `*' or `&'. */ if (TREE_TYPE (declarator)) { register tree typemodlist; int erred = 0; constp = 0; volatilep = 0; restrictp = 0; for (typemodlist = TREE_TYPE (declarator); typemodlist; typemodlist = TREE_CHAIN (typemodlist)) { tree qualifier = TREE_VALUE (typemodlist); if (qualifier == ridpointers[(int) RID_CONST]) constp++; else if (qualifier == ridpointers[(int) RID_VOLATILE]) volatilep++; else if (qualifier == ridpointers[(int) RID_RESTRICT]) restrictp++; else if (!erred) { erred = 1; error ("invalid type modifier within pointer declarator"); } } if (constp > 1) pedwarn ("duplicate `const'"); if (volatilep > 1) pedwarn ("duplicate `volatile'"); if (restrictp > 1) pedwarn ("duplicate `restrict'"); type_quals = ((constp ? TYPE_QUAL_CONST : 0) | (restrictp ? TYPE_QUAL_RESTRICT : 0) | (volatilep ? TYPE_QUAL_VOLATILE : 0)); if (TREE_CODE (declarator) == ADDR_EXPR && (constp || volatilep)) { if (constp) pedwarn ("discarding `const' applied to a reference"); if (volatilep) pedwarn ("discarding `volatile' applied to a reference"); type_quals &= ~(TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE); } type = cp_build_qualified_type (type, type_quals); } declarator = TREE_OPERAND (declarator, 0); ctype = NULL_TREE; break; case SCOPE_REF: { /* We have converted type names to NULL_TREE if the name was bogus, or to a _TYPE node, if not. The variable CTYPE holds the type we will ultimately resolve to. The code here just needs to build up appropriate member types. */ tree sname = TREE_OPERAND (declarator, 1); tree t; /* Destructors can have their visibilities changed as well. */ if (TREE_CODE (sname) == BIT_NOT_EXPR) sname = TREE_OPERAND (sname, 0); if (TREE_COMPLEXITY (declarator) == 0) /* This needs to be here, in case we are called multiple times. */ ; else if (TREE_COMPLEXITY (declarator) == -1) /* Namespace member. */ pop_decl_namespace (); else if (friendp && (TREE_COMPLEXITY (declarator) < 2)) /* Don't fall out into global scope. Hides real bug? --eichin */ ; else if (! IS_AGGR_TYPE_CODE (TREE_CODE (TREE_OPERAND (declarator, 0)))) ; else if (TREE_COMPLEXITY (declarator) == current_class_depth) { /* Resolve any TYPENAME_TYPEs from the decl-specifier-seq that refer to ctype. They couldn't be resolved earlier because we hadn't pushed into the class yet. Example: resolve 'B::type' in 'B::type> B::f () { }'. */ if (current_template_parms && uses_template_parms (type) && uses_template_parms (current_class_type)) { tree args = current_template_args (); type = tsubst (type, args, /*complain=*/1, NULL_TREE); } /* This pop_nested_class corresponds to the push_nested_class used to push into class scope for parsing the argument list of a function decl, in qualified_id. */ pop_nested_class (); TREE_COMPLEXITY (declarator) = current_class_depth; } else my_friendly_abort (16); if (TREE_OPERAND (declarator, 0) == NULL_TREE) { /* We had a reference to a global decl, or perhaps we were given a non-aggregate typedef, in which case we cleared this out, and should just keep going as though it wasn't there. */ declarator = sname; continue; } ctype = TREE_OPERAND (declarator, 0); t = ctype; while (t != NULL_TREE && CLASS_TYPE_P (t)) { if (CLASSTYPE_TEMPLATE_INFO (t) && !CLASSTYPE_TEMPLATE_SPECIALIZATION (t)) template_count += 1; t = TYPE_MAIN_DECL (t); if (DECL_LANG_SPECIFIC (t)) t = DECL_CLASS_CONTEXT (t); else t = NULL_TREE; } if (sname == NULL_TREE) goto done_scoping; if (TREE_CODE (sname) == IDENTIFIER_NODE) { /* This is the `standard' use of the scoping operator: basetype :: member . */ if (ctype == current_class_type) { /* class A { void A::f (); }; Is this ill-formed? */ if (pedantic) cp_pedwarn ("extra qualification `%T::' on member `%s' ignored", ctype, name); } else if (TREE_CODE (type) == FUNCTION_TYPE) { if (current_class_type == NULL_TREE || friendp) type = build_cplus_method_type (ctype, TREE_TYPE (type), TYPE_ARG_TYPES (type)); else { cp_error ("cannot declare member function `%T::%s' within `%T'", ctype, name, current_class_type); return void_type_node; } } else if (RIDBIT_SETP (RID_TYPEDEF, specbits) || TYPE_SIZE (complete_type (ctype)) != NULL_TREE) { /* Have to move this code elsewhere in this function. this code is used for i.e., typedef int A::M; M *pm; It is? How? jason 10/2/94 */ if (current_class_type) { cp_error ("cannot declare member `%T::%s' within `%T'", ctype, name, current_class_type); return void_type_node; } type = build_offset_type (ctype, type); } else if (uses_template_parms (ctype)) { if (TREE_CODE (type) == FUNCTION_TYPE) type = build_cplus_method_type (ctype, TREE_TYPE (type), TYPE_ARG_TYPES (type)); } else { cp_error ("structure `%T' not yet defined", ctype); return error_mark_node; } declarator = sname; } else if (TREE_CODE (sname) == SCOPE_REF) my_friendly_abort (17); else { done_scoping: declarator = TREE_OPERAND (declarator, 1); if (declarator && TREE_CODE (declarator) == CALL_EXPR) /* In this case, we will deal with it later. */ ; else { if (TREE_CODE (type) == FUNCTION_TYPE) type = build_cplus_method_type (ctype, TREE_TYPE (type), TYPE_ARG_TYPES (type)); else type = build_offset_type (ctype, type); } } } break; case BIT_NOT_EXPR: declarator = TREE_OPERAND (declarator, 0); break; case RECORD_TYPE: case UNION_TYPE: case ENUMERAL_TYPE: declarator = NULL_TREE; break; case ERROR_MARK: declarator = NULL_TREE; break; default: my_friendly_abort (158); } } /* See the comment for the TREE_LIST case, above. */ if (inner_attrs) { if (! ignore_attrs) decl_attributes (type, inner_attrs, NULL_TREE); else if (attrlist) TREE_VALUE (attrlist) = chainon (inner_attrs, TREE_VALUE (attrlist)); else attrlist = build_decl_list (NULL_TREE, inner_attrs); } /* Now TYPE has the actual type. */ if (explicitp == 1) { error ("only constructors can be declared `explicit'"); explicitp = 0; } if (RIDBIT_SETP (RID_MUTABLE, specbits)) { if (type_quals & TYPE_QUAL_CONST) { error ("const `%s' cannot be declared `mutable'", name); RIDBIT_RESET (RID_MUTABLE, specbits); } else if (staticp) { error ("static `%s' cannot be declared `mutable'", name); RIDBIT_RESET (RID_MUTABLE, specbits); } } if (declarator == NULL_TREE || TREE_CODE (declarator) == IDENTIFIER_NODE || (TREE_CODE (declarator) == TEMPLATE_ID_EXPR && (TREE_CODE (type) == FUNCTION_TYPE || TREE_CODE (type) == METHOD_TYPE))) /* OK */; else if (TREE_CODE (declarator) == TEMPLATE_ID_EXPR) { cp_error ("template-id `%D' used as a declarator", declarator); declarator = dname; } else /* Unexpected declarator format. */ my_friendly_abort (990210); /* If this is declaring a typedef name, return a TYPE_DECL. */ if (RIDBIT_SETP (RID_TYPEDEF, specbits) && decl_context != TYPENAME) { tree decl; /* Note that the grammar rejects storage classes in typenames, fields or parameters. */ if (current_lang_name == lang_name_java) TYPE_FOR_JAVA (type) = 1; if (decl_context == FIELD) { if (declarator == constructor_name (current_class_type)) cp_pedwarn ("ANSI C++ forbids nested type `%D' with same name as enclosing class", declarator); decl = build_lang_decl (TYPE_DECL, declarator, type); if (IS_SIGNATURE (current_class_type) && opaque_typedef) SIGNATURE_HAS_OPAQUE_TYPEDECLS (current_class_type) = 1; } else { /* Make sure this typedef lives as long as its type, since it might be used as a template parameter. */ if (type != error_mark_node) push_obstacks (TYPE_OBSTACK (type), TYPE_OBSTACK (type)); decl = build_decl (TYPE_DECL, declarator, type); if (type != error_mark_node) pop_obstacks (); } /* If the user declares "struct {...} foo" then `foo' will have an anonymous name. Fill that name in now. Nothing can refer to it, so nothing needs know about the name change. The TYPE_NAME field was filled in by build_struct_xref. */ if (type != error_mark_node && TYPE_NAME (type) && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL && ANON_AGGRNAME_P (TYPE_IDENTIFIER (type))) { tree oldname = TYPE_NAME (type); tree t; /* FIXME: This is bogus; we should not be doing this for cv-qualified types. */ /* Replace the anonymous name with the real name everywhere. */ lookup_tag_reverse (type, declarator); for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t)) if (TYPE_NAME (t) == oldname) TYPE_NAME (t) = decl; if (TYPE_LANG_SPECIFIC (type)) TYPE_WAS_ANONYMOUS (type) = 1; /* If this is a typedef within a template class, the nested type is a (non-primary) template. The name for the template needs updating as well. */ if (TYPE_LANG_SPECIFIC (type) && CLASSTYPE_TEMPLATE_INFO (type)) DECL_NAME (CLASSTYPE_TI_TEMPLATE (type)) = TYPE_IDENTIFIER (type); /* XXX Temporarily set the scope. When returning, start_decl expects it as NULL_TREE, and will then then set it using pushdecl. */ my_friendly_assert (DECL_CONTEXT (decl) == NULL_TREE, 980404); if (current_class_type) DECL_CONTEXT (decl) = current_class_type; else DECL_CONTEXT (decl) = FROB_CONTEXT (current_namespace); DECL_ASSEMBLER_NAME (decl) = DECL_NAME (decl); DECL_ASSEMBLER_NAME (decl) = get_identifier (build_overload_name (type, 1, 1)); DECL_CONTEXT (decl) = NULL_TREE; /* FIXME remangle member functions; member functions of a type with external linkage have external linkage. */ } if (TREE_CODE (type) == OFFSET_TYPE || TREE_CODE (type) == METHOD_TYPE) { cp_error_at ("typedef name may not be class-qualified", decl); return NULL_TREE; } else if (quals) { if (ctype == NULL_TREE) { if (TREE_CODE (type) != METHOD_TYPE) cp_error_at ("invalid type qualifier for non-method type", decl); else ctype = TYPE_METHOD_BASETYPE (type); } if (ctype != NULL_TREE) grok_method_quals (ctype, decl, quals); } if (RIDBIT_SETP (RID_SIGNED, specbits) || (typedef_decl && C_TYPEDEF_EXPLICITLY_SIGNED (typedef_decl))) C_TYPEDEF_EXPLICITLY_SIGNED (decl) = 1; if (RIDBIT_SETP (RID_MUTABLE, specbits)) error ("non-object member `%s' cannot be declared mutable", name); bad_specifiers (decl, "type", virtualp, quals != NULL_TREE, inlinep, friendp, raises != NULL_TREE); if (initialized) error ("typedef declaration includes an initializer"); return decl; } /* Detect the case of an array type of unspecified size which came, as such, direct from a typedef name. We must copy the type, so that each identifier gets a distinct type, so that each identifier's size can be controlled separately by its own initializer. */ if (type == typedef_type && TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type) == NULL_TREE) { type = build_cplus_array_type (TREE_TYPE (type), TYPE_DOMAIN (type)); } /* If this is a type name (such as, in a cast or sizeof), compute the type and return it now. */ if (decl_context == TYPENAME) { /* Note that the grammar rejects storage classes in typenames, fields or parameters. */ if (type_quals != TYPE_UNQUALIFIED) { if (IS_SIGNATURE (type)) error ("type qualifiers specified for signature type"); type_quals = TYPE_UNQUALIFIED; } /* Special case: "friend class foo" looks like a TYPENAME context. */ if (friendp) { if (type_quals != TYPE_UNQUALIFIED) { cp_error ("type qualifiers specified for friend class declaration"); type_quals = TYPE_UNQUALIFIED; } if (inlinep) { cp_error ("`inline' specified for friend class declaration"); inlinep = 0; } /* Only try to do this stuff if we didn't already give up. */ if (type != integer_type_node) { /* A friendly class? */ if (current_class_type) make_friend_class (current_class_type, TYPE_MAIN_VARIANT (type)); else error ("trying to make class `%s' a friend of global scope", TYPE_NAME_STRING (type)); type = void_type_node; } } else if (quals) { tree dummy = build_decl (TYPE_DECL, declarator, type); if (ctype == NULL_TREE) { my_friendly_assert (TREE_CODE (type) == METHOD_TYPE, 159); ctype = TYPE_METHOD_BASETYPE (type); } grok_method_quals (ctype, dummy, quals); type = TREE_TYPE (dummy); } return type; } else if (declarator == NULL_TREE && decl_context != PARM && decl_context != CATCHPARM && TREE_CODE (type) != UNION_TYPE && ! bitfield) { cp_error ("abstract declarator `%T' used as declaration", type); declarator = make_anon_name (); } /* `void' at top level (not within pointer) is allowed only in typedefs or type names. We don't complain about parms either, but that is because a better error message can be made later. */ if (TREE_CODE (type) == VOID_TYPE && decl_context != PARM) { if (! declarator) error ("unnamed variable or field declared void"); else if (TREE_CODE (declarator) == IDENTIFIER_NODE) { if (IDENTIFIER_OPNAME_P (declarator)) my_friendly_abort (356); else error ("variable or field `%s' declared void", name); } else error ("variable or field declared void"); type = integer_type_node; } /* Now create the decl, which may be a VAR_DECL, a PARM_DECL or a FUNCTION_DECL, depending on DECL_CONTEXT and TYPE. */ if (decl_context == PARM || decl_context == CATCHPARM) { if (ctype || in_namespace) error ("cannot use `::' in parameter declaration"); /* A parameter declared as an array of T is really a pointer to T. One declared as a function is really a pointer to a function. One declared as a member is really a pointer to member. */ if (TREE_CODE (type) == ARRAY_TYPE) { /* Transfer const-ness of array into that of type pointed to. */ type = build_pointer_type (TREE_TYPE (type)); type_quals = TYPE_UNQUALIFIED; } else if (TREE_CODE (type) == FUNCTION_TYPE) type = build_pointer_type (type); else if (TREE_CODE (type) == OFFSET_TYPE) type = build_pointer_type (type); else if (TREE_CODE (type) == VOID_TYPE && declarator) { error ("declaration of `%s' as void", name); return NULL_TREE; } } { register tree decl; if (decl_context == PARM) { decl = build_decl (PARM_DECL, declarator, type); bad_specifiers (decl, "parameter", virtualp, quals != NULL_TREE, inlinep, friendp, raises != NULL_TREE); if (current_class_type && IS_SIGNATURE (current_class_type)) { if (inlinep) error ("parameter of signature member function declared `inline'"); if (RIDBIT_SETP (RID_AUTO, specbits)) error ("parameter of signature member function declared `auto'"); if (RIDBIT_SETP (RID_REGISTER, specbits)) error ("parameter of signature member function declared `register'"); } /* Compute the type actually passed in the parmlist, for the case where there is no prototype. (For example, shorts and chars are passed as ints.) When there is a prototype, this is overridden later. */ DECL_ARG_TYPE (decl) = type_promotes_to (type); } else if (decl_context == FIELD) { if (type == error_mark_node) { /* Happens when declaring arrays of sizes which are error_mark_node, for example. */ decl = NULL_TREE; } else if (in_namespace && !friendp) { /* Something like struct S { int N::j; }; */ cp_error ("invalid use of `::'"); decl = NULL_TREE; } else if (TREE_CODE (type) == FUNCTION_TYPE) { int publicp = 0; tree function_context; /* We catch the others as conflicts with the builtin typedefs. */ if (friendp && declarator == ridpointers[(int) RID_SIGNED]) { cp_error ("function `%D' cannot be declared friend", declarator); friendp = 0; } if (friendp == 0) { if (ctype == NULL_TREE) ctype = current_class_type; if (ctype == NULL_TREE) { cp_error ("can't make `%D' into a method -- not in a class", declarator); return void_type_node; } /* ``A union may [ ... ] not [ have ] virtual functions.'' ARM 9.5 */ if (virtualp && TREE_CODE (ctype) == UNION_TYPE) { cp_error ("function `%D' declared virtual inside a union", declarator); return void_type_node; } if (declarator == ansi_opname[(int) NEW_EXPR] || declarator == ansi_opname[(int) VEC_NEW_EXPR] || declarator == ansi_opname[(int) DELETE_EXPR] || declarator == ansi_opname[(int) VEC_DELETE_EXPR]) { if (virtualp) { cp_error ("`%D' cannot be declared virtual, since it is always static", declarator); virtualp = 0; } } else if (staticp < 2) type = build_cplus_method_type (ctype, TREE_TYPE (type), TYPE_ARG_TYPES (type)); } /* Tell grokfndecl if it needs to set TREE_PUBLIC on the node. */ function_context = (ctype != NULL_TREE) ? hack_decl_function_context (TYPE_MAIN_DECL (ctype)) : NULL_TREE; publicp = (! friendp || ! staticp) && function_context == NULL_TREE; decl = grokfndecl (ctype, type, TREE_CODE (declarator) != TEMPLATE_ID_EXPR ? declarator : dname, declarator, virtualp, flags, quals, raises, friendp ? -1 : 0, friendp, publicp, inlinep, funcdef_flag, template_count, in_namespace); if (decl == NULL_TREE) return decl; #if 0 /* This clobbers the attrs stored in `decl' from `attrlist'. */ /* The decl and setting of decl_machine_attr is also turned off. */ decl = build_decl_attribute_variant (decl, decl_machine_attr); #endif /* [class.conv.ctor] A constructor declared without the function-specifier explicit that can be called with a single parameter specifies a conversion from the type of its first parameter to the type of its class. Such a constructor is called a converting constructor. */ if (explicitp == 2) DECL_NONCONVERTING_P (decl) = 1; else if (DECL_CONSTRUCTOR_P (decl)) { /* The constructor can be called with exactly one parameter if there is at least one parameter, and any subsequent parameters have default arguments. We don't look at the first parameter, which is really just the `this' parameter for the new object. */ tree arg_types = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (decl))); /* Skip the `in_chrg' argument too, if present. */ if (TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (decl))) arg_types = TREE_CHAIN (arg_types); + /* And the `vlist' argument. */ + if (TYPE_USES_PVBASES (DECL_CONTEXT (decl))) + arg_types = TREE_CHAIN (arg_types); + if (arg_types == void_list_node || (arg_types && TREE_CHAIN (arg_types) && TREE_CHAIN (arg_types) != void_list_node && !TREE_PURPOSE (TREE_CHAIN (arg_types)))) DECL_NONCONVERTING_P (decl) = 1; } } else if (TREE_CODE (type) == METHOD_TYPE) { /* We only get here for friend declarations of members of other classes. */ /* All method decls are public, so tell grokfndecl to set TREE_PUBLIC, also. */ decl = grokfndecl (ctype, type, declarator, declarator, virtualp, flags, quals, raises, friendp ? -1 : 0, friendp, 1, 0, funcdef_flag, template_count, in_namespace); if (decl == NULL_TREE) return NULL_TREE; } else if (!staticp && ! processing_template_decl && TYPE_SIZE (complete_type (type)) == NULL_TREE && (TREE_CODE (type) != ARRAY_TYPE || initialized == 0)) { if (declarator) cp_error ("field `%D' has incomplete type", declarator); else cp_error ("name `%T' has incomplete type", type); /* If we're instantiating a template, tell them which instantiation made the field's type be incomplete. */ if (current_class_type && TYPE_NAME (current_class_type) && IDENTIFIER_TEMPLATE (TYPE_IDENTIFIER (current_class_type)) && declspecs && TREE_VALUE (declspecs) && TREE_TYPE (TREE_VALUE (declspecs)) == type) cp_error (" in instantiation of template `%T'", current_class_type); type = error_mark_node; decl = NULL_TREE; } else { if (friendp) { error ("`%s' is neither function nor method; cannot be declared friend", IDENTIFIER_POINTER (declarator)); friendp = 0; } decl = NULL_TREE; } if (friendp) { /* Friends are treated specially. */ if (ctype == current_class_type) warning ("member functions are implicitly friends of their class"); else { tree t = NULL_TREE; if (decl && DECL_NAME (decl)) { if (template_class_depth (current_class_type) == 0) { decl = check_explicit_specialization (declarator, decl, template_count, 2 * (funcdef_flag != 0) + 4); if (decl == error_mark_node) return error_mark_node; } t = do_friend (ctype, declarator, decl, last_function_parms, attrlist, flags, quals, funcdef_flag); } if (t && funcdef_flag) return t; return void_type_node; } } /* Structure field. It may not be a function, except for C++ */ if (decl == NULL_TREE) { if (initialized) { if (!staticp) { /* An attempt is being made to initialize a non-static member. But, from [class.mem]: 4 A member-declarator can contain a constant-initializer only if it declares a static member (_class.static_) of integral or enumeration type, see _class.static.data_. This used to be relatively common practice, but the rest of the compiler does not correctly handle the initialization unless the member is static so we make it static below. */ cp_pedwarn ("ANSI C++ forbids initialization of member `%D'", declarator); cp_pedwarn ("making `%D' static", declarator); staticp = 1; } if (uses_template_parms (type)) /* We'll check at instantiation time. */ ; else if (check_static_variable_definition (declarator, type)) /* If we just return the declaration, crashes will sometimes occur. We therefore return void_type_node, as if this was a friend declaration, to cause callers to completely ignore this declaration. */ return void_type_node; } /* 9.2p13 [class.mem] */ if (declarator == constructor_name (current_class_type) /* Divergence from the standard: In extern "C", we allow non-static data members here, because C does and /usr/include/netinet/in.h uses that. */ && (staticp || ! in_system_header)) cp_pedwarn ("ANSI C++ forbids data member `%D' with same name as enclosing class", declarator); if (staticp) { /* C++ allows static class members. All other work for this is done by grokfield. This VAR_DCL is built by build_lang_field_decl. All other VAR_DECLs are built by build_decl. */ decl = build_lang_field_decl (VAR_DECL, declarator, type); TREE_STATIC (decl) = 1; /* In class context, 'static' means public access. */ TREE_PUBLIC (decl) = DECL_EXTERNAL (decl) = 1; } else { decl = build_lang_field_decl (FIELD_DECL, declarator, type); if (RIDBIT_SETP (RID_MUTABLE, specbits)) { DECL_MUTABLE_P (decl) = 1; RIDBIT_RESET (RID_MUTABLE, specbits); } } bad_specifiers (decl, "field", virtualp, quals != NULL_TREE, inlinep, friendp, raises != NULL_TREE); } } else if (TREE_CODE (type) == FUNCTION_TYPE || TREE_CODE (type) == METHOD_TYPE) { tree original_name; int publicp = 0; if (! declarator) return NULL_TREE; if (TREE_CODE (declarator) == TEMPLATE_ID_EXPR) original_name = dname; else original_name = declarator; if (RIDBIT_SETP (RID_AUTO, specbits)) error ("storage class `auto' invalid for function `%s'", name); else if (RIDBIT_SETP (RID_REGISTER, specbits)) error ("storage class `register' invalid for function `%s'", name); /* Function declaration not at top level. Storage classes other than `extern' are not allowed and `extern' makes no difference. */ if (! toplevel_bindings_p () && (RIDBIT_SETP (RID_STATIC, specbits) || RIDBIT_SETP (RID_INLINE, specbits)) && pedantic) { if (RIDBIT_SETP (RID_STATIC, specbits)) pedwarn ("storage class `static' invalid for function `%s' declared out of global scope", name); else pedwarn ("storage class `inline' invalid for function `%s' declared out of global scope", name); } if (ctype == NULL_TREE) { if (virtualp) { error ("virtual non-class function `%s'", name); virtualp = 0; } } else if (TREE_CODE (type) == FUNCTION_TYPE && staticp < 2) type = build_cplus_method_type (ctype, TREE_TYPE (type), TYPE_ARG_TYPES (type)); /* Record presence of `static'. */ publicp = (ctype != NULL_TREE || RIDBIT_SETP (RID_EXTERN, specbits) || !RIDBIT_SETP (RID_STATIC, specbits)); decl = grokfndecl (ctype, type, original_name, declarator, virtualp, flags, quals, raises, 1, friendp, publicp, inlinep, funcdef_flag, template_count, in_namespace); if (decl == NULL_TREE) return NULL_TREE; if (staticp == 1) { int illegal_static = 0; /* Don't allow a static member function in a class, and forbid declaring main to be static. */ if (TREE_CODE (type) == METHOD_TYPE) { cp_pedwarn ("cannot declare member function `%D' to have static linkage", decl); illegal_static = 1; } else if (current_function_decl) { /* FIXME need arm citation */ error ("cannot declare static function inside another function"); illegal_static = 1; } if (illegal_static) { staticp = 0; RIDBIT_RESET (RID_STATIC, specbits); } } } else { /* It's a variable. */ /* An uninitialized decl with `extern' is a reference. */ decl = grokvardecl (type, declarator, &specbits, initialized, (type_quals & TYPE_QUAL_CONST) != 0, in_namespace); bad_specifiers (decl, "variable", virtualp, quals != NULL_TREE, inlinep, friendp, raises != NULL_TREE); if (ctype) { DECL_CONTEXT (decl) = ctype; if (staticp == 1) { cp_pedwarn ("static member `%D' re-declared as static", decl); staticp = 0; RIDBIT_RESET (RID_STATIC, specbits); } if (RIDBIT_SETP (RID_REGISTER, specbits) && TREE_STATIC (decl)) { cp_error ("static member `%D' declared `register'", decl); RIDBIT_RESET (RID_REGISTER, specbits); } if (RIDBIT_SETP (RID_EXTERN, specbits) && pedantic) { cp_pedwarn ("cannot explicitly declare member `%#D' to have extern linkage", decl); RIDBIT_RESET (RID_EXTERN, specbits); } } } if (RIDBIT_SETP (RID_MUTABLE, specbits)) { error ("`%s' cannot be declared mutable", name); } /* Record `register' declaration for warnings on & and in case doing stupid register allocation. */ if (RIDBIT_SETP (RID_REGISTER, specbits)) DECL_REGISTER (decl) = 1; if (RIDBIT_SETP (RID_EXTERN, specbits)) DECL_THIS_EXTERN (decl) = 1; if (RIDBIT_SETP (RID_STATIC, specbits)) DECL_THIS_STATIC (decl) = 1; /* Record constancy and volatility. */ /* FIXME: Disallow `restrict' pointer-to-member declarations. */ c_apply_type_quals_to_decl (type_quals, decl); return decl; } } /* Tell if a parmlist/exprlist looks like an exprlist or a parmlist. An empty exprlist is a parmlist. An exprlist which contains only identifiers at the global level is a parmlist. Otherwise, it is an exprlist. */ int parmlist_is_exprlist (exprs) tree exprs; { if (exprs == NULL_TREE || TREE_PARMLIST (exprs)) return 0; if (toplevel_bindings_p ()) { /* At the global level, if these are all identifiers, then it is a parmlist. */ while (exprs) { if (TREE_CODE (TREE_VALUE (exprs)) != IDENTIFIER_NODE) return 1; exprs = TREE_CHAIN (exprs); } return 0; } return 1; } /* Subroutine of start_function. Ensure that each of the parameter types (as listed in PARMS) is complete, as is required for a function definition. */ static void require_complete_types_for_parms (parms) tree parms; { while (parms) { tree type = TREE_TYPE (parms); if (TYPE_SIZE (complete_type (type)) == NULL_TREE) { if (DECL_NAME (parms)) error ("parameter `%s' has incomplete type", IDENTIFIER_POINTER (DECL_NAME (parms))); else error ("parameter has incomplete type"); TREE_TYPE (parms) = error_mark_node; } else layout_decl (parms, 0); parms = TREE_CHAIN (parms); } } /* Returns DECL if DECL is a local variable (or parameter). Returns NULL_TREE otherwise. */ static tree local_variable_p (t) tree t; { if ((TREE_CODE (t) == VAR_DECL /* A VAR_DECL with a context that is a _TYPE is a static data member. */ && !TYPE_P (CP_DECL_CONTEXT (t)) /* Any other non-local variable must be at namespace scope. */ && TREE_CODE (CP_DECL_CONTEXT (t)) != NAMESPACE_DECL) || (TREE_CODE (t) == PARM_DECL)) return t; return NULL_TREE; } /* Check that ARG, which is a default-argument expression for a parameter DECL, is legal. Returns ARG, or ERROR_MARK_NODE, if something goes wrong. DECL may also be a _TYPE node, rather than a DECL, if there is no DECL available. */ tree check_default_argument (decl, arg) tree decl; tree arg; { tree var; tree decl_type; if (TREE_CODE (arg) == DEFAULT_ARG) /* We get a DEFAULT_ARG when looking at an in-class declaration with a default argument. Ignore the argument for now; we'll deal with it after the class is complete. */ return arg; if (processing_template_decl || uses_template_parms (arg)) /* We don't do anything checking until instantiation-time. Note that there may be uninstantiated arguments even for an instantiated function, since default arguments are not instantiated until they are needed. */ return arg; if (TYPE_P (decl)) { decl_type = decl; decl = NULL_TREE; } else decl_type = TREE_TYPE (decl); if (arg == error_mark_node || decl == error_mark_node || TREE_TYPE (arg) == error_mark_node || decl_type == error_mark_node) /* Something already went wrong. There's no need to check further. */ return error_mark_node; /* [dcl.fct.default] A default argument expression is implicitly converted to the parameter type. */ if (!TREE_TYPE (arg) || !can_convert_arg (decl_type, TREE_TYPE (arg), arg)) { if (decl) cp_error ("default argument for `%#D' has type `%T'", decl, TREE_TYPE (arg)); else cp_error ("default argument for paramter of type `%T' has type `%T'", decl_type, TREE_TYPE (arg)); return error_mark_node; } /* [dcl.fct.default] Local variables shall not be used in default argument expressions. The keyword `this' shall not be used in a default argument of a member function. */ var = search_tree (arg, local_variable_p); if (var) { cp_error ("default argument `%E' uses local variable `%D'", arg, var); return error_mark_node; } /* All is well. */ return arg; } /* Decode the list of parameter types for a function type. Given the list of things declared inside the parens, return a list of types. The list we receive can have three kinds of elements: an IDENTIFIER_NODE for names given without types, a TREE_LIST node for arguments given as typespecs or names with typespecs, or void_type_node, to mark the end of an argument list when additional arguments are not permitted (... was not used). FUNCDEF_FLAG is nonzero for a function definition, 0 for a mere declaration. A nonempty identifier-list gets an error message when FUNCDEF_FLAG is zero. If FUNCDEF_FLAG is 1, then parameter types must be complete. If FUNCDEF_FLAG is -1, then parameter types may be incomplete. If all elements of the input list contain types, we return a list of the types. If all elements contain no type (except perhaps a void_type_node at the end), we return a null list. If some have types and some do not, it is an error, and we return a null list. Also set last_function_parms to either a list of names (IDENTIFIER_NODEs) or a chain of PARM_DECLs. A list of names is converted to a chain of PARM_DECLs by store_parm_decls so that ultimately it is always a chain of decls. Note that in C++, parameters can take default values. These default values are in the TREE_PURPOSE field of the TREE_LIST. It is an error to specify default values which are followed by parameters that have no default values, or an ELLIPSES. For simplicities sake, only parameters which are specified with their types can take on default values. */ static tree grokparms (first_parm, funcdef_flag) tree first_parm; int funcdef_flag; { tree result = NULL_TREE; tree decls = NULL_TREE; if (first_parm != NULL_TREE && TREE_CODE (TREE_VALUE (first_parm)) == IDENTIFIER_NODE) { if (! funcdef_flag) pedwarn ("parameter names (without types) in function declaration"); last_function_parms = first_parm; return NULL_TREE; } else if (first_parm != NULL_TREE && TREE_CODE (TREE_VALUE (first_parm)) != TREE_LIST && TREE_CODE (TREE_VALUE (first_parm)) != VOID_TYPE) my_friendly_abort (145); else { /* Types were specified. This is a list of declarators each represented as a TREE_LIST node. */ register tree parm, chain; int any_init = 0, any_error = 0; if (first_parm != NULL_TREE) { tree last_result = NULL_TREE; tree last_decl = NULL_TREE; for (parm = first_parm; parm != NULL_TREE; parm = chain) { tree type = NULL_TREE, list_node = parm; register tree decl = TREE_VALUE (parm); tree init = TREE_PURPOSE (parm); chain = TREE_CHAIN (parm); /* @@ weak defense against parse errors. */ if (TREE_CODE (decl) != VOID_TYPE && TREE_CODE (decl) != TREE_LIST) { /* Give various messages as the need arises. */ if (TREE_CODE (decl) == STRING_CST) cp_error ("invalid string constant `%E'", decl); else if (TREE_CODE (decl) == INTEGER_CST) error ("invalid integer constant in parameter list, did you forget to give parameter name?"); continue; } if (TREE_CODE (decl) != VOID_TYPE) { decl = grokdeclarator (TREE_VALUE (decl), TREE_PURPOSE (decl), PARM, init != NULL_TREE, NULL_TREE); if (! decl || TREE_TYPE (decl) == error_mark_node) continue; /* Top-level qualifiers on the parameters are ignored for function types. */ type = TYPE_MAIN_VARIANT (TREE_TYPE (decl)); if (TREE_CODE (type) == VOID_TYPE) decl = void_type_node; else if (TREE_CODE (type) == METHOD_TYPE) { if (DECL_NAME (decl)) /* Cannot use the decl here because we don't have DECL_CONTEXT set up yet. */ cp_error ("parameter `%D' invalidly declared method type", DECL_NAME (decl)); else error ("parameter invalidly declared method type"); type = build_pointer_type (type); TREE_TYPE (decl) = type; } else if (TREE_CODE (type) == OFFSET_TYPE) { if (DECL_NAME (decl)) cp_error ("parameter `%D' invalidly declared offset type", DECL_NAME (decl)); else error ("parameter invalidly declared offset type"); type = build_pointer_type (type); TREE_TYPE (decl) = type; } else if (TREE_CODE (type) == RECORD_TYPE && TYPE_LANG_SPECIFIC (type) && CLASSTYPE_ABSTRACT_VIRTUALS (type)) { abstract_virtuals_error (decl, type); any_error = 1; /* Seems like a good idea. */ } else if (TREE_CODE (type) == RECORD_TYPE && TYPE_LANG_SPECIFIC (type) && IS_SIGNATURE (type)) { signature_error (decl, type); any_error = 1; /* Seems like a good idea. */ } else if (POINTER_TYPE_P (type)) { tree t = type; while (POINTER_TYPE_P (t) || (TREE_CODE (t) == ARRAY_TYPE && TYPE_DOMAIN (t) != NULL_TREE)) t = TREE_TYPE (t); if (TREE_CODE (t) == ARRAY_TYPE) cp_error ("parameter type `%T' includes %s to array of unknown bound", type, TYPE_PTR_P (type) ? "pointer" : "reference"); } } if (TREE_CODE (decl) == VOID_TYPE) { if (result == NULL_TREE) { result = void_list_node; last_result = result; } else { TREE_CHAIN (last_result) = void_list_node; last_result = void_list_node; } if (chain && (chain != void_list_node || TREE_CHAIN (chain))) error ("`void' in parameter list must be entire list"); break; } /* Since there is a prototype, args are passed in their own types. */ DECL_ARG_TYPE (decl) = TREE_TYPE (decl); #ifdef PROMOTE_PROTOTYPES if ((TREE_CODE (type) == INTEGER_TYPE || TREE_CODE (type) == ENUMERAL_TYPE) && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)) DECL_ARG_TYPE (decl) = integer_type_node; #endif if (!any_error && init) { any_init++; init = check_default_argument (decl, init); } else init = NULL_TREE; if (decls == NULL_TREE) { decls = decl; last_decl = decls; } else { TREE_CHAIN (last_decl) = decl; last_decl = decl; } if (! current_function_decl && TREE_PERMANENT (list_node)) { TREE_PURPOSE (list_node) = init; TREE_VALUE (list_node) = type; TREE_CHAIN (list_node) = NULL_TREE; } else list_node = saveable_tree_cons (init, type, NULL_TREE); if (result == NULL_TREE) { result = list_node; last_result = result; } else { TREE_CHAIN (last_result) = list_node; last_result = list_node; } } if (last_result) TREE_CHAIN (last_result) = NULL_TREE; /* If there are no parameters, and the function does not end with `...', then last_decl will be NULL_TREE. */ if (last_decl != NULL_TREE) TREE_CHAIN (last_decl) = NULL_TREE; } } last_function_parms = decls; return result; } /* Called from the parser to update an element of TYPE_ARG_TYPES for some FUNCTION_TYPE with the newly parsed version of its default argument, which was previously digested as text. See snarf_defarg et al in lex.c. */ void replace_defarg (arg, init) tree arg, init; { if (! processing_template_decl && ! can_convert_arg (TREE_VALUE (arg), TREE_TYPE (init), init)) cp_pedwarn ("invalid type `%T' for default argument to `%T'", TREE_TYPE (init), TREE_VALUE (arg)); TREE_PURPOSE (arg) = init; } +/* Return 1 if D copies its arguments. This is used to test for copy + constructors and copy assignment operators. */ + int copy_args_p (d) tree d; { tree t = FUNCTION_ARG_CHAIN (d); if (DECL_CONSTRUCTOR_P (d) && TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (d))) - t = TREE_CHAIN (t); + { + t = TREE_CHAIN (t); + if (TYPE_USES_PVBASES (DECL_CONTEXT (d))) + t = TREE_CHAIN (t); + } + if (t && TREE_CODE (TREE_VALUE (t)) == REFERENCE_TYPE && (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_VALUE (t))) == DECL_CLASS_CONTEXT (d)) && (TREE_CHAIN (t) == NULL_TREE || TREE_CHAIN (t) == void_list_node || TREE_PURPOSE (TREE_CHAIN (t)))) return 1; return 0; } /* These memoizing functions keep track of special properties which a class may have. `grok_ctor_properties' notices whether a class has a constructor of the form X(X&), and also complains if the class has a constructor of the form X(X). `grok_op_properties' takes notice of the various forms of operator= which are defined, as well as what sorts of type conversion may apply. Both functions take a FUNCTION_DECL as an argument. */ int grok_ctor_properties (ctype, decl) tree ctype, decl; { tree parmtypes = FUNCTION_ARG_CHAIN (decl); tree parmtype = parmtypes ? TREE_VALUE (parmtypes) : void_type_node; /* When a type has virtual baseclasses, a magical first int argument is added to any ctor so we can tell if the class has been initialized yet. This could screw things up in this function, so we deliberately ignore the leading int if we're in that situation. */ - if (TYPE_USES_VIRTUAL_BASECLASSES (ctype)) + if (TYPE_USES_VIRTUAL_BASECLASSES (ctype) + && !CLASSTYPE_IS_TEMPLATE (ctype)) { my_friendly_assert (parmtypes && TREE_VALUE (parmtypes) == integer_type_node, 980529); parmtypes = TREE_CHAIN (parmtypes); parmtype = TREE_VALUE (parmtypes); } + if (TYPE_USES_PVBASES (ctype)) + { + my_friendly_assert (parmtypes + && TREE_VALUE (parmtypes) == vlist_type_node, + 980529); + parmtypes = TREE_CHAIN (parmtypes); + parmtype = TREE_VALUE (parmtypes); + } + /* [class.copy] A non-template constructor for class X is a copy constructor if its first parameter is of type X&, const X&, volatile X& or const volatile X&, and either there are no other parameters or else all other parameters have default arguments. */ if (TREE_CODE (parmtype) == REFERENCE_TYPE && TYPE_MAIN_VARIANT (TREE_TYPE (parmtype)) == ctype && (TREE_CHAIN (parmtypes) == NULL_TREE || TREE_CHAIN (parmtypes) == void_list_node || TREE_PURPOSE (TREE_CHAIN (parmtypes))) && !(DECL_TEMPLATE_INSTANTIATION (decl) && is_member_template (DECL_TI_TEMPLATE (decl)))) { TYPE_HAS_INIT_REF (ctype) = 1; if (CP_TYPE_CONST_P (TREE_TYPE (parmtype))) TYPE_HAS_CONST_INIT_REF (ctype) = 1; } /* [class.copy] A declaration of a constructor for a class X is ill-formed if its first parameter is of type (optionally cv-qualified) X and either there are no other parameters or else all other parameters have default arguments. We *don't* complain about member template instantiations that have this form, though; they can occur as we try to decide what constructor to use during overload resolution. Since overload resolution will never prefer such a constructor to the non-template copy constructor (which is either explicitly or implicitly defined), there's no need to worry about their existence. Theoretically, they should never even be instantiated, but that's hard to forestall. */ else if (TYPE_MAIN_VARIANT (parmtype) == ctype && (TREE_CHAIN (parmtypes) == NULL_TREE || TREE_CHAIN (parmtypes) == void_list_node || TREE_PURPOSE (TREE_CHAIN (parmtypes))) && !(DECL_TEMPLATE_INSTANTIATION (decl) && is_member_template (DECL_TI_TEMPLATE (decl)))) { cp_error ("invalid constructor; you probably meant `%T (const %T&)'", ctype, ctype); SET_IDENTIFIER_ERROR_LOCUS (DECL_NAME (decl), ctype); return 0; } else if (TREE_CODE (parmtype) == VOID_TYPE || TREE_PURPOSE (parmtypes) != NULL_TREE) TYPE_HAS_DEFAULT_CONSTRUCTOR (ctype) = 1; return 1; } /* An operator with this name can be either unary or binary. */ static int ambi_op_p (name) tree name; { return (name == ansi_opname [(int) INDIRECT_REF] || name == ansi_opname [(int) ADDR_EXPR] || name == ansi_opname [(int) NEGATE_EXPR] || name == ansi_opname[(int) POSTINCREMENT_EXPR] || name == ansi_opname[(int) POSTDECREMENT_EXPR] || name == ansi_opname [(int) CONVERT_EXPR]); } /* An operator with this name can only be unary. */ static int unary_op_p (name) tree name; { return (name == ansi_opname [(int) TRUTH_NOT_EXPR] || name == ansi_opname [(int) BIT_NOT_EXPR] || name == ansi_opname [(int) COMPONENT_REF] || IDENTIFIER_TYPENAME_P (name)); } /* Do a little sanity-checking on how they declared their operator. */ void grok_op_properties (decl, virtualp, friendp) tree decl; int virtualp, friendp; { tree argtypes = TYPE_ARG_TYPES (TREE_TYPE (decl)); int methodp = (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE); tree name = DECL_NAME (decl); if (current_class_type == NULL_TREE) friendp = 1; if (! friendp) { /* [class.copy] A user-declared copy assignment operator X::operator= is a non-static non-template member function of class X with exactly one parameter of type X, X&, const X&, volatile X& or const volatile X&. */ if (name == ansi_opname[(int) MODIFY_EXPR] && !(DECL_TEMPLATE_INSTANTIATION (decl) && is_member_template (DECL_TI_TEMPLATE (decl)))) ; else if (name == ansi_opname[(int) CALL_EXPR]) TYPE_OVERLOADS_CALL_EXPR (current_class_type) = 1; else if (name == ansi_opname[(int) ARRAY_REF]) TYPE_OVERLOADS_ARRAY_REF (current_class_type) = 1; else if (name == ansi_opname[(int) COMPONENT_REF] || name == ansi_opname[(int) MEMBER_REF]) TYPE_OVERLOADS_ARROW (current_class_type) = 1; else if (name == ansi_opname[(int) NEW_EXPR]) TYPE_GETS_NEW (current_class_type) |= 1; else if (name == ansi_opname[(int) DELETE_EXPR]) TYPE_GETS_DELETE (current_class_type) |= 1; else if (name == ansi_opname[(int) VEC_NEW_EXPR]) TYPE_GETS_NEW (current_class_type) |= 2; else if (name == ansi_opname[(int) VEC_DELETE_EXPR]) TYPE_GETS_DELETE (current_class_type) |= 2; } if (name == ansi_opname[(int) NEW_EXPR] || name == ansi_opname[(int) VEC_NEW_EXPR]) { /* When the compiler encounters the definition of A::operator new, it doesn't look at the class declaration to find out if it's static. */ if (methodp) revert_static_member_fn (&decl, NULL, NULL); /* Take care of function decl if we had syntax errors. */ if (argtypes == NULL_TREE) TREE_TYPE (decl) = build_function_type (ptr_type_node, hash_tree_chain (integer_type_node, void_list_node)); else TREE_TYPE (decl) = coerce_new_type (TREE_TYPE (decl)); } else if (name == ansi_opname[(int) DELETE_EXPR] || name == ansi_opname[(int) VEC_DELETE_EXPR]) { if (methodp) revert_static_member_fn (&decl, NULL, NULL); if (argtypes == NULL_TREE) TREE_TYPE (decl) = build_function_type (void_type_node, hash_tree_chain (ptr_type_node, void_list_node)); else { TREE_TYPE (decl) = coerce_delete_type (TREE_TYPE (decl)); if (! friendp && name == ansi_opname[(int) VEC_DELETE_EXPR] && (TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (decl))) != void_list_node)) TYPE_VEC_DELETE_TAKES_SIZE (current_class_type) = 1; } } else { /* An operator function must either be a non-static member function or have at least one parameter of a class, a reference to a class, an enumeration, or a reference to an enumeration. 13.4.0.6 */ if (! methodp || DECL_STATIC_FUNCTION_P (decl)) { if (IDENTIFIER_TYPENAME_P (name) || name == ansi_opname[(int) CALL_EXPR] || name == ansi_opname[(int) MODIFY_EXPR] || name == ansi_opname[(int) COMPONENT_REF] || name == ansi_opname[(int) ARRAY_REF]) cp_error ("`%D' must be a nonstatic member function", decl); else { tree p = argtypes; if (DECL_STATIC_FUNCTION_P (decl)) cp_error ("`%D' must be either a non-static member function or a non-member function", decl); if (p) for (; TREE_CODE (TREE_VALUE (p)) != VOID_TYPE ; p = TREE_CHAIN (p)) { tree arg = TREE_VALUE (p); if (TREE_CODE (arg) == REFERENCE_TYPE) arg = TREE_TYPE (arg); /* This lets bad template code slip through. */ if (IS_AGGR_TYPE (arg) || TREE_CODE (arg) == ENUMERAL_TYPE || TREE_CODE (arg) == TEMPLATE_TYPE_PARM || TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM) goto foundaggr; } cp_error ("`%D' must have an argument of class or enumerated type", decl); foundaggr: ; } } if (name == ansi_opname[(int) CALL_EXPR]) return; /* No restrictions on args. */ if (IDENTIFIER_TYPENAME_P (name) && ! DECL_TEMPLATE_INFO (decl)) { tree t = TREE_TYPE (name); if (TREE_CODE (t) == VOID_TYPE) pedwarn ("void is not a valid type conversion operator"); else if (! friendp) { int ref = (TREE_CODE (t) == REFERENCE_TYPE); const char *what = 0; if (ref) t = TYPE_MAIN_VARIANT (TREE_TYPE (t)); if (t == current_class_type) what = "the same type"; /* Don't force t to be complete here. */ else if (IS_AGGR_TYPE (t) && TYPE_SIZE (t) && DERIVED_FROM_P (t, current_class_type)) what = "a base class"; if (what) warning ("conversion to %s%s will never use a type conversion operator", ref ? "a reference to " : "", what); } } if (name == ansi_opname[(int) MODIFY_EXPR]) { tree parmtype; if (list_length (argtypes) != 3 && methodp) { cp_error ("`%D' must take exactly one argument", decl); return; } parmtype = TREE_VALUE (TREE_CHAIN (argtypes)); if (copy_assignment_arg_p (parmtype, virtualp) && ! friendp) { TYPE_HAS_ASSIGN_REF (current_class_type) = 1; if (TREE_CODE (parmtype) != REFERENCE_TYPE || CP_TYPE_CONST_P (TREE_TYPE (parmtype))) TYPE_HAS_CONST_ASSIGN_REF (current_class_type) = 1; } } else if (name == ansi_opname[(int) COND_EXPR]) { /* 13.4.0.3 */ pedwarn ("ANSI C++ prohibits overloading operator ?:"); if (list_length (argtypes) != 4) cp_error ("`%D' must take exactly three arguments", decl); } else if (ambi_op_p (name)) { if (list_length (argtypes) == 2) /* prefix */; else if (list_length (argtypes) == 3) { if ((name == ansi_opname[(int) POSTINCREMENT_EXPR] || name == ansi_opname[(int) POSTDECREMENT_EXPR]) && ! processing_template_decl && ! same_type_p (TREE_VALUE (TREE_CHAIN (argtypes)), integer_type_node)) { if (methodp) cp_error ("postfix `%D' must take `int' as its argument", decl); else cp_error ("postfix `%D' must take `int' as its second argument", decl); } } else { if (methodp) cp_error ("`%D' must take either zero or one argument", decl); else cp_error ("`%D' must take either one or two arguments", decl); } /* More Effective C++ rule 6. */ if (warn_ecpp && (name == ansi_opname[(int) POSTINCREMENT_EXPR] || name == ansi_opname[(int) POSTDECREMENT_EXPR])) { tree arg = TREE_VALUE (argtypes); tree ret = TREE_TYPE (TREE_TYPE (decl)); if (methodp || TREE_CODE (arg) == REFERENCE_TYPE) arg = TREE_TYPE (arg); arg = TYPE_MAIN_VARIANT (arg); if (list_length (argtypes) == 2) { if (TREE_CODE (ret) != REFERENCE_TYPE || !same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (ret)), arg)) cp_warning ("prefix `%D' should return `%T'", decl, build_reference_type (arg)); } else { if (!same_type_p (TYPE_MAIN_VARIANT (ret), arg)) cp_warning ("postfix `%D' should return `%T'", decl, arg); } } } else if (unary_op_p (name)) { if (list_length (argtypes) != 2) { if (methodp) cp_error ("`%D' must take `void'", decl); else cp_error ("`%D' must take exactly one argument", decl); } } else /* if (binary_op_p (name)) */ { if (list_length (argtypes) != 3) { if (methodp) cp_error ("`%D' must take exactly one argument", decl); else cp_error ("`%D' must take exactly two arguments", decl); } /* More Effective C++ rule 7. */ if (warn_ecpp && (name == ansi_opname [TRUTH_ANDIF_EXPR] || name == ansi_opname [TRUTH_ORIF_EXPR] || name == ansi_opname [COMPOUND_EXPR])) cp_warning ("user-defined `%D' always evaluates both arguments", decl); } /* Effective C++ rule 23. */ if (warn_ecpp && list_length (argtypes) == 3 && (name == ansi_opname [PLUS_EXPR] || name == ansi_opname [MINUS_EXPR] || name == ansi_opname [TRUNC_DIV_EXPR] || name == ansi_opname [MULT_EXPR]) && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == REFERENCE_TYPE) cp_warning ("`%D' should return by value", decl); /* 13.4.0.8 */ if (argtypes) for (; argtypes != void_list_node ; argtypes = TREE_CHAIN (argtypes)) if (TREE_PURPOSE (argtypes)) { TREE_PURPOSE (argtypes) = NULL_TREE; if (name == ansi_opname[(int) POSTINCREMENT_EXPR] || name == ansi_opname[(int) POSTDECREMENT_EXPR]) { if (pedantic) cp_pedwarn ("`%D' cannot have default arguments", decl); } else cp_error ("`%D' cannot have default arguments", decl); } } } static const char * tag_name (code) enum tag_types code; { switch (code) { case record_type: return "struct"; case class_type: return "class"; case union_type: return "union "; case enum_type: return "enum"; case signature_type: return "signature"; default: my_friendly_abort (981122); } } /* Get the struct, enum or union (CODE says which) with tag NAME. Define the tag as a forward-reference if it is not defined. C++: If a class derivation is given, process it here, and report an error if multiple derivation declarations are not identical. If this is a definition, come in through xref_tag and only look in the current frame for the name (since C++ allows new names in any scope.) */ tree xref_tag (code_type_node, name, globalize) tree code_type_node; tree name; int globalize; { enum tag_types tag_code; enum tree_code code; int temp = 0; register tree ref, t; struct binding_level *b = current_binding_level; int got_type = 0; tree attributes = NULL_TREE; tree context = NULL_TREE; /* If we are called from the parser, code_type_node will sometimes be a TREE_LIST. This indicates that the user wrote "class __attribute__ ((foo)) bar". Extract the attributes so we can use them later. */ if (TREE_CODE (code_type_node) == TREE_LIST) { attributes = TREE_PURPOSE (code_type_node); code_type_node = TREE_VALUE (code_type_node); } tag_code = (enum tag_types) TREE_INT_CST_LOW (code_type_node); switch (tag_code) { case record_type: case class_type: case signature_type: code = RECORD_TYPE; break; case union_type: code = UNION_TYPE; break; case enum_type: code = ENUMERAL_TYPE; break; default: my_friendly_abort (18); } /* If a cross reference is requested, look up the type already defined for this tag and return it. */ if (TREE_CODE_CLASS (TREE_CODE (name)) == 't') { t = name; name = TYPE_IDENTIFIER (t); got_type = 1; } else t = IDENTIFIER_TYPE_VALUE (name); if (t && TREE_CODE (t) != code && TREE_CODE (t) != TEMPLATE_TYPE_PARM && TREE_CODE (t) != TEMPLATE_TEMPLATE_PARM) t = NULL_TREE; if (! globalize) { /* If we know we are defining this tag, only look it up in this scope and don't try to find it as a type. */ ref = lookup_tag (code, name, b, 1); } else { if (t) { /* [dcl.type.elab] If the identifier resolves to a typedef-name or a template type-parameter, the elaborated-type-specifier is ill-formed. */ if (t != TYPE_MAIN_VARIANT (t) || (CLASS_TYPE_P (t) && TYPE_WAS_ANONYMOUS (t))) cp_pedwarn ("using typedef-name `%D' after `%s'", TYPE_NAME (t), tag_name (tag_code)); else if (TREE_CODE (t) == TEMPLATE_TYPE_PARM) cp_error ("using template type parameter `%T' after `%s'", t, tag_name (tag_code)); ref = t; } else ref = lookup_tag (code, name, b, 0); if (! ref) { /* Try finding it as a type declaration. If that wins, use it. */ ref = lookup_name (name, 1); if (ref != NULL_TREE && processing_template_decl && DECL_CLASS_TEMPLATE_P (ref) && template_class_depth (current_class_type) == 0) /* Since GLOBALIZE is true, we're declaring a global template, so we want this type. */ ref = DECL_RESULT (ref); if (ref && TREE_CODE (ref) == TYPE_DECL && TREE_CODE (TREE_TYPE (ref)) == code) ref = TREE_TYPE (ref); else ref = NULL_TREE; } if (ref && current_class_type && template_class_depth (current_class_type) && PROCESSING_REAL_TEMPLATE_DECL_P ()) { /* Since GLOBALIZE is non-zero, we are not looking at a definition of this tag. Since, in addition, we are currently processing a (member) template declaration of a template class, we must be very careful; consider: template struct S1 template struct S2 { template friend struct S1; }; Here, the S2::S1 declaration should not be confused with the outer declaration. In particular, the inner version should have a template parameter of level 2, not level 1. This would be particularly important if the member declaration were instead: template friend struct S1; say, when we should tsubst into `U' when instantiating S2. On the other hand, when presented with: template struct S1 { template struct S2 {}; template friend struct S2; }; we must find the inner binding eventually. We accomplish this by making sure that the new type we create to represent this declaration has the right TYPE_CONTEXT. */ context = TYPE_CONTEXT (ref); ref = NULL_TREE; } } push_obstacks_nochange (); if (! ref) { /* If no such tag is yet defined, create a forward-reference node and record it as the "definition". When a real declaration of this type is found, the forward-reference will be altered into a real type. */ /* In C++, since these migrate into the global scope, we must build them on the permanent obstack. */ temp = allocation_temporary_p (); if (temp) end_temporary_allocation (); if (code == ENUMERAL_TYPE) { cp_error ("use of enum `%#D' without previous declaration", name); ref = make_node (ENUMERAL_TYPE); /* Give the type a default layout like unsigned int to avoid crashing if it does not get defined. */ TYPE_MODE (ref) = TYPE_MODE (unsigned_type_node); TYPE_ALIGN (ref) = TYPE_ALIGN (unsigned_type_node); TREE_UNSIGNED (ref) = 1; TYPE_PRECISION (ref) = TYPE_PRECISION (unsigned_type_node); TYPE_MIN_VALUE (ref) = TYPE_MIN_VALUE (unsigned_type_node); TYPE_MAX_VALUE (ref) = TYPE_MAX_VALUE (unsigned_type_node); /* Enable us to recognize when a type is created in class context. To do nested classes correctly, this should probably be cleared out when we leave this classes scope. Currently this in only done in `start_enum'. */ pushtag (name, ref, globalize); } else { struct binding_level *old_b = class_binding_level; ref = make_lang_type (code); TYPE_CONTEXT (ref) = context; if (tag_code == signature_type) { SET_SIGNATURE (ref); /* Since a signature type will be turned into the type of signature tables, it's not only an interface. */ CLASSTYPE_INTERFACE_ONLY (ref) = 0; SET_CLASSTYPE_INTERFACE_KNOWN (ref); /* A signature doesn't have a vtable. */ CLASSTYPE_VTABLE_NEEDS_WRITING (ref) = 0; } #ifdef NONNESTED_CLASSES /* Class types don't nest the way enums do. */ class_binding_level = (struct binding_level *)0; #endif pushtag (name, ref, globalize); class_binding_level = old_b; } } else { /* If it no longer looks like a nested type, make sure it's in global scope. If it is not an IDENTIFIER, this is not a declaration */ if (b->namespace_p && !class_binding_level && TREE_CODE (name) == IDENTIFIER_NODE) { if (IDENTIFIER_NAMESPACE_VALUE (name) == NULL_TREE) SET_IDENTIFIER_NAMESPACE_VALUE (name, TYPE_NAME (ref)); } if (!globalize && processing_template_decl && IS_AGGR_TYPE (ref)) redeclare_class_template (ref, current_template_parms); } /* Until the type is defined, tentatively accept whatever structure tag the user hands us. */ if (TYPE_SIZE (ref) == NULL_TREE && ref != current_class_type /* Have to check this, in case we have contradictory tag info. */ && IS_AGGR_TYPE_CODE (TREE_CODE (ref))) { if (tag_code == class_type) CLASSTYPE_DECLARED_CLASS (ref) = 1; else if (tag_code == record_type || tag_code == signature_type) CLASSTYPE_DECLARED_CLASS (ref) = 0; } pop_obstacks (); TREE_TYPE (ref) = attributes; return ref; } tree xref_tag_from_type (old, id, globalize) tree old, id; int globalize; { tree code_type_node; if (TREE_CODE (old) == RECORD_TYPE) code_type_node = (CLASSTYPE_DECLARED_CLASS (old) ? class_type_node : record_type_node); else code_type_node = union_type_node; if (id == NULL_TREE) id = TYPE_IDENTIFIER (old); return xref_tag (code_type_node, id, globalize); } /* REF is a type (named NAME), for which we have just seen some baseclasses. BINFO is a list of those baseclasses; the TREE_PURPOSE is an access_* node, and the TREE_VALUE is the type of the base-class. CODE_TYPE_NODE indicates whether REF is a class, struct, or union. */ void xref_basetypes (code_type_node, name, ref, binfo) tree code_type_node; tree name, ref; tree binfo; { /* In the declaration `A : X, Y, ... Z' we mark all the types (A, X, Y, ..., Z) so we can check for duplicates. */ tree binfos; tree base; int i, len; enum tag_types tag_code = (enum tag_types) TREE_INT_CST_LOW (code_type_node); if (tag_code == union_type) { cp_error ("derived union `%T' invalid", ref); return; } len = list_length (binfo); push_obstacks (TYPE_OBSTACK (ref), TYPE_OBSTACK (ref)); /* First, make sure that any templates in base-classes are instantiated. This ensures that if we call ourselves recursively we do not get confused about which classes are marked and which are not. */ for (base = binfo; base; base = TREE_CHAIN (base)) complete_type (TREE_VALUE (base)); SET_CLASSTYPE_MARKED (ref); BINFO_BASETYPES (TYPE_BINFO (ref)) = binfos = make_tree_vec (len); for (i = 0; binfo; binfo = TREE_CHAIN (binfo)) { /* The base of a derived struct is public by default. */ int via_public = (TREE_PURPOSE (binfo) == access_public_node || TREE_PURPOSE (binfo) == access_public_virtual_node || (tag_code != class_type && (TREE_PURPOSE (binfo) == access_default_node || TREE_PURPOSE (binfo) == access_default_virtual_node))); int via_protected = (TREE_PURPOSE (binfo) == access_protected_node || TREE_PURPOSE (binfo) == access_protected_virtual_node); int via_virtual = (TREE_PURPOSE (binfo) == access_private_virtual_node || TREE_PURPOSE (binfo) == access_protected_virtual_node || TREE_PURPOSE (binfo) == access_public_virtual_node || TREE_PURPOSE (binfo) == access_default_virtual_node); tree basetype = TREE_VALUE (binfo); tree base_binfo; if (basetype && TREE_CODE (basetype) == TYPE_DECL) basetype = TREE_TYPE (basetype); if (!basetype || (TREE_CODE (basetype) != RECORD_TYPE && TREE_CODE (basetype) != TYPENAME_TYPE && TREE_CODE (basetype) != TEMPLATE_TYPE_PARM && TREE_CODE (basetype) != TEMPLATE_TEMPLATE_PARM)) { cp_error ("base type `%T' fails to be a struct or class type", TREE_VALUE (binfo)); continue; } GNU_xref_hier (name, basetype, via_public, via_virtual, 0); /* This code replaces similar code in layout_basetypes. We put the complete_type first for implicit `typename'. */ if (TYPE_SIZE (basetype) == NULL_TREE && ! (current_template_parms && uses_template_parms (basetype))) { cp_error ("base class `%T' has incomplete type", basetype); continue; } else { if (CLASSTYPE_MARKED (basetype)) { if (basetype == ref) cp_error ("recursive type `%T' undefined", basetype); else cp_error ("duplicate base type `%T' invalid", basetype); continue; } if (TYPE_FOR_JAVA (basetype) && current_lang_stack == current_lang_base) TYPE_FOR_JAVA (ref) = 1; /* Note that the BINFO records which describe individual inheritances are *not* shared in the lattice! They cannot be shared because a given baseclass may be inherited with different `accessibility' by different derived classes. (Each BINFO record describing an individual inheritance contains flags which say what the `accessibility' of that particular inheritance is.) */ base_binfo = make_binfo (integer_zero_node, basetype, CLASS_TYPE_P (basetype) ? TYPE_BINFO_VTABLE (basetype) : NULL_TREE, CLASS_TYPE_P (basetype) ? TYPE_BINFO_VIRTUALS (basetype) : NULL_TREE); TREE_VEC_ELT (binfos, i) = base_binfo; TREE_VIA_PUBLIC (base_binfo) = via_public; TREE_VIA_PROTECTED (base_binfo) = via_protected; TREE_VIA_VIRTUAL (base_binfo) = via_virtual; BINFO_INHERITANCE_CHAIN (base_binfo) = TYPE_BINFO (ref); /* We need to unshare the binfos now so that lookups during class definition work. */ unshare_base_binfos (base_binfo); SET_CLASSTYPE_MARKED (basetype); /* We are free to modify these bits because they are meaningless at top level, and BASETYPE is a top-level type. */ if (via_virtual || TYPE_USES_VIRTUAL_BASECLASSES (basetype)) { TYPE_USES_VIRTUAL_BASECLASSES (ref) = 1; TYPE_USES_COMPLEX_INHERITANCE (ref) = 1; + /* The PVBASES flag is never set for templates; we know + only for instantiations whether the virtual bases are + polymorphic. */ + if (flag_vtable_thunks >= 2 && !CLASSTYPE_IS_TEMPLATE (ref)) + { + if (via_virtual && TYPE_VIRTUAL_P (basetype)) + TYPE_USES_PVBASES (ref) = 1; + else if (TYPE_USES_PVBASES (basetype)) + TYPE_USES_PVBASES (ref) = 1; + } } if (CLASS_TYPE_P (basetype)) { TYPE_GETS_NEW (ref) |= TYPE_GETS_NEW (basetype); TYPE_GETS_DELETE (ref) |= TYPE_GETS_DELETE (basetype); } i += 1; } } if (i) TREE_VEC_LENGTH (binfos) = i; else BINFO_BASETYPES (TYPE_BINFO (ref)) = NULL_TREE; if (i > 1) TYPE_USES_MULTIPLE_INHERITANCE (ref) = 1; else if (i == 1) { tree basetype = BINFO_TYPE (TREE_VEC_ELT (binfos, 0)); if (CLASS_TYPE_P (basetype)) TYPE_USES_MULTIPLE_INHERITANCE (ref) = TYPE_USES_MULTIPLE_INHERITANCE (basetype); } if (TYPE_USES_MULTIPLE_INHERITANCE (ref)) TYPE_USES_COMPLEX_INHERITANCE (ref) = 1; /* Unmark all the types. */ while (--i >= 0) CLEAR_CLASSTYPE_MARKED (BINFO_TYPE (TREE_VEC_ELT (binfos, i))); CLEAR_CLASSTYPE_MARKED (ref); /* Now that we know all the base-classes, set up the list of virtual bases. */ CLASSTYPE_VBASECLASSES (ref) = get_vbase_types (ref); pop_obstacks (); } /* Begin compiling the definition of an enumeration type. NAME is its name (or null if anonymous). Returns the type object, as yet incomplete. Also records info about it so that build_enumerator may be used to declare the individual values as they are read. */ tree start_enum (name) tree name; { register tree enumtype = NULL_TREE; struct binding_level *b = current_binding_level; /* We are wasting space here and putting these on the permanent_obstack so that typeid(local enum) will work correctly. */ push_obstacks (&permanent_obstack, &permanent_obstack); /* If this is the real definition for a previous forward reference, fill in the contents in the same object that used to be the forward reference. */ if (name != NULL_TREE) enumtype = lookup_tag (ENUMERAL_TYPE, name, b, 1); if (enumtype != NULL_TREE && TREE_CODE (enumtype) == ENUMERAL_TYPE) cp_error ("multiple definition of `%#T'", enumtype); else { enumtype = make_node (ENUMERAL_TYPE); pushtag (name, enumtype, 0); } if (current_class_type) TREE_ADDRESSABLE (b->tags) = 1; /* We don't copy this value because build_enumerator needs to do it. */ enum_next_value = integer_zero_node; enum_overflow = 0; GNU_xref_decl (current_function_decl, enumtype); return enumtype; } /* After processing and defining all the values of an enumeration type, install their decls in the enumeration type and finish it off. ENUMTYPE is the type object and VALUES a list of name-value pairs. Returns ENUMTYPE. */ tree finish_enum (enumtype) tree enumtype; { register tree minnode = NULL_TREE, maxnode = NULL_TREE; /* Calculate the maximum value of any enumerator in this type. */ tree values = TYPE_VALUES (enumtype); if (values) { tree pair; for (pair = values; pair; pair = TREE_CHAIN (pair)) { tree decl; tree value; /* The TREE_VALUE is a CONST_DECL for this enumeration constant. */ decl = TREE_VALUE (pair); /* The DECL_INITIAL will be NULL if we are processing a template declaration and this enumeration constant had no explicit initializer. */ value = DECL_INITIAL (decl); if (value && !processing_template_decl) { /* Set the TREE_TYPE for the VALUE as well. That's so that when we call decl_constant_value we get an entity of the right type (but with the constant value). Since we shouldn't ever call decl_constant_value on a template type, there's no reason to do that when processing_template_decl. And, if the expression is something like a TEMPLATE_PARM_INDEX or a CAST_EXPR doing so will wreak havoc on the intended type of the expression. Of course, there's also no point in trying to compute minimum or maximum values if we're in a template. */ TREE_TYPE (value) = enumtype; if (!minnode) minnode = maxnode = value; else if (tree_int_cst_lt (maxnode, value)) maxnode = value; else if (tree_int_cst_lt (value, minnode)) minnode = value; } if (processing_template_decl) /* If this is just a template, leave the CONST_DECL alone. That way tsubst_copy will find CONST_DECLs for CONST_DECLs, and not INTEGER_CSTs. */ ; else /* In the list we're building up, we want the enumeration values, not the CONST_DECLs. */ TREE_VALUE (pair) = value; } } else maxnode = minnode = integer_zero_node; TYPE_VALUES (enumtype) = nreverse (values); if (processing_template_decl) { tree scope = current_scope (); if (scope && TREE_CODE (scope) == FUNCTION_DECL) add_tree (build_min (TAG_DEFN, enumtype)); } else { int unsignedp = tree_int_cst_sgn (minnode) >= 0; int lowprec = min_precision (minnode, unsignedp); int highprec = min_precision (maxnode, unsignedp); int precision = MAX (lowprec, highprec); tree tem; TYPE_SIZE (enumtype) = NULL_TREE; /* Set TYPE_MIN_VALUE and TYPE_MAX_VALUE according to `precision'. */ TYPE_PRECISION (enumtype) = precision; if (unsignedp) fixup_unsigned_type (enumtype); else fixup_signed_type (enumtype); if (flag_short_enums || (precision > TYPE_PRECISION (integer_type_node))) /* Use the width of the narrowest normal C type which is wide enough. */ TYPE_PRECISION (enumtype) = TYPE_PRECISION (type_for_size (precision, 1)); else TYPE_PRECISION (enumtype) = TYPE_PRECISION (integer_type_node); TYPE_SIZE (enumtype) = 0; layout_type (enumtype); /* Fix up all variant types of this enum type. */ for (tem = TYPE_MAIN_VARIANT (enumtype); tem; tem = TYPE_NEXT_VARIANT (tem)) { TYPE_VALUES (tem) = TYPE_VALUES (enumtype); TYPE_MIN_VALUE (tem) = TYPE_MIN_VALUE (enumtype); TYPE_MAX_VALUE (tem) = TYPE_MAX_VALUE (enumtype); TYPE_SIZE (tem) = TYPE_SIZE (enumtype); TYPE_SIZE_UNIT (tem) = TYPE_SIZE_UNIT (enumtype); TYPE_MODE (tem) = TYPE_MODE (enumtype); TYPE_PRECISION (tem) = TYPE_PRECISION (enumtype); TYPE_ALIGN (tem) = TYPE_ALIGN (enumtype); TREE_UNSIGNED (tem) = TREE_UNSIGNED (enumtype); } /* Finish debugging output for this type. */ rest_of_type_compilation (enumtype, namespace_bindings_p ()); } /* In start_enum we pushed obstacks. Here, we must pop them. */ pop_obstacks (); return enumtype; } /* Build and install a CONST_DECL for an enumeration constant of the enumeration type TYPE whose NAME and VALUE (if any) are provided. Assignment of sequential values by default is handled here. */ tree build_enumerator (name, value, type) tree name; tree value; tree type; { tree decl, result; tree context; /* Remove no-op casts from the value. */ if (value) STRIP_TYPE_NOPS (value); if (! processing_template_decl) { /* Validate and default VALUE. */ if (value != NULL_TREE) { if (TREE_READONLY_DECL_P (value)) value = decl_constant_value (value); if (TREE_CODE (value) == INTEGER_CST) { value = default_conversion (value); constant_expression_warning (value); } else { cp_error ("enumerator value for `%D' not integer constant", name); value = NULL_TREE; } } /* Default based on previous value. */ if (value == NULL_TREE && ! processing_template_decl) { value = enum_next_value; if (enum_overflow) cp_error ("overflow in enumeration values at `%D'", name); } /* Remove no-op casts from the value. */ if (value) STRIP_TYPE_NOPS (value); #if 0 /* To fix MAX_VAL enum consts. (bkoz) */ TREE_TYPE (value) = integer_type_node; #endif } /* We always have to copy here; not all INTEGER_CSTs are unshared. Even in other cases, we will later (in finish_enum) be setting the type of VALUE. */ if (value != NULL_TREE) value = copy_node (value); /* C++ associates enums with global, function, or class declarations. */ context = current_scope (); if (context && context == current_class_type) /* This enum declaration is local to the class. */ decl = build_lang_field_decl (CONST_DECL, name, type); else /* It's a global enum, or it's local to a function. (Note local to a function could mean local to a class method. */ decl = build_decl (CONST_DECL, name, type); DECL_CONTEXT (decl) = FROB_CONTEXT (context); DECL_INITIAL (decl) = value; TREE_READONLY (decl) = 1; if (context && context == current_class_type) /* In something like `struct S { enum E { i = 7 }; };' we put `i' on the TYPE_FIELDS list for `S'. (That's so that you can say things like `S::i' later.) */ finish_member_declaration (decl); else { pushdecl (decl); GNU_xref_decl (current_function_decl, decl); } if (! processing_template_decl) { /* Set basis for default for next value. */ enum_next_value = build_binary_op_nodefault (PLUS_EXPR, value, integer_one_node, PLUS_EXPR); enum_overflow = tree_int_cst_lt (enum_next_value, value); } result = saveable_tree_cons (name, decl, NULL_TREE); return result; } static int function_depth; /* Create the FUNCTION_DECL for a function definition. DECLSPECS and DECLARATOR are the parts of the declaration; they describe the function's name and the type it returns, but twisted together in a fashion that parallels the syntax of C. If PRE_PARSED_P is non-zero then DECLARATOR is really the DECL for the function we are about to process; DECLSPECS are ignored. For example, we set PRE_PARSED_P when processing the definition of inline function that was defined in-class; the definition is actually processed when the class is complete. In this case, PRE_PARSED_P is 2. We also set PRE_PARSED_P when instanting the body of a template function, and when constructing thunk functions and such; in these cases PRE_PARSED_P is 1. This function creates a binding context for the function body as well as setting up the FUNCTION_DECL in current_function_decl. Returns 1 on success. If the DECLARATOR is not suitable for a function (it defines a datum instead), we return 0, which tells yyparse to report a parse error. For C++, we must first check whether that datum makes any sense. For example, "class A local_a(1,2);" means that variable local_a is an aggregate of type A, which should have a constructor applied to it with the argument list [1, 2]. @@ There is currently no way to retrieve the storage @@ allocated to FUNCTION (or all of its parms) if we return @@ something we had previously. */ int start_function (declspecs, declarator, attrs, pre_parsed_p) tree declspecs, declarator, attrs; int pre_parsed_p; { tree decl1; tree ctype = NULL_TREE; tree fntype; tree restype; extern int have_extern_spec; extern int used_extern_spec; int doing_friend = 0; /* Sanity check. */ my_friendly_assert (TREE_CODE (TREE_VALUE (void_list_node)) == VOID_TYPE, 160); my_friendly_assert (TREE_CHAIN (void_list_node) == NULL_TREE, 161); /* Assume, until we see it does. */ current_function_returns_value = 0; current_function_returns_null = 0; named_labels = 0; shadowed_labels = 0; current_function_assigns_this = 0; current_function_just_assigned_this = 0; current_function_parms_stored = 0; original_result_rtx = NULL_RTX; base_init_expr = NULL_TREE; current_base_init_list = NULL_TREE; current_member_init_list = NULL_TREE; ctor_label = dtor_label = NULL_TREE; static_labelno = 0; clear_temp_name (); /* This should only be done once on the top most decl. */ if (have_extern_spec && !used_extern_spec) { declspecs = decl_tree_cons (NULL_TREE, get_identifier ("extern"), declspecs); used_extern_spec = 1; } if (pre_parsed_p) { decl1 = declarator; #if 0 /* What was this testing for, exactly? */ if (! DECL_ARGUMENTS (decl1) && !DECL_STATIC_FUNCTION_P (decl1) && !DECL_ARTIFICIAL (decl1) && DECL_CLASS_SCOPE_P (decl1) && TYPE_IDENTIFIER (DECL_CONTEXT (decl1)) && IDENTIFIER_TEMPLATE (TYPE_IDENTIFIER (DECL_CONTEXT (decl1)))) { tree binding = binding_for_name (DECL_NAME (decl1), current_namespace); cp_error ("redeclaration of `%#D'", decl1); if (IDENTIFIER_CLASS_VALUE (DECL_NAME (decl1))) cp_error_at ("previous declaration here", IDENTIFIER_CLASS_VALUE (DECL_NAME (decl1))); else if (BINDING_VALUE (binding)) cp_error_at ("previous declaration here", BINDING_VALUE (binding)); } #endif fntype = TREE_TYPE (decl1); if (TREE_CODE (fntype) == METHOD_TYPE) ctype = TYPE_METHOD_BASETYPE (fntype); /* ANSI C++ June 5 1992 WP 11.4.5. A friend function defined in a class is in the (lexical) scope of the class in which it is defined. */ if (!ctype && DECL_FRIEND_P (decl1)) { ctype = DECL_CLASS_CONTEXT (decl1); /* CTYPE could be null here if we're dealing with a template; for example, `inline friend float foo()' inside a template will have no CTYPE set. */ if (ctype && TREE_CODE (ctype) != RECORD_TYPE) ctype = NULL_TREE; else doing_friend = 1; } last_function_parms = DECL_ARGUMENTS (decl1); last_function_parm_tags = NULL_TREE; } else { decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, 1, NULL_TREE); /* If the declarator is not suitable for a function definition, cause a syntax error. */ if (decl1 == NULL_TREE || TREE_CODE (decl1) != FUNCTION_DECL) return 0; fntype = TREE_TYPE (decl1); restype = TREE_TYPE (fntype); if (CLASS_TYPE_P (restype) && !CLASSTYPE_GOT_SEMICOLON (restype)) { cp_error ("semicolon missing after declaration of `%#T'", restype); shadow_tag (build_expr_list (NULL_TREE, restype)); CLASSTYPE_GOT_SEMICOLON (restype) = 1; if (TREE_CODE (fntype) == FUNCTION_TYPE) fntype = build_function_type (integer_type_node, TYPE_ARG_TYPES (fntype)); else fntype = build_cplus_method_type (build_type_variant (TYPE_METHOD_BASETYPE (fntype), TREE_READONLY (decl1), TREE_SIDE_EFFECTS (decl1)), integer_type_node, TYPE_ARG_TYPES (fntype)); TREE_TYPE (decl1) = fntype; } if (TREE_CODE (fntype) == METHOD_TYPE) ctype = TYPE_METHOD_BASETYPE (fntype); else if (DECL_MAIN_P (decl1)) { /* If this doesn't return integer_type, complain. */ if (TREE_TYPE (TREE_TYPE (decl1)) != integer_type_node) { if (pedantic || warn_return_type) pedwarn ("return type for `main' changed to `int'"); TREE_TYPE (decl1) = fntype = default_function_type; } } } /* Warn if function was previously implicitly declared (but not if we warned then). */ if (! warn_implicit && IDENTIFIER_IMPLICIT_DECL (DECL_NAME (decl1)) != NULL_TREE) cp_warning_at ("`%D' implicitly declared before its definition", IDENTIFIER_IMPLICIT_DECL (DECL_NAME (decl1))); announce_function (decl1); /* Set up current_class_type, and enter the scope of the class, if appropriate. */ if (ctype) push_nested_class (ctype, 1); else if (DECL_STATIC_FUNCTION_P (decl1)) push_nested_class (DECL_CONTEXT (decl1), 2); /* Now that we have entered the scope of the class, we must restore the bindings for any template parameters surrounding DECL1, if it is an inline member template. (Order is important; consider the case where a template parameter has the same name as a field of the class.) It is not until after this point that PROCESSING_TEMPLATE_DECL is guaranteed to be set up correctly. */ if (pre_parsed_p == 2) maybe_begin_member_template_processing (decl1); /* We are now in the scope of the function being defined. */ current_function_decl = decl1; /* Save the parm names or decls from this function's declarator where store_parm_decls will find them. */ current_function_parms = last_function_parms; current_function_parm_tags = last_function_parm_tags; if (! processing_template_decl) { /* In a function definition, arg types must be complete. */ require_complete_types_for_parms (current_function_parms); if (TYPE_SIZE (complete_type (TREE_TYPE (fntype))) == NULL_TREE) { cp_error ("return-type `%#T' is an incomplete type", TREE_TYPE (fntype)); /* Make it return void instead, but don't change the type of the DECL_RESULT, in case we have a named return value. */ if (ctype) TREE_TYPE (decl1) = build_cplus_method_type (build_type_variant (ctype, TREE_READONLY (decl1), TREE_SIDE_EFFECTS (decl1)), void_type_node, FUNCTION_ARG_CHAIN (decl1)); else TREE_TYPE (decl1) = build_function_type (void_type_node, TYPE_ARG_TYPES (TREE_TYPE (decl1))); DECL_RESULT (decl1) = build_decl (RESULT_DECL, 0, TYPE_MAIN_VARIANT (TREE_TYPE (fntype))); TREE_READONLY (DECL_RESULT (decl1)) = CP_TYPE_CONST_P (TREE_TYPE (fntype)); TREE_THIS_VOLATILE (DECL_RESULT (decl1)) = CP_TYPE_VOLATILE_P (TREE_TYPE (fntype)); } if (TYPE_LANG_SPECIFIC (TREE_TYPE (fntype)) && CLASSTYPE_ABSTRACT_VIRTUALS (TREE_TYPE (fntype))) abstract_virtuals_error (decl1, TREE_TYPE (fntype)); } /* Effective C++ rule 15. See also c_expand_return. */ if (warn_ecpp && DECL_NAME (decl1) == ansi_opname[(int) MODIFY_EXPR] && TREE_CODE (TREE_TYPE (fntype)) == VOID_TYPE) cp_warning ("`operator=' should return a reference to `*this'"); /* Make the init_value nonzero so pushdecl knows this is not tentative. error_mark_node is replaced below (in poplevel) with the BLOCK. */ DECL_INITIAL (decl1) = error_mark_node; #ifdef SET_DEFAULT_DECL_ATTRIBUTES SET_DEFAULT_DECL_ATTRIBUTES (decl1, attrs); #endif /* This function exists in static storage. (This does not mean `static' in the C sense!) */ TREE_STATIC (decl1) = 1; /* We must call push_template_decl after current_class_type is set up. (If we are processing inline definitions after exiting a class scope, current_class_type will be NULL_TREE until set above by push_nested_class.) */ if (processing_template_decl) decl1 = push_template_decl (decl1); /* Record the decl so that the function name is defined. If we already have a decl for this name, and it is a FUNCTION_DECL, use the old decl. */ if (!processing_template_decl && pre_parsed_p == 0) { /* A specialization is not used to guide overload resolution. */ if ((flag_guiding_decls || !DECL_TEMPLATE_SPECIALIZATION (decl1)) && ! DECL_FUNCTION_MEMBER_P (decl1)) decl1 = pushdecl (decl1); else { /* We need to set the DECL_CONTEXT. */ if (!DECL_CONTEXT (decl1) && DECL_TEMPLATE_INFO (decl1)) DECL_CONTEXT (decl1) = DECL_CONTEXT (DECL_TI_TEMPLATE (decl1)); /* And make sure we have enough default args. */ check_default_args (decl1); } DECL_MAIN_VARIANT (decl1) = decl1; fntype = TREE_TYPE (decl1); } current_function_decl = decl1; if (DECL_INTERFACE_KNOWN (decl1)) { tree ctx = hack_decl_function_context (decl1); if (DECL_NOT_REALLY_EXTERN (decl1)) DECL_EXTERNAL (decl1) = 0; if (ctx != NULL_TREE && DECL_THIS_INLINE (ctx) && TREE_PUBLIC (ctx)) /* This is a function in a local class in an extern inline function. */ comdat_linkage (decl1); } /* If this function belongs to an interface, it is public. If it belongs to someone else's interface, it is also external. This only affects inlines and template instantiations. */ else if (interface_unknown == 0 && (! DECL_TEMPLATE_INSTANTIATION (decl1) || flag_alt_external_templates)) { if (DECL_THIS_INLINE (decl1) || DECL_TEMPLATE_INSTANTIATION (decl1) || processing_template_decl) { DECL_EXTERNAL (decl1) = (interface_only || (DECL_THIS_INLINE (decl1) && ! flag_implement_inlines && !DECL_VINDEX (decl1))); /* For WIN32 we also want to put these in linkonce sections. */ maybe_make_one_only (decl1); } else DECL_EXTERNAL (decl1) = 0; DECL_NOT_REALLY_EXTERN (decl1) = 0; DECL_INTERFACE_KNOWN (decl1) = 1; } else if (interface_unknown && interface_only && (! DECL_TEMPLATE_INSTANTIATION (decl1) || flag_alt_external_templates)) { /* If MULTIPLE_SYMBOL_SPACES is defined and we saw a #pragma interface, we will have interface_only set but not interface_known. In that case, we don't want to use the normal heuristics because someone will supply a #pragma implementation elsewhere, and deducing it here would produce a conflict. */ comdat_linkage (decl1); DECL_EXTERNAL (decl1) = 0; DECL_INTERFACE_KNOWN (decl1) = 1; DECL_DEFER_OUTPUT (decl1) = 1; } else { /* This is a definition, not a reference. So clear DECL_EXTERNAL. */ DECL_EXTERNAL (decl1) = 0; if ((DECL_THIS_INLINE (decl1) || DECL_TEMPLATE_INSTANTIATION (decl1)) && ! DECL_INTERFACE_KNOWN (decl1) /* Don't try to defer nested functions for now. */ && ! hack_decl_function_context (decl1)) DECL_DEFER_OUTPUT (decl1) = 1; else DECL_INTERFACE_KNOWN (decl1) = 1; } if (ctype != NULL_TREE && DECL_STATIC_FUNCTION_P (decl1)) { if (TREE_CODE (fntype) == METHOD_TYPE) TREE_TYPE (decl1) = fntype = build_function_type (TREE_TYPE (fntype), TREE_CHAIN (TYPE_ARG_TYPES (fntype))); current_function_parms = TREE_CHAIN (current_function_parms); DECL_ARGUMENTS (decl1) = current_function_parms; ctype = NULL_TREE; } restype = TREE_TYPE (fntype); if (ctype) { /* If we're compiling a friend function, neither of the variables current_class_ptr nor current_class_type will have values. */ if (! doing_friend) { /* We know that this was set up by `grokclassfn'. We do not wait until `store_parm_decls', since evil parse errors may never get us to that point. Here we keep the consistency between `current_class_type' and `current_class_ptr'. */ tree t = current_function_parms; my_friendly_assert (t != NULL_TREE && TREE_CODE (t) == PARM_DECL, 162); if (TREE_CODE (TREE_TYPE (t)) == POINTER_TYPE) { int i; if (! hack_decl_function_context (decl1)) temporary_allocation (); i = suspend_momentary (); /* Normally, build_indirect_ref returns current_class_ref whenever current_class_ptr is dereferenced. This time, however, we want it to *create* current_class_ref, so we temporarily clear current_class_ptr to fool it. */ current_class_ptr = NULL_TREE; current_class_ref = build_indirect_ref (t, NULL_PTR); current_class_ptr = t; resume_momentary (i); if (! hack_decl_function_context (decl1)) end_temporary_allocation (); } else /* We're having a signature pointer here. */ current_class_ref = current_class_ptr = t; } } else current_class_ptr = current_class_ref = NULL_TREE; pushlevel (0); current_binding_level->parm_flag = 1; GNU_xref_function (decl1, current_function_parms); if (attrs) cplus_decl_attributes (decl1, NULL_TREE, attrs); make_function_rtl (decl1); /* Promote the value to int before returning it. */ if (C_PROMOTING_INTEGER_TYPE_P (restype)) restype = type_promotes_to (restype); /* If this fcn was already referenced via a block-scope `extern' decl (or an implicit decl), propagate certain information about the usage. */ if (TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (decl1))) TREE_ADDRESSABLE (decl1) = 1; if (DECL_RESULT (decl1) == NULL_TREE) { DECL_RESULT (decl1) = build_decl (RESULT_DECL, 0, TYPE_MAIN_VARIANT (restype)); TREE_READONLY (DECL_RESULT (decl1)) = CP_TYPE_CONST_P (restype); TREE_THIS_VOLATILE (DECL_RESULT (decl1)) = CP_TYPE_VOLATILE_P (restype); } /* Allocate further tree nodes temporarily during compilation of this function only. Tiemann moved up here from bottom of fn. */ /* If this is a nested function, then we must continue to allocate RTL on the permanent obstack in case we need to inline it later. */ if (! hack_decl_function_context (decl1)) temporary_allocation (); if (processing_template_decl) { ++minimal_parse_mode; last_tree = DECL_SAVED_TREE (decl1) = build_nt (EXPR_STMT, void_zero_node); } ++function_depth; if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (decl1)) && DECL_LANGUAGE (decl1) == lang_cplusplus) { dtor_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); ctor_label = NULL_TREE; } else { dtor_label = NULL_TREE; if (DECL_CONSTRUCTOR_P (decl1)) ctor_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); } return 1; } /* Called after store_parm_decls for a function-try-block. We need to update last_parm_cleanup_insn so that the base initializers for a constructor are run within this block, not before it. */ void expand_start_early_try_stmts () { expand_start_try_stmts (); last_parm_cleanup_insn = get_last_insn (); } /* Store the parameter declarations into the current function declaration. This is called after parsing the parameter declarations, before digesting the body of the function. Also install to binding contour return value identifier, if any. */ void store_parm_decls () { register tree fndecl = current_function_decl; register tree parm; int parms_have_cleanups = 0; tree cleanups = NULL_TREE; /* This is either a chain of PARM_DECLs (when a prototype is used). */ tree specparms = current_function_parms; /* This is a list of types declared among parms in a prototype. */ tree parmtags = current_function_parm_tags; /* This is a chain of any other decls that came in among the parm declarations. If a parm is declared with enum {foo, bar} x; then CONST_DECLs for foo and bar are put here. */ tree nonparms = NULL_TREE; if (toplevel_bindings_p ()) fatal ("parse errors have confused me too much"); /* Initialize RTL machinery. */ init_function_start (fndecl, input_filename, lineno); /* Create a binding level for the parms. */ expand_start_bindings (0); if (specparms != NULL_TREE) { /* This case is when the function was defined with an ANSI prototype. The parms already have decls, so we need not do anything here except record them as in effect and complain if any redundant old-style parm decls were written. */ register tree next; /* Must clear this because it might contain TYPE_DECLs declared at class level. */ storedecls (NULL_TREE); for (parm = nreverse (specparms); parm; parm = next) { next = TREE_CHAIN (parm); if (TREE_CODE (parm) == PARM_DECL) { tree cleanup; if (DECL_NAME (parm) == NULL_TREE) { pushdecl (parm); } else if (TREE_CODE (TREE_TYPE (parm)) == VOID_TYPE) cp_error ("parameter `%D' declared void", parm); else { /* Now fill in DECL_REFERENCE_SLOT for any of the parm decls. A parameter is assumed not to have any side effects. If this should change for any reason, then this will have to wrap the bashed reference type in a save_expr. Also, if the parameter type is declared to be an X and there is an X(X&) constructor, we cannot lay it into the stack (any more), so we make this parameter look like it is really of reference type. Functions which pass parameters to this function will know to create a temporary in their frame, and pass a reference to that. */ if (TREE_CODE (TREE_TYPE (parm)) == REFERENCE_TYPE && TYPE_SIZE (TREE_TYPE (TREE_TYPE (parm)))) SET_DECL_REFERENCE_SLOT (parm, convert_from_reference (parm)); pushdecl (parm); } if (! processing_template_decl && (cleanup = maybe_build_cleanup (parm), cleanup)) { expand_decl (parm); parms_have_cleanups = 1; /* Keep track of the cleanups. */ cleanups = tree_cons (parm, cleanup, cleanups); } } else { /* If we find an enum constant or a type tag, put it aside for the moment. */ TREE_CHAIN (parm) = NULL_TREE; nonparms = chainon (nonparms, parm); } } /* Get the decls in their original chain order and record in the function. This is all and only the PARM_DECLs that were pushed into scope by the loop above. */ DECL_ARGUMENTS (fndecl) = getdecls (); storetags (chainon (parmtags, gettags ())); } else DECL_ARGUMENTS (fndecl) = NULL_TREE; /* Now store the final chain of decls for the arguments as the decl-chain of the current lexical scope. Put the enumerators in as well, at the front so that DECL_ARGUMENTS is not modified. */ storedecls (chainon (nonparms, DECL_ARGUMENTS (fndecl))); /* Declare __FUNCTION__ and __PRETTY_FUNCTION__ for this function. */ declare_function_name (); /* Initialize the RTL code for the function. */ DECL_SAVED_INSNS (fndecl) = NULL_RTX; if (! processing_template_decl) expand_function_start (fndecl, parms_have_cleanups); current_function_parms_stored = 1; /* If this function is `main', emit a call to `__main' to run global initializers, etc. */ if (DECL_MAIN_P (fndecl)) expand_main_function (); /* Now that we have initialized the parms, we can start their cleanups. We cannot do this before, since expand_decl_cleanup should not be called before the parm can be used. */ if (cleanups && ! processing_template_decl) { for (cleanups = nreverse (cleanups); cleanups; cleanups = TREE_CHAIN (cleanups)) { if (! expand_decl_cleanup (TREE_PURPOSE (cleanups), TREE_VALUE (cleanups))) cp_error ("parser lost in parsing declaration of `%D'", TREE_PURPOSE (cleanups)); } } /* Create a binding contour which can be used to catch cleanup-generated temporaries. Also, if the return value needs or has initialization, deal with that now. */ if (parms_have_cleanups) { pushlevel (0); expand_start_bindings (0); } if (! processing_template_decl && flag_exceptions) { /* Do the starting of the exception specifications, if we have any. */ if (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (current_function_decl))) expand_start_eh_spec (); } last_parm_cleanup_insn = get_last_insn (); last_dtor_insn = get_last_insn (); } /* Bind a name and initialization to the return value of the current function. */ void store_return_init (return_id, init) tree return_id, init; { tree decl = DECL_RESULT (current_function_decl); if (pedantic) /* Give this error as many times as there are occurrences, so that users can use Emacs compilation buffers to find and fix all such places. */ pedwarn ("ANSI C++ does not permit named return values"); if (return_id != NULL_TREE) { if (DECL_NAME (decl) == NULL_TREE) { DECL_NAME (decl) = return_id; DECL_ASSEMBLER_NAME (decl) = return_id; } else cp_error ("return identifier `%D' already in place", decl); } /* Can't let this happen for constructors. */ if (DECL_CONSTRUCTOR_P (current_function_decl)) { error ("can't redefine default return value for constructors"); return; } /* If we have a named return value, put that in our scope as well. */ if (DECL_NAME (decl) != NULL_TREE) { /* If this named return value comes in a register, put it in a pseudo-register. */ if (DECL_REGISTER (decl)) { original_result_rtx = DECL_RTL (decl); DECL_RTL (decl) = gen_reg_rtx (DECL_MODE (decl)); } /* Let `cp_finish_decl' know that this initializer is ok. */ DECL_INITIAL (decl) = init; pushdecl (decl); if (minimal_parse_mode) add_tree (build_min_nt (RETURN_INIT, return_id, copy_to_permanent (init))); else cp_finish_decl (decl, init, NULL_TREE, 0, 0); } } +/* Emit implicit code for a destructor. This is a subroutine of + finish_function. */ + +static void +finish_dtor () +{ + tree binfo = TYPE_BINFO (current_class_type); + tree cond = integer_one_node; + tree exprstmt; + tree in_charge_node = lookup_name (in_charge_identifier, 0); + tree virtual_size; + int ok_to_optimize_dtor = 0; + int empty_dtor = get_last_insn () == last_dtor_insn; + rtx insns, last_parm_insn; + + if (current_function_assigns_this) + cond = build (NE_EXPR, boolean_type_node, + current_class_ptr, integer_zero_node); + else + { + int n_baseclasses = CLASSTYPE_N_BASECLASSES (current_class_type); + + /* If this destructor is empty, then we don't need to check + whether `this' is NULL in some cases. */ + if ((flag_this_is_variable & 1) == 0) + ok_to_optimize_dtor = 1; + else if (empty_dtor) + ok_to_optimize_dtor + = (n_baseclasses == 0 + || (n_baseclasses == 1 + && TYPE_HAS_DESTRUCTOR (TYPE_BINFO_BASETYPE (current_class_type, 0)))); + } + + /* If this has a vlist1 parameter, allocate the corresponding vlist + parameter. */ + if (DECL_DESTRUCTOR_FOR_PVBASE_P (current_function_decl)) + { + /* _Vlist __vlist; */ + tree vlist; + + mark_all_temps_used(); + vlist = pushdecl (build_decl (VAR_DECL, vlist_identifier, + vlist_type_node)); + TREE_USED (vlist) = 1; + DECL_ARTIFICIAL (vlist) = 1; + expand_decl (vlist); + expand_decl_init (vlist); + } + + /* These initializations might go inline. Protect + the binding level of the parms. */ + pushlevel (0); + expand_start_bindings (0); + + if (current_function_assigns_this) + { + current_function_assigns_this = 0; + current_function_just_assigned_this = 0; + } + + /* Generate the code to call destructor on base class. + If this destructor belongs to a class with virtual + functions, then set the virtual function table + pointer to represent the type of our base class. */ + + /* This side-effect makes call to `build_delete' generate the + code we have to have at the end of this destructor. + `build_delete' will set the flag again. */ + TYPE_HAS_DESTRUCTOR (current_class_type) = 0; + + /* These are two cases where we cannot delegate deletion. */ + if (TYPE_USES_VIRTUAL_BASECLASSES (current_class_type) + || TYPE_GETS_REG_DELETE (current_class_type)) + exprstmt = build_delete + (current_class_type, current_class_ref, integer_zero_node, + LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR|LOOKUP_NORMAL, 0); + else + exprstmt = build_delete + (current_class_type, current_class_ref, in_charge_node, + LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR|LOOKUP_NORMAL, 0); + + /* If we did not assign to this, then `this' is non-zero at + the end of a destructor. As a special optimization, don't + emit test if this is an empty destructor. If it does nothing, + it does nothing. If it calls a base destructor, the base + destructor will perform the test. */ + + if (exprstmt != error_mark_node + && (TREE_CODE (exprstmt) != NOP_EXPR + || TREE_OPERAND (exprstmt, 0) != integer_zero_node + || TYPE_USES_VIRTUAL_BASECLASSES (current_class_type))) + { + expand_label (dtor_label); + if (cond != integer_one_node) + expand_start_cond (cond, 0); + if (exprstmt != void_zero_node) + /* Don't call `expand_expr_stmt' if we're not going to do + anything, since -Wall will give a diagnostic. */ + expand_expr_stmt (exprstmt); + + /* Run destructor on all virtual baseclasses. */ + if (TYPE_USES_VIRTUAL_BASECLASSES (current_class_type)) + { + tree vbases = nreverse + (copy_list (CLASSTYPE_VBASECLASSES (current_class_type))); + expand_start_cond (build (BIT_AND_EXPR, integer_type_node, + in_charge_node, integer_two_node), 0); + while (vbases) + { + if (TYPE_NEEDS_DESTRUCTOR (BINFO_TYPE (vbases))) + { + tree vb = get_vbase + (BINFO_TYPE (vbases), + TYPE_BINFO (current_class_type)); + + expand_expr_stmt + (build_base_dtor_call (current_class_ref, + vb, integer_zero_node)); + } + vbases = TREE_CHAIN (vbases); + } + expand_end_cond (); + } + + do_pending_stack_adjust (); + if (cond != integer_one_node) + expand_end_cond (); + } + + virtual_size = c_sizeof (current_class_type); + + /* At the end, call delete if that's what's requested. */ + + /* FDIS sez: At the point of definition of a virtual destructor + (including an implicit definition), non-placement operator + delete shall be looked up in the scope of the destructor's + class and if found shall be accessible and unambiguous. + + This is somewhat unclear, but I take it to mean that if the + class only defines placement deletes we don't do anything here. + So we pass LOOKUP_SPECULATIVELY; delete_sanity will complain + for us if they ever try to delete one of these. */ + + if (TYPE_GETS_REG_DELETE (current_class_type) + || TYPE_USES_VIRTUAL_BASECLASSES (current_class_type)) + exprstmt = build_op_delete_call + (DELETE_EXPR, current_class_ptr, virtual_size, + LOOKUP_NORMAL | LOOKUP_SPECULATIVELY, NULL_TREE); + else + exprstmt = NULL_TREE; + + if (exprstmt) + { + cond = build (BIT_AND_EXPR, integer_type_node, + in_charge_node, integer_one_node); + expand_start_cond (cond, 0); + expand_expr_stmt (exprstmt); + expand_end_cond (); + } + + /* End of destructor. */ + expand_end_bindings (NULL_TREE, getdecls () != NULL_TREE, 0); + poplevel (getdecls () != NULL_TREE, 0, 0); + + /* Back to the top of destructor. */ + /* Don't execute destructor code if `this' is NULL. */ + + start_sequence (); + + /* If we need thunk-style vlists, initialize them if the caller did + not pass them. This requires a new temporary. The generated code + looks like + if (!(__in_charge & 4)) + __vlist = __vl. + sizeof(__vl.); + else + __vlist = __vlist1; + */ + if (TYPE_USES_PVBASES (current_class_type)) + { + tree vlist = lookup_name (vlist_identifier, 0); + tree vlist1 = lookup_name (get_identifier (VLIST1_NAME), 0); + cond = build (BIT_AND_EXPR, integer_type_node, + in_charge_node, build_int_2 (4, 0)); + cond = build1 (TRUTH_NOT_EXPR, boolean_type_node, cond); + expand_start_cond (cond, 0); + init_vlist (current_class_type); + expand_start_else (); + expand_expr_stmt (build_modify_expr (vlist, NOP_EXPR, vlist1)); + expand_end_cond (); + } + + /* If the dtor is empty, and we know there is not possible way we + could use any vtable entries, before they are possibly set by + a base class dtor, we don't have to setup the vtables, as we + know that any base class dtoring will set up any vtables it + needs. We avoid MI, because one base class dtor can do a + virtual dispatch to an overridden function that would need to + have a non-related vtable set up, we cannot avoid setting up + vtables in that case. We could change this to see if there is + just one vtable. */ + if (! empty_dtor || TYPE_USES_COMPLEX_INHERITANCE (current_class_type)) + { + /* Make all virtual function table pointers in non-virtual base + classes point to CURRENT_CLASS_TYPE's virtual function + tables. */ + expand_direct_vtbls_init (binfo, binfo, 1, 0, current_class_ptr); + + if (TYPE_USES_VIRTUAL_BASECLASSES (current_class_type)) + expand_indirect_vtbls_init (binfo, current_class_ref, current_class_ptr); + } + + if (! ok_to_optimize_dtor) + { + cond = build_binary_op (NE_EXPR, + current_class_ptr, integer_zero_node); + expand_start_cond (cond, 0); + } + + insns = get_insns (); + end_sequence (); + + last_parm_insn = get_first_nonparm_insn (); + if (last_parm_insn == NULL_RTX) + last_parm_insn = get_last_insn (); + else + last_parm_insn = previous_insn (last_parm_insn); + + emit_insns_after (insns, last_parm_insn); + + if (! ok_to_optimize_dtor) + expand_end_cond (); +} + +/* Emit implicit code for a constructor. This is a subroutine of + finish_function. CALL_POPLEVEL is the same variable in + finish_function. */ + +static void +finish_ctor (call_poplevel) + int call_poplevel; +{ + register tree fndecl = current_function_decl; + tree cond = NULL_TREE, thenclause = NULL_TREE; + rtx insns; + tree decls; + + /* Allow constructor for a type to get a new instance of the object + using `build_new'. */ + tree abstract_virtuals = CLASSTYPE_ABSTRACT_VIRTUALS (current_class_type); + CLASSTYPE_ABSTRACT_VIRTUALS (current_class_type) = NULL_TREE; + + if (flag_this_is_variable > 0) + { + cond = build_binary_op (EQ_EXPR, current_class_ptr, integer_zero_node); + thenclause = + build_modify_expr (current_class_ptr, NOP_EXPR, + build_new (NULL_TREE, current_class_type, + void_type_node, 0)); + } + + CLASSTYPE_ABSTRACT_VIRTUALS (current_class_type) = abstract_virtuals; + + start_sequence (); + + if (flag_this_is_variable > 0) + { + expand_start_cond (cond, 0); + expand_expr_stmt (thenclause); + expand_end_cond (); + } + + /* Emit insns from `emit_base_init' which sets up virtual + function table pointer(s). */ + if (base_init_expr) + { + expand_expr_stmt (base_init_expr); + base_init_expr = NULL_TREE; + } + + insns = get_insns (); + end_sequence (); + + /* This is where the body of the constructor begins. */ + + emit_insns_after (insns, last_parm_cleanup_insn); + + end_protect_partials (); + + /* This is where the body of the constructor ends. */ + expand_label (ctor_label); + ctor_label = NULL_TREE; + + if (call_poplevel) + { + decls = getdecls (); + expand_end_bindings (decls, decls != NULL_TREE, 0); + poplevel (decls != NULL_TREE, 1, 0); + } + + /* c_expand_return knows to return 'this' from a constructor. */ + c_expand_return (NULL_TREE); + + current_function_assigns_this = 0; + current_function_just_assigned_this = 0; +} + + /* Finish up a function declaration and compile that function all the way to assembler language output. The free the storage for the function definition. This is called after parsing the body of the function definition. LINENO is the current line number. FLAGS is a bitwise or of the following values: 1 - CALL_POPLEVEL An extra call to poplevel (and expand_end_bindings) must be made to take care of the binding contour for the base initializers. This is only relevant for constructors. 2 - INCLASS_INLINE We just finished processing the body of an in-class inline function definition. (This processing will have taken place after the class definition is complete.) NESTED is nonzero if we were in the middle of compiling another function when we started on this one. */ void finish_function (lineno, flags, nested) int lineno; int flags; int nested; { register tree fndecl = current_function_decl; tree fntype, ctype = NULL_TREE; - rtx last_parm_insn, insns; /* Label to use if this function is supposed to return a value. */ tree no_return_label = NULL_TREE; tree decls = NULL_TREE; int call_poplevel = (flags & 1) != 0; int inclass_inline = (flags & 2) != 0; int in_template; /* When we get some parse errors, we can end up without a current_function_decl, so cope. */ if (fndecl == NULL_TREE) return; if (function_depth > 1) nested = 1; fntype = TREE_TYPE (fndecl); /* TREE_READONLY (fndecl) = 1; This caused &foo to be of type ptr-to-const-function which then got a warning when stored in a ptr-to-function variable. */ /* This happens on strange parse errors. */ if (! current_function_parms_stored) { call_poplevel = 0; store_parm_decls (); } if (processing_template_decl) { if (DECL_CONSTRUCTOR_P (fndecl) && call_poplevel) { decls = getdecls (); expand_end_bindings (decls, decls != NULL_TREE, 0); poplevel (decls != NULL_TREE, 0, 0); } } else { if (write_symbols != NO_DEBUG /*&& TREE_CODE (fntype) != METHOD_TYPE*/) { tree ttype = target_type (fntype); tree parmdecl; if (IS_AGGR_TYPE (ttype)) /* Let debugger know it should output info for this type. */ note_debug_info_needed (ttype); for (parmdecl = DECL_ARGUMENTS (fndecl); parmdecl; parmdecl = TREE_CHAIN (parmdecl)) { ttype = target_type (TREE_TYPE (parmdecl)); if (IS_AGGR_TYPE (ttype)) /* Let debugger know it should output info for this type. */ note_debug_info_needed (ttype); } } /* Clean house because we will need to reorder insns here. */ do_pending_stack_adjust (); if (dtor_label) - { - tree binfo = TYPE_BINFO (current_class_type); - tree cond = integer_one_node; - tree exprstmt; - tree in_charge_node = lookup_name (in_charge_identifier, 0); - tree virtual_size; - int ok_to_optimize_dtor = 0; - int empty_dtor = get_last_insn () == last_dtor_insn; - - if (current_function_assigns_this) - cond = build (NE_EXPR, boolean_type_node, - current_class_ptr, integer_zero_node); - else - { - int n_baseclasses = CLASSTYPE_N_BASECLASSES (current_class_type); - - /* If this destructor is empty, then we don't need to check - whether `this' is NULL in some cases. */ - if ((flag_this_is_variable & 1) == 0) - ok_to_optimize_dtor = 1; - else if (empty_dtor) - ok_to_optimize_dtor - = (n_baseclasses == 0 - || (n_baseclasses == 1 - && TYPE_HAS_DESTRUCTOR (TYPE_BINFO_BASETYPE (current_class_type, 0)))); - } - - /* These initializations might go inline. Protect - the binding level of the parms. */ - pushlevel (0); - expand_start_bindings (0); - - if (current_function_assigns_this) - { - current_function_assigns_this = 0; - current_function_just_assigned_this = 0; - } - - /* Generate the code to call destructor on base class. - If this destructor belongs to a class with virtual - functions, then set the virtual function table - pointer to represent the type of our base class. */ - - /* This side-effect makes call to `build_delete' generate the - code we have to have at the end of this destructor. - `build_delete' will set the flag again. */ - TYPE_HAS_DESTRUCTOR (current_class_type) = 0; - - /* These are two cases where we cannot delegate deletion. */ - if (TYPE_USES_VIRTUAL_BASECLASSES (current_class_type) - || TYPE_GETS_REG_DELETE (current_class_type)) - exprstmt = build_delete (current_class_type, current_class_ref, integer_zero_node, - LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR|LOOKUP_NORMAL, 0); - else - exprstmt = build_delete (current_class_type, current_class_ref, in_charge_node, - LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR|LOOKUP_NORMAL, 0); - - /* If we did not assign to this, then `this' is non-zero at - the end of a destructor. As a special optimization, don't - emit test if this is an empty destructor. If it does nothing, - it does nothing. If it calls a base destructor, the base - destructor will perform the test. */ - - if (exprstmt != error_mark_node - && (TREE_CODE (exprstmt) != NOP_EXPR - || TREE_OPERAND (exprstmt, 0) != integer_zero_node - || TYPE_USES_VIRTUAL_BASECLASSES (current_class_type))) - { - expand_label (dtor_label); - if (cond != integer_one_node) - expand_start_cond (cond, 0); - if (exprstmt != void_zero_node) - /* Don't call `expand_expr_stmt' if we're not going to do - anything, since -Wall will give a diagnostic. */ - expand_expr_stmt (exprstmt); - - /* Run destructor on all virtual baseclasses. */ - if (TYPE_USES_VIRTUAL_BASECLASSES (current_class_type)) - { - tree vbases = nreverse (copy_list (CLASSTYPE_VBASECLASSES (current_class_type))); - expand_start_cond (build (BIT_AND_EXPR, integer_type_node, - in_charge_node, integer_two_node), 0); - while (vbases) - { - if (TYPE_NEEDS_DESTRUCTOR (BINFO_TYPE (vbases))) - { - tree vb = get_vbase - (BINFO_TYPE (vbases), - TYPE_BINFO (current_class_type)); - expand_expr_stmt - (build_scoped_method_call - (current_class_ref, vb, dtor_identifier, - build_expr_list (NULL_TREE, integer_zero_node))); - } - vbases = TREE_CHAIN (vbases); - } - expand_end_cond (); - } - - do_pending_stack_adjust (); - if (cond != integer_one_node) - expand_end_cond (); - } - - virtual_size = c_sizeof (current_class_type); - - /* At the end, call delete if that's what's requested. */ - - /* FDIS sez: At the point of definition of a virtual destructor - (including an implicit definition), non-placement operator - delete shall be looked up in the scope of the destructor's - class and if found shall be accessible and unambiguous. - - This is somewhat unclear, but I take it to mean that if the - class only defines placement deletes we don't do anything here. - So we pass LOOKUP_SPECULATIVELY; delete_sanity will complain - for us if they ever try to delete one of these. */ - - if (TYPE_GETS_REG_DELETE (current_class_type) - || TYPE_USES_VIRTUAL_BASECLASSES (current_class_type)) - exprstmt = build_op_delete_call - (DELETE_EXPR, current_class_ptr, virtual_size, - LOOKUP_NORMAL | LOOKUP_SPECULATIVELY, NULL_TREE); - else - exprstmt = NULL_TREE; - - if (exprstmt) - { - cond = build (BIT_AND_EXPR, integer_type_node, - in_charge_node, integer_one_node); - expand_start_cond (cond, 0); - expand_expr_stmt (exprstmt); - expand_end_cond (); - } - - /* End of destructor. */ - expand_end_bindings (NULL_TREE, getdecls () != NULL_TREE, 0); - poplevel (getdecls () != NULL_TREE, 0, 0); - - /* Back to the top of destructor. */ - /* Don't execute destructor code if `this' is NULL. */ - - start_sequence (); - - /* If the dtor is empty, and we know there is not possible way we - could use any vtable entries, before they are possibly set by - a base class dtor, we don't have to setup the vtables, as we - know that any base class dtoring will set up any vtables it - needs. We avoid MI, because one base class dtor can do a - virtual dispatch to an overridden function that would need to - have a non-related vtable set up, we cannot avoid setting up - vtables in that case. We could change this to see if there is - just one vtable. */ - if (! empty_dtor || TYPE_USES_COMPLEX_INHERITANCE (current_class_type)) - { - /* Make all virtual function table pointers in non-virtual base - classes point to CURRENT_CLASS_TYPE's virtual function - tables. */ - expand_direct_vtbls_init (binfo, binfo, 1, 0, current_class_ptr); - - if (TYPE_USES_VIRTUAL_BASECLASSES (current_class_type)) - expand_indirect_vtbls_init (binfo, current_class_ref, current_class_ptr); - } - - if (! ok_to_optimize_dtor) - { - cond = build_binary_op (NE_EXPR, - current_class_ptr, integer_zero_node); - expand_start_cond (cond, 0); - } - - insns = get_insns (); - end_sequence (); - - last_parm_insn = get_first_nonparm_insn (); - if (last_parm_insn == NULL_RTX) - last_parm_insn = get_last_insn (); - else - last_parm_insn = previous_insn (last_parm_insn); - - emit_insns_after (insns, last_parm_insn); - - if (! ok_to_optimize_dtor) - expand_end_cond (); - } + finish_dtor (); else if (current_function_assigns_this) { /* Does not need to call emit_base_init, because that is done (if needed) just after assignment to this is seen. */ if (DECL_CONSTRUCTOR_P (current_function_decl)) { end_protect_partials (); expand_label (ctor_label); ctor_label = NULL_TREE; if (call_poplevel) { decls = getdecls (); expand_end_bindings (decls, decls != NULL_TREE, 0); poplevel (decls != NULL_TREE, 0, 0); } /* c_expand_return knows to return 'this' from a constructor. */ c_expand_return (NULL_TREE); } else if (TREE_CODE (TREE_TYPE (DECL_RESULT (current_function_decl))) != VOID_TYPE && return_label != NULL_RTX) no_return_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); current_function_assigns_this = 0; current_function_just_assigned_this = 0; base_init_expr = NULL_TREE; } - else if (DECL_CONSTRUCTOR_P (fndecl)) - { - tree cond = NULL_TREE, thenclause = NULL_TREE; - /* Allow constructor for a type to get a new instance of the object - using `build_new'. */ - tree abstract_virtuals = CLASSTYPE_ABSTRACT_VIRTUALS (current_class_type); - CLASSTYPE_ABSTRACT_VIRTUALS (current_class_type) = NULL_TREE; - - if (flag_this_is_variable > 0) - { - cond = build_binary_op (EQ_EXPR, - current_class_ptr, integer_zero_node); - thenclause = build_modify_expr (current_class_ptr, NOP_EXPR, - build_new (NULL_TREE, current_class_type, void_type_node, 0)); - } - - CLASSTYPE_ABSTRACT_VIRTUALS (current_class_type) = abstract_virtuals; - - start_sequence (); - - if (flag_this_is_variable > 0) - { - expand_start_cond (cond, 0); - expand_expr_stmt (thenclause); - expand_end_cond (); - } - - /* Emit insns from `emit_base_init' which sets up virtual - function table pointer(s). */ - if (base_init_expr) - { - expand_expr_stmt (base_init_expr); - base_init_expr = NULL_TREE; - } - - insns = get_insns (); - end_sequence (); - - /* This is where the body of the constructor begins. */ - - emit_insns_after (insns, last_parm_cleanup_insn); - - end_protect_partials (); - - /* This is where the body of the constructor ends. */ - expand_label (ctor_label); - ctor_label = NULL_TREE; - - if (call_poplevel) - { - decls = getdecls (); - expand_end_bindings (decls, decls != NULL_TREE, 0); - poplevel (decls != NULL_TREE, 1, 0); - } - - /* c_expand_return knows to return 'this' from a constructor. */ - c_expand_return (NULL_TREE); - - current_function_assigns_this = 0; - current_function_just_assigned_this = 0; - } + else if (DECL_CONSTRUCTOR_P (fndecl) + && !DECL_VLIST_CTOR_WRAPPER_P (fndecl)) + finish_ctor (call_poplevel); else if (DECL_MAIN_P (fndecl)) { /* Make it so that `main' always returns 0 by default. */ #ifdef VMS c_expand_return (integer_one_node); #else c_expand_return (integer_zero_node); #endif } else if (return_label != NULL_RTX && current_function_return_value == NULL_TREE && ! DECL_NAME (DECL_RESULT (current_function_decl))) no_return_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); if (flag_exceptions) expand_exception_blocks (); /* If this function is supposed to return a value, ensure that we do not fall into the cleanups by mistake. The end of our function will look like this: user code (may have return stmt somewhere) goto no_return_label cleanup_label: cleanups goto return_label no_return_label: NOTE_INSN_FUNCTION_END return_label: things for return If the user omits a return stmt in the USER CODE section, we will have a control path which reaches NOTE_INSN_FUNCTION_END. Otherwise, we won't. */ if (no_return_label) { DECL_CONTEXT (no_return_label) = fndecl; DECL_INITIAL (no_return_label) = error_mark_node; DECL_SOURCE_FILE (no_return_label) = input_filename; DECL_SOURCE_LINE (no_return_label) = lineno; expand_goto (no_return_label); } if (cleanup_label) { /* Remove the binding contour which is used to catch cleanup-generated temporaries. */ expand_end_bindings (0, 0, 0); poplevel (0, 0, 0); /* Emit label at beginning of cleanup code for parameters. */ emit_label (cleanup_label); } /* Get return value into register if that's where it's supposed to be. */ if (original_result_rtx) fixup_result_decl (DECL_RESULT (fndecl), original_result_rtx); /* Finish building code that will trigger warnings if users forget to make their functions return values. */ if (no_return_label || cleanup_label) emit_jump (return_label); if (no_return_label) { /* We don't need to call `expand_*_return' here because we don't need any cleanups here--this path of code is only for error checking purposes. */ expand_label (no_return_label); } /* Generate rtl for function exit. */ expand_function_end (input_filename, lineno, 1); } /* If we're processing a template, squirrel away the definition until we do an instantiation. */ if (processing_template_decl) { --minimal_parse_mode; DECL_SAVED_TREE (fndecl) = TREE_CHAIN (DECL_SAVED_TREE (fndecl)); /* We have to save this value here in case maybe_end_member_template_processing decides to pop all the template parameters. */ in_template = 1; } else in_template = 0; /* This must come after expand_function_end because cleanups might have declarations (from inline functions) that need to go into this function's blocks. */ if (current_binding_level->parm_flag != 1) my_friendly_abort (122); poplevel (1, 0, 1); /* If this is a in-class inline definition, we may have to pop the bindings for the template parameters that we added in maybe_begin_member_template_processing when start_function was called. */ if (inclass_inline) maybe_end_member_template_processing (); /* Reset scope for C++: if we were in the scope of a class, then when we finish this function, we are not longer so. This cannot be done until we know for sure that no more class members will ever be referenced in this function (i.e., calls to destructors). */ if (current_class_name) { ctype = current_class_type; pop_nested_class (); } /* Must mark the RESULT_DECL as being in this function. */ DECL_CONTEXT (DECL_RESULT (fndecl)) = fndecl; /* Set the BLOCK_SUPERCONTEXT of the outermost function scope to point to the FUNCTION_DECL node itself. */ BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl; if (!in_template) { int saved_flag_keep_inline_functions = flag_keep_inline_functions; /* So we can tell if jump_optimize sets it to 1. */ can_reach_end = 0; if (DECL_CONTEXT (fndecl) != NULL_TREE && hack_decl_function_context (fndecl)) /* Trick rest_of_compilation into not deferring output of this function, even if it is inline, since the rtl_obstack for this function is the function_obstack of the enclosing function and will be deallocated when the enclosing function is gone. See save_tree_status. */ flag_keep_inline_functions = 1; /* Run the optimizers and output the assembler code for this function. */ if (DECL_ARTIFICIAL (fndecl)) { /* Do we really *want* to inline this synthesized method? */ int save_fif = flag_inline_functions; flag_inline_functions = 1; /* Turn off DECL_INLINE for the moment so function_cannot_inline_p will check our size. */ DECL_INLINE (fndecl) = 0; rest_of_compilation (fndecl); flag_inline_functions = save_fif; } else rest_of_compilation (fndecl); flag_keep_inline_functions = saved_flag_keep_inline_functions; if (DECL_SAVED_INSNS (fndecl) && ! TREE_ASM_WRITTEN (fndecl)) { /* Set DECL_EXTERNAL so that assemble_external will be called as necessary. We'll clear it again in finish_file. */ if (! DECL_EXTERNAL (fndecl)) DECL_NOT_REALLY_EXTERN (fndecl) = 1; DECL_EXTERNAL (fndecl) = 1; mark_inline_for_output (fndecl); } if (ctype && TREE_ASM_WRITTEN (fndecl)) note_debug_info_needed (ctype); current_function_returns_null |= can_reach_end; /* Since we don't normally go through c_expand_return for constructors, this normally gets the wrong value. Also, named return values have their return codes emitted after NOTE_INSN_FUNCTION_END, confusing jump.c. */ if (DECL_CONSTRUCTOR_P (fndecl) || DECL_NAME (DECL_RESULT (fndecl)) != NULL_TREE) current_function_returns_null = 0; if (TREE_THIS_VOLATILE (fndecl) && current_function_returns_null) cp_warning ("`noreturn' function `%D' does return", fndecl); else if ((warn_return_type || pedantic) && current_function_returns_null && TREE_CODE (TREE_TYPE (fntype)) != VOID_TYPE) { /* If this function returns non-void and control can drop through, complain. */ cp_warning ("control reaches end of non-void function `%D'", fndecl); } /* With just -W, complain only if function returns both with and without a value. */ else if (extra_warnings && current_function_returns_value && current_function_returns_null) warning ("this function may return with or without a value"); } --function_depth; /* Free all the tree nodes making up this function. */ /* Switch back to allocating nodes permanently until we start another function. */ if (! nested) permanent_allocation (1); if (DECL_SAVED_INSNS (fndecl) == NULL_RTX) { tree t; /* Stop pointing to the local nodes about to be freed. */ /* But DECL_INITIAL must remain nonzero so we know this was an actual function definition. */ DECL_INITIAL (fndecl) = error_mark_node; for (t = DECL_ARGUMENTS (fndecl); t; t = TREE_CHAIN (t)) DECL_RTL (t) = DECL_INCOMING_RTL (t) = NULL_RTX; } if (DECL_STATIC_CONSTRUCTOR (fndecl)) static_ctors = perm_tree_cons (NULL_TREE, fndecl, static_ctors); if (DECL_STATIC_DESTRUCTOR (fndecl)) static_dtors = perm_tree_cons (NULL_TREE, fndecl, static_dtors); if (! nested) { /* Let the error reporting routines know that we're outside a function. For a nested function, this value is used in pop_cp_function_context and then reset via pop_function_context. */ current_function_decl = NULL_TREE; } named_label_uses = NULL; current_class_ptr = NULL_TREE; current_class_ref = NULL_TREE; } /* Create the FUNCTION_DECL for a function definition. DECLSPECS and DECLARATOR are the parts of the declaration; they describe the return type and the name of the function, but twisted together in a fashion that parallels the syntax of C. This function creates a binding context for the function body as well as setting up the FUNCTION_DECL in current_function_decl. Returns a FUNCTION_DECL on success. If the DECLARATOR is not suitable for a function (it defines a datum instead), we return 0, which tells yyparse to report a parse error. May return void_type_node indicating that this method is actually a friend. See grokfield for more details. Came here with a `.pushlevel' . DO NOT MAKE ANY CHANGES TO THIS CODE WITHOUT MAKING CORRESPONDING CHANGES TO CODE IN `grokfield'. */ tree start_method (declspecs, declarator, attrlist) tree declarator, declspecs, attrlist; { tree fndecl = grokdeclarator (declarator, declspecs, MEMFUNCDEF, 0, attrlist); /* Something too ugly to handle. */ if (fndecl == NULL_TREE) return NULL_TREE; /* Pass friends other than inline friend functions back. */ if (fndecl == void_type_node) return fndecl; if (TREE_CODE (fndecl) != FUNCTION_DECL) /* Not a function, tell parser to report parse error. */ return NULL_TREE; if (IS_SIGNATURE (current_class_type)) IS_DEFAULT_IMPLEMENTATION (fndecl) = 1; if (DECL_IN_AGGR_P (fndecl)) { if (IDENTIFIER_ERROR_LOCUS (DECL_ASSEMBLER_NAME (fndecl)) != current_class_type) { if (DECL_CONTEXT (fndecl) && TREE_CODE( DECL_CONTEXT (fndecl)) != NAMESPACE_DECL) cp_error ("`%D' is already defined in class %s", fndecl, TYPE_NAME_STRING (DECL_CONTEXT (fndecl))); } return void_type_node; } check_template_shadow (fndecl); DECL_THIS_INLINE (fndecl) = 1; if (flag_default_inline) DECL_INLINE (fndecl) = 1; /* We process method specializations in finish_struct_1. */ if (processing_template_decl && !DECL_TEMPLATE_SPECIALIZATION (fndecl)) fndecl = push_template_decl (fndecl); /* We read in the parameters on the maybepermanent_obstack, but we won't be getting back to them until after we may have clobbered them. So the call to preserve_data will keep them safe. */ preserve_data (); if (! DECL_FRIEND_P (fndecl)) { if (TREE_CHAIN (fndecl)) { fndecl = copy_node (fndecl); TREE_CHAIN (fndecl) = NULL_TREE; } if (DECL_CONSTRUCTOR_P (fndecl)) { if (! grok_ctor_properties (current_class_type, fndecl)) return void_type_node; } else if (IDENTIFIER_OPNAME_P (DECL_NAME (fndecl))) grok_op_properties (fndecl, DECL_VIRTUAL_P (fndecl), 0); } cp_finish_decl (fndecl, NULL_TREE, NULL_TREE, 0, 0); /* Make a place for the parms */ pushlevel (0); current_binding_level->parm_flag = 1; DECL_IN_AGGR_P (fndecl) = 1; return fndecl; } /* Go through the motions of finishing a function definition. We don't compile this method until after the whole class has been processed. FINISH_METHOD must return something that looks as though it came from GROKFIELD (since we are defining a method, after all). This is called after parsing the body of the function definition. STMTS is the chain of statements that makes up the function body. DECL is the ..._DECL that `start_method' provided. */ tree finish_method (decl) tree decl; { register tree fndecl = decl; tree old_initial; register tree link; if (decl == void_type_node) return decl; old_initial = DECL_INITIAL (fndecl); /* Undo the level for the parms (from start_method). This is like poplevel, but it causes nothing to be saved. Saving information here confuses symbol-table output routines. Besides, this information will be correctly output when this method is actually compiled. */ /* Clear out the meanings of the local variables of this level; also record in each decl which block it belongs to. */ for (link = current_binding_level->names; link; link = TREE_CHAIN (link)) { if (DECL_NAME (link) != NULL_TREE) pop_binding (DECL_NAME (link), link); my_friendly_assert (TREE_CODE (link) != FUNCTION_DECL, 163); DECL_CONTEXT (link) = NULL_TREE; } GNU_xref_end_scope ((HOST_WIDE_INT) current_binding_level, (HOST_WIDE_INT) current_binding_level->level_chain, current_binding_level->parm_flag, current_binding_level->keep); poplevel (0, 0, 0); DECL_INITIAL (fndecl) = old_initial; /* We used to check if the context of FNDECL was different from current_class_type as another way to get inside here. This didn't work for String.cc in libg++. */ if (DECL_FRIEND_P (fndecl)) { CLASSTYPE_INLINE_FRIENDS (current_class_type) = tree_cons (NULL_TREE, fndecl, CLASSTYPE_INLINE_FRIENDS (current_class_type)); decl = void_type_node; } return decl; } /* Called when a new struct TYPE is defined. If this structure or union completes the type of any previous variable declaration, lay it out and output its rtl. */ void hack_incomplete_structures (type) tree type; { tree *list; if (current_binding_level->incomplete == NULL_TREE) return; if (!type) /* Don't do this for class templates. */ return; for (list = ¤t_binding_level->incomplete; *list; ) { tree decl = TREE_VALUE (*list); if ((decl && TREE_TYPE (decl) == type) || (TREE_TYPE (decl) && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE && TREE_TYPE (TREE_TYPE (decl)) == type)) { int toplevel = toplevel_bindings_p (); if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE && TREE_TYPE (TREE_TYPE (decl)) == type) layout_type (TREE_TYPE (decl)); layout_decl (decl, 0); rest_of_decl_compilation (decl, NULL_PTR, toplevel, 0); if (! toplevel) { tree cleanup; expand_decl (decl); cleanup = maybe_build_cleanup (decl); expand_decl_init (decl); if (! expand_decl_cleanup (decl, cleanup)) cp_error ("parser lost in parsing declaration of `%D'", decl); } *list = TREE_CHAIN (*list); } else list = &TREE_CHAIN (*list); } } /* If DECL is of a type which needs a cleanup, build that cleanup here. See build_delete for information about AUTO_DELETE. Don't build these on the momentary obstack; they must live the life of the binding contour. */ static tree maybe_build_cleanup_1 (decl, auto_delete) tree decl, auto_delete; { tree type = TREE_TYPE (decl); if (type != error_mark_node && TYPE_NEEDS_DESTRUCTOR (type)) { int temp = 0, flags = LOOKUP_NORMAL|LOOKUP_DESTRUCTOR; tree rval; if (TREE_CODE (decl) != PARM_DECL) temp = suspend_momentary (); if (TREE_CODE (type) == ARRAY_TYPE) rval = decl; else { mark_addressable (decl); rval = build_unary_op (ADDR_EXPR, decl, 0); } /* Optimize for space over speed here. */ if (! TYPE_USES_VIRTUAL_BASECLASSES (type) || flag_expensive_optimizations) flags |= LOOKUP_NONVIRTUAL; rval = build_delete (TREE_TYPE (rval), rval, auto_delete, flags, 0); if (TYPE_USES_VIRTUAL_BASECLASSES (type) && ! TYPE_HAS_DESTRUCTOR (type)) rval = build_compound_expr (expr_tree_cons (NULL_TREE, rval, build_expr_list (NULL_TREE, build_vbase_delete (type, decl)))); if (TREE_CODE (decl) != PARM_DECL) resume_momentary (temp); return rval; } return 0; } /* If DECL is of a type which needs a cleanup, build that cleanup here. The cleanup does free the storage with a call to delete. */ tree maybe_build_cleanup_and_delete (decl) tree decl; { return maybe_build_cleanup_1 (decl, integer_three_node); } /* If DECL is of a type which needs a cleanup, build that cleanup here. The cleanup does not free the storage with a call a delete. */ tree maybe_build_cleanup (decl) tree decl; { return maybe_build_cleanup_1 (decl, integer_two_node); } /* Expand a C++ expression at the statement level. This is needed to ferret out nodes which have UNKNOWN_TYPE. The C++ type checker should get all of these out when expressions are combined with other, type-providing, expressions, leaving only orphan expressions, such as: &class::bar; / / takes its address, but does nothing with it. */ void cplus_expand_expr_stmt (exp) tree exp; { if (processing_template_decl) { add_tree (build_min_nt (EXPR_STMT, exp)); return; } /* Arrange for all temps to disappear. */ expand_start_target_temps (); exp = require_complete_type_in_void (exp); if (TREE_CODE (exp) == FUNCTION_DECL) { cp_warning ("reference, not call, to function `%D'", exp); warning ("at this point in file"); } #if 0 /* We should do this eventually, but right now this causes regex.o from libg++ to miscompile, and tString to core dump. */ exp = build1 (CLEANUP_POINT_EXPR, TREE_TYPE (exp), exp); #endif /* Strip unused implicit INDIRECT_REFs of references. */ if (TREE_CODE (exp) == INDIRECT_REF && TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == REFERENCE_TYPE) exp = TREE_OPERAND (exp, 0); /* If we don't do this, we end up down inside expand_expr trying to do TYPE_MODE on the ERROR_MARK, and really go outside the bounds of the type. */ if (exp != error_mark_node) expand_expr_stmt (break_out_cleanups (exp)); /* Clean up any pending cleanups. This happens when a function call returns a cleanup-needing value that nobody uses. */ expand_end_target_temps (); } /* When a stmt has been parsed, this function is called. Currently, this function only does something within a constructor's scope: if a stmt has just assigned to this, and we are in a derived class, we call `emit_base_init'. */ void finish_stmt () { extern struct nesting *cond_stack, *loop_stack, *case_stack; if (current_function_assigns_this || ! current_function_just_assigned_this) return; if (DECL_CONSTRUCTOR_P (current_function_decl)) { /* Constructors must wait until we are out of control zones before calling base constructors. */ if (cond_stack || loop_stack || case_stack) return; expand_expr_stmt (base_init_expr); check_base_init (current_class_type); } current_function_assigns_this = 1; } /* Change a static member function definition into a FUNCTION_TYPE, instead of the METHOD_TYPE that we create when it's originally parsed. WARNING: DO NOT pass &TREE_TYPE (decl) to FN or &TYPE_ARG_TYPES (TREE_TYPE (decl)) to ARGTYPES, as doing so will corrupt the types of other decls. Either pass the addresses of local variables or NULL. */ void revert_static_member_fn (decl, fn, argtypes) tree *decl, *fn, *argtypes; { tree tmp; tree function = fn ? *fn : TREE_TYPE (*decl); tree args = argtypes ? *argtypes : TYPE_ARG_TYPES (function); if (CP_TYPE_QUALS (TREE_TYPE (TREE_VALUE (args))) != TYPE_UNQUALIFIED) cp_error ("static member function `%#D' declared with type qualifiers", *decl); args = TREE_CHAIN (args); tmp = build_function_type (TREE_TYPE (function), args); tmp = build_qualified_type (tmp, CP_TYPE_QUALS (function)); tmp = build_exception_variant (tmp, TYPE_RAISES_EXCEPTIONS (function)); TREE_TYPE (*decl) = tmp; if (DECL_ARGUMENTS (*decl)) DECL_ARGUMENTS (*decl) = TREE_CHAIN (DECL_ARGUMENTS (*decl)); DECL_STATIC_FUNCTION_P (*decl) = 1; if (fn) *fn = tmp; if (argtypes) *argtypes = args; } struct cp_function { int returns_value; int returns_null; int assigns_this; int just_assigned_this; int parms_stored; int temp_name_counter; tree named_labels; struct named_label_list *named_label_uses; tree shadowed_labels; tree ctor_label; tree dtor_label; rtx last_dtor_insn; rtx last_parm_cleanup_insn; tree base_init_list; tree member_init_list; tree base_init_expr; tree current_class_ptr; tree current_class_ref; rtx result_rtx; struct cp_function *next; struct binding_level *binding_level; int static_labelno; }; static struct cp_function *cp_function_chain; extern int temp_name_counter; /* Save and reinitialize the variables used during compilation of a C++ function. */ void push_cp_function_context (context) tree context; { struct cp_function *p = (struct cp_function *) xmalloc (sizeof (struct cp_function)); push_function_context_to (context); p->next = cp_function_chain; cp_function_chain = p; p->named_labels = named_labels; p->named_label_uses = named_label_uses; p->shadowed_labels = shadowed_labels; p->returns_value = current_function_returns_value; p->returns_null = current_function_returns_null; p->binding_level = current_binding_level; p->ctor_label = ctor_label; p->dtor_label = dtor_label; p->last_dtor_insn = last_dtor_insn; p->last_parm_cleanup_insn = last_parm_cleanup_insn; p->assigns_this = current_function_assigns_this; p->just_assigned_this = current_function_just_assigned_this; p->parms_stored = current_function_parms_stored; p->result_rtx = original_result_rtx; p->base_init_expr = base_init_expr; p->temp_name_counter = temp_name_counter; p->base_init_list = current_base_init_list; p->member_init_list = current_member_init_list; p->current_class_ptr = current_class_ptr; p->current_class_ref = current_class_ref; p->static_labelno = static_labelno; } /* Restore the variables used during compilation of a C++ function. */ void pop_cp_function_context (context) tree context; { struct cp_function *p = cp_function_chain; tree link; /* Bring back all the labels that were shadowed. */ for (link = shadowed_labels; link; link = TREE_CHAIN (link)) if (DECL_NAME (TREE_VALUE (link)) != 0) SET_IDENTIFIER_LABEL_VALUE (DECL_NAME (TREE_VALUE (link)), TREE_VALUE (link)); pop_function_context_from (context); cp_function_chain = p->next; named_labels = p->named_labels; named_label_uses = p->named_label_uses; shadowed_labels = p->shadowed_labels; current_function_returns_value = p->returns_value; current_function_returns_null = p->returns_null; current_binding_level = p->binding_level; ctor_label = p->ctor_label; dtor_label = p->dtor_label; last_dtor_insn = p->last_dtor_insn; last_parm_cleanup_insn = p->last_parm_cleanup_insn; current_function_assigns_this = p->assigns_this; current_function_just_assigned_this = p->just_assigned_this; current_function_parms_stored = p->parms_stored; original_result_rtx = p->result_rtx; base_init_expr = p->base_init_expr; temp_name_counter = p->temp_name_counter; current_base_init_list = p->base_init_list; current_member_init_list = p->member_init_list; current_class_ptr = p->current_class_ptr; current_class_ref = p->current_class_ref; static_labelno = p->static_labelno; free (p); } int in_function_p () { return function_depth != 0; } Index: vendor/gcc/dist/contrib/gcc/cp/decl2.c =================================================================== --- vendor/gcc/dist/contrib/gcc/cp/decl2.c (revision 60966) +++ vendor/gcc/dist/contrib/gcc/cp/decl2.c (revision 60967) @@ -1,5304 +1,5379 @@ /* Process declarations and variables for C compiler. Copyright (C) 1988, 92-98, 1999 Free Software Foundation, Inc. Hacked by Michael Tiemann (tiemann@cygnus.com) 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. */ /* Process declarations and symbol lookup for C front end. Also constructs types; the standard scalar types at initialization, and structure, union, array and enum types when they are declared. */ /* ??? not all decl nodes are given the most useful possible line numbers. For example, the CONST_DECLs for enum values. */ #include "config.h" #include "system.h" #include "tree.h" #include "rtl.h" #include "flags.h" #include "cp-tree.h" #include "decl.h" #include "lex.h" #include "output.h" #include "except.h" #include "expr.h" #include "defaults.h" #include "toplev.h" #include "dwarf2out.h" #include "dwarfout.h" #include "splay-tree.h" #include "varray.h" #if USE_CPPLIB #include "cpplib.h" extern cpp_reader parse_in; #endif /* This structure contains information about the initializations and/or destructions required for a particular priority level. */ typedef struct priority_info_s { /* A label indicating where we should generate the next initialization with this priority. */ rtx initialization_sequence; /* A label indicating where we should generate the next destruction with this priority. */ rtx destruction_sequence; /* Non-zero if there have been any initializations at this priority throughout the translation unit. */ int initializations_p; /* Non-zero if there have been any destructions at this priority throughout the translation unit. */ int destructions_p; } *priority_info; static tree get_sentry PROTO((tree)); static void mark_vtable_entries PROTO((tree)); static void grok_function_init PROTO((tree, tree)); static int finish_vtable_vardecl PROTO((tree *, void *)); static int prune_vtable_vardecl PROTO((tree *, void *)); static int finish_sigtable_vardecl PROTO((tree *, void *)); static int is_namespace_ancestor PROTO((tree, tree)); static void add_using_namespace PROTO((tree, tree, int)); static tree ambiguous_decl PROTO((tree, tree, tree,int)); static tree build_anon_union_vars PROTO((tree, tree*, int, int)); static int acceptable_java_type PROTO((tree)); static void output_vtable_inherit PROTO((tree)); static void start_objects PROTO((int, int)); static void finish_objects PROTO((int, int)); static tree merge_functions PROTO((tree, tree)); static tree decl_namespace PROTO((tree)); static tree validate_nonmember_using_decl PROTO((tree, tree *, tree *)); static void do_nonmember_using_decl PROTO((tree, tree, tree, tree, tree *, tree *)); static void start_static_storage_duration_function PROTO((void)); static int generate_inits_for_priority PROTO((splay_tree_node, void *)); static void finish_static_storage_duration_function PROTO((void)); static priority_info get_priority_info PROTO((int)); static void do_static_initialization PROTO((tree, tree, tree, int)); static void do_static_destruction PROTO((tree, tree, int)); static void do_static_initialization_and_destruction PROTO((tree, tree)); static void generate_ctor_or_dtor_function PROTO((int, int)); static int generate_ctor_and_dtor_functions_for_priority PROTO((splay_tree_node, void *)); extern int current_class_depth; /* A list of virtual function tables we must make sure to write out. */ tree pending_vtables; /* A list of static class variables. This is needed, because a static class variable can be declared inside the class without an initializer, and then initialized, staticly, outside the class. */ static varray_type pending_statics; static size_t pending_statics_used; /* A list of functions which were declared inline, but which we may need to emit outline anyway. */ static varray_type saved_inlines; static size_t saved_inlines_used; /* Used to help generate temporary names which are unique within a function. Reset to 0 by start_function. */ int temp_name_counter; /* Same, but not reset. Local temp variables and global temp variables can have the same name. */ static int global_temp_name_counter; /* Flag used when debugging spew.c */ extern int spew_debug; /* Nonzero if we're done parsing and into end-of-file activities. */ int at_eof; /* Functions called along with real static constructors and destructors. */ tree static_ctors, static_dtors; /* The current open namespace, and ::. */ tree current_namespace; tree global_namespace; /* The stack for namespaces of current declarations. */ static tree decl_namespace_list; /* C (and C++) language-specific option variables. */ /* Nonzero means allow type mismatches in conditional expressions; just make their values `void'. */ int flag_cond_mismatch; /* Nonzero means give `double' the same size as `float'. */ int flag_short_double; /* Nonzero means don't recognize the keyword `asm'. */ int flag_no_asm; /* Nonzero means don't recognize any extension keywords. */ int flag_no_gnu_keywords; /* Nonzero means don't recognize the non-ANSI builtin functions. */ int flag_no_builtin; /* Nonzero means don't recognize the non-ANSI builtin functions. -ansi sets this. */ int flag_no_nonansi_builtin; /* Nonzero means do some things the same way PCC does. Only provided so the compiler will link. */ int flag_traditional; /* Nonzero means to treat bitfields as unsigned unless they say `signed'. */ int flag_signed_bitfields = 1; /* Nonzero means enable obscure ANSI features and disable GNU extensions that might cause ANSI-compliant code to be miscompiled. */ int flag_ansi; /* Nonzero means do emit exported implementations of functions even if they can be inlined. */ int flag_implement_inlines = 1; /* Nonzero means do emit exported implementations of templates, instead of multiple static copies in each file that needs a definition. */ int flag_external_templates; /* Nonzero means that the decision to emit or not emit the implementation of a template depends on where the template is instantiated, rather than where it is defined. */ int flag_alt_external_templates; /* Nonzero means that implicit instantiations will be emitted if needed. */ int flag_implicit_templates = 1; /* Nonzero means that implicit instantiations of inline templates will be emitted if needed, even if instantiations of non-inline templates aren't. */ int flag_implicit_inline_templates = 1; /* Nonzero means warn about implicit declarations. */ int warn_implicit = 1; /* Nonzero means warn about usage of long long when `-pedantic'. */ int warn_long_long = 1; /* Nonzero means warn when all ctors or dtors are private, and the class has no friends. */ int warn_ctor_dtor_privacy = 1; -/* True if we want to implement vtables using "thunks". - The default is off. */ +/* 1 or 2 if we want to implement vtables using "thunks". + The default is off. Version 1 indicates "old" implementation; + Version 2 passes the __vlist argument in pvbase cases. */ #ifndef DEFAULT_VTABLE_THUNKS #define DEFAULT_VTABLE_THUNKS 0 #endif int flag_vtable_thunks = DEFAULT_VTABLE_THUNKS; +#if DEFAULT_VTABLE_THUNKS == 2 +int flag_vtable_thunks_compat = 1; +#else +int flag_vtable_thunks_compat = 0; +#endif + /* True if we want to deal with repository information. */ int flag_use_repository; /* Nonzero if we want to issue diagnostics that the standard says are not required. */ int flag_optional_diags = 1; /* Nonzero means give string constants the type `const char *', as mandated by the standard. */ int flag_const_strings = 1; /* Nonzero means warn about deprecated conversion from string constant to `char *'. */ int warn_write_strings; /* Nonzero means warn about pointer casts that can drop a type qualifier from the pointer target type. */ int warn_cast_qual; /* Nonzero means warn about sizeof(function) or addition/subtraction of function pointers. */ int warn_pointer_arith = 1; /* Nonzero means warn for any function def without prototype decl. */ int warn_missing_prototypes; /* Nonzero means warn about multiple (redundant) decls for the same single variable or function. */ int warn_redundant_decls; /* Warn if initializer is not completely bracketed. */ int warn_missing_braces; /* Warn about comparison of signed and unsigned values. */ int warn_sign_compare; /* Warn about *printf or *scanf format/argument anomalies. */ int warn_format; /* Warn about a subscript that has type char. */ int warn_char_subscripts; /* Warn if a type conversion is done that might have confusing results. */ int warn_conversion; /* Warn if adding () is suggested. */ int warn_parentheses; /* 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. */ int warn_overloaded_virtual; /* Non-zero means warn when declaring a class that has a non virtual destructor, when it really ought to have a virtual one. */ int warn_nonvdtor; /* Non-zero means warn when a function is declared extern and later inline. */ int warn_extern_inline; /* Non-zero means warn when the compiler will reorder code. */ int warn_reorder; /* Non-zero means warn when synthesis behavior differs from Cfront's. */ int warn_synth; /* Non-zero means warn when we convert a pointer to member function into a pointer to (void or function). */ int warn_pmf2ptr = 1; /* Nonzero means warn about violation of some Effective C++ style rules. */ int warn_ecpp; /* Nonzero means warn where overload resolution chooses a promotion from unsigned to signed over a conversion to an unsigned of the same size. */ int warn_sign_promo; /* Nonzero means warn when an old-style cast is used. */ int warn_old_style_cast; /* Warn about #pragma directives that are not recognised. */ int warn_unknown_pragmas; /* Tri state variable. */ /* Nonzero means warn about use of multicharacter literals. */ int warn_multichar = 1; /* Nonzero means warn when non-templatized friend functions are declared within a template */ int warn_nontemplate_friend = 1; /* Nonzero means complain about deprecated features. */ int warn_deprecated = 1; /* Nonzero means `$' can be in an identifier. */ #ifndef DOLLARS_IN_IDENTIFIERS #define DOLLARS_IN_IDENTIFIERS 1 #endif int dollars_in_ident = DOLLARS_IN_IDENTIFIERS; /* Nonzero for -fno-strict-prototype switch: do not consider empty argument prototype to mean function takes no arguments. */ int flag_strict_prototype = 2; int strict_prototype = 1; int strict_prototypes_lang_c, strict_prototypes_lang_cplusplus = 1; /* Nonzero means that labels can be used as first-class objects */ int flag_labels_ok; /* 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. -2 means we're constructing an object and it has fixed type. */ int flag_this_is_variable; /* 3 means write out only virtuals function tables `defined' in this implementation file. 0 means write out virtual function tables and give them (C) static access (default). */ int write_virtuals; /* Nonzero means we should attempt to elide constructors when possible. */ int flag_elide_constructors = 1; /* Nonzero means recognize and handle signature language constructs. */ int flag_handle_signatures; /* Nonzero means that member functions defined in class scope are inline by default. */ int flag_default_inline = 1; /* Controls whether compiler generates 'type descriptor' that give run-time type information. */ int flag_rtti = 1; /* Nonzero if we wish to output cross-referencing information for the GNU class browser. */ extern int flag_gnu_xref; /* Nonzero if we want to support huge (> 2^(sizeof(short)*8-1) bytes) objects. */ int flag_huge_objects; /* Nonzero if we want to conserve space in the .o files. We do this by putting uninitialized data and runtime initialized data into .common instead of .data at the expense of not flagging multiple definitions. */ int flag_conserve_space; /* Nonzero if we want to obey access control semantics. */ int flag_access_control = 1; /* Nonzero if we want to understand the operator names, i.e. 'bitand'. */ int flag_operator_names; /* Nonzero if we want to check the return value of new and avoid calling constructors if it is a null pointer. */ int flag_check_new; /* Nonzero if we want the new ANSI rules for pushing a new scope for `for' initialization variables. 0: Old rules, set by -fno-for-scope. 2: New ANSI rules, set by -ffor-scope. 1: Try to implement new ANSI rules, but with backup compatibility (and warnings). This is the default, for now. */ int flag_new_for_scope = 1; /* Nonzero if we want to emit defined symbols with common-like linkage as weak symbols where possible, in order to conform to C++ semantics. Otherwise, emit them as local symbols. */ int flag_weak = 1; /* Nonzero to enable experimental ABI changes. */ int flag_new_abi; /* Nonzero to not ignore namespace std. */ int flag_honor_std; /* Maximum template instantiation depth. Must be at least 17 for ANSI compliance. */ int max_tinst_depth = 17; /* The name-mangling scheme to use. Must be 1 or greater to support template functions with identical types, but different template arguments. */ int name_mangling_version = 2; /* Nonzero means that guiding declarations are allowed. */ int flag_guiding_decls; /* Nonzero if squashed mangling is to be performed. This uses the B and K codes to reference previously seen class types and class qualifiers. */ int flag_do_squangling; /* Nonzero means output .vtable_{entry,inherit} for use in doing vtable gc. */ int flag_vtable_gc; /* Nonzero means make the default pedwarns warnings instead of errors. The value of this flag is ignored if -pedantic is specified. */ int flag_permissive; /* Table of language-dependent -f options. STRING is the option name. VARIABLE is the address of the variable. ON_VALUE is the value to store in VARIABLE if `-fSTRING' is seen as an option. (If `-fno-STRING' is seen as an option, the opposite value is stored.) */ static struct { const char *string; int *variable; int on_value;} lang_f_options[] = { /* C/C++ options. */ {"signed-char", &flag_signed_char, 1}, {"unsigned-char", &flag_signed_char, 0}, {"signed-bitfields", &flag_signed_bitfields, 1}, {"unsigned-bitfields", &flag_signed_bitfields, 0}, {"short-enums", &flag_short_enums, 1}, {"short-double", &flag_short_double, 1}, {"cond-mismatch", &flag_cond_mismatch, 1}, {"asm", &flag_no_asm, 0}, {"builtin", &flag_no_builtin, 0}, /* C++-only options. */ {"access-control", &flag_access_control, 1}, {"check-new", &flag_check_new, 1}, {"conserve-space", &flag_conserve_space, 1}, {"const-strings", &flag_const_strings, 1}, {"default-inline", &flag_default_inline, 1}, {"dollars-in-identifiers", &dollars_in_ident, 1}, {"elide-constructors", &flag_elide_constructors, 1}, {"external-templates", &flag_external_templates, 1}, {"for-scope", &flag_new_for_scope, 2}, {"gnu-keywords", &flag_no_gnu_keywords, 0}, {"handle-exceptions", &flag_exceptions, 1}, {"handle-signatures", &flag_handle_signatures, 1}, {"honor-std", &flag_honor_std, 1}, {"huge-objects", &flag_huge_objects, 1}, {"implement-inlines", &flag_implement_inlines, 1}, {"implicit-inline-templates", &flag_implicit_inline_templates, 1}, {"implicit-templates", &flag_implicit_templates, 1}, {"labels-ok", &flag_labels_ok, 1}, {"nonansi-builtins", &flag_no_nonansi_builtin, 0}, {"operator-names", &flag_operator_names, 1}, {"optional-diags", &flag_optional_diags, 1}, {"permissive", &flag_permissive, 1}, {"repo", &flag_use_repository, 1}, {"rtti", &flag_rtti, 1}, {"squangle", &flag_do_squangling, 1}, {"stats", &flag_detailed_statistics, 1}, {"strict-prototype", &flag_strict_prototype, 1}, {"this-is-variable", &flag_this_is_variable, 1}, {"vtable-gc", &flag_vtable_gc, 1}, {"vtable-thunks", &flag_vtable_thunks, 1}, {"weak", &flag_weak, 1}, {"xref", &flag_gnu_xref, 1} }; /* Decode the string P as a language-specific option. Return the number of strings consumed for a valid option. Otherwise return 0. */ int lang_decode_option (argc, argv) int argc #if !USE_CPPLIB ATTRIBUTE_UNUSED #endif ; char **argv; { int strings_processed; char *p = argv[0]; #if USE_CPPLIB strings_processed = cpp_handle_option (&parse_in, argc, argv); #else strings_processed = 0; #endif /* ! USE_CPPLIB */ if (!strcmp (p, "-ftraditional") || !strcmp (p, "-traditional")) /* ignore */; else if (p[0] == '-' && p[1] == 'f') { /* Some kind of -f option. P's value is the option sans `-f'. Search for it in the table of options. */ int found = 0; size_t j; p += 2; /* Try special -f options. */ if (!strcmp (p, "handle-exceptions") || !strcmp (p, "no-handle-exceptions")) warning ("-fhandle-exceptions has been renamed to -fexceptions (and is now on by default)"); if (!strcmp (p, "memoize-lookups") || !strcmp (p, "no-memoize-lookups") || !strcmp (p, "save-memoized") || !strcmp (p, "no-save-memoized") || !strcmp (p, "no-all-virtual") || !strcmp (p, "no-enum-int-equiv") || !strcmp (p, "nonnull-objects") || !strcmp (p, "ansi-overloading")) { /* ignore */ found = 1; } else if (!strcmp (p, "all-virtual") || !strcmp (p, "enum-int-equiv") || !strcmp (p, "no-nonnull-objects") || !strcmp (p, "no-ansi-overloading")) { warning ("-f%s is no longer supported", p); found = 1; } else if (! strcmp (p, "alt-external-templates")) { flag_external_templates = 1; flag_alt_external_templates = 1; found = 1; cp_deprecated ("-falt-external-templates"); } else if (! strcmp (p, "no-alt-external-templates")) { flag_alt_external_templates = 0; found = 1; } else if (!strcmp (p, "repo")) { flag_use_repository = 1; flag_implicit_templates = 0; found = 1; } else if (!strcmp (p, "guiding-decls")) { flag_guiding_decls = 1; name_mangling_version = 0; found = 1; } else if (!strcmp (p, "no-guiding-decls")) { flag_guiding_decls = 0; found = 1; } else if (!strcmp (p, "this-is-variable")) { flag_this_is_variable = 1; found = 1; cp_deprecated ("-fthis-is-variable"); } else if (!strcmp (p, "external-templates")) { flag_external_templates = 1; found = 1; cp_deprecated ("-fexternal-templates"); } + else if (!strncmp (p, "vtable-thunks", 13)) + { + if (p[13] == '=') + { + flag_vtable_thunks = + read_integral_parameter (p+14, p, 1); + } + else + { + /* If the machine file has a default setting, use that + for -fvtable-thunks. Otherwise, set it to version + 2. */ +#if DEFAULT_VTABLE_THUNKS + flag_vtable_thunks = DEFAULT_VTABLE_THUNKS; +#else + flag_vtable_thunks = 1; +#endif + } + if (flag_vtable_thunks == 2) + /* v2 is a compatibility mode between v1 and v3. */ + flag_vtable_thunks_compat = 1; + else if(flag_vtable_thunks == 3) + flag_vtable_thunks_compat = 0; + found = 1; + } else if (!strcmp (p, "handle-signatures")) { flag_handle_signatures = 1; found = 1; cp_deprecated ("-fhandle-signatures"); } else if (!strcmp (p, "new-abi")) { flag_new_abi = 1; flag_do_squangling = 1; flag_honor_std = 1; - flag_vtable_thunks = 1; + flag_vtable_thunks = 2; } else if (!strcmp (p, "no-new-abi")) { flag_new_abi = 0; flag_do_squangling = 0; flag_honor_std = 0; } else if (!strncmp (p, "template-depth-", 15)) { max_tinst_depth = read_integral_parameter (p + 15, p - 2, max_tinst_depth); } else if (!strncmp (p, "name-mangling-version-", 22)) { name_mangling_version = read_integral_parameter (p + 22, p - 2, name_mangling_version); } else for (j = 0; !found && j < sizeof (lang_f_options) / sizeof (lang_f_options[0]); j++) { if (!strcmp (p, lang_f_options[j].string)) { *lang_f_options[j].variable = lang_f_options[j].on_value; /* A goto here would be cleaner, but breaks the vax pcc. */ found = 1; } if (p[0] == 'n' && p[1] == 'o' && p[2] == '-' && ! strcmp (p+3, lang_f_options[j].string)) { *lang_f_options[j].variable = ! lang_f_options[j].on_value; found = 1; } } return found; } else if (p[0] == '-' && p[1] == 'W') { int setting = 1; /* The -W options control the warning behavior of the compiler. */ p += 2; if (p[0] == 'n' && p[1] == 'o' && p[2] == '-') setting = 0, p += 3; if (!strcmp (p, "implicit")) warn_implicit = setting; else if (!strcmp (p, "long-long")) warn_long_long = setting; else if (!strcmp (p, "return-type")) warn_return_type = setting; else if (!strcmp (p, "ctor-dtor-privacy")) warn_ctor_dtor_privacy = setting; else if (!strcmp (p, "write-strings")) warn_write_strings = setting; else if (!strcmp (p, "cast-qual")) warn_cast_qual = setting; else if (!strcmp (p, "char-subscripts")) warn_char_subscripts = setting; else if (!strcmp (p, "pointer-arith")) warn_pointer_arith = setting; else if (!strcmp (p, "missing-prototypes")) warn_missing_prototypes = setting; else if (!strcmp (p, "redundant-decls")) warn_redundant_decls = setting; else if (!strcmp (p, "missing-braces")) warn_missing_braces = setting; else if (!strcmp (p, "sign-compare")) warn_sign_compare = setting; else if (!strcmp (p, "format")) warn_format = setting; else if (!strcmp (p, "conversion")) warn_conversion = setting; else if (!strcmp (p, "parentheses")) warn_parentheses = setting; else if (!strcmp (p, "non-virtual-dtor")) warn_nonvdtor = setting; else if (!strcmp (p, "extern-inline")) warn_extern_inline = setting; else if (!strcmp (p, "reorder")) warn_reorder = setting; else if (!strcmp (p, "synth")) warn_synth = setting; else if (!strcmp (p, "pmf-conversions")) warn_pmf2ptr = setting; else if (!strcmp (p, "effc++")) warn_ecpp = setting; else if (!strcmp (p, "sign-promo")) warn_sign_promo = setting; else if (!strcmp (p, "old-style-cast")) warn_old_style_cast = setting; else if (!strcmp (p, "overloaded-virtual")) warn_overloaded_virtual = setting; else if (!strcmp (p, "multichar")) warn_multichar = setting; else if (!strcmp (p, "unknown-pragmas")) /* Set to greater than 1, so that even unknown pragmas in system headers will be warned about. */ warn_unknown_pragmas = setting * 2; else if (!strcmp (p, "non-template-friend")) warn_nontemplate_friend = setting; else if (!strcmp (p, "deprecated")) warn_deprecated = setting; else if (!strcmp (p, "comment")) ; /* cpp handles this one. */ else if (!strcmp (p, "comments")) ; /* cpp handles this one. */ else if (!strcmp (p, "trigraphs")) ; /* cpp handles this one. */ else if (!strcmp (p, "import")) ; /* cpp handles this one. */ else if (!strcmp (p, "all")) { warn_return_type = setting; warn_unused = setting; warn_implicit = setting; warn_switch = setting; warn_format = setting; warn_parentheses = setting; warn_missing_braces = setting; warn_sign_compare = setting; warn_multichar = setting; /* We save the value of warn_uninitialized, since if they put -Wuninitialized on the command line, we need to generate a warning about not using it without also specifying -O. */ if (warn_uninitialized != 1) warn_uninitialized = (setting ? 2 : 0); /* Only warn about unknown pragmas that are not in system headers. */ warn_unknown_pragmas = 1; /* C++-specific warnings. */ warn_ctor_dtor_privacy = setting; warn_nonvdtor = setting; warn_reorder = setting; warn_nontemplate_friend = setting; } else return strings_processed; } else if (!strcmp (p, "-ansi")) flag_no_nonansi_builtin = 1, flag_ansi = 1, flag_no_gnu_keywords = 1, flag_operator_names = 1; #ifdef SPEW_DEBUG /* Undocumented, only ever used when you're invoking cc1plus by hand, since it's probably safe to assume no sane person would ever want to use this under normal circumstances. */ else if (!strcmp (p, "-spew-debug")) spew_debug = 1; #endif else return strings_processed; return 1; } /* Incorporate `const' and `volatile' qualifiers for member functions. FUNCTION is a TYPE_DECL or a FUNCTION_DECL. QUALS is a list of qualifiers. */ tree grok_method_quals (ctype, function, quals) tree ctype, function, quals; { tree fntype = TREE_TYPE (function); tree raises = TYPE_RAISES_EXCEPTIONS (fntype); int type_quals = TYPE_UNQUALIFIED; int dup_quals = TYPE_UNQUALIFIED; do { int tq = cp_type_qual_from_rid (TREE_VALUE (quals)); if (type_quals & tq) dup_quals |= tq; else type_quals |= tq; quals = TREE_CHAIN (quals); } while (quals); if (dup_quals != TYPE_UNQUALIFIED) cp_error ("duplicate type qualifiers in %s declaration", TREE_CODE (function) == FUNCTION_DECL ? "member function" : "type"); ctype = cp_build_qualified_type (ctype, type_quals); fntype = build_cplus_method_type (ctype, TREE_TYPE (fntype), (TREE_CODE (fntype) == METHOD_TYPE ? TREE_CHAIN (TYPE_ARG_TYPES (fntype)) : TYPE_ARG_TYPES (fntype))); if (raises) fntype = build_exception_variant (fntype, raises); TREE_TYPE (function) = fntype; return ctype; } /* Warn when -fexternal-templates is used and #pragma interface/implementation is not used all the times it should be, inform the user. */ void warn_if_unknown_interface (decl) tree decl; { static int already_warned = 0; if (already_warned++) return; if (flag_alt_external_templates) { struct tinst_level *til = tinst_for_decl (); int sl = lineno; char *sf = input_filename; if (til) { lineno = til->line; input_filename = til->file; } cp_warning ("template `%#D' instantiated in file without #pragma interface", decl); lineno = sl; input_filename = sf; } else cp_warning_at ("template `%#D' defined in file without #pragma interface", decl); } /* A subroutine of the parser, to handle a component list. */ void grok_x_components (specs) tree specs; { struct pending_inline **p; tree t; specs = strip_attrs (specs); check_tag_decl (specs); t = groktypename (build_decl_list (specs, NULL_TREE)); /* The only case where we need to do anything additional here is an anonymous union field, e.g.: `struct S { union { int i; }; };'. */ if (t == NULL_TREE || !ANON_UNION_TYPE_P (t)) return; fixup_anonymous_union (t); finish_member_declaration (build_lang_field_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; } /* Constructors for types with virtual baseclasses need an "in-charge" flag saying whether this constructor is responsible for initialization of virtual baseclasses or not. All destructors also need this "in-charge" flag, which additionally determines whether or not the destructor should free the memory for the object. This function adds the "in-charge" flag to member function FN if appropriate. It is called from grokclassfn and tsubst. - FN must be either a constructor or destructor. */ + FN must be either a constructor or destructor. + For vtable thunks, types with polymorphic virtual bases need an + additional "vlist" argument which is an array of virtual tables. + In addition, if backwards-compatibility to v1 thunks is requested, + a wrapper constructor may be needed as well. */ + void maybe_retrofit_in_chrg (fn) tree fn; { tree basetype, arg_types, parms, parm, fntype; + tree wrapper; + if (CLASSTYPE_IS_TEMPLATE (DECL_CLASS_CONTEXT (fn))) + /* Never retrofit arguments on template methods. */ + return; + if (DECL_CONSTRUCTOR_P (fn) && TYPE_USES_VIRTUAL_BASECLASSES (DECL_CLASS_CONTEXT (fn)) - && ! DECL_CONSTRUCTOR_FOR_VBASE_P (fn)) + && DECL_CONSTRUCTOR_FOR_VBASE (fn) == 0) /* OK */; else if (! DECL_CONSTRUCTOR_P (fn) && TREE_CHAIN (DECL_ARGUMENTS (fn)) == NULL_TREE) /* OK */; else return; if (DECL_CONSTRUCTOR_P (fn)) - DECL_CONSTRUCTOR_FOR_VBASE_P (fn) = 1; + { + if (TYPE_USES_PVBASES (DECL_CLASS_CONTEXT (fn))) + DECL_CONSTRUCTOR_FOR_VBASE (fn) = CONSTRUCTOR_FOR_PVBASE; + else + DECL_CONSTRUCTOR_FOR_VBASE (fn) = CONSTRUCTOR_FOR_VBASE; + } + else if (TYPE_USES_PVBASES (DECL_CLASS_CONTEXT (fn))) + DECL_CONSTRUCTOR_FOR_VBASE (fn) = DESTRUCTOR_FOR_PVBASE; + /* Retrieve the arguments, because it is potentially modified twice. */ + arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn)); + basetype = TREE_TYPE (TREE_VALUE (arg_types)); + arg_types = TREE_CHAIN (arg_types); + + if (DECL_CONSTRUCTOR_FOR_PVBASE_P (fn) + || DECL_DESTRUCTOR_FOR_PVBASE_P (fn)) + { + /* Add the __vlist argument first. See __in_chrg below. */ + tree id = vlist_identifier; + if (DECL_DESTRUCTOR_FOR_PVBASE_P (fn)) + id = get_identifier (VLIST1_NAME); + parm = build_decl (PARM_DECL, id, vlist_type_node); + SET_DECL_ARTIFICIAL (parm); + DECL_ARG_TYPE (parm) = vlist_type_node; + parms = DECL_ARGUMENTS (fn); + /* Add it after 'this'. */ + TREE_CHAIN (parm) = TREE_CHAIN (parms); + TREE_CHAIN (parms) = parm; + + arg_types = hash_tree_chain (vlist_type_node, arg_types); + } + /* First add it to DECL_ARGUMENTS... */ parm = build_decl (PARM_DECL, in_charge_identifier, integer_type_node); /* Mark the artificial `__in_chrg' parameter as "artificial". */ SET_DECL_ARTIFICIAL (parm); DECL_ARG_TYPE (parm) = integer_type_node; TREE_READONLY (parm) = 1; parms = DECL_ARGUMENTS (fn); TREE_CHAIN (parm) = TREE_CHAIN (parms); TREE_CHAIN (parms) = parm; /* ...and then to TYPE_ARG_TYPES. */ - arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn)); - basetype = TREE_TYPE (TREE_VALUE (arg_types)); - arg_types = hash_tree_chain (integer_type_node, TREE_CHAIN (arg_types)); + arg_types = hash_tree_chain (integer_type_node, arg_types); fntype = build_cplus_method_type (basetype, TREE_TYPE (TREE_TYPE (fn)), arg_types); if (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn))) fntype = build_exception_variant (fntype, TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn))); TREE_TYPE (fn) = fntype; + + if (flag_vtable_thunks_compat + && DECL_CONSTRUCTOR_FOR_PVBASE_P (fn)) + make_vlist_ctor_wrapper (fn); } /* Classes overload their constituent function names automatically. When a function name is declared in a record structure, its name is changed to it overloaded name. Since names for constructors and destructors can conflict, we place a leading '$' for destructors. CNAME is the name of the class we are grokking for. FUNCTION is a FUNCTION_DECL. It was created by `grokdeclarator'. FLAGS contains bits saying what's special about today's arguments. 1 == DESTRUCTOR. 2 == OPERATOR. If FUNCTION is a destructor, then we must add the `auto-delete' field as a second parameter. There is some hair associated with the fact that we must "declare" this variable in the manner consistent with the way the rest of the arguments were declared. QUALS are the qualifiers for the this pointer. */ void grokclassfn (ctype, function, flags, quals) tree ctype, function; enum overload_flags flags; tree quals; { tree fn_name = DECL_NAME (function); tree arg_types; tree parm; tree qualtype; if (fn_name == NULL_TREE) { error ("name missing for member function"); fn_name = get_identifier (""); DECL_NAME (function) = fn_name; } if (quals) qualtype = grok_method_quals (ctype, function, quals); else qualtype = ctype; arg_types = TYPE_ARG_TYPES (TREE_TYPE (function)); if (TREE_CODE (TREE_TYPE (function)) == METHOD_TYPE) { /* Must add the class instance variable up front. */ /* Right now we just make this a pointer. But later we may wish to make it special. */ tree type = TREE_VALUE (arg_types); int constp = 1; if ((flag_this_is_variable > 0) && (flags == DTOR_FLAG || DECL_CONSTRUCTOR_P (function))) constp = 0; parm = build_decl (PARM_DECL, this_identifier, type); /* Mark the artificial `this' parameter as "artificial". */ SET_DECL_ARTIFICIAL (parm); DECL_ARG_TYPE (parm) = type; /* We can make this a register, so long as we don't accidentally complain if someone tries to take its address. */ DECL_REGISTER (parm) = 1; if (constp) TREE_READONLY (parm) = 1; TREE_CHAIN (parm) = last_function_parms; last_function_parms = parm; } DECL_ARGUMENTS (function) = last_function_parms; /* First approximations. */ DECL_CONTEXT (function) = ctype; DECL_CLASS_CONTEXT (function) = ctype; if (flags == DTOR_FLAG || DECL_CONSTRUCTOR_P (function)) { maybe_retrofit_in_chrg (function); arg_types = TYPE_ARG_TYPES (TREE_TYPE (function)); } if (flags == DTOR_FLAG) { - DECL_ASSEMBLER_NAME (function) = build_destructor_name (ctype); + DECL_ASSEMBLER_NAME (function) = + build_destructor_name (ctype, DECL_DESTRUCTOR_FOR_PVBASE_P (function)); TYPE_HAS_DESTRUCTOR (ctype) = 1; } else set_mangled_name_for_decl (function); } /* Work on the expr used by alignof (this is only called by the parser). */ tree grok_alignof (expr) tree expr; { tree best, t; int bestalign; if (processing_template_decl) return build_min (ALIGNOF_EXPR, sizetype, expr); if (TREE_CODE (expr) == COMPONENT_REF && DECL_C_BIT_FIELD (TREE_OPERAND (expr, 1))) error ("`__alignof__' applied to a bit-field"); if (TREE_CODE (expr) == INDIRECT_REF) { best = t = TREE_OPERAND (expr, 0); bestalign = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (t))); while (TREE_CODE (t) == NOP_EXPR && TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) == POINTER_TYPE) { int thisalign; t = TREE_OPERAND (t, 0); thisalign = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (t))); if (thisalign > bestalign) best = t, bestalign = thisalign; } return c_alignof (TREE_TYPE (TREE_TYPE (best))); } else { /* ANSI says arrays and fns are converted inside comma. But we can't convert them in build_compound_expr because that would break commas in lvalues. So do the conversion here if operand was a comma. */ if (TREE_CODE (expr) == COMPOUND_EXPR && (TREE_CODE (TREE_TYPE (expr)) == ARRAY_TYPE || TREE_CODE (TREE_TYPE (expr)) == FUNCTION_TYPE)) expr = default_conversion (expr); return c_alignof (TREE_TYPE (expr)); } } /* Create an ARRAY_REF, checking for the user doing things backwards along the way. */ tree grok_array_decl (array_expr, index_exp) tree array_expr, index_exp; { tree type = TREE_TYPE (array_expr); tree p1, p2, i1, i2; if (type == error_mark_node || index_exp == error_mark_node) return error_mark_node; if (processing_template_decl) return build_min (ARRAY_REF, type ? TREE_TYPE (type) : NULL_TREE, array_expr, index_exp); if (type == NULL_TREE) { /* Something has gone very wrong. Assume we are mistakenly reducing an expression instead of a declaration. */ error ("parser may be lost: is there a '{' missing somewhere?"); return NULL_TREE; } if (TREE_CODE (type) == OFFSET_TYPE || TREE_CODE (type) == REFERENCE_TYPE) type = TREE_TYPE (type); /* If they have an `operator[]', use that. */ if (IS_AGGR_TYPE (type) || IS_AGGR_TYPE (TREE_TYPE (index_exp))) return build_opfncall (ARRAY_REF, LOOKUP_NORMAL, array_expr, index_exp, NULL_TREE); /* Otherwise, create an ARRAY_REF for a pointer or array type. It is a little-known fact that, if `a' is an array and `i' is an int, you can write `i[a]', which means the same thing as `a[i]'. */ if (TREE_CODE (type) == ARRAY_TYPE) p1 = array_expr; else p1 = build_expr_type_conversion (WANT_POINTER, array_expr, 0); if (TREE_CODE (TREE_TYPE (index_exp)) == ARRAY_TYPE) p2 = index_exp; else p2 = build_expr_type_conversion (WANT_POINTER, index_exp, 0); i1 = build_expr_type_conversion (WANT_INT | WANT_ENUM, array_expr, 0); i2 = build_expr_type_conversion (WANT_INT | WANT_ENUM, index_exp, 0); if ((p1 && i2) && (i1 && p2)) error ("ambiguous conversion for array subscript"); if (p1 && i2) array_expr = p1, index_exp = i2; else if (i1 && p2) array_expr = p2, index_exp = i1; else { cp_error ("invalid types `%T[%T]' for array subscript", type, TREE_TYPE (index_exp)); return error_mark_node; } if (array_expr == error_mark_node || index_exp == error_mark_node) error ("ambiguous conversion for array subscript"); return build_array_ref (array_expr, index_exp); } /* Given the cast expression EXP, checking out its validity. Either return an error_mark_node if there was an unavoidable error, return a cast to void for trying to delete a pointer w/ the value 0, or return the call to delete. If DOING_VEC is 1, we handle things differently for doing an array delete. If DOING_VEC is 2, they gave us the array size as an argument to delete. Implements ARM $5.3.4. This is called from the parser. */ tree delete_sanity (exp, size, doing_vec, use_global_delete) tree exp, size; int doing_vec, use_global_delete; { tree t, type; /* For a regular vector delete (aka, no size argument) we will pass this down as a NULL_TREE into build_vec_delete. */ tree maxindex = NULL_TREE; if (exp == error_mark_node) return exp; if (processing_template_decl) { t = build_min (DELETE_EXPR, void_type_node, exp, size); DELETE_EXPR_USE_GLOBAL (t) = use_global_delete; DELETE_EXPR_USE_VEC (t) = doing_vec; return t; } if (TREE_CODE (exp) == OFFSET_REF) exp = resolve_offset_ref (exp); exp = convert_from_reference (exp); t = stabilize_reference (exp); t = build_expr_type_conversion (WANT_POINTER, t, 1); if (t == NULL_TREE || t == error_mark_node) { cp_error ("type `%#T' argument given to `delete', expected pointer", TREE_TYPE (exp)); return error_mark_node; } if (doing_vec == 2) { maxindex = build_binary_op (MINUS_EXPR, size, integer_one_node); pedwarn ("anachronistic use of array size in vector delete"); } type = TREE_TYPE (t); /* As of Valley Forge, you can delete a pointer to const. */ /* You can't delete functions. */ if (TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE) { error ("cannot delete a function"); return error_mark_node; } /* Deleting ptr to void is undefined behaviour [expr.delete/3]. */ if (TREE_CODE (TREE_TYPE (type)) == VOID_TYPE) cp_warning ("`%T' is not a pointer-to-object type", type); /* An array can't have been allocated by new, so complain. */ if (TREE_CODE (t) == ADDR_EXPR && TREE_CODE (TREE_OPERAND (t, 0)) == VAR_DECL && TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) == ARRAY_TYPE) cp_warning ("deleting array `%#D'", TREE_OPERAND (t, 0)); /* Deleting a pointer with the value zero is valid and has no effect. */ if (integer_zerop (t)) return build1 (NOP_EXPR, void_type_node, t); if (doing_vec) return build_vec_delete (t, maxindex, integer_one_node, integer_zero_node, use_global_delete); else { if (IS_AGGR_TYPE (TREE_TYPE (type)) && TYPE_GETS_REG_DELETE (TREE_TYPE (type))) { /* Only do access checking here; we'll be calling op delete from the destructor. */ tree tmp = build_op_delete_call (DELETE_EXPR, t, size_zero_node, LOOKUP_NORMAL, NULL_TREE); if (tmp == error_mark_node) return error_mark_node; } return build_delete (type, t, integer_three_node, LOOKUP_NORMAL, use_global_delete); } } /* Report an error if the indicated template declaration is not the sort of thing that should be a member template. */ void check_member_template (tmpl) tree tmpl; { tree decl; my_friendly_assert (TREE_CODE (tmpl) == TEMPLATE_DECL, 0); decl = DECL_TEMPLATE_RESULT (tmpl); if (TREE_CODE (decl) == FUNCTION_DECL || (TREE_CODE (decl) == TYPE_DECL && IS_AGGR_TYPE (TREE_TYPE (decl)))) { if (current_function_decl) /* 14.5.2.2 [temp.mem] A local class shall not have member templates. */ cp_error ("declaration of member template `%#D' in local class", decl); if (TREE_CODE (decl) == FUNCTION_DECL && DECL_VIRTUAL_P (decl)) { /* 14.5.2.3 [temp.mem] A member function template shall not be virtual. */ cp_error ("invalid use of `virtual' in template declaration of `%#D'", decl); DECL_VIRTUAL_P (decl) = 0; } /* The debug-information generating code doesn't know what to do with member templates. */ DECL_IGNORED_P (tmpl) = 1; } else cp_error ("template declaration of `%#D'", decl); } /* Return true iff TYPE is a valid Java parameter or return type. */ static int acceptable_java_type (type) tree type; { if (TREE_CODE (type) == VOID_TYPE || TYPE_FOR_JAVA (type)) return 1; if (TREE_CODE (type) == POINTER_TYPE) { type = TREE_TYPE (type); if (TREE_CODE (type) == RECORD_TYPE) { tree args; int i; if (! TYPE_FOR_JAVA (type)) return 0; if (! CLASSTYPE_TEMPLATE_INFO (type)) return 1; args = CLASSTYPE_TI_ARGS (type); i = TREE_VEC_LENGTH (args); while (--i >= 0) { type = TREE_VEC_ELT (args, i); if (TREE_CODE (type) == POINTER_TYPE) type = TREE_TYPE (type); if (! TYPE_FOR_JAVA (type)) return 0; } return 1; } } return 0; } /* For a METHOD in a Java class CTYPE, return 1 if the parameter and return types are valid Java types. Otherwise, print appropriate error messages, and return 0. */ int check_java_method (method) tree method; { int jerr = 0; tree arg_types = TYPE_ARG_TYPES (TREE_TYPE (method)); tree ret_type = TREE_TYPE (TREE_TYPE (method)); if (! acceptable_java_type (ret_type)) { cp_error ("Java method '%D' has non-Java return type `%T'", method, ret_type); jerr++; } for (; arg_types != NULL_TREE; arg_types = TREE_CHAIN (arg_types)) { tree type = TREE_VALUE (arg_types); if (! acceptable_java_type (type)) { cp_error ("Java method '%D' has non-Java parameter type `%T'", method, type); jerr++; } } return jerr ? 0 : 1; } /* Sanity check: report error if this function FUNCTION is not really a member of the class (CTYPE) it is supposed to belong to. CNAME is the same here as it is for grokclassfn above. */ tree check_classfn (ctype, function) tree ctype, function; { tree fn_name = DECL_NAME (function); tree fndecl, fndecls; tree method_vec = CLASSTYPE_METHOD_VEC (complete_type (ctype)); tree *methods = 0; tree *end = 0; if (DECL_USE_TEMPLATE (function) && is_member_template (DECL_TI_TEMPLATE (function))) /* Since this is a specialization of a member template, we're not going to find the declaration in the class. For example, in: struct S { template void f(T); }; template <> void S::f(int); we're not going to find `S::f(int)', but there's no reason we should, either. We let our callers know we didn't find the method, but we don't complain. */ return NULL_TREE; if (method_vec != 0) { methods = &TREE_VEC_ELT (method_vec, 0); end = TREE_VEC_END (method_vec); /* First suss out ctors and dtors. */ if (*methods && fn_name == DECL_NAME (OVL_CURRENT (*methods)) && DECL_CONSTRUCTOR_P (function)) goto got_it; if (*++methods && fn_name == DECL_NAME (OVL_CURRENT (*methods)) && DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (function))) goto got_it; while (++methods != end && *methods) { fndecl = *methods; if (fn_name == DECL_NAME (OVL_CURRENT (*methods))) { got_it: for (fndecls = *methods; fndecls != NULL_TREE; fndecls = OVL_NEXT (fndecls)) { fndecl = OVL_CURRENT (fndecls); /* The DECL_ASSEMBLER_NAME for a TEMPLATE_DECL, or for a for member function of a template class, is not mangled, so the check below does not work correctly in that case. Since mangled destructor names do not include the type of the arguments, we can't use this short-cut for them, either. (It's not legal to declare arguments for a destructor, but some people try.) */ if (!DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (function)) && (DECL_ASSEMBLER_NAME (function) != DECL_NAME (function)) && (DECL_ASSEMBLER_NAME (fndecl) != DECL_NAME (fndecl)) && (DECL_ASSEMBLER_NAME (function) == DECL_ASSEMBLER_NAME (fndecl))) return fndecl; /* We cannot simply call decls_match because this doesn't work for static member functions that are pretending to be methods, and because the name may have been changed by asm("new_name"). */ if (DECL_NAME (function) == DECL_NAME (fndecl)) { tree p1 = TYPE_ARG_TYPES (TREE_TYPE (function)); tree p2 = TYPE_ARG_TYPES (TREE_TYPE (fndecl)); /* Get rid of the this parameter on functions that become static. */ if (DECL_STATIC_FUNCTION_P (fndecl) && TREE_CODE (TREE_TYPE (function)) == METHOD_TYPE) p1 = TREE_CHAIN (p1); if (same_type_p (TREE_TYPE (TREE_TYPE (function)), TREE_TYPE (TREE_TYPE (fndecl))) && compparms (p1, p2) && (DECL_TEMPLATE_SPECIALIZATION (function) == DECL_TEMPLATE_SPECIALIZATION (fndecl)) && (!DECL_TEMPLATE_SPECIALIZATION (function) || (DECL_TI_TEMPLATE (function) == DECL_TI_TEMPLATE (fndecl)))) return fndecl; } } break; /* loser */ } } } if (methods != end && *methods) { tree fndecl = *methods; cp_error ("prototype for `%#D' does not match any in class `%T'", function, ctype); cp_error_at ("candidate%s: %+#D", OVL_NEXT (fndecl) ? "s are" : " is", OVL_CURRENT (fndecl)); while (fndecl = OVL_NEXT (fndecl), fndecl) cp_error_at (" %#D", OVL_CURRENT(fndecl)); } else { methods = 0; if (TYPE_SIZE (ctype) == 0) incomplete_type_error (function, ctype); else cp_error ("no `%#D' member function declared in class `%T'", function, ctype); } /* If we did not find the method in the class, add it to avoid spurious errors (unless the CTYPE is not yet defined, in which case we'll only confuse ourselves when the function is declared properly within the class. */ if (TYPE_SIZE (ctype)) add_method (ctype, methods, function); return NULL_TREE; } /* We have just processed the DECL, which is a static data member. Its initializer, if present, is INIT. The ASMSPEC_TREE, if present, is the assembly-language name for the data member. NEED_POP and FLAGS are as for cp_finish_decl. */ void finish_static_data_member_decl (decl, init, asmspec_tree, need_pop, flags) tree decl; tree init; tree asmspec_tree; int need_pop; int flags; { char* asmspec = 0; if (asmspec_tree) asmspec = TREE_STRING_POINTER (asmspec_tree); my_friendly_assert (TREE_PUBLIC (decl), 0); /* We cannot call pushdecl here, because that would fill in the decl of our TREE_CHAIN. Instead, we modify cp_finish_decl to do the right thing, namely, to put this decl out straight away. */ /* current_class_type can be NULL_TREE in case of error. */ if (!asmspec && current_class_type) { DECL_INITIAL (decl) = error_mark_node; DECL_ASSEMBLER_NAME (decl) = build_static_name (current_class_type, DECL_NAME (decl)); } if (! processing_template_decl) { if (!pending_statics) VARRAY_TREE_INIT (pending_statics, 32, "pending_statics"); if (pending_statics_used == pending_statics->num_elements) VARRAY_GROW (pending_statics, 2 * pending_statics->num_elements); VARRAY_TREE (pending_statics, pending_statics_used) = decl; ++pending_statics_used; } /* Static consts need not be initialized in the class definition. */ if (init != NULL_TREE && TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))) { static int explanation = 0; error ("initializer invalid for static member with constructor"); if (explanation++ == 0) error ("(you really want to initialize it separately)"); init = 0; } /* Force the compiler to know when an uninitialized static const member is being used. */ if (CP_TYPE_CONST_P (TREE_TYPE (decl)) && init == 0) TREE_USED (decl) = 1; DECL_INITIAL (decl) = init; DECL_IN_AGGR_P (decl) = 1; DECL_CONTEXT (decl) = current_class_type; DECL_CLASS_CONTEXT (decl) = current_class_type; cp_finish_decl (decl, init, asmspec_tree, need_pop, flags); } /* Process the specs, declarator (NULL if omitted) and width (NULL if omitted) of a structure component, returning a FIELD_DECL node. QUALS is a list of type qualifiers for this decl (such as for declaring const member functions). This is done during the parsing of the struct declaration. The FIELD_DECL nodes are chained together and the lot of them are ultimately passed to `build_struct' to make the RECORD_TYPE node. C++: If class A defines that certain functions in class B are friends, then the way I have set things up, it is B who is interested in permission granted by A. However, it is in A's context that these declarations are parsed. By returning a void_type_node, class A does not attempt to incorporate the declarations of the friends within its structure. DO NOT MAKE ANY CHANGES TO THIS CODE WITHOUT MAKING CORRESPONDING CHANGES TO CODE IN `start_method'. */ tree grokfield (declarator, declspecs, init, asmspec_tree, attrlist) tree declarator, declspecs, init, asmspec_tree, attrlist; { register tree value; char *asmspec = 0; int flags = LOOKUP_ONLYCONVERTING; /* Convert () initializers to = initializers. */ if (init == NULL_TREE && declarator != NULL_TREE && TREE_CODE (declarator) == CALL_EXPR && TREE_OPERAND (declarator, 0) && (TREE_CODE (TREE_OPERAND (declarator, 0)) == IDENTIFIER_NODE || TREE_CODE (TREE_OPERAND (declarator, 0)) == SCOPE_REF) && parmlist_is_exprlist (TREE_OPERAND (declarator, 1))) { init = TREE_OPERAND (declarator, 1); declarator = TREE_OPERAND (declarator, 0); flags = 0; } if (declspecs == NULL_TREE && TREE_CODE (declarator) == SCOPE_REF && TREE_CODE (TREE_OPERAND (declarator, 1)) == IDENTIFIER_NODE) { /* Access declaration */ if (! IS_AGGR_TYPE_CODE (TREE_CODE (TREE_OPERAND (declarator, 0)))) ; else if (TREE_COMPLEXITY (declarator) == current_class_depth) pop_nested_class (); return do_class_using_decl (declarator); } if (init && TREE_CODE (init) == TREE_LIST && TREE_VALUE (init) == error_mark_node && TREE_CHAIN (init) == NULL_TREE) init = NULL_TREE; value = grokdeclarator (declarator, declspecs, FIELD, init != 0, attrlist); if (! value || value == error_mark_node) /* friend or constructor went bad. */ return value; /* Pass friendly classes back. */ if (TREE_CODE (value) == VOID_TYPE) return void_type_node; if (DECL_NAME (value) != NULL_TREE && IDENTIFIER_POINTER (DECL_NAME (value))[0] == '_' && ! strcmp (IDENTIFIER_POINTER (DECL_NAME (value)), "_vptr")) cp_error ("member `%D' conflicts with virtual function table field name", value); /* Stash away type declarations. */ if (TREE_CODE (value) == TYPE_DECL) { DECL_NONLOCAL (value) = 1; DECL_CONTEXT (value) = current_class_type; DECL_CLASS_CONTEXT (value) = current_class_type; /* Now that we've updated the context, we need to remangle the name for this TYPE_DECL. */ DECL_ASSEMBLER_NAME (value) = DECL_NAME (value); if (!uses_template_parms (value)) DECL_ASSEMBLER_NAME (value) = get_identifier (build_overload_name (TREE_TYPE (value), 1, 1)); return value; } if (IS_SIGNATURE (current_class_type) && TREE_CODE (value) != FUNCTION_DECL) { error ("field declaration not allowed in signature"); return void_type_node; } if (DECL_IN_AGGR_P (value)) { cp_error ("`%D' is already defined in `%T'", value, DECL_CONTEXT (value)); return void_type_node; } if (asmspec_tree) asmspec = TREE_STRING_POINTER (asmspec_tree); if (init) { if (IS_SIGNATURE (current_class_type) && TREE_CODE (value) == FUNCTION_DECL) { error ("function declarations cannot have initializers in signature"); init = NULL_TREE; } else if (TREE_CODE (value) == FUNCTION_DECL) { grok_function_init (value, init); init = NULL_TREE; } else if (pedantic && TREE_CODE (value) != VAR_DECL) /* Already complained in grokdeclarator. */ init = NULL_TREE; else { /* We allow initializers to become parameters to base initializers. */ if (TREE_CODE (init) == TREE_LIST) { if (TREE_CHAIN (init) == NULL_TREE) init = TREE_VALUE (init); else init = digest_init (TREE_TYPE (value), init, (tree *)0); } if (TREE_CODE (init) == CONST_DECL) init = DECL_INITIAL (init); else if (TREE_READONLY_DECL_P (init)) init = decl_constant_value (init); else if (TREE_CODE (init) == CONSTRUCTOR) init = digest_init (TREE_TYPE (value), init, (tree *)0); my_friendly_assert (TREE_PERMANENT (init), 192); if (init == error_mark_node) /* We must make this look different than `error_mark_node' because `decl_const_value' would mis-interpret it as only meaning that this VAR_DECL is defined. */ init = build1 (NOP_EXPR, TREE_TYPE (value), init); else if (processing_template_decl) ; else if (! TREE_CONSTANT (init)) { /* We can allow references to things that are effectively static, since references are initialized with the address. */ if (TREE_CODE (TREE_TYPE (value)) != REFERENCE_TYPE || (TREE_STATIC (init) == 0 && (TREE_CODE_CLASS (TREE_CODE (init)) != 'd' || DECL_EXTERNAL (init) == 0))) { error ("field initializer is not constant"); init = error_mark_node; } } } } /* The corresponding pop_obstacks is in cp_finish_decl. */ push_obstacks_nochange (); if (processing_template_decl && ! current_function_decl && (TREE_CODE (value) == VAR_DECL || TREE_CODE (value) == FUNCTION_DECL)) value = push_template_decl (value); if (attrlist) cplus_decl_attributes (value, TREE_PURPOSE (attrlist), TREE_VALUE (attrlist)); if (TREE_CODE (value) == VAR_DECL) { finish_static_data_member_decl (value, init, asmspec_tree, /*need_pop=*/1, flags); return value; } if (TREE_CODE (value) == FIELD_DECL) { if (asmspec) { /* This must override the asm specifier which was placed by grokclassfn. Lay this out fresh. */ DECL_RTL (value) = NULL_RTX; DECL_ASSEMBLER_NAME (value) = get_identifier (asmspec); } if (DECL_INITIAL (value) == error_mark_node) init = error_mark_node; cp_finish_decl (value, init, asmspec_tree, 1, flags); DECL_INITIAL (value) = init; DECL_IN_AGGR_P (value) = 1; return value; } if (TREE_CODE (value) == FUNCTION_DECL) { if (asmspec) { /* This must override the asm specifier which was placed by grokclassfn. Lay this out fresh. */ DECL_RTL (value) = NULL_RTX; DECL_ASSEMBLER_NAME (value) = get_identifier (asmspec); } cp_finish_decl (value, init, asmspec_tree, 1, flags); /* Pass friends back this way. */ if (DECL_FRIEND_P (value)) return void_type_node; #if 0 /* Just because a fn is declared doesn't mean we'll try to define it. */ if (current_function_decl && ! IS_SIGNATURE (current_class_type)) cp_error ("method `%#D' of local class must be defined in class body", value); #endif DECL_IN_AGGR_P (value) = 1; return value; } my_friendly_abort (21); /* NOTREACHED */ return NULL_TREE; } /* Like `grokfield', but for bitfields. WIDTH is non-NULL for bit fields only, and is an INTEGER_CST node. */ tree grokbitfield (declarator, declspecs, width) tree declarator, declspecs, width; { register tree value = grokdeclarator (declarator, declspecs, BITFIELD, 0, NULL_TREE); if (! value) return NULL_TREE; /* friends went bad. */ /* Pass friendly classes back. */ if (TREE_CODE (value) == VOID_TYPE) return void_type_node; if (TREE_CODE (value) == TYPE_DECL) { cp_error ("cannot declare `%D' to be a bitfield type", value); return NULL_TREE; } /* Usually, finish_struct_1 catches bitifields with invalid types. But, in the case of bitfields with function type, we confuse ourselves into thinking they are member functions, so we must check here. */ if (TREE_CODE (value) == FUNCTION_DECL) { cp_error ("cannot declare bitfield `%D' with funcion type", DECL_NAME (value)); return NULL_TREE; } if (IS_SIGNATURE (current_class_type)) { error ("field declaration not allowed in signature"); return void_type_node; } if (DECL_IN_AGGR_P (value)) { cp_error ("`%D' is already defined in the class %T", value, DECL_CONTEXT (value)); return void_type_node; } GNU_xref_member (current_class_name, value); if (TREE_STATIC (value)) { cp_error ("static member `%D' cannot be a bitfield", value); return NULL_TREE; } cp_finish_decl (value, NULL_TREE, NULL_TREE, 0, 0); if (width != error_mark_node) { constant_expression_warning (width); DECL_INITIAL (value) = width; SET_DECL_C_BIT_FIELD (value); } DECL_IN_AGGR_P (value) = 1; return value; } tree grokoptypename (declspecs, declarator) tree declspecs, declarator; { tree t = grokdeclarator (declarator, declspecs, TYPENAME, 0, NULL_TREE); return build_typename_overload (t); } /* When a function is declared with an initializer, do the right thing. Currently, there are two possibilities: class B { public: // initialization possibility #1. virtual void f () = 0; int g (); }; class D1 : B { public: int d1; // error, no f (); }; class D2 : B { public: int d2; void f (); }; class D3 : B { public: int d3; // initialization possibility #2 void f () = B::f; }; */ int copy_assignment_arg_p (parmtype, virtualp) tree parmtype; int virtualp ATTRIBUTE_UNUSED; { if (current_class_type == NULL_TREE) return 0; if (TREE_CODE (parmtype) == REFERENCE_TYPE) parmtype = TREE_TYPE (parmtype); if ((TYPE_MAIN_VARIANT (parmtype) == current_class_type) #if 0 /* Non-standard hack to support old Booch components. */ || (! virtualp && DERIVED_FROM_P (parmtype, current_class_type)) #endif ) return 1; return 0; } static void grok_function_init (decl, init) tree decl; tree init; { /* An initializer for a function tells how this function should be inherited. */ tree type = TREE_TYPE (decl); if (TREE_CODE (type) == FUNCTION_TYPE) cp_error ("initializer specified for non-member function `%D'", decl); #if 0 /* We'll check for this in finish_struct_1. */ else if (DECL_VINDEX (decl) == NULL_TREE) cp_error ("initializer specified for non-virtual method `%D'", decl); #endif else if (integer_zerop (init)) { #if 0 /* Mark this function as being "defined". */ DECL_INITIAL (decl) = error_mark_node; /* pure virtual destructors must be defined. */ /* pure virtual needs to be defined (as abort) only when put in vtbl. For wellformed call, it should be itself. pr4737 */ if (!DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (decl))) { extern tree abort_fndecl; /* Give this node rtl from `abort'. */ DECL_RTL (decl) = DECL_RTL (abort_fndecl); } #endif DECL_ABSTRACT_VIRTUAL_P (decl) = 1; if (DECL_NAME (decl) == ansi_opname [(int) MODIFY_EXPR]) { tree parmtype = TREE_VALUE (TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (decl)))); if (copy_assignment_arg_p (parmtype, 1)) TYPE_HAS_ABSTRACT_ASSIGN_REF (current_class_type) = 1; } } else cp_error ("invalid initializer for virtual method `%D'", decl); } void cplus_decl_attributes (decl, attributes, prefix_attributes) tree decl, attributes, prefix_attributes; { if (decl == NULL_TREE || decl == void_type_node) return; if (TREE_CODE (decl) == TEMPLATE_DECL) decl = DECL_TEMPLATE_RESULT (decl); decl_attributes (decl, attributes, prefix_attributes); if (TREE_CODE (decl) == TYPE_DECL) SET_IDENTIFIER_TYPE_VALUE (DECL_NAME (decl), TREE_TYPE (decl)); } /* CONSTRUCTOR_NAME: Return the name for the constructor (or destructor) for the specified class. Argument can be RECORD_TYPE, TYPE_DECL, or IDENTIFIER_NODE. When given a template, this routine doesn't lose the specialization. */ tree constructor_name_full (thing) tree thing; { if (TREE_CODE (thing) == TEMPLATE_TYPE_PARM || TREE_CODE (thing) == TEMPLATE_TEMPLATE_PARM || TREE_CODE (thing) == TYPENAME_TYPE) thing = TYPE_NAME (thing); else if (IS_AGGR_TYPE_CODE (TREE_CODE (thing))) { if (TYPE_WAS_ANONYMOUS (thing) && TYPE_HAS_CONSTRUCTOR (thing)) thing = DECL_NAME (OVL_CURRENT (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (thing), 0))); else thing = TYPE_NAME (thing); } if (TREE_CODE (thing) == TYPE_DECL || (TREE_CODE (thing) == TEMPLATE_DECL && TREE_CODE (DECL_TEMPLATE_RESULT (thing)) == TYPE_DECL)) thing = DECL_NAME (thing); my_friendly_assert (TREE_CODE (thing) == IDENTIFIER_NODE, 197); return thing; } /* CONSTRUCTOR_NAME: Return the name for the constructor (or destructor) for the specified class. Argument can be RECORD_TYPE, TYPE_DECL, or IDENTIFIER_NODE. When given a template, return the plain unspecialized name. */ tree constructor_name (thing) tree thing; { tree t; thing = constructor_name_full (thing); t = IDENTIFIER_TEMPLATE (thing); if (!t) return thing; return t; } /* Cache the value of this class's main virtual function table pointer in a register variable. This will save one indirection if a more than one virtual function call is made this function. */ void setup_vtbl_ptr () { extern tree base_init_expr; if (base_init_expr == 0 && DECL_CONSTRUCTOR_P (current_function_decl)) { if (processing_template_decl) add_tree (build_min_nt (CTOR_INITIALIZER, current_member_init_list, current_base_init_list)); else emit_base_init (current_class_type, 0); } } /* Record the existence of an addressable inline function. */ void mark_inline_for_output (decl) tree decl; { decl = DECL_MAIN_VARIANT (decl); if (DECL_SAVED_INLINE (decl)) return; my_friendly_assert (TREE_PERMANENT (decl), 363); DECL_SAVED_INLINE (decl) = 1; if (!saved_inlines) VARRAY_TREE_INIT (saved_inlines, 32, "saved_inlines"); if (saved_inlines_used == saved_inlines->num_elements) VARRAY_GROW (saved_inlines, 2 * saved_inlines->num_elements); VARRAY_TREE (saved_inlines, saved_inlines_used) = decl; ++saved_inlines_used; } void clear_temp_name () { temp_name_counter = 0; } /* Hand off a unique name which can be used for variable we don't really want to know about anyway, for example, the anonymous variables which are needed to make references work. Declare this thing so we can use it. The variable created will be of type TYPE. STATICP is nonzero if this variable should be static. */ tree get_temp_name (type, staticp) tree type; int staticp; { char buf[sizeof (AUTO_TEMP_FORMAT) + 20]; tree decl; int toplev = toplevel_bindings_p (); push_obstacks_nochange (); if (toplev || staticp) { end_temporary_allocation (); sprintf (buf, AUTO_TEMP_FORMAT, global_temp_name_counter++); decl = pushdecl_top_level (build_decl (VAR_DECL, get_identifier (buf), type)); } else { sprintf (buf, AUTO_TEMP_FORMAT, temp_name_counter++); decl = pushdecl (build_decl (VAR_DECL, get_identifier (buf), type)); } TREE_USED (decl) = 1; TREE_STATIC (decl) = staticp; DECL_ARTIFICIAL (decl) = 1; /* If this is a local variable, then lay out its rtl now. Otherwise, callers of this function are responsible for dealing with this variable's rtl. */ if (! toplev) { expand_decl (decl); expand_decl_init (decl); } pop_obstacks (); return decl; } /* Get a variable which we can use for multiple assignments. It is not entered into current_binding_level, because that breaks things when it comes time to do final cleanups (which take place "outside" the binding contour of the function). */ tree get_temp_regvar (type, init) tree type, init; { tree decl; decl = build_decl (VAR_DECL, NULL_TREE, type); TREE_USED (decl) = 1; DECL_REGISTER (decl) = 1; DECL_ARTIFICIAL (decl) = 1; DECL_RTL (decl) = assign_temp (type, 2, 0, 1); /* We can expand these without fear, since they cannot need constructors or destructors. */ expand_expr (build_modify_expr (decl, INIT_EXPR, init), NULL_RTX, VOIDmode, 0); return decl; } /* Hunts through the global anonymous union ANON_DECL, building appropriate VAR_DECLs. Stores cleanups on the list of ELEMS, and returns a VAR_DECL whose size is the same as the size of the ANON_DECL, if one is available. */ static tree build_anon_union_vars (anon_decl, elems, static_p, external_p) tree anon_decl; tree* elems; int static_p; int external_p; { tree type = TREE_TYPE (anon_decl); tree main_decl = NULL_TREE; tree field; for (field = TYPE_FIELDS (type); field != NULL_TREE; field = TREE_CHAIN (field)) { tree decl; if (DECL_ARTIFICIAL (field)) continue; if (TREE_CODE (field) != FIELD_DECL) { cp_pedwarn_at ("`%#D' invalid; an anonymous union can only have non-static data members", field); continue; } if (TREE_PRIVATE (field)) cp_pedwarn_at ("private member `%#D' in anonymous union", field); else if (TREE_PROTECTED (field)) cp_pedwarn_at ("protected member `%#D' in anonymous union", field); if (DECL_NAME (field) == NULL_TREE && TREE_CODE (TREE_TYPE (field)) == UNION_TYPE) { decl = build_anon_union_vars (field, elems, static_p, external_p); if (!decl) continue; } else if (DECL_NAME (field) == NULL_TREE) continue; else { decl = build_decl (VAR_DECL, DECL_NAME (field), TREE_TYPE (field)); /* tell `pushdecl' that this is not tentative. */ DECL_INITIAL (decl) = error_mark_node; TREE_PUBLIC (decl) = 0; TREE_STATIC (decl) = static_p; DECL_EXTERNAL (decl) = external_p; decl = pushdecl (decl); DECL_INITIAL (decl) = NULL_TREE; } /* Only write out one anon union element--choose the one that can hold them all. */ if (main_decl == NULL_TREE && simple_cst_equal (DECL_SIZE (decl), DECL_SIZE (anon_decl)) == 1) main_decl = decl; else /* ??? This causes there to be no debug info written out about this decl. */ TREE_ASM_WRITTEN (decl) = 1; if (DECL_NAME (field) == NULL_TREE && TREE_CODE (TREE_TYPE (field)) == UNION_TYPE) /* The remainder of the processing was already done in the recursive call. */ continue; /* If there's a cleanup to do, it belongs in the TREE_PURPOSE of the following TREE_LIST. */ *elems = scratch_tree_cons (NULL_TREE, decl, *elems); TREE_TYPE (*elems) = type; } return main_decl; } /* Finish off the processing of a UNION_TYPE structure. If there are static members, then all members are static, and must be laid out together. If the union is an anonymous union, we arrange for that as well. PUBLIC_P is nonzero if this union is not declared static. */ void finish_anon_union (anon_union_decl) tree anon_union_decl; { tree type = TREE_TYPE (anon_union_decl); tree elems = NULL_TREE; tree main_decl; int public_p = TREE_PUBLIC (anon_union_decl); int static_p = TREE_STATIC (anon_union_decl); int external_p = DECL_EXTERNAL (anon_union_decl); if (TYPE_FIELDS (type) == NULL_TREE) return; if (public_p) { error ("global anonymous unions must be declared static"); return; } main_decl = build_anon_union_vars (anon_union_decl, &elems, static_p, external_p); if (main_decl == NULL_TREE) { warning ("anonymous union with no members"); return; } if (static_p) { make_decl_rtl (main_decl, 0, toplevel_bindings_p ()); DECL_RTL (anon_union_decl) = DECL_RTL (main_decl); } /* The following call assumes that there are never any cleanups for anonymous unions--a reasonable assumption. */ expand_anon_union_decl (anon_union_decl, NULL_TREE, elems); } /* Finish processing a builtin type TYPE. It's name is NAME, its fields are in the array FIELDS. LEN is the number of elements in FIELDS minus one, or put another way, it is the maximum subscript used in FIELDS. It is given the same alignment as ALIGN_TYPE. */ void finish_builtin_type (type, name, fields, len, align_type) tree type; const char *name; tree fields[]; int len; tree align_type; { register int i; TYPE_FIELDS (type) = fields[0]; for (i = 0; i < len; i++) { layout_type (TREE_TYPE (fields[i])); DECL_FIELD_CONTEXT (fields[i]) = type; TREE_CHAIN (fields[i]) = fields[i+1]; } DECL_FIELD_CONTEXT (fields[i]) = type; DECL_CLASS_CONTEXT (fields[i]) = type; TYPE_ALIGN (type) = TYPE_ALIGN (align_type); layout_type (type); #if 0 /* not yet, should get fixed properly later */ TYPE_NAME (type) = make_type_decl (get_identifier (name), type); #else TYPE_NAME (type) = build_decl (TYPE_DECL, get_identifier (name), type); #endif TYPE_STUB_DECL (type) = TYPE_NAME (type); layout_decl (TYPE_NAME (type), 0); } /* Auxiliary functions to make type signatures for `operator new' and `operator delete' correspond to what compiler will be expecting. */ tree coerce_new_type (type) tree type; { int e1 = 0, e2 = 0; if (TREE_CODE (type) == METHOD_TYPE) type = build_function_type (TREE_TYPE (type), TREE_CHAIN (TYPE_ARG_TYPES (type))); if (! same_type_p (TREE_TYPE (type), ptr_type_node)) e1 = 1, error ("`operator new' must return type `void *'"); /* Technically the type must be `size_t', but we may not know what that is. */ if (TYPE_ARG_TYPES (type) == NULL_TREE) e1 = 1, error ("`operator new' takes type `size_t' parameter"); else if (! same_type_p (TREE_VALUE (TYPE_ARG_TYPES (type)), sizetype)) e2 = 1, error ("`operator new' takes type `size_t' as first parameter"); if (e2) type = build_function_type (ptr_type_node, tree_cons (NULL_TREE, sizetype, TREE_CHAIN (TYPE_ARG_TYPES (type)))); else if (e1) type = build_function_type (ptr_type_node, TYPE_ARG_TYPES (type)); return type; } tree coerce_delete_type (type) tree type; { int e1 = 0, e2 = 0; #if 0 e3 = 0; #endif tree arg_types = TYPE_ARG_TYPES (type); if (TREE_CODE (type) == METHOD_TYPE) { type = build_function_type (TREE_TYPE (type), TREE_CHAIN (arg_types)); arg_types = TREE_CHAIN (arg_types); } if (TREE_TYPE (type) != void_type_node) e1 = 1, error ("`operator delete' must return type `void'"); if (arg_types == NULL_TREE || ! same_type_p (TREE_VALUE (arg_types), ptr_type_node)) e2 = 1, error ("`operator delete' takes type `void *' as first parameter"); #if 0 if (arg_types && TREE_CHAIN (arg_types) && TREE_CHAIN (arg_types) != void_list_node) { /* Again, technically this argument must be `size_t', but again we may not know what that is. */ tree t2 = TREE_VALUE (TREE_CHAIN (arg_types)); if (! same_type_p (t2, sizetype)) e3 = 1, error ("second argument to `operator delete' must be of type `size_t'"); else if (TREE_CHAIN (TREE_CHAIN (arg_types)) != void_list_node) { e3 = 1; if (TREE_CHAIN (TREE_CHAIN (arg_types))) error ("too many arguments in declaration of `operator delete'"); else error ("`...' invalid in specification of `operator delete'"); } } if (e3) arg_types = tree_cons (NULL_TREE, ptr_type_node, build_tree_list (NULL_TREE, sizetype)); else if (e3 |= e2) { if (arg_types == NULL_TREE) arg_types = tree_cons (NULL_TREE, ptr_type_node, void_list_node); else arg_types = tree_cons (NULL_TREE, ptr_type_node, TREE_CHAIN (arg_types)); } else e3 |= e1; #endif if (e2) arg_types = tree_cons (NULL_TREE, ptr_type_node, arg_types ? TREE_CHAIN (arg_types): NULL_TREE); if (e2 || e1) type = build_function_type (void_type_node, arg_types); return type; } extern tree abort_fndecl; static void mark_vtable_entries (decl) tree decl; { tree entries = CONSTRUCTOR_ELTS (DECL_INITIAL (decl)); for (; entries; entries = TREE_CHAIN (entries)) { tree fnaddr; tree fn; fnaddr = (flag_vtable_thunks ? TREE_VALUE (entries) : FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (entries))); if (TREE_CODE (fnaddr) == NOP_EXPR) /* RTTI offset. */ continue; fn = TREE_OPERAND (fnaddr, 0); TREE_ADDRESSABLE (fn) = 1; if (DECL_LANG_SPECIFIC (fn) && DECL_ABSTRACT_VIRTUAL_P (fn)) { TREE_OPERAND (fnaddr, 0) = fn = copy_node (fn); DECL_RTL (fn) = DECL_RTL (abort_fndecl); mark_used (abort_fndecl); } if (TREE_CODE (fn) == THUNK_DECL && DECL_EXTERNAL (fn)) { DECL_EXTERNAL (fn) = 0; emit_thunk (fn); } mark_used (fn); } } /* Set DECL up to have the closest approximation of "initialized common" linkage available. */ void comdat_linkage (decl) tree decl; { if (flag_weak) make_decl_one_only (decl); else if (TREE_CODE (decl) == FUNCTION_DECL || DECL_VIRTUAL_P (decl)) /* We can just emit functions and vtables statically; it doesn't really matter if we have multiple copies. */ TREE_PUBLIC (decl) = 0; else { /* Static data member template instantiations, however, cannot have multiple copies. */ if (DECL_INITIAL (decl) == 0 || DECL_INITIAL (decl) == error_mark_node) DECL_COMMON (decl) = 1; else if (EMPTY_CONSTRUCTOR_P (DECL_INITIAL (decl))) { DECL_COMMON (decl) = 1; DECL_INITIAL (decl) = error_mark_node; } else { /* We can't do anything useful; leave vars for explicit instantiation. */ DECL_EXTERNAL (decl) = 1; DECL_NOT_REALLY_EXTERN (decl) = 0; } } if (DECL_LANG_SPECIFIC (decl)) DECL_COMDAT (decl) = 1; } /* For win32 we also want to put explicit instantiations in linkonce sections, so that they will be merged with implicit instantiations; otherwise we get duplicate symbol errors. */ void maybe_make_one_only (decl) tree decl; { /* We used to say that this was not necessary on targets that support weak symbols, because the implicit instantiations will defer to the explicit one. However, that's not actually the case in SVR4; a strong definition after a weak one is an error. Also, not making explicit instantiations one_only means that we can end up with two copies of some template instantiations. */ if (! supports_one_only ()) return; /* We can't set DECL_COMDAT on functions, or finish_file will think we can get away with not emitting them if they aren't used. We need to for variables so that cp_finish_decl will update their linkage, because their DECL_INITIAL may not have been set properly yet. */ make_decl_one_only (decl); if (TREE_CODE (decl) == VAR_DECL && DECL_LANG_SPECIFIC (decl)) DECL_COMDAT (decl) = 1; } /* Set TREE_PUBLIC and/or DECL_EXTERN on the vtable DECL, based on TYPE and other static flags. Note that anything public is tagged TREE_PUBLIC, whether it's public in this file or in another one. */ void import_export_vtable (decl, type, final) tree decl, type; int final; { if (DECL_INTERFACE_KNOWN (decl)) return; if (TYPE_FOR_JAVA (type)) { TREE_PUBLIC (decl) = 1; DECL_EXTERNAL (decl) = 1; DECL_INTERFACE_KNOWN (decl) = 1; } else if (CLASSTYPE_INTERFACE_KNOWN (type)) { TREE_PUBLIC (decl) = 1; DECL_EXTERNAL (decl) = ! CLASSTYPE_VTABLE_NEEDS_WRITING (type); DECL_INTERFACE_KNOWN (decl) = 1; } else { /* We can only wait to decide if we have real non-inline virtual functions in our class, or if we come from a template. */ int found = CLASSTYPE_TEMPLATE_INSTANTIATION (type); if (! found && ! final) { tree method; for (method = TYPE_METHODS (type); method != NULL_TREE; method = TREE_CHAIN (method)) if (DECL_VINDEX (method) != NULL_TREE && ! DECL_THIS_INLINE (method) && ! DECL_ABSTRACT_VIRTUAL_P (method)) { found = 1; break; } } if (final || ! found) { comdat_linkage (decl); DECL_EXTERNAL (decl) = 0; } else { TREE_PUBLIC (decl) = 1; DECL_EXTERNAL (decl) = 1; } } } /* Determine whether or not we want to specifically import or export CTYPE, using various heuristics. */ void import_export_class (ctype) tree ctype; { /* -1 for imported, 1 for exported. */ int import_export = 0; if (CLASSTYPE_INTERFACE_KNOWN (ctype)) return; /* If MULTIPLE_SYMBOL_SPACES is defined and we saw a #pragma interface, we will have CLASSTYPE_INTERFACE_ONLY set but not CLASSTYPE_INTERFACE_KNOWN. In that case, we don't want to use this heuristic because someone will supply a #pragma implementation elsewhere, and deducing it here would produce a conflict. */ if (CLASSTYPE_INTERFACE_ONLY (ctype)) return; #ifdef VALID_MACHINE_TYPE_ATTRIBUTE /* FIXME this should really use some sort of target-independent macro. */ if (lookup_attribute ("dllimport", TYPE_ATTRIBUTES (ctype))) import_export = -1; else if (lookup_attribute ("dllexport", TYPE_ATTRIBUTES (ctype))) import_export = 1; #endif /* If we got -fno-implicit-templates, we import template classes that weren't explicitly instantiated. */ if (import_export == 0 && CLASSTYPE_IMPLICIT_INSTANTIATION (ctype) && ! flag_implicit_templates) import_export = -1; /* Base our import/export status on that of the first non-inline, non-abstract virtual function, if any. */ if (import_export == 0 && TYPE_VIRTUAL_P (ctype) && ! CLASSTYPE_TEMPLATE_INSTANTIATION (ctype)) { tree method; for (method = TYPE_METHODS (ctype); method != NULL_TREE; method = TREE_CHAIN (method)) { if (DECL_VINDEX (method) != NULL_TREE && !DECL_THIS_INLINE (method) && !DECL_ABSTRACT_VIRTUAL_P (method)) { import_export = (DECL_REALLY_EXTERN (method) ? -1 : 1); break; } } } #ifdef MULTIPLE_SYMBOL_SPACES if (import_export == -1) import_export = 0; #endif if (import_export) { SET_CLASSTYPE_INTERFACE_KNOWN (ctype); CLASSTYPE_VTABLE_NEEDS_WRITING (ctype) = (import_export > 0); CLASSTYPE_INTERFACE_ONLY (ctype) = (import_export < 0); } } /* We need to describe to the assembler the relationship between a vtable and the vtable of the parent class. */ static void output_vtable_inherit (vars) tree vars; { tree parent; rtx op[2]; op[0] = XEXP (DECL_RTL (vars), 0); /* strip the mem ref */ parent = binfo_for_vtable (vars); if (parent == TYPE_BINFO (DECL_CONTEXT (vars))) op[1] = const0_rtx; else if (parent) { parent = TYPE_BINFO_VTABLE (BINFO_TYPE (parent)); op[1] = XEXP (DECL_RTL (parent), 0); /* strip the mem ref */ } else my_friendly_abort (980826); output_asm_insn (".vtable_inherit %c0, %c1", op); } static int finish_vtable_vardecl (t, data) tree *t; void *data ATTRIBUTE_UNUSED; { tree vars = *t; tree ctype = DECL_CONTEXT (vars); import_export_class (ctype); import_export_vtable (vars, ctype, 1); if (! DECL_EXTERNAL (vars) && (DECL_INTERFACE_KNOWN (vars) || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (vars)) || (hack_decl_function_context (vars) && TREE_USED (vars))) && ! TREE_ASM_WRITTEN (vars)) { /* Write it out. */ mark_vtable_entries (vars); if (TREE_TYPE (DECL_INITIAL (vars)) == 0) store_init_value (vars, DECL_INITIAL (vars)); if (write_symbols == DWARF_DEBUG || write_symbols == DWARF2_DEBUG) { /* Mark the VAR_DECL node representing the vtable itself as a "gratuitous" one, thereby forcing dwarfout.c to ignore it. It is rather important that such things be ignored because any effort to actually generate DWARF for them will run into trouble when/if we encounter code like: #pragma interface struct S { virtual void member (); }; because the artificial declaration of the vtable itself (as manufactured by the g++ front end) will say that the vtable is a static member of `S' but only *after* the debug output for the definition of `S' has already been output. This causes grief because the DWARF entry for the definition of the vtable will try to refer back to an earlier *declaration* of the vtable as a static member of `S' and there won't be one. We might be able to arrange to have the "vtable static member" attached to the member list for `S' before the debug info for `S' get written (which would solve the problem) but that would require more intrusive changes to the g++ front end. */ DECL_IGNORED_P (vars) = 1; } /* Always make vtables weak. */ if (flag_weak) comdat_linkage (vars); rest_of_decl_compilation (vars, NULL_PTR, 1, 1); if (flag_vtable_gc) output_vtable_inherit (vars); return 1; } else if (! TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (vars))) /* We don't know what to do with this one yet. */ return 0; *t = TREE_CHAIN (vars); return 0; } static int prune_vtable_vardecl (t, data) tree *t; void *data ATTRIBUTE_UNUSED; { *t = TREE_CHAIN (*t); return 1; } static int finish_sigtable_vardecl (t, data) tree *t; void *data ATTRIBUTE_UNUSED; { /* We don't need to mark sigtable entries as addressable here as is done for vtables. Since sigtables, unlike vtables, are always written out, that was already done in build_signature_table_constructor. */ rest_of_decl_compilation (*t, NULL_PTR, 1, 1); *t = TREE_CHAIN (*t); return 1; } /* Determines the proper settings of TREE_PUBLIC and DECL_EXTERNAL for an inline function or template instantiation at end-of-file. */ void import_export_decl (decl) tree decl; { if (DECL_INTERFACE_KNOWN (decl)) return; if (DECL_TEMPLATE_INSTANTIATION (decl) || DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (decl)) { DECL_NOT_REALLY_EXTERN (decl) = 1; if ((DECL_IMPLICIT_INSTANTIATION (decl) || DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (decl)) && (flag_implicit_templates || (flag_implicit_inline_templates && DECL_THIS_INLINE (decl)))) { if (!TREE_PUBLIC (decl)) /* Templates are allowed to have internal linkage. See [basic.link]. */ ; else comdat_linkage (decl); } else DECL_NOT_REALLY_EXTERN (decl) = 0; } else if (DECL_FUNCTION_MEMBER_P (decl)) { tree ctype = DECL_CLASS_CONTEXT (decl); import_export_class (ctype); if (CLASSTYPE_INTERFACE_KNOWN (ctype) && (! DECL_ARTIFICIAL (decl) || DECL_VINDEX (decl))) { DECL_NOT_REALLY_EXTERN (decl) = ! (CLASSTYPE_INTERFACE_ONLY (ctype) || (DECL_THIS_INLINE (decl) && ! flag_implement_inlines && !DECL_VINDEX (decl))); /* Always make artificials weak. */ if (DECL_ARTIFICIAL (decl) && flag_weak) comdat_linkage (decl); else maybe_make_one_only (decl); } else comdat_linkage (decl); } else if (DECL_TINFO_FN_P (decl)) { tree ctype = TREE_TYPE (DECL_NAME (decl)); if (IS_AGGR_TYPE (ctype)) import_export_class (ctype); if (IS_AGGR_TYPE (ctype) && CLASSTYPE_INTERFACE_KNOWN (ctype) && TYPE_VIRTUAL_P (ctype) /* If the type is a cv-qualified variant of a type, then we must emit the tinfo function in this translation unit since it will not be emitted when the vtable for the type is output (which is when the unqualified version is generated). */ && same_type_p (ctype, TYPE_MAIN_VARIANT (ctype))) { DECL_NOT_REALLY_EXTERN (decl) = ! (CLASSTYPE_INTERFACE_ONLY (ctype) || (DECL_THIS_INLINE (decl) && ! flag_implement_inlines && !DECL_VINDEX (decl))); /* Always make artificials weak. */ if (flag_weak) comdat_linkage (decl); } else if (TYPE_BUILT_IN (ctype) && same_type_p (ctype, TYPE_MAIN_VARIANT (ctype))) DECL_NOT_REALLY_EXTERN (decl) = 0; else comdat_linkage (decl); } else comdat_linkage (decl); DECL_INTERFACE_KNOWN (decl) = 1; } tree build_cleanup (decl) tree decl; { tree temp; tree type = TREE_TYPE (decl); if (TREE_CODE (type) == ARRAY_TYPE) temp = decl; else { mark_addressable (decl); temp = build1 (ADDR_EXPR, build_pointer_type (type), decl); } temp = build_delete (TREE_TYPE (temp), temp, integer_two_node, LOOKUP_NORMAL|LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR, 0); return temp; } extern int parse_time, varconst_time; static tree get_sentry (base) tree base; { tree sname = get_id_2 ("__sn", base); /* For struct X foo __attribute__((weak)), there is a counter __snfoo. Since base is already an assembler name, sname should be globally unique */ tree sentry = IDENTIFIER_GLOBAL_VALUE (sname); if (! sentry) { push_obstacks_nochange (); end_temporary_allocation (); sentry = build_decl (VAR_DECL, sname, integer_type_node); TREE_PUBLIC (sentry) = 1; DECL_ARTIFICIAL (sentry) = 1; TREE_STATIC (sentry) = 1; TREE_USED (sentry) = 1; DECL_COMMON (sentry) = 1; pushdecl_top_level (sentry); cp_finish_decl (sentry, NULL_TREE, NULL_TREE, 0, 0); pop_obstacks (); } return sentry; } /* Start the process of running a particular set of global constructors or destructors. Subroutine of do_[cd]tors. */ static void start_objects (method_type, initp) int method_type, initp; { tree fnname; char type[10]; /* Make ctor or dtor function. METHOD_TYPE may be 'I' or 'D'. */ if (initp != DEFAULT_INIT_PRIORITY) { char joiner; #ifdef JOINER joiner = JOINER; #else joiner = '_'; #endif sprintf (type, "%c%c%.5u", method_type, joiner, initp); } else sprintf (type, "%c", method_type); fnname = get_file_function_name_long (type); start_function (void_list_node, make_call_declarator (fnname, void_list_node, NULL_TREE, NULL_TREE), NULL_TREE, 0); #if defined(ASM_OUTPUT_CONSTRUCTOR) && defined(ASM_OUTPUT_DESTRUCTOR) /* It can be a static function as long as collect2 does not have to scan the object file to find its ctor/dtor routine. */ TREE_PUBLIC (current_function_decl) = 0; #endif store_parm_decls (); pushlevel (0); clear_last_expr (); push_momentary (); expand_start_bindings (0); /* We cannot allow these functions to be elided, even if they do not have external linkage. And, there's no point in deferring copmilation of thes functions; they're all going to have to be out anyhow. */ current_function_cannot_inline = "static constructors and destructors cannot be inlined"; } /* Finish the process of running a particular set of global constructors or destructors. Subroutine of do_[cd]tors. */ static void finish_objects (method_type, initp) int method_type, initp; { char *fnname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0); /* Finish up. */ expand_end_bindings (getdecls (), 1, 0); poplevel (1, 0, 0); pop_momentary (); finish_function (lineno, 0, 0); if (initp == DEFAULT_INIT_PRIORITY) { if (method_type == 'I') assemble_constructor (fnname); else assemble_destructor (fnname); } #if defined (ASM_OUTPUT_SECTION_NAME) && defined (ASM_OUTPUT_CONSTRUCTOR) /* If we're using init priority we can't use assemble_*tor, but on ELF targets we can stick the references into named sections for GNU ld to collect. */ else { char buf[15]; sprintf (buf, ".%ctors.%.5u", method_type == 'I' ? 'c' : 'd', /* invert the numbering so the linker puts us in the proper order; constructors are run from right to left, and the linker sorts in increasing order. */ MAX_INIT_PRIORITY - initp); named_section (NULL_TREE, buf, 0); assemble_integer (gen_rtx_SYMBOL_REF (Pmode, fnname), POINTER_SIZE / BITS_PER_UNIT, 1); } #endif } /* The names of the parameters to the function created to handle initializations and destructions for objects with static storage duration. */ #define INITIALIZE_P_IDENTIFIER "__initialize_p" #define PRIORITY_IDENTIFIER "__priority" /* The name of the function we create to handle initializations and destructions for objects with static storage duration. */ #define SSDF_IDENTIFIER "__static_initialization_and_destruction" /* The declaration for the __INITIALIZE_P argument. */ static tree initialize_p_decl; /* The declaration for the __PRIORITY argument. */ static tree priority_decl; /* The declaration for the static storage duration function. */ static tree ssdf_decl; /* All the static storage duration functions created in this translation unit. */ static varray_type ssdf_decls; static size_t ssdf_decls_used; /* A map from priority levels to information about that priority level. There may be many such levels, so efficient lookup is important. */ static splay_tree priority_info_map; /* Begins the generation of the function that will handle all initialization and destruction of objects with static storage duration. The function generated takes two parameters of type `int': __INITIALIZE_P and __PRIORITY. If __INITIALIZE_P is non-zero, it performs initializations. Otherwise, it performs destructions. It only performs those initializations or destructions with the indicated __PRIORITY. The generated function returns no value. It is assumed that this function will only be called once per translation unit. */ static void start_static_storage_duration_function () { static unsigned ssdf_number; tree parm_types; tree type; char id[sizeof (SSDF_IDENTIFIER) + 1 /* '\0' */ + 32]; /* Create the identifier for this function. It will be of the form SSDF_IDENTIFIER_. */ sprintf (id, "%s_%u", SSDF_IDENTIFIER, ssdf_number++); if (ssdf_number == 0) { /* Overflow occurred. That means there are at least 4 billion initialization functions. */ sorry ("too many initialization functions required"); my_friendly_abort (19990430); } /* Create the parameters. */ parm_types = void_list_node; parm_types = perm_tree_cons (NULL_TREE, integer_type_node, parm_types); parm_types = perm_tree_cons (NULL_TREE, integer_type_node, parm_types); type = build_function_type (void_type_node, parm_types); /* Create the FUNCTION_DECL itself. */ ssdf_decl = build_lang_decl (FUNCTION_DECL, get_identifier (id), type); TREE_PUBLIC (ssdf_decl) = 0; DECL_ARTIFICIAL (ssdf_decl) = 1; /* Put this function in the list of functions to be called from the static constructors and destructors. */ if (!ssdf_decls) { VARRAY_TREE_INIT (ssdf_decls, 32, "ssdf_decls"); /* Take this opportunity to initialize the map from priority numbers to information about that priority level. */ priority_info_map = splay_tree_new (splay_tree_compare_ints, /*delete_key_fn=*/0, /*delete_value_fn=*/ (splay_tree_delete_value_fn) &free); /* We always need to generate functions for the DEFAULT_INIT_PRIORITY so enter it now. That way when we walk priorities later, we'll be sure to find the DEFAULT_INIT_PRIORITY. */ get_priority_info (DEFAULT_INIT_PRIORITY); } if (ssdf_decls_used == ssdf_decls->num_elements) VARRAY_GROW (ssdf_decls, 2 * ssdf_decls_used); VARRAY_TREE (ssdf_decls, ssdf_decls_used) = ssdf_decl; ++ssdf_decls_used; /* Create the argument list. */ initialize_p_decl = build_decl (PARM_DECL, get_identifier (INITIALIZE_P_IDENTIFIER), integer_type_node); DECL_CONTEXT (initialize_p_decl) = ssdf_decl; DECL_ARG_TYPE (initialize_p_decl) = integer_type_node; TREE_USED (initialize_p_decl) = 1; priority_decl = build_decl (PARM_DECL, get_identifier (PRIORITY_IDENTIFIER), integer_type_node); DECL_CONTEXT (priority_decl) = ssdf_decl; DECL_ARG_TYPE (priority_decl) = integer_type_node; TREE_USED (priority_decl) = 1; TREE_CHAIN (initialize_p_decl) = priority_decl; DECL_ARGUMENTS (ssdf_decl) = initialize_p_decl; /* Start the function itself. This is equivalent to declarating the function as: static void __ssdf (int __initialize_p, init __priority_p); It is static because we only need to call this function from the various constructor and destructor functions for this module. */ start_function (/*specs=*/NULL_TREE, ssdf_decl, /*attrs=*/NULL_TREE, /*pre_parsed_p=*/1); /* Set up the scope of the outermost block in the function. */ store_parm_decls (); pushlevel (0); clear_last_expr (); push_momentary (); expand_start_bindings (0); /* This function must not be deferred because we are depending on its compilation to tell us what is TREE_SYMBOL_REFERENCED. */ current_function_cannot_inline = "static storage duration functions cannot be inlined"; } /* Generate the initialization code for the priority indicated in N. */ static int generate_inits_for_priority (n, data) splay_tree_node n; void *data ATTRIBUTE_UNUSED; { int priority = (int) n->key; priority_info pi = (priority_info) n->value; /* For each priority N which has been used generate code which looks like: if (__priority == N) { if (__initialize_p) ... else ... } We use the sequences we've accumulated to fill in the `...'s. */ expand_start_cond (build_binary_op (EQ_EXPR, priority_decl, build_int_2 (priority, 0)), /*exit_flag=*/0); /* Do the initializations. */ expand_start_cond (build_binary_op (NE_EXPR, initialize_p_decl, integer_zero_node), /*exit_flag=*/0); if (pi->initialization_sequence) { rtx insns; push_to_sequence (pi->initialization_sequence); insns = gen_sequence (); end_sequence (); emit_insn (insns); pi->initialization_sequence = NULL_RTX; pi->initializations_p = 1; } /* Do the destructions. */ expand_start_else (); if (pi->destruction_sequence) { rtx insns; push_to_sequence (pi->destruction_sequence); insns = gen_sequence (); end_sequence (); emit_insn (insns); pi->destruction_sequence = NULL_RTX; pi->destructions_p = 1; } /* Close out the conditionals. */ expand_end_cond (); expand_end_cond (); /* Don't stop iterating. */ return 0; } /* Finish the generation of the function which performs initialization and destruction of objects with static storage duration. After this point, no more such objects can be created. */ static void finish_static_storage_duration_function () { splay_tree_foreach (priority_info_map, generate_inits_for_priority, /*data=*/0); /* Close out the function. */ expand_end_bindings (getdecls (), 1, 0); poplevel (1, 0, 0); pop_momentary (); finish_function (lineno, 0, 0); } /* Return the information about the indicated PRIORITY level. If no code to handle this level has yet been generated, generate the appropriate prologue. */ static priority_info get_priority_info (priority) int priority; { priority_info pi; splay_tree_node n; n = splay_tree_lookup (priority_info_map, (splay_tree_key) priority); if (!n) { /* Create a new priority information structure, and insert it into the map. */ pi = (priority_info) xmalloc (sizeof (struct priority_info_s)); pi->initialization_sequence = NULL_RTX; pi->destruction_sequence = NULL_RTX; pi->initializations_p = 0; pi->destructions_p = 0; splay_tree_insert (priority_info_map, (splay_tree_key) priority, (splay_tree_value) pi); } else pi = (priority_info) n->value; return pi; } /* Generate code to do the static initialization of DECL. The initialization is INIT. If DECL may be initialized more than once in different object files, SENTRY is the guard variable to check. PRIORITY is the priority for the initialization. */ static void do_static_initialization (decl, init, sentry, priority) tree decl; tree init; tree sentry; int priority; { priority_info pi; /* Get the priority information for this PRIORITY, */ pi = get_priority_info (priority); if (!pi->initialization_sequence) start_sequence (); else push_to_sequence (pi->initialization_sequence); /* Tell the debugger that we are at the location of the static variable in question. */ emit_note (input_filename, lineno); /* If there's a SENTRY, we only do the initialization if it is zero, i.e., if we are the first to initialize it. */ if (sentry) expand_start_cond (build_binary_op (EQ_EXPR, build_unary_op (PREINCREMENT_EXPR, sentry, /*noconvert=*/0), integer_one_node), /*exit_flag=*/0); /* Prepare a binding level for temporaries created during the initialization. */ expand_start_target_temps (); if (IS_AGGR_TYPE (TREE_TYPE (decl)) || TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE) expand_aggr_init (decl, init, 0); else if (TREE_CODE (init) == TREE_VEC) expand_expr (expand_vec_init (decl, TREE_VEC_ELT (init, 0), TREE_VEC_ELT (init, 1), TREE_VEC_ELT (init, 2), 0), const0_rtx, VOIDmode, EXPAND_NORMAL); else expand_assignment (decl, init, 0, 0); /* The expression might have involved increments and decrements. */ emit_queue (); /* Cleanup any temporaries needed for the initial value. */ expand_end_target_temps (); /* Cleanup any deferred pops from function calls. This would be done by expand_end_cond, but we also need it when !SENTRY, since we are constructing these sequences by parts. */ do_pending_stack_adjust (); /* Close the conditional opened above. */ if (sentry) expand_end_cond (); /* Save the sequence for later use. */ pi->initialization_sequence = get_insns (); end_sequence (); } /* Generate code to do the static destruction of DECL. If DECL may be initialized more than once in different object files, SENTRY is the guard variable to check. PRIORITY is the priority for the destruction. */ static void do_static_destruction (decl, sentry, priority) tree decl; tree sentry; int priority; { rtx new_insns; priority_info pi; /* If we don't need a destructor, there's nothing to do. */ if (!TYPE_NEEDS_DESTRUCTOR (TREE_TYPE (decl))) return; /* Get the priority information for this PRIORITY, */ pi = get_priority_info (priority); if (!pi->destruction_sequence) start_sequence (); else push_to_sequence (pi->destruction_sequence); /* Start a new sequence to handle just this destruction. */ start_sequence (); /* Tell the debugger that we are at the location of the static variable in question. */ emit_note (input_filename, lineno); /* If there's a SENTRY, we only do the destruction if it is one, i.e., if we are the last to destroy it. */ if (sentry) expand_start_cond (build_binary_op (EQ_EXPR, build_unary_op (PREDECREMENT_EXPR, sentry, /*nonconvert=*/1), integer_zero_node), /*exit_flag=*/0); /* Actually to the destruction. */ expand_expr_stmt (build_cleanup (decl)); /* Cleanup any deferred pops from function calls. This would be done by expand_end_cond, but we also need it when !SENTRY, since we are constructing these sequences by parts. */ do_pending_stack_adjust (); /* Close the conditional opened above. */ if (sentry) expand_end_cond (); /* Insert the NEW_INSNS before the current insns. (Destructions are run in reverse order of initializations.) */ new_insns = gen_sequence (); end_sequence (); if (pi->destruction_sequence) emit_insn_before (new_insns, pi->destruction_sequence); else emit_insn (new_insns); /* Save the sequence for later use. */ pi->destruction_sequence = get_insns (); end_sequence (); } /* Add code to the static storage duration function that will handle DECL (a static variable that needs initializing and/or destruction) with the indicated PRIORITY. If DECL needs initializing, INIT is the initializer. */ static void do_static_initialization_and_destruction (decl, init) tree decl; tree init; { tree sentry = NULL_TREE; int priority; /* Deal gracefully with error. */ if (decl == error_mark_node) return; /* The only things that can be initialized are variables. */ my_friendly_assert (TREE_CODE (decl) == VAR_DECL, 19990420); /* If this object is not defined, we don't need to do anything here. */ if (DECL_EXTERNAL (decl)) return; /* Also, if the initializer already contains errors, we can bail out now. */ if (init && TREE_CODE (init) == TREE_LIST && value_member (error_mark_node, init)) return; /* Trick the compiler into thinking we are at the file and line where DECL was declared so that error-messages make sense, and so that the debugger will show somewhat sensible file and line information. */ input_filename = DECL_SOURCE_FILE (decl); lineno = DECL_SOURCE_LINE (decl); /* Because of: [class.access.spec] Access control for implicit calls to the constructors, the conversion functions, or the destructor called to create and destroy a static data member is performed as if these calls appeared in the scope of the member's class. we pretend we are in a static member function of the class of which the DECL is a member. */ if (member_p (decl)) { DECL_CLASS_CONTEXT (current_function_decl) = DECL_CONTEXT (decl); DECL_STATIC_FUNCTION_P (current_function_decl) = 1; } /* We need a sentry if this is an object with external linkage that might be initialized in more than one place. */ if (TREE_PUBLIC (decl) && (DECL_COMMON (decl) || DECL_ONE_ONLY (decl) || DECL_WEAK (decl))) sentry = get_sentry (DECL_ASSEMBLER_NAME (decl)); /* Generate the code to actually do the intialization and destruction. */ priority = DECL_INIT_PRIORITY (decl); if (!priority) priority = DEFAULT_INIT_PRIORITY; do_static_initialization (decl, init, sentry, priority); do_static_destruction (decl, sentry, priority); /* Now that we're done with DECL we don't need to pretend to be a member of its class any longer. */ DECL_CLASS_CONTEXT (current_function_decl) = NULL_TREE; DECL_STATIC_FUNCTION_P (current_function_decl) = 0; } /* Generate a static constructor (if CONSTRUCTOR_P) or destructor (otherwise) that will initialize all gobal objects with static storage duration having the indicated PRIORITY. */ static void generate_ctor_or_dtor_function (constructor_p, priority) int constructor_p; int priority; { char function_key; tree arguments; size_t i; /* We use `I' to indicate initialization and `D' to indicate destruction. */ if (constructor_p) function_key = 'I'; else function_key = 'D'; /* Begin the function. */ start_objects (function_key, priority); /* Call the static storage duration function with appropriate arguments. */ for (i = 0; i < ssdf_decls_used; ++i) { arguments = tree_cons (NULL_TREE, build_int_2 (priority, 0), NULL_TREE); arguments = tree_cons (NULL_TREE, build_int_2 (constructor_p, 0), arguments); expand_expr_stmt (build_function_call (VARRAY_TREE (ssdf_decls, i), arguments)); } /* If we're generating code for the DEFAULT_INIT_PRIORITY, throw in calls to any functions marked with attributes indicating that they should be called at initialization- or destruction-time. */ if (priority == DEFAULT_INIT_PRIORITY) { tree fns; for (fns = constructor_p ? static_ctors : static_dtors; fns; fns = TREE_CHAIN (fns)) expand_expr_stmt (build_function_call (TREE_VALUE (fns), NULL_TREE)); } /* Close out the function. */ finish_objects (function_key, priority); } /* Generate constructor and destructor functions for the priority indicated by N. */ static int generate_ctor_and_dtor_functions_for_priority (n, data) splay_tree_node n; void *data ATTRIBUTE_UNUSED; { int priority = (int) n->key; priority_info pi = (priority_info) n->value; /* Generate the functions themselves, but only if they are really needed. */ if (pi->initializations_p || (priority == DEFAULT_INIT_PRIORITY && static_ctors)) generate_ctor_or_dtor_function (/*constructor_p=*/1, priority); if (pi->destructions_p || (priority == DEFAULT_INIT_PRIORITY && static_dtors)) generate_ctor_or_dtor_function (/*constructor_p=*/0, priority); /* Keep iterating. */ return 0; } /* This routine is called from the last rule in yyparse (). Its job is to create all the code needed to initialize and destroy the global aggregates. We do the destruction first, since that way we only need to reverse the decls once. */ void finish_file () { extern int lineno; int start_time, this_time; tree vars; int reconsider; size_t i; at_eof = 1; /* Bad parse errors. Just forget about it. */ if (! global_bindings_p () || current_class_type || decl_namespace_list) return; start_time = get_run_time (); /* Otherwise, GDB can get confused, because in only knows about source for LINENO-1 lines. */ lineno -= 1; interface_unknown = 1; interface_only = 0; /* We now have to write out all the stuff we put off writing out. These include: o Template specializations that we have not yet instantiated, but which are needed. o Initialization and destruction for non-local objects with static storage duration. (Local objects with static storage duration are initialized when their scope is first entered, and are cleaned up via atexit.) o Virtual function tables. All of these may cause others to be needed. For example, instantiating one function may cause another to be needed, and generating the intiailzer for an object may cause templates to be instantiated, etc., etc. */ this_time = get_run_time (); parse_time -= this_time - start_time; varconst_time += this_time - start_time; start_time = get_run_time (); permanent_allocation (1); do { /* Non-zero if we need a static storage duration function on this iteration through the loop. */ int need_ssdf_p = 0; reconsider = 0; /* If there are templates that we've put off instantiating, do them now. */ instantiate_pending_templates (); /* Write out signature-tables and virtual tables as required. Note that writing out the virtual table for a template class may cause the instantiation of members of that class. */ if (flag_handle_signatures && walk_globals (sigtable_decl_p, finish_sigtable_vardecl, /*data=*/0)) reconsider = 1; if (walk_globals (vtable_decl_p, finish_vtable_vardecl, /*data=*/0)) reconsider = 1; /* The list of objects with static storage duration is built up in reverse order, so we reverse it here. We also clear STATIC_AGGREGATES so that any new aggregates added during the initialization of these will be initialized in the correct order when we next come around the loop. */ vars = nreverse (static_aggregates); static_aggregates = NULL_TREE; while (vars) { if (! TREE_ASM_WRITTEN (TREE_VALUE (vars))) rest_of_decl_compilation (TREE_VALUE (vars), 0, 1, 1); if (!need_ssdf_p) { /* We need to start a new initialization function each time through the loop. That's because we need to know which vtables have been referenced, and TREE_SYMBOL_REFERENCED isn't computed until a function is finished, and written out. That's a deficiency in the back-end. When this is fixed, these initialization functions could all become inline, with resulting performance improvements. */ start_static_storage_duration_function (); need_ssdf_p = 1; } do_static_initialization_and_destruction (TREE_VALUE (vars), TREE_PURPOSE (vars)); reconsider = 1; vars = TREE_CHAIN (vars); } /* Finish up the static storage duration function for this round. */ if (need_ssdf_p) finish_static_storage_duration_function (); /* Go through the various inline functions, and see if any need synthesizing. */ for (i = 0; i < saved_inlines_used; ++i) { tree decl = VARRAY_TREE (saved_inlines, i); import_export_decl (decl); if (DECL_ARTIFICIAL (decl) && ! DECL_INITIAL (decl) && TREE_USED (decl) && (! DECL_REALLY_EXTERN (decl) || DECL_INLINE (decl))) { /* Even though we're already at the top-level, we push there again. That way, when we pop back a few lines hence, all of our state is restored. Otherwise, finish_function doesn't clean things up, and we end up with CURRENT_FUNCTION_DECL set. */ push_to_top_level (); if (DECL_TINFO_FN_P (decl)) synthesize_tinfo_fn (decl); else synthesize_method (decl); pop_from_top_level (); reconsider = 1; } } /* Mark all functions that might deal with exception-handling as referenced. */ mark_all_runtime_matches (); /* We lie to the back-end, pretending that some functions are not defined when they really are. This keeps these functions from being put out unncessarily. But, we must stop lying when the functions are referenced, or if they are not comdat since they need to be put out now. */ for (i = 0; i < saved_inlines_used; ++i) { tree decl = VARRAY_TREE (saved_inlines, i); if (DECL_NOT_REALLY_EXTERN (decl) && DECL_INITIAL (decl) && (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)) || !DECL_COMDAT (decl))) DECL_EXTERNAL (decl) = 0; } if (saved_inlines_used && wrapup_global_declarations (&VARRAY_TREE (saved_inlines, 0), saved_inlines_used)) reconsider = 1; if (walk_namespaces (wrapup_globals_for_namespace, /*data=*/0)) reconsider = 1; /* Static data members are just like namespace-scope globals. */ for (i = 0; i < pending_statics_used; ++i) { tree decl = VARRAY_TREE (pending_statics, i); if (TREE_ASM_WRITTEN (decl)) continue; import_export_decl (decl); if (DECL_NOT_REALLY_EXTERN (decl) && ! DECL_IN_AGGR_P (decl)) DECL_EXTERNAL (decl) = 0; } if (pending_statics && wrapup_global_declarations (&VARRAY_TREE (pending_statics, 0), pending_statics_used)) reconsider = 1; } while (reconsider); /* We give C linkage to static constructors and destructors. */ push_lang_context (lang_name_c); /* Generate initialization and destruction functions for all priorities for which they are required. */ if (priority_info_map) splay_tree_foreach (priority_info_map, generate_ctor_and_dtor_functions_for_priority, /*data=*/0); /* We're done with the splay-tree now. */ if (priority_info_map) splay_tree_delete (priority_info_map); /* We're done with static constructors, so we can go back to "C++" linkage now. */ pop_lang_context (); /* Now delete from the chain of variables all virtual function tables. We output them all ourselves, because each will be treated specially. */ walk_globals (vtable_decl_p, prune_vtable_vardecl, /*data=*/0); /* Now, issue warnings about static, but not defined, functions, etc. */ walk_namespaces (wrapup_globals_for_namespace, /*data=*/&reconsider); finish_repo (); this_time = get_run_time (); parse_time -= this_time - start_time; varconst_time += this_time - start_time; if (flag_detailed_statistics) { dump_tree_statistics (); dump_time_statistics (); } } /* This is something of the form 'A()()()()()+1' that has turned out to be an expr. Since it was parsed like a type, we need to wade through and fix that. Unfortunately, since operator() is left-associative, we can't use tail recursion. In the above example, TYPE is `A', and DECL is `()()()()()'. Maybe this shouldn't be recursive, but how often will it actually be used? (jason) */ tree reparse_absdcl_as_expr (type, decl) tree type, decl; { /* do build_functional_cast (type, NULL_TREE) at bottom */ if (TREE_OPERAND (decl, 0) == NULL_TREE) return build_functional_cast (type, NULL_TREE); /* recurse */ decl = reparse_absdcl_as_expr (type, TREE_OPERAND (decl, 0)); decl = build_x_function_call (decl, NULL_TREE, current_class_ref); if (TREE_CODE (decl) == CALL_EXPR && (! TREE_TYPE (decl) || TREE_CODE (TREE_TYPE (decl)) != VOID_TYPE)) decl = require_complete_type (decl); return decl; } /* This is something of the form `int ((int)(int)(int)1)' that has turned out to be an expr. Since it was parsed like a type, we need to wade through and fix that. Since casts are right-associative, we are reversing the order, so we don't have to recurse. In the above example, DECL is the `(int)(int)(int)', and EXPR is the `1'. */ tree reparse_absdcl_as_casts (decl, expr) tree decl, expr; { tree type; if (TREE_CODE (expr) == CONSTRUCTOR && TREE_TYPE (expr) == 0) { type = groktypename (TREE_VALUE (TREE_OPERAND (decl, 1))); decl = TREE_OPERAND (decl, 0); if (IS_SIGNATURE (type)) { error ("cast specifies signature type"); return error_mark_node; } expr = digest_init (type, expr, (tree *) 0); if (TREE_CODE (type) == ARRAY_TYPE && TYPE_SIZE (type) == 0) { int failure = complete_array_type (type, expr, 1); if (failure) my_friendly_abort (78); } } while (decl) { type = groktypename (TREE_VALUE (TREE_OPERAND (decl, 1))); decl = TREE_OPERAND (decl, 0); expr = build_c_cast (type, expr); } if (warn_old_style_cast && ! in_system_header && current_lang_name != lang_name_c) warning ("use of old-style cast"); return expr; } /* Given plain tree nodes for an expression, build up the full semantics. */ tree build_expr_from_tree (t) tree t; { if (t == NULL_TREE || t == error_mark_node) return t; switch (TREE_CODE (t)) { case IDENTIFIER_NODE: return do_identifier (t, 0, NULL_TREE); case LOOKUP_EXPR: if (LOOKUP_EXPR_GLOBAL (t)) return do_scoped_id (TREE_OPERAND (t, 0), 0); else return do_identifier (TREE_OPERAND (t, 0), 0, NULL_TREE); case TEMPLATE_ID_EXPR: return (lookup_template_function (build_expr_from_tree (TREE_OPERAND (t, 0)), build_expr_from_tree (TREE_OPERAND (t, 1)))); case INDIRECT_REF: return build_x_indirect_ref (build_expr_from_tree (TREE_OPERAND (t, 0)), "unary *"); case CAST_EXPR: return build_functional_cast (TREE_TYPE (t), build_expr_from_tree (TREE_OPERAND (t, 0))); case REINTERPRET_CAST_EXPR: return build_reinterpret_cast (TREE_TYPE (t), build_expr_from_tree (TREE_OPERAND (t, 0))); case CONST_CAST_EXPR: return build_const_cast (TREE_TYPE (t), build_expr_from_tree (TREE_OPERAND (t, 0))); case DYNAMIC_CAST_EXPR: return build_dynamic_cast (TREE_TYPE (t), build_expr_from_tree (TREE_OPERAND (t, 0))); case STATIC_CAST_EXPR: return build_static_cast (TREE_TYPE (t), build_expr_from_tree (TREE_OPERAND (t, 0))); case PREDECREMENT_EXPR: case PREINCREMENT_EXPR: case POSTDECREMENT_EXPR: case POSTINCREMENT_EXPR: case NEGATE_EXPR: case BIT_NOT_EXPR: case ABS_EXPR: case TRUTH_NOT_EXPR: case ADDR_EXPR: case CONVERT_EXPR: /* Unary + */ if (TREE_TYPE (t)) return t; return build_x_unary_op (TREE_CODE (t), build_expr_from_tree (TREE_OPERAND (t, 0))); case PLUS_EXPR: case MINUS_EXPR: case MULT_EXPR: case TRUNC_DIV_EXPR: case CEIL_DIV_EXPR: case FLOOR_DIV_EXPR: case ROUND_DIV_EXPR: case EXACT_DIV_EXPR: case BIT_AND_EXPR: case BIT_ANDTC_EXPR: case BIT_IOR_EXPR: case BIT_XOR_EXPR: case TRUNC_MOD_EXPR: case FLOOR_MOD_EXPR: case TRUTH_ANDIF_EXPR: case TRUTH_ORIF_EXPR: case TRUTH_AND_EXPR: case TRUTH_OR_EXPR: case RSHIFT_EXPR: case LSHIFT_EXPR: case RROTATE_EXPR: case LROTATE_EXPR: case EQ_EXPR: case NE_EXPR: case MAX_EXPR: case MIN_EXPR: case LE_EXPR: case GE_EXPR: case LT_EXPR: case GT_EXPR: case MEMBER_REF: return build_x_binary_op (TREE_CODE (t), build_expr_from_tree (TREE_OPERAND (t, 0)), build_expr_from_tree (TREE_OPERAND (t, 1))); case DOTSTAR_EXPR: return build_m_component_ref (build_expr_from_tree (TREE_OPERAND (t, 0)), build_expr_from_tree (TREE_OPERAND (t, 1))); case SCOPE_REF: return build_offset_ref (TREE_OPERAND (t, 0), TREE_OPERAND (t, 1)); case ARRAY_REF: if (TREE_OPERAND (t, 0) == NULL_TREE) /* new-type-id */ return build_parse_node (ARRAY_REF, NULL_TREE, build_expr_from_tree (TREE_OPERAND (t, 1))); return grok_array_decl (build_expr_from_tree (TREE_OPERAND (t, 0)), build_expr_from_tree (TREE_OPERAND (t, 1))); case SIZEOF_EXPR: case ALIGNOF_EXPR: { tree r = build_expr_from_tree (TREE_OPERAND (t, 0)); if (TREE_CODE_CLASS (TREE_CODE (r)) != 't') r = TREE_TYPE (r); return TREE_CODE (t) == SIZEOF_EXPR ? c_sizeof (r) : c_alignof (r); } case MODOP_EXPR: return build_x_modify_expr (build_expr_from_tree (TREE_OPERAND (t, 0)), TREE_CODE (TREE_OPERAND (t, 1)), build_expr_from_tree (TREE_OPERAND (t, 2))); case ARROW_EXPR: return build_x_arrow (build_expr_from_tree (TREE_OPERAND (t, 0))); case NEW_EXPR: return build_new (build_expr_from_tree (TREE_OPERAND (t, 0)), build_expr_from_tree (TREE_OPERAND (t, 1)), build_expr_from_tree (TREE_OPERAND (t, 2)), NEW_EXPR_USE_GLOBAL (t)); case DELETE_EXPR: return delete_sanity (build_expr_from_tree (TREE_OPERAND (t, 0)), build_expr_from_tree (TREE_OPERAND (t, 1)), DELETE_EXPR_USE_VEC (t), DELETE_EXPR_USE_GLOBAL (t)); case COMPOUND_EXPR: if (TREE_OPERAND (t, 1) == NULL_TREE) return build_x_compound_expr (build_expr_from_tree (TREE_OPERAND (t, 0))); else my_friendly_abort (42); case METHOD_CALL_EXPR: if (TREE_CODE (TREE_OPERAND (t, 0)) == SCOPE_REF) { tree ref = TREE_OPERAND (t, 0); return build_scoped_method_call (build_expr_from_tree (TREE_OPERAND (t, 1)), build_expr_from_tree (TREE_OPERAND (ref, 0)), TREE_OPERAND (ref, 1), build_expr_from_tree (TREE_OPERAND (t, 2))); } else { tree fn = TREE_OPERAND (t, 0); /* We can get a TEMPLATE_ID_EXPR here on code like: x->f<2>(); so we must resolve that. However, we can also get things like a BIT_NOT_EXPR here, when referring to a destructor, and things like that are not correctly resolved by build_expr_from_tree. So, just use build_expr_from_tree when we really need it. */ if (TREE_CODE (fn) == TEMPLATE_ID_EXPR) fn = lookup_template_function (TREE_OPERAND (fn, 0), build_expr_from_tree (TREE_OPERAND (fn, 1))); return build_method_call (build_expr_from_tree (TREE_OPERAND (t, 1)), fn, build_expr_from_tree (TREE_OPERAND (t, 2)), NULL_TREE, LOOKUP_NORMAL); } case CALL_EXPR: if (TREE_CODE (TREE_OPERAND (t, 0)) == SCOPE_REF) { tree ref = TREE_OPERAND (t, 0); return build_member_call (build_expr_from_tree (TREE_OPERAND (ref, 0)), TREE_OPERAND (ref, 1), build_expr_from_tree (TREE_OPERAND (t, 1))); } else { tree name = TREE_OPERAND (t, 0); tree id; tree args = build_expr_from_tree (TREE_OPERAND (t, 1)); if (args != NULL_TREE && TREE_CODE (name) == LOOKUP_EXPR && !LOOKUP_EXPR_GLOBAL (name) && TREE_CODE ((id = TREE_OPERAND (name, 0))) == IDENTIFIER_NODE && (!current_class_type || !lookup_member (current_class_type, id, 0, 0))) { /* Do Koenig lookup if there are no class members. */ name = do_identifier (id, 0, args); } else if (TREE_CODE (name) == TEMPLATE_ID_EXPR || ! really_overloaded_fn (name)) name = build_expr_from_tree (name); return build_x_function_call (name, args, current_class_ref); } case COND_EXPR: return build_x_conditional_expr (build_expr_from_tree (TREE_OPERAND (t, 0)), build_expr_from_tree (TREE_OPERAND (t, 1)), build_expr_from_tree (TREE_OPERAND (t, 2))); case TREE_LIST: { tree purpose, value, chain; if (t == void_list_node) return t; purpose = TREE_PURPOSE (t); if (purpose) purpose = build_expr_from_tree (purpose); value = TREE_VALUE (t); if (value) value = build_expr_from_tree (value); chain = TREE_CHAIN (t); if (chain && chain != void_type_node) chain = build_expr_from_tree (chain); return expr_tree_cons (purpose, value, chain); } case COMPONENT_REF: { tree object = build_expr_from_tree (TREE_OPERAND (t, 0)); tree field = TREE_OPERAND (t, 1); /* We use a COMPONENT_REF to indicate things of the form `x.b' and `x.A::b'. We must distinguish between those cases here. */ if (TREE_CODE (field) == SCOPE_REF) return build_object_ref (object, TREE_OPERAND (field, 0), TREE_OPERAND (field, 1)); else return build_x_component_ref (object, field, NULL_TREE, 1); } case THROW_EXPR: return build_throw (build_expr_from_tree (TREE_OPERAND (t, 0))); case CONSTRUCTOR: { tree r; /* digest_init will do the wrong thing if we let it. */ if (TREE_TYPE (t) && TYPE_PTRMEMFUNC_P (TREE_TYPE (t))) return t; r = build_nt (CONSTRUCTOR, NULL_TREE, build_expr_from_tree (CONSTRUCTOR_ELTS (t))); TREE_HAS_CONSTRUCTOR (r) = TREE_HAS_CONSTRUCTOR (t); if (TREE_TYPE (t)) return digest_init (TREE_TYPE (t), r, 0); return r; } case TYPEID_EXPR: if (TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (t, 0))) == 't') return get_typeid (TREE_OPERAND (t, 0)); return build_x_typeid (build_expr_from_tree (TREE_OPERAND (t, 0))); case VAR_DECL: return convert_from_reference (t); default: return t; } } /* This is something of the form `int (*a)++' that has turned out to be an expr. It was only converted into parse nodes, so we need to go through and build up the semantics. Most of the work is done by build_expr_from_tree, above. In the above example, TYPE is `int' and DECL is `*a'. */ tree reparse_decl_as_expr (type, decl) tree type, decl; { decl = build_expr_from_tree (decl); if (type) return build_functional_cast (type, build_expr_list (NULL_TREE, decl)); else return decl; } /* This is something of the form `int (*a)' that has turned out to be a decl. It was only converted into parse nodes, so we need to do the checking that make_{pointer,reference}_declarator do. */ tree finish_decl_parsing (decl) tree decl; { extern int current_class_depth; switch (TREE_CODE (decl)) { case IDENTIFIER_NODE: return decl; case INDIRECT_REF: return make_pointer_declarator (NULL_TREE, finish_decl_parsing (TREE_OPERAND (decl, 0))); case ADDR_EXPR: return make_reference_declarator (NULL_TREE, finish_decl_parsing (TREE_OPERAND (decl, 0))); case BIT_NOT_EXPR: TREE_OPERAND (decl, 0) = finish_decl_parsing (TREE_OPERAND (decl, 0)); return decl; case SCOPE_REF: push_nested_class (TREE_TYPE (TREE_OPERAND (decl, 0)), 3); TREE_COMPLEXITY (decl) = current_class_depth; return decl; case ARRAY_REF: TREE_OPERAND (decl, 0) = finish_decl_parsing (TREE_OPERAND (decl, 0)); return decl; case TREE_LIST: /* For attribute handling. */ TREE_VALUE (decl) = finish_decl_parsing (TREE_VALUE (decl)); return decl; default: my_friendly_abort (5); return NULL_TREE; } } tree check_cp_case_value (value) tree value; { if (value == NULL_TREE) return value; /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue. */ STRIP_TYPE_NOPS (value); if (TREE_READONLY_DECL_P (value)) { value = decl_constant_value (value); STRIP_TYPE_NOPS (value); } value = fold (value); if (TREE_CODE (value) != INTEGER_CST && value != error_mark_node) { cp_error ("case label `%E' does not reduce to an integer constant", value); value = error_mark_node; } else /* Promote char or short to int. */ value = default_conversion (value); constant_expression_warning (value); return value; } /* Return 1 if root encloses child. */ static int is_namespace_ancestor (root, child) tree root, child; { if (root == child) return 1; if (root == global_namespace) return 1; if (child == global_namespace) return 0; return is_namespace_ancestor (root, CP_DECL_CONTEXT (child)); } /* Return the namespace that is the common ancestor of two given namespaces. */ tree namespace_ancestor (ns1, ns2) tree ns1, ns2; { if (is_namespace_ancestor (ns1, ns2)) return ns1; return namespace_ancestor (CP_DECL_CONTEXT (ns1), ns2); } /* Insert used into the using list of user. Set indirect_flag if this directive is not directly from the source. Also find the common ancestor and let our users know about the new namespace */ static void add_using_namespace (user, used, indirect) tree user; tree used; int indirect; { tree t; /* Using oneself is a no-op. */ if (user == used) return; my_friendly_assert (TREE_CODE (user) == NAMESPACE_DECL, 380); my_friendly_assert (TREE_CODE (used) == NAMESPACE_DECL, 380); /* Check if we already have this. */ t = purpose_member (used, DECL_NAMESPACE_USING (user)); if (t != NULL_TREE) { if (!indirect) /* Promote to direct usage. */ TREE_INDIRECT_USING (t) = 0; return; } /* Add used to the user's using list. */ DECL_NAMESPACE_USING (user) = perm_tree_cons (used, namespace_ancestor (user, used), DECL_NAMESPACE_USING (user)); TREE_INDIRECT_USING (DECL_NAMESPACE_USING (user)) = indirect; /* Add user to the used's users list. */ DECL_NAMESPACE_USERS (used) = perm_tree_cons (user, 0, DECL_NAMESPACE_USERS (used)); /* Recursively add all namespaces used. */ for (t = DECL_NAMESPACE_USING (used); t; t = TREE_CHAIN (t)) /* indirect usage */ add_using_namespace (user, TREE_PURPOSE (t), 1); /* Tell everyone using us about the new used namespaces. */ for (t = DECL_NAMESPACE_USERS (user); t; t = TREE_CHAIN (t)) add_using_namespace (TREE_PURPOSE (t), used, 1); } /* Combines two sets of overloaded functions into an OVERLOAD chain, removing duplicates. The first list becomes the tail of the result. The algorithm is O(n^2). We could get this down to O(n log n) by doing a sort on the addresses of the functions, if that becomes necessary. */ static tree merge_functions (s1, s2) tree s1; tree s2; { for (; s2; s2 = OVL_NEXT (s2)) { tree fn = OVL_CURRENT (s2); if (! ovl_member (fn, s1)) s1 = build_overload (fn, s1); } return s1; } /* This should return an error not all definitions define functions. It is not an error if we find two functions with exactly the same signature, only if these are selected in overload resolution. old is the current set of bindings, new the freshly-found binding. XXX Do we want to give *all* candidates in case of ambiguity? XXX In what way should I treat extern declarations? XXX I don't want to repeat the entire duplicate_decls here */ static tree ambiguous_decl (name, old, new, flags) tree name; tree old; tree new; int flags; { tree val, type; my_friendly_assert (old != NULL_TREE, 393); /* Copy the value. */ val = BINDING_VALUE (new); if (val) switch (TREE_CODE (val)) { case TEMPLATE_DECL: /* If we expect types or namespaces, and not templates, or this is not a template class. */ if (LOOKUP_QUALIFIERS_ONLY (flags) && !DECL_CLASS_TEMPLATE_P (val)) val = NULL_TREE; break; case TYPE_DECL: if (LOOKUP_NAMESPACES_ONLY (flags)) val = NULL_TREE; break; case NAMESPACE_DECL: if (LOOKUP_TYPES_ONLY (flags)) val = NULL_TREE; break; default: if (LOOKUP_QUALIFIERS_ONLY (flags)) val = NULL_TREE; } if (!BINDING_VALUE (old)) BINDING_VALUE (old) = val; else if (val && val != BINDING_VALUE (old)) { if (is_overloaded_fn (BINDING_VALUE (old)) && is_overloaded_fn (val)) { BINDING_VALUE (old) = merge_functions (BINDING_VALUE (old), val); } else { /* Some declarations are functions, some are not. */ if (flags & LOOKUP_COMPLAIN) { /* If we've already given this error for this lookup, BINDING_VALUE (old) is error_mark_node, so let's not repeat ourselves. */ if (BINDING_VALUE (old) != error_mark_node) { cp_error ("use of `%D' is ambiguous", name); cp_error_at (" first declared as `%#D' here", BINDING_VALUE (old)); } cp_error_at (" also declared as `%#D' here", val); } return error_mark_node; } } /* ... and copy the type. */ type = BINDING_TYPE (new); if (LOOKUP_NAMESPACES_ONLY (flags)) type = NULL_TREE; if (!BINDING_TYPE (old)) BINDING_TYPE (old) = type; else if (type && BINDING_TYPE (old) != type) { if (flags & LOOKUP_COMPLAIN) { cp_error ("`%D' denotes an ambiguous type",name); cp_error_at (" first type here", BINDING_TYPE (old)); cp_error_at (" other type here", type); } } return old; } /* Add the bindings of name in used namespaces to val. The using list is defined by usings, and the lookup goes to scope. Returns zero on errors. */ int lookup_using_namespace (name, val, usings, scope, flags) tree name, val, usings, scope; int flags; { tree iter; tree val1; /* Iterate over all used namespaces in current, searching for using directives of scope. */ for (iter = usings; iter; iter = TREE_CHAIN (iter)) if (TREE_VALUE (iter) == scope) { val1 = binding_for_name (name, TREE_PURPOSE (iter)); /* Resolve ambiguities. */ val = ambiguous_decl (name, val, val1, flags); } return val != error_mark_node; } /* [namespace.qual] Excepts the name to lookup and its qualifying scope. Returns the name/type pair found into the CPLUS_BINDING result, or 0 on error. */ int qualified_lookup_using_namespace (name, scope, result, flags) tree name; tree scope; tree result; int flags; { /* Maintain a list of namespaces visited... */ tree seen = NULL_TREE; /* ... and a list of namespace yet to see. */ tree todo = NULL_TREE; tree usings; while (scope && (result != error_mark_node)) { seen = temp_tree_cons (scope, NULL_TREE, seen); result = ambiguous_decl (name, result, binding_for_name (name, scope), flags); if (!BINDING_VALUE (result) && !BINDING_TYPE (result)) /* Consider using directives. */ for (usings = DECL_NAMESPACE_USING (scope); usings; usings = TREE_CHAIN (usings)) /* If this was a real directive, and we have not seen it. */ if (!TREE_INDIRECT_USING (usings) && !purpose_member (TREE_PURPOSE (usings), seen)) todo = temp_tree_cons (TREE_PURPOSE (usings), NULL_TREE, todo); if (todo) { scope = TREE_PURPOSE (todo); todo = TREE_CHAIN (todo); } else scope = NULL_TREE; /* If there never was a todo list. */ } return result != error_mark_node; } /* [namespace.memdef]/2 */ /* Set the context of a declaration to scope. Complain if we are not outside scope. */ void set_decl_namespace (decl, scope, friendp) tree decl; tree scope; int friendp; { tree old; if (scope == std_node) scope = global_namespace; /* Get rid of namespace aliases. */ scope = ORIGINAL_NAMESPACE (scope); /* It is ok for friends to be qualified in parallel space. */ if (!friendp && !is_namespace_ancestor (current_namespace, scope)) cp_error ("declaration of `%D' not in a namespace surrounding `%D'", decl, scope); DECL_CONTEXT (decl) = FROB_CONTEXT (scope); if (scope != current_namespace) { /* See whether this has been declared in the namespace. */ old = namespace_binding (DECL_NAME (decl), scope); if (!old) /* No old declaration at all. */ goto complain; if (!is_overloaded_fn (decl)) /* Don't compare non-function decls with decls_match here, since it can't check for the correct constness at this point. pushdecl will find those errors later. */ return; /* Since decl is a function, old should contain a function decl. */ if (!is_overloaded_fn (old)) goto complain; if (processing_template_decl || processing_specialization) /* We have not yet called push_template_decl to turn the FUNCTION_DECL into a TEMPLATE_DECL, so the declarations won't match. But, we'll check later, when we construct the template. */ return; for (; old; old = OVL_NEXT (old)) if (decls_match (decl, OVL_CURRENT (old))) return; } else return; complain: cp_error ("`%D' should have been declared inside `%D'", decl, scope); } /* Compute the namespace where a declaration is defined. */ static tree decl_namespace (decl) tree decl; { while (DECL_CONTEXT (decl)) { decl = DECL_CONTEXT (decl); if (TREE_CODE (decl) == NAMESPACE_DECL) return decl; if (TREE_CODE_CLASS (TREE_CODE (decl)) == 't') decl = TYPE_STUB_DECL (decl); my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (decl)) == 'd', 390); } return global_namespace; } /* Return the namespace where the current declaration is declared. */ tree current_decl_namespace () { tree result; /* If we have been pushed into a different namespace, use it. */ if (decl_namespace_list) return TREE_PURPOSE (decl_namespace_list); if (current_class_type) result = decl_namespace (TYPE_STUB_DECL (current_class_type)); else if (current_function_decl) result = decl_namespace (current_function_decl); else result = current_namespace; return result; } /* Temporarily set the namespace for the current declaration. */ void push_decl_namespace (decl) tree decl; { if (TREE_CODE (decl) != NAMESPACE_DECL) decl = decl_namespace (decl); decl_namespace_list = tree_cons (decl, NULL_TREE, decl_namespace_list); } void pop_decl_namespace () { decl_namespace_list = TREE_CHAIN (decl_namespace_list); } /* Enter a class or namespace scope. */ void push_scope (t) tree t; { if (TREE_CODE (t) == NAMESPACE_DECL) push_decl_namespace (t); else pushclass (t, 2); } /* Leave scope pushed by push_scope. */ void pop_scope (t) tree t; { if (TREE_CODE (t) == NAMESPACE_DECL) pop_decl_namespace (); else popclass (); } /* [basic.lookup.koenig] */ /* A non-zero return value in the functions below indicates an error. All nodes allocated in the procedure are on the scratch obstack. */ struct arg_lookup { tree name; tree namespaces; tree classes; tree functions; }; static int arg_assoc PROTO((struct arg_lookup*, tree)); static int arg_assoc_args PROTO((struct arg_lookup*, tree)); static int arg_assoc_type PROTO((struct arg_lookup*, tree)); static int add_function PROTO((struct arg_lookup *, tree)); static int arg_assoc_namespace PROTO((struct arg_lookup *, tree)); static int arg_assoc_class PROTO((struct arg_lookup *, tree)); /* Add a function to the lookup structure. Returns 1 on error. */ static int add_function (k, fn) struct arg_lookup *k; tree fn; { if (ovl_member (fn, k->functions)) return 0; /* We must find only functions, or exactly one non-function. */ if (k->functions && is_overloaded_fn (k->functions) && is_overloaded_fn (fn)) k->functions = build_overload (fn, k->functions); else if(k->functions) { tree f1 = OVL_CURRENT (k->functions); tree f2 = fn; if (is_overloaded_fn (f1)) { fn = f1; f1 = f2; f2 = fn; } cp_error_at ("`%D' is not a function,", f1); cp_error_at (" conflict with `%D'", f2); cp_error (" in call to `%D'", k->name); return 1; } else k->functions = fn; return 0; } /* Add functions of a namespace to the lookup structure. Returns 1 on error. */ static int arg_assoc_namespace (k, scope) struct arg_lookup *k; tree scope; { tree value; if (purpose_member (scope, k->namespaces)) return 0; k->namespaces = tree_cons (scope, NULL_TREE, k->namespaces); value = namespace_binding (k->name, scope); if (!value) return 0; for (; value; value = OVL_NEXT (value)) if (add_function (k, OVL_CURRENT (value))) return 1; return 0; } /* Adds everything associated with class to the lookup structure. Returns 1 on error. */ static int arg_assoc_class (k, type) struct arg_lookup* k; tree type; { tree list, friends, context; int i; if (purpose_member (type, k->classes)) return 0; k->classes = tree_cons (type, NULL_TREE, k->classes); context = decl_namespace (TYPE_MAIN_DECL (type)); if (arg_assoc_namespace (k, context)) return 1; /* Process baseclasses. */ for (i = 0; i < CLASSTYPE_N_BASECLASSES (type); i++) if (arg_assoc_class (k, TYPE_BINFO_BASETYPE (type, i))) return 1; /* Process friends. */ for (list = DECL_FRIENDLIST (TYPE_MAIN_DECL (type)); list; list = TREE_CHAIN (list)) if (k->name == TREE_PURPOSE (list)) for (friends = TREE_VALUE (list); friends; friends = TREE_CHAIN (friends)) /* Only interested in global functions with potentially hidden (i.e. unqualified) declarations. */ if (TREE_PURPOSE (list) == error_mark_node && TREE_VALUE (list) && decl_namespace (TREE_VALUE (list)) == context) if (add_function (k, TREE_VALUE (list))) return 1; /* Process template arguments. */ if (CLASSTYPE_TEMPLATE_INFO (type)) { list = innermost_args (CLASSTYPE_TI_ARGS (type)); for (i = 0; i < TREE_VEC_LENGTH (list); ++i) arg_assoc (k, TREE_VEC_ELT (list, i)); } return 0; } /* Adds everything associated with a given type. Returns 1 on error. */ static int arg_assoc_type (k, type) struct arg_lookup *k; tree type; { switch (TREE_CODE (type)) { case VOID_TYPE: case INTEGER_TYPE: case REAL_TYPE: case COMPLEX_TYPE: case CHAR_TYPE: case BOOLEAN_TYPE: return 0; case RECORD_TYPE: if (TYPE_PTRMEMFUNC_P (type)) return arg_assoc_type (k, TYPE_PTRMEMFUNC_FN_TYPE (type)); return arg_assoc_class (k, type); case POINTER_TYPE: case REFERENCE_TYPE: case ARRAY_TYPE: return arg_assoc_type (k, TREE_TYPE (type)); case UNION_TYPE: case ENUMERAL_TYPE: return arg_assoc_namespace (k, decl_namespace (TYPE_MAIN_DECL (type))); case OFFSET_TYPE: /* Pointer to member: associate class type and value type. */ if (arg_assoc_type (k, TYPE_OFFSET_BASETYPE (type))) return 1; return arg_assoc_type (k, TREE_TYPE (type)); case METHOD_TYPE: /* The basetype is referenced in the first arg type, so just fall through. */ case FUNCTION_TYPE: /* Associate the parameter types. */ if (arg_assoc_args (k, TYPE_ARG_TYPES (type))) return 1; /* Associate the return type. */ return arg_assoc_type (k, TREE_TYPE (type)); case TEMPLATE_TYPE_PARM: case TEMPLATE_TEMPLATE_PARM: return 0; case LANG_TYPE: if (type == unknown_type_node) return 0; /* else fall through */ default: my_friendly_abort (390); } return 0; } /* Adds everything associated with arguments. Returns 1 on error. */ static int arg_assoc_args (k, args) struct arg_lookup* k; tree args; { for (; args; args = TREE_CHAIN (args)) if (arg_assoc (k, TREE_VALUE (args))) return 1; return 0; } /* Adds everything associated with a given tree_node. Returns 1 on error. */ static int arg_assoc (k, n) struct arg_lookup* k; tree n; { if (n == error_mark_node) return 0; if (TREE_CODE_CLASS (TREE_CODE (n)) == 't') return arg_assoc_type (k, n); if (! type_unknown_p (n)) return arg_assoc_type (k, TREE_TYPE (n)); if (TREE_CODE (n) == ADDR_EXPR) n = TREE_OPERAND (n, 0); if (TREE_CODE (n) == COMPONENT_REF) n = TREE_OPERAND (n, 1); if (TREE_CODE (n) == OFFSET_REF) n = TREE_OPERAND (n, 1); while (TREE_CODE (n) == TREE_LIST) n = TREE_VALUE (n); if (TREE_CODE (n) == FUNCTION_DECL) return arg_assoc_type (k, TREE_TYPE (n)); if (TREE_CODE (n) == TEMPLATE_ID_EXPR) { /* [basic.lookup.koenig] If T is a template-id, its associated namespaces and classes are the namespace in which the template is defined; for member templates, the member template's class; the namespaces and classes associated with the types of the template arguments provided for template type parameters (excluding template template parameters); the namespaces in which any template template arguments are defined; and the classes in which any member templates used as template template arguments are defined. [Note: non-type template arguments do not contribute to the set of associated namespaces. ] */ tree template = TREE_OPERAND (n, 0); tree args = TREE_OPERAND (n, 1); tree ctx; tree arg; /* First, the template. There may actually be more than one if this is an overloaded function template. But, in that case, we only need the first; all the functions will be in the same namespace. */ template = OVL_CURRENT (template); ctx = CP_DECL_CONTEXT (template); if (TREE_CODE (ctx) == NAMESPACE_DECL) { if (arg_assoc_namespace (k, ctx) == 1) return 1; } /* It must be a member template. */ else if (arg_assoc_class (k, ctx) == 1) return 1; /* Now the arguments. */ for (arg = args; arg != NULL_TREE; arg = TREE_CHAIN (arg)) { tree t = TREE_VALUE (arg); if (TREE_CODE (t) == TEMPLATE_DECL) { ctx = CP_DECL_CONTEXT (t); if (TREE_CODE (ctx) == NAMESPACE_DECL) { if (arg_assoc_namespace (k, ctx) == 1) return 1; } else if (arg_assoc_class (k, ctx) == 1) return 1; } else if (TREE_CODE_CLASS (TREE_CODE (t)) == 't' && arg_assoc_type (k, t) == 1) return 1; } } else { my_friendly_assert (TREE_CODE (n) == OVERLOAD, 980715); for (; n; n = OVL_CHAIN (n)) if (arg_assoc_type (k, TREE_TYPE (OVL_FUNCTION (n)))) return 1; } return 0; } /* Performs Koenig lookup depending on arguments, where fns are the functions found in normal lookup. */ tree lookup_arg_dependent (name, fns, args) tree name; tree fns; tree args; { struct arg_lookup k; k.name = name; k.functions = fns; k.classes = NULL_TREE; /* Note that we've already looked at the current namespace during normal unqualified lookup, unless we found a decl in function scope. */ if (fns && ! TREE_PERMANENT (OVL_CURRENT (fns))) k.namespaces = NULL_TREE; else k.namespaces = scratch_tree_cons (current_decl_namespace (), NULL_TREE, NULL_TREE); push_scratch_obstack (); arg_assoc_args (&k, args); pop_obstacks (); return k.functions; } /* Process a namespace-alias declaration. */ void do_namespace_alias (alias, namespace) tree alias, namespace; { if (TREE_CODE (namespace) != NAMESPACE_DECL) { /* The parser did not find it, so it's not there. */ cp_error ("unknown namespace `%D'", namespace); return; } namespace = ORIGINAL_NAMESPACE (namespace); /* Build the alias. */ alias = build_lang_decl (NAMESPACE_DECL, alias, void_type_node); DECL_NAMESPACE_ALIAS (alias) = namespace; pushdecl (alias); } /* Check a non-member using-declaration. Return the name and scope being used, and the USING_DECL, or NULL_TREE on failure. */ static tree validate_nonmember_using_decl (decl, scope, name) tree decl; tree *scope; tree *name; { if (TREE_CODE (decl) == SCOPE_REF && TREE_OPERAND (decl, 0) == std_node) { if (namespace_bindings_p () && current_namespace == global_namespace) /* There's no need for a using declaration at all, here, since `std' is the same as `::'. We can't just pass this on because we'll complain later about declaring something in the same scope as a using declaration with the same name. We return NULL_TREE which indicates to the caller that there's no need to do any further processing. */ return NULL_TREE; *scope = global_namespace; *name = TREE_OPERAND (decl, 1); } else if (TREE_CODE (decl) == SCOPE_REF) { *scope = TREE_OPERAND (decl, 0); *name = TREE_OPERAND (decl, 1); /* [namespace.udecl] A using-declaration for a class member shall be a member-declaration. */ if (TREE_CODE (*scope) != NAMESPACE_DECL) { if (TYPE_P (*scope)) cp_error ("`%T' is not a namespace", *scope); else cp_error ("`%D' is not a namespace", *scope); return NULL_TREE; } } else if (TREE_CODE (decl) == IDENTIFIER_NODE || TREE_CODE (decl) == TYPE_DECL || TREE_CODE (decl) == TEMPLATE_DECL) { *scope = global_namespace; *name = decl; } else my_friendly_abort (382); if (TREE_CODE_CLASS (TREE_CODE (*name)) == 'd') *name = DECL_NAME (*name); /* Make a USING_DECL. */ return push_using_decl (*scope, *name); } /* Process local and global using-declarations. */ static void do_nonmember_using_decl (scope, name, oldval, oldtype, newval, newtype) tree scope, name; tree oldval, oldtype; tree *newval, *newtype; { tree decls; struct tree_binding _decls; *newval = *newtype = NULL_TREE; decls = binding_init (&_decls); if (!qualified_lookup_using_namespace (name, scope, decls, 0)) /* Lookup error */ return; if (!BINDING_VALUE (decls) && !BINDING_TYPE (decls)) { cp_error ("`%D' not declared", name); return; } /* Check for using functions. */ if (BINDING_VALUE (decls) && is_overloaded_fn (BINDING_VALUE (decls))) { tree tmp, tmp1; if (oldval && !is_overloaded_fn (oldval)) { duplicate_decls (OVL_CURRENT (BINDING_VALUE (decls)), oldval); oldval = NULL_TREE; } *newval = oldval; for (tmp = BINDING_VALUE (decls); tmp; tmp = OVL_NEXT (tmp)) { tree new_fn = OVL_CURRENT (tmp); /* [namespace.udecl] If a function declaration in namespace scope or block scope has the same name and the same parameter types as a function introduced by a using declaration the program is ill-formed. */ for (tmp1 = oldval; tmp1; tmp1 = OVL_NEXT (tmp1)) { tree old_fn = OVL_CURRENT (tmp1); if (!OVL_USED (tmp1) && compparms (TYPE_ARG_TYPES (TREE_TYPE (new_fn)), TYPE_ARG_TYPES (TREE_TYPE (old_fn)))) { /* There was already a non-using declaration in this scope with the same parameter types. */ cp_error ("`%D' is already declared in this scope", name); break; } else if (duplicate_decls (new_fn, old_fn)) /* We're re-using something we already used before. We don't need to add it again. */ break; } /* If we broke out of the loop, there's no reason to add this function to the using declarations for this scope. */ if (tmp1) continue; *newval = build_overload (OVL_CURRENT (tmp), *newval); if (TREE_CODE (*newval) != OVERLOAD) *newval = ovl_cons (*newval, NULL_TREE); OVL_USED (*newval) = 1; } } else { *newval = BINDING_VALUE (decls); if (oldval) duplicate_decls (*newval, oldval); } *newtype = BINDING_TYPE (decls); if (oldtype && *newtype && oldtype != *newtype) { cp_error ("using directive `%D' introduced ambiguous type `%T'", name, oldtype); return; } } /* Process a using-declaration not appearing in class or local scope. */ void do_toplevel_using_decl (decl) tree decl; { tree scope, name, binding; tree oldval, oldtype, newval, newtype; decl = validate_nonmember_using_decl (decl, &scope, &name); if (decl == NULL_TREE) return; binding = binding_for_name (name, current_namespace); oldval = BINDING_VALUE (binding); oldtype = BINDING_TYPE (binding); do_nonmember_using_decl (scope, name, oldval, oldtype, &newval, &newtype); /* Copy declarations found. */ if (newval) BINDING_VALUE (binding) = newval; if (newtype) BINDING_TYPE (binding) = newtype; return; } /* Process a using-declaration at function scope. */ void do_local_using_decl (decl) tree decl; { tree scope, name; tree oldval, oldtype, newval, newtype; decl = validate_nonmember_using_decl (decl, &scope, &name); if (decl == NULL_TREE) return; oldval = lookup_name_current_level (name); oldtype = lookup_type_current_level (name); do_nonmember_using_decl (scope, name, oldval, oldtype, &newval, &newtype); if (newval) { if (is_overloaded_fn (newval)) { tree fn, term; /* We only need to push declarations for those functions that were not already bound in the current level. The old value might be NULL_TREE, it might be a single function, or an OVERLOAD. */ if (oldval && TREE_CODE (oldval) == OVERLOAD) term = OVL_FUNCTION (oldval); else term = oldval; for (fn = newval; fn && OVL_CURRENT (fn) != term; fn = OVL_NEXT (fn)) push_overloaded_decl (OVL_CURRENT (fn), PUSH_LOCAL | PUSH_USING); } else push_local_binding (name, newval, PUSH_USING); } if (newtype) set_identifier_type_value (name, newtype); } tree do_class_using_decl (decl) tree decl; { tree name, value; if (TREE_CODE (decl) != SCOPE_REF || TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (decl, 0))) != 't') { cp_error ("using-declaration for non-member at class scope"); return NULL_TREE; } name = TREE_OPERAND (decl, 1); if (TREE_CODE (name) == BIT_NOT_EXPR) { cp_error ("using-declaration for destructor"); return NULL_TREE; } if (TREE_CODE (name) == TYPE_DECL) name = DECL_NAME (name); my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 980716); value = build_lang_field_decl (USING_DECL, name, void_type_node); DECL_INITIAL (value) = TREE_OPERAND (decl, 0); return value; } /* Process a using-directive. */ void do_using_directive (namespace) tree namespace; { if (namespace == std_node) return; /* using namespace A::B::C; */ if (TREE_CODE (namespace) == SCOPE_REF) namespace = TREE_OPERAND (namespace, 1); if (TREE_CODE (namespace) == IDENTIFIER_NODE) { /* Lookup in lexer did not find a namespace. */ cp_error ("namespace `%T' undeclared", namespace); return; } if (TREE_CODE (namespace) != NAMESPACE_DECL) { cp_error ("`%T' is not a namespace", namespace); return; } namespace = ORIGINAL_NAMESPACE (namespace); if (!toplevel_bindings_p ()) push_using_directive (namespace); else /* direct usage */ add_using_namespace (current_namespace, namespace, 0); } void check_default_args (x) tree x; { tree arg = TYPE_ARG_TYPES (TREE_TYPE (x)); int saw_def = 0, i = 0 - (TREE_CODE (TREE_TYPE (x)) == METHOD_TYPE); for (; arg && arg != void_list_node; arg = TREE_CHAIN (arg), ++i) { if (TREE_PURPOSE (arg)) saw_def = 1; else if (saw_def) { cp_error_at ("default argument missing for parameter %P of `%+#D'", i, x); break; } } } void mark_used (decl) tree decl; { TREE_USED (decl) = 1; if (processing_template_decl) return; assemble_external (decl); /* Is it a synthesized method that needs to be synthesized? */ if (TREE_CODE (decl) == FUNCTION_DECL && DECL_CLASS_CONTEXT (decl) && DECL_ARTIFICIAL (decl) && ! DECL_INITIAL (decl) /* Kludge: don't synthesize for default args. */ && current_function_decl) synthesize_method (decl); /* If this is a function or variable that is an instance of some template, we now know that we will need to actually do the instantiation. A TEMPLATE_DECL may also have DECL_TEMPLATE_INFO, if it's a partial instantiation, but there's no need to instantiate such a thing. We check that DECL is not an explicit instantiation because that is not checked in instantiate_decl. */ if (TREE_CODE (decl) != TEMPLATE_DECL && DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl) && !DECL_EXPLICIT_INSTANTIATION (decl)) instantiate_decl (decl); } /* Helper function for named_class_head_sans_basetype nonterminal. We have just seen something of the form `AGGR SCOPE::ID'. Return a TYPE_DECL for the type declared by ID in SCOPE. */ tree handle_class_head (aggr, scope, id) tree aggr, scope, id; { tree decl; if (TREE_CODE (id) == TYPE_DECL) decl = id; else if (DECL_CLASS_TEMPLATE_P (id)) decl = DECL_TEMPLATE_RESULT (id); else { if (scope) cp_error ("`%T' does not have a nested type named `%D'", scope, id); else cp_error ("no file-scope type named `%D'", id); decl = TYPE_MAIN_DECL (xref_tag (aggr, make_anon_name (), 1)); } /* This syntax is only allowed when we're defining a type, so we enter the SCOPE. */ push_scope (CP_DECL_CONTEXT (decl)); /* If we see something like: template struct S::I .... we must create a TEMPLATE_DECL for the nested type. */ if (PROCESSING_REAL_TEMPLATE_DECL_P ()) decl = push_template_decl (decl); return decl; } Index: vendor/gcc/dist/contrib/gcc/cp/exception.cc =================================================================== --- vendor/gcc/dist/contrib/gcc/cp/exception.cc (revision 60966) +++ vendor/gcc/dist/contrib/gcc/cp/exception.cc (revision 60967) @@ -1,343 +1,343 @@ // Functions for Exception Support for -*- C++ -*- // Copyright (C) 1994, 95-97, 1998 Free Software Foundation // 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. // As a special exception, if you link this library with other files, // some of which are compiled with GCC, to produce an executable, // this library does not by itself cause the resulting executable // to be covered by the GNU General Public License. // This exception does not however invalidate any other reasons why // the executable file might be covered by the GNU General Public License. #pragma implementation "exception" #include "typeinfo" #include "exception" #include #include "gansidecl.h" /* Needed to support macros used in eh-common.h. */ #include "eh-common.h" /* Define terminate, unexpected, set_terminate, set_unexpected as well as the default terminate func and default unexpected func. */ extern std::terminate_handler __terminate_func __attribute__((__noreturn__)); using std::terminate; void std::terminate () { __terminate_func (); } void __default_unexpected () { terminate (); } static std::unexpected_handler __unexpected_func __attribute__((__noreturn__)) = __default_unexpected; std::terminate_handler std::set_terminate (std::terminate_handler func) { std::terminate_handler old = __terminate_func; __terminate_func = func; return old; } std::unexpected_handler std::set_unexpected (std::unexpected_handler func) { std::unexpected_handler old = __unexpected_func; __unexpected_func = func; return old; } void std::unexpected () { __unexpected_func (); } /* C++-specific state about the current exception. This must match init_exception_processing(). Note that handlers and caught are not redundant; when rethrown, an exception can have multiple active handlers and still be considered uncaught. */ struct cp_eh_info { __eh_info eh_info; void *value; void *type; void (*cleanup)(void *, int); bool caught; cp_eh_info *next; long handlers; void *original_value; }; /* Language-specific EH info pointer, defined in libgcc2. */ extern "C" cp_eh_info **__get_eh_info (); // actually void ** /* Is P the type_info node for a pointer of some kind? */ extern bool __is_pointer (void *); /* OLD Compiler hook to return a pointer to the info for the current exception. Used by get_eh_info (). This fudges the actualy returned value to point to the beginning of what USE to be the cp_eh_info structure. THis is so that old code that dereferences this pointer will find things where it expects it to be.*/ extern "C" void * __cp_exception_info (void) { return &((*__get_eh_info ())->value); } #define CP_EH_INFO ((cp_eh_info *) *__get_eh_info ()) /* Old Compiler hook to return a pointer to the info for the current exception. Used by get_eh_info (). */ extern "C" cp_eh_info * __cp_eh_info (void) { cp_eh_info *p = CP_EH_INFO; return p; } /* Compiler hook to return a pointer to the info for the current exception, Set the caught bit, and increment the number of handlers that are looking at this exception. This makes handlers smaller. */ extern "C" cp_eh_info * __start_cp_handler (void) { cp_eh_info *p = CP_EH_INFO; p->caught = 1; p->handlers++; return p; } /* Allocate a buffer for a cp_eh_info and an exception object of size SIZE, and return a pointer to the beginning of the object's space. */ extern "C" void * malloc (size_t); extern "C" void * __eh_alloc (size_t size) { void *p = malloc (size); if (p == 0) terminate (); return p; } /* Free the memory for an cp_eh_info and associated exception, given a pointer to the cp_eh_info. */ extern "C" void free (void *); extern "C" void __eh_free (void *p) { free (p); } typedef void * (* rtimetype) (void); extern "C" void * __cplus_type_matcher (cp_eh_info *info, rtimetype match_info, exception_descriptor *exception_table) { void *ret; /* No exception table implies the old style mechanism, so don't check. */ if (exception_table != NULL && exception_table->lang.language != EH_LANG_C_plus_plus) return NULL; if (match_info == CATCH_ALL_TYPE) return info->value; /* we don't worry about version info yet, there is only one version! */ void *match_type = match_info (); ret = __throw_type_match_rtti (match_type, info->type, info->original_value); /* change value of exception */ if (ret) info->value = ret; return ret; } /* Compiler hook to push a new exception onto the stack. Used by expand_throw(). */ extern "C" void __cp_push_exception (void *value, void *type, void (*cleanup)(void *, int)) { cp_eh_info *p = (cp_eh_info *) __eh_alloc (sizeof (cp_eh_info)); p->value = value; p->type = type; p->cleanup = cleanup; p->handlers = 0; p->caught = false; p->original_value = value; p->eh_info.match_function = __cplus_type_matcher; p->eh_info.language = EH_LANG_C_plus_plus; p->eh_info.version = 1; cp_eh_info **q = __get_eh_info (); p->next = *q; *q = p; } /* Compiler hook to pop an exception that has been finalized. Used by push_eh_cleanup(). P is the info for the exception caught by the current catch block. */ extern "C" void __cp_pop_exception (cp_eh_info *p) { cp_eh_info **q = __get_eh_info (); --p->handlers; /* Don't really pop if there are still active handlers for our exception, or if our exception is being rethrown (i.e. if the active exception is our exception and it is uncaught). */ if (p->handlers != 0 || (p == *q && !p->caught)) return; for (; *q; q = &((*q)->next)) if (*q == p) break; if (! *q) terminate (); *q = p->next; if (p->cleanup) /* 2 is a magic value for destructors; see build_delete(). */ - p->cleanup (p->value, 2); + p->cleanup (p->original_value, 2); // value may have been adjusted. if (! __is_pointer (p->type)) - __eh_free (p->original_value); // value may have been co-erced. + __eh_free (p->original_value); // value may have been adjusted. __eh_free (p); } extern "C" void __uncatch_exception (void) { cp_eh_info *p = CP_EH_INFO; if (p == 0) terminate (); p->caught = false; } /* As per [except.unexpected]: If an exception is thrown, we check it against the spec. If it doesn't match, we call unexpected (). If unexpected () throws, we check that exception against the spec. If it doesn't match, if the spec allows bad_exception we throw that; otherwise we call terminate (). The compiler treats an exception spec as a try block with a generic handler that just calls this function with a list of the allowed exception types, so we have an active exception that can be rethrown. This function does not return. */ extern "C" void __check_eh_spec (int n, const void **spec) { cp_eh_info *p = CP_EH_INFO; for (int i = 0; i < n; ++i) { if (__throw_type_match_rtti (spec[i], p->type, p->value)) throw; } try { std::unexpected (); } catch (...) { // __exception_info is an artificial var pushed into each catch block. if (p != __exception_info) { p = __exception_info; for (int i = 0; i < n; ++i) { if (__throw_type_match_rtti (spec[i], p->type, p->value)) throw; } } const std::type_info &bad_exc = typeid (std::bad_exception); for (int i = 0; i < n; ++i) { if (__throw_type_match_rtti (spec[i], &bad_exc, p->value)) throw std::bad_exception (); } terminate (); } } extern "C" void __throw_bad_cast (void) { throw std::bad_cast (); } extern "C" void __throw_bad_typeid (void) { throw std::bad_typeid (); } /* Has the current exception been caught? */ bool std::uncaught_exception () { cp_eh_info *p = CP_EH_INFO; return p && ! p->caught; } const char * std::exception:: what () const { return typeid (*this).name (); } Index: vendor/gcc/dist/contrib/gcc/cp/gxxint.texi =================================================================== --- vendor/gcc/dist/contrib/gcc/cp/gxxint.texi (revision 60966) +++ vendor/gcc/dist/contrib/gcc/cp/gxxint.texi (revision 60967) @@ -1,1848 +1,2075 @@ \input texinfo @c -*-texinfo-*- @c %**start of header @setfilename g++int.info @settitle G++ internals @setchapternewpage odd @c %**end of header @node Top, Limitations of g++, (dir), (dir) @chapter Internal Architecture of the Compiler This is meant to describe the C++ front-end for gcc in detail. Questions and comments to Benjamin Kosnik @code{}. @menu * Limitations of g++:: * Routines:: * Implementation Specifics:: * Glossary:: * Macros:: * Typical Behavior:: * Coding Conventions:: * Templates:: * Access Control:: * Error Reporting:: * Parser:: * Exception Handling:: * Free Store:: * Mangling:: Function name mangling for C++ and Java +* Vtables:: Two ways to do virtual functions * Concept Index:: @end menu @node Limitations of g++, Routines, Top, Top @section Limitations of g++ @itemize @bullet @item Limitations on input source code: 240 nesting levels with the parser stacksize (YYSTACKSIZE) set to 500 (the default), and requires around 16.4k swap space per nesting level. The parser needs about 2.09 * number of nesting levels worth of stackspace. @cindex pushdecl_class_level @item I suspect there are other uses of pushdecl_class_level that do not call set_identifier_type_value in tandem with the call to pushdecl_class_level. It would seem to be an omission. @cindex access checking @item Access checking is unimplemented for nested types. @cindex @code{volatile} @item @code{volatile} is not implemented in general. @end itemize @node Routines, Implementation Specifics, Limitations of g++, Top @section Routines This section describes some of the routines used in the C++ front-end. @code{build_vtable} and @code{prepare_fresh_vtable} is used only within the @file{cp-class.c} file, and only in @code{finish_struct} and @code{modify_vtable_entries}. @code{build_vtable}, @code{prepare_fresh_vtable}, and @code{finish_struct} are the only routines that set @code{DECL_VPARENT}. @code{finish_struct} can steal the virtual function table from parents, this prohibits related_vslot from working. When finish_struct steals, we know that @example get_binfo (DECL_FIELD_CONTEXT (CLASSTYPE_VFIELD (t)), t, 0) @end example @noindent will get the related binfo. @code{layout_basetypes} does something with the VIRTUALS. Supposedly (according to Tiemann) most of the breadth first searching done, like in @code{get_base_distance} and in @code{get_binfo} was not because of any design decision. I have since found out the at least one part of the compiler needs the notion of depth first binfo searching, I am going to try and convert the whole thing, it should just work. The term left-most refers to the depth first left-most node. It uses @code{MAIN_VARIANT == type} as the condition to get left-most, because the things that have @code{BINFO_OFFSET}s of zero are shared and will have themselves as their own @code{MAIN_VARIANT}s. The non-shared right ones, are copies of the left-most one, hence if it is its own @code{MAIN_VARIANT}, we know it IS a left-most one, if it is not, it is a non-left-most one. @code{get_base_distance}'s path and distance matters in its use in: @itemize @bullet @item @code{prepare_fresh_vtable} (the code is probably wrong) @item @code{init_vfields} Depends upon distance probably in a safe way, build_offset_ref might use partial paths to do further lookups, hack_identifier is probably not properly checking access. @item @code{get_first_matching_virtual} probably should check for @code{get_base_distance} returning -2. @item @code{resolve_offset_ref} should be called in a more deterministic manner. Right now, it is called in some random contexts, like for arguments at @code{build_method_call} time, @code{default_conversion} time, @code{convert_arguments} time, @code{build_unary_op} time, @code{build_c_cast} time, @code{build_modify_expr} time, @code{convert_for_assignment} time, and @code{convert_for_initialization} time. But, there are still more contexts it needs to be called in, one was the ever simple: @example if (obj.*pmi != 7) @dots{} @end example Seems that the problems were due to the fact that @code{TREE_TYPE} of the @code{OFFSET_REF} was not a @code{OFFSET_TYPE}, but rather the type of the referent (like @code{INTEGER_TYPE}). This problem was fixed by changing @code{default_conversion} to check @code{TREE_CODE (x)}, instead of only checking @code{TREE_CODE (TREE_TYPE (x))} to see if it was @code{OFFSET_TYPE}. @end itemize @node Implementation Specifics, Glossary, Routines, Top @section Implementation Specifics @itemize @bullet @item Explicit Initialization The global list @code{current_member_init_list} contains the list of mem-initializers specified in a constructor declaration. For example: @example foo::foo() : a(1), b(2) @{@} @end example @noindent will initialize @samp{a} with 1 and @samp{b} with 2. @code{expand_member_init} places each initialization (a with 1) on the global list. Then, when the fndecl is being processed, @code{emit_base_init} runs down the list, initializing them. It used to be the case that g++ first ran down @code{current_member_init_list}, then ran down the list of members initializing the ones that weren't explicitly initialized. Things were rewritten to perform the initializations in order of declaration in the class. So, for the above example, @samp{a} and @samp{b} will be initialized in the order that they were declared: @example class foo @{ public: int b; int a; foo (); @}; @end example @noindent Thus, @samp{b} will be initialized with 2 first, then @samp{a} will be initialized with 1, regardless of how they're listed in the mem-initializer. @item The Explicit Keyword The use of @code{explicit} on a constructor is used by @code{grokdeclarator} to set the field @code{DECL_NONCONVERTING_P}. That value is used by @code{build_method_call} and @code{build_user_type_conversion_1} to decide if a particular constructor should be used as a candidate for conversions. @end itemize @node Glossary, Macros, Implementation Specifics, Top @section Glossary @table @r @item binfo The main data structure in the compiler used to represent the inheritance relationships between classes. The data in the binfo can be accessed by the BINFO_ accessor macros. @item vtable @itemx virtual function table The virtual function table holds information used in virtual function dispatching. In the compiler, they are usually referred to as vtables, or vtbls. The first index is not used in the normal way, I believe it -is probably used for the virtual destructor. +is probably used for the virtual destructor. There are two forms of +virtual tables, one that has offsets in addition to pointers, and one +using thunks. @xref{Vtables}. @item vfield vfields can be thought of as the base information needed to build vtables. For every vtable that exists for a class, there is a vfield. See also vtable and virtual function table pointer. When a type is used as a base class to another type, the virtual function table for the derived class can be based upon the vtable for the base class, just extended to include the additional virtual methods declared in the derived class. The virtual function table from a virtual base class is never reused in a derived class. @code{is_normal} depends upon this. @item virtual function table pointer These are @code{FIELD_DECL}s that are pointer types that point to vtables. See also vtable and vfield. @end table @node Macros, Typical Behavior, Glossary, Top @section Macros This section describes some of the macros used on trees. The list should be alphabetical. Eventually all macros should be documented here. @table @code @item BINFO_BASETYPES A vector of additional binfos for the types inherited by this basetype. The binfos are fully unshared (except for virtual bases, in which case the binfo structure is shared). If this basetype describes type D as inherited in C, and if the basetypes of D are E anf F, then this vector contains binfos for inheritance of E and F by C. Has values of: TREE_VECs @item BINFO_INHERITANCE_CHAIN Temporarily used to represent specific inheritances. It usually points to the binfo associated with the lesser derived type, but it can be reversed by reverse_path. For example: @example Z ZbY least derived | Y YbX | X Xb most derived TYPE_BINFO (X) == Xb BINFO_INHERITANCE_CHAIN (Xb) == YbX BINFO_INHERITANCE_CHAIN (Yb) == ZbY BINFO_INHERITANCE_CHAIN (Zb) == 0 @end example Not sure is the above is really true, get_base_distance has is point towards the most derived type, opposite from above. Set by build_vbase_path, recursive_bounded_basetype_p, get_base_distance, lookup_field, lookup_fnfields, and reverse_path. What things can this be used on: TREE_VECs that are binfos @item BINFO_OFFSET The offset where this basetype appears in its containing type. BINFO_OFFSET slot holds the offset (in bytes) from the base of the complete object to the base of the part of the object that is allocated on behalf of this `type'. This is always 0 except when there is multiple inheritance. Used on TREE_VEC_ELTs of the binfos BINFO_BASETYPES (...) for example. @item BINFO_VIRTUALS A unique list of functions for the virtual function table. See also TYPE_BINFO_VIRTUALS. What things can this be used on: TREE_VECs that are binfos @item BINFO_VTABLE Used to find the VAR_DECL that is the virtual function table associated with this binfo. See also TYPE_BINFO_VTABLE. To get the virtual function table pointer, see CLASSTYPE_VFIELD. What things can this be used on: TREE_VECs that are binfos Has values of: VAR_DECLs that are virtual function tables @item BLOCK_SUPERCONTEXT In the outermost scope of each function, it points to the FUNCTION_DECL node. It aids in better DWARF support of inline functions. @item CLASSTYPE_TAGS CLASSTYPE_TAGS is a linked (via TREE_CHAIN) list of member classes of a class. TREE_PURPOSE is the name, TREE_VALUE is the type (pushclass scans these and calls pushtag on them.) finish_struct scans these to produce TYPE_DECLs to add to the TYPE_FIELDS of the type. It is expected that name found in the TREE_PURPOSE slot is unique, resolve_scope_to_name is one such place that depends upon this uniqueness. @item CLASSTYPE_METHOD_VEC The following is true after finish_struct has been called (on the class?) but not before. Before finish_struct is called, things are different to some extent. Contains a TREE_VEC of methods of the class. The TREE_VEC_LENGTH is the number of differently named methods plus one for the 0th entry. The 0th entry is always allocated, and reserved for ctors and dtors. If there are none, TREE_VEC_ELT(N,0) == NULL_TREE. Each entry of the TREE_VEC is a FUNCTION_DECL. For each FUNCTION_DECL, there is a DECL_CHAIN slot. If the FUNCTION_DECL is the last one with a given name, the DECL_CHAIN slot is NULL_TREE. Otherwise it is the next method that has the same name (but a different signature). It would seem that it is not true that because the DECL_CHAIN slot is used in this way, we cannot call pushdecl to put the method in the global scope (cause that would overwrite the TREE_CHAIN slot), because they use different _CHAINs. finish_struct_methods setups up one version of the TREE_CHAIN slots on the FUNCTION_DECLs. friends are kept in TREE_LISTs, so that there's no need to use their TREE_CHAIN slot for anything. Has values of: TREE_VECs @item CLASSTYPE_VFIELD Seems to be in the process of being renamed TYPE_VFIELD. Use on types to get the main virtual function table pointer. To get the virtual function table use BINFO_VTABLE (TYPE_BINFO ()). Has values of: FIELD_DECLs that are virtual function table pointers What things can this be used on: RECORD_TYPEs @item DECL_CLASS_CONTEXT Identifies the context that the _DECL was found in. For virtual function tables, it points to the type associated with the virtual function table. See also DECL_CONTEXT, DECL_FIELD_CONTEXT and DECL_FCONTEXT. The difference between this and DECL_CONTEXT, is that for virtuals functions like: @example struct A @{ virtual int f (); @}; struct B : A @{ int f (); @}; DECL_CONTEXT (A::f) == A DECL_CLASS_CONTEXT (A::f) == A DECL_CONTEXT (B::f) == A DECL_CLASS_CONTEXT (B::f) == B @end example Has values of: RECORD_TYPEs, or UNION_TYPEs What things can this be used on: TYPE_DECLs, _DECLs @item DECL_CONTEXT Identifies the context that the _DECL was found in. Can be used on virtual function tables to find the type associated with the virtual function table, but since they are FIELD_DECLs, DECL_FIELD_CONTEXT is a better access method. Internally the same as DECL_FIELD_CONTEXT, so don't us both. See also DECL_FIELD_CONTEXT, DECL_FCONTEXT and DECL_CLASS_CONTEXT. Has values of: RECORD_TYPEs What things can this be used on: @display VAR_DECLs that are virtual function tables _DECLs @end display @item DECL_FIELD_CONTEXT Identifies the context that the FIELD_DECL was found in. Internally the same as DECL_CONTEXT, so don't us both. See also DECL_CONTEXT, DECL_FCONTEXT and DECL_CLASS_CONTEXT. Has values of: RECORD_TYPEs What things can this be used on: @display FIELD_DECLs that are virtual function pointers FIELD_DECLs @end display @item DECL_NAME Has values of: @display 0 for things that don't have names IDENTIFIER_NODEs for TYPE_DECLs @end display @item DECL_IGNORED_P A bit that can be set to inform the debug information output routines in the back-end that a certain _DECL node should be totally ignored. Used in cases where it is known that the debugging information will be output in another file, or where a sub-type is known not to be needed because the enclosing type is not needed. A compiler constructed virtual destructor in derived classes that do not define an explicit destructor that was defined explicit in a base class has this bit set as well. Also used on __FUNCTION__ and __PRETTY_FUNCTION__ to mark they are ``compiler generated.'' c-decl and c-lex.c both want DECL_IGNORED_P set for ``internally generated vars,'' and ``user-invisible variable.'' Functions built by the C++ front-end such as default destructors, virtual destructors and default constructors want to be marked that they are compiler generated, but unsure why. Currently, it is used in an absolute way in the C++ front-end, as an optimization, to tell the debug information output routines to not generate debugging information that will be output by another separately compiled file. @item DECL_VIRTUAL_P A flag used on FIELD_DECLs and VAR_DECLs. (Documentation in tree.h is wrong.) Used in VAR_DECLs to indicate that the variable is a vtable. It is also used in FIELD_DECLs for vtable pointers. What things can this be used on: FIELD_DECLs and VAR_DECLs @item DECL_VPARENT Used to point to the parent type of the vtable if there is one, else it is just the type associated with the vtable. Because of the sharing of virtual function tables that goes on, this slot is not very useful, and is in fact, not used in the compiler at all. It can be removed. What things can this be used on: VAR_DECLs that are virtual function tables Has values of: RECORD_TYPEs maybe UNION_TYPEs @item DECL_FCONTEXT Used to find the first baseclass in which this FIELD_DECL is defined. See also DECL_CONTEXT, DECL_FIELD_CONTEXT and DECL_CLASS_CONTEXT. How it is used: Used when writing out debugging information about vfield and vbase decls. What things can this be used on: FIELD_DECLs that are virtual function pointers FIELD_DECLs @item DECL_REFERENCE_SLOT Used to hold the initialize for the reference. What things can this be used on: PARM_DECLs and VAR_DECLs that have a reference type @item DECL_VINDEX Used for FUNCTION_DECLs in two different ways. Before the structure containing the FUNCTION_DECL is laid out, DECL_VINDEX may point to a FUNCTION_DECL in a base class which is the FUNCTION_DECL which this FUNCTION_DECL will replace as a virtual function. When the class is laid out, this pointer is changed to an INTEGER_CST node which is suitable to find an index into the virtual function table. See get_vtable_entry as to how one can find the right index into the virtual function table. The first index 0, of a virtual function table it not used in the normal way, so the first real index is 1. DECL_VINDEX may be a TREE_LIST, that would seem to be a list of overridden FUNCTION_DECLs. add_virtual_function has code to deal with this when it uses the variable base_fndecl_list, but it would seem that somehow, it is possible for the TREE_LIST to pursist until method_call, and it should not. What things can this be used on: FUNCTION_DECLs @item DECL_SOURCE_FILE Identifies what source file a particular declaration was found in. Has values of: "" on TYPE_DECLs to mean the typedef is built in @item DECL_SOURCE_LINE Identifies what source line number in the source file the declaration was found at. Has values of: @display 0 for an undefined label 0 for TYPE_DECLs that are internally generated 0 for FUNCTION_DECLs for functions generated by the compiler (not yet, but should be) 0 for ``magic'' arguments to functions, that the user has no control over @end display @item TREE_USED Has values of: 0 for unused labels @item TREE_ADDRESSABLE A flag that is set for any type that has a constructor. @item TREE_COMPLEXITY They seem a kludge way to track recursion, poping, and pushing. They only appear in cp-decl.c and cp-decl2.c, so the are a good candidate for proper fixing, and removal. @item TREE_HAS_CONSTRUCTOR A flag to indicate when a CALL_EXPR represents a call to a constructor. If set, we know that the type of the object, is the complete type of the object, and that the value returned is nonnull. When used in this fashion, it is an optimization. Can also be used on SAVE_EXPRs to indicate when they are of fixed type and nonnull. Can also be used on INDIRECT_EXPRs on CALL_EXPRs that represent a call to a constructor. @item TREE_PRIVATE Set for FIELD_DECLs by finish_struct. But not uniformly set. The following routines do something with PRIVATE access: build_method_call, alter_access, finish_struct_methods, finish_struct, convert_to_aggr, CWriteLanguageDecl, CWriteLanguageType, CWriteUseObject, compute_access, lookup_field, dfs_pushdecl, GNU_xref_member, dbxout_type_fields, dbxout_type_method_1 @item TREE_PROTECTED The following routines do something with PROTECTED access: build_method_call, alter_access, finish_struct, convert_to_aggr, CWriteLanguageDecl, CWriteLanguageType, CWriteUseObject, compute_access, lookup_field, GNU_xref_member, dbxout_type_fields, dbxout_type_method_1 @item TYPE_BINFO Used to get the binfo for the type. Has values of: TREE_VECs that are binfos What things can this be used on: RECORD_TYPEs @item TYPE_BINFO_BASETYPES See also BINFO_BASETYPES. @item TYPE_BINFO_VIRTUALS A unique list of functions for the virtual function table. See also BINFO_VIRTUALS. What things can this be used on: RECORD_TYPEs @item TYPE_BINFO_VTABLE Points to the virtual function table associated with the given type. See also BINFO_VTABLE. What things can this be used on: RECORD_TYPEs Has values of: VAR_DECLs that are virtual function tables @item TYPE_NAME Names the type. Has values of: @display 0 for things that don't have names. should be IDENTIFIER_NODE for RECORD_TYPEs UNION_TYPEs and ENUM_TYPEs. TYPE_DECL for RECORD_TYPEs, UNION_TYPEs and ENUM_TYPEs, but shouldn't be. TYPE_DECL for typedefs, unsure why. @end display What things can one use this on: @display TYPE_DECLs RECORD_TYPEs UNION_TYPEs ENUM_TYPEs @end display History: It currently points to the TYPE_DECL for RECORD_TYPEs, UNION_TYPEs and ENUM_TYPEs, but it should be history soon. @item TYPE_METHODS Synonym for @code{CLASSTYPE_METHOD_VEC}. Chained together with @code{TREE_CHAIN}. @file{dbxout.c} uses this to get at the methods of a class. @item TYPE_DECL Used to represent typedefs, and used to represent bindings layers. Components: DECL_NAME is the name of the typedef. For example, foo would be found in the DECL_NAME slot when @code{typedef int foo;} is seen. DECL_SOURCE_LINE identifies what source line number in the source file the declaration was found at. A value of 0 indicates that this TYPE_DECL is just an internal binding layer marker, and does not correspond to a user supplied typedef. DECL_SOURCE_FILE @item TYPE_FIELDS A linked list (via @code{TREE_CHAIN}) of member types of a class. The list can contain @code{TYPE_DECL}s, but there can also be other things in the list apparently. See also @code{CLASSTYPE_TAGS}. @item TYPE_VIRTUAL_P A flag used on a @code{FIELD_DECL} or a @code{VAR_DECL}, indicates it is a virtual function table or a pointer to one. When used on a @code{FUNCTION_DECL}, indicates that it is a virtual function. When used on an @code{IDENTIFIER_NODE}, indicates that a function with this same name exists and has been declared virtual. When used on types, it indicates that the type has virtual functions, or is derived from one that does. Not sure if the above about virtual function tables is still true. See also info on @code{DECL_VIRTUAL_P}. What things can this be used on: FIELD_DECLs, VAR_DECLs, FUNCTION_DECLs, IDENTIFIER_NODEs @item VF_BASETYPE_VALUE Get the associated type from the binfo that caused the given vfield to exist. This is the least derived class (the most parent class) that needed a virtual function table. It is probably the case that all uses of this field are misguided, but they need to be examined on a case-by-case basis. See history for more information on why the previous statement was made. Set at @code{finish_base_struct} time. What things can this be used on: TREE_LISTs that are vfields History: This field was used to determine if a virtual function table's slot should be filled in with a certain virtual function, by checking to see if the type returned by VF_BASETYPE_VALUE was a parent of the context in which the old virtual function existed. This incorrectly assumes that a given type _could_ not appear as a parent twice in a given inheritance lattice. For single inheritance, this would in fact work, because a type could not possibly appear more than once in an inheritance lattice, but with multiple inheritance, a type can appear more than once. @item VF_BINFO_VALUE Identifies the binfo that caused this vfield to exist. If this vfield is from the first direct base class that has a virtual function table, then VF_BINFO_VALUE is NULL_TREE, otherwise it will be the binfo of the direct base where the vfield came from. Can use @code{TREE_VIA_VIRTUAL} on result to find out if it is a virtual base class. Related to the binfo found by @example get_binfo (VF_BASETYPE_VALUE (vfield), t, 0) @end example @noindent where @samp{t} is the type that has the given vfield. @example get_binfo (VF_BASETYPE_VALUE (vfield), t, 0) @end example @noindent will return the binfo for the given vfield. May or may not be set at @code{modify_vtable_entries} time. Set at @code{finish_base_struct} time. What things can this be used on: TREE_LISTs that are vfields @item VF_DERIVED_VALUE Identifies the type of the most derived class of the vfield, excluding the class this vfield is for. Set at @code{finish_base_struct} time. What things can this be used on: TREE_LISTs that are vfields @item VF_NORMAL_VALUE Identifies the type of the most derived class of the vfield, including the class this vfield is for. Set at @code{finish_base_struct} time. What things can this be used on: TREE_LISTs that are vfields @item WRITABLE_VTABLES This is a option that can be defined when building the compiler, that will cause the compiler to output vtables into the data segment so that the vtables maybe written. This is undefined by default, because normally the vtables should be unwritable. People that implement object I/O facilities may, or people that want to change the dynamic type of objects may want to have the vtables writable. Another way of achieving this would be to make a copy of the vtable into writable memory, but the drawback there is that that method only changes the type for one object. @end table @node Typical Behavior, Coding Conventions, Macros, Top @section Typical Behavior @cindex parse errors Whenever seemingly normal code fails with errors like @code{syntax error at `\@{'}, it's highly likely that grokdeclarator is returning a NULL_TREE for whatever reason. @node Coding Conventions, Templates, Typical Behavior, Top @section Coding Conventions It should never be that case that trees are modified in-place by the back-end, @emph{unless} it is guaranteed that the semantics are the same no matter how shared the tree structure is. @file{fold-const.c} still has some cases where this is not true, but rms hypothesizes that this will never be a problem. @node Templates, Access Control, Coding Conventions, Top @section Templates A template is represented by a @code{TEMPLATE_DECL}. The specific fields used are: @table @code @item DECL_TEMPLATE_RESULT The generic decl on which instantiations are based. This looks just like any other decl. @item DECL_TEMPLATE_PARMS The parameters to this template. @end table The generic decl is parsed as much like any other decl as possible, given the parameterization. The template decl is not built up until the generic decl has been completed. For template classes, a template decl is generated for each member function and static data member, as well. Template members of template classes are represented by a TEMPLATE_DECL for the class' parameters around another TEMPLATE_DECL for the member's parameters. All declarations that are instantiations or specializations of templates refer to their template and parameters through DECL_TEMPLATE_INFO. How should I handle parsing member functions with the proper param decls? Set them up again or try to use the same ones? Currently we do the former. We can probably do this without any extra machinery in store_pending_inline, by deducing the parameters from the decl in do_pending_inlines. PRE_PARSED_TEMPLATE_DECL? If a base is a parm, we can't check anything about it. If a base is not a parm, we need to check it for name binding. Do finish_base_struct if no bases are parameterized (only if none, including indirect, are parms). Nah, don't bother trying to do any of this until instantiation -- we only need to do name binding in advance. Always set up method vec and fields, inc. synthesized methods. Really? We can't know the types of the copy folks, or whether we need a destructor, or can have a default ctor, until we know our bases and fields. Otherwise, we can assume and fix ourselves later. Hopefully. @node Access Control, Error Reporting, Templates, Top @section Access Control The function compute_access returns one of three values: @table @code @item access_public means that the field can be accessed by the current lexical scope. @item access_protected means that the field cannot be accessed by the current lexical scope because it is protected. @item access_private means that the field cannot be accessed by the current lexical scope because it is private. @end table DECL_ACCESS is used for access declarations; alter_access creates a list of types and accesses for a given decl. Formerly, DECL_@{PUBLIC,PROTECTED,PRIVATE@} corresponded to the return codes of compute_access and were used as a cache for compute_access. Now they are not used at all. TREE_PROTECTED and TREE_PRIVATE are used to record the access levels granted by the containing class. BEWARE: TREE_PUBLIC means something completely unrelated to access control! @node Error Reporting, Parser, Access Control, Top @section Error Reporting The C++ front-end uses a call-back mechanism to allow functions to print out reasonable strings for types and functions without putting extra logic in the functions where errors are found. The interface is through the @code{cp_error} function (or @code{cp_warning}, etc.). The syntax is exactly like that of @code{error}, except that a few more conversions are supported: @itemize @bullet @item %C indicates a value of `enum tree_code'. @item %D indicates a *_DECL node. @item %E indicates a *_EXPR node. @item %L indicates a value of `enum languages'. @item %P indicates the name of a parameter (i.e. "this", "1", "2", ...) @item %T indicates a *_TYPE node. @item %O indicates the name of an operator (MODIFY_EXPR -> "operator ="). @end itemize There is some overlap between these; for instance, any of the node options can be used for printing an identifier (though only @code{%D} tries to decipher function names). For a more verbose message (@code{class foo} as opposed to just @code{foo}, including the return type for functions), use @code{%#c}. To have the line number on the error message indicate the line of the DECL, use @code{cp_error_at} and its ilk; to indicate which argument you want, use @code{%+D}, or it will default to the first. @node Parser, Exception Handling, Error Reporting, Top @section Parser Some comments on the parser: The @code{after_type_declarator} / @code{notype_declarator} hack is necessary in order to allow redeclarations of @code{TYPENAME}s, for instance @example typedef int foo; class A @{ char *foo; @}; @end example In the above, the first @code{foo} is parsed as a @code{notype_declarator}, and the second as a @code{after_type_declarator}. Ambiguities: There are currently four reduce/reduce ambiguities in the parser. They are: 1) Between @code{template_parm} and @code{named_class_head_sans_basetype}, for the tokens @code{aggr identifier}. This situation occurs in code looking like @example template class A @{ @}; @end example It is ambiguous whether @code{class T} should be parsed as the declaration of a template type parameter named @code{T} or an unnamed constant parameter of type @code{class T}. Section 14.6, paragraph 3 of the January '94 working paper states that the first interpretation is the correct one. This ambiguity results in two reduce/reduce conflicts. 2) Between @code{primary} and @code{type_id} for code like @samp{int()} in places where both can be accepted, such as the argument to @code{sizeof}. Section 8.1 of the pre-San Diego working paper specifies that these ambiguous constructs will be interpreted as @code{typename}s. This ambiguity results in six reduce/reduce conflicts between @samp{absdcl} and @samp{functional_cast}. 3) Between @code{functional_cast} and @code{complex_direct_notype_declarator}, for various token strings. This situation occurs in code looking like @example int (*a); @end example This code is ambiguous; it could be a declaration of the variable @samp{a} as a pointer to @samp{int}, or it could be a functional cast of @samp{*a} to @samp{int}. Section 6.8 specifies that the former interpretation is correct. This ambiguity results in 7 reduce/reduce conflicts. Another aspect of this ambiguity is code like 'int (x[2]);', which is resolved at the '[' and accounts for 6 reduce/reduce conflicts between @samp{direct_notype_declarator} and @samp{primary}/@samp{overqualified_id}. Finally, there are 4 r/r conflicts between @samp{expr_or_declarator} and @samp{primary} over code like 'int (a);', which could probably be resolved but would also probably be more trouble than it's worth. In all, this situation accounts for 17 conflicts. Ack! The second case above is responsible for the failure to parse 'LinppFile ppfile (String (argv[1]), &outs, argc, argv);' (from Rogue Wave Math.h++) as an object declaration, and must be fixed so that it does not resolve until later. 4) Indirectly between @code{after_type_declarator} and @code{parm}, for type names. This occurs in (as one example) code like @example typedef int foo, bar; class A @{ foo (bar); @}; @end example What is @code{bar} inside the class definition? We currently interpret it as a @code{parm}, as does Cfront, but IBM xlC interprets it as an @code{after_type_declarator}. I believe that xlC is correct, in light of 7.1p2, which says "The longest sequence of @i{decl-specifiers} that could possibly be a type name is taken as the @i{decl-specifier-seq} of a @i{declaration}." However, it seems clear that this rule must be violated in the case of constructors. This ambiguity accounts for 8 conflicts. Unlike the others, this ambiguity is not recognized by the Working Paper. @node Exception Handling, Free Store, Parser, Top @section Exception Handling Note, exception handling in g++ is still under development. This section describes the mapping of C++ exceptions in the C++ front-end, into the back-end exception handling framework. The basic mechanism of exception handling in the back-end is unwind-protect a la elisp. This is a general, robust, and language independent representation for exceptions. The C++ front-end exceptions are mapping into the unwind-protect semantics by the C++ front-end. The mapping is describe below. When -frtti is used, rtti is used to do exception object type checking, when it isn't used, the encoded name for the type of the object being thrown is used instead. All code that originates exceptions, even code that throws exceptions as a side effect, like dynamic casting, and all code that catches exceptions must be compiled with either -frtti, or -fno-rtti. It is not possible to mix rtti base exception handling objects with code that doesn't use rtti. The exceptions to this, are code that doesn't catch or throw exceptions, catch (...), and code that just rethrows an exception. Currently we use the normal mangling used in building functions names (int's are "i", const char * is PCc) to build the non-rtti base type descriptors for exception handling. These descriptors are just plain NULL terminated strings, and internally they are passed around as char *. In C++, all cleanups should be protected by exception regions. The region starts just after the reason why the cleanup is created has ended. For example, with an automatic variable, that has a constructor, it would be right after the constructor is run. The region ends just before the finalization is expanded. Since the backend may expand the cleanup multiple times along different paths, once for normal end of the region, once for non-local gotos, once for returns, etc, the backend must take special care to protect the finalization expansion, if the expansion is for any other reason than normal region end, and it is `inline' (it is inside the exception region). The backend can either choose to move them out of line, or it can created an exception region over the finalization to protect it, and in the handler associated with it, it would not run the finalization as it otherwise would have, but rather just rethrow to the outer handler, careful to skip the normal handler for the original region. In Ada, they will use the more runtime intensive approach of having fewer regions, but at the cost of additional work at run time, to keep a list of things that need cleanups. When a variable has finished construction, they add the cleanup to the list, when the come to the end of the lifetime of the variable, the run the list down. If the take a hit before the section finishes normally, they examine the list for actions to perform. I hope they add this logic into the back-end, as it would be nice to get that alternative approach in C++. On an rs6000, xlC stores exception objects on that stack, under the try block. When is unwinds down into a handler, the frame pointer is adjusted back to the normal value for the frame in which the handler resides, and the stack pointer is left unchanged from the time at which the object was thrown. This is so that there is always someplace for the exception object, and nothing can overwrite it, once we start throwing. The only bad part, is that the stack remains large. The below points out some things that work in g++'s exception handling. All completely constructed temps and local variables are cleaned up in all unwinded scopes. Completely constructed parts of partially constructed objects are cleaned up. This includes partially built arrays. Exception specifications are now handled. Thrown objects are now cleaned up all the time. We can now tell if we have an active exception being thrown or not (__eh_type != 0). We use this to call terminate if someone does a throw; without there being an active exception object. uncaught_exception () works. Exception handling should work right if you optimize. Exception handling should work with -fpic or -fPIC. The below points out some flaws in g++'s exception handling, as it now stands. Only exact type matching or reference matching of throw types works when -fno-rtti is used. Only works on a SPARC (like Suns) (both -mflat and -mno-flat models work), SPARClite, Hitachi SH, i386, arm, rs6000, PowerPC, Alpha, mips, VAX, m68k and z8k machines. SPARC v9 may not work. HPPA is mostly done, but throwing between a shared library and user code doesn't yet work. Some targets have support for data-driven unwinding. Partial support is in for all other machines, but a stack unwinder called __unwind_function has to be written, and added to libgcc2 for them. The new EH code doesn't rely upon the __unwind_function for C++ code, instead it creates per function unwinders right inside the function, unfortunately, on many platforms the definition of RETURN_ADDR_RTX in the tm.h file for the machine port is wrong. See below for details on __unwind_function. RTL_EXPRs for EH cond variables for && and || exprs should probably be wrapped in UNSAVE_EXPRs, and RTL_EXPRs tweaked so that they can be unsaved. We only do pointer conversions on exception matching a la 15.3 p2 case 3: `A handler with type T, const T, T&, or const T& is a match for a throw-expression with an object of type E if [3]T is a pointer type and E is a pointer type that can be converted to T by a standard pointer conversion (_conv.ptr_) not involving conversions to pointers to private or protected base classes.' when -frtti is given. We don't call delete on new expressions that die because the ctor threw an exception. See except/18 for a test case. 15.2 para 13: The exception being handled should be rethrown if control reaches the end of a handler of the function-try-block of a constructor or destructor, right now, it is not. 15.2 para 12: If a return statement appears in a handler of function-try-block of a constructor, the program is ill-formed, but this isn't diagnosed. 15.2 para 11: If the handlers of a function-try-block contain a jump into the body of a constructor or destructor, the program is ill-formed, but this isn't diagnosed. 15.2 para 9: Check that the fully constructed base classes and members of an object are destroyed before entering the handler of a function-try-block of a constructor or destructor for that object. build_exception_variant should sort the incoming list, so that it implements set compares, not exact list equality. Type smashing should smash exception specifications using set union. Thrown objects are usually allocated on the heap, in the usual way. If one runs out of heap space, throwing an object will probably never work. This could be relaxed some by passing an __in_chrg parameter to track who has control over the exception object. Thrown objects are not allocated on the heap when they are pointer to object types. We should extend it so that all small (<4*sizeof(void*)) objects are stored directly, instead of allocated on the heap. When the backend returns a value, it can create new exception regions that need protecting. The new region should rethrow the object in context of the last associated cleanup that ran to completion. The structure of the code that is generated for C++ exception handling code is shown below: @example Ln: throw value; copy value onto heap jump throw (Ln, id, address of copy of value on heap) try @{ +Lstart: the start of the main EH region |... ... +Lend: the end of the main EH region @} catch (T o) @{ ...1 @} Lresume: nop used to make sure there is something before the next region ends, if there is one ... ... jump Ldone [ Lmainhandler: handler for the region Lstart-Lend cleanup ] zero or more, depending upon automatic vars with dtors +Lpartial: | jump Lover +Lhere: rethrow (Lhere, same id, same obj); Lterm: handler for the region Lpartial-Lhere call terminate Lover: [ [ call throw_type_match if (eq) @{ ] these lines disappear when there is no catch condition +Lsregion2: | ...1 | jump Lresume |Lhandler: handler for the region Lsregion2-Leregion2 | rethrow (Lresume, same id, same obj); +Leregion2 @} ] there are zero or more of these sections, depending upon how many catch clauses there are ----------------------------- expand_end_all_catch -------------------------- here we have fallen off the end of all catch clauses, so we rethrow to outer rethrow (Lresume, same id, same obj); ----------------------------- expand_end_all_catch -------------------------- [ L1: maybe throw routine ] depending upon if we have expanded it or not Ldone: ret start_all_catch emits labels: Lresume, @end example The __unwind_function takes a pointer to the throw handler, and is expected to pop the stack frame that was built to call it, as well as the frame underneath and then jump to the throw handler. It must restore all registers to their proper values as well as all other machine state as determined by the context in which we are unwinding into. The way I normally start is to compile: void *g; foo(void* a) @{ g = a; @} with -S, and change the thing that alters the PC (return, or ret usually) to not alter the PC, making sure to leave all other semantics (like adjusting the stack pointer, or frame pointers) in. After that, replicate the prologue once more at the end, again, changing the PC altering instructions, and finally, at the very end, jump to `g'. It takes about a week to write this routine, if someone wants to volunteer to write this routine for any architecture, exception support for that architecture will be added to g++. Please send in those code donations. One other thing that needs to be done, is to double check that __builtin_return_address (0) works. @subsection Specific Targets For the alpha, the __unwind_function will be something resembling: @example void __unwind_function(void *ptr) @{ /* First frame */ asm ("ldq $15, 8($30)"); /* get the saved frame ptr; 15 is fp, 30 is sp */ asm ("bis $15, $15, $30"); /* reload sp with the fp we found */ /* Second frame */ asm ("ldq $15, 8($30)"); /* fp */ asm ("bis $15, $15, $30"); /* reload sp with the fp we found */ /* Return */ asm ("ret $31, ($16), 1"); /* return to PTR, stored in a0 */ @} @end example @noindent However, there are a few problems preventing it from working. First of all, the gcc-internal function @code{__builtin_return_address} needs to work given an argument of 0 for the alpha. As it stands as of August 30th, 1995, the code for @code{BUILT_IN_RETURN_ADDRESS} in @file{expr.c} will definitely not work on the alpha. Instead, we need to define the macros @code{DYNAMIC_CHAIN_ADDRESS} (maybe), @code{RETURN_ADDR_IN_PREVIOUS_FRAME}, and definitely need a new definition for @code{RETURN_ADDR_RTX}. In addition (and more importantly), we need a way to reliably find the frame pointer on the alpha. The use of the value 8 above to restore the frame pointer (register 15) is incorrect. On many systems, the frame pointer is consistently offset to a specific point on the stack. On the alpha, however, the frame pointer is pushed last. First the return address is stored, then any other registers are saved (e.g., @code{s0}), and finally the frame pointer is put in place. So @code{fp} could have an offset of 8, but if the calling function saved any registers at all, they add to the offset. The only places the frame size is noted are with the @samp{.frame} directive, for use by the debugger and the OSF exception handling model (useless to us), and in the initial computation of the new value for @code{sp}, the stack pointer. For example, the function may start with: @example lda $30,-32($30) .frame $15,32,$26,0 @end example @noindent The 32 above is exactly the value we need. With this, we can be sure that the frame pointer is stored 8 bytes less---in this case, at 24(sp)). The drawback is that there is no way that I (Brendan) have found to let us discover the size of a previous frame @emph{inside} the definition of @code{__unwind_function}. So to accomplish exception handling support on the alpha, we need two things: first, a way to figure out where the frame pointer was stored, and second, a functional @code{__builtin_return_address} implementation for except.c to be able to use it. Or just support DWARF 2 unwind info. @subsection New Backend Exception Support This subsection discusses various aspects of the design of the data-driven model being implemented for the exception handling backend. The goal is to generate enough data during the compilation of user code, such that we can dynamically unwind through functions at run time with a single routine (@code{__throw}) that lives in libgcc.a, built by the compiler, and dispatch into associated exception handlers. This information is generated by the DWARF 2 debugging backend, and includes all of the information __throw needs to unwind an arbitrary frame. It specifies where all of the saved registers and the return address can be found at any point in the function. Major disadvantages when enabling exceptions are: @itemize @bullet @item Code that uses caller saved registers, can't, when flow can be transferred into that code from an exception handler. In high performance code this should not usually be true, so the effects should be minimal. @end itemize @subsection Backend Exception Support The backend must be extended to fully support exceptions. Right now there are a few hooks into the alpha exception handling backend that resides in the C++ frontend from that backend that allows exception handling to work in g++. An exception region is a segment of generated code that has a handler associated with it. The exception regions are denoted in the generated code as address ranges denoted by a starting PC value and an ending PC value of the region. Some of the limitations with this scheme are: @itemize @bullet @item The backend replicates insns for such things as loop unrolling and function inlining. Right now, there are no hooks into the frontend's exception handling backend to handle the replication of insns. When replication happens, a new exception region descriptor needs to be generated for the new region. @item The backend expects to be able to rearrange code, for things like jump optimization. Any rearranging of the code needs have exception region descriptors updated appropriately. @item The backend can eliminate dead code. Any associated exception region descriptor that refers to fully contained code that has been eliminated should also be removed, although not doing this is harmless in terms of semantics. @end itemize The above is not meant to be exhaustive, but does include all things I have thought of so far. I am sure other limitations exist. Below are some notes on the migration of the exception handling code backend from the C++ frontend to the backend. NOTEs are to be used to denote the start of an exception region, and the end of the region. I presume that the interface used to generate these notes in the backend would be two functions, start_exception_region and end_exception_region (or something like that). The frontends are required to call them in pairs. When marking the end of a region, an argument can be passed to indicate the handler for the marked region. This can be passed in many ways, currently a tree is used. Another possibility would be insns for the handler, or a label that denotes a handler. I have a feeling insns might be the best way to pass it. Semantics are, if an exception is thrown inside the region, control is transferred unconditionally to the handler. If control passes through the handler, then the backend is to rethrow the exception, in the context of the end of the original region. The handler is protected by the conventional mechanisms; it is the frontend's responsibility to protect the handler, if special semantics are required. This is a very low level view, and it would be nice is the backend supported a somewhat higher level view in addition to this view. This higher level could include source line number, name of the source file, name of the language that threw the exception and possibly the name of the exception. Kenner may want to rope you into doing more than just the basics required by C++. You will have to resolve this. He may want you to do support for non-local gotos, first scan for exception handler, if none is found, allow the debugger to be entered, without any cleanups being done. To do this, the backend would have to know the difference between a cleanup-rethrower, and a real handler, if would also have to have a way to know if a handler `matches' a thrown exception, and this is frontend specific. The stack unwinder is one of the hardest parts to do. It is highly machine dependent. The form that kenner seems to like was a couple of macros, that would do the machine dependent grunt work. One preexisting function that might be of some use is __builtin_return_address (). One macro he seemed to want was __builtin_return_address, and the other would do the hard work of fixing up the registers, adjusting the stack pointer, frame pointer, arg pointer and so on. @node Free Store, Mangling, Exception Handling, Top @section Free Store @code{operator new []} adds a magic cookie to the beginning of arrays for which the number of elements will be needed by @code{operator delete []}. These are arrays of objects with destructors and arrays of objects that define @code{operator delete []} with the optional size_t argument. This cookie can be examined from a program as follows: @example typedef unsigned long size_t; extern "C" int printf (const char *, ...); size_t nelts (void *p) @{ struct cookie @{ size_t nelts __attribute__ ((aligned (sizeof (double)))); @}; cookie *cp = (cookie *)p; --cp; return cp->nelts; @} struct A @{ ~A() @{ @} @}; main() @{ A *ap = new A[3]; printf ("%ld\n", nelts (ap)); @} @end example @section Linkage The linkage code in g++ is horribly twisted in order to meet two design goals: 1) Avoid unnecessary emission of inlines and vtables. 2) Support pedantic assemblers like the one in AIX. To meet the first goal, we defer emission of inlines and vtables until the end of the translation unit, where we can decide whether or not they are needed, and how to emit them if they are. -@node Mangling, Concept Index, Free Store, Top +@node Mangling, Vtables, Free Store, Top @section Function name mangling for C++ and Java Both C++ and Jave provide overloaded function and methods, which are methods with the same types but different parameter lists. Selecting the correct version is done at compile time. Though the overloaded functions have the same name in the source code, they need to be translated into different assembler-level names, since typical assemblers and linkers cannot handle overloading. This process of encoding the parameter types with the method name into a unique name is called @dfn{name mangling}. The inverse process is called @dfn{demangling}. It is convenient that C++ and Java use compatible mangling schemes, since the makes life easier for tools such as gdb, and it eases integration between C++ and Java. Note there is also a standard "Jave Native Interface" (JNI) which implements a different calling convention, and uses a different mangling scheme. The JNI is a rather abstract ABI so Java can call methods written in C or C++; we are concerned here about a lower-level interface primarily intended for methods written in Java, but that can also be used for C++ (and less easily C). Note that on systems that follow BSD tradition, a C identifier @code{var} would get "mangled" into the assembler name @samp{_var}. On such systems, all other mangled names are also prefixed by a @samp{_} which is not shown in the following examples. @subsection Method name mangling C++ mangles a method by emitting the function name, followed by @code{__}, followed by encodings of any method qualifiers (such as @code{const}), followed by the mangling of the method's class, followed by the mangling of the parameters, in order. For example @code{Foo::bar(int, long) const} is mangled as @samp{bar__C3Fooil}. For a constructor, the method name is left out. That is @code{Foo::Foo(int, long) const} is mangled as @samp{__C3Fooil}. GNU Java does the same. @subsection Primitive types The C++ types @code{int}, @code{long}, @code{short}, @code{char}, and @code{long long} are mangled as @samp{i}, @samp{l}, @samp{s}, @samp{c}, and @samp{x}, respectively. The corresponding unsigned types have @samp{U} prefixed to the mangling. The type @code{signed char} is mangled @samp{Sc}. The C++ and Java floating-point types @code{float} and @code{double} are mangled as @samp{f} and @samp{d} respectively. The C++ @code{bool} type and the Java @code{boolean} type are mangled as @samp{b}. The C++ @code{wchar_t} and the Java @code{char} types are mangled as @samp{w}. The Java integral types @code{byte}, @code{short}, @code{int} and @code{long} are mangled as @samp{c}, @samp{s}, @samp{i}, and @samp{x}, respectively. C++ code that has included @code{javatypes.h} will mangle the typedefs @code{jbyte}, @code{jshort}, @code{jint} and @code{jlong} as respectively @samp{c}, @samp{s}, @samp{i}, and @samp{x}. (This has not been implemented yet.) @subsection Mangling of simple names A simple class, package, template, or namespace name is encoded as the number of characters in the name, followed by the actual characters. Thus the class @code{Foo} is encoded as @samp{3Foo}. If any of the characters in the name are not alphanumeric (i.e not one of the standard ASCII letters, digits, or '_'), or the initial character is a digit, then the name is mangled as a sequence of encoded Unicode letters. A Unicode encoding starts with a @samp{U} to indicate that Unicode escapes are used, followed by the number of bytes used by the Unicode encoding, followed by the bytes representing the encoding. ASSCI letters and non-initial digits are encoded without change. However, all other characters (including underscore and initial digits) are translated into a sequence starting with an underscore, followed by the big-endian 4-hex-digit lower-case encoding of the character. If a method name contains Unicode-escaped characters, the entire mangled method name is followed by a @samp{U}. For example, the method @code{X\u0319::M\u002B(int)} is encoded as @samp{M_002b__U6X_0319iU}. @subsection Pointer and reference types A C++ pointer type is mangled as @samp{P} followed by the mangling of the type pointed to. A C++ reference type as mangled as @samp{R} followed by the mangling of the type referenced. A Java object reference type is equivalent to a C++ pointer parameter, so we mangle such an parameter type as @samp{P} followed by the mangling of the class name. @subsection Squangled type compression Squangling (enabled with the @samp{-fsquangle} option), utilizes the @samp{B} code to indicate reuse of a previously seen type within an indentifier. Types are recognized in a left to right manner and given increasing values, which are appended to the code in the standard manner. Ie, multiple digit numbers are delimited by @samp{_} characters. A type is considered to be any non primitive type, regardless of whether its a parameter, template parameter, or entire template. Certain codes are considered modifiers of a type, and are not included as part of the type. These are the @samp{C}, @samp{V}, @samp{P}, @samp{A}, @samp{R}, @samp{U} and @samp{u} codes, denoting constant, volatile, pointer, array, reference, unsigned, and restrict. These codes may precede a @samp{B} type in order to make the required modifications to the type. For example: @example template class class1 @{ @}; template class class2 @{ @}; class class3 @{ @}; int f(class2 > a ,int b, const class1&c, class3 *d) @{ @} B0 -> class2 B1 -> class1 B2 -> class3 @end example Produces the mangled name @samp{f__FGt6class21Zt6class11Z6class3iRCB1PB2}. The int parameter is a basic type, and does not receive a B encoding... @subsection Qualified names Both C++ and Java allow a class to be lexically nested inside another class. C++ also supports namespaces (not yet implemented by G++). Java also supports packages. These are all mangled the same way: First the letter @samp{Q} indicates that we are emitting a qualified name. That is followed by the number of parts in the qualified name. If that number is 9 or less, it is emitted with no delimiters. Otherwise, an underscore is written before and after the count. Then follows each part of the qualified name, as described above. For example @code{Foo::\u0319::Bar} is encoded as @samp{Q33FooU5_03193Bar}. Squangling utilizes the the letter @samp{K} to indicate a remembered portion of a qualified name. As qualified names are processed for an identifier, the names are numbered and remembered in a manner similar to the @samp{B} type compression code. Names are recognized left to right, and given increasing values, which are appended to the code in the standard manner. ie, multiple digit numbers are delimited by @samp{_} characters. For example @example class Andrew @{ class WasHere @{ class AndHereToo @{ @}; @}; @}; f(Andrew&r1, Andrew::WasHere& r2, Andrew::WasHere::AndHereToo& r3) @{ @} K0 -> Andrew K1 -> Andrew::WasHere K2 -> Andrew::WasHere::AndHereToo @end example Function @samp{f()} would be mangled as : @samp{f__FR6AndrewRQ2K07WasHereRQ2K110AndHereToo} There are some occasions when either a @samp{B} or @samp{K} code could be chosen, preference is always given to the @samp{B} code. Ie, the example in the section on @samp{B} mangling could have used a @samp{K} code instead of @samp{B2}. @subsection Templates A class template instantiation is encoded as the letter @samp{t}, followed by the encoding of the template name, followed the number of template parameters, followed by encoding of the template parameters. If a template parameter is a type, it is written as a @samp{Z} followed by the encoding of the type. A function template specialization (either an instantiation or an explicit specialization) is encoded by an @samp{H} followed by the encoding of the template parameters, as described above, followed by an @samp{_}, the encoding of the argument types to the template function (not the specialization), another @samp{_}, and the return type. (Like the argument types, the return type is the return type of the function template, not the specialization.) Template parameters in the argument and return types are encoded by an @samp{X} for type parameters, or a @samp{Y} for constant parameters, an index indicating their position in the template parameter list declaration, and their template depth. @subsection Arrays C++ array types are mangled by emitting @samp{A}, followed by the length of the array, followed by an @samp{_}, followed by the mangling of the element type. Of course, normally array parameter types decay into a pointer types, so you don't see this. Java arrays are objects. A Java type @code{T[]} is mangled as if it were the C++ type @code{JArray}. For example @code{java.lang.String[]} is encoded as @samp{Pt6JArray1ZPQ34java4lang6String}. @subsection Static fields Both C++ and Java classes can have static fields. These are allocated statically, and are shared among all instances. The mangling starts with a prefix (@samp{_} in most systems), which is followed by the mangling of the class name, followed by the "joiner" and finally the field name. The joiner (see @code{JOINER} in @code{cp-tree.h}) is a special separator character. For historical reasons (and idiosyncracies of assembler syntax) it can @samp{$} or @samp{.} (or even @samp{_} on a few systems). If the joiner is @samp{_} then the prefix is @samp{__static_} instead of just @samp{_}. For example @code{Foo::Bar::var} (or @code{Foo.Bar.var} in Java syntax) would be encoded as @samp{_Q23Foo3Bar$var} or @samp{_Q23Foo3Bar.var} (or rarely @samp{__static_Q23Foo3Bar_var}). If the name of a static variable needs Unicode escapes, the Unicode indicator @samp{U} comes before the "joiner". This @code{\u1234Foo::var\u3445} becomes @code{_U8_1234FooU.var_3445}. @subsection Table of demangling code characters The following special characters are used in mangling: @table @samp @item A Indicates a C++ array type. @item b Encodes the C++ @code{bool} type, and the Java @code{boolean} type. @item B Used for squangling. Similar in concept to the 'T' non-squangled code. @item c Encodes the C++ @code{char} type, and the Java @code{byte} type. @item C A modifier to indicate a @code{const} type. Also used to indicate a @code{const} member function (in which cases it precedes the encoding of the method's class). @item d Encodes the C++ and Java @code{double} types. @item e Indicates extra unknown arguments @code{...}. @item E Indicates the opening parenthesis of an expression. @item f Encodes the C++ and Java @code{float} types. @item F Used to indicate a function type. @item H Used to indicate a template function. @item i Encodes the C++ and Java @code{int} types. @item I Encodes typedef names of the form @code{int@var{n}_t}, where @var{n} is a positive decimal number. The @samp{I} is followed by either two hexidecimal digits, which encode the value of @var{n}, or by an arbitrary number of hexidecimal digits between underscores. For example, @samp{I40} encodes the type @code{int64_t}, and @samp{I_200_} encodes the type @code{int512_t}. @item J Indicates a complex type. @item K Used by squangling to compress qualified names. @item l Encodes the C++ @code{long} type. @item n Immediate repeated type. Followed by the repeat count. @item N Repeated type. Followed by the repeat count of the repeated type, followed by the type index of the repeated type. Due to a bug in g++ 2.7.2, this is only generated if index is 0. Superceded by @samp{n} when squangling. @item P Indicates a pointer type. Followed by the type pointed to. @item Q Used to mangle qualified names, which arise from nested classes. Also used for namespaces. In Java used to mangle package-qualified names, and inner classes. @item r Encodes the GNU C++ @code{long double} type. @item R Indicates a reference type. Followed by the referenced type. @item s Encodes the C++ and java @code{short} types. @item S A modifier that indicates that the following integer type is signed. Only used with @code{char}. Also used as a modifier to indicate a static member function. @item t Indicates a template instantiation. @item T A back reference to a previously seen type. @item U A modifier that indicates that the following integer type is unsigned. Also used to indicate that the following class or namespace name is encoded using Unicode-mangling. @item u The @code{restrict} type qualifier. @item v Encodes the C++ and Java @code{void} types. @item V A modifier for a @code{volatile} type or method. @item w Encodes the C++ @code{wchar_t} type, and the Java @code{char} types. @item W Indicates the closing parenthesis of an expression. @item x Encodes the GNU C++ @code{long long} type, and the Java @code{long} type. @item X Encodes a template type parameter, when part of a function type. @item Y Encodes a template constant parameter, when part of a function type. @item Z Used for template type parameters. @end table The letters @samp{G}, @samp{M}, @samp{O}, and @samp{p} also seem to be used for obscure purposes ... -@node Concept Index, , Mangling, Top +@node Vtables, Concept Index, Mangling, Top +@section Virtual Tables + +In order to invoke virtual functions, GNU C++ uses virtual tables. Each +virtual function gets an index, and the table entry points to the +overridden function to call. Sometimes, and adjustment to the this +pointer has to be made before calling a virtual function: + +@example +struct A@{ + int i; + virtual void foo(); +@}; + +struct B@{ + int j; + virtual void bar(); +@}; + +struct C:A,B@{ + virtual void bar(); +@}; + +void C::bar() +@{ + i++; +@} + +int main() +@{ + C *c = new C; + B *b = c; + c->bar(); +@} +@end example + +Here, casting from @samp{c} to @samp{b} adds an offset. When @samp{bar} +is called, this offset needs to be subtracted, so that @samp{C::bar} can +properly access @samp{i}. One approach of achieving this is to use +@emph{thunks}, which are small half-functions put into the virtual +table. The modify the first argument (the @samp{this} pointer), and then +jump into the real function. + +The other (traditional) approach is to have an additional integer in the +virtual table which is added to this. This is an additional overhead +both at the function call, and in the size of virtual tables: In the +case of single inheritance (or for the first base class), these integers +will always be zero. + +@subsection Virtual Base Classes with Virtual Tables + +In case of virtual bases, the code is even more +complicated. Constructors and destructors need to know whether they are +"in charge" of the virtual bases, and an implicit integer +@samp{__in_chrg} for that purpose. + +@example +struct A@{ + int i; + virtual void bar(); + void call_bar()@{bar();@} +@}; + +struct B:virtual A@{ + B(); + int j; + virtual void bar(); +@}; + +B::B()@{ + call_bar(); +@} + +struct C@{ + int k; +@}; + +struct D:C,B@{ + int l; + virtual void bar(); +@}; + +@end example + +When constructing an instance of B, it will have the following layout: +@samp{vbase pointer to A}, @samp{j}, @samp{A virtual table}, @samp{i}. +On a 32-bit machine, downcasting from @samp{A*} to @samp{B*} would need +to subtract 8, which would be the thunk executed when calling +@samp{B::bar} inside @samp{call_bar}. + +When constructing an instance of D, it will have a different layout: +@samp{k}, @samp{vbase pointer to A}, @samp{j}, @samp{l}, @samp{A virtual +table}, @samp{i}. So, when downcasting from @samp{A*} to @samp{B*} in a +@samp{D} object, the offset would be @samp{12}. + +This means that during construction of the @samp{B} base of a @samp{D} +object, a virtual table is needed which has a @samp{-12} thunk to +@samp{B::bar}. This is @emph{only} needed during construction and +destruction, as the full object will use a @samp{-16} thunk to +@samp{D::bar}. + +In order to implement this, the compiler generates an implicit argument +(in addition to @code{__in_chrg}): the virtual list argument +@code{__vlist}. This is a list of virtual tables needed during +construction and destruction. The virtual pointers are ordered in the +way they are used during construction; the destructors will process the +array in reverse order. The ordering is as follows: +@itemize @bullet +@item +If the class is in charge, the vlist starts with virtual table pointers +for the virtual bases that have virtual bases themselves. Here, only +@emph{polymorphic} virtual bases (pvbases) are interesting: if a vbase +has no virtual functions, it doesn't have a virtual table. + +@item +Next, the vlist has virtual tables for the initialization of the +non-virtual bases. These bases are not in charge, so the layout is +recursive, but ignores virtual bases during recursion. + +@item +Next, there is a number of virtual tables for each virtual base. These +are sorted in the order in which virtual bases are constructed. Each +virtual base may have more than one @code{vfield}, and therefore require +more than one @code{vtable}. The order of vtables is the same as used +when initializing vfields of non-virtual bases in a constructor. +@end itemize + +The compiler emits a virtual table list in a variable mangled as +@code{__vl.classname}. + +Class with virtual bases, but without pvbases, only have the +@code{__in_chrg} argument to their ctors and dtors: they don't have any +vfields in the vbases to initialize. + +A further problem arises with virtual destructors: A destructor +typically has only the @code{__in_chrg} argument, which also indicates +whether the destructor should call @code{operator delete}. A dtor of a +class with pvbases has an additional argument. Unfortunately, a caller +of a virtual dtor might not know whether to pass that argument or not. +Therefore, the dtor processes the @code{__vlist} argument in an +automatic variable, which is initialized from the class' vlist if the +__in_chrg flag has a zero value in bit 2 (bit mask 4), or from the +argument @code{__vlist1} if bit 2 of the __in_chrg parameter is set to +one. + +@subsection Specification of non-thunked vtables + +In the traditional implementation of vtables, each slot contains three +fields: The offset to be added to the this pointer before invoking a +virtual function, an unused field that is always zero, and the pointer +to the virtual function. The first two fields are typically 16 bits +wide. The unused field is called `index'; it may be non-zero in +pointer-to-member-functions, which use the same layout. + +The virtual table then is an array of vtable slots. The first slot is +always the virtual type info function, the other slots are in the order +in which the virtual functions appear in the class declaration. + +If a class has base classes, it may inherit other bases' vfields. Each +class may have a primary vfield; the primary vfield of the derived class +is the primary vfield of the left-most non-virtual base class. If a +class inherits a primary vfield, any new virtual functions in the +derived class are appended to the virtual table of the primary +vfield. If there are new virtual functions in the derived class, and no +primary vfield is inherited, a new vfield is introduced which becomes +primary. The redefined virtual functions fill the vtable slots inherited +from the base; new virtual functions are put into the primary vtable in +the order of declaration. If no new virtual functions are introduced, no +primary vfield is allocated. + +In a base class that has pvbases, virtual tables are needed which are +used only in the constructor (see example above). At run-time, the +virtual tables of the base class are adjusted, to reflect the new offset +of the pvbase. The compiler knows statically what offset the pvbase has +for a complete object. At run-time, the offset of the pvbase can be +extracted from the vbase pointer, which is set in the constructor of the +complete object. These two offsets result in a delta, which is used to +adjust the deltas in the vtable (the adjustment might be different for +different vtable slots). To adjust the vtables, the compiler emits code +that creates a vtable on the stack. This vtable is initialized with the +vtable for the complete base type, and then adjusted. + +In order to call a virtual function, the compiler gets the offset field +from the vtable entry, and adds it to the this pointer. It then +indirectly calls the virtual function pointer, passing the adjusted this +pointer, and any arguments the virtual function may have. + +To implement dynamic casting, the dynamic_cast function needs typeinfos +for the complete type, and the pointer to the complete type. The +typeinfo pointer is obtained by calling the virtual typeinfo function +(which doesn't take a this parameter). The pointer to the complete +object is obtained by adding the offset of the virtual typeinfo vtable +slot, since this virtual function is always implemented in the complete +object. + +@subsection Specification of thunked vtables + +For vtable thunks, each slot only consists of a pointer to the virtual +function, which might be a thunk function. The first slot in the vtable +is an offset of the this pointer to the complete object, which is needed +as a parameter to __dynamic_cast. The second slot is the virtual +typeinfo function. All other slots are allocated with the same procedure +as in the non-thunked case. Allocation of vfields also uses the same +procedure as described above. + +If the virtual function needs an adjusted this pointer, a thunk function +is emitted. If supported by the target architecture, this is only a +half-function. Such a thunk has no stack frame; it merely adjusts the +first argument of the function, and then directly branches into the +implementation of the virtual function. If the architecture does not +support half-functions (i.e. if ASM_OUTPUT_MI_THUNK is not defined), the +compiler emits a wrapper function, which copies all arguments, adjust +the this pointer, and then calls the original function. Since objects of +non-aggregate type are passed by invisible reference, this copies only +POD arguments. The approach fails for virtual functions with a variable +number of arguments. + +In order to support the vtables needed in base constructors with +pvbases, the compiler passes an implicit __vlist argument as described +above, if the version 2 thunks are used. For version 1 thunks, the base +class constructor will fill in the vtables for the complete base class, +which will incorrectly adjust the this pointer, leading to a dynamic +error. + +@node Concept Index, , Vtables, Top @section Concept Index @printindex cp @bye Index: vendor/gcc/dist/contrib/gcc/cp/init.c =================================================================== --- vendor/gcc/dist/contrib/gcc/cp/init.c (revision 60966) +++ vendor/gcc/dist/contrib/gcc/cp/init.c (revision 60967) @@ -1,3321 +1,3499 @@ /* Handle initialization things in C++. Copyright (C) 1987, 89, 92-98, 1999 Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@cygnus.com) 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. */ /* High-level class interface. */ #include "config.h" #include "system.h" #include "tree.h" #include "rtl.h" #include "cp-tree.h" #include "flags.h" #include "output.h" #include "except.h" #include "expr.h" #include "toplev.h" /* In C++, structures with well-defined constructors are initialized by those constructors, unasked. CURRENT_BASE_INIT_LIST holds a list of stmts for a BASE_INIT term in the grammar. This list has one element for each base class which must be initialized. The list elements are [basename, init], with type basetype. This allows the possibly anachronistic form (assuming d : a, b, c) "d (int a) : c(a+5), b (a-4), a (a+3)" where each successive term can be handed down the constructor line. Perhaps this was not intended. */ tree current_base_init_list, current_member_init_list; static void expand_aggr_vbase_init_1 PROTO((tree, tree, tree, tree)); static void construct_virtual_bases PROTO((tree, tree, tree, tree, tree)); static void expand_aggr_init_1 PROTO((tree, tree, tree, tree, int)); static void expand_default_init PROTO((tree, tree, tree, tree, int)); static tree build_vec_delete_1 PROTO((tree, tree, tree, tree, tree, int)); static void perform_member_init PROTO((tree, tree, tree, int)); static void sort_base_init PROTO((tree, tree *, tree *)); static tree build_builtin_delete_call PROTO((tree)); static int member_init_ok_or_else PROTO((tree, tree, const char *)); static void expand_virtual_init PROTO((tree, tree)); static tree sort_member_init PROTO((tree)); static tree initializing_context PROTO((tree)); static void expand_vec_init_try_block PROTO((tree)); static void expand_vec_init_catch_clause PROTO((tree, tree, tree, tree)); static tree build_java_class_ref PROTO((tree)); -static void expand_cleanup_for_base PROTO((tree, tree)); +static void expand_cleanup_for_base PROTO((tree, tree, tree)); +static int pvbasecount PROTO((tree, int)); /* Cache the identifier nodes for the magic field of a new cookie. */ static tree nc_nelts_field_id; static tree minus_one; /* Set up local variable for this file. MUST BE CALLED AFTER INIT_DECL_PROCESSING. */ static tree BI_header_type, BI_header_size; void init_init_processing () { tree fields[1]; minus_one = build_int_2 (-1, -1); /* Define the structure that holds header information for arrays allocated via operator new. */ BI_header_type = make_lang_type (RECORD_TYPE); nc_nelts_field_id = get_identifier ("nelts"); fields[0] = build_lang_field_decl (FIELD_DECL, nc_nelts_field_id, sizetype); finish_builtin_type (BI_header_type, "__new_cookie", fields, 0, double_type_node); BI_header_size = size_in_bytes (BI_header_type); } /* Subroutine of emit_base_init. For BINFO, initialize all the virtual function table pointers, except those that come from virtual base classes. Initialize binfo's vtable pointer, if INIT_SELF is true. CAN_ELIDE is true when we know that all virtual function table pointers in all bases have been initialized already, probably because their constructors have just be run. ADDR is the pointer to the object whos vtables we are going to initialize. REAL_BINFO is usually the same as BINFO, except when addr is not of pointer to the type of the real derived type that we want to initialize for. This is the case when addr is a pointer to a sub object of a complete object, and we only want to do part of the complete object's initialization of vtable pointers. This is done for all virtual table pointers in virtual base classes. REAL_BINFO is used to find the BINFO_VTABLE that we initialize with. BINFO is used for conversions of addr to subobjects. BINFO_TYPE (real_binfo) must be BINFO_TYPE (binfo). Relies upon binfo being inside TYPE_BINFO (TREE_TYPE (TREE_TYPE (addr))). */ void expand_direct_vtbls_init (real_binfo, binfo, init_self, can_elide, addr) tree real_binfo, binfo, addr; int init_self, can_elide; { tree real_binfos = BINFO_BASETYPES (real_binfo); tree binfos = BINFO_BASETYPES (binfo); int i, n_baselinks = real_binfos ? TREE_VEC_LENGTH (real_binfos) : 0; for (i = 0; i < n_baselinks; i++) { tree real_base_binfo = TREE_VEC_ELT (real_binfos, i); tree base_binfo = TREE_VEC_ELT (binfos, i); int is_not_base_vtable = i != CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (real_binfo)); if (! TREE_VIA_VIRTUAL (real_base_binfo)) expand_direct_vtbls_init (real_base_binfo, base_binfo, is_not_base_vtable, can_elide, addr); } #if 0 /* Before turning this on, make sure it is correct. */ if (can_elide && ! BINFO_MODIFIED (binfo)) return; #endif /* Should we use something besides CLASSTYPE_VFIELDS? */ if (init_self && CLASSTYPE_VFIELDS (BINFO_TYPE (real_binfo))) { tree base_ptr = convert_pointer_to_real (binfo, addr); expand_virtual_init (real_binfo, base_ptr); } } /* 348 - 351 */ /* Subroutine of emit_base_init. */ static void perform_member_init (member, name, init, explicit) tree member, name, init; int explicit; { tree decl; tree type = TREE_TYPE (member); expand_start_target_temps (); if (TYPE_NEEDS_CONSTRUCTING (type) || (init && TYPE_HAS_CONSTRUCTOR (type))) { /* Since `init' is already a TREE_LIST on the current_member_init_list, only build it into one if we aren't already a list. */ if (init != NULL_TREE && TREE_CODE (init) != TREE_LIST) init = build_expr_list (NULL_TREE, init); decl = build_component_ref (current_class_ref, name, NULL_TREE, explicit); if (explicit && TREE_CODE (type) == ARRAY_TYPE && init != NULL_TREE && TREE_CHAIN (init) == NULL_TREE && TREE_CODE (TREE_TYPE (TREE_VALUE (init))) == ARRAY_TYPE) { /* Initialization of one array from another. */ expand_vec_init (TREE_OPERAND (decl, 1), decl, array_type_nelts (type), TREE_VALUE (init), 1); } else expand_aggr_init (decl, init, 0); } else { if (init == NULL_TREE) { if (explicit) { /* default-initialization. */ if (AGGREGATE_TYPE_P (type)) init = build (CONSTRUCTOR, type, NULL_TREE, NULL_TREE); else if (TREE_CODE (type) == REFERENCE_TYPE) { cp_error ("default-initialization of `%#D', which has reference type", member); init = error_mark_node; } else init = integer_zero_node; } /* member traversal: note it leaves init NULL */ else if (TREE_CODE (TREE_TYPE (member)) == REFERENCE_TYPE) cp_pedwarn ("uninitialized reference member `%D'", member); } else if (TREE_CODE (init) == TREE_LIST) { /* There was an explicit member initialization. Do some work in that case. */ if (TREE_CHAIN (init)) { warning ("initializer list treated as compound expression"); init = build_compound_expr (init); } else init = TREE_VALUE (init); } /* We only build this with a null init if we got it from the current_member_init_list. */ if (init || explicit) { decl = build_component_ref (current_class_ref, name, NULL_TREE, explicit); expand_expr_stmt (build_modify_expr (decl, INIT_EXPR, init)); } } expand_end_target_temps (); free_temp_slots (); if (TYPE_NEEDS_DESTRUCTOR (type)) { tree expr; /* All cleanups must be on the function_obstack. */ push_obstacks_nochange (); resume_temporary_allocation (); expr = build_component_ref (current_class_ref, name, NULL_TREE, explicit); expr = build_delete (type, expr, integer_zero_node, LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR, 0); if (expr != error_mark_node) add_partial_entry (expr); pop_obstacks (); } } extern int warn_reorder; /* Subroutine of emit_member_init. */ static tree sort_member_init (t) tree t; { tree x, member, name, field; tree init_list = NULL_TREE; int last_pos = 0; tree last_field = NULL_TREE; for (member = TYPE_FIELDS (t); member ; member = TREE_CHAIN (member)) { int pos; /* member could be, for example, a CONST_DECL for an enumerated tag; we don't want to try to initialize that, since it already has a value. */ if (TREE_CODE (member) != FIELD_DECL || !DECL_NAME (member)) continue; for (x = current_member_init_list, pos = 0; x; x = TREE_CHAIN (x), ++pos) { /* If we cleared this out, then pay no attention to it. */ if (TREE_PURPOSE (x) == NULL_TREE) continue; name = TREE_PURPOSE (x); #if 0 /* This happens in templates, since the IDENTIFIER is replaced with the COMPONENT_REF in tsubst_expr. */ field = (TREE_CODE (name) == COMPONENT_REF ? TREE_OPERAND (name, 1) : IDENTIFIER_CLASS_VALUE (name)); #else /* Let's find out when this happens. */ my_friendly_assert (TREE_CODE (name) != COMPONENT_REF, 348); field = IDENTIFIER_CLASS_VALUE (name); #endif /* If one member shadows another, get the outermost one. */ if (TREE_CODE (field) == TREE_LIST) field = TREE_VALUE (field); if (field == member) { if (warn_reorder) { if (pos < last_pos) { cp_warning_at ("member initializers for `%#D'", last_field); cp_warning_at (" and `%#D'", field); warning (" will be re-ordered to match declaration order"); } last_pos = pos; last_field = field; } /* Make sure we won't try to work on this init again. */ TREE_PURPOSE (x) = NULL_TREE; x = build_tree_list (name, TREE_VALUE (x)); goto got_it; } } /* If we didn't find MEMBER in the list, create a dummy entry so the two lists (INIT_LIST and the list of members) will be symmetrical. */ x = build_tree_list (NULL_TREE, NULL_TREE); got_it: init_list = chainon (init_list, x); } /* Initializers for base members go at the end. */ for (x = current_member_init_list ; x ; x = TREE_CHAIN (x)) { name = TREE_PURPOSE (x); if (name) { if (purpose_member (name, init_list)) { cp_error ("multiple initializations given for member `%D'", IDENTIFIER_CLASS_VALUE (name)); continue; } init_list = chainon (init_list, build_tree_list (name, TREE_VALUE (x))); TREE_PURPOSE (x) = NULL_TREE; } } return init_list; } static void sort_base_init (t, rbase_ptr, vbase_ptr) tree t, *rbase_ptr, *vbase_ptr; { tree binfos = BINFO_BASETYPES (TYPE_BINFO (t)); int n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0; int i; tree x; tree last; /* For warn_reorder. */ int last_pos = 0; tree last_base = NULL_TREE; tree rbases = NULL_TREE; tree vbases = NULL_TREE; /* First walk through and splice out vbase and invalid initializers. Also replace names with binfos. */ last = tree_cons (NULL_TREE, NULL_TREE, current_base_init_list); for (x = TREE_CHAIN (last); x; x = TREE_CHAIN (x)) { tree basetype = TREE_PURPOSE (x); tree binfo = NULL_TREE; if (basetype == NULL_TREE) { /* Initializer for single base class. Must not use multiple inheritance or this is ambiguous. */ switch (n_baseclasses) { case 0: cp_error ("`%T' does not have a base class to initialize", current_class_type); return; case 1: break; default: cp_error ("unnamed initializer ambiguous for `%T' which uses multiple inheritance", current_class_type); return; } binfo = TREE_VEC_ELT (binfos, 0); } else if (is_aggr_type (basetype, 1)) { binfo = binfo_or_else (basetype, t); if (binfo == NULL_TREE) continue; /* Virtual base classes are special cases. Their initializers are recorded with this constructor, and they are used when this constructor is the top-level constructor called. */ if (TREE_VIA_VIRTUAL (binfo)) { tree v = CLASSTYPE_VBASECLASSES (t); while (BINFO_TYPE (v) != BINFO_TYPE (binfo)) v = TREE_CHAIN (v); vbases = tree_cons (v, TREE_VALUE (x), vbases); continue; } else { /* Otherwise, if it is not an immediate base class, complain. */ for (i = n_baseclasses-1; i >= 0; i--) if (BINFO_TYPE (binfo) == BINFO_TYPE (TREE_VEC_ELT (binfos, i))) break; if (i < 0) { cp_error ("`%T' is not an immediate base class of `%T'", basetype, current_class_type); continue; } } } else my_friendly_abort (365); TREE_PURPOSE (x) = binfo; TREE_CHAIN (last) = x; last = x; } TREE_CHAIN (last) = NULL_TREE; /* Now walk through our regular bases and make sure they're initialized. */ for (i = 0; i < n_baseclasses; ++i) { tree base_binfo = TREE_VEC_ELT (binfos, i); int pos; if (TREE_VIA_VIRTUAL (base_binfo)) continue; for (x = current_base_init_list, pos = 0; x; x = TREE_CHAIN (x), ++pos) { tree binfo = TREE_PURPOSE (x); if (binfo == NULL_TREE) continue; if (binfo == base_binfo) { if (warn_reorder) { if (pos < last_pos) { cp_warning_at ("base initializers for `%#T'", last_base); cp_warning_at (" and `%#T'", BINFO_TYPE (binfo)); warning (" will be re-ordered to match inheritance order"); } last_pos = pos; last_base = BINFO_TYPE (binfo); } /* Make sure we won't try to work on this init again. */ TREE_PURPOSE (x) = NULL_TREE; x = build_tree_list (binfo, TREE_VALUE (x)); goto got_it; } } /* If we didn't find BASE_BINFO in the list, create a dummy entry so the two lists (RBASES and the list of bases) will be symmetrical. */ x = build_tree_list (NULL_TREE, NULL_TREE); got_it: rbases = chainon (rbases, x); } *rbase_ptr = rbases; *vbase_ptr = vbases; } +/* Invoke a base-class destructor. REF is the object being destroyed, + BINFO is the base class, and DTOR_ARG indicates whether the base + class should invoke delete. */ + +tree +build_base_dtor_call (ref, binfo, dtor_arg) + tree ref, binfo, dtor_arg; +{ + tree args = NULL_TREE; + tree vlist = lookup_name (vlist_identifier, 0); + tree call, decr; + + if (TYPE_USES_PVBASES (BINFO_TYPE (binfo))) + { + args = expr_tree_cons (NULL_TREE, vlist, args); + dtor_arg = build (BIT_IOR_EXPR, integer_type_node, + dtor_arg, build_int_2 (4, 0)); + dtor_arg = fold (dtor_arg); + } + args = expr_tree_cons (NULL_TREE, dtor_arg, args); + call = build_scoped_method_call (ref, binfo, dtor_identifier, args); + + if (!TYPE_USES_PVBASES (BINFO_TYPE (binfo))) + /* For plain inheritance, do not try to adjust __vlist. */ + return call; + + /* Now decrement __vlist by the number of slots consumed by the base + dtor. */ + decr = build_int_2 (pvbasecount (BINFO_TYPE (binfo), 0), 0); + decr = build_binary_op (MINUS_EXPR, vlist, decr); + decr = build_modify_expr (vlist, NOP_EXPR, decr); + + return build (COMPOUND_EXPR, void_type_node, call, decr); +} + +/* Return the number of vlist entries needed to initialize TYPE, + depending on whether it is IN_CHARGE. */ + +static int +pvbasecount (type, in_charge) + tree type; + int in_charge; +{ + int i; + int result = 0; + tree vbase; + + for (vbase = (CLASSTYPE_VBASECLASSES (type)); vbase; + vbase = TREE_CHAIN (vbase)) + { + result += list_length (CLASSTYPE_VFIELDS (BINFO_TYPE (vbase))); + if (in_charge) + result += pvbasecount (BINFO_TYPE (vbase), 0); + } + + for (i=0; i < CLASSTYPE_N_BASECLASSES (type); i++) + { + tree base = TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type), i); + if (TREE_VIA_VIRTUAL (base)) + continue; + result += pvbasecount (BINFO_TYPE (base), 0); + } + return result; +} + +void +init_vlist (t) + tree t; +{ + char *name; + tree expr; + tree vlist = lookup_name (vlist_identifier, 0); + + name = alloca (strlen (VLIST_NAME_FORMAT) + + TYPE_ASSEMBLER_NAME_LENGTH (t) + 2); + sprintf (name, VLIST_NAME_FORMAT, TYPE_ASSEMBLER_NAME_STRING (t)); + + expr = get_identifier (name); + expr = lookup_name (expr, 0); + expr = build1 (ADDR_EXPR, TREE_TYPE (vlist), expr); + if (DECL_DESTRUCTOR_FOR_PVBASE_P (current_function_decl)) + /* Move to the end of the vlist. */ + expr = build_binary_op (PLUS_EXPR, expr, + build_int_2 (pvbasecount (t, 1), 0)); + expand_expr_stmt (build_modify_expr (vlist, NOP_EXPR, expr)); +} + /* Perform whatever initializations have yet to be done on the base class of the class variable. These actions are in the global variable CURRENT_BASE_INIT_LIST. Such an action could be NULL_TREE, meaning that the user has explicitly called the base class constructor with no arguments. If there is a need for a call to a constructor, we must surround that call with a pushlevel/poplevel pair, since we are technically at the PARM level of scope. Argument IMMEDIATELY, if zero, forces a new sequence to be generated to contain these new insns, so it can be emitted later. This sequence is saved in the global variable BASE_INIT_EXPR. Otherwise, the insns are emitted into the current sequence. Note that emit_base_init does *not* initialize virtual base classes. That is done specially, elsewhere. */ extern tree base_init_expr, rtl_expr_chain; void emit_base_init (t, immediately) tree t; int immediately; { tree member; tree mem_init_list; tree rbase_init_list, vbase_init_list; tree t_binfo = TYPE_BINFO (t); tree binfos = BINFO_BASETYPES (t_binfo); int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0; tree expr = NULL_TREE; + tree vlist = lookup_name (vlist_identifier, 0); if (! immediately) { int momentary; do_pending_stack_adjust (); /* Make the RTL_EXPR node temporary, not momentary, so that rtl_expr_chain doesn't become garbage. */ momentary = suspend_momentary (); expr = make_node (RTL_EXPR); resume_momentary (momentary); start_sequence_for_rtl_expr (expr); } if (write_symbols == NO_DEBUG) /* As a matter of principle, `start_sequence' should do this. */ emit_note (0, -1); else /* Always emit a line number note so we can step into constructors. */ emit_line_note_force (DECL_SOURCE_FILE (current_function_decl), DECL_SOURCE_LINE (current_function_decl)); mem_init_list = sort_member_init (t); current_member_init_list = NULL_TREE; sort_base_init (t, &rbase_init_list, &vbase_init_list); current_base_init_list = NULL_TREE; /* First, initialize the virtual base classes, if we are constructing the most-derived object. */ if (TYPE_USES_VIRTUAL_BASECLASSES (t)) { tree first_arg = TREE_CHAIN (DECL_ARGUMENTS (current_function_decl)); construct_virtual_bases (t, current_class_ref, current_class_ptr, vbase_init_list, first_arg); } /* Now, perform initialization of non-virtual base classes. */ for (i = 0; i < n_baseclasses; i++) { tree base_binfo = TREE_VEC_ELT (binfos, i); tree init = void_list_node; if (TREE_VIA_VIRTUAL (base_binfo)) continue; my_friendly_assert (BINFO_INHERITANCE_CHAIN (base_binfo) == t_binfo, 999); if (TREE_PURPOSE (rbase_init_list)) init = TREE_VALUE (rbase_init_list); else if (TYPE_NEEDS_CONSTRUCTING (BINFO_TYPE (base_binfo))) { init = NULL_TREE; if (extra_warnings && copy_args_p (current_function_decl)) cp_warning ("base class `%#T' should be explicitly initialized in the copy constructor", BINFO_TYPE (base_binfo)); } if (init != void_list_node) { expand_start_target_temps (); member = convert_pointer_to_real (base_binfo, current_class_ptr); expand_aggr_init_1 (base_binfo, NULL_TREE, build_indirect_ref (member, NULL_PTR), init, LOOKUP_NORMAL); expand_end_target_temps (); free_temp_slots (); } - expand_cleanup_for_base (base_binfo, NULL_TREE); + expand_cleanup_for_base (base_binfo, vlist, NULL_TREE); rbase_init_list = TREE_CHAIN (rbase_init_list); } /* Initialize all the virtual function table fields that do come from virtual base classes. */ if (TYPE_USES_VIRTUAL_BASECLASSES (t)) expand_indirect_vtbls_init (t_binfo, current_class_ref, current_class_ptr); /* Initialize all the virtual function table fields that do not come from virtual base classes. */ expand_direct_vtbls_init (t_binfo, t_binfo, 1, 1, current_class_ptr); for (member = TYPE_FIELDS (t); member; member = TREE_CHAIN (member)) { tree init, name; int from_init_list; /* member could be, for example, a CONST_DECL for an enumerated tag; we don't want to try to initialize that, since it already has a value. */ if (TREE_CODE (member) != FIELD_DECL || !DECL_NAME (member)) continue; /* See if we had a user-specified member initialization. */ if (TREE_PURPOSE (mem_init_list)) { name = TREE_PURPOSE (mem_init_list); init = TREE_VALUE (mem_init_list); from_init_list = 1; #if 0 if (TREE_CODE (name) == COMPONENT_REF) name = DECL_NAME (TREE_OPERAND (name, 1)); #else /* Also see if it's ever a COMPONENT_REF here. If it is, we need to do `expand_assignment (name, init, 0, 0);' and a continue. */ my_friendly_assert (TREE_CODE (name) != COMPONENT_REF, 349); #endif } else { name = DECL_NAME (member); init = DECL_INITIAL (member); from_init_list = 0; /* Effective C++ rule 12. */ if (warn_ecpp && init == NULL_TREE && !DECL_ARTIFICIAL (member) && TREE_CODE (TREE_TYPE (member)) != ARRAY_TYPE) cp_warning ("`%D' should be initialized in the member initialization list", member); } perform_member_init (member, name, init, from_init_list); mem_init_list = TREE_CHAIN (mem_init_list); } /* Now initialize any members from our bases. */ while (mem_init_list) { tree name, init, field; if (TREE_PURPOSE (mem_init_list)) { name = TREE_PURPOSE (mem_init_list); init = TREE_VALUE (mem_init_list); /* XXX: this may need the COMPONENT_REF operand 0 check if it turns out we actually get them. */ field = IDENTIFIER_CLASS_VALUE (name); /* If one member shadows another, get the outermost one. */ if (TREE_CODE (field) == TREE_LIST) { field = TREE_VALUE (field); if (decl_type_context (field) != current_class_type) cp_error ("field `%D' not in immediate context", field); } #if 0 /* It turns out if you have an anonymous union in the class, a member from it can end up not being on the list of fields (rather, the type is), and therefore won't be seen by the for loop above. */ /* The code in this for loop is derived from a general loop which had this check in it. Theoretically, we've hit every initialization for the list of members in T, so we shouldn't have anything but these left in this list. */ my_friendly_assert (DECL_FIELD_CONTEXT (field) != t, 351); #endif perform_member_init (field, name, init, 1); } mem_init_list = TREE_CHAIN (mem_init_list); } if (! immediately) { do_pending_stack_adjust (); my_friendly_assert (base_init_expr == 0, 207); base_init_expr = expr; TREE_TYPE (expr) = void_type_node; RTL_EXPR_RTL (expr) = const0_rtx; RTL_EXPR_SEQUENCE (expr) = get_insns (); rtl_expr_chain = tree_cons (NULL_TREE, expr, rtl_expr_chain); end_sequence (); TREE_SIDE_EFFECTS (expr) = 1; } /* All the implicit try blocks we built up will be zapped when we come to a real binding contour boundary. */ } /* Check that all fields are properly initialized after an assignment to `this'. */ void check_base_init (t) tree t; { tree member; for (member = TYPE_FIELDS (t); member; member = TREE_CHAIN (member)) if (DECL_NAME (member) && TREE_USED (member)) cp_error ("field `%D' used before initialized (after assignment to `this')", member); } /* This code sets up the virtual function tables appropriate for the pointer DECL. It is a one-ply initialization. BINFO is the exact type that DECL is supposed to be. In multiple inheritance, this might mean "C's A" if C : A, B. */ static void expand_virtual_init (binfo, decl) tree binfo, decl; { tree type = BINFO_TYPE (binfo); tree vtbl, vtbl_ptr; tree vtype, vtype_binfo; /* This code is crusty. Should be simple, like: vtbl = BINFO_VTABLE (binfo); */ vtype = DECL_CONTEXT (CLASSTYPE_VFIELD (type)); vtype_binfo = get_binfo (vtype, TREE_TYPE (TREE_TYPE (decl)), 0); vtbl = BINFO_VTABLE (binfo_value (DECL_FIELD_CONTEXT (CLASSTYPE_VFIELD (type)), binfo)); assemble_external (vtbl); TREE_USED (vtbl) = 1; vtbl = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (vtbl)), vtbl); decl = convert_pointer_to_real (vtype_binfo, decl); vtbl_ptr = build_vfield_ref (build_indirect_ref (decl, NULL_PTR), vtype); if (vtbl_ptr == error_mark_node) return; /* Have to convert VTBL since array sizes may be different. */ vtbl = convert_force (TREE_TYPE (vtbl_ptr), vtbl, 0); expand_expr_stmt (build_modify_expr (vtbl_ptr, NOP_EXPR, vtbl)); } /* If an exception is thrown in a constructor, those base classes already constructed must be destroyed. This function creates the cleanup for BINFO, which has just been constructed. If FLAG is non-NULL, it is a DECL which is non-zero when this base needs to be destroyed. */ static void -expand_cleanup_for_base (binfo, flag) +expand_cleanup_for_base (binfo, vlist, flag) tree binfo; + tree vlist; tree flag; { tree expr; - if (!TYPE_NEEDS_DESTRUCTOR (BINFO_TYPE (binfo))) - return; + if (TYPE_NEEDS_DESTRUCTOR (BINFO_TYPE (binfo))) + { + /* All cleanups must be on the function_obstack. */ + push_obstacks_nochange (); + resume_temporary_allocation (); - /* All cleanups must be on the function_obstack. */ - push_obstacks_nochange (); - resume_temporary_allocation (); + /* Call the destructor. */ + expr = build_base_dtor_call (current_class_ref, binfo, + integer_zero_node); + if (flag) + expr = fold (build (COND_EXPR, void_type_node, + truthvalue_conversion (flag), + expr, integer_zero_node)); - /* Call the destructor. */ - expr = (build_scoped_method_call - (current_class_ref, binfo, dtor_identifier, - build_expr_list (NULL_TREE, integer_zero_node))); - if (flag) - expr = fold (build (COND_EXPR, void_type_node, - truthvalue_conversion (flag), - expr, integer_zero_node)); + pop_obstacks (); + add_partial_entry (expr); + } - pop_obstacks (); - add_partial_entry (expr); + if (TYPE_USES_PVBASES (BINFO_TYPE (binfo))) + { + /* Increment vlist by number of base's vbase classes. */ + expr = build_int_2 (pvbasecount (BINFO_TYPE (binfo), 0), 0); + expr = build_binary_op (PLUS_EXPR, vlist, expr); + expr = build_modify_expr (vlist, NOP_EXPR, expr); + expand_expr_stmt (expr); + } } /* Subroutine of `expand_aggr_vbase_init'. BINFO is the binfo of the type that is being initialized. INIT_LIST is the list of initializers for the virtual baseclass. */ static void expand_aggr_vbase_init_1 (binfo, exp, addr, init_list) tree binfo, exp, addr, init_list; { tree init = purpose_member (binfo, init_list); tree ref = build_indirect_ref (addr, NULL_PTR); expand_start_target_temps (); if (init) init = TREE_VALUE (init); /* Call constructors, but don't set up vtables. */ expand_aggr_init_1 (binfo, exp, ref, init, LOOKUP_COMPLAIN); expand_end_target_temps (); free_temp_slots (); } /* Construct the virtual base-classes of THIS_REF (whose address is THIS_PTR). The object has the indicated TYPE. The construction actually takes place only if FLAG is non-zero. INIT_LIST is list of initialization for constructor to perform. */ static void construct_virtual_bases (type, this_ref, this_ptr, init_list, flag) tree type; tree this_ref; tree this_ptr; tree init_list; tree flag; { tree vbases; tree result; + tree vlist = NULL_TREE; /* If there are no virtual baseclasses, we shouldn't even be here. */ my_friendly_assert (TYPE_USES_VIRTUAL_BASECLASSES (type), 19990621); /* First set the pointers in our object that tell us where to find our virtual baseclasses. */ expand_start_cond (flag, 0); + if (TYPE_USES_PVBASES (type)) + { + init_vlist (type); + vlist = lookup_name (vlist_identifier, 0); + } result = init_vbase_pointers (type, this_ptr); if (result) expand_expr_stmt (build_compound_expr (result)); expand_end_cond (); /* Now, run through the baseclasses, initializing each. */ for (vbases = CLASSTYPE_VBASECLASSES (type); vbases; vbases = TREE_CHAIN (vbases)) { tree tmp = purpose_member (vbases, result); /* If there are virtual base classes with destructors, we need to emit cleanups to destroy them if an exception is thrown during the construction process. These exception regions (i.e., the period during which the cleanups must occur) begin from the time the construction is complete to the end of the function. If we create a conditional block in which to initialize the base-classes, then the cleanup region for the virtual base begins inside a block, and ends outside of that block. This situation confuses the sjlj exception-handling code. Therefore, we do not create a single conditional block, but one for each initialization. (That way the cleanup regions always begin in the outer block.) We trust the back-end to figure out that the FLAG will not change across initializations, and avoid doing multiple tests. */ expand_start_cond (flag, 0); expand_aggr_vbase_init_1 (vbases, this_ref, TREE_OPERAND (TREE_VALUE (tmp), 0), init_list); expand_end_cond (); - expand_cleanup_for_base (vbases, flag); + expand_cleanup_for_base (vbases, vlist, flag); } } /* Find the context in which this FIELD can be initialized. */ static tree initializing_context (field) tree field; { tree t = DECL_CONTEXT (field); /* Anonymous union members can be initialized in the first enclosing non-anonymous union context. */ while (t && ANON_UNION_TYPE_P (t)) t = TYPE_CONTEXT (t); return t; } /* Function to give error message if member initialization specification is erroneous. FIELD is the member we decided to initialize. TYPE is the type for which the initialization is being performed. FIELD must be a member of TYPE. MEMBER_NAME is the name of the member. */ static int member_init_ok_or_else (field, type, member_name) tree field; tree type; const char *member_name; { if (field == error_mark_node) return 0; if (field == NULL_TREE || initializing_context (field) != type) { cp_error ("class `%T' does not have any field named `%s'", type, member_name); return 0; } if (TREE_STATIC (field)) { cp_error ("field `%#D' is static; only point of initialization is its declaration", field); return 0; } return 1; } /* If NAME is a viable field name for the aggregate DECL, and PARMS is a viable parameter list, then expand an _EXPR which describes this initialization. Note that we do not need to chase through the class's base classes to look for NAME, because if it's in that list, it will be handled by the constructor for that base class. We do not yet have a fixed-point finder to instantiate types being fed to overloaded constructors. If there is a unique constructor, then argument types can be got from that one. If INIT is non-NULL, then it the initialization should be placed in `current_base_init_list', where it will be processed by `emit_base_init'. */ void expand_member_init (exp, name, init) tree exp, name, init; { tree basetype = NULL_TREE, field; tree type; if (exp == NULL_TREE) return; /* complain about this later */ type = TYPE_MAIN_VARIANT (TREE_TYPE (exp)); if (name && TREE_CODE (name) == TYPE_DECL) { basetype = TYPE_MAIN_VARIANT (TREE_TYPE (name)); name = DECL_NAME (name); } if (name == NULL_TREE && IS_AGGR_TYPE (type)) switch (CLASSTYPE_N_BASECLASSES (type)) { case 0: error ("base class initializer specified, but no base class to initialize"); return; case 1: basetype = TYPE_BINFO_BASETYPE (type, 0); break; default: error ("initializer for unnamed base class ambiguous"); cp_error ("(type `%T' uses multiple inheritance)", type); return; } my_friendly_assert (init != NULL_TREE, 0); /* The grammar should not allow fields which have names that are TYPENAMEs. Therefore, if the field has a non-NULL TREE_TYPE, we may assume that this is an attempt to initialize a base class member of the current type. Otherwise, it is an attempt to initialize a member field. */ if (init == void_type_node) init = NULL_TREE; if (name == NULL_TREE || basetype) { tree base_init; if (name == NULL_TREE) { #if 0 if (basetype) name = TYPE_IDENTIFIER (basetype); else { error ("no base class to initialize"); return; } #endif } else if (basetype != type && ! current_template_parms && ! vec_binfo_member (basetype, TYPE_BINFO_BASETYPES (type)) && ! binfo_member (basetype, CLASSTYPE_VBASECLASSES (type))) { if (IDENTIFIER_CLASS_VALUE (name)) goto try_member; if (TYPE_USES_VIRTUAL_BASECLASSES (type)) cp_error ("type `%T' is not an immediate or virtual basetype for `%T'", basetype, type); else cp_error ("type `%T' is not an immediate basetype for `%T'", basetype, type); return; } if (purpose_member (basetype, current_base_init_list)) { cp_error ("base class `%T' already initialized", basetype); return; } if (warn_reorder && current_member_init_list) { cp_warning ("base initializer for `%T'", basetype); warning (" will be re-ordered to precede member initializations"); } base_init = build_tree_list (basetype, init); current_base_init_list = chainon (current_base_init_list, base_init); } else { tree member_init; try_member: field = lookup_field (type, name, 1, 0); if (! member_init_ok_or_else (field, type, IDENTIFIER_POINTER (name))) return; if (purpose_member (name, current_member_init_list)) { cp_error ("field `%D' already initialized", field); return; } member_init = build_tree_list (name, init); current_member_init_list = chainon (current_member_init_list, member_init); } } /* This is like `expand_member_init', only it stores one aggregate value into another. INIT comes in two flavors: it is either a value which is to be stored in EXP, or it is a parameter list to go to a constructor, which will operate on EXP. If INIT is not a parameter list for a constructor, then set LOOKUP_ONLYCONVERTING. If FLAGS is LOOKUP_ONLYCONVERTING then it is the = init form of the initializer, if FLAGS is 0, then it is the (init) form. If `init' is a CONSTRUCTOR, then we emit a warning message, explaining that such initializations are invalid. ALIAS_THIS is nonzero iff we are initializing something which is essentially an alias for current_class_ref. In this case, the base constructor may move it on us, and we must keep track of such deviations. If INIT resolves to a CALL_EXPR which happens to return something of the type we are looking for, then we know that we can safely use that call to perform the initialization. The virtual function table pointer cannot be set up here, because we do not really know its type. Virtual baseclass pointers are also set up here. This never calls operator=(). When initializing, nothing is CONST. A default copy constructor may have to be used to perform the initialization. A constructor or a conversion operator may have to be used to perform the initialization, but not both, as it would be ambiguous. */ void expand_aggr_init (exp, init, flags) tree exp, init; int flags; { tree type = TREE_TYPE (exp); int was_const = TREE_READONLY (exp); int was_volatile = TREE_THIS_VOLATILE (exp); if (init == error_mark_node) return; TREE_READONLY (exp) = 0; TREE_THIS_VOLATILE (exp) = 0; if (init && TREE_CODE (init) != TREE_LIST) flags |= LOOKUP_ONLYCONVERTING; if (TREE_CODE (type) == ARRAY_TYPE) { /* Must arrange to initialize each element of EXP from elements of INIT. */ tree itype = init ? TREE_TYPE (init) : NULL_TREE; if (CP_TYPE_QUALS (type) != TYPE_UNQUALIFIED) { TREE_TYPE (exp) = TYPE_MAIN_VARIANT (type); if (init) TREE_TYPE (init) = TYPE_MAIN_VARIANT (itype); } if (init && TREE_TYPE (init) == NULL_TREE) { /* Handle bad initializers like: class COMPLEX { public: double re, im; COMPLEX(double r = 0.0, double i = 0.0) {re = r; im = i;}; ~COMPLEX() {}; }; int main(int argc, char **argv) { COMPLEX zees(1.0, 0.0)[10]; } */ error ("bad array initializer"); return; } expand_vec_init (exp, exp, array_type_nelts (type), init, init && same_type_p (TREE_TYPE (init), TREE_TYPE (exp))); TREE_READONLY (exp) = was_const; TREE_THIS_VOLATILE (exp) = was_volatile; TREE_TYPE (exp) = type; if (init) TREE_TYPE (init) = itype; return; } if (TREE_CODE (exp) == VAR_DECL || TREE_CODE (exp) == PARM_DECL) /* just know that we've seen something for this node */ TREE_USED (exp) = 1; #if 0 /* If initializing from a GNU C CONSTRUCTOR, consider the elts in the constructor as parameters to an implicit GNU C++ constructor. */ if (init && TREE_CODE (init) == CONSTRUCTOR && TYPE_HAS_CONSTRUCTOR (type) && TREE_TYPE (init) == type) init = CONSTRUCTOR_ELTS (init); #endif TREE_TYPE (exp) = TYPE_MAIN_VARIANT (type); expand_aggr_init_1 (TYPE_BINFO (type), exp, exp, init, LOOKUP_NORMAL|flags); TREE_TYPE (exp) = type; TREE_READONLY (exp) = was_const; TREE_THIS_VOLATILE (exp) = was_volatile; } +static tree +no_vlist_base_init (rval, exp, init, binfo, flags) + tree rval, exp, init, binfo; + int flags; +{ + tree nrval, func, parms; + + /* Obtain the vlist-expecting ctor. */ + func = rval; + my_friendly_assert (TREE_CODE (func) == CALL_EXPR, 20000131); + func = TREE_OPERAND (func, 0); + my_friendly_assert (TREE_CODE (func) == ADDR_EXPR, 20000132); + + if (init == NULL_TREE + || (TREE_CODE (init) == TREE_LIST && ! TREE_TYPE (init))) + { + parms = init; + if (parms) + init = TREE_VALUE (parms); + } + else + parms = build_expr_list (NULL_TREE, init); + + flags &= ~LOOKUP_HAS_VLIST; + + parms = expr_tree_cons (NULL_TREE, integer_zero_node, parms); + flags |= LOOKUP_HAS_IN_CHARGE; + + nrval = build_method_call (exp, ctor_identifier, + parms, binfo, flags); + + func = build (NE_EXPR, boolean_type_node, + func, null_pointer_node); + nrval = build (COND_EXPR, void_type_node, + func, rval, nrval); + return nrval; +} + static void expand_default_init (binfo, true_exp, exp, init, flags) tree binfo; tree true_exp, exp; tree init; int flags; { tree type = TREE_TYPE (exp); /* It fails because there may not be a constructor which takes its own type as the first (or only parameter), but which does take other types via a conversion. So, if the thing initializing the expression is a unit element of type X, first try X(X&), followed by initialization by X. If neither of these work out, then look hard. */ tree rval; tree parms; + tree vlist = NULL_TREE; + tree orig_init = init; if (init && TREE_CODE (init) != TREE_LIST && (flags & LOOKUP_ONLYCONVERTING)) { /* Base subobjects should only get direct-initialization. */ if (true_exp != exp) abort (); if (flags & DIRECT_BIND) /* Do nothing. We hit this in two cases: Reference initialization, where we aren't initializing a real variable, so we don't want to run a new constructor; and catching an exception, where we have already built up the constructor call so we could wrap it in an exception region. */; else init = ocp_convert (type, init, CONV_IMPLICIT|CONV_FORCE_TEMP, flags); if (TREE_CODE (init) == TRY_CATCH_EXPR) /* We need to protect the initialization of a catch parm with a call to terminate(), which shows up as a TRY_CATCH_EXPR around the TARGET_EXPR for the copy constructor. See expand_start_catch_block. */ TREE_OPERAND (init, 0) = build (INIT_EXPR, TREE_TYPE (exp), exp, TREE_OPERAND (init, 0)); else init = build (INIT_EXPR, TREE_TYPE (exp), exp, init); TREE_SIDE_EFFECTS (init) = 1; expand_expr_stmt (init); return; } if (init == NULL_TREE || (TREE_CODE (init) == TREE_LIST && ! TREE_TYPE (init))) { parms = init; if (parms) init = TREE_VALUE (parms); } else parms = build_expr_list (NULL_TREE, init); if (TYPE_USES_VIRTUAL_BASECLASSES (type)) { + if (TYPE_USES_PVBASES (type)) + { + /* In compatibility mode, when not calling a base ctor, + we do not pass the vlist argument. */ + if (true_exp == exp) + vlist = flag_vtable_thunks_compat? NULL_TREE : vlist_zero_node; + else + vlist = lookup_name (vlist_identifier, 0); + + if (vlist) + { + parms = expr_tree_cons (NULL_TREE, vlist, parms); + flags |= LOOKUP_HAS_VLIST; + } + } if (true_exp == exp) parms = expr_tree_cons (NULL_TREE, integer_one_node, parms); else parms = expr_tree_cons (NULL_TREE, integer_zero_node, parms); flags |= LOOKUP_HAS_IN_CHARGE; } rval = build_method_call (exp, ctor_identifier, parms, binfo, flags); + if (vlist && true_exp != exp && flag_vtable_thunks_compat) + { + rval = no_vlist_base_init (rval, exp, orig_init, binfo, flags); + } if (TREE_SIDE_EFFECTS (rval)) expand_expr_stmt (rval); } /* This function is responsible for initializing EXP with INIT (if any). BINFO is the binfo of the type for who we are performing the initialization. For example, if W is a virtual base class of A and B, and C : A, B. If we are initializing B, then W must contain B's W vtable, whereas were we initializing C, W must contain C's W vtable. TRUE_EXP is nonzero if it is the true expression being initialized. In this case, it may be EXP, or may just contain EXP. The reason we need this is because if EXP is a base element of TRUE_EXP, we don't necessarily know by looking at EXP where its virtual baseclass fields should really be pointing. But we do know from TRUE_EXP. In constructors, we don't know anything about the value being initialized. ALIAS_THIS serves the same purpose it serves for expand_aggr_init. FLAGS is just passes to `build_method_call'. See that function for its description. */ static void expand_aggr_init_1 (binfo, true_exp, exp, init, flags) tree binfo; tree true_exp, exp; tree init; int flags; { tree type = TREE_TYPE (exp); my_friendly_assert (init != error_mark_node && type != error_mark_node, 211); /* Use a function returning the desired type to initialize EXP for us. If the function is a constructor, and its first argument is NULL_TREE, know that it was meant for us--just slide exp on in and expand the constructor. Constructors now come as TARGET_EXPRs. */ if (init && TREE_CODE (exp) == VAR_DECL && TREE_CODE (init) == CONSTRUCTOR && TREE_HAS_CONSTRUCTOR (init)) { tree t = store_init_value (exp, init); if (!t) { expand_decl_init (exp); return; } t = build (INIT_EXPR, type, exp, init); TREE_SIDE_EFFECTS (t) = 1; expand_expr_stmt (t); return; } /* We know that expand_default_init can handle everything we want at this point. */ expand_default_init (binfo, true_exp, exp, init, flags); } /* Report an error if NAME is not the name of a user-defined, aggregate type. If OR_ELSE is nonzero, give an error message. */ int is_aggr_typedef (name, or_else) tree name; int or_else; { tree type; if (name == error_mark_node) return 0; if (IDENTIFIER_HAS_TYPE_VALUE (name)) type = IDENTIFIER_TYPE_VALUE (name); else { if (or_else) cp_error ("`%T' is not an aggregate typedef", name); return 0; } if (! IS_AGGR_TYPE (type) && TREE_CODE (type) != TEMPLATE_TYPE_PARM && TREE_CODE (type) != TEMPLATE_TEMPLATE_PARM) { if (or_else) cp_error ("`%T' is not an aggregate type", type); return 0; } return 1; } /* Report an error if TYPE is not a user-defined, aggregate type. If OR_ELSE is nonzero, give an error message. */ int is_aggr_type (type, or_else) tree type; int or_else; { if (type == error_mark_node) return 0; if (! IS_AGGR_TYPE (type) && TREE_CODE (type) != TEMPLATE_TYPE_PARM && TREE_CODE (type) != TEMPLATE_TEMPLATE_PARM) { if (or_else) cp_error ("`%T' is not an aggregate type", type); return 0; } return 1; } /* Like is_aggr_typedef, but returns typedef if successful. */ tree get_aggr_from_typedef (name, or_else) tree name; int or_else; { tree type; if (name == error_mark_node) return NULL_TREE; if (IDENTIFIER_HAS_TYPE_VALUE (name)) type = IDENTIFIER_TYPE_VALUE (name); else { if (or_else) cp_error ("`%T' fails to be an aggregate typedef", name); return NULL_TREE; } if (! IS_AGGR_TYPE (type) && TREE_CODE (type) != TEMPLATE_TYPE_PARM && TREE_CODE (type) != TEMPLATE_TEMPLATE_PARM) { if (or_else) cp_error ("type `%T' is of non-aggregate type", type); return NULL_TREE; } return type; } tree get_type_value (name) tree name; { if (name == error_mark_node) return NULL_TREE; if (IDENTIFIER_HAS_TYPE_VALUE (name)) return IDENTIFIER_TYPE_VALUE (name); else return NULL_TREE; } /* This code could just as well go in `class.c', but is placed here for modularity. */ /* For an expression of the form TYPE :: NAME (PARMLIST), build the appropriate function call. */ tree build_member_call (type, name, parmlist) tree type, name, parmlist; { tree t; tree method_name; int dtor = 0; tree basetype_path, decl; if (TREE_CODE (name) == TEMPLATE_ID_EXPR && TREE_CODE (type) == NAMESPACE_DECL) { /* 'name' already refers to the decls from the namespace, since we hit do_identifier for template_ids. */ method_name = TREE_OPERAND (name, 0); /* FIXME: Since we don't do independent names right yet, the name might also be a LOOKUP_EXPR. Once we resolve this to a real decl earlier, this can go. This may happen during tsubst'ing. */ if (TREE_CODE (method_name) == LOOKUP_EXPR) { method_name = lookup_namespace_name (type, TREE_OPERAND (method_name, 0)); TREE_OPERAND (name, 0) = method_name; } my_friendly_assert (is_overloaded_fn (method_name), 980519); return build_x_function_call (name, parmlist, current_class_ref); } if (type == std_node) return build_x_function_call (do_scoped_id (name, 0), parmlist, current_class_ref); if (TREE_CODE (type) == NAMESPACE_DECL) return build_x_function_call (lookup_namespace_name (type, name), parmlist, current_class_ref); if (TREE_CODE (name) == TEMPLATE_ID_EXPR) { method_name = TREE_OPERAND (name, 0); if (TREE_CODE (method_name) == COMPONENT_REF) method_name = TREE_OPERAND (method_name, 1); if (is_overloaded_fn (method_name)) method_name = DECL_NAME (OVL_CURRENT (method_name)); TREE_OPERAND (name, 0) = method_name; } else method_name = name; if (TREE_CODE (method_name) == BIT_NOT_EXPR) { method_name = TREE_OPERAND (method_name, 0); dtor = 1; } /* This shouldn't be here, and build_member_call shouldn't appear in parse.y! (mrs) */ if (type && TREE_CODE (type) == IDENTIFIER_NODE && get_aggr_from_typedef (type, 0) == 0) { tree ns = lookup_name (type, 0); if (ns && TREE_CODE (ns) == NAMESPACE_DECL) { return build_x_function_call (build_offset_ref (type, name), parmlist, current_class_ref); } } if (type == NULL_TREE || ! is_aggr_type (type, 1)) return error_mark_node; /* An operator we did not like. */ if (name == NULL_TREE) return error_mark_node; if (dtor) { cp_error ("cannot call destructor `%T::~%T' without object", type, method_name); return error_mark_node; } decl = maybe_dummy_object (type, &basetype_path); /* Convert 'this' to the specified type to disambiguate conversion to the function's context. Apparently Standard C++ says that we shouldn't do this. */ if (decl == current_class_ref && ! pedantic && ACCESSIBLY_UNIQUELY_DERIVED_P (type, current_class_type)) { tree olddecl = current_class_ptr; tree oldtype = TREE_TYPE (TREE_TYPE (olddecl)); if (oldtype != type) { tree newtype = build_qualified_type (type, TYPE_QUALS (oldtype)); decl = convert_force (build_pointer_type (newtype), olddecl, 0); decl = build_indirect_ref (decl, NULL_PTR); } } if (method_name == constructor_name (type) || method_name == constructor_name_full (type)) return build_functional_cast (type, parmlist); if (lookup_fnfields (basetype_path, method_name, 0)) return build_method_call (decl, TREE_CODE (name) == TEMPLATE_ID_EXPR ? name : method_name, parmlist, basetype_path, LOOKUP_NORMAL|LOOKUP_NONVIRTUAL); if (TREE_CODE (name) == IDENTIFIER_NODE && ((t = lookup_field (TYPE_BINFO (type), name, 1, 0)))) { if (t == error_mark_node) return error_mark_node; if (TREE_CODE (t) == FIELD_DECL) { if (is_dummy_object (decl)) { cp_error ("invalid use of non-static field `%D'", t); return error_mark_node; } decl = build (COMPONENT_REF, TREE_TYPE (t), decl, t); } else if (TREE_CODE (t) == VAR_DECL) decl = t; else { cp_error ("invalid use of member `%D'", t); return error_mark_node; } if (TYPE_LANG_SPECIFIC (TREE_TYPE (decl))) return build_opfncall (CALL_EXPR, LOOKUP_NORMAL, decl, parmlist, NULL_TREE); return build_function_call (decl, parmlist); } else { cp_error ("no method `%T::%D'", type, name); return error_mark_node; } } /* Build a reference to a member of an aggregate. This is not a C++ `&', but really something which can have its address taken, and then act as a pointer to member, for example TYPE :: FIELD can have its address taken by saying & TYPE :: FIELD. @@ Prints out lousy diagnostics for operator @@ fields. @@ This function should be rewritten and placed in search.c. */ tree build_offset_ref (type, name) tree type, name; { tree decl, t = error_mark_node; tree member; tree basebinfo = NULL_TREE; tree orig_name = name; /* class templates can come in as TEMPLATE_DECLs here. */ if (TREE_CODE (name) == TEMPLATE_DECL) return name; if (type == std_node) return do_scoped_id (name, 0); if (processing_template_decl || uses_template_parms (type)) return build_min_nt (SCOPE_REF, type, name); /* Handle namespace names fully here. */ if (TREE_CODE (type) == NAMESPACE_DECL) { t = lookup_namespace_name (type, name); if (t != error_mark_node && ! type_unknown_p (t)) { mark_used (t); t = convert_from_reference (t); } return t; } if (type == NULL_TREE || ! is_aggr_type (type, 1)) return error_mark_node; if (TREE_CODE (name) == TEMPLATE_ID_EXPR) { /* If the NAME is a TEMPLATE_ID_EXPR, we are looking at something like `a.template f' or the like. For the most part, we treat this just like a.f. We do remember, however, the template-id that was used. */ name = TREE_OPERAND (orig_name, 0); if (TREE_CODE (name) == LOOKUP_EXPR) /* This can happen during tsubst'ing. */ name = TREE_OPERAND (name, 0); my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 0); } if (TREE_CODE (name) == BIT_NOT_EXPR) { if (! check_dtor_name (type, name)) cp_error ("qualified type `%T' does not match destructor name `~%T'", type, TREE_OPERAND (name, 0)); name = dtor_identifier; } #if 0 /* I think this is wrong, but the draft is unclear. --jason 6/15/98 */ else if (name == constructor_name_full (type) || name == constructor_name (type)) name = ctor_identifier; #endif if (TYPE_SIZE (complete_type (type)) == 0 && !TYPE_BEING_DEFINED (type)) { cp_error ("incomplete type `%T' does not have member `%D'", type, name); return error_mark_node; } decl = maybe_dummy_object (type, &basebinfo); member = lookup_member (basebinfo, name, 1, 0); if (member == error_mark_node) return error_mark_node; /* A lot of this logic is now handled in lookup_field and lookup_fnfield. */ if (member && BASELINK_P (member)) { /* Go from the TREE_BASELINK to the member function info. */ tree fnfields = member; t = TREE_VALUE (fnfields); if (TREE_CODE (orig_name) == TEMPLATE_ID_EXPR) { /* The FNFIELDS are going to contain functions that aren't necessarily templates, and templates that don't necessarily match the explicit template parameters. We save all the functions, and the explicit parameters, and then figure out exactly what to instantiate with what arguments in instantiate_type. */ if (TREE_CODE (t) != OVERLOAD) /* The code in instantiate_type which will process this expects to encounter OVERLOADs, not raw functions. */ t = ovl_cons (t, NULL_TREE); return build (OFFSET_REF, unknown_type_node, decl, build (TEMPLATE_ID_EXPR, TREE_TYPE (t), t, TREE_OPERAND (orig_name, 1))); } if (!really_overloaded_fn (t)) { /* Get rid of a potential OVERLOAD around it */ t = OVL_CURRENT (t); /* unique functions are handled easily. */ basebinfo = TREE_PURPOSE (fnfields); if (!enforce_access (basebinfo, t)) return error_mark_node; mark_used (t); if (DECL_STATIC_FUNCTION_P (t)) return t; return build (OFFSET_REF, TREE_TYPE (t), decl, t); } /* FNFIELDS is most likely allocated on the search_obstack, which will go away after this class scope. If we need to save this value for later (i.e. for use as an initializer for a static variable), then do so here. ??? The smart thing to do for the case of saving initializers is to resolve them before we're done with this scope. */ if (!TREE_PERMANENT (fnfields) && ! allocation_temporary_p ()) fnfields = copy_list (fnfields); TREE_TYPE (fnfields) = unknown_type_node; return build (OFFSET_REF, unknown_type_node, decl, fnfields); } t = member; if (t == NULL_TREE) { cp_error ("`%D' is not a member of type `%T'", name, type); return error_mark_node; } if (TREE_CODE (t) == TYPE_DECL) { TREE_USED (t) = 1; return t; } /* static class members and class-specific enum values can be returned without further ado. */ if (TREE_CODE (t) == VAR_DECL || TREE_CODE (t) == CONST_DECL) { mark_used (t); return convert_from_reference (t); } if (TREE_CODE (t) == FIELD_DECL && DECL_C_BIT_FIELD (t)) { cp_error ("illegal pointer to bit field `%D'", t); return error_mark_node; } /* static class functions too. */ if (TREE_CODE (t) == FUNCTION_DECL && TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE) my_friendly_abort (53); /* In member functions, the form `type::name' is no longer equivalent to `this->type::name', at least not until resolve_offset_ref. */ return build (OFFSET_REF, build_offset_type (type, TREE_TYPE (t)), decl, t); } /* If a OFFSET_REF made it through to here, then it did not have its address taken. */ tree resolve_offset_ref (exp) tree exp; { tree type = TREE_TYPE (exp); tree base = NULL_TREE; tree member; tree basetype, addr; if (TREE_CODE (exp) == OFFSET_REF) { member = TREE_OPERAND (exp, 1); base = TREE_OPERAND (exp, 0); } else { my_friendly_assert (TREE_CODE (type) == OFFSET_TYPE, 214); if (TYPE_OFFSET_BASETYPE (type) != current_class_type) { error ("object missing in use of pointer-to-member construct"); return error_mark_node; } member = exp; type = TREE_TYPE (type); base = current_class_ref; } if (BASELINK_P (member)) { cp_pedwarn ("assuming & on overloaded member function"); return build_unary_op (ADDR_EXPR, exp, 0); } if (TREE_CODE (TREE_TYPE (member)) == METHOD_TYPE) { cp_pedwarn ("assuming & on `%E'", member); return build_unary_op (ADDR_EXPR, exp, 0); } if ((TREE_CODE (member) == VAR_DECL && ! TYPE_PTRMEMFUNC_P (TREE_TYPE (member)) && ! TYPE_PTRMEM_P (TREE_TYPE (member))) || TREE_CODE (TREE_TYPE (member)) == FUNCTION_TYPE) { /* These were static members. */ if (mark_addressable (member) == 0) return error_mark_node; return member; } if (TREE_CODE (TREE_TYPE (member)) == POINTER_TYPE && TREE_CODE (TREE_TYPE (TREE_TYPE (member))) == METHOD_TYPE) return member; /* Syntax error can cause a member which should have been seen as static to be grok'd as non-static. */ if (TREE_CODE (member) == FIELD_DECL && current_class_ref == NULL_TREE) { if (TREE_ADDRESSABLE (member) == 0) { cp_error_at ("member `%D' is non-static but referenced as a static member", member); error ("at this point in file"); TREE_ADDRESSABLE (member) = 1; } return error_mark_node; } /* The first case is really just a reference to a member of `this'. */ if (TREE_CODE (member) == FIELD_DECL && (base == current_class_ref || is_dummy_object (base))) { tree basetype_path; tree expr; if (TREE_CODE (exp) == OFFSET_REF && TREE_CODE (type) == OFFSET_TYPE) basetype = TYPE_OFFSET_BASETYPE (type); else basetype = DECL_CONTEXT (member); base = current_class_ptr; if (get_base_distance (basetype, TREE_TYPE (TREE_TYPE (base)), 0, &basetype_path) < 0) { error_not_base_type (basetype, TREE_TYPE (TREE_TYPE (base))); return error_mark_node; } /* Kludge: we need to use basetype_path now, because convert_pointer_to will bash it. */ enforce_access (basetype_path, member); addr = convert_pointer_to (basetype, base); /* Even in the case of illegal access, we form the COMPONENT_REF; that will allow better error recovery than just feeding back error_mark_node. */ expr = build (COMPONENT_REF, TREE_TYPE (member), build_indirect_ref (addr, NULL_PTR), member); return convert_from_reference (expr); } /* Ensure that we have an object. */ if (is_dummy_object (base)) addr = error_mark_node; else /* If this is a reference to a member function, then return the address of the member function (which may involve going through the object's vtable), otherwise, return an expression for the dereferenced pointer-to-member construct. */ addr = build_unary_op (ADDR_EXPR, base, 0); if (TYPE_PTRMEM_P (TREE_TYPE (member))) { if (addr == error_mark_node) { cp_error ("object missing in `%E'", exp); return error_mark_node; } basetype = TYPE_OFFSET_BASETYPE (TREE_TYPE (TREE_TYPE (member))); addr = convert_pointer_to (basetype, addr); member = cp_convert (ptrdiff_type_node, member); /* Pointer to data members are offset by one, so that a null pointer with a real value of 0 is distinguishable from an offset of the first member of a structure. */ member = build_binary_op (MINUS_EXPR, member, cp_convert (ptrdiff_type_node, integer_one_node)); return build1 (INDIRECT_REF, type, build (PLUS_EXPR, build_pointer_type (type), addr, member)); } else if (TYPE_PTRMEMFUNC_P (TREE_TYPE (member))) { return get_member_function_from_ptrfunc (&addr, member); } my_friendly_abort (56); /* NOTREACHED */ return NULL_TREE; } /* Return either DECL or its known constant value (if it has one). */ tree decl_constant_value (decl) tree decl; { if (! TREE_THIS_VOLATILE (decl) && DECL_INITIAL (decl) && DECL_INITIAL (decl) != error_mark_node /* This is invalid if initial value is not constant. If it has either a function call, a memory reference, or a variable, then re-evaluating it could give different results. */ && TREE_CONSTANT (DECL_INITIAL (decl)) /* Check for cases where this is sub-optimal, even though valid. */ && TREE_CODE (DECL_INITIAL (decl)) != CONSTRUCTOR) return DECL_INITIAL (decl); return decl; } /* Common subroutines of build_new and build_vec_delete. */ /* Call the global __builtin_delete to delete ADDR. */ static tree build_builtin_delete_call (addr) tree addr; { mark_used (global_delete_fndecl); return build_call (global_delete_fndecl, void_type_node, build_expr_list (NULL_TREE, addr)); } /* Generate a C++ "new" expression. DECL is either a TREE_LIST (which needs to go through some sort of groktypename) or it is the name of the class we are newing. INIT is an initialization value. It is either an EXPRLIST, an EXPR_NO_COMMAS, or something in braces. If INIT is void_type_node, it means do *not* call a constructor for this instance. For types with constructors, the data returned is initialized by the appropriate constructor. Whether the type has a constructor or not, if it has a pointer to a virtual function table, then that pointer is set up here. Unless I am mistaken, a call to new () will return initialized data regardless of whether the constructor itself is private or not. NOPE; new fails if the constructor is private (jcm). Note that build_new does nothing to assure that any special alignment requirements of the type are met. Rather, it leaves it up to malloc to do the right thing. Otherwise, folding to the right alignment cal cause problems if the user tries to later free the memory returned by `new'. PLACEMENT is the `placement' list for user-defined operator new (). */ extern int flag_check_new; tree build_new (placement, decl, init, use_global_new) tree placement; tree decl, init; int use_global_new; { tree type, rval; tree nelts = NULL_TREE, t; int has_array = 0; tree pending_sizes = NULL_TREE; if (decl == error_mark_node) return error_mark_node; if (TREE_CODE (decl) == TREE_LIST) { tree absdcl = TREE_VALUE (decl); tree last_absdcl = NULL_TREE; int old_immediate_size_expand = 0; if (current_function_decl && DECL_CONSTRUCTOR_P (current_function_decl)) { old_immediate_size_expand = immediate_size_expand; immediate_size_expand = 0; } nelts = integer_one_node; if (absdcl && TREE_CODE (absdcl) == CALL_EXPR) my_friendly_abort (215); while (absdcl && TREE_CODE (absdcl) == INDIRECT_REF) { last_absdcl = absdcl; absdcl = TREE_OPERAND (absdcl, 0); } if (absdcl && TREE_CODE (absdcl) == ARRAY_REF) { /* probably meant to be a vec new */ tree this_nelts; while (TREE_OPERAND (absdcl, 0) && TREE_CODE (TREE_OPERAND (absdcl, 0)) == ARRAY_REF) { last_absdcl = absdcl; absdcl = TREE_OPERAND (absdcl, 0); } has_array = 1; this_nelts = TREE_OPERAND (absdcl, 1); if (this_nelts != error_mark_node) { if (this_nelts == NULL_TREE) error ("new of array type fails to specify size"); else if (processing_template_decl) { nelts = this_nelts; absdcl = TREE_OPERAND (absdcl, 0); } else { int flags = pedantic ? WANT_INT : (WANT_INT | WANT_ENUM); if (build_expr_type_conversion (flags, this_nelts, 0) == NULL_TREE) pedwarn ("size in array new must have integral type"); this_nelts = save_expr (cp_convert (sizetype, this_nelts)); absdcl = TREE_OPERAND (absdcl, 0); if (this_nelts == integer_zero_node) { warning ("zero size array reserves no space"); nelts = integer_zero_node; } else nelts = build_binary_op (MULT_EXPR, nelts, this_nelts); } } else nelts = integer_zero_node; } if (last_absdcl) TREE_OPERAND (last_absdcl, 0) = absdcl; else TREE_VALUE (decl) = absdcl; type = groktypename (decl); if (! type || type == error_mark_node) { immediate_size_expand = old_immediate_size_expand; return error_mark_node; } if (current_function_decl && DECL_CONSTRUCTOR_P (current_function_decl)) { pending_sizes = get_pending_sizes (); immediate_size_expand = old_immediate_size_expand; } } else if (TREE_CODE (decl) == IDENTIFIER_NODE) { if (IDENTIFIER_HAS_TYPE_VALUE (decl)) { /* An aggregate type. */ type = IDENTIFIER_TYPE_VALUE (decl); decl = TYPE_MAIN_DECL (type); } else { /* A builtin type. */ decl = lookup_name (decl, 1); my_friendly_assert (TREE_CODE (decl) == TYPE_DECL, 215); type = TREE_TYPE (decl); } } else if (TREE_CODE (decl) == TYPE_DECL) { type = TREE_TYPE (decl); } else { type = decl; decl = TYPE_MAIN_DECL (type); } if (processing_template_decl) { if (has_array) t = min_tree_cons (min_tree_cons (NULL_TREE, type, NULL_TREE), build_min_nt (ARRAY_REF, NULL_TREE, nelts), NULL_TREE); else t = type; rval = build_min_nt (NEW_EXPR, placement, t, init); NEW_EXPR_USE_GLOBAL (rval) = use_global_new; return rval; } /* ``A reference cannot be created by the new operator. A reference is not an object (8.2.2, 8.4.3), so a pointer to it could not be returned by new.'' ARM 5.3.3 */ if (TREE_CODE (type) == REFERENCE_TYPE) { error ("new cannot be applied to a reference type"); type = TREE_TYPE (type); } if (TREE_CODE (type) == FUNCTION_TYPE) { error ("new cannot be applied to a function type"); return error_mark_node; } /* When the object being created is an array, the new-expression yields a pointer to the initial element (if any) of the array. For example, both new int and new int[10] return an int*. 5.3.4. */ if (TREE_CODE (type) == ARRAY_TYPE && has_array == 0) { nelts = array_type_nelts_top (type); has_array = 1; type = TREE_TYPE (type); } if (has_array) t = build_nt (ARRAY_REF, type, nelts); else t = type; rval = build (NEW_EXPR, build_pointer_type (type), placement, t, init); NEW_EXPR_USE_GLOBAL (rval) = use_global_new; TREE_SIDE_EFFECTS (rval) = 1; /* Wrap it in a NOP_EXPR so warn_if_unused_value doesn't complain. */ rval = build1 (NOP_EXPR, TREE_TYPE (rval), rval); TREE_NO_UNUSED_WARNING (rval) = 1; if (pending_sizes) rval = build_compound_expr (chainon (pending_sizes, build_expr_list (NULL_TREE, rval))); return rval; } /* If non-NULL, a POINTER_TYPE equivalent to (java::lang::Class*). */ static tree jclass_node = NULL_TREE; /* Given a Java class, return a decl for the corresponding java.lang.Class. */ static tree build_java_class_ref (type) tree type; { tree name, class_decl; static tree CL_prefix = NULL_TREE; if (CL_prefix == NULL_TREE) CL_prefix = get_identifier("_CL_"); if (jclass_node == NULL_TREE) { jclass_node = IDENTIFIER_GLOBAL_VALUE (get_identifier("jclass")); if (jclass_node == NULL_TREE) fatal("call to Java constructor, while `jclass' undefined"); jclass_node = TREE_TYPE (jclass_node); } name = build_overload_with_type (CL_prefix, type); class_decl = IDENTIFIER_GLOBAL_VALUE (name); if (class_decl == NULL_TREE) { push_obstacks_nochange (); end_temporary_allocation (); class_decl = build_decl (VAR_DECL, name, TREE_TYPE (jclass_node)); TREE_STATIC (class_decl) = 1; DECL_EXTERNAL (class_decl) = 1; TREE_PUBLIC (class_decl) = 1; DECL_ARTIFICIAL (class_decl) = 1; DECL_IGNORED_P (class_decl) = 1; pushdecl_top_level (class_decl); make_decl_rtl (class_decl, NULL_PTR, 1); pop_obstacks (); } return class_decl; } /* Called from cplus_expand_expr when expanding a NEW_EXPR. The return value is immediately handed to expand_expr. */ tree build_new_1 (exp) tree exp; { tree placement, init; tree type, true_type, size, rval; tree nelts = NULL_TREE; tree alloc_expr, alloc_node = NULL_TREE; int has_array = 0; enum tree_code code = NEW_EXPR; int use_cookie, nothrow, check_new; int use_global_new; int use_java_new = 0; placement = TREE_OPERAND (exp, 0); type = TREE_OPERAND (exp, 1); init = TREE_OPERAND (exp, 2); use_global_new = NEW_EXPR_USE_GLOBAL (exp); if (TREE_CODE (type) == ARRAY_REF) { has_array = 1; nelts = TREE_OPERAND (type, 1); type = TREE_OPERAND (type, 0); } true_type = type; if (CP_TYPE_QUALS (type)) type = TYPE_MAIN_VARIANT (type); /* If our base type is an array, then make sure we know how many elements it has. */ while (TREE_CODE (true_type) == ARRAY_TYPE) { tree this_nelts = array_type_nelts_top (true_type); nelts = build_binary_op (MULT_EXPR, nelts, this_nelts); true_type = TREE_TYPE (true_type); } if (!complete_type_or_else (true_type, exp)) return error_mark_node; if (has_array) size = fold (build_binary_op (MULT_EXPR, size_in_bytes (true_type), nelts)); else size = size_in_bytes (type); if (TREE_CODE (true_type) == VOID_TYPE) { error ("invalid type `void' for new"); return error_mark_node; } if (TYPE_LANG_SPECIFIC (true_type) && CLASSTYPE_ABSTRACT_VIRTUALS (true_type)) { abstract_virtuals_error (NULL_TREE, true_type); return error_mark_node; } if (TYPE_LANG_SPECIFIC (true_type) && IS_SIGNATURE (true_type)) { signature_error (NULL_TREE, true_type); return error_mark_node; } /* When we allocate an array, and the corresponding deallocation function takes a second argument of type size_t, and that's the "usual deallocation function", we allocate some extra space at the beginning of the array to store the size of the array. Well, that's what we should do. For backwards compatibility, we have to do this whenever there's a two-argument array-delete operator. FIXME: For -fnew-abi, we don't have to maintain backwards compatibility and we should fix this. */ use_cookie = (has_array && TYPE_VEC_NEW_USES_COOKIE (true_type) && ! (placement && ! TREE_CHAIN (placement) && TREE_TYPE (TREE_VALUE (placement)) == ptr_type_node)); if (use_cookie) { tree extra = BI_header_size; size = size_binop (PLUS_EXPR, size, extra); } if (has_array) { code = VEC_NEW_EXPR; if (init && pedantic) cp_pedwarn ("initialization in array new"); } /* Allocate the object. */ if (! has_array && ! placement && flag_this_is_variable > 0 && TYPE_NEEDS_CONSTRUCTING (true_type) && init != void_type_node) { if (init == NULL_TREE || TREE_CODE (init) == TREE_LIST) rval = NULL_TREE; else { error ("constructors take parameter lists"); return error_mark_node; } } else if (! placement && TYPE_FOR_JAVA (true_type)) { tree class_addr, alloc_decl; tree class_decl = build_java_class_ref (true_type); tree class_size = size_in_bytes (true_type); static char alloc_name[] = "_Jv_AllocObject"; use_java_new = 1; alloc_decl = IDENTIFIER_GLOBAL_VALUE (get_identifier (alloc_name)); if (alloc_decl == NULL_TREE) fatal("call to Java constructor, while `%s' undefined", alloc_name); class_addr = build1 (ADDR_EXPR, jclass_node, class_decl); rval = build_function_call (alloc_decl, tree_cons (NULL_TREE, class_addr, build_tree_list (NULL_TREE, class_size))); rval = cp_convert (build_pointer_type (true_type), rval); } else { int susp = 0; if (flag_exceptions) /* We will use RVAL when generating an exception handler for this new-expression, so we must save it. */ susp = suspend_momentary (); rval = build_op_new_call (code, true_type, expr_tree_cons (NULL_TREE, size, placement), LOOKUP_NORMAL | (use_global_new * LOOKUP_GLOBAL)); rval = cp_convert (build_pointer_type (true_type), rval); if (flag_exceptions) resume_momentary (susp); } /* unless an allocation function is declared with an empty excep- tion-specification (_except.spec_), throw(), it indicates failure to allocate storage by throwing a bad_alloc exception (clause _except_, _lib.bad.alloc_); it returns a non-null pointer otherwise If the allo- cation function is declared with an empty exception-specification, throw(), it returns null to indicate failure to allocate storage and a non-null pointer otherwise. So check for a null exception spec on the op new we just called. */ nothrow = 0; if (rval) { /* The CALL_EXPR. */ tree t = TREE_OPERAND (rval, 0); /* The function. */ t = TREE_OPERAND (TREE_OPERAND (t, 0), 0); nothrow = TYPE_NOTHROW_P (TREE_TYPE (t)); } check_new = (flag_check_new || nothrow) && ! use_java_new; if ((check_new || flag_exceptions) && rval) { alloc_expr = get_target_expr (rval); alloc_node = rval = TREE_OPERAND (alloc_expr, 0); } else alloc_expr = NULL_TREE; /* if rval is NULL_TREE I don't have to allocate it, but are we totally sure we have some extra bytes in that case for the BI_header_size cookies? And how does that interact with the code below? (mrs) */ /* Finish up some magic for new'ed arrays */ if (use_cookie && rval != NULL_TREE) { tree extra = BI_header_size; tree cookie, exp1; rval = convert (string_type_node, rval); /* for ptr arithmetic */ rval = save_expr (build_binary_op (PLUS_EXPR, rval, extra)); /* Store header info. */ cookie = build_indirect_ref (build (MINUS_EXPR, build_pointer_type (BI_header_type), rval, extra), NULL_PTR); exp1 = build (MODIFY_EXPR, void_type_node, build_component_ref (cookie, nc_nelts_field_id, NULL_TREE, 0), nelts); TREE_SIDE_EFFECTS (exp1) = 1; rval = cp_convert (build_pointer_type (true_type), rval); rval = build_compound_expr (expr_tree_cons (NULL_TREE, exp1, build_expr_list (NULL_TREE, rval))); } if (rval == error_mark_node) return error_mark_node; /* Don't call any constructors or do any initialization. */ if (init == void_type_node) goto done; if (TYPE_NEEDS_CONSTRUCTING (type) || init) { if (! TYPE_NEEDS_CONSTRUCTING (type) && ! IS_AGGR_TYPE (type) && ! has_array) { /* We are processing something like `new int (10)', which means allocate an int, and initialize it with 10. */ tree deref; tree deref_type; /* At present RVAL is a temporary variable, created to hold the value from the call to `operator new'. We transform it to (*RVAL = INIT, RVAL). */ rval = save_expr (rval); deref = build_indirect_ref (rval, NULL_PTR); /* Even for something like `new const int (10)' we must allow the expression to be non-const while we do the initialization. */ deref_type = TREE_TYPE (deref); if (CP_TYPE_CONST_P (deref_type)) TREE_TYPE (deref) = cp_build_qualified_type (deref_type, CP_TYPE_QUALS (deref_type) & ~TYPE_QUAL_CONST); TREE_READONLY (deref) = 0; if (TREE_CHAIN (init) != NULL_TREE) pedwarn ("initializer list being treated as compound expression"); else if (TREE_CODE (init) == CONSTRUCTOR) { pedwarn ("initializer list appears where operand should be used"); init = TREE_OPERAND (init, 1); } init = build_compound_expr (init); init = convert_for_initialization (deref, type, init, LOOKUP_NORMAL, "new", NULL_TREE, 0); rval = build (COMPOUND_EXPR, TREE_TYPE (rval), build_modify_expr (deref, NOP_EXPR, init), rval); TREE_NO_UNUSED_WARNING (rval) = 1; TREE_SIDE_EFFECTS (rval) = 1; } else if (! has_array) { tree newrval; /* Constructors are never virtual. If it has an initialization, we need to complain if we aren't allowed to use the ctor that took that argument. */ int flags = LOOKUP_NORMAL|LOOKUP_NONVIRTUAL|LOOKUP_COMPLAIN; if (rval && TYPE_USES_VIRTUAL_BASECLASSES (true_type)) { + if (TYPE_USES_PVBASES (true_type) + && !flag_vtable_thunks_compat) + { + init = expr_tree_cons (NULL_TREE, vlist_zero_node, init); + flags |= LOOKUP_HAS_VLIST; + } init = expr_tree_cons (NULL_TREE, integer_one_node, init); flags |= LOOKUP_HAS_IN_CHARGE; } if (use_java_new) rval = save_expr (rval); newrval = rval; if (newrval && TREE_CODE (TREE_TYPE (newrval)) == POINTER_TYPE) newrval = build_indirect_ref (newrval, NULL_PTR); newrval = build_method_call (newrval, ctor_identifier, init, TYPE_BINFO (true_type), flags); if (newrval == NULL_TREE || newrval == error_mark_node) return error_mark_node; /* Java constructors compiled by jc1 do not return this. */ if (use_java_new) newrval = build (COMPOUND_EXPR, TREE_TYPE (newrval), newrval, rval); rval = newrval; TREE_HAS_CONSTRUCTOR (rval) = 1; } else rval = build (VEC_INIT_EXPR, TREE_TYPE (rval), save_expr (rval), init, nelts); /* If any part of the object initialization terminates by throwing an exception and a suitable deallocation function can be found, the deallocation function is called to free the memory in which the object was being constructed, after which the exception continues to propagate in the context of the new-expression. If no unambiguous matching deallocation function can be found, propagating the exception does not cause the object's memory to be freed. */ if (flag_exceptions && alloc_expr && ! use_java_new) { enum tree_code dcode = has_array ? VEC_DELETE_EXPR : DELETE_EXPR; tree cleanup, fn = NULL_TREE; int flags = LOOKUP_NORMAL | (use_global_new * LOOKUP_GLOBAL); /* All cleanups must last longer than normal. */ int yes = suspend_momentary (); if (placement) { flags |= LOOKUP_SPECULATIVELY; /* We expect alloc_expr to look like a TARGET_EXPR around a NOP_EXPR around the CALL_EXPR we want. */ fn = TREE_OPERAND (alloc_expr, 1); fn = TREE_OPERAND (fn, 0); } /* Copy size to the saveable obstack. */ size = mapcar (size, permanent_p); cleanup = build_op_delete_call (dcode, alloc_node, size, flags, fn); resume_momentary (yes); /* Ack! First we allocate the memory. Then we set our sentry variable to true, and expand a cleanup that deletes the memory if sentry is true. Then we run the constructor and store the returned pointer in buf. Then we clear sentry and return buf. */ if (cleanup) { tree end, sentry, begin, buf, t = TREE_TYPE (rval); begin = get_target_expr (boolean_true_node); sentry = TREE_OPERAND (begin, 0); yes = suspend_momentary (); TREE_OPERAND (begin, 2) = build (COND_EXPR, void_type_node, sentry, cleanup, void_zero_node); resume_momentary (yes); rval = get_target_expr (rval); end = build (MODIFY_EXPR, TREE_TYPE (sentry), sentry, boolean_false_node); TREE_SIDE_EFFECTS (end) = 1; buf = TREE_OPERAND (rval, 0); rval = build (COMPOUND_EXPR, t, begin, build (COMPOUND_EXPR, t, rval, build (COMPOUND_EXPR, t, end, buf))); } } } else if (CP_TYPE_CONST_P (true_type)) cp_error ("uninitialized const in `new' of `%#T'", true_type); done: if (alloc_expr && rval == alloc_node) { rval = TREE_OPERAND (alloc_expr, 1); alloc_expr = NULL_TREE; } if (check_new && alloc_expr) { /* Did we modify the storage? */ tree ifexp = build_binary_op (NE_EXPR, alloc_node, integer_zero_node); rval = build_conditional_expr (ifexp, rval, alloc_node); } if (alloc_expr) rval = build (COMPOUND_EXPR, TREE_TYPE (rval), alloc_expr, rval); if (rval && TREE_TYPE (rval) != build_pointer_type (type)) { /* The type of new int [3][3] is not int *, but int [3] * */ rval = build_c_cast (build_pointer_type (type), rval); } return rval; } static tree build_vec_delete_1 (base, maxindex, type, auto_delete_vec, auto_delete, use_global_delete) tree base, maxindex, type; tree auto_delete_vec, auto_delete; int use_global_delete; { tree virtual_size; tree ptype = build_pointer_type (type = complete_type (type)); tree size_exp = size_in_bytes (type); /* Temporary variables used by the loop. */ tree tbase, tbase_init; /* This is the body of the loop that implements the deletion of a single element, and moves temp variables to next elements. */ tree body; /* This is the LOOP_EXPR that governs the deletion of the elements. */ tree loop; /* This is the thing that governs what to do after the loop has run. */ tree deallocate_expr = 0; /* This is the BIND_EXPR which holds the outermost iterator of the loop. It is convenient to set this variable up and test it before executing any other code in the loop. This is also the containing expression returned by this function. */ tree controller = NULL_TREE; if (! IS_AGGR_TYPE (type) || ! TYPE_NEEDS_DESTRUCTOR (type)) { loop = integer_zero_node; goto no_destructor; } /* The below is short by BI_header_size */ virtual_size = fold (size_binop (MULT_EXPR, size_exp, maxindex)); tbase = build_decl (VAR_DECL, NULL_TREE, ptype); tbase_init = build_modify_expr (tbase, NOP_EXPR, fold (build (PLUS_EXPR, ptype, base, virtual_size))); DECL_REGISTER (tbase) = 1; controller = build (BIND_EXPR, void_type_node, tbase, NULL_TREE, NULL_TREE); TREE_SIDE_EFFECTS (controller) = 1; if (auto_delete != integer_zero_node && auto_delete != integer_two_node) { tree base_tbd = cp_convert (ptype, build_binary_op (MINUS_EXPR, cp_convert (ptr_type_node, base), BI_header_size)); /* This is the real size */ virtual_size = size_binop (PLUS_EXPR, virtual_size, BI_header_size); body = build_expr_list (NULL_TREE, build_x_delete (base_tbd, 2 | use_global_delete, virtual_size)); body = build (COND_EXPR, void_type_node, build (BIT_AND_EXPR, integer_type_node, auto_delete, integer_one_node), body, integer_zero_node); } else body = NULL_TREE; body = expr_tree_cons (NULL_TREE, build_delete (ptype, tbase, auto_delete, LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 1), body); body = expr_tree_cons (NULL_TREE, build_modify_expr (tbase, NOP_EXPR, build (MINUS_EXPR, ptype, tbase, size_exp)), body); body = expr_tree_cons (NULL_TREE, build (EXIT_EXPR, void_type_node, build (EQ_EXPR, boolean_type_node, base, tbase)), body); loop = build (LOOP_EXPR, void_type_node, build_compound_expr (body)); loop = expr_tree_cons (NULL_TREE, tbase_init, expr_tree_cons (NULL_TREE, loop, NULL_TREE)); loop = build_compound_expr (loop); no_destructor: /* If the delete flag is one, or anything else with the low bit set, delete the storage. */ if (auto_delete_vec == integer_zero_node) deallocate_expr = integer_zero_node; else { tree base_tbd; /* The below is short by BI_header_size */ virtual_size = fold (size_binop (MULT_EXPR, size_exp, maxindex)); if (! TYPE_VEC_NEW_USES_COOKIE (type)) /* no header */ base_tbd = base; else { base_tbd = cp_convert (ptype, build_binary_op (MINUS_EXPR, cp_convert (string_type_node, base), BI_header_size)); /* True size with header. */ virtual_size = size_binop (PLUS_EXPR, virtual_size, BI_header_size); } deallocate_expr = build_x_delete (base_tbd, 2 | use_global_delete, virtual_size); if (auto_delete_vec != integer_one_node) deallocate_expr = build (COND_EXPR, void_type_node, build (BIT_AND_EXPR, integer_type_node, auto_delete_vec, integer_one_node), deallocate_expr, integer_zero_node); } if (loop && deallocate_expr != integer_zero_node) { body = expr_tree_cons (NULL_TREE, loop, expr_tree_cons (NULL_TREE, deallocate_expr, NULL_TREE)); body = build_compound_expr (body); } else body = loop; /* Outermost wrapper: If pointer is null, punt. */ body = build (COND_EXPR, void_type_node, build (NE_EXPR, boolean_type_node, base, integer_zero_node), body, integer_zero_node); body = build1 (NOP_EXPR, void_type_node, body); if (controller) { TREE_OPERAND (controller, 1) = body; return controller; } else return cp_convert (void_type_node, body); } /* Protect the vector initialization with a try-block so that we can destroy the first few elements if constructing a later element causes an exception to be thrown. TYPE is the type of the array elements. */ static void expand_vec_init_try_block (type) tree type; { if (!TYPE_NEEDS_DESTRUCTOR (type) || !flag_exceptions) return; /* The code we generate looks like: try { // Initialize the vector. } catch (...) { // Destory the elements that need destroying. throw; } Here we're just beginning the `try'. */ expand_eh_region_start (); } /* Add code to destroy the array elements constructed so far if the construction of some element in the array causes an exception to be thrown. RVAL is the address of the last element in the array. TYPE is the type of the array elements. MAXINDEX is the maximum allowable index into the array. ITERATOR is an integer variable indicating how many elements remain to be constructed. */ static void expand_vec_init_catch_clause (rval, type, maxindex, iterator) tree rval; tree type; tree maxindex; tree iterator; { tree e; tree cleanup; if (!TYPE_NEEDS_DESTRUCTOR (type) || !flag_exceptions) return; /* We have to ensure that this can live to the cleanup expansion time, since we know it is only ever needed once, generate code now. */ push_obstacks_nochange (); resume_temporary_allocation (); cleanup = make_node (RTL_EXPR); TREE_TYPE (cleanup) = void_type_node; RTL_EXPR_RTL (cleanup) = const0_rtx; TREE_SIDE_EFFECTS (cleanup) = 1; do_pending_stack_adjust (); start_sequence_for_rtl_expr (cleanup); e = build_vec_delete_1 (rval, build_binary_op (MINUS_EXPR, maxindex, iterator), type, /*auto_delete_vec=*/integer_zero_node, /*auto_delete=*/integer_zero_node, /*use_global_delete=*/0); expand_expr (e, const0_rtx, VOIDmode, EXPAND_NORMAL); do_pending_stack_adjust (); RTL_EXPR_SEQUENCE (cleanup) = get_insns (); end_sequence (); cleanup = protect_with_terminate (cleanup); expand_eh_region_end (cleanup); pop_obstacks (); } /* `expand_vec_init' performs initialization of a vector of aggregate types. DECL is passed only for error reporting, and provides line number and source file name information. BASE is the space where the vector will be. MAXINDEX is the maximum index of the array (one less than the number of elements). INIT is the (possibly NULL) initializer. FROM_ARRAY is 0 if we should init everything with INIT (i.e., every element initialized from INIT). FROM_ARRAY is 1 if we should index into INIT in parallel with initialization of DECL. FROM_ARRAY is 2 if we should index into INIT in parallel, but use assignment instead of initialization. */ tree expand_vec_init (decl, base, maxindex, init, from_array) tree decl, base, maxindex, init; int from_array; { tree rval; tree base2 = NULL_TREE; tree type = TREE_TYPE (TREE_TYPE (base)); tree size; tree itype = NULL_TREE; tree iterator; int num_initialized_elts = 0; maxindex = cp_convert (ptrdiff_type_node, maxindex); if (maxindex == error_mark_node) return error_mark_node; if (current_function_decl == NULL_TREE) { rval = make_tree_vec (3); TREE_VEC_ELT (rval, 0) = base; TREE_VEC_ELT (rval, 1) = maxindex; TREE_VEC_ELT (rval, 2) = init; return rval; } size = size_in_bytes (type); base = default_conversion (base); base = cp_convert (build_pointer_type (type), base); rval = get_temp_regvar (build_pointer_type (type), base); base = get_temp_regvar (build_pointer_type (type), base); iterator = get_temp_regvar (ptrdiff_type_node, maxindex); /* Protect the entire array initialization so that we can destroy the partially constructed array if an exception is thrown. */ expand_vec_init_try_block (type); if (init != NULL_TREE && TREE_CODE (init) == CONSTRUCTOR && (!decl || same_type_p (TREE_TYPE (init), TREE_TYPE (decl)))) { /* Do non-default initialization resulting from brace-enclosed initializers. */ tree elts; tree baseref = build1 (INDIRECT_REF, type, base); from_array = 0; for (elts = CONSTRUCTOR_ELTS (init); elts; elts = TREE_CHAIN (elts)) { tree elt = TREE_VALUE (elts); num_initialized_elts++; if (IS_AGGR_TYPE (type) || TREE_CODE (type) == ARRAY_TYPE) expand_aggr_init (baseref, elt, 0); else expand_assignment (baseref, elt, 0, 0); expand_assignment (base, build (PLUS_EXPR, build_pointer_type (type), base, size), 0, 0); expand_assignment (iterator, build (MINUS_EXPR, ptrdiff_type_node, iterator, integer_one_node), 0, 0); } /* Clear out INIT so that we don't get confused below. */ init = NULL_TREE; if (obey_regdecls) use_variable (DECL_RTL (base)); } else if (from_array) { /* If initializing one array from another, initialize element by element. We rely upon the below calls the do argument checking. */ if (decl == NULL_TREE) { sorry ("initialization of array from dissimilar array type"); return error_mark_node; } if (init) { base2 = default_conversion (init); itype = TREE_TYPE (base2); base2 = get_temp_regvar (itype, base2); itype = TREE_TYPE (itype); } else if (TYPE_LANG_SPECIFIC (type) && TYPE_NEEDS_CONSTRUCTING (type) && ! TYPE_HAS_DEFAULT_CONSTRUCTOR (type)) { error ("initializer ends prematurely"); return error_mark_node; } } /* Now, default-initialize any remaining elements. We don't need to do that if a) the type does not need constructing, or b) we've already initialized all the elements. We do need to keep going if we're copying an array. */ if (from_array || (TYPE_NEEDS_CONSTRUCTING (type) && !(TREE_CODE (maxindex) == INTEGER_CST && num_initialized_elts == TREE_INT_CST_LOW (maxindex) + 1))) { /* If the ITERATOR is equal to -1, then we don't have to loop; we've already initialized all the elements. */ expand_start_cond (build (NE_EXPR, boolean_type_node, iterator, minus_one), 0); /* Otherwise, loop through the elements. */ expand_start_loop_continue_elsewhere (1); /* The initialization of each array element is a full-expression. */ expand_start_target_temps (); if (from_array) { tree to = build1 (INDIRECT_REF, type, base); tree from; if (base2) from = build1 (INDIRECT_REF, itype, base2); else from = NULL_TREE; if (from_array == 2) expand_expr_stmt (build_modify_expr (to, NOP_EXPR, from)); else if (TYPE_NEEDS_CONSTRUCTING (type)) expand_aggr_init (to, from, 0); else if (from) expand_assignment (to, from, 0, 0); else my_friendly_abort (57); } else if (TREE_CODE (type) == ARRAY_TYPE) { if (init != 0) sorry ("cannot initialize multi-dimensional array with initializer"); expand_vec_init (decl, build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (type)), base), array_type_nelts (type), 0, 0); } else expand_aggr_init (build1 (INDIRECT_REF, type, base), init, 0); expand_assignment (base, build (PLUS_EXPR, build_pointer_type (type), base, size), 0, 0); if (base2) expand_assignment (base2, build (PLUS_EXPR, build_pointer_type (type), base2, size), 0, 0); /* Cleanup any temporaries needed for the initial value. */ expand_end_target_temps (); expand_loop_continue_here (); expand_exit_loop_if_false (0, build (NE_EXPR, boolean_type_node, build (PREDECREMENT_EXPR, ptrdiff_type_node, iterator, integer_one_node), minus_one)); if (obey_regdecls) { use_variable (DECL_RTL (base)); if (base2) use_variable (DECL_RTL (base2)); } expand_end_loop (); expand_end_cond (); } /* Make sure to cleanup any partially constructed elements. */ expand_vec_init_catch_clause (rval, type, maxindex, iterator); if (obey_regdecls) { use_variable (DECL_RTL (iterator)); use_variable (DECL_RTL (rval)); } return rval; } /* Free up storage of type TYPE, at address ADDR. TYPE is a POINTER_TYPE and can be ptr_type_node for no special type of pointer. VIRTUAL_SIZE is the amount of storage that was allocated, and is used as the second argument to operator delete. It can include things like padding and magic size cookies. It has virtual in it, because if you have a base pointer and you delete through a virtual destructor, it should be the size of the dynamic object, not the static object, see Free Store 12.5 ANSI C++ WP. This does not call any destructors. */ tree build_x_delete (addr, which_delete, virtual_size) tree addr; int which_delete; tree virtual_size; { int use_global_delete = which_delete & 1; int use_vec_delete = !!(which_delete & 2); enum tree_code code = use_vec_delete ? VEC_DELETE_EXPR : DELETE_EXPR; int flags = LOOKUP_NORMAL | (use_global_delete * LOOKUP_GLOBAL); return build_op_delete_call (code, addr, virtual_size, flags, NULL_TREE); } /* Generate a call to a destructor. TYPE is the type to cast ADDR to. ADDR is an expression which yields the store to be destroyed. AUTO_DELETE is nonzero if a call to DELETE should be made or not. If in the program, (AUTO_DELETE & 2) is non-zero, we tear down the virtual baseclasses. If in the program, (AUTO_DELETE & 1) is non-zero, then we deallocate. FLAGS is the logical disjunction of zero or more LOOKUP_ flags. See cp-tree.h for more info. This function does not delete an object's virtual base classes. */ tree build_delete (type, addr, auto_delete, flags, use_global_delete) tree type, addr; tree auto_delete; int flags; int use_global_delete; { tree member; tree expr; tree ref; if (addr == error_mark_node) return error_mark_node; /* Can happen when CURRENT_EXCEPTION_OBJECT gets its type set to `error_mark_node' before it gets properly cleaned up. */ if (type == error_mark_node) return error_mark_node; type = TYPE_MAIN_VARIANT (type); if (TREE_CODE (type) == POINTER_TYPE) { type = TYPE_MAIN_VARIANT (TREE_TYPE (type)); if (type != void_type_node && !complete_type_or_else (type, addr)) return error_mark_node; if (TREE_CODE (type) == ARRAY_TYPE) goto handle_array; if (! IS_AGGR_TYPE (type)) { /* Call the builtin operator delete. */ return build_builtin_delete_call (addr); } if (TREE_SIDE_EFFECTS (addr)) addr = save_expr (addr); /* throw away const and volatile on target type of addr */ addr = convert_force (build_pointer_type (type), addr, 0); ref = build_indirect_ref (addr, NULL_PTR); } else if (TREE_CODE (type) == ARRAY_TYPE) { handle_array: if (TREE_SIDE_EFFECTS (addr)) addr = save_expr (addr); if (TYPE_DOMAIN (type) == NULL_TREE) { error ("unknown array size in delete"); return error_mark_node; } return build_vec_delete (addr, array_type_nelts (type), auto_delete, integer_zero_node, use_global_delete); } else { /* Don't check PROTECT here; leave that decision to the destructor. If the destructor is accessible, call it, else report error. */ addr = build_unary_op (ADDR_EXPR, addr, 0); if (TREE_SIDE_EFFECTS (addr)) addr = save_expr (addr); if (TREE_CONSTANT (addr)) addr = convert_pointer_to (type, addr); else addr = convert_force (build_pointer_type (type), addr, 0); ref = build_indirect_ref (addr, NULL_PTR); } my_friendly_assert (IS_AGGR_TYPE (type), 220); if (! TYPE_NEEDS_DESTRUCTOR (type)) { if (auto_delete == integer_zero_node) return void_zero_node; return build_op_delete_call (DELETE_EXPR, addr, c_sizeof_nowarn (type), LOOKUP_NORMAL | (use_global_delete * LOOKUP_GLOBAL), NULL_TREE); } /* Below, we will reverse the order in which these calls are made. If we have a destructor, then that destructor will take care of the base classes; otherwise, we must do that here. */ if (TYPE_HAS_DESTRUCTOR (type)) { tree passed_auto_delete; tree do_delete = NULL_TREE; tree ifexp; if (use_global_delete) { tree cond = fold (build (BIT_AND_EXPR, integer_type_node, auto_delete, integer_one_node)); tree call = build_builtin_delete_call (addr); cond = fold (build (COND_EXPR, void_type_node, cond, call, void_zero_node)); if (cond != void_zero_node) do_delete = cond; passed_auto_delete = fold (build (BIT_AND_EXPR, integer_type_node, auto_delete, integer_two_node)); } else passed_auto_delete = auto_delete; - expr = build_method_call - (ref, dtor_identifier, build_expr_list (NULL_TREE, passed_auto_delete), - NULL_TREE, flags); + /* Maybe pass vlist pointer to destructor. */ + if (TYPE_USES_PVBASES (type)) + { + /* Pass vlist_zero even if in backwards compatibility mode, + as the extra argument should not hurt if it is not used. */ + expr = build_expr_list (NULL_TREE, vlist_zero_node); + flags |= LOOKUP_HAS_VLIST; + } + else + expr = NULL_TREE; + expr = expr_tree_cons (NULL_TREE, passed_auto_delete, expr); + + expr = build_method_call (ref, dtor_identifier, expr, + NULL_TREE, flags); + if (do_delete) expr = build (COMPOUND_EXPR, void_type_node, expr, do_delete); if (flags & LOOKUP_DESTRUCTOR) /* Explicit destructor call; don't check for null pointer. */ ifexp = integer_one_node; else /* Handle deleting a null pointer. */ ifexp = fold (build_binary_op (NE_EXPR, addr, integer_zero_node)); if (ifexp != integer_one_node) expr = build (COND_EXPR, void_type_node, ifexp, expr, void_zero_node); return expr; } else { /* We only get here from finish_function for a destructor. */ tree binfos = BINFO_BASETYPES (TYPE_BINFO (type)); int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0; tree base_binfo = n_baseclasses > 0 ? TREE_VEC_ELT (binfos, 0) : NULL_TREE; tree exprstmt = NULL_TREE; tree parent_auto_delete = auto_delete; tree cond; /* Set this again before we call anything, as we might get called recursively. */ TYPE_HAS_DESTRUCTOR (type) = 1; /* If we have member delete or vbases, we call delete in finish_function. */ if (auto_delete == integer_zero_node) cond = NULL_TREE; else if (base_binfo == NULL_TREE || ! TYPE_NEEDS_DESTRUCTOR (BINFO_TYPE (base_binfo))) { cond = build (COND_EXPR, void_type_node, build (BIT_AND_EXPR, integer_type_node, auto_delete, integer_one_node), build_builtin_delete_call (addr), void_zero_node); } else cond = NULL_TREE; if (cond) exprstmt = build_expr_list (NULL_TREE, cond); if (base_binfo && ! TREE_VIA_VIRTUAL (base_binfo) && TYPE_NEEDS_DESTRUCTOR (BINFO_TYPE (base_binfo))) { tree this_auto_delete; + /* Should the base invoke delete? */ if (BINFO_OFFSET_ZEROP (base_binfo)) this_auto_delete = parent_auto_delete; else this_auto_delete = integer_zero_node; - expr = build_scoped_method_call - (ref, base_binfo, dtor_identifier, - build_expr_list (NULL_TREE, this_auto_delete)); + expr = build_base_dtor_call (ref, base_binfo, this_auto_delete); exprstmt = expr_tree_cons (NULL_TREE, expr, exprstmt); } /* Take care of the remaining baseclasses. */ for (i = 1; i < n_baseclasses; i++) { base_binfo = TREE_VEC_ELT (binfos, i); if (! TYPE_NEEDS_DESTRUCTOR (BINFO_TYPE (base_binfo)) || TREE_VIA_VIRTUAL (base_binfo)) continue; - expr = build_scoped_method_call - (ref, base_binfo, dtor_identifier, - build_expr_list (NULL_TREE, integer_zero_node)); + expr = build_base_dtor_call (ref, base_binfo, integer_zero_node); exprstmt = expr_tree_cons (NULL_TREE, expr, exprstmt); } for (member = TYPE_FIELDS (type); member; member = TREE_CHAIN (member)) { if (TREE_CODE (member) != FIELD_DECL) continue; if (TYPE_NEEDS_DESTRUCTOR (TREE_TYPE (member))) { tree this_member = build_component_ref (ref, DECL_NAME (member), NULL_TREE, 0); tree this_type = TREE_TYPE (member); expr = build_delete (this_type, this_member, integer_two_node, flags, 0); exprstmt = expr_tree_cons (NULL_TREE, expr, exprstmt); } } if (exprstmt) return build_compound_expr (exprstmt); /* Virtual base classes make this function do nothing. */ return void_zero_node; } } /* For type TYPE, delete the virtual baseclass objects of DECL. */ tree build_vbase_delete (type, decl) tree type, decl; { tree vbases = CLASSTYPE_VBASECLASSES (type); tree result = NULL_TREE; tree addr = build_unary_op (ADDR_EXPR, decl, 0); my_friendly_assert (addr != error_mark_node, 222); while (vbases) { tree this_addr = convert_force (build_pointer_type (BINFO_TYPE (vbases)), addr, 0); result = expr_tree_cons (NULL_TREE, build_delete (TREE_TYPE (this_addr), this_addr, integer_zero_node, LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 0), result); vbases = TREE_CHAIN (vbases); } return build_compound_expr (nreverse (result)); } /* Build a C++ vector delete expression. MAXINDEX is the number of elements to be deleted. ELT_SIZE is the nominal size of each element in the vector. BASE is the expression that should yield the store to be deleted. This function expands (or synthesizes) these calls itself. AUTO_DELETE_VEC says whether the container (vector) should be deallocated. AUTO_DELETE say whether each item in the container should be deallocated. This also calls delete for virtual baseclasses of elements of the vector. Update: MAXINDEX is no longer needed. The size can be extracted from the start of the vector for pointers, and from the type for arrays. We still use MAXINDEX for arrays because it happens to already have one of the values we'd have to extract. (We could use MAXINDEX with pointers to confirm the size, and trap if the numbers differ; not clear that it'd be worth bothering.) */ tree build_vec_delete (base, maxindex, auto_delete_vec, auto_delete, use_global_delete) tree base, maxindex; tree auto_delete_vec, auto_delete; int use_global_delete; { tree type; if (TREE_CODE (base) == OFFSET_REF) base = resolve_offset_ref (base); type = TREE_TYPE (base); base = stabilize_reference (base); /* Since we can use base many times, save_expr it. */ if (TREE_SIDE_EFFECTS (base)) base = save_expr (base); if (TREE_CODE (type) == POINTER_TYPE) { /* Step back one from start of vector, and read dimension. */ tree cookie_addr = build (MINUS_EXPR, build_pointer_type (BI_header_type), base, BI_header_size); tree cookie = build_indirect_ref (cookie_addr, NULL_PTR); maxindex = build_component_ref (cookie, nc_nelts_field_id, NULL_TREE, 0); do type = TREE_TYPE (type); while (TREE_CODE (type) == ARRAY_TYPE); } else if (TREE_CODE (type) == ARRAY_TYPE) { /* get the total number of things in the array, maxindex is a bad name */ maxindex = array_type_nelts_total (type); while (TREE_CODE (type) == ARRAY_TYPE) type = TREE_TYPE (type); base = build_unary_op (ADDR_EXPR, base, 1); } else { if (base != error_mark_node) error ("type to vector delete is neither pointer or array type"); return error_mark_node; } return build_vec_delete_1 (base, maxindex, type, auto_delete_vec, auto_delete, use_global_delete); } Index: vendor/gcc/dist/contrib/gcc/cp/method.c =================================================================== --- vendor/gcc/dist/contrib/gcc/cp/method.c (revision 60966) +++ vendor/gcc/dist/contrib/gcc/cp/method.c (revision 60967) @@ -1,2445 +1,2656 @@ /* Handle the hair of processing (but not expanding) inline functions. Also manage function and variable name overloading. Copyright (C) 1987, 89, 92-97, 1998, 1999 Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@cygnus.com) 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. */ #ifndef __GNUC__ #define __inline #endif #ifndef PARM_CAN_BE_ARRAY_TYPE #define PARM_CAN_BE_ARRAY_TYPE 1 #endif /* Handle method declarations. */ #include "config.h" #include "system.h" #include "tree.h" #include "cp-tree.h" #include "obstack.h" #include "rtl.h" #include "expr.h" #include "output.h" #include "hard-reg-set.h" #include "flags.h" #include "toplev.h" +#include "decl.h" /* TREE_LIST of the current inline functions that need to be processed. */ struct pending_inline *pending_inlines; int static_labelno; #define obstack_chunk_alloc xmalloc #define obstack_chunk_free free /* Obstack where we build text strings for overloading, etc. */ static struct obstack scratch_obstack; static char *scratch_firstobj; static void icat PROTO((HOST_WIDE_INT)); static void dicat PROTO((HOST_WIDE_INT, HOST_WIDE_INT)); static int old_backref_index PROTO((tree)); static int flush_repeats PROTO((int, tree)); static void build_overload_identifier PROTO((tree)); static void build_overload_nested_name PROTO((tree)); static void build_overload_int PROTO((tree, int)); static void build_overload_identifier PROTO((tree)); static void build_qualified_name PROTO((tree)); static void build_overload_value PROTO((tree, tree, int)); static void issue_nrepeats PROTO((int, tree)); static char *build_mangled_name PROTO((tree,int,int)); static void process_modifiers PROTO((tree)); static void process_overload_item PROTO((tree,int)); static void do_build_assign_ref PROTO((tree)); static void do_build_copy_constructor PROTO((tree)); static tree largest_union_member PROTO((tree)); static void build_template_template_parm_names PROTO((tree)); static void build_template_parm_names PROTO((tree, tree)); static void build_underscore_int PROTO((int)); static void start_squangling PROTO((void)); static void end_squangling PROTO((void)); static int check_ktype PROTO((tree, int)); static int issue_ktype PROTO((tree)); static void build_overload_scope_ref PROTO((tree)); static void build_mangled_template_parm_index PROTO((char *, tree)); #if HOST_BITS_PER_WIDE_INT >= 64 static void build_mangled_C9x_name PROTO((int)); #endif static int is_back_referenceable_type PROTO((tree)); static int check_btype PROTO((tree)); static void build_mangled_name_for_type PROTO((tree)); static void build_mangled_name_for_type_with_Gcode PROTO((tree, int)); +static tree build_base_path PROTO((tree, int)); + # define OB_INIT() (scratch_firstobj ? (obstack_free (&scratch_obstack, scratch_firstobj), 0) : 0) # define OB_PUTC(C) (obstack_1grow (&scratch_obstack, (C))) # define OB_PUTC2(C1,C2) \ (obstack_1grow (&scratch_obstack, (C1)), obstack_1grow (&scratch_obstack, (C2))) # define OB_PUTS(S) (obstack_grow (&scratch_obstack, (S), sizeof (S) - 1)) # define OB_PUTID(ID) \ (obstack_grow (&scratch_obstack, IDENTIFIER_POINTER (ID), \ IDENTIFIER_LENGTH (ID))) # define OB_PUTCP(S) (obstack_grow (&scratch_obstack, (S), strlen (S))) # define OB_FINISH() (obstack_1grow (&scratch_obstack, '\0')) # define OB_LAST() (obstack_next_free (&scratch_obstack)[-1]) void init_method () { gcc_obstack_init (&scratch_obstack); scratch_firstobj = (char *)obstack_alloc (&scratch_obstack, 0); } /* This must be large enough to hold any printed integer or floating-point value. */ static char digit_buffer[128]; /* Move inline function definitions out of structure so that they can be processed normally. CNAME is the name of the class we are working from, METHOD_LIST is the list of method lists of the structure. We delete friend methods here, after saving away their inline function definitions (if any). */ void do_inline_function_hair (type, friend_list) tree type, friend_list; { tree method = TYPE_METHODS (type); if (method && TREE_CODE (method) == TREE_VEC) { if (TREE_VEC_ELT (method, 1)) method = TREE_VEC_ELT (method, 1); else if (TREE_VEC_ELT (method, 0)) method = TREE_VEC_ELT (method, 0); else method = TREE_VEC_ELT (method, 2); } while (method) { /* Do inline member functions. */ struct pending_inline *info = DECL_PENDING_INLINE_INFO (method); if (info) { tree args; my_friendly_assert (info->fndecl == method, 238); args = DECL_ARGUMENTS (method); while (args) { DECL_CONTEXT (args) = method; args = TREE_CHAIN (args); } } method = TREE_CHAIN (method); } while (friend_list) { tree fndecl = TREE_VALUE (friend_list); struct pending_inline *info = DECL_PENDING_INLINE_INFO (fndecl); if (info) { tree args; my_friendly_assert (info->fndecl == fndecl, 239); args = DECL_ARGUMENTS (fndecl); while (args) { DECL_CONTEXT (args) = fndecl; args = TREE_CHAIN (args); } } friend_list = TREE_CHAIN (friend_list); } } /* Here is where overload code starts. */ /* type tables for K and B type compression */ static tree *btypelist = NULL; static tree *ktypelist = NULL; static int maxbsize = 0; static int maxksize = 0; /* number of each type seen */ static int maxbtype = 0; static int maxktype = 0; /* Array of types seen so far in top-level call to `build_mangled_name'. Allocated and deallocated by caller. */ static tree *typevec = NULL; static int typevec_size; /* Number of types interned by `build_mangled_name' so far. */ static int maxtype = 0; /* Nonzero if we should not try folding parameter types. */ static int nofold; /* This appears to be set to true if an underscore is required to be comcatenated before another number can be outputed. */ static int numeric_output_need_bar; static __inline void start_squangling () { if (flag_do_squangling) { nofold = 0; maxbtype = 0; maxktype = 0; maxbsize = 50; maxksize = 50; btypelist = (tree *)xmalloc (sizeof (tree) * maxbsize); ktypelist = (tree *)xmalloc (sizeof (tree) * maxksize); } } static __inline void end_squangling () { if (flag_do_squangling) { if (ktypelist) free (ktypelist); if (btypelist) free (btypelist); maxbsize = 0; maxksize = 0; maxbtype = 0; maxktype = 0; ktypelist = NULL; btypelist = NULL; } } /* Code to concatenate an asciified integer to a string. */ static __inline void icat (i) HOST_WIDE_INT i; { unsigned HOST_WIDE_INT ui; /* Handle this case first, to go really quickly. For many common values, the result of ui/10 below is 1. */ if (i == 1) { OB_PUTC ('1'); return; } if (i >= 0) ui = i; else { OB_PUTC ('m'); ui = -i; } if (ui >= 10) icat (ui / 10); OB_PUTC ('0' + (ui % 10)); } static void dicat (lo, hi) HOST_WIDE_INT lo, hi; { unsigned HOST_WIDE_INT ulo, uhi, qlo, qhi; if (hi >= 0) { uhi = hi; ulo = lo; } else { uhi = (lo == 0 ? -hi : -hi-1); ulo = -lo; } if (uhi == 0 && ulo < ((unsigned HOST_WIDE_INT)1 << (HOST_BITS_PER_WIDE_INT - 1))) { icat (ulo); return; } /* Divide 2^HOST_WIDE_INT*uhi+ulo by 10. */ qhi = uhi / 10; uhi = uhi % 10; qlo = uhi * (((unsigned HOST_WIDE_INT)1 << (HOST_BITS_PER_WIDE_INT - 1)) / 5); qlo += ulo / 10; ulo = ulo % 10; ulo += uhi * (((unsigned HOST_WIDE_INT)1 << (HOST_BITS_PER_WIDE_INT - 1)) % 5) * 2; qlo += ulo / 10; ulo = ulo % 10; /* Quotient is 2^HOST_WIDE_INT*qhi+qlo, remainder is ulo. */ dicat (qlo, qhi); OB_PUTC ('0' + ulo); } /* Returns the index of TYPE in the typevec, or -1 if it's not there. */ static __inline int old_backref_index (type) tree type; { int tindex = 0; if (! is_back_referenceable_type (type)) return -1; /* The entry for this parm is at maxtype-1, so don't look there for something to repeat. */ for (tindex = 0; tindex < maxtype - 1; ++tindex) if (same_type_p (typevec[tindex], type)) break; if (tindex == maxtype - 1) return -1; return tindex; } /* Old mangling style: If TYPE has already been used in the parameter list, emit a backward reference and return non-zero; otherwise, return 0. NREPEATS is the number of repeats we've recorded of this type, or 0 if this is the first time we've seen it and we're just looking to see if it had been used before. */ static __inline int flush_repeats (nrepeats, type) int nrepeats; tree type; { int tindex = old_backref_index (type); if (tindex == -1) { my_friendly_assert (nrepeats == 0, 990316); return 0; } if (nrepeats > 1) { OB_PUTC ('N'); icat (nrepeats); if (nrepeats > 9) OB_PUTC ('_'); } else OB_PUTC ('T'); icat (tindex); if (tindex > 9) OB_PUTC ('_'); return 1; } /* Returns nonzero iff this is a type to which we will want to make back-references (using the `B' code). */ static int is_back_referenceable_type (type) tree type; { /* For some reason, the Java folks don't want back refs on these. */ if (TYPE_FOR_JAVA (type)) return 0; switch (TREE_CODE (type)) { case BOOLEAN_TYPE: if (!flag_do_squangling) /* Even though the mangling of this is just `b', we did historically generate back-references for it. */ return 1; /* Fall through. */ case INTEGER_TYPE: case REAL_TYPE: case VOID_TYPE: /* These types have single-character manglings, so there's no point in generating back-references. */ return 0; case TEMPLATE_TYPE_PARM: /* It would be a bit complex to demangle signatures correctly if we generated back-references to these, and the manglings of type parameters are short. */ return 0; default: return 1; } } /* Issue the squangling code indicating NREPEATS repetitions of TYPE, which was the last parameter type output. */ static void issue_nrepeats (nrepeats, type) int nrepeats; tree type; { if (nrepeats == 1 && !is_back_referenceable_type (type)) /* For types whose manglings are short, don't bother using the repetition code if there's only one repetition, since the repetition code will be about as long as the ordinary mangling. */ build_mangled_name_for_type (type); else { OB_PUTC ('n'); icat (nrepeats); if (nrepeats > 9) OB_PUTC ('_'); } } /* Check to see if a tree node has been entered into the Kcode typelist. If not, add it. Returns -1 if it isn't found, otherwise returns the index. */ static int check_ktype (node, add) tree node; int add; { int x; tree localnode = node; if (ktypelist == NULL) return -1; if (TREE_CODE (node) == TYPE_DECL) localnode = TREE_TYPE (node); for (x=0; x < maxktype; x++) { if (same_type_p (localnode, ktypelist[x])) return x; } /* Didn't find it, so add it here. */ if (add) { if (maxksize <= maxktype) { maxksize = maxksize* 3 / 2; ktypelist = (tree *)xrealloc (ktypelist, sizeof (tree) * maxksize); } ktypelist[maxktype++] = localnode; } return -1; } static __inline int issue_ktype (decl) tree decl; { int kindex; kindex = check_ktype (decl, FALSE); if (kindex != -1) { OB_PUTC ('K'); icat (kindex); if (kindex > 9) OB_PUTC ('_'); return TRUE; } return FALSE; } /* Build a representation for DECL, which may be an entity not at global scope. If so, a marker indicating that the name is qualified has already been output, but the qualifying context has not. */ static void build_overload_nested_name (decl) tree decl; { tree context; if (ktypelist && issue_ktype (decl)) return; if (decl == global_namespace) return; context = CP_DECL_CONTEXT (decl); /* try to issue a K type, and if we can't continue the normal path */ if (!(ktypelist && issue_ktype (context))) { /* For a template type parameter, we want to output an 'Xn' rather than 'T' or some such. */ if (TREE_CODE (context) == TEMPLATE_TYPE_PARM || TREE_CODE (context) == TEMPLATE_TEMPLATE_PARM) build_mangled_name_for_type (context); else { if (TREE_CODE_CLASS (TREE_CODE (context)) == 't') context = TYPE_NAME (context); build_overload_nested_name (context); } } if (TREE_CODE (decl) == FUNCTION_DECL) { tree name = DECL_ASSEMBLER_NAME (decl); char *label; ASM_FORMAT_PRIVATE_NAME (label, IDENTIFIER_POINTER (name), static_labelno); static_labelno++; if (numeric_output_need_bar) OB_PUTC ('_'); icat (strlen (label)); OB_PUTCP (label); numeric_output_need_bar = 1; } else if (TREE_CODE (decl) == NAMESPACE_DECL) build_overload_identifier (DECL_NAME (decl)); else /* TYPE_DECL */ build_overload_identifier (decl); } /* Output the decimal representation of I. If I > 9, the decimal representation is preceeded and followed by an underscore. */ static void build_underscore_int (i) int i; { if (i > 9) OB_PUTC ('_'); icat (i); if (i > 9) OB_PUTC ('_'); } static void build_overload_scope_ref (value) tree value; { OB_PUTC2 ('Q', '2'); numeric_output_need_bar = 0; build_mangled_name_for_type (TREE_OPERAND (value, 0)); build_overload_identifier (TREE_OPERAND (value, 1)); } /* Encoding for an INTEGER_CST value. */ static void build_overload_int (value, in_template) tree value; int in_template; { if (in_template && TREE_CODE (value) != INTEGER_CST) { if (TREE_CODE (value) == SCOPE_REF) { build_overload_scope_ref (value); return; } OB_PUTC ('E'); numeric_output_need_bar = 0; if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (value)))) { int i; int operands = tree_code_length[(int) TREE_CODE (value)]; tree id; char* name; id = ansi_opname [(int) TREE_CODE (value)]; my_friendly_assert (id != NULL_TREE, 0); name = IDENTIFIER_POINTER (id); if (name[0] != '_' || name[1] != '_') /* On some erroneous inputs, we can get here with VALUE a LOOKUP_EXPR. In that case, the NAME will be the identifier for "". We must survive this routine in order to issue a sensible error message, so we fall through to the case below. */ goto bad_value; for (i = 0; i < operands; ++i) { tree operand; enum tree_code tc; /* We just outputted either the `E' or the name of the operator. */ numeric_output_need_bar = 0; if (i != 0) /* Skip the leading underscores. */ OB_PUTCP (name + 2); operand = TREE_OPERAND (value, i); tc = TREE_CODE (operand); if (TREE_CODE_CLASS (tc) == 't') /* We can get here with sizeof, e.g.: template void f(A); */ build_mangled_name_for_type (operand); else if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (tc))) build_overload_int (operand, in_template); else build_overload_value (TREE_TYPE (operand), operand, in_template); } } else { /* We don't ever want this output, but it's inconvenient not to be able to build the string. This should cause assembler errors we'll notice. */ static int n; bad_value: sprintf (digit_buffer, " *%d", n++); OB_PUTCP (digit_buffer); } OB_PUTC ('W'); numeric_output_need_bar = 0; return; } my_friendly_assert (TREE_CODE (value) == INTEGER_CST, 243); if (TYPE_PRECISION (TREE_TYPE (value)) == 2 * HOST_BITS_PER_WIDE_INT) { if (TREE_INT_CST_HIGH (value) != (TREE_INT_CST_LOW (value) >> (HOST_BITS_PER_WIDE_INT - 1))) { /* need to print a DImode value in decimal */ dicat (TREE_INT_CST_LOW (value), TREE_INT_CST_HIGH (value)); numeric_output_need_bar = 1; return; } /* else fall through to print in smaller mode */ } /* Wordsize or smaller */ icat (TREE_INT_CST_LOW (value)); numeric_output_need_bar = 1; } /* Output S followed by a representation of the TEMPLATE_PARM_INDEX supplied in INDEX. */ static void build_mangled_template_parm_index (s, index) char* s; tree index; { OB_PUTCP (s); build_underscore_int (TEMPLATE_PARM_IDX (index)); /* We use the LEVEL, not the ORIG_LEVEL, because the mangling is a representation of the function from the point of view of its type. */ build_underscore_int (TEMPLATE_PARM_LEVEL (index)); } /* Mangling for C9X integer types (and Cygnus extensions for 128-bit and other types) is based on the letter "I" followed by the hex representations of the bitsize for the type in question. For encodings that result in larger than two digits, a leading and trailing underscore is added. Thus: int1_t = 001 = I01 int8_t = 008 = I08 int16_t = 010 = I10 int24_t = 018 = I18 int32_t = 020 = I20 int64_t = 040 = I40 int80_t = 050 = I50 int128_t = 080 = I80 int256_t = 100 = I_100_ int512_t = 200 = I_200_ Given an integer in decimal format, mangle according to this scheme. */ #if HOST_BITS_PER_WIDE_INT >= 64 static void build_mangled_C9x_name (bits) int bits; { char mangled[10] = ""; if (bits > 255) sprintf (mangled, "I_%x_", bits); else sprintf (mangled, "I%.2x", bits); OB_PUTCP (mangled); } #endif static void build_overload_value (type, value, in_template) tree type, value; int in_template; { my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (type)) == 't', 0); while (TREE_CODE (value) == NON_LVALUE_EXPR || TREE_CODE (value) == NOP_EXPR) value = TREE_OPERAND (value, 0); if (numeric_output_need_bar) { OB_PUTC ('_'); numeric_output_need_bar = 0; } if (TREE_CODE (value) == TEMPLATE_PARM_INDEX) { build_mangled_template_parm_index ("Y", value); return; } if (TYPE_PTRMEM_P (type)) { if (TREE_CODE (value) != PTRMEM_CST) /* We should have already rejected this pointer to member, since it is not a constant. */ my_friendly_abort (0); /* Get the actual FIELD_DECL. */ value = PTRMEM_CST_MEMBER (value); my_friendly_assert (TREE_CODE (value) == FIELD_DECL, 0); /* Output the name of the field. */ build_overload_identifier (DECL_NAME (value)); return; } switch (TREE_CODE (type)) { case INTEGER_TYPE: case ENUMERAL_TYPE: case BOOLEAN_TYPE: { build_overload_int (value, in_template); return; } case REAL_TYPE: { REAL_VALUE_TYPE val; char *bufp = digit_buffer; pedwarn ("ANSI C++ forbids floating-point template arguments"); my_friendly_assert (TREE_CODE (value) == REAL_CST, 244); val = TREE_REAL_CST (value); if (REAL_VALUE_ISNAN (val)) { sprintf (bufp, "NaN"); } else { if (REAL_VALUE_NEGATIVE (val)) { val = REAL_VALUE_NEGATE (val); *bufp++ = 'm'; } if (REAL_VALUE_ISINF (val)) { sprintf (bufp, "Infinity"); } else { REAL_VALUE_TO_DECIMAL (val, "%.20e", bufp); bufp = (char *) index (bufp, 'e'); if (!bufp) strcat (digit_buffer, "e0"); else { char *p; bufp++; if (*bufp == '-') { *bufp++ = 'm'; } p = bufp; if (*p == '+') p++; while (*p == '0') p++; if (*p == 0) { *bufp++ = '0'; *bufp = 0; } else if (p != bufp) { while (*p) *bufp++ = *p++; *bufp = 0; } } #ifdef NO_DOT_IN_LABEL bufp = (char *) index (bufp, '.'); if (bufp) *bufp = '_'; #endif } } OB_PUTCP (digit_buffer); numeric_output_need_bar = 1; return; } case POINTER_TYPE: if (TREE_CODE (value) == INTEGER_CST) { build_overload_int (value, in_template); return; } else if (TREE_CODE (value) == TEMPLATE_PARM_INDEX) { build_mangled_template_parm_index ("", value); numeric_output_need_bar = 1; return; } value = TREE_OPERAND (value, 0); /* Fall through. */ case REFERENCE_TYPE: if (TREE_CODE (value) == VAR_DECL) { my_friendly_assert (DECL_NAME (value) != 0, 245); build_overload_identifier (DECL_ASSEMBLER_NAME (value)); return; } else if (TREE_CODE (value) == FUNCTION_DECL) { my_friendly_assert (DECL_NAME (value) != 0, 246); build_overload_identifier (DECL_ASSEMBLER_NAME (value)); return; } else if (TREE_CODE (value) == SCOPE_REF) build_overload_scope_ref (value); else my_friendly_abort (71); break; /* not really needed */ case RECORD_TYPE: { tree delta; tree idx; tree pfn; tree delta2; my_friendly_assert (TYPE_PTRMEMFUNC_P (type), 0); /* We'll get a ADDR_EXPR of a SCOPE_REF here if we're mangling, an instantiation of something like: template class C {}; template C x(); We mangle the return type of the function, and that contains template parameters. */ if (TREE_CODE (value) == ADDR_EXPR && TREE_CODE (TREE_OPERAND (value, 0)) == SCOPE_REF) { build_overload_scope_ref (TREE_OPERAND (value, 0)); break; } my_friendly_assert (TREE_CODE (value) == PTRMEM_CST, 0); expand_ptrmemfunc_cst (value, &delta, &idx, &pfn, &delta2); build_overload_int (delta, in_template); OB_PUTC ('_'); build_overload_int (idx, in_template); OB_PUTC ('_'); if (pfn) { numeric_output_need_bar = 0; build_overload_identifier (DECL_ASSEMBLER_NAME (PTRMEM_CST_MEMBER (value))); } else { OB_PUTC ('i'); build_overload_int (delta2, in_template); } } break; default: sorry ("conversion of %s as template parameter", tree_code_name [(int) TREE_CODE (type)]); my_friendly_abort (72); } } /* Add encodings for the declaration of template template parameters. PARMLIST must be a TREE_VEC. */ static void build_template_template_parm_names (parmlist) tree parmlist; { int i, nparms; my_friendly_assert (TREE_CODE (parmlist) == TREE_VEC, 246.5); nparms = TREE_VEC_LENGTH (parmlist); icat (nparms); for (i = 0; i < nparms; i++) { tree parm = TREE_VALUE (TREE_VEC_ELT (parmlist, i)); if (TREE_CODE (parm) == TYPE_DECL) { /* This parameter is a type. */ OB_PUTC ('Z'); } else if (TREE_CODE (parm) == TEMPLATE_DECL) { /* This parameter is a template. */ OB_PUTC ('z'); build_template_template_parm_names (DECL_INNERMOST_TEMPLATE_PARMS (parm)); } else /* It's a PARM_DECL. */ build_mangled_name_for_type (TREE_TYPE (parm)); } } /* Add encodings for the vector of template parameters in PARMLIST, given the vector of arguments to be substituted in ARGLIST. */ static void build_template_parm_names (parmlist, arglist) tree parmlist; tree arglist; { int i, nparms; tree inner_args = innermost_args (arglist); nparms = TREE_VEC_LENGTH (parmlist); icat (nparms); for (i = 0; i < nparms; i++) { tree parm = TREE_VALUE (TREE_VEC_ELT (parmlist, i)); tree arg = TREE_VEC_ELT (inner_args, i); if (TREE_CODE (parm) == TYPE_DECL) { /* This parameter is a type. */ OB_PUTC ('Z'); build_mangled_name_for_type (arg); } else if (TREE_CODE (parm) == TEMPLATE_DECL) { /* This parameter is a template. */ if (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM) /* Output parameter declaration, argument index and level. */ build_mangled_name_for_type (arg); else { /* A TEMPLATE_DECL node, output the parameter declaration and template name */ OB_PUTC ('z'); build_template_template_parm_names (DECL_INNERMOST_TEMPLATE_PARMS (parm)); icat (IDENTIFIER_LENGTH (DECL_NAME (arg))); OB_PUTID (DECL_NAME (arg)); } } else { parm = tsubst (parm, arglist, /*complain=*/1, NULL_TREE); /* It's a PARM_DECL. */ build_mangled_name_for_type (TREE_TYPE (parm)); build_overload_value (TREE_TYPE (parm), arg, uses_template_parms (arglist)); } } } /* Output the representation for NAME, which is either a TYPE_DECL or an IDENTIFIER. */ static void build_overload_identifier (name) tree name; { if (TREE_CODE (name) == TYPE_DECL && CLASS_TYPE_P (TREE_TYPE (name)) && CLASSTYPE_TEMPLATE_INFO (TREE_TYPE (name)) && (PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (TREE_TYPE (name))) || (TREE_CODE (DECL_CONTEXT (CLASSTYPE_TI_TEMPLATE (TREE_TYPE (name)))) == FUNCTION_DECL))) { /* NAME is the TYPE_DECL for a template specialization. */ tree template, parmlist, arglist, tname; template = CLASSTYPE_TI_TEMPLATE (TREE_TYPE (name)); arglist = CLASSTYPE_TI_ARGS (TREE_TYPE (name)); tname = DECL_NAME (template); parmlist = DECL_INNERMOST_TEMPLATE_PARMS (template); OB_PUTC ('t'); icat (IDENTIFIER_LENGTH (tname)); OB_PUTID (tname); build_template_parm_names (parmlist, arglist); } else { if (TREE_CODE (name) == TYPE_DECL) name = DECL_NAME (name); if (numeric_output_need_bar) { OB_PUTC ('_'); numeric_output_need_bar = 0; } icat (IDENTIFIER_LENGTH (name)); OB_PUTID (name); } } /* Given DECL, either a class TYPE, TYPE_DECL or FUNCTION_DECL, produce the mangling for it. Used by build_mangled_name and build_static_name. */ static void build_qualified_name (decl) tree decl; { tree context; int i = 1; if (TREE_CODE_CLASS (TREE_CODE (decl)) == 't') decl = TYPE_NAME (decl); /* If DECL_ASSEMBLER_NAME has been set properly, use it. */ if (TREE_CODE (decl) == TYPE_DECL && DECL_ASSEMBLER_NAME (decl) != DECL_NAME (decl) && !flag_do_squangling) { tree id = DECL_ASSEMBLER_NAME (decl); OB_PUTID (id); if (ISDIGIT (IDENTIFIER_POINTER (id) [IDENTIFIER_LENGTH (id) - 1])) numeric_output_need_bar = 1; return; } context = decl; /* If we can't find a Ktype, do it the hard way. */ if (check_ktype (context, FALSE) == -1) { /* Count type and namespace scopes. */ while (1) { context = CP_DECL_CONTEXT (context); if (context == global_namespace) break; i += 1; if (check_ktype (context, FALSE) != -1) /* Found one! */ break; if (TREE_CODE_CLASS (TREE_CODE (context)) == 't') context = TYPE_NAME (context); } } if (i > 1) { OB_PUTC ('Q'); build_underscore_int (i); numeric_output_need_bar = 0; } build_overload_nested_name (decl); } /* Output the mangled representation for TYPE. If EXTRA_GCODE is non-zero, mangled names for structure/union types are intentionally mangled differently from the method described in the ARM. */ static void build_mangled_name_for_type_with_Gcode (type, extra_Gcode) tree type; int extra_Gcode; { if (TYPE_PTRMEMFUNC_P (type)) type = TYPE_PTRMEMFUNC_FN_TYPE (type); process_modifiers (type); process_overload_item (type, extra_Gcode); } /* Like build_mangled_name_for_type_with_Gcode, but never outputs the `G'. */ static void build_mangled_name_for_type (type) tree type; { build_mangled_name_for_type_with_Gcode (type, 0); } /* Given a list of parameters in PARMTYPES, create an unambiguous overload string. Should distinguish any type that C (or C++) can distinguish. I.e., pointers to functions are treated correctly. Caller must deal with whether a final `e' goes on the end or not. Any default conversions must take place before this function is called. BEGIN and END control initialization and finalization of the obstack where we build the string. */ char * build_overload_name (parmtypes, begin, end) tree parmtypes; int begin, end; { char *ret; start_squangling (); ret = build_mangled_name (parmtypes, begin, end); end_squangling (); return ret ; } /* Output the mangled representation for PARMTYPES. If PARMTYPES is a TREE_LIST, then it is a list of parameter types. Otherwise, PARMTYPES must be a single type. */ static char * build_mangled_name (parmtypes, begin, end) tree parmtypes; int begin, end; { if (begin) OB_INIT (); if (TREE_CODE (parmtypes) != TREE_LIST) /* There is only one type. */ build_mangled_name_for_type (parmtypes); else { /* There are several types in a parameter list. */ int nrepeats = 0; int old_style_repeats = !flag_do_squangling && !nofold && typevec; tree last_type = NULL_TREE; for (; parmtypes && parmtypes != void_list_node; parmtypes = TREE_CHAIN (parmtypes)) { /* We used to call canonical_type_variant here, but that isn't good enough; it doesn't handle pointers to typedef types. So we can't just set TREE_USED to say we've seen a type already; we have to check each of the earlier types with same_type_p. */ tree parmtype = TREE_VALUE (parmtypes); if (old_style_repeats) { /* Every argument gets counted. */ my_friendly_assert (maxtype < typevec_size, 387); typevec[maxtype++] = parmtype; } if (last_type && same_type_p (parmtype, last_type)) { if (flag_do_squangling || (old_style_repeats && is_back_referenceable_type (parmtype))) { /* The next type is the same as this one. Keep track of the repetition, and output the repeat count later. */ nrepeats++; continue; } } else if (nrepeats != 0) { /* Indicate how many times the previous parameter was repeated. */ if (old_style_repeats) flush_repeats (nrepeats, last_type); else issue_nrepeats (nrepeats, last_type); nrepeats = 0; } last_type = parmtype; /* Note that for bug-compatibility with 2.7.2, we can't build up repeats of types other than the most recent one. So we call flush_repeats every round, if we get this far. */ if (old_style_repeats && flush_repeats (0, parmtype)) continue; /* Output the PARMTYPE. */ build_mangled_name_for_type_with_Gcode (parmtype, 1); } /* Output the repeat count for the last parameter, if necessary. */ if (nrepeats != 0) { if (old_style_repeats) flush_repeats (nrepeats, last_type); else issue_nrepeats (nrepeats, last_type); nrepeats = 0; } if (!parmtypes) /* The parameter list ends in an ellipsis. */ OB_PUTC ('e'); } if (end) OB_FINISH (); return (char *)obstack_base (&scratch_obstack); } /* Emit modifiers such as constant, read-only, and volatile. */ static void process_modifiers (parmtype) tree parmtype; { /* Note that here we do not use CP_TYPE_CONST_P and friends because we describe types recursively; we will get the `const' in `const int ()[10]' when processing the `const int' part. */ if (TYPE_READONLY (parmtype)) OB_PUTC ('C'); if (TREE_CODE (parmtype) == INTEGER_TYPE && parmtype != char_type_node && parmtype != wchar_type_node && (TYPE_MAIN_VARIANT (parmtype) == unsigned_type (TYPE_MAIN_VARIANT (parmtype))) && ! TYPE_FOR_JAVA (parmtype)) OB_PUTC ('U'); if (TYPE_VOLATILE (parmtype)) OB_PUTC ('V'); /* It would be better to use `R' for `restrict', but that's already used for reference types. And `r' is used for `long double'. */ if (TYPE_RESTRICT (parmtype)) OB_PUTC ('u'); } /* Check to see if TYPE has been entered into the Bcode typelist. If so, return 1 and emit a backreference to TYPE. Otherwise, add TYPE to the list of back-referenceable types and return 0. */ static int check_btype (type) tree type; { int x; if (btypelist == NULL) return 0; if (!is_back_referenceable_type (type)) return 0; for (x = 0; x < maxbtype; x++) if (same_type_p (type, btypelist[x])) { OB_PUTC ('B'); icat (x); if (x > 9) OB_PUTC ('_'); return 1 ; } if (maxbsize <= maxbtype) { /* Enlarge the table. */ maxbsize = maxbsize * 3 / 2; btypelist = (tree *)xrealloc (btypelist, sizeof (tree) * maxbsize); } /* Register the TYPE. */ btypelist[maxbtype++] = type; return 0; } /* Emit the correct code for various node types. */ static void process_overload_item (parmtype, extra_Gcode) tree parmtype; int extra_Gcode; { numeric_output_need_bar = 0; /* Our caller should have already handed any qualifiers, so pull out the TYPE_MAIN_VARIANT to avoid typedef confusion. Except we can't do that for arrays, because they are transparent to qualifiers. Sigh. */ if (TREE_CODE (parmtype) == ARRAY_TYPE) parmtype = canonical_type_variant (parmtype); else parmtype = TYPE_MAIN_VARIANT (parmtype); /* These tree types are considered modifiers for B code squangling, and therefore should not get entries in the Btypelist. They are, however, repeatable types. */ switch (TREE_CODE (parmtype)) { case REFERENCE_TYPE: OB_PUTC ('R'); goto more; case ARRAY_TYPE: #if PARM_CAN_BE_ARRAY_TYPE { OB_PUTC ('A'); if (TYPE_DOMAIN (parmtype) == NULL_TREE) OB_PUTC ('_'); else { tree length = array_type_nelts (parmtype); if (TREE_CODE (length) != INTEGER_CST || flag_do_squangling) { length = fold (build (PLUS_EXPR, TREE_TYPE (length), length, integer_one_node)); STRIP_NOPS (length); } build_overload_value (sizetype, length, 1); } if (numeric_output_need_bar && ! flag_do_squangling) OB_PUTC ('_'); goto more; } #else OB_PUTC ('P'); goto more; #endif case POINTER_TYPE: + /* Even though the vlist_type_node is PPPFe (i.e. `int + (***)(...)'), it is different from the any other occurence of + the pointer type, because the underlying function type is + different. */ + if (parmtype == vlist_type_node) + { + OB_PUTS (VLIST_TYPE_NAME); + return; + } OB_PUTC ('P'); more: build_mangled_name_for_type (TREE_TYPE (parmtype)); return; break; default: break; } if (flag_do_squangling && check_btype (parmtype)) /* If PARMTYPE is already in the list of back-referenceable types, then check_btype will output the appropriate reference, and there's nothing more to do. */ return; switch (TREE_CODE (parmtype)) { case OFFSET_TYPE: OB_PUTC ('O'); build_mangled_name_for_type (TYPE_OFFSET_BASETYPE (parmtype)); OB_PUTC ('_'); build_mangled_name_for_type (TREE_TYPE (parmtype)); break; case FUNCTION_TYPE: case METHOD_TYPE: { tree parms = TYPE_ARG_TYPES (parmtype); /* Rather than implementing a reentrant TYPEVEC, we turn off repeat codes here, unless we're squangling. Squangling doesn't make use of the TYPEVEC, so there's no reentrancy problem. */ int old_nofold = nofold; if (!flag_do_squangling) nofold = 1; if (TREE_CODE (parmtype) == METHOD_TYPE) { /* Mark this as a method. */ OB_PUTC ('M'); /* Output the class of which this method is a member. */ build_mangled_name_for_type (TYPE_METHOD_BASETYPE (parmtype)); /* Output any qualifiers for the `this' parameter. */ process_modifiers (TREE_TYPE (TREE_VALUE (parms))); } /* Output the parameter types. */ OB_PUTC ('F'); if (parms == NULL_TREE) OB_PUTC ('e'); else if (parms == void_list_node) OB_PUTC ('v'); else build_mangled_name (parms, 0, 0); /* Output the return type. */ OB_PUTC ('_'); build_mangled_name_for_type (TREE_TYPE (parmtype)); nofold = old_nofold; break; } case INTEGER_TYPE: if (parmtype == integer_type_node || parmtype == unsigned_type_node || parmtype == java_int_type_node) OB_PUTC ('i'); else if (parmtype == long_integer_type_node || parmtype == long_unsigned_type_node) OB_PUTC ('l'); else if (parmtype == short_integer_type_node || parmtype == short_unsigned_type_node || parmtype == java_short_type_node) OB_PUTC ('s'); else if (parmtype == signed_char_type_node) { OB_PUTC ('S'); OB_PUTC ('c'); } else if (parmtype == char_type_node || parmtype == unsigned_char_type_node || parmtype == java_byte_type_node) OB_PUTC ('c'); else if (parmtype == wchar_type_node || parmtype == java_char_type_node) OB_PUTC ('w'); else if (parmtype == long_long_integer_type_node || parmtype == long_long_unsigned_type_node || parmtype == java_long_type_node) OB_PUTC ('x'); else if (parmtype == java_boolean_type_node) OB_PUTC ('b'); #if HOST_BITS_PER_WIDE_INT >= 64 else if (parmtype == intTI_type_node || parmtype == unsigned_intTI_type_node) { /* Should just check a flag here instead of specific *_type_nodes, because all C9x types could use this. */ int bits = TREE_INT_CST_LOW (TYPE_SIZE (parmtype)); build_mangled_C9x_name (bits); } #endif else my_friendly_abort (73); break; case BOOLEAN_TYPE: OB_PUTC ('b'); break; case REAL_TYPE: if (parmtype == long_double_type_node) OB_PUTC ('r'); else if (parmtype == double_type_node || parmtype == java_double_type_node) OB_PUTC ('d'); else if (parmtype == float_type_node || parmtype == java_float_type_node) OB_PUTC ('f'); else my_friendly_abort (74); break; case COMPLEX_TYPE: OB_PUTC ('J'); build_mangled_name_for_type (TREE_TYPE (parmtype)); break; case VOID_TYPE: OB_PUTC ('v'); break; case ERROR_MARK: /* not right, but nothing is anyway */ break; /* have to do these */ case UNION_TYPE: case RECORD_TYPE: { if (extra_Gcode) OB_PUTC ('G'); /* make it look incompatible with AT&T */ /* drop through into next case */ } case ENUMERAL_TYPE: { tree name = TYPE_NAME (parmtype); my_friendly_assert (TREE_CODE (name) == TYPE_DECL, 248); build_qualified_name (name); break; } case UNKNOWN_TYPE: /* This will take some work. */ OB_PUTC ('?'); break; case TEMPLATE_TEMPLATE_PARM: /* Find and output the original template parameter declaration. */ if (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (parmtype)) { build_mangled_template_parm_index ("tzX", TEMPLATE_TYPE_PARM_INDEX (parmtype)); build_template_parm_names (DECL_INNERMOST_TEMPLATE_PARMS (TYPE_TI_TEMPLATE (parmtype)), TYPE_TI_ARGS (parmtype)); } else { build_mangled_template_parm_index ("ZzX", TEMPLATE_TYPE_PARM_INDEX (parmtype)); build_template_template_parm_names (DECL_INNERMOST_TEMPLATE_PARMS (TYPE_STUB_DECL (parmtype))); } break; case TEMPLATE_TYPE_PARM: build_mangled_template_parm_index ("X", TEMPLATE_TYPE_PARM_INDEX (parmtype)); break; case TYPENAME_TYPE: /* When mangling the type of a function template whose declaration looks like: template void foo(typename T::U) we have to mangle these. */ build_qualified_name (parmtype); break; default: my_friendly_abort (75); } } /* Produce the mangling for a variable named NAME in CONTEXT, which can be either a class TYPE or a FUNCTION_DECL. */ tree build_static_name (context, name) tree context, name; { OB_INIT (); numeric_output_need_bar = 0; start_squangling (); #ifdef JOINER OB_PUTC ('_'); build_qualified_name (context); OB_PUTC (JOINER); #else OB_PUTS ("__static_"); build_qualified_name (context); OB_PUTC ('_'); #endif OB_PUTID (name); OB_FINISH (); end_squangling (); return get_identifier ((char *)obstack_base (&scratch_obstack)); } /* FOR_METHOD should be 1 if the declaration in question is for a member of a class (including a static member) and 2 if the declaration is for a constructor. */ tree build_decl_overload_real (dname, parms, ret_type, tparms, targs, for_method) tree dname; tree parms; tree ret_type; tree tparms; tree targs; int for_method; { char *name = IDENTIFIER_POINTER (dname); /* member operators new and delete look like methods at this point. */ if (! for_method && parms != NULL_TREE && TREE_CODE (parms) == TREE_LIST && TREE_CHAIN (parms) == void_list_node) { if (dname == ansi_opname[(int) DELETE_EXPR]) return get_identifier ("__builtin_delete"); else if (dname == ansi_opname[(int) VEC_DELETE_EXPR]) return get_identifier ("__builtin_vec_delete"); if (dname == ansi_opname[(int) NEW_EXPR]) return get_identifier ("__builtin_new"); else if (dname == ansi_opname[(int) VEC_NEW_EXPR]) return get_identifier ("__builtin_vec_new"); } start_squangling (); OB_INIT (); if (for_method != 2) OB_PUTCP (name); /* Otherwise, we can divine that this is a constructor, and figure out its name without any extra encoding. */ OB_PUTC2 ('_', '_'); numeric_output_need_bar = 0; if (tparms) { OB_PUTC ('H'); build_template_parm_names (tparms, targs); OB_PUTC ('_'); } else if (!for_method && current_namespace == global_namespace) /* XXX this works only if we call this in the same namespace as the declaration. Unfortunately, we don't have the _DECL, only its name */ OB_PUTC ('F'); if (!for_method && current_namespace != global_namespace) /* qualify with namespace */ build_qualified_name (current_namespace); if (parms == NULL_TREE) OB_PUTC ('e'); else if (parms == void_list_node) OB_PUTC ('v'); else { if (!flag_do_squangling) { /* Allocate typevec array. */ maxtype = 0; typevec_size = list_length (parms); if (!for_method && current_namespace != global_namespace) /* The namespace of a global function needs one slot. */ typevec_size++; typevec = (tree *)alloca (typevec_size * sizeof (tree)); } nofold = 0; if (for_method) { tree this_type = TREE_VALUE (parms); if (TREE_CODE (this_type) == RECORD_TYPE) /* a signature pointer */ this_type = SIGNATURE_TYPE (this_type); else this_type = TREE_TYPE (this_type); build_mangled_name_for_type (this_type); if (!flag_do_squangling) { my_friendly_assert (maxtype < typevec_size, 387); typevec[maxtype++] = this_type; } if (TREE_CHAIN (parms)) build_mangled_name (TREE_CHAIN (parms), 0, 0); else OB_PUTC ('e'); } else { /* the namespace qualifier for a global function will count as type */ if (current_namespace != global_namespace && !flag_do_squangling) { my_friendly_assert (maxtype < typevec_size, 387); typevec[maxtype++] = current_namespace; } build_mangled_name (parms, 0, 0); } if (!flag_do_squangling) /* Deallocate typevec array. */ typevec = NULL; } if (ret_type != NULL_TREE && for_method != 2) { /* Add the return type. */ OB_PUTC ('_'); build_mangled_name_for_type (ret_type); } OB_FINISH (); end_squangling (); { tree n = get_identifier (obstack_base (&scratch_obstack)); if (IDENTIFIER_OPNAME_P (dname)) IDENTIFIER_OPNAME_P (n) = 1; return n; } } /* Change the name of a function definition so that it may be overloaded. NAME is the name of the function to overload, PARMS is the parameter list (which determines what name the final function obtains). FOR_METHOD is 1 if this overload is being performed for a method, rather than a function type. It is 2 if this overload is being performed for a constructor. */ tree build_decl_overload (dname, parms, for_method) tree dname; tree parms; int for_method; { return build_decl_overload_real (dname, parms, NULL_TREE, NULL_TREE, NULL_TREE, for_method); } /* Set the mangled name (DECL_ASSEMBLER_NAME) for DECL. */ void set_mangled_name_for_decl (decl) tree decl; { tree parm_types; if (processing_template_decl) /* There's no need to mangle the name of a template function. */ return; parm_types = TYPE_ARG_TYPES (TREE_TYPE (decl)); if (DECL_STATIC_FUNCTION_P (decl)) parm_types = hash_tree_chain (build_pointer_type (DECL_CLASS_CONTEXT (decl)), parm_types); else /* The only member functions whose type is a FUNCTION_TYPE, rather than a METHOD_TYPE, should be static members. */ my_friendly_assert (!DECL_CONTEXT (decl) || !IS_AGGR_TYPE_CODE (TREE_CODE (DECL_CONTEXT (decl))) || TREE_CODE (TREE_TYPE (decl)) != FUNCTION_TYPE, 0); DECL_ASSEMBLER_NAME (decl) = build_decl_overload (DECL_NAME (decl), parm_types, DECL_FUNCTION_MEMBER_P (decl) + DECL_CONSTRUCTOR_P (decl)); } /* Build an overload name for the type expression TYPE. */ tree build_typename_overload (type) tree type; { tree id; OB_INIT (); OB_PUTID (ansi_opname[(int) TYPE_EXPR]); nofold = 1; start_squangling (); build_mangled_name (type, 0, 1); id = get_identifier (obstack_base (&scratch_obstack)); IDENTIFIER_OPNAME_P (id) = 1; #if 0 IDENTIFIER_GLOBAL_VALUE (id) = TYPE_MAIN_DECL (type); #endif TREE_TYPE (id) = type; end_squangling (); return id; } tree build_overload_with_type (name, type) tree name, type; { OB_INIT (); OB_PUTID (name); nofold = 1; start_squangling (); build_mangled_name (type, 0, 1); end_squangling (); return get_identifier (obstack_base (&scratch_obstack)); } tree get_id_2 (name, name2) char *name; tree name2; { OB_INIT (); OB_PUTCP (name); OB_PUTID (name2); OB_FINISH (); return get_identifier (obstack_base (&scratch_obstack)); } -/* Returns a DECL_ASSEMBLER_NAME for the destructor of type TYPE. */ +/* Print a binfo path T, starting with the most derived class. If + OMIT_LAST is set, drop and return the most derived class. */ +static tree +build_base_path (t, omit_last) + tree t; + int omit_last; +{ + tree ret = NULL_TREE; + if (BINFO_INHERITANCE_CHAIN (t)) + ret = build_base_path (BINFO_INHERITANCE_CHAIN (t), omit_last); + else if (omit_last) + return t; + process_overload_item (BINFO_TYPE (t), 0); + return ret; +} + +/* Return a mangled name for a vlist vtable, using the path of both + BASE and VBASE. */ + tree -build_destructor_name (type) +get_vlist_vtable_id (base, vbase) + tree base, vbase; +{ + tree last; + OB_INIT (); + OB_PUTS (VCTABLE_NAME); + build_base_path (base, 0); + OB_PUTC ('_'); + /* Since the base path should end where the vbase path starts, we + can omit the most-derived class in the vbase path. Check below + that this really happens. */ + last = build_base_path (vbase, 1); + my_friendly_assert (BINFO_TYPE (last) == BINFO_TYPE (base), 990402); + OB_FINISH (); + return get_identifier (obstack_base (&scratch_obstack)); +} + +/* Returns a DECL_ASSEMBLER_NAME for the destructor of type TYPE. If + HAS_VLIST is set, also add the vlist argument. */ + +tree +build_destructor_name (type, has_vlist) tree type; + int has_vlist; { - return build_overload_with_type (get_identifier (DESTRUCTOR_DECL_PREFIX), - type); + OB_INIT (); + OB_PUTS (DESTRUCTOR_DECL_PREFIX); + start_squangling (); + build_mangled_name_for_type (type); + /* If we need backwards compatibility, we can get aways by + not linking type-safely, as the dtor will check whether + the argument was provided. */ + if (has_vlist && !flag_vtable_thunks_compat) + OB_PUTS (VLIST_TYPE_NAME); + OB_FINISH (); + end_squangling (); + return get_identifier (obstack_base (&scratch_obstack)); } /* Given a tree_code CODE, and some arguments (at least one), attempt to use an overloaded operator on the arguments. For unary operators, only the first argument need be checked. For binary operators, both arguments may need to be checked. Member functions can convert class references to class pointers, for one-level deep indirection. More than that is not supported. Operators [](), ()(), and ->() must be member functions. We call function call building calls with LOOKUP_COMPLAIN if they are our only hope. This is true when we see a vanilla operator applied to something of aggregate type. If this fails, we are free to return `error_mark_node', because we will have reported the error. Operators NEW and DELETE overload in funny ways: operator new takes a single `size' parameter, and operator delete takes a pointer to the storage being deleted. When overloading these operators, success is assumed. If there is a failure, report an error message and return `error_mark_node'. */ /* NOSTRICT */ tree build_opfncall (code, flags, xarg1, xarg2, arg3) enum tree_code code; int flags; tree xarg1, xarg2, arg3; { return build_new_op (code, flags, xarg1, xarg2, arg3); } /* This function takes an identifier, ID, and attempts to figure out what it means. There are a number of possible scenarios, presented in increasing order of hair: 1) not in a class's scope 2) in class's scope, member name of the class's method 3) in class's scope, but not a member name of the class 4) in class's scope, member name of a class's variable NAME is $1 from the bison rule. It is an IDENTIFIER_NODE. VALUE is $$ from the bison rule. It is the value returned by lookup_name ($1) As a last ditch, try to look up the name as a label and return that address. Values which are declared as being of REFERENCE_TYPE are automatically dereferenced here (as a hack to make the compiler faster). */ tree hack_identifier (value, name) tree value, name; { tree type; if (value == error_mark_node) { if (current_class_name) { tree fields = lookup_fnfields (TYPE_BINFO (current_class_type), name, 1); if (fields == error_mark_node) return error_mark_node; if (fields) { tree fndecl; fndecl = TREE_VALUE (fields); my_friendly_assert (TREE_CODE (fndecl) == FUNCTION_DECL, 251); /* I could not trigger this code. MvL */ my_friendly_abort (980325); #ifdef DEAD if (DECL_CHAIN (fndecl) == NULL_TREE) { warning ("methods cannot be converted to function pointers"); return fndecl; } else { error ("ambiguous request for method pointer `%s'", IDENTIFIER_POINTER (name)); return error_mark_node; } #endif } } if (flag_labels_ok && IDENTIFIER_LABEL_VALUE (name)) { return IDENTIFIER_LABEL_VALUE (name); } return error_mark_node; } type = TREE_TYPE (value); if (TREE_CODE (value) == FIELD_DECL) { if (current_class_ptr == NULL_TREE) { if (current_function_decl && DECL_STATIC_FUNCTION_P (current_function_decl)) cp_error ("invalid use of member `%D' in static member function", value); else /* We can get here when processing a bad default argument, like: struct S { int a; void f(int i = a); } */ cp_error ("invalid use of member `%D'", value); return error_mark_node; } TREE_USED (current_class_ptr) = 1; /* Mark so that if we are in a constructor, and then find that this field was initialized by a base initializer, we can emit an error message. */ TREE_USED (value) = 1; value = build_component_ref (current_class_ref, name, NULL_TREE, 1); } else if ((TREE_CODE (value) == FUNCTION_DECL && DECL_FUNCTION_MEMBER_P (value)) || (TREE_CODE (value) == OVERLOAD && DECL_FUNCTION_MEMBER_P (OVL_CURRENT (value)))) { tree decl; if (TREE_CODE (value) == OVERLOAD) value = OVL_CURRENT (value); if (IS_SIGNATURE (DECL_CLASS_CONTEXT (value))) return value; decl = maybe_dummy_object (DECL_CLASS_CONTEXT (value), 0); value = build_component_ref (decl, name, NULL_TREE, 1); } else if (really_overloaded_fn (value)) ; else if (TREE_CODE (value) == OVERLOAD) /* not really overloaded function */ mark_used (OVL_FUNCTION (value)); else if (TREE_CODE (value) == TREE_LIST) { /* Ambiguous reference to base members, possibly other cases?. */ tree t = value; while (t && TREE_CODE (t) == TREE_LIST) { mark_used (TREE_VALUE (t)); t = TREE_CHAIN (t); } } else if (TREE_CODE (value) == NAMESPACE_DECL) { cp_error ("use of namespace `%D' as expression", value); return error_mark_node; } else if (DECL_CLASS_TEMPLATE_P (value)) { cp_error ("use of class template `%T' as expression", value); return error_mark_node; } else mark_used (value); if (TREE_CODE (value) == VAR_DECL || TREE_CODE (value) == PARM_DECL || TREE_CODE (value) == RESULT_DECL) { tree context = decl_function_context (value); if (context != NULL_TREE && context != current_function_decl && ! TREE_STATIC (value)) { cp_error ("use of %s from containing function", (TREE_CODE (value) == VAR_DECL ? "`auto' variable" : "parameter")); cp_error_at (" `%#D' declared here", value); value = error_mark_node; } } if (TREE_CODE_CLASS (TREE_CODE (value)) == 'd' && DECL_NONLOCAL (value)) { if (DECL_LANG_SPECIFIC (value) && DECL_CLASS_CONTEXT (value) != current_class_type) { tree path; register tree context = (TREE_CODE (value) == FUNCTION_DECL && DECL_VIRTUAL_P (value)) ? DECL_CLASS_CONTEXT (value) : DECL_CONTEXT (value); get_base_distance (context, current_class_type, 0, &path); if (path && !enforce_access (current_class_type, value)) return error_mark_node; } } else if (TREE_CODE (value) == TREE_LIST && TREE_TYPE (value) == error_mark_node) { error ("request for member `%s' is ambiguous in multiple inheritance lattice", IDENTIFIER_POINTER (name)); print_candidates (value); return error_mark_node; } if (! processing_template_decl) value = convert_from_reference (value); return value; } tree make_thunk (function, delta) tree function; int delta; { tree thunk_id; tree thunk; tree func_decl; if (TREE_CODE (function) != ADDR_EXPR) abort (); func_decl = TREE_OPERAND (function, 0); if (TREE_CODE (func_decl) != FUNCTION_DECL) abort (); OB_INIT (); OB_PUTS ("__thunk_"); if (delta > 0) { OB_PUTC ('n'); icat (delta); } else icat (-delta); OB_PUTC ('_'); OB_PUTID (DECL_ASSEMBLER_NAME (func_decl)); OB_FINISH (); thunk_id = get_identifier (obstack_base (&scratch_obstack)); thunk = IDENTIFIER_GLOBAL_VALUE (thunk_id); if (thunk && TREE_CODE (thunk) != THUNK_DECL) { cp_error ("implementation-reserved name `%D' used", thunk_id); thunk = NULL_TREE; SET_IDENTIFIER_GLOBAL_VALUE (thunk_id, thunk); } if (thunk == NULL_TREE) { thunk = build_decl (FUNCTION_DECL, thunk_id, TREE_TYPE (func_decl)); TREE_READONLY (thunk) = TREE_READONLY (func_decl); TREE_THIS_VOLATILE (thunk) = TREE_THIS_VOLATILE (func_decl); comdat_linkage (thunk); TREE_SET_CODE (thunk, THUNK_DECL); DECL_INITIAL (thunk) = function; THUNK_DELTA (thunk) = delta; DECL_EXTERNAL (thunk) = 1; DECL_ARTIFICIAL (thunk) = 1; /* So that finish_file can write out any thunks that need to be: */ pushdecl_top_level (thunk); } return thunk; } /* Emit the definition of a C++ multiple inheritance vtable thunk. */ void emit_thunk (thunk_fndecl) tree thunk_fndecl; { tree function = TREE_OPERAND (DECL_INITIAL (thunk_fndecl), 0); int delta = THUNK_DELTA (thunk_fndecl); if (TREE_ASM_WRITTEN (thunk_fndecl)) return; TREE_ASM_WRITTEN (thunk_fndecl) = 1; TREE_ADDRESSABLE (function) = 1; mark_used (function); if (current_function_decl) abort (); TREE_SET_CODE (thunk_fndecl, FUNCTION_DECL); { #ifdef ASM_OUTPUT_MI_THUNK char *fnname; current_function_decl = thunk_fndecl; /* Make sure we build up its RTL before we go onto the temporary obstack. */ make_function_rtl (thunk_fndecl); temporary_allocation (); DECL_RESULT (thunk_fndecl) = build_decl (RESULT_DECL, 0, integer_type_node); fnname = XSTR (XEXP (DECL_RTL (thunk_fndecl), 0), 0); init_function_start (thunk_fndecl, input_filename, lineno); current_function_is_thunk = 1; assemble_start_function (thunk_fndecl, fnname); ASM_OUTPUT_MI_THUNK (asm_out_file, thunk_fndecl, delta, function); assemble_end_function (thunk_fndecl, fnname); permanent_allocation (1); current_function_decl = 0; #else /* ASM_OUTPUT_MI_THUNK */ /* If we don't have the necessary macro for efficient thunks, generate a thunk function that just makes a call to the real function. Unfortunately, this doesn't work for varargs. */ tree a, t; if (varargs_function_p (function)) cp_error ("generic thunk code fails for method `%#D' which uses `...'", function); /* Set up clone argument trees for the thunk. */ t = NULL_TREE; for (a = DECL_ARGUMENTS (function); a; a = TREE_CHAIN (a)) { tree x = copy_node (a); TREE_CHAIN (x) = t; DECL_CONTEXT (x) = thunk_fndecl; t = x; } a = nreverse (t); DECL_ARGUMENTS (thunk_fndecl) = a; DECL_RESULT (thunk_fndecl) = NULL_TREE; DECL_LANG_SPECIFIC (thunk_fndecl) = DECL_LANG_SPECIFIC (function); copy_lang_decl (thunk_fndecl); DECL_INTERFACE_KNOWN (thunk_fndecl) = 1; DECL_NOT_REALLY_EXTERN (thunk_fndecl) = 1; start_function (NULL_TREE, thunk_fndecl, NULL_TREE, 1); store_parm_decls (); current_function_is_thunk = 1; /* Build up the call to the real function. */ t = build_int_2 (delta, -1 * (delta < 0)); TREE_TYPE (t) = signed_type (sizetype); t = fold (build (PLUS_EXPR, TREE_TYPE (a), a, t)); t = expr_tree_cons (NULL_TREE, t, NULL_TREE); for (a = TREE_CHAIN (a); a; a = TREE_CHAIN (a)) t = expr_tree_cons (NULL_TREE, a, t); t = nreverse (t); t = build_call (function, TREE_TYPE (TREE_TYPE (function)), t); c_expand_return (t); finish_function (lineno, 0, 0); /* Don't let the backend defer this function. */ if (DECL_DEFER_OUTPUT (thunk_fndecl)) { output_inline_function (thunk_fndecl); permanent_allocation (1); } #endif /* ASM_OUTPUT_MI_THUNK */ } TREE_SET_CODE (thunk_fndecl, THUNK_DECL); } +void +make_vlist_ctor_wrapper (fn) + tree fn; +{ + tree fntype, decl; + tree arg_types, parms, parm, basetype, pbasetype; + tree t, ctors; + + arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn)); + pbasetype = TREE_VALUE (arg_types); + basetype = TREE_TYPE (pbasetype); + parms = DECL_ARGUMENTS (fn); + + /* Skip this, __in_chrg, and _vlist */ + arg_types = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arg_types))); + + + /* Add __in_charge. */ + arg_types = hash_tree_chain (integer_type_node, arg_types); + + /* Don't add this to arg_types, as build_cplus_method_type does so. */ + + fntype = build_cplus_method_type (basetype, TREE_TYPE (TREE_TYPE (fn)), + arg_types); + + decl = build_lang_decl (FUNCTION_DECL, DECL_NAME (fn), fntype); + DECL_LANG_SPECIFIC (decl)->decl_flags = DECL_LANG_SPECIFIC (fn)->decl_flags; + DECL_EXTERNAL (decl) = 0; + TREE_PUBLIC (decl) = 1; + DECL_ARTIFICIAL (decl) = 1; + DECL_CONSTRUCTOR_P (decl) = 1; + DECL_CONSTRUCTOR_FOR_VBASE (decl) = CONSTRUCTOR_FOR_VBASE; + /* Claim that this is never a template instantiation. */ + DECL_USE_TEMPLATE (decl) = 0; + DECL_TEMPLATE_INFO (decl) = NULL_TREE; + + /* Set up clone argument trees for the thunk. */ + parms = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (parms))); + /* Add this */ + t = build_decl (PARM_DECL, this_identifier, pbasetype); + SET_DECL_ARTIFICIAL (t); + DECL_ARG_TYPE (t) = pbasetype; + DECL_REGISTER (t) = 1; + /* Add __in_charge. */ + parm = build_decl (PARM_DECL, in_charge_identifier, integer_type_node); + SET_DECL_ARTIFICIAL (parm); + DECL_ARG_TYPE (parm) = integer_type_node; + TREE_CHAIN (parm) = t; + t = parm; + + while (parms) + { + tree x = copy_node (parms); + TREE_CHAIN (x) = t; + DECL_CONTEXT (x) = decl; + t = x; + parms = TREE_CHAIN (parms); + } + parms = nreverse (t); + DECL_ARGUMENTS (decl) = parms; + + DECL_ASSEMBLER_NAME (decl) + = build_decl_overload (DECL_NAME (decl), + TYPE_ARG_TYPES (TREE_TYPE (decl)), 2); + + ctors = CLASSTYPE_METHOD_VEC (basetype); + if (ctors) + ctors = TREE_VEC_ELT (ctors, 0); + for ( ; ctors; ctors = OVL_NEXT (ctors)) + if (DECL_ASSEMBLER_NAME (OVL_CURRENT (ctors)) + == DECL_ASSEMBLER_NAME (decl)) + break; + + if (!ctors) + { + add_method (basetype, 0, decl); + cp_finish_decl (decl, NULL_TREE, NULL_TREE, 0, 0); + } + else + decl = OVL_CURRENT (ctors); + + /* Remember the original function. */ + DECL_VLIST_CTOR_WRAPPED (decl) = fn; + + /* When fn is declared, DECL_INITIAL is null. When it is defined, + DECL_INITIAL will be error_mark_node. */ + if (DECL_INITIAL (fn) == error_mark_node) + { + /* Record that the ctor is being defined, so we also emit the + wrapper later. */ + TREE_USED (decl) = 1; + DECL_NOT_REALLY_EXTERN (decl) = 1; + DECL_INITIAL (decl) = NULL_TREE; + mark_inline_for_output (decl); + } +} + +static void +emit_vlist_ctor_wrapper (decl) + tree decl; +{ + tree t, parms, fn; + + current_function_is_thunk = 1; + + parms = DECL_ARGUMENTS (decl); + fn = DECL_VLIST_CTOR_WRAPPED (decl); + mark_used (fn); + + /* Build up the call to the real function. */ + t = NULL_TREE; + /* Push this, __in_charge. */ + t = expr_tree_cons (NULL_TREE, parms, t); + parms = TREE_CHAIN (parms); + t = expr_tree_cons (NULL_TREE, parms, t); + parms = TREE_CHAIN (parms); + /* Push 0 as __vlist. */ + t = expr_tree_cons (NULL_TREE, vlist_zero_node, t); + /* Push rest of arguments. */ + while (parms) + { + t = expr_tree_cons (NULL_TREE, parms, t); + parms = TREE_CHAIN (parms); + } + t = nreverse (t); + t = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), t); + expand_expr_stmt (t); +} + + /* Code for synthesizing methods which have default semantics defined. */ /* For the anonymous union in TYPE, return the member that is at least as large as the rest of the members, so we can copy it. */ static tree largest_union_member (type) tree type; { tree f, type_size = TYPE_SIZE (type); for (f = TYPE_FIELDS (type); f; f = TREE_CHAIN (f)) if (simple_cst_equal (DECL_SIZE (f), type_size) == 1) return f; /* We should always find one. */ my_friendly_abort (323); return NULL_TREE; } /* Generate code for default X(X&) constructor. */ static void do_build_copy_constructor (fndecl) tree fndecl; { tree parm = TREE_CHAIN (DECL_ARGUMENTS (fndecl)); tree t; clear_last_expr (); push_momentary (); if (TYPE_USES_VIRTUAL_BASECLASSES (current_class_type)) parm = TREE_CHAIN (parm); + if (TYPE_USES_PVBASES (current_class_type)) + parm = TREE_CHAIN (parm); parm = convert_from_reference (parm); if (TYPE_HAS_TRIVIAL_INIT_REF (current_class_type) && is_empty_class (current_class_type)) /* Don't copy the padding byte; it might not have been allocated if *this is a base subobject. */; else if (TYPE_HAS_TRIVIAL_INIT_REF (current_class_type)) { t = build (INIT_EXPR, void_type_node, current_class_ref, parm); TREE_SIDE_EFFECTS (t) = 1; cplus_expand_expr_stmt (t); } else { tree fields = TYPE_FIELDS (current_class_type); int n_bases = CLASSTYPE_N_BASECLASSES (current_class_type); tree binfos = TYPE_BINFO_BASETYPES (current_class_type); int i; /* Initialize all the base-classes. */ for (t = CLASSTYPE_VBASECLASSES (current_class_type); t; t = TREE_CHAIN (t)) current_base_init_list = tree_cons (BINFO_TYPE (t), parm, current_base_init_list); for (i = 0; i < n_bases; ++i) { t = TREE_VEC_ELT (binfos, i); if (TREE_VIA_VIRTUAL (t)) continue; current_base_init_list = tree_cons (BINFO_TYPE (t), parm, current_base_init_list); } for (; fields; fields = TREE_CHAIN (fields)) { tree init, t; tree field = fields; if (TREE_CODE (field) != FIELD_DECL) continue; init = parm; if (DECL_NAME (field)) { if (VFIELD_NAME_P (DECL_NAME (field))) continue; if (VBASE_NAME_P (DECL_NAME (field))) continue; /* True for duplicate members. */ if (IDENTIFIER_CLASS_VALUE (DECL_NAME (field)) != field) continue; } else if ((t = TREE_TYPE (field)) != NULL_TREE && ANON_UNION_TYPE_P (t) && TYPE_FIELDS (t) != NULL_TREE) { do { init = build (COMPONENT_REF, t, init, field); field = largest_union_member (t); } while ((t = TREE_TYPE (field)) != NULL_TREE && ANON_UNION_TYPE_P (t) && TYPE_FIELDS (t) != NULL_TREE); } else continue; init = build (COMPONENT_REF, TREE_TYPE (field), init, field); init = build_tree_list (NULL_TREE, init); current_member_init_list = tree_cons (DECL_NAME (field), init, current_member_init_list); } current_member_init_list = nreverse (current_member_init_list); current_base_init_list = nreverse (current_base_init_list); setup_vtbl_ptr (); } pop_momentary (); } static void do_build_assign_ref (fndecl) tree fndecl; { tree parm = TREE_CHAIN (DECL_ARGUMENTS (fndecl)); clear_last_expr (); push_momentary (); parm = convert_from_reference (parm); if (TYPE_HAS_TRIVIAL_ASSIGN_REF (current_class_type) && is_empty_class (current_class_type)) /* Don't copy the padding byte; it might not have been allocated if *this is a base subobject. */; else if (TYPE_HAS_TRIVIAL_ASSIGN_REF (current_class_type)) { tree t = build (MODIFY_EXPR, void_type_node, current_class_ref, parm); TREE_SIDE_EFFECTS (t) = 1; cplus_expand_expr_stmt (t); } else { tree fields = TYPE_FIELDS (current_class_type); int n_bases = CLASSTYPE_N_BASECLASSES (current_class_type); tree binfos = TYPE_BINFO_BASETYPES (current_class_type); int i; for (i = 0; i < n_bases; ++i) { tree basetype = BINFO_TYPE (TREE_VEC_ELT (binfos, i)); tree p = convert_to_reference (build_reference_type (basetype), parm, CONV_IMPLICIT|CONV_CONST, LOOKUP_COMPLAIN, NULL_TREE); p = convert_from_reference (p); p = build_member_call (basetype, ansi_opname [MODIFY_EXPR], build_expr_list (NULL_TREE, p)); expand_expr_stmt (p); } for (; fields; fields = TREE_CHAIN (fields)) { tree comp, init, t; tree field = fields; if (TREE_CODE (field) != FIELD_DECL) continue; if (CP_TYPE_CONST_P (TREE_TYPE (field))) { if (DECL_NAME (field)) cp_error ("non-static const member `%#D', can't use default assignment operator", field); else cp_error ("non-static const member in type `%T', can't use default assignment operator", current_class_type); continue; } else if (TREE_CODE (TREE_TYPE (field)) == REFERENCE_TYPE) { if (DECL_NAME (field)) cp_error ("non-static reference member `%#D', can't use default assignment operator", field); else cp_error ("non-static reference member in type `%T', can't use default assignment operator", current_class_type); continue; } comp = current_class_ref; init = parm; if (DECL_NAME (field)) { if (VFIELD_NAME_P (DECL_NAME (field))) continue; if (VBASE_NAME_P (DECL_NAME (field))) continue; /* True for duplicate members. */ if (IDENTIFIER_CLASS_VALUE (DECL_NAME (field)) != field) continue; } else if ((t = TREE_TYPE (field)) != NULL_TREE && ANON_UNION_TYPE_P (t) && TYPE_FIELDS (t) != NULL_TREE) { do { comp = build (COMPONENT_REF, t, comp, field); init = build (COMPONENT_REF, t, init, field); field = largest_union_member (t); } while ((t = TREE_TYPE (field)) != NULL_TREE && ANON_UNION_TYPE_P (t) && TYPE_FIELDS (t) != NULL_TREE); } else continue; comp = build (COMPONENT_REF, TREE_TYPE (field), comp, field); init = build (COMPONENT_REF, TREE_TYPE (field), init, field); expand_expr_stmt (build_modify_expr (comp, NOP_EXPR, init)); } } c_expand_return (current_class_ref); pop_momentary (); } void synthesize_method (fndecl) tree fndecl; { int nested = (current_function_decl != NULL_TREE); tree context = hack_decl_function_context (fndecl); + /* If this is a wrapper around a undefined vlist ctor, don't emit it + even if it is used. */ + if (DECL_VLIST_CTOR_WRAPPER_P (fndecl)) + { + tree orig_fn = DECL_VLIST_CTOR_WRAPPED (fndecl); + mark_used (orig_fn); + if (DECL_INITIAL (orig_fn) == NULL_TREE) + return; + } + if (at_eof) import_export_decl (fndecl); if (! context) push_to_top_level (); else if (nested) push_cp_function_context (context); interface_unknown = 1; start_function (NULL_TREE, fndecl, NULL_TREE, 1); store_parm_decls (); if (DECL_NAME (fndecl) == ansi_opname[MODIFY_EXPR]) do_build_assign_ref (fndecl); else if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (fndecl))) ; else { tree arg_chain = FUNCTION_ARG_CHAIN (fndecl); if (DECL_CONSTRUCTOR_FOR_VBASE_P (fndecl)) arg_chain = TREE_CHAIN (arg_chain); - if (arg_chain != void_list_node) + else if (DECL_CONSTRUCTOR_FOR_PVBASE_P (fndecl)) + arg_chain = TREE_CHAIN (TREE_CHAIN (arg_chain)); + if (DECL_VLIST_CTOR_WRAPPER_P (fndecl)) + emit_vlist_ctor_wrapper (fndecl); + else if (arg_chain != void_list_node) do_build_copy_constructor (fndecl); else if (TYPE_NEEDS_CONSTRUCTING (current_class_type)) setup_vtbl_ptr (); } finish_function (lineno, 0, nested); extract_interface_info (); if (! context) pop_from_top_level (); else if (nested) pop_cp_function_context (context); } + + + Index: vendor/gcc/dist/contrib/gcc/cp/pt.c =================================================================== --- vendor/gcc/dist/contrib/gcc/cp/pt.c (revision 60966) +++ vendor/gcc/dist/contrib/gcc/cp/pt.c (revision 60967) @@ -1,9840 +1,9876 @@ /* Handle parameterized types (templates) for GNU C++. Copyright (C) 1992, 93-97, 1998, 1999 Free Software Foundation, Inc. Written by Ken Raeburn (raeburn@cygnus.com) while at Watchmaker Computing. Rewritten by Jason Merrill (jason@cygnus.com). 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. */ /* Known bugs or deficiencies include: all methods must be provided in header files; can't use a source file that contains only the method templates and "just win". */ #include "config.h" #include "system.h" #include "obstack.h" #include "tree.h" #include "flags.h" #include "cp-tree.h" #include "decl.h" #include "parse.h" #include "lex.h" #include "output.h" #include "defaults.h" #include "except.h" #include "toplev.h" #include "rtl.h" #include "varray.h" /* The type of functions taking a tree, and some additional data, and returning an int. */ typedef int (*tree_fn_t) PROTO((tree, void*)); extern struct obstack permanent_obstack; extern int lineno; extern char *input_filename; tree current_template_parms; HOST_WIDE_INT processing_template_decl; /* The PENDING_TEMPLATES is a TREE_LIST of templates whose instantiations have been deferred, either because their definitions were not yet available, or because we were putting off doing the work. The TREE_PURPOSE of each entry is a SRCLOC indicating where the instantiate request occurred; the TREE_VALUE is a either a DECL (for a function or static data member), or a TYPE (for a class) indicating what we are hoping to instantiate. */ static tree pending_templates; static tree *template_tail = &pending_templates; static tree maybe_templates; static tree *maybe_template_tail = &maybe_templates; int minimal_parse_mode; int processing_specialization; int processing_explicit_instantiation; int processing_template_parmlist; static int template_header_count; static tree saved_trees; static varray_type inline_parm_levels; static size_t inline_parm_levels_used; #define obstack_chunk_alloc xmalloc #define obstack_chunk_free free #define UNIFY_ALLOW_NONE 0 #define UNIFY_ALLOW_MORE_CV_QUAL 1 #define UNIFY_ALLOW_LESS_CV_QUAL 2 #define UNIFY_ALLOW_DERIVED 4 #define UNIFY_ALLOW_INTEGER 8 #define GTB_VIA_VIRTUAL 1 /* The base class we are examining is virtual, or a base class of a virtual base. */ #define GTB_IGNORE_TYPE 2 /* We don't need to try to unify the current type with the desired type. */ static int resolve_overloaded_unification PROTO((tree, tree, tree, tree, unification_kind_t, int)); static int try_one_overload PROTO((tree, tree, tree, tree, tree, unification_kind_t, int)); static int unify PROTO((tree, tree, tree, tree, int)); static void add_pending_template PROTO((tree)); static int push_tinst_level PROTO((tree)); static tree classtype_mangled_name PROTO((tree)); static char *mangle_class_name_for_template PROTO((char *, tree, tree)); static tree tsubst_expr_values PROTO((tree, tree)); static int list_eq PROTO((tree, tree)); static tree get_class_bindings PROTO((tree, tree, tree)); static tree coerce_template_parms PROTO((tree, tree, tree, int, int)); static void tsubst_enum PROTO((tree, tree, tree)); static tree add_to_template_args PROTO((tree, tree)); static tree add_outermost_template_args PROTO((tree, tree)); static void maybe_adjust_types_for_deduction PROTO((unification_kind_t, tree*, tree*)); static int type_unification_real PROTO((tree, tree, tree, tree, int, unification_kind_t, int)); static void note_template_header PROTO((int)); static tree maybe_fold_nontype_arg PROTO((tree)); static tree convert_nontype_argument PROTO((tree, tree)); static tree convert_template_argument PROTO ((tree, tree, tree, int, int , tree)); static tree get_bindings_overload PROTO((tree, tree, tree)); static int for_each_template_parm PROTO((tree, tree_fn_t, void*)); static tree build_template_parm_index PROTO((int, int, int, tree, tree)); static int inline_needs_template_parms PROTO((tree)); static void push_inline_template_parms_recursive PROTO((tree, int)); static tree retrieve_specialization PROTO((tree, tree)); static tree register_specialization PROTO((tree, tree, tree)); static int unregister_specialization PROTO((tree, tree)); static tree reduce_template_parm_level PROTO((tree, tree, int)); static tree build_template_decl PROTO((tree, tree)); static int mark_template_parm PROTO((tree, void *)); static tree tsubst_friend_function PROTO((tree, tree)); static tree tsubst_friend_class PROTO((tree, tree)); static tree get_bindings_real PROTO((tree, tree, tree, int)); static int template_decl_level PROTO((tree)); static tree maybe_get_template_decl_from_type_decl PROTO((tree)); static int check_cv_quals_for_unify PROTO((int, tree, tree)); static tree tsubst_template_arg_vector PROTO((tree, tree, int)); static tree tsubst_template_parms PROTO((tree, tree, int)); static void regenerate_decl_from_template PROTO((tree, tree)); static tree most_specialized PROTO((tree, tree, tree)); static tree most_specialized_class PROTO((tree, tree)); static tree most_general_template PROTO((tree)); static void set_mangled_name_for_template_decl PROTO((tree)); static int template_class_depth_real PROTO((tree, int)); static tree tsubst_aggr_type PROTO((tree, tree, int, tree, int)); static tree tsubst_decl PROTO((tree, tree, tree, tree)); static tree tsubst_arg_types PROTO((tree, tree, int, tree)); static tree tsubst_function_type PROTO((tree, tree, int, tree)); static void check_specialization_scope PROTO((void)); static tree process_partial_specialization PROTO((tree)); static void set_current_access_from_decl PROTO((tree)); static void check_default_tmpl_args PROTO((tree, tree, int, int)); static tree tsubst_call_declarator_parms PROTO((tree, tree, int, tree)); static tree get_template_base_recursive PROTO((tree, tree, tree, tree, tree, int)); static tree get_template_base PROTO((tree, tree, tree, tree)); static tree try_class_unification PROTO((tree, tree, tree, tree)); static int coerce_template_template_parms PROTO((tree, tree, int, tree, tree)); static tree determine_specialization PROTO((tree, tree, tree *, int)); static int template_args_equal PROTO((tree, tree)); static void print_template_context PROTO((int)); +static int has_pvbases_p PROTO((tree, tree)); /* We use TREE_VECs to hold template arguments. If there is only one level of template arguments, then the TREE_VEC contains the arguments directly. If there is more than one level of template arguments, then each entry in the TREE_VEC is itself a TREE_VEC, containing the template arguments for a single level. The first entry in the outer TREE_VEC is the outermost level of template parameters; the last is the innermost. It is incorrect to ever form a template argument vector containing only one level of arguments, but which is a TREE_VEC containing as its only entry the TREE_VEC for that level. */ /* Non-zero if the template arguments is actually a vector of vectors, rather than just a vector. */ #define TMPL_ARGS_HAVE_MULTIPLE_LEVELS(NODE) \ (NODE != NULL_TREE \ && TREE_CODE (NODE) == TREE_VEC \ && TREE_VEC_LENGTH (NODE) > 0 \ && TREE_VEC_ELT (NODE, 0) != NULL_TREE \ && TREE_CODE (TREE_VEC_ELT (NODE, 0)) == TREE_VEC) /* The depth of a template argument vector. When called directly by the parser, we use a TREE_LIST rather than a TREE_VEC to represent template arguments. In fact, we may even see NULL_TREE if there are no template arguments. In both of those cases, there is only one level of template arguments. */ #define TMPL_ARGS_DEPTH(NODE) \ (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (NODE) ? TREE_VEC_LENGTH (NODE) : 1) /* The LEVELth level of the template ARGS. Note that template parameter levels are indexed from 1, not from 0. */ #define TMPL_ARGS_LEVEL(ARGS, LEVEL) \ (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (ARGS) \ ? TREE_VEC_ELT ((ARGS), (LEVEL) - 1) : ARGS) /* Set the LEVELth level of the template ARGS to VAL. This macro does not work with single-level argument vectors. */ #define SET_TMPL_ARGS_LEVEL(ARGS, LEVEL, VAL) \ (TREE_VEC_ELT ((ARGS), (LEVEL) - 1) = (VAL)) /* Accesses the IDXth parameter in the LEVELth level of the ARGS. */ #define TMPL_ARG(ARGS, LEVEL, IDX) \ (TREE_VEC_ELT (TMPL_ARGS_LEVEL (ARGS, LEVEL), IDX)) /* Set the IDXth element in the LEVELth level of ARGS to VAL. This macro does not work with single-level argument vectors. */ #define SET_TMPL_ARG(ARGS, LEVEL, IDX, VAL) \ (TREE_VEC_ELT (TREE_VEC_ELT ((ARGS), (LEVEL) - 1), (IDX)) = (VAL)) /* Given a single level of template arguments in NODE, return the number of arguments. */ #define NUM_TMPL_ARGS(NODE) \ ((NODE) == NULL_TREE ? 0 \ : (TREE_CODE (NODE) == TREE_VEC \ ? TREE_VEC_LENGTH (NODE) : list_length (NODE))) /* The number of levels of template parameters given by NODE. */ #define TMPL_PARMS_DEPTH(NODE) \ (TREE_INT_CST_HIGH (TREE_PURPOSE (NODE))) /* Do any processing required when DECL (a member template declaration using TEMPLATE_PARAMETERS as its innermost parameter list) is finished. Returns the TEMPLATE_DECL corresponding to DECL, unless it is a specialization, in which case the DECL itself is returned. */ tree finish_member_template_decl (decl) tree decl; { if (decl == NULL_TREE || decl == void_type_node) return NULL_TREE; else if (decl == error_mark_node) /* By returning NULL_TREE, the parser will just ignore this declaration. We have already issued the error. */ return NULL_TREE; else if (TREE_CODE (decl) == TREE_LIST) { /* Assume that the class is the only declspec. */ decl = TREE_VALUE (decl); if (IS_AGGR_TYPE (decl) && CLASSTYPE_TEMPLATE_INFO (decl) && ! CLASSTYPE_TEMPLATE_SPECIALIZATION (decl)) { tree tmpl = CLASSTYPE_TI_TEMPLATE (decl); check_member_template (tmpl); return tmpl; } return NULL_TREE; } else if (DECL_TEMPLATE_INFO (decl)) { if (!DECL_TEMPLATE_SPECIALIZATION (decl)) { check_member_template (DECL_TI_TEMPLATE (decl)); return DECL_TI_TEMPLATE (decl); } else return decl; } else cp_error ("invalid member template declaration `%D'", decl); return error_mark_node; } /* Returns the template nesting level of the indicated class TYPE. For example, in: template struct A { template struct B {}; }; A::B has depth two, while A has depth one. Both A::B and A::B have depth one, if COUNT_SPECIALIZATIONS is 0 or if they are instantiations, not specializations. This function is guaranteed to return 0 if passed NULL_TREE so that, for example, `template_class_depth (current_class_type)' is always safe. */ static int template_class_depth_real (type, count_specializations) tree type; int count_specializations; { int depth; for (depth = 0; type && TREE_CODE (type) != NAMESPACE_DECL; type = (TREE_CODE (type) == FUNCTION_DECL) ? DECL_REAL_CONTEXT (type) : TYPE_CONTEXT (type)) { if (TREE_CODE (type) != FUNCTION_DECL) { if (CLASSTYPE_TEMPLATE_INFO (type) && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (type)) && ((count_specializations && CLASSTYPE_TEMPLATE_SPECIALIZATION (type)) || uses_template_parms (CLASSTYPE_TI_ARGS (type)))) ++depth; } else { if (DECL_TEMPLATE_INFO (type) && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (type)) && ((count_specializations && DECL_TEMPLATE_SPECIALIZATION (type)) || uses_template_parms (DECL_TI_ARGS (type)))) ++depth; } } return depth; } /* Returns the template nesting level of the indicated class TYPE. Like template_class_depth_real, but instantiations do not count in the depth. */ int template_class_depth (type) tree type; { return template_class_depth_real (type, /*count_specializations=*/0); } /* Returns 1 if processing DECL as part of do_pending_inlines needs us to push template parms. */ static int inline_needs_template_parms (decl) tree decl; { if (! DECL_TEMPLATE_INFO (decl)) return 0; return (TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (most_general_template (decl))) > (processing_template_decl + DECL_TEMPLATE_SPECIALIZATION (decl))); } /* Subroutine of maybe_begin_member_template_processing. Push the template parms in PARMS, starting from LEVELS steps into the chain, and ending at the beginning, since template parms are listed innermost first. */ static void push_inline_template_parms_recursive (parmlist, levels) tree parmlist; int levels; { tree parms = TREE_VALUE (parmlist); int i; if (levels > 1) push_inline_template_parms_recursive (TREE_CHAIN (parmlist), levels - 1); ++processing_template_decl; current_template_parms = tree_cons (build_int_2 (0, processing_template_decl), parms, current_template_parms); TEMPLATE_PARMS_FOR_INLINE (current_template_parms) = 1; pushlevel (0); for (i = 0; i < TREE_VEC_LENGTH (parms); ++i) { tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i)); my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (parm)) == 'd', 0); switch (TREE_CODE (parm)) { case TYPE_DECL: case TEMPLATE_DECL: pushdecl (parm); break; case PARM_DECL: { /* Make a CONST_DECL as is done in process_template_parm. It is ugly that we recreate this here; the original version built in process_template_parm is no longer available. */ tree decl = build_decl (CONST_DECL, DECL_NAME (parm), TREE_TYPE (parm)); SET_DECL_ARTIFICIAL (decl); DECL_INITIAL (decl) = DECL_INITIAL (parm); DECL_TEMPLATE_PARM_P (decl) = 1; pushdecl (decl); } break; default: my_friendly_abort (0); } } } /* Restore the template parameter context for a member template or a friend template defined in a class definition. */ void maybe_begin_member_template_processing (decl) tree decl; { tree parms; int levels = 0; if (inline_needs_template_parms (decl)) { parms = DECL_TEMPLATE_PARMS (most_general_template (decl)); levels = TMPL_PARMS_DEPTH (parms) - processing_template_decl; if (DECL_TEMPLATE_SPECIALIZATION (decl)) { --levels; parms = TREE_CHAIN (parms); } push_inline_template_parms_recursive (parms, levels); } /* Remember how many levels of template parameters we pushed so that we can pop them later. */ if (!inline_parm_levels) VARRAY_INT_INIT (inline_parm_levels, 4, "inline_parm_levels"); if (inline_parm_levels_used == inline_parm_levels->num_elements) VARRAY_GROW (inline_parm_levels, 2 * inline_parm_levels_used); VARRAY_INT (inline_parm_levels, inline_parm_levels_used) = levels; ++inline_parm_levels_used; } /* Undo the effects of begin_member_template_processing. */ void maybe_end_member_template_processing () { int i; if (!inline_parm_levels_used) return; --inline_parm_levels_used; for (i = 0; i < VARRAY_INT (inline_parm_levels, inline_parm_levels_used); ++i) { --processing_template_decl; current_template_parms = TREE_CHAIN (current_template_parms); poplevel (0, 0, 0); } } /* Returns non-zero iff T is a member template function. We must be careful as in template class C { void f(); } Here, f is a template function, and a member, but not a member template. This function does not concern itself with the origin of T, only its present state. So if we have template class C { template void f(U); } then neither C::f nor C::f is considered to be a member template. But, `template void C::f(U)' is considered a member template. */ int is_member_template (t) tree t; { if (!DECL_FUNCTION_TEMPLATE_P (t)) /* Anything that isn't a function or a template function is certainly not a member template. */ return 0; /* A local class can't have member templates. */ if (hack_decl_function_context (t)) return 0; return (DECL_FUNCTION_MEMBER_P (DECL_TEMPLATE_RESULT (t)) /* If there are more levels of template parameters than there are template classes surrounding the declaration, then we have a member template. */ && (TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (t)) > template_class_depth (DECL_CLASS_CONTEXT (t)))); } #if 0 /* UNUSED */ /* Returns non-zero iff T is a member template class. See is_member_template for a description of what precisely constitutes a member template. */ int is_member_template_class (t) tree t; { if (!DECL_CLASS_TEMPLATE_P (t)) /* Anything that isn't a class template, is certainly not a member template. */ return 0; if (!DECL_CLASS_SCOPE_P (t)) /* Anything whose context isn't a class type is surely not a member template. */ return 0; /* If there are more levels of template parameters than there are template classes surrounding the declaration, then we have a member template. */ return (TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (t)) > template_class_depth (DECL_CONTEXT (t))); } #endif /* Return a new template argument vector which contains all of ARGS, but has as its innermost set of arguments the EXTRA_ARGS. The resulting vector will be built on a temporary obstack, and so must be explicitly copied to the permanent obstack, if required. */ static tree add_to_template_args (args, extra_args) tree args; tree extra_args; { tree new_args; int extra_depth; int i; int j; extra_depth = TMPL_ARGS_DEPTH (extra_args); new_args = make_temp_vec (TMPL_ARGS_DEPTH (args) + extra_depth); for (i = 1; i <= TMPL_ARGS_DEPTH (args); ++i) SET_TMPL_ARGS_LEVEL (new_args, i, TMPL_ARGS_LEVEL (args, i)); for (j = 1; j <= extra_depth; ++j, ++i) SET_TMPL_ARGS_LEVEL (new_args, i, TMPL_ARGS_LEVEL (extra_args, j)); return new_args; } /* Like add_to_template_args, but only the outermost ARGS are added to the EXTRA_ARGS. In particular, all but TMPL_ARGS_DEPTH (EXTRA_ARGS) levels are added. This function is used to combine the template arguments from a partial instantiation with the template arguments used to attain the full instantiation from the partial instantiation. */ static tree add_outermost_template_args (args, extra_args) tree args; tree extra_args; { tree new_args; /* If there are more levels of EXTRA_ARGS than there are ARGS, something very fishy is going on. */ my_friendly_assert (TMPL_ARGS_DEPTH (args) >= TMPL_ARGS_DEPTH (extra_args), 0); /* If *all* the new arguments will be the EXTRA_ARGS, just return them. */ if (TMPL_ARGS_DEPTH (args) == TMPL_ARGS_DEPTH (extra_args)) return extra_args; /* For the moment, we make ARGS look like it contains fewer levels. */ TREE_VEC_LENGTH (args) -= TMPL_ARGS_DEPTH (extra_args); new_args = add_to_template_args (args, extra_args); /* Now, we restore ARGS to its full dimensions. */ TREE_VEC_LENGTH (args) += TMPL_ARGS_DEPTH (extra_args); return new_args; } /* We've got a template header coming up; push to a new level for storing the parms. */ void begin_template_parm_list () { /* We use a non-tag-transparent scope here, which causes pushtag to put tags in this scope, rather than in the enclosing class or namespace scope. This is the right thing, since we want TEMPLATE_DECLS, and not TYPE_DECLS for template classes. For a global template class, push_template_decl handles putting the TEMPLATE_DECL into top-level scope. For a nested template class, e.g.: template struct S1 { template struct S2 {}; }; pushtag contains special code to call pushdecl_with_scope on the TEMPLATE_DECL for S2. */ pushlevel (0); declare_pseudo_global_level (); ++processing_template_decl; ++processing_template_parmlist; note_template_header (0); } /* This routine is called when a specialization is declared. If it is illegal to declare a specialization here, an error is reported. */ static void check_specialization_scope () { tree scope = current_scope (); /* [temp.expl.spec] An explicit specialization shall be declared in the namespace of which the template is a member, or, for member templates, in the namespace of which the enclosing class or enclosing class template is a member. An explicit specialization of a member function, member class or static data member of a class template shall be declared in the namespace of which the class template is a member. */ if (scope && TREE_CODE (scope) != NAMESPACE_DECL) cp_error ("explicit specialization in non-namespace scope `%D'", scope); /* [temp.expl.spec] In an explicit specialization declaration for a member of a class template or a member template that appears in namespace scope, the member template and some of its enclosing class templates may remain unspecialized, except that the declaration shall not explicitly specialize a class member template if its enclosing class templates are not explicitly specialized as well. */ if (current_template_parms) cp_error ("enclosing class templates are not explicitly specialized"); } /* We've just seen template <>. */ void begin_specialization () { note_template_header (1); check_specialization_scope (); } /* Called at then end of processing a declaration preceeded by template<>. */ void end_specialization () { reset_specialization (); } /* Any template <>'s that we have seen thus far are not referring to a function specialization. */ void reset_specialization () { processing_specialization = 0; template_header_count = 0; } /* We've just seen a template header. If SPECIALIZATION is non-zero, it was of the form template <>. */ static void note_template_header (specialization) int specialization; { processing_specialization = specialization; template_header_count++; } /* We're beginning an explicit instantiation. */ void begin_explicit_instantiation () { ++processing_explicit_instantiation; } void end_explicit_instantiation () { my_friendly_assert(processing_explicit_instantiation > 0, 0); --processing_explicit_instantiation; } /* The TYPE is being declared. If it is a template type, that means it is a partial specialization. Do appropriate error-checking. */ void maybe_process_partial_specialization (type) tree type; { if (IS_AGGR_TYPE (type) && CLASSTYPE_USE_TEMPLATE (type)) { if (CLASSTYPE_IMPLICIT_INSTANTIATION (type) && TYPE_SIZE (type) == NULL_TREE) { if (current_namespace != decl_namespace_context (CLASSTYPE_TI_TEMPLATE (type))) { cp_pedwarn ("specializing `%#T' in different namespace", type); cp_pedwarn_at (" from definition of `%#D'", CLASSTYPE_TI_TEMPLATE (type)); } SET_CLASSTYPE_TEMPLATE_SPECIALIZATION (type); if (processing_template_decl) push_template_decl (TYPE_MAIN_DECL (type)); } else if (CLASSTYPE_TEMPLATE_INSTANTIATION (type)) cp_error ("specialization of `%T' after instantiation", type); } else if (processing_specialization) cp_error ("explicit specialization of non-template `%T'", type); } /* Retrieve the specialization (in the sense of [temp.spec] - a specialization is either an instantiation or an explicit specialization) of TMPL for the given template ARGS. If there is no such specialization, return NULL_TREE. The ARGS are a vector of arguments, or a vector of vectors of arguments, in the case of templates with more than one level of parameters. */ static tree retrieve_specialization (tmpl, args) tree tmpl; tree args; { tree s; my_friendly_assert (TREE_CODE (tmpl) == TEMPLATE_DECL, 0); /* There should be as many levels of arguments as there are levels of parameters. */ my_friendly_assert (TMPL_ARGS_DEPTH (args) == TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl)), 0); for (s = DECL_TEMPLATE_SPECIALIZATIONS (tmpl); s != NULL_TREE; s = TREE_CHAIN (s)) if (comp_template_args (TREE_PURPOSE (s), args)) return TREE_VALUE (s); return NULL_TREE; } /* Returns non-zero iff DECL is a specialization of TMPL. */ int is_specialization_of (decl, tmpl) tree decl; tree tmpl; { tree t; if (TREE_CODE (decl) == FUNCTION_DECL) { for (t = decl; t != NULL_TREE; t = DECL_TEMPLATE_INFO (t) ? DECL_TI_TEMPLATE (t) : NULL_TREE) if (t == tmpl) return 1; } else { my_friendly_assert (TREE_CODE (decl) == TYPE_DECL, 0); for (t = TREE_TYPE (decl); t != NULL_TREE; t = CLASSTYPE_USE_TEMPLATE (t) ? TREE_TYPE (CLASSTYPE_TI_TEMPLATE (t)) : NULL_TREE) if (same_type_p (TYPE_MAIN_VARIANT (t), TYPE_MAIN_VARIANT (TREE_TYPE (tmpl)))) return 1; } return 0; } /* Register the specialization SPEC as a specialization of TMPL with the indicated ARGS. Returns SPEC, or an equivalent prior declaration, if available. */ static tree register_specialization (spec, tmpl, args) tree spec; tree tmpl; tree args; { tree s; my_friendly_assert (TREE_CODE (tmpl) == TEMPLATE_DECL, 0); if (TREE_CODE (spec) == FUNCTION_DECL && uses_template_parms (DECL_TI_ARGS (spec))) /* This is the FUNCTION_DECL for a partial instantiation. Don't register it; we want the corresponding TEMPLATE_DECL instead. We use `uses_template_parms (DECL_TI_ARGS (spec))' rather than the more obvious `uses_template_parms (spec)' to avoid problems with default function arguments. In particular, given something like this: template void f(T t1, T t = T()) the default argument expression is not substituted for in an instantiation unless and until it is actually needed. */ return spec; /* There should be as many levels of arguments as there are levels of parameters. */ my_friendly_assert (TMPL_ARGS_DEPTH (args) == TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl)), 0); for (s = DECL_TEMPLATE_SPECIALIZATIONS (tmpl); s != NULL_TREE; s = TREE_CHAIN (s)) if (comp_template_args (TREE_PURPOSE (s), args)) { tree fn = TREE_VALUE (s); if (DECL_TEMPLATE_SPECIALIZATION (spec)) { if (DECL_TEMPLATE_INSTANTIATION (fn)) { if (TREE_USED (fn) || DECL_EXPLICIT_INSTANTIATION (fn)) { cp_error ("specialization of %D after instantiation", fn); return spec; } else { /* This situation should occur only if the first specialization is an implicit instantiation, the second is an explicit specialization, and the implicit instantiation has not yet been used. That situation can occur if we have implicitly instantiated a member function and then specialized it later. We can also wind up here if a friend declaration that looked like an instantiation turns out to be a specialization: template void foo(T); class S { friend void foo<>(int) }; template <> void foo(int); We transform the existing DECL in place so that any pointers to it become pointers to the updated declaration. If there was a definition for the template, but not for the specialization, we want this to look as if there is no definition, and vice versa. */ DECL_INITIAL (fn) = NULL_TREE; duplicate_decls (spec, fn); return fn; } } else if (DECL_TEMPLATE_SPECIALIZATION (fn)) { duplicate_decls (spec, fn); return fn; } } } DECL_TEMPLATE_SPECIALIZATIONS (tmpl) = perm_tree_cons (args, spec, DECL_TEMPLATE_SPECIALIZATIONS (tmpl)); return spec; } /* Unregister the specialization SPEC as a specialization of TMPL. Returns nonzero if the SPEC was listed as a specialization of TMPL. */ static int unregister_specialization (spec, tmpl) tree spec; tree tmpl; { tree* s; for (s = &DECL_TEMPLATE_SPECIALIZATIONS (tmpl); *s != NULL_TREE; s = &TREE_CHAIN (*s)) if (TREE_VALUE (*s) == spec) { *s = TREE_CHAIN (*s); return 1; } return 0; } /* Print the list of candidate FNS in an error message. */ void print_candidates (fns) tree fns; { tree fn; const char *str = "candidates are:"; for (fn = fns; fn != NULL_TREE; fn = TREE_CHAIN (fn)) { tree f; for (f = TREE_VALUE (fn); f; f = OVL_NEXT (f)) cp_error_at ("%s %+#D", str, OVL_CURRENT (f)); str = " "; } } /* Returns the template (one of the functions given by TEMPLATE_ID) which can be specialized to match the indicated DECL with the explicit template args given in TEMPLATE_ID. The DECL may be NULL_TREE if none is available. In that case, the functions in TEMPLATE_ID are non-members. If NEED_MEMBER_TEMPLATE is non-zero the function is known to be a specialization of a member template. The template args (those explicitly specified and those deduced) are output in a newly created vector *TARGS_OUT. If it is impossible to determine the result, an error message is issued. The error_mark_node is returned to indicate failure. */ static tree determine_specialization (template_id, decl, targs_out, need_member_template) tree template_id; tree decl; tree* targs_out; int need_member_template; { tree fn; tree fns; tree targs; tree explicit_targs; tree candidates = NULL_TREE; tree templates = NULL_TREE; *targs_out = NULL_TREE; if (template_id == error_mark_node) return error_mark_node; fns = TREE_OPERAND (template_id, 0); explicit_targs = TREE_OPERAND (template_id, 1); if (fns == error_mark_node) return error_mark_node; /* Check for baselinks. */ if (TREE_CODE (fns) == TREE_LIST) fns = TREE_VALUE (fns); for (; fns; fns = OVL_NEXT (fns)) { tree tmpl; fn = OVL_CURRENT (fns); if (TREE_CODE (fn) == TEMPLATE_DECL) /* DECL might be a specialization of FN. */ tmpl = fn; else if (need_member_template) /* FN is an ordinary member function, and we need a specialization of a member template. */ continue; else if (TREE_CODE (fn) != FUNCTION_DECL) /* We can get IDENTIFIER_NODEs here in certain erroneous cases. */ continue; else if (!DECL_FUNCTION_MEMBER_P (fn)) /* This is just an ordinary non-member function. Nothing can be a specialization of that. */ continue; else { tree decl_arg_types; /* This is an ordinary member function. However, since we're here, we can assume it's enclosing class is a template class. For example, template struct S { void f(); }; template <> void S::f() {} Here, S::f is a non-template, but S is a template class. If FN has the same type as DECL, we might be in business. */ if (!same_type_p (TREE_TYPE (TREE_TYPE (decl)), TREE_TYPE (TREE_TYPE (fn)))) /* The return types differ. */ continue; /* Adjust the type of DECL in case FN is a static member. */ decl_arg_types = TYPE_ARG_TYPES (TREE_TYPE (decl)); if (DECL_STATIC_FUNCTION_P (fn) && DECL_NONSTATIC_MEMBER_FUNCTION_P (decl)) decl_arg_types = TREE_CHAIN (decl_arg_types); if (compparms (TYPE_ARG_TYPES (TREE_TYPE (fn)), decl_arg_types)) /* They match! */ candidates = tree_cons (NULL_TREE, fn, candidates); continue; } /* See whether this function might be a specialization of this template. */ targs = get_bindings (tmpl, decl, explicit_targs); if (!targs) /* We cannot deduce template arguments that when used to specialize TMPL will produce DECL. */ continue; /* Save this template, and the arguments deduced. */ templates = scratch_tree_cons (targs, tmpl, templates); } if (templates && TREE_CHAIN (templates)) { /* We have: [temp.expl.spec] It is possible for a specialization with a given function signature to be instantiated from more than one function template. In such cases, explicit specification of the template arguments must be used to uniquely identify the function template specialization being specialized. Note that here, there's no suggestion that we're supposed to determine which of the candidate templates is most specialized. However, we, also have: [temp.func.order] Partial ordering of overloaded function template declarations is used in the following contexts to select the function template to which a function template specialization refers: -- when an explicit specialization refers to a function template. So, we do use the partial ordering rules, at least for now. This extension can only serve to make illegal programs legal, so it's safe. And, there is strong anecdotal evidence that the committee intended the partial ordering rules to apply; the EDG front-end has that behavior, and John Spicer claims that the committee simply forgot to delete the wording in [temp.expl.spec]. */ tree tmpl = most_specialized (templates, decl, explicit_targs); if (tmpl && tmpl != error_mark_node) { targs = get_bindings (tmpl, decl, explicit_targs); templates = scratch_tree_cons (targs, tmpl, NULL_TREE); } } if (templates == NULL_TREE && candidates == NULL_TREE) { cp_error_at ("template-id `%D' for `%+D' does not match any template declaration", template_id, decl); return error_mark_node; } else if ((templates && TREE_CHAIN (templates)) || (candidates && TREE_CHAIN (candidates)) || (templates && candidates)) { cp_error_at ("ambiguous template specialization `%D' for `%+D'", template_id, decl); chainon (candidates, templates); print_candidates (candidates); return error_mark_node; } /* We have one, and exactly one, match. */ if (candidates) { /* It was a specialization of an ordinary member function in a template class. */ *targs_out = copy_node (DECL_TI_ARGS (TREE_VALUE (candidates))); return DECL_TI_TEMPLATE (TREE_VALUE (candidates)); } /* It was a specialization of a template. */ targs = DECL_TI_ARGS (DECL_RESULT (TREE_VALUE (templates))); if (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (targs)) { *targs_out = copy_node (targs); SET_TMPL_ARGS_LEVEL (*targs_out, TMPL_ARGS_DEPTH (*targs_out), TREE_PURPOSE (templates)); } else *targs_out = TREE_PURPOSE (templates); return TREE_VALUE (templates); } /* Check to see if the function just declared, as indicated in DECLARATOR, and in DECL, is a specialization of a function template. We may also discover that the declaration is an explicit instantiation at this point. Returns DECL, or an equivalent declaration that should be used instead if all goes well. Issues an error message if something is amiss. Returns error_mark_node if the error is not easily recoverable. FLAGS is a bitmask consisting of the following flags: 2: The function has a definition. 4: The function is a friend. The TEMPLATE_COUNT is the number of references to qualifying template classes that appeared in the name of the function. For example, in template struct S { void f(); }; void S::f(); the TEMPLATE_COUNT would be 1. However, explicitly specialized classes are not counted in the TEMPLATE_COUNT, so that in template struct S {}; template <> struct S { void f(); } template <> void S::f(); the TEMPLATE_COUNT would be 0. (Note that this declaration is illegal; there should be no template <>.) If the function is a specialization, it is marked as such via DECL_TEMPLATE_SPECIALIZATION. Furthermore, its DECL_TEMPLATE_INFO is set up correctly, and it is added to the list of specializations for that template. */ tree check_explicit_specialization (declarator, decl, template_count, flags) tree declarator; tree decl; int template_count; int flags; { int have_def = flags & 2; int is_friend = flags & 4; int specialization = 0; int explicit_instantiation = 0; int member_specialization = 0; tree ctype = DECL_CLASS_CONTEXT (decl); tree dname = DECL_NAME (decl); if (processing_specialization) { /* The last template header was of the form template <>. */ if (template_header_count > template_count) { /* There were more template headers than qualifying template classes. */ if (template_header_count - template_count > 1) /* There shouldn't be that many template parameter lists. There can be at most one parameter list for every qualifying class, plus one for the function itself. */ cp_error ("too many template parameter lists in declaration of `%D'", decl); SET_DECL_TEMPLATE_SPECIALIZATION (decl); if (ctype) member_specialization = 1; else specialization = 1; } else if (template_header_count == template_count) { /* The counts are equal. So, this might be a specialization, but it is not a specialization of a member template. It might be something like template struct S { void f(int i); }; template <> void S::f(int i) {} */ specialization = 1; SET_DECL_TEMPLATE_SPECIALIZATION (decl); } else { /* This cannot be an explicit specialization. There are not enough headers for all of the qualifying classes. For example, we might have: template <> void S::T::f(); But, we're missing another template <>. */ cp_error("too few template parameter lists in declaration of `%D'", decl); return decl; } } else if (processing_explicit_instantiation) { if (template_header_count) cp_error ("template parameter list used in explicit instantiation"); if (have_def) cp_error ("definition provided for explicit instantiation"); explicit_instantiation = 1; } else if (ctype != NULL_TREE && !TYPE_BEING_DEFINED (ctype) && CLASSTYPE_TEMPLATE_INSTANTIATION (ctype) && !is_friend) { /* This case catches outdated code that looks like this: template struct S { void f(); }; void S::f() {} // Missing template <> We disable this check when the type is being defined to avoid complaining about default compiler-generated constructors, destructors, and assignment operators. Since the type is an instantiation, not a specialization, these are the only functions that can be defined before the class is complete. */ /* If they said template void S::f() {} that's bogus. */ if (template_header_count) { cp_error ("template parameters specified in specialization"); return decl; } if (pedantic) cp_pedwarn ("explicit specialization not preceded by `template <>'"); specialization = 1; SET_DECL_TEMPLATE_SPECIALIZATION (decl); } else if (TREE_CODE (declarator) == TEMPLATE_ID_EXPR) { if (is_friend) /* This could be something like: template void f(T); class S { friend void f<>(int); } */ specialization = 1; else { /* This case handles bogus declarations like template <> template void f(); */ cp_error ("template-id `%D' in declaration of primary template", declarator); return decl; } } if (specialization || member_specialization) { tree t = TYPE_ARG_TYPES (TREE_TYPE (decl)); for (; t; t = TREE_CHAIN (t)) if (TREE_PURPOSE (t)) { cp_pedwarn ("default argument specified in explicit specialization"); break; } if (current_lang_name == lang_name_c) cp_error ("template specialization with C linkage"); } if (specialization || member_specialization || explicit_instantiation) { tree tmpl = NULL_TREE; tree targs = NULL_TREE; /* Make sure that the declarator is a TEMPLATE_ID_EXPR. */ if (TREE_CODE (declarator) != TEMPLATE_ID_EXPR) { tree fns; my_friendly_assert (TREE_CODE (declarator) == IDENTIFIER_NODE, 0); if (!ctype) fns = IDENTIFIER_NAMESPACE_VALUE (dname); else fns = dname; declarator = lookup_template_function (fns, NULL_TREE); } if (declarator == error_mark_node) return error_mark_node; if (ctype != NULL_TREE && TYPE_BEING_DEFINED (ctype)) { if (!explicit_instantiation) /* A specialization in class scope. This is illegal, but the error will already have been flagged by check_specialization_scope. */ return error_mark_node; else { /* It's not legal to write an explicit instantiation in class scope, e.g.: class C { template void f(); } This case is caught by the parser. However, on something like: template class C { void f(); }; (which is illegal) we can get here. The error will be issued later. */ ; } return decl; } else if (TREE_CODE (TREE_OPERAND (declarator, 0)) == LOOKUP_EXPR) { /* A friend declaration. We can't do much, because we don't know what this resolves to, yet. */ my_friendly_assert (is_friend != 0, 0); my_friendly_assert (!explicit_instantiation, 0); SET_DECL_IMPLICIT_INSTANTIATION (decl); return decl; } else if (ctype != NULL_TREE && (TREE_CODE (TREE_OPERAND (declarator, 0)) == IDENTIFIER_NODE)) { /* Find the list of functions in ctype that have the same name as the declared function. */ tree name = TREE_OPERAND (declarator, 0); tree fns = NULL_TREE; int idx; if (name == constructor_name (ctype) || name == constructor_name_full (ctype)) { int is_constructor = DECL_CONSTRUCTOR_P (decl); if (is_constructor ? !TYPE_HAS_CONSTRUCTOR (ctype) : !TYPE_HAS_DESTRUCTOR (ctype)) { /* From [temp.expl.spec]: If such an explicit specialization for the member of a class template names an implicitly-declared special member function (clause _special_), the program is ill-formed. Similar language is found in [temp.explicit]. */ cp_error ("specialization of implicitly-declared special member function"); return error_mark_node; } name = is_constructor ? ctor_identifier : dtor_identifier; } if (!IDENTIFIER_TYPENAME_P (name)) { idx = lookup_fnfields_1 (ctype, name); if (idx >= 0) fns = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (ctype), idx); } else { tree methods; /* For a type-conversion operator, we cannot do a name-based lookup. We might be looking for `operator int' which will be a specialization of `operator T'. So, we find *all* the conversion operators, and then select from them. */ fns = NULL_TREE; methods = CLASSTYPE_METHOD_VEC (ctype); if (methods) for (idx = 2; idx < TREE_VEC_LENGTH (methods); ++idx) { tree ovl = TREE_VEC_ELT (methods, idx); if (!ovl || !DECL_CONV_FN_P (OVL_CURRENT (ovl))) /* There are no more conversion functions. */ break; /* Glue all these conversion functions together with those we already have. */ for (; ovl; ovl = OVL_NEXT (ovl)) fns = ovl_cons (OVL_CURRENT (ovl), fns); } } if (fns == NULL_TREE) { cp_error ("no member function `%D' declared in `%T'", name, ctype); return error_mark_node; } else TREE_OPERAND (declarator, 0) = fns; } /* Figure out what exactly is being specialized at this point. Note that for an explicit instantiation, even one for a member function, we cannot tell apriori whether the instantiation is for a member template, or just a member function of a template class. Even if a member template is being instantiated, the member template arguments may be elided if they can be deduced from the rest of the declaration. */ tmpl = determine_specialization (declarator, decl, &targs, member_specialization); if (!tmpl || tmpl == error_mark_node) /* We couldn't figure out what this declaration was specializing. */ return error_mark_node; else { tree gen_tmpl = most_general_template (tmpl); if (explicit_instantiation) { /* We don't set DECL_EXPLICIT_INSTANTIATION here; that is done by do_decl_instantiation later. */ int arg_depth = TMPL_ARGS_DEPTH (targs); int parm_depth = TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl)); if (arg_depth > parm_depth) { /* If TMPL is not the most general template (for example, if TMPL is a friend template that is injected into namespace scope), then there will be too many levels fo TARGS. Remove some of them here. */ int i; tree new_targs; new_targs = make_temp_vec (parm_depth); for (i = arg_depth - parm_depth; i < arg_depth; ++i) TREE_VEC_ELT (new_targs, i - (arg_depth - parm_depth)) = TREE_VEC_ELT (targs, i); targs = new_targs; } decl = instantiate_template (tmpl, targs); return decl; } /* If we though that the DECL was a member function, but it turns out to be specializing a static member function, make DECL a static member function as well. */ if (DECL_STATIC_FUNCTION_P (tmpl) && DECL_NONSTATIC_MEMBER_FUNCTION_P (decl)) { revert_static_member_fn (&decl, 0, 0); last_function_parms = TREE_CHAIN (last_function_parms); } /* Set up the DECL_TEMPLATE_INFO for DECL. */ DECL_TEMPLATE_INFO (decl) = perm_tree_cons (tmpl, targs, NULL_TREE); /* Mangle the function name appropriately. Note that we do not mangle specializations of non-template member functions of template classes, e.g. with template struct S { void f(); } and given the specialization template <> void S::f() {} we do not mangle S::f() here. That's because it's just an ordinary member function and doesn't need special treatment. We do this here so that the ordinary, non-template, name-mangling algorith will not be used later. */ if ((is_member_template (tmpl) || ctype == NULL_TREE) && name_mangling_version >= 1) set_mangled_name_for_template_decl (decl); if (is_friend && !have_def) /* This is not really a declaration of a specialization. It's just the name of an instantiation. But, it's not a request for an instantiation, either. */ SET_DECL_IMPLICIT_INSTANTIATION (decl); /* Register this specialization so that we can find it again. */ decl = register_specialization (decl, gen_tmpl, targs); } } return decl; } /* TYPE is being declared. Verify that the use of template headers and such is reasonable. Issue error messages if not. */ void maybe_check_template_type (type) tree type; { if (template_header_count) { /* We are in the scope of some `template <...>' header. */ int context_depth = template_class_depth_real (TYPE_CONTEXT (type), /*count_specializations=*/1); if (template_header_count <= context_depth) /* This is OK; the template headers are for the context. We are actually too lenient here; like check_explicit_specialization we should consider the number of template types included in the actual declaration. For example, template struct S { template template struct I {}; }; is illegal, but: template struct S { template struct I; }; template template ::I {}; is not. */ ; else if (template_header_count > context_depth + 1) /* There are two many template parameter lists. */ cp_error ("too many template parameter lists in declaration of `%T'", type); } } /* Returns 1 iff PARMS1 and PARMS2 are identical sets of template parameters. These are represented in the same format used for DECL_TEMPLATE_PARMS. */ int comp_template_parms (parms1, parms2) tree parms1; tree parms2; { tree p1; tree p2; if (parms1 == parms2) return 1; for (p1 = parms1, p2 = parms2; p1 != NULL_TREE && p2 != NULL_TREE; p1 = TREE_CHAIN (p1), p2 = TREE_CHAIN (p2)) { tree t1 = TREE_VALUE (p1); tree t2 = TREE_VALUE (p2); int i; my_friendly_assert (TREE_CODE (t1) == TREE_VEC, 0); my_friendly_assert (TREE_CODE (t2) == TREE_VEC, 0); if (TREE_VEC_LENGTH (t1) != TREE_VEC_LENGTH (t2)) return 0; for (i = 0; i < TREE_VEC_LENGTH (t2); ++i) { tree parm1 = TREE_VALUE (TREE_VEC_ELT (t1, i)); tree parm2 = TREE_VALUE (TREE_VEC_ELT (t2, i)); if (TREE_CODE (parm1) != TREE_CODE (parm2)) return 0; if (TREE_CODE (parm1) == TEMPLATE_TYPE_PARM) continue; else if (!same_type_p (TREE_TYPE (parm1), TREE_TYPE (parm2))) return 0; } } if ((p1 != NULL_TREE) != (p2 != NULL_TREE)) /* One set of parameters has more parameters lists than the other. */ return 0; return 1; } /* Complain if DECL shadows a template parameter. [temp.local]: A template-parameter shall not be redeclared within its scope (including nested scopes). */ void check_template_shadow (decl) tree decl; { tree olddecl; /* If we're not in a template, we can't possibly shadow a template parameter. */ if (!current_template_parms) return; /* Figure out what we're shadowing. */ if (TREE_CODE (decl) == OVERLOAD) decl = OVL_CURRENT (decl); olddecl = IDENTIFIER_VALUE (DECL_NAME (decl)); /* If there's no previous binding for this name, we're not shadowing anything, let alone a template parameter. */ if (!olddecl) return; /* If we're not shadowing a template parameter, we're done. Note that OLDDECL might be an OVERLOAD (or perhaps even an ERROR_MARK), so we can't just blithely assume it to be a _DECL node. */ if (TREE_CODE_CLASS (TREE_CODE (olddecl)) != 'd' || !DECL_TEMPLATE_PARM_P (olddecl)) return; /* We check for decl != olddecl to avoid bogus errors for using a name inside a class. We check TPFI to avoid duplicate errors for inline member templates. */ if (decl == olddecl || TEMPLATE_PARMS_FOR_INLINE (current_template_parms)) return; cp_error_at ("declaration of `%#D'", decl); cp_error_at (" shadows template parm `%#D'", olddecl); } /* Return a new TEMPLATE_PARM_INDEX with the indicated INDEX, LEVEL, ORIG_LEVEL, DECL, and TYPE. */ static tree build_template_parm_index (index, level, orig_level, decl, type) int index; int level; int orig_level; tree decl; tree type; { tree t = make_node (TEMPLATE_PARM_INDEX); TEMPLATE_PARM_IDX (t) = index; TEMPLATE_PARM_LEVEL (t) = level; TEMPLATE_PARM_ORIG_LEVEL (t) = orig_level; TEMPLATE_PARM_DECL (t) = decl; TREE_TYPE (t) = type; return t; } /* Return a TEMPLATE_PARM_INDEX, similar to INDEX, but whose TEMPLATE_PARM_LEVEL has been decreased by LEVELS. If such a TEMPLATE_PARM_INDEX already exists, it is returned; otherwise, a new one is created. */ static tree reduce_template_parm_level (index, type, levels) tree index; tree type; int levels; { if (TEMPLATE_PARM_DESCENDANTS (index) == NULL_TREE || (TEMPLATE_PARM_LEVEL (TEMPLATE_PARM_DESCENDANTS (index)) != TEMPLATE_PARM_LEVEL (index) - levels)) { tree decl = build_decl (TREE_CODE (TEMPLATE_PARM_DECL (index)), DECL_NAME (TEMPLATE_PARM_DECL (index)), type); tree t = build_template_parm_index (TEMPLATE_PARM_IDX (index), TEMPLATE_PARM_LEVEL (index) - levels, TEMPLATE_PARM_ORIG_LEVEL (index), decl, type); TEMPLATE_PARM_DESCENDANTS (index) = t; /* Template template parameters need this. */ DECL_TEMPLATE_PARMS (decl) = DECL_TEMPLATE_PARMS (TEMPLATE_PARM_DECL (index)); } return TEMPLATE_PARM_DESCENDANTS (index); } /* Process information from new template parameter NEXT and append it to the LIST being built. */ tree process_template_parm (list, next) tree list, next; { tree parm; tree decl = 0; tree defval; int is_type, idx; parm = next; my_friendly_assert (TREE_CODE (parm) == TREE_LIST, 259); defval = TREE_PURPOSE (parm); parm = TREE_VALUE (parm); is_type = TREE_PURPOSE (parm) == class_type_node; if (list) { tree p = TREE_VALUE (tree_last (list)); if (TREE_CODE (p) == TYPE_DECL) idx = TEMPLATE_TYPE_IDX (TREE_TYPE (p)); else if (TREE_CODE (p) == TEMPLATE_DECL) idx = TEMPLATE_TYPE_IDX (TREE_TYPE (DECL_TEMPLATE_RESULT (p))); else idx = TEMPLATE_PARM_IDX (DECL_INITIAL (p)); ++idx; } else idx = 0; if (!is_type) { my_friendly_assert (TREE_CODE (TREE_PURPOSE (parm)) == TREE_LIST, 260); /* is a const-param */ parm = grokdeclarator (TREE_VALUE (parm), TREE_PURPOSE (parm), PARM, 0, NULL_TREE); /* [temp.param] The top-level cv-qualifiers on the template-parameter are ignored when determining its type. */ TREE_TYPE (parm) = TYPE_MAIN_VARIANT (TREE_TYPE (parm)); /* A template parameter is not modifiable. */ TREE_READONLY (parm) = 1; if (IS_AGGR_TYPE (TREE_TYPE (parm)) && TREE_CODE (TREE_TYPE (parm)) != TEMPLATE_TYPE_PARM && TREE_CODE (TREE_TYPE (parm)) != TYPENAME_TYPE) { cp_error ("`%#T' is not a valid type for a template constant parameter", TREE_TYPE (parm)); if (DECL_NAME (parm) == NULL_TREE) error (" a template type parameter must begin with `class' or `typename'"); TREE_TYPE (parm) = void_type_node; } else if (pedantic && (TREE_CODE (TREE_TYPE (parm)) == REAL_TYPE || TREE_CODE (TREE_TYPE (parm)) == COMPLEX_TYPE)) cp_pedwarn ("`%T' is not a valid type for a template constant parameter", TREE_TYPE (parm)); if (TREE_PERMANENT (parm) == 0) { parm = copy_node (parm); TREE_PERMANENT (parm) = 1; } decl = build_decl (CONST_DECL, DECL_NAME (parm), TREE_TYPE (parm)); DECL_INITIAL (parm) = DECL_INITIAL (decl) = build_template_parm_index (idx, processing_template_decl, processing_template_decl, decl, TREE_TYPE (parm)); } else { tree t; parm = TREE_VALUE (parm); if (parm && TREE_CODE (parm) == TEMPLATE_DECL) { t = make_lang_type (TEMPLATE_TEMPLATE_PARM); /* This is for distinguishing between real templates and template template parameters */ TREE_TYPE (parm) = t; TREE_TYPE (DECL_TEMPLATE_RESULT (parm)) = t; decl = parm; } else { t = make_lang_type (TEMPLATE_TYPE_PARM); /* parm is either IDENTIFIER_NODE or NULL_TREE */ decl = build_decl (TYPE_DECL, parm, t); } TYPE_NAME (t) = decl; TYPE_STUB_DECL (t) = decl; parm = decl; TEMPLATE_TYPE_PARM_INDEX (t) = build_template_parm_index (idx, processing_template_decl, processing_template_decl, decl, TREE_TYPE (parm)); } SET_DECL_ARTIFICIAL (decl); DECL_TEMPLATE_PARM_P (decl) = 1; pushdecl (decl); parm = build_tree_list (defval, parm); return chainon (list, parm); } /* The end of a template parameter list has been reached. Process the tree list into a parameter vector, converting each parameter into a more useful form. Type parameters are saved as IDENTIFIER_NODEs, and others as PARM_DECLs. */ tree end_template_parm_list (parms) tree parms; { int nparms; tree parm; tree saved_parmlist = make_tree_vec (list_length (parms)); current_template_parms = tree_cons (build_int_2 (0, processing_template_decl), saved_parmlist, current_template_parms); for (parm = parms, nparms = 0; parm; parm = TREE_CHAIN (parm), nparms++) TREE_VEC_ELT (saved_parmlist, nparms) = parm; --processing_template_parmlist; return saved_parmlist; } /* end_template_decl is called after a template declaration is seen. */ void end_template_decl () { reset_specialization (); if (! processing_template_decl) return; /* This matches the pushlevel in begin_template_parm_list. */ poplevel (0, 0, 0); --processing_template_decl; current_template_parms = TREE_CHAIN (current_template_parms); (void) get_pending_sizes (); /* Why? */ } /* Given a template argument vector containing the template PARMS. The innermost PARMS are given first. */ tree current_template_args () { tree header; tree args = NULL_TREE; int length = TMPL_PARMS_DEPTH (current_template_parms); int l = length; /* If there is only one level of template parameters, we do not create a TREE_VEC of TREE_VECs. Instead, we return a single TREE_VEC containing the arguments. */ if (length > 1) args = make_tree_vec (length); for (header = current_template_parms; header; header = TREE_CHAIN (header)) { tree a = copy_node (TREE_VALUE (header)); int i; TREE_TYPE (a) = NULL_TREE; for (i = TREE_VEC_LENGTH (a) - 1; i >= 0; --i) { tree t = TREE_VEC_ELT (a, i); /* T will be a list if we are called from within a begin/end_template_parm_list pair, but a vector directly if within a begin/end_member_template_processing pair. */ if (TREE_CODE (t) == TREE_LIST) { t = TREE_VALUE (t); if (TREE_CODE (t) == TYPE_DECL || TREE_CODE (t) == TEMPLATE_DECL) t = TREE_TYPE (t); else t = DECL_INITIAL (t); TREE_VEC_ELT (a, i) = t; } } if (length > 1) TREE_VEC_ELT (args, --l) = a; else args = a; } return args; } /* Return a TEMPLATE_DECL corresponding to DECL, using the indicated template PARMS. Used by push_template_decl below. */ static tree build_template_decl (decl, parms) tree decl; tree parms; { tree tmpl = build_lang_decl (TEMPLATE_DECL, DECL_NAME (decl), NULL_TREE); DECL_TEMPLATE_PARMS (tmpl) = parms; DECL_CONTEXT (tmpl) = DECL_CONTEXT (decl); if (DECL_LANG_SPECIFIC (decl)) { DECL_CLASS_CONTEXT (tmpl) = DECL_CLASS_CONTEXT (decl); DECL_STATIC_FUNCTION_P (tmpl) = DECL_STATIC_FUNCTION_P (decl); DECL_CONSTRUCTOR_P (tmpl) = DECL_CONSTRUCTOR_P (decl); } return tmpl; } struct template_parm_data { /* The level of the template parameters we are currently processing. */ int level; /* The index of the specialization argument we are currently processing. */ int current_arg; /* An array whose size is the number of template parameters. The elements are non-zero if the parameter has been used in any one of the arguments processed so far. */ int* parms; /* An array whose size is the number of template arguments. The elements are non-zero if the argument makes use of template parameters of this level. */ int* arg_uses_template_parms; }; /* Subroutine of push_template_decl used to see if each template parameter in a partial specialization is used in the explicit argument list. If T is of the LEVEL given in DATA (which is treated as a template_parm_data*), then DATA->PARMS is marked appropriately. */ static int mark_template_parm (t, data) tree t; void* data; { int level; int idx; struct template_parm_data* tpd = (struct template_parm_data*) data; if (TREE_CODE (t) == TEMPLATE_PARM_INDEX) { level = TEMPLATE_PARM_LEVEL (t); idx = TEMPLATE_PARM_IDX (t); } else { level = TEMPLATE_TYPE_LEVEL (t); idx = TEMPLATE_TYPE_IDX (t); } if (level == tpd->level) { tpd->parms[idx] = 1; tpd->arg_uses_template_parms[tpd->current_arg] = 1; } /* Return zero so that for_each_template_parm will continue the traversal of the tree; we want to mark *every* template parm. */ return 0; } /* Process the partial specialization DECL. */ static tree process_partial_specialization (decl) tree decl; { tree type = TREE_TYPE (decl); tree maintmpl = CLASSTYPE_TI_TEMPLATE (type); tree specargs = CLASSTYPE_TI_ARGS (type); tree inner_args = innermost_args (specargs); tree inner_parms = INNERMOST_TEMPLATE_PARMS (current_template_parms); tree main_inner_parms = DECL_INNERMOST_TEMPLATE_PARMS (maintmpl); int nargs = TREE_VEC_LENGTH (inner_args); int ntparms = TREE_VEC_LENGTH (inner_parms); int i; int did_error_intro = 0; struct template_parm_data tpd; struct template_parm_data tpd2; /* We check that each of the template parameters given in the partial specialization is used in the argument list to the specialization. For example: template struct S; template struct S; The second declaration is OK because `T*' uses the template parameter T, whereas template struct S; is no good. Even trickier is: template struct S1 { template struct S2; template struct S2; }; The S2 declaration is actually illegal; it is a full-specialization. Of course, template struct S2; or some such would have been OK. */ tpd.level = TMPL_PARMS_DEPTH (current_template_parms); tpd.parms = alloca (sizeof (int) * ntparms); bzero ((PTR) tpd.parms, sizeof (int) * ntparms); tpd.arg_uses_template_parms = alloca (sizeof (int) * nargs); bzero ((PTR) tpd.arg_uses_template_parms, sizeof (int) * nargs); for (i = 0; i < nargs; ++i) { tpd.current_arg = i; for_each_template_parm (TREE_VEC_ELT (inner_args, i), &mark_template_parm, &tpd); } for (i = 0; i < ntparms; ++i) if (tpd.parms[i] == 0) { /* One of the template parms was not used in the specialization. */ if (!did_error_intro) { cp_error ("template parameters not used in partial specialization:"); did_error_intro = 1; } cp_error (" `%D'", TREE_VALUE (TREE_VEC_ELT (inner_parms, i))); } /* [temp.class.spec] The argument list of the specialization shall not be identical to the implicit argument list of the primary template. */ if (comp_template_args (inner_args, innermost_args (CLASSTYPE_TI_ARGS (TREE_TYPE (maintmpl))))) cp_error ("partial specialization `%T' does not specialize any template arguments", type); /* [temp.class.spec] A partially specialized non-type argument expression shall not involve template parameters of the partial specialization except when the argument expression is a simple identifier. The type of a template parameter corresponding to a specialized non-type argument shall not be dependent on a parameter of the specialization. */ my_friendly_assert (nargs == DECL_NTPARMS (maintmpl), 0); tpd2.parms = 0; for (i = 0; i < nargs; ++i) { tree arg = TREE_VEC_ELT (inner_args, i); if (/* These first two lines are the `non-type' bit. */ TREE_CODE_CLASS (TREE_CODE (arg)) != 't' && TREE_CODE (arg) != TEMPLATE_DECL /* This next line is the `argument expression is not just a simple identifier' condition and also the `specialized non-type argument' bit. */ && TREE_CODE (arg) != TEMPLATE_PARM_INDEX) { if (tpd.arg_uses_template_parms[i]) cp_error ("template argument `%E' involves template parameter(s)", arg); else { /* Look at the corresponding template parameter, marking which template parameters its type depends upon. */ tree type = TREE_TYPE (TREE_VALUE (TREE_VEC_ELT (main_inner_parms, i))); if (!tpd2.parms) { /* We haven't yet initialized TPD2. Do so now. */ tpd2.arg_uses_template_parms = (int*) alloca (sizeof (int) * nargs); /* The number of parameters here is the number in the main template, which, as checked in the assertion above, is NARGS. */ tpd2.parms = (int*) alloca (sizeof (int) * nargs); tpd2.level = TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (maintmpl)); } /* Mark the template parameters. But this time, we're looking for the template parameters of the main template, not in the specialization. */ tpd2.current_arg = i; tpd2.arg_uses_template_parms[i] = 0; bzero ((PTR) tpd2.parms, sizeof (int) * nargs); for_each_template_parm (type, &mark_template_parm, &tpd2); if (tpd2.arg_uses_template_parms [i]) { /* The type depended on some template parameters. If they are fully specialized in the specialization, that's OK. */ int j; for (j = 0; j < nargs; ++j) if (tpd2.parms[j] != 0 && tpd.arg_uses_template_parms [j]) { cp_error ("type `%T' of template argument `%E' depends on template parameter(s)", type, arg); break; } } } } } if (retrieve_specialization (maintmpl, specargs)) /* We've already got this specialization. */ return decl; DECL_TEMPLATE_SPECIALIZATIONS (maintmpl) = CLASSTYPE_TI_SPEC_INFO (type) = perm_tree_cons (inner_args, inner_parms, DECL_TEMPLATE_SPECIALIZATIONS (maintmpl)); TREE_TYPE (DECL_TEMPLATE_SPECIALIZATIONS (maintmpl)) = type; return decl; } /* Check that a template declaration's use of default arguments is not invalid. Here, PARMS are the template parameters. IS_PRIMARY is non-zero if DECL is the thing declared by a primary template. IS_PARTIAL is non-zero if DECL is a partial specialization. */ static void check_default_tmpl_args (decl, parms, is_primary, is_partial) tree decl; tree parms; int is_primary; int is_partial; { const char *msg; int last_level_to_check; /* [temp.param] A default template-argument shall not be specified in a function template declaration or a function template definition, nor in the template-parameter-list of the definition of a member of a class template. */ if (current_class_type && !TYPE_BEING_DEFINED (current_class_type) && DECL_LANG_SPECIFIC (decl) /* If this is either a friend defined in the scope of the class or a member function. */ && DECL_CLASS_CONTEXT (decl) == current_class_type /* And, if it was a member function, it really was defined in the scope of the class. */ && (!DECL_FUNCTION_MEMBER_P (decl) || DECL_DEFINED_IN_CLASS_P (decl))) /* We already checked these parameters when the template was declared, so there's no need to do it again now. This function was defined in class scope, but we're processing it's body now that the class is complete. */ return; if (TREE_CODE (decl) != TYPE_DECL || is_partial || !is_primary) /* For an ordinary class template, default template arguments are allowed at the innermost level, e.g.: template struct S {}; but, in a partial specialization, they're not allowed even there, as we have in [temp.class.spec]: The template parameter list of a specialization shall not contain default template argument values. So, for a partial specialization, or for a function template, we look at all of them. */ ; else /* But, for a primary class template that is not a partial specialization we look at all template parameters except the innermost ones. */ parms = TREE_CHAIN (parms); /* Figure out what error message to issue. */ if (TREE_CODE (decl) == FUNCTION_DECL) msg = "default argument for template parameter in function template `%D'"; else if (is_partial) msg = "default argument in partial specialization `%D'"; else msg = "default argument for template parameter for class enclosing `%D'"; if (current_class_type && TYPE_BEING_DEFINED (current_class_type)) /* If we're inside a class definition, there's no need to examine the parameters to the class itself. On the one hand, they will be checked when the class is defined, and, on the other, default arguments are legal in things like: template struct S { template void f(U); }; Here the default argument for `S' has no bearing on the declaration of `f'. */ last_level_to_check = template_class_depth (current_class_type) + 1; else /* Check everything. */ last_level_to_check = 0; for (; parms && TMPL_PARMS_DEPTH (parms) >= last_level_to_check; parms = TREE_CHAIN (parms)) { tree inner_parms = TREE_VALUE (parms); int i, ntparms; ntparms = TREE_VEC_LENGTH (inner_parms); for (i = 0; i < ntparms; ++i) if (TREE_PURPOSE (TREE_VEC_ELT (inner_parms, i))) { if (msg) { cp_error (msg, decl); msg = 0; } /* Clear out the default argument so that we are not confused later. */ TREE_PURPOSE (TREE_VEC_ELT (inner_parms, i)) = NULL_TREE; } /* At this point, if we're still interested in issuing messages, they must apply to classes surrounding the object declared. */ if (msg) msg = "default argument for template parameter for class enclosing `%D'"; } } /* Creates a TEMPLATE_DECL for the indicated DECL using the template parameters given by current_template_args, or reuses a previously existing one, if appropriate. Returns the DECL, or an equivalent one, if it is replaced via a call to duplicate_decls. If IS_FRIEND is non-zero, DECL is a friend declaration. */ tree push_template_decl_real (decl, is_friend) tree decl; int is_friend; { tree tmpl; tree args; tree info; tree ctx; int primary; int is_partial; /* See if this is a partial specialization. */ is_partial = (TREE_CODE (decl) == TYPE_DECL && DECL_ARTIFICIAL (decl) && TREE_CODE (TREE_TYPE (decl)) != ENUMERAL_TYPE && CLASSTYPE_TEMPLATE_SPECIALIZATION (TREE_TYPE (decl))); is_friend |= (TREE_CODE (decl) == FUNCTION_DECL && DECL_FRIEND_P (decl)); if (is_friend) /* For a friend, we want the context of the friend function, not the type of which it is a friend. */ ctx = DECL_CONTEXT (decl); else if (DECL_REAL_CONTEXT (decl) && TREE_CODE (DECL_REAL_CONTEXT (decl)) != NAMESPACE_DECL) /* In the case of a virtual function, we want the class in which it is defined. */ ctx = DECL_REAL_CONTEXT (decl); else /* Otherwise, if we're currently definining some class, the DECL is assumed to be a member of the class. */ ctx = current_class_type; if (ctx && TREE_CODE (ctx) == NAMESPACE_DECL) ctx = NULL_TREE; if (!DECL_CONTEXT (decl)) DECL_CONTEXT (decl) = FROB_CONTEXT (current_namespace); /* For determining whether this is a primary template or not, we're really interested in the lexical context, not the true context. */ if (is_friend) info = current_class_type; else info = ctx; /* See if this is a primary template. */ if (info && TREE_CODE (info) == FUNCTION_DECL) primary = 0; /* Note that template_class_depth returns 0 if given NULL_TREE, so this next line works even when we are at global scope. */ else if (processing_template_decl > template_class_depth (info)) primary = 1; else primary = 0; if (primary) { if (current_lang_name == lang_name_c) cp_error ("template with C linkage"); if (TREE_CODE (decl) == TYPE_DECL && ANON_AGGRNAME_P (DECL_NAME (decl))) cp_error ("template class without a name"); if (TREE_CODE (decl) == TYPE_DECL && TREE_CODE (TREE_TYPE (decl)) == ENUMERAL_TYPE) cp_error ("template declaration of `%#T'", TREE_TYPE (decl)); } /* Check to see that the rules regarding the use of default arguments are not being violated. */ check_default_tmpl_args (decl, current_template_parms, primary, is_partial); if (is_partial) return process_partial_specialization (decl); args = current_template_args (); if (!ctx || TREE_CODE (ctx) == FUNCTION_DECL || TYPE_BEING_DEFINED (ctx) || (is_friend && !DECL_TEMPLATE_INFO (decl))) { if (DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl) && DECL_TI_TEMPLATE (decl)) tmpl = DECL_TI_TEMPLATE (decl); else { tmpl = build_template_decl (decl, current_template_parms); if (DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_SPECIALIZATION (decl)) { /* A specialization of a member template of a template class. */ SET_DECL_TEMPLATE_SPECIALIZATION (tmpl); DECL_TEMPLATE_INFO (tmpl) = DECL_TEMPLATE_INFO (decl); DECL_TEMPLATE_INFO (decl) = NULL_TREE; } } } else { tree a, t, current, parms; int i; if (CLASSTYPE_TEMPLATE_INSTANTIATION (ctx)) cp_error ("must specialize `%#T' before defining member `%#D'", ctx, decl); if (TREE_CODE (decl) == TYPE_DECL) { if ((IS_AGGR_TYPE_CODE (TREE_CODE (TREE_TYPE (decl))) || TREE_CODE (TREE_TYPE (decl)) == ENUMERAL_TYPE) && TYPE_TEMPLATE_INFO (TREE_TYPE (decl)) && TYPE_TI_TEMPLATE (TREE_TYPE (decl))) tmpl = TYPE_TI_TEMPLATE (TREE_TYPE (decl)); else { cp_error ("`%D' does not declare a template type", decl); return decl; } } else if (! DECL_TEMPLATE_INFO (decl)) { cp_error ("template definition of non-template `%#D'", decl); return decl; } else tmpl = DECL_TI_TEMPLATE (decl); if (is_member_template (tmpl) && DECL_FUNCTION_TEMPLATE_P (tmpl) && DECL_TEMPLATE_INFO (decl) && DECL_TI_ARGS (decl) && DECL_TEMPLATE_SPECIALIZATION (decl)) { tree new_tmpl; /* The declaration is a specialization of a member template, declared outside the class. Therefore, the innermost template arguments will be NULL, so we replace them with the arguments determined by the earlier call to check_explicit_specialization. */ args = DECL_TI_ARGS (decl); new_tmpl = build_template_decl (decl, current_template_parms); DECL_TEMPLATE_RESULT (new_tmpl) = decl; TREE_TYPE (new_tmpl) = TREE_TYPE (decl); DECL_TI_TEMPLATE (decl) = new_tmpl; SET_DECL_TEMPLATE_SPECIALIZATION (new_tmpl); DECL_TEMPLATE_INFO (new_tmpl) = perm_tree_cons (tmpl, args, NULL_TREE); register_specialization (new_tmpl, tmpl, args); return decl; } /* Make sure the template headers we got make sense. */ parms = DECL_TEMPLATE_PARMS (tmpl); i = TMPL_PARMS_DEPTH (parms); if (TMPL_ARGS_DEPTH (args) != i) { cp_error ("expected %d levels of template parms for `%#D', got %d", i, decl, TMPL_ARGS_DEPTH (args)); } else for (current = decl; i > 0; --i, parms = TREE_CHAIN (parms)) { a = TMPL_ARGS_LEVEL (args, i); t = INNERMOST_TEMPLATE_PARMS (parms); if (TREE_VEC_LENGTH (t) != TREE_VEC_LENGTH (a)) { if (current == decl) cp_error ("got %d template parameters for `%#D'", TREE_VEC_LENGTH (a), decl); else cp_error ("got %d template parameters for `%#T'", TREE_VEC_LENGTH (a), current); cp_error (" but %d required", TREE_VEC_LENGTH (t)); } /* Perhaps we should also check that the parms are used in the appropriate qualifying scopes in the declarator? */ if (current == decl) current = ctx; else current = TYPE_CONTEXT (current); } } DECL_TEMPLATE_RESULT (tmpl) = decl; TREE_TYPE (tmpl) = TREE_TYPE (decl); /* Push template declarations for global functions and types. Note that we do not try to push a global template friend declared in a template class; such a thing may well depend on the template parameters of the class. */ if (! ctx && !(is_friend && template_class_depth (current_class_type) > 0)) tmpl = pushdecl_namespace_level (tmpl); if (primary) DECL_PRIMARY_TEMPLATE (tmpl) = tmpl; info = perm_tree_cons (tmpl, args, NULL_TREE); if (TREE_CODE (decl) == TYPE_DECL && DECL_ARTIFICIAL (decl)) { SET_TYPE_TEMPLATE_INFO (TREE_TYPE (tmpl), info); if ((!ctx || TREE_CODE (ctx) != FUNCTION_DECL) && TREE_CODE (TREE_TYPE (decl)) != ENUMERAL_TYPE) DECL_NAME (decl) = classtype_mangled_name (TREE_TYPE (decl)); } else if (! DECL_LANG_SPECIFIC (decl)) cp_error ("template declaration of `%#D'", decl); else DECL_TEMPLATE_INFO (decl) = info; return DECL_TEMPLATE_RESULT (tmpl); } tree push_template_decl (decl) tree decl; { return push_template_decl_real (decl, 0); } /* Called when a class template TYPE is redeclared with the indicated template PARMS, e.g.: template struct S; template struct S {}; */ void redeclare_class_template (type, parms) tree type; tree parms; { tree tmpl; tree tmpl_parms; int i; if (!TYPE_TEMPLATE_INFO (type)) { cp_error ("`%T' is not a template type", type); return; } tmpl = TYPE_TI_TEMPLATE (type); if (!PRIMARY_TEMPLATE_P (tmpl)) /* The type is nested in some template class. Nothing to worry about here; there are no new template parameters for the nested type. */ return; parms = INNERMOST_TEMPLATE_PARMS (parms); tmpl_parms = DECL_INNERMOST_TEMPLATE_PARMS (tmpl); if (TREE_VEC_LENGTH (parms) != TREE_VEC_LENGTH (tmpl_parms)) { cp_error_at ("previous declaration `%D'", tmpl); cp_error ("used %d template parameter%s instead of %d", TREE_VEC_LENGTH (tmpl_parms), TREE_VEC_LENGTH (tmpl_parms) == 1 ? "" : "s", TREE_VEC_LENGTH (parms)); return; } for (i = 0; i < TREE_VEC_LENGTH (tmpl_parms); ++i) { tree tmpl_parm = TREE_VALUE (TREE_VEC_ELT (tmpl_parms, i)); tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i)); tree tmpl_default = TREE_PURPOSE (TREE_VEC_ELT (tmpl_parms, i)); tree parm_default = TREE_PURPOSE (TREE_VEC_ELT (parms, i)); if (TREE_CODE (tmpl_parm) != TREE_CODE (parm)) { cp_error_at ("template parameter `%#D'", tmpl_parm); cp_error ("redeclared here as `%#D'", parm); return; } if (tmpl_default != NULL_TREE && parm_default != NULL_TREE) { /* We have in [temp.param]: A template-parameter may not be given default arguments by two different declarations in the same scope. */ cp_error ("redefinition of default argument for `%#D'", parm); cp_error_at (" original definition appeared here", tmpl_parm); return; } if (parm_default != NULL_TREE) /* Update the previous template parameters (which are the ones that will really count) with the new default value. */ TREE_PURPOSE (TREE_VEC_ELT (tmpl_parms, i)) = parm_default; } } /* Attempt to convert the non-type template parameter EXPR to the indicated TYPE. If the conversion is successful, return the converted value. If the conversion is unsuccesful, return NULL_TREE if we issued an error message, or error_mark_node if we did not. We issue error messages for out-and-out bad template parameters, but not simply because the conversion failed, since we might be just trying to do argument deduction. By the time this function is called, neither TYPE nor EXPR may make use of template parameters. */ static tree convert_nontype_argument (type, expr) tree type; tree expr; { tree expr_type = TREE_TYPE (expr); /* A template-argument for a non-type, non-template template-parameter shall be one of: --an integral constant-expression of integral or enumeration type; or --the name of a non-type template-parameter; or --the name of an object or function with external linkage, including function templates and function template-ids but excluding non-static class members, expressed as id-expression; or --the address of an object or function with external linkage, including function templates and function template-ids but excluding non-static class members, expressed as & id-expression where the & is optional if the name refers to a function or array; or --a pointer to member expressed as described in _expr.unary.op_. */ /* An integral constant-expression can include const variables or enumerators. */ if (INTEGRAL_TYPE_P (expr_type) && TREE_READONLY_DECL_P (expr)) expr = decl_constant_value (expr); if (is_overloaded_fn (expr)) /* OK for now. We'll check that it has external linkage later. Check this first since if expr_type is the unknown_type_node we would otherwise complain below. */ ; else if (TYPE_PTRMEM_P (expr_type) || TYPE_PTRMEMFUNC_P (expr_type)) { if (TREE_CODE (expr) != PTRMEM_CST) goto bad_argument; } else if (TYPE_PTR_P (expr_type) || TYPE_PTRMEM_P (expr_type) || TREE_CODE (expr_type) == ARRAY_TYPE || TREE_CODE (type) == REFERENCE_TYPE /* If expr is the address of an overloaded function, we will get the unknown_type_node at this point. */ || expr_type == unknown_type_node) { tree referent; tree e = expr; STRIP_NOPS (e); if (TREE_CODE (type) == REFERENCE_TYPE || TREE_CODE (expr_type) == ARRAY_TYPE) referent = e; else { if (TREE_CODE (e) != ADDR_EXPR) { bad_argument: cp_error ("`%E' is not a valid template argument", expr); if (TYPE_PTR_P (expr_type)) { if (TREE_CODE (TREE_TYPE (expr_type)) == FUNCTION_TYPE) cp_error ("it must be the address of a function with external linkage"); else cp_error ("it must be the address of an object with external linkage"); } else if (TYPE_PTRMEM_P (expr_type) || TYPE_PTRMEMFUNC_P (expr_type)) cp_error ("it must be a pointer-to-member of the form `&X::Y'"); return NULL_TREE; } referent = TREE_OPERAND (e, 0); STRIP_NOPS (referent); } if (TREE_CODE (referent) == STRING_CST) { cp_error ("string literal %E is not a valid template argument", referent); error ("because it is the address of an object with static linkage"); return NULL_TREE; } if (is_overloaded_fn (referent)) /* We'll check that it has external linkage later. */ ; else if (TREE_CODE (referent) != VAR_DECL) goto bad_argument; else if (!TREE_PUBLIC (referent)) { cp_error ("address of non-extern `%E' cannot be used as template argument", referent); return error_mark_node; } } else if (INTEGRAL_TYPE_P (expr_type) || TYPE_PTRMEM_P (expr_type) || TYPE_PTRMEMFUNC_P (expr_type) /* The next two are g++ extensions. */ || TREE_CODE (expr_type) == REAL_TYPE || TREE_CODE (expr_type) == COMPLEX_TYPE) { if (! TREE_CONSTANT (expr)) { non_constant: cp_error ("non-constant `%E' cannot be used as template argument", expr); return NULL_TREE; } } else { cp_error ("object `%E' cannot be used as template argument", expr); return NULL_TREE; } switch (TREE_CODE (type)) { case INTEGER_TYPE: case BOOLEAN_TYPE: case ENUMERAL_TYPE: /* For a non-type template-parameter of integral or enumeration type, integral promotions (_conv.prom_) and integral conversions (_conv.integral_) are applied. */ if (!INTEGRAL_TYPE_P (expr_type)) return error_mark_node; /* It's safe to call digest_init in this case; we know we're just converting one integral constant expression to another. */ expr = digest_init (type, expr, (tree*) 0); if (TREE_CODE (expr) != INTEGER_CST) /* Curiously, some TREE_CONSTANT integral expressions do not simplify to integer constants. For example, `3 % 0', remains a TRUNC_MOD_EXPR. */ goto non_constant; return expr; case REAL_TYPE: case COMPLEX_TYPE: /* These are g++ extensions. */ if (TREE_CODE (expr_type) != TREE_CODE (type)) return error_mark_node; expr = digest_init (type, expr, (tree*) 0); if (TREE_CODE (expr) != REAL_CST) goto non_constant; return expr; case POINTER_TYPE: { tree type_pointed_to = TREE_TYPE (type); if (TYPE_PTRMEM_P (type)) { tree e; /* For a non-type template-parameter of type pointer to data member, qualification conversions (_conv.qual_) are applied. */ e = perform_qualification_conversions (type, expr); if (TREE_CODE (e) == NOP_EXPR) /* The call to perform_qualification_conversions will insert a NOP_EXPR over EXPR to do express conversion, if necessary. But, that will confuse us if we use this (converted) template parameter to instantiate another template; then the thing will not look like a valid template argument. So, just make a new constant, of the appropriate type. */ e = make_ptrmem_cst (type, PTRMEM_CST_MEMBER (expr)); return e; } else if (TREE_CODE (type_pointed_to) == FUNCTION_TYPE) { /* For a non-type template-parameter of type pointer to function, only the function-to-pointer conversion (_conv.func_) is applied. If the template-argument represents a set of overloaded functions (or a pointer to such), the matching function is selected from the set (_over.over_). */ tree fns; tree fn; if (TREE_CODE (expr) == ADDR_EXPR) fns = TREE_OPERAND (expr, 0); else fns = expr; fn = instantiate_type (type_pointed_to, fns, 0); if (fn == error_mark_node) return error_mark_node; if (!TREE_PUBLIC (fn)) { if (really_overloaded_fn (fns)) return error_mark_node; else goto bad_argument; } expr = build_unary_op (ADDR_EXPR, fn, 0); my_friendly_assert (same_type_p (type, TREE_TYPE (expr)), 0); return expr; } else { /* For a non-type template-parameter of type pointer to object, qualification conversions (_conv.qual_) and the array-to-pointer conversion (_conv.array_) are applied. [Note: In particular, neither the null pointer conversion (_conv.ptr_) nor the derived-to-base conversion (_conv.ptr_) are applied. Although 0 is a valid template-argument for a non-type template-parameter of integral type, it is not a valid template-argument for a non-type template-parameter of pointer type.] The call to decay_conversion performs the array-to-pointer conversion, if appropriate. */ expr = decay_conversion (expr); if (expr == error_mark_node) return error_mark_node; else return perform_qualification_conversions (type, expr); } } break; case REFERENCE_TYPE: { tree type_referred_to = TREE_TYPE (type); if (TREE_CODE (type_referred_to) == FUNCTION_TYPE) { /* For a non-type template-parameter of type reference to function, no conversions apply. If the template-argument represents a set of overloaded functions, the matching function is selected from the set (_over.over_). */ tree fns = expr; tree fn; fn = instantiate_type (type_referred_to, fns, 0); if (fn == error_mark_node) return error_mark_node; if (!TREE_PUBLIC (fn)) { if (really_overloaded_fn (fns)) /* Don't issue an error here; we might get a different function if the overloading had worked out differently. */ return error_mark_node; else goto bad_argument; } my_friendly_assert (same_type_p (type_referred_to, TREE_TYPE (fn)), 0); return fn; } else { /* For a non-type template-parameter of type reference to object, no conversions apply. The type referred to by the reference may be more cv-qualified than the (otherwise identical) type of the template-argument. The template-parameter is bound directly to the template-argument, which must be an lvalue. */ if ((TYPE_MAIN_VARIANT (expr_type) != TYPE_MAIN_VARIANT (type_referred_to)) || !at_least_as_qualified_p (type_referred_to, expr_type) || !real_lvalue_p (expr)) return error_mark_node; else return expr; } } break; case RECORD_TYPE: { if (!TYPE_PTRMEMFUNC_P (type)) /* This handles templates like template void f(); when T is substituted with any class. The second template parameter becomes invalid and the template candidate is rejected. */ return error_mark_node; /* For a non-type template-parameter of type pointer to member function, no conversions apply. If the template-argument represents a set of overloaded member functions, the matching member function is selected from the set (_over.over_). */ if (!TYPE_PTRMEMFUNC_P (expr_type) && expr_type != unknown_type_node) return error_mark_node; if (TREE_CODE (expr) == PTRMEM_CST) { /* A ptr-to-member constant. */ if (!same_type_p (type, expr_type)) return error_mark_node; else return expr; } if (TREE_CODE (expr) != ADDR_EXPR) return error_mark_node; expr = instantiate_type (type, expr, 0); if (expr == error_mark_node) return error_mark_node; my_friendly_assert (same_type_p (type, TREE_TYPE (expr)), 0); return expr; } break; default: /* All non-type parameters must have one of these types. */ my_friendly_abort (0); break; } return error_mark_node; } /* Return 1 if PARM_PARMS and ARG_PARMS matches using rule for template template parameters. Both PARM_PARMS and ARG_PARMS are vectors of TREE_LIST nodes containing TYPE_DECL, TEMPLATE_DECL or PARM_DECL. ARG_PARMS may contain more parameters than PARM_PARMS. If this is the case, then extra parameters must have default arguments. Consider the example: template class vector; template