1232922Stheraven/* 2232922Stheraven * Copyright 2010-2011 PathScale, Inc. All rights reserved. 3232922Stheraven * 4232922Stheraven * Redistribution and use in source and binary forms, with or without 5232922Stheraven * modification, are permitted provided that the following conditions are met: 6232922Stheraven * 7232922Stheraven * 1. Redistributions of source code must retain the above copyright notice, 8232922Stheraven * this list of conditions and the following disclaimer. 9232922Stheraven * 10232922Stheraven * 2. Redistributions in binary form must reproduce the above copyright notice, 11232922Stheraven * this list of conditions and the following disclaimer in the documentation 12232922Stheraven * and/or other materials provided with the distribution. 13232922Stheraven * 14232922Stheraven * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS 15232922Stheraven * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 16232922Stheraven * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 17232922Stheraven * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 18232922Stheraven * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 19232922Stheraven * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 20232922Stheraven * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 21232922Stheraven * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 22232922Stheraven * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 23232922Stheraven * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 24232922Stheraven * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25232922Stheraven */ 26232922Stheraven 27227825Stheraven#include <stddef.h> 28227825Stheraven#include "abi_namespace.h" 29227825Stheraven 30227825Stheravennamespace ABI_NAMESPACE 31227825Stheraven{ 32233233Stheraven struct __class_type_info; 33233233Stheraven} 34233233Stheravennamespace std 35233233Stheraven{ 36227825Stheraven /** 37233233Stheraven * Standard type info class. The layout of this class is specified by the 38233233Stheraven * ABI. The layout of the vtable is not, but is intended to be 39233233Stheraven * compatible with the GNU ABI. 40233233Stheraven * 41233233Stheraven * Unlike the GNU version, the vtable layout is considered semi-private. 42233233Stheraven */ 43233233Stheraven class type_info 44233233Stheraven { 45233233Stheraven public: 46233233Stheraven /** 47233233Stheraven * Virtual destructor. This class must have one virtual function to 48233233Stheraven * ensure that it has a vtable. 49233233Stheraven */ 50233233Stheraven virtual ~type_info(); 51233233Stheraven bool operator==(const type_info &) const; 52233233Stheraven bool operator!=(const type_info &) const; 53233233Stheraven bool before(const type_info &) const; 54233233Stheraven const char* name() const; 55233233Stheraven type_info(); 56233233Stheraven private: 57233233Stheraven type_info(const type_info& rhs); 58233233Stheraven type_info& operator= (const type_info& rhs); 59233233Stheraven const char *__type_name; 60233233Stheraven /* 61233233Stheraven * The following functions are in this order to match the 62233233Stheraven * vtable layout of libsupc++. This allows libcxxrt to be used 63233233Stheraven * with libraries that depend on this. 64233233Stheraven * 65233233Stheraven * These functions are in the public headers for libstdc++, so 66233233Stheraven * we have to assume that someone will probably call them and 67233233Stheraven * expect them to work. Their names must also match the names used in 68233233Stheraven * libsupc++, so that code linking against this library can subclass 69233233Stheraven * type_info and correctly fill in the values in the vtables. 70233233Stheraven */ 71233233Stheraven public: 72233233Stheraven /** 73245302Stheraven * Returns true if this is some pointer type, false otherwise. 74245302Stheraven */ 75245302Stheraven virtual bool __is_pointer_p() const { return false; } 76245302Stheraven /** 77245302Stheraven * Returns true if this is some function type, false otherwise. 78245302Stheraven */ 79245302Stheraven virtual bool __is_function_p() const { return false; } 80245302Stheraven /** 81233233Stheraven * Catch function. Allows external libraries to implement 82233233Stheraven * their own basic types. This is used, for example, in the 83233233Stheraven * GNUstep Objective-C runtime to allow Objective-C types to be 84233233Stheraven * caught in G++ catch blocks. 85233233Stheraven * 86233233Stheraven * The outer parameter indicates the number of outer pointers 87233233Stheraven * in the high bits. The low bit indicates whether the 88233233Stheraven * pointers are const qualified. 89233233Stheraven */ 90233233Stheraven virtual bool __do_catch(const type_info *thrown_type, 91233233Stheraven void **thrown_object, 92233233Stheraven unsigned outer) const; 93233233Stheraven /** 94233233Stheraven * Performs an upcast. This is used in exception handling to 95233233Stheraven * cast from subclasses to superclasses. If the upcast is 96233233Stheraven * possible, it returns true and adjusts the pointer. If the 97233233Stheraven * upcast is not possible, it returns false and does not adjust 98233233Stheraven * the pointer. 99233233Stheraven */ 100233233Stheraven virtual bool __do_upcast( 101233233Stheraven const ABI_NAMESPACE::__class_type_info *target, 102233233Stheraven void **thrown_object) const 103233233Stheraven { 104233233Stheraven return false; 105233233Stheraven } 106233233Stheraven }; 107233233Stheraven} 108233233Stheraven 109233233Stheraven 110233233Stheravennamespace ABI_NAMESPACE 111233233Stheraven{ 112233233Stheraven /** 113227825Stheraven * Primitive type info, for intrinsic types. 114227825Stheraven */ 115227825Stheraven struct __fundamental_type_info : public std::type_info 116227825Stheraven { 117227825Stheraven virtual ~__fundamental_type_info(); 118227825Stheraven }; 119227825Stheraven /** 120227825Stheraven * Type info for arrays. 121227825Stheraven */ 122227825Stheraven struct __array_type_info : public std::type_info 123227825Stheraven { 124227825Stheraven virtual ~__array_type_info(); 125227825Stheraven }; 126227825Stheraven /** 127227825Stheraven * Type info for functions. 128227825Stheraven */ 129227825Stheraven struct __function_type_info : public std::type_info 130227825Stheraven { 131227825Stheraven virtual ~__function_type_info(); 132233233Stheraven virtual bool __is_function_p() const { return true; } 133227825Stheraven }; 134227825Stheraven /** 135227825Stheraven * Type info for enums. 136227825Stheraven */ 137227825Stheraven struct __enum_type_info : public std::type_info 138227825Stheraven { 139227825Stheraven virtual ~__enum_type_info(); 140227825Stheraven }; 141227825Stheraven 142227825Stheraven /** 143227825Stheraven * Base class for class type info. Used only for tentative definitions. 144227825Stheraven */ 145227825Stheraven struct __class_type_info : public std::type_info 146227825Stheraven { 147227825Stheraven virtual ~__class_type_info(); 148227825Stheraven /** 149227825Stheraven * Function implementing dynamic casts. 150227825Stheraven */ 151233233Stheraven virtual void *cast_to(void *obj, const struct __class_type_info *other) const; 152233233Stheraven virtual bool __do_upcast(const __class_type_info *target, 153233233Stheraven void **thrown_object) const 154233233Stheraven { 155233233Stheraven return this == target; 156233233Stheraven } 157227825Stheraven }; 158227825Stheraven 159227825Stheraven /** 160227825Stheraven * Single-inheritance class type info. This is used for classes containing 161227825Stheraven * a single non-virtual base class at offset 0. 162227825Stheraven */ 163227825Stheraven struct __si_class_type_info : public __class_type_info 164227825Stheraven { 165227825Stheraven virtual ~__si_class_type_info(); 166227825Stheraven const __class_type_info *__base_type; 167233233Stheraven virtual bool __do_upcast( 168233233Stheraven const ABI_NAMESPACE::__class_type_info *target, 169233233Stheraven void **thrown_object) const; 170227825Stheraven virtual void *cast_to(void *obj, const struct __class_type_info *other) const; 171227825Stheraven }; 172227825Stheraven 173227825Stheraven /** 174227825Stheraven * Type info for base classes. Classes with multiple bases store an array 175227825Stheraven * of these, one for each superclass. 176227825Stheraven */ 177227825Stheraven struct __base_class_type_info 178227825Stheraven { 179227825Stheraven const __class_type_info *__base_type; 180227825Stheraven private: 181227825Stheraven /** 182227825Stheraven * The high __offset_shift bits of this store the (signed) offset 183227825Stheraven * of the base class. The low bits store flags from 184227825Stheraven * __offset_flags_masks. 185227825Stheraven */ 186227825Stheraven long __offset_flags; 187227825Stheraven /** 188227825Stheraven * Flags used in the low bits of __offset_flags. 189227825Stheraven */ 190227825Stheraven enum __offset_flags_masks 191227825Stheraven { 192227825Stheraven /** This base class is virtual. */ 193227825Stheraven __virtual_mask = 0x1, 194227825Stheraven /** This base class is public. */ 195227825Stheraven __public_mask = 0x2, 196227825Stheraven /** The number of bits reserved for flags. */ 197227825Stheraven __offset_shift = 8 198227825Stheraven }; 199227825Stheraven public: 200227825Stheraven /** 201227825Stheraven * Returns the offset of the base class. 202227825Stheraven */ 203227825Stheraven long offset() const 204227825Stheraven { 205227825Stheraven return __offset_flags >> __offset_shift; 206227825Stheraven } 207227825Stheraven /** 208227825Stheraven * Returns the flags. 209227825Stheraven */ 210227825Stheraven long flags() const 211227825Stheraven { 212227825Stheraven return __offset_flags & ((1 << __offset_shift) - 1); 213227825Stheraven } 214227825Stheraven /** 215227825Stheraven * Returns whether this is a public base class. 216227825Stheraven */ 217227825Stheraven bool isPublic() const { return flags() & __public_mask; } 218227825Stheraven /** 219227825Stheraven * Returns whether this is a virtual base class. 220227825Stheraven */ 221227825Stheraven bool isVirtual() const { return flags() & __virtual_mask; } 222227825Stheraven }; 223227825Stheraven 224227825Stheraven /** 225227825Stheraven * Type info for classes with virtual bases or multiple superclasses. 226227825Stheraven */ 227227825Stheraven struct __vmi_class_type_info : public __class_type_info 228227825Stheraven { 229227825Stheraven virtual ~__vmi_class_type_info(); 230227825Stheraven /** Flags describing this class. Contains values from __flags_masks. */ 231227825Stheraven unsigned int __flags; 232227825Stheraven /** The number of base classes. */ 233227825Stheraven unsigned int __base_count; 234227825Stheraven /** 235227825Stheraven * Array of base classes - this actually has __base_count elements, not 236227825Stheraven * 1. 237227825Stheraven */ 238227825Stheraven __base_class_type_info __base_info[1]; 239227825Stheraven 240227825Stheraven /** 241227825Stheraven * Flags used in the __flags field. 242227825Stheraven */ 243227825Stheraven enum __flags_masks 244227825Stheraven { 245227825Stheraven /** The class has non-diamond repeated inheritance. */ 246227825Stheraven __non_diamond_repeat_mask = 0x1, 247227825Stheraven /** The class is diamond shaped. */ 248227825Stheraven __diamond_shaped_mask = 0x2 249227825Stheraven }; 250233233Stheraven virtual bool __do_upcast( 251233233Stheraven const ABI_NAMESPACE::__class_type_info *target, 252233233Stheraven void **thrown_object) const; 253227825Stheraven virtual void *cast_to(void *obj, const struct __class_type_info *other) const; 254227825Stheraven }; 255227825Stheraven 256227825Stheraven /** 257227825Stheraven * Base class used for both pointer and pointer-to-member type info. 258227825Stheraven */ 259227825Stheraven struct __pbase_type_info : public std::type_info 260227825Stheraven { 261227825Stheraven virtual ~__pbase_type_info(); 262227825Stheraven /** 263227825Stheraven * Flags. Values from __masks. 264227825Stheraven */ 265227825Stheraven unsigned int __flags; 266227825Stheraven /** 267227825Stheraven * The type info for the pointee. 268227825Stheraven */ 269227825Stheraven const std::type_info *__pointee; 270227825Stheraven 271227825Stheraven /** 272227825Stheraven * Masks used for qualifiers on the pointer. 273227825Stheraven */ 274227825Stheraven enum __masks 275227825Stheraven { 276227825Stheraven /** Pointer has const qualifier. */ 277227825Stheraven __const_mask = 0x1, 278227825Stheraven /** Pointer has volatile qualifier. */ 279227825Stheraven __volatile_mask = 0x2, 280227825Stheraven /** Pointer has restrict qualifier. */ 281227825Stheraven __restrict_mask = 0x4, 282227825Stheraven /** Pointer points to an incomplete type. */ 283227825Stheraven __incomplete_mask = 0x8, 284227825Stheraven /** Pointer is a pointer to a member of an incomplete class. */ 285227825Stheraven __incomplete_class_mask = 0x10 286227825Stheraven }; 287233233Stheraven virtual bool __do_catch(const type_info *thrown_type, 288233233Stheraven void **thrown_object, 289233233Stheraven unsigned outer) const; 290227825Stheraven }; 291227825Stheraven 292227825Stheraven /** 293227825Stheraven * Pointer type info. 294227825Stheraven */ 295227825Stheraven struct __pointer_type_info : public __pbase_type_info 296227825Stheraven { 297227825Stheraven virtual ~__pointer_type_info(); 298245302Stheraven virtual bool __is_pointer_p() const { return true; } 299227825Stheraven }; 300227825Stheraven 301227825Stheraven /** 302227825Stheraven * Pointer to member type info. 303227825Stheraven */ 304227825Stheraven struct __pointer_to_member_type_info : public __pbase_type_info 305227825Stheraven { 306227825Stheraven virtual ~__pointer_to_member_type_info(); 307227825Stheraven /** 308227825Stheraven * Pointer to the class containing this member. 309227825Stheraven */ 310227825Stheraven const __class_type_info *__context; 311227825Stheraven }; 312227825Stheraven 313227825Stheraven} 314