]> git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/libsupc++/tinfo.h
Add support for -fno-exceptions.
[thirdparty/gcc.git] / libstdc++-v3 / libsupc++ / tinfo.h
1 // RTTI support internals for -*- C++ -*-
2
3 // Copyright (C) 1994, 1995, 1996, 1998, 1999, 2000 Free Software Foundation
4
5 #include "typeinfo"
6 #include <cstddef>
7
8 // Class declarations shared between the typeinfo implementation files.
9
10 #if !defined(__GXX_ABI_VERSION) || __GXX_ABI_VERSION < 100
11 // original (old) abi
12
13 // type_info for a class with no base classes (or an enum).
14
15 struct __user_type_info : public std::type_info {
16 __user_type_info (const char *n) : type_info (n) {}
17
18 // If our type can be upcast to a public and unambiguous base, then return
19 // non-zero and set RES to point to the base object. OBJ points to the throw
20 // object and can be NULL, if there is no object to adjust.
21 int upcast (const type_info &target, void *obj, void **res) const;
22
23 // If our type can be dynamicly cast to the target type, then return
24 // pointer to the target object. OBJ is the pointer to the most derived
25 // type and cannot be NULL. SUBTYPE and SUBOBJ indicate the static type
26 // base object from whence we came, it cannot be NULL. SUBTYPE cannot be
27 // the same as TARGET. TARGET cannot be a base of SUBTYPE.
28 // BOFF indicates how SUBTYPE is related to TARGET.
29 // BOFF >= 0, there is only one public non-virtual SUBTYPE base at offset
30 // BOFF, and there are no public virtual SUBTYPE bases.
31 // Therefore check if SUBOBJ is at offset BOFF when we find a target
32 // BOFF == -1, SUBTYPE occurs as multiple public virtual or non-virtual bases.
33 // Lazily search all the bases of TARGET.
34 // BOFF == -2, SUBTYPE is not a public base.
35 // BOFF == -3, SUBTYPE occurs as multiple public non-virtual bases.
36 // Lazily search the non-virtual bases of TARGET.
37 // For backwards compatibility set BOFF to -1, that is the safe "unknown"
38 // value. We do not care about SUBTYPES as private bases of TARGET, as they
39 // can never succeed as downcasts, only as crosscasts -- and then only if
40 // they are virtual. This is more complicated that it might seem.
41 void *dyncast (int boff,
42 const type_info &target, void *obj,
43 const type_info &subtype, void *subobj) const;
44
45 // non_virtual_base_type is used to indicate that a base class is via a
46 // non-virtual access path.
47 static const type_info *const nonvirtual_base_type
48 = static_cast <const type_info *> (0) + 1;
49
50 // sub_kind tells us about how a base object is contained within a derived
51 // object. We often do this lazily, hence the UNKNOWN value. At other times
52 // we may use NOT_CONTAINED to mean not publicly contained.
53 enum sub_kind
54 {
55 unknown = 0, // we have no idea
56 not_contained, // not contained within us (in some
57 // circumstances this might mean not contained
58 // publicly)
59 contained_ambig, // contained ambiguously
60 contained_mask = 4, // contained within us
61 contained_virtual_mask = 1, // via a virtual path
62 contained_public_mask = 2, // via a public path
63 contained_private = contained_mask,
64 contained_public = contained_mask | contained_public_mask
65 };
66 // some predicate functions for sub_kind
67 static inline bool contained_p (sub_kind access_path)
68 {
69 return access_path >= contained_mask;
70 }
71 static inline bool contained_public_p (sub_kind access_path)
72 {
73 return access_path >= contained_public;
74 }
75 static inline bool contained_nonpublic_p (sub_kind access_path)
76 {
77 return (access_path & contained_public) == contained_mask;
78 }
79 static inline bool contained_nonvirtual_p (sub_kind access_path)
80 {
81 return (access_path & (contained_mask | contained_virtual_mask))
82 == contained_mask;
83 }
84 static inline bool contained_virtual_p (sub_kind access_path)
85 {
86 return (access_path & (contained_mask | contained_virtual_mask))
87 == (contained_mask | contained_virtual_mask);
88 }
89
90 struct upcast_result
91 {
92 void *target_obj; // pointer to target object or NULL (init NULL)
93 sub_kind whole2target; // path from most derived object to target
94 const type_info *base_type; // where we found the target, (init NULL)
95 // if in vbase the __user_type_info of vbase)
96 // if a non-virtual base then 1
97 // else NULL
98 public:
99 upcast_result ()
100 :target_obj (NULL), whole2target (unknown), base_type (NULL)
101 {}
102 };
103 struct dyncast_result
104 {
105 void *target_obj; // pointer to target object or NULL (init NULL)
106 sub_kind whole2target; // path from most derived object to target
107 sub_kind whole2sub; // path from most derived object to sub object
108 sub_kind target2sub; // path from target to sub object
109
110 public:
111 dyncast_result ()
112 :target_obj (NULL), whole2target (unknown),
113 whole2sub (unknown), target2sub (unknown)
114 {}
115 };
116
117 public:
118 // Helper for upcast. See if TARGET is us, or one of our bases. ACCESS_PATH
119 // gives the access from the start object. Return TRUE if we know the catch
120 // fails.
121 virtual bool do_upcast (sub_kind access_path,
122 const type_info &target, void *obj,
123 upcast_result &__restrict result) const;
124 // Helper for dyncast. BOFF indicates how the SUBTYPE is related to TARGET.
125 // ACCESS_PATH indicates the access from the most derived object. It is
126 // used to prune the DAG walk. All information about what we find is put
127 // into RESULT. Return true, if the match we have found is ambiguous.
128 virtual bool do_dyncast (int boff, sub_kind access_path,
129 const type_info &target, void *obj,
130 const type_info &subtype, void *subptr,
131 dyncast_result &__restrict result) const;
132 public:
133 // Indicate whether SUBPTR of type SUBTYPE is contained publicly within
134 // OBJPTR. OBJPTR points to this base object. BOFF indicates how SUBTYPE
135 // objects might be contained within this type. If SUBPTR is one of our
136 // SUBTYPE bases, indicate virtuality. Returns not_contained for non
137 // containment or private containment.
138 sub_kind find_public_subobj (int boff, const type_info &subtype,
139 void *objptr, void *subptr) const
140 {
141 if (boff >= 0)
142 return ((char *)subptr - (char *)objptr) == boff
143 ? contained_public : not_contained;
144 if (boff == -2)
145 return not_contained;
146 return do_find_public_subobj (boff, subtype, objptr, subptr);
147 }
148
149 public:
150 // Helper for find_subobj. BOFF indicates how SUBTYPE bases are inherited by
151 // the type started from -- which is not necessarily the current type.
152 // OBJPTR points to the current base.
153 virtual sub_kind do_find_public_subobj (int boff, const type_info &subtype,
154 void *objptr, void *subptr) const;
155 };
156
157 // type_info for a class with one public, nonvirtual base class.
158
159 class __si_type_info : public __user_type_info {
160 const __user_type_info &base;
161
162 public:
163 __si_type_info (const char *n, const __user_type_info &b)
164 : __user_type_info (n), base (b) { }
165
166 private:
167 virtual bool do_upcast (sub_kind access_path,
168 const type_info &target, void *obj,
169 upcast_result &__restrict result) const;
170 virtual bool do_dyncast (int boff, sub_kind access_path,
171 const type_info &target, void *obj,
172 const type_info &subtype, void *subptr,
173 dyncast_result &__restrict result) const;
174 virtual sub_kind do_find_public_subobj (int boff, const type_info &subtype,
175 void *objptr, void *subptr) const;
176 };
177
178 // type_info for a general class.
179
180 #include <climits>
181
182 #if INT_MAX == 2147483647
183 typedef int myint32;
184 #elif SHRT_MAX == 2147483647
185 typedef short myint32;
186 #elif SCHAR_MAX == 2147483647
187 typedef signed char myint32;
188 #elif LONG_MAX == 2147483647
189 typedef long myint32;
190 #else
191 # error "No 32-bit data type?"
192 #endif
193
194 struct __class_type_info : public __user_type_info {
195 enum access { PUBLIC = 1, PROTECTED = 2, PRIVATE = 3 };
196
197 struct base_info {
198 const __user_type_info *base;
199 myint32 offset: 29;
200 bool is_virtual: 1;
201 enum access access: 2;
202 };
203
204 const base_info *base_list;
205 std::size_t n_bases;
206
207 __class_type_info (const char *name, const base_info *bl, std::size_t bn)
208 : __user_type_info (name), base_list (bl), n_bases (bn) {}
209
210 public:
211 virtual bool do_upcast (sub_kind access_path,
212 const type_info &target, void *obj,
213 upcast_result &__restrict result) const;
214 virtual bool do_dyncast (int boff, sub_kind access_path,
215 const type_info &target, void *obj,
216 const type_info &subtype, void *subptr,
217 dyncast_result &__restrict result) const;
218 virtual sub_kind do_find_public_subobj (int boff, const type_info &subtype,
219 void *objptr, void *subptr) const;
220 };
221 #else
222 // new abi
223 #include <cxxabi.h>
224
225 #endif