File: | build/gcc/objc/objc-next-runtime-abi-02.c |
Warning: | line 1771, column 3 Called C++ object pointer is null |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* Next Runtime (ABI-2) private. | ||||
2 | Copyright (C) 2011-2021 Free Software Foundation, Inc. | ||||
3 | |||||
4 | Contributed by Iain Sandoe and based, in part, on an implementation in | ||||
5 | 'branches/apple/trunk' contributed by Apple Computer Inc. | ||||
6 | |||||
7 | This file is part of GCC. | ||||
8 | |||||
9 | GCC is free software; you can redistribute it and/or modify | ||||
10 | it under the terms of the GNU General Public License as published by | ||||
11 | the Free Software Foundation; either version 3, or (at your option) | ||||
12 | any later version. | ||||
13 | |||||
14 | GCC is distributed in the hope that it will be useful, | ||||
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||
17 | GNU General Public License for more details. | ||||
18 | |||||
19 | You should have received a copy of the GNU General Public License | ||||
20 | along with GCC; see the file COPYING3. If not see | ||||
21 | <http://www.gnu.org/licenses/>. */ | ||||
22 | |||||
23 | /* The NeXT ABI2 is used for m64 implementations on Darwin/OSX machines. | ||||
24 | |||||
25 | This version is intended to match (logically) the output of Apple's | ||||
26 | 4.2.1 compiler. */ | ||||
27 | |||||
28 | #include "config.h" | ||||
29 | #include "system.h" | ||||
30 | #include "coretypes.h" | ||||
31 | #include "tree.h" | ||||
32 | #include "stringpool.h" | ||||
33 | #include "attribs.h" | ||||
34 | |||||
35 | #ifdef OBJCPLUS | ||||
36 | #include "cp/cp-tree.h" | ||||
37 | #else | ||||
38 | #include "c/c-tree.h" | ||||
39 | #include "c/c-lang.h" | ||||
40 | #endif | ||||
41 | #include "langhooks.h" | ||||
42 | #include "c-family/c-objc.h" | ||||
43 | #include "objc-act.h" | ||||
44 | |||||
45 | /* When building Objective-C++, we are not linking against the C front-end | ||||
46 | and so need to replicate the C tree-construction functions in some way. */ | ||||
47 | #ifdef OBJCPLUS | ||||
48 | #define OBJCP_REMAP_FUNCTIONS | ||||
49 | #include "objcp-decl.h" | ||||
50 | #endif /* OBJCPLUS */ | ||||
51 | |||||
52 | #include "target.h" | ||||
53 | #include "tree-iterator.h" | ||||
54 | |||||
55 | #include "objc-runtime-hooks.h" | ||||
56 | #include "objc-runtime-shared-support.h" | ||||
57 | #include "objc-encoding.h" | ||||
58 | |||||
59 | /* ABI 2 Private definitions. */ | ||||
60 | #define DEF_CONSTANT_STRING_CLASS_NAME"NSConstantString" "NSConstantString" | ||||
61 | |||||
62 | #define TAG_GETCLASS"objc_getClass" "objc_getClass" | ||||
63 | #define TAG_GETMETACLASS"objc_getMetaClass" "objc_getMetaClass" | ||||
64 | |||||
65 | #define TAG_MSGSEND"objc_msgSend" "objc_msgSend" | ||||
66 | #define TAG_MSGSENDID"objc_msgSendId" "objc_msgSendId" | ||||
67 | #define TAG_MSGSENDSUPER"objc_msgSendSuper2" "objc_msgSendSuper2" | ||||
68 | #define TAG_MSGSEND_STRET"objc_msgSend_stret" "objc_msgSend_stret" | ||||
69 | #define TAG_MSGSENDID_STRET"objc_msgSendId_stret" "objc_msgSendId_stret" | ||||
70 | #define TAG_MSGSENDSUPER_STRET"objc_msgSendSuper2_stret" "objc_msgSendSuper2_stret" | ||||
71 | |||||
72 | #define USE_FIXUP_BEFORE100600 100600 | ||||
73 | #define TAG_FIXUP"_fixup" "_fixup" | ||||
74 | |||||
75 | |||||
76 | #define TAG_NEXT_EHVTABLE_NAME"objc_ehtype_vtable" "objc_ehtype_vtable" | ||||
77 | #define TAG_V2_EH_TYPE"objc_ehtype_t" "objc_ehtype_t" | ||||
78 | |||||
79 | #define UTAG_V2_CLASS"_class_t" "_class_t" | ||||
80 | #define UTAG_V2_CLASS_RO"_class_ro_t" "_class_ro_t" | ||||
81 | #define UTAG_V2_PROTOCOL"_protocol_t" "_protocol_t" | ||||
82 | #define UTAG_V2_PROTOCOL_LIST"_protocol_list_t" "_protocol_list_t" | ||||
83 | |||||
84 | #define UTAG_V2_EH_TYPE"_objc_ehtype_t" "_objc_ehtype_t" | ||||
85 | |||||
86 | #define OBJC2_CLS_HAS_CXX_STRUCTORS0x0004L 0x0004L | ||||
87 | |||||
88 | enum objc_v2_tree_index | ||||
89 | { | ||||
90 | /* Templates. */ | ||||
91 | OCTI_V2_CLS_TEMPL, | ||||
92 | OCTI_V2_CAT_TEMPL, | ||||
93 | OCTI_V2_CLS_RO_TEMPL, | ||||
94 | OCTI_V2_PROTO_TEMPL, | ||||
95 | OCTI_V2_IVAR_TEMPL, | ||||
96 | OCTI_V2_IVAR_LIST_TEMPL, | ||||
97 | OCTI_V2_MESSAGE_REF_TEMPL, | ||||
98 | OCTI_V2_SUPER_MESSAGE_REF_TEMPL, | ||||
99 | |||||
100 | OCTI_V2_MESSAGE_SELECTOR_TYPE, | ||||
101 | OCTI_V2_SUPER_MESSAGE_SELECTOR_TYPE, | ||||
102 | OCTI_V2_IMP_TYPE, | ||||
103 | OCTI_V2_SUPER_IMP_TYPE, | ||||
104 | |||||
105 | OCTI_V2_CACHE_DECL, | ||||
106 | OCTI_V2_VTABLE_DECL, | ||||
107 | |||||
108 | OCTI_V2_PROPERTY_TEMPL, | ||||
109 | |||||
110 | /* V2 messaging. */ | ||||
111 | OCTI_V2_UMSG_FIXUP_DECL, | ||||
112 | OCTI_V2_UMSG_STRET_FIXUP_DECL, | ||||
113 | OCTI_V2_UMSG_ID_FIXUP_DECL, | ||||
114 | OCTI_V2_UMSG_ID_STRET_FIXUP_DECL, | ||||
115 | OCTI_V2_UMSG_SUPER2_FIXUP_DECL, | ||||
116 | OCTI_V2_UMSG_SUPER2_STRET_FIXUP_DECL, | ||||
117 | |||||
118 | /* Exceptions - related. */ | ||||
119 | OCTI_V2_BEGIN_CATCH_DECL, | ||||
120 | OCTI_V2_END_CATCH_DECL, | ||||
121 | OCTI_V2_RETHROW_DECL, | ||||
122 | |||||
123 | OCTI_V2_MAX | ||||
124 | }; | ||||
125 | |||||
126 | #define objc_v2_class_templateobjc_v2_global_trees[OCTI_V2_CLS_TEMPL] objc_v2_global_trees[OCTI_V2_CLS_TEMPL] | ||||
127 | #define objc_v2_class_ro_templateobjc_v2_global_trees[OCTI_V2_CLS_RO_TEMPL] \ | ||||
128 | objc_v2_global_trees[OCTI_V2_CLS_RO_TEMPL] | ||||
129 | #define objc_v2_category_templateobjc_v2_global_trees[OCTI_V2_CAT_TEMPL] \ | ||||
130 | objc_v2_global_trees[OCTI_V2_CAT_TEMPL] | ||||
131 | #define objc_v2_protocol_templateobjc_v2_global_trees[OCTI_V2_PROTO_TEMPL] \ | ||||
132 | objc_v2_global_trees[OCTI_V2_PROTO_TEMPL] | ||||
133 | |||||
134 | /* struct message_ref_t */ | ||||
135 | #define objc_v2_message_ref_templateobjc_v2_global_trees[OCTI_V2_MESSAGE_REF_TEMPL] \ | ||||
136 | objc_v2_global_trees[OCTI_V2_MESSAGE_REF_TEMPL] | ||||
137 | |||||
138 | #define objc_v2_ivar_list_ptrobjc_v2_global_trees[OCTI_V2_IVAR_LIST_TEMPL] objc_v2_global_trees[OCTI_V2_IVAR_LIST_TEMPL] | ||||
139 | |||||
140 | /* struct super_message_ref_t */ | ||||
141 | #define objc_v2_super_message_ref_templateobjc_v2_global_trees[OCTI_V2_SUPER_MESSAGE_REF_TEMPL] \ | ||||
142 | objc_v2_global_trees[OCTI_V2_SUPER_MESSAGE_REF_TEMPL] | ||||
143 | |||||
144 | /* struct message_ref_t* */ | ||||
145 | #define objc_v2_selector_typeobjc_v2_global_trees[OCTI_V2_MESSAGE_SELECTOR_TYPE] objc_v2_global_trees[OCTI_V2_MESSAGE_SELECTOR_TYPE] | ||||
146 | /* struct super_super_message_ref_t */ | ||||
147 | #define objc_v2_super_selector_typeobjc_v2_global_trees[OCTI_V2_SUPER_MESSAGE_SELECTOR_TYPE] \ | ||||
148 | objc_v2_global_trees[OCTI_V2_SUPER_MESSAGE_SELECTOR_TYPE] | ||||
149 | #define objc_v2_imp_typeobjc_v2_global_trees[OCTI_V2_IMP_TYPE] objc_v2_global_trees[OCTI_V2_IMP_TYPE] | ||||
150 | #define objc_v2_super_imp_typeobjc_v2_global_trees[OCTI_V2_SUPER_IMP_TYPE] objc_v2_global_trees[OCTI_V2_SUPER_IMP_TYPE] | ||||
151 | |||||
152 | #define UOBJC_V2_CACHE_declobjc_v2_global_trees[OCTI_V2_CACHE_DECL] objc_v2_global_trees[OCTI_V2_CACHE_DECL] | ||||
153 | #define UOBJC_V2_VTABLE_declobjc_v2_global_trees[OCTI_V2_VTABLE_DECL] objc_v2_global_trees[OCTI_V2_VTABLE_DECL] | ||||
154 | |||||
155 | #define objc_v2_ivar_templateobjc_v2_global_trees[OCTI_V2_IVAR_TEMPL] objc_v2_global_trees[OCTI_V2_IVAR_TEMPL] | ||||
156 | #define objc_v2_property_templateobjc_v2_global_trees[OCTI_V2_PROPERTY_TEMPL] \ | ||||
157 | objc_v2_global_trees[OCTI_V2_PROPERTY_TEMPL] | ||||
158 | |||||
159 | /* V2 Messaging */ | ||||
160 | |||||
161 | /* objc_msgSend_fixup_rtp */ | ||||
162 | #define umsg_fixup_declobjc_v2_global_trees[OCTI_V2_UMSG_FIXUP_DECL] objc_v2_global_trees[OCTI_V2_UMSG_FIXUP_DECL] | ||||
163 | /* objc_msgSend_stret_fixup_rtp */ | ||||
164 | #define umsg_stret_fixup_declobjc_v2_global_trees[OCTI_V2_UMSG_STRET_FIXUP_DECL] objc_v2_global_trees[OCTI_V2_UMSG_STRET_FIXUP_DECL] | ||||
165 | /* objc_msgSendId_fixup_rtp */ | ||||
166 | #define umsg_id_fixup_declobjc_v2_global_trees[OCTI_V2_UMSG_ID_FIXUP_DECL] objc_v2_global_trees[OCTI_V2_UMSG_ID_FIXUP_DECL] | ||||
167 | /* objc_msgSendId_stret_fixup_rtp */ | ||||
168 | #define umsg_id_stret_fixup_declobjc_v2_global_trees[OCTI_V2_UMSG_ID_STRET_FIXUP_DECL] \ | ||||
169 | objc_v2_global_trees[OCTI_V2_UMSG_ID_STRET_FIXUP_DECL] | ||||
170 | /* objc_msgSendSuper2_fixup_rtp */ | ||||
171 | #define umsg_id_super2_fixup_declobjc_v2_global_trees[OCTI_V2_UMSG_SUPER2_FIXUP_DECL] \ | ||||
172 | objc_v2_global_trees[OCTI_V2_UMSG_SUPER2_FIXUP_DECL] | ||||
173 | /* objc_msgSendSuper2_stret_fixup_rtp */ | ||||
174 | #define umsg_id_super2_stret_fixup_declobjc_v2_global_trees[OCTI_V2_UMSG_SUPER2_STRET_FIXUP_DECL] \ | ||||
175 | objc_v2_global_trees[OCTI_V2_UMSG_SUPER2_STRET_FIXUP_DECL] | ||||
176 | |||||
177 | #define objc2_begin_catch_declobjc_v2_global_trees[OCTI_V2_BEGIN_CATCH_DECL] objc_v2_global_trees[OCTI_V2_BEGIN_CATCH_DECL] | ||||
178 | #define objc2_end_catch_declobjc_v2_global_trees[OCTI_V2_END_CATCH_DECL] objc_v2_global_trees[OCTI_V2_END_CATCH_DECL] | ||||
179 | #define objc_rethrow_exception_declobjc_v2_global_trees[OCTI_V2_RETHROW_DECL] \ | ||||
180 | objc_v2_global_trees[OCTI_V2_RETHROW_DECL] | ||||
181 | |||||
182 | /* rt_trees identifiers - shared between NeXT implementations. These allow | ||||
183 | the FE to tag meta-data in a manner that survives LTO and can be used when | ||||
184 | the runtime requires that certain meta-data items appear in particular | ||||
185 | named sections. */ | ||||
186 | |||||
187 | #include "objc-next-metadata-tags.h" | ||||
188 | extern GTY(()) tree objc_rt_trees[OCTI_RT_META_MAX]; | ||||
189 | |||||
190 | /* The OCTI_V2_... enumeration itself is in above. */ | ||||
191 | static GTY(()) tree objc_v2_global_trees[OCTI_V2_MAX]; | ||||
192 | |||||
193 | static void next_runtime_02_initialize (void); | ||||
194 | |||||
195 | static void build_v2_message_ref_templates (void); | ||||
196 | static void build_v2_class_templates (void); | ||||
197 | static void build_v2_super_template (void); | ||||
198 | static void build_v2_category_template (void); | ||||
199 | static void build_v2_protocol_template (void); | ||||
200 | |||||
201 | static tree next_runtime_abi_02_super_superclassfield_id (void); | ||||
202 | |||||
203 | static tree next_runtime_abi_02_class_decl (tree); | ||||
204 | static tree next_runtime_abi_02_metaclass_decl (tree); | ||||
205 | static tree next_runtime_abi_02_category_decl (tree); | ||||
206 | static tree next_runtime_abi_02_protocol_decl (tree); | ||||
207 | static tree next_runtime_abi_02_string_decl (tree, const char *, string_section); | ||||
208 | |||||
209 | static tree next_runtime_abi_02_get_class_reference (tree); | ||||
210 | static tree next_runtime_abi_02_build_selector_reference (location_t, tree, tree); | ||||
211 | static tree next_runtime_abi_02_get_protocol_reference (location_t, tree); | ||||
212 | static tree next_runtime_abi_02_build_ivar_ref (location_t, tree, tree); | ||||
213 | static tree next_runtime_abi_02_get_class_super_ref (location_t, struct imp_entry *, bool); | ||||
214 | static tree next_runtime_abi_02_get_category_super_ref (location_t, struct imp_entry *, bool); | ||||
215 | |||||
216 | static tree next_runtime_abi_02_receiver_is_class_object (tree); | ||||
217 | static void next_runtime_abi_02_get_arg_type_list_base (vec<tree, va_gc> **, | ||||
218 | tree, int, int); | ||||
219 | static tree next_runtime_abi_02_build_objc_method_call (location_t, tree, tree, | ||||
220 | tree, tree, tree, int); | ||||
221 | static bool next_runtime_abi_02_setup_const_string_class_decl (void); | ||||
222 | static tree next_runtime_abi_02_build_const_string_constructor (location_t, tree, int); | ||||
223 | |||||
224 | static tree create_extern_decl (tree, const char *); | ||||
225 | |||||
226 | static void objc_generate_v2_next_metadata (void); | ||||
227 | static bool objc2_objc_exception_attr (tree); | ||||
228 | |||||
229 | /* void build_v2_protocol_reference (tree);*/ | ||||
230 | static void build_v2_ehtype_template (void); | ||||
231 | static void build_v2_eh_catch_objects (void); | ||||
232 | static tree next_runtime_02_eh_type (tree); | ||||
233 | static tree objc_eh_personality (void); | ||||
234 | static tree build_throw_stmt (location_t, tree, bool); | ||||
235 | static tree objc_build_exc_ptr (struct objc_try_context **); | ||||
236 | static tree begin_catch (struct objc_try_context **, tree, tree, tree, bool); | ||||
237 | static void finish_catch (struct objc_try_context **, tree); | ||||
238 | static tree finish_try_stmt (struct objc_try_context **); | ||||
239 | |||||
240 | /* TODO: Use an objc-map. */ | ||||
241 | static GTY ((length ("SIZEHASHTABLE"))) hash *extern_names; | ||||
242 | |||||
243 | bool | ||||
244 | objc_next_runtime_abi_02_init (objc_runtime_hooks *rthooks) | ||||
245 | { | ||||
246 | extern_names = ggc_cleared_vec_alloc<hash> (SIZEHASHTABLE257); | ||||
247 | |||||
248 | if (flag_objc_exceptionsglobal_options.x_flag_objc_exceptions && flag_objc_sjlj_exceptionsglobal_options.x_flag_objc_sjlj_exceptions) | ||||
249 | { | ||||
250 | inform (UNKNOWN_LOCATION((location_t) 0), | ||||
251 | "%<-fobjc-sjlj-exceptions%> is ignored for " | ||||
252 | "%<-fnext-runtime%> when %<-fobjc-abi-version%> " | ||||
253 | "greater than 1"); | ||||
254 | flag_objc_sjlj_exceptionsglobal_options.x_flag_objc_sjlj_exceptions = 0; | ||||
255 | } | ||||
256 | |||||
257 | rthooks->initialize = next_runtime_02_initialize; | ||||
258 | rthooks->default_constant_string_class_name = DEF_CONSTANT_STRING_CLASS_NAME"NSConstantString"; | ||||
259 | rthooks->tag_getclass = TAG_GETCLASS"objc_getClass"; | ||||
260 | rthooks->super_superclassfield_ident = next_runtime_abi_02_super_superclassfield_id; | ||||
261 | |||||
262 | rthooks->class_decl = next_runtime_abi_02_class_decl; | ||||
263 | rthooks->metaclass_decl = next_runtime_abi_02_metaclass_decl; | ||||
264 | rthooks->category_decl = next_runtime_abi_02_category_decl; | ||||
265 | rthooks->protocol_decl = next_runtime_abi_02_protocol_decl; | ||||
266 | rthooks->string_decl = next_runtime_abi_02_string_decl; | ||||
267 | |||||
268 | rthooks->get_class_reference = next_runtime_abi_02_get_class_reference; | ||||
269 | rthooks->build_selector_reference = next_runtime_abi_02_build_selector_reference; | ||||
270 | rthooks->get_protocol_reference = next_runtime_abi_02_get_protocol_reference; | ||||
271 | rthooks->build_ivar_reference = next_runtime_abi_02_build_ivar_ref; | ||||
272 | rthooks->get_class_super_ref = next_runtime_abi_02_get_class_super_ref; | ||||
273 | rthooks->get_category_super_ref = next_runtime_abi_02_get_category_super_ref; | ||||
274 | |||||
275 | rthooks->receiver_is_class_object = next_runtime_abi_02_receiver_is_class_object; | ||||
276 | rthooks->get_arg_type_list_base = next_runtime_abi_02_get_arg_type_list_base; | ||||
277 | rthooks->build_objc_method_call = next_runtime_abi_02_build_objc_method_call; | ||||
278 | |||||
279 | rthooks->setup_const_string_class_decl = | ||||
280 | next_runtime_abi_02_setup_const_string_class_decl; | ||||
281 | rthooks->build_const_string_constructor = | ||||
282 | next_runtime_abi_02_build_const_string_constructor; | ||||
283 | |||||
284 | rthooks->build_throw_stmt = build_throw_stmt; | ||||
285 | rthooks->build_exc_ptr = objc_build_exc_ptr; | ||||
286 | rthooks->begin_catch = begin_catch; | ||||
287 | rthooks->finish_catch = finish_catch; | ||||
288 | rthooks->finish_try_stmt = finish_try_stmt; | ||||
289 | |||||
290 | rthooks->generate_metadata = objc_generate_v2_next_metadata; | ||||
291 | return true; | ||||
292 | } | ||||
293 | |||||
294 | /* We need a way to convey what kind of meta-data are represented by a given | ||||
295 | variable, since each type is expected (by the runtime) to be found in a | ||||
296 | specific named section. The solution must be usable with LTO. | ||||
297 | |||||
298 | The scheme used for NeXT ABI 0/1 (partial matching of variable names) is not | ||||
299 | satisfactory when LTO is used with ABI-2. We now tag ObjC meta-data with | ||||
300 | identification attributes in the front end. The back-end may choose to act | ||||
301 | on these as it requires. */ | ||||
302 | |||||
303 | static void | ||||
304 | next_runtime_abi_02_init_metadata_attributes (void) | ||||
305 | { | ||||
306 | if (!objc_metaobjc_rt_trees[OCTI_RT_OBJC_META]) | ||||
307 | objc_metaobjc_rt_trees[OCTI_RT_OBJC_META] = get_identifier ("OBJC2META")(__builtin_constant_p ("OBJC2META") ? get_identifier_with_length (("OBJC2META"), strlen ("OBJC2META")) : get_identifier ("OBJC2META" )); | ||||
308 | |||||
309 | if (!meta_baseobjc_rt_trees[OCTI_RT_META_BASE]) | ||||
310 | meta_baseobjc_rt_trees[OCTI_RT_META_BASE] = get_identifier ("V2_BASE")(__builtin_constant_p ("V2_BASE") ? get_identifier_with_length (("V2_BASE"), strlen ("V2_BASE")) : get_identifier ("V2_BASE" )); | ||||
311 | |||||
312 | meta_classobjc_rt_trees[OCTI_RT_META_CLASS] = get_identifier ("G2_CLAS")(__builtin_constant_p ("G2_CLAS") ? get_identifier_with_length (("G2_CLAS"), strlen ("G2_CLAS")) : get_identifier ("G2_CLAS" )); | ||||
313 | meta_metaclassobjc_rt_trees[OCTI_RT_META_METACLASS] = get_identifier ("G2_META")(__builtin_constant_p ("G2_META") ? get_identifier_with_length (("G2_META"), strlen ("G2_META")) : get_identifier ("G2_META" )); | ||||
314 | meta_categoryobjc_rt_trees[OCTI_RT_META_CATEGORY] = meta_baseobjc_rt_trees[OCTI_RT_META_BASE]; | ||||
315 | meta_protocolobjc_rt_trees[OCTI_RT_META_PROTOCOL] = get_identifier ("V2_PCOL")(__builtin_constant_p ("V2_PCOL") ? get_identifier_with_length (("V2_PCOL"), strlen ("V2_PCOL")) : get_identifier ("V2_PCOL" )); | ||||
316 | |||||
317 | meta_clac_varsobjc_rt_trees[OCTI_RT_META_CLASS_CLS_VARS] = | ||||
318 | meta_clai_varsobjc_rt_trees[OCTI_RT_META_CLASS_NST_VARS] = meta_baseobjc_rt_trees[OCTI_RT_META_BASE]; | ||||
319 | |||||
320 | meta_clac_methobjc_rt_trees[OCTI_RT_META_CLASS_CLS_METH] = | ||||
321 | meta_clai_methobjc_rt_trees[OCTI_RT_META_CLASS_NST_METH] = | ||||
322 | meta_catc_methobjc_rt_trees[OCTI_RT_META_CATEG_CLS_METH] = | ||||
323 | meta_cati_methobjc_rt_trees[OCTI_RT_META_CATEG_NST_METH] = | ||||
324 | meta_proto_cls_methobjc_rt_trees[OCTI_RT_META_PROTO_CLS_METH] = | ||||
325 | meta_proto_nst_methobjc_rt_trees[OCTI_RT_META_PROTO_NST_METH] = meta_baseobjc_rt_trees[OCTI_RT_META_BASE]; | ||||
326 | |||||
327 | meta_clas_protobjc_rt_trees[OCTI_RT_META_CLASS_PROT] = | ||||
328 | meta_catg_protobjc_rt_trees[OCTI_RT_META_CATEG_PROT] = meta_baseobjc_rt_trees[OCTI_RT_META_BASE]; | ||||
329 | |||||
330 | meta_sel_refsobjc_rt_trees[OCTI_RT_META_SEL_REFS] = get_identifier ("V2_SRFS")(__builtin_constant_p ("V2_SRFS") ? get_identifier_with_length (("V2_SRFS"), strlen ("V2_SRFS")) : get_identifier ("V2_SRFS" )); | ||||
331 | |||||
332 | meta_class_nameobjc_rt_trees[OCTI_RT_META_CLASS_NAME] = get_identifier ("V2_CNAM")(__builtin_constant_p ("V2_CNAM") ? get_identifier_with_length (("V2_CNAM"), strlen ("V2_CNAM")) : get_identifier ("V2_CNAM" )); | ||||
333 | meta_meth_nameobjc_rt_trees[OCTI_RT_META_METHD_NAME] = get_identifier ("V2_MNAM")(__builtin_constant_p ("V2_MNAM") ? get_identifier_with_length (("V2_MNAM"), strlen ("V2_MNAM")) : get_identifier ("V2_MNAM" )); | ||||
334 | |||||
335 | meta_meth_typeobjc_rt_trees[OCTI_RT_META_METHD_TYPE] = get_identifier ("V2_MTYP")(__builtin_constant_p ("V2_MTYP") ? get_identifier_with_length (("V2_MTYP"), strlen ("V2_MTYP")) : get_identifier ("V2_MTYP" )); | ||||
336 | meta_prop_name_attrobjc_rt_trees[OCTI_RT_META_PROPN_ATTR] = get_identifier ("V2_STRG")(__builtin_constant_p ("V2_STRG") ? get_identifier_with_length (("V2_STRG"), strlen ("V2_STRG")) : get_identifier ("V2_STRG" )); | ||||
337 | |||||
338 | meta_mrefobjc_rt_trees[OCTI_RT_META_MSG_REFS] = get_identifier ("V2_MREF")(__builtin_constant_p ("V2_MREF") ? get_identifier_with_length (("V2_MREF"), strlen ("V2_MREF")) : get_identifier ("V2_MREF" )); | ||||
339 | meta_class_refobjc_rt_trees[OCTI_RT_META_CLSLST_REFS] = get_identifier ("V2_CLRF")(__builtin_constant_p ("V2_CLRF") ? get_identifier_with_length (("V2_CLRF"), strlen ("V2_CLRF")) : get_identifier ("V2_CLRF" )); | ||||
340 | meta_superclass_refobjc_rt_trees[OCTI_RT_META_SUPER_REF] = get_identifier ("V2_SURF")(__builtin_constant_p ("V2_SURF") ? get_identifier_with_length (("V2_SURF"), strlen ("V2_SURF")) : get_identifier ("V2_SURF" )); | ||||
341 | |||||
342 | meta_label_classlistobjc_rt_trees[OCTI_RT_META_CLSLST_LAB] = get_identifier ("V2_CLAB")(__builtin_constant_p ("V2_CLAB") ? get_identifier_with_length (("V2_CLAB"), strlen ("V2_CLAB")) : get_identifier ("V2_CLAB" )); | ||||
343 | meta_label_nonlazy_classlistobjc_rt_trees[OCTI_RT_META_CLSLST_NLZY_LAB] = get_identifier ("V2_NLCL")(__builtin_constant_p ("V2_NLCL") ? get_identifier_with_length (("V2_NLCL"), strlen ("V2_NLCL")) : get_identifier ("V2_NLCL" )); | ||||
344 | meta_label_categorylistobjc_rt_trees[OCTI_RT_META_LAB_CAT] = get_identifier ("V2_CALA")(__builtin_constant_p ("V2_CALA") ? get_identifier_with_length (("V2_CALA"), strlen ("V2_CALA")) : get_identifier ("V2_CALA" )); | ||||
345 | meta_label_nonlazy_categorylistobjc_rt_trees[OCTI_RT_META_LAB_NLZY_CAT] = get_identifier ("V2_NLCA")(__builtin_constant_p ("V2_NLCA") ? get_identifier_with_length (("V2_NLCA"), strlen ("V2_NLCA")) : get_identifier ("V2_NLCA" )); | ||||
346 | |||||
347 | meta_label_protocollistobjc_rt_trees[OCTI_RT_META_LAB_PROTOLIST] = get_identifier ("V2_PLST")(__builtin_constant_p ("V2_PLST") ? get_identifier_with_length (("V2_PLST"), strlen ("V2_PLST")) : get_identifier ("V2_PLST" )); | ||||
348 | meta_proto_refobjc_rt_trees[OCTI_RT_META_PROT_REFS] = get_identifier ("V2_PRFS")(__builtin_constant_p ("V2_PRFS") ? get_identifier_with_length (("V2_PRFS"), strlen ("V2_PRFS")) : get_identifier ("V2_PRFS" )); | ||||
349 | |||||
350 | meta_infoobjc_rt_trees[OCTI_RT_META_INFO] = get_identifier ("V2_INFO")(__builtin_constant_p ("V2_INFO") ? get_identifier_with_length (("V2_INFO"), strlen ("V2_INFO")) : get_identifier ("V2_INFO" )); | ||||
351 | |||||
352 | meta_ehtypeobjc_rt_trees[OCTI_RT_META_EHTYPE] = get_identifier ("V2_EHTY")(__builtin_constant_p ("V2_EHTY") ? get_identifier_with_length (("V2_EHTY"), strlen ("V2_EHTY")) : get_identifier ("V2_EHTY" )); | ||||
353 | |||||
354 | meta_const_strobjc_rt_trees[OCTI_RT_META_CONST_STR] = get_identifier ("V2_CSTR")(__builtin_constant_p ("V2_CSTR") ? get_identifier_with_length (("V2_CSTR"), strlen ("V2_CSTR")) : get_identifier ("V2_CSTR" )); | ||||
355 | |||||
356 | meta_ivar_refobjc_rt_trees[OCTI_RT_META_IVAR_REF] = get_identifier ("V2_IVRF")(__builtin_constant_p ("V2_IVRF") ? get_identifier_with_length (("V2_IVRF"), strlen ("V2_IVRF")) : get_identifier ("V2_IVRF" )); | ||||
357 | } | ||||
358 | |||||
359 | static void next_runtime_02_initialize (void) | ||||
360 | { | ||||
361 | tree type; | ||||
362 | #ifdef OBJCPLUS | ||||
363 | /* For all NeXT objc ABIs -fobjc-call-cxx-cdtors is on by | ||||
364 | default. */ | ||||
365 | if (!global_options_set.x_flag_objc_call_cxx_cdtors) | ||||
366 | global_options.x_flag_objc_call_cxx_cdtors = 1; | ||||
367 | #endif | ||||
368 | |||||
369 | /* Set up attributes to be attached to the meta-data so that they | ||||
370 | will be placed in the correct sections. */ | ||||
371 | next_runtime_abi_02_init_metadata_attributes (); | ||||
372 | |||||
373 | /* `struct objc_selector *' */ | ||||
374 | objc_selector_typeobjc_global_trees[OCTI_SEL_TYPE] = build_pointer_type (xref_tag (RECORD_TYPE, | ||||
375 | get_identifier (TAG_SELECTOR)(__builtin_constant_p ("objc_selector") ? get_identifier_with_length (("objc_selector"), strlen ("objc_selector")) : get_identifier ("objc_selector")))); | ||||
376 | |||||
377 | /* SEL typedef. */ | ||||
378 | type = lang_hooks.decls.pushdecl (build_decl (input_location, | ||||
379 | TYPE_DECL, | ||||
380 | objc_selector_nameobjc_global_trees[OCTI_SEL_NAME], | ||||
381 | objc_selector_typeobjc_global_trees[OCTI_SEL_TYPE])); | ||||
382 | TREE_NO_WARNING (type)((type)->base.nowarning_flag) = 1; | ||||
383 | |||||
384 | /* IMP : id (*) (id, _message_ref_t*, ...) | ||||
385 | SUPER_IMP : id (*) ( super_t*, _super_message_ref_t*, ...) | ||||
386 | objc_v2_selector_type. */ | ||||
387 | build_v2_message_ref_templates (); | ||||
388 | |||||
389 | objc_v2_ivar_list_ptrobjc_v2_global_trees[OCTI_V2_IVAR_LIST_TEMPL] = | ||||
390 | build_pointer_type (xref_tag (RECORD_TYPE, | ||||
391 | get_identifier ("_ivar_list_t")(__builtin_constant_p ("_ivar_list_t") ? get_identifier_with_length (("_ivar_list_t"), strlen ("_ivar_list_t")) : get_identifier ("_ivar_list_t")))); | ||||
392 | |||||
393 | objc_prop_list_ptrobjc_global_trees[OCTI_V1_PROP_LIST_TEMPL] = | ||||
394 | build_pointer_type (xref_tag (RECORD_TYPE, | ||||
395 | get_identifier ("_prop_list_t")(__builtin_constant_p ("_prop_list_t") ? get_identifier_with_length (("_prop_list_t"), strlen ("_prop_list_t")) : get_identifier ("_prop_list_t")))); | ||||
396 | |||||
397 | build_v2_class_templates (); | ||||
398 | build_v2_super_template (); | ||||
399 | build_v2_protocol_template (); | ||||
400 | build_v2_category_template (); | ||||
401 | |||||
402 | bool fixup_p = flag_next_runtimeglobal_options.x_flag_next_runtime < USE_FIXUP_BEFORE100600; | ||||
403 | if (fixup_p) | ||||
404 | { | ||||
405 | /* id objc_msgSend_fixup_rtp (id, struct message_ref_t*, ...); */ | ||||
406 | type = build_varargs_function_type_list (objc_object_typeobjc_global_trees[OCTI_ID_TYPE], | ||||
407 | objc_object_typeobjc_global_trees[OCTI_ID_TYPE], | ||||
408 | objc_v2_selector_typeobjc_v2_global_trees[OCTI_V2_MESSAGE_SELECTOR_TYPE], | ||||
409 | NULL_TREE(tree) nullptr); | ||||
410 | } | ||||
411 | else | ||||
412 | { | ||||
413 | /* id objc_msgSendXXXX (id, SEL, ...); */ | ||||
414 | type = build_varargs_function_type_list (objc_object_typeobjc_global_trees[OCTI_ID_TYPE], | ||||
415 | objc_object_typeobjc_global_trees[OCTI_ID_TYPE], | ||||
416 | objc_selector_typeobjc_global_trees[OCTI_SEL_TYPE], | ||||
417 | NULL_TREE(tree) nullptr); | ||||
418 | } | ||||
419 | const char *fnam = fixup_p ? TAG_MSGSEND"objc_msgSend" TAG_FIXUP"_fixup" : TAG_MSGSEND"objc_msgSend"; | ||||
420 | umsg_fixup_declobjc_v2_global_trees[OCTI_V2_UMSG_FIXUP_DECL] = add_builtin_function (fnam, type, 0, NOT_BUILT_IN, | ||||
421 | NULLnullptr, NULL_TREE(tree) nullptr); | ||||
422 | TREE_NOTHROW (umsg_fixup_decl)((objc_v2_global_trees[OCTI_V2_UMSG_FIXUP_DECL])->base.nothrow_flag ) = 0; | ||||
423 | |||||
424 | /* id objc_msgSend_stret_fixup_rtp (id, struct message_ref_t*, ...); */ | ||||
425 | fnam = fixup_p ? TAG_MSGSEND_STRET"objc_msgSend_stret" TAG_FIXUP"_fixup" : TAG_MSGSEND_STRET"objc_msgSend_stret"; | ||||
426 | umsg_stret_fixup_declobjc_v2_global_trees[OCTI_V2_UMSG_STRET_FIXUP_DECL] = add_builtin_function (fnam, type, 0, NOT_BUILT_IN, | ||||
427 | NULLnullptr, NULL_TREE(tree) nullptr); | ||||
428 | TREE_NOTHROW (umsg_stret_fixup_decl)((objc_v2_global_trees[OCTI_V2_UMSG_STRET_FIXUP_DECL])->base .nothrow_flag) = 0; | ||||
429 | |||||
430 | /* id objc_msgSendId_fixup_rtp (id, struct message_ref_t*, ...); */ | ||||
431 | fnam = fixup_p ? TAG_MSGSENDID"objc_msgSendId" TAG_FIXUP"_fixup" : TAG_MSGSENDID"objc_msgSendId"; | ||||
432 | umsg_id_fixup_declobjc_v2_global_trees[OCTI_V2_UMSG_ID_FIXUP_DECL] = add_builtin_function (fnam, type, 0, NOT_BUILT_IN, | ||||
433 | NULLnullptr, NULL_TREE(tree) nullptr); | ||||
434 | TREE_NOTHROW (umsg_id_fixup_decl)((objc_v2_global_trees[OCTI_V2_UMSG_ID_FIXUP_DECL])->base. nothrow_flag) = 0; | ||||
435 | |||||
436 | /* id objc_msgSendId_stret_fixup_rtp (id, struct message_ref_t*, ...); */ | ||||
437 | fnam = fixup_p ? TAG_MSGSENDID_STRET"objc_msgSendId_stret" TAG_FIXUP"_fixup" : TAG_MSGSENDID_STRET"objc_msgSendId_stret"; | ||||
438 | umsg_id_stret_fixup_declobjc_v2_global_trees[OCTI_V2_UMSG_ID_STRET_FIXUP_DECL] = add_builtin_function (fnam, type, 0, NOT_BUILT_IN, | ||||
439 | NULLnullptr, NULL_TREE(tree) nullptr); | ||||
440 | TREE_NOTHROW (umsg_id_stret_fixup_decl)((objc_v2_global_trees[OCTI_V2_UMSG_ID_STRET_FIXUP_DECL])-> base.nothrow_flag) = 0; | ||||
441 | |||||
442 | /* id objc_msgSendSuper2_fixup_rtp | ||||
443 | (struct objc_super *, struct message_ref_t*, ...); */ | ||||
444 | type = build_varargs_function_type_list (objc_object_typeobjc_global_trees[OCTI_ID_TYPE], | ||||
445 | objc_super_typeobjc_global_trees[OCTI_SUPER_TYPE], | ||||
446 | objc_v2_super_selector_typeobjc_v2_global_trees[OCTI_V2_SUPER_MESSAGE_SELECTOR_TYPE], | ||||
447 | NULL_TREE(tree) nullptr); | ||||
448 | fnam = fixup_p ? TAG_MSGSENDSUPER"objc_msgSendSuper2" TAG_FIXUP"_fixup" : TAG_MSGSENDSUPER"objc_msgSendSuper2"; | ||||
449 | umsg_id_super2_fixup_declobjc_v2_global_trees[OCTI_V2_UMSG_SUPER2_FIXUP_DECL] = add_builtin_function (fnam, type, 0, NOT_BUILT_IN, | ||||
450 | NULLnullptr, NULL_TREE(tree) nullptr); | ||||
451 | TREE_NOTHROW (umsg_id_super2_fixup_decl)((objc_v2_global_trees[OCTI_V2_UMSG_SUPER2_FIXUP_DECL])->base .nothrow_flag) = 0; | ||||
452 | |||||
453 | /* id objc_msgSendSuper2_stret_fixup_rtp | ||||
454 | (struct objc_super *, struct message_ref_t*, ...); */ | ||||
455 | fnam = fixup_p ? TAG_MSGSENDSUPER_STRET"objc_msgSendSuper2_stret" TAG_FIXUP"_fixup" : TAG_MSGSENDSUPER_STRET"objc_msgSendSuper2_stret"; | ||||
456 | umsg_id_super2_stret_fixup_declobjc_v2_global_trees[OCTI_V2_UMSG_SUPER2_STRET_FIXUP_DECL] = add_builtin_function (fnam, type, 0, | ||||
457 | NOT_BUILT_IN, NULLnullptr, | ||||
458 | NULL_TREE(tree) nullptr); | ||||
459 | TREE_NOTHROW (umsg_id_super2_stret_fixup_decl)((objc_v2_global_trees[OCTI_V2_UMSG_SUPER2_STRET_FIXUP_DECL]) ->base.nothrow_flag) = 0; | ||||
460 | |||||
461 | /* Present in the library, but unused by the FE. */ | ||||
462 | /* Protocol *objc_getProtocol (const char *) | ||||
463 | type = build_function_type_list (objc_protocol_type, | ||||
464 | const_string_type_node, | ||||
465 | NULL_TREE); | ||||
466 | objc_v2_getprotocol_decl = add_builtin_function ("objc_getProtocol", | ||||
467 | type, 0, NOT_BUILT_IN, | ||||
468 | NULL, NULL_TREE); | ||||
469 | TREE_NOTHROW (objc_v2_getprotocol_decl) = 0;*/ | ||||
470 | |||||
471 | UOBJC_V2_CACHE_declobjc_v2_global_trees[OCTI_V2_CACHE_DECL] = create_extern_decl (ptr_type_nodeglobal_trees[TI_PTR_TYPE], | ||||
472 | "_objc_empty_cache"); | ||||
473 | |||||
474 | UOBJC_V2_VTABLE_declobjc_v2_global_trees[OCTI_V2_VTABLE_DECL] = create_extern_decl (objc_v2_imp_typeobjc_v2_global_trees[OCTI_V2_IMP_TYPE], | ||||
475 | "_objc_empty_vtable"); | ||||
476 | |||||
477 | /* id objc_getClass (const char *); */ | ||||
478 | type = build_function_type_list (objc_object_typeobjc_global_trees[OCTI_ID_TYPE], | ||||
479 | const_string_type_nodec_global_trees[CTI_CONST_STRING_TYPE], | ||||
480 | NULL_TREE(tree) nullptr); | ||||
481 | objc_get_class_declobjc_global_trees[OCTI_GET_CLASS_DECL] = add_builtin_function (TAG_GETCLASS"objc_getClass", | ||||
482 | type, 0, NOT_BUILT_IN, | ||||
483 | NULLnullptr, NULL_TREE(tree) nullptr); | ||||
484 | |||||
485 | /* id objc_getMetaClass (const char *); */ | ||||
486 | objc_get_meta_class_declobjc_global_trees[OCTI_GET_MCLASS_DECL] = add_builtin_function (TAG_GETMETACLASS"objc_getMetaClass", | ||||
487 | type, 0, NOT_BUILT_IN, | ||||
488 | NULLnullptr, NULL_TREE(tree) nullptr); | ||||
489 | |||||
490 | /* This is the type of all of the following functions | ||||
491 | objc_copyStruct(). */ | ||||
492 | type = build_function_type_list (void_type_nodeglobal_trees[TI_VOID_TYPE], | ||||
493 | ptr_type_nodeglobal_trees[TI_PTR_TYPE], | ||||
494 | const_ptr_type_nodeglobal_trees[TI_CONST_PTR_TYPE], | ||||
495 | ptrdiff_type_nodeglobal_trees[TI_PTRDIFF_TYPE], | ||||
496 | boolean_type_nodeglobal_trees[TI_BOOLEAN_TYPE], | ||||
497 | boolean_type_nodeglobal_trees[TI_BOOLEAN_TYPE], | ||||
498 | NULL_TREE(tree) nullptr); | ||||
499 | /* Declare the following function: | ||||
500 | void | ||||
501 | objc_copyStruct (void *destination, const void *source, | ||||
502 | ptrdiff_t size, BOOL is_atomic, BOOL has_strong); */ | ||||
503 | objc_copyStruct_declobjc_global_trees[OCTI_COPY_STRUCT_DECL] = add_builtin_function ("objc_copyStruct", | ||||
504 | type, 0, NOT_BUILT_IN, | ||||
505 | NULLnullptr, NULL_TREE(tree) nullptr); | ||||
506 | TREE_NOTHROW (objc_copyStruct_decl)((objc_global_trees[OCTI_COPY_STRUCT_DECL])->base.nothrow_flag ) = 0; | ||||
507 | objc_getPropertyStruct_declobjc_global_trees[OCTI_GET_PROPERTY_STRUCT_DECL] = NULL_TREE(tree) nullptr; | ||||
508 | objc_setPropertyStruct_declobjc_global_trees[OCTI_SET_PROPERTY_STRUCT_DECL] = NULL_TREE(tree) nullptr; | ||||
509 | |||||
510 | gcc_assert (!flag_objc_sjlj_exceptions)((void)(!(!global_options.x_flag_objc_sjlj_exceptions) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 510, __FUNCTION__), 0 : 0)); | ||||
511 | |||||
512 | /* Although we warn that fobjc-exceptions is required for exceptions | ||||
513 | code, we carry on and create it anyway. */ | ||||
514 | |||||
515 | /* This can be required, even when exceptions code is not present, | ||||
516 | when an __attribute__((objc_exception)) is applied to a | ||||
517 | class. */ | ||||
518 | build_v2_ehtype_template (); | ||||
519 | |||||
520 | /* void * objc_begin_catch (void *) */ | ||||
521 | type = build_function_type_list (ptr_type_nodeglobal_trees[TI_PTR_TYPE], | ||||
522 | ptr_type_nodeglobal_trees[TI_PTR_TYPE], NULL_TREE(tree) nullptr); | ||||
523 | |||||
524 | objc2_begin_catch_declobjc_v2_global_trees[OCTI_V2_BEGIN_CATCH_DECL] = add_builtin_function ("objc_begin_catch", | ||||
525 | type, 0, NOT_BUILT_IN, | ||||
526 | NULLnullptr, NULL_TREE(tree) nullptr); | ||||
527 | TREE_NOTHROW (objc2_begin_catch_decl)((objc_v2_global_trees[OCTI_V2_BEGIN_CATCH_DECL])->base.nothrow_flag ) = 0; | ||||
528 | |||||
529 | /* void objc_end_catch () */ | ||||
530 | type = build_function_type_list (void_type_nodeglobal_trees[TI_VOID_TYPE], NULL_TREE(tree) nullptr); | ||||
531 | objc2_end_catch_declobjc_v2_global_trees[OCTI_V2_END_CATCH_DECL] = add_builtin_function ("objc_end_catch", | ||||
532 | type, 0, NOT_BUILT_IN, | ||||
533 | NULLnullptr, NULL_TREE(tree) nullptr); | ||||
534 | TREE_NOTHROW (objc2_end_catch_decl)((objc_v2_global_trees[OCTI_V2_END_CATCH_DECL])->base.nothrow_flag ) = 0; | ||||
535 | |||||
536 | /* void objc_exception_rethrow (void) */ | ||||
537 | objc_rethrow_exception_declobjc_v2_global_trees[OCTI_V2_RETHROW_DECL] = | ||||
538 | add_builtin_function ("objc_exception_rethrow", | ||||
539 | type, 0, NOT_BUILT_IN, | ||||
540 | NULLnullptr, NULL_TREE(tree) nullptr); | ||||
541 | TREE_NOTHROW (objc_rethrow_exception_decl)((objc_v2_global_trees[OCTI_V2_RETHROW_DECL])->base.nothrow_flag ) = 0; | ||||
542 | using_eh_for_cleanups (); | ||||
543 | lang_hooks.eh_runtime_type = next_runtime_02_eh_type; | ||||
544 | lang_hooks.eh_personality = objc_eh_personality; | ||||
545 | } | ||||
546 | |||||
547 | /* NOTE --- templates --- */ | ||||
548 | |||||
549 | /* Set 'objc_v2_message_ref_template' to the data type node for | ||||
550 | 'struct _message_ref_t'. This needs to be done just once per | ||||
551 | compilation. Also Set 'objc_v2_super_message_ref_template' to data | ||||
552 | type node for 'struct _super_message_ref_t'. */ | ||||
553 | |||||
554 | /* struct _message_ref_t | ||||
555 | { | ||||
556 | IMP messenger; | ||||
557 | SEL name; | ||||
558 | }; | ||||
559 | where IMP is: id (*) (id, _message_ref_t*, ...) | ||||
560 | */ | ||||
561 | |||||
562 | /* struct _super_message_ref_t | ||||
563 | { | ||||
564 | SUPER_IMP messenger; | ||||
565 | SEL name; | ||||
566 | }; | ||||
567 | where SUPER_IMP is: id (*) ( super_t*, _super_message_ref_t*, ...) | ||||
568 | */ | ||||
569 | |||||
570 | static void | ||||
571 | build_v2_message_ref_templates (void) | ||||
572 | { | ||||
573 | tree ptr_message_ref_t; | ||||
574 | tree decls, *chain = NULLnullptr; | ||||
575 | |||||
576 | /* struct _message_ref_t {...} */ | ||||
577 | objc_v2_message_ref_templateobjc_v2_global_trees[OCTI_V2_MESSAGE_REF_TEMPL] = | ||||
578 | objc_start_struct (get_identifier ("_message_ref_t")(__builtin_constant_p ("_message_ref_t") ? get_identifier_with_length (("_message_ref_t"), strlen ("_message_ref_t")) : get_identifier ("_message_ref_t"))); | ||||
579 | |||||
580 | /* IMP messenger; */ | ||||
581 | ptr_message_ref_t = | ||||
582 | build_pointer_type (xref_tag (RECORD_TYPE, | ||||
583 | get_identifier ("_message_ref_t")(__builtin_constant_p ("_message_ref_t") ? get_identifier_with_length (("_message_ref_t"), strlen ("_message_ref_t")) : get_identifier ("_message_ref_t")))); | ||||
584 | |||||
585 | objc_v2_imp_typeobjc_v2_global_trees[OCTI_V2_IMP_TYPE] = | ||||
586 | build_pointer_type (build_function_type_list | ||||
587 | (objc_object_typeobjc_global_trees[OCTI_ID_TYPE], | ||||
588 | objc_object_typeobjc_global_trees[OCTI_ID_TYPE], | ||||
589 | ptr_message_ref_t, | ||||
590 | NULL_TREE(tree) nullptr)); | ||||
591 | |||||
592 | decls = add_field_decl (objc_v2_imp_typeobjc_v2_global_trees[OCTI_V2_IMP_TYPE], "messenger", &chain); | ||||
593 | |||||
594 | /* SEL name; */ | ||||
595 | add_field_decl (objc_selector_typeobjc_global_trees[OCTI_SEL_TYPE], "name", &chain); | ||||
596 | |||||
597 | objc_finish_struct (objc_v2_message_ref_templateobjc_v2_global_trees[OCTI_V2_MESSAGE_REF_TEMPL], decls); | ||||
598 | |||||
599 | objc_v2_selector_typeobjc_v2_global_trees[OCTI_V2_MESSAGE_SELECTOR_TYPE] = build_pointer_type (objc_v2_message_ref_templateobjc_v2_global_trees[OCTI_V2_MESSAGE_REF_TEMPL]); | ||||
600 | |||||
601 | chain = NULLnullptr; | ||||
602 | /* struct _super_message_ref_t {...} */ | ||||
603 | objc_v2_super_message_ref_templateobjc_v2_global_trees[OCTI_V2_SUPER_MESSAGE_REF_TEMPL] = | ||||
604 | objc_start_struct (get_identifier ("_super_message_ref_t")(__builtin_constant_p ("_super_message_ref_t") ? get_identifier_with_length (("_super_message_ref_t"), strlen ("_super_message_ref_t")) : get_identifier ("_super_message_ref_t"))); | ||||
605 | |||||
606 | /* SUPER_IMP messenger; */ | ||||
607 | ptr_message_ref_t = build_pointer_type | ||||
608 | (xref_tag (RECORD_TYPE, | ||||
609 | get_identifier ("_super_message_ref_t")(__builtin_constant_p ("_super_message_ref_t") ? get_identifier_with_length (("_super_message_ref_t"), strlen ("_super_message_ref_t")) : get_identifier ("_super_message_ref_t")))); | ||||
610 | |||||
611 | objc_v2_super_imp_typeobjc_v2_global_trees[OCTI_V2_SUPER_IMP_TYPE] = | ||||
612 | build_pointer_type (build_function_type_list | ||||
613 | (objc_object_typeobjc_global_trees[OCTI_ID_TYPE], | ||||
614 | objc_super_typeobjc_global_trees[OCTI_SUPER_TYPE], | ||||
615 | ptr_message_ref_t, | ||||
616 | NULL_TREE(tree) nullptr)); | ||||
617 | |||||
618 | add_field_decl (objc_v2_super_imp_typeobjc_v2_global_trees[OCTI_V2_SUPER_IMP_TYPE], "messenger", &chain); | ||||
619 | |||||
620 | /* SEL name; */ | ||||
621 | add_field_decl (objc_selector_typeobjc_global_trees[OCTI_SEL_TYPE], "name", &chain); | ||||
622 | |||||
623 | objc_finish_struct (objc_v2_super_message_ref_templateobjc_v2_global_trees[OCTI_V2_SUPER_MESSAGE_REF_TEMPL], decls); | ||||
624 | objc_v2_super_selector_typeobjc_v2_global_trees[OCTI_V2_SUPER_MESSAGE_SELECTOR_TYPE] = | ||||
625 | build_pointer_type (objc_v2_super_message_ref_templateobjc_v2_global_trees[OCTI_V2_SUPER_MESSAGE_REF_TEMPL]); | ||||
626 | } | ||||
627 | |||||
628 | /* Build following types which represent each class implementation. | ||||
629 | |||||
630 | struct class_ro_t | ||||
631 | { | ||||
632 | uint32_t const flags; | ||||
633 | uint32_t const instanceStart; | ||||
634 | uint32_t const instanceSize; | ||||
635 | #ifdef __LP64__ | ||||
636 | uint32_t const reserved; | ||||
637 | #endif | ||||
638 | const uint8_t * const ivarLayout; | ||||
639 | const char *const name; | ||||
640 | const struct method_list_t * const baseMethods; | ||||
641 | const struct objc_protocol_list *const baseProtocols; | ||||
642 | const struct ivar_list_t *const ivars; | ||||
643 | const uint8_t * const weakIvarLayout; | ||||
644 | const struct _prop_list_t * const properties; | ||||
645 | }; | ||||
646 | |||||
647 | struct class_t | ||||
648 | { | ||||
649 | struct class_t *isa; | ||||
650 | struct class_t *superclass; | ||||
651 | void *cache; | ||||
652 | IMP *vtable; | ||||
653 | |||||
654 | ...When this is active - it will point to a rw version, but | ||||
655 | when we build the meta-data we point it to the ro... | ||||
656 | struct class_ro_t *data; | ||||
657 | }; | ||||
658 | |||||
659 | */ | ||||
660 | |||||
661 | static void | ||||
662 | build_v2_class_templates (void) | ||||
663 | { | ||||
664 | tree cnst_strg_type; | ||||
665 | tree decls, *chain = NULLnullptr; | ||||
666 | |||||
667 | /* struct class_ro_t {...} */ | ||||
668 | objc_v2_class_ro_templateobjc_v2_global_trees[OCTI_V2_CLS_RO_TEMPL] = | ||||
669 | objc_start_struct (get_identifier (UTAG_V2_CLASS_RO)(__builtin_constant_p ("_class_ro_t") ? get_identifier_with_length (("_class_ro_t"), strlen ("_class_ro_t")) : get_identifier ( "_class_ro_t"))); | ||||
670 | |||||
671 | /* uint32_t const flags; */ | ||||
672 | decls = add_field_decl (integer_type_nodeinteger_types[itk_int], "flags", &chain); | ||||
673 | |||||
674 | /* uint32_t const instanceStart; */ | ||||
675 | add_field_decl (integer_type_nodeinteger_types[itk_int], "instanceStart", &chain); | ||||
676 | |||||
677 | /* uint32_t const instanceSize; */ | ||||
678 | add_field_decl (integer_type_nodeinteger_types[itk_int], "instanceSize", &chain); | ||||
679 | |||||
680 | /* This ABI is currently only used on m64 NeXT. We always | ||||
681 | explicitly declare the alignment padding. */ | ||||
682 | /* uint32_t const reserved; */ | ||||
683 | add_field_decl (integer_type_nodeinteger_types[itk_int], "reserved", &chain); | ||||
684 | |||||
685 | /* const uint8_t * const ivarLayout; */ | ||||
686 | cnst_strg_type = build_pointer_type (unsigned_char_type_nodeinteger_types[itk_unsigned_char]); | ||||
687 | add_field_decl (cnst_strg_type, "ivarLayout", &chain); | ||||
688 | |||||
689 | /* const char *const name; */ | ||||
690 | add_field_decl (string_type_nodec_global_trees[CTI_STRING_TYPE], "name", &chain); | ||||
691 | |||||
692 | /* const struct method_list_t * const baseMethods; */ | ||||
693 | add_field_decl (objc_method_list_ptrobjc_global_trees[OCTI_METH_LIST_TEMPL], "baseMethods", &chain); | ||||
694 | |||||
695 | /* const struct objc_protocol_list *const baseProtocols; */ | ||||
696 | add_field_decl (build_pointer_type | ||||
697 | (xref_tag (RECORD_TYPE, | ||||
698 | get_identifier (UTAG_V2_PROTOCOL_LIST)(__builtin_constant_p ("_protocol_list_t") ? get_identifier_with_length (("_protocol_list_t"), strlen ("_protocol_list_t")) : get_identifier ("_protocol_list_t")))), | ||||
699 | "baseProtocols", &chain); | ||||
700 | |||||
701 | /* const struct ivar_list_t *const ivars; */ | ||||
702 | add_field_decl (objc_v2_ivar_list_ptrobjc_v2_global_trees[OCTI_V2_IVAR_LIST_TEMPL], "ivars", &chain); | ||||
703 | |||||
704 | /* const uint8_t * const weakIvarLayout; */ | ||||
705 | add_field_decl (cnst_strg_type, "weakIvarLayout", &chain); | ||||
706 | |||||
707 | /* struct _prop_list_t * baseProperties; */ | ||||
708 | add_field_decl (objc_prop_list_ptrobjc_global_trees[OCTI_V1_PROP_LIST_TEMPL], "baseProperties", &chain); | ||||
709 | |||||
710 | objc_finish_struct (objc_v2_class_ro_templateobjc_v2_global_trees[OCTI_V2_CLS_RO_TEMPL], decls); | ||||
711 | |||||
712 | chain = NULLnullptr; | ||||
713 | /* struct class_t {...} */ | ||||
714 | objc_v2_class_templateobjc_v2_global_trees[OCTI_V2_CLS_TEMPL] = | ||||
715 | objc_start_struct (get_identifier (UTAG_V2_CLASS)(__builtin_constant_p ("_class_t") ? get_identifier_with_length (("_class_t"), strlen ("_class_t")) : get_identifier ("_class_t" ))); | ||||
716 | |||||
717 | /* struct class_t *isa; */ | ||||
718 | decls = add_field_decl (build_pointer_type (objc_v2_class_templateobjc_v2_global_trees[OCTI_V2_CLS_TEMPL]), | ||||
719 | "isa", &chain); | ||||
720 | |||||
721 | /* struct class_t * const superclass; */ | ||||
722 | add_field_decl (build_pointer_type (objc_v2_class_templateobjc_v2_global_trees[OCTI_V2_CLS_TEMPL]), | ||||
723 | "superclass", &chain); | ||||
724 | |||||
725 | /* void *cache; */ | ||||
726 | add_field_decl (build_pointer_type (void_type_nodeglobal_trees[TI_VOID_TYPE]), "cache", &chain); | ||||
727 | |||||
728 | /* IMP *vtable; */ | ||||
729 | add_field_decl (build_pointer_type (objc_v2_imp_typeobjc_v2_global_trees[OCTI_V2_IMP_TYPE]), "vtable", &chain); | ||||
730 | |||||
731 | /* struct class_ro_t *ro; */ | ||||
732 | add_field_decl (build_pointer_type (objc_v2_class_ro_templateobjc_v2_global_trees[OCTI_V2_CLS_RO_TEMPL]), "ro", &chain); | ||||
733 | |||||
734 | objc_finish_struct (objc_v2_class_templateobjc_v2_global_trees[OCTI_V2_CLS_TEMPL], decls); | ||||
735 | } | ||||
736 | |||||
737 | /* struct _objc_super | ||||
738 | { | ||||
739 | struct _objc_object *self; | ||||
740 | Class cls; | ||||
741 | }; */ | ||||
742 | void | ||||
743 | build_v2_super_template (void) | ||||
744 | { | ||||
745 | tree decls, *chain = NULLnullptr; | ||||
746 | |||||
747 | objc_super_templateobjc_global_trees[OCTI_SUPER_TEMPL] = objc_start_struct (get_identifier (UTAG_SUPER)(__builtin_constant_p ("_objc_super") ? get_identifier_with_length (("_objc_super"), strlen ("_objc_super")) : get_identifier ( "_objc_super"))); | ||||
748 | |||||
749 | /* struct _objc_object *self; */ | ||||
750 | decls = add_field_decl (objc_object_typeobjc_global_trees[OCTI_ID_TYPE], "self", &chain); | ||||
751 | |||||
752 | /* Class cls; */ | ||||
753 | add_field_decl (objc_class_typeobjc_global_trees[OCTI_CLS_TYPE], "cls", &chain); | ||||
754 | |||||
755 | objc_finish_struct (objc_super_templateobjc_global_trees[OCTI_SUPER_TEMPL], decls); | ||||
756 | } | ||||
757 | |||||
758 | /* struct protocol_t | ||||
759 | { | ||||
760 | Class isa; | ||||
761 | const char * const protocol_name; | ||||
762 | const struct protocol_list_t * const protocol_list; | ||||
763 | const struct method_list_t * const instance_methods; | ||||
764 | const struct method_list_t * const class_methods; | ||||
765 | const struct method_list_t * optionalInstanceMethods; | ||||
766 | const struct method_list_t * optionalClassMethod | ||||
767 | const struct _prop_list_t * const properties; | ||||
768 | const uint32_t size; | ||||
769 | const uint32_t flags; | ||||
770 | const char ** extended_method_types; | ||||
771 | const char * demangled_name; | ||||
772 | const struct _prop_list_t * class_properties; | ||||
773 | } | ||||
774 | */ | ||||
775 | static void | ||||
776 | build_v2_protocol_template (void) | ||||
777 | { | ||||
778 | tree decls, *chain = NULLnullptr; | ||||
779 | |||||
780 | objc_v2_protocol_templateobjc_v2_global_trees[OCTI_V2_PROTO_TEMPL] = | ||||
781 | objc_start_struct (get_identifier (UTAG_V2_PROTOCOL)(__builtin_constant_p ("_protocol_t") ? get_identifier_with_length (("_protocol_t"), strlen ("_protocol_t")) : get_identifier ( "_protocol_t"))); | ||||
782 | |||||
783 | /* Class isa; */ | ||||
784 | decls = add_field_decl (objc_object_typeobjc_global_trees[OCTI_ID_TYPE], "isa", &chain); | ||||
785 | |||||
786 | /* char *protocol_name; */ | ||||
787 | add_field_decl (string_type_nodec_global_trees[CTI_STRING_TYPE], "protocol_name", &chain); | ||||
788 | |||||
789 | /* const struct protocol_list_t * const protocol_list; */ | ||||
790 | add_field_decl (build_pointer_type (objc_v2_protocol_templateobjc_v2_global_trees[OCTI_V2_PROTO_TEMPL]), | ||||
791 | "protocol_list", &chain); | ||||
792 | |||||
793 | /* const struct method_list_t * const instance_methods; */ | ||||
794 | add_field_decl (objc_method_proto_list_ptrobjc_global_trees[OCTI_METH_PROTO_LIST_TEMPL], "instance_methods", &chain); | ||||
795 | |||||
796 | /* const struct method_list_t * const class_methods; */ | ||||
797 | add_field_decl (objc_method_proto_list_ptrobjc_global_trees[OCTI_METH_PROTO_LIST_TEMPL], "class_methods", &chain); | ||||
798 | |||||
799 | /* const struct method_list_t * optionalInstanceMethods; */ | ||||
800 | add_field_decl (objc_method_proto_list_ptrobjc_global_trees[OCTI_METH_PROTO_LIST_TEMPL], "optionalInstanceMethods", &chain); | ||||
801 | |||||
802 | /* const struct method_list_t * optionalClassMethods; */ | ||||
803 | add_field_decl (objc_method_proto_list_ptrobjc_global_trees[OCTI_METH_PROTO_LIST_TEMPL], "optionalClassMethods", &chain); | ||||
804 | |||||
805 | /* struct _prop_list_t * properties; */ | ||||
806 | add_field_decl (objc_prop_list_ptrobjc_global_trees[OCTI_V1_PROP_LIST_TEMPL], "properties", &chain); | ||||
807 | |||||
808 | /* const uint32_t size; */ | ||||
809 | add_field_decl (integer_type_nodeinteger_types[itk_int], "size", &chain); | ||||
810 | |||||
811 | /* const uint32_t flags; */ | ||||
812 | add_field_decl (integer_type_nodeinteger_types[itk_int], "flags", &chain); | ||||
813 | |||||
814 | /* const char **extendedMethodTypes; */ | ||||
815 | tree ptr_to_ptr_to_char = build_pointer_type (string_type_nodec_global_trees[CTI_STRING_TYPE]); | ||||
816 | add_field_decl (ptr_to_ptr_to_char, "extended_method_types", &chain); | ||||
817 | |||||
818 | /* const char *demangledName; */ | ||||
819 | add_field_decl (string_type_nodec_global_trees[CTI_STRING_TYPE], "demangled_name", &chain); | ||||
820 | |||||
821 | /* const struct _prop_list_t *class_properties; */ | ||||
822 | add_field_decl (objc_prop_list_ptrobjc_global_trees[OCTI_V1_PROP_LIST_TEMPL], "class_properties", &chain); | ||||
823 | |||||
824 | objc_finish_struct (objc_v2_protocol_templateobjc_v2_global_trees[OCTI_V2_PROTO_TEMPL], decls); | ||||
825 | } | ||||
826 | |||||
827 | /* Build type for a category: | ||||
828 | struct category_t | ||||
829 | { | ||||
830 | const char * const name; | ||||
831 | struct class_t *const cls; | ||||
832 | const struct method_list_t * const instance_methods; | ||||
833 | const struct method_list_t * const class_methods; | ||||
834 | const struct protocol_list_t * const protocols; | ||||
835 | const struct _prop_list_t * const properties; | ||||
836 | } | ||||
837 | */ | ||||
838 | |||||
839 | static void | ||||
840 | build_v2_category_template (void) | ||||
841 | { | ||||
842 | tree decls, *chain = NULLnullptr; | ||||
843 | |||||
844 | objc_v2_category_templateobjc_v2_global_trees[OCTI_V2_CAT_TEMPL] = | ||||
845 | objc_start_struct (get_identifier ("_category_t")(__builtin_constant_p ("_category_t") ? get_identifier_with_length (("_category_t"), strlen ("_category_t")) : get_identifier ( "_category_t"))); | ||||
846 | |||||
847 | /* char *name; */ | ||||
848 | decls = add_field_decl (string_type_nodec_global_trees[CTI_STRING_TYPE], "name", &chain); | ||||
849 | |||||
850 | /* struct class_t *const cls; */ | ||||
851 | add_field_decl (build_pointer_type (objc_v2_class_templateobjc_v2_global_trees[OCTI_V2_CLS_TEMPL]), "cls", &chain); | ||||
852 | |||||
853 | /* struct method_list_t *instance_methods; */ | ||||
854 | add_field_decl (objc_method_list_ptrobjc_global_trees[OCTI_METH_LIST_TEMPL], "instance_methods", &chain); | ||||
855 | |||||
856 | /* struct method_list_t *class_methods; */ | ||||
857 | add_field_decl (objc_method_list_ptrobjc_global_trees[OCTI_METH_LIST_TEMPL], "class_methods", &chain); | ||||
858 | |||||
859 | /* struct protocol_list_t *protocol_list; */ | ||||
860 | add_field_decl (build_pointer_type (objc_v2_protocol_templateobjc_v2_global_trees[OCTI_V2_PROTO_TEMPL]), | ||||
861 | "protocol_list", &chain ); | ||||
862 | |||||
863 | /* struct _prop_list_t * properties; */ | ||||
864 | add_field_decl (objc_prop_list_ptrobjc_global_trees[OCTI_V1_PROP_LIST_TEMPL], "properties", &chain); | ||||
865 | |||||
866 | objc_finish_struct (objc_v2_category_templateobjc_v2_global_trees[OCTI_V2_CAT_TEMPL], decls); | ||||
867 | } | ||||
868 | |||||
869 | /* NOTE --- Decls, Identifiers, Names etc. --- */ | ||||
870 | |||||
871 | /* This routine is given a name and returns a matching extern variable | ||||
872 | if one is found. */ | ||||
873 | |||||
874 | static tree | ||||
875 | hash_name_lookup (hash *hashlist, tree name) | ||||
876 | { | ||||
877 | hash target; | ||||
878 | |||||
879 | target = hashlist[IDENTIFIER_HASH_VALUE (name)((tree_check ((name), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 879, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.hash_value ) % SIZEHASHTABLE257]; | ||||
880 | |||||
881 | while (target) | ||||
882 | { | ||||
883 | if (name == DECL_NAME (target->key)((contains_struct_check ((target->key), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 883, __FUNCTION__))->decl_minimal.name)) | ||||
884 | return target->key; | ||||
885 | |||||
886 | target = target->next; | ||||
887 | } | ||||
888 | return 0; | ||||
889 | } | ||||
890 | |||||
891 | /* This routine is given an extern variable and enters it in its hash | ||||
892 | table. Note that hashing is done on its inner IDENTIFIER_NODE | ||||
893 | node. */ | ||||
894 | |||||
895 | static void | ||||
896 | hash_name_enter (hash *hashlist, tree id) | ||||
897 | { | ||||
898 | hash obj; | ||||
899 | int slot = IDENTIFIER_HASH_VALUE (DECL_NAME (id))((tree_check ((((contains_struct_check ((id), (TS_DECL_MINIMAL ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 899, __FUNCTION__))->decl_minimal.name)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 899, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.hash_value ) % SIZEHASHTABLE257; | ||||
900 | |||||
901 | obj = ggc_alloc<hashed_entry> (); | ||||
902 | obj->list = 0; | ||||
903 | obj->next = hashlist[slot]; | ||||
904 | obj->key = id; | ||||
905 | |||||
906 | hashlist[slot] = obj; /* append to front */ | ||||
907 | } | ||||
908 | |||||
909 | /* Create a declaration "extern <type> <name>;" | ||||
910 | The var will need to be finalized (e.g. by calling finish_var_decl()). */ | ||||
911 | |||||
912 | static tree | ||||
913 | create_extern_decl (tree type, const char *name) | ||||
914 | { | ||||
915 | tree id = get_identifier (name)(__builtin_constant_p (name) ? get_identifier_with_length ((name ), strlen (name)) : get_identifier (name)); | ||||
916 | tree var = hash_name_lookup (extern_names, id); | ||||
917 | if (var) | ||||
918 | return var; | ||||
919 | /* New name. */ | ||||
920 | var = start_var_decl (type, name); | ||||
921 | TREE_STATIC (var)((var)->base.static_flag) = 0; | ||||
922 | DECL_EXTERNAL (var)((contains_struct_check ((var), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 922, __FUNCTION__))->decl_common.decl_flag_1) = 1; | ||||
923 | TREE_PUBLIC (var)((var)->base.public_flag) = 1; | ||||
924 | hash_name_enter (extern_names, var); | ||||
925 | return var; | ||||
926 | } | ||||
927 | |||||
928 | /* Create a globally visible definition for variable NAME of a given TYPE. The | ||||
929 | finish_var_decl() routine will need to be called on it afterwards. */ | ||||
930 | static tree | ||||
931 | create_global_decl (tree type, const char *name, bool is_def = false); | ||||
932 | |||||
933 | static tree | ||||
934 | create_global_decl (tree type, const char *name, bool is_def) | ||||
935 | { | ||||
936 | tree id = get_identifier (name)(__builtin_constant_p (name) ? get_identifier_with_length ((name ), strlen (name)) : get_identifier (name)); | ||||
937 | tree var = hash_name_lookup (extern_names, id); | ||||
938 | if (var) | ||||
939 | is_def = true; | ||||
940 | else | ||||
941 | { | ||||
942 | var = start_var_decl (type, name); | ||||
943 | hash_name_enter (extern_names, var); | ||||
944 | } | ||||
945 | if (is_def) | ||||
946 | { | ||||
947 | DECL_EXTERNAL (var)((contains_struct_check ((var), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 947, __FUNCTION__))->decl_common.decl_flag_1) = 0; | ||||
948 | TREE_STATIC (var)((var)->base.static_flag) = 1; | ||||
949 | } | ||||
950 | TREE_PUBLIC (var)((var)->base.public_flag) = 1; | ||||
951 | return var; | ||||
952 | } | ||||
953 | |||||
954 | /* Create a symbol with __attribute__ ((visibility ("hidden"))) | ||||
955 | attribute (private extern). */ | ||||
956 | static tree | ||||
957 | create_hidden_decl (tree type, const char *name, bool is_def = false); | ||||
958 | |||||
959 | static tree | ||||
960 | create_hidden_decl (tree type, const char *name, bool is_def) | ||||
961 | { | ||||
962 | tree decl = create_global_decl (type, name, is_def); | ||||
963 | DECL_VISIBILITY (decl)((contains_struct_check ((decl), (TS_DECL_WITH_VIS), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 963, __FUNCTION__))->decl_with_vis.visibility) = VISIBILITY_HIDDEN; | ||||
964 | DECL_VISIBILITY_SPECIFIED (decl)((contains_struct_check ((decl), (TS_DECL_WITH_VIS), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 964, __FUNCTION__))->decl_with_vis.visibility_specified) = 1; | ||||
965 | return decl; | ||||
966 | } | ||||
967 | |||||
968 | /* Irritatingly, we have a different superclass field name for ABI=2. */ | ||||
969 | /* PS/TODO: The field name does not matter, it is only used internally | ||||
970 | by the compiler. We can rename it to whatever we want. ;-) */ | ||||
971 | |||||
972 | static tree | ||||
973 | next_runtime_abi_02_super_superclassfield_id (void) | ||||
974 | { | ||||
975 | /* TODO: Simplify. Just always return get_identifier ("cls"), or at | ||||
976 | most look it once at startup then always return it. */ | ||||
977 | if (!super_superclassfield_idobjc_global_trees[OCTI_SUPER_SUPERFIELD_ID]) | ||||
978 | super_superclassfield_idobjc_global_trees[OCTI_SUPER_SUPERFIELD_ID] = get_identifier ("cls")(__builtin_constant_p ("cls") ? get_identifier_with_length (( "cls"), strlen ("cls")) : get_identifier ("cls")); | ||||
979 | return super_superclassfield_idobjc_global_trees[OCTI_SUPER_SUPERFIELD_ID]; | ||||
980 | } | ||||
981 | |||||
982 | static tree | ||||
983 | next_runtime_abi_02_class_decl (tree klass) | ||||
984 | { | ||||
985 | tree decl; | ||||
986 | char buf[BUFSIZE1024]; | ||||
987 | snprintf (buf, BUFSIZE1024, "OBJC_CLASS_$_%s", | ||||
988 | IDENTIFIER_POINTER (CLASS_NAME (klass))((const char *) (tree_check (((((tree_class_check ((klass), ( tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 988, __FUNCTION__))->type_common.name))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 988, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
989 | /* ObjC2 classes are extern visible. */ | ||||
990 | decl = create_global_decl (objc_v2_class_templateobjc_v2_global_trees[OCTI_V2_CLS_TEMPL], buf); | ||||
991 | OBJCMETA (decl, objc_meta, meta_class)if (objc_rt_trees[OCTI_RT_OBJC_META]) ((contains_struct_check ((decl), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 991, __FUNCTION__))->decl_common.attributes) = build_tree_list ((objc_rt_trees[OCTI_RT_OBJC_META]), (objc_rt_trees[OCTI_RT_META_CLASS ]));; | ||||
992 | return decl; | ||||
993 | } | ||||
994 | |||||
995 | static tree | ||||
996 | next_runtime_abi_02_metaclass_decl (tree klass) | ||||
997 | { | ||||
998 | tree decl; | ||||
999 | char buf[BUFSIZE1024]; | ||||
1000 | snprintf (buf, BUFSIZE1024, "OBJC_METACLASS_$_%s", | ||||
1001 | IDENTIFIER_POINTER (CLASS_NAME (klass))((const char *) (tree_check (((((tree_class_check ((klass), ( tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1001, __FUNCTION__))->type_common.name))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1001, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
1002 | /* ObjC2 classes are extern visible. */ | ||||
1003 | decl = create_global_decl (objc_v2_class_templateobjc_v2_global_trees[OCTI_V2_CLS_TEMPL], buf); | ||||
1004 | OBJCMETA (decl, objc_meta, meta_metaclass)if (objc_rt_trees[OCTI_RT_OBJC_META]) ((contains_struct_check ((decl), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1004, __FUNCTION__))->decl_common.attributes) = build_tree_list ((objc_rt_trees[OCTI_RT_OBJC_META]), (objc_rt_trees[OCTI_RT_META_METACLASS ]));; | ||||
1005 | return decl; | ||||
1006 | } | ||||
1007 | |||||
1008 | static tree | ||||
1009 | next_runtime_abi_02_category_decl (tree klass) | ||||
1010 | { | ||||
1011 | tree decl; | ||||
1012 | char buf[BUFSIZE1024]; | ||||
1013 | snprintf (buf, BUFSIZE1024, "_OBJC_Category_%s_%s", | ||||
1014 | IDENTIFIER_POINTER (CLASS_NAME (klass))((const char *) (tree_check (((((tree_class_check ((klass), ( tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1014, __FUNCTION__))->type_common.name))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1014, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ), | ||||
1015 | IDENTIFIER_POINTER (CLASS_SUPER_NAME (klass))((const char *) (tree_check (((((tree_class_check ((klass), ( tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1015, __FUNCTION__))->type_common.context))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1015, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
1016 | decl = start_var_decl (objc_v2_category_templateobjc_v2_global_trees[OCTI_V2_CAT_TEMPL], buf); | ||||
1017 | OBJCMETA (decl, objc_meta, meta_category)if (objc_rt_trees[OCTI_RT_OBJC_META]) ((contains_struct_check ((decl), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1017, __FUNCTION__))->decl_common.attributes) = build_tree_list ((objc_rt_trees[OCTI_RT_OBJC_META]), (objc_rt_trees[OCTI_RT_META_CATEGORY ]));; | ||||
1018 | return decl; | ||||
1019 | } | ||||
1020 | |||||
1021 | static tree | ||||
1022 | next_runtime_abi_02_protocol_decl (tree p) | ||||
1023 | { | ||||
1024 | tree decl; | ||||
1025 | char buf[BUFSIZE1024]; | ||||
1026 | |||||
1027 | /* static struct _objc_protocol _OBJC_Protocol_<mumble>; */ | ||||
1028 | snprintf (buf, BUFSIZE1024, "_OBJC_Protocol_%s", | ||||
1029 | IDENTIFIER_POINTER (PROTOCOL_NAME (p))((const char *) (tree_check (((((tree_class_check ((p), (tcc_type ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1029, __FUNCTION__))->type_common.name))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1029, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
1030 | if (flag_next_runtimeglobal_options.x_flag_next_runtime >= USE_FIXUP_BEFORE100600) | ||||
1031 | { | ||||
1032 | decl = create_hidden_decl (objc_v2_protocol_templateobjc_v2_global_trees[OCTI_V2_PROTO_TEMPL], buf); | ||||
1033 | DECL_WEAK (decl)((contains_struct_check ((decl), (TS_DECL_WITH_VIS), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1033, __FUNCTION__))->decl_with_vis.weak_flag) = true; | ||||
1034 | } | ||||
1035 | else | ||||
1036 | decl = start_var_decl (objc_v2_protocol_templateobjc_v2_global_trees[OCTI_V2_PROTO_TEMPL], buf); | ||||
1037 | OBJCMETA (decl, objc_meta, meta_protocol)if (objc_rt_trees[OCTI_RT_OBJC_META]) ((contains_struct_check ((decl), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1037, __FUNCTION__))->decl_common.attributes) = build_tree_list ((objc_rt_trees[OCTI_RT_OBJC_META]), (objc_rt_trees[OCTI_RT_META_PROTOCOL ]));; | ||||
1038 | return decl; | ||||
1039 | } | ||||
1040 | |||||
1041 | static tree | ||||
1042 | next_runtime_abi_02_string_decl (tree type, const char *name, string_section where) | ||||
1043 | { | ||||
1044 | tree var = start_var_decl (type, name); | ||||
1045 | switch (where) | ||||
1046 | { | ||||
1047 | case class_names: | ||||
1048 | OBJCMETA (var, objc_meta, meta_class_name)if (objc_rt_trees[OCTI_RT_OBJC_META]) ((contains_struct_check ((var), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1048, __FUNCTION__))->decl_common.attributes) = build_tree_list ((objc_rt_trees[OCTI_RT_OBJC_META]), (objc_rt_trees[OCTI_RT_META_CLASS_NAME ]));; | ||||
1049 | break; | ||||
1050 | case meth_var_names: | ||||
1051 | OBJCMETA (var, objc_meta, meta_meth_name)if (objc_rt_trees[OCTI_RT_OBJC_META]) ((contains_struct_check ((var), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1051, __FUNCTION__))->decl_common.attributes) = build_tree_list ((objc_rt_trees[OCTI_RT_OBJC_META]), (objc_rt_trees[OCTI_RT_META_METHD_NAME ]));; | ||||
1052 | break; | ||||
1053 | case meth_var_types: | ||||
1054 | OBJCMETA (var, objc_meta, meta_meth_type)if (objc_rt_trees[OCTI_RT_OBJC_META]) ((contains_struct_check ((var), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1054, __FUNCTION__))->decl_common.attributes) = build_tree_list ((objc_rt_trees[OCTI_RT_OBJC_META]), (objc_rt_trees[OCTI_RT_META_METHD_TYPE ]));; | ||||
1055 | break; | ||||
1056 | case prop_names_attr: | ||||
1057 | OBJCMETA (var, objc_meta, meta_prop_name_attr)if (objc_rt_trees[OCTI_RT_OBJC_META]) ((contains_struct_check ((var), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1057, __FUNCTION__))->decl_common.attributes) = build_tree_list ((objc_rt_trees[OCTI_RT_OBJC_META]), (objc_rt_trees[OCTI_RT_META_PROPN_ATTR ]));; | ||||
1058 | break; | ||||
1059 | default: | ||||
1060 | OBJCMETA (var, objc_meta, meta_base)if (objc_rt_trees[OCTI_RT_OBJC_META]) ((contains_struct_check ((var), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1060, __FUNCTION__))->decl_common.attributes) = build_tree_list ((objc_rt_trees[OCTI_RT_OBJC_META]), (objc_rt_trees[OCTI_RT_META_BASE ]));; | ||||
1061 | break; | ||||
1062 | } | ||||
1063 | return var; | ||||
1064 | } | ||||
1065 | |||||
1066 | /* NOTE --- entry --- */ | ||||
1067 | |||||
1068 | struct GTY(()) ident_data_tuple { | ||||
1069 | tree ident; | ||||
1070 | tree data; | ||||
1071 | }; | ||||
1072 | |||||
1073 | /* This routine creates a file scope static variable of type 'Class' | ||||
1074 | to hold the address of a class. */ | ||||
1075 | |||||
1076 | static tree | ||||
1077 | build_v2_class_reference_decl (tree ident) | ||||
1078 | { | ||||
1079 | tree decl; | ||||
1080 | char buf[BUFSIZE1024]; | ||||
1081 | |||||
1082 | snprintf (buf, BUFSIZE1024, "_OBJC_ClassRef_%s", IDENTIFIER_POINTER (ident)((const char *) (tree_check ((ident), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1082, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
1083 | decl = start_var_decl (objc_class_typeobjc_global_trees[OCTI_CLS_TYPE], buf); | ||||
1084 | OBJCMETA (decl, objc_meta, meta_class_ref)if (objc_rt_trees[OCTI_RT_OBJC_META]) ((contains_struct_check ((decl), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1084, __FUNCTION__))->decl_common.attributes) = build_tree_list ((objc_rt_trees[OCTI_RT_OBJC_META]), (objc_rt_trees[OCTI_RT_META_CLSLST_REFS ]));; | ||||
1085 | return decl; | ||||
1086 | } | ||||
1087 | |||||
1088 | /* This routine builds a class refs entry for each class name used. | ||||
1089 | Initially, a (static-ref, IDENT) tuple is added to the list. The | ||||
1090 | ident is replaced with address of the class metadata (of type | ||||
1091 | 'Class') in the output routine. */ | ||||
1092 | |||||
1093 | static GTY (()) vec<ident_data_tuple, va_gc> *classrefs; | ||||
1094 | |||||
1095 | static tree | ||||
1096 | objc_v2_get_class_reference (tree ident) | ||||
1097 | { | ||||
1098 | tree decl; | ||||
1099 | ident_data_tuple e; | ||||
1100 | if (classrefs) | ||||
1101 | { | ||||
1102 | int count; | ||||
1103 | ident_data_tuple *ref; | ||||
1104 | FOR_EACH_VEC_ELT (*classrefs, count, ref)for (count = 0; (*classrefs).iterate ((count), &(ref)); ++ (count)) | ||||
1105 | { | ||||
1106 | if (ref->ident == ident) | ||||
1107 | { | ||||
1108 | if (!ref->data) | ||||
1109 | ref->data = build_v2_class_reference_decl (ident); | ||||
1110 | return ref->data; | ||||
1111 | } | ||||
1112 | } | ||||
1113 | } | ||||
1114 | else | ||||
1115 | /* Somewhat arbitrary initial provision. */ | ||||
1116 | vec_alloc (classrefs, 16); | ||||
1117 | |||||
1118 | /* We come here if we don't find the entry - or if the table was yet | ||||
1119 | to be created. */ | ||||
1120 | decl = build_v2_class_reference_decl (ident); | ||||
1121 | e.ident = ident; | ||||
1122 | e.data = decl; | ||||
1123 | vec_safe_push (classrefs, e); | ||||
1124 | return decl; | ||||
1125 | } | ||||
1126 | |||||
1127 | static tree | ||||
1128 | next_runtime_abi_02_get_class_reference (tree ident) | ||||
1129 | { | ||||
1130 | if (!flag_zero_linkglobal_options.x_flag_zero_link) | ||||
1131 | return objc_v2_get_class_reference (ident); | ||||
1132 | else | ||||
1133 | { | ||||
1134 | /* We fall back to using objc_getClass (). */ | ||||
1135 | vec<tree, va_gc> *v; | ||||
1136 | vec_alloc (v, 1); | ||||
1137 | tree t; | ||||
1138 | /* ??? add_class_reference (ident); - is pointless, since the | ||||
1139 | system lib does not export the equivalent symbols. Maybe we | ||||
1140 | need to build a class ref anyway. */ | ||||
1141 | t = my_build_string_pointer (IDENTIFIER_LENGTH (ident)((tree_check ((ident), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1141, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.len ) + 1, | ||||
1142 | IDENTIFIER_POINTER (ident)((const char *) (tree_check ((ident), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1142, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
1143 | v->quick_push (t); | ||||
1144 | t = build_function_call_vec (input_location, vNULL, objc_get_class_declobjc_global_trees[OCTI_GET_CLASS_DECL], | ||||
1145 | v, 0); | ||||
1146 | vec_free (v); | ||||
1147 | return t; | ||||
1148 | } | ||||
1149 | } | ||||
1150 | |||||
1151 | /* Used by build_function_type_for_method. Append the types for | ||||
1152 | receiver & _cmd at the start of a method argument list to ARGTYPES. | ||||
1153 | CONTEXT is either METHOD_DEF or METHOD_REF, saying whether we are | ||||
1154 | trying to define a method or call one. SUPERFLAG says this is for a | ||||
1155 | send to super. METH may be NULL, in the case that there is no | ||||
1156 | prototype. */ | ||||
1157 | |||||
1158 | static void | ||||
1159 | next_runtime_abi_02_get_arg_type_list_base (vec<tree, va_gc> **argtypes, | ||||
1160 | tree meth, int context, | ||||
1161 | int superflag) | ||||
1162 | { | ||||
1163 | tree receiver_type; | ||||
1164 | |||||
1165 | if (superflag) | ||||
1166 | receiver_type = objc_super_typeobjc_global_trees[OCTI_SUPER_TYPE]; | ||||
1167 | else if (context == METHOD_DEF0 && TREE_CODE (meth)((enum tree_code) (meth)->base.code) == INSTANCE_METHOD_DECL) | ||||
1168 | receiver_type = objc_instance_typeobjc_global_trees[OCTI_NST_TYPE]; | ||||
1169 | else | ||||
1170 | receiver_type = objc_object_typeobjc_global_trees[OCTI_ID_TYPE]; | ||||
1171 | |||||
1172 | vec_safe_push (*argtypes, receiver_type); | ||||
1173 | if (flag_next_runtimeglobal_options.x_flag_next_runtime < USE_FIXUP_BEFORE100600) | ||||
1174 | /* Selector type - will eventually change to `int'. */ | ||||
1175 | vec_safe_push (*argtypes, superflag ? objc_v2_super_selector_typeobjc_v2_global_trees[OCTI_V2_SUPER_MESSAGE_SELECTOR_TYPE] | ||||
1176 | : objc_v2_selector_typeobjc_v2_global_trees[OCTI_V2_MESSAGE_SELECTOR_TYPE]); | ||||
1177 | else | ||||
1178 | vec_safe_push (*argtypes, objc_selector_typeobjc_global_trees[OCTI_SEL_TYPE]); | ||||
1179 | } | ||||
1180 | |||||
1181 | /* TODO: Merge this with the message refs. */ | ||||
1182 | static tree | ||||
1183 | build_selector_reference_decl (tree ident) | ||||
1184 | { | ||||
1185 | tree decl; | ||||
1186 | char *t, buf[BUFSIZE1024]; | ||||
1187 | |||||
1188 | snprintf (buf, BUFSIZE1024, "_OBJC_SelRef_%s", IDENTIFIER_POINTER (ident)((const char *) (tree_check ((ident), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1188, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
1189 | t = buf; | ||||
1190 | while (*t) | ||||
1191 | { | ||||
1192 | if (*t==':') | ||||
1193 | *t = '$'; /* Underscore would clash between foo:bar and foo_bar. */ | ||||
1194 | t++; | ||||
1195 | } | ||||
1196 | decl = start_var_decl (objc_selector_typeobjc_global_trees[OCTI_SEL_TYPE], buf); | ||||
1197 | OBJCMETA (decl, objc_meta, meta_sel_refs)if (objc_rt_trees[OCTI_RT_OBJC_META]) ((contains_struct_check ((decl), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1197, __FUNCTION__))->decl_common.attributes) = build_tree_list ((objc_rt_trees[OCTI_RT_OBJC_META]), (objc_rt_trees[OCTI_RT_META_SEL_REFS ]));; | ||||
1198 | return decl; | ||||
1199 | } | ||||
1200 | |||||
1201 | static tree | ||||
1202 | next_runtime_abi_02_build_selector_reference (location_t loc ATTRIBUTE_UNUSED__attribute__ ((__unused__)), | ||||
1203 | tree ident, | ||||
1204 | tree proto ATTRIBUTE_UNUSED__attribute__ ((__unused__))) | ||||
1205 | { | ||||
1206 | tree *chain = &sel_ref_chainobjc_global_trees[OCTI_SEL_REF_CHAIN]; | ||||
1207 | tree expr; | ||||
1208 | |||||
1209 | while (*chain) | ||||
1210 | { | ||||
1211 | if (TREE_VALUE (*chain)((tree_check ((*chain), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1211, __FUNCTION__, (TREE_LIST)))->list.value) == ident) | ||||
1212 | return TREE_PURPOSE (*chain)((tree_check ((*chain), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1212, __FUNCTION__, (TREE_LIST)))->list.purpose); | ||||
1213 | |||||
1214 | chain = &TREE_CHAIN (*chain)((contains_struct_check ((*chain), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1214, __FUNCTION__))->common.chain); | ||||
1215 | } | ||||
1216 | |||||
1217 | expr = build_selector_reference_decl (ident); | ||||
1218 | *chain = tree_cons (expr, ident, NULL_TREE(tree) nullptr); | ||||
1219 | |||||
1220 | return expr; | ||||
1221 | } | ||||
1222 | |||||
1223 | /* Declare a variable of type 'struct message_ref_t'. */ | ||||
1224 | /* This will be finished in build_v2_message_ref_translation_table (). | ||||
1225 | We take an idea from LLVM in making the names a bit more connected | ||||
1226 | and thus the asm more readable. */ | ||||
1227 | |||||
1228 | static tree | ||||
1229 | build_v2_message_reference_decl (tree sel_name, tree message_func_ident) | ||||
1230 | { | ||||
1231 | tree decl; | ||||
1232 | char buf[BUFSIZE1024], *t; | ||||
1233 | int offset = 12; | ||||
1234 | |||||
1235 | /* Skip past the objc_msgSend it's the same for all... */ | ||||
1236 | if (IDENTIFIER_POINTER (message_func_ident)((const char *) (tree_check ((message_func_ident), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1236, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )[offset] == '_') | ||||
1237 | offset++; | ||||
1238 | |||||
1239 | snprintf (buf, BUFSIZE1024, "_OBJC_MsgRef_%s_%s", | ||||
1240 | &(IDENTIFIER_POINTER (message_func_ident)((const char *) (tree_check ((message_func_ident), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1240, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )[offset]), | ||||
1241 | IDENTIFIER_POINTER (sel_name)((const char *) (tree_check ((sel_name), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1241, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
1242 | t = buf; | ||||
1243 | while (*t) | ||||
1244 | { | ||||
1245 | if (*t==':') | ||||
1246 | *t = '$'; /* Underscore would clash between foo:bar and foo_bar. */ | ||||
1247 | t++; | ||||
1248 | } | ||||
1249 | decl = start_var_decl (objc_v2_message_ref_templateobjc_v2_global_trees[OCTI_V2_MESSAGE_REF_TEMPL], buf); | ||||
1250 | OBJCMETA (decl, objc_meta, meta_mref)if (objc_rt_trees[OCTI_RT_OBJC_META]) ((contains_struct_check ((decl), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1250, __FUNCTION__))->decl_common.attributes) = build_tree_list ((objc_rt_trees[OCTI_RT_OBJC_META]), (objc_rt_trees[OCTI_RT_META_MSG_REFS ]));; | ||||
1251 | return decl; | ||||
1252 | } | ||||
1253 | |||||
1254 | struct GTY(()) msgref_entry { | ||||
1255 | tree func; | ||||
1256 | tree selname; | ||||
1257 | tree refdecl; | ||||
1258 | }; | ||||
1259 | |||||
1260 | static GTY (()) vec<msgref_entry, va_gc> *msgrefs; | ||||
1261 | |||||
1262 | /* Build the list of (objc_msgSend_fixup_xxx, selector name), used | ||||
1263 | later on to initialize the table of 'struct message_ref_t' | ||||
1264 | elements. */ | ||||
1265 | |||||
1266 | static tree | ||||
1267 | build_v2_selector_messenger_reference (tree sel_name, tree message_func_decl) | ||||
1268 | { | ||||
1269 | tree decl; | ||||
1270 | msgref_entry e; | ||||
1271 | if (msgrefs) | ||||
1272 | { | ||||
1273 | int count; | ||||
1274 | msgref_entry *ref; | ||||
1275 | FOR_EACH_VEC_ELT (*msgrefs, count, ref)for (count = 0; (*msgrefs).iterate ((count), &(ref)); ++( count)) | ||||
1276 | if (ref->func == message_func_decl && ref->selname == sel_name) | ||||
1277 | return ref->refdecl; | ||||
1278 | } | ||||
1279 | else | ||||
1280 | /* Somewhat arbitrary initial provision. */ | ||||
1281 | vec_alloc (msgrefs, 32); | ||||
1282 | |||||
1283 | /* We come here if we don't find a match or at the start. */ | ||||
1284 | decl = build_v2_message_reference_decl (sel_name, | ||||
1285 | DECL_NAME (message_func_decl)((contains_struct_check ((message_func_decl), (TS_DECL_MINIMAL ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1285, __FUNCTION__))->decl_minimal.name)); | ||||
1286 | e.func = message_func_decl; | ||||
1287 | e.selname = sel_name; | ||||
1288 | e.refdecl = decl; | ||||
1289 | vec_safe_push (msgrefs, e); | ||||
1290 | return decl; | ||||
1291 | } | ||||
1292 | |||||
1293 | static tree | ||||
1294 | build_v2_protocollist_ref_decl (tree protocol) | ||||
1295 | { | ||||
1296 | tree decl; | ||||
1297 | tree protocol_ident = PROTOCOL_NAME (protocol)(((tree_class_check ((protocol), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1297, __FUNCTION__))->type_common.name)); | ||||
1298 | char buf[BUFSIZE1024]; | ||||
1299 | |||||
1300 | snprintf (buf, BUFSIZE1024, "_OBJC_ProtocolRef_%s", | ||||
1301 | IDENTIFIER_POINTER (protocol_ident)((const char *) (tree_check ((protocol_ident), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1301, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
1302 | /* TODO: other compiler versions make these hidden & weak. */ | ||||
1303 | decl = create_global_decl (objc_protocol_typeobjc_global_trees[OCTI_PROTO_TYPE], buf); | ||||
1304 | /* Let optimizer know that this decl is not removable. */ | ||||
1305 | DECL_PRESERVE_P (decl)(contains_struct_check ((decl), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1305, __FUNCTION__))->decl_common.preserve_flag = 1; | ||||
1306 | OBJCMETA (decl, objc_meta, meta_proto_ref)if (objc_rt_trees[OCTI_RT_OBJC_META]) ((contains_struct_check ((decl), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1306, __FUNCTION__))->decl_common.attributes) = build_tree_list ((objc_rt_trees[OCTI_RT_OBJC_META]), (objc_rt_trees[OCTI_RT_META_PROT_REFS ]));; | ||||
1307 | return decl; | ||||
1308 | } | ||||
1309 | |||||
1310 | struct GTY(()) prot_list_entry { | ||||
1311 | tree id; | ||||
1312 | tree refdecl; | ||||
1313 | }; | ||||
1314 | static GTY (()) vec<prot_list_entry, va_gc> *protrefs; | ||||
1315 | |||||
1316 | static tree | ||||
1317 | objc_v2_get_protocol_reference (tree ident) | ||||
1318 | { | ||||
1319 | tree decl; | ||||
1320 | prot_list_entry e; | ||||
1321 | if (protrefs) | ||||
1322 | { | ||||
1323 | int count; | ||||
1324 | prot_list_entry *ref; | ||||
1325 | FOR_EACH_VEC_ELT (*protrefs, count, ref)for (count = 0; (*protrefs).iterate ((count), &(ref)); ++ (count)) | ||||
1326 | { | ||||
1327 | if (ref->id == ident) | ||||
1328 | { | ||||
1329 | if (!ref->refdecl) | ||||
1330 | ref->refdecl = build_v2_protocollist_ref_decl (ident); | ||||
1331 | return ref->refdecl; | ||||
1332 | } | ||||
1333 | } | ||||
1334 | } | ||||
1335 | else | ||||
1336 | /* Somewhat arbitrary initial provision. */ | ||||
1337 | vec_alloc (protrefs, 32); | ||||
1338 | |||||
1339 | /* We come here if we don't find the entry - or if the table was yet | ||||
1340 | to be created. */ | ||||
1341 | decl = build_v2_protocollist_ref_decl (ident); | ||||
1342 | e.id = ident; | ||||
1343 | e.refdecl = decl; | ||||
1344 | vec_safe_push (protrefs, e); | ||||
1345 | return decl; | ||||
1346 | } | ||||
1347 | |||||
1348 | static tree | ||||
1349 | next_runtime_abi_02_get_protocol_reference (location_t loc ATTRIBUTE_UNUSED__attribute__ ((__unused__)), | ||||
1350 | tree p) | ||||
1351 | { | ||||
1352 | if (!PROTOCOL_FORWARD_DECL (p)(*((const_cast<tree *> (tree_vec_elt_check ((((tree_class_check ((p), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1352, __FUNCTION__))->type_non_common.lang_1)), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1352, __FUNCTION__)))))) | ||||
1353 | PROTOCOL_FORWARD_DECL (p)(*((const_cast<tree *> (tree_vec_elt_check ((((tree_class_check ((p), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1353, __FUNCTION__))->type_non_common.lang_1)), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1353, __FUNCTION__))))) = next_runtime_abi_02_protocol_decl (p); | ||||
1354 | |||||
1355 | return objc_v2_get_protocol_reference (p); | ||||
1356 | } | ||||
1357 | |||||
1358 | /* This routine returns the ivar declaration, if component is a valid | ||||
1359 | ivar field; NULL_TREE otherwise. On finding an ivar, it also | ||||
1360 | returns the class name in CLASS. */ | ||||
1361 | |||||
1362 | static tree | ||||
1363 | objc_is_ivar (tree expr, tree component, tree *klass) | ||||
1364 | { | ||||
1365 | tree field = NULL_TREE(tree) nullptr; | ||||
1366 | tree basetype = TYPE_MAIN_VARIANT (TREE_TYPE (expr))((tree_class_check ((((contains_struct_check ((expr), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1366, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1366, __FUNCTION__))->type_common.main_variant); | ||||
1367 | |||||
1368 | if (TREE_CODE (basetype)((enum tree_code) (basetype)->base.code) == RECORD_TYPE | ||||
1369 | && TYPE_HAS_OBJC_INFO (basetype)(((tree_class_check ((basetype), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1369, __FUNCTION__))->type_with_lang_specific.lang_specific ) && ((tree_class_check ((basetype), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1369, __FUNCTION__))->type_with_lang_specific.lang_specific )->objc_info) && TYPE_OBJC_INTERFACE (basetype)(*((const_cast<tree *> (tree_vec_elt_check ((((tree_class_check ((basetype), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1369, __FUNCTION__))->type_with_lang_specific.lang_specific )->objc_info), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1369, __FUNCTION__)))))) | ||||
1370 | { | ||||
1371 | *klass = lookup_interface (OBJC_TYPE_NAME (basetype)((tree_class_check ((basetype), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1371, __FUNCTION__))->type_common.name)); | ||||
1372 | if (*klass) | ||||
1373 | { | ||||
1374 | do | ||||
1375 | { | ||||
1376 | tree ivar_chain = CLASS_RAW_IVARS (*klass)(*((const_cast<tree *> (tree_vec_elt_check ((((tree_class_check ((*klass), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1376, __FUNCTION__))->type_non_common.lang_1)), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1376, __FUNCTION__))))); | ||||
1377 | if (ivar_chain) | ||||
1378 | { | ||||
1379 | field = is_ivar (ivar_chain, component); | ||||
1380 | if (field != NULL_TREE(tree) nullptr) | ||||
1381 | break; | ||||
1382 | } | ||||
1383 | *klass = lookup_interface (CLASS_SUPER_NAME (*klass)(((tree_class_check ((*klass), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1383, __FUNCTION__))->type_common.context))); | ||||
1384 | } | ||||
1385 | while (*klass); | ||||
1386 | } | ||||
1387 | } | ||||
1388 | return field; | ||||
1389 | } | ||||
1390 | |||||
1391 | static void | ||||
1392 | create_ivar_offset_name (char *buf, tree class_name, tree field_decl) | ||||
1393 | { | ||||
1394 | tree fname = DECL_NAME (field_decl)((contains_struct_check ((field_decl), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1394, __FUNCTION__))->decl_minimal.name); | ||||
1395 | |||||
1396 | sprintf (buf, "OBJC_IVAR_$_%s.%s", IDENTIFIER_POINTER (class_name)((const char *) (tree_check ((class_name), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1396, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ), | ||||
1397 | IDENTIFIER_POINTER (fname)((const char *) (tree_check ((fname), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1397, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
1398 | return; | ||||
1399 | } | ||||
1400 | |||||
1401 | /* This routine generates new abi's ivar reference tree. It amounts | ||||
1402 | to generating *(TYPE*)((char*)pObj + OFFSET_IVAR) when we normally | ||||
1403 | generate pObj->IVAR. OFFSET_IVAR is an 'extern' variable holding | ||||
1404 | the offset for 'IVAR' field. TYPE is type of IVAR field. */ | ||||
1405 | |||||
1406 | static tree | ||||
1407 | objc_v2_build_ivar_ref (tree datum, tree component) | ||||
1408 | { | ||||
1409 | tree field, ref, class_name, offset, ftype, expr; | ||||
1410 | char var_offset_name[512]; | ||||
1411 | |||||
1412 | field = objc_is_ivar (datum, component, &class_name); | ||||
1413 | if (!field) | ||||
1414 | return NULL_TREE(tree) nullptr; | ||||
1415 | |||||
1416 | /* This routine only handles non-bitfield fields */ | ||||
1417 | if (DECL_C_BIT_FIELD (field)(((contains_struct_check (((tree_check ((field), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1417, __FUNCTION__, (FIELD_DECL)))), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1417, __FUNCTION__))->decl_common.lang_flag_4) == 1)) | ||||
1418 | return NULL_TREE(tree) nullptr; | ||||
1419 | |||||
1420 | create_ivar_offset_name (var_offset_name, CLASS_NAME (class_name)(((tree_class_check ((class_name), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1420, __FUNCTION__))->type_common.name)), field); | ||||
1421 | |||||
1422 | offset = create_extern_decl (TREE_TYPE (size_zero_node)((contains_struct_check ((global_trees[TI_SIZE_ZERO]), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1422, __FUNCTION__))->typed.type), var_offset_name); | ||||
1423 | |||||
1424 | ftype = TREE_TYPE (field)((contains_struct_check ((field), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1424, __FUNCTION__))->typed.type); | ||||
1425 | |||||
1426 | /* (char*)datum */ | ||||
1427 | expr = build_c_cast (input_location, | ||||
1428 | string_type_nodec_global_trees[CTI_STRING_TYPE], build_fold_addr_expr (datum)build_fold_addr_expr_loc (((location_t) 0), (datum))); | ||||
1429 | |||||
1430 | /* (char*)datum + offset */ | ||||
1431 | expr = fold_build_pointer_plus_loc (input_location, expr, offset); | ||||
1432 | |||||
1433 | /* (ftype*)((char*)datum + offset) */ | ||||
1434 | expr = build_c_cast (input_location, build_pointer_type (ftype), expr); | ||||
1435 | |||||
1436 | /* Finally: *(ftype*)((char*)datum + offset) */ | ||||
1437 | ref = build_indirect_ref (input_location, expr, RO_UNARY_STAR); | ||||
1438 | |||||
1439 | /* We must set type of the resulting expression to be the same as | ||||
1440 | the field type. This is because, build_indirect_ref (...) | ||||
1441 | rebuilds the type which may result in lost information; as in the | ||||
1442 | case of protocol-qualified types (id <protocol> ). */ | ||||
1443 | TREE_TYPE (ref)((contains_struct_check ((ref), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1443, __FUNCTION__))->typed.type) = ftype; | ||||
1444 | |||||
1445 | if (TREE_READONLY (datum)((non_type_check ((datum), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1445, __FUNCTION__))->base.readonly_flag) || TREE_READONLY (field)((non_type_check ((field), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1445, __FUNCTION__))->base.readonly_flag)) | ||||
1446 | TREE_READONLY (ref)((non_type_check ((ref), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1446, __FUNCTION__))->base.readonly_flag) = 1; | ||||
1447 | |||||
1448 | if (TREE_THIS_VOLATILE (datum)((datum)->base.volatile_flag) || TREE_THIS_VOLATILE (field)((field)->base.volatile_flag)) | ||||
1449 | TREE_THIS_VOLATILE (ref)((ref)->base.volatile_flag) = 1; | ||||
1450 | |||||
1451 | if (TREE_DEPRECATED (field)((field)->base.deprecated_flag)) | ||||
1452 | warn_deprecated_use (field, NULL_TREE(tree) nullptr); | ||||
1453 | |||||
1454 | return ref; | ||||
1455 | } | ||||
1456 | |||||
1457 | /* IVAR refs are made via an externally referenceable offset and built | ||||
1458 | on the fly. That is, unless they refer to (private) fields in the | ||||
1459 | class structure. */ | ||||
1460 | static tree | ||||
1461 | next_runtime_abi_02_build_ivar_ref (location_t loc ATTRIBUTE_UNUSED__attribute__ ((__unused__)), | ||||
1462 | tree base, tree id) | ||||
1463 | { | ||||
1464 | tree ivar; | ||||
1465 | if ((ivar = objc_v2_build_ivar_ref (base, id))) | ||||
1466 | return ivar; | ||||
1467 | return objc_build_component_ref (base, id); | ||||
1468 | } | ||||
1469 | |||||
1470 | /* [super ...] references are listed here (and built into a table at | ||||
1471 | meta -data emit time). */ | ||||
1472 | static tree | ||||
1473 | build_v2_superclass_ref_decl (tree ident, bool inst) | ||||
1474 | { | ||||
1475 | tree decl; | ||||
1476 | char buf[BUFSIZE1024]; | ||||
1477 | |||||
1478 | snprintf (buf, BUFSIZE1024, "_OBJC_%sSuperRef_%s", (inst?"":"Meta"), | ||||
1479 | IDENTIFIER_POINTER (ident)((const char *) (tree_check ((ident), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1479, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
1480 | decl = start_var_decl (objc_class_typeobjc_global_trees[OCTI_CLS_TYPE], buf); | ||||
1481 | OBJCMETA (decl, objc_meta, meta_superclass_ref)if (objc_rt_trees[OCTI_RT_OBJC_META]) ((contains_struct_check ((decl), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1481, __FUNCTION__))->decl_common.attributes) = build_tree_list ((objc_rt_trees[OCTI_RT_OBJC_META]), (objc_rt_trees[OCTI_RT_META_SUPER_REF ]));; | ||||
1482 | return decl; | ||||
1483 | } | ||||
1484 | |||||
1485 | static GTY (()) vec<ident_data_tuple, va_gc> *class_super_refs; | ||||
1486 | static GTY (()) vec<ident_data_tuple, va_gc> *metaclass_super_refs; | ||||
1487 | |||||
1488 | /* Find or build a superclass reference decl for class NAME. */ | ||||
1489 | |||||
1490 | static tree | ||||
1491 | objc_get_superclass_ref_decl (tree name, bool inst_meth) | ||||
1492 | { | ||||
1493 | tree decl; | ||||
1494 | vec<ident_data_tuple, va_gc> *list = inst_meth ? class_super_refs | ||||
1495 | : metaclass_super_refs; | ||||
1496 | |||||
1497 | if (list) | ||||
1498 | { | ||||
1499 | int count; | ||||
1500 | ident_data_tuple *ref; | ||||
1501 | FOR_EACH_VEC_ELT (*list, count, ref)for (count = 0; (*list).iterate ((count), &(ref)); ++(count )) | ||||
1502 | { | ||||
1503 | if (ref->ident == name) | ||||
1504 | { | ||||
1505 | if (!ref->data) | ||||
1506 | ref->data = build_v2_superclass_ref_decl (name, inst_meth); | ||||
1507 | return ref->data; | ||||
1508 | } | ||||
1509 | } | ||||
1510 | } | ||||
1511 | else | ||||
1512 | { | ||||
1513 | /* Somewhat arbitrary initial provision. */ | ||||
1514 | if (inst_meth) | ||||
1515 | { | ||||
1516 | vec_alloc (class_super_refs, 16); | ||||
1517 | list = class_super_refs; | ||||
1518 | } | ||||
1519 | else | ||||
1520 | { | ||||
1521 | vec_alloc (metaclass_super_refs, 16); | ||||
1522 | list = metaclass_super_refs; | ||||
1523 | } | ||||
1524 | } | ||||
1525 | /* We come here if we don't find the entry - or if the table was yet | ||||
1526 | to be created. */ | ||||
1527 | decl = build_v2_superclass_ref_decl (name, inst_meth); | ||||
1528 | ident_data_tuple e; | ||||
1529 | e.ident = name; | ||||
1530 | e.data = decl; | ||||
1531 | vec_safe_push (list, e); | ||||
1532 | return decl; | ||||
1533 | } | ||||
1534 | |||||
1535 | /* Get a reference to the superclass for IMP. */ | ||||
1536 | |||||
1537 | static tree | ||||
1538 | next_runtime_abi_02_get_class_super_ref (location_t loc ATTRIBUTE_UNUSED__attribute__ ((__unused__)), | ||||
1539 | struct imp_entry *imp, bool inst_meth) | ||||
1540 | { | ||||
1541 | tree name = CLASS_NAME (imp->imp_context)(((tree_class_check ((imp->imp_context), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1541, __FUNCTION__))->type_common.name)); | ||||
1542 | return objc_get_superclass_ref_decl (name, inst_meth); | ||||
1543 | } | ||||
1544 | |||||
1545 | /* Get a reference to the superclass for category IMP. */ | ||||
1546 | |||||
1547 | static tree | ||||
1548 | next_runtime_abi_02_get_category_super_ref (location_t loc ATTRIBUTE_UNUSED__attribute__ ((__unused__)), | ||||
1549 | struct imp_entry *imp, | ||||
1550 | bool inst_meth) | ||||
1551 | { | ||||
1552 | if (flag_zero_linkglobal_options.x_flag_zero_link) | ||||
1553 | { | ||||
1554 | /* Do it the slow way. */ | ||||
1555 | tree get_cl_fn = inst_meth ? objc_get_class_declobjc_global_trees[OCTI_GET_CLASS_DECL] | ||||
1556 | : objc_get_meta_class_declobjc_global_trees[OCTI_GET_MCLASS_DECL]; | ||||
1557 | tree super_name = CLASS_SUPER_NAME (imp->imp_template)(((tree_class_check ((imp->imp_template), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1557, __FUNCTION__))->type_common.context)); | ||||
1558 | super_name = my_build_string_pointer (IDENTIFIER_LENGTH (super_name)((tree_check ((super_name), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1558, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.len ) + 1, | ||||
1559 | IDENTIFIER_POINTER (super_name)((const char *) (tree_check ((super_name), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1559, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
1560 | /* super_class = objc_get{Meta}Class("CLASS_SUPER_NAME"); */ | ||||
1561 | return build_function_call (input_location, get_cl_fn, | ||||
1562 | build_tree_list (NULL_TREE(tree) nullptr, super_name)); | ||||
1563 | } | ||||
1564 | |||||
1565 | /* This is the 'usual' path. */ | ||||
1566 | tree cls_name = CLASS_NAME (imp->imp_template)(((tree_class_check ((imp->imp_template), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1566, __FUNCTION__))->type_common.name)); | ||||
1567 | if (!inst_meth) | ||||
1568 | return objc_get_superclass_ref_decl (cls_name, inst_meth); | ||||
1569 | return objc_get_class_reference (cls_name); | ||||
1570 | } | ||||
1571 | |||||
1572 | static tree | ||||
1573 | next_runtime_abi_02_receiver_is_class_object (tree receiver) | ||||
1574 | { | ||||
1575 | if (TREE_CODE (receiver)((enum tree_code) (receiver)->base.code) == VAR_DECL | ||||
1576 | && IS_CLASS (TREE_TYPE (receiver))(((enum tree_code) (((contains_struct_check ((receiver), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1576, __FUNCTION__))->typed.type))->base.code) == POINTER_TYPE && (((tree_class_check ((((contains_struct_check ((( (contains_struct_check ((receiver), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1576, __FUNCTION__))->typed.type)), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1576, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1576, __FUNCTION__))->type_common.main_variant) == ((contains_struct_check ((objc_global_trees[OCTI_CLS_TYPE]), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1576, __FUNCTION__))->typed.type))) | ||||
1577 | && vec_safe_length (classrefs)) | ||||
1578 | { | ||||
1579 | int count; | ||||
1580 | ident_data_tuple *ref; | ||||
1581 | /* The receiver is a variable created by build_class_reference_decl. */ | ||||
1582 | FOR_EACH_VEC_ELT (*classrefs, count, ref)for (count = 0; (*classrefs).iterate ((count), &(ref)); ++ (count)) | ||||
1583 | if (ref->data == receiver) | ||||
1584 | return ref->ident; | ||||
1585 | } | ||||
1586 | return NULL_TREE(tree) nullptr; | ||||
1587 | } | ||||
1588 | |||||
1589 | /* Assign all arguments in VALUES which have side-effect to a temporary | ||||
1590 | and replaced that argument in VALUES list with the temporary. The | ||||
1591 | arguments will be passed to a function with FNTYPE. */ | ||||
1592 | |||||
1593 | static tree | ||||
1594 | objc_copy_to_temp_side_effect_params (tree fntype, tree values) | ||||
1595 | { | ||||
1596 | tree valtail; | ||||
1597 | function_args_iterator iter; | ||||
1598 | |||||
1599 | /* Skip over receiver and the &_msf_ref types. */ | ||||
1600 | function_args_iter_init (&iter, fntype); | ||||
1601 | function_args_iter_next (&iter); | ||||
1602 | function_args_iter_next (&iter); | ||||
1603 | |||||
1604 | for (valtail = values; valtail; | ||||
1605 | valtail = TREE_CHAIN (valtail)((contains_struct_check ((valtail), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1605, __FUNCTION__))->common.chain), function_args_iter_next (&iter)) | ||||
1606 | { | ||||
1607 | tree value = TREE_VALUE (valtail)((tree_check ((valtail), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1607, __FUNCTION__, (TREE_LIST)))->list.value); | ||||
1608 | tree type = function_args_iter_cond (&iter); | ||||
1609 | if (type == NULL_TREE(tree) nullptr) | ||||
1610 | break; | ||||
1611 | if (!TREE_SIDE_EFFECTS (value)((non_type_check ((value), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1611, __FUNCTION__))->base.side_effects_flag)) | ||||
1612 | continue; | ||||
1613 | /* To prevent re-evaluation. */ | ||||
1614 | value = save_expr (value); | ||||
1615 | add_stmt (value); | ||||
1616 | TREE_VALUE (valtail)((tree_check ((valtail), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1616, __FUNCTION__, (TREE_LIST)))->list.value) = value; | ||||
1617 | } | ||||
1618 | return values; | ||||
1619 | } | ||||
1620 | |||||
1621 | /* Build the new abi's messaging library call. It looks like: | ||||
1622 | (*_msg.messenger) (receiver, &_msg, ...) */ | ||||
1623 | |||||
1624 | static tree | ||||
1625 | build_v2_objc_method_fixup_call (int super_flag, tree method_prototype, | ||||
1626 | tree lookup_object, tree selector, | ||||
1627 | tree method_params, bool check_for_nil) | ||||
1628 | { | ||||
1629 | tree ret_val; | ||||
1630 | tree sender, rcv_p, t; | ||||
1631 | tree ret_type | ||||
1632 | = (method_prototype | ||||
1633 | ? TREE_VALUE (TREE_TYPE (method_prototype))((tree_check ((((contains_struct_check ((method_prototype), ( TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1633, __FUNCTION__))->typed.type)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1633, __FUNCTION__, (TREE_LIST)))->list.value) | ||||
1634 | : objc_object_typeobjc_global_trees[OCTI_ID_TYPE]); | ||||
1635 | tree ftype = build_function_type_for_method (ret_type, method_prototype, | ||||
1636 | METHOD_REF1, super_flag); | ||||
1637 | tree sender_cast; | ||||
1638 | |||||
1639 | if (method_prototype && METHOD_TYPE_ATTRIBUTES (method_prototype)((tree_check2 ((method_prototype), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1639, __FUNCTION__, (INSTANCE_METHOD_DECL), (CLASS_METHOD_DECL )))->decl_common.abstract_origin)) | ||||
1640 | ftype = build_type_attribute_variant ( | ||||
1641 | ftype, METHOD_TYPE_ATTRIBUTES (method_prototype)((tree_check2 ((method_prototype), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1641, __FUNCTION__, (INSTANCE_METHOD_DECL), (CLASS_METHOD_DECL )))->decl_common.abstract_origin)); | ||||
1642 | |||||
1643 | sender_cast = build_pointer_type (ftype); | ||||
1644 | |||||
1645 | if (check_for_nil) | ||||
1646 | method_params = objc_copy_to_temp_side_effect_params (ftype, | ||||
1647 | method_params); | ||||
1648 | |||||
1649 | /* Get &message_ref_t.messenger. */ | ||||
1650 | sender = build_c_cast (input_location, | ||||
1651 | build_pointer_type (super_flag | ||||
1652 | ? objc_v2_super_imp_typeobjc_v2_global_trees[OCTI_V2_SUPER_IMP_TYPE] | ||||
1653 | : objc_v2_imp_typeobjc_v2_global_trees[OCTI_V2_IMP_TYPE]), | ||||
1654 | selector); | ||||
1655 | |||||
1656 | sender = build_indirect_ref (input_location, sender, RO_UNARY_STAR); | ||||
1657 | |||||
1658 | rcv_p = (super_flag ? objc_super_typeobjc_global_trees[OCTI_SUPER_TYPE] : objc_object_typeobjc_global_trees[OCTI_ID_TYPE]); | ||||
1659 | |||||
1660 | lookup_object = build_c_cast (input_location, rcv_p, lookup_object); | ||||
1661 | |||||
1662 | /* Use SAVE_EXPR to avoid evaluating the receiver twice. */ | ||||
1663 | lookup_object = save_expr (lookup_object); | ||||
1664 | |||||
1665 | method_params = tree_cons (NULL_TREE(tree) nullptr, lookup_object, | ||||
1666 | tree_cons (NULL_TREE(tree) nullptr, selector, | ||||
1667 | method_params)); | ||||
1668 | t = build3 (OBJ_TYPE_REF, sender_cast, sender, lookup_object, size_zero_nodeglobal_trees[TI_SIZE_ZERO]); | ||||
1669 | ret_val = build_function_call (input_location, t, method_params); | ||||
1670 | if (check_for_nil) | ||||
1671 | { | ||||
1672 | /* receiver != nil ? ret_val : 0 */ | ||||
1673 | tree ftree; | ||||
1674 | tree ifexp; | ||||
1675 | |||||
1676 | if (TREE_CODE (ret_type)((enum tree_code) (ret_type)->base.code) == RECORD_TYPE | ||||
1677 | || TREE_CODE (ret_type)((enum tree_code) (ret_type)->base.code) == UNION_TYPE) | ||||
1678 | { | ||||
1679 | vec<constructor_elt, va_gc> *rtt = NULLnullptr; | ||||
1680 | /* ??? CHECKME. hmmm..... think we need something more | ||||
1681 | here. */ | ||||
1682 | CONSTRUCTOR_APPEND_ELT (rtt, NULL_TREE, NULL_TREE)do { constructor_elt _ce___ = {(tree) nullptr, (tree) nullptr }; vec_safe_push ((rtt), _ce___); } while (0); | ||||
1683 | ftree = objc_build_constructor (ret_type, rtt); | ||||
1684 | } | ||||
1685 | else | ||||
1686 | ftree = fold_convert (ret_type, integer_zero_node)fold_convert_loc (((location_t) 0), ret_type, global_trees[TI_INTEGER_ZERO ]); | ||||
1687 | |||||
1688 | ifexp = build_binary_op (input_location, NE_EXPR, | ||||
1689 | lookup_object, | ||||
1690 | fold_convert (rcv_p, integer_zero_node)fold_convert_loc (((location_t) 0), rcv_p, global_trees[TI_INTEGER_ZERO ]), 1); | ||||
1691 | |||||
1692 | #ifdef OBJCPLUS | ||||
1693 | ret_val = build_conditional_expr (input_location, | ||||
1694 | ifexp, ret_val, ftree, | ||||
1695 | tf_warning_or_error); | ||||
1696 | #else | ||||
1697 | /* ??? CHECKME. */ | ||||
1698 | ret_val = build_conditional_expr (input_location, | ||||
1699 | ifexp, 1, | ||||
1700 | ret_val, NULL_TREE(tree) nullptr, input_location, | ||||
1701 | ftree, NULL_TREE(tree) nullptr, input_location); | ||||
1702 | #endif | ||||
1703 | } | ||||
1704 | return ret_val; | ||||
1705 | } | ||||
1706 | |||||
1707 | static tree | ||||
1708 | build_v2_build_objc_method_call (int super, tree method_prototype, | ||||
1709 | tree lookup_object, tree selector, | ||||
1710 | tree method_params, location_t loc, | ||||
1711 | bool check_for_nil, bool rx_is_id) | ||||
1712 | { | ||||
1713 | tree sender, sender_cast, method, t; | ||||
1714 | tree rcv_p = (super
| ||||
1715 | vec<tree, va_gc> *parms; | ||||
1716 | unsigned nparm = (method_params ? list_length (method_params) : 0); | ||||
1717 | |||||
1718 | /* If a prototype for the method to be called exists, then cast | ||||
1719 | the sender's return type and arguments to match that of the method. | ||||
1720 | Otherwise, leave sender as is. */ | ||||
1721 | tree ret_type | ||||
1722 | = (method_prototype | ||||
1723 | ? TREE_VALUE (TREE_TYPE (method_prototype))((tree_check ((((contains_struct_check ((method_prototype), ( TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1723, __FUNCTION__))->typed.type)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1723, __FUNCTION__, (TREE_LIST)))->list.value) | ||||
1724 | : objc_object_typeobjc_global_trees[OCTI_ID_TYPE]); | ||||
1725 | tree ftype = build_function_type_for_method (ret_type, method_prototype, | ||||
1726 | METHOD_REF1, super); | ||||
1727 | |||||
1728 | if (method_prototype
, 1728, __FUNCTION__, (INSTANCE_METHOD_DECL), (CLASS_METHOD_DECL )))->decl_common.abstract_origin)) | ||||
1729 | ftype = build_type_attribute_variant (ftype, | ||||
1730 | METHOD_TYPE_ATTRIBUTES((tree_check2 ((method_prototype), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1731, __FUNCTION__, (INSTANCE_METHOD_DECL), (CLASS_METHOD_DECL )))->decl_common.abstract_origin) | ||||
1731 | (method_prototype)((tree_check2 ((method_prototype), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1731, __FUNCTION__, (INSTANCE_METHOD_DECL), (CLASS_METHOD_DECL )))->decl_common.abstract_origin)); | ||||
1732 | |||||
1733 | sender_cast = build_pointer_type (ftype); | ||||
1734 | |||||
1735 | lookup_object = build_c_cast (loc, rcv_p, lookup_object); | ||||
1736 | |||||
1737 | /* Use SAVE_EXPR to avoid evaluating the receiver twice. */ | ||||
1738 | lookup_object = save_expr (lookup_object); | ||||
1739 | |||||
1740 | /* Param list + 2 slots for object and selector. */ | ||||
1741 | vec_alloc (parms, nparm + 2); | ||||
1742 | |||||
1743 | /* If we are returning a struct in memory, and the address | ||||
1744 | of that memory location is passed as a hidden first | ||||
1745 | argument, then change which messenger entry point this | ||||
1746 | expr will call. NB: Note that sender_cast remains | ||||
1747 | unchanged (it already has a struct return type). */ | ||||
1748 | if (!targetm.calls.struct_value_rtx (0, 0) | ||||
1749 | && (TREE_CODE (ret_type)((enum tree_code) (ret_type)->base.code) == RECORD_TYPE | ||||
1750 | || TREE_CODE (ret_type)((enum tree_code) (ret_type)->base.code) == UNION_TYPE) | ||||
1751 | && targetm.calls.return_in_memory (ret_type, 0)) | ||||
1752 | { | ||||
1753 | if (super
| ||||
1754 | sender = umsg_id_super2_stret_fixup_declobjc_v2_global_trees[OCTI_V2_UMSG_SUPER2_STRET_FIXUP_DECL]; | ||||
1755 | else | ||||
1756 | sender = rx_is_id ? umsg_id_stret_fixup_declobjc_v2_global_trees[OCTI_V2_UMSG_ID_STRET_FIXUP_DECL] | ||||
1757 | : umsg_stret_fixup_declobjc_v2_global_trees[OCTI_V2_UMSG_STRET_FIXUP_DECL]; | ||||
1758 | } | ||||
1759 | else | ||||
1760 | { | ||||
1761 | if (super) | ||||
1762 | sender = umsg_id_super2_fixup_declobjc_v2_global_trees[OCTI_V2_UMSG_SUPER2_FIXUP_DECL]; | ||||
1763 | else | ||||
1764 | sender = rx_is_id ? umsg_id_fixup_declobjc_v2_global_trees[OCTI_V2_UMSG_ID_FIXUP_DECL] | ||||
1765 | : umsg_fixup_declobjc_v2_global_trees[OCTI_V2_UMSG_FIXUP_DECL]; | ||||
1766 | } | ||||
1767 | |||||
1768 | method = build_fold_addr_expr_loc (loc, sender); | ||||
1769 | |||||
1770 | /* Pass the object to the method. */ | ||||
1771 | parms->quick_push (lookup_object); | ||||
| |||||
1772 | /* Pass the selector to the method. */ | ||||
1773 | parms->quick_push (selector); | ||||
1774 | /* Now append the remainder of the parms. */ | ||||
1775 | if (nparm) | ||||
1776 | for (; method_params; method_params = TREE_CHAIN (method_params)((contains_struct_check ((method_params), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1776, __FUNCTION__))->common.chain)) | ||||
1777 | parms->quick_push (TREE_VALUE (method_params)((tree_check ((method_params), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1777, __FUNCTION__, (TREE_LIST)))->list.value)); | ||||
1778 | |||||
1779 | /* Build an obj_type_ref, with the correct cast for the method call. */ | ||||
1780 | t = build3 (OBJ_TYPE_REF, sender_cast, method, | ||||
1781 | lookup_object, size_zero_nodeglobal_trees[TI_SIZE_ZERO]); | ||||
1782 | tree ret_val = build_function_call_vec (loc, vNULL, t, parms, NULLnullptr); | ||||
1783 | vec_free (parms); | ||||
1784 | if (check_for_nil) | ||||
1785 | { | ||||
1786 | /* receiver != nil ? ret_val : 0 */ | ||||
1787 | tree ftree; | ||||
1788 | tree ifexp; | ||||
1789 | |||||
1790 | if (TREE_CODE (ret_type)((enum tree_code) (ret_type)->base.code) == RECORD_TYPE | ||||
1791 | || TREE_CODE (ret_type)((enum tree_code) (ret_type)->base.code) == UNION_TYPE) | ||||
1792 | { | ||||
1793 | vec<constructor_elt, va_gc> *rtt = NULLnullptr; | ||||
1794 | /* ??? CHECKME. hmmm..... think we need something more | ||||
1795 | here. */ | ||||
1796 | CONSTRUCTOR_APPEND_ELT (rtt, NULL_TREE, NULL_TREE)do { constructor_elt _ce___ = {(tree) nullptr, (tree) nullptr }; vec_safe_push ((rtt), _ce___); } while (0); | ||||
1797 | ftree = objc_build_constructor (ret_type, rtt); | ||||
1798 | } | ||||
1799 | else | ||||
1800 | ftree = fold_convert (ret_type, integer_zero_node)fold_convert_loc (((location_t) 0), ret_type, global_trees[TI_INTEGER_ZERO ]); | ||||
1801 | |||||
1802 | ifexp = build_binary_op (loc, NE_EXPR, | ||||
1803 | lookup_object, | ||||
1804 | fold_convert (rcv_p, integer_zero_node)fold_convert_loc (((location_t) 0), rcv_p, global_trees[TI_INTEGER_ZERO ]), 1); | ||||
1805 | |||||
1806 | #ifdef OBJCPLUS | ||||
1807 | ret_val = build_conditional_expr (loc, ifexp, ret_val, ftree, | ||||
1808 | tf_warning_or_error); | ||||
1809 | #else | ||||
1810 | /* ??? CHECKME. */ | ||||
1811 | ret_val = build_conditional_expr (loc, ifexp, 1, | ||||
1812 | ret_val, NULL_TREE(tree) nullptr, loc, | ||||
1813 | ftree, NULL_TREE(tree) nullptr, loc); | ||||
1814 | #endif | ||||
1815 | } | ||||
1816 | return ret_val; | ||||
1817 | } | ||||
1818 | |||||
1819 | static tree | ||||
1820 | next_runtime_abi_02_build_objc_method_call (location_t loc, | ||||
1821 | tree method_prototype, | ||||
1822 | tree receiver, | ||||
1823 | tree rtype, | ||||
1824 | tree sel_name, | ||||
1825 | tree method_params, | ||||
1826 | int super) | ||||
1827 | { | ||||
1828 | /* Do we need to check for nil receivers ? */ | ||||
1829 | /* For now, message sent to classes need no nil check. In the | ||||
1830 | future, class declaration marked as weak_import must be nil | ||||
1831 | checked. */ | ||||
1832 | bool check_for_nil = flag_objc_nilcheckglobal_options.x_flag_objc_nilcheck; | ||||
1833 | if (super | ||||
| |||||
1834 | || (TREE_CODE (receiver)((enum tree_code) (receiver)->base.code) == VAR_DECL | ||||
1835 | && TREE_TYPE (receiver)((contains_struct_check ((receiver), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1835, __FUNCTION__))->typed.type) == objc_class_typeobjc_global_trees[OCTI_CLS_TYPE])) | ||||
1836 | check_for_nil = false; | ||||
1837 | |||||
1838 | if (flag_next_runtimeglobal_options.x_flag_next_runtime >= USE_FIXUP_BEFORE100600) | ||||
1839 | { | ||||
1840 | tree selector | ||||
1841 | = next_runtime_abi_02_build_selector_reference (loc, sel_name, | ||||
1842 | method_prototype); | ||||
1843 | return build_v2_build_objc_method_call (super, method_prototype, | ||||
1844 | receiver, selector, | ||||
1845 | method_params, loc, | ||||
1846 | check_for_nil, | ||||
1847 | objc_is_id (rtype)); | ||||
1848 | } | ||||
1849 | |||||
1850 | /* else we have to build a pair of the function and selector. */ | ||||
1851 | tree message_func_decl; | ||||
1852 | tree ret_type = method_prototype | ||||
1853 | ? TREE_VALUE (TREE_TYPE (method_prototype))((tree_check ((((contains_struct_check ((method_prototype), ( TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1853, __FUNCTION__))->typed.type)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1853, __FUNCTION__, (TREE_LIST)))->list.value) | ||||
1854 | : objc_object_typeobjc_global_trees[OCTI_ID_TYPE]; | ||||
1855 | |||||
1856 | if (!targetm.calls.struct_value_rtx (0, 0) | ||||
1857 | && (TREE_CODE (ret_type)((enum tree_code) (ret_type)->base.code) == RECORD_TYPE | ||||
1858 | || TREE_CODE (ret_type)((enum tree_code) (ret_type)->base.code) == UNION_TYPE) | ||||
1859 | && targetm.calls.return_in_memory (ret_type, 0)) | ||||
1860 | { | ||||
1861 | if (super) | ||||
1862 | message_func_decl = umsg_id_super2_stret_fixup_declobjc_v2_global_trees[OCTI_V2_UMSG_SUPER2_STRET_FIXUP_DECL]; | ||||
1863 | else | ||||
1864 | message_func_decl = objc_is_id (rtype) | ||||
1865 | ? umsg_id_stret_fixup_declobjc_v2_global_trees[OCTI_V2_UMSG_ID_STRET_FIXUP_DECL] | ||||
1866 | : umsg_stret_fixup_declobjc_v2_global_trees[OCTI_V2_UMSG_STRET_FIXUP_DECL]; | ||||
1867 | } | ||||
1868 | else | ||||
1869 | { | ||||
1870 | if (super) | ||||
1871 | message_func_decl = umsg_id_super2_fixup_declobjc_v2_global_trees[OCTI_V2_UMSG_SUPER2_FIXUP_DECL]; | ||||
1872 | else | ||||
1873 | message_func_decl = objc_is_id (rtype) | ||||
1874 | ? umsg_id_fixup_declobjc_v2_global_trees[OCTI_V2_UMSG_ID_FIXUP_DECL] | ||||
1875 | : umsg_fixup_declobjc_v2_global_trees[OCTI_V2_UMSG_FIXUP_DECL]; | ||||
1876 | } | ||||
1877 | |||||
1878 | tree selector = build_v2_selector_messenger_reference (sel_name, | ||||
1879 | message_func_decl); | ||||
1880 | |||||
1881 | /* selector = &_msg; */ | ||||
1882 | selector = build_unary_op (loc, ADDR_EXPR, selector, 0); | ||||
1883 | |||||
1884 | selector = build_c_cast (loc, (super ? objc_v2_super_selector_typeobjc_v2_global_trees[OCTI_V2_SUPER_MESSAGE_SELECTOR_TYPE] | ||||
1885 | : objc_v2_selector_typeobjc_v2_global_trees[OCTI_V2_MESSAGE_SELECTOR_TYPE]), | ||||
1886 | selector); | ||||
1887 | |||||
1888 | /* (*_msg.messenger) (receiver, &_msg, ...); */ | ||||
1889 | return build_v2_objc_method_fixup_call (super, method_prototype, receiver, | ||||
1890 | selector, method_params, | ||||
1891 | check_for_nil); | ||||
1892 | } | ||||
1893 | |||||
1894 | /* NOTE --- Constant String Class Stuff --- */ | ||||
1895 | |||||
1896 | static bool | ||||
1897 | next_runtime_abi_02_setup_const_string_class_decl (void) | ||||
1898 | { | ||||
1899 | if (!constant_string_global_idobjc_global_trees[OCTI_CNST_STR_GLOB_ID]) | ||||
1900 | { | ||||
1901 | /* Hopefully, this should not represent a serious limitation. */ | ||||
1902 | char buf[BUFSIZE1024]; | ||||
1903 | snprintf (buf, BUFSIZE1024, "OBJC_CLASS_$_%s", constant_string_class_name); | ||||
1904 | constant_string_global_idobjc_global_trees[OCTI_CNST_STR_GLOB_ID] = get_identifier (buf)(__builtin_constant_p (buf) ? get_identifier_with_length ((buf ), strlen (buf)) : get_identifier (buf)); | ||||
1905 | } | ||||
1906 | |||||
1907 | string_class_declobjc_global_trees[OCTI_STRING_CLASS_DECL] = lookup_name (constant_string_global_idobjc_global_trees[OCTI_CNST_STR_GLOB_ID]); | ||||
1908 | |||||
1909 | /* In OBJC2 abi, constant string class reference refers to class | ||||
1910 | name for NSConstantString class. This declaration may not be | ||||
1911 | available yet (in fact it is not in most cases). So, declare an | ||||
1912 | extern OBJC_CLASS_$_NSConstantString in its place. */ | ||||
1913 | if (!string_class_declobjc_global_trees[OCTI_STRING_CLASS_DECL]) | ||||
1914 | string_class_declobjc_global_trees[OCTI_STRING_CLASS_DECL] = | ||||
1915 | create_extern_decl (objc_v2_class_templateobjc_v2_global_trees[OCTI_V2_CLS_TEMPL], | ||||
1916 | IDENTIFIER_POINTER (constant_string_global_id)((const char *) (tree_check ((objc_global_trees[OCTI_CNST_STR_GLOB_ID ]), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1916, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
1917 | |||||
1918 | return (string_class_declobjc_global_trees[OCTI_STRING_CLASS_DECL] != NULL_TREE(tree) nullptr); | ||||
1919 | } | ||||
1920 | |||||
1921 | static tree | ||||
1922 | next_runtime_abi_02_build_const_string_constructor (location_t loc, tree string, | ||||
1923 | int length) | ||||
1924 | { | ||||
1925 | tree constructor, fields, var; | ||||
1926 | vec<constructor_elt, va_gc> *v = NULLnullptr; | ||||
1927 | |||||
1928 | /* NeXT: (NSConstantString *) & ((__builtin_ObjCString) { isa, string, length }) */ | ||||
1929 | fields = TYPE_FIELDS (internal_const_str_type)((tree_check3 ((objc_global_trees[OCTI_INTERNAL_CNST_STR_TYPE ]), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1929, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.values); | ||||
1930 | CONSTRUCTOR_APPEND_ELT (v, fields,do { constructor_elt _ce___ = {fields, build_unary_op (loc, ADDR_EXPR , objc_global_trees[OCTI_STRING_CLASS_DECL], 0)}; vec_safe_push ((v), _ce___); } while (0) | ||||
1931 | build_unary_op (loc, ADDR_EXPR, string_class_decl, 0))do { constructor_elt _ce___ = {fields, build_unary_op (loc, ADDR_EXPR , objc_global_trees[OCTI_STRING_CLASS_DECL], 0)}; vec_safe_push ((v), _ce___); } while (0); | ||||
1932 | |||||
1933 | fields = DECL_CHAIN (fields)(((contains_struct_check (((contains_struct_check ((fields), ( TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1933, __FUNCTION__))), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1933, __FUNCTION__))->common.chain)); | ||||
1934 | CONSTRUCTOR_APPEND_ELT (v, fields,do { constructor_elt _ce___ = {fields, build_unary_op (loc, ADDR_EXPR , string, 1)}; vec_safe_push ((v), _ce___); } while (0) | ||||
1935 | build_unary_op (loc, ADDR_EXPR, string, 1))do { constructor_elt _ce___ = {fields, build_unary_op (loc, ADDR_EXPR , string, 1)}; vec_safe_push ((v), _ce___); } while (0); | ||||
1936 | |||||
1937 | /* ??? check if this should be long. */ | ||||
1938 | fields = DECL_CHAIN (fields)(((contains_struct_check (((contains_struct_check ((fields), ( TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1938, __FUNCTION__))), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1938, __FUNCTION__))->common.chain)); | ||||
1939 | CONSTRUCTOR_APPEND_ELT (v, fields, build_int_cst (NULL_TREE, length))do { constructor_elt _ce___ = {fields, build_int_cst ((tree) nullptr , length)}; vec_safe_push ((v), _ce___); } while (0); | ||||
1940 | constructor = objc_build_constructor (internal_const_str_typeobjc_global_trees[OCTI_INTERNAL_CNST_STR_TYPE], v); | ||||
1941 | |||||
1942 | var = build_decl (input_location, CONST_DECL, NULLnullptr, TREE_TYPE (constructor)((contains_struct_check ((constructor), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1942, __FUNCTION__))->typed.type)); | ||||
1943 | DECL_INITIAL (var)((contains_struct_check ((var), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1943, __FUNCTION__))->decl_common.initial) = constructor; | ||||
1944 | TREE_STATIC (var)((var)->base.static_flag) = 1; | ||||
1945 | DECL_CONTEXT (var)((contains_struct_check ((var), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1945, __FUNCTION__))->decl_minimal.context) = NULLnullptr; | ||||
1946 | OBJCMETA (var, objc_meta, meta_const_str)if (objc_rt_trees[OCTI_RT_OBJC_META]) ((contains_struct_check ((var), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1946, __FUNCTION__))->decl_common.attributes) = build_tree_list ((objc_rt_trees[OCTI_RT_OBJC_META]), (objc_rt_trees[OCTI_RT_META_CONST_STR ]));; | ||||
1947 | return var; | ||||
1948 | } | ||||
1949 | |||||
1950 | /* NOTE --- NeXT V2 Metadata templates --- */ | ||||
1951 | |||||
1952 | /* This routine builds the following type: | ||||
1953 | struct _prop_t | ||||
1954 | { | ||||
1955 | const char * const name; // property name | ||||
1956 | const char * const attributes; // comma-delimited, encoded, | ||||
1957 | // property attributes | ||||
1958 | }; | ||||
1959 | */ | ||||
1960 | |||||
1961 | static tree | ||||
1962 | build_v2_property_template (void) | ||||
1963 | { | ||||
1964 | tree prop_record; | ||||
1965 | tree decls, *chain = NULLnullptr; | ||||
1966 | |||||
1967 | prop_record = objc_start_struct (get_identifier ("_prop_t")(__builtin_constant_p ("_prop_t") ? get_identifier_with_length (("_prop_t"), strlen ("_prop_t")) : get_identifier ("_prop_t" ))); | ||||
1968 | /* const char * name */ | ||||
1969 | decls = add_field_decl (string_type_nodec_global_trees[CTI_STRING_TYPE], "name", &chain); | ||||
1970 | |||||
1971 | /* const char * attribute */ | ||||
1972 | add_field_decl (string_type_nodec_global_trees[CTI_STRING_TYPE], "attribute", &chain); | ||||
1973 | |||||
1974 | objc_finish_struct (prop_record, decls); | ||||
1975 | return prop_record; | ||||
1976 | } | ||||
1977 | |||||
1978 | /* struct ivar_t | ||||
1979 | { | ||||
1980 | unsigned long int *offset; | ||||
1981 | char *name; | ||||
1982 | char *type; | ||||
1983 | uint32_t alignment; | ||||
1984 | uint32_t size; | ||||
1985 | }; | ||||
1986 | */ | ||||
1987 | |||||
1988 | static tree | ||||
1989 | build_v2_ivar_t_template (void) | ||||
1990 | { | ||||
1991 | tree objc_ivar_id, objc_ivar_record; | ||||
1992 | tree decls, *chain = NULLnullptr; | ||||
1993 | |||||
1994 | objc_ivar_id = get_identifier ("_ivar_t")(__builtin_constant_p ("_ivar_t") ? get_identifier_with_length (("_ivar_t"), strlen ("_ivar_t")) : get_identifier ("_ivar_t" )); | ||||
1995 | objc_ivar_record = objc_start_struct (objc_ivar_id); | ||||
1996 | |||||
1997 | /* unsigned long int *offset; */ | ||||
1998 | decls = add_field_decl (build_pointer_type | ||||
1999 | (TREE_TYPE (size_zero_node)((contains_struct_check ((global_trees[TI_SIZE_ZERO]), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 1999, __FUNCTION__))->typed.type)), "offset", &chain); | ||||
2000 | |||||
2001 | /* char *name; */ | ||||
2002 | add_field_decl (string_type_nodec_global_trees[CTI_STRING_TYPE], "name", &chain); | ||||
2003 | |||||
2004 | /* char *type; */ | ||||
2005 | add_field_decl (string_type_nodec_global_trees[CTI_STRING_TYPE], "type", &chain); | ||||
2006 | |||||
2007 | /* uint32_t alignment; */ | ||||
2008 | add_field_decl (integer_type_nodeinteger_types[itk_int], "alignment", &chain); | ||||
2009 | |||||
2010 | /* uint32_t size; */ | ||||
2011 | add_field_decl (integer_type_nodeinteger_types[itk_int], "size", &chain); | ||||
2012 | |||||
2013 | objc_finish_struct (objc_ivar_record, decls); | ||||
2014 | return objc_ivar_record; | ||||
2015 | } | ||||
2016 | |||||
2017 | static void | ||||
2018 | build_metadata_templates (void) | ||||
2019 | { | ||||
2020 | |||||
2021 | if (!objc_method_templateobjc_global_trees[OCTI_METH_TEMPL]) | ||||
2022 | objc_method_templateobjc_global_trees[OCTI_METH_TEMPL] = build_method_template (); | ||||
2023 | |||||
2024 | if (!objc_v2_property_templateobjc_v2_global_trees[OCTI_V2_PROPERTY_TEMPL]) | ||||
2025 | objc_v2_property_templateobjc_v2_global_trees[OCTI_V2_PROPERTY_TEMPL] = build_v2_property_template (); | ||||
2026 | |||||
2027 | if (!objc_v2_ivar_templateobjc_v2_global_trees[OCTI_V2_IVAR_TEMPL]) | ||||
2028 | objc_v2_ivar_templateobjc_v2_global_trees[OCTI_V2_IVAR_TEMPL] = build_v2_ivar_t_template (); | ||||
2029 | |||||
2030 | } | ||||
2031 | |||||
2032 | /* NOTE --- Output NeXT V2 Metadata --- */ | ||||
2033 | |||||
2034 | /* Routine builds name of Interface's main meta-data of type class_t. */ | ||||
2035 | |||||
2036 | static char * | ||||
2037 | objc_build_internal_classname (tree ident, bool metaclass) | ||||
2038 | { | ||||
2039 | static char string[512]; | ||||
2040 | snprintf (string, 512, "%s_%s", metaclass ? "OBJC_METACLASS_$" | ||||
2041 | : "OBJC_CLASS_$", | ||||
2042 | IDENTIFIER_POINTER (ident)((const char *) (tree_check ((ident), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2042, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
2043 | return string; | ||||
2044 | } | ||||
2045 | |||||
2046 | /* Build the name for object of type struct class_ro_t */ | ||||
2047 | |||||
2048 | static const char * | ||||
2049 | newabi_append_ro (const char *name) | ||||
2050 | { | ||||
2051 | const char *dollar; | ||||
2052 | char *p; | ||||
2053 | static char string[BUFSIZE1024]; | ||||
2054 | dollar = strchr (name, '$'); | ||||
2055 | gcc_assert (dollar)((void)(!(dollar) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2055, __FUNCTION__), 0 : 0)); | ||||
2056 | p = string; | ||||
2057 | *p = '_'; p++; | ||||
2058 | strncpy (p, name, (int)(dollar - name)); | ||||
2059 | p += (int)(dollar - name); | ||||
2060 | sprintf (p, "RO_%s", dollar); | ||||
2061 | return string; | ||||
2062 | } | ||||
2063 | |||||
2064 | /* Build the struct message_ref_t msg = | ||||
2065 | {objc_msgSend_fixup_xxx, @selector(func)} | ||||
2066 | table. */ | ||||
2067 | |||||
2068 | static | ||||
2069 | void build_v2_message_ref_translation_table (void) | ||||
2070 | { | ||||
2071 | int count; | ||||
2072 | msgref_entry *ref; | ||||
2073 | |||||
2074 | if (!vec_safe_length (msgrefs)) | ||||
2075 | return; | ||||
2076 | |||||
2077 | FOR_EACH_VEC_ELT (*msgrefs, count, ref)for (count = 0; (*msgrefs).iterate ((count), &(ref)); ++( count)) | ||||
2078 | { | ||||
2079 | vec<constructor_elt, va_gc> *initializer; | ||||
2080 | tree expr, constructor; | ||||
2081 | tree struct_type = TREE_TYPE (ref->refdecl)((contains_struct_check ((ref->refdecl), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2081, __FUNCTION__))->typed.type); | ||||
2082 | location_t loc = DECL_SOURCE_LOCATION (ref->refdecl)((contains_struct_check ((ref->refdecl), (TS_DECL_MINIMAL) , "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2082, __FUNCTION__))->decl_minimal.locus); | ||||
2083 | |||||
2084 | initializer = NULLnullptr; | ||||
2085 | /* First 'IMP messenger' field... */ | ||||
2086 | expr = build_unary_op (loc, ADDR_EXPR, ref->func, 0); | ||||
2087 | expr = convert (objc_v2_imp_typeobjc_v2_global_trees[OCTI_V2_IMP_TYPE], expr); | ||||
2088 | CONSTRUCTOR_APPEND_ELT (initializer, NULL_TREE, expr)do { constructor_elt _ce___ = {(tree) nullptr, expr}; vec_safe_push ((initializer), _ce___); } while (0); | ||||
2089 | |||||
2090 | /* ... then 'SEL name' field. */ | ||||
2091 | expr = build_selector (ref->selname); | ||||
2092 | CONSTRUCTOR_APPEND_ELT (initializer, NULL_TREE, expr)do { constructor_elt _ce___ = {(tree) nullptr, expr}; vec_safe_push ((initializer), _ce___); } while (0); | ||||
2093 | constructor = objc_build_constructor (struct_type, initializer); | ||||
2094 | finish_var_decl (ref->refdecl, constructor); | ||||
2095 | } | ||||
2096 | } | ||||
2097 | |||||
2098 | /* Build decl = initializer; for each externally visible class | ||||
2099 | reference. */ | ||||
2100 | |||||
2101 | static void | ||||
2102 | build_v2_classrefs_table (void) | ||||
2103 | { | ||||
2104 | int count; | ||||
2105 | ident_data_tuple *ref; | ||||
2106 | |||||
2107 | if (!vec_safe_length (classrefs)) | ||||
2108 | return; | ||||
2109 | |||||
2110 | FOR_EACH_VEC_ELT (*classrefs, count, ref)for (count = 0; (*classrefs).iterate ((count), &(ref)); ++ (count)) | ||||
2111 | { | ||||
2112 | tree expr = ref->ident; | ||||
2113 | tree decl = ref->data; | ||||
2114 | /* Interface with no implementation and yet one of its messages | ||||
2115 | has been used. Need to generate a full address-of tree for it | ||||
2116 | here. */ | ||||
2117 | if (TREE_CODE (expr)((enum tree_code) (expr)->base.code) == IDENTIFIER_NODE) | ||||
2118 | { | ||||
2119 | const char *name = objc_build_internal_classname (expr, false); | ||||
2120 | expr = create_extern_decl (objc_v2_class_templateobjc_v2_global_trees[OCTI_V2_CLS_TEMPL], name); | ||||
2121 | expr = convert (objc_class_typeobjc_global_trees[OCTI_CLS_TYPE], build_fold_addr_expr (expr)build_fold_addr_expr_loc (((location_t) 0), (expr))); | ||||
2122 | } | ||||
2123 | /* The runtime wants this, even if it appears unused, so we must force the | ||||
2124 | output. | ||||
2125 | DECL_PRESERVE_P (decl) = 1; */ | ||||
2126 | finish_var_decl (decl, expr); | ||||
2127 | } | ||||
2128 | } | ||||
2129 | |||||
2130 | /* Build decl = initializer; for each externally visible super class | ||||
2131 | reference. */ | ||||
2132 | |||||
2133 | static void | ||||
2134 | build_v2_super_classrefs_table (bool metaclass) | ||||
2135 | { | ||||
2136 | int count; | ||||
2137 | ident_data_tuple *ref; | ||||
2138 | vec<ident_data_tuple, va_gc> *list = metaclass ? metaclass_super_refs | ||||
2139 | : class_super_refs; | ||||
2140 | |||||
2141 | if (!vec_safe_length (list)) | ||||
2142 | return; | ||||
2143 | |||||
2144 | FOR_EACH_VEC_ELT (*list, count, ref)for (count = 0; (*list).iterate ((count), &(ref)); ++(count )) | ||||
2145 | { | ||||
2146 | tree expr = ref->ident; | ||||
2147 | tree decl = ref->data; | ||||
2148 | /* Interface with no implementation and yet one of its messages | ||||
2149 | has been used. Need to generate a full address-of tree for it | ||||
2150 | here. */ | ||||
2151 | if (TREE_CODE (expr)((enum tree_code) (expr)->base.code) == IDENTIFIER_NODE) | ||||
2152 | { | ||||
2153 | const char * name = objc_build_internal_classname (expr, metaclass); | ||||
2154 | expr = create_extern_decl (objc_v2_class_templateobjc_v2_global_trees[OCTI_V2_CLS_TEMPL], name); | ||||
2155 | expr = convert (objc_class_typeobjc_global_trees[OCTI_CLS_TYPE], build_fold_addr_expr (expr)build_fold_addr_expr_loc (((location_t) 0), (expr))); | ||||
2156 | } | ||||
2157 | finish_var_decl (decl, expr); | ||||
2158 | } | ||||
2159 | } | ||||
2160 | |||||
2161 | /* Add the global class meta-data declaration to the list which later | ||||
2162 | on ends up in the __class_list section. */ | ||||
2163 | |||||
2164 | static GTY(()) vec<tree, va_gc> *class_list; | ||||
2165 | |||||
2166 | static void | ||||
2167 | objc_v2_add_to_class_list (tree global_class_decl) | ||||
2168 | { | ||||
2169 | vec_safe_push (class_list, global_class_decl); | ||||
2170 | } | ||||
2171 | |||||
2172 | static GTY(()) vec<tree, va_gc> *nonlazy_class_list; | ||||
2173 | |||||
2174 | /* Add the global class meta-data declaration to the list which later | ||||
2175 | on ends up in the __nonlazy_class section. */ | ||||
2176 | |||||
2177 | static void | ||||
2178 | objc_v2_add_to_nonlazy_class_list (tree global_class_decl) | ||||
2179 | { | ||||
2180 | vec_safe_push (nonlazy_class_list, global_class_decl); | ||||
2181 | } | ||||
2182 | |||||
2183 | static GTY(()) vec<tree, va_gc> *category_list; | ||||
2184 | |||||
2185 | /* Add the category meta-data declaration to the list which later on | ||||
2186 | ends up in the __nonlazy_category section. */ | ||||
2187 | |||||
2188 | static void | ||||
2189 | objc_v2_add_to_category_list (tree decl) | ||||
2190 | { | ||||
2191 | vec_safe_push (category_list, decl); | ||||
2192 | } | ||||
2193 | |||||
2194 | static GTY(()) vec<tree, va_gc> *nonlazy_category_list; | ||||
2195 | |||||
2196 | /* Add the category meta-data declaration to the list which later on | ||||
2197 | ends up in the __category_list section. */ | ||||
2198 | |||||
2199 | static void | ||||
2200 | objc_v2_add_to_nonlazy_category_list (tree decl) | ||||
2201 | { | ||||
2202 | vec_safe_push (nonlazy_category_list, decl); | ||||
2203 | } | ||||
2204 | |||||
2205 | static bool | ||||
2206 | has_load_impl (tree clsmeth) | ||||
2207 | { | ||||
2208 | while (clsmeth) | ||||
2209 | { | ||||
2210 | tree id = METHOD_SEL_NAME (clsmeth)((tree_check2 ((clsmeth), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2210, __FUNCTION__, (INSTANCE_METHOD_DECL), (CLASS_METHOD_DECL )))->decl_minimal.name); | ||||
2211 | if (IDENTIFIER_LENGTH (id)((tree_check ((id), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2211, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.len ) == 4 | ||||
2212 | && strncmp (IDENTIFIER_POINTER (id)((const char *) (tree_check ((id), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2212, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ), "load", 4) == 0) | ||||
2213 | return true; | ||||
2214 | clsmeth = DECL_CHAIN (clsmeth)(((contains_struct_check (((contains_struct_check ((clsmeth), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2214, __FUNCTION__))), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2214, __FUNCTION__))->common.chain)); | ||||
2215 | } | ||||
2216 | |||||
2217 | return false; | ||||
2218 | } | ||||
2219 | |||||
2220 | /* Build a __{class,category}_list section table containing address of | ||||
2221 | all @implemented {class,category} meta-data. */ | ||||
2222 | |||||
2223 | static void | ||||
2224 | build_v2_address_table (vec<tree, va_gc> *src, const char *nam, tree attr) | ||||
2225 | { | ||||
2226 | int count=0; | ||||
2227 | tree type, decl, expr; | ||||
2228 | vec<constructor_elt, va_gc> *initlist = NULLnullptr; | ||||
2229 | |||||
2230 | if (!vec_safe_length (src)) | ||||
2231 | return; | ||||
2232 | |||||
2233 | FOR_EACH_VEC_ELT (*src, count, decl)for (count = 0; (*src).iterate ((count), &(decl)); ++(count )) | ||||
2234 | { | ||||
2235 | #ifndef OBJCPLUS | ||||
2236 | tree purpose = build_int_cst (NULL_TREE(tree) nullptr, count); | ||||
2237 | #else | ||||
2238 | tree purpose = NULL_TREE(tree) nullptr; | ||||
2239 | #endif | ||||
2240 | expr = convert (objc_class_typeobjc_global_trees[OCTI_CLS_TYPE], build_fold_addr_expr (decl)build_fold_addr_expr_loc (((location_t) 0), (decl))); | ||||
2241 | CONSTRUCTOR_APPEND_ELT (initlist, purpose, expr)do { constructor_elt _ce___ = {purpose, expr}; vec_safe_push ( (initlist), _ce___); } while (0); | ||||
2242 | } | ||||
2243 | gcc_assert (count > 0)((void)(!(count > 0) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2243, __FUNCTION__), 0 : 0)); | ||||
2244 | type = build_array_type (objc_class_typeobjc_global_trees[OCTI_CLS_TYPE], | ||||
2245 | build_index_type (build_int_cst (NULL_TREE(tree) nullptr, count - 1))); | ||||
2246 | decl = start_var_decl (type, nam); | ||||
2247 | /* The runtime wants this, even if it appears unused, so we must | ||||
2248 | force the output. */ | ||||
2249 | DECL_PRESERVE_P (decl)(contains_struct_check ((decl), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2249, __FUNCTION__))->decl_common.preserve_flag = 1; | ||||
2250 | expr = objc_build_constructor (type, initlist); | ||||
2251 | OBJCMETA (decl, objc_meta, attr)if (objc_rt_trees[OCTI_RT_OBJC_META]) ((contains_struct_check ((decl), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2251, __FUNCTION__))->decl_common.attributes) = build_tree_list ((objc_rt_trees[OCTI_RT_OBJC_META]), (attr));; | ||||
2252 | finish_var_decl (decl, expr); | ||||
2253 | } | ||||
2254 | |||||
2255 | /* Build decl = initializer; for each protocol referenced in | ||||
2256 | @protocol(MyProt) expression. Refs as built in the entry section | ||||
2257 | above. */ | ||||
2258 | |||||
2259 | static void | ||||
2260 | build_v2_protocol_list_translation_table (void) | ||||
2261 | { | ||||
2262 | int count; | ||||
2263 | prot_list_entry *ref; | ||||
2264 | |||||
2265 | if (!protrefs) | ||||
2266 | return; | ||||
2267 | |||||
2268 | FOR_EACH_VEC_ELT (*protrefs, count, ref)for (count = 0; (*protrefs).iterate ((count), &(ref)); ++ (count)) | ||||
2269 | { | ||||
2270 | char buf[BUFSIZE1024]; | ||||
2271 | tree expr; | ||||
2272 | gcc_assert (TREE_CODE (ref->id) == PROTOCOL_INTERFACE_TYPE)((void)(!(((enum tree_code) (ref->id)->base.code) == PROTOCOL_INTERFACE_TYPE ) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2272, __FUNCTION__), 0 : 0)); | ||||
2273 | snprintf (buf, BUFSIZE1024, "_OBJC_Protocol_%s", | ||||
2274 | IDENTIFIER_POINTER (PROTOCOL_NAME (ref->id))((const char *) (tree_check (((((tree_class_check ((ref->id ), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2274, __FUNCTION__))->type_common.name))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2274, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
2275 | expr = start_var_decl (objc_v2_protocol_templateobjc_v2_global_trees[OCTI_V2_PROTO_TEMPL], buf); | ||||
2276 | expr = convert (objc_protocol_typeobjc_global_trees[OCTI_PROTO_TYPE], build_fold_addr_expr (expr)build_fold_addr_expr_loc (((location_t) 0), (expr))); | ||||
2277 | finish_var_decl (ref->refdecl, expr); | ||||
2278 | } | ||||
2279 | /* TODO: Maybe we could explicitly delete the vec. now? */ | ||||
2280 | } | ||||
2281 | |||||
2282 | static GTY (()) vec<prot_list_entry, va_gc> *protlist; | ||||
2283 | |||||
2284 | /* Add the local protocol meta-data declaration to the list which | ||||
2285 | later on ends up in the __protocol_list section. */ | ||||
2286 | |||||
2287 | static void | ||||
2288 | objc_add_to_protocol_list (tree protocol_interface_decl, tree protocol_decl) | ||||
2289 | { | ||||
2290 | prot_list_entry e; | ||||
2291 | if (!protlist) | ||||
2292 | /* Arbitrary init count. */ | ||||
2293 | vec_alloc (protlist, 32); | ||||
2294 | e.id = protocol_interface_decl; | ||||
2295 | e.refdecl = protocol_decl; | ||||
2296 | vec_safe_push (protlist, e); | ||||
2297 | } | ||||
2298 | |||||
2299 | /* Build the __protocol_list section table containing address of all | ||||
2300 | generate protocol_t meta-data. */ | ||||
2301 | |||||
2302 | static void | ||||
2303 | build_v2_protocol_list_address_table (void) | ||||
2304 | { | ||||
2305 | int count; | ||||
2306 | prot_list_entry *ref; | ||||
2307 | if (!vec_safe_length (protlist)) | ||||
2308 | return; | ||||
2309 | |||||
2310 | FOR_EACH_VEC_ELT (*protlist, count, ref)for (count = 0; (*protlist).iterate ((count), &(ref)); ++ (count)) | ||||
2311 | { | ||||
2312 | tree decl, expr; | ||||
2313 | char buf[BUFSIZE1024]; | ||||
2314 | gcc_assert (ref->id && TREE_CODE (ref->id) == PROTOCOL_INTERFACE_TYPE)((void)(!(ref->id && ((enum tree_code) (ref->id )->base.code) == PROTOCOL_INTERFACE_TYPE) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2314, __FUNCTION__), 0 : 0)); | ||||
2315 | snprintf (buf, BUFSIZE1024, "_OBJC_LabelProtocol_%s", | ||||
2316 | IDENTIFIER_POINTER (PROTOCOL_NAME (ref->id))((const char *) (tree_check (((((tree_class_check ((ref->id ), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2316, __FUNCTION__))->type_common.name))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2316, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
2317 | if (flag_next_runtimeglobal_options.x_flag_next_runtime >= USE_FIXUP_BEFORE100600) | ||||
2318 | { | ||||
2319 | decl = create_hidden_decl (objc_protocol_typeobjc_global_trees[OCTI_PROTO_TYPE], buf, /*is def=*/true); | ||||
2320 | DECL_WEAK (decl)((contains_struct_check ((decl), (TS_DECL_WITH_VIS), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2320, __FUNCTION__))->decl_with_vis.weak_flag) = true; | ||||
2321 | } | ||||
2322 | else | ||||
2323 | decl = create_global_decl (objc_protocol_typeobjc_global_trees[OCTI_PROTO_TYPE], buf, /*is def=*/true); | ||||
2324 | expr = convert (objc_protocol_typeobjc_global_trees[OCTI_PROTO_TYPE], build_fold_addr_expr (ref->refdecl)build_fold_addr_expr_loc (((location_t) 0), (ref->refdecl) )); | ||||
2325 | OBJCMETA (decl, objc_meta, meta_label_protocollist)if (objc_rt_trees[OCTI_RT_OBJC_META]) ((contains_struct_check ((decl), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2325, __FUNCTION__))->decl_common.attributes) = build_tree_list ((objc_rt_trees[OCTI_RT_OBJC_META]), (objc_rt_trees[OCTI_RT_META_LAB_PROTOLIST ]));; | ||||
2326 | finish_var_decl (decl, expr); | ||||
2327 | } | ||||
2328 | |||||
2329 | /* TODO: delete the vec. */ | ||||
2330 | /* TODO: upgrade to the clang/llvm hidden version. */ | ||||
2331 | } | ||||
2332 | |||||
2333 | /* This routine declares a variable to hold meta data for 'struct | ||||
2334 | protocol_list_t'. */ | ||||
2335 | |||||
2336 | static tree | ||||
2337 | generate_v2_protocol_list (tree i_or_p, tree klass_ctxt) | ||||
2338 | { | ||||
2339 | tree refs_decl, lproto, e, plist, ptempl_p_t; | ||||
2340 | int size = 0; | ||||
2341 | vec<constructor_elt, va_gc> *initlist = NULLnullptr; | ||||
2342 | char buf[BUFSIZE1024]; | ||||
2343 | |||||
2344 | if (TREE_CODE (i_or_p)((enum tree_code) (i_or_p)->base.code) == CLASS_INTERFACE_TYPE | ||||
2345 | || TREE_CODE (i_or_p)((enum tree_code) (i_or_p)->base.code) == CATEGORY_INTERFACE_TYPE) | ||||
2346 | plist = CLASS_PROTOCOL_LIST (i_or_p)(*((const_cast<tree *> (tree_vec_elt_check ((((tree_class_check ((i_or_p), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2346, __FUNCTION__))->type_non_common.lang_1)), (4), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2346, __FUNCTION__))))); | ||||
2347 | else if (TREE_CODE (i_or_p)((enum tree_code) (i_or_p)->base.code) == PROTOCOL_INTERFACE_TYPE) | ||||
2348 | plist = PROTOCOL_LIST (i_or_p)(*((const_cast<tree *> (tree_vec_elt_check ((((tree_class_check ((i_or_p), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2348, __FUNCTION__))->type_non_common.lang_1)), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2348, __FUNCTION__))))); | ||||
2349 | else | ||||
2350 | gcc_unreachable ()(fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2350, __FUNCTION__)); | ||||
2351 | |||||
2352 | /* Compute size. */ | ||||
2353 | for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto)((contains_struct_check ((lproto), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2353, __FUNCTION__))->common.chain)) | ||||
2354 | if (TREE_CODE (TREE_VALUE (lproto))((enum tree_code) (((tree_check ((lproto), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2354, __FUNCTION__, (TREE_LIST)))->list.value))->base .code) == PROTOCOL_INTERFACE_TYPE | ||||
2355 | && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto))(*((const_cast<tree *> (tree_vec_elt_check ((((tree_class_check ((((tree_check ((lproto), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2355, __FUNCTION__, (TREE_LIST)))->list.value)), (tcc_type ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2355, __FUNCTION__))->type_non_common.lang_1)), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2355, __FUNCTION__)))))) | ||||
2356 | size++; | ||||
2357 | |||||
2358 | /* Build initializer. */ | ||||
2359 | |||||
2360 | ptempl_p_t = build_pointer_type (objc_v2_protocol_templateobjc_v2_global_trees[OCTI_V2_PROTO_TEMPL]); | ||||
2361 | e = build_int_cst (ptempl_p_t, size); | ||||
2362 | CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, e)do { constructor_elt _ce___ = {(tree) nullptr, e}; vec_safe_push ((initlist), _ce___); } while (0); | ||||
2363 | |||||
2364 | for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto)((contains_struct_check ((lproto), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2364, __FUNCTION__))->common.chain)) | ||||
2365 | { | ||||
2366 | tree pval = TREE_VALUE (lproto)((tree_check ((lproto), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2366, __FUNCTION__, (TREE_LIST)))->list.value); | ||||
2367 | |||||
2368 | if (TREE_CODE (pval)((enum tree_code) (pval)->base.code) == PROTOCOL_INTERFACE_TYPE | ||||
2369 | && PROTOCOL_FORWARD_DECL (pval)(*((const_cast<tree *> (tree_vec_elt_check ((((tree_class_check ((pval), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2369, __FUNCTION__))->type_non_common.lang_1)), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2369, __FUNCTION__)))))) | ||||
2370 | { | ||||
2371 | tree fwref = PROTOCOL_FORWARD_DECL (pval)(*((const_cast<tree *> (tree_vec_elt_check ((((tree_class_check ((pval), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2371, __FUNCTION__))->type_non_common.lang_1)), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2371, __FUNCTION__))))); | ||||
2372 | location_t loc = DECL_SOURCE_LOCATION (fwref)((contains_struct_check ((fwref), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2372, __FUNCTION__))->decl_minimal.locus) ; | ||||
2373 | e = build_unary_op (loc, ADDR_EXPR, fwref, 0); | ||||
2374 | CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, e)do { constructor_elt _ce___ = {(tree) nullptr, e}; vec_safe_push ((initlist), _ce___); } while (0); | ||||
2375 | } | ||||
2376 | } | ||||
2377 | |||||
2378 | /* static struct protocol_list_t *list[size]; */ | ||||
2379 | |||||
2380 | switch (TREE_CODE (i_or_p)((enum tree_code) (i_or_p)->base.code)) | ||||
2381 | { | ||||
2382 | case PROTOCOL_INTERFACE_TYPE: | ||||
2383 | snprintf (buf, BUFSIZE1024, "_OBJC_ProtocolRefs_%s", | ||||
2384 | IDENTIFIER_POINTER (PROTOCOL_NAME (i_or_p))((const char *) (tree_check (((((tree_class_check ((i_or_p), ( tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2384, __FUNCTION__))->type_common.name))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2384, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
2385 | break; | ||||
2386 | case CLASS_INTERFACE_TYPE: | ||||
2387 | snprintf (buf, BUFSIZE1024, "_OBJC_ClassProtocols_%s", | ||||
2388 | IDENTIFIER_POINTER (CLASS_NAME (i_or_p))((const char *) (tree_check (((((tree_class_check ((i_or_p), ( tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2388, __FUNCTION__))->type_common.name))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2388, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
2389 | break; | ||||
2390 | case CATEGORY_INTERFACE_TYPE: | ||||
2391 | snprintf (buf, BUFSIZE1024, "_OBJC_CategoryProtocols_%s_%s", | ||||
2392 | IDENTIFIER_POINTER (CLASS_NAME (klass_ctxt))((const char *) (tree_check (((((tree_class_check ((klass_ctxt ), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2392, __FUNCTION__))->type_common.name))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2392, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ), | ||||
2393 | IDENTIFIER_POINTER (CLASS_SUPER_NAME (klass_ctxt))((const char *) (tree_check (((((tree_class_check ((klass_ctxt ), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2393, __FUNCTION__))->type_common.context))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2393, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
2394 | break; | ||||
2395 | default: | ||||
2396 | gcc_unreachable ()(fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2396, __FUNCTION__)); | ||||
2397 | } | ||||
2398 | |||||
2399 | refs_decl = start_var_decl (build_sized_array_type (ptempl_p_t, size+1), | ||||
2400 | buf); | ||||
2401 | /* ObjC2 puts all these in the base section. */ | ||||
2402 | OBJCMETA (refs_decl, objc_meta, meta_base)if (objc_rt_trees[OCTI_RT_OBJC_META]) ((contains_struct_check ((refs_decl), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2402, __FUNCTION__))->decl_common.attributes) = build_tree_list ((objc_rt_trees[OCTI_RT_OBJC_META]), (objc_rt_trees[OCTI_RT_META_BASE ]));; | ||||
2403 | DECL_PRESERVE_P (refs_decl)(contains_struct_check ((refs_decl), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2403, __FUNCTION__))->decl_common.preserve_flag = 1; | ||||
2404 | finish_var_decl (refs_decl, | ||||
2405 | objc_build_constructor (TREE_TYPE (refs_decl)((contains_struct_check ((refs_decl), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2405, __FUNCTION__))->typed.type),initlist)); | ||||
2406 | return refs_decl; | ||||
2407 | } | ||||
2408 | |||||
2409 | /* This routine builds one 'struct method_t' initializer list. Note | ||||
2410 | that the old ABI is supposed to build 'struct objc_method' which | ||||
2411 | has 3 fields, but it does not build the initialization expression | ||||
2412 | for 'method_imp' which for protocols is NULL any way. To be | ||||
2413 | consistent with declaration of 'struct method_t', in the new ABI we | ||||
2414 | set the method_t.imp to NULL. */ | ||||
2415 | |||||
2416 | static tree | ||||
2417 | build_v2_descriptor_table_initializer (tree type, tree entries) | ||||
2418 | { | ||||
2419 | vec<constructor_elt, va_gc> *initlist = NULLnullptr; | ||||
2420 | do | ||||
2421 | { | ||||
2422 | vec<constructor_elt, va_gc> *eltlist = NULLnullptr; | ||||
2423 | CONSTRUCTOR_APPEND_ELT (eltlist, NULL_TREE,do { constructor_elt _ce___ = {(tree) nullptr, build_selector (((tree_check2 ((entries), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2424, __FUNCTION__, (INSTANCE_METHOD_DECL), (CLASS_METHOD_DECL )))->decl_minimal.name))}; vec_safe_push ((eltlist), _ce___ ); } while (0) | ||||
2424 | build_selector (METHOD_SEL_NAME (entries)))do { constructor_elt _ce___ = {(tree) nullptr, build_selector (((tree_check2 ((entries), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2424, __FUNCTION__, (INSTANCE_METHOD_DECL), (CLASS_METHOD_DECL )))->decl_minimal.name))}; vec_safe_push ((eltlist), _ce___ ); } while (0); | ||||
2425 | CONSTRUCTOR_APPEND_ELT (eltlist, NULL_TREE,do { constructor_elt _ce___ = {(tree) nullptr, add_objc_string (((tree_check2 ((entries), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2426, __FUNCTION__, (INSTANCE_METHOD_DECL), (CLASS_METHOD_DECL )))->decl_minimal.context), meth_var_types)}; vec_safe_push ((eltlist), _ce___); } while (0) | ||||
2426 | add_objc_string (METHOD_ENCODING (entries),do { constructor_elt _ce___ = {(tree) nullptr, add_objc_string (((tree_check2 ((entries), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2426, __FUNCTION__, (INSTANCE_METHOD_DECL), (CLASS_METHOD_DECL )))->decl_minimal.context), meth_var_types)}; vec_safe_push ((eltlist), _ce___); } while (0) | ||||
2427 | meth_var_types))do { constructor_elt _ce___ = {(tree) nullptr, add_objc_string (((tree_check2 ((entries), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2426, __FUNCTION__, (INSTANCE_METHOD_DECL), (CLASS_METHOD_DECL )))->decl_minimal.context), meth_var_types)}; vec_safe_push ((eltlist), _ce___); } while (0); | ||||
2428 | CONSTRUCTOR_APPEND_ELT (eltlist, NULL_TREE, null_pointer_node)do { constructor_elt _ce___ = {(tree) nullptr, global_trees[TI_NULL_POINTER ]}; vec_safe_push ((eltlist), _ce___); } while (0); | ||||
2429 | |||||
2430 | CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE,do { constructor_elt _ce___ = {(tree) nullptr, objc_build_constructor (type, eltlist)}; vec_safe_push ((initlist), _ce___); } while (0) | ||||
2431 | objc_build_constructor (type, eltlist))do { constructor_elt _ce___ = {(tree) nullptr, objc_build_constructor (type, eltlist)}; vec_safe_push ((initlist), _ce___); } while (0); | ||||
2432 | entries = TREE_CHAIN (entries)((contains_struct_check ((entries), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2432, __FUNCTION__))->common.chain); | ||||
2433 | } | ||||
2434 | while (entries); | ||||
2435 | |||||
2436 | return objc_build_constructor (build_array_type (type, 0), initlist); | ||||
2437 | } | ||||
2438 | |||||
2439 | /* struct method_list_t | ||||
2440 | { | ||||
2441 | uint32_t entsize; | ||||
2442 | uint32_t method_count; | ||||
2443 | struct objc_method method_list[method_count]; | ||||
2444 | }; */ | ||||
2445 | |||||
2446 | static tree | ||||
2447 | build_v2_method_list_template (tree list_type, int size) | ||||
2448 | { | ||||
2449 | tree method_list_t_record; | ||||
2450 | tree array_type, decls, *chain = NULLnullptr; | ||||
2451 | |||||
2452 | method_list_t_record = objc_start_struct (NULL_TREE(tree) nullptr); | ||||
2453 | |||||
2454 | /* uint32_t const entsize; */ | ||||
2455 | decls = add_field_decl (integer_type_nodeinteger_types[itk_int], "entsize", &chain); | ||||
2456 | |||||
2457 | /* int method_count; */ | ||||
2458 | add_field_decl (integer_type_nodeinteger_types[itk_int], "method_count", &chain); | ||||
2459 | |||||
2460 | /* struct objc_method method_list[]; */ | ||||
2461 | array_type = build_sized_array_type (list_type, size); | ||||
2462 | add_field_decl (array_type, "method_list", &chain); | ||||
2463 | |||||
2464 | objc_finish_struct (method_list_t_record, decls); | ||||
2465 | return method_list_t_record; | ||||
2466 | } | ||||
2467 | |||||
2468 | /* Note, as above that we are building to the objc_method_template | ||||
2469 | which has the *imp field. ABI0/1 build with | ||||
2470 | objc_method_prototype_template which is missing this field. */ | ||||
2471 | static tree | ||||
2472 | generate_v2_meth_descriptor_table (tree chain, tree protocol, | ||||
2473 | const char *prefix, tree attr, | ||||
2474 | vec<tree>& all_meths) | ||||
2475 | { | ||||
2476 | tree method_list_template, initlist, decl; | ||||
2477 | int size, entsize; | ||||
2478 | vec<constructor_elt, va_gc> *v = NULLnullptr; | ||||
2479 | char buf[BUFSIZE1024]; | ||||
2480 | |||||
2481 | if (!chain || !prefix) | ||||
2482 | return NULL_TREE(tree) nullptr; | ||||
2483 | |||||
2484 | tree method = chain; | ||||
2485 | size = 0; | ||||
2486 | while (method) | ||||
2487 | { | ||||
2488 | if (! METHOD_ENCODING (method)((tree_check2 ((method), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2488, __FUNCTION__, (INSTANCE_METHOD_DECL), (CLASS_METHOD_DECL )))->decl_minimal.context)) | ||||
2489 | METHOD_ENCODING (method)((tree_check2 ((method), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2489, __FUNCTION__, (INSTANCE_METHOD_DECL), (CLASS_METHOD_DECL )))->decl_minimal.context) = encode_method_prototype (method); | ||||
2490 | all_meths.safe_push (method); | ||||
2491 | method = TREE_CHAIN (method)((contains_struct_check ((method), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2491, __FUNCTION__))->common.chain); | ||||
2492 | size++; | ||||
2493 | } | ||||
2494 | |||||
2495 | gcc_assert (size)((void)(!(size) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2495, __FUNCTION__), 0 : 0)); | ||||
2496 | method_list_template = build_v2_method_list_template (objc_method_templateobjc_global_trees[OCTI_METH_TEMPL], | ||||
2497 | size); | ||||
2498 | snprintf (buf, BUFSIZE1024, "%s_%s", prefix, | ||||
2499 | IDENTIFIER_POINTER (PROTOCOL_NAME (protocol))((const char *) (tree_check (((((tree_class_check ((protocol) , (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2499, __FUNCTION__))->type_common.name))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2499, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
2500 | |||||
2501 | decl = start_var_decl (method_list_template, buf); | ||||
2502 | |||||
2503 | entsize = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (objc_method_template))((unsigned long) (*tree_int_cst_elt_check ((((tree_class_check ((objc_global_trees[OCTI_METH_TEMPL]), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2503, __FUNCTION__))->type_common.size_unit)), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2503, __FUNCTION__))); | ||||
2504 | CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, entsize))do { constructor_elt _ce___ = {(tree) nullptr, build_int_cst ( (tree) nullptr, entsize)}; vec_safe_push ((v), _ce___); } while (0); | ||||
2505 | CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, size))do { constructor_elt _ce___ = {(tree) nullptr, build_int_cst ( (tree) nullptr, size)}; vec_safe_push ((v), _ce___); } while ( 0); | ||||
2506 | initlist = | ||||
2507 | build_v2_descriptor_table_initializer (objc_method_templateobjc_global_trees[OCTI_METH_TEMPL], | ||||
2508 | chain); | ||||
2509 | CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, initlist)do { constructor_elt _ce___ = {(tree) nullptr, initlist}; vec_safe_push ((v), _ce___); } while (0); | ||||
2510 | /* Get into the right section. */ | ||||
2511 | OBJCMETA (decl, objc_meta, attr)if (objc_rt_trees[OCTI_RT_OBJC_META]) ((contains_struct_check ((decl), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2511, __FUNCTION__))->decl_common.attributes) = build_tree_list ((objc_rt_trees[OCTI_RT_OBJC_META]), (attr));; | ||||
2512 | finish_var_decl (decl, objc_build_constructor (method_list_template, v)); | ||||
2513 | return decl; | ||||
2514 | } | ||||
2515 | |||||
2516 | static tree | ||||
2517 | generate_v2_meth_type_list (vec<tree>& all_meths, tree protocol, | ||||
2518 | const char *prefix) | ||||
2519 | { | ||||
2520 | if (all_meths.is_empty () || !prefix) | ||||
2521 | return NULL_TREE(tree) nullptr; | ||||
2522 | |||||
2523 | unsigned size = all_meths.length (); | ||||
2524 | tree list_type = build_sized_array_type (string_type_nodec_global_trees[CTI_STRING_TYPE], size); | ||||
2525 | char *nam; | ||||
2526 | asprintf (&nam, "%s_%s", prefix, | ||||
2527 | IDENTIFIER_POINTER (PROTOCOL_NAME (protocol))((const char *) (tree_check (((((tree_class_check ((protocol) , (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2527, __FUNCTION__))->type_common.name))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2527, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
2528 | tree decl = start_var_decl (list_type, nam); | ||||
2529 | free (nam); | ||||
2530 | OBJCMETA (decl, objc_meta, meta_base)if (objc_rt_trees[OCTI_RT_OBJC_META]) ((contains_struct_check ((decl), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2530, __FUNCTION__))->decl_common.attributes) = build_tree_list ((objc_rt_trees[OCTI_RT_OBJC_META]), (objc_rt_trees[OCTI_RT_META_BASE ]));; | ||||
2531 | vec<constructor_elt, va_gc> *v = NULLnullptr; | ||||
2532 | |||||
2533 | for (unsigned i = 0; i < size; ++i) | ||||
2534 | CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,do { constructor_elt _ce___ = {(tree) nullptr, add_objc_string (((tree_check2 ((all_meths[i]), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2535, __FUNCTION__, (INSTANCE_METHOD_DECL), (CLASS_METHOD_DECL )))->decl_minimal.context), meth_var_types)}; vec_safe_push ((v), _ce___); } while (0) | ||||
2535 | add_objc_string (METHOD_ENCODING (all_meths[i]),do { constructor_elt _ce___ = {(tree) nullptr, add_objc_string (((tree_check2 ((all_meths[i]), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2535, __FUNCTION__, (INSTANCE_METHOD_DECL), (CLASS_METHOD_DECL )))->decl_minimal.context), meth_var_types)}; vec_safe_push ((v), _ce___); } while (0) | ||||
2536 | meth_var_types))do { constructor_elt _ce___ = {(tree) nullptr, add_objc_string (((tree_check2 ((all_meths[i]), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2535, __FUNCTION__, (INSTANCE_METHOD_DECL), (CLASS_METHOD_DECL )))->decl_minimal.context), meth_var_types)}; vec_safe_push ((v), _ce___); } while (0); | ||||
2537 | finish_var_decl (decl, objc_build_constructor (list_type, v)); | ||||
2538 | return decl; | ||||
2539 | } | ||||
2540 | |||||
2541 | /* This routine builds the initializer list to initialize the 'struct | ||||
2542 | _prop_t prop_list[]' field of 'struct _prop_list_t' meta-data. */ | ||||
2543 | |||||
2544 | static tree | ||||
2545 | build_v2_property_table_initializer (tree type, tree context) | ||||
2546 | { | ||||
2547 | tree x; | ||||
2548 | vec<constructor_elt, va_gc> *inits = NULLnullptr; | ||||
2549 | if (TREE_CODE (context)((enum tree_code) (context)->base.code) == PROTOCOL_INTERFACE_TYPE) | ||||
2550 | x = CLASS_PROPERTY_DECL (context)(*((const_cast<tree *> (tree_vec_elt_check ((((tree_class_check ((context), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2550, __FUNCTION__))->type_non_common.lang_1)), (6), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2550, __FUNCTION__))))); | ||||
2551 | else | ||||
2552 | x = IMPL_PROPERTY_DECL (context)(*((const_cast<tree *> (tree_vec_elt_check ((((tree_class_check ((context), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2552, __FUNCTION__))->type_non_common.lang_1)), (6), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2552, __FUNCTION__))))); | ||||
2553 | |||||
2554 | for (; x; x = TREE_CHAIN (x)((contains_struct_check ((x), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2554, __FUNCTION__))->common.chain)) | ||||
2555 | { | ||||
2556 | vec<constructor_elt, va_gc> *elemlist = NULLnullptr; | ||||
2557 | /* NOTE! sections where property name/attribute go MUST change | ||||
2558 | later. */ | ||||
2559 | tree attribute, name_ident = PROPERTY_NAME (x)((contains_struct_check (((tree_check ((x), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2559, __FUNCTION__, (PROPERTY_DECL)))), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2559, __FUNCTION__))->decl_minimal.name); | ||||
2560 | |||||
2561 | CONSTRUCTOR_APPEND_ELT (elemlist, NULL_TREE,do { constructor_elt _ce___ = {(tree) nullptr, add_objc_string (name_ident, prop_names_attr)}; vec_safe_push ((elemlist), _ce___ ); } while (0) | ||||
2562 | add_objc_string (name_ident, prop_names_attr))do { constructor_elt _ce___ = {(tree) nullptr, add_objc_string (name_ident, prop_names_attr)}; vec_safe_push ((elemlist), _ce___ ); } while (0); | ||||
2563 | |||||
2564 | attribute = objc_v2_encode_prop_attr (x); | ||||
2565 | CONSTRUCTOR_APPEND_ELT (elemlist, NULL_TREE,do { constructor_elt _ce___ = {(tree) nullptr, add_objc_string (attribute, prop_names_attr)}; vec_safe_push ((elemlist), _ce___ ); } while (0) | ||||
2566 | add_objc_string (attribute, prop_names_attr))do { constructor_elt _ce___ = {(tree) nullptr, add_objc_string (attribute, prop_names_attr)}; vec_safe_push ((elemlist), _ce___ ); } while (0); | ||||
2567 | |||||
2568 | CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,do { constructor_elt _ce___ = {(tree) nullptr, objc_build_constructor (type, elemlist)}; vec_safe_push ((inits), _ce___); } while ( 0) | ||||
2569 | objc_build_constructor (type, elemlist))do { constructor_elt _ce___ = {(tree) nullptr, objc_build_constructor (type, elemlist)}; vec_safe_push ((inits), _ce___); } while ( 0); | ||||
2570 | } | ||||
2571 | |||||
2572 | return objc_build_constructor (build_array_type (type, 0),inits); | ||||
2573 | } | ||||
2574 | |||||
2575 | /* This routine builds the following type: | ||||
2576 | struct _prop_list_t | ||||
2577 | { | ||||
2578 | uint32_t entsize; // sizeof (struct _prop_t) | ||||
2579 | uint32_t prop_count; | ||||
2580 | struct _prop_t prop_list [prop_count]; | ||||
2581 | } | ||||
2582 | */ | ||||
2583 | |||||
2584 | static tree | ||||
2585 | build_v2_property_list_template (tree list_type, int size) | ||||
2586 | { | ||||
2587 | tree property_list_t_record; | ||||
2588 | tree array_type, decls, *chain = NULLnullptr; | ||||
2589 | |||||
2590 | /* anonymous. */ | ||||
2591 | property_list_t_record = objc_start_struct (NULL_TREE(tree) nullptr); | ||||
2592 | |||||
2593 | /* uint32_t const entsize; */ | ||||
2594 | decls = add_field_decl (integer_type_nodeinteger_types[itk_int], "entsize", &chain); | ||||
2595 | |||||
2596 | /* int prop_count; */ | ||||
2597 | add_field_decl (integer_type_nodeinteger_types[itk_int], "prop_count", &chain); | ||||
2598 | |||||
2599 | /* struct _prop_t prop_list[]; */ | ||||
2600 | array_type = build_sized_array_type (list_type, size); | ||||
2601 | add_field_decl (array_type, "prop_list", &chain); | ||||
2602 | |||||
2603 | objc_finish_struct (property_list_t_record, decls); | ||||
2604 | return property_list_t_record; | ||||
2605 | } | ||||
2606 | |||||
2607 | /* Top-level routine to generate property tables for each | ||||
2608 | implementation. */ | ||||
2609 | |||||
2610 | static tree | ||||
2611 | generate_v2_property_table (tree context, tree klass_ctxt) | ||||
2612 | { | ||||
2613 | tree x, decl, initlist, property_list_template; | ||||
2614 | bool is_proto = false; | ||||
2615 | vec<constructor_elt, va_gc> *inits = NULLnullptr; | ||||
2616 | int init_val, size = 0; | ||||
2617 | char buf[BUFSIZE1024]; | ||||
2618 | |||||
2619 | if (context) | ||||
2620 | { | ||||
2621 | gcc_assert (TREE_CODE (context) == PROTOCOL_INTERFACE_TYPE)((void)(!(((enum tree_code) (context)->base.code) == PROTOCOL_INTERFACE_TYPE ) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2621, __FUNCTION__), 0 : 0)); | ||||
2622 | x = CLASS_PROPERTY_DECL (context)(*((const_cast<tree *> (tree_vec_elt_check ((((tree_class_check ((context), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2622, __FUNCTION__))->type_non_common.lang_1)), (6), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2622, __FUNCTION__))))); | ||||
2623 | is_proto = true; | ||||
2624 | } | ||||
2625 | else | ||||
2626 | x = IMPL_PROPERTY_DECL (klass_ctxt)(*((const_cast<tree *> (tree_vec_elt_check ((((tree_class_check ((klass_ctxt), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2626, __FUNCTION__))->type_non_common.lang_1)), (6), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2626, __FUNCTION__))))); | ||||
2627 | |||||
2628 | for (; x; x = TREE_CHAIN (x)((contains_struct_check ((x), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2628, __FUNCTION__))->common.chain)) | ||||
2629 | size++; | ||||
2630 | |||||
2631 | if (size == 0) | ||||
2632 | return NULL_TREE(tree) nullptr; | ||||
2633 | |||||
2634 | property_list_template = | ||||
2635 | build_v2_property_list_template (objc_v2_property_templateobjc_v2_global_trees[OCTI_V2_PROPERTY_TEMPL], | ||||
2636 | size); | ||||
2637 | |||||
2638 | initlist = build_v2_property_table_initializer (objc_v2_property_templateobjc_v2_global_trees[OCTI_V2_PROPERTY_TEMPL], | ||||
2639 | is_proto ? context | ||||
2640 | : klass_ctxt); | ||||
2641 | |||||
2642 | init_val = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (objc_v2_property_template))((unsigned long) (*tree_int_cst_elt_check ((((tree_class_check ((objc_v2_global_trees[OCTI_V2_PROPERTY_TEMPL]), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2642, __FUNCTION__))->type_common.size_unit)), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2642, __FUNCTION__))); | ||||
2643 | if (is_proto) | ||||
2644 | snprintf (buf, BUFSIZE1024, "_OBJC_ProtocolPropList_%s", | ||||
2645 | IDENTIFIER_POINTER (PROTOCOL_NAME (context))((const char *) (tree_check (((((tree_class_check ((context), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2645, __FUNCTION__))->type_common.name))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2645, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
2646 | else | ||||
2647 | snprintf (buf, BUFSIZE1024, "_OBJC_ClassPropList_%s", | ||||
2648 | IDENTIFIER_POINTER (CLASS_NAME (klass_ctxt))((const char *) (tree_check (((((tree_class_check ((klass_ctxt ), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2648, __FUNCTION__))->type_common.name))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2648, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
2649 | |||||
2650 | decl = start_var_decl (property_list_template, buf); | ||||
2651 | |||||
2652 | CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,do { constructor_elt _ce___ = {(tree) nullptr, build_int_cst ( (tree) nullptr, init_val)}; vec_safe_push ((inits), _ce___); } while (0) | ||||
2653 | build_int_cst (NULL_TREE, init_val))do { constructor_elt _ce___ = {(tree) nullptr, build_int_cst ( (tree) nullptr, init_val)}; vec_safe_push ((inits), _ce___); } while (0); | ||||
2654 | CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,do { constructor_elt _ce___ = {(tree) nullptr, build_int_cst ( (tree) nullptr, size)}; vec_safe_push ((inits), _ce___); } while (0) | ||||
2655 | build_int_cst (NULL_TREE, size))do { constructor_elt _ce___ = {(tree) nullptr, build_int_cst ( (tree) nullptr, size)}; vec_safe_push ((inits), _ce___); } while (0); | ||||
2656 | CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, initlist)do { constructor_elt _ce___ = {(tree) nullptr, initlist}; vec_safe_push ((inits), _ce___); } while (0); | ||||
2657 | |||||
2658 | OBJCMETA (decl, objc_meta, meta_base)if (objc_rt_trees[OCTI_RT_OBJC_META]) ((contains_struct_check ((decl), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2658, __FUNCTION__))->decl_common.attributes) = build_tree_list ((objc_rt_trees[OCTI_RT_OBJC_META]), (objc_rt_trees[OCTI_RT_META_BASE ]));; | ||||
2659 | finish_var_decl (decl, objc_build_constructor (TREE_TYPE (decl)((contains_struct_check ((decl), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2659, __FUNCTION__))->typed.type), inits)); | ||||
2660 | return decl; | ||||
2661 | } | ||||
2662 | |||||
2663 | static tree | ||||
2664 | build_v2_protocol_initializer (tree type, tree protocol_name, tree protocol_list, | ||||
2665 | tree inst_methods, tree class_methods, | ||||
2666 | tree opt_ins_meth, tree opt_cls_meth, | ||||
2667 | tree property_list, tree ext_meth_types, | ||||
2668 | tree demangled_name, tree class_prop_list) | ||||
2669 | { | ||||
2670 | tree expr, ttyp; | ||||
2671 | location_t loc; | ||||
2672 | vec<constructor_elt, va_gc> *inits = NULLnullptr; | ||||
2673 | |||||
2674 | /* TODO: find a better representation of location from the inputs. */ | ||||
2675 | loc = UNKNOWN_LOCATION((location_t) 0); | ||||
2676 | |||||
2677 | /* This is NULL for the new ABI. */ | ||||
2678 | CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,do { constructor_elt _ce___ = {(tree) nullptr, convert (objc_global_trees [OCTI_ID_TYPE], global_trees[TI_NULL_POINTER])}; vec_safe_push ((inits), _ce___); } while (0) | ||||
2679 | convert (objc_object_type, null_pointer_node))do { constructor_elt _ce___ = {(tree) nullptr, convert (objc_global_trees [OCTI_ID_TYPE], global_trees[TI_NULL_POINTER])}; vec_safe_push ((inits), _ce___); } while (0); | ||||
2680 | |||||
2681 | CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, protocol_name)do { constructor_elt _ce___ = {(tree) nullptr, protocol_name} ; vec_safe_push ((inits), _ce___); } while (0); | ||||
2682 | CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, protocol_list)do { constructor_elt _ce___ = {(tree) nullptr, protocol_list} ; vec_safe_push ((inits), _ce___); } while (0); | ||||
2683 | |||||
2684 | ttyp = objc_method_proto_list_ptrobjc_global_trees[OCTI_METH_PROTO_LIST_TEMPL]; | ||||
2685 | if (inst_methods) | ||||
2686 | expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, inst_methods, 0)); | ||||
2687 | else | ||||
2688 | expr = convert (ttyp, null_pointer_nodeglobal_trees[TI_NULL_POINTER]); | ||||
2689 | CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr)do { constructor_elt _ce___ = {(tree) nullptr, expr}; vec_safe_push ((inits), _ce___); } while (0); | ||||
2690 | |||||
2691 | if (class_methods) | ||||
2692 | expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, class_methods, 0)); | ||||
2693 | else | ||||
2694 | expr = convert (ttyp, null_pointer_nodeglobal_trees[TI_NULL_POINTER]); | ||||
2695 | CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr)do { constructor_elt _ce___ = {(tree) nullptr, expr}; vec_safe_push ((inits), _ce___); } while (0); | ||||
2696 | |||||
2697 | if (opt_ins_meth) | ||||
2698 | expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, opt_ins_meth, 0)); | ||||
2699 | else | ||||
2700 | expr = convert (ttyp, null_pointer_nodeglobal_trees[TI_NULL_POINTER]); | ||||
2701 | CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr)do { constructor_elt _ce___ = {(tree) nullptr, expr}; vec_safe_push ((inits), _ce___); } while (0); | ||||
2702 | |||||
2703 | if (opt_cls_meth) | ||||
2704 | expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, opt_cls_meth, 0)); | ||||
2705 | else | ||||
2706 | expr = convert (ttyp, null_pointer_nodeglobal_trees[TI_NULL_POINTER]); | ||||
2707 | CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr)do { constructor_elt _ce___ = {(tree) nullptr, expr}; vec_safe_push ((inits), _ce___); } while (0); | ||||
2708 | |||||
2709 | ttyp = objc_prop_list_ptrobjc_global_trees[OCTI_V1_PROP_LIST_TEMPL]; | ||||
2710 | if (property_list) | ||||
2711 | expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, property_list, 0)); | ||||
2712 | else | ||||
2713 | expr = convert (ttyp, null_pointer_nodeglobal_trees[TI_NULL_POINTER]); | ||||
2714 | CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr)do { constructor_elt _ce___ = {(tree) nullptr, expr}; vec_safe_push ((inits), _ce___); } while (0); | ||||
2715 | |||||
2716 | /* const uint32_t size; = sizeof(struct protocol_t) */ | ||||
2717 | expr = build_int_cst (integer_type_nodeinteger_types[itk_int], | ||||
2718 | TREE_INT_CST_LOW (TYPE_SIZE_UNIT (objc_v2_protocol_template))((unsigned long) (*tree_int_cst_elt_check ((((tree_class_check ((objc_v2_global_trees[OCTI_V2_PROTO_TEMPL]), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2718, __FUNCTION__))->type_common.size_unit)), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2718, __FUNCTION__)))); | ||||
2719 | CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr)do { constructor_elt _ce___ = {(tree) nullptr, expr}; vec_safe_push ((inits), _ce___); } while (0); | ||||
2720 | /* const uint32_t flags; = 0 */ | ||||
2721 | CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, integer_zero_node)do { constructor_elt _ce___ = {(tree) nullptr, global_trees[TI_INTEGER_ZERO ]}; vec_safe_push ((inits), _ce___); } while (0); | ||||
2722 | |||||
2723 | ttyp = build_pointer_type (string_type_nodec_global_trees[CTI_STRING_TYPE]); | ||||
2724 | if (ext_meth_types) | ||||
2725 | expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, ext_meth_types, 0)); | ||||
2726 | else | ||||
2727 | expr = convert (ttyp, null_pointer_nodeglobal_trees[TI_NULL_POINTER]); | ||||
2728 | CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr)do { constructor_elt _ce___ = {(tree) nullptr, expr}; vec_safe_push ((inits), _ce___); } while (0); | ||||
2729 | |||||
2730 | ttyp = string_type_nodec_global_trees[CTI_STRING_TYPE]; | ||||
2731 | if (demangled_name) | ||||
2732 | expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, demangled_name, 0)); | ||||
2733 | else | ||||
2734 | expr = convert (ttyp, null_pointer_nodeglobal_trees[TI_NULL_POINTER]); | ||||
2735 | CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr)do { constructor_elt _ce___ = {(tree) nullptr, expr}; vec_safe_push ((inits), _ce___); } while (0); | ||||
2736 | |||||
2737 | ttyp = objc_prop_list_ptrobjc_global_trees[OCTI_V1_PROP_LIST_TEMPL]; | ||||
2738 | if (class_prop_list) | ||||
2739 | expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, class_prop_list, 0)); | ||||
2740 | else | ||||
2741 | expr = convert (ttyp, null_pointer_nodeglobal_trees[TI_NULL_POINTER]); | ||||
2742 | CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr)do { constructor_elt _ce___ = {(tree) nullptr, expr}; vec_safe_push ((inits), _ce___); } while (0); | ||||
2743 | |||||
2744 | return objc_build_constructor (type, inits); | ||||
2745 | } | ||||
2746 | |||||
2747 | /* Main routine to build all meta data for all protocols used in a | ||||
2748 | translation unit. */ | ||||
2749 | |||||
2750 | static void | ||||
2751 | generate_v2_protocols (void) | ||||
2752 | { | ||||
2753 | tree p ; | ||||
2754 | bool some = false; | ||||
2755 | |||||
2756 | if (!protocol_chainobjc_global_trees[OCTI_PROTO_CHAIN]) | ||||
2757 | return ; | ||||
2758 | |||||
2759 | /* If a protocol was directly referenced, pull in indirect | ||||
2760 | references. */ | ||||
2761 | for (p = protocol_chainobjc_global_trees[OCTI_PROTO_CHAIN]; p; p = TREE_CHAIN (p)((contains_struct_check ((p), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2761, __FUNCTION__))->common.chain)) | ||||
2762 | if (PROTOCOL_FORWARD_DECL (p)(*((const_cast<tree *> (tree_vec_elt_check ((((tree_class_check ((p), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2762, __FUNCTION__))->type_non_common.lang_1)), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2762, __FUNCTION__))))) && PROTOCOL_LIST (p)(*((const_cast<tree *> (tree_vec_elt_check ((((tree_class_check ((p), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2762, __FUNCTION__))->type_non_common.lang_1)), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2762, __FUNCTION__)))))) | ||||
2763 | generate_protocol_references (PROTOCOL_LIST (p)(*((const_cast<tree *> (tree_vec_elt_check ((((tree_class_check ((p), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2763, __FUNCTION__))->type_non_common.lang_1)), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2763, __FUNCTION__)))))); | ||||
2764 | |||||
2765 | for (p = protocol_chainobjc_global_trees[OCTI_PROTO_CHAIN]; p; p = TREE_CHAIN (p)((contains_struct_check ((p), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2765, __FUNCTION__))->common.chain)) | ||||
2766 | { | ||||
2767 | location_t loc; | ||||
2768 | tree inst_meth, class_meth, opt_inst_meth, opt_class_meth, props; | ||||
2769 | tree decl, initlist, protocol_name_expr, refs_decl, refs_expr; | ||||
2770 | |||||
2771 | /* If protocol wasn't referenced, don't generate any code. */ | ||||
2772 | decl = PROTOCOL_FORWARD_DECL (p)(*((const_cast<tree *> (tree_vec_elt_check ((((tree_class_check ((p), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2772, __FUNCTION__))->type_non_common.lang_1)), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2772, __FUNCTION__))))); | ||||
2773 | |||||
2774 | if (!decl) | ||||
2775 | continue; | ||||
2776 | |||||
2777 | loc = DECL_SOURCE_LOCATION (decl)((contains_struct_check ((decl), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2777, __FUNCTION__))->decl_minimal.locus); | ||||
2778 | some = true; | ||||
2779 | |||||
2780 | vec<tree> all_meths = vNULL; | ||||
2781 | inst_meth = | ||||
2782 | generate_v2_meth_descriptor_table (PROTOCOL_NST_METHODS (p)(((tree_class_check ((p), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2782, __FUNCTION__))->type_non_common.minval)), p, | ||||
2783 | "_OBJC_ProtocolInstanceMethods", | ||||
2784 | meta_proto_nst_methobjc_rt_trees[OCTI_RT_META_PROTO_NST_METH], all_meths); | ||||
2785 | |||||
2786 | class_meth = | ||||
2787 | generate_v2_meth_descriptor_table (PROTOCOL_CLS_METHODS (p)(((tree_class_check ((p), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2787, __FUNCTION__))->type_non_common.maxval)), p, | ||||
2788 | "_OBJC_ProtocolClassMethods", | ||||
2789 | meta_proto_cls_methobjc_rt_trees[OCTI_RT_META_PROTO_CLS_METH], all_meths); | ||||
2790 | |||||
2791 | opt_inst_meth = | ||||
2792 | generate_v2_meth_descriptor_table (PROTOCOL_OPTIONAL_NST_METHODS (p)(*((const_cast<tree *> (tree_vec_elt_check ((((tree_class_check ((p), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2792, __FUNCTION__))->type_non_common.lang_1)), (3), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2792, __FUNCTION__))))), p, | ||||
2793 | "_OBJC_ProtocolOptInstMethods", | ||||
2794 | meta_proto_nst_methobjc_rt_trees[OCTI_RT_META_PROTO_NST_METH], all_meths); | ||||
2795 | |||||
2796 | opt_class_meth = | ||||
2797 | generate_v2_meth_descriptor_table (PROTOCOL_OPTIONAL_CLS_METHODS (p)(*((const_cast<tree *> (tree_vec_elt_check ((((tree_class_check ((p), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2797, __FUNCTION__))->type_non_common.lang_1)), (2), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2797, __FUNCTION__))))), p, | ||||
2798 | "_OBJC_ProtocolOptClassMethods", | ||||
2799 | meta_proto_cls_methobjc_rt_trees[OCTI_RT_META_PROTO_CLS_METH], all_meths); | ||||
2800 | |||||
2801 | if (PROTOCOL_LIST (p)(*((const_cast<tree *> (tree_vec_elt_check ((((tree_class_check ((p), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2801, __FUNCTION__))->type_non_common.lang_1)), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2801, __FUNCTION__)))))) | ||||
2802 | refs_decl = generate_v2_protocol_list (p, NULL_TREE(tree) nullptr); | ||||
2803 | else | ||||
2804 | refs_decl = 0; | ||||
2805 | |||||
2806 | /* static struct objc_protocol _OBJC_Protocol_<mumble>; */ | ||||
2807 | protocol_name_expr = add_objc_string (PROTOCOL_NAME (p)(((tree_class_check ((p), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2807, __FUNCTION__))->type_common.name)), class_names); | ||||
2808 | |||||
2809 | if (refs_decl) | ||||
2810 | refs_expr = convert (build_pointer_type (objc_v2_protocol_templateobjc_v2_global_trees[OCTI_V2_PROTO_TEMPL]), | ||||
2811 | build_unary_op (loc, ADDR_EXPR, refs_decl, 0)); | ||||
2812 | else | ||||
2813 | refs_expr = build_int_cst (NULL_TREE(tree) nullptr, 0); | ||||
2814 | |||||
2815 | props = generate_v2_property_table (p, NULL_TREE(tree) nullptr); | ||||
2816 | |||||
2817 | tree ext_meth_types | ||||
2818 | = generate_v2_meth_type_list (all_meths, p, | ||||
2819 | "_OBJC_ProtocolMethodTypes"); | ||||
2820 | tree demangled_name = NULL_TREE(tree) nullptr; | ||||
2821 | tree class_prop_list = NULL_TREE(tree) nullptr; | ||||
2822 | |||||
2823 | initlist = build_v2_protocol_initializer (TREE_TYPE (decl)((contains_struct_check ((decl), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2823, __FUNCTION__))->typed.type), | ||||
2824 | protocol_name_expr, refs_expr, | ||||
2825 | inst_meth, class_meth, | ||||
2826 | opt_inst_meth, opt_class_meth, | ||||
2827 | props, ext_meth_types, | ||||
2828 | demangled_name,class_prop_list); | ||||
2829 | finish_var_decl (decl, initlist); | ||||
2830 | objc_add_to_protocol_list (p, decl); | ||||
2831 | all_meths.truncate (0); | ||||
2832 | } | ||||
2833 | |||||
2834 | if (some) | ||||
2835 | { | ||||
2836 | /* Make sure we get the Protocol class linked in - reference | ||||
2837 | it... */ | ||||
2838 | p = objc_v2_get_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME)(__builtin_constant_p ("Protocol") ? get_identifier_with_length (("Protocol"), strlen ("Protocol")) : get_identifier ("Protocol" ))); | ||||
2839 | /* ... but since we don't specifically use the reference... we | ||||
2840 | need to force it. */ | ||||
2841 | DECL_PRESERVE_P (p)(contains_struct_check ((p), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2841, __FUNCTION__))->decl_common.preserve_flag = 1; | ||||
2842 | } | ||||
2843 | } | ||||
2844 | |||||
2845 | static tree | ||||
2846 | generate_v2_dispatch_table (tree chain, const char *name, tree attr) | ||||
2847 | { | ||||
2848 | tree decl, method_list_template, initlist; | ||||
2849 | vec<constructor_elt, va_gc> *v = NULLnullptr; | ||||
2850 | int size, init_val; | ||||
2851 | |||||
2852 | if (!chain || !name || !(size = list_length (chain))) | ||||
2853 | return NULL_TREE(tree) nullptr; | ||||
2854 | |||||
2855 | method_list_template | ||||
2856 | = build_v2_method_list_template (objc_method_templateobjc_global_trees[OCTI_METH_TEMPL], size); | ||||
2857 | initlist | ||||
2858 | = build_dispatch_table_initializer (objc_method_templateobjc_global_trees[OCTI_METH_TEMPL], chain); | ||||
2859 | |||||
2860 | decl = start_var_decl (method_list_template, name); | ||||
2861 | |||||
2862 | init_val = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (objc_method_template))((unsigned long) (*tree_int_cst_elt_check ((((tree_class_check ((objc_global_trees[OCTI_METH_TEMPL]), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2862, __FUNCTION__))->type_common.size_unit)), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2862, __FUNCTION__))); | ||||
2863 | CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,do { constructor_elt _ce___ = {(tree) nullptr, build_int_cst ( integer_types[itk_int], init_val)}; vec_safe_push ((v), _ce___ ); } while (0) | ||||
2864 | build_int_cst (integer_type_node, init_val))do { constructor_elt _ce___ = {(tree) nullptr, build_int_cst ( integer_types[itk_int], init_val)}; vec_safe_push ((v), _ce___ ); } while (0); | ||||
2865 | CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,do { constructor_elt _ce___ = {(tree) nullptr, build_int_cst ( integer_types[itk_int], size)}; vec_safe_push ((v), _ce___); } while (0) | ||||
2866 | build_int_cst (integer_type_node, size))do { constructor_elt _ce___ = {(tree) nullptr, build_int_cst ( integer_types[itk_int], size)}; vec_safe_push ((v), _ce___); } while (0); | ||||
2867 | CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, initlist)do { constructor_elt _ce___ = {(tree) nullptr, initlist}; vec_safe_push ((v), _ce___); } while (0); | ||||
2868 | |||||
2869 | OBJCMETA (decl, objc_meta, attr)if (objc_rt_trees[OCTI_RT_OBJC_META]) ((contains_struct_check ((decl), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2869, __FUNCTION__))->decl_common.attributes) = build_tree_list ((objc_rt_trees[OCTI_RT_OBJC_META]), (attr));; | ||||
2870 | finish_var_decl (decl, | ||||
2871 | objc_build_constructor (TREE_TYPE (decl)((contains_struct_check ((decl), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2871, __FUNCTION__))->typed.type), v)); | ||||
2872 | return decl; | ||||
2873 | } | ||||
2874 | |||||
2875 | /* Init a category. */ | ||||
2876 | static tree | ||||
2877 | build_v2_category_initializer (tree type, tree cat_name, tree class_name, | ||||
2878 | tree inst_methods, tree class_methods, | ||||
2879 | tree protocol_list, tree property_list, | ||||
2880 | location_t loc) | ||||
2881 | { | ||||
2882 | tree expr, ltyp; | ||||
2883 | vec<constructor_elt, va_gc> *v = NULLnullptr; | ||||
2884 | |||||
2885 | CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, cat_name)do { constructor_elt _ce___ = {(tree) nullptr, cat_name}; vec_safe_push ((v), _ce___); } while (0); | ||||
2886 | CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, class_name)do { constructor_elt _ce___ = {(tree) nullptr, class_name}; vec_safe_push ((v), _ce___); } while (0); | ||||
2887 | |||||
2888 | ltyp = objc_method_list_ptrobjc_global_trees[OCTI_METH_LIST_TEMPL]; | ||||
2889 | if (inst_methods) | ||||
2890 | expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, inst_methods, 0)); | ||||
2891 | else | ||||
2892 | expr = convert (ltyp, null_pointer_nodeglobal_trees[TI_NULL_POINTER]); | ||||
2893 | CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr)do { constructor_elt _ce___ = {(tree) nullptr, expr}; vec_safe_push ((v), _ce___); } while (0); | ||||
2894 | |||||
2895 | if (class_methods) | ||||
2896 | expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, class_methods, 0)); | ||||
2897 | else | ||||
2898 | expr = convert (ltyp, null_pointer_nodeglobal_trees[TI_NULL_POINTER]); | ||||
2899 | CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr)do { constructor_elt _ce___ = {(tree) nullptr, expr}; vec_safe_push ((v), _ce___); } while (0); | ||||
2900 | |||||
2901 | /* protocol_list = */ | ||||
2902 | ltyp = build_pointer_type (objc_v2_protocol_templateobjc_v2_global_trees[OCTI_V2_PROTO_TEMPL]); | ||||
2903 | if (protocol_list) | ||||
2904 | expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, protocol_list, 0)); | ||||
2905 | else | ||||
2906 | expr = convert (ltyp, null_pointer_nodeglobal_trees[TI_NULL_POINTER]); | ||||
2907 | CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr)do { constructor_elt _ce___ = {(tree) nullptr, expr}; vec_safe_push ((v), _ce___); } while (0); | ||||
2908 | |||||
2909 | ltyp = objc_prop_list_ptrobjc_global_trees[OCTI_V1_PROP_LIST_TEMPL]; | ||||
2910 | if (property_list) | ||||
2911 | expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, property_list, 0)); | ||||
2912 | else | ||||
2913 | expr = convert (ltyp, null_pointer_nodeglobal_trees[TI_NULL_POINTER]); | ||||
2914 | CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr)do { constructor_elt _ce___ = {(tree) nullptr, expr}; vec_safe_push ((v), _ce___); } while (0); | ||||
2915 | |||||
2916 | return objc_build_constructor (type, v); | ||||
2917 | } | ||||
2918 | |||||
2919 | /* static struct category_t _OBJC_CATEGORY_$_<name> = { ... }; */ | ||||
2920 | |||||
2921 | static void | ||||
2922 | generate_v2_category (struct imp_entry *impent) | ||||
2923 | { | ||||
2924 | tree initlist, cat_name_expr, class_name_expr; | ||||
2925 | tree protocol_decl, category, props, t; | ||||
2926 | tree inst_methods = NULL_TREE(tree) nullptr, class_methods = NULL_TREE(tree) nullptr; | ||||
2927 | tree cat = impent->imp_context; | ||||
2928 | tree cat_decl = impent->class_decl; | ||||
2929 | location_t loc; | ||||
2930 | char buf[BUFSIZE1024]; | ||||
2931 | |||||
2932 | loc = DECL_SOURCE_LOCATION (cat_decl)((contains_struct_check ((cat_decl), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2932, __FUNCTION__))->decl_minimal.locus); | ||||
2933 | |||||
2934 | /* ??? not sure this is really necessary, the following references should | ||||
2935 | force appropriate linkage linkage... | ||||
2936 | -- but ... ensure a reference to the class... */ | ||||
2937 | t = objc_v2_get_class_reference (CLASS_NAME (cat)(((tree_class_check ((cat), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2937, __FUNCTION__))->type_common.name))); | ||||
2938 | /* ... which we ignore so force it out.. */ | ||||
2939 | DECL_PRESERVE_P (t)(contains_struct_check ((t), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2939, __FUNCTION__))->decl_common.preserve_flag = 1; | ||||
2940 | |||||
2941 | snprintf (buf, BUFSIZE1024, "OBJC_CLASS_$_%s", IDENTIFIER_POINTER (CLASS_NAME (cat))((const char *) (tree_check (((((tree_class_check ((cat), (tcc_type ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2941, __FUNCTION__))->type_common.name))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2941, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
2942 | class_name_expr = create_extern_decl (objc_v2_class_templateobjc_v2_global_trees[OCTI_V2_CLS_TEMPL], buf); | ||||
2943 | class_name_expr = build_fold_addr_expr (class_name_expr)build_fold_addr_expr_loc (((location_t) 0), (class_name_expr) ); | ||||
2944 | |||||
2945 | cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat)(((tree_class_check ((cat), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2945, __FUNCTION__))->type_common.context)), class_names); | ||||
2946 | category = lookup_category (impent->imp_template, CLASS_SUPER_NAME (cat)(((tree_class_check ((cat), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2946, __FUNCTION__))->type_common.context))); | ||||
2947 | |||||
2948 | if (category && CLASS_PROTOCOL_LIST (category)(*((const_cast<tree *> (tree_vec_elt_check ((((tree_class_check ((category), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2948, __FUNCTION__))->type_non_common.lang_1)), (4), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2948, __FUNCTION__)))))) | ||||
2949 | { | ||||
2950 | generate_protocol_references (CLASS_PROTOCOL_LIST (category)(*((const_cast<tree *> (tree_vec_elt_check ((((tree_class_check ((category), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2950, __FUNCTION__))->type_non_common.lang_1)), (4), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2950, __FUNCTION__)))))); | ||||
2951 | protocol_decl = generate_v2_protocol_list (category, cat); | ||||
2952 | } | ||||
2953 | else | ||||
2954 | protocol_decl = NULL_TREE(tree) nullptr; | ||||
2955 | |||||
2956 | /* decl = update_var_decl(impent->class_decl); */ | ||||
2957 | |||||
2958 | props = generate_v2_property_table (NULL_TREE(tree) nullptr, cat); | ||||
2959 | |||||
2960 | if (CLASS_NST_METHODS (cat)(((tree_class_check ((cat), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2960, __FUNCTION__))->type_non_common.minval))) | ||||
2961 | { | ||||
2962 | snprintf (buf, BUFSIZE1024, "_OBJC_CategoryInstanceMethods_%s_%s", | ||||
2963 | IDENTIFIER_POINTER (CLASS_NAME (cat))((const char *) (tree_check (((((tree_class_check ((cat), (tcc_type ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2963, __FUNCTION__))->type_common.name))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2963, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ), | ||||
2964 | IDENTIFIER_POINTER (CLASS_SUPER_NAME (cat))((const char *) (tree_check (((((tree_class_check ((cat), (tcc_type ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2964, __FUNCTION__))->type_common.context))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2964, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
2965 | inst_methods = generate_v2_dispatch_table (CLASS_NST_METHODS (cat)(((tree_class_check ((cat), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2965, __FUNCTION__))->type_non_common.minval)), buf, | ||||
2966 | meta_cati_methobjc_rt_trees[OCTI_RT_META_CATEG_NST_METH]); | ||||
2967 | } | ||||
2968 | |||||
2969 | if (CLASS_CLS_METHODS (cat)(((tree_class_check ((cat), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2969, __FUNCTION__))->type_non_common.maxval))) | ||||
2970 | { | ||||
2971 | snprintf (buf, BUFSIZE1024, "_OBJC_CategoryClassMethods_%s_%s", | ||||
2972 | IDENTIFIER_POINTER (CLASS_NAME (cat))((const char *) (tree_check (((((tree_class_check ((cat), (tcc_type ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2972, __FUNCTION__))->type_common.name))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2972, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ), | ||||
2973 | IDENTIFIER_POINTER (CLASS_SUPER_NAME (cat))((const char *) (tree_check (((((tree_class_check ((cat), (tcc_type ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2973, __FUNCTION__))->type_common.context))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2973, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
2974 | class_methods = generate_v2_dispatch_table (CLASS_CLS_METHODS (cat)(((tree_class_check ((cat), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2974, __FUNCTION__))->type_non_common.maxval)), buf, | ||||
2975 | meta_catc_methobjc_rt_trees[OCTI_RT_META_CATEG_CLS_METH]); | ||||
2976 | } | ||||
2977 | |||||
2978 | initlist = build_v2_category_initializer (TREE_TYPE (cat_decl)((contains_struct_check ((cat_decl), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2978, __FUNCTION__))->typed.type), | ||||
2979 | cat_name_expr, class_name_expr, | ||||
2980 | inst_methods, class_methods, | ||||
2981 | protocol_decl, props, loc); | ||||
2982 | |||||
2983 | finish_var_decl (cat_decl, initlist); | ||||
2984 | impent->class_decl = cat_decl; | ||||
2985 | |||||
2986 | /* Add to list of pointers in __category_list section. */ | ||||
2987 | objc_v2_add_to_category_list (cat_decl); | ||||
2988 | if (has_load_impl (CLASS_CLS_METHODS (impent->imp_context)(((tree_class_check ((impent->imp_context), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 2988, __FUNCTION__))->type_non_common.maxval)))) | ||||
2989 | objc_v2_add_to_nonlazy_category_list (cat_decl); | ||||
2990 | } | ||||
2991 | |||||
2992 | /* This routine declares a variable to hold the offset for ivar | ||||
2993 | FIELD_DECL. Variable name is .objc_ivar.ClassName.IvarName. */ | ||||
2994 | |||||
2995 | struct GTY(()) ivarref_entry | ||||
2996 | { | ||||
2997 | tree decl; | ||||
2998 | tree offset; | ||||
2999 | }; | ||||
3000 | |||||
3001 | static GTY (()) vec<ivarref_entry, va_gc> *ivar_offset_refs; | ||||
3002 | |||||
3003 | static tree | ||||
3004 | ivar_offset_ref (tree class_name, tree field_decl) | ||||
3005 | { | ||||
3006 | tree decl, field_decl_id; | ||||
3007 | ivarref_entry e; | ||||
3008 | bool global_var; | ||||
3009 | char buf[512]; | ||||
3010 | |||||
3011 | create_ivar_offset_name (buf, class_name, field_decl); | ||||
3012 | field_decl_id = get_identifier (buf)(__builtin_constant_p (buf) ? get_identifier_with_length ((buf ), strlen (buf)) : get_identifier (buf)); | ||||
3013 | |||||
3014 | if (ivar_offset_refs) | ||||
3015 | { | ||||
3016 | int count; | ||||
3017 | ivarref_entry *ref; | ||||
3018 | FOR_EACH_VEC_ELT (*ivar_offset_refs, count, ref)for (count = 0; (*ivar_offset_refs).iterate ((count), &(ref )); ++(count)) | ||||
3019 | if (DECL_NAME (ref->decl)((contains_struct_check ((ref->decl), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3019, __FUNCTION__))->decl_minimal.name) == field_decl_id) | ||||
3020 | return ref->decl; | ||||
3021 | } | ||||
3022 | else | ||||
3023 | /* Somewhat arbitrary initial provision. */ | ||||
3024 | vec_alloc (ivar_offset_refs, 32); | ||||
3025 | |||||
3026 | /* We come here if we don't find a match or at the start. */ | ||||
3027 | global_var = (TREE_PUBLIC (field_decl)((field_decl)->base.public_flag) || TREE_PROTECTED (field_decl)((field_decl)->base.protected_flag)); | ||||
3028 | if (global_var) | ||||
3029 | decl = create_global_decl (TREE_TYPE (size_zero_node)((contains_struct_check ((global_trees[TI_SIZE_ZERO]), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3029, __FUNCTION__))->typed.type), buf); | ||||
3030 | else | ||||
3031 | decl = create_hidden_decl (TREE_TYPE (size_zero_node)((contains_struct_check ((global_trees[TI_SIZE_ZERO]), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3031, __FUNCTION__))->typed.type), buf); | ||||
3032 | |||||
3033 | /* Identify so that we can indirect these where the ABI requires. */ | ||||
3034 | OBJCMETA (decl, objc_meta, meta_ivar_ref)if (objc_rt_trees[OCTI_RT_OBJC_META]) ((contains_struct_check ((decl), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3034, __FUNCTION__))->decl_common.attributes) = build_tree_list ((objc_rt_trees[OCTI_RT_OBJC_META]), (objc_rt_trees[OCTI_RT_META_IVAR_REF ]));; | ||||
3035 | |||||
3036 | e.decl = decl; | ||||
3037 | e.offset = byte_position (field_decl); | ||||
3038 | vec_safe_push (ivar_offset_refs, e); | ||||
3039 | return decl; | ||||
3040 | } | ||||
3041 | |||||
3042 | /* This routine builds initializer-list needed to initialize 'struct | ||||
3043 | ivar_t list[count] of 'struct ivar_list_t' meta data. TYPE is | ||||
3044 | 'struct ivar_t' and FIELD_DECL is list of ivars for the target | ||||
3045 | class. */ | ||||
3046 | |||||
3047 | static tree | ||||
3048 | build_v2_ivar_list_initializer (tree class_name, tree type, tree field_decl) | ||||
3049 | { | ||||
3050 | vec<constructor_elt, va_gc> *inits = NULLnullptr; | ||||
3051 | |||||
3052 | do | ||||
3053 | { | ||||
3054 | vec<constructor_elt, va_gc> *ivar = NULLnullptr; | ||||
3055 | int val; | ||||
3056 | tree id; | ||||
3057 | |||||
3058 | /* Unnamed bitfields are ignored. */ | ||||
3059 | if (!DECL_NAME (field_decl)((contains_struct_check ((field_decl), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3059, __FUNCTION__))->decl_minimal.name)) | ||||
3060 | { | ||||
3061 | field_decl = DECL_CHAIN (field_decl)(((contains_struct_check (((contains_struct_check ((field_decl ), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3061, __FUNCTION__))), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3061, __FUNCTION__))->common.chain)); | ||||
3062 | continue; | ||||
3063 | } | ||||
3064 | |||||
3065 | /* Set offset. */ | ||||
3066 | CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE,do { constructor_elt _ce___ = {(tree) nullptr, build_unary_op (input_location, ADDR_EXPR, ivar_offset_ref (class_name, field_decl ), 0)}; vec_safe_push ((ivar), _ce___); } while (0) | ||||
3067 | build_unary_op (input_location,do { constructor_elt _ce___ = {(tree) nullptr, build_unary_op (input_location, ADDR_EXPR, ivar_offset_ref (class_name, field_decl ), 0)}; vec_safe_push ((ivar), _ce___); } while (0) | ||||
3068 | ADDR_EXPR,do { constructor_elt _ce___ = {(tree) nullptr, build_unary_op (input_location, ADDR_EXPR, ivar_offset_ref (class_name, field_decl ), 0)}; vec_safe_push ((ivar), _ce___); } while (0) | ||||
3069 | ivar_offset_ref (class_name,do { constructor_elt _ce___ = {(tree) nullptr, build_unary_op (input_location, ADDR_EXPR, ivar_offset_ref (class_name, field_decl ), 0)}; vec_safe_push ((ivar), _ce___); } while (0) | ||||
3070 | field_decl), 0))do { constructor_elt _ce___ = {(tree) nullptr, build_unary_op (input_location, ADDR_EXPR, ivar_offset_ref (class_name, field_decl ), 0)}; vec_safe_push ((ivar), _ce___); } while (0); | ||||
3071 | |||||
3072 | /* Set name. */ | ||||
3073 | CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE,do { constructor_elt _ce___ = {(tree) nullptr, add_objc_string (((contains_struct_check ((field_decl), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3074, __FUNCTION__))->decl_minimal.name), meth_var_names )}; vec_safe_push ((ivar), _ce___); } while (0) | ||||
3074 | add_objc_string (DECL_NAME (field_decl),do { constructor_elt _ce___ = {(tree) nullptr, add_objc_string (((contains_struct_check ((field_decl), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3074, __FUNCTION__))->decl_minimal.name), meth_var_names )}; vec_safe_push ((ivar), _ce___); } while (0) | ||||
3075 | meth_var_names))do { constructor_elt _ce___ = {(tree) nullptr, add_objc_string (((contains_struct_check ((field_decl), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3074, __FUNCTION__))->decl_minimal.name), meth_var_names )}; vec_safe_push ((ivar), _ce___); } while (0); | ||||
3076 | |||||
3077 | /* Set type. */ | ||||
3078 | id = add_objc_string (encode_field_decl (field_decl), | ||||
3079 | meth_var_types); | ||||
3080 | CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, id)do { constructor_elt _ce___ = {(tree) nullptr, id}; vec_safe_push ((ivar), _ce___); } while (0); | ||||
3081 | |||||
3082 | /* Set alignment. */ | ||||
3083 | val = DECL_ALIGN_UNIT (field_decl)((((contains_struct_check ((field_decl), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3083, __FUNCTION__))->decl_common.align) ? ((unsigned)1) << (((contains_struct_check ((field_decl), (TS_DECL_COMMON ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3083, __FUNCTION__))->decl_common.align) - 1) : 0) / (8) ); | ||||
3084 | val = exact_log2 (val); | ||||
3085 | CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE,do { constructor_elt _ce___ = {(tree) nullptr, build_int_cst ( integer_types[itk_int], val)}; vec_safe_push ((ivar), _ce___) ; } while (0) | ||||
3086 | build_int_cst (integer_type_node, val))do { constructor_elt _ce___ = {(tree) nullptr, build_int_cst ( integer_types[itk_int], val)}; vec_safe_push ((ivar), _ce___) ; } while (0); | ||||
3087 | |||||
3088 | /* Set size. */ | ||||
3089 | val = TREE_INT_CST_LOW (DECL_SIZE_UNIT (field_decl))((unsigned long) (*tree_int_cst_elt_check ((((contains_struct_check ((field_decl), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3089, __FUNCTION__))->decl_common.size_unit)), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3089, __FUNCTION__))); | ||||
3090 | CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE,do { constructor_elt _ce___ = {(tree) nullptr, build_int_cst ( integer_types[itk_int], val)}; vec_safe_push ((ivar), _ce___) ; } while (0) | ||||
3091 | build_int_cst (integer_type_node, val))do { constructor_elt _ce___ = {(tree) nullptr, build_int_cst ( integer_types[itk_int], val)}; vec_safe_push ((ivar), _ce___) ; } while (0); | ||||
3092 | |||||
3093 | CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,do { constructor_elt _ce___ = {(tree) nullptr, objc_build_constructor (type, ivar)}; vec_safe_push ((inits), _ce___); } while (0) | ||||
3094 | objc_build_constructor (type, ivar))do { constructor_elt _ce___ = {(tree) nullptr, objc_build_constructor (type, ivar)}; vec_safe_push ((inits), _ce___); } while (0); | ||||
3095 | |||||
3096 | do | ||||
3097 | field_decl = DECL_CHAIN (field_decl)(((contains_struct_check (((contains_struct_check ((field_decl ), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3097, __FUNCTION__))), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3097, __FUNCTION__))->common.chain)); | ||||
3098 | while (field_decl && TREE_CODE (field_decl)((enum tree_code) (field_decl)->base.code) != FIELD_DECL); | ||||
3099 | } | ||||
3100 | while (field_decl); | ||||
3101 | |||||
3102 | return objc_build_constructor (build_array_type (type, 0), inits); | ||||
3103 | } | ||||
3104 | |||||
3105 | /* | ||||
3106 | struct ivar_list_t | ||||
3107 | { | ||||
3108 | uint32 entsize; | ||||
3109 | uint32 count; | ||||
3110 | struct iver_t list[count]; | ||||
3111 | }; | ||||
3112 | */ | ||||
3113 | |||||
3114 | static tree | ||||
3115 | build_v2_ivar_list_t_template (tree list_type, int size) | ||||
3116 | { | ||||
3117 | tree objc_ivar_list_record; | ||||
3118 | tree decls, *chain = NULLnullptr; | ||||
3119 | |||||
3120 | /* Anonymous. */ | ||||
3121 | objc_ivar_list_record = objc_start_struct (NULL_TREE(tree) nullptr); | ||||
3122 | |||||
3123 | /* uint32 entsize; */ | ||||
3124 | decls = add_field_decl (integer_type_nodeinteger_types[itk_int], "entsize", &chain); | ||||
3125 | |||||
3126 | /* uint32 count; */ | ||||
3127 | add_field_decl (integer_type_nodeinteger_types[itk_int], "count", &chain); | ||||
3128 | |||||
3129 | /* struct objc_ivar ivar_list[]; */ | ||||
3130 | add_field_decl (build_sized_array_type (list_type, size), | ||||
3131 | "list", &chain); | ||||
3132 | |||||
3133 | objc_finish_struct (objc_ivar_list_record, decls); | ||||
3134 | return objc_ivar_list_record; | ||||
3135 | } | ||||
3136 | |||||
3137 | /* This routine declares a static variable of type 'struct | ||||
3138 | ivar_list_t' and initializes it. chain is the source of the data, | ||||
3139 | name is the name for the var. attr is the meta-data section tag | ||||
3140 | attribute. templ is the implementation template for the class. */ | ||||
3141 | |||||
3142 | static tree | ||||
3143 | generate_v2_ivars_list (tree chain, const char *name, tree attr, tree templ) | ||||
3144 | { | ||||
3145 | tree decl, initlist, ivar_list_template; | ||||
3146 | vec<constructor_elt, va_gc> *inits = NULLnullptr; | ||||
3147 | int size, ivar_t_size; | ||||
3148 | |||||
3149 | if (!chain || !name || !(size = ivar_list_length (chain))) | ||||
3150 | return NULL_TREE(tree) nullptr; | ||||
3151 | |||||
3152 | generating_instance_variables = 1; | ||||
3153 | ivar_list_template = build_v2_ivar_list_t_template (objc_v2_ivar_templateobjc_v2_global_trees[OCTI_V2_IVAR_TEMPL], | ||||
3154 | size); | ||||
3155 | |||||
3156 | initlist = build_v2_ivar_list_initializer (CLASS_NAME (templ)(((tree_class_check ((templ), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3156, __FUNCTION__))->type_common.name)), | ||||
3157 | objc_v2_ivar_templateobjc_v2_global_trees[OCTI_V2_IVAR_TEMPL], chain); | ||||
3158 | ivar_t_size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (objc_v2_ivar_template))((unsigned long) (*tree_int_cst_elt_check ((((tree_class_check ((objc_v2_global_trees[OCTI_V2_IVAR_TEMPL]), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3158, __FUNCTION__))->type_common.size_unit)), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3158, __FUNCTION__))); | ||||
3159 | |||||
3160 | decl = start_var_decl (ivar_list_template, name); | ||||
3161 | CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,do { constructor_elt _ce___ = {(tree) nullptr, build_int_cst ( integer_types[itk_int], ivar_t_size)}; vec_safe_push ((inits) , _ce___); } while (0) | ||||
3162 | build_int_cst (integer_type_node, ivar_t_size))do { constructor_elt _ce___ = {(tree) nullptr, build_int_cst ( integer_types[itk_int], ivar_t_size)}; vec_safe_push ((inits) , _ce___); } while (0); | ||||
3163 | CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,do { constructor_elt _ce___ = {(tree) nullptr, build_int_cst ( integer_types[itk_int], size)}; vec_safe_push ((inits), _ce___ ); } while (0) | ||||
3164 | build_int_cst (integer_type_node, size))do { constructor_elt _ce___ = {(tree) nullptr, build_int_cst ( integer_types[itk_int], size)}; vec_safe_push ((inits), _ce___ ); } while (0); | ||||
3165 | CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, initlist)do { constructor_elt _ce___ = {(tree) nullptr, initlist}; vec_safe_push ((inits), _ce___); } while (0); | ||||
3166 | OBJCMETA (decl, objc_meta, attr)if (objc_rt_trees[OCTI_RT_OBJC_META]) ((contains_struct_check ((decl), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3166, __FUNCTION__))->decl_common.attributes) = build_tree_list ((objc_rt_trees[OCTI_RT_OBJC_META]), (attr));; | ||||
3167 | finish_var_decl (decl, objc_build_constructor (TREE_TYPE (decl)((contains_struct_check ((decl), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3167, __FUNCTION__))->typed.type), inits)); | ||||
3168 | generating_instance_variables = 0; | ||||
3169 | return decl; | ||||
3170 | } | ||||
3171 | |||||
3172 | /* Routine to build initializer list to initialize objects of type | ||||
3173 | struct class_t; */ | ||||
3174 | |||||
3175 | static tree | ||||
3176 | build_v2_class_t_initializer (tree type, tree isa, tree superclass, | ||||
3177 | tree ro, tree cache, tree vtable) | ||||
3178 | { | ||||
3179 | vec<constructor_elt, va_gc> *initlist = NULLnullptr; | ||||
3180 | |||||
3181 | /* isa */ | ||||
3182 | CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, isa)do { constructor_elt _ce___ = {(tree) nullptr, isa}; vec_safe_push ((initlist), _ce___); } while (0); | ||||
3183 | |||||
3184 | /* superclass */ | ||||
3185 | CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, superclass)do { constructor_elt _ce___ = {(tree) nullptr, superclass}; vec_safe_push ((initlist), _ce___); } while (0); | ||||
3186 | |||||
3187 | /* cache */ | ||||
3188 | if (cache) | ||||
3189 | CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, cache)do { constructor_elt _ce___ = {(tree) nullptr, cache}; vec_safe_push ((initlist), _ce___); } while (0); | ||||
3190 | else | ||||
3191 | CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, null_pointer_node)do { constructor_elt _ce___ = {(tree) nullptr, global_trees[TI_NULL_POINTER ]}; vec_safe_push ((initlist), _ce___); } while (0); | ||||
3192 | |||||
3193 | /* vtable */ | ||||
3194 | if (vtable) | ||||
3195 | CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, vtable)do { constructor_elt _ce___ = {(tree) nullptr, vtable}; vec_safe_push ((initlist), _ce___); } while (0); | ||||
3196 | else | ||||
3197 | CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, null_pointer_node)do { constructor_elt _ce___ = {(tree) nullptr, global_trees[TI_NULL_POINTER ]}; vec_safe_push ((initlist), _ce___); } while (0); | ||||
3198 | |||||
3199 | /* ro */ | ||||
3200 | CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, ro)do { constructor_elt _ce___ = {(tree) nullptr, ro}; vec_safe_push ((initlist), _ce___); } while (0); | ||||
3201 | |||||
3202 | return objc_build_constructor (type, initlist); | ||||
3203 | } | ||||
3204 | |||||
3205 | /* Routine to build object of struct class_ro_t { ... }; */ | ||||
3206 | |||||
3207 | static tree | ||||
3208 | build_v2_class_ro_t_initializer (tree type, tree name, | ||||
3209 | unsigned int flags, unsigned int instanceStart, | ||||
3210 | unsigned int instanceSize, | ||||
3211 | tree ivarLayout, | ||||
3212 | tree baseMethods, tree baseProtocols, | ||||
3213 | tree ivars, tree property_list) | ||||
3214 | { | ||||
3215 | tree expr, unsigned_char_star, ltyp; | ||||
3216 | location_t loc; | ||||
3217 | vec<constructor_elt, va_gc> *initlist = NULLnullptr; | ||||
3218 | |||||
3219 | /* TODO: fish out the real location from somewhere. */ | ||||
3220 | loc = UNKNOWN_LOCATION((location_t) 0); | ||||
3221 | |||||
3222 | /* flags */ | ||||
3223 | CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE,do { constructor_elt _ce___ = {(tree) nullptr, build_int_cst ( integer_types[itk_int], flags)}; vec_safe_push ((initlist), _ce___ ); } while (0) | ||||
3224 | build_int_cst (integer_type_node, flags))do { constructor_elt _ce___ = {(tree) nullptr, build_int_cst ( integer_types[itk_int], flags)}; vec_safe_push ((initlist), _ce___ ); } while (0); | ||||
3225 | |||||
3226 | /* instanceStart */ | ||||
3227 | CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE,do { constructor_elt _ce___ = {(tree) nullptr, build_int_cst ( integer_types[itk_int], instanceStart)}; vec_safe_push ((initlist ), _ce___); } while (0) | ||||
3228 | build_int_cst (integer_type_node, instanceStart))do { constructor_elt _ce___ = {(tree) nullptr, build_int_cst ( integer_types[itk_int], instanceStart)}; vec_safe_push ((initlist ), _ce___); } while (0); | ||||
3229 | |||||
3230 | /* instanceSize */ | ||||
3231 | CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE,do { constructor_elt _ce___ = {(tree) nullptr, build_int_cst ( integer_types[itk_int], instanceSize)}; vec_safe_push ((initlist ), _ce___); } while (0) | ||||
3232 | build_int_cst (integer_type_node, instanceSize))do { constructor_elt _ce___ = {(tree) nullptr, build_int_cst ( integer_types[itk_int], instanceSize)}; vec_safe_push ((initlist ), _ce___); } while (0); | ||||
3233 | |||||
3234 | /* This ABI is currently only used on m64 NeXT. We always | ||||
3235 | explicitly declare the alignment padding. */ | ||||
3236 | /* reserved, pads alignment. */ | ||||
3237 | CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE,do { constructor_elt _ce___ = {(tree) nullptr, build_int_cst ( integer_types[itk_int], 0)}; vec_safe_push ((initlist), _ce___ ); } while (0) | ||||
3238 | build_int_cst (integer_type_node, 0))do { constructor_elt _ce___ = {(tree) nullptr, build_int_cst ( integer_types[itk_int], 0)}; vec_safe_push ((initlist), _ce___ ); } while (0); | ||||
3239 | |||||
3240 | /* ivarLayout */ | ||||
3241 | unsigned_char_star = build_pointer_type (unsigned_char_type_nodeinteger_types[itk_unsigned_char]); | ||||
3242 | if (ivarLayout) | ||||
3243 | expr = ivarLayout; | ||||
3244 | else | ||||
3245 | expr = convert (unsigned_char_star, null_pointer_nodeglobal_trees[TI_NULL_POINTER]); | ||||
3246 | CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, expr)do { constructor_elt _ce___ = {(tree) nullptr, expr}; vec_safe_push ((initlist), _ce___); } while (0); | ||||
3247 | |||||
3248 | /* name */ | ||||
3249 | CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, default_conversion (name))do { constructor_elt _ce___ = {(tree) nullptr, default_conversion (name)}; vec_safe_push ((initlist), _ce___); } while (0); | ||||
3250 | |||||
3251 | /* baseMethods */ | ||||
3252 | ltyp = objc_method_list_ptrobjc_global_trees[OCTI_METH_LIST_TEMPL]; | ||||
3253 | if (baseMethods) | ||||
3254 | expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, baseMethods, 0)); | ||||
3255 | else | ||||
3256 | expr = convert (ltyp, null_pointer_nodeglobal_trees[TI_NULL_POINTER]); | ||||
3257 | CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, expr)do { constructor_elt _ce___ = {(tree) nullptr, expr}; vec_safe_push ((initlist), _ce___); } while (0); | ||||
3258 | |||||
3259 | /* baseProtocols */ | ||||
3260 | ltyp = build_pointer_type (xref_tag (RECORD_TYPE, | ||||
3261 | get_identifier (UTAG_V2_PROTOCOL_LIST)(__builtin_constant_p ("_protocol_list_t") ? get_identifier_with_length (("_protocol_list_t"), strlen ("_protocol_list_t")) : get_identifier ("_protocol_list_t")))); | ||||
3262 | if (baseProtocols) | ||||
3263 | expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, baseProtocols, 0)); | ||||
3264 | else | ||||
3265 | expr = convert (ltyp, null_pointer_nodeglobal_trees[TI_NULL_POINTER]); | ||||
3266 | CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, expr)do { constructor_elt _ce___ = {(tree) nullptr, expr}; vec_safe_push ((initlist), _ce___); } while (0); | ||||
3267 | |||||
3268 | /* ivars */ | ||||
3269 | ltyp = objc_v2_ivar_list_ptrobjc_v2_global_trees[OCTI_V2_IVAR_LIST_TEMPL]; | ||||
3270 | if (ivars) | ||||
3271 | expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, ivars, 0)); | ||||
3272 | else | ||||
3273 | expr = convert (ltyp, null_pointer_nodeglobal_trees[TI_NULL_POINTER]); | ||||
3274 | CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, expr)do { constructor_elt _ce___ = {(tree) nullptr, expr}; vec_safe_push ((initlist), _ce___); } while (0); | ||||
3275 | |||||
3276 | /* TODO: We don't yet have the weak/strong stuff... */ | ||||
3277 | /* weakIvarLayout */ | ||||
3278 | CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE,do { constructor_elt _ce___ = {(tree) nullptr, convert (unsigned_char_star , global_trees[TI_NULL_POINTER])}; vec_safe_push ((initlist), _ce___); } while (0) | ||||
3279 | convert (unsigned_char_star, null_pointer_node))do { constructor_elt _ce___ = {(tree) nullptr, convert (unsigned_char_star , global_trees[TI_NULL_POINTER])}; vec_safe_push ((initlist), _ce___); } while (0); | ||||
3280 | |||||
3281 | /* property list */ | ||||
3282 | ltyp = objc_prop_list_ptrobjc_global_trees[OCTI_V1_PROP_LIST_TEMPL]; | ||||
3283 | if (property_list) | ||||
3284 | expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, property_list, 0)); | ||||
3285 | else | ||||
3286 | expr = convert (ltyp, null_pointer_nodeglobal_trees[TI_NULL_POINTER]); | ||||
3287 | CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, expr)do { constructor_elt _ce___ = {(tree) nullptr, expr}; vec_safe_push ((initlist), _ce___); } while (0); | ||||
3288 | return objc_build_constructor (type, initlist); | ||||
3289 | } | ||||
3290 | |||||
3291 | static GTY (()) vec<ident_data_tuple, va_gc> *ehtype_list; | ||||
3292 | |||||
3293 | /* Record a name as needing a catcher. */ | ||||
3294 | static void | ||||
3295 | objc_v2_add_to_ehtype_list (tree name) | ||||
3296 | { | ||||
3297 | ident_data_tuple e; | ||||
3298 | if (ehtype_list) | ||||
3299 | { | ||||
3300 | int count = 0; | ||||
3301 | ident_data_tuple *ref; | ||||
3302 | |||||
3303 | FOR_EACH_VEC_ELT (*ehtype_list, count, ref)for (count = 0; (*ehtype_list).iterate ((count), &(ref)); ++(count)) | ||||
3304 | if (ref->ident == name) | ||||
3305 | return; /* Already entered. */ | ||||
3306 | } | ||||
3307 | else | ||||
3308 | /* Arbitrary initial count. */ | ||||
3309 | vec_alloc (ehtype_list, 8); | ||||
3310 | |||||
3311 | /* Not found, or new list. */ | ||||
3312 | e.ident = name; | ||||
3313 | e.data = NULL_TREE(tree) nullptr; | ||||
3314 | vec_safe_push (ehtype_list, e); | ||||
3315 | } | ||||
3316 | |||||
3317 | static void | ||||
3318 | generate_v2_class_structs (struct imp_entry *impent) | ||||
3319 | { | ||||
3320 | tree decl, name_expr, initlist, protocol_decl, metaclass_decl, class_decl; | ||||
3321 | tree field, firstIvar, chain; | ||||
3322 | tree class_superclass_expr, metaclass_superclass_expr, props; | ||||
3323 | /* TODO: figure out how to compute this. */ | ||||
3324 | tree ivarLayout = NULL_TREE(tree) nullptr; | ||||
3325 | tree my_super_id = NULL_TREE(tree) nullptr, root_expr = NULL_TREE(tree) nullptr; | ||||
3326 | tree inst_methods = NULL_TREE(tree) nullptr, class_methods = NULL_TREE(tree) nullptr; | ||||
3327 | tree inst_ivars = NULL_TREE(tree) nullptr, class_ivars = NULL_TREE(tree) nullptr; | ||||
3328 | location_t loc; | ||||
3329 | char buf[BUFSIZE1024]; | ||||
3330 | unsigned int instanceStart, instanceSize; | ||||
3331 | unsigned int flags = 0x01; /* RO_META */ | ||||
3332 | int cls_flags = impent->has_cxx_cdtors ? OBJC2_CLS_HAS_CXX_STRUCTORS0x0004L | ||||
3333 | : 0 ; | ||||
3334 | |||||
3335 | class_decl = impent->class_decl; | ||||
3336 | metaclass_decl = impent->meta_decl; | ||||
3337 | loc = DECL_SOURCE_LOCATION (class_decl)((contains_struct_check ((class_decl), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3337, __FUNCTION__))->decl_minimal.locus); | ||||
3338 | |||||
3339 | DECL_EXTERNAL (class_decl)((contains_struct_check ((class_decl), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3339, __FUNCTION__))->decl_common.decl_flag_1) = DECL_EXTERNAL (metaclass_decl)((contains_struct_check ((metaclass_decl), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3339, __FUNCTION__))->decl_common.decl_flag_1) = 0; | ||||
3340 | TREE_PUBLIC (class_decl)((class_decl)->base.public_flag) = TREE_PUBLIC (metaclass_decl)((metaclass_decl)->base.public_flag) = 1; | ||||
3341 | #ifdef OBJCPLUS | ||||
3342 | gcc_assert (!CP_DECL_CONTEXT (class_decl) || CP_DECL_CONTEXT (class_decl) == global_namespace)((void)(!(!CP_DECL_CONTEXT (class_decl) || CP_DECL_CONTEXT (class_decl ) == global_namespace) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3342, __FUNCTION__), 0 : 0)); | ||||
3343 | gcc_assert (!CP_DECL_CONTEXT (metaclass_decl) || CP_DECL_CONTEXT (metaclass_decl) == global_namespace)((void)(!(!CP_DECL_CONTEXT (metaclass_decl) || CP_DECL_CONTEXT (metaclass_decl) == global_namespace) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3343, __FUNCTION__), 0 : 0)); | ||||
3344 | #endif | ||||
3345 | |||||
3346 | /* Generation of data for meta class. */ | ||||
3347 | my_super_id = CLASS_SUPER_NAME (impent->imp_template)(((tree_class_check ((impent->imp_template), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3347, __FUNCTION__))->type_common.context)); | ||||
3348 | if (my_super_id) | ||||
3349 | { | ||||
3350 | /* Compute reference to root's name. For a meta class, "isa" is | ||||
3351 | a reference to the root class name. */ | ||||
3352 | tree my_root_id = my_super_id; | ||||
3353 | tree my_root_int, interface; | ||||
3354 | do | ||||
3355 | { | ||||
3356 | my_root_int = lookup_interface (my_root_id); | ||||
3357 | |||||
3358 | if (my_root_int && CLASS_SUPER_NAME (my_root_int)(((tree_class_check ((my_root_int), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3358, __FUNCTION__))->type_common.context))) | ||||
3359 | my_root_id = CLASS_SUPER_NAME (my_root_int)(((tree_class_check ((my_root_int), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3359, __FUNCTION__))->type_common.context)); | ||||
3360 | else | ||||
3361 | break; | ||||
3362 | } | ||||
3363 | while (1); | ||||
3364 | |||||
3365 | /* {extern} struct class_t OBJC_METACLASS_$_<my_root_int> | ||||
3366 | create extern if not already declared. */ | ||||
3367 | snprintf (buf, BUFSIZE1024, "OBJC_METACLASS_$_%s", | ||||
3368 | IDENTIFIER_POINTER (CLASS_NAME (my_root_int))((const char *) (tree_check (((((tree_class_check ((my_root_int ), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3368, __FUNCTION__))->type_common.name))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3368, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
3369 | root_expr = create_extern_decl (objc_v2_class_templateobjc_v2_global_trees[OCTI_V2_CLS_TEMPL], buf); | ||||
3370 | root_expr = build_fold_addr_expr (root_expr)build_fold_addr_expr_loc (((location_t) 0), (root_expr)); | ||||
3371 | |||||
3372 | /* Install class `isa' and `super' pointers at runtime. */ | ||||
3373 | interface = lookup_interface (my_super_id); | ||||
3374 | gcc_assert (interface)((void)(!(interface) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3374, __FUNCTION__), 0 : 0)); | ||||
3375 | /* Similarly, for OBJC_CLASS_$_<interface>... */ | ||||
3376 | snprintf (buf, BUFSIZE1024, "OBJC_CLASS_$_%s", | ||||
3377 | IDENTIFIER_POINTER (CLASS_NAME (interface))((const char *) (tree_check (((((tree_class_check ((interface ), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3377, __FUNCTION__))->type_common.name))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3377, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
3378 | class_superclass_expr = create_extern_decl (objc_v2_class_templateobjc_v2_global_trees[OCTI_V2_CLS_TEMPL], buf); | ||||
3379 | class_superclass_expr = build_fold_addr_expr (class_superclass_expr)build_fold_addr_expr_loc (((location_t) 0), (class_superclass_expr )); | ||||
3380 | /* ... and for OBJC_METACLASS_$_<interface>. */ | ||||
3381 | snprintf (buf, BUFSIZE1024, "OBJC_METACLASS_$_%s", | ||||
3382 | IDENTIFIER_POINTER (CLASS_NAME (interface))((const char *) (tree_check (((((tree_class_check ((interface ), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3382, __FUNCTION__))->type_common.name))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3382, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
3383 | metaclass_superclass_expr = create_extern_decl (objc_v2_class_templateobjc_v2_global_trees[OCTI_V2_CLS_TEMPL], buf); | ||||
3384 | metaclass_superclass_expr = build_fold_addr_expr (metaclass_superclass_expr)build_fold_addr_expr_loc (((location_t) 0), (metaclass_superclass_expr )); | ||||
3385 | } | ||||
3386 | else | ||||
3387 | { | ||||
3388 | /* Root class. */ | ||||
3389 | root_expr = build_unary_op (loc, ADDR_EXPR, metaclass_decl, 0); | ||||
3390 | metaclass_superclass_expr = build_unary_op (loc, ADDR_EXPR, class_decl, 0); | ||||
3391 | class_superclass_expr = build_int_cst (NULL_TREE(tree) nullptr, 0); | ||||
3392 | flags |= 0x02; /* RO_ROOT: it is also a root meta class. */ | ||||
3393 | } | ||||
3394 | |||||
3395 | if (CLASS_PROTOCOL_LIST (impent->imp_template)(*((const_cast<tree *> (tree_vec_elt_check ((((tree_class_check ((impent->imp_template), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3395, __FUNCTION__))->type_non_common.lang_1)), (4), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3395, __FUNCTION__)))))) | ||||
3396 | { | ||||
3397 | generate_protocol_references (CLASS_PROTOCOL_LIST (impent->imp_template)(*((const_cast<tree *> (tree_vec_elt_check ((((tree_class_check ((impent->imp_template), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3397, __FUNCTION__))->type_non_common.lang_1)), (4), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3397, __FUNCTION__)))))); | ||||
3398 | protocol_decl = generate_v2_protocol_list (impent->imp_template, | ||||
3399 | impent->imp_context); | ||||
3400 | } | ||||
3401 | else | ||||
3402 | protocol_decl = 0; | ||||
3403 | |||||
3404 | name_expr = add_objc_string (CLASS_NAME (impent->imp_template)(((tree_class_check ((impent->imp_template), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3404, __FUNCTION__))->type_common.name)), | ||||
3405 | class_names); | ||||
3406 | |||||
3407 | if (CLASS_CLS_METHODS (impent->imp_context)(((tree_class_check ((impent->imp_context), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3407, __FUNCTION__))->type_non_common.maxval))) | ||||
3408 | { | ||||
3409 | snprintf (buf, BUFSIZE1024, "_OBJC_ClassMethods_%s", | ||||
3410 | IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context))((const char *) (tree_check (((((tree_class_check ((impent-> imp_context), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3410, __FUNCTION__))->type_common.name))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3410, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
3411 | class_methods = | ||||
3412 | generate_v2_dispatch_table (CLASS_CLS_METHODS (impent->imp_context)(((tree_class_check ((impent->imp_context), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3412, __FUNCTION__))->type_non_common.maxval)), | ||||
3413 | buf, meta_clac_methobjc_rt_trees[OCTI_RT_META_CLASS_CLS_METH]); | ||||
3414 | } | ||||
3415 | |||||
3416 | instanceStart = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (objc_v2_class_template))((unsigned long) (*tree_int_cst_elt_check ((((tree_class_check ((objc_v2_global_trees[OCTI_V2_CLS_TEMPL]), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3416, __FUNCTION__))->type_common.size_unit)), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3416, __FUNCTION__))); | ||||
3417 | |||||
3418 | /* Currently there are no class ivars and generation of class | ||||
3419 | variables for the root of the inheritance has been removed. It | ||||
3420 | causes multiple defines if there are two root classes in the | ||||
3421 | link, because each will define its own identically-named offset | ||||
3422 | variable. */ | ||||
3423 | |||||
3424 | class_ivars = NULL_TREE(tree) nullptr; | ||||
3425 | /* TODO: Add total size of class variables when implemented. */ | ||||
3426 | instanceSize = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (objc_v2_class_template))((unsigned long) (*tree_int_cst_elt_check ((((tree_class_check ((objc_v2_global_trees[OCTI_V2_CLS_TEMPL]), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3426, __FUNCTION__))->type_common.size_unit)), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3426, __FUNCTION__))); | ||||
3427 | |||||
3428 | /* So now build the META CLASS structs. */ | ||||
3429 | /* static struct class_ro_t _OBJC_METACLASS_Foo = { ... }; */ | ||||
3430 | |||||
3431 | decl = start_var_decl (objc_v2_class_ro_templateobjc_v2_global_trees[OCTI_V2_CLS_RO_TEMPL], | ||||
3432 | newabi_append_ro (IDENTIFIER_POINTER((const char *) (tree_check ((((contains_struct_check ((metaclass_decl ), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3433, __FUNCTION__))->decl_minimal.name)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3433, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ) | ||||
3433 | (DECL_NAME (metaclass_decl))((const char *) (tree_check ((((contains_struct_check ((metaclass_decl ), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3433, __FUNCTION__))->decl_minimal.name)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3433, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ))); | ||||
3434 | |||||
3435 | /* TODO: ivarLayout needs t be built. */ | ||||
3436 | initlist = | ||||
3437 | build_v2_class_ro_t_initializer (TREE_TYPE (decl)((contains_struct_check ((decl), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3437, __FUNCTION__))->typed.type), name_expr, | ||||
3438 | (flags | cls_flags), instanceStart, | ||||
3439 | instanceSize, ivarLayout, | ||||
3440 | class_methods, protocol_decl, | ||||
3441 | class_ivars, NULL_TREE(tree) nullptr); | ||||
3442 | /* The ROs sit in the default const section. */ | ||||
3443 | OBJCMETA (decl, objc_meta, meta_base)if (objc_rt_trees[OCTI_RT_OBJC_META]) ((contains_struct_check ((decl), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3443, __FUNCTION__))->decl_common.attributes) = build_tree_list ((objc_rt_trees[OCTI_RT_OBJC_META]), (objc_rt_trees[OCTI_RT_META_BASE ]));; | ||||
3444 | finish_var_decl (decl, initlist); | ||||
3445 | |||||
3446 | /* static struct class_t _OBJC_METACLASS_Foo = { ... }; */ | ||||
3447 | initlist = | ||||
3448 | build_v2_class_t_initializer (TREE_TYPE (metaclass_decl)((contains_struct_check ((metaclass_decl), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3448, __FUNCTION__))->typed.type), | ||||
3449 | root_expr, | ||||
3450 | metaclass_superclass_expr, | ||||
3451 | build_fold_addr_expr (decl)build_fold_addr_expr_loc (((location_t) 0), (decl)), | ||||
3452 | build_fold_addr_expr (UOBJC_V2_CACHE_decl)build_fold_addr_expr_loc (((location_t) 0), (objc_v2_global_trees [OCTI_V2_CACHE_DECL])), | ||||
3453 | build_fold_addr_expr (UOBJC_V2_VTABLE_decl)build_fold_addr_expr_loc (((location_t) 0), (objc_v2_global_trees [OCTI_V2_VTABLE_DECL]))); | ||||
3454 | /* The class section attributes are set when they are created. */ | ||||
3455 | finish_var_decl (metaclass_decl, initlist); | ||||
3456 | impent->meta_decl = metaclass_decl; | ||||
3457 | |||||
3458 | /* So now build the CLASS structs. */ | ||||
3459 | |||||
3460 | flags = 0x0; /* ... */ | ||||
3461 | if (!my_super_id) | ||||
3462 | flags |= 0x02; /* RO_ROOT: this is a root class */ | ||||
3463 | |||||
3464 | if (DECL_VISIBILITY (class_decl)((contains_struct_check ((class_decl), (TS_DECL_WITH_VIS), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3464, __FUNCTION__))->decl_with_vis.visibility) == VISIBILITY_HIDDEN) | ||||
3465 | flags |= 0x10; /* RO_HIDDEN, OBJC2_CLS_HIDDEN; */ | ||||
3466 | |||||
3467 | if (objc2_objc_exception_attr (impent->imp_template)) | ||||
3468 | flags |= 0x20; /* RO_EXCEPTION */ | ||||
3469 | |||||
3470 | if (CLASS_NST_METHODS (impent->imp_context)(((tree_class_check ((impent->imp_context), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3470, __FUNCTION__))->type_non_common.minval))) | ||||
3471 | { | ||||
3472 | snprintf (buf, BUFSIZE1024, "_OBJC_InstanceMethods_%s", | ||||
3473 | IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context))((const char *) (tree_check (((((tree_class_check ((impent-> imp_context), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3473, __FUNCTION__))->type_common.name))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3473, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
3474 | inst_methods = | ||||
3475 | generate_v2_dispatch_table (CLASS_NST_METHODS (impent->imp_context)(((tree_class_check ((impent->imp_context), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3475, __FUNCTION__))->type_non_common.minval)), | ||||
3476 | buf, meta_clai_methobjc_rt_trees[OCTI_RT_META_CLASS_NST_METH]); | ||||
3477 | } | ||||
3478 | |||||
3479 | /* Sort out the ivars before we try to compute the class sizes. */ | ||||
3480 | if ((chain = CLASS_IVARS (impent->imp_template)(*((const_cast<tree *> (tree_vec_elt_check ((((tree_class_check ((impent->imp_template), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3480, __FUNCTION__))->type_non_common.lang_1)), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3480, __FUNCTION__))))))) | ||||
3481 | { | ||||
3482 | snprintf (buf, BUFSIZE1024, "_OBJC_InstanceIvars_%s", | ||||
3483 | IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context))((const char *) (tree_check (((((tree_class_check ((impent-> imp_context), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3483, __FUNCTION__))->type_common.name))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3483, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
3484 | inst_ivars = generate_v2_ivars_list (chain, buf, meta_clai_varsobjc_rt_trees[OCTI_RT_META_CLASS_NST_VARS], | ||||
3485 | impent->imp_template); | ||||
3486 | } | ||||
3487 | |||||
3488 | /* Compute instanceStart. */ | ||||
3489 | gcc_assert (CLASS_STATIC_TEMPLATE (impent->imp_template))((void)(!((*((const_cast<tree *> (tree_vec_elt_check (( ((tree_class_check ((impent->imp_template), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3489, __FUNCTION__))->type_non_common.lang_1)), (2), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3489, __FUNCTION__)))))) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3489, __FUNCTION__), 0 : 0)); | ||||
3490 | field = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (impent->imp_template))((tree_check3 (((*((const_cast<tree *> (tree_vec_elt_check ((((tree_class_check ((impent->imp_template), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3490, __FUNCTION__))->type_non_common.lang_1)), (2), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3490, __FUNCTION__)))))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3490, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.values); | ||||
3491 | if (my_super_id && field && TREE_CHAIN (field)((contains_struct_check ((field), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3491, __FUNCTION__))->common.chain)) | ||||
3492 | field = TREE_CHAIN (field)((contains_struct_check ((field), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3492, __FUNCTION__))->common.chain); | ||||
3493 | |||||
3494 | firstIvar = field; | ||||
3495 | |||||
3496 | while (firstIvar && TREE_CODE (firstIvar)((enum tree_code) (firstIvar)->base.code) != FIELD_DECL) | ||||
3497 | firstIvar = TREE_CHAIN (firstIvar)((contains_struct_check ((firstIvar), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3497, __FUNCTION__))->common.chain); | ||||
3498 | |||||
3499 | gcc_assert (inst_ivars? (firstIvar != NULL_TREE): true)((void)(!(inst_ivars? (firstIvar != (tree) nullptr): true) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3499, __FUNCTION__), 0 : 0)); | ||||
3500 | |||||
3501 | /* Compute instanceSize. */ | ||||
3502 | while (field && TREE_CHAIN (field)((contains_struct_check ((field), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3502, __FUNCTION__))->common.chain) | ||||
3503 | && TREE_CODE (TREE_CHAIN (field))((enum tree_code) (((contains_struct_check ((field), (TS_COMMON ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3503, __FUNCTION__))->common.chain))->base.code) == FIELD_DECL) | ||||
3504 | field = TREE_CHAIN (field)((contains_struct_check ((field), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3504, __FUNCTION__))->common.chain); | ||||
3505 | |||||
3506 | if (field && TREE_CODE (field)((enum tree_code) (field)->base.code) == FIELD_DECL) | ||||
3507 | instanceSize = int_byte_position (field) * BITS_PER_UNIT(8) | ||||
3508 | + tree_to_shwi (DECL_SIZE (field)((contains_struct_check ((field), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3508, __FUNCTION__))->decl_common.size)); | ||||
3509 | else | ||||
3510 | instanceSize = 0; | ||||
3511 | instanceSize /= BITS_PER_UNIT(8); | ||||
3512 | |||||
3513 | props = generate_v2_property_table (NULL_TREE(tree) nullptr, impent->imp_context); | ||||
3514 | |||||
3515 | /* If the class has no ivars, instanceStart should be set to the | ||||
3516 | superclass's instanceSize. */ | ||||
3517 | instanceStart = | ||||
3518 | (inst_ivars != NULL_TREE(tree) nullptr) ? (unsigned) int_byte_position (firstIvar) | ||||
3519 | : instanceSize; | ||||
3520 | |||||
3521 | /* static struct class_ro_t _OBJC_CLASS_Foo = { ... }; */ | ||||
3522 | decl = start_var_decl (objc_v2_class_ro_templateobjc_v2_global_trees[OCTI_V2_CLS_RO_TEMPL], | ||||
3523 | newabi_append_ro (IDENTIFIER_POINTER((const char *) (tree_check ((((contains_struct_check ((class_decl ), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3524, __FUNCTION__))->decl_minimal.name)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3524, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ) | ||||
3524 | (DECL_NAME (class_decl))((const char *) (tree_check ((((contains_struct_check ((class_decl ), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3524, __FUNCTION__))->decl_minimal.name)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3524, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ))); | ||||
3525 | |||||
3526 | initlist = | ||||
3527 | build_v2_class_ro_t_initializer (TREE_TYPE (decl)((contains_struct_check ((decl), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3527, __FUNCTION__))->typed.type), name_expr, | ||||
3528 | (flags | cls_flags), instanceStart, | ||||
3529 | instanceSize, ivarLayout, | ||||
3530 | inst_methods, protocol_decl, | ||||
3531 | inst_ivars, props); | ||||
3532 | /* The ROs sit in the default const section. */ | ||||
3533 | OBJCMETA (decl, objc_meta, meta_base)if (objc_rt_trees[OCTI_RT_OBJC_META]) ((contains_struct_check ((decl), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3533, __FUNCTION__))->decl_common.attributes) = build_tree_list ((objc_rt_trees[OCTI_RT_OBJC_META]), (objc_rt_trees[OCTI_RT_META_BASE ]));; | ||||
3534 | finish_var_decl (decl, initlist); | ||||
3535 | |||||
3536 | /* static struct class_t _OBJC_CLASS_Foo = { ... }; */ | ||||
3537 | initlist = build_v2_class_t_initializer (TREE_TYPE (class_decl)((contains_struct_check ((class_decl), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3537, __FUNCTION__))->typed.type), | ||||
3538 | build_fold_addr_expr (metaclass_decl)build_fold_addr_expr_loc (((location_t) 0), (metaclass_decl)), | ||||
3539 | class_superclass_expr, | ||||
3540 | build_fold_addr_expr (decl)build_fold_addr_expr_loc (((location_t) 0), (decl)), | ||||
3541 | build_fold_addr_expr (UOBJC_V2_CACHE_decl)build_fold_addr_expr_loc (((location_t) 0), (objc_v2_global_trees [OCTI_V2_CACHE_DECL])), | ||||
3542 | build_fold_addr_expr (UOBJC_V2_VTABLE_decl)build_fold_addr_expr_loc (((location_t) 0), (objc_v2_global_trees [OCTI_V2_VTABLE_DECL]))); | ||||
3543 | |||||
3544 | /* The class section attributes are set when they are created. */ | ||||
3545 | finish_var_decl (class_decl, initlist); | ||||
3546 | impent->class_decl = class_decl; | ||||
3547 | |||||
3548 | objc_v2_add_to_class_list (class_decl); | ||||
3549 | if (has_load_impl (CLASS_CLS_METHODS (impent->imp_context)(((tree_class_check ((impent->imp_context), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3549, __FUNCTION__))->type_non_common.maxval)))) | ||||
3550 | objc_v2_add_to_nonlazy_class_list (class_decl); | ||||
3551 | |||||
3552 | if (flags & 0x20) /* RO_EXCEPTION */ | ||||
3553 | objc_v2_add_to_ehtype_list (CLASS_NAME (impent->imp_template)(((tree_class_check ((impent->imp_template), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3553, __FUNCTION__))->type_common.name))); | ||||
3554 | } | ||||
3555 | |||||
3556 | /* This routine outputs the (ivar_reference_offset, offset) | ||||
3557 | tuples. */ | ||||
3558 | |||||
3559 | static void | ||||
3560 | build_v2_ivar_offset_ref_table (void) | ||||
3561 | { | ||||
3562 | int count; | ||||
3563 | ivarref_entry *ref; | ||||
3564 | |||||
3565 | if (!vec_safe_length (ivar_offset_refs)) | ||||
3566 | return; | ||||
3567 | |||||
3568 | FOR_EACH_VEC_ELT (*ivar_offset_refs, count, ref)for (count = 0; (*ivar_offset_refs).iterate ((count), &(ref )); ++(count)) | ||||
3569 | finish_var_decl (ref->decl, ref->offset); | ||||
3570 | } | ||||
3571 | |||||
3572 | static void | ||||
3573 | objc_generate_v2_next_metadata (void) | ||||
3574 | { | ||||
3575 | struct imp_entry *impent; | ||||
3576 | |||||
3577 | /* FIXME: Make sure that we generate no metadata if there is nothing | ||||
3578 | to put into it. */ | ||||
3579 | |||||
3580 | gcc_assert (!objc_static_instances)((void)(!(!objc_global_trees[OCTI_STATIC_NST]) ? fancy_abort ( "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3580, __FUNCTION__), 0 : 0)); /* Not for NeXT */ | ||||
3581 | |||||
3582 | build_metadata_templates (); | ||||
3583 | |||||
3584 | for (impent = imp_list; impent; impent = impent->next) | ||||
3585 | { | ||||
3586 | /* If -gen-decls is present, Dump the @interface of each class. | ||||
3587 | TODO: Dump the classes in the order they were found, rather | ||||
3588 | than in reverse order as we are doing now. */ | ||||
3589 | if (flag_gen_declarationglobal_options.x_flag_gen_declaration) | ||||
3590 | dump_interface (gen_declaration_file, impent->imp_context); | ||||
3591 | |||||
3592 | /* all of the following reference the string pool... */ | ||||
3593 | if (TREE_CODE (impent->imp_context)((enum tree_code) (impent->imp_context)->base.code) == CLASS_IMPLEMENTATION_TYPE) | ||||
3594 | generate_v2_class_structs (impent); | ||||
3595 | else | ||||
3596 | generate_v2_category (impent); | ||||
3597 | } | ||||
3598 | |||||
3599 | build_next_selector_translation_table (); | ||||
3600 | build_v2_message_ref_translation_table (); | ||||
3601 | |||||
3602 | /* This will add "Protocol" to the class refs. */ | ||||
3603 | generate_v2_protocols (); | ||||
3604 | |||||
3605 | build_v2_classrefs_table (); | ||||
3606 | build_v2_super_classrefs_table (/*metaclass= */false); | ||||
3607 | build_v2_super_classrefs_table (/*metaclass= */true); | ||||
3608 | |||||
3609 | build_v2_ivar_offset_ref_table (); | ||||
3610 | |||||
3611 | build_v2_protocol_list_translation_table (); | ||||
3612 | build_v2_protocol_list_address_table (); | ||||
3613 | |||||
3614 | build_v2_address_table (class_list, "_OBJC_ClassList$", | ||||
3615 | meta_label_classlistobjc_rt_trees[OCTI_RT_META_CLSLST_LAB]); | ||||
3616 | build_v2_address_table (category_list, "_OBJC_CategoryList$", | ||||
3617 | meta_label_categorylistobjc_rt_trees[OCTI_RT_META_LAB_CAT]); | ||||
3618 | build_v2_address_table (nonlazy_class_list, "_OBJC_NonLazyClassList$", | ||||
3619 | meta_label_nonlazy_classlistobjc_rt_trees[OCTI_RT_META_CLSLST_NLZY_LAB]); | ||||
3620 | build_v2_address_table (nonlazy_category_list, "_OBJC_NonLazyCategoryList$", | ||||
3621 | meta_label_nonlazy_categorylistobjc_rt_trees[OCTI_RT_META_LAB_NLZY_CAT]); | ||||
3622 | |||||
3623 | /* Generate catch objects for eh, if any are needed. */ | ||||
3624 | build_v2_eh_catch_objects (); | ||||
3625 | |||||
3626 | /* Emit the string table last. */ | ||||
3627 | generate_strings (); | ||||
3628 | } | ||||
3629 | |||||
3630 | /* NOTE --- Output NeXT V2 Exceptions --- */ | ||||
3631 | |||||
3632 | static GTY(()) tree objc_v2_ehtype_template; | ||||
3633 | static GTY(()) tree next_v2_ehvtable_decl; | ||||
3634 | static GTY(()) tree next_v2_EHTYPE_id_decl; | ||||
3635 | |||||
3636 | static void | ||||
3637 | build_v2_ehtype_template (void) | ||||
3638 | { | ||||
3639 | tree decls, *chain = NULLnullptr; | ||||
3640 | objc_v2_ehtype_template = objc_start_struct (get_identifier (UTAG_V2_EH_TYPE)(__builtin_constant_p ("_objc_ehtype_t") ? get_identifier_with_length (("_objc_ehtype_t"), strlen ("_objc_ehtype_t")) : get_identifier ("_objc_ehtype_t"))); | ||||
3641 | |||||
3642 | /* void *_objc_ehtype_vtable; */ | ||||
3643 | decls = add_field_decl (ptr_type_nodeglobal_trees[TI_PTR_TYPE], "_objc_ehtype_vtable_ptr", &chain); | ||||
3644 | |||||
3645 | /* const char *className; */ | ||||
3646 | add_field_decl (string_type_nodec_global_trees[CTI_STRING_TYPE], "className", &chain); | ||||
3647 | |||||
3648 | /* struct class_t *const cls; */ | ||||
3649 | add_field_decl (build_pointer_type (objc_v2_class_templateobjc_v2_global_trees[OCTI_V2_CLS_TEMPL]), "cls", &chain); | ||||
3650 | |||||
3651 | objc_finish_struct (objc_v2_ehtype_template, decls); | ||||
3652 | } | ||||
3653 | |||||
3654 | /* Template for the Objective-C family typeinfo type for ABI=2. This | ||||
3655 | starts off the same as the gxx/cxx eh typeinfo. | ||||
3656 | |||||
3657 | struct _objc_ehtype_t | ||||
3658 | { | ||||
3659 | void *_objc_ehtype_vtable_ptr; - as per c++ | ||||
3660 | const char *className; - as per c++ | ||||
3661 | struct class_t *const cls; | ||||
3662 | } | ||||
3663 | */ | ||||
3664 | |||||
3665 | /* This routine builds initializer list for object of type struct _objc_ehtype_t. | ||||
3666 | */ | ||||
3667 | |||||
3668 | static tree | ||||
3669 | objc2_build_ehtype_initializer (tree name, tree cls) | ||||
3670 | { | ||||
3671 | vec<constructor_elt, va_gc> *initlist = NULLnullptr; | ||||
3672 | tree addr, offs; | ||||
3673 | |||||
3674 | /* This is done the same way as c++, missing the two first entries | ||||
3675 | in the parent vtable. NOTE: there is a fix-me in the Apple/NeXT | ||||
3676 | runtime source about this so, perhaps, this will change at some | ||||
3677 | point. */ | ||||
3678 | /* _objc_ehtype_vtable + 2*sizeof(void*) */ | ||||
3679 | if (!next_v2_ehvtable_decl) | ||||
3680 | { | ||||
3681 | next_v2_ehvtable_decl = | ||||
3682 | start_var_decl (ptr_type_nodeglobal_trees[TI_PTR_TYPE], TAG_NEXT_EHVTABLE_NAME"objc_ehtype_vtable"); | ||||
3683 | TREE_STATIC (next_v2_ehvtable_decl)((next_v2_ehvtable_decl)->base.static_flag) = 0; | ||||
3684 | DECL_EXTERNAL (next_v2_ehvtable_decl)((contains_struct_check ((next_v2_ehvtable_decl), (TS_DECL_COMMON ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3684, __FUNCTION__))->decl_common.decl_flag_1) = 1; | ||||
3685 | TREE_PUBLIC (next_v2_ehvtable_decl)((next_v2_ehvtable_decl)->base.public_flag) = 1; | ||||
3686 | } | ||||
3687 | addr = build_fold_addr_expr_with_type (next_v2_ehvtable_decl, ptr_type_node)build_fold_addr_expr_with_type_loc (((location_t) 0), (next_v2_ehvtable_decl ), global_trees[TI_PTR_TYPE]); | ||||
3688 | offs = size_int (2 * int_cst_value (TYPE_SIZE_UNIT (ptr_type_node)))size_int_kind (2 * int_cst_value (((tree_class_check ((global_trees [TI_PTR_TYPE]), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3688, __FUNCTION__))->type_common.size_unit)), stk_sizetype ); | ||||
3689 | addr = fold_build_pointer_plus (addr, offs)fold_build_pointer_plus_loc (((location_t) 0), addr, offs); | ||||
3690 | |||||
3691 | CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, addr)do { constructor_elt _ce___ = {(tree) nullptr, addr}; vec_safe_push ((initlist), _ce___); } while (0); | ||||
3692 | |||||
3693 | /* className */ | ||||
3694 | CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, name)do { constructor_elt _ce___ = {(tree) nullptr, name}; vec_safe_push ((initlist), _ce___); } while (0); | ||||
3695 | |||||
3696 | /* cls */ | ||||
3697 | CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, cls)do { constructor_elt _ce___ = {(tree) nullptr, cls}; vec_safe_push ((initlist), _ce___); } while (0); | ||||
3698 | |||||
3699 | return objc_build_constructor (objc_v2_ehtype_template, initlist); | ||||
3700 | } | ||||
3701 | |||||
3702 | static tree | ||||
3703 | build_ehtype (tree name, const char *eh_name, bool weak) | ||||
3704 | { | ||||
3705 | tree name_expr, class_name_expr, ehtype_decl, inits; | ||||
3706 | |||||
3707 | name_expr = add_objc_string (name, class_names); | ||||
3708 | /* Extern ref. for the class. ??? Maybe we can look this up | ||||
3709 | somewhere. */ | ||||
3710 | class_name_expr = | ||||
3711 | create_extern_decl (objc_v2_class_templateobjc_v2_global_trees[OCTI_V2_CLS_TEMPL], | ||||
3712 | objc_build_internal_classname (name, false)); | ||||
3713 | class_name_expr = build_fold_addr_expr (class_name_expr)build_fold_addr_expr_loc (((location_t) 0), (class_name_expr) ); | ||||
3714 | ehtype_decl = create_global_decl (objc_v2_ehtype_template, eh_name); | ||||
3715 | if (weak) | ||||
3716 | DECL_WEAK (ehtype_decl)((contains_struct_check ((ehtype_decl), (TS_DECL_WITH_VIS), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3716, __FUNCTION__))->decl_with_vis.weak_flag) = 1; | ||||
3717 | inits = objc2_build_ehtype_initializer (name_expr, class_name_expr); | ||||
3718 | OBJCMETA (ehtype_decl, objc_meta, meta_ehtype)if (objc_rt_trees[OCTI_RT_OBJC_META]) ((contains_struct_check ((ehtype_decl), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3718, __FUNCTION__))->decl_common.attributes) = build_tree_list ((objc_rt_trees[OCTI_RT_OBJC_META]), (objc_rt_trees[OCTI_RT_META_EHTYPE ]));; | ||||
3719 | finish_var_decl (ehtype_decl, inits); | ||||
3720 | return ehtype_decl; | ||||
3721 | } | ||||
3722 | |||||
3723 | /* This routine returns TRUE if CLS or any of its super classes has | ||||
3724 | __attribute__ ((objc_exception)). */ | ||||
3725 | |||||
3726 | static bool | ||||
3727 | objc2_objc_exception_attr (tree cls) | ||||
3728 | { | ||||
3729 | while (cls) | ||||
3730 | { | ||||
3731 | if (CLASS_HAS_EXCEPTION_ATTR (cls)(((tree_class_check ((cls), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3731, __FUNCTION__))->type_common.lang_flag_0))) | ||||
3732 | return true; | ||||
3733 | cls = lookup_interface (CLASS_SUPER_NAME (cls)(((tree_class_check ((cls), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3733, __FUNCTION__))->type_common.context))); | ||||
3734 | } | ||||
3735 | |||||
3736 | return false; | ||||
3737 | } | ||||
3738 | |||||
3739 | static bool | ||||
3740 | is_implemented (tree name) | ||||
3741 | { | ||||
3742 | struct imp_entry *t; | ||||
3743 | for (t = imp_list; t; t = t->next) | ||||
3744 | if (TREE_CODE (t->imp_context)((enum tree_code) (t->imp_context)->base.code) == CLASS_IMPLEMENTATION_TYPE | ||||
3745 | && CLASS_NAME (t->imp_template)(((tree_class_check ((t->imp_template), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3745, __FUNCTION__))->type_common.name)) == name) | ||||
3746 | return true; | ||||
3747 | |||||
3748 | return false; | ||||
3749 | } | ||||
3750 | |||||
3751 | /* We will build catch objects: | ||||
3752 | for any type implemented here. | ||||
3753 | for any type used in a catch that has no exception attribute. */ | ||||
3754 | static void build_v2_eh_catch_objects (void) | ||||
3755 | { | ||||
3756 | int count=0; | ||||
3757 | ident_data_tuple *ref; | ||||
3758 | |||||
3759 | if (!vec_safe_length (ehtype_list)) | ||||
3760 | return; | ||||
3761 | |||||
3762 | FOR_EACH_VEC_ELT (*ehtype_list, count, ref)for (count = 0; (*ehtype_list).iterate ((count), &(ref)); ++(count)) | ||||
3763 | { | ||||
3764 | char buf[BUFSIZE1024]; | ||||
3765 | bool impl = is_implemented (ref->ident); | ||||
3766 | bool excpt = objc2_objc_exception_attr (lookup_interface (ref->ident)); | ||||
3767 | snprintf (buf, BUFSIZE1024, "OBJC_EHTYPE_$_%s", IDENTIFIER_POINTER (ref->ident)((const char *) (tree_check ((ref->ident), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3767, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
3768 | if (!impl && excpt) | ||||
3769 | /* The User says this class has a catcher already. */ | ||||
3770 | ref->data = create_extern_decl (objc_v2_ehtype_template, buf); | ||||
3771 | else | ||||
3772 | /* Create a catcher, weak if it wasn't marked. */ | ||||
3773 | ref->data = build_ehtype (ref->ident, buf, !excpt); | ||||
3774 | } | ||||
3775 | } | ||||
3776 | |||||
3777 | static tree | ||||
3778 | lookup_ehtype_ref (tree id) | ||||
3779 | { | ||||
3780 | int count=0; | ||||
3781 | ident_data_tuple *ref; | ||||
3782 | |||||
3783 | if (!vec_safe_length (ehtype_list)) | ||||
3784 | return NULL_TREE(tree) nullptr; | ||||
3785 | |||||
3786 | FOR_EACH_VEC_ELT (*ehtype_list, count, ref)for (count = 0; (*ehtype_list).iterate ((count), &(ref)); ++(count)) | ||||
3787 | if (ref->ident == id) | ||||
3788 | return ref->data; | ||||
3789 | return NULL_TREE(tree) nullptr; | ||||
3790 | } | ||||
3791 | |||||
3792 | /* This hook, called via lang_eh_runtime_type, generates a runtime | ||||
3793 | object which is either the address of the 'OBJC_EHTYPE_$_class' | ||||
3794 | object or address of external OBJC_EHTYPE_id object. */ | ||||
3795 | static tree | ||||
3796 | next_runtime_02_eh_type (tree type) | ||||
3797 | { | ||||
3798 | tree t; | ||||
3799 | |||||
3800 | if (type == error_mark_nodeglobal_trees[TI_ERROR_MARK] | ||||
3801 | /*|| errorcount || sorrycount*/) | ||||
3802 | goto err_mark_in; | ||||
3803 | |||||
3804 | if (POINTER_TYPE_P (type)(((enum tree_code) (type)->base.code) == POINTER_TYPE || ( (enum tree_code) (type)->base.code) == REFERENCE_TYPE) && objc_is_object_id (TREE_TYPE (type))(((tree_class_check ((((contains_struct_check ((type), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3804, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3804, __FUNCTION__))->type_common.name) == objc_global_trees [OCTI_OBJ_ID])) | ||||
3805 | { | ||||
3806 | if (!next_v2_EHTYPE_id_decl) | ||||
3807 | { | ||||
3808 | /* This is provided by the Apple/NeXT libobjc.dylib so we | ||||
3809 | need only to reference it. */ | ||||
3810 | next_v2_EHTYPE_id_decl = | ||||
3811 | start_var_decl (objc_v2_ehtype_template, "OBJC_EHTYPE_id"); | ||||
3812 | DECL_EXTERNAL (next_v2_EHTYPE_id_decl)((contains_struct_check ((next_v2_EHTYPE_id_decl), (TS_DECL_COMMON ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3812, __FUNCTION__))->decl_common.decl_flag_1) = 1; | ||||
3813 | TREE_PUBLIC (next_v2_EHTYPE_id_decl)((next_v2_EHTYPE_id_decl)->base.public_flag) = 1; | ||||
3814 | TREE_STATIC (next_v2_EHTYPE_id_decl)((next_v2_EHTYPE_id_decl)->base.static_flag) = 0; | ||||
3815 | } | ||||
3816 | return build_fold_addr_expr (next_v2_EHTYPE_id_decl)build_fold_addr_expr_loc (((location_t) 0), (next_v2_EHTYPE_id_decl )); | ||||
3817 | } | ||||
3818 | |||||
3819 | if (!POINTER_TYPE_P (type)(((enum tree_code) (type)->base.code) == POINTER_TYPE || ( (enum tree_code) (type)->base.code) == REFERENCE_TYPE) || !TYPED_OBJECT (TREE_TYPE (type))(((enum tree_code) (((contains_struct_check ((type), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3819, __FUNCTION__))->typed.type))->base.code) == RECORD_TYPE && (((tree_class_check ((((contains_struct_check ((type ), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3819, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3819, __FUNCTION__))->type_with_lang_specific.lang_specific ) && ((tree_class_check ((((contains_struct_check ((type ), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3819, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3819, __FUNCTION__))->type_with_lang_specific.lang_specific )->objc_info) && (*((const_cast<tree *> (tree_vec_elt_check ((((tree_class_check ((((contains_struct_check ((type), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3819, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3819, __FUNCTION__))->type_with_lang_specific.lang_specific )->objc_info), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3819, __FUNCTION__))))))) | ||||
3820 | { | ||||
3821 | #ifdef OBJCPLUS | ||||
3822 | /* This routine is also called for c++'s catch clause; in which | ||||
3823 | case, we use c++'s typeinfo decl. */ | ||||
3824 | return build_eh_type_type (type); | ||||
3825 | #else | ||||
3826 | error ("non-objective-c type %qT cannot be caught", type); | ||||
3827 | goto err_mark_in; | ||||
3828 | #endif | ||||
3829 | } | ||||
3830 | else | ||||
3831 | t = OBJC_TYPE_NAME (TREE_TYPE (type))((tree_class_check ((((contains_struct_check ((type), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3831, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3831, __FUNCTION__))->type_common.name); | ||||
3832 | |||||
3833 | /* We have to build a reference to the OBJC_EHTYPE_<Class>. */ | ||||
3834 | t = lookup_ehtype_ref (t); | ||||
3835 | if (!t) | ||||
3836 | goto err_mark_in; | ||||
3837 | |||||
3838 | return build_fold_addr_expr (t)build_fold_addr_expr_loc (((location_t) 0), (t)); | ||||
3839 | |||||
3840 | err_mark_in: | ||||
3841 | return error_mark_nodeglobal_trees[TI_ERROR_MARK]; | ||||
3842 | } | ||||
3843 | |||||
3844 | static GTY(()) tree objc_eh_personality_decl; | ||||
3845 | |||||
3846 | static tree | ||||
3847 | objc_eh_personality (void) | ||||
3848 | { | ||||
3849 | if (!objc_eh_personality_decl) | ||||
3850 | objc_eh_personality_decl = build_personality_function ("objc"); | ||||
3851 | return objc_eh_personality_decl; | ||||
3852 | } | ||||
3853 | |||||
3854 | /* NOTE --- interfaces --- */ | ||||
3855 | |||||
3856 | static tree | ||||
3857 | build_throw_stmt (location_t loc, tree throw_expr, bool rethrown) | ||||
3858 | { | ||||
3859 | tree t; | ||||
3860 | if (rethrown) | ||||
3861 | /* We have a separate re-throw entry. */ | ||||
3862 | t = build_function_call_vec (loc, vNULL, objc_rethrow_exception_declobjc_v2_global_trees[OCTI_V2_RETHROW_DECL], | ||||
3863 | NULLnullptr, NULLnullptr); | ||||
3864 | else | ||||
3865 | { | ||||
3866 | /* Throw like the others... */ | ||||
3867 | vec<tree, va_gc> *parms; | ||||
3868 | vec_alloc (parms, 1); | ||||
3869 | parms->quick_push (throw_expr); | ||||
3870 | t = build_function_call_vec (loc, vNULL, objc_exception_throw_declobjc_global_trees[OCTI_EXCEPTION_THROW_DECL], | ||||
3871 | parms, 0); | ||||
3872 | vec_free (parms); | ||||
3873 | } | ||||
3874 | return add_stmt (t); | ||||
3875 | } | ||||
3876 | |||||
3877 | /* Build __builtin_eh_pointer. */ | ||||
3878 | |||||
3879 | static tree | ||||
3880 | objc_build_exc_ptr (struct objc_try_context **x ATTRIBUTE_UNUSED__attribute__ ((__unused__))) | ||||
3881 | { | ||||
3882 | tree t; | ||||
3883 | t = builtin_decl_explicit (BUILT_IN_EH_POINTER); | ||||
3884 | t = build_call_expr (t, 1, integer_zero_nodeglobal_trees[TI_INTEGER_ZERO]); | ||||
3885 | return fold_convert (objc_object_type, t)fold_convert_loc (((location_t) 0), objc_global_trees[OCTI_ID_TYPE ], t); | ||||
3886 | } | ||||
3887 | |||||
3888 | static tree begin_catch (struct objc_try_context **cur_try_context, tree type, | ||||
3889 | tree decl, tree compound, bool ellipsis ATTRIBUTE_UNUSED__attribute__ ((__unused__))) | ||||
3890 | { | ||||
3891 | tree t; | ||||
3892 | |||||
3893 | /* Record the data for the catch in the try context so that we can | ||||
3894 | finalize it later. Ellipsis is signalled by a NULL entry. */ | ||||
3895 | if (ellipsis) | ||||
3896 | t = build_stmt (input_location, CATCH_EXPR, NULL_TREE(tree) nullptr, compound); | ||||
3897 | else | ||||
3898 | t = build_stmt (input_location, CATCH_EXPR, type, compound); | ||||
3899 | (*cur_try_context)->current_catch = t; | ||||
3900 | |||||
3901 | /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */ | ||||
3902 | t = objc_build_exc_ptr (cur_try_context); | ||||
3903 | t = convert (TREE_TYPE (decl)((contains_struct_check ((decl), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3903, __FUNCTION__))->typed.type), t); | ||||
3904 | /* FIXME: location. */ | ||||
3905 | if (type && type != error_mark_nodeglobal_trees[TI_ERROR_MARK]) | ||||
3906 | { | ||||
3907 | t = build1(NOP_EXPR, ptr_type_nodeglobal_trees[TI_PTR_TYPE], t); | ||||
3908 | t = build_function_call (input_location, objc2_begin_catch_declobjc_v2_global_trees[OCTI_V2_BEGIN_CATCH_DECL], | ||||
3909 | tree_cons (NULL_TREE(tree) nullptr, t, NULL_TREE(tree) nullptr)); | ||||
3910 | |||||
3911 | /* We might want to build a catch object for this (if it's not | ||||
3912 | id). */ | ||||
3913 | if (POINTER_TYPE_P (type)(((enum tree_code) (type)->base.code) == POINTER_TYPE || ( (enum tree_code) (type)->base.code) == REFERENCE_TYPE) | ||||
3914 | && !objc_is_object_id (TREE_TYPE (type))(((tree_class_check ((((contains_struct_check ((type), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3914, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3914, __FUNCTION__))->type_common.name) == objc_global_trees [OCTI_OBJ_ID]) | ||||
3915 | && TYPED_OBJECT (TREE_TYPE (type))(((enum tree_code) (((contains_struct_check ((type), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3915, __FUNCTION__))->typed.type))->base.code) == RECORD_TYPE && (((tree_class_check ((((contains_struct_check ((type ), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3915, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3915, __FUNCTION__))->type_with_lang_specific.lang_specific ) && ((tree_class_check ((((contains_struct_check ((type ), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3915, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3915, __FUNCTION__))->type_with_lang_specific.lang_specific )->objc_info) && (*((const_cast<tree *> (tree_vec_elt_check ((((tree_class_check ((((contains_struct_check ((type), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3915, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3915, __FUNCTION__))->type_with_lang_specific.lang_specific )->objc_info), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3915, __FUNCTION__))))))) | ||||
3916 | objc_v2_add_to_ehtype_list (OBJC_TYPE_NAME (TREE_TYPE (type))((tree_class_check ((((contains_struct_check ((type), (TS_TYPED ), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3916, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3916, __FUNCTION__))->type_common.name)); | ||||
3917 | } | ||||
3918 | return build2 (MODIFY_EXPR, void_type_nodeglobal_trees[TI_VOID_TYPE], decl, t); | ||||
3919 | } | ||||
3920 | |||||
3921 | /* try { catch-body } finally { objc_end_catch (); } */ | ||||
3922 | static void | ||||
3923 | finish_catch (struct objc_try_context **cur_try_context, tree curr_catch) | ||||
3924 | { | ||||
3925 | struct objc_try_context *ct; | ||||
3926 | tree try_exp, func, *l, t ; | ||||
3927 | location_t loc = (*cur_try_context)->try_locus; | ||||
3928 | |||||
3929 | if (!curr_catch || curr_catch == error_mark_nodeglobal_trees[TI_ERROR_MARK]) | ||||
3930 | return; | ||||
3931 | |||||
3932 | t = CATCH_BODY (curr_catch)(*((const_cast<tree*> (tree_operand_check (((tree_check ((curr_catch), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3932, __FUNCTION__, (CATCH_EXPR)))), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3932, __FUNCTION__))))); | ||||
3933 | if (TREE_CODE (t)((enum tree_code) (t)->base.code) == BIND_EXPR) | ||||
3934 | { | ||||
3935 | /* Usual case of @catch (objc-expr). */ | ||||
3936 | objc_begin_try_stmt (loc, BIND_EXPR_BODY (t)((*((const_cast<tree*> (tree_operand_check (((tree_check ((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3936, __FUNCTION__, (BIND_EXPR)))), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3936, __FUNCTION__))))))); | ||||
3937 | BIND_EXPR_BODY (t)((*((const_cast<tree*> (tree_operand_check (((tree_check ((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3937, __FUNCTION__, (BIND_EXPR)))), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3937, __FUNCTION__)))))) = NULL_TREE(tree) nullptr; | ||||
3938 | l = &BIND_EXPR_BODY (t)((*((const_cast<tree*> (tree_operand_check (((tree_check ((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3938, __FUNCTION__, (BIND_EXPR)))), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3938, __FUNCTION__)))))); | ||||
3939 | } | ||||
3940 | else | ||||
3941 | { | ||||
3942 | /* NULL entry, meaning @catch (...). */ | ||||
3943 | objc_begin_try_stmt (loc, t); | ||||
3944 | CATCH_BODY (curr_catch)(*((const_cast<tree*> (tree_operand_check (((tree_check ((curr_catch), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3944, __FUNCTION__, (CATCH_EXPR)))), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3944, __FUNCTION__))))) = NULL_TREE(tree) nullptr; | ||||
3945 | l = &CATCH_BODY (curr_catch)(*((const_cast<tree*> (tree_operand_check (((tree_check ((curr_catch), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3945, __FUNCTION__, (CATCH_EXPR)))), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.c" , 3945, __FUNCTION__))))); | ||||
3946 | } | ||||
3947 | |||||
3948 | /* Pick up the new context we made in begin_try above... */ | ||||
3949 | ct = *cur_try_context; | ||||
3950 | func = build_function_call_vec (loc, vNULL, objc2_end_catch_declobjc_v2_global_trees[OCTI_V2_END_CATCH_DECL], NULLnullptr, | ||||
3951 | NULLnullptr); | ||||
3952 | append_to_statement_list (func, &ct->finally_body); | ||||
3953 | try_exp = build_stmt (loc, TRY_FINALLY_EXPR, ct->try_body, ct->finally_body); | ||||
3954 | *cur_try_context = ct->outer; | ||||
3955 | free (ct); | ||||
3956 | append_to_statement_list (try_exp, l); | ||||
3957 | append_to_statement_list (curr_catch, &((*cur_try_context)->catch_list)); | ||||
3958 | } | ||||
3959 | |||||
3960 | static tree | ||||
3961 | finish_try_stmt (struct objc_try_context **cur_try_context) | ||||
3962 | { | ||||
3963 | struct objc_try_context *c = *cur_try_context; | ||||
3964 | tree stmt = c->try_body; | ||||
3965 | if (c->catch_list) | ||||
3966 | stmt = build_stmt (c->try_locus, TRY_CATCH_EXPR, stmt, c->catch_list); | ||||
3967 | if (c->finally_body) | ||||
3968 | stmt = build_stmt (c->try_locus, TRY_FINALLY_EXPR, stmt, c->finally_body); | ||||
3969 | return stmt; | ||||
3970 | } | ||||
3971 | |||||
3972 | #include "gt-objc-objc-next-runtime-abi-02.h" |
1 | /* Vector API for GNU compiler. | ||||
2 | Copyright (C) 2004-2021 Free Software Foundation, Inc. | ||||
3 | Contributed by Nathan Sidwell <nathan@codesourcery.com> | ||||
4 | Re-implemented in C++ by Diego Novillo <dnovillo@google.com> | ||||
5 | |||||
6 | This file is part of GCC. | ||||
7 | |||||
8 | GCC is free software; you can redistribute it and/or modify it under | ||||
9 | the terms of the GNU General Public License as published by the Free | ||||
10 | Software Foundation; either version 3, or (at your option) any later | ||||
11 | version. | ||||
12 | |||||
13 | GCC is distributed in the hope that it will be useful, but WITHOUT ANY | ||||
14 | WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||||
15 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||||
16 | for more details. | ||||
17 | |||||
18 | You should have received a copy of the GNU General Public License | ||||
19 | along with GCC; see the file COPYING3. If not see | ||||
20 | <http://www.gnu.org/licenses/>. */ | ||||
21 | |||||
22 | #ifndef GCC_VEC_H | ||||
23 | #define GCC_VEC_H | ||||
24 | |||||
25 | /* Some gen* file have no ggc support as the header file gtype-desc.h is | ||||
26 | missing. Provide these definitions in case ggc.h has not been included. | ||||
27 | This is not a problem because any code that runs before gengtype is built | ||||
28 | will never need to use GC vectors.*/ | ||||
29 | |||||
30 | extern void ggc_free (void *); | ||||
31 | extern size_t ggc_round_alloc_size (size_t requested_size); | ||||
32 | extern void *ggc_realloc (void *, size_t MEM_STAT_DECL); | ||||
33 | |||||
34 | /* Templated vector type and associated interfaces. | ||||
35 | |||||
36 | The interface functions are typesafe and use inline functions, | ||||
37 | sometimes backed by out-of-line generic functions. The vectors are | ||||
38 | designed to interoperate with the GTY machinery. | ||||
39 | |||||
40 | There are both 'index' and 'iterate' accessors. The index accessor | ||||
41 | is implemented by operator[]. The iterator returns a boolean | ||||
42 | iteration condition and updates the iteration variable passed by | ||||
43 | reference. Because the iterator will be inlined, the address-of | ||||
44 | can be optimized away. | ||||
45 | |||||
46 | Each operation that increases the number of active elements is | ||||
47 | available in 'quick' and 'safe' variants. The former presumes that | ||||
48 | there is sufficient allocated space for the operation to succeed | ||||
49 | (it dies if there is not). The latter will reallocate the | ||||
50 | vector, if needed. Reallocation causes an exponential increase in | ||||
51 | vector size. If you know you will be adding N elements, it would | ||||
52 | be more efficient to use the reserve operation before adding the | ||||
53 | elements with the 'quick' operation. This will ensure there are at | ||||
54 | least as many elements as you ask for, it will exponentially | ||||
55 | increase if there are too few spare slots. If you want reserve a | ||||
56 | specific number of slots, but do not want the exponential increase | ||||
57 | (for instance, you know this is the last allocation), use the | ||||
58 | reserve_exact operation. You can also create a vector of a | ||||
59 | specific size from the get go. | ||||
60 | |||||
61 | You should prefer the push and pop operations, as they append and | ||||
62 | remove from the end of the vector. If you need to remove several | ||||
63 | items in one go, use the truncate operation. The insert and remove | ||||
64 | operations allow you to change elements in the middle of the | ||||
65 | vector. There are two remove operations, one which preserves the | ||||
66 | element ordering 'ordered_remove', and one which does not | ||||
67 | 'unordered_remove'. The latter function copies the end element | ||||
68 | into the removed slot, rather than invoke a memmove operation. The | ||||
69 | 'lower_bound' function will determine where to place an item in the | ||||
70 | array using insert that will maintain sorted order. | ||||
71 | |||||
72 | Vectors are template types with three arguments: the type of the | ||||
73 | elements in the vector, the allocation strategy, and the physical | ||||
74 | layout to use | ||||
75 | |||||
76 | Four allocation strategies are supported: | ||||
77 | |||||
78 | - Heap: allocation is done using malloc/free. This is the | ||||
79 | default allocation strategy. | ||||
80 | |||||
81 | - GC: allocation is done using ggc_alloc/ggc_free. | ||||
82 | |||||
83 | - GC atomic: same as GC with the exception that the elements | ||||
84 | themselves are assumed to be of an atomic type that does | ||||
85 | not need to be garbage collected. This means that marking | ||||
86 | routines do not need to traverse the array marking the | ||||
87 | individual elements. This increases the performance of | ||||
88 | GC activities. | ||||
89 | |||||
90 | Two physical layouts are supported: | ||||
91 | |||||
92 | - Embedded: The vector is structured using the trailing array | ||||
93 | idiom. The last member of the structure is an array of size | ||||
94 | 1. When the vector is initially allocated, a single memory | ||||
95 | block is created to hold the vector's control data and the | ||||
96 | array of elements. These vectors cannot grow without | ||||
97 | reallocation (see discussion on embeddable vectors below). | ||||
98 | |||||
99 | - Space efficient: The vector is structured as a pointer to an | ||||
100 | embedded vector. This is the default layout. It means that | ||||
101 | vectors occupy a single word of storage before initial | ||||
102 | allocation. Vectors are allowed to grow (the internal | ||||
103 | pointer is reallocated but the main vector instance does not | ||||
104 | need to relocate). | ||||
105 | |||||
106 | The type, allocation and layout are specified when the vector is | ||||
107 | declared. | ||||
108 | |||||
109 | If you need to directly manipulate a vector, then the 'address' | ||||
110 | accessor will return the address of the start of the vector. Also | ||||
111 | the 'space' predicate will tell you whether there is spare capacity | ||||
112 | in the vector. You will not normally need to use these two functions. | ||||
113 | |||||
114 | Notes on the different layout strategies | ||||
115 | |||||
116 | * Embeddable vectors (vec<T, A, vl_embed>) | ||||
117 | |||||
118 | These vectors are suitable to be embedded in other data | ||||
119 | structures so that they can be pre-allocated in a contiguous | ||||
120 | memory block. | ||||
121 | |||||
122 | Embeddable vectors are implemented using the trailing array | ||||
123 | idiom, thus they are not resizeable without changing the address | ||||
124 | of the vector object itself. This means you cannot have | ||||
125 | variables or fields of embeddable vector type -- always use a | ||||
126 | pointer to a vector. The one exception is the final field of a | ||||
127 | structure, which could be a vector type. | ||||
128 | |||||
129 | You will have to use the embedded_size & embedded_init calls to | ||||
130 | create such objects, and they will not be resizeable (so the | ||||
131 | 'safe' allocation variants are not available). | ||||
132 | |||||
133 | Properties of embeddable vectors: | ||||
134 | |||||
135 | - The whole vector and control data are allocated in a single | ||||
136 | contiguous block. It uses the trailing-vector idiom, so | ||||
137 | allocation must reserve enough space for all the elements | ||||
138 | in the vector plus its control data. | ||||
139 | - The vector cannot be re-allocated. | ||||
140 | - The vector cannot grow nor shrink. | ||||
141 | - No indirections needed for access/manipulation. | ||||
142 | - It requires 2 words of storage (prior to vector allocation). | ||||
143 | |||||
144 | |||||
145 | * Space efficient vector (vec<T, A, vl_ptr>) | ||||
146 | |||||
147 | These vectors can grow dynamically and are allocated together | ||||
148 | with their control data. They are suited to be included in data | ||||
149 | structures. Prior to initial allocation, they only take a single | ||||
150 | word of storage. | ||||
151 | |||||
152 | These vectors are implemented as a pointer to embeddable vectors. | ||||
153 | The semantics allow for this pointer to be NULL to represent | ||||
154 | empty vectors. This way, empty vectors occupy minimal space in | ||||
155 | the structure containing them. | ||||
156 | |||||
157 | Properties: | ||||
158 | |||||
159 | - The whole vector and control data are allocated in a single | ||||
160 | contiguous block. | ||||
161 | - The whole vector may be re-allocated. | ||||
162 | - Vector data may grow and shrink. | ||||
163 | - Access and manipulation requires a pointer test and | ||||
164 | indirection. | ||||
165 | - It requires 1 word of storage (prior to vector allocation). | ||||
166 | |||||
167 | An example of their use would be, | ||||
168 | |||||
169 | struct my_struct { | ||||
170 | // A space-efficient vector of tree pointers in GC memory. | ||||
171 | vec<tree, va_gc, vl_ptr> v; | ||||
172 | }; | ||||
173 | |||||
174 | struct my_struct *s; | ||||
175 | |||||
176 | if (s->v.length ()) { we have some contents } | ||||
177 | s->v.safe_push (decl); // append some decl onto the end | ||||
178 | for (ix = 0; s->v.iterate (ix, &elt); ix++) | ||||
179 | { do something with elt } | ||||
180 | */ | ||||
181 | |||||
182 | /* Support function for statistics. */ | ||||
183 | extern void dump_vec_loc_statistics (void); | ||||
184 | |||||
185 | /* Hashtable mapping vec addresses to descriptors. */ | ||||
186 | extern htab_t vec_mem_usage_hash; | ||||
187 | |||||
188 | /* Control data for vectors. This contains the number of allocated | ||||
189 | and used slots inside a vector. */ | ||||
190 | |||||
191 | struct vec_prefix | ||||
192 | { | ||||
193 | /* FIXME - These fields should be private, but we need to cater to | ||||
194 | compilers that have stricter notions of PODness for types. */ | ||||
195 | |||||
196 | /* Memory allocation support routines in vec.c. */ | ||||
197 | void register_overhead (void *, size_t, size_t CXX_MEM_STAT_INFO); | ||||
198 | void release_overhead (void *, size_t, size_t, bool CXX_MEM_STAT_INFO); | ||||
199 | static unsigned calculate_allocation (vec_prefix *, unsigned, bool); | ||||
200 | static unsigned calculate_allocation_1 (unsigned, unsigned); | ||||
201 | |||||
202 | /* Note that vec_prefix should be a base class for vec, but we use | ||||
203 | offsetof() on vector fields of tree structures (e.g., | ||||
204 | tree_binfo::base_binfos), and offsetof only supports base types. | ||||
205 | |||||
206 | To compensate, we make vec_prefix a field inside vec and make | ||||
207 | vec a friend class of vec_prefix so it can access its fields. */ | ||||
208 | template <typename, typename, typename> friend struct vec; | ||||
209 | |||||
210 | /* The allocator types also need access to our internals. */ | ||||
211 | friend struct va_gc; | ||||
212 | friend struct va_gc_atomic; | ||||
213 | friend struct va_heap; | ||||
214 | |||||
215 | unsigned m_alloc : 31; | ||||
216 | unsigned m_using_auto_storage : 1; | ||||
217 | unsigned m_num; | ||||
218 | }; | ||||
219 | |||||
220 | /* Calculate the number of slots to reserve a vector, making sure that | ||||
221 | RESERVE slots are free. If EXACT grow exactly, otherwise grow | ||||
222 | exponentially. PFX is the control data for the vector. */ | ||||
223 | |||||
224 | inline unsigned | ||||
225 | vec_prefix::calculate_allocation (vec_prefix *pfx, unsigned reserve, | ||||
226 | bool exact) | ||||
227 | { | ||||
228 | if (exact) | ||||
229 | return (pfx ? pfx->m_num : 0) + reserve; | ||||
230 | else if (!pfx) | ||||
231 | return MAX (4, reserve)((4) > (reserve) ? (4) : (reserve)); | ||||
232 | return calculate_allocation_1 (pfx->m_alloc, pfx->m_num + reserve); | ||||
233 | } | ||||
234 | |||||
235 | template<typename, typename, typename> struct vec; | ||||
236 | |||||
237 | /* Valid vector layouts | ||||
238 | |||||
239 | vl_embed - Embeddable vector that uses the trailing array idiom. | ||||
240 | vl_ptr - Space efficient vector that uses a pointer to an | ||||
241 | embeddable vector. */ | ||||
242 | struct vl_embed { }; | ||||
243 | struct vl_ptr { }; | ||||
244 | |||||
245 | |||||
246 | /* Types of supported allocations | ||||
247 | |||||
248 | va_heap - Allocation uses malloc/free. | ||||
249 | va_gc - Allocation uses ggc_alloc. | ||||
250 | va_gc_atomic - Same as GC, but individual elements of the array | ||||
251 | do not need to be marked during collection. */ | ||||
252 | |||||
253 | /* Allocator type for heap vectors. */ | ||||
254 | struct va_heap | ||||
255 | { | ||||
256 | /* Heap vectors are frequently regular instances, so use the vl_ptr | ||||
257 | layout for them. */ | ||||
258 | typedef vl_ptr default_layout; | ||||
259 | |||||
260 | template<typename T> | ||||
261 | static void reserve (vec<T, va_heap, vl_embed> *&, unsigned, bool | ||||
262 | CXX_MEM_STAT_INFO); | ||||
263 | |||||
264 | template<typename T> | ||||
265 | static void release (vec<T, va_heap, vl_embed> *&); | ||||
266 | }; | ||||
267 | |||||
268 | |||||
269 | /* Allocator for heap memory. Ensure there are at least RESERVE free | ||||
270 | slots in V. If EXACT is true, grow exactly, else grow | ||||
271 | exponentially. As a special case, if the vector had not been | ||||
272 | allocated and RESERVE is 0, no vector will be created. */ | ||||
273 | |||||
274 | template<typename T> | ||||
275 | inline void | ||||
276 | va_heap::reserve (vec<T, va_heap, vl_embed> *&v, unsigned reserve, bool exact | ||||
277 | MEM_STAT_DECL) | ||||
278 | { | ||||
279 | size_t elt_size = sizeof (T); | ||||
280 | unsigned alloc | ||||
281 | = vec_prefix::calculate_allocation (v ? &v->m_vecpfx : 0, reserve, exact); | ||||
282 | gcc_checking_assert (alloc)((void)(!(alloc) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h" , 282, __FUNCTION__), 0 : 0)); | ||||
283 | |||||
284 | if (GATHER_STATISTICS0 && v) | ||||
285 | v->m_vecpfx.release_overhead (v, elt_size * v->allocated (), | ||||
286 | v->allocated (), false); | ||||
287 | |||||
288 | size_t size = vec<T, va_heap, vl_embed>::embedded_size (alloc); | ||||
289 | unsigned nelem = v ? v->length () : 0; | ||||
290 | v = static_cast <vec<T, va_heap, vl_embed> *> (xrealloc (v, size)); | ||||
291 | v->embedded_init (alloc, nelem); | ||||
292 | |||||
293 | if (GATHER_STATISTICS0) | ||||
294 | v->m_vecpfx.register_overhead (v, alloc, elt_size PASS_MEM_STAT); | ||||
295 | } | ||||
296 | |||||
297 | |||||
298 | #if GCC_VERSION(4 * 1000 + 2) >= 4007 | ||||
299 | #pragma GCC diagnostic push | ||||
300 | #pragma GCC diagnostic ignored "-Wfree-nonheap-object" | ||||
301 | #endif | ||||
302 | |||||
303 | /* Free the heap space allocated for vector V. */ | ||||
304 | |||||
305 | template<typename T> | ||||
306 | void | ||||
307 | va_heap::release (vec<T, va_heap, vl_embed> *&v) | ||||
308 | { | ||||
309 | size_t elt_size = sizeof (T); | ||||
310 | if (v == NULLnullptr) | ||||
311 | return; | ||||
312 | |||||
313 | if (GATHER_STATISTICS0) | ||||
314 | v->m_vecpfx.release_overhead (v, elt_size * v->allocated (), | ||||
315 | v->allocated (), true); | ||||
316 | ::free (v); | ||||
317 | v = NULLnullptr; | ||||
318 | } | ||||
319 | |||||
320 | #if GCC_VERSION(4 * 1000 + 2) >= 4007 | ||||
321 | #pragma GCC diagnostic pop | ||||
322 | #endif | ||||
323 | |||||
324 | /* Allocator type for GC vectors. Notice that we need the structure | ||||
325 | declaration even if GC is not enabled. */ | ||||
326 | |||||
327 | struct va_gc | ||||
328 | { | ||||
329 | /* Use vl_embed as the default layout for GC vectors. Due to GTY | ||||
330 | limitations, GC vectors must always be pointers, so it is more | ||||
331 | efficient to use a pointer to the vl_embed layout, rather than | ||||
332 | using a pointer to a pointer as would be the case with vl_ptr. */ | ||||
333 | typedef vl_embed default_layout; | ||||
334 | |||||
335 | template<typename T, typename A> | ||||
336 | static void reserve (vec<T, A, vl_embed> *&, unsigned, bool | ||||
337 | CXX_MEM_STAT_INFO); | ||||
338 | |||||
339 | template<typename T, typename A> | ||||
340 | static void release (vec<T, A, vl_embed> *&v); | ||||
341 | }; | ||||
342 | |||||
343 | |||||
344 | /* Free GC memory used by V and reset V to NULL. */ | ||||
345 | |||||
346 | template<typename T, typename A> | ||||
347 | inline void | ||||
348 | va_gc::release (vec<T, A, vl_embed> *&v) | ||||
349 | { | ||||
350 | if (v) | ||||
351 | ::ggc_free (v); | ||||
352 | v = NULLnullptr; | ||||
353 | } | ||||
354 | |||||
355 | |||||
356 | /* Allocator for GC memory. Ensure there are at least RESERVE free | ||||
357 | slots in V. If EXACT is true, grow exactly, else grow | ||||
358 | exponentially. As a special case, if the vector had not been | ||||
359 | allocated and RESERVE is 0, no vector will be created. */ | ||||
360 | |||||
361 | template<typename T, typename A> | ||||
362 | void | ||||
363 | va_gc::reserve (vec<T, A, vl_embed> *&v, unsigned reserve, bool exact | ||||
364 | MEM_STAT_DECL) | ||||
365 | { | ||||
366 | unsigned alloc | ||||
367 | = vec_prefix::calculate_allocation (v ? &v->m_vecpfx : 0, reserve, exact); | ||||
368 | if (!alloc) | ||||
369 | { | ||||
370 | ::ggc_free (v); | ||||
371 | v = NULLnullptr; | ||||
372 | return; | ||||
373 | } | ||||
374 | |||||
375 | /* Calculate the amount of space we want. */ | ||||
376 | size_t size = vec<T, A, vl_embed>::embedded_size (alloc); | ||||
377 | |||||
378 | /* Ask the allocator how much space it will really give us. */ | ||||
379 | size = ::ggc_round_alloc_size (size); | ||||
380 | |||||
381 | /* Adjust the number of slots accordingly. */ | ||||
382 | size_t vec_offset = sizeof (vec_prefix); | ||||
383 | size_t elt_size = sizeof (T); | ||||
384 | alloc = (size - vec_offset) / elt_size; | ||||
385 | |||||
386 | /* And finally, recalculate the amount of space we ask for. */ | ||||
387 | size = vec_offset + alloc * elt_size; | ||||
388 | |||||
389 | unsigned nelem = v ? v->length () : 0; | ||||
390 | v = static_cast <vec<T, A, vl_embed> *> (::ggc_realloc (v, size | ||||
391 | PASS_MEM_STAT)); | ||||
392 | v->embedded_init (alloc, nelem); | ||||
393 | } | ||||
394 | |||||
395 | |||||
396 | /* Allocator type for GC vectors. This is for vectors of types | ||||
397 | atomics w.r.t. collection, so allocation and deallocation is | ||||
398 | completely inherited from va_gc. */ | ||||
399 | struct va_gc_atomic : va_gc | ||||
400 | { | ||||
401 | }; | ||||
402 | |||||
403 | |||||
404 | /* Generic vector template. Default values for A and L indicate the | ||||
405 | most commonly used strategies. | ||||
406 | |||||
407 | FIXME - Ideally, they would all be vl_ptr to encourage using regular | ||||
408 | instances for vectors, but the existing GTY machinery is limited | ||||
409 | in that it can only deal with GC objects that are pointers | ||||
410 | themselves. | ||||
411 | |||||
412 | This means that vector operations that need to deal with | ||||
413 | potentially NULL pointers, must be provided as free | ||||
414 | functions (see the vec_safe_* functions above). */ | ||||
415 | template<typename T, | ||||
416 | typename A = va_heap, | ||||
417 | typename L = typename A::default_layout> | ||||
418 | struct GTY((user)) vec | ||||
419 | { | ||||
420 | }; | ||||
421 | |||||
422 | /* Allow C++11 range-based 'for' to work directly on vec<T>*. */ | ||||
423 | template<typename T, typename A, typename L> | ||||
424 | T* begin (vec<T,A,L> *v) { return v ? v->begin () : nullptr; } | ||||
425 | template<typename T, typename A, typename L> | ||||
426 | T* end (vec<T,A,L> *v) { return v ? v->end () : nullptr; } | ||||
427 | template<typename T, typename A, typename L> | ||||
428 | const T* begin (const vec<T,A,L> *v) { return v ? v->begin () : nullptr; } | ||||
429 | template<typename T, typename A, typename L> | ||||
430 | const T* end (const vec<T,A,L> *v) { return v ? v->end () : nullptr; } | ||||
431 | |||||
432 | /* Generic vec<> debug helpers. | ||||
433 | |||||
434 | These need to be instantiated for each vec<TYPE> used throughout | ||||
435 | the compiler like this: | ||||
436 | |||||
437 | DEFINE_DEBUG_VEC (TYPE) | ||||
438 | |||||
439 | The reason we have a debug_helper() is because GDB can't | ||||
440 | disambiguate a plain call to debug(some_vec), and it must be called | ||||
441 | like debug<TYPE>(some_vec). */ | ||||
442 | |||||
443 | template<typename T> | ||||
444 | void | ||||
445 | debug_helper (vec<T> &ref) | ||||
446 | { | ||||
447 | unsigned i; | ||||
448 | for (i = 0; i < ref.length (); ++i) | ||||
449 | { | ||||
450 | fprintf (stderrstderr, "[%d] = ", i); | ||||
451 | debug_slim (ref[i]); | ||||
452 | fputc ('\n', stderrstderr); | ||||
453 | } | ||||
454 | } | ||||
455 | |||||
456 | /* We need a separate va_gc variant here because default template | ||||
457 | argument for functions cannot be used in c++-98. Once this | ||||
458 | restriction is removed, those variant should be folded with the | ||||
459 | above debug_helper. */ | ||||
460 | |||||
461 | template<typename T> | ||||
462 | void | ||||
463 | debug_helper (vec<T, va_gc> &ref) | ||||
464 | { | ||||
465 | unsigned i; | ||||
466 | for (i = 0; i < ref.length (); ++i) | ||||
467 | { | ||||
468 | fprintf (stderrstderr, "[%d] = ", i); | ||||
469 | debug_slim (ref[i]); | ||||
470 | fputc ('\n', stderrstderr); | ||||
471 | } | ||||
472 | } | ||||
473 | |||||
474 | /* Macro to define debug(vec<T>) and debug(vec<T, va_gc>) helper | ||||
475 | functions for a type T. */ | ||||
476 | |||||
477 | #define DEFINE_DEBUG_VEC(T)template void debug_helper (vec<T> &); template void debug_helper (vec<T, va_gc> &); __attribute__ ((__used__ )) void debug (vec<T> &ref) { debug_helper <T> (ref); } __attribute__ ((__used__)) void debug (vec<T> *ptr) { if (ptr) debug (*ptr); else fprintf (stderr, "<nil>\n" ); } __attribute__ ((__used__)) void debug (vec<T, va_gc> &ref) { debug_helper <T> (ref); } __attribute__ (( __used__)) void debug (vec<T, va_gc> *ptr) { if (ptr) debug (*ptr); else fprintf (stderr, "<nil>\n"); } \ | ||||
478 | template void debug_helper (vec<T> &); \ | ||||
479 | template void debug_helper (vec<T, va_gc> &); \ | ||||
480 | /* Define the vec<T> debug functions. */ \ | ||||
481 | DEBUG_FUNCTION__attribute__ ((__used__)) void \ | ||||
482 | debug (vec<T> &ref) \ | ||||
483 | { \ | ||||
484 | debug_helper <T> (ref); \ | ||||
485 | } \ | ||||
486 | DEBUG_FUNCTION__attribute__ ((__used__)) void \ | ||||
487 | debug (vec<T> *ptr) \ | ||||
488 | { \ | ||||
489 | if (ptr) \ | ||||
490 | debug (*ptr); \ | ||||
491 | else \ | ||||
492 | fprintf (stderrstderr, "<nil>\n"); \ | ||||
493 | } \ | ||||
494 | /* Define the vec<T, va_gc> debug functions. */ \ | ||||
495 | DEBUG_FUNCTION__attribute__ ((__used__)) void \ | ||||
496 | debug (vec<T, va_gc> &ref) \ | ||||
497 | { \ | ||||
498 | debug_helper <T> (ref); \ | ||||
499 | } \ | ||||
500 | DEBUG_FUNCTION__attribute__ ((__used__)) void \ | ||||
501 | debug (vec<T, va_gc> *ptr) \ | ||||
502 | { \ | ||||
503 | if (ptr) \ | ||||
504 | debug (*ptr); \ | ||||
505 | else \ | ||||
506 | fprintf (stderrstderr, "<nil>\n"); \ | ||||
507 | } | ||||
508 | |||||
509 | /* Default-construct N elements in DST. */ | ||||
510 | |||||
511 | template <typename T> | ||||
512 | inline void | ||||
513 | vec_default_construct (T *dst, unsigned n) | ||||
514 | { | ||||
515 | #ifdef BROKEN_VALUE_INITIALIZATION | ||||
516 | /* Versions of GCC before 4.4 sometimes leave certain objects | ||||
517 | uninitialized when value initialized, though if the type has | ||||
518 | user defined default ctor, that ctor is invoked. As a workaround | ||||
519 | perform clearing first and then the value initialization, which | ||||
520 | fixes the case when value initialization doesn't initialize due to | ||||
521 | the bugs and should initialize to all zeros, but still allows | ||||
522 | vectors for types with user defined default ctor that initializes | ||||
523 | some or all elements to non-zero. If T has no user defined | ||||
524 | default ctor and some non-static data members have user defined | ||||
525 | default ctors that initialize to non-zero the workaround will | ||||
526 | still not work properly; in that case we just need to provide | ||||
527 | user defined default ctor. */ | ||||
528 | memset (dst, '\0', sizeof (T) * n); | ||||
529 | #endif | ||||
530 | for ( ; n; ++dst, --n) | ||||
531 | ::new (static_cast<void*>(dst)) T (); | ||||
532 | } | ||||
533 | |||||
534 | /* Copy-construct N elements in DST from *SRC. */ | ||||
535 | |||||
536 | template <typename T> | ||||
537 | inline void | ||||
538 | vec_copy_construct (T *dst, const T *src, unsigned n) | ||||
539 | { | ||||
540 | for ( ; n; ++dst, ++src, --n) | ||||
541 | ::new (static_cast<void*>(dst)) T (*src); | ||||
542 | } | ||||
543 | |||||
544 | /* Type to provide NULL values for vec<T, A, L>. This is used to | ||||
545 | provide nil initializers for vec instances. Since vec must be | ||||
546 | a POD, we cannot have proper ctor/dtor for it. To initialize | ||||
547 | a vec instance, you can assign it the value vNULL. This isn't | ||||
548 | needed for file-scope and function-local static vectors, which | ||||
549 | are zero-initialized by default. */ | ||||
550 | struct vnull | ||||
551 | { | ||||
552 | template <typename T, typename A, typename L> | ||||
553 | CONSTEXPRconstexpr operator vec<T, A, L> () const { return vec<T, A, L>(); } | ||||
554 | }; | ||||
555 | extern vnull vNULL; | ||||
556 | |||||
557 | |||||
558 | /* Embeddable vector. These vectors are suitable to be embedded | ||||
559 | in other data structures so that they can be pre-allocated in a | ||||
560 | contiguous memory block. | ||||
561 | |||||
562 | Embeddable vectors are implemented using the trailing array idiom, | ||||
563 | thus they are not resizeable without changing the address of the | ||||
564 | vector object itself. This means you cannot have variables or | ||||
565 | fields of embeddable vector type -- always use a pointer to a | ||||
566 | vector. The one exception is the final field of a structure, which | ||||
567 | could be a vector type. | ||||
568 | |||||
569 | You will have to use the embedded_size & embedded_init calls to | ||||
570 | create such objects, and they will not be resizeable (so the 'safe' | ||||
571 | allocation variants are not available). | ||||
572 | |||||
573 | Properties: | ||||
574 | |||||
575 | - The whole vector and control data are allocated in a single | ||||
576 | contiguous block. It uses the trailing-vector idiom, so | ||||
577 | allocation must reserve enough space for all the elements | ||||
578 | in the vector plus its control data. | ||||
579 | - The vector cannot be re-allocated. | ||||
580 | - The vector cannot grow nor shrink. | ||||
581 | - No indirections needed for access/manipulation. | ||||
582 | - It requires 2 words of storage (prior to vector allocation). */ | ||||
583 | |||||
584 | template<typename T, typename A> | ||||
585 | struct GTY((user)) vec<T, A, vl_embed> | ||||
586 | { | ||||
587 | public: | ||||
588 | unsigned allocated (void) const { return m_vecpfx.m_alloc; } | ||||
589 | unsigned length (void) const { return m_vecpfx.m_num; } | ||||
590 | bool is_empty (void) const { return m_vecpfx.m_num == 0; } | ||||
591 | T *address (void) { return m_vecdata; } | ||||
592 | const T *address (void) const { return m_vecdata; } | ||||
593 | T *begin () { return address (); } | ||||
594 | const T *begin () const { return address (); } | ||||
595 | T *end () { return address () + length (); } | ||||
596 | const T *end () const { return address () + length (); } | ||||
597 | const T &operator[] (unsigned) const; | ||||
598 | T &operator[] (unsigned); | ||||
599 | T &last (void); | ||||
600 | bool space (unsigned) const; | ||||
601 | bool iterate (unsigned, T *) const; | ||||
602 | bool iterate (unsigned, T **) const; | ||||
603 | vec *copy (ALONE_CXX_MEM_STAT_INFO) const; | ||||
604 | void splice (const vec &); | ||||
605 | void splice (const vec *src); | ||||
606 | T *quick_push (const T &); | ||||
607 | T &pop (void); | ||||
608 | void truncate (unsigned); | ||||
609 | void quick_insert (unsigned, const T &); | ||||
610 | void ordered_remove (unsigned); | ||||
611 | void unordered_remove (unsigned); | ||||
612 | void block_remove (unsigned, unsigned); | ||||
613 | void qsort (int (*) (const void *, const void *))qsort (int (*) (const void *, const void *)); | ||||
614 | void sort (int (*) (const void *, const void *, void *), void *); | ||||
615 | T *bsearch (const void *key, int (*compar)(const void *, const void *)); | ||||
616 | T *bsearch (const void *key, | ||||
617 | int (*compar)(const void *, const void *, void *), void *); | ||||
618 | unsigned lower_bound (T, bool (*)(const T &, const T &)) const; | ||||
619 | bool contains (const T &search) const; | ||||
620 | static size_t embedded_size (unsigned); | ||||
621 | void embedded_init (unsigned, unsigned = 0, unsigned = 0); | ||||
622 | void quick_grow (unsigned len); | ||||
623 | void quick_grow_cleared (unsigned len); | ||||
624 | |||||
625 | /* vec class can access our internal data and functions. */ | ||||
626 | template <typename, typename, typename> friend struct vec; | ||||
627 | |||||
628 | /* The allocator types also need access to our internals. */ | ||||
629 | friend struct va_gc; | ||||
630 | friend struct va_gc_atomic; | ||||
631 | friend struct va_heap; | ||||
632 | |||||
633 | /* FIXME - These fields should be private, but we need to cater to | ||||
634 | compilers that have stricter notions of PODness for types. */ | ||||
635 | vec_prefix m_vecpfx; | ||||
636 | T m_vecdata[1]; | ||||
637 | }; | ||||
638 | |||||
639 | |||||
640 | /* Convenience wrapper functions to use when dealing with pointers to | ||||
641 | embedded vectors. Some functionality for these vectors must be | ||||
642 | provided via free functions for these reasons: | ||||
643 | |||||
644 | 1- The pointer may be NULL (e.g., before initial allocation). | ||||
645 | |||||
646 | 2- When the vector needs to grow, it must be reallocated, so | ||||
647 | the pointer will change its value. | ||||
648 | |||||
649 | Because of limitations with the current GC machinery, all vectors | ||||
650 | in GC memory *must* be pointers. */ | ||||
651 | |||||
652 | |||||
653 | /* If V contains no room for NELEMS elements, return false. Otherwise, | ||||
654 | return true. */ | ||||
655 | template<typename T, typename A> | ||||
656 | inline bool | ||||
657 | vec_safe_space (const vec<T, A, vl_embed> *v, unsigned nelems) | ||||
658 | { | ||||
659 | return v ? v->space (nelems) : nelems == 0; | ||||
660 | } | ||||
661 | |||||
662 | |||||
663 | /* If V is NULL, return 0. Otherwise, return V->length(). */ | ||||
664 | template<typename T, typename A> | ||||
665 | inline unsigned | ||||
666 | vec_safe_length (const vec<T, A, vl_embed> *v) | ||||
667 | { | ||||
668 | return v ? v->length () : 0; | ||||
669 | } | ||||
670 | |||||
671 | |||||
672 | /* If V is NULL, return NULL. Otherwise, return V->address(). */ | ||||
673 | template<typename T, typename A> | ||||
674 | inline T * | ||||
675 | vec_safe_address (vec<T, A, vl_embed> *v) | ||||
676 | { | ||||
677 | return v ? v->address () : NULLnullptr; | ||||
678 | } | ||||
679 | |||||
680 | |||||
681 | /* If V is NULL, return true. Otherwise, return V->is_empty(). */ | ||||
682 | template<typename T, typename A> | ||||
683 | inline bool | ||||
684 | vec_safe_is_empty (vec<T, A, vl_embed> *v) | ||||
685 | { | ||||
686 | return v ? v->is_empty () : true; | ||||
687 | } | ||||
688 | |||||
689 | /* If V does not have space for NELEMS elements, call | ||||
690 | V->reserve(NELEMS, EXACT). */ | ||||
691 | template<typename T, typename A> | ||||
692 | inline bool | ||||
693 | vec_safe_reserve (vec<T, A, vl_embed> *&v, unsigned nelems, bool exact = false | ||||
694 | CXX_MEM_STAT_INFO) | ||||
695 | { | ||||
696 | bool extend = nelems ? !vec_safe_space (v, nelems) : false; | ||||
697 | if (extend
| ||||
698 | A::reserve (v, nelems, exact PASS_MEM_STAT); | ||||
699 | return extend; | ||||
700 | } | ||||
701 | |||||
702 | template<typename T, typename A> | ||||
703 | inline bool | ||||
704 | vec_safe_reserve_exact (vec<T, A, vl_embed> *&v, unsigned nelems | ||||
705 | CXX_MEM_STAT_INFO) | ||||
706 | { | ||||
707 | return vec_safe_reserve (v, nelems, true PASS_MEM_STAT); | ||||
708 | } | ||||
709 | |||||
710 | |||||
711 | /* Allocate GC memory for V with space for NELEMS slots. If NELEMS | ||||
712 | is 0, V is initialized to NULL. */ | ||||
713 | |||||
714 | template<typename T, typename A> | ||||
715 | inline void | ||||
716 | vec_alloc (vec<T, A, vl_embed> *&v, unsigned nelems CXX_MEM_STAT_INFO) | ||||
717 | { | ||||
718 | v = NULLnullptr; | ||||
719 | vec_safe_reserve (v, nelems, false PASS_MEM_STAT); | ||||
720 | } | ||||
721 | |||||
722 | |||||
723 | /* Free the GC memory allocated by vector V and set it to NULL. */ | ||||
724 | |||||
725 | template<typename T, typename A> | ||||
726 | inline void | ||||
727 | vec_free (vec<T, A, vl_embed> *&v) | ||||
728 | { | ||||
729 | A::release (v); | ||||
730 | } | ||||
731 | |||||
732 | |||||
733 | /* Grow V to length LEN. Allocate it, if necessary. */ | ||||
734 | template<typename T, typename A> | ||||
735 | inline void | ||||
736 | vec_safe_grow (vec<T, A, vl_embed> *&v, unsigned len, | ||||
737 | bool exact = false CXX_MEM_STAT_INFO) | ||||
738 | { | ||||
739 | unsigned oldlen = vec_safe_length (v); | ||||
740 | gcc_checking_assert (len >= oldlen)((void)(!(len >= oldlen) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h" , 740, __FUNCTION__), 0 : 0)); | ||||
741 | vec_safe_reserve (v, len - oldlen, exact PASS_MEM_STAT); | ||||
742 | v->quick_grow (len); | ||||
743 | } | ||||
744 | |||||
745 | |||||
746 | /* If V is NULL, allocate it. Call V->safe_grow_cleared(LEN). */ | ||||
747 | template<typename T, typename A> | ||||
748 | inline void | ||||
749 | vec_safe_grow_cleared (vec<T, A, vl_embed> *&v, unsigned len, | ||||
750 | bool exact = false CXX_MEM_STAT_INFO) | ||||
751 | { | ||||
752 | unsigned oldlen = vec_safe_length (v); | ||||
753 | vec_safe_grow (v, len, exact PASS_MEM_STAT); | ||||
754 | vec_default_construct (v->address () + oldlen, len - oldlen); | ||||
755 | } | ||||
756 | |||||
757 | |||||
758 | /* Assume V is not NULL. */ | ||||
759 | |||||
760 | template<typename T> | ||||
761 | inline void | ||||
762 | vec_safe_grow_cleared (vec<T, va_heap, vl_ptr> *&v, | ||||
763 | unsigned len, bool exact = false CXX_MEM_STAT_INFO) | ||||
764 | { | ||||
765 | v->safe_grow_cleared (len, exact PASS_MEM_STAT); | ||||
766 | } | ||||
767 | |||||
768 | /* If V does not have space for NELEMS elements, call | ||||
769 | V->reserve(NELEMS, EXACT). */ | ||||
770 | |||||
771 | template<typename T> | ||||
772 | inline bool | ||||
773 | vec_safe_reserve (vec<T, va_heap, vl_ptr> *&v, unsigned nelems, bool exact = false | ||||
774 | CXX_MEM_STAT_INFO) | ||||
775 | { | ||||
776 | return v->reserve (nelems, exact); | ||||
777 | } | ||||
778 | |||||
779 | |||||
780 | /* If V is NULL return false, otherwise return V->iterate(IX, PTR). */ | ||||
781 | template<typename T, typename A> | ||||
782 | inline bool | ||||
783 | vec_safe_iterate (const vec<T, A, vl_embed> *v, unsigned ix, T **ptr) | ||||
784 | { | ||||
785 | if (v) | ||||
786 | return v->iterate (ix, ptr); | ||||
787 | else | ||||
788 | { | ||||
789 | *ptr = 0; | ||||
790 | return false; | ||||
791 | } | ||||
792 | } | ||||
793 | |||||
794 | template<typename T, typename A> | ||||
795 | inline bool | ||||
796 | vec_safe_iterate (const vec<T, A, vl_embed> *v, unsigned ix, T *ptr) | ||||
797 | { | ||||
798 | if (v) | ||||
799 | return v->iterate (ix, ptr); | ||||
800 | else | ||||
801 | { | ||||
802 | *ptr = 0; | ||||
803 | return false; | ||||
804 | } | ||||
805 | } | ||||
806 | |||||
807 | |||||
808 | /* If V has no room for one more element, reallocate it. Then call | ||||
809 | V->quick_push(OBJ). */ | ||||
810 | template<typename T, typename A> | ||||
811 | inline T * | ||||
812 | vec_safe_push (vec<T, A, vl_embed> *&v, const T &obj CXX_MEM_STAT_INFO) | ||||
813 | { | ||||
814 | vec_safe_reserve (v, 1, false PASS_MEM_STAT); | ||||
815 | return v->quick_push (obj); | ||||
816 | } | ||||
817 | |||||
818 | |||||
819 | /* if V has no room for one more element, reallocate it. Then call | ||||
820 | V->quick_insert(IX, OBJ). */ | ||||
821 | template<typename T, typename A> | ||||
822 | inline void | ||||
823 | vec_safe_insert (vec<T, A, vl_embed> *&v, unsigned ix, const T &obj | ||||
824 | CXX_MEM_STAT_INFO) | ||||
825 | { | ||||
826 | vec_safe_reserve (v, 1, false PASS_MEM_STAT); | ||||
827 | v->quick_insert (ix, obj); | ||||
828 | } | ||||
829 | |||||
830 | |||||
831 | /* If V is NULL, do nothing. Otherwise, call V->truncate(SIZE). */ | ||||
832 | template<typename T, typename A> | ||||
833 | inline void | ||||
834 | vec_safe_truncate (vec<T, A, vl_embed> *v, unsigned size) | ||||
835 | { | ||||
836 | if (v) | ||||
837 | v->truncate (size); | ||||
838 | } | ||||
839 | |||||
840 | |||||
841 | /* If SRC is not NULL, return a pointer to a copy of it. */ | ||||
842 | template<typename T, typename A> | ||||
843 | inline vec<T, A, vl_embed> * | ||||
844 | vec_safe_copy (vec<T, A, vl_embed> *src CXX_MEM_STAT_INFO) | ||||
845 | { | ||||
846 | return src ? src->copy (ALONE_PASS_MEM_STAT) : NULLnullptr; | ||||
847 | } | ||||
848 | |||||
849 | /* Copy the elements from SRC to the end of DST as if by memcpy. | ||||
850 | Reallocate DST, if necessary. */ | ||||
851 | template<typename T, typename A> | ||||
852 | inline void | ||||
853 | vec_safe_splice (vec<T, A, vl_embed> *&dst, const vec<T, A, vl_embed> *src | ||||
854 | CXX_MEM_STAT_INFO) | ||||
855 | { | ||||
856 | unsigned src_len = vec_safe_length (src); | ||||
857 | if (src_len) | ||||
858 | { | ||||
859 | vec_safe_reserve_exact (dst, vec_safe_length (dst) + src_len | ||||
860 | PASS_MEM_STAT); | ||||
861 | dst->splice (*src); | ||||
862 | } | ||||
863 | } | ||||
864 | |||||
865 | /* Return true if SEARCH is an element of V. Note that this is O(N) in the | ||||
866 | size of the vector and so should be used with care. */ | ||||
867 | |||||
868 | template<typename T, typename A> | ||||
869 | inline bool | ||||
870 | vec_safe_contains (vec<T, A, vl_embed> *v, const T &search) | ||||
871 | { | ||||
872 | return v ? v->contains (search) : false; | ||||
873 | } | ||||
874 | |||||
875 | /* Index into vector. Return the IX'th element. IX must be in the | ||||
876 | domain of the vector. */ | ||||
877 | |||||
878 | template<typename T, typename A> | ||||
879 | inline const T & | ||||
880 | vec<T, A, vl_embed>::operator[] (unsigned ix) const | ||||
881 | { | ||||
882 | gcc_checking_assert (ix < m_vecpfx.m_num)((void)(!(ix < m_vecpfx.m_num) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h" , 882, __FUNCTION__), 0 : 0)); | ||||
883 | return m_vecdata[ix]; | ||||
884 | } | ||||
885 | |||||
886 | template<typename T, typename A> | ||||
887 | inline T & | ||||
888 | vec<T, A, vl_embed>::operator[] (unsigned ix) | ||||
889 | { | ||||
890 | gcc_checking_assert (ix < m_vecpfx.m_num)((void)(!(ix < m_vecpfx.m_num) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h" , 890, __FUNCTION__), 0 : 0)); | ||||
891 | return m_vecdata[ix]; | ||||
892 | } | ||||
893 | |||||
894 | |||||
895 | /* Get the final element of the vector, which must not be empty. */ | ||||
896 | |||||
897 | template<typename T, typename A> | ||||
898 | inline T & | ||||
899 | vec<T, A, vl_embed>::last (void) | ||||
900 | { | ||||
901 | gcc_checking_assert (m_vecpfx.m_num > 0)((void)(!(m_vecpfx.m_num > 0) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h" , 901, __FUNCTION__), 0 : 0)); | ||||
902 | return (*this)[m_vecpfx.m_num - 1]; | ||||
903 | } | ||||
904 | |||||
905 | |||||
906 | /* If this vector has space for NELEMS additional entries, return | ||||
907 | true. You usually only need to use this if you are doing your | ||||
908 | own vector reallocation, for instance on an embedded vector. This | ||||
909 | returns true in exactly the same circumstances that vec::reserve | ||||
910 | will. */ | ||||
911 | |||||
912 | template<typename T, typename A> | ||||
913 | inline bool | ||||
914 | vec<T, A, vl_embed>::space (unsigned nelems) const | ||||
915 | { | ||||
916 | return m_vecpfx.m_alloc - m_vecpfx.m_num >= nelems; | ||||
917 | } | ||||
918 | |||||
919 | |||||
920 | /* Return iteration condition and update PTR to point to the IX'th | ||||
921 | element of this vector. Use this to iterate over the elements of a | ||||
922 | vector as follows, | ||||
923 | |||||
924 | for (ix = 0; vec<T, A>::iterate (v, ix, &ptr); ix++) | ||||
925 | continue; */ | ||||
926 | |||||
927 | template<typename T, typename A> | ||||
928 | inline bool | ||||
929 | vec<T, A, vl_embed>::iterate (unsigned ix, T *ptr) const | ||||
930 | { | ||||
931 | if (ix < m_vecpfx.m_num) | ||||
932 | { | ||||
933 | *ptr = m_vecdata[ix]; | ||||
934 | return true; | ||||
935 | } | ||||
936 | else | ||||
937 | { | ||||
938 | *ptr = 0; | ||||
939 | return false; | ||||
940 | } | ||||
941 | } | ||||
942 | |||||
943 | |||||
944 | /* Return iteration condition and update *PTR to point to the | ||||
945 | IX'th element of this vector. Use this to iterate over the | ||||
946 | elements of a vector as follows, | ||||
947 | |||||
948 | for (ix = 0; v->iterate (ix, &ptr); ix++) | ||||
949 | continue; | ||||
950 | |||||
951 | This variant is for vectors of objects. */ | ||||
952 | |||||
953 | template<typename T, typename A> | ||||
954 | inline bool | ||||
955 | vec<T, A, vl_embed>::iterate (unsigned ix, T **ptr) const | ||||
956 | { | ||||
957 | if (ix < m_vecpfx.m_num) | ||||
958 | { | ||||
959 | *ptr = CONST_CAST (T *, &m_vecdata[ix])(const_cast<T *> ((&m_vecdata[ix]))); | ||||
960 | return true; | ||||
961 | } | ||||
962 | else | ||||
963 | { | ||||
964 | *ptr = 0; | ||||
965 | return false; | ||||
966 | } | ||||
967 | } | ||||
968 | |||||
969 | |||||
970 | /* Return a pointer to a copy of this vector. */ | ||||
971 | |||||
972 | template<typename T, typename A> | ||||
973 | inline vec<T, A, vl_embed> * | ||||
974 | vec<T, A, vl_embed>::copy (ALONE_MEM_STAT_DECLvoid) const | ||||
975 | { | ||||
976 | vec<T, A, vl_embed> *new_vec = NULLnullptr; | ||||
977 | unsigned len = length (); | ||||
978 | if (len) | ||||
979 | { | ||||
980 | vec_alloc (new_vec, len PASS_MEM_STAT); | ||||
981 | new_vec->embedded_init (len, len); | ||||
982 | vec_copy_construct (new_vec->address (), m_vecdata, len); | ||||
983 | } | ||||
984 | return new_vec; | ||||
985 | } | ||||
986 | |||||
987 | |||||
988 | /* Copy the elements from SRC to the end of this vector as if by memcpy. | ||||
989 | The vector must have sufficient headroom available. */ | ||||
990 | |||||
991 | template<typename T, typename A> | ||||
992 | inline void | ||||
993 | vec<T, A, vl_embed>::splice (const vec<T, A, vl_embed> &src) | ||||
994 | { | ||||
995 | unsigned len = src.length (); | ||||
996 | if (len) | ||||
997 | { | ||||
998 | gcc_checking_assert (space (len))((void)(!(space (len)) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h" , 998, __FUNCTION__), 0 : 0)); | ||||
999 | vec_copy_construct (end (), src.address (), len); | ||||
1000 | m_vecpfx.m_num += len; | ||||
1001 | } | ||||
1002 | } | ||||
1003 | |||||
1004 | template<typename T, typename A> | ||||
1005 | inline void | ||||
1006 | vec<T, A, vl_embed>::splice (const vec<T, A, vl_embed> *src) | ||||
1007 | { | ||||
1008 | if (src) | ||||
1009 | splice (*src); | ||||
1010 | } | ||||
1011 | |||||
1012 | |||||
1013 | /* Push OBJ (a new element) onto the end of the vector. There must be | ||||
1014 | sufficient space in the vector. Return a pointer to the slot | ||||
1015 | where OBJ was inserted. */ | ||||
1016 | |||||
1017 | template<typename T, typename A> | ||||
1018 | inline T * | ||||
1019 | vec<T, A, vl_embed>::quick_push (const T &obj) | ||||
1020 | { | ||||
1021 | gcc_checking_assert (space (1))((void)(!(space (1)) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h" , 1021, __FUNCTION__), 0 : 0)); | ||||
1022 | T *slot = &m_vecdata[m_vecpfx.m_num++]; | ||||
1023 | *slot = obj; | ||||
1024 | return slot; | ||||
1025 | } | ||||
1026 | |||||
1027 | |||||
1028 | /* Pop and return the last element off the end of the vector. */ | ||||
1029 | |||||
1030 | template<typename T, typename A> | ||||
1031 | inline T & | ||||
1032 | vec<T, A, vl_embed>::pop (void) | ||||
1033 | { | ||||
1034 | gcc_checking_assert (length () > 0)((void)(!(length () > 0) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h" , 1034, __FUNCTION__), 0 : 0)); | ||||
1035 | return m_vecdata[--m_vecpfx.m_num]; | ||||
1036 | } | ||||
1037 | |||||
1038 | |||||
1039 | /* Set the length of the vector to SIZE. The new length must be less | ||||
1040 | than or equal to the current length. This is an O(1) operation. */ | ||||
1041 | |||||
1042 | template<typename T, typename A> | ||||
1043 | inline void | ||||
1044 | vec<T, A, vl_embed>::truncate (unsigned size) | ||||
1045 | { | ||||
1046 | gcc_checking_assert (length () >= size)((void)(!(length () >= size) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h" , 1046, __FUNCTION__), 0 : 0)); | ||||
1047 | m_vecpfx.m_num = size; | ||||
1048 | } | ||||
1049 | |||||
1050 | |||||
1051 | /* Insert an element, OBJ, at the IXth position of this vector. There | ||||
1052 | must be sufficient space. */ | ||||
1053 | |||||
1054 | template<typename T, typename A> | ||||
1055 | inline void | ||||
1056 | vec<T, A, vl_embed>::quick_insert (unsigned ix, const T &obj) | ||||
1057 | { | ||||
1058 | gcc_checking_assert (length () < allocated ())((void)(!(length () < allocated ()) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h" , 1058, __FUNCTION__), 0 : 0)); | ||||
1059 | gcc_checking_assert (ix <= length ())((void)(!(ix <= length ()) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h" , 1059, __FUNCTION__), 0 : 0)); | ||||
1060 | T *slot = &m_vecdata[ix]; | ||||
1061 | memmove (slot + 1, slot, (m_vecpfx.m_num++ - ix) * sizeof (T)); | ||||
1062 | *slot = obj; | ||||
1063 | } | ||||
1064 | |||||
1065 | |||||
1066 | /* Remove an element from the IXth position of this vector. Ordering of | ||||
1067 | remaining elements is preserved. This is an O(N) operation due to | ||||
1068 | memmove. */ | ||||
1069 | |||||
1070 | template<typename T, typename A> | ||||
1071 | inline void | ||||
1072 | vec<T, A, vl_embed>::ordered_remove (unsigned ix) | ||||
1073 | { | ||||
1074 | gcc_checking_assert (ix < length ())((void)(!(ix < length ()) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h" , 1074, __FUNCTION__), 0 : 0)); | ||||
1075 | T *slot = &m_vecdata[ix]; | ||||
1076 | memmove (slot, slot + 1, (--m_vecpfx.m_num - ix) * sizeof (T)); | ||||
1077 | } | ||||
1078 | |||||
1079 | |||||
1080 | /* Remove elements in [START, END) from VEC for which COND holds. Ordering of | ||||
1081 | remaining elements is preserved. This is an O(N) operation. */ | ||||
1082 | |||||
1083 | #define VEC_ORDERED_REMOVE_IF_FROM_TO(vec, read_index, write_index, \{ ((void)(!((end) <= (vec).length ()) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h" , 1084, __FUNCTION__), 0 : 0)); for (read_index = write_index = (start); read_index < (end); ++read_index) { elem_ptr = &(vec)[read_index]; bool remove_p = (cond); if (remove_p ) continue; if (read_index != write_index) (vec)[write_index] = (vec)[read_index]; write_index++; } if (read_index - write_index > 0) (vec).block_remove (write_index, read_index - write_index ); } | ||||
1084 | elem_ptr, start, end, cond){ ((void)(!((end) <= (vec).length ()) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h" , 1084, __FUNCTION__), 0 : 0)); for (read_index = write_index = (start); read_index < (end); ++read_index) { elem_ptr = &(vec)[read_index]; bool remove_p = (cond); if (remove_p ) continue; if (read_index != write_index) (vec)[write_index] = (vec)[read_index]; write_index++; } if (read_index - write_index > 0) (vec).block_remove (write_index, read_index - write_index ); } \ | ||||
1085 | { \ | ||||
1086 | gcc_assert ((end) <= (vec).length ())((void)(!((end) <= (vec).length ()) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h" , 1086, __FUNCTION__), 0 : 0)); \ | ||||
1087 | for (read_index = write_index = (start); read_index < (end); \ | ||||
1088 | ++read_index) \ | ||||
1089 | { \ | ||||
1090 | elem_ptr = &(vec)[read_index]; \ | ||||
1091 | bool remove_p = (cond); \ | ||||
1092 | if (remove_p) \ | ||||
1093 | continue; \ | ||||
1094 | \ | ||||
1095 | if (read_index != write_index) \ | ||||
1096 | (vec)[write_index] = (vec)[read_index]; \ | ||||
1097 | \ | ||||
1098 | write_index++; \ | ||||
1099 | } \ | ||||
1100 | \ | ||||
1101 | if (read_index - write_index > 0) \ | ||||
1102 | (vec).block_remove (write_index, read_index - write_index); \ | ||||
1103 | } | ||||
1104 | |||||
1105 | |||||
1106 | /* Remove elements from VEC for which COND holds. Ordering of remaining | ||||
1107 | elements is preserved. This is an O(N) operation. */ | ||||
1108 | |||||
1109 | #define VEC_ORDERED_REMOVE_IF(vec, read_index, write_index, elem_ptr, \{ ((void)(!(((vec).length ()) <= ((vec)).length ()) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h" , 1110, __FUNCTION__), 0 : 0)); for (read_index = write_index = (0); read_index < ((vec).length ()); ++read_index) { elem_ptr = &((vec))[read_index]; bool remove_p = ((cond)); if (remove_p ) continue; if (read_index != write_index) ((vec))[write_index ] = ((vec))[read_index]; write_index++; } if (read_index - write_index > 0) ((vec)).block_remove (write_index, read_index - write_index ); } | ||||
1110 | cond){ ((void)(!(((vec).length ()) <= ((vec)).length ()) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h" , 1110, __FUNCTION__), 0 : 0)); for (read_index = write_index = (0); read_index < ((vec).length ()); ++read_index) { elem_ptr = &((vec))[read_index]; bool remove_p = ((cond)); if (remove_p ) continue; if (read_index != write_index) ((vec))[write_index ] = ((vec))[read_index]; write_index++; } if (read_index - write_index > 0) ((vec)).block_remove (write_index, read_index - write_index ); } \ | ||||
1111 | VEC_ORDERED_REMOVE_IF_FROM_TO ((vec), read_index, write_index, \{ ((void)(!(((vec).length ()) <= ((vec)).length ()) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h" , 1112, __FUNCTION__), 0 : 0)); for (read_index = write_index = (0); read_index < ((vec).length ()); ++read_index) { elem_ptr = &((vec))[read_index]; bool remove_p = ((cond)); if (remove_p ) continue; if (read_index != write_index) ((vec))[write_index ] = ((vec))[read_index]; write_index++; } if (read_index - write_index > 0) ((vec)).block_remove (write_index, read_index - write_index ); } | ||||
1112 | elem_ptr, 0, (vec).length (), (cond)){ ((void)(!(((vec).length ()) <= ((vec)).length ()) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h" , 1112, __FUNCTION__), 0 : 0)); for (read_index = write_index = (0); read_index < ((vec).length ()); ++read_index) { elem_ptr = &((vec))[read_index]; bool remove_p = ((cond)); if (remove_p ) continue; if (read_index != write_index) ((vec))[write_index ] = ((vec))[read_index]; write_index++; } if (read_index - write_index > 0) ((vec)).block_remove (write_index, read_index - write_index ); } | ||||
1113 | |||||
1114 | /* Remove an element from the IXth position of this vector. Ordering of | ||||
1115 | remaining elements is destroyed. This is an O(1) operation. */ | ||||
1116 | |||||
1117 | template<typename T, typename A> | ||||
1118 | inline void | ||||
1119 | vec<T, A, vl_embed>::unordered_remove (unsigned ix) | ||||
1120 | { | ||||
1121 | gcc_checking_assert (ix < length ())((void)(!(ix < length ()) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h" , 1121, __FUNCTION__), 0 : 0)); | ||||
1122 | m_vecdata[ix] = m_vecdata[--m_vecpfx.m_num]; | ||||
1123 | } | ||||
1124 | |||||
1125 | |||||
1126 | /* Remove LEN elements starting at the IXth. Ordering is retained. | ||||
1127 | This is an O(N) operation due to memmove. */ | ||||
1128 | |||||
1129 | template<typename T, typename A> | ||||
1130 | inline void | ||||
1131 | vec<T, A, vl_embed>::block_remove (unsigned ix, unsigned len) | ||||
1132 | { | ||||
1133 | gcc_checking_assert (ix + len <= length ())((void)(!(ix + len <= length ()) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h" , 1133, __FUNCTION__), 0 : 0)); | ||||
1134 | T *slot = &m_vecdata[ix]; | ||||
1135 | m_vecpfx.m_num -= len; | ||||
1136 | memmove (slot, slot + len, (m_vecpfx.m_num - ix) * sizeof (T)); | ||||
1137 | } | ||||
1138 | |||||
1139 | |||||
1140 | /* Sort the contents of this vector with qsort. CMP is the comparison | ||||
1141 | function to pass to qsort. */ | ||||
1142 | |||||
1143 | template<typename T, typename A> | ||||
1144 | inline void | ||||
1145 | vec<T, A, vl_embed>::qsort (int (*cmp) (const void *, const void *))qsort (int (*cmp) (const void *, const void *)) | ||||
1146 | { | ||||
1147 | if (length () > 1) | ||||
1148 | gcc_qsort (address (), length (), sizeof (T), cmp); | ||||
1149 | } | ||||
1150 | |||||
1151 | /* Sort the contents of this vector with qsort. CMP is the comparison | ||||
1152 | function to pass to qsort. */ | ||||
1153 | |||||
1154 | template<typename T, typename A> | ||||
1155 | inline void | ||||
1156 | vec<T, A, vl_embed>::sort (int (*cmp) (const void *, const void *, void *), | ||||
1157 | void *data) | ||||
1158 | { | ||||
1159 | if (length () > 1) | ||||
1160 | gcc_sort_r (address (), length (), sizeof (T), cmp, data); | ||||
1161 | } | ||||
1162 | |||||
1163 | |||||
1164 | /* Search the contents of the sorted vector with a binary search. | ||||
1165 | CMP is the comparison function to pass to bsearch. */ | ||||
1166 | |||||
1167 | template<typename T, typename A> | ||||
1168 | inline T * | ||||
1169 | vec<T, A, vl_embed>::bsearch (const void *key, | ||||
1170 | int (*compar) (const void *, const void *)) | ||||
1171 | { | ||||
1172 | const void *base = this->address (); | ||||
1173 | size_t nmemb = this->length (); | ||||
1174 | size_t size = sizeof (T); | ||||
1175 | /* The following is a copy of glibc stdlib-bsearch.h. */ | ||||
1176 | size_t l, u, idx; | ||||
1177 | const void *p; | ||||
1178 | int comparison; | ||||
1179 | |||||
1180 | l = 0; | ||||
1181 | u = nmemb; | ||||
1182 | while (l < u) | ||||
1183 | { | ||||
1184 | idx = (l + u) / 2; | ||||
1185 | p = (const void *) (((const char *) base) + (idx * size)); | ||||
1186 | comparison = (*compar) (key, p); | ||||
1187 | if (comparison < 0) | ||||
1188 | u = idx; | ||||
1189 | else if (comparison > 0) | ||||
1190 | l = idx + 1; | ||||
1191 | else | ||||
1192 | return (T *)const_cast<void *>(p); | ||||
1193 | } | ||||
1194 | |||||
1195 | return NULLnullptr; | ||||
1196 | } | ||||
1197 | |||||
1198 | /* Search the contents of the sorted vector with a binary search. | ||||
1199 | CMP is the comparison function to pass to bsearch. */ | ||||
1200 | |||||
1201 | template<typename T, typename A> | ||||
1202 | inline T * | ||||
1203 | vec<T, A, vl_embed>::bsearch (const void *key, | ||||
1204 | int (*compar) (const void *, const void *, | ||||
1205 | void *), void *data) | ||||
1206 | { | ||||
1207 | const void *base = this->address (); | ||||
1208 | size_t nmemb = this->length (); | ||||
1209 | size_t size = sizeof (T); | ||||
1210 | /* The following is a copy of glibc stdlib-bsearch.h. */ | ||||
1211 | size_t l, u, idx; | ||||
1212 | const void *p; | ||||
1213 | int comparison; | ||||
1214 | |||||
1215 | l = 0; | ||||
1216 | u = nmemb; | ||||
1217 | while (l < u) | ||||
1218 | { | ||||
1219 | idx = (l + u) / 2; | ||||
1220 | p = (const void *) (((const char *) base) + (idx * size)); | ||||
1221 | comparison = (*compar) (key, p, data); | ||||
1222 | if (comparison < 0) | ||||
1223 | u = idx; | ||||
1224 | else if (comparison > 0) | ||||
1225 | l = idx + 1; | ||||
1226 | else | ||||
1227 | return (T *)const_cast<void *>(p); | ||||
1228 | } | ||||
1229 | |||||
1230 | return NULLnullptr; | ||||
1231 | } | ||||
1232 | |||||
1233 | /* Return true if SEARCH is an element of V. Note that this is O(N) in the | ||||
1234 | size of the vector and so should be used with care. */ | ||||
1235 | |||||
1236 | template<typename T, typename A> | ||||
1237 | inline bool | ||||
1238 | vec<T, A, vl_embed>::contains (const T &search) const | ||||
1239 | { | ||||
1240 | unsigned int len = length (); | ||||
1241 | for (unsigned int i = 0; i < len; i++) | ||||
1242 | if ((*this)[i] == search) | ||||
1243 | return true; | ||||
1244 | |||||
1245 | return false; | ||||
1246 | } | ||||
1247 | |||||
1248 | /* Find and return the first position in which OBJ could be inserted | ||||
1249 | without changing the ordering of this vector. LESSTHAN is a | ||||
1250 | function that returns true if the first argument is strictly less | ||||
1251 | than the second. */ | ||||
1252 | |||||
1253 | template<typename T, typename A> | ||||
1254 | unsigned | ||||
1255 | vec<T, A, vl_embed>::lower_bound (T obj, bool (*lessthan)(const T &, const T &)) | ||||
1256 | const | ||||
1257 | { | ||||
1258 | unsigned int len = length (); | ||||
1259 | unsigned int half, middle; | ||||
1260 | unsigned int first = 0; | ||||
1261 | while (len > 0) | ||||
1262 | { | ||||
1263 | half = len / 2; | ||||
1264 | middle = first; | ||||
1265 | middle += half; | ||||
1266 | T middle_elem = (*this)[middle]; | ||||
1267 | if (lessthan (middle_elem, obj)) | ||||
1268 | { | ||||
1269 | first = middle; | ||||
1270 | ++first; | ||||
1271 | len = len - half - 1; | ||||
1272 | } | ||||
1273 | else | ||||
1274 | len = half; | ||||
1275 | } | ||||
1276 | return first; | ||||
1277 | } | ||||
1278 | |||||
1279 | |||||
1280 | /* Return the number of bytes needed to embed an instance of an | ||||
1281 | embeddable vec inside another data structure. | ||||
1282 | |||||
1283 | Use these methods to determine the required size and initialization | ||||
1284 | of a vector V of type T embedded within another structure (as the | ||||
1285 | final member): | ||||
1286 | |||||
1287 | size_t vec<T, A, vl_embed>::embedded_size (unsigned alloc); | ||||
1288 |