blob: 5a32013e39977cde06907458856d358612b9229a [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
Greg Clayton8de27c72010-10-15 22:48:33 +000042ClangExpressionDeclMap::ClangExpressionDeclMap (ExecutionContext *exe_ctx) :
43 m_found_entities (),
44 m_struct_members (),
45 m_exe_ctx (),
46 m_sym_ctx (),
47 m_persistent_vars (NULL),
48 m_struct_alignment (0),
49 m_struct_size (0),
50 m_struct_laid_out (false),
51 m_enable_lookups (false),
52 m_allocated_area (0),
53 m_materialized_location (0),
54 m_result_name (),
55 m_object_pointer_type (),
56 m_lookedup_types ()
Chris Lattner24943d22010-06-08 16:52:24 +000057{
Greg Clayton8de27c72010-10-15 22:48:33 +000058 if (exe_ctx)
59 {
60 m_exe_ctx = *exe_ctx;
61 if (exe_ctx->frame)
62 m_sym_ctx = exe_ctx->frame->GetSymbolContext(lldb::eSymbolContextEverything);
63 if (exe_ctx->process)
64 m_persistent_vars = &exe_ctx->process->GetPersistentVariables();
65 }
Chris Lattner24943d22010-06-08 16:52:24 +000066}
67
68ClangExpressionDeclMap::~ClangExpressionDeclMap()
Sean Callanan8c127202010-08-23 23:09:38 +000069{
70 for (uint64_t entity_index = 0, num_entities = m_found_entities.Size();
71 entity_index < num_entities;
72 ++entity_index)
73 {
74 ClangExpressionVariable &entity(m_found_entities.VariableAtIndex(entity_index));
75 if (entity.m_parser_vars.get() &&
76 entity.m_parser_vars->m_lldb_value)
77 delete entity.m_parser_vars->m_lldb_value;
Sean Callanan45690fe2010-08-30 22:17:16 +000078
79 entity.DisableParserVars();
80 }
81
82 for (uint64_t pvar_index = 0, num_pvars = m_persistent_vars->Size();
83 pvar_index < num_pvars;
84 ++pvar_index)
85 {
86 ClangExpressionVariable &pvar(m_persistent_vars->VariableAtIndex(pvar_index));
87 pvar.DisableParserVars();
Sean Callanan8c127202010-08-23 23:09:38 +000088 }
Chris Lattner24943d22010-06-08 16:52:24 +000089
Sean Callanan7a60b942010-10-08 01:58:41 +000090 if (m_materialized_location)
91 {
Greg Clayton8de27c72010-10-15 22:48:33 +000092 m_exe_ctx.process->DeallocateMemory(m_materialized_location);
Sean Callanan7a60b942010-10-08 01:58:41 +000093 m_materialized_location = 0;
94 }
Chris Lattner24943d22010-06-08 16:52:24 +000095}
96
Sean Callanan8bce6652010-07-13 21:41:46 +000097// Interface for IRForTarget
98
Greg Clayton8de27c72010-10-15 22:48:33 +000099const ConstString &
100ClangExpressionDeclMap::GetPersistentResultName ()
Sean Callanan82b74c82010-08-12 01:56:52 +0000101{
Greg Clayton8de27c72010-10-15 22:48:33 +0000102 if (!m_result_name)
103 m_persistent_vars->GetNextResultName(m_result_name);
104 return m_result_name;
Sean Callanan82b74c82010-08-12 01:56:52 +0000105}
106
Sean Callanan8bce6652010-07-13 21:41:46 +0000107bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000108ClangExpressionDeclMap::AddPersistentVariable
109(
110 const clang::NamedDecl *decl,
111 const ConstString &name,
112 TypeFromParser parser_type
113)
Sean Callanana48fe162010-08-11 03:57:18 +0000114{
Greg Clayton8de27c72010-10-15 22:48:33 +0000115 clang::ASTContext *context(m_exe_ctx.target->GetScratchClangASTContext()->getASTContext());
Sean Callanana48fe162010-08-11 03:57:18 +0000116
Sean Callanana48fe162010-08-11 03:57:18 +0000117 TypeFromUser user_type(ClangASTContext::CopyType(context,
Sean Callanan82b74c82010-08-12 01:56:52 +0000118 parser_type.GetASTContext(),
119 parser_type.GetOpaqueQualType()),
Sean Callanana48fe162010-08-11 03:57:18 +0000120 context);
121
Sean Callanan8c127202010-08-23 23:09:38 +0000122 if (!m_persistent_vars->CreatePersistentVariable (name, user_type))
123 return false;
124
125 ClangExpressionVariable *var = m_persistent_vars->GetVariable(name);
126
127 if (!var)
128 return false;
129
130 var->EnableParserVars();
131
132 var->m_parser_vars->m_named_decl = decl;
133 var->m_parser_vars->m_parser_type = parser_type;
134
135 return true;
Sean Callanana48fe162010-08-11 03:57:18 +0000136}
137
138bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000139ClangExpressionDeclMap::AddValueToStruct
140(
141 const clang::NamedDecl *decl,
142 const ConstString &name,
143 llvm::Value *value,
144 size_t size,
145 off_t alignment
146)
Sean Callanan8bce6652010-07-13 21:41:46 +0000147{
Sean Callanan45690fe2010-08-30 22:17:16 +0000148 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
149
Sean Callanan8bce6652010-07-13 21:41:46 +0000150 m_struct_laid_out = false;
151
Sean Callanan8c127202010-08-23 23:09:38 +0000152 if (m_struct_members.GetVariable(decl))
153 return true;
Sean Callanan8bce6652010-07-13 21:41:46 +0000154
Sean Callanan8c127202010-08-23 23:09:38 +0000155 ClangExpressionVariable *var = m_found_entities.GetVariable(decl);
Sean Callanan8bce6652010-07-13 21:41:46 +0000156
Sean Callanan8c127202010-08-23 23:09:38 +0000157 if (!var)
158 var = m_persistent_vars->GetVariable(decl);
Sean Callanan8bce6652010-07-13 21:41:46 +0000159
Sean Callanan8c127202010-08-23 23:09:38 +0000160 if (!var)
161 return false;
162
Sean Callanan45690fe2010-08-30 22:17:16 +0000163 if (log)
164 log->Printf("Adding value for decl %p [%s - %s] to the structure",
165 decl,
Greg Clayton8de27c72010-10-15 22:48:33 +0000166 name.GetCString(),
167 var->m_name.GetCString());
Sean Callanan45690fe2010-08-30 22:17:16 +0000168
Sean Callanan8c127202010-08-23 23:09:38 +0000169 // We know entity->m_parser_vars is valid because we used a parser variable
170 // to find it
171 var->m_parser_vars->m_llvm_value = value;
172
173 var->EnableJITVars();
174 var->m_jit_vars->m_alignment = alignment;
175 var->m_jit_vars->m_size = size;
176
177 m_struct_members.AddVariable(*var);
Sean Callanan8bce6652010-07-13 21:41:46 +0000178
179 return true;
180}
181
182bool
183ClangExpressionDeclMap::DoStructLayout ()
184{
185 if (m_struct_laid_out)
186 return true;
187
Sean Callanan8bce6652010-07-13 21:41:46 +0000188 off_t cursor = 0;
189
190 m_struct_alignment = 0;
191 m_struct_size = 0;
192
Sean Callanan8c127202010-08-23 23:09:38 +0000193 for (uint64_t member_index = 0, num_members = m_struct_members.Size();
194 member_index < num_members;
195 ++member_index)
Sean Callanan8bce6652010-07-13 21:41:46 +0000196 {
Sean Callanan8c127202010-08-23 23:09:38 +0000197 ClangExpressionVariable &member(m_struct_members.VariableAtIndex(member_index));
Sean Callanan8bce6652010-07-13 21:41:46 +0000198
Sean Callanan8c127202010-08-23 23:09:38 +0000199 if (!member.m_jit_vars.get())
200 return false;
Sean Callanan8bce6652010-07-13 21:41:46 +0000201
Sean Callanan8c127202010-08-23 23:09:38 +0000202 if (member_index == 0)
203 m_struct_alignment = member.m_jit_vars->m_alignment;
204
205 if (cursor % member.m_jit_vars->m_alignment)
206 cursor += (member.m_jit_vars->m_alignment - (cursor % member.m_jit_vars->m_alignment));
207
208 member.m_jit_vars->m_offset = cursor;
209 cursor += member.m_jit_vars->m_size;
Sean Callanan8bce6652010-07-13 21:41:46 +0000210 }
211
212 m_struct_size = cursor;
213
214 m_struct_laid_out = true;
215 return true;
216}
217
Greg Clayton8de27c72010-10-15 22:48:33 +0000218bool ClangExpressionDeclMap::GetStructInfo
219(
220 uint32_t &num_elements,
221 size_t &size,
222 off_t &alignment
223)
Sean Callanan8bce6652010-07-13 21:41:46 +0000224{
225 if (!m_struct_laid_out)
226 return false;
227
Sean Callanan8c127202010-08-23 23:09:38 +0000228 num_elements = m_struct_members.Size();
Sean Callanan8bce6652010-07-13 21:41:46 +0000229 size = m_struct_size;
230 alignment = m_struct_alignment;
231
232 return true;
233}
234
235bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000236ClangExpressionDeclMap::GetStructElement
237(
238 const clang::NamedDecl *&decl,
239 llvm::Value *&value,
240 off_t &offset,
241 ConstString &name,
242 uint32_t index
243)
Sean Callanan8bce6652010-07-13 21:41:46 +0000244{
245 if (!m_struct_laid_out)
246 return false;
247
Sean Callanan8c127202010-08-23 23:09:38 +0000248 if (index >= m_struct_members.Size())
Sean Callanan8bce6652010-07-13 21:41:46 +0000249 return false;
250
Sean Callanan8c127202010-08-23 23:09:38 +0000251 ClangExpressionVariable &member(m_struct_members.VariableAtIndex(index));
Sean Callanan8bce6652010-07-13 21:41:46 +0000252
Sean Callanan8c127202010-08-23 23:09:38 +0000253 if (!member.m_parser_vars.get() ||
254 !member.m_jit_vars.get())
255 return false;
256
257 decl = member.m_parser_vars->m_named_decl;
258 value = member.m_parser_vars->m_llvm_value;
259 offset = member.m_jit_vars->m_offset;
Greg Clayton8de27c72010-10-15 22:48:33 +0000260 name = member.m_name;
Sean Callanan8c127202010-08-23 23:09:38 +0000261
Sean Callanan8bce6652010-07-13 21:41:46 +0000262 return true;
263}
264
Sean Callanan02fbafa2010-07-27 21:39:39 +0000265bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000266ClangExpressionDeclMap::GetFunctionInfo
267(
268 const clang::NamedDecl *decl,
269 llvm::Value**& value,
270 uint64_t &ptr
271)
Sean Callananba992c52010-07-27 02:07:53 +0000272{
Sean Callanan8c127202010-08-23 23:09:38 +0000273 ClangExpressionVariable *entity = m_found_entities.GetVariable(decl);
274
275 if (!entity)
276 return false;
Sean Callananba992c52010-07-27 02:07:53 +0000277
Sean Callanan8c127202010-08-23 23:09:38 +0000278 // We know m_parser_vars is valid since we searched for the variable by
279 // its NamedDecl
Sean Callananba992c52010-07-27 02:07:53 +0000280
Sean Callanan8c127202010-08-23 23:09:38 +0000281 value = &entity->m_parser_vars->m_llvm_value;
282 ptr = entity->m_parser_vars->m_lldb_value->GetScalar().ULongLong();
283
284 return true;
Sean Callananba992c52010-07-27 02:07:53 +0000285}
286
Sean Callananf5857a02010-07-31 01:32:05 +0000287bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000288ClangExpressionDeclMap::GetFunctionAddress
289(
290 const ConstString &name,
291 uint64_t &ptr
292)
Sean Callananf5857a02010-07-31 01:32:05 +0000293{
294 // Back out in all cases where we're not fully initialized
Greg Clayton8de27c72010-10-15 22:48:33 +0000295 if (m_exe_ctx.frame == NULL)
Sean Callananf5857a02010-07-31 01:32:05 +0000296 return false;
297
Sean Callananf5857a02010-07-31 01:32:05 +0000298 SymbolContextList sym_ctxs;
299
Greg Clayton8de27c72010-10-15 22:48:33 +0000300 m_sym_ctx.FindFunctionsByName(name, false, sym_ctxs);
Sean Callananf5857a02010-07-31 01:32:05 +0000301
302 if (!sym_ctxs.GetSize())
303 return false;
304
305 SymbolContext sym_ctx;
306 sym_ctxs.GetContextAtIndex(0, sym_ctx);
307
308 const Address *fun_address;
309
310 if (sym_ctx.function)
311 fun_address = &sym_ctx.function->GetAddressRange().GetBaseAddress();
312 else if (sym_ctx.symbol)
313 fun_address = &sym_ctx.symbol->GetAddressRangeRef().GetBaseAddress();
314 else
315 return false;
316
Greg Clayton8de27c72010-10-15 22:48:33 +0000317 ptr = fun_address->GetLoadAddress (m_exe_ctx.target);
Sean Callananf5857a02010-07-31 01:32:05 +0000318
319 return true;
320}
321
Sean Callanan810f22d2010-07-16 00:09:46 +0000322// Interface for CommandObjectExpression
Sean Callananf328c9f2010-07-20 23:31:16 +0000323
324bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000325ClangExpressionDeclMap::Materialize
326(
327 ExecutionContext *exe_ctx,
328 lldb::addr_t &struct_address,
329 Error &err
330)
Sean Callananf328c9f2010-07-20 23:31:16 +0000331{
332 bool result = DoMaterialize(false, exe_ctx, NULL, err);
333
334 if (result)
335 struct_address = m_materialized_location;
336
337 return result;
338}
339
340bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000341ClangExpressionDeclMap::GetObjectPointer
342(
343 lldb::addr_t &object_ptr,
344 ExecutionContext *exe_ctx,
345 Error &err
346)
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000347{
348 if (!exe_ctx || !exe_ctx->frame || !exe_ctx->target || !exe_ctx->process)
349 {
350 err.SetErrorString("Couldn't load 'this' because the context is incomplete");
351 return false;
352 }
353
354 if (!m_object_pointer_type.GetOpaqueQualType())
355 {
356 err.SetErrorString("Couldn't load 'this' because its type is unknown");
357 return false;
358 }
359
Greg Clayton8de27c72010-10-15 22:48:33 +0000360 static ConstString g_this_cs ("this");
361 Variable *object_ptr_var = FindVariableInScope(*exe_ctx->frame, g_this_cs, &m_object_pointer_type);
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000362
363 if (!object_ptr_var)
364 {
365 err.SetErrorString("Couldn't find 'this' with appropriate type in scope");
366 return false;
367 }
368
369 std::auto_ptr<lldb_private::Value> location_value(GetVariableValue(*exe_ctx,
370 object_ptr_var,
371 m_object_pointer_type.GetASTContext()));
372
373 if (!location_value.get())
374 {
375 err.SetErrorString("Couldn't get the location for 'this'");
376 return false;
377 }
378
379 if (location_value->GetValueType() == Value::eValueTypeLoadAddress)
380 {
381 lldb::addr_t value_addr = location_value->GetScalar().ULongLong();
382 uint32_t address_byte_size = exe_ctx->target->GetArchitecture().GetAddressByteSize();
383 lldb::ByteOrder address_byte_order = exe_ctx->process->GetByteOrder();
384
385 if (ClangASTType::GetClangTypeBitWidth(m_object_pointer_type.GetASTContext(), m_object_pointer_type.GetOpaqueQualType()) != address_byte_size * 8)
386 {
387 err.SetErrorStringWithFormat("'this' is not of an expected pointer size");
388 return false;
389 }
390
391 DataBufferHeap data;
392 data.SetByteSize(address_byte_size);
393 Error read_error;
394
395 if (exe_ctx->process->ReadMemory (value_addr, data.GetBytes(), address_byte_size, read_error) != address_byte_size)
396 {
397 err.SetErrorStringWithFormat("Coldn't read 'this' from the target: %s", read_error.AsCString());
398 return false;
399 }
400
401 DataExtractor extractor(data.GetBytes(), data.GetByteSize(), address_byte_order, address_byte_size);
402
403 uint32_t offset = 0;
404
405 object_ptr = extractor.GetPointer(&offset);
406
407 return true;
408 }
409 else
410 {
411 err.SetErrorString("'this' is not in memory; LLDB must be extended to handle registers");
412 return false;
413 }
414}
415
416bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000417ClangExpressionDeclMap::Dematerialize
418(
419 ExecutionContext *exe_ctx,
420 ClangExpressionVariable *&result,
421 Error &err
422)
Sean Callananf328c9f2010-07-20 23:31:16 +0000423{
Sean Callanan82b74c82010-08-12 01:56:52 +0000424 return DoMaterialize(true, exe_ctx, &result, err);
Sean Callananf328c9f2010-07-20 23:31:16 +0000425}
426
Sean Callanan32824aa2010-07-23 22:19:18 +0000427bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000428ClangExpressionDeclMap::DumpMaterializedStruct
429(
430 ExecutionContext *exe_ctx,
431 Stream &s,
432 Error &err
433)
Sean Callanan32824aa2010-07-23 22:19:18 +0000434{
435 if (!m_struct_laid_out)
436 {
437 err.SetErrorString("Structure hasn't been laid out yet");
438 return false;
439 }
440
441 if (!exe_ctx)
442 {
443 err.SetErrorString("Received null execution context");
444 return false;
445 }
446
447
448 if (!exe_ctx->process)
449 {
450 err.SetErrorString("Couldn't find the process");
451 return false;
452 }
453
454 if (!exe_ctx->target)
455 {
456 err.SetErrorString("Couldn't find the target");
457 return false;
458 }
459
460 lldb::DataBufferSP data(new DataBufferHeap(m_struct_size, 0));
461
462 Error error;
463 if (exe_ctx->process->ReadMemory (m_materialized_location, data->GetBytes(), data->GetByteSize(), error) != data->GetByteSize())
464 {
465 err.SetErrorStringWithFormat ("Couldn't read struct from the target: %s", error.AsCString());
466 return false;
467 }
468
469 DataExtractor extractor(data, exe_ctx->process->GetByteOrder(), exe_ctx->target->GetArchitecture().GetAddressByteSize());
470
Sean Callanan8c127202010-08-23 23:09:38 +0000471 for (uint64_t member_index = 0, num_members = m_struct_members.Size();
472 member_index < num_members;
473 ++member_index)
Sean Callanan32824aa2010-07-23 22:19:18 +0000474 {
Sean Callanan8c127202010-08-23 23:09:38 +0000475 ClangExpressionVariable &member (m_struct_members.VariableAtIndex(member_index));
Sean Callanan32824aa2010-07-23 22:19:18 +0000476
Greg Clayton8de27c72010-10-15 22:48:33 +0000477 s.Printf("[%s]\n", member.m_name.GetCString());
Sean Callanan8c127202010-08-23 23:09:38 +0000478
479 if (!member.m_jit_vars.get())
480 return false;
481
482 extractor.Dump(&s, // stream
483 member.m_jit_vars->m_offset, // offset
484 lldb::eFormatBytesWithASCII, // format
485 1, // byte size of individual entries
486 member.m_jit_vars->m_size, // number of entries
487 16, // entries per line
488 m_materialized_location + member.m_jit_vars->m_offset, // address to print
489 0, // bit size (bitfields only; 0 means ignore)
490 0); // bit alignment (bitfields only; 0 means ignore)
Sean Callanan32824aa2010-07-23 22:19:18 +0000491
492 s.PutChar('\n');
493 }
494
495 return true;
496}
497
Sean Callananf328c9f2010-07-20 23:31:16 +0000498bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000499ClangExpressionDeclMap::DoMaterialize
500(
501 bool dematerialize,
502 ExecutionContext *exe_ctx,
503 ClangExpressionVariable **result,
504 Error &err
505)
Sean Callanan810f22d2010-07-16 00:09:46 +0000506{
Sean Callanan336a0002010-07-17 00:43:37 +0000507 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
Sean Callanan82b74c82010-08-12 01:56:52 +0000508
Sean Callanan810f22d2010-07-16 00:09:46 +0000509 if (!m_struct_laid_out)
510 {
511 err.SetErrorString("Structure hasn't been laid out yet");
512 return LLDB_INVALID_ADDRESS;
513 }
514
Sean Callanan810f22d2010-07-16 00:09:46 +0000515 if (!exe_ctx)
516 {
517 err.SetErrorString("Received null execution context");
518 return LLDB_INVALID_ADDRESS;
519 }
520
Sean Callanan45839272010-07-24 01:37:44 +0000521 if (!exe_ctx->frame)
522 {
523 err.SetErrorString("Received null execution frame");
524 return LLDB_INVALID_ADDRESS;
525 }
526
Sean Callanane8a59a82010-09-13 21:34:21 +0000527 if (!m_struct_size)
528 {
529 if (log)
530 log->PutCString("Not bothering to allocate a struct because no arguments are needed");
531
532 m_allocated_area = NULL;
533
534 return true;
535 }
536
Sean Callanan810f22d2010-07-16 00:09:46 +0000537 const SymbolContext &sym_ctx(exe_ctx->frame->GetSymbolContext(lldb::eSymbolContextEverything));
538
Sean Callananf328c9f2010-07-20 23:31:16 +0000539 if (!dematerialize)
Sean Callanan810f22d2010-07-16 00:09:46 +0000540 {
Sean Callananf328c9f2010-07-20 23:31:16 +0000541 if (m_materialized_location)
542 {
543 exe_ctx->process->DeallocateMemory(m_materialized_location);
544 m_materialized_location = 0;
545 }
546
Sean Callanan7a60b942010-10-08 01:58:41 +0000547 if (log)
548 log->PutCString("Allocating memory for materialized argument struct");
549
Sean Callananf328c9f2010-07-20 23:31:16 +0000550 lldb::addr_t mem = exe_ctx->process->AllocateMemory(m_struct_alignment + m_struct_size,
551 lldb::ePermissionsReadable | lldb::ePermissionsWritable,
552 err);
553
554 if (mem == LLDB_INVALID_ADDRESS)
555 return false;
556
557 m_allocated_area = mem;
Sean Callanan810f22d2010-07-16 00:09:46 +0000558 }
559
Sean Callananf328c9f2010-07-20 23:31:16 +0000560 m_materialized_location = m_allocated_area;
561
562 if (m_materialized_location % m_struct_alignment)
Sean Callananf328c9f2010-07-20 23:31:16 +0000563 m_materialized_location += (m_struct_alignment - (m_materialized_location % m_struct_alignment));
Sean Callananf328c9f2010-07-20 23:31:16 +0000564
Sean Callanan8c127202010-08-23 23:09:38 +0000565 for (uint64_t member_index = 0, num_members = m_struct_members.Size();
566 member_index < num_members;
567 ++member_index)
Sean Callanan810f22d2010-07-16 00:09:46 +0000568 {
Sean Callanan8c127202010-08-23 23:09:38 +0000569 ClangExpressionVariable &member (m_struct_members.VariableAtIndex(member_index));
Sean Callanan810f22d2010-07-16 00:09:46 +0000570
Sean Callanan8c127202010-08-23 23:09:38 +0000571 if (!member.m_parser_vars.get())
Sean Callanan336a0002010-07-17 00:43:37 +0000572 return false;
Sean Callanan8c127202010-08-23 23:09:38 +0000573
574 ClangExpressionVariable *entity = m_found_entities.GetVariable(member.m_parser_vars->m_named_decl);
Greg Clayton8de27c72010-10-15 22:48:33 +0000575 ClangExpressionVariable *persistent_variable = m_persistent_vars->GetVariable(member.m_name);
Sean Callanan8c127202010-08-23 23:09:38 +0000576
577 if (entity)
578 {
579 if (!member.m_jit_vars.get())
580 return false;
581
Greg Clayton8de27c72010-10-15 22:48:33 +0000582 if (!DoMaterializeOneVariable(dematerialize, *exe_ctx, sym_ctx, member.m_name, member.m_user_type, m_materialized_location + member.m_jit_vars->m_offset, err))
Sean Callanan8c127202010-08-23 23:09:38 +0000583 return false;
584 }
585 else if (persistent_variable)
586 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000587 if (member.m_name == m_result_name)
Sean Callanan45690fe2010-08-30 22:17:16 +0000588 {
589 if (!dematerialize)
590 continue;
Sean Callanan8c127202010-08-23 23:09:38 +0000591
Sean Callanan8c127202010-08-23 23:09:38 +0000592 if (log)
593 log->PutCString("Found result member in the struct");
Sean Callanan45690fe2010-08-30 22:17:16 +0000594
Sean Callanan8c127202010-08-23 23:09:38 +0000595 *result = &member;
596 }
597
Sean Callanan45690fe2010-08-30 22:17:16 +0000598 if (log)
Greg Clayton8de27c72010-10-15 22:48:33 +0000599 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 +0000600
Greg Clayton8de27c72010-10-15 22:48:33 +0000601 if (!DoMaterializeOnePersistentVariable(dematerialize, *exe_ctx, persistent_variable->m_name, m_materialized_location + member.m_jit_vars->m_offset, err))
Sean Callanan8c127202010-08-23 23:09:38 +0000602 return false;
603 }
604 else
605 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000606 err.SetErrorStringWithFormat("Unexpected variable %s", member.m_name.GetCString());
Sean Callanan8c127202010-08-23 23:09:38 +0000607 return false;
608 }
Sean Callanan810f22d2010-07-16 00:09:46 +0000609 }
610
Sean Callananf328c9f2010-07-20 23:31:16 +0000611 return true;
612}
613
Sean Callanana48fe162010-08-11 03:57:18 +0000614bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000615ClangExpressionDeclMap::DoMaterializeOnePersistentVariable
616(
617 bool dematerialize,
618 ExecutionContext &exe_ctx,
619 const ConstString &name,
620 lldb::addr_t addr,
621 Error &err
622)
Sean Callanan45690fe2010-08-30 22:17:16 +0000623{
Sean Callanana6223432010-08-20 01:02:30 +0000624 ClangExpressionVariable *pvar(m_persistent_vars->GetVariable(name));
Sean Callanana48fe162010-08-11 03:57:18 +0000625
626 if (!pvar)
627 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000628 err.SetErrorStringWithFormat("Undefined persistent variable %s", name.GetCString());
Sean Callanana48fe162010-08-11 03:57:18 +0000629 return LLDB_INVALID_ADDRESS;
630 }
631
632 size_t pvar_size = pvar->Size();
Sean Callanana6223432010-08-20 01:02:30 +0000633
Greg Clayton66ed2fb2010-10-05 00:00:42 +0000634 if (!pvar->m_data_sp.get())
Sean Callanana6223432010-08-20 01:02:30 +0000635 return false;
636
Greg Clayton66ed2fb2010-10-05 00:00:42 +0000637 uint8_t *pvar_data = pvar->m_data_sp->GetBytes();
Sean Callanana48fe162010-08-11 03:57:18 +0000638 Error error;
639
640 if (dematerialize)
641 {
642 if (exe_ctx.process->ReadMemory (addr, pvar_data, pvar_size, error) != pvar_size)
643 {
644 err.SetErrorStringWithFormat ("Couldn't read a composite type from the target: %s", error.AsCString());
645 return false;
646 }
647 }
648 else
649 {
650 if (exe_ctx.process->WriteMemory (addr, pvar_data, pvar_size, error) != pvar_size)
651 {
652 err.SetErrorStringWithFormat ("Couldn't write a composite type to the target: %s", error.AsCString());
653 return false;
654 }
655 }
656
657 return true;
658}
659
Sean Callananf328c9f2010-07-20 23:31:16 +0000660bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000661ClangExpressionDeclMap::DoMaterializeOneVariable
662(
663 bool dematerialize,
664 ExecutionContext &exe_ctx,
665 const SymbolContext &sym_ctx,
666 const ConstString &name,
667 TypeFromUser type,
668 lldb::addr_t addr,
669 Error &err
670)
Sean Callananf328c9f2010-07-20 23:31:16 +0000671{
672 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
673
Sean Callanan17c6a052010-10-05 20:18:48 +0000674 if (!exe_ctx.frame || !exe_ctx.process)
Sean Callanancc074622010-09-14 21:59:34 +0000675 return false;
676
677 Variable *var = FindVariableInScope(*exe_ctx.frame, name, &type);
Sean Callananf328c9f2010-07-20 23:31:16 +0000678
679 if (!var)
680 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000681 err.SetErrorStringWithFormat("Couldn't find %s with appropriate type", name.GetCString());
Sean Callananf328c9f2010-07-20 23:31:16 +0000682 return false;
683 }
684
Sean Callanan841026f2010-07-23 00:16:21 +0000685 if (log)
Greg Clayton8de27c72010-10-15 22:48:33 +0000686 log->Printf("%s %s with type %p", (dematerialize ? "Dematerializing" : "Materializing"), name.GetCString(), type.GetOpaqueQualType());
Sean Callananf328c9f2010-07-20 23:31:16 +0000687
688 std::auto_ptr<lldb_private::Value> location_value(GetVariableValue(exe_ctx,
689 var,
690 type.GetASTContext()));
691
692 if (!location_value.get())
693 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000694 err.SetErrorStringWithFormat("Couldn't get value for %s", name.GetCString());
Sean Callananf328c9f2010-07-20 23:31:16 +0000695 return false;
696 }
Sean Callanan17c6a052010-10-05 20:18:48 +0000697
698 // The size of the type contained in addr
Sean Callananf328c9f2010-07-20 23:31:16 +0000699
Sean Callanan17c6a052010-10-05 20:18:48 +0000700 size_t addr_bit_size = ClangASTType::GetClangTypeBitWidth(type.GetASTContext(), type.GetOpaqueQualType());
701 size_t addr_byte_size = addr_bit_size % 8 ? ((addr_bit_size + 8) / 8) : (addr_bit_size / 8);
702
703 Value::ValueType value_type = location_value->GetValueType();
704
705 switch (value_type)
Sean Callananf328c9f2010-07-20 23:31:16 +0000706 {
Sean Callanan17c6a052010-10-05 20:18:48 +0000707 default:
Sean Callananf328c9f2010-07-20 23:31:16 +0000708 {
Sean Callanan17c6a052010-10-05 20:18:48 +0000709 StreamString ss;
710
711 location_value->Dump(&ss);
712
Greg Clayton8de27c72010-10-15 22:48:33 +0000713 err.SetErrorStringWithFormat("%s has a value of unhandled type: %s", name.GetCString(), ss.GetString().c_str());
Sean Callananf328c9f2010-07-20 23:31:16 +0000714 return false;
715 }
Sean Callanan17c6a052010-10-05 20:18:48 +0000716 break;
717 case Value::eValueTypeLoadAddress:
Sean Callananf328c9f2010-07-20 23:31:16 +0000718 {
Sean Callanan17c6a052010-10-05 20:18:48 +0000719 lldb::addr_t value_addr = location_value->GetScalar().ULongLong();
720
721 DataBufferHeap data;
722 data.SetByteSize(addr_byte_size);
723
724 lldb::addr_t src_addr;
725 lldb::addr_t dest_addr;
726
727 if (dematerialize)
728 {
729 src_addr = addr;
730 dest_addr = value_addr;
731 }
732 else
733 {
734 src_addr = value_addr;
735 dest_addr = addr;
736 }
737
738 Error error;
739 if (exe_ctx.process->ReadMemory (src_addr, data.GetBytes(), addr_byte_size, error) != addr_byte_size)
740 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000741 err.SetErrorStringWithFormat ("Couldn't read %s from the target: %s", name.GetCString(), error.AsCString());
Sean Callanan17c6a052010-10-05 20:18:48 +0000742 return false;
743 }
744
745 if (exe_ctx.process->WriteMemory (dest_addr, data.GetBytes(), addr_byte_size, error) != addr_byte_size)
746 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000747 err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", name.GetCString(), error.AsCString());
Sean Callanan17c6a052010-10-05 20:18:48 +0000748 return false;
749 }
750
751 if (log)
752 log->Printf("Copied from 0x%llx to 0x%llx", (uint64_t)src_addr, (uint64_t)addr);
Sean Callananf328c9f2010-07-20 23:31:16 +0000753 }
Sean Callanan17c6a052010-10-05 20:18:48 +0000754 break;
755 case Value::eValueTypeScalar:
756 {
757 if (location_value->GetContextType() != Value::eContextTypeDCRegisterInfo)
758 {
759 StreamString ss;
760
761 location_value->Dump(&ss);
762
Greg Clayton8de27c72010-10-15 22:48:33 +0000763 err.SetErrorStringWithFormat("%s is a scalar of unhandled type: %s", name.GetCString(), ss.GetString().c_str());
Sean Callanan17c6a052010-10-05 20:18:48 +0000764 return false;
765 }
766
767 lldb::RegisterInfo *register_info = location_value->GetRegisterInfo();
768
769 if (!register_info)
770 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000771 err.SetErrorStringWithFormat("Couldn't get the register information for %s", name.GetCString());
Sean Callanan17c6a052010-10-05 20:18:48 +0000772 return false;
773 }
774
775 RegisterContext *register_context = exe_ctx.GetRegisterContext();
776
777 if (!register_context)
778 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000779 err.SetErrorStringWithFormat("Couldn't read register context to read %s from %s", name.GetCString(), register_info->name);
Sean Callanan17c6a052010-10-05 20:18:48 +0000780 return false;
781 }
782
783 uint32_t register_number = register_info->kinds[lldb::eRegisterKindLLDB];
784 uint32_t register_byte_size = register_info->byte_size;
785
786 if (dematerialize)
787 {
788 // Moving from addr into a register
789 //
790 // Case 1: addr_byte_size and register_byte_size are the same
791 //
792 // |AABBCCDD| Address contents
793 // |AABBCCDD| Register contents
794 //
795 // Case 2: addr_byte_size is bigger than register_byte_size
796 //
797 // Error! (The register should always be big enough to hold the data)
798 //
799 // Case 3: register_byte_size is bigger than addr_byte_size
800 //
801 // |AABB| Address contents
802 // |AABB0000| Register contents [on little-endian hardware]
803 // |0000AABB| Register contents [on big-endian hardware]
804
805 if (addr_byte_size > register_byte_size)
806 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000807 err.SetErrorStringWithFormat("%s is too big to store in %s", name.GetCString(), register_info->name);
Sean Callanan17c6a052010-10-05 20:18:48 +0000808 return false;
809 }
810
811 uint32_t register_offset;
812
813 switch (exe_ctx.process->GetByteOrder())
814 {
815 default:
Greg Clayton8de27c72010-10-15 22:48:33 +0000816 err.SetErrorStringWithFormat("%s is stored with an unhandled byte order", name.GetCString());
Sean Callanan17c6a052010-10-05 20:18:48 +0000817 return false;
818 case lldb::eByteOrderLittle:
819 register_offset = 0;
820 break;
821 case lldb::eByteOrderBig:
822 register_offset = register_byte_size - addr_byte_size;
823 break;
824 }
825
826 DataBufferHeap register_data (register_byte_size, 0);
827
828 Error error;
829 if (exe_ctx.process->ReadMemory (addr, register_data.GetBytes() + register_offset, addr_byte_size, error) != addr_byte_size)
830 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000831 err.SetErrorStringWithFormat ("Couldn't read %s from the target: %s", name.GetCString(), error.AsCString());
Sean Callanan17c6a052010-10-05 20:18:48 +0000832 return false;
833 }
834
835 DataExtractor register_extractor (register_data.GetBytes(), register_byte_size, exe_ctx.process->GetByteOrder(), exe_ctx.process->GetAddressByteSize());
836
837 if (!register_context->WriteRegisterBytes(register_number, register_extractor, 0))
838 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000839 err.SetErrorStringWithFormat("Couldn't read %s from %s", name.GetCString(), register_info->name);
Sean Callanan17c6a052010-10-05 20:18:48 +0000840 return false;
841 }
842 }
843 else
844 {
845 // Moving from a register into addr
846 //
847 // Case 1: addr_byte_size and register_byte_size are the same
848 //
849 // |AABBCCDD| Register contents
850 // |AABBCCDD| Address contents
851 //
852 // Case 2: addr_byte_size is bigger than register_byte_size
853 //
854 // Error! (The register should always be big enough to hold the data)
855 //
856 // Case 3: register_byte_size is bigger than addr_byte_size
857 //
858 // |AABBCCDD| Register contents
859 // |AABB| Address contents on little-endian hardware
860 // |CCDD| Address contents on big-endian hardware
861
862 if (addr_byte_size > register_byte_size)
863 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000864 err.SetErrorStringWithFormat("%s is too big to store in %s", name.GetCString(), register_info->name);
Sean Callanan17c6a052010-10-05 20:18:48 +0000865 return false;
866 }
867
868 uint32_t register_offset;
869
870 switch (exe_ctx.process->GetByteOrder())
871 {
872 default:
Greg Clayton8de27c72010-10-15 22:48:33 +0000873 err.SetErrorStringWithFormat("%s is stored with an unhandled byte order", name.GetCString());
Sean Callanan17c6a052010-10-05 20:18:48 +0000874 return false;
875 case lldb::eByteOrderLittle:
876 register_offset = 0;
877 break;
878 case lldb::eByteOrderBig:
879 register_offset = register_byte_size - addr_byte_size;
880 break;
881 }
882
883 DataExtractor register_extractor;
884
885 if (!register_context->ReadRegisterBytes(register_number, register_extractor))
886 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000887 err.SetErrorStringWithFormat("Couldn't read %s from %s", name.GetCString(), register_info->name);
Sean Callanan17c6a052010-10-05 20:18:48 +0000888 return false;
889 }
890
891 const void *register_data = register_extractor.GetData(&register_offset, addr_byte_size);
892
893 if (!register_data)
894 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000895 err.SetErrorStringWithFormat("Read but couldn't extract data for %s from %s", name.GetCString(), register_info->name);
Sean Callanan17c6a052010-10-05 20:18:48 +0000896 return false;
897 }
898
899 Error error;
900 if (exe_ctx.process->WriteMemory (addr, register_data, addr_byte_size, error) != addr_byte_size)
901 {
902 err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", error.AsCString());
903 return false;
904 }
905 }
906 }
Sean Callananf328c9f2010-07-20 23:31:16 +0000907 }
908
909 return true;
Sean Callanan810f22d2010-07-16 00:09:46 +0000910}
911
Sean Callanancc074622010-09-14 21:59:34 +0000912Variable *
Greg Clayton8de27c72010-10-15 22:48:33 +0000913ClangExpressionDeclMap::FindVariableInScope
914(
915 StackFrame &frame,
916 const ConstString &name,
917 TypeFromUser *type
918)
Sean Callanancc074622010-09-14 21:59:34 +0000919{
920 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
921
Sean Callanancc074622010-09-14 21:59:34 +0000922 VariableList *var_list = frame.GetVariableList(true);
923
Greg Claytonbf8e42b2010-10-14 22:52:14 +0000924 if (!var_list)
925 return NULL;
926
Greg Clayton8de27c72010-10-15 22:48:33 +0000927 lldb::VariableSP var = var_list->FindVariable(name);
Sean Callanancc074622010-09-14 21:59:34 +0000928
929 if (!var)
930 return NULL;
931
932 if (!type)
933 return var.get();
934
935 if (type->GetASTContext() == var->GetType()->GetClangAST())
936 {
Greg Clayton462d4142010-09-29 01:12:09 +0000937 if (!ClangASTContext::AreTypesSame(type->GetASTContext(), type->GetOpaqueQualType(), var->GetType()->GetClangType()))
Sean Callanancc074622010-09-14 21:59:34 +0000938 return NULL;
939 }
940 else
941 {
942 if (log)
943 log->PutCString("Skipping a candidate variable because of different AST contexts");
944 return NULL;
945 }
946
947 return var.get();
948
949 return NULL;
950}
Sean Callanan336a0002010-07-17 00:43:37 +0000951
Chris Lattner24943d22010-06-08 16:52:24 +0000952// Interface for ClangASTSource
953void
Greg Clayton8de27c72010-10-15 22:48:33 +0000954ClangExpressionDeclMap::GetDecls
955(
956 NameSearchContext &context,
957 const ConstString &name
958)
Chris Lattner24943d22010-06-08 16:52:24 +0000959{
Sean Callanan6184dfe2010-06-23 00:47:48 +0000960 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000961
Sean Callanan810f22d2010-07-16 00:09:46 +0000962 if (log)
Greg Clayton8de27c72010-10-15 22:48:33 +0000963 log->Printf("Hunting for a definition for '%s'", name.GetCString());
Chris Lattner24943d22010-06-08 16:52:24 +0000964
965 // Back out in all cases where we're not fully initialized
Greg Clayton8de27c72010-10-15 22:48:33 +0000966 if (m_exe_ctx.frame == NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000967 return;
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000968
Greg Clayton8de27c72010-10-15 22:48:33 +0000969 static ConstString g_lldb_class_name ("$__lldb_class");
970 if (name == g_lldb_class_name)
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000971 {
972 // Clang is looking for the type of "this"
973
Greg Clayton8de27c72010-10-15 22:48:33 +0000974 VariableList *vars = m_exe_ctx.frame->GetVariableList(false);
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000975
976 if (!vars)
977 return;
978
979 lldb::VariableSP this_var = vars->FindVariable(ConstString("this"));
980
981 if (!this_var)
982 return;
983
984 Type *this_type = this_var->GetType();
985
986 if (!this_type)
987 return;
988
Greg Clayton462d4142010-09-29 01:12:09 +0000989 TypeFromUser this_user_type(this_type->GetClangType(),
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000990 this_type->GetClangAST());
991
992 m_object_pointer_type = this_user_type;
993
994 void *pointer_target_type;
995
996 if (!ClangASTContext::IsPointerType(this_user_type.GetOpaqueQualType(),
997 &pointer_target_type))
998 return;
999
1000 TypeFromUser class_user_type(pointer_target_type,
1001 this_type->GetClangAST());
1002
1003 AddOneType(context, class_user_type, true);
1004
1005 return;
1006 }
1007
Sean Callanan0fc73582010-07-27 00:55:47 +00001008 SymbolContextList sym_ctxs;
Chris Lattner24943d22010-06-08 16:52:24 +00001009
Greg Clayton8de27c72010-10-15 22:48:33 +00001010 // Only look for functions by name out in our symbols if the function
1011 // doesn't start with our phony prefix of '$'
1012 if (name.GetCString()[0] != '$')
Sean Callanan0fc73582010-07-27 00:55:47 +00001013 {
Greg Clayton8de27c72010-10-15 22:48:33 +00001014
1015 Variable *var = FindVariableInScope(*m_exe_ctx.frame, name);
1016
1017 // If we found a variable in scope, no need to pull up function names
1018 if (var != NULL)
1019 {
1020 AddOneVariable(context, var);
1021 }
1022 else
1023 {
1024 m_sym_ctx.FindFunctionsByName (name, false, sym_ctxs);
1025
1026 bool found_specific = false;
1027 Symbol *generic_symbol = NULL;
1028 Symbol *non_extern_symbol = NULL;
1029
1030 for (uint32_t index = 0, num_indices = sym_ctxs.GetSize();
1031 index < num_indices;
1032 ++index)
1033 {
1034 SymbolContext sym_ctx;
1035 sym_ctxs.GetContextAtIndex(index, sym_ctx);
Sean Callanan3cfbd332010-10-06 00:10:07 +00001036
Greg Clayton8de27c72010-10-15 22:48:33 +00001037 if (sym_ctx.function)
1038 {
1039 // TODO only do this if it's a C function; C++ functions may be
1040 // overloaded
1041 if (!found_specific)
1042 AddOneFunction(context, sym_ctx.function, NULL);
1043 found_specific = true;
1044 }
1045 else if (sym_ctx.symbol)
1046 {
1047 if (sym_ctx.symbol->IsExternal())
1048 generic_symbol = sym_ctx.symbol;
1049 else
1050 non_extern_symbol = sym_ctx.symbol;
1051 }
1052 }
1053
Sean Callanan92aa6662010-09-07 21:49:41 +00001054 if (!found_specific)
Greg Clayton8de27c72010-10-15 22:48:33 +00001055 {
1056 if (generic_symbol)
1057 AddOneFunction(context, NULL, generic_symbol);
1058 else if (non_extern_symbol)
1059 AddOneFunction(context, NULL, non_extern_symbol);
1060 }
Sean Callanan92aa6662010-09-07 21:49:41 +00001061 }
Sean Callanan0fc73582010-07-27 00:55:47 +00001062 }
Greg Clayton8de27c72010-10-15 22:48:33 +00001063 else
Sean Callanan3cfbd332010-10-06 00:10:07 +00001064 {
Greg Clayton8de27c72010-10-15 22:48:33 +00001065 ClangExpressionVariable *pvar(m_persistent_vars->GetVariable(name));
1066
1067 if (pvar)
1068 AddOneVariable(context, pvar);
Sean Callanan3cfbd332010-10-06 00:10:07 +00001069 }
1070
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001071
Sean Callanan6df08402010-09-27 23:54:58 +00001072 // See information on gating of this operation next to the definition for
1073 // m_lookedup_types.
1074
Greg Clayton8de27c72010-10-15 22:48:33 +00001075 const char *name_uniq = name.GetCString();
Sean Callanan6df08402010-09-27 23:54:58 +00001076
1077 if (m_lookedup_types.find(name_uniq) == m_lookedup_types.end())
1078 {
1079 // 1 The name is added to m_lookedup_types.
1080 m_lookedup_types.insert(std::pair<const char*, bool>(name_uniq, true));
1081
1082 // 2 The type is looked up and added, potentially causing more type loookups.
Greg Clayton8de27c72010-10-15 22:48:33 +00001083 lldb::TypeSP type = m_sym_ctx.FindTypeByName (name);
Sean Callanan6df08402010-09-27 23:54:58 +00001084
1085 if (type.get())
1086 {
Greg Clayton462d4142010-09-29 01:12:09 +00001087 TypeFromUser user_type(type->GetClangType(),
Sean Callanan6df08402010-09-27 23:54:58 +00001088 type->GetClangAST());
1089
1090 AddOneType(context, user_type, false);
1091 }
1092
1093 // 3 The name is removed from m_lookedup_types.
1094 m_lookedup_types.erase(name_uniq);
1095 }
Sean Callanan336a0002010-07-17 00:43:37 +00001096}
1097
1098Value *
Greg Clayton8de27c72010-10-15 22:48:33 +00001099ClangExpressionDeclMap::GetVariableValue
1100(
1101 ExecutionContext &exe_ctx,
1102 Variable *var,
1103 clang::ASTContext *parser_ast_context,
1104 TypeFromUser *user_type,
1105 TypeFromParser *parser_type
1106)
Chris Lattner24943d22010-06-08 16:52:24 +00001107{
Sean Callanan6184dfe2010-06-23 00:47:48 +00001108 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
1109
Chris Lattner24943d22010-06-08 16:52:24 +00001110 Type *var_type = var->GetType();
1111
1112 if (!var_type)
1113 {
Sean Callanan810f22d2010-07-16 00:09:46 +00001114 if (log)
1115 log->PutCString("Skipped a definition because it has no type");
Sean Callanan336a0002010-07-17 00:43:37 +00001116 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001117 }
1118
Greg Clayton462d4142010-09-29 01:12:09 +00001119 void *var_opaque_type = var_type->GetClangType();
Chris Lattner24943d22010-06-08 16:52:24 +00001120
1121 if (!var_opaque_type)
1122 {
Sean Callanan810f22d2010-07-16 00:09:46 +00001123 if (log)
1124 log->PutCString("Skipped a definition because it has no Clang type");
Sean Callanan336a0002010-07-17 00:43:37 +00001125 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001126 }
1127
Chris Lattner24943d22010-06-08 16:52:24 +00001128 TypeList *type_list = var_type->GetTypeList();
1129
1130 if (!type_list)
1131 {
Sean Callanan810f22d2010-07-16 00:09:46 +00001132 if (log)
1133 log->PutCString("Skipped a definition because the type has no associated type list");
Sean Callanan336a0002010-07-17 00:43:37 +00001134 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001135 }
1136
1137 clang::ASTContext *exe_ast_ctx = type_list->GetClangASTContext().getASTContext();
1138
1139 if (!exe_ast_ctx)
1140 {
Sean Callanan810f22d2010-07-16 00:09:46 +00001141 if (log)
1142 log->PutCString("There is no AST context for the current execution context");
Sean Callanan336a0002010-07-17 00:43:37 +00001143 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001144 }
1145
Sean Callanan336a0002010-07-17 00:43:37 +00001146 DWARFExpression &var_location_expr = var->LocationExpression();
1147
Chris Lattner24943d22010-06-08 16:52:24 +00001148 std::auto_ptr<Value> var_location(new Value);
1149
Greg Clayton178710c2010-09-14 02:20:48 +00001150 lldb::addr_t loclist_base_load_addr = LLDB_INVALID_ADDRESS;
1151
1152 if (var_location_expr.IsLocationList())
1153 {
1154 SymbolContext var_sc;
1155 var->CalculateSymbolContext (&var_sc);
Greg Claytoneea26402010-09-14 23:36:40 +00001156 loclist_base_load_addr = var_sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (exe_ctx.target);
Greg Clayton178710c2010-09-14 02:20:48 +00001157 }
Chris Lattner24943d22010-06-08 16:52:24 +00001158 Error err;
1159
Greg Clayton178710c2010-09-14 02:20:48 +00001160 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 +00001161 {
Sean Callanan810f22d2010-07-16 00:09:46 +00001162 if (log)
1163 log->Printf("Error evaluating location: %s", err.AsCString());
Sean Callanan336a0002010-07-17 00:43:37 +00001164 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001165 }
1166
Sean Callanan810f22d2010-07-16 00:09:46 +00001167 clang::ASTContext *var_ast_context = type_list->GetClangASTContext().getASTContext();
1168
Sean Callanan336a0002010-07-17 00:43:37 +00001169 void *type_to_use;
1170
Sean Callananf328c9f2010-07-20 23:31:16 +00001171 if (parser_ast_context)
1172 {
1173 type_to_use = ClangASTContext::CopyType(parser_ast_context, var_ast_context, var_opaque_type);
1174
1175 if (parser_type)
1176 *parser_type = TypeFromParser(type_to_use, parser_ast_context);
1177 }
Sean Callanan336a0002010-07-17 00:43:37 +00001178 else
1179 type_to_use = var_opaque_type;
Chris Lattner24943d22010-06-08 16:52:24 +00001180
1181 if (var_location.get()->GetContextType() == Value::eContextTypeInvalid)
Sean Callanan336a0002010-07-17 00:43:37 +00001182 var_location.get()->SetContext(Value::eContextTypeOpaqueClangQualType, type_to_use);
Chris Lattner24943d22010-06-08 16:52:24 +00001183
1184 if (var_location.get()->GetValueType() == Value::eValueTypeFileAddress)
1185 {
1186 SymbolContext var_sc;
1187 var->CalculateSymbolContext(&var_sc);
Sean Callanan336a0002010-07-17 00:43:37 +00001188
Chris Lattner24943d22010-06-08 16:52:24 +00001189 if (!var_sc.module_sp)
Sean Callanan336a0002010-07-17 00:43:37 +00001190 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001191
1192 ObjectFile *object_file = var_sc.module_sp->GetObjectFile();
1193
1194 if (!object_file)
Sean Callanan336a0002010-07-17 00:43:37 +00001195 return NULL;
1196
Chris Lattner24943d22010-06-08 16:52:24 +00001197 Address so_addr(var_location->GetScalar().ULongLong(), object_file->GetSectionList());
1198
Greg Clayton8de27c72010-10-15 22:48:33 +00001199 lldb::addr_t load_addr = so_addr.GetLoadAddress(m_exe_ctx.target);
Chris Lattner24943d22010-06-08 16:52:24 +00001200
1201 var_location->GetScalar() = load_addr;
1202 var_location->SetValueType(Value::eValueTypeLoadAddress);
1203 }
1204
Sean Callananf328c9f2010-07-20 23:31:16 +00001205 if (user_type)
1206 *user_type = TypeFromUser(var_opaque_type, var_ast_context);
Sean Callanan336a0002010-07-17 00:43:37 +00001207
1208 return var_location.release();
1209}
1210
1211void
1212ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001213 Variable* var)
Sean Callanan336a0002010-07-17 00:43:37 +00001214{
1215 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
1216
Sean Callananf328c9f2010-07-20 23:31:16 +00001217 TypeFromUser ut;
1218 TypeFromParser pt;
Sean Callanan336a0002010-07-17 00:43:37 +00001219
Greg Clayton8de27c72010-10-15 22:48:33 +00001220 Value *var_location = GetVariableValue (m_exe_ctx,
1221 var,
1222 context.GetASTContext(),
1223 &ut,
1224 &pt);
Sean Callanan336a0002010-07-17 00:43:37 +00001225
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001226 NamedDecl *var_decl = context.AddVarDecl(pt.GetOpaqueQualType());
Chris Lattner24943d22010-06-08 16:52:24 +00001227
Sean Callanan8c127202010-08-23 23:09:38 +00001228 ClangExpressionVariable &entity(m_found_entities.VariableAtIndex(m_found_entities.CreateVariable()));
Greg Clayton8de27c72010-10-15 22:48:33 +00001229 std::string decl_name(context.m_decl_name.getAsString());
1230 entity.m_name.SetCString (decl_name.c_str());
1231 entity.m_user_type = ut;
Chris Lattner24943d22010-06-08 16:52:24 +00001232
Sean Callanan8c127202010-08-23 23:09:38 +00001233 entity.EnableParserVars();
1234 entity.m_parser_vars->m_parser_type = pt;
1235 entity.m_parser_vars->m_named_decl = var_decl;
1236 entity.m_parser_vars->m_llvm_value = NULL;
1237 entity.m_parser_vars->m_lldb_value = var_location;
Chris Lattner24943d22010-06-08 16:52:24 +00001238
Sean Callanan810f22d2010-07-16 00:09:46 +00001239 if (log)
Greg Clayton8de27c72010-10-15 22:48:33 +00001240 {
1241 log->Printf("Found variable %s, returned (NamedDecl)%p", decl_name.c_str(), var_decl);
1242 }
Sean Callanan8f0dc342010-06-22 23:46:24 +00001243}
1244
1245void
Sean Callanana48fe162010-08-11 03:57:18 +00001246ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
Sean Callanana6223432010-08-20 01:02:30 +00001247 ClangExpressionVariable *pvar)
Sean Callanana48fe162010-08-11 03:57:18 +00001248{
Sean Callanan45690fe2010-08-30 22:17:16 +00001249 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
1250
Sean Callanana6223432010-08-20 01:02:30 +00001251 TypeFromUser user_type = pvar->m_user_type;
Sean Callanana48fe162010-08-11 03:57:18 +00001252
1253 TypeFromParser parser_type(ClangASTContext::CopyType(context.GetASTContext(),
1254 user_type.GetASTContext(),
1255 user_type.GetOpaqueQualType()),
1256 context.GetASTContext());
1257
Sean Callanan8c127202010-08-23 23:09:38 +00001258 NamedDecl *var_decl = context.AddVarDecl(parser_type.GetOpaqueQualType());
1259
1260 pvar->EnableParserVars();
1261 pvar->m_parser_vars->m_parser_type = parser_type;
1262 pvar->m_parser_vars->m_named_decl = var_decl;
1263 pvar->m_parser_vars->m_llvm_value = NULL;
1264 pvar->m_parser_vars->m_lldb_value = NULL;
Sean Callanan45690fe2010-08-30 22:17:16 +00001265
1266 if (log)
Greg Clayton8de27c72010-10-15 22:48:33 +00001267 log->Printf("Added pvar %s, returned (NamedDecl)%p", pvar->m_name.GetCString(), var_decl);
Sean Callanana48fe162010-08-11 03:57:18 +00001268}
1269
1270void
Sean Callanan8f0dc342010-06-22 23:46:24 +00001271ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
Sean Callanan0fc73582010-07-27 00:55:47 +00001272 Function* fun,
1273 Symbol* symbol)
Sean Callanan8f0dc342010-06-22 23:46:24 +00001274{
Sean Callanan6184dfe2010-06-23 00:47:48 +00001275 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
Sean Callanan8f0dc342010-06-22 23:46:24 +00001276
Sean Callanan0fc73582010-07-27 00:55:47 +00001277 NamedDecl *fun_decl;
Sean Callanan8f0dc342010-06-22 23:46:24 +00001278 std::auto_ptr<Value> fun_location(new Value);
Sean Callanan0fc73582010-07-27 00:55:47 +00001279 const Address *fun_address;
Sean Callanan8f0dc342010-06-22 23:46:24 +00001280
Sean Callanan0fc73582010-07-27 00:55:47 +00001281 // only valid for Functions, not for Symbols
1282 void *fun_opaque_type = NULL;
1283 clang::ASTContext *fun_ast_context = NULL;
1284
1285 if (fun)
1286 {
Sean Callanan55261a12010-09-08 22:38:54 +00001287#define BROKEN_OVERLOADING
1288 // Awaiting a fix on the Clang side
1289#ifndef BROKEN_OVERLOADING
Sean Callanan0fc73582010-07-27 00:55:47 +00001290 Type *fun_type = fun->GetType();
1291
1292 if (!fun_type)
1293 {
1294 if (log)
1295 log->PutCString("Skipped a function because it has no type");
1296 return;
1297 }
1298
Greg Clayton462d4142010-09-29 01:12:09 +00001299 fun_opaque_type = fun_type->GetClangType();
Sean Callanan0fc73582010-07-27 00:55:47 +00001300
1301 if (!fun_opaque_type)
1302 {
1303 if (log)
1304 log->PutCString("Skipped a function because it has no Clang type");
1305 return;
1306 }
1307
1308 fun_address = &fun->GetAddressRange().GetBaseAddress();
1309
1310 TypeList *type_list = fun_type->GetTypeList();
1311 fun_ast_context = type_list->GetClangASTContext().getASTContext();
1312 void *copied_type = ClangASTContext::CopyType(context.GetASTContext(), fun_ast_context, fun_opaque_type);
1313
1314 fun_decl = context.AddFunDecl(copied_type);
Sean Callanan55261a12010-09-08 22:38:54 +00001315#else
1316 fun_address = &fun->GetAddressRange().GetBaseAddress();
1317
1318 fun_decl = context.AddGenericFunDecl();
1319#endif
Sean Callanan0fc73582010-07-27 00:55:47 +00001320 }
1321 else if (symbol)
1322 {
1323 fun_address = &symbol->GetAddressRangeRef().GetBaseAddress();
1324
1325 fun_decl = context.AddGenericFunDecl();
1326 }
1327 else
1328 {
1329 if (log)
1330 log->PutCString("AddOneFunction called with no function and no symbol");
1331 return;
1332 }
1333
Greg Clayton8de27c72010-10-15 22:48:33 +00001334 lldb::addr_t load_addr = fun_address->GetLoadAddress(m_exe_ctx.target);
Sean Callanan8f0dc342010-06-22 23:46:24 +00001335 fun_location->SetValueType(Value::eValueTypeLoadAddress);
1336 fun_location->GetScalar() = load_addr;
1337
Sean Callanan8c127202010-08-23 23:09:38 +00001338 ClangExpressionVariable &entity(m_found_entities.VariableAtIndex(m_found_entities.CreateVariable()));
Greg Clayton8de27c72010-10-15 22:48:33 +00001339 std::string decl_name(context.m_decl_name.getAsString());
1340 entity.m_name.SetCString(decl_name.c_str());
Sean Callanan8c127202010-08-23 23:09:38 +00001341 entity.m_user_type = TypeFromUser(fun_opaque_type, fun_ast_context);;
Sean Callanan8f0dc342010-06-22 23:46:24 +00001342
Sean Callanan8c127202010-08-23 23:09:38 +00001343 entity.EnableParserVars();
1344 entity.m_parser_vars->m_named_decl = fun_decl;
1345 entity.m_parser_vars->m_llvm_value = NULL;
1346 entity.m_parser_vars->m_lldb_value = fun_location.release();
1347
Sean Callanan810f22d2010-07-16 00:09:46 +00001348 if (log)
Greg Clayton8de27c72010-10-15 22:48:33 +00001349 {
1350 log->Printf("Found %s function %s, returned (NamedDecl)%p", (fun ? "specific" : "generic"), decl_name.c_str(), fun_decl);
1351 }
Chris Lattner24943d22010-06-08 16:52:24 +00001352}
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001353
1354void
1355ClangExpressionDeclMap::AddOneType(NameSearchContext &context,
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001356 TypeFromUser &ut,
1357 bool add_method)
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001358{
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001359 clang::ASTContext *parser_ast_context = context.GetASTContext();
1360 clang::ASTContext *user_ast_context = ut.GetASTContext();
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001361
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001362 void *copied_type = ClangASTContext::CopyType(parser_ast_context, user_ast_context, ut.GetOpaqueQualType());
1363
1364 TypeFromParser parser_type(copied_type, parser_ast_context);
1365
1366 if (add_method && ClangASTContext::IsAggregateType(copied_type))
1367 {
1368 void *args[1];
1369
1370 args[0] = ClangASTContext::GetVoidPtrType(parser_ast_context, false);
1371
1372 void *method_type = ClangASTContext::CreateFunctionType (parser_ast_context,
1373 ClangASTContext::GetBuiltInType_void(parser_ast_context),
1374 args,
1375 1,
1376 false,
1377 ClangASTContext::GetTypeQualifiers(copied_type));
Greg Clayton30449d52010-10-01 02:31:07 +00001378
Greg Clayton1d8173f2010-09-24 05:15:53 +00001379 const bool is_virtual = false;
1380 const bool is_static = false;
1381 const bool is_inline = false;
Greg Clayton30449d52010-10-01 02:31:07 +00001382 const bool is_explicit = false;
1383
Greg Clayton1d8173f2010-09-24 05:15:53 +00001384 ClangASTContext::AddMethodToCXXRecordType (parser_ast_context,
1385 copied_type,
Greg Clayton8de27c72010-10-15 22:48:33 +00001386 "$__lldb_expr",
Greg Clayton1d8173f2010-09-24 05:15:53 +00001387 method_type,
1388 lldb::eAccessPublic,
1389 is_virtual,
1390 is_static,
Greg Clayton30449d52010-10-01 02:31:07 +00001391 is_inline,
1392 is_explicit);
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001393 }
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001394
1395 context.AddTypeDecl(copied_type);
1396}