Author: theraven
Date: Tue Mar 20 17:58:15 2012
New Revision: 233235
URL: http://svn.freebsd.org/changeset/base/233235

Log:
  Import new version of libcxxrt.  Now works correctly with libobjc2 to 
implement
  the unified exception model for Objective-C++.
  
  Approved by:  dim (mentor)

Deleted:
  head/contrib/libcxxrt/typeinfo
Modified:
  head/contrib/libcxxrt/dynamic_cast.cc
  head/contrib/libcxxrt/exception.cc
  head/contrib/libcxxrt/typeinfo.h
  head/lib/libcxxrt/Version.map
Directory Properties:
  head/contrib/libcxxrt/   (props changed)

Modified: head/contrib/libcxxrt/dynamic_cast.cc
==============================================================================
--- head/contrib/libcxxrt/dynamic_cast.cc       Tue Mar 20 17:43:30 2012        
(r233234)
+++ head/contrib/libcxxrt/dynamic_cast.cc       Tue Mar 20 17:58:15 2012        
(r233235)
@@ -46,9 +46,65 @@ struct vtable_header
  */
 #define ADD_TO_PTR(x, off) (__typeof__(x))(((char*)x) + off)
 
-bool __class_type_info::can_cast_to(const struct __class_type_info *other) 
const
+bool std::type_info::__do_catch(std::type_info const *ex_type,
+                                void **exception_object,
+                                unsigned int outer) const
 {
-    return this == other;
+       const type_info *type = this;
+
+       if (type == ex_type)
+       {
+               return true;
+       }
+       if (const __class_type_info *cti = dynamic_cast<const __class_type_info 
*>(type))
+       {
+               return ex_type->__do_upcast(cti, exception_object);
+       }
+       return false;
+}
+
+bool __pbase_type_info::__do_catch(std::type_info const *ex_type,
+                                   void **exception_object,
+                                   unsigned int outer) const
+{
+       if (ex_type == this)
+       {
+               return true;
+       }
+       if (!ex_type->__is_pointer_p())
+       {
+               // Can't catch a non-pointer type in a pointer catch
+               return false;
+       }
+
+       if (!(outer & 1))
+       {
+               // If the low bit is cleared on this means that we've gone
+               // through a pointer that is not const qualified.
+               return false;
+       }
+       // Clear the low bit on outer if we're not const qualified.
+       if (!(__flags & __const_mask))
+       {
+               outer &= ~1;
+       }
+
+       const __pbase_type_info *ptr_type =
+               static_cast<const __pbase_type_info*>(ex_type);
+
+       if (ptr_type->__flags & ~__flags)
+       {
+               // Handler pointer is less qualified
+               return false;
+       }
+
+       // Special case for void* handler.  
+       if(*__pointee == typeid(void))
+       {
+               return true;
+       }
+
+       return __pointee->__do_catch(ptr_type->__pointee, exception_object, 
outer);
 }
 
 void *__class_type_info::cast_to(void *obj, const struct __class_type_info 
*other) const
@@ -60,12 +116,6 @@ void *__class_type_info::cast_to(void *o
        return 0;
 }
 
-
-bool __si_class_type_info::can_cast_to(const struct __class_type_info *other) 
const
-{
-    return this == other || __base_type->can_cast_to(other);
-}
-
 void *__si_class_type_info::cast_to(void *obj, const struct __class_type_info 
*other) const
 {
        if (this == other)
@@ -74,31 +124,32 @@ void *__si_class_type_info::cast_to(void
        }
        return __base_type->cast_to(obj, other);
 }
