bridges/source/cpp_uno/gcc3_macosx_intel/except.cxx | 166 ++++++++++---------- 1 file changed, 83 insertions(+), 83 deletions(-)
New commits: commit 5272f275d02344922b22a43b7c5cd2bb72a47e63 Author: Stephan Bergmann <sberg...@redhat.com> Date: Fri Aug 30 07:56:27 2013 +0200 Make RTTI creation work for libc++ Unlike libstdc++.dylib, libc++abi.dylib no longer exports the type info for std::type_info, but the layout of the __cxxabiv1::__*_type_info classes is controlled by the Generic C++ ABI anyway, so consolidate to a single approach that works across all versions. Change-Id: Ic68f2386261bae4a4349ad646590cc15c768f04e diff --git a/bridges/source/cpp_uno/gcc3_macosx_intel/except.cxx b/bridges/source/cpp_uno/gcc3_macosx_intel/except.cxx index f51cb75..0c31eed 100644 --- a/bridges/source/cpp_uno/gcc3_macosx_intel/except.cxx +++ b/bridges/source/cpp_uno/gcc3_macosx_intel/except.cxx @@ -17,92 +17,105 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ +#include "sal/config.h" +#include <cassert> +#include <new> #include <stdio.h> +#include <string.h> +#include <typeinfo> + #include <dlfcn.h> + +// MacOSX10.4u.sdk/usr/include/c++/4.0.0/cxxabi.h defined +// __cxxabiv1::__class_type_info and __cxxabiv1::__si_class_type_info but +// MacOSX10.7.sdk/usr/include/cxxabi.h no longer does: #if MACOSX_SDK_VERSION < 1070 #include <cxxabi.h> -#else -#include <typeinfo> #endif -#include <boost/unordered_map.hpp> - -#include <rtl/strbuf.hxx> -#include <rtl/ustrbuf.hxx> -#include <osl/diagnose.h> -#include <osl/mutex.hxx> -#include <com/sun/star/uno/genfunc.hxx> +#include "boost/static_assert.hpp" +#include "boost/unordered_map.hpp" #include "com/sun/star/uno/RuntimeException.hpp" -#include <typelib/typedescription.hxx> -#include <uno/any2.h> +#include "com/sun/star/uno/genfunc.hxx" +#include "osl/diagnose.h" +#include "osl/mutex.hxx" +#include "rtl/strbuf.hxx" +#include "rtl/ustrbuf.hxx" +#include "typelib/typedescription.h" +#include "uno/any2.h" #include "share.hxx" - -using namespace ::std; using namespace ::osl; -using namespace ::rtl; using namespace ::com::sun::star::uno; -#if MACOSX_SDK_VERSION < 1070 -using namespace ::__cxxabiv1; -#endif - -namespace CPPU_CURRENT_NAMESPACE -{ -#ifndef _LIBCPP_VERSION +namespace CPPU_CURRENT_NAMESPACE { -#if MACOSX_SDK_VERSION >= 1070 - -// MacOSX10.4u.sdk/usr/include/c++/4.0.0/cxxabi.h defined -// __cxxabiv1::__class_type_info and __cxxabiv1::__si_class_type_info but -// MacOSX10.7.sdk/usr/include/cxxabi.h no longer does, so instances of those -// classes need to be created manually: +namespace { -// std::type_info defined in <typeinfo> offers a protected ctor: -struct FAKE_type_info: public std::type_info { - FAKE_type_info(char const * name): type_info(name) {} +struct Fake_type_info { + virtual ~Fake_type_info() {} + char const * name; }; -// Modeled after __cxxabiv1::__si_class_type_info defined in -// MacOSX10.4u.sdk/usr/include/c++/4.0.0/cxxabi.h (i.e., -// abi::__si_class_type_info documented at -// <http://www.codesourcery.com/public/cxx-abi/abi.html#rtti>): -struct FAKE_si_class_type_info: public FAKE_type_info { - FAKE_si_class_type_info(char const * name, std::type_info const * theBase): - FAKE_type_info(name), base(theBase) {} +struct Fake_class_type_info: Fake_type_info {}; - std::type_info const * base; - // actually a __cxxabiv1::__class_type_info pointer +#if MACOSX_SDK_VERSION < 1070 +BOOST_STATIC_ASSERT( + sizeof (Fake_class_type_info) == sizeof (__cxxabiv1::__class_type_info)); +#endif + +struct Fake_si_class_type_info: Fake_class_type_info { + void const * base; }; +#if MACOSX_SDK_VERSION < 1070 +BOOST_STATIC_ASSERT( + sizeof (Fake_si_class_type_info) + == sizeof (__cxxabiv1::__si_class_type_info)); +#endif + struct Base {}; struct Derived: Base {}; -std::type_info * create_FAKE_class_type_info(char const * name) { - std::type_info * p = new FAKE_type_info(name); - // cxxabiv1::__class_type_info has no data members in addition to - // std::type_info - *reinterpret_cast< void ** >(p) = *reinterpret_cast< void * const * >( +std::type_info * createFake_class_type_info(char const * name) { + char * buf = new char[sizeof (Fake_class_type_info)]; +#if MACOSX_SDK_VERSION < 1070 + assert( + dynamic_cast<__cxxabiv1::__class_type_info const *>(&typeid(Base)) + != 0); +#endif + *reinterpret_cast<void **>(buf) = *reinterpret_cast<void * const *>( &typeid(Base)); - // copy correct __cxxabiv1::__class_type_info vtable into place - return p; + // copy __cxxabiv1::__class_type_info vtable into place + Fake_class_type_info * fake = reinterpret_cast<Fake_class_type_info *>(buf); + fake->name = name; + return reinterpret_cast<std::type_info *>( + static_cast<Fake_type_info *>(fake)); } -std::type_info * create_FAKE_si_class_type_info( +std::type_info * createFake_si_class_type_info( char const * name, std::type_info const * base) { - std::type_info * p = new FAKE_si_class_type_info(name, base); - *reinterpret_cast< void ** >(p) = *reinterpret_cast< void * const * >( + char * buf = new char[sizeof (Fake_si_class_type_info)]; +#if MACOSX_SDK_VERSION < 1070 + assert( + dynamic_cast<__cxxabiv1::__si_class_type_info const *>(&typeid(Derived)) + != 0); +#endif + *reinterpret_cast<void **>(buf) = *reinterpret_cast<void * const *>( &typeid(Derived)); - // copy correct __cxxabiv1::__si_class_type_info vtable into place - return p; + // copy __cxxabiv1::__si_class_type_info vtable into place + Fake_si_class_type_info * fake + = reinterpret_cast<Fake_si_class_type_info *>(buf); + fake->name = name; + fake->base = base; + return reinterpret_cast<std::type_info *>( + static_cast<Fake_type_info *>(fake)); } -#endif - -#endif +} void dummy_can_throw_anything( char const * ) { @@ -149,7 +162,7 @@ static OUString toUNOname( char const * p ) SAL_THROW(()) //================================================================================================== class RTTI { - typedef boost::unordered_map< OUString, type_info *, OUStringHash > t_rtti_map; + typedef boost::unordered_map< OUString, std::type_info *, OUStringHash > t_rtti_map; Mutex m_mutex; t_rtti_map m_rttis; @@ -161,7 +174,7 @@ public: RTTI() SAL_THROW(()); ~RTTI() SAL_THROW(()); - type_info * getRTTI( typelib_CompoundTypeDescription * ) SAL_THROW(()); + std::type_info * getRTTI( typelib_CompoundTypeDescription * ) SAL_THROW(()); }; //__________________________________________________________________________________________________ RTTI::RTTI() SAL_THROW(()) @@ -175,9 +188,9 @@ RTTI::~RTTI() SAL_THROW(()) } //__________________________________________________________________________________________________ -type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr ) SAL_THROW(()) +std::type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr ) SAL_THROW(()) { - type_info * rtti; + std::type_info * rtti; OUString const & unoName = *(OUString const *)&pTypeDescr->aBase.pTypeName; @@ -200,11 +213,11 @@ type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr ) SAL_THR buf.append( 'E' ); OString symName( buf.makeStringAndClear() ); - rtti = (type_info *)dlsym( m_hApp, symName.getStr() ); + rtti = (std::type_info *)dlsym( m_hApp, symName.getStr() ); if (rtti) { - pair< t_rtti_map::iterator, bool > insertion( + std::pair< t_rtti_map::iterator, bool > insertion( m_rttis.insert( t_rtti_map::value_type( unoName, rtti ) ) ); SAL_WARN_IF( !insertion.second, "bridges", @@ -216,46 +229,33 @@ type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr ) SAL_THR t_rtti_map::const_iterator iFind2( m_generatedRttis.find( unoName ) ); if (iFind2 == m_generatedRttis.end()) { -#ifndef _LIBCPP_VERSION // we must generate it ! // symbol and rtti-name is nearly identical, // the symbol is prefixed with _ZTI - char const * rttiName = symName.getStr() +4; + char * rttiName = strdup(symName.getStr() + 4); + if (rttiName == 0) { + throw std::bad_alloc(); + } #if OSL_DEBUG_LEVEL > 1 fprintf( stderr,"generated rtti for %s\n", rttiName ); #endif if (pTypeDescr->pBaseTypeDescription) { // ensure availability of base - type_info * base_rtti = getRTTI( + std::type_info * base_rtti = getRTTI( (typelib_CompoundTypeDescription *)pTypeDescr->pBaseTypeDescription ); -#if MACOSX_SDK_VERSION < 1070 - rtti = new __si_class_type_info( - strdup( rttiName ), (__class_type_info *)base_rtti ); -#else - rtti = create_FAKE_si_class_type_info( - strdup( rttiName ), base_rtti ); -#endif + rtti = createFake_si_class_type_info(rttiName, base_rtti); } else { - // this class has no base class -#if MACOSX_SDK_VERSION < 1070 - rtti = new __class_type_info( strdup( rttiName ) ); -#else - rtti = create_FAKE_class_type_info( strdup( rttiName ) ); -#endif + rtti = createFake_class_type_info(rttiName); } - pair< t_rtti_map::iterator, bool > insertion( + std::pair< t_rtti_map::iterator, bool > insertion( m_generatedRttis.insert( t_rtti_map::value_type( unoName, rtti ) ) ); SAL_WARN_IF( !insertion.second, "bridges", "inserting new generated rtti failed" ); -#else - OSL_FAIL("Cannot generate type_infos with libc++, sigh"); - return NULL; -#endif } else // taking already generated rtti { @@ -297,7 +297,7 @@ void raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp ) fprintf( stderr, "> uno exception occurred: %s\n", cstr.getStr() ); #endif void * pCppExc; - type_info * rtti; + std::type_info * rtti; { // construct cpp exception object @@ -332,7 +332,7 @@ void raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp ) #endif } } - rtti = (type_info *)s_rtti->getRTTI( (typelib_CompoundTypeDescription *) pTypeDescr ); + rtti = s_rtti->getRTTI( (typelib_CompoundTypeDescription *) pTypeDescr ); TYPELIB_DANGER_RELEASE( pTypeDescr ); OSL_ENSURE( rtti, "### no rtti for throwing exception!" ); if (! rtti) _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits