Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name ABISysV_mips64.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/gnu/usr.bin/clang/liblldbABI/obj -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/gnu/usr.bin/clang/liblldbABI/../../../llvm/llvm/include -I /usr/src/gnu/usr.bin/clang/liblldbABI/../include -I /usr/src/gnu/usr.bin/clang/liblldbABI/obj -I /usr/src/gnu/usr.bin/clang/liblldbABI/obj/../include -D NDEBUG -D __STDC_LIMIT_MACROS -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D LLVM_PREFIX="/usr" -I /usr/src/gnu/usr.bin/clang/liblldbABI/../../../llvm/lldb/include -I /usr/src/gnu/usr.bin/clang/liblldbABI/../../../llvm/lldb/source -I /usr/src/gnu/usr.bin/clang/liblldbABI/../../../llvm/clang/include -internal-isystem /usr/include/c++/v1 -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-comment -std=c++14 -fdeprecated-macro -fdebug-compilation-dir=/usr/src/gnu/usr.bin/clang/liblldbABI/obj -ferror-limit 19 -fvisibility-inlines-hidden -fwrapv -stack-protector 2 -fno-rtti -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c++ /usr/src/gnu/usr.bin/clang/liblldbABI/../../../llvm/lldb/source/Plugins/ABI/Mips/ABISysV_mips64.cpp

