8sa1-gcc/libstdc++-v3/libsupc++/tinfo.h
Benjamin Kosnik e2c094827c Add support for -fno-exceptions.
2001-02-15  Benjamin Kosnik  <bkoz@redhat.com>

	Add support for -fno-exceptions.
	* include/bits/exception_support.h: Remove.
	* include/bits/basic_string.h: Remove exception_support.
	(string::_M_check): Replace __OUTOFRANGE with __throw_out_of_range.
	(string::at): Same.
	(string::substr): Same.
	* include/bits/basic_string.tcc (string::reserve): Replace
	__LENGTHERROR with __throw_length_error.
	(string::_S_create): Same.
	(string::resize): Same.
	(string::_M_replace): Same.
	(string::replace): Same.
	(string::copy): Replace __OUTOFRANGE with __throw_out_of_range.
	(string::compare): Same.
	* include/bits/stl_vector.h: Remove exception_support.
	* src/Makefile.am (base_headers): Remove here.
	* src/Makefile.in: Regenerate.

	* include/bits/stl_range_errors.h: Remove.
	* include/bits/stl_deque.h: Use __throw_range_error.
	* include/bits/std_deque.h: Include functexcept.h.
	* include/bits/std_vector.h: Same.
	* src/Makefile.am (base_headers): Remove here.
	* src/Makefile.in: Regenerate.
	* include/ext/stl_bvector.h (class __BVECTOR): Use __throw_range_error.
	* include/ext/bvector: Remove stl_range_errors.h

	* include/bits/c++config (_GLIBCPP_USE_EXCEPTIONS): Remove.

	* include/bits/functexcept.h: New file.
	* src/functexcept.cc: New file. Definitions for function-based
	exception routines.
	* src/Makefile.am (sources): Add functexcept.cc.
	* src/Makefile.in: Regenerate.

	* include/bits/stl_config.h (__STL_USE_EXCEPTIONS): Wrap with
	__EXCEPTIONS.

	* include/bits/localefwd.h: Include functexcept.h.
	* include/bits/std_iosfwd.h: Same.

	* include/bits/basic_ios.h: Use __throw_ios_failure instead of
	throw basic_ios::failure.
	* include/bits/fstream.tcc (filebuf::_M_allocate_buffers):
	Use __throw_exception_again.
	(filebuf::_M_filebuf_init): Same.
	* include/bits/streambuf.tcc (__copy_streambufs): Same.
	* include/bits/ostream.tcc (ostream::operator<<): Same.
	* include/bits/istream.tcc (istream::operator>>): Same.
	* include/bits/basic_string.tcc (string::_M_mutate): Same.
	(string::_S_construct): Same.
	(string::_M_clone): Same.
	* include/bits/locale_facets.tcc (use_facet(const locale&)): Use
	__throw_bad_cast.
	(num_put<_CharT, _OutIter>::do_put): Use __throw_exception_again.
	* src/localename.cc (locale::_Imp::_Imp(const _Impl&, size_t): Use
	__throw_exception_again.
	(locale::_Imp::_Imp(string, size_t): Same.
	(locale::_Imp::_M_replace_facet): Use __throw_runtime_error.
	* src/locale.cc (locale::_M_coalesce): Use __throw_exception_again.
	(locale::locale(const char*)): Use __throw_runtime_error.
	(locale::classic): Use __throw_exception_again.
	(locale::_S_normalize_category): Use __throw_runtime_error.

	* src/stdexcept.cc: Remove cruft.

	* libsupc++/exception_defines.h: New file.
	* libsupc++/new_opnt.cc: Include exception_defines.h.
	* libsupc++/vec.cc: Same.
	(__cxa_vec_new2): Use __throw_exception_again.
	(__cxa_vec_new3): Same.
	(__cxa_vec_ctor): Same.
	(__cxa_vec_delete3): Same.
	(__cxa_vec_cctor): Same.
	(__cxa_vec_delete2): Same.
	(__cxa_vec_dtor): Same.
	* libsupc++/exception_support.cc: Include exception_defines.h. Only
	compile exception-handling bits if __EXCEPTIONS is defined.
	Remove old ABI support.
	* libsupc++/new_op.cc (new): Include exception_defines.h. Use
	std::__throw_bad_alloc() instead of throw bad_alloc.
	* libsupc++/Makefile.am: Add exception_defines.h.
	* libsupc++/Makefile.in: Reformat.
	* libsupc++/*: Format.

From-SVN: r39730
2001-02-16 00:44:44 +00:00

226 lines
9.0 KiB
C++

// RTTI support internals for -*- C++ -*-
// Copyright (C) 1994, 1995, 1996, 1998, 1999, 2000 Free Software Foundation
#include "typeinfo"
#include <cstddef>
// Class declarations shared between the typeinfo implementation files.
#if !defined(__GXX_ABI_VERSION) || __GXX_ABI_VERSION < 100
// original (old) abi
// type_info for a class with no base classes (or an enum).
struct __user_type_info : public std::type_info {
__user_type_info (const char *n) : type_info (n) {}
// If our type can be upcast to a public and unambiguous base, then return
// non-zero and set RES to point to the base object. OBJ points to the throw
// object and can be NULL, if there is no object to adjust.
int upcast (const type_info &target, void *obj, void **res) const;
// If our type can be dynamicly cast to the target type, then return
// pointer to the target object. OBJ is the pointer to the most derived
// type and cannot be NULL. SUBTYPE and SUBOBJ indicate the static type
// base object from whence we came, it cannot be NULL. SUBTYPE cannot be
// the same as TARGET. TARGET cannot be a base of SUBTYPE.
// BOFF indicates how SUBTYPE is related to TARGET.
// BOFF >= 0, there is only one public non-virtual SUBTYPE base at offset
// BOFF, and there are no public virtual SUBTYPE bases.
// Therefore check if SUBOBJ is at offset BOFF when we find a target
// BOFF == -1, SUBTYPE occurs as multiple public virtual or non-virtual bases.
// Lazily search all the bases of TARGET.
// BOFF == -2, SUBTYPE is not a public base.
// BOFF == -3, SUBTYPE occurs as multiple public non-virtual bases.
// Lazily search the non-virtual bases of TARGET.
// For backwards compatibility set BOFF to -1, that is the safe "unknown"
// value. We do not care about SUBTYPES as private bases of TARGET, as they
// can never succeed as downcasts, only as crosscasts -- and then only if
// they are virtual. This is more complicated that it might seem.
void *dyncast (int boff,
const type_info &target, void *obj,
const type_info &subtype, void *subobj) const;
// non_virtual_base_type is used to indicate that a base class is via a
// non-virtual access path.
static const type_info *const nonvirtual_base_type
= static_cast <const type_info *> (0) + 1;
// sub_kind tells us about how a base object is contained within a derived
// object. We often do this lazily, hence the UNKNOWN value. At other times
// we may use NOT_CONTAINED to mean not publicly contained.
enum sub_kind
{
unknown = 0, // we have no idea
not_contained, // not contained within us (in some
// circumstances this might mean not contained
// publicly)
contained_ambig, // contained ambiguously
contained_mask = 4, // contained within us
contained_virtual_mask = 1, // via a virtual path
contained_public_mask = 2, // via a public path
contained_private = contained_mask,
contained_public = contained_mask | contained_public_mask
};
// some predicate functions for sub_kind
static inline bool contained_p (sub_kind access_path)
{
return access_path >= contained_mask;
}
static inline bool contained_public_p (sub_kind access_path)
{
return access_path >= contained_public;
}
static inline bool contained_nonpublic_p (sub_kind access_path)
{
return (access_path & contained_public) == contained_mask;
}
static inline bool contained_nonvirtual_p (sub_kind access_path)
{
return (access_path & (contained_mask | contained_virtual_mask))
== contained_mask;
}
static inline bool contained_virtual_p (sub_kind access_path)
{
return (access_path & (contained_mask | contained_virtual_mask))
== (contained_mask | contained_virtual_mask);
}
struct upcast_result
{
void *target_obj; // pointer to target object or NULL (init NULL)
sub_kind whole2target; // path from most derived object to target
const type_info *base_type; // where we found the target, (init NULL)
// if in vbase the __user_type_info of vbase)
// if a non-virtual base then 1
// else NULL
public:
upcast_result ()
:target_obj (NULL), whole2target (unknown), base_type (NULL)
{}
};
struct dyncast_result
{
void *target_obj; // pointer to target object or NULL (init NULL)
sub_kind whole2target; // path from most derived object to target
sub_kind whole2sub; // path from most derived object to sub object
sub_kind target2sub; // path from target to sub object
public:
dyncast_result ()
:target_obj (NULL), whole2target (unknown),
whole2sub (unknown), target2sub (unknown)
{}
};
public:
// Helper for upcast. See if TARGET is us, or one of our bases. ACCESS_PATH
// gives the access from the start object. Return TRUE if we know the catch
// fails.
virtual bool do_upcast (sub_kind access_path,
const type_info &target, void *obj,
upcast_result &__restrict result) const;
// Helper for dyncast. BOFF indicates how the SUBTYPE is related to TARGET.
// ACCESS_PATH indicates the access from the most derived object. It is
// used to prune the DAG walk. All information about what we find is put
// into RESULT. Return true, if the match we have found is ambiguous.
virtual bool do_dyncast (int boff, sub_kind access_path,
const type_info &target, void *obj,
const type_info &subtype, void *subptr,
dyncast_result &__restrict result) const;
public:
// Indicate whether SUBPTR of type SUBTYPE is contained publicly within
// OBJPTR. OBJPTR points to this base object. BOFF indicates how SUBTYPE
// objects might be contained within this type. If SUBPTR is one of our
// SUBTYPE bases, indicate virtuality. Returns not_contained for non
// containment or private containment.
sub_kind find_public_subobj (int boff, const type_info &subtype,
void *objptr, void *subptr) const
{
if (boff >= 0)
return ((char *)subptr - (char *)objptr) == boff
? contained_public : not_contained;
if (boff == -2)
return not_contained;
return do_find_public_subobj (boff, subtype, objptr, subptr);
}
public:
// Helper for find_subobj. BOFF indicates how SUBTYPE bases are inherited by
// the type started from -- which is not necessarily the current type.
// OBJPTR points to the current base.
virtual sub_kind do_find_public_subobj (int boff, const type_info &subtype,
void *objptr, void *subptr) const;
};
// type_info for a class with one public, nonvirtual base class.
class __si_type_info : public __user_type_info {
const __user_type_info &base;
public:
__si_type_info (const char *n, const __user_type_info &b)
: __user_type_info (n), base (b) { }
private:
virtual bool do_upcast (sub_kind access_path,
const type_info &target, void *obj,
upcast_result &__restrict result) const;
virtual bool do_dyncast (int boff, sub_kind access_path,
const type_info &target, void *obj,
const type_info &subtype, void *subptr,
dyncast_result &__restrict result) const;
virtual sub_kind do_find_public_subobj (int boff, const type_info &subtype,
void *objptr, void *subptr) const;
};
// type_info for a general class.
#include <climits>
#if INT_MAX == 2147483647
typedef int myint32;
#elif SHRT_MAX == 2147483647
typedef short myint32;
#elif SCHAR_MAX == 2147483647
typedef signed char myint32;
#elif LONG_MAX == 2147483647
typedef long myint32;
#else
# error "No 32-bit data type?"
#endif
struct __class_type_info : public __user_type_info {
enum access { PUBLIC = 1, PROTECTED = 2, PRIVATE = 3 };
struct base_info {
const __user_type_info *base;
myint32 offset: 29;
bool is_virtual: 1;
enum access access: 2;
};
const base_info *base_list;
std::size_t n_bases;
__class_type_info (const char *name, const base_info *bl, std::size_t bn)
: __user_type_info (name), base_list (bl), n_bases (bn) {}
public:
virtual bool do_upcast (sub_kind access_path,
const type_info &target, void *obj,
upcast_result &__restrict result) const;
virtual bool do_dyncast (int boff, sub_kind access_path,
const type_info &target, void *obj,
const type_info &subtype, void *subptr,
dyncast_result &__restrict result) const;
virtual sub_kind do_find_public_subobj (int boff, const type_info &subtype,
void *objptr, void *subptr) const;
};
#else
// new abi
#include <cxxabi.h>
#endif