blob: 662f1539d939d13a2f9785a58f84fe74e04fbeeb [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
16#include "lldb/lldb-private.h"
17#include "lldb/Core/Address.h"
Sean Callanan810f22d2010-07-16 00:09:46 +000018#include "lldb/Core/Error.h"
Sean Callanan6184dfe2010-06-23 00:47:48 +000019#include "lldb/Core/Log.h"
Chris Lattner24943d22010-06-08 16:52:24 +000020#include "lldb/Core/Module.h"
21#include "lldb/Expression/ClangASTSource.h"
Sean Callanana48fe162010-08-11 03:57:18 +000022#include "lldb/Expression/ClangPersistentVariables.h"
Chris Lattner24943d22010-06-08 16:52:24 +000023#include "lldb/Symbol/ClangASTContext.h"
24#include "lldb/Symbol/CompileUnit.h"
25#include "lldb/Symbol/Function.h"
26#include "lldb/Symbol/ObjectFile.h"
27#include "lldb/Symbol/SymbolContext.h"
28#include "lldb/Symbol/Type.h"
29#include "lldb/Symbol/TypeList.h"
30#include "lldb/Symbol/Variable.h"
31#include "lldb/Symbol/VariableList.h"
Sean Callananf328c9f2010-07-20 23:31:16 +000032#include "lldb/Target/ExecutionContext.h"
Sean Callanan810f22d2010-07-16 00:09:46 +000033#include "lldb/Target/Process.h"
Chris Lattner24943d22010-06-08 16:52:24 +000034#include "lldb/Target/StackFrame.h"
Sean Callananf328c9f2010-07-20 23:31:16 +000035#include "lldb/Target/Target.h"
Chris Lattner24943d22010-06-08 16:52:24 +000036
Chris Lattner24943d22010-06-08 16:52:24 +000037using namespace lldb_private;
38using namespace clang;
39
Sean Callanana48fe162010-08-11 03:57:18 +000040ClangExpressionDeclMap::ClangExpressionDeclMap(ExecutionContext *exe_ctx) :
41 m_exe_ctx(exe_ctx), m_struct_laid_out(false),
Sean Callanan810f22d2010-07-16 00:09:46 +000042 m_materialized_location(0)
Chris Lattner24943d22010-06-08 16:52:24 +000043{
44 if (exe_ctx && exe_ctx->frame)
45 m_sym_ctx = new SymbolContext(exe_ctx->frame->GetSymbolContext(lldb::eSymbolContextEverything));
46 else
47 m_sym_ctx = NULL;
Sean Callanana48fe162010-08-11 03:57:18 +000048
49 if (exe_ctx && exe_ctx->process)
50 m_persistent_vars = &exe_ctx->process->GetPersistentVariables();
Chris Lattner24943d22010-06-08 16:52:24 +000051}
52
53ClangExpressionDeclMap::~ClangExpressionDeclMap()
Sean Callanan8c127202010-08-23 23:09:38 +000054{
55 for (uint64_t entity_index = 0, num_entities = m_found_entities.Size();
56 entity_index < num_entities;
57 ++entity_index)
58 {
59 ClangExpressionVariable &entity(m_found_entities.VariableAtIndex(entity_index));
60 if (entity.m_parser_vars.get() &&
61 entity.m_parser_vars->m_lldb_value)
62 delete entity.m_parser_vars->m_lldb_value;
Sean Callanan45690fe2010-08-30 22:17:16 +000063
64 entity.DisableParserVars();
65 }
66
67 for (uint64_t pvar_index = 0, num_pvars = m_persistent_vars->Size();
68 pvar_index < num_pvars;
69 ++pvar_index)
70 {
71 ClangExpressionVariable &pvar(m_persistent_vars->VariableAtIndex(pvar_index));
72 pvar.DisableParserVars();
Sean Callanan8c127202010-08-23 23:09:38 +000073 }
Chris Lattner24943d22010-06-08 16:52:24 +000074
75 if (m_sym_ctx)
76 delete m_sym_ctx;
77}
78
Sean Callanan8bce6652010-07-13 21:41:46 +000079// Interface for IRForTarget
80
Sean Callanan82b74c82010-08-12 01:56:52 +000081void
82ClangExpressionDeclMap::GetPersistentResultName (std::string &name)
83{
84 m_persistent_vars->GetNextResultName(m_result_name);
85
86 name = m_result_name;
87}
88
Sean Callanan8bce6652010-07-13 21:41:46 +000089bool
Sean Callanan8c127202010-08-23 23:09:38 +000090ClangExpressionDeclMap::AddPersistentVariable (const clang::NamedDecl *decl,
91 const char *name,
92 TypeFromParser parser_type)
Sean Callanana48fe162010-08-11 03:57:18 +000093{
94 clang::ASTContext *context(m_exe_ctx->target->GetScratchClangASTContext()->getASTContext());
95
Sean Callanana48fe162010-08-11 03:57:18 +000096 TypeFromUser user_type(ClangASTContext::CopyType(context,
Sean Callanan82b74c82010-08-12 01:56:52 +000097 parser_type.GetASTContext(),
98 parser_type.GetOpaqueQualType()),
Sean Callanana48fe162010-08-11 03:57:18 +000099 context);
100
Sean Callanan8c127202010-08-23 23:09:38 +0000101 if (!m_persistent_vars->CreatePersistentVariable (name, user_type))
102 return false;
103
104 ClangExpressionVariable *var = m_persistent_vars->GetVariable(name);
105
106 if (!var)
107 return false;
108
109 var->EnableParserVars();
110
111 var->m_parser_vars->m_named_decl = decl;
112 var->m_parser_vars->m_parser_type = parser_type;
113
114 return true;
Sean Callanana48fe162010-08-11 03:57:18 +0000115}
116
117bool
Sean Callanan8c127202010-08-23 23:09:38 +0000118ClangExpressionDeclMap::AddValueToStruct (const clang::NamedDecl *decl,
Sean Callanan45690fe2010-08-30 22:17:16 +0000119 const char *name,
Sean Callanan8c127202010-08-23 23:09:38 +0000120 llvm::Value *value,
Sean Callanan8bce6652010-07-13 21:41:46 +0000121 size_t size,
122 off_t alignment)
123{
Sean Callanan45690fe2010-08-30 22:17:16 +0000124 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
125
Sean Callanan8bce6652010-07-13 21:41:46 +0000126 m_struct_laid_out = false;
127
Sean Callanan8c127202010-08-23 23:09:38 +0000128 if (m_struct_members.GetVariable(decl))
129 return true;
Sean Callanan8bce6652010-07-13 21:41:46 +0000130
Sean Callanan8c127202010-08-23 23:09:38 +0000131 ClangExpressionVariable *var = m_found_entities.GetVariable(decl);
Sean Callanan8bce6652010-07-13 21:41:46 +0000132
Sean Callanan8c127202010-08-23 23:09:38 +0000133 if (!var)
134 var = m_persistent_vars->GetVariable(decl);
Sean Callanan8bce6652010-07-13 21:41:46 +0000135
Sean Callanan8c127202010-08-23 23:09:38 +0000136 if (!var)
137 return false;
138
Sean Callanan45690fe2010-08-30 22:17:16 +0000139 if (log)
140 log->Printf("Adding value for decl %p [%s - %s] to the structure",
141 decl,
142 name,
143 var->m_name.c_str());
144
Sean Callanan8c127202010-08-23 23:09:38 +0000145 // We know entity->m_parser_vars is valid because we used a parser variable
146 // to find it
147 var->m_parser_vars->m_llvm_value = value;
148
149 var->EnableJITVars();
150 var->m_jit_vars->m_alignment = alignment;
151 var->m_jit_vars->m_size = size;
152
153 m_struct_members.AddVariable(*var);
Sean Callanan8bce6652010-07-13 21:41:46 +0000154
155 return true;
156}
157
158bool
159ClangExpressionDeclMap::DoStructLayout ()
160{
161 if (m_struct_laid_out)
162 return true;
163
Sean Callanan8bce6652010-07-13 21:41:46 +0000164 off_t cursor = 0;
165
166 m_struct_alignment = 0;
167 m_struct_size = 0;
168
Sean Callanan8c127202010-08-23 23:09:38 +0000169 for (uint64_t member_index = 0, num_members = m_struct_members.Size();
170 member_index < num_members;
171 ++member_index)
Sean Callanan8bce6652010-07-13 21:41:46 +0000172 {
Sean Callanan8c127202010-08-23 23:09:38 +0000173 ClangExpressionVariable &member(m_struct_members.VariableAtIndex(member_index));
Sean Callanan8bce6652010-07-13 21:41:46 +0000174
Sean Callanan8c127202010-08-23 23:09:38 +0000175 if (!member.m_jit_vars.get())
176 return false;
Sean Callanan8bce6652010-07-13 21:41:46 +0000177
Sean Callanan8c127202010-08-23 23:09:38 +0000178 if (member_index == 0)
179 m_struct_alignment = member.m_jit_vars->m_alignment;
180
181 if (cursor % member.m_jit_vars->m_alignment)
182 cursor += (member.m_jit_vars->m_alignment - (cursor % member.m_jit_vars->m_alignment));
183
184 member.m_jit_vars->m_offset = cursor;
185 cursor += member.m_jit_vars->m_size;
Sean Callanan8bce6652010-07-13 21:41:46 +0000186 }
187
188 m_struct_size = cursor;
189
190 m_struct_laid_out = true;
191 return true;
192}
193
194bool ClangExpressionDeclMap::GetStructInfo (uint32_t &num_elements,
195 size_t &size,
196 off_t &alignment)
197{
198 if (!m_struct_laid_out)
199 return false;
200
Sean Callanan8c127202010-08-23 23:09:38 +0000201 num_elements = m_struct_members.Size();
Sean Callanan8bce6652010-07-13 21:41:46 +0000202 size = m_struct_size;
203 alignment = m_struct_alignment;
204
205 return true;
206}
207
208bool
209ClangExpressionDeclMap::GetStructElement (const clang::NamedDecl *&decl,
210 llvm::Value *&value,
211 off_t &offset,
Sean Callanan45690fe2010-08-30 22:17:16 +0000212 const char *&name,
Sean Callanan8bce6652010-07-13 21:41:46 +0000213 uint32_t index)
214{
215 if (!m_struct_laid_out)
216 return false;
217
Sean Callanan8c127202010-08-23 23:09:38 +0000218 if (index >= m_struct_members.Size())
Sean Callanan8bce6652010-07-13 21:41:46 +0000219 return false;
220
Sean Callanan8c127202010-08-23 23:09:38 +0000221 ClangExpressionVariable &member(m_struct_members.VariableAtIndex(index));
Sean Callanan8bce6652010-07-13 21:41:46 +0000222
Sean Callanan8c127202010-08-23 23:09:38 +0000223 if (!member.m_parser_vars.get() ||
224 !member.m_jit_vars.get())
225 return false;
226
227 decl = member.m_parser_vars->m_named_decl;
228 value = member.m_parser_vars->m_llvm_value;
229 offset = member.m_jit_vars->m_offset;
Sean Callanan45690fe2010-08-30 22:17:16 +0000230 name = member.m_name.c_str();
Sean Callanan8c127202010-08-23 23:09:38 +0000231
Sean Callanan8bce6652010-07-13 21:41:46 +0000232 return true;
233}
234
Sean Callanan02fbafa2010-07-27 21:39:39 +0000235bool
236ClangExpressionDeclMap::GetFunctionInfo (const clang::NamedDecl *decl,
237 llvm::Value**& value,
238 uint64_t &ptr)
Sean Callananba992c52010-07-27 02:07:53 +0000239{
Sean Callanan8c127202010-08-23 23:09:38 +0000240 ClangExpressionVariable *entity = m_found_entities.GetVariable(decl);
241
242 if (!entity)
243 return false;
Sean Callananba992c52010-07-27 02:07:53 +0000244
Sean Callanan8c127202010-08-23 23:09:38 +0000245 // We know m_parser_vars is valid since we searched for the variable by
246 // its NamedDecl
Sean Callananba992c52010-07-27 02:07:53 +0000247
Sean Callanan8c127202010-08-23 23:09:38 +0000248 value = &entity->m_parser_vars->m_llvm_value;
249 ptr = entity->m_parser_vars->m_lldb_value->GetScalar().ULongLong();
250
251 return true;
Sean Callananba992c52010-07-27 02:07:53 +0000252}
253
Sean Callananf5857a02010-07-31 01:32:05 +0000254bool
255ClangExpressionDeclMap::GetFunctionAddress (const char *name,
256 uint64_t &ptr)
257{
258 // Back out in all cases where we're not fully initialized
259 if (!m_exe_ctx || !m_exe_ctx->frame || !m_sym_ctx)
260 return false;
261
262 ConstString name_cs(name);
263 SymbolContextList sym_ctxs;
264
265 m_sym_ctx->FindFunctionsByName(name_cs, false, sym_ctxs);
266
267 if (!sym_ctxs.GetSize())
268 return false;
269
270 SymbolContext sym_ctx;
271 sym_ctxs.GetContextAtIndex(0, sym_ctx);
272
273 const Address *fun_address;
274
275 if (sym_ctx.function)
276 fun_address = &sym_ctx.function->GetAddressRange().GetBaseAddress();
277 else if (sym_ctx.symbol)
278 fun_address = &sym_ctx.symbol->GetAddressRangeRef().GetBaseAddress();
279 else
280 return false;
281
Greg Claytoneea26402010-09-14 23:36:40 +0000282 ptr = fun_address->GetLoadAddress(m_exe_ctx->target);
Sean Callananf5857a02010-07-31 01:32:05 +0000283
284 return true;
285}
286
Sean Callanan810f22d2010-07-16 00:09:46 +0000287// Interface for CommandObjectExpression
Sean Callananf328c9f2010-07-20 23:31:16 +0000288
289bool
290ClangExpressionDeclMap::Materialize (ExecutionContext *exe_ctx,
291 lldb::addr_t &struct_address,
292 Error &err)
293{
294 bool result = DoMaterialize(false, exe_ctx, NULL, err);
295
296 if (result)
297 struct_address = m_materialized_location;
298
299 return result;
300}
301
302bool
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000303ClangExpressionDeclMap::GetObjectPointer(lldb::addr_t &object_ptr,
304 ExecutionContext *exe_ctx,
305 Error &err)
306{
307 if (!exe_ctx || !exe_ctx->frame || !exe_ctx->target || !exe_ctx->process)
308 {
309 err.SetErrorString("Couldn't load 'this' because the context is incomplete");
310 return false;
311 }
312
313 if (!m_object_pointer_type.GetOpaqueQualType())
314 {
315 err.SetErrorString("Couldn't load 'this' because its type is unknown");
316 return false;
317 }
318
319 Variable *object_ptr_var = FindVariableInScope(*exe_ctx->frame, "this", &m_object_pointer_type);
320
321 if (!object_ptr_var)
322 {
323 err.SetErrorString("Couldn't find 'this' with appropriate type in scope");
324 return false;
325 }
326
327 std::auto_ptr<lldb_private::Value> location_value(GetVariableValue(*exe_ctx,
328 object_ptr_var,
329 m_object_pointer_type.GetASTContext()));
330
331 if (!location_value.get())
332 {
333 err.SetErrorString("Couldn't get the location for 'this'");
334 return false;
335 }
336
337 if (location_value->GetValueType() == Value::eValueTypeLoadAddress)
338 {
339 lldb::addr_t value_addr = location_value->GetScalar().ULongLong();
340 uint32_t address_byte_size = exe_ctx->target->GetArchitecture().GetAddressByteSize();
341 lldb::ByteOrder address_byte_order = exe_ctx->process->GetByteOrder();
342
343 if (ClangASTType::GetClangTypeBitWidth(m_object_pointer_type.GetASTContext(), m_object_pointer_type.GetOpaqueQualType()) != address_byte_size * 8)
344 {
345 err.SetErrorStringWithFormat("'this' is not of an expected pointer size");
346 return false;
347 }
348
349 DataBufferHeap data;
350 data.SetByteSize(address_byte_size);
351 Error read_error;
352
353 if (exe_ctx->process->ReadMemory (value_addr, data.GetBytes(), address_byte_size, read_error) != address_byte_size)
354 {
355 err.SetErrorStringWithFormat("Coldn't read 'this' from the target: %s", read_error.AsCString());
356 return false;
357 }
358
359 DataExtractor extractor(data.GetBytes(), data.GetByteSize(), address_byte_order, address_byte_size);
360
361 uint32_t offset = 0;
362
363 object_ptr = extractor.GetPointer(&offset);
364
365 return true;
366 }
367 else
368 {
369 err.SetErrorString("'this' is not in memory; LLDB must be extended to handle registers");
370 return false;
371 }
372}
373
374bool
Sean Callananf328c9f2010-07-20 23:31:16 +0000375ClangExpressionDeclMap::Dematerialize (ExecutionContext *exe_ctx,
Sean Callanana6223432010-08-20 01:02:30 +0000376 ClangExpressionVariable *&result,
Sean Callananf328c9f2010-07-20 23:31:16 +0000377 Error &err)
378{
Sean Callanan82b74c82010-08-12 01:56:52 +0000379 return DoMaterialize(true, exe_ctx, &result, err);
Sean Callananf328c9f2010-07-20 23:31:16 +0000380}
381
Sean Callanan32824aa2010-07-23 22:19:18 +0000382bool
383ClangExpressionDeclMap::DumpMaterializedStruct(ExecutionContext *exe_ctx,
384 Stream &s,
385 Error &err)
386{
387 if (!m_struct_laid_out)
388 {
389 err.SetErrorString("Structure hasn't been laid out yet");
390 return false;
391 }
392
393 if (!exe_ctx)
394 {
395 err.SetErrorString("Received null execution context");
396 return false;
397 }
398
399
400 if (!exe_ctx->process)
401 {
402 err.SetErrorString("Couldn't find the process");
403 return false;
404 }
405
406 if (!exe_ctx->target)
407 {
408 err.SetErrorString("Couldn't find the target");
409 return false;
410 }
411
412 lldb::DataBufferSP data(new DataBufferHeap(m_struct_size, 0));
413
414 Error error;
415 if (exe_ctx->process->ReadMemory (m_materialized_location, data->GetBytes(), data->GetByteSize(), error) != data->GetByteSize())
416 {
417 err.SetErrorStringWithFormat ("Couldn't read struct from the target: %s", error.AsCString());
418 return false;
419 }
420
421 DataExtractor extractor(data, exe_ctx->process->GetByteOrder(), exe_ctx->target->GetArchitecture().GetAddressByteSize());
422
Sean Callanan8c127202010-08-23 23:09:38 +0000423 for (uint64_t member_index = 0, num_members = m_struct_members.Size();
424 member_index < num_members;
425 ++member_index)
Sean Callanan32824aa2010-07-23 22:19:18 +0000426 {
Sean Callanan8c127202010-08-23 23:09:38 +0000427 ClangExpressionVariable &member (m_struct_members.VariableAtIndex(member_index));
Sean Callanan32824aa2010-07-23 22:19:18 +0000428
Sean Callanan8c127202010-08-23 23:09:38 +0000429 s.Printf("[%s]\n", member.m_name.c_str());
430
431 if (!member.m_jit_vars.get())
432 return false;
433
434 extractor.Dump(&s, // stream
435 member.m_jit_vars->m_offset, // offset
436 lldb::eFormatBytesWithASCII, // format
437 1, // byte size of individual entries
438 member.m_jit_vars->m_size, // number of entries
439 16, // entries per line
440 m_materialized_location + member.m_jit_vars->m_offset, // address to print
441 0, // bit size (bitfields only; 0 means ignore)
442 0); // bit alignment (bitfields only; 0 means ignore)
Sean Callanan32824aa2010-07-23 22:19:18 +0000443
444 s.PutChar('\n');
445 }
446
447 return true;
448}
449
Sean Callananf328c9f2010-07-20 23:31:16 +0000450bool
451ClangExpressionDeclMap::DoMaterialize (bool dematerialize,
452 ExecutionContext *exe_ctx,
Sean Callanana6223432010-08-20 01:02:30 +0000453 ClangExpressionVariable **result,
Sean Callananf328c9f2010-07-20 23:31:16 +0000454 Error &err)
Sean Callanan810f22d2010-07-16 00:09:46 +0000455{
Sean Callanan336a0002010-07-17 00:43:37 +0000456 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
Sean Callanan82b74c82010-08-12 01:56:52 +0000457
Sean Callanan810f22d2010-07-16 00:09:46 +0000458 if (!m_struct_laid_out)
459 {
460 err.SetErrorString("Structure hasn't been laid out yet");
461 return LLDB_INVALID_ADDRESS;
462 }
463
Sean Callanan810f22d2010-07-16 00:09:46 +0000464 if (!exe_ctx)
465 {
466 err.SetErrorString("Received null execution context");
467 return LLDB_INVALID_ADDRESS;
468 }
469
Sean Callanan45839272010-07-24 01:37:44 +0000470 if (!exe_ctx->frame)
471 {
472 err.SetErrorString("Received null execution frame");
473 return LLDB_INVALID_ADDRESS;
474 }
475
Sean Callanane8a59a82010-09-13 21:34:21 +0000476 if (!m_struct_size)
477 {
478 if (log)
479 log->PutCString("Not bothering to allocate a struct because no arguments are needed");
480
481 m_allocated_area = NULL;
482
483 return true;
484 }
485
Sean Callanan810f22d2010-07-16 00:09:46 +0000486 const SymbolContext &sym_ctx(exe_ctx->frame->GetSymbolContext(lldb::eSymbolContextEverything));
487
Sean Callananf328c9f2010-07-20 23:31:16 +0000488 if (!dematerialize)
Sean Callanan810f22d2010-07-16 00:09:46 +0000489 {
Sean Callananf328c9f2010-07-20 23:31:16 +0000490 if (m_materialized_location)
491 {
492 exe_ctx->process->DeallocateMemory(m_materialized_location);
493 m_materialized_location = 0;
494 }
495
496 lldb::addr_t mem = exe_ctx->process->AllocateMemory(m_struct_alignment + m_struct_size,
497 lldb::ePermissionsReadable | lldb::ePermissionsWritable,
498 err);
499
500 if (mem == LLDB_INVALID_ADDRESS)
501 return false;
502
503 m_allocated_area = mem;
Sean Callanan810f22d2010-07-16 00:09:46 +0000504 }
505
Sean Callananf328c9f2010-07-20 23:31:16 +0000506 m_materialized_location = m_allocated_area;
507
508 if (m_materialized_location % m_struct_alignment)
Sean Callananf328c9f2010-07-20 23:31:16 +0000509 m_materialized_location += (m_struct_alignment - (m_materialized_location % m_struct_alignment));
Sean Callananf328c9f2010-07-20 23:31:16 +0000510
Sean Callanan8c127202010-08-23 23:09:38 +0000511 for (uint64_t member_index = 0, num_members = m_struct_members.Size();
512 member_index < num_members;
513 ++member_index)
Sean Callanan810f22d2010-07-16 00:09:46 +0000514 {
Sean Callanan8c127202010-08-23 23:09:38 +0000515 ClangExpressionVariable &member (m_struct_members.VariableAtIndex(member_index));
Sean Callanan810f22d2010-07-16 00:09:46 +0000516
Sean Callanan8c127202010-08-23 23:09:38 +0000517 if (!member.m_parser_vars.get())
Sean Callanan336a0002010-07-17 00:43:37 +0000518 return false;
Sean Callanan8c127202010-08-23 23:09:38 +0000519
520 ClangExpressionVariable *entity = m_found_entities.GetVariable(member.m_parser_vars->m_named_decl);
521 ClangExpressionVariable *persistent_variable = m_persistent_vars->GetVariable(member.m_name.c_str());
522
523 if (entity)
524 {
525 if (!member.m_jit_vars.get())
526 return false;
527
528 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))
529 return false;
530 }
531 else if (persistent_variable)
532 {
Sean Callanan45690fe2010-08-30 22:17:16 +0000533 if (!member.m_name.compare(m_result_name))
534 {
535 if (!dematerialize)
536 continue;
Sean Callanan8c127202010-08-23 23:09:38 +0000537
Sean Callanan8c127202010-08-23 23:09:38 +0000538 if (log)
539 log->PutCString("Found result member in the struct");
Sean Callanan45690fe2010-08-30 22:17:16 +0000540
Sean Callanan8c127202010-08-23 23:09:38 +0000541 *result = &member;
542 }
543
Sean Callanan45690fe2010-08-30 22:17:16 +0000544 if (log)
545 log->Printf("Searched for persistent variable %s and found %s", member.m_name.c_str(), persistent_variable->m_name.c_str());
546
Sean Callanan8c127202010-08-23 23:09:38 +0000547 if (!DoMaterializeOnePersistentVariable(dematerialize, *exe_ctx, persistent_variable->m_name.c_str(), m_materialized_location + member.m_jit_vars->m_offset, err))
548 return false;
549 }
550 else
551 {
552 err.SetErrorStringWithFormat("Unexpected variable %s", member.m_name.c_str());
553 return false;
554 }
Sean Callanan810f22d2010-07-16 00:09:46 +0000555 }
556
Sean Callananf328c9f2010-07-20 23:31:16 +0000557 return true;
558}
559
Sean Callanana48fe162010-08-11 03:57:18 +0000560bool
561ClangExpressionDeclMap::DoMaterializeOnePersistentVariable(bool dematerialize,
562 ExecutionContext &exe_ctx,
563 const char *name,
564 lldb::addr_t addr,
565 Error &err)
Sean Callanan45690fe2010-08-30 22:17:16 +0000566{
Sean Callanana6223432010-08-20 01:02:30 +0000567 ClangExpressionVariable *pvar(m_persistent_vars->GetVariable(name));
Sean Callanana48fe162010-08-11 03:57:18 +0000568
569 if (!pvar)
570 {
571 err.SetErrorStringWithFormat("Undefined persistent variable %s", name);
572 return LLDB_INVALID_ADDRESS;
573 }
574
575 size_t pvar_size = pvar->Size();
Sean Callanana6223432010-08-20 01:02:30 +0000576
577 if (!pvar->m_data_vars.get())
578 return false;
579
580 uint8_t *pvar_data = pvar->m_data_vars->m_data->GetBytes();
Sean Callanana48fe162010-08-11 03:57:18 +0000581 Error error;
582
583 if (dematerialize)
584 {
585 if (exe_ctx.process->ReadMemory (addr, pvar_data, pvar_size, error) != pvar_size)
586 {
587 err.SetErrorStringWithFormat ("Couldn't read a composite type from the target: %s", error.AsCString());
588 return false;
589 }
590 }
591 else
592 {
593 if (exe_ctx.process->WriteMemory (addr, pvar_data, pvar_size, error) != pvar_size)
594 {
595 err.SetErrorStringWithFormat ("Couldn't write a composite type to the target: %s", error.AsCString());
596 return false;
597 }
598 }
599
600 return true;
601}
602
Sean Callananf328c9f2010-07-20 23:31:16 +0000603bool
604ClangExpressionDeclMap::DoMaterializeOneVariable(bool dematerialize,
605 ExecutionContext &exe_ctx,
606 const SymbolContext &sym_ctx,
607 const char *name,
608 TypeFromUser type,
609 lldb::addr_t addr,
610 Error &err)
611{
612 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
613
Sean Callanancc074622010-09-14 21:59:34 +0000614 if (!exe_ctx.frame)
615 return false;
616
617 Variable *var = FindVariableInScope(*exe_ctx.frame, name, &type);
Sean Callananf328c9f2010-07-20 23:31:16 +0000618
619 if (!var)
620 {
621 err.SetErrorStringWithFormat("Couldn't find %s with appropriate type", name);
622 return false;
623 }
624
Sean Callanan841026f2010-07-23 00:16:21 +0000625 if (log)
626 log->Printf("%s %s with type %p", (dematerialize ? "Dematerializing" : "Materializing"), name, type.GetOpaqueQualType());
Sean Callananf328c9f2010-07-20 23:31:16 +0000627
628 std::auto_ptr<lldb_private::Value> location_value(GetVariableValue(exe_ctx,
629 var,
630 type.GetASTContext()));
631
632 if (!location_value.get())
633 {
634 err.SetErrorStringWithFormat("Couldn't get value for %s", name);
635 return false;
636 }
637
638 if (location_value->GetValueType() == Value::eValueTypeLoadAddress)
639 {
640 lldb::addr_t value_addr = location_value->GetScalar().ULongLong();
641
Greg Clayton960d6a42010-08-03 00:35:52 +0000642 size_t bit_size = ClangASTType::GetClangTypeBitWidth(type.GetASTContext(), type.GetOpaqueQualType());
Sean Callananf328c9f2010-07-20 23:31:16 +0000643 size_t byte_size = bit_size % 8 ? ((bit_size + 8) / 8) : (bit_size / 8);
644
645 DataBufferHeap data;
646 data.SetByteSize(byte_size);
647
648 lldb::addr_t src_addr;
649 lldb::addr_t dest_addr;
650
651 if (dematerialize)
652 {
653 src_addr = addr;
654 dest_addr = value_addr;
655 }
656 else
657 {
658 src_addr = value_addr;
659 dest_addr = addr;
660 }
661
662 Error error;
663 if (exe_ctx.process->ReadMemory (src_addr, data.GetBytes(), byte_size, error) != byte_size)
664 {
665 err.SetErrorStringWithFormat ("Couldn't read a composite type from the target: %s", error.AsCString());
666 return false;
667 }
668
669 if (exe_ctx.process->WriteMemory (dest_addr, data.GetBytes(), byte_size, error) != byte_size)
670 {
671 err.SetErrorStringWithFormat ("Couldn't write a composite type to the target: %s", error.AsCString());
672 return false;
673 }
674
675 if (log)
676 log->Printf("Copied from 0x%llx to 0x%llx", (uint64_t)src_addr, (uint64_t)addr);
677 }
678 else
679 {
680 StreamString ss;
681
682 location_value->Dump(&ss);
683
684 err.SetErrorStringWithFormat("%s has a value of unhandled type: %s", name, ss.GetString().c_str());
685 }
686
687 return true;
Sean Callanan810f22d2010-07-16 00:09:46 +0000688}
689
Sean Callanancc074622010-09-14 21:59:34 +0000690#ifdef OLD_CODE
Sean Callanan336a0002010-07-17 00:43:37 +0000691Variable*
692ClangExpressionDeclMap::FindVariableInScope(const SymbolContext &sym_ctx,
693 const char *name,
Sean Callananf328c9f2010-07-20 23:31:16 +0000694 TypeFromUser *type)
Sean Callanan810f22d2010-07-16 00:09:46 +0000695{
696 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
697
Greg Clayton75ccf502010-08-21 02:22:51 +0000698 if (m_sym_ctx->function == NULL || m_sym_ctx->block == NULL)
Sean Callanan810f22d2010-07-16 00:09:46 +0000699 {
700 if (log)
Greg Clayton75ccf502010-08-21 02:22:51 +0000701 log->Printf("function = %p, block = %p", m_sym_ctx->function, m_sym_ctx->block);
Sean Callanan336a0002010-07-17 00:43:37 +0000702 return NULL;
Sean Callanan810f22d2010-07-16 00:09:46 +0000703 }
704
Sean Callanan336a0002010-07-17 00:43:37 +0000705 ConstString name_cs(name);
706
Greg Clayton75ccf502010-08-21 02:22:51 +0000707 Block *current_block;
Sean Callanan810f22d2010-07-16 00:09:46 +0000708
Greg Clayton75ccf502010-08-21 02:22:51 +0000709 for (current_block = m_sym_ctx->block;
710 current_block != NULL;
711 current_block = current_block->GetParent())
712 {
Sean Callanan810f22d2010-07-16 00:09:46 +0000713 lldb::VariableListSP var_list = current_block->GetVariableList(false, true);
714
715 if (!var_list)
716 continue;
717
Sean Callanan336a0002010-07-17 00:43:37 +0000718 lldb::VariableSP var = var_list->FindVariable(name_cs);
Sean Callanan810f22d2010-07-16 00:09:46 +0000719
720 if (!var)
721 continue;
722
723 // var->GetType()->GetClangAST() is the program's AST context and holds
724 // var->GetType()->GetOpaqueClangQualType().
725
726 // type is m_type for one of the struct members, which was added by
727 // AddValueToStruct. That type was extracted from the AST context of
728 // the compiler in IRForTarget. The original for the type was copied
729 // out of the program's AST context by AddOneVariable.
730
Sean Callanan336a0002010-07-17 00:43:37 +0000731 // So that we can compare these two without having to copy back
732 // something we already had in the original AST context, we maintain
733 // m_orig_type and m_ast_context (which are passed into
734 // MaterializeOneVariable by Materialize) for each variable.
735
736 if (!type)
737 return var.get();
Sean Callanan810f22d2010-07-16 00:09:46 +0000738
Sean Callananf328c9f2010-07-20 23:31:16 +0000739 if (type->GetASTContext() == var->GetType()->GetClangAST())
Sean Callanan810f22d2010-07-16 00:09:46 +0000740 {
Sean Callananf5857a02010-07-31 01:32:05 +0000741 if (!ClangASTContext::AreTypesSame(type->GetASTContext(), type->GetOpaqueQualType(), var->GetType()->GetOpaqueClangQualType()))
Sean Callanan810f22d2010-07-16 00:09:46 +0000742 continue;
743 }
744 else
745 {
746 if (log)
747 log->PutCString("Skipping a candidate variable because of different AST contexts");
748 continue;
749 }
750
Sean Callanan336a0002010-07-17 00:43:37 +0000751 return var.get();
752 }
753
754 {
755 CompileUnit *compile_unit = m_sym_ctx->comp_unit;
Sean Callanan810f22d2010-07-16 00:09:46 +0000756
Sean Callanan336a0002010-07-17 00:43:37 +0000757 if (!compile_unit)
758 {
759 if (log)
760 log->Printf("compile_unit = %p", compile_unit);
761 return NULL;
762 }
763
764 lldb::VariableListSP var_list = compile_unit->GetVariableList(true);
765
766 if (!var_list)
767 return NULL;
768
769 lldb::VariableSP var = var_list->FindVariable(name_cs);
770
771 if (!var)
772 return NULL;
773
774 if (!type)
775 return var.get();
776
Sean Callananf328c9f2010-07-20 23:31:16 +0000777 if (type->GetASTContext() == var->GetType()->GetClangAST())
Sean Callanan336a0002010-07-17 00:43:37 +0000778 {
Sean Callanan841026f2010-07-23 00:16:21 +0000779 if (!ClangASTContext::AreTypesSame(type->GetASTContext(), type->GetOpaqueQualType(), var->GetType()->GetOpaqueClangQualType()))
Sean Callanan336a0002010-07-17 00:43:37 +0000780 return NULL;
781 }
782 else
783 {
784 if (log)
785 log->PutCString("Skipping a candidate variable because of different AST contexts");
786 return NULL;
787 }
788
789 return var.get();
790 }
791
792 return NULL;
793}
Sean Callanancc074622010-09-14 21:59:34 +0000794#endif
795
796Variable *
797ClangExpressionDeclMap::FindVariableInScope(StackFrame &frame,
798 const char *name,
799 TypeFromUser *type)
800{
801 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
802
803 ConstString name_cs(name);
804
805 VariableList *var_list = frame.GetVariableList(true);
806
807 lldb::VariableSP var = var_list->FindVariable(name_cs);
808
809 if (!var)
810 return NULL;
811
812 if (!type)
813 return var.get();
814
815 if (type->GetASTContext() == var->GetType()->GetClangAST())
816 {
817 if (!ClangASTContext::AreTypesSame(type->GetASTContext(), type->GetOpaqueQualType(), var->GetType()->GetOpaqueClangQualType()))
818 return NULL;
819 }
820 else
821 {
822 if (log)
823 log->PutCString("Skipping a candidate variable because of different AST contexts");
824 return NULL;
825 }
826
827 return var.get();
828
829 return NULL;
830}
Sean Callanan336a0002010-07-17 00:43:37 +0000831
Chris Lattner24943d22010-06-08 16:52:24 +0000832// Interface for ClangASTSource
833void
834ClangExpressionDeclMap::GetDecls(NameSearchContext &context,
835 const char *name)
836{
Sean Callanan6184dfe2010-06-23 00:47:48 +0000837 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000838
Sean Callanan810f22d2010-07-16 00:09:46 +0000839 if (log)
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000840 log->Printf("Hunting for a definition for %s", name);
Chris Lattner24943d22010-06-08 16:52:24 +0000841
842 // Back out in all cases where we're not fully initialized
843 if (!m_exe_ctx || !m_exe_ctx->frame || !m_sym_ctx)
844 return;
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000845
846 ConstString name_cs(name);
Sean Callanancc074622010-09-14 21:59:34 +0000847
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000848 if (!strcmp(name, "___clang_class"))
849 {
850 // Clang is looking for the type of "this"
851
852 VariableList *vars = m_exe_ctx->frame->GetVariableList(false);
853
854 if (!vars)
855 return;
856
857 lldb::VariableSP this_var = vars->FindVariable(ConstString("this"));
858
859 if (!this_var)
860 return;
861
862 Type *this_type = this_var->GetType();
863
864 if (!this_type)
865 return;
866
867 TypeFromUser this_user_type(this_type->GetOpaqueClangQualType(),
868 this_type->GetClangAST());
869
870 m_object_pointer_type = this_user_type;
871
872 void *pointer_target_type;
873
874 if (!ClangASTContext::IsPointerType(this_user_type.GetOpaqueQualType(),
875 &pointer_target_type))
876 return;
877
878 TypeFromUser class_user_type(pointer_target_type,
879 this_type->GetClangAST());
880
881 AddOneType(context, class_user_type, true);
882
883 return;
884 }
885
Sean Callanan0fc73582010-07-27 00:55:47 +0000886 SymbolContextList sym_ctxs;
Chris Lattner24943d22010-06-08 16:52:24 +0000887
Sean Callanan0fc73582010-07-27 00:55:47 +0000888 m_sym_ctx->FindFunctionsByName(name_cs, false, sym_ctxs);
Sean Callanan8f0dc342010-06-22 23:46:24 +0000889
Sean Callanan92aa6662010-09-07 21:49:41 +0000890 bool found_generic = false;
891 bool found_specific = false;
892
Sean Callanan0fc73582010-07-27 00:55:47 +0000893 for (uint32_t index = 0, num_indices = sym_ctxs.GetSize();
894 index < num_indices;
895 ++index)
896 {
897 SymbolContext sym_ctx;
898 sym_ctxs.GetContextAtIndex(index, sym_ctx);
899
900 if (sym_ctx.function)
Sean Callanan92aa6662010-09-07 21:49:41 +0000901 {
902 // TODO only do this if it's a C function; C++ functions may be
903 // overloaded
904 if (!found_specific)
905 AddOneFunction(context, sym_ctx.function, NULL);
906 found_specific = true;
907 }
Sean Callanan0fc73582010-07-27 00:55:47 +0000908 else if(sym_ctx.symbol)
Sean Callanan92aa6662010-09-07 21:49:41 +0000909 {
910 if (!found_generic && !found_specific)
911 {
912 AddOneFunction(context, NULL, sym_ctx.symbol);
913 found_generic = true;
914 }
915 }
Sean Callanan0fc73582010-07-27 00:55:47 +0000916 }
917
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000918 Variable *var = FindVariableInScope(*m_exe_ctx->frame, name);
Sean Callanan336a0002010-07-17 00:43:37 +0000919
920 if (var)
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000921 AddOneVariable(context, var);
Sean Callanan93a4b1a2010-08-04 01:02:13 +0000922
Sean Callanana6223432010-08-20 01:02:30 +0000923 ClangExpressionVariable *pvar(m_persistent_vars->GetVariable(name));
Sean Callanana48fe162010-08-11 03:57:18 +0000924
925 if (pvar)
926 AddOneVariable(context, pvar);
927
Sean Callanan93a4b1a2010-08-04 01:02:13 +0000928 /* Commented out pending resolution of a loop when the TagType is imported
929 lldb::TypeSP type = m_sym_ctx->FindTypeByName(name_cs);
930
931 if (type.get())
932 AddOneType(context, type.get());
933 */
Sean Callanan336a0002010-07-17 00:43:37 +0000934}
935
936Value *
937ClangExpressionDeclMap::GetVariableValue(ExecutionContext &exe_ctx,
938 Variable *var,
Sean Callananf328c9f2010-07-20 23:31:16 +0000939 clang::ASTContext *parser_ast_context,
940 TypeFromUser *user_type,
941 TypeFromParser *parser_type)
Chris Lattner24943d22010-06-08 16:52:24 +0000942{
Sean Callanan6184dfe2010-06-23 00:47:48 +0000943 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
944
Chris Lattner24943d22010-06-08 16:52:24 +0000945 Type *var_type = var->GetType();
946
947 if (!var_type)
948 {
Sean Callanan810f22d2010-07-16 00:09:46 +0000949 if (log)
950 log->PutCString("Skipped a definition because it has no type");
Sean Callanan336a0002010-07-17 00:43:37 +0000951 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000952 }
953
954 void *var_opaque_type = var_type->GetOpaqueClangQualType();
955
956 if (!var_opaque_type)
957 {
Sean Callanan810f22d2010-07-16 00:09:46 +0000958 if (log)
959 log->PutCString("Skipped a definition because it has no Clang type");
Sean Callanan336a0002010-07-17 00:43:37 +0000960 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000961 }
962
Chris Lattner24943d22010-06-08 16:52:24 +0000963 TypeList *type_list = var_type->GetTypeList();
964
965 if (!type_list)
966 {
Sean Callanan810f22d2010-07-16 00:09:46 +0000967 if (log)
968 log->PutCString("Skipped a definition because the type has no associated type list");
Sean Callanan336a0002010-07-17 00:43:37 +0000969 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000970 }
971
972 clang::ASTContext *exe_ast_ctx = type_list->GetClangASTContext().getASTContext();
973
974 if (!exe_ast_ctx)
975 {
Sean Callanan810f22d2010-07-16 00:09:46 +0000976 if (log)
977 log->PutCString("There is no AST context for the current execution context");
Sean Callanan336a0002010-07-17 00:43:37 +0000978 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000979 }
980
Sean Callanan336a0002010-07-17 00:43:37 +0000981 DWARFExpression &var_location_expr = var->LocationExpression();
982
Chris Lattner24943d22010-06-08 16:52:24 +0000983 std::auto_ptr<Value> var_location(new Value);
984
Greg Clayton178710c2010-09-14 02:20:48 +0000985 lldb::addr_t loclist_base_load_addr = LLDB_INVALID_ADDRESS;
986
987 if (var_location_expr.IsLocationList())
988 {
989 SymbolContext var_sc;
990 var->CalculateSymbolContext (&var_sc);
Greg Claytoneea26402010-09-14 23:36:40 +0000991 loclist_base_load_addr = var_sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (exe_ctx.target);
Greg Clayton178710c2010-09-14 02:20:48 +0000992 }
Chris Lattner24943d22010-06-08 16:52:24 +0000993 Error err;
994
Greg Clayton178710c2010-09-14 02:20:48 +0000995 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 +0000996 {
Sean Callanan810f22d2010-07-16 00:09:46 +0000997 if (log)
998 log->Printf("Error evaluating location: %s", err.AsCString());
Sean Callanan336a0002010-07-17 00:43:37 +0000999 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001000 }
1001
Sean Callanan810f22d2010-07-16 00:09:46 +00001002 clang::ASTContext *var_ast_context = type_list->GetClangASTContext().getASTContext();
1003
Sean Callanan336a0002010-07-17 00:43:37 +00001004 void *type_to_use;
1005
Sean Callananf328c9f2010-07-20 23:31:16 +00001006 if (parser_ast_context)
1007 {
1008 type_to_use = ClangASTContext::CopyType(parser_ast_context, var_ast_context, var_opaque_type);
1009
1010 if (parser_type)
1011 *parser_type = TypeFromParser(type_to_use, parser_ast_context);
1012 }
Sean Callanan336a0002010-07-17 00:43:37 +00001013 else
1014 type_to_use = var_opaque_type;
Chris Lattner24943d22010-06-08 16:52:24 +00001015
1016 if (var_location.get()->GetContextType() == Value::eContextTypeInvalid)
Sean Callanan336a0002010-07-17 00:43:37 +00001017 var_location.get()->SetContext(Value::eContextTypeOpaqueClangQualType, type_to_use);
Chris Lattner24943d22010-06-08 16:52:24 +00001018
1019 if (var_location.get()->GetValueType() == Value::eValueTypeFileAddress)
1020 {
1021 SymbolContext var_sc;
1022 var->CalculateSymbolContext(&var_sc);
Sean Callanan336a0002010-07-17 00:43:37 +00001023
Chris Lattner24943d22010-06-08 16:52:24 +00001024 if (!var_sc.module_sp)
Sean Callanan336a0002010-07-17 00:43:37 +00001025 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001026
1027 ObjectFile *object_file = var_sc.module_sp->GetObjectFile();
1028
1029 if (!object_file)
Sean Callanan336a0002010-07-17 00:43:37 +00001030 return NULL;
1031
Chris Lattner24943d22010-06-08 16:52:24 +00001032 Address so_addr(var_location->GetScalar().ULongLong(), object_file->GetSectionList());
1033
Greg Claytoneea26402010-09-14 23:36:40 +00001034 lldb::addr_t load_addr = so_addr.GetLoadAddress(m_exe_ctx->target);
Chris Lattner24943d22010-06-08 16:52:24 +00001035
1036 var_location->GetScalar() = load_addr;
1037 var_location->SetValueType(Value::eValueTypeLoadAddress);
1038 }
1039
Sean Callananf328c9f2010-07-20 23:31:16 +00001040 if (user_type)
1041 *user_type = TypeFromUser(var_opaque_type, var_ast_context);
Sean Callanan336a0002010-07-17 00:43:37 +00001042
1043 return var_location.release();
1044}
1045
1046void
1047ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001048 Variable* var)
Sean Callanan336a0002010-07-17 00:43:37 +00001049{
1050 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
1051
Sean Callananf328c9f2010-07-20 23:31:16 +00001052 TypeFromUser ut;
1053 TypeFromParser pt;
Sean Callanan336a0002010-07-17 00:43:37 +00001054
1055 Value *var_location = GetVariableValue(*m_exe_ctx,
1056 var,
1057 context.GetASTContext(),
Sean Callananf328c9f2010-07-20 23:31:16 +00001058 &ut,
1059 &pt);
Sean Callanan336a0002010-07-17 00:43:37 +00001060
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001061 NamedDecl *var_decl = context.AddVarDecl(pt.GetOpaqueQualType());
Chris Lattner24943d22010-06-08 16:52:24 +00001062
Sean Callanan8c127202010-08-23 23:09:38 +00001063 ClangExpressionVariable &entity(m_found_entities.VariableAtIndex(m_found_entities.CreateVariable()));
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001064 entity.m_name = context.Name.getAsString();
Sean Callanan8c127202010-08-23 23:09:38 +00001065 entity.m_user_type = ut;
Chris Lattner24943d22010-06-08 16:52:24 +00001066
Sean Callanan8c127202010-08-23 23:09:38 +00001067 entity.EnableParserVars();
1068 entity.m_parser_vars->m_parser_type = pt;
1069 entity.m_parser_vars->m_named_decl = var_decl;
1070 entity.m_parser_vars->m_llvm_value = NULL;
1071 entity.m_parser_vars->m_lldb_value = var_location;
Chris Lattner24943d22010-06-08 16:52:24 +00001072
Sean Callanan810f22d2010-07-16 00:09:46 +00001073 if (log)
Sean Callananf5857a02010-07-31 01:32:05 +00001074 log->Printf("Found variable %s, returned (NamedDecl)%p", context.Name.getAsString().c_str(), var_decl);
Sean Callanan8f0dc342010-06-22 23:46:24 +00001075}
1076
1077void
Sean Callanana48fe162010-08-11 03:57:18 +00001078ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
Sean Callanana6223432010-08-20 01:02:30 +00001079 ClangExpressionVariable *pvar)
Sean Callanana48fe162010-08-11 03:57:18 +00001080{
Sean Callanan45690fe2010-08-30 22:17:16 +00001081 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
1082
Sean Callanana6223432010-08-20 01:02:30 +00001083 TypeFromUser user_type = pvar->m_user_type;
Sean Callanana48fe162010-08-11 03:57:18 +00001084
1085 TypeFromParser parser_type(ClangASTContext::CopyType(context.GetASTContext(),
1086 user_type.GetASTContext(),
1087 user_type.GetOpaqueQualType()),
1088 context.GetASTContext());
1089
Sean Callanan8c127202010-08-23 23:09:38 +00001090 NamedDecl *var_decl = context.AddVarDecl(parser_type.GetOpaqueQualType());
1091
1092 pvar->EnableParserVars();
1093 pvar->m_parser_vars->m_parser_type = parser_type;
1094 pvar->m_parser_vars->m_named_decl = var_decl;
1095 pvar->m_parser_vars->m_llvm_value = NULL;
1096 pvar->m_parser_vars->m_lldb_value = NULL;
Sean Callanan45690fe2010-08-30 22:17:16 +00001097
1098 if (log)
1099 log->Printf("Added pvar %s, returned (NamedDecl)%p", pvar->m_name.c_str(), var_decl);
Sean Callanana48fe162010-08-11 03:57:18 +00001100}
1101
1102void
Sean Callanan8f0dc342010-06-22 23:46:24 +00001103ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
Sean Callanan0fc73582010-07-27 00:55:47 +00001104 Function* fun,
1105 Symbol* symbol)
Sean Callanan8f0dc342010-06-22 23:46:24 +00001106{
Sean Callanan6184dfe2010-06-23 00:47:48 +00001107 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
Sean Callanan8f0dc342010-06-22 23:46:24 +00001108
Sean Callanan0fc73582010-07-27 00:55:47 +00001109 NamedDecl *fun_decl;
Sean Callanan8f0dc342010-06-22 23:46:24 +00001110 std::auto_ptr<Value> fun_location(new Value);
Sean Callanan0fc73582010-07-27 00:55:47 +00001111 const Address *fun_address;
Sean Callanan8f0dc342010-06-22 23:46:24 +00001112
Sean Callanan0fc73582010-07-27 00:55:47 +00001113 // only valid for Functions, not for Symbols
1114 void *fun_opaque_type = NULL;
1115 clang::ASTContext *fun_ast_context = NULL;
1116
1117 if (fun)
1118 {
Sean Callanan55261a12010-09-08 22:38:54 +00001119#define BROKEN_OVERLOADING
1120 // Awaiting a fix on the Clang side
1121#ifndef BROKEN_OVERLOADING
Sean Callanan0fc73582010-07-27 00:55:47 +00001122 Type *fun_type = fun->GetType();
1123
1124 if (!fun_type)
1125 {
1126 if (log)
1127 log->PutCString("Skipped a function because it has no type");
1128 return;
1129 }
1130
1131 fun_opaque_type = fun_type->GetOpaqueClangQualType();
1132
1133 if (!fun_opaque_type)
1134 {
1135 if (log)
1136 log->PutCString("Skipped a function because it has no Clang type");
1137 return;
1138 }
1139
1140 fun_address = &fun->GetAddressRange().GetBaseAddress();
1141
1142 TypeList *type_list = fun_type->GetTypeList();
1143 fun_ast_context = type_list->GetClangASTContext().getASTContext();
1144 void *copied_type = ClangASTContext::CopyType(context.GetASTContext(), fun_ast_context, fun_opaque_type);
1145
1146 fun_decl = context.AddFunDecl(copied_type);
Sean Callanan55261a12010-09-08 22:38:54 +00001147#else
1148 fun_address = &fun->GetAddressRange().GetBaseAddress();
1149
1150 fun_decl = context.AddGenericFunDecl();
1151#endif
Sean Callanan0fc73582010-07-27 00:55:47 +00001152 }
1153 else if (symbol)
1154 {
1155 fun_address = &symbol->GetAddressRangeRef().GetBaseAddress();
1156
1157 fun_decl = context.AddGenericFunDecl();
1158 }
1159 else
1160 {
1161 if (log)
1162 log->PutCString("AddOneFunction called with no function and no symbol");
1163 return;
1164 }
1165
Greg Claytoneea26402010-09-14 23:36:40 +00001166 lldb::addr_t load_addr = fun_address->GetLoadAddress(m_exe_ctx->target);
Sean Callanan8f0dc342010-06-22 23:46:24 +00001167 fun_location->SetValueType(Value::eValueTypeLoadAddress);
1168 fun_location->GetScalar() = load_addr;
1169
Sean Callanan8c127202010-08-23 23:09:38 +00001170 ClangExpressionVariable &entity(m_found_entities.VariableAtIndex(m_found_entities.CreateVariable()));
1171 entity.m_name = context.Name.getAsString();
1172 entity.m_user_type = TypeFromUser(fun_opaque_type, fun_ast_context);;
Sean Callanan8f0dc342010-06-22 23:46:24 +00001173
Sean Callanan8c127202010-08-23 23:09:38 +00001174 entity.EnableParserVars();
1175 entity.m_parser_vars->m_named_decl = fun_decl;
1176 entity.m_parser_vars->m_llvm_value = NULL;
1177 entity.m_parser_vars->m_lldb_value = fun_location.release();
1178
Sean Callanan810f22d2010-07-16 00:09:46 +00001179 if (log)
Sean Callanan92aa6662010-09-07 21:49:41 +00001180 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 +00001181}
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001182
1183void
1184ClangExpressionDeclMap::AddOneType(NameSearchContext &context,
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001185 TypeFromUser &ut,
1186 bool add_method)
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001187{
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001188 clang::ASTContext *parser_ast_context = context.GetASTContext();
1189 clang::ASTContext *user_ast_context = ut.GetASTContext();
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001190
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001191 void *copied_type = ClangASTContext::CopyType(parser_ast_context, user_ast_context, ut.GetOpaqueQualType());
1192
1193 TypeFromParser parser_type(copied_type, parser_ast_context);
1194
1195 if (add_method && ClangASTContext::IsAggregateType(copied_type))
1196 {
1197 void *args[1];
1198
1199 args[0] = ClangASTContext::GetVoidPtrType(parser_ast_context, false);
1200
1201 void *method_type = ClangASTContext::CreateFunctionType (parser_ast_context,
1202 ClangASTContext::GetBuiltInType_void(parser_ast_context),
1203 args,
1204 1,
1205 false,
1206 ClangASTContext::GetTypeQualifiers(copied_type));
1207
1208 ClangASTContext::AddMethodToCXXRecordType(parser_ast_context,
1209 copied_type,
1210 "___clang_expr",
1211 method_type);
1212 }
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001213
1214 context.AddTypeDecl(copied_type);
1215}