/usr/src/gnu/usr.bin/clang/liblldbABI/../../../llvm/lldb/source/Plugins/ABI/Mips/ABISysV_mips64.cpp

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
32using namespace lldb;
33using namespace lldb_private;
34
35LLDB_PLUGIN_DEFINE(ABISysV_mips64)namespace lldb_private { void lldb_initialize_ABISysV_mips64(
) { ABISysV_mips64::Initialize(); } void lldb_terminate_ABISysV_mips64
() { ABISysV_mips64::Terminate(); } }
36
37enum 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
78static 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
543static const uint32_t k_num_register_infos =
544 llvm::array_lengthof(g_register_infos_mips64);
545
546const lldb_private::RegisterInfo *
547ABISysV_mips64::GetRegisterInfoArray(uint32_t &count) {
548 count = k_num_register_infos;
549 return g_register_infos_mips64;
550}
551
552size_t ABISysV_mips64::GetRedZoneSize() const { return 0; }
553
554// Static Functions
555
556ABISP
557ABISysV_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
564bool 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
655bool ABISysV_mips64::GetArgumentValues(Thread &thread,
656 ValueList &values) const {
657 return false;
658}
659
660Status ABISysV_mips64::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
661 lldb::ValueObjectSP &new_value_sp) {
662 Status error;
663 if (!new_value_sp) {
1
Calling 'shared_ptr::operator bool'
4
Returning from 'shared_ptr::operator bool'
5
Taking false branch
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) {
6
Calling 'CompilerType::operator bool'
10
Returning from 'CompilerType::operator bool'
11
Taking false branch
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();
12
Value assigned to field '__ptr_'
13
'reg_ctx' initialized here
677
678 if (!reg_ctx)
14
Assuming 'reg_ctx' is null
15
Taking true branch
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()) {
16
Assuming the condition is false
17
Taking false branch
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) {
18
Assuming the condition is true
694 if (type_flags & eTypeIsInteger || type_flags & eTypeIsPointer) {
19
Assuming the condition is true
695 lldb::offset_t offset = 0;
696
697 if (num_bytes <= 16) {
20
Assuming 'num_bytes' is <= 16
21
Taking true branch
698 const RegisterInfo *r2_info = reg_ctx->GetRegisterInfoByName("r2", 0);
22
Called C++ object pointer is null
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
730ValueObjectSP ABISysV_mips64::GetReturnValueObjectSimple(
731 Thread &thread, CompilerType &return_compiler_type) const {
732 ValueObjectSP return_valobj_sp;
733 return return_valobj_sp;
734}
735
736ValueObjectSP 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
1132bool 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
1153bool 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
1172bool ABISysV_mips64::RegisterIsVolatile(const RegisterInfo *reg_info) {
1173 return !RegisterIsCalleeSaved(reg_info);
1174}
1175
1176bool ABISysV_mips64::IsSoftFloat(uint32_t fp_flag) const {
1177 return (fp_flag == lldb_private::ArchSpec::eMIPS_ABI_FP_SOFT);
1178}
1179
1180bool 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
1195void ABISysV_mips64::Initialize() {
1196 PluginManager::RegisterPlugin(
1197 GetPluginNameStatic(), "System V ABI for mips64 targets", CreateInstance);
1198}
1199
1200void ABISysV_mips64::Terminate() {
1201 PluginManager::UnregisterPlugin(CreateInstance);
1202}
1203
1204lldb_private::ConstString ABISysV_mips64::GetPluginNameStatic() {
1205 static ConstString g_name("sysv-mips64");
1206 return g_name;
1207}
1208
1209// PluginInterface protocol
1210
1211lldb_private::ConstString ABISysV_mips64::GetPluginName() {
1212 return GetPluginNameStatic();
1213}
1214
1215uint32_t ABISysV_mips64::GetPluginVersion() { return 1; }

/usr/include/c++/v1/__memory/shared_ptr.h

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
51template <class _Alloc>
52class __allocator_destructor
53{
54 typedef _LIBCPP_NODEBUG_TYPE__attribute__((nodebug)) allocator_traits<_Alloc> __alloc_traits;
55public:
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;
58private:
59 _Alloc& __alloc_;
60 size_type __s_;
61public:
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
81template <class _ValueType>
82inline _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
93template <class _ValueType>
94inline _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
105template <class _Tp>
106inline _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
116template <class _Tp>
117inline _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
127class _LIBCPP_EXCEPTION_ABI__attribute__ ((__visibility__("default"))) bad_weak_ptr
128 : public std::exception
129{
130public:
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__
))
138void __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
147template<class _Tp> class _LIBCPP_TEMPLATE_VIS__attribute__ ((__type_visibility__("default"))) weak_ptr;
148
149class _LIBCPP_TYPE_VIS__attribute__ ((__visibility__("default"))) __shared_count
150{
151 __shared_count(const __shared_count&);
152 __shared_count& operator=(const __shared_count&);
153
154protected:
155 long __shared_owners_;
156 virtual ~__shared_count();
157private:
158 virtual void __on_zero_shared() _NOEXCEPTnoexcept = 0;
159
160public:
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
189class _LIBCPP_TYPE_VIS__attribute__ ((__visibility__("default"))) __shared_weak_count
190 : private __shared_count
191{
192 long __shared_weak_owners_;
193
194public:
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) {}
199protected:
200 virtual ~__shared_weak_count();
201
202public:
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;
229private:
230 virtual void __on_zero_shared_weak() _NOEXCEPTnoexcept = 0;
231};
232
233template <class _Tp, class _Dp, class _Alloc>
234class __shared_ptr_pointer
235 : public __shared_weak_count
236{
237 __compressed_pair<__compressed_pair<_Tp, _Dp>, _Alloc> __data_;
238public:
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
247private:
248 virtual void __on_zero_shared() _NOEXCEPTnoexcept;
249 virtual void __on_zero_shared_weak() _NOEXCEPTnoexcept;
250};
251
252#ifndef _LIBCPP_NO_RTTI
253
254template <class _Tp, class _Dp, class _Alloc>
255const 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
263template <class _Tp, class _Dp, class _Alloc>
264void
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
271template <class _Tp, class _Dp, class _Alloc>
272void
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
284template <class _Tp, class _Alloc>
285struct __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
308private:
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
365struct __shared_ptr_dummy_rebind_allocator_type;
366template <>
367class _LIBCPP_TEMPLATE_VIS__attribute__ ((__type_visibility__("default"))) allocator<__shared_ptr_dummy_rebind_allocator_type>
368{
369public:
370 template <class _Other>
371 struct rebind
372 {
373 typedef allocator<_Other> other;
374 };
375};
376
377template<class _Tp> class _LIBCPP_TEMPLATE_VIS__attribute__ ((__type_visibility__("default"))) enable_shared_from_this;
378
379template<class _Tp, class _Up>
380struct __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
387template <class _Ptr, class = void>
388struct __is_deletable : false_type { };
389template <class _Ptr>
390struct __is_deletable<_Ptr, decltype(delete declval<_Ptr>())> : true_type { };
391
392template <class _Ptr, class = void>
393struct __is_array_deletable : false_type { };
394template <class _Ptr>
395struct __is_array_deletable<_Ptr, decltype(delete[] declval<_Ptr>())> : true_type { };
396
397template <class _Dp, class _Pt,
398 class = decltype(declval<_Dp>()(declval<_Pt>()))>
399static true_type __well_formed_deleter_test(int);
400
401template <class, class>
402static false_type __well_formed_deleter_test(...);
403
404template <class _Dp, class _Pt>
405struct __well_formed_deleter : decltype(__well_formed_deleter_test<_Dp, _Pt>(0)) {};
406
407template<class _Dp, class _Tp, class _Yp>
408struct __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
421template<class _Tp>
422class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS__attribute__ ((__type_visibility__("default"))) shared_ptr
423{
424public:
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
432private:
433 element_type* __ptr_;
434 __shared_weak_count* __cntrl_;
435
436 struct __nat {int __for_bool_;};
437public:
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;}
2
Assuming the condition is true
3
Returning the value 1, which participates in a condition later
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
641private:
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
690template<class _Tp>
691shared_ptr(weak_ptr<_Tp>) -> shared_ptr<_Tp>;
692template<class _Tp, class _Dp>
693shared_ptr(unique_ptr<_Tp, _Dp>) -> shared_ptr<_Tp>;
694#endif
695
696template<class _Tp>
697inline
698_LIBCPP_CONSTEXPRconstexpr
699shared_ptr<_Tp>::shared_ptr() _NOEXCEPTnoexcept
700 : __ptr_(nullptr),
701 __cntrl_(nullptr)
702{
703}
704
705template<class _Tp>
706inline
707_LIBCPP_CONSTEXPRconstexpr
708shared_ptr<_Tp>::shared_ptr(nullptr_t) _NOEXCEPTnoexcept
709 : __ptr_(nullptr),
710 __cntrl_(nullptr)
711{
712}
713
714template<class _Tp>
715template<class _Yp, class _Dp>
716shared_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
742template<class _Tp>
743template<class _Dp>
744shared_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
768template<class _Tp>
769template<class _Yp, class _Dp, class _Alloc>
770shared_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
801template<class _Tp>
802template<class _Dp, class _Alloc>
803shared_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
832template<class _Tp>
833template<class _Yp>
834inline
835shared_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
843template<class _Tp>
844inline
845shared_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
853template<class _Tp>
854template<class _Yp>
855inline
856shared_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
866template<class _Tp>
867inline
868shared_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
876template<class _Tp>
877template<class _Yp>
878inline
879shared_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)
890template<class _Tp>
891template<class _Yp>
892shared_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
903template<class _Tp>
904template <class _Yp, class _Dp>
905shared_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
928template<class _Tp>
929template <class _Yp, class _Dp>
930shared_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
955template<class _Tp>
956shared_ptr<_Tp>::~shared_ptr()
957{
958 if (__cntrl_)
959 __cntrl_->__release_shared();
960}
961
962template<class _Tp>
963inline
964shared_ptr<_Tp>&
965shared_ptr<_Tp>::operator=(const shared_ptr& __r) _NOEXCEPTnoexcept
966{
967 shared_ptr(__r).swap(*this);
968 return *this;
969}
970
971template<class _Tp>
972template<class _Yp>
973inline
974typename enable_if
975<
976 __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value,
977 shared_ptr<_Tp>&
978>::type
979shared_ptr<_Tp>::operator=(const shared_ptr<_Yp>& __r) _NOEXCEPTnoexcept
980{
981 shared_ptr(__r).swap(*this);
982 return *this;
983}
984
985template<class _Tp>
986inline
987shared_ptr<_Tp>&
988shared_ptr<_Tp>::operator=(shared_ptr&& __r) _NOEXCEPTnoexcept
989{
990 shared_ptr(_VSTDstd::__1::move(__r)).swap(*this);
991 return *this;
992}
993
994template<class _Tp>
995template<class _Yp>
996inline
997typename enable_if
998<
999 __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value,
1000 shared_ptr<_Tp>&
1001>::type
1002shared_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)
1009template<class _Tp>
1010template<class _Yp>
1011inline
1012typename 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&
1018shared_ptr<_Tp>::operator=(auto_ptr<_Yp>&& __r)
1019{
1020 shared_ptr(_VSTDstd::__1::move(__r)).swap(*this);
1021 return *this;
1022}
1023#endif
1024
1025template<class _Tp>
1026template <class _Yp, class _Dp>
1027inline
1028typename 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
1034shared_ptr<_Tp>::operator=(unique_ptr<_Yp, _Dp>&& __r)
1035{
1036 shared_ptr(_VSTDstd::__1::move(__r)).swap(*this);
1037 return *this;
1038}
1039
1040template<class _Tp>
1041inline
1042void
1043shared_ptr<_Tp>::swap(shared_ptr& __r) _NOEXCEPTnoexcept
1044{
1045 _VSTDstd::__1::swap(__ptr_, __r.__ptr_);
1046 _VSTDstd::__1::swap(__cntrl_, __r.__cntrl_);
1047}
1048
1049template<class _Tp>
1050inline
1051void
1052shared_ptr<_Tp>::reset() _NOEXCEPTnoexcept
1053{
1054 shared_ptr().swap(*this);
1055}
1056
1057template<class _Tp>
1058template<class _Yp>
1059inline
1060typename enable_if
1061<
1062 __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value,
1063 void
1064>::type
1065shared_ptr<_Tp>::reset(_Yp* __p)
1066{
1067 shared_ptr(__p).swap(*this);
1068}
1069
1070template<class _Tp>
1071template<class _Yp, class _Dp>
1072inline
1073typename enable_if
1074<
1075 __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value,
1076 void
1077>::type
1078shared_ptr<_Tp>::reset(_Yp* __p, _Dp __d)
1079{
1080 shared_ptr(__p, __d).swap(*this);
1081}
1082
1083template<class _Tp>
1084template<class _Yp, class _Dp, class _Alloc>
1085inline
1086typename enable_if
1087<
1088 __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value,
1089 void
1090>::type
1091shared_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//
1099template<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__
))
1101shared_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
1111template<class _Tp, class ..._Args, class = _EnableIf<!is_array<_Tp>::value> >
1112_LIBCPP_HIDE_FROM_ABI__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1113shared_ptr<_Tp> make_shared(_Args&& ...__args)
1114{
1115 return _VSTDstd::__1::allocate_shared<_Tp>(allocator<_Tp>(), _VSTDstd::__1::forward<_Args>(__args)...);
1116}
1117
1118template<class _Tp, class _Up>
1119inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1120bool
1121operator==(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPTnoexcept
1122{
1123 return __x.get() == __y.get();
1124}
1125
1126template<class _Tp, class _Up>
1127inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1128bool
1129operator!=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPTnoexcept
1130{
1131 return !(__x == __y);
1132}
1133
1134template<class _Tp, class _Up>
1135inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1136bool
1137operator<(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
1148template<class _Tp, class _Up>
1149inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1150bool
1151operator>(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPTnoexcept
1152{
1153 return __y < __x;
1154}
1155
1156template<class _Tp, class _Up>
1157inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1158bool
1159operator<=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPTnoexcept
1160{
1161 return !(__y < __x);
1162}
1163
1164template<class _Tp, class _Up>
1165inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1166bool
1167operator>=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPTnoexcept
1168{
1169 return !(__x < __y);
1170}
1171
1172template<class _Tp>
1173inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1174bool
1175operator==(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPTnoexcept
1176{
1177 return !__x;
1178}
1179
1180template<class _Tp>
1181inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1182bool
1183operator==(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPTnoexcept
1184{
1185 return !__x;
1186}
1187
1188template<class _Tp>
1189inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1190bool
1191operator!=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPTnoexcept
1192{
1193 return static_cast<bool>(__x);
1194}
1195
1196template<class _Tp>
1197inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1198bool
1199operator!=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPTnoexcept
1200{
1201 return static_cast<bool>(__x);
1202}
1203
1204template<class _Tp>
1205inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1206bool
1207operator<(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPTnoexcept
1208{
1209 return less<_Tp*>()(__x.get(), nullptr);
1210}
1211
1212template<class _Tp>
1213inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1214bool
1215operator<(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPTnoexcept
1216{
1217 return less<_Tp*>()(nullptr, __x.get());
1218}
1219
1220template<class _Tp>
1221inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1222bool
1223operator>(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPTnoexcept
1224{
1225 return nullptr < __x;
1226}
1227
1228template<class _Tp>
1229inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1230bool
1231operator>(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPTnoexcept
1232{
1233 return __x < nullptr;
1234}
1235
1236template<class _Tp>
1237inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1238bool
1239operator<=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPTnoexcept
1240{
1241 return !(nullptr < __x);
1242}
1243
1244template<class _Tp>
1245inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1246bool
1247operator<=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPTnoexcept
1248{
1249 return !(__x < nullptr);
1250}
1251
1252template<class _Tp>
1253inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1254bool
1255operator>=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPTnoexcept
1256{
1257 return !(__x < nullptr);
1258}
1259
1260template<class _Tp>
1261inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1262bool
1263operator>=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPTnoexcept
1264{
1265 return !(nullptr < __x);
1266}
1267
1268template<class _Tp>
1269inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1270void
1271swap(shared_ptr<_Tp>& __x, shared_ptr<_Tp>& __y) _NOEXCEPTnoexcept
1272{
1273 __x.swap(__y);
1274}
1275
1276template<class _Tp, class _Up>
1277inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1278shared_ptr<_Tp>
1279static_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
1286template<class _Tp, class _Up>
1287inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1288shared_ptr<_Tp>
1289dynamic_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
1296template<class _Tp, class _Up>
1297shared_ptr<_Tp>
1298const_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
1304template<class _Tp, class _Up>
1305shared_ptr<_Tp>
1306reinterpret_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
1315template<class _Dp, class _Tp>
1316inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1317_Dp*
1318get_deleter(const shared_ptr<_Tp>& __p) _NOEXCEPTnoexcept
1319{
1320 return __p.template __get_deleter<_Dp>();
1321}
1322
1323#endif // _LIBCPP_NO_RTTI
1324
1325template<class _Tp>
1326class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS__attribute__ ((__type_visibility__("default"))) weak_ptr
1327{
1328public:
1329 typedef _Tp element_type;
1330private:
1331 element_type* __ptr_;
1332 __shared_weak_count* __cntrl_;
1333
1334public:
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
1410template<class _Tp>
1411weak_ptr(shared_ptr<_Tp>) -> weak_ptr<_Tp>;
1412#endif
1413
1414template<class _Tp>
1415inline
1416_LIBCPP_CONSTEXPRconstexpr
1417weak_ptr<_Tp>::weak_ptr() _NOEXCEPTnoexcept
1418 : __ptr_(nullptr),
1419 __cntrl_(nullptr)
1420{
1421}
1422
1423template<class _Tp>
1424inline
1425weak_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
1433template<class _Tp>
1434template<class _Yp>
1435inline
1436weak_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
1446template<class _Tp>
1447template<class _Yp>
1448inline
1449weak_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
1459template<class _Tp>
1460inline
1461weak_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
1469template<class _Tp>
1470template<class _Yp>
1471inline
1472weak_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
1482template<class _Tp>
1483weak_ptr<_Tp>::~weak_ptr()
1484{
1485 if (__cntrl_)
1486 __cntrl_->__release_weak();
1487}
1488
1489template<class _Tp>
1490inline
1491weak_ptr<_Tp>&
1492weak_ptr<_Tp>::operator=(weak_ptr const& __r) _NOEXCEPTnoexcept
1493{
1494 weak_ptr(__r).swap(*this);
1495 return *this;
1496}
1497
1498template<class _Tp>
1499template<class _Yp>
1500inline
1501typename enable_if
1502<
1503 is_convertible<_Yp*, _Tp*>::value,
1504 weak_ptr<_Tp>&
1505>::type
1506weak_ptr<_Tp>::operator=(weak_ptr<_Yp> const& __r) _NOEXCEPTnoexcept
1507{
1508 weak_ptr(__r).swap(*this);
1509 return *this;
1510}
1511
1512template<class _Tp>
1513inline
1514weak_ptr<_Tp>&
1515weak_ptr<_Tp>::operator=(weak_ptr&& __r) _NOEXCEPTnoexcept
1516{
1517 weak_ptr(_VSTDstd::__1::move(__r)).swap(*this);
1518 return *this;
1519}
1520
1521template<class _Tp>
1522template<class _Yp>
1523inline
1524typename enable_if
1525<
1526 is_convertible<_Yp*, _Tp*>::value,
1527 weak_ptr<_Tp>&
1528>::type
1529weak_ptr<_Tp>::operator=(weak_ptr<_Yp>&& __r) _NOEXCEPTnoexcept
1530{
1531 weak_ptr(_VSTDstd::__1::move(__r)).swap(*this);
1532 return *this;
1533}
1534
1535template<class _Tp>
1536template<class _Yp>
1537inline
1538typename enable_if
1539<
1540 is_convertible<_Yp*, _Tp*>::value,
1541 weak_ptr<_Tp>&
1542>::type
1543weak_ptr<_Tp>::operator=(shared_ptr<_Yp> const& __r) _NOEXCEPTnoexcept
1544{
1545 weak_ptr(__r).swap(*this);
1546 return *this;
1547}
1548
1549template<class _Tp>
1550inline
1551void
1552weak_ptr<_Tp>::swap(weak_ptr& __r) _NOEXCEPTnoexcept
1553{
1554 _VSTDstd::__1::swap(__ptr_, __r.__ptr_);
1555 _VSTDstd::__1::swap(__cntrl_, __r.__cntrl_);
1556}
1557
1558template<class _Tp>
1559inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1560void
1561swap(weak_ptr<_Tp>& __x, weak_ptr<_Tp>& __y) _NOEXCEPTnoexcept
1562{
1563 __x.swap(__y);
1564}
1565
1566template<class _Tp>
1567inline
1568void
1569weak_ptr<_Tp>::reset() _NOEXCEPTnoexcept
1570{
1571 weak_ptr().swap(*this);
1572}
1573
1574template<class _Tp>
1575template<class _Yp>
1576shared_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
1585template<class _Tp>
1586shared_ptr<_Tp>
1587weak_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
1597template <class _Tp = void> struct owner_less;
1598#else
1599template <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"
1604template <class _Tp>
1605struct _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"
1628template <class _Tp>
1629struct _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
1652template <>
1653struct _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
1675template<class _Tp>
1676class _LIBCPP_TEMPLATE_VIS__attribute__ ((__type_visibility__("default"))) enable_shared_from_this
1677{
1678 mutable weak_ptr<_Tp> __weak_this_;
1679protected:
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() {}
1689public:
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
1710template <class _Tp> struct _LIBCPP_TEMPLATE_VIS__attribute__ ((__type_visibility__("default"))) hash;
1711
1712template <class _Tp>
1713struct _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
1727template<class _CharT, class _Traits, class _Yp>
1728inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1729basic_ostream<_CharT, _Traits>&
1730operator<<(basic_ostream<_CharT, _Traits>& __os, shared_ptr<_Yp> const& __p);
1731
1732
1733#if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
1734
1735class _LIBCPP_TYPE_VIS__attribute__ ((__visibility__("default"))) __sp_mut
1736{
1737 void* __lx;
1738public:
1739 void lock() _NOEXCEPTnoexcept;
1740 void unlock() _NOEXCEPTnoexcept;
1741
1742private:
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
1753template <class _Tp>
1754inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1755bool
1756atomic_is_lock_free(const shared_ptr<_Tp>*)
1757{
1758 return false;
1759}
1760
1761template <class _Tp>
1762_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
1763shared_ptr<_Tp>
1764atomic_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
1773template <class _Tp>
1774inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1775_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
1776shared_ptr<_Tp>
1777atomic_load_explicit(const shared_ptr<_Tp>* __p, memory_order)
1778{
1779 return atomic_load(__p);
1780}
1781
1782template <class _Tp>
1783_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
1784void
1785atomic_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
1793template <class _Tp>
1794inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1795_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
1796void
1797atomic_store_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r, memory_order)
1798{
1799 atomic_store(__p, __r);
1800}
1801
1802template <class _Tp>
1803_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
1804shared_ptr<_Tp>
1805atomic_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
1814template <class _Tp>
1815inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1816_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
1817shared_ptr<_Tp>
1818atomic_exchange_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r, memory_order)
1819{
1820 return atomic_exchange(__p, __r);
1821}
1822
1823template <class _Tp>
1824_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
1825bool
1826atomic_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
1844template <class _Tp>
1845inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1846_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
1847bool
1848atomic_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
1853template <class _Tp>
1854inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1855_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
1856bool
1857atomic_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
1863template <class _Tp>
1864inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1865_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
1866bool
1867atomic_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

/usr/src/gnu/usr.bin/clang/liblldbABI/../../../llvm/lldb/include/lldb/Symbol/CompilerType.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
19namespace lldb_private {
20
21class 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
33class CompilerType {
34public:
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;
7
Assuming the condition is true
8
Assuming the condition is true
9
Returning the value 1, which participates in a condition later
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
400private:
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
412bool operator==(const CompilerType &lhs, const CompilerType &rhs);
413bool operator!=(const CompilerType &lhs, const CompilerType &rhs);
414
415struct CompilerType::IntegralTemplateArgument {
416 llvm::APSInt value;
417 CompilerType type;
418};
419
420} // namespace lldb_private
421
422#endif // LLDB_SYMBOL_COMPILERTYPE_H