-
-
-bool __vmi_class_type_info::can_cast_to(const struct __class_type_info *other) 
const
+bool __si_class_type_info::__do_upcast(const __class_type_info *target,
+                                     void **thrown_object) const
 {
-       if (this == other)
+       if (this == target)
        {
                return true;
        }
-       for (unsigned int i=0 ; i<__base_count ; i++)
-       {
-               const __base_class_type_info *info = &__base_info[i];
-        if(info->isPublic() && info->__base_type->can_cast_to(other))
-        {
-            return true;
-        }
-       }
-       return false;
+       return __base_type->__do_upcast(target, thrown_object);
 }
 
 void *__vmi_class_type_info::cast_to(void *obj, const struct __class_type_info 
*other) const
 {
-       if (this == other)
+       if (__do_upcast(other, &obj))
        {
                return obj;
        }
+       return 0;
+}
+
+bool __vmi_class_type_info::__do_upcast(const __class_type_info *target,
+                                     void **thrown_object) const
+{
+       if (this == target)
+       {
+               return true;
+       }
        for (unsigned int i=0 ; i<__base_count ; i++)
        {
                const __base_class_type_info *info = &__base_info[i];
@@ -111,6 +162,7 @@ void *__vmi_class_type_info::cast_to(voi
                // virtual table of the virtual base offset for the virtual base
                // referenced (negative).'
 
+               void *obj = *thrown_object;
                if (info->isVirtual())
                {
                        // Object's vtable
@@ -121,18 +173,17 @@ void *__vmi_class_type_info::cast_to(voi
                }
                void *cast = ADD_TO_PTR(obj, offset);
 
-               if (info->__base_type == other)
+               if (info->__base_type == target ||
+                   (info->__base_type->__do_upcast(target, &cast)))
                {
-                       return cast;
-               }
-               if ((cast = info->__base_type->cast_to(cast, other)))
-               {
-                       return cast;
+                       *thrown_object = cast;
+                       return true;
                }
        }
        return 0;
 }
 
+
 /**
  * ABI function used to implement the dynamic_cast<> operator.  Some cases of
  * this operator are implemented entirely in the compiler (e.g. to void*).

Modified: head/contrib/libcxxrt/exception.cc
==============================================================================
--- head/contrib/libcxxrt/exception.cc  Tue Mar 20 17:43:30 2012        
(r233234)
+++ head/contrib/libcxxrt/exception.cc  Tue Mar 20 17:58:15 2012        
(r233235)
@@ -847,14 +847,11 @@ static bool check_type_signature(__cxa_e
                                  const std::type_info *type,
                                  void *&adjustedPtr)
 {
-       // TODO: For compatibility with the GNU implementation, we should move 
this
-       // out into a __do_catch() virtual function in std::type_info
        void *exception_ptr = (void*)(ex+1);
-    const std::type_info *ex_type = ex->exceptionType;
+       const std::type_info *ex_type = ex->exceptionType;
 
-       const __pointer_type_info *ptr_type =
-               dynamic_cast<const __pointer_type_info*>(ex_type);
-       if (0 != ptr_type)
+       bool is_ptr = ex_type->__is_pointer_p();
+       if (is_ptr)
        {
                exception_ptr = *(void**)exception_ptr;
        }
@@ -862,11 +859,6 @@ static bool check_type_signature(__cxa_e
        //
        // Note: A 0 here is a catchall, not a cleanup, so we return true to
        // indicate that we found a catch.
-       //
-       // TODO: Provide a class for matching against foreign exceptions.  This 
is
-       // already done in libobjc2, allowing C++ exceptions to be boxed as
-       // Objective-C objects.  We should do something similar, allowing 
foreign
-       // exceptions to be wrapped in a C++ exception and delivered.
        if (0 == type)
        {
                if (ex)
@@ -878,28 +870,6 @@ static bool check_type_signature(__cxa_e
 
        if (0 == ex) { return false; }
 
-       const __pointer_type_info *target_ptr_type =
-               dynamic_cast<const __pointer_type_info*>(type);
-
-       if (0 != ptr_type && 0 != target_ptr_type)
-       {
-               if (ptr_type->__flags & ~target_ptr_type->__flags)
-               {
-                       // Handler pointer is less qualified
-                       return false;
-               }
-
-               // Special case for void* handler.  
-               if(*target_ptr_type->__pointee == typeid(void))
-               {
-                       adjustedPtr = exception_ptr;
-                       return true;
-               }
-
-               ex_type = ptr_type->__pointee;
-               type = target_ptr_type->__pointee;
-       }
-
        // If the types are the same, no casting is needed.
        if (*type == *ex_type)
        {
@@ -907,18 +877,13 @@ static bool check_type_signature(__cxa_e
                return true;
        }
 
-       const __class_type_info *cls_type =
-               dynamic_cast<const __class_type_info*>(ex_type);
-       const __class_type_info *target_cls_type =
-               dynamic_cast<const __class_type_info*>(type);
-
-       if (0 != cls_type &&
-               0 != target_cls_type &&
-               cls_type->can_cast_to(target_cls_type))
+
+       if (type->__do_catch(ex_type, &exception_ptr, 1))
        {
-               adjustedPtr = cls_type->cast_to(exception_ptr, target_cls_type);
+               adjustedPtr = exception_ptr;
                return true;
        }
+
        return false;
 }
 /**

Modified: head/contrib/libcxxrt/typeinfo.h
==============================================================================
--- head/contrib/libcxxrt/typeinfo.h    Tue Mar 20 17:43:30 2012        
(r233234)
+++ head/contrib/libcxxrt/typeinfo.h    Tue Mar 20 17:58:15 2012        
(r233235)
@@ -26,7 +26,86 @@
 
 #include <stddef.h>
 #include "abi_namespace.h"
-#include "typeinfo"
+
+namespace ABI_NAMESPACE
+{
+       struct __class_type_info;
+}
+namespace std
+{
+       /**
+         * Standard type info class.  The layout of this class is specified by 
the
+         * ABI.  The layout of the vtable is not, but is intended to be
+         * compatible with the GNU ABI.
+         *
+         * Unlike the GNU version, the vtable layout is considered 
semi-private.
+         */
+       class type_info
+       {
+               public:
+               /**
+                * Virtual destructor.  This class must have one virtual 
function to
+                * ensure that it has a vtable.
+                */
+               virtual ~type_info();
+               bool operator==(const type_info &) const;
+               bool operator!=(const type_info &) const;
+               bool before(const type_info &) const;
+               const char* name() const;
+               type_info();
+               private:
+               type_info(const type_info& rhs);
+               type_info& operator= (const type_info& rhs);
+               const char *__type_name;
+               /*
+                * The following functions are in this order to match the
+                * vtable layout of libsupc++.  This allows libcxxrt to be used
+                * with libraries that depend on this.
+                *
+                * These functions are in the public headers for libstdc++, so
+                * we have to assume that someone will probably call them and
+                * expect them to work.  Their names must also match the names 
used in
+                * libsupc++, so that code linking against this library can 
subclass
+                * type_info and correctly fill in the values in the vtables.
+                */
+               public:
+               /**
+                * Catch function.  Allows external libraries to implement
+                * their own basic types.  This is used, for example, in the
+                * GNUstep Objective-C runtime to allow Objective-C types to be
+                * caught in G++ catch blocks.
+                *
+                * The outer parameter indicates the number of outer pointers
+                * in the high bits.  The low bit indicates whether the
+                * pointers are const qualified.
+                */
+               virtual bool __do_catch(const type_info *thrown_type,
+                                       void **thrown_object,
+                                       unsigned outer) const;
+               /**
+                * Performs an upcast.  This is used in exception handling to
+                * cast from subclasses to superclasses.  If the upcast is
+                * possible, it returns true and adjusts the pointer.  If the
+                * upcast is not possible, it returns false and does not adjust
+                * the pointer.
+                */
+               virtual bool __do_upcast(
+                               const ABI_NAMESPACE::__class_type_info *target,
+                               void **thrown_object) const
+               {
+                       return false;
+               }
+               /**
+                * Returns true if this is some pointer type, false otherwise.
+                */
+               virtual bool __is_pointer_p() const { return false; }
+               /**
+                * Returns true if this is some function type, false otherwise.
+                */
+               virtual bool __is_function_p() const { return false; }
+       };
+}
+
 
 namespace ABI_NAMESPACE
 {
@@ -50,6 +129,7 @@ namespace ABI_NAMESPACE
        struct __function_type_info : public std::type_info
        {
                virtual ~__function_type_info();
+               virtual bool __is_function_p() const { return true; }
        };
        /**
         * Type info for enums.
@@ -68,13 +148,12 @@ namespace ABI_NAMESPACE
                /**
                 * Function implementing dynamic casts.
                 */
-               virtual void *cast_to(void *obj,
-                                     const struct __class_type_info *other) 
const;
-               /**
-                * Function returning whether a cast from this type to another 
type is
-                * possible.
-                */
-               virtual bool can_cast_to(const struct __class_type_info *other) 
const;
+               virtual void *cast_to(void *obj, const struct __class_type_info 
*other) const;
+               virtual bool __do_upcast(const __class_type_info *target,
+                                      void **thrown_object) const
+               {
+                       return this == target;
+               }
        };
 
        /**
@@ -85,8 +164,10 @@ namespace ABI_NAMESPACE
        {
                virtual ~__si_class_type_info();
                const __class_type_info *__base_type;
+               virtual bool __do_upcast(
+                               const ABI_NAMESPACE::__class_type_info *target,
+                               void **thrown_object) const;
                virtual void *cast_to(void *obj, const struct __class_type_info 
*other) const;
-        virtual bool can_cast_to(const struct __class_type_info *other) const;
        };
 
        /**
@@ -166,8 +247,10 @@ namespace ABI_NAMESPACE
                        /** The class is diamond shaped. */
                        __diamond_shaped_mask = 0x2
                };
