re PR rtl-optimization/7291 (off-by-one in generated inline bzero code for i386 (64bit))
gcc/ChangeLog 2002-07-24 Frank van der Linden <fvdl@wasabisystems.com> PR optimization/7291 * config/i386/i386.c (ix86_expand_clrstr): Fix bzero alignment problem on x86_64. 2002-05-16 Jason Merrill <jason@redhat.com> * config/mips/mips.c (mips_output_external): Don't do sdata optimization for a variable with DECL_COMDAT set. 2002-01-03 Jakub Jelinek <jakub@redhat.com> * c-decl.c (build_compound_literal): Set decl TREE_READONLY from TYPE. * c-decl.c (build_compound_literal): Defer compound literal decls until until file end to emit them only if they are actually used. gcc/cp/ChangeLog 2002-07-17 Scott Snyder <snyder@fnal.gov> PR c++/7320 * rtti.c (get_tinfo_decl): Set DECL_COMDAT. 2002-07-05 Nathan Sidwell <nathan@codesourcery.com> Repair damage on weak-impared targets caused by my previous patch. * cp-tree.h (import_export_tinfo): Add parameter. * decl2.c (import_export_tinfo): Add parameter, post adjust DECL_COMDAT. * rtti.c (emit_tinfo_decl): DECL_COMDAT is (nearly) always setup by import_export_tinfo. 2002-06-30 Nathan Sidwell <nathan@codesourcery.com> * cp-tree.h (CPTI_TINFO_DECL_TYPE): Replace with ... (CPTI_TYPE_INFO_PTR_TYPE): ... this. (tinfo_decl_type): Replace with ... (type_info_ptr_type): ... this. (import_export_tinfo): Declare. (tinfo_decl_p): Rename to ... (unemitted_tinfo_decl_p): ... this. * decl2.c (import_export_decl): Break out tinfo handling into ... (import_export_tinfo): ... here. New function. (finish_file): Adjust. * rtti.c (TINFO_REAL_NAME): New macro. (init_rtti_processing): Create the tinfo types. (get_tinfo_decl_dynamic): Use type_info_ptr_type, get_tinfo_ptr. (get_tinfo_decl): Adjust. (get_tinfo_ptr): New function. (get_type_id): Use it. (tinfo_base_init): Create vtable decl here, if it doesn't exist. (ptr_initializer): Use get_tinfo_ptr. (ptm_initializer): Likewise. (synthesize_tinfo_var): Break into ... (get_pseudo_ti_init): ... this. Just create the initializer. (get_pseudo_ti_desc): .. and this. (create_real_tinfo_var): Remove. (create_pseudo_type_info): Don't create the vtable decl here. (get_vmi_pseudo_type_info): Remove. (create_tinfo_types): Adjust. (tinfo_decl_p): Rename to ... (unemitted_tinfo_decl_p): ... here. Adjust. (emit_tinfo_decl): Adjust. Create the initializer. 2002-06-14 Jason Merrill <jason@redhat.com> C++ ABI changes. * class.c (build_base_field): Set DECL_PACKED. (layout_class_type): Don't use tail padding of PODs. * mangle.c (write_unqualified_name): Fix template conversion op mangling. 2002-05-18 Jason Merrill <jason@redhat.com> PR c++/6611 * decl2.c (import_export_decl): If we clear DECL_NOT_REALLY_EXTERN, make sure DECL_EXTERNAL is set. 2002-05-14 Jason Merrill <jason@redhat.com> * rtti.c (get_tinfo_decl): Don't call comdat_linkage. Do set DECL_COMDAT. (synthesize_tinfo_var): Take the public decl. (create_real_tinfo_var): Likewise. Check DECL_COMDAT. (emit_tinfo_decl): Adjust. Call import_export_decl. * decl2.c (import_export_decl): Simplify tinfo decl handling. gcc/testsuite/ChangeLog 2002-07-24 Roger Sayle <roger@eyesopen.com> * gcc.c-torture/execute/memset-3.c: New testcase. 2002-06-14 Jason Merrill <jason@redhat.com> * g++.dg/abi/layout1.C: New test. * g++.dg/abi/layout2.C: New test. * g++.dg/abi/mangle8.C: New test. 2002-05-14 Jason Merrill <jason@redhat.com> * g++.dg/abi/rtti1.C: New test. 2002-01-03 Jakub Jelinek <jakub@redhat.com> * gcc.dg/gnu89-init-2.c: New test. libstdc++-v3/ChangeLog 2002-07-26 Phil Edwards <pme@gcc.gnu.org> * libsupc++/new (placement delete): Remove unused paramater names. 2002-07-25 Benjamin Kosnik <bkoz@redhat.com> PR libstdc++/7216 * include/std/std_istream.h (basic_iostream): Add typedefs for char_type, int_type, pos_type, off_type, and traits_type. * testsuite/27_io/iostream.cc (test01): Add typedef tests. * testsuite/27_io/istream.cc: Same. * testsuite/27_io/ostream.cc: Same. * testsuite/27_io/filebuf.cc: Same. * testsuite/27_io/stringbuf.cc: Replace content, move to... * testsuite/27_io/stringbuf_members.cc: ...here. * testsuite/27_io/streambuf.cc: Replace content, move to... * testsuite/27_io/streambuf_members.cc: ...here. * testsuite/27_io/stringstream.cc: Replace content, move to... * testsuite/27_io/stringstream_members.cc: ...here. * testsuite/27_io/ios.cc: New file. * testsuite/27_io/fstream.cc: New file. * testsuite/27_io/ifstream.cc: New file. * testsuite/27_io/ofstream.cc: New file. * testsuite/27_io/istringstream.cc: New file. * testsuite/27_io/ostringstream.cc: New file. 2002-07-25 Benjamin Kosnik <bkoz@redhat.com> PR libstdc++/7220 * include/bits/istream.tcc (istream::ignore): Don't extract on zero. * testsuite/27_io/istream_unformatted.cc (test10): Add. 2002-07-24 Benjamin Kosnik <bkoz@redhat.com> PR libstdc++/7222 * src/locale.cc (locale::locale(const char*)): Use setlocale NULL. * testsuite/22_locale/ctor_copy_dtor.cc (test02): New. 2002-07-24 Benjamin Kosnik <bkoz@redhat.com> PR libstdc++/7286 * libsupc++/new: Add placement delete. * testsuite/18_support/new_delete_placement.cc: New. 2002-07-07 Paolo Carlini <pcarlini@unitus.it> PR libstdc++/7186 * include/bits/stl_deque.h (_Deque_iterator::operator-): Make non-member, as already happens for the comparison operators in accord with DR179 (Ready). * testsuite/23_containers/deque_operators.cc: Add test02. 2002-07-04 Benjamin Kosnik <bkoz@redhat.com> Jack Reeves <jackw_reeves@hotmail.com> * include/std/std_streambuf.h (basic_streambuf::_M_buf): Change to size_t, from int_type. (basic_streambuf::_M_buf_size_opt): Same. (basic_streambuf::_S_pback_sizex): Same. * include/bits/streambuf.tcc: Same. * include/std/std_streambuf.h (basic_streambuf::snextc): Use eq_int_type. (basic_streambuf::uflow): Same. * include/bits/sstream.tcc (basic_stringbuf::overflow): Use to_char_type. * include/bits/basic_ios.tcc (basic_ios::init): Use _CharT(). * include/bits/streambuf.tcc (basic_streambuf::xsgetn): Use eq_int_type. (basic_streambuf::xsputn): Same. (__copy_streambufs): Same. 2002-07-02 Paolo Carlini <pcarlini@unitus.it> PR libstdc++/6642 * include/bits/stl_iterator.h (__normal_iterator::operator-(const __normal_iterator&)): Make non-member, as already happens for the comparison operators in accord with DR179 (Ready). * testsuite/24_iterators/iterator.cc: Add test from the PR. 2002-07-02 Benjamin Kosnik <bkoz@redhat.com> PR libstdc++/6410 * include/bits/locale_facets.h (moneypunct::moneypunct): Add const char* name parameter. * config/locale/gnu/monetary_members.cc: Use it. * config/locale/generic/monetary_members.cc: Same. * src/localename.cc (_Impl::_Impl(const char*, size_t)): Use it. 2002-07-01 Benjamin Kosnik <bkoz@redhat.com> * configure.in (libtool_VERSION): Bump to 5:0:0. * configure: Regenerate. 2002-05-19 Paolo Carlini <pcarlini@unitus.it> * testsuite/23_containers/deque_operators.cc (test01): Fix minor typo in last commit. 2002-05-18 Paolo Carlini <pcarlini@unitus.it> PR libstdc++/6503 * include/bits/stl_deque.h (_Deque_iterator::operator==, operator!=, operator<, operator>, operator>=, operator<=): Make non-member functions, to allow comparing const and non-const iterators in any order. * testsuite/23_containers/deque_operators.cc: New testfile. From-SVN: r55786
This commit is contained in:
parent
09f8b2cd1b
commit
a7580e63a7
|
@ -1,3 +1,21 @@
|
|||
2002-07-24 Frank van der Linden <fvdl@wasabisystems.com>
|
||||
|
||||
PR optimization/7291
|
||||
* config/i386/i386.c (ix86_expand_clrstr): Fix bzero alignment
|
||||
problem on x86_64.
|
||||
|
||||
2002-05-16 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* config/mips/mips.c (mips_output_external): Don't do sdata
|
||||
optimization for a variable with DECL_COMDAT set.
|
||||
|
||||
2002-01-03 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* c-decl.c (build_compound_literal): Set decl TREE_READONLY from TYPE.
|
||||
|
||||
* c-decl.c (build_compound_literal): Defer compound literal decls
|
||||
until until file end to emit them only if they are actually used.
|
||||
|
||||
2002-07-25 Release Manager
|
||||
|
||||
* GCC 3.1.1 Released.
|
||||
|
|
17
gcc/c-decl.c
17
gcc/c-decl.c
|
@ -3911,6 +3911,7 @@ build_compound_literal (type, init)
|
|||
DECL_CONTEXT (decl) = current_function_decl;
|
||||
TREE_USED (decl) = 1;
|
||||
TREE_TYPE (decl) = type;
|
||||
TREE_READONLY (decl) = TREE_READONLY (type);
|
||||
store_init_value (decl, init);
|
||||
|
||||
if (TREE_CODE (type) == ARRAY_TYPE && !COMPLETE_TYPE_P (type))
|
||||
|
@ -3933,12 +3934,18 @@ build_compound_literal (type, init)
|
|||
if (TREE_STATIC (decl))
|
||||
{
|
||||
/* This decl needs a name for the assembler output. We also need
|
||||
a unique suffix to be added to the name, for which DECL_CONTEXT
|
||||
must be set. */
|
||||
DECL_NAME (decl) = get_identifier ("__compound_literal");
|
||||
DECL_CONTEXT (decl) = complit;
|
||||
a unique suffix to be added to the name. */
|
||||
char *name;
|
||||
extern int var_labelno;
|
||||
|
||||
ASM_FORMAT_PRIVATE_NAME (name, "__compound_literal", var_labelno);
|
||||
var_labelno++;
|
||||
DECL_NAME (decl) = get_identifier (name);
|
||||
DECL_DEFER_OUTPUT (decl) = 1;
|
||||
DECL_COMDAT (decl) = 1;
|
||||
DECL_ARTIFICIAL (decl) = 1;
|
||||
pushdecl (decl);
|
||||
rest_of_decl_compilation (decl, NULL, 1, 0);
|
||||
DECL_CONTEXT (decl) = NULL_TREE;
|
||||
}
|
||||
|
||||
return complit;
|
||||
|
|
|
@ -9505,7 +9505,7 @@ ix86_expand_clrstr (src, count_exp, align_exp)
|
|||
gen_rtx_SUBREG (SImode, zeroreg, 0)));
|
||||
if (TARGET_64BIT && (align <= 4 || count == 0))
|
||||
{
|
||||
rtx label = ix86_expand_aligntest (countreg, 2);
|
||||
rtx label = ix86_expand_aligntest (countreg, 4);
|
||||
emit_insn (gen_strsetsi (destreg,
|
||||
gen_rtx_SUBREG (SImode, zeroreg, 0)));
|
||||
emit_label (label);
|
||||
|
|
|
@ -5854,6 +5854,7 @@ mips_output_external (file, decl, name)
|
|||
|
||||
if (TARGET_GP_OPT
|
||||
&& TREE_CODE (decl) != FUNCTION_DECL
|
||||
&& !DECL_COMDAT (decl)
|
||||
&& (len = int_size_in_bytes (TREE_TYPE (decl))) > 0
|
||||
&& ((section_name = DECL_SECTION_NAME (decl)) == NULL
|
||||
|| strcmp (TREE_STRING_POINTER (section_name), ".sbss") == 0
|
||||
|
|
|
@ -1,3 +1,72 @@
|
|||
2002-07-17 Scott Snyder <snyder@fnal.gov>
|
||||
|
||||
PR c++/7320
|
||||
* rtti.c (get_tinfo_decl): Set DECL_COMDAT.
|
||||
|
||||
2002-07-05 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
Repair damage on weak-impared targets caused by my previous patch.
|
||||
* cp-tree.h (import_export_tinfo): Add parameter.
|
||||
* decl2.c (import_export_tinfo): Add parameter, post adjust
|
||||
DECL_COMDAT.
|
||||
* rtti.c (emit_tinfo_decl): DECL_COMDAT is (nearly) always setup by
|
||||
import_export_tinfo.
|
||||
|
||||
2002-06-30 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
* cp-tree.h (CPTI_TINFO_DECL_TYPE): Replace with ...
|
||||
(CPTI_TYPE_INFO_PTR_TYPE): ... this.
|
||||
(tinfo_decl_type): Replace with ...
|
||||
(type_info_ptr_type): ... this.
|
||||
(import_export_tinfo): Declare.
|
||||
(tinfo_decl_p): Rename to ...
|
||||
(unemitted_tinfo_decl_p): ... this.
|
||||
* decl2.c (import_export_decl): Break out tinfo handling into ...
|
||||
(import_export_tinfo): ... here. New function.
|
||||
(finish_file): Adjust.
|
||||
* rtti.c (TINFO_REAL_NAME): New macro.
|
||||
(init_rtti_processing): Create the tinfo types.
|
||||
(get_tinfo_decl_dynamic): Use type_info_ptr_type, get_tinfo_ptr.
|
||||
(get_tinfo_decl): Adjust.
|
||||
(get_tinfo_ptr): New function.
|
||||
(get_type_id): Use it.
|
||||
(tinfo_base_init): Create vtable decl here, if it doesn't exist.
|
||||
(ptr_initializer): Use get_tinfo_ptr.
|
||||
(ptm_initializer): Likewise.
|
||||
(synthesize_tinfo_var): Break into ...
|
||||
(get_pseudo_ti_init): ... this. Just create the initializer.
|
||||
(get_pseudo_ti_desc): .. and this.
|
||||
(create_real_tinfo_var): Remove.
|
||||
(create_pseudo_type_info): Don't create the vtable decl here.
|
||||
(get_vmi_pseudo_type_info): Remove.
|
||||
(create_tinfo_types): Adjust.
|
||||
(tinfo_decl_p): Rename to ...
|
||||
(unemitted_tinfo_decl_p): ... here. Adjust.
|
||||
(emit_tinfo_decl): Adjust. Create the initializer.
|
||||
|
||||
2002-06-14 Jason Merrill <jason@redhat.com>
|
||||
|
||||
C++ ABI changes.
|
||||
* class.c (build_base_field): Set DECL_PACKED.
|
||||
(layout_class_type): Don't use tail padding of PODs.
|
||||
* mangle.c (write_unqualified_name): Fix template conversion op
|
||||
mangling.
|
||||
|
||||
2002-05-18 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/6611
|
||||
* decl2.c (import_export_decl): If we clear
|
||||
DECL_NOT_REALLY_EXTERN, make sure DECL_EXTERNAL is set.
|
||||
|
||||
2002-05-14 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* rtti.c (get_tinfo_decl): Don't call comdat_linkage.
|
||||
Do set DECL_COMDAT.
|
||||
(synthesize_tinfo_var): Take the public decl.
|
||||
(create_real_tinfo_var): Likewise. Check DECL_COMDAT.
|
||||
(emit_tinfo_decl): Adjust. Call import_export_decl.
|
||||
* decl2.c (import_export_decl): Simplify tinfo decl handling.
|
||||
|
||||
2002-07-25 Release Manager
|
||||
|
||||
* GCC 3.1.1 Released.
|
||||
|
|
|
@ -3830,6 +3830,8 @@ build_base_field (rli, binfo, empty_p, offsets, t)
|
|||
DECL_SIZE_UNIT (decl) = CLASSTYPE_SIZE_UNIT (basetype);
|
||||
DECL_ALIGN (decl) = CLASSTYPE_ALIGN (basetype);
|
||||
DECL_USER_ALIGN (decl) = CLASSTYPE_USER_ALIGN (basetype);
|
||||
/* Tell the backend not to round up to TYPE_ALIGN. */
|
||||
DECL_PACKED (decl) = 1;
|
||||
|
||||
if (!integer_zerop (DECL_SIZE (decl)))
|
||||
{
|
||||
|
@ -4971,6 +4973,12 @@ layout_class_type (t, empty_p, vfuns_p,
|
|||
CLASSTYPE_SIZE (t) = bitsize_zero_node;
|
||||
CLASSTYPE_SIZE_UNIT (t) = size_zero_node;
|
||||
}
|
||||
/* If this is a POD, we can't reuse its tail padding. */
|
||||
else if (!CLASSTYPE_NON_POD_P (t))
|
||||
{
|
||||
CLASSTYPE_SIZE (t) = TYPE_SIZE (t);
|
||||
CLASSTYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (t);
|
||||
}
|
||||
else
|
||||
{
|
||||
CLASSTYPE_SIZE (t) = TYPE_BINFO_SIZE (t);
|
||||
|
|
|
@ -539,7 +539,7 @@ enum cp_tree_index
|
|||
CPTI_STD,
|
||||
CPTI_ABI,
|
||||
CPTI_TYPE_INFO_TYPE,
|
||||
CPTI_TINFO_DECL_TYPE,
|
||||
CPTI_TYPE_INFO_PTR_TYPE,
|
||||
CPTI_ABORT_FNDECL,
|
||||
CPTI_GLOBAL_DELETE_FNDECL,
|
||||
CPTI_AGGR_TAG,
|
||||
|
@ -626,7 +626,7 @@ extern tree cp_global_trees[CPTI_MAX];
|
|||
#define std_node cp_global_trees[CPTI_STD]
|
||||
#define abi_node cp_global_trees[CPTI_ABI]
|
||||
#define type_info_type_node cp_global_trees[CPTI_TYPE_INFO_TYPE]
|
||||
#define tinfo_decl_type cp_global_trees[CPTI_TINFO_DECL_TYPE]
|
||||
#define type_info_ptr_type cp_global_trees[CPTI_TYPE_INFO_PTR_TYPE]
|
||||
#define abort_fndecl cp_global_trees[CPTI_ABORT_FNDECL]
|
||||
#define global_delete_fndecl cp_global_trees[CPTI_GLOBAL_DELETE_FNDECL]
|
||||
#define current_aggr cp_global_trees[CPTI_AGGR_TAG]
|
||||
|
@ -3819,6 +3819,7 @@ extern tree coerce_delete_type PARAMS ((tree));
|
|||
extern void comdat_linkage PARAMS ((tree));
|
||||
extern void import_export_vtable PARAMS ((tree, tree, int));
|
||||
extern void import_export_decl PARAMS ((tree));
|
||||
extern void import_export_tinfo PARAMS ((tree, tree, int));
|
||||
extern tree build_cleanup PARAMS ((tree));
|
||||
extern void finish_file PARAMS ((void));
|
||||
extern tree reparse_absdcl_as_expr PARAMS ((tree, tree));
|
||||
|
@ -4051,7 +4052,7 @@ extern tree get_tinfo_decl PARAMS((tree));
|
|||
extern tree get_typeid PARAMS((tree));
|
||||
extern tree build_dynamic_cast PARAMS((tree, tree));
|
||||
extern void emit_support_tinfos PARAMS((void));
|
||||
extern int tinfo_decl_p PARAMS((tree, void *));
|
||||
extern int unemitted_tinfo_decl_p PARAMS((tree, void *));
|
||||
extern int emit_tinfo_decl PARAMS((tree *, void *));
|
||||
|
||||
/* in search.c */
|
||||
|
|
|
@ -2529,48 +2529,53 @@ import_export_decl (decl)
|
|||
else
|
||||
comdat_linkage (decl);
|
||||
}
|
||||
else if (tinfo_decl_p (decl, 0))
|
||||
{
|
||||
tree ctype = TREE_TYPE (DECL_NAME (decl));
|
||||
|
||||
if (IS_AGGR_TYPE (ctype))
|
||||
import_export_class (ctype);
|
||||
|
||||
if (IS_AGGR_TYPE (ctype) && CLASSTYPE_INTERFACE_KNOWN (ctype)
|
||||
&& TYPE_POLYMORPHIC_P (ctype)
|
||||
/* If -fno-rtti, we're not necessarily emitting this stuff with
|
||||
the class, so go ahead and emit it now. This can happen
|
||||
when a class is used in exception handling. */
|
||||
&& flag_rtti
|
||||
/* If the type is a cv-qualified variant of a type, then we
|
||||
must emit the tinfo function in this translation unit
|
||||
since it will not be emitted when the vtable for the type
|
||||
is output (which is when the unqualified version is
|
||||
generated). */
|
||||
&& same_type_p (ctype, TYPE_MAIN_VARIANT (ctype)))
|
||||
{
|
||||
DECL_NOT_REALLY_EXTERN (decl)
|
||||
= ! (CLASSTYPE_INTERFACE_ONLY (ctype)
|
||||
|| (DECL_DECLARED_INLINE_P (decl)
|
||||
&& ! flag_implement_inlines
|
||||
&& !DECL_VINDEX (decl)));
|
||||
|
||||
/* Always make artificials weak. */
|
||||
if (flag_weak)
|
||||
comdat_linkage (decl);
|
||||
}
|
||||
else if (TYPE_BUILT_IN (ctype)
|
||||
&& same_type_p (ctype, TYPE_MAIN_VARIANT (ctype)))
|
||||
DECL_NOT_REALLY_EXTERN (decl) = 0;
|
||||
else
|
||||
comdat_linkage (decl);
|
||||
}
|
||||
else
|
||||
comdat_linkage (decl);
|
||||
|
||||
DECL_INTERFACE_KNOWN (decl) = 1;
|
||||
}
|
||||
|
||||
/* Here, we only decide whether or not the tinfo node should be
|
||||
emitted with the vtable. IS_IN_LIBRARY is non-zero iff the
|
||||
typeinfo for TYPE should be in the runtime library. */
|
||||
|
||||
void
|
||||
import_export_tinfo (decl, type, is_in_library)
|
||||
tree decl;
|
||||
tree type;
|
||||
int is_in_library;
|
||||
{
|
||||
if (DECL_INTERFACE_KNOWN (decl))
|
||||
return;
|
||||
|
||||
if (IS_AGGR_TYPE (type))
|
||||
import_export_class (type);
|
||||
|
||||
if (IS_AGGR_TYPE (type) && CLASSTYPE_INTERFACE_KNOWN (type)
|
||||
&& TYPE_POLYMORPHIC_P (type)
|
||||
/* If -fno-rtti, we're not necessarily emitting this stuff with
|
||||
the class, so go ahead and emit it now. This can happen when
|
||||
a class is used in exception handling. */
|
||||
&& flag_rtti)
|
||||
{
|
||||
DECL_NOT_REALLY_EXTERN (decl) = !CLASSTYPE_INTERFACE_ONLY (type);
|
||||
DECL_COMDAT (decl) = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
DECL_NOT_REALLY_EXTERN (decl) = 1;
|
||||
DECL_COMDAT (decl) = 1;
|
||||
}
|
||||
|
||||
/* Now override some cases. */
|
||||
if (flag_weak)
|
||||
DECL_COMDAT (decl) = 1;
|
||||
else if (is_in_library)
|
||||
DECL_COMDAT (decl) = 0;
|
||||
|
||||
DECL_INTERFACE_KNOWN (decl) = 1;
|
||||
}
|
||||
|
||||
tree
|
||||
build_cleanup (decl)
|
||||
tree decl;
|
||||
|
@ -3364,7 +3369,7 @@ finish_file ()
|
|||
|
||||
/* Write out needed type info variables. Writing out one variable
|
||||
might cause others to be needed. */
|
||||
if (walk_globals (tinfo_decl_p, emit_tinfo_decl, /*data=*/0))
|
||||
if (walk_globals (unemitted_tinfo_decl_p, emit_tinfo_decl, /*data=*/0))
|
||||
reconsider = 1;
|
||||
|
||||
/* The list of objects with static storage duration is built up
|
||||
|
|
|
@ -982,8 +982,17 @@ write_unqualified_name (decl)
|
|||
{
|
||||
/* Conversion operator. Handle it right here.
|
||||
<operator> ::= cv <type> */
|
||||
tree type;
|
||||
if (decl_is_template_id (decl, NULL))
|
||||
{
|
||||
tree fn_type = get_mostly_instantiated_function_type (decl, NULL,
|
||||
NULL);
|
||||
type = TREE_TYPE (fn_type);
|
||||
}
|
||||
else
|
||||
type = TREE_TYPE (DECL_NAME (decl));
|
||||
write_string ("cv");
|
||||
write_type (TREE_TYPE (DECL_NAME (decl)));
|
||||
write_type (type);
|
||||
}
|
||||
else if (DECL_OVERLOADED_OPERATOR_P (decl))
|
||||
{
|
||||
|
|
616
gcc/cp/rtti.c
616
gcc/cp/rtti.c
|
@ -1,5 +1,5 @@
|
|||
/* RunTime Type Identification
|
||||
Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001
|
||||
Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
|
||||
Free Software Foundation, Inc.
|
||||
Mostly written by Jason Merrill (jason@cygnus.com).
|
||||
|
||||
|
@ -30,16 +30,46 @@ Boston, MA 02111-1307, USA. */
|
|||
#include "assert.h"
|
||||
#include "toplev.h"
|
||||
|
||||
/* C++ returns type information to the user in struct type_info
|
||||
objects. We also use type information to implement dynamic_cast and
|
||||
exception handlers. Type information for a particular type is
|
||||
indicated with an ABI defined structure derived from type_info.
|
||||
This would all be very straight forward, but for the fact that the
|
||||
runtime library provides the definitions of the type_info structure
|
||||
and the ABI defined derived classes. We cannot build declarations
|
||||
of them directly in the compiler, but we need to layout objects of
|
||||
their type. Somewhere we have to lie.
|
||||
|
||||
We define layout compatible POD-structs with compiler-defined names
|
||||
and generate the appropriate initializations for them (complete
|
||||
with explicit mention of their vtable). When we have to provide a
|
||||
type_info to the user we reinterpret_cast the internal compiler
|
||||
type to type_info. A well formed program can only explicitly refer
|
||||
to the type_infos of complete types (& cv void). However, we chain
|
||||
pointer type_infos to the pointed-to-type, and that can be
|
||||
incomplete. We only need the addresses of such incomplete
|
||||
type_info objects for static initialization.
|
||||
|
||||
The type information VAR_DECL of a type is held on the
|
||||
IDENTIFIER_GLOBAL_VALUE of the type's mangled name. That VAR_DECL
|
||||
will be the internal type. It will usually have the correct
|
||||
internal type reflecting the kind of type it represents (pointer,
|
||||
array, function, class, inherited class, etc). When the type it
|
||||
represents is incomplete, it will have the internal type
|
||||
corresponding to type_info. That will only happen at the end of
|
||||
translation, when we are emitting the type info objects. */
|
||||
|
||||
/* Accessors for the type_info objects. We need to remember several things
|
||||
about each of the type_info types. The global tree nodes such as
|
||||
bltn_desc_type_node are TREE_LISTs, and these macros are used to access
|
||||
the required information. */
|
||||
/* The RECORD_TYPE of a type_info derived class. */
|
||||
#define TINFO_PSEUDO_TYPE(NODE) TREE_TYPE (NODE)
|
||||
/* The VAR_DECL of the vtable for the type_info derived class. */
|
||||
/* The VAR_DECL of the vtable for the type_info derived class.
|
||||
This is only filled in at the end of the translation. */
|
||||
#define TINFO_VTABLE_DECL(NODE) TREE_VALUE (NODE)
|
||||
|
||||
extern struct obstack permanent_obstack;
|
||||
/* The IDENTIFIER_NODE naming the real class. */
|
||||
#define TINFO_REAL_NAME(NODE) TREE_PURPOSE (NODE)
|
||||
|
||||
static tree build_headof PARAMS((tree));
|
||||
static tree ifnonnull PARAMS((tree, tree));
|
||||
|
@ -48,7 +78,8 @@ static tree build_dynamic_cast_1 PARAMS((tree, tree));
|
|||
static tree throw_bad_cast PARAMS((void));
|
||||
static tree throw_bad_typeid PARAMS((void));
|
||||
static tree get_tinfo_decl_dynamic PARAMS((tree));
|
||||
static bool typeid_ok_p PARAMS ((void));
|
||||
static tree get_tinfo_ptr PARAMS((tree));
|
||||
static bool typeid_ok_p PARAMS((void));
|
||||
static int qualifier_flags PARAMS((tree));
|
||||
static int target_incomplete_p PARAMS((tree));
|
||||
static tree tinfo_base_init PARAMS((tree, tree));
|
||||
|
@ -59,15 +90,21 @@ static tree dfs_class_hint_mark PARAMS ((tree, void *));
|
|||
static tree dfs_class_hint_unmark PARAMS ((tree, void *));
|
||||
static int class_hint_flags PARAMS((tree));
|
||||
static tree class_initializer PARAMS((tree, tree, tree));
|
||||
static tree synthesize_tinfo_var PARAMS((tree, tree));
|
||||
static tree create_real_tinfo_var PARAMS((tree, tree, tree, tree, int));
|
||||
static tree create_pseudo_type_info PARAMS((const char *, int, ...));
|
||||
static tree get_vmi_pseudo_type_info PARAMS((int));
|
||||
static tree get_pseudo_ti_init PARAMS ((tree, tree, int *));
|
||||
static tree get_pseudo_ti_desc PARAMS((tree));
|
||||
static void create_tinfo_types PARAMS((void));
|
||||
static int typeinfo_in_lib_p PARAMS((tree));
|
||||
|
||||
static int doing_runtime = 0;
|
||||
|
||||
|
||||
/* Declare language defined type_info type and a pointer to const
|
||||
type_info. This is incomplete here, and will be completed when
|
||||
the user #includes <typeinfo>. There are language defined
|
||||
restrictions on what can be done until that is included. Create
|
||||
the internal versions of the ABI types. */
|
||||
|
||||
void
|
||||
init_rtti_processing ()
|
||||
{
|
||||
|
@ -75,8 +112,11 @@ init_rtti_processing ()
|
|||
type_info_type_node = xref_tag
|
||||
(class_type_node, get_identifier ("type_info"), 1);
|
||||
pop_namespace ();
|
||||
tinfo_decl_type =
|
||||
build_qualified_type (type_info_type_node, TYPE_QUAL_CONST);
|
||||
type_info_ptr_type =
|
||||
build_pointer_type
|
||||
(build_qualified_type (type_info_type_node, TYPE_QUAL_CONST));
|
||||
|
||||
create_tinfo_types ();
|
||||
}
|
||||
|
||||
/* Given the expression EXP of type `class *', return the head of the
|
||||
|
@ -183,13 +223,12 @@ get_tinfo_decl_dynamic (exp)
|
|||
/* The RTTI information is at index -1. */
|
||||
index = integer_minus_one_node;
|
||||
t = build_vtbl_ref (exp, index);
|
||||
TREE_TYPE (t) = build_pointer_type (tinfo_decl_type);
|
||||
TREE_TYPE (t) = type_info_ptr_type;
|
||||
return t;
|
||||
}
|
||||
|
||||
/* otherwise return the type_info for the static type of the expr. */
|
||||
exp = get_tinfo_decl (TYPE_MAIN_VARIANT (type));
|
||||
return build_unary_op (ADDR_EXPR, exp, 0);
|
||||
/* Otherwise return the type_info for the static type of the expr. */
|
||||
return get_tinfo_ptr (TYPE_MAIN_VARIANT (type));
|
||||
}
|
||||
|
||||
static bool
|
||||
|
@ -263,9 +302,9 @@ tinfo_name (type)
|
|||
return name_string;
|
||||
}
|
||||
|
||||
/* Returns a decl for the type_info variable for TYPE. You must
|
||||
arrange that the decl is mark_used, if actually use it --- decls in
|
||||
vtables are only used if the vtable is output. */
|
||||
/* Return a VAR_DECL for the internal ABI defined type_info object for
|
||||
TYPE. You must arrange that the decl is mark_used, if actually use
|
||||
it --- decls in vtables are only used if the vtable is output. */
|
||||
|
||||
tree
|
||||
get_tinfo_decl (type)
|
||||
|
@ -278,7 +317,7 @@ get_tinfo_decl (type)
|
|||
&& TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
|
||||
{
|
||||
error ("cannot create type information for type `%T' because its size is variable",
|
||||
type);
|
||||
type);
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
|
@ -291,37 +330,45 @@ get_tinfo_decl (type)
|
|||
name = mangle_typeinfo_for_type (type);
|
||||
|
||||
d = IDENTIFIER_GLOBAL_VALUE (name);
|
||||
if (d)
|
||||
/* OK */;
|
||||
else
|
||||
if (!d)
|
||||
{
|
||||
/* The tinfo decl is the type_info object itself. We make all
|
||||
tinfo objects look as type_info, even though they will end up
|
||||
being a subclass of that when emitted. This means that we'll
|
||||
erroneously think we know the dynamic type -- be careful in the
|
||||
runtime. */
|
||||
d = build_lang_decl (VAR_DECL, name, tinfo_decl_type);
|
||||
tree var_desc = get_pseudo_ti_desc (type);
|
||||
|
||||
d = build_lang_decl (VAR_DECL, name, TINFO_PSEUDO_TYPE (var_desc));
|
||||
|
||||
DECL_ARTIFICIAL (d) = 1;
|
||||
DECL_ALIGN (d) = TYPE_ALIGN (ptr_type_node);
|
||||
DECL_USER_ALIGN (d) = 0;
|
||||
TREE_READONLY (d) = 1;
|
||||
TREE_STATIC (d) = 1;
|
||||
DECL_EXTERNAL (d) = 1;
|
||||
TREE_PUBLIC (d) = 1;
|
||||
if (flag_weak || !typeinfo_in_lib_p (type))
|
||||
comdat_linkage (d);
|
||||
SET_DECL_ASSEMBLER_NAME (d, name);
|
||||
DECL_COMDAT (d) = 1;
|
||||
cp_finish_decl (d, NULL_TREE, NULL_TREE, 0);
|
||||
|
||||
pushdecl_top_level (d);
|
||||
|
||||
/* Remember the type it is for. */
|
||||
TREE_TYPE (name) = type;
|
||||
TREE_USED (name) = 1;
|
||||
}
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
/* Return a pointer to a type_info object describing TYPE, suitably
|
||||
cast to the language defined type. */
|
||||
|
||||
static tree
|
||||
get_tinfo_ptr (type)
|
||||
tree type;
|
||||
{
|
||||
tree exp = get_tinfo_decl (type);
|
||||
|
||||
/* Convert to type_info type. */
|
||||
exp = build_unary_op (ADDR_EXPR, exp, 0);
|
||||
exp = ocp_convert (type_info_ptr_type, exp, CONV_REINTERPRET, 0);
|
||||
|
||||
return exp;
|
||||
}
|
||||
|
||||
/* Return the type_info object for TYPE. */
|
||||
|
||||
tree
|
||||
|
@ -350,7 +397,7 @@ get_typeid (type)
|
|||
if (!type)
|
||||
return error_mark_node;
|
||||
|
||||
return get_tinfo_decl (type);
|
||||
return build_indirect_ref (get_tinfo_ptr (type), NULL);
|
||||
}
|
||||
|
||||
/* Check whether TEST is null before returning RESULT. If TEST is used in
|
||||
|
@ -683,6 +730,7 @@ tinfo_base_init (desc, target)
|
|||
{
|
||||
tree init = NULL_TREE;
|
||||
tree name_decl;
|
||||
tree vtable_ptr;
|
||||
|
||||
{
|
||||
tree name_name;
|
||||
|
@ -710,12 +758,40 @@ tinfo_base_init (desc, target)
|
|||
cp_finish_decl (name_decl, name_string, NULL_TREE, 0);
|
||||
pushdecl_top_level (name_decl);
|
||||
}
|
||||
|
||||
if (TINFO_VTABLE_DECL (desc))
|
||||
|
||||
vtable_ptr = TINFO_VTABLE_DECL (desc);
|
||||
if (!vtable_ptr)
|
||||
{
|
||||
tree vtbl_ptr = TINFO_VTABLE_DECL (desc);
|
||||
init = tree_cons (NULL_TREE, vtbl_ptr, init);
|
||||
tree real_type;
|
||||
|
||||
push_nested_namespace (abi_node);
|
||||
real_type = xref_tag (class_type_node, TINFO_REAL_NAME (desc), 1);
|
||||
pop_nested_namespace (abi_node);
|
||||
|
||||
if (!COMPLETE_TYPE_P (real_type))
|
||||
{
|
||||
/* We never saw a definition of this type, so we need to
|
||||
tell the compiler that this is an exported class, as
|
||||
indeed all of the __*_type_info classes are. */
|
||||
SET_CLASSTYPE_INTERFACE_KNOWN (real_type);
|
||||
CLASSTYPE_INTERFACE_ONLY (real_type) = 1;
|
||||
}
|
||||
|
||||
vtable_ptr = get_vtable_decl (real_type, /*complete=*/1);
|
||||
vtable_ptr = build_unary_op (ADDR_EXPR, vtable_ptr, 0);
|
||||
|
||||
/* We need to point into the middle of the vtable. */
|
||||
vtable_ptr = build
|
||||
(PLUS_EXPR, TREE_TYPE (vtable_ptr), vtable_ptr,
|
||||
size_binop (MULT_EXPR,
|
||||
size_int (2),
|
||||
TYPE_SIZE_UNIT (vtable_entry_type)));
|
||||
TREE_CONSTANT (vtable_ptr) = 1;
|
||||
|
||||
TINFO_VTABLE_DECL (desc) = vtable_ptr;
|
||||
}
|
||||
|
||||
init = tree_cons (NULL_TREE, vtable_ptr, init);
|
||||
|
||||
init = tree_cons (NULL_TREE, decay_conversion (name_decl), init);
|
||||
|
||||
|
@ -764,8 +840,7 @@ ptr_initializer (desc, target, non_public_ptr)
|
|||
}
|
||||
init = tree_cons (NULL_TREE, build_int_2 (flags, 0), init);
|
||||
init = tree_cons (NULL_TREE,
|
||||
build_unary_op (ADDR_EXPR,
|
||||
get_tinfo_decl (TYPE_MAIN_VARIANT (to)), 0),
|
||||
get_tinfo_ptr (TYPE_MAIN_VARIANT (to)),
|
||||
init);
|
||||
|
||||
init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, nreverse (init));
|
||||
|
@ -802,12 +877,11 @@ ptm_initializer (desc, target, non_public_ptr)
|
|||
}
|
||||
init = tree_cons (NULL_TREE, build_int_2 (flags, 0), init);
|
||||
init = tree_cons (NULL_TREE,
|
||||
build_unary_op (ADDR_EXPR,
|
||||
get_tinfo_decl (TYPE_MAIN_VARIANT (to)), 0),
|
||||
get_tinfo_ptr (TYPE_MAIN_VARIANT (to)),
|
||||
init);
|
||||
init = tree_cons (NULL_TREE,
|
||||
build_unary_op (ADDR_EXPR, get_tinfo_decl (klass), 0),
|
||||
init);
|
||||
get_tinfo_ptr (klass),
|
||||
init);
|
||||
|
||||
init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, nreverse (init));
|
||||
TREE_HAS_CONSTRUCTOR (init) = TREE_CONSTANT (init) = TREE_STATIC (init) = 1;
|
||||
|
@ -928,77 +1002,63 @@ typeinfo_in_lib_p (type)
|
|||
}
|
||||
}
|
||||
|
||||
/* Generate a pseudo_type_info VAR_DECL suitable for the supplied
|
||||
TARGET_TYPE and given the REAL_NAME. This is the structure expected by
|
||||
the runtime, and therefore has additional fields. If we need not emit a
|
||||
definition (because the runtime must contain it), return NULL_TREE,
|
||||
otherwise return the VAR_DECL. */
|
||||
/* Generate the initializer for the type info describing
|
||||
TYPE. VAR_DESC is a . NON_PUBLIC_P is set non-zero, if the VAR_DECL
|
||||
should not be exported from this object file. This should only be
|
||||
called at the end of translation, when we know that no further
|
||||
types will be completed. */
|
||||
|
||||
static tree
|
||||
synthesize_tinfo_var (target_type, real_name)
|
||||
tree target_type;
|
||||
tree real_name;
|
||||
get_pseudo_ti_init (type, var_desc, non_public_p)
|
||||
tree type;
|
||||
tree var_desc;
|
||||
int *non_public_p;
|
||||
{
|
||||
tree var_init = NULL_TREE;
|
||||
tree var_type = NULL_TREE;
|
||||
int non_public = 0;
|
||||
|
||||
switch (TREE_CODE (target_type))
|
||||
my_friendly_assert (at_eof, 20021120);
|
||||
switch (TREE_CODE (type))
|
||||
{
|
||||
case POINTER_TYPE:
|
||||
if (TYPE_PTRMEM_P (target_type))
|
||||
{
|
||||
var_type = ptm_desc_type_node;
|
||||
var_init = ptm_initializer (var_type, target_type, &non_public);
|
||||
}
|
||||
if (TYPE_PTRMEM_P (type))
|
||||
return ptm_initializer (var_desc, type, non_public_p);
|
||||
else
|
||||
{
|
||||
if (typeinfo_in_lib_p (target_type) && !doing_runtime)
|
||||
/* These are in the runtime. */
|
||||
return NULL_TREE;
|
||||
var_type = ptr_desc_type_node;
|
||||
var_init = ptr_initializer (var_type, target_type, &non_public);
|
||||
}
|
||||
return ptr_initializer (var_desc, type, non_public_p);
|
||||
break;
|
||||
case ENUMERAL_TYPE:
|
||||
var_type = enum_desc_type_node;
|
||||
var_init = generic_initializer (var_type, target_type);
|
||||
return generic_initializer (var_desc, type);
|
||||
break;
|
||||
case FUNCTION_TYPE:
|
||||
var_type = func_desc_type_node;
|
||||
var_init = generic_initializer (var_type, target_type);
|
||||
return generic_initializer (var_desc, type);
|
||||
break;
|
||||
case ARRAY_TYPE:
|
||||
var_type = ary_desc_type_node;
|
||||
var_init = generic_initializer (var_type, target_type);
|
||||
return generic_initializer (var_desc, type);
|
||||
break;
|
||||
case UNION_TYPE:
|
||||
case RECORD_TYPE:
|
||||
if (TYPE_PTRMEMFUNC_P (target_type))
|
||||
if (TYPE_PTRMEMFUNC_P (type))
|
||||
return ptm_initializer (var_desc, type, non_public_p);
|
||||
else if (var_desc == class_desc_type_node)
|
||||
{
|
||||
var_type = ptm_desc_type_node;
|
||||
var_init = ptm_initializer (var_type, target_type, &non_public);
|
||||
}
|
||||
else if (!COMPLETE_TYPE_P (target_type))
|
||||
{
|
||||
/* Emit a non-public class_type_info. */
|
||||
non_public = 1;
|
||||
var_type = class_desc_type_node;
|
||||
var_init = class_initializer (var_type, target_type, NULL_TREE);
|
||||
}
|
||||
else if (!CLASSTYPE_N_BASECLASSES (target_type))
|
||||
{
|
||||
var_type = class_desc_type_node;
|
||||
var_init = class_initializer (var_type, target_type, NULL_TREE);
|
||||
if (!COMPLETE_TYPE_P (type))
|
||||
/* Emit a non-public class_type_info. */
|
||||
*non_public_p = 1;
|
||||
return class_initializer (var_desc, type, NULL_TREE);
|
||||
}
|
||||
else if (var_desc == si_class_desc_type_node)
|
||||
{
|
||||
tree base_binfos = BINFO_BASETYPES (TYPE_BINFO (type));
|
||||
tree base_binfo = TREE_VEC_ELT (base_binfos, 0);
|
||||
tree tinfo = get_tinfo_ptr (BINFO_TYPE (base_binfo));
|
||||
tree base_inits = tree_cons (NULL_TREE, tinfo, NULL_TREE);
|
||||
|
||||
return class_initializer (var_desc, type, base_inits);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* if this has a single public non-virtual base, it's easier */
|
||||
tree binfo = TYPE_BINFO (target_type);
|
||||
int hint = class_hint_flags (type);
|
||||
tree binfo = TYPE_BINFO (type);
|
||||
int nbases = BINFO_N_BASETYPES (binfo);
|
||||
tree base_binfos = BINFO_BASETYPES (binfo);
|
||||
tree base_inits = NULL_TREE;
|
||||
int is_simple = nbases == 1;
|
||||
int ix;
|
||||
|
||||
/* Generate the base information initializer. */
|
||||
|
@ -1012,28 +1072,19 @@ synthesize_tinfo_var (target_type, real_name)
|
|||
|
||||
if (TREE_PUBLIC (base_binfo))
|
||||
flags |= 2;
|
||||
tinfo = get_tinfo_decl (BINFO_TYPE (base_binfo));
|
||||
tinfo = build_unary_op (ADDR_EXPR, tinfo, 0);
|
||||
tinfo = get_tinfo_ptr (BINFO_TYPE (base_binfo));
|
||||
if (TREE_VIA_VIRTUAL (base_binfo))
|
||||
{
|
||||
/* We store the vtable offset at which the virtual
|
||||
base offset can be found. */
|
||||
offset = BINFO_VPTR_FIELD (binfo_for_vbase (BINFO_TYPE (base_binfo),
|
||||
target_type));
|
||||
offset = BINFO_VPTR_FIELD
|
||||
(binfo_for_vbase (BINFO_TYPE (base_binfo), type));
|
||||
offset = convert (sizetype, offset);
|
||||
flags |= 1;
|
||||
}
|
||||
else
|
||||
offset = BINFO_OFFSET (base_binfo);
|
||||
|
||||
/* is it a single public inheritance? */
|
||||
if (is_simple && flags == 2 && integer_zerop (offset))
|
||||
{
|
||||
base_inits = tree_cons (NULL_TREE, tinfo, NULL_TREE);
|
||||
break;
|
||||
}
|
||||
is_simple = 0;
|
||||
|
||||
/* combine offset and flags into one field */
|
||||
offset = cp_build_binary_op (LSHIFT_EXPR, offset,
|
||||
build_int_2 (8, 0));
|
||||
|
@ -1044,86 +1095,23 @@ synthesize_tinfo_var (target_type, real_name)
|
|||
base_init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, base_init);
|
||||
base_inits = tree_cons (NULL_TREE, base_init, base_inits);
|
||||
}
|
||||
|
||||
if (is_simple)
|
||||
var_type = si_class_desc_type_node;
|
||||
else
|
||||
{
|
||||
int hint = class_hint_flags (target_type);
|
||||
|
||||
base_inits = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, base_inits);
|
||||
base_inits = tree_cons (NULL_TREE, base_inits, NULL_TREE);
|
||||
/* Prepend the number of bases. */
|
||||
base_inits = tree_cons (NULL_TREE,
|
||||
build_int_2 (nbases, 0), base_inits);
|
||||
/* Prepend the hint flags. */
|
||||
base_inits = tree_cons (NULL_TREE,
|
||||
build_int_2 (hint, 0), base_inits);
|
||||
var_type = get_vmi_pseudo_type_info (nbases);
|
||||
}
|
||||
var_init = class_initializer (var_type, target_type, base_inits);
|
||||
base_inits = build (CONSTRUCTOR,
|
||||
NULL_TREE, NULL_TREE, base_inits);
|
||||
base_inits = tree_cons (NULL_TREE, base_inits, NULL_TREE);
|
||||
/* Prepend the number of bases. */
|
||||
base_inits = tree_cons (NULL_TREE,
|
||||
build_int_2 (nbases, 0), base_inits);
|
||||
/* Prepend the hint flags. */
|
||||
base_inits = tree_cons (NULL_TREE,
|
||||
build_int_2 (hint, 0), base_inits);
|
||||
|
||||
return class_initializer (var_desc, type, base_inits);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (typeinfo_in_lib_p (target_type))
|
||||
{
|
||||
if (!doing_runtime)
|
||||
/* These are guaranteed to be in the runtime. */
|
||||
return NULL_TREE;
|
||||
var_type = bltn_desc_type_node;
|
||||
var_init = generic_initializer (var_type, target_type);
|
||||
break;
|
||||
}
|
||||
abort ();
|
||||
return generic_initializer (var_desc, type);
|
||||
}
|
||||
|
||||
return create_real_tinfo_var (target_type,
|
||||
real_name, TINFO_PSEUDO_TYPE (var_type),
|
||||
var_init, non_public);
|
||||
}
|
||||
|
||||
/* Create the real typeinfo variable. NON_PUBLIC indicates that we cannot
|
||||
make this variable public (comdat). */
|
||||
|
||||
static tree
|
||||
create_real_tinfo_var (target_type, name, type, init, non_public)
|
||||
tree target_type;
|
||||
tree name;
|
||||
tree type;
|
||||
tree init;
|
||||
int non_public;
|
||||
{
|
||||
static int count = 0;
|
||||
tree decl;
|
||||
tree hidden_name;
|
||||
char hidden[30];
|
||||
|
||||
/* We cannot give this the name NAME, as that already is globally
|
||||
bound to the tinfo_decl we originally created for this type in
|
||||
get_tinfo_decl. */
|
||||
sprintf (hidden, "__ti_%d", count++);
|
||||
hidden_name = get_identifier (hidden);
|
||||
|
||||
decl = build_lang_decl (VAR_DECL, hidden_name,
|
||||
build_qualified_type (type, TYPE_QUAL_CONST));
|
||||
DECL_ARTIFICIAL (decl) = 1;
|
||||
TREE_READONLY (decl) = 1;
|
||||
TREE_STATIC (decl) = 1;
|
||||
DECL_EXTERNAL (decl) = 0;
|
||||
|
||||
if (!non_public)
|
||||
{
|
||||
TREE_PUBLIC (decl) = 1;
|
||||
if (flag_weak || !typeinfo_in_lib_p (target_type))
|
||||
comdat_linkage (decl);
|
||||
}
|
||||
SET_DECL_ASSEMBLER_NAME (decl, name);
|
||||
DECL_INITIAL (decl) = init;
|
||||
cp_finish_decl (decl, init, NULL_TREE, 0);
|
||||
pushdecl_top_level (decl);
|
||||
TREE_USED (decl) = 1;
|
||||
return decl;
|
||||
}
|
||||
|
||||
/* Generate the RECORD_TYPE containing the data layout of a type_info
|
||||
|
@ -1132,7 +1120,10 @@ create_real_tinfo_var (target_type, name, type, init, non_public)
|
|||
type's vtable. We explicitly manage the vtable member, and name it for
|
||||
real type as used in the runtime. The RECORD type has a different name,
|
||||
to avoid collisions. Return a TREE_LIST who's TINFO_PSEUDO_TYPE
|
||||
is the generated type and TINFO_VTABLE_DECL is the vtable decl.
|
||||
is the generated type and TINFO_VTABLE_NAME is the name of the
|
||||
vtable. We have to delay generating the VAR_DECL of the vtable
|
||||
until the end of the translation, when we'll have seen the library
|
||||
definition, if there was one.
|
||||
|
||||
REAL_NAME is the runtime's name of the type. Trailing arguments are
|
||||
additional FIELD_DECL's for the structure. The final argument must be
|
||||
|
@ -1141,9 +1132,8 @@ create_real_tinfo_var (target_type, name, type, init, non_public)
|
|||
static tree
|
||||
create_pseudo_type_info VPARAMS((const char *real_name, int ident, ...))
|
||||
{
|
||||
tree real_type, pseudo_type;
|
||||
tree pseudo_type;
|
||||
char *pseudo_name;
|
||||
tree vtable_decl;
|
||||
int ix;
|
||||
tree fields[10];
|
||||
tree field_decl;
|
||||
|
@ -1160,29 +1150,6 @@ create_pseudo_type_info VPARAMS((const char *real_name, int ident, ...))
|
|||
if (ident)
|
||||
sprintf (pseudo_name + strlen (pseudo_name), "%d", ident);
|
||||
|
||||
/* Get the vtable decl. */
|
||||
real_type = xref_tag (class_type_node, get_identifier (real_name), 1);
|
||||
if (! TYPE_SIZE (real_type))
|
||||
{
|
||||
/* We never saw a definition of this type, so we need to tell the
|
||||
compiler that this is an exported class, as indeed all of the
|
||||
__*_type_info classes are. */
|
||||
SET_CLASSTYPE_INTERFACE_KNOWN (real_type);
|
||||
CLASSTYPE_INTERFACE_ONLY (real_type) = 1;
|
||||
}
|
||||
|
||||
vtable_decl = get_vtable_decl (real_type, /*complete=*/1);
|
||||
vtable_decl = build_unary_op (ADDR_EXPR, vtable_decl, 0);
|
||||
|
||||
/* We need to point into the middle of the vtable. */
|
||||
vtable_decl = build (PLUS_EXPR,
|
||||
TREE_TYPE (vtable_decl),
|
||||
vtable_decl,
|
||||
size_binop (MULT_EXPR,
|
||||
size_int (2),
|
||||
TYPE_SIZE_UNIT (vtable_entry_type)));
|
||||
TREE_CONSTANT (vtable_decl) = 1;
|
||||
|
||||
/* First field is the pseudo type_info base class. */
|
||||
fields[0] = build_decl (FIELD_DECL, NULL_TREE, ti_desc_type_node);
|
||||
|
||||
|
@ -1196,53 +1163,96 @@ create_pseudo_type_info VPARAMS((const char *real_name, int ident, ...))
|
|||
TYPE_HAS_CONSTRUCTOR (pseudo_type) = 1;
|
||||
|
||||
result = tree_cons (NULL_TREE, NULL_TREE, NULL_TREE);
|
||||
TINFO_VTABLE_DECL (result) = vtable_decl;
|
||||
TINFO_PSEUDO_TYPE (result) = pseudo_type;
|
||||
TINFO_REAL_NAME (result) = get_identifier (real_name);
|
||||
TINFO_PSEUDO_TYPE (result) =
|
||||
cp_build_qualified_type (pseudo_type, TYPE_QUAL_CONST);
|
||||
|
||||
VA_CLOSE (ap);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Return a descriptor for a vmi type with NUM_BASES bases. */
|
||||
/* Return a pseudo type info type node used to describe TYPE. TYPE
|
||||
must be a complete type (or cv void), except at the end of the
|
||||
translation unit. */
|
||||
|
||||
static tree
|
||||
get_vmi_pseudo_type_info (num_bases)
|
||||
int num_bases;
|
||||
get_pseudo_ti_desc (type)
|
||||
tree type;
|
||||
{
|
||||
tree desc;
|
||||
tree array_domain, base_array;
|
||||
|
||||
if (TREE_VEC_LENGTH (vmi_class_desc_type_node) <= num_bases)
|
||||
switch (TREE_CODE (type))
|
||||
{
|
||||
int ix;
|
||||
tree extend = make_tree_vec (num_bases + 5);
|
||||
|
||||
for (ix = TREE_VEC_LENGTH (vmi_class_desc_type_node); ix--;)
|
||||
TREE_VEC_ELT (extend, ix) = TREE_VEC_ELT (vmi_class_desc_type_node, ix);
|
||||
vmi_class_desc_type_node = extend;
|
||||
case POINTER_TYPE:
|
||||
return TYPE_PTRMEM_P (type) ? ptm_desc_type_node : ptr_desc_type_node;
|
||||
case ENUMERAL_TYPE:
|
||||
return enum_desc_type_node;
|
||||
case FUNCTION_TYPE:
|
||||
return func_desc_type_node;
|
||||
case ARRAY_TYPE:
|
||||
return ary_desc_type_node;
|
||||
case UNION_TYPE:
|
||||
case RECORD_TYPE:
|
||||
if (TYPE_PTRMEMFUNC_P (type))
|
||||
return ptm_desc_type_node;
|
||||
else if (!COMPLETE_TYPE_P (type))
|
||||
{
|
||||
my_friendly_assert (at_eof, 20020609);
|
||||
return class_desc_type_node;
|
||||
}
|
||||
else if (!CLASSTYPE_N_BASECLASSES (type))
|
||||
return class_desc_type_node;
|
||||
else
|
||||
{
|
||||
tree base_binfo =
|
||||
TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO (type)), 0);
|
||||
int num_bases = BINFO_N_BASETYPES (TYPE_BINFO (type));
|
||||
|
||||
if (num_bases == 1
|
||||
&& TREE_PUBLIC (base_binfo)
|
||||
&& !TREE_VIA_VIRTUAL (base_binfo)
|
||||
&& integer_zerop (BINFO_OFFSET (base_binfo)))
|
||||
/* single non-virtual public. */
|
||||
return si_class_desc_type_node;
|
||||
else
|
||||
{
|
||||
tree var_desc;
|
||||
tree array_domain, base_array;
|
||||
|
||||
if (TREE_VEC_LENGTH (vmi_class_desc_type_node) <= num_bases)
|
||||
{
|
||||
int ix;
|
||||
tree extend = make_tree_vec (num_bases + 5);
|
||||
|
||||
for (ix = TREE_VEC_LENGTH (vmi_class_desc_type_node); ix--;)
|
||||
TREE_VEC_ELT (extend, ix)
|
||||
= TREE_VEC_ELT (vmi_class_desc_type_node, ix);
|
||||
vmi_class_desc_type_node = extend;
|
||||
}
|
||||
var_desc = TREE_VEC_ELT (vmi_class_desc_type_node, num_bases);
|
||||
if (var_desc)
|
||||
return var_desc;
|
||||
|
||||
/* Add number of bases and trailing array of
|
||||
base_class_type_info. */
|
||||
array_domain = build_index_type (size_int (num_bases));
|
||||
base_array =
|
||||
build_array_type (base_desc_type_node, array_domain);
|
||||
|
||||
push_nested_namespace (abi_node);
|
||||
var_desc = create_pseudo_type_info
|
||||
("__vmi_class_type_info", num_bases,
|
||||
build_decl (FIELD_DECL, NULL_TREE, integer_type_node),
|
||||
build_decl (FIELD_DECL, NULL_TREE, integer_type_node),
|
||||
build_decl (FIELD_DECL, NULL_TREE, base_array),
|
||||
NULL);
|
||||
pop_nested_namespace (abi_node);
|
||||
|
||||
TREE_VEC_ELT (vmi_class_desc_type_node, num_bases) = var_desc;
|
||||
return var_desc;
|
||||
}
|
||||
}
|
||||
default:
|
||||
return bltn_desc_type_node;
|
||||
}
|
||||
desc = TREE_VEC_ELT (vmi_class_desc_type_node, num_bases);
|
||||
|
||||
if (desc)
|
||||
return desc;
|
||||
|
||||
/* Add number of bases and trailing array of base_class_type_info. */
|
||||
array_domain = build_index_type (size_int (num_bases));
|
||||
base_array = build_array_type (base_desc_type_node, array_domain);
|
||||
|
||||
push_nested_namespace (abi_node);
|
||||
|
||||
desc = create_pseudo_type_info
|
||||
("__vmi_class_type_info", num_bases,
|
||||
build_decl (FIELD_DECL, NULL_TREE, integer_type_node),
|
||||
build_decl (FIELD_DECL, NULL_TREE, integer_type_node),
|
||||
build_decl (FIELD_DECL, NULL_TREE, base_array),
|
||||
NULL);
|
||||
|
||||
pop_nested_namespace (abi_node);
|
||||
|
||||
TREE_VEC_ELT (vmi_class_desc_type_node, num_bases) = desc;
|
||||
return desc;
|
||||
}
|
||||
|
||||
/* Make sure the required builtin types exist for generating the type_info
|
||||
|
@ -1251,15 +1261,9 @@ get_vmi_pseudo_type_info (num_bases)
|
|||
static void
|
||||
create_tinfo_types ()
|
||||
{
|
||||
tree ptr_type_info;
|
||||
|
||||
if (bltn_desc_type_node)
|
||||
return;
|
||||
push_nested_namespace (abi_node);
|
||||
my_friendly_assert (!ti_desc_type_node, 20020609);
|
||||
|
||||
ptr_type_info = build_pointer_type
|
||||
(build_qualified_type
|
||||
(type_info_type_node, TYPE_QUAL_CONST));
|
||||
push_nested_namespace (abi_node);
|
||||
|
||||
/* Create the internal type_info structure. This is used as a base for
|
||||
the other structures. */
|
||||
|
@ -1299,7 +1303,7 @@ create_tinfo_types ()
|
|||
This is really a descendant of __class_type_info. */
|
||||
si_class_desc_type_node = create_pseudo_type_info
|
||||
("__si_class_type_info", 0,
|
||||
build_decl (FIELD_DECL, NULL_TREE, ptr_type_info),
|
||||
build_decl (FIELD_DECL, NULL_TREE, type_info_ptr_type),
|
||||
NULL);
|
||||
|
||||
/* Base class internal helper. Pointer to base type, offset to base,
|
||||
|
@ -1307,7 +1311,7 @@ create_tinfo_types ()
|
|||
{
|
||||
tree fields[2];
|
||||
|
||||
fields[0] = build_decl (FIELD_DECL, NULL_TREE, ptr_type_info);
|
||||
fields[0] = build_decl (FIELD_DECL, NULL_TREE, type_info_ptr_type);
|
||||
fields[1] = build_decl (FIELD_DECL, NULL_TREE, integer_types[itk_long]);
|
||||
base_desc_type_node = make_aggr_type (RECORD_TYPE);
|
||||
finish_builtin_type (base_desc_type_node, "__base_class_type_info_pseudo",
|
||||
|
@ -1324,7 +1328,7 @@ create_tinfo_types ()
|
|||
ptr_desc_type_node = create_pseudo_type_info
|
||||
("__pointer_type_info", 0,
|
||||
build_decl (FIELD_DECL, NULL_TREE, integer_type_node),
|
||||
build_decl (FIELD_DECL, NULL_TREE, ptr_type_info),
|
||||
build_decl (FIELD_DECL, NULL_TREE, type_info_ptr_type),
|
||||
NULL);
|
||||
|
||||
/* Pointer to member data type_info. Add qualifications flags,
|
||||
|
@ -1333,8 +1337,8 @@ create_tinfo_types ()
|
|||
ptm_desc_type_node = create_pseudo_type_info
|
||||
("__pointer_to_member_type_info", 0,
|
||||
build_decl (FIELD_DECL, NULL_TREE, integer_type_node),
|
||||
build_decl (FIELD_DECL, NULL_TREE, ptr_type_info),
|
||||
build_decl (FIELD_DECL, NULL_TREE, ptr_type_info),
|
||||
build_decl (FIELD_DECL, NULL_TREE, type_info_ptr_type),
|
||||
build_decl (FIELD_DECL, NULL_TREE, type_info_ptr_type),
|
||||
NULL);
|
||||
|
||||
pop_nested_namespace (abi_node);
|
||||
|
@ -1401,75 +1405,61 @@ emit_support_tinfos ()
|
|||
definition emitted for it. */
|
||||
|
||||
int
|
||||
tinfo_decl_p (t, data)
|
||||
unemitted_tinfo_decl_p (t, data)
|
||||
tree t;
|
||||
void *data ATTRIBUTE_UNUSED;
|
||||
{
|
||||
return TREE_CODE (t) == VAR_DECL
|
||||
&& IDENTIFIER_GLOBAL_VALUE (DECL_NAME (t)) == (t)
|
||||
&& TREE_TYPE (t) == tinfo_decl_type
|
||||
&& TREE_TYPE (DECL_NAME (t));
|
||||
if (/* It's a var decl */
|
||||
TREE_CODE (t) == VAR_DECL
|
||||
/* whos name points back to itself */
|
||||
&& IDENTIFIER_GLOBAL_VALUE (DECL_NAME (t)) == t
|
||||
/* whos name's type is non-null */
|
||||
&& TREE_TYPE (DECL_NAME (t))
|
||||
/* and whos type is a struct */
|
||||
&& TREE_CODE (TREE_TYPE (t)) == RECORD_TYPE
|
||||
/* with a first field of our pseudo type info */
|
||||
&& TREE_TYPE (TYPE_FIELDS (TREE_TYPE (t))) == ti_desc_type_node)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Emit a suitable type_info definition for the type_info decl pointed to by
|
||||
DECL_PTR. We emit a completely new variable, of the correct type for the
|
||||
actual type this is describing. The DECL_ASSEMBLER_NAME of the generated
|
||||
definition is set to that of the supplied decl, so that they can be tied
|
||||
up. Mark the supplied decl as having been dealt with. Emitting one
|
||||
definition might cause other definitions to be required.
|
||||
|
||||
We need to do things this way, because we're trying to do something like
|
||||
|
||||
struct B : A {
|
||||
...
|
||||
};
|
||||
|
||||
extern const A tinfo_var;
|
||||
|
||||
const B tinfo_var = {...};
|
||||
|
||||
which is not permitted. Also, we've not necessarily seen the definition of B.
|
||||
So we do something like the following,
|
||||
|
||||
extern const A tinfo_var;
|
||||
|
||||
struct pseudo_A {
|
||||
const void *vtable_ptr;
|
||||
const char *name;
|
||||
};
|
||||
struct pseudo_B {
|
||||
pseudo_A base;
|
||||
...
|
||||
};
|
||||
|
||||
const pseudo_B proxy_tinfo_var attribute((assembler_name="tinfo_var")) =
|
||||
{
|
||||
{&B::vtable, "..."},
|
||||
...
|
||||
};
|
||||
|
||||
pseudo_A and pseudo_B must be layout equivalent to the real definitions in
|
||||
the runtime. */
|
||||
/* Finish a type info decl. DECL_PTR is a pointer to an unemitted
|
||||
tinfo decl. Determine whether it needs emitting, and if so
|
||||
generate the initializer. */
|
||||
|
||||
int
|
||||
emit_tinfo_decl (decl_ptr, data)
|
||||
tree *decl_ptr;
|
||||
void *data ATTRIBUTE_UNUSED;
|
||||
{
|
||||
tree tinfo_decl = *decl_ptr;
|
||||
tree tinfo_type, decl;
|
||||
tree decl = *decl_ptr;
|
||||
tree type = TREE_TYPE (DECL_NAME (decl));
|
||||
int non_public;
|
||||
int in_library = typeinfo_in_lib_p (type);
|
||||
tree var_desc, var_init;
|
||||
|
||||
my_friendly_assert (TREE_TYPE (tinfo_decl) == tinfo_decl_type, 20000121);
|
||||
tinfo_type = TREE_TYPE (DECL_NAME (tinfo_decl));
|
||||
my_friendly_assert (tinfo_type != NULL_TREE, 20000120);
|
||||
|
||||
if (!DECL_NEEDED_P (tinfo_decl))
|
||||
import_export_tinfo (decl, type, in_library);
|
||||
if (DECL_REALLY_EXTERN (decl) || !DECL_NEEDED_P (decl))
|
||||
return 0;
|
||||
|
||||
if (!doing_runtime && in_library)
|
||||
return 0;
|
||||
|
||||
non_public = 0;
|
||||
var_desc = get_pseudo_ti_desc (type);
|
||||
var_init = get_pseudo_ti_init (type, var_desc, &non_public);
|
||||
|
||||
DECL_EXTERNAL (decl) = 0;
|
||||
TREE_PUBLIC (decl) = !non_public;
|
||||
if (non_public)
|
||||
DECL_COMDAT (decl) = 0;
|
||||
|
||||
DECL_INITIAL (decl) = var_init;
|
||||
cp_finish_decl (decl, var_init, NULL_TREE, 0);
|
||||
/* cp_finish_decl will have dealt with linkage. */
|
||||
|
||||
/* Say we've dealt with it. */
|
||||
TREE_TYPE (DECL_NAME (tinfo_decl)) = NULL_TREE;
|
||||
|
||||
create_tinfo_types ();
|
||||
decl = synthesize_tinfo_var (tinfo_type, DECL_ASSEMBLER_NAME (tinfo_decl));
|
||||
|
||||
return decl != 0;
|
||||
TREE_TYPE (DECL_NAME (decl)) = NULL_TREE;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,21 @@
|
|||
2002-07-24 Roger Sayle <roger@eyesopen.com>
|
||||
|
||||
* gcc.c-torture/execute/memset-3.c: New testcase.
|
||||
|
||||
2002-06-14 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* g++.dg/abi/layout1.C: New test.
|
||||
* g++.dg/abi/layout2.C: New test.
|
||||
* g++.dg/abi/mangle8.C: New test.
|
||||
|
||||
2002-05-14 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* g++.dg/abi/rtti1.C: New test.
|
||||
|
||||
2002-01-03 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* gcc.dg/gnu89-init-2.c: New test.
|
||||
|
||||
2002-07-25 Release Manager
|
||||
|
||||
* GCC 3.1.1 Released.
|
||||
|
|
|
@ -1,3 +1,112 @@
|
|||
2002-07-26 Phil Edwards <pme@gcc.gnu.org>
|
||||
|
||||
* libsupc++/new (placement delete): Remove unused paramater names.
|
||||
|
||||
2002-07-25 Benjamin Kosnik <bkoz@redhat.com>
|
||||
|
||||
PR libstdc++/7216
|
||||
* include/std/std_istream.h (basic_iostream): Add typedefs for
|
||||
char_type, int_type, pos_type, off_type, and traits_type.
|
||||
* testsuite/27_io/iostream.cc (test01): Add typedef tests.
|
||||
* testsuite/27_io/istream.cc: Same.
|
||||
* testsuite/27_io/ostream.cc: Same.
|
||||
* testsuite/27_io/filebuf.cc: Same.
|
||||
* testsuite/27_io/stringbuf.cc: Replace content, move to...
|
||||
* testsuite/27_io/stringbuf_members.cc: ...here.
|
||||
* testsuite/27_io/streambuf.cc: Replace content, move to...
|
||||
* testsuite/27_io/streambuf_members.cc: ...here.
|
||||
* testsuite/27_io/stringstream.cc: Replace content, move to...
|
||||
* testsuite/27_io/stringstream_members.cc: ...here.
|
||||
* testsuite/27_io/ios.cc: New file.
|
||||
* testsuite/27_io/fstream.cc: New file.
|
||||
* testsuite/27_io/ifstream.cc: New file.
|
||||
* testsuite/27_io/ofstream.cc: New file.
|
||||
* testsuite/27_io/istringstream.cc: New file.
|
||||
* testsuite/27_io/ostringstream.cc: New file.
|
||||
|
||||
2002-07-25 Benjamin Kosnik <bkoz@redhat.com>
|
||||
|
||||
PR libstdc++/7220
|
||||
* include/bits/istream.tcc (istream::ignore): Don't extract on
|
||||
zero.
|
||||
* testsuite/27_io/istream_unformatted.cc (test10): Add.
|
||||
|
||||
2002-07-24 Benjamin Kosnik <bkoz@redhat.com>
|
||||
|
||||
PR libstdc++/7222
|
||||
* src/locale.cc (locale::locale(const char*)): Use setlocale NULL.
|
||||
* testsuite/22_locale/ctor_copy_dtor.cc (test02): New.
|
||||
|
||||
2002-07-24 Benjamin Kosnik <bkoz@redhat.com>
|
||||
|
||||
PR libstdc++/7286
|
||||
* libsupc++/new: Add placement delete.
|
||||
* testsuite/18_support/new_delete_placement.cc: New.
|
||||
|
||||
2002-07-07 Paolo Carlini <pcarlini@unitus.it>
|
||||
|
||||
PR libstdc++/7186
|
||||
* include/bits/stl_deque.h (_Deque_iterator::operator-):
|
||||
Make non-member, as already happens for the comparison
|
||||
operators in accord with DR179 (Ready).
|
||||
* testsuite/23_containers/deque_operators.cc: Add test02.
|
||||
|
||||
2002-07-04 Benjamin Kosnik <bkoz@redhat.com>
|
||||
Jack Reeves <jackw_reeves@hotmail.com>
|
||||
|
||||
* include/std/std_streambuf.h (basic_streambuf::_M_buf): Change to
|
||||
size_t, from int_type.
|
||||
(basic_streambuf::_M_buf_size_opt): Same.
|
||||
(basic_streambuf::_S_pback_sizex): Same.
|
||||
* include/bits/streambuf.tcc: Same.
|
||||
* include/std/std_streambuf.h (basic_streambuf::snextc): Use
|
||||
eq_int_type.
|
||||
(basic_streambuf::uflow): Same.
|
||||
* include/bits/sstream.tcc (basic_stringbuf::overflow): Use
|
||||
to_char_type.
|
||||
* include/bits/basic_ios.tcc (basic_ios::init): Use _CharT().
|
||||
* include/bits/streambuf.tcc (basic_streambuf::xsgetn): Use
|
||||
eq_int_type.
|
||||
(basic_streambuf::xsputn): Same.
|
||||
(__copy_streambufs): Same.
|
||||
|
||||
2002-07-02 Paolo Carlini <pcarlini@unitus.it>
|
||||
|
||||
PR libstdc++/6642
|
||||
* include/bits/stl_iterator.h
|
||||
(__normal_iterator::operator-(const __normal_iterator&)):
|
||||
Make non-member, as already happens for the comparison
|
||||
operators in accord with DR179 (Ready).
|
||||
* testsuite/24_iterators/iterator.cc: Add test from the PR.
|
||||
|
||||
2002-07-02 Benjamin Kosnik <bkoz@redhat.com>
|
||||
|
||||
PR libstdc++/6410
|
||||
* include/bits/locale_facets.h (moneypunct::moneypunct): Add const
|
||||
char* name parameter.
|
||||
* config/locale/gnu/monetary_members.cc: Use it.
|
||||
* config/locale/generic/monetary_members.cc: Same.
|
||||
* src/localename.cc (_Impl::_Impl(const char*, size_t)): Use it.
|
||||
|
||||
2002-07-01 Benjamin Kosnik <bkoz@redhat.com>
|
||||
|
||||
* configure.in (libtool_VERSION): Bump to 5:0:0.
|
||||
* configure: Regenerate.
|
||||
|
||||
2002-05-19 Paolo Carlini <pcarlini@unitus.it>
|
||||
|
||||
* testsuite/23_containers/deque_operators.cc (test01):
|
||||
Fix minor typo in last commit.
|
||||
|
||||
2002-05-18 Paolo Carlini <pcarlini@unitus.it>
|
||||
|
||||
PR libstdc++/6503
|
||||
* include/bits/stl_deque.h (_Deque_iterator::operator==,
|
||||
operator!=, operator<, operator>, operator>=, operator<=):
|
||||
Make non-member functions, to allow comparing const and
|
||||
non-const iterators in any order.
|
||||
* testsuite/23_containers/deque_operators.cc: New testfile.
|
||||
|
||||
2002-07-25 Release Manager
|
||||
|
||||
* GCC 3.1.1 Released.
|
||||
|
|
|
@ -45,7 +45,7 @@ namespace std
|
|||
|
||||
template<>
|
||||
void
|
||||
moneypunct<char, true>::_M_initialize_moneypunct(__c_locale)
|
||||
moneypunct<char, true>::_M_initialize_moneypunct(__c_locale, const char*)
|
||||
{
|
||||
// "C" locale
|
||||
_M_decimal_point = '.';
|
||||
|
@ -61,7 +61,7 @@ namespace std
|
|||
|
||||
template<>
|
||||
void
|
||||
moneypunct<char, false>::_M_initialize_moneypunct(__c_locale)
|
||||
moneypunct<char, false>::_M_initialize_moneypunct(__c_locale, const char*)
|
||||
{
|
||||
// "C" locale
|
||||
_M_decimal_point = '.';
|
||||
|
@ -86,7 +86,8 @@ namespace std
|
|||
#ifdef _GLIBCPP_USE_WCHAR_T
|
||||
template<>
|
||||
void
|
||||
moneypunct<wchar_t, true>::_M_initialize_moneypunct(__c_locale)
|
||||
moneypunct<wchar_t, true>::_M_initialize_moneypunct(__c_locale,
|
||||
const char*)
|
||||
{
|
||||
// "C" locale
|
||||
_M_decimal_point = L'.';
|
||||
|
@ -102,7 +103,8 @@ namespace std
|
|||
|
||||
template<>
|
||||
void
|
||||
moneypunct<wchar_t, false>::_M_initialize_moneypunct(__c_locale)
|
||||
moneypunct<wchar_t, false>::_M_initialize_moneypunct(__c_locale,
|
||||
const char*)
|
||||
{
|
||||
// "C" locale
|
||||
_M_decimal_point = L'.';
|
||||
|
|
|
@ -216,7 +216,8 @@ namespace std
|
|||
|
||||
template<>
|
||||
void
|
||||
moneypunct<char, true>::_M_initialize_moneypunct(__c_locale __cloc)
|
||||
moneypunct<char, true>::_M_initialize_moneypunct(__c_locale __cloc,
|
||||
const char*)
|
||||
{
|
||||
if (__cloc == _S_c_locale)
|
||||
{
|
||||
|
@ -260,7 +261,8 @@ namespace std
|
|||
|
||||
template<>
|
||||
void
|
||||
moneypunct<char, false>::_M_initialize_moneypunct(__c_locale __cloc)
|
||||
moneypunct<char, false>::_M_initialize_moneypunct(__c_locale __cloc,
|
||||
const char*)
|
||||
{
|
||||
if (__cloc == _S_c_locale)
|
||||
{
|
||||
|
@ -313,7 +315,8 @@ namespace std
|
|||
#ifdef _GLIBCPP_USE_WCHAR_T
|
||||
template<>
|
||||
void
|
||||
moneypunct<wchar_t, true>::_M_initialize_moneypunct(__c_locale __cloc)
|
||||
moneypunct<wchar_t, true>::_M_initialize_moneypunct(__c_locale __cloc,
|
||||
const char* __name)
|
||||
{
|
||||
if (__cloc == _S_c_locale)
|
||||
{
|
||||
|
@ -331,6 +334,10 @@ namespace std
|
|||
else
|
||||
{
|
||||
// Named locale.
|
||||
// XXX Fix me. Switch to named locale so that mbsrtowcs will work.
|
||||
char* __old = strdup(setlocale(LC_ALL, NULL));
|
||||
setlocale(LC_ALL, __name);
|
||||
|
||||
_M_decimal_point = static_cast<wchar_t>(((union { const char *__s; unsigned int __w; }){ __s: __nl_langinfo_l(_NL_NUMERIC_DECIMAL_POINT_WC, __cloc)}).__w);
|
||||
|
||||
_M_thousands_sep = static_cast<wchar_t>(((union { const char *__s; unsigned int __w; }){ __s: __nl_langinfo_l(_NL_NUMERIC_THOUSANDS_SEP_WC, __cloc)}).__w);
|
||||
|
@ -391,12 +398,17 @@ namespace std
|
|||
char __nprecedes = *(__nl_langinfo_l(__INT_N_CS_PRECEDES, __cloc));
|
||||
char __nspace = *(__nl_langinfo_l(__INT_N_SEP_BY_SPACE, __cloc));
|
||||
_M_neg_format = _S_construct_pattern(__nprecedes, __nspace, __nposn);
|
||||
|
||||
// XXX
|
||||
setlocale(LC_ALL, __old);
|
||||
free(__old);
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
void
|
||||
moneypunct<wchar_t, false>::_M_initialize_moneypunct(__c_locale __cloc)
|
||||
moneypunct<wchar_t, false>::_M_initialize_moneypunct(__c_locale __cloc,
|
||||
const char* __name)
|
||||
{
|
||||
if (__cloc == _S_c_locale)
|
||||
{
|
||||
|
@ -414,6 +426,10 @@ namespace std
|
|||
else
|
||||
{
|
||||
// Named locale.
|
||||
// XXX Fix me. Switch to named locale so that mbsrtowcs will work.
|
||||
char* __old = strdup(setlocale(LC_ALL, NULL));
|
||||
setlocale(LC_ALL, __name);
|
||||
|
||||
_M_decimal_point = static_cast<wchar_t>(((union { const char *__s; unsigned int __w; }){ __s: __nl_langinfo_l(_NL_NUMERIC_DECIMAL_POINT_WC, __cloc)}).__w);
|
||||
_M_thousands_sep = static_cast<wchar_t>(((union { const char *__s; unsigned int __w; }){ __s: __nl_langinfo_l(_NL_NUMERIC_THOUSANDS_SEP_WC, __cloc)}).__w);
|
||||
_M_grouping = __nl_langinfo_l(GROUPING, __cloc);
|
||||
|
@ -473,6 +489,10 @@ namespace std
|
|||
char __nprecedes = *(__nl_langinfo_l(__N_CS_PRECEDES, __cloc));
|
||||
char __nspace = *(__nl_langinfo_l(__N_SEP_BY_SPACE, __cloc));
|
||||
_M_neg_format = _S_construct_pattern(__nprecedes, __nspace, __nposn);
|
||||
|
||||
// XXX
|
||||
setlocale(LC_ALL, __old);
|
||||
free(__old);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -599,7 +599,7 @@ ORIGINAL_LD_FOR_MULTILIBS=$LD
|
|||
PACKAGE=libstdc++
|
||||
|
||||
# For libtool versioning info, format is CURRENT:REVISION:AGE
|
||||
libtool_VERSION=4:1:0
|
||||
libtool_VERSION=5:0:0
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ ORIGINAL_LD_FOR_MULTILIBS=$LD
|
|||
PACKAGE=libstdc++
|
||||
AC_SUBST(PACKAGE)
|
||||
# For libtool versioning info, format is CURRENT:REVISION:AGE
|
||||
libtool_VERSION=4:1:0
|
||||
libtool_VERSION=5:0:0
|
||||
AC_SUBST(libtool_VERSION)
|
||||
|
||||
GLIBCPP_TOPREL_CONFIGURE
|
||||
|
|
|
@ -156,7 +156,7 @@ namespace std
|
|||
// unformatted input and output with non-required basic_ios
|
||||
// instantiations is possible even without imbuing the expected
|
||||
// ctype<char_type> facet.
|
||||
_M_fill = 0;
|
||||
_M_fill = _CharT();
|
||||
_M_fill_init = false;
|
||||
|
||||
_M_exception = goodbit;
|
||||
|
|
|
@ -708,7 +708,7 @@ namespace std
|
|||
{
|
||||
_M_gcount = 0;
|
||||
sentry __cerb(*this, true);
|
||||
if (__cerb)
|
||||
if (__cerb && __n > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
|
@ -1357,8 +1357,9 @@ namespace std
|
|||
{ _M_initialize_moneypunct(); }
|
||||
|
||||
explicit
|
||||
moneypunct(__c_locale __cloc, size_t __refs = 0) : locale::facet(__refs)
|
||||
{ _M_initialize_moneypunct(__cloc); }
|
||||
moneypunct(__c_locale __cloc, const char* __s, size_t __refs = 0)
|
||||
: locale::facet(__refs)
|
||||
{ _M_initialize_moneypunct(__cloc, __s); }
|
||||
|
||||
char_type
|
||||
decimal_point() const
|
||||
|
@ -1438,7 +1439,8 @@ namespace std
|
|||
|
||||
// For use at construction time only.
|
||||
void
|
||||
_M_initialize_moneypunct(__c_locale __cloc = _S_c_locale);
|
||||
_M_initialize_moneypunct(__c_locale __cloc = _S_c_locale,
|
||||
const char* __name = NULL);
|
||||
};
|
||||
|
||||
template<typename _CharT, bool _Intl>
|
||||
|
@ -1455,11 +1457,11 @@ namespace std
|
|||
|
||||
template<>
|
||||
void
|
||||
moneypunct<char, true>::_M_initialize_moneypunct(__c_locale __cloc);
|
||||
moneypunct<char, true>::_M_initialize_moneypunct(__c_locale, const char*);
|
||||
|
||||
template<>
|
||||
void
|
||||
moneypunct<char, false>::_M_initialize_moneypunct(__c_locale __cloc);
|
||||
moneypunct<char, false>::_M_initialize_moneypunct(__c_locale, const char*);
|
||||
|
||||
#ifdef _GLIBCPP_USE_WCHAR_T
|
||||
template<>
|
||||
|
@ -1470,11 +1472,13 @@ namespace std
|
|||
|
||||
template<>
|
||||
void
|
||||
moneypunct<wchar_t, true>::_M_initialize_moneypunct(__c_locale __cloc);
|
||||
moneypunct<wchar_t, true>::_M_initialize_moneypunct(__c_locale,
|
||||
const char*);
|
||||
|
||||
template<>
|
||||
void
|
||||
moneypunct<wchar_t, false>::_M_initialize_moneypunct(__c_locale __cloc);
|
||||
moneypunct<wchar_t, false>::_M_initialize_moneypunct(__c_locale,
|
||||
const char*);
|
||||
#endif
|
||||
|
||||
template<typename _CharT, bool _Intl>
|
||||
|
|
|
@ -95,13 +95,13 @@ namespace std
|
|||
__len *= 2;
|
||||
|
||||
if (__testwrite)
|
||||
__ret = this->sputc(__c);
|
||||
__ret = this->sputc(traits_type::to_char_type(__c));
|
||||
else if (__len <= _M_string.max_size())
|
||||
{
|
||||
// Force-allocate, re-sync.
|
||||
_M_string = this->str();
|
||||
_M_string.reserve(__len);
|
||||
_M_buf_size = static_cast<int_type>(__len);
|
||||
_M_buf_size = __len;
|
||||
_M_really_sync(_M_in_cur - _M_in_beg,
|
||||
_M_out_cur - _M_out_beg);
|
||||
*_M_out_cur = traits_type::to_char_type(__c);
|
||||
|
|
|
@ -130,11 +130,6 @@ struct _Deque_iterator
|
|||
reference operator*() const { return *_M_cur; }
|
||||
pointer operator->() const { return _M_cur; }
|
||||
|
||||
difference_type operator-(const _Self& __x) const {
|
||||
return difference_type(_S_buffer_size()) * (_M_node - __x._M_node - 1) +
|
||||
(_M_cur - _M_first) + (__x._M_last - __x._M_cur);
|
||||
}
|
||||
|
||||
_Self& operator++() {
|
||||
++_M_cur;
|
||||
if (_M_cur == _M_last) {
|
||||
|
@ -194,16 +189,6 @@ struct _Deque_iterator
|
|||
|
||||
reference operator[](difference_type __n) const { return *(*this + __n); }
|
||||
|
||||
bool operator==(const _Self& __x) const { return _M_cur == __x._M_cur; }
|
||||
bool operator!=(const _Self& __x) const { return !(*this == __x); }
|
||||
bool operator<(const _Self& __x) const {
|
||||
return (_M_node == __x._M_node) ?
|
||||
(_M_cur < __x._M_cur) : (_M_node < __x._M_node);
|
||||
}
|
||||
bool operator>(const _Self& __x) const { return __x < *this; }
|
||||
bool operator<=(const _Self& __x) const { return !(__x < *this); }
|
||||
bool operator>=(const _Self& __x) const { return !(*this < __x); }
|
||||
|
||||
/** @if maint
|
||||
* Prepares to traverse new_node. Sets everything except _M_cur, which
|
||||
* should therefore be set by the caller immediately afterwards, based on
|
||||
|
@ -217,6 +202,123 @@ struct _Deque_iterator
|
|||
}
|
||||
};
|
||||
|
||||
// Note: we also provide overloads whose operands are of the same type in
|
||||
// order to avoid ambiguos overload resolution when std::rel_ops operators
|
||||
// are in scope (for additional details, see libstdc++/3628)
|
||||
template <class _Tp, class _Ref, class _Ptr>
|
||||
inline bool
|
||||
operator==(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
|
||||
const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
|
||||
{
|
||||
return __x._M_cur == __y._M_cur;
|
||||
}
|
||||
|
||||
template <class _Tp, class _RefL, class _PtrL, class _RefR, class _PtrR>
|
||||
inline bool
|
||||
operator==(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
|
||||
const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
|
||||
{
|
||||
return __x._M_cur == __y._M_cur;
|
||||
}
|
||||
|
||||
template <class _Tp, class _Ref, class _Ptr>
|
||||
inline bool
|
||||
operator!=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
|
||||
const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
|
||||
{
|
||||
return !(__x == __y);
|
||||
}
|
||||
|
||||
template <class _Tp, class _RefL, class _PtrL, class _RefR, class _PtrR>
|
||||
inline bool
|
||||
operator!=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
|
||||
const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
|
||||
{
|
||||
return !(__x == __y);
|
||||
}
|
||||
|
||||
template <class _Tp, class _Ref, class _Ptr>
|
||||
inline bool
|
||||
operator<(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
|
||||
const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
|
||||
{
|
||||
return (__x._M_node == __y._M_node) ?
|
||||
(__x._M_cur < __y._M_cur) : (__x._M_node < __y._M_node);
|
||||
}
|
||||
|
||||
template <class _Tp, class _RefL, class _PtrL, class _RefR, class _PtrR>
|
||||
inline bool
|
||||
operator<(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
|
||||
const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
|
||||
{
|
||||
return (__x._M_node == __y._M_node) ?
|
||||
(__x._M_cur < __y._M_cur) : (__x._M_node < __y._M_node);
|
||||
}
|
||||
|
||||
template <class _Tp, class _Ref, class _Ptr>
|
||||
inline bool
|
||||
operator>(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
|
||||
const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
|
||||
{
|
||||
return __y < __x;
|
||||
}
|
||||
|
||||
template <class _Tp, class _RefL, class _PtrL, class _RefR, class _PtrR>
|
||||
inline bool
|
||||
operator>(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
|
||||
const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
|
||||
{
|
||||
return __y < __x;
|
||||
}
|
||||
|
||||
template <class _Tp, class _Ref, class _Ptr>
|
||||
inline bool
|
||||
operator<=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
|
||||
const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
|
||||
{
|
||||
return !(__y < __x);
|
||||
}
|
||||
|
||||
template <class _Tp, class _RefL, class _PtrL, class _RefR, class _PtrR>
|
||||
inline bool
|
||||
operator<=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
|
||||
const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
|
||||
{
|
||||
return !(__y < __x);
|
||||
}
|
||||
|
||||
template <class _Tp, class _Ref, class _Ptr>
|
||||
inline bool
|
||||
operator>=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
|
||||
const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
|
||||
{
|
||||
return !(__x < __y);
|
||||
}
|
||||
|
||||
template <class _Tp, class _RefL, class _PtrL, class _RefR, class _PtrR>
|
||||
inline bool
|
||||
operator>=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
|
||||
const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
|
||||
{
|
||||
return !(__x < __y);
|
||||
}
|
||||
|
||||
// _GLIBCPP_RESOLVE_LIB_DEFECTS
|
||||
// According to the resolution of DR179 not only the various comparison
|
||||
// operators but also operator- must accept mixed iterator/const_iterator
|
||||
// parameters.
|
||||
template <typename _Tp, typename _RefL, typename _PtrL,
|
||||
typename _RefR, typename _PtrR>
|
||||
inline typename _Deque_iterator<_Tp, _RefL, _PtrL>::difference_type
|
||||
operator-(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
|
||||
const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
|
||||
{
|
||||
return _Deque_iterator<_Tp, _RefL, _PtrL>::difference_type
|
||||
(_Deque_iterator<_Tp, _RefL, _PtrL>::_S_buffer_size()) *
|
||||
(__x._M_node - __y._M_node - 1) + (__x._M_cur - __x._M_first) +
|
||||
(__y._M_last - __y._M_cur);
|
||||
}
|
||||
|
||||
template <class _Tp, class _Ref, class _Ptr>
|
||||
inline _Deque_iterator<_Tp, _Ref, _Ptr>
|
||||
operator+(ptrdiff_t __n, const _Deque_iterator<_Tp, _Ref, _Ptr>& __x)
|
||||
|
|
|
@ -629,10 +629,6 @@ namespace __gnu_cxx
|
|||
operator-(const difference_type& __n) const
|
||||
{ return __normal_iterator(_M_current - __n); }
|
||||
|
||||
difference_type
|
||||
operator-(const __normal_iterator& __i) const
|
||||
{ return _M_current - __i._M_current; }
|
||||
|
||||
const _Iterator&
|
||||
base() const { return _M_current; }
|
||||
};
|
||||
|
@ -719,6 +715,16 @@ namespace __gnu_cxx
|
|||
const __normal_iterator<_Iterator, _Container>& __rhs)
|
||||
{ return __lhs.base() >= __rhs.base(); }
|
||||
|
||||
// _GLIBCPP_RESOLVE_LIB_DEFECTS
|
||||
// According to the resolution of DR179 not only the various comparison
|
||||
// operators but also operator- must accept mixed iterator/const_iterator
|
||||
// parameters.
|
||||
template<typename _IteratorL, typename _IteratorR, typename _Container>
|
||||
inline typename __normal_iterator<_IteratorL, _Container>::difference_type
|
||||
operator-(const __normal_iterator<_IteratorL, _Container>& __lhs,
|
||||
const __normal_iterator<_IteratorR, _Container>& __rhs)
|
||||
{ return __lhs.base() - __rhs.base(); }
|
||||
|
||||
template<typename _Iterator, typename _Container>
|
||||
inline __normal_iterator<_Iterator, _Container>
|
||||
operator+(typename __normal_iterator<_Iterator, _Container>::difference_type __n,
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
namespace std
|
||||
{
|
||||
template<typename _CharT, typename _Traits>
|
||||
const typename basic_streambuf<_CharT, _Traits>::int_type
|
||||
const size_t
|
||||
basic_streambuf<_CharT, _Traits>::_S_pback_size;
|
||||
|
||||
template<typename _CharT, typename _Traits>
|
||||
|
@ -138,7 +138,7 @@ namespace std
|
|||
if (__ret < __n)
|
||||
{
|
||||
int_type __c = this->uflow();
|
||||
if (__c != traits_type::eof())
|
||||
if (!traits_type::eq_int_type(__c, traits_type::eof()))
|
||||
{
|
||||
traits_type::assign(*__s++, traits_type::to_char_type(__c));
|
||||
++__ret;
|
||||
|
@ -177,7 +177,7 @@ namespace std
|
|||
if (__ret < __n)
|
||||
{
|
||||
int_type __c = this->overflow(traits_type::to_int_type(*__s));
|
||||
if (__c != traits_type::eof())
|
||||
if (!traits_type::eq_int_type(__c, traits_type::eof()))
|
||||
{
|
||||
++__ret;
|
||||
++__s;
|
||||
|
@ -214,7 +214,7 @@ namespace std
|
|||
__sbin->_M_in_cur_move(__xtrct);
|
||||
if (__xtrct == __bufsize)
|
||||
{
|
||||
if (__sbin->sgetc() == _Traits::eof())
|
||||
if (_Traits::eq_int_type(__sbin->sgetc(), _Traits::eof()))
|
||||
break;
|
||||
__bufsize = __sbin->in_avail();
|
||||
}
|
||||
|
|
|
@ -261,6 +261,16 @@ namespace std
|
|||
public basic_ostream<_CharT, _Traits>
|
||||
{
|
||||
public:
|
||||
#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
|
||||
// 271. basic_iostream missing typedefs
|
||||
// Types (inherited):
|
||||
typedef _CharT char_type;
|
||||
typedef typename _Traits::int_type int_type;
|
||||
typedef typename _Traits::pos_type pos_type;
|
||||
typedef typename _Traits::off_type off_type;
|
||||
typedef _Traits traits_type;
|
||||
#endif
|
||||
|
||||
// Non-standard Types:
|
||||
typedef basic_istream<_CharT, _Traits> __istream_type;
|
||||
typedef basic_ostream<_CharT, _Traits> __ostream_type;
|
||||
|
|
|
@ -91,10 +91,10 @@ namespace std
|
|||
char_type* _M_buf;
|
||||
|
||||
// Actual size of allocated internal buffer, in bytes.
|
||||
int_type _M_buf_size;
|
||||
size_t _M_buf_size;
|
||||
|
||||
// Optimal or preferred size of internal buffer, in bytes.
|
||||
int_type _M_buf_size_opt;
|
||||
size_t _M_buf_size_opt;
|
||||
|
||||
// True iff _M_in_* and _M_out_* buffers should always point to
|
||||
// the same place. True for fstreams, false for sstreams.
|
||||
|
@ -126,7 +126,7 @@ namespace std
|
|||
// requirements. The only basic_streambuf member function that
|
||||
// needs access to these data members is in_avail...
|
||||
// NB: pbacks of over one character are not currently supported.
|
||||
static const int_type _S_pback_size = 1;
|
||||
static const size_t _S_pback_size = 1;
|
||||
char_type _M_pback[_S_pback_size];
|
||||
char_type* _M_pback_cur_save;
|
||||
char_type* _M_pback_end_save;
|
||||
|
@ -140,8 +140,8 @@ namespace std
|
|||
{
|
||||
if (!_M_pback_init)
|
||||
{
|
||||
int_type __dist = _M_in_end - _M_in_cur;
|
||||
int_type __len = min(_S_pback_size, __dist);
|
||||
size_t __dist = _M_in_end - _M_in_cur;
|
||||
size_t __len = min(_S_pback_size, __dist);
|
||||
traits_type::copy(_M_pback, _M_in_cur, __len);
|
||||
_M_pback_cur_save = _M_in_cur;
|
||||
_M_pback_end_save = _M_in_end;
|
||||
|
@ -159,12 +159,12 @@ namespace std
|
|||
if (_M_pback_init)
|
||||
{
|
||||
// Length _M_in_cur moved in the pback buffer.
|
||||
int_type __off_cur = _M_in_cur - _M_pback;
|
||||
size_t __off_cur = _M_in_cur - _M_pback;
|
||||
|
||||
// For in | out buffers, the end can be pushed back...
|
||||
int_type __off_end = 0;
|
||||
int_type __pback_len = _M_in_end - _M_pback;
|
||||
int_type __save_len = _M_pback_end_save - _M_buf;
|
||||
size_t __off_end = 0;
|
||||
size_t __pback_len = _M_in_end - _M_pback;
|
||||
size_t __save_len = _M_pback_end_save - _M_buf;
|
||||
if (__pback_len > __save_len)
|
||||
__off_end = __pback_len - __save_len;
|
||||
|
||||
|
@ -288,8 +288,8 @@ namespace std
|
|||
{
|
||||
if (_M_pback_init)
|
||||
{
|
||||
int_type __save_len = _M_pback_end_save - _M_pback_cur_save;
|
||||
int_type __pback_len = _M_in_cur - _M_pback;
|
||||
size_t __save_len = _M_pback_end_save - _M_pback_cur_save;
|
||||
size_t __pback_len = _M_in_cur - _M_pback;
|
||||
__ret = __save_len - __pback_len;
|
||||
}
|
||||
else
|
||||
|
@ -304,7 +304,8 @@ namespace std
|
|||
snextc()
|
||||
{
|
||||
int_type __eof = traits_type::eof();
|
||||
return (this->sbumpc() == __eof ? __eof : this->sgetc());
|
||||
return (traits_type::eq_int_type(this->sbumpc(), __eof)
|
||||
? __eof : this->sgetc());
|
||||
}
|
||||
|
||||
int_type
|
||||
|
@ -342,10 +343,10 @@ namespace std
|
|||
|
||||
protected:
|
||||
basic_streambuf()
|
||||
: _M_buf(NULL), _M_buf_size(0),
|
||||
_M_buf_size_opt(static_cast<int_type>(BUFSIZ)), _M_buf_unified(false),
|
||||
_M_in_beg(0), _M_in_cur(0), _M_in_end(0), _M_out_beg(0), _M_out_cur(0),
|
||||
_M_out_end(0), _M_mode(ios_base::openmode(0)), _M_buf_locale(locale()),
|
||||
: _M_buf(NULL), _M_buf_size(0), _M_buf_size_opt(BUFSIZ),
|
||||
_M_buf_unified(false), _M_in_beg(0), _M_in_cur(0), _M_in_end(0),
|
||||
_M_out_beg(0), _M_out_cur(0), _M_out_end(0),
|
||||
_M_mode(ios_base::openmode(0)), _M_buf_locale(locale()),
|
||||
_M_buf_locale_init(false), _M_pback_cur_save(0), _M_pback_end_save(0),
|
||||
_M_pback_init(false)
|
||||
{ }
|
||||
|
@ -438,7 +439,7 @@ namespace std
|
|||
uflow()
|
||||
{
|
||||
int_type __ret = traits_type::eof();
|
||||
bool __testeof = this->underflow() == __ret;
|
||||
bool __testeof = traits_type::eq_int_type(this->underflow(), __ret);
|
||||
bool __testpending = _M_in_cur && _M_in_cur < _M_in_end;
|
||||
if (!__testeof && __testpending)
|
||||
{
|
||||
|
|
|
@ -88,6 +88,10 @@ void operator delete[](void*, const std::nothrow_t&) throw();
|
|||
// Default placement versions of operator new.
|
||||
inline void* operator new(std::size_t, void* __p) throw() { return __p; }
|
||||
inline void* operator new[](std::size_t, void* __p) throw() { return __p; }
|
||||
|
||||
// Default placement versions of operator delete.
|
||||
inline void operator delete (void*, void*) throw() { };
|
||||
inline void operator delete[](void*, void*) throw() { };
|
||||
//@}
|
||||
} // extern "C++"
|
||||
|
||||
|
|
|
@ -202,7 +202,7 @@ namespace std
|
|||
if (strcmp(__s, "C") == 0 || strcmp(__s, "POSIX") == 0)
|
||||
(_M_impl = _S_classic)->_M_add_reference();
|
||||
else if (strcmp(__s, "") == 0)
|
||||
_M_impl = new _Impl(setlocale(LC_ALL, __s), 1);
|
||||
_M_impl = new _Impl(setlocale(LC_ALL, NULL), 1);
|
||||
else
|
||||
_M_impl = new _Impl(__s, 1);
|
||||
}
|
||||
|
|
|
@ -132,8 +132,8 @@ namespace std
|
|||
_M_init_facet(new num_get<char>);
|
||||
_M_init_facet(new num_put<char>);
|
||||
_M_init_facet(new std::collate<char>(__cloc));
|
||||
_M_init_facet(new moneypunct<char, false>(__cloc));
|
||||
_M_init_facet(new moneypunct<char, true>(__cloc));
|
||||
_M_init_facet(new moneypunct<char, false>(__cloc, __s));
|
||||
_M_init_facet(new moneypunct<char, true>(__cloc, __s));
|
||||
_M_init_facet(new money_get<char>);
|
||||
_M_init_facet(new money_put<char>);
|
||||
_M_init_facet(new __timepunct<char>(__cloc, __s));
|
||||
|
@ -148,8 +148,8 @@ namespace std
|
|||
_M_init_facet(new num_get<wchar_t>);
|
||||
_M_init_facet(new num_put<wchar_t>);
|
||||
_M_init_facet(new std::collate<wchar_t>(__cloc));
|
||||
_M_init_facet(new moneypunct<wchar_t, false>(__cloc));
|
||||
_M_init_facet(new moneypunct<wchar_t, true>(__cloc));
|
||||
_M_init_facet(new moneypunct<wchar_t, false>(__cloc, __s));
|
||||
_M_init_facet(new moneypunct<wchar_t, true>(__cloc, __s));
|
||||
_M_init_facet(new money_get<wchar_t>);
|
||||
_M_init_facet(new money_put<wchar_t>);
|
||||
_M_init_facet(new __timepunct<wchar_t>(__cloc, __s));
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
#include <stdexcept>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
|
||||
void test00()
|
||||
{
|
||||
// Should be able to do this as the first thing that happens in a
|
||||
|
@ -238,7 +237,21 @@ void test01()
|
|||
}
|
||||
#endif // _GLIBCPP_USE___ENC_TRAITS
|
||||
|
||||
int main ()
|
||||
// libstdc++/7222
|
||||
void test02()
|
||||
{
|
||||
bool test = true;
|
||||
std::locale loc_c1("C");
|
||||
std::locale loc_c2 ("C");
|
||||
|
||||
std::locale loc_1("");
|
||||
std::locale loc_2("");
|
||||
|
||||
VERIFY( loc_c1 == loc_c2 );
|
||||
VERIFY( loc_1 == loc_2 );
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test00();
|
||||
|
||||
|
@ -246,5 +259,7 @@ int main ()
|
|||
test01();
|
||||
#endif
|
||||
|
||||
test02();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -577,6 +577,17 @@ wrong_stuff()
|
|||
return failures;
|
||||
}
|
||||
|
||||
// libstdc++/6642
|
||||
int
|
||||
test6642()
|
||||
{
|
||||
std::string s;
|
||||
std::string::iterator it = s.begin();
|
||||
std::string::const_iterator cit = s.begin();
|
||||
|
||||
return it - cit;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
|
@ -590,6 +601,8 @@ main(int argc, char **argv)
|
|||
|
||||
failures += wrong_stuff();
|
||||
|
||||
failures += test6642();
|
||||
|
||||
#ifdef DEBUG_ASSERT
|
||||
assert (failures == 0);
|
||||
#endif
|
||||
|
|
|
@ -19,15 +19,26 @@
|
|||
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
// USA.
|
||||
|
||||
// NB: this test assumes that _M_buf_size == 40, and not the usual
|
||||
// buffer_size length of BUFSIZ (8192), so that overflow/underflow can be
|
||||
// simulated a bit more readily.
|
||||
// 27.8.1.1 - Template class basic_filebuf
|
||||
// NB: This file is for testing basic_filebuf with NO OTHER INCLUDES.
|
||||
|
||||
#include <fstream>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
// { dg-do compile }
|
||||
|
||||
// libstdc++/7216
|
||||
void test01()
|
||||
{
|
||||
// Check for required typedefs
|
||||
typedef std::filebuf test_type;
|
||||
typedef test_type::char_type char_type;
|
||||
typedef test_type::traits_type traits_type;
|
||||
typedef test_type::int_type int_type;
|
||||
typedef test_type::pos_type pos_type;
|
||||
typedef test_type::off_type off_type;
|
||||
}
|
||||
|
||||
// test05
|
||||
// libstdc++/1886
|
||||
// should be able to instantiate basic_filebuf for non-standard types.
|
||||
|
@ -35,6 +46,7 @@ template class std::basic_filebuf<short, std::char_traits<short> >;
|
|||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -34,6 +34,18 @@
|
|||
|
||||
#include <istream>
|
||||
|
||||
// libstdc++/7216
|
||||
void test01()
|
||||
{
|
||||
// Check for required typedefs
|
||||
typedef std::iostream test_type;
|
||||
typedef test_type::char_type char_type;
|
||||
typedef test_type::traits_type traits_type;
|
||||
typedef test_type::int_type int_type;
|
||||
typedef test_type::pos_type pos_type;
|
||||
typedef test_type::off_type off_type;
|
||||
}
|
||||
|
||||
namespace test
|
||||
{
|
||||
using namespace std;
|
||||
|
@ -43,5 +55,6 @@ namespace test
|
|||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -34,6 +34,18 @@
|
|||
|
||||
// { dg-do compile }
|
||||
|
||||
// libstdc++/7216
|
||||
void test01()
|
||||
{
|
||||
// Check for required typedefs
|
||||
typedef std::istream test_type;
|
||||
typedef test_type::char_type char_type;
|
||||
typedef test_type::traits_type traits_type;
|
||||
typedef test_type::int_type int_type;
|
||||
typedef test_type::pos_type pos_type;
|
||||
typedef test_type::off_type off_type;
|
||||
}
|
||||
|
||||
namespace test
|
||||
{
|
||||
using namespace std;
|
||||
|
@ -43,5 +55,6 @@ namespace test
|
|||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -514,6 +514,43 @@ test09()
|
|||
VERIFY( test );
|
||||
}
|
||||
|
||||
// libstdc++/70220
|
||||
void
|
||||
test10()
|
||||
{
|
||||
using namespace std;
|
||||
bool test = true;
|
||||
typedef string string_type;
|
||||
typedef stringbuf stringbuf_type;
|
||||
typedef istream istream_type;
|
||||
|
||||
int res = 0;
|
||||
streamsize n;
|
||||
string_type input("abcdefg\n");
|
||||
stringbuf_type sbuf(input);
|
||||
istream_type istr(&sbuf);
|
||||
|
||||
istr.ignore(0);
|
||||
if (istr.gcount() != 0)
|
||||
test = false;
|
||||
VERIFY( test );
|
||||
|
||||
istr.ignore(0, 'b');
|
||||
if (istr.gcount() != 0)
|
||||
test = false;
|
||||
VERIFY( test );
|
||||
|
||||
istr.ignore(); // Advance to next position.
|
||||
istr.ignore(0, 'b');
|
||||
if ((n=istr.gcount()) != 0)
|
||||
test = false;
|
||||
VERIFY( test );
|
||||
|
||||
if (istr.peek() != 'b')
|
||||
test = false;
|
||||
VERIFY( test );
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
|
@ -526,6 +563,7 @@ main()
|
|||
test07();
|
||||
test08();
|
||||
test09();
|
||||
test10();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -34,6 +34,18 @@
|
|||
|
||||
// { dg-do compile }
|
||||
|
||||
// libstdc++/7216
|
||||
void test01()
|
||||
{
|
||||
// Check for required typedefs
|
||||
typedef std::ostream test_type;
|
||||
typedef test_type::char_type char_type;
|
||||
typedef test_type::traits_type traits_type;
|
||||
typedef test_type::int_type int_type;
|
||||
typedef test_type::pos_type pos_type;
|
||||
typedef test_type::off_type off_type;
|
||||
}
|
||||
|
||||
namespace test
|
||||
{
|
||||
using namespace std;
|
||||
|
@ -43,5 +55,6 @@ namespace test
|
|||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// 2001-05-23 Benjamin Kosnik <bkoz@redhat.com>
|
||||
|
||||
// Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
// Copyright (C) 2001, 2002 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
|
||||
|
@ -97,9 +97,61 @@ void test02()
|
|||
// These semantics are a joke, a serious defect, and incredibly lame.
|
||||
}
|
||||
|
||||
// 03: sanity checks for strings, stringbufs
|
||||
void
|
||||
test03()
|
||||
{
|
||||
bool test = false;
|
||||
|
||||
// Empty string sanity check.
|
||||
std::string str01;
|
||||
std::string::iterator __i_start = str01.begin();
|
||||
std::string::iterator __i_end = str01.end();
|
||||
std::string::size_type len = str01.size();
|
||||
test = __i_start == __i_end;
|
||||
VERIFY( len == 0 );
|
||||
|
||||
// Full string sanity check.
|
||||
std::string str02("these golden days, i spend waiting for you:\n"
|
||||
"Betty Carter on Verve with I'm Yours and You're Mine.");
|
||||
__i_start = str02.begin();
|
||||
__i_end = str02.end();
|
||||
len = str02.size();
|
||||
VERIFY( __i_start != __i_end );
|
||||
VERIFY( len != 0 );
|
||||
|
||||
// Test an empty ostringstream for sanity.
|
||||
std::ostringstream ostrstream0;
|
||||
std::string str03 = ostrstream0.str();
|
||||
__i_start = str03.begin();
|
||||
__i_end = str03.end();
|
||||
len = str03.size();
|
||||
VERIFY( __i_start == __i_end );
|
||||
VERIFY( len == 0 );
|
||||
VERIFY( str01 == str03 );
|
||||
}
|
||||
|
||||
// user-reported error
|
||||
class derived_oss: public std::ostringstream
|
||||
{
|
||||
public:
|
||||
derived_oss() : std::ostringstream() { }
|
||||
};
|
||||
|
||||
void
|
||||
test04()
|
||||
{
|
||||
bool test = true;
|
||||
derived_oss yy;
|
||||
yy << "buena vista social club\n";
|
||||
VERIFY( yy.str() == std::string("buena vista social club\n") );
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
test02();
|
||||
test03();
|
||||
test04();
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// 1999-10-11 bkoz
|
||||
// 2002-07-25 Benjamin Kosnik <bkoz@redhat.com>
|
||||
|
||||
// Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
// Copyright (C) 2002 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
|
||||
|
@ -27,352 +27,34 @@
|
|||
// invalidate any other reasons why the executable file might be covered by
|
||||
// the GNU General Public License.
|
||||
|
||||
// 27.5.2 template class basic_streambuf
|
||||
// 27.5.2 - Template class basic_streambuf
|
||||
// NB: This file is for testing basic_streambuf with NO OTHER INCLUDES.
|
||||
|
||||
#include <cstring> // for memset, memcmp
|
||||
#include <streambuf>
|
||||
#include <string>
|
||||
#include <ostream>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
class testbuf : public std::streambuf
|
||||
{
|
||||
public:
|
||||
|
||||
// Typedefs:
|
||||
typedef std::streambuf::traits_type traits_type;
|
||||
typedef std::streambuf::char_type char_type;
|
||||
|
||||
testbuf(): std::streambuf()
|
||||
{ _M_mode = (std::ios_base::in | std::ios_base::out); }
|
||||
|
||||
bool
|
||||
check_pointers()
|
||||
{
|
||||
bool test = true;
|
||||
VERIFY( this->eback() == NULL );
|
||||
VERIFY( this->gptr() == NULL );
|
||||
VERIFY( this->egptr() == NULL );
|
||||
VERIFY( this->pbase() == NULL );
|
||||
VERIFY( this->pptr() == NULL );
|
||||
VERIFY( this->epptr() == NULL );
|
||||
return test;
|
||||
}
|
||||
|
||||
int_type
|
||||
pub_uflow()
|
||||
{ return (this->uflow()); }
|
||||
|
||||
int_type
|
||||
pub_overflow(int_type __c = traits_type::eof())
|
||||
{ return (this->overflow(__c)); }
|
||||
|
||||
int_type
|
||||
pub_pbackfail(int_type __c)
|
||||
{ return (this->pbackfail(__c)); }
|
||||
|
||||
void
|
||||
pub_setg(char* beg, char* cur, char *end)
|
||||
{ this->setg(beg, cur, end); }
|
||||
|
||||
void
|
||||
pub_setp(char* beg, char* end)
|
||||
{ this->setp(beg, end); }
|
||||
|
||||
protected:
|
||||
int_type
|
||||
underflow()
|
||||
{
|
||||
int_type __retval = traits_type::eof();
|
||||
if (this->gptr() < this->egptr())
|
||||
__retval = traits_type::not_eof(0);
|
||||
return __retval;
|
||||
}
|
||||
};
|
||||
// { dg-do compile }
|
||||
|
||||
// libstdc++/7216
|
||||
void test01()
|
||||
{
|
||||
typedef testbuf::traits_type traits_type;
|
||||
typedef testbuf::int_type int_type;
|
||||
|
||||
bool test = true;
|
||||
char* lit01 = "chicago underground trio/possible cube on delmark";
|
||||
testbuf buf01;
|
||||
|
||||
// 27.5.2.1 basic_streambuf ctors
|
||||
// default ctor initializes
|
||||
// - all pointer members to null pointers
|
||||
// - locale to current global locale
|
||||
VERIFY( buf01.check_pointers() );
|
||||
VERIFY( buf01.getloc() == std::locale() );
|
||||
|
||||
// 27.5.2.3.1 get area
|
||||
// 27.5.2.2.3 get area
|
||||
// 27.5.2.4.3 get area
|
||||
int i01 = 3;
|
||||
buf01.pub_setg(lit01, lit01, (lit01 + i01));
|
||||
VERIFY( i01 == buf01.in_avail() );
|
||||
|
||||
VERIFY( buf01.pub_uflow() == lit01[0] );
|
||||
VERIFY( buf01.sgetc() == traits_type::to_int_type(lit01[1]) );
|
||||
VERIFY( buf01.pub_uflow() == lit01[1] );
|
||||
VERIFY( buf01.sgetc() == traits_type::to_int_type(lit01[2]) );
|
||||
VERIFY( buf01.pub_uflow() == lit01[2] );
|
||||
VERIFY( buf01.sgetc() == traits_type::eof() );
|
||||
|
||||
// pbackfail
|
||||
buf01.pub_setg(lit01, lit01, (lit01 + i01));
|
||||
VERIFY( i01 == buf01.in_avail() );
|
||||
int_type intt01 = traits_type::to_int_type('b');
|
||||
VERIFY( traits_type::eof() == buf01.pub_pbackfail(intt01) );
|
||||
|
||||
// overflow
|
||||
VERIFY( traits_type::eof() == buf01.pub_overflow(intt01) );
|
||||
VERIFY( traits_type::eof() == buf01.pub_overflow() );
|
||||
VERIFY( buf01.sgetc() == traits_type::to_int_type(lit01[0]) );
|
||||
|
||||
// sputn/xsputn
|
||||
char* lit02 = "isotope 217: the unstable molecule on thrill jockey";
|
||||
int i02 = std::strlen(lit02);
|
||||
char carray[i02 + 1];
|
||||
std::memset(carray, 0, i02 + 1);
|
||||
|
||||
buf01.pub_setp(carray, (carray + i02));
|
||||
buf01.sputn(lit02, 0);
|
||||
VERIFY( carray[0] == 0 );
|
||||
VERIFY( lit02[0] == 'i' );
|
||||
buf01.sputn(lit02, 1);
|
||||
VERIFY( lit02[0] == carray[0] );
|
||||
VERIFY( lit02[1] == 's' );
|
||||
VERIFY( carray[1] == 0 );
|
||||
buf01.sputn(lit02 + 1, 10);
|
||||
VERIFY( std::memcmp(lit02, carray, 10) == 0 );
|
||||
buf01.sputn(lit02 + 11, 20);
|
||||
VERIFY( std::memcmp(lit02, carray, 30) == 0 );
|
||||
|
||||
#ifdef DEBUG_ASSERT
|
||||
assert(test);
|
||||
#endif
|
||||
// Check for required typedefs
|
||||
typedef std::streambuf test_type;
|
||||
typedef test_type::char_type char_type;
|
||||
typedef test_type::traits_type traits_type;
|
||||
typedef test_type::int_type int_type;
|
||||
typedef test_type::pos_type pos_type;
|
||||
typedef test_type::off_type off_type;
|
||||
}
|
||||
|
||||
void test02()
|
||||
namespace test
|
||||
{
|
||||
typedef testbuf::traits_type traits_type;
|
||||
typedef testbuf::int_type int_type;
|
||||
|
||||
bool test = true;
|
||||
char* lit01 = "chicago underground trio/possible cube on delmark";
|
||||
testbuf buf01;
|
||||
|
||||
// 27.5.2.1 basic_streambuf ctors
|
||||
// default ctor initializes
|
||||
// - all pointer members to null pointers
|
||||
// - locale to current global locale
|
||||
VERIFY( buf01.check_pointers() );
|
||||
VERIFY( buf01.getloc() == std::locale() );
|
||||
|
||||
// 27.5.2.2.5 Put area
|
||||
size_t i01 = traits_type::length(lit01);
|
||||
char carray01[i01];
|
||||
std::memset(carray01, 0, i01);
|
||||
|
||||
buf01.pub_setg(lit01, lit01, lit01 + i01);
|
||||
buf01.sgetn(carray01, 0);
|
||||
VERIFY( carray01[0] == 0 );
|
||||
buf01.sgetn(carray01, 1);
|
||||
VERIFY( carray01[0] == 'c' );
|
||||
buf01.sgetn(carray01 + 1, i01 - 1);
|
||||
VERIFY( carray01[0] == 'c' );
|
||||
VERIFY( carray01[1] == 'h' );
|
||||
VERIFY( carray01[i01 - 1] == 'k' );
|
||||
|
||||
#ifdef DEBUG_ASSERT
|
||||
assert(test);
|
||||
#endif
|
||||
}
|
||||
|
||||
// test03
|
||||
// http://gcc.gnu.org/ml/libstdc++/2000-q1/msg00151.html
|
||||
template<typename charT, typename traits = std::char_traits<charT> >
|
||||
class basic_nullbuf : public std::basic_streambuf<charT, traits>
|
||||
{
|
||||
protected:
|
||||
typedef typename
|
||||
std::basic_streambuf<charT, traits>::int_type int_type;
|
||||
virtual int_type
|
||||
overflow(int_type c)
|
||||
{ return traits::not_eof(c); }
|
||||
};
|
||||
|
||||
typedef basic_nullbuf<char> nullbuf;
|
||||
typedef basic_nullbuf<wchar_t> wnullbuf;
|
||||
|
||||
template<typename T>
|
||||
char
|
||||
print(const T& x)
|
||||
{
|
||||
nullbuf ob;
|
||||
std::ostream out(&ob);
|
||||
out << x << std::endl;
|
||||
return (!out ? '0' : '1');
|
||||
}
|
||||
|
||||
void test03()
|
||||
{
|
||||
bool test = true;
|
||||
const std::string control01("11111");
|
||||
std::string test01;
|
||||
|
||||
test01 += print(true);
|
||||
test01 += print(3.14159);
|
||||
test01 += print(10);
|
||||
test01 += print('x');
|
||||
test01 += print("pipo");
|
||||
|
||||
VERIFY( test01 == control01 );
|
||||
#ifdef DEBUG_ASSERT
|
||||
assert(test);
|
||||
#endif
|
||||
}
|
||||
|
||||
class setpbuf : public std::streambuf
|
||||
{
|
||||
char buffer[4];
|
||||
std::string result;
|
||||
|
||||
public:
|
||||
|
||||
std::string&
|
||||
get_result()
|
||||
{ return result; }
|
||||
|
||||
setpbuf()
|
||||
{
|
||||
char foo [32];
|
||||
setp(foo, foo + 32);
|
||||
setp(buffer, buffer + 4);
|
||||
}
|
||||
|
||||
~setpbuf()
|
||||
{ sync(); }
|
||||
|
||||
virtual int_type
|
||||
overflow(int_type n)
|
||||
{
|
||||
if (sync() != 0)
|
||||
return traits_type::eof();
|
||||
|
||||
result += traits_type::to_char_type(n);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
virtual int
|
||||
sync()
|
||||
{
|
||||
result.append(pbase(), pptr());
|
||||
setp(buffer, buffer + 4);
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
// libstdc++/1057
|
||||
void test04()
|
||||
{
|
||||
bool test = true;
|
||||
std::string text = "abcdefghijklmn";
|
||||
|
||||
// 01
|
||||
setpbuf sp1;
|
||||
// Here xsputn writes over sp1.result
|
||||
sp1.sputn(text.c_str(), text.length());
|
||||
|
||||
// This crashes when result is accessed
|
||||
sp1.pubsync();
|
||||
VERIFY( sp1.get_result() == text );
|
||||
|
||||
|
||||
// 02
|
||||
setpbuf sp2;
|
||||
for (std::string::size_type i = 0; i < text.length(); ++i)
|
||||
{
|
||||
// sputc also writes over result
|
||||
sp2.sputc(text[i]);
|
||||
}
|
||||
|
||||
// Crash here
|
||||
sp2.pubsync();
|
||||
VERIFY( sp2.get_result() == text );
|
||||
}
|
||||
|
||||
class nullsetpbuf : public std::streambuf
|
||||
{
|
||||
char foo[64];
|
||||
public:
|
||||
nullsetpbuf()
|
||||
{
|
||||
setp(foo, foo + 64);
|
||||
setp(NULL, NULL);
|
||||
}
|
||||
};
|
||||
|
||||
// libstdc++/1057
|
||||
void test05()
|
||||
{
|
||||
std::string text1 = "abcdefghijklmn";
|
||||
|
||||
nullsetpbuf nsp;
|
||||
// Immediate crash as xsputn writes to null pointer
|
||||
nsp.sputn(text1.c_str(), text1.length());
|
||||
// ditto
|
||||
nsp.sputc('a');
|
||||
}
|
||||
|
||||
// test06
|
||||
namespace gnu
|
||||
{
|
||||
class something_derived;
|
||||
}
|
||||
|
||||
class gnu::something_derived : std::streambuf { };
|
||||
|
||||
// libstdc++/3599
|
||||
class testbuf2 : public std::streambuf
|
||||
{
|
||||
public:
|
||||
typedef std::streambuf::traits_type traits_type;
|
||||
|
||||
testbuf2() : std::streambuf() { }
|
||||
|
||||
protected:
|
||||
int_type
|
||||
overflow(int_type c = traits_type::eof())
|
||||
{ return traits_type::not_eof(0); }
|
||||
};
|
||||
|
||||
void
|
||||
test07()
|
||||
{
|
||||
bool test = true;
|
||||
testbuf2 ob;
|
||||
std::ostream out(&ob);
|
||||
|
||||
out << "gasp";
|
||||
VERIFY(out.good());
|
||||
|
||||
out << std::endl;
|
||||
VERIFY(out.good());
|
||||
}
|
||||
using namespace std;
|
||||
typedef short type_t;
|
||||
template class basic_streambuf<type_t, char_traits<type_t> >;
|
||||
} // test
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
test02();
|
||||
test03();
|
||||
|
||||
test04();
|
||||
test05();
|
||||
|
||||
test07();
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
// 981208 bkoz test functionality of basic_stringbuf for char_type == char
|
||||
// 2002-07-25 Benjamin Kosnik <bkoz@redhat.com>
|
||||
|
||||
// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002
|
||||
// Free Software Foundation, Inc.
|
||||
// Copyright (C) 2002 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
|
||||
|
@ -19,472 +18,43 @@
|
|||
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
// USA.
|
||||
|
||||
// As a special exception, you may use this file as part of a free software
|
||||
// library without restriction. Specifically, if other files instantiate
|
||||
// templates or use macros or inline functions from this file, or you compile
|
||||
// this file and link it with other files to produce an executable, this
|
||||
// file does not by itself cause the resulting executable to be covered by
|
||||
// the GNU General Public License. This exception does not however
|
||||
// invalidate any other reasons why the executable file might be covered by
|
||||
// the GNU General Public License.
|
||||
|
||||
// 27.7.1 - Template class basic_stringbuf
|
||||
// NB: This file is for testing basic_stringbuf with NO OTHER INCLUDES.
|
||||
|
||||
#include <sstream>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
std::string str_01("mykonos. . . or what?");
|
||||
std::string str_02("paris, or sainte-maxime?");
|
||||
std::string str_03;
|
||||
std::stringbuf strb_01(str_01);
|
||||
std::stringbuf strb_02(str_02, std::ios_base::in);
|
||||
std::stringbuf strb_03(str_03, std::ios_base::out);
|
||||
// { dg-do compile }
|
||||
|
||||
|
||||
// test the underlying allocator
|
||||
bool test01() {
|
||||
bool test = false;
|
||||
std::allocator<char> alloc_01;
|
||||
std::allocator<char>::size_type size_01 = alloc_01.max_size();
|
||||
std::allocator<char>::pointer p_01 = alloc_01.allocate(32);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// test the streambuf/stringbuf locale settings
|
||||
bool test02() {
|
||||
std::locale loc_tmp;
|
||||
loc_tmp = strb_01.getloc();
|
||||
strb_01.pubimbue(loc_tmp); //This should initialize _M_init to true
|
||||
strb_01.getloc(); //This should just return _M_locale
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// test member functions
|
||||
bool test03() {
|
||||
bool test = true;
|
||||
|
||||
//stringbuf::str()
|
||||
VERIFY( strb_01.str() == str_01 );
|
||||
VERIFY( strb_02.str() == str_02 );
|
||||
VERIFY( strb_03.str() == str_03 );
|
||||
|
||||
//stringbuf::str(string&)
|
||||
strb_03.str("none of the above, go to the oberoi in cairo, egypt.");
|
||||
strb_03.str(str_01);
|
||||
std::streamsize d1 = strb_01.in_avail();
|
||||
std::streamsize d2 = strb_03.in_avail();
|
||||
VERIFY( d1 ); // non-zero
|
||||
VERIFY( !d2 ); // zero, cuz ios_base::out
|
||||
VERIFY( d1 != d2 ); //these should be the same
|
||||
VERIFY( str_01.length() == d1 );
|
||||
VERIFY( strb_01.str() == strb_03.str() ); //ditto
|
||||
|
||||
// stringbuf::str(string&) and stringbuf::stringbuf(string&), where the
|
||||
// string in question contains embedded NUL characters. Note that in this
|
||||
// embedded-NUL situation, the size must be passed to the string ctor.
|
||||
std::string str_nulls ("eschew \0 obfuscation", 20); // tested in 21_strings
|
||||
std::stringbuf strb_normal (str_01);
|
||||
std::stringbuf strb_nulls (str_nulls);
|
||||
strb_normal.str(str_nulls); // tried using 'strb_01' rather than declaring
|
||||
// another variable, but then test04 broke!
|
||||
VERIFY( strb_nulls.in_avail() == str_nulls.size() );
|
||||
VERIFY( strb_nulls.str().size() == 20 );
|
||||
VERIFY( strb_normal.in_avail() == str_nulls.size() );
|
||||
|
||||
#ifdef DEBUG_ASSERT
|
||||
assert(test);
|
||||
#endif
|
||||
|
||||
return test;
|
||||
}
|
||||
|
||||
|
||||
// test overloaded virtual functions
|
||||
bool test04() {
|
||||
bool test = true;
|
||||
std::string str_tmp;
|
||||
std::stringbuf strb_tmp;
|
||||
std::streamsize strmsz_1, strmsz_2;
|
||||
std::streamoff strmof_1(-1), strmof_2;
|
||||
typedef std::stringbuf::int_type int_type;
|
||||
typedef std::stringbuf::traits_type traits_type;
|
||||
typedef std::stringbuf::pos_type pos_type;
|
||||
typedef std::stringbuf::off_type off_type;
|
||||
|
||||
// GET
|
||||
// int in_avail()
|
||||
strmof_1 = strb_01.in_avail();
|
||||
strmof_2 = strb_02.in_avail();
|
||||
VERIFY( strmof_1 != strmof_2 );
|
||||
VERIFY( strmof_1 == str_01.length() );
|
||||
VERIFY( strmof_2 == str_02.length() );
|
||||
strmof_1 = strb_03.in_avail();
|
||||
VERIFY( strmof_1 == 0 ); // zero cuz write-only, or eof()? zero, from showmany
|
||||
|
||||
// int_type sbumpc()
|
||||
// if read_cur not avail, return uflow(), else return *read_cur & increment
|
||||
int_type c1 = strb_01.sbumpc();
|
||||
int_type c2 = strb_02.sbumpc();
|
||||
VERIFY( c1 != c2 );
|
||||
VERIFY( c1 == str_01[0] );
|
||||
VERIFY( c2 == str_02[0] ); //should equal first letter at this point
|
||||
int_type c3 = strb_01.sbumpc();
|
||||
int_type c4 = strb_02.sbumpc();
|
||||
VERIFY( c1 != c2 );
|
||||
VERIFY( c1 != c3 );
|
||||
VERIFY( c2 != c4 );
|
||||
int_type c5 = strb_03.sbumpc();
|
||||
VERIFY( c5 == traits_type::eof() );
|
||||
|
||||
// int_type sgetc()
|
||||
// if read_cur not avail, return uflow(), else return *read_cur
|
||||
int_type c6 = strb_01.sgetc();
|
||||
int_type c7 = strb_02.sgetc();
|
||||
VERIFY( c6 != c3 );
|
||||
VERIFY( c7 != c4 );
|
||||
int_type c8 = strb_01.sgetc();
|
||||
int_type c9 = strb_02.sgetc();
|
||||
VERIFY( c6 == c8 );
|
||||
VERIFY( c7 == c9 );
|
||||
c5 = strb_03.sgetc();
|
||||
VERIFY( c5 == traits_type::eof() );
|
||||
|
||||
// int_type snextc()
|
||||
// calls sbumpc and if sbumpc != eof, return sgetc
|
||||
c6 = strb_01.snextc();
|
||||
c7 = strb_02.snextc();
|
||||
VERIFY( c6 != c8 );
|
||||
VERIFY( c7 != c9 );
|
||||
VERIFY( c6 == str_01[3] );
|
||||
VERIFY( c7 == str_02[3] ); //should equal fourth letter at this point
|
||||
c5 = strb_03.snextc();
|
||||
VERIFY( c5 == traits_type::eof() );
|
||||
|
||||
// int showmanyc
|
||||
// streamsize sgetn(char_type *s, streamsize n)
|
||||
// streamsize xsgetn(char_type *s, streamsize n)
|
||||
// assign up to n chars to s from input sequence, indexing in_cur as
|
||||
// approp and returning the number of chars assigned
|
||||
strmsz_1 = strb_01.in_avail();
|
||||
strmsz_2 = strb_02.in_avail();
|
||||
test = strmsz_1 != strmsz_2;
|
||||
VERIFY( strmsz_1 != str_01.length() );
|
||||
VERIFY( strmsz_2 != str_02.length() ); //because now we've moved into string
|
||||
char carray1[11] = "";
|
||||
strmsz_1 = strb_01.sgetn(carray1, 10);
|
||||
char carray2[20] = "";
|
||||
strmsz_2 = strb_02.sgetn(carray2, 10);
|
||||
VERIFY( strmsz_1 == strmsz_2 );
|
||||
VERIFY( strmsz_1 == 10 );
|
||||
c1 = strb_01.sgetc();
|
||||
c2 = strb_02.sgetc();
|
||||
VERIFY( c6 == c1 ); //just by co-incidence both o's
|
||||
VERIFY( c7 != c2 ); // n != i
|
||||
VERIFY( c1 == str_01[13] );
|
||||
VERIFY( c2 == str_02[13] ); //should equal fourteenth letter at this point
|
||||
strmsz_1 = strb_03.sgetn(carray1, 10);
|
||||
VERIFY( !strmsz_1 ); //zero
|
||||
strmsz_1 = strb_02.in_avail();
|
||||
strmsz_2 = strb_02.sgetn(carray2, strmsz_1 + 5);
|
||||
VERIFY( strmsz_1 == strmsz_2 ); //write off the end
|
||||
c4 = strb_02.sgetc(); // should be EOF
|
||||
VERIFY( c4 == traits_type::eof() );
|
||||
|
||||
// PUT
|
||||
// int_type sputc(char_type c)
|
||||
// if out_cur not avail, return overflow. Else, stores c at out_cur,
|
||||
// increments out_cur, and returns c as int_type
|
||||
strb_03.str(str_01); //reset
|
||||
std::string::size_type sz1 = strb_03.str().length();
|
||||
c1 = strb_03.sputc('a');
|
||||
std::string::size_type sz2 = strb_03.str().length();
|
||||
VERIFY( sz1 == sz2 ); //cuz inserting at out_cur, which is at beg to start
|
||||
c2 = strb_03.sputc('b');
|
||||
VERIFY( c1 != c2 );
|
||||
VERIFY( strb_03.str() != str_01 );
|
||||
c3 = strb_02.sputc('a'); // should be EOF because this is read-only
|
||||
VERIFY( c3 == traits_type::eof() );
|
||||
|
||||
// streamsize sputn(const char_typs* s, streamsize n)
|
||||
// write up to n chars to out_cur from s, returning number assigned
|
||||
// NB *sputn will happily put '\0' into your stream if you give it a chance*
|
||||
str_tmp = strb_03.str();
|
||||
sz1 = str_tmp.length();
|
||||
strmsz_1 = strb_03.sputn("racadabras", 10);//"abracadabras or what?"
|
||||
sz2 = strb_03.str().length();
|
||||
VERIFY( sz1 == sz2 ); //shouldn't have changed length
|
||||
VERIFY( strmsz_1 == 10 );
|
||||
VERIFY( str_tmp != strb_03.str() );
|
||||
strmsz_2 = strb_03.sputn(", i wanna reach out and", 10);
|
||||
VERIFY( strmsz_1 == strmsz_2 ); // should re-allocate, copy 10 chars.
|
||||
VERIFY( strmsz_1 == 10 );
|
||||
VERIFY( strmsz_2 == 10 );
|
||||
sz2 = strb_03.str().length();
|
||||
VERIFY( sz1 != sz2 ); // need to change length
|
||||
VERIFY( str_tmp != strb_03.str() );
|
||||
str_tmp = strb_02.str();
|
||||
strmsz_1 = strb_02.sputn("racadabra", 10);
|
||||
VERIFY( strmsz_1 == 0 );
|
||||
VERIFY( str_tmp == strb_02.str() );
|
||||
|
||||
// PUTBACK
|
||||
// int_type pbfail(int_type c)
|
||||
// called when gptr() null, gptr() == eback(), or traits::eq(*gptr, c) false
|
||||
// "pending sequence" is:
|
||||
// 1) everything as defined in underflow
|
||||
// 2) + if (traits::eq_int_type(c, traits::eof()), then input
|
||||
// sequence is backed up one char before the pending sequence is
|
||||
// determined.
|
||||
// 3) + if (not 2) then c is prepended. Left unspecified is
|
||||
// whether the input sequence is backedup or modified in any way
|
||||
// returns traits::eof() for failure, unspecified other value for success
|
||||
|
||||
// int_type sputbackc(char_type c)
|
||||
// if in_cur not avail || ! traits::eq(c, gptr() [-1]), return pbfail
|
||||
// otherwise decrements in_cur and returns *gptr()
|
||||
strmsz_1 = strb_01.in_avail();
|
||||
str_tmp = strb_01.str();
|
||||
c1 = strb_01.sgetc(); //"mykonos. . . 'o'r what?"
|
||||
c2 = strb_01.sputbackc('z');//"mykonos. . .zor what?"
|
||||
c3 = strb_01.sgetc();
|
||||
VERIFY( c1 != c2 );
|
||||
VERIFY( c3 == c2 );
|
||||
VERIFY( strb_01.str() == std::string("mykonos. . .zor what?") );
|
||||
VERIFY( str_tmp.size() == strb_01.str().size() );
|
||||
//test for _in_cur == _in_beg
|
||||
strb_01.str(str_tmp);
|
||||
strmsz_1 = strb_01.in_avail();
|
||||
c1 = strb_01.sgetc(); //"'m'ykonos. . . or what?"
|
||||
c2 = strb_01.sputbackc('z');//"mykonos. . . or what?"
|
||||
c3 = strb_01.sgetc();
|
||||
VERIFY( c1 != c2 );
|
||||
VERIFY( c3 != c2 );
|
||||
VERIFY( c1 == c3 );
|
||||
VERIFY( c2 == traits_type::eof() );
|
||||
VERIFY( strb_01.str() == str_tmp );
|
||||
VERIFY( str_tmp.size() == strb_01.str().size() );
|
||||
// test for replacing char with identical one
|
||||
strb_01.str(str_01); //reset
|
||||
strmsz_1 = strb_01.in_avail();
|
||||
strb_01.sbumpc();
|
||||
strb_01.sbumpc();
|
||||
c1 = strb_01.sgetc(); //"my'k'onos. . . or what?"
|
||||
c2 = strb_01.sputbackc('y');//"mykonos. . . or what?"
|
||||
c3 = strb_01.sgetc();
|
||||
VERIFY( c1 != c2 );
|
||||
VERIFY( c3 == c2 );
|
||||
VERIFY( c1 != c3 );
|
||||
VERIFY( strb_01.str() == str_01 );
|
||||
VERIFY( str_01.size() == strb_01.str().size() );
|
||||
//test for ios_base::out
|
||||
strmsz_2 = strb_03.in_avail();
|
||||
c4 = strb_03.sputbackc('x');
|
||||
VERIFY( c4 == traits_type::eof() );
|
||||
|
||||
// int_type sungetc()
|
||||
// if in_cur not avail, return pbackfail(), else decrement and
|
||||
// return to_int_type(*gptr())
|
||||
for (int i = 0; i<12; ++i)
|
||||
strb_01.sbumpc();
|
||||
strmsz_1 = strb_01.in_avail();
|
||||
str_tmp = strb_01.str();
|
||||
c1 = strb_01.sgetc(); //"mykonos. . . 'o'r what?"
|
||||
c2 = strb_01.sungetc();//"mykonos. . . or what?"
|
||||
c3 = strb_01.sgetc();
|
||||
VERIFY( c1 != c2 );
|
||||
VERIFY( c3 == c2 );
|
||||
VERIFY( c1 != c3 );
|
||||
VERIFY( c2 == ' ' );
|
||||
VERIFY( strb_01.str() == str_01 );
|
||||
VERIFY( str_01.size() == strb_01.str().size() );
|
||||
//test for _in_cur == _in_beg
|
||||
strb_01.str(str_tmp);
|
||||
strmsz_1 = strb_01.in_avail();
|
||||
c1 = strb_01.sgetc(); //"'m'ykonos. . . or what?"
|
||||
c2 = strb_01.sungetc();//"mykonos. . . or what?"
|
||||
c3 = strb_01.sgetc();
|
||||
VERIFY( c1 != c2 );
|
||||
VERIFY( c3 != c2 );
|
||||
VERIFY( c1 == c3 );
|
||||
VERIFY( c2 == traits_type::eof() );
|
||||
VERIFY( strb_01.str() == str_01 );
|
||||
VERIFY( str_01.size() == strb_01.str().size() );
|
||||
// test for replacing char with identical one
|
||||
strb_01.str(str_01); //reset
|
||||
strmsz_1 = strb_01.in_avail();
|
||||
strb_01.sbumpc();
|
||||
strb_01.sbumpc();
|
||||
c1 = strb_01.sgetc(); //"my'k'onos. . . or what?"
|
||||
c2 = strb_01.sungetc();//"mykonos. . . or what?"
|
||||
c3 = strb_01.sgetc();
|
||||
VERIFY( c1 != c2 );
|
||||
VERIFY( c3 == c2 );
|
||||
VERIFY( c1 != c3 );
|
||||
VERIFY( strb_01.str() == str_01 );
|
||||
VERIFY( str_01.size() == strb_01.str().size() );
|
||||
//test for ios_base::out
|
||||
strmsz_2 = strb_03.in_avail();
|
||||
c4 = strb_03.sungetc();
|
||||
VERIFY( c4 == traits_type::eof() );
|
||||
|
||||
// BUFFER MANAGEMENT & POSITIONING
|
||||
// sync
|
||||
// pubsync
|
||||
strb_01.pubsync();
|
||||
strb_02.pubsync();
|
||||
strb_03.pubsync();
|
||||
|
||||
// setbuf
|
||||
// pubsetbuf(char_type* s, streamsize n)
|
||||
str_tmp = std::string("naaaah, go to cebu");
|
||||
strb_01.pubsetbuf(const_cast<char*> (str_tmp.c_str()), str_tmp.size());
|
||||
VERIFY( strb_01.str() == str_tmp );
|
||||
strb_01.pubsetbuf(0,0);
|
||||
VERIFY( strb_01.str() == str_tmp );
|
||||
|
||||
// seekoff
|
||||
// pubseekoff(off_type off, ios_base::seekdir way, ios_base::openmode which)
|
||||
// alters the stream position to off
|
||||
pos_type pt_1(off_type(-1));
|
||||
pos_type pt_2(off_type(0));
|
||||
off_type off_1 = 0;
|
||||
off_type off_2 = 0;
|
||||
strb_01.str(str_01); //in|out ("mykonos. . . or what?");
|
||||
strb_02.str(str_02); //in ("paris, or sainte-maxime?");
|
||||
strb_03.str(str_03); //out ("")
|
||||
//IN|OUT
|
||||
//beg
|
||||
pt_1 = strb_01.pubseekoff(2, std::ios_base::beg);
|
||||
off_1 = pt_1;
|
||||
VERIFY( off_1 >= 0 );
|
||||
c1 = strb_01.snextc(); //current in pointer +1
|
||||
VERIFY( c1 == 'o' );
|
||||
c2 = strb_01.sputc('x'); //test current out pointer
|
||||
str_tmp = std::string("myxonos. . . or what?");
|
||||
VERIFY( strb_01.str() == str_tmp );
|
||||
//cur
|
||||
pt_1 = strb_01.pubseekoff(2, std::ios_base::cur);
|
||||
off_1 = pt_1;
|
||||
VERIFY( off_1 == -1 ); // can't seekoff for in and out + cur in sstreams
|
||||
pt_1 = strb_01.pubseekoff(2, std::ios_base::cur, std::ios_base::in);
|
||||
off_1 = pt_1;
|
||||
pt_2 = strb_01.pubseekoff(2, std::ios_base::cur, std::ios_base::in);
|
||||
off_2 = pt_2;
|
||||
VERIFY( off_2 == off_1 + 2 );
|
||||
c1 = strb_01.snextc(); //current in pointer + 1
|
||||
VERIFY( c1 == ' ' );
|
||||
c2 = strb_01.sputc('x'); //test current out pointer
|
||||
str_tmp = std::string("myxxnos. . . or what?");
|
||||
VERIFY( strb_01.str() == str_tmp );
|
||||
//end
|
||||
pt_2 = strb_01.pubseekoff(2, std::ios_base::end);
|
||||
off_1 = pt_2;
|
||||
VERIFY( off_1 == -1 ); // not a valid position
|
||||
VERIFY( strb_01.str() == str_tmp );
|
||||
// end part two (from the filebuf tests)
|
||||
strb_01.pubseekoff(0, std::ios_base::end);
|
||||
strmsz_1 = strb_01.in_avail(); // 0 cuz at the end
|
||||
c1 = strb_01.sgetc();
|
||||
c2 = strb_01.sungetc();
|
||||
strmsz_2 = strb_01.in_avail(); // 1
|
||||
c3 = strb_01.sgetc();
|
||||
VERIFY( c1 != c2 );
|
||||
VERIFY( strmsz_2 != strmsz_1 );
|
||||
VERIFY( strmsz_2 == 1 );
|
||||
// end part three
|
||||
strmsz_1 = strb_01.str().size();
|
||||
strmsz_2 = strb_01.sputn(" ravi shankar meets carlos santana in LoHa", 90);
|
||||
strb_01.pubseekoff(0, std::ios_base::end);
|
||||
strb_01.sputc('<');
|
||||
str_tmp = strb_01.str();
|
||||
VERIFY( str_tmp.size() == strmsz_1 + strmsz_2 + 1 );
|
||||
// IN
|
||||
// OUT
|
||||
|
||||
// seekpos
|
||||
// pubseekpos(pos_type sp, ios_base::openmode)
|
||||
// alters the stream position to sp
|
||||
strb_01.str(str_01); //in|out ("mykonos. . . or what?");
|
||||
strb_02.str(str_02); //in ("paris, or sainte-maxime?");
|
||||
strb_03.str(str_03); //out ("")
|
||||
//IN|OUT
|
||||
//beg
|
||||
pt_1 = strb_01.pubseekoff(2, std::ios_base::beg);
|
||||
off_1 = pt_1;
|
||||
VERIFY( off_1 >= 0 );
|
||||
pt_1 = strb_01.pubseekoff(0, std::ios_base::cur, std::ios_base::out);
|
||||
off_1 = pt_1;
|
||||
c1 = strb_01.snextc(); //current in pointer +1
|
||||
VERIFY( c1 == 'o' );
|
||||
c2 = strb_01.sputc('x'); //test current out pointer
|
||||
str_tmp = std::string("myxonos. . . or what?");
|
||||
VERIFY( strb_01.str() == str_tmp );
|
||||
strb_01.pubsync(); //resets pointers
|
||||
pt_2 = strb_01.pubseekpos(pt_1, std::ios_base::in|std::ios_base::out);
|
||||
off_2 = pt_2;
|
||||
VERIFY( off_1 == off_2 );
|
||||
c3 = strb_01.snextc(); //current in pointer +1
|
||||
VERIFY( c1 == c3 );
|
||||
c2 = strb_01.sputc('x'); //test current out pointer
|
||||
str_tmp = std::string("myxonos. . . or what?");
|
||||
VERIFY( strb_01.str() == str_tmp );
|
||||
|
||||
// VIRTUALS (indirectly tested)
|
||||
// underflow
|
||||
// if read position avail, returns *gptr()
|
||||
|
||||
// pbackfail(int_type c)
|
||||
// put c back into input sequence
|
||||
|
||||
// overflow
|
||||
// appends c to output seq
|
||||
|
||||
#ifdef DEBUG_ASSERT
|
||||
assert(test);
|
||||
#endif
|
||||
|
||||
return test;
|
||||
}
|
||||
|
||||
|
||||
// libstdc++/3955 -- ios_base::app overwrites from the beginning
|
||||
bool test05()
|
||||
// libstdc++/7216
|
||||
void test01()
|
||||
{
|
||||
bool test = true;
|
||||
|
||||
std::ostringstream os ("foo");
|
||||
os << "bar";
|
||||
|
||||
test = os.str() == "bar";
|
||||
|
||||
#ifdef DEBUG_ASSERT
|
||||
assert(test);
|
||||
#endif
|
||||
|
||||
return test;
|
||||
// Check for required typedefs
|
||||
typedef std::stringbuf test_type;
|
||||
typedef test_type::char_type char_type;
|
||||
typedef test_type::traits_type traits_type;
|
||||
typedef test_type::int_type int_type;
|
||||
typedef test_type::pos_type pos_type;
|
||||
typedef test_type::off_type off_type;
|
||||
}
|
||||
|
||||
bool test06()
|
||||
namespace test
|
||||
{
|
||||
bool test = true;
|
||||
using namespace std;
|
||||
typedef short type_t;
|
||||
template class basic_stringbuf<type_t, char_traits<type_t> >;
|
||||
} // test
|
||||
|
||||
std::ostringstream os ("foo", std::ios_base::app);
|
||||
os << "bar";
|
||||
|
||||
test = os.str() == "foobar";
|
||||
|
||||
#ifdef DEBUG_ASSERT
|
||||
assert(test);
|
||||
#endif
|
||||
|
||||
return test;
|
||||
}
|
||||
|
||||
int main()
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
test02();
|
||||
test03();
|
||||
test04();
|
||||
test05();
|
||||
test06();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// more candy!!!
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
// 981015 bkoz
|
||||
// i,o,stringstream usage
|
||||
// 2002-07-25 Benjamin Kosnik <bkoz@redhat.com>
|
||||
|
||||
// Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
|
||||
// Copyright (C) 2002 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
|
||||
|
@ -28,133 +27,34 @@
|
|||
// invalidate any other reasons why the executable file might be covered by
|
||||
// the GNU General Public License.
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
// 27.7.4 - Template class basic_stringstream
|
||||
// NB: This file is for testing basic_stringstream with NO OTHER INCLUDES.
|
||||
|
||||
#include <sstream>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
// 01: sanity checks for strings, stringbufs
|
||||
std::string
|
||||
test01()
|
||||
// { dg-do compile }
|
||||
|
||||
// libstdc++/7216
|
||||
void test01()
|
||||
{
|
||||
bool test = false;
|
||||
|
||||
// Empty string sanity check.
|
||||
std::string str01;
|
||||
std::string::iterator __i_start = str01.begin();
|
||||
std::string::iterator __i_end = str01.end();
|
||||
std::string::size_type len = str01.size();
|
||||
test = __i_start == __i_end;
|
||||
VERIFY( len == 0 );
|
||||
|
||||
// Full string sanity check.
|
||||
std::string str02("these golden days, i spend waiting for you:\n"
|
||||
"Betty Carter on Verve with I'm Yours and You're Mine.");
|
||||
__i_start = str02.begin();
|
||||
__i_end = str02.end();
|
||||
len = str02.size();
|
||||
VERIFY( __i_start != __i_end );
|
||||
VERIFY( len != 0 );
|
||||
|
||||
// Test an empty ostring stream for sanity.
|
||||
std::ostringstream ostrstream0;
|
||||
std::string str03 = ostrstream0.str();
|
||||
__i_start = str03.begin();
|
||||
__i_end = str03.end();
|
||||
len = str03.size();
|
||||
VERIFY( __i_start == __i_end );
|
||||
VERIFY( len == 0 );
|
||||
VERIFY( str01 == str03 );
|
||||
|
||||
return str02;
|
||||
// Check for required typedefs
|
||||
typedef std::stringstream test_type;
|
||||
typedef test_type::char_type char_type;
|
||||
typedef test_type::traits_type traits_type;
|
||||
typedef test_type::int_type int_type;
|
||||
typedef test_type::pos_type pos_type;
|
||||
typedef test_type::off_type off_type;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
test02()
|
||||
namespace test
|
||||
{
|
||||
bool test = true;
|
||||
using namespace std;
|
||||
typedef short type_t;
|
||||
template class basic_stringstream<type_t, char_traits<type_t> >;
|
||||
} // test
|
||||
|
||||
//
|
||||
// 1: Automatic formatting of a compound string
|
||||
//
|
||||
int i = 1024;
|
||||
int *pi = &i;
|
||||
double d = 3.14159;
|
||||
double *pd = &d;
|
||||
std::string blank;
|
||||
std::ostringstream ostrst01;
|
||||
std::ostringstream ostrst02(blank);
|
||||
|
||||
// No buffer,so should be created.
|
||||
ostrst01 << "i: " << i << " i's address: " << pi << "\n"
|
||||
<< "d: " << d << " d's address: " << pd << std::endl;
|
||||
// Buffer, so existing buffer should be overwritten.
|
||||
ostrst02 << "i: " << i << " i's address: " << pi << "\n"
|
||||
<< "d: " << d << " d's address: " << pd << std::endl;
|
||||
|
||||
std::string msg01 = ostrst01.str();
|
||||
std::string msg02 = ostrst02.str();
|
||||
VERIFY( msg01 == msg02 );
|
||||
VERIFY( msg02 != blank );
|
||||
|
||||
//
|
||||
// 2: istringstream
|
||||
//
|
||||
// extracts the stored ascii values, placing them in turn in the four vars
|
||||
#if 0
|
||||
int i2 = 0;
|
||||
int *pi2 = &i2;
|
||||
double d2 = 0.0;
|
||||
double *pd2 = &d2;
|
||||
std::istringstream istrst01(ostrst02.str());
|
||||
|
||||
istrst01 >> i2 >> pi2 >> d2 >> pd2;
|
||||
//istrst01 >> i2;
|
||||
//istrst01 >> pi2;
|
||||
VERIFY( i2 == i );
|
||||
VERIFY( d2 == d );
|
||||
VERIFY( pd2 == pd );
|
||||
VERIFY( pi2 == pi );
|
||||
#endif
|
||||
|
||||
// stringstream
|
||||
std::string str1("");
|
||||
std::string str3("this is a somewhat string");
|
||||
std::stringstream ss1(str1, std::ios_base::in|std::ios_base::out);
|
||||
std::stringstream ss2(str3, std::ios_base::in|std::ios_base::out);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// user-reported error
|
||||
class derived_oss: public std::ostringstream
|
||||
{
|
||||
public:
|
||||
derived_oss() : std::ostringstream() {}
|
||||
};
|
||||
|
||||
int
|
||||
test03()
|
||||
{
|
||||
bool test = true;
|
||||
derived_oss yy;
|
||||
yy << "buena vista social club\n";
|
||||
VERIFY( yy.str() == std::string("buena vista social club\n") );
|
||||
|
||||
#ifdef DEBUG_ASSERT
|
||||
assert(test);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
test02();
|
||||
test03();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// 2001-05-24 Benjamin Kosnik <bkoz@redhat.com>
|
||||
|
||||
// Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
// Copyright (C) 2001, 2002 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
|
||||
|
@ -120,12 +120,67 @@ void test02()
|
|||
// These semantics are a joke, a serious defect, and incredibly lame.
|
||||
}
|
||||
|
||||
void
|
||||
test03()
|
||||
{
|
||||
bool test = true;
|
||||
|
||||
//
|
||||
// 1: Automatic formatting of a compound string
|
||||
//
|
||||
int i = 1024;
|
||||
int *pi = &i;
|
||||
double d = 3.14159;
|
||||
double *pd = &d;
|
||||
std::string blank;
|
||||
std::ostringstream ostrst01;
|
||||
std::ostringstream ostrst02(blank);
|
||||
|
||||
// No buffer, so should be created.
|
||||
ostrst01 << "i: " << i << " i's address: " << pi << "\n"
|
||||
<< "d: " << d << " d's address: " << pd << std::endl;
|
||||
// Buffer, so existing buffer should be overwritten.
|
||||
ostrst02 << "i: " << i << " i's address: " << pi << "\n"
|
||||
<< "d: " << d << " d's address: " << pd << std::endl;
|
||||
|
||||
std::string msg01 = ostrst01.str();
|
||||
std::string msg02 = ostrst02.str();
|
||||
VERIFY( msg01 == msg02 );
|
||||
VERIFY( msg02 != blank );
|
||||
|
||||
//
|
||||
// 2: istringstream
|
||||
//
|
||||
// extracts the stored ascii values, placing them in turn in the four vars
|
||||
#if 0
|
||||
int i2 = 0;
|
||||
//int* pi2 = &i2;
|
||||
void* pi2 = &i2;
|
||||
double d2 = 0.0;
|
||||
// double* pd2 = &d2;
|
||||
void* pd2 = &d2;
|
||||
std::istringstream istrst01(ostrst02.str());
|
||||
|
||||
istrst01 >> i2 >> pi2 >> d2 >> pd2;
|
||||
//istrst01 >> i2;
|
||||
//istrst01 >> pi2;
|
||||
VERIFY( i2 == i );
|
||||
VERIFY( d2 == d );
|
||||
VERIFY( pd2 == pd );
|
||||
VERIFY( pi2 == pi );
|
||||
#endif
|
||||
|
||||
// stringstream
|
||||
std::string str1("");
|
||||
std::string str3("this is a somewhat string");
|
||||
std::stringstream ss1(str1, std::ios_base::in|std::ios_base::out);
|
||||
std::stringstream ss2(str3, std::ios_base::in|std::ios_base::out);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
test02();
|
||||
test03();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue