OSDN Git Service

91d52bdce0f6b5a9d33ca5d2302b6931d5f368e3
[pf3gnuchains/gcc-fork.git] / gcc / cp / tinfo.h
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 // type_info for a class with no base classes (or an enum).
9
10 struct __user_type_info : public std::type_info {
11   __user_type_info (const char *n) : type_info (n) {}
12
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;
17   
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;
39   
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;
44   
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.
48   enum sub_kind
49   {
50     unknown = 0,              // we have no idea
51     not_contained,            // not contained within us (in some
52                               // circumstances this might mean not contained
53                               // publicly)
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
60   };
61   // some predicate functions for sub_kind
62   static inline bool contained_p (sub_kind access_path)
63   {
64     return access_path >= contained_mask;
65   }
66   static inline bool contained_public_p (sub_kind access_path)
67   {
68     return access_path >= contained_public;
69   }
70   static inline bool contained_nonpublic_p (sub_kind access_path)
71   {
72     return (access_path & contained_public) == contained_mask;
73   }
74   static inline bool contained_nonvirtual_p (sub_kind access_path)
75   {
76     return (access_path & (contained_mask | contained_virtual_mask))
77            == contained_mask;
78   }
79   
80   struct upcast_result
81   {
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
87                                 // else NULL
88     public:
89     upcast_result ()
90       :target_obj (NULL), whole2target (unknown), base_type (NULL)
91       {}
92   };
93   struct dyncast_result
94   {
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
99     
100     public:
101     dyncast_result ()
102       :target_obj (NULL), whole2target (unknown),
103        whole2sub (unknown), target2sub (unknown)
104       {}
105   };
106   
107   public:
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
110   // fails.
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;
122   public:
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
130   {
131     if (boff >= 0)
132       return ((char *)subptr - (char *)objptr) == boff
133               ? contained_public : not_contained;
134     if (boff == -2)
135       return not_contained;
136     return do_find_public_subobj (boff, subtype, objptr, subptr);
137   }
138   
139   public:
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;
145 };
146
147 // type_info for a class with one public, nonvirtual base class.
148
149 class __si_type_info : public __user_type_info {
150   const __user_type_info &base;
151
152 public:
153   __si_type_info (const char *n, const __user_type_info &b)
154     : __user_type_info (n), base (b) { }
155
156   private:
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;
166 };
167
168 // type_info for a general class.
169
170 #ifdef __GXX_ABI_VERSION
171 typedef int USItype __attribute__ ((mode (SI)));
172 #else
173 typedef unsigned int USItype    __attribute__ ((mode (SI)));
174 #endif
175
176 struct __class_type_info : public __user_type_info {
177   enum access { PUBLIC = 1, PROTECTED = 2, PRIVATE = 3 };
178
179   struct base_info {
180     const __user_type_info *base;
181     USItype offset: 29;
182     bool is_virtual: 1;
183     enum access access: 2;
184   };
185
186   const base_info *base_list;
187   size_t n_bases;
188
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) {}
191
192   public:
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;
202 };