1 // RTTI support internals for -*- C++ -*-
2 // Copyright (C) 1994, 1995, 1996, 1998, 1999, 2000 Free Software Foundation
6 // Class declarations shared between the typeinfo implementation files.
8 // type_info for a class with no base classes (or an enum).
10 struct __user_type_info : public std::type_info {
11 __user_type_info (const char *n) : type_info (n) {}
13 // If our type can be upcast to a public and unambiguous base, then return
14 // non-zero and set RES to point to the base object. OBJ points to the throw
15 // object and can be NULL, if there is no object to adjust.
16 int upcast (const type_info &target, void *obj, void **res) const;
18 // If our type can be dynamicly cast to the target type, then return
19 // pointer to the target object. OBJ is the pointer to the most derived
20 // type and cannot be NULL. SUBTYPE and SUBOBJ indicate the static type
21 // base object from whence we came, it cannot be NULL. SUBTYPE cannot be
22 // the same as TARGET. TARGET cannot be a base of SUBTYPE.
23 // BOFF indicates how SUBTYPE is related to TARGET.
24 // BOFF >= 0, there is only one public non-virtual SUBTYPE base at offset
25 // BOFF, and there are no public virtual SUBTYPE bases.
26 // Therefore check if SUBOBJ is at offset BOFF when we find a target
27 // BOFF == -1, SUBTYPE occurs as multiple public virtual or non-virtual bases.
28 // Lazily search all the bases of TARGET.
29 // BOFF == -2, SUBTYPE is not a public base.
30 // BOFF == -3, SUBTYPE occurs as multiple public non-virtual bases.
31 // Lazily search the non-virtual bases of TARGET.
32 // For backwards compatibility set BOFF to -1, that is the safe `don't know'
33 // value. We don't care about SUBTYPES as private bases of TARGET, as they
34 // can never succeed as downcasts, only as crosscasts -- and then only if
35 // they are virtual. This is more complicated that it might seem.
36 void *dyncast (int boff,
37 const type_info &target, void *obj,
38 const type_info &subtype, void *subobj) const;
40 // non_virtual_base_type is used to indicate that a base class is via a
41 // non-virtual access path.
42 static const type_info *const nonvirtual_base_type
43 = static_cast <const type_info *> (0) + 1;
45 // sub_kind tells us about how a base object is contained within a derived
46 // object. We often do this lazily, hence the UNKNOWN value. At other times
47 // we may use NOT_CONTAINED to mean not publicly contained.
50 unknown = 0, // we have no idea
51 not_contained, // not contained within us (in some
52 // circumstances this might mean not contained
54 contained_ambig, // contained ambiguously
55 contained_mask = 4, // contained within us
56 contained_virtual_mask = 1, // via a virtual path
57 contained_public_mask = 2, // via a public path
58 contained_private = contained_mask,
59 contained_public = contained_mask | contained_public_mask
61 // some predicate functions for sub_kind
62 static inline bool contained_p (sub_kind access_path)
64 return access_path >= contained_mask;
66 static inline bool contained_public_p (sub_kind access_path)
68 return access_path >= contained_public;
70 static inline bool contained_nonpublic_p (sub_kind access_path)
72 return (access_path & contained_public) == contained_mask;
74 static inline bool contained_nonvirtual_p (sub_kind access_path)
76 return (access_path & (contained_mask | contained_virtual_mask))
82 void *target_obj; // pointer to target object or NULL (init NULL)
83 sub_kind whole2target; // path from most derived object to target
84 const type_info *base_type; // where we found the target, (init NULL)
85 // if in vbase the __user_type_info of vbase)
86 // if a non-virtual base then 1
90 :target_obj (NULL), whole2target (unknown), base_type (NULL)
95 void *target_obj; // pointer to target object or NULL (init NULL)
96 sub_kind whole2target; // path from most derived object to target
97 sub_kind whole2sub; // path from most derived object to sub object
98 sub_kind target2sub; // path from target to sub object
102 :target_obj (NULL), whole2target (unknown),
103 whole2sub (unknown), target2sub (unknown)
108 // Helper for upcast. See if TARGET is us, or one of our bases. ACCESS_PATH
109 // gives the access from the start object. Return TRUE if we know the catch
111 virtual bool do_upcast (sub_kind access_path,
112 const type_info &target, void *obj,
113 upcast_result &__restrict result) const;
114 // Helper for dyncast. BOFF indicates how the SUBTYPE is related to TARGET.
115 // ACCESS_PATH indicates the access from the most derived object. It is
116 // used to prune the DAG walk. All information about what we find is put
117 // into RESULT. Return true, if the match we have found is ambiguous.
118 virtual bool do_dyncast (int boff, sub_kind access_path,
119 const type_info &target, void *obj,
120 const type_info &subtype, void *subptr,
121 dyncast_result &__restrict result) const;
123 // Indicate whether SUBPTR of type SUBTYPE is contained publicly within
124 // OBJPTR. OBJPTR points to this base object. BOFF indicates how SUBTYPE
125 // objects might be contained within this type. If SUBPTR is one of our
126 // SUBTYPE bases, indicate virtuality. Returns not_contained for non
127 // containment or private containment.
128 sub_kind find_public_subobj (int boff, const type_info &subtype,
129 void *objptr, void *subptr) const
132 return ((char *)subptr - (char *)objptr) == boff
133 ? contained_public : not_contained;
135 return not_contained;
136 return do_find_public_subobj (boff, subtype, objptr, subptr);
140 // Helper for find_subobj. BOFF indicates how SUBTYPE bases are inherited by
141 // the type started from -- which is not necessarily the current type.
142 // OBJPTR points to the current base.
143 virtual sub_kind do_find_public_subobj (int boff, const type_info &subtype,
144 void *objptr, void *subptr) const;
147 // type_info for a class with one public, nonvirtual base class.
149 class __si_type_info : public __user_type_info {
150 const __user_type_info &base;
153 __si_type_info (const char *n, const __user_type_info &b)
154 : __user_type_info (n), base (b) { }
157 virtual bool do_upcast (sub_kind access_path,
158 const type_info &target, void *obj,
159 upcast_result &__restrict result) const;
160 virtual bool do_dyncast (int boff, sub_kind access_path,
161 const type_info &target, void *obj,
162 const type_info &subtype, void *subptr,
163 dyncast_result &__restrict result) const;
164 virtual sub_kind do_find_public_subobj (int boff, const type_info &subtype,
165 void *objptr, void *subptr) const;
168 // type_info for a general class.
170 #ifdef __GXX_ABI_VERSION
171 typedef int USItype __attribute__ ((mode (SI)));
173 typedef unsigned int USItype __attribute__ ((mode (SI)));
176 struct __class_type_info : public __user_type_info {
177 enum access { PUBLIC = 1, PROTECTED = 2, PRIVATE = 3 };
180 const __user_type_info *base;
183 enum access access: 2;
186 const base_info *base_list;
189 __class_type_info (const char *name, const base_info *bl, size_t bn)
190 : __user_type_info (name), base_list (bl), n_bases (bn) {}
193 virtual bool do_upcast (sub_kind access_path,
194 const type_info &target, void *obj,
195 upcast_result &__restrict result) const;
196 virtual bool do_dyncast (int boff, sub_kind access_path,
197 const type_info &target, void *obj,
198 const type_info &subtype, void *subptr,
199 dyncast_result &__restrict result) const;
200 virtual sub_kind do_find_public_subobj (int boff, const type_info &subtype,
201 void *objptr, void *subptr) const;