[docs] Enable documentation for metadata.
[mono.git] / mono / metadata / class-accessors.c
1 /**
2  * \file
3  * Copyright 2016 Microsoft
4  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
5  */
6 #include <mono/metadata/class-internals.h>
7 #include <mono/metadata/tabledefs.h>
8
9
10 typedef enum {
11         PROP_MARSHAL_INFO = 1, /* MonoMarshalType */
12         PROP_REF_INFO_HANDLE = 2, /* gchandle */
13         PROP_EXCEPTION_DATA = 3, /* MonoErrorBoxed* */
14         PROP_NESTED_CLASSES = 4, /* GList* */
15         PROP_PROPERTY_INFO = 5, /* MonoClassPropertyInfo* */
16         PROP_EVENT_INFO = 6, /* MonoClassEventInfo* */
17         PROP_FIELD_DEF_VALUES = 7, /* MonoFieldDefaultValue* */
18         PROP_DECLSEC_FLAGS = 8 /* guint32 */
19 }  InfrequentDataKind;
20
21 /* Accessors based on class kind*/
22
23 /*
24 * mono_class_get_generic_class:
25 *
26 *   Return the MonoGenericClass of @klass, which MUST be a generic instance.
27 */
28 MonoGenericClass*
29 mono_class_get_generic_class (MonoClass *klass)
30 {
31         g_assert (mono_class_is_ginst (klass));
32         return ((MonoClassGenericInst*)klass)->generic_class;
33 }
34
35 /*
36 * mono_class_try_get_generic_class:
37 *
38 *   Return the MonoGenericClass if @klass is a ginst, NULL otherwise
39 */
40 MonoGenericClass*
41 mono_class_try_get_generic_class (MonoClass *klass)
42 {
43         if (mono_class_is_ginst (klass))
44                 return ((MonoClassGenericInst*)klass)->generic_class;
45         return NULL;
46 }
47
48 /**
49  * mono_class_get_flags:
50  * @klass: the MonoClass to act on
51  *
52  * Return the TypeAttributes flags of @klass.
53  * See the TYPE_ATTRIBUTE_* definitions on tabledefs.h for the different values.
54  *
55  * Returns: The type flags
56  */
57 guint32
58 mono_class_get_flags (MonoClass *klass)
59 {
60         switch (klass->class_kind) {
61         case MONO_CLASS_DEF:
62         case MONO_CLASS_GTD:
63                 return ((MonoClassDef*)klass)->flags;
64         case MONO_CLASS_GINST:
65                 return mono_class_get_flags (((MonoClassGenericInst*)klass)->generic_class->container_class);
66         case MONO_CLASS_GPARAM:
67                 return TYPE_ATTRIBUTE_PUBLIC;
68         case MONO_CLASS_ARRAY:
69                 /* all arrays are marked serializable and sealed, bug #42779 */
70                 return TYPE_ATTRIBUTE_CLASS | TYPE_ATTRIBUTE_SERIALIZABLE | TYPE_ATTRIBUTE_SEALED | TYPE_ATTRIBUTE_PUBLIC;
71         case MONO_CLASS_POINTER:
72                 return TYPE_ATTRIBUTE_CLASS | (mono_class_get_flags (klass->element_class) & TYPE_ATTRIBUTE_VISIBILITY_MASK);
73         }
74         g_assert_not_reached ();
75 }
76
77 void
78 mono_class_set_flags (MonoClass *klass, guint32 flags)
79 {
80         g_assert (klass->class_kind == MONO_CLASS_DEF || klass->class_kind == MONO_CLASS_GTD);
81         ((MonoClassDef*)klass)->flags = flags;
82 }
83
84 /*
85  * mono_class_get_generic_container:
86  *
87  *   Return the generic container of KLASS which should be a generic type definition.
88  */
89 MonoGenericContainer*
90 mono_class_get_generic_container (MonoClass *klass)
91 {
92         g_assert (mono_class_is_gtd (klass));
93
94         return ((MonoClassGtd*)klass)->generic_container;
95 }
96
97 MonoGenericContainer*
98 mono_class_try_get_generic_container (MonoClass *klass)
99 {
100         if (mono_class_is_gtd (klass))
101                 return ((MonoClassGtd*)klass)->generic_container;
102         return NULL;
103 }
104
105
106 void
107 mono_class_set_generic_container (MonoClass *klass, MonoGenericContainer *container)
108 {
109         g_assert (mono_class_is_gtd (klass));
110
111         ((MonoClassGtd*)klass)->generic_container = container;
112 }
113
114 /*
115  * mono_class_get_first_method_idx:
116  *
117  *   Return the table index of the first method for metadata classes.
118  */
119 guint32
120 mono_class_get_first_method_idx (MonoClass *klass)
121 {
122         g_assert (mono_class_has_static_metadata (klass));
123
124         return ((MonoClassDef*)klass)->first_method_idx;
125 }
126
127 void
128 mono_class_set_first_method_idx (MonoClass *klass, guint32 idx)
129 {
130         g_assert (mono_class_has_static_metadata (klass));
131
132         ((MonoClassDef*)klass)->first_method_idx = idx;
133 }
134
135 guint32
136 mono_class_get_first_field_idx (MonoClass *klass)
137 {
138         if (mono_class_is_ginst (klass))
139                 return mono_class_get_first_field_idx (mono_class_get_generic_class (klass)->container_class);
140
141         g_assert (mono_class_has_static_metadata (klass));
142
143         return ((MonoClassDef*)klass)->first_field_idx;
144 }
145
146 void
147 mono_class_set_first_field_idx (MonoClass *klass, guint32 idx)
148 {
149         g_assert (mono_class_has_static_metadata (klass));
150
151         ((MonoClassDef*)klass)->first_field_idx = idx;
152 }
153
154 guint32
155 mono_class_get_method_count (MonoClass *klass)
156 {
157         switch (klass->class_kind) {
158         case MONO_CLASS_DEF:
159         case MONO_CLASS_GTD:
160                 return ((MonoClassDef*)klass)->method_count;
161         case MONO_CLASS_GINST:
162                 return mono_class_get_method_count (((MonoClassGenericInst*)klass)->generic_class->container_class);
163         case MONO_CLASS_GPARAM:
164                 return 0;
165         case MONO_CLASS_ARRAY:
166                 return ((MonoClassArray*)klass)->method_count;
167         case MONO_CLASS_POINTER:
168                 return 0;
169         default:
170                 g_assert_not_reached ();
171                 return 0;
172         }
173 }
174
175 void
176 mono_class_set_method_count (MonoClass *klass, guint32 count)
177 {
178         switch (klass->class_kind) {
179         case MONO_CLASS_DEF:
180         case MONO_CLASS_GTD:
181                 ((MonoClassDef*)klass)->method_count = count;
182                 break;
183         case MONO_CLASS_GINST:
184                 break;
185         case MONO_CLASS_GPARAM:
186         case MONO_CLASS_POINTER:
187                 g_assert (count == 0);
188                 break;
189         case MONO_CLASS_ARRAY:
190                 ((MonoClassArray*)klass)->method_count = count;
191                 break;
192         default:
193                 g_assert_not_reached ();
194                 break;
195         }
196 }
197
198 guint32
199 mono_class_get_field_count (MonoClass *klass)
200 {
201         switch (klass->class_kind) {
202         case MONO_CLASS_DEF:
203         case MONO_CLASS_GTD:
204                 return ((MonoClassDef*)klass)->field_count;
205         case MONO_CLASS_GINST:
206                 return mono_class_get_field_count (((MonoClassGenericInst*)klass)->generic_class->container_class);
207         case MONO_CLASS_GPARAM:
208         case MONO_CLASS_ARRAY:
209         case MONO_CLASS_POINTER:
210                 return 0;
211         default:
212                 g_assert_not_reached ();
213                 return 0;
214         }
215 }
216
217 void
218 mono_class_set_field_count (MonoClass *klass, guint32 count)
219 {
220         switch (klass->class_kind) {
221         case MONO_CLASS_DEF:
222         case MONO_CLASS_GTD:
223                 ((MonoClassDef*)klass)->field_count = count;
224                 break;
225         case MONO_CLASS_GINST:
226                 break;
227         case MONO_CLASS_GPARAM:
228         case MONO_CLASS_ARRAY:
229         case MONO_CLASS_POINTER:
230                 g_assert (count == 0);
231                 break;
232         default:
233                 g_assert_not_reached ();
234                 break;
235         }
236 }
237
238 MonoMarshalType*
239 mono_class_get_marshal_info (MonoClass *class)
240 {
241         return mono_property_bag_get (&class->infrequent_data, PROP_MARSHAL_INFO);
242 }
243
244 void
245 mono_class_set_marshal_info (MonoClass *class, MonoMarshalType *marshal_info)
246 {
247         marshal_info->head.tag = PROP_MARSHAL_INFO;
248         mono_property_bag_add (&class->infrequent_data, marshal_info);
249 }
250
251 typedef struct {
252         MonoPropertyBagItem head;
253         guint32 value;
254 } Uint32Property;
255
256 guint32
257 mono_class_get_ref_info_handle (MonoClass *class)
258 {
259         Uint32Property *prop = mono_property_bag_get (&class->infrequent_data, PROP_REF_INFO_HANDLE);
260         return prop ? prop->value : 0;
261 }
262
263 guint32
264 mono_class_set_ref_info_handle (MonoClass *class, guint32 value)
265 {
266         if (!value) {
267                 Uint32Property *prop = mono_property_bag_get (&class->infrequent_data, PROP_REF_INFO_HANDLE);
268                 if (prop)
269                         prop->value = 0;
270                 return 0;
271         }
272
273         Uint32Property *prop = mono_class_alloc (class, sizeof (Uint32Property));
274         prop->head.tag = PROP_REF_INFO_HANDLE;
275         prop->value = value;
276         prop = mono_property_bag_add (&class->infrequent_data, prop);
277         return prop->value;
278 }
279
280 typedef struct {
281         MonoPropertyBagItem head;
282         gpointer value;
283 } PointerProperty;
284
285 static void
286 set_pointer_property (MonoClass *klass, InfrequentDataKind property, gpointer value)
287 {
288         PointerProperty *prop = mono_class_alloc (klass, sizeof (PointerProperty));
289         prop->head.tag = property;
290         prop->value = value;
291         mono_property_bag_add (&klass->infrequent_data, prop);
292 }
293
294 static gpointer
295 get_pointer_property (MonoClass *klass, InfrequentDataKind property)
296 {
297         PointerProperty *prop = (PointerProperty*)mono_property_bag_get (&klass->infrequent_data, property);
298         return prop ? prop->value : NULL;
299 }
300
301 MonoErrorBoxed*
302 mono_class_get_exception_data (MonoClass *klass)
303 {
304         return (MonoErrorBoxed*)get_pointer_property (klass, PROP_EXCEPTION_DATA);
305 }
306
307 void
308 mono_class_set_exception_data (MonoClass *klass, MonoErrorBoxed *value)
309 {
310         set_pointer_property (klass, PROP_EXCEPTION_DATA, value);
311 }
312
313 GList*
314 mono_class_get_nested_classes_property (MonoClass *klass)
315 {
316         return (GList*)get_pointer_property (klass, PROP_NESTED_CLASSES);
317 }
318
319 void
320 mono_class_set_nested_classes_property (MonoClass *klass, GList *value)
321 {
322         set_pointer_property (klass, PROP_NESTED_CLASSES, value);
323 }
324
325 MonoClassPropertyInfo*
326 mono_class_get_property_info (MonoClass *klass)
327 {
328         return mono_property_bag_get (&klass->infrequent_data, PROP_PROPERTY_INFO);
329 }
330
331 void
332 mono_class_set_property_info (MonoClass *klass, MonoClassPropertyInfo *info)
333 {
334         info->head.tag = PROP_PROPERTY_INFO;
335         mono_property_bag_add (&klass->infrequent_data, info);
336 }
337
338 MonoClassEventInfo*
339 mono_class_get_event_info (MonoClass *klass)
340 {
341         return mono_property_bag_get (&klass->infrequent_data, PROP_EVENT_INFO);
342 }
343
344 void
345 mono_class_set_event_info (MonoClass *klass, MonoClassEventInfo *info)
346 {
347         info->head.tag = PROP_EVENT_INFO;
348         mono_property_bag_add (&klass->infrequent_data, info);
349 }
350
351 MonoFieldDefaultValue*
352 mono_class_get_field_def_values (MonoClass *klass)
353 {
354         return (MonoFieldDefaultValue*)get_pointer_property (klass, PROP_FIELD_DEF_VALUES);
355 }
356
357 void
358 mono_class_set_field_def_values (MonoClass *klass, MonoFieldDefaultValue *values)
359 {
360         set_pointer_property (klass, PROP_FIELD_DEF_VALUES, values);
361 }
362
363 guint32
364 mono_class_get_declsec_flags (MonoClass *class)
365 {
366         Uint32Property *prop = mono_property_bag_get (&class->infrequent_data, PROP_DECLSEC_FLAGS);
367         return prop ? prop->value : 0;
368 }
369
370 void
371 mono_class_set_declsec_flags (MonoClass *class, guint32 value)
372 {
373         Uint32Property *prop = mono_class_alloc (class, sizeof (Uint32Property));
374         prop->head.tag = PROP_DECLSEC_FLAGS;
375         prop->value = value;
376         mono_property_bag_add (&class->infrequent_data, prop);
377 }
378
379 void
380 mono_class_set_is_com_object (MonoClass *klass)
381 {
382 #ifndef DISABLE_COM
383         mono_loader_lock ();
384         klass->is_com_object = 1;
385         mono_loader_unlock ();
386 #endif
387 }