OpenCores
URL https://opencores.org/ocsvn/altor32/altor32/trunk

Subversion Repositories altor32

[/] [altor32/] [trunk/] [gcc-x64/] [or1knd-elf/] [lib/] [gcc/] [or1knd-elf/] [4.8.0/] [plugin/] [include/] [is-a.h] - Blame information for rev 35

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 35 ultra_embe
/* Dynamic testing for abstract is-a relationships.
2
   Copyright (C) 2012 Free Software Foundation, Inc.
3
   Contributed by Lawrence Crowl.
4
 
5
This file is part of GCC.
6
 
7
GCC is free software; you can redistribute it and/or modify it under
8
the terms of the GNU General Public License as published by the Free
9
Software Foundation; either version 3, or (at your option) any later
10
version.
11
 
12
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13
WARRANTY; without even the implied warranty of MERCHANTABILITY or
14
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15
for more details.
16
 
17
You should have received a copy of the GNU General Public License
18
along with GCC; see the file COPYING3.  If not see
19
<http://www.gnu.org/licenses/>.  */
20
 
21
 
22
/* This header generic type query and conversion functions.
23
 
24
 
25
USING THE GENERIC TYPE FACILITY
26
 
27
 
28
The user functions are:
29
 
30
bool is_a <TYPE> (pointer)
31
 
32
    Tests whether the pointer actually points to a more derived TYPE.
33
 
34
    Suppose you have a symtab_node_def *ptr, AKA symtab_node ptr.  You can test
35
    whether it points to a 'derived' cgraph_node as follows.
36
 
37
      if (is_a <cgraph_node> (ptr))
38
        ....
39
 
40
 
41
TYPE *as_a <TYPE> (pointer)
42
 
43
    Converts pointer to a TYPE*.
44
 
45
    You can just assume that it is such a node.
46
 
47
      do_something_with (as_a <cgraph_node> *ptr);
48
 
49
TYPE *dyn_cast <TYPE> (pointer)
50
 
51
    Converts pointer to TYPE* if and only if "is_a <TYPE> pointer".  Otherwise,
52
    returns NULL.  This function is essentially a checked down cast.
53
 
54
    This functions reduce compile time and increase type safety when treating a
55
    generic item as a more specific item.
56
 
57
    You can test and obtain a pointer to the 'derived' type in one indivisible
58
    operation.
59
 
60
      if (cgraph_node *cptr = dyn_cast <cgraph_node> (ptr))
61
        ....
62
 
63
    As an example, the code change is from
64
 
65
      if (symtab_function_p (node))
66
        {
67
          struct cgraph_node *cnode = cgraph (node);
68
          ....
69
        }
70
 
71
    to
72
 
73
      if (cgraph_node *cnode = dyn_cast <cgraph_node> (node))
74
        {
75
          ....
76
        }
77
 
78
    The necessary conditional test defines a variable that holds a known good
79
    pointer to the specific item and avoids subsequent conversion calls and
80
    the assertion checks that may come with them.
81
 
82
    When, the property test is embedded within a larger condition, the
83
    variable declaration gets pulled out of the condition.  (This approach
84
    leaves some room for using the variable inappropriately.)
85
 
86
      if (symtab_variable_p (node) && varpool (node)->finalized)
87
        varpool_analyze_node (varpool (node));
88
 
89
    becomes
90
 
91
      varpool_node *vnode = dyn_cast <varpool_node> (node);
92
      if (vnode && vnode->finalized)
93
        varpool_analyze_node (vnode);
94
 
95
    Note that we have converted two sets of assertions in the calls to varpool
96
    into safe and efficient use of a variable.
97
 
98
 
99
If you use these functions and get a 'inline function not defined' or a
100
'missing symbol' error message for 'is_a_helper<....>::test', it means that
101
the connection between the types has not been made.  See below.
102
 
103
 
104
EXTENDING THE GENERIC TYPE FACILITY
105
 
106
Each connection between types must be made by defining a specialization of the
107
template member function 'test' of the template class 'is_a_helper'.  For
108
example,
109
 
110
  template <>
111
  template <>
112
  inline bool
113
  is_a_helper <cgraph_node>::test (symtab_node_def *p)
114
  {
115
    return p->symbol.type == SYMTAB_FUNCTION;
116
  }
117
 
118
If a simple reinterpret_cast between the pointer types is incorrect, then you
119
must also specialize the template member function 'cast'.  Failure to do so
120
when needed may result in a crash.  For example,
121
 
122
  template <>
123
  template <>
124
  inline bool
125
  is_a_helper <cgraph_node>::cast (symtab_node_def *p)
126
  {
127
    return &p->x_function;
128
  }
129
 
130
*/
131
 
132
#ifndef GCC_IS_A_H
133
#define GCC_IS_A_H
134
 
135
/* A generic type conversion internal helper class.  */
136
 
137
template <typename T>
138
struct is_a_helper
139
{
140
  template <typename U>
141
  static inline bool test (U *p);
142
  template <typename U>
143
  static inline T *cast (U *p);
144
};
145
 
146
/* Note that we deliberately do not define the 'test' member template.  Not
147
   doing so will result in a build-time error for type relationships that have
148
   not been defined, rather than a run-time error.  See the discussion above
149
   for when to define this member.  */
150
 
151
/* This is the generic implementation for casting from one type to another.
152
   Do not use this routine directly; it is an internal function.  See the
153
   discussion above for when to define this member.  */
154
 
155
template <typename T>
156
template <typename U>
157
inline T *
158
is_a_helper <T>::cast (U *p)
159
{
160
  return reinterpret_cast <T *> (p);
161
}
162
 
163
 
164
/* The public interface.  */
165
 
166
/* A generic test for a type relationship.  See the discussion above for when
167
   to use this function.  The question answered is "Is type T a derived type of
168
   type U?".  */
169
 
170
template <typename T, typename U>
171
inline bool
172
is_a (U *p)
173
{
174
  return is_a_helper<T>::test (p);
175
}
176
 
177
/* A generic conversion from a base type U to a derived type T.  See the
178
   discussion above for when to use this function.  */
179
 
180
template <typename T, typename U>
181
inline T *
182
as_a (U *p)
183
{
184
  gcc_assert (is_a <T> (p));
185
  return is_a_helper <T>::cast (p);
186
}
187
 
188
/* A generic checked conversion from a base type U to a derived type T.  See
189
   the discussion above for when to use this function.  */
190
 
191
template <typename T, typename U>
192
inline T *
193
dyn_cast (U *p)
194
{
195
  if (is_a <T> (p))
196
    return is_a_helper <T>::cast (p);
197
  else
198
    return static_cast <T *> (0);
199
}
200
 
201
#endif  /* GCC_IS_A_H  */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.