1 //===-- TypeSynthetic.h -------------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #ifndef lldb_TypeSynthetic_h_
11 #define lldb_TypeSynthetic_h_
20 // Other libraries and framework includes
23 #include "lldb/lldb-public.h"
24 #include "lldb/lldb-enumerations.h"
26 #include "lldb/Core/StructuredData.h"
27 #include "lldb/Core/ValueObject.h"
29 namespace lldb_private {
30 class SyntheticChildrenFrontEnd
33 ValueObject &m_backend;
49 SyntheticChildrenFrontEnd (ValueObject &backend) :
55 ~SyntheticChildrenFrontEnd ()
60 CalculateNumChildren () = 0;
62 virtual lldb::ValueObjectSP
63 GetChildAtIndex (size_t idx) = 0;
66 GetIndexOfChildWithName (const ConstString &name) = 0;
68 // this function is assumed to always succeed and it if fails, the front-end should know to deal
69 // with it in the correct way (most probably, by refusing to return any children)
70 // the return value of Update() should actually be interpreted as "ValueObjectSyntheticFilter cache is good/bad"
71 // if =true, ValueObjectSyntheticFilter is allowed to use the children it fetched previously and cached
72 // if =false, ValueObjectSyntheticFilter must throw away its cache, and query again for children
76 // if this function returns false, then CalculateNumChildren() MUST return 0 since UI frontends
77 // might validly decide not to inquire for children given a false return value from this call
78 // if it returns true, then CalculateNumChildren() can return any number >= 0 (0 being valid)
79 // it should if at all possible be more efficient than CalculateNumChildren()
81 MightHaveChildren () = 0;
83 // if this function returns a non-null ValueObject, then the returned ValueObject will stand
84 // for this ValueObject whenever a "value" request is made to this ValueObject
85 virtual lldb::ValueObjectSP
86 GetSyntheticValue () { return nullptr; }
88 typedef std::shared_ptr<SyntheticChildrenFrontEnd> SharedPointer;
89 typedef std::unique_ptr<SyntheticChildrenFrontEnd> AutoPointer;
93 CreateValueObjectFromExpression (const char* name,
94 const char* expression,
95 const ExecutionContext& exe_ctx);
98 CreateValueObjectFromAddress (const char* name,
100 const ExecutionContext& exe_ctx,
104 CreateValueObjectFromData (const char* name,
105 const DataExtractor& data,
106 const ExecutionContext& exe_ctx,
111 DISALLOW_COPY_AND_ASSIGN(SyntheticChildrenFrontEnd);
114 class SyntheticValueProviderFrontEnd : public SyntheticChildrenFrontEnd
117 SyntheticValueProviderFrontEnd (ValueObject &backend) :
118 SyntheticChildrenFrontEnd(backend)
122 ~SyntheticValueProviderFrontEnd ()
127 CalculateNumChildren () { return 0; }
129 virtual lldb::ValueObjectSP
130 GetChildAtIndex (size_t idx) { return nullptr; }
133 GetIndexOfChildWithName (const ConstString &name) { return UINT32_MAX; }
136 Update () { return false; }
139 MightHaveChildren () { return false; }
141 virtual lldb::ValueObjectSP
142 GetSyntheticValue () = 0;
145 DISALLOW_COPY_AND_ASSIGN(SyntheticValueProviderFrontEnd);
148 class SyntheticChildren
157 m_flags (lldb::eTypeOptionCascade)
160 Flags (const Flags& other) :
161 m_flags (other.m_flags)
164 Flags (uint32_t value) :
169 operator = (const Flags& rhs)
172 m_flags = rhs.m_flags;
178 operator = (const uint32_t& rhs)
194 return (m_flags & lldb::eTypeOptionCascade) == lldb::eTypeOptionCascade;
198 SetCascades (bool value = true)
201 m_flags |= lldb::eTypeOptionCascade;
203 m_flags &= ~lldb::eTypeOptionCascade;
208 GetSkipPointers () const
210 return (m_flags & lldb::eTypeOptionSkipPointers) == lldb::eTypeOptionSkipPointers;
214 SetSkipPointers (bool value = true)
217 m_flags |= lldb::eTypeOptionSkipPointers;
219 m_flags &= ~lldb::eTypeOptionSkipPointers;
224 GetSkipReferences () const
226 return (m_flags & lldb::eTypeOptionSkipReferences) == lldb::eTypeOptionSkipReferences;
230 SetSkipReferences (bool value = true)
233 m_flags |= lldb::eTypeOptionSkipReferences;
235 m_flags &= ~lldb::eTypeOptionSkipReferences;
240 GetNonCacheable () const
242 return (m_flags & lldb::eTypeOptionNonCacheable) == lldb::eTypeOptionNonCacheable;
246 SetNonCacheable (bool value = true)
249 m_flags |= lldb::eTypeOptionNonCacheable;
251 m_flags &= ~lldb::eTypeOptionNonCacheable;
262 SetValue (uint32_t value)
271 SyntheticChildren (const Flags& flags) :
277 ~SyntheticChildren ()
284 return m_flags.GetCascades();
287 SkipsPointers () const
289 return m_flags.GetSkipPointers();
292 SkipsReferences () const
294 return m_flags.GetSkipReferences();
297 NonCacheable () const
299 return m_flags.GetNonCacheable();
303 SetCascades (bool value)
305 m_flags.SetCascades(value);
309 SetSkipsPointers (bool value)
311 m_flags.SetSkipPointers(value);
315 SetSkipsReferences (bool value)
317 m_flags.SetSkipReferences(value);
321 SetNonCacheable (bool value)
323 m_flags.SetNonCacheable(value);
329 return m_flags.GetValue();
333 SetOptions (uint32_t value)
335 m_flags.SetValue(value);
342 GetDescription () = 0;
344 virtual SyntheticChildrenFrontEnd::AutoPointer
345 GetFrontEnd (ValueObject &backend) = 0;
347 typedef std::shared_ptr<SyntheticChildren> SharedPointer;
348 typedef bool(*SyntheticChildrenCallback)(void*, ConstString, const SyntheticChildren::SharedPointer&);
353 return m_my_revision;
357 uint32_t m_my_revision;
361 DISALLOW_COPY_AND_ASSIGN(SyntheticChildren);
364 class TypeFilterImpl : public SyntheticChildren
366 std::vector<std::string> m_expression_paths;
368 TypeFilterImpl(const SyntheticChildren::Flags& flags) :
369 SyntheticChildren(flags),
374 TypeFilterImpl(const SyntheticChildren::Flags& flags,
375 const std::initializer_list<const char*> items) :
376 SyntheticChildren(flags),
379 for (auto path : items)
380 AddExpressionPath (path);
384 AddExpressionPath (const char* path)
386 AddExpressionPath(std::string(path));
392 m_expression_paths.clear();
398 return m_expression_paths.size();
402 GetExpressionPathAtIndex(size_t i) const
404 return m_expression_paths[i].c_str();
408 SetExpressionPathAtIndex (size_t i, const char* path)
410 return SetExpressionPathAtIndex(i, std::string(path));
414 AddExpressionPath (const std::string& path);
417 SetExpressionPathAtIndex (size_t i, const std::string& path);
428 class FrontEnd : public SyntheticChildrenFrontEnd
431 TypeFilterImpl* filter;
434 FrontEnd(TypeFilterImpl* flt,
435 ValueObject &backend) :
436 SyntheticChildrenFrontEnd(backend),
446 CalculateNumChildren ()
448 return filter->GetCount();
451 virtual lldb::ValueObjectSP
452 GetChildAtIndex (size_t idx)
454 if (idx >= filter->GetCount())
455 return lldb::ValueObjectSP();
456 return m_backend.GetSyntheticExpressionPathChild(filter->GetExpressionPathAtIndex(idx), true);
460 Update() { return false; }
465 return filter->GetCount() > 0;
469 GetIndexOfChildWithName (const ConstString &name);
471 typedef std::shared_ptr<SyntheticChildrenFrontEnd> SharedPointer;
474 DISALLOW_COPY_AND_ASSIGN(FrontEnd);
477 virtual SyntheticChildrenFrontEnd::AutoPointer
478 GetFrontEnd(ValueObject &backend)
480 return SyntheticChildrenFrontEnd::AutoPointer(new FrontEnd(this, backend));
484 DISALLOW_COPY_AND_ASSIGN(TypeFilterImpl);
487 class CXXSyntheticChildren : public SyntheticChildren
490 typedef SyntheticChildrenFrontEnd* (*CreateFrontEndCallback) (CXXSyntheticChildren*, lldb::ValueObjectSP);
492 CreateFrontEndCallback m_create_callback;
493 std::string m_description;
495 CXXSyntheticChildren (const SyntheticChildren::Flags& flags,
496 const char* description,
497 CreateFrontEndCallback callback) :
498 SyntheticChildren(flags),
499 m_create_callback(callback),
500 m_description(description ? description : "")
513 virtual SyntheticChildrenFrontEnd::AutoPointer
514 GetFrontEnd (ValueObject &backend)
516 return SyntheticChildrenFrontEnd::AutoPointer(m_create_callback(this, backend.GetSP()));
520 DISALLOW_COPY_AND_ASSIGN(CXXSyntheticChildren);
523 #ifndef LLDB_DISABLE_PYTHON
525 class ScriptedSyntheticChildren : public SyntheticChildren
527 std::string m_python_class;
528 std::string m_python_code;
531 ScriptedSyntheticChildren (const SyntheticChildren::Flags& flags,
533 const char* pcode = NULL) :
534 SyntheticChildren(flags),
539 m_python_class = pclass;
541 m_python_code = pcode;
545 GetPythonClassName ()
547 return m_python_class.c_str();
553 return m_python_code.c_str();
557 SetPythonClassName (const char* fname)
559 m_python_class.assign(fname);
560 m_python_code.clear();
564 SetPythonCode (const char* script)
566 m_python_code.assign(script);
578 class FrontEnd : public SyntheticChildrenFrontEnd
581 std::string m_python_class;
582 StructuredData::ObjectSP m_wrapper_sp;
583 ScriptInterpreter *m_interpreter;
586 FrontEnd (std::string pclass,
587 ValueObject &backend);
596 CalculateNumChildren ();
598 virtual lldb::ValueObjectSP
599 GetChildAtIndex (size_t idx);
605 MightHaveChildren ();
608 GetIndexOfChildWithName (const ConstString &name);
610 virtual lldb::ValueObjectSP
611 GetSyntheticValue ();
613 typedef std::shared_ptr<SyntheticChildrenFrontEnd> SharedPointer;
616 DISALLOW_COPY_AND_ASSIGN(FrontEnd);
619 virtual SyntheticChildrenFrontEnd::AutoPointer
620 GetFrontEnd(ValueObject &backend)
622 auto synth_ptr = SyntheticChildrenFrontEnd::AutoPointer(new FrontEnd(m_python_class, backend));
623 if (synth_ptr && ((FrontEnd*)synth_ptr.get())->IsValid())
629 DISALLOW_COPY_AND_ASSIGN(ScriptedSyntheticChildren);
632 } // namespace lldb_private
634 #endif // lldb_TypeSynthetic_h_