blob: 6d72ed2488d53160ef71102502199355a98f882a [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- ClangExpressionDeclMap.cpp -----------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lldb/Expression/ClangExpressionDeclMap.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
Sean Callanan47a5c4c2010-09-23 03:01:22 +000016#include "clang/AST/DeclarationName.h"
Chris Lattner24943d22010-06-08 16:52:24 +000017#include "lldb/lldb-private.h"
18#include "lldb/Core/Address.h"
Sean Callanan810f22d2010-07-16 00:09:46 +000019#include "lldb/Core/Error.h"
Sean Callanan6184dfe2010-06-23 00:47:48 +000020#include "lldb/Core/Log.h"
Chris Lattner24943d22010-06-08 16:52:24 +000021#include "lldb/Core/Module.h"
22#include "lldb/Expression/ClangASTSource.h"
Sean Callanana48fe162010-08-11 03:57:18 +000023#include "lldb/Expression/ClangPersistentVariables.h"
Chris Lattner24943d22010-06-08 16:52:24 +000024#include "lldb/Symbol/ClangASTContext.h"
25#include "lldb/Symbol/CompileUnit.h"
26#include "lldb/Symbol/Function.h"
27#include "lldb/Symbol/ObjectFile.h"
28#include "lldb/Symbol/SymbolContext.h"
29#include "lldb/Symbol/Type.h"
30#include "lldb/Symbol/TypeList.h"
31#include "lldb/Symbol/Variable.h"
32#include "lldb/Symbol/VariableList.h"
Sean Callananf328c9f2010-07-20 23:31:16 +000033#include "lldb/Target/ExecutionContext.h"
Sean Callanan810f22d2010-07-16 00:09:46 +000034#include "lldb/Target/Process.h"
Sean Callanan17c6a052010-10-05 20:18:48 +000035#include "lldb/Target/RegisterContext.h"
Chris Lattner24943d22010-06-08 16:52:24 +000036#include "lldb/Target/StackFrame.h"
Sean Callananf328c9f2010-07-20 23:31:16 +000037#include "lldb/Target/Target.h"
Chris Lattner24943d22010-06-08 16:52:24 +000038
Chris Lattner24943d22010-06-08 16:52:24 +000039using namespace lldb_private;
40using namespace clang;
41
Sean Callanana48fe162010-08-11 03:57:18 +000042ClangExpressionDeclMap::ClangExpressionDeclMap(ExecutionContext *exe_ctx) :
43 m_exe_ctx(exe_ctx), m_struct_laid_out(false),
Sean Callanan810f22d2010-07-16 00:09:46 +000044 m_materialized_location(0)
Chris Lattner24943d22010-06-08 16:52:24 +000045{
46 if (exe_ctx && exe_ctx->frame)
47 m_sym_ctx = new SymbolContext(exe_ctx->frame->GetSymbolContext(lldb::eSymbolContextEverything));
48 else
49 m_sym_ctx = NULL;
Sean Callanana48fe162010-08-11 03:57:18 +000050
51 if (exe_ctx && exe_ctx->process)
52 m_persistent_vars = &exe_ctx->process->GetPersistentVariables();
Chris Lattner24943d22010-06-08 16:52:24 +000053}
54
55ClangExpressionDeclMap::~ClangExpressionDeclMap()
Sean Callanan8c127202010-08-23 23:09:38 +000056{
57 for (uint64_t entity_index = 0, num_entities = m_found_entities.Size();
58 entity_index < num_entities;
59 ++entity_index)
60 {
61 ClangExpressionVariable &entity(m_found_entities.VariableAtIndex(entity_index));
62 if (entity.m_parser_vars.get() &&
63 entity.m_parser_vars->m_lldb_value)
64 delete entity.m_parser_vars->m_lldb_value;
Sean Callanan45690fe2010-08-30 22:17:16 +000065
66 entity.DisableParserVars();
67 }
68
69 for (uint64_t pvar_index = 0, num_pvars = m_persistent_vars->Size();
70 pvar_index < num_pvars;
71 ++pvar_index)
72 {
73 ClangExpressionVariable &pvar(m_persistent_vars->VariableAtIndex(pvar_index));
74 pvar.DisableParserVars();
Sean Callanan8c127202010-08-23 23:09:38 +000075 }
Chris Lattner24943d22010-06-08 16:52:24 +000076
Sean Callanan7a60b942010-10-08 01:58:41 +000077 if (m_materialized_location)
78 {
79 m_exe_ctx->process->DeallocateMemory(m_materialized_location);
80 m_materialized_location = 0;
81 }
82
Chris Lattner24943d22010-06-08 16:52:24 +000083 if (m_sym_ctx)
84 delete m_sym_ctx;
85}
86
Sean Callanan8bce6652010-07-13 21:41:46 +000087// Interface for IRForTarget
88
Sean Callanan82b74c82010-08-12 01:56:52 +000089void
90ClangExpressionDeclMap::GetPersistentResultName (std::string &name)
91{
92 m_persistent_vars->GetNextResultName(m_result_name);
93
94 name = m_result_name;
95}
96
Sean Callanan8bce6652010-07-13 21:41:46 +000097bool
Sean Callanan8c127202010-08-23 23:09:38 +000098ClangExpressionDeclMap::AddPersistentVariable (const clang::NamedDecl *decl,
99 const char *name,
100 TypeFromParser parser_type)
Sean Callanana48fe162010-08-11 03:57:18 +0000101{
102 clang::ASTContext *context(m_exe_ctx->target->GetScratchClangASTContext()->getASTContext());
103
Sean Callanana48fe162010-08-11 03:57:18 +0000104 TypeFromUser user_type(ClangASTContext::CopyType(context,
Sean Callanan82b74c82010-08-12 01:56:52 +0000105 parser_type.GetASTContext(),
106 parser_type.GetOpaqueQualType()),
Sean Callanana48fe162010-08-11 03:57:18 +0000107 context);
108
Sean Callanan8c127202010-08-23 23:09:38 +0000109 if (!m_persistent_vars->CreatePersistentVariable (name, user_type))
110 return false;
111
112 ClangExpressionVariable *var = m_persistent_vars->GetVariable(name);
113
114 if (!var)
115 return false;
116
117 var->EnableParserVars();
118
119 var->m_parser_vars->m_named_decl = decl;
120 var->m_parser_vars->m_parser_type = parser_type;
121
122 return true;
Sean Callanana48fe162010-08-11 03:57:18 +0000123}
124
125bool
Sean Callanan8c127202010-08-23 23:09:38 +0000126ClangExpressionDeclMap::AddValueToStruct (const clang::NamedDecl *decl,
Sean Callanan45690fe2010-08-30 22:17:16 +0000127 const char *name,
Sean Callanan8c127202010-08-23 23:09:38 +0000128 llvm::Value *value,
Sean Callanan8bce6652010-07-13 21:41:46 +0000129 size_t size,
130 off_t alignment)
131{
Sean Callanan45690fe2010-08-30 22:17:16 +0000132 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
133
Sean Callanan8bce6652010-07-13 21:41:46 +0000134 m_struct_laid_out = false;
135
Sean Callanan8c127202010-08-23 23:09:38 +0000136 if (m_struct_members.GetVariable(decl))
137 return true;
Sean Callanan8bce6652010-07-13 21:41:46 +0000138
Sean Callanan8c127202010-08-23 23:09:38 +0000139 ClangExpressionVariable *var = m_found_entities.GetVariable(decl);
Sean Callanan8bce6652010-07-13 21:41:46 +0000140
Sean Callanan8c127202010-08-23 23:09:38 +0000141 if (!var)
142 var = m_persistent_vars->GetVariable(decl);
Sean Callanan8bce6652010-07-13 21:41:46 +0000143
Sean Callanan8c127202010-08-23 23:09:38 +0000144 if (!var)
145 return false;
146
Sean Callanan45690fe2010-08-30 22:17:16 +0000147 if (log)
148 log->Printf("Adding value for decl %p [%s - %s] to the structure",
149 decl,
150 name,
151 var->m_name.c_str());
152
Sean Callanan8c127202010-08-23 23:09:38 +0000153 // We know entity->m_parser_vars is valid because we used a parser variable
154 // to find it
155 var->m_parser_vars->m_llvm_value = value;
156
157 var->EnableJITVars();
158 var->m_jit_vars->m_alignment = alignment;
159 var->m_jit_vars->m_size = size;
160
161 m_struct_members.AddVariable(*var);
Sean Callanan8bce6652010-07-13 21:41:46 +0000162
163 return true;
164}
165
166bool
167ClangExpressionDeclMap::DoStructLayout ()
168{
169 if (m_struct_laid_out)
170 return true;
171
Sean Callanan8bce6652010-07-13 21:41:46 +0000172 off_t cursor = 0;
173
174 m_struct_alignment = 0;
175 m_struct_size = 0;
176
Sean Callanan8c127202010-08-23 23:09:38 +0000177 for (uint64_t member_index = 0, num_members = m_struct_members.Size();
178 member_index < num_members;
179 ++member_index)
Sean Callanan8bce6652010-07-13 21:41:46 +0000180 {
Sean Callanan8c127202010-08-23 23:09:38 +0000181 ClangExpressionVariable &member(m_struct_members.VariableAtIndex(member_index));
Sean Callanan8bce6652010-07-13 21:41:46 +0000182
Sean Callanan8c127202010-08-23 23:09:38 +0000183 if (!member.m_jit_vars.get())
184 return false;
Sean Callanan8bce6652010-07-13 21:41:46 +0000185
Sean Callanan8c127202010-08-23 23:09:38 +0000186 if (member_index == 0)
187 m_struct_alignment = member.m_jit_vars->m_alignment;
188
189 if (cursor % member.m_jit_vars->m_alignment)
190 cursor += (member.m_jit_vars->m_alignment - (cursor % member.m_jit_vars->m_alignment));
191
192 member.m_jit_vars->m_offset = cursor;
193 cursor += member.m_jit_vars->m_size;
Sean Callanan8bce6652010-07-13 21:41:46 +0000194 }
195
196 m_struct_size = cursor;
197
198 m_struct_laid_out = true;
199 return true;
200}
201
202bool ClangExpressionDeclMap::GetStructInfo (uint32_t &num_elements,
203 size_t &size,
204 off_t &alignment)
205{
206 if (!m_struct_laid_out)
207 return false;
208
Sean Callanan8c127202010-08-23 23:09:38 +0000209 num_elements = m_struct_members.Size();
Sean Callanan8bce6652010-07-13 21:41:46 +0000210 size = m_struct_size;
211 alignment = m_struct_alignment;
212
213 return true;
214}
215
216bool
217ClangExpressionDeclMap::GetStructElement (const clang::NamedDecl *&decl,
218 llvm::Value *&value,
219 off_t &offset,
Sean Callanan45690fe2010-08-30 22:17:16 +0000220 const char *&name,
Sean Callanan8bce6652010-07-13 21:41:46 +0000221 uint32_t index)
222{
223 if (!m_struct_laid_out)
224 return false;
225
Sean Callanan8c127202010-08-23 23:09:38 +0000226 if (index >= m_struct_members.Size())
Sean Callanan8bce6652010-07-13 21:41:46 +0000227 return false;
228
Sean Callanan8c127202010-08-23 23:09:38 +0000229 ClangExpressionVariable &member(m_struct_members.VariableAtIndex(index));
Sean Callanan8bce6652010-07-13 21:41:46 +0000230
Sean Callanan8c127202010-08-23 23:09:38 +0000231 if (!member.m_parser_vars.get() ||
232 !member.m_jit_vars.get())
233 return false;
234
235 decl = member.m_parser_vars->m_named_decl;
236 value = member.m_parser_vars->m_llvm_value;
237 offset = member.m_jit_vars->m_offset;
Sean Callanan45690fe2010-08-30 22:17:16 +0000238 name = member.m_name.c_str();
Sean Callanan8c127202010-08-23 23:09:38 +0000239
Sean Callanan8bce6652010-07-13 21:41:46 +0000240 return true;
241}
242
Sean Callanan02fbafa2010-07-27 21:39:39 +0000243bool
244ClangExpressionDeclMap::GetFunctionInfo (const clang::NamedDecl *decl,
245 llvm::Value**& value,
246 uint64_t &ptr)
Sean Callananba992c52010-07-27 02:07:53 +0000247{
Sean Callanan8c127202010-08-23 23:09:38 +0000248 ClangExpressionVariable *entity = m_found_entities.GetVariable(decl);
249
250 if (!entity)
251 return false;
Sean Callananba992c52010-07-27 02:07:53 +0000252
Sean Callanan8c127202010-08-23 23:09:38 +0000253 // We know m_parser_vars is valid since we searched for the variable by
254 // its NamedDecl
Sean Callananba992c52010-07-27 02:07:53 +0000255
Sean Callanan8c127202010-08-23 23:09:38 +0000256 value = &entity->m_parser_vars->m_llvm_value;
257 ptr = entity->m_parser_vars->m_lldb_value->GetScalar().ULongLong();
258
259 return true;
Sean Callananba992c52010-07-27 02:07:53 +0000260}
261
Sean Callananf5857a02010-07-31 01:32:05 +0000262bool
263ClangExpressionDeclMap::GetFunctionAddress (const char *name,
264 uint64_t &ptr)
265{
266 // Back out in all cases where we're not fully initialized
267 if (!m_exe_ctx || !m_exe_ctx->frame || !m_sym_ctx)
268 return false;
269
270 ConstString name_cs(name);
271 SymbolContextList sym_ctxs;
272
273 m_sym_ctx->FindFunctionsByName(name_cs, false, sym_ctxs);
274
275 if (!sym_ctxs.GetSize())
276 return false;
277
278 SymbolContext sym_ctx;
279 sym_ctxs.GetContextAtIndex(0, sym_ctx);
280
281 const Address *fun_address;
282
283 if (sym_ctx.function)
284 fun_address = &sym_ctx.function->GetAddressRange().GetBaseAddress();
285 else if (sym_ctx.symbol)
286 fun_address = &sym_ctx.symbol->GetAddressRangeRef().GetBaseAddress();
287 else
288 return false;
289
Greg Claytoneea26402010-09-14 23:36:40 +0000290 ptr = fun_address->GetLoadAddress(m_exe_ctx->target);
Sean Callananf5857a02010-07-31 01:32:05 +0000291
292 return true;
293}
294
Sean Callanan810f22d2010-07-16 00:09:46 +0000295// Interface for CommandObjectExpression
Sean Callananf328c9f2010-07-20 23:31:16 +0000296
297bool
298ClangExpressionDeclMap::Materialize (ExecutionContext *exe_ctx,
299 lldb::addr_t &struct_address,
300 Error &err)
301{
302 bool result = DoMaterialize(false, exe_ctx, NULL, err);
303
304 if (result)
305 struct_address = m_materialized_location;
306
307 return result;
308}
309
310bool
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000311ClangExpressionDeclMap::GetObjectPointer(lldb::addr_t &object_ptr,
312 ExecutionContext *exe_ctx,
313 Error &err)
314{
315 if (!exe_ctx || !exe_ctx->frame || !exe_ctx->target || !exe_ctx->process)
316 {
317 err.SetErrorString("Couldn't load 'this' because the context is incomplete");
318 return false;
319 }
320
321 if (!m_object_pointer_type.GetOpaqueQualType())
322 {
323 err.SetErrorString("Couldn't load 'this' because its type is unknown");
324 return false;
325 }
326
327 Variable *object_ptr_var = FindVariableInScope(*exe_ctx->frame, "this", &m_object_pointer_type);
328
329 if (!object_ptr_var)
330 {
331 err.SetErrorString("Couldn't find 'this' with appropriate type in scope");
332 return false;
333 }
334
335 std::auto_ptr<lldb_private::Value> location_value(GetVariableValue(*exe_ctx,
336 object_ptr_var,
337 m_object_pointer_type.GetASTContext()));
338
339 if (!location_value.get())
340 {
341 err.SetErrorString("Couldn't get the location for 'this'");
342 return false;
343 }
344
345 if (location_value->GetValueType() == Value::eValueTypeLoadAddress)
346 {
347 lldb::addr_t value_addr = location_value->GetScalar().ULongLong();
348 uint32_t address_byte_size = exe_ctx->target->GetArchitecture().GetAddressByteSize();
349 lldb::ByteOrder address_byte_order = exe_ctx->process->GetByteOrder();
350
351 if (ClangASTType::GetClangTypeBitWidth(m_object_pointer_type.GetASTContext(), m_object_pointer_type.GetOpaqueQualType()) != address_byte_size * 8)
352 {
353 err.SetErrorStringWithFormat("'this' is not of an expected pointer size");
354 return false;
355 }
356
357 DataBufferHeap data;
358 data.SetByteSize(address_byte_size);
359 Error read_error;
360
361 if (exe_ctx->process->ReadMemory (value_addr, data.GetBytes(), address_byte_size, read_error) != address_byte_size)
362 {
363 err.SetErrorStringWithFormat("Coldn't read 'this' from the target: %s", read_error.AsCString());
364 return false;
365 }
366
367 DataExtractor extractor(data.GetBytes(), data.GetByteSize(), address_byte_order, address_byte_size);
368
369 uint32_t offset = 0;
370
371 object_ptr = extractor.GetPointer(&offset);
372
373 return true;
374 }
375 else
376 {
377 err.SetErrorString("'this' is not in memory; LLDB must be extended to handle registers");
378 return false;
379 }
380}
381
382bool
Sean Callananf328c9f2010-07-20 23:31:16 +0000383ClangExpressionDeclMap::Dematerialize (ExecutionContext *exe_ctx,
Sean Callanana6223432010-08-20 01:02:30 +0000384 ClangExpressionVariable *&result,
Sean Callananf328c9f2010-07-20 23:31:16 +0000385 Error &err)
386{
Sean Callanan82b74c82010-08-12 01:56:52 +0000387 return DoMaterialize(true, exe_ctx, &result, err);
Sean Callananf328c9f2010-07-20 23:31:16 +0000388}
389
Sean Callanan32824aa2010-07-23 22:19:18 +0000390bool
391ClangExpressionDeclMap::DumpMaterializedStruct(ExecutionContext *exe_ctx,
392 Stream &s,
393 Error &err)
394{
395 if (!m_struct_laid_out)
396 {
397 err.SetErrorString("Structure hasn't been laid out yet");
398 return false;
399 }
400
401 if (!exe_ctx)
402 {
403 err.SetErrorString("Received null execution context");
404 return false;
405 }
406
407
408 if (!exe_ctx->process)
409 {
410 err.SetErrorString("Couldn't find the process");
411 return false;
412 }
413
414 if (!exe_ctx->target)
415 {
416 err.SetErrorString("Couldn't find the target");
417 return false;
418 }
419
420 lldb::DataBufferSP data(new DataBufferHeap(m_struct_size, 0));
421
422 Error error;
423 if (exe_ctx->process->ReadMemory (m_materialized_location, data->GetBytes(), data->GetByteSize(), error) != data->GetByteSize())
424 {
425 err.SetErrorStringWithFormat ("Couldn't read struct from the target: %s", error.AsCString());
426 return false;
427 }
428
429 DataExtractor extractor(data, exe_ctx->process->GetByteOrder(), exe_ctx->target->GetArchitecture().GetAddressByteSize());
430
Sean Callanan8c127202010-08-23 23:09:38 +0000431 for (uint64_t member_index = 0, num_members = m_struct_members.Size();
432 member_index < num_members;
433 ++member_index)
Sean Callanan32824aa2010-07-23 22:19:18 +0000434 {
Sean Callanan8c127202010-08-23 23:09:38 +0000435 ClangExpressionVariable &member (m_struct_members.VariableAtIndex(member_index));
Sean Callanan32824aa2010-07-23 22:19:18 +0000436
Sean Callanan8c127202010-08-23 23:09:38 +0000437 s.Printf("[%s]\n", member.m_name.c_str());
438
439 if (!member.m_jit_vars.get())
440 return false;
441
442 extractor.Dump(&s, // stream
443 member.m_jit_vars->m_offset, // offset
444 lldb::eFormatBytesWithASCII, // format
445 1, // byte size of individual entries
446 member.m_jit_vars->m_size, // number of entries
447 16, // entries per line
448 m_materialized_location + member.m_jit_vars->m_offset, // address to print
449 0, // bit size (bitfields only; 0 means ignore)
450 0); // bit alignment (bitfields only; 0 means ignore)
Sean Callanan32824aa2010-07-23 22:19:18 +0000451
452 s.PutChar('\n');
453 }
454
455 return true;
456}
457
Sean Callananf328c9f2010-07-20 23:31:16 +0000458bool
459ClangExpressionDeclMap::DoMaterialize (bool dematerialize,
460 ExecutionContext *exe_ctx,
Sean Callanana6223432010-08-20 01:02:30 +0000461 ClangExpressionVariable **result,
Sean Callananf328c9f2010-07-20 23:31:16 +0000462 Error &err)
Sean Callanan810f22d2010-07-16 00:09:46 +0000463{
Sean Callanan336a0002010-07-17 00:43:37 +0000464 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
Sean Callanan82b74c82010-08-12 01:56:52 +0000465
Sean Callanan810f22d2010-07-16 00:09:46 +0000466 if (!m_struct_laid_out)
467 {
468 err.SetErrorString("Structure hasn't been laid out yet");
469 return LLDB_INVALID_ADDRESS;
470 }
471
Sean Callanan810f22d2010-07-16 00:09:46 +0000472 if (!exe_ctx)
473 {
474 err.SetErrorString("Received null execution context");
475 return LLDB_INVALID_ADDRESS;
476 }
477
Sean Callanan45839272010-07-24 01:37:44 +0000478 if (!exe_ctx->frame)
479 {
480 err.SetErrorString("Received null execution frame");
481 return LLDB_INVALID_ADDRESS;
482 }
483
Sean Callanane8a59a82010-09-13 21:34:21 +0000484 if (!m_struct_size)
485 {
486 if (log)
487 log->PutCString("Not bothering to allocate a struct because no arguments are needed");
488
489 m_allocated_area = NULL;
490
491 return true;
492 }
493
Sean Callanan810f22d2010-07-16 00:09:46 +0000494 const SymbolContext &sym_ctx(exe_ctx->frame->GetSymbolContext(lldb::eSymbolContextEverything));
495
Sean Callananf328c9f2010-07-20 23:31:16 +0000496 if (!dematerialize)
Sean Callanan810f22d2010-07-16 00:09:46 +0000497 {
Sean Callananf328c9f2010-07-20 23:31:16 +0000498 if (m_materialized_location)
499 {
500 exe_ctx->process->DeallocateMemory(m_materialized_location);
501 m_materialized_location = 0;
502 }
503
Sean Callanan7a60b942010-10-08 01:58:41 +0000504 if (log)
505 log->PutCString("Allocating memory for materialized argument struct");
506
Sean Callananf328c9f2010-07-20 23:31:16 +0000507 lldb::addr_t mem = exe_ctx->process->AllocateMemory(m_struct_alignment + m_struct_size,
508 lldb::ePermissionsReadable | lldb::ePermissionsWritable,
509 err);
510
511 if (mem == LLDB_INVALID_ADDRESS)
512 return false;
513
514 m_allocated_area = mem;
Sean Callanan810f22d2010-07-16 00:09:46 +0000515 }
516
Sean Callananf328c9f2010-07-20 23:31:16 +0000517 m_materialized_location = m_allocated_area;
518
519 if (m_materialized_location % m_struct_alignment)
Sean Callananf328c9f2010-07-20 23:31:16 +0000520 m_materialized_location += (m_struct_alignment - (m_materialized_location % m_struct_alignment));
Sean Callananf328c9f2010-07-20 23:31:16 +0000521
Sean Callanan8c127202010-08-23 23:09:38 +0000522 for (uint64_t member_index = 0, num_members = m_struct_members.Size();
523 member_index < num_members;
524 ++member_index)
Sean Callanan810f22d2010-07-16 00:09:46 +0000525 {
Sean Callanan8c127202010-08-23 23:09:38 +0000526 ClangExpressionVariable &member (m_struct_members.VariableAtIndex(member_index));
Sean Callanan810f22d2010-07-16 00:09:46 +0000527
Sean Callanan8c127202010-08-23 23:09:38 +0000528 if (!member.m_parser_vars.get())
Sean Callanan336a0002010-07-17 00:43:37 +0000529 return false;
Sean Callanan8c127202010-08-23 23:09:38 +0000530
531 ClangExpressionVariable *entity = m_found_entities.GetVariable(member.m_parser_vars->m_named_decl);
532 ClangExpressionVariable *persistent_variable = m_persistent_vars->GetVariable(member.m_name.c_str());
533
534 if (entity)
535 {
536 if (!member.m_jit_vars.get())
537 return false;
538
539 if (!DoMaterializeOneVariable(dematerialize, *exe_ctx, sym_ctx, member.m_name.c_str(), member.m_user_type, m_materialized_location + member.m_jit_vars->m_offset, err))
540 return false;
541 }
542 else if (persistent_variable)
543 {
Sean Callanan45690fe2010-08-30 22:17:16 +0000544 if (!member.m_name.compare(m_result_name))
545 {
546 if (!dematerialize)
547 continue;
Sean Callanan8c127202010-08-23 23:09:38 +0000548
Sean Callanan8c127202010-08-23 23:09:38 +0000549 if (log)
550 log->PutCString("Found result member in the struct");
Sean Callanan45690fe2010-08-30 22:17:16 +0000551
Sean Callanan8c127202010-08-23 23:09:38 +0000552 *result = &member;
553 }
554
Sean Callanan45690fe2010-08-30 22:17:16 +0000555 if (log)
556 log->Printf("Searched for persistent variable %s and found %s", member.m_name.c_str(), persistent_variable->m_name.c_str());
557
Sean Callanan8c127202010-08-23 23:09:38 +0000558 if (!DoMaterializeOnePersistentVariable(dematerialize, *exe_ctx, persistent_variable->m_name.c_str(), m_materialized_location + member.m_jit_vars->m_offset, err))
559 return false;
560 }
561 else
562 {
563 err.SetErrorStringWithFormat("Unexpected variable %s", member.m_name.c_str());
564 return false;
565 }
Sean Callanan810f22d2010-07-16 00:09:46 +0000566 }
567
Sean Callananf328c9f2010-07-20 23:31:16 +0000568 return true;
569}
570
Sean Callanana48fe162010-08-11 03:57:18 +0000571bool
572ClangExpressionDeclMap::DoMaterializeOnePersistentVariable(bool dematerialize,
573 ExecutionContext &exe_ctx,
574 const char *name,
575 lldb::addr_t addr,
576 Error &err)
Sean Callanan45690fe2010-08-30 22:17:16 +0000577{
Sean Callanana6223432010-08-20 01:02:30 +0000578 ClangExpressionVariable *pvar(m_persistent_vars->GetVariable(name));
Sean Callanana48fe162010-08-11 03:57:18 +0000579
580 if (!pvar)
581 {
582 err.SetErrorStringWithFormat("Undefined persistent variable %s", name);
583 return LLDB_INVALID_ADDRESS;
584 }
585
586 size_t pvar_size = pvar->Size();
Sean Callanana6223432010-08-20 01:02:30 +0000587
Greg Clayton66ed2fb2010-10-05 00:00:42 +0000588 if (!pvar->m_data_sp.get())
Sean Callanana6223432010-08-20 01:02:30 +0000589 return false;
590
Greg Clayton66ed2fb2010-10-05 00:00:42 +0000591 uint8_t *pvar_data = pvar->m_data_sp->GetBytes();
Sean Callanana48fe162010-08-11 03:57:18 +0000592 Error error;
593
594 if (dematerialize)
595 {
596 if (exe_ctx.process->ReadMemory (addr, pvar_data, pvar_size, error) != pvar_size)
597 {
598 err.SetErrorStringWithFormat ("Couldn't read a composite type from the target: %s", error.AsCString());
599 return false;
600 }
601 }
602 else
603 {
604 if (exe_ctx.process->WriteMemory (addr, pvar_data, pvar_size, error) != pvar_size)
605 {
606 err.SetErrorStringWithFormat ("Couldn't write a composite type to the target: %s", error.AsCString());
607 return false;
608 }
609 }
610
611 return true;
612}
613
Sean Callananf328c9f2010-07-20 23:31:16 +0000614bool
615ClangExpressionDeclMap::DoMaterializeOneVariable(bool dematerialize,
616 ExecutionContext &exe_ctx,
617 const SymbolContext &sym_ctx,
618 const char *name,
619 TypeFromUser type,
620 lldb::addr_t addr,
621 Error &err)
622{
623 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
624
Sean Callanan17c6a052010-10-05 20:18:48 +0000625 if (!exe_ctx.frame || !exe_ctx.process)
Sean Callanancc074622010-09-14 21:59:34 +0000626 return false;
627
628 Variable *var = FindVariableInScope(*exe_ctx.frame, name, &type);
Sean Callananf328c9f2010-07-20 23:31:16 +0000629
630 if (!var)
631 {
632 err.SetErrorStringWithFormat("Couldn't find %s with appropriate type", name);
633 return false;
634 }
635
Sean Callanan841026f2010-07-23 00:16:21 +0000636 if (log)
637 log->Printf("%s %s with type %p", (dematerialize ? "Dematerializing" : "Materializing"), name, type.GetOpaqueQualType());
Sean Callananf328c9f2010-07-20 23:31:16 +0000638
639 std::auto_ptr<lldb_private::Value> location_value(GetVariableValue(exe_ctx,
640 var,
641 type.GetASTContext()));
642
643 if (!location_value.get())
644 {
645 err.SetErrorStringWithFormat("Couldn't get value for %s", name);
646 return false;
647 }
Sean Callanan17c6a052010-10-05 20:18:48 +0000648
649 // The size of the type contained in addr
Sean Callananf328c9f2010-07-20 23:31:16 +0000650
Sean Callanan17c6a052010-10-05 20:18:48 +0000651 size_t addr_bit_size = ClangASTType::GetClangTypeBitWidth(type.GetASTContext(), type.GetOpaqueQualType());
652 size_t addr_byte_size = addr_bit_size % 8 ? ((addr_bit_size + 8) / 8) : (addr_bit_size / 8);
653
654 Value::ValueType value_type = location_value->GetValueType();
655
656 switch (value_type)
Sean Callananf328c9f2010-07-20 23:31:16 +0000657 {
Sean Callanan17c6a052010-10-05 20:18:48 +0000658 default:
Sean Callananf328c9f2010-07-20 23:31:16 +0000659 {
Sean Callanan17c6a052010-10-05 20:18:48 +0000660 StreamString ss;
661
662 location_value->Dump(&ss);
663
664 err.SetErrorStringWithFormat("%s has a value of unhandled type: %s", name, ss.GetString().c_str());
Sean Callananf328c9f2010-07-20 23:31:16 +0000665 return false;
666 }
Sean Callanan17c6a052010-10-05 20:18:48 +0000667 break;
668 case Value::eValueTypeLoadAddress:
Sean Callananf328c9f2010-07-20 23:31:16 +0000669 {
Sean Callanan17c6a052010-10-05 20:18:48 +0000670 lldb::addr_t value_addr = location_value->GetScalar().ULongLong();
671
672 DataBufferHeap data;
673 data.SetByteSize(addr_byte_size);
674
675 lldb::addr_t src_addr;
676 lldb::addr_t dest_addr;
677
678 if (dematerialize)
679 {
680 src_addr = addr;
681 dest_addr = value_addr;
682 }
683 else
684 {
685 src_addr = value_addr;
686 dest_addr = addr;
687 }
688
689 Error error;
690 if (exe_ctx.process->ReadMemory (src_addr, data.GetBytes(), addr_byte_size, error) != addr_byte_size)
691 {
692 err.SetErrorStringWithFormat ("Couldn't read %s from the target: %s", name, error.AsCString());
693 return false;
694 }
695
696 if (exe_ctx.process->WriteMemory (dest_addr, data.GetBytes(), addr_byte_size, error) != addr_byte_size)
697 {
698 err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", name, error.AsCString());
699 return false;
700 }
701
702 if (log)
703 log->Printf("Copied from 0x%llx to 0x%llx", (uint64_t)src_addr, (uint64_t)addr);
Sean Callananf328c9f2010-07-20 23:31:16 +0000704 }
Sean Callanan17c6a052010-10-05 20:18:48 +0000705 break;
706 case Value::eValueTypeScalar:
707 {
708 if (location_value->GetContextType() != Value::eContextTypeDCRegisterInfo)
709 {
710 StreamString ss;
711
712 location_value->Dump(&ss);
713
714 err.SetErrorStringWithFormat("%s is a scalar of unhandled type: %s", name, ss.GetString().c_str());
715 return false;
716 }
717
718 lldb::RegisterInfo *register_info = location_value->GetRegisterInfo();
719
720 if (!register_info)
721 {
722 err.SetErrorStringWithFormat("Couldn't get the register information for %s", name);
723 return false;
724 }
725
726 RegisterContext *register_context = exe_ctx.GetRegisterContext();
727
728 if (!register_context)
729 {
730 err.SetErrorStringWithFormat("Couldn't read register context to read %s from %s", name, register_info->name);
731 return false;
732 }
733
734 uint32_t register_number = register_info->kinds[lldb::eRegisterKindLLDB];
735 uint32_t register_byte_size = register_info->byte_size;
736
737 if (dematerialize)
738 {
739 // Moving from addr into a register
740 //
741 // Case 1: addr_byte_size and register_byte_size are the same
742 //
743 // |AABBCCDD| Address contents
744 // |AABBCCDD| Register contents
745 //
746 // Case 2: addr_byte_size is bigger than register_byte_size
747 //
748 // Error! (The register should always be big enough to hold the data)
749 //
750 // Case 3: register_byte_size is bigger than addr_byte_size
751 //
752 // |AABB| Address contents
753 // |AABB0000| Register contents [on little-endian hardware]
754 // |0000AABB| Register contents [on big-endian hardware]
755
756 if (addr_byte_size > register_byte_size)
757 {
758 err.SetErrorStringWithFormat("%s is too big to store in %s", name, register_info->name);
759 return false;
760 }
761
762 uint32_t register_offset;
763
764 switch (exe_ctx.process->GetByteOrder())
765 {
766 default:
767 err.SetErrorStringWithFormat("%s is stored with an unhandled byte order", name);
768 return false;
769 case lldb::eByteOrderLittle:
770 register_offset = 0;
771 break;
772 case lldb::eByteOrderBig:
773 register_offset = register_byte_size - addr_byte_size;
774 break;
775 }
776
777 DataBufferHeap register_data (register_byte_size, 0);
778
779 Error error;
780 if (exe_ctx.process->ReadMemory (addr, register_data.GetBytes() + register_offset, addr_byte_size, error) != addr_byte_size)
781 {
782 err.SetErrorStringWithFormat ("Couldn't read %s from the target: %s", name, error.AsCString());
783 return false;
784 }
785
786 DataExtractor register_extractor (register_data.GetBytes(), register_byte_size, exe_ctx.process->GetByteOrder(), exe_ctx.process->GetAddressByteSize());
787
788 if (!register_context->WriteRegisterBytes(register_number, register_extractor, 0))
789 {
790 err.SetErrorStringWithFormat("Couldn't read %s from %s", name, register_info->name);
791 return false;
792 }
793 }
794 else
795 {
796 // Moving from a register into addr
797 //
798 // Case 1: addr_byte_size and register_byte_size are the same
799 //
800 // |AABBCCDD| Register contents
801 // |AABBCCDD| Address contents
802 //
803 // Case 2: addr_byte_size is bigger than register_byte_size
804 //
805 // Error! (The register should always be big enough to hold the data)
806 //
807 // Case 3: register_byte_size is bigger than addr_byte_size
808 //
809 // |AABBCCDD| Register contents
810 // |AABB| Address contents on little-endian hardware
811 // |CCDD| Address contents on big-endian hardware
812
813 if (addr_byte_size > register_byte_size)
814 {
815 err.SetErrorStringWithFormat("%s is too big to store in %s", name, register_info->name);
816 return false;
817 }
818
819 uint32_t register_offset;
820
821 switch (exe_ctx.process->GetByteOrder())
822 {
823 default:
824 err.SetErrorStringWithFormat("%s is stored with an unhandled byte order", name);
825 return false;
826 case lldb::eByteOrderLittle:
827 register_offset = 0;
828 break;
829 case lldb::eByteOrderBig:
830 register_offset = register_byte_size - addr_byte_size;
831 break;
832 }
833
834 DataExtractor register_extractor;
835
836 if (!register_context->ReadRegisterBytes(register_number, register_extractor))
837 {
838 err.SetErrorStringWithFormat("Couldn't read %s from %s", name, register_info->name);
839 return false;
840 }
841
842 const void *register_data = register_extractor.GetData(&register_offset, addr_byte_size);
843
844 if (!register_data)
845 {
846 err.SetErrorStringWithFormat("Read but couldn't extract data for %s from %s", name, register_info->name);
847 return false;
848 }
849
850 Error error;
851 if (exe_ctx.process->WriteMemory (addr, register_data, addr_byte_size, error) != addr_byte_size)
852 {
853 err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", error.AsCString());
854 return false;
855 }
856 }
857 }
Sean Callananf328c9f2010-07-20 23:31:16 +0000858 }
859
860 return true;
Sean Callanan810f22d2010-07-16 00:09:46 +0000861}
862
Sean Callanancc074622010-09-14 21:59:34 +0000863Variable *
864ClangExpressionDeclMap::FindVariableInScope(StackFrame &frame,
865 const char *name,
866 TypeFromUser *type)
867{
868 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
869
870 ConstString name_cs(name);
871
872 VariableList *var_list = frame.GetVariableList(true);
873
874 lldb::VariableSP var = var_list->FindVariable(name_cs);
875
876 if (!var)
877 return NULL;
878
879 if (!type)
880 return var.get();
881
882 if (type->GetASTContext() == var->GetType()->GetClangAST())
883 {
Greg Clayton462d4142010-09-29 01:12:09 +0000884 if (!ClangASTContext::AreTypesSame(type->GetASTContext(), type->GetOpaqueQualType(), var->GetType()->GetClangType()))
Sean Callanancc074622010-09-14 21:59:34 +0000885 return NULL;
886 }
887 else
888 {
889 if (log)
890 log->PutCString("Skipping a candidate variable because of different AST contexts");
891 return NULL;
892 }
893
894 return var.get();
895
896 return NULL;
897}
Sean Callanan336a0002010-07-17 00:43:37 +0000898
Chris Lattner24943d22010-06-08 16:52:24 +0000899// Interface for ClangASTSource
900void
901ClangExpressionDeclMap::GetDecls(NameSearchContext &context,
902 const char *name)
903{
Sean Callanan6184dfe2010-06-23 00:47:48 +0000904 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000905
Sean Callanan810f22d2010-07-16 00:09:46 +0000906 if (log)
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000907 log->Printf("Hunting for a definition for %s", name);
Chris Lattner24943d22010-06-08 16:52:24 +0000908
909 // Back out in all cases where we're not fully initialized
910 if (!m_exe_ctx || !m_exe_ctx->frame || !m_sym_ctx)
911 return;
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000912
913 ConstString name_cs(name);
Sean Callanancc074622010-09-14 21:59:34 +0000914
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000915 if (!strcmp(name, "___clang_class"))
916 {
917 // Clang is looking for the type of "this"
918
919 VariableList *vars = m_exe_ctx->frame->GetVariableList(false);
920
921 if (!vars)
922 return;
923
924 lldb::VariableSP this_var = vars->FindVariable(ConstString("this"));
925
926 if (!this_var)
927 return;
928
929 Type *this_type = this_var->GetType();
930
931 if (!this_type)
932 return;
933
Greg Clayton462d4142010-09-29 01:12:09 +0000934 TypeFromUser this_user_type(this_type->GetClangType(),
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000935 this_type->GetClangAST());
936
937 m_object_pointer_type = this_user_type;
938
939 void *pointer_target_type;
940
941 if (!ClangASTContext::IsPointerType(this_user_type.GetOpaqueQualType(),
942 &pointer_target_type))
943 return;
944
945 TypeFromUser class_user_type(pointer_target_type,
946 this_type->GetClangAST());
947
948 AddOneType(context, class_user_type, true);
949
950 return;
951 }
952
Sean Callanan0fc73582010-07-27 00:55:47 +0000953 SymbolContextList sym_ctxs;
Chris Lattner24943d22010-06-08 16:52:24 +0000954
Sean Callanan0fc73582010-07-27 00:55:47 +0000955 m_sym_ctx->FindFunctionsByName(name_cs, false, sym_ctxs);
Sean Callanan8f0dc342010-06-22 23:46:24 +0000956
Sean Callanan92aa6662010-09-07 21:49:41 +0000957 bool found_specific = false;
Sean Callanan3cfbd332010-10-06 00:10:07 +0000958 Symbol *generic_symbol = NULL;
959 Symbol *non_extern_symbol = NULL;
Sean Callanan92aa6662010-09-07 21:49:41 +0000960
Sean Callanan0fc73582010-07-27 00:55:47 +0000961 for (uint32_t index = 0, num_indices = sym_ctxs.GetSize();
962 index < num_indices;
963 ++index)
964 {
965 SymbolContext sym_ctx;
966 sym_ctxs.GetContextAtIndex(index, sym_ctx);
Sean Callanan3cfbd332010-10-06 00:10:07 +0000967
Sean Callanan0fc73582010-07-27 00:55:47 +0000968 if (sym_ctx.function)
Sean Callanan92aa6662010-09-07 21:49:41 +0000969 {
970 // TODO only do this if it's a C function; C++ functions may be
971 // overloaded
972 if (!found_specific)
973 AddOneFunction(context, sym_ctx.function, NULL);
974 found_specific = true;
975 }
Sean Callanan3cfbd332010-10-06 00:10:07 +0000976 else if (sym_ctx.symbol)
Sean Callanan92aa6662010-09-07 21:49:41 +0000977 {
Sean Callanan3cfbd332010-10-06 00:10:07 +0000978 if (sym_ctx.symbol->IsExternal())
979 generic_symbol = sym_ctx.symbol;
980 else
981 non_extern_symbol = sym_ctx.symbol;
Sean Callanan92aa6662010-09-07 21:49:41 +0000982 }
Sean Callanan0fc73582010-07-27 00:55:47 +0000983 }
984
Sean Callanan3cfbd332010-10-06 00:10:07 +0000985 if (!found_specific)
986 {
987 if (generic_symbol)
988 AddOneFunction(context, NULL, generic_symbol);
989 else if (non_extern_symbol)
990 AddOneFunction(context, NULL, non_extern_symbol);
991 }
992
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000993 Variable *var = FindVariableInScope(*m_exe_ctx->frame, name);
Sean Callanan336a0002010-07-17 00:43:37 +0000994
995 if (var)
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000996 AddOneVariable(context, var);
Sean Callanan93a4b1a2010-08-04 01:02:13 +0000997
Sean Callanana6223432010-08-20 01:02:30 +0000998 ClangExpressionVariable *pvar(m_persistent_vars->GetVariable(name));
Sean Callanana48fe162010-08-11 03:57:18 +0000999
1000 if (pvar)
1001 AddOneVariable(context, pvar);
1002
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001003
Sean Callanan6df08402010-09-27 23:54:58 +00001004 // See information on gating of this operation next to the definition for
1005 // m_lookedup_types.
1006
1007 const char *name_uniq = name_cs.GetCString();
1008
1009 if (m_lookedup_types.find(name_uniq) == m_lookedup_types.end())
1010 {
1011 // 1 The name is added to m_lookedup_types.
1012 m_lookedup_types.insert(std::pair<const char*, bool>(name_uniq, true));
1013
1014 // 2 The type is looked up and added, potentially causing more type loookups.
1015 lldb::TypeSP type = m_sym_ctx->FindTypeByName(name_cs);
1016
1017 if (type.get())
1018 {
Greg Clayton462d4142010-09-29 01:12:09 +00001019 TypeFromUser user_type(type->GetClangType(),
Sean Callanan6df08402010-09-27 23:54:58 +00001020 type->GetClangAST());
1021
1022 AddOneType(context, user_type, false);
1023 }
1024
1025 // 3 The name is removed from m_lookedup_types.
1026 m_lookedup_types.erase(name_uniq);
1027 }
1028
Sean Callanan336a0002010-07-17 00:43:37 +00001029}
1030
1031Value *
1032ClangExpressionDeclMap::GetVariableValue(ExecutionContext &exe_ctx,
1033 Variable *var,
Sean Callananf328c9f2010-07-20 23:31:16 +00001034 clang::ASTContext *parser_ast_context,
1035 TypeFromUser *user_type,
1036 TypeFromParser *parser_type)
Chris Lattner24943d22010-06-08 16:52:24 +00001037{
Sean Callanan6184dfe2010-06-23 00:47:48 +00001038 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
1039
Chris Lattner24943d22010-06-08 16:52:24 +00001040 Type *var_type = var->GetType();
1041
1042 if (!var_type)
1043 {
Sean Callanan810f22d2010-07-16 00:09:46 +00001044 if (log)
1045 log->PutCString("Skipped a definition because it has no type");
Sean Callanan336a0002010-07-17 00:43:37 +00001046 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001047 }
1048
Greg Clayton462d4142010-09-29 01:12:09 +00001049 void *var_opaque_type = var_type->GetClangType();
Chris Lattner24943d22010-06-08 16:52:24 +00001050
1051 if (!var_opaque_type)
1052 {
Sean Callanan810f22d2010-07-16 00:09:46 +00001053 if (log)
1054 log->PutCString("Skipped a definition because it has no Clang type");
Sean Callanan336a0002010-07-17 00:43:37 +00001055 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001056 }
1057
Chris Lattner24943d22010-06-08 16:52:24 +00001058 TypeList *type_list = var_type->GetTypeList();
1059
1060 if (!type_list)
1061 {
Sean Callanan810f22d2010-07-16 00:09:46 +00001062 if (log)
1063 log->PutCString("Skipped a definition because the type has no associated type list");
Sean Callanan336a0002010-07-17 00:43:37 +00001064 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001065 }
1066
1067 clang::ASTContext *exe_ast_ctx = type_list->GetClangASTContext().getASTContext();
1068
1069 if (!exe_ast_ctx)
1070 {
Sean Callanan810f22d2010-07-16 00:09:46 +00001071 if (log)
1072 log->PutCString("There is no AST context for the current execution context");
Sean Callanan336a0002010-07-17 00:43:37 +00001073 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001074 }
1075
Sean Callanan336a0002010-07-17 00:43:37 +00001076 DWARFExpression &var_location_expr = var->LocationExpression();
1077
Chris Lattner24943d22010-06-08 16:52:24 +00001078 std::auto_ptr<Value> var_location(new Value);
1079
Greg Clayton178710c2010-09-14 02:20:48 +00001080 lldb::addr_t loclist_base_load_addr = LLDB_INVALID_ADDRESS;
1081
1082 if (var_location_expr.IsLocationList())
1083 {
1084 SymbolContext var_sc;
1085 var->CalculateSymbolContext (&var_sc);
Greg Claytoneea26402010-09-14 23:36:40 +00001086 loclist_base_load_addr = var_sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (exe_ctx.target);
Greg Clayton178710c2010-09-14 02:20:48 +00001087 }
Chris Lattner24943d22010-06-08 16:52:24 +00001088 Error err;
1089
Greg Clayton178710c2010-09-14 02:20:48 +00001090 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 +00001091 {
Sean Callanan810f22d2010-07-16 00:09:46 +00001092 if (log)
1093 log->Printf("Error evaluating location: %s", err.AsCString());
Sean Callanan336a0002010-07-17 00:43:37 +00001094 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001095 }
1096
Sean Callanan810f22d2010-07-16 00:09:46 +00001097 clang::ASTContext *var_ast_context = type_list->GetClangASTContext().getASTContext();
1098
Sean Callanan336a0002010-07-17 00:43:37 +00001099 void *type_to_use;
1100
Sean Callananf328c9f2010-07-20 23:31:16 +00001101 if (parser_ast_context)
1102 {
1103 type_to_use = ClangASTContext::CopyType(parser_ast_context, var_ast_context, var_opaque_type);
1104
1105 if (parser_type)
1106 *parser_type = TypeFromParser(type_to_use, parser_ast_context);
1107 }
Sean Callanan336a0002010-07-17 00:43:37 +00001108 else
1109 type_to_use = var_opaque_type;
Chris Lattner24943d22010-06-08 16:52:24 +00001110
1111 if (var_location.get()->GetContextType() == Value::eContextTypeInvalid)
Sean Callanan336a0002010-07-17 00:43:37 +00001112 var_location.get()->SetContext(Value::eContextTypeOpaqueClangQualType, type_to_use);
Chris Lattner24943d22010-06-08 16:52:24 +00001113
1114 if (var_location.get()->GetValueType() == Value::eValueTypeFileAddress)
1115 {
1116 SymbolContext var_sc;
1117 var->CalculateSymbolContext(&var_sc);
Sean Callanan336a0002010-07-17 00:43:37 +00001118
Chris Lattner24943d22010-06-08 16:52:24 +00001119 if (!var_sc.module_sp)
Sean Callanan336a0002010-07-17 00:43:37 +00001120 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001121
1122 ObjectFile *object_file = var_sc.module_sp->GetObjectFile();
1123
1124 if (!object_file)
Sean Callanan336a0002010-07-17 00:43:37 +00001125 return NULL;
1126
Chris Lattner24943d22010-06-08 16:52:24 +00001127 Address so_addr(var_location->GetScalar().ULongLong(), object_file->GetSectionList());
1128
Greg Claytoneea26402010-09-14 23:36:40 +00001129 lldb::addr_t load_addr = so_addr.GetLoadAddress(m_exe_ctx->target);
Chris Lattner24943d22010-06-08 16:52:24 +00001130
1131 var_location->GetScalar() = load_addr;
1132 var_location->SetValueType(Value::eValueTypeLoadAddress);
1133 }
1134
Sean Callananf328c9f2010-07-20 23:31:16 +00001135 if (user_type)
1136 *user_type = TypeFromUser(var_opaque_type, var_ast_context);
Sean Callanan336a0002010-07-17 00:43:37 +00001137
1138 return var_location.release();
1139}
1140
1141void
1142ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001143 Variable* var)
Sean Callanan336a0002010-07-17 00:43:37 +00001144{
1145 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
1146
Sean Callananf328c9f2010-07-20 23:31:16 +00001147 TypeFromUser ut;
1148 TypeFromParser pt;
Sean Callanan336a0002010-07-17 00:43:37 +00001149
1150 Value *var_location = GetVariableValue(*m_exe_ctx,
1151 var,
1152 context.GetASTContext(),
Sean Callananf328c9f2010-07-20 23:31:16 +00001153 &ut,
1154 &pt);
Sean Callanan336a0002010-07-17 00:43:37 +00001155
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001156 NamedDecl *var_decl = context.AddVarDecl(pt.GetOpaqueQualType());
Chris Lattner24943d22010-06-08 16:52:24 +00001157
Sean Callanan8c127202010-08-23 23:09:38 +00001158 ClangExpressionVariable &entity(m_found_entities.VariableAtIndex(m_found_entities.CreateVariable()));
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001159 entity.m_name = context.Name.getAsString();
Sean Callanan8c127202010-08-23 23:09:38 +00001160 entity.m_user_type = ut;
Chris Lattner24943d22010-06-08 16:52:24 +00001161
Sean Callanan8c127202010-08-23 23:09:38 +00001162 entity.EnableParserVars();
1163 entity.m_parser_vars->m_parser_type = pt;
1164 entity.m_parser_vars->m_named_decl = var_decl;
1165 entity.m_parser_vars->m_llvm_value = NULL;
1166 entity.m_parser_vars->m_lldb_value = var_location;
Chris Lattner24943d22010-06-08 16:52:24 +00001167
Sean Callanan810f22d2010-07-16 00:09:46 +00001168 if (log)
Sean Callananf5857a02010-07-31 01:32:05 +00001169 log->Printf("Found variable %s, returned (NamedDecl)%p", context.Name.getAsString().c_str(), var_decl);
Sean Callanan8f0dc342010-06-22 23:46:24 +00001170}
1171
1172void
Sean Callanana48fe162010-08-11 03:57:18 +00001173ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
Sean Callanana6223432010-08-20 01:02:30 +00001174 ClangExpressionVariable *pvar)
Sean Callanana48fe162010-08-11 03:57:18 +00001175{
Sean Callanan45690fe2010-08-30 22:17:16 +00001176 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
1177
Sean Callanana6223432010-08-20 01:02:30 +00001178 TypeFromUser user_type = pvar->m_user_type;
Sean Callanana48fe162010-08-11 03:57:18 +00001179
1180 TypeFromParser parser_type(ClangASTContext::CopyType(context.GetASTContext(),
1181 user_type.GetASTContext(),
1182 user_type.GetOpaqueQualType()),
1183 context.GetASTContext());
1184
Sean Callanan8c127202010-08-23 23:09:38 +00001185 NamedDecl *var_decl = context.AddVarDecl(parser_type.GetOpaqueQualType());
1186
1187 pvar->EnableParserVars();
1188 pvar->m_parser_vars->m_parser_type = parser_type;
1189 pvar->m_parser_vars->m_named_decl = var_decl;
1190 pvar->m_parser_vars->m_llvm_value = NULL;
1191 pvar->m_parser_vars->m_lldb_value = NULL;
Sean Callanan45690fe2010-08-30 22:17:16 +00001192
1193 if (log)
1194 log->Printf("Added pvar %s, returned (NamedDecl)%p", pvar->m_name.c_str(), var_decl);
Sean Callanana48fe162010-08-11 03:57:18 +00001195}
1196
1197void
Sean Callanan8f0dc342010-06-22 23:46:24 +00001198ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
Sean Callanan0fc73582010-07-27 00:55:47 +00001199 Function* fun,
1200 Symbol* symbol)
Sean Callanan8f0dc342010-06-22 23:46:24 +00001201{
Sean Callanan6184dfe2010-06-23 00:47:48 +00001202 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
Sean Callanan8f0dc342010-06-22 23:46:24 +00001203
Sean Callanan0fc73582010-07-27 00:55:47 +00001204 NamedDecl *fun_decl;
Sean Callanan8f0dc342010-06-22 23:46:24 +00001205 std::auto_ptr<Value> fun_location(new Value);
Sean Callanan0fc73582010-07-27 00:55:47 +00001206 const Address *fun_address;
Sean Callanan8f0dc342010-06-22 23:46:24 +00001207
Sean Callanan0fc73582010-07-27 00:55:47 +00001208 // only valid for Functions, not for Symbols
1209 void *fun_opaque_type = NULL;
1210 clang::ASTContext *fun_ast_context = NULL;
1211
1212 if (fun)
1213 {
Sean Callanan55261a12010-09-08 22:38:54 +00001214#define BROKEN_OVERLOADING
1215 // Awaiting a fix on the Clang side
1216#ifndef BROKEN_OVERLOADING
Sean Callanan0fc73582010-07-27 00:55:47 +00001217 Type *fun_type = fun->GetType();
1218
1219 if (!fun_type)
1220 {
1221 if (log)
1222 log->PutCString("Skipped a function because it has no type");
1223 return;
1224 }
1225
Greg Clayton462d4142010-09-29 01:12:09 +00001226 fun_opaque_type = fun_type->GetClangType();
Sean Callanan0fc73582010-07-27 00:55:47 +00001227
1228 if (!fun_opaque_type)
1229 {
1230 if (log)
1231 log->PutCString("Skipped a function because it has no Clang type");
1232 return;
1233 }
1234
1235 fun_address = &fun->GetAddressRange().GetBaseAddress();
1236
1237 TypeList *type_list = fun_type->GetTypeList();
1238 fun_ast_context = type_list->GetClangASTContext().getASTContext();
1239 void *copied_type = ClangASTContext::CopyType(context.GetASTContext(), fun_ast_context, fun_opaque_type);
1240
1241 fun_decl = context.AddFunDecl(copied_type);
Sean Callanan55261a12010-09-08 22:38:54 +00001242#else
1243 fun_address = &fun->GetAddressRange().GetBaseAddress();
1244
1245 fun_decl = context.AddGenericFunDecl();
1246#endif
Sean Callanan0fc73582010-07-27 00:55:47 +00001247 }
1248 else if (symbol)
1249 {
1250 fun_address = &symbol->GetAddressRangeRef().GetBaseAddress();
1251
1252 fun_decl = context.AddGenericFunDecl();
1253 }
1254 else
1255 {
1256 if (log)
1257 log->PutCString("AddOneFunction called with no function and no symbol");
1258 return;
1259 }
1260
Greg Claytoneea26402010-09-14 23:36:40 +00001261 lldb::addr_t load_addr = fun_address->GetLoadAddress(m_exe_ctx->target);
Sean Callanan8f0dc342010-06-22 23:46:24 +00001262 fun_location->SetValueType(Value::eValueTypeLoadAddress);
1263 fun_location->GetScalar() = load_addr;
1264
Sean Callanan8c127202010-08-23 23:09:38 +00001265 ClangExpressionVariable &entity(m_found_entities.VariableAtIndex(m_found_entities.CreateVariable()));
1266 entity.m_name = context.Name.getAsString();
1267 entity.m_user_type = TypeFromUser(fun_opaque_type, fun_ast_context);;
Sean Callanan8f0dc342010-06-22 23:46:24 +00001268
Sean Callanan8c127202010-08-23 23:09:38 +00001269 entity.EnableParserVars();
1270 entity.m_parser_vars->m_named_decl = fun_decl;
1271 entity.m_parser_vars->m_llvm_value = NULL;
1272 entity.m_parser_vars->m_lldb_value = fun_location.release();
1273
Sean Callanan810f22d2010-07-16 00:09:46 +00001274 if (log)
Sean Callanan92aa6662010-09-07 21:49:41 +00001275 log->Printf("Found %s function %s, returned (NamedDecl)%p", (fun ? "specific" : "generic"), context.Name.getAsString().c_str(), fun_decl);
Chris Lattner24943d22010-06-08 16:52:24 +00001276}
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001277
1278void
1279ClangExpressionDeclMap::AddOneType(NameSearchContext &context,
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001280 TypeFromUser &ut,
1281 bool add_method)
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001282{
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001283 clang::ASTContext *parser_ast_context = context.GetASTContext();
1284 clang::ASTContext *user_ast_context = ut.GetASTContext();
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001285
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001286 void *copied_type = ClangASTContext::CopyType(parser_ast_context, user_ast_context, ut.GetOpaqueQualType());
1287
1288 TypeFromParser parser_type(copied_type, parser_ast_context);
1289
1290 if (add_method && ClangASTContext::IsAggregateType(copied_type))
1291 {
1292 void *args[1];
1293
1294 args[0] = ClangASTContext::GetVoidPtrType(parser_ast_context, false);
1295
1296 void *method_type = ClangASTContext::CreateFunctionType (parser_ast_context,
1297 ClangASTContext::GetBuiltInType_void(parser_ast_context),
1298 args,
1299 1,
1300 false,
1301 ClangASTContext::GetTypeQualifiers(copied_type));
Greg Clayton30449d52010-10-01 02:31:07 +00001302
Greg Clayton1d8173f2010-09-24 05:15:53 +00001303 const bool is_virtual = false;
1304 const bool is_static = false;
1305 const bool is_inline = false;
Greg Clayton30449d52010-10-01 02:31:07 +00001306 const bool is_explicit = false;
1307
Greg Clayton1d8173f2010-09-24 05:15:53 +00001308 ClangASTContext::AddMethodToCXXRecordType (parser_ast_context,
1309 copied_type,
1310 "___clang_expr",
1311 method_type,
1312 lldb::eAccessPublic,
1313 is_virtual,
1314 is_static,
Greg Clayton30449d52010-10-01 02:31:07 +00001315 is_inline,
1316 is_explicit);
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001317 }
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001318
1319 context.AddTypeDecl(copied_type);
1320}