blob: 446490836f808e86a4fd53a7d4fbc943fd5a599c [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 Callanana6223432010-08-20 01:02:30 +0000104 return m_persistent_vars->CreatePersistentVariable (name, user_type);
Sean Callanana48fe162010-08-11 03:57:18 +0000105}
106
107bool
Sean Callanan8bce6652010-07-13 21:41:46 +0000108ClangExpressionDeclMap::AddValueToStruct (llvm::Value *value,
109 const clang::NamedDecl *decl,
Sean Callanan810f22d2010-07-16 00:09:46 +0000110 std::string &name,
Sean Callanana386e052010-08-13 22:29:54 +0000111 TypeFromParser type,
Sean Callanan8bce6652010-07-13 21:41:46 +0000112 size_t size,
113 off_t alignment)
114{
115 m_struct_laid_out = false;
116
117 StructMemberIterator iter;
118
119 for (iter = m_members.begin();
120 iter != m_members.end();
121 ++iter)
122 {
123 if (iter->m_decl == decl)
124 return true;
125 }
126
127 StructMember member;
128
Sean Callananf328c9f2010-07-20 23:31:16 +0000129 member.m_value = value;
130 member.m_decl = decl;
131 member.m_name = name;
Sean Callanana386e052010-08-13 22:29:54 +0000132 member.m_parser_type = type;
Sean Callananf328c9f2010-07-20 23:31:16 +0000133 member.m_offset = 0;
134 member.m_size = size;
135 member.m_alignment = alignment;
Sean Callanan8bce6652010-07-13 21:41:46 +0000136
137 m_members.push_back(member);
138
139 return true;
140}
141
142bool
143ClangExpressionDeclMap::DoStructLayout ()
144{
145 if (m_struct_laid_out)
146 return true;
147
148 StructMemberIterator iter;
149
150 off_t cursor = 0;
151
152 m_struct_alignment = 0;
153 m_struct_size = 0;
154
155 for (iter = m_members.begin();
156 iter != m_members.end();
157 ++iter)
158 {
159 if (iter == m_members.begin())
160 m_struct_alignment = iter->m_alignment;
161
162 if (cursor % iter->m_alignment)
163 cursor += (iter->m_alignment - (cursor % iter->m_alignment));
164
165 iter->m_offset = cursor;
166 cursor += iter->m_size;
167 }
168
169 m_struct_size = cursor;
170
171 m_struct_laid_out = true;
172 return true;
173}
174
175bool ClangExpressionDeclMap::GetStructInfo (uint32_t &num_elements,
176 size_t &size,
177 off_t &alignment)
178{
179 if (!m_struct_laid_out)
180 return false;
181
182 num_elements = m_members.size();
183 size = m_struct_size;
184 alignment = m_struct_alignment;
185
186 return true;
187}
188
189bool
190ClangExpressionDeclMap::GetStructElement (const clang::NamedDecl *&decl,
191 llvm::Value *&value,
192 off_t &offset,
193 uint32_t index)
194{
195 if (!m_struct_laid_out)
196 return false;
197
198 if (index >= m_members.size())
199 return false;
200
201 decl = m_members[index].m_decl;
202 value = m_members[index].m_value;
203 offset = m_members[index].m_offset;
204
205 return true;
206}
207
Sean Callanan02fbafa2010-07-27 21:39:39 +0000208bool
209ClangExpressionDeclMap::GetFunctionInfo (const clang::NamedDecl *decl,
210 llvm::Value**& value,
211 uint64_t &ptr)
Sean Callananba992c52010-07-27 02:07:53 +0000212{
213 TupleIterator iter;
214
215 for (iter = m_tuples.begin();
216 iter != m_tuples.end();
217 ++iter)
218 {
219 if (decl == iter->m_decl)
220 {
Sean Callanan02fbafa2010-07-27 21:39:39 +0000221 value = &iter->m_llvm_value;
222 ptr = iter->m_value->GetScalar().ULongLong();
223 return true;
Sean Callananba992c52010-07-27 02:07:53 +0000224 }
225 }
226
Sean Callanan02fbafa2010-07-27 21:39:39 +0000227 return false;
Sean Callananba992c52010-07-27 02:07:53 +0000228}
229
Sean Callananf5857a02010-07-31 01:32:05 +0000230bool
231ClangExpressionDeclMap::GetFunctionAddress (const char *name,
232 uint64_t &ptr)
233{
234 // Back out in all cases where we're not fully initialized
235 if (!m_exe_ctx || !m_exe_ctx->frame || !m_sym_ctx)
236 return false;
237
238 ConstString name_cs(name);
239 SymbolContextList sym_ctxs;
240
241 m_sym_ctx->FindFunctionsByName(name_cs, false, sym_ctxs);
242
243 if (!sym_ctxs.GetSize())
244 return false;
245
246 SymbolContext sym_ctx;
247 sym_ctxs.GetContextAtIndex(0, sym_ctx);
248
249 const Address *fun_address;
250
251 if (sym_ctx.function)
252 fun_address = &sym_ctx.function->GetAddressRange().GetBaseAddress();
253 else if (sym_ctx.symbol)
254 fun_address = &sym_ctx.symbol->GetAddressRangeRef().GetBaseAddress();
255 else
256 return false;
257
258 ptr = fun_address->GetLoadAddress(m_exe_ctx->process);
259
260 return true;
261}
262
Chris Lattner24943d22010-06-08 16:52:24 +0000263// Interface for DwarfExpression
Sean Callananf328c9f2010-07-20 23:31:16 +0000264lldb_private::Value
Chris Lattner24943d22010-06-08 16:52:24 +0000265*ClangExpressionDeclMap::GetValueForIndex (uint32_t index)
266{
267 if (index >= m_tuples.size ())
268 return NULL;
269
270 return m_tuples[index].m_value;
271}
272
Sean Callanan810f22d2010-07-16 00:09:46 +0000273// Interface for CommandObjectExpression
Sean Callananf328c9f2010-07-20 23:31:16 +0000274
275bool
276ClangExpressionDeclMap::Materialize (ExecutionContext *exe_ctx,
277 lldb::addr_t &struct_address,
278 Error &err)
279{
280 bool result = DoMaterialize(false, exe_ctx, NULL, err);
281
282 if (result)
283 struct_address = m_materialized_location;
284
285 return result;
286}
287
288bool
289ClangExpressionDeclMap::Dematerialize (ExecutionContext *exe_ctx,
Sean Callanana6223432010-08-20 01:02:30 +0000290 ClangExpressionVariable *&result,
Sean Callananf328c9f2010-07-20 23:31:16 +0000291 Error &err)
292{
Sean Callanan82b74c82010-08-12 01:56:52 +0000293 return DoMaterialize(true, exe_ctx, &result, err);
Sean Callananf328c9f2010-07-20 23:31:16 +0000294}
295
Sean Callanan32824aa2010-07-23 22:19:18 +0000296bool
297ClangExpressionDeclMap::DumpMaterializedStruct(ExecutionContext *exe_ctx,
298 Stream &s,
299 Error &err)
300{
301 if (!m_struct_laid_out)
302 {
303 err.SetErrorString("Structure hasn't been laid out yet");
304 return false;
305 }
306
307 if (!exe_ctx)
308 {
309 err.SetErrorString("Received null execution context");
310 return false;
311 }
312
313
314 if (!exe_ctx->process)
315 {
316 err.SetErrorString("Couldn't find the process");
317 return false;
318 }
319
320 if (!exe_ctx->target)
321 {
322 err.SetErrorString("Couldn't find the target");
323 return false;
324 }
325
326 lldb::DataBufferSP data(new DataBufferHeap(m_struct_size, 0));
327
328 Error error;
329 if (exe_ctx->process->ReadMemory (m_materialized_location, data->GetBytes(), data->GetByteSize(), error) != data->GetByteSize())
330 {
331 err.SetErrorStringWithFormat ("Couldn't read struct from the target: %s", error.AsCString());
332 return false;
333 }
334
335 DataExtractor extractor(data, exe_ctx->process->GetByteOrder(), exe_ctx->target->GetArchitecture().GetAddressByteSize());
336
337 StructMemberIterator iter;
338
339 for (iter = m_members.begin();
340 iter != m_members.end();
341 ++iter)
342 {
343 s.Printf("[%s]\n", iter->m_name.c_str());
344
345 extractor.Dump(&s, // stream
346 iter->m_offset, // offset
347 lldb::eFormatBytesWithASCII, // format
348 1, // byte size of individual entries
349 iter->m_size, // number of entries
350 16, // entries per line
351 m_materialized_location + iter->m_offset, // address to print
352 0, // bit size (bitfields only; 0 means ignore)
353 0); // bit alignment (bitfields only; 0 means ignore)
354
355 s.PutChar('\n');
356 }
357
358 return true;
359}
360
Sean Callananf328c9f2010-07-20 23:31:16 +0000361bool
362ClangExpressionDeclMap::DoMaterialize (bool dematerialize,
363 ExecutionContext *exe_ctx,
Sean Callanana6223432010-08-20 01:02:30 +0000364 ClangExpressionVariable **result,
Sean Callananf328c9f2010-07-20 23:31:16 +0000365 Error &err)
Sean Callanan810f22d2010-07-16 00:09:46 +0000366{
Sean Callanan336a0002010-07-17 00:43:37 +0000367 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
Sean Callanan82b74c82010-08-12 01:56:52 +0000368
Sean Callanan810f22d2010-07-16 00:09:46 +0000369 if (!m_struct_laid_out)
370 {
371 err.SetErrorString("Structure hasn't been laid out yet");
372 return LLDB_INVALID_ADDRESS;
373 }
374
Sean Callanan810f22d2010-07-16 00:09:46 +0000375 if (!exe_ctx)
376 {
377 err.SetErrorString("Received null execution context");
378 return LLDB_INVALID_ADDRESS;
379 }
380
Sean Callanan45839272010-07-24 01:37:44 +0000381 if (!exe_ctx->frame)
382 {
383 err.SetErrorString("Received null execution frame");
384 return LLDB_INVALID_ADDRESS;
385 }
386
Sean Callanan810f22d2010-07-16 00:09:46 +0000387 const SymbolContext &sym_ctx(exe_ctx->frame->GetSymbolContext(lldb::eSymbolContextEverything));
388
Sean Callananf328c9f2010-07-20 23:31:16 +0000389 if (!dematerialize)
Sean Callanan810f22d2010-07-16 00:09:46 +0000390 {
Sean Callananf328c9f2010-07-20 23:31:16 +0000391 if (m_materialized_location)
392 {
393 exe_ctx->process->DeallocateMemory(m_materialized_location);
394 m_materialized_location = 0;
395 }
396
397 lldb::addr_t mem = exe_ctx->process->AllocateMemory(m_struct_alignment + m_struct_size,
398 lldb::ePermissionsReadable | lldb::ePermissionsWritable,
399 err);
400
401 if (mem == LLDB_INVALID_ADDRESS)
402 return false;
403
404 m_allocated_area = mem;
Sean Callanan810f22d2010-07-16 00:09:46 +0000405 }
406
Sean Callananf328c9f2010-07-20 23:31:16 +0000407 m_materialized_location = m_allocated_area;
408
409 if (m_materialized_location % m_struct_alignment)
410 {
411 m_materialized_location += (m_struct_alignment - (m_materialized_location % m_struct_alignment));
412 }
413
414 StructMemberIterator iter;
415
Sean Callanan810f22d2010-07-16 00:09:46 +0000416 for (iter = m_members.begin();
417 iter != m_members.end();
418 ++iter)
419 {
420 uint32_t tuple_index;
421
Sean Callanan336a0002010-07-17 00:43:37 +0000422 if (!GetIndexForDecl(tuple_index, iter->m_decl))
423 {
Sean Callanan82b74c82010-08-12 01:56:52 +0000424 if (iter->m_name.find("___clang_expr_result") != std::string::npos)
425 {
426 if (dematerialize)
427 {
428 // Here we pick up the odd anomaly produced by
429 // IRForTarget::createResultVariable (and described in a comment
430 // there).
431 //
432 // We rename the variable to the name of the result PVar and
433 // incidentally drop the address of the PVar into *result
434 // (if it's non-NULL, of course). We then let this case fall
435 // through to the persistent variable handler.
436
437 if (log)
438 log->PutCString("Found result member in the struct");
439
440 iter->m_name = m_result_name;
441
442 if (result)
443 {
444 if (log)
445 log->PutCString("Returning result PVar");
446
Sean Callanana6223432010-08-20 01:02:30 +0000447 *result = m_persistent_vars->GetVariable(m_result_name.c_str());
Sean Callanan82b74c82010-08-12 01:56:52 +0000448
449 if (!*result)
450 {
451 err.SetErrorStringWithFormat("Couldn't find persistent variable for result %s", m_result_name.c_str());
452 }
453 }
454 else
455 {
456 if (log)
457 log->PutCString("Didn't return result PVar; pointer was NULL");
458 }
459 }
460 else
461 {
462 // The result variable doesn't need to be materialized, ever.
463 continue;
464 }
465 }
466
Sean Callanana48fe162010-08-11 03:57:18 +0000467 if (iter->m_name[0] == '$')
468 {
469 if (!DoMaterializeOnePersistentVariable(dematerialize, *exe_ctx, iter->m_name.c_str(), m_materialized_location + iter->m_offset, err))
470 return false;
471 }
Sean Callanana48fe162010-08-11 03:57:18 +0000472 else
Sean Callanan336a0002010-07-17 00:43:37 +0000473 {
474 err.SetErrorStringWithFormat("Unexpected variable %s", iter->m_name.c_str());
475 return false;
476 }
477
Sean Callanan810f22d2010-07-16 00:09:46 +0000478 continue;
Sean Callanan336a0002010-07-17 00:43:37 +0000479 }
Sean Callanan810f22d2010-07-16 00:09:46 +0000480
481 Tuple &tuple(m_tuples[tuple_index]);
482
Sean Callananf328c9f2010-07-20 23:31:16 +0000483 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 +0000484 return false;
Sean Callanan810f22d2010-07-16 00:09:46 +0000485 }
486
Sean Callananf328c9f2010-07-20 23:31:16 +0000487 return true;
488}
489
Sean Callanana48fe162010-08-11 03:57:18 +0000490bool
491ClangExpressionDeclMap::DoMaterializeOnePersistentVariable(bool dematerialize,
492 ExecutionContext &exe_ctx,
493 const char *name,
494 lldb::addr_t addr,
495 Error &err)
496{
497 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
498
499 if (log)
500 log->Printf("Found persistent variable %s", name);
501
Sean Callanana6223432010-08-20 01:02:30 +0000502 ClangExpressionVariable *pvar(m_persistent_vars->GetVariable(name));
Sean Callanana48fe162010-08-11 03:57:18 +0000503
504 if (!pvar)
505 {
506 err.SetErrorStringWithFormat("Undefined persistent variable %s", name);
507 return LLDB_INVALID_ADDRESS;
508 }
509
510 size_t pvar_size = pvar->Size();
Sean Callanana6223432010-08-20 01:02:30 +0000511
512 if (!pvar->m_data_vars.get())
513 return false;
514
515 uint8_t *pvar_data = pvar->m_data_vars->m_data->GetBytes();
Sean Callanana48fe162010-08-11 03:57:18 +0000516 Error error;
517
518 if (dematerialize)
519 {
520 if (exe_ctx.process->ReadMemory (addr, pvar_data, pvar_size, error) != pvar_size)
521 {
522 err.SetErrorStringWithFormat ("Couldn't read a composite type from the target: %s", error.AsCString());
523 return false;
524 }
525 }
526 else
527 {
528 if (exe_ctx.process->WriteMemory (addr, pvar_data, pvar_size, error) != pvar_size)
529 {
530 err.SetErrorStringWithFormat ("Couldn't write a composite type to the target: %s", error.AsCString());
531 return false;
532 }
533 }
534
535 return true;
536}
537
Sean Callananf328c9f2010-07-20 23:31:16 +0000538bool
539ClangExpressionDeclMap::DoMaterializeOneVariable(bool dematerialize,
540 ExecutionContext &exe_ctx,
541 const SymbolContext &sym_ctx,
542 const char *name,
543 TypeFromUser type,
544 lldb::addr_t addr,
545 Error &err)
546{
547 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
548
549 Variable *var = FindVariableInScope(sym_ctx, name, &type);
550
551 if (!var)
552 {
553 err.SetErrorStringWithFormat("Couldn't find %s with appropriate type", name);
554 return false;
555 }
556
Sean Callanan841026f2010-07-23 00:16:21 +0000557 if (log)
558 log->Printf("%s %s with type %p", (dematerialize ? "Dematerializing" : "Materializing"), name, type.GetOpaqueQualType());
Sean Callananf328c9f2010-07-20 23:31:16 +0000559
560 std::auto_ptr<lldb_private::Value> location_value(GetVariableValue(exe_ctx,
561 var,
562 type.GetASTContext()));
563
564 if (!location_value.get())
565 {
566 err.SetErrorStringWithFormat("Couldn't get value for %s", name);
567 return false;
568 }
569
570 if (location_value->GetValueType() == Value::eValueTypeLoadAddress)
571 {
572 lldb::addr_t value_addr = location_value->GetScalar().ULongLong();
573
Greg Clayton960d6a42010-08-03 00:35:52 +0000574 size_t bit_size = ClangASTType::GetClangTypeBitWidth(type.GetASTContext(), type.GetOpaqueQualType());
Sean Callananf328c9f2010-07-20 23:31:16 +0000575 size_t byte_size = bit_size % 8 ? ((bit_size + 8) / 8) : (bit_size / 8);
576
577 DataBufferHeap data;
578 data.SetByteSize(byte_size);
579
580 lldb::addr_t src_addr;
581 lldb::addr_t dest_addr;
582
583 if (dematerialize)
584 {
585 src_addr = addr;
586 dest_addr = value_addr;
587 }
588 else
589 {
590 src_addr = value_addr;
591 dest_addr = addr;
592 }
593
594 Error error;
595 if (exe_ctx.process->ReadMemory (src_addr, data.GetBytes(), byte_size, error) != byte_size)
596 {
597 err.SetErrorStringWithFormat ("Couldn't read a composite type from the target: %s", error.AsCString());
598 return false;
599 }
600
601 if (exe_ctx.process->WriteMemory (dest_addr, data.GetBytes(), byte_size, error) != byte_size)
602 {
603 err.SetErrorStringWithFormat ("Couldn't write a composite type to the target: %s", error.AsCString());
604 return false;
605 }
606
607 if (log)
608 log->Printf("Copied from 0x%llx to 0x%llx", (uint64_t)src_addr, (uint64_t)addr);
609 }
610 else
611 {
612 StreamString ss;
613
614 location_value->Dump(&ss);
615
616 err.SetErrorStringWithFormat("%s has a value of unhandled type: %s", name, ss.GetString().c_str());
617 }
618
619 return true;
Sean Callanan810f22d2010-07-16 00:09:46 +0000620}
621
Sean Callanan336a0002010-07-17 00:43:37 +0000622Variable*
623ClangExpressionDeclMap::FindVariableInScope(const SymbolContext &sym_ctx,
624 const char *name,
Sean Callananf328c9f2010-07-20 23:31:16 +0000625 TypeFromUser *type)
Sean Callanan810f22d2010-07-16 00:09:46 +0000626{
627 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
628
Greg Clayton75ccf502010-08-21 02:22:51 +0000629 if (m_sym_ctx->function == NULL || m_sym_ctx->block == NULL)
Sean Callanan810f22d2010-07-16 00:09:46 +0000630 {
631 if (log)
Greg Clayton75ccf502010-08-21 02:22:51 +0000632 log->Printf("function = %p, block = %p", m_sym_ctx->function, m_sym_ctx->block);
Sean Callanan336a0002010-07-17 00:43:37 +0000633 return NULL;
Sean Callanan810f22d2010-07-16 00:09:46 +0000634 }
635
Sean Callanan336a0002010-07-17 00:43:37 +0000636 ConstString name_cs(name);
637
Greg Clayton75ccf502010-08-21 02:22:51 +0000638 Block *current_block;
Sean Callanan810f22d2010-07-16 00:09:46 +0000639
Greg Clayton75ccf502010-08-21 02:22:51 +0000640 for (current_block = m_sym_ctx->block;
641 current_block != NULL;
642 current_block = current_block->GetParent())
643 {
Sean Callanan810f22d2010-07-16 00:09:46 +0000644 lldb::VariableListSP var_list = current_block->GetVariableList(false, true);
645
646 if (!var_list)
647 continue;
648
Sean Callanan336a0002010-07-17 00:43:37 +0000649 lldb::VariableSP var = var_list->FindVariable(name_cs);
Sean Callanan810f22d2010-07-16 00:09:46 +0000650
651 if (!var)
652 continue;
653
654 // var->GetType()->GetClangAST() is the program's AST context and holds
655 // var->GetType()->GetOpaqueClangQualType().
656
657 // type is m_type for one of the struct members, which was added by
658 // AddValueToStruct. That type was extracted from the AST context of
659 // the compiler in IRForTarget. The original for the type was copied
660 // out of the program's AST context by AddOneVariable.
661
Sean Callanan336a0002010-07-17 00:43:37 +0000662 // So that we can compare these two without having to copy back
663 // something we already had in the original AST context, we maintain
664 // m_orig_type and m_ast_context (which are passed into
665 // MaterializeOneVariable by Materialize) for each variable.
666
667 if (!type)
668 return var.get();
Sean Callanan810f22d2010-07-16 00:09:46 +0000669
Sean Callananf328c9f2010-07-20 23:31:16 +0000670 if (type->GetASTContext() == var->GetType()->GetClangAST())
Sean Callanan810f22d2010-07-16 00:09:46 +0000671 {
Sean Callananf5857a02010-07-31 01:32:05 +0000672 if (!ClangASTContext::AreTypesSame(type->GetASTContext(), type->GetOpaqueQualType(), var->GetType()->GetOpaqueClangQualType()))
Sean Callanan810f22d2010-07-16 00:09:46 +0000673 continue;
674 }
675 else
676 {
677 if (log)
678 log->PutCString("Skipping a candidate variable because of different AST contexts");
679 continue;
680 }
681
Sean Callanan336a0002010-07-17 00:43:37 +0000682 return var.get();
683 }
684
685 {
686 CompileUnit *compile_unit = m_sym_ctx->comp_unit;
Sean Callanan810f22d2010-07-16 00:09:46 +0000687
Sean Callanan336a0002010-07-17 00:43:37 +0000688 if (!compile_unit)
689 {
690 if (log)
691 log->Printf("compile_unit = %p", compile_unit);
692 return NULL;
693 }
694
695 lldb::VariableListSP var_list = compile_unit->GetVariableList(true);
696
697 if (!var_list)
698 return NULL;
699
700 lldb::VariableSP var = var_list->FindVariable(name_cs);
701
702 if (!var)
703 return NULL;
704
705 if (!type)
706 return var.get();
707
Sean Callananf328c9f2010-07-20 23:31:16 +0000708 if (type->GetASTContext() == var->GetType()->GetClangAST())
Sean Callanan336a0002010-07-17 00:43:37 +0000709 {
Sean Callanan841026f2010-07-23 00:16:21 +0000710 if (!ClangASTContext::AreTypesSame(type->GetASTContext(), type->GetOpaqueQualType(), var->GetType()->GetOpaqueClangQualType()))
Sean Callanan336a0002010-07-17 00:43:37 +0000711 return NULL;
712 }
713 else
714 {
715 if (log)
716 log->PutCString("Skipping a candidate variable because of different AST contexts");
717 return NULL;
718 }
719
720 return var.get();
721 }
722
723 return NULL;
724}
725
Chris Lattner24943d22010-06-08 16:52:24 +0000726// Interface for ClangASTSource
727void
728ClangExpressionDeclMap::GetDecls(NameSearchContext &context,
729 const char *name)
730{
Sean Callanan6184dfe2010-06-23 00:47:48 +0000731 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
732
Sean Callanan810f22d2010-07-16 00:09:46 +0000733 if (log)
734 log->Printf("Hunting for a definition for %s", name);
Chris Lattner24943d22010-06-08 16:52:24 +0000735
736 // Back out in all cases where we're not fully initialized
737 if (!m_exe_ctx || !m_exe_ctx->frame || !m_sym_ctx)
738 return;
739
740 Function *function = m_sym_ctx->function;
Chris Lattner24943d22010-06-08 16:52:24 +0000741
Sean Callanan336a0002010-07-17 00:43:37 +0000742 if (!function)
Chris Lattner24943d22010-06-08 16:52:24 +0000743 {
Sean Callanan810f22d2010-07-16 00:09:46 +0000744 if (log)
Sean Callanan336a0002010-07-17 00:43:37 +0000745 log->Printf("Can't evaluate an expression when not in a function");
Chris Lattner24943d22010-06-08 16:52:24 +0000746 return;
747 }
748
Chris Lattner24943d22010-06-08 16:52:24 +0000749 ConstString name_cs(name);
Sean Callanan0fc73582010-07-27 00:55:47 +0000750 SymbolContextList sym_ctxs;
Chris Lattner24943d22010-06-08 16:52:24 +0000751
Sean Callanan0fc73582010-07-27 00:55:47 +0000752 m_sym_ctx->FindFunctionsByName(name_cs, false, sym_ctxs);
Sean Callanan8f0dc342010-06-22 23:46:24 +0000753
Sean Callanan0fc73582010-07-27 00:55:47 +0000754 for (uint32_t index = 0, num_indices = sym_ctxs.GetSize();
755 index < num_indices;
756 ++index)
757 {
758 SymbolContext sym_ctx;
759 sym_ctxs.GetContextAtIndex(index, sym_ctx);
760
761 if (sym_ctx.function)
762 AddOneFunction(context, sym_ctx.function, NULL);
763 else if(sym_ctx.symbol)
764 AddOneFunction(context, NULL, sym_ctx.symbol);
765 }
766
Sean Callanan336a0002010-07-17 00:43:37 +0000767 Variable *var = FindVariableInScope(*m_sym_ctx, name);
768
769 if (var)
770 AddOneVariable(context, var);
Sean Callanan93a4b1a2010-08-04 01:02:13 +0000771
Sean Callanana6223432010-08-20 01:02:30 +0000772 ClangExpressionVariable *pvar(m_persistent_vars->GetVariable(name));
Sean Callanana48fe162010-08-11 03:57:18 +0000773
774 if (pvar)
775 AddOneVariable(context, pvar);
776
Sean Callanan93a4b1a2010-08-04 01:02:13 +0000777 /* Commented out pending resolution of a loop when the TagType is imported
778 lldb::TypeSP type = m_sym_ctx->FindTypeByName(name_cs);
779
780 if (type.get())
781 AddOneType(context, type.get());
782 */
Sean Callanan336a0002010-07-17 00:43:37 +0000783}
784
785Value *
786ClangExpressionDeclMap::GetVariableValue(ExecutionContext &exe_ctx,
787 Variable *var,
Sean Callananf328c9f2010-07-20 23:31:16 +0000788 clang::ASTContext *parser_ast_context,
789 TypeFromUser *user_type,
790 TypeFromParser *parser_type)
Chris Lattner24943d22010-06-08 16:52:24 +0000791{
Sean Callanan6184dfe2010-06-23 00:47:48 +0000792 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
793
Chris Lattner24943d22010-06-08 16:52:24 +0000794 Type *var_type = var->GetType();
795
796 if (!var_type)
797 {
Sean Callanan810f22d2010-07-16 00:09:46 +0000798 if (log)
799 log->PutCString("Skipped a definition because it has no type");
Sean Callanan336a0002010-07-17 00:43:37 +0000800 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000801 }
802
803 void *var_opaque_type = var_type->GetOpaqueClangQualType();
804
805 if (!var_opaque_type)
806 {
Sean Callanan810f22d2010-07-16 00:09:46 +0000807 if (log)
808 log->PutCString("Skipped a definition because it has no Clang type");
Sean Callanan336a0002010-07-17 00:43:37 +0000809 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000810 }
811
Chris Lattner24943d22010-06-08 16:52:24 +0000812 TypeList *type_list = var_type->GetTypeList();
813
814 if (!type_list)
815 {
Sean Callanan810f22d2010-07-16 00:09:46 +0000816 if (log)
817 log->PutCString("Skipped a definition because the type has no associated type list");
Sean Callanan336a0002010-07-17 00:43:37 +0000818 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000819 }
820
821 clang::ASTContext *exe_ast_ctx = type_list->GetClangASTContext().getASTContext();
822
823 if (!exe_ast_ctx)
824 {
Sean Callanan810f22d2010-07-16 00:09:46 +0000825 if (log)
826 log->PutCString("There is no AST context for the current execution context");
Sean Callanan336a0002010-07-17 00:43:37 +0000827 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000828 }
829
Sean Callanan336a0002010-07-17 00:43:37 +0000830 DWARFExpression &var_location_expr = var->LocationExpression();
831
Chris Lattner24943d22010-06-08 16:52:24 +0000832 std::auto_ptr<Value> var_location(new Value);
833
834 Error err;
835
Sean Callanan336a0002010-07-17 00:43:37 +0000836 if (!var_location_expr.Evaluate(&exe_ctx, exe_ast_ctx, NULL, *var_location.get(), &err))
Chris Lattner24943d22010-06-08 16:52:24 +0000837 {
Sean Callanan810f22d2010-07-16 00:09:46 +0000838 if (log)
839 log->Printf("Error evaluating location: %s", err.AsCString());
Sean Callanan336a0002010-07-17 00:43:37 +0000840 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000841 }
842
Sean Callanan810f22d2010-07-16 00:09:46 +0000843 clang::ASTContext *var_ast_context = type_list->GetClangASTContext().getASTContext();
844
Sean Callanan336a0002010-07-17 00:43:37 +0000845 void *type_to_use;
846
Sean Callananf328c9f2010-07-20 23:31:16 +0000847 if (parser_ast_context)
848 {
849 type_to_use = ClangASTContext::CopyType(parser_ast_context, var_ast_context, var_opaque_type);
850
851 if (parser_type)
852 *parser_type = TypeFromParser(type_to_use, parser_ast_context);
853 }
Sean Callanan336a0002010-07-17 00:43:37 +0000854 else
855 type_to_use = var_opaque_type;
Chris Lattner24943d22010-06-08 16:52:24 +0000856
857 if (var_location.get()->GetContextType() == Value::eContextTypeInvalid)
Sean Callanan336a0002010-07-17 00:43:37 +0000858 var_location.get()->SetContext(Value::eContextTypeOpaqueClangQualType, type_to_use);
Chris Lattner24943d22010-06-08 16:52:24 +0000859
860 if (var_location.get()->GetValueType() == Value::eValueTypeFileAddress)
861 {
862 SymbolContext var_sc;
863 var->CalculateSymbolContext(&var_sc);
Sean Callanan336a0002010-07-17 00:43:37 +0000864
Chris Lattner24943d22010-06-08 16:52:24 +0000865 if (!var_sc.module_sp)
Sean Callanan336a0002010-07-17 00:43:37 +0000866 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000867
868 ObjectFile *object_file = var_sc.module_sp->GetObjectFile();
869
870 if (!object_file)
Sean Callanan336a0002010-07-17 00:43:37 +0000871 return NULL;
872
Chris Lattner24943d22010-06-08 16:52:24 +0000873 Address so_addr(var_location->GetScalar().ULongLong(), object_file->GetSectionList());
874
875 lldb::addr_t load_addr = so_addr.GetLoadAddress(m_exe_ctx->process);
876
877 var_location->GetScalar() = load_addr;
878 var_location->SetValueType(Value::eValueTypeLoadAddress);
879 }
880
Sean Callananf328c9f2010-07-20 23:31:16 +0000881 if (user_type)
882 *user_type = TypeFromUser(var_opaque_type, var_ast_context);
Sean Callanan336a0002010-07-17 00:43:37 +0000883
884 return var_location.release();
885}
886
887void
888ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
889 Variable* var)
890{
891 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
892
Sean Callananf328c9f2010-07-20 23:31:16 +0000893 TypeFromUser ut;
894 TypeFromParser pt;
Sean Callanan336a0002010-07-17 00:43:37 +0000895
896 Value *var_location = GetVariableValue(*m_exe_ctx,
897 var,
898 context.GetASTContext(),
Sean Callananf328c9f2010-07-20 23:31:16 +0000899 &ut,
900 &pt);
Sean Callanan336a0002010-07-17 00:43:37 +0000901
Greg Clayton1674b122010-07-21 22:12:05 +0000902 NamedDecl *var_decl = context.AddVarDecl(pt.GetOpaqueQualType());
Chris Lattner24943d22010-06-08 16:52:24 +0000903
904 Tuple tuple;
905
Sean Callanan810f22d2010-07-16 00:09:46 +0000906 tuple.m_decl = var_decl;
Sean Callanan336a0002010-07-17 00:43:37 +0000907 tuple.m_value = var_location;
Sean Callananf328c9f2010-07-20 23:31:16 +0000908 tuple.m_user_type = ut;
909 tuple.m_parser_type = pt;
Sean Callanan02fbafa2010-07-27 21:39:39 +0000910 tuple.m_llvm_value = NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000911
912 m_tuples.push_back(tuple);
913
Sean Callanan810f22d2010-07-16 00:09:46 +0000914 if (log)
Sean Callananf5857a02010-07-31 01:32:05 +0000915 log->Printf("Found variable %s, returned (NamedDecl)%p", context.Name.getAsString().c_str(), var_decl);
Sean Callanan8f0dc342010-06-22 23:46:24 +0000916}
917
918void
Sean Callanana48fe162010-08-11 03:57:18 +0000919ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
Sean Callanana6223432010-08-20 01:02:30 +0000920 ClangExpressionVariable *pvar)
Sean Callanana48fe162010-08-11 03:57:18 +0000921{
Sean Callanana6223432010-08-20 01:02:30 +0000922 TypeFromUser user_type = pvar->m_user_type;
Sean Callanana48fe162010-08-11 03:57:18 +0000923
924 TypeFromParser parser_type(ClangASTContext::CopyType(context.GetASTContext(),
925 user_type.GetASTContext(),
926 user_type.GetOpaqueQualType()),
927 context.GetASTContext());
928
929 (void)context.AddVarDecl(parser_type.GetOpaqueQualType());
930}
931
932void
Sean Callanan8f0dc342010-06-22 23:46:24 +0000933ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
Sean Callanan0fc73582010-07-27 00:55:47 +0000934 Function* fun,
935 Symbol* symbol)
Sean Callanan8f0dc342010-06-22 23:46:24 +0000936{
Sean Callanan6184dfe2010-06-23 00:47:48 +0000937 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
Sean Callanan8f0dc342010-06-22 23:46:24 +0000938
Sean Callanan0fc73582010-07-27 00:55:47 +0000939 NamedDecl *fun_decl;
Sean Callanan8f0dc342010-06-22 23:46:24 +0000940 std::auto_ptr<Value> fun_location(new Value);
Sean Callanan0fc73582010-07-27 00:55:47 +0000941 const Address *fun_address;
Sean Callanan8f0dc342010-06-22 23:46:24 +0000942
Sean Callanan0fc73582010-07-27 00:55:47 +0000943 // only valid for Functions, not for Symbols
944 void *fun_opaque_type = NULL;
945 clang::ASTContext *fun_ast_context = NULL;
946
947 if (fun)
948 {
949 Type *fun_type = fun->GetType();
950
951 if (!fun_type)
952 {
953 if (log)
954 log->PutCString("Skipped a function because it has no type");
955 return;
956 }
957
958 fun_opaque_type = fun_type->GetOpaqueClangQualType();
959
960 if (!fun_opaque_type)
961 {
962 if (log)
963 log->PutCString("Skipped a function because it has no Clang type");
964 return;
965 }
966
967 fun_address = &fun->GetAddressRange().GetBaseAddress();
968
969 TypeList *type_list = fun_type->GetTypeList();
970 fun_ast_context = type_list->GetClangASTContext().getASTContext();
971 void *copied_type = ClangASTContext::CopyType(context.GetASTContext(), fun_ast_context, fun_opaque_type);
972
973 fun_decl = context.AddFunDecl(copied_type);
974 }
975 else if (symbol)
976 {
977 fun_address = &symbol->GetAddressRangeRef().GetBaseAddress();
978
979 fun_decl = context.AddGenericFunDecl();
980 }
981 else
982 {
983 if (log)
984 log->PutCString("AddOneFunction called with no function and no symbol");
985 return;
986 }
987
988 lldb::addr_t load_addr = fun_address->GetLoadAddress(m_exe_ctx->process);
Sean Callanan8f0dc342010-06-22 23:46:24 +0000989 fun_location->SetValueType(Value::eValueTypeLoadAddress);
990 fun_location->GetScalar() = load_addr;
991
Sean Callanan8f0dc342010-06-22 23:46:24 +0000992 Tuple tuple;
993
Sean Callanan810f22d2010-07-16 00:09:46 +0000994 tuple.m_decl = fun_decl;
995 tuple.m_value = fun_location.release();
Sean Callananf328c9f2010-07-20 23:31:16 +0000996 tuple.m_user_type = TypeFromUser(fun_opaque_type, fun_ast_context);
Sean Callanan02fbafa2010-07-27 21:39:39 +0000997 tuple.m_llvm_value = NULL;
Sean Callanan8f0dc342010-06-22 23:46:24 +0000998
999 m_tuples.push_back(tuple);
1000
Sean Callanan810f22d2010-07-16 00:09:46 +00001001 if (log)
Sean Callananf5857a02010-07-31 01:32:05 +00001002 log->Printf("Found function %s, returned (NamedDecl)%p", context.Name.getAsString().c_str(), fun_decl);
Chris Lattner24943d22010-06-08 16:52:24 +00001003}
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001004
1005void
1006ClangExpressionDeclMap::AddOneType(NameSearchContext &context,
1007 Type *type)
1008{
1009 TypeFromUser ut(type->GetOpaqueClangQualType(),
1010 type->GetClangAST());
1011
1012 void *copied_type = ClangASTContext::CopyType(context.GetASTContext(), ut.GetASTContext(), ut.GetOpaqueQualType());
1013
1014 context.AddTypeDecl(copied_type);
1015}