]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/lldb/source/DataFormatters/TypeSynthetic.cpp
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm-project / lldb / source / DataFormatters / TypeSynthetic.cpp
1 //===-- TypeSynthetic.cpp ----------------------------------------*- 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
11
12
13 #include "lldb/lldb-enumerations.h"
14 #include "lldb/lldb-public.h"
15
16 #include "lldb/Core/Debugger.h"
17 #include "lldb/DataFormatters/TypeSynthetic.h"
18 #include "lldb/Interpreter/CommandInterpreter.h"
19 #include "lldb/Interpreter/ScriptInterpreter.h"
20 #include "lldb/Symbol/CompilerType.h"
21 #include "lldb/Target/Target.h"
22 #include "lldb/Utility/StreamString.h"
23
24 using namespace lldb;
25 using namespace lldb_private;
26
27 void TypeFilterImpl::AddExpressionPath(const std::string &path) {
28   bool need_add_dot = true;
29   if (path[0] == '.' || (path[0] == '-' && path[1] == '>') || path[0] == '[')
30     need_add_dot = false;
31   // add a '.' symbol to help forgetful users
32   if (!need_add_dot)
33     m_expression_paths.push_back(path);
34   else
35     m_expression_paths.push_back(std::string(".") + path);
36 }
37
38 bool TypeFilterImpl::SetExpressionPathAtIndex(size_t i,
39                                               const std::string &path) {
40   if (i >= GetCount())
41     return false;
42   bool need_add_dot = true;
43   if (path[0] == '.' || (path[0] == '-' && path[1] == '>') || path[0] == '[')
44     need_add_dot = false;
45   // add a '.' symbol to help forgetful users
46   if (!need_add_dot)
47     m_expression_paths[i] = path;
48   else
49     m_expression_paths[i] = std::string(".") + path;
50   return true;
51 }
52
53 size_t
54 TypeFilterImpl::FrontEnd::GetIndexOfChildWithName(ConstString name) {
55   const char *name_cstr = name.GetCString();
56   if (name_cstr) {
57     for (size_t i = 0; i < filter->GetCount(); i++) {
58       const char *expr_cstr = filter->GetExpressionPathAtIndex(i);
59       if (expr_cstr) {
60         if (*expr_cstr == '.')
61           expr_cstr++;
62         else if (*expr_cstr == '-' && *(expr_cstr + 1) == '>')
63           expr_cstr += 2;
64       }
65       if (expr_cstr) {
66         if (!::strcmp(name_cstr, expr_cstr))
67           return i;
68       }
69     }
70   }
71   return UINT32_MAX;
72 }
73
74 std::string TypeFilterImpl::GetDescription() {
75   StreamString sstr;
76   sstr.Printf("%s%s%s {\n", Cascades() ? "" : " (not cascading)",
77               SkipsPointers() ? " (skip pointers)" : "",
78               SkipsReferences() ? " (skip references)" : "");
79
80   for (size_t i = 0; i < GetCount(); i++) {
81     sstr.Printf("    %s\n", GetExpressionPathAtIndex(i));
82   }
83
84   sstr.Printf("}");
85   return sstr.GetString();
86 }
87
88 std::string CXXSyntheticChildren::GetDescription() {
89   StreamString sstr;
90   sstr.Printf("%s%s%s %s", Cascades() ? "" : " (not cascading)",
91               SkipsPointers() ? " (skip pointers)" : "",
92               SkipsReferences() ? " (skip references)" : "",
93               m_description.c_str());
94
95   return sstr.GetString();
96 }
97
98 lldb::ValueObjectSP SyntheticChildrenFrontEnd::CreateValueObjectFromExpression(
99     llvm::StringRef name, llvm::StringRef expression,
100     const ExecutionContext &exe_ctx) {
101   ValueObjectSP valobj_sp(
102       ValueObject::CreateValueObjectFromExpression(name, expression, exe_ctx));
103   if (valobj_sp)
104     valobj_sp->SetSyntheticChildrenGenerated(true);
105   return valobj_sp;
106 }
107
108 lldb::ValueObjectSP SyntheticChildrenFrontEnd::CreateValueObjectFromAddress(
109     llvm::StringRef name, uint64_t address, const ExecutionContext &exe_ctx,
110     CompilerType type) {
111   ValueObjectSP valobj_sp(
112       ValueObject::CreateValueObjectFromAddress(name, address, exe_ctx, type));
113   if (valobj_sp)
114     valobj_sp->SetSyntheticChildrenGenerated(true);
115   return valobj_sp;
116 }
117
118 lldb::ValueObjectSP SyntheticChildrenFrontEnd::CreateValueObjectFromData(
119     llvm::StringRef name, const DataExtractor &data,
120     const ExecutionContext &exe_ctx, CompilerType type) {
121   ValueObjectSP valobj_sp(
122       ValueObject::CreateValueObjectFromData(name, data, exe_ctx, type));
123   if (valobj_sp)
124     valobj_sp->SetSyntheticChildrenGenerated(true);
125   return valobj_sp;
126 }
127
128 ScriptedSyntheticChildren::FrontEnd::FrontEnd(std::string pclass,
129                                               ValueObject &backend)
130     : SyntheticChildrenFrontEnd(backend), m_python_class(pclass),
131       m_wrapper_sp(), m_interpreter(nullptr) {
132   if (backend == LLDB_INVALID_UID)
133     return;
134
135   TargetSP target_sp = backend.GetTargetSP();
136
137   if (!target_sp)
138     return;
139
140   m_interpreter = target_sp->GetDebugger().GetScriptInterpreter();
141
142   if (m_interpreter != nullptr)
143     m_wrapper_sp = m_interpreter->CreateSyntheticScriptedProvider(
144         m_python_class.c_str(), backend.GetSP());
145 }
146
147 ScriptedSyntheticChildren::FrontEnd::~FrontEnd() {}
148
149 lldb::ValueObjectSP
150 ScriptedSyntheticChildren::FrontEnd::GetChildAtIndex(size_t idx) {
151   if (!m_wrapper_sp || !m_interpreter)
152     return lldb::ValueObjectSP();
153
154   return m_interpreter->GetChildAtIndex(m_wrapper_sp, idx);
155 }
156
157 bool ScriptedSyntheticChildren::FrontEnd::IsValid() {
158   return (m_wrapper_sp && m_wrapper_sp->IsValid() && m_interpreter);
159 }
160
161 size_t ScriptedSyntheticChildren::FrontEnd::CalculateNumChildren() {
162   if (!m_wrapper_sp || m_interpreter == nullptr)
163     return 0;
164   return m_interpreter->CalculateNumChildren(m_wrapper_sp, UINT32_MAX);
165 }
166
167 size_t ScriptedSyntheticChildren::FrontEnd::CalculateNumChildren(uint32_t max) {
168   if (!m_wrapper_sp || m_interpreter == nullptr)
169     return 0;
170   return m_interpreter->CalculateNumChildren(m_wrapper_sp, max);
171 }
172
173 bool ScriptedSyntheticChildren::FrontEnd::Update() {
174   if (!m_wrapper_sp || m_interpreter == nullptr)
175     return false;
176
177   return m_interpreter->UpdateSynthProviderInstance(m_wrapper_sp);
178 }
179
180 bool ScriptedSyntheticChildren::FrontEnd::MightHaveChildren() {
181   if (!m_wrapper_sp || m_interpreter == nullptr)
182     return false;
183
184   return m_interpreter->MightHaveChildrenSynthProviderInstance(m_wrapper_sp);
185 }
186
187 size_t ScriptedSyntheticChildren::FrontEnd::GetIndexOfChildWithName(
188     ConstString name) {
189   if (!m_wrapper_sp || m_interpreter == nullptr)
190     return UINT32_MAX;
191   return m_interpreter->GetIndexOfChildWithName(m_wrapper_sp,
192                                                 name.GetCString());
193 }
194
195 lldb::ValueObjectSP ScriptedSyntheticChildren::FrontEnd::GetSyntheticValue() {
196   if (!m_wrapper_sp || m_interpreter == nullptr)
197     return nullptr;
198
199   return m_interpreter->GetSyntheticValue(m_wrapper_sp);
200 }
201
202 ConstString ScriptedSyntheticChildren::FrontEnd::GetSyntheticTypeName() {
203   if (!m_wrapper_sp || m_interpreter == nullptr)
204     return ConstString();
205
206   return m_interpreter->GetSyntheticTypeName(m_wrapper_sp);
207 }
208
209 std::string ScriptedSyntheticChildren::GetDescription() {
210   StreamString sstr;
211   sstr.Printf("%s%s%s Python class %s", Cascades() ? "" : " (not cascading)",
212               SkipsPointers() ? " (skip pointers)" : "",
213               SkipsReferences() ? " (skip references)" : "",
214               m_python_class.c_str());
215
216   return sstr.GetString();
217 }