blob: 0d8d09f65bf1e523c4be35cb194e710481e31910 [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
16#include "lldb/lldb-private.h"
17#include "lldb/Core/Address.h"
Sean Callanan810f22d2010-07-16 00:09:46 +000018#include "lldb/Core/Error.h"
Sean Callanan6184dfe2010-06-23 00:47:48 +000019#include "lldb/Core/Log.h"
Chris Lattner24943d22010-06-08 16:52:24 +000020#include "lldb/Core/Module.h"
21#include "lldb/Expression/ClangASTSource.h"
Sean Callanana48fe162010-08-11 03:57:18 +000022#include "lldb/Expression/ClangPersistentVariables.h"
Chris Lattner24943d22010-06-08 16:52:24 +000023#include "lldb/Symbol/ClangASTContext.h"
24#include "lldb/Symbol/CompileUnit.h"
25#include "lldb/Symbol/Function.h"
26#include "lldb/Symbol/ObjectFile.h"
27#include "lldb/Symbol/SymbolContext.h"
28#include "lldb/Symbol/Type.h"
29#include "lldb/Symbol/TypeList.h"
30#include "lldb/Symbol/Variable.h"
31#include "lldb/Symbol/VariableList.h"
Sean Callananf328c9f2010-07-20 23:31:16 +000032#include "lldb/Target/ExecutionContext.h"
Sean Callanan810f22d2010-07-16 00:09:46 +000033#include "lldb/Target/Process.h"
Chris Lattner24943d22010-06-08 16:52:24 +000034#include "lldb/Target/StackFrame.h"
Sean Callananf328c9f2010-07-20 23:31:16 +000035#include "lldb/Target/Target.h"
Chris Lattner24943d22010-06-08 16:52:24 +000036
Chris Lattner24943d22010-06-08 16:52:24 +000037using namespace lldb_private;
38using namespace clang;
39
Sean Callanana48fe162010-08-11 03:57:18 +000040ClangExpressionDeclMap::ClangExpressionDeclMap(ExecutionContext *exe_ctx) :
41 m_exe_ctx(exe_ctx), m_struct_laid_out(false),
Sean Callanan810f22d2010-07-16 00:09:46 +000042 m_materialized_location(0)
Chris Lattner24943d22010-06-08 16:52:24 +000043{
44 if (exe_ctx && exe_ctx->frame)
45 m_sym_ctx = new SymbolContext(exe_ctx->frame->GetSymbolContext(lldb::eSymbolContextEverything));
46 else
47 m_sym_ctx = NULL;
Sean Callanana48fe162010-08-11 03:57:18 +000048
49 if (exe_ctx && exe_ctx->process)
50 m_persistent_vars = &exe_ctx->process->GetPersistentVariables();
Chris Lattner24943d22010-06-08 16:52:24 +000051}
52
53ClangExpressionDeclMap::~ClangExpressionDeclMap()
Sean Callanan8c127202010-08-23 23:09:38 +000054{
55 for (uint64_t entity_index = 0, num_entities = m_found_entities.Size();
56 entity_index < num_entities;
57 ++entity_index)
58 {
59 ClangExpressionVariable &entity(m_found_entities.VariableAtIndex(entity_index));
60 if (entity.m_parser_vars.get() &&
61 entity.m_parser_vars->m_lldb_value)
62 delete entity.m_parser_vars->m_lldb_value;
63 }
Chris Lattner24943d22010-06-08 16:52:24 +000064
65 if (m_sym_ctx)
66 delete m_sym_ctx;
67}
68
Sean Callanan8bce6652010-07-13 21:41:46 +000069// Interface for IRForTarget
70
Sean Callanan82b74c82010-08-12 01:56:52 +000071void
72ClangExpressionDeclMap::GetPersistentResultName (std::string &name)
73{
74 m_persistent_vars->GetNextResultName(m_result_name);
75
76 name = m_result_name;
77}
78
Sean Callanan8bce6652010-07-13 21:41:46 +000079bool
Sean Callanan8c127202010-08-23 23:09:38 +000080ClangExpressionDeclMap::AddPersistentVariable (const clang::NamedDecl *decl,
81 const char *name,
82 TypeFromParser parser_type)
Sean Callanana48fe162010-08-11 03:57:18 +000083{
84 clang::ASTContext *context(m_exe_ctx->target->GetScratchClangASTContext()->getASTContext());
85
Sean Callanana48fe162010-08-11 03:57:18 +000086 TypeFromUser user_type(ClangASTContext::CopyType(context,
Sean Callanan82b74c82010-08-12 01:56:52 +000087 parser_type.GetASTContext(),
88 parser_type.GetOpaqueQualType()),
Sean Callanana48fe162010-08-11 03:57:18 +000089 context);
90
Sean Callanan8c127202010-08-23 23:09:38 +000091 if (!m_persistent_vars->CreatePersistentVariable (name, user_type))
92 return false;
93
94 ClangExpressionVariable *var = m_persistent_vars->GetVariable(name);
95
96 if (!var)
97 return false;
98
99 var->EnableParserVars();
100
101 var->m_parser_vars->m_named_decl = decl;
102 var->m_parser_vars->m_parser_type = parser_type;
103
104 return true;
Sean Callanana48fe162010-08-11 03:57:18 +0000105}
106
107bool
Sean Callanan8c127202010-08-23 23:09:38 +0000108ClangExpressionDeclMap::AddValueToStruct (const clang::NamedDecl *decl,
109 llvm::Value *value,
Sean Callanan8bce6652010-07-13 21:41:46 +0000110 size_t size,
111 off_t alignment)
112{
113 m_struct_laid_out = false;
114
Sean Callanan8c127202010-08-23 23:09:38 +0000115 if (m_struct_members.GetVariable(decl))
116 return true;
Sean Callanan8bce6652010-07-13 21:41:46 +0000117
Sean Callanan8c127202010-08-23 23:09:38 +0000118 ClangExpressionVariable *var = m_found_entities.GetVariable(decl);
Sean Callanan8bce6652010-07-13 21:41:46 +0000119
Sean Callanan8c127202010-08-23 23:09:38 +0000120 if (!var)
121 var = m_persistent_vars->GetVariable(decl);
Sean Callanan8bce6652010-07-13 21:41:46 +0000122
Sean Callanan8c127202010-08-23 23:09:38 +0000123 if (!var)
124 return false;
125
126 // We know entity->m_parser_vars is valid because we used a parser variable
127 // to find it
128 var->m_parser_vars->m_llvm_value = value;
129
130 var->EnableJITVars();
131 var->m_jit_vars->m_alignment = alignment;
132 var->m_jit_vars->m_size = size;
133
134 m_struct_members.AddVariable(*var);
Sean Callanan8bce6652010-07-13 21:41:46 +0000135
136 return true;
137}
138
139bool
140ClangExpressionDeclMap::DoStructLayout ()
141{
142 if (m_struct_laid_out)
143 return true;
144
Sean Callanan8bce6652010-07-13 21:41:46 +0000145 off_t cursor = 0;
146
147 m_struct_alignment = 0;
148 m_struct_size = 0;
149
Sean Callanan8c127202010-08-23 23:09:38 +0000150 for (uint64_t member_index = 0, num_members = m_struct_members.Size();
151 member_index < num_members;
152 ++member_index)
Sean Callanan8bce6652010-07-13 21:41:46 +0000153 {
Sean Callanan8c127202010-08-23 23:09:38 +0000154 ClangExpressionVariable &member(m_struct_members.VariableAtIndex(member_index));
Sean Callanan8bce6652010-07-13 21:41:46 +0000155
Sean Callanan8c127202010-08-23 23:09:38 +0000156 if (!member.m_jit_vars.get())
157 return false;
Sean Callanan8bce6652010-07-13 21:41:46 +0000158
Sean Callanan8c127202010-08-23 23:09:38 +0000159 if (member_index == 0)
160 m_struct_alignment = member.m_jit_vars->m_alignment;
161
162 if (cursor % member.m_jit_vars->m_alignment)
163 cursor += (member.m_jit_vars->m_alignment - (cursor % member.m_jit_vars->m_alignment));
164
165 member.m_jit_vars->m_offset = cursor;
166 cursor += member.m_jit_vars->m_size;
Sean Callanan8bce6652010-07-13 21:41:46 +0000167 }
168
169 m_struct_size = cursor;
170
171 m_struct_laid_out = true;
172 return true;
173}
174
175bool ClangExpressionDeclMap::GetStructInfo (uint32_t &num_elements,
176 size_t &size,
177 off_t &alignment)
178{
179 if (!m_struct_laid_out)
180 return false;
181
Sean Callanan8c127202010-08-23 23:09:38 +0000182 num_elements = m_struct_members.Size();
Sean Callanan8bce6652010-07-13 21:41:46 +0000183 size = m_struct_size;
184 alignment = m_struct_alignment;
185
186 return true;
187}
188
189bool
190ClangExpressionDeclMap::GetStructElement (const clang::NamedDecl *&decl,
191 llvm::Value *&value,
192 off_t &offset,
193 uint32_t index)
194{
195 if (!m_struct_laid_out)
196 return false;
197
Sean Callanan8c127202010-08-23 23:09:38 +0000198 if (index >= m_struct_members.Size())
Sean Callanan8bce6652010-07-13 21:41:46 +0000199 return false;
200
Sean Callanan8c127202010-08-23 23:09:38 +0000201 ClangExpressionVariable &member(m_struct_members.VariableAtIndex(index));
Sean Callanan8bce6652010-07-13 21:41:46 +0000202
Sean Callanan8c127202010-08-23 23:09:38 +0000203 if (!member.m_parser_vars.get() ||
204 !member.m_jit_vars.get())
205 return false;
206
207 decl = member.m_parser_vars->m_named_decl;
208 value = member.m_parser_vars->m_llvm_value;
209 offset = member.m_jit_vars->m_offset;
210
Sean Callanan8bce6652010-07-13 21:41:46 +0000211 return true;
212}
213
Sean Callanan02fbafa2010-07-27 21:39:39 +0000214bool
215ClangExpressionDeclMap::GetFunctionInfo (const clang::NamedDecl *decl,
216 llvm::Value**& value,
217 uint64_t &ptr)
Sean Callananba992c52010-07-27 02:07:53 +0000218{
Sean Callanan8c127202010-08-23 23:09:38 +0000219 ClangExpressionVariable *entity = m_found_entities.GetVariable(decl);
220
221 if (!entity)
222 return false;
Sean Callananba992c52010-07-27 02:07:53 +0000223
Sean Callanan8c127202010-08-23 23:09:38 +0000224 // We know m_parser_vars is valid since we searched for the variable by
225 // its NamedDecl
Sean Callananba992c52010-07-27 02:07:53 +0000226
Sean Callanan8c127202010-08-23 23:09:38 +0000227 value = &entity->m_parser_vars->m_llvm_value;
228 ptr = entity->m_parser_vars->m_lldb_value->GetScalar().ULongLong();
229
230 return true;
Sean Callananba992c52010-07-27 02:07:53 +0000231}
232
Sean Callananf5857a02010-07-31 01:32:05 +0000233bool
234ClangExpressionDeclMap::GetFunctionAddress (const char *name,
235 uint64_t &ptr)
236{
237 // Back out in all cases where we're not fully initialized
238 if (!m_exe_ctx || !m_exe_ctx->frame || !m_sym_ctx)
239 return false;
240
241 ConstString name_cs(name);
242 SymbolContextList sym_ctxs;
243
244 m_sym_ctx->FindFunctionsByName(name_cs, false, sym_ctxs);
245
246 if (!sym_ctxs.GetSize())
247 return false;
248
249 SymbolContext sym_ctx;
250 sym_ctxs.GetContextAtIndex(0, sym_ctx);
251
252 const Address *fun_address;
253
254 if (sym_ctx.function)
255 fun_address = &sym_ctx.function->GetAddressRange().GetBaseAddress();
256 else if (sym_ctx.symbol)
257 fun_address = &sym_ctx.symbol->GetAddressRangeRef().GetBaseAddress();
258 else
259 return false;
260
261 ptr = fun_address->GetLoadAddress(m_exe_ctx->process);
262
263 return true;
264}
265
Sean Callanan810f22d2010-07-16 00:09:46 +0000266// Interface for CommandObjectExpression
Sean Callananf328c9f2010-07-20 23:31:16 +0000267
268bool
269ClangExpressionDeclMap::Materialize (ExecutionContext *exe_ctx,
270 lldb::addr_t &struct_address,
271 Error &err)
272{
273 bool result = DoMaterialize(false, exe_ctx, NULL, err);
274
275 if (result)
276 struct_address = m_materialized_location;
277
278 return result;
279}
280
281bool
282ClangExpressionDeclMap::Dematerialize (ExecutionContext *exe_ctx,
Sean Callanana6223432010-08-20 01:02:30 +0000283 ClangExpressionVariable *&result,
Sean Callananf328c9f2010-07-20 23:31:16 +0000284 Error &err)
285{
Sean Callanan82b74c82010-08-12 01:56:52 +0000286 return DoMaterialize(true, exe_ctx, &result, err);
Sean Callananf328c9f2010-07-20 23:31:16 +0000287}
288
Sean Callanan32824aa2010-07-23 22:19:18 +0000289bool
290ClangExpressionDeclMap::DumpMaterializedStruct(ExecutionContext *exe_ctx,
291 Stream &s,
292 Error &err)
293{
294 if (!m_struct_laid_out)
295 {
296 err.SetErrorString("Structure hasn't been laid out yet");
297 return false;
298 }
299
300 if (!exe_ctx)
301 {
302 err.SetErrorString("Received null execution context");
303 return false;
304 }
305
306
307 if (!exe_ctx->process)
308 {
309 err.SetErrorString("Couldn't find the process");
310 return false;
311 }
312
313 if (!exe_ctx->target)
314 {
315 err.SetErrorString("Couldn't find the target");
316 return false;
317 }
318
319 lldb::DataBufferSP data(new DataBufferHeap(m_struct_size, 0));
320
321 Error error;
322 if (exe_ctx->process->ReadMemory (m_materialized_location, data->GetBytes(), data->GetByteSize(), error) != data->GetByteSize())
323 {
324 err.SetErrorStringWithFormat ("Couldn't read struct from the target: %s", error.AsCString());
325 return false;
326 }
327
328 DataExtractor extractor(data, exe_ctx->process->GetByteOrder(), exe_ctx->target->GetArchitecture().GetAddressByteSize());
329
Sean Callanan8c127202010-08-23 23:09:38 +0000330 for (uint64_t member_index = 0, num_members = m_struct_members.Size();
331 member_index < num_members;
332 ++member_index)
Sean Callanan32824aa2010-07-23 22:19:18 +0000333 {
Sean Callanan8c127202010-08-23 23:09:38 +0000334 ClangExpressionVariable &member (m_struct_members.VariableAtIndex(member_index));
Sean Callanan32824aa2010-07-23 22:19:18 +0000335
Sean Callanan8c127202010-08-23 23:09:38 +0000336 s.Printf("[%s]\n", member.m_name.c_str());
337
338 if (!member.m_jit_vars.get())
339 return false;
340
341 extractor.Dump(&s, // stream
342 member.m_jit_vars->m_offset, // offset
343 lldb::eFormatBytesWithASCII, // format
344 1, // byte size of individual entries
345 member.m_jit_vars->m_size, // number of entries
346 16, // entries per line
347 m_materialized_location + member.m_jit_vars->m_offset, // address to print
348 0, // bit size (bitfields only; 0 means ignore)
349 0); // bit alignment (bitfields only; 0 means ignore)
Sean Callanan32824aa2010-07-23 22:19:18 +0000350
351 s.PutChar('\n');
352 }
353
354 return true;
355}
356
Sean Callananf328c9f2010-07-20 23:31:16 +0000357bool
358ClangExpressionDeclMap::DoMaterialize (bool dematerialize,
359 ExecutionContext *exe_ctx,
Sean Callanana6223432010-08-20 01:02:30 +0000360 ClangExpressionVariable **result,
Sean Callananf328c9f2010-07-20 23:31:16 +0000361 Error &err)
Sean Callanan810f22d2010-07-16 00:09:46 +0000362{
Sean Callanan336a0002010-07-17 00:43:37 +0000363 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
Sean Callanan82b74c82010-08-12 01:56:52 +0000364
Sean Callanan810f22d2010-07-16 00:09:46 +0000365 if (!m_struct_laid_out)
366 {
367 err.SetErrorString("Structure hasn't been laid out yet");
368 return LLDB_INVALID_ADDRESS;
369 }
370
Sean Callanan810f22d2010-07-16 00:09:46 +0000371 if (!exe_ctx)
372 {
373 err.SetErrorString("Received null execution context");
374 return LLDB_INVALID_ADDRESS;
375 }
376
Sean Callanan45839272010-07-24 01:37:44 +0000377 if (!exe_ctx->frame)
378 {
379 err.SetErrorString("Received null execution frame");
380 return LLDB_INVALID_ADDRESS;
381 }
382
Sean Callanan810f22d2010-07-16 00:09:46 +0000383 const SymbolContext &sym_ctx(exe_ctx->frame->GetSymbolContext(lldb::eSymbolContextEverything));
384
Sean Callananf328c9f2010-07-20 23:31:16 +0000385 if (!dematerialize)
Sean Callanan810f22d2010-07-16 00:09:46 +0000386 {
Sean Callananf328c9f2010-07-20 23:31:16 +0000387 if (m_materialized_location)
388 {
389 exe_ctx->process->DeallocateMemory(m_materialized_location);
390 m_materialized_location = 0;
391 }
392
393 lldb::addr_t mem = exe_ctx->process->AllocateMemory(m_struct_alignment + m_struct_size,
394 lldb::ePermissionsReadable | lldb::ePermissionsWritable,
395 err);
396
397 if (mem == LLDB_INVALID_ADDRESS)
398 return false;
399
400 m_allocated_area = mem;
Sean Callanan810f22d2010-07-16 00:09:46 +0000401 }
402
Sean Callananf328c9f2010-07-20 23:31:16 +0000403 m_materialized_location = m_allocated_area;
404
405 if (m_materialized_location % m_struct_alignment)
Sean Callananf328c9f2010-07-20 23:31:16 +0000406 m_materialized_location += (m_struct_alignment - (m_materialized_location % m_struct_alignment));
Sean Callananf328c9f2010-07-20 23:31:16 +0000407
Sean Callanan8c127202010-08-23 23:09:38 +0000408 for (uint64_t member_index = 0, num_members = m_struct_members.Size();
409 member_index < num_members;
410 ++member_index)
Sean Callanan810f22d2010-07-16 00:09:46 +0000411 {
Sean Callanan8c127202010-08-23 23:09:38 +0000412 ClangExpressionVariable &member (m_struct_members.VariableAtIndex(member_index));
Sean Callanan810f22d2010-07-16 00:09:46 +0000413
Sean Callanan8c127202010-08-23 23:09:38 +0000414 if (!member.m_parser_vars.get())
Sean Callanan336a0002010-07-17 00:43:37 +0000415 return false;
Sean Callanan8c127202010-08-23 23:09:38 +0000416
417 ClangExpressionVariable *entity = m_found_entities.GetVariable(member.m_parser_vars->m_named_decl);
418 ClangExpressionVariable *persistent_variable = m_persistent_vars->GetVariable(member.m_name.c_str());
419
420 if (entity)
421 {
422 if (!member.m_jit_vars.get())
423 return false;
424
425 if (!DoMaterializeOneVariable(dematerialize, *exe_ctx, sym_ctx, member.m_name.c_str(), member.m_user_type, m_materialized_location + member.m_jit_vars->m_offset, err))
426 return false;
427 }
428 else if (persistent_variable)
429 {
430 if (!member.m_name.compare(m_result_name) && !dematerialize)
431 continue;
432
433 if (dematerialize)
434 {
435 if (log)
436 log->PutCString("Found result member in the struct");
437
438 *result = &member;
439 }
440
441 if (!DoMaterializeOnePersistentVariable(dematerialize, *exe_ctx, persistent_variable->m_name.c_str(), m_materialized_location + member.m_jit_vars->m_offset, err))
442 return false;
443 }
444 else
445 {
446 err.SetErrorStringWithFormat("Unexpected variable %s", member.m_name.c_str());
447 return false;
448 }
Sean Callanan810f22d2010-07-16 00:09:46 +0000449 }
450
Sean Callananf328c9f2010-07-20 23:31:16 +0000451 return true;
452}
453
Sean Callanana48fe162010-08-11 03:57:18 +0000454bool
455ClangExpressionDeclMap::DoMaterializeOnePersistentVariable(bool dematerialize,
456 ExecutionContext &exe_ctx,
457 const char *name,
458 lldb::addr_t addr,
459 Error &err)
460{
461 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
462
463 if (log)
464 log->Printf("Found persistent variable %s", name);
465
Sean Callanana6223432010-08-20 01:02:30 +0000466 ClangExpressionVariable *pvar(m_persistent_vars->GetVariable(name));
Sean Callanana48fe162010-08-11 03:57:18 +0000467
468 if (!pvar)
469 {
470 err.SetErrorStringWithFormat("Undefined persistent variable %s", name);
471 return LLDB_INVALID_ADDRESS;
472 }
473
474 size_t pvar_size = pvar->Size();
Sean Callanana6223432010-08-20 01:02:30 +0000475
476 if (!pvar->m_data_vars.get())
477 return false;
478
479 uint8_t *pvar_data = pvar->m_data_vars->m_data->GetBytes();
Sean Callanana48fe162010-08-11 03:57:18 +0000480 Error error;
481
482 if (dematerialize)
483 {
484 if (exe_ctx.process->ReadMemory (addr, pvar_data, pvar_size, error) != pvar_size)
485 {
486 err.SetErrorStringWithFormat ("Couldn't read a composite type from the target: %s", error.AsCString());
487 return false;
488 }
489 }
490 else
491 {
492 if (exe_ctx.process->WriteMemory (addr, pvar_data, pvar_size, error) != pvar_size)
493 {
494 err.SetErrorStringWithFormat ("Couldn't write a composite type to the target: %s", error.AsCString());
495 return false;
496 }
497 }
498
499 return true;
500}
501
Sean Callananf328c9f2010-07-20 23:31:16 +0000502bool
503ClangExpressionDeclMap::DoMaterializeOneVariable(bool dematerialize,
504 ExecutionContext &exe_ctx,
505 const SymbolContext &sym_ctx,
506 const char *name,
507 TypeFromUser type,
508 lldb::addr_t addr,
509 Error &err)
510{
511 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
512
513 Variable *var = FindVariableInScope(sym_ctx, name, &type);
514
515 if (!var)
516 {
517 err.SetErrorStringWithFormat("Couldn't find %s with appropriate type", name);
518 return false;
519 }
520
Sean Callanan841026f2010-07-23 00:16:21 +0000521 if (log)
522 log->Printf("%s %s with type %p", (dematerialize ? "Dematerializing" : "Materializing"), name, type.GetOpaqueQualType());
Sean Callananf328c9f2010-07-20 23:31:16 +0000523
524 std::auto_ptr<lldb_private::Value> location_value(GetVariableValue(exe_ctx,
525 var,
526 type.GetASTContext()));
527
528 if (!location_value.get())
529 {
530 err.SetErrorStringWithFormat("Couldn't get value for %s", name);
531 return false;
532 }
533
534 if (location_value->GetValueType() == Value::eValueTypeLoadAddress)
535 {
536 lldb::addr_t value_addr = location_value->GetScalar().ULongLong();
537
Greg Clayton960d6a42010-08-03 00:35:52 +0000538 size_t bit_size = ClangASTType::GetClangTypeBitWidth(type.GetASTContext(), type.GetOpaqueQualType());
Sean Callananf328c9f2010-07-20 23:31:16 +0000539 size_t byte_size = bit_size % 8 ? ((bit_size + 8) / 8) : (bit_size / 8);
540
541 DataBufferHeap data;
542 data.SetByteSize(byte_size);
543
544 lldb::addr_t src_addr;
545 lldb::addr_t dest_addr;
546
547 if (dematerialize)
548 {
549 src_addr = addr;
550 dest_addr = value_addr;
551 }
552 else
553 {
554 src_addr = value_addr;
555 dest_addr = addr;
556 }
557
558 Error error;
559 if (exe_ctx.process->ReadMemory (src_addr, data.GetBytes(), byte_size, error) != byte_size)
560 {
561 err.SetErrorStringWithFormat ("Couldn't read a composite type from the target: %s", error.AsCString());
562 return false;
563 }
564
565 if (exe_ctx.process->WriteMemory (dest_addr, data.GetBytes(), byte_size, error) != byte_size)
566 {
567 err.SetErrorStringWithFormat ("Couldn't write a composite type to the target: %s", error.AsCString());
568 return false;
569 }
570
571 if (log)
572 log->Printf("Copied from 0x%llx to 0x%llx", (uint64_t)src_addr, (uint64_t)addr);
573 }
574 else
575 {
576 StreamString ss;
577
578 location_value->Dump(&ss);
579
580 err.SetErrorStringWithFormat("%s has a value of unhandled type: %s", name, ss.GetString().c_str());
581 }
582
583 return true;
Sean Callanan810f22d2010-07-16 00:09:46 +0000584}
585
Sean Callanan336a0002010-07-17 00:43:37 +0000586Variable*
587ClangExpressionDeclMap::FindVariableInScope(const SymbolContext &sym_ctx,
588 const char *name,
Sean Callananf328c9f2010-07-20 23:31:16 +0000589 TypeFromUser *type)
Sean Callanan810f22d2010-07-16 00:09:46 +0000590{
591 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
592
Greg Clayton75ccf502010-08-21 02:22:51 +0000593 if (m_sym_ctx->function == NULL || m_sym_ctx->block == NULL)
Sean Callanan810f22d2010-07-16 00:09:46 +0000594 {
595 if (log)
Greg Clayton75ccf502010-08-21 02:22:51 +0000596 log->Printf("function = %p, block = %p", m_sym_ctx->function, m_sym_ctx->block);
Sean Callanan336a0002010-07-17 00:43:37 +0000597 return NULL;
Sean Callanan810f22d2010-07-16 00:09:46 +0000598 }
599
Sean Callanan336a0002010-07-17 00:43:37 +0000600 ConstString name_cs(name);
601
Greg Clayton75ccf502010-08-21 02:22:51 +0000602 Block *current_block;
Sean Callanan810f22d2010-07-16 00:09:46 +0000603
Greg Clayton75ccf502010-08-21 02:22:51 +0000604 for (current_block = m_sym_ctx->block;
605 current_block != NULL;
606 current_block = current_block->GetParent())
607 {
Sean Callanan810f22d2010-07-16 00:09:46 +0000608 lldb::VariableListSP var_list = current_block->GetVariableList(false, true);
609
610 if (!var_list)
611 continue;
612
Sean Callanan336a0002010-07-17 00:43:37 +0000613 lldb::VariableSP var = var_list->FindVariable(name_cs);
Sean Callanan810f22d2010-07-16 00:09:46 +0000614
615 if (!var)
616 continue;
617
618 // var->GetType()->GetClangAST() is the program's AST context and holds
619 // var->GetType()->GetOpaqueClangQualType().
620
621 // type is m_type for one of the struct members, which was added by
622 // AddValueToStruct. That type was extracted from the AST context of
623 // the compiler in IRForTarget. The original for the type was copied
624 // out of the program's AST context by AddOneVariable.
625
Sean Callanan336a0002010-07-17 00:43:37 +0000626 // So that we can compare these two without having to copy back
627 // something we already had in the original AST context, we maintain
628 // m_orig_type and m_ast_context (which are passed into
629 // MaterializeOneVariable by Materialize) for each variable.
630
631 if (!type)
632 return var.get();
Sean Callanan810f22d2010-07-16 00:09:46 +0000633
Sean Callananf328c9f2010-07-20 23:31:16 +0000634 if (type->GetASTContext() == var->GetType()->GetClangAST())
Sean Callanan810f22d2010-07-16 00:09:46 +0000635 {
Sean Callananf5857a02010-07-31 01:32:05 +0000636 if (!ClangASTContext::AreTypesSame(type->GetASTContext(), type->GetOpaqueQualType(), var->GetType()->GetOpaqueClangQualType()))
Sean Callanan810f22d2010-07-16 00:09:46 +0000637 continue;
638 }
639 else
640 {
641 if (log)
642 log->PutCString("Skipping a candidate variable because of different AST contexts");
643 continue;
644 }
645
Sean Callanan336a0002010-07-17 00:43:37 +0000646 return var.get();
647 }
648
649 {
650 CompileUnit *compile_unit = m_sym_ctx->comp_unit;
Sean Callanan810f22d2010-07-16 00:09:46 +0000651
Sean Callanan336a0002010-07-17 00:43:37 +0000652 if (!compile_unit)
653 {
654 if (log)
655 log->Printf("compile_unit = %p", compile_unit);
656 return NULL;
657 }
658
659 lldb::VariableListSP var_list = compile_unit->GetVariableList(true);
660
661 if (!var_list)
662 return NULL;
663
664 lldb::VariableSP var = var_list->FindVariable(name_cs);
665
666 if (!var)
667 return NULL;
668
669 if (!type)
670 return var.get();
671
Sean Callananf328c9f2010-07-20 23:31:16 +0000672 if (type->GetASTContext() == var->GetType()->GetClangAST())
Sean Callanan336a0002010-07-17 00:43:37 +0000673 {
Sean Callanan841026f2010-07-23 00:16:21 +0000674 if (!ClangASTContext::AreTypesSame(type->GetASTContext(), type->GetOpaqueQualType(), var->GetType()->GetOpaqueClangQualType()))
Sean Callanan336a0002010-07-17 00:43:37 +0000675 return NULL;
676 }
677 else
678 {
679 if (log)
680 log->PutCString("Skipping a candidate variable because of different AST contexts");
681 return NULL;
682 }
683
684 return var.get();
685 }
686
687 return NULL;
688}
689
Chris Lattner24943d22010-06-08 16:52:24 +0000690// Interface for ClangASTSource
691void
692ClangExpressionDeclMap::GetDecls(NameSearchContext &context,
693 const char *name)
694{
Sean Callanan6184dfe2010-06-23 00:47:48 +0000695 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
696
Sean Callanan810f22d2010-07-16 00:09:46 +0000697 if (log)
698 log->Printf("Hunting for a definition for %s", name);
Chris Lattner24943d22010-06-08 16:52:24 +0000699
700 // Back out in all cases where we're not fully initialized
701 if (!m_exe_ctx || !m_exe_ctx->frame || !m_sym_ctx)
702 return;
703
704 Function *function = m_sym_ctx->function;
Chris Lattner24943d22010-06-08 16:52:24 +0000705
Sean Callanan336a0002010-07-17 00:43:37 +0000706 if (!function)
Chris Lattner24943d22010-06-08 16:52:24 +0000707 {
Sean Callanan810f22d2010-07-16 00:09:46 +0000708 if (log)
Sean Callanan336a0002010-07-17 00:43:37 +0000709 log->Printf("Can't evaluate an expression when not in a function");
Chris Lattner24943d22010-06-08 16:52:24 +0000710 return;
711 }
712
Chris Lattner24943d22010-06-08 16:52:24 +0000713 ConstString name_cs(name);
Sean Callanan0fc73582010-07-27 00:55:47 +0000714 SymbolContextList sym_ctxs;
Chris Lattner24943d22010-06-08 16:52:24 +0000715
Sean Callanan0fc73582010-07-27 00:55:47 +0000716 m_sym_ctx->FindFunctionsByName(name_cs, false, sym_ctxs);
Sean Callanan8f0dc342010-06-22 23:46:24 +0000717
Sean Callanan0fc73582010-07-27 00:55:47 +0000718 for (uint32_t index = 0, num_indices = sym_ctxs.GetSize();
719 index < num_indices;
720 ++index)
721 {
722 SymbolContext sym_ctx;
723 sym_ctxs.GetContextAtIndex(index, sym_ctx);
724
725 if (sym_ctx.function)
726 AddOneFunction(context, sym_ctx.function, NULL);
727 else if(sym_ctx.symbol)
728 AddOneFunction(context, NULL, sym_ctx.symbol);
729 }
730
Sean Callanan336a0002010-07-17 00:43:37 +0000731 Variable *var = FindVariableInScope(*m_sym_ctx, name);
732
733 if (var)
734 AddOneVariable(context, var);
Sean Callanan93a4b1a2010-08-04 01:02:13 +0000735
Sean Callanana6223432010-08-20 01:02:30 +0000736 ClangExpressionVariable *pvar(m_persistent_vars->GetVariable(name));
Sean Callanana48fe162010-08-11 03:57:18 +0000737
738 if (pvar)
739 AddOneVariable(context, pvar);
740
Sean Callanan93a4b1a2010-08-04 01:02:13 +0000741 /* Commented out pending resolution of a loop when the TagType is imported
742 lldb::TypeSP type = m_sym_ctx->FindTypeByName(name_cs);
743
744 if (type.get())
745 AddOneType(context, type.get());
746 */
Sean Callanan336a0002010-07-17 00:43:37 +0000747}
748
749Value *
750ClangExpressionDeclMap::GetVariableValue(ExecutionContext &exe_ctx,
751 Variable *var,
Sean Callananf328c9f2010-07-20 23:31:16 +0000752 clang::ASTContext *parser_ast_context,
753 TypeFromUser *user_type,
754 TypeFromParser *parser_type)
Chris Lattner24943d22010-06-08 16:52:24 +0000755{
Sean Callanan6184dfe2010-06-23 00:47:48 +0000756 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
757
Chris Lattner24943d22010-06-08 16:52:24 +0000758 Type *var_type = var->GetType();
759
760 if (!var_type)
761 {
Sean Callanan810f22d2010-07-16 00:09:46 +0000762 if (log)
763 log->PutCString("Skipped a definition because it has no type");
Sean Callanan336a0002010-07-17 00:43:37 +0000764 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000765 }
766
767 void *var_opaque_type = var_type->GetOpaqueClangQualType();
768
769 if (!var_opaque_type)
770 {
Sean Callanan810f22d2010-07-16 00:09:46 +0000771 if (log)
772 log->PutCString("Skipped a definition because it has no Clang type");
Sean Callanan336a0002010-07-17 00:43:37 +0000773 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000774 }
775
Chris Lattner24943d22010-06-08 16:52:24 +0000776 TypeList *type_list = var_type->GetTypeList();
777
778 if (!type_list)
779 {
Sean Callanan810f22d2010-07-16 00:09:46 +0000780 if (log)
781 log->PutCString("Skipped a definition because the type has no associated type list");
Sean Callanan336a0002010-07-17 00:43:37 +0000782 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000783 }
784
785 clang::ASTContext *exe_ast_ctx = type_list->GetClangASTContext().getASTContext();
786
787 if (!exe_ast_ctx)
788 {
Sean Callanan810f22d2010-07-16 00:09:46 +0000789 if (log)
790 log->PutCString("There is no AST context for the current execution context");
Sean Callanan336a0002010-07-17 00:43:37 +0000791 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000792 }
793
Sean Callanan336a0002010-07-17 00:43:37 +0000794 DWARFExpression &var_location_expr = var->LocationExpression();
795
Chris Lattner24943d22010-06-08 16:52:24 +0000796 std::auto_ptr<Value> var_location(new Value);
797
798 Error err;
799
Sean Callanan336a0002010-07-17 00:43:37 +0000800 if (!var_location_expr.Evaluate(&exe_ctx, exe_ast_ctx, NULL, *var_location.get(), &err))
Chris Lattner24943d22010-06-08 16:52:24 +0000801 {
Sean Callanan810f22d2010-07-16 00:09:46 +0000802 if (log)
803 log->Printf("Error evaluating location: %s", err.AsCString());
Sean Callanan336a0002010-07-17 00:43:37 +0000804 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000805 }
806
Sean Callanan810f22d2010-07-16 00:09:46 +0000807 clang::ASTContext *var_ast_context = type_list->GetClangASTContext().getASTContext();
808
Sean Callanan336a0002010-07-17 00:43:37 +0000809 void *type_to_use;
810
Sean Callananf328c9f2010-07-20 23:31:16 +0000811 if (parser_ast_context)
812 {
813 type_to_use = ClangASTContext::CopyType(parser_ast_context, var_ast_context, var_opaque_type);
814
815 if (parser_type)
816 *parser_type = TypeFromParser(type_to_use, parser_ast_context);
817 }
Sean Callanan336a0002010-07-17 00:43:37 +0000818 else
819 type_to_use = var_opaque_type;
Chris Lattner24943d22010-06-08 16:52:24 +0000820
821 if (var_location.get()->GetContextType() == Value::eContextTypeInvalid)
Sean Callanan336a0002010-07-17 00:43:37 +0000822 var_location.get()->SetContext(Value::eContextTypeOpaqueClangQualType, type_to_use);
Chris Lattner24943d22010-06-08 16:52:24 +0000823
824 if (var_location.get()->GetValueType() == Value::eValueTypeFileAddress)
825 {
826 SymbolContext var_sc;
827 var->CalculateSymbolContext(&var_sc);
Sean Callanan336a0002010-07-17 00:43:37 +0000828
Chris Lattner24943d22010-06-08 16:52:24 +0000829 if (!var_sc.module_sp)
Sean Callanan336a0002010-07-17 00:43:37 +0000830 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000831
832 ObjectFile *object_file = var_sc.module_sp->GetObjectFile();
833
834 if (!object_file)
Sean Callanan336a0002010-07-17 00:43:37 +0000835 return NULL;
836
Chris Lattner24943d22010-06-08 16:52:24 +0000837 Address so_addr(var_location->GetScalar().ULongLong(), object_file->GetSectionList());
838
839 lldb::addr_t load_addr = so_addr.GetLoadAddress(m_exe_ctx->process);
840
841 var_location->GetScalar() = load_addr;
842 var_location->SetValueType(Value::eValueTypeLoadAddress);
843 }
844
Sean Callananf328c9f2010-07-20 23:31:16 +0000845 if (user_type)
846 *user_type = TypeFromUser(var_opaque_type, var_ast_context);
Sean Callanan336a0002010-07-17 00:43:37 +0000847
848 return var_location.release();
849}
850
851void
852ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
853 Variable* var)
854{
855 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
856
Sean Callananf328c9f2010-07-20 23:31:16 +0000857 TypeFromUser ut;
858 TypeFromParser pt;
Sean Callanan336a0002010-07-17 00:43:37 +0000859
860 Value *var_location = GetVariableValue(*m_exe_ctx,
861 var,
862 context.GetASTContext(),
Sean Callananf328c9f2010-07-20 23:31:16 +0000863 &ut,
864 &pt);
Sean Callanan336a0002010-07-17 00:43:37 +0000865
Greg Clayton1674b122010-07-21 22:12:05 +0000866 NamedDecl *var_decl = context.AddVarDecl(pt.GetOpaqueQualType());
Chris Lattner24943d22010-06-08 16:52:24 +0000867
Sean Callanan8c127202010-08-23 23:09:38 +0000868 ClangExpressionVariable &entity(m_found_entities.VariableAtIndex(m_found_entities.CreateVariable()));
869 entity.m_name = context.Name.getAsString();
870 entity.m_user_type = ut;
Chris Lattner24943d22010-06-08 16:52:24 +0000871
Sean Callanan8c127202010-08-23 23:09:38 +0000872 entity.EnableParserVars();
873 entity.m_parser_vars->m_parser_type = pt;
874 entity.m_parser_vars->m_named_decl = var_decl;
875 entity.m_parser_vars->m_llvm_value = NULL;
876 entity.m_parser_vars->m_lldb_value = var_location;
Chris Lattner24943d22010-06-08 16:52:24 +0000877
Sean Callanan810f22d2010-07-16 00:09:46 +0000878 if (log)
Sean Callananf5857a02010-07-31 01:32:05 +0000879 log->Printf("Found variable %s, returned (NamedDecl)%p", context.Name.getAsString().c_str(), var_decl);
Sean Callanan8f0dc342010-06-22 23:46:24 +0000880}
881
882void
Sean Callanana48fe162010-08-11 03:57:18 +0000883ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
Sean Callanana6223432010-08-20 01:02:30 +0000884 ClangExpressionVariable *pvar)
Sean Callanana48fe162010-08-11 03:57:18 +0000885{
Sean Callanana6223432010-08-20 01:02:30 +0000886 TypeFromUser user_type = pvar->m_user_type;
Sean Callanana48fe162010-08-11 03:57:18 +0000887
888 TypeFromParser parser_type(ClangASTContext::CopyType(context.GetASTContext(),
889 user_type.GetASTContext(),
890 user_type.GetOpaqueQualType()),
891 context.GetASTContext());
892
Sean Callanan8c127202010-08-23 23:09:38 +0000893 NamedDecl *var_decl = context.AddVarDecl(parser_type.GetOpaqueQualType());
894
895 pvar->EnableParserVars();
896 pvar->m_parser_vars->m_parser_type = parser_type;
897 pvar->m_parser_vars->m_named_decl = var_decl;
898 pvar->m_parser_vars->m_llvm_value = NULL;
899 pvar->m_parser_vars->m_lldb_value = NULL;
Sean Callanana48fe162010-08-11 03:57:18 +0000900}
901
902void
Sean Callanan8f0dc342010-06-22 23:46:24 +0000903ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
Sean Callanan0fc73582010-07-27 00:55:47 +0000904 Function* fun,
905 Symbol* symbol)
Sean Callanan8f0dc342010-06-22 23:46:24 +0000906{
Sean Callanan6184dfe2010-06-23 00:47:48 +0000907 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
Sean Callanan8f0dc342010-06-22 23:46:24 +0000908
Sean Callanan0fc73582010-07-27 00:55:47 +0000909 NamedDecl *fun_decl;
Sean Callanan8f0dc342010-06-22 23:46:24 +0000910 std::auto_ptr<Value> fun_location(new Value);
Sean Callanan0fc73582010-07-27 00:55:47 +0000911 const Address *fun_address;
Sean Callanan8f0dc342010-06-22 23:46:24 +0000912
Sean Callanan0fc73582010-07-27 00:55:47 +0000913 // only valid for Functions, not for Symbols
914 void *fun_opaque_type = NULL;
915 clang::ASTContext *fun_ast_context = NULL;
916
917 if (fun)
918 {
919 Type *fun_type = fun->GetType();
920
921 if (!fun_type)
922 {
923 if (log)
924 log->PutCString("Skipped a function because it has no type");
925 return;
926 }
927
928 fun_opaque_type = fun_type->GetOpaqueClangQualType();
929
930 if (!fun_opaque_type)
931 {
932 if (log)
933 log->PutCString("Skipped a function because it has no Clang type");
934 return;
935 }
936
937 fun_address = &fun->GetAddressRange().GetBaseAddress();
938
939 TypeList *type_list = fun_type->GetTypeList();
940 fun_ast_context = type_list->GetClangASTContext().getASTContext();
941 void *copied_type = ClangASTContext::CopyType(context.GetASTContext(), fun_ast_context, fun_opaque_type);
942
943 fun_decl = context.AddFunDecl(copied_type);
944 }
945 else if (symbol)
946 {
947 fun_address = &symbol->GetAddressRangeRef().GetBaseAddress();
948
949 fun_decl = context.AddGenericFunDecl();
950 }
951 else
952 {
953 if (log)
954 log->PutCString("AddOneFunction called with no function and no symbol");
955 return;
956 }
957
958 lldb::addr_t load_addr = fun_address->GetLoadAddress(m_exe_ctx->process);
Sean Callanan8f0dc342010-06-22 23:46:24 +0000959 fun_location->SetValueType(Value::eValueTypeLoadAddress);
960 fun_location->GetScalar() = load_addr;
961
Sean Callanan8c127202010-08-23 23:09:38 +0000962 ClangExpressionVariable &entity(m_found_entities.VariableAtIndex(m_found_entities.CreateVariable()));
963 entity.m_name = context.Name.getAsString();
964 entity.m_user_type = TypeFromUser(fun_opaque_type, fun_ast_context);;
Sean Callanan8f0dc342010-06-22 23:46:24 +0000965
Sean Callanan8c127202010-08-23 23:09:38 +0000966 entity.EnableParserVars();
967 entity.m_parser_vars->m_named_decl = fun_decl;
968 entity.m_parser_vars->m_llvm_value = NULL;
969 entity.m_parser_vars->m_lldb_value = fun_location.release();
970
Sean Callanan810f22d2010-07-16 00:09:46 +0000971 if (log)
Sean Callananf5857a02010-07-31 01:32:05 +0000972 log->Printf("Found function %s, returned (NamedDecl)%p", context.Name.getAsString().c_str(), fun_decl);
Chris Lattner24943d22010-06-08 16:52:24 +0000973}
Sean Callanan93a4b1a2010-08-04 01:02:13 +0000974
975void
976ClangExpressionDeclMap::AddOneType(NameSearchContext &context,
977 Type *type)
978{
979 TypeFromUser ut(type->GetOpaqueClangQualType(),
980 type->GetClangAST());
981
982 void *copied_type = ClangASTContext::CopyType(context.GetASTContext(), ut.GetASTContext(), ut.GetOpaqueQualType());
983
984 context.AddTypeDecl(copied_type);
985}