xref: /freebsd/contrib/libcxxrt/typeinfo.h (revision 193d9e768ba63fcfb187cfd17f461f7d41345048)
1 /*
2  * Copyright 2010-2011 PathScale, Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright notice,
8  *    this list of conditions and the following disclaimer.
9  *
10  * 2. Redistributions in binary form must reproduce the above copyright notice,
11  *    this list of conditions and the following disclaimer in the documentation
12  *    and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
15  * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
24  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 
27 #include <stddef.h>
28 #include "abi_namespace.h"
29 
30 namespace ABI_NAMESPACE
31 {
32 	struct __class_type_info;
33 }
34 namespace std
35 {
36 	/**
37 	  * Standard type info class.  The layout of this class is specified by the
38 	  * ABI.  The layout of the vtable is not, but is intended to be
39 	  * compatible with the GNU ABI.
40 	  *
41 	  * Unlike the GNU version, the vtable layout is considered semi-private.
42 	  */
43 	class type_info
44 	{
45 		public:
46 		/**
47 		 * Virtual destructor.  This class must have one virtual function to
48 		 * ensure that it has a vtable.
49 		 */
50 		virtual ~type_info();
51 		bool operator==(const type_info &) const;
52 		bool operator!=(const type_info &) const;
53 		bool before(const type_info &) const;
54 		const char* name() const;
55 		type_info();
56 		private:
57 		type_info(const type_info& rhs);
58 		type_info& operator= (const type_info& rhs);
59 		const char *__type_name;
60 		/*
61 		 * The following functions are in this order to match the
62 		 * vtable layout of libsupc++.  This allows libcxxrt to be used
63 		 * with libraries that depend on this.
64 		 *
65 		 * These functions are in the public headers for libstdc++, so
66 		 * we have to assume that someone will probably call them and
67 		 * expect them to work.  Their names must also match the names used in
68 		 * libsupc++, so that code linking against this library can subclass
69 		 * type_info and correctly fill in the values in the vtables.
70 		 */
71 		public:
72 		/**
73 		 * Returns true if this is some pointer type, false otherwise.
74 		 */
75 		virtual bool __is_pointer_p() const { return false; }
76 		/**
77 		 * Returns true if this is some function type, false otherwise.
78 		 */
79 		virtual bool __is_function_p() const { return false; }
80 		/**
81 		 * Catch function.  Allows external libraries to implement
82 		 * their own basic types.  This is used, for example, in the
83 		 * GNUstep Objective-C runtime to allow Objective-C types to be
84 		 * caught in G++ catch blocks.
85 		 *
86 		 * The outer parameter indicates the number of outer pointers
87 		 * in the high bits.  The low bit indicates whether the
88 		 * pointers are const qualified.
89 		 */
90 		virtual bool __do_catch(const type_info *thrown_type,
91 		                        void **thrown_object,
92 		                        unsigned outer) const;
93 		/**
94 		 * Performs an upcast.  This is used in exception handling to
95 		 * cast from subclasses to superclasses.  If the upcast is
96 		 * possible, it returns true and adjusts the pointer.  If the
97 		 * upcast is not possible, it returns false and does not adjust
98 		 * the pointer.
99 		 */
100 		virtual bool __do_upcast(
101 		                const ABI_NAMESPACE::__class_type_info *target,
102 		                void **thrown_object) const
103 		{
104 			return false;
105 		}
106 	};
107 }
108 
109 
110 namespace ABI_NAMESPACE
111 {
112 	/**
113 	 * Primitive type info, for intrinsic types.
114 	 */
115 	struct __fundamental_type_info : public std::type_info
116 	{
117 		virtual ~__fundamental_type_info();
118 	};
119 	/**
120 	 * Type info for arrays.
121 	 */
122 	struct __array_type_info : public std::type_info
123 	{
124 		virtual ~__array_type_info();
125 	};
126 	/**
127 	 * Type info for functions.
128 	 */
129 	struct __function_type_info : public std::type_info
130 	{
131 		virtual ~__function_type_info();
132 		virtual bool __is_function_p() const { return true; }
133 	};
134 	/**
135 	 * Type info for enums.
136 	 */
137 	struct __enum_type_info : public std::type_info
138 	{
139 		virtual ~__enum_type_info();
140 	};
141 
142 	/**
143 	 * Base class for class type info.  Used only for tentative definitions.
144 	 */
145 	struct __class_type_info : public std::type_info
146 	{
147 		virtual ~__class_type_info();
148 		/**
149 		 * Function implementing dynamic casts.
150 		 */
151 		virtual void *cast_to(void *obj, const struct __class_type_info *other) const;
152 		virtual bool __do_upcast(const __class_type_info *target,
153 		                       void **thrown_object) const
154 		{
155 			return this == target;
156 		}
157 	};
158 
159 	/**
160 	 * Single-inheritance class type info.  This is used for classes containing
161 	 * a single non-virtual base class at offset 0.
162 	 */
163 	struct __si_class_type_info : public __class_type_info
164 	{
165 		virtual ~__si_class_type_info();
166 		const __class_type_info *__base_type;
167 		virtual bool __do_upcast(
168 		                const ABI_NAMESPACE::__class_type_info *target,
169 		                void **thrown_object) const;
170 		virtual void *cast_to(void *obj, const struct __class_type_info *other) const;
171 	};
172 
173 	/**
174 	 * Type info for base classes.  Classes with multiple bases store an array
175 	 * of these, one for each superclass.
176 	 */
177 	struct __base_class_type_info
178 	{
179 		const __class_type_info *__base_type;
180 		private:
181 			/**
182 			 * The high __offset_shift bits of this store the (signed) offset
183 			 * of the base class.  The low bits store flags from
184 			 * __offset_flags_masks.
185 			 */
186 			long __offset_flags;
187 			/**
188 			 * Flags used in the low bits of __offset_flags.
189 			 */
190 			enum __offset_flags_masks
191 			{
192 				/** This base class is virtual. */
193 				__virtual_mask = 0x1,
194 				/** This base class is public. */
195 				__public_mask = 0x2,
196 				/** The number of bits reserved for flags. */
197 				__offset_shift = 8
198 			};
199 		public:
200 			/**
201 			 * Returns the offset of the base class.
202 			 */
203 			long offset() const
204 			{
205 				return __offset_flags >> __offset_shift;
206 			}
207 			/**
208 			 * Returns the flags.
209 			 */
210 			long flags() const
211 			{
212 				return __offset_flags & ((1 << __offset_shift) - 1);
213 			}
214 			/**
215 			 * Returns whether this is a public base class.
216 			 */
217 			bool isPublic() const { return flags() & __public_mask; }
218 			/**
219 			 * Returns whether this is a virtual base class.
220 			 */
221 			bool isVirtual() const { return flags() & __virtual_mask; }
222 	};
223 
224 	/**
225 	 * Type info for classes with virtual bases or multiple superclasses.
226 	 */
227 	struct __vmi_class_type_info : public __class_type_info
228 	{
229 		virtual ~__vmi_class_type_info();
230 		/** Flags describing this class.  Contains values from __flags_masks. */
231 		unsigned int __flags;
232 		/** The number of base classes. */
233 		unsigned int __base_count;
234 		/**
235 		 * Array of base classes - this actually has __base_count elements, not
236 		 * 1.
237 		 */
238 		__base_class_type_info __base_info[1];
239 
240 		/**
241 		 * Flags used in the __flags field.
242 		 */
243 		enum __flags_masks
244 		{
245 			/** The class has non-diamond repeated inheritance. */
246 			__non_diamond_repeat_mask = 0x1,
247 			/** The class is diamond shaped. */
248 			__diamond_shaped_mask = 0x2
249 		};
250 		virtual bool __do_upcast(
251 		                const ABI_NAMESPACE::__class_type_info *target,
252 		                void **thrown_object) const;
253 		virtual void *cast_to(void *obj, const struct __class_type_info *other) const;
254 	};
255 
256 	/**
257 	 * Base class used for both pointer and pointer-to-member type info.
258 	 */
259 	struct __pbase_type_info : public std::type_info
260 	{
261 		virtual ~__pbase_type_info();
262 		/**
263 		 * Flags.  Values from __masks.
264 		 */
265 		unsigned int __flags;
266 		/**
267 		 * The type info for the pointee.
268 		 */
269 		const std::type_info *__pointee;
270 
271 		/**
272 		 * Masks used for qualifiers on the pointer.
273 		 */
274 		enum __masks
275 		{
276 			/** Pointer has const qualifier. */
277 			__const_mask = 0x1,
278 			/** Pointer has volatile qualifier. */
279 			__volatile_mask = 0x2,
280 			/** Pointer has restrict qualifier. */
281 			__restrict_mask = 0x4,
282 			/** Pointer points to an incomplete type. */
283 			__incomplete_mask = 0x8,
284 			/** Pointer is a pointer to a member of an incomplete class. */
285 			__incomplete_class_mask = 0x10
286 		};
287 		virtual bool __do_catch(const type_info *thrown_type,
288 		                        void **thrown_object,
289 		                        unsigned outer) const;
290 	};
291 
292 	/**
293 	 * Pointer type info.
294 	 */
295 	struct __pointer_type_info : public __pbase_type_info
296 	{
297 		virtual ~__pointer_type_info();
298 		virtual bool __is_pointer_p() const { return true; }
299 	};
300 
301 	/**
302 	 * Pointer to member type info.
303 	 */
304 	struct __pointer_to_member_type_info : public __pbase_type_info
305 	{
306 		virtual ~__pointer_to_member_type_info();
307 		/**
308 		 * Pointer to the class containing this member.
309 		 */
310 		const __class_type_info *__context;
311 	};
312 
313 }
314