]> git.ipfire.org Git - thirdparty/gcc.git/blame - libobjc/ivars.c
Daily bump.
[thirdparty/gcc.git] / libobjc / ivars.c
CommitLineData
fdcbbfe7
NP
1/* GNU Objective C Runtime ivar related functions.
2 Copyright (C) 2010 Free Software Foundation, Inc.
3 Contributed by Nicola Pero
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under the
8terms of the GNU General Public License as published by the Free Software
9Foundation; either version 3, or (at your option) any later version.
10
11GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14details.
15
16Under Section 7 of GPL version 3, you are granted additional
17permissions described in the GCC Runtime Library Exception, version
183.1, as published by the Free Software Foundation.
19
20You should have received a copy of the GNU General Public License and
21a copy of the GCC Runtime Library Exception along with this program;
22see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23<http://www.gnu.org/licenses/>. */
24
25#include "objc-private/common.h"
718a8e53
NP
26#include "objc/runtime.h"
27#include "objc-private/module-abi-8.h" /* For runtime structures */
28#include "objc/thr.h"
ad9eef11
NP
29#include "objc-private/runtime.h" /* the kitchen sink */
30#include <string.h> /* For strcmp */
fdcbbfe7
NP
31
32struct objc_ivar *
33class_getInstanceVariable (Class class_, const char *name)
34{
6c5c7efd 35 if (class_ != Nil && name != NULL && ! CLS_IS_IN_CONSTRUCTION (class_))
fdcbbfe7 36 {
fdcbbfe7
NP
37 while (class_ != Nil)
38 {
39 struct objc_ivar_list *ivars = class_->ivars;
40 if (ivars != NULL)
41 {
42 int i;
43
44 for (i = 0; i < ivars->ivar_count; i++)
45 {
46 struct objc_ivar *ivar = &(ivars->ivar_list[i]);
47
48 if (!strcmp (ivar->ivar_name, name))
49 {
fdcbbfe7
NP
50 return ivar;
51 }
52 }
53 }
1cde73d7 54 class_ = class_getSuperclass (class_);
fdcbbfe7 55 }
fdcbbfe7
NP
56 }
57 return NULL;
58}
59
be05b0f5
NP
60struct objc_ivar *
61class_getClassVariable (Class class_, const char *name)
62{
63 if (class_ == Nil)
64 return NULL;
65
66 /* Logically, since a class is an instance of its meta-class, and
67 since its class methods are the instance methods of the
68 meta-class, class variables should be instance variables of the
69 meta-class. That is different from the normal use of having
70 'static' variables in the class implementation file, because
71 every class would have its own variables.
72
73 Anyway, it is all speculative at this stage, but if we get class
74 variables in Objective-C, it is conceivable that this
75 implementation should work. */
76 return class_getInstanceVariable (class_->class_pointer, name);
77}
78
fdcbbfe7
NP
79void *
80object_getIndexedIvars (id object)
81{
82 if (object == nil)
83 return NULL;
84 else
85 {
86 return (void *)(((char *)object)
87 + object->class_pointer->instance_size);
88 }
89}
90
91struct objc_ivar *
92object_getInstanceVariable (id object, const char *name, void **returnValue)
93{
94 if (object == nil || name == NULL)
95 return NULL;
96 else
97 {
98 struct objc_ivar * variable = class_getInstanceVariable (object->class_pointer, name);
99
100 if (variable != NULL && returnValue != NULL)
101 {
102 char *location = (char *)object + variable->ivar_offset;
103
104 *returnValue = *((id *)location);
105 }
106
107 return variable;
108 }
109}
110
111struct objc_ivar *
112object_setInstanceVariable (id object, const char *name, void *newValue)
113{
114 if (object == nil || name == NULL)
115 return NULL;
116 else
117 {
118 struct objc_ivar * variable = class_getInstanceVariable (object->class_pointer, name);
119
120 if (variable != NULL)
121 {
122 char *location = (char *)object + variable->ivar_offset;
123
124 *((id *)location) = (id)newValue;
125 }
126
127 return variable;
128 }
129}
130
131id object_getIvar (id object, struct objc_ivar * variable)
132{
133 if (object == nil || variable == NULL)
134 return nil;
135 else
136 {
137 char *location = (char *)object + variable->ivar_offset;
138
139 return *((id *)location);
140 }
141}
142
143void object_setIvar (id object, struct objc_ivar * variable, id value)
144{
145 if (object == nil || variable == NULL)
146 return;
147 else
148 {
149 char *location = (char *)object + variable->ivar_offset;
150
151 *((id *)location) = value;
152 }
153}
154
155const char * ivar_getName (struct objc_ivar * variable)
156{
ad9eef11
NP
157 if (variable == NULL)
158 return NULL;
159
fdcbbfe7
NP
160 return variable->ivar_name;
161}
162
163ptrdiff_t ivar_getOffset (struct objc_ivar * variable)
164{
ad9eef11
NP
165 if (variable == NULL)
166 return 0;
167
fdcbbfe7
NP
168 return (ptrdiff_t)(variable->ivar_offset);
169}
170
171const char * ivar_getTypeEncoding (struct objc_ivar * variable)
172{
ad9eef11
NP
173 if (variable == NULL)
174 return NULL;
175
fdcbbfe7
NP
176 return variable->ivar_type;
177}
ad9eef11
NP
178
179struct objc_ivar ** class_copyIvarList (Class class_, unsigned int *numberOfReturnedIvars)
180{
181 unsigned int count = 0;
182 struct objc_ivar **returnValue = NULL;
183 struct objc_ivar_list* ivar_list;
184
6c5c7efd 185 if (class_ == Nil || CLS_IS_IN_CONSTRUCTION (class_))
ad9eef11
NP
186 {
187 if (numberOfReturnedIvars)
188 *numberOfReturnedIvars = 0;
189 return NULL;
190 }
6c5c7efd 191
ad9eef11
NP
192 /* Count how many ivars we have. */
193 ivar_list = class_->ivars;
194 count = ivar_list->ivar_count;
195
196 if (count != 0)
197 {
198 unsigned int i = 0;
199
200 /* Allocate enough memory to hold them. */
201 returnValue = (struct objc_ivar **)(malloc (sizeof (struct objc_ivar *) * (count + 1)));
202
203 /* Copy the ivars. */
204 for (i = 0; i < count; i++)
205 {
206 returnValue[i] = &(ivar_list->ivar_list[i]);
207 }
208
209 returnValue[i] = NULL;
210 }
211
ad9eef11
NP
212 if (numberOfReturnedIvars)
213 *numberOfReturnedIvars = count;
214
215 return returnValue;
216}
8437e063 217
6c5c7efd
NP
218BOOL
219class_addIvar (Class class_, const char * ivar_name, size_t size,
220 unsigned char alignment, const char *type)
221{
222 struct objc_ivar_list *ivars;
223
224 if (class_ == Nil
225 || (! CLS_IS_IN_CONSTRUCTION (class_))
226 || ivar_name == NULL
227 || (strcmp (ivar_name, "") == 0)
228 || size == 0
229 || type == NULL)
230 return NO;
231
232 /* Check if the class has an instance variable with that name
233 already. */
234 ivars = class_->ivars;
235
236 if (ivars != NULL)
237 {
238 int i;
239
240 for (i = 0; i < ivars->ivar_count; i++)
241 {
242 struct objc_ivar *ivar = &(ivars->ivar_list[i]);
243
244 if (strcmp (ivar->ivar_name, ivar_name) == 0)
245 {
246 return NO;
247 }
248 }
249 }
250
251 /* Ok, no direct ivars. Check superclasses. */
252 if (class_getInstanceVariable (objc_getClass ((char *)(class_->super_class)),
253 ivar_name))
254 return NO;
255
256 /* Good. Create space for the new instance variable. */
257 if (ivars)
258 {
259 int ivar_count = ivars->ivar_count + 1;
260 int new_size = sizeof (struct objc_ivar_list)
261 + (ivar_count - 1) * sizeof (struct objc_ivar);
262
263 ivars = (struct objc_ivar_list*) objc_realloc (ivars, new_size);
264 ivars->ivar_count = ivar_count;
265 class_->ivars = ivars;
266 }
267 else
268 {
269 int new_size = sizeof (struct objc_ivar_list);
270
271 ivars = (struct objc_ivar_list*) objc_malloc (new_size);
272 ivars->ivar_count = 1;
273 class_->ivars = ivars;
274 }
275
276 /* Now ivars is set to a list of instance variables of the right
277 size. */
278 {
279 struct objc_ivar *ivar = &(ivars->ivar_list[ivars->ivar_count - 1]);
280 int misalignment;
281
282 ivar->ivar_name = objc_malloc (strlen (ivar_name) + 1);
283 strcpy ((char *)ivar->ivar_name, ivar_name);
284
285 ivar->ivar_type = objc_malloc (strlen (type) + 1);
286 strcpy ((char *)ivar->ivar_type, type);
287
288 /* The new instance variable is placed at the end of the existing
289 instance_size, at the first byte that is aligned with
290 alignment. */
291 misalignment = class_->instance_size % alignment;
292
293 if (misalignment == 0)
294 ivar->ivar_offset = class_->instance_size;
295 else
296 ivar->ivar_offset = class_->instance_size - misalignment + alignment;
297
298 class_->instance_size = ivar->ivar_offset + objc_sizeof_type (ivar->ivar_type);
299 }
300
301 return YES;
302}
303
304
8437e063
NP
305const char *
306property_getName (struct objc_property * property __attribute__ ((__unused__)))
307{
308 if (property == NULL)
309 return NULL;
310
311 /* TODO: New ABI. */
312 /* The current ABI does not have any information on properties. */
313 return NULL;
314}
315
316const char *
317property_getAttributes (struct objc_property * property __attribute__ ((__unused__)))
318{
319 if (property == NULL)
320 return NULL;
321
322 /* TODO: New ABI. */
323 /* The current ABI does not have any information on properties. */
324 return NULL;
325}
326
327struct objc_property *
328class_getProperty (Class class_ __attribute__ ((__unused__)),
329 const char *propertyName __attribute__ ((__unused__)))
330{
331 if (class_ == NULL || propertyName == NULL)
332 return NULL;
333
334 /* TODO: New ABI. */
335 /* The current ABI does not have any information on class properties. */
336 return NULL;
337}
338
339struct objc_property **
340class_copyPropertyList (Class class_ __attribute__ ((__unused__)),
341 unsigned int *numberOfReturnedProperties __attribute__ ((__unused__)))
342{
343 if (class_ == Nil)
344 {
345 if (numberOfReturnedProperties)
346 *numberOfReturnedProperties = 0;
347 return NULL;
348 }
349
350 /* TODO: New ABI. */
351 /* The current ABI does not have any information on class properties. */
352 if (numberOfReturnedProperties)
353 *numberOfReturnedProperties = 0;
354
355 return NULL;
356}
3c44c190
NP
357
358const char *
359class_getIvarLayout (Class class_ __attribute__ ((__unused__)))
360{
361 return NULL;
362}
363
364const char *
365class_getWeakIvarLayout (Class class_ __attribute__ ((__unused__)))
366{
367 return NULL;
368}
369
370void
371class_setIvarLayout (Class class_ __attribute__ ((__unused__)),
372 const char *layout __attribute__ ((__unused__)))
373{
374 return;
375}
376
377void
378class_setWeakIvarLayout (Class class_ __attribute__ ((__unused__)),
379 const char *layout __attribute__ ((__unused__)))
380{
381 return;
382}