File: | src/gnu/usr.bin/clang/liblldbABI/../../../llvm/lldb/source/Plugins/ABI/Mips/ABISysV_mips64.cpp |
Warning: | line 698, column 39 Called C++ object pointer is null |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | //===-- ABISysV_mips64.cpp ------------------------------------------------===// | |||
2 | // | |||
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |||
4 | // See https://llvm.org/LICENSE.txt for license information. | |||
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |||
6 | // | |||
7 | //===----------------------------------------------------------------------===// | |||
8 | ||||
9 | #include "ABISysV_mips64.h" | |||
10 | ||||
11 | #include "llvm/ADT/STLExtras.h" | |||
12 | #include "llvm/ADT/Triple.h" | |||
13 | ||||
14 | #include "lldb/Core/Module.h" | |||
15 | #include "lldb/Core/PluginManager.h" | |||
16 | #include "lldb/Core/Value.h" | |||
17 | #include "lldb/Core/ValueObjectConstResult.h" | |||
18 | #include "lldb/Core/ValueObjectMemory.h" | |||
19 | #include "lldb/Core/ValueObjectRegister.h" | |||
20 | #include "lldb/Symbol/UnwindPlan.h" | |||
21 | #include "lldb/Target/Process.h" | |||
22 | #include "lldb/Target/RegisterContext.h" | |||
23 | #include "lldb/Target/StackFrame.h" | |||
24 | #include "lldb/Target/Target.h" | |||
25 | #include "lldb/Target/Thread.h" | |||
26 | #include "lldb/Utility/ConstString.h" | |||
27 | #include "lldb/Utility/DataExtractor.h" | |||
28 | #include "lldb/Utility/Log.h" | |||
29 | #include "lldb/Utility/RegisterValue.h" | |||
30 | #include "lldb/Utility/Status.h" | |||
31 | ||||
32 | using namespace lldb; | |||
33 | using namespace lldb_private; | |||
34 | ||||
35 | LLDB_PLUGIN_DEFINE(ABISysV_mips64)namespace lldb_private { void lldb_initialize_ABISysV_mips64( ) { ABISysV_mips64::Initialize(); } void lldb_terminate_ABISysV_mips64 () { ABISysV_mips64::Terminate(); } } | |||
36 | ||||
37 | enum dwarf_regnums { | |||
38 | dwarf_r0 = 0, | |||
39 | dwarf_r1, | |||
40 | dwarf_r2, | |||
41 | dwarf_r3, | |||
42 | dwarf_r4, | |||
43 | dwarf_r5, | |||
44 | dwarf_r6, | |||
45 | dwarf_r7, | |||
46 | dwarf_r8, | |||
47 | dwarf_r9, | |||
48 | dwarf_r10, | |||
49 | dwarf_r11, | |||
50 | dwarf_r12, | |||
51 | dwarf_r13, | |||
52 | dwarf_r14, | |||
53 | dwarf_r15, | |||
54 | dwarf_r16, | |||
55 | dwarf_r17, | |||
56 | dwarf_r18, | |||
57 | dwarf_r19, | |||
58 | dwarf_r20, | |||
59 | dwarf_r21, | |||
60 | dwarf_r22, | |||
61 | dwarf_r23, | |||
62 | dwarf_r24, | |||
63 | dwarf_r25, | |||
64 | dwarf_r26, | |||
65 | dwarf_r27, | |||
66 | dwarf_r28, | |||
67 | dwarf_r29, | |||
68 | dwarf_r30, | |||
69 | dwarf_r31, | |||
70 | dwarf_sr, | |||
71 | dwarf_lo, | |||
72 | dwarf_hi, | |||
73 | dwarf_bad, | |||
74 | dwarf_cause, | |||
75 | dwarf_pc | |||
76 | }; | |||
77 | ||||
78 | static const RegisterInfo g_register_infos_mips64[] = { | |||
79 | // NAME ALT SZ OFF ENCODING FORMAT EH_FRAME | |||
80 | // DWARF GENERIC PROCESS PLUGIN | |||
81 | // LLDB NATIVE | |||
82 | // ======== ====== == === ============= ========== ============= | |||
83 | // ================= ==================== ================= | |||
84 | // ==================== | |||
85 | {"r0", | |||
86 | "zero", | |||
87 | 8, | |||
88 | 0, | |||
89 | eEncodingUint, | |||
90 | eFormatHex, | |||
91 | {dwarf_r0, dwarf_r0, LLDB_INVALID_REGNUM0xffffffffU, LLDB_INVALID_REGNUM0xffffffffU, | |||
92 | LLDB_INVALID_REGNUM0xffffffffU}, | |||
93 | nullptr, | |||
94 | nullptr, | |||
95 | nullptr, | |||
96 | 0}, | |||
97 | {"r1", | |||
98 | "AT", | |||
99 | 8, | |||
100 | 0, | |||
101 | eEncodingUint, | |||
102 | eFormatHex, | |||
103 | {dwarf_r1, dwarf_r1, LLDB_INVALID_REGNUM0xffffffffU, LLDB_INVALID_REGNUM0xffffffffU, | |||
104 | LLDB_INVALID_REGNUM0xffffffffU}, | |||
105 | nullptr, | |||
106 | nullptr, | |||
107 | nullptr, | |||
108 | 0}, | |||
109 | {"r2", | |||
110 | "v0", | |||
111 | 8, | |||
112 | 0, | |||
113 | eEncodingUint, | |||
114 | eFormatHex, | |||
115 | {dwarf_r2, dwarf_r2, LLDB_INVALID_REGNUM0xffffffffU, LLDB_INVALID_REGNUM0xffffffffU, | |||
116 | LLDB_INVALID_REGNUM0xffffffffU}, | |||
117 | nullptr, | |||
118 | nullptr, | |||
119 | nullptr, | |||
120 | 0}, | |||
121 | {"r3", | |||
122 | "v1", | |||
123 | 8, | |||
124 | 0, | |||
125 | eEncodingUint, | |||
126 | eFormatHex, | |||
127 | {dwarf_r3, dwarf_r3, LLDB_INVALID_REGNUM0xffffffffU, LLDB_INVALID_REGNUM0xffffffffU, | |||
128 | LLDB_INVALID_REGNUM0xffffffffU}, | |||
129 | nullptr, | |||
130 | nullptr, | |||
131 | nullptr, | |||
132 | 0}, | |||
133 | {"r4", | |||
134 | "arg1", | |||
135 | 8, | |||
136 | 0, | |||
137 | eEncodingUint, | |||
138 | eFormatHex, | |||
139 | {dwarf_r4, dwarf_r4, LLDB_REGNUM_GENERIC_ARG15, LLDB_INVALID_REGNUM0xffffffffU, | |||
140 | LLDB_INVALID_REGNUM0xffffffffU}, | |||
141 | nullptr, | |||
142 | nullptr, | |||
143 | nullptr, | |||
144 | 0}, | |||
145 | {"r5", | |||
146 | "arg2", | |||
147 | 8, | |||
148 | 0, | |||
149 | eEncodingUint, | |||
150 | eFormatHex, | |||
151 | {dwarf_r5, dwarf_r5, LLDB_REGNUM_GENERIC_ARG26, LLDB_INVALID_REGNUM0xffffffffU, | |||
152 | LLDB_INVALID_REGNUM0xffffffffU}, | |||
153 | nullptr, | |||
154 | nullptr, | |||
155 | nullptr, | |||
156 | 0}, | |||
157 | {"r6", | |||
158 | "arg3", | |||
159 | 8, | |||
160 | 0, | |||
161 | eEncodingUint, | |||
162 | eFormatHex, | |||
163 | {dwarf_r6, dwarf_r6, LLDB_REGNUM_GENERIC_ARG37, LLDB_INVALID_REGNUM0xffffffffU, | |||
164 | LLDB_INVALID_REGNUM0xffffffffU}, | |||
165 | nullptr, | |||
166 | nullptr, | |||
167 | nullptr, | |||
168 | 0}, | |||
169 | {"r7", | |||
170 | "arg4", | |||
171 | 8, | |||
172 | 0, | |||
173 | eEncodingUint, | |||
174 | eFormatHex, | |||
175 | {dwarf_r7, dwarf_r7, LLDB_REGNUM_GENERIC_ARG48, LLDB_INVALID_REGNUM0xffffffffU, | |||
176 | LLDB_INVALID_REGNUM0xffffffffU}, | |||
177 | nullptr, | |||
178 | nullptr, | |||
179 | nullptr, | |||
180 | 0}, | |||
181 | {"r8", | |||
182 | "arg5", | |||
183 | 8, | |||
184 | 0, | |||
185 | eEncodingUint, | |||
186 | eFormatHex, | |||
187 | {dwarf_r8, dwarf_r8, LLDB_REGNUM_GENERIC_ARG59, LLDB_INVALID_REGNUM0xffffffffU, | |||
188 | LLDB_INVALID_REGNUM0xffffffffU}, | |||
189 | nullptr, | |||
190 | nullptr, | |||
191 | nullptr, | |||
192 | 0}, | |||
193 | {"r9", | |||
194 | "arg6", | |||
195 | 8, | |||
196 | 0, | |||
197 | eEncodingUint, | |||
198 | eFormatHex, | |||
199 | {dwarf_r9, dwarf_r9, LLDB_REGNUM_GENERIC_ARG610, LLDB_INVALID_REGNUM0xffffffffU, | |||
200 | LLDB_INVALID_REGNUM0xffffffffU}, | |||
201 | nullptr, | |||
202 | nullptr, | |||
203 | nullptr, | |||
204 | 0}, | |||
205 | {"r10", | |||
206 | "arg7", | |||
207 | 8, | |||
208 | 0, | |||
209 | eEncodingUint, | |||
210 | eFormatHex, | |||
211 | {dwarf_r10, dwarf_r10, LLDB_REGNUM_GENERIC_ARG711, LLDB_INVALID_REGNUM0xffffffffU, | |||
212 | LLDB_INVALID_REGNUM0xffffffffU}, | |||
213 | nullptr, | |||
214 | nullptr, | |||
215 | nullptr, | |||
216 | 0}, | |||
217 | {"r11", | |||
218 | "arg8", | |||
219 | 8, | |||
220 | 0, | |||
221 | eEncodingUint, | |||
222 | eFormatHex, | |||
223 | {dwarf_r11, dwarf_r11, LLDB_REGNUM_GENERIC_ARG812, LLDB_INVALID_REGNUM0xffffffffU, | |||
224 | LLDB_INVALID_REGNUM0xffffffffU}, | |||
225 | nullptr, | |||
226 | nullptr, | |||
227 | nullptr, | |||
228 | 0}, | |||
229 | {"r12", | |||
230 | nullptr, | |||
231 | 8, | |||
232 | 0, | |||
233 | eEncodingUint, | |||
234 | eFormatHex, | |||
235 | {dwarf_r12, dwarf_r12, LLDB_INVALID_REGNUM0xffffffffU, LLDB_INVALID_REGNUM0xffffffffU, | |||
236 | LLDB_INVALID_REGNUM0xffffffffU}, | |||
237 | nullptr, | |||
238 | nullptr, | |||
239 | nullptr, | |||
240 | 0}, | |||
241 | {"r13", | |||
242 | nullptr, | |||
243 | 8, | |||
244 | 0, | |||
245 | eEncodingUint, | |||
246 | eFormatHex, | |||
247 | {dwarf_r13, dwarf_r13, LLDB_INVALID_REGNUM0xffffffffU, LLDB_INVALID_REGNUM0xffffffffU, | |||
248 | LLDB_INVALID_REGNUM0xffffffffU}, | |||
249 | nullptr, | |||
250 | nullptr, | |||
251 | nullptr, | |||
252 | 0}, | |||
253 | {"r14", | |||
254 | nullptr, | |||
255 | 8, | |||
256 | 0, | |||
257 | eEncodingUint, | |||
258 | eFormatHex, | |||
259 | {dwarf_r14, dwarf_r14, LLDB_INVALID_REGNUM0xffffffffU, LLDB_INVALID_REGNUM0xffffffffU, | |||
260 | LLDB_INVALID_REGNUM0xffffffffU}, | |||
261 | nullptr, | |||
262 | nullptr, | |||
263 | nullptr, | |||
264 | 0}, | |||
265 | {"r15", | |||
266 | nullptr, | |||
267 | 8, | |||
268 | 0, | |||
269 | eEncodingUint, | |||
270 | eFormatHex, | |||
271 | {dwarf_r15, dwarf_r15, LLDB_INVALID_REGNUM0xffffffffU, LLDB_INVALID_REGNUM0xffffffffU, | |||
272 | LLDB_INVALID_REGNUM0xffffffffU}, | |||
273 | nullptr, | |||
274 | nullptr, | |||
275 | nullptr, | |||
276 | 0}, | |||
277 | {"r16", | |||
278 | nullptr, | |||
279 | 8, | |||
280 | 0, | |||
281 | eEncodingUint, | |||
282 | eFormatHex, | |||
283 | {dwarf_r16, dwarf_r16, LLDB_INVALID_REGNUM0xffffffffU, LLDB_INVALID_REGNUM0xffffffffU, | |||
284 | LLDB_INVALID_REGNUM0xffffffffU}, | |||
285 | nullptr, | |||
286 | nullptr, | |||
287 | nullptr, | |||
288 | 0}, | |||
289 | {"r17", | |||
290 | nullptr, | |||
291 | 8, | |||
292 | 0, | |||
293 | eEncodingUint, | |||
294 | eFormatHex, | |||
295 | {dwarf_r17, dwarf_r17, LLDB_INVALID_REGNUM0xffffffffU, LLDB_INVALID_REGNUM0xffffffffU, | |||
296 | LLDB_INVALID_REGNUM0xffffffffU}, | |||
297 | nullptr, | |||
298 | nullptr, | |||
299 | nullptr, | |||
300 | 0}, | |||
301 | {"r18", | |||
302 | nullptr, | |||
303 | 8, | |||
304 | 0, | |||
305 | eEncodingUint, | |||
306 | eFormatHex, | |||
307 | {dwarf_r18, dwarf_r18, LLDB_INVALID_REGNUM0xffffffffU, LLDB_INVALID_REGNUM0xffffffffU, | |||
308 | LLDB_INVALID_REGNUM0xffffffffU}, | |||
309 | nullptr, | |||
310 | nullptr, | |||
311 | nullptr, | |||
312 | 0}, | |||
313 | {"r19", | |||
314 | nullptr, | |||
315 | 8, | |||
316 | 0, | |||
317 | eEncodingUint, | |||
318 | eFormatHex, | |||
319 | {dwarf_r19, dwarf_r19, LLDB_INVALID_REGNUM0xffffffffU, LLDB_INVALID_REGNUM0xffffffffU, | |||
320 | LLDB_INVALID_REGNUM0xffffffffU}, | |||
321 | nullptr, | |||
322 | nullptr, | |||
323 | nullptr, | |||
324 | 0}, | |||
325 | {"r20", | |||
326 | nullptr, | |||
327 | 8, | |||
328 | 0, | |||
329 | eEncodingUint, | |||
330 | eFormatHex, | |||
331 | {dwarf_r20, dwarf_r20, LLDB_INVALID_REGNUM0xffffffffU, LLDB_INVALID_REGNUM0xffffffffU, | |||
332 | LLDB_INVALID_REGNUM0xffffffffU}, | |||
333 | nullptr, | |||
334 | nullptr, | |||
335 | nullptr, | |||
336 | 0}, | |||
337 | {"r21", | |||
338 | nullptr, | |||
339 | 8, | |||
340 | 0, | |||
341 | eEncodingUint, | |||
342 | eFormatHex, | |||
343 | {dwarf_r21, dwarf_r21, LLDB_INVALID_REGNUM0xffffffffU, LLDB_INVALID_REGNUM0xffffffffU, | |||
344 | LLDB_INVALID_REGNUM0xffffffffU}, | |||
345 | nullptr, | |||
346 | nullptr, | |||
347 | nullptr, | |||
348 | 0}, | |||
349 | {"r22", | |||
350 | nullptr, | |||
351 | 8, | |||
352 | 0, | |||
353 | eEncodingUint, | |||
354 | eFormatHex, | |||
355 | {dwarf_r22, dwarf_r22, LLDB_INVALID_REGNUM0xffffffffU, LLDB_INVALID_REGNUM0xffffffffU, | |||
356 | LLDB_INVALID_REGNUM0xffffffffU}, | |||
357 | nullptr, | |||
358 | nullptr, | |||
359 | nullptr, | |||
360 | 0}, | |||
361 | {"r23", | |||
362 | nullptr, | |||
363 | 8, | |||
364 | 0, | |||
365 | eEncodingUint, | |||
366 | eFormatHex, | |||
367 | {dwarf_r23, dwarf_r23, LLDB_INVALID_REGNUM0xffffffffU, LLDB_INVALID_REGNUM0xffffffffU, | |||
368 | LLDB_INVALID_REGNUM0xffffffffU}, | |||
369 | nullptr, | |||
370 | nullptr, | |||
371 | nullptr, | |||
372 | 0}, | |||
373 | {"r24", | |||
374 | nullptr, | |||
375 | 8, | |||
376 | 0, | |||
377 | eEncodingUint, | |||
378 | eFormatHex, | |||
379 | {dwarf_r24, dwarf_r24, LLDB_INVALID_REGNUM0xffffffffU, LLDB_INVALID_REGNUM0xffffffffU, | |||
380 | LLDB_INVALID_REGNUM0xffffffffU}, | |||
381 | nullptr, | |||
382 | nullptr, | |||
383 | nullptr, | |||
384 | 0}, | |||
385 | {"r25", | |||
386 | nullptr, | |||
387 | 8, | |||
388 | 0, | |||
389 | eEncodingUint, | |||
390 | eFormatHex, | |||
391 | {dwarf_r25, dwarf_r25, LLDB_INVALID_REGNUM0xffffffffU, LLDB_INVALID_REGNUM0xffffffffU, | |||
392 | LLDB_INVALID_REGNUM0xffffffffU}, | |||
393 | nullptr, | |||
394 | nullptr, | |||
395 | nullptr, | |||
396 | 0}, | |||
397 | {"r26", | |||
398 | nullptr, | |||
399 | 8, | |||
400 | 0, | |||
401 | eEncodingUint, | |||
402 | eFormatHex, | |||
403 | {dwarf_r26, dwarf_r26, LLDB_INVALID_REGNUM0xffffffffU, LLDB_INVALID_REGNUM0xffffffffU, | |||
404 | LLDB_INVALID_REGNUM0xffffffffU}, | |||
405 | nullptr, | |||
406 | nullptr, | |||
407 | nullptr, | |||
408 | 0}, | |||
409 | {"r27", | |||
410 | nullptr, | |||
411 | 8, | |||
412 | 0, | |||
413 | eEncodingUint, | |||
414 | eFormatHex, | |||
415 | {dwarf_r27, dwarf_r27, LLDB_INVALID_REGNUM0xffffffffU, LLDB_INVALID_REGNUM0xffffffffU, | |||
416 | LLDB_INVALID_REGNUM0xffffffffU}, | |||
417 | nullptr, | |||
418 | nullptr, | |||
419 | nullptr, | |||
420 | 0}, | |||
421 | {"r28", | |||
422 | "gp", | |||
423 | 8, | |||
424 | 0, | |||
425 | eEncodingUint, | |||
426 | eFormatHex, | |||
427 | {dwarf_r28, dwarf_r28, LLDB_INVALID_REGNUM0xffffffffU, LLDB_INVALID_REGNUM0xffffffffU, | |||
428 | LLDB_INVALID_REGNUM0xffffffffU}, | |||
429 | nullptr, | |||
430 | nullptr, | |||
431 | nullptr, | |||
432 | 0}, | |||
433 | {"r29", | |||
434 | "sp", | |||
435 | 8, | |||
436 | 0, | |||
437 | eEncodingUint, | |||
438 | eFormatHex, | |||
439 | {dwarf_r29, dwarf_r29, LLDB_REGNUM_GENERIC_SP1, LLDB_INVALID_REGNUM0xffffffffU, | |||
440 | LLDB_INVALID_REGNUM0xffffffffU}, | |||
441 | nullptr, | |||
442 | nullptr, | |||
443 | nullptr, | |||
444 | 0}, | |||
445 | {"r30", | |||
446 | "fp", | |||
447 | 8, | |||
448 | 0, | |||
449 | eEncodingUint, | |||
450 | eFormatHex, | |||
451 | {dwarf_r30, dwarf_r30, LLDB_REGNUM_GENERIC_FP2, LLDB_INVALID_REGNUM0xffffffffU, | |||
452 | LLDB_INVALID_REGNUM0xffffffffU}, | |||
453 | nullptr, | |||
454 | nullptr, | |||
455 | nullptr, | |||
456 | 0}, | |||
457 | {"r31", | |||
458 | "ra", | |||
459 | 8, | |||
460 | 0, | |||
461 | eEncodingUint, | |||
462 | eFormatHex, | |||
463 | {dwarf_r31, dwarf_r31, LLDB_REGNUM_GENERIC_RA3, LLDB_INVALID_REGNUM0xffffffffU, | |||
464 | LLDB_INVALID_REGNUM0xffffffffU}, | |||
465 | nullptr, | |||
466 | nullptr, | |||
467 | nullptr, | |||
468 | 0}, | |||
469 | {"sr", | |||
470 | nullptr, | |||
471 | 4, | |||
472 | 0, | |||
473 | eEncodingUint, | |||
474 | eFormatHex, | |||
475 | {dwarf_sr, dwarf_sr, LLDB_REGNUM_GENERIC_FLAGS4, LLDB_INVALID_REGNUM0xffffffffU, | |||
476 | LLDB_INVALID_REGNUM0xffffffffU}, | |||
477 | nullptr, | |||
478 | nullptr, | |||
479 | nullptr, | |||
480 | 0}, | |||
481 | {"lo", | |||
482 | nullptr, | |||
483 | 8, | |||
484 | 0, | |||
485 | eEncodingUint, | |||
486 | eFormatHex, | |||
487 | {dwarf_lo, dwarf_lo, LLDB_INVALID_REGNUM0xffffffffU, LLDB_INVALID_REGNUM0xffffffffU, | |||
488 | LLDB_INVALID_REGNUM0xffffffffU}, | |||
489 | nullptr, | |||
490 | nullptr, | |||
491 | nullptr, | |||
492 | 0}, | |||
493 | {"hi", | |||
494 | nullptr, | |||
495 | 8, | |||
496 | 0, | |||
497 | eEncodingUint, | |||
498 | eFormatHex, | |||
499 | {dwarf_hi, dwarf_hi, LLDB_INVALID_REGNUM0xffffffffU, LLDB_INVALID_REGNUM0xffffffffU, | |||
500 | LLDB_INVALID_REGNUM0xffffffffU}, | |||
501 | nullptr, | |||
502 | nullptr, | |||
503 | nullptr, | |||
504 | 0}, | |||
505 | {"bad", | |||
506 | nullptr, | |||
507 | 8, | |||
508 | 0, | |||
509 | eEncodingUint, | |||
510 | eFormatHex, | |||
511 | {dwarf_bad, dwarf_bad, LLDB_INVALID_REGNUM0xffffffffU, LLDB_INVALID_REGNUM0xffffffffU, | |||
512 | LLDB_INVALID_REGNUM0xffffffffU}, | |||
513 | nullptr, | |||
514 | nullptr, | |||
515 | nullptr, | |||
516 | 0}, | |||
517 | {"cause", | |||
518 | nullptr, | |||
519 | 8, | |||
520 | 0, | |||
521 | eEncodingUint, | |||
522 | eFormatHex, | |||
523 | {dwarf_cause, dwarf_cause, LLDB_INVALID_REGNUM0xffffffffU, LLDB_INVALID_REGNUM0xffffffffU, | |||
524 | LLDB_INVALID_REGNUM0xffffffffU}, | |||
525 | nullptr, | |||
526 | nullptr, | |||
527 | nullptr, | |||
528 | 0}, | |||
529 | {"pc", | |||
530 | nullptr, | |||
531 | 8, | |||
532 | 0, | |||
533 | eEncodingUint, | |||
534 | eFormatHex, | |||
535 | {dwarf_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC0, LLDB_INVALID_REGNUM0xffffffffU, | |||
536 | LLDB_INVALID_REGNUM0xffffffffU}, | |||
537 | nullptr, | |||
538 | nullptr, | |||
539 | nullptr, | |||
540 | 0}, | |||
541 | }; | |||
542 | ||||
543 | static const uint32_t k_num_register_infos = | |||
544 | llvm::array_lengthof(g_register_infos_mips64); | |||
545 | ||||
546 | const lldb_private::RegisterInfo * | |||
547 | ABISysV_mips64::GetRegisterInfoArray(uint32_t &count) { | |||
548 | count = k_num_register_infos; | |||
549 | return g_register_infos_mips64; | |||
550 | } | |||
551 | ||||
552 | size_t ABISysV_mips64::GetRedZoneSize() const { return 0; } | |||
553 | ||||
554 | // Static Functions | |||
555 | ||||
556 | ABISP | |||
557 | ABISysV_mips64::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) { | |||
558 | if (arch.GetTriple().isMIPS64()) | |||
559 | return ABISP( | |||
560 | new ABISysV_mips64(std::move(process_sp), MakeMCRegisterInfo(arch))); | |||
561 | return ABISP(); | |||
562 | } | |||
563 | ||||
564 | bool ABISysV_mips64::PrepareTrivialCall(Thread &thread, addr_t sp, | |||
565 | addr_t func_addr, addr_t return_addr, | |||
566 | llvm::ArrayRef<addr_t> args) const { | |||
567 | Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS(1u << 8))); | |||
568 | ||||
569 | if (log) { | |||
570 | StreamString s; | |||
571 | s.Printf("ABISysV_mips64::PrepareTrivialCall (tid = 0x%" PRIx64"llx" | |||
572 | ", sp = 0x%" PRIx64"llx" ", func_addr = 0x%" PRIx64"llx" | |||
573 | ", return_addr = 0x%" PRIx64"llx", | |||
574 | thread.GetID(), (uint64_t)sp, (uint64_t)func_addr, | |||
575 | (uint64_t)return_addr); | |||
576 | ||||
577 | for (size_t i = 0; i < args.size(); ++i) | |||
578 | s.Printf(", arg%zd = 0x%" PRIx64"llx", i + 1, args[i]); | |||
579 | s.PutCString(")"); | |||
580 | log->PutString(s.GetString()); | |||
581 | } | |||
582 | ||||
583 | RegisterContext *reg_ctx = thread.GetRegisterContext().get(); | |||
584 | if (!reg_ctx) | |||
585 | return false; | |||
586 | ||||
587 | const RegisterInfo *reg_info = nullptr; | |||
588 | ||||
589 | if (args.size() > 8) // TODO handle more than 8 arguments | |||
590 | return false; | |||
591 | ||||
592 | for (size_t i = 0; i < args.size(); ++i) { | |||
593 | reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, | |||
594 | LLDB_REGNUM_GENERIC_ARG15 + i); | |||
595 | LLDB_LOGF(log, "About to write arg%zd (0x%" PRIx64 ") into %s", i + 1,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("About to write arg%zd (0x%" "llx" ") into %s" , i + 1, args[i], reg_info->name); } while (0) | |||
596 | args[i], reg_info->name)do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("About to write arg%zd (0x%" "llx" ") into %s" , i + 1, args[i], reg_info->name); } while (0); | |||
597 | if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i])) | |||
598 | return false; | |||
599 | } | |||
600 | ||||
601 | // First, align the SP | |||
602 | ||||
603 | LLDB_LOGF(log, "16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64,do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("16-byte aligning SP: 0x%" "llx" " to 0x%" "llx", (uint64_t)sp, (uint64_t)(sp & ~0xfull)); } while ( 0) | |||
604 | (uint64_t)sp, (uint64_t)(sp & ~0xfull))do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("16-byte aligning SP: 0x%" "llx" " to 0x%" "llx", (uint64_t)sp, (uint64_t)(sp & ~0xfull)); } while ( 0); | |||
605 | ||||
606 | sp &= ~(0xfull); // 16-byte alignment | |||
607 | ||||
608 | Status error; | |||
609 | const RegisterInfo *pc_reg_info = | |||
610 | reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC0); | |||
611 | const RegisterInfo *sp_reg_info = | |||
612 | reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP1); | |||
613 | const RegisterInfo *ra_reg_info = | |||
614 | reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA3); | |||
615 | const RegisterInfo *r25_info = reg_ctx->GetRegisterInfoByName("r25", 0); | |||
616 | const RegisterInfo *r0_info = reg_ctx->GetRegisterInfoByName("zero", 0); | |||
617 | ||||
618 | LLDB_LOGF(log, "Writing R0: 0x%" PRIx64, (uint64_t)0)do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Writing R0: 0x%" "llx", (uint64_t)0 ); } while (0); | |||
619 | ||||
620 | /* Write r0 with 0, in case we are stopped in syscall, | |||
621 | * such setting prevents automatic decrement of the PC. | |||
622 | * This clears the bug 23659 for MIPS. | |||
623 | */ | |||
624 | if (!reg_ctx->WriteRegisterFromUnsigned(r0_info, (uint64_t)0)) | |||
625 | return false; | |||
626 | ||||
627 | LLDB_LOGF(log, "Writing SP: 0x%" PRIx64, (uint64_t)sp)do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Writing SP: 0x%" "llx", (uint64_t)sp ); } while (0); | |||
628 | ||||
629 | // Set "sp" to the requested value | |||
630 | if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp)) | |||
631 | return false; | |||
632 | ||||
633 | LLDB_LOGF(log, "Writing RA: 0x%" PRIx64, (uint64_t)return_addr)do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Writing RA: 0x%" "llx", (uint64_t)return_addr ); } while (0); | |||
634 | ||||
635 | // Set "ra" to the return address | |||
636 | if (!reg_ctx->WriteRegisterFromUnsigned(ra_reg_info, return_addr)) | |||
637 | return false; | |||
638 | ||||
639 | LLDB_LOGF(log, "Writing PC: 0x%" PRIx64, (uint64_t)func_addr)do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Writing PC: 0x%" "llx", (uint64_t)func_addr ); } while (0); | |||
640 | ||||
641 | // Set pc to the address of the called function. | |||
642 | if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr)) | |||
643 | return false; | |||
644 | ||||
645 | LLDB_LOGF(log, "Writing r25: 0x%" PRIx64, (uint64_t)func_addr)do { ::lldb_private::Log *log_private = (log); if (log_private ) log_private->Printf("Writing r25: 0x%" "llx", (uint64_t) func_addr); } while (0); | |||
646 | ||||
647 | // All callers of position independent functions must place the address of | |||
648 | // the called function in t9 (r25) | |||
649 | if (!reg_ctx->WriteRegisterFromUnsigned(r25_info, func_addr)) | |||
650 | return false; | |||
651 | ||||
652 | return true; | |||
653 | } | |||
654 | ||||
655 | bool ABISysV_mips64::GetArgumentValues(Thread &thread, | |||
656 | ValueList &values) const { | |||
657 | return false; | |||
658 | } | |||
659 | ||||
660 | Status ABISysV_mips64::SetReturnValueObject(lldb::StackFrameSP &frame_sp, | |||
661 | lldb::ValueObjectSP &new_value_sp) { | |||
662 | Status error; | |||
663 | if (!new_value_sp) { | |||
| ||||
664 | error.SetErrorString("Empty value object for return value."); | |||
665 | return error; | |||
666 | } | |||
667 | ||||
668 | CompilerType compiler_type = new_value_sp->GetCompilerType(); | |||
669 | if (!compiler_type) { | |||
670 | error.SetErrorString("Null clang type for return value."); | |||
671 | return error; | |||
672 | } | |||
673 | ||||
674 | Thread *thread = frame_sp->GetThread().get(); | |||
675 | ||||
676 | RegisterContext *reg_ctx = thread->GetRegisterContext().get(); | |||
677 | ||||
678 | if (!reg_ctx) | |||
679 | error.SetErrorString("no registers are available"); | |||
680 | ||||
681 | DataExtractor data; | |||
682 | Status data_error; | |||
683 | size_t num_bytes = new_value_sp->GetData(data, data_error); | |||
684 | if (data_error.Fail()) { | |||
685 | error.SetErrorStringWithFormat( | |||
686 | "Couldn't convert return value to raw data: %s", | |||
687 | data_error.AsCString()); | |||
688 | return error; | |||
689 | } | |||
690 | ||||
691 | const uint32_t type_flags = compiler_type.GetTypeInfo(nullptr); | |||
692 | ||||
693 | if (type_flags & eTypeIsScalar || type_flags & eTypeIsPointer) { | |||
694 | if (type_flags & eTypeIsInteger || type_flags & eTypeIsPointer) { | |||
695 | lldb::offset_t offset = 0; | |||
696 | ||||
697 | if (num_bytes <= 16) { | |||
698 | const RegisterInfo *r2_info = reg_ctx->GetRegisterInfoByName("r2", 0); | |||
| ||||
699 | if (num_bytes <= 8) { | |||
700 | uint64_t raw_value = data.GetMaxU64(&offset, num_bytes); | |||
701 | ||||
702 | if (!reg_ctx->WriteRegisterFromUnsigned(r2_info, raw_value)) | |||
703 | error.SetErrorString("failed to write register r2"); | |||
704 | } else { | |||
705 | uint64_t raw_value = data.GetMaxU64(&offset, 8); | |||
706 | if (reg_ctx->WriteRegisterFromUnsigned(r2_info, raw_value)) { | |||
707 | const RegisterInfo *r3_info = | |||
708 | reg_ctx->GetRegisterInfoByName("r3", 0); | |||
709 | raw_value = data.GetMaxU64(&offset, num_bytes - offset); | |||
710 | ||||
711 | if (!reg_ctx->WriteRegisterFromUnsigned(r3_info, raw_value)) | |||
712 | error.SetErrorString("failed to write register r3"); | |||
713 | } else | |||
714 | error.SetErrorString("failed to write register r2"); | |||
715 | } | |||
716 | } else { | |||
717 | error.SetErrorString("We don't support returning longer than 128 bit " | |||
718 | "integer values at present."); | |||
719 | } | |||
720 | } else if (type_flags & eTypeIsFloat) { | |||
721 | error.SetErrorString("TODO: Handle Float Types."); | |||
722 | } | |||
723 | } else if (type_flags & eTypeIsVector) { | |||
724 | error.SetErrorString("returning vector values are not supported"); | |||
725 | } | |||
726 | ||||
727 | return error; | |||
728 | } | |||
729 | ||||
730 | ValueObjectSP ABISysV_mips64::GetReturnValueObjectSimple( | |||
731 | Thread &thread, CompilerType &return_compiler_type) const { | |||
732 | ValueObjectSP return_valobj_sp; | |||
733 | return return_valobj_sp; | |||
734 | } | |||
735 | ||||
736 | ValueObjectSP ABISysV_mips64::GetReturnValueObjectImpl( | |||
737 | Thread &thread, CompilerType &return_compiler_type) const { | |||
738 | ValueObjectSP return_valobj_sp; | |||
739 | Value value; | |||
740 | Status error; | |||
741 | ||||
742 | ExecutionContext exe_ctx(thread.shared_from_this()); | |||
743 | if (exe_ctx.GetTargetPtr() == nullptr || exe_ctx.GetProcessPtr() == nullptr) | |||
744 | return return_valobj_sp; | |||
745 | ||||
746 | value.SetCompilerType(return_compiler_type); | |||
747 | ||||
748 | RegisterContext *reg_ctx = thread.GetRegisterContext().get(); | |||
749 | if (!reg_ctx) | |||
750 | return return_valobj_sp; | |||
751 | ||||
752 | Target *target = exe_ctx.GetTargetPtr(); | |||
753 | const ArchSpec target_arch = target->GetArchitecture(); | |||
754 | ByteOrder target_byte_order = target_arch.GetByteOrder(); | |||
755 | llvm::Optional<uint64_t> byte_size = | |||
756 | return_compiler_type.GetByteSize(&thread); | |||
757 | if (!byte_size) | |||
758 | return return_valobj_sp; | |||
759 | const uint32_t type_flags = return_compiler_type.GetTypeInfo(nullptr); | |||
760 | uint32_t fp_flag = | |||
761 | target_arch.GetFlags() & lldb_private::ArchSpec::eMIPS_ABI_FP_mask; | |||
762 | ||||
763 | const RegisterInfo *r2_info = reg_ctx->GetRegisterInfoByName("r2", 0); | |||
764 | const RegisterInfo *r3_info = reg_ctx->GetRegisterInfoByName("r3", 0); | |||
765 | ||||
766 | if (type_flags & eTypeIsScalar || type_flags & eTypeIsPointer) { | |||
767 | value.SetValueType(Value::ValueType::Scalar); | |||
768 | ||||
769 | bool success = false; | |||
770 | if (type_flags & eTypeIsInteger || type_flags & eTypeIsPointer) { | |||
771 | // Extract the register context so we can read arguments from registers | |||
772 | // In MIPS register "r2" (v0) holds the integer function return values | |||
773 | ||||
774 | uint64_t raw_value = reg_ctx->ReadRegisterAsUnsigned(r2_info, 0); | |||
775 | ||||
776 | const bool is_signed = (type_flags & eTypeIsSigned) != 0; | |||
777 | switch (*byte_size) { | |||
778 | default: | |||
779 | break; | |||
780 | ||||
781 | case sizeof(uint64_t): | |||
782 | if (is_signed) | |||
783 | value.GetScalar() = (int64_t)(raw_value); | |||
784 | else | |||
785 | value.GetScalar() = (uint64_t)(raw_value); | |||
786 | success = true; | |||
787 | break; | |||
788 | ||||
789 | case sizeof(uint32_t): | |||
790 | if (is_signed) | |||
791 | value.GetScalar() = (int32_t)(raw_value & UINT32_MAX0xffffffffU); | |||
792 | else | |||
793 | value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX0xffffffffU); | |||
794 | success = true; | |||
795 | break; | |||
796 | ||||
797 | case sizeof(uint16_t): | |||
798 | if (is_signed) | |||
799 | value.GetScalar() = (int16_t)(raw_value & UINT16_MAX0xffff); | |||
800 | else | |||
801 | value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX0xffff); | |||
802 | success = true; | |||
803 | break; | |||
804 | ||||
805 | case sizeof(uint8_t): | |||
806 | if (is_signed) | |||
807 | value.GetScalar() = (int8_t)(raw_value & UINT8_MAX0xff); | |||
808 | else | |||
809 | value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX0xff); | |||
810 | success = true; | |||
811 | break; | |||
812 | } | |||
813 | } else if (type_flags & eTypeIsFloat) { | |||
814 | if (type_flags & eTypeIsComplex) { | |||
815 | // Don't handle complex yet. | |||
816 | } else if (IsSoftFloat(fp_flag)) { | |||
817 | uint64_t raw_value = reg_ctx->ReadRegisterAsUnsigned(r2_info, 0); | |||
818 | switch (*byte_size) { | |||
819 | case 4: | |||
820 | value.GetScalar() = *((float *)(&raw_value)); | |||
821 | success = true; | |||
822 | break; | |||
823 | case 8: | |||
824 | value.GetScalar() = *((double *)(&raw_value)); | |||
825 | success = true; | |||
826 | break; | |||
827 | case 16: | |||
828 | uint64_t result[2]; | |||
829 | if (target_byte_order == eByteOrderLittle) { | |||
830 | result[0] = raw_value; | |||
831 | result[1] = reg_ctx->ReadRegisterAsUnsigned(r3_info, 0); | |||
832 | value.GetScalar() = *((long double *)(result)); | |||
833 | } else { | |||
834 | result[0] = reg_ctx->ReadRegisterAsUnsigned(r3_info, 0); | |||
835 | result[1] = raw_value; | |||
836 | value.GetScalar() = *((long double *)(result)); | |||
837 | } | |||
838 | success = true; | |||
839 | break; | |||
840 | } | |||
841 | ||||
842 | } else { | |||
843 | if (*byte_size <= sizeof(long double)) { | |||
844 | const RegisterInfo *f0_info = reg_ctx->GetRegisterInfoByName("f0", 0); | |||
845 | ||||
846 | RegisterValue f0_value; | |||
847 | DataExtractor f0_data; | |||
848 | ||||
849 | reg_ctx->ReadRegister(f0_info, f0_value); | |||
850 | ||||
851 | f0_value.GetData(f0_data); | |||
852 | ||||
853 | lldb::offset_t offset = 0; | |||
854 | if (*byte_size == sizeof(float)) { | |||
855 | value.GetScalar() = (float)f0_data.GetFloat(&offset); | |||
856 | success = true; | |||
857 | } else if (*byte_size == sizeof(double)) { | |||
858 | value.GetScalar() = (double)f0_data.GetDouble(&offset); | |||
859 | success = true; | |||
860 | } else if (*byte_size == sizeof(long double)) { | |||
861 | const RegisterInfo *f2_info = | |||
862 | reg_ctx->GetRegisterInfoByName("f2", 0); | |||
863 | RegisterValue f2_value; | |||
864 | DataExtractor f2_data; | |||
865 | reg_ctx->ReadRegister(f2_info, f2_value); | |||
866 | DataExtractor *copy_from_extractor = nullptr; | |||
867 | DataBufferSP data_sp(new DataBufferHeap(16, 0)); | |||
868 | DataExtractor return_ext( | |||
869 | data_sp, target_byte_order, | |||
870 | target->GetArchitecture().GetAddressByteSize()); | |||
871 | ||||
872 | if (target_byte_order == eByteOrderLittle) { | |||
873 | copy_from_extractor = &f0_data; | |||
874 | copy_from_extractor->CopyByteOrderedData( | |||
875 | 0, 8, data_sp->GetBytes(), *byte_size - 8, target_byte_order); | |||
876 | f2_value.GetData(f2_data); | |||
877 | copy_from_extractor = &f2_data; | |||
878 | copy_from_extractor->CopyByteOrderedData( | |||
879 | 0, 8, data_sp->GetBytes() + 8, *byte_size - 8, | |||
880 | target_byte_order); | |||
881 | } else { | |||
882 | copy_from_extractor = &f0_data; | |||
883 | copy_from_extractor->CopyByteOrderedData( | |||
884 | 0, 8, data_sp->GetBytes() + 8, *byte_size - 8, | |||
885 | target_byte_order); | |||
886 | f2_value.GetData(f2_data); | |||
887 | copy_from_extractor = &f2_data; | |||
888 | copy_from_extractor->CopyByteOrderedData( | |||
889 | 0, 8, data_sp->GetBytes(), *byte_size - 8, target_byte_order); | |||
890 | } | |||
891 | ||||
892 | return_valobj_sp = ValueObjectConstResult::Create( | |||
893 | &thread, return_compiler_type, ConstString(""), return_ext); | |||
894 | return return_valobj_sp; | |||
895 | } | |||
896 | } | |||
897 | } | |||
898 | } | |||
899 | ||||
900 | if (success) | |||
901 | return_valobj_sp = ValueObjectConstResult::Create( | |||
902 | thread.GetStackFrameAtIndex(0).get(), value, ConstString("")); | |||
903 | } else if (type_flags & eTypeIsStructUnion || type_flags & eTypeIsClass || | |||
904 | type_flags & eTypeIsVector) { | |||
905 | // Any structure of up to 16 bytes in size is returned in the registers. | |||
906 | if (*byte_size <= 16) { | |||
907 | DataBufferSP data_sp(new DataBufferHeap(16, 0)); | |||
908 | DataExtractor return_ext(data_sp, target_byte_order, | |||
909 | target->GetArchitecture().GetAddressByteSize()); | |||
910 | ||||
911 | RegisterValue r2_value, r3_value, f0_value, f1_value, f2_value; | |||
912 | // Tracks how much bytes of r2 and r3 registers we've consumed so far | |||
913 | uint32_t integer_bytes = 0; | |||
914 | ||||
915 | // True if return values are in FP return registers. | |||
916 | bool use_fp_regs = false; | |||
917 | // True if we found any non floating point field in structure. | |||
918 | bool found_non_fp_field = false; | |||
919 | // True if return values are in r2 register. | |||
920 | bool use_r2 = false; | |||
921 | // True if return values are in r3 register. | |||
922 | bool use_r3 = false; | |||
923 | // True if the result is copied into our data buffer | |||
924 | bool sucess = false; | |||
925 | std::string name; | |||
926 | bool is_complex; | |||
927 | uint32_t count; | |||
928 | const uint32_t num_children = return_compiler_type.GetNumFields(); | |||
929 | ||||
930 | // A structure consisting of one or two FP values (and nothing else) will | |||
931 | // be returned in the two FP return-value registers i.e fp0 and fp2. | |||
932 | if (num_children <= 2) { | |||
933 | uint64_t field_bit_offset = 0; | |||
934 | ||||
935 | // Check if this structure contains only floating point fields | |||
936 | for (uint32_t idx = 0; idx < num_children; idx++) { | |||
937 | CompilerType field_compiler_type = | |||
938 | return_compiler_type.GetFieldAtIndex(idx, name, &field_bit_offset, | |||
939 | nullptr, nullptr); | |||
940 | ||||
941 | if (field_compiler_type.IsFloatingPointType(count, is_complex)) | |||
942 | use_fp_regs = true; | |||
943 | else | |||
944 | found_non_fp_field = true; | |||
945 | } | |||
946 | ||||
947 | if (use_fp_regs && !found_non_fp_field) { | |||
948 | // We have one or two FP-only values in this structure. Get it from | |||
949 | // f0/f2 registers. | |||
950 | DataExtractor f0_data, f1_data, f2_data; | |||
951 | const RegisterInfo *f0_info = reg_ctx->GetRegisterInfoByName("f0", 0); | |||
952 | const RegisterInfo *f1_info = reg_ctx->GetRegisterInfoByName("f1", 0); | |||
953 | const RegisterInfo *f2_info = reg_ctx->GetRegisterInfoByName("f2", 0); | |||
954 | ||||
955 | reg_ctx->ReadRegister(f0_info, f0_value); | |||
956 | reg_ctx->ReadRegister(f2_info, f2_value); | |||
957 | ||||
958 | f0_value.GetData(f0_data); | |||
959 | ||||
960 | for (uint32_t idx = 0; idx < num_children; idx++) { | |||
961 | CompilerType field_compiler_type = | |||
962 | return_compiler_type.GetFieldAtIndex( | |||
963 | idx, name, &field_bit_offset, nullptr, nullptr); | |||
964 | llvm::Optional<uint64_t> field_byte_width = | |||
965 | field_compiler_type.GetByteSize(&thread); | |||
966 | if (!field_byte_width) | |||
967 | return return_valobj_sp; | |||
968 | ||||
969 | DataExtractor *copy_from_extractor = nullptr; | |||
970 | uint64_t return_value[2]; | |||
971 | offset_t offset = 0; | |||
972 | ||||
973 | if (idx == 0) { | |||
974 | // This case is for long double type. | |||
975 | if (*field_byte_width == 16) { | |||
976 | ||||
977 | // If structure contains long double type, then it is returned | |||
978 | // in fp0/fp1 registers. | |||
979 | if (target_byte_order == eByteOrderLittle) { | |||
980 | return_value[0] = f0_data.GetU64(&offset); | |||
981 | reg_ctx->ReadRegister(f1_info, f1_value); | |||
982 | f1_value.GetData(f1_data); | |||
983 | offset = 0; | |||
984 | return_value[1] = f1_data.GetU64(&offset); | |||
985 | } else { | |||
986 | return_value[1] = f0_data.GetU64(&offset); | |||
987 | reg_ctx->ReadRegister(f1_info, f1_value); | |||
988 | f1_value.GetData(f1_data); | |||
989 | offset = 0; | |||
990 | return_value[0] = f1_data.GetU64(&offset); | |||
991 | } | |||
992 | ||||
993 | f0_data.SetData(return_value, *field_byte_width, | |||
994 | target_byte_order); | |||
995 | } | |||
996 | copy_from_extractor = &f0_data; // This is in f0, copy from | |||
997 | // register to our result | |||
998 | // structure | |||
999 | } else { | |||
1000 | f2_value.GetData(f2_data); | |||
1001 | // This is in f2, copy from register to our result structure | |||
1002 | copy_from_extractor = &f2_data; | |||
1003 | } | |||
1004 | ||||
1005 | // Sanity check to avoid crash | |||
1006 | if (!copy_from_extractor || | |||
1007 | *field_byte_width > copy_from_extractor->GetByteSize()) | |||
1008 | return return_valobj_sp; | |||
1009 | ||||
1010 | // copy the register contents into our data buffer | |||
1011 | copy_from_extractor->CopyByteOrderedData( | |||
1012 | 0, *field_byte_width, | |||
1013 | data_sp->GetBytes() + (field_bit_offset / 8), *field_byte_width, | |||
1014 | target_byte_order); | |||
1015 | } | |||
1016 | ||||
1017 | // The result is in our data buffer. Create a variable object out of | |||
1018 | // it | |||
1019 | return_valobj_sp = ValueObjectConstResult::Create( | |||
1020 | &thread, return_compiler_type, ConstString(""), return_ext); | |||
1021 | ||||
1022 | return return_valobj_sp; | |||
1023 | } | |||
1024 | } | |||
1025 | ||||
1026 | // If we reach here, it means this structure either contains more than | |||
1027 | // two fields or it contains at least one non floating point type. In | |||
1028 | // that case, all fields are returned in GP return registers. | |||
1029 | for (uint32_t idx = 0; idx < num_children; idx++) { | |||
1030 | uint64_t field_bit_offset = 0; | |||
1031 | bool is_signed; | |||
1032 | uint32_t padding; | |||
1033 | ||||
1034 | CompilerType field_compiler_type = return_compiler_type.GetFieldAtIndex( | |||
1035 | idx, name, &field_bit_offset, nullptr, nullptr); | |||
1036 | llvm::Optional<uint64_t> field_byte_width = | |||
1037 | field_compiler_type.GetByteSize(&thread); | |||
1038 | ||||
1039 | // if we don't know the size of the field (e.g. invalid type), just | |||
1040 | // bail out | |||
1041 | if (!field_byte_width || *field_byte_width == 0) | |||
1042 | break; | |||
1043 | ||||
1044 | uint32_t field_byte_offset = field_bit_offset / 8; | |||
1045 | ||||
1046 | if (field_compiler_type.IsIntegerOrEnumerationType(is_signed) || | |||
1047 | field_compiler_type.IsPointerType() || | |||
1048 | field_compiler_type.IsFloatingPointType(count, is_complex)) { | |||
1049 | padding = field_byte_offset - integer_bytes; | |||
1050 | ||||
1051 | if (integer_bytes < 8) { | |||
1052 | // We have not yet consumed r2 completely. | |||
1053 | if (integer_bytes + *field_byte_width + padding <= 8) { | |||
1054 | // This field fits in r2, copy its value from r2 to our result | |||
1055 | // structure | |||
1056 | integer_bytes = integer_bytes + *field_byte_width + | |||
1057 | padding; // Increase the consumed bytes. | |||
1058 | use_r2 = true; | |||
1059 | } else { | |||
1060 | // There isn't enough space left in r2 for this field, so this | |||
1061 | // will be in r3. | |||
1062 | integer_bytes = integer_bytes + *field_byte_width + | |||
1063 | padding; // Increase the consumed bytes. | |||
1064 | use_r3 = true; | |||
1065 | } | |||
1066 | } | |||
1067 | // We already have consumed at-least 8 bytes that means r2 is done, | |||
1068 | // and this field will be in r3. Check if this field can fit in r3. | |||
1069 | else if (integer_bytes + *field_byte_width + padding <= 16) { | |||
1070 | integer_bytes = integer_bytes + *field_byte_width + padding; | |||
1071 | use_r3 = true; | |||
1072 | } else { | |||
1073 | // There isn't any space left for this field, this should not | |||
1074 | // happen as we have already checked the overall size is not | |||
1075 | // greater than 16 bytes. For now, return a nullptr return value | |||
1076 | // object. | |||
1077 | return return_valobj_sp; | |||
1078 | } | |||
1079 | } | |||
1080 | } | |||
1081 | // Vector types up to 16 bytes are returned in GP return registers | |||
1082 | if (type_flags & eTypeIsVector) { | |||
1083 | if (*byte_size <= 8) | |||
1084 | use_r2 = true; | |||
1085 | else { | |||
1086 | use_r2 = true; | |||
1087 | use_r3 = true; | |||
1088 | } | |||
1089 | } | |||
1090 | ||||
1091 | if (use_r2) { | |||
1092 | reg_ctx->ReadRegister(r2_info, r2_value); | |||
1093 | ||||
1094 | const size_t bytes_copied = r2_value.GetAsMemoryData( | |||
1095 | r2_info, data_sp->GetBytes(), r2_info->byte_size, target_byte_order, | |||
1096 | error); | |||
1097 | if (bytes_copied != r2_info->byte_size) | |||
1098 | return return_valobj_sp; | |||
1099 | sucess = true; | |||
1100 | } | |||
1101 | if (use_r3) { | |||
1102 | reg_ctx->ReadRegister(r3_info, r3_value); | |||
1103 | const size_t bytes_copied = r3_value.GetAsMemoryData( | |||
1104 | r3_info, data_sp->GetBytes() + r2_info->byte_size, | |||
1105 | r3_info->byte_size, target_byte_order, error); | |||
1106 | ||||
1107 | if (bytes_copied != r3_info->byte_size) | |||
1108 | return return_valobj_sp; | |||
1109 | sucess = true; | |||
1110 | } | |||
1111 | if (sucess) { | |||
1112 | // The result is in our data buffer. Create a variable object out of | |||
1113 | // it | |||
1114 | return_valobj_sp = ValueObjectConstResult::Create( | |||
1115 | &thread, return_compiler_type, ConstString(""), return_ext); | |||
1116 | } | |||
1117 | return return_valobj_sp; | |||
1118 | } | |||
1119 | ||||
1120 | // Any structure/vector greater than 16 bytes in size is returned in | |||
1121 | // memory. The pointer to that memory is returned in r2. | |||
1122 | uint64_t mem_address = reg_ctx->ReadRegisterAsUnsigned( | |||
1123 | reg_ctx->GetRegisterInfoByName("r2", 0), 0); | |||
1124 | ||||
1125 | // We have got the address. Create a memory object out of it | |||
1126 | return_valobj_sp = ValueObjectMemory::Create( | |||
1127 | &thread, "", Address(mem_address, nullptr), return_compiler_type); | |||
1128 | } | |||
1129 | return return_valobj_sp; | |||
1130 | } | |||
1131 | ||||
1132 | bool ABISysV_mips64::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) { | |||
1133 | unwind_plan.Clear(); | |||
1134 | unwind_plan.SetRegisterKind(eRegisterKindDWARF); | |||
1135 | ||||
1136 | UnwindPlan::RowSP row(new UnwindPlan::Row); | |||
1137 | ||||
1138 | // Our Call Frame Address is the stack pointer value | |||
1139 | row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_r29, 0); | |||
1140 | ||||
1141 | // The previous PC is in the RA | |||
1142 | row->SetRegisterLocationToRegister(dwarf_pc, dwarf_r31, true); | |||
1143 | unwind_plan.AppendRow(row); | |||
1144 | ||||
1145 | // All other registers are the same. | |||
1146 | ||||
1147 | unwind_plan.SetSourceName("mips64 at-func-entry default"); | |||
1148 | unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); | |||
1149 | unwind_plan.SetReturnAddressRegister(dwarf_r31); | |||
1150 | return true; | |||
1151 | } | |||
1152 | ||||
1153 | bool ABISysV_mips64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) { | |||
1154 | unwind_plan.Clear(); | |||
1155 | unwind_plan.SetRegisterKind(eRegisterKindDWARF); | |||
1156 | ||||
1157 | UnwindPlan::RowSP row(new UnwindPlan::Row); | |||
1158 | ||||
1159 | row->SetUnspecifiedRegistersAreUndefined(true); | |||
1160 | row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_r29, 0); | |||
1161 | ||||
1162 | row->SetRegisterLocationToRegister(dwarf_pc, dwarf_r31, true); | |||
1163 | ||||
1164 | unwind_plan.AppendRow(row); | |||
1165 | unwind_plan.SetSourceName("mips64 default unwind plan"); | |||
1166 | unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); | |||
1167 | unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo); | |||
1168 | unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo); | |||
1169 | return true; | |||
1170 | } | |||
1171 | ||||
1172 | bool ABISysV_mips64::RegisterIsVolatile(const RegisterInfo *reg_info) { | |||
1173 | return !RegisterIsCalleeSaved(reg_info); | |||
1174 | } | |||
1175 | ||||
1176 | bool ABISysV_mips64::IsSoftFloat(uint32_t fp_flag) const { | |||
1177 | return (fp_flag == lldb_private::ArchSpec::eMIPS_ABI_FP_SOFT); | |||
1178 | } | |||
1179 | ||||
1180 | bool ABISysV_mips64::RegisterIsCalleeSaved(const RegisterInfo *reg_info) { | |||
1181 | if (reg_info) { | |||
1182 | // Preserved registers are : | |||
1183 | // r16-r23, r28, r29, r30, r31 | |||
1184 | ||||
1185 | int reg = ((reg_info->byte_offset) / 8); | |||
1186 | ||||
1187 | bool save = (reg >= 16) && (reg <= 23); | |||
1188 | save |= (reg >= 28) && (reg <= 31); | |||
1189 | ||||
1190 | return save; | |||
1191 | } | |||
1192 | return false; | |||
1193 | } | |||
1194 | ||||
1195 | void ABISysV_mips64::Initialize() { | |||
1196 | PluginManager::RegisterPlugin( | |||
1197 | GetPluginNameStatic(), "System V ABI for mips64 targets", CreateInstance); | |||
1198 | } | |||
1199 | ||||
1200 | void ABISysV_mips64::Terminate() { | |||
1201 | PluginManager::UnregisterPlugin(CreateInstance); | |||
1202 | } | |||
1203 | ||||
1204 | lldb_private::ConstString ABISysV_mips64::GetPluginNameStatic() { | |||
1205 | static ConstString g_name("sysv-mips64"); | |||
1206 | return g_name; | |||
1207 | } | |||
1208 | ||||
1209 | // PluginInterface protocol | |||
1210 | ||||
1211 | lldb_private::ConstString ABISysV_mips64::GetPluginName() { | |||
1212 | return GetPluginNameStatic(); | |||
1213 | } | |||
1214 | ||||
1215 | uint32_t ABISysV_mips64::GetPluginVersion() { return 1; } |
1 | // -*- C++ -*- |
2 | //===----------------------------------------------------------------------===// |
3 | // |
4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
5 | // See https://llvm.org/LICENSE.txt for license information. |
6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
7 | // |
8 | //===----------------------------------------------------------------------===// |
9 | |
10 | #ifndef _LIBCPP___MEMORY_SHARED_PTR_H |
11 | #define _LIBCPP___MEMORY_SHARED_PTR_H |
12 | |
13 | #include <__availability> |
14 | #include <__config> |
15 | #include <__functional_base> |
16 | #include <__functional/binary_function.h> |
17 | #include <__functional/operations.h> |
18 | #include <__functional/reference_wrapper.h> |
19 | #include <__memory/addressof.h> |
20 | #include <__memory/allocation_guard.h> |
21 | #include <__memory/allocator_traits.h> |
22 | #include <__memory/allocator.h> |
23 | #include <__memory/compressed_pair.h> |
24 | #include <__memory/pointer_traits.h> |
25 | #include <__memory/unique_ptr.h> |
26 | #include <__utility/forward.h> |
27 | #include <cstddef> |
28 | #include <cstdlib> // abort |
29 | #include <iosfwd> |
30 | #include <stdexcept> |
31 | #include <typeinfo> |
32 | #include <type_traits> |
33 | #include <utility> |
34 | #if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER) |
35 | # include <atomic> |
36 | #endif |
37 | |
38 | #if _LIBCPP_STD_VER14 <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR) |
39 | # include <__memory/auto_ptr.h> |
40 | #endif |
41 | |
42 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
43 | #pragma GCC system_header |
44 | #endif |
45 | |
46 | _LIBCPP_PUSH_MACROSpush_macro("min") push_macro("max") |
47 | #include <__undef_macros> |
48 | |
49 | _LIBCPP_BEGIN_NAMESPACE_STDnamespace std { inline namespace __1 { |
50 | |
51 | template <class _Alloc> |
52 | class __allocator_destructor |
53 | { |
54 | typedef _LIBCPP_NODEBUG_TYPE__attribute__((nodebug)) allocator_traits<_Alloc> __alloc_traits; |
55 | public: |
56 | typedef _LIBCPP_NODEBUG_TYPE__attribute__((nodebug)) typename __alloc_traits::pointer pointer; |
57 | typedef _LIBCPP_NODEBUG_TYPE__attribute__((nodebug)) typename __alloc_traits::size_type size_type; |
58 | private: |
59 | _Alloc& __alloc_; |
60 | size_type __s_; |
61 | public: |
62 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) __allocator_destructor(_Alloc& __a, size_type __s) |
63 | _NOEXCEPTnoexcept |
64 | : __alloc_(__a), __s_(__s) {} |
65 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
66 | void operator()(pointer __p) _NOEXCEPTnoexcept |
67 | {__alloc_traits::deallocate(__alloc_, __p, __s_);} |
68 | }; |
69 | |
70 | // NOTE: Relaxed and acq/rel atomics (for increment and decrement respectively) |
71 | // should be sufficient for thread safety. |
72 | // See https://llvm.org/PR22803 |
73 | #if defined(__clang__1) && __has_builtin(__atomic_add_fetch)1 \ |
74 | && defined(__ATOMIC_RELAXED0) \ |
75 | && defined(__ATOMIC_ACQ_REL4) |
76 | # define _LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT |
77 | #elif defined(_LIBCPP_COMPILER_GCC) |
78 | # define _LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT |
79 | #endif |
80 | |
81 | template <class _ValueType> |
82 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
83 | _ValueType __libcpp_relaxed_load(_ValueType const* __value) { |
84 | #if !defined(_LIBCPP_HAS_NO_THREADS) && \ |
85 | defined(__ATOMIC_RELAXED0) && \ |
86 | (__has_builtin(__atomic_load_n)1 || defined(_LIBCPP_COMPILER_GCC)) |
87 | return __atomic_load_n(__value, __ATOMIC_RELAXED0); |
88 | #else |
89 | return *__value; |
90 | #endif |
91 | } |
92 | |
93 | template <class _ValueType> |
94 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
95 | _ValueType __libcpp_acquire_load(_ValueType const* __value) { |
96 | #if !defined(_LIBCPP_HAS_NO_THREADS) && \ |
97 | defined(__ATOMIC_ACQUIRE2) && \ |
98 | (__has_builtin(__atomic_load_n)1 || defined(_LIBCPP_COMPILER_GCC)) |
99 | return __atomic_load_n(__value, __ATOMIC_ACQUIRE2); |
100 | #else |
101 | return *__value; |
102 | #endif |
103 | } |
104 | |
105 | template <class _Tp> |
106 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) _Tp |
107 | __libcpp_atomic_refcount_increment(_Tp& __t) _NOEXCEPTnoexcept |
108 | { |
109 | #if defined(_LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT) && !defined(_LIBCPP_HAS_NO_THREADS) |
110 | return __atomic_add_fetch(&__t, 1, __ATOMIC_RELAXED0); |
111 | #else |
112 | return __t += 1; |
113 | #endif |
114 | } |
115 | |
116 | template <class _Tp> |
117 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) _Tp |
118 | __libcpp_atomic_refcount_decrement(_Tp& __t) _NOEXCEPTnoexcept |
119 | { |
120 | #if defined(_LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT) && !defined(_LIBCPP_HAS_NO_THREADS) |
121 | return __atomic_add_fetch(&__t, -1, __ATOMIC_ACQ_REL4); |
122 | #else |
123 | return __t -= 1; |
124 | #endif |
125 | } |
126 | |
127 | class _LIBCPP_EXCEPTION_ABI__attribute__ ((__visibility__("default"))) bad_weak_ptr |
128 | : public std::exception |
129 | { |
130 | public: |
131 | bad_weak_ptr() _NOEXCEPTnoexcept = default; |
132 | bad_weak_ptr(const bad_weak_ptr&) _NOEXCEPTnoexcept = default; |
133 | virtual ~bad_weak_ptr() _NOEXCEPTnoexcept; |
134 | virtual const char* what() const _NOEXCEPTnoexcept; |
135 | }; |
136 | |
137 | _LIBCPP_NORETURN[[noreturn]] inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
138 | void __throw_bad_weak_ptr() |
139 | { |
140 | #ifndef _LIBCPP_NO_EXCEPTIONS |
141 | throw bad_weak_ptr(); |
142 | #else |
143 | _VSTDstd::__1::abort(); |
144 | #endif |
145 | } |
146 | |
147 | template<class _Tp> class _LIBCPP_TEMPLATE_VIS__attribute__ ((__type_visibility__("default"))) weak_ptr; |
148 | |
149 | class _LIBCPP_TYPE_VIS__attribute__ ((__visibility__("default"))) __shared_count |
150 | { |
151 | __shared_count(const __shared_count&); |
152 | __shared_count& operator=(const __shared_count&); |
153 | |
154 | protected: |
155 | long __shared_owners_; |
156 | virtual ~__shared_count(); |
157 | private: |
158 | virtual void __on_zero_shared() _NOEXCEPTnoexcept = 0; |
159 | |
160 | public: |
161 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
162 | explicit __shared_count(long __refs = 0) _NOEXCEPTnoexcept |
163 | : __shared_owners_(__refs) {} |
164 | |
165 | #if defined(_LIBCPP_BUILDING_LIBRARY) && \ |
166 | defined(_LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS) |
167 | void __add_shared() _NOEXCEPTnoexcept; |
168 | bool __release_shared() _NOEXCEPTnoexcept; |
169 | #else |
170 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
171 | void __add_shared() _NOEXCEPTnoexcept { |
172 | __libcpp_atomic_refcount_increment(__shared_owners_); |
173 | } |
174 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
175 | bool __release_shared() _NOEXCEPTnoexcept { |
176 | if (__libcpp_atomic_refcount_decrement(__shared_owners_) == -1) { |
177 | __on_zero_shared(); |
178 | return true; |
179 | } |
180 | return false; |
181 | } |
182 | #endif |
183 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
184 | long use_count() const _NOEXCEPTnoexcept { |
185 | return __libcpp_relaxed_load(&__shared_owners_) + 1; |
186 | } |
187 | }; |
188 | |
189 | class _LIBCPP_TYPE_VIS__attribute__ ((__visibility__("default"))) __shared_weak_count |
190 | : private __shared_count |
191 | { |
192 | long __shared_weak_owners_; |
193 | |
194 | public: |
195 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
196 | explicit __shared_weak_count(long __refs = 0) _NOEXCEPTnoexcept |
197 | : __shared_count(__refs), |
198 | __shared_weak_owners_(__refs) {} |
199 | protected: |
200 | virtual ~__shared_weak_count(); |
201 | |
202 | public: |
203 | #if defined(_LIBCPP_BUILDING_LIBRARY) && \ |
204 | defined(_LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS) |
205 | void __add_shared() _NOEXCEPTnoexcept; |
206 | void __add_weak() _NOEXCEPTnoexcept; |
207 | void __release_shared() _NOEXCEPTnoexcept; |
208 | #else |
209 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
210 | void __add_shared() _NOEXCEPTnoexcept { |
211 | __shared_count::__add_shared(); |
212 | } |
213 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
214 | void __add_weak() _NOEXCEPTnoexcept { |
215 | __libcpp_atomic_refcount_increment(__shared_weak_owners_); |
216 | } |
217 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
218 | void __release_shared() _NOEXCEPTnoexcept { |
219 | if (__shared_count::__release_shared()) |
220 | __release_weak(); |
221 | } |
222 | #endif |
223 | void __release_weak() _NOEXCEPTnoexcept; |
224 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
225 | long use_count() const _NOEXCEPTnoexcept {return __shared_count::use_count();} |
226 | __shared_weak_count* lock() _NOEXCEPTnoexcept; |
227 | |
228 | virtual const void* __get_deleter(const type_info&) const _NOEXCEPTnoexcept; |
229 | private: |
230 | virtual void __on_zero_shared_weak() _NOEXCEPTnoexcept = 0; |
231 | }; |
232 | |
233 | template <class _Tp, class _Dp, class _Alloc> |
234 | class __shared_ptr_pointer |
235 | : public __shared_weak_count |
236 | { |
237 | __compressed_pair<__compressed_pair<_Tp, _Dp>, _Alloc> __data_; |
238 | public: |
239 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
240 | __shared_ptr_pointer(_Tp __p, _Dp __d, _Alloc __a) |
241 | : __data_(__compressed_pair<_Tp, _Dp>(__p, _VSTDstd::__1::move(__d)), _VSTDstd::__1::move(__a)) {} |
242 | |
243 | #ifndef _LIBCPP_NO_RTTI |
244 | virtual const void* __get_deleter(const type_info&) const _NOEXCEPTnoexcept; |
245 | #endif |
246 | |
247 | private: |
248 | virtual void __on_zero_shared() _NOEXCEPTnoexcept; |
249 | virtual void __on_zero_shared_weak() _NOEXCEPTnoexcept; |
250 | }; |
251 | |
252 | #ifndef _LIBCPP_NO_RTTI |
253 | |
254 | template <class _Tp, class _Dp, class _Alloc> |
255 | const void* |
256 | __shared_ptr_pointer<_Tp, _Dp, _Alloc>::__get_deleter(const type_info& __t) const _NOEXCEPTnoexcept |
257 | { |
258 | return __t == typeid(_Dp) ? _VSTDstd::__1::addressof(__data_.first().second()) : nullptr; |
259 | } |
260 | |
261 | #endif // _LIBCPP_NO_RTTI |
262 | |
263 | template <class _Tp, class _Dp, class _Alloc> |
264 | void |
265 | __shared_ptr_pointer<_Tp, _Dp, _Alloc>::__on_zero_shared() _NOEXCEPTnoexcept |
266 | { |
267 | __data_.first().second()(__data_.first().first()); |
268 | __data_.first().second().~_Dp(); |
269 | } |
270 | |
271 | template <class _Tp, class _Dp, class _Alloc> |
272 | void |
273 | __shared_ptr_pointer<_Tp, _Dp, _Alloc>::__on_zero_shared_weak() _NOEXCEPTnoexcept |
274 | { |
275 | typedef typename __allocator_traits_rebind<_Alloc, __shared_ptr_pointer>::type _Al; |
276 | typedef allocator_traits<_Al> _ATraits; |
277 | typedef pointer_traits<typename _ATraits::pointer> _PTraits; |
278 | |
279 | _Al __a(__data_.second()); |
280 | __data_.second().~_Alloc(); |
281 | __a.deallocate(_PTraits::pointer_to(*this), 1); |
282 | } |
283 | |
284 | template <class _Tp, class _Alloc> |
285 | struct __shared_ptr_emplace |
286 | : __shared_weak_count |
287 | { |
288 | template<class ..._Args> |
289 | _LIBCPP_HIDE_FROM_ABI__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
290 | explicit __shared_ptr_emplace(_Alloc __a, _Args&& ...__args) |
291 | : __storage_(_VSTDstd::__1::move(__a)) |
292 | { |
293 | #if _LIBCPP_STD_VER14 > 17 |
294 | using _TpAlloc = typename __allocator_traits_rebind<_Alloc, _Tp>::type; |
295 | _TpAlloc __tmp(*__get_alloc()); |
296 | allocator_traits<_TpAlloc>::construct(__tmp, __get_elem(), _VSTDstd::__1::forward<_Args>(__args)...); |
297 | #else |
298 | ::new ((void*)__get_elem()) _Tp(_VSTDstd::__1::forward<_Args>(__args)...); |
299 | #endif |
300 | } |
301 | |
302 | _LIBCPP_HIDE_FROM_ABI__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
303 | _Alloc* __get_alloc() _NOEXCEPTnoexcept { return __storage_.__get_alloc(); } |
304 | |
305 | _LIBCPP_HIDE_FROM_ABI__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
306 | _Tp* __get_elem() _NOEXCEPTnoexcept { return __storage_.__get_elem(); } |
307 | |
308 | private: |
309 | virtual void __on_zero_shared() _NOEXCEPTnoexcept { |
310 | #if _LIBCPP_STD_VER14 > 17 |
311 | using _TpAlloc = typename __allocator_traits_rebind<_Alloc, _Tp>::type; |
312 | _TpAlloc __tmp(*__get_alloc()); |
313 | allocator_traits<_TpAlloc>::destroy(__tmp, __get_elem()); |
314 | #else |
315 | __get_elem()->~_Tp(); |
316 | #endif |
317 | } |
318 | |
319 | virtual void __on_zero_shared_weak() _NOEXCEPTnoexcept { |
320 | using _ControlBlockAlloc = typename __allocator_traits_rebind<_Alloc, __shared_ptr_emplace>::type; |
321 | using _ControlBlockPointer = typename allocator_traits<_ControlBlockAlloc>::pointer; |
322 | _ControlBlockAlloc __tmp(*__get_alloc()); |
323 | __storage_.~_Storage(); |
324 | allocator_traits<_ControlBlockAlloc>::deallocate(__tmp, |
325 | pointer_traits<_ControlBlockPointer>::pointer_to(*this), 1); |
326 | } |
327 | |
328 | // This class implements the control block for non-array shared pointers created |
329 | // through `std::allocate_shared` and `std::make_shared`. |
330 | // |
331 | // In previous versions of the library, we used a compressed pair to store |
332 | // both the _Alloc and the _Tp. This implies using EBO, which is incompatible |
333 | // with Allocator construction for _Tp. To allow implementing P0674 in C++20, |
334 | // we now use a properly aligned char buffer while making sure that we maintain |
335 | // the same layout that we had when we used a compressed pair. |
336 | using _CompressedPair = __compressed_pair<_Alloc, _Tp>; |
337 | struct _ALIGNAS_TYPE(_CompressedPair)alignas(_CompressedPair) _Storage { |
338 | char __blob_[sizeof(_CompressedPair)]; |
339 | |
340 | _LIBCPP_HIDE_FROM_ABI__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) explicit _Storage(_Alloc&& __a) { |
341 | ::new ((void*)__get_alloc()) _Alloc(_VSTDstd::__1::move(__a)); |
342 | } |
343 | _LIBCPP_HIDE_FROM_ABI__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) ~_Storage() { |
344 | __get_alloc()->~_Alloc(); |
345 | } |
346 | _Alloc* __get_alloc() _NOEXCEPTnoexcept { |
347 | _CompressedPair *__as_pair = reinterpret_cast<_CompressedPair*>(__blob_); |
348 | typename _CompressedPair::_Base1* __first = _CompressedPair::__get_first_base(__as_pair); |
349 | _Alloc *__alloc = reinterpret_cast<_Alloc*>(__first); |
350 | return __alloc; |
351 | } |
352 | _LIBCPP_NO_CFI__attribute__((__no_sanitize__("cfi"))) _Tp* __get_elem() _NOEXCEPTnoexcept { |
353 | _CompressedPair *__as_pair = reinterpret_cast<_CompressedPair*>(__blob_); |
354 | typename _CompressedPair::_Base2* __second = _CompressedPair::__get_second_base(__as_pair); |
355 | _Tp *__elem = reinterpret_cast<_Tp*>(__second); |
356 | return __elem; |
357 | } |
358 | }; |
359 | |
360 | static_assert(_LIBCPP_ALIGNOF(_Storage)alignof(_Storage) == _LIBCPP_ALIGNOF(_CompressedPair)alignof(_CompressedPair), ""); |
361 | static_assert(sizeof(_Storage) == sizeof(_CompressedPair), ""); |
362 | _Storage __storage_; |
363 | }; |
364 | |
365 | struct __shared_ptr_dummy_rebind_allocator_type; |
366 | template <> |
367 | class _LIBCPP_TEMPLATE_VIS__attribute__ ((__type_visibility__("default"))) allocator<__shared_ptr_dummy_rebind_allocator_type> |
368 | { |
369 | public: |
370 | template <class _Other> |
371 | struct rebind |
372 | { |
373 | typedef allocator<_Other> other; |
374 | }; |
375 | }; |
376 | |
377 | template<class _Tp> class _LIBCPP_TEMPLATE_VIS__attribute__ ((__type_visibility__("default"))) enable_shared_from_this; |
378 | |
379 | template<class _Tp, class _Up> |
380 | struct __compatible_with |
381 | #if _LIBCPP_STD_VER14 > 14 |
382 | : is_convertible<remove_extent_t<_Tp>*, remove_extent_t<_Up>*> {}; |
383 | #else |
384 | : is_convertible<_Tp*, _Up*> {}; |
385 | #endif // _LIBCPP_STD_VER > 14 |
386 | |
387 | template <class _Ptr, class = void> |
388 | struct __is_deletable : false_type { }; |
389 | template <class _Ptr> |
390 | struct __is_deletable<_Ptr, decltype(delete declval<_Ptr>())> : true_type { }; |
391 | |
392 | template <class _Ptr, class = void> |
393 | struct __is_array_deletable : false_type { }; |
394 | template <class _Ptr> |
395 | struct __is_array_deletable<_Ptr, decltype(delete[] declval<_Ptr>())> : true_type { }; |
396 | |
397 | template <class _Dp, class _Pt, |
398 | class = decltype(declval<_Dp>()(declval<_Pt>()))> |
399 | static true_type __well_formed_deleter_test(int); |
400 | |
401 | template <class, class> |
402 | static false_type __well_formed_deleter_test(...); |
403 | |
404 | template <class _Dp, class _Pt> |
405 | struct __well_formed_deleter : decltype(__well_formed_deleter_test<_Dp, _Pt>(0)) {}; |
406 | |
407 | template<class _Dp, class _Tp, class _Yp> |
408 | struct __shared_ptr_deleter_ctor_reqs |
409 | { |
410 | static const bool value = __compatible_with<_Tp, _Yp>::value && |
411 | is_move_constructible<_Dp>::value && |
412 | __well_formed_deleter<_Dp, _Tp*>::value; |
413 | }; |
414 | |
415 | #if defined(_LIBCPP_ABI_ENABLE_SHARED_PTR_TRIVIAL_ABI) |
416 | # define _LIBCPP_SHARED_PTR_TRIVIAL_ABI __attribute__((trivial_abi)) |
417 | #else |
418 | # define _LIBCPP_SHARED_PTR_TRIVIAL_ABI |
419 | #endif |
420 | |
421 | template<class _Tp> |
422 | class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS__attribute__ ((__type_visibility__("default"))) shared_ptr |
423 | { |
424 | public: |
425 | #if _LIBCPP_STD_VER14 > 14 |
426 | typedef weak_ptr<_Tp> weak_type; |
427 | typedef remove_extent_t<_Tp> element_type; |
428 | #else |
429 | typedef _Tp element_type; |
430 | #endif |
431 | |
432 | private: |
433 | element_type* __ptr_; |
434 | __shared_weak_count* __cntrl_; |
435 | |
436 | struct __nat {int __for_bool_;}; |
437 | public: |
438 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
439 | _LIBCPP_CONSTEXPRconstexpr shared_ptr() _NOEXCEPTnoexcept; |
440 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
441 | _LIBCPP_CONSTEXPRconstexpr shared_ptr(nullptr_t) _NOEXCEPTnoexcept; |
442 | |
443 | template<class _Yp, class = _EnableIf< |
444 | _And< |
445 | __compatible_with<_Yp, _Tp> |
446 | // In C++03 we get errors when trying to do SFINAE with the |
447 | // delete operator, so we always pretend that it's deletable. |
448 | // The same happens on GCC. |
449 | #if !defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_COMPILER_GCC) |
450 | , _If<is_array<_Tp>::value, __is_array_deletable<_Yp*>, __is_deletable<_Yp*> > |
451 | #endif |
452 | >::value |
453 | > > |
454 | explicit shared_ptr(_Yp* __p) : __ptr_(__p) { |
455 | unique_ptr<_Yp> __hold(__p); |
456 | typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT; |
457 | typedef __shared_ptr_pointer<_Yp*, __shared_ptr_default_delete<_Tp, _Yp>, _AllocT > _CntrlBlk; |
458 | __cntrl_ = new _CntrlBlk(__p, __shared_ptr_default_delete<_Tp, _Yp>(), _AllocT()); |
459 | __hold.release(); |
460 | __enable_weak_this(__p, __p); |
461 | } |
462 | |
463 | template<class _Yp, class _Dp> |
464 | shared_ptr(_Yp* __p, _Dp __d, |
465 | typename enable_if<__shared_ptr_deleter_ctor_reqs<_Dp, _Yp, element_type>::value, __nat>::type = __nat()); |
466 | template<class _Yp, class _Dp, class _Alloc> |
467 | shared_ptr(_Yp* __p, _Dp __d, _Alloc __a, |
468 | typename enable_if<__shared_ptr_deleter_ctor_reqs<_Dp, _Yp, element_type>::value, __nat>::type = __nat()); |
469 | template <class _Dp> shared_ptr(nullptr_t __p, _Dp __d); |
470 | template <class _Dp, class _Alloc> shared_ptr(nullptr_t __p, _Dp __d, _Alloc __a); |
471 | template<class _Yp> _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) shared_ptr(const shared_ptr<_Yp>& __r, element_type* __p) _NOEXCEPTnoexcept; |
472 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
473 | shared_ptr(const shared_ptr& __r) _NOEXCEPTnoexcept; |
474 | template<class _Yp> |
475 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
476 | shared_ptr(const shared_ptr<_Yp>& __r, |
477 | typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type = __nat()) |
478 | _NOEXCEPTnoexcept; |
479 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
480 | shared_ptr(shared_ptr&& __r) _NOEXCEPTnoexcept; |
481 | template<class _Yp> _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) shared_ptr(shared_ptr<_Yp>&& __r, |
482 | typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type = __nat()) |
483 | _NOEXCEPTnoexcept; |
484 | template<class _Yp> explicit shared_ptr(const weak_ptr<_Yp>& __r, |
485 | typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type= __nat()); |
486 | #if _LIBCPP_STD_VER14 <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR) |
487 | template<class _Yp> |
488 | shared_ptr(auto_ptr<_Yp>&& __r, |
489 | typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type = __nat()); |
490 | #endif |
491 | template <class _Yp, class _Dp> |
492 | shared_ptr(unique_ptr<_Yp, _Dp>&&, |
493 | typename enable_if |
494 | < |
495 | !is_lvalue_reference<_Dp>::value && |
496 | is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value, |
497 | __nat |
498 | >::type = __nat()); |
499 | template <class _Yp, class _Dp> |
500 | shared_ptr(unique_ptr<_Yp, _Dp>&&, |
501 | typename enable_if |
502 | < |
503 | is_lvalue_reference<_Dp>::value && |
504 | is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value, |
505 | __nat |
506 | >::type = __nat()); |
507 | |
508 | ~shared_ptr(); |
509 | |
510 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
511 | shared_ptr& operator=(const shared_ptr& __r) _NOEXCEPTnoexcept; |
512 | template<class _Yp> |
513 | typename enable_if |
514 | < |
515 | __compatible_with<_Yp, element_type>::value, |
516 | shared_ptr& |
517 | >::type |
518 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
519 | operator=(const shared_ptr<_Yp>& __r) _NOEXCEPTnoexcept; |
520 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
521 | shared_ptr& operator=(shared_ptr&& __r) _NOEXCEPTnoexcept; |
522 | template<class _Yp> |
523 | typename enable_if |
524 | < |
525 | __compatible_with<_Yp, element_type>::value, |
526 | shared_ptr& |
527 | >::type |
528 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
529 | operator=(shared_ptr<_Yp>&& __r); |
530 | #if _LIBCPP_STD_VER14 <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR) |
531 | template<class _Yp> |
532 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
533 | typename enable_if |
534 | < |
535 | !is_array<_Yp>::value && |
536 | is_convertible<_Yp*, element_type*>::value, |
537 | shared_ptr |
538 | >::type& |
539 | operator=(auto_ptr<_Yp>&& __r); |
540 | #endif |
541 | template <class _Yp, class _Dp> |
542 | typename enable_if |
543 | < |
544 | is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value, |
545 | shared_ptr& |
546 | >::type |
547 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
548 | operator=(unique_ptr<_Yp, _Dp>&& __r); |
549 | |
550 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
551 | void swap(shared_ptr& __r) _NOEXCEPTnoexcept; |
552 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
553 | void reset() _NOEXCEPTnoexcept; |
554 | template<class _Yp> |
555 | typename enable_if |
556 | < |
557 | __compatible_with<_Yp, element_type>::value, |
558 | void |
559 | >::type |
560 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
561 | reset(_Yp* __p); |
562 | template<class _Yp, class _Dp> |
563 | typename enable_if |
564 | < |
565 | __compatible_with<_Yp, element_type>::value, |
566 | void |
567 | >::type |
568 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
569 | reset(_Yp* __p, _Dp __d); |
570 | template<class _Yp, class _Dp, class _Alloc> |
571 | typename enable_if |
572 | < |
573 | __compatible_with<_Yp, element_type>::value, |
574 | void |
575 | >::type |
576 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
577 | reset(_Yp* __p, _Dp __d, _Alloc __a); |
578 | |
579 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
580 | element_type* get() const _NOEXCEPTnoexcept {return __ptr_;} |
581 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
582 | typename add_lvalue_reference<element_type>::type operator*() const _NOEXCEPTnoexcept |
583 | {return *__ptr_;} |
584 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
585 | element_type* operator->() const _NOEXCEPTnoexcept |
586 | { |
587 | static_assert(!is_array<_Tp>::value, |
588 | "std::shared_ptr<T>::operator-> is only valid when T is not an array type."); |
589 | return __ptr_; |
590 | } |
591 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
592 | long use_count() const _NOEXCEPTnoexcept {return __cntrl_ ? __cntrl_->use_count() : 0;} |
593 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
594 | bool unique() const _NOEXCEPTnoexcept {return use_count() == 1;} |
595 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
596 | explicit operator bool() const _NOEXCEPTnoexcept {return get() != nullptr;} |
597 | template <class _Up> |
598 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
599 | bool owner_before(shared_ptr<_Up> const& __p) const _NOEXCEPTnoexcept |
600 | {return __cntrl_ < __p.__cntrl_;} |
601 | template <class _Up> |
602 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
603 | bool owner_before(weak_ptr<_Up> const& __p) const _NOEXCEPTnoexcept |
604 | {return __cntrl_ < __p.__cntrl_;} |
605 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
606 | bool |
607 | __owner_equivalent(const shared_ptr& __p) const |
608 | {return __cntrl_ == __p.__cntrl_;} |
609 | |
610 | #if _LIBCPP_STD_VER14 > 14 |
611 | typename add_lvalue_reference<element_type>::type |
612 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
613 | operator[](ptrdiff_t __i) const |
614 | { |
615 | static_assert(is_array<_Tp>::value, |
616 | "std::shared_ptr<T>::operator[] is only valid when T is an array type."); |
617 | return __ptr_[__i]; |
618 | } |
619 | #endif |
620 | |
621 | #ifndef _LIBCPP_NO_RTTI |
622 | template <class _Dp> |
623 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
624 | _Dp* __get_deleter() const _NOEXCEPTnoexcept |
625 | {return static_cast<_Dp*>(__cntrl_ |
626 | ? const_cast<void *>(__cntrl_->__get_deleter(typeid(_Dp))) |
627 | : nullptr);} |
628 | #endif // _LIBCPP_NO_RTTI |
629 | |
630 | template<class _Yp, class _CntrlBlk> |
631 | static shared_ptr<_Tp> |
632 | __create_with_control_block(_Yp* __p, _CntrlBlk* __cntrl) _NOEXCEPTnoexcept |
633 | { |
634 | shared_ptr<_Tp> __r; |
635 | __r.__ptr_ = __p; |
636 | __r.__cntrl_ = __cntrl; |
637 | __r.__enable_weak_this(__r.__ptr_, __r.__ptr_); |
638 | return __r; |
639 | } |
640 | |
641 | private: |
642 | template <class _Yp, bool = is_function<_Yp>::value> |
643 | struct __shared_ptr_default_allocator |
644 | { |
645 | typedef allocator<_Yp> type; |
646 | }; |
647 | |
648 | template <class _Yp> |
649 | struct __shared_ptr_default_allocator<_Yp, true> |
650 | { |
651 | typedef allocator<__shared_ptr_dummy_rebind_allocator_type> type; |
652 | }; |
653 | |
654 | template <class _Yp, class _OrigPtr> |
655 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
656 | typename enable_if<is_convertible<_OrigPtr*, |
657 | const enable_shared_from_this<_Yp>* |
658 | >::value, |
659 | void>::type |
660 | __enable_weak_this(const enable_shared_from_this<_Yp>* __e, |
661 | _OrigPtr* __ptr) _NOEXCEPTnoexcept |
662 | { |
663 | typedef typename remove_cv<_Yp>::type _RawYp; |
664 | if (__e && __e->__weak_this_.expired()) |
665 | { |
666 | __e->__weak_this_ = shared_ptr<_RawYp>(*this, |
667 | const_cast<_RawYp*>(static_cast<const _Yp*>(__ptr))); |
668 | } |
669 | } |
670 | |
671 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) void __enable_weak_this(...) _NOEXCEPTnoexcept {} |
672 | |
673 | template <class, class _Yp> |
674 | struct __shared_ptr_default_delete |
675 | : default_delete<_Yp> {}; |
676 | |
677 | template <class _Yp, class _Un, size_t _Sz> |
678 | struct __shared_ptr_default_delete<_Yp[_Sz], _Un> |
679 | : default_delete<_Yp[]> {}; |
680 | |
681 | template <class _Yp, class _Un> |
682 | struct __shared_ptr_default_delete<_Yp[], _Un> |
683 | : default_delete<_Yp[]> {}; |
684 | |
685 | template <class _Up> friend class _LIBCPP_TEMPLATE_VIS__attribute__ ((__type_visibility__("default"))) shared_ptr; |
686 | template <class _Up> friend class _LIBCPP_TEMPLATE_VIS__attribute__ ((__type_visibility__("default"))) weak_ptr; |
687 | }; |
688 | |
689 | #ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES |
690 | template<class _Tp> |
691 | shared_ptr(weak_ptr<_Tp>) -> shared_ptr<_Tp>; |
692 | template<class _Tp, class _Dp> |
693 | shared_ptr(unique_ptr<_Tp, _Dp>) -> shared_ptr<_Tp>; |
694 | #endif |
695 | |
696 | template<class _Tp> |
697 | inline |
698 | _LIBCPP_CONSTEXPRconstexpr |
699 | shared_ptr<_Tp>::shared_ptr() _NOEXCEPTnoexcept |
700 | : __ptr_(nullptr), |
701 | __cntrl_(nullptr) |
702 | { |
703 | } |
704 | |
705 | template<class _Tp> |
706 | inline |
707 | _LIBCPP_CONSTEXPRconstexpr |
708 | shared_ptr<_Tp>::shared_ptr(nullptr_t) _NOEXCEPTnoexcept |
709 | : __ptr_(nullptr), |
710 | __cntrl_(nullptr) |
711 | { |
712 | } |
713 | |
714 | template<class _Tp> |
715 | template<class _Yp, class _Dp> |
716 | shared_ptr<_Tp>::shared_ptr(_Yp* __p, _Dp __d, |
717 | typename enable_if<__shared_ptr_deleter_ctor_reqs<_Dp, _Yp, element_type>::value, __nat>::type) |
718 | : __ptr_(__p) |
719 | { |
720 | #ifndef _LIBCPP_NO_EXCEPTIONS |
721 | try |
722 | { |
723 | #endif // _LIBCPP_NO_EXCEPTIONS |
724 | typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT; |
725 | typedef __shared_ptr_pointer<_Yp*, _Dp, _AllocT > _CntrlBlk; |
726 | #ifndef _LIBCPP_CXX03_LANG |
727 | __cntrl_ = new _CntrlBlk(__p, _VSTDstd::__1::move(__d), _AllocT()); |
728 | #else |
729 | __cntrl_ = new _CntrlBlk(__p, __d, _AllocT()); |
730 | #endif // not _LIBCPP_CXX03_LANG |
731 | __enable_weak_this(__p, __p); |
732 | #ifndef _LIBCPP_NO_EXCEPTIONS |
733 | } |
734 | catch (...) |
735 | { |
736 | __d(__p); |
737 | throw; |
738 | } |
739 | #endif // _LIBCPP_NO_EXCEPTIONS |
740 | } |
741 | |
742 | template<class _Tp> |
743 | template<class _Dp> |
744 | shared_ptr<_Tp>::shared_ptr(nullptr_t __p, _Dp __d) |
745 | : __ptr_(nullptr) |
746 | { |
747 | #ifndef _LIBCPP_NO_EXCEPTIONS |
748 | try |
749 | { |
750 | #endif // _LIBCPP_NO_EXCEPTIONS |
751 | typedef typename __shared_ptr_default_allocator<_Tp>::type _AllocT; |
752 | typedef __shared_ptr_pointer<nullptr_t, _Dp, _AllocT > _CntrlBlk; |
753 | #ifndef _LIBCPP_CXX03_LANG |
754 | __cntrl_ = new _CntrlBlk(__p, _VSTDstd::__1::move(__d), _AllocT()); |
755 | #else |
756 | __cntrl_ = new _CntrlBlk(__p, __d, _AllocT()); |
757 | #endif // not _LIBCPP_CXX03_LANG |
758 | #ifndef _LIBCPP_NO_EXCEPTIONS |
759 | } |
760 | catch (...) |
761 | { |
762 | __d(__p); |
763 | throw; |
764 | } |
765 | #endif // _LIBCPP_NO_EXCEPTIONS |
766 | } |
767 | |
768 | template<class _Tp> |
769 | template<class _Yp, class _Dp, class _Alloc> |
770 | shared_ptr<_Tp>::shared_ptr(_Yp* __p, _Dp __d, _Alloc __a, |
771 | typename enable_if<__shared_ptr_deleter_ctor_reqs<_Dp, _Yp, element_type>::value, __nat>::type) |
772 | : __ptr_(__p) |
773 | { |
774 | #ifndef _LIBCPP_NO_EXCEPTIONS |
775 | try |
776 | { |
777 | #endif // _LIBCPP_NO_EXCEPTIONS |
778 | typedef __shared_ptr_pointer<_Yp*, _Dp, _Alloc> _CntrlBlk; |
779 | typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2; |
780 | typedef __allocator_destructor<_A2> _D2; |
781 | _A2 __a2(__a); |
782 | unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1)); |
783 | ::new ((void*)_VSTDstd::__1::addressof(*__hold2.get())) |
784 | #ifndef _LIBCPP_CXX03_LANG |
785 | _CntrlBlk(__p, _VSTDstd::__1::move(__d), __a); |
786 | #else |
787 | _CntrlBlk(__p, __d, __a); |
788 | #endif // not _LIBCPP_CXX03_LANG |
789 | __cntrl_ = _VSTDstd::__1::addressof(*__hold2.release()); |
790 | __enable_weak_this(__p, __p); |
791 | #ifndef _LIBCPP_NO_EXCEPTIONS |
792 | } |
793 | catch (...) |
794 | { |
795 | __d(__p); |
796 | throw; |
797 | } |
798 | #endif // _LIBCPP_NO_EXCEPTIONS |
799 | } |
800 | |
801 | template<class _Tp> |
802 | template<class _Dp, class _Alloc> |
803 | shared_ptr<_Tp>::shared_ptr(nullptr_t __p, _Dp __d, _Alloc __a) |
804 | : __ptr_(nullptr) |
805 | { |
806 | #ifndef _LIBCPP_NO_EXCEPTIONS |
807 | try |
808 | { |
809 | #endif // _LIBCPP_NO_EXCEPTIONS |
810 | typedef __shared_ptr_pointer<nullptr_t, _Dp, _Alloc> _CntrlBlk; |
811 | typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2; |
812 | typedef __allocator_destructor<_A2> _D2; |
813 | _A2 __a2(__a); |
814 | unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1)); |
815 | ::new ((void*)_VSTDstd::__1::addressof(*__hold2.get())) |
816 | #ifndef _LIBCPP_CXX03_LANG |
817 | _CntrlBlk(__p, _VSTDstd::__1::move(__d), __a); |
818 | #else |
819 | _CntrlBlk(__p, __d, __a); |
820 | #endif // not _LIBCPP_CXX03_LANG |
821 | __cntrl_ = _VSTDstd::__1::addressof(*__hold2.release()); |
822 | #ifndef _LIBCPP_NO_EXCEPTIONS |
823 | } |
824 | catch (...) |
825 | { |
826 | __d(__p); |
827 | throw; |
828 | } |
829 | #endif // _LIBCPP_NO_EXCEPTIONS |
830 | } |
831 | |
832 | template<class _Tp> |
833 | template<class _Yp> |
834 | inline |
835 | shared_ptr<_Tp>::shared_ptr(const shared_ptr<_Yp>& __r, element_type *__p) _NOEXCEPTnoexcept |
836 | : __ptr_(__p), |
837 | __cntrl_(__r.__cntrl_) |
838 | { |
839 | if (__cntrl_) |
840 | __cntrl_->__add_shared(); |
841 | } |
842 | |
843 | template<class _Tp> |
844 | inline |
845 | shared_ptr<_Tp>::shared_ptr(const shared_ptr& __r) _NOEXCEPTnoexcept |
846 | : __ptr_(__r.__ptr_), |
847 | __cntrl_(__r.__cntrl_) |
848 | { |
849 | if (__cntrl_) |
850 | __cntrl_->__add_shared(); |
851 | } |
852 | |
853 | template<class _Tp> |
854 | template<class _Yp> |
855 | inline |
856 | shared_ptr<_Tp>::shared_ptr(const shared_ptr<_Yp>& __r, |
857 | typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type) |
858 | _NOEXCEPTnoexcept |
859 | : __ptr_(__r.__ptr_), |
860 | __cntrl_(__r.__cntrl_) |
861 | { |
862 | if (__cntrl_) |
863 | __cntrl_->__add_shared(); |
864 | } |
865 | |
866 | template<class _Tp> |
867 | inline |
868 | shared_ptr<_Tp>::shared_ptr(shared_ptr&& __r) _NOEXCEPTnoexcept |
869 | : __ptr_(__r.__ptr_), |
870 | __cntrl_(__r.__cntrl_) |
871 | { |
872 | __r.__ptr_ = nullptr; |
873 | __r.__cntrl_ = nullptr; |
874 | } |
875 | |
876 | template<class _Tp> |
877 | template<class _Yp> |
878 | inline |
879 | shared_ptr<_Tp>::shared_ptr(shared_ptr<_Yp>&& __r, |
880 | typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type) |
881 | _NOEXCEPTnoexcept |
882 | : __ptr_(__r.__ptr_), |
883 | __cntrl_(__r.__cntrl_) |
884 | { |
885 | __r.__ptr_ = nullptr; |
886 | __r.__cntrl_ = nullptr; |
887 | } |
888 | |
889 | #if _LIBCPP_STD_VER14 <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR) |
890 | template<class _Tp> |
891 | template<class _Yp> |
892 | shared_ptr<_Tp>::shared_ptr(auto_ptr<_Yp>&& __r, |
893 | typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type) |
894 | : __ptr_(__r.get()) |
895 | { |
896 | typedef __shared_ptr_pointer<_Yp*, default_delete<_Yp>, allocator<_Yp> > _CntrlBlk; |
897 | __cntrl_ = new _CntrlBlk(__r.get(), default_delete<_Yp>(), allocator<_Yp>()); |
898 | __enable_weak_this(__r.get(), __r.get()); |
899 | __r.release(); |
900 | } |
901 | #endif |
902 | |
903 | template<class _Tp> |
904 | template <class _Yp, class _Dp> |
905 | shared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp>&& __r, |
906 | typename enable_if |
907 | < |
908 | !is_lvalue_reference<_Dp>::value && |
909 | is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value, |
910 | __nat |
911 | >::type) |
912 | : __ptr_(__r.get()) |
913 | { |
914 | #if _LIBCPP_STD_VER14 > 11 |
915 | if (__ptr_ == nullptr) |
916 | __cntrl_ = nullptr; |
917 | else |
918 | #endif |
919 | { |
920 | typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT; |
921 | typedef __shared_ptr_pointer<typename unique_ptr<_Yp, _Dp>::pointer, _Dp, _AllocT > _CntrlBlk; |
922 | __cntrl_ = new _CntrlBlk(__r.get(), __r.get_deleter(), _AllocT()); |
923 | __enable_weak_this(__r.get(), __r.get()); |
924 | } |
925 | __r.release(); |
926 | } |
927 | |
928 | template<class _Tp> |
929 | template <class _Yp, class _Dp> |
930 | shared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp>&& __r, |
931 | typename enable_if |
932 | < |
933 | is_lvalue_reference<_Dp>::value && |
934 | is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value, |
935 | __nat |
936 | >::type) |
937 | : __ptr_(__r.get()) |
938 | { |
939 | #if _LIBCPP_STD_VER14 > 11 |
940 | if (__ptr_ == nullptr) |
941 | __cntrl_ = nullptr; |
942 | else |
943 | #endif |
944 | { |
945 | typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT; |
946 | typedef __shared_ptr_pointer<typename unique_ptr<_Yp, _Dp>::pointer, |
947 | reference_wrapper<typename remove_reference<_Dp>::type>, |
948 | _AllocT > _CntrlBlk; |
949 | __cntrl_ = new _CntrlBlk(__r.get(), _VSTDstd::__1::ref(__r.get_deleter()), _AllocT()); |
950 | __enable_weak_this(__r.get(), __r.get()); |
951 | } |
952 | __r.release(); |
953 | } |
954 | |
955 | template<class _Tp> |
956 | shared_ptr<_Tp>::~shared_ptr() |
957 | { |
958 | if (__cntrl_) |
959 | __cntrl_->__release_shared(); |
960 | } |
961 | |
962 | template<class _Tp> |
963 | inline |
964 | shared_ptr<_Tp>& |
965 | shared_ptr<_Tp>::operator=(const shared_ptr& __r) _NOEXCEPTnoexcept |
966 | { |
967 | shared_ptr(__r).swap(*this); |
968 | return *this; |
969 | } |
970 | |
971 | template<class _Tp> |
972 | template<class _Yp> |
973 | inline |
974 | typename enable_if |
975 | < |
976 | __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value, |
977 | shared_ptr<_Tp>& |
978 | >::type |
979 | shared_ptr<_Tp>::operator=(const shared_ptr<_Yp>& __r) _NOEXCEPTnoexcept |
980 | { |
981 | shared_ptr(__r).swap(*this); |
982 | return *this; |
983 | } |
984 | |
985 | template<class _Tp> |
986 | inline |
987 | shared_ptr<_Tp>& |
988 | shared_ptr<_Tp>::operator=(shared_ptr&& __r) _NOEXCEPTnoexcept |
989 | { |
990 | shared_ptr(_VSTDstd::__1::move(__r)).swap(*this); |
991 | return *this; |
992 | } |
993 | |
994 | template<class _Tp> |
995 | template<class _Yp> |
996 | inline |
997 | typename enable_if |
998 | < |
999 | __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value, |
1000 | shared_ptr<_Tp>& |
1001 | >::type |
1002 | shared_ptr<_Tp>::operator=(shared_ptr<_Yp>&& __r) |
1003 | { |
1004 | shared_ptr(_VSTDstd::__1::move(__r)).swap(*this); |
1005 | return *this; |
1006 | } |
1007 | |
1008 | #if _LIBCPP_STD_VER14 <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR) |
1009 | template<class _Tp> |
1010 | template<class _Yp> |
1011 | inline |
1012 | typename enable_if |
1013 | < |
1014 | !is_array<_Yp>::value && |
1015 | is_convertible<_Yp*, typename shared_ptr<_Tp>::element_type*>::value, |
1016 | shared_ptr<_Tp> |
1017 | >::type& |
1018 | shared_ptr<_Tp>::operator=(auto_ptr<_Yp>&& __r) |
1019 | { |
1020 | shared_ptr(_VSTDstd::__1::move(__r)).swap(*this); |
1021 | return *this; |
1022 | } |
1023 | #endif |
1024 | |
1025 | template<class _Tp> |
1026 | template <class _Yp, class _Dp> |
1027 | inline |
1028 | typename enable_if |
1029 | < |
1030 | is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, |
1031 | typename shared_ptr<_Tp>::element_type*>::value, |
1032 | shared_ptr<_Tp>& |
1033 | >::type |
1034 | shared_ptr<_Tp>::operator=(unique_ptr<_Yp, _Dp>&& __r) |
1035 | { |
1036 | shared_ptr(_VSTDstd::__1::move(__r)).swap(*this); |
1037 | return *this; |
1038 | } |
1039 | |
1040 | template<class _Tp> |
1041 | inline |
1042 | void |
1043 | shared_ptr<_Tp>::swap(shared_ptr& __r) _NOEXCEPTnoexcept |
1044 | { |
1045 | _VSTDstd::__1::swap(__ptr_, __r.__ptr_); |
1046 | _VSTDstd::__1::swap(__cntrl_, __r.__cntrl_); |
1047 | } |
1048 | |
1049 | template<class _Tp> |
1050 | inline |
1051 | void |
1052 | shared_ptr<_Tp>::reset() _NOEXCEPTnoexcept |
1053 | { |
1054 | shared_ptr().swap(*this); |
1055 | } |
1056 | |
1057 | template<class _Tp> |
1058 | template<class _Yp> |
1059 | inline |
1060 | typename enable_if |
1061 | < |
1062 | __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value, |
1063 | void |
1064 | >::type |
1065 | shared_ptr<_Tp>::reset(_Yp* __p) |
1066 | { |
1067 | shared_ptr(__p).swap(*this); |
1068 | } |
1069 | |
1070 | template<class _Tp> |
1071 | template<class _Yp, class _Dp> |
1072 | inline |
1073 | typename enable_if |
1074 | < |
1075 | __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value, |
1076 | void |
1077 | >::type |
1078 | shared_ptr<_Tp>::reset(_Yp* __p, _Dp __d) |
1079 | { |
1080 | shared_ptr(__p, __d).swap(*this); |
1081 | } |
1082 | |
1083 | template<class _Tp> |
1084 | template<class _Yp, class _Dp, class _Alloc> |
1085 | inline |
1086 | typename enable_if |
1087 | < |
1088 | __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value, |
1089 | void |
1090 | >::type |
1091 | shared_ptr<_Tp>::reset(_Yp* __p, _Dp __d, _Alloc __a) |
1092 | { |
1093 | shared_ptr(__p, __d, __a).swap(*this); |
1094 | } |
1095 | |
1096 | // |
1097 | // std::allocate_shared and std::make_shared |
1098 | // |
1099 | template<class _Tp, class _Alloc, class ..._Args, class = _EnableIf<!is_array<_Tp>::value> > |
1100 | _LIBCPP_HIDE_FROM_ABI__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1101 | shared_ptr<_Tp> allocate_shared(const _Alloc& __a, _Args&& ...__args) |
1102 | { |
1103 | using _ControlBlock = __shared_ptr_emplace<_Tp, _Alloc>; |
1104 | using _ControlBlockAllocator = typename __allocator_traits_rebind<_Alloc, _ControlBlock>::type; |
1105 | __allocation_guard<_ControlBlockAllocator> __guard(__a, 1); |
1106 | ::new ((void*)_VSTDstd::__1::addressof(*__guard.__get())) _ControlBlock(__a, _VSTDstd::__1::forward<_Args>(__args)...); |
1107 | auto __control_block = __guard.__release_ptr(); |
1108 | return shared_ptr<_Tp>::__create_with_control_block((*__control_block).__get_elem(), _VSTDstd::__1::addressof(*__control_block)); |
1109 | } |
1110 | |
1111 | template<class _Tp, class ..._Args, class = _EnableIf<!is_array<_Tp>::value> > |
1112 | _LIBCPP_HIDE_FROM_ABI__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1113 | shared_ptr<_Tp> make_shared(_Args&& ...__args) |
1114 | { |
1115 | return _VSTDstd::__1::allocate_shared<_Tp>(allocator<_Tp>(), _VSTDstd::__1::forward<_Args>(__args)...); |
1116 | } |
1117 | |
1118 | template<class _Tp, class _Up> |
1119 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1120 | bool |
1121 | operator==(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPTnoexcept |
1122 | { |
1123 | return __x.get() == __y.get(); |
1124 | } |
1125 | |
1126 | template<class _Tp, class _Up> |
1127 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1128 | bool |
1129 | operator!=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPTnoexcept |
1130 | { |
1131 | return !(__x == __y); |
1132 | } |
1133 | |
1134 | template<class _Tp, class _Up> |
1135 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1136 | bool |
1137 | operator<(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPTnoexcept |
1138 | { |
1139 | #if _LIBCPP_STD_VER14 <= 11 |
1140 | typedef typename common_type<_Tp*, _Up*>::type _Vp; |
1141 | return less<_Vp>()(__x.get(), __y.get()); |
1142 | #else |
1143 | return less<>()(__x.get(), __y.get()); |
1144 | #endif |
1145 | |
1146 | } |
1147 | |
1148 | template<class _Tp, class _Up> |
1149 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1150 | bool |
1151 | operator>(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPTnoexcept |
1152 | { |
1153 | return __y < __x; |
1154 | } |
1155 | |
1156 | template<class _Tp, class _Up> |
1157 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1158 | bool |
1159 | operator<=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPTnoexcept |
1160 | { |
1161 | return !(__y < __x); |
1162 | } |
1163 | |
1164 | template<class _Tp, class _Up> |
1165 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1166 | bool |
1167 | operator>=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPTnoexcept |
1168 | { |
1169 | return !(__x < __y); |
1170 | } |
1171 | |
1172 | template<class _Tp> |
1173 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1174 | bool |
1175 | operator==(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPTnoexcept |
1176 | { |
1177 | return !__x; |
1178 | } |
1179 | |
1180 | template<class _Tp> |
1181 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1182 | bool |
1183 | operator==(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPTnoexcept |
1184 | { |
1185 | return !__x; |
1186 | } |
1187 | |
1188 | template<class _Tp> |
1189 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1190 | bool |
1191 | operator!=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPTnoexcept |
1192 | { |
1193 | return static_cast<bool>(__x); |
1194 | } |
1195 | |
1196 | template<class _Tp> |
1197 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1198 | bool |
1199 | operator!=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPTnoexcept |
1200 | { |
1201 | return static_cast<bool>(__x); |
1202 | } |
1203 | |
1204 | template<class _Tp> |
1205 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1206 | bool |
1207 | operator<(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPTnoexcept |
1208 | { |
1209 | return less<_Tp*>()(__x.get(), nullptr); |
1210 | } |
1211 | |
1212 | template<class _Tp> |
1213 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1214 | bool |
1215 | operator<(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPTnoexcept |
1216 | { |
1217 | return less<_Tp*>()(nullptr, __x.get()); |
1218 | } |
1219 | |
1220 | template<class _Tp> |
1221 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1222 | bool |
1223 | operator>(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPTnoexcept |
1224 | { |
1225 | return nullptr < __x; |
1226 | } |
1227 | |
1228 | template<class _Tp> |
1229 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1230 | bool |
1231 | operator>(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPTnoexcept |
1232 | { |
1233 | return __x < nullptr; |
1234 | } |
1235 | |
1236 | template<class _Tp> |
1237 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1238 | bool |
1239 | operator<=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPTnoexcept |
1240 | { |
1241 | return !(nullptr < __x); |
1242 | } |
1243 | |
1244 | template<class _Tp> |
1245 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1246 | bool |
1247 | operator<=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPTnoexcept |
1248 | { |
1249 | return !(__x < nullptr); |
1250 | } |
1251 | |
1252 | template<class _Tp> |
1253 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1254 | bool |
1255 | operator>=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPTnoexcept |
1256 | { |
1257 | return !(__x < nullptr); |
1258 | } |
1259 | |
1260 | template<class _Tp> |
1261 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1262 | bool |
1263 | operator>=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPTnoexcept |
1264 | { |
1265 | return !(nullptr < __x); |
1266 | } |
1267 | |
1268 | template<class _Tp> |
1269 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1270 | void |
1271 | swap(shared_ptr<_Tp>& __x, shared_ptr<_Tp>& __y) _NOEXCEPTnoexcept |
1272 | { |
1273 | __x.swap(__y); |
1274 | } |
1275 | |
1276 | template<class _Tp, class _Up> |
1277 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1278 | shared_ptr<_Tp> |
1279 | static_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPTnoexcept |
1280 | { |
1281 | return shared_ptr<_Tp>(__r, |
1282 | static_cast< |
1283 | typename shared_ptr<_Tp>::element_type*>(__r.get())); |
1284 | } |
1285 | |
1286 | template<class _Tp, class _Up> |
1287 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1288 | shared_ptr<_Tp> |
1289 | dynamic_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPTnoexcept |
1290 | { |
1291 | typedef typename shared_ptr<_Tp>::element_type _ET; |
1292 | _ET* __p = dynamic_cast<_ET*>(__r.get()); |
1293 | return __p ? shared_ptr<_Tp>(__r, __p) : shared_ptr<_Tp>(); |
1294 | } |
1295 | |
1296 | template<class _Tp, class _Up> |
1297 | shared_ptr<_Tp> |
1298 | const_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPTnoexcept |
1299 | { |
1300 | typedef typename shared_ptr<_Tp>::element_type _RTp; |
1301 | return shared_ptr<_Tp>(__r, const_cast<_RTp*>(__r.get())); |
1302 | } |
1303 | |
1304 | template<class _Tp, class _Up> |
1305 | shared_ptr<_Tp> |
1306 | reinterpret_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPTnoexcept |
1307 | { |
1308 | return shared_ptr<_Tp>(__r, |
1309 | reinterpret_cast< |
1310 | typename shared_ptr<_Tp>::element_type*>(__r.get())); |
1311 | } |
1312 | |
1313 | #ifndef _LIBCPP_NO_RTTI |
1314 | |
1315 | template<class _Dp, class _Tp> |
1316 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1317 | _Dp* |
1318 | get_deleter(const shared_ptr<_Tp>& __p) _NOEXCEPTnoexcept |
1319 | { |
1320 | return __p.template __get_deleter<_Dp>(); |
1321 | } |
1322 | |
1323 | #endif // _LIBCPP_NO_RTTI |
1324 | |
1325 | template<class _Tp> |
1326 | class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS__attribute__ ((__type_visibility__("default"))) weak_ptr |
1327 | { |
1328 | public: |
1329 | typedef _Tp element_type; |
1330 | private: |
1331 | element_type* __ptr_; |
1332 | __shared_weak_count* __cntrl_; |
1333 | |
1334 | public: |
1335 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1336 | _LIBCPP_CONSTEXPRconstexpr weak_ptr() _NOEXCEPTnoexcept; |
1337 | template<class _Yp> _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) weak_ptr(shared_ptr<_Yp> const& __r, |
1338 | typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type = 0) |
1339 | _NOEXCEPTnoexcept; |
1340 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1341 | weak_ptr(weak_ptr const& __r) _NOEXCEPTnoexcept; |
1342 | template<class _Yp> _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) weak_ptr(weak_ptr<_Yp> const& __r, |
1343 | typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type = 0) |
1344 | _NOEXCEPTnoexcept; |
1345 | |
1346 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1347 | weak_ptr(weak_ptr&& __r) _NOEXCEPTnoexcept; |
1348 | template<class _Yp> _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) weak_ptr(weak_ptr<_Yp>&& __r, |
1349 | typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type = 0) |
1350 | _NOEXCEPTnoexcept; |
1351 | ~weak_ptr(); |
1352 | |
1353 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1354 | weak_ptr& operator=(weak_ptr const& __r) _NOEXCEPTnoexcept; |
1355 | template<class _Yp> |
1356 | typename enable_if |
1357 | < |
1358 | is_convertible<_Yp*, element_type*>::value, |
1359 | weak_ptr& |
1360 | >::type |
1361 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1362 | operator=(weak_ptr<_Yp> const& __r) _NOEXCEPTnoexcept; |
1363 | |
1364 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1365 | weak_ptr& operator=(weak_ptr&& __r) _NOEXCEPTnoexcept; |
1366 | template<class _Yp> |
1367 | typename enable_if |
1368 | < |
1369 | is_convertible<_Yp*, element_type*>::value, |
1370 | weak_ptr& |
1371 | >::type |
1372 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1373 | operator=(weak_ptr<_Yp>&& __r) _NOEXCEPTnoexcept; |
1374 | |
1375 | template<class _Yp> |
1376 | typename enable_if |
1377 | < |
1378 | is_convertible<_Yp*, element_type*>::value, |
1379 | weak_ptr& |
1380 | >::type |
1381 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1382 | operator=(shared_ptr<_Yp> const& __r) _NOEXCEPTnoexcept; |
1383 | |
1384 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1385 | void swap(weak_ptr& __r) _NOEXCEPTnoexcept; |
1386 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1387 | void reset() _NOEXCEPTnoexcept; |
1388 | |
1389 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1390 | long use_count() const _NOEXCEPTnoexcept |
1391 | {return __cntrl_ ? __cntrl_->use_count() : 0;} |
1392 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1393 | bool expired() const _NOEXCEPTnoexcept |
1394 | {return __cntrl_ == nullptr || __cntrl_->use_count() == 0;} |
1395 | shared_ptr<_Tp> lock() const _NOEXCEPTnoexcept; |
1396 | template<class _Up> |
1397 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1398 | bool owner_before(const shared_ptr<_Up>& __r) const _NOEXCEPTnoexcept |
1399 | {return __cntrl_ < __r.__cntrl_;} |
1400 | template<class _Up> |
1401 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1402 | bool owner_before(const weak_ptr<_Up>& __r) const _NOEXCEPTnoexcept |
1403 | {return __cntrl_ < __r.__cntrl_;} |
1404 | |
1405 | template <class _Up> friend class _LIBCPP_TEMPLATE_VIS__attribute__ ((__type_visibility__("default"))) weak_ptr; |
1406 | template <class _Up> friend class _LIBCPP_TEMPLATE_VIS__attribute__ ((__type_visibility__("default"))) shared_ptr; |
1407 | }; |
1408 | |
1409 | #ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES |
1410 | template<class _Tp> |
1411 | weak_ptr(shared_ptr<_Tp>) -> weak_ptr<_Tp>; |
1412 | #endif |
1413 | |
1414 | template<class _Tp> |
1415 | inline |
1416 | _LIBCPP_CONSTEXPRconstexpr |
1417 | weak_ptr<_Tp>::weak_ptr() _NOEXCEPTnoexcept |
1418 | : __ptr_(nullptr), |
1419 | __cntrl_(nullptr) |
1420 | { |
1421 | } |
1422 | |
1423 | template<class _Tp> |
1424 | inline |
1425 | weak_ptr<_Tp>::weak_ptr(weak_ptr const& __r) _NOEXCEPTnoexcept |
1426 | : __ptr_(__r.__ptr_), |
1427 | __cntrl_(__r.__cntrl_) |
1428 | { |
1429 | if (__cntrl_) |
1430 | __cntrl_->__add_weak(); |
1431 | } |
1432 | |
1433 | template<class _Tp> |
1434 | template<class _Yp> |
1435 | inline |
1436 | weak_ptr<_Tp>::weak_ptr(shared_ptr<_Yp> const& __r, |
1437 | typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type) |
1438 | _NOEXCEPTnoexcept |
1439 | : __ptr_(__r.__ptr_), |
1440 | __cntrl_(__r.__cntrl_) |
1441 | { |
1442 | if (__cntrl_) |
1443 | __cntrl_->__add_weak(); |
1444 | } |
1445 | |
1446 | template<class _Tp> |
1447 | template<class _Yp> |
1448 | inline |
1449 | weak_ptr<_Tp>::weak_ptr(weak_ptr<_Yp> const& __r, |
1450 | typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type) |
1451 | _NOEXCEPTnoexcept |
1452 | : __ptr_(__r.__ptr_), |
1453 | __cntrl_(__r.__cntrl_) |
1454 | { |
1455 | if (__cntrl_) |
1456 | __cntrl_->__add_weak(); |
1457 | } |
1458 | |
1459 | template<class _Tp> |
1460 | inline |
1461 | weak_ptr<_Tp>::weak_ptr(weak_ptr&& __r) _NOEXCEPTnoexcept |
1462 | : __ptr_(__r.__ptr_), |
1463 | __cntrl_(__r.__cntrl_) |
1464 | { |
1465 | __r.__ptr_ = nullptr; |
1466 | __r.__cntrl_ = nullptr; |
1467 | } |
1468 | |
1469 | template<class _Tp> |
1470 | template<class _Yp> |
1471 | inline |
1472 | weak_ptr<_Tp>::weak_ptr(weak_ptr<_Yp>&& __r, |
1473 | typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type) |
1474 | _NOEXCEPTnoexcept |
1475 | : __ptr_(__r.__ptr_), |
1476 | __cntrl_(__r.__cntrl_) |
1477 | { |
1478 | __r.__ptr_ = nullptr; |
1479 | __r.__cntrl_ = nullptr; |
1480 | } |
1481 | |
1482 | template<class _Tp> |
1483 | weak_ptr<_Tp>::~weak_ptr() |
1484 | { |
1485 | if (__cntrl_) |
1486 | __cntrl_->__release_weak(); |
1487 | } |
1488 | |
1489 | template<class _Tp> |
1490 | inline |
1491 | weak_ptr<_Tp>& |
1492 | weak_ptr<_Tp>::operator=(weak_ptr const& __r) _NOEXCEPTnoexcept |
1493 | { |
1494 | weak_ptr(__r).swap(*this); |
1495 | return *this; |
1496 | } |
1497 | |
1498 | template<class _Tp> |
1499 | template<class _Yp> |
1500 | inline |
1501 | typename enable_if |
1502 | < |
1503 | is_convertible<_Yp*, _Tp*>::value, |
1504 | weak_ptr<_Tp>& |
1505 | >::type |
1506 | weak_ptr<_Tp>::operator=(weak_ptr<_Yp> const& __r) _NOEXCEPTnoexcept |
1507 | { |
1508 | weak_ptr(__r).swap(*this); |
1509 | return *this; |
1510 | } |
1511 | |
1512 | template<class _Tp> |
1513 | inline |
1514 | weak_ptr<_Tp>& |
1515 | weak_ptr<_Tp>::operator=(weak_ptr&& __r) _NOEXCEPTnoexcept |
1516 | { |
1517 | weak_ptr(_VSTDstd::__1::move(__r)).swap(*this); |
1518 | return *this; |
1519 | } |
1520 | |
1521 | template<class _Tp> |
1522 | template<class _Yp> |
1523 | inline |
1524 | typename enable_if |
1525 | < |
1526 | is_convertible<_Yp*, _Tp*>::value, |
1527 | weak_ptr<_Tp>& |
1528 | >::type |
1529 | weak_ptr<_Tp>::operator=(weak_ptr<_Yp>&& __r) _NOEXCEPTnoexcept |
1530 | { |
1531 | weak_ptr(_VSTDstd::__1::move(__r)).swap(*this); |
1532 | return *this; |
1533 | } |
1534 | |
1535 | template<class _Tp> |
1536 | template<class _Yp> |
1537 | inline |
1538 | typename enable_if |
1539 | < |
1540 | is_convertible<_Yp*, _Tp*>::value, |
1541 | weak_ptr<_Tp>& |
1542 | >::type |
1543 | weak_ptr<_Tp>::operator=(shared_ptr<_Yp> const& __r) _NOEXCEPTnoexcept |
1544 | { |
1545 | weak_ptr(__r).swap(*this); |
1546 | return *this; |
1547 | } |
1548 | |
1549 | template<class _Tp> |
1550 | inline |
1551 | void |
1552 | weak_ptr<_Tp>::swap(weak_ptr& __r) _NOEXCEPTnoexcept |
1553 | { |
1554 | _VSTDstd::__1::swap(__ptr_, __r.__ptr_); |
1555 | _VSTDstd::__1::swap(__cntrl_, __r.__cntrl_); |
1556 | } |
1557 | |
1558 | template<class _Tp> |
1559 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1560 | void |
1561 | swap(weak_ptr<_Tp>& __x, weak_ptr<_Tp>& __y) _NOEXCEPTnoexcept |
1562 | { |
1563 | __x.swap(__y); |
1564 | } |
1565 | |
1566 | template<class _Tp> |
1567 | inline |
1568 | void |
1569 | weak_ptr<_Tp>::reset() _NOEXCEPTnoexcept |
1570 | { |
1571 | weak_ptr().swap(*this); |
1572 | } |
1573 | |
1574 | template<class _Tp> |
1575 | template<class _Yp> |
1576 | shared_ptr<_Tp>::shared_ptr(const weak_ptr<_Yp>& __r, |
1577 | typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type) |
1578 | : __ptr_(__r.__ptr_), |
1579 | __cntrl_(__r.__cntrl_ ? __r.__cntrl_->lock() : __r.__cntrl_) |
1580 | { |
1581 | if (__cntrl_ == nullptr) |
1582 | __throw_bad_weak_ptr(); |
1583 | } |
1584 | |
1585 | template<class _Tp> |
1586 | shared_ptr<_Tp> |
1587 | weak_ptr<_Tp>::lock() const _NOEXCEPTnoexcept |
1588 | { |
1589 | shared_ptr<_Tp> __r; |
1590 | __r.__cntrl_ = __cntrl_ ? __cntrl_->lock() : __cntrl_; |
1591 | if (__r.__cntrl_) |
1592 | __r.__ptr_ = __ptr_; |
1593 | return __r; |
1594 | } |
1595 | |
1596 | #if _LIBCPP_STD_VER14 > 14 |
1597 | template <class _Tp = void> struct owner_less; |
1598 | #else |
1599 | template <class _Tp> struct owner_less; |
1600 | #endif |
1601 | |
1602 | |
1603 | _LIBCPP_SUPPRESS_DEPRECATED_PUSHGCC diagnostic push
GCC diagnostic ignored "-Wdeprecated"
GCC diagnostic ignored "-Wdeprecated-declarations" |
1604 | template <class _Tp> |
1605 | struct _LIBCPP_TEMPLATE_VIS__attribute__ ((__type_visibility__("default"))) owner_less<shared_ptr<_Tp> > |
1606 | #if !defined(_LIBCPP_ABI_NO_BINDER_BASES) |
1607 | : binary_function<shared_ptr<_Tp>, shared_ptr<_Tp>, bool> |
1608 | #endif |
1609 | { |
1610 | _LIBCPP_SUPPRESS_DEPRECATED_POPGCC diagnostic pop |
1611 | #if _LIBCPP_STD_VER14 <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) |
1612 | _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type; |
1613 | _LIBCPP_DEPRECATED_IN_CXX17 typedef shared_ptr<_Tp> first_argument_type; |
1614 | _LIBCPP_DEPRECATED_IN_CXX17 typedef shared_ptr<_Tp> second_argument_type; |
1615 | #endif |
1616 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1617 | bool operator()(shared_ptr<_Tp> const& __x, shared_ptr<_Tp> const& __y) const _NOEXCEPTnoexcept |
1618 | {return __x.owner_before(__y);} |
1619 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1620 | bool operator()(shared_ptr<_Tp> const& __x, weak_ptr<_Tp> const& __y) const _NOEXCEPTnoexcept |
1621 | {return __x.owner_before(__y);} |
1622 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1623 | bool operator()( weak_ptr<_Tp> const& __x, shared_ptr<_Tp> const& __y) const _NOEXCEPTnoexcept |
1624 | {return __x.owner_before(__y);} |
1625 | }; |
1626 | |
1627 | _LIBCPP_SUPPRESS_DEPRECATED_PUSHGCC diagnostic push
GCC diagnostic ignored "-Wdeprecated"
GCC diagnostic ignored "-Wdeprecated-declarations" |
1628 | template <class _Tp> |
1629 | struct _LIBCPP_TEMPLATE_VIS__attribute__ ((__type_visibility__("default"))) owner_less<weak_ptr<_Tp> > |
1630 | #if !defined(_LIBCPP_ABI_NO_BINDER_BASES) |
1631 | : binary_function<weak_ptr<_Tp>, weak_ptr<_Tp>, bool> |
1632 | #endif |
1633 | { |
1634 | _LIBCPP_SUPPRESS_DEPRECATED_POPGCC diagnostic pop |
1635 | #if _LIBCPP_STD_VER14 <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) |
1636 | _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type; |
1637 | _LIBCPP_DEPRECATED_IN_CXX17 typedef weak_ptr<_Tp> first_argument_type; |
1638 | _LIBCPP_DEPRECATED_IN_CXX17 typedef weak_ptr<_Tp> second_argument_type; |
1639 | #endif |
1640 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1641 | bool operator()( weak_ptr<_Tp> const& __x, weak_ptr<_Tp> const& __y) const _NOEXCEPTnoexcept |
1642 | {return __x.owner_before(__y);} |
1643 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1644 | bool operator()(shared_ptr<_Tp> const& __x, weak_ptr<_Tp> const& __y) const _NOEXCEPTnoexcept |
1645 | {return __x.owner_before(__y);} |
1646 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1647 | bool operator()( weak_ptr<_Tp> const& __x, shared_ptr<_Tp> const& __y) const _NOEXCEPTnoexcept |
1648 | {return __x.owner_before(__y);} |
1649 | }; |
1650 | |
1651 | #if _LIBCPP_STD_VER14 > 14 |
1652 | template <> |
1653 | struct _LIBCPP_TEMPLATE_VIS__attribute__ ((__type_visibility__("default"))) owner_less<void> |
1654 | { |
1655 | template <class _Tp, class _Up> |
1656 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1657 | bool operator()( shared_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const _NOEXCEPTnoexcept |
1658 | {return __x.owner_before(__y);} |
1659 | template <class _Tp, class _Up> |
1660 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1661 | bool operator()( shared_ptr<_Tp> const& __x, weak_ptr<_Up> const& __y) const _NOEXCEPTnoexcept |
1662 | {return __x.owner_before(__y);} |
1663 | template <class _Tp, class _Up> |
1664 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1665 | bool operator()( weak_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const _NOEXCEPTnoexcept |
1666 | {return __x.owner_before(__y);} |
1667 | template <class _Tp, class _Up> |
1668 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1669 | bool operator()( weak_ptr<_Tp> const& __x, weak_ptr<_Up> const& __y) const _NOEXCEPTnoexcept |
1670 | {return __x.owner_before(__y);} |
1671 | typedef void is_transparent; |
1672 | }; |
1673 | #endif |
1674 | |
1675 | template<class _Tp> |
1676 | class _LIBCPP_TEMPLATE_VIS__attribute__ ((__type_visibility__("default"))) enable_shared_from_this |
1677 | { |
1678 | mutable weak_ptr<_Tp> __weak_this_; |
1679 | protected: |
1680 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) _LIBCPP_CONSTEXPRconstexpr |
1681 | enable_shared_from_this() _NOEXCEPTnoexcept {} |
1682 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1683 | enable_shared_from_this(enable_shared_from_this const&) _NOEXCEPTnoexcept {} |
1684 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1685 | enable_shared_from_this& operator=(enable_shared_from_this const&) _NOEXCEPTnoexcept |
1686 | {return *this;} |
1687 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1688 | ~enable_shared_from_this() {} |
1689 | public: |
1690 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1691 | shared_ptr<_Tp> shared_from_this() |
1692 | {return shared_ptr<_Tp>(__weak_this_);} |
1693 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1694 | shared_ptr<_Tp const> shared_from_this() const |
1695 | {return shared_ptr<const _Tp>(__weak_this_);} |
1696 | |
1697 | #if _LIBCPP_STD_VER14 > 14 |
1698 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1699 | weak_ptr<_Tp> weak_from_this() _NOEXCEPTnoexcept |
1700 | { return __weak_this_; } |
1701 | |
1702 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1703 | weak_ptr<const _Tp> weak_from_this() const _NOEXCEPTnoexcept |
1704 | { return __weak_this_; } |
1705 | #endif // _LIBCPP_STD_VER > 14 |
1706 | |
1707 | template <class _Up> friend class shared_ptr; |
1708 | }; |
1709 | |
1710 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS__attribute__ ((__type_visibility__("default"))) hash; |
1711 | |
1712 | template <class _Tp> |
1713 | struct _LIBCPP_TEMPLATE_VIS__attribute__ ((__type_visibility__("default"))) hash<shared_ptr<_Tp> > |
1714 | { |
1715 | #if _LIBCPP_STD_VER14 <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) |
1716 | _LIBCPP_DEPRECATED_IN_CXX17 typedef shared_ptr<_Tp> argument_type; |
1717 | _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; |
1718 | #endif |
1719 | |
1720 | _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1721 | size_t operator()(const shared_ptr<_Tp>& __ptr) const _NOEXCEPTnoexcept |
1722 | { |
1723 | return hash<typename shared_ptr<_Tp>::element_type*>()(__ptr.get()); |
1724 | } |
1725 | }; |
1726 | |
1727 | template<class _CharT, class _Traits, class _Yp> |
1728 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1729 | basic_ostream<_CharT, _Traits>& |
1730 | operator<<(basic_ostream<_CharT, _Traits>& __os, shared_ptr<_Yp> const& __p); |
1731 | |
1732 | |
1733 | #if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER) |
1734 | |
1735 | class _LIBCPP_TYPE_VIS__attribute__ ((__visibility__("default"))) __sp_mut |
1736 | { |
1737 | void* __lx; |
1738 | public: |
1739 | void lock() _NOEXCEPTnoexcept; |
1740 | void unlock() _NOEXCEPTnoexcept; |
1741 | |
1742 | private: |
1743 | _LIBCPP_CONSTEXPRconstexpr __sp_mut(void*) _NOEXCEPTnoexcept; |
1744 | __sp_mut(const __sp_mut&); |
1745 | __sp_mut& operator=(const __sp_mut&); |
1746 | |
1747 | friend _LIBCPP_FUNC_VIS__attribute__ ((__visibility__("default"))) __sp_mut& __get_sp_mut(const void*); |
1748 | }; |
1749 | |
1750 | _LIBCPP_FUNC_VIS__attribute__ ((__visibility__("default"))) _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR |
1751 | __sp_mut& __get_sp_mut(const void*); |
1752 | |
1753 | template <class _Tp> |
1754 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1755 | bool |
1756 | atomic_is_lock_free(const shared_ptr<_Tp>*) |
1757 | { |
1758 | return false; |
1759 | } |
1760 | |
1761 | template <class _Tp> |
1762 | _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR |
1763 | shared_ptr<_Tp> |
1764 | atomic_load(const shared_ptr<_Tp>* __p) |
1765 | { |
1766 | __sp_mut& __m = __get_sp_mut(__p); |
1767 | __m.lock(); |
1768 | shared_ptr<_Tp> __q = *__p; |
1769 | __m.unlock(); |
1770 | return __q; |
1771 | } |
1772 | |
1773 | template <class _Tp> |
1774 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1775 | _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR |
1776 | shared_ptr<_Tp> |
1777 | atomic_load_explicit(const shared_ptr<_Tp>* __p, memory_order) |
1778 | { |
1779 | return atomic_load(__p); |
1780 | } |
1781 | |
1782 | template <class _Tp> |
1783 | _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR |
1784 | void |
1785 | atomic_store(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r) |
1786 | { |
1787 | __sp_mut& __m = __get_sp_mut(__p); |
1788 | __m.lock(); |
1789 | __p->swap(__r); |
1790 | __m.unlock(); |
1791 | } |
1792 | |
1793 | template <class _Tp> |
1794 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1795 | _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR |
1796 | void |
1797 | atomic_store_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r, memory_order) |
1798 | { |
1799 | atomic_store(__p, __r); |
1800 | } |
1801 | |
1802 | template <class _Tp> |
1803 | _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR |
1804 | shared_ptr<_Tp> |
1805 | atomic_exchange(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r) |
1806 | { |
1807 | __sp_mut& __m = __get_sp_mut(__p); |
1808 | __m.lock(); |
1809 | __p->swap(__r); |
1810 | __m.unlock(); |
1811 | return __r; |
1812 | } |
1813 | |
1814 | template <class _Tp> |
1815 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1816 | _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR |
1817 | shared_ptr<_Tp> |
1818 | atomic_exchange_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r, memory_order) |
1819 | { |
1820 | return atomic_exchange(__p, __r); |
1821 | } |
1822 | |
1823 | template <class _Tp> |
1824 | _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR |
1825 | bool |
1826 | atomic_compare_exchange_strong(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, shared_ptr<_Tp> __w) |
1827 | { |
1828 | shared_ptr<_Tp> __temp; |
1829 | __sp_mut& __m = __get_sp_mut(__p); |
1830 | __m.lock(); |
1831 | if (__p->__owner_equivalent(*__v)) |
1832 | { |
1833 | _VSTDstd::__1::swap(__temp, *__p); |
1834 | *__p = __w; |
1835 | __m.unlock(); |
1836 | return true; |
1837 | } |
1838 | _VSTDstd::__1::swap(__temp, *__v); |
1839 | *__v = *__p; |
1840 | __m.unlock(); |
1841 | return false; |
1842 | } |
1843 | |
1844 | template <class _Tp> |
1845 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1846 | _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR |
1847 | bool |
1848 | atomic_compare_exchange_weak(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, shared_ptr<_Tp> __w) |
1849 | { |
1850 | return atomic_compare_exchange_strong(__p, __v, __w); |
1851 | } |
1852 | |
1853 | template <class _Tp> |
1854 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1855 | _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR |
1856 | bool |
1857 | atomic_compare_exchange_strong_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, |
1858 | shared_ptr<_Tp> __w, memory_order, memory_order) |
1859 | { |
1860 | return atomic_compare_exchange_strong(__p, __v, __w); |
1861 | } |
1862 | |
1863 | template <class _Tp> |
1864 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1865 | _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR |
1866 | bool |
1867 | atomic_compare_exchange_weak_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, |
1868 | shared_ptr<_Tp> __w, memory_order, memory_order) |
1869 | { |
1870 | return atomic_compare_exchange_weak(__p, __v, __w); |
1871 | } |
1872 | |
1873 | #endif // !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER) |
1874 | |
1875 | _LIBCPP_END_NAMESPACE_STD} } |
1876 | |
1877 | _LIBCPP_POP_MACROSpop_macro("min") pop_macro("max") |
1878 | |
1879 | #endif // _LIBCPP___MEMORY_SHARED_PTR_H |
1 | //===-- CompilerType.h ------------------------------------------*- C++ -*-===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #ifndef LLDB_SYMBOL_COMPILERTYPE_H |
10 | #define LLDB_SYMBOL_COMPILERTYPE_H |
11 | |
12 | #include <functional> |
13 | #include <string> |
14 | #include <vector> |
15 | |
16 | #include "lldb/lldb-private.h" |
17 | #include "llvm/ADT/APSInt.h" |
18 | |
19 | namespace lldb_private { |
20 | |
21 | class DataExtractor; |
22 | |
23 | /// Generic representation of a type in a programming language. |
24 | /// |
25 | /// This class serves as an abstraction for a type inside one of the TypeSystems |
26 | /// implemented by the language plugins. It does not have any actual logic in it |
27 | /// but only stores an opaque pointer and a pointer to the TypeSystem that |
28 | /// gives meaning to this opaque pointer. All methods of this class should call |
29 | /// their respective method in the TypeSystem interface and pass the opaque |
30 | /// pointer along. |
31 | /// |
32 | /// \see lldb_private::TypeSystem |
33 | class CompilerType { |
34 | public: |
35 | /// Creates a CompilerType with the given TypeSystem and opaque compiler type. |
36 | /// |
37 | /// This constructor should only be called from the respective TypeSystem |
38 | /// implementation. |
39 | /// |
40 | /// \see lldb_private::TypeSystemClang::GetType(clang::QualType) |
41 | CompilerType(TypeSystem *type_system, lldb::opaque_compiler_type_t type) |
42 | : m_type(type), m_type_system(type_system) { |
43 | assert(Verify() && "verification failed")((void)0); |
44 | } |
45 | |
46 | CompilerType(const CompilerType &rhs) |
47 | : m_type(rhs.m_type), m_type_system(rhs.m_type_system) {} |
48 | |
49 | CompilerType() = default; |
50 | |
51 | /// Operators. |
52 | /// \{ |
53 | const CompilerType &operator=(const CompilerType &rhs) { |
54 | m_type = rhs.m_type; |
55 | m_type_system = rhs.m_type_system; |
56 | return *this; |
57 | } |
58 | |
59 | bool operator<(const CompilerType &rhs) const { |
60 | if (m_type_system == rhs.m_type_system) |
61 | return m_type < rhs.m_type; |
62 | return m_type_system < rhs.m_type_system; |
63 | } |
64 | /// \} |
65 | |
66 | /// Tests. |
67 | /// \{ |
68 | explicit operator bool() const { |
69 | return m_type != nullptr && m_type_system != nullptr; |
70 | } |
71 | |
72 | bool IsValid() const { return m_type != nullptr && m_type_system != nullptr; } |
73 | |
74 | bool IsArrayType(CompilerType *element_type = nullptr, |
75 | uint64_t *size = nullptr, |
76 | bool *is_incomplete = nullptr) const; |
77 | |
78 | bool IsVectorType(CompilerType *element_type = nullptr, |
79 | uint64_t *size = nullptr) const; |
80 | |
81 | bool IsArrayOfScalarType() const; |
82 | |
83 | bool IsAggregateType() const; |
84 | |
85 | bool IsAnonymousType() const; |
86 | |
87 | bool IsScopedEnumerationType() const; |
88 | |
89 | bool IsBeingDefined() const; |
90 | |
91 | bool IsCharType() const; |
92 | |
93 | bool IsCompleteType() const; |
94 | |
95 | bool IsConst() const; |
96 | |
97 | bool IsCStringType(uint32_t &length) const; |
98 | |
99 | bool IsDefined() const; |
100 | |
101 | bool IsFloatingPointType(uint32_t &count, bool &is_complex) const; |
102 | |
103 | bool IsFunctionType() const; |
104 | |
105 | uint32_t IsHomogeneousAggregate(CompilerType *base_type_ptr) const; |
106 | |
107 | size_t GetNumberOfFunctionArguments() const; |
108 | |
109 | CompilerType GetFunctionArgumentAtIndex(const size_t index) const; |
110 | |
111 | bool IsVariadicFunctionType() const; |
112 | |
113 | bool IsFunctionPointerType() const; |
114 | |
115 | bool |
116 | IsBlockPointerType(CompilerType *function_pointer_type_ptr = nullptr) const; |
117 | |
118 | bool IsIntegerType(bool &is_signed) const; |
119 | |
120 | bool IsEnumerationType(bool &is_signed) const; |
121 | |
122 | bool IsIntegerOrEnumerationType(bool &is_signed) const; |
123 | |
124 | bool IsPolymorphicClass() const; |
125 | |
126 | /// \param target_type Can pass nullptr. |
127 | bool IsPossibleDynamicType(CompilerType *target_type, bool check_cplusplus, |
128 | bool check_objc) const; |
129 | |
130 | bool IsPointerToScalarType() const; |
131 | |
132 | bool IsRuntimeGeneratedType() const; |
133 | |
134 | bool IsPointerType(CompilerType *pointee_type = nullptr) const; |
135 | |
136 | bool IsPointerOrReferenceType(CompilerType *pointee_type = nullptr) const; |
137 | |
138 | bool IsReferenceType(CompilerType *pointee_type = nullptr, |
139 | bool *is_rvalue = nullptr) const; |
140 | |
141 | bool ShouldTreatScalarValueAsAddress() const; |
142 | |
143 | bool IsScalarType() const; |
144 | |
145 | bool IsTypedefType() const; |
146 | |
147 | bool IsVoidType() const; |
148 | /// \} |
149 | |
150 | /// Type Completion. |
151 | /// \{ |
152 | bool GetCompleteType() const; |
153 | /// \} |
154 | |
155 | /// AST related queries. |
156 | /// \{ |
157 | size_t GetPointerByteSize() const; |
158 | /// \} |
159 | |
160 | /// Accessors. |
161 | /// \{ |
162 | TypeSystem *GetTypeSystem() const { return m_type_system; } |
163 | |
164 | ConstString GetTypeName() const; |
165 | |
166 | ConstString GetDisplayTypeName() const; |
167 | |
168 | uint32_t |
169 | GetTypeInfo(CompilerType *pointee_or_element_compiler_type = nullptr) const; |
170 | |
171 | lldb::LanguageType GetMinimumLanguage(); |
172 | |
173 | lldb::opaque_compiler_type_t GetOpaqueQualType() const { return m_type; } |
174 | |
175 | lldb::TypeClass GetTypeClass() const; |
176 | |
177 | void SetCompilerType(TypeSystem *type_system, |
178 | lldb::opaque_compiler_type_t type); |
179 | |
180 | unsigned GetTypeQualifiers() const; |
181 | /// \} |
182 | |
183 | /// Creating related types. |
184 | /// \{ |
185 | CompilerType GetArrayElementType(ExecutionContextScope *exe_scope) const; |
186 | |
187 | CompilerType GetArrayType(uint64_t size) const; |
188 | |
189 | CompilerType GetCanonicalType() const; |
190 | |
191 | CompilerType GetFullyUnqualifiedType() const; |
192 | |
193 | CompilerType GetEnumerationIntegerType() const; |
194 | |
195 | /// Returns -1 if this isn't a function of if the function doesn't |
196 | /// have a prototype Returns a value >= 0 if there is a prototype. |
197 | int GetFunctionArgumentCount() const; |
198 | |
199 | CompilerType GetFunctionArgumentTypeAtIndex(size_t idx) const; |
200 | |
201 | CompilerType GetFunctionReturnType() const; |
202 | |
203 | size_t GetNumMemberFunctions() const; |
204 | |
205 | TypeMemberFunctionImpl GetMemberFunctionAtIndex(size_t idx); |
206 | |
207 | /// If this type is a reference to a type (L value or R value reference), |
208 | /// return a new type with the reference removed, else return the current type |
209 | /// itself. |
210 | CompilerType GetNonReferenceType() const; |
211 | |
212 | /// If this type is a pointer type, return the type that the pointer points |
213 | /// to, else return an invalid type. |
214 | CompilerType GetPointeeType() const; |
215 | |
216 | /// Return a new CompilerType that is a pointer to this type |
217 | CompilerType GetPointerType() const; |
218 | |
219 | /// Return a new CompilerType that is a L value reference to this type if this |
220 | /// type is valid and the type system supports L value references, else return |
221 | /// an invalid type. |
222 | CompilerType GetLValueReferenceType() const; |
223 | |
224 | /// Return a new CompilerType that is a R value reference to this type if this |
225 | /// type is valid and the type system supports R value references, else return |
226 | /// an invalid type. |
227 | CompilerType GetRValueReferenceType() const; |
228 | |
229 | /// Return a new CompilerType adds a const modifier to this type if this type |
230 | /// is valid and the type system supports const modifiers, else return an |
231 | /// invalid type. |
232 | CompilerType AddConstModifier() const; |
233 | |
234 | /// Return a new CompilerType adds a volatile modifier to this type if this |
235 | /// type is valid and the type system supports volatile modifiers, else return |
236 | /// an invalid type. |
237 | CompilerType AddVolatileModifier() const; |
238 | |
239 | /// Return a new CompilerType that is the atomic type of this type. If this |
240 | /// type is not valid or the type system doesn't support atomic types, this |
241 | /// returns an invalid type. |
242 | CompilerType GetAtomicType() const; |
243 | |
244 | /// Return a new CompilerType adds a restrict modifier to this type if this |
245 | /// type is valid and the type system supports restrict modifiers, else return |
246 | /// an invalid type. |
247 | CompilerType AddRestrictModifier() const; |
248 | |
249 | /// Create a typedef to this type using "name" as the name of the typedef this |
250 | /// type is valid and the type system supports typedefs, else return an |
251 | /// invalid type. |
252 | /// \param payload The typesystem-specific \p lldb::Type payload. |
253 | CompilerType CreateTypedef(const char *name, |
254 | const CompilerDeclContext &decl_ctx, |
255 | uint32_t payload) const; |
256 | |
257 | /// If the current object represents a typedef type, get the underlying type |
258 | CompilerType GetTypedefedType() const; |
259 | |
260 | /// Create related types using the current type's AST |
261 | CompilerType GetBasicTypeFromAST(lldb::BasicType basic_type) const; |
262 | /// \} |
263 | |
264 | /// Exploring the type. |
265 | /// \{ |
266 | struct IntegralTemplateArgument; |
267 | |
268 | /// Return the size of the type in bytes. |
269 | llvm::Optional<uint64_t> GetByteSize(ExecutionContextScope *exe_scope) const; |
270 | /// Return the size of the type in bits. |
271 | llvm::Optional<uint64_t> GetBitSize(ExecutionContextScope *exe_scope) const; |
272 | |
273 | lldb::Encoding GetEncoding(uint64_t &count) const; |
274 | |
275 | lldb::Format GetFormat() const; |
276 | |
277 | llvm::Optional<size_t> |
278 | GetTypeBitAlign(ExecutionContextScope *exe_scope) const; |
279 | |
280 | uint32_t GetNumChildren(bool omit_empty_base_classes, |
281 | const ExecutionContext *exe_ctx) const; |
282 | |
283 | lldb::BasicType GetBasicTypeEnumeration() const; |
284 | |
285 | static lldb::BasicType GetBasicTypeEnumeration(ConstString name); |
286 | |
287 | /// If this type is an enumeration, iterate through all of its enumerators |
288 | /// using a callback. If the callback returns true, keep iterating, else abort |
289 | /// the iteration. |
290 | void ForEachEnumerator( |
291 | std::function<bool(const CompilerType &integer_type, ConstString name, |
292 | const llvm::APSInt &value)> const &callback) const; |
293 | |
294 | uint32_t GetNumFields() const; |
295 | |
296 | CompilerType GetFieldAtIndex(size_t idx, std::string &name, |
297 | uint64_t *bit_offset_ptr, |
298 | uint32_t *bitfield_bit_size_ptr, |
299 | bool *is_bitfield_ptr) const; |
300 | |
301 | uint32_t GetNumDirectBaseClasses() const; |
302 | |
303 | uint32_t GetNumVirtualBaseClasses() const; |
304 | |
305 | CompilerType GetDirectBaseClassAtIndex(size_t idx, |
306 | uint32_t *bit_offset_ptr) const; |
307 | |
308 | CompilerType GetVirtualBaseClassAtIndex(size_t idx, |
309 | uint32_t *bit_offset_ptr) const; |
310 | |
311 | uint32_t GetIndexOfFieldWithName(const char *name, |
312 | CompilerType *field_compiler_type = nullptr, |
313 | uint64_t *bit_offset_ptr = nullptr, |
314 | uint32_t *bitfield_bit_size_ptr = nullptr, |
315 | bool *is_bitfield_ptr = nullptr) const; |
316 | |
317 | CompilerType GetChildCompilerTypeAtIndex( |
318 | ExecutionContext *exe_ctx, size_t idx, bool transparent_pointers, |
319 | bool omit_empty_base_classes, bool ignore_array_bounds, |
320 | std::string &child_name, uint32_t &child_byte_size, |
321 | int32_t &child_byte_offset, uint32_t &child_bitfield_bit_size, |
322 | uint32_t &child_bitfield_bit_offset, bool &child_is_base_class, |
323 | bool &child_is_deref_of_parent, ValueObject *valobj, |
324 | uint64_t &language_flags) const; |
325 | |
326 | /// Lookup a child given a name. This function will match base class names and |
327 | /// member member names in "clang_type" only, not descendants. |
328 | uint32_t GetIndexOfChildWithName(const char *name, |
329 | bool omit_empty_base_classes) const; |
330 | |
331 | /// Lookup a child member given a name. This function will match member names |
332 | /// only and will descend into "clang_type" children in search for the first |
333 | /// member in this class, or any base class that matches "name". |
334 | /// TODO: Return all matches for a given name by returning a |
335 | /// vector<vector<uint32_t>> |
336 | /// so we catch all names that match a given child name, not just the first. |
337 | size_t |
338 | GetIndexOfChildMemberWithName(const char *name, bool omit_empty_base_classes, |
339 | std::vector<uint32_t> &child_indexes) const; |
340 | |
341 | size_t GetNumTemplateArguments() const; |
342 | |
343 | lldb::TemplateArgumentKind GetTemplateArgumentKind(size_t idx) const; |
344 | CompilerType GetTypeTemplateArgument(size_t idx) const; |
345 | |
346 | /// Returns the value of the template argument and its type. |
347 | llvm::Optional<IntegralTemplateArgument> |
348 | GetIntegralTemplateArgument(size_t idx) const; |
349 | |
350 | CompilerType GetTypeForFormatters() const; |
351 | |
352 | LazyBool ShouldPrintAsOneLiner(ValueObject *valobj) const; |
353 | |
354 | bool IsMeaninglessWithoutDynamicResolution() const; |
355 | /// \} |
356 | |
357 | /// Dumping types. |
358 | /// \{ |
359 | #ifndef NDEBUG1 |
360 | /// Convenience LLVM-style dump method for use in the debugger only. |
361 | /// Don't call this function from actual code. |
362 | LLVM_DUMP_METHOD__attribute__((noinline)) void dump() const; |
363 | #endif |
364 | |
365 | void DumpValue(ExecutionContext *exe_ctx, Stream *s, lldb::Format format, |
366 | const DataExtractor &data, lldb::offset_t data_offset, |
367 | size_t data_byte_size, uint32_t bitfield_bit_size, |
368 | uint32_t bitfield_bit_offset, bool show_types, |
369 | bool show_summary, bool verbose, uint32_t depth); |
370 | |
371 | bool DumpTypeValue(Stream *s, lldb::Format format, const DataExtractor &data, |
372 | lldb::offset_t data_offset, size_t data_byte_size, |
373 | uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, |
374 | ExecutionContextScope *exe_scope); |
375 | |
376 | void DumpSummary(ExecutionContext *exe_ctx, Stream *s, |
377 | const DataExtractor &data, lldb::offset_t data_offset, |
378 | size_t data_byte_size); |
379 | |
380 | /// Dump to stdout. |
381 | void DumpTypeDescription(lldb::DescriptionLevel level = |
382 | lldb::eDescriptionLevelFull) const; |
383 | |
384 | /// Print a description of the type to a stream. The exact implementation |
385 | /// varies, but the expectation is that eDescriptionLevelFull returns a |
386 | /// source-like representation of the type, whereas eDescriptionLevelVerbose |
387 | /// does a dump of the underlying AST if applicable. |
388 | void DumpTypeDescription(Stream *s, lldb::DescriptionLevel level = |
389 | lldb::eDescriptionLevelFull) const; |
390 | /// \} |
391 | |
392 | bool GetValueAsScalar(const DataExtractor &data, lldb::offset_t data_offset, |
393 | size_t data_byte_size, Scalar &value, |
394 | ExecutionContextScope *exe_scope) const; |
395 | void Clear() { |
396 | m_type = nullptr; |
397 | m_type_system = nullptr; |
398 | } |
399 | |
400 | private: |
401 | #ifndef NDEBUG1 |
402 | /// If the type is valid, ask the TypeSystem to verify the integrity |
403 | /// of the type to catch CompilerTypes that mix and match invalid |
404 | /// TypeSystem/Opaque type pairs. |
405 | bool Verify() const; |
406 | #endif |
407 | |
408 | lldb::opaque_compiler_type_t m_type = nullptr; |
409 | TypeSystem *m_type_system = nullptr; |
410 | }; |
411 | |
412 | bool operator==(const CompilerType &lhs, const CompilerType &rhs); |
413 | bool operator!=(const CompilerType &lhs, const CompilerType &rhs); |
414 | |
415 | struct CompilerType::IntegralTemplateArgument { |
416 | llvm::APSInt value; |
417 | CompilerType type; |
418 | }; |
419 | |
420 | } // namespace lldb_private |
421 | |
422 | #endif // LLDB_SYMBOL_COMPILERTYPE_H |