194e3ee44SDavid Chisnall /* 294e3ee44SDavid Chisnall * Copyright 2010-2011 PathScale, Inc. All rights reserved. 394e3ee44SDavid Chisnall * 494e3ee44SDavid Chisnall * Redistribution and use in source and binary forms, with or without 594e3ee44SDavid Chisnall * modification, are permitted provided that the following conditions are met: 694e3ee44SDavid Chisnall * 794e3ee44SDavid Chisnall * 1. Redistributions of source code must retain the above copyright notice, 894e3ee44SDavid Chisnall * this list of conditions and the following disclaimer. 994e3ee44SDavid Chisnall * 1094e3ee44SDavid Chisnall * 2. Redistributions in binary form must reproduce the above copyright notice, 1194e3ee44SDavid Chisnall * this list of conditions and the following disclaimer in the documentation 1294e3ee44SDavid Chisnall * and/or other materials provided with the distribution. 1394e3ee44SDavid Chisnall * 1494e3ee44SDavid Chisnall * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS 1594e3ee44SDavid Chisnall * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 1694e3ee44SDavid Chisnall * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 1794e3ee44SDavid Chisnall * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 1894e3ee44SDavid Chisnall * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 1994e3ee44SDavid Chisnall * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 2094e3ee44SDavid Chisnall * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 2194e3ee44SDavid Chisnall * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 2294e3ee44SDavid Chisnall * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 2394e3ee44SDavid Chisnall * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 2494e3ee44SDavid Chisnall * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2594e3ee44SDavid Chisnall */ 2694e3ee44SDavid Chisnall 277a984708SDavid Chisnall #include <stddef.h> 287a984708SDavid Chisnall #include "abi_namespace.h" 29c725650dSDavid Chisnall 30c725650dSDavid Chisnall namespace ABI_NAMESPACE 31c725650dSDavid Chisnall { 32c725650dSDavid Chisnall struct __class_type_info; 33c725650dSDavid Chisnall } 34c725650dSDavid Chisnall namespace std 35c725650dSDavid Chisnall { 36c725650dSDavid Chisnall /** 37c725650dSDavid Chisnall * Standard type info class. The layout of this class is specified by the 38c725650dSDavid Chisnall * ABI. The layout of the vtable is not, but is intended to be 39c725650dSDavid Chisnall * compatible with the GNU ABI. 40c725650dSDavid Chisnall * 41c725650dSDavid Chisnall * Unlike the GNU version, the vtable layout is considered semi-private. 42c725650dSDavid Chisnall */ 43c725650dSDavid Chisnall class type_info 44c725650dSDavid Chisnall { 45c725650dSDavid Chisnall public: 46c725650dSDavid Chisnall /** 47c725650dSDavid Chisnall * Virtual destructor. This class must have one virtual function to 48c725650dSDavid Chisnall * ensure that it has a vtable. 49c725650dSDavid Chisnall */ 50c725650dSDavid Chisnall virtual ~type_info(); 51c725650dSDavid Chisnall bool operator==(const type_info &) const; 52c725650dSDavid Chisnall bool operator!=(const type_info &) const; 53c725650dSDavid Chisnall bool before(const type_info &) const; 54c725650dSDavid Chisnall const char* name() const; 55c725650dSDavid Chisnall type_info(); 56c725650dSDavid Chisnall private: 57c725650dSDavid Chisnall type_info(const type_info& rhs); 58c725650dSDavid Chisnall type_info& operator= (const type_info& rhs); 59c725650dSDavid Chisnall const char *__type_name; 60c725650dSDavid Chisnall /* 61c725650dSDavid Chisnall * The following functions are in this order to match the 62c725650dSDavid Chisnall * vtable layout of libsupc++. This allows libcxxrt to be used 63c725650dSDavid Chisnall * with libraries that depend on this. 64c725650dSDavid Chisnall * 65c725650dSDavid Chisnall * These functions are in the public headers for libstdc++, so 66c725650dSDavid Chisnall * we have to assume that someone will probably call them and 67c725650dSDavid Chisnall * expect them to work. Their names must also match the names used in 68c725650dSDavid Chisnall * libsupc++, so that code linking against this library can subclass 69c725650dSDavid Chisnall * type_info and correctly fill in the values in the vtables. 70c725650dSDavid Chisnall */ 71c725650dSDavid Chisnall public: 72c725650dSDavid Chisnall /** 73*f7cb1657SDavid Chisnall * Returns true if this is some pointer type, false otherwise. 74*f7cb1657SDavid Chisnall */ __is_pointer_p()75*f7cb1657SDavid Chisnall virtual bool __is_pointer_p() const { return false; } 76*f7cb1657SDavid Chisnall /** 77*f7cb1657SDavid Chisnall * Returns true if this is some function type, false otherwise. 78*f7cb1657SDavid Chisnall */ __is_function_p()79*f7cb1657SDavid Chisnall virtual bool __is_function_p() const { return false; } 80*f7cb1657SDavid Chisnall /** 81c725650dSDavid Chisnall * Catch function. Allows external libraries to implement 82c725650dSDavid Chisnall * their own basic types. This is used, for example, in the 83c725650dSDavid Chisnall * GNUstep Objective-C runtime to allow Objective-C types to be 84c725650dSDavid Chisnall * caught in G++ catch blocks. 85c725650dSDavid Chisnall * 86c725650dSDavid Chisnall * The outer parameter indicates the number of outer pointers 87c725650dSDavid Chisnall * in the high bits. The low bit indicates whether the 88c725650dSDavid Chisnall * pointers are const qualified. 89c725650dSDavid Chisnall */ 90c725650dSDavid Chisnall virtual bool __do_catch(const type_info *thrown_type, 91c725650dSDavid Chisnall void **thrown_object, 92c725650dSDavid Chisnall unsigned outer) const; 93c725650dSDavid Chisnall /** 94c725650dSDavid Chisnall * Performs an upcast. This is used in exception handling to 95c725650dSDavid Chisnall * cast from subclasses to superclasses. If the upcast is 96c725650dSDavid Chisnall * possible, it returns true and adjusts the pointer. If the 97c725650dSDavid Chisnall * upcast is not possible, it returns false and does not adjust 98c725650dSDavid Chisnall * the pointer. 99c725650dSDavid Chisnall */ __do_upcast(const ABI_NAMESPACE::__class_type_info * target,void ** thrown_object)100c725650dSDavid Chisnall virtual bool __do_upcast( 101c725650dSDavid Chisnall const ABI_NAMESPACE::__class_type_info *target, 102c725650dSDavid Chisnall void **thrown_object) const 103c725650dSDavid Chisnall { 104c725650dSDavid Chisnall return false; 105c725650dSDavid Chisnall } 106c725650dSDavid Chisnall }; 107c725650dSDavid Chisnall } 108c725650dSDavid Chisnall 1097a984708SDavid Chisnall 1107a984708SDavid Chisnall namespace ABI_NAMESPACE 1117a984708SDavid Chisnall { 1127a984708SDavid Chisnall /** 1137a984708SDavid Chisnall * Primitive type info, for intrinsic types. 1147a984708SDavid Chisnall */ 1157a984708SDavid Chisnall struct __fundamental_type_info : public std::type_info 1167a984708SDavid Chisnall { 1177a984708SDavid Chisnall virtual ~__fundamental_type_info(); 1187a984708SDavid Chisnall }; 1197a984708SDavid Chisnall /** 1207a984708SDavid Chisnall * Type info for arrays. 1217a984708SDavid Chisnall */ 1227a984708SDavid Chisnall struct __array_type_info : public std::type_info 1237a984708SDavid Chisnall { 1247a984708SDavid Chisnall virtual ~__array_type_info(); 1257a984708SDavid Chisnall }; 1267a984708SDavid Chisnall /** 1277a984708SDavid Chisnall * Type info for functions. 1287a984708SDavid Chisnall */ 1297a984708SDavid Chisnall struct __function_type_info : public std::type_info 1307a984708SDavid Chisnall { 1317a984708SDavid Chisnall virtual ~__function_type_info(); __is_function_p__function_type_info132c725650dSDavid Chisnall virtual bool __is_function_p() const { return true; } 1337a984708SDavid Chisnall }; 1347a984708SDavid Chisnall /** 1357a984708SDavid Chisnall * Type info for enums. 1367a984708SDavid Chisnall */ 1377a984708SDavid Chisnall struct __enum_type_info : public std::type_info 1387a984708SDavid Chisnall { 1397a984708SDavid Chisnall virtual ~__enum_type_info(); 1407a984708SDavid Chisnall }; 1417a984708SDavid Chisnall 1427a984708SDavid Chisnall /** 1437a984708SDavid Chisnall * Base class for class type info. Used only for tentative definitions. 1447a984708SDavid Chisnall */ 1457a984708SDavid Chisnall struct __class_type_info : public std::type_info 1467a984708SDavid Chisnall { 1477a984708SDavid Chisnall virtual ~__class_type_info(); 1487a984708SDavid Chisnall /** 1497a984708SDavid Chisnall * Function implementing dynamic casts. 1507a984708SDavid Chisnall */ 151c725650dSDavid Chisnall virtual void *cast_to(void *obj, const struct __class_type_info *other) const; __do_upcast__class_type_info152c725650dSDavid Chisnall virtual bool __do_upcast(const __class_type_info *target, 153c725650dSDavid Chisnall void **thrown_object) const 154c725650dSDavid Chisnall { 155c725650dSDavid Chisnall return this == target; 156c725650dSDavid Chisnall } 1577a984708SDavid Chisnall }; 1587a984708SDavid Chisnall 1597a984708SDavid Chisnall /** 1607a984708SDavid Chisnall * Single-inheritance class type info. This is used for classes containing 1617a984708SDavid Chisnall * a single non-virtual base class at offset 0. 1627a984708SDavid Chisnall */ 1637a984708SDavid Chisnall struct __si_class_type_info : public __class_type_info 1647a984708SDavid Chisnall { 1657a984708SDavid Chisnall virtual ~__si_class_type_info(); 1667a984708SDavid Chisnall const __class_type_info *__base_type; 167c725650dSDavid Chisnall virtual bool __do_upcast( 168c725650dSDavid Chisnall const ABI_NAMESPACE::__class_type_info *target, 169c725650dSDavid Chisnall void **thrown_object) const; 1707a984708SDavid Chisnall virtual void *cast_to(void *obj, const struct __class_type_info *other) const; 1717a984708SDavid Chisnall }; 1727a984708SDavid Chisnall 1737a984708SDavid Chisnall /** 1747a984708SDavid Chisnall * Type info for base classes. Classes with multiple bases store an array 1757a984708SDavid Chisnall * of these, one for each superclass. 1767a984708SDavid Chisnall */ 1777a984708SDavid Chisnall struct __base_class_type_info 1787a984708SDavid Chisnall { 1797a984708SDavid Chisnall const __class_type_info *__base_type; 1807a984708SDavid Chisnall private: 1817a984708SDavid Chisnall /** 1827a984708SDavid Chisnall * The high __offset_shift bits of this store the (signed) offset 1837a984708SDavid Chisnall * of the base class. The low bits store flags from 1847a984708SDavid Chisnall * __offset_flags_masks. 1857a984708SDavid Chisnall */ 1867a984708SDavid Chisnall long __offset_flags; 1877a984708SDavid Chisnall /** 1887a984708SDavid Chisnall * Flags used in the low bits of __offset_flags. 1897a984708SDavid Chisnall */ 1907a984708SDavid Chisnall enum __offset_flags_masks 1917a984708SDavid Chisnall { 1927a984708SDavid Chisnall /** This base class is virtual. */ 1937a984708SDavid Chisnall __virtual_mask = 0x1, 1947a984708SDavid Chisnall /** This base class is public. */ 1957a984708SDavid Chisnall __public_mask = 0x2, 1967a984708SDavid Chisnall /** The number of bits reserved for flags. */ 1977a984708SDavid Chisnall __offset_shift = 8 1987a984708SDavid Chisnall }; 1997a984708SDavid Chisnall public: 2007a984708SDavid Chisnall /** 2017a984708SDavid Chisnall * Returns the offset of the base class. 2027a984708SDavid Chisnall */ offset__base_class_type_info2037a984708SDavid Chisnall long offset() const 2047a984708SDavid Chisnall { 2057a984708SDavid Chisnall return __offset_flags >> __offset_shift; 2067a984708SDavid Chisnall } 2077a984708SDavid Chisnall /** 2087a984708SDavid Chisnall * Returns the flags. 2097a984708SDavid Chisnall */ flags__base_class_type_info2107a984708SDavid Chisnall long flags() const 2117a984708SDavid Chisnall { 2127a984708SDavid Chisnall return __offset_flags & ((1 << __offset_shift) - 1); 2137a984708SDavid Chisnall } 2147a984708SDavid Chisnall /** 2157a984708SDavid Chisnall * Returns whether this is a public base class. 2167a984708SDavid Chisnall */ isPublic__base_class_type_info2177a984708SDavid Chisnall bool isPublic() const { return flags() & __public_mask; } 2187a984708SDavid Chisnall /** 2197a984708SDavid Chisnall * Returns whether this is a virtual base class. 2207a984708SDavid Chisnall */ isVirtual__base_class_type_info2217a984708SDavid Chisnall bool isVirtual() const { return flags() & __virtual_mask; } 2227a984708SDavid Chisnall }; 2237a984708SDavid Chisnall 2247a984708SDavid Chisnall /** 2257a984708SDavid Chisnall * Type info for classes with virtual bases or multiple superclasses. 2267a984708SDavid Chisnall */ 2277a984708SDavid Chisnall struct __vmi_class_type_info : public __class_type_info 2287a984708SDavid Chisnall { 2297a984708SDavid Chisnall virtual ~__vmi_class_type_info(); 2307a984708SDavid Chisnall /** Flags describing this class. Contains values from __flags_masks. */ 2317a984708SDavid Chisnall unsigned int __flags; 2327a984708SDavid Chisnall /** The number of base classes. */ 2337a984708SDavid Chisnall unsigned int __base_count; 2347a984708SDavid Chisnall /** 2357a984708SDavid Chisnall * Array of base classes - this actually has __base_count elements, not 2367a984708SDavid Chisnall * 1. 2377a984708SDavid Chisnall */ 2387a984708SDavid Chisnall __base_class_type_info __base_info[1]; 2397a984708SDavid Chisnall 2407a984708SDavid Chisnall /** 2417a984708SDavid Chisnall * Flags used in the __flags field. 2427a984708SDavid Chisnall */ 2437a984708SDavid Chisnall enum __flags_masks 2447a984708SDavid Chisnall { 2457a984708SDavid Chisnall /** The class has non-diamond repeated inheritance. */ 2467a984708SDavid Chisnall __non_diamond_repeat_mask = 0x1, 2477a984708SDavid Chisnall /** The class is diamond shaped. */ 2487a984708SDavid Chisnall __diamond_shaped_mask = 0x2 2497a984708SDavid Chisnall }; 250c725650dSDavid Chisnall virtual bool __do_upcast( 251c725650dSDavid Chisnall const ABI_NAMESPACE::__class_type_info *target, 252c725650dSDavid Chisnall void **thrown_object) const; 2537a984708SDavid Chisnall virtual void *cast_to(void *obj, const struct __class_type_info *other) const; 2547a984708SDavid Chisnall }; 2557a984708SDavid Chisnall 2567a984708SDavid Chisnall /** 2577a984708SDavid Chisnall * Base class used for both pointer and pointer-to-member type info. 2587a984708SDavid Chisnall */ 2597a984708SDavid Chisnall struct __pbase_type_info : public std::type_info 2607a984708SDavid Chisnall { 2617a984708SDavid Chisnall virtual ~__pbase_type_info(); 2627a984708SDavid Chisnall /** 2637a984708SDavid Chisnall * Flags. Values from __masks. 2647a984708SDavid Chisnall */ 2657a984708SDavid Chisnall unsigned int __flags; 2667a984708SDavid Chisnall /** 2677a984708SDavid Chisnall * The type info for the pointee. 2687a984708SDavid Chisnall */ 2697a984708SDavid Chisnall const std::type_info *__pointee; 2707a984708SDavid Chisnall 2717a984708SDavid Chisnall /** 2727a984708SDavid Chisnall * Masks used for qualifiers on the pointer. 2737a984708SDavid Chisnall */ 2747a984708SDavid Chisnall enum __masks 2757a984708SDavid Chisnall { 2767a984708SDavid Chisnall /** Pointer has const qualifier. */ 2777a984708SDavid Chisnall __const_mask = 0x1, 2787a984708SDavid Chisnall /** Pointer has volatile qualifier. */ 2797a984708SDavid Chisnall __volatile_mask = 0x2, 2807a984708SDavid Chisnall /** Pointer has restrict qualifier. */ 2817a984708SDavid Chisnall __restrict_mask = 0x4, 2827a984708SDavid Chisnall /** Pointer points to an incomplete type. */ 2837a984708SDavid Chisnall __incomplete_mask = 0x8, 2847a984708SDavid Chisnall /** Pointer is a pointer to a member of an incomplete class. */ 2857a984708SDavid Chisnall __incomplete_class_mask = 0x10 2867a984708SDavid Chisnall }; 287c725650dSDavid Chisnall virtual bool __do_catch(const type_info *thrown_type, 288c725650dSDavid Chisnall void **thrown_object, 289c725650dSDavid Chisnall unsigned outer) const; 2907a984708SDavid Chisnall }; 2917a984708SDavid Chisnall 2927a984708SDavid Chisnall /** 2937a984708SDavid Chisnall * Pointer type info. 2947a984708SDavid Chisnall */ 2957a984708SDavid Chisnall struct __pointer_type_info : public __pbase_type_info 2967a984708SDavid Chisnall { 2977a984708SDavid Chisnall virtual ~__pointer_type_info(); __is_pointer_p__pointer_type_info298*f7cb1657SDavid Chisnall virtual bool __is_pointer_p() const { return true; } 2997a984708SDavid Chisnall }; 3007a984708SDavid Chisnall 3017a984708SDavid Chisnall /** 3027a984708SDavid Chisnall * Pointer to member type info. 3037a984708SDavid Chisnall */ 3047a984708SDavid Chisnall struct __pointer_to_member_type_info : public __pbase_type_info 3057a984708SDavid Chisnall { 3067a984708SDavid Chisnall virtual ~__pointer_to_member_type_info(); 3077a984708SDavid Chisnall /** 3087a984708SDavid Chisnall * Pointer to the class containing this member. 3097a984708SDavid Chisnall */ 3107a984708SDavid Chisnall const __class_type_info *__context; 3117a984708SDavid Chisnall }; 3127a984708SDavid Chisnall 3137a984708SDavid Chisnall } 314