]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/llvm/tools/lldb/source/Core/ValueObjectSyntheticFilter.cpp
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / llvm / tools / lldb / source / Core / ValueObjectSyntheticFilter.cpp
1 //===-- ValueObjectSyntheticFilter.cpp -----------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "lldb/lldb-python.h"
11
12 #include "lldb/Core/ValueObjectSyntheticFilter.h"
13
14 // C Includes
15 // C++ Includes
16 // Other libraries and framework includes
17 // Project includes
18 #include "lldb/Core/ValueObject.h"
19 #include "lldb/DataFormatters/FormatClasses.h"
20
21 using namespace lldb_private;
22
23 class DummySyntheticFrontEnd : public SyntheticChildrenFrontEnd
24 {
25 public:
26     DummySyntheticFrontEnd(ValueObject &backend) :
27     SyntheticChildrenFrontEnd(backend)
28     {}
29
30     size_t
31     CalculateNumChildren()
32     {
33         return 0;
34     }
35     
36     lldb::ValueObjectSP
37     GetChildAtIndex (size_t idx)
38     {
39         return lldb::ValueObjectSP();
40     }
41     
42     size_t
43     GetIndexOfChildWithName (const ConstString &name)
44     {
45         return UINT32_MAX;
46     }
47     
48     bool
49     MightHaveChildren ()
50     {
51         return true;
52     }
53     
54     bool
55     Update()
56     {
57         return false;
58     }
59
60 };
61
62 ValueObjectSynthetic::ValueObjectSynthetic (ValueObject &parent, lldb::SyntheticChildrenSP filter) :
63     ValueObject(parent),
64     m_synth_sp(filter),
65     m_children_byindex(),
66     m_name_toindex(),
67     m_synthetic_children_count(UINT32_MAX),
68     m_parent_type_name(parent.GetTypeName()),
69     m_might_have_children(eLazyBoolCalculate)
70 {
71 #ifdef LLDB_CONFIGURATION_DEBUG
72     std::string new_name(parent.GetName().AsCString());
73     new_name += "$$__synth__";
74     SetName (ConstString(new_name.c_str()));
75 #else
76     SetName(parent.GetName());
77 #endif
78     CopyParentData();
79     CreateSynthFilter();
80 }
81
82 ValueObjectSynthetic::~ValueObjectSynthetic()
83 {
84 }
85
86 ClangASTType
87 ValueObjectSynthetic::GetClangTypeImpl ()
88 {
89     return m_parent->GetClangType();
90 }
91
92 ConstString
93 ValueObjectSynthetic::GetTypeName()
94 {
95     return m_parent->GetTypeName();
96 }
97
98 ConstString
99 ValueObjectSynthetic::GetQualifiedTypeName()
100 {
101     return m_parent->GetQualifiedTypeName();
102 }
103
104 size_t
105 ValueObjectSynthetic::CalculateNumChildren()
106 {
107     UpdateValueIfNeeded();
108     if (m_synthetic_children_count < UINT32_MAX)
109         return m_synthetic_children_count;
110     return (m_synthetic_children_count = m_synth_filter_ap->CalculateNumChildren());
111 }
112
113 lldb::ValueObjectSP
114 ValueObjectSynthetic::GetDynamicValue (lldb::DynamicValueType valueType)
115 {
116     if (!m_parent)
117         return lldb::ValueObjectSP();
118     if (IsDynamic() && GetDynamicValueType() == valueType)
119         return GetSP();
120     return m_parent->GetDynamicValue(valueType);
121 }
122
123 bool
124 ValueObjectSynthetic::MightHaveChildren()
125 {
126     if (m_might_have_children == eLazyBoolCalculate)
127         m_might_have_children = (m_synth_filter_ap->MightHaveChildren() ? eLazyBoolYes : eLazyBoolNo);
128     return (m_might_have_children == eLazyBoolNo ? false : true);
129 }
130
131 uint64_t
132 ValueObjectSynthetic::GetByteSize()
133 {
134     return m_parent->GetByteSize();
135 }
136
137 lldb::ValueType
138 ValueObjectSynthetic::GetValueType() const
139 {
140     return m_parent->GetValueType();
141 }
142
143 void
144 ValueObjectSynthetic::CreateSynthFilter ()
145 {
146     m_synth_filter_ap = (m_synth_sp->GetFrontEnd(*m_parent));
147     if (!m_synth_filter_ap.get())
148         m_synth_filter_ap.reset(new DummySyntheticFrontEnd(*m_parent));
149 }
150
151 bool
152 ValueObjectSynthetic::UpdateValue ()
153 {
154     SetValueIsValid (false);
155     m_error.Clear();
156
157     if (!m_parent->UpdateValueIfNeeded(false))
158     {
159         // our parent could not update.. as we are meaningless without a parent, just stop
160         if (m_parent->GetError().Fail())
161             m_error = m_parent->GetError();
162         return false;
163     }
164     
165     // regenerate the synthetic filter if our typename changes
166     // <rdar://problem/12424824>
167     ConstString new_parent_type_name = m_parent->GetTypeName();
168     if (new_parent_type_name != m_parent_type_name)
169     {
170         m_parent_type_name = new_parent_type_name;
171         CreateSynthFilter();
172     }
173
174     // let our backend do its update
175     if (m_synth_filter_ap->Update() == false)
176     {
177         // filter said that cached values are stale
178         m_children_byindex.clear();
179         m_name_toindex.clear();
180         // usually, an object's value can change but this does not alter its children count
181         // for a synthetic VO that might indeed happen, so we need to tell the upper echelons
182         // that they need to come back to us asking for children
183         m_children_count_valid = false;
184         m_synthetic_children_count = UINT32_MAX;
185         m_might_have_children = eLazyBoolCalculate;
186     }
187     
188     CopyParentData();
189     
190     SetValueIsValid(true);
191     return true;
192 }
193
194 lldb::ValueObjectSP
195 ValueObjectSynthetic::GetChildAtIndex (size_t idx, bool can_create)
196 {
197     UpdateValueIfNeeded();
198     
199     ByIndexIterator iter = m_children_byindex.find(idx);
200     
201     if (iter == m_children_byindex.end())
202     {
203         if (can_create && m_synth_filter_ap.get() != NULL)
204         {
205             lldb::ValueObjectSP synth_guy = m_synth_filter_ap->GetChildAtIndex (idx);
206             if (!synth_guy)
207                 return synth_guy;
208             m_children_byindex[idx]= synth_guy.get();
209             return synth_guy;
210         }
211         else
212             return lldb::ValueObjectSP();
213     }
214     else
215         return iter->second->GetSP();
216 }
217
218 lldb::ValueObjectSP
219 ValueObjectSynthetic::GetChildMemberWithName (const ConstString &name, bool can_create)
220 {
221     UpdateValueIfNeeded();
222
223     uint32_t index = GetIndexOfChildWithName(name);
224     
225     if (index == UINT32_MAX)
226         return lldb::ValueObjectSP();
227     
228     return GetChildAtIndex(index, can_create);
229 }
230
231 size_t
232 ValueObjectSynthetic::GetIndexOfChildWithName (const ConstString &name)
233 {
234     UpdateValueIfNeeded();
235     
236     NameToIndexIterator iter = m_name_toindex.find(name.GetCString());
237     
238     if (iter == m_name_toindex.end() && m_synth_filter_ap.get() != NULL)
239     {
240         uint32_t index = m_synth_filter_ap->GetIndexOfChildWithName (name);
241         if (index == UINT32_MAX)
242             return index;
243         m_name_toindex[name.GetCString()] = index;
244         return index;
245     }
246     else if (iter == m_name_toindex.end() && m_synth_filter_ap.get() == NULL)
247         return UINT32_MAX;
248     else /*if (iter != m_name_toindex.end())*/
249         return iter->second;
250 }
251
252 bool
253 ValueObjectSynthetic::IsInScope ()
254 {
255     return m_parent->IsInScope();
256 }
257
258 lldb::ValueObjectSP
259 ValueObjectSynthetic::GetNonSyntheticValue ()
260 {
261     return m_parent->GetSP();
262 }
263
264 void
265 ValueObjectSynthetic::CopyParentData ()
266 {
267     m_value = m_parent->GetValue();
268     ExecutionContext exe_ctx (GetExecutionContextRef());
269     m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get());
270 }