blob: 92b1ebb0cd0b8651e9beaf2c3d65361d32816e94 [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"
Greg Clayton6916e352010-11-13 03:52:47 +000026#include "lldb/Symbol/ClangNamespaceDecl.h"
Chris Lattner24943d22010-06-08 16:52:24 +000027#include "lldb/Symbol/CompileUnit.h"
28#include "lldb/Symbol/Function.h"
29#include "lldb/Symbol/ObjectFile.h"
30#include "lldb/Symbol/SymbolContext.h"
31#include "lldb/Symbol/Type.h"
32#include "lldb/Symbol/TypeList.h"
33#include "lldb/Symbol/Variable.h"
34#include "lldb/Symbol/VariableList.h"
Sean Callananf328c9f2010-07-20 23:31:16 +000035#include "lldb/Target/ExecutionContext.h"
Sean Callanan810f22d2010-07-16 00:09:46 +000036#include "lldb/Target/Process.h"
Sean Callanan17c6a052010-10-05 20:18:48 +000037#include "lldb/Target/RegisterContext.h"
Chris Lattner24943d22010-06-08 16:52:24 +000038#include "lldb/Target/StackFrame.h"
Sean Callananf328c9f2010-07-20 23:31:16 +000039#include "lldb/Target/Target.h"
Sean Callanana0744822010-11-01 23:22:47 +000040#include "llvm/Support/raw_ostream.h"
Chris Lattner24943d22010-06-08 16:52:24 +000041
Chris Lattner24943d22010-06-08 16:52:24 +000042using namespace lldb_private;
43using namespace clang;
44
Greg Clayton8de27c72010-10-15 22:48:33 +000045ClangExpressionDeclMap::ClangExpressionDeclMap (ExecutionContext *exe_ctx) :
46 m_found_entities (),
47 m_struct_members (),
48 m_exe_ctx (),
49 m_sym_ctx (),
50 m_persistent_vars (NULL),
51 m_struct_alignment (0),
52 m_struct_size (0),
53 m_struct_laid_out (false),
54 m_enable_lookups (false),
55 m_allocated_area (0),
56 m_materialized_location (0),
57 m_result_name (),
58 m_object_pointer_type (),
59 m_lookedup_types ()
Chris Lattner24943d22010-06-08 16:52:24 +000060{
Greg Clayton8de27c72010-10-15 22:48:33 +000061 if (exe_ctx)
62 {
63 m_exe_ctx = *exe_ctx;
64 if (exe_ctx->frame)
65 m_sym_ctx = exe_ctx->frame->GetSymbolContext(lldb::eSymbolContextEverything);
66 if (exe_ctx->process)
67 m_persistent_vars = &exe_ctx->process->GetPersistentVariables();
68 }
Chris Lattner24943d22010-06-08 16:52:24 +000069}
70
71ClangExpressionDeclMap::~ClangExpressionDeclMap()
Sean Callanan8c127202010-08-23 23:09:38 +000072{
73 for (uint64_t entity_index = 0, num_entities = m_found_entities.Size();
74 entity_index < num_entities;
75 ++entity_index)
76 {
77 ClangExpressionVariable &entity(m_found_entities.VariableAtIndex(entity_index));
78 if (entity.m_parser_vars.get() &&
79 entity.m_parser_vars->m_lldb_value)
80 delete entity.m_parser_vars->m_lldb_value;
Sean Callanan45690fe2010-08-30 22:17:16 +000081
82 entity.DisableParserVars();
83 }
84
85 for (uint64_t pvar_index = 0, num_pvars = m_persistent_vars->Size();
86 pvar_index < num_pvars;
87 ++pvar_index)
88 {
89 ClangExpressionVariable &pvar(m_persistent_vars->VariableAtIndex(pvar_index));
90 pvar.DisableParserVars();
Sean Callanan8c127202010-08-23 23:09:38 +000091 }
Chris Lattner24943d22010-06-08 16:52:24 +000092
Sean Callanan7a60b942010-10-08 01:58:41 +000093 if (m_materialized_location)
Sean Callananc2c6f772010-10-26 00:31:56 +000094 {
95//#define SINGLE_STEP_EXPRESSIONS
96
97#ifndef SINGLE_STEP_EXPRESSIONS
Greg Clayton8de27c72010-10-15 22:48:33 +000098 m_exe_ctx.process->DeallocateMemory(m_materialized_location);
Sean Callananc2c6f772010-10-26 00:31:56 +000099#endif
Sean Callanan7a60b942010-10-08 01:58:41 +0000100 m_materialized_location = 0;
101 }
Chris Lattner24943d22010-06-08 16:52:24 +0000102}
103
Sean Callanan8bce6652010-07-13 21:41:46 +0000104// Interface for IRForTarget
105
Greg Clayton8de27c72010-10-15 22:48:33 +0000106const ConstString &
107ClangExpressionDeclMap::GetPersistentResultName ()
Sean Callanan82b74c82010-08-12 01:56:52 +0000108{
Greg Clayton8de27c72010-10-15 22:48:33 +0000109 if (!m_result_name)
110 m_persistent_vars->GetNextResultName(m_result_name);
111 return m_result_name;
Sean Callanan82b74c82010-08-12 01:56:52 +0000112}
113
Sean Callanan8bce6652010-07-13 21:41:46 +0000114bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000115ClangExpressionDeclMap::AddPersistentVariable
116(
117 const clang::NamedDecl *decl,
118 const ConstString &name,
119 TypeFromParser parser_type
120)
Sean Callanana48fe162010-08-11 03:57:18 +0000121{
Greg Clayton8de27c72010-10-15 22:48:33 +0000122 clang::ASTContext *context(m_exe_ctx.target->GetScratchClangASTContext()->getASTContext());
Sean Callanana48fe162010-08-11 03:57:18 +0000123
Sean Callanana48fe162010-08-11 03:57:18 +0000124 TypeFromUser user_type(ClangASTContext::CopyType(context,
Sean Callanan82b74c82010-08-12 01:56:52 +0000125 parser_type.GetASTContext(),
126 parser_type.GetOpaqueQualType()),
Sean Callanana48fe162010-08-11 03:57:18 +0000127 context);
128
Sean Callanan8c127202010-08-23 23:09:38 +0000129 if (!m_persistent_vars->CreatePersistentVariable (name, user_type))
130 return false;
131
132 ClangExpressionVariable *var = m_persistent_vars->GetVariable(name);
133
134 if (!var)
135 return false;
136
137 var->EnableParserVars();
138
139 var->m_parser_vars->m_named_decl = decl;
140 var->m_parser_vars->m_parser_type = parser_type;
141
142 return true;
Sean Callanana48fe162010-08-11 03:57:18 +0000143}
144
145bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000146ClangExpressionDeclMap::AddValueToStruct
147(
148 const clang::NamedDecl *decl,
149 const ConstString &name,
150 llvm::Value *value,
151 size_t size,
152 off_t alignment
153)
Sean Callanan8bce6652010-07-13 21:41:46 +0000154{
Greg Claytone005f2c2010-11-06 01:53:30 +0000155 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan45690fe2010-08-30 22:17:16 +0000156
Sean Callanan8bce6652010-07-13 21:41:46 +0000157 m_struct_laid_out = false;
158
Sean Callanan8c127202010-08-23 23:09:38 +0000159 if (m_struct_members.GetVariable(decl))
160 return true;
Sean Callanan8bce6652010-07-13 21:41:46 +0000161
Sean Callanan8c127202010-08-23 23:09:38 +0000162 ClangExpressionVariable *var = m_found_entities.GetVariable(decl);
Sean Callanan8bce6652010-07-13 21:41:46 +0000163
Sean Callanan8c127202010-08-23 23:09:38 +0000164 if (!var)
165 var = m_persistent_vars->GetVariable(decl);
Sean Callanan8bce6652010-07-13 21:41:46 +0000166
Sean Callanan8c127202010-08-23 23:09:38 +0000167 if (!var)
168 return false;
169
Sean Callanan45690fe2010-08-30 22:17:16 +0000170 if (log)
171 log->Printf("Adding value for decl %p [%s - %s] to the structure",
172 decl,
Greg Clayton8de27c72010-10-15 22:48:33 +0000173 name.GetCString(),
174 var->m_name.GetCString());
Sean Callanan45690fe2010-08-30 22:17:16 +0000175
Sean Callanan8c127202010-08-23 23:09:38 +0000176 // We know entity->m_parser_vars is valid because we used a parser variable
177 // to find it
178 var->m_parser_vars->m_llvm_value = value;
179
180 var->EnableJITVars();
181 var->m_jit_vars->m_alignment = alignment;
182 var->m_jit_vars->m_size = size;
183
184 m_struct_members.AddVariable(*var);
Sean Callanan8bce6652010-07-13 21:41:46 +0000185
186 return true;
187}
188
189bool
190ClangExpressionDeclMap::DoStructLayout ()
191{
192 if (m_struct_laid_out)
193 return true;
194
Sean Callanan8bce6652010-07-13 21:41:46 +0000195 off_t cursor = 0;
196
197 m_struct_alignment = 0;
198 m_struct_size = 0;
199
Sean Callanan8c127202010-08-23 23:09:38 +0000200 for (uint64_t member_index = 0, num_members = m_struct_members.Size();
201 member_index < num_members;
202 ++member_index)
Sean Callanan8bce6652010-07-13 21:41:46 +0000203 {
Sean Callanan8c127202010-08-23 23:09:38 +0000204 ClangExpressionVariable &member(m_struct_members.VariableAtIndex(member_index));
Sean Callanan8bce6652010-07-13 21:41:46 +0000205
Sean Callanan8c127202010-08-23 23:09:38 +0000206 if (!member.m_jit_vars.get())
207 return false;
Sean Callanan8bce6652010-07-13 21:41:46 +0000208
Sean Callanan8c127202010-08-23 23:09:38 +0000209 if (member_index == 0)
210 m_struct_alignment = member.m_jit_vars->m_alignment;
211
212 if (cursor % member.m_jit_vars->m_alignment)
213 cursor += (member.m_jit_vars->m_alignment - (cursor % member.m_jit_vars->m_alignment));
214
215 member.m_jit_vars->m_offset = cursor;
216 cursor += member.m_jit_vars->m_size;
Sean Callanan8bce6652010-07-13 21:41:46 +0000217 }
218
219 m_struct_size = cursor;
220
221 m_struct_laid_out = true;
222 return true;
223}
224
Greg Clayton8de27c72010-10-15 22:48:33 +0000225bool ClangExpressionDeclMap::GetStructInfo
226(
227 uint32_t &num_elements,
228 size_t &size,
229 off_t &alignment
230)
Sean Callanan8bce6652010-07-13 21:41:46 +0000231{
232 if (!m_struct_laid_out)
233 return false;
234
Sean Callanan8c127202010-08-23 23:09:38 +0000235 num_elements = m_struct_members.Size();
Sean Callanan8bce6652010-07-13 21:41:46 +0000236 size = m_struct_size;
237 alignment = m_struct_alignment;
238
239 return true;
240}
241
242bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000243ClangExpressionDeclMap::GetStructElement
244(
245 const clang::NamedDecl *&decl,
246 llvm::Value *&value,
247 off_t &offset,
248 ConstString &name,
249 uint32_t index
250)
Sean Callanan8bce6652010-07-13 21:41:46 +0000251{
252 if (!m_struct_laid_out)
253 return false;
254
Sean Callanan8c127202010-08-23 23:09:38 +0000255 if (index >= m_struct_members.Size())
Sean Callanan8bce6652010-07-13 21:41:46 +0000256 return false;
257
Sean Callanan8c127202010-08-23 23:09:38 +0000258 ClangExpressionVariable &member(m_struct_members.VariableAtIndex(index));
Sean Callanan8bce6652010-07-13 21:41:46 +0000259
Sean Callanan8c127202010-08-23 23:09:38 +0000260 if (!member.m_parser_vars.get() ||
261 !member.m_jit_vars.get())
262 return false;
263
264 decl = member.m_parser_vars->m_named_decl;
265 value = member.m_parser_vars->m_llvm_value;
266 offset = member.m_jit_vars->m_offset;
Greg Clayton8de27c72010-10-15 22:48:33 +0000267 name = member.m_name;
Sean Callanan8c127202010-08-23 23:09:38 +0000268
Sean Callanan8bce6652010-07-13 21:41:46 +0000269 return true;
270}
271
Sean Callanan02fbafa2010-07-27 21:39:39 +0000272bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000273ClangExpressionDeclMap::GetFunctionInfo
274(
275 const clang::NamedDecl *decl,
276 llvm::Value**& value,
277 uint64_t &ptr
278)
Sean Callananba992c52010-07-27 02:07:53 +0000279{
Sean Callanan8c127202010-08-23 23:09:38 +0000280 ClangExpressionVariable *entity = m_found_entities.GetVariable(decl);
281
282 if (!entity)
283 return false;
Sean Callananba992c52010-07-27 02:07:53 +0000284
Sean Callanan8c127202010-08-23 23:09:38 +0000285 // We know m_parser_vars is valid since we searched for the variable by
286 // its NamedDecl
Sean Callananba992c52010-07-27 02:07:53 +0000287
Sean Callanan8c127202010-08-23 23:09:38 +0000288 value = &entity->m_parser_vars->m_llvm_value;
289 ptr = entity->m_parser_vars->m_lldb_value->GetScalar().ULongLong();
290
291 return true;
Sean Callananba992c52010-07-27 02:07:53 +0000292}
293
Sean Callananf5857a02010-07-31 01:32:05 +0000294bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000295ClangExpressionDeclMap::GetFunctionAddress
296(
297 const ConstString &name,
298 uint64_t &ptr
299)
Sean Callananf5857a02010-07-31 01:32:05 +0000300{
301 // Back out in all cases where we're not fully initialized
Greg Clayton8de27c72010-10-15 22:48:33 +0000302 if (m_exe_ctx.frame == NULL)
Sean Callananf5857a02010-07-31 01:32:05 +0000303 return false;
304
Greg Claytone5748d82010-11-09 23:46:37 +0000305 SymbolContextList sc_list;
Sean Callananf5857a02010-07-31 01:32:05 +0000306
Greg Claytone5748d82010-11-09 23:46:37 +0000307 m_sym_ctx.FindFunctionsByName(name, false, sc_list);
Sean Callananf5857a02010-07-31 01:32:05 +0000308
Greg Claytone5748d82010-11-09 23:46:37 +0000309 if (!sc_list.GetSize())
Sean Callananf5857a02010-07-31 01:32:05 +0000310 return false;
311
312 SymbolContext sym_ctx;
Greg Claytone5748d82010-11-09 23:46:37 +0000313 sc_list.GetContextAtIndex(0, sym_ctx);
Sean Callananf5857a02010-07-31 01:32:05 +0000314
315 const Address *fun_address;
316
317 if (sym_ctx.function)
318 fun_address = &sym_ctx.function->GetAddressRange().GetBaseAddress();
319 else if (sym_ctx.symbol)
320 fun_address = &sym_ctx.symbol->GetAddressRangeRef().GetBaseAddress();
321 else
322 return false;
323
Greg Clayton8de27c72010-10-15 22:48:33 +0000324 ptr = fun_address->GetLoadAddress (m_exe_ctx.target);
Sean Callananf5857a02010-07-31 01:32:05 +0000325
326 return true;
327}
328
Sean Callanan810f22d2010-07-16 00:09:46 +0000329// Interface for CommandObjectExpression
Sean Callananf328c9f2010-07-20 23:31:16 +0000330
331bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000332ClangExpressionDeclMap::Materialize
333(
334 ExecutionContext *exe_ctx,
335 lldb::addr_t &struct_address,
336 Error &err
337)
Sean Callananf328c9f2010-07-20 23:31:16 +0000338{
339 bool result = DoMaterialize(false, exe_ctx, NULL, err);
340
341 if (result)
342 struct_address = m_materialized_location;
343
344 return result;
345}
346
347bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000348ClangExpressionDeclMap::GetObjectPointer
349(
350 lldb::addr_t &object_ptr,
351 ExecutionContext *exe_ctx,
352 Error &err
353)
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000354{
355 if (!exe_ctx || !exe_ctx->frame || !exe_ctx->target || !exe_ctx->process)
356 {
357 err.SetErrorString("Couldn't load 'this' because the context is incomplete");
358 return false;
359 }
360
361 if (!m_object_pointer_type.GetOpaqueQualType())
362 {
363 err.SetErrorString("Couldn't load 'this' because its type is unknown");
364 return false;
365 }
366
Greg Clayton8de27c72010-10-15 22:48:33 +0000367 static ConstString g_this_cs ("this");
368 Variable *object_ptr_var = FindVariableInScope(*exe_ctx->frame, g_this_cs, &m_object_pointer_type);
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000369
370 if (!object_ptr_var)
371 {
372 err.SetErrorString("Couldn't find 'this' with appropriate type in scope");
373 return false;
374 }
375
376 std::auto_ptr<lldb_private::Value> location_value(GetVariableValue(*exe_ctx,
377 object_ptr_var,
378 m_object_pointer_type.GetASTContext()));
379
380 if (!location_value.get())
381 {
382 err.SetErrorString("Couldn't get the location for 'this'");
383 return false;
384 }
385
386 if (location_value->GetValueType() == Value::eValueTypeLoadAddress)
387 {
388 lldb::addr_t value_addr = location_value->GetScalar().ULongLong();
389 uint32_t address_byte_size = exe_ctx->target->GetArchitecture().GetAddressByteSize();
390 lldb::ByteOrder address_byte_order = exe_ctx->process->GetByteOrder();
391
392 if (ClangASTType::GetClangTypeBitWidth(m_object_pointer_type.GetASTContext(), m_object_pointer_type.GetOpaqueQualType()) != address_byte_size * 8)
393 {
394 err.SetErrorStringWithFormat("'this' is not of an expected pointer size");
395 return false;
396 }
397
398 DataBufferHeap data;
399 data.SetByteSize(address_byte_size);
400 Error read_error;
401
402 if (exe_ctx->process->ReadMemory (value_addr, data.GetBytes(), address_byte_size, read_error) != address_byte_size)
403 {
404 err.SetErrorStringWithFormat("Coldn't read 'this' from the target: %s", read_error.AsCString());
405 return false;
406 }
407
408 DataExtractor extractor(data.GetBytes(), data.GetByteSize(), address_byte_order, address_byte_size);
409
410 uint32_t offset = 0;
411
412 object_ptr = extractor.GetPointer(&offset);
413
414 return true;
415 }
416 else
417 {
418 err.SetErrorString("'this' is not in memory; LLDB must be extended to handle registers");
419 return false;
420 }
421}
422
423bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000424ClangExpressionDeclMap::Dematerialize
425(
426 ExecutionContext *exe_ctx,
427 ClangExpressionVariable *&result,
428 Error &err
429)
Sean Callananf328c9f2010-07-20 23:31:16 +0000430{
Sean Callanan82b74c82010-08-12 01:56:52 +0000431 return DoMaterialize(true, exe_ctx, &result, err);
Sean Callananf328c9f2010-07-20 23:31:16 +0000432}
433
Sean Callanan32824aa2010-07-23 22:19:18 +0000434bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000435ClangExpressionDeclMap::DumpMaterializedStruct
436(
437 ExecutionContext *exe_ctx,
438 Stream &s,
439 Error &err
440)
Sean Callanan32824aa2010-07-23 22:19:18 +0000441{
442 if (!m_struct_laid_out)
443 {
444 err.SetErrorString("Structure hasn't been laid out yet");
445 return false;
446 }
447
448 if (!exe_ctx)
449 {
450 err.SetErrorString("Received null execution context");
451 return false;
452 }
453
454
455 if (!exe_ctx->process)
456 {
457 err.SetErrorString("Couldn't find the process");
458 return false;
459 }
460
461 if (!exe_ctx->target)
462 {
463 err.SetErrorString("Couldn't find the target");
464 return false;
465 }
466
467 lldb::DataBufferSP data(new DataBufferHeap(m_struct_size, 0));
468
469 Error error;
470 if (exe_ctx->process->ReadMemory (m_materialized_location, data->GetBytes(), data->GetByteSize(), error) != data->GetByteSize())
471 {
472 err.SetErrorStringWithFormat ("Couldn't read struct from the target: %s", error.AsCString());
473 return false;
474 }
475
476 DataExtractor extractor(data, exe_ctx->process->GetByteOrder(), exe_ctx->target->GetArchitecture().GetAddressByteSize());
477
Sean Callanan8c127202010-08-23 23:09:38 +0000478 for (uint64_t member_index = 0, num_members = m_struct_members.Size();
479 member_index < num_members;
480 ++member_index)
Sean Callanan32824aa2010-07-23 22:19:18 +0000481 {
Sean Callanan8c127202010-08-23 23:09:38 +0000482 ClangExpressionVariable &member (m_struct_members.VariableAtIndex(member_index));
Sean Callanan32824aa2010-07-23 22:19:18 +0000483
Greg Clayton8de27c72010-10-15 22:48:33 +0000484 s.Printf("[%s]\n", member.m_name.GetCString());
Sean Callanan8c127202010-08-23 23:09:38 +0000485
486 if (!member.m_jit_vars.get())
487 return false;
488
489 extractor.Dump(&s, // stream
490 member.m_jit_vars->m_offset, // offset
491 lldb::eFormatBytesWithASCII, // format
492 1, // byte size of individual entries
493 member.m_jit_vars->m_size, // number of entries
494 16, // entries per line
495 m_materialized_location + member.m_jit_vars->m_offset, // address to print
496 0, // bit size (bitfields only; 0 means ignore)
497 0); // bit alignment (bitfields only; 0 means ignore)
Sean Callanan32824aa2010-07-23 22:19:18 +0000498
499 s.PutChar('\n');
500 }
501
502 return true;
503}
504
Sean Callananf328c9f2010-07-20 23:31:16 +0000505bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000506ClangExpressionDeclMap::DoMaterialize
507(
508 bool dematerialize,
509 ExecutionContext *exe_ctx,
510 ClangExpressionVariable **result,
511 Error &err
512)
Sean Callanan810f22d2010-07-16 00:09:46 +0000513{
Greg Claytone005f2c2010-11-06 01:53:30 +0000514 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan82b74c82010-08-12 01:56:52 +0000515
Sean Callanan810f22d2010-07-16 00:09:46 +0000516 if (!m_struct_laid_out)
517 {
518 err.SetErrorString("Structure hasn't been laid out yet");
519 return LLDB_INVALID_ADDRESS;
520 }
521
Sean Callanan810f22d2010-07-16 00:09:46 +0000522 if (!exe_ctx)
523 {
524 err.SetErrorString("Received null execution context");
525 return LLDB_INVALID_ADDRESS;
526 }
527
Sean Callanan45839272010-07-24 01:37:44 +0000528 if (!exe_ctx->frame)
529 {
530 err.SetErrorString("Received null execution frame");
531 return LLDB_INVALID_ADDRESS;
532 }
533
Sean Callanane8a59a82010-09-13 21:34:21 +0000534 if (!m_struct_size)
535 {
536 if (log)
537 log->PutCString("Not bothering to allocate a struct because no arguments are needed");
538
539 m_allocated_area = NULL;
540
541 return true;
542 }
543
Sean Callanan810f22d2010-07-16 00:09:46 +0000544 const SymbolContext &sym_ctx(exe_ctx->frame->GetSymbolContext(lldb::eSymbolContextEverything));
545
Sean Callananf328c9f2010-07-20 23:31:16 +0000546 if (!dematerialize)
Sean Callanan810f22d2010-07-16 00:09:46 +0000547 {
Sean Callananf328c9f2010-07-20 23:31:16 +0000548 if (m_materialized_location)
549 {
550 exe_ctx->process->DeallocateMemory(m_materialized_location);
551 m_materialized_location = 0;
552 }
553
Sean Callanan7a60b942010-10-08 01:58:41 +0000554 if (log)
555 log->PutCString("Allocating memory for materialized argument struct");
556
Sean Callananf328c9f2010-07-20 23:31:16 +0000557 lldb::addr_t mem = exe_ctx->process->AllocateMemory(m_struct_alignment + m_struct_size,
558 lldb::ePermissionsReadable | lldb::ePermissionsWritable,
559 err);
560
561 if (mem == LLDB_INVALID_ADDRESS)
562 return false;
563
564 m_allocated_area = mem;
Sean Callanan810f22d2010-07-16 00:09:46 +0000565 }
566
Sean Callananf328c9f2010-07-20 23:31:16 +0000567 m_materialized_location = m_allocated_area;
568
569 if (m_materialized_location % m_struct_alignment)
Sean Callananf328c9f2010-07-20 23:31:16 +0000570 m_materialized_location += (m_struct_alignment - (m_materialized_location % m_struct_alignment));
Sean Callananf328c9f2010-07-20 23:31:16 +0000571
Sean Callanan8c127202010-08-23 23:09:38 +0000572 for (uint64_t member_index = 0, num_members = m_struct_members.Size();
573 member_index < num_members;
574 ++member_index)
Sean Callanan810f22d2010-07-16 00:09:46 +0000575 {
Sean Callanan8c127202010-08-23 23:09:38 +0000576 ClangExpressionVariable &member (m_struct_members.VariableAtIndex(member_index));
Sean Callanan810f22d2010-07-16 00:09:46 +0000577
Sean Callanan8c127202010-08-23 23:09:38 +0000578 if (!member.m_parser_vars.get())
Sean Callanan336a0002010-07-17 00:43:37 +0000579 return false;
Sean Callanan8c127202010-08-23 23:09:38 +0000580
581 ClangExpressionVariable *entity = m_found_entities.GetVariable(member.m_parser_vars->m_named_decl);
Greg Clayton8de27c72010-10-15 22:48:33 +0000582 ClangExpressionVariable *persistent_variable = m_persistent_vars->GetVariable(member.m_name);
Sean Callanan8c127202010-08-23 23:09:38 +0000583
584 if (entity)
585 {
586 if (!member.m_jit_vars.get())
587 return false;
588
Greg Clayton8de27c72010-10-15 22:48:33 +0000589 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 +0000590 return false;
591 }
592 else if (persistent_variable)
593 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000594 if (member.m_name == m_result_name)
Sean Callanan45690fe2010-08-30 22:17:16 +0000595 {
596 if (!dematerialize)
597 continue;
Sean Callanan8c127202010-08-23 23:09:38 +0000598
Sean Callanan8c127202010-08-23 23:09:38 +0000599 if (log)
600 log->PutCString("Found result member in the struct");
Sean Callanan45690fe2010-08-30 22:17:16 +0000601
Sean Callanan8c127202010-08-23 23:09:38 +0000602 *result = &member;
603 }
604
Sean Callanan45690fe2010-08-30 22:17:16 +0000605 if (log)
Greg Clayton8de27c72010-10-15 22:48:33 +0000606 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 +0000607
Greg Clayton8de27c72010-10-15 22:48:33 +0000608 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 +0000609 return false;
610 }
611 else
612 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000613 err.SetErrorStringWithFormat("Unexpected variable %s", member.m_name.GetCString());
Sean Callanan8c127202010-08-23 23:09:38 +0000614 return false;
615 }
Sean Callanan810f22d2010-07-16 00:09:46 +0000616 }
617
Sean Callananf328c9f2010-07-20 23:31:16 +0000618 return true;
619}
620
Sean Callanana48fe162010-08-11 03:57:18 +0000621bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000622ClangExpressionDeclMap::DoMaterializeOnePersistentVariable
623(
624 bool dematerialize,
625 ExecutionContext &exe_ctx,
626 const ConstString &name,
627 lldb::addr_t addr,
628 Error &err
629)
Sean Callanan45690fe2010-08-30 22:17:16 +0000630{
Sean Callanana6223432010-08-20 01:02:30 +0000631 ClangExpressionVariable *pvar(m_persistent_vars->GetVariable(name));
Sean Callanana48fe162010-08-11 03:57:18 +0000632
633 if (!pvar)
634 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000635 err.SetErrorStringWithFormat("Undefined persistent variable %s", name.GetCString());
Sean Callanana48fe162010-08-11 03:57:18 +0000636 return LLDB_INVALID_ADDRESS;
637 }
638
639 size_t pvar_size = pvar->Size();
Sean Callanana6223432010-08-20 01:02:30 +0000640
Greg Clayton66ed2fb2010-10-05 00:00:42 +0000641 if (!pvar->m_data_sp.get())
Sean Callanana6223432010-08-20 01:02:30 +0000642 return false;
643
Greg Clayton66ed2fb2010-10-05 00:00:42 +0000644 uint8_t *pvar_data = pvar->m_data_sp->GetBytes();
Sean Callanana48fe162010-08-11 03:57:18 +0000645 Error error;
646
647 if (dematerialize)
648 {
649 if (exe_ctx.process->ReadMemory (addr, pvar_data, pvar_size, error) != pvar_size)
650 {
651 err.SetErrorStringWithFormat ("Couldn't read a composite type from the target: %s", error.AsCString());
652 return false;
653 }
654 }
655 else
656 {
657 if (exe_ctx.process->WriteMemory (addr, pvar_data, pvar_size, error) != pvar_size)
658 {
659 err.SetErrorStringWithFormat ("Couldn't write a composite type to the target: %s", error.AsCString());
660 return false;
661 }
662 }
663
664 return true;
665}
666
Sean Callananf328c9f2010-07-20 23:31:16 +0000667bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000668ClangExpressionDeclMap::DoMaterializeOneVariable
669(
670 bool dematerialize,
671 ExecutionContext &exe_ctx,
672 const SymbolContext &sym_ctx,
673 const ConstString &name,
674 TypeFromUser type,
675 lldb::addr_t addr,
676 Error &err
677)
Sean Callananf328c9f2010-07-20 23:31:16 +0000678{
Greg Claytone005f2c2010-11-06 01:53:30 +0000679 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callananf328c9f2010-07-20 23:31:16 +0000680
Sean Callanan17c6a052010-10-05 20:18:48 +0000681 if (!exe_ctx.frame || !exe_ctx.process)
Sean Callanancc074622010-09-14 21:59:34 +0000682 return false;
683
684 Variable *var = FindVariableInScope(*exe_ctx.frame, name, &type);
Sean Callananf328c9f2010-07-20 23:31:16 +0000685
686 if (!var)
687 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000688 err.SetErrorStringWithFormat("Couldn't find %s with appropriate type", name.GetCString());
Sean Callananf328c9f2010-07-20 23:31:16 +0000689 return false;
690 }
691
Sean Callanan841026f2010-07-23 00:16:21 +0000692 if (log)
Greg Clayton8de27c72010-10-15 22:48:33 +0000693 log->Printf("%s %s with type %p", (dematerialize ? "Dematerializing" : "Materializing"), name.GetCString(), type.GetOpaqueQualType());
Sean Callananf328c9f2010-07-20 23:31:16 +0000694
695 std::auto_ptr<lldb_private::Value> location_value(GetVariableValue(exe_ctx,
696 var,
697 type.GetASTContext()));
698
699 if (!location_value.get())
700 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000701 err.SetErrorStringWithFormat("Couldn't get value for %s", name.GetCString());
Sean Callananf328c9f2010-07-20 23:31:16 +0000702 return false;
703 }
Sean Callanan17c6a052010-10-05 20:18:48 +0000704
705 // The size of the type contained in addr
Sean Callananf328c9f2010-07-20 23:31:16 +0000706
Sean Callanan17c6a052010-10-05 20:18:48 +0000707 size_t addr_bit_size = ClangASTType::GetClangTypeBitWidth(type.GetASTContext(), type.GetOpaqueQualType());
708 size_t addr_byte_size = addr_bit_size % 8 ? ((addr_bit_size + 8) / 8) : (addr_bit_size / 8);
709
710 Value::ValueType value_type = location_value->GetValueType();
711
712 switch (value_type)
Sean Callananf328c9f2010-07-20 23:31:16 +0000713 {
Sean Callanan17c6a052010-10-05 20:18:48 +0000714 default:
Sean Callananf328c9f2010-07-20 23:31:16 +0000715 {
Sean Callanan17c6a052010-10-05 20:18:48 +0000716 StreamString ss;
717
718 location_value->Dump(&ss);
719
Greg Clayton8de27c72010-10-15 22:48:33 +0000720 err.SetErrorStringWithFormat("%s has a value of unhandled type: %s", name.GetCString(), ss.GetString().c_str());
Sean Callananf328c9f2010-07-20 23:31:16 +0000721 return false;
722 }
Sean Callanan17c6a052010-10-05 20:18:48 +0000723 break;
724 case Value::eValueTypeLoadAddress:
Sean Callananf328c9f2010-07-20 23:31:16 +0000725 {
Sean Callanan17c6a052010-10-05 20:18:48 +0000726 lldb::addr_t value_addr = location_value->GetScalar().ULongLong();
727
728 DataBufferHeap data;
729 data.SetByteSize(addr_byte_size);
730
731 lldb::addr_t src_addr;
732 lldb::addr_t dest_addr;
733
734 if (dematerialize)
735 {
736 src_addr = addr;
737 dest_addr = value_addr;
738 }
739 else
740 {
741 src_addr = value_addr;
742 dest_addr = addr;
743 }
744
745 Error error;
746 if (exe_ctx.process->ReadMemory (src_addr, data.GetBytes(), addr_byte_size, error) != addr_byte_size)
747 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000748 err.SetErrorStringWithFormat ("Couldn't read %s from the target: %s", name.GetCString(), error.AsCString());
Sean Callanan17c6a052010-10-05 20:18:48 +0000749 return false;
750 }
751
752 if (exe_ctx.process->WriteMemory (dest_addr, data.GetBytes(), addr_byte_size, error) != addr_byte_size)
753 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000754 err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", name.GetCString(), error.AsCString());
Sean Callanan17c6a052010-10-05 20:18:48 +0000755 return false;
756 }
757
758 if (log)
759 log->Printf("Copied from 0x%llx to 0x%llx", (uint64_t)src_addr, (uint64_t)addr);
Sean Callananf328c9f2010-07-20 23:31:16 +0000760 }
Sean Callanan17c6a052010-10-05 20:18:48 +0000761 break;
762 case Value::eValueTypeScalar:
763 {
Greg Clayton6916e352010-11-13 03:52:47 +0000764 if (location_value->GetContextType() != Value::eContextTypeRegisterInfo)
Sean Callanan17c6a052010-10-05 20:18:48 +0000765 {
766 StreamString ss;
767
768 location_value->Dump(&ss);
769
Greg Clayton8de27c72010-10-15 22:48:33 +0000770 err.SetErrorStringWithFormat("%s is a scalar of unhandled type: %s", name.GetCString(), ss.GetString().c_str());
Sean Callanan17c6a052010-10-05 20:18:48 +0000771 return false;
772 }
773
774 lldb::RegisterInfo *register_info = location_value->GetRegisterInfo();
775
776 if (!register_info)
777 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000778 err.SetErrorStringWithFormat("Couldn't get the register information for %s", name.GetCString());
Sean Callanan17c6a052010-10-05 20:18:48 +0000779 return false;
780 }
781
782 RegisterContext *register_context = exe_ctx.GetRegisterContext();
783
784 if (!register_context)
785 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000786 err.SetErrorStringWithFormat("Couldn't read register context to read %s from %s", name.GetCString(), register_info->name);
Sean Callanan17c6a052010-10-05 20:18:48 +0000787 return false;
788 }
789
790 uint32_t register_number = register_info->kinds[lldb::eRegisterKindLLDB];
791 uint32_t register_byte_size = register_info->byte_size;
792
793 if (dematerialize)
794 {
795 // Moving from addr into a register
796 //
797 // Case 1: addr_byte_size and register_byte_size are the same
798 //
799 // |AABBCCDD| Address contents
800 // |AABBCCDD| Register contents
801 //
802 // Case 2: addr_byte_size is bigger than register_byte_size
803 //
804 // Error! (The register should always be big enough to hold the data)
805 //
806 // Case 3: register_byte_size is bigger than addr_byte_size
807 //
808 // |AABB| Address contents
809 // |AABB0000| Register contents [on little-endian hardware]
810 // |0000AABB| Register contents [on big-endian hardware]
811
812 if (addr_byte_size > register_byte_size)
813 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000814 err.SetErrorStringWithFormat("%s is too big to store in %s", name.GetCString(), register_info->name);
Sean Callanan17c6a052010-10-05 20:18:48 +0000815 return false;
816 }
817
818 uint32_t register_offset;
819
820 switch (exe_ctx.process->GetByteOrder())
821 {
822 default:
Greg Clayton8de27c72010-10-15 22:48:33 +0000823 err.SetErrorStringWithFormat("%s is stored with an unhandled byte order", name.GetCString());
Sean Callanan17c6a052010-10-05 20:18:48 +0000824 return false;
825 case lldb::eByteOrderLittle:
826 register_offset = 0;
827 break;
828 case lldb::eByteOrderBig:
829 register_offset = register_byte_size - addr_byte_size;
830 break;
831 }
832
833 DataBufferHeap register_data (register_byte_size, 0);
834
835 Error error;
836 if (exe_ctx.process->ReadMemory (addr, register_data.GetBytes() + register_offset, addr_byte_size, error) != addr_byte_size)
837 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000838 err.SetErrorStringWithFormat ("Couldn't read %s from the target: %s", name.GetCString(), error.AsCString());
Sean Callanan17c6a052010-10-05 20:18:48 +0000839 return false;
840 }
841
842 DataExtractor register_extractor (register_data.GetBytes(), register_byte_size, exe_ctx.process->GetByteOrder(), exe_ctx.process->GetAddressByteSize());
843
844 if (!register_context->WriteRegisterBytes(register_number, register_extractor, 0))
845 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000846 err.SetErrorStringWithFormat("Couldn't read %s from %s", name.GetCString(), register_info->name);
Sean Callanan17c6a052010-10-05 20:18:48 +0000847 return false;
848 }
849 }
850 else
851 {
852 // Moving from a register into addr
853 //
854 // Case 1: addr_byte_size and register_byte_size are the same
855 //
856 // |AABBCCDD| Register contents
857 // |AABBCCDD| Address contents
858 //
859 // Case 2: addr_byte_size is bigger than register_byte_size
860 //
861 // Error! (The register should always be big enough to hold the data)
862 //
863 // Case 3: register_byte_size is bigger than addr_byte_size
864 //
865 // |AABBCCDD| Register contents
866 // |AABB| Address contents on little-endian hardware
867 // |CCDD| Address contents on big-endian hardware
868
869 if (addr_byte_size > register_byte_size)
870 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000871 err.SetErrorStringWithFormat("%s is too big to store in %s", name.GetCString(), register_info->name);
Sean Callanan17c6a052010-10-05 20:18:48 +0000872 return false;
873 }
874
875 uint32_t register_offset;
876
877 switch (exe_ctx.process->GetByteOrder())
878 {
879 default:
Greg Clayton8de27c72010-10-15 22:48:33 +0000880 err.SetErrorStringWithFormat("%s is stored with an unhandled byte order", name.GetCString());
Sean Callanan17c6a052010-10-05 20:18:48 +0000881 return false;
882 case lldb::eByteOrderLittle:
883 register_offset = 0;
884 break;
885 case lldb::eByteOrderBig:
886 register_offset = register_byte_size - addr_byte_size;
887 break;
888 }
889
890 DataExtractor register_extractor;
891
892 if (!register_context->ReadRegisterBytes(register_number, register_extractor))
893 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000894 err.SetErrorStringWithFormat("Couldn't read %s from %s", name.GetCString(), register_info->name);
Sean Callanan17c6a052010-10-05 20:18:48 +0000895 return false;
896 }
897
898 const void *register_data = register_extractor.GetData(&register_offset, addr_byte_size);
899
900 if (!register_data)
901 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000902 err.SetErrorStringWithFormat("Read but couldn't extract data for %s from %s", name.GetCString(), register_info->name);
Sean Callanan17c6a052010-10-05 20:18:48 +0000903 return false;
904 }
905
906 Error error;
907 if (exe_ctx.process->WriteMemory (addr, register_data, addr_byte_size, error) != addr_byte_size)
908 {
909 err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", error.AsCString());
910 return false;
911 }
912 }
913 }
Sean Callananf328c9f2010-07-20 23:31:16 +0000914 }
915
916 return true;
Sean Callanan810f22d2010-07-16 00:09:46 +0000917}
918
Sean Callanancc074622010-09-14 21:59:34 +0000919Variable *
Greg Clayton8de27c72010-10-15 22:48:33 +0000920ClangExpressionDeclMap::FindVariableInScope
921(
922 StackFrame &frame,
923 const ConstString &name,
924 TypeFromUser *type
925)
Sean Callanancc074622010-09-14 21:59:34 +0000926{
Greg Claytone005f2c2010-11-06 01:53:30 +0000927 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanancc074622010-09-14 21:59:34 +0000928
Sean Callanancc074622010-09-14 21:59:34 +0000929 VariableList *var_list = frame.GetVariableList(true);
930
Greg Claytonbf8e42b2010-10-14 22:52:14 +0000931 if (!var_list)
932 return NULL;
933
Greg Clayton8de27c72010-10-15 22:48:33 +0000934 lldb::VariableSP var = var_list->FindVariable(name);
Sean Callanancc074622010-09-14 21:59:34 +0000935
936 if (!var)
937 return NULL;
938
939 if (!type)
940 return var.get();
941
942 if (type->GetASTContext() == var->GetType()->GetClangAST())
943 {
Greg Clayton462d4142010-09-29 01:12:09 +0000944 if (!ClangASTContext::AreTypesSame(type->GetASTContext(), type->GetOpaqueQualType(), var->GetType()->GetClangType()))
Sean Callanancc074622010-09-14 21:59:34 +0000945 return NULL;
946 }
947 else
948 {
949 if (log)
950 log->PutCString("Skipping a candidate variable because of different AST contexts");
951 return NULL;
952 }
953
954 return var.get();
Sean Callanancc074622010-09-14 21:59:34 +0000955}
Sean Callanan336a0002010-07-17 00:43:37 +0000956
Chris Lattner24943d22010-06-08 16:52:24 +0000957// Interface for ClangASTSource
958void
Greg Claytone5748d82010-11-09 23:46:37 +0000959ClangExpressionDeclMap::GetDecls (NameSearchContext &context, const ConstString &name)
Chris Lattner24943d22010-06-08 16:52:24 +0000960{
Greg Claytone005f2c2010-11-06 01:53:30 +0000961 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000962
Sean Callanan810f22d2010-07-16 00:09:46 +0000963 if (log)
Greg Clayton8de27c72010-10-15 22:48:33 +0000964 log->Printf("Hunting for a definition for '%s'", name.GetCString());
Chris Lattner24943d22010-06-08 16:52:24 +0000965
966 // Back out in all cases where we're not fully initialized
Greg Clayton8de27c72010-10-15 22:48:33 +0000967 if (m_exe_ctx.frame == NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000968 return;
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000969
Greg Claytone5748d82010-11-09 23:46:37 +0000970 SymbolContextList sc_list;
Chris Lattner24943d22010-06-08 16:52:24 +0000971
Greg Clayton8de27c72010-10-15 22:48:33 +0000972 // Only look for functions by name out in our symbols if the function
973 // doesn't start with our phony prefix of '$'
974 if (name.GetCString()[0] != '$')
Sean Callanan0fc73582010-07-27 00:55:47 +0000975 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000976
977 Variable *var = FindVariableInScope(*m_exe_ctx.frame, name);
978
979 // If we found a variable in scope, no need to pull up function names
980 if (var != NULL)
981 {
982 AddOneVariable(context, var);
983 }
984 else
985 {
Greg Claytone5748d82010-11-09 23:46:37 +0000986 m_sym_ctx.FindFunctionsByName (name, false, sc_list);
Greg Clayton8de27c72010-10-15 22:48:33 +0000987
988 bool found_specific = false;
989 Symbol *generic_symbol = NULL;
990 Symbol *non_extern_symbol = NULL;
991
Greg Claytone5748d82010-11-09 23:46:37 +0000992 for (uint32_t index = 0, num_indices = sc_list.GetSize();
Greg Clayton8de27c72010-10-15 22:48:33 +0000993 index < num_indices;
994 ++index)
995 {
996 SymbolContext sym_ctx;
Greg Claytone5748d82010-11-09 23:46:37 +0000997 sc_list.GetContextAtIndex(index, sym_ctx);
Sean Callanan3cfbd332010-10-06 00:10:07 +0000998
Greg Clayton8de27c72010-10-15 22:48:33 +0000999 if (sym_ctx.function)
1000 {
1001 // TODO only do this if it's a C function; C++ functions may be
1002 // overloaded
1003 if (!found_specific)
1004 AddOneFunction(context, sym_ctx.function, NULL);
1005 found_specific = true;
1006 }
1007 else if (sym_ctx.symbol)
1008 {
1009 if (sym_ctx.symbol->IsExternal())
1010 generic_symbol = sym_ctx.symbol;
1011 else
1012 non_extern_symbol = sym_ctx.symbol;
1013 }
1014 }
1015
Sean Callanan92aa6662010-09-07 21:49:41 +00001016 if (!found_specific)
Greg Clayton8de27c72010-10-15 22:48:33 +00001017 {
1018 if (generic_symbol)
1019 AddOneFunction(context, NULL, generic_symbol);
1020 else if (non_extern_symbol)
1021 AddOneFunction(context, NULL, non_extern_symbol);
1022 }
Greg Clayton6916e352010-11-13 03:52:47 +00001023
1024 ClangNamespaceDecl namespace_decl (m_sym_ctx.FindNamespace(name));
1025 if (namespace_decl)
1026 {
1027// clang::NamespaceDecl *clang_namespace_decl = AddNamespace(context, namespace_decl);
1028// if (clang_namespace_decl)
1029// {
1030// // TODO: is this how we get the decl lookups to be called for
1031// // this namespace??
1032// clang_namespace_decl->setHasExternalLexicalStorage();
1033// }
1034 }
Sean Callanan92aa6662010-09-07 21:49:41 +00001035 }
Sean Callanan0fc73582010-07-27 00:55:47 +00001036 }
Greg Clayton8de27c72010-10-15 22:48:33 +00001037 else
Sean Callanan3cfbd332010-10-06 00:10:07 +00001038 {
Greg Clayton57452832010-11-09 04:42:43 +00001039 static ConstString g_lldb_class_name ("$__lldb_class");
1040 if (name == g_lldb_class_name)
1041 {
1042 // Clang is looking for the type of "this"
1043
1044 VariableList *vars = m_exe_ctx.frame->GetVariableList(false);
1045
1046 if (!vars)
1047 return;
1048
1049 lldb::VariableSP this_var = vars->FindVariable(ConstString("this"));
1050
1051 if (!this_var)
1052 return;
1053
1054 Type *this_type = this_var->GetType();
1055
1056 if (!this_type)
1057 return;
1058
1059 TypeFromUser this_user_type(this_type->GetClangType(),
1060 this_type->GetClangAST());
1061
1062 m_object_pointer_type = this_user_type;
1063
1064 void *pointer_target_type;
1065
1066 if (!ClangASTContext::IsPointerType(this_user_type.GetOpaqueQualType(),
1067 &pointer_target_type))
1068 return;
1069
1070 TypeFromUser class_user_type(pointer_target_type,
1071 this_type->GetClangAST());
1072
1073 AddOneType(context, class_user_type, true);
1074
1075 return;
1076 }
1077
Greg Clayton8de27c72010-10-15 22:48:33 +00001078 ClangExpressionVariable *pvar(m_persistent_vars->GetVariable(name));
1079
1080 if (pvar)
1081 AddOneVariable(context, pvar);
Sean Callanan3cfbd332010-10-06 00:10:07 +00001082 }
1083
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001084
Sean Callanan6df08402010-09-27 23:54:58 +00001085 // See information on gating of this operation next to the definition for
1086 // m_lookedup_types.
1087
Greg Clayton8de27c72010-10-15 22:48:33 +00001088 const char *name_uniq = name.GetCString();
Sean Callanan6df08402010-09-27 23:54:58 +00001089
1090 if (m_lookedup_types.find(name_uniq) == m_lookedup_types.end())
1091 {
1092 // 1 The name is added to m_lookedup_types.
1093 m_lookedup_types.insert(std::pair<const char*, bool>(name_uniq, true));
1094
1095 // 2 The type is looked up and added, potentially causing more type loookups.
Greg Clayton8de27c72010-10-15 22:48:33 +00001096 lldb::TypeSP type = m_sym_ctx.FindTypeByName (name);
Sean Callanan6df08402010-09-27 23:54:58 +00001097
1098 if (type.get())
1099 {
Greg Clayton462d4142010-09-29 01:12:09 +00001100 TypeFromUser user_type(type->GetClangType(),
Sean Callanan6df08402010-09-27 23:54:58 +00001101 type->GetClangAST());
1102
1103 AddOneType(context, user_type, false);
1104 }
1105
1106 // 3 The name is removed from m_lookedup_types.
1107 m_lookedup_types.erase(name_uniq);
1108 }
Sean Callanan336a0002010-07-17 00:43:37 +00001109}
1110
1111Value *
Greg Clayton8de27c72010-10-15 22:48:33 +00001112ClangExpressionDeclMap::GetVariableValue
1113(
1114 ExecutionContext &exe_ctx,
1115 Variable *var,
1116 clang::ASTContext *parser_ast_context,
1117 TypeFromUser *user_type,
1118 TypeFromParser *parser_type
1119)
Chris Lattner24943d22010-06-08 16:52:24 +00001120{
Greg Claytone005f2c2010-11-06 01:53:30 +00001121 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan6184dfe2010-06-23 00:47:48 +00001122
Chris Lattner24943d22010-06-08 16:52:24 +00001123 Type *var_type = var->GetType();
1124
1125 if (!var_type)
1126 {
Sean Callanan810f22d2010-07-16 00:09:46 +00001127 if (log)
1128 log->PutCString("Skipped a definition because it has no type");
Sean Callanan336a0002010-07-17 00:43:37 +00001129 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001130 }
1131
Greg Clayton462d4142010-09-29 01:12:09 +00001132 void *var_opaque_type = var_type->GetClangType();
Chris Lattner24943d22010-06-08 16:52:24 +00001133
1134 if (!var_opaque_type)
1135 {
Sean Callanan810f22d2010-07-16 00:09:46 +00001136 if (log)
1137 log->PutCString("Skipped a definition because it has no Clang type");
Sean Callanan336a0002010-07-17 00:43:37 +00001138 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001139 }
1140
Chris Lattner24943d22010-06-08 16:52:24 +00001141 TypeList *type_list = var_type->GetTypeList();
1142
1143 if (!type_list)
1144 {
Sean Callanan810f22d2010-07-16 00:09:46 +00001145 if (log)
1146 log->PutCString("Skipped a definition because the type has no associated type list");
Sean Callanan336a0002010-07-17 00:43:37 +00001147 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001148 }
1149
1150 clang::ASTContext *exe_ast_ctx = type_list->GetClangASTContext().getASTContext();
1151
1152 if (!exe_ast_ctx)
1153 {
Sean Callanan810f22d2010-07-16 00:09:46 +00001154 if (log)
1155 log->PutCString("There is no AST context for the current execution context");
Sean Callanan336a0002010-07-17 00:43:37 +00001156 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001157 }
1158
Sean Callanan336a0002010-07-17 00:43:37 +00001159 DWARFExpression &var_location_expr = var->LocationExpression();
1160
Chris Lattner24943d22010-06-08 16:52:24 +00001161 std::auto_ptr<Value> var_location(new Value);
1162
Greg Clayton178710c2010-09-14 02:20:48 +00001163 lldb::addr_t loclist_base_load_addr = LLDB_INVALID_ADDRESS;
1164
1165 if (var_location_expr.IsLocationList())
1166 {
1167 SymbolContext var_sc;
1168 var->CalculateSymbolContext (&var_sc);
Greg Claytoneea26402010-09-14 23:36:40 +00001169 loclist_base_load_addr = var_sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (exe_ctx.target);
Greg Clayton178710c2010-09-14 02:20:48 +00001170 }
Chris Lattner24943d22010-06-08 16:52:24 +00001171 Error err;
1172
Greg Clayton178710c2010-09-14 02:20:48 +00001173 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 +00001174 {
Sean Callanan810f22d2010-07-16 00:09:46 +00001175 if (log)
1176 log->Printf("Error evaluating location: %s", err.AsCString());
Sean Callanan336a0002010-07-17 00:43:37 +00001177 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001178 }
1179
Sean Callanan810f22d2010-07-16 00:09:46 +00001180 clang::ASTContext *var_ast_context = type_list->GetClangASTContext().getASTContext();
1181
Sean Callanan336a0002010-07-17 00:43:37 +00001182 void *type_to_use;
1183
Sean Callananf328c9f2010-07-20 23:31:16 +00001184 if (parser_ast_context)
1185 {
1186 type_to_use = ClangASTContext::CopyType(parser_ast_context, var_ast_context, var_opaque_type);
1187
1188 if (parser_type)
1189 *parser_type = TypeFromParser(type_to_use, parser_ast_context);
1190 }
Sean Callanan336a0002010-07-17 00:43:37 +00001191 else
1192 type_to_use = var_opaque_type;
Chris Lattner24943d22010-06-08 16:52:24 +00001193
1194 if (var_location.get()->GetContextType() == Value::eContextTypeInvalid)
Greg Clayton6916e352010-11-13 03:52:47 +00001195 var_location.get()->SetContext(Value::eContextTypeClangType, type_to_use);
Chris Lattner24943d22010-06-08 16:52:24 +00001196
1197 if (var_location.get()->GetValueType() == Value::eValueTypeFileAddress)
1198 {
1199 SymbolContext var_sc;
1200 var->CalculateSymbolContext(&var_sc);
Sean Callanan336a0002010-07-17 00:43:37 +00001201
Chris Lattner24943d22010-06-08 16:52:24 +00001202 if (!var_sc.module_sp)
Sean Callanan336a0002010-07-17 00:43:37 +00001203 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001204
1205 ObjectFile *object_file = var_sc.module_sp->GetObjectFile();
1206
1207 if (!object_file)
Sean Callanan336a0002010-07-17 00:43:37 +00001208 return NULL;
1209
Chris Lattner24943d22010-06-08 16:52:24 +00001210 Address so_addr(var_location->GetScalar().ULongLong(), object_file->GetSectionList());
1211
Greg Clayton8de27c72010-10-15 22:48:33 +00001212 lldb::addr_t load_addr = so_addr.GetLoadAddress(m_exe_ctx.target);
Chris Lattner24943d22010-06-08 16:52:24 +00001213
1214 var_location->GetScalar() = load_addr;
1215 var_location->SetValueType(Value::eValueTypeLoadAddress);
1216 }
1217
Sean Callananf328c9f2010-07-20 23:31:16 +00001218 if (user_type)
1219 *user_type = TypeFromUser(var_opaque_type, var_ast_context);
Sean Callanan336a0002010-07-17 00:43:37 +00001220
1221 return var_location.release();
1222}
1223
1224void
1225ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001226 Variable* var)
Sean Callanan336a0002010-07-17 00:43:37 +00001227{
Greg Claytone005f2c2010-11-06 01:53:30 +00001228 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan336a0002010-07-17 00:43:37 +00001229
Sean Callananf328c9f2010-07-20 23:31:16 +00001230 TypeFromUser ut;
1231 TypeFromParser pt;
Sean Callanan336a0002010-07-17 00:43:37 +00001232
Greg Clayton8de27c72010-10-15 22:48:33 +00001233 Value *var_location = GetVariableValue (m_exe_ctx,
1234 var,
1235 context.GetASTContext(),
1236 &ut,
1237 &pt);
Sean Callanan336a0002010-07-17 00:43:37 +00001238
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001239 NamedDecl *var_decl = context.AddVarDecl(pt.GetOpaqueQualType());
Chris Lattner24943d22010-06-08 16:52:24 +00001240
Sean Callanan8c127202010-08-23 23:09:38 +00001241 ClangExpressionVariable &entity(m_found_entities.VariableAtIndex(m_found_entities.CreateVariable()));
Greg Clayton8de27c72010-10-15 22:48:33 +00001242 std::string decl_name(context.m_decl_name.getAsString());
1243 entity.m_name.SetCString (decl_name.c_str());
1244 entity.m_user_type = ut;
Chris Lattner24943d22010-06-08 16:52:24 +00001245
Sean Callanan8c127202010-08-23 23:09:38 +00001246 entity.EnableParserVars();
1247 entity.m_parser_vars->m_parser_type = pt;
1248 entity.m_parser_vars->m_named_decl = var_decl;
1249 entity.m_parser_vars->m_llvm_value = NULL;
1250 entity.m_parser_vars->m_lldb_value = var_location;
Chris Lattner24943d22010-06-08 16:52:24 +00001251
Sean Callanan810f22d2010-07-16 00:09:46 +00001252 if (log)
Greg Clayton8de27c72010-10-15 22:48:33 +00001253 {
Sean Callanana0744822010-11-01 23:22:47 +00001254 std::string var_decl_print_string;
1255 llvm::raw_string_ostream var_decl_print_stream(var_decl_print_string);
1256 var_decl->print(var_decl_print_stream);
1257 var_decl_print_stream.flush();
1258
1259 log->Printf("Found variable %s, returned %s", decl_name.c_str(), var_decl_print_string.c_str());
Greg Clayton8de27c72010-10-15 22:48:33 +00001260 }
Sean Callanan8f0dc342010-06-22 23:46:24 +00001261}
1262
1263void
Sean Callanana48fe162010-08-11 03:57:18 +00001264ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
Sean Callanana6223432010-08-20 01:02:30 +00001265 ClangExpressionVariable *pvar)
Sean Callanana48fe162010-08-11 03:57:18 +00001266{
Greg Claytone005f2c2010-11-06 01:53:30 +00001267 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan45690fe2010-08-30 22:17:16 +00001268
Sean Callanana6223432010-08-20 01:02:30 +00001269 TypeFromUser user_type = pvar->m_user_type;
Sean Callanana48fe162010-08-11 03:57:18 +00001270
1271 TypeFromParser parser_type(ClangASTContext::CopyType(context.GetASTContext(),
1272 user_type.GetASTContext(),
1273 user_type.GetOpaqueQualType()),
1274 context.GetASTContext());
1275
Sean Callanan8c127202010-08-23 23:09:38 +00001276 NamedDecl *var_decl = context.AddVarDecl(parser_type.GetOpaqueQualType());
1277
1278 pvar->EnableParserVars();
1279 pvar->m_parser_vars->m_parser_type = parser_type;
1280 pvar->m_parser_vars->m_named_decl = var_decl;
1281 pvar->m_parser_vars->m_llvm_value = NULL;
1282 pvar->m_parser_vars->m_lldb_value = NULL;
Sean Callanan45690fe2010-08-30 22:17:16 +00001283
1284 if (log)
Sean Callanana0744822010-11-01 23:22:47 +00001285 {
1286 std::string var_decl_print_string;
1287 llvm::raw_string_ostream var_decl_print_stream(var_decl_print_string);
1288 var_decl->print(var_decl_print_stream);
1289 var_decl_print_stream.flush();
1290
1291 log->Printf("Added pvar %s, returned %s", pvar->m_name.GetCString(), var_decl_print_string.c_str());
1292 }
Sean Callanana48fe162010-08-11 03:57:18 +00001293}
1294
Greg Clayton6916e352010-11-13 03:52:47 +00001295clang::NamespaceDecl *
1296ClangExpressionDeclMap::AddNamespace (NameSearchContext &context, const ClangNamespaceDecl &namespace_decl)
1297{
1298 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
1299
1300
1301 clang::Decl *copied_decl = ClangASTContext::CopyDecl (context.GetASTContext(),
1302 namespace_decl.GetASTContext(),
1303 namespace_decl.GetNamespaceDecl());
1304
1305 return dyn_cast<clang::NamespaceDecl>(copied_decl);
1306}
1307
Sean Callanana48fe162010-08-11 03:57:18 +00001308void
Sean Callanan8f0dc342010-06-22 23:46:24 +00001309ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
Sean Callanan0fc73582010-07-27 00:55:47 +00001310 Function* fun,
1311 Symbol* symbol)
Sean Callanan8f0dc342010-06-22 23:46:24 +00001312{
Greg Claytone005f2c2010-11-06 01:53:30 +00001313 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan8f0dc342010-06-22 23:46:24 +00001314
Sean Callanan0fc73582010-07-27 00:55:47 +00001315 NamedDecl *fun_decl;
Sean Callanan8f0dc342010-06-22 23:46:24 +00001316 std::auto_ptr<Value> fun_location(new Value);
Sean Callanan0fc73582010-07-27 00:55:47 +00001317 const Address *fun_address;
Sean Callanan8f0dc342010-06-22 23:46:24 +00001318
Sean Callanan0fc73582010-07-27 00:55:47 +00001319 // only valid for Functions, not for Symbols
1320 void *fun_opaque_type = NULL;
1321 clang::ASTContext *fun_ast_context = NULL;
1322
1323 if (fun)
1324 {
1325 Type *fun_type = fun->GetType();
1326
1327 if (!fun_type)
1328 {
1329 if (log)
1330 log->PutCString("Skipped a function because it has no type");
1331 return;
1332 }
1333
Greg Clayton462d4142010-09-29 01:12:09 +00001334 fun_opaque_type = fun_type->GetClangType();
Sean Callanan0fc73582010-07-27 00:55:47 +00001335
1336 if (!fun_opaque_type)
1337 {
1338 if (log)
1339 log->PutCString("Skipped a function because it has no Clang type");
1340 return;
1341 }
1342
1343 fun_address = &fun->GetAddressRange().GetBaseAddress();
1344
1345 TypeList *type_list = fun_type->GetTypeList();
1346 fun_ast_context = type_list->GetClangASTContext().getASTContext();
1347 void *copied_type = ClangASTContext::CopyType(context.GetASTContext(), fun_ast_context, fun_opaque_type);
1348
1349 fun_decl = context.AddFunDecl(copied_type);
1350 }
1351 else if (symbol)
1352 {
1353 fun_address = &symbol->GetAddressRangeRef().GetBaseAddress();
1354
1355 fun_decl = context.AddGenericFunDecl();
1356 }
1357 else
1358 {
1359 if (log)
1360 log->PutCString("AddOneFunction called with no function and no symbol");
1361 return;
1362 }
1363
Greg Clayton8de27c72010-10-15 22:48:33 +00001364 lldb::addr_t load_addr = fun_address->GetLoadAddress(m_exe_ctx.target);
Sean Callanan8f0dc342010-06-22 23:46:24 +00001365 fun_location->SetValueType(Value::eValueTypeLoadAddress);
1366 fun_location->GetScalar() = load_addr;
1367
Sean Callanan8c127202010-08-23 23:09:38 +00001368 ClangExpressionVariable &entity(m_found_entities.VariableAtIndex(m_found_entities.CreateVariable()));
Greg Clayton8de27c72010-10-15 22:48:33 +00001369 std::string decl_name(context.m_decl_name.getAsString());
1370 entity.m_name.SetCString(decl_name.c_str());
Sean Callanan8c127202010-08-23 23:09:38 +00001371 entity.m_user_type = TypeFromUser(fun_opaque_type, fun_ast_context);;
Sean Callanan8f0dc342010-06-22 23:46:24 +00001372
Sean Callanan8c127202010-08-23 23:09:38 +00001373 entity.EnableParserVars();
1374 entity.m_parser_vars->m_named_decl = fun_decl;
1375 entity.m_parser_vars->m_llvm_value = NULL;
1376 entity.m_parser_vars->m_lldb_value = fun_location.release();
1377
Sean Callanan810f22d2010-07-16 00:09:46 +00001378 if (log)
Greg Clayton8de27c72010-10-15 22:48:33 +00001379 {
Sean Callanana0744822010-11-01 23:22:47 +00001380 std::string fun_decl_print_string;
1381 llvm::raw_string_ostream fun_decl_print_stream(fun_decl_print_string);
1382 fun_decl->print(fun_decl_print_stream);
1383 fun_decl_print_stream.flush();
1384
1385 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 +00001386 }
Chris Lattner24943d22010-06-08 16:52:24 +00001387}
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001388
1389void
1390ClangExpressionDeclMap::AddOneType(NameSearchContext &context,
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001391 TypeFromUser &ut,
1392 bool add_method)
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001393{
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001394 clang::ASTContext *parser_ast_context = context.GetASTContext();
1395 clang::ASTContext *user_ast_context = ut.GetASTContext();
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001396
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001397 void *copied_type = ClangASTContext::CopyType(parser_ast_context, user_ast_context, ut.GetOpaqueQualType());
1398
1399 TypeFromParser parser_type(copied_type, parser_ast_context);
1400
1401 if (add_method && ClangASTContext::IsAggregateType(copied_type))
1402 {
1403 void *args[1];
1404
1405 args[0] = ClangASTContext::GetVoidPtrType(parser_ast_context, false);
1406
1407 void *method_type = ClangASTContext::CreateFunctionType (parser_ast_context,
1408 ClangASTContext::GetBuiltInType_void(parser_ast_context),
1409 args,
1410 1,
1411 false,
1412 ClangASTContext::GetTypeQualifiers(copied_type));
Greg Clayton30449d52010-10-01 02:31:07 +00001413
Greg Clayton1d8173f2010-09-24 05:15:53 +00001414 const bool is_virtual = false;
1415 const bool is_static = false;
1416 const bool is_inline = false;
Greg Clayton30449d52010-10-01 02:31:07 +00001417 const bool is_explicit = false;
1418
Greg Clayton1d8173f2010-09-24 05:15:53 +00001419 ClangASTContext::AddMethodToCXXRecordType (parser_ast_context,
1420 copied_type,
Greg Clayton8de27c72010-10-15 22:48:33 +00001421 "$__lldb_expr",
Greg Clayton1d8173f2010-09-24 05:15:53 +00001422 method_type,
1423 lldb::eAccessPublic,
1424 is_virtual,
1425 is_static,
Greg Clayton30449d52010-10-01 02:31:07 +00001426 is_inline,
1427 is_explicit);
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001428 }
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001429
1430 context.AddTypeDecl(copied_type);
1431}