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/ValueObject.h"
27 #include "lldb/Interpreter/ScriptInterpreterPython.h"
28 #include "lldb/Symbol/Type.h"
30 namespace lldb_private {
31 class SyntheticChildrenFrontEnd
34 ValueObject &m_backend;
50 SyntheticChildrenFrontEnd (ValueObject &backend) :
56 ~SyntheticChildrenFrontEnd ()
61 CalculateNumChildren () = 0;
63 virtual lldb::ValueObjectSP
64 GetChildAtIndex (size_t idx) = 0;
67 GetIndexOfChildWithName (const ConstString &name) = 0;
69 // this function is assumed to always succeed and it if fails, the front-end should know to deal
70 // with it in the correct way (most probably, by refusing to return any children)
71 // the return value of Update() should actually be interpreted as "ValueObjectSyntheticFilter cache is good/bad"
72 // if =true, ValueObjectSyntheticFilter is allowed to use the children it fetched previously and cached
73 // if =false, ValueObjectSyntheticFilter must throw away its cache, and query again for children
77 // if this function returns false, then CalculateNumChildren() MUST return 0 since UI frontends
78 // might validly decide not to inquire for children given a false return value from this call
79 // if it returns true, then CalculateNumChildren() can return any number >= 0 (0 being valid)
80 // it should if at all possible be more efficient than CalculateNumChildren()
82 MightHaveChildren () = 0;
84 typedef std::shared_ptr<SyntheticChildrenFrontEnd> SharedPointer;
85 typedef std::unique_ptr<SyntheticChildrenFrontEnd> AutoPointer;
89 DISALLOW_COPY_AND_ASSIGN(SyntheticChildrenFrontEnd);
92 class SyntheticChildren
101 m_flags (lldb::eTypeOptionCascade)
104 Flags (const Flags& other) :
105 m_flags (other.m_flags)
108 Flags (uint32_t value) :
113 operator = (const Flags& rhs)
116 m_flags = rhs.m_flags;
122 operator = (const uint32_t& rhs)
138 return (m_flags & lldb::eTypeOptionCascade) == lldb::eTypeOptionCascade;
142 SetCascades (bool value = true)
145 m_flags |= lldb::eTypeOptionCascade;
147 m_flags &= ~lldb::eTypeOptionCascade;
152 GetSkipPointers () const
154 return (m_flags & lldb::eTypeOptionSkipPointers) == lldb::eTypeOptionSkipPointers;
158 SetSkipPointers (bool value = true)
161 m_flags |= lldb::eTypeOptionSkipPointers;
163 m_flags &= ~lldb::eTypeOptionSkipPointers;
168 GetSkipReferences () const
170 return (m_flags & lldb::eTypeOptionSkipReferences) == lldb::eTypeOptionSkipReferences;
174 SetSkipReferences (bool value = true)
177 m_flags |= lldb::eTypeOptionSkipReferences;
179 m_flags &= ~lldb::eTypeOptionSkipReferences;
190 SetValue (uint32_t value)
199 SyntheticChildren (const Flags& flags) :
205 ~SyntheticChildren ()
212 return m_flags.GetCascades();
215 SkipsPointers () const
217 return m_flags.GetSkipPointers();
220 SkipsReferences () const
222 return m_flags.GetSkipReferences();
226 SetCascades (bool value)
228 m_flags.SetCascades(value);
232 SetSkipsPointers (bool value)
234 m_flags.SetSkipPointers(value);
238 SetSkipsReferences (bool value)
240 m_flags.SetSkipReferences(value);
246 return m_flags.GetValue();
250 SetOptions (uint32_t value)
252 m_flags.SetValue(value);
259 GetDescription () = 0;
261 virtual SyntheticChildrenFrontEnd::AutoPointer
262 GetFrontEnd (ValueObject &backend) = 0;
264 typedef std::shared_ptr<SyntheticChildren> SharedPointer;
265 typedef bool(*SyntheticChildrenCallback)(void*, ConstString, const SyntheticChildren::SharedPointer&);
270 return m_my_revision;
274 uint32_t m_my_revision;
278 DISALLOW_COPY_AND_ASSIGN(SyntheticChildren);
281 class TypeFilterImpl : public SyntheticChildren
283 std::vector<std::string> m_expression_paths;
285 TypeFilterImpl(const SyntheticChildren::Flags& flags) :
286 SyntheticChildren(flags),
291 TypeFilterImpl(const SyntheticChildren::Flags& flags,
292 const std::initializer_list<const char*> items) :
293 SyntheticChildren(flags),
296 for (auto path : items)
297 AddExpressionPath (path);
301 AddExpressionPath (const char* path)
303 AddExpressionPath(std::string(path));
309 m_expression_paths.clear();
315 return m_expression_paths.size();
319 GetExpressionPathAtIndex(size_t i) const
321 return m_expression_paths[i].c_str();
325 SetExpressionPathAtIndex (size_t i, const char* path)
327 return SetExpressionPathAtIndex(i, std::string(path));
331 AddExpressionPath (const std::string& path)
333 bool need_add_dot = true;
334 if (path[0] == '.' ||
335 (path[0] == '-' && path[1] == '>') ||
337 need_add_dot = false;
338 // add a '.' symbol to help forgetful users
340 m_expression_paths.push_back(path);
342 m_expression_paths.push_back(std::string(".") + path);
346 SetExpressionPathAtIndex (size_t i, const std::string& path)
350 bool need_add_dot = true;
351 if (path[0] == '.' ||
352 (path[0] == '-' && path[1] == '>') ||
354 need_add_dot = false;
355 // add a '.' symbol to help forgetful users
357 m_expression_paths[i] = path;
359 m_expression_paths[i] = std::string(".") + path;
372 class FrontEnd : public SyntheticChildrenFrontEnd
375 TypeFilterImpl* filter;
378 FrontEnd(TypeFilterImpl* flt,
379 ValueObject &backend) :
380 SyntheticChildrenFrontEnd(backend),
390 CalculateNumChildren ()
392 return filter->GetCount();
395 virtual lldb::ValueObjectSP
396 GetChildAtIndex (size_t idx)
398 if (idx >= filter->GetCount())
399 return lldb::ValueObjectSP();
400 return m_backend.GetSyntheticExpressionPathChild(filter->GetExpressionPathAtIndex(idx), true);
404 Update() { return false; }
409 return filter->GetCount() > 0;
413 GetIndexOfChildWithName (const ConstString &name)
415 const char* name_cstr = name.GetCString();
416 for (size_t i = 0; i < filter->GetCount(); i++)
418 const char* expr_cstr = filter->GetExpressionPathAtIndex(i);
421 if (*expr_cstr == '.')
423 else if (*expr_cstr == '-' && *(expr_cstr+1) == '>')
426 if (!::strcmp(name_cstr, expr_cstr))
432 typedef std::shared_ptr<SyntheticChildrenFrontEnd> SharedPointer;
435 DISALLOW_COPY_AND_ASSIGN(FrontEnd);
438 virtual SyntheticChildrenFrontEnd::AutoPointer
439 GetFrontEnd(ValueObject &backend)
441 return SyntheticChildrenFrontEnd::AutoPointer(new FrontEnd(this, backend));
445 DISALLOW_COPY_AND_ASSIGN(TypeFilterImpl);
448 class CXXSyntheticChildren : public SyntheticChildren
451 typedef SyntheticChildrenFrontEnd* (*CreateFrontEndCallback) (CXXSyntheticChildren*, lldb::ValueObjectSP);
453 CreateFrontEndCallback m_create_callback;
454 std::string m_description;
456 CXXSyntheticChildren (const SyntheticChildren::Flags& flags,
457 const char* description,
458 CreateFrontEndCallback callback) :
459 SyntheticChildren(flags),
460 m_create_callback(callback),
461 m_description(description ? description : "")
474 virtual SyntheticChildrenFrontEnd::AutoPointer
475 GetFrontEnd (ValueObject &backend)
477 return SyntheticChildrenFrontEnd::AutoPointer(m_create_callback(this, backend.GetSP()));
481 DISALLOW_COPY_AND_ASSIGN(CXXSyntheticChildren);
484 #ifndef LLDB_DISABLE_PYTHON
486 class ScriptedSyntheticChildren : public SyntheticChildren
488 std::string m_python_class;
489 std::string m_python_code;
492 ScriptedSyntheticChildren (const SyntheticChildren::Flags& flags,
494 const char* pcode = NULL) :
495 SyntheticChildren(flags),
500 m_python_class = pclass;
502 m_python_code = pcode;
506 GetPythonClassName ()
508 return m_python_class.c_str();
514 return m_python_code.c_str();
518 SetPythonClassName (const char* fname)
520 m_python_class.assign(fname);
521 m_python_code.clear();
525 SetPythonCode (const char* script)
527 m_python_code.assign(script);
539 class FrontEnd : public SyntheticChildrenFrontEnd
542 std::string m_python_class;
543 lldb::ScriptInterpreterObjectSP m_wrapper_sp;
544 ScriptInterpreter *m_interpreter;
547 FrontEnd (std::string pclass,
548 ValueObject &backend);
553 return m_wrapper_sp.get() != nullptr && m_wrapper_sp->operator bool() && m_interpreter != nullptr;
560 CalculateNumChildren ()
562 if (!m_wrapper_sp || m_interpreter == NULL)
564 return m_interpreter->CalculateNumChildren(m_wrapper_sp);
567 virtual lldb::ValueObjectSP
568 GetChildAtIndex (size_t idx);
573 if (!m_wrapper_sp || m_interpreter == NULL)
576 return m_interpreter->UpdateSynthProviderInstance(m_wrapper_sp);
582 if (!m_wrapper_sp || m_interpreter == NULL)
585 return m_interpreter->MightHaveChildrenSynthProviderInstance(m_wrapper_sp);
589 GetIndexOfChildWithName (const ConstString &name)
591 if (!m_wrapper_sp || m_interpreter == NULL)
593 return m_interpreter->GetIndexOfChildWithName(m_wrapper_sp, name.GetCString());
596 typedef std::shared_ptr<SyntheticChildrenFrontEnd> SharedPointer;
599 DISALLOW_COPY_AND_ASSIGN(FrontEnd);
602 virtual SyntheticChildrenFrontEnd::AutoPointer
603 GetFrontEnd(ValueObject &backend)
605 auto synth_ptr = SyntheticChildrenFrontEnd::AutoPointer(new FrontEnd(m_python_class, backend));
606 if (synth_ptr && ((FrontEnd*)synth_ptr.get())->IsValid())
612 DISALLOW_COPY_AND_ASSIGN(ScriptedSyntheticChildren);
615 } // namespace lldb_private
617 #endif // lldb_TypeSynthetic_h_