blob: aa7d458badb57da87c7e642c8db9c0070208f22e [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- ClangExpressionDeclMap.cpp -----------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lldb/Expression/ClangExpressionDeclMap.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
Sean Callanan47a5c4c2010-09-23 03:01:22 +000016#include "clang/AST/DeclarationName.h"
Sean Callanana0744822010-11-01 23:22:47 +000017#include "clang/AST/Decl.h"
Chris Lattner24943d22010-06-08 16:52:24 +000018#include "lldb/lldb-private.h"
19#include "lldb/Core/Address.h"
Sean Callanan810f22d2010-07-16 00:09:46 +000020#include "lldb/Core/Error.h"
Sean Callanan6184dfe2010-06-23 00:47:48 +000021#include "lldb/Core/Log.h"
Chris Lattner24943d22010-06-08 16:52:24 +000022#include "lldb/Core/Module.h"
23#include "lldb/Expression/ClangASTSource.h"
Sean Callanana48fe162010-08-11 03:57:18 +000024#include "lldb/Expression/ClangPersistentVariables.h"
Chris Lattner24943d22010-06-08 16:52:24 +000025#include "lldb/Symbol/ClangASTContext.h"
26#include "lldb/Symbol/CompileUnit.h"
27#include "lldb/Symbol/Function.h"
28#include "lldb/Symbol/ObjectFile.h"
29#include "lldb/Symbol/SymbolContext.h"
30#include "lldb/Symbol/Type.h"
31#include "lldb/Symbol/TypeList.h"
32#include "lldb/Symbol/Variable.h"
33#include "lldb/Symbol/VariableList.h"
Sean Callananf328c9f2010-07-20 23:31:16 +000034#include "lldb/Target/ExecutionContext.h"
Sean Callanan810f22d2010-07-16 00:09:46 +000035#include "lldb/Target/Process.h"
Sean Callanan17c6a052010-10-05 20:18:48 +000036#include "lldb/Target/RegisterContext.h"
Chris Lattner24943d22010-06-08 16:52:24 +000037#include "lldb/Target/StackFrame.h"
Sean Callananf328c9f2010-07-20 23:31:16 +000038#include "lldb/Target/Target.h"
Sean Callanana0744822010-11-01 23:22:47 +000039#include "llvm/Support/raw_ostream.h"
Chris Lattner24943d22010-06-08 16:52:24 +000040
Chris Lattner24943d22010-06-08 16:52:24 +000041using namespace lldb_private;
42using namespace clang;
43
Greg Clayton8de27c72010-10-15 22:48:33 +000044ClangExpressionDeclMap::ClangExpressionDeclMap (ExecutionContext *exe_ctx) :
45 m_found_entities (),
46 m_struct_members (),
47 m_exe_ctx (),
48 m_sym_ctx (),
49 m_persistent_vars (NULL),
50 m_struct_alignment (0),
51 m_struct_size (0),
52 m_struct_laid_out (false),
53 m_enable_lookups (false),
54 m_allocated_area (0),
55 m_materialized_location (0),
56 m_result_name (),
57 m_object_pointer_type (),
58 m_lookedup_types ()
Chris Lattner24943d22010-06-08 16:52:24 +000059{
Greg Clayton8de27c72010-10-15 22:48:33 +000060 if (exe_ctx)
61 {
62 m_exe_ctx = *exe_ctx;
63 if (exe_ctx->frame)
64 m_sym_ctx = exe_ctx->frame->GetSymbolContext(lldb::eSymbolContextEverything);
65 if (exe_ctx->process)
66 m_persistent_vars = &exe_ctx->process->GetPersistentVariables();
67 }
Chris Lattner24943d22010-06-08 16:52:24 +000068}
69
70ClangExpressionDeclMap::~ClangExpressionDeclMap()
Sean Callanan8c127202010-08-23 23:09:38 +000071{
72 for (uint64_t entity_index = 0, num_entities = m_found_entities.Size();
73 entity_index < num_entities;
74 ++entity_index)
75 {
76 ClangExpressionVariable &entity(m_found_entities.VariableAtIndex(entity_index));
77 if (entity.m_parser_vars.get() &&
78 entity.m_parser_vars->m_lldb_value)
79 delete entity.m_parser_vars->m_lldb_value;
Sean Callanan45690fe2010-08-30 22:17:16 +000080
81 entity.DisableParserVars();
82 }
83
84 for (uint64_t pvar_index = 0, num_pvars = m_persistent_vars->Size();
85 pvar_index < num_pvars;
86 ++pvar_index)
87 {
88 ClangExpressionVariable &pvar(m_persistent_vars->VariableAtIndex(pvar_index));
89 pvar.DisableParserVars();
Sean Callanan8c127202010-08-23 23:09:38 +000090 }
Chris Lattner24943d22010-06-08 16:52:24 +000091
Sean Callanan7a60b942010-10-08 01:58:41 +000092 if (m_materialized_location)
Sean Callananc2c6f772010-10-26 00:31:56 +000093 {
94//#define SINGLE_STEP_EXPRESSIONS
95
96#ifndef SINGLE_STEP_EXPRESSIONS
Greg Clayton8de27c72010-10-15 22:48:33 +000097 m_exe_ctx.process->DeallocateMemory(m_materialized_location);
Sean Callananc2c6f772010-10-26 00:31:56 +000098#endif
Sean Callanan7a60b942010-10-08 01:58:41 +000099 m_materialized_location = 0;
100 }
Chris Lattner24943d22010-06-08 16:52:24 +0000101}
102
Sean Callanan8bce6652010-07-13 21:41:46 +0000103// Interface for IRForTarget
104
Greg Clayton8de27c72010-10-15 22:48:33 +0000105const ConstString &
106ClangExpressionDeclMap::GetPersistentResultName ()
Sean Callanan82b74c82010-08-12 01:56:52 +0000107{
Greg Clayton8de27c72010-10-15 22:48:33 +0000108 if (!m_result_name)
109 m_persistent_vars->GetNextResultName(m_result_name);
110 return m_result_name;
Sean Callanan82b74c82010-08-12 01:56:52 +0000111}
112
Sean Callanan8bce6652010-07-13 21:41:46 +0000113bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000114ClangExpressionDeclMap::AddPersistentVariable
115(
116 const clang::NamedDecl *decl,
117 const ConstString &name,
118 TypeFromParser parser_type
119)
Sean Callanana48fe162010-08-11 03:57:18 +0000120{
Greg Clayton8de27c72010-10-15 22:48:33 +0000121 clang::ASTContext *context(m_exe_ctx.target->GetScratchClangASTContext()->getASTContext());
Sean Callanana48fe162010-08-11 03:57:18 +0000122
Sean Callanana48fe162010-08-11 03:57:18 +0000123 TypeFromUser user_type(ClangASTContext::CopyType(context,
Sean Callanan82b74c82010-08-12 01:56:52 +0000124 parser_type.GetASTContext(),
125 parser_type.GetOpaqueQualType()),
Sean Callanana48fe162010-08-11 03:57:18 +0000126 context);
127
Sean Callanan8c127202010-08-23 23:09:38 +0000128 if (!m_persistent_vars->CreatePersistentVariable (name, user_type))
129 return false;
130
131 ClangExpressionVariable *var = m_persistent_vars->GetVariable(name);
132
133 if (!var)
134 return false;
135
136 var->EnableParserVars();
137
138 var->m_parser_vars->m_named_decl = decl;
139 var->m_parser_vars->m_parser_type = parser_type;
140
141 return true;
Sean Callanana48fe162010-08-11 03:57:18 +0000142}
143
144bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000145ClangExpressionDeclMap::AddValueToStruct
146(
147 const clang::NamedDecl *decl,
148 const ConstString &name,
149 llvm::Value *value,
150 size_t size,
151 off_t alignment
152)
Sean Callanan8bce6652010-07-13 21:41:46 +0000153{
Greg Claytone005f2c2010-11-06 01:53:30 +0000154 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan45690fe2010-08-30 22:17:16 +0000155
Sean Callanan8bce6652010-07-13 21:41:46 +0000156 m_struct_laid_out = false;
157
Sean Callanan8c127202010-08-23 23:09:38 +0000158 if (m_struct_members.GetVariable(decl))
159 return true;
Sean Callanan8bce6652010-07-13 21:41:46 +0000160
Sean Callanan8c127202010-08-23 23:09:38 +0000161 ClangExpressionVariable *var = m_found_entities.GetVariable(decl);
Sean Callanan8bce6652010-07-13 21:41:46 +0000162
Sean Callanan8c127202010-08-23 23:09:38 +0000163 if (!var)
164 var = m_persistent_vars->GetVariable(decl);
Sean Callanan8bce6652010-07-13 21:41:46 +0000165
Sean Callanan8c127202010-08-23 23:09:38 +0000166 if (!var)
167 return false;
168
Sean Callanan45690fe2010-08-30 22:17:16 +0000169 if (log)
170 log->Printf("Adding value for decl %p [%s - %s] to the structure",
171 decl,
Greg Clayton8de27c72010-10-15 22:48:33 +0000172 name.GetCString(),
173 var->m_name.GetCString());
Sean Callanan45690fe2010-08-30 22:17:16 +0000174
Sean Callanan8c127202010-08-23 23:09:38 +0000175 // We know entity->m_parser_vars is valid because we used a parser variable
176 // to find it
177 var->m_parser_vars->m_llvm_value = value;
178
179 var->EnableJITVars();
180 var->m_jit_vars->m_alignment = alignment;
181 var->m_jit_vars->m_size = size;
182
183 m_struct_members.AddVariable(*var);
Sean Callanan8bce6652010-07-13 21:41:46 +0000184
185 return true;
186}
187
188bool
189ClangExpressionDeclMap::DoStructLayout ()
190{
191 if (m_struct_laid_out)
192 return true;
193
Sean Callanan8bce6652010-07-13 21:41:46 +0000194 off_t cursor = 0;
195
196 m_struct_alignment = 0;
197 m_struct_size = 0;
198
Sean Callanan8c127202010-08-23 23:09:38 +0000199 for (uint64_t member_index = 0, num_members = m_struct_members.Size();
200 member_index < num_members;
201 ++member_index)
Sean Callanan8bce6652010-07-13 21:41:46 +0000202 {
Sean Callanan8c127202010-08-23 23:09:38 +0000203 ClangExpressionVariable &member(m_struct_members.VariableAtIndex(member_index));
Sean Callanan8bce6652010-07-13 21:41:46 +0000204
Sean Callanan8c127202010-08-23 23:09:38 +0000205 if (!member.m_jit_vars.get())
206 return false;
Sean Callanan8bce6652010-07-13 21:41:46 +0000207
Sean Callanan8c127202010-08-23 23:09:38 +0000208 if (member_index == 0)
209 m_struct_alignment = member.m_jit_vars->m_alignment;
210
211 if (cursor % member.m_jit_vars->m_alignment)
212 cursor += (member.m_jit_vars->m_alignment - (cursor % member.m_jit_vars->m_alignment));
213
214 member.m_jit_vars->m_offset = cursor;
215 cursor += member.m_jit_vars->m_size;
Sean Callanan8bce6652010-07-13 21:41:46 +0000216 }
217
218 m_struct_size = cursor;
219
220 m_struct_laid_out = true;
221 return true;
222}
223
Greg Clayton8de27c72010-10-15 22:48:33 +0000224bool ClangExpressionDeclMap::GetStructInfo
225(
226 uint32_t &num_elements,
227 size_t &size,
228 off_t &alignment
229)
Sean Callanan8bce6652010-07-13 21:41:46 +0000230{
231 if (!m_struct_laid_out)
232 return false;
233
Sean Callanan8c127202010-08-23 23:09:38 +0000234 num_elements = m_struct_members.Size();
Sean Callanan8bce6652010-07-13 21:41:46 +0000235 size = m_struct_size;
236 alignment = m_struct_alignment;
237
238 return true;
239}
240
241bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000242ClangExpressionDeclMap::GetStructElement
243(
244 const clang::NamedDecl *&decl,
245 llvm::Value *&value,
246 off_t &offset,
247 ConstString &name,
248 uint32_t index
249)
Sean Callanan8bce6652010-07-13 21:41:46 +0000250{
251 if (!m_struct_laid_out)
252 return false;
253
Sean Callanan8c127202010-08-23 23:09:38 +0000254 if (index >= m_struct_members.Size())
Sean Callanan8bce6652010-07-13 21:41:46 +0000255 return false;
256
Sean Callanan8c127202010-08-23 23:09:38 +0000257 ClangExpressionVariable &member(m_struct_members.VariableAtIndex(index));
Sean Callanan8bce6652010-07-13 21:41:46 +0000258
Sean Callanan8c127202010-08-23 23:09:38 +0000259 if (!member.m_parser_vars.get() ||
260 !member.m_jit_vars.get())
261 return false;
262
263 decl = member.m_parser_vars->m_named_decl;
264 value = member.m_parser_vars->m_llvm_value;
265 offset = member.m_jit_vars->m_offset;
Greg Clayton8de27c72010-10-15 22:48:33 +0000266 name = member.m_name;
Sean Callanan8c127202010-08-23 23:09:38 +0000267
Sean Callanan8bce6652010-07-13 21:41:46 +0000268 return true;
269}
270
Sean Callanan02fbafa2010-07-27 21:39:39 +0000271bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000272ClangExpressionDeclMap::GetFunctionInfo
273(
274 const clang::NamedDecl *decl,
275 llvm::Value**& value,
276 uint64_t &ptr
277)
Sean Callananba992c52010-07-27 02:07:53 +0000278{
Sean Callanan8c127202010-08-23 23:09:38 +0000279 ClangExpressionVariable *entity = m_found_entities.GetVariable(decl);
280
281 if (!entity)
282 return false;
Sean Callananba992c52010-07-27 02:07:53 +0000283
Sean Callanan8c127202010-08-23 23:09:38 +0000284 // We know m_parser_vars is valid since we searched for the variable by
285 // its NamedDecl
Sean Callananba992c52010-07-27 02:07:53 +0000286
Sean Callanan8c127202010-08-23 23:09:38 +0000287 value = &entity->m_parser_vars->m_llvm_value;
288 ptr = entity->m_parser_vars->m_lldb_value->GetScalar().ULongLong();
289
290 return true;
Sean Callananba992c52010-07-27 02:07:53 +0000291}
292
Sean Callananf5857a02010-07-31 01:32:05 +0000293bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000294ClangExpressionDeclMap::GetFunctionAddress
295(
296 const ConstString &name,
297 uint64_t &ptr
298)
Sean Callananf5857a02010-07-31 01:32:05 +0000299{
300 // Back out in all cases where we're not fully initialized
Greg Clayton8de27c72010-10-15 22:48:33 +0000301 if (m_exe_ctx.frame == NULL)
Sean Callananf5857a02010-07-31 01:32:05 +0000302 return false;
303
Greg Claytone5748d82010-11-09 23:46:37 +0000304 SymbolContextList sc_list;
Sean Callananf5857a02010-07-31 01:32:05 +0000305
Greg Claytone5748d82010-11-09 23:46:37 +0000306 m_sym_ctx.FindFunctionsByName(name, false, sc_list);
Sean Callananf5857a02010-07-31 01:32:05 +0000307
Greg Claytone5748d82010-11-09 23:46:37 +0000308 if (!sc_list.GetSize())
Sean Callananf5857a02010-07-31 01:32:05 +0000309 return false;
310
311 SymbolContext sym_ctx;
Greg Claytone5748d82010-11-09 23:46:37 +0000312 sc_list.GetContextAtIndex(0, sym_ctx);
Sean Callananf5857a02010-07-31 01:32:05 +0000313
314 const Address *fun_address;
315
316 if (sym_ctx.function)
317 fun_address = &sym_ctx.function->GetAddressRange().GetBaseAddress();
318 else if (sym_ctx.symbol)
319 fun_address = &sym_ctx.symbol->GetAddressRangeRef().GetBaseAddress();
320 else
321 return false;
322
Greg Clayton8de27c72010-10-15 22:48:33 +0000323 ptr = fun_address->GetLoadAddress (m_exe_ctx.target);
Sean Callananf5857a02010-07-31 01:32:05 +0000324
325 return true;
326}
327
Sean Callanan810f22d2010-07-16 00:09:46 +0000328// Interface for CommandObjectExpression
Sean Callananf328c9f2010-07-20 23:31:16 +0000329
330bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000331ClangExpressionDeclMap::Materialize
332(
333 ExecutionContext *exe_ctx,
334 lldb::addr_t &struct_address,
335 Error &err
336)
Sean Callananf328c9f2010-07-20 23:31:16 +0000337{
338 bool result = DoMaterialize(false, exe_ctx, NULL, err);
339
340 if (result)
341 struct_address = m_materialized_location;
342
343 return result;
344}
345
346bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000347ClangExpressionDeclMap::GetObjectPointer
348(
349 lldb::addr_t &object_ptr,
350 ExecutionContext *exe_ctx,
351 Error &err
352)
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000353{
354 if (!exe_ctx || !exe_ctx->frame || !exe_ctx->target || !exe_ctx->process)
355 {
356 err.SetErrorString("Couldn't load 'this' because the context is incomplete");
357 return false;
358 }
359
360 if (!m_object_pointer_type.GetOpaqueQualType())
361 {
362 err.SetErrorString("Couldn't load 'this' because its type is unknown");
363 return false;
364 }
365
Greg Clayton8de27c72010-10-15 22:48:33 +0000366 static ConstString g_this_cs ("this");
367 Variable *object_ptr_var = FindVariableInScope(*exe_ctx->frame, g_this_cs, &m_object_pointer_type);
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000368
369 if (!object_ptr_var)
370 {
371 err.SetErrorString("Couldn't find 'this' with appropriate type in scope");
372 return false;
373 }
374
375 std::auto_ptr<lldb_private::Value> location_value(GetVariableValue(*exe_ctx,
376 object_ptr_var,
377 m_object_pointer_type.GetASTContext()));
378
379 if (!location_value.get())
380 {
381 err.SetErrorString("Couldn't get the location for 'this'");
382 return false;
383 }
384
385 if (location_value->GetValueType() == Value::eValueTypeLoadAddress)
386 {
387 lldb::addr_t value_addr = location_value->GetScalar().ULongLong();
388 uint32_t address_byte_size = exe_ctx->target->GetArchitecture().GetAddressByteSize();
389 lldb::ByteOrder address_byte_order = exe_ctx->process->GetByteOrder();
390
391 if (ClangASTType::GetClangTypeBitWidth(m_object_pointer_type.GetASTContext(), m_object_pointer_type.GetOpaqueQualType()) != address_byte_size * 8)
392 {
393 err.SetErrorStringWithFormat("'this' is not of an expected pointer size");
394 return false;
395 }
396
397 DataBufferHeap data;
398 data.SetByteSize(address_byte_size);
399 Error read_error;
400
401 if (exe_ctx->process->ReadMemory (value_addr, data.GetBytes(), address_byte_size, read_error) != address_byte_size)
402 {
403 err.SetErrorStringWithFormat("Coldn't read 'this' from the target: %s", read_error.AsCString());
404 return false;
405 }
406
407 DataExtractor extractor(data.GetBytes(), data.GetByteSize(), address_byte_order, address_byte_size);
408
409 uint32_t offset = 0;
410
411 object_ptr = extractor.GetPointer(&offset);
412
413 return true;
414 }
415 else
416 {
417 err.SetErrorString("'this' is not in memory; LLDB must be extended to handle registers");
418 return false;
419 }
420}
421
422bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000423ClangExpressionDeclMap::Dematerialize
424(
425 ExecutionContext *exe_ctx,
426 ClangExpressionVariable *&result,
427 Error &err
428)
Sean Callananf328c9f2010-07-20 23:31:16 +0000429{
Sean Callanan82b74c82010-08-12 01:56:52 +0000430 return DoMaterialize(true, exe_ctx, &result, err);
Sean Callananf328c9f2010-07-20 23:31:16 +0000431}
432
Sean Callanan32824aa2010-07-23 22:19:18 +0000433bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000434ClangExpressionDeclMap::DumpMaterializedStruct
435(
436 ExecutionContext *exe_ctx,
437 Stream &s,
438 Error &err
439)
Sean Callanan32824aa2010-07-23 22:19:18 +0000440{
441 if (!m_struct_laid_out)
442 {
443 err.SetErrorString("Structure hasn't been laid out yet");
444 return false;
445 }
446
447 if (!exe_ctx)
448 {
449 err.SetErrorString("Received null execution context");
450 return false;
451 }
452
453
454 if (!exe_ctx->process)
455 {
456 err.SetErrorString("Couldn't find the process");
457 return false;
458 }
459
460 if (!exe_ctx->target)
461 {
462 err.SetErrorString("Couldn't find the target");
463 return false;
464 }
465
466 lldb::DataBufferSP data(new DataBufferHeap(m_struct_size, 0));
467
468 Error error;
469 if (exe_ctx->process->ReadMemory (m_materialized_location, data->GetBytes(), data->GetByteSize(), error) != data->GetByteSize())
470 {
471 err.SetErrorStringWithFormat ("Couldn't read struct from the target: %s", error.AsCString());
472 return false;
473 }
474
475 DataExtractor extractor(data, exe_ctx->process->GetByteOrder(), exe_ctx->target->GetArchitecture().GetAddressByteSize());
476
Sean Callanan8c127202010-08-23 23:09:38 +0000477 for (uint64_t member_index = 0, num_members = m_struct_members.Size();
478 member_index < num_members;
479 ++member_index)
Sean Callanan32824aa2010-07-23 22:19:18 +0000480 {
Sean Callanan8c127202010-08-23 23:09:38 +0000481 ClangExpressionVariable &member (m_struct_members.VariableAtIndex(member_index));
Sean Callanan32824aa2010-07-23 22:19:18 +0000482
Greg Clayton8de27c72010-10-15 22:48:33 +0000483 s.Printf("[%s]\n", member.m_name.GetCString());
Sean Callanan8c127202010-08-23 23:09:38 +0000484
485 if (!member.m_jit_vars.get())
486 return false;
487
488 extractor.Dump(&s, // stream
489 member.m_jit_vars->m_offset, // offset
490 lldb::eFormatBytesWithASCII, // format
491 1, // byte size of individual entries
492 member.m_jit_vars->m_size, // number of entries
493 16, // entries per line
494 m_materialized_location + member.m_jit_vars->m_offset, // address to print
495 0, // bit size (bitfields only; 0 means ignore)
496 0); // bit alignment (bitfields only; 0 means ignore)
Sean Callanan32824aa2010-07-23 22:19:18 +0000497
498 s.PutChar('\n');
499 }
500
501 return true;
502}
503
Sean Callananf328c9f2010-07-20 23:31:16 +0000504bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000505ClangExpressionDeclMap::DoMaterialize
506(
507 bool dematerialize,
508 ExecutionContext *exe_ctx,
509 ClangExpressionVariable **result,
510 Error &err
511)
Sean Callanan810f22d2010-07-16 00:09:46 +0000512{
Greg Claytone005f2c2010-11-06 01:53:30 +0000513 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan82b74c82010-08-12 01:56:52 +0000514
Sean Callanan810f22d2010-07-16 00:09:46 +0000515 if (!m_struct_laid_out)
516 {
517 err.SetErrorString("Structure hasn't been laid out yet");
518 return LLDB_INVALID_ADDRESS;
519 }
520
Sean Callanan810f22d2010-07-16 00:09:46 +0000521 if (!exe_ctx)
522 {
523 err.SetErrorString("Received null execution context");
524 return LLDB_INVALID_ADDRESS;
525 }
526
Sean Callanan45839272010-07-24 01:37:44 +0000527 if (!exe_ctx->frame)
528 {
529 err.SetErrorString("Received null execution frame");
530 return LLDB_INVALID_ADDRESS;
531 }
532
Sean Callanane8a59a82010-09-13 21:34:21 +0000533 if (!m_struct_size)
534 {
535 if (log)
536 log->PutCString("Not bothering to allocate a struct because no arguments are needed");
537
538 m_allocated_area = NULL;
539
540 return true;
541 }
542
Sean Callanan810f22d2010-07-16 00:09:46 +0000543 const SymbolContext &sym_ctx(exe_ctx->frame->GetSymbolContext(lldb::eSymbolContextEverything));
544
Sean Callananf328c9f2010-07-20 23:31:16 +0000545 if (!dematerialize)
Sean Callanan810f22d2010-07-16 00:09:46 +0000546 {
Sean Callananf328c9f2010-07-20 23:31:16 +0000547 if (m_materialized_location)
548 {
549 exe_ctx->process->DeallocateMemory(m_materialized_location);
550 m_materialized_location = 0;
551 }
552
Sean Callanan7a60b942010-10-08 01:58:41 +0000553 if (log)
554 log->PutCString("Allocating memory for materialized argument struct");
555
Sean Callananf328c9f2010-07-20 23:31:16 +0000556 lldb::addr_t mem = exe_ctx->process->AllocateMemory(m_struct_alignment + m_struct_size,
557 lldb::ePermissionsReadable | lldb::ePermissionsWritable,
558 err);
559
560 if (mem == LLDB_INVALID_ADDRESS)
561 return false;
562
563 m_allocated_area = mem;
Sean Callanan810f22d2010-07-16 00:09:46 +0000564 }
565
Sean Callananf328c9f2010-07-20 23:31:16 +0000566 m_materialized_location = m_allocated_area;
567
568 if (m_materialized_location % m_struct_alignment)
Sean Callananf328c9f2010-07-20 23:31:16 +0000569 m_materialized_location += (m_struct_alignment - (m_materialized_location % m_struct_alignment));
Sean Callananf328c9f2010-07-20 23:31:16 +0000570
Sean Callanan8c127202010-08-23 23:09:38 +0000571 for (uint64_t member_index = 0, num_members = m_struct_members.Size();
572 member_index < num_members;
573 ++member_index)
Sean Callanan810f22d2010-07-16 00:09:46 +0000574 {
Sean Callanan8c127202010-08-23 23:09:38 +0000575 ClangExpressionVariable &member (m_struct_members.VariableAtIndex(member_index));
Sean Callanan810f22d2010-07-16 00:09:46 +0000576
Sean Callanan8c127202010-08-23 23:09:38 +0000577 if (!member.m_parser_vars.get())
Sean Callanan336a0002010-07-17 00:43:37 +0000578 return false;
Sean Callanan8c127202010-08-23 23:09:38 +0000579
580 ClangExpressionVariable *entity = m_found_entities.GetVariable(member.m_parser_vars->m_named_decl);
Greg Clayton8de27c72010-10-15 22:48:33 +0000581 ClangExpressionVariable *persistent_variable = m_persistent_vars->GetVariable(member.m_name);
Sean Callanan8c127202010-08-23 23:09:38 +0000582
583 if (entity)
584 {
585 if (!member.m_jit_vars.get())
586 return false;
587
Greg Clayton8de27c72010-10-15 22:48:33 +0000588 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 +0000589 return false;
590 }
591 else if (persistent_variable)
592 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000593 if (member.m_name == m_result_name)
Sean Callanan45690fe2010-08-30 22:17:16 +0000594 {
595 if (!dematerialize)
596 continue;
Sean Callanan8c127202010-08-23 23:09:38 +0000597
Sean Callanan8c127202010-08-23 23:09:38 +0000598 if (log)
599 log->PutCString("Found result member in the struct");
Sean Callanan45690fe2010-08-30 22:17:16 +0000600
Sean Callanan8c127202010-08-23 23:09:38 +0000601 *result = &member;
602 }
603
Sean Callanan45690fe2010-08-30 22:17:16 +0000604 if (log)
Greg Clayton8de27c72010-10-15 22:48:33 +0000605 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 +0000606
Greg Clayton8de27c72010-10-15 22:48:33 +0000607 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 +0000608 return false;
609 }
610 else
611 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000612 err.SetErrorStringWithFormat("Unexpected variable %s", member.m_name.GetCString());
Sean Callanan8c127202010-08-23 23:09:38 +0000613 return false;
614 }
Sean Callanan810f22d2010-07-16 00:09:46 +0000615 }
616
Sean Callananf328c9f2010-07-20 23:31:16 +0000617 return true;
618}
619
Sean Callanana48fe162010-08-11 03:57:18 +0000620bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000621ClangExpressionDeclMap::DoMaterializeOnePersistentVariable
622(
623 bool dematerialize,
624 ExecutionContext &exe_ctx,
625 const ConstString &name,
626 lldb::addr_t addr,
627 Error &err
628)
Sean Callanan45690fe2010-08-30 22:17:16 +0000629{
Sean Callanana6223432010-08-20 01:02:30 +0000630 ClangExpressionVariable *pvar(m_persistent_vars->GetVariable(name));
Sean Callanana48fe162010-08-11 03:57:18 +0000631
632 if (!pvar)
633 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000634 err.SetErrorStringWithFormat("Undefined persistent variable %s", name.GetCString());
Sean Callanana48fe162010-08-11 03:57:18 +0000635 return LLDB_INVALID_ADDRESS;
636 }
637
638 size_t pvar_size = pvar->Size();
Sean Callanana6223432010-08-20 01:02:30 +0000639
Greg Clayton66ed2fb2010-10-05 00:00:42 +0000640 if (!pvar->m_data_sp.get())
Sean Callanana6223432010-08-20 01:02:30 +0000641 return false;
642
Greg Clayton66ed2fb2010-10-05 00:00:42 +0000643 uint8_t *pvar_data = pvar->m_data_sp->GetBytes();
Sean Callanana48fe162010-08-11 03:57:18 +0000644 Error error;
645
646 if (dematerialize)
647 {
648 if (exe_ctx.process->ReadMemory (addr, pvar_data, pvar_size, error) != pvar_size)
649 {
650 err.SetErrorStringWithFormat ("Couldn't read a composite type from the target: %s", error.AsCString());
651 return false;
652 }
653 }
654 else
655 {
656 if (exe_ctx.process->WriteMemory (addr, pvar_data, pvar_size, error) != pvar_size)
657 {
658 err.SetErrorStringWithFormat ("Couldn't write a composite type to the target: %s", error.AsCString());
659 return false;
660 }
661 }
662
663 return true;
664}
665
Sean Callananf328c9f2010-07-20 23:31:16 +0000666bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000667ClangExpressionDeclMap::DoMaterializeOneVariable
668(
669 bool dematerialize,
670 ExecutionContext &exe_ctx,
671 const SymbolContext &sym_ctx,
672 const ConstString &name,
673 TypeFromUser type,
674 lldb::addr_t addr,
675 Error &err
676)
Sean Callananf328c9f2010-07-20 23:31:16 +0000677{
Greg Claytone005f2c2010-11-06 01:53:30 +0000678 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callananf328c9f2010-07-20 23:31:16 +0000679
Sean Callanan17c6a052010-10-05 20:18:48 +0000680 if (!exe_ctx.frame || !exe_ctx.process)
Sean Callanancc074622010-09-14 21:59:34 +0000681 return false;
682
683 Variable *var = FindVariableInScope(*exe_ctx.frame, name, &type);
Sean Callananf328c9f2010-07-20 23:31:16 +0000684
685 if (!var)
686 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000687 err.SetErrorStringWithFormat("Couldn't find %s with appropriate type", name.GetCString());
Sean Callananf328c9f2010-07-20 23:31:16 +0000688 return false;
689 }
690
Sean Callanan841026f2010-07-23 00:16:21 +0000691 if (log)
Greg Clayton8de27c72010-10-15 22:48:33 +0000692 log->Printf("%s %s with type %p", (dematerialize ? "Dematerializing" : "Materializing"), name.GetCString(), type.GetOpaqueQualType());
Sean Callananf328c9f2010-07-20 23:31:16 +0000693
694 std::auto_ptr<lldb_private::Value> location_value(GetVariableValue(exe_ctx,
695 var,
696 type.GetASTContext()));
697
698 if (!location_value.get())
699 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000700 err.SetErrorStringWithFormat("Couldn't get value for %s", name.GetCString());
Sean Callananf328c9f2010-07-20 23:31:16 +0000701 return false;
702 }
Sean Callanan17c6a052010-10-05 20:18:48 +0000703
704 // The size of the type contained in addr
Sean Callananf328c9f2010-07-20 23:31:16 +0000705
Sean Callanan17c6a052010-10-05 20:18:48 +0000706 size_t addr_bit_size = ClangASTType::GetClangTypeBitWidth(type.GetASTContext(), type.GetOpaqueQualType());
707 size_t addr_byte_size = addr_bit_size % 8 ? ((addr_bit_size + 8) / 8) : (addr_bit_size / 8);
708
709 Value::ValueType value_type = location_value->GetValueType();
710
711 switch (value_type)
Sean Callananf328c9f2010-07-20 23:31:16 +0000712 {
Sean Callanan17c6a052010-10-05 20:18:48 +0000713 default:
Sean Callananf328c9f2010-07-20 23:31:16 +0000714 {
Sean Callanan17c6a052010-10-05 20:18:48 +0000715 StreamString ss;
716
717 location_value->Dump(&ss);
718
Greg Clayton8de27c72010-10-15 22:48:33 +0000719 err.SetErrorStringWithFormat("%s has a value of unhandled type: %s", name.GetCString(), ss.GetString().c_str());
Sean Callananf328c9f2010-07-20 23:31:16 +0000720 return false;
721 }
Sean Callanan17c6a052010-10-05 20:18:48 +0000722 break;
723 case Value::eValueTypeLoadAddress:
Sean Callananf328c9f2010-07-20 23:31:16 +0000724 {
Sean Callanan17c6a052010-10-05 20:18:48 +0000725 lldb::addr_t value_addr = location_value->GetScalar().ULongLong();
726
727 DataBufferHeap data;
728 data.SetByteSize(addr_byte_size);
729
730 lldb::addr_t src_addr;
731 lldb::addr_t dest_addr;
732
733 if (dematerialize)
734 {
735 src_addr = addr;
736 dest_addr = value_addr;
737 }
738 else
739 {
740 src_addr = value_addr;
741 dest_addr = addr;
742 }
743
744 Error error;
745 if (exe_ctx.process->ReadMemory (src_addr, data.GetBytes(), addr_byte_size, error) != addr_byte_size)
746 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000747 err.SetErrorStringWithFormat ("Couldn't read %s from the target: %s", name.GetCString(), error.AsCString());
Sean Callanan17c6a052010-10-05 20:18:48 +0000748 return false;
749 }
750
751 if (exe_ctx.process->WriteMemory (dest_addr, data.GetBytes(), addr_byte_size, error) != addr_byte_size)
752 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000753 err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", name.GetCString(), error.AsCString());
Sean Callanan17c6a052010-10-05 20:18:48 +0000754 return false;
755 }
756
757 if (log)
758 log->Printf("Copied from 0x%llx to 0x%llx", (uint64_t)src_addr, (uint64_t)addr);
Sean Callananf328c9f2010-07-20 23:31:16 +0000759 }
Sean Callanan17c6a052010-10-05 20:18:48 +0000760 break;
761 case Value::eValueTypeScalar:
762 {
763 if (location_value->GetContextType() != Value::eContextTypeDCRegisterInfo)
764 {
765 StreamString ss;
766
767 location_value->Dump(&ss);
768
Greg Clayton8de27c72010-10-15 22:48:33 +0000769 err.SetErrorStringWithFormat("%s is a scalar of unhandled type: %s", name.GetCString(), ss.GetString().c_str());
Sean Callanan17c6a052010-10-05 20:18:48 +0000770 return false;
771 }
772
773 lldb::RegisterInfo *register_info = location_value->GetRegisterInfo();
774
775 if (!register_info)
776 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000777 err.SetErrorStringWithFormat("Couldn't get the register information for %s", name.GetCString());
Sean Callanan17c6a052010-10-05 20:18:48 +0000778 return false;
779 }
780
781 RegisterContext *register_context = exe_ctx.GetRegisterContext();
782
783 if (!register_context)
784 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000785 err.SetErrorStringWithFormat("Couldn't read register context to read %s from %s", name.GetCString(), register_info->name);
Sean Callanan17c6a052010-10-05 20:18:48 +0000786 return false;
787 }
788
789 uint32_t register_number = register_info->kinds[lldb::eRegisterKindLLDB];
790 uint32_t register_byte_size = register_info->byte_size;
791
792 if (dematerialize)
793 {
794 // Moving from addr into a register
795 //
796 // Case 1: addr_byte_size and register_byte_size are the same
797 //
798 // |AABBCCDD| Address contents
799 // |AABBCCDD| Register contents
800 //
801 // Case 2: addr_byte_size is bigger than register_byte_size
802 //
803 // Error! (The register should always be big enough to hold the data)
804 //
805 // Case 3: register_byte_size is bigger than addr_byte_size
806 //
807 // |AABB| Address contents
808 // |AABB0000| Register contents [on little-endian hardware]
809 // |0000AABB| Register contents [on big-endian hardware]
810
811 if (addr_byte_size > register_byte_size)
812 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000813 err.SetErrorStringWithFormat("%s is too big to store in %s", name.GetCString(), register_info->name);
Sean Callanan17c6a052010-10-05 20:18:48 +0000814 return false;
815 }
816
817 uint32_t register_offset;
818
819 switch (exe_ctx.process->GetByteOrder())
820 {
821 default:
Greg Clayton8de27c72010-10-15 22:48:33 +0000822 err.SetErrorStringWithFormat("%s is stored with an unhandled byte order", name.GetCString());
Sean Callanan17c6a052010-10-05 20:18:48 +0000823 return false;
824 case lldb::eByteOrderLittle:
825 register_offset = 0;
826 break;
827 case lldb::eByteOrderBig:
828 register_offset = register_byte_size - addr_byte_size;
829 break;
830 }
831
832 DataBufferHeap register_data (register_byte_size, 0);
833
834 Error error;
835 if (exe_ctx.process->ReadMemory (addr, register_data.GetBytes() + register_offset, addr_byte_size, error) != addr_byte_size)
836 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000837 err.SetErrorStringWithFormat ("Couldn't read %s from the target: %s", name.GetCString(), error.AsCString());
Sean Callanan17c6a052010-10-05 20:18:48 +0000838 return false;
839 }
840
841 DataExtractor register_extractor (register_data.GetBytes(), register_byte_size, exe_ctx.process->GetByteOrder(), exe_ctx.process->GetAddressByteSize());
842
843 if (!register_context->WriteRegisterBytes(register_number, register_extractor, 0))
844 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000845 err.SetErrorStringWithFormat("Couldn't read %s from %s", name.GetCString(), register_info->name);
Sean Callanan17c6a052010-10-05 20:18:48 +0000846 return false;
847 }
848 }
849 else
850 {
851 // Moving from a register into addr
852 //
853 // Case 1: addr_byte_size and register_byte_size are the same
854 //
855 // |AABBCCDD| Register contents
856 // |AABBCCDD| Address contents
857 //
858 // Case 2: addr_byte_size is bigger than register_byte_size
859 //
860 // Error! (The register should always be big enough to hold the data)
861 //
862 // Case 3: register_byte_size is bigger than addr_byte_size
863 //
864 // |AABBCCDD| Register contents
865 // |AABB| Address contents on little-endian hardware
866 // |CCDD| Address contents on big-endian hardware
867
868 if (addr_byte_size > register_byte_size)
869 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000870 err.SetErrorStringWithFormat("%s is too big to store in %s", name.GetCString(), register_info->name);
Sean Callanan17c6a052010-10-05 20:18:48 +0000871 return false;
872 }
873
874 uint32_t register_offset;
875
876 switch (exe_ctx.process->GetByteOrder())
877 {
878 default:
Greg Clayton8de27c72010-10-15 22:48:33 +0000879 err.SetErrorStringWithFormat("%s is stored with an unhandled byte order", name.GetCString());
Sean Callanan17c6a052010-10-05 20:18:48 +0000880 return false;
881 case lldb::eByteOrderLittle:
882 register_offset = 0;
883 break;
884 case lldb::eByteOrderBig:
885 register_offset = register_byte_size - addr_byte_size;
886 break;
887 }
888
889 DataExtractor register_extractor;
890
891 if (!register_context->ReadRegisterBytes(register_number, register_extractor))
892 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000893 err.SetErrorStringWithFormat("Couldn't read %s from %s", name.GetCString(), register_info->name);
Sean Callanan17c6a052010-10-05 20:18:48 +0000894 return false;
895 }
896
897 const void *register_data = register_extractor.GetData(&register_offset, addr_byte_size);
898
899 if (!register_data)
900 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000901 err.SetErrorStringWithFormat("Read but couldn't extract data for %s from %s", name.GetCString(), register_info->name);
Sean Callanan17c6a052010-10-05 20:18:48 +0000902 return false;
903 }
904
905 Error error;
906 if (exe_ctx.process->WriteMemory (addr, register_data, addr_byte_size, error) != addr_byte_size)
907 {
908 err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", error.AsCString());
909 return false;
910 }
911 }
912 }
Sean Callananf328c9f2010-07-20 23:31:16 +0000913 }
914
915 return true;
Sean Callanan810f22d2010-07-16 00:09:46 +0000916}
917
Sean Callanancc074622010-09-14 21:59:34 +0000918Variable *
Greg Clayton8de27c72010-10-15 22:48:33 +0000919ClangExpressionDeclMap::FindVariableInScope
920(
921 StackFrame &frame,
922 const ConstString &name,
923 TypeFromUser *type
924)
Sean Callanancc074622010-09-14 21:59:34 +0000925{
Greg Claytone005f2c2010-11-06 01:53:30 +0000926 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanancc074622010-09-14 21:59:34 +0000927
Sean Callanancc074622010-09-14 21:59:34 +0000928 VariableList *var_list = frame.GetVariableList(true);
929
Greg Claytonbf8e42b2010-10-14 22:52:14 +0000930 if (!var_list)
931 return NULL;
932
Greg Clayton8de27c72010-10-15 22:48:33 +0000933 lldb::VariableSP var = var_list->FindVariable(name);
Sean Callanancc074622010-09-14 21:59:34 +0000934
935 if (!var)
936 return NULL;
937
938 if (!type)
939 return var.get();
940
941 if (type->GetASTContext() == var->GetType()->GetClangAST())
942 {
Greg Clayton462d4142010-09-29 01:12:09 +0000943 if (!ClangASTContext::AreTypesSame(type->GetASTContext(), type->GetOpaqueQualType(), var->GetType()->GetClangType()))
Sean Callanancc074622010-09-14 21:59:34 +0000944 return NULL;
945 }
946 else
947 {
948 if (log)
949 log->PutCString("Skipping a candidate variable because of different AST contexts");
950 return NULL;
951 }
952
953 return var.get();
Sean Callanancc074622010-09-14 21:59:34 +0000954}
Sean Callanan336a0002010-07-17 00:43:37 +0000955
Chris Lattner24943d22010-06-08 16:52:24 +0000956// Interface for ClangASTSource
957void
Greg Claytone5748d82010-11-09 23:46:37 +0000958ClangExpressionDeclMap::GetDecls (NameSearchContext &context, const ConstString &name)
Chris Lattner24943d22010-06-08 16:52:24 +0000959{
Greg Claytone005f2c2010-11-06 01:53:30 +0000960 lldb::LogSP 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 Claytone5748d82010-11-09 23:46:37 +0000969 SymbolContextList sc_list;
Chris Lattner24943d22010-06-08 16:52:24 +0000970
Greg Clayton8de27c72010-10-15 22:48:33 +0000971 // Only look for functions by name out in our symbols if the function
972 // doesn't start with our phony prefix of '$'
973 if (name.GetCString()[0] != '$')
Sean Callanan0fc73582010-07-27 00:55:47 +0000974 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000975
976 Variable *var = FindVariableInScope(*m_exe_ctx.frame, name);
977
978 // If we found a variable in scope, no need to pull up function names
979 if (var != NULL)
980 {
981 AddOneVariable(context, var);
982 }
983 else
984 {
Greg Claytone5748d82010-11-09 23:46:37 +0000985 m_sym_ctx.FindFunctionsByName (name, false, sc_list);
Greg Clayton8de27c72010-10-15 22:48:33 +0000986
987 bool found_specific = false;
988 Symbol *generic_symbol = NULL;
989 Symbol *non_extern_symbol = NULL;
990
Greg Claytone5748d82010-11-09 23:46:37 +0000991 for (uint32_t index = 0, num_indices = sc_list.GetSize();
Greg Clayton8de27c72010-10-15 22:48:33 +0000992 index < num_indices;
993 ++index)
994 {
995 SymbolContext sym_ctx;
Greg Claytone5748d82010-11-09 23:46:37 +0000996 sc_list.GetContextAtIndex(index, sym_ctx);
Sean Callanan3cfbd332010-10-06 00:10:07 +0000997
Greg Clayton8de27c72010-10-15 22:48:33 +0000998 if (sym_ctx.function)
999 {
1000 // TODO only do this if it's a C function; C++ functions may be
1001 // overloaded
1002 if (!found_specific)
1003 AddOneFunction(context, sym_ctx.function, NULL);
1004 found_specific = true;
1005 }
1006 else if (sym_ctx.symbol)
1007 {
1008 if (sym_ctx.symbol->IsExternal())
1009 generic_symbol = sym_ctx.symbol;
1010 else
1011 non_extern_symbol = sym_ctx.symbol;
1012 }
1013 }
1014
Sean Callanan92aa6662010-09-07 21:49:41 +00001015 if (!found_specific)
Greg Clayton8de27c72010-10-15 22:48:33 +00001016 {
1017 if (generic_symbol)
1018 AddOneFunction(context, NULL, generic_symbol);
1019 else if (non_extern_symbol)
1020 AddOneFunction(context, NULL, non_extern_symbol);
1021 }
Sean Callanan92aa6662010-09-07 21:49:41 +00001022 }
Sean Callanan0fc73582010-07-27 00:55:47 +00001023 }
Greg Clayton8de27c72010-10-15 22:48:33 +00001024 else
Sean Callanan3cfbd332010-10-06 00:10:07 +00001025 {
Greg Clayton57452832010-11-09 04:42:43 +00001026 static ConstString g_lldb_class_name ("$__lldb_class");
1027 if (name == g_lldb_class_name)
1028 {
1029 // Clang is looking for the type of "this"
1030
1031 VariableList *vars = m_exe_ctx.frame->GetVariableList(false);
1032
1033 if (!vars)
1034 return;
1035
1036 lldb::VariableSP this_var = vars->FindVariable(ConstString("this"));
1037
1038 if (!this_var)
1039 return;
1040
1041 Type *this_type = this_var->GetType();
1042
1043 if (!this_type)
1044 return;
1045
1046 TypeFromUser this_user_type(this_type->GetClangType(),
1047 this_type->GetClangAST());
1048
1049 m_object_pointer_type = this_user_type;
1050
1051 void *pointer_target_type;
1052
1053 if (!ClangASTContext::IsPointerType(this_user_type.GetOpaqueQualType(),
1054 &pointer_target_type))
1055 return;
1056
1057 TypeFromUser class_user_type(pointer_target_type,
1058 this_type->GetClangAST());
1059
1060 AddOneType(context, class_user_type, true);
1061
1062 return;
1063 }
1064
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{
Greg Claytone005f2c2010-11-06 01:53:30 +00001108 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan6184dfe2010-06-23 00:47:48 +00001109
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{
Greg Claytone005f2c2010-11-06 01:53:30 +00001215 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan336a0002010-07-17 00:43:37 +00001216
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 {
Sean Callanana0744822010-11-01 23:22:47 +00001241 std::string var_decl_print_string;
1242 llvm::raw_string_ostream var_decl_print_stream(var_decl_print_string);
1243 var_decl->print(var_decl_print_stream);
1244 var_decl_print_stream.flush();
1245
1246 log->Printf("Found variable %s, returned %s", decl_name.c_str(), var_decl_print_string.c_str());
Greg Clayton8de27c72010-10-15 22:48:33 +00001247 }
Sean Callanan8f0dc342010-06-22 23:46:24 +00001248}
1249
1250void
Sean Callanana48fe162010-08-11 03:57:18 +00001251ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
Sean Callanana6223432010-08-20 01:02:30 +00001252 ClangExpressionVariable *pvar)
Sean Callanana48fe162010-08-11 03:57:18 +00001253{
Greg Claytone005f2c2010-11-06 01:53:30 +00001254 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan45690fe2010-08-30 22:17:16 +00001255
Sean Callanana6223432010-08-20 01:02:30 +00001256 TypeFromUser user_type = pvar->m_user_type;
Sean Callanana48fe162010-08-11 03:57:18 +00001257
1258 TypeFromParser parser_type(ClangASTContext::CopyType(context.GetASTContext(),
1259 user_type.GetASTContext(),
1260 user_type.GetOpaqueQualType()),
1261 context.GetASTContext());
1262
Sean Callanan8c127202010-08-23 23:09:38 +00001263 NamedDecl *var_decl = context.AddVarDecl(parser_type.GetOpaqueQualType());
1264
1265 pvar->EnableParserVars();
1266 pvar->m_parser_vars->m_parser_type = parser_type;
1267 pvar->m_parser_vars->m_named_decl = var_decl;
1268 pvar->m_parser_vars->m_llvm_value = NULL;
1269 pvar->m_parser_vars->m_lldb_value = NULL;
Sean Callanan45690fe2010-08-30 22:17:16 +00001270
1271 if (log)
Sean Callanana0744822010-11-01 23:22:47 +00001272 {
1273 std::string var_decl_print_string;
1274 llvm::raw_string_ostream var_decl_print_stream(var_decl_print_string);
1275 var_decl->print(var_decl_print_stream);
1276 var_decl_print_stream.flush();
1277
1278 log->Printf("Added pvar %s, returned %s", pvar->m_name.GetCString(), var_decl_print_string.c_str());
1279 }
Sean Callanana48fe162010-08-11 03:57:18 +00001280}
1281
1282void
Sean Callanan8f0dc342010-06-22 23:46:24 +00001283ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
Sean Callanan0fc73582010-07-27 00:55:47 +00001284 Function* fun,
1285 Symbol* symbol)
Sean Callanan8f0dc342010-06-22 23:46:24 +00001286{
Greg Claytone005f2c2010-11-06 01:53:30 +00001287 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan8f0dc342010-06-22 23:46:24 +00001288
Sean Callanan0fc73582010-07-27 00:55:47 +00001289 NamedDecl *fun_decl;
Sean Callanan8f0dc342010-06-22 23:46:24 +00001290 std::auto_ptr<Value> fun_location(new Value);
Sean Callanan0fc73582010-07-27 00:55:47 +00001291 const Address *fun_address;
Sean Callanan8f0dc342010-06-22 23:46:24 +00001292
Sean Callanan0fc73582010-07-27 00:55:47 +00001293 // only valid for Functions, not for Symbols
1294 void *fun_opaque_type = NULL;
1295 clang::ASTContext *fun_ast_context = NULL;
1296
1297 if (fun)
1298 {
1299 Type *fun_type = fun->GetType();
1300
1301 if (!fun_type)
1302 {
1303 if (log)
1304 log->PutCString("Skipped a function because it has no type");
1305 return;
1306 }
1307
Greg Clayton462d4142010-09-29 01:12:09 +00001308 fun_opaque_type = fun_type->GetClangType();
Sean Callanan0fc73582010-07-27 00:55:47 +00001309
1310 if (!fun_opaque_type)
1311 {
1312 if (log)
1313 log->PutCString("Skipped a function because it has no Clang type");
1314 return;
1315 }
1316
1317 fun_address = &fun->GetAddressRange().GetBaseAddress();
1318
1319 TypeList *type_list = fun_type->GetTypeList();
1320 fun_ast_context = type_list->GetClangASTContext().getASTContext();
1321 void *copied_type = ClangASTContext::CopyType(context.GetASTContext(), fun_ast_context, fun_opaque_type);
1322
1323 fun_decl = context.AddFunDecl(copied_type);
1324 }
1325 else if (symbol)
1326 {
1327 fun_address = &symbol->GetAddressRangeRef().GetBaseAddress();
1328
1329 fun_decl = context.AddGenericFunDecl();
1330 }
1331 else
1332 {
1333 if (log)
1334 log->PutCString("AddOneFunction called with no function and no symbol");
1335 return;
1336 }
1337
Greg Clayton8de27c72010-10-15 22:48:33 +00001338 lldb::addr_t load_addr = fun_address->GetLoadAddress(m_exe_ctx.target);
Sean Callanan8f0dc342010-06-22 23:46:24 +00001339 fun_location->SetValueType(Value::eValueTypeLoadAddress);
1340 fun_location->GetScalar() = load_addr;
1341
Sean Callanan8c127202010-08-23 23:09:38 +00001342 ClangExpressionVariable &entity(m_found_entities.VariableAtIndex(m_found_entities.CreateVariable()));
Greg Clayton8de27c72010-10-15 22:48:33 +00001343 std::string decl_name(context.m_decl_name.getAsString());
1344 entity.m_name.SetCString(decl_name.c_str());
Sean Callanan8c127202010-08-23 23:09:38 +00001345 entity.m_user_type = TypeFromUser(fun_opaque_type, fun_ast_context);;
Sean Callanan8f0dc342010-06-22 23:46:24 +00001346
Sean Callanan8c127202010-08-23 23:09:38 +00001347 entity.EnableParserVars();
1348 entity.m_parser_vars->m_named_decl = fun_decl;
1349 entity.m_parser_vars->m_llvm_value = NULL;
1350 entity.m_parser_vars->m_lldb_value = fun_location.release();
1351
Sean Callanan810f22d2010-07-16 00:09:46 +00001352 if (log)
Greg Clayton8de27c72010-10-15 22:48:33 +00001353 {
Sean Callanana0744822010-11-01 23:22:47 +00001354 std::string fun_decl_print_string;
1355 llvm::raw_string_ostream fun_decl_print_stream(fun_decl_print_string);
1356 fun_decl->print(fun_decl_print_stream);
1357 fun_decl_print_stream.flush();
1358
1359 log->Printf("Found %s function %s, returned %s", (fun ? "specific" : "generic"), decl_name.c_str(), fun_decl_print_string.c_str());
Greg Clayton8de27c72010-10-15 22:48:33 +00001360 }
Chris Lattner24943d22010-06-08 16:52:24 +00001361}
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001362
1363void
1364ClangExpressionDeclMap::AddOneType(NameSearchContext &context,
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001365 TypeFromUser &ut,
1366 bool add_method)
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001367{
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001368 clang::ASTContext *parser_ast_context = context.GetASTContext();
1369 clang::ASTContext *user_ast_context = ut.GetASTContext();
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001370
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001371 void *copied_type = ClangASTContext::CopyType(parser_ast_context, user_ast_context, ut.GetOpaqueQualType());
1372
1373 TypeFromParser parser_type(copied_type, parser_ast_context);
1374
1375 if (add_method && ClangASTContext::IsAggregateType(copied_type))
1376 {
1377 void *args[1];
1378
1379 args[0] = ClangASTContext::GetVoidPtrType(parser_ast_context, false);
1380
1381 void *method_type = ClangASTContext::CreateFunctionType (parser_ast_context,
1382 ClangASTContext::GetBuiltInType_void(parser_ast_context),
1383 args,
1384 1,
1385 false,
1386 ClangASTContext::GetTypeQualifiers(copied_type));
Greg Clayton30449d52010-10-01 02:31:07 +00001387
Greg Clayton1d8173f2010-09-24 05:15:53 +00001388 const bool is_virtual = false;
1389 const bool is_static = false;
1390 const bool is_inline = false;
Greg Clayton30449d52010-10-01 02:31:07 +00001391 const bool is_explicit = false;
1392
Greg Clayton1d8173f2010-09-24 05:15:53 +00001393 ClangASTContext::AddMethodToCXXRecordType (parser_ast_context,
1394 copied_type,
Greg Clayton8de27c72010-10-15 22:48:33 +00001395 "$__lldb_expr",
Greg Clayton1d8173f2010-09-24 05:15:53 +00001396 method_type,
1397 lldb::eAccessPublic,
1398 is_virtual,
1399 is_static,
Greg Clayton30449d52010-10-01 02:31:07 +00001400 is_inline,
1401 is_explicit);
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001402 }
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001403
1404 context.AddTypeDecl(copied_type);
1405}