+               virtual bool __do_upcast(
+                               const ABI_NAMESPACE::__class_type_info *target,
+                               void **thrown_object) const;
                virtual void *cast_to(void *obj, const struct __class_type_info 
*other) const;
-        virtual bool can_cast_to(const struct __class_type_info *other) const;
        };
 
        /**
@@ -201,6 +284,10 @@ namespace ABI_NAMESPACE
                        /** Pointer is a pointer to a member of an incomplete 
class. */
                        __incomplete_class_mask = 0x10
                };
+               virtual bool __is_pointer_p() const { return true; }
+               virtual bool __do_catch(const type_info *thrown_type,
+                                       void **thrown_object,
+                                       unsigned outer) const;
        };
 
        /**

Modified: head/lib/libcxxrt/Version.map
==============================================================================
--- head/lib/libcxxrt/Version.map       Tue Mar 20 17:43:30 2012        
(r233234)
+++ head/lib/libcxxrt/Version.map       Tue Mar 20 17:58:15 2012        
(r233235)
@@ -301,6 +301,11 @@ CXXRT_1.0 {
         "typeinfo name for std::exception";
         "typeinfo name for std::type_info";
 
+        "std::type_info::__is_function_p() const";
+        "std::type_info::__do_upcast(__cxxabiv1::__class_type_info const*, 
void**) const";
+        "std::type_info::__is_pointer_p() const";
+
+
         "operator delete[](void*)";
         "operator delete(void*)";
         "operator new[](unsigned long)";
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to