blob: 8937571014f4fb4ef707a0aafda7dc9bf9523fd5 [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"
Chris Lattner24943d22010-06-08 16:52:24 +000017#include "lldb/lldb-private.h"
18#include "lldb/Core/Address.h"
Sean Callanan810f22d2010-07-16 00:09:46 +000019#include "lldb/Core/Error.h"
Sean Callanan6184dfe2010-06-23 00:47:48 +000020#include "lldb/Core/Log.h"
Chris Lattner24943d22010-06-08 16:52:24 +000021#include "lldb/Core/Module.h"
22#include "lldb/Expression/ClangASTSource.h"
Sean Callanana48fe162010-08-11 03:57:18 +000023#include "lldb/Expression/ClangPersistentVariables.h"
Chris Lattner24943d22010-06-08 16:52:24 +000024#include "lldb/Symbol/ClangASTContext.h"
25#include "lldb/Symbol/CompileUnit.h"
26#include "lldb/Symbol/Function.h"
27#include "lldb/Symbol/ObjectFile.h"
28#include "lldb/Symbol/SymbolContext.h"
29#include "lldb/Symbol/Type.h"
30#include "lldb/Symbol/TypeList.h"
31#include "lldb/Symbol/Variable.h"
32#include "lldb/Symbol/VariableList.h"
Sean Callananf328c9f2010-07-20 23:31:16 +000033#include "lldb/Target/ExecutionContext.h"
Sean Callanan810f22d2010-07-16 00:09:46 +000034#include "lldb/Target/Process.h"
Sean Callanan17c6a052010-10-05 20:18:48 +000035#include "lldb/Target/RegisterContext.h"
Chris Lattner24943d22010-06-08 16:52:24 +000036#include "lldb/Target/StackFrame.h"
Sean Callananf328c9f2010-07-20 23:31:16 +000037#include "lldb/Target/Target.h"
Chris Lattner24943d22010-06-08 16:52:24 +000038
Chris Lattner24943d22010-06-08 16:52:24 +000039using namespace lldb_private;
40using namespace clang;
41
Sean Callanana48fe162010-08-11 03:57:18 +000042ClangExpressionDeclMap::ClangExpressionDeclMap(ExecutionContext *exe_ctx) :
43 m_exe_ctx(exe_ctx), m_struct_laid_out(false),
Sean Callanan810f22d2010-07-16 00:09:46 +000044 m_materialized_location(0)
Chris Lattner24943d22010-06-08 16:52:24 +000045{
46 if (exe_ctx && exe_ctx->frame)
47 m_sym_ctx = new SymbolContext(exe_ctx->frame->GetSymbolContext(lldb::eSymbolContextEverything));
48 else
49 m_sym_ctx = NULL;
Sean Callanana48fe162010-08-11 03:57:18 +000050
51 if (exe_ctx && exe_ctx->process)
52 m_persistent_vars = &exe_ctx->process->GetPersistentVariables();
Chris Lattner24943d22010-06-08 16:52:24 +000053}
54
55ClangExpressionDeclMap::~ClangExpressionDeclMap()
Sean Callanan8c127202010-08-23 23:09:38 +000056{
57 for (uint64_t entity_index = 0, num_entities = m_found_entities.Size();
58 entity_index < num_entities;
59 ++entity_index)
60 {
61 ClangExpressionVariable &entity(m_found_entities.VariableAtIndex(entity_index));
62 if (entity.m_parser_vars.get() &&
63 entity.m_parser_vars->m_lldb_value)
64 delete entity.m_parser_vars->m_lldb_value;
Sean Callanan45690fe2010-08-30 22:17:16 +000065
66 entity.DisableParserVars();
67 }
68
69 for (uint64_t pvar_index = 0, num_pvars = m_persistent_vars->Size();
70 pvar_index < num_pvars;
71 ++pvar_index)
72 {
73 ClangExpressionVariable &pvar(m_persistent_vars->VariableAtIndex(pvar_index));
74 pvar.DisableParserVars();
Sean Callanan8c127202010-08-23 23:09:38 +000075 }
Chris Lattner24943d22010-06-08 16:52:24 +000076
77 if (m_sym_ctx)
78 delete m_sym_ctx;
79}
80
Sean Callanan8bce6652010-07-13 21:41:46 +000081// Interface for IRForTarget
82
Sean Callanan82b74c82010-08-12 01:56:52 +000083void
84ClangExpressionDeclMap::GetPersistentResultName (std::string &name)
85{
86 m_persistent_vars->GetNextResultName(m_result_name);
87
88 name = m_result_name;
89}
90
Sean Callanan8bce6652010-07-13 21:41:46 +000091bool
Sean Callanan8c127202010-08-23 23:09:38 +000092ClangExpressionDeclMap::AddPersistentVariable (const clang::NamedDecl *decl,
93 const char *name,
94 TypeFromParser parser_type)
Sean Callanana48fe162010-08-11 03:57:18 +000095{
96 clang::ASTContext *context(m_exe_ctx->target->GetScratchClangASTContext()->getASTContext());
97
Sean Callanana48fe162010-08-11 03:57:18 +000098 TypeFromUser user_type(ClangASTContext::CopyType(context,
Sean Callanan82b74c82010-08-12 01:56:52 +000099 parser_type.GetASTContext(),
100 parser_type.GetOpaqueQualType()),
Sean Callanana48fe162010-08-11 03:57:18 +0000101 context);
102
Sean Callanan8c127202010-08-23 23:09:38 +0000103 if (!m_persistent_vars->CreatePersistentVariable (name, user_type))
104 return false;
105
106 ClangExpressionVariable *var = m_persistent_vars->GetVariable(name);
107
108 if (!var)
109 return false;
110
111 var->EnableParserVars();
112
113 var->m_parser_vars->m_named_decl = decl;
114 var->m_parser_vars->m_parser_type = parser_type;
115
116 return true;
Sean Callanana48fe162010-08-11 03:57:18 +0000117}
118
119bool
Sean Callanan8c127202010-08-23 23:09:38 +0000120ClangExpressionDeclMap::AddValueToStruct (const clang::NamedDecl *decl,
Sean Callanan45690fe2010-08-30 22:17:16 +0000121 const char *name,
Sean Callanan8c127202010-08-23 23:09:38 +0000122 llvm::Value *value,
Sean Callanan8bce6652010-07-13 21:41:46 +0000123 size_t size,
124 off_t alignment)
125{
Sean Callanan45690fe2010-08-30 22:17:16 +0000126 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
127
Sean Callanan8bce6652010-07-13 21:41:46 +0000128 m_struct_laid_out = false;
129
Sean Callanan8c127202010-08-23 23:09:38 +0000130 if (m_struct_members.GetVariable(decl))
131 return true;
Sean Callanan8bce6652010-07-13 21:41:46 +0000132
Sean Callanan8c127202010-08-23 23:09:38 +0000133 ClangExpressionVariable *var = m_found_entities.GetVariable(decl);
Sean Callanan8bce6652010-07-13 21:41:46 +0000134
Sean Callanan8c127202010-08-23 23:09:38 +0000135 if (!var)
136 var = m_persistent_vars->GetVariable(decl);
Sean Callanan8bce6652010-07-13 21:41:46 +0000137
Sean Callanan8c127202010-08-23 23:09:38 +0000138 if (!var)
139 return false;
140
Sean Callanan45690fe2010-08-30 22:17:16 +0000141 if (log)
142 log->Printf("Adding value for decl %p [%s - %s] to the structure",
143 decl,
144 name,
145 var->m_name.c_str());
146
Sean Callanan8c127202010-08-23 23:09:38 +0000147 // We know entity->m_parser_vars is valid because we used a parser variable
148 // to find it
149 var->m_parser_vars->m_llvm_value = value;
150
151 var->EnableJITVars();
152 var->m_jit_vars->m_alignment = alignment;
153 var->m_jit_vars->m_size = size;
154
155 m_struct_members.AddVariable(*var);
Sean Callanan8bce6652010-07-13 21:41:46 +0000156
157 return true;
158}
159
160bool
161ClangExpressionDeclMap::DoStructLayout ()
162{
163 if (m_struct_laid_out)
164 return true;
165
Sean Callanan8bce6652010-07-13 21:41:46 +0000166 off_t cursor = 0;
167
168 m_struct_alignment = 0;
169 m_struct_size = 0;
170
Sean Callanan8c127202010-08-23 23:09:38 +0000171 for (uint64_t member_index = 0, num_members = m_struct_members.Size();
172 member_index < num_members;
173 ++member_index)
Sean Callanan8bce6652010-07-13 21:41:46 +0000174 {
Sean Callanan8c127202010-08-23 23:09:38 +0000175 ClangExpressionVariable &member(m_struct_members.VariableAtIndex(member_index));
Sean Callanan8bce6652010-07-13 21:41:46 +0000176
Sean Callanan8c127202010-08-23 23:09:38 +0000177 if (!member.m_jit_vars.get())
178 return false;
Sean Callanan8bce6652010-07-13 21:41:46 +0000179
Sean Callanan8c127202010-08-23 23:09:38 +0000180 if (member_index == 0)
181 m_struct_alignment = member.m_jit_vars->m_alignment;
182
183 if (cursor % member.m_jit_vars->m_alignment)
184 cursor += (member.m_jit_vars->m_alignment - (cursor % member.m_jit_vars->m_alignment));
185
186 member.m_jit_vars->m_offset = cursor;
187 cursor += member.m_jit_vars->m_size;
Sean Callanan8bce6652010-07-13 21:41:46 +0000188 }
189
190 m_struct_size = cursor;
191
192 m_struct_laid_out = true;
193 return true;
194}
195
196bool ClangExpressionDeclMap::GetStructInfo (uint32_t &num_elements,
197 size_t &size,
198 off_t &alignment)
199{
200 if (!m_struct_laid_out)
201 return false;
202
Sean Callanan8c127202010-08-23 23:09:38 +0000203 num_elements = m_struct_members.Size();
Sean Callanan8bce6652010-07-13 21:41:46 +0000204 size = m_struct_size;
205 alignment = m_struct_alignment;
206
207 return true;
208}
209
210bool
211ClangExpressionDeclMap::GetStructElement (const clang::NamedDecl *&decl,
212 llvm::Value *&value,
213 off_t &offset,
Sean Callanan45690fe2010-08-30 22:17:16 +0000214 const char *&name,
Sean Callanan8bce6652010-07-13 21:41:46 +0000215 uint32_t index)
216{
217 if (!m_struct_laid_out)
218 return false;
219
Sean Callanan8c127202010-08-23 23:09:38 +0000220 if (index >= m_struct_members.Size())
Sean Callanan8bce6652010-07-13 21:41:46 +0000221 return false;
222
Sean Callanan8c127202010-08-23 23:09:38 +0000223 ClangExpressionVariable &member(m_struct_members.VariableAtIndex(index));
Sean Callanan8bce6652010-07-13 21:41:46 +0000224
Sean Callanan8c127202010-08-23 23:09:38 +0000225 if (!member.m_parser_vars.get() ||
226 !member.m_jit_vars.get())
227 return false;
228
229 decl = member.m_parser_vars->m_named_decl;
230 value = member.m_parser_vars->m_llvm_value;
231 offset = member.m_jit_vars->m_offset;
Sean Callanan45690fe2010-08-30 22:17:16 +0000232 name = member.m_name.c_str();
Sean Callanan8c127202010-08-23 23:09:38 +0000233
Sean Callanan8bce6652010-07-13 21:41:46 +0000234 return true;
235}
236
Sean Callanan02fbafa2010-07-27 21:39:39 +0000237bool
238ClangExpressionDeclMap::GetFunctionInfo (const clang::NamedDecl *decl,
239 llvm::Value**& value,
240 uint64_t &ptr)
Sean Callananba992c52010-07-27 02:07:53 +0000241{
Sean Callanan8c127202010-08-23 23:09:38 +0000242 ClangExpressionVariable *entity = m_found_entities.GetVariable(decl);
243
244 if (!entity)
245 return false;
Sean Callananba992c52010-07-27 02:07:53 +0000246
Sean Callanan8c127202010-08-23 23:09:38 +0000247 // We know m_parser_vars is valid since we searched for the variable by
248 // its NamedDecl
Sean Callananba992c52010-07-27 02:07:53 +0000249
Sean Callanan8c127202010-08-23 23:09:38 +0000250 value = &entity->m_parser_vars->m_llvm_value;
251 ptr = entity->m_parser_vars->m_lldb_value->GetScalar().ULongLong();
252
253 return true;
Sean Callananba992c52010-07-27 02:07:53 +0000254}
255
Sean Callananf5857a02010-07-31 01:32:05 +0000256bool
257ClangExpressionDeclMap::GetFunctionAddress (const char *name,
258 uint64_t &ptr)
259{
260 // Back out in all cases where we're not fully initialized
261 if (!m_exe_ctx || !m_exe_ctx->frame || !m_sym_ctx)
262 return false;
263
264 ConstString name_cs(name);
265 SymbolContextList sym_ctxs;
266
267 m_sym_ctx->FindFunctionsByName(name_cs, false, sym_ctxs);
268
269 if (!sym_ctxs.GetSize())
270 return false;
271
272 SymbolContext sym_ctx;
273 sym_ctxs.GetContextAtIndex(0, sym_ctx);
274
275 const Address *fun_address;
276
277 if (sym_ctx.function)
278 fun_address = &sym_ctx.function->GetAddressRange().GetBaseAddress();
279 else if (sym_ctx.symbol)
280 fun_address = &sym_ctx.symbol->GetAddressRangeRef().GetBaseAddress();
281 else
282 return false;
283
Greg Claytoneea26402010-09-14 23:36:40 +0000284 ptr = fun_address->GetLoadAddress(m_exe_ctx->target);
Sean Callananf5857a02010-07-31 01:32:05 +0000285
286 return true;
287}
288
Sean Callanan810f22d2010-07-16 00:09:46 +0000289// Interface for CommandObjectExpression
Sean Callananf328c9f2010-07-20 23:31:16 +0000290
291bool
292ClangExpressionDeclMap::Materialize (ExecutionContext *exe_ctx,
293 lldb::addr_t &struct_address,
294 Error &err)
295{
296 bool result = DoMaterialize(false, exe_ctx, NULL, err);
297
298 if (result)
299 struct_address = m_materialized_location;
300
301 return result;
302}
303
304bool
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000305ClangExpressionDeclMap::GetObjectPointer(lldb::addr_t &object_ptr,
306 ExecutionContext *exe_ctx,
307 Error &err)
308{
309 if (!exe_ctx || !exe_ctx->frame || !exe_ctx->target || !exe_ctx->process)
310 {
311 err.SetErrorString("Couldn't load 'this' because the context is incomplete");
312 return false;
313 }
314
315 if (!m_object_pointer_type.GetOpaqueQualType())
316 {
317 err.SetErrorString("Couldn't load 'this' because its type is unknown");
318 return false;
319 }
320
321 Variable *object_ptr_var = FindVariableInScope(*exe_ctx->frame, "this", &m_object_pointer_type);
322
323 if (!object_ptr_var)
324 {
325 err.SetErrorString("Couldn't find 'this' with appropriate type in scope");
326 return false;
327 }
328
329 std::auto_ptr<lldb_private::Value> location_value(GetVariableValue(*exe_ctx,
330 object_ptr_var,
331 m_object_pointer_type.GetASTContext()));
332
333 if (!location_value.get())
334 {
335 err.SetErrorString("Couldn't get the location for 'this'");
336 return false;
337 }
338
339 if (location_value->GetValueType() == Value::eValueTypeLoadAddress)
340 {
341 lldb::addr_t value_addr = location_value->GetScalar().ULongLong();
342 uint32_t address_byte_size = exe_ctx->target->GetArchitecture().GetAddressByteSize();
343 lldb::ByteOrder address_byte_order = exe_ctx->process->GetByteOrder();
344
345 if (ClangASTType::GetClangTypeBitWidth(m_object_pointer_type.GetASTContext(), m_object_pointer_type.GetOpaqueQualType()) != address_byte_size * 8)
346 {
347 err.SetErrorStringWithFormat("'this' is not of an expected pointer size");
348 return false;
349 }
350
351 DataBufferHeap data;
352 data.SetByteSize(address_byte_size);
353 Error read_error;
354
355 if (exe_ctx->process->ReadMemory (value_addr, data.GetBytes(), address_byte_size, read_error) != address_byte_size)
356 {
357 err.SetErrorStringWithFormat("Coldn't read 'this' from the target: %s", read_error.AsCString());
358 return false;
359 }
360
361 DataExtractor extractor(data.GetBytes(), data.GetByteSize(), address_byte_order, address_byte_size);
362
363 uint32_t offset = 0;
364
365 object_ptr = extractor.GetPointer(&offset);
366
367 return true;
368 }
369 else
370 {
371 err.SetErrorString("'this' is not in memory; LLDB must be extended to handle registers");
372 return false;
373 }
374}
375
376bool
Sean Callananf328c9f2010-07-20 23:31:16 +0000377ClangExpressionDeclMap::Dematerialize (ExecutionContext *exe_ctx,
Sean Callanana6223432010-08-20 01:02:30 +0000378 ClangExpressionVariable *&result,
Sean Callananf328c9f2010-07-20 23:31:16 +0000379 Error &err)
380{
Sean Callanan82b74c82010-08-12 01:56:52 +0000381 return DoMaterialize(true, exe_ctx, &result, err);
Sean Callananf328c9f2010-07-20 23:31:16 +0000382}
383
Sean Callanan32824aa2010-07-23 22:19:18 +0000384bool
385ClangExpressionDeclMap::DumpMaterializedStruct(ExecutionContext *exe_ctx,
386 Stream &s,
387 Error &err)
388{
389 if (!m_struct_laid_out)
390 {
391 err.SetErrorString("Structure hasn't been laid out yet");
392 return false;
393 }
394
395 if (!exe_ctx)
396 {
397 err.SetErrorString("Received null execution context");
398 return false;
399 }
400
401
402 if (!exe_ctx->process)
403 {
404 err.SetErrorString("Couldn't find the process");
405 return false;
406 }
407
408 if (!exe_ctx->target)
409 {
410 err.SetErrorString("Couldn't find the target");
411 return false;
412 }
413
414 lldb::DataBufferSP data(new DataBufferHeap(m_struct_size, 0));
415
416 Error error;
417 if (exe_ctx->process->ReadMemory (m_materialized_location, data->GetBytes(), data->GetByteSize(), error) != data->GetByteSize())
418 {
419 err.SetErrorStringWithFormat ("Couldn't read struct from the target: %s", error.AsCString());
420 return false;
421 }
422
423 DataExtractor extractor(data, exe_ctx->process->GetByteOrder(), exe_ctx->target->GetArchitecture().GetAddressByteSize());
424
Sean Callanan8c127202010-08-23 23:09:38 +0000425 for (uint64_t member_index = 0, num_members = m_struct_members.Size();
426 member_index < num_members;
427 ++member_index)
Sean Callanan32824aa2010-07-23 22:19:18 +0000428 {
Sean Callanan8c127202010-08-23 23:09:38 +0000429 ClangExpressionVariable &member (m_struct_members.VariableAtIndex(member_index));
Sean Callanan32824aa2010-07-23 22:19:18 +0000430
Sean Callanan8c127202010-08-23 23:09:38 +0000431 s.Printf("[%s]\n", member.m_name.c_str());
432
433 if (!member.m_jit_vars.get())
434 return false;
435
436 extractor.Dump(&s, // stream
437 member.m_jit_vars->m_offset, // offset
438 lldb::eFormatBytesWithASCII, // format
439 1, // byte size of individual entries
440 member.m_jit_vars->m_size, // number of entries
441 16, // entries per line
442 m_materialized_location + member.m_jit_vars->m_offset, // address to print
443 0, // bit size (bitfields only; 0 means ignore)
444 0); // bit alignment (bitfields only; 0 means ignore)
Sean Callanan32824aa2010-07-23 22:19:18 +0000445
446 s.PutChar('\n');
447 }
448
449 return true;
450}
451
Sean Callananf328c9f2010-07-20 23:31:16 +0000452bool
453ClangExpressionDeclMap::DoMaterialize (bool dematerialize,
454 ExecutionContext *exe_ctx,
Sean Callanana6223432010-08-20 01:02:30 +0000455 ClangExpressionVariable **result,
Sean Callananf328c9f2010-07-20 23:31:16 +0000456 Error &err)
Sean Callanan810f22d2010-07-16 00:09:46 +0000457{
Sean Callanan336a0002010-07-17 00:43:37 +0000458 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
Sean Callanan82b74c82010-08-12 01:56:52 +0000459
Sean Callanan810f22d2010-07-16 00:09:46 +0000460 if (!m_struct_laid_out)
461 {
462 err.SetErrorString("Structure hasn't been laid out yet");
463 return LLDB_INVALID_ADDRESS;
464 }
465
Sean Callanan810f22d2010-07-16 00:09:46 +0000466 if (!exe_ctx)
467 {
468 err.SetErrorString("Received null execution context");
469 return LLDB_INVALID_ADDRESS;
470 }
471
Sean Callanan45839272010-07-24 01:37:44 +0000472 if (!exe_ctx->frame)
473 {
474 err.SetErrorString("Received null execution frame");
475 return LLDB_INVALID_ADDRESS;
476 }
477
Sean Callanane8a59a82010-09-13 21:34:21 +0000478 if (!m_struct_size)
479 {
480 if (log)
481 log->PutCString("Not bothering to allocate a struct because no arguments are needed");
482
483 m_allocated_area = NULL;
484
485 return true;
486 }
487
Sean Callanan810f22d2010-07-16 00:09:46 +0000488 const SymbolContext &sym_ctx(exe_ctx->frame->GetSymbolContext(lldb::eSymbolContextEverything));
489
Sean Callananf328c9f2010-07-20 23:31:16 +0000490 if (!dematerialize)
Sean Callanan810f22d2010-07-16 00:09:46 +0000491 {
Sean Callananf328c9f2010-07-20 23:31:16 +0000492 if (m_materialized_location)
493 {
494 exe_ctx->process->DeallocateMemory(m_materialized_location);
495 m_materialized_location = 0;
496 }
497
498 lldb::addr_t mem = exe_ctx->process->AllocateMemory(m_struct_alignment + m_struct_size,
499 lldb::ePermissionsReadable | lldb::ePermissionsWritable,
500 err);
501
502 if (mem == LLDB_INVALID_ADDRESS)
503 return false;
504
505 m_allocated_area = mem;
Sean Callanan810f22d2010-07-16 00:09:46 +0000506 }
507
Sean Callananf328c9f2010-07-20 23:31:16 +0000508 m_materialized_location = m_allocated_area;
509
510 if (m_materialized_location % m_struct_alignment)
Sean Callananf328c9f2010-07-20 23:31:16 +0000511 m_materialized_location += (m_struct_alignment - (m_materialized_location % m_struct_alignment));
Sean Callananf328c9f2010-07-20 23:31:16 +0000512
Sean Callanan8c127202010-08-23 23:09:38 +0000513 for (uint64_t member_index = 0, num_members = m_struct_members.Size();
514 member_index < num_members;
515 ++member_index)
Sean Callanan810f22d2010-07-16 00:09:46 +0000516 {
Sean Callanan8c127202010-08-23 23:09:38 +0000517 ClangExpressionVariable &member (m_struct_members.VariableAtIndex(member_index));
Sean Callanan810f22d2010-07-16 00:09:46 +0000518
Sean Callanan8c127202010-08-23 23:09:38 +0000519 if (!member.m_parser_vars.get())
Sean Callanan336a0002010-07-17 00:43:37 +0000520 return false;
Sean Callanan8c127202010-08-23 23:09:38 +0000521
522 ClangExpressionVariable *entity = m_found_entities.GetVariable(member.m_parser_vars->m_named_decl);
523 ClangExpressionVariable *persistent_variable = m_persistent_vars->GetVariable(member.m_name.c_str());
524
525 if (entity)
526 {
527 if (!member.m_jit_vars.get())
528 return false;
529
530 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))
531 return false;
532 }
533 else if (persistent_variable)
534 {
Sean Callanan45690fe2010-08-30 22:17:16 +0000535 if (!member.m_name.compare(m_result_name))
536 {
537 if (!dematerialize)
538 continue;
Sean Callanan8c127202010-08-23 23:09:38 +0000539
Sean Callanan8c127202010-08-23 23:09:38 +0000540 if (log)
541 log->PutCString("Found result member in the struct");
Sean Callanan45690fe2010-08-30 22:17:16 +0000542
Sean Callanan8c127202010-08-23 23:09:38 +0000543 *result = &member;
544 }
545
Sean Callanan45690fe2010-08-30 22:17:16 +0000546 if (log)
547 log->Printf("Searched for persistent variable %s and found %s", member.m_name.c_str(), persistent_variable->m_name.c_str());
548
Sean Callanan8c127202010-08-23 23:09:38 +0000549 if (!DoMaterializeOnePersistentVariable(dematerialize, *exe_ctx, persistent_variable->m_name.c_str(), m_materialized_location + member.m_jit_vars->m_offset, err))
550 return false;
551 }
552 else
553 {
554 err.SetErrorStringWithFormat("Unexpected variable %s", member.m_name.c_str());
555 return false;
556 }
Sean Callanan810f22d2010-07-16 00:09:46 +0000557 }
558
Sean Callananf328c9f2010-07-20 23:31:16 +0000559 return true;
560}
561
Sean Callanana48fe162010-08-11 03:57:18 +0000562bool
563ClangExpressionDeclMap::DoMaterializeOnePersistentVariable(bool dematerialize,
564 ExecutionContext &exe_ctx,
565 const char *name,
566 lldb::addr_t addr,
567 Error &err)
Sean Callanan45690fe2010-08-30 22:17:16 +0000568{
Sean Callanana6223432010-08-20 01:02:30 +0000569 ClangExpressionVariable *pvar(m_persistent_vars->GetVariable(name));
Sean Callanana48fe162010-08-11 03:57:18 +0000570
571 if (!pvar)
572 {
573 err.SetErrorStringWithFormat("Undefined persistent variable %s", name);
574 return LLDB_INVALID_ADDRESS;
575 }
576
577 size_t pvar_size = pvar->Size();
Sean Callanana6223432010-08-20 01:02:30 +0000578
Greg Clayton66ed2fb2010-10-05 00:00:42 +0000579 if (!pvar->m_data_sp.get())
Sean Callanana6223432010-08-20 01:02:30 +0000580 return false;
581
Greg Clayton66ed2fb2010-10-05 00:00:42 +0000582 uint8_t *pvar_data = pvar->m_data_sp->GetBytes();
Sean Callanana48fe162010-08-11 03:57:18 +0000583 Error error;
584
585 if (dematerialize)
586 {
587 if (exe_ctx.process->ReadMemory (addr, pvar_data, pvar_size, error) != pvar_size)
588 {
589 err.SetErrorStringWithFormat ("Couldn't read a composite type from the target: %s", error.AsCString());
590 return false;
591 }
592 }
593 else
594 {
595 if (exe_ctx.process->WriteMemory (addr, pvar_data, pvar_size, error) != pvar_size)
596 {
597 err.SetErrorStringWithFormat ("Couldn't write a composite type to the target: %s", error.AsCString());
598 return false;
599 }
600 }
601
602 return true;
603}
604
Sean Callananf328c9f2010-07-20 23:31:16 +0000605bool
606ClangExpressionDeclMap::DoMaterializeOneVariable(bool dematerialize,
607 ExecutionContext &exe_ctx,
608 const SymbolContext &sym_ctx,
609 const char *name,
610 TypeFromUser type,
611 lldb::addr_t addr,
612 Error &err)
613{
614 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
615
Sean Callanan17c6a052010-10-05 20:18:48 +0000616 if (!exe_ctx.frame || !exe_ctx.process)
Sean Callanancc074622010-09-14 21:59:34 +0000617 return false;
618
619 Variable *var = FindVariableInScope(*exe_ctx.frame, name, &type);
Sean Callananf328c9f2010-07-20 23:31:16 +0000620
621 if (!var)
622 {
623 err.SetErrorStringWithFormat("Couldn't find %s with appropriate type", name);
624 return false;
625 }
626
Sean Callanan841026f2010-07-23 00:16:21 +0000627 if (log)
628 log->Printf("%s %s with type %p", (dematerialize ? "Dematerializing" : "Materializing"), name, type.GetOpaqueQualType());
Sean Callananf328c9f2010-07-20 23:31:16 +0000629
630 std::auto_ptr<lldb_private::Value> location_value(GetVariableValue(exe_ctx,
631 var,
632 type.GetASTContext()));
633
634 if (!location_value.get())
635 {
636 err.SetErrorStringWithFormat("Couldn't get value for %s", name);
637 return false;
638 }
Sean Callanan17c6a052010-10-05 20:18:48 +0000639
640 // The size of the type contained in addr
Sean Callananf328c9f2010-07-20 23:31:16 +0000641
Sean Callanan17c6a052010-10-05 20:18:48 +0000642 size_t addr_bit_size = ClangASTType::GetClangTypeBitWidth(type.GetASTContext(), type.GetOpaqueQualType());
643 size_t addr_byte_size = addr_bit_size % 8 ? ((addr_bit_size + 8) / 8) : (addr_bit_size / 8);
644
645 Value::ValueType value_type = location_value->GetValueType();
646
647 switch (value_type)
Sean Callananf328c9f2010-07-20 23:31:16 +0000648 {
Sean Callanan17c6a052010-10-05 20:18:48 +0000649 default:
Sean Callananf328c9f2010-07-20 23:31:16 +0000650 {
Sean Callanan17c6a052010-10-05 20:18:48 +0000651 StreamString ss;
652
653 location_value->Dump(&ss);
654
655 err.SetErrorStringWithFormat("%s has a value of unhandled type: %s", name, ss.GetString().c_str());
Sean Callananf328c9f2010-07-20 23:31:16 +0000656 return false;
657 }
Sean Callanan17c6a052010-10-05 20:18:48 +0000658 break;
659 case Value::eValueTypeLoadAddress:
Sean Callananf328c9f2010-07-20 23:31:16 +0000660 {
Sean Callanan17c6a052010-10-05 20:18:48 +0000661 lldb::addr_t value_addr = location_value->GetScalar().ULongLong();
662
663 DataBufferHeap data;
664 data.SetByteSize(addr_byte_size);
665
666 lldb::addr_t src_addr;
667 lldb::addr_t dest_addr;
668
669 if (dematerialize)
670 {
671 src_addr = addr;
672 dest_addr = value_addr;
673 }
674 else
675 {
676 src_addr = value_addr;
677 dest_addr = addr;
678 }
679
680 Error error;
681 if (exe_ctx.process->ReadMemory (src_addr, data.GetBytes(), addr_byte_size, error) != addr_byte_size)
682 {
683 err.SetErrorStringWithFormat ("Couldn't read %s from the target: %s", name, error.AsCString());
684 return false;
685 }
686
687 if (exe_ctx.process->WriteMemory (dest_addr, data.GetBytes(), addr_byte_size, error) != addr_byte_size)
688 {
689 err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", name, error.AsCString());
690 return false;
691 }
692
693 if (log)
694 log->Printf("Copied from 0x%llx to 0x%llx", (uint64_t)src_addr, (uint64_t)addr);
Sean Callananf328c9f2010-07-20 23:31:16 +0000695 }
Sean Callanan17c6a052010-10-05 20:18:48 +0000696 break;
697 case Value::eValueTypeScalar:
698 {
699 if (location_value->GetContextType() != Value::eContextTypeDCRegisterInfo)
700 {
701 StreamString ss;
702
703 location_value->Dump(&ss);
704
705 err.SetErrorStringWithFormat("%s is a scalar of unhandled type: %s", name, ss.GetString().c_str());
706 return false;
707 }
708
709 lldb::RegisterInfo *register_info = location_value->GetRegisterInfo();
710
711 if (!register_info)
712 {
713 err.SetErrorStringWithFormat("Couldn't get the register information for %s", name);
714 return false;
715 }
716
717 RegisterContext *register_context = exe_ctx.GetRegisterContext();
718
719 if (!register_context)
720 {
721 err.SetErrorStringWithFormat("Couldn't read register context to read %s from %s", name, register_info->name);
722 return false;
723 }
724
725 uint32_t register_number = register_info->kinds[lldb::eRegisterKindLLDB];
726 uint32_t register_byte_size = register_info->byte_size;
727
728 if (dematerialize)
729 {
730 // Moving from addr into a register
731 //
732 // Case 1: addr_byte_size and register_byte_size are the same
733 //
734 // |AABBCCDD| Address contents
735 // |AABBCCDD| Register contents
736 //
737 // Case 2: addr_byte_size is bigger than register_byte_size
738 //
739 // Error! (The register should always be big enough to hold the data)
740 //
741 // Case 3: register_byte_size is bigger than addr_byte_size
742 //
743 // |AABB| Address contents
744 // |AABB0000| Register contents [on little-endian hardware]
745 // |0000AABB| Register contents [on big-endian hardware]
746
747 if (addr_byte_size > register_byte_size)
748 {
749 err.SetErrorStringWithFormat("%s is too big to store in %s", name, register_info->name);
750 return false;
751 }
752
753 uint32_t register_offset;
754
755 switch (exe_ctx.process->GetByteOrder())
756 {
757 default:
758 err.SetErrorStringWithFormat("%s is stored with an unhandled byte order", name);
759 return false;
760 case lldb::eByteOrderLittle:
761 register_offset = 0;
762 break;
763 case lldb::eByteOrderBig:
764 register_offset = register_byte_size - addr_byte_size;
765 break;
766 }
767
768 DataBufferHeap register_data (register_byte_size, 0);
769
770 Error error;
771 if (exe_ctx.process->ReadMemory (addr, register_data.GetBytes() + register_offset, addr_byte_size, error) != addr_byte_size)
772 {
773 err.SetErrorStringWithFormat ("Couldn't read %s from the target: %s", name, error.AsCString());
774 return false;
775 }
776
777 DataExtractor register_extractor (register_data.GetBytes(), register_byte_size, exe_ctx.process->GetByteOrder(), exe_ctx.process->GetAddressByteSize());
778
779 if (!register_context->WriteRegisterBytes(register_number, register_extractor, 0))
780 {
781 err.SetErrorStringWithFormat("Couldn't read %s from %s", name, register_info->name);
782 return false;
783 }
784 }
785 else
786 {
787 // Moving from a register into addr
788 //
789 // Case 1: addr_byte_size and register_byte_size are the same
790 //
791 // |AABBCCDD| Register contents
792 // |AABBCCDD| Address contents
793 //
794 // Case 2: addr_byte_size is bigger than register_byte_size
795 //
796 // Error! (The register should always be big enough to hold the data)
797 //
798 // Case 3: register_byte_size is bigger than addr_byte_size
799 //
800 // |AABBCCDD| Register contents
801 // |AABB| Address contents on little-endian hardware
802 // |CCDD| Address contents on big-endian hardware
803
804 if (addr_byte_size > register_byte_size)
805 {
806 err.SetErrorStringWithFormat("%s is too big to store in %s", name, register_info->name);
807 return false;
808 }
809
810 uint32_t register_offset;
811
812 switch (exe_ctx.process->GetByteOrder())
813 {
814 default:
815 err.SetErrorStringWithFormat("%s is stored with an unhandled byte order", name);
816 return false;
817 case lldb::eByteOrderLittle:
818 register_offset = 0;
819 break;
820 case lldb::eByteOrderBig:
821 register_offset = register_byte_size - addr_byte_size;
822 break;
823 }
824
825 DataExtractor register_extractor;
826
827 if (!register_context->ReadRegisterBytes(register_number, register_extractor))
828 {
829 err.SetErrorStringWithFormat("Couldn't read %s from %s", name, register_info->name);
830 return false;
831 }
832
833 const void *register_data = register_extractor.GetData(&register_offset, addr_byte_size);
834
835 if (!register_data)
836 {
837 err.SetErrorStringWithFormat("Read but couldn't extract data for %s from %s", name, register_info->name);
838 return false;
839 }
840
841 Error error;
842 if (exe_ctx.process->WriteMemory (addr, register_data, addr_byte_size, error) != addr_byte_size)
843 {
844 err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", error.AsCString());
845 return false;
846 }
847 }
848 }
Sean Callananf328c9f2010-07-20 23:31:16 +0000849 }
850
851 return true;
Sean Callanan810f22d2010-07-16 00:09:46 +0000852}
853
Sean Callanancc074622010-09-14 21:59:34 +0000854Variable *
855ClangExpressionDeclMap::FindVariableInScope(StackFrame &frame,
856 const char *name,
857 TypeFromUser *type)
858{
859 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
860
861 ConstString name_cs(name);
862
863 VariableList *var_list = frame.GetVariableList(true);
864
865 lldb::VariableSP var = var_list->FindVariable(name_cs);
866
867 if (!var)
868 return NULL;
869
870 if (!type)
871 return var.get();
872
873 if (type->GetASTContext() == var->GetType()->GetClangAST())
874 {
Greg Clayton462d4142010-09-29 01:12:09 +0000875 if (!ClangASTContext::AreTypesSame(type->GetASTContext(), type->GetOpaqueQualType(), var->GetType()->GetClangType()))
Sean Callanancc074622010-09-14 21:59:34 +0000876 return NULL;
877 }
878 else
879 {
880 if (log)
881 log->PutCString("Skipping a candidate variable because of different AST contexts");
882 return NULL;
883 }
884
885 return var.get();
886
887 return NULL;
888}
Sean Callanan336a0002010-07-17 00:43:37 +0000889
Chris Lattner24943d22010-06-08 16:52:24 +0000890// Interface for ClangASTSource
891void
892ClangExpressionDeclMap::GetDecls(NameSearchContext &context,
893 const char *name)
894{
Sean Callanan6184dfe2010-06-23 00:47:48 +0000895 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000896
Sean Callanan810f22d2010-07-16 00:09:46 +0000897 if (log)
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000898 log->Printf("Hunting for a definition for %s", name);
Chris Lattner24943d22010-06-08 16:52:24 +0000899
900 // Back out in all cases where we're not fully initialized
901 if (!m_exe_ctx || !m_exe_ctx->frame || !m_sym_ctx)
902 return;
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000903
904 ConstString name_cs(name);
Sean Callanancc074622010-09-14 21:59:34 +0000905
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000906 if (!strcmp(name, "___clang_class"))
907 {
908 // Clang is looking for the type of "this"
909
910 VariableList *vars = m_exe_ctx->frame->GetVariableList(false);
911
912 if (!vars)
913 return;
914
915 lldb::VariableSP this_var = vars->FindVariable(ConstString("this"));
916
917 if (!this_var)
918 return;
919
920 Type *this_type = this_var->GetType();
921
922 if (!this_type)
923 return;
924
Greg Clayton462d4142010-09-29 01:12:09 +0000925 TypeFromUser this_user_type(this_type->GetClangType(),
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000926 this_type->GetClangAST());
927
928 m_object_pointer_type = this_user_type;
929
930 void *pointer_target_type;
931
932 if (!ClangASTContext::IsPointerType(this_user_type.GetOpaqueQualType(),
933 &pointer_target_type))
934 return;
935
936 TypeFromUser class_user_type(pointer_target_type,
937 this_type->GetClangAST());
938
939 AddOneType(context, class_user_type, true);
940
941 return;
942 }
943
Sean Callanan0fc73582010-07-27 00:55:47 +0000944 SymbolContextList sym_ctxs;
Chris Lattner24943d22010-06-08 16:52:24 +0000945
Sean Callanan0fc73582010-07-27 00:55:47 +0000946 m_sym_ctx->FindFunctionsByName(name_cs, false, sym_ctxs);
Sean Callanan8f0dc342010-06-22 23:46:24 +0000947
Sean Callanan92aa6662010-09-07 21:49:41 +0000948 bool found_specific = false;
Sean Callanan3cfbd332010-10-06 00:10:07 +0000949 Symbol *generic_symbol = NULL;
950 Symbol *non_extern_symbol = NULL;
Sean Callanan92aa6662010-09-07 21:49:41 +0000951
Sean Callanan0fc73582010-07-27 00:55:47 +0000952 for (uint32_t index = 0, num_indices = sym_ctxs.GetSize();
953 index < num_indices;
954 ++index)
955 {
956 SymbolContext sym_ctx;
957 sym_ctxs.GetContextAtIndex(index, sym_ctx);
Sean Callanan3cfbd332010-10-06 00:10:07 +0000958
Sean Callanan0fc73582010-07-27 00:55:47 +0000959 if (sym_ctx.function)
Sean Callanan92aa6662010-09-07 21:49:41 +0000960 {
961 // TODO only do this if it's a C function; C++ functions may be
962 // overloaded
963 if (!found_specific)
964 AddOneFunction(context, sym_ctx.function, NULL);
965 found_specific = true;
966 }
Sean Callanan3cfbd332010-10-06 00:10:07 +0000967 else if (sym_ctx.symbol)
Sean Callanan92aa6662010-09-07 21:49:41 +0000968 {
Sean Callanan3cfbd332010-10-06 00:10:07 +0000969 if (sym_ctx.symbol->IsExternal())
970 generic_symbol = sym_ctx.symbol;
971 else
972 non_extern_symbol = sym_ctx.symbol;
Sean Callanan92aa6662010-09-07 21:49:41 +0000973 }
Sean Callanan0fc73582010-07-27 00:55:47 +0000974 }
975
Sean Callanan3cfbd332010-10-06 00:10:07 +0000976 if (!found_specific)
977 {
978 if (generic_symbol)
979 AddOneFunction(context, NULL, generic_symbol);
980 else if (non_extern_symbol)
981 AddOneFunction(context, NULL, non_extern_symbol);
982 }
983
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000984 Variable *var = FindVariableInScope(*m_exe_ctx->frame, name);
Sean Callanan336a0002010-07-17 00:43:37 +0000985
986 if (var)
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000987 AddOneVariable(context, var);
Sean Callanan93a4b1a2010-08-04 01:02:13 +0000988
Sean Callanana6223432010-08-20 01:02:30 +0000989 ClangExpressionVariable *pvar(m_persistent_vars->GetVariable(name));
Sean Callanana48fe162010-08-11 03:57:18 +0000990
991 if (pvar)
992 AddOneVariable(context, pvar);
993
Sean Callanan93a4b1a2010-08-04 01:02:13 +0000994
Sean Callanan6df08402010-09-27 23:54:58 +0000995 // See information on gating of this operation next to the definition for
996 // m_lookedup_types.
997
998 const char *name_uniq = name_cs.GetCString();
999
1000 if (m_lookedup_types.find(name_uniq) == m_lookedup_types.end())
1001 {
1002 // 1 The name is added to m_lookedup_types.
1003 m_lookedup_types.insert(std::pair<const char*, bool>(name_uniq, true));
1004
1005 // 2 The type is looked up and added, potentially causing more type loookups.
1006 lldb::TypeSP type = m_sym_ctx->FindTypeByName(name_cs);
1007
1008 if (type.get())
1009 {
Greg Clayton462d4142010-09-29 01:12:09 +00001010 TypeFromUser user_type(type->GetClangType(),
Sean Callanan6df08402010-09-27 23:54:58 +00001011 type->GetClangAST());
1012
1013 AddOneType(context, user_type, false);
1014 }
1015
1016 // 3 The name is removed from m_lookedup_types.
1017 m_lookedup_types.erase(name_uniq);
1018 }
1019
Sean Callanan336a0002010-07-17 00:43:37 +00001020}
1021
1022Value *
1023ClangExpressionDeclMap::GetVariableValue(ExecutionContext &exe_ctx,
1024 Variable *var,
Sean Callananf328c9f2010-07-20 23:31:16 +00001025 clang::ASTContext *parser_ast_context,
1026 TypeFromUser *user_type,
1027 TypeFromParser *parser_type)
Chris Lattner24943d22010-06-08 16:52:24 +00001028{
Sean Callanan6184dfe2010-06-23 00:47:48 +00001029 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
1030
Chris Lattner24943d22010-06-08 16:52:24 +00001031 Type *var_type = var->GetType();
1032
1033 if (!var_type)
1034 {
Sean Callanan810f22d2010-07-16 00:09:46 +00001035 if (log)
1036 log->PutCString("Skipped a definition because it has no type");
Sean Callanan336a0002010-07-17 00:43:37 +00001037 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001038 }
1039
Greg Clayton462d4142010-09-29 01:12:09 +00001040 void *var_opaque_type = var_type->GetClangType();
Chris Lattner24943d22010-06-08 16:52:24 +00001041
1042 if (!var_opaque_type)
1043 {
Sean Callanan810f22d2010-07-16 00:09:46 +00001044 if (log)
1045 log->PutCString("Skipped a definition because it has no Clang type");
Sean Callanan336a0002010-07-17 00:43:37 +00001046 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001047 }
1048
Chris Lattner24943d22010-06-08 16:52:24 +00001049 TypeList *type_list = var_type->GetTypeList();
1050
1051 if (!type_list)
1052 {
Sean Callanan810f22d2010-07-16 00:09:46 +00001053 if (log)
1054 log->PutCString("Skipped a definition because the type has no associated type list");
Sean Callanan336a0002010-07-17 00:43:37 +00001055 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001056 }
1057
1058 clang::ASTContext *exe_ast_ctx = type_list->GetClangASTContext().getASTContext();
1059
1060 if (!exe_ast_ctx)
1061 {
Sean Callanan810f22d2010-07-16 00:09:46 +00001062 if (log)
1063 log->PutCString("There is no AST context for the current execution context");
Sean Callanan336a0002010-07-17 00:43:37 +00001064 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001065 }
1066
Sean Callanan336a0002010-07-17 00:43:37 +00001067 DWARFExpression &var_location_expr = var->LocationExpression();
1068
Chris Lattner24943d22010-06-08 16:52:24 +00001069 std::auto_ptr<Value> var_location(new Value);
1070
Greg Clayton178710c2010-09-14 02:20:48 +00001071 lldb::addr_t loclist_base_load_addr = LLDB_INVALID_ADDRESS;
1072
1073 if (var_location_expr.IsLocationList())
1074 {
1075 SymbolContext var_sc;
1076 var->CalculateSymbolContext (&var_sc);
Greg Claytoneea26402010-09-14 23:36:40 +00001077 loclist_base_load_addr = var_sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (exe_ctx.target);
Greg Clayton178710c2010-09-14 02:20:48 +00001078 }
Chris Lattner24943d22010-06-08 16:52:24 +00001079 Error err;
1080
Greg Clayton178710c2010-09-14 02:20:48 +00001081 if (!var_location_expr.Evaluate(&exe_ctx, exe_ast_ctx, loclist_base_load_addr, NULL, *var_location.get(), &err))
Chris Lattner24943d22010-06-08 16:52:24 +00001082 {
Sean Callanan810f22d2010-07-16 00:09:46 +00001083 if (log)
1084 log->Printf("Error evaluating location: %s", err.AsCString());
Sean Callanan336a0002010-07-17 00:43:37 +00001085 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001086 }
1087
Sean Callanan810f22d2010-07-16 00:09:46 +00001088 clang::ASTContext *var_ast_context = type_list->GetClangASTContext().getASTContext();
1089
Sean Callanan336a0002010-07-17 00:43:37 +00001090 void *type_to_use;
1091
Sean Callananf328c9f2010-07-20 23:31:16 +00001092 if (parser_ast_context)
1093 {
1094 type_to_use = ClangASTContext::CopyType(parser_ast_context, var_ast_context, var_opaque_type);
1095
1096 if (parser_type)
1097 *parser_type = TypeFromParser(type_to_use, parser_ast_context);
1098 }
Sean Callanan336a0002010-07-17 00:43:37 +00001099 else
1100 type_to_use = var_opaque_type;
Chris Lattner24943d22010-06-08 16:52:24 +00001101
1102 if (var_location.get()->GetContextType() == Value::eContextTypeInvalid)
Sean Callanan336a0002010-07-17 00:43:37 +00001103 var_location.get()->SetContext(Value::eContextTypeOpaqueClangQualType, type_to_use);
Chris Lattner24943d22010-06-08 16:52:24 +00001104
1105 if (var_location.get()->GetValueType() == Value::eValueTypeFileAddress)
1106 {
1107 SymbolContext var_sc;
1108 var->CalculateSymbolContext(&var_sc);
Sean Callanan336a0002010-07-17 00:43:37 +00001109
Chris Lattner24943d22010-06-08 16:52:24 +00001110 if (!var_sc.module_sp)
Sean Callanan336a0002010-07-17 00:43:37 +00001111 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001112
1113 ObjectFile *object_file = var_sc.module_sp->GetObjectFile();
1114
1115 if (!object_file)
Sean Callanan336a0002010-07-17 00:43:37 +00001116 return NULL;
1117
Chris Lattner24943d22010-06-08 16:52:24 +00001118 Address so_addr(var_location->GetScalar().ULongLong(), object_file->GetSectionList());
1119
Greg Claytoneea26402010-09-14 23:36:40 +00001120 lldb::addr_t load_addr = so_addr.GetLoadAddress(m_exe_ctx->target);
Chris Lattner24943d22010-06-08 16:52:24 +00001121
1122 var_location->GetScalar() = load_addr;
1123 var_location->SetValueType(Value::eValueTypeLoadAddress);
1124 }
1125
Sean Callananf328c9f2010-07-20 23:31:16 +00001126 if (user_type)
1127 *user_type = TypeFromUser(var_opaque_type, var_ast_context);
Sean Callanan336a0002010-07-17 00:43:37 +00001128
1129 return var_location.release();
1130}
1131
1132void
1133ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001134 Variable* var)
Sean Callanan336a0002010-07-17 00:43:37 +00001135{
1136 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
1137
Sean Callananf328c9f2010-07-20 23:31:16 +00001138 TypeFromUser ut;
1139 TypeFromParser pt;
Sean Callanan336a0002010-07-17 00:43:37 +00001140
1141 Value *var_location = GetVariableValue(*m_exe_ctx,
1142 var,
1143 context.GetASTContext(),
Sean Callananf328c9f2010-07-20 23:31:16 +00001144 &ut,
1145 &pt);
Sean Callanan336a0002010-07-17 00:43:37 +00001146
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001147 NamedDecl *var_decl = context.AddVarDecl(pt.GetOpaqueQualType());
Chris Lattner24943d22010-06-08 16:52:24 +00001148
Sean Callanan8c127202010-08-23 23:09:38 +00001149 ClangExpressionVariable &entity(m_found_entities.VariableAtIndex(m_found_entities.CreateVariable()));
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001150 entity.m_name = context.Name.getAsString();
Sean Callanan8c127202010-08-23 23:09:38 +00001151 entity.m_user_type = ut;
Chris Lattner24943d22010-06-08 16:52:24 +00001152
Sean Callanan8c127202010-08-23 23:09:38 +00001153 entity.EnableParserVars();
1154 entity.m_parser_vars->m_parser_type = pt;
1155 entity.m_parser_vars->m_named_decl = var_decl;
1156 entity.m_parser_vars->m_llvm_value = NULL;
1157 entity.m_parser_vars->m_lldb_value = var_location;
Chris Lattner24943d22010-06-08 16:52:24 +00001158
Sean Callanan810f22d2010-07-16 00:09:46 +00001159 if (log)
Sean Callananf5857a02010-07-31 01:32:05 +00001160 log->Printf("Found variable %s, returned (NamedDecl)%p", context.Name.getAsString().c_str(), var_decl);
Sean Callanan8f0dc342010-06-22 23:46:24 +00001161}
1162
1163void
Sean Callanana48fe162010-08-11 03:57:18 +00001164ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
Sean Callanana6223432010-08-20 01:02:30 +00001165 ClangExpressionVariable *pvar)
Sean Callanana48fe162010-08-11 03:57:18 +00001166{
Sean Callanan45690fe2010-08-30 22:17:16 +00001167 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
1168
Sean Callanana6223432010-08-20 01:02:30 +00001169 TypeFromUser user_type = pvar->m_user_type;
Sean Callanana48fe162010-08-11 03:57:18 +00001170
1171 TypeFromParser parser_type(ClangASTContext::CopyType(context.GetASTContext(),
1172 user_type.GetASTContext(),
1173 user_type.GetOpaqueQualType()),
1174 context.GetASTContext());
1175
Sean Callanan8c127202010-08-23 23:09:38 +00001176 NamedDecl *var_decl = context.AddVarDecl(parser_type.GetOpaqueQualType());
1177
1178 pvar->EnableParserVars();
1179 pvar->m_parser_vars->m_parser_type = parser_type;
1180 pvar->m_parser_vars->m_named_decl = var_decl;
1181 pvar->m_parser_vars->m_llvm_value = NULL;
1182 pvar->m_parser_vars->m_lldb_value = NULL;
Sean Callanan45690fe2010-08-30 22:17:16 +00001183
1184 if (log)
1185 log->Printf("Added pvar %s, returned (NamedDecl)%p", pvar->m_name.c_str(), var_decl);
Sean Callanana48fe162010-08-11 03:57:18 +00001186}
1187
1188void
Sean Callanan8f0dc342010-06-22 23:46:24 +00001189ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
Sean Callanan0fc73582010-07-27 00:55:47 +00001190 Function* fun,
1191 Symbol* symbol)
Sean Callanan8f0dc342010-06-22 23:46:24 +00001192{
Sean Callanan6184dfe2010-06-23 00:47:48 +00001193 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
Sean Callanan8f0dc342010-06-22 23:46:24 +00001194
Sean Callanan0fc73582010-07-27 00:55:47 +00001195 NamedDecl *fun_decl;
Sean Callanan8f0dc342010-06-22 23:46:24 +00001196 std::auto_ptr<Value> fun_location(new Value);
Sean Callanan0fc73582010-07-27 00:55:47 +00001197 const Address *fun_address;
Sean Callanan8f0dc342010-06-22 23:46:24 +00001198
Sean Callanan0fc73582010-07-27 00:55:47 +00001199 // only valid for Functions, not for Symbols
1200 void *fun_opaque_type = NULL;
1201 clang::ASTContext *fun_ast_context = NULL;
1202
1203 if (fun)
1204 {
Sean Callanan55261a12010-09-08 22:38:54 +00001205#define BROKEN_OVERLOADING
1206 // Awaiting a fix on the Clang side
1207#ifndef BROKEN_OVERLOADING
Sean Callanan0fc73582010-07-27 00:55:47 +00001208 Type *fun_type = fun->GetType();
1209
1210 if (!fun_type)
1211 {
1212 if (log)
1213 log->PutCString("Skipped a function because it has no type");
1214 return;
1215 }
1216
Greg Clayton462d4142010-09-29 01:12:09 +00001217 fun_opaque_type = fun_type->GetClangType();
Sean Callanan0fc73582010-07-27 00:55:47 +00001218
1219 if (!fun_opaque_type)
1220 {
1221 if (log)
1222 log->PutCString("Skipped a function because it has no Clang type");
1223 return;
1224 }
1225
1226 fun_address = &fun->GetAddressRange().GetBaseAddress();
1227
1228 TypeList *type_list = fun_type->GetTypeList();
1229 fun_ast_context = type_list->GetClangASTContext().getASTContext();
1230 void *copied_type = ClangASTContext::CopyType(context.GetASTContext(), fun_ast_context, fun_opaque_type);
1231
1232 fun_decl = context.AddFunDecl(copied_type);
Sean Callanan55261a12010-09-08 22:38:54 +00001233#else
1234 fun_address = &fun->GetAddressRange().GetBaseAddress();
1235
1236 fun_decl = context.AddGenericFunDecl();
1237#endif
Sean Callanan0fc73582010-07-27 00:55:47 +00001238 }
1239 else if (symbol)
1240 {
1241 fun_address = &symbol->GetAddressRangeRef().GetBaseAddress();
1242
1243 fun_decl = context.AddGenericFunDecl();
1244 }
1245 else
1246 {
1247 if (log)
1248 log->PutCString("AddOneFunction called with no function and no symbol");
1249 return;
1250 }
1251
Greg Claytoneea26402010-09-14 23:36:40 +00001252 lldb::addr_t load_addr = fun_address->GetLoadAddress(m_exe_ctx->target);
Sean Callanan8f0dc342010-06-22 23:46:24 +00001253 fun_location->SetValueType(Value::eValueTypeLoadAddress);
1254 fun_location->GetScalar() = load_addr;
1255
Sean Callanan8c127202010-08-23 23:09:38 +00001256 ClangExpressionVariable &entity(m_found_entities.VariableAtIndex(m_found_entities.CreateVariable()));
1257 entity.m_name = context.Name.getAsString();
1258 entity.m_user_type = TypeFromUser(fun_opaque_type, fun_ast_context);;
Sean Callanan8f0dc342010-06-22 23:46:24 +00001259
Sean Callanan8c127202010-08-23 23:09:38 +00001260 entity.EnableParserVars();
1261 entity.m_parser_vars->m_named_decl = fun_decl;
1262 entity.m_parser_vars->m_llvm_value = NULL;
1263 entity.m_parser_vars->m_lldb_value = fun_location.release();
1264
Sean Callanan810f22d2010-07-16 00:09:46 +00001265 if (log)
Sean Callanan92aa6662010-09-07 21:49:41 +00001266 log->Printf("Found %s function %s, returned (NamedDecl)%p", (fun ? "specific" : "generic"), context.Name.getAsString().c_str(), fun_decl);
Chris Lattner24943d22010-06-08 16:52:24 +00001267}
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001268
1269void
1270ClangExpressionDeclMap::AddOneType(NameSearchContext &context,
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001271 TypeFromUser &ut,
1272 bool add_method)
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001273{
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001274 clang::ASTContext *parser_ast_context = context.GetASTContext();
1275 clang::ASTContext *user_ast_context = ut.GetASTContext();
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001276
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001277 void *copied_type = ClangASTContext::CopyType(parser_ast_context, user_ast_context, ut.GetOpaqueQualType());
1278
1279 TypeFromParser parser_type(copied_type, parser_ast_context);
1280
1281 if (add_method && ClangASTContext::IsAggregateType(copied_type))
1282 {
1283 void *args[1];
1284
1285 args[0] = ClangASTContext::GetVoidPtrType(parser_ast_context, false);
1286
1287 void *method_type = ClangASTContext::CreateFunctionType (parser_ast_context,
1288 ClangASTContext::GetBuiltInType_void(parser_ast_context),
1289 args,
1290 1,
1291 false,
1292 ClangASTContext::GetTypeQualifiers(copied_type));
Greg Clayton30449d52010-10-01 02:31:07 +00001293
Greg Clayton1d8173f2010-09-24 05:15:53 +00001294 const bool is_virtual = false;
1295 const bool is_static = false;
1296 const bool is_inline = false;
Greg Clayton30449d52010-10-01 02:31:07 +00001297 const bool is_explicit = false;
1298
Greg Clayton1d8173f2010-09-24 05:15:53 +00001299 ClangASTContext::AddMethodToCXXRecordType (parser_ast_context,
1300 copied_type,
1301 "___clang_expr",
1302 method_type,
1303 lldb::eAccessPublic,
1304 is_virtual,
1305 is_static,
Greg Clayton30449d52010-10-01 02:31:07 +00001306 is_inline,
1307 is_explicit);
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001308 }
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001309
1310 context.AddTypeDecl(copied_type);
1311}