blob: b210d49821b5348c9750c7770a475eadab8fcd28 [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- ClangExpressionDeclMap.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/Expression/ClangExpressionDeclMap.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
Sean Callanan47a5c4c2010-09-23 03:01:22 +000016#include "clang/AST/DeclarationName.h"
Sean Callanana0744822010-11-01 23:22:47 +000017#include "clang/AST/Decl.h"
Chris Lattner24943d22010-06-08 16:52:24 +000018#include "lldb/lldb-private.h"
19#include "lldb/Core/Address.h"
Sean Callanan810f22d2010-07-16 00:09:46 +000020#include "lldb/Core/Error.h"
Sean Callanan6184dfe2010-06-23 00:47:48 +000021#include "lldb/Core/Log.h"
Chris Lattner24943d22010-06-08 16:52:24 +000022#include "lldb/Core/Module.h"
23#include "lldb/Expression/ClangASTSource.h"
Sean Callanana48fe162010-08-11 03:57:18 +000024#include "lldb/Expression/ClangPersistentVariables.h"
Chris Lattner24943d22010-06-08 16:52:24 +000025#include "lldb/Symbol/ClangASTContext.h"
Greg Clayton6916e352010-11-13 03:52:47 +000026#include "lldb/Symbol/ClangNamespaceDecl.h"
Chris Lattner24943d22010-06-08 16:52:24 +000027#include "lldb/Symbol/CompileUnit.h"
28#include "lldb/Symbol/Function.h"
29#include "lldb/Symbol/ObjectFile.h"
30#include "lldb/Symbol/SymbolContext.h"
31#include "lldb/Symbol/Type.h"
32#include "lldb/Symbol/TypeList.h"
33#include "lldb/Symbol/Variable.h"
34#include "lldb/Symbol/VariableList.h"
Sean Callananf328c9f2010-07-20 23:31:16 +000035#include "lldb/Target/ExecutionContext.h"
Sean Callanan810f22d2010-07-16 00:09:46 +000036#include "lldb/Target/Process.h"
Sean Callanan17c6a052010-10-05 20:18:48 +000037#include "lldb/Target/RegisterContext.h"
Chris Lattner24943d22010-06-08 16:52:24 +000038#include "lldb/Target/StackFrame.h"
Sean Callananf328c9f2010-07-20 23:31:16 +000039#include "lldb/Target/Target.h"
Jim Ingham78b9ee82010-12-07 01:56:02 +000040#include "lldb/Target/Thread.h"
Sean Callanana0744822010-11-01 23:22:47 +000041#include "llvm/Support/raw_ostream.h"
Chris Lattner24943d22010-06-08 16:52:24 +000042
Greg Clayton3bc52d02010-11-14 22:13:40 +000043using namespace lldb;
Chris Lattner24943d22010-06-08 16:52:24 +000044using namespace lldb_private;
45using namespace clang;
46
Sean Callananaa301c42010-12-03 01:38:59 +000047ClangExpressionDeclMap::ClangExpressionDeclMap () :
Greg Clayton8de27c72010-10-15 22:48:33 +000048 m_found_entities (),
49 m_struct_members (),
Sean Callananaa301c42010-12-03 01:38:59 +000050 m_parser_vars (),
51 m_struct_vars ()
Chris Lattner24943d22010-06-08 16:52:24 +000052{
Sean Callananaa301c42010-12-03 01:38:59 +000053 EnableStructVars();
Chris Lattner24943d22010-06-08 16:52:24 +000054}
55
56ClangExpressionDeclMap::~ClangExpressionDeclMap()
Sean Callananaa301c42010-12-03 01:38:59 +000057{
58 DidDematerialize();
59 DisableStructVars();
60}
Sean Callananc2c6f772010-10-26 00:31:56 +000061
Sean Callananaa301c42010-12-03 01:38:59 +000062void ClangExpressionDeclMap::WillParse(ExecutionContext &exe_ctx)
63{
64 EnableParserVars();
65 m_parser_vars->m_exe_ctx = &exe_ctx;
66
67 if (exe_ctx.frame)
68 m_parser_vars->m_sym_ctx = exe_ctx.frame->GetSymbolContext(lldb::eSymbolContextEverything);
Jim Ingham78b9ee82010-12-07 01:56:02 +000069 else if (exe_ctx.thread)
70 m_parser_vars->m_sym_ctx = exe_ctx.thread->GetStackFrameAtIndex(0)->GetSymbolContext(lldb::eSymbolContextEverything);
71
Sean Callananaa301c42010-12-03 01:38:59 +000072 if (exe_ctx.process)
73 m_parser_vars->m_persistent_vars = &exe_ctx.process->GetPersistentVariables();
74}
75
76void ClangExpressionDeclMap::DidParse()
77{
78 if (m_parser_vars.get())
79 {
80 for (uint64_t entity_index = 0, num_entities = m_found_entities.Size();
81 entity_index < num_entities;
82 ++entity_index)
83 {
84 ClangExpressionVariable &entity(m_found_entities.VariableAtIndex(entity_index));
85 if (entity.m_parser_vars.get() &&
86 entity.m_parser_vars->m_lldb_value)
87 delete entity.m_parser_vars->m_lldb_value;
88
89 entity.DisableParserVars();
90 }
91
92 for (uint64_t pvar_index = 0, num_pvars = m_parser_vars->m_persistent_vars->Size();
93 pvar_index < num_pvars;
94 ++pvar_index)
95 {
96 ClangExpressionVariable &pvar(m_parser_vars->m_persistent_vars->VariableAtIndex(pvar_index));
97 pvar.DisableParserVars();
98 }
99
100 DisableParserVars();
Sean Callanan7a60b942010-10-08 01:58:41 +0000101 }
Chris Lattner24943d22010-06-08 16:52:24 +0000102}
103
Sean Callanan8bce6652010-07-13 21:41:46 +0000104// Interface for IRForTarget
105
Greg Clayton8de27c72010-10-15 22:48:33 +0000106const ConstString &
107ClangExpressionDeclMap::GetPersistentResultName ()
Sean Callanan82b74c82010-08-12 01:56:52 +0000108{
Sean Callananaa301c42010-12-03 01:38:59 +0000109 assert (m_struct_vars.get());
110 assert (m_parser_vars.get());
111
112 if (!m_struct_vars->m_result_name)
113 m_parser_vars->m_persistent_vars->GetNextResultName(m_struct_vars->m_result_name);
114
115 return m_struct_vars->m_result_name;
Sean Callanan82b74c82010-08-12 01:56:52 +0000116}
117
Sean Callanan8bce6652010-07-13 21:41:46 +0000118bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000119ClangExpressionDeclMap::AddPersistentVariable
120(
121 const clang::NamedDecl *decl,
122 const ConstString &name,
123 TypeFromParser parser_type
124)
Sean Callanana48fe162010-08-11 03:57:18 +0000125{
Sean Callananaa301c42010-12-03 01:38:59 +0000126 assert (m_parser_vars.get());
127
128 clang::ASTContext *context(m_parser_vars->m_exe_ctx->target->GetScratchClangASTContext()->getASTContext());
Sean Callanana48fe162010-08-11 03:57:18 +0000129
Sean Callanana48fe162010-08-11 03:57:18 +0000130 TypeFromUser user_type(ClangASTContext::CopyType(context,
Sean Callanan82b74c82010-08-12 01:56:52 +0000131 parser_type.GetASTContext(),
132 parser_type.GetOpaqueQualType()),
Sean Callanana48fe162010-08-11 03:57:18 +0000133 context);
134
Sean Callananaa301c42010-12-03 01:38:59 +0000135 if (!m_parser_vars->m_persistent_vars->CreatePersistentVariable (name, user_type))
Sean Callanan8c127202010-08-23 23:09:38 +0000136 return false;
137
Sean Callananaa301c42010-12-03 01:38:59 +0000138 ClangExpressionVariable *var = m_parser_vars->m_persistent_vars->GetVariable(name);
Sean Callanan8c127202010-08-23 23:09:38 +0000139
140 if (!var)
141 return false;
142
143 var->EnableParserVars();
144
145 var->m_parser_vars->m_named_decl = decl;
146 var->m_parser_vars->m_parser_type = parser_type;
147
148 return true;
Sean Callanana48fe162010-08-11 03:57:18 +0000149}
150
151bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000152ClangExpressionDeclMap::AddValueToStruct
153(
154 const clang::NamedDecl *decl,
155 const ConstString &name,
156 llvm::Value *value,
157 size_t size,
158 off_t alignment
159)
Sean Callanan8bce6652010-07-13 21:41:46 +0000160{
Sean Callananaa301c42010-12-03 01:38:59 +0000161 assert (m_struct_vars.get());
162 assert (m_parser_vars.get());
163
Greg Claytone005f2c2010-11-06 01:53:30 +0000164 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan45690fe2010-08-30 22:17:16 +0000165
Sean Callananaa301c42010-12-03 01:38:59 +0000166 m_struct_vars->m_struct_laid_out = false;
Sean Callanan8bce6652010-07-13 21:41:46 +0000167
Sean Callanan8c127202010-08-23 23:09:38 +0000168 if (m_struct_members.GetVariable(decl))
169 return true;
Sean Callanan8bce6652010-07-13 21:41:46 +0000170
Sean Callanan8c127202010-08-23 23:09:38 +0000171 ClangExpressionVariable *var = m_found_entities.GetVariable(decl);
Sean Callanan8bce6652010-07-13 21:41:46 +0000172
Sean Callanan8c127202010-08-23 23:09:38 +0000173 if (!var)
Sean Callananaa301c42010-12-03 01:38:59 +0000174 var = m_parser_vars->m_persistent_vars->GetVariable(decl);
Sean Callanan8bce6652010-07-13 21:41:46 +0000175
Sean Callanan8c127202010-08-23 23:09:38 +0000176 if (!var)
177 return false;
178
Sean Callanan45690fe2010-08-30 22:17:16 +0000179 if (log)
180 log->Printf("Adding value for decl %p [%s - %s] to the structure",
181 decl,
Greg Clayton8de27c72010-10-15 22:48:33 +0000182 name.GetCString(),
183 var->m_name.GetCString());
Sean Callanan45690fe2010-08-30 22:17:16 +0000184
Sean Callanan8c127202010-08-23 23:09:38 +0000185 // We know entity->m_parser_vars is valid because we used a parser variable
186 // to find it
187 var->m_parser_vars->m_llvm_value = value;
188
189 var->EnableJITVars();
190 var->m_jit_vars->m_alignment = alignment;
191 var->m_jit_vars->m_size = size;
192
193 m_struct_members.AddVariable(*var);
Sean Callanan8bce6652010-07-13 21:41:46 +0000194
195 return true;
196}
197
198bool
199ClangExpressionDeclMap::DoStructLayout ()
200{
Sean Callananaa301c42010-12-03 01:38:59 +0000201 assert (m_struct_vars.get());
202
203 if (m_struct_vars->m_struct_laid_out)
Sean Callanan8bce6652010-07-13 21:41:46 +0000204 return true;
205
Sean Callanan8bce6652010-07-13 21:41:46 +0000206 off_t cursor = 0;
207
Sean Callananaa301c42010-12-03 01:38:59 +0000208 m_struct_vars->m_struct_alignment = 0;
209 m_struct_vars->m_struct_size = 0;
Sean Callanan8bce6652010-07-13 21:41:46 +0000210
Sean Callanan8c127202010-08-23 23:09:38 +0000211 for (uint64_t member_index = 0, num_members = m_struct_members.Size();
212 member_index < num_members;
213 ++member_index)
Sean Callanan8bce6652010-07-13 21:41:46 +0000214 {
Sean Callanan8c127202010-08-23 23:09:38 +0000215 ClangExpressionVariable &member(m_struct_members.VariableAtIndex(member_index));
Sean Callanan8bce6652010-07-13 21:41:46 +0000216
Sean Callanan8c127202010-08-23 23:09:38 +0000217 if (!member.m_jit_vars.get())
218 return false;
Sean Callanan8bce6652010-07-13 21:41:46 +0000219
Sean Callanan8c127202010-08-23 23:09:38 +0000220 if (member_index == 0)
Sean Callananaa301c42010-12-03 01:38:59 +0000221 m_struct_vars->m_struct_alignment = member.m_jit_vars->m_alignment;
Sean Callanan8c127202010-08-23 23:09:38 +0000222
223 if (cursor % member.m_jit_vars->m_alignment)
224 cursor += (member.m_jit_vars->m_alignment - (cursor % member.m_jit_vars->m_alignment));
225
226 member.m_jit_vars->m_offset = cursor;
227 cursor += member.m_jit_vars->m_size;
Sean Callanan8bce6652010-07-13 21:41:46 +0000228 }
229
Sean Callananaa301c42010-12-03 01:38:59 +0000230 m_struct_vars->m_struct_size = cursor;
Sean Callanan8bce6652010-07-13 21:41:46 +0000231
Sean Callananaa301c42010-12-03 01:38:59 +0000232 m_struct_vars->m_struct_laid_out = true;
Sean Callanan8bce6652010-07-13 21:41:46 +0000233 return true;
234}
235
Greg Clayton8de27c72010-10-15 22:48:33 +0000236bool ClangExpressionDeclMap::GetStructInfo
237(
238 uint32_t &num_elements,
239 size_t &size,
240 off_t &alignment
241)
Sean Callanan8bce6652010-07-13 21:41:46 +0000242{
Sean Callananaa301c42010-12-03 01:38:59 +0000243 assert (m_struct_vars.get());
244
245 if (!m_struct_vars->m_struct_laid_out)
Sean Callanan8bce6652010-07-13 21:41:46 +0000246 return false;
247
Sean Callanan8c127202010-08-23 23:09:38 +0000248 num_elements = m_struct_members.Size();
Sean Callananaa301c42010-12-03 01:38:59 +0000249 size = m_struct_vars->m_struct_size;
250 alignment = m_struct_vars->m_struct_alignment;
Sean Callanan8bce6652010-07-13 21:41:46 +0000251
252 return true;
253}
254
255bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000256ClangExpressionDeclMap::GetStructElement
257(
258 const clang::NamedDecl *&decl,
259 llvm::Value *&value,
260 off_t &offset,
261 ConstString &name,
262 uint32_t index
263)
Sean Callanan8bce6652010-07-13 21:41:46 +0000264{
Sean Callananaa301c42010-12-03 01:38:59 +0000265 assert (m_struct_vars.get());
266
267 if (!m_struct_vars->m_struct_laid_out)
Sean Callanan8bce6652010-07-13 21:41:46 +0000268 return false;
269
Sean Callanan8c127202010-08-23 23:09:38 +0000270 if (index >= m_struct_members.Size())
Sean Callanan8bce6652010-07-13 21:41:46 +0000271 return false;
272
Sean Callanan8c127202010-08-23 23:09:38 +0000273 ClangExpressionVariable &member(m_struct_members.VariableAtIndex(index));
Sean Callanan8bce6652010-07-13 21:41:46 +0000274
Sean Callanan8c127202010-08-23 23:09:38 +0000275 if (!member.m_parser_vars.get() ||
276 !member.m_jit_vars.get())
277 return false;
278
279 decl = member.m_parser_vars->m_named_decl;
280 value = member.m_parser_vars->m_llvm_value;
281 offset = member.m_jit_vars->m_offset;
Greg Clayton8de27c72010-10-15 22:48:33 +0000282 name = member.m_name;
Sean Callanan8c127202010-08-23 23:09:38 +0000283
Sean Callanan8bce6652010-07-13 21:41:46 +0000284 return true;
285}
286
Sean Callanan02fbafa2010-07-27 21:39:39 +0000287bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000288ClangExpressionDeclMap::GetFunctionInfo
289(
290 const clang::NamedDecl *decl,
291 llvm::Value**& value,
292 uint64_t &ptr
293)
Sean Callananba992c52010-07-27 02:07:53 +0000294{
Sean Callanan8c127202010-08-23 23:09:38 +0000295 ClangExpressionVariable *entity = m_found_entities.GetVariable(decl);
296
297 if (!entity)
298 return false;
Sean Callananba992c52010-07-27 02:07:53 +0000299
Sean Callanan8c127202010-08-23 23:09:38 +0000300 // We know m_parser_vars is valid since we searched for the variable by
301 // its NamedDecl
Sean Callananba992c52010-07-27 02:07:53 +0000302
Sean Callanan8c127202010-08-23 23:09:38 +0000303 value = &entity->m_parser_vars->m_llvm_value;
304 ptr = entity->m_parser_vars->m_lldb_value->GetScalar().ULongLong();
305
306 return true;
Sean Callananba992c52010-07-27 02:07:53 +0000307}
308
Sean Callananf5857a02010-07-31 01:32:05 +0000309bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000310ClangExpressionDeclMap::GetFunctionAddress
311(
312 const ConstString &name,
313 uint64_t &ptr
314)
Sean Callananf5857a02010-07-31 01:32:05 +0000315{
Sean Callananaa301c42010-12-03 01:38:59 +0000316 assert (m_parser_vars.get());
317
Sean Callananf5857a02010-07-31 01:32:05 +0000318 // Back out in all cases where we're not fully initialized
Jim Ingham78b9ee82010-12-07 01:56:02 +0000319 if (m_parser_vars->m_exe_ctx->target == NULL)
320 return false;
321 if (!m_parser_vars->m_sym_ctx.target_sp)
Sean Callananf5857a02010-07-31 01:32:05 +0000322 return false;
323
Greg Claytone5748d82010-11-09 23:46:37 +0000324 SymbolContextList sc_list;
Sean Callananf5857a02010-07-31 01:32:05 +0000325
Sean Callananaa301c42010-12-03 01:38:59 +0000326 m_parser_vars->m_sym_ctx.FindFunctionsByName(name, false, sc_list);
Sean Callananf5857a02010-07-31 01:32:05 +0000327
Greg Claytone5748d82010-11-09 23:46:37 +0000328 if (!sc_list.GetSize())
Sean Callananf5857a02010-07-31 01:32:05 +0000329 return false;
330
331 SymbolContext sym_ctx;
Greg Claytone5748d82010-11-09 23:46:37 +0000332 sc_list.GetContextAtIndex(0, sym_ctx);
Sean Callananf5857a02010-07-31 01:32:05 +0000333
334 const Address *fun_address;
335
336 if (sym_ctx.function)
337 fun_address = &sym_ctx.function->GetAddressRange().GetBaseAddress();
338 else if (sym_ctx.symbol)
339 fun_address = &sym_ctx.symbol->GetAddressRangeRef().GetBaseAddress();
340 else
341 return false;
342
Sean Callananaa301c42010-12-03 01:38:59 +0000343 ptr = fun_address->GetLoadAddress (m_parser_vars->m_exe_ctx->target);
Sean Callananf5857a02010-07-31 01:32:05 +0000344
345 return true;
346}
347
Sean Callanan810f22d2010-07-16 00:09:46 +0000348// Interface for CommandObjectExpression
Sean Callananf328c9f2010-07-20 23:31:16 +0000349
350bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000351ClangExpressionDeclMap::Materialize
352(
Sean Callananaa301c42010-12-03 01:38:59 +0000353 ExecutionContext &exe_ctx,
Greg Clayton8de27c72010-10-15 22:48:33 +0000354 lldb::addr_t &struct_address,
355 Error &err
356)
Sean Callananf328c9f2010-07-20 23:31:16 +0000357{
Sean Callananaa301c42010-12-03 01:38:59 +0000358 EnableMaterialVars();
359
360 m_material_vars->m_process = exe_ctx.process;
361
Sean Callananf328c9f2010-07-20 23:31:16 +0000362 bool result = DoMaterialize(false, exe_ctx, NULL, err);
363
364 if (result)
Sean Callananaa301c42010-12-03 01:38:59 +0000365 struct_address = m_material_vars->m_materialized_location;
Sean Callananf328c9f2010-07-20 23:31:16 +0000366
367 return result;
368}
369
370bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000371ClangExpressionDeclMap::GetObjectPointer
372(
373 lldb::addr_t &object_ptr,
Sean Callanan3aa7da52010-12-13 22:46:15 +0000374 ConstString &object_name,
Sean Callananaa301c42010-12-03 01:38:59 +0000375 ExecutionContext &exe_ctx,
Sean Callanan047923c2010-12-14 00:42:36 +0000376 Error &err,
377 bool suppress_type_check
Greg Clayton8de27c72010-10-15 22:48:33 +0000378)
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000379{
Sean Callananaa301c42010-12-03 01:38:59 +0000380 assert (m_struct_vars.get());
381
382 if (!exe_ctx.frame || !exe_ctx.target || !exe_ctx.process)
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000383 {
384 err.SetErrorString("Couldn't load 'this' because the context is incomplete");
385 return false;
386 }
387
Sean Callananaa301c42010-12-03 01:38:59 +0000388 if (!m_struct_vars->m_object_pointer_type.GetOpaqueQualType())
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000389 {
390 err.SetErrorString("Couldn't load 'this' because its type is unknown");
391 return false;
392 }
393
Sean Callanan047923c2010-12-14 00:42:36 +0000394 Variable *object_ptr_var = FindVariableInScope (*exe_ctx.frame,
395 object_name,
396 (suppress_type_check ? NULL : &m_struct_vars->m_object_pointer_type));
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000397
398 if (!object_ptr_var)
399 {
Sean Callanan3aa7da52010-12-13 22:46:15 +0000400 err.SetErrorStringWithFormat("Couldn't find '%s' with appropriate type in scope", object_name.GetCString());
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000401 return false;
402 }
403
Sean Callananaa301c42010-12-03 01:38:59 +0000404 std::auto_ptr<lldb_private::Value> location_value(GetVariableValue(exe_ctx,
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000405 object_ptr_var,
Sean Callananaa301c42010-12-03 01:38:59 +0000406 NULL));
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000407
408 if (!location_value.get())
409 {
Sean Callanan3aa7da52010-12-13 22:46:15 +0000410 err.SetErrorStringWithFormat("Couldn't get the location for '%s'", object_name.GetCString());
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000411 return false;
412 }
413
414 if (location_value->GetValueType() == Value::eValueTypeLoadAddress)
415 {
416 lldb::addr_t value_addr = location_value->GetScalar().ULongLong();
Sean Callananaa301c42010-12-03 01:38:59 +0000417 uint32_t address_byte_size = exe_ctx.target->GetArchitecture().GetAddressByteSize();
418 lldb::ByteOrder address_byte_order = exe_ctx.process->GetByteOrder();
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000419
Sean Callananaa301c42010-12-03 01:38:59 +0000420 if (ClangASTType::GetClangTypeBitWidth(m_struct_vars->m_object_pointer_type.GetASTContext(),
421 m_struct_vars->m_object_pointer_type.GetOpaqueQualType()) != address_byte_size * 8)
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000422 {
Sean Callanan3aa7da52010-12-13 22:46:15 +0000423 err.SetErrorStringWithFormat("'%s' is not of an expected pointer size", object_name.GetCString());
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000424 return false;
425 }
426
427 DataBufferHeap data;
428 data.SetByteSize(address_byte_size);
429 Error read_error;
430
Sean Callananaa301c42010-12-03 01:38:59 +0000431 if (exe_ctx.process->ReadMemory (value_addr, data.GetBytes(), address_byte_size, read_error) != address_byte_size)
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000432 {
Sean Callanan3aa7da52010-12-13 22:46:15 +0000433 err.SetErrorStringWithFormat("Coldn't read '%s' from the target: %s", object_name.GetCString(), read_error.AsCString());
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000434 return false;
435 }
436
437 DataExtractor extractor(data.GetBytes(), data.GetByteSize(), address_byte_order, address_byte_size);
438
439 uint32_t offset = 0;
440
441 object_ptr = extractor.GetPointer(&offset);
442
443 return true;
444 }
445 else
446 {
Sean Callanan3aa7da52010-12-13 22:46:15 +0000447 err.SetErrorStringWithFormat("'%s' is not in memory; LLDB must be extended to handle registers", object_name.GetCString());
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000448 return false;
449 }
450}
451
452bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000453ClangExpressionDeclMap::Dematerialize
454(
Sean Callananaa301c42010-12-03 01:38:59 +0000455 ExecutionContext &exe_ctx,
Greg Clayton8de27c72010-10-15 22:48:33 +0000456 ClangExpressionVariable *&result,
457 Error &err
458)
Sean Callananf328c9f2010-07-20 23:31:16 +0000459{
Sean Callanan82b74c82010-08-12 01:56:52 +0000460 return DoMaterialize(true, exe_ctx, &result, err);
Sean Callananaa301c42010-12-03 01:38:59 +0000461
462 DidDematerialize();
463}
464
465void
466ClangExpressionDeclMap::DidDematerialize()
467{
468 if (m_material_vars.get())
469 {
470 if (m_material_vars->m_materialized_location)
471 {
472 //#define SINGLE_STEP_EXPRESSIONS
473
474#ifndef SINGLE_STEP_EXPRESSIONS
475 m_material_vars->m_process->DeallocateMemory(m_material_vars->m_materialized_location);
476#endif
477 m_material_vars->m_materialized_location = 0;
478 }
479
480 DisableMaterialVars();
481 }
Sean Callananf328c9f2010-07-20 23:31:16 +0000482}
483
Sean Callanan32824aa2010-07-23 22:19:18 +0000484bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000485ClangExpressionDeclMap::DumpMaterializedStruct
486(
Sean Callananaa301c42010-12-03 01:38:59 +0000487 ExecutionContext &exe_ctx,
Greg Clayton8de27c72010-10-15 22:48:33 +0000488 Stream &s,
489 Error &err
490)
Sean Callanan32824aa2010-07-23 22:19:18 +0000491{
Sean Callananaa301c42010-12-03 01:38:59 +0000492 assert (m_struct_vars.get());
493 assert (m_material_vars.get());
494
495 if (!m_struct_vars->m_struct_laid_out)
Sean Callanan32824aa2010-07-23 22:19:18 +0000496 {
497 err.SetErrorString("Structure hasn't been laid out yet");
498 return false;
499 }
500
Sean Callananaa301c42010-12-03 01:38:59 +0000501 if (!exe_ctx.process)
Sean Callanan32824aa2010-07-23 22:19:18 +0000502 {
503 err.SetErrorString("Couldn't find the process");
504 return false;
505 }
506
Sean Callananaa301c42010-12-03 01:38:59 +0000507 if (!exe_ctx.target)
Sean Callanan32824aa2010-07-23 22:19:18 +0000508 {
509 err.SetErrorString("Couldn't find the target");
510 return false;
511 }
512
Sean Callanan33711022010-12-07 10:00:20 +0000513 if (!m_material_vars->m_materialized_location)
514 {
515 err.SetErrorString("No materialized location");
516 return false;
517 }
518
Sean Callananaa301c42010-12-03 01:38:59 +0000519 lldb::DataBufferSP data(new DataBufferHeap(m_struct_vars->m_struct_size, 0));
Sean Callanan32824aa2010-07-23 22:19:18 +0000520
521 Error error;
Sean Callananaa301c42010-12-03 01:38:59 +0000522 if (exe_ctx.process->ReadMemory (m_material_vars->m_materialized_location, data->GetBytes(), data->GetByteSize(), error) != data->GetByteSize())
Sean Callanan32824aa2010-07-23 22:19:18 +0000523 {
524 err.SetErrorStringWithFormat ("Couldn't read struct from the target: %s", error.AsCString());
525 return false;
526 }
527
Sean Callananaa301c42010-12-03 01:38:59 +0000528 DataExtractor extractor(data, exe_ctx.process->GetByteOrder(), exe_ctx.target->GetArchitecture().GetAddressByteSize());
Sean Callanan32824aa2010-07-23 22:19:18 +0000529
Sean Callanan8c127202010-08-23 23:09:38 +0000530 for (uint64_t member_index = 0, num_members = m_struct_members.Size();
531 member_index < num_members;
532 ++member_index)
Sean Callanan32824aa2010-07-23 22:19:18 +0000533 {
Sean Callanan8c127202010-08-23 23:09:38 +0000534 ClangExpressionVariable &member (m_struct_members.VariableAtIndex(member_index));
Sean Callanan32824aa2010-07-23 22:19:18 +0000535
Greg Clayton8de27c72010-10-15 22:48:33 +0000536 s.Printf("[%s]\n", member.m_name.GetCString());
Sean Callanan8c127202010-08-23 23:09:38 +0000537
538 if (!member.m_jit_vars.get())
539 return false;
540
Sean Callananaa301c42010-12-03 01:38:59 +0000541 extractor.Dump(&s, // stream
542 member.m_jit_vars->m_offset, // offset
543 lldb::eFormatBytesWithASCII, // format
544 1, // byte size of individual entries
545 member.m_jit_vars->m_size, // number of entries
546 16, // entries per line
547 m_material_vars->m_materialized_location + member.m_jit_vars->m_offset, // address to print
548 0, // bit size (bitfields only; 0 means ignore)
549 0); // bit alignment (bitfields only; 0 means ignore)
Sean Callanan32824aa2010-07-23 22:19:18 +0000550
551 s.PutChar('\n');
552 }
553
554 return true;
555}
556
Sean Callananf328c9f2010-07-20 23:31:16 +0000557bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000558ClangExpressionDeclMap::DoMaterialize
559(
560 bool dematerialize,
Sean Callananaa301c42010-12-03 01:38:59 +0000561 ExecutionContext &exe_ctx,
Greg Clayton8de27c72010-10-15 22:48:33 +0000562 ClangExpressionVariable **result,
563 Error &err
564)
Sean Callanan810f22d2010-07-16 00:09:46 +0000565{
Sean Callananaa301c42010-12-03 01:38:59 +0000566 assert (m_struct_vars.get());
567
Greg Claytone005f2c2010-11-06 01:53:30 +0000568 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan82b74c82010-08-12 01:56:52 +0000569
Sean Callananaa301c42010-12-03 01:38:59 +0000570 if (!m_struct_vars->m_struct_laid_out)
Sean Callanan810f22d2010-07-16 00:09:46 +0000571 {
572 err.SetErrorString("Structure hasn't been laid out yet");
573 return LLDB_INVALID_ADDRESS;
574 }
575
Sean Callananaa301c42010-12-03 01:38:59 +0000576 if (!exe_ctx.frame)
Sean Callanan45839272010-07-24 01:37:44 +0000577 {
578 err.SetErrorString("Received null execution frame");
579 return LLDB_INVALID_ADDRESS;
580 }
581
Sean Callananaa301c42010-12-03 01:38:59 +0000582 ClangPersistentVariables &persistent_vars = exe_ctx.process->GetPersistentVariables();
583
584 if (!m_struct_vars->m_struct_size)
Sean Callanane8a59a82010-09-13 21:34:21 +0000585 {
586 if (log)
587 log->PutCString("Not bothering to allocate a struct because no arguments are needed");
588
Sean Callananaa301c42010-12-03 01:38:59 +0000589 m_material_vars->m_allocated_area = NULL;
Sean Callanane8a59a82010-09-13 21:34:21 +0000590
591 return true;
592 }
593
Sean Callananaa301c42010-12-03 01:38:59 +0000594 const SymbolContext &sym_ctx(exe_ctx.frame->GetSymbolContext(lldb::eSymbolContextEverything));
Sean Callanan810f22d2010-07-16 00:09:46 +0000595
Sean Callananf328c9f2010-07-20 23:31:16 +0000596 if (!dematerialize)
Sean Callanan810f22d2010-07-16 00:09:46 +0000597 {
Sean Callananaa301c42010-12-03 01:38:59 +0000598 if (m_material_vars->m_materialized_location)
Sean Callananf328c9f2010-07-20 23:31:16 +0000599 {
Sean Callananaa301c42010-12-03 01:38:59 +0000600 exe_ctx.process->DeallocateMemory(m_material_vars->m_materialized_location);
601 m_material_vars->m_materialized_location = 0;
Sean Callananf328c9f2010-07-20 23:31:16 +0000602 }
603
Sean Callanan7a60b942010-10-08 01:58:41 +0000604 if (log)
605 log->PutCString("Allocating memory for materialized argument struct");
606
Sean Callananaa301c42010-12-03 01:38:59 +0000607 lldb::addr_t mem = exe_ctx.process->AllocateMemory(m_struct_vars->m_struct_alignment + m_struct_vars->m_struct_size,
608 lldb::ePermissionsReadable | lldb::ePermissionsWritable,
609 err);
Sean Callananf328c9f2010-07-20 23:31:16 +0000610
611 if (mem == LLDB_INVALID_ADDRESS)
612 return false;
613
Sean Callananaa301c42010-12-03 01:38:59 +0000614 m_material_vars->m_allocated_area = mem;
Sean Callanan810f22d2010-07-16 00:09:46 +0000615 }
616
Sean Callananaa301c42010-12-03 01:38:59 +0000617 m_material_vars->m_materialized_location = m_material_vars->m_allocated_area;
Sean Callananf328c9f2010-07-20 23:31:16 +0000618
Sean Callananaa301c42010-12-03 01:38:59 +0000619 if (m_material_vars->m_materialized_location % m_struct_vars->m_struct_alignment)
620 m_material_vars->m_materialized_location += (m_struct_vars->m_struct_alignment - (m_material_vars->m_materialized_location % m_struct_vars->m_struct_alignment));
Sean Callananf328c9f2010-07-20 23:31:16 +0000621
Sean Callanan8c127202010-08-23 23:09:38 +0000622 for (uint64_t member_index = 0, num_members = m_struct_members.Size();
623 member_index < num_members;
624 ++member_index)
Sean Callanan810f22d2010-07-16 00:09:46 +0000625 {
Sean Callanan8c127202010-08-23 23:09:38 +0000626 ClangExpressionVariable &member (m_struct_members.VariableAtIndex(member_index));
Sean Callanan810f22d2010-07-16 00:09:46 +0000627
Sean Callanan4d0b1102010-12-01 01:29:06 +0000628 ClangExpressionVariable *entity = NULL;
Sean Callanan8c127202010-08-23 23:09:38 +0000629
Sean Callananaa301c42010-12-03 01:38:59 +0000630 /*
Sean Callanan4d0b1102010-12-01 01:29:06 +0000631 if (member.m_parser_vars.get())
632 entity = m_found_entities.GetVariable(member.m_parser_vars->m_named_decl);
Sean Callananaa301c42010-12-03 01:38:59 +0000633 */
Sean Callanan4d0b1102010-12-01 01:29:06 +0000634
Sean Callananaa301c42010-12-03 01:38:59 +0000635 entity = m_found_entities.GetVariable(member.m_name);
636
637 ClangExpressionVariable *persistent_variable = persistent_vars.GetVariable(member.m_name);
Sean Callanan8c127202010-08-23 23:09:38 +0000638
639 if (entity)
640 {
Sean Callanan1ddd9fe2010-11-30 00:27:43 +0000641 if (entity->m_register_info)
642 {
643 // This is a register variable
644
Sean Callananaa301c42010-12-03 01:38:59 +0000645 RegisterContext *reg_ctx = exe_ctx.GetRegisterContext();
Sean Callanan1ddd9fe2010-11-30 00:27:43 +0000646
647 if (!reg_ctx)
648 return false;
649
Sean Callananaa301c42010-12-03 01:38:59 +0000650 if (!DoMaterializeOneRegister(dematerialize, exe_ctx, *reg_ctx, *entity->m_register_info, m_material_vars->m_materialized_location + member.m_jit_vars->m_offset, err))
Sean Callanan1ddd9fe2010-11-30 00:27:43 +0000651 return false;
652 }
653 else
654 {
655 if (!member.m_jit_vars.get())
656 return false;
657
Sean Callananaa301c42010-12-03 01:38:59 +0000658 if (!DoMaterializeOneVariable(dematerialize, exe_ctx, sym_ctx, member.m_name, member.m_user_type, m_material_vars->m_materialized_location + member.m_jit_vars->m_offset, err))
Sean Callanan1ddd9fe2010-11-30 00:27:43 +0000659 return false;
660 }
Sean Callanan8c127202010-08-23 23:09:38 +0000661 }
662 else if (persistent_variable)
663 {
Sean Callananaa301c42010-12-03 01:38:59 +0000664 if (member.m_name == m_struct_vars->m_result_name)
Sean Callanan45690fe2010-08-30 22:17:16 +0000665 {
666 if (!dematerialize)
667 continue;
Sean Callanan8c127202010-08-23 23:09:38 +0000668
Sean Callanan8c127202010-08-23 23:09:38 +0000669 if (log)
670 log->PutCString("Found result member in the struct");
Sean Callanan45690fe2010-08-30 22:17:16 +0000671
Sean Callanan8c127202010-08-23 23:09:38 +0000672 *result = &member;
673 }
674
Sean Callanan45690fe2010-08-30 22:17:16 +0000675 if (log)
Greg Clayton8de27c72010-10-15 22:48:33 +0000676 log->Printf("Searched for persistent variable %s and found %s", member.m_name.GetCString(), persistent_variable->m_name.GetCString());
Sean Callanan45690fe2010-08-30 22:17:16 +0000677
Sean Callananaa301c42010-12-03 01:38:59 +0000678 if (!DoMaterializeOnePersistentVariable(dematerialize, exe_ctx, persistent_variable->m_name, m_material_vars->m_materialized_location + member.m_jit_vars->m_offset, err))
Sean Callanan8c127202010-08-23 23:09:38 +0000679 return false;
680 }
681 else
682 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000683 err.SetErrorStringWithFormat("Unexpected variable %s", member.m_name.GetCString());
Sean Callanan8c127202010-08-23 23:09:38 +0000684 return false;
685 }
Sean Callanan810f22d2010-07-16 00:09:46 +0000686 }
687
Sean Callananf328c9f2010-07-20 23:31:16 +0000688 return true;
689}
690
Sean Callanana48fe162010-08-11 03:57:18 +0000691bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000692ClangExpressionDeclMap::DoMaterializeOnePersistentVariable
693(
694 bool dematerialize,
695 ExecutionContext &exe_ctx,
696 const ConstString &name,
697 lldb::addr_t addr,
698 Error &err
699)
Sean Callananaa301c42010-12-03 01:38:59 +0000700{
701 ClangPersistentVariables &persistent_vars = exe_ctx.process->GetPersistentVariables();
702
703 ClangExpressionVariable *pvar(persistent_vars.GetVariable(name));
Sean Callanana48fe162010-08-11 03:57:18 +0000704
705 if (!pvar)
706 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000707 err.SetErrorStringWithFormat("Undefined persistent variable %s", name.GetCString());
Sean Callanana48fe162010-08-11 03:57:18 +0000708 return LLDB_INVALID_ADDRESS;
709 }
710
711 size_t pvar_size = pvar->Size();
Sean Callanana6223432010-08-20 01:02:30 +0000712
Greg Clayton66ed2fb2010-10-05 00:00:42 +0000713 if (!pvar->m_data_sp.get())
Sean Callanana6223432010-08-20 01:02:30 +0000714 return false;
715
Greg Clayton66ed2fb2010-10-05 00:00:42 +0000716 uint8_t *pvar_data = pvar->m_data_sp->GetBytes();
Sean Callanana48fe162010-08-11 03:57:18 +0000717 Error error;
718
719 if (dematerialize)
720 {
721 if (exe_ctx.process->ReadMemory (addr, pvar_data, pvar_size, error) != pvar_size)
722 {
723 err.SetErrorStringWithFormat ("Couldn't read a composite type from the target: %s", error.AsCString());
724 return false;
725 }
726 }
727 else
728 {
729 if (exe_ctx.process->WriteMemory (addr, pvar_data, pvar_size, error) != pvar_size)
730 {
731 err.SetErrorStringWithFormat ("Couldn't write a composite type to the target: %s", error.AsCString());
732 return false;
733 }
734 }
735
736 return true;
737}
738
Sean Callananf328c9f2010-07-20 23:31:16 +0000739bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000740ClangExpressionDeclMap::DoMaterializeOneVariable
741(
742 bool dematerialize,
743 ExecutionContext &exe_ctx,
744 const SymbolContext &sym_ctx,
745 const ConstString &name,
746 TypeFromUser type,
747 lldb::addr_t addr,
748 Error &err
749)
Sean Callananf328c9f2010-07-20 23:31:16 +0000750{
Greg Claytone005f2c2010-11-06 01:53:30 +0000751 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callananf328c9f2010-07-20 23:31:16 +0000752
Sean Callanan17c6a052010-10-05 20:18:48 +0000753 if (!exe_ctx.frame || !exe_ctx.process)
Sean Callanancc074622010-09-14 21:59:34 +0000754 return false;
755
Greg Clayton3bc52d02010-11-14 22:13:40 +0000756 Variable *var = FindVariableInScope (*exe_ctx.frame, name, &type);
Sean Callananf328c9f2010-07-20 23:31:16 +0000757
758 if (!var)
759 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000760 err.SetErrorStringWithFormat("Couldn't find %s with appropriate type", name.GetCString());
Sean Callananf328c9f2010-07-20 23:31:16 +0000761 return false;
762 }
763
Sean Callanan841026f2010-07-23 00:16:21 +0000764 if (log)
Greg Clayton8de27c72010-10-15 22:48:33 +0000765 log->Printf("%s %s with type %p", (dematerialize ? "Dematerializing" : "Materializing"), name.GetCString(), type.GetOpaqueQualType());
Sean Callananf328c9f2010-07-20 23:31:16 +0000766
767 std::auto_ptr<lldb_private::Value> location_value(GetVariableValue(exe_ctx,
768 var,
Sean Callananaa301c42010-12-03 01:38:59 +0000769 NULL));
Sean Callananf328c9f2010-07-20 23:31:16 +0000770
771 if (!location_value.get())
772 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000773 err.SetErrorStringWithFormat("Couldn't get value for %s", name.GetCString());
Sean Callananf328c9f2010-07-20 23:31:16 +0000774 return false;
775 }
Sean Callanan17c6a052010-10-05 20:18:48 +0000776
777 // The size of the type contained in addr
Sean Callananf328c9f2010-07-20 23:31:16 +0000778
Sean Callanan17c6a052010-10-05 20:18:48 +0000779 size_t addr_bit_size = ClangASTType::GetClangTypeBitWidth(type.GetASTContext(), type.GetOpaqueQualType());
780 size_t addr_byte_size = addr_bit_size % 8 ? ((addr_bit_size + 8) / 8) : (addr_bit_size / 8);
781
782 Value::ValueType value_type = location_value->GetValueType();
783
784 switch (value_type)
Sean Callananf328c9f2010-07-20 23:31:16 +0000785 {
Sean Callanan17c6a052010-10-05 20:18:48 +0000786 default:
Sean Callananf328c9f2010-07-20 23:31:16 +0000787 {
Sean Callanan17c6a052010-10-05 20:18:48 +0000788 StreamString ss;
789
790 location_value->Dump(&ss);
791
Greg Clayton8de27c72010-10-15 22:48:33 +0000792 err.SetErrorStringWithFormat("%s has a value of unhandled type: %s", name.GetCString(), ss.GetString().c_str());
Sean Callananf328c9f2010-07-20 23:31:16 +0000793 return false;
794 }
Sean Callanan17c6a052010-10-05 20:18:48 +0000795 break;
796 case Value::eValueTypeLoadAddress:
Sean Callananf328c9f2010-07-20 23:31:16 +0000797 {
Sean Callanan17c6a052010-10-05 20:18:48 +0000798 lldb::addr_t value_addr = location_value->GetScalar().ULongLong();
799
800 DataBufferHeap data;
801 data.SetByteSize(addr_byte_size);
802
803 lldb::addr_t src_addr;
804 lldb::addr_t dest_addr;
805
806 if (dematerialize)
807 {
808 src_addr = addr;
809 dest_addr = value_addr;
810 }
811 else
812 {
813 src_addr = value_addr;
814 dest_addr = addr;
815 }
816
817 Error error;
818 if (exe_ctx.process->ReadMemory (src_addr, data.GetBytes(), addr_byte_size, error) != addr_byte_size)
819 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000820 err.SetErrorStringWithFormat ("Couldn't read %s from the target: %s", name.GetCString(), error.AsCString());
Sean Callanan17c6a052010-10-05 20:18:48 +0000821 return false;
822 }
823
824 if (exe_ctx.process->WriteMemory (dest_addr, data.GetBytes(), addr_byte_size, error) != addr_byte_size)
825 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000826 err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", name.GetCString(), error.AsCString());
Sean Callanan17c6a052010-10-05 20:18:48 +0000827 return false;
828 }
829
830 if (log)
831 log->Printf("Copied from 0x%llx to 0x%llx", (uint64_t)src_addr, (uint64_t)addr);
Sean Callananf328c9f2010-07-20 23:31:16 +0000832 }
Sean Callanan17c6a052010-10-05 20:18:48 +0000833 break;
834 case Value::eValueTypeScalar:
835 {
Greg Clayton6916e352010-11-13 03:52:47 +0000836 if (location_value->GetContextType() != Value::eContextTypeRegisterInfo)
Sean Callanan17c6a052010-10-05 20:18:48 +0000837 {
838 StreamString ss;
839
840 location_value->Dump(&ss);
841
Greg Clayton8de27c72010-10-15 22:48:33 +0000842 err.SetErrorStringWithFormat("%s is a scalar of unhandled type: %s", name.GetCString(), ss.GetString().c_str());
Sean Callanan17c6a052010-10-05 20:18:48 +0000843 return false;
844 }
845
846 lldb::RegisterInfo *register_info = location_value->GetRegisterInfo();
847
848 if (!register_info)
849 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000850 err.SetErrorStringWithFormat("Couldn't get the register information for %s", name.GetCString());
Sean Callanan17c6a052010-10-05 20:18:48 +0000851 return false;
852 }
853
854 RegisterContext *register_context = exe_ctx.GetRegisterContext();
855
856 if (!register_context)
857 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000858 err.SetErrorStringWithFormat("Couldn't read register context to read %s from %s", name.GetCString(), register_info->name);
Sean Callanan17c6a052010-10-05 20:18:48 +0000859 return false;
860 }
861
862 uint32_t register_number = register_info->kinds[lldb::eRegisterKindLLDB];
863 uint32_t register_byte_size = register_info->byte_size;
864
865 if (dematerialize)
866 {
867 // Moving from addr into a register
868 //
869 // Case 1: addr_byte_size and register_byte_size are the same
870 //
871 // |AABBCCDD| Address contents
872 // |AABBCCDD| Register contents
873 //
874 // Case 2: addr_byte_size is bigger than register_byte_size
875 //
876 // Error! (The register should always be big enough to hold the data)
877 //
878 // Case 3: register_byte_size is bigger than addr_byte_size
879 //
880 // |AABB| Address contents
881 // |AABB0000| Register contents [on little-endian hardware]
882 // |0000AABB| Register contents [on big-endian hardware]
883
884 if (addr_byte_size > register_byte_size)
885 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000886 err.SetErrorStringWithFormat("%s is too big to store in %s", name.GetCString(), register_info->name);
Sean Callanan17c6a052010-10-05 20:18:48 +0000887 return false;
888 }
889
890 uint32_t register_offset;
891
892 switch (exe_ctx.process->GetByteOrder())
893 {
894 default:
Greg Clayton8de27c72010-10-15 22:48:33 +0000895 err.SetErrorStringWithFormat("%s is stored with an unhandled byte order", name.GetCString());
Sean Callanan17c6a052010-10-05 20:18:48 +0000896 return false;
897 case lldb::eByteOrderLittle:
898 register_offset = 0;
899 break;
900 case lldb::eByteOrderBig:
901 register_offset = register_byte_size - addr_byte_size;
902 break;
903 }
904
905 DataBufferHeap register_data (register_byte_size, 0);
906
907 Error error;
908 if (exe_ctx.process->ReadMemory (addr, register_data.GetBytes() + register_offset, addr_byte_size, error) != addr_byte_size)
909 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000910 err.SetErrorStringWithFormat ("Couldn't read %s from the target: %s", name.GetCString(), error.AsCString());
Sean Callanan17c6a052010-10-05 20:18:48 +0000911 return false;
912 }
913
914 DataExtractor register_extractor (register_data.GetBytes(), register_byte_size, exe_ctx.process->GetByteOrder(), exe_ctx.process->GetAddressByteSize());
915
916 if (!register_context->WriteRegisterBytes(register_number, register_extractor, 0))
917 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000918 err.SetErrorStringWithFormat("Couldn't read %s from %s", name.GetCString(), register_info->name);
Sean Callanan17c6a052010-10-05 20:18:48 +0000919 return false;
920 }
921 }
922 else
923 {
924 // Moving from a register into addr
925 //
926 // Case 1: addr_byte_size and register_byte_size are the same
927 //
928 // |AABBCCDD| Register contents
929 // |AABBCCDD| Address contents
930 //
931 // Case 2: addr_byte_size is bigger than register_byte_size
932 //
933 // Error! (The register should always be big enough to hold the data)
934 //
935 // Case 3: register_byte_size is bigger than addr_byte_size
936 //
937 // |AABBCCDD| Register contents
938 // |AABB| Address contents on little-endian hardware
939 // |CCDD| Address contents on big-endian hardware
940
941 if (addr_byte_size > register_byte_size)
942 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000943 err.SetErrorStringWithFormat("%s is too big to store in %s", name.GetCString(), register_info->name);
Sean Callanan17c6a052010-10-05 20:18:48 +0000944 return false;
945 }
946
947 uint32_t register_offset;
948
949 switch (exe_ctx.process->GetByteOrder())
950 {
951 default:
Greg Clayton8de27c72010-10-15 22:48:33 +0000952 err.SetErrorStringWithFormat("%s is stored with an unhandled byte order", name.GetCString());
Sean Callanan17c6a052010-10-05 20:18:48 +0000953 return false;
954 case lldb::eByteOrderLittle:
955 register_offset = 0;
956 break;
957 case lldb::eByteOrderBig:
958 register_offset = register_byte_size - addr_byte_size;
959 break;
960 }
961
962 DataExtractor register_extractor;
963
964 if (!register_context->ReadRegisterBytes(register_number, register_extractor))
965 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000966 err.SetErrorStringWithFormat("Couldn't read %s from %s", name.GetCString(), register_info->name);
Sean Callanan17c6a052010-10-05 20:18:48 +0000967 return false;
968 }
969
970 const void *register_data = register_extractor.GetData(&register_offset, addr_byte_size);
971
972 if (!register_data)
973 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000974 err.SetErrorStringWithFormat("Read but couldn't extract data for %s from %s", name.GetCString(), register_info->name);
Sean Callanan17c6a052010-10-05 20:18:48 +0000975 return false;
976 }
977
978 Error error;
979 if (exe_ctx.process->WriteMemory (addr, register_data, addr_byte_size, error) != addr_byte_size)
980 {
981 err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", error.AsCString());
982 return false;
983 }
984 }
985 }
Sean Callananf328c9f2010-07-20 23:31:16 +0000986 }
987
988 return true;
Sean Callanan810f22d2010-07-16 00:09:46 +0000989}
990
Sean Callanan1ddd9fe2010-11-30 00:27:43 +0000991bool
992ClangExpressionDeclMap::DoMaterializeOneRegister
993(
994 bool dematerialize,
995 ExecutionContext &exe_ctx,
996 RegisterContext &reg_ctx,
997 const lldb::RegisterInfo &reg_info,
998 lldb::addr_t addr,
999 Error &err
1000)
1001{
1002 uint32_t register_number = reg_info.kinds[lldb::eRegisterKindLLDB];
1003 uint32_t register_byte_size = reg_info.byte_size;
1004
1005 Error error;
1006
1007 if (dematerialize)
1008 {
1009 DataBufferHeap register_data (register_byte_size, 0);
1010
1011 Error error;
1012 if (exe_ctx.process->ReadMemory (addr, register_data.GetBytes(), register_byte_size, error) != register_byte_size)
1013 {
1014 err.SetErrorStringWithFormat ("Couldn't read %s from the target: %s", reg_info.name, error.AsCString());
1015 return false;
1016 }
1017
1018 DataExtractor register_extractor (register_data.GetBytes(), register_byte_size, exe_ctx.process->GetByteOrder(), exe_ctx.process->GetAddressByteSize());
1019
1020 if (!reg_ctx.WriteRegisterBytes(register_number, register_extractor, 0))
1021 {
1022 err.SetErrorStringWithFormat("Couldn't read %s", reg_info.name);
1023 return false;
1024 }
1025 }
1026 else
1027 {
1028 DataExtractor register_extractor;
1029
1030 if (!reg_ctx.ReadRegisterBytes(register_number, register_extractor))
1031 {
1032 err.SetErrorStringWithFormat("Couldn't read %s", reg_info.name);
1033 return false;
1034 }
1035
1036 uint32_t register_offset = 0;
1037
1038 const void *register_data = register_extractor.GetData(&register_offset, register_byte_size);
1039
1040 if (!register_data)
1041 {
1042 err.SetErrorStringWithFormat("Read but couldn't extract data for %s", reg_info.name);
1043 return false;
1044 }
1045
1046 Error error;
1047 if (exe_ctx.process->WriteMemory (addr, register_data, register_byte_size, error) != register_byte_size)
1048 {
1049 err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", error.AsCString());
1050 return false;
1051 }
1052 }
1053
1054 return true;
1055}
1056
Sean Callanancc074622010-09-14 21:59:34 +00001057Variable *
Greg Clayton8de27c72010-10-15 22:48:33 +00001058ClangExpressionDeclMap::FindVariableInScope
1059(
1060 StackFrame &frame,
1061 const ConstString &name,
1062 TypeFromUser *type
1063)
Sean Callananaa301c42010-12-03 01:38:59 +00001064{
Greg Claytone005f2c2010-11-06 01:53:30 +00001065 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanancc074622010-09-14 21:59:34 +00001066
Sean Callanancc074622010-09-14 21:59:34 +00001067 VariableList *var_list = frame.GetVariableList(true);
1068
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001069 if (!var_list)
1070 return NULL;
1071
Greg Clayton3bc52d02010-11-14 22:13:40 +00001072 lldb::VariableSP var_sp (var_list->FindVariable(name));
1073
1074 const bool append = true;
1075 const uint32_t max_matches = 1;
1076 if (!var_sp)
Sean Callanancc074622010-09-14 21:59:34 +00001077 {
Greg Clayton3bc52d02010-11-14 22:13:40 +00001078 // Look for globals elsewhere in the module for the frame
Sean Callananaa301c42010-12-03 01:38:59 +00001079 ModuleSP module_sp (frame.GetSymbolContext(eSymbolContextModule).module_sp);
Greg Clayton3bc52d02010-11-14 22:13:40 +00001080 if (module_sp)
1081 {
1082 VariableList module_globals;
1083 if (module_sp->FindGlobalVariables (name, append, max_matches, module_globals))
1084 var_sp = module_globals.GetVariableAtIndex (0);
1085 }
1086 }
1087
1088 if (!var_sp)
1089 {
1090 // Look for globals elsewhere in the program (all images)
Sean Callananaa301c42010-12-03 01:38:59 +00001091 TargetSP target_sp (frame.GetSymbolContext(eSymbolContextTarget).target_sp);
Greg Clayton3bc52d02010-11-14 22:13:40 +00001092 if (target_sp)
1093 {
1094 VariableList program_globals;
1095 if (target_sp->GetImages().FindGlobalVariables (name, append, max_matches, program_globals))
1096 var_sp = program_globals.GetVariableAtIndex (0);
1097 }
1098 }
1099
1100 if (var_sp && type)
1101 {
1102 if (type->GetASTContext() == var_sp->GetType()->GetClangAST())
1103 {
1104 if (!ClangASTContext::AreTypesSame(type->GetASTContext(), type->GetOpaqueQualType(), var_sp->GetType()->GetClangType()))
1105 return NULL;
1106 }
1107 else
1108 {
1109 if (log)
1110 log->PutCString("Skipping a candidate variable because of different AST contexts");
Sean Callanancc074622010-09-14 21:59:34 +00001111 return NULL;
Greg Clayton3bc52d02010-11-14 22:13:40 +00001112 }
Sean Callanancc074622010-09-14 21:59:34 +00001113 }
Greg Clayton3bc52d02010-11-14 22:13:40 +00001114
1115 return var_sp.get();
Sean Callanancc074622010-09-14 21:59:34 +00001116}
Sean Callanan336a0002010-07-17 00:43:37 +00001117
Chris Lattner24943d22010-06-08 16:52:24 +00001118// Interface for ClangASTSource
1119void
Greg Claytone5748d82010-11-09 23:46:37 +00001120ClangExpressionDeclMap::GetDecls (NameSearchContext &context, const ConstString &name)
Chris Lattner24943d22010-06-08 16:52:24 +00001121{
Sean Callananaa301c42010-12-03 01:38:59 +00001122 assert (m_struct_vars.get());
1123 assert (m_parser_vars.get());
1124
Greg Claytone005f2c2010-11-06 01:53:30 +00001125 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001126
Sean Callanan810f22d2010-07-16 00:09:46 +00001127 if (log)
Greg Clayton8de27c72010-10-15 22:48:33 +00001128 log->Printf("Hunting for a definition for '%s'", name.GetCString());
Chris Lattner24943d22010-06-08 16:52:24 +00001129
1130 // Back out in all cases where we're not fully initialized
Sean Callananaa301c42010-12-03 01:38:59 +00001131 if (m_parser_vars->m_exe_ctx->frame == NULL)
Chris Lattner24943d22010-06-08 16:52:24 +00001132 return;
Sean Callananee8fc722010-11-19 20:20:02 +00001133
Sean Callananaa301c42010-12-03 01:38:59 +00001134 if (m_parser_vars->m_ignore_lookups)
Sean Callananee8fc722010-11-19 20:20:02 +00001135 {
1136 if (log)
1137 log->Printf("Ignoring a query during an import");
1138 return;
1139 }
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001140
Greg Claytone5748d82010-11-09 23:46:37 +00001141 SymbolContextList sc_list;
Chris Lattner24943d22010-06-08 16:52:24 +00001142
Greg Clayton3bc52d02010-11-14 22:13:40 +00001143 const char *name_unique_cstr = name.GetCString();
1144
1145 if (name_unique_cstr == NULL)
1146 return;
1147
Greg Clayton8de27c72010-10-15 22:48:33 +00001148 // Only look for functions by name out in our symbols if the function
1149 // doesn't start with our phony prefix of '$'
Greg Clayton3bc52d02010-11-14 22:13:40 +00001150 if (name_unique_cstr[0] != '$')
Sean Callanan0fc73582010-07-27 00:55:47 +00001151 {
Sean Callananaa301c42010-12-03 01:38:59 +00001152 Variable *var = FindVariableInScope(*m_parser_vars->m_exe_ctx->frame, name);
Greg Clayton8de27c72010-10-15 22:48:33 +00001153
1154 // If we found a variable in scope, no need to pull up function names
1155 if (var != NULL)
1156 {
1157 AddOneVariable(context, var);
1158 }
1159 else
1160 {
Sean Callananaa301c42010-12-03 01:38:59 +00001161 m_parser_vars->m_sym_ctx.FindFunctionsByName (name, false, sc_list);
Greg Clayton8de27c72010-10-15 22:48:33 +00001162
1163 bool found_specific = false;
1164 Symbol *generic_symbol = NULL;
1165 Symbol *non_extern_symbol = NULL;
1166
Greg Claytone5748d82010-11-09 23:46:37 +00001167 for (uint32_t index = 0, num_indices = sc_list.GetSize();
Greg Clayton8de27c72010-10-15 22:48:33 +00001168 index < num_indices;
1169 ++index)
1170 {
1171 SymbolContext sym_ctx;
Greg Claytone5748d82010-11-09 23:46:37 +00001172 sc_list.GetContextAtIndex(index, sym_ctx);
Sean Callanan3cfbd332010-10-06 00:10:07 +00001173
Greg Clayton8de27c72010-10-15 22:48:33 +00001174 if (sym_ctx.function)
1175 {
1176 // TODO only do this if it's a C function; C++ functions may be
1177 // overloaded
1178 if (!found_specific)
1179 AddOneFunction(context, sym_ctx.function, NULL);
1180 found_specific = true;
1181 }
1182 else if (sym_ctx.symbol)
1183 {
1184 if (sym_ctx.symbol->IsExternal())
1185 generic_symbol = sym_ctx.symbol;
1186 else
1187 non_extern_symbol = sym_ctx.symbol;
1188 }
1189 }
1190
Sean Callanan92aa6662010-09-07 21:49:41 +00001191 if (!found_specific)
Greg Clayton8de27c72010-10-15 22:48:33 +00001192 {
1193 if (generic_symbol)
1194 AddOneFunction(context, NULL, generic_symbol);
1195 else if (non_extern_symbol)
1196 AddOneFunction(context, NULL, non_extern_symbol);
1197 }
Greg Clayton6916e352010-11-13 03:52:47 +00001198
Sean Callananaa301c42010-12-03 01:38:59 +00001199 ClangNamespaceDecl namespace_decl (m_parser_vars->m_sym_ctx.FindNamespace(name));
Greg Clayton6916e352010-11-13 03:52:47 +00001200 if (namespace_decl)
1201 {
Greg Clayton9ceed1e2010-11-13 04:18:24 +00001202 clang::NamespaceDecl *clang_namespace_decl = AddNamespace(context, namespace_decl);
1203 if (clang_namespace_decl)
1204 {
1205 // TODO: is this how we get the decl lookups to be called for
1206 // this namespace??
1207 clang_namespace_decl->setHasExternalLexicalStorage();
1208 }
Greg Clayton6916e352010-11-13 03:52:47 +00001209 }
Sean Callanan92aa6662010-09-07 21:49:41 +00001210 }
Sean Callanan0fc73582010-07-27 00:55:47 +00001211 }
Greg Clayton8de27c72010-10-15 22:48:33 +00001212 else
Sean Callanan3cfbd332010-10-06 00:10:07 +00001213 {
Greg Clayton57452832010-11-09 04:42:43 +00001214 static ConstString g_lldb_class_name ("$__lldb_class");
1215 if (name == g_lldb_class_name)
1216 {
1217 // Clang is looking for the type of "this"
1218
Sean Callananaa301c42010-12-03 01:38:59 +00001219 VariableList *vars = m_parser_vars->m_exe_ctx->frame->GetVariableList(false);
Greg Clayton57452832010-11-09 04:42:43 +00001220
1221 if (!vars)
1222 return;
1223
1224 lldb::VariableSP this_var = vars->FindVariable(ConstString("this"));
1225
1226 if (!this_var)
1227 return;
1228
1229 Type *this_type = this_var->GetType();
1230
1231 if (!this_type)
1232 return;
1233
Greg Clayton2403b5e2010-11-16 02:10:54 +00001234 if (log)
1235 {
1236 log->PutCString ("Type for \"this\" is: ");
1237 StreamString strm;
1238 this_type->Dump(&strm, true);
1239 log->PutCString (strm.GetData());
1240 }
1241
Greg Clayton57452832010-11-09 04:42:43 +00001242 TypeFromUser this_user_type(this_type->GetClangType(),
1243 this_type->GetClangAST());
1244
Sean Callananaa301c42010-12-03 01:38:59 +00001245 m_struct_vars->m_object_pointer_type = this_user_type;
Greg Clayton57452832010-11-09 04:42:43 +00001246
1247 void *pointer_target_type;
1248
1249 if (!ClangASTContext::IsPointerType(this_user_type.GetOpaqueQualType(),
1250 &pointer_target_type))
1251 return;
1252
1253 TypeFromUser class_user_type(pointer_target_type,
1254 this_type->GetClangAST());
1255
Sean Callanan3aa7da52010-12-13 22:46:15 +00001256 if (log)
1257 {
1258 StreamString type_stream;
1259 class_user_type.DumpTypeCode(&type_stream);
1260 type_stream.Flush();
1261 log->Printf("Adding type for $__lldb_class: %s", type_stream.GetString().c_str());
1262 }
1263
Greg Clayton57452832010-11-09 04:42:43 +00001264 AddOneType(context, class_user_type, true);
1265
1266 return;
1267 }
1268
Sean Callanan3aa7da52010-12-13 22:46:15 +00001269 static ConstString g_lldb_objc_class_name ("$__lldb_objc_class");
1270 if (name == g_lldb_objc_class_name)
1271 {
1272 // Clang is looking for the type of "*self"
1273
1274 VariableList *vars = m_parser_vars->m_exe_ctx->frame->GetVariableList(false);
1275
1276 if (!vars)
1277 return;
1278
1279 lldb::VariableSP self_var = vars->FindVariable(ConstString("self"));
1280
1281 if (!self_var)
1282 return;
1283
1284 Type *self_type = self_var->GetType();
1285
1286 if (!self_type)
1287 return;
1288
1289 TypeFromUser self_user_type(self_type->GetClangType(),
1290 self_type->GetClangAST());
1291
1292 m_struct_vars->m_object_pointer_type = self_user_type;
1293
1294 void *pointer_target_type;
1295
1296 if (!ClangASTContext::IsPointerType(self_user_type.GetOpaqueQualType(),
1297 &pointer_target_type))
1298 return;
1299
1300 TypeFromUser class_user_type(pointer_target_type,
1301 self_type->GetClangAST());
1302
1303 if (log)
1304 {
1305 StreamString type_stream;
1306 class_user_type.DumpTypeCode(&type_stream);
1307 type_stream.Flush();
1308 log->Printf("Adding type for $__lldb_objc_class: %s", type_stream.GetString().c_str());
1309 }
1310
1311 AddOneType(context, class_user_type, false);
1312
1313 return;
1314 }
1315
Sean Callananaa301c42010-12-03 01:38:59 +00001316 ClangExpressionVariable *pvar(m_parser_vars->m_persistent_vars->GetVariable(name));
Greg Clayton8de27c72010-10-15 22:48:33 +00001317
1318 if (pvar)
Sean Callanan1ddd9fe2010-11-30 00:27:43 +00001319 {
Greg Clayton8de27c72010-10-15 22:48:33 +00001320 AddOneVariable(context, pvar);
Sean Callanan1ddd9fe2010-11-30 00:27:43 +00001321 return;
1322 }
1323
1324 const char *reg_name(&name.GetCString()[1]);
1325
Sean Callananaa301c42010-12-03 01:38:59 +00001326 if (m_parser_vars->m_exe_ctx->GetRegisterContext())
Sean Callanan1ddd9fe2010-11-30 00:27:43 +00001327 {
Sean Callananaa301c42010-12-03 01:38:59 +00001328 const lldb::RegisterInfo *reg_info(m_parser_vars->m_exe_ctx->GetRegisterContext()->GetRegisterInfoByName(reg_name));
Sean Callanan1ddd9fe2010-11-30 00:27:43 +00001329
1330 if (reg_info)
1331 AddOneRegister(context, reg_info);
1332 }
Sean Callanan3cfbd332010-10-06 00:10:07 +00001333 }
1334
Sean Callananaa301c42010-12-03 01:38:59 +00001335 lldb::TypeSP type_sp (m_parser_vars->m_sym_ctx.FindTypeByName (name));
Sean Callananee8fc722010-11-19 20:20:02 +00001336
1337 if (type_sp)
Sean Callanan6df08402010-09-27 23:54:58 +00001338 {
Sean Callananee8fc722010-11-19 20:20:02 +00001339 if (log)
Sean Callanan6df08402010-09-27 23:54:58 +00001340 {
Sean Callananee8fc722010-11-19 20:20:02 +00001341 log->Printf ("Matching type found for \"%s\": ", name.GetCString());
1342 StreamString strm;
1343 type_sp->Dump(&strm, true);
1344 log->PutCString (strm.GetData());
1345 }
Greg Clayton2403b5e2010-11-16 02:10:54 +00001346
Sean Callananee8fc722010-11-19 20:20:02 +00001347 TypeFromUser user_type(type_sp->GetClangType(),
Greg Clayton2403b5e2010-11-16 02:10:54 +00001348 type_sp->GetClangAST());
Sean Callanan6df08402010-09-27 23:54:58 +00001349
Sean Callananee8fc722010-11-19 20:20:02 +00001350 AddOneType(context, user_type, false);
Sean Callanan6df08402010-09-27 23:54:58 +00001351 }
Sean Callanan336a0002010-07-17 00:43:37 +00001352}
1353
1354Value *
Greg Clayton8de27c72010-10-15 22:48:33 +00001355ClangExpressionDeclMap::GetVariableValue
1356(
1357 ExecutionContext &exe_ctx,
1358 Variable *var,
1359 clang::ASTContext *parser_ast_context,
1360 TypeFromUser *user_type,
1361 TypeFromParser *parser_type
1362)
Chris Lattner24943d22010-06-08 16:52:24 +00001363{
Greg Claytone005f2c2010-11-06 01:53:30 +00001364 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan6184dfe2010-06-23 00:47:48 +00001365
Chris Lattner24943d22010-06-08 16:52:24 +00001366 Type *var_type = var->GetType();
1367
1368 if (!var_type)
1369 {
Sean Callanan810f22d2010-07-16 00:09:46 +00001370 if (log)
1371 log->PutCString("Skipped a definition because it has no type");
Sean Callanan336a0002010-07-17 00:43:37 +00001372 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001373 }
1374
Greg Clayton462d4142010-09-29 01:12:09 +00001375 void *var_opaque_type = var_type->GetClangType();
Chris Lattner24943d22010-06-08 16:52:24 +00001376
1377 if (!var_opaque_type)
1378 {
Sean Callanan810f22d2010-07-16 00:09:46 +00001379 if (log)
1380 log->PutCString("Skipped a definition because it has no Clang type");
Sean Callanan336a0002010-07-17 00:43:37 +00001381 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001382 }
1383
Chris Lattner24943d22010-06-08 16:52:24 +00001384 TypeList *type_list = var_type->GetTypeList();
1385
1386 if (!type_list)
1387 {
Sean Callanan810f22d2010-07-16 00:09:46 +00001388 if (log)
1389 log->PutCString("Skipped a definition because the type has no associated type list");
Sean Callanan336a0002010-07-17 00:43:37 +00001390 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001391 }
1392
1393 clang::ASTContext *exe_ast_ctx = type_list->GetClangASTContext().getASTContext();
1394
1395 if (!exe_ast_ctx)
1396 {
Sean Callanan810f22d2010-07-16 00:09:46 +00001397 if (log)
1398 log->PutCString("There is no AST context for the current execution context");
Sean Callanan336a0002010-07-17 00:43:37 +00001399 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001400 }
1401
Sean Callanan336a0002010-07-17 00:43:37 +00001402 DWARFExpression &var_location_expr = var->LocationExpression();
1403
Chris Lattner24943d22010-06-08 16:52:24 +00001404 std::auto_ptr<Value> var_location(new Value);
1405
Greg Clayton178710c2010-09-14 02:20:48 +00001406 lldb::addr_t loclist_base_load_addr = LLDB_INVALID_ADDRESS;
1407
1408 if (var_location_expr.IsLocationList())
1409 {
1410 SymbolContext var_sc;
1411 var->CalculateSymbolContext (&var_sc);
Greg Claytoneea26402010-09-14 23:36:40 +00001412 loclist_base_load_addr = var_sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (exe_ctx.target);
Greg Clayton178710c2010-09-14 02:20:48 +00001413 }
Chris Lattner24943d22010-06-08 16:52:24 +00001414 Error err;
1415
Jason Molenda8e69de42010-11-20 01:28:30 +00001416 if (!var_location_expr.Evaluate(&exe_ctx, exe_ast_ctx, NULL, loclist_base_load_addr, NULL, *var_location.get(), &err))
Chris Lattner24943d22010-06-08 16:52:24 +00001417 {
Sean Callanan810f22d2010-07-16 00:09:46 +00001418 if (log)
1419 log->Printf("Error evaluating location: %s", err.AsCString());
Sean Callanan336a0002010-07-17 00:43:37 +00001420 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001421 }
1422
Sean Callanan810f22d2010-07-16 00:09:46 +00001423 clang::ASTContext *var_ast_context = type_list->GetClangASTContext().getASTContext();
1424
Sean Callanan336a0002010-07-17 00:43:37 +00001425 void *type_to_use;
1426
Sean Callananf328c9f2010-07-20 23:31:16 +00001427 if (parser_ast_context)
1428 {
Sean Callananee8fc722010-11-19 20:20:02 +00001429 type_to_use = GuardedCopyType(parser_ast_context, var_ast_context, var_opaque_type);
Sean Callananf328c9f2010-07-20 23:31:16 +00001430
Sean Callanan4b5eec62010-11-20 02:19:29 +00001431 if (!type_to_use)
1432 {
1433 if (log)
1434 log->Printf("Couldn't copy a variable's type into the parser's AST context");
1435
1436 return NULL;
1437 }
1438
Sean Callananf328c9f2010-07-20 23:31:16 +00001439 if (parser_type)
1440 *parser_type = TypeFromParser(type_to_use, parser_ast_context);
1441 }
Sean Callanan336a0002010-07-17 00:43:37 +00001442 else
1443 type_to_use = var_opaque_type;
Chris Lattner24943d22010-06-08 16:52:24 +00001444
1445 if (var_location.get()->GetContextType() == Value::eContextTypeInvalid)
Greg Clayton6916e352010-11-13 03:52:47 +00001446 var_location.get()->SetContext(Value::eContextTypeClangType, type_to_use);
Chris Lattner24943d22010-06-08 16:52:24 +00001447
1448 if (var_location.get()->GetValueType() == Value::eValueTypeFileAddress)
1449 {
1450 SymbolContext var_sc;
1451 var->CalculateSymbolContext(&var_sc);
Sean Callanan336a0002010-07-17 00:43:37 +00001452
Chris Lattner24943d22010-06-08 16:52:24 +00001453 if (!var_sc.module_sp)
Sean Callanan336a0002010-07-17 00:43:37 +00001454 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001455
1456 ObjectFile *object_file = var_sc.module_sp->GetObjectFile();
1457
1458 if (!object_file)
Sean Callanan336a0002010-07-17 00:43:37 +00001459 return NULL;
1460
Chris Lattner24943d22010-06-08 16:52:24 +00001461 Address so_addr(var_location->GetScalar().ULongLong(), object_file->GetSectionList());
1462
Sean Callananaa301c42010-12-03 01:38:59 +00001463 lldb::addr_t load_addr = so_addr.GetLoadAddress(exe_ctx.target);
Chris Lattner24943d22010-06-08 16:52:24 +00001464
1465 var_location->GetScalar() = load_addr;
1466 var_location->SetValueType(Value::eValueTypeLoadAddress);
1467 }
1468
Sean Callananf328c9f2010-07-20 23:31:16 +00001469 if (user_type)
1470 *user_type = TypeFromUser(var_opaque_type, var_ast_context);
Sean Callanan336a0002010-07-17 00:43:37 +00001471
1472 return var_location.release();
1473}
1474
1475void
1476ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001477 Variable* var)
Sean Callanan336a0002010-07-17 00:43:37 +00001478{
Sean Callananaa301c42010-12-03 01:38:59 +00001479 assert (m_parser_vars.get());
1480
Greg Claytone005f2c2010-11-06 01:53:30 +00001481 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan336a0002010-07-17 00:43:37 +00001482
Sean Callananf328c9f2010-07-20 23:31:16 +00001483 TypeFromUser ut;
1484 TypeFromParser pt;
Sean Callanan336a0002010-07-17 00:43:37 +00001485
Sean Callananaa301c42010-12-03 01:38:59 +00001486 Value *var_location = GetVariableValue (*m_parser_vars->m_exe_ctx,
Greg Clayton8de27c72010-10-15 22:48:33 +00001487 var,
1488 context.GetASTContext(),
1489 &ut,
1490 &pt);
Sean Callanan336a0002010-07-17 00:43:37 +00001491
Sean Callanan4b5eec62010-11-20 02:19:29 +00001492 if (!var_location)
1493 return;
1494
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001495 NamedDecl *var_decl = context.AddVarDecl(pt.GetOpaqueQualType());
Chris Lattner24943d22010-06-08 16:52:24 +00001496
Sean Callanan8c127202010-08-23 23:09:38 +00001497 ClangExpressionVariable &entity(m_found_entities.VariableAtIndex(m_found_entities.CreateVariable()));
Greg Clayton8de27c72010-10-15 22:48:33 +00001498 std::string decl_name(context.m_decl_name.getAsString());
1499 entity.m_name.SetCString (decl_name.c_str());
1500 entity.m_user_type = ut;
Chris Lattner24943d22010-06-08 16:52:24 +00001501
Sean Callanan8c127202010-08-23 23:09:38 +00001502 entity.EnableParserVars();
1503 entity.m_parser_vars->m_parser_type = pt;
1504 entity.m_parser_vars->m_named_decl = var_decl;
1505 entity.m_parser_vars->m_llvm_value = NULL;
1506 entity.m_parser_vars->m_lldb_value = var_location;
Chris Lattner24943d22010-06-08 16:52:24 +00001507
Sean Callanan810f22d2010-07-16 00:09:46 +00001508 if (log)
Greg Clayton8de27c72010-10-15 22:48:33 +00001509 {
Sean Callanana0744822010-11-01 23:22:47 +00001510 std::string var_decl_print_string;
1511 llvm::raw_string_ostream var_decl_print_stream(var_decl_print_string);
1512 var_decl->print(var_decl_print_stream);
1513 var_decl_print_stream.flush();
1514
1515 log->Printf("Found variable %s, returned %s", decl_name.c_str(), var_decl_print_string.c_str());
Greg Clayton8de27c72010-10-15 22:48:33 +00001516 }
Sean Callanan8f0dc342010-06-22 23:46:24 +00001517}
1518
1519void
Sean Callanana48fe162010-08-11 03:57:18 +00001520ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
Sean Callanana6223432010-08-20 01:02:30 +00001521 ClangExpressionVariable *pvar)
Sean Callanana48fe162010-08-11 03:57:18 +00001522{
Greg Claytone005f2c2010-11-06 01:53:30 +00001523 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan45690fe2010-08-30 22:17:16 +00001524
Sean Callanana6223432010-08-20 01:02:30 +00001525 TypeFromUser user_type = pvar->m_user_type;
Sean Callanana48fe162010-08-11 03:57:18 +00001526
Sean Callananee8fc722010-11-19 20:20:02 +00001527 TypeFromParser parser_type(GuardedCopyType(context.GetASTContext(),
1528 user_type.GetASTContext(),
1529 user_type.GetOpaqueQualType()),
Sean Callanana48fe162010-08-11 03:57:18 +00001530 context.GetASTContext());
1531
Sean Callanan8c127202010-08-23 23:09:38 +00001532 NamedDecl *var_decl = context.AddVarDecl(parser_type.GetOpaqueQualType());
1533
1534 pvar->EnableParserVars();
1535 pvar->m_parser_vars->m_parser_type = parser_type;
1536 pvar->m_parser_vars->m_named_decl = var_decl;
1537 pvar->m_parser_vars->m_llvm_value = NULL;
1538 pvar->m_parser_vars->m_lldb_value = NULL;
Sean Callanan45690fe2010-08-30 22:17:16 +00001539
1540 if (log)
Sean Callanana0744822010-11-01 23:22:47 +00001541 {
1542 std::string var_decl_print_string;
1543 llvm::raw_string_ostream var_decl_print_stream(var_decl_print_string);
1544 var_decl->print(var_decl_print_stream);
1545 var_decl_print_stream.flush();
1546
1547 log->Printf("Added pvar %s, returned %s", pvar->m_name.GetCString(), var_decl_print_string.c_str());
1548 }
Sean Callanana48fe162010-08-11 03:57:18 +00001549}
1550
Sean Callanan1ddd9fe2010-11-30 00:27:43 +00001551void
1552ClangExpressionDeclMap::AddOneRegister(NameSearchContext &context,
1553 const RegisterInfo *reg_info)
1554{
1555 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
1556
1557 void *ast_type = ClangASTContext::GetBuiltinTypeForEncodingAndBitSize(context.GetASTContext(),
1558 reg_info->encoding,
1559 reg_info->byte_size * 8);
1560
1561 if (!ast_type)
1562 {
1563 log->Printf("Tried to add a type for %s, but couldn't get one", context.m_decl_name.getAsString().c_str());
1564 return;
1565 }
1566
1567 TypeFromParser parser_type(ast_type,
1568 context.GetASTContext());
1569
1570 NamedDecl *var_decl = context.AddVarDecl(parser_type.GetOpaqueQualType());
1571
1572 ClangExpressionVariable &entity(m_found_entities.VariableAtIndex(m_found_entities.CreateVariable()));
1573 std::string decl_name(context.m_decl_name.getAsString());
1574 entity.m_name.SetCString (decl_name.c_str());
1575 entity.m_register_info = reg_info;
1576
1577 entity.EnableParserVars();
1578 entity.m_parser_vars->m_parser_type = parser_type;
1579 entity.m_parser_vars->m_named_decl = var_decl;
1580 entity.m_parser_vars->m_llvm_value = NULL;
1581 entity.m_parser_vars->m_lldb_value = NULL;
1582
1583 if (log)
1584 {
1585 std::string var_decl_print_string;
1586 llvm::raw_string_ostream var_decl_print_stream(var_decl_print_string);
1587 var_decl->print(var_decl_print_stream);
1588 var_decl_print_stream.flush();
1589
1590 log->Printf("Added register %s, returned %s", context.m_decl_name.getAsString().c_str(), var_decl_print_string.c_str());
1591 }
1592}
1593
Greg Clayton6916e352010-11-13 03:52:47 +00001594clang::NamespaceDecl *
1595ClangExpressionDeclMap::AddNamespace (NameSearchContext &context, const ClangNamespaceDecl &namespace_decl)
1596{
1597 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
1598
1599
1600 clang::Decl *copied_decl = ClangASTContext::CopyDecl (context.GetASTContext(),
1601 namespace_decl.GetASTContext(),
1602 namespace_decl.GetNamespaceDecl());
1603
1604 return dyn_cast<clang::NamespaceDecl>(copied_decl);
1605}
1606
Sean Callanana48fe162010-08-11 03:57:18 +00001607void
Sean Callanan8f0dc342010-06-22 23:46:24 +00001608ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
Sean Callanan0fc73582010-07-27 00:55:47 +00001609 Function* fun,
1610 Symbol* symbol)
Sean Callanan8f0dc342010-06-22 23:46:24 +00001611{
Sean Callananaa301c42010-12-03 01:38:59 +00001612 assert (m_parser_vars.get());
1613
Greg Claytone005f2c2010-11-06 01:53:30 +00001614 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan8f0dc342010-06-22 23:46:24 +00001615
Sean Callanan0fc73582010-07-27 00:55:47 +00001616 NamedDecl *fun_decl;
Sean Callanan8f0dc342010-06-22 23:46:24 +00001617 std::auto_ptr<Value> fun_location(new Value);
Sean Callanan0fc73582010-07-27 00:55:47 +00001618 const Address *fun_address;
Sean Callanan8f0dc342010-06-22 23:46:24 +00001619
Sean Callanan0fc73582010-07-27 00:55:47 +00001620 // only valid for Functions, not for Symbols
1621 void *fun_opaque_type = NULL;
1622 clang::ASTContext *fun_ast_context = NULL;
1623
1624 if (fun)
1625 {
1626 Type *fun_type = fun->GetType();
1627
1628 if (!fun_type)
1629 {
1630 if (log)
1631 log->PutCString("Skipped a function because it has no type");
1632 return;
1633 }
1634
Greg Clayton462d4142010-09-29 01:12:09 +00001635 fun_opaque_type = fun_type->GetClangType();
Sean Callanan0fc73582010-07-27 00:55:47 +00001636
1637 if (!fun_opaque_type)
1638 {
1639 if (log)
1640 log->PutCString("Skipped a function because it has no Clang type");
1641 return;
1642 }
1643
1644 fun_address = &fun->GetAddressRange().GetBaseAddress();
1645
1646 TypeList *type_list = fun_type->GetTypeList();
1647 fun_ast_context = type_list->GetClangASTContext().getASTContext();
Sean Callananee8fc722010-11-19 20:20:02 +00001648 void *copied_type = GuardedCopyType(context.GetASTContext(), fun_ast_context, fun_opaque_type);
Sean Callanan0fc73582010-07-27 00:55:47 +00001649
1650 fun_decl = context.AddFunDecl(copied_type);
1651 }
1652 else if (symbol)
1653 {
1654 fun_address = &symbol->GetAddressRangeRef().GetBaseAddress();
1655
1656 fun_decl = context.AddGenericFunDecl();
1657 }
1658 else
1659 {
1660 if (log)
1661 log->PutCString("AddOneFunction called with no function and no symbol");
1662 return;
1663 }
1664
Sean Callananaa301c42010-12-03 01:38:59 +00001665 lldb::addr_t load_addr = fun_address->GetLoadAddress(m_parser_vars->m_exe_ctx->target);
Sean Callanan8f0dc342010-06-22 23:46:24 +00001666 fun_location->SetValueType(Value::eValueTypeLoadAddress);
1667 fun_location->GetScalar() = load_addr;
1668
Sean Callanan8c127202010-08-23 23:09:38 +00001669 ClangExpressionVariable &entity(m_found_entities.VariableAtIndex(m_found_entities.CreateVariable()));
Greg Clayton8de27c72010-10-15 22:48:33 +00001670 std::string decl_name(context.m_decl_name.getAsString());
1671 entity.m_name.SetCString(decl_name.c_str());
Sean Callanan8c127202010-08-23 23:09:38 +00001672 entity.m_user_type = TypeFromUser(fun_opaque_type, fun_ast_context);;
Sean Callanan8f0dc342010-06-22 23:46:24 +00001673
Sean Callanan8c127202010-08-23 23:09:38 +00001674 entity.EnableParserVars();
1675 entity.m_parser_vars->m_named_decl = fun_decl;
1676 entity.m_parser_vars->m_llvm_value = NULL;
1677 entity.m_parser_vars->m_lldb_value = fun_location.release();
1678
Sean Callanan810f22d2010-07-16 00:09:46 +00001679 if (log)
Greg Clayton8de27c72010-10-15 22:48:33 +00001680 {
Sean Callanana0744822010-11-01 23:22:47 +00001681 std::string fun_decl_print_string;
1682 llvm::raw_string_ostream fun_decl_print_stream(fun_decl_print_string);
1683 fun_decl->print(fun_decl_print_stream);
1684 fun_decl_print_stream.flush();
1685
1686 log->Printf("Found %s function %s, returned %s", (fun ? "specific" : "generic"), decl_name.c_str(), fun_decl_print_string.c_str());
Greg Clayton8de27c72010-10-15 22:48:33 +00001687 }
Chris Lattner24943d22010-06-08 16:52:24 +00001688}
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001689
1690void
1691ClangExpressionDeclMap::AddOneType(NameSearchContext &context,
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001692 TypeFromUser &ut,
1693 bool add_method)
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001694{
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001695 clang::ASTContext *parser_ast_context = context.GetASTContext();
1696 clang::ASTContext *user_ast_context = ut.GetASTContext();
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001697
Sean Callananee8fc722010-11-19 20:20:02 +00001698 void *copied_type = GuardedCopyType(parser_ast_context, user_ast_context, ut.GetOpaqueQualType());
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001699
1700 TypeFromParser parser_type(copied_type, parser_ast_context);
1701
1702 if (add_method && ClangASTContext::IsAggregateType(copied_type))
1703 {
1704 void *args[1];
1705
1706 args[0] = ClangASTContext::GetVoidPtrType(parser_ast_context, false);
1707
1708 void *method_type = ClangASTContext::CreateFunctionType (parser_ast_context,
1709 ClangASTContext::GetBuiltInType_void(parser_ast_context),
1710 args,
1711 1,
1712 false,
1713 ClangASTContext::GetTypeQualifiers(copied_type));
Greg Clayton30449d52010-10-01 02:31:07 +00001714
Greg Clayton1d8173f2010-09-24 05:15:53 +00001715 const bool is_virtual = false;
1716 const bool is_static = false;
1717 const bool is_inline = false;
Greg Clayton30449d52010-10-01 02:31:07 +00001718 const bool is_explicit = false;
1719
Greg Clayton1d8173f2010-09-24 05:15:53 +00001720 ClangASTContext::AddMethodToCXXRecordType (parser_ast_context,
1721 copied_type,
Greg Clayton8de27c72010-10-15 22:48:33 +00001722 "$__lldb_expr",
Greg Clayton1d8173f2010-09-24 05:15:53 +00001723 method_type,
1724 lldb::eAccessPublic,
1725 is_virtual,
1726 is_static,
Greg Clayton30449d52010-10-01 02:31:07 +00001727 is_inline,
1728 is_explicit);
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001729 }
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001730
1731 context.AddTypeDecl(copied_type);
1732}
Sean Callananee8fc722010-11-19 20:20:02 +00001733
1734void *
1735ClangExpressionDeclMap::GuardedCopyType (ASTContext *dest_context,
1736 ASTContext *source_context,
1737 void *clang_type)
1738{
Sean Callananaa301c42010-12-03 01:38:59 +00001739 assert (m_parser_vars.get());
1740
1741 m_parser_vars->m_ignore_lookups = true;
Sean Callananee8fc722010-11-19 20:20:02 +00001742
1743 void *ret = ClangASTContext::CopyType (dest_context,
1744 source_context,
1745 clang_type);
1746
Sean Callananaa301c42010-12-03 01:38:59 +00001747 m_parser_vars->m_ignore_lookups = false;
Sean Callananee8fc722010-11-19 20:20:02 +00001748
1749 return ret;
1750}