blob: 4b540c0fa38a27dcf6f7cd29e9f4903bd6e6429f [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)
Sean Callananc2c6f772010-10-26 00:31:56 +000091 {
92//#define SINGLE_STEP_EXPRESSIONS
93
94#ifndef SINGLE_STEP_EXPRESSIONS
Greg Clayton8de27c72010-10-15 22:48:33 +000095 m_exe_ctx.process->DeallocateMemory(m_materialized_location);
Sean Callananc2c6f772010-10-26 00:31:56 +000096#endif
Sean Callanan7a60b942010-10-08 01:58:41 +000097 m_materialized_location = 0;
98 }
Chris Lattner24943d22010-06-08 16:52:24 +000099}
100
Sean Callanan8bce6652010-07-13 21:41:46 +0000101// Interface for IRForTarget
102
Greg Clayton8de27c72010-10-15 22:48:33 +0000103const ConstString &
104ClangExpressionDeclMap::GetPersistentResultName ()
Sean Callanan82b74c82010-08-12 01:56:52 +0000105{
Greg Clayton8de27c72010-10-15 22:48:33 +0000106 if (!m_result_name)
107 m_persistent_vars->GetNextResultName(m_result_name);
108 return m_result_name;
Sean Callanan82b74c82010-08-12 01:56:52 +0000109}
110
Sean Callanan8bce6652010-07-13 21:41:46 +0000111bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000112ClangExpressionDeclMap::AddPersistentVariable
113(
114 const clang::NamedDecl *decl,
115 const ConstString &name,
116 TypeFromParser parser_type
117)
Sean Callanana48fe162010-08-11 03:57:18 +0000118{
Greg Clayton8de27c72010-10-15 22:48:33 +0000119 clang::ASTContext *context(m_exe_ctx.target->GetScratchClangASTContext()->getASTContext());
Sean Callanana48fe162010-08-11 03:57:18 +0000120
Sean Callanana48fe162010-08-11 03:57:18 +0000121 TypeFromUser user_type(ClangASTContext::CopyType(context,
Sean Callanan82b74c82010-08-12 01:56:52 +0000122 parser_type.GetASTContext(),
123 parser_type.GetOpaqueQualType()),
Sean Callanana48fe162010-08-11 03:57:18 +0000124 context);
125
Sean Callanan8c127202010-08-23 23:09:38 +0000126 if (!m_persistent_vars->CreatePersistentVariable (name, user_type))
127 return false;
128
129 ClangExpressionVariable *var = m_persistent_vars->GetVariable(name);
130
131 if (!var)
132 return false;
133
134 var->EnableParserVars();
135
136 var->m_parser_vars->m_named_decl = decl;
137 var->m_parser_vars->m_parser_type = parser_type;
138
139 return true;
Sean Callanana48fe162010-08-11 03:57:18 +0000140}
141
142bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000143ClangExpressionDeclMap::AddValueToStruct
144(
145 const clang::NamedDecl *decl,
146 const ConstString &name,
147 llvm::Value *value,
148 size_t size,
149 off_t alignment
150)
Sean Callanan8bce6652010-07-13 21:41:46 +0000151{
Sean Callanan45690fe2010-08-30 22:17:16 +0000152 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
153
Sean Callanan8bce6652010-07-13 21:41:46 +0000154 m_struct_laid_out = false;
155
Sean Callanan8c127202010-08-23 23:09:38 +0000156 if (m_struct_members.GetVariable(decl))
157 return true;
Sean Callanan8bce6652010-07-13 21:41:46 +0000158
Sean Callanan8c127202010-08-23 23:09:38 +0000159 ClangExpressionVariable *var = m_found_entities.GetVariable(decl);
Sean Callanan8bce6652010-07-13 21:41:46 +0000160
Sean Callanan8c127202010-08-23 23:09:38 +0000161 if (!var)
162 var = m_persistent_vars->GetVariable(decl);
Sean Callanan8bce6652010-07-13 21:41:46 +0000163
Sean Callanan8c127202010-08-23 23:09:38 +0000164 if (!var)
165 return false;
166
Sean Callanan45690fe2010-08-30 22:17:16 +0000167 if (log)
168 log->Printf("Adding value for decl %p [%s - %s] to the structure",
169 decl,
Greg Clayton8de27c72010-10-15 22:48:33 +0000170 name.GetCString(),
171 var->m_name.GetCString());
Sean Callanan45690fe2010-08-30 22:17:16 +0000172
Sean Callanan8c127202010-08-23 23:09:38 +0000173 // We know entity->m_parser_vars is valid because we used a parser variable
174 // to find it
175 var->m_parser_vars->m_llvm_value = value;
176
177 var->EnableJITVars();
178 var->m_jit_vars->m_alignment = alignment;
179 var->m_jit_vars->m_size = size;
180
181 m_struct_members.AddVariable(*var);
Sean Callanan8bce6652010-07-13 21:41:46 +0000182
183 return true;
184}
185
186bool
187ClangExpressionDeclMap::DoStructLayout ()
188{
189 if (m_struct_laid_out)
190 return true;
191
Sean Callanan8bce6652010-07-13 21:41:46 +0000192 off_t cursor = 0;
193
194 m_struct_alignment = 0;
195 m_struct_size = 0;
196
Sean Callanan8c127202010-08-23 23:09:38 +0000197 for (uint64_t member_index = 0, num_members = m_struct_members.Size();
198 member_index < num_members;
199 ++member_index)
Sean Callanan8bce6652010-07-13 21:41:46 +0000200 {
Sean Callanan8c127202010-08-23 23:09:38 +0000201 ClangExpressionVariable &member(m_struct_members.VariableAtIndex(member_index));
Sean Callanan8bce6652010-07-13 21:41:46 +0000202
Sean Callanan8c127202010-08-23 23:09:38 +0000203 if (!member.m_jit_vars.get())
204 return false;
Sean Callanan8bce6652010-07-13 21:41:46 +0000205
Sean Callanan8c127202010-08-23 23:09:38 +0000206 if (member_index == 0)
207 m_struct_alignment = member.m_jit_vars->m_alignment;
208
209 if (cursor % member.m_jit_vars->m_alignment)
210 cursor += (member.m_jit_vars->m_alignment - (cursor % member.m_jit_vars->m_alignment));
211
212 member.m_jit_vars->m_offset = cursor;
213 cursor += member.m_jit_vars->m_size;
Sean Callanan8bce6652010-07-13 21:41:46 +0000214 }
215
216 m_struct_size = cursor;
217
218 m_struct_laid_out = true;
219 return true;
220}
221
Greg Clayton8de27c72010-10-15 22:48:33 +0000222bool ClangExpressionDeclMap::GetStructInfo
223(
224 uint32_t &num_elements,
225 size_t &size,
226 off_t &alignment
227)
Sean Callanan8bce6652010-07-13 21:41:46 +0000228{
229 if (!m_struct_laid_out)
230 return false;
231
Sean Callanan8c127202010-08-23 23:09:38 +0000232 num_elements = m_struct_members.Size();
Sean Callanan8bce6652010-07-13 21:41:46 +0000233 size = m_struct_size;
234 alignment = m_struct_alignment;
235
236 return true;
237}
238
239bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000240ClangExpressionDeclMap::GetStructElement
241(
242 const clang::NamedDecl *&decl,
243 llvm::Value *&value,
244 off_t &offset,
245 ConstString &name,
246 uint32_t index
247)
Sean Callanan8bce6652010-07-13 21:41:46 +0000248{
249 if (!m_struct_laid_out)
250 return false;
251
Sean Callanan8c127202010-08-23 23:09:38 +0000252 if (index >= m_struct_members.Size())
Sean Callanan8bce6652010-07-13 21:41:46 +0000253 return false;
254
Sean Callanan8c127202010-08-23 23:09:38 +0000255 ClangExpressionVariable &member(m_struct_members.VariableAtIndex(index));
Sean Callanan8bce6652010-07-13 21:41:46 +0000256
Sean Callanan8c127202010-08-23 23:09:38 +0000257 if (!member.m_parser_vars.get() ||
258 !member.m_jit_vars.get())
259 return false;
260
261 decl = member.m_parser_vars->m_named_decl;
262 value = member.m_parser_vars->m_llvm_value;
263 offset = member.m_jit_vars->m_offset;
Greg Clayton8de27c72010-10-15 22:48:33 +0000264 name = member.m_name;
Sean Callanan8c127202010-08-23 23:09:38 +0000265
Sean Callanan8bce6652010-07-13 21:41:46 +0000266 return true;
267}
268
Sean Callanan02fbafa2010-07-27 21:39:39 +0000269bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000270ClangExpressionDeclMap::GetFunctionInfo
271(
272 const clang::NamedDecl *decl,
273 llvm::Value**& value,
274 uint64_t &ptr
275)
Sean Callananba992c52010-07-27 02:07:53 +0000276{
Sean Callanan8c127202010-08-23 23:09:38 +0000277 ClangExpressionVariable *entity = m_found_entities.GetVariable(decl);
278
279 if (!entity)
280 return false;
Sean Callananba992c52010-07-27 02:07:53 +0000281
Sean Callanan8c127202010-08-23 23:09:38 +0000282 // We know m_parser_vars is valid since we searched for the variable by
283 // its NamedDecl
Sean Callananba992c52010-07-27 02:07:53 +0000284
Sean Callanan8c127202010-08-23 23:09:38 +0000285 value = &entity->m_parser_vars->m_llvm_value;
286 ptr = entity->m_parser_vars->m_lldb_value->GetScalar().ULongLong();
287
288 return true;
Sean Callananba992c52010-07-27 02:07:53 +0000289}
290
Sean Callananf5857a02010-07-31 01:32:05 +0000291bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000292ClangExpressionDeclMap::GetFunctionAddress
293(
294 const ConstString &name,
295 uint64_t &ptr
296)
Sean Callananf5857a02010-07-31 01:32:05 +0000297{
298 // Back out in all cases where we're not fully initialized
Greg Clayton8de27c72010-10-15 22:48:33 +0000299 if (m_exe_ctx.frame == NULL)
Sean Callananf5857a02010-07-31 01:32:05 +0000300 return false;
301
Sean Callananf5857a02010-07-31 01:32:05 +0000302 SymbolContextList sym_ctxs;
303
Greg Clayton8de27c72010-10-15 22:48:33 +0000304 m_sym_ctx.FindFunctionsByName(name, false, sym_ctxs);
Sean Callananf5857a02010-07-31 01:32:05 +0000305
306 if (!sym_ctxs.GetSize())
307 return false;
308
309 SymbolContext sym_ctx;
310 sym_ctxs.GetContextAtIndex(0, sym_ctx);
311
312 const Address *fun_address;
313
314 if (sym_ctx.function)
315 fun_address = &sym_ctx.function->GetAddressRange().GetBaseAddress();
316 else if (sym_ctx.symbol)
317 fun_address = &sym_ctx.symbol->GetAddressRangeRef().GetBaseAddress();
318 else
319 return false;
320
Greg Clayton8de27c72010-10-15 22:48:33 +0000321 ptr = fun_address->GetLoadAddress (m_exe_ctx.target);
Sean Callananf5857a02010-07-31 01:32:05 +0000322
323 return true;
324}
325
Sean Callanan810f22d2010-07-16 00:09:46 +0000326// Interface for CommandObjectExpression
Sean Callananf328c9f2010-07-20 23:31:16 +0000327
328bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000329ClangExpressionDeclMap::Materialize
330(
331 ExecutionContext *exe_ctx,
332 lldb::addr_t &struct_address,
333 Error &err
334)
Sean Callananf328c9f2010-07-20 23:31:16 +0000335{
336 bool result = DoMaterialize(false, exe_ctx, NULL, err);
337
338 if (result)
339 struct_address = m_materialized_location;
340
341 return result;
342}
343
344bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000345ClangExpressionDeclMap::GetObjectPointer
346(
347 lldb::addr_t &object_ptr,
348 ExecutionContext *exe_ctx,
349 Error &err
350)
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000351{
352 if (!exe_ctx || !exe_ctx->frame || !exe_ctx->target || !exe_ctx->process)
353 {
354 err.SetErrorString("Couldn't load 'this' because the context is incomplete");
355 return false;
356 }
357
358 if (!m_object_pointer_type.GetOpaqueQualType())
359 {
360 err.SetErrorString("Couldn't load 'this' because its type is unknown");
361 return false;
362 }
363
Greg Clayton8de27c72010-10-15 22:48:33 +0000364 static ConstString g_this_cs ("this");
365 Variable *object_ptr_var = FindVariableInScope(*exe_ctx->frame, g_this_cs, &m_object_pointer_type);
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000366
367 if (!object_ptr_var)
368 {
369 err.SetErrorString("Couldn't find 'this' with appropriate type in scope");
370 return false;
371 }
372
373 std::auto_ptr<lldb_private::Value> location_value(GetVariableValue(*exe_ctx,
374 object_ptr_var,
375 m_object_pointer_type.GetASTContext()));
376
377 if (!location_value.get())
378 {
379 err.SetErrorString("Couldn't get the location for 'this'");
380 return false;
381 }
382
383 if (location_value->GetValueType() == Value::eValueTypeLoadAddress)
384 {
385 lldb::addr_t value_addr = location_value->GetScalar().ULongLong();
386 uint32_t address_byte_size = exe_ctx->target->GetArchitecture().GetAddressByteSize();
387 lldb::ByteOrder address_byte_order = exe_ctx->process->GetByteOrder();
388
389 if (ClangASTType::GetClangTypeBitWidth(m_object_pointer_type.GetASTContext(), m_object_pointer_type.GetOpaqueQualType()) != address_byte_size * 8)
390 {
391 err.SetErrorStringWithFormat("'this' is not of an expected pointer size");
392 return false;
393 }
394
395 DataBufferHeap data;
396 data.SetByteSize(address_byte_size);
397 Error read_error;
398
399 if (exe_ctx->process->ReadMemory (value_addr, data.GetBytes(), address_byte_size, read_error) != address_byte_size)
400 {
401 err.SetErrorStringWithFormat("Coldn't read 'this' from the target: %s", read_error.AsCString());
402 return false;
403 }
404
405 DataExtractor extractor(data.GetBytes(), data.GetByteSize(), address_byte_order, address_byte_size);
406
407 uint32_t offset = 0;
408
409 object_ptr = extractor.GetPointer(&offset);
410
411 return true;
412 }
413 else
414 {
415 err.SetErrorString("'this' is not in memory; LLDB must be extended to handle registers");
416 return false;
417 }
418}
419
420bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000421ClangExpressionDeclMap::Dematerialize
422(
423 ExecutionContext *exe_ctx,
424 ClangExpressionVariable *&result,
425 Error &err
426)
Sean Callananf328c9f2010-07-20 23:31:16 +0000427{
Sean Callanan82b74c82010-08-12 01:56:52 +0000428 return DoMaterialize(true, exe_ctx, &result, err);
Sean Callananf328c9f2010-07-20 23:31:16 +0000429}
430
Sean Callanan32824aa2010-07-23 22:19:18 +0000431bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000432ClangExpressionDeclMap::DumpMaterializedStruct
433(
434 ExecutionContext *exe_ctx,
435 Stream &s,
436 Error &err
437)
Sean Callanan32824aa2010-07-23 22:19:18 +0000438{
439 if (!m_struct_laid_out)
440 {
441 err.SetErrorString("Structure hasn't been laid out yet");
442 return false;
443 }
444
445 if (!exe_ctx)
446 {
447 err.SetErrorString("Received null execution context");
448 return false;
449 }
450
451
452 if (!exe_ctx->process)
453 {
454 err.SetErrorString("Couldn't find the process");
455 return false;
456 }
457
458 if (!exe_ctx->target)
459 {
460 err.SetErrorString("Couldn't find the target");
461 return false;
462 }
463
464 lldb::DataBufferSP data(new DataBufferHeap(m_struct_size, 0));
465
466 Error error;
467 if (exe_ctx->process->ReadMemory (m_materialized_location, data->GetBytes(), data->GetByteSize(), error) != data->GetByteSize())
468 {
469 err.SetErrorStringWithFormat ("Couldn't read struct from the target: %s", error.AsCString());
470 return false;
471 }
472
473 DataExtractor extractor(data, exe_ctx->process->GetByteOrder(), exe_ctx->target->GetArchitecture().GetAddressByteSize());
474
Sean Callanan8c127202010-08-23 23:09:38 +0000475 for (uint64_t member_index = 0, num_members = m_struct_members.Size();
476 member_index < num_members;
477 ++member_index)
Sean Callanan32824aa2010-07-23 22:19:18 +0000478 {
Sean Callanan8c127202010-08-23 23:09:38 +0000479 ClangExpressionVariable &member (m_struct_members.VariableAtIndex(member_index));
Sean Callanan32824aa2010-07-23 22:19:18 +0000480
Greg Clayton8de27c72010-10-15 22:48:33 +0000481 s.Printf("[%s]\n", member.m_name.GetCString());
Sean Callanan8c127202010-08-23 23:09:38 +0000482
483 if (!member.m_jit_vars.get())
484 return false;
485
486 extractor.Dump(&s, // stream
487 member.m_jit_vars->m_offset, // offset
488 lldb::eFormatBytesWithASCII, // format
489 1, // byte size of individual entries
490 member.m_jit_vars->m_size, // number of entries
491 16, // entries per line
492 m_materialized_location + member.m_jit_vars->m_offset, // address to print
493 0, // bit size (bitfields only; 0 means ignore)
494 0); // bit alignment (bitfields only; 0 means ignore)
Sean Callanan32824aa2010-07-23 22:19:18 +0000495
496 s.PutChar('\n');
497 }
498
499 return true;
500}
501
Sean Callananf328c9f2010-07-20 23:31:16 +0000502bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000503ClangExpressionDeclMap::DoMaterialize
504(
505 bool dematerialize,
506 ExecutionContext *exe_ctx,
507 ClangExpressionVariable **result,
508 Error &err
509)
Sean Callanan810f22d2010-07-16 00:09:46 +0000510{
Sean Callanan336a0002010-07-17 00:43:37 +0000511 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
Sean Callanan82b74c82010-08-12 01:56:52 +0000512
Sean Callanan810f22d2010-07-16 00:09:46 +0000513 if (!m_struct_laid_out)
514 {
515 err.SetErrorString("Structure hasn't been laid out yet");
516 return LLDB_INVALID_ADDRESS;
517 }
518
Sean Callanan810f22d2010-07-16 00:09:46 +0000519 if (!exe_ctx)
520 {
521 err.SetErrorString("Received null execution context");
522 return LLDB_INVALID_ADDRESS;
523 }
524
Sean Callanan45839272010-07-24 01:37:44 +0000525 if (!exe_ctx->frame)
526 {
527 err.SetErrorString("Received null execution frame");
528 return LLDB_INVALID_ADDRESS;
529 }
530
Sean Callanane8a59a82010-09-13 21:34:21 +0000531 if (!m_struct_size)
532 {
533 if (log)
534 log->PutCString("Not bothering to allocate a struct because no arguments are needed");
535
536 m_allocated_area = NULL;
537
538 return true;
539 }
540
Sean Callanan810f22d2010-07-16 00:09:46 +0000541 const SymbolContext &sym_ctx(exe_ctx->frame->GetSymbolContext(lldb::eSymbolContextEverything));
542
Sean Callananf328c9f2010-07-20 23:31:16 +0000543 if (!dematerialize)
Sean Callanan810f22d2010-07-16 00:09:46 +0000544 {
Sean Callananf328c9f2010-07-20 23:31:16 +0000545 if (m_materialized_location)
546 {
547 exe_ctx->process->DeallocateMemory(m_materialized_location);
548 m_materialized_location = 0;
549 }
550
Sean Callanan7a60b942010-10-08 01:58:41 +0000551 if (log)
552 log->PutCString("Allocating memory for materialized argument struct");
553
Sean Callananf328c9f2010-07-20 23:31:16 +0000554 lldb::addr_t mem = exe_ctx->process->AllocateMemory(m_struct_alignment + m_struct_size,
555 lldb::ePermissionsReadable | lldb::ePermissionsWritable,
556 err);
557
558 if (mem == LLDB_INVALID_ADDRESS)
559 return false;
560
561 m_allocated_area = mem;
Sean Callanan810f22d2010-07-16 00:09:46 +0000562 }
563
Sean Callananf328c9f2010-07-20 23:31:16 +0000564 m_materialized_location = m_allocated_area;
565
566 if (m_materialized_location % m_struct_alignment)
Sean Callananf328c9f2010-07-20 23:31:16 +0000567 m_materialized_location += (m_struct_alignment - (m_materialized_location % m_struct_alignment));
Sean Callananf328c9f2010-07-20 23:31:16 +0000568
Sean Callanan8c127202010-08-23 23:09:38 +0000569 for (uint64_t member_index = 0, num_members = m_struct_members.Size();
570 member_index < num_members;
571 ++member_index)
Sean Callanan810f22d2010-07-16 00:09:46 +0000572 {
Sean Callanan8c127202010-08-23 23:09:38 +0000573 ClangExpressionVariable &member (m_struct_members.VariableAtIndex(member_index));
Sean Callanan810f22d2010-07-16 00:09:46 +0000574
Sean Callanan8c127202010-08-23 23:09:38 +0000575 if (!member.m_parser_vars.get())
Sean Callanan336a0002010-07-17 00:43:37 +0000576 return false;
Sean Callanan8c127202010-08-23 23:09:38 +0000577
578 ClangExpressionVariable *entity = m_found_entities.GetVariable(member.m_parser_vars->m_named_decl);
Greg Clayton8de27c72010-10-15 22:48:33 +0000579 ClangExpressionVariable *persistent_variable = m_persistent_vars->GetVariable(member.m_name);
Sean Callanan8c127202010-08-23 23:09:38 +0000580
581 if (entity)
582 {
583 if (!member.m_jit_vars.get())
584 return false;
585
Greg Clayton8de27c72010-10-15 22:48:33 +0000586 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 +0000587 return false;
588 }
589 else if (persistent_variable)
590 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000591 if (member.m_name == m_result_name)
Sean Callanan45690fe2010-08-30 22:17:16 +0000592 {
593 if (!dematerialize)
594 continue;
Sean Callanan8c127202010-08-23 23:09:38 +0000595
Sean Callanan8c127202010-08-23 23:09:38 +0000596 if (log)
597 log->PutCString("Found result member in the struct");
Sean Callanan45690fe2010-08-30 22:17:16 +0000598
Sean Callanan8c127202010-08-23 23:09:38 +0000599 *result = &member;
600 }
601
Sean Callanan45690fe2010-08-30 22:17:16 +0000602 if (log)
Greg Clayton8de27c72010-10-15 22:48:33 +0000603 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 +0000604
Greg Clayton8de27c72010-10-15 22:48:33 +0000605 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 +0000606 return false;
607 }
608 else
609 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000610 err.SetErrorStringWithFormat("Unexpected variable %s", member.m_name.GetCString());
Sean Callanan8c127202010-08-23 23:09:38 +0000611 return false;
612 }
Sean Callanan810f22d2010-07-16 00:09:46 +0000613 }
614
Sean Callananf328c9f2010-07-20 23:31:16 +0000615 return true;
616}
617
Sean Callanana48fe162010-08-11 03:57:18 +0000618bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000619ClangExpressionDeclMap::DoMaterializeOnePersistentVariable
620(
621 bool dematerialize,
622 ExecutionContext &exe_ctx,
623 const ConstString &name,
624 lldb::addr_t addr,
625 Error &err
626)
Sean Callanan45690fe2010-08-30 22:17:16 +0000627{
Sean Callanana6223432010-08-20 01:02:30 +0000628 ClangExpressionVariable *pvar(m_persistent_vars->GetVariable(name));
Sean Callanana48fe162010-08-11 03:57:18 +0000629
630 if (!pvar)
631 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000632 err.SetErrorStringWithFormat("Undefined persistent variable %s", name.GetCString());
Sean Callanana48fe162010-08-11 03:57:18 +0000633 return LLDB_INVALID_ADDRESS;
634 }
635
636 size_t pvar_size = pvar->Size();
Sean Callanana6223432010-08-20 01:02:30 +0000637
Greg Clayton66ed2fb2010-10-05 00:00:42 +0000638 if (!pvar->m_data_sp.get())
Sean Callanana6223432010-08-20 01:02:30 +0000639 return false;
640
Greg Clayton66ed2fb2010-10-05 00:00:42 +0000641 uint8_t *pvar_data = pvar->m_data_sp->GetBytes();
Sean Callanana48fe162010-08-11 03:57:18 +0000642 Error error;
643
644 if (dematerialize)
645 {
646 if (exe_ctx.process->ReadMemory (addr, pvar_data, pvar_size, error) != pvar_size)
647 {
648 err.SetErrorStringWithFormat ("Couldn't read a composite type from the target: %s", error.AsCString());
649 return false;
650 }
651 }
652 else
653 {
654 if (exe_ctx.process->WriteMemory (addr, pvar_data, pvar_size, error) != pvar_size)
655 {
656 err.SetErrorStringWithFormat ("Couldn't write a composite type to the target: %s", error.AsCString());
657 return false;
658 }
659 }
660
661 return true;
662}
663
Sean Callananf328c9f2010-07-20 23:31:16 +0000664bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000665ClangExpressionDeclMap::DoMaterializeOneVariable
666(
667 bool dematerialize,
668 ExecutionContext &exe_ctx,
669 const SymbolContext &sym_ctx,
670 const ConstString &name,
671 TypeFromUser type,
672 lldb::addr_t addr,
673 Error &err
674)
Sean Callananf328c9f2010-07-20 23:31:16 +0000675{
676 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
677
Sean Callanan17c6a052010-10-05 20:18:48 +0000678 if (!exe_ctx.frame || !exe_ctx.process)
Sean Callanancc074622010-09-14 21:59:34 +0000679 return false;
680
681 Variable *var = FindVariableInScope(*exe_ctx.frame, name, &type);
Sean Callananf328c9f2010-07-20 23:31:16 +0000682
683 if (!var)
684 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000685 err.SetErrorStringWithFormat("Couldn't find %s with appropriate type", name.GetCString());
Sean Callananf328c9f2010-07-20 23:31:16 +0000686 return false;
687 }
688
Sean Callanan841026f2010-07-23 00:16:21 +0000689 if (log)
Greg Clayton8de27c72010-10-15 22:48:33 +0000690 log->Printf("%s %s with type %p", (dematerialize ? "Dematerializing" : "Materializing"), name.GetCString(), type.GetOpaqueQualType());
Sean Callananf328c9f2010-07-20 23:31:16 +0000691
692 std::auto_ptr<lldb_private::Value> location_value(GetVariableValue(exe_ctx,
693 var,
694 type.GetASTContext()));
695
696 if (!location_value.get())
697 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000698 err.SetErrorStringWithFormat("Couldn't get value for %s", name.GetCString());
Sean Callananf328c9f2010-07-20 23:31:16 +0000699 return false;
700 }
Sean Callanan17c6a052010-10-05 20:18:48 +0000701
702 // The size of the type contained in addr
Sean Callananf328c9f2010-07-20 23:31:16 +0000703
Sean Callanan17c6a052010-10-05 20:18:48 +0000704 size_t addr_bit_size = ClangASTType::GetClangTypeBitWidth(type.GetASTContext(), type.GetOpaqueQualType());
705 size_t addr_byte_size = addr_bit_size % 8 ? ((addr_bit_size + 8) / 8) : (addr_bit_size / 8);
706
707 Value::ValueType value_type = location_value->GetValueType();
708
709 switch (value_type)
Sean Callananf328c9f2010-07-20 23:31:16 +0000710 {
Sean Callanan17c6a052010-10-05 20:18:48 +0000711 default:
Sean Callananf328c9f2010-07-20 23:31:16 +0000712 {
Sean Callanan17c6a052010-10-05 20:18:48 +0000713 StreamString ss;
714
715 location_value->Dump(&ss);
716
Greg Clayton8de27c72010-10-15 22:48:33 +0000717 err.SetErrorStringWithFormat("%s has a value of unhandled type: %s", name.GetCString(), ss.GetString().c_str());
Sean Callananf328c9f2010-07-20 23:31:16 +0000718 return false;
719 }
Sean Callanan17c6a052010-10-05 20:18:48 +0000720 break;
721 case Value::eValueTypeLoadAddress:
Sean Callananf328c9f2010-07-20 23:31:16 +0000722 {
Sean Callanan17c6a052010-10-05 20:18:48 +0000723 lldb::addr_t value_addr = location_value->GetScalar().ULongLong();
724
725 DataBufferHeap data;
726 data.SetByteSize(addr_byte_size);
727
728 lldb::addr_t src_addr;
729 lldb::addr_t dest_addr;
730
731 if (dematerialize)
732 {
733 src_addr = addr;
734 dest_addr = value_addr;
735 }
736 else
737 {
738 src_addr = value_addr;
739 dest_addr = addr;
740 }
741
742 Error error;
743 if (exe_ctx.process->ReadMemory (src_addr, data.GetBytes(), addr_byte_size, error) != addr_byte_size)
744 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000745 err.SetErrorStringWithFormat ("Couldn't read %s from the target: %s", name.GetCString(), error.AsCString());
Sean Callanan17c6a052010-10-05 20:18:48 +0000746 return false;
747 }
748
749 if (exe_ctx.process->WriteMemory (dest_addr, data.GetBytes(), addr_byte_size, error) != addr_byte_size)
750 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000751 err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", name.GetCString(), error.AsCString());
Sean Callanan17c6a052010-10-05 20:18:48 +0000752 return false;
753 }
754
755 if (log)
756 log->Printf("Copied from 0x%llx to 0x%llx", (uint64_t)src_addr, (uint64_t)addr);
Sean Callananf328c9f2010-07-20 23:31:16 +0000757 }
Sean Callanan17c6a052010-10-05 20:18:48 +0000758 break;
759 case Value::eValueTypeScalar:
760 {
761 if (location_value->GetContextType() != Value::eContextTypeDCRegisterInfo)
762 {
763 StreamString ss;
764
765 location_value->Dump(&ss);
766
Greg Clayton8de27c72010-10-15 22:48:33 +0000767 err.SetErrorStringWithFormat("%s is a scalar of unhandled type: %s", name.GetCString(), ss.GetString().c_str());
Sean Callanan17c6a052010-10-05 20:18:48 +0000768 return false;
769 }
770
771 lldb::RegisterInfo *register_info = location_value->GetRegisterInfo();
772
773 if (!register_info)
774 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000775 err.SetErrorStringWithFormat("Couldn't get the register information for %s", name.GetCString());
Sean Callanan17c6a052010-10-05 20:18:48 +0000776 return false;
777 }
778
779 RegisterContext *register_context = exe_ctx.GetRegisterContext();
780
781 if (!register_context)
782 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000783 err.SetErrorStringWithFormat("Couldn't read register context to read %s from %s", name.GetCString(), register_info->name);
Sean Callanan17c6a052010-10-05 20:18:48 +0000784 return false;
785 }
786
787 uint32_t register_number = register_info->kinds[lldb::eRegisterKindLLDB];
788 uint32_t register_byte_size = register_info->byte_size;
789
790 if (dematerialize)
791 {
792 // Moving from addr into a register
793 //
794 // Case 1: addr_byte_size and register_byte_size are the same
795 //
796 // |AABBCCDD| Address contents
797 // |AABBCCDD| Register contents
798 //
799 // Case 2: addr_byte_size is bigger than register_byte_size
800 //
801 // Error! (The register should always be big enough to hold the data)
802 //
803 // Case 3: register_byte_size is bigger than addr_byte_size
804 //
805 // |AABB| Address contents
806 // |AABB0000| Register contents [on little-endian hardware]
807 // |0000AABB| Register contents [on big-endian hardware]
808
809 if (addr_byte_size > register_byte_size)
810 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000811 err.SetErrorStringWithFormat("%s is too big to store in %s", name.GetCString(), register_info->name);
Sean Callanan17c6a052010-10-05 20:18:48 +0000812 return false;
813 }
814
815 uint32_t register_offset;
816
817 switch (exe_ctx.process->GetByteOrder())
818 {
819 default:
Greg Clayton8de27c72010-10-15 22:48:33 +0000820 err.SetErrorStringWithFormat("%s is stored with an unhandled byte order", name.GetCString());
Sean Callanan17c6a052010-10-05 20:18:48 +0000821 return false;
822 case lldb::eByteOrderLittle:
823 register_offset = 0;
824 break;
825 case lldb::eByteOrderBig:
826 register_offset = register_byte_size - addr_byte_size;
827 break;
828 }
829
830 DataBufferHeap register_data (register_byte_size, 0);
831
832 Error error;
833 if (exe_ctx.process->ReadMemory (addr, register_data.GetBytes() + register_offset, addr_byte_size, error) != addr_byte_size)
834 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000835 err.SetErrorStringWithFormat ("Couldn't read %s from the target: %s", name.GetCString(), error.AsCString());
Sean Callanan17c6a052010-10-05 20:18:48 +0000836 return false;
837 }
838
839 DataExtractor register_extractor (register_data.GetBytes(), register_byte_size, exe_ctx.process->GetByteOrder(), exe_ctx.process->GetAddressByteSize());
840
841 if (!register_context->WriteRegisterBytes(register_number, register_extractor, 0))
842 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000843 err.SetErrorStringWithFormat("Couldn't read %s from %s", name.GetCString(), register_info->name);
Sean Callanan17c6a052010-10-05 20:18:48 +0000844 return false;
845 }
846 }
847 else
848 {
849 // Moving from a register into addr
850 //
851 // Case 1: addr_byte_size and register_byte_size are the same
852 //
853 // |AABBCCDD| Register contents
854 // |AABBCCDD| Address contents
855 //
856 // Case 2: addr_byte_size is bigger than register_byte_size
857 //
858 // Error! (The register should always be big enough to hold the data)
859 //
860 // Case 3: register_byte_size is bigger than addr_byte_size
861 //
862 // |AABBCCDD| Register contents
863 // |AABB| Address contents on little-endian hardware
864 // |CCDD| Address contents on big-endian hardware
865
866 if (addr_byte_size > register_byte_size)
867 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000868 err.SetErrorStringWithFormat("%s is too big to store in %s", name.GetCString(), register_info->name);
Sean Callanan17c6a052010-10-05 20:18:48 +0000869 return false;
870 }
871
872 uint32_t register_offset;
873
874 switch (exe_ctx.process->GetByteOrder())
875 {
876 default:
Greg Clayton8de27c72010-10-15 22:48:33 +0000877 err.SetErrorStringWithFormat("%s is stored with an unhandled byte order", name.GetCString());
Sean Callanan17c6a052010-10-05 20:18:48 +0000878 return false;
879 case lldb::eByteOrderLittle:
880 register_offset = 0;
881 break;
882 case lldb::eByteOrderBig:
883 register_offset = register_byte_size - addr_byte_size;
884 break;
885 }
886
887 DataExtractor register_extractor;
888
889 if (!register_context->ReadRegisterBytes(register_number, register_extractor))
890 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000891 err.SetErrorStringWithFormat("Couldn't read %s from %s", name.GetCString(), register_info->name);
Sean Callanan17c6a052010-10-05 20:18:48 +0000892 return false;
893 }
894
895 const void *register_data = register_extractor.GetData(&register_offset, addr_byte_size);
896
897 if (!register_data)
898 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000899 err.SetErrorStringWithFormat("Read but couldn't extract data for %s from %s", name.GetCString(), register_info->name);
Sean Callanan17c6a052010-10-05 20:18:48 +0000900 return false;
901 }
902
903 Error error;
904 if (exe_ctx.process->WriteMemory (addr, register_data, addr_byte_size, error) != addr_byte_size)
905 {
906 err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", error.AsCString());
907 return false;
908 }
909 }
910 }
Sean Callananf328c9f2010-07-20 23:31:16 +0000911 }
912
913 return true;
Sean Callanan810f22d2010-07-16 00:09:46 +0000914}
915
Sean Callanancc074622010-09-14 21:59:34 +0000916Variable *
Greg Clayton8de27c72010-10-15 22:48:33 +0000917ClangExpressionDeclMap::FindVariableInScope
918(
919 StackFrame &frame,
920 const ConstString &name,
921 TypeFromUser *type
922)
Sean Callanancc074622010-09-14 21:59:34 +0000923{
924 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
925
Sean Callanancc074622010-09-14 21:59:34 +0000926 VariableList *var_list = frame.GetVariableList(true);
927
Greg Claytonbf8e42b2010-10-14 22:52:14 +0000928 if (!var_list)
929 return NULL;
930
Greg Clayton8de27c72010-10-15 22:48:33 +0000931 lldb::VariableSP var = var_list->FindVariable(name);
Sean Callanancc074622010-09-14 21:59:34 +0000932
933 if (!var)
934 return NULL;
935
936 if (!type)
937 return var.get();
938
939 if (type->GetASTContext() == var->GetType()->GetClangAST())
940 {
Greg Clayton462d4142010-09-29 01:12:09 +0000941 if (!ClangASTContext::AreTypesSame(type->GetASTContext(), type->GetOpaqueQualType(), var->GetType()->GetClangType()))
Sean Callanancc074622010-09-14 21:59:34 +0000942 return NULL;
943 }
944 else
945 {
946 if (log)
947 log->PutCString("Skipping a candidate variable because of different AST contexts");
948 return NULL;
949 }
950
951 return var.get();
952
953 return NULL;
954}
Sean Callanan336a0002010-07-17 00:43:37 +0000955
Chris Lattner24943d22010-06-08 16:52:24 +0000956// Interface for ClangASTSource
957void
Greg Clayton8de27c72010-10-15 22:48:33 +0000958ClangExpressionDeclMap::GetDecls
959(
960 NameSearchContext &context,
961 const ConstString &name
962)
Chris Lattner24943d22010-06-08 16:52:24 +0000963{
Sean Callanan6184dfe2010-06-23 00:47:48 +0000964 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000965
Sean Callanan810f22d2010-07-16 00:09:46 +0000966 if (log)
Greg Clayton8de27c72010-10-15 22:48:33 +0000967 log->Printf("Hunting for a definition for '%s'", name.GetCString());
Chris Lattner24943d22010-06-08 16:52:24 +0000968
969 // Back out in all cases where we're not fully initialized
Greg Clayton8de27c72010-10-15 22:48:33 +0000970 if (m_exe_ctx.frame == NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000971 return;
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000972
Greg Clayton8de27c72010-10-15 22:48:33 +0000973 static ConstString g_lldb_class_name ("$__lldb_class");
974 if (name == g_lldb_class_name)
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000975 {
976 // Clang is looking for the type of "this"
977
Greg Clayton8de27c72010-10-15 22:48:33 +0000978 VariableList *vars = m_exe_ctx.frame->GetVariableList(false);
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000979
980 if (!vars)
981 return;
982
983 lldb::VariableSP this_var = vars->FindVariable(ConstString("this"));
984
985 if (!this_var)
986 return;
987
988 Type *this_type = this_var->GetType();
989
990 if (!this_type)
991 return;
992
Greg Clayton462d4142010-09-29 01:12:09 +0000993 TypeFromUser this_user_type(this_type->GetClangType(),
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000994 this_type->GetClangAST());
995
996 m_object_pointer_type = this_user_type;
997
998 void *pointer_target_type;
999
1000 if (!ClangASTContext::IsPointerType(this_user_type.GetOpaqueQualType(),
1001 &pointer_target_type))
1002 return;
1003
1004 TypeFromUser class_user_type(pointer_target_type,
1005 this_type->GetClangAST());
1006
1007 AddOneType(context, class_user_type, true);
1008
1009 return;
1010 }
1011
Sean Callanan0fc73582010-07-27 00:55:47 +00001012 SymbolContextList sym_ctxs;
Chris Lattner24943d22010-06-08 16:52:24 +00001013
Greg Clayton8de27c72010-10-15 22:48:33 +00001014 // Only look for functions by name out in our symbols if the function
1015 // doesn't start with our phony prefix of '$'
1016 if (name.GetCString()[0] != '$')
Sean Callanan0fc73582010-07-27 00:55:47 +00001017 {
Greg Clayton8de27c72010-10-15 22:48:33 +00001018
1019 Variable *var = FindVariableInScope(*m_exe_ctx.frame, name);
1020
1021 // If we found a variable in scope, no need to pull up function names
1022 if (var != NULL)
1023 {
1024 AddOneVariable(context, var);
1025 }
1026 else
1027 {
1028 m_sym_ctx.FindFunctionsByName (name, false, sym_ctxs);
1029
1030 bool found_specific = false;
1031 Symbol *generic_symbol = NULL;
1032 Symbol *non_extern_symbol = NULL;
1033
1034 for (uint32_t index = 0, num_indices = sym_ctxs.GetSize();
1035 index < num_indices;
1036 ++index)
1037 {
1038 SymbolContext sym_ctx;
1039 sym_ctxs.GetContextAtIndex(index, sym_ctx);
Sean Callanan3cfbd332010-10-06 00:10:07 +00001040
Greg Clayton8de27c72010-10-15 22:48:33 +00001041 if (sym_ctx.function)
1042 {
1043 // TODO only do this if it's a C function; C++ functions may be
1044 // overloaded
1045 if (!found_specific)
1046 AddOneFunction(context, sym_ctx.function, NULL);
1047 found_specific = true;
1048 }
1049 else if (sym_ctx.symbol)
1050 {
1051 if (sym_ctx.symbol->IsExternal())
1052 generic_symbol = sym_ctx.symbol;
1053 else
1054 non_extern_symbol = sym_ctx.symbol;
1055 }
1056 }
1057
Sean Callanan92aa6662010-09-07 21:49:41 +00001058 if (!found_specific)
Greg Clayton8de27c72010-10-15 22:48:33 +00001059 {
1060 if (generic_symbol)
1061 AddOneFunction(context, NULL, generic_symbol);
1062 else if (non_extern_symbol)
1063 AddOneFunction(context, NULL, non_extern_symbol);
1064 }
Sean Callanan92aa6662010-09-07 21:49:41 +00001065 }
Sean Callanan0fc73582010-07-27 00:55:47 +00001066 }
Greg Clayton8de27c72010-10-15 22:48:33 +00001067 else
Sean Callanan3cfbd332010-10-06 00:10:07 +00001068 {
Greg Clayton8de27c72010-10-15 22:48:33 +00001069 ClangExpressionVariable *pvar(m_persistent_vars->GetVariable(name));
1070
1071 if (pvar)
1072 AddOneVariable(context, pvar);
Sean Callanan3cfbd332010-10-06 00:10:07 +00001073 }
1074
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001075
Sean Callanan6df08402010-09-27 23:54:58 +00001076 // See information on gating of this operation next to the definition for
1077 // m_lookedup_types.
1078
Greg Clayton8de27c72010-10-15 22:48:33 +00001079 const char *name_uniq = name.GetCString();
Sean Callanan6df08402010-09-27 23:54:58 +00001080
1081 if (m_lookedup_types.find(name_uniq) == m_lookedup_types.end())
1082 {
1083 // 1 The name is added to m_lookedup_types.
1084 m_lookedup_types.insert(std::pair<const char*, bool>(name_uniq, true));
1085
1086 // 2 The type is looked up and added, potentially causing more type loookups.
Greg Clayton8de27c72010-10-15 22:48:33 +00001087 lldb::TypeSP type = m_sym_ctx.FindTypeByName (name);
Sean Callanan6df08402010-09-27 23:54:58 +00001088
1089 if (type.get())
1090 {
Greg Clayton462d4142010-09-29 01:12:09 +00001091 TypeFromUser user_type(type->GetClangType(),
Sean Callanan6df08402010-09-27 23:54:58 +00001092 type->GetClangAST());
1093
1094 AddOneType(context, user_type, false);
1095 }
1096
1097 // 3 The name is removed from m_lookedup_types.
1098 m_lookedup_types.erase(name_uniq);
1099 }
Sean Callanan336a0002010-07-17 00:43:37 +00001100}
1101
1102Value *
Greg Clayton8de27c72010-10-15 22:48:33 +00001103ClangExpressionDeclMap::GetVariableValue
1104(
1105 ExecutionContext &exe_ctx,
1106 Variable *var,
1107 clang::ASTContext *parser_ast_context,
1108 TypeFromUser *user_type,
1109 TypeFromParser *parser_type
1110)
Chris Lattner24943d22010-06-08 16:52:24 +00001111{
Sean Callanan6184dfe2010-06-23 00:47:48 +00001112 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
1113
Chris Lattner24943d22010-06-08 16:52:24 +00001114 Type *var_type = var->GetType();
1115
1116 if (!var_type)
1117 {
Sean Callanan810f22d2010-07-16 00:09:46 +00001118 if (log)
1119 log->PutCString("Skipped a definition because it has no type");
Sean Callanan336a0002010-07-17 00:43:37 +00001120 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001121 }
1122
Greg Clayton462d4142010-09-29 01:12:09 +00001123 void *var_opaque_type = var_type->GetClangType();
Chris Lattner24943d22010-06-08 16:52:24 +00001124
1125 if (!var_opaque_type)
1126 {
Sean Callanan810f22d2010-07-16 00:09:46 +00001127 if (log)
1128 log->PutCString("Skipped a definition because it has no Clang type");
Sean Callanan336a0002010-07-17 00:43:37 +00001129 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001130 }
1131
Chris Lattner24943d22010-06-08 16:52:24 +00001132 TypeList *type_list = var_type->GetTypeList();
1133
1134 if (!type_list)
1135 {
Sean Callanan810f22d2010-07-16 00:09:46 +00001136 if (log)
1137 log->PutCString("Skipped a definition because the type has no associated type list");
Sean Callanan336a0002010-07-17 00:43:37 +00001138 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001139 }
1140
1141 clang::ASTContext *exe_ast_ctx = type_list->GetClangASTContext().getASTContext();
1142
1143 if (!exe_ast_ctx)
1144 {
Sean Callanan810f22d2010-07-16 00:09:46 +00001145 if (log)
1146 log->PutCString("There is no AST context for the current execution context");
Sean Callanan336a0002010-07-17 00:43:37 +00001147 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001148 }
1149
Sean Callanan336a0002010-07-17 00:43:37 +00001150 DWARFExpression &var_location_expr = var->LocationExpression();
1151
Chris Lattner24943d22010-06-08 16:52:24 +00001152 std::auto_ptr<Value> var_location(new Value);
1153
Greg Clayton178710c2010-09-14 02:20:48 +00001154 lldb::addr_t loclist_base_load_addr = LLDB_INVALID_ADDRESS;
1155
1156 if (var_location_expr.IsLocationList())
1157 {
1158 SymbolContext var_sc;
1159 var->CalculateSymbolContext (&var_sc);
Greg Claytoneea26402010-09-14 23:36:40 +00001160 loclist_base_load_addr = var_sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (exe_ctx.target);
Greg Clayton178710c2010-09-14 02:20:48 +00001161 }
Chris Lattner24943d22010-06-08 16:52:24 +00001162 Error err;
1163
Greg Clayton178710c2010-09-14 02:20:48 +00001164 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 +00001165 {
Sean Callanan810f22d2010-07-16 00:09:46 +00001166 if (log)
1167 log->Printf("Error evaluating location: %s", err.AsCString());
Sean Callanan336a0002010-07-17 00:43:37 +00001168 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001169 }
1170
Sean Callanan810f22d2010-07-16 00:09:46 +00001171 clang::ASTContext *var_ast_context = type_list->GetClangASTContext().getASTContext();
1172
Sean Callanan336a0002010-07-17 00:43:37 +00001173 void *type_to_use;
1174
Sean Callananf328c9f2010-07-20 23:31:16 +00001175 if (parser_ast_context)
1176 {
1177 type_to_use = ClangASTContext::CopyType(parser_ast_context, var_ast_context, var_opaque_type);
1178
1179 if (parser_type)
1180 *parser_type = TypeFromParser(type_to_use, parser_ast_context);
1181 }
Sean Callanan336a0002010-07-17 00:43:37 +00001182 else
1183 type_to_use = var_opaque_type;
Chris Lattner24943d22010-06-08 16:52:24 +00001184
1185 if (var_location.get()->GetContextType() == Value::eContextTypeInvalid)
Sean Callanan336a0002010-07-17 00:43:37 +00001186 var_location.get()->SetContext(Value::eContextTypeOpaqueClangQualType, type_to_use);
Chris Lattner24943d22010-06-08 16:52:24 +00001187
1188 if (var_location.get()->GetValueType() == Value::eValueTypeFileAddress)
1189 {
1190 SymbolContext var_sc;
1191 var->CalculateSymbolContext(&var_sc);
Sean Callanan336a0002010-07-17 00:43:37 +00001192
Chris Lattner24943d22010-06-08 16:52:24 +00001193 if (!var_sc.module_sp)
Sean Callanan336a0002010-07-17 00:43:37 +00001194 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001195
1196 ObjectFile *object_file = var_sc.module_sp->GetObjectFile();
1197
1198 if (!object_file)
Sean Callanan336a0002010-07-17 00:43:37 +00001199 return NULL;
1200
Chris Lattner24943d22010-06-08 16:52:24 +00001201 Address so_addr(var_location->GetScalar().ULongLong(), object_file->GetSectionList());
1202
Greg Clayton8de27c72010-10-15 22:48:33 +00001203 lldb::addr_t load_addr = so_addr.GetLoadAddress(m_exe_ctx.target);
Chris Lattner24943d22010-06-08 16:52:24 +00001204
1205 var_location->GetScalar() = load_addr;
1206 var_location->SetValueType(Value::eValueTypeLoadAddress);
1207 }
1208
Sean Callananf328c9f2010-07-20 23:31:16 +00001209 if (user_type)
1210 *user_type = TypeFromUser(var_opaque_type, var_ast_context);
Sean Callanan336a0002010-07-17 00:43:37 +00001211
1212 return var_location.release();
1213}
1214
1215void
1216ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001217 Variable* var)
Sean Callanan336a0002010-07-17 00:43:37 +00001218{
1219 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
1220
Sean Callananf328c9f2010-07-20 23:31:16 +00001221 TypeFromUser ut;
1222 TypeFromParser pt;
Sean Callanan336a0002010-07-17 00:43:37 +00001223
Greg Clayton8de27c72010-10-15 22:48:33 +00001224 Value *var_location = GetVariableValue (m_exe_ctx,
1225 var,
1226 context.GetASTContext(),
1227 &ut,
1228 &pt);
Sean Callanan336a0002010-07-17 00:43:37 +00001229
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001230 NamedDecl *var_decl = context.AddVarDecl(pt.GetOpaqueQualType());
Chris Lattner24943d22010-06-08 16:52:24 +00001231
Sean Callanan8c127202010-08-23 23:09:38 +00001232 ClangExpressionVariable &entity(m_found_entities.VariableAtIndex(m_found_entities.CreateVariable()));
Greg Clayton8de27c72010-10-15 22:48:33 +00001233 std::string decl_name(context.m_decl_name.getAsString());
1234 entity.m_name.SetCString (decl_name.c_str());
1235 entity.m_user_type = ut;
Chris Lattner24943d22010-06-08 16:52:24 +00001236
Sean Callanan8c127202010-08-23 23:09:38 +00001237 entity.EnableParserVars();
1238 entity.m_parser_vars->m_parser_type = pt;
1239 entity.m_parser_vars->m_named_decl = var_decl;
1240 entity.m_parser_vars->m_llvm_value = NULL;
1241 entity.m_parser_vars->m_lldb_value = var_location;
Chris Lattner24943d22010-06-08 16:52:24 +00001242
Sean Callanan810f22d2010-07-16 00:09:46 +00001243 if (log)
Greg Clayton8de27c72010-10-15 22:48:33 +00001244 {
1245 log->Printf("Found variable %s, returned (NamedDecl)%p", decl_name.c_str(), var_decl);
1246 }
Sean Callanan8f0dc342010-06-22 23:46:24 +00001247}
1248
1249void
Sean Callanana48fe162010-08-11 03:57:18 +00001250ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
Sean Callanana6223432010-08-20 01:02:30 +00001251 ClangExpressionVariable *pvar)
Sean Callanana48fe162010-08-11 03:57:18 +00001252{
Sean Callanan45690fe2010-08-30 22:17:16 +00001253 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
1254
Sean Callanana6223432010-08-20 01:02:30 +00001255 TypeFromUser user_type = pvar->m_user_type;
Sean Callanana48fe162010-08-11 03:57:18 +00001256
1257 TypeFromParser parser_type(ClangASTContext::CopyType(context.GetASTContext(),
1258 user_type.GetASTContext(),
1259 user_type.GetOpaqueQualType()),
1260 context.GetASTContext());
1261
Sean Callanan8c127202010-08-23 23:09:38 +00001262 NamedDecl *var_decl = context.AddVarDecl(parser_type.GetOpaqueQualType());
1263
1264 pvar->EnableParserVars();
1265 pvar->m_parser_vars->m_parser_type = parser_type;
1266 pvar->m_parser_vars->m_named_decl = var_decl;
1267 pvar->m_parser_vars->m_llvm_value = NULL;
1268 pvar->m_parser_vars->m_lldb_value = NULL;
Sean Callanan45690fe2010-08-30 22:17:16 +00001269
1270 if (log)
Greg Clayton8de27c72010-10-15 22:48:33 +00001271 log->Printf("Added pvar %s, returned (NamedDecl)%p", pvar->m_name.GetCString(), var_decl);
Sean Callanana48fe162010-08-11 03:57:18 +00001272}
1273
1274void
Sean Callanan8f0dc342010-06-22 23:46:24 +00001275ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
Sean Callanan0fc73582010-07-27 00:55:47 +00001276 Function* fun,
1277 Symbol* symbol)
Sean Callanan8f0dc342010-06-22 23:46:24 +00001278{
Sean Callanan6184dfe2010-06-23 00:47:48 +00001279 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
Sean Callanan8f0dc342010-06-22 23:46:24 +00001280
Sean Callanan0fc73582010-07-27 00:55:47 +00001281 NamedDecl *fun_decl;
Sean Callanan8f0dc342010-06-22 23:46:24 +00001282 std::auto_ptr<Value> fun_location(new Value);
Sean Callanan0fc73582010-07-27 00:55:47 +00001283 const Address *fun_address;
Sean Callanan8f0dc342010-06-22 23:46:24 +00001284
Sean Callanan0fc73582010-07-27 00:55:47 +00001285 // only valid for Functions, not for Symbols
1286 void *fun_opaque_type = NULL;
1287 clang::ASTContext *fun_ast_context = NULL;
1288
1289 if (fun)
1290 {
Sean Callanan55261a12010-09-08 22:38:54 +00001291#define BROKEN_OVERLOADING
1292 // Awaiting a fix on the Clang side
1293#ifndef BROKEN_OVERLOADING
Sean Callanan0fc73582010-07-27 00:55:47 +00001294 Type *fun_type = fun->GetType();
1295
1296 if (!fun_type)
1297 {
1298 if (log)
1299 log->PutCString("Skipped a function because it has no type");
1300 return;
1301 }
1302
Greg Clayton462d4142010-09-29 01:12:09 +00001303 fun_opaque_type = fun_type->GetClangType();
Sean Callanan0fc73582010-07-27 00:55:47 +00001304
1305 if (!fun_opaque_type)
1306 {
1307 if (log)
1308 log->PutCString("Skipped a function because it has no Clang type");
1309 return;
1310 }
1311
1312 fun_address = &fun->GetAddressRange().GetBaseAddress();
1313
1314 TypeList *type_list = fun_type->GetTypeList();
1315 fun_ast_context = type_list->GetClangASTContext().getASTContext();
1316 void *copied_type = ClangASTContext::CopyType(context.GetASTContext(), fun_ast_context, fun_opaque_type);
1317
1318 fun_decl = context.AddFunDecl(copied_type);
Sean Callanan55261a12010-09-08 22:38:54 +00001319#else
1320 fun_address = &fun->GetAddressRange().GetBaseAddress();
1321
1322 fun_decl = context.AddGenericFunDecl();
1323#endif
Sean Callanan0fc73582010-07-27 00:55:47 +00001324 }
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 {
1354 log->Printf("Found %s function %s, returned (NamedDecl)%p", (fun ? "specific" : "generic"), decl_name.c_str(), fun_decl);
1355 }
Chris Lattner24943d22010-06-08 16:52:24 +00001356}
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001357
1358void
1359ClangExpressionDeclMap::AddOneType(NameSearchContext &context,
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001360 TypeFromUser &ut,
1361 bool add_method)
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001362{
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001363 clang::ASTContext *parser_ast_context = context.GetASTContext();
1364 clang::ASTContext *user_ast_context = ut.GetASTContext();
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001365
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001366 void *copied_type = ClangASTContext::CopyType(parser_ast_context, user_ast_context, ut.GetOpaqueQualType());
1367
1368 TypeFromParser parser_type(copied_type, parser_ast_context);
1369
1370 if (add_method && ClangASTContext::IsAggregateType(copied_type))
1371 {
1372 void *args[1];
1373
1374 args[0] = ClangASTContext::GetVoidPtrType(parser_ast_context, false);
1375
1376 void *method_type = ClangASTContext::CreateFunctionType (parser_ast_context,
1377 ClangASTContext::GetBuiltInType_void(parser_ast_context),
1378 args,
1379 1,
1380 false,
1381 ClangASTContext::GetTypeQualifiers(copied_type));
Greg Clayton30449d52010-10-01 02:31:07 +00001382
Greg Clayton1d8173f2010-09-24 05:15:53 +00001383 const bool is_virtual = false;
1384 const bool is_static = false;
1385 const bool is_inline = false;
Greg Clayton30449d52010-10-01 02:31:07 +00001386 const bool is_explicit = false;
1387
Greg Clayton1d8173f2010-09-24 05:15:53 +00001388 ClangASTContext::AddMethodToCXXRecordType (parser_ast_context,
1389 copied_type,
Greg Clayton8de27c72010-10-15 22:48:33 +00001390 "$__lldb_expr",
Greg Clayton1d8173f2010-09-24 05:15:53 +00001391 method_type,
1392 lldb::eAccessPublic,
1393 is_virtual,
1394 is_static,
Greg Clayton30449d52010-10-01 02:31:07 +00001395 is_inline,
1396 is_explicit);
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001397 }
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001398
1399 context.AddTypeDecl(copied_type);
1400}