Bug Summary

File:tools/lldb/source/API/SBValue.cpp
Warning:line 476, column 7
Inner pointer of container used after re/deallocation

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name SBValue.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 -mrelocation-model pic -pic-level 2 -mthread-model posix -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -momit-leaf-frame-pointer -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-8/lib/clang/8.0.0 -D HAVE_ROUND -D LLDB_CONFIGURATION_RELEASE -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/tools/lldb/source/API -I /build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/API -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/tools/lldb/include -I /build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/include -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/include -I /build/llvm-toolchain-snapshot-8~svn345461/include -I /usr/include/python2.7 -I /build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/tools/lldb/../clang/include -I /build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/. -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/backward -internal-isystem /usr/include/clang/8.0.0/include/ -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-8/lib/clang/8.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-comment -Wno-deprecated-declarations -Wno-unknown-pragmas -Wno-strict-aliasing -Wno-deprecated-register -Wno-vla-extension -std=c++11 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/tools/lldb/source/API -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -o /tmp/scan-build-2018-10-27-211344-32123-1 -x c++ /build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/API/SBValue.cpp -faddrsig

/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/API/SBValue.cpp

1//===-- SBValue.cpp ---------------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lldb/API/SBValue.h"
11
12#include "lldb/API/SBDeclaration.h"
13#include "lldb/API/SBStream.h"
14#include "lldb/API/SBTypeFilter.h"
15#include "lldb/API/SBTypeFormat.h"
16#include "lldb/API/SBTypeSummary.h"
17#include "lldb/API/SBTypeSynthetic.h"
18
19#include "lldb/Breakpoint/Watchpoint.h"
20#include "lldb/Core/Module.h"
21#include "lldb/Core/Section.h"
22#include "lldb/Core/StreamFile.h"
23#include "lldb/Core/Value.h"
24#include "lldb/Core/ValueObject.h"
25#include "lldb/Core/ValueObjectConstResult.h"
26#include "lldb/DataFormatters/DataVisualization.h"
27#include "lldb/Symbol/Block.h"
28#include "lldb/Symbol/Declaration.h"
29#include "lldb/Symbol/ObjectFile.h"
30#include "lldb/Symbol/Type.h"
31#include "lldb/Symbol/Variable.h"
32#include "lldb/Symbol/VariableList.h"
33#include "lldb/Target/ExecutionContext.h"
34#include "lldb/Target/Process.h"
35#include "lldb/Target/StackFrame.h"
36#include "lldb/Target/Target.h"
37#include "lldb/Target/Thread.h"
38#include "lldb/Utility/DataExtractor.h"
39#include "lldb/Utility/Log.h"
40#include "lldb/Utility/Scalar.h"
41#include "lldb/Utility/Stream.h"
42
43#include "lldb/API/SBDebugger.h"
44#include "lldb/API/SBExpressionOptions.h"
45#include "lldb/API/SBFrame.h"
46#include "lldb/API/SBProcess.h"
47#include "lldb/API/SBTarget.h"
48#include "lldb/API/SBThread.h"
49
50using namespace lldb;
51using namespace lldb_private;
52
53class ValueImpl {
54public:
55 ValueImpl() {}
56
57 ValueImpl(lldb::ValueObjectSP in_valobj_sp,
58 lldb::DynamicValueType use_dynamic, bool use_synthetic,
59 const char *name = NULL__null)
60 : m_valobj_sp(), m_use_dynamic(use_dynamic),
61 m_use_synthetic(use_synthetic), m_name(name) {
62 if (in_valobj_sp) {
63 if ((m_valobj_sp = in_valobj_sp->GetQualifiedRepresentationIfAvailable(
64 lldb::eNoDynamicValues, false))) {
65 if (!m_name.IsEmpty())
66 m_valobj_sp->SetName(m_name);
67 }
68 }
69 }
70
71 ValueImpl(const ValueImpl &rhs)
72 : m_valobj_sp(rhs.m_valobj_sp), m_use_dynamic(rhs.m_use_dynamic),
73 m_use_synthetic(rhs.m_use_synthetic), m_name(rhs.m_name) {}
74
75 ValueImpl &operator=(const ValueImpl &rhs) {
76 if (this != &rhs) {
77 m_valobj_sp = rhs.m_valobj_sp;
78 m_use_dynamic = rhs.m_use_dynamic;
79 m_use_synthetic = rhs.m_use_synthetic;
80 m_name = rhs.m_name;
81 }
82 return *this;
83 }
84
85 bool IsValid() {
86 if (m_valobj_sp.get() == NULL__null)
87 return false;
88 else {
89 // FIXME: This check is necessary but not sufficient. We for sure don't
90 // want to touch SBValues whose owning
91 // targets have gone away. This check is a little weak in that it
92 // enforces that restriction when you call IsValid, but since IsValid
93 // doesn't lock the target, you have no guarantee that the SBValue won't
94 // go invalid after you call this... Also, an SBValue could depend on
95 // data from one of the modules in the target, and those could go away
96 // independently of the target, for instance if a module is unloaded.
97 // But right now, neither SBValues nor ValueObjects know which modules
98 // they depend on. So I have no good way to make that check without
99 // tracking that in all the ValueObject subclasses.
100 TargetSP target_sp = m_valobj_sp->GetTargetSP();
101 if (target_sp && target_sp->IsValid())
102 return true;
103 else
104 return false;
105 }
106 }
107
108 lldb::ValueObjectSP GetRootSP() { return m_valobj_sp; }
109
110 lldb::ValueObjectSP GetSP(Process::StopLocker &stop_locker,
111 std::unique_lock<std::recursive_mutex> &lock,
112 Status &error) {
113 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
114 if (!m_valobj_sp) {
115 error.SetErrorString("invalid value object");
116 return m_valobj_sp;
117 }
118
119 lldb::ValueObjectSP value_sp = m_valobj_sp;
120
121 Target *target = value_sp->GetTargetSP().get();
122 if (!target)
123 return ValueObjectSP();
124
125 lock = std::unique_lock<std::recursive_mutex>(target->GetAPIMutex());
126
127 ProcessSP process_sp(value_sp->GetProcessSP());
128 if (process_sp && !stop_locker.TryLock(&process_sp->GetRunLock())) {
129 // We don't allow people to play around with ValueObject if the process
130 // is running. If you want to look at values, pause the process, then
131 // look.
132 if (log)
133 log->Printf("SBValue(%p)::GetSP() => error: process is running",
134 static_cast<void *>(value_sp.get()));
135 error.SetErrorString("process must be stopped.");
136 return ValueObjectSP();
137 }
138
139 if (m_use_dynamic != eNoDynamicValues) {
140 ValueObjectSP dynamic_sp = value_sp->GetDynamicValue(m_use_dynamic);
141 if (dynamic_sp)
142 value_sp = dynamic_sp;
143 }
144
145 if (m_use_synthetic) {
146 ValueObjectSP synthetic_sp = value_sp->GetSyntheticValue(m_use_synthetic);
147 if (synthetic_sp)
148 value_sp = synthetic_sp;
149 }
150
151 if (!value_sp)
152 error.SetErrorString("invalid value object");
153 if (!m_name.IsEmpty())
154 value_sp->SetName(m_name);
155
156 return value_sp;
157 }
158
159 void SetUseDynamic(lldb::DynamicValueType use_dynamic) {
160 m_use_dynamic = use_dynamic;
161 }
162
163 void SetUseSynthetic(bool use_synthetic) { m_use_synthetic = use_synthetic; }
164
165 lldb::DynamicValueType GetUseDynamic() { return m_use_dynamic; }
166
167 bool GetUseSynthetic() { return m_use_synthetic; }
168
169 // All the derived values that we would make from the m_valobj_sp will share
170 // the ExecutionContext with m_valobj_sp, so we don't need to do the
171 // calculations in GetSP to return the Target, Process, Thread or Frame. It
172 // is convenient to provide simple accessors for these, which I do here.
173 TargetSP GetTargetSP() {
174 if (m_valobj_sp)
175 return m_valobj_sp->GetTargetSP();
176 else
177 return TargetSP();
178 }
179
180 ProcessSP GetProcessSP() {
181 if (m_valobj_sp)
182 return m_valobj_sp->GetProcessSP();
183 else
184 return ProcessSP();
185 }
186
187 ThreadSP GetThreadSP() {
188 if (m_valobj_sp)
189 return m_valobj_sp->GetThreadSP();
190 else
191 return ThreadSP();
192 }
193
194 StackFrameSP GetFrameSP() {
195 if (m_valobj_sp)
196 return m_valobj_sp->GetFrameSP();
197 else
198 return StackFrameSP();
199 }
200
201private:
202 lldb::ValueObjectSP m_valobj_sp;
203 lldb::DynamicValueType m_use_dynamic;
204 bool m_use_synthetic;
205 ConstString m_name;
206};
207
208class ValueLocker {
209public:
210 ValueLocker() {}
211
212 ValueObjectSP GetLockedSP(ValueImpl &in_value) {
213 return in_value.GetSP(m_stop_locker, m_lock, m_lock_error);
214 }
215
216 Status &GetError() { return m_lock_error; }
217
218private:
219 Process::StopLocker m_stop_locker;
220 std::unique_lock<std::recursive_mutex> m_lock;
221 Status m_lock_error;
222};
223
224SBValue::SBValue() : m_opaque_sp() {}
225
226SBValue::SBValue(const lldb::ValueObjectSP &value_sp) { SetSP(value_sp); }
227
228SBValue::SBValue(const SBValue &rhs) { SetSP(rhs.m_opaque_sp); }
229
230SBValue &SBValue::operator=(const SBValue &rhs) {
231 if (this != &rhs) {
232 SetSP(rhs.m_opaque_sp);
233 }
234 return *this;
235}
236
237SBValue::~SBValue() {}
238
239bool SBValue::IsValid() {
240 // If this function ever changes to anything that does more than just check
241 // if the opaque shared pointer is non NULL, then we need to update all "if
242 // (m_opaque_sp)" code in this file.
243 return m_opaque_sp.get() != NULL__null && m_opaque_sp->IsValid() &&
244 m_opaque_sp->GetRootSP().get() != NULL__null;
245}
246
247void SBValue::Clear() { m_opaque_sp.reset(); }
248
249SBError SBValue::GetError() {
250 SBError sb_error;
251
252 ValueLocker locker;
253 lldb::ValueObjectSP value_sp(GetSP(locker));
254 if (value_sp)
255 sb_error.SetError(value_sp->GetError());
256 else
257 sb_error.SetErrorStringWithFormat("error: %s",
258 locker.GetError().AsCString());
259
260 return sb_error;
261}
262
263user_id_t SBValue::GetID() {
264 ValueLocker locker;
265 lldb::ValueObjectSP value_sp(GetSP(locker));
266 if (value_sp)
267 return value_sp->GetID();
268 return LLDB_INVALID_UID(18446744073709551615UL);
269}
270
271const char *SBValue::GetName() {
272 const char *name = NULL__null;
273 ValueLocker locker;
274 lldb::ValueObjectSP value_sp(GetSP(locker));
275 if (value_sp)
276 name = value_sp->GetName().GetCString();
277
278 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
279 if (log) {
280 if (name)
281 log->Printf("SBValue(%p)::GetName () => \"%s\"",
282 static_cast<void *>(value_sp.get()), name);
283 else
284 log->Printf("SBValue(%p)::GetName () => NULL",
285 static_cast<void *>(value_sp.get()));
286 }
287
288 return name;
289}
290
291const char *SBValue::GetTypeName() {
292 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
293 const char *name = NULL__null;
294 ValueLocker locker;
295 lldb::ValueObjectSP value_sp(GetSP(locker));
296 if (value_sp) {
297 name = value_sp->GetQualifiedTypeName().GetCString();
298 }
299
300 if (log) {
301 if (name)
302 log->Printf("SBValue(%p)::GetTypeName () => \"%s\"",
303 static_cast<void *>(value_sp.get()), name);
304 else
305 log->Printf("SBValue(%p)::GetTypeName () => NULL",
306 static_cast<void *>(value_sp.get()));
307 }
308
309 return name;
310}
311
312const char *SBValue::GetDisplayTypeName() {
313 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
314 const char *name = NULL__null;
315 ValueLocker locker;
316 lldb::ValueObjectSP value_sp(GetSP(locker));
317 if (value_sp) {
318 name = value_sp->GetDisplayTypeName().GetCString();
319 }
320
321 if (log) {
322 if (name)
323 log->Printf("SBValue(%p)::GetTypeName () => \"%s\"",
324 static_cast<void *>(value_sp.get()), name);
325 else
326 log->Printf("SBValue(%p)::GetTypeName () => NULL",
327 static_cast<void *>(value_sp.get()));
328 }
329
330 return name;
331}
332
333size_t SBValue::GetByteSize() {
334 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
335 size_t result = 0;
336
337 ValueLocker locker;
338 lldb::ValueObjectSP value_sp(GetSP(locker));
339 if (value_sp) {
340 result = value_sp->GetByteSize();
341 }
342
343 if (log)
344 log->Printf("SBValue(%p)::GetByteSize () => %" PRIu64"l" "u",
345 static_cast<void *>(value_sp.get()),
346 static_cast<uint64_t>(result));
347
348 return result;
349}
350
351bool SBValue::IsInScope() {
352 bool result = false;
353
354 ValueLocker locker;
355 lldb::ValueObjectSP value_sp(GetSP(locker));
356 if (value_sp) {
357 result = value_sp->IsInScope();
358 }
359
360 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
361 if (log)
362 log->Printf("SBValue(%p)::IsInScope () => %i",
363 static_cast<void *>(value_sp.get()), result);
364
365 return result;
366}
367
368const char *SBValue::GetValue() {
369 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
370
371 const char *cstr = NULL__null;
372 ValueLocker locker;
373 lldb::ValueObjectSP value_sp(GetSP(locker));
374 if (value_sp) {
375 cstr = value_sp->GetValueAsCString();
376 }
377 if (log) {
378 if (cstr)
379 log->Printf("SBValue(%p)::GetValue() => \"%s\"",
380 static_cast<void *>(value_sp.get()), cstr);
381 else
382 log->Printf("SBValue(%p)::GetValue() => NULL",
383 static_cast<void *>(value_sp.get()));
384 }
385
386 return cstr;
387}
388
389ValueType SBValue::GetValueType() {
390 ValueType result = eValueTypeInvalid;
391 ValueLocker locker;
392 lldb::ValueObjectSP value_sp(GetSP(locker));
393 if (value_sp)
394 result = value_sp->GetValueType();
395
396 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
397 if (log) {
398 switch (result) {
399 case eValueTypeInvalid:
400 log->Printf("SBValue(%p)::GetValueType () => eValueTypeInvalid",
401 static_cast<void *>(value_sp.get()));
402 break;
403 case eValueTypeVariableGlobal:
404 log->Printf("SBValue(%p)::GetValueType () => eValueTypeVariableGlobal",
405 static_cast<void *>(value_sp.get()));
406 break;
407 case eValueTypeVariableStatic:
408 log->Printf("SBValue(%p)::GetValueType () => eValueTypeVariableStatic",
409 static_cast<void *>(value_sp.get()));
410 break;
411 case eValueTypeVariableArgument:
412 log->Printf("SBValue(%p)::GetValueType () => eValueTypeVariableArgument",
413 static_cast<void *>(value_sp.get()));
414 break;
415 case eValueTypeVariableLocal:
416 log->Printf("SBValue(%p)::GetValueType () => eValueTypeVariableLocal",
417 static_cast<void *>(value_sp.get()));
418 break;
419 case eValueTypeRegister:
420 log->Printf("SBValue(%p)::GetValueType () => eValueTypeRegister",
421 static_cast<void *>(value_sp.get()));
422 break;
423 case eValueTypeRegisterSet:
424 log->Printf("SBValue(%p)::GetValueType () => eValueTypeRegisterSet",
425 static_cast<void *>(value_sp.get()));
426 break;
427 case eValueTypeConstResult:
428 log->Printf("SBValue(%p)::GetValueType () => eValueTypeConstResult",
429 static_cast<void *>(value_sp.get()));
430 break;
431 case eValueTypeVariableThreadLocal:
432 log->Printf(
433 "SBValue(%p)::GetValueType () => eValueTypeVariableThreadLocal",
434 static_cast<void *>(value_sp.get()));
435 break;
436 }
437 }
438 return result;
439}
440
441const char *SBValue::GetObjectDescription() {
442 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
443 const char *cstr = NULL__null;
444 ValueLocker locker;
445 lldb::ValueObjectSP value_sp(GetSP(locker));
446 if (value_sp) {
447 cstr = value_sp->GetObjectDescription();
448 }
449 if (log) {
450 if (cstr)
451 log->Printf("SBValue(%p)::GetObjectDescription() => \"%s\"",
452 static_cast<void *>(value_sp.get()), cstr);
453 else
454 log->Printf("SBValue(%p)::GetObjectDescription() => NULL",
455 static_cast<void *>(value_sp.get()));
456 }
457 return cstr;
458}
459
460const char *SBValue::GetTypeValidatorResult() {
461 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
462 const char *cstr = NULL__null;
463 ValueLocker locker;
464 lldb::ValueObjectSP value_sp(GetSP(locker));
465 if (value_sp) {
1
Assuming the condition is true
2
Taking true branch
466 const auto &validation(value_sp->GetValidationStatus());
467 if (TypeValidatorResult::Failure == validation.first) {
3
Assuming the condition is true
4
Taking true branch
468 if (validation.second.empty())
5
Assuming the condition is false
6
Taking false branch
469 cstr = "unknown error";
470 else
471 cstr = validation.second.c_str();
7
Pointer to inner buffer of 'class std::__cxx11::basic_string<char>' obtained here
472 }
473 }
8
Calling implicit destructor for 'pair<lldb_private::TypeValidatorResult, std::__cxx11::basic_string<char>>'
10
Returning from destructor for 'pair<lldb_private::TypeValidatorResult, std::__cxx11::basic_string<char>>'
474 if (log) {
11
Assuming 'log' is non-null
12
Taking true branch
475 if (cstr)
13
Assuming 'cstr' is non-null
14
Taking true branch
476 log->Printf("SBValue(%p)::GetTypeValidatorResult() => \"%s\"",
15
Inner pointer of container used after re/deallocation
477 static_cast<void *>(value_sp.get()), cstr);
478 else
479 log->Printf("SBValue(%p)::GetTypeValidatorResult() => NULL",
480 static_cast<void *>(value_sp.get()));
481 }
482 return cstr;
483}
484
485SBType SBValue::GetType() {
486 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
487 SBType sb_type;
488 ValueLocker locker;
489 lldb::ValueObjectSP value_sp(GetSP(locker));
490 TypeImplSP type_sp;
491 if (value_sp) {
492 type_sp.reset(new TypeImpl(value_sp->GetTypeImpl()));
493 sb_type.SetSP(type_sp);
494 }
495 if (log) {
496 if (type_sp)
497 log->Printf("SBValue(%p)::GetType => SBType(%p)",
498 static_cast<void *>(value_sp.get()),
499 static_cast<void *>(type_sp.get()));
500 else
501 log->Printf("SBValue(%p)::GetType => NULL",
502 static_cast<void *>(value_sp.get()));
503 }
504 return sb_type;
505}
506
507bool SBValue::GetValueDidChange() {
508 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
509 bool result = false;
510 ValueLocker locker;
511 lldb::ValueObjectSP value_sp(GetSP(locker));
512 if (value_sp) {
513 if (value_sp->UpdateValueIfNeeded(false))
514 result = value_sp->GetValueDidChange();
515 }
516 if (log)
517 log->Printf("SBValue(%p)::GetValueDidChange() => %i",
518 static_cast<void *>(value_sp.get()), result);
519
520 return result;
521}
522
523const char *SBValue::GetSummary() {
524 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
525 const char *cstr = NULL__null;
526 ValueLocker locker;
527 lldb::ValueObjectSP value_sp(GetSP(locker));
528 if (value_sp) {
529 cstr = value_sp->GetSummaryAsCString();
530 }
531 if (log) {
532 if (cstr)
533 log->Printf("SBValue(%p)::GetSummary() => \"%s\"",
534 static_cast<void *>(value_sp.get()), cstr);
535 else
536 log->Printf("SBValue(%p)::GetSummary() => NULL",
537 static_cast<void *>(value_sp.get()));
538 }
539 return cstr;
540}
541
542const char *SBValue::GetSummary(lldb::SBStream &stream,
543 lldb::SBTypeSummaryOptions &options) {
544 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
545 ValueLocker locker;
546 lldb::ValueObjectSP value_sp(GetSP(locker));
547 if (value_sp) {
548 std::string buffer;
549 if (value_sp->GetSummaryAsCString(buffer, options.ref()) && !buffer.empty())
550 stream.Printf("%s", buffer.c_str());
551 }
552 const char *cstr = stream.GetData();
553 if (log) {
554 if (cstr)
555 log->Printf("SBValue(%p)::GetSummary() => \"%s\"",
556 static_cast<void *>(value_sp.get()), cstr);
557 else
558 log->Printf("SBValue(%p)::GetSummary() => NULL",
559 static_cast<void *>(value_sp.get()));
560 }
561 return cstr;
562}
563
564const char *SBValue::GetLocation() {
565 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
566 const char *cstr = NULL__null;
567 ValueLocker locker;
568 lldb::ValueObjectSP value_sp(GetSP(locker));
569 if (value_sp) {
570 cstr = value_sp->GetLocationAsCString();
571 }
572 if (log) {
573 if (cstr)
574 log->Printf("SBValue(%p)::GetLocation() => \"%s\"",
575 static_cast<void *>(value_sp.get()), cstr);
576 else
577 log->Printf("SBValue(%p)::GetLocation() => NULL",
578 static_cast<void *>(value_sp.get()));
579 }
580 return cstr;
581}
582
583// Deprecated - use the one that takes an lldb::SBError
584bool SBValue::SetValueFromCString(const char *value_str) {
585 lldb::SBError dummy;
586 return SetValueFromCString(value_str, dummy);
587}
588
589bool SBValue::SetValueFromCString(const char *value_str, lldb::SBError &error) {
590 bool success = false;
591 ValueLocker locker;
592 lldb::ValueObjectSP value_sp(GetSP(locker));
593 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
594 if (value_sp) {
595 success = value_sp->SetValueFromCString(value_str, error.ref());
596 } else
597 error.SetErrorStringWithFormat("Could not get value: %s",
598 locker.GetError().AsCString());
599
600 if (log)
601 log->Printf("SBValue(%p)::SetValueFromCString(\"%s\") => %i",
602 static_cast<void *>(value_sp.get()), value_str, success);
603
604 return success;
605}
606
607lldb::SBTypeFormat SBValue::GetTypeFormat() {
608 lldb::SBTypeFormat format;
609 ValueLocker locker;
610 lldb::ValueObjectSP value_sp(GetSP(locker));
611 if (value_sp) {
612 if (value_sp->UpdateValueIfNeeded(true)) {
613 lldb::TypeFormatImplSP format_sp = value_sp->GetValueFormat();
614 if (format_sp)
615 format.SetSP(format_sp);
616 }
617 }
618 return format;
619}
620
621lldb::SBTypeSummary SBValue::GetTypeSummary() {
622 lldb::SBTypeSummary summary;
623 ValueLocker locker;
624 lldb::ValueObjectSP value_sp(GetSP(locker));
625 if (value_sp) {
626 if (value_sp->UpdateValueIfNeeded(true)) {
627 lldb::TypeSummaryImplSP summary_sp = value_sp->GetSummaryFormat();
628 if (summary_sp)
629 summary.SetSP(summary_sp);
630 }
631 }
632 return summary;
633}
634
635lldb::SBTypeFilter SBValue::GetTypeFilter() {
636 lldb::SBTypeFilter filter;
637 ValueLocker locker;
638 lldb::ValueObjectSP value_sp(GetSP(locker));
639 if (value_sp) {
640 if (value_sp->UpdateValueIfNeeded(true)) {
641 lldb::SyntheticChildrenSP synthetic_sp = value_sp->GetSyntheticChildren();
642
643 if (synthetic_sp && !synthetic_sp->IsScripted()) {
644 TypeFilterImplSP filter_sp =
645 std::static_pointer_cast<TypeFilterImpl>(synthetic_sp);
646 filter.SetSP(filter_sp);
647 }
648 }
649 }
650 return filter;
651}
652
653#ifndef LLDB_DISABLE_PYTHON
654lldb::SBTypeSynthetic SBValue::GetTypeSynthetic() {
655 lldb::SBTypeSynthetic synthetic;
656 ValueLocker locker;
657 lldb::ValueObjectSP value_sp(GetSP(locker));
658 if (value_sp) {
659 if (value_sp->UpdateValueIfNeeded(true)) {
660 lldb::SyntheticChildrenSP children_sp = value_sp->GetSyntheticChildren();
661
662 if (children_sp && children_sp->IsScripted()) {
663 ScriptedSyntheticChildrenSP synth_sp =
664 std::static_pointer_cast<ScriptedSyntheticChildren>(children_sp);
665 synthetic.SetSP(synth_sp);
666 }
667 }
668 }
669 return synthetic;
670}
671#endif
672
673lldb::SBValue SBValue::CreateChildAtOffset(const char *name, uint32_t offset,
674 SBType type) {
675 lldb::SBValue sb_value;
676 ValueLocker locker;
677 lldb::ValueObjectSP value_sp(GetSP(locker));
678 lldb::ValueObjectSP new_value_sp;
679 if (value_sp) {
680 TypeImplSP type_sp(type.GetSP());
681 if (type.IsValid()) {
682 sb_value.SetSP(value_sp->GetSyntheticChildAtOffset(
683 offset, type_sp->GetCompilerType(false), true),
684 GetPreferDynamicValue(), GetPreferSyntheticValue(), name);
685 }
686 }
687 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
688 if (log) {
689 if (new_value_sp)
690 log->Printf("SBValue(%p)::CreateChildAtOffset => \"%s\"",
691 static_cast<void *>(value_sp.get()),
692 new_value_sp->GetName().AsCString());
693 else
694 log->Printf("SBValue(%p)::CreateChildAtOffset => NULL",
695 static_cast<void *>(value_sp.get()));
696 }
697 return sb_value;
698}
699
700lldb::SBValue SBValue::Cast(SBType type) {
701 lldb::SBValue sb_value;
702 ValueLocker locker;
703 lldb::ValueObjectSP value_sp(GetSP(locker));
704 TypeImplSP type_sp(type.GetSP());
705 if (value_sp && type_sp)
706 sb_value.SetSP(value_sp->Cast(type_sp->GetCompilerType(false)),
707 GetPreferDynamicValue(), GetPreferSyntheticValue());
708 return sb_value;
709}
710
711lldb::SBValue SBValue::CreateValueFromExpression(const char *name,
712 const char *expression) {
713 SBExpressionOptions options;
714 options.ref().SetKeepInMemory(true);
715 return CreateValueFromExpression(name, expression, options);
716}
717
718lldb::SBValue SBValue::CreateValueFromExpression(const char *name,
719 const char *expression,
720 SBExpressionOptions &options) {
721 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
722 lldb::SBValue sb_value;
723 ValueLocker locker;
724 lldb::ValueObjectSP value_sp(GetSP(locker));
725 lldb::ValueObjectSP new_value_sp;
726 if (value_sp) {
727 ExecutionContext exe_ctx(value_sp->GetExecutionContextRef());
728 new_value_sp = ValueObject::CreateValueObjectFromExpression(
729 name, expression, exe_ctx, options.ref());
730 if (new_value_sp)
731 new_value_sp->SetName(ConstString(name));
732 }
733 sb_value.SetSP(new_value_sp);
734 if (log) {
735 if (new_value_sp)
736 log->Printf("SBValue(%p)::CreateValueFromExpression(name=\"%s\", "
737 "expression=\"%s\") => SBValue (%p)",
738 static_cast<void *>(value_sp.get()), name, expression,
739 static_cast<void *>(new_value_sp.get()));
740 else
741 log->Printf("SBValue(%p)::CreateValueFromExpression(name=\"%s\", "
742 "expression=\"%s\") => NULL",
743 static_cast<void *>(value_sp.get()), name, expression);
744 }
745 return sb_value;
746}
747
748lldb::SBValue SBValue::CreateValueFromAddress(const char *name,
749 lldb::addr_t address,
750 SBType sb_type) {
751 lldb::SBValue sb_value;
752 ValueLocker locker;
753 lldb::ValueObjectSP value_sp(GetSP(locker));
754 lldb::ValueObjectSP new_value_sp;
755 lldb::TypeImplSP type_impl_sp(sb_type.GetSP());
756 if (value_sp && type_impl_sp) {
757 CompilerType ast_type(type_impl_sp->GetCompilerType(true));
758 ExecutionContext exe_ctx(value_sp->GetExecutionContextRef());
759 new_value_sp = ValueObject::CreateValueObjectFromAddress(name, address,
760 exe_ctx, ast_type);
761 }
762 sb_value.SetSP(new_value_sp);
763 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
764 if (log) {
765 if (new_value_sp)
766 log->Printf("SBValue(%p)::CreateValueFromAddress => \"%s\"",
767 static_cast<void *>(value_sp.get()),
768 new_value_sp->GetName().AsCString());
769 else
770 log->Printf("SBValue(%p)::CreateValueFromAddress => NULL",
771 static_cast<void *>(value_sp.get()));
772 }
773 return sb_value;
774}
775
776lldb::SBValue SBValue::CreateValueFromData(const char *name, SBData data,
777 SBType sb_type) {
778 lldb::SBValue sb_value;
779 lldb::ValueObjectSP new_value_sp;
780 ValueLocker locker;
781 lldb::ValueObjectSP value_sp(GetSP(locker));
782 lldb::TypeImplSP type_impl_sp(sb_type.GetSP());
783 if (value_sp && type_impl_sp) {
784 ExecutionContext exe_ctx(value_sp->GetExecutionContextRef());
785 new_value_sp = ValueObject::CreateValueObjectFromData(
786 name, **data, exe_ctx, type_impl_sp->GetCompilerType(true));
787 new_value_sp->SetAddressTypeOfChildren(eAddressTypeLoad);
788 }
789 sb_value.SetSP(new_value_sp);
790 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
791 if (log) {
792 if (new_value_sp)
793 log->Printf("SBValue(%p)::CreateValueFromData => \"%s\"",
794 static_cast<void *>(value_sp.get()),
795 new_value_sp->GetName().AsCString());
796 else
797 log->Printf("SBValue(%p)::CreateValueFromData => NULL",
798 static_cast<void *>(value_sp.get()));
799 }
800 return sb_value;
801}
802
803SBValue SBValue::GetChildAtIndex(uint32_t idx) {
804 const bool can_create_synthetic = false;
805 lldb::DynamicValueType use_dynamic = eNoDynamicValues;
806 TargetSP target_sp;
807 if (m_opaque_sp)
808 target_sp = m_opaque_sp->GetTargetSP();
809
810 if (target_sp)
811 use_dynamic = target_sp->GetPreferDynamicValue();
812
813 return GetChildAtIndex(idx, use_dynamic, can_create_synthetic);
814}
815
816SBValue SBValue::GetChildAtIndex(uint32_t idx,
817 lldb::DynamicValueType use_dynamic,
818 bool can_create_synthetic) {
819 lldb::ValueObjectSP child_sp;
820 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
821
822 ValueLocker locker;
823 lldb::ValueObjectSP value_sp(GetSP(locker));
824 if (value_sp) {
825 const bool can_create = true;
826 child_sp = value_sp->GetChildAtIndex(idx, can_create);
827 if (can_create_synthetic && !child_sp) {
828 child_sp = value_sp->GetSyntheticArrayMember(idx, can_create);
829 }
830 }
831
832 SBValue sb_value;
833 sb_value.SetSP(child_sp, use_dynamic, GetPreferSyntheticValue());
834 if (log)
835 log->Printf("SBValue(%p)::GetChildAtIndex (%u) => SBValue(%p)",
836 static_cast<void *>(value_sp.get()), idx,
837 static_cast<void *>(value_sp.get()));
838
839 return sb_value;
840}
841
842uint32_t SBValue::GetIndexOfChildWithName(const char *name) {
843 uint32_t idx = UINT32_MAX(4294967295U);
844 ValueLocker locker;
845 lldb::ValueObjectSP value_sp(GetSP(locker));
846 if (value_sp) {
847 idx = value_sp->GetIndexOfChildWithName(ConstString(name));
848 }
849 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
850 if (log) {
851 if (idx == UINT32_MAX(4294967295U))
852 log->Printf(
853 "SBValue(%p)::GetIndexOfChildWithName (name=\"%s\") => NOT FOUND",
854 static_cast<void *>(value_sp.get()), name);
855 else
856 log->Printf("SBValue(%p)::GetIndexOfChildWithName (name=\"%s\") => %u",
857 static_cast<void *>(value_sp.get()), name, idx);
858 }
859 return idx;
860}
861
862SBValue SBValue::GetChildMemberWithName(const char *name) {
863 lldb::DynamicValueType use_dynamic_value = eNoDynamicValues;
864 TargetSP target_sp;
865 if (m_opaque_sp)
866 target_sp = m_opaque_sp->GetTargetSP();
867
868 if (target_sp)
869 use_dynamic_value = target_sp->GetPreferDynamicValue();
870 return GetChildMemberWithName(name, use_dynamic_value);
871}
872
873SBValue
874SBValue::GetChildMemberWithName(const char *name,
875 lldb::DynamicValueType use_dynamic_value) {
876 lldb::ValueObjectSP child_sp;
877 const ConstString str_name(name);
878
879 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
880
881 ValueLocker locker;
882 lldb::ValueObjectSP value_sp(GetSP(locker));
883 if (value_sp) {
884 child_sp = value_sp->GetChildMemberWithName(str_name, true);
885 }
886
887 SBValue sb_value;
888 sb_value.SetSP(child_sp, use_dynamic_value, GetPreferSyntheticValue());
889
890 if (log)
891 log->Printf(
892 "SBValue(%p)::GetChildMemberWithName (name=\"%s\") => SBValue(%p)",
893 static_cast<void *>(value_sp.get()), name,
894 static_cast<void *>(value_sp.get()));
895
896 return sb_value;
897}
898
899lldb::SBValue SBValue::GetDynamicValue(lldb::DynamicValueType use_dynamic) {
900 SBValue value_sb;
901 if (IsValid()) {
902 ValueImplSP proxy_sp(new ValueImpl(m_opaque_sp->GetRootSP(), use_dynamic,
903 m_opaque_sp->GetUseSynthetic()));
904 value_sb.SetSP(proxy_sp);
905 }
906 return value_sb;
907}
908
909lldb::SBValue SBValue::GetStaticValue() {
910 SBValue value_sb;
911 if (IsValid()) {
912 ValueImplSP proxy_sp(new ValueImpl(m_opaque_sp->GetRootSP(),
913 eNoDynamicValues,
914 m_opaque_sp->GetUseSynthetic()));
915 value_sb.SetSP(proxy_sp);
916 }
917 return value_sb;
918}
919
920lldb::SBValue SBValue::GetNonSyntheticValue() {
921 SBValue value_sb;
922 if (IsValid()) {
923 ValueImplSP proxy_sp(new ValueImpl(m_opaque_sp->GetRootSP(),
924 m_opaque_sp->GetUseDynamic(), false));
925 value_sb.SetSP(proxy_sp);
926 }
927 return value_sb;
928}
929
930lldb::DynamicValueType SBValue::GetPreferDynamicValue() {
931 if (!IsValid())
932 return eNoDynamicValues;
933 return m_opaque_sp->GetUseDynamic();
934}
935
936void SBValue::SetPreferDynamicValue(lldb::DynamicValueType use_dynamic) {
937 if (IsValid())
938 return m_opaque_sp->SetUseDynamic(use_dynamic);
939}
940
941bool SBValue::GetPreferSyntheticValue() {
942 if (!IsValid())
943 return false;
944 return m_opaque_sp->GetUseSynthetic();
945}
946
947void SBValue::SetPreferSyntheticValue(bool use_synthetic) {
948 if (IsValid())
949 return m_opaque_sp->SetUseSynthetic(use_synthetic);
950}
951
952bool SBValue::IsDynamic() {
953 ValueLocker locker;
954 lldb::ValueObjectSP value_sp(GetSP(locker));
955 if (value_sp)
956 return value_sp->IsDynamic();
957 return false;
958}
959
960bool SBValue::IsSynthetic() {
961 ValueLocker locker;
962 lldb::ValueObjectSP value_sp(GetSP(locker));
963 if (value_sp)
964 return value_sp->IsSynthetic();
965 return false;
966}
967
968bool SBValue::IsSyntheticChildrenGenerated() {
969 ValueLocker locker;
970 lldb::ValueObjectSP value_sp(GetSP(locker));
971 if (value_sp)
972 return value_sp->IsSyntheticChildrenGenerated();
973 return false;
974}
975
976void SBValue::SetSyntheticChildrenGenerated(bool is) {
977 ValueLocker locker;
978 lldb::ValueObjectSP value_sp(GetSP(locker));
979 if (value_sp)
980 return value_sp->SetSyntheticChildrenGenerated(is);
981}
982
983lldb::SBValue SBValue::GetValueForExpressionPath(const char *expr_path) {
984 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
985 lldb::ValueObjectSP child_sp;
986 ValueLocker locker;
987 lldb::ValueObjectSP value_sp(GetSP(locker));
988 if (value_sp) {
989 // using default values for all the fancy options, just do it if you can
990 child_sp = value_sp->GetValueForExpressionPath(expr_path);
991 }
992
993 SBValue sb_value;
994 sb_value.SetSP(child_sp, GetPreferDynamicValue(), GetPreferSyntheticValue());
995
996 if (log)
997 log->Printf("SBValue(%p)::GetValueForExpressionPath (expr_path=\"%s\") => "
998 "SBValue(%p)",
999 static_cast<void *>(value_sp.get()), expr_path,
1000 static_cast<void *>(value_sp.get()));
1001
1002 return sb_value;
1003}
1004
1005int64_t SBValue::GetValueAsSigned(SBError &error, int64_t fail_value) {
1006 error.Clear();
1007 ValueLocker locker;
1008 lldb::ValueObjectSP value_sp(GetSP(locker));
1009 if (value_sp) {
1010 bool success = true;
1011 uint64_t ret_val = fail_value;
1012 ret_val = value_sp->GetValueAsSigned(fail_value, &success);
1013 if (!success)
1014 error.SetErrorString("could not resolve value");
1015 return ret_val;
1016 } else
1017 error.SetErrorStringWithFormat("could not get SBValue: %s",
1018 locker.GetError().AsCString());
1019
1020 return fail_value;
1021}
1022
1023uint64_t SBValue::GetValueAsUnsigned(SBError &error, uint64_t fail_value) {
1024 error.Clear();
1025 ValueLocker locker;
1026 lldb::ValueObjectSP value_sp(GetSP(locker));
1027 if (value_sp) {
1028 bool success = true;
1029 uint64_t ret_val = fail_value;
1030 ret_val = value_sp->GetValueAsUnsigned(fail_value, &success);
1031 if (!success)
1032 error.SetErrorString("could not resolve value");
1033 return ret_val;
1034 } else
1035 error.SetErrorStringWithFormat("could not get SBValue: %s",
1036 locker.GetError().AsCString());
1037
1038 return fail_value;
1039}
1040
1041int64_t SBValue::GetValueAsSigned(int64_t fail_value) {
1042 ValueLocker locker;
1043 lldb::ValueObjectSP value_sp(GetSP(locker));
1044 if (value_sp) {
1045 return value_sp->GetValueAsSigned(fail_value);
1046 }
1047 return fail_value;
1048}
1049
1050uint64_t SBValue::GetValueAsUnsigned(uint64_t fail_value) {
1051 ValueLocker locker;
1052 lldb::ValueObjectSP value_sp(GetSP(locker));
1053 if (value_sp) {
1054 return value_sp->GetValueAsUnsigned(fail_value);
1055 }
1056 return fail_value;
1057}
1058
1059bool SBValue::MightHaveChildren() {
1060 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
1061 bool has_children = false;
1062 ValueLocker locker;
1063 lldb::ValueObjectSP value_sp(GetSP(locker));
1064 if (value_sp)
1065 has_children = value_sp->MightHaveChildren();
1066
1067 if (log)
1068 log->Printf("SBValue(%p)::MightHaveChildren() => %i",
1069 static_cast<void *>(value_sp.get()), has_children);
1070 return has_children;
1071}
1072
1073bool SBValue::IsRuntimeSupportValue() {
1074 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
1075 bool is_support = false;
1076 ValueLocker locker;
1077 lldb::ValueObjectSP value_sp(GetSP(locker));
1078 if (value_sp)
1079 is_support = value_sp->IsRuntimeSupportValue();
1080
1081 if (log)
1082 log->Printf("SBValue(%p)::IsRuntimeSupportValue() => %i",
1083 static_cast<void *>(value_sp.get()), is_support);
1084 return is_support;
1085}
1086
1087uint32_t SBValue::GetNumChildren() { return GetNumChildren(UINT32_MAX(4294967295U)); }
1088
1089uint32_t SBValue::GetNumChildren(uint32_t max) {
1090 uint32_t num_children = 0;
1091
1092 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
1093 ValueLocker locker;
1094 lldb::ValueObjectSP value_sp(GetSP(locker));
1095 if (value_sp)
1096 num_children = value_sp->GetNumChildren(max);
1097
1098 if (log)
1099 log->Printf("SBValue(%p)::GetNumChildren (%u) => %u",
1100 static_cast<void *>(value_sp.get()), max, num_children);
1101
1102 return num_children;
1103}
1104
1105SBValue SBValue::Dereference() {
1106 SBValue sb_value;
1107 ValueLocker locker;
1108 lldb::ValueObjectSP value_sp(GetSP(locker));
1109 if (value_sp) {
1110 Status error;
1111 sb_value = value_sp->Dereference(error);
1112 }
1113 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
1114 if (log)
1115 log->Printf("SBValue(%p)::Dereference () => SBValue(%p)",
1116 static_cast<void *>(value_sp.get()),
1117 static_cast<void *>(value_sp.get()));
1118
1119 return sb_value;
1120}
1121
1122// Deprecated - please use GetType().IsPointerType() instead.
1123bool SBValue::TypeIsPointerType() { return GetType().IsPointerType(); }
1124
1125void *SBValue::GetOpaqueType() {
1126 ValueLocker locker;
1127 lldb::ValueObjectSP value_sp(GetSP(locker));
1128 if (value_sp)
1129 return value_sp->GetCompilerType().GetOpaqueQualType();
1130 return NULL__null;
1131}
1132
1133lldb::SBTarget SBValue::GetTarget() {
1134 SBTarget sb_target;
1135 TargetSP target_sp;
1136 if (m_opaque_sp) {
1137 target_sp = m_opaque_sp->GetTargetSP();
1138 sb_target.SetSP(target_sp);
1139 }
1140 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
1141 if (log) {
1142 if (target_sp.get() == NULL__null)
1143 log->Printf("SBValue(%p)::GetTarget () => NULL",
1144 static_cast<void *>(m_opaque_sp.get()));
1145 else
1146 log->Printf("SBValue(%p)::GetTarget () => %p",
1147 static_cast<void *>(m_opaque_sp.get()),
1148 static_cast<void *>(target_sp.get()));
1149 }
1150 return sb_target;
1151}
1152
1153lldb::SBProcess SBValue::GetProcess() {
1154 SBProcess sb_process;
1155 ProcessSP process_sp;
1156 if (m_opaque_sp) {
1157 process_sp = m_opaque_sp->GetProcessSP();
1158 sb_process.SetSP(process_sp);
1159 }
1160 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
1161 if (log) {
1162 if (process_sp.get() == NULL__null)
1163 log->Printf("SBValue(%p)::GetProcess () => NULL",
1164 static_cast<void *>(m_opaque_sp.get()));
1165 else
1166 log->Printf("SBValue(%p)::GetProcess () => %p",
1167 static_cast<void *>(m_opaque_sp.get()),
1168 static_cast<void *>(process_sp.get()));
1169 }
1170 return sb_process;
1171}
1172
1173lldb::SBThread SBValue::GetThread() {
1174 SBThread sb_thread;
1175 ThreadSP thread_sp;
1176 if (m_opaque_sp) {
1177 thread_sp = m_opaque_sp->GetThreadSP();
1178 sb_thread.SetThread(thread_sp);
1179 }
1180 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
1181 if (log) {
1182 if (thread_sp.get() == NULL__null)
1183 log->Printf("SBValue(%p)::GetThread () => NULL",
1184 static_cast<void *>(m_opaque_sp.get()));
1185 else
1186 log->Printf("SBValue(%p)::GetThread () => %p",
1187 static_cast<void *>(m_opaque_sp.get()),
1188 static_cast<void *>(thread_sp.get()));
1189 }
1190 return sb_thread;
1191}
1192
1193lldb::SBFrame SBValue::GetFrame() {
1194 SBFrame sb_frame;
1195 StackFrameSP frame_sp;
1196 if (m_opaque_sp) {
1197 frame_sp = m_opaque_sp->GetFrameSP();
1198 sb_frame.SetFrameSP(frame_sp);
1199 }
1200 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
1201 if (log) {
1202 if (frame_sp.get() == NULL__null)
1203 log->Printf("SBValue(%p)::GetFrame () => NULL",
1204 static_cast<void *>(m_opaque_sp.get()));
1205 else
1206 log->Printf("SBValue(%p)::GetFrame () => %p",
1207 static_cast<void *>(m_opaque_sp.get()),
1208 static_cast<void *>(frame_sp.get()));
1209 }
1210 return sb_frame;
1211}
1212
1213lldb::ValueObjectSP SBValue::GetSP(ValueLocker &locker) const {
1214 if (!m_opaque_sp || !m_opaque_sp->IsValid()) {
1215 locker.GetError().SetErrorString("No value");
1216 return ValueObjectSP();
1217 }
1218 return locker.GetLockedSP(*m_opaque_sp.get());
1219}
1220
1221lldb::ValueObjectSP SBValue::GetSP() const {
1222 ValueLocker locker;
1223 return GetSP(locker);
1224}
1225
1226void SBValue::SetSP(ValueImplSP impl_sp) { m_opaque_sp = impl_sp; }
1227
1228void SBValue::SetSP(const lldb::ValueObjectSP &sp) {
1229 if (sp) {
1230 lldb::TargetSP target_sp(sp->GetTargetSP());
1231 if (target_sp) {
1232 lldb::DynamicValueType use_dynamic = target_sp->GetPreferDynamicValue();
1233 bool use_synthetic =
1234 target_sp->TargetProperties::GetEnableSyntheticValue();
1235 m_opaque_sp = ValueImplSP(new ValueImpl(sp, use_dynamic, use_synthetic));
1236 } else
1237 m_opaque_sp = ValueImplSP(new ValueImpl(sp, eNoDynamicValues, true));
1238 } else
1239 m_opaque_sp = ValueImplSP(new ValueImpl(sp, eNoDynamicValues, false));
1240}
1241
1242void SBValue::SetSP(const lldb::ValueObjectSP &sp,
1243 lldb::DynamicValueType use_dynamic) {
1244 if (sp) {
1245 lldb::TargetSP target_sp(sp->GetTargetSP());
1246 if (target_sp) {
1247 bool use_synthetic =
1248 target_sp->TargetProperties::GetEnableSyntheticValue();
1249 SetSP(sp, use_dynamic, use_synthetic);
1250 } else
1251 SetSP(sp, use_dynamic, true);
1252 } else
1253 SetSP(sp, use_dynamic, false);
1254}
1255
1256void SBValue::SetSP(const lldb::ValueObjectSP &sp, bool use_synthetic) {
1257 if (sp) {
1258 lldb::TargetSP target_sp(sp->GetTargetSP());
1259 if (target_sp) {
1260 lldb::DynamicValueType use_dynamic = target_sp->GetPreferDynamicValue();
1261 SetSP(sp, use_dynamic, use_synthetic);
1262 } else
1263 SetSP(sp, eNoDynamicValues, use_synthetic);
1264 } else
1265 SetSP(sp, eNoDynamicValues, use_synthetic);
1266}
1267
1268void SBValue::SetSP(const lldb::ValueObjectSP &sp,
1269 lldb::DynamicValueType use_dynamic, bool use_synthetic) {
1270 m_opaque_sp = ValueImplSP(new ValueImpl(sp, use_dynamic, use_synthetic));
1271}
1272
1273void SBValue::SetSP(const lldb::ValueObjectSP &sp,
1274 lldb::DynamicValueType use_dynamic, bool use_synthetic,
1275 const char *name) {
1276 m_opaque_sp =
1277 ValueImplSP(new ValueImpl(sp, use_dynamic, use_synthetic, name));
1278}
1279
1280bool SBValue::GetExpressionPath(SBStream &description) {
1281 ValueLocker locker;
1282 lldb::ValueObjectSP value_sp(GetSP(locker));
1283 if (value_sp) {
1284 value_sp->GetExpressionPath(description.ref(), false);
1285 return true;
1286 }
1287 return false;
1288}
1289
1290bool SBValue::GetExpressionPath(SBStream &description,
1291 bool qualify_cxx_base_classes) {
1292 ValueLocker locker;
1293 lldb::ValueObjectSP value_sp(GetSP(locker));
1294 if (value_sp) {
1295 value_sp->GetExpressionPath(description.ref(), qualify_cxx_base_classes);
1296 return true;
1297 }
1298 return false;
1299}
1300
1301bool SBValue::GetDescription(SBStream &description) {
1302 Stream &strm = description.ref();
1303
1304 ValueLocker locker;
1305 lldb::ValueObjectSP value_sp(GetSP(locker));
1306 if (value_sp)
1307 value_sp->Dump(strm);
1308 else
1309 strm.PutCString("No value");
1310
1311 return true;
1312}
1313
1314lldb::Format SBValue::GetFormat() {
1315 ValueLocker locker;
1316 lldb::ValueObjectSP value_sp(GetSP(locker));
1317 if (value_sp)
1318 return value_sp->GetFormat();
1319 return eFormatDefault;
1320}
1321
1322void SBValue::SetFormat(lldb::Format format) {
1323 ValueLocker locker;
1324 lldb::ValueObjectSP value_sp(GetSP(locker));
1325 if (value_sp)
1326 value_sp->SetFormat(format);
1327}
1328
1329lldb::SBValue SBValue::AddressOf() {
1330 SBValue sb_value;
1331 ValueLocker locker;
1332 lldb::ValueObjectSP value_sp(GetSP(locker));
1333 if (value_sp) {
1334 Status error;
1335 sb_value.SetSP(value_sp->AddressOf(error), GetPreferDynamicValue(),
1336 GetPreferSyntheticValue());
1337 }
1338 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
1339 if (log)
1340 log->Printf("SBValue(%p)::AddressOf () => SBValue(%p)",
1341 static_cast<void *>(value_sp.get()),
1342 static_cast<void *>(value_sp.get()));
1343
1344 return sb_value;
1345}
1346
1347lldb::addr_t SBValue::GetLoadAddress() {
1348 lldb::addr_t value = LLDB_INVALID_ADDRESS(18446744073709551615UL);
1349 ValueLocker locker;
1350 lldb::ValueObjectSP value_sp(GetSP(locker));
1351 if (value_sp) {
1352 TargetSP target_sp(value_sp->GetTargetSP());
1353 if (target_sp) {
1354 const bool scalar_is_load_address = true;
1355 AddressType addr_type;
1356 value = value_sp->GetAddressOf(scalar_is_load_address, &addr_type);
1357 if (addr_type == eAddressTypeFile) {
1358 ModuleSP module_sp(value_sp->GetModule());
1359 if (!module_sp)
1360 value = LLDB_INVALID_ADDRESS(18446744073709551615UL);
1361 else {
1362 Address addr;
1363 module_sp->ResolveFileAddress(value, addr);
1364 value = addr.GetLoadAddress(target_sp.get());
1365 }
1366 } else if (addr_type == eAddressTypeHost ||
1367 addr_type == eAddressTypeInvalid)
1368 value = LLDB_INVALID_ADDRESS(18446744073709551615UL);
1369 }
1370 }
1371 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
1372 if (log)
1373 log->Printf("SBValue(%p)::GetLoadAddress () => (%" PRIu64"l" "u" ")",
1374 static_cast<void *>(value_sp.get()), value);
1375
1376 return value;
1377}
1378
1379lldb::SBAddress SBValue::GetAddress() {
1380 Address addr;
1381 ValueLocker locker;
1382 lldb::ValueObjectSP value_sp(GetSP(locker));
1383 if (value_sp) {
1384 TargetSP target_sp(value_sp->GetTargetSP());
1385 if (target_sp) {
1386 lldb::addr_t value = LLDB_INVALID_ADDRESS(18446744073709551615UL);
1387 const bool scalar_is_load_address = true;
1388 AddressType addr_type;
1389 value = value_sp->GetAddressOf(scalar_is_load_address, &addr_type);
1390 if (addr_type == eAddressTypeFile) {
1391 ModuleSP module_sp(value_sp->GetModule());
1392 if (module_sp)
1393 module_sp->ResolveFileAddress(value, addr);
1394 } else if (addr_type == eAddressTypeLoad) {
1395 // no need to check the return value on this.. if it can actually do
1396 // the resolve addr will be in the form (section,offset), otherwise it
1397 // will simply be returned as (NULL, value)
1398 addr.SetLoadAddress(value, target_sp.get());
1399 }
1400 }
1401 }
1402 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
1403 if (log)
1404 log->Printf("SBValue(%p)::GetAddress () => (%s,%" PRIu64"l" "u" ")",
1405 static_cast<void *>(value_sp.get()),
1406 (addr.GetSection() ? addr.GetSection()->GetName().GetCString()
1407 : "NULL"),
1408 addr.GetOffset());
1409 return SBAddress(new Address(addr));
1410}
1411
1412lldb::SBData SBValue::GetPointeeData(uint32_t item_idx, uint32_t item_count) {
1413 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
1414 lldb::SBData sb_data;
1415 ValueLocker locker;
1416 lldb::ValueObjectSP value_sp(GetSP(locker));
1417 if (value_sp) {
1418 TargetSP target_sp(value_sp->GetTargetSP());
1419 if (target_sp) {
1420 DataExtractorSP data_sp(new DataExtractor());
1421 value_sp->GetPointeeData(*data_sp, item_idx, item_count);
1422 if (data_sp->GetByteSize() > 0)
1423 *sb_data = data_sp;
1424 }
1425 }
1426 if (log)
1427 log->Printf("SBValue(%p)::GetPointeeData (%d, %d) => SBData(%p)",
1428 static_cast<void *>(value_sp.get()), item_idx, item_count,
1429 static_cast<void *>(sb_data.get()));
1430
1431 return sb_data;
1432}
1433
1434lldb::SBData SBValue::GetData() {
1435 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
1436 lldb::SBData sb_data;
1437 ValueLocker locker;
1438 lldb::ValueObjectSP value_sp(GetSP(locker));
1439 if (value_sp) {
1440 DataExtractorSP data_sp(new DataExtractor());
1441 Status error;
1442 value_sp->GetData(*data_sp, error);
1443 if (error.Success())
1444 *sb_data = data_sp;
1445 }
1446 if (log)
1447 log->Printf("SBValue(%p)::GetData () => SBData(%p)",
1448 static_cast<void *>(value_sp.get()),
1449 static_cast<void *>(sb_data.get()));
1450
1451 return sb_data;
1452}
1453
1454bool SBValue::SetData(lldb::SBData &data, SBError &error) {
1455 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
1456 ValueLocker locker;
1457 lldb::ValueObjectSP value_sp(GetSP(locker));
1458 bool ret = true;
1459
1460 if (value_sp) {
1461 DataExtractor *data_extractor = data.get();
1462
1463 if (!data_extractor) {
1464 if (log)
1465 log->Printf("SBValue(%p)::SetData() => error: no data to set",
1466 static_cast<void *>(value_sp.get()));
1467
1468 error.SetErrorString("No data to set");
1469 ret = false;
1470 } else {
1471 Status set_error;
1472
1473 value_sp->SetData(*data_extractor, set_error);
1474
1475 if (!set_error.Success()) {
1476 error.SetErrorStringWithFormat("Couldn't set data: %s",
1477 set_error.AsCString());
1478 ret = false;
1479 }
1480 }
1481 } else {
1482 error.SetErrorStringWithFormat(
1483 "Couldn't set data: could not get SBValue: %s",
1484 locker.GetError().AsCString());
1485 ret = false;
1486 }
1487
1488 if (log)
1489 log->Printf("SBValue(%p)::SetData (%p) => %s",
1490 static_cast<void *>(value_sp.get()),
1491 static_cast<void *>(data.get()), ret ? "true" : "false");
1492 return ret;
1493}
1494
1495lldb::SBDeclaration SBValue::GetDeclaration() {
1496 ValueLocker locker;
1497 lldb::ValueObjectSP value_sp(GetSP(locker));
1498 SBDeclaration decl_sb;
1499 if (value_sp) {
1500 Declaration decl;
1501 if (value_sp->GetDeclaration(decl))
1502 decl_sb.SetDeclaration(decl);
1503 }
1504 return decl_sb;
1505}
1506
1507lldb::SBWatchpoint SBValue::Watch(bool resolve_location, bool read, bool write,
1508 SBError &error) {
1509 SBWatchpoint sb_watchpoint;
1510
1511 // If the SBValue is not valid, there's no point in even trying to watch it.
1512 ValueLocker locker;
1513 lldb::ValueObjectSP value_sp(GetSP(locker));
1514 TargetSP target_sp(GetTarget().GetSP());
1515 if (value_sp && target_sp) {
1516 // Read and Write cannot both be false.
1517 if (!read && !write)
1518 return sb_watchpoint;
1519
1520 // If the value is not in scope, don't try and watch and invalid value
1521 if (!IsInScope())
1522 return sb_watchpoint;
1523
1524 addr_t addr = GetLoadAddress();
1525 if (addr == LLDB_INVALID_ADDRESS(18446744073709551615UL))
1526 return sb_watchpoint;
1527 size_t byte_size = GetByteSize();
1528 if (byte_size == 0)
1529 return sb_watchpoint;
1530
1531 uint32_t watch_type = 0;
1532 if (read)
1533 watch_type |= LLDB_WATCH_TYPE_READ(1u << 0);
1534 if (write)
1535 watch_type |= LLDB_WATCH_TYPE_WRITE(1u << 1);
1536
1537 Status rc;
1538 CompilerType type(value_sp->GetCompilerType());
1539 WatchpointSP watchpoint_sp =
1540 target_sp->CreateWatchpoint(addr, byte_size, &type, watch_type, rc);
1541 error.SetError(rc);
1542
1543 if (watchpoint_sp) {
1544 sb_watchpoint.SetSP(watchpoint_sp);
1545 Declaration decl;
1546 if (value_sp->GetDeclaration(decl)) {
1547 if (decl.GetFile()) {
1548 StreamString ss;
1549 // True to show fullpath for declaration file.
1550 decl.DumpStopContext(&ss, true);
1551 watchpoint_sp->SetDeclInfo(ss.GetString());
1552 }
1553 }
1554 }
1555 } else if (target_sp) {
1556 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
1557 if (log)
1558 log->Printf("SBValue(%p)::Watch() => error getting SBValue: %s",
1559 static_cast<void *>(value_sp.get()),
1560 locker.GetError().AsCString());
1561
1562 error.SetErrorStringWithFormat("could not get SBValue: %s",
1563 locker.GetError().AsCString());
1564 } else {
1565 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
1566 if (log)
1567 log->Printf("SBValue(%p)::Watch() => error getting SBValue: no target",
1568 static_cast<void *>(value_sp.get()));
1569 error.SetErrorString("could not set watchpoint, a target is required");
1570 }
1571
1572 return sb_watchpoint;
1573}
1574
1575// FIXME: Remove this method impl (as well as the decl in .h) once it is no
1576// longer needed.
1577// Backward compatibility fix in the interim.
1578lldb::SBWatchpoint SBValue::Watch(bool resolve_location, bool read,
1579 bool write) {
1580 SBError error;
1581 return Watch(resolve_location, read, write, error);
1582}
1583
1584lldb::SBWatchpoint SBValue::WatchPointee(bool resolve_location, bool read,
1585 bool write, SBError &error) {
1586 SBWatchpoint sb_watchpoint;
1587 if (IsInScope() && GetType().IsPointerType())
1588 sb_watchpoint = Dereference().Watch(resolve_location, read, write, error);
1589 return sb_watchpoint;
1590}
1591
1592lldb::SBValue SBValue::Persist() {
1593 ValueLocker locker;
1594 lldb::ValueObjectSP value_sp(GetSP(locker));
1595 SBValue persisted_sb;
1596 if (value_sp) {
1597 persisted_sb.SetSP(value_sp->Persist());
1598 }
1599 return persisted_sb;
1600}

/usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/bits/stl_pair.h

1// Pair implementation -*- C++ -*-
2
3// Copyright (C) 2001-2016 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library. This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 3, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23// <http://www.gnu.org/licenses/>.
24
25/*
26 *
27 * Copyright (c) 1994
28 * Hewlett-Packard Company
29 *
30 * Permission to use, copy, modify, distribute and sell this software
31 * and its documentation for any purpose is hereby granted without fee,
32 * provided that the above copyright notice appear in all copies and
33 * that both that copyright notice and this permission notice appear
34 * in supporting documentation. Hewlett-Packard Company makes no
35 * representations about the suitability of this software for any
36 * purpose. It is provided "as is" without express or implied warranty.
37 *
38 *
39 * Copyright (c) 1996,1997
40 * Silicon Graphics Computer Systems, Inc.
41 *
42 * Permission to use, copy, modify, distribute and sell this software
43 * and its documentation for any purpose is hereby granted without fee,
44 * provided that the above copyright notice appear in all copies and
45 * that both that copyright notice and this permission notice appear
46 * in supporting documentation. Silicon Graphics makes no
47 * representations about the suitability of this software for any
48 * purpose. It is provided "as is" without express or implied warranty.
49 */
50
51/** @file bits/stl_pair.h
52 * This is an internal header file, included by other library headers.
53 * Do not attempt to use it directly. @headername{utility}
54 */
55
56#ifndef _STL_PAIR_H1
57#define _STL_PAIR_H1 1
58
59#include <bits/move.h> // for std::move / std::forward, and std::swap
60
61#if __cplusplus201103L >= 201103L
62#include <type_traits> // for std::__decay_and_strip too
63#endif
64
65namespace std _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default")))
66{
67_GLIBCXX_BEGIN_NAMESPACE_VERSION
68
69 /**
70 * @addtogroup utilities
71 * @{
72 */
73
74#if __cplusplus201103L >= 201103L
75 /// piecewise_construct_t
76 struct piecewise_construct_t { explicit piecewise_construct_t() = default; };
77
78 /// piecewise_construct
79 constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t();
80
81 // Forward declarations.
82 template<typename...>
83 class tuple;
84
85 template<std::size_t...>
86 struct _Index_tuple;
87
88 // Concept utility functions, reused in conditionally-explicit
89 // constructors.
90 // See PR 70437, don't look at is_constructible or
91 // is_convertible if the types are the same to
92 // avoid querying those properties for incomplete types.
93 template <bool, typename _T1, typename _T2>
94 struct _PCC
95 {
96 template <typename _U1, typename _U2>
97 static constexpr bool _ConstructiblePair()
98 {
99 return __and_<is_constructible<_T1, const _U1&>,
100 is_constructible<_T2, const _U2&>>::value;
101 }
102
103 template <typename _U1, typename _U2>
104 static constexpr bool _ImplicitlyConvertiblePair()
105 {
106 return __and_<is_convertible<const _U1&, _T1>,
107 is_convertible<const _U2&, _T2>>::value;
108 }
109
110 template <typename _U1, typename _U2>
111 static constexpr bool _MoveConstructiblePair()
112 {
113 return __and_<is_constructible<_T1, _U1&&>,
114 is_constructible<_T2, _U2&&>>::value;
115 }
116
117 template <typename _U1, typename _U2>
118 static constexpr bool _ImplicitlyMoveConvertiblePair()
119 {
120 return __and_<is_convertible<_U1&&, _T1>,
121 is_convertible<_U2&&, _T2>>::value;
122 }
123
124 template <bool __implicit, typename _U1, typename _U2>
125 static constexpr bool _CopyMovePair()
126 {
127 using __do_converts = __and_<is_convertible<const _U1&, _T1>,
128 is_convertible<_U2&&, _T2>>;
129 using __converts = typename conditional<__implicit,
130 __do_converts,
131 __not_<__do_converts>>::type;
132 return __and_<is_constructible<_T1, const _U1&>,
133 is_constructible<_T2, _U2&&>,
134 __converts
135 >::value;
136 }
137
138 template <bool __implicit, typename _U1, typename _U2>
139 static constexpr bool _MoveCopyPair()
140 {
141 using __do_converts = __and_<is_convertible<_U1&&, _T1>,
142 is_convertible<const _U2&, _T2>>;
143 using __converts = typename conditional<__implicit,
144 __do_converts,
145 __not_<__do_converts>>::type;
146 return __and_<is_constructible<_T1, _U1&&>,
147 is_constructible<_T2, const _U2&&>,
148 __converts
149 >::value;
150 }
151 };
152
153 template <typename _T1, typename _T2>
154 struct _PCC<false, _T1, _T2>
155 {
156 template <typename _U1, typename _U2>
157 static constexpr bool _ConstructiblePair()
158 {
159 return false;
160 }
161
162 template <typename _U1, typename _U2>
163 static constexpr bool _ImplicitlyConvertiblePair()
164 {
165 return false;
166 }
167
168 template <typename _U1, typename _U2>
169 static constexpr bool _MoveConstructiblePair()
170 {
171 return false;
172 }
173
174 template <typename _U1, typename _U2>
175 static constexpr bool _ImplicitlyMoveConvertiblePair()
176 {
177 return false;
178 }
179 };
180
181 struct __wrap_nonesuch : std::__nonesuch {
182 explicit __wrap_nonesuch(const __nonesuch&) = delete;
183 };
184
185#endif
186
187 /**
188 * @brief Struct holding two objects of arbitrary type.
189 *
190 * @tparam _T1 Type of first object.
191 * @tparam _T2 Type of second object.
192 */
193 template<typename _T1, typename _T2>
194 struct pair
9
Inner buffer of 'class std::__cxx11::basic_string<char>' deallocated by call to destructor
195 {
196 typedef _T1 first_type; /// @c first_type is the first bound type
197 typedef _T2 second_type; /// @c second_type is the second bound type
198
199 _T1 first; /// @c first is a copy of the first object
200 _T2 second; /// @c second is a copy of the second object
201
202 // _GLIBCXX_RESOLVE_LIB_DEFECTS
203 // 265. std::pair::pair() effects overly restrictive
204 /** The default constructor creates @c first and @c second using their
205 * respective default constructors. */
206#if __cplusplus201103L >= 201103L
207 template <typename _U1 = _T1,
208 typename _U2 = _T2,
209 typename enable_if<__and_<
210 __is_implicitly_default_constructible<_U1>,
211 __is_implicitly_default_constructible<_U2>>
212 ::value, bool>::type = true>
213#endif
214 _GLIBCXX_CONSTEXPRconstexpr pair()
215 : first(), second() { }
216
217#if __cplusplus201103L >= 201103L
218 template <typename _U1 = _T1,
219 typename _U2 = _T2,
220 typename enable_if<__and_<
221 is_default_constructible<_U1>,
222 is_default_constructible<_U2>,
223 __not_<
224 __and_<__is_implicitly_default_constructible<_U1>,
225 __is_implicitly_default_constructible<_U2>>>>
226 ::value, bool>::type = false>
227 explicit constexpr pair()
228 : first(), second() { }
229#endif
230
231 /** Two objects may be passed to a @c pair constructor to be copied. */
232#if __cplusplus201103L < 201103L
233 pair(const _T1& __a, const _T2& __b)
234 : first(__a), second(__b) { }
235#else
236 // Shortcut for constraining the templates that don't take pairs.
237 using _PCCP = _PCC<true, _T1, _T2>;
238
239 template<typename _U1 = _T1, typename _U2=_T2, typename
240 enable_if<_PCCP::template
241 _ConstructiblePair<_U1, _U2>()
242 && _PCCP::template
243 _ImplicitlyConvertiblePair<_U1, _U2>(),
244 bool>::type=true>
245 constexpr pair(const _T1& __a, const _T2& __b)
246 : first(__a), second(__b) { }
247
248 template<typename _U1 = _T1, typename _U2=_T2, typename
249 enable_if<_PCCP::template
250 _ConstructiblePair<_U1, _U2>()
251 && !_PCCP::template
252 _ImplicitlyConvertiblePair<_U1, _U2>(),
253 bool>::type=false>
254 explicit constexpr pair(const _T1& __a, const _T2& __b)
255 : first(__a), second(__b) { }
256#endif
257
258 /** There is also a templated copy ctor for the @c pair class itself. */
259#if __cplusplus201103L < 201103L
260 template<typename _U1, typename _U2>
261 pair(const pair<_U1, _U2>& __p)
262 : first(__p.first), second(__p.second) { }
263#else
264 // Shortcut for constraining the templates that take pairs.
265 template <typename _U1, typename _U2>
266 using _PCCFP = _PCC<!is_same<_T1, _U1>::value
267 || !is_same<_T2, _U2>::value,
268 _T1, _T2>;
269
270 template<typename _U1, typename _U2, typename
271 enable_if<_PCCFP<_U1, _U2>::template
272 _ConstructiblePair<_U1, _U2>()
273 && _PCCFP<_U1, _U2>::template
274 _ImplicitlyConvertiblePair<_U1, _U2>(),
275 bool>::type=true>
276 constexpr pair(const pair<_U1, _U2>& __p)
277 : first(__p.first), second(__p.second) { }
278
279 template<typename _U1, typename _U2, typename
280 enable_if<_PCCFP<_U1, _U2>::template
281 _ConstructiblePair<_U1, _U2>()
282 && !_PCCFP<_U1, _U2>::template
283 _ImplicitlyConvertiblePair<_U1, _U2>(),
284 bool>::type=false>
285 explicit constexpr pair(const pair<_U1, _U2>& __p)
286 : first(__p.first), second(__p.second) { }
287
288 constexpr pair(const pair&) = default;
289 constexpr pair(pair&&) = default;
290
291 // DR 811.
292 template<typename _U1, typename
293 enable_if<_PCCP::template
294 _MoveCopyPair<true, _U1, _T2>(),
295 bool>::type=true>
296 constexpr pair(_U1&& __x, const _T2& __y)
297 : first(std::forward<_U1>(__x)), second(__y) { }
298
299 template<typename _U1, typename
300 enable_if<_PCCP::template
301 _MoveCopyPair<false, _U1, _T2>(),
302 bool>::type=false>
303 explicit constexpr pair(_U1&& __x, const _T2& __y)
304 : first(std::forward<_U1>(__x)), second(__y) { }
305
306 template<typename _U2, typename
307 enable_if<_PCCP::template
308 _CopyMovePair<true, _T1, _U2>(),
309 bool>::type=true>
310 constexpr pair(const _T1& __x, _U2&& __y)
311 : first(__x), second(std::forward<_U2>(__y)) { }
312
313 template<typename _U2, typename
314 enable_if<_PCCP::template
315 _CopyMovePair<false, _T1, _U2>(),
316 bool>::type=false>
317 explicit pair(const _T1& __x, _U2&& __y)
318 : first(__x), second(std::forward<_U2>(__y)) { }
319
320 template<typename _U1, typename _U2, typename
321 enable_if<_PCCP::template
322 _MoveConstructiblePair<_U1, _U2>()
323 && _PCCP::template
324 _ImplicitlyMoveConvertiblePair<_U1, _U2>(),
325 bool>::type=true>
326 constexpr pair(_U1&& __x, _U2&& __y)
327 : first(std::forward<_U1>(__x)), second(std::forward<_U2>(__y)) { }
328
329 template<typename _U1, typename _U2, typename
330 enable_if<_PCCP::template
331 _MoveConstructiblePair<_U1, _U2>()
332 && !_PCCP::template
333 _ImplicitlyMoveConvertiblePair<_U1, _U2>(),
334 bool>::type=false>
335 explicit constexpr pair(_U1&& __x, _U2&& __y)
336 : first(std::forward<_U1>(__x)), second(std::forward<_U2>(__y)) { }
337
338
339 template<typename _U1, typename _U2, typename
340 enable_if<_PCCFP<_U1, _U2>::template
341 _MoveConstructiblePair<_U1, _U2>()
342 && _PCCFP<_U1, _U2>::template
343 _ImplicitlyMoveConvertiblePair<_U1, _U2>(),
344 bool>::type=true>
345 constexpr pair(pair<_U1, _U2>&& __p)
346 : first(std::forward<_U1>(__p.first)),
347 second(std::forward<_U2>(__p.second)) { }
348
349 template<typename _U1, typename _U2, typename
350 enable_if<_PCCFP<_U1, _U2>::template
351 _MoveConstructiblePair<_U1, _U2>()
352 && !_PCCFP<_U1, _U2>::template
353 _ImplicitlyMoveConvertiblePair<_U1, _U2>(),
354 bool>::type=false>
355 explicit constexpr pair(pair<_U1, _U2>&& __p)
356 : first(std::forward<_U1>(__p.first)),
357 second(std::forward<_U2>(__p.second)) { }
358
359 template<typename... _Args1, typename... _Args2>
360 pair(piecewise_construct_t, tuple<_Args1...>, tuple<_Args2...>);
361
362 pair&
363 operator=(typename conditional<
364 __and_<is_copy_assignable<_T1>,
365 is_copy_assignable<_T2>>::value,
366 const pair&, const __wrap_nonesuch&>::type __p)
367 {
368 first = __p.first;
369 second = __p.second;
370 return *this;
371 }
372
373 pair&
374 operator=(typename conditional<
375 __not_<__and_<is_copy_assignable<_T1>,
376 is_copy_assignable<_T2>>>::value,
377 const pair&, const __wrap_nonesuch&>::type __p) = delete;
378
379 pair&
380 operator=(typename conditional<
381 __and_<is_move_assignable<_T1>,
382 is_move_assignable<_T2>>::value,
383 pair&&, __wrap_nonesuch&&>::type __p)
384 noexcept(__and_<is_nothrow_move_assignable<_T1>,
385 is_nothrow_move_assignable<_T2>>::value)
386 {
387 first = std::forward<first_type>(__p.first);
388 second = std::forward<second_type>(__p.second);
389 return *this;
390 }
391
392 template<typename _U1, typename _U2>
393 typename enable_if<__and_<is_assignable<_T1&, const _U1&>,
394 is_assignable<_T2&, const _U2&>>::value,
395 pair&>::type
396 operator=(const pair<_U1, _U2>& __p)
397 {
398 first = __p.first;
399 second = __p.second;
400 return *this;
401 }
402
403 template<typename _U1, typename _U2>
404 typename enable_if<__and_<is_assignable<_T1&, _U1&&>,
405 is_assignable<_T2&, _U2&&>>::value,
406 pair&>::type
407 operator=(pair<_U1, _U2>&& __p)
408 {
409 first = std::forward<_U1>(__p.first);
410 second = std::forward<_U2>(__p.second);
411 return *this;
412 }
413
414 void
415 swap(pair& __p)
416 noexcept(__is_nothrow_swappable<_T1>::value
417 && __is_nothrow_swappable<_T2>::value)
418 {
419 using std::swap;
420 swap(first, __p.first);
421 swap(second, __p.second);
422 }
423
424 private:
425 template<typename... _Args1, std::size_t... _Indexes1,
426 typename... _Args2, std::size_t... _Indexes2>
427 pair(tuple<_Args1...>&, tuple<_Args2...>&,
428 _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>);
429#endif
430 };
431
432 /// Two pairs of the same type are equal iff their members are equal.
433 template<typename _T1, typename _T2>
434 inline _GLIBCXX_CONSTEXPRconstexpr bool
435 operator==(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
436 { return __x.first == __y.first && __x.second == __y.second; }
437
438 /// <http://gcc.gnu.org/onlinedocs/libstdc++/manual/utilities.html>
439 template<typename _T1, typename _T2>
440 inline _GLIBCXX_CONSTEXPRconstexpr bool
441 operator<(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
442 { return __x.first < __y.first
443 || (!(__y.first < __x.first) && __x.second < __y.second); }
444
445 /// Uses @c operator== to find the result.
446 template<typename _T1, typename _T2>
447 inline _GLIBCXX_CONSTEXPRconstexpr bool
448 operator!=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
449 { return !(__x == __y); }
450
451 /// Uses @c operator< to find the result.
452 template<typename _T1, typename _T2>
453 inline _GLIBCXX_CONSTEXPRconstexpr bool
454 operator>(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
455 { return __y < __x; }
456
457 /// Uses @c operator< to find the result.
458 template<typename _T1, typename _T2>
459 inline _GLIBCXX_CONSTEXPRconstexpr bool
460 operator<=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
461 { return !(__y < __x); }
462
463 /// Uses @c operator< to find the result.
464 template<typename _T1, typename _T2>
465 inline _GLIBCXX_CONSTEXPRconstexpr bool
466 operator>=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
467 { return !(__x < __y); }
468
469#if __cplusplus201103L >= 201103L
470 /// See std::pair::swap().
471 // Note: no std::swap overloads in C++03 mode, this has performance
472 // implications, see, eg, libstdc++/38466.
473 template<typename _T1, typename _T2>
474 inline void
475 swap(pair<_T1, _T2>& __x, pair<_T1, _T2>& __y)
476 noexcept(noexcept(__x.swap(__y)))
477 { __x.swap(__y); }
478#endif
479
480 /**
481 * @brief A convenience wrapper for creating a pair from two objects.
482 * @param __x The first object.
483 * @param __y The second object.
484 * @return A newly-constructed pair<> object of the appropriate type.
485 *
486 * The standard requires that the objects be passed by reference-to-const,
487 * but LWG issue #181 says they should be passed by const value. We follow
488 * the LWG by default.
489 */
490 // _GLIBCXX_RESOLVE_LIB_DEFECTS
491 // 181. make_pair() unintended behavior
492#if __cplusplus201103L >= 201103L
493 // NB: DR 706.
494 template<typename _T1, typename _T2>
495 constexpr pair<typename __decay_and_strip<_T1>::__type,
496 typename __decay_and_strip<_T2>::__type>
497 make_pair(_T1&& __x, _T2&& __y)
498 {
499 typedef typename __decay_and_strip<_T1>::__type __ds_type1;
500 typedef typename __decay_and_strip<_T2>::__type __ds_type2;
501 typedef pair<__ds_type1, __ds_type2> __pair_type;
502 return __pair_type(std::forward<_T1>(__x), std::forward<_T2>(__y));
503 }
504#else
505 template<typename _T1, typename _T2>
506 inline pair<_T1, _T2>
507 make_pair(_T1 __x, _T2 __y)
508 { return pair<_T1, _T2>(__x, __y); }
509#endif
510
511 /// @}
512
513_GLIBCXX_END_NAMESPACE_VERSION
514} // namespace std
515
516#endif /* _STL_PAIR_H */