xref: /freebsd-src/contrib/libcxxrt/typeinfo.h (revision cfe30d02adda7c3b5c76156ac52d50d8cab325d9)
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