LLDB  mainline
TypeSynthetic.h
Go to the documentation of this file.
1 //===-- TypeSynthetic.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_TypeSynthetic_h_
10 #define lldb_TypeSynthetic_h_
11 
12 #include <stdint.h>
13 
14 #include <functional>
15 #include <initializer_list>
16 #include <memory>
17 #include <string>
18 #include <vector>
19 
20 #include "lldb/lldb-enumerations.h"
21 #include "lldb/lldb-public.h"
22 
23 #include "lldb/Core/ValueObject.h"
25 
26 namespace lldb_private {
28 protected:
30 
31  void SetValid(bool valid) { m_valid = valid; }
32 
33  bool IsValid() { return m_valid; }
34 
35 public:
37  : m_backend(backend), m_valid(true) {}
38 
39  virtual ~SyntheticChildrenFrontEnd() = default;
40 
41  virtual size_t CalculateNumChildren() = 0;
42 
43  virtual size_t CalculateNumChildren(uint32_t max) {
44  auto count = CalculateNumChildren();
45  return count <= max ? count : max;
46  }
47 
48  virtual lldb::ValueObjectSP GetChildAtIndex(size_t idx) = 0;
49 
50  virtual size_t GetIndexOfChildWithName(ConstString name) = 0;
51 
52  // this function is assumed to always succeed and it if fails, the front-end
53  // should know to deal with it in the correct way (most probably, by refusing
54  // to return any children) the return value of Update() should actually be
55  // interpreted as "ValueObjectSyntheticFilter cache is good/bad" if =true,
56  // ValueObjectSyntheticFilter is allowed to use the children it fetched
57  // previously and cached if =false, ValueObjectSyntheticFilter must throw
58  // away its cache, and query again for children
59  virtual bool Update() = 0;
60 
61  // if this function returns false, then CalculateNumChildren() MUST return 0
62  // since UI frontends might validly decide not to inquire for children given
63  // a false return value from this call if it returns true, then
64  // CalculateNumChildren() can return any number >= 0 (0 being valid) it
65  // should if at all possible be more efficient than CalculateNumChildren()
66  virtual bool MightHaveChildren() = 0;
67 
68  // if this function returns a non-null ValueObject, then the returned
69  // ValueObject will stand for this ValueObject whenever a "value" request is
70  // made to this ValueObject
71  virtual lldb::ValueObjectSP GetSyntheticValue() { return nullptr; }
72 
73  // if this function returns a non-empty ConstString, then clients are
74  // expected to use the return as the name of the type of this ValueObject for
75  // display purposes
77 
78  typedef std::shared_ptr<SyntheticChildrenFrontEnd> SharedPointer;
79  typedef std::unique_ptr<SyntheticChildrenFrontEnd> AutoPointer;
80 
81 protected:
82  lldb::ValueObjectSP
83  CreateValueObjectFromExpression(llvm::StringRef name,
84  llvm::StringRef expression,
85  const ExecutionContext &exe_ctx);
86 
87  lldb::ValueObjectSP
88  CreateValueObjectFromAddress(llvm::StringRef name, uint64_t address,
89  const ExecutionContext &exe_ctx,
90  CompilerType type);
91 
92  lldb::ValueObjectSP CreateValueObjectFromData(llvm::StringRef name,
93  const DataExtractor &data,
94  const ExecutionContext &exe_ctx,
95  CompilerType type);
96 
97 private:
98  bool m_valid;
99  DISALLOW_COPY_AND_ASSIGN(SyntheticChildrenFrontEnd);
100 };
101 
103 public:
105  : SyntheticChildrenFrontEnd(backend) {}
106 
107  ~SyntheticValueProviderFrontEnd() override = default;
108 
109  size_t CalculateNumChildren() override { return 0; }
110 
111  lldb::ValueObjectSP GetChildAtIndex(size_t idx) override { return nullptr; }
112 
113  size_t GetIndexOfChildWithName(ConstString name) override {
114  return UINT32_MAX;
115  }
116 
117  bool Update() override { return false; }
118 
119  bool MightHaveChildren() override { return false; }
120 
121  lldb::ValueObjectSP GetSyntheticValue() override = 0;
122 
123 private:
124  DISALLOW_COPY_AND_ASSIGN(SyntheticValueProviderFrontEnd);
125 };
126 
128 public:
129  class Flags {
130  public:
131  Flags() : m_flags(lldb::eTypeOptionCascade) {}
132 
133  Flags(const Flags &other) : m_flags(other.m_flags) {}
134 
135  Flags(uint32_t value) : m_flags(value) {}
136 
137  Flags &operator=(const Flags &rhs) {
138  if (&rhs != this)
139  m_flags = rhs.m_flags;
140 
141  return *this;
142  }
143 
144  Flags &operator=(const uint32_t &rhs) {
145  m_flags = rhs;
146  return *this;
147  }
148 
150  m_flags = 0;
151  return *this;
152  }
153 
154  bool GetCascades() const {
155  return (m_flags & lldb::eTypeOptionCascade) == lldb::eTypeOptionCascade;
156  }
157 
158  Flags &SetCascades(bool value = true) {
159  if (value)
160  m_flags |= lldb::eTypeOptionCascade;
161  else
162  m_flags &= ~lldb::eTypeOptionCascade;
163  return *this;
164  }
165 
166  bool GetSkipPointers() const {
167  return (m_flags & lldb::eTypeOptionSkipPointers) ==
168  lldb::eTypeOptionSkipPointers;
169  }
170 
171  Flags &SetSkipPointers(bool value = true) {
172  if (value)
173  m_flags |= lldb::eTypeOptionSkipPointers;
174  else
175  m_flags &= ~lldb::eTypeOptionSkipPointers;
176  return *this;
177  }
178 
179  bool GetSkipReferences() const {
180  return (m_flags & lldb::eTypeOptionSkipReferences) ==
181  lldb::eTypeOptionSkipReferences;
182  }
183 
184  Flags &SetSkipReferences(bool value = true) {
185  if (value)
186  m_flags |= lldb::eTypeOptionSkipReferences;
187  else
188  m_flags &= ~lldb::eTypeOptionSkipReferences;
189  return *this;
190  }
191 
192  bool GetNonCacheable() const {
193  return (m_flags & lldb::eTypeOptionNonCacheable) ==
194  lldb::eTypeOptionNonCacheable;
195  }
196 
197  Flags &SetNonCacheable(bool value = true) {
198  if (value)
199  m_flags |= lldb::eTypeOptionNonCacheable;
200  else
201  m_flags &= ~lldb::eTypeOptionNonCacheable;
202  return *this;
203  }
204 
206  return (m_flags & lldb::eTypeOptionFrontEndWantsDereference) ==
207  lldb::eTypeOptionFrontEndWantsDereference;
208  }
209 
210  Flags &SetFrontEndWantsDereference(bool value = true) {
211  if (value)
212  m_flags |= lldb::eTypeOptionFrontEndWantsDereference;
213  else
214  m_flags &= ~lldb::eTypeOptionFrontEndWantsDereference;
215  return *this;
216  }
217 
218  uint32_t GetValue() { return m_flags; }
219 
220  void SetValue(uint32_t value) { m_flags = value; }
221 
222  private:
223  uint32_t m_flags;
224  };
225 
226  SyntheticChildren(const Flags &flags) : m_flags(flags) {}
227 
228  virtual ~SyntheticChildren() = default;
229 
230  bool Cascades() const { return m_flags.GetCascades(); }
231 
232  bool SkipsPointers() const { return m_flags.GetSkipPointers(); }
233 
234  bool SkipsReferences() const { return m_flags.GetSkipReferences(); }
235 
236  bool NonCacheable() const { return m_flags.GetNonCacheable(); }
237 
238  bool WantsDereference() const { return m_flags.GetFrontEndWantsDereference();}
239 
240  void SetCascades(bool value) { m_flags.SetCascades(value); }
241 
242  void SetSkipsPointers(bool value) { m_flags.SetSkipPointers(value); }
243 
244  void SetSkipsReferences(bool value) { m_flags.SetSkipReferences(value); }
245 
246  void SetNonCacheable(bool value) { m_flags.SetNonCacheable(value); }
247 
248  uint32_t GetOptions() { return m_flags.GetValue(); }
249 
250  void SetOptions(uint32_t value) { m_flags.SetValue(value); }
251 
252  virtual bool IsScripted() = 0;
253 
254  virtual std::string GetDescription() = 0;
255 
257  GetFrontEnd(ValueObject &backend) = 0;
258 
259  typedef std::shared_ptr<SyntheticChildren> SharedPointer;
260 
261  uint32_t &GetRevision() { return m_my_revision; }
262 
263 protected:
266 
267 private:
268  DISALLOW_COPY_AND_ASSIGN(SyntheticChildren);
269 };
270 
272  std::vector<std::string> m_expression_paths;
273 
274 public:
276  : SyntheticChildren(flags), m_expression_paths() {}
277 
279  const std::initializer_list<const char *> items)
280  : SyntheticChildren(flags), m_expression_paths() {
281  for (auto path : items)
282  AddExpressionPath(path);
283  }
284 
285  void AddExpressionPath(const char *path) {
286  AddExpressionPath(std::string(path));
287  }
288 
289  void Clear() { m_expression_paths.clear(); }
290 
291  size_t GetCount() const { return m_expression_paths.size(); }
292 
293  const char *GetExpressionPathAtIndex(size_t i) const {
294  return m_expression_paths[i].c_str();
295  }
296 
297  bool SetExpressionPathAtIndex(size_t i, const char *path) {
298  return SetExpressionPathAtIndex(i, std::string(path));
299  }
300 
301  void AddExpressionPath(const std::string &path);
302 
303  bool SetExpressionPathAtIndex(size_t i, const std::string &path);
304 
305  bool IsScripted() override { return false; }
306 
307  std::string GetDescription() override;
308 
310  public:
312  : SyntheticChildrenFrontEnd(backend), filter(flt) {}
313 
314  ~FrontEnd() override = default;
315 
316  size_t CalculateNumChildren() override { return filter->GetCount(); }
317 
318  lldb::ValueObjectSP GetChildAtIndex(size_t idx) override {
319  if (idx >= filter->GetCount())
320  return lldb::ValueObjectSP();
322  filter->GetExpressionPathAtIndex(idx), true);
323  }
324 
325  bool Update() override { return false; }
326 
327  bool MightHaveChildren() override { return filter->GetCount() > 0; }
328 
329  size_t GetIndexOfChildWithName(ConstString name) override;
330 
331  typedef std::shared_ptr<SyntheticChildrenFrontEnd> SharedPointer;
332 
333  private:
334  TypeFilterImpl *filter;
335 
336  DISALLOW_COPY_AND_ASSIGN(FrontEnd);
337  };
338 
340  GetFrontEnd(ValueObject &backend) override {
341  return SyntheticChildrenFrontEnd::AutoPointer(new FrontEnd(this, backend));
342  }
343 
344  typedef std::shared_ptr<TypeFilterImpl> SharedPointer;
345 
346 private:
347  DISALLOW_COPY_AND_ASSIGN(TypeFilterImpl);
348 };
349 
351 public:
352  typedef std::function<SyntheticChildrenFrontEnd *(CXXSyntheticChildren *,
353  lldb::ValueObjectSP)>
356  const char *description, CreateFrontEndCallback callback)
357  : SyntheticChildren(flags), m_create_callback(callback),
358  m_description(description ? description : "") {}
359 
360  bool IsScripted() override { return false; }
361 
362  std::string GetDescription() override;
363 
365  GetFrontEnd(ValueObject &backend) override {
367  m_create_callback(this, backend.GetSP()));
368  }
369 
370 protected:
372  std::string m_description;
373 
374 private:
375  DISALLOW_COPY_AND_ASSIGN(CXXSyntheticChildren);
376 };
377 
379  std::string m_python_class;
380  std::string m_python_code;
381 
382 public:
384  const char *pclass, const char *pcode = nullptr)
385  : SyntheticChildren(flags), m_python_class(), m_python_code() {
386  if (pclass)
387  m_python_class = pclass;
388  if (pcode)
389  m_python_code = pcode;
390  }
391 
392  const char *GetPythonClassName() { return m_python_class.c_str(); }
393 
394  const char *GetPythonCode() { return m_python_code.c_str(); }
395 
396  void SetPythonClassName(const char *fname) {
397  m_python_class.assign(fname);
398  m_python_code.clear();
399  }
400 
401  void SetPythonCode(const char *script) { m_python_code.assign(script); }
402 
403  std::string GetDescription() override;
404 
405  bool IsScripted() override { return true; }
406 
408  public:
409  FrontEnd(std::string pclass, ValueObject &backend);
410 
411  ~FrontEnd() override;
412 
413  bool IsValid();
414 
415  size_t CalculateNumChildren() override;
416 
417  size_t CalculateNumChildren(uint32_t max) override;
418 
419  lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
420 
421  bool Update() override;
422 
423  bool MightHaveChildren() override;
424 
425  size_t GetIndexOfChildWithName(ConstString name) override;
426 
427  lldb::ValueObjectSP GetSyntheticValue() override;
428 
430 
431  typedef std::shared_ptr<SyntheticChildrenFrontEnd> SharedPointer;
432 
433  private:
434  std::string m_python_class;
435  StructuredData::ObjectSP m_wrapper_sp;
436  ScriptInterpreter *m_interpreter;
437 
438  DISALLOW_COPY_AND_ASSIGN(FrontEnd);
439  };
440 
442  GetFrontEnd(ValueObject &backend) override {
444  new FrontEnd(m_python_class, backend));
445  if (synth_ptr && ((FrontEnd *)synth_ptr.get())->IsValid())
446  return synth_ptr;
447  return nullptr;
448  }
449 
450 private:
451  DISALLOW_COPY_AND_ASSIGN(ScriptedSyntheticChildren);
452 };
453 } // namespace lldb_private
454 
455 #endif // lldb_TypeSynthetic_h_
virtual lldb::ValueObjectSP GetSyntheticValue()
Definition: TypeSynthetic.h:71
virtual ConstString GetSyntheticTypeName()
Definition: TypeSynthetic.h:76
void SetPythonClassName(const char *fname)
An data extractor class.
Definition: DataExtractor.h:47
SyntheticChildrenFrontEnd::AutoPointer GetFrontEnd(ValueObject &backend) override
const char * GetExpressionPathAtIndex(size_t i) const
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
void SetOptions(uint32_t value)
ScriptedSyntheticChildren(const SyntheticChildren::Flags &flags, const char *pclass, const char *pcode=nullptr)
lldb::ValueObjectSP GetSyntheticExpressionPathChild(const char *expression, bool can_create)
Flags & SetSkipReferences(bool value=true)
FrontEnd(TypeFilterImpl *flt, ValueObject &backend)
Flags & SetNonCacheable(bool value=true)
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
std::shared_ptr< TypeFilterImpl > SharedPointer
SyntheticValueProviderFrontEnd(ValueObject &backend)
CXXSyntheticChildren(const SyntheticChildren::Flags &flags, const char *description, CreateFrontEndCallback callback)
Flags & SetCascades(bool value=true)
lldb::ValueObjectSP CreateValueObjectFromExpression(llvm::StringRef name, llvm::StringRef expression, const ExecutionContext &exe_ctx)
CreateFrontEndCallback m_create_callback
void SetPythonCode(const char *script)
std::shared_ptr< SyntheticChildren > SharedPointer
#define UINT32_MAX
Definition: lldb-defines.h:31
Flags & SetFrontEndWantsDereference(bool value=true)
std::shared_ptr< SyntheticChildrenFrontEnd > SharedPointer
lldb::ValueObjectSP CreateValueObjectFromData(llvm::StringRef name, const DataExtractor &data, const ExecutionContext &exe_ctx, CompilerType type)
virtual lldb::ValueObjectSP GetChildAtIndex(size_t idx)=0
SyntheticChildrenFrontEnd::AutoPointer GetFrontEnd(ValueObject &backend) override
void AddExpressionPath(const char *path)
Flags & SetSkipPointers(bool value=true)
bool SetExpressionPathAtIndex(size_t i, const char *path)
std::shared_ptr< SyntheticChildrenFrontEnd > SharedPointer
lldb::ValueObjectSP GetChildAtIndex(size_t idx) override
virtual size_t CalculateNumChildren(uint32_t max)
Definition: TypeSynthetic.h:43
SyntheticChildrenFrontEnd(ValueObject &backend)
Definition: TypeSynthetic.h:36
virtual size_t GetIndexOfChildWithName(ConstString name)=0
TypeFilterImpl(const SyntheticChildren::Flags &flags)
SyntheticChildrenFrontEnd::AutoPointer GetFrontEnd(ValueObject &backend) override
size_t GetIndexOfChildWithName(ConstString name) override
lldb::ValueObjectSP CreateValueObjectFromAddress(llvm::StringRef name, uint64_t address, const ExecutionContext &exe_ctx, CompilerType type)
A uniqued constant string class.
Definition: ConstString.h:38
lldb::ValueObjectSP GetChildAtIndex(size_t idx) override
void SetSkipsReferences(bool value)
Definition: SBAddress.h:15
lldb::ValueObjectSP GetSP()
Definition: ValueObject.h:565
std::shared_ptr< Object > ObjectSP
Flags & operator=(const Flags &rhs)
SyntheticChildren(const Flags &flags)
std::unique_ptr< SyntheticChildrenFrontEnd > AutoPointer
Definition: TypeSynthetic.h:79
std::function< SyntheticChildrenFrontEnd *(CXXSyntheticChildren *, lldb::ValueObjectSP)> CreateFrontEndCallback
Flags & operator=(const uint32_t &rhs)
TypeFilterImpl(const SyntheticChildren::Flags &flags, const std::initializer_list< const char *> items)
std::shared_ptr< SyntheticChildrenFrontEnd > SharedPointer
Definition: TypeSynthetic.h:78