1 /*
2 * Objective-C type encoding support
3 *
4 * Copyright (C) 2012-2014 Free Software Foundation, Inc.
5 *
6 * Written by Marat Ibadinov <ibadinov@me.com>
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 * THE SOFTWARE.
25 */
26
27 #ifndef GS_TYPE_ENCODING_H
28 #define GS_TYPE_ENCODING_H
29
30 #include <GNUstepBase/GSVersionMacros.h>
31
32 #if defined(__MINGW__)
33 /* On MINGW we need to get the boolean type from the runtime at this point.
34 */
35 #define _NO_BOOL_TYPEDEF
36 #endif
37
38 #if defined (NeXT_RUNTIME)
39 # include <objc/objc-runtime.h>
40 #else
41 # include <objc/objc.h>
42 # if defined (__GNU_LIBOBJC__)
43 # include <objc/runtime.h>
44 # else
45 # include <objc/objc-api.h>
46 # include <objc/encoding.h>
47 # endif
48 #endif
49
50 #if !defined(GS_STATIC_INLINE)
51 # if defined(__GNUC__)
52 # define GS_STATIC_INLINE static __inline__ __attribute__((always_inline))
53 # else
54 # define GS_STATIC_INLINE static inline
55 # endif
56 #endif
57
58 /* type mangling is compiler independent so we can safely define this by hand */
59
60 typedef enum GSObjCTypeQualifier
61 {
62 GSObjCQualifierConst = 'r',
63 GSObjCQualifierIn = 'n',
64 GSObjCQualifierInOut = 'N',
65 GSObjCQualifierOut = 'o',
66 GSObjCQualifierByCopy = 'O',
67 GSObjCQualifierByRef = 'R',
68 GSObjCQualifierOneWay = 'V',
69 GSObjCQualifierInvisible = '!'
70 } GSObjCTypeQualifier;
71
72 typedef enum GSObjCType
73 {
74 GSObjCTypeId = '@',
75 GSObjCTypeClass = '#',
76 GSObjCTypeSelector = ':',
77 GSObjCTypeChar = 'c',
78 GSObjCTypeUnsignedChar = 'C',
79 GSObjCTypeShort = 's',
80 GSObjCTypeUnsignedShort = 'S',
81 GSObjCTypeInt = 'i',
82 GSObjCTypeUnsignedInt = 'I',
83 GSObjCTypeLong = 'l',
84 GSObjCTypeUnsignedLong = 'L',
85 GSObjCTypeLongLong = 'q',
86 GSObjCTypeUnsignedLongLong = 'Q',
87 GSObjCTypeFloat = 'f',
88 GSObjCTypeDouble = 'd',
89 GSObjCTypeComplex = 'j',
90 GSObjCTypeBitField = 'b',
91 GSObjCTypeBool = 'B',
92 GSObjCTypeVoid = 'v',
93 GSObjCTypePointer = '^',
94 GSObjCTypeCharPointer = '*',
95 GSObjCTypeAtom = '%',
96 GSObjCTypeArrayBegin = '[',
97 GSObjCTypeArrayEnd = ']',
98 GSObjCTypeStructureBegin = '{',
99 GSObjCTypeStructureEnd = '}',
100 GSObjCTypeUnionBegin = '(',
101 GSObjCTypeUnionEnd = ')',
102 GSObjCTypeUnknown = '?'
103 } GSObjCType;
104
105 /* maximum and minimum char values in a type specification */
106 typedef enum GSObjCTypeBound
107 {
108 GSObjCTypeMin = ' ',
109 GSObjCTypeMax = '~'
110 } GSObjCTypeBound;
111
112 #if defined (NeXT_RUNTIME)
113 typedef enum GSObjCTypeQualifierMask
114 {
115 GSObjCQualifierConstMask = 0x01,
116 GSObjCQualifierInMask = 0x01,
117 GSObjCQualifierOutMask = 0x02,
118 GSObjCQualifierInOutMask = 0x03,
119 GSObjCQualifierByCopyMask = 0x04,
120 GSObjCQualifierByRefMask = 0x08,
121 GSObjCQualifierOneWayMask = 0x10,
122 GSObjCQualifierInvisibleMask = 0x20
123 } GSObjCTypeQualifierMask;
124 #else
125 typedef enum GSObjCTypeQualifierMask
126 {
127 GSObjCQualifierConstMask = _F_CONST,
128 GSObjCQualifierInMask = _F_IN,
129 GSObjCQualifierOutMask = _F_OUT,
130 GSObjCQualifierInOutMask = _F_INOUT,
131 GSObjCQualifierByCopyMask = _F_BYCOPY,
132 GSObjCQualifierByRefMask = _F_BYREF,
133 GSObjCQualifierOneWayMask = _F_ONEWAY,
134 GSObjCQualifierInvisibleMask = _F_GCINVISIBLE
135 } GSObjCTypeQualifierMask;
136 #endif
137
138 /*
139 * parser-related stuff
140 */
141
142 typedef struct GSObjCTypeInfo {
143 /* store pointer to allow recursive parsing of pointer types, e.g. ^{^[2*]} */
144 const char *type;
145 size_t size;
146 uint8_t alignment;
147 uint8_t qualifiers;
148 } GSObjCTypeInfo;
149
150 typedef void (*GSObjCTypeParserDelegate)(void *context, GSObjCTypeInfo type);
151
152 typedef enum GSObjCParserOptions {
153 GSObjCReportArrayOnceMask = 1
154 } GSObjCParserOptions;
155
156 const char *
157 GSObjCParseTypeSpecification (const char *cursor,
158 GSObjCTypeParserDelegate delegate,
159 void *context,
160 unsigned options);
161
162 GS_STATIC_INLINE size_t
GSObjCPadSize(size_t size,uint8_t alignment)163 GSObjCPadSize (size_t size, uint8_t alignment)
164 {
165 return alignment * ((size + alignment - 1) / alignment);
166 }
167
168 GS_STATIC_INLINE size_t
GSObjCGetPadding(size_t size,uint8_t alignment)169 GSObjCGetPadding (size_t size, uint8_t alignment)
170 {
171 return (alignment - (size & (alignment - 1))) & (alignment - 1);
172 }
173
174 const char *
175 GSGetSizeAndAlignment (const char *type, size_t *sizep, uint8_t *alignp);
176
177
178 #if defined (NeXT_RUNTIME)
179
180 /* GNU API support for NeXT runtime */
181
182 int
183 objc_sizeof_type (const char* type);
184 int
185 objc_alignof_type (const char* type);
186 int
187 objc_aligned_size (const char* type);
188 int
189 objc_promoted_size (const char* type);
190
191 unsigned
192 objc_get_type_qualifiers (const char* type);
193
194 const char *
195 objc_skip_typespec (const char* type);
196 const char *
197 objc_skip_offset (const char* type);
198 const char *
199 objc_skip_argspec (const char* type);
200 const char *
201 objc_skip_type_qualifiers (const char* type);
202
203 struct objc_struct_layout
204 {
205 GSObjCTypeInfo *info;
206 long position;
207 unsigned count;
208 unsigned allocated;
209 unsigned depth;
210 unsigned offset;
211 unsigned alignment;
212 };
213
214 void
215 objc_layout_structure (const char *type,
216 struct objc_struct_layout *layout);
217
218 BOOL
219 objc_layout_structure_next_member (struct objc_struct_layout *layout);
220
221 void
222 objc_layout_structure_get_info (struct objc_struct_layout *layout,
223 unsigned int *offset,
224 unsigned int *align,
225 const char **type);
226
227 void
228 objc_layout_finish_structure (struct objc_struct_layout *layout,
229 unsigned int *size,
230 unsigned int *align);
231
232 #endif /* NeXT_RUNTIME */
233 #endif /* GS_TYPE_ENCODING_H */
234