blob: fb10605a36fb125ea9b4db4f4dd23d5b04b2845d [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()
54{
55 uint32_t num_tuples = m_tuples.size ();
56 uint32_t tuple_index;
57
58 for (tuple_index = 0; tuple_index < num_tuples; ++tuple_index)
59 delete m_tuples[tuple_index].m_value;
60
61 if (m_sym_ctx)
62 delete m_sym_ctx;
63}
64
65bool
66ClangExpressionDeclMap::GetIndexForDecl (uint32_t &index,
67 const clang::Decl *decl)
68{
69 uint32_t num_tuples = m_tuples.size ();
70 uint32_t tuple_index;
71
72 for (tuple_index = 0; tuple_index < num_tuples; ++tuple_index)
73 {
74 if (m_tuples[tuple_index].m_decl == decl)
75 {
76 index = tuple_index;
77 return true;
78 }
79 }
80
81 return false;
82}
83
Sean Callanan8bce6652010-07-13 21:41:46 +000084// Interface for IRForTarget
85
Sean Callanan82b74c82010-08-12 01:56:52 +000086void
87ClangExpressionDeclMap::GetPersistentResultName (std::string &name)
88{
89 m_persistent_vars->GetNextResultName(m_result_name);
90
91 name = m_result_name;
92}
93
Sean Callanan8bce6652010-07-13 21:41:46 +000094bool
Sean Callanan82b74c82010-08-12 01:56:52 +000095ClangExpressionDeclMap::AddPersistentVariable (const char *name, TypeFromParser parser_type)
Sean Callanana48fe162010-08-11 03:57:18 +000096{
97 clang::ASTContext *context(m_exe_ctx->target->GetScratchClangASTContext()->getASTContext());
98
Sean Callanana48fe162010-08-11 03:57:18 +000099 TypeFromUser user_type(ClangASTContext::CopyType(context,
Sean Callanan82b74c82010-08-12 01:56:52 +0000100 parser_type.GetASTContext(),
101 parser_type.GetOpaqueQualType()),
Sean Callanana48fe162010-08-11 03:57:18 +0000102 context);
103
Sean Callanan82b74c82010-08-12 01:56:52 +0000104 ConstString const_name(name);
Sean Callanana48fe162010-08-11 03:57:18 +0000105
106 ClangPersistentVariable *pvar = m_persistent_vars->CreateVariable(const_name, user_type);
107
108 if (!pvar)
109 return false;
110
111 return true;
112}
113
114bool
Sean Callanan8bce6652010-07-13 21:41:46 +0000115ClangExpressionDeclMap::AddValueToStruct (llvm::Value *value,
116 const clang::NamedDecl *decl,
Sean Callanan810f22d2010-07-16 00:09:46 +0000117 std::string &name,
Sean Callananf328c9f2010-07-20 23:31:16 +0000118 void *parser_type,
119 clang::ASTContext *parser_ast_context,
Sean Callanan8bce6652010-07-13 21:41:46 +0000120 size_t size,
121 off_t alignment)
122{
123 m_struct_laid_out = false;
124
125 StructMemberIterator iter;
126
127 for (iter = m_members.begin();
128 iter != m_members.end();
129 ++iter)
130 {
131 if (iter->m_decl == decl)
132 return true;
133 }
134
135 StructMember member;
136
Sean Callananf328c9f2010-07-20 23:31:16 +0000137 member.m_value = value;
138 member.m_decl = decl;
139 member.m_name = name;
140 member.m_parser_type = TypeFromParser(parser_type, parser_ast_context);
141 member.m_offset = 0;
142 member.m_size = size;
143 member.m_alignment = alignment;
Sean Callanan8bce6652010-07-13 21:41:46 +0000144
145 m_members.push_back(member);
146
147 return true;
148}
149
150bool
151ClangExpressionDeclMap::DoStructLayout ()
152{
153 if (m_struct_laid_out)
154 return true;
155
156 StructMemberIterator iter;
157
158 off_t cursor = 0;
159
160 m_struct_alignment = 0;
161 m_struct_size = 0;
162
163 for (iter = m_members.begin();
164 iter != m_members.end();
165 ++iter)
166 {
167 if (iter == m_members.begin())
168 m_struct_alignment = iter->m_alignment;
169
170 if (cursor % iter->m_alignment)
171 cursor += (iter->m_alignment - (cursor % iter->m_alignment));
172
173 iter->m_offset = cursor;
174 cursor += iter->m_size;
175 }
176
177 m_struct_size = cursor;
178
179 m_struct_laid_out = true;
180 return true;
181}
182
183bool ClangExpressionDeclMap::GetStructInfo (uint32_t &num_elements,
184 size_t &size,
185 off_t &alignment)
186{
187 if (!m_struct_laid_out)
188 return false;
189
190 num_elements = m_members.size();
191 size = m_struct_size;
192 alignment = m_struct_alignment;
193
194 return true;
195}
196
197bool
198ClangExpressionDeclMap::GetStructElement (const clang::NamedDecl *&decl,
199 llvm::Value *&value,
200 off_t &offset,
201 uint32_t index)
202{
203 if (!m_struct_laid_out)
204 return false;
205
206 if (index >= m_members.size())
207 return false;
208
209 decl = m_members[index].m_decl;
210 value = m_members[index].m_value;
211 offset = m_members[index].m_offset;
212
213 return true;
214}
215
Sean Callanan02fbafa2010-07-27 21:39:39 +0000216bool
217ClangExpressionDeclMap::GetFunctionInfo (const clang::NamedDecl *decl,
218 llvm::Value**& value,
219 uint64_t &ptr)
Sean Callananba992c52010-07-27 02:07:53 +0000220{
221 TupleIterator iter;
222
223 for (iter = m_tuples.begin();
224 iter != m_tuples.end();
225 ++iter)
226 {
227 if (decl == iter->m_decl)
228 {
Sean Callanan02fbafa2010-07-27 21:39:39 +0000229 value = &iter->m_llvm_value;
230 ptr = iter->m_value->GetScalar().ULongLong();
231 return true;
Sean Callananba992c52010-07-27 02:07:53 +0000232 }
233 }
234
Sean Callanan02fbafa2010-07-27 21:39:39 +0000235 return false;
Sean Callananba992c52010-07-27 02:07:53 +0000236}
237
Sean Callananf5857a02010-07-31 01:32:05 +0000238bool
239ClangExpressionDeclMap::GetFunctionAddress (const char *name,
240 uint64_t &ptr)
241{
242 // Back out in all cases where we're not fully initialized
243 if (!m_exe_ctx || !m_exe_ctx->frame || !m_sym_ctx)
244 return false;
245
246 ConstString name_cs(name);
247 SymbolContextList sym_ctxs;
248
249 m_sym_ctx->FindFunctionsByName(name_cs, false, sym_ctxs);
250
251 if (!sym_ctxs.GetSize())
252 return false;
253
254 SymbolContext sym_ctx;
255 sym_ctxs.GetContextAtIndex(0, sym_ctx);
256
257 const Address *fun_address;
258
259 if (sym_ctx.function)
260 fun_address = &sym_ctx.function->GetAddressRange().GetBaseAddress();
261 else if (sym_ctx.symbol)
262 fun_address = &sym_ctx.symbol->GetAddressRangeRef().GetBaseAddress();
263 else
264 return false;
265
266 ptr = fun_address->GetLoadAddress(m_exe_ctx->process);
267
268 return true;
269}
270
Chris Lattner24943d22010-06-08 16:52:24 +0000271// Interface for DwarfExpression
Sean Callananf328c9f2010-07-20 23:31:16 +0000272lldb_private::Value
Chris Lattner24943d22010-06-08 16:52:24 +0000273*ClangExpressionDeclMap::GetValueForIndex (uint32_t index)
274{
275 if (index >= m_tuples.size ())
276 return NULL;
277
278 return m_tuples[index].m_value;
279}
280
Sean Callanan810f22d2010-07-16 00:09:46 +0000281// Interface for CommandObjectExpression
Sean Callananf328c9f2010-07-20 23:31:16 +0000282
283bool
284ClangExpressionDeclMap::Materialize (ExecutionContext *exe_ctx,
285 lldb::addr_t &struct_address,
286 Error &err)
287{
288 bool result = DoMaterialize(false, exe_ctx, NULL, err);
289
290 if (result)
291 struct_address = m_materialized_location;
292
293 return result;
294}
295
296bool
297ClangExpressionDeclMap::Dematerialize (ExecutionContext *exe_ctx,
Sean Callanan82b74c82010-08-12 01:56:52 +0000298 ClangPersistentVariable *&result,
Sean Callananf328c9f2010-07-20 23:31:16 +0000299 Error &err)
300{
Sean Callanan82b74c82010-08-12 01:56:52 +0000301 return DoMaterialize(true, exe_ctx, &result, err);
Sean Callananf328c9f2010-07-20 23:31:16 +0000302}
303
Sean Callanan32824aa2010-07-23 22:19:18 +0000304bool
305ClangExpressionDeclMap::DumpMaterializedStruct(ExecutionContext *exe_ctx,
306 Stream &s,
307 Error &err)
308{
309 if (!m_struct_laid_out)
310 {
311 err.SetErrorString("Structure hasn't been laid out yet");
312 return false;
313 }
314
315 if (!exe_ctx)
316 {
317 err.SetErrorString("Received null execution context");
318 return false;
319 }
320
321
322 if (!exe_ctx->process)
323 {
324 err.SetErrorString("Couldn't find the process");
325 return false;
326 }
327
328 if (!exe_ctx->target)
329 {
330 err.SetErrorString("Couldn't find the target");
331 return false;
332 }
333
334 lldb::DataBufferSP data(new DataBufferHeap(m_struct_size, 0));
335
336 Error error;
337 if (exe_ctx->process->ReadMemory (m_materialized_location, data->GetBytes(), data->GetByteSize(), error) != data->GetByteSize())
338 {
339 err.SetErrorStringWithFormat ("Couldn't read struct from the target: %s", error.AsCString());
340 return false;
341 }
342
343 DataExtractor extractor(data, exe_ctx->process->GetByteOrder(), exe_ctx->target->GetArchitecture().GetAddressByteSize());
344
345 StructMemberIterator iter;
346
347 for (iter = m_members.begin();
348 iter != m_members.end();
349 ++iter)
350 {
351 s.Printf("[%s]\n", iter->m_name.c_str());
352
353 extractor.Dump(&s, // stream
354 iter->m_offset, // offset
355 lldb::eFormatBytesWithASCII, // format
356 1, // byte size of individual entries
357 iter->m_size, // number of entries
358 16, // entries per line
359 m_materialized_location + iter->m_offset, // address to print
360 0, // bit size (bitfields only; 0 means ignore)
361 0); // bit alignment (bitfields only; 0 means ignore)
362
363 s.PutChar('\n');
364 }
365
366 return true;
367}
368
Sean Callananf328c9f2010-07-20 23:31:16 +0000369bool
370ClangExpressionDeclMap::DoMaterialize (bool dematerialize,
371 ExecutionContext *exe_ctx,
Sean Callanan82b74c82010-08-12 01:56:52 +0000372 ClangPersistentVariable **result,
Sean Callananf328c9f2010-07-20 23:31:16 +0000373 Error &err)
Sean Callanan810f22d2010-07-16 00:09:46 +0000374{
Sean Callanan336a0002010-07-17 00:43:37 +0000375 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
Sean Callanan82b74c82010-08-12 01:56:52 +0000376
Sean Callanan810f22d2010-07-16 00:09:46 +0000377 if (!m_struct_laid_out)
378 {
379 err.SetErrorString("Structure hasn't been laid out yet");
380 return LLDB_INVALID_ADDRESS;
381 }
382
Sean Callanan810f22d2010-07-16 00:09:46 +0000383 if (!exe_ctx)
384 {
385 err.SetErrorString("Received null execution context");
386 return LLDB_INVALID_ADDRESS;
387 }
388
Sean Callanan45839272010-07-24 01:37:44 +0000389 if (!exe_ctx->frame)
390 {
391 err.SetErrorString("Received null execution frame");
392 return LLDB_INVALID_ADDRESS;
393 }
394
Sean Callanan810f22d2010-07-16 00:09:46 +0000395 const SymbolContext &sym_ctx(exe_ctx->frame->GetSymbolContext(lldb::eSymbolContextEverything));
396
Sean Callananf328c9f2010-07-20 23:31:16 +0000397 if (!dematerialize)
Sean Callanan810f22d2010-07-16 00:09:46 +0000398 {
Sean Callananf328c9f2010-07-20 23:31:16 +0000399 if (m_materialized_location)
400 {
401 exe_ctx->process->DeallocateMemory(m_materialized_location);
402 m_materialized_location = 0;
403 }
404
405 lldb::addr_t mem = exe_ctx->process->AllocateMemory(m_struct_alignment + m_struct_size,
406 lldb::ePermissionsReadable | lldb::ePermissionsWritable,
407 err);
408
409 if (mem == LLDB_INVALID_ADDRESS)
410 return false;
411
412 m_allocated_area = mem;
Sean Callanan810f22d2010-07-16 00:09:46 +0000413 }
414
Sean Callananf328c9f2010-07-20 23:31:16 +0000415 m_materialized_location = m_allocated_area;
416
417 if (m_materialized_location % m_struct_alignment)
418 {
419 m_materialized_location += (m_struct_alignment - (m_materialized_location % m_struct_alignment));
420 }
421
422 StructMemberIterator iter;
423
Sean Callanan810f22d2010-07-16 00:09:46 +0000424 for (iter = m_members.begin();
425 iter != m_members.end();
426 ++iter)
427 {
428 uint32_t tuple_index;
429
Sean Callanan336a0002010-07-17 00:43:37 +0000430 if (!GetIndexForDecl(tuple_index, iter->m_decl))
431 {
Sean Callanan82b74c82010-08-12 01:56:52 +0000432 if (iter->m_name.find("___clang_expr_result") != std::string::npos)
433 {
434 if (dematerialize)
435 {
436 // Here we pick up the odd anomaly produced by
437 // IRForTarget::createResultVariable (and described in a comment
438 // there).
439 //
440 // We rename the variable to the name of the result PVar and
441 // incidentally drop the address of the PVar into *result
442 // (if it's non-NULL, of course). We then let this case fall
443 // through to the persistent variable handler.
444
445 if (log)
446 log->PutCString("Found result member in the struct");
447
448 iter->m_name = m_result_name;
449
450 if (result)
451 {
452 if (log)
453 log->PutCString("Returning result PVar");
454
455 *result = m_persistent_vars->GetVariable(ConstString(m_result_name.c_str()));
456
457 if (!*result)
458 {
459 err.SetErrorStringWithFormat("Couldn't find persistent variable for result %s", m_result_name.c_str());
460 }
461 }
462 else
463 {
464 if (log)
465 log->PutCString("Didn't return result PVar; pointer was NULL");
466 }
467 }
468 else
469 {
470 // The result variable doesn't need to be materialized, ever.
471 continue;
472 }
473 }
474
Sean Callanana48fe162010-08-11 03:57:18 +0000475 if (iter->m_name[0] == '$')
476 {
477 if (!DoMaterializeOnePersistentVariable(dematerialize, *exe_ctx, iter->m_name.c_str(), m_materialized_location + iter->m_offset, err))
478 return false;
479 }
Sean Callanana48fe162010-08-11 03:57:18 +0000480 else
Sean Callanan336a0002010-07-17 00:43:37 +0000481 {
482 err.SetErrorStringWithFormat("Unexpected variable %s", iter->m_name.c_str());
483 return false;
484 }
485
Sean Callanan810f22d2010-07-16 00:09:46 +0000486 continue;
Sean Callanan336a0002010-07-17 00:43:37 +0000487 }
Sean Callanan810f22d2010-07-16 00:09:46 +0000488
489 Tuple &tuple(m_tuples[tuple_index]);
490
Sean Callananf328c9f2010-07-20 23:31:16 +0000491 if (!DoMaterializeOneVariable(dematerialize, *exe_ctx, sym_ctx, iter->m_name.c_str(), tuple.m_user_type, m_materialized_location + iter->m_offset, err))
Sean Callanan336a0002010-07-17 00:43:37 +0000492 return false;
Sean Callanan810f22d2010-07-16 00:09:46 +0000493 }
494
Sean Callananf328c9f2010-07-20 23:31:16 +0000495 return true;
496}
497
Sean Callanana48fe162010-08-11 03:57:18 +0000498bool
499ClangExpressionDeclMap::DoMaterializeOnePersistentVariable(bool dematerialize,
500 ExecutionContext &exe_ctx,
501 const char *name,
502 lldb::addr_t addr,
503 Error &err)
504{
505 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
506
507 if (log)
508 log->Printf("Found persistent variable %s", name);
509
510 ClangPersistentVariable *pvar(m_persistent_vars->GetVariable(ConstString(name)));
511
512 if (!pvar)
513 {
514 err.SetErrorStringWithFormat("Undefined persistent variable %s", name);
515 return LLDB_INVALID_ADDRESS;
516 }
517
518 size_t pvar_size = pvar->Size();
519 uint8_t *pvar_data = pvar->Data();
520 Error error;
521
522 if (dematerialize)
523 {
524 if (exe_ctx.process->ReadMemory (addr, pvar_data, pvar_size, error) != pvar_size)
525 {
526 err.SetErrorStringWithFormat ("Couldn't read a composite type from the target: %s", error.AsCString());
527 return false;
528 }
529 }
530 else
531 {
532 if (exe_ctx.process->WriteMemory (addr, pvar_data, pvar_size, error) != pvar_size)
533 {
534 err.SetErrorStringWithFormat ("Couldn't write a composite type to the target: %s", error.AsCString());
535 return false;
536 }
537 }
538
539 return true;
540}
541
Sean Callananf328c9f2010-07-20 23:31:16 +0000542bool
543ClangExpressionDeclMap::DoMaterializeOneVariable(bool dematerialize,
544 ExecutionContext &exe_ctx,
545 const SymbolContext &sym_ctx,
546 const char *name,
547 TypeFromUser type,
548 lldb::addr_t addr,
549 Error &err)
550{
551 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
552
553 Variable *var = FindVariableInScope(sym_ctx, name, &type);
554
555 if (!var)
556 {
557 err.SetErrorStringWithFormat("Couldn't find %s with appropriate type", name);
558 return false;
559 }
560
Sean Callanan841026f2010-07-23 00:16:21 +0000561 if (log)
562 log->Printf("%s %s with type %p", (dematerialize ? "Dematerializing" : "Materializing"), name, type.GetOpaqueQualType());
Sean Callananf328c9f2010-07-20 23:31:16 +0000563
564 std::auto_ptr<lldb_private::Value> location_value(GetVariableValue(exe_ctx,
565 var,
566 type.GetASTContext()));
567
568 if (!location_value.get())
569 {
570 err.SetErrorStringWithFormat("Couldn't get value for %s", name);
571 return false;
572 }
573
574 if (location_value->GetValueType() == Value::eValueTypeLoadAddress)
575 {
576 lldb::addr_t value_addr = location_value->GetScalar().ULongLong();
577
Greg Clayton960d6a42010-08-03 00:35:52 +0000578 size_t bit_size = ClangASTType::GetClangTypeBitWidth(type.GetASTContext(), type.GetOpaqueQualType());
Sean Callananf328c9f2010-07-20 23:31:16 +0000579 size_t byte_size = bit_size % 8 ? ((bit_size + 8) / 8) : (bit_size / 8);
580
581 DataBufferHeap data;
582 data.SetByteSize(byte_size);
583
584 lldb::addr_t src_addr;
585 lldb::addr_t dest_addr;
586
587 if (dematerialize)
588 {
589 src_addr = addr;
590 dest_addr = value_addr;
591 }
592 else
593 {
594 src_addr = value_addr;
595 dest_addr = addr;
596 }
597
598 Error error;
599 if (exe_ctx.process->ReadMemory (src_addr, data.GetBytes(), byte_size, error) != byte_size)
600 {
601 err.SetErrorStringWithFormat ("Couldn't read a composite type from the target: %s", error.AsCString());
602 return false;
603 }
604
605 if (exe_ctx.process->WriteMemory (dest_addr, data.GetBytes(), byte_size, error) != byte_size)
606 {
607 err.SetErrorStringWithFormat ("Couldn't write a composite type to the target: %s", error.AsCString());
608 return false;
609 }
610
611 if (log)
612 log->Printf("Copied from 0x%llx to 0x%llx", (uint64_t)src_addr, (uint64_t)addr);
613 }
614 else
615 {
616 StreamString ss;
617
618 location_value->Dump(&ss);
619
620 err.SetErrorStringWithFormat("%s has a value of unhandled type: %s", name, ss.GetString().c_str());
621 }
622
623 return true;
Sean Callanan810f22d2010-07-16 00:09:46 +0000624}
625
Sean Callanan336a0002010-07-17 00:43:37 +0000626Variable*
627ClangExpressionDeclMap::FindVariableInScope(const SymbolContext &sym_ctx,
628 const char *name,
Sean Callananf328c9f2010-07-20 23:31:16 +0000629 TypeFromUser *type)
Sean Callanan810f22d2010-07-16 00:09:46 +0000630{
631 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
632
633 Function *function(m_sym_ctx->function);
634 Block *block(m_sym_ctx->block);
635
636 if (!function || !block)
637 {
638 if (log)
639 log->Printf("function = %p, block = %p", function, block);
Sean Callanan336a0002010-07-17 00:43:37 +0000640 return NULL;
Sean Callanan810f22d2010-07-16 00:09:46 +0000641 }
642
643 BlockList& blocks(function->GetBlocks(true));
644
Sean Callanan336a0002010-07-17 00:43:37 +0000645 ConstString name_cs(name);
646
Sean Callanan810f22d2010-07-16 00:09:46 +0000647 lldb::user_id_t current_block_id;
648
649 for (current_block_id = block->GetID();
650 current_block_id != Block::InvalidID;
651 current_block_id = blocks.GetParent(current_block_id))
652 {
653 Block *current_block(blocks.GetBlockByID(current_block_id));
654
655 lldb::VariableListSP var_list = current_block->GetVariableList(false, true);
656
657 if (!var_list)
658 continue;
659
Sean Callanan336a0002010-07-17 00:43:37 +0000660 lldb::VariableSP var = var_list->FindVariable(name_cs);
Sean Callanan810f22d2010-07-16 00:09:46 +0000661
662 if (!var)
663 continue;
664
665 // var->GetType()->GetClangAST() is the program's AST context and holds
666 // var->GetType()->GetOpaqueClangQualType().
667
668 // type is m_type for one of the struct members, which was added by
669 // AddValueToStruct. That type was extracted from the AST context of
670 // the compiler in IRForTarget. The original for the type was copied
671 // out of the program's AST context by AddOneVariable.
672
Sean Callanan336a0002010-07-17 00:43:37 +0000673 // So that we can compare these two without having to copy back
674 // something we already had in the original AST context, we maintain
675 // m_orig_type and m_ast_context (which are passed into
676 // MaterializeOneVariable by Materialize) for each variable.
677
678 if (!type)
679 return var.get();
Sean Callanan810f22d2010-07-16 00:09:46 +0000680
Sean Callananf328c9f2010-07-20 23:31:16 +0000681 if (type->GetASTContext() == var->GetType()->GetClangAST())
Sean Callanan810f22d2010-07-16 00:09:46 +0000682 {
Sean Callananf5857a02010-07-31 01:32:05 +0000683 if (!ClangASTContext::AreTypesSame(type->GetASTContext(), type->GetOpaqueQualType(), var->GetType()->GetOpaqueClangQualType()))
Sean Callanan810f22d2010-07-16 00:09:46 +0000684 continue;
685 }
686 else
687 {
688 if (log)
689 log->PutCString("Skipping a candidate variable because of different AST contexts");
690 continue;
691 }
692
Sean Callanan336a0002010-07-17 00:43:37 +0000693 return var.get();
694 }
695
696 {
697 CompileUnit *compile_unit = m_sym_ctx->comp_unit;
Sean Callanan810f22d2010-07-16 00:09:46 +0000698
Sean Callanan336a0002010-07-17 00:43:37 +0000699 if (!compile_unit)
700 {
701 if (log)
702 log->Printf("compile_unit = %p", compile_unit);
703 return NULL;
704 }
705
706 lldb::VariableListSP var_list = compile_unit->GetVariableList(true);
707
708 if (!var_list)
709 return NULL;
710
711 lldb::VariableSP var = var_list->FindVariable(name_cs);
712
713 if (!var)
714 return NULL;
715
716 if (!type)
717 return var.get();
718
Sean Callananf328c9f2010-07-20 23:31:16 +0000719 if (type->GetASTContext() == var->GetType()->GetClangAST())
Sean Callanan336a0002010-07-17 00:43:37 +0000720 {
Sean Callanan841026f2010-07-23 00:16:21 +0000721 if (!ClangASTContext::AreTypesSame(type->GetASTContext(), type->GetOpaqueQualType(), var->GetType()->GetOpaqueClangQualType()))
Sean Callanan336a0002010-07-17 00:43:37 +0000722 return NULL;
723 }
724 else
725 {
726 if (log)
727 log->PutCString("Skipping a candidate variable because of different AST contexts");
728 return NULL;
729 }
730
731 return var.get();
732 }
733
734 return NULL;
735}
736
Chris Lattner24943d22010-06-08 16:52:24 +0000737// Interface for ClangASTSource
738void
739ClangExpressionDeclMap::GetDecls(NameSearchContext &context,
740 const char *name)
741{
Sean Callanan6184dfe2010-06-23 00:47:48 +0000742 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
743
Sean Callanan810f22d2010-07-16 00:09:46 +0000744 if (log)
745 log->Printf("Hunting for a definition for %s", name);
Chris Lattner24943d22010-06-08 16:52:24 +0000746
747 // Back out in all cases where we're not fully initialized
748 if (!m_exe_ctx || !m_exe_ctx->frame || !m_sym_ctx)
749 return;
750
751 Function *function = m_sym_ctx->function;
Chris Lattner24943d22010-06-08 16:52:24 +0000752
Sean Callanan336a0002010-07-17 00:43:37 +0000753 if (!function)
Chris Lattner24943d22010-06-08 16:52:24 +0000754 {
Sean Callanan810f22d2010-07-16 00:09:46 +0000755 if (log)
Sean Callanan336a0002010-07-17 00:43:37 +0000756 log->Printf("Can't evaluate an expression when not in a function");
Chris Lattner24943d22010-06-08 16:52:24 +0000757 return;
758 }
759
Chris Lattner24943d22010-06-08 16:52:24 +0000760 ConstString name_cs(name);
Sean Callanan0fc73582010-07-27 00:55:47 +0000761 SymbolContextList sym_ctxs;
Chris Lattner24943d22010-06-08 16:52:24 +0000762
Sean Callanan0fc73582010-07-27 00:55:47 +0000763 m_sym_ctx->FindFunctionsByName(name_cs, false, sym_ctxs);
Sean Callanan8f0dc342010-06-22 23:46:24 +0000764
Sean Callanan0fc73582010-07-27 00:55:47 +0000765 for (uint32_t index = 0, num_indices = sym_ctxs.GetSize();
766 index < num_indices;
767 ++index)
768 {
769 SymbolContext sym_ctx;
770 sym_ctxs.GetContextAtIndex(index, sym_ctx);
771
772 if (sym_ctx.function)
773 AddOneFunction(context, sym_ctx.function, NULL);
774 else if(sym_ctx.symbol)
775 AddOneFunction(context, NULL, sym_ctx.symbol);
776 }
777
Sean Callanan336a0002010-07-17 00:43:37 +0000778 Variable *var = FindVariableInScope(*m_sym_ctx, name);
779
780 if (var)
781 AddOneVariable(context, var);
Sean Callanan93a4b1a2010-08-04 01:02:13 +0000782
Sean Callanana48fe162010-08-11 03:57:18 +0000783 ClangPersistentVariable *pvar(m_persistent_vars->GetVariable(ConstString(name)));
784
785 if (pvar)
786 AddOneVariable(context, pvar);
787
Sean Callanan93a4b1a2010-08-04 01:02:13 +0000788 /* Commented out pending resolution of a loop when the TagType is imported
789 lldb::TypeSP type = m_sym_ctx->FindTypeByName(name_cs);
790
791 if (type.get())
792 AddOneType(context, type.get());
793 */
Sean Callanan336a0002010-07-17 00:43:37 +0000794}
795
796Value *
797ClangExpressionDeclMap::GetVariableValue(ExecutionContext &exe_ctx,
798 Variable *var,
Sean Callananf328c9f2010-07-20 23:31:16 +0000799 clang::ASTContext *parser_ast_context,
800 TypeFromUser *user_type,
801 TypeFromParser *parser_type)
Chris Lattner24943d22010-06-08 16:52:24 +0000802{
Sean Callanan6184dfe2010-06-23 00:47:48 +0000803 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
804
Chris Lattner24943d22010-06-08 16:52:24 +0000805 Type *var_type = var->GetType();
806
807 if (!var_type)
808 {
Sean Callanan810f22d2010-07-16 00:09:46 +0000809 if (log)
810 log->PutCString("Skipped a definition because it has no type");
Sean Callanan336a0002010-07-17 00:43:37 +0000811 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000812 }
813
814 void *var_opaque_type = var_type->GetOpaqueClangQualType();
815
816 if (!var_opaque_type)
817 {
Sean Callanan810f22d2010-07-16 00:09:46 +0000818 if (log)
819 log->PutCString("Skipped a definition because it has no Clang type");
Sean Callanan336a0002010-07-17 00:43:37 +0000820 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000821 }
822
Chris Lattner24943d22010-06-08 16:52:24 +0000823 TypeList *type_list = var_type->GetTypeList();
824
825 if (!type_list)
826 {
Sean Callanan810f22d2010-07-16 00:09:46 +0000827 if (log)
828 log->PutCString("Skipped a definition because the type has no associated type list");
Sean Callanan336a0002010-07-17 00:43:37 +0000829 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000830 }
831
832 clang::ASTContext *exe_ast_ctx = type_list->GetClangASTContext().getASTContext();
833
834 if (!exe_ast_ctx)
835 {
Sean Callanan810f22d2010-07-16 00:09:46 +0000836 if (log)
837 log->PutCString("There is no AST context for the current execution context");
Sean Callanan336a0002010-07-17 00:43:37 +0000838 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000839 }
840
Sean Callanan336a0002010-07-17 00:43:37 +0000841 DWARFExpression &var_location_expr = var->LocationExpression();
842
Chris Lattner24943d22010-06-08 16:52:24 +0000843 std::auto_ptr<Value> var_location(new Value);
844
845 Error err;
846
Sean Callanan336a0002010-07-17 00:43:37 +0000847 if (!var_location_expr.Evaluate(&exe_ctx, exe_ast_ctx, NULL, *var_location.get(), &err))
Chris Lattner24943d22010-06-08 16:52:24 +0000848 {
Sean Callanan810f22d2010-07-16 00:09:46 +0000849 if (log)
850 log->Printf("Error evaluating location: %s", err.AsCString());
Sean Callanan336a0002010-07-17 00:43:37 +0000851 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000852 }
853
Sean Callanan810f22d2010-07-16 00:09:46 +0000854 clang::ASTContext *var_ast_context = type_list->GetClangASTContext().getASTContext();
855
Sean Callanan336a0002010-07-17 00:43:37 +0000856 void *type_to_use;
857
Sean Callananf328c9f2010-07-20 23:31:16 +0000858 if (parser_ast_context)
859 {
860 type_to_use = ClangASTContext::CopyType(parser_ast_context, var_ast_context, var_opaque_type);
861
862 if (parser_type)
863 *parser_type = TypeFromParser(type_to_use, parser_ast_context);
864 }
Sean Callanan336a0002010-07-17 00:43:37 +0000865 else
866 type_to_use = var_opaque_type;
Chris Lattner24943d22010-06-08 16:52:24 +0000867
868 if (var_location.get()->GetContextType() == Value::eContextTypeInvalid)
Sean Callanan336a0002010-07-17 00:43:37 +0000869 var_location.get()->SetContext(Value::eContextTypeOpaqueClangQualType, type_to_use);
Chris Lattner24943d22010-06-08 16:52:24 +0000870
871 if (var_location.get()->GetValueType() == Value::eValueTypeFileAddress)
872 {
873 SymbolContext var_sc;
874 var->CalculateSymbolContext(&var_sc);
Sean Callanan336a0002010-07-17 00:43:37 +0000875
Chris Lattner24943d22010-06-08 16:52:24 +0000876 if (!var_sc.module_sp)
Sean Callanan336a0002010-07-17 00:43:37 +0000877 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000878
879 ObjectFile *object_file = var_sc.module_sp->GetObjectFile();
880
881 if (!object_file)
Sean Callanan336a0002010-07-17 00:43:37 +0000882 return NULL;
883
Chris Lattner24943d22010-06-08 16:52:24 +0000884 Address so_addr(var_location->GetScalar().ULongLong(), object_file->GetSectionList());
885
886 lldb::addr_t load_addr = so_addr.GetLoadAddress(m_exe_ctx->process);
887
888 var_location->GetScalar() = load_addr;
889 var_location->SetValueType(Value::eValueTypeLoadAddress);
890 }
891
Sean Callananf328c9f2010-07-20 23:31:16 +0000892 if (user_type)
893 *user_type = TypeFromUser(var_opaque_type, var_ast_context);
Sean Callanan336a0002010-07-17 00:43:37 +0000894
895 return var_location.release();
896}
897
898void
899ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
900 Variable* var)
901{
902 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
903
Sean Callananf328c9f2010-07-20 23:31:16 +0000904 TypeFromUser ut;
905 TypeFromParser pt;
Sean Callanan336a0002010-07-17 00:43:37 +0000906
907 Value *var_location = GetVariableValue(*m_exe_ctx,
908 var,
909 context.GetASTContext(),
Sean Callananf328c9f2010-07-20 23:31:16 +0000910 &ut,
911 &pt);
Sean Callanan336a0002010-07-17 00:43:37 +0000912
Greg Clayton1674b122010-07-21 22:12:05 +0000913 NamedDecl *var_decl = context.AddVarDecl(pt.GetOpaqueQualType());
Chris Lattner24943d22010-06-08 16:52:24 +0000914
915 Tuple tuple;
916
Sean Callanan810f22d2010-07-16 00:09:46 +0000917 tuple.m_decl = var_decl;
Sean Callanan336a0002010-07-17 00:43:37 +0000918 tuple.m_value = var_location;
Sean Callananf328c9f2010-07-20 23:31:16 +0000919 tuple.m_user_type = ut;
920 tuple.m_parser_type = pt;
Sean Callanan02fbafa2010-07-27 21:39:39 +0000921 tuple.m_llvm_value = NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000922
923 m_tuples.push_back(tuple);
924
Sean Callanan810f22d2010-07-16 00:09:46 +0000925 if (log)
Sean Callananf5857a02010-07-31 01:32:05 +0000926 log->Printf("Found variable %s, returned (NamedDecl)%p", context.Name.getAsString().c_str(), var_decl);
Sean Callanan8f0dc342010-06-22 23:46:24 +0000927}
928
929void
Sean Callanana48fe162010-08-11 03:57:18 +0000930ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
931 ClangPersistentVariable *pvar)
932{
933 TypeFromUser user_type = pvar->Type();
934
935 TypeFromParser parser_type(ClangASTContext::CopyType(context.GetASTContext(),
936 user_type.GetASTContext(),
937 user_type.GetOpaqueQualType()),
938 context.GetASTContext());
939
940 (void)context.AddVarDecl(parser_type.GetOpaqueQualType());
941}
942
943void
Sean Callanan8f0dc342010-06-22 23:46:24 +0000944ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
Sean Callanan0fc73582010-07-27 00:55:47 +0000945 Function* fun,
946 Symbol* symbol)
Sean Callanan8f0dc342010-06-22 23:46:24 +0000947{
Sean Callanan6184dfe2010-06-23 00:47:48 +0000948 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
Sean Callanan8f0dc342010-06-22 23:46:24 +0000949
Sean Callanan0fc73582010-07-27 00:55:47 +0000950 NamedDecl *fun_decl;
Sean Callanan8f0dc342010-06-22 23:46:24 +0000951 std::auto_ptr<Value> fun_location(new Value);
Sean Callanan0fc73582010-07-27 00:55:47 +0000952 const Address *fun_address;
Sean Callanan8f0dc342010-06-22 23:46:24 +0000953
Sean Callanan0fc73582010-07-27 00:55:47 +0000954 // only valid for Functions, not for Symbols
955 void *fun_opaque_type = NULL;
956 clang::ASTContext *fun_ast_context = NULL;
957
958 if (fun)
959 {
960 Type *fun_type = fun->GetType();
961
962 if (!fun_type)
963 {
964 if (log)
965 log->PutCString("Skipped a function because it has no type");
966 return;
967 }
968
969 fun_opaque_type = fun_type->GetOpaqueClangQualType();
970
971 if (!fun_opaque_type)
972 {
973 if (log)
974 log->PutCString("Skipped a function because it has no Clang type");
975 return;
976 }
977
978 fun_address = &fun->GetAddressRange().GetBaseAddress();
979
980 TypeList *type_list = fun_type->GetTypeList();
981 fun_ast_context = type_list->GetClangASTContext().getASTContext();
982 void *copied_type = ClangASTContext::CopyType(context.GetASTContext(), fun_ast_context, fun_opaque_type);
983
984 fun_decl = context.AddFunDecl(copied_type);
985 }
986 else if (symbol)
987 {
988 fun_address = &symbol->GetAddressRangeRef().GetBaseAddress();
989
990 fun_decl = context.AddGenericFunDecl();
991 }
992 else
993 {
994 if (log)
995 log->PutCString("AddOneFunction called with no function and no symbol");
996 return;
997 }
998
999 lldb::addr_t load_addr = fun_address->GetLoadAddress(m_exe_ctx->process);
Sean Callanan8f0dc342010-06-22 23:46:24 +00001000 fun_location->SetValueType(Value::eValueTypeLoadAddress);
1001 fun_location->GetScalar() = load_addr;
1002
Sean Callanan8f0dc342010-06-22 23:46:24 +00001003 Tuple tuple;
1004
Sean Callanan810f22d2010-07-16 00:09:46 +00001005 tuple.m_decl = fun_decl;
1006 tuple.m_value = fun_location.release();
Sean Callananf328c9f2010-07-20 23:31:16 +00001007 tuple.m_user_type = TypeFromUser(fun_opaque_type, fun_ast_context);
Sean Callanan02fbafa2010-07-27 21:39:39 +00001008 tuple.m_llvm_value = NULL;
Sean Callanan8f0dc342010-06-22 23:46:24 +00001009
1010 m_tuples.push_back(tuple);
1011
Sean Callanan810f22d2010-07-16 00:09:46 +00001012 if (log)
Sean Callananf5857a02010-07-31 01:32:05 +00001013 log->Printf("Found function %s, returned (NamedDecl)%p", context.Name.getAsString().c_str(), fun_decl);
Chris Lattner24943d22010-06-08 16:52:24 +00001014}
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001015
1016void
1017ClangExpressionDeclMap::AddOneType(NameSearchContext &context,
1018 Type *type)
1019{
1020 TypeFromUser ut(type->GetOpaqueClangQualType(),
1021 type->GetClangAST());
1022
1023 void *copied_type = ClangASTContext::CopyType(context.GetASTContext(), ut.GetASTContext(), ut.GetOpaqueQualType());
1024
1025 context.AddTypeDecl(copied_type);
1026}