OSDN Git Service

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