1 //===-- ValueObjectDynamicValue.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 
11 #include "lldb/Core/ValueObjectDynamicValue.h"
12 
13 // C Includes
14 // C++ Includes
15 // Other libraries and framework includes
16 // Project includes
17 #include "lldb/Core/Module.h"
18 #include "lldb/Core/ValueObjectList.h"
19 #include "lldb/Core/Value.h"
20 #include "lldb/Core/ValueObject.h"
21 
22 #include "lldb/Symbol/ObjectFile.h"
23 #include "lldb/Symbol/SymbolContext.h"
24 #include "lldb/Symbol/Type.h"
25 #include "lldb/Symbol/Variable.h"
26 
27 #include "lldb/Target/ExecutionContext.h"
28 #include "lldb/Target/LanguageRuntime.h"
29 #include "lldb/Target/Process.h"
30 #include "lldb/Target/RegisterContext.h"
31 #include "lldb/Target/Target.h"
32 #include "lldb/Target/Thread.h"
33 
34 
35 using namespace lldb_private;
36 
37 ValueObjectDynamicValue::ValueObjectDynamicValue (ValueObject &parent) :
38     ValueObject(parent),
39     m_address (),
40     m_type_sp()
41 {
42     SetName (parent.GetName().AsCString());
43 }
44 
45 ValueObjectDynamicValue::~ValueObjectDynamicValue()
46 {
47     m_owning_valobj_sp.reset();
48 }
49 
50 lldb::clang_type_t
51 ValueObjectDynamicValue::GetClangType ()
52 {
53     if (m_type_sp)
54         return m_value.GetClangType();
55     else
56         return m_parent->GetClangType();
57 }
58 
59 ConstString
60 ValueObjectDynamicValue::GetTypeName()
61 {
62     // FIXME: Maybe cache the name, but have to clear it out if the type changes...
63     if (!UpdateValueIfNeeded())
64         return ConstString("<unknown type>");
65 
66     if (m_type_sp)
67         return ClangASTType::GetClangTypeName (GetClangType());
68     else
69         return m_parent->GetTypeName();
70 }
71 
72 uint32_t
73 ValueObjectDynamicValue::CalculateNumChildren()
74 {
75     if (!UpdateValueIfNeeded())
76         return 0;
77 
78     if (m_type_sp)
79         return ClangASTContext::GetNumChildren (GetClangAST (), GetClangType(), true);
80     else
81         return m_parent->GetNumChildren();
82 }
83 
84 clang::ASTContext *
85 ValueObjectDynamicValue::GetClangAST ()
86 {
87     if (!UpdateValueIfNeeded())
88         return NULL;
89 
90     if (m_type_sp)
91         return m_type_sp->GetClangAST();
92     else
93         return m_parent->GetClangAST ();
94 }
95 
96 size_t
97 ValueObjectDynamicValue::GetByteSize()
98 {
99     if (!UpdateValueIfNeeded())
100         return 0;
101 
102     if (m_type_sp)
103         return m_value.GetValueByteSize(GetClangAST(), NULL);
104     else
105         return m_parent->GetByteSize();
106 }
107 
108 lldb::ValueType
109 ValueObjectDynamicValue::GetValueType() const
110 {
111     return m_parent->GetValueType();
112 }
113 
114 bool
115 ValueObjectDynamicValue::UpdateValue ()
116 {
117     SetValueIsValid (false);
118     m_error.Clear();
119 
120     if (!m_parent->UpdateValueIfNeeded())
121     {
122         return false;
123     }
124 
125     ExecutionContext exe_ctx (GetExecutionContextScope());
126 
127     if (exe_ctx.target)
128     {
129         m_data.SetByteOrder(exe_ctx.target->GetArchitecture().GetByteOrder());
130         m_data.SetAddressByteSize(exe_ctx.target->GetArchitecture().GetAddressByteSize());
131     }
132 
133     // First make sure our Type and/or Address haven't changed:
134     Process *process = m_update_point.GetProcess();
135     if (!process)
136         return false;
137 
138     lldb::TypeSP dynamic_type_sp;
139     Address dynamic_address;
140     bool found_dynamic_type = false;
141 
142     lldb::LanguageType known_type = m_parent->GetObjectRuntimeLanguage();
143     if (known_type != lldb::eLanguageTypeUnknown && known_type != lldb::eLanguageTypeC)
144     {
145         LanguageRuntime *runtime = process->GetLanguageRuntime (known_type);
146         if (runtime)
147             found_dynamic_type = runtime->GetDynamicValue(*m_parent, dynamic_type_sp, dynamic_address);
148     }
149     else
150     {
151         LanguageRuntime *cpp_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeC_plus_plus);
152         if (cpp_runtime)
153             found_dynamic_type = cpp_runtime->GetDynamicValue(*m_parent, dynamic_type_sp, dynamic_address);
154 
155         if (!found_dynamic_type)
156         {
157             LanguageRuntime *objc_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeObjC);
158             if (objc_runtime)
159                 found_dynamic_type = cpp_runtime->GetDynamicValue(*m_parent, dynamic_type_sp, dynamic_address);
160         }
161     }
162 
163     // If we don't have a dynamic type, then make ourselves just a echo of our parent.
164     // Or we could return false, and make ourselves an echo of our parent?
165     if (!found_dynamic_type)
166     {
167         if (m_type_sp)
168             SetValueDidChange(true);
169         m_value = m_parent->GetValue();
170         m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST(), m_data, 0);
171         return m_error.Success();
172     }
173 
174     Value old_value(m_value);
175 
176     if (!m_type_sp)
177     {
178         m_type_sp = dynamic_type_sp;
179     }
180     else if (dynamic_type_sp != m_type_sp)
181     {
182         // We are another type, we need to tear down our children...
183         m_type_sp = dynamic_type_sp;
184         SetValueDidChange (true);
185     }
186 
187     if (!m_address.IsValid() || m_address != dynamic_address)
188     {
189         if (m_address.IsValid())
190             SetValueDidChange (true);
191 
192         // We've moved, so we should be fine...
193         m_address = dynamic_address;
194         lldb::addr_t load_address = m_address.GetLoadAddress(m_update_point.GetTarget());
195         m_value.GetScalar() = load_address;
196     }
197 
198     // The type will always be the type of the dynamic object.  If our parent's type was a pointer,
199     // then our type should be a pointer to the type of the dynamic object.  If a reference, then the original type
200     // should be okay...
201     lldb::clang_type_t orig_type = m_type_sp->GetClangForwardType();
202     lldb::clang_type_t corrected_type = orig_type;
203     if (m_parent->IsPointerType())
204         corrected_type = ClangASTContext::CreatePointerType (m_type_sp->GetClangAST(), orig_type);
205     else if (m_parent->IsPointerOrReferenceType())
206         corrected_type = ClangASTContext::CreateLValueReferenceType (m_type_sp->GetClangAST(), orig_type);
207 
208     m_value.SetContext (Value::eContextTypeClangType, corrected_type);
209 
210     // Our address is the location of the dynamic type stored in memory.  It isn't a load address,
211     // because we aren't pointing to the LOCATION that stores the pointer to us, we're pointing to us...
212     m_value.SetValueType(Value::eValueTypeScalar);
213 
214     if (m_address.IsValid() && m_type_sp)
215     {
216         // The variable value is in the Scalar value inside the m_value.
217         // We can point our m_data right to it.
218         m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST(), m_data, 0);
219         if (m_error.Success())
220         {
221             if (ClangASTContext::IsAggregateType (GetClangType()))
222             {
223                 // this value object represents an aggregate type whose
224                 // children have values, but this object does not. So we
225                 // say we are changed if our location has changed.
226                 SetValueDidChange (m_value.GetValueType() != old_value.GetValueType() || m_value.GetScalar() != old_value.GetScalar());
227             }
228 
229             SetValueIsValid (true);
230             return true;
231         }
232     }
233 
234     // We get here if we've failed above...
235     SetValueIsValid (false);
236     return false;
237 }
238 
239 
240 
241 bool
242 ValueObjectDynamicValue::IsInScope ()
243 {
244     return m_parent->IsInScope();
245 }
246 
247