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_
21 // Other libraries and framework includes
24 #include "lldb/lldb-public.h"
25 #include "lldb/lldb-enumerations.h"
27 #include "lldb/Core/ValueObject.h"
28 #include "lldb/Interpreter/ScriptInterpreterPython.h"
29 #include "lldb/Symbol/Type.h"
31 namespace lldb_private {
32 class SyntheticChildrenFrontEnd
35 ValueObject &m_backend;
38 SyntheticChildrenFrontEnd (ValueObject &backend) :
43 ~SyntheticChildrenFrontEnd ()
48 CalculateNumChildren () = 0;
50 virtual lldb::ValueObjectSP
51 GetChildAtIndex (size_t idx) = 0;
54 GetIndexOfChildWithName (const ConstString &name) = 0;
56 // this function is assumed to always succeed and it if fails, the front-end should know to deal
57 // with it in the correct way (most probably, by refusing to return any children)
58 // the return value of Update() should actually be interpreted as "ValueObjectSyntheticFilter cache is good/bad"
59 // if =true, ValueObjectSyntheticFilter is allowed to use the children it fetched previously and cached
60 // if =false, ValueObjectSyntheticFilter must throw away its cache, and query again for children
64 // if this function returns false, then CalculateNumChildren() MUST return 0 since UI frontends
65 // might validly decide not to inquire for children given a false return value from this call
66 // if it returns true, then CalculateNumChildren() can return any number >= 0 (0 being valid)
67 // it should if at all possible be more efficient than CalculateNumChildren()
69 MightHaveChildren () = 0;
71 typedef std::shared_ptr<SyntheticChildrenFrontEnd> SharedPointer;
72 typedef std::unique_ptr<SyntheticChildrenFrontEnd> AutoPointer;
75 DISALLOW_COPY_AND_ASSIGN(SyntheticChildrenFrontEnd);
78 class SyntheticChildren
87 m_flags (lldb::eTypeOptionCascade)
90 Flags (const Flags& other) :
91 m_flags (other.m_flags)
94 Flags (uint32_t value) :
99 operator = (const Flags& rhs)
102 m_flags = rhs.m_flags;
108 operator = (const uint32_t& rhs)
124 return (m_flags & lldb::eTypeOptionCascade) == lldb::eTypeOptionCascade;
128 SetCascades (bool value = true)
131 m_flags |= lldb::eTypeOptionCascade;
133 m_flags &= ~lldb::eTypeOptionCascade;
138 GetSkipPointers () const
140 return (m_flags & lldb::eTypeOptionSkipPointers) == lldb::eTypeOptionSkipPointers;
144 SetSkipPointers (bool value = true)
147 m_flags |= lldb::eTypeOptionSkipPointers;
149 m_flags &= ~lldb::eTypeOptionSkipPointers;
154 GetSkipReferences () const
156 return (m_flags & lldb::eTypeOptionSkipReferences) == lldb::eTypeOptionSkipReferences;
160 SetSkipReferences (bool value = true)
163 m_flags |= lldb::eTypeOptionSkipReferences;
165 m_flags &= ~lldb::eTypeOptionSkipReferences;
176 SetValue (uint32_t value)
185 SyntheticChildren (const Flags& flags) :
191 ~SyntheticChildren ()
198 return m_flags.GetCascades();
201 SkipsPointers () const
203 return m_flags.GetSkipPointers();
206 SkipsReferences () const
208 return m_flags.GetSkipReferences();
212 SetCascades (bool value)
214 m_flags.SetCascades(value);
218 SetSkipsPointers (bool value)
220 m_flags.SetSkipPointers(value);
224 SetSkipsReferences (bool value)
226 m_flags.SetSkipReferences(value);
232 return m_flags.GetValue();
236 SetOptions (uint32_t value)
238 m_flags.SetValue(value);
245 GetDescription () = 0;
247 virtual SyntheticChildrenFrontEnd::AutoPointer
248 GetFrontEnd (ValueObject &backend) = 0;
250 typedef std::shared_ptr<SyntheticChildren> SharedPointer;
251 typedef bool(*SyntheticChildrenCallback)(void*, ConstString, const SyntheticChildren::SharedPointer&);
256 return m_my_revision;
260 uint32_t m_my_revision;
264 DISALLOW_COPY_AND_ASSIGN(SyntheticChildren);
267 class TypeFilterImpl : public SyntheticChildren
269 std::vector<std::string> m_expression_paths;
271 TypeFilterImpl(const SyntheticChildren::Flags& flags) :
272 SyntheticChildren(flags),
277 TypeFilterImpl(const SyntheticChildren::Flags& flags,
278 const std::initializer_list<const char*> items) :
279 SyntheticChildren(flags),
282 for (auto path : items)
283 AddExpressionPath (path);
287 AddExpressionPath (const char* path)
289 AddExpressionPath(std::string(path));
295 m_expression_paths.clear();
301 return m_expression_paths.size();
305 GetExpressionPathAtIndex(size_t i) const
307 return m_expression_paths[i].c_str();
311 SetExpressionPathAtIndex (size_t i, const char* path)
313 return SetExpressionPathAtIndex(i, std::string(path));
317 AddExpressionPath (const std::string& path)
319 bool need_add_dot = true;
320 if (path[0] == '.' ||
321 (path[0] == '-' && path[1] == '>') ||
323 need_add_dot = false;
324 // add a '.' symbol to help forgetful users
326 m_expression_paths.push_back(path);
328 m_expression_paths.push_back(std::string(".") + path);
332 SetExpressionPathAtIndex (size_t i, const std::string& path)
336 bool need_add_dot = true;
337 if (path[0] == '.' ||
338 (path[0] == '-' && path[1] == '>') ||
340 need_add_dot = false;
341 // add a '.' symbol to help forgetful users
343 m_expression_paths[i] = path;
345 m_expression_paths[i] = std::string(".") + path;
358 class FrontEnd : public SyntheticChildrenFrontEnd
361 TypeFilterImpl* filter;
364 FrontEnd(TypeFilterImpl* flt,
365 ValueObject &backend) :
366 SyntheticChildrenFrontEnd(backend),
376 CalculateNumChildren ()
378 return filter->GetCount();
381 virtual lldb::ValueObjectSP
382 GetChildAtIndex (size_t idx)
384 if (idx >= filter->GetCount())
385 return lldb::ValueObjectSP();
386 return m_backend.GetSyntheticExpressionPathChild(filter->GetExpressionPathAtIndex(idx), true);
390 Update() { return false; }
395 return filter->GetCount() > 0;
399 GetIndexOfChildWithName (const ConstString &name)
401 const char* name_cstr = name.GetCString();
402 for (size_t i = 0; i < filter->GetCount(); i++)
404 const char* expr_cstr = filter->GetExpressionPathAtIndex(i);
407 if (*expr_cstr == '.')
409 else if (*expr_cstr == '-' && *(expr_cstr+1) == '>')
412 if (!::strcmp(name_cstr, expr_cstr))
418 typedef std::shared_ptr<SyntheticChildrenFrontEnd> SharedPointer;
421 DISALLOW_COPY_AND_ASSIGN(FrontEnd);
424 virtual SyntheticChildrenFrontEnd::AutoPointer
425 GetFrontEnd(ValueObject &backend)
427 return SyntheticChildrenFrontEnd::AutoPointer(new FrontEnd(this, backend));
431 DISALLOW_COPY_AND_ASSIGN(TypeFilterImpl);
434 class CXXSyntheticChildren : public SyntheticChildren
437 typedef SyntheticChildrenFrontEnd* (*CreateFrontEndCallback) (CXXSyntheticChildren*, lldb::ValueObjectSP);
439 CreateFrontEndCallback m_create_callback;
440 std::string m_description;
442 CXXSyntheticChildren (const SyntheticChildren::Flags& flags,
443 const char* description,
444 CreateFrontEndCallback callback) :
445 SyntheticChildren(flags),
446 m_create_callback(callback),
447 m_description(description ? description : "")
460 virtual SyntheticChildrenFrontEnd::AutoPointer
461 GetFrontEnd (ValueObject &backend)
463 return SyntheticChildrenFrontEnd::AutoPointer(m_create_callback(this, backend.GetSP()));
467 DISALLOW_COPY_AND_ASSIGN(CXXSyntheticChildren);
470 #ifndef LLDB_DISABLE_PYTHON
472 class ScriptedSyntheticChildren : public SyntheticChildren
474 std::string m_python_class;
475 std::string m_python_code;
478 ScriptedSyntheticChildren (const SyntheticChildren::Flags& flags,
480 const char* pcode = NULL) :
481 SyntheticChildren(flags),
486 m_python_class = pclass;
488 m_python_code = pcode;
492 GetPythonClassName ()
494 return m_python_class.c_str();
500 return m_python_code.c_str();
504 SetPythonClassName (const char* fname)
506 m_python_class.assign(fname);
507 m_python_code.clear();
511 SetPythonCode (const char* script)
513 m_python_code.assign(script);
525 class FrontEnd : public SyntheticChildrenFrontEnd
528 std::string m_python_class;
529 lldb::ScriptInterpreterObjectSP m_wrapper_sp;
530 ScriptInterpreter *m_interpreter;
533 FrontEnd (std::string pclass,
534 ValueObject &backend);
540 CalculateNumChildren ()
542 if (!m_wrapper_sp || m_interpreter == NULL)
544 return m_interpreter->CalculateNumChildren(m_wrapper_sp);
547 virtual lldb::ValueObjectSP
548 GetChildAtIndex (size_t idx);
553 if (!m_wrapper_sp || m_interpreter == NULL)
556 return m_interpreter->UpdateSynthProviderInstance(m_wrapper_sp);
562 if (!m_wrapper_sp || m_interpreter == NULL)
565 return m_interpreter->MightHaveChildrenSynthProviderInstance(m_wrapper_sp);
569 GetIndexOfChildWithName (const ConstString &name)
571 if (!m_wrapper_sp || m_interpreter == NULL)
573 return m_interpreter->GetIndexOfChildWithName(m_wrapper_sp, name.GetCString());
576 typedef std::shared_ptr<SyntheticChildrenFrontEnd> SharedPointer;
579 DISALLOW_COPY_AND_ASSIGN(FrontEnd);
582 virtual SyntheticChildrenFrontEnd::AutoPointer
583 GetFrontEnd(ValueObject &backend)
585 return SyntheticChildrenFrontEnd::AutoPointer(new FrontEnd(m_python_class, backend));
589 DISALLOW_COPY_AND_ASSIGN(ScriptedSyntheticChildren);
592 } // namespace lldb_private
594 #endif // lldb_TypeSynthetic_h_