File: | build/gcc/objc/objc-next-runtime-abi-02.cc |
Warning: | line 1767, 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-2023 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 | #include "opts.h" | ||||
55 | |||||
56 | #include "objc-runtime-hooks.h" | ||||
57 | #include "objc-runtime-shared-support.h" | ||||
58 | #include "objc-next-metadata-tags.h" | ||||
59 | #include "objc-encoding.h" | ||||
60 | |||||
61 | /* ABI 2 Private definitions. */ | ||||
62 | #define DEF_CONSTANT_STRING_CLASS_NAME"NSConstantString" "NSConstantString" | ||||
63 | |||||
64 | #define TAG_GETCLASS"objc_getClass" "objc_getClass" | ||||
65 | #define TAG_GETMETACLASS"objc_getMetaClass" "objc_getMetaClass" | ||||
66 | |||||
67 | #define TAG_MSGSEND"objc_msgSend" "objc_msgSend" | ||||
68 | #define TAG_MSGSENDID"objc_msgSendId" "objc_msgSendId" | ||||
69 | #define TAG_MSGSENDSUPER"objc_msgSendSuper2" "objc_msgSendSuper2" | ||||
70 | #define TAG_MSGSEND_STRET"objc_msgSend_stret" "objc_msgSend_stret" | ||||
71 | #define TAG_MSGSENDID_STRET"objc_msgSendId_stret" "objc_msgSendId_stret" | ||||
72 | #define TAG_MSGSENDSUPER_STRET"objc_msgSendSuper2_stret" "objc_msgSendSuper2_stret" | ||||
73 | |||||
74 | #define USE_FIXUP_BEFORE100600 100600 | ||||
75 | #define TAG_FIXUP"_fixup" "_fixup" | ||||
76 | |||||
77 | |||||
78 | #define TAG_NEXT_EHVTABLE_NAME"objc_ehtype_vtable" "objc_ehtype_vtable" | ||||
79 | #define TAG_V2_EH_TYPE"objc_ehtype_t" "objc_ehtype_t" | ||||
80 | |||||
81 | #define UTAG_V2_CLASS"_class_t" "_class_t" | ||||
82 | #define UTAG_V2_CLASS_RO"_class_ro_t" "_class_ro_t" | ||||
83 | #define UTAG_V2_PROTOCOL"_protocol_t" "_protocol_t" | ||||
84 | #define UTAG_V2_PROTOCOL_LIST"_protocol_list_t" "_protocol_list_t" | ||||
85 | |||||
86 | #define UTAG_V2_EH_TYPE"_objc_ehtype_t" "_objc_ehtype_t" | ||||
87 | |||||
88 | #define OBJC2_CLS_HAS_CXX_STRUCTORS0x0004L 0x0004L | ||||
89 | |||||
90 | enum objc_v2_tree_index | ||||
91 | { | ||||
92 | /* Templates. */ | ||||
93 | OCTI_V2_CLS_TEMPL, | ||||
94 | OCTI_V2_CAT_TEMPL, | ||||
95 | OCTI_V2_CLS_RO_TEMPL, | ||||
96 | OCTI_V2_PROTO_TEMPL, | ||||
97 | OCTI_V2_IVAR_TEMPL, | ||||
98 | OCTI_V2_IVAR_LIST_TEMPL, | ||||
99 | OCTI_V2_MESSAGE_REF_TEMPL, | ||||
100 | OCTI_V2_SUPER_MESSAGE_REF_TEMPL, | ||||
101 | |||||
102 | OCTI_V2_MESSAGE_SELECTOR_TYPE, | ||||
103 | OCTI_V2_SUPER_MESSAGE_SELECTOR_TYPE, | ||||
104 | OCTI_V2_IMP_TYPE, | ||||
105 | OCTI_V2_SUPER_IMP_TYPE, | ||||
106 | |||||
107 | OCTI_V2_CACHE_DECL, | ||||
108 | OCTI_V2_VTABLE_DECL, | ||||
109 | |||||
110 | OCTI_V2_PROPERTY_TEMPL, | ||||
111 | |||||
112 | /* V2 messaging. */ | ||||
113 | OCTI_V2_UMSG_FIXUP_DECL, | ||||
114 | OCTI_V2_UMSG_STRET_FIXUP_DECL, | ||||
115 | OCTI_V2_UMSG_ID_FIXUP_DECL, | ||||
116 | OCTI_V2_UMSG_ID_STRET_FIXUP_DECL, | ||||
117 | OCTI_V2_UMSG_SUPER2_FIXUP_DECL, | ||||
118 | OCTI_V2_UMSG_SUPER2_STRET_FIXUP_DECL, | ||||
119 | |||||
120 | /* Exceptions - related. */ | ||||
121 | OCTI_V2_BEGIN_CATCH_DECL, | ||||
122 | OCTI_V2_END_CATCH_DECL, | ||||
123 | OCTI_V2_RETHROW_DECL, | ||||
124 | |||||
125 | OCTI_V2_MAX | ||||
126 | }; | ||||
127 | |||||
128 | #define objc_v2_class_templateobjc_v2_global_trees[OCTI_V2_CLS_TEMPL] objc_v2_global_trees[OCTI_V2_CLS_TEMPL] | ||||
129 | #define objc_v2_class_ro_templateobjc_v2_global_trees[OCTI_V2_CLS_RO_TEMPL] \ | ||||
130 | objc_v2_global_trees[OCTI_V2_CLS_RO_TEMPL] | ||||
131 | #define objc_v2_category_templateobjc_v2_global_trees[OCTI_V2_CAT_TEMPL] \ | ||||
132 | objc_v2_global_trees[OCTI_V2_CAT_TEMPL] | ||||
133 | #define objc_v2_protocol_templateobjc_v2_global_trees[OCTI_V2_PROTO_TEMPL] \ | ||||
134 | objc_v2_global_trees[OCTI_V2_PROTO_TEMPL] | ||||
135 | |||||
136 | /* struct message_ref_t */ | ||||
137 | #define objc_v2_message_ref_templateobjc_v2_global_trees[OCTI_V2_MESSAGE_REF_TEMPL] \ | ||||
138 | objc_v2_global_trees[OCTI_V2_MESSAGE_REF_TEMPL] | ||||
139 | |||||
140 | #define objc_v2_ivar_list_ptrobjc_v2_global_trees[OCTI_V2_IVAR_LIST_TEMPL] objc_v2_global_trees[OCTI_V2_IVAR_LIST_TEMPL] | ||||
141 | |||||
142 | /* struct super_message_ref_t */ | ||||
143 | #define objc_v2_super_message_ref_templateobjc_v2_global_trees[OCTI_V2_SUPER_MESSAGE_REF_TEMPL] \ | ||||
144 | objc_v2_global_trees[OCTI_V2_SUPER_MESSAGE_REF_TEMPL] | ||||
145 | |||||
146 | /* struct message_ref_t* */ | ||||
147 | #define objc_v2_selector_typeobjc_v2_global_trees[OCTI_V2_MESSAGE_SELECTOR_TYPE] objc_v2_global_trees[OCTI_V2_MESSAGE_SELECTOR_TYPE] | ||||
148 | /* struct super_super_message_ref_t */ | ||||
149 | #define objc_v2_super_selector_typeobjc_v2_global_trees[OCTI_V2_SUPER_MESSAGE_SELECTOR_TYPE] \ | ||||
150 | objc_v2_global_trees[OCTI_V2_SUPER_MESSAGE_SELECTOR_TYPE] | ||||
151 | #define objc_v2_imp_typeobjc_v2_global_trees[OCTI_V2_IMP_TYPE] objc_v2_global_trees[OCTI_V2_IMP_TYPE] | ||||
152 | #define objc_v2_super_imp_typeobjc_v2_global_trees[OCTI_V2_SUPER_IMP_TYPE] objc_v2_global_trees[OCTI_V2_SUPER_IMP_TYPE] | ||||
153 | |||||
154 | #define UOBJC_V2_CACHE_declobjc_v2_global_trees[OCTI_V2_CACHE_DECL] objc_v2_global_trees[OCTI_V2_CACHE_DECL] | ||||
155 | #define UOBJC_V2_VTABLE_declobjc_v2_global_trees[OCTI_V2_VTABLE_DECL] objc_v2_global_trees[OCTI_V2_VTABLE_DECL] | ||||
156 | |||||
157 | #define objc_v2_ivar_templateobjc_v2_global_trees[OCTI_V2_IVAR_TEMPL] objc_v2_global_trees[OCTI_V2_IVAR_TEMPL] | ||||
158 | #define objc_v2_property_templateobjc_v2_global_trees[OCTI_V2_PROPERTY_TEMPL] \ | ||||
159 | objc_v2_global_trees[OCTI_V2_PROPERTY_TEMPL] | ||||
160 | |||||
161 | /* V2 Messaging */ | ||||
162 | |||||
163 | /* objc_msgSend_fixup_rtp */ | ||||
164 | #define umsg_fixup_declobjc_v2_global_trees[OCTI_V2_UMSG_FIXUP_DECL] objc_v2_global_trees[OCTI_V2_UMSG_FIXUP_DECL] | ||||
165 | /* objc_msgSend_stret_fixup_rtp */ | ||||
166 | #define umsg_stret_fixup_declobjc_v2_global_trees[OCTI_V2_UMSG_STRET_FIXUP_DECL] objc_v2_global_trees[OCTI_V2_UMSG_STRET_FIXUP_DECL] | ||||
167 | /* objc_msgSendId_fixup_rtp */ | ||||
168 | #define umsg_id_fixup_declobjc_v2_global_trees[OCTI_V2_UMSG_ID_FIXUP_DECL] objc_v2_global_trees[OCTI_V2_UMSG_ID_FIXUP_DECL] | ||||
169 | /* objc_msgSendId_stret_fixup_rtp */ | ||||
170 | #define umsg_id_stret_fixup_declobjc_v2_global_trees[OCTI_V2_UMSG_ID_STRET_FIXUP_DECL] \ | ||||
171 | objc_v2_global_trees[OCTI_V2_UMSG_ID_STRET_FIXUP_DECL] | ||||
172 | /* objc_msgSendSuper2_fixup_rtp */ | ||||
173 | #define umsg_id_super2_fixup_declobjc_v2_global_trees[OCTI_V2_UMSG_SUPER2_FIXUP_DECL] \ | ||||
174 | objc_v2_global_trees[OCTI_V2_UMSG_SUPER2_FIXUP_DECL] | ||||
175 | /* objc_msgSendSuper2_stret_fixup_rtp */ | ||||
176 | #define umsg_id_super2_stret_fixup_declobjc_v2_global_trees[OCTI_V2_UMSG_SUPER2_STRET_FIXUP_DECL] \ | ||||
177 | objc_v2_global_trees[OCTI_V2_UMSG_SUPER2_STRET_FIXUP_DECL] | ||||
178 | |||||
179 | #define objc2_begin_catch_declobjc_v2_global_trees[OCTI_V2_BEGIN_CATCH_DECL] objc_v2_global_trees[OCTI_V2_BEGIN_CATCH_DECL] | ||||
180 | #define objc2_end_catch_declobjc_v2_global_trees[OCTI_V2_END_CATCH_DECL] objc_v2_global_trees[OCTI_V2_END_CATCH_DECL] | ||||
181 | #define objc_rethrow_exception_declobjc_v2_global_trees[OCTI_V2_RETHROW_DECL] \ | ||||
182 | objc_v2_global_trees[OCTI_V2_RETHROW_DECL] | ||||
183 | |||||
184 | /* The OCTI_V2_... enumeration itself is in above. */ | ||||
185 | static GTY(()) tree objc_v2_global_trees[OCTI_V2_MAX]; | ||||
186 | |||||
187 | static void next_runtime_02_initialize (void); | ||||
188 | |||||
189 | static void build_v2_message_ref_templates (void); | ||||
190 | static void build_v2_class_templates (void); | ||||
191 | static void build_v2_super_template (void); | ||||
192 | static void build_v2_category_template (void); | ||||
193 | static void build_v2_protocol_template (void); | ||||
194 | |||||
195 | static tree next_runtime_abi_02_super_superclassfield_id (void); | ||||
196 | |||||
197 | static tree next_runtime_abi_02_class_decl (tree); | ||||
198 | static tree next_runtime_abi_02_metaclass_decl (tree); | ||||
199 | static tree next_runtime_abi_02_category_decl (tree); | ||||
200 | static tree next_runtime_abi_02_protocol_decl (tree); | ||||
201 | static tree next_runtime_abi_02_string_decl (tree, const char *, string_section); | ||||
202 | |||||
203 | static tree next_runtime_abi_02_get_class_reference (tree); | ||||
204 | static tree next_runtime_abi_02_build_selector_reference (location_t, tree, tree); | ||||
205 | static tree next_runtime_abi_02_get_protocol_reference (location_t, tree); | ||||
206 | static tree next_runtime_abi_02_build_ivar_ref (location_t, tree, tree); | ||||
207 | static tree next_runtime_abi_02_get_class_super_ref (location_t, struct imp_entry *, bool); | ||||
208 | static tree next_runtime_abi_02_get_category_super_ref (location_t, struct imp_entry *, bool); | ||||
209 | |||||
210 | static tree next_runtime_abi_02_receiver_is_class_object (tree); | ||||
211 | static void next_runtime_abi_02_get_arg_type_list_base (vec<tree, va_gc> **, | ||||
212 | tree, int, int); | ||||
213 | static tree next_runtime_abi_02_build_objc_method_call (location_t, tree, tree, | ||||
214 | tree, tree, tree, int); | ||||
215 | static bool next_runtime_abi_02_setup_const_string_class_decl (void); | ||||
216 | static tree next_runtime_abi_02_build_const_string_constructor (location_t, tree, int); | ||||
217 | |||||
218 | static tree create_extern_decl (tree, const char *); | ||||
219 | |||||
220 | static void objc_generate_v2_next_metadata (void); | ||||
221 | static bool objc2_objc_exception_attr (tree); | ||||
222 | |||||
223 | /* void build_v2_protocol_reference (tree);*/ | ||||
224 | static void build_v2_ehtype_template (void); | ||||
225 | static void build_v2_eh_catch_objects (void); | ||||
226 | static tree next_runtime_02_eh_type (tree); | ||||
227 | static tree objc_eh_personality (void); | ||||
228 | static tree build_throw_stmt (location_t, tree, bool); | ||||
229 | static tree objc_build_exc_ptr (struct objc_try_context **); | ||||
230 | static tree begin_catch (struct objc_try_context **, tree, tree, tree, bool); | ||||
231 | static void finish_catch (struct objc_try_context **, tree); | ||||
232 | static tree finish_try_stmt (struct objc_try_context **); | ||||
233 | |||||
234 | /* TODO: Use an objc-map. */ | ||||
235 | static GTY ((length ("SIZEHASHTABLE"))) hash *extern_names; | ||||
236 | |||||
237 | bool | ||||
238 | objc_next_runtime_abi_02_init (objc_runtime_hooks *rthooks) | ||||
239 | { | ||||
240 | extern_names = ggc_cleared_vec_alloc<hash> (SIZEHASHTABLE257); | ||||
241 | |||||
242 | if (flag_objc_sjlj_exceptionsglobal_options.x_flag_objc_sjlj_exceptions) | ||||
243 | { | ||||
244 | inform (UNKNOWN_LOCATION((location_t) 0), | ||||
245 | "%<-fobjc-sjlj-exceptions%> is ignored for " | ||||
246 | "%<-fnext-runtime%> when %<-fobjc-abi-version%> " | ||||
247 | "greater than 1"); | ||||
248 | flag_objc_sjlj_exceptionsglobal_options.x_flag_objc_sjlj_exceptions = 0; | ||||
249 | } | ||||
250 | |||||
251 | /* NeXT ABI 2 is intended to default to checking for nil receivers. */ | ||||
252 | if (! OPTION_SET_P (flag_objc_nilcheck)global_options_set.x_flag_objc_nilcheck) | ||||
253 | flag_objc_nilcheckglobal_options.x_flag_objc_nilcheck = 1; | ||||
254 | |||||
255 | rthooks->initialize = next_runtime_02_initialize; | ||||
256 | rthooks->default_constant_string_class_name = DEF_CONSTANT_STRING_CLASS_NAME"NSConstantString"; | ||||
257 | rthooks->tag_getclass = TAG_GETCLASS"objc_getClass"; | ||||
258 | rthooks->super_superclassfield_ident = next_runtime_abi_02_super_superclassfield_id; | ||||
259 | |||||
260 | rthooks->class_decl = next_runtime_abi_02_class_decl; | ||||
261 | rthooks->metaclass_decl = next_runtime_abi_02_metaclass_decl; | ||||
262 | rthooks->category_decl = next_runtime_abi_02_category_decl; | ||||
263 | rthooks->protocol_decl = next_runtime_abi_02_protocol_decl; | ||||
264 | rthooks->string_decl = next_runtime_abi_02_string_decl; | ||||
265 | |||||
266 | rthooks->get_class_reference = next_runtime_abi_02_get_class_reference; | ||||
267 | rthooks->build_selector_reference = next_runtime_abi_02_build_selector_reference; | ||||
268 | rthooks->get_protocol_reference = next_runtime_abi_02_get_protocol_reference; | ||||
269 | rthooks->build_ivar_reference = next_runtime_abi_02_build_ivar_ref; | ||||
270 | rthooks->get_class_super_ref = next_runtime_abi_02_get_class_super_ref; | ||||
271 | rthooks->get_category_super_ref = next_runtime_abi_02_get_category_super_ref; | ||||
272 | |||||
273 | rthooks->receiver_is_class_object = next_runtime_abi_02_receiver_is_class_object; | ||||
274 | rthooks->get_arg_type_list_base = next_runtime_abi_02_get_arg_type_list_base; | ||||
275 | rthooks->build_objc_method_call = next_runtime_abi_02_build_objc_method_call; | ||||
276 | |||||
277 | rthooks->setup_const_string_class_decl = | ||||
278 | next_runtime_abi_02_setup_const_string_class_decl; | ||||
279 | rthooks->build_const_string_constructor = | ||||
280 | next_runtime_abi_02_build_const_string_constructor; | ||||
281 | |||||
282 | rthooks->build_throw_stmt = build_throw_stmt; | ||||
283 | rthooks->build_exc_ptr = objc_build_exc_ptr; | ||||
284 | rthooks->begin_catch = begin_catch; | ||||
285 | rthooks->finish_catch = finish_catch; | ||||
286 | rthooks->finish_try_stmt = finish_try_stmt; | ||||
287 | |||||
288 | rthooks->generate_metadata = objc_generate_v2_next_metadata; | ||||
289 | return true; | ||||
290 | } | ||||
291 | |||||
292 | /* We need a way to convey what kind of meta-data are represented by a given | ||||
293 | variable, since each type is expected (by the runtime) to be found in a | ||||
294 | specific named section. The solution must be usable with LTO. | ||||
295 | |||||
296 | The scheme used for NeXT ABI 0/1 (partial matching of variable names) is not | ||||
297 | satisfactory when LTO is used with ABI-2. We now tag ObjC meta-data with | ||||
298 | identification attributes in the front end. The back-end may choose to act | ||||
299 | on these as it requires. */ | ||||
300 | |||||
301 | static void | ||||
302 | next_runtime_abi_02_init_metadata_attributes (void) | ||||
303 | { | ||||
304 | if (!objc_metaobjc_rt_trees[OCTI_RT_OBJC_META]) | ||||
305 | 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" )); | ||||
306 | |||||
307 | if (!meta_baseobjc_rt_trees[OCTI_RT_META_BASE]) | ||||
308 | 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" )); | ||||
309 | |||||
310 | 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" )); | ||||
311 | 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" )); | ||||
312 | meta_categoryobjc_rt_trees[OCTI_RT_META_CATEGORY] = meta_baseobjc_rt_trees[OCTI_RT_META_BASE]; | ||||
313 | 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" )); | ||||
314 | |||||
315 | meta_clac_varsobjc_rt_trees[OCTI_RT_META_CLASS_CLS_VARS] = | ||||
316 | meta_clai_varsobjc_rt_trees[OCTI_RT_META_CLASS_NST_VARS] = meta_baseobjc_rt_trees[OCTI_RT_META_BASE]; | ||||
317 | |||||
318 | meta_clac_methobjc_rt_trees[OCTI_RT_META_CLASS_CLS_METH] = | ||||
319 | meta_clai_methobjc_rt_trees[OCTI_RT_META_CLASS_NST_METH] = | ||||
320 | meta_catc_methobjc_rt_trees[OCTI_RT_META_CATEG_CLS_METH] = | ||||
321 | meta_cati_methobjc_rt_trees[OCTI_RT_META_CATEG_NST_METH] = | ||||
322 | meta_proto_cls_methobjc_rt_trees[OCTI_RT_META_PROTO_CLS_METH] = | ||||
323 | meta_proto_nst_methobjc_rt_trees[OCTI_RT_META_PROTO_NST_METH] = meta_baseobjc_rt_trees[OCTI_RT_META_BASE]; | ||||
324 | |||||
325 | meta_clas_protobjc_rt_trees[OCTI_RT_META_CLASS_PROT] = | ||||
326 | meta_catg_protobjc_rt_trees[OCTI_RT_META_CATEG_PROT] = meta_baseobjc_rt_trees[OCTI_RT_META_BASE]; | ||||
327 | |||||
328 | 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" )); | ||||
329 | |||||
330 | 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" )); | ||||
331 | 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" )); | ||||
332 | |||||
333 | 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" )); | ||||
334 | 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" )); | ||||
335 | |||||
336 | 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" )); | ||||
337 | 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" )); | ||||
338 | 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" )); | ||||
339 | |||||
340 | 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" )); | ||||
341 | 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" )); | ||||
342 | 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" )); | ||||
343 | 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" )); | ||||
344 | |||||
345 | 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" )); | ||||
346 | 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" )); | ||||
347 | |||||
348 | 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" )); | ||||
349 | |||||
350 | 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" )); | ||||
351 | |||||
352 | 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" )); | ||||
353 | |||||
354 | 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" )); | ||||
355 | } | ||||
356 | |||||
357 | static void next_runtime_02_initialize (void) | ||||
358 | { | ||||
359 | tree type; | ||||
360 | #ifdef OBJCPLUS | ||||
361 | /* For all NeXT objc ABIs -fobjc-call-cxx-cdtors is on by | ||||
362 | default. */ | ||||
363 | if (!OPTION_SET_P (flag_objc_call_cxx_cdtors)global_options_set.x_flag_objc_call_cxx_cdtors) | ||||
364 | global_options.x_flag_objc_call_cxx_cdtors = 1; | ||||
365 | #endif | ||||
366 | |||||
367 | /* Set up attributes to be attached to the meta-data so that they | ||||
368 | will be placed in the correct sections. */ | ||||
369 | next_runtime_abi_02_init_metadata_attributes (); | ||||
370 | |||||
371 | /* `struct objc_selector *' */ | ||||
372 | objc_selector_typeobjc_global_trees[OCTI_SEL_TYPE] = build_pointer_type (xref_tag (RECORD_TYPE, | ||||
373 | get_identifier (TAG_SELECTOR)(__builtin_constant_p ("objc_selector") ? get_identifier_with_length (("objc_selector"), strlen ("objc_selector")) : get_identifier ("objc_selector")))); | ||||
374 | |||||
375 | /* SEL typedef. */ | ||||
376 | type = lang_hooks.decls.pushdecl (build_decl (input_location, | ||||
377 | TYPE_DECL, | ||||
378 | objc_selector_nameobjc_global_trees[OCTI_SEL_NAME], | ||||
379 | objc_selector_typeobjc_global_trees[OCTI_SEL_TYPE])); | ||||
380 | suppress_warning (type); | ||||
381 | |||||
382 | /* IMP : id (*) (id, _message_ref_t*, ...) | ||||
383 | SUPER_IMP : id (*) ( super_t*, _super_message_ref_t*, ...) | ||||
384 | objc_v2_selector_type. */ | ||||
385 | build_v2_message_ref_templates (); | ||||
386 | |||||
387 | objc_v2_ivar_list_ptrobjc_v2_global_trees[OCTI_V2_IVAR_LIST_TEMPL] = | ||||
388 | build_pointer_type (xref_tag (RECORD_TYPE, | ||||
389 | 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")))); | ||||
390 | |||||
391 | objc_prop_list_ptrobjc_global_trees[OCTI_V1_PROP_LIST_TEMPL] = | ||||
392 | build_pointer_type (xref_tag (RECORD_TYPE, | ||||
393 | 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")))); | ||||
394 | |||||
395 | build_v2_class_templates (); | ||||
396 | build_v2_super_template (); | ||||
397 | build_v2_protocol_template (); | ||||
398 | build_v2_category_template (); | ||||
399 | |||||
400 | bool fixup_p = flag_next_runtimeglobal_options.x_flag_next_runtime < USE_FIXUP_BEFORE100600; | ||||
401 | if (fixup_p) | ||||
402 | { | ||||
403 | /* id objc_msgSend_fixup_rtp (id, struct message_ref_t*, ...); */ | ||||
404 | type = build_varargs_function_type_list (objc_object_typeobjc_global_trees[OCTI_ID_TYPE], | ||||
405 | objc_object_typeobjc_global_trees[OCTI_ID_TYPE], | ||||
406 | objc_v2_selector_typeobjc_v2_global_trees[OCTI_V2_MESSAGE_SELECTOR_TYPE], | ||||
407 | NULL_TREE(tree) nullptr); | ||||
408 | } | ||||
409 | else | ||||
410 | { | ||||
411 | /* id objc_msgSendXXXX (id, SEL, ...); */ | ||||
412 | type = build_varargs_function_type_list (objc_object_typeobjc_global_trees[OCTI_ID_TYPE], | ||||
413 | objc_object_typeobjc_global_trees[OCTI_ID_TYPE], | ||||
414 | objc_selector_typeobjc_global_trees[OCTI_SEL_TYPE], | ||||
415 | NULL_TREE(tree) nullptr); | ||||
416 | } | ||||
417 | const char *fnam = fixup_p ? TAG_MSGSEND"objc_msgSend" TAG_FIXUP"_fixup" : TAG_MSGSEND"objc_msgSend"; | ||||
418 | umsg_fixup_declobjc_v2_global_trees[OCTI_V2_UMSG_FIXUP_DECL] = add_builtin_function (fnam, type, 0, NOT_BUILT_IN, | ||||
419 | NULLnullptr, NULL_TREE(tree) nullptr); | ||||
420 | TREE_NOTHROW (umsg_fixup_decl)((objc_v2_global_trees[OCTI_V2_UMSG_FIXUP_DECL])->base.nothrow_flag ) = 0; | ||||
421 | |||||
422 | /* id objc_msgSend_stret_fixup_rtp (id, struct message_ref_t*, ...); */ | ||||
423 | fnam = fixup_p ? TAG_MSGSEND_STRET"objc_msgSend_stret" TAG_FIXUP"_fixup" : TAG_MSGSEND_STRET"objc_msgSend_stret"; | ||||
424 | umsg_stret_fixup_declobjc_v2_global_trees[OCTI_V2_UMSG_STRET_FIXUP_DECL] = add_builtin_function (fnam, type, 0, NOT_BUILT_IN, | ||||
425 | NULLnullptr, NULL_TREE(tree) nullptr); | ||||
426 | TREE_NOTHROW (umsg_stret_fixup_decl)((objc_v2_global_trees[OCTI_V2_UMSG_STRET_FIXUP_DECL])->base .nothrow_flag) = 0; | ||||
427 | |||||
428 | /* id objc_msgSendId_fixup_rtp (id, struct message_ref_t*, ...); */ | ||||
429 | fnam = fixup_p ? TAG_MSGSENDID"objc_msgSendId" TAG_FIXUP"_fixup" : TAG_MSGSENDID"objc_msgSendId"; | ||||
430 | umsg_id_fixup_declobjc_v2_global_trees[OCTI_V2_UMSG_ID_FIXUP_DECL] = add_builtin_function (fnam, type, 0, NOT_BUILT_IN, | ||||
431 | NULLnullptr, NULL_TREE(tree) nullptr); | ||||
432 | TREE_NOTHROW (umsg_id_fixup_decl)((objc_v2_global_trees[OCTI_V2_UMSG_ID_FIXUP_DECL])->base. nothrow_flag) = 0; | ||||
433 | |||||
434 | /* id objc_msgSendId_stret_fixup_rtp (id, struct message_ref_t*, ...); */ | ||||
435 | fnam = fixup_p ? TAG_MSGSENDID_STRET"objc_msgSendId_stret" TAG_FIXUP"_fixup" : TAG_MSGSENDID_STRET"objc_msgSendId_stret"; | ||||
436 | umsg_id_stret_fixup_declobjc_v2_global_trees[OCTI_V2_UMSG_ID_STRET_FIXUP_DECL] = add_builtin_function (fnam, type, 0, NOT_BUILT_IN, | ||||
437 | NULLnullptr, NULL_TREE(tree) nullptr); | ||||
438 | TREE_NOTHROW (umsg_id_stret_fixup_decl)((objc_v2_global_trees[OCTI_V2_UMSG_ID_STRET_FIXUP_DECL])-> base.nothrow_flag) = 0; | ||||
439 | |||||
440 | /* id objc_msgSendSuper2_fixup_rtp | ||||
441 | (struct objc_super *, struct message_ref_t*, ...); */ | ||||
442 | type = build_varargs_function_type_list (objc_object_typeobjc_global_trees[OCTI_ID_TYPE], | ||||
443 | objc_super_typeobjc_global_trees[OCTI_SUPER_TYPE], | ||||
444 | objc_v2_super_selector_typeobjc_v2_global_trees[OCTI_V2_SUPER_MESSAGE_SELECTOR_TYPE], | ||||
445 | NULL_TREE(tree) nullptr); | ||||
446 | fnam = fixup_p ? TAG_MSGSENDSUPER"objc_msgSendSuper2" TAG_FIXUP"_fixup" : TAG_MSGSENDSUPER"objc_msgSendSuper2"; | ||||
447 | umsg_id_super2_fixup_declobjc_v2_global_trees[OCTI_V2_UMSG_SUPER2_FIXUP_DECL] = add_builtin_function (fnam, type, 0, NOT_BUILT_IN, | ||||
448 | NULLnullptr, NULL_TREE(tree) nullptr); | ||||
449 | TREE_NOTHROW (umsg_id_super2_fixup_decl)((objc_v2_global_trees[OCTI_V2_UMSG_SUPER2_FIXUP_DECL])->base .nothrow_flag) = 0; | ||||
450 | |||||
451 | /* id objc_msgSendSuper2_stret_fixup_rtp | ||||
452 | (struct objc_super *, struct message_ref_t*, ...); */ | ||||
453 | fnam = fixup_p ? TAG_MSGSENDSUPER_STRET"objc_msgSendSuper2_stret" TAG_FIXUP"_fixup" : TAG_MSGSENDSUPER_STRET"objc_msgSendSuper2_stret"; | ||||
454 | umsg_id_super2_stret_fixup_declobjc_v2_global_trees[OCTI_V2_UMSG_SUPER2_STRET_FIXUP_DECL] = add_builtin_function (fnam, type, 0, | ||||
455 | NOT_BUILT_IN, NULLnullptr, | ||||
456 | NULL_TREE(tree) nullptr); | ||||
457 | TREE_NOTHROW (umsg_id_super2_stret_fixup_decl)((objc_v2_global_trees[OCTI_V2_UMSG_SUPER2_STRET_FIXUP_DECL]) ->base.nothrow_flag) = 0; | ||||
458 | |||||
459 | /* Present in the library, but unused by the FE. */ | ||||
460 | /* Protocol *objc_getProtocol (const char *) | ||||
461 | type = build_function_type_list (objc_protocol_type, | ||||
462 | const_string_type_node, | ||||
463 | NULL_TREE); | ||||
464 | objc_v2_getprotocol_decl = add_builtin_function ("objc_getProtocol", | ||||
465 | type, 0, NOT_BUILT_IN, | ||||
466 | NULL, NULL_TREE); | ||||
467 | TREE_NOTHROW (objc_v2_getprotocol_decl) = 0;*/ | ||||
468 | |||||
469 | UOBJC_V2_CACHE_declobjc_v2_global_trees[OCTI_V2_CACHE_DECL] = create_extern_decl (ptr_type_nodeglobal_trees[TI_PTR_TYPE], | ||||
470 | "_objc_empty_cache"); | ||||
471 | |||||
472 | 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], | ||||
473 | "_objc_empty_vtable"); | ||||
474 | |||||
475 | /* id objc_getClass (const char *); */ | ||||
476 | type = build_function_type_list (objc_object_typeobjc_global_trees[OCTI_ID_TYPE], | ||||
477 | const_string_type_nodec_global_trees[CTI_CONST_STRING_TYPE], | ||||
478 | NULL_TREE(tree) nullptr); | ||||
479 | objc_get_class_declobjc_global_trees[OCTI_GET_CLASS_DECL] = add_builtin_function (TAG_GETCLASS"objc_getClass", | ||||
480 | type, 0, NOT_BUILT_IN, | ||||
481 | NULLnullptr, NULL_TREE(tree) nullptr); | ||||
482 | |||||
483 | /* id objc_getMetaClass (const char *); */ | ||||
484 | objc_get_meta_class_declobjc_global_trees[OCTI_GET_MCLASS_DECL] = add_builtin_function (TAG_GETMETACLASS"objc_getMetaClass", | ||||
485 | type, 0, NOT_BUILT_IN, | ||||
486 | NULLnullptr, NULL_TREE(tree) nullptr); | ||||
487 | |||||
488 | /* This is the type of all of the following functions | ||||
489 | objc_copyStruct(). */ | ||||
490 | type = build_function_type_list (void_type_nodeglobal_trees[TI_VOID_TYPE], | ||||
491 | ptr_type_nodeglobal_trees[TI_PTR_TYPE], | ||||
492 | const_ptr_type_nodeglobal_trees[TI_CONST_PTR_TYPE], | ||||
493 | ptrdiff_type_nodeglobal_trees[TI_PTRDIFF_TYPE], | ||||
494 | boolean_type_nodeglobal_trees[TI_BOOLEAN_TYPE], | ||||
495 | boolean_type_nodeglobal_trees[TI_BOOLEAN_TYPE], | ||||
496 | NULL_TREE(tree) nullptr); | ||||
497 | /* Declare the following function: | ||||
498 | void | ||||
499 | objc_copyStruct (void *destination, const void *source, | ||||
500 | ptrdiff_t size, BOOL is_atomic, BOOL has_strong); */ | ||||
501 | objc_copyStruct_declobjc_global_trees[OCTI_COPY_STRUCT_DECL] = add_builtin_function ("objc_copyStruct", | ||||
502 | type, 0, NOT_BUILT_IN, | ||||
503 | NULLnullptr, NULL_TREE(tree) nullptr); | ||||
504 | TREE_NOTHROW (objc_copyStruct_decl)((objc_global_trees[OCTI_COPY_STRUCT_DECL])->base.nothrow_flag ) = 0; | ||||
505 | objc_getPropertyStruct_declobjc_global_trees[OCTI_GET_PROPERTY_STRUCT_DECL] = NULL_TREE(tree) nullptr; | ||||
506 | objc_setPropertyStruct_declobjc_global_trees[OCTI_SET_PROPERTY_STRUCT_DECL] = NULL_TREE(tree) nullptr; | ||||
507 | |||||
508 | gcc_checking_assert (!flag_objc_sjlj_exceptions)((void)(!(!global_options.x_flag_objc_sjlj_exceptions) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 508, __FUNCTION__), 0 : 0)); | ||||
509 | |||||
510 | /* Although we warn that fobjc-exceptions is required for exceptions | ||||
511 | code, we carry on and create it anyway. */ | ||||
512 | |||||
513 | /* This can be required, even when exceptions code is not present, | ||||
514 | when an __attribute__((objc_exception)) is applied to a | ||||
515 | class. */ | ||||
516 | build_v2_ehtype_template (); | ||||
517 | |||||
518 | /* void * objc_begin_catch (void *) */ | ||||
519 | type = build_function_type_list (ptr_type_nodeglobal_trees[TI_PTR_TYPE], | ||||
520 | ptr_type_nodeglobal_trees[TI_PTR_TYPE], NULL_TREE(tree) nullptr); | ||||
521 | |||||
522 | objc2_begin_catch_declobjc_v2_global_trees[OCTI_V2_BEGIN_CATCH_DECL] = add_builtin_function ("objc_begin_catch", | ||||
523 | type, 0, NOT_BUILT_IN, | ||||
524 | NULLnullptr, NULL_TREE(tree) nullptr); | ||||
525 | TREE_NOTHROW (objc2_begin_catch_decl)((objc_v2_global_trees[OCTI_V2_BEGIN_CATCH_DECL])->base.nothrow_flag ) = 0; | ||||
526 | |||||
527 | /* void objc_end_catch () */ | ||||
528 | type = build_function_type_list (void_type_nodeglobal_trees[TI_VOID_TYPE], NULL_TREE(tree) nullptr); | ||||
529 | objc2_end_catch_declobjc_v2_global_trees[OCTI_V2_END_CATCH_DECL] = add_builtin_function ("objc_end_catch", | ||||
530 | type, 0, NOT_BUILT_IN, | ||||
531 | NULLnullptr, NULL_TREE(tree) nullptr); | ||||
532 | TREE_NOTHROW (objc2_end_catch_decl)((objc_v2_global_trees[OCTI_V2_END_CATCH_DECL])->base.nothrow_flag ) = 0; | ||||
533 | |||||
534 | /* void objc_exception_rethrow (void) */ | ||||
535 | objc_rethrow_exception_declobjc_v2_global_trees[OCTI_V2_RETHROW_DECL] = | ||||
536 | add_builtin_function ("objc_exception_rethrow", | ||||
537 | type, 0, NOT_BUILT_IN, | ||||
538 | NULLnullptr, NULL_TREE(tree) nullptr); | ||||
539 | TREE_NOTHROW (objc_rethrow_exception_decl)((objc_v2_global_trees[OCTI_V2_RETHROW_DECL])->base.nothrow_flag ) = 0; | ||||
540 | using_eh_for_cleanups (); | ||||
541 | lang_hooks.eh_runtime_type = next_runtime_02_eh_type; | ||||
542 | lang_hooks.eh_personality = objc_eh_personality; | ||||
543 | } | ||||
544 | |||||
545 | /* NOTE --- templates --- */ | ||||
546 | |||||
547 | /* Set 'objc_v2_message_ref_template' to the data type node for | ||||
548 | 'struct _message_ref_t'. This needs to be done just once per | ||||
549 | compilation. Also Set 'objc_v2_super_message_ref_template' to data | ||||
550 | type node for 'struct _super_message_ref_t'. */ | ||||
551 | |||||
552 | /* struct _message_ref_t | ||||
553 | { | ||||
554 | IMP messenger; | ||||
555 | SEL name; | ||||
556 | }; | ||||
557 | where IMP is: id (*) (id, _message_ref_t*, ...) | ||||
558 | */ | ||||
559 | |||||
560 | /* struct _super_message_ref_t | ||||
561 | { | ||||
562 | SUPER_IMP messenger; | ||||
563 | SEL name; | ||||
564 | }; | ||||
565 | where SUPER_IMP is: id (*) ( super_t*, _super_message_ref_t*, ...) | ||||
566 | */ | ||||
567 | |||||
568 | static void | ||||
569 | build_v2_message_ref_templates (void) | ||||
570 | { | ||||
571 | tree ptr_message_ref_t; | ||||
572 | tree decls, *chain = NULLnullptr; | ||||
573 | |||||
574 | /* struct _message_ref_t {...} */ | ||||
575 | objc_v2_message_ref_templateobjc_v2_global_trees[OCTI_V2_MESSAGE_REF_TEMPL] = | ||||
576 | 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"))); | ||||
577 | |||||
578 | /* IMP messenger; */ | ||||
579 | ptr_message_ref_t = | ||||
580 | build_pointer_type (xref_tag (RECORD_TYPE, | ||||
581 | 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")))); | ||||
582 | |||||
583 | objc_v2_imp_typeobjc_v2_global_trees[OCTI_V2_IMP_TYPE] = | ||||
584 | build_pointer_type (build_function_type_list | ||||
585 | (objc_object_typeobjc_global_trees[OCTI_ID_TYPE], | ||||
586 | objc_object_typeobjc_global_trees[OCTI_ID_TYPE], | ||||
587 | ptr_message_ref_t, | ||||
588 | NULL_TREE(tree) nullptr)); | ||||
589 | |||||
590 | decls = add_field_decl (objc_v2_imp_typeobjc_v2_global_trees[OCTI_V2_IMP_TYPE], "messenger", &chain); | ||||
591 | |||||
592 | /* SEL name; */ | ||||
593 | add_field_decl (objc_selector_typeobjc_global_trees[OCTI_SEL_TYPE], "name", &chain); | ||||
594 | |||||
595 | objc_finish_struct (objc_v2_message_ref_templateobjc_v2_global_trees[OCTI_V2_MESSAGE_REF_TEMPL], decls); | ||||
596 | |||||
597 | 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]); | ||||
598 | |||||
599 | chain = NULLnullptr; | ||||
600 | /* struct _super_message_ref_t {...} */ | ||||
601 | objc_v2_super_message_ref_templateobjc_v2_global_trees[OCTI_V2_SUPER_MESSAGE_REF_TEMPL] = | ||||
602 | 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"))); | ||||
603 | |||||
604 | /* SUPER_IMP messenger; */ | ||||
605 | ptr_message_ref_t = build_pointer_type | ||||
606 | (xref_tag (RECORD_TYPE, | ||||
607 | 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")))); | ||||
608 | |||||
609 | objc_v2_super_imp_typeobjc_v2_global_trees[OCTI_V2_SUPER_IMP_TYPE] = | ||||
610 | build_pointer_type (build_function_type_list | ||||
611 | (objc_object_typeobjc_global_trees[OCTI_ID_TYPE], | ||||
612 | objc_super_typeobjc_global_trees[OCTI_SUPER_TYPE], | ||||
613 | ptr_message_ref_t, | ||||
614 | NULL_TREE(tree) nullptr)); | ||||
615 | |||||
616 | add_field_decl (objc_v2_super_imp_typeobjc_v2_global_trees[OCTI_V2_SUPER_IMP_TYPE], "messenger", &chain); | ||||
617 | |||||
618 | /* SEL name; */ | ||||
619 | add_field_decl (objc_selector_typeobjc_global_trees[OCTI_SEL_TYPE], "name", &chain); | ||||
620 | |||||
621 | objc_finish_struct (objc_v2_super_message_ref_templateobjc_v2_global_trees[OCTI_V2_SUPER_MESSAGE_REF_TEMPL], decls); | ||||
622 | objc_v2_super_selector_typeobjc_v2_global_trees[OCTI_V2_SUPER_MESSAGE_SELECTOR_TYPE] = | ||||
623 | build_pointer_type (objc_v2_super_message_ref_templateobjc_v2_global_trees[OCTI_V2_SUPER_MESSAGE_REF_TEMPL]); | ||||
624 | } | ||||
625 | |||||
626 | /* Build following types which represent each class implementation. | ||||
627 | |||||
628 | struct class_ro_t | ||||
629 | { | ||||
630 | uint32_t const flags; | ||||
631 | uint32_t const instanceStart; | ||||
632 | uint32_t const instanceSize; | ||||
633 | #ifdef __LP64__ | ||||
634 | uint32_t const reserved; | ||||
635 | #endif | ||||
636 | const uint8_t * const ivarLayout; | ||||
637 | const char *const name; | ||||
638 | const struct method_list_t * const baseMethods; | ||||
639 | const struct objc_protocol_list *const baseProtocols; | ||||
640 | const struct ivar_list_t *const ivars; | ||||
641 | const uint8_t * const weakIvarLayout; | ||||
642 | const struct _prop_list_t * const properties; | ||||
643 | }; | ||||
644 | |||||
645 | struct class_t | ||||
646 | { | ||||
647 | struct class_t *isa; | ||||
648 | struct class_t *superclass; | ||||
649 | void *cache; | ||||
650 | IMP *vtable; | ||||
651 | |||||
652 | ...When this is active - it will point to a rw version, but | ||||
653 | when we build the meta-data we point it to the ro... | ||||
654 | struct class_ro_t *data; | ||||
655 | }; | ||||
656 | |||||
657 | */ | ||||
658 | |||||
659 | static void | ||||
660 | build_v2_class_templates (void) | ||||
661 | { | ||||
662 | tree cnst_strg_type; | ||||
663 | tree decls, *chain = NULLnullptr; | ||||
664 | |||||
665 | /* struct class_ro_t {...} */ | ||||
666 | objc_v2_class_ro_templateobjc_v2_global_trees[OCTI_V2_CLS_RO_TEMPL] = | ||||
667 | 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"))); | ||||
668 | |||||
669 | /* uint32_t const flags; */ | ||||
670 | decls = add_field_decl (integer_type_nodeinteger_types[itk_int], "flags", &chain); | ||||
671 | |||||
672 | /* uint32_t const instanceStart; */ | ||||
673 | add_field_decl (integer_type_nodeinteger_types[itk_int], "instanceStart", &chain); | ||||
674 | |||||
675 | /* uint32_t const instanceSize; */ | ||||
676 | add_field_decl (integer_type_nodeinteger_types[itk_int], "instanceSize", &chain); | ||||
677 | |||||
678 | /* This ABI is currently only used on m64 NeXT. We always | ||||
679 | explicitly declare the alignment padding. */ | ||||
680 | /* uint32_t const reserved; */ | ||||
681 | add_field_decl (integer_type_nodeinteger_types[itk_int], "reserved", &chain); | ||||
682 | |||||
683 | /* const uint8_t * const ivarLayout; */ | ||||
684 | cnst_strg_type = build_pointer_type (unsigned_char_type_nodeinteger_types[itk_unsigned_char]); | ||||
685 | add_field_decl (cnst_strg_type, "ivarLayout", &chain); | ||||
686 | |||||
687 | /* const char *const name; */ | ||||
688 | add_field_decl (string_type_nodec_global_trees[CTI_STRING_TYPE], "name", &chain); | ||||
689 | |||||
690 | /* const struct method_list_t * const baseMethods; */ | ||||
691 | add_field_decl (objc_method_list_ptrobjc_global_trees[OCTI_METH_LIST_TEMPL], "baseMethods", &chain); | ||||
692 | |||||
693 | /* const struct objc_protocol_list *const baseProtocols; */ | ||||
694 | add_field_decl (build_pointer_type | ||||
695 | (xref_tag (RECORD_TYPE, | ||||
696 | 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")))), | ||||
697 | "baseProtocols", &chain); | ||||
698 | |||||
699 | /* const struct ivar_list_t *const ivars; */ | ||||
700 | add_field_decl (objc_v2_ivar_list_ptrobjc_v2_global_trees[OCTI_V2_IVAR_LIST_TEMPL], "ivars", &chain); | ||||
701 | |||||
702 | /* const uint8_t * const weakIvarLayout; */ | ||||
703 | add_field_decl (cnst_strg_type, "weakIvarLayout", &chain); | ||||
704 | |||||
705 | /* struct _prop_list_t * baseProperties; */ | ||||
706 | add_field_decl (objc_prop_list_ptrobjc_global_trees[OCTI_V1_PROP_LIST_TEMPL], "baseProperties", &chain); | ||||
707 | |||||
708 | objc_finish_struct (objc_v2_class_ro_templateobjc_v2_global_trees[OCTI_V2_CLS_RO_TEMPL], decls); | ||||
709 | |||||
710 | chain = NULLnullptr; | ||||
711 | /* struct class_t {...} */ | ||||
712 | objc_v2_class_templateobjc_v2_global_trees[OCTI_V2_CLS_TEMPL] = | ||||
713 | 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" ))); | ||||
714 | |||||
715 | /* struct class_t *isa; */ | ||||
716 | decls = add_field_decl (build_pointer_type (objc_v2_class_templateobjc_v2_global_trees[OCTI_V2_CLS_TEMPL]), | ||||
717 | "isa", &chain); | ||||
718 | |||||
719 | /* struct class_t * const superclass; */ | ||||
720 | add_field_decl (build_pointer_type (objc_v2_class_templateobjc_v2_global_trees[OCTI_V2_CLS_TEMPL]), | ||||
721 | "superclass", &chain); | ||||
722 | |||||
723 | /* void *cache; */ | ||||
724 | add_field_decl (build_pointer_type (void_type_nodeglobal_trees[TI_VOID_TYPE]), "cache", &chain); | ||||
725 | |||||
726 | /* IMP *vtable; */ | ||||
727 | add_field_decl (build_pointer_type (objc_v2_imp_typeobjc_v2_global_trees[OCTI_V2_IMP_TYPE]), "vtable", &chain); | ||||
728 | |||||
729 | /* struct class_ro_t *ro; */ | ||||
730 | add_field_decl (build_pointer_type (objc_v2_class_ro_templateobjc_v2_global_trees[OCTI_V2_CLS_RO_TEMPL]), "ro", &chain); | ||||
731 | |||||
732 | objc_finish_struct (objc_v2_class_templateobjc_v2_global_trees[OCTI_V2_CLS_TEMPL], decls); | ||||
733 | } | ||||
734 | |||||
735 | /* struct _objc_super | ||||
736 | { | ||||
737 | struct _objc_object *self; | ||||
738 | Class cls; | ||||
739 | }; */ | ||||
740 | void | ||||
741 | build_v2_super_template (void) | ||||
742 | { | ||||
743 | tree decls, *chain = NULLnullptr; | ||||
744 | |||||
745 | 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"))); | ||||
746 | |||||
747 | /* struct _objc_object *self; */ | ||||
748 | decls = add_field_decl (objc_object_typeobjc_global_trees[OCTI_ID_TYPE], "self", &chain); | ||||
749 | |||||
750 | /* Class cls; */ | ||||
751 | add_field_decl (objc_class_typeobjc_global_trees[OCTI_CLS_TYPE], "cls", &chain); | ||||
752 | |||||
753 | objc_finish_struct (objc_super_templateobjc_global_trees[OCTI_SUPER_TEMPL], decls); | ||||
754 | } | ||||
755 | |||||
756 | /* struct protocol_t | ||||
757 | { | ||||
758 | Class isa; | ||||
759 | const char * const protocol_name; | ||||
760 | const struct protocol_list_t * const protocol_list; | ||||
761 | const struct method_list_t * const instance_methods; | ||||
762 | const struct method_list_t * const class_methods; | ||||
763 | const struct method_list_t * optionalInstanceMethods; | ||||
764 | const struct method_list_t * optionalClassMethod | ||||
765 | const struct _prop_list_t * const properties; | ||||
766 | const uint32_t size; | ||||
767 | const uint32_t flags; | ||||
768 | const char ** extended_method_types; | ||||
769 | const char * demangled_name; | ||||
770 | const struct _prop_list_t * class_properties; | ||||
771 | } | ||||
772 | */ | ||||
773 | static void | ||||
774 | build_v2_protocol_template (void) | ||||
775 | { | ||||
776 | tree decls, *chain = NULLnullptr; | ||||
777 | |||||
778 | objc_v2_protocol_templateobjc_v2_global_trees[OCTI_V2_PROTO_TEMPL] = | ||||
779 | 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"))); | ||||
780 | |||||
781 | /* Class isa; */ | ||||
782 | decls = add_field_decl (objc_object_typeobjc_global_trees[OCTI_ID_TYPE], "isa", &chain); | ||||
783 | |||||
784 | /* char *protocol_name; */ | ||||
785 | add_field_decl (string_type_nodec_global_trees[CTI_STRING_TYPE], "protocol_name", &chain); | ||||
786 | |||||
787 | /* const struct protocol_list_t * const protocol_list; */ | ||||
788 | add_field_decl (build_pointer_type (objc_v2_protocol_templateobjc_v2_global_trees[OCTI_V2_PROTO_TEMPL]), | ||||
789 | "protocol_list", &chain); | ||||
790 | |||||
791 | /* const struct method_list_t * const instance_methods; */ | ||||
792 | add_field_decl (objc_method_proto_list_ptrobjc_global_trees[OCTI_METH_PROTO_LIST_TEMPL], "instance_methods", &chain); | ||||
793 | |||||
794 | /* const struct method_list_t * const class_methods; */ | ||||
795 | add_field_decl (objc_method_proto_list_ptrobjc_global_trees[OCTI_METH_PROTO_LIST_TEMPL], "class_methods", &chain); | ||||
796 | |||||
797 | /* const struct method_list_t * optionalInstanceMethods; */ | ||||
798 | add_field_decl (objc_method_proto_list_ptrobjc_global_trees[OCTI_METH_PROTO_LIST_TEMPL], "optionalInstanceMethods", &chain); | ||||
799 | |||||
800 | /* const struct method_list_t * optionalClassMethods; */ | ||||
801 | add_field_decl (objc_method_proto_list_ptrobjc_global_trees[OCTI_METH_PROTO_LIST_TEMPL], "optionalClassMethods", &chain); | ||||
802 | |||||
803 | /* struct _prop_list_t * properties; */ | ||||
804 | add_field_decl (objc_prop_list_ptrobjc_global_trees[OCTI_V1_PROP_LIST_TEMPL], "properties", &chain); | ||||
805 | |||||
806 | /* const uint32_t size; */ | ||||
807 | add_field_decl (integer_type_nodeinteger_types[itk_int], "size", &chain); | ||||
808 | |||||
809 | /* const uint32_t flags; */ | ||||
810 | add_field_decl (integer_type_nodeinteger_types[itk_int], "flags", &chain); | ||||
811 | |||||
812 | /* const char **extendedMethodTypes; */ | ||||
813 | tree ptr_to_ptr_to_char = build_pointer_type (string_type_nodec_global_trees[CTI_STRING_TYPE]); | ||||
814 | add_field_decl (ptr_to_ptr_to_char, "extended_method_types", &chain); | ||||
815 | |||||
816 | /* const char *demangledName; */ | ||||
817 | add_field_decl (string_type_nodec_global_trees[CTI_STRING_TYPE], "demangled_name", &chain); | ||||
818 | |||||
819 | /* const struct _prop_list_t *class_properties; */ | ||||
820 | add_field_decl (objc_prop_list_ptrobjc_global_trees[OCTI_V1_PROP_LIST_TEMPL], "class_properties", &chain); | ||||
821 | |||||
822 | objc_finish_struct (objc_v2_protocol_templateobjc_v2_global_trees[OCTI_V2_PROTO_TEMPL], decls); | ||||
823 | } | ||||
824 | |||||
825 | /* Build type for a category: | ||||
826 | struct category_t | ||||
827 | { | ||||
828 | const char * const name; | ||||
829 | struct class_t *const cls; | ||||
830 | const struct method_list_t * const instance_methods; | ||||
831 | const struct method_list_t * const class_methods; | ||||
832 | const struct protocol_list_t * const protocols; | ||||
833 | const struct _prop_list_t * const properties; | ||||
834 | } | ||||
835 | */ | ||||
836 | |||||
837 | static void | ||||
838 | build_v2_category_template (void) | ||||
839 | { | ||||
840 | tree decls, *chain = NULLnullptr; | ||||
841 | |||||
842 | objc_v2_category_templateobjc_v2_global_trees[OCTI_V2_CAT_TEMPL] = | ||||
843 | 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"))); | ||||
844 | |||||
845 | /* char *name; */ | ||||
846 | decls = add_field_decl (string_type_nodec_global_trees[CTI_STRING_TYPE], "name", &chain); | ||||
847 | |||||
848 | /* struct class_t *const cls; */ | ||||
849 | add_field_decl (build_pointer_type (objc_v2_class_templateobjc_v2_global_trees[OCTI_V2_CLS_TEMPL]), "cls", &chain); | ||||
850 | |||||
851 | /* struct method_list_t *instance_methods; */ | ||||
852 | add_field_decl (objc_method_list_ptrobjc_global_trees[OCTI_METH_LIST_TEMPL], "instance_methods", &chain); | ||||
853 | |||||
854 | /* struct method_list_t *class_methods; */ | ||||
855 | add_field_decl (objc_method_list_ptrobjc_global_trees[OCTI_METH_LIST_TEMPL], "class_methods", &chain); | ||||
856 | |||||
857 | /* struct protocol_list_t *protocol_list; */ | ||||
858 | add_field_decl (build_pointer_type (objc_v2_protocol_templateobjc_v2_global_trees[OCTI_V2_PROTO_TEMPL]), | ||||
859 | "protocol_list", &chain ); | ||||
860 | |||||
861 | /* struct _prop_list_t * properties; */ | ||||
862 | add_field_decl (objc_prop_list_ptrobjc_global_trees[OCTI_V1_PROP_LIST_TEMPL], "properties", &chain); | ||||
863 | |||||
864 | objc_finish_struct (objc_v2_category_templateobjc_v2_global_trees[OCTI_V2_CAT_TEMPL], decls); | ||||
865 | } | ||||
866 | |||||
867 | /* NOTE --- Decls, Identifiers, Names etc. --- */ | ||||
868 | |||||
869 | /* This routine is given a name and returns a matching extern variable | ||||
870 | if one is found. */ | ||||
871 | |||||
872 | static tree | ||||
873 | hash_name_lookup (hash *hashlist, tree name) | ||||
874 | { | ||||
875 | hash target; | ||||
876 | |||||
877 | target = hashlist[IDENTIFIER_HASH_VALUE (name)((tree_check ((name), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 877, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.hash_value ) % SIZEHASHTABLE257]; | ||||
878 | |||||
879 | while (target) | ||||
880 | { | ||||
881 | if (name == DECL_NAME (target->key)((contains_struct_check ((target->key), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 881, __FUNCTION__))->decl_minimal.name)) | ||||
882 | return target->key; | ||||
883 | |||||
884 | target = target->next; | ||||
885 | } | ||||
886 | return 0; | ||||
887 | } | ||||
888 | |||||
889 | /* This routine is given an extern variable and enters it in its hash | ||||
890 | table. Note that hashing is done on its inner IDENTIFIER_NODE | ||||
891 | node. */ | ||||
892 | |||||
893 | static void | ||||
894 | hash_name_enter (hash *hashlist, tree id) | ||||
895 | { | ||||
896 | hash obj; | ||||
897 | int slot = IDENTIFIER_HASH_VALUE (DECL_NAME (id))((tree_check ((((contains_struct_check ((id), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 897, __FUNCTION__))->decl_minimal.name)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 897, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.hash_value ) % SIZEHASHTABLE257; | ||||
898 | |||||
899 | obj = ggc_alloc<hashed_entry> (); | ||||
900 | obj->list = 0; | ||||
901 | obj->next = hashlist[slot]; | ||||
902 | obj->key = id; | ||||
903 | |||||
904 | hashlist[slot] = obj; /* append to front */ | ||||
905 | } | ||||
906 | |||||
907 | /* Create a declaration "extern <type> <name>;" | ||||
908 | The var will need to be finalized (e.g. by calling finish_var_decl()). */ | ||||
909 | |||||
910 | static tree | ||||
911 | create_extern_decl (tree type, const char *name) | ||||
912 | { | ||||
913 | tree id = get_identifier (name)(__builtin_constant_p (name) ? get_identifier_with_length ((name ), strlen (name)) : get_identifier (name)); | ||||
914 | tree var = hash_name_lookup (extern_names, id); | ||||
915 | if (var) | ||||
916 | return var; | ||||
917 | /* New name. */ | ||||
918 | var = start_var_decl (type, name); | ||||
919 | TREE_STATIC (var)((var)->base.static_flag) = 0; | ||||
920 | DECL_EXTERNAL (var)((contains_struct_check ((var), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 920, __FUNCTION__))->decl_common.decl_flag_1) = 1; | ||||
921 | TREE_PUBLIC (var)((var)->base.public_flag) = 1; | ||||
922 | hash_name_enter (extern_names, var); | ||||
923 | return var; | ||||
924 | } | ||||
925 | |||||
926 | /* Create a globally visible definition for variable NAME of a given TYPE. The | ||||
927 | finish_var_decl() routine will need to be called on it afterwards. */ | ||||
928 | static tree | ||||
929 | create_global_decl (tree type, const char *name, bool is_def = false); | ||||
930 | |||||
931 | static tree | ||||
932 | create_global_decl (tree type, const char *name, bool is_def) | ||||
933 | { | ||||
934 | tree id = get_identifier (name)(__builtin_constant_p (name) ? get_identifier_with_length ((name ), strlen (name)) : get_identifier (name)); | ||||
935 | tree var = hash_name_lookup (extern_names, id); | ||||
936 | if (var) | ||||
937 | is_def = true; | ||||
938 | else | ||||
939 | { | ||||
940 | var = start_var_decl (type, name); | ||||
941 | hash_name_enter (extern_names, var); | ||||
942 | } | ||||
943 | if (is_def) | ||||
944 | { | ||||
945 | DECL_EXTERNAL (var)((contains_struct_check ((var), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 945, __FUNCTION__))->decl_common.decl_flag_1) = 0; | ||||
946 | TREE_STATIC (var)((var)->base.static_flag) = 1; | ||||
947 | } | ||||
948 | TREE_PUBLIC (var)((var)->base.public_flag) = 1; | ||||
949 | return var; | ||||
950 | } | ||||
951 | |||||
952 | /* Create a symbol with __attribute__ ((visibility ("hidden"))) | ||||
953 | attribute (private extern). */ | ||||
954 | static tree | ||||
955 | create_hidden_decl (tree type, const char *name, bool is_def = false); | ||||
956 | |||||
957 | static tree | ||||
958 | create_hidden_decl (tree type, const char *name, bool is_def) | ||||
959 | { | ||||
960 | tree decl = create_global_decl (type, name, is_def); | ||||
961 | DECL_VISIBILITY (decl)((contains_struct_check ((decl), (TS_DECL_WITH_VIS), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 961, __FUNCTION__))->decl_with_vis.visibility) = VISIBILITY_HIDDEN; | ||||
962 | DECL_VISIBILITY_SPECIFIED (decl)((contains_struct_check ((decl), (TS_DECL_WITH_VIS), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 962, __FUNCTION__))->decl_with_vis.visibility_specified) = 1; | ||||
963 | return decl; | ||||
964 | } | ||||
965 | |||||
966 | /* Irritatingly, we have a different superclass field name for ABI=2. */ | ||||
967 | /* PS/TODO: The field name does not matter, it is only used internally | ||||
968 | by the compiler. We can rename it to whatever we want. ;-) */ | ||||
969 | |||||
970 | static tree | ||||
971 | next_runtime_abi_02_super_superclassfield_id (void) | ||||
972 | { | ||||
973 | /* TODO: Simplify. Just always return get_identifier ("cls"), or at | ||||
974 | most look it once at startup then always return it. */ | ||||
975 | if (!super_superclassfield_idobjc_global_trees[OCTI_SUPER_SUPERFIELD_ID]) | ||||
976 | 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")); | ||||
977 | return super_superclassfield_idobjc_global_trees[OCTI_SUPER_SUPERFIELD_ID]; | ||||
978 | } | ||||
979 | |||||
980 | static tree | ||||
981 | next_runtime_abi_02_class_decl (tree klass) | ||||
982 | { | ||||
983 | tree decl; | ||||
984 | char buf[BUFSIZE1024]; | ||||
985 | snprintf (buf, BUFSIZE1024, "OBJC_CLASS_$_%s", | ||||
986 | IDENTIFIER_POINTER (CLASS_NAME (klass))((const char *) (tree_check (((((tree_class_check ((klass), ( tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 986, __FUNCTION__))->type_common.name))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 986, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
987 | /* ObjC2 classes are extern visible. */ | ||||
988 | decl = create_global_decl (objc_v2_class_templateobjc_v2_global_trees[OCTI_V2_CLS_TEMPL], buf); | ||||
989 | OBJCMETA (decl, objc_meta, meta_class)if (objc_rt_trees[OCTI_RT_OBJC_META]) ((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 989, __FUNCTION__))->decl_common.attributes) = build_tree_list ((objc_rt_trees[OCTI_RT_OBJC_META]), (objc_rt_trees[OCTI_RT_META_CLASS ]));; | ||||
990 | return decl; | ||||
991 | } | ||||
992 | |||||
993 | static tree | ||||
994 | next_runtime_abi_02_metaclass_decl (tree klass) | ||||
995 | { | ||||
996 | tree decl; | ||||
997 | char buf[BUFSIZE1024]; | ||||
998 | snprintf (buf, BUFSIZE1024, "OBJC_METACLASS_$_%s", | ||||
999 | IDENTIFIER_POINTER (CLASS_NAME (klass))((const char *) (tree_check (((((tree_class_check ((klass), ( tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 999, __FUNCTION__))->type_common.name))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 999, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
1000 | /* ObjC2 classes are extern visible. */ | ||||
1001 | decl = create_global_decl (objc_v2_class_templateobjc_v2_global_trees[OCTI_V2_CLS_TEMPL], buf); | ||||
1002 | OBJCMETA (decl, objc_meta, meta_metaclass)if (objc_rt_trees[OCTI_RT_OBJC_META]) ((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1002, __FUNCTION__))->decl_common.attributes) = build_tree_list ((objc_rt_trees[OCTI_RT_OBJC_META]), (objc_rt_trees[OCTI_RT_META_METACLASS ]));; | ||||
1003 | return decl; | ||||
1004 | } | ||||
1005 | |||||
1006 | static tree | ||||
1007 | next_runtime_abi_02_category_decl (tree klass) | ||||
1008 | { | ||||
1009 | tree decl; | ||||
1010 | char buf[BUFSIZE1024]; | ||||
1011 | snprintf (buf, BUFSIZE1024, "_OBJC_Category_%s_%s", | ||||
1012 | IDENTIFIER_POINTER (CLASS_NAME (klass))((const char *) (tree_check (((((tree_class_check ((klass), ( tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1012, __FUNCTION__))->type_common.name))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1012, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ), | ||||
1013 | IDENTIFIER_POINTER (CLASS_SUPER_NAME (klass))((const char *) (tree_check (((((tree_class_check ((klass), ( tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1013, __FUNCTION__))->type_common.context))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1013, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
1014 | decl = start_var_decl (objc_v2_category_templateobjc_v2_global_trees[OCTI_V2_CAT_TEMPL], buf); | ||||
1015 | OBJCMETA (decl, objc_meta, meta_category)if (objc_rt_trees[OCTI_RT_OBJC_META]) ((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1015, __FUNCTION__))->decl_common.attributes) = build_tree_list ((objc_rt_trees[OCTI_RT_OBJC_META]), (objc_rt_trees[OCTI_RT_META_CATEGORY ]));; | ||||
1016 | return decl; | ||||
1017 | } | ||||
1018 | |||||
1019 | static tree | ||||
1020 | next_runtime_abi_02_protocol_decl (tree p) | ||||
1021 | { | ||||
1022 | tree decl; | ||||
1023 | char buf[BUFSIZE1024]; | ||||
1024 | |||||
1025 | /* static struct _objc_protocol _OBJC_Protocol_<mumble>; */ | ||||
1026 | snprintf (buf, BUFSIZE1024, "_OBJC_Protocol_%s", | ||||
1027 | IDENTIFIER_POINTER (PROTOCOL_NAME (p))((const char *) (tree_check (((((tree_class_check ((p), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1027, __FUNCTION__))->type_common.name))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1027, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
1028 | if (flag_next_runtimeglobal_options.x_flag_next_runtime >= USE_FIXUP_BEFORE100600) | ||||
1029 | { | ||||
1030 | decl = create_hidden_decl (objc_v2_protocol_templateobjc_v2_global_trees[OCTI_V2_PROTO_TEMPL], buf); | ||||
1031 | DECL_WEAK (decl)((contains_struct_check ((decl), (TS_DECL_WITH_VIS), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1031, __FUNCTION__))->decl_with_vis.weak_flag) = true; | ||||
1032 | } | ||||
1033 | else | ||||
1034 | decl = start_var_decl (objc_v2_protocol_templateobjc_v2_global_trees[OCTI_V2_PROTO_TEMPL], buf); | ||||
1035 | OBJCMETA (decl, objc_meta, meta_protocol)if (objc_rt_trees[OCTI_RT_OBJC_META]) ((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1035, __FUNCTION__))->decl_common.attributes) = build_tree_list ((objc_rt_trees[OCTI_RT_OBJC_META]), (objc_rt_trees[OCTI_RT_META_PROTOCOL ]));; | ||||
1036 | DECL_PRESERVE_P (decl)(contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1036, __FUNCTION__))->decl_common.preserve_flag = 1; | ||||
1037 | return decl; | ||||
1038 | } | ||||
1039 | |||||
1040 | static tree | ||||
1041 | next_runtime_abi_02_string_decl (tree type, const char *name, string_section where) | ||||
1042 | { | ||||
1043 | tree var = start_var_decl (type, name); | ||||
1044 | switch (where) | ||||
1045 | { | ||||
1046 | case class_names: | ||||
1047 | OBJCMETA (var, objc_meta, meta_class_name)if (objc_rt_trees[OCTI_RT_OBJC_META]) ((contains_struct_check ((var), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1047, __FUNCTION__))->decl_common.attributes) = build_tree_list ((objc_rt_trees[OCTI_RT_OBJC_META]), (objc_rt_trees[OCTI_RT_META_CLASS_NAME ]));; | ||||
1048 | break; | ||||
1049 | case meth_var_names: | ||||
1050 | OBJCMETA (var, objc_meta, meta_meth_name)if (objc_rt_trees[OCTI_RT_OBJC_META]) ((contains_struct_check ((var), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1050, __FUNCTION__))->decl_common.attributes) = build_tree_list ((objc_rt_trees[OCTI_RT_OBJC_META]), (objc_rt_trees[OCTI_RT_META_METHD_NAME ]));; | ||||
1051 | break; | ||||
1052 | case meth_var_types: | ||||
1053 | OBJCMETA (var, objc_meta, meta_meth_type)if (objc_rt_trees[OCTI_RT_OBJC_META]) ((contains_struct_check ((var), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1053, __FUNCTION__))->decl_common.attributes) = build_tree_list ((objc_rt_trees[OCTI_RT_OBJC_META]), (objc_rt_trees[OCTI_RT_META_METHD_TYPE ]));; | ||||
1054 | break; | ||||
1055 | case prop_names_attr: | ||||
1056 | OBJCMETA (var, objc_meta, meta_prop_name_attr)if (objc_rt_trees[OCTI_RT_OBJC_META]) ((contains_struct_check ((var), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1056, __FUNCTION__))->decl_common.attributes) = build_tree_list ((objc_rt_trees[OCTI_RT_OBJC_META]), (objc_rt_trees[OCTI_RT_META_PROPN_ATTR ]));; | ||||
1057 | break; | ||||
1058 | default: | ||||
1059 | OBJCMETA (var, objc_meta, meta_base)if (objc_rt_trees[OCTI_RT_OBJC_META]) ((contains_struct_check ((var), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1059, __FUNCTION__))->decl_common.attributes) = build_tree_list ((objc_rt_trees[OCTI_RT_OBJC_META]), (objc_rt_trees[OCTI_RT_META_BASE ]));; | ||||
1060 | break; | ||||
1061 | } | ||||
1062 | return var; | ||||
1063 | } | ||||
1064 | |||||
1065 | /* NOTE --- entry --- */ | ||||
1066 | |||||
1067 | struct GTY(()) ident_data_tuple { | ||||
1068 | tree ident; | ||||
1069 | tree data; | ||||
1070 | }; | ||||
1071 | |||||
1072 | /* This routine creates a file scope static variable of type 'Class' | ||||
1073 | to hold the address of a class. */ | ||||
1074 | |||||
1075 | static tree | ||||
1076 | build_v2_class_reference_decl (tree ident) | ||||
1077 | { | ||||
1078 | tree decl; | ||||
1079 | char buf[BUFSIZE1024]; | ||||
1080 | |||||
1081 | snprintf (buf, BUFSIZE1024, "_OBJC_ClassRef_%s", IDENTIFIER_POINTER (ident)((const char *) (tree_check ((ident), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1081, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
1082 | decl = start_var_decl (objc_class_typeobjc_global_trees[OCTI_CLS_TYPE], buf); | ||||
1083 | OBJCMETA (decl, objc_meta, meta_class_ref)if (objc_rt_trees[OCTI_RT_OBJC_META]) ((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1083, __FUNCTION__))->decl_common.attributes) = build_tree_list ((objc_rt_trees[OCTI_RT_OBJC_META]), (objc_rt_trees[OCTI_RT_META_CLSLST_REFS ]));; | ||||
1084 | return decl; | ||||
1085 | } | ||||
1086 | |||||
1087 | /* This routine builds a class refs entry for each class name used. | ||||
1088 | Initially, a (static-ref, IDENT) tuple is added to the list. The | ||||
1089 | ident is replaced with address of the class metadata (of type | ||||
1090 | 'Class') in the output routine. */ | ||||
1091 | |||||
1092 | static GTY (()) vec<ident_data_tuple, va_gc> *classrefs; | ||||
1093 | |||||
1094 | static tree | ||||
1095 | objc_v2_get_class_reference (tree ident) | ||||
1096 | { | ||||
1097 | tree decl; | ||||
1098 | ident_data_tuple e; | ||||
1099 | if (classrefs) | ||||
1100 | { | ||||
1101 | int count; | ||||
1102 | ident_data_tuple *ref; | ||||
1103 | FOR_EACH_VEC_ELT (*classrefs, count, ref)for (count = 0; (*classrefs).iterate ((count), &(ref)); ++ (count)) | ||||
1104 | { | ||||
1105 | if (ref->ident == ident) | ||||
1106 | { | ||||
1107 | if (!ref->data) | ||||
1108 | ref->data = build_v2_class_reference_decl (ident); | ||||
1109 | return ref->data; | ||||
1110 | } | ||||
1111 | } | ||||
1112 | } | ||||
1113 | else | ||||
1114 | /* Somewhat arbitrary initial provision. */ | ||||
1115 | vec_alloc (classrefs, 16); | ||||
1116 | |||||
1117 | /* We come here if we don't find the entry - or if the table was yet | ||||
1118 | to be created. */ | ||||
1119 | decl = build_v2_class_reference_decl (ident); | ||||
1120 | e.ident = ident; | ||||
1121 | e.data = decl; | ||||
1122 | vec_safe_push (classrefs, e); | ||||
1123 | return decl; | ||||
1124 | } | ||||
1125 | |||||
1126 | static tree | ||||
1127 | next_runtime_abi_02_get_class_reference (tree ident) | ||||
1128 | { | ||||
1129 | if (!flag_zero_linkglobal_options.x_flag_zero_link) | ||||
1130 | return objc_v2_get_class_reference (ident); | ||||
1131 | else | ||||
1132 | { | ||||
1133 | /* We fall back to using objc_getClass (). */ | ||||
1134 | vec<tree, va_gc> *v; | ||||
1135 | vec_alloc (v, 1); | ||||
1136 | tree t; | ||||
1137 | /* ??? add_class_reference (ident); - is pointless, since the | ||||
1138 | system lib does not export the equivalent symbols. Maybe we | ||||
1139 | need to build a class ref anyway. */ | ||||
1140 | t = my_build_string_pointer (IDENTIFIER_LENGTH (ident)((tree_check ((ident), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1140, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.len ) + 1, | ||||
1141 | IDENTIFIER_POINTER (ident)((const char *) (tree_check ((ident), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1141, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
1142 | v->quick_push (t); | ||||
1143 | t = build_function_call_vec (input_location, vNULL, objc_get_class_declobjc_global_trees[OCTI_GET_CLASS_DECL], | ||||
1144 | v, 0); | ||||
1145 | vec_free (v); | ||||
1146 | return t; | ||||
1147 | } | ||||
1148 | } | ||||
1149 | |||||
1150 | /* Used by build_function_type_for_method. Append the types for | ||||
1151 | receiver & _cmd at the start of a method argument list to ARGTYPES. | ||||
1152 | CONTEXT is either METHOD_DEF or METHOD_REF, saying whether we are | ||||
1153 | trying to define a method or call one. SUPERFLAG says this is for a | ||||
1154 | send to super. METH may be NULL, in the case that there is no | ||||
1155 | prototype. */ | ||||
1156 | |||||
1157 | static void | ||||
1158 | next_runtime_abi_02_get_arg_type_list_base (vec<tree, va_gc> **argtypes, | ||||
1159 | tree meth, int context, | ||||
1160 | int superflag) | ||||
1161 | { | ||||
1162 | tree receiver_type; | ||||
1163 | |||||
1164 | if (superflag) | ||||
1165 | receiver_type = objc_super_typeobjc_global_trees[OCTI_SUPER_TYPE]; | ||||
1166 | else if (context == METHOD_DEF0 && TREE_CODE (meth)((enum tree_code) (meth)->base.code) == INSTANCE_METHOD_DECL) | ||||
1167 | receiver_type = objc_instance_typeobjc_global_trees[OCTI_NST_TYPE]; | ||||
1168 | else | ||||
1169 | receiver_type = objc_object_typeobjc_global_trees[OCTI_ID_TYPE]; | ||||
1170 | |||||
1171 | vec_safe_push (*argtypes, receiver_type); | ||||
1172 | if (flag_next_runtimeglobal_options.x_flag_next_runtime < USE_FIXUP_BEFORE100600) | ||||
1173 | /* Selector type - will eventually change to `int'. */ | ||||
1174 | vec_safe_push (*argtypes, superflag ? objc_v2_super_selector_typeobjc_v2_global_trees[OCTI_V2_SUPER_MESSAGE_SELECTOR_TYPE] | ||||
1175 | : objc_v2_selector_typeobjc_v2_global_trees[OCTI_V2_MESSAGE_SELECTOR_TYPE]); | ||||
1176 | else | ||||
1177 | vec_safe_push (*argtypes, objc_selector_typeobjc_global_trees[OCTI_SEL_TYPE]); | ||||
1178 | } | ||||
1179 | |||||
1180 | /* TODO: Merge this with the message refs. */ | ||||
1181 | static tree | ||||
1182 | build_selector_reference_decl (tree ident) | ||||
1183 | { | ||||
1184 | tree decl; | ||||
1185 | char *t, buf[BUFSIZE1024]; | ||||
1186 | |||||
1187 | snprintf (buf, BUFSIZE1024, "_OBJC_SelRef_%s", IDENTIFIER_POINTER (ident)((const char *) (tree_check ((ident), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1187, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
1188 | t = buf; | ||||
1189 | while (*t) | ||||
1190 | { | ||||
1191 | if (*t==':') | ||||
1192 | *t = '$'; /* Underscore would clash between foo:bar and foo_bar. */ | ||||
1193 | t++; | ||||
1194 | } | ||||
1195 | decl = start_var_decl (objc_selector_typeobjc_global_trees[OCTI_SEL_TYPE], buf); | ||||
1196 | OBJCMETA (decl, objc_meta, meta_sel_refs)if (objc_rt_trees[OCTI_RT_OBJC_META]) ((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1196, __FUNCTION__))->decl_common.attributes) = build_tree_list ((objc_rt_trees[OCTI_RT_OBJC_META]), (objc_rt_trees[OCTI_RT_META_SEL_REFS ]));; | ||||
1197 | return decl; | ||||
1198 | } | ||||
1199 | |||||
1200 | static tree | ||||
1201 | next_runtime_abi_02_build_selector_reference (location_t loc ATTRIBUTE_UNUSED__attribute__ ((__unused__)), | ||||
1202 | tree ident, | ||||
1203 | tree proto ATTRIBUTE_UNUSED__attribute__ ((__unused__))) | ||||
1204 | { | ||||
1205 | tree *chain = &sel_ref_chainobjc_global_trees[OCTI_SEL_REF_CHAIN]; | ||||
1206 | tree expr; | ||||
1207 | |||||
1208 | while (*chain) | ||||
1209 | { | ||||
1210 | if (TREE_VALUE (*chain)((tree_check ((*chain), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1210, __FUNCTION__, (TREE_LIST)))->list.value) == ident) | ||||
1211 | return TREE_PURPOSE (*chain)((tree_check ((*chain), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1211, __FUNCTION__, (TREE_LIST)))->list.purpose); | ||||
1212 | |||||
1213 | chain = &TREE_CHAIN (*chain)((contains_struct_check ((*chain), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1213, __FUNCTION__))->common.chain); | ||||
1214 | } | ||||
1215 | |||||
1216 | expr = build_selector_reference_decl (ident); | ||||
1217 | *chain = tree_cons (expr, ident, NULL_TREE(tree) nullptr); | ||||
1218 | |||||
1219 | return expr; | ||||
1220 | } | ||||
1221 | |||||
1222 | /* Declare a variable of type 'struct message_ref_t'. */ | ||||
1223 | /* This will be finished in build_v2_message_ref_translation_table (). | ||||
1224 | We take an idea from LLVM in making the names a bit more connected | ||||
1225 | and thus the asm more readable. */ | ||||
1226 | |||||
1227 | static tree | ||||
1228 | build_v2_message_reference_decl (tree sel_name, tree message_func_ident) | ||||
1229 | { | ||||
1230 | tree decl; | ||||
1231 | char buf[BUFSIZE1024], *t; | ||||
1232 | int offset = 12; | ||||
1233 | |||||
1234 | /* Skip past the objc_msgSend it's the same for all... */ | ||||
1235 | if (IDENTIFIER_POINTER (message_func_ident)((const char *) (tree_check ((message_func_ident), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1235, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )[offset] == '_') | ||||
1236 | offset++; | ||||
1237 | |||||
1238 | snprintf (buf, BUFSIZE1024, "_OBJC_MsgRef_%s_%s", | ||||
1239 | &(IDENTIFIER_POINTER (message_func_ident)((const char *) (tree_check ((message_func_ident), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1239, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )[offset]), | ||||
1240 | IDENTIFIER_POINTER (sel_name)((const char *) (tree_check ((sel_name), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1240, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
1241 | t = buf; | ||||
1242 | while (*t) | ||||
1243 | { | ||||
1244 | if (*t==':') | ||||
1245 | *t = '$'; /* Underscore would clash between foo:bar and foo_bar. */ | ||||
1246 | t++; | ||||
1247 | } | ||||
1248 | decl = start_var_decl (objc_v2_message_ref_templateobjc_v2_global_trees[OCTI_V2_MESSAGE_REF_TEMPL], buf); | ||||
1249 | OBJCMETA (decl, objc_meta, meta_mref)if (objc_rt_trees[OCTI_RT_OBJC_META]) ((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1249, __FUNCTION__))->decl_common.attributes) = build_tree_list ((objc_rt_trees[OCTI_RT_OBJC_META]), (objc_rt_trees[OCTI_RT_META_MSG_REFS ]));; | ||||
1250 | return decl; | ||||
1251 | } | ||||
1252 | |||||
1253 | struct GTY(()) msgref_entry { | ||||
1254 | tree func; | ||||
1255 | tree selname; | ||||
1256 | tree refdecl; | ||||
1257 | }; | ||||
1258 | |||||
1259 | static GTY (()) vec<msgref_entry, va_gc> *msgrefs; | ||||
1260 | |||||
1261 | /* Build the list of (objc_msgSend_fixup_xxx, selector name), used | ||||
1262 | later on to initialize the table of 'struct message_ref_t' | ||||
1263 | elements. */ | ||||
1264 | |||||
1265 | static tree | ||||
1266 | build_v2_selector_messenger_reference (tree sel_name, tree message_func_decl) | ||||
1267 | { | ||||
1268 | tree decl; | ||||
1269 | msgref_entry e; | ||||
1270 | if (msgrefs) | ||||
1271 | { | ||||
1272 | int count; | ||||
1273 | msgref_entry *ref; | ||||
1274 | FOR_EACH_VEC_ELT (*msgrefs, count, ref)for (count = 0; (*msgrefs).iterate ((count), &(ref)); ++( count)) | ||||
1275 | if (ref->func == message_func_decl && ref->selname == sel_name) | ||||
1276 | return ref->refdecl; | ||||
1277 | } | ||||
1278 | else | ||||
1279 | /* Somewhat arbitrary initial provision. */ | ||||
1280 | vec_alloc (msgrefs, 32); | ||||
1281 | |||||
1282 | /* We come here if we don't find a match or at the start. */ | ||||
1283 | decl = build_v2_message_reference_decl (sel_name, | ||||
1284 | DECL_NAME (message_func_decl)((contains_struct_check ((message_func_decl), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1284, __FUNCTION__))->decl_minimal.name)); | ||||
1285 | e.func = message_func_decl; | ||||
1286 | e.selname = sel_name; | ||||
1287 | e.refdecl = decl; | ||||
1288 | vec_safe_push (msgrefs, e); | ||||
1289 | return decl; | ||||
1290 | } | ||||
1291 | |||||
1292 | static tree | ||||
1293 | build_v2_protocollist_ref_decl (tree protocol) | ||||
1294 | { | ||||
1295 | tree decl; | ||||
1296 | tree protocol_ident = PROTOCOL_NAME (protocol)(((tree_class_check ((protocol), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1296, __FUNCTION__))->type_common.name)); | ||||
1297 | char buf[BUFSIZE1024]; | ||||
1298 | |||||
1299 | snprintf (buf, BUFSIZE1024, "_OBJC_ProtocolRef_%s", | ||||
1300 | IDENTIFIER_POINTER (protocol_ident)((const char *) (tree_check ((protocol_ident), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1300, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
1301 | /* TODO: other compiler versions make these hidden & weak. */ | ||||
1302 | decl = create_global_decl (objc_protocol_typeobjc_global_trees[OCTI_PROTO_TYPE], buf); | ||||
1303 | /* Let optimizer know that this decl is not removable. */ | ||||
1304 | DECL_PRESERVE_P (decl)(contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1304, __FUNCTION__))->decl_common.preserve_flag = 1; | ||||
1305 | OBJCMETA (decl, objc_meta, meta_proto_ref)if (objc_rt_trees[OCTI_RT_OBJC_META]) ((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1305, __FUNCTION__))->decl_common.attributes) = build_tree_list ((objc_rt_trees[OCTI_RT_OBJC_META]), (objc_rt_trees[OCTI_RT_META_PROT_REFS ]));; | ||||
1306 | return decl; | ||||
1307 | } | ||||
1308 | |||||
1309 | struct GTY(()) prot_list_entry { | ||||
1310 | tree id; | ||||
1311 | tree refdecl; | ||||
1312 | }; | ||||
1313 | static GTY (()) vec<prot_list_entry, va_gc> *protrefs; | ||||
1314 | |||||
1315 | static tree | ||||
1316 | objc_v2_get_protocol_reference (tree ident) | ||||
1317 | { | ||||
1318 | tree decl; | ||||
1319 | prot_list_entry e; | ||||
1320 | if (protrefs) | ||||
1321 | { | ||||
1322 | int count; | ||||
1323 | prot_list_entry *ref; | ||||
1324 | FOR_EACH_VEC_ELT (*protrefs, count, ref)for (count = 0; (*protrefs).iterate ((count), &(ref)); ++ (count)) | ||||
1325 | { | ||||
1326 | if (ref->id == ident) | ||||
1327 | { | ||||
1328 | if (!ref->refdecl) | ||||
1329 | ref->refdecl = build_v2_protocollist_ref_decl (ident); | ||||
1330 | return ref->refdecl; | ||||
1331 | } | ||||
1332 | } | ||||
1333 | } | ||||
1334 | else | ||||
1335 | /* Somewhat arbitrary initial provision. */ | ||||
1336 | vec_alloc (protrefs, 32); | ||||
1337 | |||||
1338 | /* We come here if we don't find the entry - or if the table was yet | ||||
1339 | to be created. */ | ||||
1340 | decl = build_v2_protocollist_ref_decl (ident); | ||||
1341 | e.id = ident; | ||||
1342 | e.refdecl = decl; | ||||
1343 | vec_safe_push (protrefs, e); | ||||
1344 | return decl; | ||||
1345 | } | ||||
1346 | |||||
1347 | static tree | ||||
1348 | next_runtime_abi_02_get_protocol_reference (location_t loc ATTRIBUTE_UNUSED__attribute__ ((__unused__)), | ||||
1349 | tree p) | ||||
1350 | { | ||||
1351 | if (!PROTOCOL_FORWARD_DECL (p)(*((const_cast<tree *> (tree_vec_elt_check ((((tree_class_check ((p), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1351, __FUNCTION__))->type_non_common.lang_1)), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1351, __FUNCTION__)))))) | ||||
1352 | PROTOCOL_FORWARD_DECL (p)(*((const_cast<tree *> (tree_vec_elt_check ((((tree_class_check ((p), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1352, __FUNCTION__))->type_non_common.lang_1)), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1352, __FUNCTION__))))) = next_runtime_abi_02_protocol_decl (p); | ||||
1353 | |||||
1354 | return objc_v2_get_protocol_reference (p); | ||||
1355 | } | ||||
1356 | |||||
1357 | /* This routine returns the ivar declaration, if component is a valid | ||||
1358 | ivar field; NULL_TREE otherwise. On finding an ivar, it also | ||||
1359 | returns the class name in CLASS. */ | ||||
1360 | |||||
1361 | static tree | ||||
1362 | objc_is_ivar (tree expr, tree component, tree *klass) | ||||
1363 | { | ||||
1364 | tree field = NULL_TREE(tree) nullptr; | ||||
1365 | tree basetype = TYPE_MAIN_VARIANT (TREE_TYPE (expr))((tree_class_check ((((contains_struct_check ((expr), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1365, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1365, __FUNCTION__))->type_common.main_variant); | ||||
1366 | |||||
1367 | if (TREE_CODE (basetype)((enum tree_code) (basetype)->base.code) == RECORD_TYPE | ||||
1368 | && TYPE_HAS_OBJC_INFO (basetype)(((tree_class_check ((basetype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1368, __FUNCTION__))->type_with_lang_specific.lang_specific ) && ((tree_class_check ((basetype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1368, __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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1368, __FUNCTION__))->type_with_lang_specific.lang_specific )->objc_info), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1368, __FUNCTION__)))))) | ||||
1369 | { | ||||
1370 | *klass = lookup_interface (OBJC_TYPE_NAME (basetype)((tree_class_check ((basetype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1370, __FUNCTION__))->type_common.name)); | ||||
1371 | if (*klass) | ||||
1372 | { | ||||
1373 | do | ||||
1374 | { | ||||
1375 | tree ivar_chain = CLASS_RAW_IVARS (*klass)(*((const_cast<tree *> (tree_vec_elt_check ((((tree_class_check ((*klass), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1375, __FUNCTION__))->type_non_common.lang_1)), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1375, __FUNCTION__))))); | ||||
1376 | if (ivar_chain) | ||||
1377 | { | ||||
1378 | field = is_ivar (ivar_chain, component); | ||||
1379 | if (field != NULL_TREE(tree) nullptr) | ||||
1380 | break; | ||||
1381 | } | ||||
1382 | *klass = lookup_interface (CLASS_SUPER_NAME (*klass)(((tree_class_check ((*klass), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1382, __FUNCTION__))->type_common.context))); | ||||
1383 | } | ||||
1384 | while (*klass); | ||||
1385 | } | ||||
1386 | } | ||||
1387 | return field; | ||||
1388 | } | ||||
1389 | |||||
1390 | static void | ||||
1391 | create_ivar_offset_name (char *buf, tree class_name, tree field_decl) | ||||
1392 | { | ||||
1393 | tree fname = DECL_NAME (field_decl)((contains_struct_check ((field_decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1393, __FUNCTION__))->decl_minimal.name); | ||||
1394 | |||||
1395 | sprintf (buf, "OBJC_IVAR_$_%s.%s", IDENTIFIER_POINTER (class_name)((const char *) (tree_check ((class_name), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1395, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ), | ||||
1396 | IDENTIFIER_POINTER (fname)((const char *) (tree_check ((fname), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1396, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
1397 | return; | ||||
1398 | } | ||||
1399 | |||||
1400 | /* This routine generates new abi's ivar reference tree. It amounts | ||||
1401 | to generating *(TYPE*)((char*)pObj + OFFSET_IVAR) when we normally | ||||
1402 | generate pObj->IVAR. OFFSET_IVAR is an 'extern' variable holding | ||||
1403 | the offset for 'IVAR' field. TYPE is type of IVAR field. */ | ||||
1404 | |||||
1405 | static tree | ||||
1406 | objc_v2_build_ivar_ref (tree datum, tree component) | ||||
1407 | { | ||||
1408 | tree field, ref, class_name, offset, ftype, expr; | ||||
1409 | char var_offset_name[512]; | ||||
1410 | |||||
1411 | field = objc_is_ivar (datum, component, &class_name); | ||||
1412 | if (!field) | ||||
1413 | return NULL_TREE(tree) nullptr; | ||||
1414 | |||||
1415 | /* This routine only handles non-bitfield fields */ | ||||
1416 | if (DECL_C_BIT_FIELD (field)(((contains_struct_check (((tree_check ((field), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1416, __FUNCTION__, (FIELD_DECL)))), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1416, __FUNCTION__))->decl_common.lang_flag_4) == 1)) | ||||
1417 | return NULL_TREE(tree) nullptr; | ||||
1418 | |||||
1419 | create_ivar_offset_name (var_offset_name, CLASS_NAME (class_name)(((tree_class_check ((class_name), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1419, __FUNCTION__))->type_common.name)), field); | ||||
1420 | |||||
1421 | offset = create_extern_decl (TREE_TYPE (size_zero_node)((contains_struct_check ((global_trees[TI_SIZE_ZERO]), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1421, __FUNCTION__))->typed.type), var_offset_name); | ||||
1422 | |||||
1423 | ftype = TREE_TYPE (field)((contains_struct_check ((field), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1423, __FUNCTION__))->typed.type); | ||||
1424 | |||||
1425 | /* (char*)datum */ | ||||
1426 | expr = build_c_cast (input_location, | ||||
1427 | string_type_nodec_global_trees[CTI_STRING_TYPE], build_fold_addr_expr (datum)build_fold_addr_expr_loc (((location_t) 0), (datum))); | ||||
1428 | |||||
1429 | /* (char*)datum + offset */ | ||||
1430 | expr = fold_build_pointer_plus_loc (input_location, expr, offset); | ||||
1431 | |||||
1432 | /* (ftype*)((char*)datum + offset) */ | ||||
1433 | expr = build_c_cast (input_location, build_pointer_type (ftype), expr); | ||||
1434 | |||||
1435 | /* Finally: *(ftype*)((char*)datum + offset) */ | ||||
1436 | ref = build_indirect_ref (input_location, expr, RO_UNARY_STAR); | ||||
1437 | |||||
1438 | /* We must set type of the resulting expression to be the same as | ||||
1439 | the field type. This is because, build_indirect_ref (...) | ||||
1440 | rebuilds the type which may result in lost information; as in the | ||||
1441 | case of protocol-qualified types (id <protocol> ). */ | ||||
1442 | TREE_TYPE (ref)((contains_struct_check ((ref), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1442, __FUNCTION__))->typed.type) = ftype; | ||||
1443 | |||||
1444 | if (TREE_READONLY (datum)((non_type_check ((datum), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1444, __FUNCTION__))->base.readonly_flag) || TREE_READONLY (field)((non_type_check ((field), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1444, __FUNCTION__))->base.readonly_flag)) | ||||
1445 | TREE_READONLY (ref)((non_type_check ((ref), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1445, __FUNCTION__))->base.readonly_flag) = 1; | ||||
1446 | |||||
1447 | if (TREE_THIS_VOLATILE (datum)((datum)->base.volatile_flag) || TREE_THIS_VOLATILE (field)((field)->base.volatile_flag)) | ||||
1448 | TREE_THIS_VOLATILE (ref)((ref)->base.volatile_flag) = 1; | ||||
1449 | |||||
1450 | if (TREE_DEPRECATED (field)((field)->base.deprecated_flag)) | ||||
1451 | warn_deprecated_use (field, NULL_TREE(tree) nullptr); | ||||
1452 | |||||
1453 | return ref; | ||||
1454 | } | ||||
1455 | |||||
1456 | /* IVAR refs are made via an externally referenceable offset and built | ||||
1457 | on the fly. That is, unless they refer to (private) fields in the | ||||
1458 | class structure. */ | ||||
1459 | static tree | ||||
1460 | next_runtime_abi_02_build_ivar_ref (location_t loc ATTRIBUTE_UNUSED__attribute__ ((__unused__)), | ||||
1461 | tree base, tree id) | ||||
1462 | { | ||||
1463 | tree ivar; | ||||
1464 | if ((ivar = objc_v2_build_ivar_ref (base, id))) | ||||
1465 | return ivar; | ||||
1466 | return objc_build_component_ref (base, id); | ||||
1467 | } | ||||
1468 | |||||
1469 | /* [super ...] references are listed here (and built into a table at | ||||
1470 | meta -data emit time). */ | ||||
1471 | static tree | ||||
1472 | build_v2_superclass_ref_decl (tree ident, bool inst) | ||||
1473 | { | ||||
1474 | tree decl; | ||||
1475 | char buf[BUFSIZE1024]; | ||||
1476 | |||||
1477 | snprintf (buf, BUFSIZE1024, "_OBJC_%sSuperRef_%s", (inst?"":"Meta"), | ||||
1478 | IDENTIFIER_POINTER (ident)((const char *) (tree_check ((ident), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1478, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
1479 | decl = start_var_decl (objc_class_typeobjc_global_trees[OCTI_CLS_TYPE], buf); | ||||
1480 | OBJCMETA (decl, objc_meta, meta_superclass_ref)if (objc_rt_trees[OCTI_RT_OBJC_META]) ((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1480, __FUNCTION__))->decl_common.attributes) = build_tree_list ((objc_rt_trees[OCTI_RT_OBJC_META]), (objc_rt_trees[OCTI_RT_META_SUPER_REF ]));; | ||||
1481 | return decl; | ||||
1482 | } | ||||
1483 | |||||
1484 | static GTY (()) vec<ident_data_tuple, va_gc> *class_super_refs; | ||||
1485 | static GTY (()) vec<ident_data_tuple, va_gc> *metaclass_super_refs; | ||||
1486 | |||||
1487 | /* Find or build a superclass reference decl for class NAME. */ | ||||
1488 | |||||
1489 | static tree | ||||
1490 | objc_get_superclass_ref_decl (tree name, bool inst_meth) | ||||
1491 | { | ||||
1492 | tree decl; | ||||
1493 | vec<ident_data_tuple, va_gc> *list = inst_meth ? class_super_refs | ||||
1494 | : metaclass_super_refs; | ||||
1495 | |||||
1496 | if (list) | ||||
1497 | { | ||||
1498 | int count; | ||||
1499 | ident_data_tuple *ref; | ||||
1500 | FOR_EACH_VEC_ELT (*list, count, ref)for (count = 0; (*list).iterate ((count), &(ref)); ++(count )) | ||||
1501 | { | ||||
1502 | if (ref->ident == name) | ||||
1503 | { | ||||
1504 | if (!ref->data) | ||||
1505 | ref->data = build_v2_superclass_ref_decl (name, inst_meth); | ||||
1506 | return ref->data; | ||||
1507 | } | ||||
1508 | } | ||||
1509 | } | ||||
1510 | else | ||||
1511 | { | ||||
1512 | /* Somewhat arbitrary initial provision. */ | ||||
1513 | if (inst_meth) | ||||
1514 | { | ||||
1515 | vec_alloc (class_super_refs, 16); | ||||
1516 | list = class_super_refs; | ||||
1517 | } | ||||
1518 | else | ||||
1519 | { | ||||
1520 | vec_alloc (metaclass_super_refs, 16); | ||||
1521 | list = metaclass_super_refs; | ||||
1522 | } | ||||
1523 | } | ||||
1524 | /* We come here if we don't find the entry - or if the table was yet | ||||
1525 | to be created. */ | ||||
1526 | decl = build_v2_superclass_ref_decl (name, inst_meth); | ||||
1527 | ident_data_tuple e; | ||||
1528 | e.ident = name; | ||||
1529 | e.data = decl; | ||||
1530 | vec_safe_push (list, e); | ||||
1531 | return decl; | ||||
1532 | } | ||||
1533 | |||||
1534 | /* Get a reference to the superclass for IMP. */ | ||||
1535 | |||||
1536 | static tree | ||||
1537 | next_runtime_abi_02_get_class_super_ref (location_t loc ATTRIBUTE_UNUSED__attribute__ ((__unused__)), | ||||
1538 | struct imp_entry *imp, bool inst_meth) | ||||
1539 | { | ||||
1540 | tree name = CLASS_NAME (imp->imp_context)(((tree_class_check ((imp->imp_context), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1540, __FUNCTION__))->type_common.name)); | ||||
1541 | return objc_get_superclass_ref_decl (name, inst_meth); | ||||
1542 | } | ||||
1543 | |||||
1544 | /* Get a reference to the superclass for category IMP. */ | ||||
1545 | |||||
1546 | static tree | ||||
1547 | next_runtime_abi_02_get_category_super_ref (location_t loc ATTRIBUTE_UNUSED__attribute__ ((__unused__)), | ||||
1548 | struct imp_entry *imp, | ||||
1549 | bool inst_meth) | ||||
1550 | { | ||||
1551 | if (flag_zero_linkglobal_options.x_flag_zero_link) | ||||
1552 | { | ||||
1553 | /* Do it the slow way. */ | ||||
1554 | tree get_cl_fn = inst_meth ? objc_get_class_declobjc_global_trees[OCTI_GET_CLASS_DECL] | ||||
1555 | : objc_get_meta_class_declobjc_global_trees[OCTI_GET_MCLASS_DECL]; | ||||
1556 | tree super_name = CLASS_SUPER_NAME (imp->imp_template)(((tree_class_check ((imp->imp_template), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1556, __FUNCTION__))->type_common.context)); | ||||
1557 | super_name = my_build_string_pointer (IDENTIFIER_LENGTH (super_name)((tree_check ((super_name), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1557, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.len ) + 1, | ||||
1558 | IDENTIFIER_POINTER (super_name)((const char *) (tree_check ((super_name), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1558, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
1559 | /* super_class = objc_get{Meta}Class("CLASS_SUPER_NAME"); */ | ||||
1560 | return build_function_call (input_location, get_cl_fn, | ||||
1561 | build_tree_list (NULL_TREE(tree) nullptr, super_name)); | ||||
1562 | } | ||||
1563 | |||||
1564 | /* This is the 'usual' path. */ | ||||
1565 | tree cls_name = CLASS_NAME (imp->imp_template)(((tree_class_check ((imp->imp_template), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1565, __FUNCTION__))->type_common.name)); | ||||
1566 | if (!inst_meth) | ||||
1567 | return objc_get_superclass_ref_decl (cls_name, inst_meth); | ||||
1568 | return objc_get_class_reference (cls_name); | ||||
1569 | } | ||||
1570 | |||||
1571 | static tree | ||||
1572 | next_runtime_abi_02_receiver_is_class_object (tree receiver) | ||||
1573 | { | ||||
1574 | if (TREE_CODE (receiver)((enum tree_code) (receiver)->base.code) == VAR_DECL | ||||
1575 | && IS_CLASS (TREE_TYPE (receiver))(((enum tree_code) (((contains_struct_check ((receiver), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1575, __FUNCTION__))->typed.type))->base.code) == POINTER_TYPE && (((tree_class_check ((((contains_struct_check ((( (contains_struct_check ((receiver), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1575, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1575, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1575, __FUNCTION__))->type_common.main_variant) == ((contains_struct_check ((objc_global_trees[OCTI_CLS_TYPE]), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1575, __FUNCTION__))->typed.type))) | ||||
1576 | && vec_safe_length (classrefs)) | ||||
1577 | { | ||||
1578 | int count; | ||||
1579 | ident_data_tuple *ref; | ||||
1580 | /* The receiver is a variable created by build_class_reference_decl. */ | ||||
1581 | FOR_EACH_VEC_ELT (*classrefs, count, ref)for (count = 0; (*classrefs).iterate ((count), &(ref)); ++ (count)) | ||||
1582 | if (ref->data == receiver) | ||||
1583 | return ref->ident; | ||||
1584 | } | ||||
1585 | return NULL_TREE(tree) nullptr; | ||||
1586 | } | ||||
1587 | |||||
1588 | /* Assign all arguments in VALUES which have side-effect to a temporary | ||||
1589 | and replaced that argument in VALUES list with the temporary. The | ||||
1590 | arguments will be passed to a function with FNTYPE. */ | ||||
1591 | |||||
1592 | static tree | ||||
1593 | objc_copy_to_temp_side_effect_params (tree fntype, tree values) | ||||
1594 | { | ||||
1595 | tree valtail; | ||||
1596 | function_args_iterator iter; | ||||
1597 | |||||
1598 | /* Skip over receiver and the &_msf_ref types. */ | ||||
1599 | function_args_iter_init (&iter, fntype); | ||||
1600 | function_args_iter_next (&iter); | ||||
1601 | function_args_iter_next (&iter); | ||||
1602 | |||||
1603 | for (valtail = values; valtail; | ||||
1604 | valtail = TREE_CHAIN (valtail)((contains_struct_check ((valtail), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1604, __FUNCTION__))->common.chain), function_args_iter_next (&iter)) | ||||
1605 | { | ||||
1606 | tree value = TREE_VALUE (valtail)((tree_check ((valtail), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1606, __FUNCTION__, (TREE_LIST)))->list.value); | ||||
1607 | tree type = function_args_iter_cond (&iter); | ||||
1608 | if (type == NULL_TREE(tree) nullptr) | ||||
1609 | break; | ||||
1610 | if (!TREE_SIDE_EFFECTS (value)((non_type_check ((value), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1610, __FUNCTION__))->base.side_effects_flag)) | ||||
1611 | continue; | ||||
1612 | /* To prevent re-evaluation. */ | ||||
1613 | value = save_expr (value); | ||||
1614 | add_stmt (value); | ||||
1615 | TREE_VALUE (valtail)((tree_check ((valtail), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1615, __FUNCTION__, (TREE_LIST)))->list.value) = value; | ||||
1616 | } | ||||
1617 | return values; | ||||
1618 | } | ||||
1619 | |||||
1620 | /* Build the new abi's messaging library call. It looks like: | ||||
1621 | (*_msg.messenger) (receiver, &_msg, ...) */ | ||||
1622 | |||||
1623 | static tree | ||||
1624 | build_v2_objc_method_fixup_call (int super_flag, tree method_prototype, | ||||
1625 | tree lookup_object, tree selector, | ||||
1626 | tree method_params, bool check_for_nil) | ||||
1627 | { | ||||
1628 | tree ret_val; | ||||
1629 | tree sender, rcv_p, t; | ||||
1630 | tree ret_type | ||||
1631 | = (method_prototype | ||||
1632 | ? TREE_VALUE (TREE_TYPE (method_prototype))((tree_check ((((contains_struct_check ((method_prototype), ( TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1632, __FUNCTION__))->typed.type)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1632, __FUNCTION__, (TREE_LIST)))->list.value) | ||||
1633 | : objc_object_typeobjc_global_trees[OCTI_ID_TYPE]); | ||||
1634 | tree ftype = build_function_type_for_method (ret_type, method_prototype, | ||||
1635 | METHOD_REF1, super_flag); | ||||
1636 | tree sender_cast; | ||||
1637 | |||||
1638 | if (method_prototype && METHOD_TYPE_ATTRIBUTES (method_prototype)((tree_check2 ((method_prototype), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1638, __FUNCTION__, (INSTANCE_METHOD_DECL), (CLASS_METHOD_DECL )))->decl_common.abstract_origin)) | ||||
1639 | ftype = build_type_attribute_variant ( | ||||
1640 | ftype, METHOD_TYPE_ATTRIBUTES (method_prototype)((tree_check2 ((method_prototype), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1640, __FUNCTION__, (INSTANCE_METHOD_DECL), (CLASS_METHOD_DECL )))->decl_common.abstract_origin)); | ||||
1641 | |||||
1642 | sender_cast = build_pointer_type (ftype); | ||||
1643 | |||||
1644 | if (check_for_nil) | ||||
1645 | method_params = objc_copy_to_temp_side_effect_params (ftype, | ||||
1646 | method_params); | ||||
1647 | |||||
1648 | /* Get &message_ref_t.messenger. */ | ||||
1649 | sender = build_c_cast (input_location, | ||||
1650 | build_pointer_type (super_flag | ||||
1651 | ? objc_v2_super_imp_typeobjc_v2_global_trees[OCTI_V2_SUPER_IMP_TYPE] | ||||
1652 | : objc_v2_imp_typeobjc_v2_global_trees[OCTI_V2_IMP_TYPE]), | ||||
1653 | selector); | ||||
1654 | |||||
1655 | sender = build_indirect_ref (input_location, sender, RO_UNARY_STAR); | ||||
1656 | |||||
1657 | rcv_p = (super_flag ? objc_super_typeobjc_global_trees[OCTI_SUPER_TYPE] : objc_object_typeobjc_global_trees[OCTI_ID_TYPE]); | ||||
1658 | |||||
1659 | lookup_object = build_c_cast (input_location, rcv_p, lookup_object); | ||||
1660 | |||||
1661 | /* Use SAVE_EXPR to avoid evaluating the receiver twice. */ | ||||
1662 | lookup_object = save_expr (lookup_object); | ||||
1663 | |||||
1664 | method_params = tree_cons (NULL_TREE(tree) nullptr, lookup_object, | ||||
1665 | tree_cons (NULL_TREE(tree) nullptr, selector, | ||||
1666 | method_params)); | ||||
1667 | t = build3 (OBJ_TYPE_REF, sender_cast, sender, lookup_object, | ||||
1668 | build_int_cst (TREE_TYPE (lookup_object)((contains_struct_check ((lookup_object), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1668, __FUNCTION__))->typed.type), 0)); | ||||
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 | /* An empty constructor is zero-filled by the middle end. */ | ||||
1679 | ftree = objc_build_constructor (ret_type, NULLnullptr); | ||||
1680 | else | ||||
1681 | ftree = fold_convert (ret_type, integer_zero_node)fold_convert_loc (((location_t) 0), ret_type, global_trees[TI_INTEGER_ZERO ]); | ||||
1682 | |||||
1683 | ifexp = build_binary_op (input_location, NE_EXPR, | ||||
1684 | lookup_object, | ||||
1685 | fold_convert (rcv_p, integer_zero_node)fold_convert_loc (((location_t) 0), rcv_p, global_trees[TI_INTEGER_ZERO ]), 1); | ||||
1686 | |||||
1687 | #ifdef OBJCPLUS | ||||
1688 | ret_val = build_conditional_expr (input_location, | ||||
1689 | ifexp, ret_val, ftree, | ||||
1690 | tf_warning_or_error); | ||||
1691 | #else | ||||
1692 | ret_val = build_conditional_expr (input_location, | ||||
1693 | ifexp, 0, | ||||
1694 | ret_val, NULL_TREE(tree) nullptr, input_location, | ||||
1695 | ftree, NULL_TREE(tree) nullptr, input_location); | ||||
1696 | ret_val = fold_convert (ret_type, ret_val)fold_convert_loc (((location_t) 0), ret_type, ret_val); | ||||
1697 | #endif | ||||
1698 | } | ||||
1699 | return ret_val; | ||||
1700 | } | ||||
1701 | |||||
1702 | static tree | ||||
1703 | build_v2_build_objc_method_call (int super, tree method_prototype, | ||||
1704 | tree lookup_object, tree selector, | ||||
1705 | tree method_params, location_t loc, | ||||
1706 | bool check_for_nil, bool rx_is_id) | ||||
1707 | { | ||||
1708 | tree sender, sender_cast, method, t; | ||||
1709 | tree rcv_p = (super
| ||||
1710 | vec<tree, va_gc> *parms; | ||||
1711 | unsigned nparm = (method_params ? list_length (method_params) : 0); | ||||
1712 | |||||
1713 | /* If a prototype for the method to be called exists, then cast | ||||
1714 | the sender's return type and arguments to match that of the method. | ||||
1715 | Otherwise, leave sender as is. */ | ||||
1716 | tree ret_type | ||||
1717 | = (method_prototype | ||||
1718 | ? TREE_VALUE (TREE_TYPE (method_prototype))((tree_check ((((contains_struct_check ((method_prototype), ( TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1718, __FUNCTION__))->typed.type)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1718, __FUNCTION__, (TREE_LIST)))->list.value) | ||||
1719 | : objc_object_typeobjc_global_trees[OCTI_ID_TYPE]); | ||||
1720 | tree ftype = build_function_type_for_method (ret_type, method_prototype, | ||||
1721 | METHOD_REF1, super); | ||||
1722 | |||||
1723 | if (method_prototype
, 1723, __FUNCTION__, (INSTANCE_METHOD_DECL), (CLASS_METHOD_DECL )))->decl_common.abstract_origin)) | ||||
1724 | ftype = build_type_attribute_variant (ftype, | ||||
1725 | METHOD_TYPE_ATTRIBUTES((tree_check2 ((method_prototype), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1726, __FUNCTION__, (INSTANCE_METHOD_DECL), (CLASS_METHOD_DECL )))->decl_common.abstract_origin) | ||||
1726 | (method_prototype)((tree_check2 ((method_prototype), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1726, __FUNCTION__, (INSTANCE_METHOD_DECL), (CLASS_METHOD_DECL )))->decl_common.abstract_origin)); | ||||
1727 | |||||
1728 | sender_cast = build_pointer_type (ftype); | ||||
1729 | |||||
1730 | lookup_object = build_c_cast (loc, rcv_p, lookup_object); | ||||
1731 | |||||
1732 | /* Use SAVE_EXPR to avoid evaluating the receiver twice. */ | ||||
1733 | lookup_object = save_expr (lookup_object); | ||||
1734 | |||||
1735 | /* Param list + 2 slots for object and selector. */ | ||||
1736 | vec_alloc (parms, nparm + 2); | ||||
1737 | |||||
1738 | /* If we are returning an item that must be returned in memory, and the | ||||
1739 | target ABI does this by an invisible pointer provided as the first arg, | ||||
1740 | we need to adjust the message signature to include this. The second | ||||
1741 | part of this excludes targets that provide some alternate scheme for | ||||
1742 | structure returns. */ | ||||
1743 | if (ret_type && !VOID_TYPE_P (ret_type)(((enum tree_code) (ret_type)->base.code) == VOID_TYPE) | ||||
1744 | && targetm.calls.return_in_memory (ret_type, 0) | ||||
1745 | && !(targetm.calls.struct_value_rtx (0, 0) | ||||
1746 | && (TREE_CODE (ret_type)((enum tree_code) (ret_type)->base.code) == RECORD_TYPE | ||||
1747 | || TREE_CODE (ret_type)((enum tree_code) (ret_type)->base.code) == UNION_TYPE))) | ||||
1748 | { | ||||
1749 | if (super) | ||||
1750 | sender = umsg_id_super2_stret_fixup_declobjc_v2_global_trees[OCTI_V2_UMSG_SUPER2_STRET_FIXUP_DECL]; | ||||
1751 | else | ||||
1752 | sender = rx_is_id ? umsg_id_stret_fixup_declobjc_v2_global_trees[OCTI_V2_UMSG_ID_STRET_FIXUP_DECL] | ||||
1753 | : umsg_stret_fixup_declobjc_v2_global_trees[OCTI_V2_UMSG_STRET_FIXUP_DECL]; | ||||
1754 | } | ||||
1755 | else | ||||
1756 | { | ||||
1757 | if (super
| ||||
1758 | sender = umsg_id_super2_fixup_declobjc_v2_global_trees[OCTI_V2_UMSG_SUPER2_FIXUP_DECL]; | ||||
1759 | else | ||||
1760 | sender = rx_is_id ? umsg_id_fixup_declobjc_v2_global_trees[OCTI_V2_UMSG_ID_FIXUP_DECL] | ||||
1761 | : umsg_fixup_declobjc_v2_global_trees[OCTI_V2_UMSG_FIXUP_DECL]; | ||||
1762 | } | ||||
1763 | |||||
1764 | method = build_fold_addr_expr_loc (loc, sender); | ||||
1765 | |||||
1766 | /* Pass the object to the method. */ | ||||
1767 | parms->quick_push (lookup_object); | ||||
| |||||
1768 | /* Pass the selector to the method. */ | ||||
1769 | parms->quick_push (selector); | ||||
1770 | /* Now append the remainder of the parms. */ | ||||
1771 | if (nparm) | ||||
1772 | for (; method_params; method_params = TREE_CHAIN (method_params)((contains_struct_check ((method_params), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1772, __FUNCTION__))->common.chain)) | ||||
1773 | parms->quick_push (TREE_VALUE (method_params)((tree_check ((method_params), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1773, __FUNCTION__, (TREE_LIST)))->list.value)); | ||||
1774 | |||||
1775 | /* Build an obj_type_ref, with the correct cast for the method call. */ | ||||
1776 | t = build3 (OBJ_TYPE_REF, sender_cast, method, | ||||
1777 | lookup_object, build_int_cst (TREE_TYPE (lookup_object)((contains_struct_check ((lookup_object), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1777, __FUNCTION__))->typed.type), 0)); | ||||
1778 | tree ret_val = build_function_call_vec (loc, vNULL, t, parms, NULLnullptr); | ||||
1779 | vec_free (parms); | ||||
1780 | if (check_for_nil) | ||||
1781 | { | ||||
1782 | /* receiver != nil ? ret_val : 0 */ | ||||
1783 | tree ftree; | ||||
1784 | tree ifexp; | ||||
1785 | |||||
1786 | if (TREE_CODE (ret_type)((enum tree_code) (ret_type)->base.code) == RECORD_TYPE | ||||
1787 | || TREE_CODE (ret_type)((enum tree_code) (ret_type)->base.code) == UNION_TYPE) | ||||
1788 | { | ||||
1789 | /* An empty constructor is zero-filled by the middle end. */ | ||||
1790 | ftree = objc_build_constructor (ret_type, NULLnullptr); | ||||
1791 | } | ||||
1792 | else | ||||
1793 | ftree = fold_convert (ret_type, integer_zero_node)fold_convert_loc (((location_t) 0), ret_type, global_trees[TI_INTEGER_ZERO ]); | ||||
1794 | |||||
1795 | ifexp = build_binary_op (loc, NE_EXPR, | ||||
1796 | lookup_object, | ||||
1797 | fold_convert (rcv_p, integer_zero_node)fold_convert_loc (((location_t) 0), rcv_p, global_trees[TI_INTEGER_ZERO ]), 1); | ||||
1798 | |||||
1799 | #ifdef OBJCPLUS | ||||
1800 | ret_val = build_conditional_expr (loc, ifexp, ret_val, ftree, | ||||
1801 | tf_warning_or_error); | ||||
1802 | #else | ||||
1803 | ret_val = build_conditional_expr (loc, ifexp, 1, | ||||
1804 | ret_val, NULL_TREE(tree) nullptr, loc, | ||||
1805 | ftree, NULL_TREE(tree) nullptr, loc); | ||||
1806 | ret_val = fold_convert (ret_type, ret_val)fold_convert_loc (((location_t) 0), ret_type, ret_val); | ||||
1807 | #endif | ||||
1808 | } | ||||
1809 | return ret_val; | ||||
1810 | } | ||||
1811 | |||||
1812 | static tree | ||||
1813 | next_runtime_abi_02_build_objc_method_call (location_t loc, | ||||
1814 | tree method_prototype, | ||||
1815 | tree receiver, | ||||
1816 | tree rtype, | ||||
1817 | tree sel_name, | ||||
1818 | tree method_params, | ||||
1819 | int super) | ||||
1820 | { | ||||
1821 | /* Do we need to check for nil receivers ? */ | ||||
1822 | /* For now, message sent to classes need no nil check. In the | ||||
1823 | future, class declaration marked as weak_import must be nil | ||||
1824 | checked. */ | ||||
1825 | bool check_for_nil = flag_objc_nilcheckglobal_options.x_flag_objc_nilcheck; | ||||
1826 | if (super | ||||
| |||||
1827 | || (TREE_CODE (receiver)((enum tree_code) (receiver)->base.code) == VAR_DECL | ||||
1828 | && TREE_TYPE (receiver)((contains_struct_check ((receiver), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1828, __FUNCTION__))->typed.type) == objc_class_typeobjc_global_trees[OCTI_CLS_TYPE])) | ||||
1829 | check_for_nil = false; | ||||
1830 | |||||
1831 | if (flag_next_runtimeglobal_options.x_flag_next_runtime >= USE_FIXUP_BEFORE100600) | ||||
1832 | { | ||||
1833 | tree selector | ||||
1834 | = next_runtime_abi_02_build_selector_reference (loc, sel_name, | ||||
1835 | method_prototype); | ||||
1836 | return build_v2_build_objc_method_call (super, method_prototype, | ||||
1837 | receiver, selector, | ||||
1838 | method_params, loc, | ||||
1839 | check_for_nil, | ||||
1840 | objc_is_id (rtype)); | ||||
1841 | } | ||||
1842 | |||||
1843 | /* else we have to build a pair of the function and selector. */ | ||||
1844 | tree message_func_decl; | ||||
1845 | tree ret_type = method_prototype | ||||
1846 | ? TREE_VALUE (TREE_TYPE (method_prototype))((tree_check ((((contains_struct_check ((method_prototype), ( TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1846, __FUNCTION__))->typed.type)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1846, __FUNCTION__, (TREE_LIST)))->list.value) | ||||
1847 | : objc_object_typeobjc_global_trees[OCTI_ID_TYPE]; | ||||
1848 | |||||
1849 | /* See comment for the fixup version above. */ | ||||
1850 | if (ret_type && !VOID_TYPE_P (ret_type)(((enum tree_code) (ret_type)->base.code) == VOID_TYPE) | ||||
1851 | && targetm.calls.return_in_memory (ret_type, 0) | ||||
1852 | && !(targetm.calls.struct_value_rtx (0, 0) | ||||
1853 | && (TREE_CODE (ret_type)((enum tree_code) (ret_type)->base.code) == RECORD_TYPE | ||||
1854 | || TREE_CODE (ret_type)((enum tree_code) (ret_type)->base.code) == UNION_TYPE))) | ||||
1855 | { | ||||
1856 | if (super) | ||||
1857 | message_func_decl = umsg_id_super2_stret_fixup_declobjc_v2_global_trees[OCTI_V2_UMSG_SUPER2_STRET_FIXUP_DECL]; | ||||
1858 | else | ||||
1859 | message_func_decl = objc_is_id (rtype) | ||||
1860 | ? umsg_id_stret_fixup_declobjc_v2_global_trees[OCTI_V2_UMSG_ID_STRET_FIXUP_DECL] | ||||
1861 | : umsg_stret_fixup_declobjc_v2_global_trees[OCTI_V2_UMSG_STRET_FIXUP_DECL]; | ||||
1862 | } | ||||
1863 | else | ||||
1864 | { | ||||
1865 | if (super) | ||||
1866 | message_func_decl = umsg_id_super2_fixup_declobjc_v2_global_trees[OCTI_V2_UMSG_SUPER2_FIXUP_DECL]; | ||||
1867 | else | ||||
1868 | message_func_decl = objc_is_id (rtype) | ||||
1869 | ? umsg_id_fixup_declobjc_v2_global_trees[OCTI_V2_UMSG_ID_FIXUP_DECL] | ||||
1870 | : umsg_fixup_declobjc_v2_global_trees[OCTI_V2_UMSG_FIXUP_DECL]; | ||||
1871 | } | ||||
1872 | |||||
1873 | tree selector = build_v2_selector_messenger_reference (sel_name, | ||||
1874 | message_func_decl); | ||||
1875 | |||||
1876 | /* selector = &_msg; */ | ||||
1877 | selector = build_unary_op (loc, ADDR_EXPR, selector, 0); | ||||
1878 | |||||
1879 | selector = build_c_cast (loc, (super ? objc_v2_super_selector_typeobjc_v2_global_trees[OCTI_V2_SUPER_MESSAGE_SELECTOR_TYPE] | ||||
1880 | : objc_v2_selector_typeobjc_v2_global_trees[OCTI_V2_MESSAGE_SELECTOR_TYPE]), | ||||
1881 | selector); | ||||
1882 | |||||
1883 | /* (*_msg.messenger) (receiver, &_msg, ...); */ | ||||
1884 | return build_v2_objc_method_fixup_call (super, method_prototype, receiver, | ||||
1885 | selector, method_params, | ||||
1886 | check_for_nil); | ||||
1887 | } | ||||
1888 | |||||
1889 | /* NOTE --- Constant String Class Stuff --- */ | ||||
1890 | |||||
1891 | static bool | ||||
1892 | next_runtime_abi_02_setup_const_string_class_decl (void) | ||||
1893 | { | ||||
1894 | if (!constant_string_global_idobjc_global_trees[OCTI_CNST_STR_GLOB_ID]) | ||||
1895 | { | ||||
1896 | /* Hopefully, this should not represent a serious limitation. */ | ||||
1897 | char buf[BUFSIZE1024]; | ||||
1898 | snprintf (buf, BUFSIZE1024, "OBJC_CLASS_$_%s", constant_string_class_name); | ||||
1899 | 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)); | ||||
1900 | } | ||||
1901 | |||||
1902 | string_class_declobjc_global_trees[OCTI_STRING_CLASS_DECL] = lookup_name (constant_string_global_idobjc_global_trees[OCTI_CNST_STR_GLOB_ID]); | ||||
1903 | |||||
1904 | /* In OBJC2 abi, constant string class reference refers to class | ||||
1905 | name for NSConstantString class. This declaration may not be | ||||
1906 | available yet (in fact it is not in most cases). So, declare an | ||||
1907 | extern OBJC_CLASS_$_NSConstantString in its place. */ | ||||
1908 | if (!string_class_declobjc_global_trees[OCTI_STRING_CLASS_DECL]) | ||||
1909 | string_class_declobjc_global_trees[OCTI_STRING_CLASS_DECL] = | ||||
1910 | create_extern_decl (objc_v2_class_templateobjc_v2_global_trees[OCTI_V2_CLS_TEMPL], | ||||
1911 | IDENTIFIER_POINTER (constant_string_global_id)((const char *) (tree_check ((objc_global_trees[OCTI_CNST_STR_GLOB_ID ]), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1911, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
1912 | |||||
1913 | return (string_class_declobjc_global_trees[OCTI_STRING_CLASS_DECL] != NULL_TREE(tree) nullptr); | ||||
1914 | } | ||||
1915 | |||||
1916 | static tree | ||||
1917 | next_runtime_abi_02_build_const_string_constructor (location_t loc, tree string, | ||||
1918 | int length) | ||||
1919 | { | ||||
1920 | tree constructor, fields, var; | ||||
1921 | vec<constructor_elt, va_gc> *v = NULLnullptr; | ||||
1922 | |||||
1923 | /* NeXT: (NSConstantString *) & ((__builtin_ObjCString) { isa, string, length }) */ | ||||
1924 | fields = TYPE_FIELDS (internal_const_str_type)((tree_check3 ((objc_global_trees[OCTI_INTERNAL_CNST_STR_TYPE ]), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1924, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.values); | ||||
1925 | 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) | ||||
1926 | 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); | ||||
1927 | |||||
1928 | fields = DECL_CHAIN (fields)(((contains_struct_check (((contains_struct_check ((fields), ( TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1928, __FUNCTION__))), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1928, __FUNCTION__))->common.chain)); | ||||
1929 | 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) | ||||
1930 | 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); | ||||
1931 | |||||
1932 | /* ??? check if this should be long. */ | ||||
1933 | fields = DECL_CHAIN (fields)(((contains_struct_check (((contains_struct_check ((fields), ( TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1933, __FUNCTION__))), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1933, __FUNCTION__))->common.chain)); | ||||
1934 | 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); | ||||
1935 | constructor = objc_build_constructor (internal_const_str_typeobjc_global_trees[OCTI_INTERNAL_CNST_STR_TYPE], v); | ||||
1936 | |||||
1937 | var = build_decl (input_location, CONST_DECL, NULLnullptr, TREE_TYPE (constructor)((contains_struct_check ((constructor), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1937, __FUNCTION__))->typed.type)); | ||||
1938 | DECL_INITIAL (var)((contains_struct_check ((var), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1938, __FUNCTION__))->decl_common.initial) = constructor; | ||||
1939 | TREE_STATIC (var)((var)->base.static_flag) = 1; | ||||
1940 | DECL_CONTEXT (var)((contains_struct_check ((var), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1940, __FUNCTION__))->decl_minimal.context) = NULLnullptr; | ||||
1941 | OBJCMETA (var, objc_meta, meta_const_str)if (objc_rt_trees[OCTI_RT_OBJC_META]) ((contains_struct_check ((var), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1941, __FUNCTION__))->decl_common.attributes) = build_tree_list ((objc_rt_trees[OCTI_RT_OBJC_META]), (objc_rt_trees[OCTI_RT_META_CONST_STR ]));; | ||||
1942 | return var; | ||||
1943 | } | ||||
1944 | |||||
1945 | /* NOTE --- NeXT V2 Metadata templates --- */ | ||||
1946 | |||||
1947 | /* This routine builds the following type: | ||||
1948 | struct _prop_t | ||||
1949 | { | ||||
1950 | const char * const name; // property name | ||||
1951 | const char * const attributes; // comma-delimited, encoded, | ||||
1952 | // property attributes | ||||
1953 | }; | ||||
1954 | */ | ||||
1955 | |||||
1956 | static tree | ||||
1957 | build_v2_property_template (void) | ||||
1958 | { | ||||
1959 | tree prop_record; | ||||
1960 | tree decls, *chain = NULLnullptr; | ||||
1961 | |||||
1962 | 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" ))); | ||||
1963 | /* const char * name */ | ||||
1964 | decls = add_field_decl (string_type_nodec_global_trees[CTI_STRING_TYPE], "name", &chain); | ||||
1965 | |||||
1966 | /* const char * attribute */ | ||||
1967 | add_field_decl (string_type_nodec_global_trees[CTI_STRING_TYPE], "attribute", &chain); | ||||
1968 | |||||
1969 | objc_finish_struct (prop_record, decls); | ||||
1970 | return prop_record; | ||||
1971 | } | ||||
1972 | |||||
1973 | /* struct ivar_t | ||||
1974 | { | ||||
1975 | unsigned long int *offset; | ||||
1976 | char *name; | ||||
1977 | char *type; | ||||
1978 | uint32_t alignment; | ||||
1979 | uint32_t size; | ||||
1980 | }; | ||||
1981 | */ | ||||
1982 | |||||
1983 | static tree | ||||
1984 | build_v2_ivar_t_template (void) | ||||
1985 | { | ||||
1986 | tree objc_ivar_id, objc_ivar_record; | ||||
1987 | tree decls, *chain = NULLnullptr; | ||||
1988 | |||||
1989 | 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" )); | ||||
1990 | objc_ivar_record = objc_start_struct (objc_ivar_id); | ||||
1991 | |||||
1992 | /* unsigned long int *offset; */ | ||||
1993 | decls = add_field_decl (build_pointer_type | ||||
1994 | (TREE_TYPE (size_zero_node)((contains_struct_check ((global_trees[TI_SIZE_ZERO]), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 1994, __FUNCTION__))->typed.type)), "offset", &chain); | ||||
1995 | |||||
1996 | /* char *name; */ | ||||
1997 | add_field_decl (string_type_nodec_global_trees[CTI_STRING_TYPE], "name", &chain); | ||||
1998 | |||||
1999 | /* char *type; */ | ||||
2000 | add_field_decl (string_type_nodec_global_trees[CTI_STRING_TYPE], "type", &chain); | ||||
2001 | |||||
2002 | /* uint32_t alignment; */ | ||||
2003 | add_field_decl (integer_type_nodeinteger_types[itk_int], "alignment", &chain); | ||||
2004 | |||||
2005 | /* uint32_t size; */ | ||||
2006 | add_field_decl (integer_type_nodeinteger_types[itk_int], "size", &chain); | ||||
2007 | |||||
2008 | objc_finish_struct (objc_ivar_record, decls); | ||||
2009 | return objc_ivar_record; | ||||
2010 | } | ||||
2011 | |||||
2012 | static void | ||||
2013 | build_metadata_templates (void) | ||||
2014 | { | ||||
2015 | |||||
2016 | if (!objc_method_templateobjc_global_trees[OCTI_METH_TEMPL]) | ||||
2017 | objc_method_templateobjc_global_trees[OCTI_METH_TEMPL] = build_method_template (); | ||||
2018 | |||||
2019 | if (!objc_v2_property_templateobjc_v2_global_trees[OCTI_V2_PROPERTY_TEMPL]) | ||||
2020 | objc_v2_property_templateobjc_v2_global_trees[OCTI_V2_PROPERTY_TEMPL] = build_v2_property_template (); | ||||
2021 | |||||
2022 | if (!objc_v2_ivar_templateobjc_v2_global_trees[OCTI_V2_IVAR_TEMPL]) | ||||
2023 | objc_v2_ivar_templateobjc_v2_global_trees[OCTI_V2_IVAR_TEMPL] = build_v2_ivar_t_template (); | ||||
2024 | |||||
2025 | } | ||||
2026 | |||||
2027 | /* NOTE --- Output NeXT V2 Metadata --- */ | ||||
2028 | |||||
2029 | /* Routine builds name of Interface's main meta-data of type class_t. */ | ||||
2030 | |||||
2031 | static char * | ||||
2032 | objc_build_internal_classname (tree ident, bool metaclass) | ||||
2033 | { | ||||
2034 | static char string[512]; | ||||
2035 | snprintf (string, 512, "%s_%s", metaclass ? "OBJC_METACLASS_$" | ||||
2036 | : "OBJC_CLASS_$", | ||||
2037 | IDENTIFIER_POINTER (ident)((const char *) (tree_check ((ident), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2037, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
2038 | return string; | ||||
2039 | } | ||||
2040 | |||||
2041 | /* Build the name for object of type struct class_ro_t */ | ||||
2042 | |||||
2043 | static const char * | ||||
2044 | newabi_append_ro (const char *name) | ||||
2045 | { | ||||
2046 | const char *dollar; | ||||
2047 | char *p; | ||||
2048 | static char string[BUFSIZE1024]; | ||||
2049 | dollar = strchr (name, '$'); | ||||
2050 | gcc_assert (dollar)((void)(!(dollar) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2050, __FUNCTION__), 0 : 0)); | ||||
2051 | p = string; | ||||
2052 | *p = '_'; p++; | ||||
2053 | strncpy (p, name, (int)(dollar - name)); | ||||
2054 | p += (int)(dollar - name); | ||||
2055 | sprintf (p, "RO_%s", dollar); | ||||
2056 | return string; | ||||
2057 | } | ||||
2058 | |||||
2059 | /* Build the struct message_ref_t msg = | ||||
2060 | {objc_msgSend_fixup_xxx, @selector(func)} | ||||
2061 | table. */ | ||||
2062 | |||||
2063 | static | ||||
2064 | void build_v2_message_ref_translation_table (void) | ||||
2065 | { | ||||
2066 | int count; | ||||
2067 | msgref_entry *ref; | ||||
2068 | |||||
2069 | if (!vec_safe_length (msgrefs)) | ||||
2070 | return; | ||||
2071 | |||||
2072 | FOR_EACH_VEC_ELT (*msgrefs, count, ref)for (count = 0; (*msgrefs).iterate ((count), &(ref)); ++( count)) | ||||
2073 | { | ||||
2074 | vec<constructor_elt, va_gc> *initializer; | ||||
2075 | tree expr, constructor; | ||||
2076 | tree struct_type = TREE_TYPE (ref->refdecl)((contains_struct_check ((ref->refdecl), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2076, __FUNCTION__))->typed.type); | ||||
2077 | location_t loc = DECL_SOURCE_LOCATION (ref->refdecl)((contains_struct_check ((ref->refdecl), (TS_DECL_MINIMAL) , "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2077, __FUNCTION__))->decl_minimal.locus); | ||||
2078 | |||||
2079 | initializer = NULLnullptr; | ||||
2080 | /* First 'IMP messenger' field... */ | ||||
2081 | expr = build_unary_op (loc, ADDR_EXPR, ref->func, 0); | ||||
2082 | expr = convert (objc_v2_imp_typeobjc_v2_global_trees[OCTI_V2_IMP_TYPE], expr); | ||||
2083 | CONSTRUCTOR_APPEND_ELT (initializer, NULL_TREE, expr)do { constructor_elt _ce___ = {(tree) nullptr, expr}; vec_safe_push ((initializer), _ce___); } while (0); | ||||
2084 | |||||
2085 | /* ... then 'SEL name' field. */ | ||||
2086 | expr = build_selector (ref->selname); | ||||
2087 | CONSTRUCTOR_APPEND_ELT (initializer, NULL_TREE, expr)do { constructor_elt _ce___ = {(tree) nullptr, expr}; vec_safe_push ((initializer), _ce___); } while (0); | ||||
2088 | constructor = objc_build_constructor (struct_type, initializer); | ||||
2089 | finish_var_decl (ref->refdecl, constructor); | ||||
2090 | } | ||||
2091 | } | ||||
2092 | |||||
2093 | /* Build decl = initializer; for each externally visible class | ||||
2094 | reference. */ | ||||
2095 | |||||
2096 | static void | ||||
2097 | build_v2_classrefs_table (void) | ||||
2098 | { | ||||
2099 | int count; | ||||
2100 | ident_data_tuple *ref; | ||||
2101 | |||||
2102 | if (!vec_safe_length (classrefs)) | ||||
2103 | return; | ||||
2104 | |||||
2105 | FOR_EACH_VEC_ELT (*classrefs, count, ref)for (count = 0; (*classrefs).iterate ((count), &(ref)); ++ (count)) | ||||
2106 | { | ||||
2107 | tree expr = ref->ident; | ||||
2108 | tree decl = ref->data; | ||||
2109 | /* Interface with no implementation and yet one of its messages | ||||
2110 | has been used. Need to generate a full address-of tree for it | ||||
2111 | here. */ | ||||
2112 | if (TREE_CODE (expr)((enum tree_code) (expr)->base.code) == IDENTIFIER_NODE) | ||||
2113 | { | ||||
2114 | const char *name = objc_build_internal_classname (expr, false); | ||||
2115 | expr = create_extern_decl (objc_v2_class_templateobjc_v2_global_trees[OCTI_V2_CLS_TEMPL], name); | ||||
2116 | expr = convert (objc_class_typeobjc_global_trees[OCTI_CLS_TYPE], build_fold_addr_expr (expr)build_fold_addr_expr_loc (((location_t) 0), (expr))); | ||||
2117 | } | ||||
2118 | /* The runtime wants this, even if it appears unused, so we must force the | ||||
2119 | output. */ | ||||
2120 | DECL_PRESERVE_P (decl)(contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2120, __FUNCTION__))->decl_common.preserve_flag = 1; | ||||
2121 | finish_var_decl (decl, expr); | ||||
2122 | } | ||||
2123 | } | ||||
2124 | |||||
2125 | /* Build decl = initializer; for each externally visible super class | ||||
2126 | reference. */ | ||||
2127 | |||||
2128 | static void | ||||
2129 | build_v2_super_classrefs_table (bool metaclass) | ||||
2130 | { | ||||
2131 | int count; | ||||
2132 | ident_data_tuple *ref; | ||||
2133 | vec<ident_data_tuple, va_gc> *list = metaclass ? metaclass_super_refs | ||||
2134 | : class_super_refs; | ||||
2135 | |||||
2136 | if (!vec_safe_length (list)) | ||||
2137 | return; | ||||
2138 | |||||
2139 | FOR_EACH_VEC_ELT (*list, count, ref)for (count = 0; (*list).iterate ((count), &(ref)); ++(count )) | ||||
2140 | { | ||||
2141 | tree expr = ref->ident; | ||||
2142 | tree decl = ref->data; | ||||
2143 | /* Interface with no implementation and yet one of its messages | ||||
2144 | has been used. Need to generate a full address-of tree for it | ||||
2145 | here. */ | ||||
2146 | if (TREE_CODE (expr)((enum tree_code) (expr)->base.code) == IDENTIFIER_NODE) | ||||
2147 | { | ||||
2148 | const char * name = objc_build_internal_classname (expr, metaclass); | ||||
2149 | expr = create_extern_decl (objc_v2_class_templateobjc_v2_global_trees[OCTI_V2_CLS_TEMPL], name); | ||||
2150 | expr = convert (objc_class_typeobjc_global_trees[OCTI_CLS_TYPE], build_fold_addr_expr (expr)build_fold_addr_expr_loc (((location_t) 0), (expr))); | ||||
2151 | } | ||||
2152 | finish_var_decl (decl, expr); | ||||
2153 | } | ||||
2154 | } | ||||
2155 | |||||
2156 | /* Add the global class meta-data declaration to the list which later | ||||
2157 | on ends up in the __class_list section. */ | ||||
2158 | |||||
2159 | static GTY(()) vec<tree, va_gc> *class_list; | ||||
2160 | |||||
2161 | static void | ||||
2162 | objc_v2_add_to_class_list (tree global_class_decl) | ||||
2163 | { | ||||
2164 | vec_safe_push (class_list, global_class_decl); | ||||
2165 | } | ||||
2166 | |||||
2167 | static GTY(()) vec<tree, va_gc> *nonlazy_class_list; | ||||
2168 | |||||
2169 | /* Add the global class meta-data declaration to the list which later | ||||
2170 | on ends up in the __nonlazy_class section. */ | ||||
2171 | |||||
2172 | static void | ||||
2173 | objc_v2_add_to_nonlazy_class_list (tree global_class_decl) | ||||
2174 | { | ||||
2175 | vec_safe_push (nonlazy_class_list, global_class_decl); | ||||
2176 | } | ||||
2177 | |||||
2178 | static GTY(()) vec<tree, va_gc> *category_list; | ||||
2179 | |||||
2180 | /* Add the category meta-data declaration to the list which later on | ||||
2181 | ends up in the __nonlazy_category section. */ | ||||
2182 | |||||
2183 | static void | ||||
2184 | objc_v2_add_to_category_list (tree decl) | ||||
2185 | { | ||||
2186 | vec_safe_push (category_list, decl); | ||||
2187 | } | ||||
2188 | |||||
2189 | static GTY(()) vec<tree, va_gc> *nonlazy_category_list; | ||||
2190 | |||||
2191 | /* Add the category meta-data declaration to the list which later on | ||||
2192 | ends up in the __category_list section. */ | ||||
2193 | |||||
2194 | static void | ||||
2195 | objc_v2_add_to_nonlazy_category_list (tree decl) | ||||
2196 | { | ||||
2197 | vec_safe_push (nonlazy_category_list, decl); | ||||
2198 | } | ||||
2199 | |||||
2200 | static bool | ||||
2201 | has_load_impl (tree clsmeth) | ||||
2202 | { | ||||
2203 | while (clsmeth) | ||||
2204 | { | ||||
2205 | tree id = METHOD_SEL_NAME (clsmeth)((tree_check2 ((clsmeth), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2205, __FUNCTION__, (INSTANCE_METHOD_DECL), (CLASS_METHOD_DECL )))->decl_minimal.name); | ||||
2206 | if (IDENTIFIER_LENGTH (id)((tree_check ((id), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2206, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.len ) == 4 | ||||
2207 | && startswith (IDENTIFIER_POINTER (id)((const char *) (tree_check ((id), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2207, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ), "load")) | ||||
2208 | return true; | ||||
2209 | clsmeth = DECL_CHAIN (clsmeth)(((contains_struct_check (((contains_struct_check ((clsmeth), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2209, __FUNCTION__))), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2209, __FUNCTION__))->common.chain)); | ||||
2210 | } | ||||
2211 | |||||
2212 | return false; | ||||
2213 | } | ||||
2214 | |||||
2215 | /* Build a __{class,category}_list section table containing address of | ||||
2216 | all @implemented {class,category} meta-data. */ | ||||
2217 | |||||
2218 | static void | ||||
2219 | build_v2_address_table (vec<tree, va_gc> *src, const char *nam, tree attr) | ||||
2220 | { | ||||
2221 | int count=0; | ||||
2222 | tree type, decl, expr; | ||||
2223 | vec<constructor_elt, va_gc> *initlist = NULLnullptr; | ||||
2224 | |||||
2225 | if (!vec_safe_length (src)) | ||||
2226 | return; | ||||
2227 | |||||
2228 | FOR_EACH_VEC_ELT (*src, count, decl)for (count = 0; (*src).iterate ((count), &(decl)); ++(count )) | ||||
2229 | { | ||||
2230 | #ifndef OBJCPLUS | ||||
2231 | tree purpose = build_int_cst (NULL_TREE(tree) nullptr, count); | ||||
2232 | #else | ||||
2233 | tree purpose = NULL_TREE(tree) nullptr; | ||||
2234 | #endif | ||||
2235 | expr = convert (objc_class_typeobjc_global_trees[OCTI_CLS_TYPE], build_fold_addr_expr (decl)build_fold_addr_expr_loc (((location_t) 0), (decl))); | ||||
2236 | CONSTRUCTOR_APPEND_ELT (initlist, purpose, expr)do { constructor_elt _ce___ = {purpose, expr}; vec_safe_push ( (initlist), _ce___); } while (0); | ||||
2237 | } | ||||
2238 | gcc_assert (count > 0)((void)(!(count > 0) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2238, __FUNCTION__), 0 : 0)); | ||||
2239 | type = build_array_type (objc_class_typeobjc_global_trees[OCTI_CLS_TYPE], | ||||
2240 | build_index_type (build_int_cst (NULL_TREE(tree) nullptr, count - 1))); | ||||
2241 | decl = start_var_decl (type, nam); | ||||
2242 | /* The runtime wants this, even if it appears unused, so we must | ||||
2243 | force the output. */ | ||||
2244 | DECL_PRESERVE_P (decl)(contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2244, __FUNCTION__))->decl_common.preserve_flag = 1; | ||||
2245 | expr = objc_build_constructor (type, initlist); | ||||
2246 | OBJCMETA (decl, objc_meta, attr)if (objc_rt_trees[OCTI_RT_OBJC_META]) ((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2246, __FUNCTION__))->decl_common.attributes) = build_tree_list ((objc_rt_trees[OCTI_RT_OBJC_META]), (attr));; | ||||
2247 | finish_var_decl (decl, expr); | ||||
2248 | } | ||||
2249 | |||||
2250 | /* Build decl = initializer; for each protocol referenced in | ||||
2251 | @protocol(MyProt) expression. Refs as built in the entry section | ||||
2252 | above. */ | ||||
2253 | |||||
2254 | static void | ||||
2255 | build_v2_protocol_list_translation_table (void) | ||||
2256 | { | ||||
2257 | int count; | ||||
2258 | prot_list_entry *ref; | ||||
2259 | |||||
2260 | if (!protrefs) | ||||
2261 | return; | ||||
2262 | |||||
2263 | FOR_EACH_VEC_ELT (*protrefs, count, ref)for (count = 0; (*protrefs).iterate ((count), &(ref)); ++ (count)) | ||||
2264 | { | ||||
2265 | char buf[BUFSIZE1024]; | ||||
2266 | tree expr; | ||||
2267 | gcc_assert (TREE_CODE (ref->id) == PROTOCOL_INTERFACE_TYPE)((void)(!(((enum tree_code) (ref->id)->base.code) == PROTOCOL_INTERFACE_TYPE ) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2267, __FUNCTION__), 0 : 0)); | ||||
2268 | snprintf (buf, BUFSIZE1024, "_OBJC_Protocol_%s", | ||||
2269 | IDENTIFIER_POINTER (PROTOCOL_NAME (ref->id))((const char *) (tree_check (((((tree_class_check ((ref->id ), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2269, __FUNCTION__))->type_common.name))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2269, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
2270 | expr = start_var_decl (objc_v2_protocol_templateobjc_v2_global_trees[OCTI_V2_PROTO_TEMPL], buf); | ||||
2271 | expr = convert (objc_protocol_typeobjc_global_trees[OCTI_PROTO_TYPE], build_fold_addr_expr (expr)build_fold_addr_expr_loc (((location_t) 0), (expr))); | ||||
2272 | finish_var_decl (ref->refdecl, expr); | ||||
2273 | } | ||||
2274 | /* TODO: Maybe we could explicitly delete the vec. now? */ | ||||
2275 | } | ||||
2276 | |||||
2277 | static GTY (()) vec<prot_list_entry, va_gc> *protlist; | ||||
2278 | |||||
2279 | /* Add the local protocol meta-data declaration to the list which | ||||
2280 | later on ends up in the __protocol_list section. */ | ||||
2281 | |||||
2282 | static void | ||||
2283 | objc_add_to_protocol_list (tree protocol_interface_decl, tree protocol_decl) | ||||
2284 | { | ||||
2285 | prot_list_entry e; | ||||
2286 | if (!protlist) | ||||
2287 | /* Arbitrary init count. */ | ||||
2288 | vec_alloc (protlist, 32); | ||||
2289 | e.id = protocol_interface_decl; | ||||
2290 | e.refdecl = protocol_decl; | ||||
2291 | vec_safe_push (protlist, e); | ||||
2292 | } | ||||
2293 | |||||
2294 | /* Build the __protocol_list section table containing address of all | ||||
2295 | generate protocol_t meta-data. */ | ||||
2296 | |||||
2297 | static void | ||||
2298 | build_v2_protocol_list_address_table (void) | ||||
2299 | { | ||||
2300 | int count; | ||||
2301 | prot_list_entry *ref; | ||||
2302 | if (!vec_safe_length (protlist)) | ||||
2303 | return; | ||||
2304 | |||||
2305 | FOR_EACH_VEC_ELT (*protlist, count, ref)for (count = 0; (*protlist).iterate ((count), &(ref)); ++ (count)) | ||||
2306 | { | ||||
2307 | tree decl, expr; | ||||
2308 | char buf[BUFSIZE1024]; | ||||
2309 | 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 ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2309, __FUNCTION__), 0 : 0)); | ||||
2310 | snprintf (buf, BUFSIZE1024, "_OBJC_LabelProtocol_%s", | ||||
2311 | IDENTIFIER_POINTER (PROTOCOL_NAME (ref->id))((const char *) (tree_check (((((tree_class_check ((ref->id ), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2311, __FUNCTION__))->type_common.name))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2311, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
2312 | if (flag_next_runtimeglobal_options.x_flag_next_runtime >= USE_FIXUP_BEFORE100600) | ||||
2313 | { | ||||
2314 | decl = create_hidden_decl (objc_protocol_typeobjc_global_trees[OCTI_PROTO_TYPE], buf, /*is def=*/true); | ||||
2315 | DECL_WEAK (decl)((contains_struct_check ((decl), (TS_DECL_WITH_VIS), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2315, __FUNCTION__))->decl_with_vis.weak_flag) = true; | ||||
2316 | } | ||||
2317 | else | ||||
2318 | decl = create_global_decl (objc_protocol_typeobjc_global_trees[OCTI_PROTO_TYPE], buf, /*is def=*/true); | ||||
2319 | 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) )); | ||||
2320 | OBJCMETA (decl, objc_meta, meta_label_protocollist)if (objc_rt_trees[OCTI_RT_OBJC_META]) ((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2320, __FUNCTION__))->decl_common.attributes) = build_tree_list ((objc_rt_trees[OCTI_RT_OBJC_META]), (objc_rt_trees[OCTI_RT_META_LAB_PROTOLIST ]));; | ||||
2321 | finish_var_decl (decl, expr); | ||||
2322 | DECL_PRESERVE_P (decl)(contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2322, __FUNCTION__))->decl_common.preserve_flag = 1; | ||||
2323 | } | ||||
2324 | |||||
2325 | /* TODO: delete the vec. */ | ||||
2326 | /* TODO: upgrade to the clang/llvm hidden version. */ | ||||
2327 | } | ||||
2328 | |||||
2329 | /* This routine declares a variable to hold meta data for 'struct | ||||
2330 | protocol_list_t'. */ | ||||
2331 | |||||
2332 | static tree | ||||
2333 | generate_v2_protocol_list (tree i_or_p, tree klass_ctxt) | ||||
2334 | { | ||||
2335 | tree refs_decl, lproto, e, plist, ptempl_p_t; | ||||
2336 | int size = 0; | ||||
2337 | vec<constructor_elt, va_gc> *initlist = NULLnullptr; | ||||
2338 | char buf[BUFSIZE1024]; | ||||
2339 | |||||
2340 | if (TREE_CODE (i_or_p)((enum tree_code) (i_or_p)->base.code) == CLASS_INTERFACE_TYPE | ||||
2341 | || TREE_CODE (i_or_p)((enum tree_code) (i_or_p)->base.code) == CATEGORY_INTERFACE_TYPE) | ||||
2342 | plist = CLASS_PROTOCOL_LIST (i_or_p)(*((const_cast<tree *> (tree_vec_elt_check ((((tree_class_check ((i_or_p), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2342, __FUNCTION__))->type_non_common.lang_1)), (4), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2342, __FUNCTION__))))); | ||||
2343 | else if (TREE_CODE (i_or_p)((enum tree_code) (i_or_p)->base.code) == PROTOCOL_INTERFACE_TYPE) | ||||
2344 | plist = PROTOCOL_LIST (i_or_p)(*((const_cast<tree *> (tree_vec_elt_check ((((tree_class_check ((i_or_p), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2344, __FUNCTION__))->type_non_common.lang_1)), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2344, __FUNCTION__))))); | ||||
2345 | else | ||||
2346 | gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2346, __FUNCTION__)); | ||||
2347 | |||||
2348 | /* Compute size. */ | ||||
2349 | for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto)((contains_struct_check ((lproto), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2349, __FUNCTION__))->common.chain)) | ||||
2350 | if (TREE_CODE (TREE_VALUE (lproto))((enum tree_code) (((tree_check ((lproto), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2350, __FUNCTION__, (TREE_LIST)))->list.value))->base .code) == PROTOCOL_INTERFACE_TYPE | ||||
2351 | && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto))(*((const_cast<tree *> (tree_vec_elt_check ((((tree_class_check ((((tree_check ((lproto), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2351, __FUNCTION__, (TREE_LIST)))->list.value)), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2351, __FUNCTION__))->type_non_common.lang_1)), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2351, __FUNCTION__)))))) | ||||
2352 | size++; | ||||
2353 | |||||
2354 | /* Build initializer. */ | ||||
2355 | |||||
2356 | ptempl_p_t = build_pointer_type (objc_v2_protocol_templateobjc_v2_global_trees[OCTI_V2_PROTO_TEMPL]); | ||||
2357 | e = build_int_cst (ptempl_p_t, size); | ||||
2358 | CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, e)do { constructor_elt _ce___ = {(tree) nullptr, e}; vec_safe_push ((initlist), _ce___); } while (0); | ||||
2359 | |||||
2360 | for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto)((contains_struct_check ((lproto), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2360, __FUNCTION__))->common.chain)) | ||||
2361 | { | ||||
2362 | tree pval = TREE_VALUE (lproto)((tree_check ((lproto), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2362, __FUNCTION__, (TREE_LIST)))->list.value); | ||||
2363 | |||||
2364 | if (TREE_CODE (pval)((enum tree_code) (pval)->base.code) == PROTOCOL_INTERFACE_TYPE | ||||
2365 | && PROTOCOL_FORWARD_DECL (pval)(*((const_cast<tree *> (tree_vec_elt_check ((((tree_class_check ((pval), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2365, __FUNCTION__))->type_non_common.lang_1)), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2365, __FUNCTION__)))))) | ||||
2366 | { | ||||
2367 | tree fwref = PROTOCOL_FORWARD_DECL (pval)(*((const_cast<tree *> (tree_vec_elt_check ((((tree_class_check ((pval), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2367, __FUNCTION__))->type_non_common.lang_1)), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2367, __FUNCTION__))))); | ||||
2368 | location_t loc = DECL_SOURCE_LOCATION (fwref)((contains_struct_check ((fwref), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2368, __FUNCTION__))->decl_minimal.locus) ; | ||||
2369 | e = build_unary_op (loc, ADDR_EXPR, fwref, 0); | ||||
2370 | CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, e)do { constructor_elt _ce___ = {(tree) nullptr, e}; vec_safe_push ((initlist), _ce___); } while (0); | ||||
2371 | } | ||||
2372 | } | ||||
2373 | |||||
2374 | /* static struct protocol_list_t *list[size]; */ | ||||
2375 | |||||
2376 | switch (TREE_CODE (i_or_p)((enum tree_code) (i_or_p)->base.code)) | ||||
2377 | { | ||||
2378 | case PROTOCOL_INTERFACE_TYPE: | ||||
2379 | snprintf (buf, BUFSIZE1024, "_OBJC_ProtocolRefs_%s", | ||||
2380 | IDENTIFIER_POINTER (PROTOCOL_NAME (i_or_p))((const char *) (tree_check (((((tree_class_check ((i_or_p), ( tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2380, __FUNCTION__))->type_common.name))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2380, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
2381 | break; | ||||
2382 | case CLASS_INTERFACE_TYPE: | ||||
2383 | snprintf (buf, BUFSIZE1024, "_OBJC_ClassProtocols_%s", | ||||
2384 | IDENTIFIER_POINTER (CLASS_NAME (i_or_p))((const char *) (tree_check (((((tree_class_check ((i_or_p), ( tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2384, __FUNCTION__))->type_common.name))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2384, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
2385 | break; | ||||
2386 | case CATEGORY_INTERFACE_TYPE: | ||||
2387 | snprintf (buf, BUFSIZE1024, "_OBJC_CategoryProtocols_%s_%s", | ||||
2388 | IDENTIFIER_POINTER (CLASS_NAME (klass_ctxt))((const char *) (tree_check (((((tree_class_check ((klass_ctxt ), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2388, __FUNCTION__))->type_common.name))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2388, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ), | ||||
2389 | IDENTIFIER_POINTER (CLASS_SUPER_NAME (klass_ctxt))((const char *) (tree_check (((((tree_class_check ((klass_ctxt ), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2389, __FUNCTION__))->type_common.context))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2389, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
2390 | break; | ||||
2391 | default: | ||||
2392 | gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2392, __FUNCTION__)); | ||||
2393 | } | ||||
2394 | |||||
2395 | refs_decl = start_var_decl (build_sized_array_type (ptempl_p_t, size+1), | ||||
2396 | buf); | ||||
2397 | /* ObjC2 puts all these in the base section. */ | ||||
2398 | OBJCMETA (refs_decl, objc_meta, meta_base)if (objc_rt_trees[OCTI_RT_OBJC_META]) ((contains_struct_check ((refs_decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2398, __FUNCTION__))->decl_common.attributes) = build_tree_list ((objc_rt_trees[OCTI_RT_OBJC_META]), (objc_rt_trees[OCTI_RT_META_BASE ]));; | ||||
2399 | DECL_PRESERVE_P (refs_decl)(contains_struct_check ((refs_decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2399, __FUNCTION__))->decl_common.preserve_flag = 1; | ||||
2400 | finish_var_decl (refs_decl, | ||||
2401 | objc_build_constructor (TREE_TYPE (refs_decl)((contains_struct_check ((refs_decl), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2401, __FUNCTION__))->typed.type),initlist)); | ||||
2402 | return refs_decl; | ||||
2403 | } | ||||
2404 | |||||
2405 | /* This routine builds one 'struct method_t' initializer list. Note | ||||
2406 | that the old ABI is supposed to build 'struct objc_method' which | ||||
2407 | has 3 fields, but it does not build the initialization expression | ||||
2408 | for 'method_imp' which for protocols is NULL any way. To be | ||||
2409 | consistent with declaration of 'struct method_t', in the new ABI we | ||||
2410 | set the method_t.imp to NULL. */ | ||||
2411 | |||||
2412 | static tree | ||||
2413 | build_v2_descriptor_table_initializer (tree type, tree entries) | ||||
2414 | { | ||||
2415 | vec<constructor_elt, va_gc> *initlist = NULLnullptr; | ||||
2416 | do | ||||
2417 | { | ||||
2418 | vec<constructor_elt, va_gc> *eltlist = NULLnullptr; | ||||
2419 | CONSTRUCTOR_APPEND_ELT (eltlist, NULL_TREE,do { constructor_elt _ce___ = {(tree) nullptr, build_selector (((tree_check2 ((entries), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2420, __FUNCTION__, (INSTANCE_METHOD_DECL), (CLASS_METHOD_DECL )))->decl_minimal.name))}; vec_safe_push ((eltlist), _ce___ ); } while (0) | ||||
2420 | build_selector (METHOD_SEL_NAME (entries)))do { constructor_elt _ce___ = {(tree) nullptr, build_selector (((tree_check2 ((entries), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2420, __FUNCTION__, (INSTANCE_METHOD_DECL), (CLASS_METHOD_DECL )))->decl_minimal.name))}; vec_safe_push ((eltlist), _ce___ ); } while (0); | ||||
2421 | CONSTRUCTOR_APPEND_ELT (eltlist, NULL_TREE,do { constructor_elt _ce___ = {(tree) nullptr, add_objc_string (((tree_check2 ((entries), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2422, __FUNCTION__, (INSTANCE_METHOD_DECL), (CLASS_METHOD_DECL )))->decl_minimal.context), meth_var_types)}; vec_safe_push ((eltlist), _ce___); } while (0) | ||||
2422 | add_objc_string (METHOD_ENCODING (entries),do { constructor_elt _ce___ = {(tree) nullptr, add_objc_string (((tree_check2 ((entries), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2422, __FUNCTION__, (INSTANCE_METHOD_DECL), (CLASS_METHOD_DECL )))->decl_minimal.context), meth_var_types)}; vec_safe_push ((eltlist), _ce___); } while (0) | ||||
2423 | meth_var_types))do { constructor_elt _ce___ = {(tree) nullptr, add_objc_string (((tree_check2 ((entries), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2422, __FUNCTION__, (INSTANCE_METHOD_DECL), (CLASS_METHOD_DECL )))->decl_minimal.context), meth_var_types)}; vec_safe_push ((eltlist), _ce___); } while (0); | ||||
2424 | 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); | ||||
2425 | |||||
2426 | CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE,do { constructor_elt _ce___ = {(tree) nullptr, objc_build_constructor (type, eltlist)}; vec_safe_push ((initlist), _ce___); } while (0) | ||||
2427 | objc_build_constructor (type, eltlist))do { constructor_elt _ce___ = {(tree) nullptr, objc_build_constructor (type, eltlist)}; vec_safe_push ((initlist), _ce___); } while (0); | ||||
2428 | entries = TREE_CHAIN (entries)((contains_struct_check ((entries), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2428, __FUNCTION__))->common.chain); | ||||
2429 | } | ||||
2430 | while (entries); | ||||
2431 | |||||
2432 | return objc_build_constructor (build_array_type (type, 0), initlist); | ||||
2433 | } | ||||
2434 | |||||
2435 | /* struct method_list_t | ||||
2436 | { | ||||
2437 | uint32_t entsize; | ||||
2438 | uint32_t method_count; | ||||
2439 | struct objc_method method_list[method_count]; | ||||
2440 | }; */ | ||||
2441 | |||||
2442 | static tree | ||||
2443 | build_v2_method_list_template (tree list_type, int size) | ||||
2444 | { | ||||
2445 | tree method_list_t_record; | ||||
2446 | tree array_type, decls, *chain = NULLnullptr; | ||||
2447 | |||||
2448 | method_list_t_record = objc_start_struct (NULL_TREE(tree) nullptr); | ||||
2449 | |||||
2450 | /* uint32_t const entsize; */ | ||||
2451 | decls = add_field_decl (integer_type_nodeinteger_types[itk_int], "entsize", &chain); | ||||
2452 | |||||
2453 | /* int method_count; */ | ||||
2454 | add_field_decl (integer_type_nodeinteger_types[itk_int], "method_count", &chain); | ||||
2455 | |||||
2456 | /* struct objc_method method_list[]; */ | ||||
2457 | array_type = build_sized_array_type (list_type, size); | ||||
2458 | add_field_decl (array_type, "method_list", &chain); | ||||
2459 | |||||
2460 | objc_finish_struct (method_list_t_record, decls); | ||||
2461 | return method_list_t_record; | ||||
2462 | } | ||||
2463 | |||||
2464 | /* Note, as above that we are building to the objc_method_template | ||||
2465 | which has the *imp field. ABI0/1 build with | ||||
2466 | objc_method_prototype_template which is missing this field. */ | ||||
2467 | static tree | ||||
2468 | generate_v2_meth_descriptor_table (tree chain, tree protocol, | ||||
2469 | const char *prefix, tree attr, | ||||
2470 | vec<tree>& all_meths) | ||||
2471 | { | ||||
2472 | tree method_list_template, initlist, decl; | ||||
2473 | int size, entsize; | ||||
2474 | vec<constructor_elt, va_gc> *v = NULLnullptr; | ||||
2475 | char buf[BUFSIZE1024]; | ||||
2476 | |||||
2477 | if (!chain || !prefix) | ||||
2478 | return NULL_TREE(tree) nullptr; | ||||
2479 | |||||
2480 | tree method = chain; | ||||
2481 | size = 0; | ||||
2482 | while (method) | ||||
2483 | { | ||||
2484 | if (! METHOD_ENCODING (method)((tree_check2 ((method), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2484, __FUNCTION__, (INSTANCE_METHOD_DECL), (CLASS_METHOD_DECL )))->decl_minimal.context)) | ||||
2485 | METHOD_ENCODING (method)((tree_check2 ((method), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2485, __FUNCTION__, (INSTANCE_METHOD_DECL), (CLASS_METHOD_DECL )))->decl_minimal.context) = encode_method_prototype (method); | ||||
2486 | all_meths.safe_push (method); | ||||
2487 | method = TREE_CHAIN (method)((contains_struct_check ((method), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2487, __FUNCTION__))->common.chain); | ||||
2488 | size++; | ||||
2489 | } | ||||
2490 | |||||
2491 | gcc_assert (size)((void)(!(size) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2491, __FUNCTION__), 0 : 0)); | ||||
2492 | method_list_template = build_v2_method_list_template (objc_method_templateobjc_global_trees[OCTI_METH_TEMPL], | ||||
2493 | size); | ||||
2494 | snprintf (buf, BUFSIZE1024, "%s_%s", prefix, | ||||
2495 | IDENTIFIER_POINTER (PROTOCOL_NAME (protocol))((const char *) (tree_check (((((tree_class_check ((protocol) , (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2495, __FUNCTION__))->type_common.name))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2495, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
2496 | |||||
2497 | decl = start_var_decl (method_list_template, buf); | ||||
2498 | |||||
2499 | 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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2499, __FUNCTION__))->type_common.size_unit)), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2499, __FUNCTION__))); | ||||
2500 | 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); | ||||
2501 | 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); | ||||
2502 | initlist = | ||||
2503 | build_v2_descriptor_table_initializer (objc_method_templateobjc_global_trees[OCTI_METH_TEMPL], | ||||
2504 | chain); | ||||
2505 | CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, initlist)do { constructor_elt _ce___ = {(tree) nullptr, initlist}; vec_safe_push ((v), _ce___); } while (0); | ||||
2506 | /* Get into the right section. */ | ||||
2507 | OBJCMETA (decl, objc_meta, attr)if (objc_rt_trees[OCTI_RT_OBJC_META]) ((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2507, __FUNCTION__))->decl_common.attributes) = build_tree_list ((objc_rt_trees[OCTI_RT_OBJC_META]), (attr));; | ||||
2508 | finish_var_decl (decl, objc_build_constructor (method_list_template, v)); | ||||
2509 | return decl; | ||||
2510 | } | ||||
2511 | |||||
2512 | static tree | ||||
2513 | generate_v2_meth_type_list (vec<tree>& all_meths, tree protocol, | ||||
2514 | const char *prefix) | ||||
2515 | { | ||||
2516 | if (all_meths.is_empty () || !prefix) | ||||
2517 | return NULL_TREE(tree) nullptr; | ||||
2518 | |||||
2519 | unsigned size = all_meths.length (); | ||||
2520 | tree list_type = build_sized_array_type (string_type_nodec_global_trees[CTI_STRING_TYPE], size); | ||||
2521 | char *nam; | ||||
2522 | asprintf (&nam, "%s_%s", prefix, | ||||
2523 | IDENTIFIER_POINTER (PROTOCOL_NAME (protocol))((const char *) (tree_check (((((tree_class_check ((protocol) , (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2523, __FUNCTION__))->type_common.name))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2523, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
2524 | tree decl = start_var_decl (list_type, nam); | ||||
2525 | free (nam); | ||||
2526 | OBJCMETA (decl, objc_meta, meta_base)if (objc_rt_trees[OCTI_RT_OBJC_META]) ((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2526, __FUNCTION__))->decl_common.attributes) = build_tree_list ((objc_rt_trees[OCTI_RT_OBJC_META]), (objc_rt_trees[OCTI_RT_META_BASE ]));; | ||||
2527 | vec<constructor_elt, va_gc> *v = NULLnullptr; | ||||
2528 | |||||
2529 | for (unsigned i = 0; i < size; ++i) | ||||
2530 | CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,do { constructor_elt _ce___ = {(tree) nullptr, add_objc_string (((tree_check2 ((all_meths[i]), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2531, __FUNCTION__, (INSTANCE_METHOD_DECL), (CLASS_METHOD_DECL )))->decl_minimal.context), meth_var_types)}; vec_safe_push ((v), _ce___); } while (0) | ||||
2531 | add_objc_string (METHOD_ENCODING (all_meths[i]),do { constructor_elt _ce___ = {(tree) nullptr, add_objc_string (((tree_check2 ((all_meths[i]), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2531, __FUNCTION__, (INSTANCE_METHOD_DECL), (CLASS_METHOD_DECL )))->decl_minimal.context), meth_var_types)}; vec_safe_push ((v), _ce___); } while (0) | ||||
2532 | meth_var_types))do { constructor_elt _ce___ = {(tree) nullptr, add_objc_string (((tree_check2 ((all_meths[i]), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2531, __FUNCTION__, (INSTANCE_METHOD_DECL), (CLASS_METHOD_DECL )))->decl_minimal.context), meth_var_types)}; vec_safe_push ((v), _ce___); } while (0); | ||||
2533 | finish_var_decl (decl, objc_build_constructor (list_type, v)); | ||||
2534 | return decl; | ||||
2535 | } | ||||
2536 | |||||
2537 | /* This routine builds the initializer list to initialize the 'struct | ||||
2538 | _prop_t prop_list[]' field of 'struct _prop_list_t' meta-data. */ | ||||
2539 | |||||
2540 | static tree | ||||
2541 | build_v2_property_table_initializer (tree type, tree context) | ||||
2542 | { | ||||
2543 | tree x; | ||||
2544 | vec<constructor_elt, va_gc> *inits = NULLnullptr; | ||||
2545 | if (TREE_CODE (context)((enum tree_code) (context)->base.code) == PROTOCOL_INTERFACE_TYPE) | ||||
2546 | x = CLASS_PROPERTY_DECL (context)(*((const_cast<tree *> (tree_vec_elt_check ((((tree_class_check ((context), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2546, __FUNCTION__))->type_non_common.lang_1)), (6), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2546, __FUNCTION__))))); | ||||
2547 | else | ||||
2548 | x = IMPL_PROPERTY_DECL (context)(*((const_cast<tree *> (tree_vec_elt_check ((((tree_class_check ((context), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2548, __FUNCTION__))->type_non_common.lang_1)), (6), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2548, __FUNCTION__))))); | ||||
2549 | |||||
2550 | for (; x; x = TREE_CHAIN (x)((contains_struct_check ((x), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2550, __FUNCTION__))->common.chain)) | ||||
2551 | { | ||||
2552 | vec<constructor_elt, va_gc> *elemlist = NULLnullptr; | ||||
2553 | /* NOTE! sections where property name/attribute go MUST change | ||||
2554 | later. */ | ||||
2555 | tree attribute, name_ident = PROPERTY_NAME (x)((contains_struct_check (((tree_check ((x), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2555, __FUNCTION__, (PROPERTY_DECL)))), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2555, __FUNCTION__))->decl_minimal.name); | ||||
2556 | |||||
2557 | 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) | ||||
2558 | 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); | ||||
2559 | |||||
2560 | attribute = objc_v2_encode_prop_attr (x); | ||||
2561 | 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) | ||||
2562 | 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); | ||||
2563 | |||||
2564 | CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,do { constructor_elt _ce___ = {(tree) nullptr, objc_build_constructor (type, elemlist)}; vec_safe_push ((inits), _ce___); } while ( 0) | ||||
2565 | objc_build_constructor (type, elemlist))do { constructor_elt _ce___ = {(tree) nullptr, objc_build_constructor (type, elemlist)}; vec_safe_push ((inits), _ce___); } while ( 0); | ||||
2566 | } | ||||
2567 | |||||
2568 | return objc_build_constructor (build_array_type (type, 0),inits); | ||||
2569 | } | ||||
2570 | |||||
2571 | /* This routine builds the following type: | ||||
2572 | struct _prop_list_t | ||||
2573 | { | ||||
2574 | uint32_t entsize; // sizeof (struct _prop_t) | ||||
2575 | uint32_t prop_count; | ||||
2576 | struct _prop_t prop_list [prop_count]; | ||||
2577 | } | ||||
2578 | */ | ||||
2579 | |||||
2580 | static tree | ||||
2581 | build_v2_property_list_template (tree list_type, int size) | ||||
2582 | { | ||||
2583 | tree property_list_t_record; | ||||
2584 | tree array_type, decls, *chain = NULLnullptr; | ||||
2585 | |||||
2586 | /* anonymous. */ | ||||
2587 | property_list_t_record = objc_start_struct (NULL_TREE(tree) nullptr); | ||||
2588 | |||||
2589 | /* uint32_t const entsize; */ | ||||
2590 | decls = add_field_decl (integer_type_nodeinteger_types[itk_int], "entsize", &chain); | ||||
2591 | |||||
2592 | /* int prop_count; */ | ||||
2593 | add_field_decl (integer_type_nodeinteger_types[itk_int], "prop_count", &chain); | ||||
2594 | |||||
2595 | /* struct _prop_t prop_list[]; */ | ||||
2596 | array_type = build_sized_array_type (list_type, size); | ||||
2597 | add_field_decl (array_type, "prop_list", &chain); | ||||
2598 | |||||
2599 | objc_finish_struct (property_list_t_record, decls); | ||||
2600 | return property_list_t_record; | ||||
2601 | } | ||||
2602 | |||||
2603 | /* Top-level routine to generate property tables for each | ||||
2604 | implementation. */ | ||||
2605 | |||||
2606 | static tree | ||||
2607 | generate_v2_property_table (tree context, tree klass_ctxt) | ||||
2608 | { | ||||
2609 | tree x, decl, initlist, property_list_template; | ||||
2610 | bool is_proto = false; | ||||
2611 | vec<constructor_elt, va_gc> *inits = NULLnullptr; | ||||
2612 | int init_val, size = 0; | ||||
2613 | char buf[BUFSIZE1024]; | ||||
2614 | |||||
2615 | if (context) | ||||
2616 | { | ||||
2617 | gcc_assert (TREE_CODE (context) == PROTOCOL_INTERFACE_TYPE)((void)(!(((enum tree_code) (context)->base.code) == PROTOCOL_INTERFACE_TYPE ) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2617, __FUNCTION__), 0 : 0)); | ||||
2618 | x = CLASS_PROPERTY_DECL (context)(*((const_cast<tree *> (tree_vec_elt_check ((((tree_class_check ((context), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2618, __FUNCTION__))->type_non_common.lang_1)), (6), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2618, __FUNCTION__))))); | ||||
2619 | is_proto = true; | ||||
2620 | } | ||||
2621 | else | ||||
2622 | x = IMPL_PROPERTY_DECL (klass_ctxt)(*((const_cast<tree *> (tree_vec_elt_check ((((tree_class_check ((klass_ctxt), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2622, __FUNCTION__))->type_non_common.lang_1)), (6), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2622, __FUNCTION__))))); | ||||
2623 | |||||
2624 | for (; x; x = TREE_CHAIN (x)((contains_struct_check ((x), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2624, __FUNCTION__))->common.chain)) | ||||
2625 | size++; | ||||
2626 | |||||
2627 | if (size == 0) | ||||
2628 | return NULL_TREE(tree) nullptr; | ||||
2629 | |||||
2630 | property_list_template = | ||||
2631 | build_v2_property_list_template (objc_v2_property_templateobjc_v2_global_trees[OCTI_V2_PROPERTY_TEMPL], | ||||
2632 | size); | ||||
2633 | |||||
2634 | initlist = build_v2_property_table_initializer (objc_v2_property_templateobjc_v2_global_trees[OCTI_V2_PROPERTY_TEMPL], | ||||
2635 | is_proto ? context | ||||
2636 | : klass_ctxt); | ||||
2637 | |||||
2638 | 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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2638, __FUNCTION__))->type_common.size_unit)), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2638, __FUNCTION__))); | ||||
2639 | if (is_proto) | ||||
2640 | snprintf (buf, BUFSIZE1024, "_OBJC_ProtocolPropList_%s", | ||||
2641 | IDENTIFIER_POINTER (PROTOCOL_NAME (context))((const char *) (tree_check (((((tree_class_check ((context), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2641, __FUNCTION__))->type_common.name))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2641, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
2642 | else | ||||
2643 | snprintf (buf, BUFSIZE1024, "_OBJC_ClassPropList_%s", | ||||
2644 | IDENTIFIER_POINTER (CLASS_NAME (klass_ctxt))((const char *) (tree_check (((((tree_class_check ((klass_ctxt ), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2644, __FUNCTION__))->type_common.name))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2644, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
2645 | |||||
2646 | decl = start_var_decl (property_list_template, buf); | ||||
2647 | |||||
2648 | 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) | ||||
2649 | 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); | ||||
2650 | 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) | ||||
2651 | 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); | ||||
2652 | CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, initlist)do { constructor_elt _ce___ = {(tree) nullptr, initlist}; vec_safe_push ((inits), _ce___); } while (0); | ||||
2653 | |||||
2654 | OBJCMETA (decl, objc_meta, meta_base)if (objc_rt_trees[OCTI_RT_OBJC_META]) ((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2654, __FUNCTION__))->decl_common.attributes) = build_tree_list ((objc_rt_trees[OCTI_RT_OBJC_META]), (objc_rt_trees[OCTI_RT_META_BASE ]));; | ||||
2655 | finish_var_decl (decl, objc_build_constructor (TREE_TYPE (decl)((contains_struct_check ((decl), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2655, __FUNCTION__))->typed.type), inits)); | ||||
2656 | return decl; | ||||
2657 | } | ||||
2658 | |||||
2659 | static tree | ||||
2660 | build_v2_protocol_initializer (tree type, tree protocol_name, tree protocol_list, | ||||
2661 | tree inst_methods, tree class_methods, | ||||
2662 | tree opt_ins_meth, tree opt_cls_meth, | ||||
2663 | tree property_list, tree ext_meth_types, | ||||
2664 | tree demangled_name, tree class_prop_list) | ||||
2665 | { | ||||
2666 | tree expr, ttyp; | ||||
2667 | location_t loc; | ||||
2668 | vec<constructor_elt, va_gc> *inits = NULLnullptr; | ||||
2669 | |||||
2670 | /* TODO: find a better representation of location from the inputs. */ | ||||
2671 | loc = UNKNOWN_LOCATION((location_t) 0); | ||||
2672 | |||||
2673 | /* This is NULL for the new ABI. */ | ||||
2674 | 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) | ||||
2675 | 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); | ||||
2676 | |||||
2677 | CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, protocol_name)do { constructor_elt _ce___ = {(tree) nullptr, protocol_name} ; vec_safe_push ((inits), _ce___); } while (0); | ||||
2678 | CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, protocol_list)do { constructor_elt _ce___ = {(tree) nullptr, protocol_list} ; vec_safe_push ((inits), _ce___); } while (0); | ||||
2679 | |||||
2680 | ttyp = objc_method_proto_list_ptrobjc_global_trees[OCTI_METH_PROTO_LIST_TEMPL]; | ||||
2681 | if (inst_methods) | ||||
2682 | expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, inst_methods, 0)); | ||||
2683 | else | ||||
2684 | expr = convert (ttyp, null_pointer_nodeglobal_trees[TI_NULL_POINTER]); | ||||
2685 | CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr)do { constructor_elt _ce___ = {(tree) nullptr, expr}; vec_safe_push ((inits), _ce___); } while (0); | ||||
2686 | |||||
2687 | if (class_methods) | ||||
2688 | expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, class_methods, 0)); | ||||
2689 | else | ||||
2690 | expr = convert (ttyp, null_pointer_nodeglobal_trees[TI_NULL_POINTER]); | ||||
2691 | CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr)do { constructor_elt _ce___ = {(tree) nullptr, expr}; vec_safe_push ((inits), _ce___); } while (0); | ||||
2692 | |||||
2693 | if (opt_ins_meth) | ||||
2694 | expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, opt_ins_meth, 0)); | ||||
2695 | else | ||||
2696 | expr = convert (ttyp, null_pointer_nodeglobal_trees[TI_NULL_POINTER]); | ||||
2697 | CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr)do { constructor_elt _ce___ = {(tree) nullptr, expr}; vec_safe_push ((inits), _ce___); } while (0); | ||||
2698 | |||||
2699 | if (opt_cls_meth) | ||||
2700 | expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, opt_cls_meth, 0)); | ||||
2701 | else | ||||
2702 | expr = convert (ttyp, null_pointer_nodeglobal_trees[TI_NULL_POINTER]); | ||||
2703 | CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr)do { constructor_elt _ce___ = {(tree) nullptr, expr}; vec_safe_push ((inits), _ce___); } while (0); | ||||
2704 | |||||
2705 | ttyp = objc_prop_list_ptrobjc_global_trees[OCTI_V1_PROP_LIST_TEMPL]; | ||||
2706 | if (property_list) | ||||
2707 | expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, property_list, 0)); | ||||
2708 | else | ||||
2709 | expr = convert (ttyp, null_pointer_nodeglobal_trees[TI_NULL_POINTER]); | ||||
2710 | CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr)do { constructor_elt _ce___ = {(tree) nullptr, expr}; vec_safe_push ((inits), _ce___); } while (0); | ||||
2711 | |||||
2712 | /* const uint32_t size; = sizeof(struct protocol_t) */ | ||||
2713 | expr = build_int_cst (integer_type_nodeinteger_types[itk_int], | ||||
2714 | 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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2714, __FUNCTION__))->type_common.size_unit)), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2714, __FUNCTION__)))); | ||||
2715 | CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr)do { constructor_elt _ce___ = {(tree) nullptr, expr}; vec_safe_push ((inits), _ce___); } while (0); | ||||
2716 | /* const uint32_t flags; = 0 */ | ||||
2717 | 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); | ||||
2718 | |||||
2719 | ttyp = build_pointer_type (string_type_nodec_global_trees[CTI_STRING_TYPE]); | ||||
2720 | if (ext_meth_types) | ||||
2721 | expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, ext_meth_types, 0)); | ||||
2722 | else | ||||
2723 | expr = convert (ttyp, null_pointer_nodeglobal_trees[TI_NULL_POINTER]); | ||||
2724 | CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr)do { constructor_elt _ce___ = {(tree) nullptr, expr}; vec_safe_push ((inits), _ce___); } while (0); | ||||
2725 | |||||
2726 | ttyp = string_type_nodec_global_trees[CTI_STRING_TYPE]; | ||||
2727 | if (demangled_name) | ||||
2728 | expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, demangled_name, 0)); | ||||
2729 | else | ||||
2730 | expr = convert (ttyp, null_pointer_nodeglobal_trees[TI_NULL_POINTER]); | ||||
2731 | CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr)do { constructor_elt _ce___ = {(tree) nullptr, expr}; vec_safe_push ((inits), _ce___); } while (0); | ||||
2732 | |||||
2733 | ttyp = objc_prop_list_ptrobjc_global_trees[OCTI_V1_PROP_LIST_TEMPL]; | ||||
2734 | if (class_prop_list) | ||||
2735 | expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, class_prop_list, 0)); | ||||
2736 | else | ||||
2737 | expr = convert (ttyp, null_pointer_nodeglobal_trees[TI_NULL_POINTER]); | ||||
2738 | CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr)do { constructor_elt _ce___ = {(tree) nullptr, expr}; vec_safe_push ((inits), _ce___); } while (0); | ||||
2739 | |||||
2740 | return objc_build_constructor (type, inits); | ||||
2741 | } | ||||
2742 | |||||
2743 | /* Main routine to build all meta data for all protocols used in a | ||||
2744 | translation unit. */ | ||||
2745 | |||||
2746 | static void | ||||
2747 | generate_v2_protocols (void) | ||||
2748 | { | ||||
2749 | tree p ; | ||||
2750 | bool some = false; | ||||
2751 | |||||
2752 | if (!protocol_chainobjc_global_trees[OCTI_PROTO_CHAIN]) | ||||
2753 | return ; | ||||
2754 | |||||
2755 | /* If a protocol was directly referenced, pull in indirect | ||||
2756 | references. */ | ||||
2757 | for (p = protocol_chainobjc_global_trees[OCTI_PROTO_CHAIN]; p; p = TREE_CHAIN (p)((contains_struct_check ((p), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2757, __FUNCTION__))->common.chain)) | ||||
2758 | if (PROTOCOL_FORWARD_DECL (p)(*((const_cast<tree *> (tree_vec_elt_check ((((tree_class_check ((p), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2758, __FUNCTION__))->type_non_common.lang_1)), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2758, __FUNCTION__))))) && PROTOCOL_LIST (p)(*((const_cast<tree *> (tree_vec_elt_check ((((tree_class_check ((p), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2758, __FUNCTION__))->type_non_common.lang_1)), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2758, __FUNCTION__)))))) | ||||
2759 | generate_protocol_references (PROTOCOL_LIST (p)(*((const_cast<tree *> (tree_vec_elt_check ((((tree_class_check ((p), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2759, __FUNCTION__))->type_non_common.lang_1)), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2759, __FUNCTION__)))))); | ||||
2760 | |||||
2761 | for (p = protocol_chainobjc_global_trees[OCTI_PROTO_CHAIN]; p; p = TREE_CHAIN (p)((contains_struct_check ((p), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2761, __FUNCTION__))->common.chain)) | ||||
2762 | { | ||||
2763 | location_t loc; | ||||
2764 | tree inst_meth, class_meth, opt_inst_meth, opt_class_meth, props; | ||||
2765 | tree decl, initlist, protocol_name_expr, refs_decl, refs_expr; | ||||
2766 | |||||
2767 | /* If protocol wasn't referenced, don't generate any code. */ | ||||
2768 | decl = PROTOCOL_FORWARD_DECL (p)(*((const_cast<tree *> (tree_vec_elt_check ((((tree_class_check ((p), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2768, __FUNCTION__))->type_non_common.lang_1)), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2768, __FUNCTION__))))); | ||||
2769 | |||||
2770 | if (!decl) | ||||
2771 | continue; | ||||
2772 | |||||
2773 | loc = DECL_SOURCE_LOCATION (decl)((contains_struct_check ((decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2773, __FUNCTION__))->decl_minimal.locus); | ||||
2774 | some = true; | ||||
2775 | |||||
2776 | vec<tree> all_meths = vNULL; | ||||
2777 | inst_meth = | ||||
2778 | generate_v2_meth_descriptor_table (PROTOCOL_NST_METHODS (p)(((tree_class_check ((p), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2778, __FUNCTION__))->type_non_common.minval)), p, | ||||
2779 | "_OBJC_ProtocolInstanceMethods", | ||||
2780 | meta_proto_nst_methobjc_rt_trees[OCTI_RT_META_PROTO_NST_METH], all_meths); | ||||
2781 | |||||
2782 | class_meth = | ||||
2783 | generate_v2_meth_descriptor_table (PROTOCOL_CLS_METHODS (p)(((tree_class_check ((p), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2783, __FUNCTION__))->type_non_common.maxval)), p, | ||||
2784 | "_OBJC_ProtocolClassMethods", | ||||
2785 | meta_proto_cls_methobjc_rt_trees[OCTI_RT_META_PROTO_CLS_METH], all_meths); | ||||
2786 | |||||
2787 | opt_inst_meth = | ||||
2788 | generate_v2_meth_descriptor_table (PROTOCOL_OPTIONAL_NST_METHODS (p)(*((const_cast<tree *> (tree_vec_elt_check ((((tree_class_check ((p), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2788, __FUNCTION__))->type_non_common.lang_1)), (3), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2788, __FUNCTION__))))), p, | ||||
2789 | "_OBJC_ProtocolOptInstMethods", | ||||
2790 | meta_proto_nst_methobjc_rt_trees[OCTI_RT_META_PROTO_NST_METH], all_meths); | ||||
2791 | |||||
2792 | opt_class_meth = | ||||
2793 | generate_v2_meth_descriptor_table (PROTOCOL_OPTIONAL_CLS_METHODS (p)(*((const_cast<tree *> (tree_vec_elt_check ((((tree_class_check ((p), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2793, __FUNCTION__))->type_non_common.lang_1)), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2793, __FUNCTION__))))), p, | ||||
2794 | "_OBJC_ProtocolOptClassMethods", | ||||
2795 | meta_proto_cls_methobjc_rt_trees[OCTI_RT_META_PROTO_CLS_METH], all_meths); | ||||
2796 | |||||
2797 | if (PROTOCOL_LIST (p)(*((const_cast<tree *> (tree_vec_elt_check ((((tree_class_check ((p), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2797, __FUNCTION__))->type_non_common.lang_1)), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2797, __FUNCTION__)))))) | ||||
2798 | refs_decl = generate_v2_protocol_list (p, NULL_TREE(tree) nullptr); | ||||
2799 | else | ||||
2800 | refs_decl = 0; | ||||
2801 | |||||
2802 | /* static struct objc_protocol _OBJC_Protocol_<mumble>; */ | ||||
2803 | protocol_name_expr = add_objc_string (PROTOCOL_NAME (p)(((tree_class_check ((p), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2803, __FUNCTION__))->type_common.name)), class_names); | ||||
2804 | |||||
2805 | if (refs_decl) | ||||
2806 | refs_expr = convert (build_pointer_type (objc_v2_protocol_templateobjc_v2_global_trees[OCTI_V2_PROTO_TEMPL]), | ||||
2807 | build_unary_op (loc, ADDR_EXPR, refs_decl, 0)); | ||||
2808 | else | ||||
2809 | refs_expr = build_int_cst (NULL_TREE(tree) nullptr, 0); | ||||
2810 | |||||
2811 | props = generate_v2_property_table (p, NULL_TREE(tree) nullptr); | ||||
2812 | |||||
2813 | tree ext_meth_types | ||||
2814 | = generate_v2_meth_type_list (all_meths, p, | ||||
2815 | "_OBJC_ProtocolMethodTypes"); | ||||
2816 | tree demangled_name = NULL_TREE(tree) nullptr; | ||||
2817 | tree class_prop_list = NULL_TREE(tree) nullptr; | ||||
2818 | |||||
2819 | initlist = build_v2_protocol_initializer (TREE_TYPE (decl)((contains_struct_check ((decl), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2819, __FUNCTION__))->typed.type), | ||||
2820 | protocol_name_expr, refs_expr, | ||||
2821 | inst_meth, class_meth, | ||||
2822 | opt_inst_meth, opt_class_meth, | ||||
2823 | props, ext_meth_types, | ||||
2824 | demangled_name,class_prop_list); | ||||
2825 | finish_var_decl (decl, initlist); | ||||
2826 | objc_add_to_protocol_list (p, decl); | ||||
2827 | all_meths.truncate (0); | ||||
2828 | } | ||||
2829 | |||||
2830 | if (some) | ||||
2831 | { | ||||
2832 | /* Make sure we get the Protocol class linked in - reference | ||||
2833 | it... */ | ||||
2834 | 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" ))); | ||||
2835 | /* ... but since we don't specifically use the reference... we | ||||
2836 | need to force it. */ | ||||
2837 | DECL_PRESERVE_P (p)(contains_struct_check ((p), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2837, __FUNCTION__))->decl_common.preserve_flag = 1; | ||||
2838 | } | ||||
2839 | } | ||||
2840 | |||||
2841 | static tree | ||||
2842 | generate_v2_dispatch_table (tree chain, const char *name, tree attr) | ||||
2843 | { | ||||
2844 | tree decl, method_list_template, initlist; | ||||
2845 | vec<constructor_elt, va_gc> *v = NULLnullptr; | ||||
2846 | int size, init_val; | ||||
2847 | |||||
2848 | if (!chain || !name || !(size = list_length (chain))) | ||||
2849 | return NULL_TREE(tree) nullptr; | ||||
2850 | |||||
2851 | method_list_template | ||||
2852 | = build_v2_method_list_template (objc_method_templateobjc_global_trees[OCTI_METH_TEMPL], size); | ||||
2853 | initlist | ||||
2854 | = build_dispatch_table_initializer (objc_method_templateobjc_global_trees[OCTI_METH_TEMPL], chain); | ||||
2855 | |||||
2856 | decl = start_var_decl (method_list_template, name); | ||||
2857 | |||||
2858 | 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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2858, __FUNCTION__))->type_common.size_unit)), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2858, __FUNCTION__))); | ||||
2859 | 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) | ||||
2860 | 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); | ||||
2861 | 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) | ||||
2862 | 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); | ||||
2863 | CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, initlist)do { constructor_elt _ce___ = {(tree) nullptr, initlist}; vec_safe_push ((v), _ce___); } while (0); | ||||
2864 | |||||
2865 | OBJCMETA (decl, objc_meta, attr)if (objc_rt_trees[OCTI_RT_OBJC_META]) ((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2865, __FUNCTION__))->decl_common.attributes) = build_tree_list ((objc_rt_trees[OCTI_RT_OBJC_META]), (attr));; | ||||
2866 | finish_var_decl (decl, | ||||
2867 | objc_build_constructor (TREE_TYPE (decl)((contains_struct_check ((decl), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2867, __FUNCTION__))->typed.type), v)); | ||||
2868 | return decl; | ||||
2869 | } | ||||
2870 | |||||
2871 | /* Init a category. */ | ||||
2872 | static tree | ||||
2873 | build_v2_category_initializer (tree type, tree cat_name, tree class_name, | ||||
2874 | tree inst_methods, tree class_methods, | ||||
2875 | tree protocol_list, tree property_list, | ||||
2876 | location_t loc) | ||||
2877 | { | ||||
2878 | tree expr, ltyp; | ||||
2879 | vec<constructor_elt, va_gc> *v = NULLnullptr; | ||||
2880 | |||||
2881 | CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, cat_name)do { constructor_elt _ce___ = {(tree) nullptr, cat_name}; vec_safe_push ((v), _ce___); } while (0); | ||||
2882 | CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, class_name)do { constructor_elt _ce___ = {(tree) nullptr, class_name}; vec_safe_push ((v), _ce___); } while (0); | ||||
2883 | |||||
2884 | ltyp = objc_method_list_ptrobjc_global_trees[OCTI_METH_LIST_TEMPL]; | ||||
2885 | if (inst_methods) | ||||
2886 | expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, inst_methods, 0)); | ||||
2887 | else | ||||
2888 | expr = convert (ltyp, null_pointer_nodeglobal_trees[TI_NULL_POINTER]); | ||||
2889 | CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr)do { constructor_elt _ce___ = {(tree) nullptr, expr}; vec_safe_push ((v), _ce___); } while (0); | ||||
2890 | |||||
2891 | if (class_methods) | ||||
2892 | expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, class_methods, 0)); | ||||
2893 | else | ||||
2894 | expr = convert (ltyp, null_pointer_nodeglobal_trees[TI_NULL_POINTER]); | ||||
2895 | CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr)do { constructor_elt _ce___ = {(tree) nullptr, expr}; vec_safe_push ((v), _ce___); } while (0); | ||||
2896 | |||||
2897 | /* protocol_list = */ | ||||
2898 | ltyp = build_pointer_type (objc_v2_protocol_templateobjc_v2_global_trees[OCTI_V2_PROTO_TEMPL]); | ||||
2899 | if (protocol_list) | ||||
2900 | expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, protocol_list, 0)); | ||||
2901 | else | ||||
2902 | expr = convert (ltyp, null_pointer_nodeglobal_trees[TI_NULL_POINTER]); | ||||
2903 | CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr)do { constructor_elt _ce___ = {(tree) nullptr, expr}; vec_safe_push ((v), _ce___); } while (0); | ||||
2904 | |||||
2905 | ltyp = objc_prop_list_ptrobjc_global_trees[OCTI_V1_PROP_LIST_TEMPL]; | ||||
2906 | if (property_list) | ||||
2907 | expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, property_list, 0)); | ||||
2908 | else | ||||
2909 | expr = convert (ltyp, null_pointer_nodeglobal_trees[TI_NULL_POINTER]); | ||||
2910 | CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr)do { constructor_elt _ce___ = {(tree) nullptr, expr}; vec_safe_push ((v), _ce___); } while (0); | ||||
2911 | |||||
2912 | return objc_build_constructor (type, v); | ||||
2913 | } | ||||
2914 | |||||
2915 | /* static struct category_t _OBJC_CATEGORY_$_<name> = { ... }; */ | ||||
2916 | |||||
2917 | static void | ||||
2918 | generate_v2_category (struct imp_entry *impent) | ||||
2919 | { | ||||
2920 | tree initlist, cat_name_expr, class_name_expr; | ||||
2921 | tree protocol_decl, category, props, t; | ||||
2922 | tree inst_methods = NULL_TREE(tree) nullptr, class_methods = NULL_TREE(tree) nullptr; | ||||
2923 | tree cat = impent->imp_context; | ||||
2924 | tree cat_decl = impent->class_decl; | ||||
2925 | location_t loc; | ||||
2926 | char buf[BUFSIZE1024]; | ||||
2927 | |||||
2928 | loc = DECL_SOURCE_LOCATION (cat_decl)((contains_struct_check ((cat_decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2928, __FUNCTION__))->decl_minimal.locus); | ||||
2929 | |||||
2930 | /* ??? not sure this is really necessary, the following references should | ||||
2931 | force appropriate linkage linkage... | ||||
2932 | -- but ... ensure a reference to the class... */ | ||||
2933 | t = objc_v2_get_class_reference (CLASS_NAME (cat)(((tree_class_check ((cat), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2933, __FUNCTION__))->type_common.name))); | ||||
2934 | /* ... which we ignore so force it out.. */ | ||||
2935 | DECL_PRESERVE_P (t)(contains_struct_check ((t), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2935, __FUNCTION__))->decl_common.preserve_flag = 1; | ||||
2936 | |||||
2937 | snprintf (buf, BUFSIZE1024, "OBJC_CLASS_$_%s", IDENTIFIER_POINTER (CLASS_NAME (cat))((const char *) (tree_check (((((tree_class_check ((cat), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2937, __FUNCTION__))->type_common.name))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2937, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
2938 | class_name_expr = create_extern_decl (objc_v2_class_templateobjc_v2_global_trees[OCTI_V2_CLS_TEMPL], buf); | ||||
2939 | class_name_expr = build_fold_addr_expr (class_name_expr)build_fold_addr_expr_loc (((location_t) 0), (class_name_expr) ); | ||||
2940 | |||||
2941 | cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat)(((tree_class_check ((cat), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2941, __FUNCTION__))->type_common.context)), class_names); | ||||
2942 | category = lookup_category (impent->imp_template, CLASS_SUPER_NAME (cat)(((tree_class_check ((cat), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2942, __FUNCTION__))->type_common.context))); | ||||
2943 | |||||
2944 | if (category && CLASS_PROTOCOL_LIST (category)(*((const_cast<tree *> (tree_vec_elt_check ((((tree_class_check ((category), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2944, __FUNCTION__))->type_non_common.lang_1)), (4), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2944, __FUNCTION__)))))) | ||||
2945 | { | ||||
2946 | generate_protocol_references (CLASS_PROTOCOL_LIST (category)(*((const_cast<tree *> (tree_vec_elt_check ((((tree_class_check ((category), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2946, __FUNCTION__))->type_non_common.lang_1)), (4), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2946, __FUNCTION__)))))); | ||||
2947 | protocol_decl = generate_v2_protocol_list (category, cat); | ||||
2948 | } | ||||
2949 | else | ||||
2950 | protocol_decl = NULL_TREE(tree) nullptr; | ||||
2951 | |||||
2952 | /* decl = update_var_decl(impent->class_decl); */ | ||||
2953 | |||||
2954 | props = generate_v2_property_table (NULL_TREE(tree) nullptr, cat); | ||||
2955 | |||||
2956 | if (CLASS_NST_METHODS (cat)(((tree_class_check ((cat), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2956, __FUNCTION__))->type_non_common.minval))) | ||||
2957 | { | ||||
2958 | snprintf (buf, BUFSIZE1024, "_OBJC_CategoryInstanceMethods_%s_%s", | ||||
2959 | IDENTIFIER_POINTER (CLASS_NAME (cat))((const char *) (tree_check (((((tree_class_check ((cat), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2959, __FUNCTION__))->type_common.name))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2959, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ), | ||||
2960 | IDENTIFIER_POINTER (CLASS_SUPER_NAME (cat))((const char *) (tree_check (((((tree_class_check ((cat), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2960, __FUNCTION__))->type_common.context))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2960, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
2961 | inst_methods = generate_v2_dispatch_table (CLASS_NST_METHODS (cat)(((tree_class_check ((cat), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2961, __FUNCTION__))->type_non_common.minval)), buf, | ||||
2962 | meta_cati_methobjc_rt_trees[OCTI_RT_META_CATEG_NST_METH]); | ||||
2963 | } | ||||
2964 | |||||
2965 | if (CLASS_CLS_METHODS (cat)(((tree_class_check ((cat), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2965, __FUNCTION__))->type_non_common.maxval))) | ||||
2966 | { | ||||
2967 | snprintf (buf, BUFSIZE1024, "_OBJC_CategoryClassMethods_%s_%s", | ||||
2968 | IDENTIFIER_POINTER (CLASS_NAME (cat))((const char *) (tree_check (((((tree_class_check ((cat), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2968, __FUNCTION__))->type_common.name))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2968, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ), | ||||
2969 | IDENTIFIER_POINTER (CLASS_SUPER_NAME (cat))((const char *) (tree_check (((((tree_class_check ((cat), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2969, __FUNCTION__))->type_common.context))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2969, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
2970 | class_methods = generate_v2_dispatch_table (CLASS_CLS_METHODS (cat)(((tree_class_check ((cat), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2970, __FUNCTION__))->type_non_common.maxval)), buf, | ||||
2971 | meta_catc_methobjc_rt_trees[OCTI_RT_META_CATEG_CLS_METH]); | ||||
2972 | } | ||||
2973 | |||||
2974 | initlist = build_v2_category_initializer (TREE_TYPE (cat_decl)((contains_struct_check ((cat_decl), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2974, __FUNCTION__))->typed.type), | ||||
2975 | cat_name_expr, class_name_expr, | ||||
2976 | inst_methods, class_methods, | ||||
2977 | protocol_decl, props, loc); | ||||
2978 | |||||
2979 | finish_var_decl (cat_decl, initlist); | ||||
2980 | impent->class_decl = cat_decl; | ||||
2981 | |||||
2982 | /* Add to list of pointers in __category_list section. */ | ||||
2983 | objc_v2_add_to_category_list (cat_decl); | ||||
2984 | if (has_load_impl (CLASS_CLS_METHODS (impent->imp_context)(((tree_class_check ((impent->imp_context), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 2984, __FUNCTION__))->type_non_common.maxval)))) | ||||
2985 | objc_v2_add_to_nonlazy_category_list (cat_decl); | ||||
2986 | } | ||||
2987 | |||||
2988 | /* This routine declares a variable to hold the offset for ivar | ||||
2989 | FIELD_DECL. Variable name is .objc_ivar.ClassName.IvarName. */ | ||||
2990 | |||||
2991 | struct GTY(()) ivarref_entry | ||||
2992 | { | ||||
2993 | tree decl; | ||||
2994 | tree offset; | ||||
2995 | }; | ||||
2996 | |||||
2997 | static GTY (()) vec<ivarref_entry, va_gc> *ivar_offset_refs; | ||||
2998 | |||||
2999 | static tree | ||||
3000 | ivar_offset_ref (tree class_name, tree field_decl) | ||||
3001 | { | ||||
3002 | tree decl, field_decl_id; | ||||
3003 | ivarref_entry e; | ||||
3004 | bool global_var; | ||||
3005 | char buf[512]; | ||||
3006 | |||||
3007 | create_ivar_offset_name (buf, class_name, field_decl); | ||||
3008 | field_decl_id = get_identifier (buf)(__builtin_constant_p (buf) ? get_identifier_with_length ((buf ), strlen (buf)) : get_identifier (buf)); | ||||
3009 | |||||
3010 | if (ivar_offset_refs) | ||||
3011 | { | ||||
3012 | int count; | ||||
3013 | ivarref_entry *ref; | ||||
3014 | FOR_EACH_VEC_ELT (*ivar_offset_refs, count, ref)for (count = 0; (*ivar_offset_refs).iterate ((count), &(ref )); ++(count)) | ||||
3015 | if (DECL_NAME (ref->decl)((contains_struct_check ((ref->decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3015, __FUNCTION__))->decl_minimal.name) == field_decl_id) | ||||
3016 | return ref->decl; | ||||
3017 | } | ||||
3018 | else | ||||
3019 | /* Somewhat arbitrary initial provision. */ | ||||
3020 | vec_alloc (ivar_offset_refs, 32); | ||||
3021 | |||||
3022 | /* We come here if we don't find a match or at the start. */ | ||||
3023 | global_var = (TREE_PUBLIC (field_decl)((field_decl)->base.public_flag) || TREE_PROTECTED (field_decl)((field_decl)->base.protected_flag)); | ||||
3024 | if (global_var) | ||||
3025 | decl = create_global_decl (TREE_TYPE (size_zero_node)((contains_struct_check ((global_trees[TI_SIZE_ZERO]), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3025, __FUNCTION__))->typed.type), buf); | ||||
3026 | else | ||||
3027 | decl = create_hidden_decl (TREE_TYPE (size_zero_node)((contains_struct_check ((global_trees[TI_SIZE_ZERO]), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3027, __FUNCTION__))->typed.type), buf); | ||||
3028 | |||||
3029 | /* Identify so that we can indirect these where the ABI requires. */ | ||||
3030 | OBJCMETA (decl, objc_meta, meta_ivar_ref)if (objc_rt_trees[OCTI_RT_OBJC_META]) ((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3030, __FUNCTION__))->decl_common.attributes) = build_tree_list ((objc_rt_trees[OCTI_RT_OBJC_META]), (objc_rt_trees[OCTI_RT_META_IVAR_REF ]));; | ||||
3031 | |||||
3032 | e.decl = decl; | ||||
3033 | e.offset = byte_position (field_decl); | ||||
3034 | vec_safe_push (ivar_offset_refs, e); | ||||
3035 | return decl; | ||||
3036 | } | ||||
3037 | |||||
3038 | /* This routine builds initializer-list needed to initialize 'struct | ||||
3039 | ivar_t list[count] of 'struct ivar_list_t' meta data. TYPE is | ||||
3040 | 'struct ivar_t' and FIELD_DECL is list of ivars for the target | ||||
3041 | class. */ | ||||
3042 | |||||
3043 | static tree | ||||
3044 | build_v2_ivar_list_initializer (tree class_name, tree type, tree field_decl) | ||||
3045 | { | ||||
3046 | vec<constructor_elt, va_gc> *inits = NULLnullptr; | ||||
3047 | |||||
3048 | do | ||||
3049 | { | ||||
3050 | vec<constructor_elt, va_gc> *ivar = NULLnullptr; | ||||
3051 | int val; | ||||
3052 | tree id; | ||||
3053 | |||||
3054 | /* Unnamed bitfields are ignored. */ | ||||
3055 | if (!DECL_NAME (field_decl)((contains_struct_check ((field_decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3055, __FUNCTION__))->decl_minimal.name)) | ||||
3056 | { | ||||
3057 | field_decl = DECL_CHAIN (field_decl)(((contains_struct_check (((contains_struct_check ((field_decl ), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3057, __FUNCTION__))), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3057, __FUNCTION__))->common.chain)); | ||||
3058 | continue; | ||||
3059 | } | ||||
3060 | |||||
3061 | /* Set offset. */ | ||||
3062 | 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) | ||||
3063 | 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) | ||||
3064 | 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) | ||||
3065 | 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) | ||||
3066 | 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); | ||||
3067 | |||||
3068 | /* Set name. */ | ||||
3069 | CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE,do { constructor_elt _ce___ = {(tree) nullptr, add_objc_string (((contains_struct_check ((field_decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3070, __FUNCTION__))->decl_minimal.name), meth_var_names )}; vec_safe_push ((ivar), _ce___); } while (0) | ||||
3070 | add_objc_string (DECL_NAME (field_decl),do { constructor_elt _ce___ = {(tree) nullptr, add_objc_string (((contains_struct_check ((field_decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3070, __FUNCTION__))->decl_minimal.name), meth_var_names )}; vec_safe_push ((ivar), _ce___); } while (0) | ||||
3071 | meth_var_names))do { constructor_elt _ce___ = {(tree) nullptr, add_objc_string (((contains_struct_check ((field_decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3070, __FUNCTION__))->decl_minimal.name), meth_var_names )}; vec_safe_push ((ivar), _ce___); } while (0); | ||||
3072 | |||||
3073 | /* Set type. */ | ||||
3074 | id = add_objc_string (encode_field_decl (field_decl), | ||||
3075 | meth_var_types); | ||||
3076 | CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, id)do { constructor_elt _ce___ = {(tree) nullptr, id}; vec_safe_push ((ivar), _ce___); } while (0); | ||||
3077 | |||||
3078 | /* Set alignment. */ | ||||
3079 | val = DECL_ALIGN_UNIT (field_decl)((((contains_struct_check ((field_decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3079, __FUNCTION__))->decl_common.align) ? ((unsigned)1) << (((contains_struct_check ((field_decl), (TS_DECL_COMMON ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3079, __FUNCTION__))->decl_common.align) - 1) : 0) / (8) ); | ||||
3080 | val = exact_log2 (val); | ||||
3081 | 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) | ||||
3082 | 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); | ||||
3083 | |||||
3084 | /* Set size. */ | ||||
3085 | 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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3085, __FUNCTION__))->decl_common.size_unit)), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3085, __FUNCTION__))); | ||||
3086 | 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) | ||||
3087 | 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); | ||||
3088 | |||||
3089 | CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,do { constructor_elt _ce___ = {(tree) nullptr, objc_build_constructor (type, ivar)}; vec_safe_push ((inits), _ce___); } while (0) | ||||
3090 | objc_build_constructor (type, ivar))do { constructor_elt _ce___ = {(tree) nullptr, objc_build_constructor (type, ivar)}; vec_safe_push ((inits), _ce___); } while (0); | ||||
3091 | |||||
3092 | do | ||||
3093 | field_decl = DECL_CHAIN (field_decl)(((contains_struct_check (((contains_struct_check ((field_decl ), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3093, __FUNCTION__))), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3093, __FUNCTION__))->common.chain)); | ||||
3094 | while (field_decl && TREE_CODE (field_decl)((enum tree_code) (field_decl)->base.code) != FIELD_DECL); | ||||
3095 | } | ||||
3096 | while (field_decl); | ||||
3097 | |||||
3098 | return objc_build_constructor (build_array_type (type, 0), inits); | ||||
3099 | } | ||||
3100 | |||||
3101 | /* | ||||
3102 | struct ivar_list_t | ||||
3103 | { | ||||
3104 | uint32 entsize; | ||||
3105 | uint32 count; | ||||
3106 | struct iver_t list[count]; | ||||
3107 | }; | ||||
3108 | */ | ||||
3109 | |||||
3110 | static tree | ||||
3111 | build_v2_ivar_list_t_template (tree list_type, int size) | ||||
3112 | { | ||||
3113 | tree objc_ivar_list_record; | ||||
3114 | tree decls, *chain = NULLnullptr; | ||||
3115 | |||||
3116 | /* Anonymous. */ | ||||
3117 | objc_ivar_list_record = objc_start_struct (NULL_TREE(tree) nullptr); | ||||
3118 | |||||
3119 | /* uint32 entsize; */ | ||||
3120 | decls = add_field_decl (integer_type_nodeinteger_types[itk_int], "entsize", &chain); | ||||
3121 | |||||
3122 | /* uint32 count; */ | ||||
3123 | add_field_decl (integer_type_nodeinteger_types[itk_int], "count", &chain); | ||||
3124 | |||||
3125 | /* struct objc_ivar ivar_list[]; */ | ||||
3126 | add_field_decl (build_sized_array_type (list_type, size), | ||||
3127 | "list", &chain); | ||||
3128 | |||||
3129 | objc_finish_struct (objc_ivar_list_record, decls); | ||||
3130 | return objc_ivar_list_record; | ||||
3131 | } | ||||
3132 | |||||
3133 | /* This routine declares a static variable of type 'struct | ||||
3134 | ivar_list_t' and initializes it. chain is the source of the data, | ||||
3135 | name is the name for the var. attr is the meta-data section tag | ||||
3136 | attribute. templ is the implementation template for the class. */ | ||||
3137 | |||||
3138 | static tree | ||||
3139 | generate_v2_ivars_list (tree chain, const char *name, tree attr, tree templ) | ||||
3140 | { | ||||
3141 | tree decl, initlist, ivar_list_template; | ||||
3142 | vec<constructor_elt, va_gc> *inits = NULLnullptr; | ||||
3143 | int size, ivar_t_size; | ||||
3144 | |||||
3145 | if (!chain || !name || !(size = ivar_list_length (chain))) | ||||
3146 | return NULL_TREE(tree) nullptr; | ||||
3147 | |||||
3148 | generating_instance_variables = 1; | ||||
3149 | ivar_list_template = build_v2_ivar_list_t_template (objc_v2_ivar_templateobjc_v2_global_trees[OCTI_V2_IVAR_TEMPL], | ||||
3150 | size); | ||||
3151 | |||||
3152 | initlist = build_v2_ivar_list_initializer (CLASS_NAME (templ)(((tree_class_check ((templ), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3152, __FUNCTION__))->type_common.name)), | ||||
3153 | objc_v2_ivar_templateobjc_v2_global_trees[OCTI_V2_IVAR_TEMPL], chain); | ||||
3154 | 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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3154, __FUNCTION__))->type_common.size_unit)), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3154, __FUNCTION__))); | ||||
3155 | |||||
3156 | decl = start_var_decl (ivar_list_template, name); | ||||
3157 | 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) | ||||
3158 | 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); | ||||
3159 | 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) | ||||
3160 | 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); | ||||
3161 | CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, initlist)do { constructor_elt _ce___ = {(tree) nullptr, initlist}; vec_safe_push ((inits), _ce___); } while (0); | ||||
3162 | OBJCMETA (decl, objc_meta, attr)if (objc_rt_trees[OCTI_RT_OBJC_META]) ((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3162, __FUNCTION__))->decl_common.attributes) = build_tree_list ((objc_rt_trees[OCTI_RT_OBJC_META]), (attr));; | ||||
3163 | finish_var_decl (decl, objc_build_constructor (TREE_TYPE (decl)((contains_struct_check ((decl), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3163, __FUNCTION__))->typed.type), inits)); | ||||
3164 | generating_instance_variables = 0; | ||||
3165 | return decl; | ||||
3166 | } | ||||
3167 | |||||
3168 | /* Routine to build initializer list to initialize objects of type | ||||
3169 | struct class_t; */ | ||||
3170 | |||||
3171 | static tree | ||||
3172 | build_v2_class_t_initializer (tree type, tree isa, tree superclass, | ||||
3173 | tree ro, tree cache, tree vtable) | ||||
3174 | { | ||||
3175 | vec<constructor_elt, va_gc> *initlist = NULLnullptr; | ||||
3176 | |||||
3177 | /* isa */ | ||||
3178 | CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, isa)do { constructor_elt _ce___ = {(tree) nullptr, isa}; vec_safe_push ((initlist), _ce___); } while (0); | ||||
3179 | |||||
3180 | /* superclass */ | ||||
3181 | CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, superclass)do { constructor_elt _ce___ = {(tree) nullptr, superclass}; vec_safe_push ((initlist), _ce___); } while (0); | ||||
3182 | |||||
3183 | /* cache */ | ||||
3184 | if (cache) | ||||
3185 | CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, cache)do { constructor_elt _ce___ = {(tree) nullptr, cache}; vec_safe_push ((initlist), _ce___); } while (0); | ||||
3186 | else | ||||
3187 | 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); | ||||
3188 | |||||
3189 | /* vtable */ | ||||
3190 | if (vtable) | ||||
3191 | CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, vtable)do { constructor_elt _ce___ = {(tree) nullptr, vtable}; vec_safe_push ((initlist), _ce___); } while (0); | ||||
3192 | else | ||||
3193 | 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); | ||||
3194 | |||||
3195 | /* ro */ | ||||
3196 | CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, ro)do { constructor_elt _ce___ = {(tree) nullptr, ro}; vec_safe_push ((initlist), _ce___); } while (0); | ||||
3197 | |||||
3198 | return objc_build_constructor (type, initlist); | ||||
3199 | } | ||||
3200 | |||||
3201 | /* Routine to build object of struct class_ro_t { ... }; */ | ||||
3202 | |||||
3203 | static tree | ||||
3204 | build_v2_class_ro_t_initializer (tree type, tree name, | ||||
3205 | unsigned int flags, unsigned int instanceStart, | ||||
3206 | unsigned int instanceSize, | ||||
3207 | tree ivarLayout, | ||||
3208 | tree baseMethods, tree baseProtocols, | ||||
3209 | tree ivars, tree property_list) | ||||
3210 | { | ||||
3211 | tree expr, unsigned_char_star, ltyp; | ||||
3212 | location_t loc; | ||||
3213 | vec<constructor_elt, va_gc> *initlist = NULLnullptr; | ||||
3214 | |||||
3215 | /* TODO: fish out the real location from somewhere. */ | ||||
3216 | loc = UNKNOWN_LOCATION((location_t) 0); | ||||
3217 | |||||
3218 | /* flags */ | ||||
3219 | 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) | ||||
3220 | 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); | ||||
3221 | |||||
3222 | /* instanceStart */ | ||||
3223 | 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) | ||||
3224 | 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); | ||||
3225 | |||||
3226 | /* instanceSize */ | ||||
3227 | 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) | ||||
3228 | 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); | ||||
3229 | |||||
3230 | /* This ABI is currently only used on m64 NeXT. We always | ||||
3231 | explicitly declare the alignment padding. */ | ||||
3232 | /* reserved, pads alignment. */ | ||||
3233 | 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) | ||||
3234 | 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); | ||||
3235 | |||||
3236 | /* ivarLayout */ | ||||
3237 | unsigned_char_star = build_pointer_type (unsigned_char_type_nodeinteger_types[itk_unsigned_char]); | ||||
3238 | if (ivarLayout) | ||||
3239 | expr = ivarLayout; | ||||
3240 | else | ||||
3241 | expr = convert (unsigned_char_star, null_pointer_nodeglobal_trees[TI_NULL_POINTER]); | ||||
3242 | CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, expr)do { constructor_elt _ce___ = {(tree) nullptr, expr}; vec_safe_push ((initlist), _ce___); } while (0); | ||||
3243 | |||||
3244 | /* name */ | ||||
3245 | 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); | ||||
3246 | |||||
3247 | /* baseMethods */ | ||||
3248 | ltyp = objc_method_list_ptrobjc_global_trees[OCTI_METH_LIST_TEMPL]; | ||||
3249 | if (baseMethods) | ||||
3250 | expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, baseMethods, 0)); | ||||
3251 | else | ||||
3252 | expr = convert (ltyp, null_pointer_nodeglobal_trees[TI_NULL_POINTER]); | ||||
3253 | CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, expr)do { constructor_elt _ce___ = {(tree) nullptr, expr}; vec_safe_push ((initlist), _ce___); } while (0); | ||||
3254 | |||||
3255 | /* baseProtocols */ | ||||
3256 | ltyp = build_pointer_type (xref_tag (RECORD_TYPE, | ||||
3257 | 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")))); | ||||
3258 | if (baseProtocols) | ||||
3259 | expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, baseProtocols, 0)); | ||||
3260 | else | ||||
3261 | expr = convert (ltyp, null_pointer_nodeglobal_trees[TI_NULL_POINTER]); | ||||
3262 | CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, expr)do { constructor_elt _ce___ = {(tree) nullptr, expr}; vec_safe_push ((initlist), _ce___); } while (0); | ||||
3263 | |||||
3264 | /* ivars */ | ||||
3265 | ltyp = objc_v2_ivar_list_ptrobjc_v2_global_trees[OCTI_V2_IVAR_LIST_TEMPL]; | ||||
3266 | if (ivars) | ||||
3267 | expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, ivars, 0)); | ||||
3268 | else | ||||
3269 | expr = convert (ltyp, null_pointer_nodeglobal_trees[TI_NULL_POINTER]); | ||||
3270 | CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, expr)do { constructor_elt _ce___ = {(tree) nullptr, expr}; vec_safe_push ((initlist), _ce___); } while (0); | ||||
3271 | |||||
3272 | /* TODO: We don't yet have the weak/strong stuff... */ | ||||
3273 | /* weakIvarLayout */ | ||||
3274 | 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) | ||||
3275 | 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); | ||||
3276 | |||||
3277 | /* property list */ | ||||
3278 | ltyp = objc_prop_list_ptrobjc_global_trees[OCTI_V1_PROP_LIST_TEMPL]; | ||||
3279 | if (property_list) | ||||
3280 | expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, property_list, 0)); | ||||
3281 | else | ||||
3282 | expr = convert (ltyp, null_pointer_nodeglobal_trees[TI_NULL_POINTER]); | ||||
3283 | CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, expr)do { constructor_elt _ce___ = {(tree) nullptr, expr}; vec_safe_push ((initlist), _ce___); } while (0); | ||||
3284 | return objc_build_constructor (type, initlist); | ||||
3285 | } | ||||
3286 | |||||
3287 | static GTY (()) vec<ident_data_tuple, va_gc> *ehtype_list; | ||||
3288 | |||||
3289 | /* Record a name as needing a catcher. */ | ||||
3290 | static void | ||||
3291 | objc_v2_add_to_ehtype_list (tree name) | ||||
3292 | { | ||||
3293 | ident_data_tuple e; | ||||
3294 | if (ehtype_list) | ||||
3295 | { | ||||
3296 | int count = 0; | ||||
3297 | ident_data_tuple *ref; | ||||
3298 | |||||
3299 | FOR_EACH_VEC_ELT (*ehtype_list, count, ref)for (count = 0; (*ehtype_list).iterate ((count), &(ref)); ++(count)) | ||||
3300 | if (ref->ident == name) | ||||
3301 | return; /* Already entered. */ | ||||
3302 | } | ||||
3303 | else | ||||
3304 | /* Arbitrary initial count. */ | ||||
3305 | vec_alloc (ehtype_list, 8); | ||||
3306 | |||||
3307 | /* Not found, or new list. */ | ||||
3308 | e.ident = name; | ||||
3309 | e.data = NULL_TREE(tree) nullptr; | ||||
3310 | vec_safe_push (ehtype_list, e); | ||||
3311 | } | ||||
3312 | |||||
3313 | static void | ||||
3314 | generate_v2_class_structs (struct imp_entry *impent) | ||||
3315 | { | ||||
3316 | tree decl, name_expr, initlist, protocol_decl, metaclass_decl, class_decl; | ||||
3317 | tree field, firstIvar, chain; | ||||
3318 | tree class_superclass_expr, metaclass_superclass_expr, props; | ||||
3319 | /* TODO: figure out how to compute this. */ | ||||
3320 | tree ivarLayout = NULL_TREE(tree) nullptr; | ||||
3321 | tree my_super_id = NULL_TREE(tree) nullptr, root_expr = NULL_TREE(tree) nullptr; | ||||
3322 | tree inst_methods = NULL_TREE(tree) nullptr, class_methods = NULL_TREE(tree) nullptr; | ||||
3323 | tree inst_ivars = NULL_TREE(tree) nullptr, class_ivars = NULL_TREE(tree) nullptr; | ||||
3324 | location_t loc; | ||||
3325 | char buf[BUFSIZE1024]; | ||||
3326 | unsigned int instanceStart, instanceSize; | ||||
3327 | unsigned int flags = 0x01; /* RO_META */ | ||||
3328 | int cls_flags = impent->has_cxx_cdtors ? OBJC2_CLS_HAS_CXX_STRUCTORS0x0004L | ||||
3329 | : 0 ; | ||||
3330 | |||||
3331 | class_decl = impent->class_decl; | ||||
3332 | metaclass_decl = impent->meta_decl; | ||||
3333 | loc = DECL_SOURCE_LOCATION (class_decl)((contains_struct_check ((class_decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3333, __FUNCTION__))->decl_minimal.locus); | ||||
3334 | |||||
3335 | DECL_EXTERNAL (class_decl)((contains_struct_check ((class_decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3335, __FUNCTION__))->decl_common.decl_flag_1) = DECL_EXTERNAL (metaclass_decl)((contains_struct_check ((metaclass_decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3335, __FUNCTION__))->decl_common.decl_flag_1) = 0; | ||||
3336 | TREE_PUBLIC (class_decl)((class_decl)->base.public_flag) = TREE_PUBLIC (metaclass_decl)((metaclass_decl)->base.public_flag) = 1; | ||||
3337 | #ifdef OBJCPLUS | ||||
3338 | 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 ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3338, __FUNCTION__), 0 : 0)); | ||||
3339 | 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 ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3339, __FUNCTION__), 0 : 0)); | ||||
3340 | #endif | ||||
3341 | |||||
3342 | /* Generation of data for meta class. */ | ||||
3343 | my_super_id = CLASS_SUPER_NAME (impent->imp_template)(((tree_class_check ((impent->imp_template), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3343, __FUNCTION__))->type_common.context)); | ||||
3344 | if (my_super_id) | ||||
3345 | { | ||||
3346 | /* Compute reference to root's name. For a meta class, "isa" is | ||||
3347 | a reference to the root class name. */ | ||||
3348 | tree my_root_id = my_super_id; | ||||
3349 | tree my_root_int, interface; | ||||
3350 | do | ||||
3351 | { | ||||
3352 | my_root_int = lookup_interface (my_root_id); | ||||
3353 | |||||
3354 | if (my_root_int && CLASS_SUPER_NAME (my_root_int)(((tree_class_check ((my_root_int), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3354, __FUNCTION__))->type_common.context))) | ||||
3355 | my_root_id = CLASS_SUPER_NAME (my_root_int)(((tree_class_check ((my_root_int), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3355, __FUNCTION__))->type_common.context)); | ||||
3356 | else | ||||
3357 | break; | ||||
3358 | } | ||||
3359 | while (1); | ||||
3360 | |||||
3361 | /* {extern} struct class_t OBJC_METACLASS_$_<my_root_int> | ||||
3362 | create extern if not already declared. */ | ||||
3363 | snprintf (buf, BUFSIZE1024, "OBJC_METACLASS_$_%s", | ||||
3364 | IDENTIFIER_POINTER (CLASS_NAME (my_root_int))((const char *) (tree_check (((((tree_class_check ((my_root_int ), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3364, __FUNCTION__))->type_common.name))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3364, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
3365 | root_expr = create_extern_decl (objc_v2_class_templateobjc_v2_global_trees[OCTI_V2_CLS_TEMPL], buf); | ||||
3366 | root_expr = build_fold_addr_expr (root_expr)build_fold_addr_expr_loc (((location_t) 0), (root_expr)); | ||||
3367 | |||||
3368 | /* Install class `isa' and `super' pointers at runtime. */ | ||||
3369 | interface = lookup_interface (my_super_id); | ||||
3370 | gcc_assert (interface)((void)(!(interface) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3370, __FUNCTION__), 0 : 0)); | ||||
3371 | /* Similarly, for OBJC_CLASS_$_<interface>... */ | ||||
3372 | snprintf (buf, BUFSIZE1024, "OBJC_CLASS_$_%s", | ||||
3373 | IDENTIFIER_POINTER (CLASS_NAME (interface))((const char *) (tree_check (((((tree_class_check ((interface ), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3373, __FUNCTION__))->type_common.name))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3373, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
3374 | class_superclass_expr = create_extern_decl (objc_v2_class_templateobjc_v2_global_trees[OCTI_V2_CLS_TEMPL], buf); | ||||
3375 | class_superclass_expr = build_fold_addr_expr (class_superclass_expr)build_fold_addr_expr_loc (((location_t) 0), (class_superclass_expr )); | ||||
3376 | /* ... and for OBJC_METACLASS_$_<interface>. */ | ||||
3377 | snprintf (buf, BUFSIZE1024, "OBJC_METACLASS_$_%s", | ||||
3378 | IDENTIFIER_POINTER (CLASS_NAME (interface))((const char *) (tree_check (((((tree_class_check ((interface ), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3378, __FUNCTION__))->type_common.name))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3378, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
3379 | metaclass_superclass_expr = create_extern_decl (objc_v2_class_templateobjc_v2_global_trees[OCTI_V2_CLS_TEMPL], buf); | ||||
3380 | metaclass_superclass_expr = build_fold_addr_expr (metaclass_superclass_expr)build_fold_addr_expr_loc (((location_t) 0), (metaclass_superclass_expr )); | ||||
3381 | } | ||||
3382 | else | ||||
3383 | { | ||||
3384 | /* Root class. */ | ||||
3385 | root_expr = build_unary_op (loc, ADDR_EXPR, metaclass_decl, 0); | ||||
3386 | metaclass_superclass_expr = build_unary_op (loc, ADDR_EXPR, class_decl, 0); | ||||
3387 | class_superclass_expr = build_int_cst (NULL_TREE(tree) nullptr, 0); | ||||
3388 | flags |= 0x02; /* RO_ROOT: it is also a root meta class. */ | ||||
3389 | } | ||||
3390 | |||||
3391 | if (CLASS_PROTOCOL_LIST (impent->imp_template)(*((const_cast<tree *> (tree_vec_elt_check ((((tree_class_check ((impent->imp_template), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3391, __FUNCTION__))->type_non_common.lang_1)), (4), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3391, __FUNCTION__)))))) | ||||
3392 | { | ||||
3393 | generate_protocol_references (CLASS_PROTOCOL_LIST (impent->imp_template)(*((const_cast<tree *> (tree_vec_elt_check ((((tree_class_check ((impent->imp_template), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3393, __FUNCTION__))->type_non_common.lang_1)), (4), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3393, __FUNCTION__)))))); | ||||
3394 | protocol_decl = generate_v2_protocol_list (impent->imp_template, | ||||
3395 | impent->imp_context); | ||||
3396 | } | ||||
3397 | else | ||||
3398 | protocol_decl = 0; | ||||
3399 | |||||
3400 | name_expr = add_objc_string (CLASS_NAME (impent->imp_template)(((tree_class_check ((impent->imp_template), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3400, __FUNCTION__))->type_common.name)), | ||||
3401 | class_names); | ||||
3402 | |||||
3403 | if (CLASS_CLS_METHODS (impent->imp_context)(((tree_class_check ((impent->imp_context), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3403, __FUNCTION__))->type_non_common.maxval))) | ||||
3404 | { | ||||
3405 | snprintf (buf, BUFSIZE1024, "_OBJC_ClassMethods_%s", | ||||
3406 | IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context))((const char *) (tree_check (((((tree_class_check ((impent-> imp_context), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3406, __FUNCTION__))->type_common.name))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3406, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
3407 | class_methods = | ||||
3408 | generate_v2_dispatch_table (CLASS_CLS_METHODS (impent->imp_context)(((tree_class_check ((impent->imp_context), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3408, __FUNCTION__))->type_non_common.maxval)), | ||||
3409 | buf, meta_clac_methobjc_rt_trees[OCTI_RT_META_CLASS_CLS_METH]); | ||||
3410 | } | ||||
3411 | |||||
3412 | 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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3412, __FUNCTION__))->type_common.size_unit)), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3412, __FUNCTION__))); | ||||
3413 | |||||
3414 | /* Currently there are no class ivars and generation of class | ||||
3415 | variables for the root of the inheritance has been removed. It | ||||
3416 | causes multiple defines if there are two root classes in the | ||||
3417 | link, because each will define its own identically-named offset | ||||
3418 | variable. */ | ||||
3419 | |||||
3420 | class_ivars = NULL_TREE(tree) nullptr; | ||||
3421 | /* TODO: Add total size of class variables when implemented. */ | ||||
3422 | 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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3422, __FUNCTION__))->type_common.size_unit)), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3422, __FUNCTION__))); | ||||
3423 | |||||
3424 | /* So now build the META CLASS structs. */ | ||||
3425 | /* static struct class_ro_t _OBJC_METACLASS_Foo = { ... }; */ | ||||
3426 | |||||
3427 | decl = start_var_decl (objc_v2_class_ro_templateobjc_v2_global_trees[OCTI_V2_CLS_RO_TEMPL], | ||||
3428 | newabi_append_ro (IDENTIFIER_POINTER((const char *) (tree_check ((((contains_struct_check ((metaclass_decl ), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3429, __FUNCTION__))->decl_minimal.name)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3429, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ) | ||||
3429 | (DECL_NAME (metaclass_decl))((const char *) (tree_check ((((contains_struct_check ((metaclass_decl ), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3429, __FUNCTION__))->decl_minimal.name)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3429, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ))); | ||||
3430 | |||||
3431 | /* TODO: ivarLayout needs t be built. */ | ||||
3432 | initlist = | ||||
3433 | build_v2_class_ro_t_initializer (TREE_TYPE (decl)((contains_struct_check ((decl), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3433, __FUNCTION__))->typed.type), name_expr, | ||||
3434 | (flags | cls_flags), instanceStart, | ||||
3435 | instanceSize, ivarLayout, | ||||
3436 | class_methods, protocol_decl, | ||||
3437 | class_ivars, NULL_TREE(tree) nullptr); | ||||
3438 | /* The ROs sit in the default const section. */ | ||||
3439 | OBJCMETA (decl, objc_meta, meta_base)if (objc_rt_trees[OCTI_RT_OBJC_META]) ((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3439, __FUNCTION__))->decl_common.attributes) = build_tree_list ((objc_rt_trees[OCTI_RT_OBJC_META]), (objc_rt_trees[OCTI_RT_META_BASE ]));; | ||||
3440 | finish_var_decl (decl, initlist); | ||||
3441 | |||||
3442 | /* static struct class_t _OBJC_METACLASS_Foo = { ... }; */ | ||||
3443 | initlist = | ||||
3444 | build_v2_class_t_initializer (TREE_TYPE (metaclass_decl)((contains_struct_check ((metaclass_decl), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3444, __FUNCTION__))->typed.type), | ||||
3445 | root_expr, | ||||
3446 | metaclass_superclass_expr, | ||||
3447 | build_fold_addr_expr (decl)build_fold_addr_expr_loc (((location_t) 0), (decl)), | ||||
3448 | build_fold_addr_expr (UOBJC_V2_CACHE_decl)build_fold_addr_expr_loc (((location_t) 0), (objc_v2_global_trees [OCTI_V2_CACHE_DECL])), | ||||
3449 | build_fold_addr_expr (UOBJC_V2_VTABLE_decl)build_fold_addr_expr_loc (((location_t) 0), (objc_v2_global_trees [OCTI_V2_VTABLE_DECL]))); | ||||
3450 | /* The class section attributes are set when they are created. */ | ||||
3451 | finish_var_decl (metaclass_decl, initlist); | ||||
3452 | impent->meta_decl = metaclass_decl; | ||||
3453 | |||||
3454 | /* So now build the CLASS structs. */ | ||||
3455 | |||||
3456 | flags = 0x0; /* ... */ | ||||
3457 | if (!my_super_id) | ||||
3458 | flags |= 0x02; /* RO_ROOT: this is a root class */ | ||||
3459 | |||||
3460 | if (DECL_VISIBILITY (class_decl)((contains_struct_check ((class_decl), (TS_DECL_WITH_VIS), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3460, __FUNCTION__))->decl_with_vis.visibility) == VISIBILITY_HIDDEN) | ||||
3461 | flags |= 0x10; /* RO_HIDDEN, OBJC2_CLS_HIDDEN; */ | ||||
3462 | |||||
3463 | if (objc2_objc_exception_attr (impent->imp_template)) | ||||
3464 | flags |= 0x20; /* RO_EXCEPTION */ | ||||
3465 | |||||
3466 | if (CLASS_NST_METHODS (impent->imp_context)(((tree_class_check ((impent->imp_context), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3466, __FUNCTION__))->type_non_common.minval))) | ||||
3467 | { | ||||
3468 | snprintf (buf, BUFSIZE1024, "_OBJC_InstanceMethods_%s", | ||||
3469 | IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context))((const char *) (tree_check (((((tree_class_check ((impent-> imp_context), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3469, __FUNCTION__))->type_common.name))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3469, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
3470 | inst_methods = | ||||
3471 | generate_v2_dispatch_table (CLASS_NST_METHODS (impent->imp_context)(((tree_class_check ((impent->imp_context), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3471, __FUNCTION__))->type_non_common.minval)), | ||||
3472 | buf, meta_clai_methobjc_rt_trees[OCTI_RT_META_CLASS_NST_METH]); | ||||
3473 | } | ||||
3474 | |||||
3475 | /* Sort out the ivars before we try to compute the class sizes. */ | ||||
3476 | if ((chain = CLASS_IVARS (impent->imp_template)(*((const_cast<tree *> (tree_vec_elt_check ((((tree_class_check ((impent->imp_template), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3476, __FUNCTION__))->type_non_common.lang_1)), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3476, __FUNCTION__))))))) | ||||
3477 | { | ||||
3478 | snprintf (buf, BUFSIZE1024, "_OBJC_InstanceIvars_%s", | ||||
3479 | IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context))((const char *) (tree_check (((((tree_class_check ((impent-> imp_context), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3479, __FUNCTION__))->type_common.name))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3479, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
3480 | inst_ivars = generate_v2_ivars_list (chain, buf, meta_clai_varsobjc_rt_trees[OCTI_RT_META_CLASS_NST_VARS], | ||||
3481 | impent->imp_template); | ||||
3482 | } | ||||
3483 | |||||
3484 | /* Compute instanceStart. */ | ||||
3485 | gcc_assert (CLASS_STATIC_TEMPLATE (impent->imp_template))((void)(!((*((const_cast<tree *> (tree_vec_elt_check (( ((tree_class_check ((impent->imp_template), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3485, __FUNCTION__))->type_non_common.lang_1)), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3485, __FUNCTION__)))))) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3485, __FUNCTION__), 0 : 0)); | ||||
3486 | 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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3486, __FUNCTION__))->type_non_common.lang_1)), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3486, __FUNCTION__)))))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3486, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.values); | ||||
3487 | if (my_super_id && field && TREE_CHAIN (field)((contains_struct_check ((field), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3487, __FUNCTION__))->common.chain)) | ||||
3488 | field = TREE_CHAIN (field)((contains_struct_check ((field), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3488, __FUNCTION__))->common.chain); | ||||
3489 | |||||
3490 | firstIvar = field; | ||||
3491 | |||||
3492 | while (firstIvar && TREE_CODE (firstIvar)((enum tree_code) (firstIvar)->base.code) != FIELD_DECL) | ||||
3493 | firstIvar = TREE_CHAIN (firstIvar)((contains_struct_check ((firstIvar), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3493, __FUNCTION__))->common.chain); | ||||
3494 | |||||
3495 | gcc_assert (inst_ivars? (firstIvar != NULL_TREE): true)((void)(!(inst_ivars? (firstIvar != (tree) nullptr): true) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3495, __FUNCTION__), 0 : 0)); | ||||
3496 | |||||
3497 | /* Compute instanceSize. */ | ||||
3498 | while (field && TREE_CHAIN (field)((contains_struct_check ((field), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3498, __FUNCTION__))->common.chain) | ||||
3499 | && TREE_CODE (TREE_CHAIN (field))((enum tree_code) (((contains_struct_check ((field), (TS_COMMON ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3499, __FUNCTION__))->common.chain))->base.code) == FIELD_DECL) | ||||
3500 | field = TREE_CHAIN (field)((contains_struct_check ((field), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3500, __FUNCTION__))->common.chain); | ||||
3501 | |||||
3502 | if (field && TREE_CODE (field)((enum tree_code) (field)->base.code) == FIELD_DECL) | ||||
3503 | instanceSize = int_byte_position (field) * BITS_PER_UNIT(8) | ||||
3504 | + tree_to_shwi (DECL_SIZE (field)((contains_struct_check ((field), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3504, __FUNCTION__))->decl_common.size)); | ||||
3505 | else | ||||
3506 | instanceSize = 0; | ||||
3507 | instanceSize /= BITS_PER_UNIT(8); | ||||
3508 | |||||
3509 | props = generate_v2_property_table (NULL_TREE(tree) nullptr, impent->imp_context); | ||||
3510 | |||||
3511 | /* If the class has no ivars, instanceStart should be set to the | ||||
3512 | superclass's instanceSize. */ | ||||
3513 | instanceStart = | ||||
3514 | (inst_ivars != NULL_TREE(tree) nullptr) ? (unsigned) int_byte_position (firstIvar) | ||||
3515 | : instanceSize; | ||||
3516 | |||||
3517 | /* static struct class_ro_t _OBJC_CLASS_Foo = { ... }; */ | ||||
3518 | decl = start_var_decl (objc_v2_class_ro_templateobjc_v2_global_trees[OCTI_V2_CLS_RO_TEMPL], | ||||
3519 | newabi_append_ro (IDENTIFIER_POINTER((const char *) (tree_check ((((contains_struct_check ((class_decl ), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3520, __FUNCTION__))->decl_minimal.name)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3520, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ) | ||||
3520 | (DECL_NAME (class_decl))((const char *) (tree_check ((((contains_struct_check ((class_decl ), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3520, __FUNCTION__))->decl_minimal.name)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3520, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ))); | ||||
3521 | |||||
3522 | initlist = | ||||
3523 | build_v2_class_ro_t_initializer (TREE_TYPE (decl)((contains_struct_check ((decl), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3523, __FUNCTION__))->typed.type), name_expr, | ||||
3524 | (flags | cls_flags), instanceStart, | ||||
3525 | instanceSize, ivarLayout, | ||||
3526 | inst_methods, protocol_decl, | ||||
3527 | inst_ivars, props); | ||||
3528 | /* The ROs sit in the default const section. */ | ||||
3529 | OBJCMETA (decl, objc_meta, meta_base)if (objc_rt_trees[OCTI_RT_OBJC_META]) ((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3529, __FUNCTION__))->decl_common.attributes) = build_tree_list ((objc_rt_trees[OCTI_RT_OBJC_META]), (objc_rt_trees[OCTI_RT_META_BASE ]));; | ||||
3530 | finish_var_decl (decl, initlist); | ||||
3531 | |||||
3532 | /* static struct class_t _OBJC_CLASS_Foo = { ... }; */ | ||||
3533 | initlist = build_v2_class_t_initializer (TREE_TYPE (class_decl)((contains_struct_check ((class_decl), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3533, __FUNCTION__))->typed.type), | ||||
3534 | build_fold_addr_expr (metaclass_decl)build_fold_addr_expr_loc (((location_t) 0), (metaclass_decl)), | ||||
3535 | class_superclass_expr, | ||||
3536 | build_fold_addr_expr (decl)build_fold_addr_expr_loc (((location_t) 0), (decl)), | ||||
3537 | build_fold_addr_expr (UOBJC_V2_CACHE_decl)build_fold_addr_expr_loc (((location_t) 0), (objc_v2_global_trees [OCTI_V2_CACHE_DECL])), | ||||
3538 | build_fold_addr_expr (UOBJC_V2_VTABLE_decl)build_fold_addr_expr_loc (((location_t) 0), (objc_v2_global_trees [OCTI_V2_VTABLE_DECL]))); | ||||
3539 | |||||
3540 | /* The class section attributes are set when they are created. */ | ||||
3541 | finish_var_decl (class_decl, initlist); | ||||
3542 | impent->class_decl = class_decl; | ||||
3543 | |||||
3544 | objc_v2_add_to_class_list (class_decl); | ||||
3545 | if (has_load_impl (CLASS_CLS_METHODS (impent->imp_context)(((tree_class_check ((impent->imp_context), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3545, __FUNCTION__))->type_non_common.maxval)))) | ||||
3546 | objc_v2_add_to_nonlazy_class_list (class_decl); | ||||
3547 | |||||
3548 | if (flags & 0x20) /* RO_EXCEPTION */ | ||||
3549 | objc_v2_add_to_ehtype_list (CLASS_NAME (impent->imp_template)(((tree_class_check ((impent->imp_template), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3549, __FUNCTION__))->type_common.name))); | ||||
3550 | } | ||||
3551 | |||||
3552 | /* This routine outputs the (ivar_reference_offset, offset) | ||||
3553 | tuples. */ | ||||
3554 | |||||
3555 | static void | ||||
3556 | build_v2_ivar_offset_ref_table (void) | ||||
3557 | { | ||||
3558 | int count; | ||||
3559 | ivarref_entry *ref; | ||||
3560 | |||||
3561 | if (!vec_safe_length (ivar_offset_refs)) | ||||
3562 | return; | ||||
3563 | |||||
3564 | FOR_EACH_VEC_ELT (*ivar_offset_refs, count, ref)for (count = 0; (*ivar_offset_refs).iterate ((count), &(ref )); ++(count)) | ||||
3565 | finish_var_decl (ref->decl, ref->offset); | ||||
3566 | } | ||||
3567 | |||||
3568 | static void | ||||
3569 | objc_generate_v2_next_metadata (void) | ||||
3570 | { | ||||
3571 | struct imp_entry *impent; | ||||
3572 | |||||
3573 | /* FIXME: Make sure that we generate no metadata if there is nothing | ||||
3574 | to put into it. */ | ||||
3575 | |||||
3576 | gcc_assert (!objc_static_instances)((void)(!(!objc_global_trees[OCTI_STATIC_NST]) ? fancy_abort ( "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3576, __FUNCTION__), 0 : 0)); /* Not for NeXT */ | ||||
3577 | |||||
3578 | build_metadata_templates (); | ||||
3579 | |||||
3580 | for (impent = imp_list; impent; impent = impent->next) | ||||
3581 | { | ||||
3582 | /* If -gen-decls is present, Dump the @interface of each class. | ||||
3583 | TODO: Dump the classes in the order they were found, rather | ||||
3584 | than in reverse order as we are doing now. */ | ||||
3585 | if (flag_gen_declarationglobal_options.x_flag_gen_declaration) | ||||
3586 | dump_interface (gen_declaration_file, impent->imp_context); | ||||
3587 | |||||
3588 | /* all of the following reference the string pool... */ | ||||
3589 | if (TREE_CODE (impent->imp_context)((enum tree_code) (impent->imp_context)->base.code) == CLASS_IMPLEMENTATION_TYPE) | ||||
3590 | generate_v2_class_structs (impent); | ||||
3591 | else | ||||
3592 | generate_v2_category (impent); | ||||
3593 | } | ||||
3594 | |||||
3595 | build_next_selector_translation_table (); | ||||
3596 | build_v2_message_ref_translation_table (); | ||||
3597 | |||||
3598 | /* This will add "Protocol" to the class refs. */ | ||||
3599 | generate_v2_protocols (); | ||||
3600 | |||||
3601 | build_v2_classrefs_table (); | ||||
3602 | build_v2_super_classrefs_table (/*metaclass= */false); | ||||
3603 | build_v2_super_classrefs_table (/*metaclass= */true); | ||||
3604 | |||||
3605 | build_v2_ivar_offset_ref_table (); | ||||
3606 | |||||
3607 | build_v2_protocol_list_translation_table (); | ||||
3608 | build_v2_protocol_list_address_table (); | ||||
3609 | |||||
3610 | build_v2_address_table (class_list, "_OBJC_ClassList$", | ||||
3611 | meta_label_classlistobjc_rt_trees[OCTI_RT_META_CLSLST_LAB]); | ||||
3612 | build_v2_address_table (category_list, "_OBJC_CategoryList$", | ||||
3613 | meta_label_categorylistobjc_rt_trees[OCTI_RT_META_LAB_CAT]); | ||||
3614 | build_v2_address_table (nonlazy_class_list, "_OBJC_NonLazyClassList$", | ||||
3615 | meta_label_nonlazy_classlistobjc_rt_trees[OCTI_RT_META_CLSLST_NLZY_LAB]); | ||||
3616 | build_v2_address_table (nonlazy_category_list, "_OBJC_NonLazyCategoryList$", | ||||
3617 | meta_label_nonlazy_categorylistobjc_rt_trees[OCTI_RT_META_LAB_NLZY_CAT]); | ||||
3618 | |||||
3619 | /* Generate catch objects for eh, if any are needed. */ | ||||
3620 | build_v2_eh_catch_objects (); | ||||
3621 | |||||
3622 | /* Emit the string table last. */ | ||||
3623 | generate_strings (); | ||||
3624 | } | ||||
3625 | |||||
3626 | /* NOTE --- Output NeXT V2 Exceptions --- */ | ||||
3627 | |||||
3628 | static GTY(()) tree objc_v2_ehtype_template; | ||||
3629 | static GTY(()) tree next_v2_ehvtable_decl; | ||||
3630 | static GTY(()) tree next_v2_EHTYPE_id_decl; | ||||
3631 | |||||
3632 | static void | ||||
3633 | build_v2_ehtype_template (void) | ||||
3634 | { | ||||
3635 | tree decls, *chain = NULLnullptr; | ||||
3636 | 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"))); | ||||
3637 | |||||
3638 | /* void *_objc_ehtype_vtable; */ | ||||
3639 | decls = add_field_decl (ptr_type_nodeglobal_trees[TI_PTR_TYPE], "_objc_ehtype_vtable_ptr", &chain); | ||||
3640 | |||||
3641 | /* const char *className; */ | ||||
3642 | add_field_decl (string_type_nodec_global_trees[CTI_STRING_TYPE], "className", &chain); | ||||
3643 | |||||
3644 | /* struct class_t *const cls; */ | ||||
3645 | add_field_decl (build_pointer_type (objc_v2_class_templateobjc_v2_global_trees[OCTI_V2_CLS_TEMPL]), "cls", &chain); | ||||
3646 | |||||
3647 | objc_finish_struct (objc_v2_ehtype_template, decls); | ||||
3648 | } | ||||
3649 | |||||
3650 | /* Template for the Objective-C family typeinfo type for ABI=2. This | ||||
3651 | starts off the same as the gxx/cxx eh typeinfo. | ||||
3652 | |||||
3653 | struct _objc_ehtype_t | ||||
3654 | { | ||||
3655 | void *_objc_ehtype_vtable_ptr; - as per c++ | ||||
3656 | const char *className; - as per c++ | ||||
3657 | struct class_t *const cls; | ||||
3658 | } | ||||
3659 | */ | ||||
3660 | |||||
3661 | /* This routine builds initializer list for object of type struct _objc_ehtype_t. | ||||
3662 | */ | ||||
3663 | |||||
3664 | static tree | ||||
3665 | objc2_build_ehtype_initializer (tree name, tree cls) | ||||
3666 | { | ||||
3667 | vec<constructor_elt, va_gc> *initlist = NULLnullptr; | ||||
3668 | tree addr, offs; | ||||
3669 | |||||
3670 | /* This is done the same way as c++, missing the two first entries | ||||
3671 | in the parent vtable. NOTE: there is a fix-me in the Apple/NeXT | ||||
3672 | runtime source about this so, perhaps, this will change at some | ||||
3673 | point. */ | ||||
3674 | /* _objc_ehtype_vtable + 2*sizeof(void*) */ | ||||
3675 | if (!next_v2_ehvtable_decl) | ||||
3676 | { | ||||
3677 | next_v2_ehvtable_decl = | ||||
3678 | start_var_decl (ptr_type_nodeglobal_trees[TI_PTR_TYPE], TAG_NEXT_EHVTABLE_NAME"objc_ehtype_vtable"); | ||||
3679 | TREE_STATIC (next_v2_ehvtable_decl)((next_v2_ehvtable_decl)->base.static_flag) = 0; | ||||
3680 | DECL_EXTERNAL (next_v2_ehvtable_decl)((contains_struct_check ((next_v2_ehvtable_decl), (TS_DECL_COMMON ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3680, __FUNCTION__))->decl_common.decl_flag_1) = 1; | ||||
3681 | TREE_PUBLIC (next_v2_ehvtable_decl)((next_v2_ehvtable_decl)->base.public_flag) = 1; | ||||
3682 | } | ||||
3683 | 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]); | ||||
3684 | 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), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3684, __FUNCTION__))->type_common.size_unit)), stk_sizetype ); | ||||
3685 | addr = fold_build_pointer_plus (addr, offs)fold_build_pointer_plus_loc (((location_t) 0), addr, offs); | ||||
3686 | |||||
3687 | CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, addr)do { constructor_elt _ce___ = {(tree) nullptr, addr}; vec_safe_push ((initlist), _ce___); } while (0); | ||||
3688 | |||||
3689 | /* className */ | ||||
3690 | CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, name)do { constructor_elt _ce___ = {(tree) nullptr, name}; vec_safe_push ((initlist), _ce___); } while (0); | ||||
3691 | |||||
3692 | /* cls */ | ||||
3693 | CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, cls)do { constructor_elt _ce___ = {(tree) nullptr, cls}; vec_safe_push ((initlist), _ce___); } while (0); | ||||
3694 | |||||
3695 | return objc_build_constructor (objc_v2_ehtype_template, initlist); | ||||
3696 | } | ||||
3697 | |||||
3698 | static tree | ||||
3699 | build_ehtype (tree name, const char *eh_name, bool weak) | ||||
3700 | { | ||||
3701 | tree name_expr, class_name_expr, ehtype_decl, inits; | ||||
3702 | |||||
3703 | name_expr = add_objc_string (name, class_names); | ||||
3704 | /* Extern ref. for the class. ??? Maybe we can look this up | ||||
3705 | somewhere. */ | ||||
3706 | class_name_expr = | ||||
3707 | create_extern_decl (objc_v2_class_templateobjc_v2_global_trees[OCTI_V2_CLS_TEMPL], | ||||
3708 | objc_build_internal_classname (name, false)); | ||||
3709 | class_name_expr = build_fold_addr_expr (class_name_expr)build_fold_addr_expr_loc (((location_t) 0), (class_name_expr) ); | ||||
3710 | ehtype_decl = create_global_decl (objc_v2_ehtype_template, eh_name); | ||||
3711 | if (weak) | ||||
3712 | DECL_WEAK (ehtype_decl)((contains_struct_check ((ehtype_decl), (TS_DECL_WITH_VIS), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3712, __FUNCTION__))->decl_with_vis.weak_flag) = 1; | ||||
3713 | inits = objc2_build_ehtype_initializer (name_expr, class_name_expr); | ||||
3714 | OBJCMETA (ehtype_decl, objc_meta, meta_ehtype)if (objc_rt_trees[OCTI_RT_OBJC_META]) ((contains_struct_check ((ehtype_decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3714, __FUNCTION__))->decl_common.attributes) = build_tree_list ((objc_rt_trees[OCTI_RT_OBJC_META]), (objc_rt_trees[OCTI_RT_META_EHTYPE ]));; | ||||
3715 | finish_var_decl (ehtype_decl, inits); | ||||
3716 | return ehtype_decl; | ||||
3717 | } | ||||
3718 | |||||
3719 | /* This routine returns TRUE if CLS or any of its super classes has | ||||
3720 | __attribute__ ((objc_exception)). */ | ||||
3721 | |||||
3722 | static bool | ||||
3723 | objc2_objc_exception_attr (tree cls) | ||||
3724 | { | ||||
3725 | while (cls) | ||||
3726 | { | ||||
3727 | if (CLASS_HAS_EXCEPTION_ATTR (cls)(((tree_class_check ((cls), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3727, __FUNCTION__))->type_common.lang_flag_0))) | ||||
3728 | return true; | ||||
3729 | cls = lookup_interface (CLASS_SUPER_NAME (cls)(((tree_class_check ((cls), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3729, __FUNCTION__))->type_common.context))); | ||||
3730 | } | ||||
3731 | |||||
3732 | return false; | ||||
3733 | } | ||||
3734 | |||||
3735 | static bool | ||||
3736 | is_implemented (tree name) | ||||
3737 | { | ||||
3738 | struct imp_entry *t; | ||||
3739 | for (t = imp_list; t; t = t->next) | ||||
3740 | if (TREE_CODE (t->imp_context)((enum tree_code) (t->imp_context)->base.code) == CLASS_IMPLEMENTATION_TYPE | ||||
3741 | && CLASS_NAME (t->imp_template)(((tree_class_check ((t->imp_template), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3741, __FUNCTION__))->type_common.name)) == name) | ||||
3742 | return true; | ||||
3743 | |||||
3744 | return false; | ||||
3745 | } | ||||
3746 | |||||
3747 | /* We will build catch objects: | ||||
3748 | for any type implemented here. | ||||
3749 | for any type used in a catch that has no exception attribute. */ | ||||
3750 | static void build_v2_eh_catch_objects (void) | ||||
3751 | { | ||||
3752 | int count=0; | ||||
3753 | ident_data_tuple *ref; | ||||
3754 | |||||
3755 | if (!vec_safe_length (ehtype_list)) | ||||
3756 | return; | ||||
3757 | |||||
3758 | FOR_EACH_VEC_ELT (*ehtype_list, count, ref)for (count = 0; (*ehtype_list).iterate ((count), &(ref)); ++(count)) | ||||
3759 | { | ||||
3760 | char buf[BUFSIZE1024]; | ||||
3761 | bool impl = is_implemented (ref->ident); | ||||
3762 | bool excpt = objc2_objc_exception_attr (lookup_interface (ref->ident)); | ||||
3763 | snprintf (buf, BUFSIZE1024, "OBJC_EHTYPE_$_%s", IDENTIFIER_POINTER (ref->ident)((const char *) (tree_check ((ref->ident), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3763, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | ||||
3764 | if (!impl && excpt) | ||||
3765 | /* The User says this class has a catcher already. */ | ||||
3766 | ref->data = create_extern_decl (objc_v2_ehtype_template, buf); | ||||
3767 | else | ||||
3768 | /* Create a catcher, weak if it wasn't marked. */ | ||||
3769 | ref->data = build_ehtype (ref->ident, buf, !excpt); | ||||
3770 | } | ||||
3771 | } | ||||
3772 | |||||
3773 | static tree | ||||
3774 | lookup_ehtype_ref (tree id) | ||||
3775 | { | ||||
3776 | int count=0; | ||||
3777 | ident_data_tuple *ref; | ||||
3778 | |||||
3779 | if (!vec_safe_length (ehtype_list)) | ||||
3780 | return NULL_TREE(tree) nullptr; | ||||
3781 | |||||
3782 | FOR_EACH_VEC_ELT (*ehtype_list, count, ref)for (count = 0; (*ehtype_list).iterate ((count), &(ref)); ++(count)) | ||||
3783 | if (ref->ident == id) | ||||
3784 | return ref->data; | ||||
3785 | return NULL_TREE(tree) nullptr; | ||||
3786 | } | ||||
3787 | |||||
3788 | /* This hook, called via lang_eh_runtime_type, generates a runtime | ||||
3789 | object which is either the address of the 'OBJC_EHTYPE_$_class' | ||||
3790 | object or address of external OBJC_EHTYPE_id object. */ | ||||
3791 | static tree | ||||
3792 | next_runtime_02_eh_type (tree type) | ||||
3793 | { | ||||
3794 | tree t; | ||||
3795 | |||||
3796 | if (type == error_mark_nodeglobal_trees[TI_ERROR_MARK] | ||||
3797 | /*|| errorcount || sorrycount*/) | ||||
3798 | goto err_mark_in; | ||||
3799 | |||||
3800 | 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 ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3800, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3800, __FUNCTION__))->type_common.name) == objc_global_trees [OCTI_OBJ_ID])) | ||||
3801 | { | ||||
3802 | if (!next_v2_EHTYPE_id_decl) | ||||
3803 | { | ||||
3804 | /* This is provided by the Apple/NeXT libobjc.dylib so we | ||||
3805 | need only to reference it. */ | ||||
3806 | next_v2_EHTYPE_id_decl = | ||||
3807 | start_var_decl (objc_v2_ehtype_template, "OBJC_EHTYPE_id"); | ||||
3808 | DECL_EXTERNAL (next_v2_EHTYPE_id_decl)((contains_struct_check ((next_v2_EHTYPE_id_decl), (TS_DECL_COMMON ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3808, __FUNCTION__))->decl_common.decl_flag_1) = 1; | ||||
3809 | TREE_PUBLIC (next_v2_EHTYPE_id_decl)((next_v2_EHTYPE_id_decl)->base.public_flag) = 1; | ||||
3810 | TREE_STATIC (next_v2_EHTYPE_id_decl)((next_v2_EHTYPE_id_decl)->base.static_flag) = 0; | ||||
3811 | } | ||||
3812 | return build_fold_addr_expr (next_v2_EHTYPE_id_decl)build_fold_addr_expr_loc (((location_t) 0), (next_v2_EHTYPE_id_decl )); | ||||
3813 | } | ||||
3814 | |||||
3815 | 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 ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3815, __FUNCTION__))->typed.type))->base.code) == RECORD_TYPE && (((tree_class_check ((((contains_struct_check ((type ), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3815, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3815, __FUNCTION__))->type_with_lang_specific.lang_specific ) && ((tree_class_check ((((contains_struct_check ((type ), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3815, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3815, __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 ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3815, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3815, __FUNCTION__))->type_with_lang_specific.lang_specific )->objc_info), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3815, __FUNCTION__))))))) | ||||
3816 | { | ||||
3817 | #ifdef OBJCPLUS | ||||
3818 | /* This routine is also called for c++'s catch clause; in which | ||||
3819 | case, we use c++'s typeinfo decl. */ | ||||
3820 | return build_eh_type_type (type); | ||||
3821 | #else | ||||
3822 | error ("non-objective-c type %qT cannot be caught", type); | ||||
3823 | goto err_mark_in; | ||||
3824 | #endif | ||||
3825 | } | ||||
3826 | else | ||||
3827 | t = OBJC_TYPE_NAME (TREE_TYPE (type))((tree_class_check ((((contains_struct_check ((type), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3827, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3827, __FUNCTION__))->type_common.name); | ||||
3828 | |||||
3829 | /* We have to build a reference to the OBJC_EHTYPE_<Class>. */ | ||||
3830 | t = lookup_ehtype_ref (t); | ||||
3831 | if (!t) | ||||
3832 | goto err_mark_in; | ||||
3833 | |||||
3834 | return build_fold_addr_expr (t)build_fold_addr_expr_loc (((location_t) 0), (t)); | ||||
3835 | |||||
3836 | err_mark_in: | ||||
3837 | return error_mark_nodeglobal_trees[TI_ERROR_MARK]; | ||||
3838 | } | ||||
3839 | |||||
3840 | static GTY(()) tree objc_eh_personality_decl; | ||||
3841 | |||||
3842 | static tree | ||||
3843 | objc_eh_personality (void) | ||||
3844 | { | ||||
3845 | if (!objc_eh_personality_decl) | ||||
3846 | objc_eh_personality_decl = build_personality_function ("objc"); | ||||
3847 | return objc_eh_personality_decl; | ||||
3848 | } | ||||
3849 | |||||
3850 | /* NOTE --- interfaces --- */ | ||||
3851 | |||||
3852 | static tree | ||||
3853 | build_throw_stmt (location_t loc, tree throw_expr, bool rethrown) | ||||
3854 | { | ||||
3855 | tree t; | ||||
3856 | if (rethrown) | ||||
3857 | /* We have a separate re-throw entry. */ | ||||
3858 | t = build_function_call_vec (loc, vNULL, objc_rethrow_exception_declobjc_v2_global_trees[OCTI_V2_RETHROW_DECL], | ||||
3859 | NULLnullptr, NULLnullptr); | ||||
3860 | else | ||||
3861 | { | ||||
3862 | /* Throw like the others... */ | ||||
3863 | vec<tree, va_gc> *parms; | ||||
3864 | vec_alloc (parms, 1); | ||||
3865 | parms->quick_push (throw_expr); | ||||
3866 | t = build_function_call_vec (loc, vNULL, objc_exception_throw_declobjc_global_trees[OCTI_EXCEPTION_THROW_DECL], | ||||
3867 | parms, 0); | ||||
3868 | vec_free (parms); | ||||
3869 | } | ||||
3870 | return add_stmt (t); | ||||
3871 | } | ||||
3872 | |||||
3873 | /* Build __builtin_eh_pointer. */ | ||||
3874 | |||||
3875 | static tree | ||||
3876 | objc_build_exc_ptr (struct objc_try_context **x ATTRIBUTE_UNUSED__attribute__ ((__unused__))) | ||||
3877 | { | ||||
3878 | tree t; | ||||
3879 | t = builtin_decl_explicit (BUILT_IN_EH_POINTER); | ||||
3880 | t = build_call_expr (t, 1, integer_zero_nodeglobal_trees[TI_INTEGER_ZERO]); | ||||
3881 | return fold_convert (objc_object_type, t)fold_convert_loc (((location_t) 0), objc_global_trees[OCTI_ID_TYPE ], t); | ||||
3882 | } | ||||
3883 | |||||
3884 | static tree begin_catch (struct objc_try_context **cur_try_context, tree type, | ||||
3885 | tree decl, tree compound, bool ellipsis ATTRIBUTE_UNUSED__attribute__ ((__unused__))) | ||||
3886 | { | ||||
3887 | tree t; | ||||
3888 | |||||
3889 | /* Record the data for the catch in the try context so that we can | ||||
3890 | finalize it later. Ellipsis is signalled by a NULL entry. */ | ||||
3891 | if (ellipsis) | ||||
3892 | t = build_stmt (input_location, CATCH_EXPR, NULL_TREE(tree) nullptr, compound); | ||||
3893 | else | ||||
3894 | t = build_stmt (input_location, CATCH_EXPR, type, compound); | ||||
3895 | (*cur_try_context)->current_catch = t; | ||||
3896 | |||||
3897 | /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */ | ||||
3898 | t = objc_build_exc_ptr (cur_try_context); | ||||
3899 | t = convert (TREE_TYPE (decl)((contains_struct_check ((decl), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3899, __FUNCTION__))->typed.type), t); | ||||
3900 | /* FIXME: location. */ | ||||
3901 | if (type && type != error_mark_nodeglobal_trees[TI_ERROR_MARK]) | ||||
3902 | { | ||||
3903 | t = build1(NOP_EXPR, ptr_type_nodeglobal_trees[TI_PTR_TYPE], t); | ||||
3904 | t = build_function_call (input_location, objc2_begin_catch_declobjc_v2_global_trees[OCTI_V2_BEGIN_CATCH_DECL], | ||||
3905 | tree_cons (NULL_TREE(tree) nullptr, t, NULL_TREE(tree) nullptr)); | ||||
3906 | |||||
3907 | /* We might want to build a catch object for this (if it's not | ||||
3908 | id). */ | ||||
3909 | if (POINTER_TYPE_P (type)(((enum tree_code) (type)->base.code) == POINTER_TYPE || ( (enum tree_code) (type)->base.code) == REFERENCE_TYPE) | ||||
3910 | && !objc_is_object_id (TREE_TYPE (type))(((tree_class_check ((((contains_struct_check ((type), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3910, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3910, __FUNCTION__))->type_common.name) == objc_global_trees [OCTI_OBJ_ID]) | ||||
3911 | && TYPED_OBJECT (TREE_TYPE (type))(((enum tree_code) (((contains_struct_check ((type), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3911, __FUNCTION__))->typed.type))->base.code) == RECORD_TYPE && (((tree_class_check ((((contains_struct_check ((type ), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3911, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3911, __FUNCTION__))->type_with_lang_specific.lang_specific ) && ((tree_class_check ((((contains_struct_check ((type ), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3911, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3911, __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 ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3911, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3911, __FUNCTION__))->type_with_lang_specific.lang_specific )->objc_info), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3911, __FUNCTION__))))))) | ||||
3912 | objc_v2_add_to_ehtype_list (OBJC_TYPE_NAME (TREE_TYPE (type))((tree_class_check ((((contains_struct_check ((type), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3912, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3912, __FUNCTION__))->type_common.name)); | ||||
3913 | } | ||||
3914 | return build2 (MODIFY_EXPR, void_type_nodeglobal_trees[TI_VOID_TYPE], decl, t); | ||||
3915 | } | ||||
3916 | |||||
3917 | /* try { catch-body } finally { objc_end_catch (); } */ | ||||
3918 | static void | ||||
3919 | finish_catch (struct objc_try_context **cur_try_context, tree curr_catch) | ||||
3920 | { | ||||
3921 | struct objc_try_context *ct; | ||||
3922 | tree try_exp, func, *l, t ; | ||||
3923 | location_t loc = (*cur_try_context)->try_locus; | ||||
3924 | |||||
3925 | if (!curr_catch || curr_catch == error_mark_nodeglobal_trees[TI_ERROR_MARK]) | ||||
3926 | return; | ||||
3927 | |||||
3928 | t = CATCH_BODY (curr_catch)(*((const_cast<tree*> (tree_operand_check (((tree_check ((curr_catch), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3928, __FUNCTION__, (CATCH_EXPR)))), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3928, __FUNCTION__))))); | ||||
3929 | if (TREE_CODE (t)((enum tree_code) (t)->base.code) == BIND_EXPR) | ||||
3930 | { | ||||
3931 | /* Usual case of @catch (objc-expr). */ | ||||
3932 | objc_begin_try_stmt (loc, BIND_EXPR_BODY (t)((*((const_cast<tree*> (tree_operand_check (((tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3932, __FUNCTION__, (BIND_EXPR)))), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3932, __FUNCTION__))))))); | ||||
3933 | BIND_EXPR_BODY (t)((*((const_cast<tree*> (tree_operand_check (((tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3933, __FUNCTION__, (BIND_EXPR)))), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3933, __FUNCTION__)))))) = NULL_TREE(tree) nullptr; | ||||
3934 | l = &BIND_EXPR_BODY (t)((*((const_cast<tree*> (tree_operand_check (((tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3934, __FUNCTION__, (BIND_EXPR)))), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3934, __FUNCTION__)))))); | ||||
3935 | } | ||||
3936 | else | ||||
3937 | { | ||||
3938 | /* NULL entry, meaning @catch (...). */ | ||||
3939 | objc_begin_try_stmt (loc, t); | ||||
3940 | CATCH_BODY (curr_catch)(*((const_cast<tree*> (tree_operand_check (((tree_check ((curr_catch), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3940, __FUNCTION__, (CATCH_EXPR)))), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3940, __FUNCTION__))))) = NULL_TREE(tree) nullptr; | ||||
3941 | l = &CATCH_BODY (curr_catch)(*((const_cast<tree*> (tree_operand_check (((tree_check ((curr_catch), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3941, __FUNCTION__, (CATCH_EXPR)))), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/objc/objc-next-runtime-abi-02.cc" , 3941, __FUNCTION__))))); | ||||
3942 | } | ||||
3943 | |||||
3944 | /* Pick up the new context we made in begin_try above... */ | ||||
3945 | ct = *cur_try_context; | ||||
3946 | func = build_function_call_vec (loc, vNULL, objc2_end_catch_declobjc_v2_global_trees[OCTI_V2_END_CATCH_DECL], NULLnullptr, | ||||
3947 | NULLnullptr); | ||||
3948 | append_to_statement_list (func, &ct->finally_body); | ||||
3949 | try_exp = build_stmt (loc, TRY_FINALLY_EXPR, ct->try_body, ct->finally_body); | ||||
3950 | *cur_try_context = ct->outer; | ||||
3951 | free (ct); | ||||
3952 | append_to_statement_list (try_exp, l); | ||||
3953 | append_to_statement_list (curr_catch, &((*cur_try_context)->catch_list)); | ||||
3954 | } | ||||
3955 | |||||
3956 | static tree | ||||
3957 | finish_try_stmt (struct objc_try_context **cur_try_context) | ||||
3958 | { | ||||
3959 | struct objc_try_context *c = *cur_try_context; | ||||
3960 | tree stmt = c->try_body; | ||||
3961 | if (c->catch_list) | ||||
3962 | stmt = build_stmt (c->try_locus, TRY_CATCH_EXPR, stmt, c->catch_list); | ||||
3963 | if (c->finally_body) | ||||
3964 | stmt = build_stmt (c->try_locus, TRY_FINALLY_EXPR, stmt, c->finally_body); | ||||
3965 | return stmt; | ||||
3966 | } | ||||
3967 | |||||
3968 | #include "gt-objc-objc-next-runtime-abi-02.h" |
1 | /* Vector API for GNU compiler. | ||||
2 | Copyright (C) 2004-2023 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.cc. */ | ||||
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 ("/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 zero-initialized values for vec<T, A, L>. This is | ||||
545 | used to provide nil initializers for vec instances. Since vec must | ||||
546 | be a trivially copyable type that can be copied by memcpy and zeroed | ||||
547 | out by memset, it must have defaulted default and copy ctor and copy | ||||
548 | assignment. To initialize a vec either use value initialization | ||||
549 | (e.g., vec() or vec v{ };) or assign it the value vNULL. This isn't | ||||
550 | needed for file-scope and function-local static vectors, which are | ||||
551 | zero-initialized by default. */ | ||||
552 | struct vnull { }; | ||||
553 | constexpr vnull vNULL{ }; | ||||
554 | |||||
555 | |||||
556 | /* Embeddable vector. These vectors are suitable to be embedded | ||||
557 | in other data structures so that they can be pre-allocated in a | ||||
558 | contiguous memory block. | ||||
559 | |||||
560 | Embeddable vectors are implemented using the trailing array idiom, | ||||
561 | thus they are not resizeable without changing the address of the | ||||
562 | vector object itself. This means you cannot have variables or | ||||
563 | fields of embeddable vector type -- always use a pointer to a | ||||
564 | vector. The one exception is the final field of a structure, which | ||||
565 | could be a vector type. | ||||
566 | |||||
567 | You will have to use the embedded_size & embedded_init calls to | ||||
568 | create such objects, and they will not be resizeable (so the 'safe' | ||||
569 | allocation variants are not available). | ||||
570 | |||||
571 | Properties: | ||||
572 | |||||
573 | - The whole vector and control data are allocated in a single | ||||
574 | contiguous block. It uses the trailing-vector idiom, so | ||||
575 | allocation must reserve enough space for all the elements | ||||
576 | in the vector plus its control data. | ||||
577 | - The vector cannot be re-allocated. | ||||
578 | - The vector cannot grow nor shrink. | ||||
579 | - No indirections needed for access/manipulation. | ||||
580 | - It requires 2 words of storage (prior to vector allocation). */ | ||||
581 | |||||
582 | template<typename T, typename A> | ||||
583 | struct GTY((user)) vec<T, A, vl_embed> | ||||
584 | { | ||||
585 | public: | ||||
586 | unsigned allocated (void) const { return m_vecpfx.m_alloc; } | ||||
587 | unsigned length (void) const { return m_vecpfx.m_num; } | ||||
588 | bool is_empty (void) const { return m_vecpfx.m_num == 0; } | ||||
589 | T *address (void) { return reinterpret_cast <T *> (this + 1); } | ||||
590 | const T *address (void) const | ||||
591 | { return reinterpret_cast <const T *> (this + 1); } | ||||
592 | T *begin () { return address (); } | ||||
593 | const T *begin () const { return address (); } | ||||
594 | T *end () { return address () + length (); } | ||||
595 | const T *end () const { return address () + length (); } | ||||
596 | const T &operator[] (unsigned) const; | ||||
597 | T &operator[] (unsigned); | ||||
598 | T &last (void); | ||||
599 | bool space (unsigned) const; | ||||
600 | bool iterate (unsigned, T *) const; | ||||
601 | bool iterate (unsigned, T **) const; | ||||
602 | vec *copy (ALONE_CXX_MEM_STAT_INFO) const; | ||||
603 | void splice (const vec &); | ||||
604 | void splice (const vec *src); | ||||
605 | T *quick_push (const T &); | ||||
606 | T &pop (void); | ||||
607 | void truncate (unsigned); | ||||
608 | void quick_insert (unsigned, const T &); | ||||
609 | void ordered_remove (unsigned); | ||||
610 | void unordered_remove (unsigned); | ||||
611 | void block_remove (unsigned, unsigned); | ||||
612 | void qsort (int (*) (const void *, const void *))qsort (int (*) (const void *, const void *)); | ||||
613 | void sort (int (*) (const void *, const void *, void *), void *); | ||||
614 | void stablesort (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 (const 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 - This field should be private, but we need to cater to | ||||
634 | compilers that have stricter notions of PODness for types. */ | ||||
635 | /* Align m_vecpfx to simplify address (). */ | ||||
636 | alignas (T) alignas (vec_prefix) vec_prefix m_vecpfx; | ||||
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 ("/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 ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h" , 882, __FUNCTION__), 0 : 0)); | ||||
883 | return address ()[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 ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h" , 890, __FUNCTION__), 0 : 0)); | ||||
891 | return address ()[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 ("/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 (a copy of) 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; v->iterate (ix, &val); 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 = address ()[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 *, &address ()[ix])(const_cast<T *> ((&address ()[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 (), address (), 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 ("/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 ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h" , 1021, __FUNCTION__), 0 : 0)); | ||||
1022 | T *slot = &address ()[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 ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h" , 1034, __FUNCTION__), 0 : 0)); | ||||
1035 | return address ()[--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 ("/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 ("/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 ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h" , 1059, __FUNCTION__), 0 : 0)); | ||||
1060 | T *slot = &address ()[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 ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h" , 1074, __FUNCTION__), 0 : 0)); | ||||
1075 | T *slot = &address ()[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 ("/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 ("/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 ("/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 ("/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 ("/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 ("/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 ("/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 ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h" , 1121, __FUNCTION__), 0 : 0)); | ||||
1122 | T *p = address (); | ||||
1123 | p[ix] = p[--m_vecpfx.m_num]; | ||||
1124 | } | ||||
1125 | |||||
1126 | |||||
1127 | /* Remove LEN elements starting at the IXth. Ordering is retained. | ||||
1128 | This is an O(N) operation due to memmove. */ | ||||
1129 | |||||
1130 | template<typename T, typename A> | ||||
1131 | inline void | ||||
1132 | vec<T, A, vl_embed>::block_remove (unsigned ix, unsigned len) | ||||
1133 | { | ||||
1134 | gcc_checking_assert (ix + len <= length ())((void)(!(ix + len <= length ()) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h" , 1134, __FUNCTION__), 0 : 0)); | ||||
1135 | T *slot = &address ()[ix]; | ||||
1136 | m_vecpfx.m_num -= len; | ||||
1137 | memmove (slot, slot + len, (m_vecpfx.m_num - ix) * sizeof (T)); | ||||
1138 | } | ||||
1139 | |||||
1140 | |||||
1141 | /* Sort the contents of this vector with qsort. CMP is the comparison | ||||
1142 | function to pass to qsort. */ | ||||
1143 | |||||
1144 | template<typename T, typename A> | ||||
1145 | inline void | ||||
1146 | vec<T, A, vl_embed>::qsort (int (*cmp) (const void *, const void *))qsort (int (*cmp) (const void *, const void *)) | ||||
1147 | { | ||||
1148 | if (length () > 1) | ||||
1149 | gcc_qsort (address (), length (), sizeof (T), cmp); | ||||
1150 | } | ||||
1151 | |||||
1152 | /* Sort the contents of this vector with qsort. CMP is the comparison | ||||
1153 | function to pass to qsort. */ | ||||
1154 | |||||
1155 | template<typename T, typename A> | ||||
1156 | inline void | ||||
1157 | vec<T, A, vl_embed>::sort (int (*cmp) (const void *, const void *, void *), | ||||
1158 | void *data) | ||||
1159 | { | ||||
1160 | if (length () > 1) | ||||
1161 | gcc_sort_r (address (), length (), sizeof (T), cmp, data); | ||||
1162 | } | ||||
1163 | |||||
1164 | /* Sort the contents of this vector with gcc_stablesort_r. CMP is the | ||||
1165 | comparison function to pass to qsort. */ | ||||
1166 | |||||
1167 | template<typename T, typename A> | ||||
1168 | inline void | ||||
1169 | vec<T, A, vl_embed>::stablesort (int (*cmp) (const void *, const void *, | ||||
1170 | void *), void *data) | ||||
1171 | { | ||||
1172 | if (length () > 1) | ||||
1173 | gcc_stablesort_r (address (), length (), sizeof (T), cmp, data); | ||||
1174 | } | ||||
1175 | |||||
1176 | /* Search the contents of the sorted vector with a binary search. | ||||
1177 | CMP is the comparison function to pass to bsearch. */ | ||||
1178 | |||||
1179 | template<typename T, typename A> | ||||
1180 | inline T * | ||||
1181 | vec<T, A, vl_embed>::bsearch (const void *key, | ||||
1182 | int (*compar) (const void *, const void *)) | ||||
1183 | { | ||||
1184 | const void *base = this->address (); | ||||
1185 | size_t nmemb = this->length (); | ||||
1186 | size_t size = sizeof (T); | ||||
1187 | /* The following is a copy of glibc stdlib-bsearch.h. */ | ||||
1188 | size_t l, u, idx; | ||||
1189 | const void *p; | ||||
1190 | int comparison; | ||||
1191 | |||||
1192 | l = 0; | ||||
1193 | u = nmemb; | ||||
1194 | while (l < u) | ||||
1195 | { | ||||
1196 | idx = (l + u) / 2; | ||||
1197 | p = (const void *) (((const char *) base) + (idx * size)); | ||||
1198 | comparison = (*compar) (key, p); | ||||
1199 | if (comparison < 0) | ||||
1200 | u = idx; | ||||
1201 | else if (comparison > 0) | ||||
1202 | l = idx + 1; | ||||
1203 | else | ||||
1204 | return (T *)const_cast<void *>(p); | ||||
1205 | } | ||||
1206 | |||||
1207 | return NULLnullptr; | ||||
1208 | } | ||||
1209 | |||||
1210 | /* Search the contents of the sorted vector with a binary search. | ||||
1211 | CMP is the comparison function to pass to bsearch. */ | ||||
1212 | |||||
1213 | template<typename T, typename A> | ||||
1214 | inline T * | ||||
1215 | vec<T, A, vl_embed>::bsearch (const void *key, | ||||
1216 | int (*compar) (const void *, const void *, | ||||
1217 | void *), void *data) | ||||
1218 | { | ||||
1219 | const void *base = this->address (); | ||||
1220 | size_t nmemb = this->length (); | ||||
1221 | size_t size = sizeof (T); | ||||
1222 | /* The following is a copy of glibc stdlib-bsearch.h. */ | ||||
1223 | size_t l, u, idx; | ||||
1224 |