diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2014-12-19 23:02:17 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2014-12-19 23:02:17 +0000 |
commit | e1dc3d86ba2148df1bcd3f9d82bf9be17097e9d5 (patch) | |
tree | 00c842dfef5a4a575fdaf4e5e6fc4c6ac81ca328 | |
parent | f3c16ea146feeb67202a03cdb4b9bf1593532d87 (diff) | |
parent | 72db90a9fc84a29541b5adbb7ca90e6056973fca (diff) | |
download | gcc-e1dc3d86ba2148df1bcd3f9d82bf9be17097e9d5.zip gcc-e1dc3d86ba2148df1bcd3f9d82bf9be17097e9d5.tar.gz gcc-e1dc3d86ba2148df1bcd3f9d82bf9be17097e9d5.tar.bz2 |
Merge from trunk revision 218979.
From-SVN: r218980
174 files changed, 8384 insertions, 1010 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 19b33e7..9c5841f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,173 @@ +2014-12-19 Jan Hubicka <hubicka@ucw.cz> + + * hash-table.h (struct pointer_hash): Fix formating. + (hash_table_higher_prime_index): Declare pure. + (hash_table_mod2, hash_table_mod1, mul_mod): Move inline; + assume that uint64_t always exists. + (hash_table<Descriptor, Allocator, false>): Use gcc_checking_assert. + (hash_table<Descriptor, Allocator, false>::expand ()): Fix formating. + (hash_table<Descriptor, Allocator, false>::clear_slot (value_type **slot)): + Use checking assert. + * hash-table.c: Remove #if 0 code. + (hash_table_higher_prime_index): Use gcc_assert. + (mul_mod, hash-table_mod1, hash_table_mod2): move to hash-table.h + +2014-12-19 Matthew Fortune <matthew.fortune@imgtec.com> + + * config.gcc: Support mips*-img-linux* and mips*-img-elf*. + * config/mips/mti-linux.h: Support mips32r6 as being the default arch. + * config/mips/t-img-elf: New. + * config/mips/t-img-linux: New. + +2014-12-19 Matthew Fortune <matthew.fortune@imgtec.com> + + * config.gcc: Add mipsisa64r6 and mipsisa32r6 cpu support. + * config/mips/constraints.md (ZD): Add r6 restrictions. + * config/mips/gnu-user.h (DRIVER_SELF_SPECS): Add MIPS_ISA_LEVEL_SPEC. + * config/mips/loongson.md + (<u>div<mode>3, <u>mod<mode>3): Move to mips.md. + * config/mips/mips-cpus.def (mips32r6, mips64r6): Define. + * config/mips/mips-modes.def (CCF): New mode. + * config/mips/mips-protos.h + (mips_9bit_offset_address_p): New prototype. + * config/mips/mips-tables.opt: Regenerate. + * config/mips/mips.c (MIPS_JR): Use JALR $, <reg> for R6. + (mips_rtx_cost_data): Add pseudo-processors W32 and W64. + (mips_9bit_offset_address_p): New function. + (mips_rtx_costs): Account for R6 multiply and FMA instructions. + (mips_emit_compare): Implement R6 FPU comparisons. + (mips_expand_conditional_move): Implement R6 selects. + (mips_expand_conditional_trap): Account for removed trap immediate. + (mips_expand_block_move): Disable inline move when LWL/LWR are removed. + (mips_print_float_branch_condition): Update for R6 FPU branches. + (mips_print_operand): Handle CCF mode compares. + (mips_interrupt_extra_call_saved_reg_p): Do not attempt to callee-save + MD_REGS for R6. + (mips_hard_regno_mode_ok_p): Support CCF mode. + (mips_mode_ok_for_mov_fmt_p): Likewise. + (mips_secondary_reload_class): CCFmode can be loaded directly. + (mips_set_fast_mult_zero_zero_p): Account for R6 multiply instructions. + (mips_option_override): Ensure R6 is used with fp64. Set default + mips_nan modes. Check for mips_nan support. Prevent DSP with R6. + (mips_conditional_register_usage): Disable MD_REGS for R6. Disable + FPSW for R6. + (mips_mulsidi3_gen_fn): Support R6 multiply instructions. + * config/mips/mips.h (ISA_MIPS32R6, ISA_MIPS64R6): Define. + (TARGET_CPU_CPP_BUILTINS): Rework for mips32/mips64. + (ISA_HAS_JR): New macro. + (ISA_HAS_HILO): New macro. + (ISA_HAS_R6MUL): Likewise. + (ISA_HAS_R6DMUL): Likewise. + (ISA_HAS_R6DIV): Likewise. + (ISA_HAS_R6DDIV): Likewise. + (ISA_HAS_CCF): Likewise. + (ISA_HAS_SEL): Likewise. + (ISA_HAS_COND_TRAPI): Likewise. + (ISA_HAS_FP_MADDF_MSUBF): Likewise. + (ISA_HAS_LWL_LWR): Likewise. + (ISA_HAS_IEEE_754_LEGACY): Likewise. + (ISA_HAS_IEEE_754_2008): Likewise. + (ISA_HAS_PREFETCH_9BIT): Likewise. + (MIPSR6_9BIT_OFFSET_P): New macro. + (BASE_DRIVER_SELF_SPECS): Use MIPS_ISA_DRIVER_SELF_SPECS. + (DRIVER_SELF_SPECS): Use MIPS_ISA_LEVEL_SPEC. + (MULTILIB_ISA_DEFAULT): Handle mips32r6 and mips64r6. + (MIPS_ISA_LEVEL_SPEC): Likewise. + (MIPS_ISA_SYNCI_SPEC): Likewise. + (ISA_HAS_64BIT_REGS): Likewise. + (ISA_HAS_BRANCHLIKELY): Likewise. + (ISA_HAS_MUL3): Likewise. + (ISA_HAS_DMULT): Likewise. + (ISA_HAS_DDIV): Likewise. + (ISA_HAS_DIV): Likewise. + (ISA_HAS_MULT): Likewise. + (ISA_HAS_FP_CONDMOVE): Likewise. + (ISA_HAS_8CC): Likewise. + (ISA_HAS_FP4): Likewise. + (ISA_HAS_PAIRED_SINGLE): Likewise. + (ISA_HAS_MADD_MSUB): Likewise. + (ISA_HAS_FP_RECIP_RSQRT): Likewise. + * config/mips/mips.md (processor): Add w32 and w64. + (FPCC): New mode iterator. + (reg): Add CCF mode. + (fpcmp): New mode attribute. + (fcond): Add ordered, ltgt and ne codes. + (fcond): Update code attribute. + (sel): New code attribute. + (selinv): Likewise. + (ctrap<mode>4): Update condition. + (*conditional_trap_reg<mode>): New define_insn. + (*conditional_trap<mode>): Update condition. + (mul<mode>3): Expand R6 multiply instructions. + (<su>mulsi3_highpart): Likewise. + (<su>muldi3_highpart): Likewise. + (mul<mode>3_mul3_loongson): Rename... + (mul<mode>3_mul3_hilo): To this. Add R6 mul instruction. + (<u>mulsidi3_32bit_r6): New expander. + (<u>mulsidi3_32bit): Restrict to pre-r6 multiplies. + (<u>mulsidi3_32bit_r4000): Likewise. + (<u>mulsidi3_64bit): Likewise. + (<su>mulsi3_highpart_internal): Likewise. + (mulsidi3_64bit_r6dmul): New instruction. + (<su>mulsi3_highpart_r6): Likewise. + (<su>muldi3_highpart_r6): Likewise. + (fma<mode>4): Likewise. + (movccf): Likewise. + (*sel<code><GPR:mode>_using_<GPR2:mode>): Likewise. + (*sel<mode>): Likewise. + (<u>div<mode>3): Moved from loongson.md. Add R6 instructions. + (<u>mod<mode>3): Likewise. + (extvmisalign<mode>): Require ISA_HAS_LWL_LWR. + (extzvmisalign<mode>): Likewise. + (insvmisalign<mode>): Likewise. + (mips_cache): Account for R6 displacement field sizes. + (*branch_fp): Rename... + (*branch_fp_<mode>): To this. Add CCFmode support. + (*branch_fp_inverted): Rename... + (*branch_fp_inverted_<mode>): To this. Add CCFmode support. + (s<code>_<mode>): Rename... + (s<code>_<SCALARF:mode>_using_<FPCC:mode>): To this. Add FCCmode + condition support. + (s<code>_<mode> swapped): Rename... + (s<code>_<SCALARF:mode>_using_<FPCC:mode> swapped): To this. Add + CCFmode condition support. + (mov<mode>cc GPR): Expand R6 selects. + (mov<mode>cc FPR): Expand R6 selects. + (*tls_get_tp_<mode>_split): Do not .set push for >= mips32r2. + * config/mips/netbsd.h (TARGET_CPU_CPP_BUILTINS): Update similarly to + mips.h. + (ASM_SPEC): Add mips32r6, mips64r6. + * config/mips/t-isa3264 (MULTILIB_OPTIONS, MULTILIB_DIRNAMES): Update + for mips32r6/mips64r6. + * doc/invoke.texi: Document -mips32r6,-mips64r6. + * doc/md.texi: Update comment for ZD constraint. + +2014-12-19 Segher Boessenkool <segher@kernel.crashing.org> + + PR target/64268 + * combine.c (try_combine): Immediately return if any of I0,I1,I2 + are the same insn. + +2014-12-19 Alan Lawrence <alan.lawrence@arm.com> + + * config/aarch64/aarch64.c (<LOGICAL:optab>_one_cmpl<mode>3): + Reparameterize to... + (<NLOGICAL:optab>_one_cmpl<mode>3): with extra SIMD-register variant. + (xor_one_cmpl<mode>3): New define_insn_and_split. + + * config/aarch64/iterators.md (NLOGICAL): New define_code_iterator. + +2014-12-19 Alan Lawrence <alan.lawrence@arm.com> + + * config/aarch64/aarch64.md (<optab><mode>3, one_cmpl<mode>2): + Add SIMD-register variant. + * config/aarch64/iterators.md (Vbtype): Add value for SI. + +2014-12-19 Alan Lawrence <alan.lawrence@arm.com> + + * config/aarch64/aarch64.md (subdi3, adddi3_aarch64): Don't penalize + SIMD reg variant. + 2014-12-19 Martin Liska <mliska@suse.cz> PR ipa/63569 diff --git a/gcc/combine.c b/gcc/combine.c index ee7b3f9..212da33 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -2588,6 +2588,11 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0, rtx new_other_notes; int i; + /* Immediately return if any of I0,I1,I2 are the same insn (I3 can + never be). */ + if (i1 == i2 || i0 == i2 || (i0 && i0 == i1)) + return 0; + /* Only try four-insn combinations when there's high likelihood of success. Look for simple insns, such as loads of constants or binary operations involving a constant. */ diff --git a/gcc/config.gcc b/gcc/config.gcc index 8541274..c5d9ff8 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -1961,6 +1961,14 @@ mips*-*-netbsd*) # NetBSD/mips, either endian. tm_file="elfos.h ${tm_file} mips/elf.h netbsd.h netbsd-elf.h mips/netbsd.h" extra_options="${extra_options} netbsd.opt netbsd-elf.opt" ;; +mips*-img-linux*) + tm_file="dbxelf.h elfos.h gnu-user.h linux.h linux-android.h glibc-stdint.h ${tm_file} mips/gnu-user.h mips/linux.h mips/linux-common.h mips/mti-linux.h" + extra_options="${extra_options} linux-android.opt" + tmake_file="${tmake_file} mips/t-img-linux" + tm_defines="${tm_defines} MIPS_ISA_DEFAULT=37 MIPS_ABI_DEFAULT=ABI_32" + gnu_ld=yes + gas=yes + ;; mips*-mti-linux*) tm_file="dbxelf.h elfos.h gnu-user.h linux.h linux-android.h glibc-stdint.h ${tm_file} mips/gnu-user.h mips/linux.h mips/linux-common.h mips/mti-linux.h" extra_options="${extra_options} linux-android.opt" @@ -1973,6 +1981,9 @@ mips*-*-linux*) # Linux MIPS, either endian. tm_file="dbxelf.h elfos.h gnu-user.h linux.h linux-android.h glibc-stdint.h ${tm_file} mips/gnu-user.h mips/linux.h mips/linux-common.h" extra_options="${extra_options} linux-android.opt" case ${target} in + mipsisa32r6*) + default_mips_arch=mips32r6 + ;; mipsisa32r2*) default_mips_arch=mips32r2 ;; @@ -1991,6 +2002,11 @@ mips*-*-linux*) # Linux MIPS, either endian. target_cpu_default=MASK_SOFT_FLOAT_ABI enable_mips_multilibs="yes" ;; + mipsisa64r6*-*-linux*) + default_mips_abi=n32 + default_mips_arch=mips64r6 + enable_mips_multilibs="yes" + ;; mipsisa64r2*-*-linux*) default_mips_abi=n32 default_mips_arch=mips64r2 @@ -2013,6 +2029,11 @@ mips*-mti-elf*) tmake_file="mips/t-mti-elf" tm_defines="${tm_defines} MIPS_ISA_DEFAULT=33 MIPS_ABI_DEFAULT=ABI_32" ;; +mips*-img-elf*) + tm_file="elfos.h newlib-stdint.h ${tm_file} mips/elf.h mips/n32-elf.h mips/sde.h mips/mti-elf.h" + tmake_file="mips/t-img-elf" + tm_defines="${tm_defines} MIPS_ISA_DEFAULT=37 MIPS_ABI_DEFAULT=ABI_32" + ;; mips*-sde-elf*) tm_file="elfos.h newlib-stdint.h ${tm_file} mips/elf.h mips/n32-elf.h mips/sde.h" tmake_file="mips/t-sde" @@ -2033,12 +2054,18 @@ mips*-sde-elf*) ;; esac case ${target} in + mipsisa32r6*) + tm_defines="MIPS_ISA_DEFAULT=37 MIPS_ABI_DEFAULT=ABI_32" + ;; mipsisa32r2*) tm_defines="MIPS_ISA_DEFAULT=33 MIPS_ABI_DEFAULT=ABI_32" ;; mipsisa32*) tm_defines="MIPS_ISA_DEFAULT=32 MIPS_ABI_DEFAULT=ABI_32" ;; + mipsisa64r6*) + tm_defines="MIPS_ISA_DEFAULT=69 MIPS_ABI_DEFAULT=ABI_N32" + ;; mipsisa64r2*) tm_defines="MIPS_ISA_DEFAULT=65 MIPS_ABI_DEFAULT=ABI_N32" ;; @@ -2049,17 +2076,25 @@ mips*-sde-elf*) ;; mipsisa32-*-elf* | mipsisa32el-*-elf* | \ mipsisa32r2-*-elf* | mipsisa32r2el-*-elf* | \ +mipsisa32r6-*-elf* | mipsisa32r6el-*-elf* | \ mipsisa64-*-elf* | mipsisa64el-*-elf* | \ -mipsisa64r2-*-elf* | mipsisa64r2el-*-elf*) +mipsisa64r2-*-elf* | mipsisa64r2el-*-elf* | \ +mipsisa64r6-*-elf* | mipsisa64r6el-*-elf*) tm_file="elfos.h newlib-stdint.h ${tm_file} mips/elf.h" tmake_file="mips/t-isa3264" case ${target} in + mipsisa32r6*) + tm_defines="${tm_defines} MIPS_ISA_DEFAULT=37" + ;; mipsisa32r2*) tm_defines="${tm_defines} MIPS_ISA_DEFAULT=33" ;; mipsisa32*) tm_defines="${tm_defines} MIPS_ISA_DEFAULT=32" ;; + mipsisa64r6*) + tm_defines="${tm_defines} MIPS_ISA_DEFAULT=69" + ;; mipsisa64r2*) tm_defines="${tm_defines} MIPS_ISA_DEFAULT=65" ;; @@ -4192,8 +4227,10 @@ case ${target} in mips4) tm_defines="$tm_defines MIPS_ISA_DEFAULT=4" ;; mips32) tm_defines="$tm_defines MIPS_ISA_DEFAULT=32" ;; mips32r2) tm_defines="$tm_defines MIPS_ISA_DEFAULT=33" ;; + mips32r6) tm_defines="$tm_defines MIPS_ISA_DEFAULT=37" ;; mips64) tm_defines="$tm_defines MIPS_ISA_DEFAULT=64" ;; mips64r2) tm_defines="$tm_defines MIPS_ISA_DEFAULT=65" ;; + mips64r6) tm_defines="$tm_defines MIPS_ISA_DEFAULT=69" ;; esac case ${default_mips_abi} in 32) tm_defines="$tm_defines MIPS_ABI_DEFAULT=ABI_32" ;; diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index 12532c1..7b05359 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -1434,10 +1434,10 @@ (define_insn "*adddi3_aarch64" [(set - (match_operand:DI 0 "register_operand" "=rk,rk,rk,!w") + (match_operand:DI 0 "register_operand" "=rk,rk,rk,w") (plus:DI - (match_operand:DI 1 "register_operand" "%rk,rk,rk,!w") - (match_operand:DI 2 "aarch64_plus_operand" "I,r,J,!w")))] + (match_operand:DI 1 "register_operand" "%rk,rk,rk,w") + (match_operand:DI 2 "aarch64_plus_operand" "I,r,J,w")))] "" "@ add\\t%x0, %x1, %2 @@ -1908,9 +1908,9 @@ ) (define_insn "subdi3" - [(set (match_operand:DI 0 "register_operand" "=rk,!w") - (minus:DI (match_operand:DI 1 "register_operand" "r,!w") - (match_operand:DI 2 "register_operand" "r,!w")))] + [(set (match_operand:DI 0 "register_operand" "=rk,w") + (minus:DI (match_operand:DI 1 "register_operand" "r,w") + (match_operand:DI 2 "register_operand" "r,w")))] "" "@ sub\\t%x0, %x1, %x2 @@ -2866,12 +2866,16 @@ ;; ------------------------------------------------------------------- (define_insn "<optab><mode>3" - [(set (match_operand:GPI 0 "register_operand" "=r,rk") - (LOGICAL:GPI (match_operand:GPI 1 "register_operand" "%r,r") - (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>")))] + [(set (match_operand:GPI 0 "register_operand" "=r,rk,w") + (LOGICAL:GPI (match_operand:GPI 1 "register_operand" "%r,r,w") + (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>,w")))] "" - "<logical>\\t%<w>0, %<w>1, %<w>2" - [(set_attr "type" "logic_reg,logic_imm")] + "@ + <logical>\\t%<w>0, %<w>1, %<w>2 + <logical>\\t%<w>0, %<w>1, %<w>2 + <logical>\\t%0.<Vbtype>, %1.<Vbtype>, %2.<Vbtype>" + [(set_attr "type" "logic_reg,logic_imm,neon_logic") + (set_attr "simd" "*,*,yes")] ) ;; zero_extend version of above @@ -2992,11 +2996,14 @@ ) (define_insn "one_cmpl<mode>2" - [(set (match_operand:GPI 0 "register_operand" "=r") - (not:GPI (match_operand:GPI 1 "register_operand" "r")))] + [(set (match_operand:GPI 0 "register_operand" "=r,w") + (not:GPI (match_operand:GPI 1 "register_operand" "r,w")))] "" - "mvn\\t%<w>0, %<w>1" - [(set_attr "type" "logic_reg")] + "@ + mvn\\t%<w>0, %<w>1 + mvn\\t%0.8b, %1.8b" + [(set_attr "type" "logic_reg,neon_logic") + (set_attr "simd" "*,yes")] ) (define_insn "*one_cmpl_<optab><mode>2" @@ -3008,14 +3015,36 @@ [(set_attr "type" "logic_shift_imm")] ) -(define_insn "*<LOGICAL:optab>_one_cmpl<mode>3" - [(set (match_operand:GPI 0 "register_operand" "=r") - (LOGICAL:GPI (not:GPI - (match_operand:GPI 1 "register_operand" "r")) - (match_operand:GPI 2 "register_operand" "r")))] +;; Binary logical operators negating one operand, i.e. (a & !b), (a | !b). + +(define_insn "*<NLOGICAL:optab>_one_cmpl<mode>3" + [(set (match_operand:GPI 0 "register_operand" "=r,w") + (NLOGICAL:GPI (not:GPI (match_operand:GPI 1 "register_operand" "r,w")) + (match_operand:GPI 2 "register_operand" "r,w")))] "" - "<LOGICAL:nlogical>\\t%<w>0, %<w>2, %<w>1" - [(set_attr "type" "logic_reg")] + "@ + <NLOGICAL:nlogical>\\t%<w>0, %<w>2, %<w>1 + <NLOGICAL:nlogical>\\t%0.<Vbtype>, %2.<Vbtype>, %1.<Vbtype>" + [(set_attr "type" "logic_reg,neon_logic") + (set_attr "simd" "*,yes")] +) + +;; (xor (not a) b) is simplify_rtx-ed down to (not (xor a b)). +;; eon does not operate on SIMD registers so the vector variant must be split. +(define_insn_and_split "*xor_one_cmpl<mode>3" + [(set (match_operand:GPI 0 "register_operand" "=r,w") + (not:GPI (xor:GPI (match_operand:GPI 1 "register_operand" "r,?w") + (match_operand:GPI 2 "register_operand" "r,w"))))] + "" + "eon\\t%<w>0, %<w>1, %<w>2" ;; For GPR registers (only). + "reload_completed && (which_alternative == 1)" ;; For SIMD registers. + [(set (match_operand:GPI 0 "register_operand" "=w") + (xor:GPI (match_operand:GPI 1 "register_operand" "w") + (match_operand:GPI 2 "register_operand" "w"))) + (set (match_dup 0) (not:GPI (match_dup 0)))] + "" + [(set_attr "type" "logic_reg,multiple") + (set_attr "simd" "*,yes")] ) (define_insn "*and_one_cmpl<mode>3_compare0" diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md index 16a2647..fe9fa97b9 100644 --- a/gcc/config/aarch64/iterators.md +++ b/gcc/config/aarch64/iterators.md @@ -387,7 +387,8 @@ (V2SI "8b") (V4SI "16b") (V2DI "16b") (V2SF "8b") (V4SF "16b") (V2DF "16b") - (DI "8b") (DF "8b")]) + (DI "8b") (DF "8b") + (SI "8b")]) ;; Define element mode for each vector mode. (define_mode_attr VEL [(V8QI "QI") (V16QI "QI") @@ -664,6 +665,9 @@ ;; Code iterator for logical operations (define_code_iterator LOGICAL [and ior xor]) +;; Code iterator for logical operations whose :nlogical works on SIMD registers. +(define_code_iterator NLOGICAL [and ior]) + ;; Code iterator for sign/zero extension (define_code_iterator ANY_EXTEND [sign_extend zero_extend]) diff --git a/gcc/config/mips/constraints.md b/gcc/config/mips/constraints.md index fa33c30..816880c 100644 --- a/gcc/config/mips/constraints.md +++ b/gcc/config/mips/constraints.md @@ -321,13 +321,13 @@ (match_test "mips_address_insns (XEXP (op, 0), mode, false)")))) (define_address_constraint "ZD" - "When compiling microMIPS code, this constraint matches an address operand - that is formed from a base register and a 12-bit offset. These operands - can be used for microMIPS instructions such as @code{prefetch}. When - not compiling for microMIPS code, @code{ZD} is equivalent to @code{p}." + "An address suitable for a @code{prefetch} instruction, or for any other + instruction with the same addressing mode as @code{prefetch}." (if_then_else (match_test "TARGET_MICROMIPS") (match_test "umips_12bit_offset_address_p (op, mode)") - (match_test "mips_address_insns (op, mode, false)"))) + (if_then_else (match_test "ISA_HAS_PREFETCH_9BIT") + (match_test "mips_9bit_offset_address_p (op, mode)") + (match_test "mips_address_insns (op, mode, false)")))) (define_memory_constraint "ZR" "@internal diff --git a/gcc/config/mips/gnu-user.h b/gcc/config/mips/gnu-user.h index 6c02054..6501a27 100644 --- a/gcc/config/mips/gnu-user.h +++ b/gcc/config/mips/gnu-user.h @@ -132,6 +132,7 @@ extern const char *host_detect_local_cpu (int argc, const char **argv); #undef DRIVER_SELF_SPECS #define DRIVER_SELF_SPECS \ + MIPS_ISA_LEVEL_SPEC, \ BASE_DRIVER_SELF_SPECS, \ LINUX_DRIVER_SELF_SPECS diff --git a/gcc/config/mips/loongson.md b/gcc/config/mips/loongson.md index 474033d..0869131 100644 --- a/gcc/config/mips/loongson.md +++ b/gcc/config/mips/loongson.md @@ -907,33 +907,3 @@ mips_expand_vec_reduc (operands[0], operands[1], gen_umin<mode>3); DONE; }) - -;; Integer division and modulus. For integer multiplication, see mips.md. - -(define_insn "<u>div<mode>3" - [(set (match_operand:GPR 0 "register_operand" "=&d") - (any_div:GPR (match_operand:GPR 1 "register_operand" "d") - (match_operand:GPR 2 "register_operand" "d")))] - "TARGET_LOONGSON_2EF || TARGET_LOONGSON_3A" - { - if (TARGET_LOONGSON_2EF) - return mips_output_division ("<d>div<u>.g\t%0,%1,%2", operands); - else - return mips_output_division ("gs<d>div<u>\t%0,%1,%2", operands); - } - [(set_attr "type" "idiv3") - (set_attr "mode" "<MODE>")]) - -(define_insn "<u>mod<mode>3" - [(set (match_operand:GPR 0 "register_operand" "=&d") - (any_mod:GPR (match_operand:GPR 1 "register_operand" "d") - (match_operand:GPR 2 "register_operand" "d")))] - "TARGET_LOONGSON_2EF || TARGET_LOONGSON_3A" - { - if (TARGET_LOONGSON_2EF) - return mips_output_division ("<d>mod<u>.g\t%0,%1,%2", operands); - else - return mips_output_division ("gs<d>mod<u>\t%0,%1,%2", operands); - } - [(set_attr "type" "idiv3") - (set_attr "mode" "<MODE>")]) diff --git a/gcc/config/mips/mips-cpus.def b/gcc/config/mips/mips-cpus.def index e2985b8..0d21783 100644 --- a/gcc/config/mips/mips-cpus.def +++ b/gcc/config/mips/mips-cpus.def @@ -50,11 +50,13 @@ MIPS_CPU ("mips32r2", PROCESSOR_74KF2_1, 33, PTF_AVOID_BRANCHLIKELY) as mips32r2. */ MIPS_CPU ("mips32r3", PROCESSOR_M4K, 34, PTF_AVOID_BRANCHLIKELY) MIPS_CPU ("mips32r5", PROCESSOR_P5600, 36, PTF_AVOID_BRANCHLIKELY) +MIPS_CPU ("mips32r6", PROCESSOR_W32, 37, PTF_AVOID_BRANCHLIKELY) MIPS_CPU ("mips64", PROCESSOR_5KC, 64, PTF_AVOID_BRANCHLIKELY) /* ??? For now just tune the generic MIPS64r2 and above for 5KC as well. */ MIPS_CPU ("mips64r2", PROCESSOR_5KC, 65, PTF_AVOID_BRANCHLIKELY) MIPS_CPU ("mips64r3", PROCESSOR_5KC, 66, PTF_AVOID_BRANCHLIKELY) MIPS_CPU ("mips64r5", PROCESSOR_5KC, 68, PTF_AVOID_BRANCHLIKELY) +MIPS_CPU ("mips64r6", PROCESSOR_W64, 69, PTF_AVOID_BRANCHLIKELY) /* MIPS I processors. */ MIPS_CPU ("r3000", PROCESSOR_R3000, 1, 0) diff --git a/gcc/config/mips/mips-modes.def b/gcc/config/mips/mips-modes.def index fa1d1e7..96d72c1 100644 --- a/gcc/config/mips/mips-modes.def +++ b/gcc/config/mips/mips-modes.def @@ -46,3 +46,6 @@ ADJUST_ALIGNMENT (CCV4, 16); /* For MIPS DSP control registers. */ CC_MODE (CCDSP); + +/* For floating point conditions in FP registers. */ +CC_MODE (CCF); diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h index adeda59..087403e 100644 --- a/gcc/config/mips/mips-protos.h +++ b/gcc/config/mips/mips-protos.h @@ -347,6 +347,7 @@ extern bool umips_load_store_pair_p (bool, rtx *); extern void umips_output_load_store_pair (bool, rtx *); extern bool umips_movep_target_p (rtx, rtx); extern bool umips_12bit_offset_address_p (rtx, machine_mode); +extern bool mips_9bit_offset_address_p (rtx, machine_mode); extern bool lwsp_swsp_address_p (rtx, machine_mode); extern bool m16_based_address_p (rtx, machine_mode, int (*)(rtx_def*, machine_mode)); diff --git a/gcc/config/mips/mips-tables.opt b/gcc/config/mips/mips-tables.opt index 99d2ed8..c8cdfa7 100644 --- a/gcc/config/mips/mips-tables.opt +++ b/gcc/config/mips/mips-tables.opt @@ -82,593 +82,605 @@ EnumValue Enum(mips_mips_opt_value) String(32r5) Value(7) EnumValue -Enum(mips_arch_opt_value) String(mips64) Value(8) Canonical +Enum(mips_arch_opt_value) String(mips32r6) Value(8) Canonical EnumValue -Enum(mips_mips_opt_value) String(64) Value(8) +Enum(mips_mips_opt_value) String(32r6) Value(8) EnumValue -Enum(mips_arch_opt_value) String(mips64r2) Value(9) Canonical +Enum(mips_arch_opt_value) String(mips64) Value(9) Canonical EnumValue -Enum(mips_mips_opt_value) String(64r2) Value(9) +Enum(mips_mips_opt_value) String(64) Value(9) EnumValue -Enum(mips_arch_opt_value) String(mips64r3) Value(10) Canonical +Enum(mips_arch_opt_value) String(mips64r2) Value(10) Canonical EnumValue -Enum(mips_mips_opt_value) String(64r3) Value(10) +Enum(mips_mips_opt_value) String(64r2) Value(10) EnumValue -Enum(mips_arch_opt_value) String(mips64r5) Value(11) Canonical +Enum(mips_arch_opt_value) String(mips64r3) Value(11) Canonical EnumValue -Enum(mips_mips_opt_value) String(64r5) Value(11) +Enum(mips_mips_opt_value) String(64r3) Value(11) EnumValue -Enum(mips_arch_opt_value) String(r3000) Value(12) Canonical +Enum(mips_arch_opt_value) String(mips64r5) Value(12) Canonical EnumValue -Enum(mips_arch_opt_value) String(r3k) Value(12) +Enum(mips_mips_opt_value) String(64r5) Value(12) EnumValue -Enum(mips_arch_opt_value) String(3000) Value(12) +Enum(mips_arch_opt_value) String(mips64r6) Value(13) Canonical EnumValue -Enum(mips_arch_opt_value) String(3k) Value(12) +Enum(mips_mips_opt_value) String(64r6) Value(13) EnumValue -Enum(mips_arch_opt_value) String(r2000) Value(13) Canonical +Enum(mips_arch_opt_value) String(r3000) Value(14) Canonical EnumValue -Enum(mips_arch_opt_value) String(r2k) Value(13) +Enum(mips_arch_opt_value) String(r3k) Value(14) EnumValue -Enum(mips_arch_opt_value) String(2000) Value(13) +Enum(mips_arch_opt_value) String(3000) Value(14) EnumValue -Enum(mips_arch_opt_value) String(2k) Value(13) +Enum(mips_arch_opt_value) String(3k) Value(14) EnumValue -Enum(mips_arch_opt_value) String(r3900) Value(14) Canonical +Enum(mips_arch_opt_value) String(r2000) Value(15) Canonical EnumValue -Enum(mips_arch_opt_value) String(3900) Value(14) +Enum(mips_arch_opt_value) String(r2k) Value(15) EnumValue -Enum(mips_arch_opt_value) String(r6000) Value(15) Canonical +Enum(mips_arch_opt_value) String(2000) Value(15) EnumValue -Enum(mips_arch_opt_value) String(r6k) Value(15) +Enum(mips_arch_opt_value) String(2k) Value(15) EnumValue -Enum(mips_arch_opt_value) String(6000) Value(15) +Enum(mips_arch_opt_value) String(r3900) Value(16) Canonical EnumValue -Enum(mips_arch_opt_value) String(6k) Value(15) +Enum(mips_arch_opt_value) String(3900) Value(16) EnumValue -Enum(mips_arch_opt_value) String(r4000) Value(16) Canonical +Enum(mips_arch_opt_value) String(r6000) Value(17) Canonical EnumValue -Enum(mips_arch_opt_value) String(r4k) Value(16) +Enum(mips_arch_opt_value) String(r6k) Value(17) EnumValue -Enum(mips_arch_opt_value) String(4000) Value(16) +Enum(mips_arch_opt_value) String(6000) Value(17) EnumValue -Enum(mips_arch_opt_value) String(4k) Value(16) +Enum(mips_arch_opt_value) String(6k) Value(17) EnumValue -Enum(mips_arch_opt_value) String(vr4100) Value(17) Canonical +Enum(mips_arch_opt_value) String(r4000) Value(18) Canonical EnumValue -Enum(mips_arch_opt_value) String(4100) Value(17) +Enum(mips_arch_opt_value) String(r4k) Value(18) EnumValue -Enum(mips_arch_opt_value) String(r4100) Value(17) +Enum(mips_arch_opt_value) String(4000) Value(18) EnumValue -Enum(mips_arch_opt_value) String(vr4111) Value(18) Canonical +Enum(mips_arch_opt_value) String(4k) Value(18) EnumValue -Enum(mips_arch_opt_value) String(4111) Value(18) +Enum(mips_arch_opt_value) String(vr4100) Value(19) Canonical EnumValue -Enum(mips_arch_opt_value) String(r4111) Value(18) +Enum(mips_arch_opt_value) String(4100) Value(19) EnumValue -Enum(mips_arch_opt_value) String(vr4120) Value(19) Canonical +Enum(mips_arch_opt_value) String(r4100) Value(19) EnumValue -Enum(mips_arch_opt_value) String(4120) Value(19) +Enum(mips_arch_opt_value) String(vr4111) Value(20) Canonical EnumValue -Enum(mips_arch_opt_value) String(r4120) Value(19) +Enum(mips_arch_opt_value) String(4111) Value(20) EnumValue -Enum(mips_arch_opt_value) String(vr4130) Value(20) Canonical +Enum(mips_arch_opt_value) String(r4111) Value(20) EnumValue -Enum(mips_arch_opt_value) String(4130) Value(20) +Enum(mips_arch_opt_value) String(vr4120) Value(21) Canonical EnumValue -Enum(mips_arch_opt_value) String(r4130) Value(20) +Enum(mips_arch_opt_value) String(4120) Value(21) EnumValue -Enum(mips_arch_opt_value) String(vr4300) Value(21) Canonical +Enum(mips_arch_opt_value) String(r4120) Value(21) EnumValue -Enum(mips_arch_opt_value) String(4300) Value(21) +Enum(mips_arch_opt_value) String(vr4130) Value(22) Canonical EnumValue -Enum(mips_arch_opt_value) String(r4300) Value(21) +Enum(mips_arch_opt_value) String(4130) Value(22) EnumValue -Enum(mips_arch_opt_value) String(r4400) Value(22) Canonical +Enum(mips_arch_opt_value) String(r4130) Value(22) EnumValue -Enum(mips_arch_opt_value) String(4400) Value(22) +Enum(mips_arch_opt_value) String(vr4300) Value(23) Canonical EnumValue -Enum(mips_arch_opt_value) String(r4600) Value(23) Canonical +Enum(mips_arch_opt_value) String(4300) Value(23) EnumValue -Enum(mips_arch_opt_value) String(4600) Value(23) +Enum(mips_arch_opt_value) String(r4300) Value(23) EnumValue -Enum(mips_arch_opt_value) String(orion) Value(24) Canonical +Enum(mips_arch_opt_value) String(r4400) Value(24) Canonical EnumValue -Enum(mips_arch_opt_value) String(r4650) Value(25) Canonical +Enum(mips_arch_opt_value) String(4400) Value(24) EnumValue -Enum(mips_arch_opt_value) String(4650) Value(25) +Enum(mips_arch_opt_value) String(r4600) Value(25) Canonical EnumValue -Enum(mips_arch_opt_value) String(r4700) Value(26) Canonical +Enum(mips_arch_opt_value) String(4600) Value(25) EnumValue -Enum(mips_arch_opt_value) String(4700) Value(26) +Enum(mips_arch_opt_value) String(orion) Value(26) Canonical EnumValue -Enum(mips_arch_opt_value) String(r5900) Value(27) Canonical +Enum(mips_arch_opt_value) String(r4650) Value(27) Canonical EnumValue -Enum(mips_arch_opt_value) String(5900) Value(27) +Enum(mips_arch_opt_value) String(4650) Value(27) EnumValue -Enum(mips_arch_opt_value) String(loongson2e) Value(28) Canonical +Enum(mips_arch_opt_value) String(r4700) Value(28) Canonical EnumValue -Enum(mips_arch_opt_value) String(loongson2f) Value(29) Canonical +Enum(mips_arch_opt_value) String(4700) Value(28) EnumValue -Enum(mips_arch_opt_value) String(r8000) Value(30) Canonical +Enum(mips_arch_opt_value) String(r5900) Value(29) Canonical EnumValue -Enum(mips_arch_opt_value) String(r8k) Value(30) +Enum(mips_arch_opt_value) String(5900) Value(29) EnumValue -Enum(mips_arch_opt_value) String(8000) Value(30) +Enum(mips_arch_opt_value) String(loongson2e) Value(30) Canonical EnumValue -Enum(mips_arch_opt_value) String(8k) Value(30) +Enum(mips_arch_opt_value) String(loongson2f) Value(31) Canonical EnumValue -Enum(mips_arch_opt_value) String(r10000) Value(31) Canonical +Enum(mips_arch_opt_value) String(r8000) Value(32) Canonical EnumValue -Enum(mips_arch_opt_value) String(r10k) Value(31) +Enum(mips_arch_opt_value) String(r8k) Value(32) EnumValue -Enum(mips_arch_opt_value) String(10000) Value(31) +Enum(mips_arch_opt_value) String(8000) Value(32) EnumValue -Enum(mips_arch_opt_value) String(10k) Value(31) +Enum(mips_arch_opt_value) String(8k) Value(32) EnumValue -Enum(mips_arch_opt_value) String(r12000) Value(32) Canonical +Enum(mips_arch_opt_value) String(r10000) Value(33) Canonical EnumValue -Enum(mips_arch_opt_value) String(r12k) Value(32) +Enum(mips_arch_opt_value) String(r10k) Value(33) EnumValue -Enum(mips_arch_opt_value) String(12000) Value(32) +Enum(mips_arch_opt_value) String(10000) Value(33) EnumValue -Enum(mips_arch_opt_value) String(12k) Value(32) +Enum(mips_arch_opt_value) String(10k) Value(33) EnumValue -Enum(mips_arch_opt_value) String(r14000) Value(33) Canonical +Enum(mips_arch_opt_value) String(r12000) Value(34) Canonical EnumValue -Enum(mips_arch_opt_value) String(r14k) Value(33) +Enum(mips_arch_opt_value) String(r12k) Value(34) EnumValue -Enum(mips_arch_opt_value) String(14000) Value(33) +Enum(mips_arch_opt_value) String(12000) Value(34) EnumValue -Enum(mips_arch_opt_value) String(14k) Value(33) +Enum(mips_arch_opt_value) String(12k) Value(34) EnumValue -Enum(mips_arch_opt_value) String(r16000) Value(34) Canonical +Enum(mips_arch_opt_value) String(r14000) Value(35) Canonical EnumValue -Enum(mips_arch_opt_value) String(r16k) Value(34) +Enum(mips_arch_opt_value) String(r14k) Value(35) EnumValue -Enum(mips_arch_opt_value) String(16000) Value(34) +Enum(mips_arch_opt_value) String(14000) Value(35) EnumValue -Enum(mips_arch_opt_value) String(16k) Value(34) +Enum(mips_arch_opt_value) String(14k) Value(35) EnumValue -Enum(mips_arch_opt_value) String(vr5000) Value(35) Canonical +Enum(mips_arch_opt_value) String(r16000) Value(36) Canonical EnumValue -Enum(mips_arch_opt_value) String(vr5k) Value(35) +Enum(mips_arch_opt_value) String(r16k) Value(36) EnumValue -Enum(mips_arch_opt_value) String(5000) Value(35) +Enum(mips_arch_opt_value) String(16000) Value(36) EnumValue -Enum(mips_arch_opt_value) String(5k) Value(35) +Enum(mips_arch_opt_value) String(16k) Value(36) EnumValue -Enum(mips_arch_opt_value) String(r5000) Value(35) +Enum(mips_arch_opt_value) String(vr5000) Value(37) Canonical EnumValue -Enum(mips_arch_opt_value) String(r5k) Value(35) +Enum(mips_arch_opt_value) String(vr5k) Value(37) EnumValue -Enum(mips_arch_opt_value) String(vr5400) Value(36) Canonical +Enum(mips_arch_opt_value) String(5000) Value(37) EnumValue -Enum(mips_arch_opt_value) String(5400) Value(36) +Enum(mips_arch_opt_value) String(5k) Value(37) EnumValue -Enum(mips_arch_opt_value) String(r5400) Value(36) +Enum(mips_arch_opt_value) String(r5000) Value(37) EnumValue -Enum(mips_arch_opt_value) String(vr5500) Value(37) Canonical +Enum(mips_arch_opt_value) String(r5k) Value(37) EnumValue -Enum(mips_arch_opt_value) String(5500) Value(37) +Enum(mips_arch_opt_value) String(vr5400) Value(38) Canonical EnumValue -Enum(mips_arch_opt_value) String(r5500) Value(37) +Enum(mips_arch_opt_value) String(5400) Value(38) EnumValue -Enum(mips_arch_opt_value) String(rm7000) Value(38) Canonical +Enum(mips_arch_opt_value) String(r5400) Value(38) EnumValue -Enum(mips_arch_opt_value) String(rm7k) Value(38) +Enum(mips_arch_opt_value) String(vr5500) Value(39) Canonical EnumValue -Enum(mips_arch_opt_value) String(7000) Value(38) +Enum(mips_arch_opt_value) String(5500) Value(39) EnumValue -Enum(mips_arch_opt_value) String(7k) Value(38) +Enum(mips_arch_opt_value) String(r5500) Value(39) EnumValue -Enum(mips_arch_opt_value) String(r7000) Value(38) +Enum(mips_arch_opt_value) String(rm7000) Value(40) Canonical EnumValue -Enum(mips_arch_opt_value) String(r7k) Value(38) +Enum(mips_arch_opt_value) String(rm7k) Value(40) EnumValue -Enum(mips_arch_opt_value) String(rm9000) Value(39) Canonical +Enum(mips_arch_opt_value) String(7000) Value(40) EnumValue -Enum(mips_arch_opt_value) String(rm9k) Value(39) +Enum(mips_arch_opt_value) String(7k) Value(40) EnumValue -Enum(mips_arch_opt_value) String(9000) Value(39) +Enum(mips_arch_opt_value) String(r7000) Value(40) EnumValue -Enum(mips_arch_opt_value) String(9k) Value(39) +Enum(mips_arch_opt_value) String(r7k) Value(40) EnumValue -Enum(mips_arch_opt_value) String(r9000) Value(39) +Enum(mips_arch_opt_value) String(rm9000) Value(41) Canonical EnumValue -Enum(mips_arch_opt_value) String(r9k) Value(39) +Enum(mips_arch_opt_value) String(rm9k) Value(41) EnumValue -Enum(mips_arch_opt_value) String(4kc) Value(40) Canonical +Enum(mips_arch_opt_value) String(9000) Value(41) EnumValue -Enum(mips_arch_opt_value) String(r4kc) Value(40) +Enum(mips_arch_opt_value) String(9k) Value(41) EnumValue -Enum(mips_arch_opt_value) String(4km) Value(41) Canonical +Enum(mips_arch_opt_value) String(r9000) Value(41) EnumValue -Enum(mips_arch_opt_value) String(r4km) Value(41) +Enum(mips_arch_opt_value) String(r9k) Value(41) EnumValue -Enum(mips_arch_opt_value) String(4kp) Value(42) Canonical +Enum(mips_arch_opt_value) String(4kc) Value(42) Canonical EnumValue -Enum(mips_arch_opt_value) String(r4kp) Value(42) +Enum(mips_arch_opt_value) String(r4kc) Value(42) EnumValue -Enum(mips_arch_opt_value) String(4ksc) Value(43) Canonical +Enum(mips_arch_opt_value) String(4km) Value(43) Canonical EnumValue -Enum(mips_arch_opt_value) String(r4ksc) Value(43) +Enum(mips_arch_opt_value) String(r4km) Value(43) EnumValue -Enum(mips_arch_opt_value) String(m4k) Value(44) Canonical +Enum(mips_arch_opt_value) String(4kp) Value(44) Canonical EnumValue -Enum(mips_arch_opt_value) String(m14kc) Value(45) Canonical +Enum(mips_arch_opt_value) String(r4kp) Value(44) EnumValue -Enum(mips_arch_opt_value) String(m14k) Value(46) Canonical +Enum(mips_arch_opt_value) String(4ksc) Value(45) Canonical EnumValue -Enum(mips_arch_opt_value) String(m14ke) Value(47) Canonical +Enum(mips_arch_opt_value) String(r4ksc) Value(45) EnumValue -Enum(mips_arch_opt_value) String(m14kec) Value(48) Canonical +Enum(mips_arch_opt_value) String(m4k) Value(46) Canonical EnumValue -Enum(mips_arch_opt_value) String(4kec) Value(49) Canonical +Enum(mips_arch_opt_value) String(m14kc) Value(47) Canonical EnumValue -Enum(mips_arch_opt_value) String(r4kec) Value(49) +Enum(mips_arch_opt_value) String(m14k) Value(48) Canonical EnumValue -Enum(mips_arch_opt_value) String(4kem) Value(50) Canonical +Enum(mips_arch_opt_value) String(m14ke) Value(49) Canonical EnumValue -Enum(mips_arch_opt_value) String(r4kem) Value(50) +Enum(mips_arch_opt_value) String(m14kec) Value(50) Canonical EnumValue -Enum(mips_arch_opt_value) String(4kep) Value(51) Canonical +Enum(mips_arch_opt_value) String(4kec) Value(51) Canonical EnumValue -Enum(mips_arch_opt_value) String(r4kep) Value(51) +Enum(mips_arch_opt_value) String(r4kec) Value(51) EnumValue -Enum(mips_arch_opt_value) String(4ksd) Value(52) Canonical +Enum(mips_arch_opt_value) String(4kem) Value(52) Canonical EnumValue -Enum(mips_arch_opt_value) String(r4ksd) Value(52) +Enum(mips_arch_opt_value) String(r4kem) Value(52) EnumValue -Enum(mips_arch_opt_value) String(24kc) Value(53) Canonical +Enum(mips_arch_opt_value) String(4kep) Value(53) Canonical EnumValue -Enum(mips_arch_opt_value) String(r24kc) Value(53) +Enum(mips_arch_opt_value) String(r4kep) Value(53) EnumValue -Enum(mips_arch_opt_value) String(24kf2_1) Value(54) Canonical +Enum(mips_arch_opt_value) String(4ksd) Value(54) Canonical EnumValue -Enum(mips_arch_opt_value) String(r24kf2_1) Value(54) +Enum(mips_arch_opt_value) String(r4ksd) Value(54) EnumValue -Enum(mips_arch_opt_value) String(24kf) Value(55) Canonical +Enum(mips_arch_opt_value) String(24kc) Value(55) Canonical EnumValue -Enum(mips_arch_opt_value) String(r24kf) Value(55) +Enum(mips_arch_opt_value) String(r24kc) Value(55) EnumValue -Enum(mips_arch_opt_value) String(24kf1_1) Value(56) Canonical +Enum(mips_arch_opt_value) String(24kf2_1) Value(56) Canonical EnumValue -Enum(mips_arch_opt_value) String(r24kf1_1) Value(56) +Enum(mips_arch_opt_value) String(r24kf2_1) Value(56) EnumValue -Enum(mips_arch_opt_value) String(24kfx) Value(57) Canonical +Enum(mips_arch_opt_value) String(24kf) Value(57) Canonical EnumValue -Enum(mips_arch_opt_value) String(r24kfx) Value(57) +Enum(mips_arch_opt_value) String(r24kf) Value(57) EnumValue -Enum(mips_arch_opt_value) String(24kx) Value(58) Canonical +Enum(mips_arch_opt_value) String(24kf1_1) Value(58) Canonical EnumValue -Enum(mips_arch_opt_value) String(r24kx) Value(58) +Enum(mips_arch_opt_value) String(r24kf1_1) Value(58) EnumValue -Enum(mips_arch_opt_value) String(24kec) Value(59) Canonical +Enum(mips_arch_opt_value) String(24kfx) Value(59) Canonical EnumValue -Enum(mips_arch_opt_value) String(r24kec) Value(59) +Enum(mips_arch_opt_value) String(r24kfx) Value(59) EnumValue -Enum(mips_arch_opt_value) String(24kef2_1) Value(60) Canonical +Enum(mips_arch_opt_value) String(24kx) Value(60) Canonical EnumValue -Enum(mips_arch_opt_value) String(r24kef2_1) Value(60) +Enum(mips_arch_opt_value) String(r24kx) Value(60) EnumValue -Enum(mips_arch_opt_value) String(24kef) Value(61) Canonical +Enum(mips_arch_opt_value) String(24kec) Value(61) Canonical EnumValue -Enum(mips_arch_opt_value) String(r24kef) Value(61) +Enum(mips_arch_opt_value) String(r24kec) Value(61) EnumValue -Enum(mips_arch_opt_value) String(24kef1_1) Value(62) Canonical +Enum(mips_arch_opt_value) String(24kef2_1) Value(62) Canonical EnumValue -Enum(mips_arch_opt_value) String(r24kef1_1) Value(62) +Enum(mips_arch_opt_value) String(r24kef2_1) Value(62) EnumValue -Enum(mips_arch_opt_value) String(24kefx) Value(63) Canonical +Enum(mips_arch_opt_value) String(24kef) Value(63) Canonical EnumValue -Enum(mips_arch_opt_value) String(r24kefx) Value(63) +Enum(mips_arch_opt_value) String(r24kef) Value(63) EnumValue -Enum(mips_arch_opt_value) String(24kex) Value(64) Canonical +Enum(mips_arch_opt_value) String(24kef1_1) Value(64) Canonical EnumValue -Enum(mips_arch_opt_value) String(r24kex) Value(64) +Enum(mips_arch_opt_value) String(r24kef1_1) Value(64) EnumValue -Enum(mips_arch_opt_value) String(34kc) Value(65) Canonical +Enum(mips_arch_opt_value) String(24kefx) Value(65) Canonical EnumValue -Enum(mips_arch_opt_value) String(r34kc) Value(65) +Enum(mips_arch_opt_value) String(r24kefx) Value(65) EnumValue -Enum(mips_arch_opt_value) String(34kf2_1) Value(66) Canonical +Enum(mips_arch_opt_value) String(24kex) Value(66) Canonical EnumValue -Enum(mips_arch_opt_value) String(r34kf2_1) Value(66) +Enum(mips_arch_opt_value) String(r24kex) Value(66) EnumValue -Enum(mips_arch_opt_value) String(34kf) Value(67) Canonical +Enum(mips_arch_opt_value) String(34kc) Value(67) Canonical EnumValue -Enum(mips_arch_opt_value) String(r34kf) Value(67) +Enum(mips_arch_opt_value) String(r34kc) Value(67) EnumValue -Enum(mips_arch_opt_value) String(34kf1_1) Value(68) Canonical +Enum(mips_arch_opt_value) String(34kf2_1) Value(68) Canonical EnumValue -Enum(mips_arch_opt_value) String(r34kf1_1) Value(68) +Enum(mips_arch_opt_value) String(r34kf2_1) Value(68) EnumValue -Enum(mips_arch_opt_value) String(34kfx) Value(69) Canonical +Enum(mips_arch_opt_value) String(34kf) Value(69) Canonical EnumValue -Enum(mips_arch_opt_value) String(r34kfx) Value(69) +Enum(mips_arch_opt_value) String(r34kf) Value(69) EnumValue -Enum(mips_arch_opt_value) String(34kx) Value(70) Canonical +Enum(mips_arch_opt_value) String(34kf1_1) Value(70) Canonical EnumValue -Enum(mips_arch_opt_value) String(r34kx) Value(70) +Enum(mips_arch_opt_value) String(r34kf1_1) Value(70) EnumValue -Enum(mips_arch_opt_value) String(34kn) Value(71) Canonical +Enum(mips_arch_opt_value) String(34kfx) Value(71) Canonical EnumValue -Enum(mips_arch_opt_value) String(r34kn) Value(71) +Enum(mips_arch_opt_value) String(r34kfx) Value(71) EnumValue -Enum(mips_arch_opt_value) String(74kc) Value(72) Canonical +Enum(mips_arch_opt_value) String(34kx) Value(72) Canonical EnumValue -Enum(mips_arch_opt_value) String(r74kc) Value(72) +Enum(mips_arch_opt_value) String(r34kx) Value(72) EnumValue -Enum(mips_arch_opt_value) String(74kf2_1) Value(73) Canonical +Enum(mips_arch_opt_value) String(34kn) Value(73) Canonical EnumValue -Enum(mips_arch_opt_value) String(r74kf2_1) Value(73) +Enum(mips_arch_opt_value) String(r34kn) Value(73) EnumValue -Enum(mips_arch_opt_value) String(74kf) Value(74) Canonical +Enum(mips_arch_opt_value) String(74kc) Value(74) Canonical EnumValue -Enum(mips_arch_opt_value) String(r74kf) Value(74) +Enum(mips_arch_opt_value) String(r74kc) Value(74) EnumValue -Enum(mips_arch_opt_value) String(74kf1_1) Value(75) Canonical +Enum(mips_arch_opt_value) String(74kf2_1) Value(75) Canonical EnumValue -Enum(mips_arch_opt_value) String(r74kf1_1) Value(75) +Enum(mips_arch_opt_value) String(r74kf2_1) Value(75) EnumValue -Enum(mips_arch_opt_value) String(74kfx) Value(76) Canonical +Enum(mips_arch_opt_value) String(74kf) Value(76) Canonical EnumValue -Enum(mips_arch_opt_value) String(r74kfx) Value(76) +Enum(mips_arch_opt_value) String(r74kf) Value(76) EnumValue -Enum(mips_arch_opt_value) String(74kx) Value(77) Canonical +Enum(mips_arch_opt_value) String(74kf1_1) Value(77) Canonical EnumValue -Enum(mips_arch_opt_value) String(r74kx) Value(77) +Enum(mips_arch_opt_value) String(r74kf1_1) Value(77) EnumValue -Enum(mips_arch_opt_value) String(74kf3_2) Value(78) Canonical +Enum(mips_arch_opt_value) String(74kfx) Value(78) Canonical EnumValue -Enum(mips_arch_opt_value) String(r74kf3_2) Value(78) +Enum(mips_arch_opt_value) String(r74kfx) Value(78) EnumValue -Enum(mips_arch_opt_value) String(1004kc) Value(79) Canonical +Enum(mips_arch_opt_value) String(74kx) Value(79) Canonical EnumValue -Enum(mips_arch_opt_value) String(r1004kc) Value(79) +Enum(mips_arch_opt_value) String(r74kx) Value(79) EnumValue -Enum(mips_arch_opt_value) String(1004kf2_1) Value(80) Canonical +Enum(mips_arch_opt_value) String(74kf3_2) Value(80) Canonical EnumValue -Enum(mips_arch_opt_value) String(r1004kf2_1) Value(80) +Enum(mips_arch_opt_value) String(r74kf3_2) Value(80) EnumValue -Enum(mips_arch_opt_value) String(1004kf) Value(81) Canonical +Enum(mips_arch_opt_value) String(1004kc) Value(81) Canonical EnumValue -Enum(mips_arch_opt_value) String(r1004kf) Value(81) +Enum(mips_arch_opt_value) String(r1004kc) Value(81) EnumValue -Enum(mips_arch_opt_value) String(1004kf1_1) Value(82) Canonical +Enum(mips_arch_opt_value) String(1004kf2_1) Value(82) Canonical EnumValue -Enum(mips_arch_opt_value) String(r1004kf1_1) Value(82) +Enum(mips_arch_opt_value) String(r1004kf2_1) Value(82) EnumValue -Enum(mips_arch_opt_value) String(p5600) Value(83) Canonical +Enum(mips_arch_opt_value) String(1004kf) Value(83) Canonical EnumValue -Enum(mips_arch_opt_value) String(5kc) Value(84) Canonical +Enum(mips_arch_opt_value) String(r1004kf) Value(83) EnumValue -Enum(mips_arch_opt_value) String(r5kc) Value(84) +Enum(mips_arch_opt_value) String(1004kf1_1) Value(84) Canonical EnumValue -Enum(mips_arch_opt_value) String(5kf) Value(85) Canonical +Enum(mips_arch_opt_value) String(r1004kf1_1) Value(84) EnumValue -Enum(mips_arch_opt_value) String(r5kf) Value(85) +Enum(mips_arch_opt_value) String(p5600) Value(85) Canonical EnumValue -Enum(mips_arch_opt_value) String(20kc) Value(86) Canonical +Enum(mips_arch_opt_value) String(5kc) Value(86) Canonical EnumValue -Enum(mips_arch_opt_value) String(r20kc) Value(86) +Enum(mips_arch_opt_value) String(r5kc) Value(86) EnumValue -Enum(mips_arch_opt_value) String(sb1) Value(87) Canonical +Enum(mips_arch_opt_value) String(5kf) Value(87) Canonical EnumValue -Enum(mips_arch_opt_value) String(sb1a) Value(88) Canonical +Enum(mips_arch_opt_value) String(r5kf) Value(87) EnumValue -Enum(mips_arch_opt_value) String(sr71000) Value(89) Canonical +Enum(mips_arch_opt_value) String(20kc) Value(88) Canonical EnumValue -Enum(mips_arch_opt_value) String(sr71k) Value(89) +Enum(mips_arch_opt_value) String(r20kc) Value(88) EnumValue -Enum(mips_arch_opt_value) String(xlr) Value(90) Canonical +Enum(mips_arch_opt_value) String(sb1) Value(89) Canonical EnumValue -Enum(mips_arch_opt_value) String(loongson3a) Value(91) Canonical +Enum(mips_arch_opt_value) String(sb1a) Value(90) Canonical EnumValue -Enum(mips_arch_opt_value) String(octeon) Value(92) Canonical +Enum(mips_arch_opt_value) String(sr71000) Value(91) Canonical EnumValue -Enum(mips_arch_opt_value) String(octeon+) Value(93) Canonical +Enum(mips_arch_opt_value) String(sr71k) Value(91) EnumValue -Enum(mips_arch_opt_value) String(octeon2) Value(94) Canonical +Enum(mips_arch_opt_value) String(xlr) Value(92) Canonical EnumValue -Enum(mips_arch_opt_value) String(octeon3) Value(95) Canonical +Enum(mips_arch_opt_value) String(loongson3a) Value(93) Canonical EnumValue -Enum(mips_arch_opt_value) String(xlp) Value(96) Canonical +Enum(mips_arch_opt_value) String(octeon) Value(94) Canonical + +EnumValue +Enum(mips_arch_opt_value) String(octeon+) Value(95) Canonical + +EnumValue +Enum(mips_arch_opt_value) String(octeon2) Value(96) Canonical + +EnumValue +Enum(mips_arch_opt_value) String(octeon3) Value(97) Canonical + +EnumValue +Enum(mips_arch_opt_value) String(xlp) Value(98) Canonical diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 1aea23e..3b8daca 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -182,9 +182,10 @@ along with GCC; see the file COPYING3. If not see #define MIPS_LUI(DEST, VALUE) \ ((0xf << 26) | ((DEST) << 16) | (VALUE)) -/* Return the opcode to jump to register DEST. */ +/* Return the opcode to jump to register DEST. When the JR opcode is not + available use JALR $0, DEST. */ #define MIPS_JR(DEST) \ - (((DEST) << 21) | 0x8) + (((DEST) << 21) | (ISA_HAS_JR ? 0x8 : 0x9)) /* Return the opcode for: @@ -1225,6 +1226,32 @@ static const struct mips_rtx_cost_data COSTS_N_INSNS (8), /* int_div_di */ 2, /* branch_cost */ 4 /* memory_latency */ + }, + { /* W32 */ + COSTS_N_INSNS (4), /* fp_add */ + COSTS_N_INSNS (4), /* fp_mult_sf */ + COSTS_N_INSNS (5), /* fp_mult_df */ + COSTS_N_INSNS (17), /* fp_div_sf */ + COSTS_N_INSNS (32), /* fp_div_df */ + COSTS_N_INSNS (5), /* int_mult_si */ + COSTS_N_INSNS (5), /* int_mult_di */ + COSTS_N_INSNS (41), /* int_div_si */ + COSTS_N_INSNS (41), /* int_div_di */ + 1, /* branch_cost */ + 4 /* memory_latency */ + }, + { /* W64 */ + COSTS_N_INSNS (4), /* fp_add */ + COSTS_N_INSNS (4), /* fp_mult_sf */ + COSTS_N_INSNS (5), /* fp_mult_df */ + COSTS_N_INSNS (17), /* fp_div_sf */ + COSTS_N_INSNS (32), /* fp_div_df */ + COSTS_N_INSNS (5), /* int_mult_si */ + COSTS_N_INSNS (5), /* int_mult_di */ + COSTS_N_INSNS (41), /* int_div_si */ + COSTS_N_INSNS (41), /* int_div_di */ + 1, /* branch_cost */ + 4 /* memory_latency */ } }; @@ -2593,6 +2620,20 @@ umips_12bit_offset_address_p (rtx x, machine_mode mode) && UMIPS_12BIT_OFFSET_P (INTVAL (addr.offset))); } +/* Return true if X is a legitimate address with a 9-bit offset. + MODE is the mode of the value being accessed. */ + +bool +mips_9bit_offset_address_p (rtx x, machine_mode mode) +{ + struct mips_address_info addr; + + return (mips_classify_address (&addr, x, mode, false) + && addr.type == ADDRESS_REG + && CONST_INT_P (addr.offset) + && MIPS_9BIT_OFFSET_P (INTVAL (addr.offset))); +} + /* Return the number of instructions needed to load constant X, assuming that BASE_INSN_LENGTH is the length of one instruction. Return 0 if X isn't a valid constant. */ @@ -4102,6 +4143,11 @@ mips_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED, *total = COSTS_N_INSNS (GET_MODE_SIZE (mode) > UNITS_PER_WORD ? 4 : 1); return false; + case FMA: + if (ISA_HAS_FP_MADDF_MSUBF) + *total = mips_fp_mult_cost (mode); + return false; + case MULT: if (float_mode_p) *total = mips_fp_mult_cost (mode); @@ -4112,7 +4158,7 @@ mips_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED, ? mips_cost->int_mult_si * 3 + 6 : COSTS_N_INSNS (ISA_HAS_MUL3 ? 7 : 9)); else if (!speed) - *total = COSTS_N_INSNS (ISA_HAS_MUL3 ? 1 : 2) + 1; + *total = COSTS_N_INSNS ((ISA_HAS_MUL3 || ISA_HAS_R6MUL) ? 1 : 2) + 1; else if (mode == DImode) *total = mips_cost->int_mult_di; else @@ -4188,6 +4234,52 @@ mips_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED, } *total = mips_zero_extend_cost (mode, XEXP (x, 0)); return false; + case TRUNCATE: + /* Costings for highpart multiplies. Matching patterns of the form: + + (lshiftrt:DI (mult:DI (sign_extend:DI (...) + (sign_extend:DI (...)) + (const_int 32) + */ + if (ISA_HAS_R6MUL + && (GET_CODE (XEXP (x, 0)) == ASHIFTRT + || GET_CODE (XEXP (x, 0)) == LSHIFTRT) + && CONST_INT_P (XEXP (XEXP (x, 0), 1)) + && ((INTVAL (XEXP (XEXP (x, 0), 1)) == 32 + && GET_MODE (XEXP (x, 0)) == DImode) + || (ISA_HAS_R6DMUL + && INTVAL (XEXP (XEXP (x, 0), 1)) == 64 + && GET_MODE (XEXP (x, 0)) == TImode)) + && GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT + && ((GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == SIGN_EXTEND + && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1)) == SIGN_EXTEND) + || (GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == ZERO_EXTEND + && (GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1)) + == ZERO_EXTEND)))) + { + if (!speed) + *total = COSTS_N_INSNS (1) + 1; + else if (mode == DImode) + *total = mips_cost->int_mult_di; + else + *total = mips_cost->int_mult_si; + + /* Sign extension is free, zero extension costs for DImode when + on a 64bit core / when DMUL is present. */ + for (int i = 0; i < 2; ++i) + { + rtx op = XEXP (XEXP (XEXP (x, 0), 0), i); + if (ISA_HAS_R6DMUL + && GET_CODE (op) == ZERO_EXTEND + && GET_MODE (op) == DImode) + *total += rtx_cost (op, MULT, i, speed); + else + *total += rtx_cost (XEXP (op, 0), GET_CODE (op), 0, speed); + } + + return true; + } + return false; case FLOAT: case UNSIGNED_FLOAT: @@ -4971,17 +5063,32 @@ mips_emit_compare (enum rtx_code *code, rtx *op0, rtx *op1, bool need_eq_ne_p) { enum rtx_code cmp_code; - /* Floating-point tests use a separate C.cond.fmt comparison to - set a condition code register. The branch or conditional move - will then compare that register against zero. + /* Floating-point tests use a separate C.cond.fmt or CMP.cond.fmt + comparison to set a register. The branch or conditional move will + then compare that register against zero. Set CMP_CODE to the code of the comparison instruction and *CODE to the code that the branch or move should use. */ cmp_code = *code; - *code = mips_reversed_fp_cond (&cmp_code) ? EQ : NE; - *op0 = (ISA_HAS_8CC - ? mips_allocate_fcc (CCmode) - : gen_rtx_REG (CCmode, FPSW_REGNUM)); + if (ISA_HAS_CCF) + { + /* All FP conditions can be implemented directly with CMP.cond.fmt + or by reversing the operands. */ + *code = NE; + *op0 = gen_reg_rtx (CCFmode); + } + else + { + /* Three FP conditions cannot be implemented by reversing the + operands for C.cond.fmt, instead a reversed condition code is + required and a test for false. */ + *code = mips_reversed_fp_cond (&cmp_code) ? EQ : NE; + if (ISA_HAS_8CC) + *op0 = mips_allocate_fcc (CCmode); + else + *op0 = gen_rtx_REG (CCmode, FPSW_REGNUM); + } + *op1 = const0_rtx; mips_emit_binary (cmp_code, *op0, cmp_op0, cmp_op1); } @@ -5071,9 +5178,45 @@ mips_expand_conditional_move (rtx *operands) mips_emit_compare (&code, &op0, &op1, true); cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1); - emit_insn (gen_rtx_SET (VOIDmode, operands[0], - gen_rtx_IF_THEN_ELSE (GET_MODE (operands[0]), cond, - operands[2], operands[3]))); + + /* There is no direct support for general conditional GP move involving + two registers using SEL. */ + if (ISA_HAS_SEL + && INTEGRAL_MODE_P (GET_MODE (operands[2])) + && register_operand (operands[2], VOIDmode) + && register_operand (operands[3], VOIDmode)) + { + machine_mode mode = GET_MODE (operands[0]); + rtx temp = gen_reg_rtx (mode); + rtx temp2 = gen_reg_rtx (mode); + + emit_insn (gen_rtx_SET (VOIDmode, temp, + gen_rtx_IF_THEN_ELSE (mode, cond, + operands[2], const0_rtx))); + + /* Flip the test for the second operand. */ + cond = gen_rtx_fmt_ee ((code == EQ) ? NE : EQ, GET_MODE (op0), op0, op1); + + emit_insn (gen_rtx_SET (VOIDmode, temp2, + gen_rtx_IF_THEN_ELSE (mode, cond, + operands[3], const0_rtx))); + + /* Merge the two results, at least one is guaranteed to be zero. */ + emit_insn (gen_rtx_SET (VOIDmode, operands[0], + gen_rtx_IOR (mode, temp, temp2))); + } + else + { + if (FLOAT_MODE_P (GET_MODE (operands[2])) && !ISA_HAS_SEL) + { + operands[2] = force_reg (GET_MODE (operands[0]), operands[2]); + operands[3] = force_reg (GET_MODE (operands[0]), operands[3]); + } + + emit_insn (gen_rtx_SET (VOIDmode, operands[0], + gen_rtx_IF_THEN_ELSE (GET_MODE (operands[0]), cond, + operands[2], operands[3]))); + } } /* Perform the comparison in COMPARISON, then trap if the condition holds. */ @@ -5107,7 +5250,9 @@ mips_expand_conditional_trap (rtx comparison) mode = GET_MODE (XEXP (comparison, 0)); op0 = force_reg (mode, op0); - if (!arith_operand (op1, mode)) + if (!(ISA_HAS_COND_TRAPI + ? arith_operand (op1, mode) + : reg_or_0_operand (op1, mode))) op1 = force_reg (mode, op1); emit_insn (gen_rtx_TRAP_IF (VOIDmode, @@ -7469,6 +7614,10 @@ mips_block_move_loop (rtx dest, rtx src, HOST_WIDE_INT length, bool mips_expand_block_move (rtx dest, rtx src, rtx length) { + /* Disable entirely for R6 initially. */ + if (!ISA_HAS_LWL_LWR) + return false; + if (CONST_INT_P (length)) { if (INTVAL (length) <= MIPS_MAX_MOVE_BYTES_STRAIGHT) @@ -8231,11 +8380,17 @@ mips_print_float_branch_condition (FILE *file, enum rtx_code code, int letter) switch (code) { case EQ: - fputs ("c1f", file); + if (ISA_HAS_CCF) + fputs ("c1eqz", file); + else + fputs ("c1f", file); break; case NE: - fputs ("c1t", file); + if (ISA_HAS_CCF) + fputs ("c1nez", file); + else + fputs ("c1t", file); break; default: @@ -8365,7 +8520,7 @@ mips_print_operand (FILE *file, rtx op, int letter) break; case 'Z': - if (ISA_HAS_8CC) + if (ISA_HAS_8CC || ISA_HAS_CCF) { mips_print_operand (file, op, 0); fputc (',', file); @@ -9917,7 +10072,8 @@ mips_must_initialize_gp_p (void) static bool mips_interrupt_extra_call_saved_reg_p (unsigned int regno) { - if (MD_REG_P (regno)) + if ((ISA_HAS_HILO || TARGET_DSP) + && MD_REG_P (regno)) return true; if (TARGET_DSP && DSP_ACC_REG_P (regno)) @@ -11891,7 +12047,7 @@ mips_hard_regno_mode_ok_p (unsigned int regno, machine_mode mode) size = GET_MODE_SIZE (mode); mclass = GET_MODE_CLASS (mode); - if (GP_REG_P (regno)) + if (GP_REG_P (regno) && mode != CCFmode) return ((regno - GP_REG_FIRST) & 1) == 0 || size <= UNITS_PER_WORD; if (FP_REG_P (regno) @@ -11903,6 +12059,13 @@ mips_hard_regno_mode_ok_p (unsigned int regno, machine_mode mode) if (TARGET_O32_FP64A_ABI && size <= 4 && (regno & 1) != 0) return false; + /* The FPXX ABI requires double-precision values to be placed in + even-numbered registers. Disallow odd-numbered registers with + CCFmode because CCFmode double-precision compares will write a + 64-bit value to a register. */ + if (mode == CCFmode) + return !(TARGET_FLOATXX && (regno & 1) != 0); + /* Allow 64-bit vector modes for Loongson-2E/2F. */ if (TARGET_LOONGSON_VECTORS && (mode == V2SImode @@ -12062,6 +12225,7 @@ mips_mode_ok_for_mov_fmt_p (machine_mode mode) { switch (mode) { + case CCFmode: case SFmode: return TARGET_HARD_FLOAT; @@ -15934,8 +16098,10 @@ mips_mult_zero_zero_cost (struct mips_sim *state, bool setting) static void mips_set_fast_mult_zero_zero_p (struct mips_sim *state) { - if (TARGET_MIPS16) - /* No MTLO or MTHI available. */ + if (TARGET_MIPS16 || !ISA_HAS_HILO) + /* No MTLO or MTHI available for MIPS16. Also, when there are no HI or LO + registers then there is no reason to zero them, arbitrarily choose to + say that "MULT $0,$0" would be faster. */ mips_tuning_info.fast_mult_zero_zero_p = true; else { @@ -17179,7 +17345,10 @@ mips_option_override (void) if ((target_flags_explicit & MASK_FLOAT64) != 0) { - if (TARGET_SINGLE_FLOAT && TARGET_FLOAT64) + if (mips_isa_rev >= 6 && !TARGET_FLOAT64) + error ("the %qs architecture does not support %<-mfp32%>", + mips_arch_info->name); + else if (TARGET_SINGLE_FLOAT && TARGET_FLOAT64) error ("unsupported combination: %s", "-mfp64 -msingle-float"); else if (TARGET_64BIT && TARGET_DOUBLE_FLOAT && !TARGET_FLOAT64) error ("unsupported combination: %s", "-mgp64 -mfp32 -mdouble-float"); @@ -17195,9 +17364,13 @@ mips_option_override (void) } else { - /* -msingle-float selects 32-bit float registers. Otherwise the - float registers should be the same size as the integer ones. */ - if (TARGET_64BIT && TARGET_DOUBLE_FLOAT) + /* -msingle-float selects 32-bit float registers. On r6 and later, + -mdouble-float selects 64-bit float registers, since the old paired + register model is not supported. In other cases the float registers + should be the same size as the integer ones. */ + if (mips_isa_rev >= 6 && TARGET_DOUBLE_FLOAT && !TARGET_FLOATXX) + target_flags |= MASK_FLOAT64; + else if (TARGET_64BIT && TARGET_DOUBLE_FLOAT) target_flags |= MASK_FLOAT64; else target_flags &= ~MASK_FLOAT64; @@ -17205,6 +17378,8 @@ mips_option_override (void) if (mips_abi != ABI_32 && TARGET_FLOATXX) error ("%<-mfpxx%> can only be used with the o32 ABI"); + else if (TARGET_FLOAT64 && TARGET_FLOATXX) + error ("unsupported combination: %s", "-mfp64 -mfpxx"); else if (ISA_MIPS1 && !TARGET_FLOAT32) error ("%<-march=%s%> requires %<-mfp32%>", mips_arch_info->name); else if (TARGET_FLOATXX && !mips_lra_flag) @@ -17382,6 +17557,27 @@ mips_option_override (void) } } + /* Set NaN and ABS defaults. */ + if (mips_nan == MIPS_IEEE_754_DEFAULT && !ISA_HAS_IEEE_754_LEGACY) + mips_nan = MIPS_IEEE_754_2008; + if (mips_abs == MIPS_IEEE_754_DEFAULT && !ISA_HAS_IEEE_754_LEGACY) + mips_abs = MIPS_IEEE_754_2008; + + /* Check for IEEE 754 legacy/2008 support. */ + if ((mips_nan == MIPS_IEEE_754_LEGACY + || mips_abs == MIPS_IEEE_754_LEGACY) + && !ISA_HAS_IEEE_754_LEGACY) + warning (0, "the %qs architecture does not support %<-m%s=legacy%>", + mips_arch_info->name, + mips_nan == MIPS_IEEE_754_LEGACY ? "nan" : "abs"); + + if ((mips_nan == MIPS_IEEE_754_2008 + || mips_abs == MIPS_IEEE_754_2008) + && !ISA_HAS_IEEE_754_2008) + warning (0, "the %qs architecture does not support %<-m%s=2008%>", + mips_arch_info->name, + mips_nan == MIPS_IEEE_754_2008 ? "nan" : "abs"); + /* Pre-IEEE 754-2008 MIPS hardware has a quirky almost-IEEE format for all its floating point. */ if (mips_nan != MIPS_IEEE_754_2008) @@ -17436,6 +17632,14 @@ mips_option_override (void) if (TARGET_DSPR2) TARGET_DSP = true; + if (TARGET_DSP && mips_isa_rev >= 6) + { + error ("the %qs architecture does not support DSP instructions", + mips_arch_info->name); + TARGET_DSP = false; + TARGET_DSPR2 = false; + } + /* .eh_frame addresses should be the same width as a C pointer. Most MIPS ABIs support only one pointer size, so the assembler will usually know exactly how big an .eh_frame address is. @@ -17616,6 +17820,10 @@ mips_conditional_register_usage (void) AND_COMPL_HARD_REG_SET (accessible_reg_set, reg_class_contents[(int) DSP_ACC_REGS]); + if (!ISA_HAS_HILO) + AND_COMPL_HARD_REG_SET (accessible_reg_set, + reg_class_contents[(int) MD_REGS]); + if (!TARGET_HARD_FLOAT) { AND_COMPL_HARD_REG_SET (accessible_reg_set, @@ -17630,7 +17838,8 @@ mips_conditional_register_usage (void) RTL that refers directly to ST_REG_FIRST. */ AND_COMPL_HARD_REG_SET (accessible_reg_set, reg_class_contents[(int) ST_REGS]); - SET_HARD_REG_BIT (accessible_reg_set, FPSW_REGNUM); + if (!ISA_HAS_CCF) + SET_HARD_REG_BIT (accessible_reg_set, FPSW_REGNUM); fixed_regs[FPSW_REGNUM] = call_used_regs[FPSW_REGNUM] = 1; } if (TARGET_MIPS16) @@ -17805,6 +18014,8 @@ mips_mulsidi3_gen_fn (enum rtx_code ext_code) the extension is not needed for signed multiplication. In order to ensure that we always remove the redundant sign-extension in this case we still expand mulsidi3 for DMUL. */ + if (ISA_HAS_R6DMUL) + return signed_p ? gen_mulsidi3_64bit_r6dmul : NULL; if (ISA_HAS_DMUL3) return signed_p ? gen_mulsidi3_64bit_dmul : NULL; if (TARGET_MIPS16) @@ -17817,6 +18028,8 @@ mips_mulsidi3_gen_fn (enum rtx_code ext_code) } else { + if (ISA_HAS_R6MUL) + return (signed_p ? gen_mulsidi3_32bit_r6 : gen_umulsidi3_32bit_r6); if (TARGET_MIPS16) return (signed_p ? gen_mulsidi3_32bit_mips16 diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index 8a38829..4da256d 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -210,10 +210,12 @@ struct mips_cpu_info { #define ISA_MIPS32R2 (mips_isa == 33) #define ISA_MIPS32R3 (mips_isa == 34) #define ISA_MIPS32R5 (mips_isa == 36) +#define ISA_MIPS32R6 (mips_isa == 37) #define ISA_MIPS64 (mips_isa == 64) #define ISA_MIPS64R2 (mips_isa == 65) #define ISA_MIPS64R3 (mips_isa == 66) #define ISA_MIPS64R5 (mips_isa == 68) +#define ISA_MIPS64R6 (mips_isa == 69) /* Architecture target defines. */ #define TARGET_LOONGSON_2E (mips_arch == PROCESSOR_LOONGSON_2E) @@ -458,42 +460,12 @@ struct mips_cpu_info { builtin_define ("__mips=4"); \ builtin_define ("_MIPS_ISA=_MIPS_ISA_MIPS4"); \ } \ - else if (ISA_MIPS32) \ + else if (mips_isa >= 32 && mips_isa < 64) \ { \ builtin_define ("__mips=32"); \ builtin_define ("_MIPS_ISA=_MIPS_ISA_MIPS32"); \ } \ - else if (ISA_MIPS32R2) \ - { \ - builtin_define ("__mips=32"); \ - builtin_define ("_MIPS_ISA=_MIPS_ISA_MIPS32"); \ - } \ - else if (ISA_MIPS32R3) \ - { \ - builtin_define ("__mips=32"); \ - builtin_define ("_MIPS_ISA=_MIPS_ISA_MIPS32"); \ - } \ - else if (ISA_MIPS32R5) \ - { \ - builtin_define ("__mips=32"); \ - builtin_define ("_MIPS_ISA=_MIPS_ISA_MIPS32"); \ - } \ - else if (ISA_MIPS64) \ - { \ - builtin_define ("__mips=64"); \ - builtin_define ("_MIPS_ISA=_MIPS_ISA_MIPS64"); \ - } \ - else if (ISA_MIPS64R2) \ - { \ - builtin_define ("__mips=64"); \ - builtin_define ("_MIPS_ISA=_MIPS_ISA_MIPS64"); \ - } \ - else if (ISA_MIPS64R3) \ - { \ - builtin_define ("__mips=64"); \ - builtin_define ("_MIPS_ISA=_MIPS_ISA_MIPS64"); \ - } \ - else if (ISA_MIPS64R5) \ + else if (mips_isa >= 64) \ { \ builtin_define ("__mips=64"); \ builtin_define ("_MIPS_ISA=_MIPS_ISA_MIPS64"); \ @@ -673,10 +645,14 @@ struct mips_cpu_info { #define MULTILIB_ISA_DEFAULT "mips32" #elif MIPS_ISA_DEFAULT == 33 #define MULTILIB_ISA_DEFAULT "mips32r2" +#elif MIPS_ISA_DEFAULT == 37 +#define MULTILIB_ISA_DEFAULT "mips32r6" #elif MIPS_ISA_DEFAULT == 64 #define MULTILIB_ISA_DEFAULT "mips64" #elif MIPS_ISA_DEFAULT == 65 #define MULTILIB_ISA_DEFAULT "mips64r2" +#elif MIPS_ISA_DEFAULT == 69 +#define MULTILIB_ISA_DEFAULT "mips64r6" #else #define MULTILIB_ISA_DEFAULT "mips1" #endif @@ -743,11 +719,13 @@ struct mips_cpu_info { |march=34k*|march=74k*|march=m14k*|march=1004k*: -mips32r2} \ %{march=mips32r3: -mips32r3} \ %{march=mips32r5|march=p5600: -mips32r5} \ + %{march=mips32r6: -mips32r6} \ %{march=mips64|march=5k*|march=20k*|march=sb1*|march=sr71000 \ |march=xlr: -mips64} \ %{march=mips64r2|march=loongson3a|march=octeon|march=xlp: -mips64r2} \ %{march=mips64r3: -mips64r3} \ %{march=mips64r5: -mips64r5} \ + %{march=mips64r6: -mips64r6} \ %{!march=*: -" MULTILIB_ISA_DEFAULT "}}" /* A spec that infers a -mhard-float or -msoft-float setting from an @@ -776,8 +754,11 @@ struct mips_cpu_info { /* Infer a -msynci setting from a -mips argument, on the assumption that -msynci is desired where possible. */ #define MIPS_ISA_SYNCI_SPEC \ - "%{msynci|mno-synci:;:%{mips32r2|mips32r3|mips32r5|mips64r2|mips64r3 \ - |mips64r5:-msynci;:-mno-synci}}" + "%{msynci|mno-synci:;:%{mips32r2|mips32r3|mips32r5|mips32r6|mips64r2 \ + |mips64r3|mips64r5|mips64r6:-msynci;:-mno-synci}}" + +#define MIPS_ISA_NAN2008_SPEC \ + "%{mnan*:;mips32r6|mips64r6:-mnan=2008}" #if (MIPS_ABI_DEFAULT == ABI_O64 \ || MIPS_ABI_DEFAULT == ABI_N32 \ @@ -827,11 +808,14 @@ struct mips_cpu_info { /* A spec that infers the -mdsp setting from an -march argument. */ #define BASE_DRIVER_SELF_SPECS \ + MIPS_ISA_NAN2008_SPEC, \ "%{!mno-dsp: \ %{march=24ke*|march=34kc*|march=34kf*|march=34kx*|march=1004k*: -mdsp} \ %{march=74k*|march=m14ke*: %{!mno-dspr2: -mdspr2 -mdsp}}}" -#define DRIVER_SELF_SPECS BASE_DRIVER_SELF_SPECS +#define DRIVER_SELF_SPECS \ + MIPS_ISA_LEVEL_SPEC, \ + BASE_DRIVER_SELF_SPECS #define GENERATE_DIVIDE_TRAPS (TARGET_DIVIDE_TRAPS \ && ISA_HAS_COND_TRAP) @@ -864,12 +848,15 @@ struct mips_cpu_info { || ISA_MIPS64 \ || ISA_MIPS64R2 \ || ISA_MIPS64R3 \ - || ISA_MIPS64R5) + || ISA_MIPS64R5 \ + || ISA_MIPS64R6) + +#define ISA_HAS_JR (mips_isa_rev <= 5) /* ISA has branch likely instructions (e.g. mips2). */ /* Disable branchlikely for tx39 until compare rewrite. They haven't been generated up to this point. */ -#define ISA_HAS_BRANCHLIKELY (!ISA_MIPS1) +#define ISA_HAS_BRANCHLIKELY (!ISA_MIPS1 && mips_isa_rev <= 5) /* ISA has 32 single-precision registers. */ #define ISA_HAS_ODD_SPREG ((mips_isa_rev >= 1 \ @@ -885,7 +872,8 @@ struct mips_cpu_info { || TARGET_MIPS7000 \ || TARGET_MIPS9000 \ || TARGET_MAD \ - || mips_isa_rev >= 1) \ + || (mips_isa_rev >= 1 \ + && mips_isa_rev <= 5)) \ && !TARGET_MIPS16) /* ISA has a three-operand multiplication instruction. */ @@ -893,30 +881,48 @@ struct mips_cpu_info { && TARGET_OCTEON \ && !TARGET_MIPS16) +/* ISA has HI and LO registers. */ +#define ISA_HAS_HILO (mips_isa_rev <= 5) + /* ISA supports instructions DMULT and DMULTU. */ -#define ISA_HAS_DMULT (TARGET_64BIT && !TARGET_MIPS5900) +#define ISA_HAS_DMULT (TARGET_64BIT \ + && !TARGET_MIPS5900 \ + && mips_isa_rev <= 5) -/* ISA supports instructions MULT and MULTU. - This is always true, but the macro is needed for ISA_HAS_<D>MULT - in mips.md. */ -#define ISA_HAS_MULT (1) +/* ISA supports instructions MULT and MULTU. */ +#define ISA_HAS_MULT (mips_isa_rev <= 5) + +/* ISA supports instructions MUL, MULU, MUH, MUHU. */ +#define ISA_HAS_R6MUL (mips_isa_rev >= 6) + +/* ISA supports instructions DMUL, DMULU, DMUH, DMUHU. */ +#define ISA_HAS_R6DMUL (TARGET_64BIT && mips_isa_rev >= 6) /* ISA supports instructions DDIV and DDIVU. */ -#define ISA_HAS_DDIV (TARGET_64BIT && !TARGET_MIPS5900) +#define ISA_HAS_DDIV (TARGET_64BIT \ + && !TARGET_MIPS5900 \ + && mips_isa_rev <= 5) /* ISA supports instructions DIV and DIVU. This is always true, but the macro is needed for ISA_HAS_<D>DIV in mips.md. */ -#define ISA_HAS_DIV (1) +#define ISA_HAS_DIV (mips_isa_rev <= 5) #define ISA_HAS_DIV3 ((TARGET_LOONGSON_2EF \ || TARGET_LOONGSON_3A) \ && !TARGET_MIPS16) +/* ISA supports instructions DIV, DIVU, MOD and MODU. */ +#define ISA_HAS_R6DIV (mips_isa_rev >= 6) + +/* ISA supports instructions DDIV, DDIVU, DMOD and DMODU. */ +#define ISA_HAS_R6DDIV (TARGET_64BIT && mips_isa_rev >= 6) + /* ISA has the floating-point conditional move instructions introduced in mips4. */ #define ISA_HAS_FP_CONDMOVE ((ISA_MIPS4 \ - || mips_isa_rev >= 1) \ + || (mips_isa_rev >= 1 \ + && mips_isa_rev <= 5)) \ && !TARGET_MIPS5500 \ && !TARGET_MIPS16) @@ -933,7 +939,15 @@ struct mips_cpu_info { /* ISA has the mips4 FP condition code instructions: FP-compare to CC, branch on CC, and move (both FP and non-FP) on CC. */ -#define ISA_HAS_8CC (ISA_MIPS4 || mips_isa_rev >= 1) +#define ISA_HAS_8CC (ISA_MIPS4 \ + || (mips_isa_rev >= 1 \ + && mips_isa_rev <= 5)) + +/* ISA has the FP condition code instructions that store the flag in an + FP register. */ +#define ISA_HAS_CCF (mips_isa_rev >= 6) + +#define ISA_HAS_SEL (mips_isa_rev >= 6) /* This is a catch all for other mips4 instructions: indexed load, the FP madd and msub instructions, and the FP recip and recip sqrt @@ -941,7 +955,8 @@ struct mips_cpu_info { ISA_HAS_* macros. */ #define ISA_HAS_FP4 ((ISA_MIPS4 \ || ISA_MIPS64 \ - || mips_isa_rev >= 2) \ + || (mips_isa_rev >= 2 \ + && mips_isa_rev <= 5)) \ && !TARGET_MIPS16) /* ISA has floating-point indexed load and store instructions @@ -949,14 +964,22 @@ struct mips_cpu_info { #define ISA_HAS_LXC1_SXC1 ISA_HAS_FP4 /* ISA has paired-single instructions. */ -#define ISA_HAS_PAIRED_SINGLE (ISA_MIPS64 || mips_isa_rev >= 2) +#define ISA_HAS_PAIRED_SINGLE (ISA_MIPS64 \ + || (mips_isa_rev >= 2 \ + && mips_isa_rev <= 5)) /* ISA has conditional trap instructions. */ #define ISA_HAS_COND_TRAP (!ISA_MIPS1 \ && !TARGET_MIPS16) +/* ISA has conditional trap with immediate instructions. */ +#define ISA_HAS_COND_TRAPI (!ISA_MIPS1 \ + && mips_isa_rev <= 5 \ + && !TARGET_MIPS16) + /* ISA has integer multiply-accumulate instructions, madd and msub. */ -#define ISA_HAS_MADD_MSUB (mips_isa_rev >= 1) +#define ISA_HAS_MADD_MSUB (mips_isa_rev >= 1 \ + && mips_isa_rev <= 5) /* Integer multiply-accumulate instructions should be generated. */ #define GENERATE_MADD_MSUB (TARGET_IMADD && !TARGET_MIPS16) @@ -964,6 +987,9 @@ struct mips_cpu_info { /* ISA has floating-point madd and msub instructions 'd = a * b [+-] c'. */ #define ISA_HAS_FP_MADD4_MSUB4 ISA_HAS_FP4 +/* ISA has floating-point MADDF and MSUBF instructions 'd = d [+-] a * b'. */ +#define ISA_HAS_FP_MADDF_MSUBF (mips_isa_rev >= 6) + /* ISA has floating-point madd and msub instructions 'c = a * b [+-] c'. */ #define ISA_HAS_FP_MADD3_MSUB3 TARGET_LOONGSON_2EF @@ -985,10 +1011,19 @@ struct mips_cpu_info { || ((TARGET_FLOAT64 \ || mips_isa_rev >= 2) \ && (MODE) == DFmode))) \ + || (((MODE) == SFmode \ + || (MODE) == DFmode) \ + && (mips_isa_rev >= 6)) \ || (TARGET_SB1 \ && (MODE) == V2SFmode)) \ && !TARGET_MIPS16) +#define ISA_HAS_LWL_LWR (mips_isa_rev <= 5 && !TARGET_MIPS16) + +#define ISA_HAS_IEEE_754_LEGACY (mips_isa_rev <= 5) + +#define ISA_HAS_IEEE_754_2008 (mips_isa_rev >= 2) + /* ISA has count leading zeroes/ones instruction (not implemented). */ #define ISA_HAS_CLZ_CLO (mips_isa_rev >= 1 && !TARGET_MIPS16) @@ -1046,6 +1081,9 @@ struct mips_cpu_info { || mips_isa_rev >= 1) \ && !TARGET_MIPS16) +/* ISA has data prefetch with limited 9-bit displacement. */ +#define ISA_HAS_PREFETCH_9BIT (mips_isa_rev >= 6) + /* ISA has data indexed prefetch instructions. This controls use of 'prefx', along with TARGET_HARD_FLOAT and TARGET_DOUBLE_FLOAT. (prefx is a cop1x instruction, so can only be used if FP is @@ -2133,6 +2171,7 @@ enum reg_class #define SMALL_INT_UNSIGNED(X) SMALL_OPERAND_UNSIGNED (INTVAL (X)) #define LUI_INT(X) LUI_OPERAND (INTVAL (X)) #define UMIPS_12BIT_OFFSET_P(OFFSET) (IN_RANGE (OFFSET, -2048, 2047)) +#define MIPS_9BIT_OFFSET_P(OFFSET) (IN_RANGE (OFFSET, -256, 255)) /* The HI and LO registers can only be reloaded via the general registers. Condition code registers can only be loaded to the diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index 65c0a3f..bdcd694 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -67,6 +67,8 @@ xlr xlp p5600 + w32 + w64 ]) (define_c_enum "unspec" [ @@ -768,6 +770,11 @@ && !TARGET_LOONGSON_2EF && !TARGET_MIPS5900")]) +;; This mode iterator allows :FPCC to be used anywhere that an FP condition +;; is needed. +(define_mode_iterator FPCC [(CC "!ISA_HAS_CCF") + (CCF "ISA_HAS_CCF")]) + ;; 32-bit integer moves for which we provide move patterns. (define_mode_iterator IMOVE32 [SI @@ -857,7 +864,7 @@ ;; This attribute gives the best constraint to use for registers of ;; a given mode. -(define_mode_attr reg [(SI "d") (DI "d") (CC "z")]) +(define_mode_attr reg [(SI "d") (DI "d") (CC "z") (CCF "f")]) ;; This attribute gives the format suffix for floating-point operations. (define_mode_attr fmt [(SF "s") (DF "d") (V2SF "ps")]) @@ -897,6 +904,9 @@ (define_mode_attr sqrt_condition [(SF "!ISA_MIPS1") (DF "!ISA_MIPS1") (V2SF "TARGET_SB1")]) +;; This attribute provides the correct mnemonic for each FP condition mode. +(define_mode_attr fpcmp [(CC "c") (CCF "cmp")]) + ;; This code iterator allows signed and unsigned widening multiplications ;; to use the same template. (define_code_iterator any_extend [sign_extend zero_extend]) @@ -919,7 +929,10 @@ ;; This code iterator allows all native floating-point comparisons to be ;; generated from the same template. -(define_code_iterator fcond [unordered uneq unlt unle eq lt le]) +(define_code_iterator fcond [unordered uneq unlt unle eq lt le + (ordered "ISA_HAS_CCF") + (ltgt "ISA_HAS_CCF") + (ne "ISA_HAS_CCF")]) ;; This code iterator is used for comparisons that can be implemented ;; by swapping the operands. @@ -992,7 +1005,10 @@ (unle "ule") (eq "eq") (lt "lt") - (le "le")]) + (le "le") + (ordered "or") + (ltgt "ne") + (ne "une")]) ;; Similar, but for swapped conditions. (define_code_attr swapped_fcond [(ge "le") @@ -1006,6 +1022,10 @@ ;; This is the inverse value of bbv. (define_code_attr bbinv [(eq "1") (ne "0")]) + +;; The sel mnemonic to use depending on the condition test. +(define_code_attr sel [(eq "seleqz") (ne "selnez")]) +(define_code_attr selinv [(eq "selnez") (ne "seleqz")]) ;; ......................... ;; @@ -1114,18 +1134,27 @@ [(match_operand:GPR 1 "reg_or_0_operand") (match_operand:GPR 2 "arith_operand")]) (match_operand 3 "const_0_operand"))] - "ISA_HAS_COND_TRAP" + "ISA_HAS_COND_TRAPI || ISA_HAS_COND_TRAP" { mips_expand_conditional_trap (operands[0]); DONE; }) +(define_insn "*conditional_trap_reg<mode>" + [(trap_if (match_operator:GPR 0 "trap_comparison_operator" + [(match_operand:GPR 1 "reg_or_0_operand" "dJ") + (match_operand:GPR 2 "reg_or_0_operand" "dJ")]) + (const_int 0))] + "ISA_HAS_COND_TRAP && !ISA_HAS_COND_TRAPI" + "t%C0\t%z1,%2" + [(set_attr "type" "trap")]) + (define_insn "*conditional_trap<mode>" [(trap_if (match_operator:GPR 0 "trap_comparison_operator" [(match_operand:GPR 1 "reg_or_0_operand" "dJ") (match_operand:GPR 2 "arith_operand" "dI")]) (const_int 0))] - "ISA_HAS_COND_TRAP" + "ISA_HAS_COND_TRAPI" "t%C0\t%z1,%2" [(set_attr "type" "trap")]) @@ -1493,13 +1522,13 @@ [(set (match_operand:GPR 0 "register_operand") (mult:GPR (match_operand:GPR 1 "register_operand") (match_operand:GPR 2 "register_operand")))] - "ISA_HAS_<D>MULT" + "ISA_HAS_<D>MULT || ISA_HAS_R6<D>MUL" { rtx lo; - if (TARGET_LOONGSON_2EF || TARGET_LOONGSON_3A) - emit_insn (gen_mul<mode>3_mul3_loongson (operands[0], operands[1], - operands[2])); + if (TARGET_LOONGSON_2EF || TARGET_LOONGSON_3A || ISA_HAS_R6<D>MUL) + emit_insn (gen_mul<mode>3_mul3_nohilo (operands[0], operands[1], + operands[2])); else if (ISA_HAS_<D>MUL3) emit_insn (gen_mul<mode>3_mul3 (operands[0], operands[1], operands[2])); else if (TARGET_MIPS16) @@ -1516,16 +1545,18 @@ DONE; }) -(define_insn "mul<mode>3_mul3_loongson" +(define_insn "mul<mode>3_mul3_nohilo" [(set (match_operand:GPR 0 "register_operand" "=d") (mult:GPR (match_operand:GPR 1 "register_operand" "d") (match_operand:GPR 2 "register_operand" "d")))] - "TARGET_LOONGSON_2EF || TARGET_LOONGSON_3A" + "TARGET_LOONGSON_2EF || TARGET_LOONGSON_3A || ISA_HAS_R6<D>MUL" { if (TARGET_LOONGSON_2EF) return "<d>multu.g\t%0,%1,%2"; - else + else if (TARGET_LOONGSON_3A) return "gs<d>multu\t%0,%1,%2"; + else + return "<d>mul\t%0,%1,%2"; } [(set_attr "type" "imul3nc") (set_attr "mode" "<MODE>")]) @@ -1961,6 +1992,24 @@ DONE; }) +(define_expand "<u>mulsidi3_32bit_r6" + [(set (match_operand:DI 0 "register_operand") + (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand")) + (any_extend:DI (match_operand:SI 2 "register_operand"))))] + "!TARGET_64BIT && ISA_HAS_R6MUL" +{ + rtx dest = gen_reg_rtx (DImode); + rtx low = mips_subword (dest, 0); + rtx high = mips_subword (dest, 1); + + emit_insn (gen_mulsi3_mul3_nohilo (low, operands[1], operands[2])); + emit_insn (gen_<su>mulsi3_highpart_r6 (high, operands[1], operands[2])); + + emit_move_insn (mips_subword (operands[0], 0), low); + emit_move_insn (mips_subword (operands[0], 1), high); + DONE; +}) + (define_expand "<u>mulsidi3_32bit_mips16" [(set (match_operand:DI 0 "register_operand") (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand")) @@ -1982,7 +2031,7 @@ [(set (match_operand:DI 0 "muldiv_target_operand" "=ka") (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d")) (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))] - "!TARGET_64BIT && (!TARGET_FIX_R4000 || ISA_HAS_DSP)" + "!TARGET_64BIT && (!TARGET_FIX_R4000 || ISA_HAS_DSP) && ISA_HAS_MULT" { if (ISA_HAS_DSP_MULT) return "mult<u>\t%q0,%1,%2"; @@ -1997,7 +2046,7 @@ (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d")) (any_extend:DI (match_operand:SI 2 "register_operand" "d")))) (clobber (match_scratch:DI 3 "=x"))] - "!TARGET_64BIT && TARGET_FIX_R4000 && !ISA_HAS_DSP" + "!TARGET_64BIT && TARGET_FIX_R4000 && !ISA_HAS_DSP && ISA_HAS_MULT" "mult<u>\t%1,%2\;mflo\t%L0\;mfhi\t%M0" [(set_attr "type" "imul") (set_attr "mode" "SI") @@ -2009,7 +2058,8 @@ (any_extend:DI (match_operand:SI 2 "register_operand" "d")))) (clobber (match_scratch:TI 3 "=x")) (clobber (match_scratch:DI 4 "=d"))] - "TARGET_64BIT && !TARGET_FIX_R4000 && !ISA_HAS_DMUL3 && !TARGET_MIPS16" + "TARGET_64BIT && !TARGET_FIX_R4000 && !ISA_HAS_DMUL3 + && !TARGET_MIPS16 && ISA_HAS_MULT" "#" "&& reload_completed" [(const_int 0)] @@ -2092,6 +2142,15 @@ [(set_attr "type" "imul3") (set_attr "mode" "DI")]) +(define_insn "mulsidi3_64bit_r6dmul" + [(set (match_operand:DI 0 "register_operand" "=d") + (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d")) + (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))] + "ISA_HAS_R6DMUL" + "dmul\t%0,%1,%2" + [(set_attr "type" "imul3nc") + (set_attr "mode" "DI")]) + ;; Widening multiply with negation. (define_insn "*muls<u>_di" [(set (match_operand:DI 0 "muldiv_target_operand" "=x") @@ -2149,12 +2208,27 @@ else if (TARGET_MIPS16) emit_insn (gen_<su>mulsi3_highpart_split (operands[0], operands[1], operands[2])); + else if (ISA_HAS_R6MUL) + emit_insn (gen_<su>mulsi3_highpart_r6 (operands[0], operands[1], + operands[2])); else emit_insn (gen_<su>mulsi3_highpart_internal (operands[0], operands[1], operands[2])); DONE; }) +(define_insn "<su>mulsi3_highpart_r6" + [(set (match_operand:SI 0 "register_operand" "=d") + (truncate:SI + (lshiftrt:DI + (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d")) + (any_extend:DI (match_operand:SI 2 "register_operand" "d"))) + (const_int 32))))] + "ISA_HAS_R6MUL" + "muh<u>\t%0,%1,%2" + [(set_attr "type" "imul3nc") + (set_attr "mode" "SI")]) + (define_insn_and_split "<su>mulsi3_highpart_internal" [(set (match_operand:SI 0 "register_operand" "=d") (truncate:SI @@ -2163,7 +2237,7 @@ (any_extend:DI (match_operand:SI 2 "register_operand" "d"))) (const_int 32)))) (clobber (match_scratch:SI 3 "=l"))] - "!ISA_HAS_MULHI && !TARGET_MIPS16" + "ISA_HAS_MULT && !ISA_HAS_MULHI && !TARGET_MIPS16" { return TARGET_FIX_R4000 ? "mult<u>\t%1,%2\n\tmfhi\t%0" : "#"; } "&& reload_completed && !TARGET_FIX_R4000" [(const_int 0)] @@ -2241,17 +2315,34 @@ (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand")) (any_extend:TI (match_operand:DI 2 "register_operand"))) (const_int 64))))] - "ISA_HAS_DMULT && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)" + "ISA_HAS_R6DMUL + || (ISA_HAS_DMULT + && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120))" { if (TARGET_MIPS16) emit_insn (gen_<su>muldi3_highpart_split (operands[0], operands[1], operands[2])); + else if (ISA_HAS_R6DMUL) + emit_insn (gen_<su>muldi3_highpart_r6 (operands[0], operands[1], + operands[2])); else emit_insn (gen_<su>muldi3_highpart_internal (operands[0], operands[1], operands[2])); DONE; }) +(define_insn "<su>muldi3_highpart_r6" + [(set (match_operand:DI 0 "register_operand" "=d") + (truncate:DI + (lshiftrt:TI + (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand" "d")) + (any_extend:TI (match_operand:DI 2 "register_operand" "d"))) + (const_int 64))))] + "ISA_HAS_R6DMUL" + "dmuh<u>\t%0,%1,%2" + [(set_attr "type" "imul3nc") + (set_attr "mode" "DI")]) + (define_insn_and_split "<su>muldi3_highpart_internal" [(set (match_operand:DI 0 "register_operand" "=d") (truncate:DI @@ -2390,6 +2481,16 @@ (set_attr "accum_in" "3") (set_attr "mode" "<UNITMODE>")]) +(define_insn "fma<mode>4" + [(set (match_operand:ANYF 0 "register_operand" "=f") + (fma:ANYF (match_operand:ANYF 1 "register_operand" "f") + (match_operand:ANYF 2 "register_operand" "f") + (match_operand:ANYF 3 "register_operand" "0")))] + "ISA_HAS_FP_MADDF_MSUBF" + "maddf.<fmt>\t%0,%1,%2" + [(set_attr "type" "fmadd") + (set_attr "mode" "<UNITMODE>")]) + (define_insn "*madd3<mode>" [(set (match_operand:ANYF 0 "register_operand" "=f") (plus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f") @@ -2773,6 +2874,40 @@ { return mips_output_division ("<GPR:d>div<u>\t%.,%1,%2", operands); } [(set_attr "type" "idiv") (set_attr "mode" "<GPR:MODE>")]) + +;; Integer division and modulus. + +(define_insn "<u>div<mode>3" + [(set (match_operand:GPR 0 "register_operand" "=&d") + (any_div:GPR (match_operand:GPR 1 "register_operand" "d") + (match_operand:GPR 2 "register_operand" "d")))] + "TARGET_LOONGSON_2EF || TARGET_LOONGSON_3A || ISA_HAS_R6<D>DIV" + { + if (TARGET_LOONGSON_2EF) + return mips_output_division ("<d>div<u>.g\t%0,%1,%2", operands); + else if (TARGET_LOONGSON_3A) + return mips_output_division ("gs<d>div<u>\t%0,%1,%2", operands); + else + return mips_output_division ("<d>div<u>\t%0,%1,%2", operands); + } + [(set_attr "type" "idiv3") + (set_attr "mode" "<MODE>")]) + +(define_insn "<u>mod<mode>3" + [(set (match_operand:GPR 0 "register_operand" "=&d") + (any_mod:GPR (match_operand:GPR 1 "register_operand" "d") + (match_operand:GPR 2 "register_operand" "d")))] + "TARGET_LOONGSON_2EF || TARGET_LOONGSON_3A || ISA_HAS_R6<D>DIV" + { + if (TARGET_LOONGSON_2EF) + return mips_output_division ("<d>mod<u>.g\t%0,%1,%2", operands); + else if (TARGET_LOONGSON_3A) + return mips_output_division ("gs<d>mod<u>\t%0,%1,%2", operands); + else + return mips_output_division ("<d>mod<u>\t%0,%1,%2", operands); + } + [(set_attr "type" "idiv3") + (set_attr "mode" "<MODE>")]) ;; ;; .................... @@ -3918,7 +4053,7 @@ (sign_extract:GPR (match_operand:BLK 1 "memory_operand") (match_operand 2 "const_int_operand") (match_operand 3 "const_int_operand")))] - "!TARGET_MIPS16" + "ISA_HAS_LWL_LWR" { if (mips_expand_ext_as_unaligned_load (operands[0], operands[1], INTVAL (operands[2]), @@ -3955,7 +4090,7 @@ (zero_extract:GPR (match_operand:BLK 1 "memory_operand") (match_operand 2 "const_int_operand") (match_operand 3 "const_int_operand")))] - "!TARGET_MIPS16" + "ISA_HAS_LWL_LWR" { if (mips_expand_ext_as_unaligned_load (operands[0], operands[1], INTVAL (operands[2]), @@ -4006,7 +4141,7 @@ (match_operand 1 "const_int_operand") (match_operand 2 "const_int_operand")) (match_operand:GPR 3 "reg_or_0_operand"))] - "!TARGET_MIPS16" + "ISA_HAS_LWL_LWR" { if (mips_expand_ins_as_unaligned_store (operands[0], operands[3], INTVAL (operands[1]), @@ -4762,6 +4897,13 @@ DONE; }) +(define_insn "movccf" + [(set (match_operand:CCF 0 "nonimmediate_operand" "=f,f,m") + (match_operand:CCF 1 "nonimmediate_operand" "f,m,f"))] + "ISA_HAS_CCF" + { return mips_output_move (operands[0], operands[1]); } + [(set_attr "move_type" "fmove,fpload,fpstore")]) + (define_insn "*movsf_hardfloat" [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m") (match_operand:SF 1 "move_operand" "f,G,m,f,G,*d,*f,*G*d,*m,*d"))] @@ -5280,7 +5422,7 @@ (define_insn "mips_cache" [(set (mem:BLK (scratch)) (unspec:BLK [(match_operand:SI 0 "const_int_operand") - (match_operand:QI 1 "address_operand" "p")] + (match_operand:QI 1 "address_operand" "ZD")] UNSPEC_MIPS_CACHE))] "ISA_HAS_CACHE" "cache\t%X0,%a1") @@ -5557,11 +5699,11 @@ ;; Conditional branches on floating-point equality tests. -(define_insn "*branch_fp" +(define_insn "*branch_fp_<mode>" [(set (pc) (if_then_else (match_operator 1 "equality_operator" - [(match_operand:CC 2 "register_operand" "z") + [(match_operand:FPCC 2 "register_operand" "<reg>") (const_int 0)]) (label_ref (match_operand 0 "" "")) (pc)))] @@ -5573,11 +5715,11 @@ } [(set_attr "type" "branch")]) -(define_insn "*branch_fp_inverted" +(define_insn "*branch_fp_inverted_<mode>" [(set (pc) (if_then_else (match_operator 1 "equality_operator" - [(match_operand:CC 2 "register_operand" "z") + [(match_operand:FPCC 2 "register_operand" "<reg>") (const_int 0)]) (pc) (label_ref (match_operand 0 "" ""))))] @@ -5921,21 +6063,21 @@ ;; ;; .................... -(define_insn "s<code>_<mode>" - [(set (match_operand:CC 0 "register_operand" "=z") - (fcond:CC (match_operand:SCALARF 1 "register_operand" "f") - (match_operand:SCALARF 2 "register_operand" "f")))] +(define_insn "s<code>_<SCALARF:mode>_using_<FPCC:mode>" + [(set (match_operand:FPCC 0 "register_operand" "=<reg>") + (fcond:FPCC (match_operand:SCALARF 1 "register_operand" "f") + (match_operand:SCALARF 2 "register_operand" "f")))] "" - "c.<fcond>.<fmt>\t%Z0%1,%2" + "<fpcmp>.<fcond>.<fmt>\t%Z0%1,%2" [(set_attr "type" "fcmp") (set_attr "mode" "FPSW")]) -(define_insn "s<code>_<mode>" - [(set (match_operand:CC 0 "register_operand" "=z") - (swapped_fcond:CC (match_operand:SCALARF 1 "register_operand" "f") - (match_operand:SCALARF 2 "register_operand" "f")))] +(define_insn "s<code>_<SCALARF:mode>_using_<FPCC:mode>" + [(set (match_operand:FPCC 0 "register_operand" "=<reg>") + (swapped_fcond:FPCC (match_operand:SCALARF 1 "register_operand" "f") + (match_operand:SCALARF 2 "register_operand" "f")))] "" - "c.<swapped_fcond>.<fmt>\t%Z0%2,%1" + "<fpcmp>.<swapped_fcond>.<fmt>\t%Z0%2,%1" [(set_attr "type" "fcmp") (set_attr "mode" "FPSW")]) @@ -6953,6 +7095,41 @@ [(set_attr "type" "condmove") (set_attr "mode" "<SCALARF:MODE>")]) +(define_insn "*sel<code><GPR:mode>_using_<GPR2:mode>" + [(set (match_operand:GPR 0 "register_operand" "=d,d") + (if_then_else:GPR + (equality_op:GPR2 (match_operand:GPR2 1 "register_operand" "d,d") + (const_int 0)) + (match_operand:GPR 2 "reg_or_0_operand" "d,J") + (match_operand:GPR 3 "reg_or_0_operand" "J,d")))] + "ISA_HAS_SEL + && (register_operand (operands[2], <GPR:MODE>mode) + != register_operand (operands[3], <GPR:MODE>mode))" + "@ + <sel>\t%0,%2,%1 + <selinv>\t%0,%3,%1" + [(set_attr "type" "condmove") + (set_attr "mode" "<GPR:MODE>")]) + +;; sel.fmt copies the 3rd argument when the 1st is non-zero and the 2nd +;; argument if the 1st is zero. This means operand 2 and 3 are +;; inverted in the instruction. + +(define_insn "*sel<mode>" + [(set (match_operand:SCALARF 0 "register_operand" "=f,f,f") + (if_then_else:SCALARF + (ne:CCF (match_operand:CCF 1 "register_operand" "0,f,f") + (const_int 0)) + (match_operand:SCALARF 2 "reg_or_0_operand" "f,G,f") + (match_operand:SCALARF 3 "reg_or_0_operand" "f,f,G")))] + "ISA_HAS_SEL && ISA_HAS_CCF" + "@ + sel.<fmt>\t%0,%3,%2 + seleqz.<fmt>\t%0,%3,%1 + selnez.<fmt>\t%0,%2,%1" + [(set_attr "type" "condmove") + (set_attr "mode" "<SCALARF:MODE>")]) + ;; These are the main define_expand's used to make conditional moves. (define_expand "mov<mode>cc" @@ -6961,8 +7138,11 @@ (if_then_else:GPR (match_dup 5) (match_operand:GPR 2 "reg_or_0_operand") (match_operand:GPR 3 "reg_or_0_operand")))] - "ISA_HAS_CONDMOVE" + "ISA_HAS_CONDMOVE || ISA_HAS_SEL" { + if (ISA_HAS_SEL && !INTEGRAL_MODE_P (GET_MODE (XEXP (operands[1], 0)))) + FAIL; + mips_expand_conditional_move (operands); DONE; }) @@ -6971,10 +7151,25 @@ [(set (match_dup 4) (match_operand 1 "comparison_operator")) (set (match_operand:SCALARF 0 "register_operand") (if_then_else:SCALARF (match_dup 5) - (match_operand:SCALARF 2 "register_operand") - (match_operand:SCALARF 3 "register_operand")))] - "ISA_HAS_FP_CONDMOVE" + (match_operand:SCALARF 2 "reg_or_0_operand") + (match_operand:SCALARF 3 "reg_or_0_operand")))] + "ISA_HAS_FP_CONDMOVE + || (ISA_HAS_SEL && ISA_HAS_CCF)" { + if (ISA_HAS_SEL && !FLOAT_MODE_P (GET_MODE (XEXP (operands[1], 0)))) + FAIL; + + /* Workaround an LRA bug which means that tied operands in the sel.fmt + pattern lead to the double precision destination of sel.d getting + reloaded with the full register file usable and the restrictions on + whether the CCFmode input can be used in odd-numbered single-precision + registers are ignored. For consistency reasons the CCF mode values + must be guaranteed to only exist in the even-registers because of + the unusual duality between single and double precision values. */ + if (ISA_HAS_SEL && <MODE>mode == DFmode + && (!TARGET_ODD_SPREG || TARGET_FLOATXX)) + FAIL; + mips_expand_conditional_move (operands); DONE; }) @@ -7089,7 +7284,12 @@ [(set (reg:P TLS_GET_TP_REGNUM) (unspec:P [(const_int 0)] UNSPEC_TLS_GET_TP))] "HAVE_AS_TLS && !TARGET_MIPS16" - ".set\tpush\;.set\tmips32r2\t\;rdhwr\t$3,$29\;.set\tpop" + { + if (mips_isa_rev >= 2) + return "rdhwr\t$3,$29"; + + return ".set\tpush\;.set\tmips32r2\t\;rdhwr\t$3,$29\;.set\tpop"; + } [(set_attr "type" "unknown") ; Since rdhwr always generates a trap for now, putting it in a delay ; slot would make the kernel's emulation of it much slower. diff --git a/gcc/config/mips/mti-linux.h b/gcc/config/mips/mti-linux.h index 98d6582..5761ab7 100644 --- a/gcc/config/mips/mti-linux.h +++ b/gcc/config/mips/mti-linux.h @@ -19,8 +19,15 @@ along with GCC; see the file COPYING3. If not see /* This target is a multilib target, specify the sysroot paths. */ #undef SYSROOT_SUFFIX_SPEC +#if MIPS_ISA_DEFAULT == 33 /* mips32r2 is the default */ #define SYSROOT_SUFFIX_SPEC \ - "%{mips32:/mips32}%{mips64:/mips64}%{mips64r2:/mips64r2}%{mips16:/mips16}%{mmicromips:/micromips}%{mabi=64:/64}%{mel|EL:/el}%{msoft-float:/sof}%{mnan=2008:/nan2008}" + "%{mips32:/mips32}%{mips64:/mips64}%{mips64r2:/mips64r2}%{mips32r6:/mips32r6}%{mips64r6:/mips64r6}%{mips16:/mips16}%{mmicromips:/micromips}%{mabi=64:/64}%{mel|EL:/el}%{msoft-float:/sof}%{!mips32r6:%{!mips64r6:%{mnan=2008:/nan2008}}}" +#elif MIPS_ISA_DEFAULT == 37 /* mips32r6 is the default */ +#define SYSROOT_SUFFIX_SPEC \ + "%{mips32:/mips32}%{mips64:/mips64}%{mips32r2:/mips32r2}%{mips64r2:/mips64r2}%{mips64r6:/mips64r6}%{mips16:/mips16}%{mmicromips:/micromips}%{mabi=64:/64}%{mel|EL:/el}%{msoft-float:/sof}%{!mips32r6:%{!mips64r6:%{mnan=2008:/nan2008}}}" +#else /* Unexpected default ISA. */ +#error No SYSROOT_SUFFIX_SPEC exists for this default ISA +#endif #undef DRIVER_SELF_SPECS #define DRIVER_SELF_SPECS \ diff --git a/gcc/config/mips/netbsd.h b/gcc/config/mips/netbsd.h index efa2886..ed41e0f 100644 --- a/gcc/config/mips/netbsd.h +++ b/gcc/config/mips/netbsd.h @@ -84,21 +84,13 @@ along with GCC; see the file COPYING3. If not see builtin_define ("__mips=3"); \ else if (ISA_MIPS4) \ builtin_define ("__mips=4"); \ - else if (ISA_MIPS32) \ - { \ - builtin_define ("__mips=32"); \ - builtin_define ("__mips_isa_rev=1"); \ - } \ - else if (ISA_MIPS32R2) \ - { \ - builtin_define ("__mips=32"); \ - builtin_define ("__mips_isa_rev=2"); \ - } \ - else if (ISA_MIPS64) \ - { \ - builtin_define ("__mips=64"); \ - builtin_define ("__mips_isa_rev=1"); \ - } \ + else if (mips_isa >= 32 && mips_isa < 64) \ + builtin_define ("__mips=32"); \ + else if (mips_isa >= 64) \ + builtin_define ("__mips=64"); \ + if (mips_isa_rev > 0) \ + builtin_define_with_int_value ("__mips_isa_rev", \ + mips_isa_rev); \ \ if (TARGET_HARD_FLOAT) \ builtin_define ("__mips_hard_float"); \ @@ -141,7 +133,8 @@ along with GCC; see the file COPYING3. If not see "%{EL:-m elf32lmip} \ %{EB:-m elf32bmip} \ %(endian_spec) \ - %{G*} %{mips1} %{mips2} %{mips3} %{mips4} %{mips32} %{mips32r2} %{mips64} \ + %{G*} %{mips1} %{mips2} %{mips3} %{mips4} %{mips32} %{mips32r2} \ + %{mips32r6} %{mips64} %{mips64r6} \ %(netbsd_link_spec)" #define NETBSD_ENTRY_POINT "__start" diff --git a/gcc/config/mips/t-img-elf b/gcc/config/mips/t-img-elf new file mode 100644 index 0000000..cc5dabb --- /dev/null +++ b/gcc/config/mips/t-img-elf @@ -0,0 +1,38 @@ +# Copyright (C) 2014 Free Software Foundation, Inc. +# +# This file is part of GCC. +# +# GCC 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 3, or (at your option) +# any later version. +# +# GCC 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 GCC; see the file COPYING3. If not see +# <http://www.gnu.org/licenses/>. + +# The default build is mips32r6, hard-float big-endian. +# A multilib for mips32r6+LE +# A multilib for mips64r6 +# A multilib for mips64r6+LE +# A multilib for mips32r6+LE+singlefloat+shortdouble + +MULTILIB_OPTIONS = mips64r6 mabi=64 EL msoft-float/msingle-float fshort-double +MULTILIB_DIRNAMES = mips64r6 64 el sof sgl short +MULTILIB_MATCHES = EL=mel EB=meb + +# Don't build 64r6 with single-float +MULTILIB_EXCEPTIONS += mips64r6/*msingle-float* +MULTILIB_EXCEPTIONS += mips64r6/*fshort-double* + +MULTILIB_EXCEPTIONS += mabi=64* +MULTILIB_EXCEPTIONS += msingle-float* +MULTILIB_EXCEPTIONS += *msingle-float +MULTILIB_EXCEPTIONS += fshort-double +MULTILIB_EXCEPTIONS += EL/fshort-double +MULTILIB_EXCEPTIONS += *msoft-float/fshort-double diff --git a/gcc/config/mips/t-img-linux b/gcc/config/mips/t-img-linux new file mode 100644 index 0000000..5dbfbe4 --- /dev/null +++ b/gcc/config/mips/t-img-linux @@ -0,0 +1,30 @@ +# Copyright (C) 2014 Free Software Foundation, Inc. +# +# This file is part of GCC. +# +# GCC 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 3, or (at your option) +# any later version. +# +# GCC 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 GCC; see the file COPYING3. If not see +# <http://www.gnu.org/licenses/>. + +# The default build is mips32r6, hard-float big-endian. Add mips64r6, +# 64-bit ABI and little-endian variations. + +MULTILIB_OPTIONS = mips64r6 mabi=64 EL +MULTILIB_DIRNAMES = mips64r6 64 el +MULTILIB_MATCHES = EL=mel EB=meb + +# The 64 bit ABI is not supported on the mips32r6 architecture. +# Because mips32r6 is the default we can't use that flag to trigger +# the exception so we check for mabi=64 with no specific mips +# architecture flag instead. +MULTILIB_EXCEPTIONS += mabi=64* diff --git a/gcc/config/mips/t-isa3264 b/gcc/config/mips/t-isa3264 index 8fffdf8..8455745 100644 --- a/gcc/config/mips/t-isa3264 +++ b/gcc/config/mips/t-isa3264 @@ -22,10 +22,10 @@ ifneq ($(filter MIPS_ABI_DEFAULT=ABI_EABI,$(tm_defines)),) MULTILIB_OPTIONS = msoft-float EL/EB mips32/mips32r2/mips64/mips64r2 MULTILIB_DIRNAMES = soft-float el eb mips32 mips32r2 mips64 mips64r2 else -MULTILIB_OPTIONS = msoft-float/mfp64 EL/EB mips32/mips32r2/mips64/mips64r2 -MULTILIB_DIRNAMES = soft-float fp64 el eb mips32 mips32r2 mips64 mips64r2 +MULTILIB_OPTIONS = msoft-float/mfp64 EL/EB mips32/mips32r2/mips32r6/mips64/mips64r2/mips64r6 +MULTILIB_DIRNAMES = soft-float fp64 el eb mips32 mips32r2 mips32r6 mips64 mips64r2 mips64r6 ifneq ($(filter MIPS_ISA_DEFAULT=33,$(tm_defines)),) -MULTILIB_EXCLUSIONS = mips32/mfp64 mips64/mfp64 mips64r2/mfp64 +MULTILIB_EXCLUSIONS = mips32/mfp64 mips64/mfp64 mips64r2/mfp64 mips32r6/mfp64 mips64r6/mfp64 else MULTILIB_EXCLUSIONS = !mips32r2/mfp64 endif diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 823f086..7fcad87 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2014-12-19 Kai Tietz <ktietz@redhat.com> + + PR c++/61198 + * pt.c (most_general_template): Don't break for template-alias. + 2014-12-18 Jason Merrill <jason@redhat.com> PR c++/64105 diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 2a63a2e..15d304a 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -19207,6 +19207,7 @@ most_general_template (tree decl) break; if (CLASS_TYPE_P (TREE_TYPE (decl)) + && !TYPE_DECL_ALIAS_P (TYPE_NAME (TREE_TYPE (decl))) && CLASSTYPE_TEMPLATE_SPECIALIZATION (TREE_TYPE (decl))) break; diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 45d4e25..e37c777 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -785,7 +785,7 @@ Objective-C and Objective-C++ Dialects}. @emph{MIPS Options} @gccoptlist{-EL -EB -march=@var{arch} -mtune=@var{arch} @gol -mips1 -mips2 -mips3 -mips4 -mips32 -mips32r2 -mips32r3 -mips32r5 @gol --mips64 -mips64r2 -mips64r3 -mips64r5 @gol +-mips32r6 -mips64 -mips64r2 -mips64r3 -mips64r5 -mips64r6 @gol -mips16 -mno-mips16 -mflip-mips16 @gol -minterlink-compressed -mno-interlink-compressed @gol -minterlink-mips16 -mno-interlink-mips16 @gol @@ -17671,8 +17671,9 @@ Generate code that runs on @var{arch}, which can be the name of a generic MIPS ISA, or the name of a particular processor. The ISA names are: @samp{mips1}, @samp{mips2}, @samp{mips3}, @samp{mips4}, -@samp{mips32}, @samp{mips32r2}, @samp{mips32r3}, @samp{mips32r5}, -@samp{mips64}, @samp{mips64r2}, @samp{mips64r3} and @samp{mips64r5}. +@samp{mips32}, @samp{mips32r2}, @samp{mips32r3}, @samp{mips32r5}, +@samp{mips32r6}, @samp{mips64}, @samp{mips64r2}, @samp{mips64r3}, +@samp{mips64r5} and @samp{mips64r6}. The processor names are: @samp{4kc}, @samp{4km}, @samp{4kp}, @samp{4ksc}, @samp{4kec}, @samp{4kem}, @samp{4kep}, @samp{4ksd}, @@ -17779,6 +17780,10 @@ Equivalent to @option{-march=mips32r3}. @opindex mips32r5 Equivalent to @option{-march=mips32r5}. +@item -mips32r6 +@opindex mips32r6 +Equivalent to @option{-march=mips32r6}. + @item -mips64 @opindex mips64 Equivalent to @option{-march=mips64}. @@ -17795,6 +17800,10 @@ Equivalent to @option{-march=mips64r3}. @opindex mips64r5 Equivalent to @option{-march=mips64r5}. +@item -mips64r6 +@opindex mips64r6 +Equivalent to @option{-march=mips64r6}. + @item -mips16 @itemx -mno-mips16 @opindex mips16 diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi index f2dcac9..7f0426c 100644 --- a/gcc/doc/md.texi +++ b/gcc/doc/md.texi @@ -2994,10 +2994,8 @@ operands can be used for microMIPS instructions such as @code{ll} and equivalent to @code{R}. @item ZD -When compiling microMIPS code, this constraint matches an address operand -that is formed from a base register and a 12-bit offset. These operands -can be used for microMIPS instructions such as @code{prefetch}. When -not compiling for microMIPS code, @code{ZD} is equivalent to @code{p}. +An address suitable for a @code{prefetch} instruction, or for any other +instruction with the same addressing mode as @code{prefetch}. @end table @item Motorola 680x0---@file{config/m68k/constraints.md} diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 067b133..de2d2a9 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,10 @@ +2014-12-19 Janus Weil <janus@gcc.gnu.org> + + PR fortran/64209 + * trans-expr.c (gfc_trans_class_array_init_assign): Check if _def_init + component is non-NULL. + (gfc_trans_class_init_assign): Ditto. + 2014-12-17 Janus Weil <janus@gcc.gnu.org> PR fortran/64173 diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c index 7772dca..3793cfb 100644 --- a/gcc/fortran/trans-expr.c +++ b/gcc/fortran/trans-expr.c @@ -932,6 +932,21 @@ gfc_trans_class_array_init_assign (gfc_expr *rhs, gfc_expr *lhs, gfc_expr *obj) of arrays in gfc_trans_call. */ res = gfc_trans_call (ppc_code, false, NULL, NULL, false); gfc_free_statements (ppc_code); + + if (UNLIMITED_POLY(obj)) + { + /* Check if rhs is non-NULL. */ + gfc_se src; + gfc_init_se (&src, NULL); + gfc_conv_expr (&src, rhs); + src.expr = gfc_build_addr_expr (NULL_TREE, src.expr); + tree cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, + src.expr, fold_convert (TREE_TYPE (src.expr), + null_pointer_node)); + res = build3_loc (input_location, COND_EXPR, TREE_TYPE (res), cond, res, + build_empty_stmt (input_location)); + } + return res; } @@ -980,6 +995,17 @@ gfc_trans_class_init_assign (gfc_code *code) src.expr = gfc_build_addr_expr (NULL_TREE, src.expr); tmp = gfc_build_memcpy_call (dst.expr, src.expr, memsz.expr); + + if (UNLIMITED_POLY(code->expr1)) + { + /* Check if _def_init is non-NULL. */ + tree cond = fold_build2_loc (input_location, NE_EXPR, + boolean_type_node, src.expr, + fold_convert (TREE_TYPE (src.expr), + null_pointer_node)); + tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp), cond, + tmp, build_empty_stmt (input_location)); + } } if (code->expr1->symtree->n.sym->attr.optional diff --git a/gcc/go/ChangeLog b/gcc/go/ChangeLog index dadced9..7df6cbf 100644 --- a/gcc/go/ChangeLog +++ b/gcc/go/ChangeLog @@ -1,3 +1,8 @@ +2014-12-19 Chris Manghane <cmang@google.com> + + * go-gcc.cc (array_constructor_expression): Don't construct arrays + of zero-sized values. + 2014-10-29 Richard Sandiford <richard.sandiford@arm.com> * go-lang.c: Remove redundant enum from machine_mode. diff --git a/gcc/go/go-gcc.cc b/gcc/go/go-gcc.cc index 9aad6b0..c100630 100644 --- a/gcc/go/go-gcc.cc +++ b/gcc/go/go-gcc.cc @@ -1688,16 +1688,20 @@ Gcc_backend::constructor_expression(Btype* btype, Bexpression* Gcc_backend::array_constructor_expression( Btype* array_btype, const std::vector<unsigned long>& indexes, - const std::vector<Bexpression*>& vals, Location) + const std::vector<Bexpression*>& vals, Location location) { tree type_tree = array_btype->get_tree(); if (type_tree == error_mark_node) return this->error_expression(); gcc_assert(indexes.size() == vals.size()); + + tree element_type = TREE_TYPE(type_tree); + HOST_WIDE_INT element_size = int_size_in_bytes(element_type); vec<constructor_elt, va_gc> *init; - vec_alloc(init, vals.size()); + vec_alloc(init, element_size == 0 ? 0 : vals.size()); + tree sink = NULL_TREE; bool is_constant = true; for (size_t i = 0; i < vals.size(); ++i) { @@ -1708,6 +1712,16 @@ Gcc_backend::array_constructor_expression( || val == error_mark_node) return this->error_expression(); + if (element_size == 0) + { + // GIMPLE cannot represent arrays of zero-sized types so trying + // to construct an array of zero-sized values might lead to errors. + // Instead, we evaluate each expression that would have been added as + // an array value for its side-effects and construct an empty array. + append_to_statement_list(val, &sink); + continue; + } + if (!TREE_CONSTANT(val)) is_constant = false; @@ -1720,6 +1734,9 @@ Gcc_backend::array_constructor_expression( tree ret = build_constructor(type_tree, init); if (is_constant) TREE_CONSTANT(ret) = 1; + if (sink != NULL_TREE) + ret = fold_build2_loc(location.gcc_location(), COMPOUND_EXPR, + type_tree, sink, ret); return this->make_expression(ret); } diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index 5b95b21..ccb472b 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -8786,6 +8786,10 @@ Call_expression::do_flatten(Gogo* gogo, Named_object*, if (this->classification() == EXPRESSION_ERROR) return this; + if (this->is_flattened_) + return this; + this->is_flattened_ = true; + // Add temporary variables for all arguments that require type // conversion. Function_type* fntype = this->get_function_type(); @@ -10590,21 +10594,31 @@ Map_index_expression::do_traverse(Traverse* traverse) // recomputation. Expression* -Map_index_expression::do_flatten(Gogo*, Named_object*, +Map_index_expression::do_flatten(Gogo* gogo, Named_object*, Statement_inserter* inserter) { + Location loc = this->location(); Map_type* mt = this->get_map_type(); - if (this->index_->type() != mt->key_type()) - this->index_ = Expression::make_cast(mt->key_type(), this->index_, - this->location()); + if (!Type::are_identical(mt->key_type(), this->index_->type(), false, NULL)) + { + if (this->index_->type()->interface_type() != NULL + && !this->index_->is_variable()) + { + Temporary_statement* temp = + Statement::make_temporary(NULL, this->index_, loc); + inserter->insert(temp); + this->index_ = Expression::make_temporary_reference(temp, loc); + } + this->index_ = Expression::convert_for_assignment(gogo, mt->key_type(), + this->index_, loc); + } if (!this->index_->is_variable()) { Temporary_statement* temp = Statement::make_temporary(NULL, this->index_, - this->location()); + loc); inserter->insert(temp); - this->index_ = Expression::make_temporary_reference(temp, - this->location()); + this->index_ = Expression::make_temporary_reference(temp, loc); } if (this->value_pointer_ == NULL) @@ -10612,11 +10626,9 @@ Map_index_expression::do_flatten(Gogo*, Named_object*, if (!this->value_pointer_->is_variable()) { Temporary_statement* temp = - Statement::make_temporary(NULL, this->value_pointer_, - this->location()); + Statement::make_temporary(NULL, this->value_pointer_, loc); inserter->insert(temp); - this->value_pointer_ = - Expression::make_temporary_reference(temp, this->location()); + this->value_pointer_ = Expression::make_temporary_reference(temp, loc); } return this; @@ -12540,12 +12552,26 @@ Map_construction_expression::do_flatten(Gogo* gogo, Named_object*, ++pv, ++i) { Expression_list* key_value_pair = new Expression_list(); - Expression* key = - Expression::convert_for_assignment(gogo, key_type, *pv, loc); + Expression* key = *pv; + if (key->type()->interface_type() != NULL && !key->is_variable()) + { + Temporary_statement* temp = + Statement::make_temporary(NULL, key, loc); + inserter->insert(temp); + key = Expression::make_temporary_reference(temp, loc); + } + key = Expression::convert_for_assignment(gogo, key_type, key, loc); ++pv; - Expression* val = - Expression::convert_for_assignment(gogo, val_type, *pv, loc); + Expression* val = *pv; + if (val->type()->interface_type() != NULL && !val->is_variable()) + { + Temporary_statement* temp = + Statement::make_temporary(NULL, val, loc); + inserter->insert(temp); + val = Expression::make_temporary_reference(temp, loc); + } + val = Expression::convert_for_assignment(gogo, val_type, val, loc); key_value_pair->push_back(key); key_value_pair->push_back(val); diff --git a/gcc/go/gofrontend/expressions.h b/gcc/go/gofrontend/expressions.h index cbac504..a2346c8 100644 --- a/gcc/go/gofrontend/expressions.h +++ b/gcc/go/gofrontend/expressions.h @@ -1632,7 +1632,8 @@ class Call_expression : public Expression fn_(fn), args_(args), type_(NULL), results_(NULL), call_(NULL), call_temp_(NULL), expected_result_count_(0), is_varargs_(is_varargs), varargs_are_lowered_(false), types_are_determined_(false), - is_deferred_(false), issued_error_(false), is_multi_value_arg_(false) + is_deferred_(false), issued_error_(false), is_multi_value_arg_(false), + is_flattened_(false) { } // The function to call. @@ -1817,6 +1818,8 @@ class Call_expression : public Expression bool issued_error_; // True if this call is used as an argument that returns multiple results. bool is_multi_value_arg_; + // True if this expression has already been flattened. + bool is_flattened_; }; // An expression which represents a pointer to a function. diff --git a/gcc/hash-table.c b/gcc/hash-table.c index 3dfde6d..4c9ef0a 100644 --- a/gcc/hash-table.c +++ b/gcc/hash-table.c @@ -41,39 +41,6 @@ along with GCC; see the file COPYING3. If not see For the record, here's the function that computed the table; it's a vastly simplified version of the function of the same name from gcc. */ -#if 0 -unsigned int -ceil_log2 (unsigned int x) -{ - int i; - for (i = 31; i >= 0 ; --i) - if (x > (1u << i)) - return i+1; - abort (); -} - -unsigned int -choose_multiplier (unsigned int d, unsigned int *mlp, unsigned char *shiftp) -{ - unsigned long long mhigh; - double nx; - int lgup, post_shift; - int pow, pow2; - int n = 32, precision = 32; - - lgup = ceil_log2 (d); - pow = n + lgup; - pow2 = n + lgup - precision; - - nx = ldexp (1.0, pow) + ldexp (1.0, pow2); - mhigh = nx / d; - - *shiftp = lgup - 1; - *mlp = mhigh; - return mhigh >> 32; -} -#endif - struct prime_ent const prime_tab[] = { { 7, 0x24924925, 0x9999999b, 2 }, { 13, 0x3b13b13c, 0x745d1747, 3 }, @@ -127,67 +94,8 @@ hash_table_higher_prime_index (unsigned long n) } /* If we've run out of primes, abort. */ - if (n > prime_tab[low].prime) - { - fprintf (stderr, "Cannot find prime bigger than %lu\n", n); - abort (); - } + gcc_assert (n <= prime_tab[low].prime); return low; } -/* Return X % Y using multiplicative inverse values INV and SHIFT. - - The multiplicative inverses computed above are for 32-bit types, - and requires that we be able to compute a highpart multiply. - - FIX: I am not at all convinced that - 3 loads, 2 multiplications, 3 shifts, and 3 additions - will be faster than - 1 load and 1 modulus - on modern systems running a compiler. */ - -#ifdef UNSIGNED_64BIT_TYPE -static inline hashval_t -mul_mod (hashval_t x, hashval_t y, hashval_t inv, int shift) -{ - __extension__ typedef UNSIGNED_64BIT_TYPE ull; - hashval_t t1, t2, t3, t4, q, r; - - t1 = ((ull)x * inv) >> 32; - t2 = x - t1; - t3 = t2 >> 1; - t4 = t1 + t3; - q = t4 >> shift; - r = x - (q * y); - - return r; -} -#endif - -/* Compute the primary table index for HASH given current prime index. */ - -hashval_t -hash_table_mod1 (hashval_t hash, unsigned int index) -{ - const struct prime_ent *p = &prime_tab[index]; -#ifdef UNSIGNED_64BIT_TYPE - if (sizeof (hashval_t) * CHAR_BIT <= 32) - return mul_mod (hash, p->prime, p->inv, p->shift); -#endif - return hash % p->prime; -} - - -/* Compute the secondary table index for HASH given current prime index. */ - -hashval_t -hash_table_mod2 (hashval_t hash, unsigned int index) -{ - const struct prime_ent *p = &prime_tab[index]; -#ifdef UNSIGNED_64BIT_TYPE - if (sizeof (hashval_t) * CHAR_BIT <= 32) - return 1 + mul_mod (hash, p->prime - 2, p->inv_m2, p->shift); -#endif - return 1 + hash % (p->prime - 2); -} diff --git a/gcc/hash-table.h b/gcc/hash-table.h index 5485d06..bfbe36d 100644 --- a/gcc/hash-table.h +++ b/gcc/hash-table.h @@ -282,7 +282,8 @@ struct pointer_hash : typed_noop_remove <Type> static inline hashval_t hash (const value_type &); - static inline bool equal (const value_type &existing, const compare_type &candidate); + static inline bool equal (const value_type &existing, + const compare_type &candidate); }; template <typename Type> @@ -388,9 +389,54 @@ extern struct prime_ent const prime_tab[]; /* Functions for computing hash table indexes. */ -extern unsigned int hash_table_higher_prime_index (unsigned long n); -extern hashval_t hash_table_mod1 (hashval_t hash, unsigned int index); -extern hashval_t hash_table_mod2 (hashval_t hash, unsigned int index); +extern unsigned int hash_table_higher_prime_index (unsigned long n) + ATTRIBUTE_PURE; + +/* Return X % Y using multiplicative inverse values INV and SHIFT. + + The multiplicative inverses computed above are for 32-bit types, + and requires that we be able to compute a highpart multiply. + + FIX: I am not at all convinced that + 3 loads, 2 multiplications, 3 shifts, and 3 additions + will be faster than + 1 load and 1 modulus + on modern systems running a compiler. */ + +inline hashval_t +mul_mod (hashval_t x, hashval_t y, hashval_t inv, int shift) +{ + hashval_t t1, t2, t3, t4, q, r; + + t1 = ((uint64_t)x * inv) >> 32; + t2 = x - t1; + t3 = t2 >> 1; + t4 = t1 + t3; + q = t4 >> shift; + r = x - (q * y); + + return r; +} + +/* Compute the primary table index for HASH given current prime index. */ + +inline hashval_t +hash_table_mod1 (hashval_t hash, unsigned int index) +{ + const struct prime_ent *p = &prime_tab[index]; + gcc_checking_assert (sizeof (hashval_t) * CHAR_BIT <= 32); + return mul_mod (hash, p->prime, p->inv, p->shift); +} + +/* Compute the secondary table index for HASH given current prime index. */ + +inline hashval_t +hash_table_mod2 (hashval_t hash, unsigned int index) +{ + const struct prime_ent *p = &prime_tab[index]; + gcc_checking_assert (sizeof (hashval_t) * CHAR_BIT <= 32); + return 1 + mul_mod (hash, p->prime - 2, p->inv_m2, p->shift); +} /* The below is some template meta programming to decide if we should use the hash table partial specialization that directly stores value_type instead of @@ -748,8 +794,7 @@ hash_table<Descriptor, Allocator, false> if (*slot == HTAB_EMPTY_ENTRY) return slot; - else if (*slot == HTAB_DELETED_ENTRY) - abort (); + gcc_checking_assert (*slot != HTAB_DELETED_ENTRY); hash2 = hash_table_mod2 (hash, m_size_prime_index); for (;;) @@ -761,8 +806,7 @@ hash_table<Descriptor, Allocator, false> slot = m_entries + index; if (*slot == HTAB_EMPTY_ENTRY) return slot; - else if (*slot == HTAB_DELETED_ENTRY) - abort (); + gcc_checking_assert (*slot != HTAB_DELETED_ENTRY); } } @@ -773,7 +817,7 @@ hash_table<Descriptor, Allocator, false> table entries is changed. If memory allocation fails, this function will abort. */ - template<typename Descriptor, template<typename Type> class Allocator> +template<typename Descriptor, template<typename Type> class Allocator> void hash_table<Descriptor, Allocator, false>::expand () { @@ -862,9 +906,9 @@ template<typename Descriptor, template<typename Type> class Allocator> void hash_table<Descriptor, Allocator, false>::clear_slot (value_type **slot) { - if (slot < m_entries || slot >= m_entries + size () - || *slot == HTAB_EMPTY_ENTRY || *slot == HTAB_DELETED_ENTRY) - abort (); + gcc_checking_assert (!(slot < m_entries || slot >= m_entries + size () + || *slot == HTAB_EMPTY_ENTRY + || *slot == HTAB_DELETED_ENTRY)); Descriptor::remove (*slot); @@ -1317,8 +1361,9 @@ hash_table<Descriptor, Allocator, true> if (is_empty (*slot)) return slot; - else if (is_deleted (*slot)) - abort (); +#ifdef ENABLE_CHECKING + gcc_checking_assert (!is_deleted (*slot)); +#endif hash2 = hash_table_mod2 (hash, m_size_prime_index); for (;;) @@ -1330,8 +1375,9 @@ hash_table<Descriptor, Allocator, true> slot = m_entries + index; if (is_empty (*slot)) return slot; - else if (is_deleted (*slot)) - abort (); +#ifdef ENABLE_CHECKING + gcc_checking_assert (!is_deleted (*slot)); +#endif } } @@ -1437,9 +1483,8 @@ template<typename Descriptor, template<typename Type> class Allocator> void hash_table<Descriptor, Allocator, true>::clear_slot (value_type *slot) { - if (slot < m_entries || slot >= m_entries + size () - || is_empty (*slot) || is_deleted (*slot)) - abort (); + gcc_checking_assert (!(slot < m_entries || slot >= m_entries + size () + || is_empty (*slot) || is_deleted (*slot))); Descriptor::remove (*slot); diff --git a/gcc/jit/ChangeLog b/gcc/jit/ChangeLog index 71755ff..09e5c8a 100644 --- a/gcc/jit/ChangeLog +++ b/gcc/jit/ChangeLog @@ -1,3 +1,20 @@ +2014-12-19 David Malcolm <dmalcolm@redhat.com> + + * jit-playback.c (gcc::jit::playback::context::build_cast): In + case BOOLEAN_TYPE, don't assume that the source expression is + of type "int". + +2014-12-19 David Malcolm <dmalcolm@redhat.com> + + * jit-recording.c (gcc::jit::recording::context::context): When + copying string options from a parent context, take a copy of the + underlying buffers, rather than simply copying the pointer. + +2014-12-19 David Malcolm <dmalcolm@redhat.com> + + * jit-recording.c (gcc::jit::recording::context::set_str_option): + Handle NULL. + 2014-12-11 David Malcolm <dmalcolm@redhat.com> * docs/cp/topics/contexts.rst (gccjit::context::set_str_option): diff --git a/gcc/jit/jit-playback.c b/gcc/jit/jit-playback.c index 57ff50e..3667d1a 100644 --- a/gcc/jit/jit-playback.c +++ b/gcc/jit/jit-playback.c @@ -875,7 +875,8 @@ playback::context::build_cast (playback::location *loc, c_common_truthvalue_conversion. */ /* For now, convert to: (t_expr != 0) */ t_ret = build2 (NE_EXPR, t_dst_type, - t_expr, integer_zero_node); + t_expr, + build_int_cst (TREE_TYPE (t_expr), 0)); goto maybe_fold; case REAL_TYPE: diff --git a/gcc/jit/jit-recording.c b/gcc/jit/jit-recording.c index 9d6d26a..6613ed7 100644 --- a/gcc/jit/jit-recording.c +++ b/gcc/jit/jit-recording.c @@ -181,11 +181,14 @@ recording::context::context (context *parent_ctxt) { if (parent_ctxt) { - /* Inherit options from parent. - Note that the first memcpy means copying pointers to strings. */ - memcpy (m_str_options, - parent_ctxt->m_str_options, - sizeof (m_str_options)); + /* Inherit options from parent. */ + for (unsigned i = 0; + i < sizeof (m_str_options) / sizeof (m_str_options[0]); + i++) + { + const char *parent_opt = parent_ctxt->m_str_options[i]; + m_str_options[i] = parent_opt ? xstrdup (parent_opt) : NULL; + } memcpy (m_int_options, parent_ctxt->m_int_options, sizeof (m_int_options)); @@ -831,7 +834,7 @@ recording::context::set_str_option (enum gcc_jit_str_option opt, return; } free (m_str_options[opt]); - m_str_options[opt] = xstrdup (value); + m_str_options[opt] = value ? xstrdup (value) : NULL; } /* Set the given integer option for this context, or add an error if diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5ba1eff..ad7acfb 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,65 @@ +2014-12-19 David Malcolm <dmalcolm@redhat.com> + + * jit.dg/test-expressions.c (make_tests_of_casts): Add tests of + casting between "long" and "bool". + (verify_casts): Verify these new test cases. + +2014-12-19 Matthew Fortune <matthew.fortune@imgtec.com> + + * gcc.target/mips/pr37362.c: Skip for mips-img-elf. + +2014-12-19 Matthew Fortune <matthew.fortune@imgtec.com> + Steve Ellcey <sellcey@imgtec.com> + + * gcc.dg/torture/mips-hilo-2.c: Unconditionally pass for R6 onwards. + * gcc.dg/torture/pr19683-1.c: Likewise. + * gcc.target/mips/branch-cost-2.c: Require MOVN. + * gcc.target/mips/movcc-1.c: Likewise. + * gcc.target/mips/movcc-2.c: Likewise. + * gcc.target/mips/movcc-3.c: Likewise. + * gcc.target/mips/call-saved-4.c: Require LDC. + * gcc.target/mips/dmult-1.c: Require R5 or earlier. + * gcc.target/mips/fpcmp-1.c: Likewise. + * gcc.target/mips/fpcmp-2.c: Likewise. + * gcc.target/mips/neg-abs-2.c: Likewise. + * gcc.target/mips/timode-1.c: Likewise. + * gcc.target/mips/unaligned-1.c: Likewise. + * gcc.target/mips/madd-3.c: Require MADD. + * gcc.target/mips/madd-9.c: Likewise. + * gcc.target/mips/maddu-3.c: Likewise. + * gcc.target/mips/msub-3.c: Likewise. + * gcc.target/mips/msubu-3.c: Likewise. + * gcc.target/mips/mult-1.c: Require INS and not DMUL. + * gcc.target/mips/mips-ps-type-2.c: Require MADD.PS. + * gcc.target/mips/mips.exp (mips_option_groups): Add ins, dmul, ldc, + movn, madd, maddps. + (mips-dg-options): INS available from R2. LDC available from MIPS II, + DMUL is present in octeon. Describe all features removed from R6. + +2014-12-19 Janus Weil <janus@gcc.gnu.org> + + PR fortran/64209 + * gfortran.dg/unlimited_polymorphic_19.f90: New. + +2014-12-19 Alan Lawrence <alan.lawrence@arm.com> + + * gcc.target/aarch64/eon_1.c: New test. + +2014-12-19 Paolo Carlini <paolo.carlini@oracle.com> + + * g++.dg/template/using30.C: Move... + * g++.dg/cpp0x/alias-decl-45.C: ... here. + +2014-12-19 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/60493 + * g++.dg/template/crash120.C: New. + +2014-12-19 Kai Tietz <ktietz@redhat.com> + + PR c++/61198 + * g++.dg/template/using30.C: New file. + 2014-12-19 Martin Liska <mliska@suse.cz> PR ipa/63569 diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-45.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-45.C new file mode 100644 index 0000000..e3434f5 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-45.C @@ -0,0 +1,24 @@ +// PR c++/61198 +// { dg-do compile { target c++11 } } + +template<int herp, typename derp_t> +struct broken +{ + template<typename target_t> + using rebind = broken<herp, target_t>; +}; + +template<typename derp_t> +struct broken<2, derp_t> +{ + template<typename target_t> + using rebind = broken<2, target_t>; +}; + +int main(int argc, char **argv) +{ + broken<2, float>::rebind<double> u; + + return 0; +} + diff --git a/gcc/testsuite/g++.dg/template/crash120.C b/gcc/testsuite/g++.dg/template/crash120.C new file mode 100644 index 0000000..9d15c2e --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash120.C @@ -0,0 +1,18 @@ +// PR c++/60493 + +template <class T, class U> +struct foo +{ +}; +template <class T> +struct baz +{ + class bar; +}; + +template <class T, class D> +struct baz<T>::bar : foo<int, D> // { dg-error "parameters|required" } +{ +}; + +baz<int>::bar it; // { dg-error "incomplete" } diff --git a/gcc/testsuite/gcc.dg/torture/mips-hilo-2.c b/gcc/testsuite/gcc.dg/torture/mips-hilo-2.c index dbe9493..78f7710 100644 --- a/gcc/testsuite/gcc.dg/torture/mips-hilo-2.c +++ b/gcc/testsuite/gcc.dg/torture/mips-hilo-2.c @@ -5,6 +5,7 @@ extern void abort (void); extern void exit (int); +#if __mips_isa_rev <= 5 unsigned int g; unsigned __attribute__ ((nomips16)) long long f (unsigned int x) @@ -15,13 +16,16 @@ unsigned __attribute__ ((nomips16)) long long f (unsigned int x) asm ("mflo\t%0" : "=r" (g) : "l" (u.parts[1])); return u.ll; } +#endif int __attribute__ ((nomips16)) main () { +#if __mips_isa_rev <= 5 union { unsigned long long ll; unsigned int parts[2]; } u; u.ll = f (0x12345678); if (g != u.parts[1]) abort (); +#endif exit (0); } diff --git a/gcc/testsuite/gcc.dg/torture/pr19683-1.c b/gcc/testsuite/gcc.dg/torture/pr19683-1.c index 05bf174..aa7205f 100644 --- a/gcc/testsuite/gcc.dg/torture/pr19683-1.c +++ b/gcc/testsuite/gcc.dg/torture/pr19683-1.c @@ -14,6 +14,7 @@ extern void exit (int); #define IN(X) unsigned int x##X = ptr[0] #define OUT(X) ptr[0] = x##X +#if __mips_isa_rev <= 5 union u { unsigned long long ll; unsigned int i[2]; }; unsigned int __attribute__ ((nomips16)) @@ -28,15 +29,18 @@ foo (volatile unsigned int *ptr) asm ("#" : "=l" (result) : "l" (u.i[1])); return result; } +#endif int __attribute__ ((nomips16)) main (void) { +#if __mips_isa_rev <= 5 unsigned int array[] = { 1000 * 1000 * 1000 }; union u u; u.ll = (unsigned long long) array[0] * array[0]; if (foo (array) != u.i[1]) abort (); +#endif exit (0); } diff --git a/gcc/testsuite/gcc.target/aarch64/eon_1.c b/gcc/testsuite/gcc.target/aarch64/eon_1.c new file mode 100644 index 0000000..dcdf3b4 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/eon_1.c @@ -0,0 +1,39 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +/* { dg-final { scan-assembler-not "\tf?mov\t" } } */ + +typedef long long int64_t; +typedef int64_t int64x1_t __attribute__ ((__vector_size__ (8))); + +/* { dg-final { scan-assembler-times "\\teon\\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+" 1 } } */ + +int64_t +test_eon (int64_t a, int64_t b) +{ + return a ^ ~b; +} + +/* { dg-final { scan-assembler-times "\\tmvn\\tx\[0-9\]+, x\[0-9\]+" 1 } } */ +int64_t +test_not (int64_t a) +{ + return ~a; +} + +/* There is no eon for SIMD regs; we prefer eor+mvn to mov+mov+eon+mov. */ + +/* { dg-final { scan-assembler-times "\\teor\\tv\[0-9\]+\.8b, v\[0-9\]+\.8b, v\[0-9\]+\.8b" 1 } } */ +/* { dg-final { scan-assembler-times "\\tmvn\\tv\[0-9\]+\.8b, v\[0-9\]+\.8b" 2 } } */ +int64x1_t +test_vec_eon (int64x1_t a, int64x1_t b) +{ + return a ^ ~b; +} + +int64x1_t +test_vec_not (int64x1_t a) +{ + return ~a; +} + diff --git a/gcc/testsuite/gcc.target/mips/args-3.c b/gcc/testsuite/gcc.target/mips/args-3.c index 6a79ce6..5eddabf 100644 --- a/gcc/testsuite/gcc.target/mips/args-3.c +++ b/gcc/testsuite/gcc.target/mips/args-3.c @@ -24,7 +24,7 @@ int foo (float inf, int64 in64, int32 in32) abort (); #endif -#if (__mips == 4 || __mips == 32 || __mips == 64) && !defined (__mips16) +#if (__mips == 4 || ((__mips == 32 || __mips == 64) && __mips_isa_rev < 6)) && !defined (__mips16) __asm__ ("move %0,%.\n\tmovn %0,%1,%2" : "=&r" (res32) : "r" (in32), "r" (in64 != 0)); if (res32 != 60) diff --git a/gcc/testsuite/gcc.target/mips/branch-cost-2.c b/gcc/testsuite/gcc.target/mips/branch-cost-2.c index 3b2c4a1..5a422ae 100644 --- a/gcc/testsuite/gcc.target/mips/branch-cost-2.c +++ b/gcc/testsuite/gcc.target/mips/branch-cost-2.c @@ -1,4 +1,4 @@ -/* { dg-options "-mbranch-cost=10 isa>=4" } */ +/* { dg-options "-mbranch-cost=10 (HAS_MOVN)" } */ /* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ NOMIPS16 int foo (int x, int y, int z, int k) diff --git a/gcc/testsuite/gcc.target/mips/call-saved-4.c b/gcc/testsuite/gcc.target/mips/call-saved-4.c index e126175..846ea32 100644 --- a/gcc/testsuite/gcc.target/mips/call-saved-4.c +++ b/gcc/testsuite/gcc.target/mips/call-saved-4.c @@ -1,5 +1,5 @@ /* Check that we save the correct call-saved GPRs and FPRs. */ -/* { dg-options "isa>=2 -mabi=32 -mfp32" } */ +/* { dg-options "(HAS_LDC) -mabi=32 -mfp32" } */ void bar (void); diff --git a/gcc/testsuite/gcc.target/mips/dmult-1.c b/gcc/testsuite/gcc.target/mips/dmult-1.c index f8c0b8b..9257316 100644 --- a/gcc/testsuite/gcc.target/mips/dmult-1.c +++ b/gcc/testsuite/gcc.target/mips/dmult-1.c @@ -1,4 +1,4 @@ -/* { dg-options "forbid_cpu=octeon.* -mgp64" } */ +/* { dg-options "isa_rev<=5 forbid_cpu=octeon.* -mgp64" } */ /* { dg-final { scan-assembler "\tdmult\t" } } */ /* { dg-final { scan-assembler "\tmflo\t" } } */ /* { dg-final { scan-assembler-not "\tdmul\t" } } */ diff --git a/gcc/testsuite/gcc.target/mips/fpcmp-1.c b/gcc/testsuite/gcc.target/mips/fpcmp-1.c index c0594ff..03c2f79 100644 --- a/gcc/testsuite/gcc.target/mips/fpcmp-1.c +++ b/gcc/testsuite/gcc.target/mips/fpcmp-1.c @@ -1,5 +1,5 @@ /* We used to use c.lt.fmt instead of c.ule.fmt here. */ -/* { dg-options "-mhard-float" } */ +/* { dg-options "isa_rev<=5 -mhard-float" } */ NOMIPS16 int f1 (float x, float y) { return __builtin_isless (x, y); } NOMIPS16 int f2 (double x, double y) { return __builtin_isless (x, y); } /* { dg-final { scan-assembler "\tc\\.ule\\.s\t" } } */ diff --git a/gcc/testsuite/gcc.target/mips/fpcmp-2.c b/gcc/testsuite/gcc.target/mips/fpcmp-2.c index 23d5cb0..6936b90 100644 --- a/gcc/testsuite/gcc.target/mips/fpcmp-2.c +++ b/gcc/testsuite/gcc.target/mips/fpcmp-2.c @@ -1,5 +1,5 @@ /* We used to use c.le.fmt instead of c.ult.fmt here. */ -/* { dg-options "-mhard-float" } */ +/* { dg-options "isa_rev<=5 -mhard-float" } */ NOMIPS16 int f1 (float x, float y) { return __builtin_islessequal (x, y); } NOMIPS16 int f2 (double x, double y) { return __builtin_islessequal (x, y); } /* { dg-final { scan-assembler "\tc\\.ult\\.s\t" } } */ diff --git a/gcc/testsuite/gcc.target/mips/madd-3.c b/gcc/testsuite/gcc.target/mips/madd-3.c index 29f4c9b..b0771ad 100644 --- a/gcc/testsuite/gcc.target/mips/madd-3.c +++ b/gcc/testsuite/gcc.target/mips/madd-3.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "isa_rev>=1 -mgp32" } */ +/* { dg-options "(HAS_MADD) -mgp32" } */ /* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ /* { dg-final { scan-assembler-times "\tmadd\t" 3 } } */ diff --git a/gcc/testsuite/gcc.target/mips/madd-9.c b/gcc/testsuite/gcc.target/mips/madd-9.c index 28681a9..acafc7a 100644 --- a/gcc/testsuite/gcc.target/mips/madd-9.c +++ b/gcc/testsuite/gcc.target/mips/madd-9.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "isa_rev>=1 -mgp32 -mtune=4kc" } */ +/* { dg-options "(HAS_MADD) -mgp32 -mtune=4kc" } */ /* References to X within the loop need to have a higher frequency than references to X outside the loop, otherwise there is no reason to prefer multiply/accumulator registers over GPRs. */ diff --git a/gcc/testsuite/gcc.target/mips/maddu-3.c b/gcc/testsuite/gcc.target/mips/maddu-3.c index 27a7350..e180fa7 100644 --- a/gcc/testsuite/gcc.target/mips/maddu-3.c +++ b/gcc/testsuite/gcc.target/mips/maddu-3.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* This test requires widening_mul */ -/* { dg-options "isa_rev>=1 -mgp32 -fexpensive-optimizations" } */ +/* { dg-options "(HAS_MADD) -mgp32 -fexpensive-optimizations" } */ /* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ /* { dg-final { scan-assembler-times "\tmaddu\t" 3 } } */ diff --git a/gcc/testsuite/gcc.target/mips/mips-ps-type-2.c b/gcc/testsuite/gcc.target/mips/mips-ps-type-2.c index f52cf91..a4dfbae 100644 --- a/gcc/testsuite/gcc.target/mips/mips-ps-type-2.c +++ b/gcc/testsuite/gcc.target/mips/mips-ps-type-2.c @@ -1,7 +1,7 @@ /* Test v2sf calculations. The nmadd and nmsub patterns need -ffinite-math-only. */ /* { dg-do compile } */ -/* { dg-options "isa_rev>=2 -mgp32 -mpaired-single -ffinite-math-only" } */ +/* { dg-options "(HAS_MADDPS) -mgp32 -mpaired-single -ffinite-math-only" } */ /* { dg-skip-if "nmadd and nmsub need combine" { *-*-* } { "-O0" } { "" } } */ /* { dg-final { scan-assembler "\tcvt.ps.s\t" } } */ /* { dg-final { scan-assembler "\tmov.ps\t" } } */ diff --git a/gcc/testsuite/gcc.target/mips/mips.exp b/gcc/testsuite/gcc.target/mips/mips.exp index e117a80..febc73a 100644 --- a/gcc/testsuite/gcc.target/mips/mips.exp +++ b/gcc/testsuite/gcc.target/mips/mips.exp @@ -247,6 +247,12 @@ set mips_option_groups { small-data "-G[0-9]+" warnings "-w" dump "-fdump-.*" + ins "HAS_INS" + dmul "NOT_HAS_DMUL" + ldc "HAS_LDC" + movn "HAS_MOVN" + madd "HAS_MADD" + maddps "HAS_MADDPS" } for { set option 0 } { $option < 32 } { incr option } { @@ -1063,6 +1069,9 @@ proc mips-dg-options { args } { && (($gp_size == 32 && [mips_have_test_option_p options "-mfp64"]) || [mips_have_test_option_p options "-msynci"] || [mips_have_test_option_p options "-mdsp"] + || [mips_have_test_option_p options "HAS_INS"] + || [mips_have_test_option_p options "HAS_MADD"] + || [mips_have_test_option_p options "HAS_MADDPS"] || [mips_have_test_option_p options "-mdspr2"]) } { if { $gp_size == 32 } { mips_make_test_option options "-mips32r2" @@ -1084,6 +1093,12 @@ proc mips-dg-options { args } { } else { mips_make_test_option options "-mips64" } + # We need MIPS IV or higher for: + # + # + } elseif { $isa < 3 + && [mips_have_test_option_p options "HAS_MOVN"] } { + mips_make_test_option options "-mips4" # We need MIPS III or higher for: # # - the "cache" instruction @@ -1102,8 +1117,38 @@ proc mips-dg-options { args } { && ([mips_have_test_option_p options "-mbranch-likely"] || [mips_have_test_option_p options "-mfix-r10000"] || ($gp_size == 32 - && [mips_have_test_option_p options "-mfpxx"])) } { + && ([mips_have_test_option_p options "-mfpxx"] + || [mips_have_test_option_p options "HAS_LDC"]))) } { mips_make_test_option options "-mips2" + # We need to use octeon's base ISA if a test must not run with an + # architecture that supports dmul. + } elseif { [regexp -- "^-march=octeon.*\$" $arch] + && [mips_have_test_option_p options "NOT_HAS_DMUL"] } { + mips_make_test_option options "-mips${isa}r${isa_rev}" + # Check whether we need to switch from mips*r6 down to mips*r5 due + # to options that are incompatible with mips*r6. If we do, use + # -mnan=2008 because r6 is nan2008 by default and without this flag + # tests that include stdlib.h will fail due to not finding + # stubs-o32_hard.h (r6 compilers only have stubs-o32_hard_2008.h) + } elseif { $isa_rev > 5 + && ([mips_have_test_option_p options "-mdsp"] + || [mips_have_test_option_p options "-mdspr2"] + || [mips_have_test_option_p options "-mips16"] + || [mips_have_test_option_p options "-mmicromips"] + || [mips_have_test_option_p options "-mfp32"] + || [mips_have_test_option_p options "-mfix-r10000"] + || [mips_have_test_option_p options "NOT_HAS_DMUL"] + || [mips_have_test_option_p options "HAS_MOVN"] + || [mips_have_test_option_p options "HAS_MADD"] + || [mips_have_test_option_p options "-mpaired-single"] + || [mips_have_test_option_p options "-mnan=legacy"] + || [mips_have_test_option_p options "-mabs=legacy"]) } { + if { $gp_size == 32 } { + mips_make_test_option options "-mips32r5" + } else { + mips_make_test_option options "-mips64r5" + } + mips_make_test_option options "-mnan=2008" # Check whether we need to switch from a 32-bit processor to the # "nearest" 64-bit processor. } elseif { $gp_size == 64 && [mips_32bit_arch_p $arch] } { @@ -1128,6 +1173,10 @@ proc mips-dg-options { args } { unset isa_rev } + # Re-calculate the isa_rev for use in the abi handling code below + set arch [mips_option options arch] + set isa_rev [mips_arch_info $arch isa_rev] + # Set an appropriate ABI, handling dependencies between the pre-abi # options and the abi options. This should mirror the abi and post-abi # code below. @@ -1192,8 +1241,8 @@ proc mips-dg-options { args } { if { $abi_test_option_p } { if { $eabi_p } { mips_make_test_option options "-mno-abicalls" - if { $gp_size == 32 } { - mips_make_test_option options "-mfp32" + if { $isa_rev < 6 && $gp_size == 32 } { + mips_make_test_option options "-mfp32" } } if { [mips_using_mips16_p options] @@ -1238,6 +1287,17 @@ proc mips-dg-options { args } { mips_make_test_option options "-mno-dsp" mips_make_test_option options "-mno-synci" } + if { $isa_rev > 5 } { + mips_make_test_option options "-mno-dsp" + mips_make_test_option options "-mno-mips16" + if { [mips_have_test_option_p options "-mdsp"] } { + mips_make_test_option options "-mfp64" + } + mips_make_test_option options "-mno-fix-r10000" + mips_make_test_option options "-mno-paired-single" + mips_make_test_option options "-mnan=2008" + mips_make_test_option options "-mabs=2008" + } unset arch unset isa unset isa_rev diff --git a/gcc/testsuite/gcc.target/mips/movcc-1.c b/gcc/testsuite/gcc.target/mips/movcc-1.c index b3fe188..7943fec 100644 --- a/gcc/testsuite/gcc.target/mips/movcc-1.c +++ b/gcc/testsuite/gcc.target/mips/movcc-1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "isa>=4" } */ +/* { dg-options "(HAS_MOVN)" } */ /* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ /* { dg-final { scan-assembler "\tmovz\t" } } */ /* { dg-final { scan-assembler "\tmovn\t" } } */ diff --git a/gcc/testsuite/gcc.target/mips/movcc-2.c b/gcc/testsuite/gcc.target/mips/movcc-2.c index 2638d51..1926e64 100644 --- a/gcc/testsuite/gcc.target/mips/movcc-2.c +++ b/gcc/testsuite/gcc.target/mips/movcc-2.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "isa>=4" } */ +/* { dg-options "(HAS_MOVN)" } */ /* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ /* { dg-final { scan-assembler "\tmovz\t" } } */ /* { dg-final { scan-assembler "\tmovn\t" } } */ diff --git a/gcc/testsuite/gcc.target/mips/movcc-3.c b/gcc/testsuite/gcc.target/mips/movcc-3.c index f356465..55434b7 100644 --- a/gcc/testsuite/gcc.target/mips/movcc-3.c +++ b/gcc/testsuite/gcc.target/mips/movcc-3.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "isa>=4 -mhard-float" } */ +/* { dg-options "(HAS_MOVN) -mhard-float" } */ /* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ /* { dg-final { scan-assembler "\tmovt\t" } } */ /* { dg-final { scan-assembler "\tmovf\t" } } */ diff --git a/gcc/testsuite/gcc.target/mips/msub-3.c b/gcc/testsuite/gcc.target/mips/msub-3.c index aedd043..132db85 100644 --- a/gcc/testsuite/gcc.target/mips/msub-3.c +++ b/gcc/testsuite/gcc.target/mips/msub-3.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* This test requires widening_mul */ -/* { dg-options "isa_rev>=1 -mgp32 -fexpensive-optimizations" } */ +/* { dg-options "(HAS_MADD) -mgp32 -fexpensive-optimizations" } */ /* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ /* { dg-final { scan-assembler-times "\tmsub\t" 2 } } */ diff --git a/gcc/testsuite/gcc.target/mips/msubu-3.c b/gcc/testsuite/gcc.target/mips/msubu-3.c index 2e936eb..07cb7c7 100644 --- a/gcc/testsuite/gcc.target/mips/msubu-3.c +++ b/gcc/testsuite/gcc.target/mips/msubu-3.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* This test requires widening_mul */ -/* { dg-options "isa_rev>=1 -mgp32 -fexpensive-optimizations" } */ +/* { dg-options "(HAS_MADD) -mgp32 -fexpensive-optimizations" } */ /* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ /* { dg-final { scan-assembler-times "\tmsubu\t" 2 } } */ diff --git a/gcc/testsuite/gcc.target/mips/mult-1.c b/gcc/testsuite/gcc.target/mips/mult-1.c index 1038797..bd9757c 100644 --- a/gcc/testsuite/gcc.target/mips/mult-1.c +++ b/gcc/testsuite/gcc.target/mips/mult-1.c @@ -1,7 +1,7 @@ /* For SI->DI widening multiplication we should use DINS to combine the two halves. For Octeon use DMUL with explicit widening. */ /* This test requires widening_mul */ -/* { dg-options "-mgp64 isa_rev>=2 forbid_cpu=octeon.* -fexpensive-optimizations" } */ +/* { dg-options "-mgp64 (HAS_INS) (NOT_HAS_DMUL) -fexpensive-optimizations" } */ /* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ /* { dg-final { scan-assembler "\tdins\t" } } */ /* { dg-final { scan-assembler-not "\tdsll\t" } } */ diff --git a/gcc/testsuite/gcc.target/mips/neg-abs-2.c b/gcc/testsuite/gcc.target/mips/neg-abs-2.c index 435751e..59e797d 100644 --- a/gcc/testsuite/gcc.target/mips/neg-abs-2.c +++ b/gcc/testsuite/gcc.target/mips/neg-abs-2.c @@ -1,7 +1,7 @@ /* Make sure that we avoid abs.fmt and neg.fmt when the signs of NaNs matter. */ /* { dg-do compile } */ -/* { dg-options "-mhard-float -fno-finite-math-only" } */ +/* { dg-options "isa_rev<=5 -mhard-float -fno-finite-math-only -mabs=legacy" } */ /* { dg-final { scan-assembler-not "\tneg.s\t" } } */ /* { dg-final { scan-assembler-not "\tneg.d\t" } } */ /* { dg-final { scan-assembler-not "\tabs.s\t" } } */ diff --git a/gcc/testsuite/gcc.target/mips/pr37362.c b/gcc/testsuite/gcc.target/mips/pr37362.c index 848d879..2ad4e8d 100644 --- a/gcc/testsuite/gcc.target/mips/pr37362.c +++ b/gcc/testsuite/gcc.target/mips/pr37362.c @@ -1,5 +1,5 @@ /* mips*-sde-elf doesn't have 128-bit long doubles. */ -/* { dg-do compile { target { ! { mips*-sde-elf mips*-mti-elf } } } } */ +/* { dg-do compile { target { ! { mips*-sde-elf mips*-mti-elf mips*-img-elf } } } } */ /* { dg-options "-march=mips64r2 -mabi=n32" } */ typedef float TFtype __attribute__((mode(TF))); diff --git a/gcc/testsuite/gcc.target/mips/timode-1.c b/gcc/testsuite/gcc.target/mips/timode-1.c index 606fee0..be3d317 100644 --- a/gcc/testsuite/gcc.target/mips/timode-1.c +++ b/gcc/testsuite/gcc.target/mips/timode-1.c @@ -1,4 +1,4 @@ -/* { dg-options "-mgp64" } */ +/* { dg-options "isa_rev<=5 -mgp64" } */ /* { dg-skip-if "we deliberately use calls when optimizing for size" { *-*-* } { "-Os" } { "" } } */ typedef int int128_t __attribute__((mode(TI))); typedef unsigned int uint128_t __attribute__((mode(TI))); diff --git a/gcc/testsuite/gcc.target/mips/unaligned-1.c b/gcc/testsuite/gcc.target/mips/unaligned-1.c index 938f52d..4888ca8 100644 --- a/gcc/testsuite/gcc.target/mips/unaligned-1.c +++ b/gcc/testsuite/gcc.target/mips/unaligned-1.c @@ -1,4 +1,4 @@ -/* { dg-options "-mgp64" } */ +/* { dg-options "isa_rev<=5 -mgp64" } */ /* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ /* { dg-final { scan-assembler-times "\tsdl\t" 1 } } */ /* { dg-final { scan-assembler-times "\tsdr\t" 1 } } */ diff --git a/gcc/testsuite/gfortran.dg/unlimited_polymorphic_19.f90 b/gcc/testsuite/gfortran.dg/unlimited_polymorphic_19.f90 new file mode 100644 index 0000000..a2dbaef --- /dev/null +++ b/gcc/testsuite/gfortran.dg/unlimited_polymorphic_19.f90 @@ -0,0 +1,53 @@ +! { dg-do run } +! +! PR 64209: [OOP] runtime segfault with CLASS(*), INTENT(OUT) dummy argument +! +! Contributed by Miha Polajnar <polajnar.miha@gmail.com> + +MODULE m + IMPLICIT NONE + TYPE :: t + CLASS(*), ALLOCATABLE :: x(:) + CONTAINS + PROCEDURE :: copy + END TYPE t + INTERFACE + PURE SUBROUTINE copy_proc_intr(a,b) + CLASS(*), INTENT(IN) :: a + CLASS(*), INTENT(OUT) :: b + END SUBROUTINE copy_proc_intr + END INTERFACE +CONTAINS + SUBROUTINE copy(self,cp,a) + CLASS(t), INTENT(IN) :: self + PROCEDURE(copy_proc_intr) :: cp + CLASS(*), INTENT(OUT) :: a(:) + INTEGER :: i + IF( .not.same_type_as(self%x(1),a(1)) ) STOP -1 + DO i = 1, size(self%x) + CALL cp(self%x(i),a(i)) + END DO + END SUBROUTINE copy +END MODULE m + +PROGRAM main + USE m + IMPLICIT NONE + INTEGER, PARAMETER :: n = 3, x(n) = [ 1, 2, 3 ] + INTEGER :: copy_x(n) + TYPE(t) :: test + ALLOCATE(test%x(n),SOURCE=x) + CALL test%copy(copy_int,copy_x) +! PRINT '(*(I0,:2X))', copy_x +CONTAINS + PURE SUBROUTINE copy_int(a,b) + CLASS(*), INTENT(IN) :: a + CLASS(*), INTENT(OUT) :: b + SELECT TYPE(a); TYPE IS(integer) + SELECT TYPE(b); TYPE IS(integer) + b = a + END SELECT; END SELECT + END SUBROUTINE copy_int +END PROGRAM main + +! { dg-final { cleanup-modules "m" } } diff --git a/gcc/testsuite/jit.dg/test-expressions.c b/gcc/testsuite/jit.dg/test-expressions.c index eb986f3..87abb76 100644 --- a/gcc/testsuite/jit.dg/test-expressions.c +++ b/gcc/testsuite/jit.dg/test-expressions.c @@ -543,6 +543,8 @@ make_tests_of_casts (gcc_jit_context *ctxt) { gcc_jit_type *int_type = gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); + gcc_jit_type *long_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_LONG); gcc_jit_type *float_type = gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_FLOAT); gcc_jit_type *bool_type = @@ -582,6 +584,20 @@ make_tests_of_casts (gcc_jit_context *ctxt) "test_cast_from_int_to_bool"), "(bool)a"); + /* bool/long conversions */ + CHECK_STRING_VALUE ( + make_test_of_cast (ctxt, + bool_type, + long_type, + "test_cast_from_bool_to_long"), + "(long)a"); + CHECK_STRING_VALUE ( + make_test_of_cast (ctxt, + long_type, + bool_type, + "test_cast_from_long_to_bool"), + "(bool)a"); + /* array/ptr conversions */ { gcc_jit_function *test_fn = @@ -701,6 +717,28 @@ verify_casts (gcc_jit_result *result) CHECK_VALUE (test_cast_from_int_to_bool (1), 1); } + /* bool to long */ + { + typedef long (*fn_type) (bool); + fn_type test_cast_from_bool_to_long = + (fn_type)gcc_jit_result_get_code (result, + "test_cast_from_bool_to_long"); + CHECK_NON_NULL (test_cast_from_bool_to_long); + CHECK_VALUE (test_cast_from_bool_to_long (0), 0); + CHECK_VALUE (test_cast_from_bool_to_long (1), 1); + } + + /* long to bool */ + { + typedef bool (*fn_type) (long); + fn_type test_cast_from_long_to_bool = + (fn_type)gcc_jit_result_get_code (result, + "test_cast_from_long_to_bool"); + CHECK_NON_NULL (test_cast_from_long_to_bool); + CHECK_VALUE (test_cast_from_long_to_bool (0), 0); + CHECK_VALUE (test_cast_from_long_to_bool (1), 1); + } + /* array to ptr */ { typedef int (*fn_type) (void); diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index ea0057f..efd08c4 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,8 @@ +2014-12-19 Matthew Fortune <matthew.fortune@imgtec.com> + + * config.host: Support mipsisa32r6 and mipsisa64r6. + * config/mips/mips16.S: Do not build for R6. + 2014-12-17 Oleg Endo <olegendo@gcc.gnu.org> * config/sh/crt.h: New. diff --git a/libgcc/config.host b/libgcc/config.host index 9903d15..b10d725 100644 --- a/libgcc/config.host +++ b/libgcc/config.host @@ -827,8 +827,10 @@ mips*-sde-elf*) ;; mipsisa32-*-elf* | mipsisa32el-*-elf* | \ mipsisa32r2-*-elf* | mipsisa32r2el-*-elf* | \ +mipsisa32r6-*-elf* | mipsisa32r6el-*-elf* | \ mipsisa64-*-elf* | mipsisa64el-*-elf* | \ -mipsisa64r2-*-elf* | mipsisa64r2el-*-elf*) +mipsisa64r2-*-elf* | mipsisa64r2el-*-elf* | \ +mipsisa64r6-*-elf* | mipsisa64r6el-*-elf*) tmake_file="$tmake_file mips/t-elf mips/t-crtstuff mips/t-mips16" extra_parts="$extra_parts crti.o crtn.o" ;; diff --git a/libgcc/config/mips/mips16.S b/libgcc/config/mips/mips16.S index c0c73ff..1783d11 100644 --- a/libgcc/config/mips/mips16.S +++ b/libgcc/config/mips/mips16.S @@ -23,12 +23,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #include "auto-host.h" -#if defined(__mips_micromips) || defined(__mips_soft_float) +#if defined(__mips_micromips) || defined(__mips_soft_float) \ + || __mips_isa_rev >= 6 /* Do nothing because this code is only needed when linking against mips16 hard-float objects. Neither micromips code - nor soft-float code can be linked against mips16 hard-float - objects so we do not need these routines when building libgcc - for those cases. */ + nor soft-float nor MIPS R6 code can be linked against mips16 + hard-float objects so we do not need these routines when + building libgcc for those cases. */ #else #if defined(HAVE_AS_MODULE) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 2405bb5..a46a2b6 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,187 @@ +2014-12-19 Jonathan Wakely <jwakely@redhat.com> + + * acinclude.m4 (GLIBCXX_ENABLE_LIBSTDCXX_CXX11_ABI): Remove. + (GLIBCXX_ENABLE_LIBSTDCXX_DUAL_ABI, GLIBCXX_DEFAULT_ABI): Add. + * configure.ac: Use new macros. + * configure: Regenerate. + * Makefile.in: Regenerate. + * doc/Makefile.in: Regenerate. + * libsupc++/Makefile.in: Regenerate. + * po/Makefile.in: Regenerate. + * src/Makefile.in: Regenerate. + * testsuite/Makefile.in: Regenerate. + * include/Makefile.am: Set _GLIBCXX_USE_DUAL_ABI. + * include/Makefile.in: Regenerate. + * config/abi/pre/gnu.ver: Export symbols related to new std::string. + Tighten old patterns to not match new symbols. + * config/locale/generic/monetary_members.cc: Guard some definitions + to not compile with new ABI. + * config/locale/gnu/monetary_members.cc: Likewise. + * config/locale/gnu/numeric_members.cc: Prevent double-free. + * config/os/gnu-linux/ldbl-extra.ver: Add new __gnu_cxx_ldbl128 + exports. Tighten old patterns. + * doc/xml/manual/configure.xml: Document new configure options. + * doc/html/*: Regenerate. + * include/bits/basic_string.h (__cxx11::basic_string): Define new + non-reference-counted implementation in inline namespace __cxx11. + (stoi, stol, stoll, stof, stod, stold, to_string): Conditionally use + inline namespace. + (literals::string_literals::operator"): Conditionally use abi-tag. + * include/bits/basic_string.tcc (__cxx11::basic_string): Define. + * include/bits/c++config: Define _GLIBCXX_USE_DUAL_ABI and + LDBL_CXX11_ABI namespace macros. + * include/bits/locale_classes.h (locale::name()): Use abi_tag when + new ABI is in use. + (locale::_S_twinned_facets): New static member. + (locale::facet::__shim): Declare new type. + (locale::_facet::_M_sso_shim, locale::_facet::_M_cow_shim): New + functions for creating shims. + (locale::_Impl::_M_facet_unchecked): New member function for use + during construction. + (locale::_Impl::_M_init_extra): New member functions to create second + version of some facets. + (collate, collate_byname): Use abi_tag when new ABI is in use. + * include/bits/locale_facets.h: Add _GLIBCXX_NUM_CXX11_FACETS macro. + (numpunct, numpunct_byname): Use __cxx11 namespace. + (num_get::_M_extract_float, num_get::_M_extract_int): Use abi_tag + when new ABI is in use. + (num_get::__do_get, num_put::__do_put): Do not declare long double + compat functions for new ABI. + * include/bits/locale_facets.tcc (num_get, num_put): Use abi_tag on + definitions. + (numpunct, numpunct_byname): Qualify explicit instantiations. + * include/bits/locale_facets_nonio.h (time_get, time_get_byname, + moneypunct, moneypunct_byname, money_get, money_put, messages, + messages_byname): Use new inline namespace macros. + (money_get::__do_get, money_put::__do_put): Do not declare long + double compat functions for new ABI. + * include/bits/locale_facets_nonio.tcc (money_get, money_put): Use + new namespace macros. + (money_get::__do_get, money_put::__do_put): Do not define for new ABI. + * include/bits/localefwd.h (numpunct, numpunct_byname, collate, + collate_byname, time_get, time_get_byname, moneypunct, + moneypunct_byname, money_get, money_put, messages, messages_byname): + Use new namespace macros. + * include/bits/regex.h: Use inline namespace macros. + * include/bits/stl_list.h (_List_base, list): Use inline namespace + instead of abi-tag. + * include/bits/stringfwd.h (basic_string): Use namespace macros. + * include/std/iosfwd (basic_stringbuf, basic_istringstream, + basic_ostringstream, basic_stringstream): Likewise. + * include/std/sstream: Likewise. + (basic_stringbuf::__xfer_bufptrs): Update streambuf pointers on move. + * include/std/stdexcept (__cow_string, __sso_string): New types for + indirectly using std::string with either ABI. + (logic_error, runtime_error): Replace std::string member with + __cow_string when new ABI is in use. Declare non-inline copy + constructor and assignment operator. Declare const char* constructors. + (domain_error, invalid_argument, length_error, out_of_range, + range_error, overflow_error, underflow_error): Declare const char* + constructors. + * include/std/system_error (error_category): Replace with new + definition in inline namespace _V2. + (error_code::message, error_condition::message): Use abi_tag on + functions returning std::string. + * python/libstdcxx/v6/printers.py (StdStringPrinter): Handle new ABI. + * src/c++11/Makefile.am: Add new files. + * src/c++11/Makefile.in: Regenerate. + * src/c++11/compatibility-c++0x.cc: Compile with old std::string ABI. + Define old error_category symbols. + * src/c++11/cow-fstream-inst.cc: New. Instantiate fstream members + using old std::string ABI. + * src/c++11/cow-locale_init.cc (locale::_Impl::_M_init_extra): Define. + * src/c++11/cow-shim_facets.cc: Define shim facets using old ABI. + * src/c++11/cow-sstream-inst.cc: Instantiate stringstreams using old + std::string ABI. + * src/c++11/cow-stdexcept.cc: Define new constructors and assignment + operators. + (__cow_string, error_category::_M_message): Define. + * src/c++11/cow-string-inst.cc: Explicit instantiations using old + std::string. Include src/c++98/istream-string.cc. + * src/c++11/cow-wstring-inst.cc: Explicit instantiations using old + std::wstring. + * src/c++11/cxx11-hash_tr1.cc: Explicit instantiations using new + string. + * src/c++11/cxx11-ios_failure.cc: Add sanity check. + * src/c++11/cxx11-locale-inst.cc: Instantiate facets using new + std::string. + * src/c++11/cxx11-shim_facets.cc: Define shim facets using new ABI. + * src/c++11/cxx11-stdexcept.cc: Define constructors taking new + std::string. + * src/c++11/cxx11-wlocale-inst.cc: Instantiate facets using + new std::wstring. + * src/c++11/fstream-inst.cc: Compile with new ABI. + * src/c++11/functexcept.cc: Compile with old ABI. + * src/c++11/random.cc: Compile with new ABI. + * src/c++11/sstream-inst.cc: Compile with new ABI. + * src/c++11/string-inst.cc: Explicit instantiations for new string. + * src/c++11/system_error.cc (__sso_string, error_category::_M_message): + Define. + * src/c++11/wstring-inst.cc: Compile with new ABI. + * src/c++98/Makefile.am: Compile some host files twice for old and + new std::string. Add new files. + * src/c++98/Makefile.in: Regenerate. + * src/c++98/compatibility-ldbl.cc: Compile with old ABI. + * src/c++98/compatibility.cc: Likewise. + * src/c++98/concept-inst.cc: Likewise. + * src/c++98/hash_tr1.cc: Likewise. + * src/c++98/istream-string.cc: New file defining functions that + work with istream and std::string moved from ... + * src/c++98/istream.cc: ... here. + * src/c++98/cow-istream-string.cc: Recompile istream-string.cc with + old ABI. + * src/c++98/locale-inst.cc: Adjust facet instantiations to work for + either ABI. + * src/c++98/locale.cc (locale::_M_install_facet, + locale::_M_install_cache): Handle twinned facets. + * src/c++98/locale-facets.cc: Compile with old std::string ABI. + (__verify_grouping): Define new overload and old std::string version. + * src/c++98/locale_init.cc: Initialize twinned facets. + * src/c++98/localename.cc: Likewise. + * src/c++98/misc-inst.cc: Instantiate C++98-only std::string members. + (__verify_grouping): Define new std::string version. + * src/c++98/stdexcept.cc: Compile with old std::string ABI. + * src/c++98/wlocale-inst.cc: Likewise. + * testsuite/18_support/50594.cc: Adjust to work with SSO strings. + * testsuite/21_strings/basic_string/capacity/1.cc: Likewise. + * testsuite/21_strings/basic_string/capacity/char/1.cc: Likewise. + * testsuite/21_strings/basic_string/capacity/char/18654.cc: Likewise. + * testsuite/21_strings/basic_string/capacity/char/2.cc: Likewise. + * testsuite/21_strings/basic_string/capacity/wchar_t/1.cc: Likewise. + * testsuite/21_strings/basic_string/capacity/wchar_t/18654.cc: + Likewise. + * testsuite/21_strings/headers/string/synopsis.cc: Use inline + namespace macros. + * testsuite/23_containers/headers/list/synopsis.cc: Likewise. + * testsuite/27_io/basic_ios/copyfmt/char/1.cc: Set dg-options so + correct exception type can be caught. + * testsuite/27_io/basic_ios/exceptions/char/1.cc: Likewise. + * testsuite/27_io/basic_istream/extractors_arithmetic/char/ + exceptions_failbit.cc: Likewise. + * testsuite/27_io/basic_istream/extractors_arithmetic/wchar_t/ + exceptions_failbit.cc: Likewise. + * testsuite/27_io/basic_istream/extractors_other/char/ + exceptions_null.cc: Likewise. + * testsuite/27_io/basic_istream/extractors_other/wchar_t/ + exceptions_null.cc: Likewise. + * testsuite/27_io/basic_istream/sentry/char/12297.cc: Likewise. + * testsuite/27_io/basic_istream/sentry/wchar_t/12297.cc: Likewise. + * testsuite/27_io/basic_ostream/inserters_other/char/ + exceptions_null.cc: Likewise. + * testsuite/27_io/basic_ostream/inserters_other/wchar_t/ + exceptions_null.cc: Likewise. + * testsuite/27_io/ios_base/storage/2.cc: Likewise. + * testsuite/27_io/ios_base/failure/cxx11.cc: Disable for old ABI. + * testsuite/ext/profile/mutex_extensions_neg.cc: Adjust dg-error. + * testsuite/libstdc++-prettyprinters/libfundts.cc: Use old ABI. + * testsuite/libstdc++-prettyprinters/simple.cc: Likewise. + * testsuite/libstdc++-prettyprinters/simple11.cc: Likewise. + * testsuite/libstdc++-prettyprinters/whatis.cc: Likewise. + * testsuite/util/exception/safety.h: Adjust member function types + for new std::string. + * testsuite/util/testsuite_abi.cc: Add new version and ignore + __float128 symbols in __cxx11 namespace. + 2014-12-17 Tim Shen <timshen@google.com> PR libstdc++/64302 diff --git a/libstdc++-v3/Makefile.in b/libstdc++-v3/Makefile.in index bede542..961d840 100644 --- a/libstdc++-v3/Makefile.in +++ b/libstdc++-v3/Makefile.in @@ -244,6 +244,7 @@ glibcxx_POFILES = @glibcxx_POFILES@ glibcxx_builddir = @glibcxx_builddir@ glibcxx_compiler_pic_flag = @glibcxx_compiler_pic_flag@ glibcxx_compiler_shared_flag = @glibcxx_compiler_shared_flag@ +glibcxx_cxx98_abi = @glibcxx_cxx98_abi@ glibcxx_localedir = @glibcxx_localedir@ glibcxx_lt_pic_flag = @glibcxx_lt_pic_flag@ glibcxx_prefixdir = @glibcxx_prefixdir@ diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4 index 0229609..db357d6 100644 --- a/libstdc++-v3/acinclude.m4 +++ b/libstdc++-v3/acinclude.m4 @@ -3832,24 +3832,57 @@ AC_DEFUN([GLIBCXX_CHECK_SDT_H], [ ]) dnl -dnl Check if the user wants the new C++11-conforming ABI. +dnl Control whether the library should define symbols for old and new ABIs. +dnl This affects definitions of strings, stringstreams and locale facets. dnl -dnl --disable-libstdcxx-cxx11-abi will use old ABI for all types. +dnl --disable-libstdcxx-dual-abi will use old ABI for all types. dnl dnl Defines: -dnl _GLIBCXX_USE_ABI_TAG (always defined, either to 1 or 0) +dnl _GLIBCXX_USE_DUAL_ABI (always defined, either to 1 or 0) dnl -AC_DEFUN([GLIBCXX_ENABLE_LIBSTDCXX_CXX11_ABI], [ - AC_ARG_ENABLE([libstdcxx-cxx11-abi], - AC_HELP_STRING([--disable-libstdcxx-cxx11-abi], - [disable the C++11-conforming ABI]),, - [enable_libstdcxx_cxx11_abi=yes]) - if test x"$enable_libstdcxx_cxx11_abi" != xyes; then - AC_MSG_NOTICE([C++11-conforming ABI is disabled]) +AC_DEFUN([GLIBCXX_ENABLE_LIBSTDCXX_DUAL_ABI], [ + GLIBCXX_ENABLE(libstdcxx-dual-abi,$1,,[support two versions of std::string]) + if test x"$enable_libstdcxx_dual_abi" != xyes; then + AC_MSG_NOTICE([dual ABI is disabled]) + default_libstdcxx_abi="c++98" fi - GLIBCXX_CONDITIONAL(ENABLE_CXX11_ABI, test $enable_libstdcxx_cxx11_abi = yes) + GLIBCXX_CONDITIONAL(ENABLE_DUAL_ABI, test $enable_libstdcxx_dual_abi = yes) ]) +dnl +dnl Check to see which ABI should be enabled by default. +dnl +dnl --with-default-libstdcxx-abi={c++98,c++11} +dnl +dnl Defines: +dnl _GLIBCXX_USE_CXX11_ABI (always defined, either to 1 or 0) +dnl +AC_DEFUN([GLIBCXX_DEFAULT_ABI], [ + if test x$enable_libstdcxx_dual_abi = xyes; then + AC_MSG_CHECKING([for default std::string ABI to use]) + AC_ARG_WITH([default-libstdcxx-abi], + AS_HELP_STRING([--with-default-libstdcxx-abi], + [set the std::string ABI to use by default]), + [case "$withval" in + c++98|gnu++98|c++03|gnu++03) default_libstdcxx_abi="c++98" ;; + c++1?|gnu++1?) default_libstdcxx_abi="c++11" ;; + *) AC_MSG_ERROR([Invalid argument for --with-default-libstdcxx-abi]) ;; + esac], + [default_libstdcxx_abi="c++11"]) + AC_MSG_RESULT(${default_libstdcxx_abi}) + fi + if test $default_libstdcxx_abi = "c++11"; then + glibcxx_cxx11_abi=1 + glibcxx_cxx98_abi=0 + else + glibcxx_cxx11_abi=0 + glibcxx_cxx98_abi=1 + fi + AC_SUBST(glibcxx_cxx98_abi) + GLIBCXX_CONDITIONAL(ENABLE_CXX11_ABI, test $glibcxx_cxx11_abi = 1) +]) + + # Macros from the top-level gcc directory. m4_include([../config/gc++filt.m4]) m4_include([../config/tls.m4]) diff --git a/libstdc++-v3/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver index 5893f1b..8ba8ed4 100644 --- a/libstdc++-v3/config/abi/pre/gnu.ver +++ b/libstdc++-v3/config/abi/pre/gnu.ver @@ -73,7 +73,7 @@ GLIBCXX_3.4 { # std::[d-g]*; std::d[a-d]*; std::d[f-n]*; - std::domain_error::d*; +# std::domain_error::d*; # std::domain_error::~d*; std::d[p-z]*; std::e[a-q]*; @@ -82,7 +82,7 @@ GLIBCXX_3.4 { std::gslice*; std::h[^a]*; std::i[a-m]*; - std::invalid_argument::i*; +# std::invalid_argument::i*; # std::invalid_argument::~i*; # std::ios_base::[A-Ha-z]*; std::ios_base::[A-Ha-e]*; @@ -103,9 +103,8 @@ GLIBCXX_3.4 { std::istrstream*; std::i[t-z]*; std::[A-Zj-k]*; - std::length_error::l*; +# std::length_error::l*; # std::length_error::~l*; - std::logic_error*; std::locale::[A-Za-e]*; std::locale::facet::[A-Za-z]*; std::locale::facet::_S_get_c_locale*; @@ -115,13 +114,20 @@ GLIBCXX_3.4 { std::locale::[A-Zg-h]*; std::locale::id::[A-Za-z]*; std::locale::id::_M_id*; - std::locale::[A-Zj-z]*; + std::locale::[A-Zj-m]*; +# std::locale::name(); + std::locale::none*; + std::locale::numeric*; + std::locale::[A-Zn-z]*; std::locale::_[A-Ha-z]*; std::locale::_Impl::[A-Za-z]*; # std::locale::_Impl::_M_[A-Za-z]*; std::locale::_[J-Ra-z]*; std::locale::_S_normalize_category*; std::locale::_[T-Za-z]*; +# std::logic_error::l*; + std::logic_error::what*; +# std::logic_error::~l*; # std::[A-Zm-r]*; # std::[A-Zm]*; std::[A-Z]*; @@ -133,16 +139,19 @@ GLIBCXX_3.4 { std::nu[^m]*; std::num[^e]*; std::ostrstream*; - std::out_of_range::o*; +# std::out_of_range::o*; # std::out_of_range::~o*; - std::overflow_error::o*; +# std::overflow_error::o*; # std::overflow_error::~o*; # std::[p-q]*; - std::r[^ae]*; - std::range_error::r*; + std::r[^aeu]*; +# std::range_error::r*; # std::range_error::~r*; # std::re[^t]*; # std::rethrow_exception +# std::runtime_error::r* + std::runtime_error::what*; +# std::runtime_error::~r*; std::set_new_handler*; std::set_terminate*; std::set_unexpected*; @@ -158,7 +167,7 @@ GLIBCXX_3.4 { std::tr1::h[^a]*; std::t[s-z]*; # std::[A-Zu-z]*; - std::underflow_error::u*; +# std::underflow_error::u*; # std::underflow_error::~u*; std::uncaught_exception*; std::unexpected*; @@ -337,19 +346,19 @@ GLIBCXX_3.4 { _ZNSt19basic_istringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]E[RS]*; _ZNSt19basic_istringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EED*; _ZNSt19basic_istringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EE3str*; - _ZNKSt19basic_istringstream*; + _ZNKSt19basic_istringstreamI*; # std::basic_ostringstream _ZNSt19basic_ostringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]E[RS]*; _ZNSt19basic_ostringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EED*; _ZNSt19basic_ostringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EE3str*; - _ZNKSt19basic_ostringstream*; + _ZNKSt19basic_ostringstreamI*; # std::basic_stringstream _ZNSt18basic_stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]E[RS]*; _ZNSt18basic_stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EED*; _ZNSt18basic_stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EE3str*; - _ZNKSt18basic_stringstream*; + _ZNKSt18basic_stringstreamI*; # std::basic_iostream constructors (except move), destructors _ZNSdC[12]Ev; @@ -447,10 +456,10 @@ GLIBCXX_3.4 { _ZNSt13basic_istreamIwSt11char_traitsIwEErsE*[^g]; # std::istream operators and extractors - _ZSt7getlineI[cw]St11char_traitsI[cw]ESaI[cw]EERSt13basic_istream*; + _ZSt7getlineI[cw]St11char_traitsI[cw]ESaI[cw]EERSt13basic_istreamIT_T0_ES7_RSbI*; _ZSt2wsI[cw]St11char_traitsI[cw]EE*; _ZStrsI[cw]St11char_traitsI[cw]EERSt13basic_istream*; - _ZStrsI[cw]St11char_traitsI[cw]ESaI[cw]EERSt13basic_istream*; + _ZStrsI[cw]St11char_traitsI[cw]ESaI[cw]EERSt13basic_istreamIT_T0_ES7_RSbI*; _ZStrsISt11char_traitsI[cw]EERSt13basic_istream*; _ZStrsId[cw]St11char_traitsI[cw]EERSt13basic_istream*; _ZStrsIe[cw]St11char_traitsI[cw]EERSt13basic_istream*; @@ -484,7 +493,7 @@ GLIBCXX_3.4 { _ZSt4end[ls]I[cw]St11char_traitsI[cw]EERSt13basic_ostream*; _ZSt5flushI[cw]St11char_traitsI[cw]EERSt13basic_ostream*; _ZStlsI[cw]St11char_traitsI[cw]EERSt13basic_ostream*; - _ZStlsI[cw]St11char_traitsI[cw]ESaI[cw]EERSt13basic_ostream*; + _ZStlsI[cw]St11char_traitsI[cw]ESaI[cw]EERSt13basic_ostreamIT_T0_ES7_RKSbI*; _ZStlsISt11char_traitsI[cw]EERSt13basic_ostream*; _ZStlsId[cw]St11char_traitsI[cw]EERSt13basic_ostream*; _ZStlsIe[cw]St11char_traitsI[cw]EERSt13basic_ostream*; @@ -493,6 +502,9 @@ GLIBCXX_3.4 { # std::locale destructors _ZNSt6localeD*; + # std::locale::name() returning old std::string + _ZNKSt6locale4nameEv; + # std::locale::facet destructors _ZNSt6locale5facetD*; @@ -529,16 +541,23 @@ GLIBCXX_3.4 { _ZNSt12ctype_bynameI[cw]*; # std::num_get - _ZNKSt7num_getI[cw]St19istreambuf_iteratorI[cw]St11char_traitsI[cw]EEE*; + _ZNKSt7num_getI[cw]St19istreambuf_iteratorI[cw]St11char_traitsI[cw]EEE[2-9]*; + _ZNKSt7num_getI[cw]St19istreambuf_iteratorI[cw]St11char_traitsI[cw]EEE14_M_extract_intI*; + _ZNKSt7num_getI[cw]St19istreambuf_iteratorI[cw]St11char_traitsI[cw]EEE16_M_extract_floatI*; # std::num_put - _ZNKSt7num_putI[cw]St19ostreambuf_iteratorI[cw]St11char_traitsI[cw]EEE*; + _ZNKSt7num_putI[cw]St19ostreambuf_iteratorI[cw]St11char_traitsI[cw]EEE[2-9]*; + _ZNKSt7num_putI[cw]St19ostreambuf_iteratorI[cw]St11char_traitsI[cw]EEE1[234]*; + _ZNKSt7num_putI[cw]St19ostreambuf_iteratorI[cw]St11char_traitsI[cw]EEE15_M_insert_floatI*; # std::money_get - _ZNKSt9money_getI[cw]St19istreambuf_iteratorI[cw]St11char_traitsI[cw]EEE*; + _ZNKSt9money_getI[cw]St19istreambuf_iteratorI[cw]St11char_traitsI[cw]EEE[2-9]*; + _ZNKSt9money_getI[cw]St19istreambuf_iteratorI[cw]St11char_traitsI[cw]EEE10_M_extractILb[01]EEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRSs; # std::money_put - _ZNKSt9money_putI[cw]St19ostreambuf_iteratorI[cw]St11char_traitsI[cw]EEE*; + _ZNKSt9money_putI[cw]St19ostreambuf_iteratorI[cw]St11char_traitsI[cw]EEE[1-8]*; + _ZNKSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE9_M_insertILb[01]EEES3_S3_RSt8ios_basecRKSs; + _ZNKSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE9_M_insertILb[01]EEES3_S3_RSt8ios_basewRKSbIwS2_SaIwEE; # std::time_get _ZNSt8time_get*; @@ -679,7 +698,13 @@ GLIBCXX_3.4 { _ZTVSt[0-9][0-9]a*; _ZTVSt10bad_typeid; _ZTVSt13bad_exception; - _ZTVSt[0-9][0-9]basic*; +# _ZTVSt[0-9][0-9]basic*; + _ZTVSt1[34]basic*; + _ZTVSt15basic_streambufI*; + _ZTVSt15basic_stringbufI*; + _ZTVSt18basic_stringstreamI*; + _ZTVSt19basic_istringstreamI*; + _ZTVSt19basic_ostringstreamI*; _ZTVSt[0-9][0-9][c-d]*; _ZTVSt[0-9][0-9][g-k]*; _ZTVSt11logic_error; @@ -701,7 +726,17 @@ GLIBCXX_3.4 { # VTT structure _ZTTS[a-z]; _ZTTSt[0-9][A-Za-z]*; - _ZTTSt[0-9][0-9][A-Za-z]*; +# _ZTTSt[0-9][0-9][A-Za-z]*; + _ZTTSt1[0-4]*; + _ZTTSt15a*; + _ZTTSt15basic_streambufI*; + _ZTTSt15basic_stringbufI*; + _ZTTSt15[c-z]*; + _ZTTSt1[67]*; + _ZTTSt18basic_stringstreamI*; + _ZTTSt19basic_istringstreamI*; + _ZTTSt19basic_ostringstreamI*; + _ZTTSt[2-9]*; # typeinfo structure _ZTIS[a-z]; @@ -712,7 +747,13 @@ GLIBCXX_3.4 { _ZTISt[0-9][0-9]a*; _ZTISt10bad_typeid; _ZTISt13bad_exception; - _ZTISt[0-9][0-9]basic*; +# _ZTISt[0-9][0-9]basic*; + _ZTISt1[34]basic*; + _ZTISt15basic_streambufI*; + _ZTISt15basic_stringbufI*; + _ZTISt18basic_stringstreamI*; + _ZTISt19basic_istringstreamI*; + _ZTISt19basic_ostringstreamI*; _ZTISt[0-9][0-9][c-d]*; _ZTISt[0-9][0-9][g-k]*; _ZTISt11logic_error; @@ -749,7 +790,13 @@ GLIBCXX_3.4 { _ZTSSt[0-9][0-9]a*; _ZTSSt10bad_typeid; _ZTSSt13bad_exception; - _ZTSSt[0-9][0-9]basic*; +# _ZTSSt[0-9][0-9]basic*; + _ZTSSt1[34]basic*; + _ZTSSt15basic_stringbufI*; + _ZTSSt15basic_streambufI*; + _ZTSSt18basic_stringstreamI*; + _ZTSSt19basic_istringstreamI*; + _ZTSSt19basic_ostringstreamI*; _ZTSSt[0-9][0-9][c-d]*; _ZTSSt[0-9][0-9][g-k]*; _ZTSSt11logic_error; @@ -779,8 +826,33 @@ GLIBCXX_3.4 { _ZNSt13bad_exceptionD*; # function-scope static objects requires a guard variable. - _ZGVNSt[^1]*; - _ZGVNSt1[^7]*; + _ZGVNSt[2-6]*; + _ZGVNSt7collateI[cw]*; + _ZGVNSt7num_getI[cw]*; + _ZGVNSt7num_putI[cw]*; + _ZGVNSt8messagesI[cw]*; + _ZGVNSt8numpunctI[cw]*; + _ZGVNSt8time_getI[cw]*; + _ZGVNSt8time_putI[cw]*; + _ZGVNSt9money_getI[cw]*; + _ZGVNSt9money_putI[cw]*; + _ZGVNSt1[^07]*; + _ZGVNSt10moneypunctI[cw]Lb[01]*; + + # exception constructors taking std::string + _ZNSt11logic_errorC[12]ERKSs; + _ZNSt13runtime_errorC[12]ERKSs; + _ZNSt11range_errorC[12]ERKSs; + _ZNSt12domain_errorC[12]ERKSs; + _ZNSt12length_errorC[12]ERKSs; + _ZNSt12out_of_rangeC[12]ERKSs; + _ZNSt14overflow_errorC[12]ERKSs; + _ZNSt15underflow_errorC[12]ERKSs; + _ZNSt16invalid_argumentC[12]ERKSs; + + # complete, deleting and base destructors + _ZNSt11logic_errorD[012]Ev; + _ZNSt13runtime_errorD[012]Ev; # complete and deleting destructors where base destructors should not # be exported. @@ -793,10 +865,42 @@ GLIBCXX_3.4 { _ZNSt16invalid_argumentD[01]Ev; # virtual function thunks - _ZThn8_NS*; - _ZThn16_NS*; - _ZTv0_n12_NS*; - _ZTv0_n24_NS*; +# _ZThn8_NS*; + _ZThn8_NS[dio]*; + _ZThn8_NSt1[0-9]a*; + _ZThn8_NSt1[34]basic*; + _ZThn8_NSt18basic_stringstreamI*; + _ZThn8_NSt19basic_[io]stringstreamI*; + _ZThn8_NSt1[0-9][c-z]*; + _ZThn8_NSt[2-9][a-z0-9]*; +# _ZThn16_NS*; + _ZThn16_NS[dio]*; + _ZThn16_NSt1[0-9]a*; + _ZThn16_NSt1[34]basic*; + _ZThn16_NSt18basic_stringstreamI*; + _ZThn16_NSt19basic_[io]stringstreamI*; + _ZThn16_NSt1[0-9][c-z]*; + _ZThn16_NSt[2-9][a-z0-9]*; +# _ZTv0_n12_NS*; + _ZTv0_n12_NS[dio]*; + _ZTv0_n12_NSt1[0-9]a*; + _ZTv0_n12_NSt1[34]basic*; + _ZTv0_n12_NSt15basic_streambufI*; + _ZTv0_n12_NSt15basic_stringbufI*; + _ZTv0_n12_NSt18basic_stringstreamI*; + _ZTv0_n12_NSt19basic_[io]stringstreamI*; + _ZTv0_n12_NSt1[0-9][c-z]*; + _ZTv0_n12_NSt[2-9][a-z0-9]*; +# _ZTv0_n24_NS*; + _ZTv0_n24_NS[dio]*; + _ZTv0_n24_NSt1[0-9]a*; + _ZTv0_n24_NSt1[34]basic*; + _ZTv0_n24_NSt15basic_streambufI*; + _ZTv0_n24_NSt15basic_stringbufI*; + _ZTv0_n24_NSt18basic_stringstreamI*; + _ZTv0_n24_NSt19basic_[io]stringstreamI*; + _ZTv0_n24_NSt1[0-9][c-z]*; + _ZTv0_n24_NSt[2-9][a-z0-9]*; # stub functions from libmath sinf; @@ -1034,7 +1138,7 @@ GLIBCXX_3.4.10 { _ZNKSt4hashISsEclESs; _ZNKSt4hashIeEclEe; - _ZSt17__verify_grouping*; + _ZSt17__verify_groupingPKc[mj]RKSs; _ZNSt8__detail12__prime_listE; _ZNSt3tr18__detail12__prime_listE; @@ -1390,10 +1494,15 @@ GLIBCXX_3.4.18 { # Names inside the 'extern' block are demangled names. extern "C++" { - std::random_device::*; std::__detail::_Prime_rehash_policy::*; }; + _ZNSt13random_device14_M_init_pretr1ERKSs; + _ZNSt13random_device16_M_getval_pretr1Ev; + _ZNSt13random_device7_M_finiEv; + _ZNSt13random_device7_M_initERKSs; + _ZNSt13random_device9_M_getvalEv; + # std::this_thread::__sleep_for _ZNSt11this_thread11__sleep_for*; @@ -1487,7 +1596,7 @@ GLIBCXX_3.4.21 { _ZNKSt8ios_base7failureB5cxx114whatEv; _ZNSt8ios_base7failureB5cxx11C[12]ERKSs; _ZNSt8ios_base7failureB5cxx11C[12]EPKcRKSt10error_code; - _ZNSt8ios_base7failureB5cxx11C[12]ERKSsB5cxx11; + _ZNSt8ios_base7failureB5cxx11C[12]ERKNSt7__cxx1112basic_string*; _ZNSt8ios_base7failureB5cxx11C[12]ERKSsB5cxx11RKSt10error_code; _ZNSt8ios_base7failureB5cxx11D[012]Ev; _ZTINSt8ios_base7failureB5cxx11E; @@ -1506,6 +1615,139 @@ GLIBCXX_3.4.21 { # std::__future_base::_State_baseV2::_Make_ready::_M_set() _ZNSt13__future_base13_State_baseV211_Make_ready6_M_setEv; + # ABI-tagged std::basic_string + _ZNSt7__cxx1112basic_string*; + _ZNKSt7__cxx1112basic_string*; + + # ABI-tagged stringstreams + _ZNSt7__cxx1115basic_stringbuf*; + _ZNSt7__cxx1118basic_stringstream*; + _ZNSt7__cxx1119basic_istringstream*; + _ZNSt7__cxx1119basic_ostringstream*; + _ZNKSt7__cxx1115basic_stringbuf*; + _ZNKSt7__cxx1118basic_stringstream*; + _ZNKSt7__cxx1119basic_istringstream*; + _ZNKSt7__cxx1119basic_ostringstream*; + _ZT[ISTV]NSt7__cxx1115basic_stringbuf*; + _ZT[ISTV]NSt7__cxx1118basic_stringstream*; + _ZT[ISTV]NSt7__cxx1119basic_istringstream*; + _ZT[ISTV]NSt7__cxx1119basic_ostringstream*; + _ZThn8_NSt7__cxx1118basic_stringstream*; + _ZThn16_NSt7__cxx1118basic_stringstream*; + _ZTv0_n12_NSt7__cxx1115basic_stringbuf*; + _ZTv0_n12_NSt7__cxx1118basic_stringstream*; + _ZTv0_n12_NSt7__cxx1119basic_istringstream*; + _ZTv0_n12_NSt7__cxx1119basic_ostringstream*; + _ZTv0_n24_NSt7__cxx1115basic_stringbuf*; + _ZTv0_n24_NSt7__cxx1118basic_stringstream*; + _ZTv0_n24_NSt7__cxx1119basic_istringstream*; + _ZTv0_n24_NSt7__cxx1119basic_ostringstream*; + + # I/O functions for ABI-tagged basic_string + _ZSt7getlineI[cw]St11char_traitsI[cw]ESaI[cw]EERSt13basic_istreamIT_T0_ES7_RNSt7__cxx1112basic_string*; + _ZStlsI[cw]St11char_traitsI[cw]ESaI[cw]EERSt13basic_ostreamIT_T0_ES7_RKNSt7__cxx1112basic_string*; + _ZStrsI[cw]St11char_traitsI[cw]ESaI[cw]EERSt13basic_istreamIT_T0_ES7_RNSt7__cxx1112basic_string*; + + # std::locale::name() returning new std::string + _ZNKSt6locale4nameB5cxx11Ev; + + # ABI-tagged locale facets + _ZT[ISTV]NSt7__cxx117collateI[cw]*; + _ZT[ISTV]NSt7__cxx1114collate_bynameI[cw]*; + _ZT[ISTV]NSt7__cxx118messagesI[cw]*; + _ZT[ISTV]NSt7__cxx1115messages_bynameI[cw]*; + _ZT[ISTV]NSt7__cxx119money_getI[cw]*; + _ZT[ISTV]NSt7__cxx119money_putI[cw]*; + _ZT[ISTV]NSt7__cxx1110moneypunctI[cw]Lb[01]*; + _ZT[ISTV]NSt7__cxx1117moneypunct_bynameI[cw]Lb[01]*; + _ZT[ISTV]NSt7__cxx118numpunctI[cw]*; + _ZT[ISTV]NSt7__cxx1115numpunct_bynameI[cw]*; + _ZT[ISTV]NSt7__cxx118time_getI[cw]*; + _ZT[ISTV]NSt7__cxx1115time_get_bynameI[cw]*; + + # guard vars for new facet::id globals + _ZGVNSt7__cxx117collateI[cw]*; + _ZGVNSt7__cxx118messagesI[cw]*; + _ZGVNSt7__cxx1110moneypunctI[cw]Lb[01]*; + _ZGVNSt7__cxx119money_getI[cw]*; + _ZGVNSt7__cxx119money_putI[cw]*; + _ZGVNSt7__cxx118numpunctI[cw]*; + _ZGVNSt7__cxx118time_getI[cw]*; + + _ZNSt7__cxx117collateI*; + _ZNSt7__cxx1114collate_bynameI*; + _ZNSt7__cxx118messagesI*; + _ZNSt7__cxx1115messages_bynameI*; + _ZNSt7__cxx119money_getI*; + _ZNSt7__cxx119money_putI*; + _ZNSt7__cxx1110moneypunctI*; + _ZNSt7__cxx1117moneypunct_bynameI*; + _ZNSt7__cxx118numpunctI*; + _ZNSt7__cxx1115numpunct_bynameI*; + _ZNSt7__cxx118time_getI*; + _ZNSt7__cxx1115time_get_bynameI*; + + _ZNKSt7__cxx117collateI*; + _ZNKSt7__cxx118messagesI*; + _ZNKSt7__cxx119money_getI*; + _ZNKSt7__cxx119money_putI*; + _ZNKSt7__cxx1110moneypunctI*; + _ZNKSt7__cxx118numpunctI*; + _ZNKSt7__cxx118time_getI*; + + _ZSt9has_facetINSt7__cxx117collate*; + _ZSt9has_facetINSt7__cxx118messages*; + _ZSt9has_facetINSt7__cxx119money_get*; + _ZSt9has_facetINSt7__cxx119money_put*; + _ZSt9has_facetINSt7__cxx1110moneypunct*; + _ZSt9has_facetINSt7__cxx118numpunct*; + _ZSt9has_facetINSt7__cxx118time_get*; + _ZSt9use_facetINSt7__cxx117collate*; + _ZSt9use_facetINSt7__cxx118messages*; + _ZSt9use_facetINSt7__cxx119money_get*; + _ZSt9use_facetINSt7__cxx119money_put*; + _ZSt9use_facetINSt7__cxx1110moneypunct*; + _ZSt9use_facetINSt7__cxx118numpunct*; + _ZSt9use_facetINSt7__cxx118time_get*; + + _ZSt17__verify_groupingPKc[mj]RKNSt7__cxx1112basic_string*; + + _ZNSt3_V214error_category*; + _ZNKSt3_V214error_category*; + _ZTVNSt3_V214error_categoryE; + _ZTINSt3_V214error_categoryE; + _ZNSt3_V215system_categoryEv; + _ZNSt3_V216generic_categoryEv; + + # New exception constructors + _ZNSt11logic_errorC[12]EPKc; + _ZNSt11logic_errorC[12]ERKS_; + _ZNSt11logic_erroraSERKS_; + _ZNSt11logic_errorC[12]ERKNSt7__cxx1112basic_string*; + _ZNSt11range_errorC[12]EPKc; + _ZNSt11range_errorC[12]ERKNSt7__cxx1112basic_string*; + _ZNSt12domain_errorC[12]EPKc; + _ZNSt12domain_errorC[12]ERKNSt7__cxx1112basic_string*; + _ZNSt12length_errorC[12]EPKc; + _ZNSt12length_errorC[12]ERKNSt7__cxx1112basic_string*; + _ZNSt12out_of_rangeC[12]EPKc; + _ZNSt12out_of_rangeC[12]ERKNSt7__cxx1112basic_string*; + _ZNSt13runtime_errorC[12]EPKc; + _ZNSt13runtime_errorC[12]ERKS_; + _ZNSt13runtime_erroraSERKS_; + _ZNSt13runtime_errorC[12]ERKNSt7__cxx1112basic_string*; + _ZNSt14overflow_errorC[12]EPKc; + _ZNSt14overflow_errorC[12]ERKNSt7__cxx1112basic_string*; + _ZNSt15underflow_errorC[12]EPKc; + _ZNSt15underflow_errorC[12]ERKNSt7__cxx1112basic_string*; + _ZNSt16invalid_argumentC[12]EPKc; + _ZNSt16invalid_argumentC[12]ERKNSt7__cxx1112basic_string*; + + _ZNSt13random_device14_M_init_pretr1ERKNSt7__cxx1112basic_string*; + _ZNSt13random_device7_M_initERKNSt7__cxx1112basic_string*; + + _ZNKSt3tr14hashINSt7__cxx1112basic_string*; + } GLIBCXX_3.4.20; diff --git a/libstdc++-v3/config/locale/generic/monetary_members.cc b/libstdc++-v3/config/locale/generic/monetary_members.cc index b4f27a4..20eabe1 100644 --- a/libstdc++-v3/config/locale/generic/monetary_members.cc +++ b/libstdc++-v3/config/locale/generic/monetary_members.cc @@ -34,11 +34,16 @@ namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION +// This file might be compiled twice, but we only want to define the members +// of money_base once. +#if ! _GLIBCXX_USE_CXX11_ABI + // Construct and return valid pattern consisting of some combination of: // space none symbol sign value money_base::pattern money_base::_S_construct_pattern(char, char, char) throw() { return _S_default_pattern; } +#endif template<> void diff --git a/libstdc++-v3/config/locale/gnu/monetary_members.cc b/libstdc++-v3/config/locale/gnu/monetary_members.cc index 25cdfd0..820ced2 100644 --- a/libstdc++-v3/config/locale/gnu/monetary_members.cc +++ b/libstdc++-v3/config/locale/gnu/monetary_members.cc @@ -35,6 +35,10 @@ namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION +// This file might be compiled twice, but we only want to define the members +// of money_base once. +#if ! _GLIBCXX_USE_CXX11_ABI + // Construct and return valid pattern consisting of some combination of: // space none symbol sign value money_base::pattern @@ -201,6 +205,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } return __ret; } +#endif template<> void diff --git a/libstdc++-v3/config/locale/gnu/numeric_members.cc b/libstdc++-v3/config/locale/gnu/numeric_members.cc index 8af7cf6..69ac176 100644 --- a/libstdc++-v3/config/locale/gnu/numeric_members.cc +++ b/libstdc++-v3/config/locale/gnu/numeric_members.cc @@ -117,6 +117,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { if (_M_data->_M_grouping_size) delete [] _M_data->_M_grouping; + _M_data->_M_grouping = 0; delete _M_data; } @@ -209,6 +210,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { if (_M_data->_M_grouping_size) delete [] _M_data->_M_grouping; + _M_data->_M_grouping = 0; delete _M_data; } #endif diff --git a/libstdc++-v3/config/os/gnu-linux/ldbl-extra.ver b/libstdc++-v3/config/os/gnu-linux/ldbl-extra.ver index 3dd0336..5ef4a6c 100644 --- a/libstdc++-v3/config/os/gnu-linux/ldbl-extra.ver +++ b/libstdc++-v3/config/os/gnu-linux/ldbl-extra.ver @@ -9,7 +9,17 @@ GLIBCXX_LDBL_3.4 { _ZSt14__convert_to_vIgEvPKcRT_RSt12_Ios_IostateRKP*; _ZStlsIg[cw]St11char_traitsI[cw]EERSt13basic_ostreamIT0_T1_ES6_RKSt7complexIT_E; _ZStrsIg[cw]St11char_traitsI[cw]EERSt13basic_istreamIT0_T1_ES6_RSt7complexIT_E; - *__gnu_cxx_ldbl128*; + *__gnu_cxx_ldbl128[1-6]*; + *St9has_facetINSt17__gnu_cxx_ldbl1287*; + *St9use_facetINSt17__gnu_cxx_ldbl1287*; + *__gnu_cxx_ldbl1287num_getI[cw]St19istreambuf_iteratorI[cw]St11char_traitsI[cw]EEE[CD][0-2]E?; + *__gnu_cxx_ldbl1287num_getI[cw]St19istreambuf_iteratorI[cw]St11char_traitsI[cw]EEE2idE; + *__gnu_cxx_ldbl1287num_getI[cw]St19istreambuf_iteratorI[cw]St11char_traitsI[cw]EEEE; + *__gnu_cxx_ldbl1287num_getI[cw]*getE*; + *__gnu_cxx_ldbl1287num_getI[cw]*14_M_extract_intI*; + *__gnu_cxx_ldbl1287num_getI[cw]*16_M_extract_floatE*; + *__gnu_cxx_ldbl1287num_putI[cw]*; + *__gnu_cxx_ldbl128[8-9]*; }; # Corresponding to exports in GLIBCXX_3.4.9, not GLIBCXX_3.4.7 @@ -25,6 +35,11 @@ GLIBCXX_LDBL_3.4.10 { _ZNKSt4hashIgEclEg; } GLIBCXX_LDBL_3.4.7; +GLIBCXX_LDBL_3.4.21 { + __gnu_cxx_ldbl1287num_getI[cw]*14_M_extract_intB5cxx11*; + __gnu_cxx_ldbl1287num_getI[cw]*16_M_extract_floatB5cxx11*; +} GLIBCXX_LDBL_3.4.10; + CXXABI_LDBL_1.3 { _ZT[IS]g; _ZT[IS]Pg; diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure index 3f8ecf1..be9337fc 100755 --- a/libstdc++-v3/configure +++ b/libstdc++-v3/configure @@ -645,6 +645,9 @@ GLIBCXX_LDBL_COMPAT_FALSE GLIBCXX_LDBL_COMPAT_TRUE ENABLE_CXX11_ABI_FALSE ENABLE_CXX11_ABI_TRUE +glibcxx_cxx98_abi +ENABLE_DUAL_ABI_FALSE +ENABLE_DUAL_ABI_TRUE ENABLE_VISIBILITY_FALSE ENABLE_VISIBILITY_TRUE libtool_VERSION @@ -882,7 +885,8 @@ with_system_libunwind enable_linux_futex enable_symvers enable_libstdcxx_visibility -enable_libstdcxx_cxx11_abi +enable_libstdcxx_dual_abi +with_default_libstdcxx_abi enable_libstdcxx_threads with_gxx_include_dir enable_version_specific_runtime_libs @@ -1578,8 +1582,8 @@ Optional Features: [default=yes] --enable-libstdcxx-visibility enables visibility safe usage [default=yes] - --disable-libstdcxx-cxx11-abi - disable the C++11-conforming ABI + --enable-libstdcxx-dual-abi + support two versions of std::string [default=yes] --enable-libstdcxx-threads enable C++11 threads support [default=auto] --enable-version-specific-runtime-libs @@ -1602,6 +1606,8 @@ Optional Packages: --with-libiconv-prefix[=DIR] search for libiconv in DIR/include and DIR/lib --without-libiconv-prefix don't search for libiconv in includedir and libdir --with-system-libunwind use installed libunwind + --with-default-libstdcxx-abi + set the std::string ABI to use by default --with-gxx-include-dir=DIR installation directory for include files @@ -11531,7 +11537,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11534 "configure" +#line 11540 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11637,7 +11643,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11640 "configure" +#line 11646 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -15057,7 +15063,7 @@ fi # # Fake what AC_TRY_COMPILE does. XXX Look at redoing this new-style. cat > conftest.$ac_ext << EOF -#line 15060 "configure" +#line 15066 "configure" struct S { ~S(); }; void bar(); void foo() @@ -15409,7 +15415,7 @@ $as_echo "$glibcxx_cv_atomic_long_long" >&6; } # Fake what AC_TRY_COMPILE does. cat > conftest.$ac_ext << EOF -#line 15412 "configure" +#line 15418 "configure" int main() { typedef bool atomic_type; @@ -15444,7 +15450,7 @@ $as_echo "$glibcxx_cv_atomic_bool" >&6; } rm -f conftest* cat > conftest.$ac_ext << EOF -#line 15447 "configure" +#line 15453 "configure" int main() { typedef short atomic_type; @@ -15479,7 +15485,7 @@ $as_echo "$glibcxx_cv_atomic_short" >&6; } rm -f conftest* cat > conftest.$ac_ext << EOF -#line 15482 "configure" +#line 15488 "configure" int main() { // NB: _Atomic_word not necessarily int. @@ -15515,7 +15521,7 @@ $as_echo "$glibcxx_cv_atomic_int" >&6; } rm -f conftest* cat > conftest.$ac_ext << EOF -#line 15518 "configure" +#line 15524 "configure" int main() { typedef long long atomic_type; @@ -15594,7 +15600,7 @@ $as_echo "$as_me: WARNING: Performance of certain classes will degrade as a resu # unnecessary for this test. cat > conftest.$ac_ext << EOF -#line 15597 "configure" +#line 15603 "configure" int main() { _Decimal32 d1; @@ -15636,7 +15642,7 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu # unnecessary for this test. cat > conftest.$ac_ext << EOF -#line 15639 "configure" +#line 15645 "configure" template<typename T1, typename T2> struct same { typedef T2 type; }; @@ -15670,7 +15676,7 @@ $as_echo "$enable_int128" >&6; } rm -f conftest* cat > conftest.$ac_ext << EOF -#line 15673 "configure" +#line 15679 "configure" template<typename T1, typename T2> struct same { typedef T2 type; }; @@ -78166,20 +78172,56 @@ $as_echo "$as_me: visibility supported: $enable_libstdcxx_visibility" >&6;} - # Check whether --enable-libstdcxx-cxx11-abi was given. -if test "${enable_libstdcxx_cxx11_abi+set}" = set; then : - enableval=$enable_libstdcxx_cxx11_abi; + # Check whether --enable-libstdcxx-dual-abi was given. +if test "${enable_libstdcxx_dual_abi+set}" = set; then : + enableval=$enable_libstdcxx_dual_abi; + case "$enableval" in + yes|no) ;; + *) as_fn_error "Argument to enable/disable libstdcxx-dual-abi must be yes or no" "$LINENO" 5 ;; + esac + else - enable_libstdcxx_cxx11_abi=yes + enable_libstdcxx_dual_abi=yes fi - if test x"$enable_libstdcxx_cxx11_abi" != xyes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: C++11-conforming ABI is disabled" >&5 -$as_echo "$as_me: C++11-conforming ABI is disabled" >&6;} + + if test x"$enable_libstdcxx_dual_abi" != xyes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: dual ABI is disabled" >&5 +$as_echo "$as_me: dual ABI is disabled" >&6;} + default_libstdcxx_abi="c++98" fi + if test x$enable_libstdcxx_dual_abi = xyes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for default std::string ABI to use" >&5 +$as_echo_n "checking for default std::string ABI to use... " >&6; } + +# Check whether --with-default-libstdcxx-abi was given. +if test "${with_default_libstdcxx_abi+set}" = set; then : + withval=$with_default_libstdcxx_abi; case "$withval" in + c++98|gnu++98|c++03|gnu++03) default_libstdcxx_abi="c++98" ;; + c++1?|gnu++1?) default_libstdcxx_abi="c++11" ;; + *) as_fn_error "Invalid argument for --with-default-libstdcxx-abi" "$LINENO" 5 ;; + esac +else + default_libstdcxx_abi="c++11" +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${default_libstdcxx_abi}" >&5 +$as_echo "${default_libstdcxx_abi}" >&6; } + fi + if test $default_libstdcxx_abi = "c++11"; then + glibcxx_cxx11_abi=1 + glibcxx_cxx98_abi=0 + else + glibcxx_cxx11_abi=0 + glibcxx_cxx98_abi=1 + fi + + + + ac_ldbl_compat=no case "$target" in powerpc*-*-linux* | \ @@ -79332,7 +79374,16 @@ else fi - if test $enable_libstdcxx_cxx11_abi = yes; then + if test $enable_libstdcxx_dual_abi = yes; then + ENABLE_DUAL_ABI_TRUE= + ENABLE_DUAL_ABI_FALSE='#' +else + ENABLE_DUAL_ABI_TRUE='#' + ENABLE_DUAL_ABI_FALSE= +fi + + + if test $glibcxx_cxx11_abi = 1; then ENABLE_CXX11_ABI_TRUE= ENABLE_CXX11_ABI_FALSE='#' else @@ -79758,6 +79809,10 @@ if test -z "${ENABLE_VISIBILITY_TRUE}" && test -z "${ENABLE_VISIBILITY_FALSE}"; as_fn_error "conditional \"ENABLE_VISIBILITY\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${ENABLE_DUAL_ABI_TRUE}" && test -z "${ENABLE_DUAL_ABI_FALSE}"; then + as_fn_error "conditional \"ENABLE_DUAL_ABI\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${ENABLE_CXX11_ABI_TRUE}" && test -z "${ENABLE_CXX11_ABI_FALSE}"; then as_fn_error "conditional \"ENABLE_CXX11_ABI\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 diff --git a/libstdc++-v3/configure.ac b/libstdc++-v3/configure.ac index 135d536..7a7c1d8 100644 --- a/libstdc++-v3/configure.ac +++ b/libstdc++-v3/configure.ac @@ -368,7 +368,8 @@ AC_SUBST(libtool_VERSION) GLIBCXX_ENABLE_LIBSTDCXX_VISIBILITY([yes]) -GLIBCXX_ENABLE_LIBSTDCXX_CXX11_ABI([yes]) +GLIBCXX_ENABLE_LIBSTDCXX_DUAL_ABI([yes]) +GLIBCXX_DEFAULT_ABI ac_ldbl_compat=no case "$target" in diff --git a/libstdc++-v3/doc/Makefile.in b/libstdc++-v3/doc/Makefile.in index 85f6e3f..d1f0500 100644 --- a/libstdc++-v3/doc/Makefile.in +++ b/libstdc++-v3/doc/Makefile.in @@ -218,6 +218,7 @@ glibcxx_POFILES = @glibcxx_POFILES@ glibcxx_builddir = @glibcxx_builddir@ glibcxx_compiler_pic_flag = @glibcxx_compiler_pic_flag@ glibcxx_compiler_shared_flag = @glibcxx_compiler_shared_flag@ +glibcxx_cxx98_abi = @glibcxx_cxx98_abi@ glibcxx_localedir = @glibcxx_localedir@ glibcxx_lt_pic_flag = @glibcxx_lt_pic_flag@ glibcxx_prefixdir = @glibcxx_prefixdir@ diff --git a/libstdc++-v3/doc/html/manual/configure.html b/libstdc++-v3/doc/html/manual/configure.html index e1ca43c..6453f08 100644 --- a/libstdc++-v3/doc/html/manual/configure.html +++ b/libstdc++-v3/doc/html/manual/configure.html @@ -227,6 +227,15 @@ facilities, which might be undesirable in a low-memory environment or when standard error is not available. This option disables those messages. This option does not change the library ABI. + </p></dd><dt><span class="term"><code class="code">--disable-libstdcxx-dual-abi</code></span></dt><dd><p> + Disable support for the new, C++11-conforming <code class="code">std::string</code> + implementation. This option changes the library ABI. + </p></dd><dt><span class="term"><code class="code">--with-default-libstdcxx-abi</code></span></dt><dd><p> + By default, the new <code class="code">std::string</code> implementation will be + declared and a macro must be defined to declare the old implementation + instead. That default can be reversed by configuring the library with + <code class="code">--with-default-libstdcxx-abi=c++98</code>. + This option does not change the library ABI. </p></dd><dt><span class="term"><code class="code">--enable-vtable-verify</code>[default]</span></dt><dd><p>Use <code class="code">-fvtable-verify=std</code> to compile the C++ runtime with instrumentation for vtable verification. All virtual functions in the standard library will be verified at runtime. diff --git a/libstdc++-v3/doc/html/manual/using_exceptions.html b/libstdc++-v3/doc/html/manual/using_exceptions.html index f1dd099..00e9d38 100644 --- a/libstdc++-v3/doc/html/manual/using_exceptions.html +++ b/libstdc++-v3/doc/html/manual/using_exceptions.html @@ -310,4 +310,4 @@ is called. <a class="link" href="http://gcc.gnu.org/PR25191" target="_top"> GCC Bug 25191: exception_defines.h #defines try/catch </a> - </em>. </span></p></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="using_concurrency.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="using.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="debug.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Concurrency </td><td width="20%" align="center"><a accesskey="h" href="../index.html">Home</a></td><td width="40%" align="right" valign="top"> Debugging Support</td></tr></table></div></body></html> + </em>. </span></p></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="using_concurrency.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="using.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="debug.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Concurrency </td><td width="20%" align="center"><a accesskey="h" href="../index.html">Home</a></td><td width="40%" align="right" valign="top"> Debugging Support</td></tr></table></div></body></html>
\ No newline at end of file diff --git a/libstdc++-v3/doc/xml/manual/configure.xml b/libstdc++-v3/doc/xml/manual/configure.xml index 717cca7..a6e0c21 100644 --- a/libstdc++-v3/doc/xml/manual/configure.xml +++ b/libstdc++-v3/doc/xml/manual/configure.xml @@ -382,6 +382,25 @@ </para> </listitem></varlistentry> +<varlistentry><term><code>--disable-libstdcxx-dual-abi</code></term> + <listitem> + <para> + Disable support for the new, C++11-conforming <code>std::string</code> + implementation. This option changes the library ABI. + </para> + </listitem></varlistentry> + +<varlistentry><term><code>--with-default-libstdcxx-abi</code></term> + <listitem> + <para> + By default, the new <code>std::string</code> implementation will be + declared and a macro must be defined to declare the old implementation + instead. That default can be reversed by configuring the library with + <code>--with-default-libstdcxx-abi=c++98</code>. + This option does not change the library ABI. + </para> + </listitem></varlistentry> + <varlistentry><term><code>--enable-vtable-verify</code>[default]</term> <listitem> <para>Use <code>-fvtable-verify=std</code> to compile the C++ diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am index e6edc73..2594d76 100644 --- a/libstdc++-v3/include/Makefile.am +++ b/libstdc++-v3/include/Makefile.am @@ -1129,6 +1129,14 @@ stamp-visibility: echo 0 > stamp-visibility endif +if ENABLE_DUAL_ABI +stamp-dual-abi: + echo 1 > stamp-dual-abi +else +stamp-dual-abi: + echo 0 > stamp-dual-abi +endif + if ENABLE_CXX11_ABI stamp-cxx11-abi: echo 1 > stamp-cxx11-abi @@ -1146,11 +1154,13 @@ ${host_builddir}/c++config.h: ${CONFIG_HEADER} \ stamp-namespace-version \ stamp-visibility \ stamp-extern-template \ + stamp-dual-abi \ stamp-cxx11-abi @date=`cat ${toplevel_srcdir}/gcc/DATESTAMP` ;\ ns_version=`cat stamp-namespace-version` ;\ visibility=`cat stamp-visibility` ;\ externtemplate=`cat stamp-extern-template` ;\ + dualabi=`cat stamp-dual-abi` ;\ cxx11abi=`cat stamp-cxx11-abi` ;\ ldbl_compat='s,g,g,' ;\ grep "^[ ]*#[ ]*define[ ][ ]*_GLIBCXX_LONG_DOUBLE_COMPAT[ ][ ]*1[ ]*$$" \ @@ -1160,6 +1170,7 @@ ${host_builddir}/c++config.h: ${CONFIG_HEADER} \ -e "s,define _GLIBCXX_INLINE_VERSION, define _GLIBCXX_INLINE_VERSION $$ns_version," \ -e "s,define _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY, define _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY $$visibility," \ -e "s,define _GLIBCXX_EXTERN_TEMPLATE$$, define _GLIBCXX_EXTERN_TEMPLATE $$externtemplate," \ + -e "s,define _GLIBCXX_USE_DUAL_ABI, define _GLIBCXX_USE_DUAL_ABI $$dualabi," \ -e "s,define _GLIBCXX_USE_CXX11_ABI, define _GLIBCXX_USE_CXX11_ABI $$cxx11abi," \ -e "$$ldbl_compat" \ < ${glibcxx_srcdir}/include/bits/c++config > $@ ;\ diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in index 2ade448..3e5d82e 100644 --- a/libstdc++-v3/include/Makefile.in +++ b/libstdc++-v3/include/Makefile.in @@ -216,6 +216,7 @@ glibcxx_POFILES = @glibcxx_POFILES@ glibcxx_builddir = @glibcxx_builddir@ glibcxx_compiler_pic_flag = @glibcxx_compiler_pic_flag@ glibcxx_compiler_shared_flag = @glibcxx_compiler_shared_flag@ +glibcxx_cxx98_abi = @glibcxx_cxx98_abi@ glibcxx_localedir = @glibcxx_localedir@ glibcxx_lt_pic_flag = @glibcxx_lt_pic_flag@ glibcxx_prefixdir = @glibcxx_prefixdir@ @@ -1539,6 +1540,11 @@ stamp-host: ${host_headers} ${bits_host_headers} ${ext_host_headers} ${host_head @ENABLE_VISIBILITY_FALSE@stamp-visibility: @ENABLE_VISIBILITY_FALSE@ echo 0 > stamp-visibility +@ENABLE_DUAL_ABI_TRUE@stamp-dual-abi: +@ENABLE_DUAL_ABI_TRUE@ echo 1 > stamp-dual-abi +@ENABLE_DUAL_ABI_FALSE@stamp-dual-abi: +@ENABLE_DUAL_ABI_FALSE@ echo 0 > stamp-dual-abi + @ENABLE_CXX11_ABI_TRUE@stamp-cxx11-abi: @ENABLE_CXX11_ABI_TRUE@ echo 1 > stamp-cxx11-abi @ENABLE_CXX11_ABI_FALSE@stamp-cxx11-abi: @@ -1553,11 +1559,13 @@ ${host_builddir}/c++config.h: ${CONFIG_HEADER} \ stamp-namespace-version \ stamp-visibility \ stamp-extern-template \ + stamp-dual-abi \ stamp-cxx11-abi @date=`cat ${toplevel_srcdir}/gcc/DATESTAMP` ;\ ns_version=`cat stamp-namespace-version` ;\ visibility=`cat stamp-visibility` ;\ externtemplate=`cat stamp-extern-template` ;\ + dualabi=`cat stamp-dual-abi` ;\ cxx11abi=`cat stamp-cxx11-abi` ;\ ldbl_compat='s,g,g,' ;\ grep "^[ ]*#[ ]*define[ ][ ]*_GLIBCXX_LONG_DOUBLE_COMPAT[ ][ ]*1[ ]*$$" \ @@ -1567,6 +1575,7 @@ ${host_builddir}/c++config.h: ${CONFIG_HEADER} \ -e "s,define _GLIBCXX_INLINE_VERSION, define _GLIBCXX_INLINE_VERSION $$ns_version," \ -e "s,define _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY, define _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY $$visibility," \ -e "s,define _GLIBCXX_EXTERN_TEMPLATE$$, define _GLIBCXX_EXTERN_TEMPLATE $$externtemplate," \ + -e "s,define _GLIBCXX_USE_DUAL_ABI, define _GLIBCXX_USE_DUAL_ABI $$dualabi," \ -e "s,define _GLIBCXX_USE_CXX11_ABI, define _GLIBCXX_USE_CXX11_ABI $$cxx11abi," \ -e "$$ldbl_compat" \ < ${glibcxx_srcdir}/include/bits/c++config > $@ ;\ diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h index 8918965..7729384 100644 --- a/libstdc++-v3/include/bits/basic_string.h +++ b/libstdc++-v3/include/bits/basic_string.h @@ -37,6 +37,7 @@ #pragma GCC system_header #include <ext/atomicity.h> +#include <ext/alloc_traits.h> #include <debug/debug.h> #if __cplusplus >= 201103L #include <initializer_list> @@ -46,6 +47,2399 @@ namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION +#if _GLIBCXX_USE_CXX11_ABI +_GLIBCXX_BEGIN_NAMESPACE_CXX11 + /** + * @class basic_string basic_string.h <string> + * @brief Managing sequences of characters and character-like objects. + * + * @ingroup strings + * @ingroup sequences + * + * @tparam _CharT Type of character + * @tparam _Traits Traits for character type, defaults to + * char_traits<_CharT>. + * @tparam _Alloc Allocator type, defaults to allocator<_CharT>. + * + * Meets the requirements of a <a href="tables.html#65">container</a>, a + * <a href="tables.html#66">reversible container</a>, and a + * <a href="tables.html#67">sequence</a>. Of the + * <a href="tables.html#68">optional sequence requirements</a>, only + * @c push_back, @c at, and @c %array access are supported. + */ + template<typename _CharT, typename _Traits, typename _Alloc> + class basic_string + { + typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template + rebind<_CharT>::other _Char_alloc_type; + typedef __gnu_cxx::__alloc_traits<_Char_alloc_type> _Alloc_traits; + + // Types: + public: + typedef _Traits traits_type; + typedef typename _Traits::char_type value_type; + typedef _Char_alloc_type allocator_type; + typedef typename _Alloc_traits::size_type size_type; + typedef typename _Alloc_traits::difference_type difference_type; + typedef typename _Alloc_traits::reference reference; + typedef typename _Alloc_traits::const_reference const_reference; + typedef typename _Alloc_traits::pointer pointer; + typedef typename _Alloc_traits::const_pointer const_pointer; + typedef __gnu_cxx::__normal_iterator<pointer, basic_string> iterator; + typedef __gnu_cxx::__normal_iterator<const_pointer, basic_string> + const_iterator; + typedef std::reverse_iterator<const_iterator> const_reverse_iterator; + typedef std::reverse_iterator<iterator> reverse_iterator; + + /// Value returned by various member functions when they fail. + static const size_type npos = static_cast<size_type>(-1); + + private: + // type used for positions in insert, erase etc. +#if __cplusplus < 201103L + typedef iterator __const_iterator; +#else + typedef const_iterator __const_iterator; +#endif + + // Use empty-base optimization: http://www.cantrip.org/emptyopt.html + struct _Alloc_hider : allocator_type // TODO check __is_final + { + _Alloc_hider(pointer __dat, const _Alloc& __a = _Alloc()) + : allocator_type(__a), _M_p(__dat) { } + + pointer _M_p; // The actual data. + }; + + _Alloc_hider _M_dataplus; + size_type _M_string_length; + + enum { _S_local_capacity = 16 / sizeof(_CharT) - 1 }; + + union + { + _CharT _M_local_buf[_S_local_capacity + 1]; + size_type _M_allocated_capacity; + }; + + void + _M_data(pointer __p) + { _M_dataplus._M_p = __p; } + + void + _M_length(size_type __length) + { _M_string_length = __length; } + + pointer + _M_data() const + { return _M_dataplus._M_p; } + + pointer + _M_local_data() + { +#if __cplusplus >= 201103L + return std::pointer_traits<pointer>::pointer_to(*_M_local_buf); +#else + return pointer(_M_local_buf); +#endif + } + + const_pointer + _M_local_data() const + { +#if __cplusplus >= 201103L + return std::pointer_traits<const_pointer>::pointer_to(*_M_local_buf); +#else + return const_pointer(_M_local_buf); +#endif + } + + void + _M_capacity(size_type __capacity) + { _M_allocated_capacity = __capacity; } + + void + _M_set_length(size_type __n) + { + _M_length(__n); + traits_type::assign(_M_data()[__n], _CharT()); + } + + bool + _M_is_local() const + { return _M_data() == _M_local_data(); } + + // Create & Destroy + pointer + _M_create(size_type&, size_type); + + void + _M_dispose() + { + if (!_M_is_local()) + _M_destroy(_M_allocated_capacity); + } + + void + _M_destroy(size_type __size) throw() + { _Alloc_traits::deallocate(_M_get_allocator(), _M_data(), __size + 1); } + + // _M_construct_aux is used to implement the 21.3.1 para 15 which + // requires special behaviour if _InIterator is an integral type + template<typename _InIterator> + void + _M_construct_aux(_InIterator __beg, _InIterator __end, + std::__false_type) + { + typedef typename iterator_traits<_InIterator>::iterator_category _Tag; + _M_construct(__beg, __end, _Tag()); + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 438. Ambiguity in the "do the right thing" clause + template<typename _Integer> + void + _M_construct_aux(_Integer __beg, _Integer __end, std::__true_type) + { _M_construct_aux_2(static_cast<size_type>(__beg), __end); } + + void + _M_construct_aux_2(size_type __req, _CharT __c) + { _M_construct(__req, __c); } + + template<typename _InIterator> + void + _M_construct(_InIterator __beg, _InIterator __end) + { + typedef typename std::__is_integer<_InIterator>::__type _Integral; + _M_construct_aux(__beg, __end, _Integral()); + } + + // For Input Iterators, used in istreambuf_iterators, etc. + template<typename _InIterator> + void + _M_construct(_InIterator __beg, _InIterator __end, + std::input_iterator_tag); + + // For forward_iterators up to random_access_iterators, used for + // string::iterator, _CharT*, etc. + template<typename _FwdIterator> + void + _M_construct(_FwdIterator __beg, _FwdIterator __end, + std::forward_iterator_tag); + + void + _M_construct(size_type __req, _CharT __c); + + allocator_type& + _M_get_allocator() + { return _M_dataplus; } + + const allocator_type& + _M_get_allocator() const + { return _M_dataplus; } + + private: + +#ifdef _GLIBCXX_DISAMBIGUATE_REPLACE_INST + // The explicit instantiations in misc-inst.cc require this due to + // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64063 + template<typename _Tp, bool _Requires = + !__are_same<_Tp, _CharT*>::__value + && !__are_same<_Tp, const _CharT*>::__value + && !__are_same<_Tp, iterator>::__value + && !__are_same<_Tp, const_iterator>::__value> + struct __enable_if_not_native_iterator + { typedef basic_string& __type; }; + template<typename _Tp> + struct __enable_if_not_native_iterator<_Tp, false> { }; +#endif + + size_type + _M_check(size_type __pos, const char* __s) const + { + if (__pos > this->size()) + __throw_out_of_range_fmt(__N("%s: __pos (which is %zu) > " + "this->size() (which is %zu)"), + __s, __pos, this->size()); + return __pos; + } + + void + _M_check_length(size_type __n1, size_type __n2, const char* __s) const + { + if (this->max_size() - (this->size() - __n1) < __n2) + __throw_length_error(__N(__s)); + } + + + // NB: _M_limit doesn't check for a bad __pos value. + size_type + _M_limit(size_type __pos, size_type __off) const _GLIBCXX_NOEXCEPT + { + const bool __testoff = __off < this->size() - __pos; + return __testoff ? __off : this->size() - __pos; + } + + // True if _Rep and source do not overlap. + bool + _M_disjunct(const _CharT* __s) const _GLIBCXX_NOEXCEPT + { + return (less<const _CharT*>()(__s, _M_data()) + || less<const _CharT*>()(_M_data() + this->size(), __s)); + } + + // When __n = 1 way faster than the general multichar + // traits_type::copy/move/assign. + static void + _S_copy(_CharT* __d, const _CharT* __s, size_type __n) + { + if (__n == 1) + traits_type::assign(*__d, *__s); + else + traits_type::copy(__d, __s, __n); + } + + static void + _S_move(_CharT* __d, const _CharT* __s, size_type __n) + { + if (__n == 1) + traits_type::assign(*__d, *__s); + else + traits_type::move(__d, __s, __n); + } + + static void + _S_assign(_CharT* __d, size_type __n, _CharT __c) + { + if (__n == 1) + traits_type::assign(*__d, __c); + else + traits_type::assign(__d, __n, __c); + } + + // _S_copy_chars is a separate template to permit specialization + // to optimize for the common case of pointers as iterators. + template<class _Iterator> + static void + _S_copy_chars(_CharT* __p, _Iterator __k1, _Iterator __k2) + _GLIBCXX_NOEXCEPT + { + for (; __k1 != __k2; ++__k1, ++__p) + traits_type::assign(*__p, *__k1); // These types are off. + } + + static void + _S_copy_chars(_CharT* __p, iterator __k1, iterator __k2) _GLIBCXX_NOEXCEPT + { _S_copy_chars(__p, __k1.base(), __k2.base()); } + + static void + _S_copy_chars(_CharT* __p, const_iterator __k1, const_iterator __k2) + _GLIBCXX_NOEXCEPT + { _S_copy_chars(__p, __k1.base(), __k2.base()); } + + static void + _S_copy_chars(_CharT* __p, _CharT* __k1, _CharT* __k2) _GLIBCXX_NOEXCEPT + { _S_copy(__p, __k1, __k2 - __k1); } + + static void + _S_copy_chars(_CharT* __p, const _CharT* __k1, const _CharT* __k2) + _GLIBCXX_NOEXCEPT + { _S_copy(__p, __k1, __k2 - __k1); } + + static int + _S_compare(size_type __n1, size_type __n2) _GLIBCXX_NOEXCEPT + { + const difference_type __d = difference_type(__n1 - __n2); + + if (__d > __gnu_cxx::__numeric_traits<int>::__max) + return __gnu_cxx::__numeric_traits<int>::__max; + else if (__d < __gnu_cxx::__numeric_traits<int>::__min) + return __gnu_cxx::__numeric_traits<int>::__min; + else + return int(__d); + } + + void + _M_assign(const basic_string& __rcs); + + void + _M_mutate(size_type __pos, size_type __len1, const _CharT* __s, + size_type __len2); + + void + _M_erase(size_type __pos, size_type __n); + + public: + // Construct/copy/destroy: + // NB: We overload ctors in some cases instead of using default + // arguments, per 17.4.4.4 para. 2 item 2. + + /** + * @brief Default constructor creates an empty string. + */ + basic_string() _GLIBCXX_NOEXCEPT + : _M_dataplus(_M_local_data()) + { _M_set_length(0); } + + /** + * @brief Construct an empty string using allocator @a a. + */ + explicit + basic_string(const _Alloc& __a) + : _M_dataplus(_M_local_data(), __a) + { _M_set_length(0); } + + /** + * @brief Construct string with copy of value of @a __str. + * @param __str Source string. + */ + basic_string(const basic_string& __str) + : _M_dataplus(_M_local_data(), __str._M_get_allocator()) // TODO A traits + { _M_construct(__str._M_data(), __str._M_data() + __str.length()); } + + /** + * @brief Construct string as copy of a substring. + * @param __str Source string. + * @param __pos Index of first character to copy from. + * @param __n Number of characters to copy (default remainder). + */ + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2402. [this constructor] shouldn't use Allocator() + basic_string(const basic_string& __str, size_type __pos, + size_type __n = npos) + : _M_dataplus(_M_local_data()) + { + const _CharT* __start = __str._M_data() + + __str._M_check(__pos, "basic_string::basic_string"); + _M_construct(__start, __start + __str._M_limit(__pos, __n)); + } + + /** + * @brief Construct string as copy of a substring. + * @param __str Source string. + * @param __pos Index of first character to copy from. + * @param __n Number of characters to copy (default remainder). + * @param __a Allocator to use. + */ + basic_string(const basic_string& __str, size_type __pos, + size_type __n, const _Alloc& __a) + : _M_dataplus(_M_local_data(), __a) + { + const _CharT* __start + = __str._M_data() + __str._M_check(__pos, "string::string"); + _M_construct(__start, __start + __str._M_limit(__pos, __n)); + } + + /** + * @brief Construct string initialized by a character %array. + * @param __s Source character %array. + * @param __n Number of characters to copy. + * @param __a Allocator to use (default is default allocator). + * + * NB: @a __s must have at least @a __n characters, '\\0' + * has no special meaning. + */ + basic_string(const _CharT* __s, size_type __n, + const _Alloc& __a = _Alloc()) + : _M_dataplus(_M_local_data(), __a) + { _M_construct(__s, __s + __n); } + + /** + * @brief Construct string as copy of a C string. + * @param __s Source C string. + * @param __a Allocator to use (default is default allocator). + */ + basic_string(const _CharT* __s, const _Alloc& __a = _Alloc()) + : _M_dataplus(_M_local_data(), __a) + { _M_construct(__s, __s ? __s + traits_type::length(__s) : __s+npos); } + + /** + * @brief Construct string as multiple characters. + * @param __n Number of characters. + * @param __c Character to use. + * @param __a Allocator to use (default is default allocator). + */ + basic_string(size_type __n, _CharT __c, const _Alloc& __a = _Alloc()) + : _M_dataplus(_M_local_data(), __a) + { _M_construct(__n, __c); } + +#if __cplusplus >= 201103L + /** + * @brief Move construct string. + * @param __str Source string. + * + * The newly-created string contains the exact contents of @a __str. + * @a __str is a valid, but unspecified string. + **/ + basic_string(basic_string&& __str) noexcept + : _M_dataplus(_M_local_data(), std::move(__str._M_get_allocator())) + { + if (__str._M_is_local()) + { + if (__str.length()) + traits_type::copy(_M_local_buf, __str._M_local_buf, + _S_local_capacity + 1); + } + else + { + _M_data(__str._M_data()); + _M_capacity(__str._M_allocated_capacity); + } + + // Must use _M_length() here not _M_set_length() because + // basic_stringbuf relies on writing into unallocated capacity so + // we mess up the contents if we put a '\0' in the string. + _M_length(__str.length()); + __str._M_data(__str._M_local_data()); + __str._M_set_length(0); + } + + /** + * @brief Construct string from an initializer %list. + * @param __l std::initializer_list of characters. + * @param __a Allocator to use (default is default allocator). + */ + basic_string(initializer_list<_CharT> __l, const _Alloc& __a = _Alloc()) + : _M_dataplus(_M_local_data(), __a) + { _M_construct(__l.begin(), __l.end()); } + + basic_string(const basic_string& __str, const _Alloc& __a) + : _M_dataplus(_M_local_data(), __a) + { _M_construct(__str.begin(), __str.end()); } + + basic_string(basic_string&& __str, const _Alloc& __a) + : _M_dataplus(_M_local_data(), __a) + { + if (__str.get_allocator() == __a) + *this = std::move(__str); + else + _M_construct(__str.begin(), __str.end()); + } + +#endif // C++11 + + /** + * @brief Construct string as copy of a range. + * @param __beg Start of range. + * @param __end End of range. + * @param __a Allocator to use (default is default allocator). + */ +#if __cplusplus >= 201103L + template<typename _InputIterator, + typename = std::_RequireInputIter<_InputIterator>> +#else + template<typename _InputIterator> +#endif + basic_string(_InputIterator __beg, _InputIterator __end, + const _Alloc& __a = _Alloc()) + : _M_dataplus(_M_local_data(), __a) + { _M_construct(__beg, __end); } + + /** + * @brief Destroy the string instance. + */ + ~basic_string() + { _M_dispose(); } + + /** + * @brief Assign the value of @a str to this string. + * @param __str Source string. + */ + basic_string& + operator=(const basic_string& __str) + { return this->assign(__str); } + + /** + * @brief Copy contents of @a s into this string. + * @param __s Source null-terminated string. + */ + basic_string& + operator=(const _CharT* __s) + { return this->assign(__s); } + + /** + * @brief Set value to string of length 1. + * @param __c Source character. + * + * Assigning to a character makes this string length 1 and + * (*this)[0] == @a c. + */ + basic_string& + operator=(_CharT __c) + { + this->assign(1, __c); + return *this; + } + +#if __cplusplus >= 201103L + /** + * @brief Move assign the value of @a str to this string. + * @param __str Source string. + * + * The contents of @a str are moved into this string (without copying). + * @a str is a valid, but unspecified string. + **/ + // PR 58265, this should be noexcept. + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2063. Contradictory requirements for string move assignment + basic_string& + operator=(basic_string&& __str) + { + this->swap(__str); + return *this; + } + + /** + * @brief Set value to string constructed from initializer %list. + * @param __l std::initializer_list. + */ + basic_string& + operator=(initializer_list<_CharT> __l) + { + this->assign(__l.begin(), __l.size()); + return *this; + } +#endif // C++11 + + // Iterators: + /** + * Returns a read/write iterator that points to the first character in + * the %string. + */ + iterator + begin() _GLIBCXX_NOEXCEPT + { return iterator(_M_data()); } + + /** + * Returns a read-only (constant) iterator that points to the first + * character in the %string. + */ + const_iterator + begin() const _GLIBCXX_NOEXCEPT + { return const_iterator(_M_data()); } + + /** + * Returns a read/write iterator that points one past the last + * character in the %string. + */ + iterator + end() _GLIBCXX_NOEXCEPT + { return iterator(_M_data() + this->size()); } + + /** + * Returns a read-only (constant) iterator that points one past the + * last character in the %string. + */ + const_iterator + end() const _GLIBCXX_NOEXCEPT + { return const_iterator(_M_data() + this->size()); } + + /** + * Returns a read/write reverse iterator that points to the last + * character in the %string. Iteration is done in reverse element + * order. + */ + reverse_iterator + rbegin() _GLIBCXX_NOEXCEPT + { return reverse_iterator(this->end()); } + + /** + * Returns a read-only (constant) reverse iterator that points + * to the last character in the %string. Iteration is done in + * reverse element order. + */ + const_reverse_iterator + rbegin() const _GLIBCXX_NOEXCEPT + { return const_reverse_iterator(this->end()); } + + /** + * Returns a read/write reverse iterator that points to one before the + * first character in the %string. Iteration is done in reverse + * element order. + */ + reverse_iterator + rend() _GLIBCXX_NOEXCEPT + { return reverse_iterator(this->begin()); } + + /** + * Returns a read-only (constant) reverse iterator that points + * to one before the first character in the %string. Iteration + * is done in reverse element order. + */ + const_reverse_iterator + rend() const _GLIBCXX_NOEXCEPT + { return const_reverse_iterator(this->begin()); } + +#if __cplusplus >= 201103L + /** + * Returns a read-only (constant) iterator that points to the first + * character in the %string. + */ + const_iterator + cbegin() const noexcept + { return const_iterator(this->_M_data()); } + + /** + * Returns a read-only (constant) iterator that points one past the + * last character in the %string. + */ + const_iterator + cend() const noexcept + { return const_iterator(this->_M_data() + this->size()); } + + /** + * Returns a read-only (constant) reverse iterator that points + * to the last character in the %string. Iteration is done in + * reverse element order. + */ + const_reverse_iterator + crbegin() const noexcept + { return const_reverse_iterator(this->end()); } + + /** + * Returns a read-only (constant) reverse iterator that points + * to one before the first character in the %string. Iteration + * is done in reverse element order. + */ + const_reverse_iterator + crend() const noexcept + { return const_reverse_iterator(this->begin()); } +#endif + + public: + // Capacity: + /// Returns the number of characters in the string, not including any + /// null-termination. + size_type + size() const _GLIBCXX_NOEXCEPT + { return _M_string_length; } + + /// Returns the number of characters in the string, not including any + /// null-termination. + size_type + length() const _GLIBCXX_NOEXCEPT + { return _M_string_length; } + + /// Returns the size() of the largest possible %string. + size_type + max_size() const _GLIBCXX_NOEXCEPT + { return (_Alloc_traits::max_size(_M_get_allocator()) - 1) / 2; } + + /** + * @brief Resizes the %string to the specified number of characters. + * @param __n Number of characters the %string should contain. + * @param __c Character to fill any new elements. + * + * This function will %resize the %string to the specified + * number of characters. If the number is smaller than the + * %string's current size the %string is truncated, otherwise + * the %string is extended and new elements are %set to @a __c. + */ + void + resize(size_type __n, _CharT __c); + + /** + * @brief Resizes the %string to the specified number of characters. + * @param __n Number of characters the %string should contain. + * + * This function will resize the %string to the specified length. If + * the new size is smaller than the %string's current size the %string + * is truncated, otherwise the %string is extended and new characters + * are default-constructed. For basic types such as char, this means + * setting them to 0. + */ + void + resize(size_type __n) + { this->resize(__n, _CharT()); } + +#if __cplusplus >= 201103L + /// A non-binding request to reduce capacity() to size(). + void + shrink_to_fit() noexcept + { + if (capacity() > size()) + { + __try + { reserve(0); } + __catch(...) + { } + } + } +#endif + + /** + * Returns the total number of characters that the %string can hold + * before needing to allocate more memory. + */ + size_type + capacity() const _GLIBCXX_NOEXCEPT + { + return _M_is_local() ? size_type(_S_local_capacity) + : _M_allocated_capacity; + } + + /** + * @brief Attempt to preallocate enough memory for specified number of + * characters. + * @param __res_arg Number of characters required. + * @throw std::length_error If @a __res_arg exceeds @c max_size(). + * + * This function attempts to reserve enough memory for the + * %string to hold the specified number of characters. If the + * number requested is more than max_size(), length_error is + * thrown. + * + * The advantage of this function is that if optimal code is a + * necessity and the user can determine the string length that will be + * required, the user can reserve the memory in %advance, and thus + * prevent a possible reallocation of memory and copying of %string + * data. + */ + void + reserve(size_type __res_arg = 0); + + /** + * Erases the string, making it empty. + */ + void + clear() _GLIBCXX_NOEXCEPT + { _M_set_length(0); } + + /** + * Returns true if the %string is empty. Equivalent to + * <code>*this == ""</code>. + */ + bool + empty() const _GLIBCXX_NOEXCEPT + { return this->size() == 0; } + + // Element access: + /** + * @brief Subscript access to the data contained in the %string. + * @param __pos The index of the character to access. + * @return Read-only (constant) reference to the character. + * + * This operator allows for easy, array-style, data access. + * Note that data access with this operator is unchecked and + * out_of_range lookups are not defined. (For checked lookups + * see at().) + */ + const_reference + operator[] (size_type __pos) const _GLIBCXX_NOEXCEPT + { + _GLIBCXX_DEBUG_ASSERT(__pos <= size()); + return _M_data()[__pos]; + } + + /** + * @brief Subscript access to the data contained in the %string. + * @param __pos The index of the character to access. + * @return Read/write reference to the character. + * + * This operator allows for easy, array-style, data access. + * Note that data access with this operator is unchecked and + * out_of_range lookups are not defined. (For checked lookups + * see at().) + */ + reference + operator[](size_type __pos) + { + // Allow pos == size() both in C++98 mode, as v3 extension, + // and in C++11 mode. + _GLIBCXX_DEBUG_ASSERT(__pos <= size()); + // In pedantic mode be strict in C++98 mode. + _GLIBCXX_DEBUG_PEDASSERT(__cplusplus >= 201103L || __pos < size()); + return _M_data()[__pos]; + } + + /** + * @brief Provides access to the data contained in the %string. + * @param __n The index of the character to access. + * @return Read-only (const) reference to the character. + * @throw std::out_of_range If @a n is an invalid index. + * + * This function provides for safer data access. The parameter is + * first checked that it is in the range of the string. The function + * throws out_of_range if the check fails. + */ + const_reference + at(size_type __n) const + { + if (__n >= this->size()) + __throw_out_of_range_fmt(__N("basic_string::at: __n " + "(which is %zu) >= this->size() " + "(which is %zu)"), + __n, this->size()); + return _M_data()[__n]; + } + + /** + * @brief Provides access to the data contained in the %string. + * @param __n The index of the character to access. + * @return Read/write reference to the character. + * @throw std::out_of_range If @a n is an invalid index. + * + * This function provides for safer data access. The parameter is + * first checked that it is in the range of the string. The function + * throws out_of_range if the check fails. + */ + reference + at(size_type __n) + { + if (__n >= size()) + __throw_out_of_range_fmt(__N("basic_string::at: __n " + "(which is %zu) >= this->size() " + "(which is %zu)"), + __n, this->size()); + return _M_data()[__n]; + } + +#if __cplusplus >= 201103L + /** + * Returns a read/write reference to the data at the first + * element of the %string. + */ + reference + front() noexcept + { return operator[](0); } + + /** + * Returns a read-only (constant) reference to the data at the first + * element of the %string. + */ + const_reference + front() const noexcept + { return operator[](0); } + + /** + * Returns a read/write reference to the data at the last + * element of the %string. + */ + reference + back() noexcept + { return operator[](this->size() - 1); } + + /** + * Returns a read-only (constant) reference to the data at the + * last element of the %string. + */ + const_reference + back() const noexcept + { return operator[](this->size() - 1); } +#endif + + // Modifiers: + /** + * @brief Append a string to this string. + * @param __str The string to append. + * @return Reference to this string. + */ + basic_string& + operator+=(const basic_string& __str) + { return this->append(__str); } + + /** + * @brief Append a C string. + * @param __s The C string to append. + * @return Reference to this string. + */ + basic_string& + operator+=(const _CharT* __s) + { return this->append(__s); } + + /** + * @brief Append a character. + * @param __c The character to append. + * @return Reference to this string. + */ + basic_string& + operator+=(_CharT __c) + { + this->push_back(__c); + return *this; + } + +#if __cplusplus >= 201103L + /** + * @brief Append an initializer_list of characters. + * @param __l The initializer_list of characters to be appended. + * @return Reference to this string. + */ + basic_string& + operator+=(initializer_list<_CharT> __l) + { return this->append(__l.begin(), __l.size()); } +#endif // C++11 + + /** + * @brief Append a string to this string. + * @param __str The string to append. + * @return Reference to this string. + */ + basic_string& + append(const basic_string& __str) + { return _M_append(__str._M_data(), __str.size()); } + + /** + * @brief Append a substring. + * @param __str The string to append. + * @param __pos Index of the first character of str to append. + * @param __n The number of characters to append. + * @return Reference to this string. + * @throw std::out_of_range if @a __pos is not a valid index. + * + * This function appends @a __n characters from @a __str + * starting at @a __pos to this string. If @a __n is is larger + * than the number of available characters in @a __str, the + * remainder of @a __str is appended. + */ + basic_string& + append(const basic_string& __str, size_type __pos, size_type __n) + { return _M_append(__str._M_data() + + __str._M_check(__pos, "basic_string::append"), + __str._M_limit(__pos, __n)); } + + /** + * @brief Append a C substring. + * @param __s The C string to append. + * @param __n The number of characters to append. + * @return Reference to this string. + */ + basic_string& + append(const _CharT* __s, size_type __n) + { + __glibcxx_requires_string_len(__s, __n); + _M_check_length(size_type(0), __n, "basic_string::append"); + return _M_append(__s, __n); + } + + /** + * @brief Append a C string. + * @param __s The C string to append. + * @return Reference to this string. + */ + basic_string& + append(const _CharT* __s) + { + __glibcxx_requires_string(__s); + const size_type __n = traits_type::length(__s); + _M_check_length(size_type(0), __n, "basic_string::append"); + return _M_append(__s, __n); + } + + /** + * @brief Append multiple characters. + * @param __n The number of characters to append. + * @param __c The character to use. + * @return Reference to this string. + * + * Appends __n copies of __c to this string. + */ + basic_string& + append(size_type __n, _CharT __c) + { return _M_replace_aux(this->size(), size_type(0), __n, __c); } + +#if __cplusplus >= 201103L + /** + * @brief Append an initializer_list of characters. + * @param __l The initializer_list of characters to append. + * @return Reference to this string. + */ + basic_string& + append(initializer_list<_CharT> __l) + { return this->append(__l.begin(), __l.size()); } +#endif // C++11 + + /** + * @brief Append a range of characters. + * @param __first Iterator referencing the first character to append. + * @param __last Iterator marking the end of the range. + * @return Reference to this string. + * + * Appends characters in the range [__first,__last) to this string. + */ +#if __cplusplus >= 201103L + template<class _InputIterator, + typename = std::_RequireInputIter<_InputIterator>> +#else + template<class _InputIterator> +#endif + basic_string& + append(_InputIterator __first, _InputIterator __last) + { return this->replace(end(), end(), __first, __last); } + + /** + * @brief Append a single character. + * @param __c Character to append. + */ + void + push_back(_CharT __c) + { + const size_type __size = this->size(); + if (__size + 1 > this->capacity()) + this->_M_mutate(__size, size_type(0), 0, size_type(1)); + traits_type::assign(this->_M_data()[__size], __c); + this->_M_set_length(__size + 1); + } + + /** + * @brief Set value to contents of another string. + * @param __str Source string to use. + * @return Reference to this string. + */ + basic_string& + assign(const basic_string& __str) + { + this->_M_assign(__str); + return *this; + } + +#if __cplusplus >= 201103L + /** + * @brief Set value to contents of another string. + * @param __str Source string to use. + * @return Reference to this string. + * + * This function sets this string to the exact contents of @a __str. + * @a __str is a valid, but unspecified string. + */ + basic_string& + assign(basic_string&& __str) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2063. Contradictory requirements for string move assignment + return *this = std::move(__str); + } +#endif // C++11 + + /** + * @brief Set value to a substring of a string. + * @param __str The string to use. + * @param __pos Index of the first character of str. + * @param __n Number of characters to use. + * @return Reference to this string. + * @throw std::out_of_range if @a pos is not a valid index. + * + * This function sets this string to the substring of @a __str + * consisting of @a __n characters at @a __pos. If @a __n is + * is larger than the number of available characters in @a + * __str, the remainder of @a __str is used. + */ + basic_string& + assign(const basic_string& __str, size_type __pos, size_type __n) + { return _M_replace(size_type(0), this->size(), __str._M_data() + + __str._M_check(__pos, "basic_string::assign"), + __str._M_limit(__pos, __n)); } + + /** + * @brief Set value to a C substring. + * @param __s The C string to use. + * @param __n Number of characters to use. + * @return Reference to this string. + * + * This function sets the value of this string to the first @a __n + * characters of @a __s. If @a __n is is larger than the number of + * available characters in @a __s, the remainder of @a __s is used. + */ + basic_string& + assign(const _CharT* __s, size_type __n) + { + __glibcxx_requires_string_len(__s, __n); + return _M_replace(size_type(0), this->size(), __s, __n); + } + + /** + * @brief Set value to contents of a C string. + * @param __s The C string to use. + * @return Reference to this string. + * + * This function sets the value of this string to the value of @a __s. + * The data is copied, so there is no dependence on @a __s once the + * function returns. + */ + basic_string& + assign(const _CharT* __s) + { + __glibcxx_requires_string(__s); + return _M_replace(size_type(0), this->size(), __s, + traits_type::length(__s)); + } + + /** + * @brief Set value to multiple characters. + * @param __n Length of the resulting string. + * @param __c The character to use. + * @return Reference to this string. + * + * This function sets the value of this string to @a __n copies of + * character @a __c. + */ + basic_string& + assign(size_type __n, _CharT __c) + { return _M_replace_aux(size_type(0), this->size(), __n, __c); } + + /** + * @brief Set value to a range of characters. + * @param __first Iterator referencing the first character to append. + * @param __last Iterator marking the end of the range. + * @return Reference to this string. + * + * Sets value of string to characters in the range [__first,__last). + */ +#if __cplusplus >= 201103L + template<class _InputIterator, + typename = std::_RequireInputIter<_InputIterator>> +#else + template<class _InputIterator> +#endif + basic_string& + assign(_InputIterator __first, _InputIterator __last) + { return this->replace(begin(), end(), __first, __last); } + +#if __cplusplus >= 201103L + /** + * @brief Set value to an initializer_list of characters. + * @param __l The initializer_list of characters to assign. + * @return Reference to this string. + */ + basic_string& + assign(initializer_list<_CharT> __l) + { return this->assign(__l.begin(), __l.size()); } +#endif // C++11 + +#if __cplusplus >= 201103L + /** + * @brief Insert multiple characters. + * @param __p Const_iterator referencing location in string to + * insert at. + * @param __n Number of characters to insert + * @param __c The character to insert. + * @return Iterator referencing the first inserted char. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Inserts @a __n copies of character @a __c starting at the + * position referenced by iterator @a __p. If adding + * characters causes the length to exceed max_size(), + * length_error is thrown. The value of the string doesn't + * change if an error is thrown. + */ + iterator + insert(const_iterator __p, size_type __n, _CharT __c) + { + _GLIBCXX_DEBUG_PEDASSERT(__p >= begin() && __p <= end()); + const size_type __pos = __p - begin(); + this->replace(__p, __p, __n, __c); + return iterator(this->_M_data() + __pos); + } +#else + /** + * @brief Insert multiple characters. + * @param __p Iterator referencing location in string to insert at. + * @param __n Number of characters to insert + * @param __c The character to insert. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Inserts @a __n copies of character @a __c starting at the + * position referenced by iterator @a __p. If adding + * characters causes the length to exceed max_size(), + * length_error is thrown. The value of the string doesn't + * change if an error is thrown. + */ + void + insert(iterator __p, size_type __n, _CharT __c) + { this->replace(__p, __p, __n, __c); } +#endif + +#if __cplusplus >= 201103L + /** + * @brief Insert a range of characters. + * @param __p Const_iterator referencing location in string to + * insert at. + * @param __beg Start of range. + * @param __end End of range. + * @return Iterator referencing the first inserted char. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Inserts characters in range [beg,end). If adding characters + * causes the length to exceed max_size(), length_error is + * thrown. The value of the string doesn't change if an error + * is thrown. + */ + template<class _InputIterator, + typename = std::_RequireInputIter<_InputIterator>> + iterator + insert(const_iterator __p, _InputIterator __beg, _InputIterator __end) + { + _GLIBCXX_DEBUG_PEDASSERT(__p >= begin() && __p <= end()); + const size_type __pos = __p - begin(); + this->replace(__p, __p, __beg, __end); + return iterator(this->_M_data() + __pos); + } +#else + /** + * @brief Insert a range of characters. + * @param __p Iterator referencing location in string to insert at. + * @param __beg Start of range. + * @param __end End of range. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Inserts characters in range [__beg,__end). If adding + * characters causes the length to exceed max_size(), + * length_error is thrown. The value of the string doesn't + * change if an error is thrown. + */ + template<class _InputIterator> + void + insert(iterator __p, _InputIterator __beg, _InputIterator __end) + { this->replace(__p, __p, __beg, __end); } +#endif + +#if __cplusplus >= 201103L + /** + * @brief Insert an initializer_list of characters. + * @param __p Iterator referencing location in string to insert at. + * @param __l The initializer_list of characters to insert. + * @throw std::length_error If new length exceeds @c max_size(). + */ + void + insert(iterator __p, initializer_list<_CharT> __l) + { + _GLIBCXX_DEBUG_PEDASSERT(__p >= begin() && __p <= end()); + this->insert(__p - begin(), __l.begin(), __l.size()); + } +#endif // C++11 + + /** + * @brief Insert value of a string. + * @param __pos1 Iterator referencing location in string to insert at. + * @param __str The string to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Inserts value of @a __str starting at @a __pos1. If adding + * characters causes the length to exceed max_size(), + * length_error is thrown. The value of the string doesn't + * change if an error is thrown. + */ + basic_string& + insert(size_type __pos1, const basic_string& __str) + { return this->replace(__pos1, size_type(0), + __str._M_data(), __str.size()); } + + /** + * @brief Insert a substring. + * @param __pos1 Iterator referencing location in string to insert at. + * @param __str The string to insert. + * @param __pos2 Start of characters in str to insert. + * @param __n Number of characters to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * @throw std::out_of_range If @a pos1 > size() or + * @a __pos2 > @a str.size(). + * + * Starting at @a pos1, insert @a __n character of @a __str + * beginning with @a __pos2. If adding characters causes the + * length to exceed max_size(), length_error is thrown. If @a + * __pos1 is beyond the end of this string or @a __pos2 is + * beyond the end of @a __str, out_of_range is thrown. The + * value of the string doesn't change if an error is thrown. + */ + basic_string& + insert(size_type __pos1, const basic_string& __str, + size_type __pos2, size_type __n) + { return this->replace(__pos1, size_type(0), __str._M_data() + + __str._M_check(__pos2, "basic_string::insert"), + __str._M_limit(__pos2, __n)); } + + /** + * @brief Insert a C substring. + * @param __pos Iterator referencing location in string to insert at. + * @param __s The C string to insert. + * @param __n The number of characters to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * @throw std::out_of_range If @a __pos is beyond the end of this + * string. + * + * Inserts the first @a __n characters of @a __s starting at @a + * __pos. If adding characters causes the length to exceed + * max_size(), length_error is thrown. If @a __pos is beyond + * end(), out_of_range is thrown. The value of the string + * doesn't change if an error is thrown. + */ + basic_string& + insert(size_type __pos, const _CharT* __s, size_type __n) + { return this->replace(__pos, size_type(0), __s, __n); } + + /** + * @brief Insert a C string. + * @param __pos Iterator referencing location in string to insert at. + * @param __s The C string to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * @throw std::out_of_range If @a pos is beyond the end of this + * string. + * + * Inserts the first @a n characters of @a __s starting at @a __pos. If + * adding characters causes the length to exceed max_size(), + * length_error is thrown. If @a __pos is beyond end(), out_of_range is + * thrown. The value of the string doesn't change if an error is + * thrown. + */ + basic_string& + insert(size_type __pos, const _CharT* __s) + { + __glibcxx_requires_string(__s); + return this->replace(__pos, size_type(0), __s, + traits_type::length(__s)); + } + + /** + * @brief Insert multiple characters. + * @param __pos Index in string to insert at. + * @param __n Number of characters to insert + * @param __c The character to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * @throw std::out_of_range If @a __pos is beyond the end of this + * string. + * + * Inserts @a __n copies of character @a __c starting at index + * @a __pos. If adding characters causes the length to exceed + * max_size(), length_error is thrown. If @a __pos > length(), + * out_of_range is thrown. The value of the string doesn't + * change if an error is thrown. + */ + basic_string& + insert(size_type __pos, size_type __n, _CharT __c) + { return _M_replace_aux(_M_check(__pos, "basic_string::insert"), + size_type(0), __n, __c); } + + /** + * @brief Insert one character. + * @param __p Iterator referencing position in string to insert at. + * @param __c The character to insert. + * @return Iterator referencing newly inserted char. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Inserts character @a __c at position referenced by @a __p. + * If adding character causes the length to exceed max_size(), + * length_error is thrown. If @a __p is beyond end of string, + * out_of_range is thrown. The value of the string doesn't + * change if an error is thrown. + */ + iterator + insert(__const_iterator __p, _CharT __c) + { + _GLIBCXX_DEBUG_PEDASSERT(__p >= begin() && __p <= end()); + const size_type __pos = __p - begin(); + _M_replace_aux(__pos, size_type(0), size_type(1), __c); + return iterator(_M_data() + __pos); + } + + /** + * @brief Remove characters. + * @param __pos Index of first character to remove (default 0). + * @param __n Number of characters to remove (default remainder). + * @return Reference to this string. + * @throw std::out_of_range If @a pos is beyond the end of this + * string. + * + * Removes @a __n characters from this string starting at @a + * __pos. The length of the string is reduced by @a __n. If + * there are < @a __n characters to remove, the remainder of + * the string is truncated. If @a __p is beyond end of string, + * out_of_range is thrown. The value of the string doesn't + * change if an error is thrown. + */ + basic_string& + erase(size_type __pos = 0, size_type __n = npos) + { + this->_M_erase(_M_check(__pos, "basic_string::erase"), + _M_limit(__pos, __n)); + return *this; + } + + /** + * @brief Remove one character. + * @param __position Iterator referencing the character to remove. + * @return iterator referencing same location after removal. + * + * Removes the character at @a __position from this string. The value + * of the string doesn't change if an error is thrown. + */ + iterator + erase(__const_iterator __position) + { + _GLIBCXX_DEBUG_PEDASSERT(__position >= begin() + && __position < end()); + const size_type __pos = __position - begin(); + this->_M_erase(__pos, size_type(1)); + return iterator(_M_data() + __pos); + } + + /** + * @brief Remove a range of characters. + * @param __first Iterator referencing the first character to remove. + * @param __last Iterator referencing the end of the range. + * @return Iterator referencing location of first after removal. + * + * Removes the characters in the range [first,last) from this string. + * The value of the string doesn't change if an error is thrown. + */ + iterator + erase(__const_iterator __first, __const_iterator __last) + { + _GLIBCXX_DEBUG_PEDASSERT(__first >= begin() && __first <= __last + && __last <= end()); + const size_type __pos = __first - begin(); + this->_M_erase(__pos, __last - __first); + return iterator(this->_M_data() + __pos); + } + +#if __cplusplus >= 201103L + /** + * @brief Remove the last character. + * + * The string must be non-empty. + */ + void + pop_back() noexcept + { _M_erase(size()-1, 1); } +#endif // C++11 + + /** + * @brief Replace characters with value from another string. + * @param __pos Index of first character to replace. + * @param __n Number of characters to be replaced. + * @param __str String to insert. + * @return Reference to this string. + * @throw std::out_of_range If @a pos is beyond the end of this + * string. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [__pos,__pos+__n) from + * this string. In place, the value of @a __str is inserted. + * If @a __pos is beyond end of string, out_of_range is thrown. + * If the length of the result exceeds max_size(), length_error + * is thrown. The value of the string doesn't change if an + * error is thrown. + */ + basic_string& + replace(size_type __pos, size_type __n, const basic_string& __str) + { return this->replace(__pos, __n, __str._M_data(), __str.size()); } + + /** + * @brief Replace characters with value from another string. + * @param __pos1 Index of first character to replace. + * @param __n1 Number of characters to be replaced. + * @param __str String to insert. + * @param __pos2 Index of first character of str to use. + * @param __n2 Number of characters from str to use. + * @return Reference to this string. + * @throw std::out_of_range If @a __pos1 > size() or @a __pos2 > + * __str.size(). + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [__pos1,__pos1 + n) from this + * string. In place, the value of @a __str is inserted. If @a __pos is + * beyond end of string, out_of_range is thrown. If the length of the + * result exceeds max_size(), length_error is thrown. The value of the + * string doesn't change if an error is thrown. + */ + basic_string& + replace(size_type __pos1, size_type __n1, const basic_string& __str, + size_type __pos2, size_type __n2) + { return this->replace(__pos1, __n1, __str._M_data() + + __str._M_check(__pos2, "basic_string::replace"), + __str._M_limit(__pos2, __n2)); } + + /** + * @brief Replace characters with value of a C substring. + * @param __pos Index of first character to replace. + * @param __n1 Number of characters to be replaced. + * @param __s C string to insert. + * @param __n2 Number of characters from @a s to use. + * @return Reference to this string. + * @throw std::out_of_range If @a pos1 > size(). + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [__pos,__pos + __n1) + * from this string. In place, the first @a __n2 characters of + * @a __s are inserted, or all of @a __s if @a __n2 is too large. If + * @a __pos is beyond end of string, out_of_range is thrown. If + * the length of result exceeds max_size(), length_error is + * thrown. The value of the string doesn't change if an error + * is thrown. + */ + basic_string& + replace(size_type __pos, size_type __n1, const _CharT* __s, + size_type __n2) + { + __glibcxx_requires_string_len(__s, __n2); + return _M_replace(_M_check(__pos, "basic_string::replace"), + _M_limit(__pos, __n1), __s, __n2); + } + + /** + * @brief Replace characters with value of a C string. + * @param __pos Index of first character to replace. + * @param __n1 Number of characters to be replaced. + * @param __s C string to insert. + * @return Reference to this string. + * @throw std::out_of_range If @a pos > size(). + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [__pos,__pos + __n1) + * from this string. In place, the characters of @a __s are + * inserted. If @a __pos is beyond end of string, out_of_range + * is thrown. If the length of result exceeds max_size(), + * length_error is thrown. The value of the string doesn't + * change if an error is thrown. + */ + basic_string& + replace(size_type __pos, size_type __n1, const _CharT* __s) + { + __glibcxx_requires_string(__s); + return this->replace(__pos, __n1, __s, traits_type::length(__s)); + } + + /** + * @brief Replace characters with multiple characters. + * @param __pos Index of first character to replace. + * @param __n1 Number of characters to be replaced. + * @param __n2 Number of characters to insert. + * @param __c Character to insert. + * @return Reference to this string. + * @throw std::out_of_range If @a __pos > size(). + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [pos,pos + n1) from this + * string. In place, @a __n2 copies of @a __c are inserted. + * If @a __pos is beyond end of string, out_of_range is thrown. + * If the length of result exceeds max_size(), length_error is + * thrown. The value of the string doesn't change if an error + * is thrown. + */ + basic_string& + replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c) + { return _M_replace_aux(_M_check(__pos, "basic_string::replace"), + _M_limit(__pos, __n1), __n2, __c); } + + /** + * @brief Replace range of characters with string. + * @param __i1 Iterator referencing start of range to replace. + * @param __i2 Iterator referencing end of range to replace. + * @param __str String value to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [__i1,__i2). In place, + * the value of @a __str is inserted. If the length of result + * exceeds max_size(), length_error is thrown. The value of + * the string doesn't change if an error is thrown. + */ + basic_string& + replace(__const_iterator __i1, __const_iterator __i2, + const basic_string& __str) + { return this->replace(__i1, __i2, __str._M_data(), __str.size()); } + + /** + * @brief Replace range of characters with C substring. + * @param __i1 Iterator referencing start of range to replace. + * @param __i2 Iterator referencing end of range to replace. + * @param __s C string value to insert. + * @param __n Number of characters from s to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [__i1,__i2). In place, + * the first @a __n characters of @a __s are inserted. If the + * length of result exceeds max_size(), length_error is thrown. + * The value of the string doesn't change if an error is + * thrown. + */ + basic_string& + replace(__const_iterator __i1, __const_iterator __i2, + const _CharT* __s, size_type __n) + { + _GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2 + && __i2 <= end()); + return this->replace(__i1 - begin(), __i2 - __i1, __s, __n); + } + + /** + * @brief Replace range of characters with C string. + * @param __i1 Iterator referencing start of range to replace. + * @param __i2 Iterator referencing end of range to replace. + * @param __s C string value to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [__i1,__i2). In place, + * the characters of @a __s are inserted. If the length of + * result exceeds max_size(), length_error is thrown. The + * value of the string doesn't change if an error is thrown. + */ + basic_string& + replace(__const_iterator __i1, __const_iterator __i2, const _CharT* __s) + { + __glibcxx_requires_string(__s); + return this->replace(__i1, __i2, __s, traits_type::length(__s)); + } + + /** + * @brief Replace range of characters with multiple characters + * @param __i1 Iterator referencing start of range to replace. + * @param __i2 Iterator referencing end of range to replace. + * @param __n Number of characters to insert. + * @param __c Character to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [__i1,__i2). In place, + * @a __n copies of @a __c are inserted. If the length of + * result exceeds max_size(), length_error is thrown. The + * value of the string doesn't change if an error is thrown. + */ + basic_string& + replace(__const_iterator __i1, __const_iterator __i2, size_type __n, + _CharT __c) + { + _GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2 + && __i2 <= end()); + return _M_replace_aux(__i1 - begin(), __i2 - __i1, __n, __c); + } + + /** + * @brief Replace range of characters with range. + * @param __i1 Iterator referencing start of range to replace. + * @param __i2 Iterator referencing end of range to replace. + * @param __k1 Iterator referencing start of range to insert. + * @param __k2 Iterator referencing end of range to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [__i1,__i2). In place, + * characters in the range [__k1,__k2) are inserted. If the + * length of result exceeds max_size(), length_error is thrown. + * The value of the string doesn't change if an error is + * thrown. + */ +#if __cplusplus >= 201103L + template<class _InputIterator, + typename = std::_RequireInputIter<_InputIterator>> + basic_string& + replace(const_iterator __i1, const_iterator __i2, + _InputIterator __k1, _InputIterator __k2) + { + _GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2 + && __i2 <= end()); + __glibcxx_requires_valid_range(__k1, __k2); + return this->_M_replace_dispatch(__i1, __i2, __k1, __k2, + std::__false_type()); + } +#else + template<class _InputIterator> +#ifdef _GLIBCXX_DISAMBIGUATE_REPLACE_INST + typename __enable_if_not_native_iterator<_InputIterator>::__type +#else + basic_string& +#endif + replace(iterator __i1, iterator __i2, + _InputIterator __k1, _InputIterator __k2) + { + _GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2 + && __i2 <= end()); + __glibcxx_requires_valid_range(__k1, __k2); + typedef typename std::__is_integer<_InputIterator>::__type _Integral; + return _M_replace_dispatch(__i1, __i2, __k1, __k2, _Integral()); + } +#endif + + // Specializations for the common case of pointer and iterator: + // useful to avoid the overhead of temporary buffering in _M_replace. + basic_string& + replace(__const_iterator __i1, __const_iterator __i2, + _CharT* __k1, _CharT* __k2) + { + _GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2 + && __i2 <= end()); + __glibcxx_requires_valid_range(__k1, __k2); + return this->replace(__i1 - begin(), __i2 - __i1, + __k1, __k2 - __k1); + } + + basic_string& + replace(__const_iterator __i1, __const_iterator __i2, + const _CharT* __k1, const _CharT* __k2) + { + _GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2 + && __i2 <= end()); + __glibcxx_requires_valid_range(__k1, __k2); + return this->replace(__i1 - begin(), __i2 - __i1, + __k1, __k2 - __k1); + } + + basic_string& + replace(__const_iterator __i1, __const_iterator __i2, + iterator __k1, iterator __k2) + { + _GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2 + && __i2 <= end()); + __glibcxx_requires_valid_range(__k1, __k2); + return this->replace(__i1 - begin(), __i2 - __i1, + __k1.base(), __k2 - __k1); + } + + basic_string& + replace(__const_iterator __i1, __const_iterator __i2, + const_iterator __k1, const_iterator __k2) + { + _GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2 + && __i2 <= end()); + __glibcxx_requires_valid_range(__k1, __k2); + return this->replace(__i1 - begin(), __i2 - __i1, + __k1.base(), __k2 - __k1); + } + +#if __cplusplus >= 201103L + /** + * @brief Replace range of characters with initializer_list. + * @param __i1 Iterator referencing start of range to replace. + * @param __i2 Iterator referencing end of range to replace. + * @param __l The initializer_list of characters to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [__i1,__i2). In place, + * characters in the range [__k1,__k2) are inserted. If the + * length of result exceeds max_size(), length_error is thrown. + * The value of the string doesn't change if an error is + * thrown. + */ + basic_string& replace(const_iterator __i1, const_iterator __i2, + initializer_list<_CharT> __l) + { return this->replace(__i1, __i2, __l.begin(), __l.end()); } +#endif // C++11 + + private: + template<class _Integer> + basic_string& + _M_replace_dispatch(const_iterator __i1, const_iterator __i2, + _Integer __n, _Integer __val, __true_type) + { return _M_replace_aux(__i1 - begin(), __i2 - __i1, __n, __val); } + + template<class _InputIterator> + basic_string& + _M_replace_dispatch(const_iterator __i1, const_iterator __i2, + _InputIterator __k1, _InputIterator __k2, + __false_type); + + basic_string& + _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2, + _CharT __c); + + basic_string& + _M_replace(size_type __pos, size_type __len1, const _CharT* __s, + const size_type __len2); + + basic_string& + _M_append(const _CharT* __s, size_type __n); + + public: + + /** + * @brief Copy substring into C string. + * @param __s C string to copy value into. + * @param __n Number of characters to copy. + * @param __pos Index of first character to copy. + * @return Number of characters actually copied + * @throw std::out_of_range If __pos > size(). + * + * Copies up to @a __n characters starting at @a __pos into the + * C string @a __s. If @a __pos is %greater than size(), + * out_of_range is thrown. + */ + size_type + copy(_CharT* __s, size_type __n, size_type __pos = 0) const; + + /** + * @brief Swap contents with another string. + * @param __s String to swap with. + * + * Exchanges the contents of this string with that of @a __s in constant + * time. + */ + void + swap(basic_string& __s) _GLIBCXX_NOEXCEPT; + + // String operations: + /** + * @brief Return const pointer to null-terminated contents. + * + * This is a handle to internal data. Do not modify or dire things may + * happen. + */ + const _CharT* + c_str() const _GLIBCXX_NOEXCEPT + { return _M_data(); } + + /** + * @brief Return const pointer to contents. + * + * This is a handle to internal data. Do not modify or dire things may + * happen. + */ + const _CharT* + data() const _GLIBCXX_NOEXCEPT + { return _M_data(); } + + /** + * @brief Return copy of allocator used to construct this string. + */ + allocator_type + get_allocator() const _GLIBCXX_NOEXCEPT + { return _M_get_allocator(); } + + /** + * @brief Find position of a C substring. + * @param __s C string to locate. + * @param __pos Index of character to search from. + * @param __n Number of characters from @a s to search for. + * @return Index of start of first occurrence. + * + * Starting from @a __pos, searches forward for the first @a + * __n characters in @a __s within this string. If found, + * returns the index where it begins. If not found, returns + * npos. + */ + size_type + find(const _CharT* __s, size_type __pos, size_type __n) const; + + /** + * @brief Find position of a string. + * @param __str String to locate. + * @param __pos Index of character to search from (default 0). + * @return Index of start of first occurrence. + * + * Starting from @a __pos, searches forward for value of @a __str within + * this string. If found, returns the index where it begins. If not + * found, returns npos. + */ + size_type + find(const basic_string& __str, size_type __pos = 0) const + _GLIBCXX_NOEXCEPT + { return this->find(__str.data(), __pos, __str.size()); } + + /** + * @brief Find position of a C string. + * @param __s C string to locate. + * @param __pos Index of character to search from (default 0). + * @return Index of start of first occurrence. + * + * Starting from @a __pos, searches forward for the value of @a + * __s within this string. If found, returns the index where + * it begins. If not found, returns npos. + */ + size_type + find(const _CharT* __s, size_type __pos = 0) const + { + __glibcxx_requires_string(__s); + return this->find(__s, __pos, traits_type::length(__s)); + } + + /** + * @brief Find position of a character. + * @param __c Character to locate. + * @param __pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a __pos, searches forward for @a __c within + * this string. If found, returns the index where it was + * found. If not found, returns npos. + */ + size_type + find(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT; + + /** + * @brief Find last position of a string. + * @param __str String to locate. + * @param __pos Index of character to search back from (default end). + * @return Index of start of last occurrence. + * + * Starting from @a __pos, searches backward for value of @a + * __str within this string. If found, returns the index where + * it begins. If not found, returns npos. + */ + size_type + rfind(const basic_string& __str, size_type __pos = npos) const + _GLIBCXX_NOEXCEPT + { return this->rfind(__str.data(), __pos, __str.size()); } + + /** + * @brief Find last position of a C substring. + * @param __s C string to locate. + * @param __pos Index of character to search back from. + * @param __n Number of characters from s to search for. + * @return Index of start of last occurrence. + * + * Starting from @a __pos, searches backward for the first @a + * __n characters in @a __s within this string. If found, + * returns the index where it begins. If not found, returns + * npos. + */ + size_type + rfind(const _CharT* __s, size_type __pos, size_type __n) const; + + /** + * @brief Find last position of a C string. + * @param __s C string to locate. + * @param __pos Index of character to start search at (default end). + * @return Index of start of last occurrence. + * + * Starting from @a __pos, searches backward for the value of + * @a __s within this string. If found, returns the index + * where it begins. If not found, returns npos. + */ + size_type + rfind(const _CharT* __s, size_type __pos = npos) const + { + __glibcxx_requires_string(__s); + return this->rfind(__s, __pos, traits_type::length(__s)); + } + + /** + * @brief Find last position of a character. + * @param __c Character to locate. + * @param __pos Index of character to search back from (default end). + * @return Index of last occurrence. + * + * Starting from @a __pos, searches backward for @a __c within + * this string. If found, returns the index where it was + * found. If not found, returns npos. + */ + size_type + rfind(_CharT __c, size_type __pos = npos) const _GLIBCXX_NOEXCEPT; + + /** + * @brief Find position of a character of string. + * @param __str String containing characters to locate. + * @param __pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a __pos, searches forward for one of the + * characters of @a __str within this string. If found, + * returns the index where it was found. If not found, returns + * npos. + */ + size_type + find_first_of(const basic_string& __str, size_type __pos = 0) const + _GLIBCXX_NOEXCEPT + { return this->find_first_of(__str.data(), __pos, __str.size()); } + + /** + * @brief Find position of a character of C substring. + * @param __s String containing characters to locate. + * @param __pos Index of character to search from. + * @param __n Number of characters from s to search for. + * @return Index of first occurrence. + * + * Starting from @a __pos, searches forward for one of the + * first @a __n characters of @a __s within this string. If + * found, returns the index where it was found. If not found, + * returns npos. + */ + size_type + find_first_of(const _CharT* __s, size_type __pos, size_type __n) const; + + /** + * @brief Find position of a character of C string. + * @param __s String containing characters to locate. + * @param __pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a __pos, searches forward for one of the + * characters of @a __s within this string. If found, returns + * the index where it was found. If not found, returns npos. + */ + size_type + find_first_of(const _CharT* __s, size_type __pos = 0) const + { + __glibcxx_requires_string(__s); + return this->find_first_of(__s, __pos, traits_type::length(__s)); + } + + /** + * @brief Find position of a character. + * @param __c Character to locate. + * @param __pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a __pos, searches forward for the character + * @a __c within this string. If found, returns the index + * where it was found. If not found, returns npos. + * + * Note: equivalent to find(__c, __pos). + */ + size_type + find_first_of(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT + { return this->find(__c, __pos); } + + /** + * @brief Find last position of a character of string. + * @param __str String containing characters to locate. + * @param __pos Index of character to search back from (default end). + * @return Index of last occurrence. + * + * Starting from @a __pos, searches backward for one of the + * characters of @a __str within this string. If found, + * returns the index where it was found. If not found, returns + * npos. + */ + size_type + find_last_of(const basic_string& __str, size_type __pos = npos) const + _GLIBCXX_NOEXCEPT + { return this->find_last_of(__str.data(), __pos, __str.size()); } + + /** + * @brief Find last position of a character of C substring. + * @param __s C string containing characters to locate. + * @param __pos Index of character to search back from. + * @param __n Number of characters from s to search for. + * @return Index of last occurrence. + * + * Starting from @a __pos, searches backward for one of the + * first @a __n characters of @a __s within this string. If + * found, returns the index where it was found. If not found, + * returns npos. + */ + size_type + find_last_of(const _CharT* __s, size_type __pos, size_type __n) const; + + /** + * @brief Find last position of a character of C string. + * @param __s C string containing characters to locate. + * @param __pos Index of character to search back from (default end). + * @return Index of last occurrence. + * + * Starting from @a __pos, searches backward for one of the + * characters of @a __s within this string. If found, returns + * the index where it was found. If not found, returns npos. + */ + size_type + find_last_of(const _CharT* __s, size_type __pos = npos) const + { + __glibcxx_requires_string(__s); + return this->find_last_of(__s, __pos, traits_type::length(__s)); + } + + /** + * @brief Find last position of a character. + * @param __c Character to locate. + * @param __pos Index of character to search back from (default end). + * @return Index of last occurrence. + * + * Starting from @a __pos, searches backward for @a __c within + * this string. If found, returns the index where it was + * found. If not found, returns npos. + * + * Note: equivalent to rfind(__c, __pos). + */ + size_type + find_last_of(_CharT __c, size_type __pos = npos) const _GLIBCXX_NOEXCEPT + { return this->rfind(__c, __pos); } + + /** + * @brief Find position of a character not in string. + * @param __str String containing characters to avoid. + * @param __pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a __pos, searches forward for a character not contained + * in @a __str within this string. If found, returns the index where it + * was found. If not found, returns npos. + */ + size_type + find_first_not_of(const basic_string& __str, size_type __pos = 0) const + _GLIBCXX_NOEXCEPT + { return this->find_first_not_of(__str.data(), __pos, __str.size()); } + + /** + * @brief Find position of a character not in C substring. + * @param __s C string containing characters to avoid. + * @param __pos Index of character to search from. + * @param __n Number of characters from __s to consider. + * @return Index of first occurrence. + * + * Starting from @a __pos, searches forward for a character not + * contained in the first @a __n characters of @a __s within + * this string. If found, returns the index where it was + * found. If not found, returns npos. + */ + size_type + find_first_not_of(const _CharT* __s, size_type __pos, + size_type __n) const; + + /** + * @brief Find position of a character not in C string. + * @param __s C string containing characters to avoid. + * @param __pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a __pos, searches forward for a character not + * contained in @a __s within this string. If found, returns + * the index where it was found. If not found, returns npos. + */ + size_type + find_first_not_of(const _CharT* __s, size_type __pos = 0) const + { + __glibcxx_requires_string(__s); + return this->find_first_not_of(__s, __pos, traits_type::length(__s)); + } + + /** + * @brief Find position of a different character. + * @param __c Character to avoid. + * @param __pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a __pos, searches forward for a character + * other than @a __c within this string. If found, returns the + * index where it was found. If not found, returns npos. + */ + size_type + find_first_not_of(_CharT __c, size_type __pos = 0) const + _GLIBCXX_NOEXCEPT; + + /** + * @brief Find last position of a character not in string. + * @param __str String containing characters to avoid. + * @param __pos Index of character to search back from (default end). + * @return Index of last occurrence. + * + * Starting from @a __pos, searches backward for a character + * not contained in @a __str within this string. If found, + * returns the index where it was found. If not found, returns + * npos. + */ + size_type + find_last_not_of(const basic_string& __str, size_type __pos = npos) const + _GLIBCXX_NOEXCEPT + { return this->find_last_not_of(__str.data(), __pos, __str.size()); } + + /** + * @brief Find last position of a character not in C substring. + * @param __s C string containing characters to avoid. + * @param __pos Index of character to search back from. + * @param __n Number of characters from s to consider. + * @return Index of last occurrence. + * + * Starting from @a __pos, searches backward for a character not + * contained in the first @a __n characters of @a __s within this string. + * If found, returns the index where it was found. If not found, + * returns npos. + */ + size_type + find_last_not_of(const _CharT* __s, size_type __pos, + size_type __n) const; + /** + * @brief Find last position of a character not in C string. + * @param __s C string containing characters to avoid. + * @param __pos Index of character to search back from (default end). + * @return Index of last occurrence. + * + * Starting from @a __pos, searches backward for a character + * not contained in @a __s within this string. If found, + * returns the index where it was found. If not found, returns + * npos. + */ + size_type + find_last_not_of(const _CharT* __s, size_type __pos = npos) const + { + __glibcxx_requires_string(__s); + return this->find_last_not_of(__s, __pos, traits_type::length(__s)); + } + + /** + * @brief Find last position of a different character. + * @param __c Character to avoid. + * @param __pos Index of character to search back from (default end). + * @return Index of last occurrence. + * + * Starting from @a __pos, searches backward for a character other than + * @a __c within this string. If found, returns the index where it was + * found. If not found, returns npos. + */ + size_type + find_last_not_of(_CharT __c, size_type __pos = npos) const + _GLIBCXX_NOEXCEPT; + + /** + * @brief Get a substring. + * @param __pos Index of first character (default 0). + * @param __n Number of characters in substring (default remainder). + * @return The new string. + * @throw std::out_of_range If __pos > size(). + * + * Construct and return a new string using the @a __n + * characters starting at @a __pos. If the string is too + * short, use the remainder of the characters. If @a __pos is + * beyond the end of the string, out_of_range is thrown. + */ + basic_string + substr(size_type __pos = 0, size_type __n = npos) const + { return basic_string(*this, + _M_check(__pos, "basic_string::substr"), __n); } + + /** + * @brief Compare to a string. + * @param __str String to compare against. + * @return Integer < 0, 0, or > 0. + * + * Returns an integer < 0 if this string is ordered before @a + * __str, 0 if their values are equivalent, or > 0 if this + * string is ordered after @a __str. Determines the effective + * length rlen of the strings to compare as the smallest of + * size() and str.size(). The function then compares the two + * strings by calling traits::compare(data(), str.data(),rlen). + * If the result of the comparison is nonzero returns it, + * otherwise the shorter one is ordered first. + */ + int + compare(const basic_string& __str) const + { + const size_type __size = this->size(); + const size_type __osize = __str.size(); + const size_type __len = std::min(__size, __osize); + + int __r = traits_type::compare(_M_data(), __str.data(), __len); + if (!__r) + __r = _S_compare(__size, __osize); + return __r; + } + + /** + * @brief Compare substring to a string. + * @param __pos Index of first character of substring. + * @param __n Number of characters in substring. + * @param __str String to compare against. + * @return Integer < 0, 0, or > 0. + * + * Form the substring of this string from the @a __n characters + * starting at @a __pos. Returns an integer < 0 if the + * substring is ordered before @a __str, 0 if their values are + * equivalent, or > 0 if the substring is ordered after @a + * __str. Determines the effective length rlen of the strings + * to compare as the smallest of the length of the substring + * and @a __str.size(). The function then compares the two + * strings by calling + * traits::compare(substring.data(),str.data(),rlen). If the + * result of the comparison is nonzero returns it, otherwise + * the shorter one is ordered first. + */ + int + compare(size_type __pos, size_type __n, const basic_string& __str) const; + + /** + * @brief Compare substring to a substring. + * @param __pos1 Index of first character of substring. + * @param __n1 Number of characters in substring. + * @param __str String to compare against. + * @param __pos2 Index of first character of substring of str. + * @param __n2 Number of characters in substring of str. + * @return Integer < 0, 0, or > 0. + * + * Form the substring of this string from the @a __n1 + * characters starting at @a __pos1. Form the substring of @a + * __str from the @a __n2 characters starting at @a __pos2. + * Returns an integer < 0 if this substring is ordered before + * the substring of @a __str, 0 if their values are equivalent, + * or > 0 if this substring is ordered after the substring of + * @a __str. Determines the effective length rlen of the + * strings to compare as the smallest of the lengths of the + * substrings. The function then compares the two strings by + * calling + * traits::compare(substring.data(),str.substr(pos2,n2).data(),rlen). + * If the result of the comparison is nonzero returns it, + * otherwise the shorter one is ordered first. + */ + int + compare(size_type __pos1, size_type __n1, const basic_string& __str, + size_type __pos2, size_type __n2) const; + + /** + * @brief Compare to a C string. + * @param __s C string to compare against. + * @return Integer < 0, 0, or > 0. + * + * Returns an integer < 0 if this string is ordered before @a __s, 0 if + * their values are equivalent, or > 0 if this string is ordered after + * @a __s. Determines the effective length rlen of the strings to + * compare as the smallest of size() and the length of a string + * constructed from @a __s. The function then compares the two strings + * by calling traits::compare(data(),s,rlen). If the result of the + * comparison is nonzero returns it, otherwise the shorter one is + * ordered first. + */ + int + compare(const _CharT* __s) const; + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 5 String::compare specification questionable + /** + * @brief Compare substring to a C string. + * @param __pos Index of first character of substring. + * @param __n1 Number of characters in substring. + * @param __s C string to compare against. + * @return Integer < 0, 0, or > 0. + * + * Form the substring of this string from the @a __n1 + * characters starting at @a pos. Returns an integer < 0 if + * the substring is ordered before @a __s, 0 if their values + * are equivalent, or > 0 if the substring is ordered after @a + * __s. Determines the effective length rlen of the strings to + * compare as the smallest of the length of the substring and + * the length of a string constructed from @a __s. The + * function then compares the two string by calling + * traits::compare(substring.data(),__s,rlen). If the result of + * the comparison is nonzero returns it, otherwise the shorter + * one is ordered first. + */ + int + compare(size_type __pos, size_type __n1, const _CharT* __s) const; + + /** + * @brief Compare substring against a character %array. + * @param __pos Index of first character of substring. + * @param __n1 Number of characters in substring. + * @param __s character %array to compare against. + * @param __n2 Number of characters of s. + * @return Integer < 0, 0, or > 0. + * + * Form the substring of this string from the @a __n1 + * characters starting at @a __pos. Form a string from the + * first @a __n2 characters of @a __s. Returns an integer < 0 + * if this substring is ordered before the string from @a __s, + * 0 if their values are equivalent, or > 0 if this substring + * is ordered after the string from @a __s. Determines the + * effective length rlen of the strings to compare as the + * smallest of the length of the substring and @a __n2. The + * function then compares the two strings by calling + * traits::compare(substring.data(),s,rlen). If the result of + * the comparison is nonzero returns it, otherwise the shorter + * one is ordered first. + * + * NB: s must have at least n2 characters, '\\0' has + * no special meaning. + */ + int + compare(size_type __pos, size_type __n1, const _CharT* __s, + size_type __n2) const; + }; +_GLIBCXX_END_NAMESPACE_CXX11 +#else // !_GLIBCXX_USE_CXX11_ABI + // Reference-counted COW string implentation + /** * @class basic_string basic_string.h <string> * @brief Managing sequences of characters and character-like objects. @@ -2371,6 +4765,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION compare(size_type __pos, size_type __n1, const _CharT* __s, size_type __n2) const; }; +#endif // !_GLIBCXX_USE_CXX11_ABI // operator+ /** @@ -2419,7 +4814,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _CharT, typename _Traits, typename _Alloc> inline basic_string<_CharT, _Traits, _Alloc> operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs, - const _CharT* __rhs) + const _CharT* __rhs) { basic_string<_CharT, _Traits, _Alloc> __str(__lhs); __str.append(__rhs); @@ -2737,6 +5132,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION basic_string<_CharT, _Traits, _Alloc>& __rhs) { __lhs.swap(__rhs); } + /** * @brief Read stream into a string. * @param __is Input stream. @@ -2852,6 +5248,7 @@ _GLIBCXX_END_NAMESPACE_VERSION namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION +_GLIBCXX_BEGIN_NAMESPACE_CXX11 // 21.4 Numeric Conversions [string.conversions]. inline int @@ -3058,6 +5455,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } #endif +_GLIBCXX_END_NAMESPACE_CXX11 _GLIBCXX_END_NAMESPACE_VERSION } // namespace @@ -3147,21 +5545,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION inline namespace string_literals { + _GLIBCXX_DEFAULT_ABI_TAG inline basic_string<char> operator""s(const char* __str, size_t __len) { return basic_string<char>{__str, __len}; } #ifdef _GLIBCXX_USE_WCHAR_T + _GLIBCXX_DEFAULT_ABI_TAG inline basic_string<wchar_t> operator""s(const wchar_t* __str, size_t __len) { return basic_string<wchar_t>{__str, __len}; } #endif #ifdef _GLIBCXX_USE_C99_STDINT_TR1 + _GLIBCXX_DEFAULT_ABI_TAG inline basic_string<char16_t> operator""s(const char16_t* __str, size_t __len) { return basic_string<char16_t>{__str, __len}; } + _GLIBCXX_DEFAULT_ABI_TAG inline basic_string<char32_t> operator""s(const char32_t* __str, size_t __len) { return basic_string<char32_t>{__str, __len}; } diff --git a/libstdc++-v3/include/bits/basic_string.tcc b/libstdc++-v3/include/bits/basic_string.tcc index f8907c0..30b3f4b 100644 --- a/libstdc++-v3/include/bits/basic_string.tcc +++ b/libstdc++-v3/include/bits/basic_string.tcc @@ -33,6 +33,8 @@ // Written by Jason Merrill based upon the specification by Takanori Adachi // in ANSI X3J16/94-0013R2. Rewritten by Nathan Myers to ISO-14882. +// Non-reference-counted implementation written by Paolo Carlini and +// updated by Jonathan Wakely for ISO-14882-2011. #ifndef _BASIC_STRING_TCC #define _BASIC_STRING_TCC 1 @@ -45,6 +47,448 @@ namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION +#if _GLIBCXX_USE_CXX11_ABI + + template<typename _CharT, typename _Traits, typename _Alloc> + const typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>::npos; + + template<typename _CharT, typename _Traits, typename _Alloc> + void + basic_string<_CharT, _Traits, _Alloc>:: + swap(basic_string& __s) _GLIBCXX_NOEXCEPT + { + if (this == &__s) + return; + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 431. Swapping containers with unequal allocators. + // TODO propagation traits + std::__alloc_swap<allocator_type>::_S_do_it(_M_get_allocator(), + __s._M_get_allocator()); + + if (_M_is_local()) + if (__s._M_is_local()) + { + if (length() && __s.length()) + { + _CharT __tmp_data[_S_local_capacity + 1]; + traits_type::copy(__tmp_data, __s._M_local_buf, + _S_local_capacity + 1); + traits_type::copy(__s._M_local_buf, _M_local_buf, + _S_local_capacity + 1); + traits_type::copy(_M_local_buf, __tmp_data, + _S_local_capacity + 1); + } + else if (__s.length()) + { + traits_type::copy(_M_local_buf, __s._M_local_buf, + _S_local_capacity + 1); + _M_length(__s.length()); + __s._M_set_length(0); + return; + } + else if (length()) + { + traits_type::copy(__s._M_local_buf, _M_local_buf, + _S_local_capacity + 1); + __s._M_length(length()); + _M_set_length(0); + return; + } + } + else + { + const size_type __tmp_capacity = __s._M_allocated_capacity; + traits_type::copy(__s._M_local_buf, _M_local_buf, + _S_local_capacity + 1); + _M_data(__s._M_data()); + __s._M_data(__s._M_local_buf); + _M_capacity(__tmp_capacity); + } + else + { + const size_type __tmp_capacity = _M_allocated_capacity; + if (__s._M_is_local()) + { + traits_type::copy(_M_local_buf, __s._M_local_buf, + _S_local_capacity + 1); + __s._M_data(_M_data()); + _M_data(_M_local_buf); + } + else + { + pointer __tmp_ptr = _M_data(); + _M_data(__s._M_data()); + __s._M_data(__tmp_ptr); + _M_capacity(__s._M_allocated_capacity); + } + __s._M_capacity(__tmp_capacity); + } + + const size_type __tmp_length = length(); + _M_length(__s.length()); + __s._M_length(__tmp_length); + } + + template<typename _CharT, typename _Traits, typename _Alloc> + typename basic_string<_CharT, _Traits, _Alloc>::pointer + basic_string<_CharT, _Traits, _Alloc>:: + _M_create(size_type& __capacity, size_type __old_capacity) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 83. String::npos vs. string::max_size() + if (__capacity > max_size()) + std::__throw_length_error(__N("basic_string::_M_create")); + + // The below implements an exponential growth policy, necessary to + // meet amortized linear time requirements of the library: see + // http://gcc.gnu.org/ml/libstdc++/2001-07/msg00085.html. + if (__capacity > __old_capacity && __capacity < 2 * __old_capacity) + { + __capacity = 2 * __old_capacity; + // Never allocate a string bigger than max_size. + if (__capacity > max_size()) + __capacity = max_size(); + } + + // NB: Need an array of char_type[__capacity], plus a terminating + // null char_type() element. + return _Alloc_traits::allocate(_M_get_allocator(), __capacity + 1); + } + + // NB: This is the special case for Input Iterators, used in + // istreambuf_iterators, etc. + // Input Iterators have a cost structure very different from + // pointers, calling for a different coding style. + template<typename _CharT, typename _Traits, typename _Alloc> + template<typename _InIterator> + void + basic_string<_CharT, _Traits, _Alloc>:: + _M_construct(_InIterator __beg, _InIterator __end, + std::input_iterator_tag) + { + size_type __len = 0; + size_type __capacity = size_type(_S_local_capacity); + + while (__beg != __end && __len < __capacity) + { + _M_data()[__len++] = *__beg; + ++__beg; + } + + __try + { + while (__beg != __end) + { + if (__len == __capacity) + { + // Allocate more space. + __capacity = __len + 1; + pointer __another = _M_create(__capacity, __len); + this->_S_copy(__another, _M_data(), __len); + _M_dispose(); + _M_data(__another); + _M_capacity(__capacity); + } + _M_data()[__len++] = *__beg; + ++__beg; + } + } + __catch(...) + { + _M_dispose(); + __throw_exception_again; + } + + _M_set_length(__len); + } + + template<typename _CharT, typename _Traits, typename _Alloc> + template<typename _InIterator> + void + basic_string<_CharT, _Traits, _Alloc>:: + _M_construct(_InIterator __beg, _InIterator __end, + std::forward_iterator_tag) + { + // NB: Not required, but considered best practice. + if (__gnu_cxx::__is_null_pointer(__beg) && __beg != __end) + std::__throw_logic_error(__N("basic_string::" + "_M_construct null not valid")); + + size_type __dnew = static_cast<size_type>(std::distance(__beg, __end)); + + if (__dnew > size_type(_S_local_capacity)) + { + _M_data(_M_create(__dnew, size_type(0))); + _M_capacity(__dnew); + } + + // Check for out_of_range and length_error exceptions. + __try + { this->_S_copy_chars(_M_data(), __beg, __end); } + __catch(...) + { + _M_dispose(); + __throw_exception_again; + } + + _M_set_length(__dnew); + } + + template<typename _CharT, typename _Traits, typename _Alloc> + void + basic_string<_CharT, _Traits, _Alloc>:: + _M_construct(size_type __n, _CharT __c) + { + if (__n > size_type(_S_local_capacity)) + { + _M_data(_M_create(__n, size_type(0))); + _M_capacity(__n); + } + + if (__n) + this->_S_assign(_M_data(), __n, __c); + + _M_set_length(__n); + } + + template<typename _CharT, typename _Traits, typename _Alloc> + void + basic_string<_CharT, _Traits, _Alloc>:: + _M_assign(const basic_string& __str) + { + if (this != &__str) + { + const size_type __rsize = __str.length(); + const size_type __capacity = capacity(); + + if (__rsize > __capacity) + { + size_type __new_capacity = __rsize; + pointer __tmp = _M_create(__new_capacity, __capacity); + _M_dispose(); + _M_data(__tmp); + _M_capacity(__new_capacity); + } + + if (__rsize) + this->_S_copy(_M_data(), __str._M_data(), __rsize); + + _M_set_length(__rsize); + } + } + + template<typename _CharT, typename _Traits, typename _Alloc> + void + basic_string<_CharT, _Traits, _Alloc>:: + reserve(size_type __res) + { + // Make sure we don't shrink below the current size. + if (__res < length()) + __res = length(); + + const size_type __capacity = capacity(); + if (__res != __capacity) + { + if (__res > __capacity + || __res > size_type(_S_local_capacity)) + { + pointer __tmp = _M_create(__res, __capacity); + this->_S_copy(__tmp, _M_data(), length() + 1); + _M_dispose(); + _M_data(__tmp); + _M_capacity(__res); + } + else if (!_M_is_local()) + { + this->_S_copy(_M_local_data(), _M_data(), length() + 1); + _M_destroy(__capacity); + _M_data(_M_local_data()); + } + } + } + + template<typename _CharT, typename _Traits, typename _Alloc> + void + basic_string<_CharT, _Traits, _Alloc>:: + _M_mutate(size_type __pos, size_type __len1, const _CharT* __s, + size_type __len2) + { + const size_type __how_much = length() - __pos - __len1; + + size_type __new_capacity = length() + __len2 - __len1; + pointer __r = _M_create(__new_capacity, capacity()); + + if (__pos) + this->_S_copy(__r, _M_data(), __pos); + if (__s && __len2) + this->_S_copy(__r + __pos, __s, __len2); + if (__how_much) + this->_S_copy(__r + __pos + __len2, + _M_data() + __pos + __len1, __how_much); + + _M_dispose(); + _M_data(__r); + _M_capacity(__new_capacity); + } + + template<typename _CharT, typename _Traits, typename _Alloc> + void + basic_string<_CharT, _Traits, _Alloc>:: + _M_erase(size_type __pos, size_type __n) + { + const size_type __how_much = length() - __pos - __n; + + if (__how_much && __n) + this->_S_move(_M_data() + __pos, _M_data() + __pos + __n, __how_much); + + _M_set_length(length() - __n); + } + + template<typename _CharT, typename _Traits, typename _Alloc> + void + basic_string<_CharT, _Traits, _Alloc>:: + resize(size_type __n, _CharT __c) + { + const size_type __size = this->size(); + if (__size < __n) + this->append(__n - __size, __c); + else if (__n < __size) + this->_M_erase(__n, __size - __n); + } + + template<typename _CharT, typename _Traits, typename _Alloc> + basic_string<_CharT, _Traits, _Alloc>& + basic_string<_CharT, _Traits, _Alloc>:: + _M_append(const _CharT* __s, size_type __n) + { + const size_type __len = __n + this->size(); + + if (__len <= this->capacity()) + { + if (__n) + this->_S_copy(this->_M_data() + this->size(), __s, __n); + } + else + this->_M_mutate(this->size(), size_type(0), __s, __n); + + this->_M_set_length(__len); + return *this; + } + + template<typename _CharT, typename _Traits, typename _Alloc> + template<typename _InputIterator> + basic_string<_CharT, _Traits, _Alloc>& + basic_string<_CharT, _Traits, _Alloc>:: + _M_replace_dispatch(const_iterator __i1, const_iterator __i2, + _InputIterator __k1, _InputIterator __k2, + std::__false_type) + { + const basic_string __s(__k1, __k2); + const size_type __n1 = __i2 - __i1; + return _M_replace(__i1 - begin(), __n1, __s._M_data(), + __s.size()); + } + + template<typename _CharT, typename _Traits, typename _Alloc> + basic_string<_CharT, _Traits, _Alloc>& + basic_string<_CharT, _Traits, _Alloc>:: + _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2, + _CharT __c) + { + _M_check_length(__n1, __n2, "basic_string::_M_replace_aux"); + + const size_type __old_size = this->size(); + const size_type __new_size = __old_size + __n2 - __n1; + + if (__new_size <= this->capacity()) + { + _CharT* __p = this->_M_data() + __pos1; + + const size_type __how_much = __old_size - __pos1 - __n1; + if (__how_much && __n1 != __n2) + this->_S_move(__p + __n2, __p + __n1, __how_much); + } + else + this->_M_mutate(__pos1, __n1, 0, __n2); + + if (__n2) + this->_S_assign(this->_M_data() + __pos1, __n2, __c); + + this->_M_set_length(__new_size); + return *this; + } + + template<typename _CharT, typename _Traits, typename _Alloc> + basic_string<_CharT, _Traits, _Alloc>& + basic_string<_CharT, _Traits, _Alloc>:: + _M_replace(size_type __pos, size_type __len1, const _CharT* __s, + const size_type __len2) + { + _M_check_length(__len1, __len2, "basic_string::_M_replace"); + + const size_type __old_size = this->size(); + const size_type __new_size = __old_size + __len2 - __len1; + + if (__new_size <= this->capacity()) + { + _CharT* __p = this->_M_data() + __pos; + + const size_type __how_much = __old_size - __pos - __len1; + if (_M_disjunct(__s)) + { + if (__how_much && __len1 != __len2) + this->_S_move(__p + __len2, __p + __len1, __how_much); + if (__len2) + this->_S_copy(__p, __s, __len2); + } + else + { + // Work in-place. + if (__len2 && __len2 <= __len1) + this->_S_move(__p, __s, __len2); + if (__how_much && __len1 != __len2) + this->_S_move(__p + __len2, __p + __len1, __how_much); + if (__len2 > __len1) + { + if (__s + __len2 <= __p + __len1) + this->_S_move(__p, __s, __len2); + else if (__s >= __p + __len1) + this->_S_copy(__p, __s + __len2 - __len1, __len2); + else + { + const size_type __nleft = (__p + __len1) - __s; + this->_S_move(__p, __s, __nleft); + this->_S_copy(__p + __nleft, __p + __len2, + __len2 - __nleft); + } + } + } + } + else + this->_M_mutate(__pos, __len1, __s, __len2); + + this->_M_set_length(__new_size); + return *this; + } + + template<typename _CharT, typename _Traits, typename _Alloc> + typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + copy(_CharT* __s, size_type __n, size_type __pos) const + { + _M_check(__pos, "basic_string::copy"); + __n = _M_limit(__pos, __n); + __glibcxx_requires_string_len(__s, __n); + if (__n) + _S_copy(__s, _M_data() + __pos, __n); + // 21.3.5.7 par 3: do not append null. (good.) + return __n; + } + +#else // !_GLIBCXX_USE_CXX11_ABI + template<typename _CharT, typename _Traits, typename _Alloc> const typename basic_string<_CharT, _Traits, _Alloc>::size_type basic_string<_CharT, _Traits, _Alloc>:: @@ -686,6 +1130,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_copy(_M_data() + __pos1, __s, __n2); return *this; } + + template<typename _CharT, typename _Traits, typename _Alloc> + typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + copy(_CharT* __s, size_type __n, size_type __pos) const + { + _M_check(__pos, "basic_string::copy"); + __n = _M_limit(__pos, __n); + __glibcxx_requires_string_len(__s, __n); + if (__n) + _M_copy(__s, _M_data() + __pos, __n); + // 21.3.5.7 par 3: do not append null. (good.) + return __n; + } +#endif // !_GLIBCXX_USE_CXX11_ABI template<typename _CharT, typename _Traits, typename _Alloc> basic_string<_CharT, _Traits, _Alloc> @@ -720,20 +1179,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _CharT, typename _Traits, typename _Alloc> typename basic_string<_CharT, _Traits, _Alloc>::size_type basic_string<_CharT, _Traits, _Alloc>:: - copy(_CharT* __s, size_type __n, size_type __pos) const - { - _M_check(__pos, "basic_string::copy"); - __n = _M_limit(__pos, __n); - __glibcxx_requires_string_len(__s, __n); - if (__n) - _M_copy(__s, _M_data() + __pos, __n); - // 21.3.5.7 par 3: do not append null. (good.) - return __n; - } - - template<typename _CharT, typename _Traits, typename _Alloc> - typename basic_string<_CharT, _Traits, _Alloc>::size_type - basic_string<_CharT, _Traits, _Alloc>:: find(const _CharT* __s, size_type __pos, size_type __n) const { __glibcxx_requires_string_len(__s, __n); diff --git a/libstdc++-v3/include/bits/c++config b/libstdc++-v3/include/bits/c++config index 337f1e5..cffb065 100644 --- a/libstdc++-v3/include/bits/c++config +++ b/libstdc++-v3/include/bits/c++config @@ -193,14 +193,30 @@ namespace std #endif } -// Use abi_tag("cxx11") +#define _GLIBCXX_USE_DUAL_ABI + +#if ! _GLIBCXX_USE_DUAL_ABI +// Ignore any pre-defined value of _GLIBCXX_USE_CXX11_ABI +# undef _GLIBCXX_USE_CXX11_ABI +#endif + #ifndef _GLIBCXX_USE_CXX11_ABI #define _GLIBCXX_USE_CXX11_ABI #endif #if _GLIBCXX_USE_CXX11_ABI +namespace std +{ + inline namespace __cxx11 __attribute__((abi_tag)) { } +} +# define _GLIBCXX_NAMESPACE_CXX11 __cxx11:: +# define _GLIBCXX_BEGIN_NAMESPACE_CXX11 namespace __cxx11 { +# define _GLIBCXX_END_NAMESPACE_CXX11 } # define _GLIBCXX_DEFAULT_ABI_TAG _GLIBCXX_ABI_TAG_CXX11 #else +# define _GLIBCXX_NAMESPACE_CXX11 +# define _GLIBCXX_BEGIN_NAMESPACE_CXX11 +# define _GLIBCXX_END_NAMESPACE_CXX11 # define _GLIBCXX_DEFAULT_ABI_TAG #endif @@ -370,6 +386,15 @@ namespace std # define _GLIBCXX_BEGIN_NAMESPACE_LDBL # define _GLIBCXX_END_NAMESPACE_LDBL #endif +#if _GLIBCXX_USE_CXX11_ABI +# define _GLIBCXX_NAMESPACE_LDBL_OR_CXX11 _GLIBCXX_NAMESPACE_CXX11 +# define _GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11 _GLIBCXX_BEGIN_NAMESPACE_CXX11 +# define _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 _GLIBCXX_END_NAMESPACE_CXX11 +#else +# define _GLIBCXX_NAMESPACE_LDBL_OR_CXX11 _GLIBCXX_NAMESPACE_LDBL +# define _GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11 _GLIBCXX_BEGIN_NAMESPACE_LDBL +# define _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 _GLIBCXX_END_NAMESPACE_LDBL +#endif // Assert. #if !defined(_GLIBCXX_DEBUG) && !defined(_GLIBCXX_PARALLEL) diff --git a/libstdc++-v3/include/bits/locale_classes.h b/libstdc++-v3/include/bits/locale_classes.h index 6dd452a..9c1f8e7 100644 --- a/libstdc++-v3/include/bits/locale_classes.h +++ b/libstdc++-v3/include/bits/locale_classes.h @@ -212,6 +212,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @brief Return locale name. * @return Locale name or "*" if unnamed. */ + _GLIBCXX_DEFAULT_ABI_TAG string name() const; @@ -321,6 +322,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION void _M_coalesce(const locale& __base, const locale& __add, category __cat); + +#if _GLIBCXX_USE_CXX11_ABI + static const id* const _S_twinned_facets[]; +#endif }; @@ -419,6 +424,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION facet& operator=(const facet&); // Not defined. + + class __shim; + + const facet* _M_sso_shim(const id*) const; + const facet* _M_cow_shim(const id*) const; }; @@ -563,8 +573,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_init_facet(_Facet* __facet) { _M_install_facet(&_Facet::id, __facet); } + template<typename _Facet> + void + _M_init_facet_unchecked(_Facet* __facet) + { + __facet->_M_add_reference(); + _M_facets[_Facet::id._M_id()] = __facet; + } + void _M_install_cache(const facet*, size_t); + + void _M_init_extra(facet**); + void _M_init_extra(void*, void*, const char*, const char*); }; @@ -581,7 +602,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * collate facet. */ template<typename _CharT> - class collate : public locale::facet + class _GLIBCXX_NAMESPACE_CXX11 collate : public locale::facet { public: // Types: @@ -755,7 +776,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// class collate_byname [22.2.4.2]. template<typename _CharT> - class collate_byname : public collate<_CharT> + class _GLIBCXX_NAMESPACE_CXX11 collate_byname : public collate<_CharT> { public: //@{ diff --git a/libstdc++-v3/include/bits/locale_facets.h b/libstdc++-v3/include/bits/locale_facets.h index 234693b..ce1ffae 100644 --- a/libstdc++-v3/include/bits/locale_facets.h +++ b/libstdc++-v3/include/bits/locale_facets.h @@ -54,8 +54,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // NB: Don't instantiate required wchar_t facets if no wchar_t support. #ifdef _GLIBCXX_USE_WCHAR_T # define _GLIBCXX_NUM_FACETS 28 +# define _GLIBCXX_NUM_CXX11_FACETS 16 #else # define _GLIBCXX_NUM_FACETS 14 +# define _GLIBCXX_NUM_CXX11_FACETS 8 #endif // Convert string to numeric value of type _Tp and store results. @@ -1623,6 +1625,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } } +_GLIBCXX_BEGIN_NAMESPACE_CXX11 + /** * @brief Primary class template numpunct. * @ingroup locales @@ -1896,6 +1900,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ~numpunct_byname() { } }; +_GLIBCXX_END_NAMESPACE_CXX11 + _GLIBCXX_BEGIN_NAMESPACE_LDBL /** @@ -2107,11 +2113,13 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL /// Destructor. virtual ~num_get() { } + _GLIBCXX_DEFAULT_ABI_TAG iter_type _M_extract_float(iter_type, iter_type, ios_base&, ios_base::iostate&, string&) const; template<typename _ValueT> + _GLIBCXX_DEFAULT_ABI_TAG iter_type _M_extract_int(iter_type, iter_type, ios_base&, ios_base::iostate&, _ValueT&) const; diff --git a/libstdc++-v3/include/bits/locale_facets.tcc b/libstdc++-v3/include/bits/locale_facets.tcc index 200e099..3a4aedc 100644 --- a/libstdc++-v3/include/bits/locale_facets.tcc +++ b/libstdc++-v3/include/bits/locale_facets.tcc @@ -143,6 +143,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX_BEGIN_NAMESPACE_LDBL template<typename _CharT, typename _InIter> + _GLIBCXX_DEFAULT_ABI_TAG _InIter num_get<_CharT, _InIter>:: _M_extract_float(_InIter __beg, _InIter __end, ios_base& __io, @@ -368,6 +369,7 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL template<typename _CharT, typename _InIter> template<typename _ValueT> + _GLIBCXX_DEFAULT_ABI_TAG _InIter num_get<_CharT, _InIter>:: _M_extract_int(_InIter __beg, _InIter __end, ios_base& __io, @@ -1290,8 +1292,8 @@ _GLIBCXX_END_NAMESPACE_LDBL // Inhibit implicit instantiations for required instantiations, // which are defined via explicit instantiations elsewhere. #if _GLIBCXX_EXTERN_TEMPLATE - extern template class numpunct<char>; - extern template class numpunct_byname<char>; + extern template class _GLIBCXX_NAMESPACE_CXX11 numpunct<char>; + extern template class _GLIBCXX_NAMESPACE_CXX11 numpunct_byname<char>; extern template class _GLIBCXX_NAMESPACE_LDBL num_get<char>; extern template class _GLIBCXX_NAMESPACE_LDBL num_put<char>; extern template class ctype_byname<char>; @@ -1329,8 +1331,8 @@ _GLIBCXX_END_NAMESPACE_LDBL has_facet<num_get<char> >(const locale&); #ifdef _GLIBCXX_USE_WCHAR_T - extern template class numpunct<wchar_t>; - extern template class numpunct_byname<wchar_t>; + extern template class _GLIBCXX_NAMESPACE_CXX11 numpunct<wchar_t>; + extern template class _GLIBCXX_NAMESPACE_CXX11 numpunct_byname<wchar_t>; extern template class _GLIBCXX_NAMESPACE_LDBL num_get<wchar_t>; extern template class _GLIBCXX_NAMESPACE_LDBL num_put<wchar_t>; extern template class ctype_byname<wchar_t>; diff --git a/libstdc++-v3/include/bits/locale_facets_nonio.h b/libstdc++-v3/include/bits/locale_facets_nonio.h index 1b0aff9..9c629e2 100644 --- a/libstdc++-v3/include/bits/locale_facets_nonio.h +++ b/libstdc++-v3/include/bits/locale_facets_nonio.h @@ -347,6 +347,8 @@ namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION +_GLIBCXX_BEGIN_NAMESPACE_CXX11 + /** * @brief Primary class template time_get. * @ingroup locales @@ -694,6 +696,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ~time_get_byname() { } }; +_GLIBCXX_END_NAMESPACE_CXX11 + /** * @brief Primary class template time_put. * @ingroup locales @@ -918,6 +922,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } } +_GLIBCXX_BEGIN_NAMESPACE_CXX11 + /** * @brief Primary class template moneypunct. * @ingroup locales @@ -1346,7 +1352,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _CharT, bool _Intl> const bool moneypunct_byname<_CharT, _Intl>::intl; -_GLIBCXX_BEGIN_NAMESPACE_LDBL +_GLIBCXX_END_NAMESPACE_CXX11 + +_GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11 /** * @brief Primary class template money_get. @@ -1462,7 +1470,8 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL * value returned. @see get() for details. */ // XXX GLIBCXX_ABI Deprecated -#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ +#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ \ + && _GLIBCXX_USE_CXX11_ABI == 0 virtual iter_type __do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io, ios_base::iostate& __err, double& __units) const; @@ -1484,7 +1493,8 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL ios_base::iostate& __err, string_type& __digits) const; // XXX GLIBCXX_ABI Deprecated -#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ +#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ \ + && _GLIBCXX_USE_CXX11_ABI == 0 virtual iter_type do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io, ios_base::iostate& __err, long double& __units) const; @@ -1605,7 +1615,8 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL * @return Iterator after writing. */ // XXX GLIBCXX_ABI Deprecated -#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ +#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ \ + && _GLIBCXX_USE_CXX11_ABI == 0 virtual iter_type __do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, double __units) const; @@ -1639,7 +1650,8 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL const string_type& __digits) const; // XXX GLIBCXX_ABI Deprecated -#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ +#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ \ + && _GLIBCXX_USE_CXX11_ABI == 0 virtual iter_type do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, long double __units) const; @@ -1654,7 +1666,7 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL template<typename _CharT, typename _OutIter> locale::id money_put<_CharT, _OutIter>::id; -_GLIBCXX_END_NAMESPACE_LDBL +_GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 /** * @brief Messages facet base class providing catalog typedef. @@ -1665,6 +1677,8 @@ _GLIBCXX_END_NAMESPACE_LDBL typedef int catalog; }; +_GLIBCXX_BEGIN_NAMESPACE_CXX11 + /** * @brief Primary class template messages. * @ingroup locales @@ -1886,6 +1900,8 @@ _GLIBCXX_END_NAMESPACE_LDBL { } }; +_GLIBCXX_END_NAMESPACE_CXX11 + _GLIBCXX_END_NAMESPACE_VERSION } // namespace diff --git a/libstdc++-v3/include/bits/locale_facets_nonio.tcc b/libstdc++-v3/include/bits/locale_facets_nonio.tcc index 42c3504..200168d 100644 --- a/libstdc++-v3/include/bits/locale_facets_nonio.tcc +++ b/libstdc++-v3/include/bits/locale_facets_nonio.tcc @@ -128,7 +128,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } } -_GLIBCXX_BEGIN_NAMESPACE_LDBL +_GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11 template<typename _CharT, typename _InIter> template<bool _Intl> @@ -348,7 +348,8 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL return __beg; } -#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ +#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ \ + && _GLIBCXX_USE_CXX11_ABI == 0 template<typename _CharT, typename _InIter> _InIter money_get<_CharT, _InIter>:: @@ -559,7 +560,8 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL return __s; } -#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ +#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ \ + && _GLIBCXX_USE_CXX11_ABI == 0 template<typename _CharT, typename _OutIter> _OutIter money_put<_CharT, _OutIter>:: @@ -614,7 +616,7 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL { return __intl ? _M_insert<true>(__s, __io, __fill, __digits) : _M_insert<false>(__s, __io, __fill, __digits); } -_GLIBCXX_END_NAMESPACE_LDBL +_GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 // NB: Not especially useful. Without an ios_base object or some // kind of locale reference, we are left clawing at the air where @@ -1222,8 +1224,8 @@ _GLIBCXX_END_NAMESPACE_LDBL extern template class moneypunct<char, true>; extern template class moneypunct_byname<char, false>; extern template class moneypunct_byname<char, true>; - extern template class _GLIBCXX_NAMESPACE_LDBL money_get<char>; - extern template class _GLIBCXX_NAMESPACE_LDBL money_put<char>; + extern template class _GLIBCXX_NAMESPACE_LDBL_OR_CXX11 money_get<char>; + extern template class _GLIBCXX_NAMESPACE_LDBL_OR_CXX11 money_put<char>; extern template class __timepunct<char>; extern template class time_put<char>; extern template class time_put_byname<char>; @@ -1297,8 +1299,8 @@ _GLIBCXX_END_NAMESPACE_LDBL extern template class moneypunct<wchar_t, true>; extern template class moneypunct_byname<wchar_t, false>; extern template class moneypunct_byname<wchar_t, true>; - extern template class _GLIBCXX_NAMESPACE_LDBL money_get<wchar_t>; - extern template class _GLIBCXX_NAMESPACE_LDBL money_put<wchar_t>; + extern template class _GLIBCXX_NAMESPACE_LDBL_OR_CXX11 money_get<wchar_t>; + extern template class _GLIBCXX_NAMESPACE_LDBL_OR_CXX11 money_put<wchar_t>; extern template class __timepunct<wchar_t>; extern template class time_put<wchar_t>; extern template class time_put_byname<wchar_t>; diff --git a/libstdc++-v3/include/bits/localefwd.h b/libstdc++-v3/include/bits/localefwd.h index 3025c22..aa24a98 100644 --- a/libstdc++-v3/include/bits/localefwd.h +++ b/libstdc++-v3/include/bits/localefwd.h @@ -150,21 +150,27 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL template<typename _CharT, typename _OutIter = ostreambuf_iterator<_CharT> > class num_put; _GLIBCXX_END_NAMESPACE_LDBL +_GLIBCXX_BEGIN_NAMESPACE_CXX11 template<typename _CharT> class numpunct; template<typename _CharT> class numpunct_byname; +_GLIBCXX_END_NAMESPACE_CXX11 +_GLIBCXX_BEGIN_NAMESPACE_CXX11 // 22.2.4 collation template<typename _CharT> class collate; - template<typename _CharT> class - collate_byname; + template<typename _CharT> + class collate_byname; +_GLIBCXX_END_NAMESPACE_CXX11 // 22.2.5 date and time class time_base; +_GLIBCXX_BEGIN_NAMESPACE_CXX11 template<typename _CharT, typename _InIter = istreambuf_iterator<_CharT> > class time_get; template<typename _CharT, typename _InIter = istreambuf_iterator<_CharT> > class time_get_byname; +_GLIBCXX_END_NAMESPACE_CXX11 template<typename _CharT, typename _OutIter = ostreambuf_iterator<_CharT> > class time_put; template<typename _CharT, typename _OutIter = ostreambuf_iterator<_CharT> > @@ -172,23 +178,27 @@ _GLIBCXX_END_NAMESPACE_LDBL // 22.2.6 money class money_base; -_GLIBCXX_BEGIN_NAMESPACE_LDBL +_GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11 template<typename _CharT, typename _InIter = istreambuf_iterator<_CharT> > class money_get; template<typename _CharT, typename _OutIter = ostreambuf_iterator<_CharT> > class money_put; -_GLIBCXX_END_NAMESPACE_LDBL +_GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 +_GLIBCXX_BEGIN_NAMESPACE_CXX11 template<typename _CharT, bool _Intl = false> class moneypunct; template<typename _CharT, bool _Intl = false> class moneypunct_byname; +_GLIBCXX_END_NAMESPACE_CXX11 // 22.2.7 message retrieval class messages_base; +_GLIBCXX_BEGIN_NAMESPACE_CXX11 template<typename _CharT> class messages; template<typename _CharT> class messages_byname; +_GLIBCXX_END_NAMESPACE_CXX11 _GLIBCXX_END_NAMESPACE_VERSION } // namespace std diff --git a/libstdc++-v3/include/bits/regex.h b/libstdc++-v3/include/bits/regex.h index 80b1de8..acdac5e 100644 --- a/libstdc++-v3/include/bits/regex.h +++ b/libstdc++-v3/include/bits/regex.h @@ -31,12 +31,14 @@ namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION +_GLIBCXX_BEGIN_NAMESPACE_CXX11 template<typename, typename> class basic_regex; template<typename, typename> class match_results; +_GLIBCXX_END_NAMESPACE_CXX11 _GLIBCXX_END_NAMESPACE_VERSION namespace __detail @@ -71,6 +73,7 @@ _GLIBCXX_END_NAMESPACE_VERSION } _GLIBCXX_BEGIN_NAMESPACE_VERSION +_GLIBCXX_BEGIN_NAMESPACE_CXX11 /** * @addtogroup regex @@ -1939,6 +1942,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION match_results<_Bi_iter, _Alloc>& __rhs) { __lhs.swap(__rhs); } +_GLIBCXX_END_NAMESPACE_CXX11 + // [7.11.2] Function template regex_match /** * @name Matching, Searching, and Replacing @@ -2407,6 +2412,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION //@} +_GLIBCXX_BEGIN_NAMESPACE_CXX11 + // std [28.12] Class template regex_iterator /** * An iterator adaptor that will provide repeated calls of regex_search over @@ -2770,6 +2777,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #endif //@} // group regex + +_GLIBCXX_END_NAMESPACE_CXX11 _GLIBCXX_END_NAMESPACE_VERSION } // namespace diff --git a/libstdc++-v3/include/bits/stl_list.h b/libstdc++-v3/include/bits/stl_list.h index 5f66afd..7e8e85c 100644 --- a/libstdc++-v3/include/bits/stl_list.h +++ b/libstdc++-v3/include/bits/stl_list.h @@ -292,10 +292,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER const _List_const_iterator<_Val>& __y) _GLIBCXX_NOEXCEPT { return __x._M_node != __y._M_node; } - +_GLIBCXX_BEGIN_NAMESPACE_CXX11 /// See bits/stl_deque.h's _Deque_base for an explanation. template<typename _Tp, typename _Alloc> - class _GLIBCXX_DEFAULT_ABI_TAG _List_base + class _List_base { protected: // NOTA BENE @@ -504,7 +504,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER * %empty. */ template<typename _Tp, typename _Alloc = std::allocator<_Tp> > - class _GLIBCXX_DEFAULT_ABI_TAG list : protected _List_base<_Tp, _Alloc> + class list : protected _List_base<_Tp, _Alloc> { // concept requirements typedef typename _Alloc::value_type _Alloc_value_type; @@ -1790,6 +1790,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER __builtin_abort(); } }; +_GLIBCXX_END_NAMESPACE_CXX11 /** * @brief List equality comparison. diff --git a/libstdc++-v3/include/bits/stringfwd.h b/libstdc++-v3/include/bits/stringfwd.h index 132b88e..13cf027 100644 --- a/libstdc++-v3/include/bits/stringfwd.h +++ b/libstdc++-v3/include/bits/stringfwd.h @@ -52,35 +52,43 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<class _CharT> struct char_traits; + template<> struct char_traits<char>; + +#ifdef _GLIBCXX_USE_WCHAR_T + template<> struct char_traits<wchar_t>; +#endif + +#if ((__cplusplus >= 201103L) \ + && defined(_GLIBCXX_USE_C99_STDINT_TR1)) + template<> struct char_traits<char16_t>; + template<> struct char_traits<char32_t>; +#endif + +_GLIBCXX_BEGIN_NAMESPACE_CXX11 + template<typename _CharT, typename _Traits = char_traits<_CharT>, typename _Alloc = allocator<_CharT> > class basic_string; - template<> struct char_traits<char>; - /// A string of @c char typedef basic_string<char> string; #ifdef _GLIBCXX_USE_WCHAR_T - template<> struct char_traits<wchar_t>; - /// A string of @c wchar_t typedef basic_string<wchar_t> wstring; #endif #if ((__cplusplus >= 201103L) \ && defined(_GLIBCXX_USE_C99_STDINT_TR1)) - - template<> struct char_traits<char16_t>; - template<> struct char_traits<char32_t>; - /// A string of @c char16_t typedef basic_string<char16_t> u16string; /// A string of @c char32_t typedef basic_string<char32_t> u32string; - #endif + +_GLIBCXX_END_NAMESPACE_CXX11 + /** @} */ _GLIBCXX_END_NAMESPACE_VERSION diff --git a/libstdc++-v3/include/std/iosfwd b/libstdc++-v3/include/std/iosfwd index ed8af5c..c770ada 100644 --- a/libstdc++-v3/include/std/iosfwd +++ b/libstdc++-v3/include/std/iosfwd @@ -88,6 +88,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _CharT, typename _Traits = char_traits<_CharT> > class basic_iostream; + +_GLIBCXX_BEGIN_NAMESPACE_CXX11 + template<typename _CharT, typename _Traits = char_traits<_CharT>, typename _Alloc = allocator<_CharT> > class basic_stringbuf; @@ -104,6 +107,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typename _Alloc = allocator<_CharT> > class basic_stringstream; +_GLIBCXX_END_NAMESPACE_CXX11 + template<typename _CharT, typename _Traits = char_traits<_CharT> > class basic_filebuf; diff --git a/libstdc++-v3/include/std/sstream b/libstdc++-v3/include/std/sstream index f074eda..a46e197 100644 --- a/libstdc++-v3/include/std/sstream +++ b/libstdc++-v3/include/std/sstream @@ -41,6 +41,7 @@ namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION +_GLIBCXX_BEGIN_NAMESPACE_CXX11 // [27.7.1] template class basic_stringbuf /** @@ -63,6 +64,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _CharT, typename _Traits, typename _Alloc> class basic_stringbuf : public basic_streambuf<_CharT, _Traits> { + struct __xfer_bufptrs; public: // Types: typedef _CharT char_type; @@ -117,9 +119,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION basic_stringbuf(const basic_stringbuf&) = delete; basic_stringbuf(basic_stringbuf&& __rhs) - : __streambuf_type(static_cast<const __streambuf_type&>(__rhs)), - _M_mode(__rhs._M_mode), _M_string(std::move(__rhs._M_string)) - { __rhs._M_stringbuf_init(__rhs._M_mode); } + : basic_stringbuf(std::move(__rhs), __xfer_bufptrs(__rhs, this)) + { __rhs._M_sync(const_cast<char_type*>(__rhs._M_string.data()), 0, 0); } // 27.8.2.2 Assign and swap: @@ -129,18 +130,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION basic_stringbuf& operator=(basic_stringbuf&& __rhs) { + __xfer_bufptrs __st{__rhs, this}; const __streambuf_type& __base = __rhs; __streambuf_type::operator=(__base); this->pubimbue(__rhs.getloc()); _M_mode = __rhs._M_mode; _M_string = std::move(__rhs._M_string); - __rhs._M_stringbuf_init(__rhs._M_mode); + __rhs._M_sync(const_cast<char_type*>(__rhs._M_string.data()), 0, 0); return *this; } void swap(basic_stringbuf& __rhs) { + __xfer_bufptrs __l_st{*this, std::__addressof(__rhs)}; + __xfer_bufptrs __r_st{__rhs, this}; __streambuf_type& __base = __rhs; __streambuf_type::swap(__base); __rhs.pubimbue(this->pubimbue(__rhs.getloc())); @@ -185,7 +189,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION void str(const __string_type& __s) { - // Cannot use _M_string = __s, since v3 strings are COW. + // Cannot use _M_string = __s, since v3 strings are COW + // (not always true now but assign() always works). _M_string.assign(__s.data(), __s.size()); _M_stringbuf_init(_M_mode); } @@ -286,6 +291,60 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // interface of basic_streambuf, taking just an int. void _M_pbump(char_type* __pbeg, char_type* __pend, off_type __off); + + private: +#if __cplusplus >= 201103L +#if _GLIBCXX_USE_CXX11_ABI + // This type captures the state of the gptr / pptr pointers as offsets + // so they can be restored in another object after moving the string. + struct __xfer_bufptrs + { + __xfer_bufptrs(const basic_stringbuf& __from, basic_stringbuf* __to) + : _M_to{__to}, _M_goff{-1, -1, -1}, _M_poff{-1, -1, -1} + { + const _CharT* __str = __from._M_string.data(); + if (__from.eback()) + { + _M_goff[0] = __from.eback() - __str; + _M_goff[1] = __from.gptr() - __str; + _M_goff[2] = __from.egptr() - __str; + } + if (__from.pbase()) + { + _M_poff[0] = __from.pbase() - __str; + _M_poff[1] = __from.pptr() - __from.pbase(); + _M_poff[2] = __from.epptr() - __str; + } + } + + ~__xfer_bufptrs() + { + char_type* __str = const_cast<char_type*>(_M_to->_M_string.data()); + if (_M_goff[0] != -1) + _M_to->setg(__str+_M_goff[0], __str+_M_goff[1], __str+_M_goff[2]); + if (_M_poff[0] != -1) + _M_to->_M_pbump(__str+_M_poff[0], __str+_M_poff[2], _M_poff[1]); + } + + basic_stringbuf* _M_to; + off_type _M_goff[3]; + off_type _M_poff[3]; + }; +#else + // This type does nothing when using Copy-On-Write strings. + struct __xfer_bufptrs + { + __xfer_bufptrs(const basic_stringbuf&, basic_stringbuf*) { } + }; +#endif + + // The move constructor initializes an __xfer_bufptrs temporary then + // delegates to this constructor to performs moves during its lifetime. + basic_stringbuf(basic_stringbuf&& __rhs, __xfer_bufptrs&&) + : __streambuf_type(static_cast<const __streambuf_type&>(__rhs)), + _M_mode(__rhs._M_mode), _M_string(std::move(__rhs._M_string)) + { } +#endif }; @@ -747,6 +806,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { __x.swap(__y); } #endif +_GLIBCXX_END_NAMESPACE_CXX11 _GLIBCXX_END_NAMESPACE_VERSION } // namespace diff --git a/libstdc++-v3/include/std/stdexcept b/libstdc++-v3/include/std/stdexcept index ff18405..c927f05 100644 --- a/libstdc++-v3/include/std/stdexcept +++ b/libstdc++-v3/include/std/stdexcept @@ -42,6 +42,64 @@ namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION +#if _GLIBCXX_USE_DUAL_ABI +#if _GLIBCXX_USE_CXX11_ABI + // Emulates an old COW string when the new std::string is in use. + struct __cow_string + { + union { + const char* _M_p; + char _M_bytes[sizeof(_M_p)]; + }; + + __cow_string(); + __cow_string(const std::string&); + __cow_string(const char*, size_t); + __cow_string(const __cow_string&) _GLIBCXX_USE_NOEXCEPT; + __cow_string& operator=(const __cow_string&) _GLIBCXX_USE_NOEXCEPT; + ~__cow_string(); +#if __cplusplus >= 201103L + __cow_string(__cow_string&&) noexcept; + __cow_string& operator=(__cow_string&&) noexcept; +#endif + }; + + typedef basic_string<char> __sso_string; +#else // _GLIBCXX_USE_CXX11_ABI + typedef basic_string<char> __cow_string; + + // Emulates a new SSO string when the old std::string is in use. + struct __sso_string + { + struct __str + { + const char* _M_p; + size_t _M_string_length; + char _M_local_buf[16]; + }; + + union { + __str _M_s; + char _M_bytes[sizeof(_M_s)]; + }; + + __sso_string() _GLIBCXX_USE_NOEXCEPT; + __sso_string(const std::string&); + __sso_string(const char*, size_t); + __sso_string(const __sso_string&); + __sso_string& operator=(const __sso_string&); + ~__sso_string(); +#if __cplusplus >= 201103L + __sso_string(__sso_string&&) noexcept; + __sso_string& operator=(__sso_string&&) noexcept; +#endif + }; +#endif // _GLIBCXX_USE_CXX11_ABI +#else // _GLIBCXX_USE_DUAL_ABI + typedef basic_string<char> __sso_string; + typedef basic_string<char> __cow_string; +#endif + /** * @addtogroup exceptions * @{ @@ -54,13 +112,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION */ class logic_error : public exception { - string _M_msg; + __cow_string _M_msg; public: /** Takes a character string describing the error. */ explicit logic_error(const string& __arg); +#if __cplusplus >= 201103L + explicit + logic_error(const char*); +#endif + +#if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_COPY_OPS + logic_error(const logic_error&) _GLIBCXX_USE_NOEXCEPT; + logic_error& operator=(const logic_error&) _GLIBCXX_USE_NOEXCEPT; +#endif + virtual ~logic_error() _GLIBCXX_USE_NOEXCEPT; /** Returns a C-style character string describing the general cause of @@ -75,6 +143,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { public: explicit domain_error(const string& __arg); +#if __cplusplus >= 201103L + explicit domain_error(const char*); +#endif virtual ~domain_error() _GLIBCXX_USE_NOEXCEPT; }; @@ -83,6 +154,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { public: explicit invalid_argument(const string& __arg); +#if __cplusplus >= 201103L + explicit invalid_argument(const char*); +#endif virtual ~invalid_argument() _GLIBCXX_USE_NOEXCEPT; }; @@ -92,6 +166,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { public: explicit length_error(const string& __arg); +#if __cplusplus >= 201103L + explicit length_error(const char*); +#endif virtual ~length_error() _GLIBCXX_USE_NOEXCEPT; }; @@ -101,6 +178,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { public: explicit out_of_range(const string& __arg); +#if __cplusplus >= 201103L + explicit out_of_range(const char*); +#endif virtual ~out_of_range() _GLIBCXX_USE_NOEXCEPT; }; @@ -111,13 +191,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION */ class runtime_error : public exception { - string _M_msg; + __cow_string _M_msg; public: /** Takes a character string describing the error. */ explicit runtime_error(const string& __arg); +#if __cplusplus >= 201103L + explicit + runtime_error(const char*); +#endif + +#if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_COPY_OPS + runtime_error(const runtime_error&) _GLIBCXX_USE_NOEXCEPT; + runtime_error& operator=(const runtime_error&) _GLIBCXX_USE_NOEXCEPT; +#endif + virtual ~runtime_error() _GLIBCXX_USE_NOEXCEPT; /** Returns a C-style character string describing the general cause of @@ -131,6 +221,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { public: explicit range_error(const string& __arg); +#if __cplusplus >= 201103L + explicit range_error(const char*); +#endif virtual ~range_error() _GLIBCXX_USE_NOEXCEPT; }; @@ -139,6 +232,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { public: explicit overflow_error(const string& __arg); +#if __cplusplus >= 201103L + explicit overflow_error(const char*); +#endif virtual ~overflow_error() _GLIBCXX_USE_NOEXCEPT; }; @@ -147,6 +243,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { public: explicit underflow_error(const string& __arg); +#if __cplusplus >= 201103L + explicit underflow_error(const char*); +#endif virtual ~underflow_error() _GLIBCXX_USE_NOEXCEPT; }; diff --git a/libstdc++-v3/include/std/system_error b/libstdc++-v3/include/std/system_error index ed17f55..786445e 100644 --- a/libstdc++-v3/include/std/system_error +++ b/libstdc++-v3/include/std/system_error @@ -46,7 +46,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION class error_code; class error_condition; - class error_category; class system_error; /// is_error_code_enum @@ -61,16 +60,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct is_error_condition_enum<errc> : public true_type { }; + inline namespace _V2 { /// error_category class error_category { public: -#ifdef _GLIBCXX_COMPATIBILITY_CXX0X - error_category() noexcept; -#else constexpr error_category() noexcept = default; -#endif virtual ~error_category(); @@ -80,9 +76,30 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION virtual const char* name() const noexcept = 0; + // We need two different virtual functions here, one returning a + // COW string and one returning an SSO string. Their positions in the + // vtable must be consistent for dynamic dispatch to work, but which one + // the name "message()" finds depends on which ABI the caller is using. +#if _GLIBCXX_USE_CXX11_ABI + private: + _GLIBCXX_DEFAULT_ABI_TAG + virtual __cow_string + _M_message(int) const; + + public: + _GLIBCXX_DEFAULT_ABI_TAG + virtual string + message(int) const = 0; +#else virtual string message(int) const = 0; + private: + virtual __sso_string + _M_message(int) const; +#endif + + public: virtual error_condition default_error_condition(int __i) const noexcept; @@ -109,6 +126,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX_CONST const error_category& system_category() noexcept; _GLIBCXX_CONST const error_category& generic_category() noexcept; + } // end inline namespace + error_code make_error_code(errc) noexcept; template<typename _Tp> @@ -156,6 +175,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION error_condition default_error_condition() const noexcept; + _GLIBCXX_DEFAULT_ABI_TAG string message() const { return category().message(value()); } @@ -231,6 +251,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION const error_category& category() const noexcept { return *_M_cat; } + _GLIBCXX_DEFAULT_ABI_TAG string message() const { return category().message(value()); } diff --git a/libstdc++-v3/libsupc++/Makefile.in b/libstdc++-v3/libsupc++/Makefile.in index 1c7270a..9a1d725 100644 --- a/libstdc++-v3/libsupc++/Makefile.in +++ b/libstdc++-v3/libsupc++/Makefile.in @@ -280,6 +280,7 @@ glibcxx_POFILES = @glibcxx_POFILES@ glibcxx_builddir = @glibcxx_builddir@ glibcxx_compiler_pic_flag = @glibcxx_compiler_pic_flag@ glibcxx_compiler_shared_flag = @glibcxx_compiler_shared_flag@ +glibcxx_cxx98_abi = @glibcxx_cxx98_abi@ glibcxx_localedir = @glibcxx_localedir@ glibcxx_lt_pic_flag = @glibcxx_lt_pic_flag@ glibcxx_prefixdir = @glibcxx_prefixdir@ diff --git a/libstdc++-v3/po/Makefile.in b/libstdc++-v3/po/Makefile.in index 52f5256..46538de 100644 --- a/libstdc++-v3/po/Makefile.in +++ b/libstdc++-v3/po/Makefile.in @@ -216,6 +216,7 @@ glibcxx_POFILES = @glibcxx_POFILES@ glibcxx_builddir = @glibcxx_builddir@ glibcxx_compiler_pic_flag = @glibcxx_compiler_pic_flag@ glibcxx_compiler_shared_flag = @glibcxx_compiler_shared_flag@ +glibcxx_cxx98_abi = @glibcxx_cxx98_abi@ glibcxx_localedir = @glibcxx_localedir@ glibcxx_lt_pic_flag = @glibcxx_lt_pic_flag@ glibcxx_prefixdir = @glibcxx_prefixdir@ diff --git a/libstdc++-v3/python/Makefile.in b/libstdc++-v3/python/Makefile.in index 7d0c8ac..739edcb 100644 --- a/libstdc++-v3/python/Makefile.in +++ b/libstdc++-v3/python/Makefile.in @@ -240,6 +240,7 @@ glibcxx_POFILES = @glibcxx_POFILES@ glibcxx_builddir = @glibcxx_builddir@ glibcxx_compiler_pic_flag = @glibcxx_compiler_pic_flag@ glibcxx_compiler_shared_flag = @glibcxx_compiler_shared_flag@ +glibcxx_cxx98_abi = @glibcxx_cxx98_abi@ glibcxx_localedir = @glibcxx_localedir@ glibcxx_lt_pic_flag = @glibcxx_lt_pic_flag@ glibcxx_prefixdir = @glibcxx_prefixdir@ diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py index 48ecb67..cf5c3f1 100644 --- a/libstdc++-v3/python/libstdcxx/v6/printers.py +++ b/libstdc++-v3/python/libstdcxx/v6/printers.py @@ -660,6 +660,7 @@ class StdStringPrinter: def __init__(self, typename, val): self.val = val + self.new_string = typename.find("::__cxx11::basic_string") != -1 def to_string(self): # Make sure &string works, too. @@ -671,13 +672,18 @@ class StdStringPrinter: # the string according to length, not according to first null # encountered. ptr = self.val ['_M_dataplus']['_M_p'] - realtype = type.unqualified ().strip_typedefs () - reptype = gdb.lookup_type (str (realtype) + '::_Rep').pointer () - header = ptr.cast(reptype) - 1 - len = header.dereference ()['_M_length'] + if self.new_string: + length = self.val['_M_string_length'] + # https://sourceware.org/bugzilla/show_bug.cgi?id=17728 + ptr = ptr.cast(ptr.type.strip_typedefs()) + else: + realtype = type.unqualified ().strip_typedefs () + reptype = gdb.lookup_type (str (realtype) + '::_Rep').pointer () + header = ptr.cast(reptype) - 1 + length = header.dereference ()['_M_length'] if hasattr(ptr, "lazy_string"): - return ptr.lazy_string (length = len) - return ptr.string (length = len) + return ptr.lazy_string (length = length) + return ptr.string (length = length) def display_hint (self): return 'string' @@ -1266,6 +1272,7 @@ def build_libstdcxx_dictionary (): # In order from: # http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/a01847.html libstdcxx_printer.add_version('std::', 'basic_string', StdStringPrinter) + libstdcxx_printer.add_version('std::', '__cxx11::basic_string', StdStringPrinter) libstdcxx_printer.add_container('std::', 'bitset', StdBitsetPrinter) libstdcxx_printer.add_container('std::', 'deque', StdDequePrinter) libstdcxx_printer.add_container('std::', 'list', StdListPrinter) diff --git a/libstdc++-v3/src/Makefile.in b/libstdc++-v3/src/Makefile.in index cd3943b..d1b5ab2 100644 --- a/libstdc++-v3/src/Makefile.in +++ b/libstdc++-v3/src/Makefile.in @@ -267,6 +267,7 @@ glibcxx_POFILES = @glibcxx_POFILES@ glibcxx_builddir = @glibcxx_builddir@ glibcxx_compiler_pic_flag = @glibcxx_compiler_pic_flag@ glibcxx_compiler_shared_flag = @glibcxx_compiler_shared_flag@ +glibcxx_cxx98_abi = @glibcxx_cxx98_abi@ glibcxx_localedir = @glibcxx_localedir@ glibcxx_lt_pic_flag = @glibcxx_lt_pic_flag@ glibcxx_prefixdir = @glibcxx_prefixdir@ diff --git a/libstdc++-v3/src/c++11/Makefile.am b/libstdc++-v3/src/c++11/Makefile.am index 71306db..c4345af 100644 --- a/libstdc++-v3/src/c++11/Makefile.am +++ b/libstdc++-v3/src/c++11/Makefile.am @@ -39,9 +39,14 @@ ctype_configure_char.cc: ${glibcxx_srcdir}/$(OS_INC_SRCDIR)/ctype_configure_char ctype_members.cc: ${glibcxx_srcdir}/$(CCTYPE_CC) $(LN_S) ${glibcxx_srcdir}/$(CCTYPE_CC) . || true -if ENABLE_CXX11_ABI +if ENABLE_DUAL_ABI cxx11_abi_sources = \ - cxx11-ios_failure.cc + cow-locale_init.cc \ + cow-shim_facets.cc \ + cxx11-hash_tr1.cc \ + cxx11-ios_failure.cc \ + cxx11-shim_facets.cc \ + cxx11-stdexcept.cc else cxx11_abi_sources = endif @@ -49,6 +54,7 @@ endif sources = \ chrono.cc \ condition_variable.cc \ + cow-stdexcept.cc \ ctype.cc \ debug.cc \ functexcept.cc \ @@ -69,9 +75,22 @@ sources = \ ${cxx11_abi_sources} \ ${host_sources} +if ENABLE_DUAL_ABI +extra_string_inst_sources = \ + cow-fstream-inst.cc \ + cow-sstream-inst.cc \ + cow-string-inst.cc \ + cow-wstring-inst.cc \ + cxx11-locale-inst.cc \ + cxx11-wlocale-inst.cc +else +extra_string_inst_sources = +endif + if ENABLE_EXTERN_TEMPLATE # XTEMPLATE_FLAGS = -fno-implicit-templates inst_sources = \ + $(extra_string_inst_sources) \ ext11-inst.cc \ fstream-inst.cc \ ios-inst.cc \ diff --git a/libstdc++-v3/src/c++11/Makefile.in b/libstdc++-v3/src/c++11/Makefile.in index dd9e110..2ce23f9 100644 --- a/libstdc++-v3/src/c++11/Makefile.in +++ b/libstdc++-v3/src/c++11/Makefile.in @@ -67,20 +67,28 @@ CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libc__11convenience_la_LIBADD = -@ENABLE_CXX11_ABI_TRUE@am__objects_1 = cxx11-ios_failure.lo +@ENABLE_DUAL_ABI_TRUE@am__objects_1 = cow-locale_init.lo \ +@ENABLE_DUAL_ABI_TRUE@ cow-shim_facets.lo cxx11-hash_tr1.lo \ +@ENABLE_DUAL_ABI_TRUE@ cxx11-ios_failure.lo \ +@ENABLE_DUAL_ABI_TRUE@ cxx11-shim_facets.lo cxx11-stdexcept.lo am__objects_2 = ctype_configure_char.lo ctype_members.lo -am__objects_3 = chrono.lo condition_variable.lo ctype.lo debug.lo \ - functexcept.lo functional.lo future.lo hash_c++0x.lo \ - hashtable_c++0x.lo ios.lo limits.lo mutex.lo placeholders.lo \ - random.lo regex.lo shared_ptr.lo snprintf_lite.lo \ - system_error.lo thread.lo $(am__objects_1) $(am__objects_2) -@ENABLE_EXTERN_TEMPLATE_TRUE@am__objects_4 = ext11-inst.lo \ -@ENABLE_EXTERN_TEMPLATE_TRUE@ fstream-inst.lo ios-inst.lo \ -@ENABLE_EXTERN_TEMPLATE_TRUE@ iostream-inst.lo istream-inst.lo \ -@ENABLE_EXTERN_TEMPLATE_TRUE@ ostream-inst.lo sstream-inst.lo \ -@ENABLE_EXTERN_TEMPLATE_TRUE@ streambuf-inst.lo string-inst.lo \ -@ENABLE_EXTERN_TEMPLATE_TRUE@ wstring-inst.lo -am_libc__11convenience_la_OBJECTS = $(am__objects_3) $(am__objects_4) +am__objects_3 = chrono.lo condition_variable.lo cow-stdexcept.lo \ + ctype.lo debug.lo functexcept.lo functional.lo future.lo \ + hash_c++0x.lo hashtable_c++0x.lo ios.lo limits.lo mutex.lo \ + placeholders.lo random.lo regex.lo shared_ptr.lo \ + snprintf_lite.lo system_error.lo thread.lo $(am__objects_1) \ + $(am__objects_2) +@ENABLE_DUAL_ABI_TRUE@am__objects_4 = cow-fstream-inst.lo \ +@ENABLE_DUAL_ABI_TRUE@ cow-sstream-inst.lo cow-string-inst.lo \ +@ENABLE_DUAL_ABI_TRUE@ cow-wstring-inst.lo cxx11-locale-inst.lo \ +@ENABLE_DUAL_ABI_TRUE@ cxx11-wlocale-inst.lo +@ENABLE_EXTERN_TEMPLATE_TRUE@am__objects_5 = $(am__objects_4) \ +@ENABLE_EXTERN_TEMPLATE_TRUE@ ext11-inst.lo fstream-inst.lo \ +@ENABLE_EXTERN_TEMPLATE_TRUE@ ios-inst.lo iostream-inst.lo \ +@ENABLE_EXTERN_TEMPLATE_TRUE@ istream-inst.lo ostream-inst.lo \ +@ENABLE_EXTERN_TEMPLATE_TRUE@ sstream-inst.lo streambuf-inst.lo \ +@ENABLE_EXTERN_TEMPLATE_TRUE@ string-inst.lo wstring-inst.lo +am_libc__11convenience_la_OBJECTS = $(am__objects_3) $(am__objects_5) libc__11convenience_la_OBJECTS = $(am_libc__11convenience_la_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = @@ -240,6 +248,7 @@ glibcxx_POFILES = @glibcxx_POFILES@ glibcxx_builddir = @glibcxx_builddir@ glibcxx_compiler_pic_flag = @glibcxx_compiler_pic_flag@ glibcxx_compiler_shared_flag = @glibcxx_compiler_shared_flag@ +glibcxx_cxx98_abi = @glibcxx_cxx98_abi@ glibcxx_localedir = @glibcxx_localedir@ glibcxx_lt_pic_flag = @glibcxx_lt_pic_flag@ glibcxx_prefixdir = @glibcxx_prefixdir@ @@ -323,13 +332,19 @@ host_sources = \ ctype_configure_char.cc \ ctype_members.cc -@ENABLE_CXX11_ABI_FALSE@cxx11_abi_sources = -@ENABLE_CXX11_ABI_TRUE@cxx11_abi_sources = \ -@ENABLE_CXX11_ABI_TRUE@ cxx11-ios_failure.cc +@ENABLE_DUAL_ABI_FALSE@cxx11_abi_sources = +@ENABLE_DUAL_ABI_TRUE@cxx11_abi_sources = \ +@ENABLE_DUAL_ABI_TRUE@ cow-locale_init.cc \ +@ENABLE_DUAL_ABI_TRUE@ cow-shim_facets.cc \ +@ENABLE_DUAL_ABI_TRUE@ cxx11-hash_tr1.cc \ +@ENABLE_DUAL_ABI_TRUE@ cxx11-ios_failure.cc \ +@ENABLE_DUAL_ABI_TRUE@ cxx11-shim_facets.cc \ +@ENABLE_DUAL_ABI_TRUE@ cxx11-stdexcept.cc sources = \ chrono.cc \ condition_variable.cc \ + cow-stdexcept.cc \ ctype.cc \ debug.cc \ functexcept.cc \ @@ -350,11 +365,21 @@ sources = \ ${cxx11_abi_sources} \ ${host_sources} +@ENABLE_DUAL_ABI_FALSE@extra_string_inst_sources = +@ENABLE_DUAL_ABI_TRUE@extra_string_inst_sources = \ +@ENABLE_DUAL_ABI_TRUE@ cow-fstream-inst.cc \ +@ENABLE_DUAL_ABI_TRUE@ cow-sstream-inst.cc \ +@ENABLE_DUAL_ABI_TRUE@ cow-string-inst.cc \ +@ENABLE_DUAL_ABI_TRUE@ cow-wstring-inst.cc \ +@ENABLE_DUAL_ABI_TRUE@ cxx11-locale-inst.cc \ +@ENABLE_DUAL_ABI_TRUE@ cxx11-wlocale-inst.cc + # XTEMPLATE_FLAGS = @ENABLE_EXTERN_TEMPLATE_FALSE@inst_sources = # XTEMPLATE_FLAGS = -fno-implicit-templates @ENABLE_EXTERN_TEMPLATE_TRUE@inst_sources = \ +@ENABLE_EXTERN_TEMPLATE_TRUE@ $(extra_string_inst_sources) \ @ENABLE_EXTERN_TEMPLATE_TRUE@ ext11-inst.cc \ @ENABLE_EXTERN_TEMPLATE_TRUE@ fstream-inst.cc \ @ENABLE_EXTERN_TEMPLATE_TRUE@ ios-inst.cc \ diff --git a/libstdc++-v3/src/c++11/compatibility-c++0x.cc b/libstdc++-v3/src/c++11/compatibility-c++0x.cc index 3c83561..a554660 100644 --- a/libstdc++-v3/src/c++11/compatibility-c++0x.cc +++ b/libstdc++-v3/src/c++11/compatibility-c++0x.cc @@ -23,8 +23,18 @@ // <http://www.gnu.org/licenses/>. #define _GLIBCXX_COMPATIBILITY_CXX0X +#define _GLIBCXX_USE_CXX11_ABI 0 +#define error_category error_categoryxx +#define system_category system_categoryxx +#define generic_category generic_categoryxx +#define _V2 _V2xx #include <string> #include <system_error> +#include <cstring> +#undef error_category +#undef system_category +#undef generic_category +#undef _V2 #if __cplusplus < 201103L # error "compatibility-c++0x.cc must be compiled with -std=gnu++0x" @@ -120,9 +130,125 @@ namespace std _GLIBCXX_VISIBILITY(default) constexpr bool system_clock::is_monotonic; } // namespace chrono + // gcc-5 replaces this with _V2::error_category + class error_category + { + public: + error_category() noexcept; + + virtual ~error_category(); + + error_category(const error_category&) = delete; + error_category& operator=(const error_category&) = delete; + + virtual const char* + name() const noexcept = 0; + + virtual string + message(int) const = 0; + + virtual error_condition + default_error_condition(int __i) const noexcept; + + virtual bool + equivalent(int __i, const error_condition& __cond) const noexcept; + + virtual bool + equivalent(const error_code& __code, int __i) const noexcept; + + bool + operator<(const error_category& __other) const noexcept + { return less<const error_category*>()(this, &__other); } + + bool + operator==(const error_category& __other) const noexcept + { return this == &__other; } + + bool + operator!=(const error_category& __other) const noexcept + { return this != &__other; } + }; + // gcc-4.9.0 // LWG 2145 changes this constructor to constexpr i.e. inline error_category::error_category() noexcept = default; -} + error_category::~error_category() noexcept = default; + + namespace + { + using std::string; + + struct generic_error_category : public std::error_category + { + virtual const char* + name() const noexcept + { return "generic"; } + + virtual string + message(int i) const + { + // XXX locale issues: how does one get or set loc. + // _GLIBCXX_HAVE_STRERROR_L, strerror_l(i, cloc) + return string(strerror(i)); + } + }; + + struct system_error_category : public std::error_category + { + virtual const char* + name() const noexcept + { return "system"; } + + virtual string + message(int i) const + { + // XXX locale issues: how does one get or set loc. + // _GLIBCXX_HAVE_STRERROR_L, strerror_l(i, cloc) + return string(strerror(i)); + } + }; + + const generic_error_category generic_category_instance{}; + const system_error_category system_category_instance{}; + } + + const error_category& + system_category() noexcept { return system_category_instance; } + + const error_category& + generic_category() noexcept { return generic_category_instance; } + + namespace _V2 + { + _GLIBCXX_CONST const error_categoryxx& system_category() noexcept; + _GLIBCXX_CONST const error_categoryxx& generic_category() noexcept; + } + + error_condition + error_category::default_error_condition(int __i) const noexcept + { + if (*this == system_category()) + return error_condition(__i, _V2::system_category()); + return error_condition(__i, _V2::generic_category()); + } + + bool + error_category::equivalent(int __i, + const error_condition& __cond) const noexcept + { return default_error_condition(__i) == __cond; } + + bool + error_category::equivalent(const error_code& __code, int __i) const noexcept + { + if (*this == system_category() + && __code.category() == _V2::system_category()) + return __code.value() == __i; + if (*this == generic_category() + && __code.category() == _V2::generic_category()) + return __code.value() == __i; + return false; + } + +} #endif diff --git a/libstdc++-v3/src/c++11/cow-fstream-inst.cc b/libstdc++-v3/src/c++11/cow-fstream-inst.cc new file mode 100644 index 0000000..8e37368 --- /dev/null +++ b/libstdc++-v3/src/c++11/cow-fstream-inst.cc @@ -0,0 +1,78 @@ +// Explicit instantiation file. + +// Copyright (C) 2014 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library 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 3, or (at your option) +// any later version. + +// This library 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. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +// +// ISO C++ 14882: +// + +#define _GLIBCXX_USE_CXX11_ABI 0 +#include <fstream> + +#if ! _GLIBCXX_USE_DUAL_ABI +# error This file should not be compiled for this configuration. +#endif + +namespace std _GLIBCXX_VISIBILITY(default) +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + template basic_filebuf<char>* + basic_filebuf<char>::open(const std::string&, ios_base::openmode); + template + basic_ifstream<char>:: + basic_ifstream(const std::string&, ios_base::openmode); + template void + basic_ifstream<char>::open(const std::string&, ios_base::openmode); + template + basic_ofstream<char>:: + basic_ofstream(const std::string&, ios_base::openmode); + template void + basic_ofstream<char>::open(const std::string&, ios_base::openmode); + template + basic_fstream<char>::basic_fstream(const std::string&, ios_base::openmode); + template void + basic_fstream<char>::open(const std::string&, ios_base::openmode); + +#ifdef _GLIBCXX_USE_WCHAR_T + template basic_filebuf<wchar_t>* + basic_filebuf<wchar_t>::open(const std::string&, ios_base::openmode); + template + basic_ifstream<wchar_t>:: + basic_ifstream(const std::string&, ios_base::openmode); + template void + basic_ifstream<wchar_t>::open(const std::string&, ios_base::openmode); + template + basic_ofstream<wchar_t>:: + basic_ofstream(const std::string&, ios_base::openmode); + template void + basic_ofstream<wchar_t>::open(const std::string&, ios_base::openmode); + template + basic_fstream<wchar_t>:: + basic_fstream(const std::string&, ios_base::openmode); + template void + basic_fstream<wchar_t>::open(const std::string&, ios_base::openmode); +#endif + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace diff --git a/libstdc++-v3/src/c++11/cow-locale_init.cc b/libstdc++-v3/src/c++11/cow-locale_init.cc new file mode 100644 index 0000000..f48af64 --- /dev/null +++ b/libstdc++-v3/src/c++11/cow-locale_init.cc @@ -0,0 +1,194 @@ +// Copyright (C) 2014 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library 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 3, or (at your option) +// any later version. + +// This library 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. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +// Instantiate the facets using old std::string ABI. +#define _GLIBCXX_USE_CXX11_ABI 0 +#include <locale> + +#if ! _GLIBCXX_USE_DUAL_ABI +# error This file should not be compiled for this configuration. +#endif + +namespace std _GLIBCXX_VISIBILITY(default) +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + +namespace +{ + typedef char fake_collate_c[sizeof(std::collate<char>)] + __attribute__ ((aligned(__alignof__(std::collate<char>)))); + fake_collate_c collate_c; + + typedef char fake_numpunct_c[sizeof(numpunct<char>)] + __attribute__ ((aligned(__alignof__(numpunct<char>)))); + fake_numpunct_c numpunct_c; + + typedef char fake_moneypunct_c[sizeof(moneypunct<char, true>)] + __attribute__ ((aligned(__alignof__(moneypunct<char, true>)))); + fake_moneypunct_c moneypunct_ct; + fake_moneypunct_c moneypunct_cf; + + typedef char fake_money_get_c[sizeof(money_get<char>)] + __attribute__ ((aligned(__alignof__(money_get<char>)))); + fake_money_get_c money_get_c; + + typedef char fake_money_put_c[sizeof(money_put<char>)] + __attribute__ ((aligned(__alignof__(money_put<char>)))); + fake_money_put_c money_put_c; + + typedef char fake_time_get_c[sizeof(time_get<char>)] + __attribute__ ((aligned(__alignof__(time_get<char>)))); + fake_time_get_c time_get_c; + + typedef char fake_messages_c[sizeof(messages<char>)] + __attribute__ ((aligned(__alignof__(messages<char>)))); + fake_messages_c messages_c; + +#ifdef _GLIBCXX_USE_WCHAR_T + typedef char fake_wollate_w[sizeof(std::collate<wchar_t>)] + __attribute__ ((aligned(__alignof__(std::collate<wchar_t>)))); + fake_wollate_w collate_w; + + typedef char fake_numpunct_w[sizeof(numpunct<wchar_t>)] + __attribute__ ((aligned(__alignof__(numpunct<wchar_t>)))); + fake_numpunct_w numpunct_w; + + typedef char fake_moneypunct_w[sizeof(moneypunct<wchar_t, true>)] + __attribute__ ((aligned(__alignof__(moneypunct<wchar_t, true>)))); + fake_moneypunct_w moneypunct_wt; + fake_moneypunct_w moneypunct_wf; + + typedef char fake_money_get_w[sizeof(money_get<wchar_t>)] + __attribute__ ((aligned(__alignof__(money_get<wchar_t>)))); + fake_money_get_w money_get_w; + + typedef char fake_money_put_w[sizeof(money_put<wchar_t>)] + __attribute__ ((aligned(__alignof__(money_put<wchar_t>)))); + fake_money_put_w money_put_w; + + typedef char fake_time_get_w[sizeof(time_get<wchar_t>)] + __attribute__ ((aligned(__alignof__(time_get<wchar_t>)))); + fake_time_get_w time_get_w; + + typedef char fake_messages_w[sizeof(messages<wchar_t>)] + __attribute__ ((aligned(__alignof__(messages<wchar_t>)))); + fake_messages_w messages_w; +#endif +} // anonymous namespace + + void + locale::_Impl::_M_init_extra(facet** caches) + { + auto __npc = static_cast<__numpunct_cache<char>*>(caches[0]); + auto __mpcf = static_cast<__moneypunct_cache<char, false>*>(caches[1]); + auto __mpct = static_cast<__moneypunct_cache<char, true>*>(caches[2]); + + _M_init_facet_unchecked(new (&numpunct_c) numpunct<char>(__npc, 1)); + _M_init_facet_unchecked(new (&collate_c) std::collate<char>(1)); + _M_init_facet_unchecked(new (&moneypunct_cf) moneypunct<char, false>(__mpcf, 1)); + _M_init_facet_unchecked(new (&moneypunct_ct) moneypunct<char, true>(__mpct, 1)); + _M_init_facet_unchecked(new (&money_get_c) money_get<char>(1)); + _M_init_facet_unchecked(new (&money_put_c) money_put<char>(1)); + _M_init_facet_unchecked(new (&time_get_c) time_get<char>(1)); + _M_init_facet_unchecked(new (&messages_c) std::messages<char>(1)); +#ifdef _GLIBCXX_USE_WCHAR_T + auto __npw = static_cast<__numpunct_cache<wchar_t>*>(caches[3]); + auto __mpwf = static_cast<__moneypunct_cache<wchar_t, false>*>(caches[4]); + auto __mpwt = static_cast<__moneypunct_cache<wchar_t, true>*>(caches[5]); + + _M_init_facet_unchecked(new (&numpunct_w) numpunct<wchar_t>(__npw, 1)); + _M_init_facet_unchecked(new (&collate_w) std::collate<wchar_t>(1)); + _M_init_facet_unchecked(new (&moneypunct_wf) moneypunct<wchar_t, false>(__mpwf, 1)); + _M_init_facet_unchecked(new (&moneypunct_wt) moneypunct<wchar_t, true>(__mpwt, 1)); + _M_init_facet_unchecked(new (&money_get_w) money_get<wchar_t>(1)); + _M_init_facet_unchecked(new (&money_put_w) money_put<wchar_t>(1)); + _M_init_facet_unchecked(new (&time_get_w) time_get<wchar_t>(1)); + _M_init_facet_unchecked(new (&messages_w) std::messages<wchar_t>(1)); +#endif + + _M_caches[numpunct<char>::id._M_id()] = __npc; + _M_caches[moneypunct<char, false>::id._M_id()] = __mpcf; + _M_caches[moneypunct<char, true>::id._M_id()] = __mpct; +#ifdef _GLIBCXX_USE_WCHAR_T + _M_caches[numpunct<wchar_t>::id._M_id()] = __npw; + _M_caches[moneypunct<wchar_t, false>::id._M_id()] = __mpwf; + _M_caches[moneypunct<wchar_t, true>::id._M_id()] = __mpwt; +#endif + } + + void + locale::_Impl::_M_init_extra(void* cloc, void* clocm, + const char* __s, const char* __smon) + { + auto& __cloc = *static_cast<__c_locale*>(cloc); + + _M_init_facet_unchecked(new numpunct<char>(__cloc)); + _M_init_facet_unchecked(new std::collate<char>(__cloc)); + _M_init_facet_unchecked(new moneypunct<char, false>(__cloc, 0)); + _M_init_facet_unchecked(new moneypunct<char, true>(__cloc, 0)); + _M_init_facet_unchecked(new money_get<char>); + _M_init_facet_unchecked(new money_put<char>); + _M_init_facet_unchecked(new time_get<char>); + _M_init_facet_unchecked(new std::messages<char>(__cloc, __s)); + +#ifdef _GLIBCXX_USE_WCHAR_T + auto& __clocm = *static_cast<__c_locale*>(clocm); + + _M_init_facet_unchecked(new numpunct<wchar_t>(__cloc)); + _M_init_facet_unchecked(new std::collate<wchar_t>(__cloc)); + _M_init_facet_unchecked(new moneypunct<wchar_t, false>(__clocm, __smon)); + _M_init_facet_unchecked(new moneypunct<wchar_t, true>(__clocm, __smon)); + _M_init_facet_unchecked(new money_get<wchar_t>); + _M_init_facet_unchecked(new money_put<wchar_t>); + _M_init_facet_unchecked(new time_get<wchar_t>); + _M_init_facet_unchecked(new std::messages<wchar_t>(__cloc, __s)); +#endif + } + +// TODO should be in another file + string + locale::name() const + { + string __ret; + if (!_M_impl->_M_names[0]) + __ret = '*'; + else if (_M_impl->_M_check_same_name()) + __ret = _M_impl->_M_names[0]; + else + { + __ret.reserve(128); + __ret += _S_categories[0]; + __ret += '='; + __ret += _M_impl->_M_names[0]; + for (size_t __i = 1; __i < _S_categories_size; ++__i) + { + __ret += ';'; + __ret += _S_categories[__i]; + __ret += '='; + __ret += _M_impl->_M_names[__i]; + } + } + return __ret; + } + +_GLIBCXX_END_NAMESPACE_VERSION +} diff --git a/libstdc++-v3/src/c++11/cow-shim_facets.cc b/libstdc++-v3/src/c++11/cow-shim_facets.cc new file mode 100644 index 0000000..1373f4b --- /dev/null +++ b/libstdc++-v3/src/c++11/cow-shim_facets.cc @@ -0,0 +1,35 @@ +// Locale support -*- C++ -*- + +// Copyright (C) 2014 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library 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 3, or (at your option) +// any later version. + +// This library 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. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file bits/locale_classes.tcc + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{locale} + */ + +// +// ISO C++ 14882: 22.1 Locales +// + +#define _GLIBCXX_USE_CXX11_ABI 0 +#include "cxx11-shim_facets.cc" diff --git a/libstdc++-v3/src/c++11/cow-sstream-inst.cc b/libstdc++-v3/src/c++11/cow-sstream-inst.cc new file mode 100644 index 0000000..fdd57aa --- /dev/null +++ b/libstdc++-v3/src/c++11/cow-sstream-inst.cc @@ -0,0 +1,34 @@ +// Explicit instantiation file. + +// Copyright (C) 2014 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library 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 3, or (at your option) +// any later version. + +// This library 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. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +// +// ISO C++ 14882: +// + +#define _GLIBCXX_USE_CXX11_ABI 0 +#include "sstream-inst.cc" + +#if ! _GLIBCXX_USE_DUAL_ABI +# error This file should not be compiled for this configuration. +#endif diff --git a/libstdc++-v3/src/c++11/cow-stdexcept.cc b/libstdc++-v3/src/c++11/cow-stdexcept.cc new file mode 100644 index 0000000..1bec98c --- /dev/null +++ b/libstdc++-v3/src/c++11/cow-stdexcept.cc @@ -0,0 +1,153 @@ +// Methods for Exception Support for -*- C++ -*- + +// Copyright (C) 2014 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library 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 3, or (at your option) +// any later version. + +// This library 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. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +// +// ISO C++ 14882: 19.1 Exception classes +// + +// All exception classes still use the classic COW std::string. +#define _GLIBCXX_USE_CXX11_ABI 0 +#define _GLIBCXX_DEFINE_STDEXCEPT_COPY_OPS 1 +#define __cow_string __cow_stringxxx +#include <stdexcept> +#include <system_error> +#undef __cow_string + +namespace std _GLIBCXX_VISIBILITY(default) +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + // Copy constructors and assignment operators defined using COW std::string + + logic_error::logic_error(const logic_error& e) noexcept + : _M_msg(e._M_msg) { } + + logic_error& logic_error::operator=(const logic_error& e) noexcept + { _M_msg = e._M_msg; return *this; } + + runtime_error::runtime_error(const runtime_error& e) noexcept + : _M_msg(e._M_msg) { } + + runtime_error& + runtime_error::operator=(const runtime_error& e) noexcept + { _M_msg = e._M_msg; return *this; } + + // New C++11 constructors: + + logic_error::logic_error(const char* __arg) + : exception(), _M_msg(__arg) { } + + domain_error::domain_error(const char* __arg) + : logic_error(__arg) { } + + invalid_argument::invalid_argument(const char* __arg) + : logic_error(__arg) { } + + length_error::length_error(const char* __arg) + : logic_error(__arg) { } + + out_of_range::out_of_range(const char* __arg) + : logic_error(__arg) { } + + runtime_error::runtime_error(const char* __arg) + : exception(), _M_msg(__arg) { } + + range_error::range_error(const char* __arg) + : runtime_error(__arg) { } + + overflow_error::overflow_error(const char* __arg) + : runtime_error(__arg) { } + + underflow_error::underflow_error(const char* __arg) + : runtime_error(__arg) { } + +#if _GLIBCXX_USE_DUAL_ABI + // Converting constructor from COW std::string to SSO string. + __sso_string::__sso_string(const string& s) + : __sso_string(s.c_str(), s.length()) { } + + // Redefine __cow_string so that we can define and export its members + // in terms of the COW std::string. + struct __cow_string + { + union { + const char* _M_p; + char _M_bytes[sizeof(_M_p)]; + std::string _M_str; + }; + + __cow_string(); + __cow_string(const std::string& s); + __cow_string(const char*, size_t n); + __cow_string(const __cow_string&) noexcept; + __cow_string& operator=(const __cow_string&) noexcept; + ~__cow_string(); + __cow_string(__cow_string&&) noexcept; + __cow_string& operator=(__cow_string&&) noexcept; + }; + + __cow_string::__cow_string() : _M_str() { } + + __cow_string::__cow_string(const std::string& s) : _M_str(s) { } + + __cow_string::__cow_string(const char* s, size_t n) : _M_str(s, n) { } + + __cow_string::__cow_string(const __cow_string& s) noexcept + : _M_str(s._M_str) { } + + __cow_string& + __cow_string::operator=(const __cow_string& s) noexcept + { + _M_str = s._M_str; + return *this; + } + + __cow_string::~__cow_string() { _M_str.~basic_string(); } + + __cow_string::__cow_string(__cow_string&& s) noexcept + : _M_str(std::move(s._M_str)) { } + + __cow_string& + __cow_string::operator=(__cow_string&& s) noexcept + { + _M_str = std::move(s._M_str); + return *this; + } + + static_assert(sizeof(__cow_string) == sizeof(std::string), + "sizeof(std::string) has changed"); + static_assert(alignof(__cow_string) == alignof(std::string), + "alignof(std::string) has changed"); +#endif + + // Return error_category::message() as an SSO string + __sso_string + error_category::_M_message(int i) const + { + string msg = this->message(i); + return {msg.c_str(), msg.length()}; + } + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace diff --git a/libstdc++-v3/src/c++11/cow-string-inst.cc b/libstdc++-v3/src/c++11/cow-string-inst.cc new file mode 100644 index 0000000..45811cb --- /dev/null +++ b/libstdc++-v3/src/c++11/cow-string-inst.cc @@ -0,0 +1,120 @@ +// Reference-counted COW string instantiations -*- C++ -*- + +// Copyright (C) 2014 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library 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 3, or (at your option) +// any later version. + +// This library 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. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +// +// ISO C++ 14882: 21 Strings library +// + +#define _GLIBCXX_USE_CXX11_ABI 0 +#include "string-inst.cc" + +#include <istream> +#include <ostream> + +#if ! _GLIBCXX_USE_DUAL_ABI +# error This file should not be compiled for this configuration. +#endif + +namespace std _GLIBCXX_VISIBILITY(default) +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + // These came from c++98/misc-inst.cc, repeat them for COW string + // string related to iostreams. + template + basic_istream<char>& + operator>>(basic_istream<char>&, string&); + template + basic_ostream<char>& + operator<<(basic_ostream<char>&, const string&); + template + basic_istream<char>& + getline(basic_istream<char>&, string&, char); + template + basic_istream<char>& + getline(basic_istream<char>&, string&); + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace + +#ifdef _GLIBCXX_USE_C99_STDINT_TR1 +#include <random> +#if defined __i386__ || defined __x86_64__ +# include <cpuid.h> +#endif +#include <cstdio> + +namespace std _GLIBCXX_VISIBILITY(default) +{ + void + random_device::_M_init(const std::string& token) + { + const char *fname = token.c_str(); + + if (token == "default") + { +#if (defined __i386__ || defined __x86_64__) && defined _GLIBCXX_X86_RDRAND + unsigned int eax, ebx, ecx, edx; + // Check availability of cpuid and, for now at least, also the + // CPU signature for Intel's + if (__get_cpuid_max(0, &ebx) > 0 && ebx == signature_INTEL_ebx) + { + __cpuid(1, eax, ebx, ecx, edx); + if (ecx & bit_RDRND) + { + _M_file = nullptr; + return; + } + } +#endif + + fname = "/dev/urandom"; + } + else if (token != "/dev/urandom" && token != "/dev/random") + fail: + std::__throw_runtime_error(__N("random_device::" + "random_device(const std::string&)")); + + _M_file = static_cast<void*>(std::fopen(fname, "rb")); + if (!_M_file) + goto fail; + } + + void + random_device::_M_init_pretr1(const std::string& token) + { + unsigned long __seed = 5489UL; + if (token != "mt19937") + { + const char* __nptr = token.c_str(); + char* __endptr; + __seed = std::strtoul(__nptr, &__endptr, 0); + if (*__nptr == '\0' || *__endptr != '\0') + std::__throw_runtime_error(__N("random_device::random_device" + "(const std::string&)")); + } + _M_mt.seed(__seed); + } +} // namespace +#endif diff --git a/libstdc++-v3/src/c++11/cow-wstring-inst.cc b/libstdc++-v3/src/c++11/cow-wstring-inst.cc new file mode 100644 index 0000000..de1709d --- /dev/null +++ b/libstdc++-v3/src/c++11/cow-wstring-inst.cc @@ -0,0 +1,64 @@ +// Reference-counted COW wide string instantiations -*- C++ -*- + +// Copyright (C) 2014 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library 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 3, or (at your option) +// any later version. + +// This library 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. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +// +// ISO C++ 14882: 21 Strings library +// + +#define _GLIBCXX_USE_CXX11_ABI 0 +#include <bits/c++config.h> + +#ifdef _GLIBCXX_USE_WCHAR_T +#define C wchar_t +#include "string-inst.cc" + +#include <ostream> +#include <istream> + +#if ! _GLIBCXX_USE_DUAL_ABI +# error This file should not be compiled for this configuration. +#endif + +namespace std _GLIBCXX_VISIBILITY(default) +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + // XXX these came from c++98/misc-inst.cc, repeat them for COW string + // string related to iostreams + template + basic_istream<wchar_t>& + operator>>(basic_istream<wchar_t>&, wstring&); + template + basic_ostream<wchar_t>& + operator<<(basic_ostream<wchar_t>&, const wstring&); + template + basic_istream<wchar_t>& + getline(basic_istream<wchar_t>&, wstring&, wchar_t); + template + basic_istream<wchar_t>& + getline(basic_istream<wchar_t>&, wstring&); + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace +#endif diff --git a/libstdc++-v3/src/c++11/cxx11-hash_tr1.cc b/libstdc++-v3/src/c++11/cxx11-hash_tr1.cc new file mode 100644 index 0000000..2b710d2 --- /dev/null +++ b/libstdc++-v3/src/c++11/cxx11-hash_tr1.cc @@ -0,0 +1,59 @@ +// std::tr1::hash definitions with new string -*- C++ -*- + +// Copyright (C) 2014 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library 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 3, or (at your option) +// any later version. + +// This library 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. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +#define _GLIBCXX_USE_CXX11_ABI 1 +#include <string> + +#if ! _GLIBCXX_USE_DUAL_ABI +# error This file should not be compiled for this configuration. +#endif + +#include <tr1/functional> +namespace std _GLIBCXX_VISIBILITY(default) +{ + namespace tr1 + { + template<> + size_t + hash<string>::operator()(string __s) const + { return _Fnv_hash::hash(__s.data(), __s.length()); } + + template<> + size_t + hash<const string&>::operator()(const string& __s) const + { return _Fnv_hash::hash(__s.data(), __s.length()); } + +#ifdef _GLIBCXX_USE_WCHAR_T + template<> + size_t + hash<wstring>::operator()(wstring __s) const + { return _Fnv_hash::hash(__s.data(), __s.length() * sizeof(wchar_t)); } + + template<> + size_t + hash<const wstring&>::operator()(const wstring& __s) const + { return _Fnv_hash::hash(__s.data(), __s.length() * sizeof(wchar_t)); } +#endif + } +} diff --git a/libstdc++-v3/src/c++11/cxx11-ios_failure.cc b/libstdc++-v3/src/c++11/cxx11-ios_failure.cc index 143d70e..0663de2 100644 --- a/libstdc++-v3/src/c++11/cxx11-ios_failure.cc +++ b/libstdc++-v3/src/c++11/cxx11-ios_failure.cc @@ -26,8 +26,13 @@ // ISO C++ 14882:2011: 27.5.3.1.1 Class ios_base::failure // +#define _GLIBCXX_USE_CXX11_ABI 1 #include <ios> +#if ! _GLIBCXX_USE_DUAL_ABI +# error This file should not be compiled for this configuration. +#endif + namespace { struct io_error_category : std::error_category diff --git a/libstdc++-v3/src/c++11/cxx11-locale-inst.cc b/libstdc++-v3/src/c++11/cxx11-locale-inst.cc new file mode 100644 index 0000000..9c1a1c1 --- /dev/null +++ b/libstdc++-v3/src/c++11/cxx11-locale-inst.cc @@ -0,0 +1,39 @@ +// Copyright (C) 2014 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library 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 3, or (at your option) +// any later version. + +// This library 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. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +// +// ISO C++ 14882: 22.1 Locales +// + +// Facet instantiations using new ABI strings. + +#define _GLIBCXX_USE_CXX11_ABI 1 +#include <bits/c++config.h> +#if ! _GLIBCXX_USE_DUAL_ABI +# error This file should not be compiled for this configuration. +#endif + +#ifndef C +# define C char +# define C_is_char +#endif +# include "../c++98/locale-inst.cc" diff --git a/libstdc++-v3/src/c++11/cxx11-shim_facets.cc b/libstdc++-v3/src/c++11/cxx11-shim_facets.cc new file mode 100644 index 0000000..92990a9 --- /dev/null +++ b/libstdc++-v3/src/c++11/cxx11-shim_facets.cc @@ -0,0 +1,813 @@ +// Locale support -*- C++ -*- + +// Copyright (C) 2014 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library 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 3, or (at your option) +// any later version. + +// This library 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. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +// +// ISO C++ 14882: 22.1 Locales +// + +// This file defines classes that behave like the standard predefined locale +// facets (collate, money_get etc.) except that they forward all virtual +// functions to another facet which uses a different std::string ABI, +// converting between string types as needed. +// When a user replaces one of the relevant facets the corresponding shim in +// this file is used so that the replacement facet can be used (via the shim) +// in code that uses the other std::string ABI from the replacing code. + +#ifndef _GLIBCXX_USE_CXX11_ABI +# define _GLIBCXX_USE_CXX11_ABI 1 +#endif +#include <locale> + +#if ! _GLIBCXX_USE_DUAL_ABI +# error This file should not be compiled for this configuration. +#endif + +namespace std _GLIBCXX_VISIBILITY(default) +{ + // Base class of facet shims, holds a reference to the underlying facet + // that the shim forwards to. + class locale::facet::__shim + { + public: + const facet* _M_get() const { return _M_facet; } + + __shim(const __shim&) = delete; + __shim& operator=(const __shim&) = delete; + + protected: + explicit + __shim(const facet* __f) : _M_facet(__f) { __f->_M_add_reference(); } + + ~__shim() { _M_facet->_M_remove_reference(); } + + private: + const facet* _M_facet; + }; + +namespace __facet_shims +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + namespace // unnamed + { + template<typename C> + void __destroy_string(void* p) + { + static_cast<std::basic_string<C>*>(p)->~basic_string(); + } + } // namespace + + // Manages a buffer of uninitialized memory that can store a std::string + // or std::wstring, using either ABI, and convert to the other ABI. + class __any_string + { + struct __attribute__((may_alias)) __str_rep + { + union { + const void* _M_p; + char* _M_pc; + wchar_t* _M_pwc; + }; + size_t _M_len; + char _M_unused[16]; + + operator const char*() const { return _M_pc; } + operator const wchar_t*() const { return _M_pwc; } + }; + union { + __str_rep _M_str; + char _M_bytes[sizeof(__str_rep)]; + }; + using __dtor_func = void(*)(void*); + __dtor_func _M_dtor = nullptr; + +#if _GLIBCXX_USE_CXX11_ABI + // SSO strings overlay the entire __str_rep structure. + static_assert(sizeof(std::string) == sizeof(__str_rep), + "std::string changed size!"); +#else + // COW strings overlay just the pointer, the length is stored manually. + static_assert(sizeof(std::string) == sizeof(__str_rep::_M_p), + "std::string changed size!"); +#endif +# ifdef _GLIBCXX_USE_WCHAR_T + static_assert(sizeof(std::wstring) == sizeof(std::string), + "std::wstring and std::string are different sizes!"); +# endif + + public: + __any_string() = default; + ~__any_string() { if (_M_dtor) _M_dtor(_M_bytes); } + + __any_string(const __any_string&) = delete; + __any_string& operator=(const __any_string&) = delete; + + // Store a string (and its length if needed) in the buffer and + // set _M_dtor to the function that runs the right destructor. + template<typename C> + __any_string& + operator=(const basic_string<C>& s) + { + if (_M_dtor) + _M_dtor(_M_bytes); + ::new(_M_bytes) basic_string<C>(s); +#if ! _GLIBCXX_USE_CXX11_ABI + _M_str._M_len = s.length(); +#endif + _M_dtor = __destroy_string<C>; + return *this; + } + + // Create a new string with a copy of the characters in the stored string. + // The returned object will match the caller's string ABI, even when the + // stored string doesn't. + template<typename C> + operator basic_string<C>() const + { + if (!_M_dtor) + __throw_logic_error("uninitialized __any_string"); + return basic_string<C>(static_cast<const C*>(_M_str), _M_str._M_len); + } + }; + + // This file is compiled twice, with and without this macro defined. + // Define tag types to distinguish between the two cases and to allow + // overloading on the tag. + using current_abi = __bool_constant<_GLIBCXX_USE_CXX11_ABI>; + using other_abi = __bool_constant<!_GLIBCXX_USE_CXX11_ABI>; + + using facet = locale::facet; + + // Declare the functions that shims defined in this file will call to + // perform work in the context of the other ABI. + // These will be defined when this file is recompiled for the other ABI + // (at which point what is now "current_abi" will become "other_abi"). + + template<typename C> + void + __numpunct_fill_cache(other_abi, const facet*, __numpunct_cache<C>*, + const char*&, size_t&); + + template<typename C> + int + __collate_compare(other_abi, const facet*, const C*, const C*, + const C*, const C*); + + template<typename C> + void + __collate_transform(other_abi, const facet*, __any_string&, + const C*, const C*); + + template<typename C> + time_base::dateorder + __time_get_dateorder(other_abi, const facet* f); + + template<typename C> + istreambuf_iterator<C> + __time_get(other_abi, const facet* f, + istreambuf_iterator<C> beg, istreambuf_iterator<C> end, + ios_base& io, ios_base::iostate& err, tm* t, char which); + + template<typename C, bool Intl> + void + __moneypunct_fill_cache(other_abi, const facet*, + __moneypunct_cache<C, Intl>*); + + template<typename C> + istreambuf_iterator<C> + __money_get(other_abi, const facet*, + istreambuf_iterator<C>, istreambuf_iterator<C>, + bool, ios_base&, ios_base::iostate&, + long double*, __any_string*); + + template<typename C> + ostreambuf_iterator<C> + __money_put(other_abi, const facet*, ostreambuf_iterator<C>, bool, + ios_base&, C, long double, const __any_string*); + + template<typename C> + messages_base::catalog + __messages_open(other_abi, const facet*, const char*, size_t, + const locale&); + + template<typename C> + void + __messages_get(other_abi, const facet*, __any_string&, + messages_base::catalog, int, int, const C*, size_t); + + template<typename C> + void + __messages_close(other_abi, const facet*, messages_base::catalog); + + namespace // unnamed + { + template<typename _CharT> + struct numpunct_shim : std::numpunct<_CharT>, facet::__shim + { + typedef typename numpunct<_CharT>::__cache_type __cache_type; + + // f must point to a type derived from numpunct<C>[abi:other] + numpunct_shim(const facet* f, __cache_type* c = new __cache_type) + : std::numpunct<_CharT>(c), __shim(f), _M_cache(c) + { + __numpunct_fill_cache(other_abi{}, f, c, _M_grouping, + _M_grouping_size); + } + + ~numpunct_shim() { delete[] _M_grouping; } + + virtual string + do_grouping() const + { return string(_M_grouping, _M_grouping_size); } + + // No need to override other virtual functions, the base definitions + // will return the cached data. + + __cache_type* _M_cache; + // numpunct uses __numpunct_cache<C>::_M_grouping for its own purposes + // so we can't store that in the cache + const char* _M_grouping; + size_t _M_grouping_size; + }; + + template class numpunct_shim<char>; + template class numpunct_shim<wchar_t>; + + template<typename _CharT> + struct collate_shim : std::collate<_CharT>, facet::__shim + { + typedef basic_string<_CharT> string_type; + + // f must point to a type derived from collate<C>[abi:other] + collate_shim(const facet* f) : __shim(f) { } + + virtual int + do_compare(const _CharT* lo1, const _CharT* hi1, + const _CharT* lo2, const _CharT* hi2) const + { + return __collate_compare(other_abi{}, _M_get(), + lo1, hi1, lo2, hi2); + } + + virtual string_type + do_transform(const _CharT* lo, const _CharT* hi) const + { + __any_string st; + __collate_transform(other_abi{}, _M_get(), st, lo, hi); + return st; + } + }; + + template class collate_shim<char>; + template class collate_shim<wchar_t>; + + template<typename _CharT> + struct time_get_shim : std::time_get<_CharT>, facet::__shim + { + typedef typename std::time_get<_CharT>::iter_type iter_type; + typedef typename std::time_get<_CharT>::char_type char_type; + + // f must point to a type derived from time_get<C>[abi:other] + time_get_shim(const facet* f) : __shim(f) { } + + virtual time_base::dateorder + do_date_order() const + { return __time_get_dateorder<_CharT>(other_abi{}, _M_get()); } + + virtual iter_type + do_get_time(iter_type beg, iter_type end, ios_base& io, + ios_base::iostate& err, tm* t) const + { + return __time_get(other_abi{}, _M_get(), beg, end, io, err, t, + 't'); + } + + virtual iter_type + do_get_date(iter_type beg, iter_type end, ios_base& io, + ios_base::iostate& err, tm* t) const + { + return __time_get(other_abi{}, _M_get(), beg, end, io, err, t, + 'd'); + } + + virtual iter_type + do_get_weekday(iter_type beg, iter_type end, ios_base& io, + ios_base::iostate& err, tm* t) const + { + return __time_get(other_abi{}, _M_get(), beg, end, io, err, t, + 'w'); + } + + virtual iter_type + do_get_monthname(iter_type beg, iter_type end, ios_base& io, + ios_base::iostate& err, tm* t) const + { + return __time_get(other_abi{}, _M_get(), beg, end, io, err, t, + 'm'); + } + + virtual iter_type + do_get_year(iter_type beg, iter_type end, ios_base& io, + ios_base::iostate& err, tm* t) const + { + return __time_get(other_abi{}, _M_get(), beg, end, io, err, t, + 'y'); + } + }; + + template<typename _CharT, bool _Intl> + struct moneypunct_shim : std::moneypunct<_CharT, _Intl>, facet::__shim + { + typedef typename moneypunct<_CharT, _Intl>::__cache_type __cache_type; + + // f must point to a type derived from moneypunct<C>[abi:other] + moneypunct_shim(const facet* f, __cache_type* c = new __cache_type) + : std::moneypunct<_CharT, _Intl>(c), __shim(f), _M_cache(c) + { + __moneypunct_fill_cache(other_abi{}, f, c); + } + + ~moneypunct_shim() + { + // stop GNU locale's ~moneypunct() from freeing these strings + _M_cache->_M_grouping_size = 0; + _M_cache->_M_curr_symbol_size = 0; + _M_cache->_M_positive_sign_size = 0; + _M_cache->_M_negative_sign_size = 0; + } + + // No need to override any virtual functions, the base definitions + // will return the cached data. + + __cache_type* _M_cache; + }; + + template class moneypunct_shim<char, true>; + template class moneypunct_shim<char, false>; + template class moneypunct_shim<wchar_t, true>; + template class moneypunct_shim<wchar_t, false>; + + template<typename _CharT> + struct money_get_shim : std::money_get<_CharT>, facet::__shim + { + typedef typename std::money_get<_CharT>::iter_type iter_type; + typedef typename std::money_get<_CharT>::char_type char_type; + typedef typename std::money_get<_CharT>::string_type string_type; + + // f must point to a type derived from money_get<C>[abi:other] + money_get_shim(const facet* f) : __shim(f) { } + + virtual iter_type + do_get(iter_type s, iter_type end, bool intl, ios_base& io, + ios_base::iostate& err, long double& units) const + { + ios_base::iostate err2 = ios_base::goodbit; + long double units2; + s = __money_get(other_abi{}, _M_get(), s, end, intl, io, err2, + &units2, nullptr); + if (err2 == ios_base::goodbit) + units = units2; + else + err = err2; + return s; + } + + virtual iter_type + do_get(iter_type s, iter_type end, bool intl, ios_base& io, + ios_base::iostate& err, string_type& digits) const + { + __any_string st; + ios_base::iostate err2 = ios_base::goodbit; + s = __money_get(other_abi{}, _M_get(), s, end, intl, io, err2, + nullptr, &st); + if (err2 == ios_base::goodbit) + digits = st; + else + err = err2; + return s; + } + }; + + template class money_get_shim<char>; + template class money_get_shim<wchar_t>; + + template<typename _CharT> + struct money_put_shim : std::money_put<_CharT>, facet::__shim + { + typedef typename std::money_put<_CharT>::iter_type iter_type; + typedef typename std::money_put<_CharT>::char_type char_type; + typedef typename std::money_put<_CharT>::string_type string_type; + + // f must point to a type derived from money_put<C>[abi:other] + money_put_shim(const facet* f) : __shim(f) { } + + virtual iter_type + do_put(iter_type s, bool intl, ios_base& io, + char_type fill, long double units) const + { + return __money_put(other_abi{}, _M_get(), s, intl, io, fill, units, + nullptr); + } + + virtual iter_type + do_put(iter_type s, bool intl, ios_base& io, + char_type fill, const string_type& digits) const + { + __any_string st; + st = digits; + return __money_put(other_abi{}, _M_get(), s, intl, io, fill, 0.L, + &st); + } + }; + + template class money_put_shim<char>; + template class money_put_shim<wchar_t>; + + + template<typename _CharT> + struct messages_shim : std::messages<_CharT>, facet::__shim + { + typedef messages_base::catalog catalog; + typedef basic_string<_CharT> string_type; + + // f must point to a type derived from messages<C>[abi:other] + messages_shim(const facet* f) : __shim(f) { } + + virtual catalog + do_open(const basic_string<char>& s, const locale& l) const + { + return __messages_open<_CharT>(other_abi{}, _M_get(), + s.c_str(), s.size(), l); + } + + virtual string_type + do_get(catalog c, int set, int msgid, const string_type& dfault) const + { + __any_string st; + __messages_get(other_abi{}, _M_get(), st, c, set, msgid, + dfault.c_str(), dfault.size()); + return st; + } + + virtual void + do_close(catalog c) const + { + __messages_close<_CharT>(other_abi{}, _M_get(), c); + } + }; + + template class messages_shim<char>; + template class messages_shim<wchar_t>; + + template<typename C> + inline size_t + __copy(const C*& dest, const basic_string<C>& s) + { + auto len = s.length(); + C* p = new C[len+1]; + s.copy(p, len); + p[len] = '\0'; + dest = p; + return len; + } + + } // namespace + + // Now define and instantiate the functions that will be called by the + // shim facets defined when this file is recompiled for the other ABI. + + template<typename C> + void + __numpunct_fill_cache(current_abi, const facet* f, __numpunct_cache<C>* c, + const char*& grouping, size_t& grouping_size) + { + auto* m = static_cast<const numpunct<C>*>(f); + + c->_M_decimal_point = m->decimal_point(); + c->_M_thousands_sep = m->thousands_sep(); + + c->_M_truename = nullptr; + c->_M_falsename = nullptr; + // set _M_allocated so that if any allocation fails the previously + // allocated strings will be deleted in ~__numpunct_c() + c->_M_allocated = true; + + c->_M_truename_size = __copy(c->_M_truename, m->truename()); + c->_M_falsename_size = __copy(c->_M_falsename, m->falsename()); + // Set grouping last as it is only deleted by ~numpunct_shim() which + // won't run if this function throws an exception. + grouping_size = __copy(grouping, m->grouping()); + } + + template void + __numpunct_fill_cache(current_abi, const facet*, __numpunct_cache<char>*, + const char*&, size_t&); + + template void + __numpunct_fill_cache(current_abi, const facet*, __numpunct_cache<wchar_t>*, + const char*&, size_t&); + + template<typename C> + int + __collate_compare(current_abi, const facet* f, const C* lo1, const C* hi1, + const C* lo2, const C* hi2) + { + return static_cast<const collate<C>*>(f)->compare(lo1, hi1, lo2, hi2); + } + + template int + __collate_compare(current_abi, const facet*, const char*, const char*, + const char*, const char*); + + template int + __collate_compare(current_abi, const facet*, const wchar_t*, const wchar_t*, + const wchar_t*, const wchar_t*); + + template<typename C> + void + __collate_transform(current_abi, const facet* f, __any_string& st, + const C* __lo, const C* __hi) + { + auto* c = static_cast<const collate<C>*>(f); + st = c->transform(__lo, __hi); + } + + template void + __collate_transform(current_abi, const facet*, __any_string&, + const char*, const char*); + + template void + __collate_transform(current_abi, const facet*, __any_string&, + const wchar_t*, const wchar_t*); + + template<typename C, bool Intl> + void + __moneypunct_fill_cache(current_abi, const facet* f, + __moneypunct_cache<C, Intl>* c) + { + auto* m = static_cast<const moneypunct<C, Intl>*>(f); + + c->_M_decimal_point = m->decimal_point(); + c->_M_thousands_sep = m->thousands_sep(); + c->_M_frac_digits = m->frac_digits(); + + c->_M_grouping = nullptr; + c->_M_curr_symbol = nullptr; + c->_M_positive_sign = nullptr; + c->_M_negative_sign = nullptr; + // set _M_allocated so that if any allocation fails the previously + // allocated strings will be deleted in ~__moneypunct_c() + c->_M_allocated = true; + + c->_M_grouping_size = __copy(c->_M_grouping, m->grouping()); + c->_M_curr_symbol_size = __copy(c->_M_curr_symbol, m->curr_symbol()); + c->_M_positive_sign_size + = __copy(c->_M_positive_sign, m->positive_sign()); + c->_M_negative_sign_size + = __copy(c->_M_negative_sign, m->negative_sign()); + + c->_M_pos_format = m->pos_format(); + c->_M_neg_format = m->neg_format(); + } + + template void + __moneypunct_fill_cache(current_abi, const facet*, + __moneypunct_cache<char, true>*); + + template void + __moneypunct_fill_cache(current_abi, const facet*, + __moneypunct_cache<char, false>*); + + template void + __moneypunct_fill_cache(current_abi, const facet*, + __moneypunct_cache<wchar_t, true>*); + + template void + __moneypunct_fill_cache(current_abi, const facet*, + __moneypunct_cache<wchar_t, false>*); + + template<typename C> + messages_base::catalog + __messages_open(current_abi, const facet* f, const char* s, size_t n, + const locale& l) + { + auto* m = static_cast<const messages<C>*>(f); + string str(s, n); + return m->open(str, l); + } + + template messages_base::catalog + __messages_open<char>(current_abi, const facet*, const char*, size_t, + const locale&); + + template messages_base::catalog + __messages_open<wchar_t>(current_abi, const facet*, const char*, size_t, + const locale&); + + template<typename C> + void + __messages_get(current_abi, const facet* f, __any_string& st, + messages_base::catalog c, int set, int msgid, + const C* s, size_t n) + { + auto* m = static_cast<const messages<C>*>(f); + st = m->get(c, set, msgid, basic_string<C>(s, n)); + } + + template void + __messages_get(current_abi, const facet*, __any_string&, + messages_base::catalog, int, int, const char*, size_t); + + template void + __messages_get(current_abi, const facet*, __any_string&, + messages_base::catalog, int, int, const wchar_t*, size_t); + + template<typename C> + void + __messages_close(current_abi, const facet* f, messages_base::catalog c) + { + static_cast<const messages<C>*>(f)->close(c); + } + + template void + __messages_close<char>(current_abi, const facet*, messages_base::catalog c); + + template void + __messages_close<wchar_t>(current_abi, const facet*, + messages_base::catalog c); + + template<typename C> + time_base::dateorder + __time_get_dateorder(current_abi, const facet* f) + { return static_cast<const time_get<C>*>(f)->date_order(); } + + template time_base::dateorder + __time_get_dateorder<char>(current_abi, const facet*); + + template time_base::dateorder + __time_get_dateorder<wchar_t>(current_abi, const facet*); + + template<typename C> + istreambuf_iterator<C> + __time_get(current_abi, const facet* f, + istreambuf_iterator<C> beg, istreambuf_iterator<C> end, + ios_base& io, ios_base::iostate& err, tm* t, char which) + { + auto* g = static_cast<const time_get<C>*>(f); + switch(which) + { + case 't': + return g->get_time(beg, end, io, err, t); + case 'd': + return g->get_date(beg, end, io, err, t); + case 'w': + return g->get_weekday(beg, end, io, err, t); + case 'm': + return g->get_monthname(beg, end, io, err, t); + case 'y': + return g->get_year(beg, end, io, err, t); + default: + __builtin_unreachable(); + } + } + + template istreambuf_iterator<char> + __time_get(current_abi, const facet*, + istreambuf_iterator<char>, istreambuf_iterator<char>, + ios_base&, ios_base::iostate&, tm*, char); + + template istreambuf_iterator<wchar_t> + __time_get(current_abi, const facet*, + istreambuf_iterator<wchar_t>, istreambuf_iterator<wchar_t>, + ios_base&, ios_base::iostate&, tm*, char); + + template<typename C> + istreambuf_iterator<C> + __money_get(current_abi, const facet* f, + istreambuf_iterator<C> s, istreambuf_iterator<C> end, + bool intl, ios_base& str, ios_base::iostate& err, + long double* units, __any_string* digits) + { + auto* m = static_cast<const money_get<C>*>(f); + if (units) + return m->get(s, end, intl, str, err, *units); + basic_string<C> digits2; + s = m->get(s, end, intl, str, err, digits2); + if (err == ios_base::goodbit) + *digits = digits2; + return s; + } + + template istreambuf_iterator<char> + __money_get(current_abi, const facet*, + istreambuf_iterator<char>, istreambuf_iterator<char>, + bool, ios_base&, ios_base::iostate&, + long double*, __any_string*); + + template istreambuf_iterator<wchar_t> + __money_get(current_abi, const facet*, + istreambuf_iterator<wchar_t>, istreambuf_iterator<wchar_t>, + bool, ios_base&, ios_base::iostate&, + long double*, __any_string*); + + template<typename C> + ostreambuf_iterator<C> + __money_put(current_abi, const facet* f, ostreambuf_iterator<C> s, + bool intl, ios_base& io, C fill, long double units, + const __any_string* digits) + { + auto* m = static_cast<const money_put<C>*>(f); + if (digits) + return m->put(s, intl, io, fill, *digits); + else + return m->put(s, intl, io, fill, units); + } + + template ostreambuf_iterator<char> + __money_put(current_abi, const facet*, ostreambuf_iterator<char>, + bool, ios_base&, char, long double, const __any_string*); + + template ostreambuf_iterator<wchar_t> + __money_put(current_abi, const facet*, ostreambuf_iterator<wchar_t>, + bool, ios_base&, wchar_t, long double, const __any_string*); + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace __facet_shims + +_GLIBCXX_BEGIN_NAMESPACE_VERSION + // Create a new shim facet of type WHICH that forwards calls to F. + // F is the replacement facet provided by the user, WHICH is the ID of + // F's "other ABI twin" which we are replacing with a shim. + const locale::facet* +#if _GLIBCXX_USE_CXX11_ABI + locale::facet::_M_sso_shim(const locale::id* which) const +#else + locale::facet::_M_cow_shim(const locale::id* which) const +#endif + { + using namespace __facet_shims; + + // If this is already a shim just use its underlying facet. + if (auto* p = dynamic_cast<const __shim*>(this)) + return p->_M_get(); + + if (which == &numpunct<char>::id) + return new numpunct_shim<char>{this}; + if (which == &std::collate<char>::id) + return new collate_shim<char>{this}; + if (which == &time_get<char>::id) + return new time_get_shim<char>{this}; + if (which == &money_get<char>::id) + return new money_get_shim<char>{this}; + if (which == &money_put<char>::id) + return new money_put_shim<char>{this}; + if (which == &moneypunct<char, true>::id) + return new moneypunct_shim<char, true>{this}; + if (which == &moneypunct<char, false>::id) + return new moneypunct_shim<char, false>{this}; + if (which == &std::messages<char>::id) + return new messages_shim<char>{this}; +#ifdef _GLIBCXX_USE_WCHAR_T + if (which == &numpunct<wchar_t>::id) + return new numpunct_shim<wchar_t>{this}; + if (which == &std::collate<wchar_t>::id) + return new collate_shim<wchar_t>{this}; + if (which == &time_get<wchar_t>::id) + return new time_get_shim<wchar_t>{this}; + if (which == &money_get<wchar_t>::id) + return new money_get_shim<wchar_t>{this}; + if (which == &money_put<wchar_t>::id) + return new money_put_shim<wchar_t>{this}; + if (which == &moneypunct<wchar_t, true>::id) + return new moneypunct_shim<wchar_t, true>{this}; + if (which == &moneypunct<wchar_t, false>::id) + return new moneypunct_shim<wchar_t, false>{this}; + if (which == &std::messages<wchar_t>::id) + return new messages_shim<wchar_t>{this}; +#endif + __throw_logic_error("cannot create shim for unknown locale::facet"); + } + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace std diff --git a/libstdc++-v3/src/c++11/cxx11-stdexcept.cc b/libstdc++-v3/src/c++11/cxx11-stdexcept.cc new file mode 100644 index 0000000..64158c7 --- /dev/null +++ b/libstdc++-v3/src/c++11/cxx11-stdexcept.cc @@ -0,0 +1,78 @@ +// Methods for Exception Support for -*- C++ -*- + +// Copyright (C) 2014 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library 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 3, or (at your option) +// any later version. + +// This library 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. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +// +// ISO C++ 14882: 19.1 Exception classes +// + +#define _GLIBCXX_USE_CXX11_ABI 1 +#include <stdexcept> + +#if ! _GLIBCXX_USE_DUAL_ABI +# error This file should not be compiled for this configuration. +#endif + +namespace std _GLIBCXX_VISIBILITY(default) +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + // These constructors take an abi-tagged std::string and use it to + // initialize an untagged COW std::string in _M_msg. + + logic_error::logic_error(const string& __arg) + : _M_msg(__arg) { } + + runtime_error::runtime_error(const string& __arg) + : _M_msg(__arg) { } + + // These constructors take an abi-tagged std::string and pass it to the + // base class constructors defined above. + + domain_error::domain_error(const string& __arg) + : logic_error(__arg) { } + + invalid_argument::invalid_argument(const string& __arg) + : logic_error(__arg) { } + + length_error::length_error(const string& __arg) + : logic_error(__arg) { } + + out_of_range::out_of_range(const string& __arg) + : logic_error(__arg) { } + + range_error::range_error(const string& __arg) + : runtime_error(__arg) { } + + overflow_error::overflow_error(const string& __arg) + : runtime_error(__arg) { } + + underflow_error::underflow_error(const string& __arg) + : runtime_error(__arg) { } + + // Converting constructor from ABI-tagged std::string to COW string. + __cow_string::__cow_string(const string& s) + : __cow_string(s.c_str(), s.length()) { } + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace diff --git a/libstdc++-v3/src/c++11/cxx11-wlocale-inst.cc b/libstdc++-v3/src/c++11/cxx11-wlocale-inst.cc new file mode 100644 index 0000000..ba99355 --- /dev/null +++ b/libstdc++-v3/src/c++11/cxx11-wlocale-inst.cc @@ -0,0 +1,32 @@ +// Copyright (C) 2014 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library 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 3, or (at your option) +// any later version. + +// This library 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. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +// +// ISO C++ 14882: 22.1 Locales +// + +#define _GLIBCXX_USE_CXX11_ABI 1 +#include <bits/c++config.h> +#ifdef _GLIBCXX_USE_WCHAR_T +#define C wchar_t +#include "cxx11-locale-inst.cc" +#endif diff --git a/libstdc++-v3/src/c++11/fstream-inst.cc b/libstdc++-v3/src/c++11/fstream-inst.cc index 0ef5fc4..2e3e174 100644 --- a/libstdc++-v3/src/c++11/fstream-inst.cc +++ b/libstdc++-v3/src/c++11/fstream-inst.cc @@ -26,6 +26,7 @@ // ISO C++ 14882: // +#define _GLIBCXX_USE_CXX11_ABI 1 #include <fstream> namespace std _GLIBCXX_VISIBILITY(default) diff --git a/libstdc++-v3/src/c++11/functexcept.cc b/libstdc++-v3/src/c++11/functexcept.cc index d184bfc..9d05502 100644 --- a/libstdc++-v3/src/c++11/functexcept.cc +++ b/libstdc++-v3/src/c++11/functexcept.cc @@ -20,6 +20,9 @@ // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. +// We don't want to change the type thrown by __throw_ios_failure (yet?) +#define _GLIBCXX_USE_CXX11_ABI 0 + #include <bits/functexcept.h> #include <cstdlib> #include <exception> diff --git a/libstdc++-v3/src/c++11/random.cc b/libstdc++-v3/src/c++11/random.cc index f61daea..cb25f00 100644 --- a/libstdc++-v3/src/c++11/random.cc +++ b/libstdc++-v3/src/c++11/random.cc @@ -22,6 +22,7 @@ // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. +#define _GLIBCXX_USE_CXX11_ABI 1 #include <random> #ifdef _GLIBCXX_USE_C99_STDINT_TR1 diff --git a/libstdc++-v3/src/c++11/sstream-inst.cc b/libstdc++-v3/src/c++11/sstream-inst.cc index 728946e..ea89fbf 100644 --- a/libstdc++-v3/src/c++11/sstream-inst.cc +++ b/libstdc++-v3/src/c++11/sstream-inst.cc @@ -26,6 +26,11 @@ // ISO C++ 14882: // +#ifndef _GLIBCXX_USE_CXX11_ABI +// Instantiations in this file use the new SSO std::string ABI unless included +// by another file which defines _GLIBCXX_USE_CXX11_ABI=0. +# define _GLIBCXX_USE_CXX11_ABI 1 +#endif #include <sstream> namespace std _GLIBCXX_VISIBILITY(default) diff --git a/libstdc++-v3/src/c++11/string-inst.cc b/libstdc++-v3/src/c++11/string-inst.cc index f19a0b0..a892d5d 100644 --- a/libstdc++-v3/src/c++11/string-inst.cc +++ b/libstdc++-v3/src/c++11/string-inst.cc @@ -29,6 +29,12 @@ // Written by Jason Merrill based upon the specification by Takanori Adachi // in ANSI X3J16/94-0013R2. Rewritten by Nathan Myers. +#ifndef _GLIBCXX_USE_CXX11_ABI +// Instantiations in this file use the new SSO std::string ABI unless included +// by another file which defines _GLIBCXX_USE_CXX11_ABI=0. +# define _GLIBCXX_USE_CXX11_ABI 1 +#endif + #include <string> // Instantiation configuration. @@ -49,7 +55,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // Only one template keyword allowed here. // See core issue #46 (NAD) - // http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/cwg_closed.html#46 + // http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#46 template S::basic_string(C*, C*, const allocator<C>&); @@ -59,6 +65,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template S::basic_string(S::iterator, S::iterator, const allocator<C>&); +#if _GLIBCXX_USE_CXX11_ABI + template + void + S::_M_construct(S::iterator, S::iterator, forward_iterator_tag); + + template + void + S::_M_construct(S::const_iterator, S::const_iterator, + forward_iterator_tag); + + template + void + S::_M_construct(C*, C*, forward_iterator_tag); + + template + void + S::_M_construct(const C*, const C*, forward_iterator_tag); + +#else // !_GLIBCXX_USE_CXX11_ABI + template C* S::_S_construct(S::iterator, S::iterator, @@ -72,6 +98,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION C* S::_S_construct(const C*, const C*, const allocator<C>&, forward_iterator_tag); +#endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace diff --git a/libstdc++-v3/src/c++11/system_error.cc b/libstdc++-v3/src/c++11/system_error.cc index 5bd59f0..30e480d 100644 --- a/libstdc++-v3/src/c++11/system_error.cc +++ b/libstdc++-v3/src/c++11/system_error.cc @@ -23,10 +23,13 @@ // <http://www.gnu.org/licenses/>. +#define _GLIBCXX_USE_CXX11_ABI 1 +#define __sso_string __sso_stringxxx #include <cstring> #include <system_error> #include <bits/functexcept.h> #include <limits> +#undef __sso_string namespace { @@ -73,10 +76,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION error_category::~error_category() noexcept = default; const error_category& - system_category() noexcept { return system_category_instance; } + _V2::system_category() noexcept { return system_category_instance; } const error_category& - generic_category() noexcept { return generic_category_instance; } + _V2::generic_category() noexcept { return generic_category_instance; } system_error::~system_error() noexcept = default; @@ -97,5 +100,80 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION error_code::default_error_condition() const noexcept { return category().default_error_condition(value()); } +#if _GLIBCXX_USE_CXX11_ABI + // Return error_category::message() as a COW string + __cow_string + error_category::_M_message(int i) const + { + string msg = this->message(i); + return {msg.c_str(), msg.length()}; + } +#endif + +#if _GLIBCXX_USE_DUAL_ABI + // Redefine __sso_string so that we can define and export its members + // in terms of the SSO std::string. + struct __sso_string + { + struct __str + { + const char* _M_p; + size_t _M_string_length; + char _M_local_buf[16]; + }; + + union { + __str _M_s; + char _M_bytes[sizeof(_M_s)]; + std::string _M_str; + }; + + __sso_string(); + __sso_string(const std::string& s); + __sso_string(const char*, size_t n); + __sso_string(const __sso_string&) noexcept; + __sso_string& operator=(const __sso_string&) noexcept; + ~__sso_string(); + __sso_string(__sso_string&&) noexcept; + __sso_string& operator=(__sso_string&&) noexcept; + }; + + __sso_string::__sso_string() : _M_str() { } + +#if _GLIBCXX_USE_CXX11_ABI + static_assert(sizeof(__sso_string) == sizeof(std::string), + "sizeof(std::string) has changed"); + static_assert(alignof(__sso_string) == alignof(std::string), + "alignof(std::string) has changed"); + + // This constructor is defined in src/c++11/cow-stdexcept.cc for COW strings + __sso_string::__sso_string(const std::string& s) : _M_str(s) { } +#endif + + __sso_string::__sso_string(const char* s, size_t n) : _M_str(s, n) { } + + __sso_string::__sso_string(const __sso_string& s) noexcept + : _M_str(s._M_str) { } + + __sso_string& + __sso_string::operator=(const __sso_string& s) noexcept + { + _M_str = s._M_str; + return *this; + } + + __sso_string::~__sso_string() { _M_str.~basic_string(); } + + __sso_string::__sso_string(__sso_string&& s) noexcept + : _M_str(std::move(s._M_str)) { } + + __sso_string& + __sso_string::operator=(__sso_string&& s) noexcept + { + _M_str = std::move(s._M_str); + return *this; + } +#endif // _GLIBCXX_USE_DUAL_ABI + _GLIBCXX_END_NAMESPACE_VERSION } // namespace diff --git a/libstdc++-v3/src/c++11/wstring-inst.cc b/libstdc++-v3/src/c++11/wstring-inst.cc index 8c9f901..65425b0 100644 --- a/libstdc++-v3/src/c++11/wstring-inst.cc +++ b/libstdc++-v3/src/c++11/wstring-inst.cc @@ -26,6 +26,7 @@ // ISO C++ 14882: 21 Strings library // +#define _GLIBCXX_USE_CXX11_ABI 1 #include <bits/c++config.h> #ifdef _GLIBCXX_USE_WCHAR_T diff --git a/libstdc++-v3/src/c++98/Makefile.am b/libstdc++-v3/src/c++98/Makefile.am index 9afe904..e3e540d 100644 --- a/libstdc++-v3/src/c++98/Makefile.am +++ b/libstdc++-v3/src/c++98/Makefile.am @@ -27,9 +27,18 @@ noinst_LTLIBRARIES = libc++98convenience.la headers = +if ENABLE_DUAL_ABI +cow_string_host_sources = \ + collate_members_cow.cc \ + messages_members_cow.cc \ + monetary_members_cow.cc \ + numeric_members_cow.cc +endif + # Source files linked in via configuration/make substitution for a # particular host. host_sources = \ + $(cow_string_host_sources) \ atomicity.cc \ codecvt_members.cc \ collate_members.cc \ @@ -60,6 +69,20 @@ atomicity_file = ${glibcxx_srcdir}/$(ATOMICITY_SRCDIR)/atomicity.h atomicity.cc: ${atomicity_file} $(LN_S) ${atomicity_file} ./atomicity.cc || true +if ENABLE_DUAL_ABI +collate_members_cow.cc: ${glibcxx_srcdir}/$(CCOLLATE_CC) + $(LN_S) ${glibcxx_srcdir}/$(CCOLLATE_CC) ./$@ || true + +messages_members_cow.cc: ${glibcxx_srcdir}/$(CMESSAGES_CC) + $(LN_S) ${glibcxx_srcdir}/$(CMESSAGES_CC) ./$@ || true + +monetary_members_cow.cc: ${glibcxx_srcdir}/$(CMONEY_CC) + $(LN_S) ${glibcxx_srcdir}/$(CMONEY_CC) ./$@ || true + +numeric_members_cow.cc: ${glibcxx_srcdir}/$(CNUMERIC_CC) + $(LN_S) ${glibcxx_srcdir}/$(CNUMERIC_CC) ./$@ || true +endif + # Source files linked in via configuration/make substitution for a # particular host, but with ad hoc naming rules. host_sources_extra = \ @@ -72,6 +95,12 @@ c++locale.cc: ${glibcxx_srcdir}/$(CLOCALE_CC) basic_file.cc: ${glibcxx_srcdir}/$(BASIC_FILE_CC) $(LN_S) ${glibcxx_srcdir}/$(BASIC_FILE_CC) ./$@ || true +if ENABLE_DUAL_ABI +cxx11_abi_sources = \ + cow-istream-string.cc +else +cxx11_abi_sources = +endif if ENABLE_EXTERN_TEMPLATE # XTEMPLATE_FLAGS = -fno-implicit-templates @@ -117,8 +146,10 @@ sources = \ strstream.cc \ tree.cc \ istream.cc \ + istream-string.cc \ streambuf.cc \ valarray.cc \ + ${cxx11_abi_sources} \ ${host_sources} \ ${host_sources_extra} @@ -126,6 +157,27 @@ vpath % $(top_srcdir)/src/c++98 libc__98convenience_la_SOURCES = $(sources) +if ENABLE_DUAL_ABI +GLIBCXX_ABI_FLAGS = -D_GLIBCXX_USE_CXX11_ABI=@glibcxx_cxx98_abi@ +# Use special rules to compile with the non-default string ABI. +collate_members_cow.lo: collate_members_cow.cc + $(LTCXXCOMPILE) $(GLIBCXX_ABI_FLAGS) -fimplicit-templates -c $< +collate_members_cow.o: collate_members_cow.cc + $(CXXCOMPILE) $(GLIBCXX_ABI_FLAGS) -fimplicit-templates -c $< +messages_members_cow.lo: messages_members_cow.cc + $(LTCXXCOMPILE) $(GLIBCXX_ABI_FLAGS) -fimplicit-templates -c $< +messages_members_cow.o: messages_members_cow.cc + $(CXXCOMPILE) $(GLIBCXX_ABI_FLAGS) -fimplicit-templates -c $< +monetary_members_cow.lo: monetary_members_cow.cc + $(LTCXXCOMPILE) $(GLIBCXX_ABI_FLAGS) -fimplicit-templates -c $< +monetary_members_cow.o: monetary_members_cow.cc + $(CXXCOMPILE) $(GLIBCXX_ABI_FLAGS) -fimplicit-templates -c $< +numeric_members_cow.lo: numeric_members_cow.cc + $(LTCXXCOMPILE) $(GLIBCXX_ABI_FLAGS) -fimplicit-templates -c $< +numeric_members_cow.o: numeric_members_cow.cc + $(CXXCOMPILE) $(GLIBCXX_ABI_FLAGS) -fimplicit-templates -c $< +endif + # Use special rules for the deprecated source files so that they find # deprecated include files. GLIBCXX_INCLUDE_DIR=$(glibcxx_builddir)/include diff --git a/libstdc++-v3/src/c++98/Makefile.in b/libstdc++-v3/src/c++98/Makefile.in index 9d93792..bd8fd3d 100644 --- a/libstdc++-v3/src/c++98/Makefile.in +++ b/libstdc++-v3/src/c++98/Makefile.in @@ -67,25 +67,31 @@ CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libc__98convenience_la_LIBADD = -am__objects_1 = atomicity.lo codecvt_members.lo collate_members.lo \ - messages_members.lo monetary_members.lo numeric_members.lo \ - time_members.lo -@ENABLE_EXTERN_TEMPLATE_TRUE@am__objects_2 = allocator-inst.lo \ +@ENABLE_DUAL_ABI_TRUE@am__objects_1 = cow-istream-string.lo +@ENABLE_DUAL_ABI_TRUE@am__objects_2 = collate_members_cow.lo \ +@ENABLE_DUAL_ABI_TRUE@ messages_members_cow.lo \ +@ENABLE_DUAL_ABI_TRUE@ monetary_members_cow.lo \ +@ENABLE_DUAL_ABI_TRUE@ numeric_members_cow.lo +am__objects_3 = $(am__objects_2) atomicity.lo codecvt_members.lo \ + collate_members.lo messages_members.lo monetary_members.lo \ + numeric_members.lo time_members.lo +@ENABLE_EXTERN_TEMPLATE_TRUE@am__objects_4 = allocator-inst.lo \ @ENABLE_EXTERN_TEMPLATE_TRUE@ concept-inst.lo ext-inst.lo \ @ENABLE_EXTERN_TEMPLATE_TRUE@ locale-inst.lo misc-inst.lo \ @ENABLE_EXTERN_TEMPLATE_TRUE@ wlocale-inst.lo -am__objects_3 = parallel_settings.lo -am__objects_4 = basic_file.lo c++locale.lo $(am__objects_2) \ - $(am__objects_3) -am__objects_5 = bitmap_allocator.lo pool_allocator.lo mt_allocator.lo \ +am__objects_5 = parallel_settings.lo +am__objects_6 = basic_file.lo c++locale.lo $(am__objects_4) \ + $(am__objects_5) +am__objects_7 = bitmap_allocator.lo pool_allocator.lo mt_allocator.lo \ codecvt.lo complex_io.lo globals_io.lo hash_tr1.lo \ hashtable_tr1.lo ios_failure.lo ios_init.lo ios_locale.lo \ list.lo list-aux.lo list-aux-2.lo list_associated.lo \ list_associated-2.lo locale.lo locale_init.lo locale_facets.lo \ localename.lo math_stubs_float.lo math_stubs_long_double.lo \ - stdexcept.lo strstream.lo tree.lo istream.lo streambuf.lo \ - valarray.lo $(am__objects_1) $(am__objects_4) -am_libc__98convenience_la_OBJECTS = $(am__objects_5) + stdexcept.lo strstream.lo tree.lo istream.lo istream-string.lo \ + streambuf.lo valarray.lo $(am__objects_1) $(am__objects_3) \ + $(am__objects_6) +am_libc__98convenience_la_OBJECTS = $(am__objects_7) libc__98convenience_la_OBJECTS = $(am_libc__98convenience_la_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = @@ -245,6 +251,7 @@ glibcxx_POFILES = @glibcxx_POFILES@ glibcxx_builddir = @glibcxx_builddir@ glibcxx_compiler_pic_flag = @glibcxx_compiler_pic_flag@ glibcxx_compiler_shared_flag = @glibcxx_compiler_shared_flag@ +glibcxx_cxx98_abi = @glibcxx_cxx98_abi@ glibcxx_localedir = @glibcxx_localedir@ glibcxx_lt_pic_flag = @glibcxx_lt_pic_flag@ glibcxx_prefixdir = @glibcxx_prefixdir@ @@ -321,10 +328,17 @@ AM_CPPFLAGS = $(GLIBCXX_INCLUDES) # Convenience library for C++98 runtime. noinst_LTLIBRARIES = libc++98convenience.la headers = +@ENABLE_DUAL_ABI_TRUE@cow_string_host_sources = \ +@ENABLE_DUAL_ABI_TRUE@ collate_members_cow.cc \ +@ENABLE_DUAL_ABI_TRUE@ messages_members_cow.cc \ +@ENABLE_DUAL_ABI_TRUE@ monetary_members_cow.cc \ +@ENABLE_DUAL_ABI_TRUE@ numeric_members_cow.cc + # Source files linked in via configuration/make substitution for a # particular host. host_sources = \ + $(cow_string_host_sources) \ atomicity.cc \ codecvt_members.cc \ collate_members.cc \ @@ -341,6 +355,10 @@ host_sources_extra = \ basic_file.cc c++locale.cc \ ${inst_sources} ${parallel_sources} +@ENABLE_DUAL_ABI_FALSE@cxx11_abi_sources = +@ENABLE_DUAL_ABI_TRUE@cxx11_abi_sources = \ +@ENABLE_DUAL_ABI_TRUE@ cow-istream-string.cc + # XTEMPLATE_FLAGS = @ENABLE_EXTERN_TEMPLATE_FALSE@inst_sources = @@ -383,12 +401,15 @@ sources = \ strstream.cc \ tree.cc \ istream.cc \ + istream-string.cc \ streambuf.cc \ valarray.cc \ + ${cxx11_abi_sources} \ ${host_sources} \ ${host_sources_extra} libc__98convenience_la_SOURCES = $(sources) +@ENABLE_DUAL_ABI_TRUE@GLIBCXX_ABI_FLAGS = -D_GLIBCXX_USE_CXX11_ABI=@glibcxx_cxx98_abi@ # Use special rules for the deprecated source files so that they find # deprecated include files. @@ -710,6 +731,18 @@ time_members.cc: ${glibcxx_srcdir}/$(CTIME_CC) atomicity.cc: ${atomicity_file} $(LN_S) ${atomicity_file} ./atomicity.cc || true +@ENABLE_DUAL_ABI_TRUE@collate_members_cow.cc: ${glibcxx_srcdir}/$(CCOLLATE_CC) +@ENABLE_DUAL_ABI_TRUE@ $(LN_S) ${glibcxx_srcdir}/$(CCOLLATE_CC) ./$@ || true + +@ENABLE_DUAL_ABI_TRUE@messages_members_cow.cc: ${glibcxx_srcdir}/$(CMESSAGES_CC) +@ENABLE_DUAL_ABI_TRUE@ $(LN_S) ${glibcxx_srcdir}/$(CMESSAGES_CC) ./$@ || true + +@ENABLE_DUAL_ABI_TRUE@monetary_members_cow.cc: ${glibcxx_srcdir}/$(CMONEY_CC) +@ENABLE_DUAL_ABI_TRUE@ $(LN_S) ${glibcxx_srcdir}/$(CMONEY_CC) ./$@ || true + +@ENABLE_DUAL_ABI_TRUE@numeric_members_cow.cc: ${glibcxx_srcdir}/$(CNUMERIC_CC) +@ENABLE_DUAL_ABI_TRUE@ $(LN_S) ${glibcxx_srcdir}/$(CNUMERIC_CC) ./$@ || true + c++locale.cc: ${glibcxx_srcdir}/$(CLOCALE_CC) $(LN_S) ${glibcxx_srcdir}/$(CLOCALE_CC) ./$@ || true @@ -717,6 +750,23 @@ basic_file.cc: ${glibcxx_srcdir}/$(BASIC_FILE_CC) $(LN_S) ${glibcxx_srcdir}/$(BASIC_FILE_CC) ./$@ || true vpath % $(top_srcdir)/src/c++98 +# Use special rules to compile with the non-default string ABI. +@ENABLE_DUAL_ABI_TRUE@collate_members_cow.lo: collate_members_cow.cc +@ENABLE_DUAL_ABI_TRUE@ $(LTCXXCOMPILE) $(GLIBCXX_ABI_FLAGS) -fimplicit-templates -c $< +@ENABLE_DUAL_ABI_TRUE@collate_members_cow.o: collate_members_cow.cc +@ENABLE_DUAL_ABI_TRUE@ $(CXXCOMPILE) $(GLIBCXX_ABI_FLAGS) -fimplicit-templates -c $< +@ENABLE_DUAL_ABI_TRUE@messages_members_cow.lo: messages_members_cow.cc +@ENABLE_DUAL_ABI_TRUE@ $(LTCXXCOMPILE) $(GLIBCXX_ABI_FLAGS) -fimplicit-templates -c $< +@ENABLE_DUAL_ABI_TRUE@messages_members_cow.o: messages_members_cow.cc +@ENABLE_DUAL_ABI_TRUE@ $(CXXCOMPILE) $(GLIBCXX_ABI_FLAGS) -fimplicit-templates -c $< +@ENABLE_DUAL_ABI_TRUE@monetary_members_cow.lo: monetary_members_cow.cc +@ENABLE_DUAL_ABI_TRUE@ $(LTCXXCOMPILE) $(GLIBCXX_ABI_FLAGS) -fimplicit-templates -c $< +@ENABLE_DUAL_ABI_TRUE@monetary_members_cow.o: monetary_members_cow.cc +@ENABLE_DUAL_ABI_TRUE@ $(CXXCOMPILE) $(GLIBCXX_ABI_FLAGS) -fimplicit-templates -c $< +@ENABLE_DUAL_ABI_TRUE@numeric_members_cow.lo: numeric_members_cow.cc +@ENABLE_DUAL_ABI_TRUE@ $(LTCXXCOMPILE) $(GLIBCXX_ABI_FLAGS) -fimplicit-templates -c $< +@ENABLE_DUAL_ABI_TRUE@numeric_members_cow.o: numeric_members_cow.cc +@ENABLE_DUAL_ABI_TRUE@ $(CXXCOMPILE) $(GLIBCXX_ABI_FLAGS) -fimplicit-templates -c $< strstream.lo: strstream.cc $(LTCXXCOMPILE) -I$(GLIBCXX_INCLUDE_DIR)/backward -Wno-deprecated -c $< strstream.o: strstream.cc diff --git a/libstdc++-v3/src/c++98/compatibility-ldbl.cc b/libstdc++-v3/src/c++98/compatibility-ldbl.cc index bbef3b2..1543d40 100644 --- a/libstdc++-v3/src/c++98/compatibility-ldbl.cc +++ b/libstdc++-v3/src/c++98/compatibility-ldbl.cc @@ -22,6 +22,7 @@ // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. +#define _GLIBCXX_USE_CXX11_ABI 0 #include <locale> #include <cmath> #include <tr1/functional> diff --git a/libstdc++-v3/src/c++98/compatibility.cc b/libstdc++-v3/src/c++98/compatibility.cc index b33cbe7568..2d432e7 100644 --- a/libstdc++-v3/src/c++98/compatibility.cc +++ b/libstdc++-v3/src/c++98/compatibility.cc @@ -22,6 +22,7 @@ // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. +#define _GLIBCXX_USE_CXX11_ABI 0 #include <bits/c++config.h> #if defined(_GLIBCXX_SYMVER_GNU) && defined(_GLIBCXX_SHARED) \ diff --git a/libstdc++-v3/src/c++98/concept-inst.cc b/libstdc++-v3/src/c++98/concept-inst.cc index 9ac9920..fd374f8 100644 --- a/libstdc++-v3/src/c++98/concept-inst.cc +++ b/libstdc++-v3/src/c++98/concept-inst.cc @@ -29,6 +29,7 @@ // explicitly instantiate the initial set of symbols; compiling this file // with -fimplicit-templates will take care of the rest for us. +#define _GLIBCXX_USE_CXX11_ABI 0 #include <bits/concept_check.h> #ifdef _GLIBCXX_CONCEPT_CHECKS diff --git a/libstdc++-v3/src/c++98/cow-istream-string.cc b/libstdc++-v3/src/c++98/cow-istream-string.cc new file mode 100644 index 0000000..32723bb --- /dev/null +++ b/libstdc++-v3/src/c++98/cow-istream-string.cc @@ -0,0 +1,30 @@ +// Input streams operating on strings -*- C++ -*- + +// Copyright (C) 2014 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library 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 3, or (at your option) +// any later version. + +// This library 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. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +// +// ISO C++ 14882: 27.6.1 Input streams +// + +#define _GLIBCXX_USE_CXX11_ABI 0 +#include "istream-string.cc" diff --git a/libstdc++-v3/src/c++98/hash_tr1.cc b/libstdc++-v3/src/c++98/hash_tr1.cc index 57547bb..1a74300 100644 --- a/libstdc++-v3/src/c++98/hash_tr1.cc +++ b/libstdc++-v3/src/c++98/hash_tr1.cc @@ -22,6 +22,7 @@ // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. +#define _GLIBCXX_USE_CXX11_ABI 0 #include <string> #include <tr1/functional> diff --git a/libstdc++-v3/src/c++98/istream-string.cc b/libstdc++-v3/src/c++98/istream-string.cc new file mode 100644 index 0000000..4580adc --- /dev/null +++ b/libstdc++-v3/src/c++98/istream-string.cc @@ -0,0 +1,291 @@ +// Input streams operating on strings-*- C++ -*- + +// Copyright (C) 2004-2014 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library 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 3, or (at your option) +// any later version. + +// This library 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. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +// +// ISO C++ 14882: 27.6.1 Input streams +// + +#ifndef _GLIBCXX_USE_CXX11_ABI +// Instantiations in this file use the new SSO std::string ABI unless included +// by another file which defines _GLIBCXX_USE_CXX11_ABI=0. +# define _GLIBCXX_USE_CXX11_ABI 1 +#endif +#include <istream> +#include <string> + +namespace std _GLIBCXX_VISIBILITY(default) +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + template<> + basic_istream<char>& + operator>>(basic_istream<char>& __in, basic_string<char>& __str) + { + typedef basic_istream<char> __istream_type; + typedef __istream_type::int_type __int_type; + typedef __istream_type::traits_type __traits_type; + typedef __istream_type::__streambuf_type __streambuf_type; + typedef __istream_type::__ctype_type __ctype_type; + typedef basic_string<char> __string_type; + typedef __string_type::size_type __size_type; + + __size_type __extracted = 0; + ios_base::iostate __err = ios_base::goodbit; + __istream_type::sentry __cerb(__in, false); + if (__cerb) + { + __try + { + __str.erase(); + const streamsize __w = __in.width(); + const __size_type __n = __w > 0 ? static_cast<__size_type>(__w) + : __str.max_size(); + const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc()); + const __int_type __eof = __traits_type::eof(); + __streambuf_type* __sb = __in.rdbuf(); + __int_type __c = __sb->sgetc(); + + while (__extracted < __n + && !__traits_type::eq_int_type(__c, __eof) + && !__ct.is(ctype_base::space, + __traits_type::to_char_type(__c))) + { + streamsize __size = std::min(streamsize(__sb->egptr() + - __sb->gptr()), + streamsize(__n - __extracted)); + if (__size > 1) + { + __size = (__ct.scan_is(ctype_base::space, + __sb->gptr() + 1, + __sb->gptr() + __size) + - __sb->gptr()); + __str.append(__sb->gptr(), __size); + __sb->__safe_gbump(__size); + __extracted += __size; + __c = __sb->sgetc(); + } + else + { + __str += __traits_type::to_char_type(__c); + ++__extracted; + __c = __sb->snextc(); + } + } + + if (__traits_type::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + __in.width(0); + } + __catch(__cxxabiv1::__forced_unwind&) + { + __in._M_setstate(ios_base::badbit); + __throw_exception_again; + } + __catch(...) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 91. Description of operator>> and getline() for string<> + // might cause endless loop + __in._M_setstate(ios_base::badbit); + } + } + if (!__extracted) + __err |= ios_base::failbit; + if (__err) + __in.setstate(__err); + return __in; + } + + template<> + basic_istream<char>& + getline(basic_istream<char>& __in, basic_string<char>& __str, + char __delim) + { + typedef basic_istream<char> __istream_type; + typedef __istream_type::int_type __int_type; + typedef __istream_type::char_type __char_type; + typedef __istream_type::traits_type __traits_type; + typedef __istream_type::__streambuf_type __streambuf_type; + typedef basic_string<char> __string_type; + typedef __string_type::size_type __size_type; + + __size_type __extracted = 0; + const __size_type __n = __str.max_size(); + ios_base::iostate __err = ios_base::goodbit; + __istream_type::sentry __cerb(__in, true); + if (__cerb) + { + __try + { + __str.erase(); + const __int_type __idelim = __traits_type::to_int_type(__delim); + const __int_type __eof = __traits_type::eof(); + __streambuf_type* __sb = __in.rdbuf(); + __int_type __c = __sb->sgetc(); + + while (__extracted < __n + && !__traits_type::eq_int_type(__c, __eof) + && !__traits_type::eq_int_type(__c, __idelim)) + { + streamsize __size = std::min(streamsize(__sb->egptr() + - __sb->gptr()), + streamsize(__n - __extracted)); + if (__size > 1) + { + const __char_type* __p = __traits_type::find(__sb->gptr(), + __size, + __delim); + if (__p) + __size = __p - __sb->gptr(); + __str.append(__sb->gptr(), __size); + __sb->__safe_gbump(__size); + __extracted += __size; + __c = __sb->sgetc(); + } + else + { + __str += __traits_type::to_char_type(__c); + ++__extracted; + __c = __sb->snextc(); + } + } + + if (__traits_type::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + else if (__traits_type::eq_int_type(__c, __idelim)) + { + ++__extracted; + __sb->sbumpc(); + } + else + __err |= ios_base::failbit; + } + __catch(__cxxabiv1::__forced_unwind&) + { + __in._M_setstate(ios_base::badbit); + __throw_exception_again; + } + __catch(...) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 91. Description of operator>> and getline() for string<> + // might cause endless loop + __in._M_setstate(ios_base::badbit); + } + } + if (!__extracted) + __err |= ios_base::failbit; + if (__err) + __in.setstate(__err); + return __in; + } + +#ifdef _GLIBCXX_USE_WCHAR_T + template<> + basic_istream<wchar_t>& + getline(basic_istream<wchar_t>& __in, basic_string<wchar_t>& __str, + wchar_t __delim) + { + typedef basic_istream<wchar_t> __istream_type; + typedef __istream_type::int_type __int_type; + typedef __istream_type::char_type __char_type; + typedef __istream_type::traits_type __traits_type; + typedef __istream_type::__streambuf_type __streambuf_type; + typedef basic_string<wchar_t> __string_type; + typedef __string_type::size_type __size_type; + + __size_type __extracted = 0; + const __size_type __n = __str.max_size(); + ios_base::iostate __err = ios_base::goodbit; + __istream_type::sentry __cerb(__in, true); + if (__cerb) + { + __try + { + __str.erase(); + const __int_type __idelim = __traits_type::to_int_type(__delim); + const __int_type __eof = __traits_type::eof(); + __streambuf_type* __sb = __in.rdbuf(); + __int_type __c = __sb->sgetc(); + + while (__extracted < __n + && !__traits_type::eq_int_type(__c, __eof) + && !__traits_type::eq_int_type(__c, __idelim)) + { + streamsize __size = std::min(streamsize(__sb->egptr() + - __sb->gptr()), + streamsize(__n - __extracted)); + if (__size > 1) + { + const __char_type* __p = __traits_type::find(__sb->gptr(), + __size, + __delim); + if (__p) + __size = __p - __sb->gptr(); + __str.append(__sb->gptr(), __size); + __sb->__safe_gbump(__size); + __extracted += __size; + __c = __sb->sgetc(); + } + else + { + __str += __traits_type::to_char_type(__c); + ++__extracted; + __c = __sb->snextc(); + } + } + + if (__traits_type::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + else if (__traits_type::eq_int_type(__c, __idelim)) + { + ++__extracted; + __sb->sbumpc(); + } + else + __err |= ios_base::failbit; + } + __catch(__cxxabiv1::__forced_unwind&) + { + __in._M_setstate(ios_base::badbit); + __throw_exception_again; + } + __catch(...) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 91. Description of operator>> and getline() for string<> + // might cause endless loop + __in._M_setstate(ios_base::badbit); + } + } + if (!__extracted) + __err |= ios_base::failbit; + if (__err) + __in.setstate(__err); + return __in; + } +#endif + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace diff --git a/libstdc++-v3/src/c++98/istream.cc b/libstdc++-v3/src/c++98/istream.cc index c6dc0d6..f0b024e 100644 --- a/libstdc++-v3/src/c++98/istream.cc +++ b/libstdc++-v3/src/c++98/istream.cc @@ -273,169 +273,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __in; } - template<> - basic_istream<char>& - operator>>(basic_istream<char>& __in, basic_string<char>& __str) - { - typedef basic_istream<char> __istream_type; - typedef __istream_type::int_type __int_type; - typedef __istream_type::traits_type __traits_type; - typedef __istream_type::__streambuf_type __streambuf_type; - typedef __istream_type::__ctype_type __ctype_type; - typedef basic_string<char> __string_type; - typedef __string_type::size_type __size_type; - - __size_type __extracted = 0; - ios_base::iostate __err = ios_base::goodbit; - __istream_type::sentry __cerb(__in, false); - if (__cerb) - { - __try - { - __str.erase(); - const streamsize __w = __in.width(); - const __size_type __n = __w > 0 ? static_cast<__size_type>(__w) - : __str.max_size(); - const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc()); - const __int_type __eof = __traits_type::eof(); - __streambuf_type* __sb = __in.rdbuf(); - __int_type __c = __sb->sgetc(); - - while (__extracted < __n - && !__traits_type::eq_int_type(__c, __eof) - && !__ct.is(ctype_base::space, - __traits_type::to_char_type(__c))) - { - streamsize __size = std::min(streamsize(__sb->egptr() - - __sb->gptr()), - streamsize(__n - __extracted)); - if (__size > 1) - { - __size = (__ct.scan_is(ctype_base::space, - __sb->gptr() + 1, - __sb->gptr() + __size) - - __sb->gptr()); - __str.append(__sb->gptr(), __size); - __sb->__safe_gbump(__size); - __extracted += __size; - __c = __sb->sgetc(); - } - else - { - __str += __traits_type::to_char_type(__c); - ++__extracted; - __c = __sb->snextc(); - } - } - - if (__traits_type::eq_int_type(__c, __eof)) - __err |= ios_base::eofbit; - __in.width(0); - } - __catch(__cxxabiv1::__forced_unwind&) - { - __in._M_setstate(ios_base::badbit); - __throw_exception_again; - } - __catch(...) - { - // _GLIBCXX_RESOLVE_LIB_DEFECTS - // 91. Description of operator>> and getline() for string<> - // might cause endless loop - __in._M_setstate(ios_base::badbit); - } - } - if (!__extracted) - __err |= ios_base::failbit; - if (__err) - __in.setstate(__err); - return __in; - } - - template<> - basic_istream<char>& - getline(basic_istream<char>& __in, basic_string<char>& __str, - char __delim) - { - typedef basic_istream<char> __istream_type; - typedef __istream_type::int_type __int_type; - typedef __istream_type::char_type __char_type; - typedef __istream_type::traits_type __traits_type; - typedef __istream_type::__streambuf_type __streambuf_type; - typedef basic_string<char> __string_type; - typedef __string_type::size_type __size_type; - - __size_type __extracted = 0; - const __size_type __n = __str.max_size(); - ios_base::iostate __err = ios_base::goodbit; - __istream_type::sentry __cerb(__in, true); - if (__cerb) - { - __try - { - __str.erase(); - const __int_type __idelim = __traits_type::to_int_type(__delim); - const __int_type __eof = __traits_type::eof(); - __streambuf_type* __sb = __in.rdbuf(); - __int_type __c = __sb->sgetc(); - - while (__extracted < __n - && !__traits_type::eq_int_type(__c, __eof) - && !__traits_type::eq_int_type(__c, __idelim)) - { - streamsize __size = std::min(streamsize(__sb->egptr() - - __sb->gptr()), - streamsize(__n - __extracted)); - if (__size > 1) - { - const __char_type* __p = __traits_type::find(__sb->gptr(), - __size, - __delim); - if (__p) - __size = __p - __sb->gptr(); - __str.append(__sb->gptr(), __size); - __sb->__safe_gbump(__size); - __extracted += __size; - __c = __sb->sgetc(); - } - else - { - __str += __traits_type::to_char_type(__c); - ++__extracted; - __c = __sb->snextc(); - } - } - - if (__traits_type::eq_int_type(__c, __eof)) - __err |= ios_base::eofbit; - else if (__traits_type::eq_int_type(__c, __idelim)) - { - ++__extracted; - __sb->sbumpc(); - } - else - __err |= ios_base::failbit; - } - __catch(__cxxabiv1::__forced_unwind&) - { - __in._M_setstate(ios_base::badbit); - __throw_exception_again; - } - __catch(...) - { - // _GLIBCXX_RESOLVE_LIB_DEFECTS - // 91. Description of operator>> and getline() for string<> - // might cause endless loop - __in._M_setstate(ios_base::badbit); - } - } - if (!__extracted) - __err |= ios_base::failbit; - if (__err) - __in.setstate(__err); - return __in; - } - #ifdef _GLIBCXX_USE_WCHAR_T template<> basic_istream<wchar_t>& @@ -596,91 +433,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } return *this; } - - template<> - basic_istream<wchar_t>& - getline(basic_istream<wchar_t>& __in, basic_string<wchar_t>& __str, - wchar_t __delim) - { - typedef basic_istream<wchar_t> __istream_type; - typedef __istream_type::int_type __int_type; - typedef __istream_type::char_type __char_type; - typedef __istream_type::traits_type __traits_type; - typedef __istream_type::__streambuf_type __streambuf_type; - typedef basic_string<wchar_t> __string_type; - typedef __string_type::size_type __size_type; - - __size_type __extracted = 0; - const __size_type __n = __str.max_size(); - ios_base::iostate __err = ios_base::goodbit; - __istream_type::sentry __cerb(__in, true); - if (__cerb) - { - __try - { - __str.erase(); - const __int_type __idelim = __traits_type::to_int_type(__delim); - const __int_type __eof = __traits_type::eof(); - __streambuf_type* __sb = __in.rdbuf(); - __int_type __c = __sb->sgetc(); - - while (__extracted < __n - && !__traits_type::eq_int_type(__c, __eof) - && !__traits_type::eq_int_type(__c, __idelim)) - { - streamsize __size = std::min(streamsize(__sb->egptr() - - __sb->gptr()), - streamsize(__n - __extracted)); - if (__size > 1) - { - const __char_type* __p = __traits_type::find(__sb->gptr(), - __size, - __delim); - if (__p) - __size = __p - __sb->gptr(); - __str.append(__sb->gptr(), __size); - __sb->__safe_gbump(__size); - __extracted += __size; - __c = __sb->sgetc(); - } - else - { - __str += __traits_type::to_char_type(__c); - ++__extracted; - __c = __sb->snextc(); - } - } - - if (__traits_type::eq_int_type(__c, __eof)) - __err |= ios_base::eofbit; - else if (__traits_type::eq_int_type(__c, __idelim)) - { - ++__extracted; - __sb->sbumpc(); - } - else - __err |= ios_base::failbit; - } - __catch(__cxxabiv1::__forced_unwind&) - { - __in._M_setstate(ios_base::badbit); - __throw_exception_again; - } - __catch(...) - { - // _GLIBCXX_RESOLVE_LIB_DEFECTS - // 91. Description of operator>> and getline() for string<> - // might cause endless loop - __in._M_setstate(ios_base::badbit); - } - } - if (!__extracted) - __err |= ios_base::failbit; - if (__err) - __in.setstate(__err); - return __in; - } #endif + _GLIBCXX_END_NAMESPACE_VERSION } // namespace diff --git a/libstdc++-v3/src/c++98/locale-inst.cc b/libstdc++-v3/src/c++98/locale-inst.cc index f4d03d9..dd47921 100644 --- a/libstdc++-v3/src/c++98/locale-inst.cc +++ b/libstdc++-v3/src/c++98/locale-inst.cc @@ -26,6 +26,15 @@ // ISO C++ 14882: 22.1 Locales // +#ifndef _GLIBCXX_USE_CXX11_ABI +// Instantiations in this file use the old COW std::string ABI unless included +// by another file which defines _GLIBCXX_USE_CXX11_ABI=1. Some instantiations +// are guarded by a check for !_GLIBCXX_USE_CXX11_ABI so that they are only +// instantiated once, because they are not tagged with abi_tag so should not +// be instantiated twice. +# define _GLIBCXX_USE_CXX11_ABI 0 +#endif + #include <locale> // Instantiation configuration. @@ -39,13 +48,17 @@ namespace std _GLIBCXX_VISIBILITY(default) _GLIBCXX_BEGIN_NAMESPACE_VERSION // moneypunct, money_get, and money_put - template class moneypunct<C, false>; - template class moneypunct<C, true>; +#if ! _GLIBCXX_USE_CXX11_ABI template struct __moneypunct_cache<C, false>; template struct __moneypunct_cache<C, true>; +#endif +_GLIBCXX_BEGIN_NAMESPACE_CXX11 + template class moneypunct<C, false>; + template class moneypunct<C, true>; template class moneypunct_byname<C, false>; template class moneypunct_byname<C, true>; -_GLIBCXX_BEGIN_NAMESPACE_LDBL +_GLIBCXX_END_NAMESPACE_CXX11 +_GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11 template class money_get<C, istreambuf_iterator<C> >; template class money_put<C, ostreambuf_iterator<C> >; template @@ -71,15 +84,21 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL money_put<C, ostreambuf_iterator<C> >:: _M_insert<false>(ostreambuf_iterator<C>, ios_base&, C, const string_type&) const; -_GLIBCXX_END_NAMESPACE_LDBL +_GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 // numpunct, numpunct_byname, num_get, and num_put - template class numpunct<C>; +#if ! _GLIBCXX_USE_CXX11_ABI template struct __numpunct_cache<C>; +#endif +_GLIBCXX_BEGIN_NAMESPACE_CXX11 + template class numpunct<C>; template class numpunct_byname<C>; +_GLIBCXX_END_NAMESPACE_CXX11 _GLIBCXX_BEGIN_NAMESPACE_LDBL +#if ! _GLIBCXX_USE_CXX11_ABI template class num_get<C, istreambuf_iterator<C> >; - template class num_put<C, ostreambuf_iterator<C> >; +#endif + template istreambuf_iterator<C> num_get<C, istreambuf_iterator<C> >:: @@ -124,6 +143,9 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL unsigned long long&) const; #endif +#if ! _GLIBCXX_USE_CXX11_ABI + template class num_put<C, ostreambuf_iterator<C> >; + template ostreambuf_iterator<C> num_put<C, ostreambuf_iterator<C> >:: @@ -161,33 +183,47 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL num_put<C, ostreambuf_iterator<C> >:: _M_insert_float(ostreambuf_iterator<C>, ios_base&, C, char, long double) const; +#endif _GLIBCXX_END_NAMESPACE_LDBL // time_get and time_put +#if ! _GLIBCXX_USE_CXX11_ABI template class __timepunct<C>; template struct __timepunct_cache<C>; template class time_put<C, ostreambuf_iterator<C> >; template class time_put_byname<C, ostreambuf_iterator<C> >; +#endif +_GLIBCXX_BEGIN_NAMESPACE_CXX11 template class time_get<C, istreambuf_iterator<C> >; template class time_get_byname<C, istreambuf_iterator<C> >; +_GLIBCXX_END_NAMESPACE_CXX11 // messages +_GLIBCXX_BEGIN_NAMESPACE_CXX11 template class messages<C>; template class messages_byname<C>; +_GLIBCXX_END_NAMESPACE_CXX11 // ctype +#if ! _GLIBCXX_USE_CXX11_ABI inline template class __ctype_abstract_base<C>; template class ctype_byname<C>; +#endif // codecvt +#if ! _GLIBCXX_USE_CXX11_ABI inline template class __codecvt_abstract_base<C, char, mbstate_t>; template class codecvt_byname<C, char, mbstate_t>; +#endif // collate +_GLIBCXX_BEGIN_NAMESPACE_CXX11 template class collate<C>; template class collate_byname<C>; +_GLIBCXX_END_NAMESPACE_CXX11 // use_facet +#if ! _GLIBCXX_USE_CXX11_ABI template const ctype<C>& use_facet<ctype<C> >(const locale&); @@ -195,6 +231,7 @@ _GLIBCXX_END_NAMESPACE_LDBL template const codecvt<C, char, mbstate_t>& use_facet<codecvt<C, char, mbstate_t> >(const locale&); +#endif template const collate<C>& @@ -204,6 +241,7 @@ _GLIBCXX_END_NAMESPACE_LDBL const numpunct<C>& use_facet<numpunct<C> >(const locale&); +#if ! _GLIBCXX_USE_CXX11_ABI template const num_put<C>& use_facet<num_put<C> >(const locale&); @@ -211,6 +249,7 @@ _GLIBCXX_END_NAMESPACE_LDBL template const num_get<C>& use_facet<num_get<C> >(const locale&); +#endif template const moneypunct<C, true>& @@ -228,6 +267,7 @@ _GLIBCXX_END_NAMESPACE_LDBL const money_get<C>& use_facet<money_get<C> >(const locale&); +#if ! _GLIBCXX_USE_CXX11_ABI template const __timepunct<C>& use_facet<__timepunct<C> >(const locale&); @@ -235,6 +275,7 @@ _GLIBCXX_END_NAMESPACE_LDBL template const time_put<C>& use_facet<time_put<C> >(const locale&); +#endif template const time_get<C>& @@ -245,6 +286,7 @@ _GLIBCXX_END_NAMESPACE_LDBL use_facet<messages<C> >(const locale&); // has_facet +#if ! _GLIBCXX_USE_CXX11_ABI template bool has_facet<ctype<C> >(const locale&); @@ -252,6 +294,7 @@ _GLIBCXX_END_NAMESPACE_LDBL template bool has_facet<codecvt<C, char, mbstate_t> >(const locale&); +#endif template bool @@ -261,6 +304,7 @@ _GLIBCXX_END_NAMESPACE_LDBL bool has_facet<numpunct<C> >(const locale&); +#if ! _GLIBCXX_USE_CXX11_ABI template bool has_facet<num_put<C> >(const locale&); @@ -268,6 +312,7 @@ _GLIBCXX_END_NAMESPACE_LDBL template bool has_facet<num_get<C> >(const locale&); +#endif template bool @@ -281,6 +326,7 @@ _GLIBCXX_END_NAMESPACE_LDBL bool has_facet<money_get<C> >(const locale&); +#if ! _GLIBCXX_USE_CXX11_ABI template bool has_facet<__timepunct<C> >(const locale&); @@ -288,6 +334,7 @@ _GLIBCXX_END_NAMESPACE_LDBL template bool has_facet<time_put<C> >(const locale&); +#endif template bool @@ -322,7 +369,8 @@ _GLIBCXX_END_NAMESPACE_VERSION } // namespace // XXX GLIBCXX_ABI Deprecated -#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined C_is_char +#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined C_is_char \ + && _GLIBCXX_USE_CXX11_ABI == 0 #define _GLIBCXX_LDBL_COMPAT(dbl, ldbl) \ extern "C" void ldbl (void) __attribute__ ((alias (#dbl), weak)) diff --git a/libstdc++-v3/src/c++98/locale.cc b/libstdc++-v3/src/c++98/locale.cc index 7988232..a12bba7 100644 --- a/libstdc++-v3/src/c++98/locale.cc +++ b/libstdc++-v3/src/c++98/locale.cc @@ -20,6 +20,7 @@ // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. +#define _GLIBCXX_USE_CXX11_ABI 1 #include <clocale> #include <cstring> #include <cstdlib> // For getenv @@ -118,6 +119,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return *this; } + _GLIBCXX_DEFAULT_ABI_TAG string locale::name() const { @@ -357,6 +359,38 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION const facet*& __fpr = _M_facets[__index]; if (__fpr) { +#if _GLIBCXX_USE_DUAL_ABI + // If this is a twinned facet replace its twin with a shim. + for (const id* const* p = _S_twinned_facets; *p != 0; p += 2) + { + if (p[0]->_M_id() == __index) + { + // replacing the old ABI facet, also replace new ABI twin + const facet*& __fpr2 = _M_facets[p[1]->_M_id()]; + if (__fpr2) + { + const facet* __fp2 = __fp->_M_sso_shim(p[1]); + __fp2->_M_add_reference(); + __fpr2->_M_remove_reference(); + __fpr2 = __fp2; + } + break; + } + else if (p[1]->_M_id() == __index) + { + // replacing the new ABI facet, also replace old ABI twin + const facet*& __fpr2 = _M_facets[p[0]->_M_id()]; + if (__fpr2) + { + const facet* __fp2 = __fp->_M_cow_shim(p[0]); + __fp2->_M_add_reference(); + __fpr2->_M_remove_reference(); + __fpr2 = __fp2; + } + break; + } + } +#endif // Replacing an existing facet. Order matters. __fpr->_M_remove_reference(); __fpr = __fp; @@ -391,6 +425,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_install_cache(const facet* __cache, size_t __index) { __gnu_cxx::__scoped_lock sentry(get_locale_cache_mutex()); +#if _GLIBCXX_USE_DUAL_ABI + // If this cache is for one of the facets that is instantiated twice, + // for old and new std::string ABI, install it in both slots. + size_t __index2 = -1; + for (const id* const* p = _S_twinned_facets; *p != 0; p += 2) + { + if (p[0]->_M_id() == __index) + { + __index2 = p[1]->_M_id(); + break; + } + else if (p[1]->_M_id() == __index) + { + __index2 = __index; + __index = p[0]->_M_id(); + break; + } + } +#endif if (_M_caches[__index] != 0) { // Some other thread got in first. @@ -400,6 +453,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { __cache->_M_add_reference(); _M_caches[__index] = __cache; +#if _GLIBCXX_USE_DUAL_ABI + if (__index2 != size_t(-1)) + { + __cache->_M_add_reference(); + _M_caches[__index2] = __cache; + } +#endif } } diff --git a/libstdc++-v3/src/c++98/locale_facets.cc b/libstdc++-v3/src/c++98/locale_facets.cc index b3ca5dc..808d937 100644 --- a/libstdc++-v3/src/c++98/locale_facets.cc +++ b/libstdc++-v3/src/c++98/locale_facets.cc @@ -20,6 +20,7 @@ // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. +#define _GLIBCXX_USE_CXX11_ABI 0 #include <locale> namespace std _GLIBCXX_VISIBILITY(default) @@ -97,11 +98,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION *__fptr = '\0'; } - bool - __verify_grouping(const char* __grouping, size_t __grouping_size, - const string& __grouping_tmp) throw() + // This function is not exported but is needed internally, by the versions + // of __verify_grouping below and in src/c++11/cxx11-locale-inst.cc + extern bool + __verify_grouping_impl(const char* __grouping, size_t __grouping_size, + const char* __grouping_tmp, size_t __grouping_tmp_size) { - const size_t __n = __grouping_tmp.size() - 1; + const size_t __n = __grouping_tmp_size - 1; const size_t __min = std::min(__n, size_t(__grouping_size - 1)); size_t __i = __n; bool __test = true; @@ -122,5 +125,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __test; } + bool + __verify_grouping(const char* __grouping, size_t __grouping_size, + const string& __grouping_tmp) throw() + { + return __verify_grouping_impl(__grouping, __grouping_size, + __grouping_tmp.c_str(), + __grouping_tmp.size()); + } + _GLIBCXX_END_NAMESPACE_VERSION } // namespace diff --git a/libstdc++-v3/src/c++98/locale_init.cc b/libstdc++-v3/src/c++98/locale_init.cc index c007648..f9683fc 100644 --- a/libstdc++-v3/src/c++98/locale_init.cc +++ b/libstdc++-v3/src/c++98/locale_init.cc @@ -20,6 +20,7 @@ // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. +#define _GLIBCXX_USE_CXX11_ABI 1 #include <clocale> #include <cstring> #include <cstdlib> // For getenv, free. @@ -28,8 +29,37 @@ #include <locale> #include <ext/concurrence.h> +#if _GLIBCXX_USE_DUAL_ABI +// This file is compiled with the new std::string ABI so std::numpunct<char> +// refers to std::__cxx11::numpunct<char>. These declarations let us refer +// to the other facets instantiated with the old ABI. +# define _GLIBCXX_LOC_ID(mangled) extern std::locale::id mangled +_GLIBCXX_LOC_ID(_ZNSt8numpunctIcE2idE); +_GLIBCXX_LOC_ID(_ZNSt7collateIcE2idE); +_GLIBCXX_LOC_ID(_ZNSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE); +_GLIBCXX_LOC_ID(_ZNSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE); +_GLIBCXX_LOC_ID(_ZNSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE2idE); +_GLIBCXX_LOC_ID(_ZNSt10moneypunctIcLb0EE2idE); +_GLIBCXX_LOC_ID(_ZNSt10moneypunctIcLb1EE2idE); +_GLIBCXX_LOC_ID(_ZNSt8messagesIcE2idE); +# ifdef _GLIBCXX_USE_WCHAR_T +_GLIBCXX_LOC_ID(_ZNSt8numpunctIwE2idE); +_GLIBCXX_LOC_ID(_ZNSt7collateIwE2idE); +_GLIBCXX_LOC_ID(_ZNSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE2idE); +_GLIBCXX_LOC_ID(_ZNSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE2idE); +_GLIBCXX_LOC_ID(_ZNSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE2idE); +_GLIBCXX_LOC_ID(_ZNSt10moneypunctIwLb0EE2idE); +_GLIBCXX_LOC_ID(_ZNSt10moneypunctIwLb1EE2idE); +_GLIBCXX_LOC_ID(_ZNSt8messagesIwE2idE); +# endif +#endif + + namespace { + const int num_facets = _GLIBCXX_NUM_FACETS + + (_GLIBCXX_USE_DUAL_ABI ? _GLIBCXX_NUM_CXX11_FACETS : 0); + __gnu_cxx::__mutex& get_locale_mutex() { @@ -57,11 +87,11 @@ namespace typedef char fake_facet_vec[sizeof(locale::facet*)] __attribute__ ((aligned(__alignof__(locale::facet*)))); - fake_facet_vec facet_vec[_GLIBCXX_NUM_FACETS]; + fake_facet_vec facet_vec[num_facets]; typedef char fake_cache_vec[sizeof(locale::facet*)] __attribute__ ((aligned(__alignof__(locale::facet*)))); - fake_cache_vec cache_vec[_GLIBCXX_NUM_FACETS]; + fake_cache_vec cache_vec[num_facets]; typedef char fake_ctype_c[sizeof(std::ctype<char>)] __attribute__ ((aligned(__alignof__(std::ctype<char>)))); @@ -355,7 +385,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #endif 0 }; - + const locale::id* const* const locale::_Impl::_S_facet_categories[] = { @@ -369,10 +399,52 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION 0 }; +#if _GLIBCXX_USE_DUAL_ABI + // Facets that are instantiated for both the COW and SSO std::string ABIs. + // The COW ABI version must come first, followed by its SSO twin. + const locale::id* const locale::_S_twinned_facets[] = { + &::_ZNSt8numpunctIcE2idE, + &numpunct<char>::id, + &::_ZNSt7collateIcE2idE, + &std::collate<char>::id, + &::_ZNSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE, + &time_get<char>::id, + &::_ZNSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE, + &money_get<char>::id, + &::_ZNSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE2idE, + &money_put<char>::id, + &::_ZNSt10moneypunctIcLb0EE2idE, + &moneypunct<char, false>::id, + &::_ZNSt10moneypunctIcLb1EE2idE, + &moneypunct<char, true >::id, + &::_ZNSt8messagesIcE2idE, + &std::messages<char>::id, +# ifdef _GLIBCXX_USE_WCHAR_T + &::_ZNSt8numpunctIwE2idE, + &numpunct<wchar_t>::id, + &::_ZNSt7collateIwE2idE, + &std::collate<wchar_t>::id, + &::_ZNSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE2idE, + &time_get<wchar_t>::id, + &::_ZNSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE2idE, + &money_get<wchar_t>::id, + &::_ZNSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE2idE, + &money_put<wchar_t>::id, + &::_ZNSt10moneypunctIwLb0EE2idE, + &moneypunct<wchar_t, false>::id, + &::_ZNSt10moneypunctIwLb1EE2idE, + &moneypunct<wchar_t, true >::id, + &::_ZNSt8messagesIwE2idE, + &std::messages<wchar_t>::id, +# endif + 0, 0 + }; +#endif + // Construct "C" _Impl. locale::_Impl:: _Impl(size_t __refs) throw() - : _M_refcount(__refs), _M_facets(0), _M_facets_size(_GLIBCXX_NUM_FACETS), + : _M_refcount(__refs), _M_facets(0), _M_facets_size(num_facets), _M_caches(0), _M_names(0) { _M_facets = new (&facet_vec) const facet*[_M_facets_size](); @@ -448,8 +520,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_init_facet(new (&time_get_w) time_get<wchar_t>(1)); _M_init_facet(new (&time_put_w) time_put<wchar_t>(1)); _M_init_facet(new (&messages_w) std::messages<wchar_t>(1)); -#endif - +#endif + +#if _GLIBCXX_USE_DUAL_ABI + facet* extra[] = { __npc, __mpcf, __mpct +# ifdef _GLIBCXX_USE_WCHAR_T + , __npw, __mpwf, __mpwt +# endif + }; + + _M_init_extra(extra); +#endif + // This locale is safe to pre-cache, after all the facets have // been created and installed. _M_caches[numpunct<char>::id._M_id()] = __npc; diff --git a/libstdc++-v3/src/c++98/localename.cc b/libstdc++-v3/src/c++98/localename.cc index 589f8c6..282471f 100644 --- a/libstdc++-v3/src/c++98/localename.cc +++ b/libstdc++-v3/src/c++98/localename.cc @@ -20,6 +20,7 @@ // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. +#define _GLIBCXX_USE_CXX11_ABI 1 #include <clocale> #include <cstring> #include <cstdlib> @@ -170,10 +171,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } } +const int num_facets = _GLIBCXX_NUM_FACETS + + (_GLIBCXX_USE_DUAL_ABI ? _GLIBCXX_NUM_CXX11_FACETS : 0); + // Construct named _Impl. locale::_Impl:: _Impl(const char* __s, size_t __refs) - : _M_refcount(__refs), _M_facets(0), _M_facets_size(_GLIBCXX_NUM_FACETS), + : _M_refcount(__refs), _M_facets(0), _M_facets_size(num_facets), _M_caches(0), _M_names(0) { // Initialize the underlying locale model, which also checks to @@ -264,6 +268,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_init_facet(new time_put<wchar_t>); _M_init_facet(new std::messages<wchar_t>(__cloc, __s)); #endif + +#if _GLIBCXX_USE_DUAL_ABI + _M_init_extra(&__cloc, &__clocm, __s, __smon); +#endif + locale::facet::_S_destroy_c_locale(__cloc); if (__clocm != __cloc) locale::facet::_S_destroy_c_locale(__clocm); diff --git a/libstdc++-v3/src/c++98/misc-inst.cc b/libstdc++-v3/src/c++98/misc-inst.cc index 540e76d..989218f 100644 --- a/libstdc++-v3/src/c++98/misc-inst.cc +++ b/libstdc++-v3/src/c++98/misc-inst.cc @@ -26,6 +26,8 @@ // ISO C++ 14882: // +#define _GLIBCXX_USE_CXX11_ABI 1 +#define _GLIBCXX_DISAMBIGUATE_REPLACE_INST 1 #include <string> #include <istream> #include <ostream> @@ -62,5 +64,44 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION getline(basic_istream<wchar_t>&, wstring&); #endif +#if _GLIBCXX_USE_CXX11_ABI + // C++98 members that are not instantiated by src/c++11/string-inst.cc + // because they changed in C++11 to take const_iterator parameters. + template string::iterator string::erase(iterator); + template void string::insert(iterator, iterator, iterator); + template string::iterator string::insert(iterator, char); + template string& string::replace(iterator, iterator, size_type, char); + template string& string::replace(iterator, iterator, char*, char*); + template string& string::replace(iterator, iterator, iterator, iterator); + template string& + string::replace(iterator, iterator, const_iterator, const_iterator); + +#ifdef _GLIBCXX_USE_WCHAR_T + template wstring::iterator wstring::erase(iterator); + template void wstring::insert(iterator, iterator, iterator); + template wstring::iterator wstring::insert(iterator, wchar_t); + template wstring& wstring::replace(iterator, iterator, size_type, wchar_t); + template wstring& wstring::replace(iterator, iterator, wchar_t*, wchar_t*); + template wstring& wstring::replace(iterator, iterator, iterator, iterator); + template wstring& + wstring::replace(iterator, iterator, const_iterator, const_iterator); +#endif + + // XXX this doesn't belong in an -inst.cc file + // Defined in src/c++98/locale_facets.cc + _GLIBCXX_PURE bool + __verify_grouping_impl(const char* __grouping, size_t __grouping_size, + const char* __grouping_tmp, size_t __n); + + bool + __verify_grouping(const char* __grouping, size_t __grouping_size, + const string& __grouping_tmp) throw() + { + return __verify_grouping_impl(__grouping, __grouping_size, + __grouping_tmp.c_str(), + __grouping_tmp.size()); + } +#endif + _GLIBCXX_END_NAMESPACE_VERSION } // namespace diff --git a/libstdc++-v3/src/c++98/stdexcept.cc b/libstdc++-v3/src/c++98/stdexcept.cc index c3fdc38..25c75f4 100644 --- a/libstdc++-v3/src/c++98/stdexcept.cc +++ b/libstdc++-v3/src/c++98/stdexcept.cc @@ -26,6 +26,8 @@ // ISO C++ 14882: 19.1 Exception classes // +// All exception classes still use the classic COW std::string. +#define _GLIBCXX_USE_CXX11_ABI 0 #include <string> #include <stdexcept> diff --git a/libstdc++-v3/src/c++98/wlocale-inst.cc b/libstdc++-v3/src/c++98/wlocale-inst.cc index 2bcfa98..85ab48a 100644 --- a/libstdc++-v3/src/c++98/wlocale-inst.cc +++ b/libstdc++-v3/src/c++98/wlocale-inst.cc @@ -26,6 +26,8 @@ // ISO C++ 14882: 22.1 Locales // +// Instantiate locales using COW std::wstring ABI +#define _GLIBCXX_USE_CXX11_ABI 0 #include <bits/c++config.h> #ifdef _GLIBCXX_USE_WCHAR_T diff --git a/libstdc++-v3/testsuite/18_support/50594.cc b/libstdc++-v3/testsuite/18_support/50594.cc index 27538af..5444827 100644 --- a/libstdc++-v3/testsuite/18_support/50594.cc +++ b/libstdc++-v3/testsuite/18_support/50594.cc @@ -59,7 +59,7 @@ void test01() bool test __attribute__((unused)) = true; { - std::string s = "Hello World."; + std::string s = "Hello World, this is not a small string."; } VERIFY( user_new_called ); diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/capacity/1.cc b/libstdc++-v3/testsuite/21_strings/basic_string/capacity/1.cc index eb4565c4..32d4ec0 100644 --- a/libstdc++-v3/testsuite/21_strings/basic_string/capacity/1.cc +++ b/libstdc++-v3/testsuite/21_strings/basic_string/capacity/1.cc @@ -140,7 +140,11 @@ void test01() VERIFY( sz04 >= 100 ); str02.reserve(); sz03 = str02.capacity(); +#if _GLIBCXX_USE_CXX11_ABI + VERIFY( sz03 < 100); +#else VERIFY( sz03 == 0 ); +#endif sz03 = str02.size() + 5; str02.resize(sz03); diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/capacity/char/1.cc b/libstdc++-v3/testsuite/21_strings/basic_string/capacity/char/1.cc index 29bb91e..dc15b25 100644 --- a/libstdc++-v3/testsuite/21_strings/basic_string/capacity/char/1.cc +++ b/libstdc++-v3/testsuite/21_strings/basic_string/capacity/char/1.cc @@ -36,7 +36,11 @@ void test01() VERIFY( sz02 >= 100 ); str01.reserve(); sz01 = str01.capacity(); +#if _GLIBCXX_USE_CXX11_ABI + VERIFY( sz01 < 100); +#else VERIFY( sz01 == 0 ); +#endif sz01 = str01.size() + 5; str01.resize(sz01); diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/capacity/char/18654.cc b/libstdc++-v3/testsuite/21_strings/basic_string/capacity/char/18654.cc index d1e0d69..9a54b6b 100644 --- a/libstdc++-v3/testsuite/21_strings/basic_string/capacity/char/18654.cc +++ b/libstdc++-v3/testsuite/21_strings/basic_string/capacity/char/18654.cc @@ -36,10 +36,13 @@ void test01() typedef string::size_type size_type; - // Our current implementation provides exact shrink-to-size - // and shrink-to-fit (in the future, maybe this will change - // for short strings). +#if _GLIBCXX_USE_CXX11_ABI + // Can't shrink below small string size. + const size_type minsize = 2 << 3; +#else + // Exact shrink-to-size and shrink-to-fit const size_type minsize = 2 << 0; +#endif const size_type maxsize = 2 << MAX_SIZE; for (size_type i = minsize; i <= maxsize; i *= 2) { diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/capacity/char/2.cc b/libstdc++-v3/testsuite/21_strings/basic_string/capacity/char/2.cc index 8e52068..333fe15 100644 --- a/libstdc++-v3/testsuite/21_strings/basic_string/capacity/char/2.cc +++ b/libstdc++-v3/testsuite/21_strings/basic_string/capacity/char/2.cc @@ -32,7 +32,7 @@ void test02() // str01 becomes shared std::string str02 = str01; str01.reserve(1); - VERIFY( str01.capacity() == 12 ); + VERIFY( str01.capacity() >= 12 ); } int main() diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/capacity/wchar_t/1.cc b/libstdc++-v3/testsuite/21_strings/basic_string/capacity/wchar_t/1.cc index 150a8f8..8efc715 100644 --- a/libstdc++-v3/testsuite/21_strings/basic_string/capacity/wchar_t/1.cc +++ b/libstdc++-v3/testsuite/21_strings/basic_string/capacity/wchar_t/1.cc @@ -36,7 +36,11 @@ void test01() VERIFY( sz02 >= 100 ); str01.reserve(); sz01 = str01.capacity(); +#if _GLIBCXX_USE_CXX11_ABI + VERIFY( sz01 < 100); +#else VERIFY( sz01 == 0 ); +#endif sz01 = str01.size() + 5; str01.resize(sz01); diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/capacity/wchar_t/18654.cc b/libstdc++-v3/testsuite/21_strings/basic_string/capacity/wchar_t/18654.cc index e4cd85c..855578d 100644 --- a/libstdc++-v3/testsuite/21_strings/basic_string/capacity/wchar_t/18654.cc +++ b/libstdc++-v3/testsuite/21_strings/basic_string/capacity/wchar_t/18654.cc @@ -36,10 +36,13 @@ void test01() typedef wstring::size_type size_type; - // Our current implementation provides exact shrink-to-size - // and shrink-to-fit (in the future, maybe this will change - // for short strings). +#if _GLIBCXX_USE_CXX11_ABI + // Can't shrink below small string size. + const size_type minsize = 2 << 1; +#else + // Exact shrink-to-size and shrink-to-fit const size_type minsize = 2 << 0; +#endif const size_type maxsize = 2 << MAX_SIZE; for (size_type i = minsize; i <= maxsize; i *= 2) { diff --git a/libstdc++-v3/testsuite/21_strings/headers/string/synopsis.cc b/libstdc++-v3/testsuite/21_strings/headers/string/synopsis.cc index 95b8e9b..ff14038 100644 --- a/libstdc++-v3/testsuite/21_strings/headers/string/synopsis.cc +++ b/libstdc++-v3/testsuite/21_strings/headers/string/synopsis.cc @@ -26,9 +26,11 @@ namespace std { template <> struct char_traits<char>; template <> struct char_traits<wchar_t>; +_GLIBCXX_BEGIN_NAMESPACE_CXX11 // lib.basic.string, basic_string: template<class charT, class traits, class Allocator > class basic_string; +_GLIBCXX_END_NAMESPACE_CXX11 template<class charT, class traits, class Allocator> basic_string<charT,traits,Allocator> diff --git a/libstdc++-v3/testsuite/23_containers/headers/list/synopsis.cc b/libstdc++-v3/testsuite/23_containers/headers/list/synopsis.cc index dc9330b..8b76de7 100644 --- a/libstdc++-v3/testsuite/23_containers/headers/list/synopsis.cc +++ b/libstdc++-v3/testsuite/23_containers/headers/list/synopsis.cc @@ -21,7 +21,9 @@ #include <list> namespace std { +_GLIBCXX_BEGIN_NAMESPACE_CXX11 template <class T, class Allocator> class list; +_GLIBCXX_END_NAMESPACE_CXX11 template <class T, class Allocator> bool operator==(const list<T,Allocator>& x, const list<T,Allocator>&); diff --git a/libstdc++-v3/testsuite/27_io/basic_ios/copyfmt/char/1.cc b/libstdc++-v3/testsuite/27_io/basic_ios/copyfmt/char/1.cc index 306d22f..577dacc 100644 --- a/libstdc++-v3/testsuite/27_io/basic_ios/copyfmt/char/1.cc +++ b/libstdc++-v3/testsuite/27_io/basic_ios/copyfmt/char/1.cc @@ -17,6 +17,8 @@ // with this library; see the file COPYING3. If not see // <http://www.gnu.org/licenses/>. +// The library still throws the original definition of std::ios::failure +// { dg-options "-D_GLIBCXX_USE_CXX11_ABI=0" } // 27.4.4.2 basic_ios member functions diff --git a/libstdc++-v3/testsuite/27_io/basic_ios/exceptions/char/1.cc b/libstdc++-v3/testsuite/27_io/basic_ios/exceptions/char/1.cc index 4359ca8..0fe2739 100644 --- a/libstdc++-v3/testsuite/27_io/basic_ios/exceptions/char/1.cc +++ b/libstdc++-v3/testsuite/27_io/basic_ios/exceptions/char/1.cc @@ -17,6 +17,8 @@ // with this library; see the file COPYING3. If not see // <http://www.gnu.org/licenses/>. +// The library still throws the original definition of std::ios::failure +// { dg-options "-D_GLIBCXX_USE_CXX11_ABI=0" } // 27.4.4.2 basic_ios member functions diff --git a/libstdc++-v3/testsuite/27_io/basic_istream/extractors_arithmetic/char/exceptions_failbit.cc b/libstdc++-v3/testsuite/27_io/basic_istream/extractors_arithmetic/char/exceptions_failbit.cc index 23064db..e390b9e 100644 --- a/libstdc++-v3/testsuite/27_io/basic_istream/extractors_arithmetic/char/exceptions_failbit.cc +++ b/libstdc++-v3/testsuite/27_io/basic_istream/extractors_arithmetic/char/exceptions_failbit.cc @@ -15,6 +15,8 @@ // with this library; see the file COPYING3. If not see // <http://www.gnu.org/licenses/>. +// The library still throws the original definition of std::ios::failure +// { dg-options "-D_GLIBCXX_USE_CXX11_ABI=0" } #include <sstream> #include <testsuite_hooks.h> diff --git a/libstdc++-v3/testsuite/27_io/basic_istream/extractors_arithmetic/wchar_t/exceptions_failbit.cc b/libstdc++-v3/testsuite/27_io/basic_istream/extractors_arithmetic/wchar_t/exceptions_failbit.cc index 133c5d7..6588a8a 100644 --- a/libstdc++-v3/testsuite/27_io/basic_istream/extractors_arithmetic/wchar_t/exceptions_failbit.cc +++ b/libstdc++-v3/testsuite/27_io/basic_istream/extractors_arithmetic/wchar_t/exceptions_failbit.cc @@ -15,6 +15,8 @@ // with this library; see the file COPYING3. If not see // <http://www.gnu.org/licenses/>. +// The library still throws the original definition of std::ios::failure +// { dg-options "-D_GLIBCXX_USE_CXX11_ABI=0" } #include <sstream> #include <testsuite_hooks.h> diff --git a/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/char/exceptions_null.cc b/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/char/exceptions_null.cc index d1ce3ad..d73b302 100644 --- a/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/char/exceptions_null.cc +++ b/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/char/exceptions_null.cc @@ -15,6 +15,8 @@ // with this library; see the file COPYING3. If not see // <http://www.gnu.org/licenses/>. +// The library still throws the original definition of std::ios::failure +// { dg-options "-D_GLIBCXX_USE_CXX11_ABI=0" } #include <istream> #include <ostream> diff --git a/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/wchar_t/exceptions_null.cc b/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/wchar_t/exceptions_null.cc index 1e64cb2..f609d04 100644 --- a/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/wchar_t/exceptions_null.cc +++ b/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/wchar_t/exceptions_null.cc @@ -15,6 +15,8 @@ // with this library; see the file COPYING3. If not see // <http://www.gnu.org/licenses/>. +// The library still throws the original definition of std::ios::failure +// { dg-options "-D_GLIBCXX_USE_CXX11_ABI=0" } #include <istream> #include <ostream> diff --git a/libstdc++-v3/testsuite/27_io/basic_istream/sentry/char/12297.cc b/libstdc++-v3/testsuite/27_io/basic_istream/sentry/char/12297.cc index f9dbb05..8048652 100644 --- a/libstdc++-v3/testsuite/27_io/basic_istream/sentry/char/12297.cc +++ b/libstdc++-v3/testsuite/27_io/basic_istream/sentry/char/12297.cc @@ -18,6 +18,9 @@ // 27.6.1.1.2 class basic_istream::sentry +// The library still throws the original definition of std::ios::failure +// { dg-options "-D_GLIBCXX_USE_CXX11_ABI=0" } + #include <sstream> #include <testsuite_hooks.h> diff --git a/libstdc++-v3/testsuite/27_io/basic_istream/sentry/wchar_t/12297.cc b/libstdc++-v3/testsuite/27_io/basic_istream/sentry/wchar_t/12297.cc index 8d88418..1e3fc01 100644 --- a/libstdc++-v3/testsuite/27_io/basic_istream/sentry/wchar_t/12297.cc +++ b/libstdc++-v3/testsuite/27_io/basic_istream/sentry/wchar_t/12297.cc @@ -15,6 +15,8 @@ // with this library; see the file COPYING3. If not see // <http://www.gnu.org/licenses/>. +// The library still throws the original definition of std::ios::failure +// { dg-options "-D_GLIBCXX_USE_CXX11_ABI=0" } // 27.6.1.1.2 class basic_istream::sentry diff --git a/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/char/exceptions_null.cc b/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/char/exceptions_null.cc index 564f43a..781b5f0 100644 --- a/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/char/exceptions_null.cc +++ b/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/char/exceptions_null.cc @@ -15,6 +15,8 @@ // with this library; see the file COPYING3. If not see // <http://www.gnu.org/licenses/>. +// The library still throws the original definition of std::ios::failure +// { dg-options "-D_GLIBCXX_USE_CXX11_ABI=0" } #include <istream> #include <ostream> diff --git a/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/wchar_t/exceptions_null.cc b/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/wchar_t/exceptions_null.cc index c769ecb..8539340 100644 --- a/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/wchar_t/exceptions_null.cc +++ b/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/wchar_t/exceptions_null.cc @@ -15,6 +15,8 @@ // with this library; see the file COPYING3. If not see // <http://www.gnu.org/licenses/>. +// The library still throws the original definition of std::ios::failure +// { dg-options "-D_GLIBCXX_USE_CXX11_ABI=0" } #include <istream> #include <ostream> diff --git a/libstdc++-v3/testsuite/27_io/headers/sstream/synopsis.cc b/libstdc++-v3/testsuite/27_io/headers/sstream/synopsis.cc index 14534fd..f1e1af2 100644 --- a/libstdc++-v3/testsuite/27_io/headers/sstream/synopsis.cc +++ b/libstdc++-v3/testsuite/27_io/headers/sstream/synopsis.cc @@ -20,6 +20,7 @@ #include <sstream> namespace std { +_GLIBCXX_BEGIN_NAMESPACE_CXX11 template <class charT, class traits, class Allocator> class basic_stringbuf; typedef basic_stringbuf<char> stringbuf; @@ -39,4 +40,5 @@ namespace std { class basic_stringstream; typedef basic_stringstream<char> stringstream; typedef basic_stringstream<wchar_t> wstringstream; +_GLIBCXX_END_NAMESPACE_CXX11 } diff --git a/libstdc++-v3/testsuite/27_io/ios_base/failure/cxx11.cc b/libstdc++-v3/testsuite/27_io/ios_base/failure/cxx11.cc index a3276e1..29d1b63 100644 --- a/libstdc++-v3/testsuite/27_io/ios_base/failure/cxx11.cc +++ b/libstdc++-v3/testsuite/27_io/ios_base/failure/cxx11.cc @@ -20,6 +20,7 @@ #include <ios> #include <testsuite_hooks.h> +#if _GLIBCXX_USE_CXX11_ABI using test_type = std::ios_base::failure; static_assert( std::is_base_of<std::system_error, test_type>::value, "base" ); @@ -50,3 +51,6 @@ main() test01(); test02(); } +#else +int main() { } +#endif diff --git a/libstdc++-v3/testsuite/27_io/ios_base/storage/2.cc b/libstdc++-v3/testsuite/27_io/ios_base/storage/2.cc index 2304b1a..0a2ed8c 100644 --- a/libstdc++-v3/testsuite/27_io/ios_base/storage/2.cc +++ b/libstdc++-v3/testsuite/27_io/ios_base/storage/2.cc @@ -28,6 +28,9 @@ // Radar 6467884: 10.X systems are not robust when paging space is exceeded // { dg-skip-if "" { *-*-darwin* && lp64 } { "*" } { "" } } +// The library still throws the original definition of std::ios::failure +// { dg-options "-D_GLIBCXX_USE_CXX11_ABI=0" } + #include <sstream> #include <iostream> #include <limits> diff --git a/libstdc++-v3/testsuite/Makefile.in b/libstdc++-v3/testsuite/Makefile.in index 7100a64..ac64520 100644 --- a/libstdc++-v3/testsuite/Makefile.in +++ b/libstdc++-v3/testsuite/Makefile.in @@ -216,6 +216,7 @@ glibcxx_POFILES = @glibcxx_POFILES@ glibcxx_builddir = @glibcxx_builddir@ glibcxx_compiler_pic_flag = @glibcxx_compiler_pic_flag@ glibcxx_compiler_shared_flag = @glibcxx_compiler_shared_flag@ +glibcxx_cxx98_abi = @glibcxx_cxx98_abi@ glibcxx_localedir = @glibcxx_localedir@ glibcxx_lt_pic_flag = @glibcxx_lt_pic_flag@ glibcxx_prefixdir = @glibcxx_prefixdir@ diff --git a/libstdc++-v3/testsuite/ext/profile/mutex_extensions_neg.cc b/libstdc++-v3/testsuite/ext/profile/mutex_extensions_neg.cc index 5597c57..76e045d 100644 --- a/libstdc++-v3/testsuite/ext/profile/mutex_extensions_neg.cc +++ b/libstdc++-v3/testsuite/ext/profile/mutex_extensions_neg.cc @@ -25,4 +25,4 @@ #include <vector> -// { dg-error "multiple inlined namespaces" "" { target *-*-* } 290 } +// { dg-error "multiple inlined namespaces" "" { target *-*-* } 306 } diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/libfundts.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/libfundts.cc index e2f99a1..2c42b7d 100644 --- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/libfundts.cc +++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/libfundts.cc @@ -18,6 +18,9 @@ // with this library; see the file COPYING3. If not see // <http://www.gnu.org/licenses/>. +// Type printers only recognize the old std::string for now. +#define _GLIBCXX_USE_CXX11_ABI 0 + #include <experimental/any> #include <experimental/optional> #include <experimental/string_view> diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple.cc index 030207a..167a711 100644 --- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple.cc +++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple.cc @@ -20,6 +20,9 @@ // with this library; see the file COPYING3. If not see // <http://www.gnu.org/licenses/>. +// Type printers only recognize the old std::string for now. +#define _GLIBCXX_USE_CXX11_ABI 0 + #include <string> #include <deque> #include <bitset> diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple11.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple11.cc index e94bea6..fc2e03c 100644 --- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple11.cc +++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple11.cc @@ -20,6 +20,9 @@ // with this library; see the file COPYING3. If not see // <http://www.gnu.org/licenses/>. +// Type printers only recognize the old std::string for now. +#define _GLIBCXX_USE_CXX11_ABI 0 + #include <string> #include <deque> #include <bitset> diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/whatis.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/whatis.cc index b398972..76ba1b8 100644 --- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/whatis.cc +++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/whatis.cc @@ -18,6 +18,9 @@ // with this library; see the file COPYING3. If not see // <http://www.gnu.org/licenses/>. +// Type printers only recognize the old std::string for now. +#define _GLIBCXX_USE_CXX11_ABI 0 + #include <string> #include <iostream> #include <regex> diff --git a/libstdc++-v3/testsuite/util/exception/safety.h b/libstdc++-v3/testsuite/util/exception/safety.h index bb3f0a2..22dff63 100644 --- a/libstdc++-v3/testsuite/util/exception/safety.h +++ b/libstdc++-v3/testsuite/util/exception/safety.h @@ -255,6 +255,7 @@ namespace __gnu_test : _F_erase_point(&_Tp::erase), _F_erase_range(&_Tp::erase) { } }; +#if _GLIBCXX_USE_CXX11_ABI == 0 || __cplusplus < 201103L // Specialization, old C++03 signature. template<typename _Tp1, typename _Tp2, typename _Tp3> struct erase_base<std::basic_string<_Tp1, _Tp2, _Tp3>> @@ -269,6 +270,7 @@ namespace __gnu_test : _F_erase_point(&container_type::erase), _F_erase_range(&container_type::erase) { } }; +#endif // Specialization, as forward_list has erase_after. template<typename _Tp1, typename _Tp2> @@ -676,9 +678,15 @@ namespace __gnu_test { typedef std::basic_string<_Tp1, _Tp2, _Tp3> container_type; typedef typename container_type::iterator iterator; + typedef typename container_type::const_iterator const_iterator; typedef typename container_type::value_type value_type; +#if _GLIBCXX_USE_CXX11_ABI == 0 || __cplusplus < 201103L iterator (container_type::* _F_insert_point)(iterator, value_type); +#else + iterator (container_type::* _F_insert_point)(const_iterator, + value_type); +#endif insert_base() : _F_insert_point(&container_type::insert) { } }; diff --git a/libstdc++-v3/testsuite/util/testsuite_abi.cc b/libstdc++-v3/testsuite/util/testsuite_abi.cc index 15b05dc..958ec0f 100644 --- a/libstdc++-v3/testsuite/util/testsuite_abi.cc +++ b/libstdc++-v3/testsuite/util/testsuite_abi.cc @@ -201,6 +201,7 @@ check_version(symbol& test, bool added) known_versions.push_back("GLIBCXX_3.4.19"); known_versions.push_back("GLIBCXX_3.4.20"); known_versions.push_back("GLIBCXX_3.4.21"); + known_versions.push_back("GLIBCXX_LDBL_3.4.21"); known_versions.push_back("CXXABI_1.3"); known_versions.push_back("CXXABI_LDBL_1.3"); known_versions.push_back("CXXABI_1.3.1"); @@ -239,7 +240,8 @@ check_version(symbol& test, bool added) // Check that long double compatibility symbols demangled as // __float128 and regular __float128 symbols are put into some _LDBL_ // or _FLOAT128 version name. - if (added && test.demangled_name.find("__float128") != std::string::npos) + if (added && test.demangled_name.find("__float128") != std::string::npos + && test.demangled_name.find("std::__cxx11::") != 0) { if (test.version_name.find("_LDBL_") == std::string::npos && test.version_name.find("_FLOAT128") == std::string::npos) |