LLDB mainline
LibStdcppAtomic.cpp
Go to the documentation of this file.
1//===---------------------------------------------------------------------===//
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 "LibStdcpp.h"
10
15#include "llvm/Support/Error.h"
16
17using namespace lldb;
18
20
23public:
26
27 llvm::Expected<uint32_t> CalculateNumChildren() override {
28 if (!m_inner)
29 return llvm::createStringError("Invalid atomic ValueObject.");
30 return 1;
31 }
32
33 ValueObjectSP GetChildAtIndex(uint32_t idx) override {
34 if (idx == 0 && m_inner)
35 return m_inner->GetSP()->Clone(k_inner_name);
36
37 return {};
38 }
39
42 // show the Type, instead of std::__atomic_base<Type>::__Type_type.
43 value = value->Cast(value->GetCompilerType().GetCanonicalType());
44 m_inner = value.get();
45 }
46
48 }
49
50 llvm::Expected<size_t>
51 GetIndexOfChildWithName(llvm::StringRef name) override {
52 if (name == k_inner_name)
53 return 0;
54
55 return llvm::createStringErrorV("Type has no child named '{}'", name);
56 }
57
59 const ValueObjectSP non_synthetic = backend_syn.GetNonSyntheticValue();
60 if (!non_synthetic)
61 return {};
62 ValueObject &backend = *non_synthetic;
63
64 const CompilerType type = backend.GetCompilerType();
65 if (!type || type.GetNumTemplateArguments() == 0)
66 return {};
67
68 const CompilerType first_type = type.GetTypeTemplateArgument(0);
69 if (!first_type)
70 return {};
71
72 if (first_type.IsBoolean())
73 return backend.GetChildAtNamePath({"_M_base", "_M_i"});
74
75 const uint32_t float_mask = lldb::eTypeIsFloat | lldb::eTypeIsBuiltIn;
76 if ((first_type.GetTypeInfo() & float_mask) == float_mask) {
77 // added float types specialization in c++20
78 if (const auto child = backend.GetChildMemberWithName("_M_fp"))
79 return child;
80
81 return backend.GetChildMemberWithName("_M_i");
82 }
83
84 if (first_type.IsPointerType())
85 return backend.GetChildAtNamePath({"_M_b", "_M_p"});
86
87 const auto first_typename = first_type.GetDisplayTypeName().GetStringRef();
88 if (first_typename.starts_with("std::shared_ptr<") ||
89 first_typename.starts_with("std::weak_ptr<"))
90 return backend.GetChildAtNamePath({"_M_impl", "_M_ptr"});
91
92 return backend.GetChildMemberWithName("_M_i");
93 }
94
95private:
96 inline static const ConstString k_inner_name = ConstString("Value");
97 ValueObject *m_inner = nullptr;
98};
99
102 const lldb::ValueObjectSP &valobj_sp) {
103 if (!valobj_sp)
104 return nullptr;
105
106 const ValueObjectSP member =
108 if (!member)
109 return nullptr;
110
111 return new LibStdcppAtomicSyntheticFrontEnd(*valobj_sp);
112}
113
115 const TypeSummaryOptions &options) {
116
117 if (const ValueObjectSP atomic_value =
119 std::string summary;
120 if (atomic_value->GetSummaryAsCString(summary, options) &&
121 !summary.empty()) {
122 stream << summary;
123 return true;
124 }
125
126 ValueObject *aparent = atomic_value->GetParent();
127 if (aparent && aparent->GetName() == "_M_impl") {
128 return LibStdcppSmartPointerSummaryProvider(*aparent, stream, options,
129 /*is_atomic_child=*/true);
130 }
131 }
132
133 return false;
134}
135
136} // namespace lldb_private::formatters
Generic representation of a type in a programming language.
CompilerType GetTypeTemplateArgument(size_t idx, bool expand_pack=false) const
ConstString GetDisplayTypeName() const
size_t GetNumTemplateArguments(bool expand_pack=false) const
Return the number of template arguments the type has.
uint32_t GetTypeInfo(CompilerType *pointee_or_element_compiler_type=nullptr) const
bool IsPointerType(CompilerType *pointee_type=nullptr) const
A uniqued constant string class.
Definition ConstString.h:40
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
A stream class that can stream formatted output to a file.
Definition Stream.h:28
SyntheticChildrenFrontEnd(ValueObject &backend)
virtual lldb::ValueObjectSP GetChildMemberWithName(llvm::StringRef name, bool can_create=true)
lldb::ValueObjectSP GetChildAtNamePath(llvm::ArrayRef< llvm::StringRef > names)
CompilerType GetCompilerType()
ConstString GetName() const
virtual ValueObject * GetParent()
virtual lldb::ValueObjectSP GetNonSyntheticValue()
llvm::Expected< uint32_t > CalculateNumChildren() override
lldb::ChildCacheState Update() override
This function is assumed to always succeed and if it fails, the front-end should know to deal with it...
llvm::Expected< size_t > GetIndexOfChildWithName(llvm::StringRef name) override
Determine the index of a named child.
static ValueObjectSP ContainerFieldName(ValueObject &backend_syn)
SyntheticChildrenFrontEnd * LibStdcppAtomicSyntheticFrontEndCreator(CXXSyntheticChildren *, const lldb::ValueObjectSP &)
bool LibStdcppSmartPointerSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options, bool is_atomic_child=false)
bool LibStdcppAtomicSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options)
ChildCacheState
Specifies if children need to be re-computed after a call to SyntheticChildrenFrontEnd::Update.
@ eRefetch
Children need to be recomputed dynamically.
std::shared_ptr< lldb_private::ValueObject > ValueObjectSP