source: branches/libc-0.6/src/gcc/libobjc/gc.c@ 2816

Last change on this file since 2816 was 1392, checked in by bird, 22 years ago

This commit was generated by cvs2svn to compensate for changes in r1391,
which included commits to RCS files with non-trunk default branches.

  • Property cvs2svn:cvs-rev set to 1.1.1.2
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 11.6 KB
Line 
1/* Basic data types for Objective C.
2 Copyright (C) 1998, 2002 Free Software Foundation, Inc.
3 Contributed by Ovidiu Predescu.
4
5This file is part of GNU CC.
6
7GNU CC is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12GNU CC is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU CC; see the file COPYING. If not, write to
19the Free Software Foundation, 59 Temple Place - Suite 330,
20Boston, MA 02111-1307, USA. */
21
22/* As a special exception, if you link this library with files
23 compiled with GCC to produce an executable, this does not cause
24 the resulting executable to be covered by the GNU General Public License.
25 This exception does not however invalidate any other reasons why
26 the executable file might be covered by the GNU General Public License. */
27
28#include "tconfig.h"
29#include "objc.h"
30#include "encoding.h"
31
32#include <assert.h>
33#include <string.h>
34
35#if OBJC_WITH_GC
36
37#include <gc.h>
38
39/* gc_typed.h uses the following but doesn't declare them */
40typedef GC_word word;
41typedef GC_signed_word signed_word;
42
43#if BITS_PER_WORD == 32
44# define LOGWL 5
45# define modWORDSZ(n) ((n) & 0x1f) /* n mod size of word */
46#endif
47
48#if BITS_PER_WORD == 64
49# define LOGWL 6
50# define modWORDSZ(n) ((n) & 0x3f) /* n mod size of word */
51#endif
52
53#define divWORDSZ(n) ((n) >> LOGWL) /* divide n by size of word */
54
55#include <gc_typed.h>
56
57/* The following functions set up in `mask` the corresponding pointers.
58 The offset is incremented with the size of the type. */
59
60#define ROUND(V, A) \
61 ({ typeof (V) __v = (V); typeof (A) __a = (A); \
62 __a * ((__v+__a - 1)/__a); })
63
64#define SET_BIT_FOR_OFFSET(mask, offset) \
65 GC_set_bit (mask, offset / sizeof (void *))
66
67/* Some prototypes */
68static void
69__objc_gc_setup_struct (GC_bitmap mask, const char *type, int offset);
70static void
71__objc_gc_setup_union (GC_bitmap mask, const char *type, int offset);
72
73
74static void
75__objc_gc_setup_array (GC_bitmap mask, const char *type, int offset)
76{
77 int i, len = atoi (type + 1);
78
79 while (isdigit (*++type))
80 /* do nothing */; /* skip the size of the array */
81
82 switch (*type) {
83 case _C_ARY_B:
84 for (i = 0; i < len; i++)
85 __objc_gc_setup_array (mask, type, offset);
86 break;
87
88 case _C_STRUCT_B:
89 for (i = 0; i < len; i++)
90 __objc_gc_setup_struct (mask, type, offset);
91 break;
92
93 case _C_UNION_B:
94 for (i = 0; i < len; i++)
95 __objc_gc_setup_union (mask, type, offset);
96 break;
97
98 default:
99 break;
100 }
101}
102
103static void
104__objc_gc_setup_struct (GC_bitmap mask, const char *type, int offset)
105{
106 struct objc_struct_layout layout;
107 unsigned int position;
108 const char *mtype;
109
110 objc_layout_structure (type, &layout);
111
112 while (objc_layout_structure_next_member (&layout))
113 {
114 BOOL gc_invisible = NO;
115
116 objc_layout_structure_get_info (&layout, &position, NULL, &mtype);
117
118 /* Skip the variable name */
119 if (*mtype == '"')
120 {
121 for (mtype++; *mtype++ != '"';)
122 /* do nothing */;
123 }
124
125 if (*mtype == _C_GCINVISIBLE)
126 {
127 gc_invisible = YES;
128 mtype++;
129 }
130
131 /* Add to position the offset of this structure */
132 position += offset;
133
134 switch (*mtype) {
135 case _C_ID:
136 case _C_CLASS:
137 case _C_SEL:
138 case _C_PTR:
139 case _C_CHARPTR:
140 case _C_ATOM:
141 if (! gc_invisible)
142 SET_BIT_FOR_OFFSET (mask, position);
143 break;
144
145 case _C_ARY_B:
146 __objc_gc_setup_array (mask, mtype, position);
147 break;
148
149 case _C_STRUCT_B:
150 __objc_gc_setup_struct (mask, mtype, position);
151 break;
152
153 case _C_UNION_B:
154 __objc_gc_setup_union (mask, mtype, position);
155 break;
156
157 default:
158 break;
159 }
160 }
161}
162
163static void
164__objc_gc_setup_union (GC_bitmap mask, const char *type, int offset)
165{
166 /* Sub-optimal, quick implementation: assume the union is made of
167 pointers, set up the mask accordingly. */
168
169 int i, size, align;
170
171 /* Skip the variable name */
172 if (*type == '"')
173 {
174 for (type++; *type++ != '"';)
175 /* do nothing */;
176 }
177
178 size = objc_sizeof_type (type);
179 align = objc_alignof_type (type);
180
181 offset = ROUND (offset, align);
182 for (i = 0; i < size; i += sizeof (void *))
183 {
184 SET_BIT_FOR_OFFSET (mask, offset);
185 offset += sizeof (void *);
186 }
187}
188
189
190/* Iterates over the types in the structure that represents the class
191 encoding and sets the bits in mask according to each ivar type. */
192static void
193__objc_gc_type_description_from_type (GC_bitmap mask, const char *type)
194{
195 struct objc_struct_layout layout;
196 unsigned int offset, align;
197 const char *ivar_type;
198
199 objc_layout_structure (type, &layout);
200
201 while (objc_layout_structure_next_member (&layout))
202 {
203 BOOL gc_invisible = NO;
204
205 objc_layout_structure_get_info (&layout, &offset, &align, &ivar_type);
206
207 /* Skip the variable name */
208 if (*ivar_type == '"')
209 {
210 for (ivar_type++; *ivar_type++ != '"';)
211 /* do nothing */;
212 }
213
214 if (*ivar_type == _C_GCINVISIBLE)
215 {
216 gc_invisible = YES;
217 ivar_type++;
218 }
219
220 switch (*ivar_type) {
221 case _C_ID:
222 case _C_CLASS:
223 case _C_SEL:
224 case _C_PTR:
225 case _C_CHARPTR:
226 if (! gc_invisible)
227 SET_BIT_FOR_OFFSET (mask, offset);
228 break;
229
230 case _C_ARY_B:
231 __objc_gc_setup_array (mask, ivar_type, offset);
232 break;
233
234 case _C_STRUCT_B: